import assert from "node:assert/strict"; import { mkdtemp } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import test from "node:test"; import { argumentCompletions } from "../index.ts"; import { addEntry, updateState, type WorktreeEntry } from "../src/state.ts"; function entry(overrides: Partial = {}): WorktreeEntry { return { slug: "demo", path: "/nonexistent/demo", branch: "wt/demo", sourcePath: "/nonexistent/source", sourceBranch: "main", sourceSha: "0".repeat(40), createdAt: new Date().toISOString(), ...overrides, }; } test("first-token completion returns subcommand names", async () => { const items = await argumentCompletions("mer"); assert.ok(items?.some((item) => item.value === "merge")); }); test("merge flag completions expand to the full argument line", async () => { const items = await argumentCompletions("merge --c"); assert.deepEqual( items?.map((item) => ({ value: item.value, label: item.label })), [{ value: "merge --continue", label: "--continue" }], ); }); test("bare -- after merge offers all four flags as full lines", async () => { const items = await argumentCompletions("merge --"); assert.equal(items?.length, 4); for (const item of items ?? []) { assert.ok(item.value.startsWith("merge --"), item.value); } }); test("slug completions keep the subcommand in the replacement value", async (t) => { const agentDir = await mkdtemp(join(tmpdir(), "pi-worktree-agent-")); const previous = process.env.PI_CODING_AGENT_DIR; process.env.PI_CODING_AGENT_DIR = agentDir; t.after(() => { if (previous === undefined) delete process.env.PI_CODING_AGENT_DIR; else process.env.PI_CODING_AGENT_DIR = previous; }); await updateState((s) => addEntry(s, entry())); const switchItems = await argumentCompletions("switch "); const values = switchItems?.map((item) => item.value) ?? []; assert.ok(values.includes("switch main"), JSON.stringify(values)); assert.ok(values.includes("switch demo"), JSON.stringify(values)); const removeItems = await argumentCompletions("remove d"); assert.deepEqual( removeItems?.map((item) => ({ value: item.value, label: item.label })), [{ value: "remove demo", label: "demo" }], ); });