Luigit
repositories / pi-ext

pi-ext

bugabingas pi extensions

owned by admin

extensions/afk/__serial__/package.test.ts

Raw
import { cp, mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { fileURLToPath } from "node:url";
import { fauxAssistantMessage, fauxToolCall } from "@earendil-works/pi-ai";
import { describe, expect, it, vi } from "vitest";
import {
	createPiSession,
	type PiSession,
} from "../../../test/fixture/create-pi-session.ts";

// Keep focused relocation independent of the root's all-package release matrix.
describe.skipIf(process.env["PI_AFK_VERIFY_PACKAGE"] !== "1")(
	"afk relocated package",
	() => {
		it("loads outside the checkout and completes real AFK work", async () => {
			const root = await mkdtemp(join(tmpdir(), "afk-package-"));
			let session: PiSession | undefined;
			try {
				const target = join(root, "afk");
				await cp(
					fileURLToPath(new URL("../../../dist/afk", import.meta.url)),
					target,
					{ recursive: true },
				);
				session = await createPiSession({
					cwd: root,
					extensionPaths: [join(target, "index.ts")],
					responses: [
						fauxAssistantMessage(fauxToolCall("afk_complete", {}), {
							stopReason: "toolUse",
						}),
						fauxAssistantMessage("Relocated AFK work complete."),
					],
				});
				expect(session.errors).toEqual([]);
				expect(session.extensions[0]?.path).toBe(join(target, "index.ts"));
				const command = session.extensions[0]?.commands.get("afk");
				if (!command) throw new Error("Relocated AFK command missing");
				const start = vi
					.spyOn(session.session, "sendCustomMessage")
					.mockImplementationOnce(async () => {});
				await command.handler(
					"",
					session.session.extensionRunner.createContext() as never,
				);
				start.mockRestore();
				await session.session.extensionRunner.emit({
					type: "session_compact",
					compactionEntry: { id: "relocated-compact" },
					fromExtension: false,
					reason: "manual",
					willRetry: false,
				} as never);
				await vi.waitFor(() =>
					expect(session!.providerState.callCount).toBe(2),
				);
				await session.session.waitForIdle();
				expect(session.providerState.callCount).toBe(2);
				expect(session.errors).toEqual([]);
			} finally {
				await session?.dispose();
				await rm(root, {
					recursive: true,
					force: true,
					maxRetries: 10,
					retryDelay: 100,
				});
			}
		}, 60_000);
	},
);