repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
extensions/git-safe/__tests__/debug.test.ts
Rawimport { readdirSync, readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { afterEach, describe, expect, it, vi } from "vitest";
import {
createPiSession,
type PiSession,
} from "../../../test/fixture/create-pi-session.ts";
const extensionPath = fileURLToPath(new URL("../index.ts", import.meta.url));
let session: PiSession | undefined;
afterEach(async () => {
await session?.dispose();
session = undefined;
});
function readRecords(directory: string) {
return readdirSync(directory).flatMap((file) =>
readFileSync(path.join(directory, file), "utf8")
.trim()
.split("\n")
.filter(Boolean)
.map((line) => JSON.parse(line) as { event: string; extension: string }),
);
}
describe("git-safe debug interface", () => {
it("writes its lifecycle records in the isolated sandbox", async () => {
session = await createPiSession({
env: { PI_GIT_SAFE_DEBUG: "1" },
extensionPaths: [extensionPath],
});
const runner = session.session.extensionRunner;
await runner.emit({
type: "session_start",
reason: "startup",
});
await runner.emitToolResult({
type: "tool_result",
toolName: "read",
toolCallId: "missing-read",
input: { path: path.join(session.cwd, "missing") },
content: [],
isError: true,
} as never);
await runner.emit({
type: "session_shutdown",
reason: "quit",
});
if (!session.env["XDG_STATE_HOME"])
throw new Error("missing sandbox state home");
const directory = path.join(
session.env["XDG_STATE_HOME"],
"pi-ext",
"debug",
"git-safe",
);
// Debug records flush asynchronously; poll until they appear.
await vi.waitFor(
() => {
const records = readRecords(directory);
expect(records).toContainEqual(
expect.objectContaining({
event: "session.start",
extension: "git-safe",
}),
);
expect(records).toContainEqual(
expect.objectContaining({
event: "session.shutdown",
extension: "git-safe",
}),
);
expect(records).toContainEqual(
expect.objectContaining({
event: "read.spotlight.error",
type: "readpath",
}),
);
},
{ timeout: 5_000 },
);
});
});