@victor-software-house/pi-acp 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -129,7 +129,7 @@ Zed shows an Authenticate banner that launches this automatically.
129
129
  ```bash
130
130
  bun install
131
131
  bun run dev # run from src
132
- bun run build # tsup -> dist/index.js
132
+ bun run build # tsdown -> dist/index.mjs
133
133
  bun run typecheck # tsc --noEmit
134
134
  bun run lint # biome + oxlint
135
135
  bun test # 26 tests
package/dist/index.mjs CHANGED
@@ -2,81 +2,11 @@
2
2
  import { homedir, platform } from "node:os";
3
3
  import { AgentSideConnection, RequestError, ndJsonStream } from "@agentclientprotocol/sdk";
4
4
  import { spawnSync } from "node:child_process";
5
- import { existsSync, readFileSync, readdirSync, realpathSync, statSync } from "node:fs";
5
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
6
6
  import { dirname, isAbsolute, join, resolve } from "node:path";
7
7
  import { fileURLToPath } from "node:url";
8
8
  import { SessionManager, VERSION, createAgentSession } from "@mariozechner/pi-coding-agent";
9
9
  import * as z from "zod";
10
- //#region src/pi-auth/status.ts
11
- /**
12
- * Detect whether the user has any pi authentication configured.
13
- *
14
- * Checks three sources:
15
- * 1. auth.json (API keys, OAuth credentials)
16
- * 2. models.json custom provider apiKey entries
17
- * 3. Known provider environment variables
18
- */
19
- const modelsConfigSchema = z.object({ providers: z.record(z.string().trim(), z.object({ apiKey: z.string().trim().optional() })).optional() });
20
- function agentDir() {
21
- const env = process.env.PI_CODING_AGENT_DIR;
22
- if (env === void 0) return join(homedir(), ".pi", "agent");
23
- if (env === "~") return homedir();
24
- if (env.startsWith("~/")) return homedir() + env.slice(1);
25
- return env;
26
- }
27
- function readJsonFile(path) {
28
- try {
29
- if (!existsSync(path)) return null;
30
- const raw = readFileSync(path, "utf-8").trim();
31
- if (!raw) return null;
32
- return JSON.parse(raw);
33
- } catch {
34
- return null;
35
- }
36
- }
37
- function hasAuthJson() {
38
- const data = readJsonFile(join(agentDir(), "auth.json"));
39
- return typeof data === "object" && data !== null && Object.keys(data).length > 0;
40
- }
41
- function hasCustomProviderKey() {
42
- const raw = readJsonFile(join(agentDir(), "models.json"));
43
- const result = modelsConfigSchema.safeParse(raw);
44
- if (!result.success || !result.data.providers) return false;
45
- return Object.values(result.data.providers).some((provider) => typeof provider.apiKey === "string" && provider.apiKey.trim().length > 0);
46
- }
47
- /** Environment variables that indicate a configured provider API key. */
48
- const PROVIDER_ENV_VARS = [
49
- "ANTHROPIC_API_KEY",
50
- "ANTHROPIC_OAUTH_TOKEN",
51
- "OPENAI_API_KEY",
52
- "AZURE_OPENAI_API_KEY",
53
- "GEMINI_API_KEY",
54
- "GROQ_API_KEY",
55
- "CEREBRAS_API_KEY",
56
- "XAI_API_KEY",
57
- "OPENROUTER_API_KEY",
58
- "AI_GATEWAY_API_KEY",
59
- "ZAI_API_KEY",
60
- "MISTRAL_API_KEY",
61
- "MINIMAX_API_KEY",
62
- "MINIMAX_CN_API_KEY",
63
- "HF_TOKEN",
64
- "OPENCODE_API_KEY",
65
- "KIMI_API_KEY",
66
- "COPILOT_GITHUB_TOKEN",
67
- "GH_TOKEN",
68
- "GITHUB_TOKEN"
69
- ];
70
- function hasProviderEnvVar() {
71
- return PROVIDER_ENV_VARS.some((key) => {
72
- const val = process.env[key];
73
- return typeof val === "string" && val.trim().length > 0;
74
- });
75
- }
76
- function hasPiAuthConfigured() {
77
- return hasAuthJson() || hasCustomProviderKey() || hasProviderEnvVar();
78
- }
79
- //#endregion
80
10
  //#region src/acp/auth.ts
81
11
  const AUTH_METHOD_ID = "pi_terminal_login";
82
12
  function buildAuthMethods(opts) {
@@ -285,8 +215,8 @@ function parseToolInput(tc) {
285
215
  return tc.arguments;
286
216
  }
287
217
  const toolArgsSchema = z.object({
288
- path: z.string().optional(),
289
- oldText: z.string().optional()
218
+ path: z.string().trim().optional(),
219
+ oldText: z.string().trim().optional()
290
220
  }).loose();
291
221
  function toToolArgs(raw) {
292
222
  const result = toolArgsSchema.safeParse(raw);
@@ -631,6 +561,76 @@ function acpPromptToPiMessage(blocks) {
631
561
  };
632
562
  }
633
563
  //#endregion
564
+ //#region src/pi-auth/status.ts
565
+ /**
566
+ * Detect whether the user has any pi authentication configured.
567
+ *
568
+ * Checks three sources:
569
+ * 1. auth.json (API keys, OAuth credentials)
570
+ * 2. models.json custom provider apiKey entries
571
+ * 3. Known provider environment variables
572
+ */
573
+ const modelsConfigSchema = z.object({ providers: z.record(z.string().trim(), z.object({ apiKey: z.string().trim().optional() })).optional() });
574
+ function agentDir() {
575
+ const env = process.env.PI_CODING_AGENT_DIR;
576
+ if (env === void 0) return join(homedir(), ".pi", "agent");
577
+ if (env === "~") return homedir();
578
+ if (env.startsWith("~/")) return homedir() + env.slice(1);
579
+ return env;
580
+ }
581
+ function readJsonFile(path) {
582
+ try {
583
+ if (!existsSync(path)) return null;
584
+ const raw = readFileSync(path, "utf-8").trim();
585
+ if (!raw) return null;
586
+ return JSON.parse(raw);
587
+ } catch {
588
+ return null;
589
+ }
590
+ }
591
+ function hasAuthJson() {
592
+ const data = readJsonFile(join(agentDir(), "auth.json"));
593
+ return typeof data === "object" && data !== null && Object.keys(data).length > 0;
594
+ }
595
+ function hasCustomProviderKey() {
596
+ const raw = readJsonFile(join(agentDir(), "models.json"));
597
+ const result = modelsConfigSchema.safeParse(raw);
598
+ if (!result.success || !result.data.providers) return false;
599
+ return Object.values(result.data.providers).some((provider) => typeof provider.apiKey === "string" && provider.apiKey.trim().length > 0);
600
+ }
601
+ /** Environment variables that indicate a configured provider API key. */
602
+ const PROVIDER_ENV_VARS = [
603
+ "ANTHROPIC_API_KEY",
604
+ "ANTHROPIC_OAUTH_TOKEN",
605
+ "OPENAI_API_KEY",
606
+ "AZURE_OPENAI_API_KEY",
607
+ "GEMINI_API_KEY",
608
+ "GROQ_API_KEY",
609
+ "CEREBRAS_API_KEY",
610
+ "XAI_API_KEY",
611
+ "OPENROUTER_API_KEY",
612
+ "AI_GATEWAY_API_KEY",
613
+ "ZAI_API_KEY",
614
+ "MISTRAL_API_KEY",
615
+ "MINIMAX_API_KEY",
616
+ "MINIMAX_CN_API_KEY",
617
+ "HF_TOKEN",
618
+ "OPENCODE_API_KEY",
619
+ "KIMI_API_KEY",
620
+ "COPILOT_GITHUB_TOKEN",
621
+ "GH_TOKEN",
622
+ "GITHUB_TOKEN"
623
+ ];
624
+ function hasProviderEnvVar() {
625
+ return PROVIDER_ENV_VARS.some((key) => {
626
+ const val = process.env[key];
627
+ return typeof val === "string" && val.trim().length > 0;
628
+ });
629
+ }
630
+ function hasPiAuthConfigured() {
631
+ return hasAuthJson() || hasCustomProviderKey() || hasProviderEnvVar();
632
+ }
633
+ //#endregion
634
634
  //#region src/acp/agent.ts
635
635
  function builtinAvailableCommands() {
636
636
  return [
@@ -703,6 +703,8 @@ const pkg = readNearestPackageJson(import.meta.url);
703
703
  var PiAcpAgent = class {
704
704
  conn;
705
705
  sessions = new SessionManager$1();
706
+ /** Cache of sessionId → file path, populated by listSessions and newSession. */
707
+ sessionPaths = /* @__PURE__ */ new Map();
706
708
  dispose() {
707
709
  this.sessions.disposeAll();
708
710
  }
@@ -750,8 +752,11 @@ var PiAcpAgent = class {
750
752
  piSession.dispose();
751
753
  throw RequestError.authRequired({ authMethods: buildAuthMethods() }, "Configure an API key or log in with an OAuth provider.");
752
754
  }
755
+ const sessionId = piSession.sessionManager.getSessionId();
756
+ const sessionFile = piSession.sessionManager.getSessionFile();
757
+ if (sessionFile !== void 0) this.sessionPaths.set(sessionId, sessionFile);
753
758
  const session = new PiAcpSession({
754
- sessionId: piSession.sessionManager.getSessionId(),
759
+ sessionId,
755
760
  cwd: params.cwd,
756
761
  mcpServers: params.mcpServers,
757
762
  piSession,
@@ -812,9 +817,23 @@ var PiAcpAgent = class {
812
817
  async cancel(params) {
813
818
  await this.sessions.get(params.sessionId).cancel();
814
819
  }
820
+ /**
821
+ * Resolve a session ID to a file path.
822
+ * Checks the local cache first (populated by listSessions/newSession),
823
+ * falls back to a full listAll() scan on cache miss.
824
+ */
825
+ async resolveSessionFile(sessionId) {
826
+ const cached = this.sessionPaths.get(sessionId);
827
+ if (cached !== void 0) return cached;
828
+ const all = await SessionManager.listAll();
829
+ for (const s of all) this.sessionPaths.set(s.id, s.path);
830
+ return this.sessionPaths.get(sessionId) ?? null;
831
+ }
815
832
  async listSessions(params) {
816
833
  const cwd = params.cwd;
817
- const sessions = (cwd !== void 0 && cwd !== null ? await SessionManager.list(cwd) : await SessionManager.listAll()).map((s) => ({
834
+ const raw = cwd !== void 0 && cwd !== null ? await SessionManager.list(cwd) : await SessionManager.listAll();
835
+ for (const s of raw) this.sessionPaths.set(s.id, s.path);
836
+ const sessions = raw.map((s) => ({
818
837
  id: s.id,
819
838
  cwd: s.cwd,
820
839
  name: s.name ?? "",
@@ -841,7 +860,7 @@ var PiAcpAgent = class {
841
860
  async loadSession(params) {
842
861
  if (!isAbsolute(params.cwd)) throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
843
862
  this.sessions.close(params.sessionId);
844
- const sessionFile = findPiSessionFile(params.sessionId);
863
+ const sessionFile = await this.resolveSessionFile(params.sessionId);
845
864
  if (sessionFile === null) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
846
865
  let result;
847
866
  try {
@@ -1389,41 +1408,12 @@ function buildCommandList(piSession, enableSkillCommands) {
1389
1408
  });
1390
1409
  }
1391
1410
  const runner = piSession.extensionRunner;
1392
- if (runner) for (const { command } of runner.getRegisteredCommandsWithPaths()) commands.push({
1393
- name: command.name,
1394
- description: command.description ?? `(extension)`
1411
+ if (runner) for (const cmd of runner.getRegisteredCommands()) commands.push({
1412
+ name: cmd.name,
1413
+ description: cmd.description ?? "(extension)"
1395
1414
  });
1396
1415
  return commands;
1397
1416
  }
1398
- function findPiSessionFile(sessionId) {
1399
- const sessionsDir = join(piAgentDir(), "sessions");
1400
- if (!existsSync(sessionsDir)) return null;
1401
- const walkJsonl = (dir) => {
1402
- let entries;
1403
- try {
1404
- entries = readdirSync(dir);
1405
- } catch {
1406
- return null;
1407
- }
1408
- for (const name of entries) {
1409
- const p = join(dir, name);
1410
- try {
1411
- const st = statSync(p);
1412
- if (st.isDirectory()) {
1413
- const found = walkJsonl(p);
1414
- if (found !== void 0) return found;
1415
- } else if (st.isFile() && name.endsWith(".jsonl")) try {
1416
- const firstLine = readFileSync(p, "utf8").split("\n")[0];
1417
- if (firstLine === void 0) continue;
1418
- const header = JSON.parse(firstLine);
1419
- if (typeof header === "object" && header !== null && "type" in header && header.type === "session" && "id" in header && header.id === sessionId) return p;
1420
- } catch {}
1421
- } catch {}
1422
- }
1423
- return null;
1424
- };
1425
- return walkJsonl(sessionsDir);
1426
- }
1427
1417
  function buildUpdateNotice() {
1428
1418
  try {
1429
1419
  const installed = VERSION;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["resolvePath","SessionManager","SessionManager","PiSessionManager","PI_VERSION"],"sources":["../src/pi-auth/status.ts","../src/acp/auth.ts","../src/acp/pi-settings.ts","../src/acp/translate/pi-tools.ts","../src/acp/session.ts","../src/acp/translate/pi-messages.ts","../src/acp/translate/prompt.ts","../src/acp/agent.ts","../src/index.ts"],"sourcesContent":["/**\n * Detect whether the user has any pi authentication configured.\n *\n * Checks three sources:\n * 1. auth.json (API keys, OAuth credentials)\n * 2. models.json custom provider apiKey entries\n * 3. Known provider environment variables\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as z from \"zod\";\n\nconst modelsConfigSchema = z.object({\n\tproviders: z\n\t\t.record(\n\t\t\tz.string().trim(),\n\t\t\tz.object({\n\t\t\t\tapiKey: z.string().trim().optional(),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n});\n\nfunction agentDir(): string {\n\tconst env = process.env.PI_CODING_AGENT_DIR;\n\tif (env === undefined) return join(homedir(), \".pi\", \"agent\");\n\tif (env === \"~\") return homedir();\n\tif (env.startsWith(\"~/\")) return homedir() + env.slice(1);\n\treturn env;\n}\n\nfunction readJsonFile(path: string): unknown {\n\ttry {\n\t\tif (!existsSync(path)) return null;\n\t\tconst raw = readFileSync(path, \"utf-8\").trim();\n\t\tif (!raw) return null;\n\t\treturn JSON.parse(raw);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction hasAuthJson(): boolean {\n\tconst data = readJsonFile(join(agentDir(), \"auth.json\"));\n\treturn typeof data === \"object\" && data !== null && Object.keys(data).length > 0;\n}\n\nfunction hasCustomProviderKey(): boolean {\n\tconst raw = readJsonFile(join(agentDir(), \"models.json\"));\n\tconst result = modelsConfigSchema.safeParse(raw);\n\tif (!result.success || !result.data.providers) return false;\n\n\treturn Object.values(result.data.providers).some(\n\t\t(provider) => typeof provider.apiKey === \"string\" && provider.apiKey.trim().length > 0,\n\t);\n}\n\n/** Environment variables that indicate a configured provider API key. */\nconst PROVIDER_ENV_VARS = [\n\t\"ANTHROPIC_API_KEY\",\n\t\"ANTHROPIC_OAUTH_TOKEN\",\n\t\"OPENAI_API_KEY\",\n\t\"AZURE_OPENAI_API_KEY\",\n\t\"GEMINI_API_KEY\",\n\t\"GROQ_API_KEY\",\n\t\"CEREBRAS_API_KEY\",\n\t\"XAI_API_KEY\",\n\t\"OPENROUTER_API_KEY\",\n\t\"AI_GATEWAY_API_KEY\",\n\t\"ZAI_API_KEY\",\n\t\"MISTRAL_API_KEY\",\n\t\"MINIMAX_API_KEY\",\n\t\"MINIMAX_CN_API_KEY\",\n\t\"HF_TOKEN\",\n\t\"OPENCODE_API_KEY\",\n\t\"KIMI_API_KEY\",\n\t\"COPILOT_GITHUB_TOKEN\",\n\t\"GH_TOKEN\",\n\t\"GITHUB_TOKEN\",\n];\n\nfunction hasProviderEnvVar(): boolean {\n\treturn PROVIDER_ENV_VARS.some((key) => {\n\t\tconst val = process.env[key];\n\t\treturn typeof val === \"string\" && val.trim().length > 0;\n\t});\n}\n\nexport function hasPiAuthConfigured(): boolean {\n\treturn hasAuthJson() || hasCustomProviderKey() || hasProviderEnvVar();\n}\n","/**\n * Build ACP AuthMethod descriptors for terminal-based authentication.\n *\n * Supports both the registry-required \"type/args/env\" shape and Zed's\n * _meta[\"terminal-auth\"] extension for the Authenticate banner.\n */\n\nimport type { AuthMethod } from \"@agentclientprotocol/sdk\";\n\nexport const AUTH_METHOD_ID = \"pi_terminal_login\";\n\ninterface AuthMethodOptions {\n\tsupportsTerminalAuthMeta?: boolean;\n}\n\nexport function buildAuthMethods(opts?: AuthMethodOptions): AuthMethod[] {\n\tconst supportsTerminalAuthMeta = opts?.supportsTerminalAuthMeta ?? true;\n\n\tconst method: AuthMethod = {\n\t\tid: AUTH_METHOD_ID,\n\t\tname: \"Launch pi in the terminal\",\n\t\tdescription: \"Start pi in an interactive terminal to configure API keys or login\",\n\t\ttype: \"terminal\",\n\t\targs: [\"--terminal-login\"],\n\t\tenv: {},\n\t};\n\n\tif (supportsTerminalAuthMeta) {\n\t\tconst launch = resolveTerminalLaunchCommand();\n\t\tmethod._meta = {\n\t\t\t\"terminal-auth\": {\n\t\t\t\t...launch,\n\t\t\t\tlabel: \"Launch pi\",\n\t\t\t},\n\t\t};\n\t}\n\n\treturn [method];\n}\n\nfunction resolveTerminalLaunchCommand(): { command: string; args: string[] } {\n\tconst argv0 = process.argv[0] ?? \"node\";\n\tconst argv1 = process.argv[1];\n\n\tif (argv1 !== undefined && argv0.includes(\"node\") && argv1.endsWith(\".js\")) {\n\t\treturn { command: argv0, args: [argv1, \"--terminal-login\"] };\n\t}\n\n\treturn { command: \"pi-acp\", args: [\"--terminal-login\"] };\n}\n","/**\n * Read pi settings from global and project config files.\n *\n * Settings are merged: project overrides global.\n * Paths follow pi-mono conventions:\n * Global: ~/.pi/agent/settings.json\n * Project: <cwd>/.pi/settings.json\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport * as z from \"zod\";\n\nconst piSettingsSchema = z.object({\n\tenableSkillCommands: z.boolean().optional(),\n\tquietStartup: z.boolean().optional(),\n\tquietStart: z.boolean().optional(),\n\tskills: z\n\t\t.object({\n\t\t\tenableSkillCommands: z.boolean().optional(),\n\t\t})\n\t\t.optional(),\n});\n\ntype PiSettings = z.infer<typeof piSettingsSchema>;\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n\treturn typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction merge(\n\tbase: Record<string, unknown>,\n\toverride: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...base };\n\tfor (const [key, val] of Object.entries(override)) {\n\t\tconst existing = result[key];\n\t\tif (isRecord(existing) && isRecord(val)) {\n\t\t\tresult[key] = merge(existing, val);\n\t\t} else {\n\t\t\tresult[key] = val;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction readJson(path: string): Record<string, unknown> {\n\ttry {\n\t\tif (!existsSync(path)) return {};\n\t\tconst data: unknown = JSON.parse(readFileSync(path, \"utf-8\"));\n\t\treturn isRecord(data) ? data : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nexport function piAgentDir(): string {\n\treturn process.env.PI_CODING_AGENT_DIR !== undefined\n\t\t? resolve(process.env.PI_CODING_AGENT_DIR)\n\t\t: join(homedir(), \".pi\", \"agent\");\n}\n\nfunction resolvedSettings(cwd: string): PiSettings {\n\tconst globalPath = join(piAgentDir(), \"settings.json\");\n\tconst projectPath = resolve(cwd, \".pi\", \"settings.json\");\n\tconst merged = merge(readJson(globalPath), readJson(projectPath));\n\tconst result = piSettingsSchema.safeParse(merged);\n\treturn result.success ? result.data : {};\n}\n\nexport function skillCommandsEnabled(cwd: string): boolean {\n\tconst settings = resolvedSettings(cwd);\n\n\tif (typeof settings.enableSkillCommands === \"boolean\") {\n\t\treturn settings.enableSkillCommands;\n\t}\n\n\tif (typeof settings.skills?.enableSkillCommands === \"boolean\") {\n\t\treturn settings.skills.enableSkillCommands;\n\t}\n\n\treturn true;\n}\n\nexport function quietStartupEnabled(cwd: string): boolean {\n\tconst settings = resolvedSettings(cwd);\n\n\tif (typeof settings.quietStartup === \"boolean\") {\n\t\treturn settings.quietStartup;\n\t}\n\n\tif (typeof settings.quietStart === \"boolean\") {\n\t\treturn settings.quietStart;\n\t}\n\n\treturn false;\n}\n","/**\n * Extract displayable text from a pi tool result.\n *\n * Pi tool results have varying shapes depending on the tool. This function\n * tries content blocks first, then falls back to details fields (diff, stdout/stderr),\n * and finally JSON serialization as a last resort.\n */\n\nimport * as z from \"zod\";\n\nconst textBlockSchema = z.object({\n\ttype: z.literal(\"text\"),\n\ttext: z.string(),\n});\n\nconst toolDetailsSchema = z.object({\n\tdiff: z.string().optional(),\n\tstdout: z.string().optional(),\n\tstderr: z.string().optional(),\n\toutput: z.string().optional(),\n\texitCode: z.number().optional(),\n\tcode: z.number().optional(),\n});\n\nconst toolResultSchema = z.object({\n\tcontent: z.array(z.unknown()).optional(),\n\tdetails: toolDetailsSchema.optional(),\n\tstdout: z.string().optional(),\n\tstderr: z.string().optional(),\n\toutput: z.string().optional(),\n\texitCode: z.number().optional(),\n\tcode: z.number().optional(),\n});\n\nexport function toolResultToText(result: unknown): string {\n\tif (result === null || result === undefined || typeof result !== \"object\") return \"\";\n\n\tconst parsed = toolResultSchema.safeParse(result);\n\tif (!parsed.success) {\n\t\ttry {\n\t\t\treturn JSON.stringify(result, null, 2);\n\t\t} catch {\n\t\t\treturn String(result);\n\t\t}\n\t}\n\n\tconst r = parsed.data;\n\n\tif (r.content !== undefined) {\n\t\tconst texts = r.content\n\t\t\t.map((block) => textBlockSchema.safeParse(block))\n\t\t\t.filter((res) => res.success)\n\t\t\t.map((res) => res.data.text);\n\t\tif (texts.length > 0) return texts.join(\"\");\n\t}\n\n\tconst d = r.details;\n\n\tconst diff = d?.diff;\n\tif (diff !== undefined && diff.trim() !== \"\") return diff;\n\n\tconst stdout = d?.stdout ?? r.stdout ?? d?.output ?? r.output;\n\tconst stderr = d?.stderr ?? r.stderr;\n\tconst exitCode = d?.exitCode ?? r.exitCode ?? d?.code ?? r.code;\n\n\tconst hasStdout = stdout !== undefined && stdout.trim() !== \"\";\n\tconst hasStderr = stderr !== undefined && stderr.trim() !== \"\";\n\n\tif (hasStdout || hasStderr) {\n\t\tconst parts: string[] = [];\n\t\tif (hasStdout) parts.push(stdout);\n\t\tif (hasStderr) parts.push(`stderr:\\n${stderr}`);\n\t\tif (exitCode !== undefined) parts.push(`exit code: ${exitCode}`);\n\t\treturn parts.join(\"\\n\\n\").trimEnd();\n\t}\n\n\ttry {\n\t\treturn JSON.stringify(result, null, 2);\n\t} catch {\n\t\treturn String(result);\n\t}\n}\n","import { readFileSync } from \"node:fs\";\nimport { isAbsolute, resolve as resolvePath } from \"node:path\";\nimport {\n\ttype AgentSideConnection,\n\ttype ContentBlock,\n\ttype McpServer,\n\tRequestError,\n\ttype SessionUpdate,\n\ttype ToolCallContent,\n\ttype ToolCallLocation,\n\ttype ToolKind,\n} from \"@agentclientprotocol/sdk\";\nimport type { AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessageEvent, ToolCall } from \"@mariozechner/pi-ai\";\nimport type { AgentSession, AgentSessionEvent } from \"@mariozechner/pi-coding-agent\";\nimport * as z from \"zod\";\nimport { toolResultToText } from \"./translate/pi-tools.js\";\n\nexport type StopReason = \"end_turn\" | \"cancelled\" | \"max_tokens\" | \"error\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction findUniqueLineNumber(text: string, needle: string): number | undefined {\n\tif (!needle) return undefined;\n\tconst first = text.indexOf(needle);\n\tif (first < 0) return undefined;\n\tif (text.indexOf(needle, first + needle.length) >= 0) return undefined;\n\n\tlet line = 1;\n\tfor (let i = 0; i < first; i++) {\n\t\tif (text.charCodeAt(i) === 10) line++;\n\t}\n\treturn line;\n}\n\ninterface ToolArgs {\n\tpath?: string | undefined;\n\toldText?: string | undefined;\n\t[key: string]: unknown;\n}\n\nfunction resolveToolPath(\n\targs: ToolArgs,\n\tcwd: string,\n\tline?: number,\n): ToolCallLocation[] | undefined {\n\tconst p = args.path;\n\tif (p === undefined) return undefined;\n\n\tconst resolved = isAbsolute(p) ? p : resolvePath(cwd, p);\n\treturn [{ path: resolved, ...(typeof line === \"number\" ? { line } : {}) }];\n}\n\nfunction toToolKind(toolName: string): ToolKind {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn \"read\";\n\t\tcase \"write\":\n\t\tcase \"edit\":\n\t\t\treturn \"edit\";\n\t\tcase \"bash\":\n\t\t\treturn \"execute\";\n\t\tdefault:\n\t\t\treturn \"other\";\n\t}\n}\n\n/**\n * Map pi assistant stopReason to ACP StopReason.\n * pi: \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\"\n * ACP: \"end_turn\" | \"cancelled\" | \"max_tokens\" | \"error\"\n */\nfunction mapPiStopReason(piReason: string | null): StopReason {\n\tswitch (piReason) {\n\t\tcase \"stop\":\n\t\tcase \"toolUse\":\n\t\t\treturn \"end_turn\";\n\t\tcase \"length\":\n\t\t\treturn \"max_tokens\";\n\t\tcase \"aborted\":\n\t\t\treturn \"cancelled\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\treturn \"end_turn\";\n\t}\n}\n\nfunction extractToolCallFromPartial(ame: AssistantMessageEvent): ToolCall | undefined {\n\tif (!(\"partial\" in ame)) return undefined;\n\tconst content = ame.partial.content;\n\tconst idx = \"contentIndex\" in ame ? ame.contentIndex : 0;\n\tconst block = content[idx];\n\tif (block && \"type\" in block && block.type === \"toolCall\") return block;\n\treturn undefined;\n}\n\nfunction parseToolInput(tc: ToolCall): ToolArgs {\n\treturn tc.arguments;\n}\n\nconst toolArgsSchema = z\n\t.object({\n\t\tpath: z.string().optional(),\n\t\toldText: z.string().optional(),\n\t})\n\t.loose();\n\nfunction toToolArgs(raw: unknown): ToolArgs {\n\tconst result = toolArgsSchema.safeParse(raw);\n\treturn result.success ? result.data : {};\n}\n\n// ---------------------------------------------------------------------------\n// Session manager\n// ---------------------------------------------------------------------------\n\nexport class SessionManager {\n\tprivate sessions = new Map<string, PiAcpSession>();\n\n\tdisposeAll(): void {\n\t\tfor (const id of this.sessions.keys()) this.close(id);\n\t}\n\n\tmaybeGet(sessionId: string): PiAcpSession | undefined {\n\t\treturn this.sessions.get(sessionId);\n\t}\n\n\tclose(sessionId: string): void {\n\t\tconst s = this.sessions.get(sessionId);\n\t\tif (!s) return;\n\t\ttry {\n\t\t\ts.dispose();\n\t\t} catch {\n\t\t\t// best-effort\n\t\t}\n\t\tthis.sessions.delete(sessionId);\n\t}\n\n\tcloseAllExcept(keepSessionId: string): void {\n\t\tfor (const id of this.sessions.keys()) {\n\t\t\tif (id !== keepSessionId) this.close(id);\n\t\t}\n\t}\n\n\tregister(session: PiAcpSession): void {\n\t\tthis.sessions.set(session.sessionId, session);\n\t}\n\n\tget(sessionId: string): PiAcpSession {\n\t\tconst s = this.sessions.get(sessionId);\n\t\tif (!s) throw RequestError.invalidParams(`Unknown sessionId: ${sessionId}`);\n\t\treturn s;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// ACP session wrapping a pi AgentSession\n// ---------------------------------------------------------------------------\n\ninterface PiAcpSessionOpts {\n\tsessionId: string;\n\tcwd: string;\n\tmcpServers: McpServer[];\n\tpiSession: AgentSession;\n\tconn: AgentSideConnection;\n}\n\nexport class PiAcpSession {\n\treadonly sessionId: string;\n\treadonly cwd: string;\n\treadonly mcpServers: McpServer[];\n\treadonly piSession: AgentSession;\n\n\tprivate startupInfo: string | null = null;\n\tprivate startupInfoSent = false;\n\tprivate readonly conn: AgentSideConnection;\n\n\tprivate cancelRequested = false;\n\tprivate pendingTurn: { resolve: (r: StopReason) => void; reject: (e: unknown) => void } | null =\n\t\tnull;\n\n\tprivate currentToolCalls = new Map<string, \"pending\" | \"in_progress\">();\n\tprivate editSnapshots = new Map<string, { path: string; oldText: string }>();\n\tprivate lastAssistantStopReason: string | null = null;\n\tprivate lastEmit: Promise<void> = Promise.resolve();\n\tprivate unsubscribe: (() => void) | undefined;\n\n\tconstructor(opts: PiAcpSessionOpts) {\n\t\tthis.sessionId = opts.sessionId;\n\t\tthis.cwd = opts.cwd;\n\t\tthis.mcpServers = opts.mcpServers;\n\t\tthis.piSession = opts.piSession;\n\t\tthis.conn = opts.conn;\n\t\tthis.unsubscribe = this.piSession.subscribe((ev: AgentSessionEvent) => this.handlePiEvent(ev));\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.piSession.dispose();\n\t}\n\n\tsetStartupInfo(text: string): void {\n\t\tthis.startupInfo = text;\n\t}\n\n\tsendStartupInfoIfPending(): void {\n\t\tif (this.startupInfoSent || this.startupInfo === null) return;\n\t\tthis.startupInfoSent = true;\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\tcontent: { type: \"text\", text: this.startupInfo },\n\t\t});\n\t}\n\n\tasync prompt(message: string, images: unknown[] = []): Promise<StopReason> {\n\t\tconst turnPromise = new Promise<StopReason>((resolve, reject) => {\n\t\t\tthis.cancelRequested = false;\n\t\t\tthis.pendingTurn = { resolve, reject };\n\t\t});\n\n\t\tconst imageContents = Array.isArray(images)\n\t\t\t? images.filter(\n\t\t\t\t\t(img): img is { type: \"image\"; data: string; mimeType: string } =>\n\t\t\t\t\t\ttypeof img === \"object\" && img !== null && \"type\" in img && img.type === \"image\",\n\t\t\t\t)\n\t\t\t: [];\n\n\t\tthis.piSession.prompt(message, { images: imageContents }).catch(() => {\n\t\t\tvoid this.flushEmits().finally(() => {\n\t\t\t\tconst reason: StopReason = this.cancelRequested ? \"cancelled\" : \"error\";\n\t\t\t\tthis.pendingTurn?.resolve(reason);\n\t\t\t\tthis.pendingTurn = null;\n\t\t\t});\n\t\t});\n\n\t\treturn turnPromise;\n\t}\n\n\tasync cancel(): Promise<void> {\n\t\tthis.cancelRequested = true;\n\t\tawait this.piSession.abort();\n\t}\n\n\twasCancelRequested(): boolean {\n\t\treturn this.cancelRequested;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Internal\n\t// -----------------------------------------------------------------------\n\n\tprivate emit(update: SessionUpdate): void {\n\t\tthis.lastEmit = this.lastEmit\n\t\t\t.then(() => this.conn.sessionUpdate({ sessionId: this.sessionId, update }))\n\t\t\t.catch(() => {});\n\t}\n\n\tprivate async flushEmits(): Promise<void> {\n\t\tawait this.lastEmit;\n\t}\n\n\tprivate handlePiEvent(ev: AgentSessionEvent): void {\n\t\tif (!isAgentEvent(ev)) return;\n\n\t\tswitch (ev.type) {\n\t\t\tcase \"message_update\":\n\t\t\t\tthis.handleMessageUpdate(ev.assistantMessageEvent);\n\t\t\t\tbreak;\n\t\t\tcase \"message_end\":\n\t\t\t\tthis.handleMessageEnd(ev.message);\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_start\":\n\t\t\t\tthis.handleToolStart(ev.toolCallId, ev.toolName, toToolArgs(ev.args));\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_update\":\n\t\t\t\tthis.handleToolUpdate(ev.toolCallId, ev.partialResult);\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_end\":\n\t\t\t\tthis.handleToolEnd(ev.toolCallId, ev.result, ev.isError);\n\t\t\t\tbreak;\n\t\t\tcase \"agent_end\":\n\t\t\t\tthis.handleAgentEnd();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleMessageUpdate(ame: AssistantMessageEvent): void {\n\t\tif (ame.type === \"text_delta\") {\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\tcontent: { type: \"text\", text: ame.delta } satisfies ContentBlock,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (ame.type === \"thinking_delta\") {\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"agent_thought_chunk\",\n\t\t\t\tcontent: { type: \"text\", text: ame.delta } satisfies ContentBlock,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tame.type === \"toolcall_start\" ||\n\t\t\tame.type === \"toolcall_delta\" ||\n\t\t\tame.type === \"toolcall_end\"\n\t\t) {\n\t\t\tconst toolCall = ame.type === \"toolcall_end\" ? ame.toolCall : extractToolCallFromPartial(ame);\n\t\t\tif (!toolCall) return;\n\n\t\t\tconst rawInput = parseToolInput(toolCall);\n\t\t\tconst locations = resolveToolPath(rawInput, this.cwd);\n\t\t\tconst existingStatus = this.currentToolCalls.get(toolCall.id);\n\t\t\tconst status = existingStatus ?? \"pending\";\n\n\t\t\tif (!existingStatus) {\n\t\t\t\tthis.currentToolCalls.set(toolCall.id, \"pending\");\n\t\t\t\tthis.emit({\n\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttitle: toolCall.name,\n\t\t\t\t\tkind: toToolKind(toolCall.name),\n\t\t\t\t\tstatus,\n\t\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\t\trawInput,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.emit({\n\t\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tstatus,\n\t\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\t\trawInput,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleMessageEnd(msg: AgentMessage): void {\n\t\tif (\"role\" in msg && msg.role === \"assistant\") {\n\t\t\tthis.lastAssistantStopReason = msg.stopReason;\n\t\t}\n\t}\n\n\tprivate handleToolStart(toolCallId: string, toolName: string, args: ToolArgs): void {\n\t\tlet line: number | undefined;\n\n\t\tif (toolName === \"edit\" && args.path !== undefined) {\n\t\t\ttry {\n\t\t\t\tconst abs = isAbsolute(args.path) ? args.path : resolvePath(this.cwd, args.path);\n\t\t\t\tconst oldText = readFileSync(abs, \"utf8\");\n\t\t\t\tthis.editSnapshots.set(toolCallId, { path: abs, oldText });\n\t\t\t\tline = findUniqueLineNumber(oldText, args.oldText ?? \"\");\n\t\t\t} catch {\n\t\t\t\t// snapshot failure is non-fatal\n\t\t\t}\n\t\t}\n\n\t\tconst locations = resolveToolPath(args, this.cwd, line);\n\n\t\tif (!this.currentToolCalls.has(toolCallId)) {\n\t\t\tthis.currentToolCalls.set(toolCallId, \"in_progress\");\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\ttoolCallId,\n\t\t\t\ttitle: toolName,\n\t\t\t\tkind: toToolKind(toolName),\n\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\trawInput: args,\n\t\t\t});\n\t\t} else {\n\t\t\tthis.currentToolCalls.set(toolCallId, \"in_progress\");\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\ttoolCallId,\n\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\trawInput: args,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleToolUpdate(toolCallId: string, partialResult: unknown): void {\n\t\tconst text = toolResultToText(partialResult);\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\ttoolCallId,\n\t\t\tstatus: \"in_progress\",\n\t\t\tcontent: text\n\t\t\t\t? ([{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[])\n\t\t\t\t: null,\n\t\t\trawOutput: partialResult,\n\t\t});\n\t}\n\n\tprivate handleToolEnd(toolCallId: string, result: unknown, isError: boolean): void {\n\t\tconst text = toolResultToText(result);\n\t\tconst snapshot = this.editSnapshots.get(toolCallId);\n\t\tlet content: ToolCallContent[] | null = null;\n\n\t\tif (!isError && snapshot) {\n\t\t\ttry {\n\t\t\t\tconst newText = readFileSync(snapshot.path, \"utf8\");\n\t\t\t\tif (newText !== snapshot.oldText) {\n\t\t\t\t\tcontent = [\n\t\t\t\t\t\t{ type: \"diff\", path: snapshot.path, oldText: snapshot.oldText, newText },\n\t\t\t\t\t\t...(text\n\t\t\t\t\t\t\t? ([{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[])\n\t\t\t\t\t\t\t: []),\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// fall back to text\n\t\t\t}\n\t\t}\n\n\t\tif (!content && text) {\n\t\t\tcontent = [{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[];\n\t\t}\n\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\ttoolCallId,\n\t\t\tstatus: isError ? \"failed\" : \"completed\",\n\t\t\tcontent,\n\t\t\trawOutput: result,\n\t\t});\n\n\t\tthis.currentToolCalls.delete(toolCallId);\n\t\tthis.editSnapshots.delete(toolCallId);\n\t}\n\n\tprivate handleAgentEnd(): void {\n\t\tvoid this.flushEmits().finally(() => {\n\t\t\tconst reason: StopReason = this.cancelRequested\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: mapPiStopReason(this.lastAssistantStopReason);\n\t\t\tthis.lastAssistantStopReason = null;\n\t\t\tthis.pendingTurn?.resolve(reason);\n\t\t\tthis.pendingTurn = null;\n\t\t});\n\t}\n}\n\n/**\n * Type guard to narrow AgentSessionEvent to the AgentEvent subset\n * (the variants we handle). Session-specific events like auto_compaction\n * are ignored.\n */\nfunction isAgentEvent(\n\tev: AgentSessionEvent,\n): ev is Extract<\n\tAgentEvent,\n\t| { type: \"message_update\" }\n\t| { type: \"message_end\" }\n\t| { type: \"tool_execution_start\" }\n\t| { type: \"tool_execution_update\" }\n\t| { type: \"tool_execution_end\" }\n\t| { type: \"agent_end\" }\n> {\n\treturn (\n\t\tev.type === \"message_update\" ||\n\t\tev.type === \"message_end\" ||\n\t\tev.type === \"tool_execution_start\" ||\n\t\tev.type === \"tool_execution_update\" ||\n\t\tev.type === \"tool_execution_end\" ||\n\t\tev.type === \"agent_end\"\n\t);\n}\n","/**\n * Extract plain text from pi message content.\n *\n * Pi messages store content as either a string or an array of typed blocks.\n * These helpers extract the text portions for ACP session replay.\n */\n\ninterface TextBlock {\n\ttype: \"text\";\n\ttext: string;\n}\n\nfunction isTextBlock(block: unknown): block is TextBlock {\n\tif (typeof block !== \"object\" || block === null) return false;\n\treturn (\n\t\t\"type\" in block && block.type === \"text\" && \"text\" in block && typeof block.text === \"string\"\n\t);\n}\n\nexport function extractUserMessageText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter(isTextBlock)\n\t\t.map((b) => b.text)\n\t\t.join(\"\");\n}\n\nexport function extractAssistantText(content: unknown): string {\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter(isTextBlock)\n\t\t.map((b) => b.text)\n\t\t.join(\"\");\n}\n","/**\n * Convert ACP prompt ContentBlocks to a pi-compatible message string and image array.\n */\n\nimport type { ContentBlock } from \"@agentclientprotocol/sdk\";\n\nexport interface PiImage {\n\ttype: \"image\";\n\tmimeType: string;\n\tdata: string;\n}\n\nexport function acpPromptToPiMessage(blocks: ContentBlock[]): {\n\tmessage: string;\n\timages: PiImage[];\n} {\n\tlet message = \"\";\n\tconst images: PiImage[] = [];\n\n\tfor (const block of blocks) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\":\n\t\t\t\tmessage += block.text;\n\t\t\t\tbreak;\n\n\t\t\tcase \"resource_link\":\n\t\t\t\tmessage += `\\n[Context] ${block.uri}`;\n\t\t\t\tbreak;\n\n\t\t\tcase \"image\":\n\t\t\t\timages.push({\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType: block.mimeType,\n\t\t\t\t\tdata: block.data,\n\t\t\t\t});\n\t\t\t\tbreak;\n\n\t\t\tcase \"resource\": {\n\t\t\t\tconst resource = block.resource;\n\t\t\t\tconst uri = resource.uri;\n\t\t\t\tconst mime = resource.mimeType ?? null;\n\n\t\t\t\tif (\"text\" in resource) {\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri} (${mime ?? \"text/plain\"})\\n${resource.text}`;\n\t\t\t\t} else if (\"blob\" in resource) {\n\t\t\t\t\tconst bytes = Buffer.byteLength(resource.blob, \"base64\");\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri} (${mime ?? \"application/octet-stream\"}, ${bytes} bytes)`;\n\t\t\t\t} else {\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri}`;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"audio\": {\n\t\t\t\tconst bytes = Buffer.byteLength(block.data, \"base64\");\n\t\t\t\tmessage += `\\n[Audio] (${block.mimeType}, ${bytes} bytes) not supported`;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { message, images };\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, readdirSync, readFileSync, realpathSync, statSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n\ttype Agent as ACPAgent,\n\ttype AgentSideConnection,\n\ttype AuthenticateRequest,\n\ttype AvailableCommand,\n\ttype CancelNotification,\n\ttype InitializeRequest,\n\ttype InitializeResponse,\n\ttype ListSessionsRequest,\n\ttype ListSessionsResponse,\n\ttype LoadSessionRequest,\n\ttype LoadSessionResponse,\n\ttype ModelInfo,\n\ttype NewSessionRequest,\n\ttype PromptRequest,\n\ttype PromptResponse,\n\tRequestError,\n\ttype SessionConfigOption,\n\ttype SessionInfo,\n\ttype SessionModelState,\n\ttype SessionModeState,\n\ttype SetSessionConfigOptionRequest,\n\ttype SetSessionConfigOptionResponse,\n\ttype SetSessionModelRequest,\n\ttype SetSessionModelResponse,\n\ttype SetSessionModeRequest,\n\ttype SetSessionModeResponse,\n\ttype StopReason,\n} from \"@agentclientprotocol/sdk\";\nimport type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessage, ToolResultMessage, UserMessage } from \"@mariozechner/pi-ai\";\nimport {\n\ttype AgentSession,\n\ttype CreateAgentSessionResult,\n\tcreateAgentSession,\n\tVERSION as PI_VERSION,\n\tSessionManager as PiSessionManager,\n} from \"@mariozechner/pi-coding-agent\";\nimport { hasPiAuthConfigured } from \"../pi-auth/status.js\";\nimport { buildAuthMethods } from \"./auth.js\";\nimport { piAgentDir, quietStartupEnabled, skillCommandsEnabled } from \"./pi-settings.js\";\nimport { PiAcpSession, SessionManager } from \"./session.js\";\nimport { extractAssistantText, extractUserMessageText } from \"./translate/pi-messages.js\";\nimport { toolResultToText } from \"./translate/pi-tools.js\";\nimport { acpPromptToPiMessage } from \"./translate/prompt.js\";\n\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\nfunction builtinAvailableCommands(): AvailableCommand[] {\n\treturn [\n\t\t{\n\t\t\tname: \"compact\",\n\t\t\tdescription: \"Manually compact the session context\",\n\t\t\tinput: { hint: \"optional custom instructions\" },\n\t\t},\n\t\t{\n\t\t\tname: \"autocompact\",\n\t\t\tdescription: \"Toggle automatic context compaction\",\n\t\t\tinput: { hint: \"on|off|toggle\" },\n\t\t},\n\t\t{ name: \"export\", description: \"Export session to an HTML file in the session cwd\" },\n\t\t{ name: \"session\", description: \"Show session stats (messages, tokens, cost, session file)\" },\n\t\t{ name: \"name\", description: \"Set session display name\", input: { hint: \"<name>\" } },\n\t\t{\n\t\t\tname: \"steering\",\n\t\t\tdescription: \"Get/set pi steering message delivery mode\",\n\t\t\tinput: { hint: \"(no args to show) all | one-at-a-time\" },\n\t\t},\n\t\t{\n\t\t\tname: \"follow-up\",\n\t\t\tdescription: \"Get/set pi follow-up message delivery mode\",\n\t\t\tinput: { hint: \"(no args to show) all | one-at-a-time\" },\n\t\t},\n\t\t{ name: \"changelog\", description: \"Show pi changelog\" },\n\t];\n}\n\nfunction mergeCommands(a: AvailableCommand[], b: AvailableCommand[]): AvailableCommand[] {\n\tconst out: AvailableCommand[] = [];\n\tconst seen = new Set<string>();\n\tfor (const c of [...a, ...b]) {\n\t\tif (seen.has(c.name)) continue;\n\t\tseen.add(c.name);\n\t\tout.push(c);\n\t}\n\treturn out;\n}\n\nfunction parseArgs(input: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet quote: string | null = null;\n\n\tfor (const ch of input) {\n\t\tif (quote !== null) {\n\t\t\tif (ch === quote) quote = null;\n\t\t\telse current += ch;\n\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\tquote = ch;\n\t\t} else if (ch === \" \" || ch === \"\\t\") {\n\t\t\tif (current !== \"\") {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tif (current !== \"\") args.push(current);\n\treturn args;\n}\n\nconst pkg = readNearestPackageJson(import.meta.url);\n\nexport class PiAcpAgent implements ACPAgent {\n\tprivate readonly conn: AgentSideConnection;\n\tprivate readonly sessions = new SessionManager();\n\n\tdispose(): void {\n\t\tthis.sessions.disposeAll();\n\t}\n\n\tconstructor(conn: AgentSideConnection, _config?: unknown) {\n\t\tthis.conn = conn;\n\t\tvoid _config;\n\t}\n\n\tasync initialize(params: InitializeRequest): Promise<InitializeResponse> {\n\t\tconst supportedVersion = 1;\n\t\tconst requested = params.protocolVersion;\n\n\t\treturn {\n\t\t\tprotocolVersion: requested === supportedVersion ? requested : supportedVersion,\n\t\t\tagentInfo: {\n\t\t\t\tname: pkg.name,\n\t\t\t\ttitle: \"pi ACP adapter\",\n\t\t\t\tversion: pkg.version,\n\t\t\t},\n\t\t\tauthMethods: buildAuthMethods({\n\t\t\t\tsupportsTerminalAuthMeta: params.clientCapabilities?._meta?.[\"terminal-auth\"] === true,\n\t\t\t}),\n\t\t\tagentCapabilities: {\n\t\t\t\tloadSession: true,\n\t\t\t\tmcpCapabilities: { http: false, sse: false },\n\t\t\t\tpromptCapabilities: {\n\t\t\t\t\timage: true,\n\t\t\t\t\taudio: false,\n\t\t\t\t\tembeddedContext: false,\n\t\t\t\t},\n\t\t\t\tsessionCapabilities: {\n\t\t\t\t\tlist: {},\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync newSession(params: NewSessionRequest) {\n\t\tif (!isAbsolute(params.cwd)) {\n\t\t\tthrow RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);\n\t\t}\n\n\t\tif (!hasPiAuthConfigured()) {\n\t\t\tthrow RequestError.authRequired(\n\t\t\t\t{ authMethods: buildAuthMethods() },\n\t\t\t\t\"Configure an API key or log in with an OAuth provider.\",\n\t\t\t);\n\t\t}\n\n\t\tlet result: CreateAgentSessionResult;\n\t\ttry {\n\t\t\tresult = await createAgentSession({ cwd: params.cwd });\n\t\t} catch (e: unknown) {\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to create pi session: ${msg}`);\n\t\t}\n\n\t\tconst piSession = result.session;\n\n\t\tconst availableModels = piSession.modelRegistry.getAvailable();\n\t\tif (availableModels.length === 0) {\n\t\t\tpiSession.dispose();\n\t\t\tthrow RequestError.authRequired(\n\t\t\t\t{ authMethods: buildAuthMethods() },\n\t\t\t\t\"Configure an API key or log in with an OAuth provider.\",\n\t\t\t);\n\t\t}\n\n\t\tconst sessionId = piSession.sessionManager.getSessionId();\n\n\t\tconst session = new PiAcpSession({\n\t\t\tsessionId,\n\t\t\tcwd: params.cwd,\n\t\t\tmcpServers: params.mcpServers,\n\t\t\tpiSession,\n\t\t\tconn: this.conn,\n\t\t});\n\n\t\tthis.sessions.register(session);\n\n\t\tconst quietStartup = quietStartupEnabled(params.cwd);\n\t\tconst updateNotice = buildUpdateNotice();\n\n\t\tconst preludeText = quietStartup\n\t\t\t? updateNotice !== null\n\t\t\t\t? `${updateNotice}\\n`\n\t\t\t\t: \"\"\n\t\t\t: buildStartupInfo({ cwd: params.cwd, updateNotice });\n\n\t\tif (preludeText) session.setStartupInfo(preludeText);\n\n\t\tthis.sessions.closeAllExcept(session.sessionId);\n\n\t\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tconst response = {\n\t\t\tsessionId: session.sessionId,\n\t\t\tconfigOptions,\n\t\t\tmodes,\n\t\t\tmodels,\n\t\t\t_meta: {\n\t\t\t\tpiAcp: { startupInfo: preludeText || null },\n\t\t\t},\n\t\t};\n\n\t\tif (preludeText) setTimeout(() => session.sendStartupInfoIfPending(), 0);\n\n\t\tconst enableSkillCommands = skillCommandsEnabled(params.cwd);\n\t\tsetTimeout(() => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst commands = buildCommandList(piSession, enableSkillCommands);\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tsessionUpdate: \"available_commands_update\",\n\t\t\t\t\t\t\tavailableCommands: mergeCommands(commands, builtinAvailableCommands()),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch {}\n\t\t\t})();\n\t\t}, 0);\n\n\t\treturn response;\n\t}\n\n\tasync authenticate(_params: AuthenticateRequest) {\n\t\treturn;\n\t}\n\n\tasync prompt(params: PromptRequest): Promise<PromptResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst { message, images } = acpPromptToPiMessage(params.prompt);\n\n\t\tif (images.length === 0 && message.trimStart().startsWith(\"/\")) {\n\t\t\tconst trimmed = message.trim();\n\t\t\tconst space = trimmed.indexOf(\" \");\n\t\t\tconst cmd = space === -1 ? trimmed.slice(1) : trimmed.slice(1, space);\n\t\t\tconst argsString = space === -1 ? \"\" : trimmed.slice(space + 1);\n\t\t\tconst args = parseArgs(argsString);\n\n\t\t\tconst handled = await this.handleBuiltinCommand(session, cmd, args);\n\t\t\tif (handled) return handled;\n\t\t}\n\n\t\tconst result = await session.prompt(message, images);\n\n\t\tconst stopReason: StopReason = result === \"error\" ? \"end_turn\" : result;\n\n\t\treturn { stopReason };\n\t}\n\n\tasync cancel(params: CancelNotification): Promise<void> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tawait session.cancel();\n\t}\n\n\tasync listSessions(params: ListSessionsRequest): Promise<ListSessionsResponse> {\n\t\tconst cwd = params.cwd;\n\n\t\tconst raw =\n\t\t\tcwd !== undefined && cwd !== null\n\t\t\t\t? await PiSessionManager.list(cwd)\n\t\t\t\t: await PiSessionManager.listAll();\n\t\tconst sessions = raw.map((s) => ({\n\t\t\tid: s.id,\n\t\t\tcwd: s.cwd,\n\t\t\tname: s.name ?? \"\",\n\t\t\tmodified: s.modified,\n\t\t\tmessageCount: s.messageCount,\n\t\t}));\n\n\t\tif (params.cursor !== undefined && params.cursor !== null) {\n\t\t\tconst parsed = Number.parseInt(params.cursor, 10);\n\t\t\tif (!Number.isFinite(parsed) || parsed < 0) {\n\t\t\t\tthrow RequestError.invalidParams(`Invalid cursor: ${params.cursor}`);\n\t\t\t}\n\t\t}\n\n\t\tconst start =\n\t\t\tparams.cursor !== undefined && params.cursor !== null\n\t\t\t\t? Number.parseInt(params.cursor, 10)\n\t\t\t\t: 0;\n\n\t\tconst PAGE_SIZE = 50;\n\t\tconst page = sessions.slice(start, start + PAGE_SIZE);\n\n\t\tconst acpSessions: SessionInfo[] = page.map((s) => ({\n\t\t\tsessionId: s.id,\n\t\t\tcwd: s.cwd,\n\t\t\ttitle: s.name ?? null,\n\t\t\tupdatedAt: s.modified.toISOString(),\n\t\t}));\n\n\t\tconst nextCursor = start + PAGE_SIZE < sessions.length ? String(start + PAGE_SIZE) : null;\n\n\t\treturn { sessions: acpSessions, nextCursor, _meta: {} };\n\t}\n\n\tasync loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse> {\n\t\tif (!isAbsolute(params.cwd)) {\n\t\t\tthrow RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);\n\t\t}\n\n\t\tthis.sessions.close(params.sessionId);\n\n\t\tconst sessionFile = findPiSessionFile(params.sessionId);\n\t\tif (sessionFile === null) {\n\t\t\tthrow RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);\n\t\t}\n\n\t\tlet result: CreateAgentSessionResult;\n\t\ttry {\n\t\t\tconst sm = PiSessionManager.open(sessionFile);\n\t\t\tresult = await createAgentSession({\n\t\t\t\tcwd: params.cwd,\n\t\t\t\tsessionManager: sm,\n\t\t\t});\n\t\t} catch (e: unknown) {\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to load pi session: ${msg}`);\n\t\t}\n\n\t\tconst piSession = result.session;\n\n\t\tconst session = new PiAcpSession({\n\t\t\tsessionId: params.sessionId,\n\t\t\tcwd: params.cwd,\n\t\t\tmcpServers: params.mcpServers,\n\t\t\tpiSession,\n\t\t\tconn: this.conn,\n\t\t});\n\n\t\tthis.sessions.register(session);\n\t\tthis.sessions.closeAllExcept(session.sessionId);\n\n\t\tconst messages: AgentMessage[] = piSession.messages;\n\t\tfor (const m of messages) {\n\t\t\tif (!(\"role\" in m)) continue;\n\n\t\t\tif (m.role === \"user\") {\n\t\t\t\tconst text = extractUserMessageText((m satisfies UserMessage).content);\n\t\t\t\tif (text) {\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: { sessionUpdate: \"user_message_chunk\", content: { type: \"text\", text } },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m.role === \"assistant\") {\n\t\t\t\tconst text = extractAssistantText((m satisfies AssistantMessage).content);\n\t\t\t\tif (text) {\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\tconst tr = m satisfies ToolResultMessage;\n\t\t\t\tconst toolName = tr.toolName;\n\t\t\t\tconst toolCallId = tr.toolCallId;\n\t\t\t\tconst isError = tr.isError;\n\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\ttitle: toolName,\n\t\t\t\t\t\tkind:\n\t\t\t\t\t\t\ttoolName === \"read\"\n\t\t\t\t\t\t\t\t? \"read\"\n\t\t\t\t\t\t\t\t: toolName === \"write\" || toolName === \"edit\"\n\t\t\t\t\t\t\t\t\t? \"edit\"\n\t\t\t\t\t\t\t\t\t: \"other\",\n\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\trawInput: null,\n\t\t\t\t\t\trawOutput: m,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst text = toolResultToText(m);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\tstatus: isError ? \"failed\" : \"completed\",\n\t\t\t\t\t\tcontent: text ? [{ type: \"content\", content: { type: \"text\", text } }] : null,\n\t\t\t\t\t\trawOutput: m,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tconst enableSkillCommands = skillCommandsEnabled(params.cwd);\n\t\tsetTimeout(() => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst commands = buildCommandList(piSession, enableSkillCommands);\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tsessionUpdate: \"available_commands_update\",\n\t\t\t\t\t\t\tavailableCommands: mergeCommands(commands, builtinAvailableCommands()),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch {}\n\t\t\t})();\n\t\t}, 0);\n\n\t\treturn {\n\t\t\tconfigOptions,\n\t\t\tmodes,\n\t\t\tmodels,\n\t\t\t_meta: { piAcp: { startupInfo: null } },\n\t\t};\n\t}\n\n\tasync setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst mode = String(params.modeId);\n\t\tif (!isThinkingLevel(mode)) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modeId: ${mode}`);\n\t\t}\n\n\t\tsession.piSession.setThinkingLevel(mode);\n\n\t\tvoid this.conn.sessionUpdate({\n\t\t\tsessionId: session.sessionId,\n\t\t\tupdate: { sessionUpdate: \"current_mode_update\", currentModeId: mode },\n\t\t});\n\n\t\tthis.emitConfigOptionUpdate(session);\n\n\t\treturn {};\n\t}\n\n\tasync unstable_setSessionModel(\n\t\tparams: SetSessionModelRequest,\n\t): Promise<SetSessionModelResponse | void> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\n\t\tlet provider: string | null = null;\n\t\tlet modelId: string | null = null;\n\n\t\tif (params.modelId.includes(\"/\")) {\n\t\t\tconst [p, ...rest] = params.modelId.split(\"/\");\n\t\t\tprovider = p ?? null;\n\t\t\tmodelId = rest.join(\"/\");\n\t\t} else {\n\t\t\tmodelId = params.modelId;\n\t\t}\n\n\t\tif (provider === null) {\n\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\tconst found = available.find((m) => m.id === modelId);\n\t\t\tif (found) {\n\t\t\t\tprovider = found.provider;\n\t\t\t\tmodelId = found.id;\n\t\t\t}\n\t\t}\n\n\t\tif (provider === null || modelId === null) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modelId: ${params.modelId}`);\n\t\t}\n\n\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\tconst model = available.find((m) => m.provider === provider && m.id === modelId);\n\t\tif (!model) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modelId: ${params.modelId}`);\n\t\t}\n\n\t\tawait session.piSession.setModel(model);\n\t\tthis.emitConfigOptionUpdate(session);\n\t}\n\n\tasync setSessionConfigOption(\n\t\tparams: SetSessionConfigOptionRequest,\n\t): Promise<SetSessionConfigOptionResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst configId = String(params.configId);\n\t\tconst value = String(params.value);\n\n\t\tif (configId === \"model\") {\n\t\t\tlet provider: string | null = null;\n\t\t\tlet modelId: string | null = null;\n\n\t\t\tif (value.includes(\"/\")) {\n\t\t\t\tconst [p, ...rest] = value.split(\"/\");\n\t\t\t\tprovider = p ?? null;\n\t\t\t\tmodelId = rest.join(\"/\");\n\t\t\t} else {\n\t\t\t\tmodelId = value;\n\t\t\t}\n\n\t\t\tif (provider === null) {\n\t\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\t\tconst found = available.find((m) => m.id === modelId);\n\t\t\t\tif (found) {\n\t\t\t\t\tprovider = found.provider;\n\t\t\t\t\tmodelId = found.id;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (provider === null || modelId === null) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t}\n\n\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\tconst model = available.find((m) => m.provider === provider && m.id === modelId);\n\t\t\tif (!model) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t}\n\n\t\t\tawait session.piSession.setModel(model);\n\t\t} else if (configId === \"thought_level\") {\n\t\t\tif (!isThinkingLevel(value)) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown thinking level: ${value}`);\n\t\t\t}\n\t\t\tsession.piSession.setThinkingLevel(value);\n\t\t} else {\n\t\t\tthrow RequestError.invalidParams(`Unknown config option: ${configId}`);\n\t\t}\n\n\t\tconst modes = buildThinkingModes(session.piSession);\n\t\tconst models = buildModelState(session.piSession);\n\t\treturn { configOptions: buildConfigOptions(modes, models) };\n\t}\n\n\tprivate emitConfigOptionUpdate(session: PiAcpSession): void {\n\t\tconst modes = buildThinkingModes(session.piSession);\n\t\tconst models = buildModelState(session.piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tvoid this.conn.sessionUpdate({\n\t\t\tsessionId: session.sessionId,\n\t\t\tupdate: {\n\t\t\t\tsessionUpdate: \"config_option_update\",\n\t\t\t\tconfigOptions,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async handleBuiltinCommand(\n\t\tsession: PiAcpSession,\n\t\tcmd: string,\n\t\targs: string[],\n\t): Promise<PromptResponse | null> {\n\t\tconst piSession = session.piSession;\n\n\t\tif (cmd === \"compact\") {\n\t\t\tconst customInstructions = args.join(\" \").trim() || undefined;\n\t\t\tconst res = await piSession.compact(customInstructions);\n\n\t\t\tconst headerLines = [\n\t\t\t\t`Compaction completed.${customInstructions !== undefined && customInstructions !== \"\" ? \" (custom instructions applied)\" : \"\"}`,\n\t\t\t\ttypeof res?.tokensBefore === \"number\" ? `Tokens before: ${res.tokensBefore}` : null,\n\t\t\t].filter(Boolean);\n\n\t\t\tconst text = headerLines.join(\"\\n\") + (res?.summary ? `\\n\\n${res.summary}` : \"\");\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"session\") {\n\t\t\tconst stats = piSession.getSessionStats();\n\t\t\tconst lines: string[] = [];\n\t\t\tif (stats.sessionId !== undefined && stats.sessionId !== \"\")\n\t\t\t\tlines.push(`Session: ${stats.sessionId}`);\n\t\t\tif (stats.sessionFile !== undefined && stats.sessionFile !== \"\")\n\t\t\t\tlines.push(`Session file: ${stats.sessionFile}`);\n\t\t\tlines.push(`Messages: ${stats.totalMessages}`);\n\t\t\tlines.push(`Cost: ${stats.cost}`);\n\t\t\tconst t = stats.tokens;\n\t\t\tconst parts: string[] = [];\n\t\t\tif (t.input) parts.push(`in ${t.input}`);\n\t\t\tif (t.output) parts.push(`out ${t.output}`);\n\t\t\tif (t.cacheRead) parts.push(`cache read ${t.cacheRead}`);\n\t\t\tif (t.cacheWrite) parts.push(`cache write ${t.cacheWrite}`);\n\t\t\tif (t.total) parts.push(`total ${t.total}`);\n\t\t\tif (parts.length > 0) lines.push(`Tokens: ${parts.join(\", \")}`);\n\n\t\t\tconst text = lines.join(\"\\n\");\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"name\") {\n\t\t\tconst name = args.join(\" \").trim();\n\t\t\tif (!name) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /name <name>\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tpiSession.setSessionName(name);\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"session_info_update\",\n\t\t\t\t\ttitle: name,\n\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Session name set: ${name}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"steering\") {\n\t\t\tconst modeRaw = String(args[0] ?? \"\").toLowerCase();\n\t\t\tif (!modeRaw) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Steering mode: ${piSession.steeringMode}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tif (modeRaw !== \"all\" && modeRaw !== \"one-at-a-time\") {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /steering all | /steering one-at-a-time\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tpiSession.setSteeringMode(modeRaw);\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Steering mode set to: ${modeRaw}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"follow-up\") {\n\t\t\tconst modeRaw = String(args[0] ?? \"\").toLowerCase();\n\t\t\tif (!modeRaw) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Follow-up mode: ${piSession.followUpMode}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tif (modeRaw !== \"all\" && modeRaw !== \"one-at-a-time\") {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /follow-up all | /follow-up one-at-a-time\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tpiSession.setFollowUpMode(modeRaw);\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Follow-up mode set to: ${modeRaw}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"autocompact\") {\n\t\t\tconst mode = (args[0] ?? \"toggle\").toLowerCase();\n\t\t\tlet enabled: boolean | null = null;\n\t\t\tif (mode === \"on\" || mode === \"true\" || mode === \"enable\") enabled = true;\n\t\t\telse if (mode === \"off\" || mode === \"false\" || mode === \"disable\") enabled = false;\n\n\t\t\tif (enabled === null) {\n\t\t\t\tenabled = !piSession.autoCompactionEnabled;\n\t\t\t}\n\n\t\t\tpiSession.setAutoCompactionEnabled(enabled);\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Auto-compaction ${enabled ? \"enabled\" : \"disabled\"}.` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"changelog\") {\n\t\t\tconst changelogPath = findChangelog();\n\t\t\tif (changelogPath === null) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Changelog not found.\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tlet text = \"\";\n\t\t\ttry {\n\t\t\t\ttext = readFileSync(changelogPath, \"utf-8\");\n\t\t\t} catch (e: unknown) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Failed to read changelog: ${msg}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tconst maxChars = 20_000;\n\t\t\tif (text.length > maxChars) text = `${text.slice(0, maxChars)}\\n\\n...(truncated)...`;\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"export\") {\n\t\t\tconst messageCount = piSession.messages.length;\n\t\t\tif (messageCount === 0) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Nothing to export yet. Send a prompt first.\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst safeSessionId = session.sessionId.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n\t\t\t\tconst outputPath = join(session.cwd, `pi-session-${safeSessionId}.html`);\n\t\t\t\tconst resultPath = await piSession.exportToHtml(outputPath);\n\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Session exported: \" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\ttype: \"resource_link\",\n\t\t\t\t\t\t\tname: `pi-session-${safeSessionId}.html`,\n\t\t\t\t\t\t\turi: `file://${resultPath}`,\n\t\t\t\t\t\t\tmimeType: \"text/html\",\n\t\t\t\t\t\t\ttitle: \"Session exported\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (e: unknown) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Export failed: ${msg}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nfunction isThinkingLevel(x: string): x is ThinkingLevel {\n\treturn (\n\t\tx === \"off\" || x === \"minimal\" || x === \"low\" || x === \"medium\" || x === \"high\" || x === \"xhigh\"\n\t);\n}\n\nfunction buildThinkingModes(piSession: AgentSession): {\n\tavailableModes: Array<{ id: string; name: string; description?: string | null }>;\n\tcurrentModeId: string;\n} {\n\tconst levels = piSession.getAvailableThinkingLevels();\n\treturn {\n\t\tcurrentModeId: piSession.thinkingLevel,\n\t\tavailableModes: levels.map((id) => ({\n\t\t\tid,\n\t\t\tname: `Thinking: ${id}`,\n\t\t\tdescription: null,\n\t\t})),\n\t};\n}\n\nfunction buildModelState(piSession: AgentSession): SessionModelState {\n\tconst available = piSession.modelRegistry.getAvailable();\n\tconst current = piSession.model;\n\n\tconst availableModels: ModelInfo[] = available.map((m) => ({\n\t\tmodelId: `${m.provider}/${m.id}`,\n\t\tname: `${m.provider}/${m.name ?? m.id}`,\n\t\tdescription: null,\n\t}));\n\n\tlet currentModelId = \"default\";\n\tif (current !== undefined) {\n\t\tcurrentModelId = `${current.provider}/${current.id}`;\n\t} else if (availableModels.length > 0 && availableModels[0] !== undefined) {\n\t\tcurrentModelId = availableModels[0].modelId;\n\t}\n\n\treturn { availableModels, currentModelId };\n}\n\nfunction buildConfigOptions(\n\tmodes: SessionModeState,\n\tmodels: SessionModelState,\n): SessionConfigOption[] {\n\treturn [\n\t\t{\n\t\t\tid: \"model\",\n\t\t\tname: \"Model\",\n\t\t\tdescription: \"AI model to use\",\n\t\t\tcategory: \"model\",\n\t\t\ttype: \"select\" as const,\n\t\t\tcurrentValue: models.currentModelId,\n\t\t\toptions: models.availableModels.map((m) => ({\n\t\t\t\tvalue: m.modelId,\n\t\t\t\tname: m.name,\n\t\t\t\tdescription: m.description ?? null,\n\t\t\t})),\n\t\t},\n\t\t{\n\t\t\tid: \"thought_level\",\n\t\t\tname: \"Thinking Level\",\n\t\t\tdescription: \"Reasoning depth for models that support it\",\n\t\t\tcategory: \"thought_level\",\n\t\t\ttype: \"select\" as const,\n\t\t\tcurrentValue: modes.currentModeId,\n\t\t\toptions: modes.availableModes.map((m) => ({\n\t\t\t\tvalue: m.id,\n\t\t\t\tname: m.name,\n\t\t\t\tdescription: m.description ?? null,\n\t\t\t})),\n\t\t},\n\t];\n}\n\nfunction buildCommandList(\n\tpiSession: AgentSession,\n\tenableSkillCommands: boolean,\n): AvailableCommand[] {\n\tconst commands: AvailableCommand[] = [];\n\n\tfor (const template of piSession.promptTemplates) {\n\t\tcommands.push({\n\t\t\tname: template.name,\n\t\t\tdescription: template.description ?? `(prompt)`,\n\t\t});\n\t}\n\n\tif (enableSkillCommands) {\n\t\tconst skills = piSession.resourceLoader.getSkills();\n\t\tfor (const skill of skills.skills) {\n\t\t\tcommands.push({\n\t\t\t\tname: `skill:${skill.name}`,\n\t\t\t\tdescription: skill.description ?? `(skill)`,\n\t\t\t});\n\t\t}\n\t}\n\n\tconst runner = piSession.extensionRunner;\n\tif (runner) {\n\t\tfor (const { command } of runner.getRegisteredCommandsWithPaths()) {\n\t\t\tcommands.push({\n\t\t\t\tname: command.name,\n\t\t\t\tdescription: command.description ?? `(extension)`,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn commands;\n}\n\nfunction findPiSessionFile(sessionId: string): string | null {\n\tconst sessionsDir = join(piAgentDir(), \"sessions\");\n\tif (!existsSync(sessionsDir)) return null;\n\n\tconst walkJsonl = (dir: string): string | null => {\n\t\tlet entries: string[];\n\t\ttry {\n\t\t\tentries = readdirSync(dir);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\n\t\tfor (const name of entries) {\n\t\t\tconst p = join(dir, name);\n\t\t\ttry {\n\t\t\t\tconst st = statSync(p);\n\t\t\t\tif (st.isDirectory()) {\n\t\t\t\t\tconst found = walkJsonl(p);\n\t\t\t\t\tif (found !== undefined) return found;\n\t\t\t\t} else if (st.isFile() && name.endsWith(\".jsonl\")) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst firstLine = readFileSync(p, \"utf8\").split(\"\\n\")[0];\n\t\t\t\t\t\tif (firstLine === undefined) continue;\n\t\t\t\t\t\tconst header: unknown = JSON.parse(firstLine);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\ttypeof header === \"object\" &&\n\t\t\t\t\t\t\theader !== null &&\n\t\t\t\t\t\t\t\"type\" in header &&\n\t\t\t\t\t\t\theader.type === \"session\" &&\n\t\t\t\t\t\t\t\"id\" in header &&\n\t\t\t\t\t\t\theader.id === sessionId\n\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn p;\n\t\t\t\t\t} catch {}\n\t\t\t\t}\n\t\t\t} catch {}\n\t\t}\n\t\treturn null;\n\t};\n\n\treturn walkJsonl(sessionsDir);\n}\n\nfunction buildUpdateNotice(): string | null {\n\ttry {\n\t\tconst installed = PI_VERSION;\n\t\tif (!installed || !isSemver(installed)) return null;\n\n\t\tconst latestRes = spawnSync(\"npm\", [\"view\", \"@mariozechner/pi-coding-agent\", \"version\"], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 800,\n\t\t});\n\t\tconst latest = String(latestRes.stdout ?? \"\")\n\t\t\t.trim()\n\t\t\t.replace(/^v/i, \"\");\n\t\tif (!latest || !isSemver(latest)) return null;\n\t\tif (compareSemver(latest, installed) <= 0) return null;\n\n\t\treturn `New version available: v${latest} (installed v${installed}). Run: \\`npm i -g @mariozechner/pi-coding-agent\\``;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildStartupInfo(opts: { cwd: string; updateNotice: string | null }): string {\n\tconst md: string[] = [];\n\n\tif (PI_VERSION) {\n\t\tmd.push(`pi v${PI_VERSION}`);\n\t\tmd.push(\"---\");\n\t\tmd.push(\"\");\n\t}\n\n\tconst addSection = (title: string, items: string[]) => {\n\t\tconst cleaned = items.map((s) => s.trim()).filter(Boolean);\n\t\tif (cleaned.length === 0) return;\n\t\tmd.push(`## ${title}`);\n\t\tfor (const item of cleaned) md.push(`- ${item}`);\n\t\tmd.push(\"\");\n\t};\n\n\tconst contextItems: string[] = [];\n\tconst contextPath = join(opts.cwd, \"AGENTS.md\");\n\tif (existsSync(contextPath)) contextItems.push(contextPath);\n\taddSection(\"Context\", contextItems);\n\n\tif (opts.updateNotice !== undefined && opts.updateNotice !== null) {\n\t\tmd.push(\"---\");\n\t\tmd.push(opts.updateNotice);\n\t\tmd.push(\"\");\n\t}\n\n\treturn `${md.join(\"\\n\").trim()}\\n`;\n}\n\nfunction findChangelog(): string | null {\n\ttry {\n\t\tconst whichCmd = process.platform === \"win32\" ? \"where\" : \"which\";\n\t\tconst which = spawnSync(whichCmd, [\"pi\"], { encoding: \"utf-8\" });\n\t\tconst piPath = String(which.stdout ?? \"\")\n\t\t\t.split(/\\r?\\n/)[0]\n\t\t\t?.trim();\n\t\tif (piPath !== undefined && piPath !== \"\") {\n\t\t\tconst resolved = realpathSync(piPath);\n\t\t\tconst pkgRoot = dirname(dirname(resolved));\n\t\t\tconst p = join(pkgRoot, \"CHANGELOG.md\");\n\t\t\tif (existsSync(p)) return p;\n\t\t}\n\t} catch {}\n\n\ttry {\n\t\tconst npmRoot = spawnSync(\"npm\", [\"root\", \"-g\"], { encoding: \"utf-8\" });\n\t\tconst root = String(npmRoot.stdout ?? \"\").trim();\n\t\tif (root) {\n\t\t\tconst p = join(root, \"@mariozechner\", \"pi-coding-agent\", \"CHANGELOG.md\");\n\t\t\tif (existsSync(p)) return p;\n\t\t}\n\t} catch {}\n\n\treturn null;\n}\n\nfunction isSemver(v: string): boolean {\n\treturn /^\\d+\\.\\d+\\.\\d+(?:[-+].+)?$/.test(v);\n}\n\nfunction compareSemver(a: string, b: string): number {\n\tconst pa = a\n\t\t.split(/[.-]/)\n\t\t.slice(0, 3)\n\t\t.map((n) => Number(n));\n\tconst pb = b\n\t\t.split(/[.-]/)\n\t\t.slice(0, 3)\n\t\t.map((n) => Number(n));\n\tfor (let i = 0; i < 3; i++) {\n\t\tconst da = pa[i] ?? 0;\n\t\tconst db = pb[i] ?? 0;\n\t\tif (da > db) return 1;\n\t\tif (da < db) return -1;\n\t}\n\treturn 0;\n}\n\nfunction readNearestPackageJson(metaUrl: string): { name: string; version: string } {\n\tconst fallback = { name: \"pi-acp\", version: \"0.0.0\" };\n\ttry {\n\t\tlet dir = dirname(fileURLToPath(metaUrl));\n\t\tfor (let i = 0; i < 6; i++) {\n\t\t\tconst p = join(dir, \"package.json\");\n\t\t\tif (existsSync(p)) {\n\t\t\t\tconst raw: unknown = JSON.parse(readFileSync(p, \"utf-8\"));\n\t\t\t\tif (typeof raw !== \"object\" || raw === null) return fallback;\n\t\t\t\tconst name = \"name\" in raw && typeof raw.name === \"string\" ? raw.name : fallback.name;\n\t\t\t\tconst version =\n\t\t\t\t\t\"version\" in raw && typeof raw.version === \"string\" ? raw.version : fallback.version;\n\t\t\t\treturn { name, version };\n\t\t\t}\n\t\t\tdir = dirname(dir);\n\t\t}\n\t} catch {\n\t\t// fall through\n\t}\n\treturn fallback;\n}\n","import { platform } from \"node:os\";\nimport { AgentSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\";\nimport { PiAcpAgent } from \"./acp/agent.js\";\n\n// Terminal Auth entrypoint: ACP client launches with `--terminal-login`.\nif (process.argv.includes(\"--terminal-login\")) {\n\tconst { spawnSync } = await import(\"node:child_process\");\n\tconst isWindows = platform() === \"win32\";\n\tconst cmd = process.env.PI_ACP_PI_COMMAND ?? (isWindows ? \"pi.cmd\" : \"pi\");\n\tconst res = spawnSync(cmd, [], { stdio: \"inherit\", env: process.env });\n\n\tif (res.error && \"code\" in res.error && res.error.code === \"ENOENT\") {\n\t\tprocess.stderr.write(\n\t\t\t`pi-acp: could not start pi (command not found: ${cmd}). ` +\n\t\t\t\t\"Install via `npm install -g @mariozechner/pi-coding-agent` \" +\n\t\t\t\t\"or ensure `pi` is on your PATH.\\n\",\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tprocess.exit(typeof res.status === \"number\" ? res.status : 1);\n}\n\nconst input = new WritableStream<Uint8Array>({\n\twrite(chunk) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tif (process.stdout.destroyed || !process.stdout.writable) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tprocess.stdout.write(chunk, () => resolve());\n\t\t\t} catch {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t},\n});\n\nconst output = new ReadableStream<Uint8Array>({\n\tstart(controller) {\n\t\tprocess.stdin.on(\"data\", (chunk: Buffer) => controller.enqueue(new Uint8Array(chunk)));\n\t\tprocess.stdin.on(\"end\", () => controller.close());\n\t\tprocess.stdin.on(\"error\", (err) => controller.error(err));\n\t},\n});\n\nconst stream = ndJsonStream(input, output);\nconst agent = new AgentSideConnection((conn) => new PiAcpAgent(conn), stream);\n\nfunction shutdown() {\n\ttry {\n\t\t// AgentSideConnection stores the agent instance internally;\n\t\t// call dispose() on it if available for clean shutdown.\n\t\tif (\"agent\" in agent) {\n\t\t\tconst inner: unknown = agent.agent;\n\t\t\tif (\n\t\t\t\ttypeof inner === \"object\" &&\n\t\t\t\tinner !== null &&\n\t\t\t\t\"dispose\" in inner &&\n\t\t\t\ttypeof inner.dispose === \"function\"\n\t\t\t) {\n\t\t\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-call -- runtime-guarded\n\t\t\t\tinner.dispose();\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// best-effort cleanup\n\t}\n\tprocess.exit(0);\n}\n\nprocess.stdin.on(\"end\", shutdown);\nprocess.stdin.on(\"close\", shutdown);\nprocess.stdin.resume();\nprocess.on(\"SIGINT\", shutdown);\nprocess.on(\"SIGTERM\", shutdown);\nprocess.stdout.on(\"error\", () => process.exit(0));\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["resolvePath","SessionManager","SessionManager","PiSessionManager","PI_VERSION"],"sources":["../src/acp/auth.ts","../src/acp/pi-settings.ts","../src/acp/translate/pi-tools.ts","../src/acp/session.ts","../src/acp/translate/pi-messages.ts","../src/acp/translate/prompt.ts","../src/pi-auth/status.ts","../src/acp/agent.ts","../src/index.ts"],"sourcesContent":["/**\n * Build ACP AuthMethod descriptors for terminal-based authentication.\n *\n * Supports both the registry-required \"type/args/env\" shape and Zed's\n * _meta[\"terminal-auth\"] extension for the Authenticate banner.\n */\n\nimport type { AuthMethod } from \"@agentclientprotocol/sdk\";\n\nexport const AUTH_METHOD_ID = \"pi_terminal_login\";\n\ninterface AuthMethodOptions {\n\tsupportsTerminalAuthMeta?: boolean;\n}\n\nexport function buildAuthMethods(opts?: AuthMethodOptions): AuthMethod[] {\n\tconst supportsTerminalAuthMeta = opts?.supportsTerminalAuthMeta ?? true;\n\n\tconst method: AuthMethod = {\n\t\tid: AUTH_METHOD_ID,\n\t\tname: \"Launch pi in the terminal\",\n\t\tdescription: \"Start pi in an interactive terminal to configure API keys or login\",\n\t\ttype: \"terminal\",\n\t\targs: [\"--terminal-login\"],\n\t\tenv: {},\n\t};\n\n\tif (supportsTerminalAuthMeta) {\n\t\tconst launch = resolveTerminalLaunchCommand();\n\t\tmethod._meta = {\n\t\t\t\"terminal-auth\": {\n\t\t\t\t...launch,\n\t\t\t\tlabel: \"Launch pi\",\n\t\t\t},\n\t\t};\n\t}\n\n\treturn [method];\n}\n\nfunction resolveTerminalLaunchCommand(): { command: string; args: string[] } {\n\tconst argv0 = process.argv[0] ?? \"node\";\n\tconst argv1 = process.argv[1];\n\n\tif (argv1 !== undefined && argv0.includes(\"node\") && argv1.endsWith(\".js\")) {\n\t\treturn { command: argv0, args: [argv1, \"--terminal-login\"] };\n\t}\n\n\treturn { command: \"pi-acp\", args: [\"--terminal-login\"] };\n}\n","/**\n * Read pi settings from global and project config files.\n *\n * Settings are merged: project overrides global.\n * Paths follow pi-mono conventions:\n * Global: ~/.pi/agent/settings.json\n * Project: <cwd>/.pi/settings.json\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join, resolve } from \"node:path\";\nimport * as z from \"zod\";\n\nconst piSettingsSchema = z.object({\n\tenableSkillCommands: z.boolean().optional(),\n\tquietStartup: z.boolean().optional(),\n\tquietStart: z.boolean().optional(),\n\tskills: z\n\t\t.object({\n\t\t\tenableSkillCommands: z.boolean().optional(),\n\t\t})\n\t\t.optional(),\n});\n\ntype PiSettings = z.infer<typeof piSettingsSchema>;\n\nfunction isRecord(x: unknown): x is Record<string, unknown> {\n\treturn typeof x === \"object\" && x !== null && !Array.isArray(x);\n}\n\nfunction merge(\n\tbase: Record<string, unknown>,\n\toverride: Record<string, unknown>,\n): Record<string, unknown> {\n\tconst result: Record<string, unknown> = { ...base };\n\tfor (const [key, val] of Object.entries(override)) {\n\t\tconst existing = result[key];\n\t\tif (isRecord(existing) && isRecord(val)) {\n\t\t\tresult[key] = merge(existing, val);\n\t\t} else {\n\t\t\tresult[key] = val;\n\t\t}\n\t}\n\treturn result;\n}\n\nfunction readJson(path: string): Record<string, unknown> {\n\ttry {\n\t\tif (!existsSync(path)) return {};\n\t\tconst data: unknown = JSON.parse(readFileSync(path, \"utf-8\"));\n\t\treturn isRecord(data) ? data : {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nexport function piAgentDir(): string {\n\treturn process.env.PI_CODING_AGENT_DIR !== undefined\n\t\t? resolve(process.env.PI_CODING_AGENT_DIR)\n\t\t: join(homedir(), \".pi\", \"agent\");\n}\n\nfunction resolvedSettings(cwd: string): PiSettings {\n\tconst globalPath = join(piAgentDir(), \"settings.json\");\n\tconst projectPath = resolve(cwd, \".pi\", \"settings.json\");\n\tconst merged = merge(readJson(globalPath), readJson(projectPath));\n\tconst result = piSettingsSchema.safeParse(merged);\n\treturn result.success ? result.data : {};\n}\n\nexport function skillCommandsEnabled(cwd: string): boolean {\n\tconst settings = resolvedSettings(cwd);\n\n\tif (typeof settings.enableSkillCommands === \"boolean\") {\n\t\treturn settings.enableSkillCommands;\n\t}\n\n\tif (typeof settings.skills?.enableSkillCommands === \"boolean\") {\n\t\treturn settings.skills.enableSkillCommands;\n\t}\n\n\treturn true;\n}\n\nexport function quietStartupEnabled(cwd: string): boolean {\n\tconst settings = resolvedSettings(cwd);\n\n\tif (typeof settings.quietStartup === \"boolean\") {\n\t\treturn settings.quietStartup;\n\t}\n\n\tif (typeof settings.quietStart === \"boolean\") {\n\t\treturn settings.quietStart;\n\t}\n\n\treturn false;\n}\n","/**\n * Extract displayable text from a pi tool result.\n *\n * Pi tool results have varying shapes depending on the tool. This function\n * tries content blocks first, then falls back to details fields (diff, stdout/stderr),\n * and finally JSON serialization as a last resort.\n */\n\nimport * as z from \"zod\";\n\nconst textBlockSchema = z.object({\n\ttype: z.literal(\"text\"),\n\ttext: z.string(),\n});\n\nconst toolDetailsSchema = z.object({\n\tdiff: z.string().optional(),\n\tstdout: z.string().optional(),\n\tstderr: z.string().optional(),\n\toutput: z.string().optional(),\n\texitCode: z.number().optional(),\n\tcode: z.number().optional(),\n});\n\nconst toolResultSchema = z.object({\n\tcontent: z.array(z.unknown()).optional(),\n\tdetails: toolDetailsSchema.optional(),\n\tstdout: z.string().optional(),\n\tstderr: z.string().optional(),\n\toutput: z.string().optional(),\n\texitCode: z.number().optional(),\n\tcode: z.number().optional(),\n});\n\nexport function toolResultToText(result: unknown): string {\n\tif (result === null || result === undefined || typeof result !== \"object\") return \"\";\n\n\tconst parsed = toolResultSchema.safeParse(result);\n\tif (!parsed.success) {\n\t\ttry {\n\t\t\treturn JSON.stringify(result, null, 2);\n\t\t} catch {\n\t\t\treturn String(result);\n\t\t}\n\t}\n\n\tconst r = parsed.data;\n\n\tif (r.content !== undefined) {\n\t\tconst texts = r.content\n\t\t\t.map((block) => textBlockSchema.safeParse(block))\n\t\t\t.filter((res) => res.success)\n\t\t\t.map((res) => res.data.text);\n\t\tif (texts.length > 0) return texts.join(\"\");\n\t}\n\n\tconst d = r.details;\n\n\tconst diff = d?.diff;\n\tif (diff !== undefined && diff.trim() !== \"\") return diff;\n\n\tconst stdout = d?.stdout ?? r.stdout ?? d?.output ?? r.output;\n\tconst stderr = d?.stderr ?? r.stderr;\n\tconst exitCode = d?.exitCode ?? r.exitCode ?? d?.code ?? r.code;\n\n\tconst hasStdout = stdout !== undefined && stdout.trim() !== \"\";\n\tconst hasStderr = stderr !== undefined && stderr.trim() !== \"\";\n\n\tif (hasStdout || hasStderr) {\n\t\tconst parts: string[] = [];\n\t\tif (hasStdout) parts.push(stdout);\n\t\tif (hasStderr) parts.push(`stderr:\\n${stderr}`);\n\t\tif (exitCode !== undefined) parts.push(`exit code: ${exitCode}`);\n\t\treturn parts.join(\"\\n\\n\").trimEnd();\n\t}\n\n\ttry {\n\t\treturn JSON.stringify(result, null, 2);\n\t} catch {\n\t\treturn String(result);\n\t}\n}\n","import { readFileSync } from \"node:fs\";\nimport { isAbsolute, resolve as resolvePath } from \"node:path\";\nimport {\n\ttype AgentSideConnection,\n\ttype ContentBlock,\n\ttype McpServer,\n\tRequestError,\n\ttype SessionUpdate,\n\ttype ToolCallContent,\n\ttype ToolCallLocation,\n\ttype ToolKind,\n} from \"@agentclientprotocol/sdk\";\nimport type { AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessageEvent, ToolCall } from \"@mariozechner/pi-ai\";\nimport type { AgentSession, AgentSessionEvent } from \"@mariozechner/pi-coding-agent\";\nimport { toolResultToText } from \"@pi-acp/acp/translate/pi-tools\";\nimport * as z from \"zod\";\n\nexport type StopReason = \"end_turn\" | \"cancelled\" | \"max_tokens\" | \"error\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction findUniqueLineNumber(text: string, needle: string): number | undefined {\n\tif (!needle) return undefined;\n\tconst first = text.indexOf(needle);\n\tif (first < 0) return undefined;\n\tif (text.indexOf(needle, first + needle.length) >= 0) return undefined;\n\n\tlet line = 1;\n\tfor (let i = 0; i < first; i++) {\n\t\tif (text.charCodeAt(i) === 10) line++;\n\t}\n\treturn line;\n}\n\ninterface ToolArgs {\n\tpath?: string | undefined;\n\toldText?: string | undefined;\n\t[key: string]: unknown;\n}\n\nfunction resolveToolPath(\n\targs: ToolArgs,\n\tcwd: string,\n\tline?: number,\n): ToolCallLocation[] | undefined {\n\tconst p = args.path;\n\tif (p === undefined) return undefined;\n\n\tconst resolved = isAbsolute(p) ? p : resolvePath(cwd, p);\n\treturn [{ path: resolved, ...(typeof line === \"number\" ? { line } : {}) }];\n}\n\nfunction toToolKind(toolName: string): ToolKind {\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn \"read\";\n\t\tcase \"write\":\n\t\tcase \"edit\":\n\t\t\treturn \"edit\";\n\t\tcase \"bash\":\n\t\t\treturn \"execute\";\n\t\tdefault:\n\t\t\treturn \"other\";\n\t}\n}\n\n/**\n * Map pi assistant stopReason to ACP StopReason.\n * pi: \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\"\n * ACP: \"end_turn\" | \"cancelled\" | \"max_tokens\" | \"error\"\n */\nfunction mapPiStopReason(piReason: string | null): StopReason {\n\tswitch (piReason) {\n\t\tcase \"stop\":\n\t\tcase \"toolUse\":\n\t\t\treturn \"end_turn\";\n\t\tcase \"length\":\n\t\t\treturn \"max_tokens\";\n\t\tcase \"aborted\":\n\t\t\treturn \"cancelled\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tdefault:\n\t\t\treturn \"end_turn\";\n\t}\n}\n\nfunction extractToolCallFromPartial(ame: AssistantMessageEvent): ToolCall | undefined {\n\tif (!(\"partial\" in ame)) return undefined;\n\tconst content = ame.partial.content;\n\tconst idx = \"contentIndex\" in ame ? ame.contentIndex : 0;\n\tconst block = content[idx];\n\tif (block && \"type\" in block && block.type === \"toolCall\") return block;\n\treturn undefined;\n}\n\nfunction parseToolInput(tc: ToolCall): ToolArgs {\n\treturn tc.arguments;\n}\n\nconst toolArgsSchema = z\n\t.object({\n\t\tpath: z.string().trim().optional(),\n\t\toldText: z.string().trim().optional(),\n\t})\n\t.loose();\n\nfunction toToolArgs(raw: unknown): ToolArgs {\n\tconst result = toolArgsSchema.safeParse(raw);\n\treturn result.success ? result.data : {};\n}\n\n// ---------------------------------------------------------------------------\n// Session manager\n// ---------------------------------------------------------------------------\n\nexport class SessionManager {\n\tprivate sessions = new Map<string, PiAcpSession>();\n\n\tdisposeAll(): void {\n\t\tfor (const id of this.sessions.keys()) this.close(id);\n\t}\n\n\tmaybeGet(sessionId: string): PiAcpSession | undefined {\n\t\treturn this.sessions.get(sessionId);\n\t}\n\n\tclose(sessionId: string): void {\n\t\tconst s = this.sessions.get(sessionId);\n\t\tif (!s) return;\n\t\ttry {\n\t\t\ts.dispose();\n\t\t} catch {\n\t\t\t// best-effort\n\t\t}\n\t\tthis.sessions.delete(sessionId);\n\t}\n\n\tcloseAllExcept(keepSessionId: string): void {\n\t\tfor (const id of this.sessions.keys()) {\n\t\t\tif (id !== keepSessionId) this.close(id);\n\t\t}\n\t}\n\n\tregister(session: PiAcpSession): void {\n\t\tthis.sessions.set(session.sessionId, session);\n\t}\n\n\tget(sessionId: string): PiAcpSession {\n\t\tconst s = this.sessions.get(sessionId);\n\t\tif (!s) throw RequestError.invalidParams(`Unknown sessionId: ${sessionId}`);\n\t\treturn s;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// ACP session wrapping a pi AgentSession\n// ---------------------------------------------------------------------------\n\ninterface PiAcpSessionOpts {\n\tsessionId: string;\n\tcwd: string;\n\tmcpServers: McpServer[];\n\tpiSession: AgentSession;\n\tconn: AgentSideConnection;\n}\n\nexport class PiAcpSession {\n\treadonly sessionId: string;\n\treadonly cwd: string;\n\treadonly mcpServers: McpServer[];\n\treadonly piSession: AgentSession;\n\n\tprivate startupInfo: string | null = null;\n\tprivate startupInfoSent = false;\n\tprivate readonly conn: AgentSideConnection;\n\n\tprivate cancelRequested = false;\n\tprivate pendingTurn: { resolve: (r: StopReason) => void; reject: (e: unknown) => void } | null =\n\t\tnull;\n\n\tprivate currentToolCalls = new Map<string, \"pending\" | \"in_progress\">();\n\tprivate editSnapshots = new Map<string, { path: string; oldText: string }>();\n\tprivate lastAssistantStopReason: string | null = null;\n\tprivate lastEmit: Promise<void> = Promise.resolve();\n\tprivate unsubscribe: (() => void) | undefined;\n\n\tconstructor(opts: PiAcpSessionOpts) {\n\t\tthis.sessionId = opts.sessionId;\n\t\tthis.cwd = opts.cwd;\n\t\tthis.mcpServers = opts.mcpServers;\n\t\tthis.piSession = opts.piSession;\n\t\tthis.conn = opts.conn;\n\t\tthis.unsubscribe = this.piSession.subscribe((ev: AgentSessionEvent) => this.handlePiEvent(ev));\n\t}\n\n\tdispose(): void {\n\t\tthis.unsubscribe?.();\n\t\tthis.piSession.dispose();\n\t}\n\n\tsetStartupInfo(text: string): void {\n\t\tthis.startupInfo = text;\n\t}\n\n\tsendStartupInfoIfPending(): void {\n\t\tif (this.startupInfoSent || this.startupInfo === null) return;\n\t\tthis.startupInfoSent = true;\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\tcontent: { type: \"text\", text: this.startupInfo },\n\t\t});\n\t}\n\n\tasync prompt(message: string, images: unknown[] = []): Promise<StopReason> {\n\t\tconst turnPromise = new Promise<StopReason>((resolve, reject) => {\n\t\t\tthis.cancelRequested = false;\n\t\t\tthis.pendingTurn = { resolve, reject };\n\t\t});\n\n\t\tconst imageContents = Array.isArray(images)\n\t\t\t? images.filter(\n\t\t\t\t\t(img): img is { type: \"image\"; data: string; mimeType: string } =>\n\t\t\t\t\t\ttypeof img === \"object\" && img !== null && \"type\" in img && img.type === \"image\",\n\t\t\t\t)\n\t\t\t: [];\n\n\t\tthis.piSession.prompt(message, { images: imageContents }).catch(() => {\n\t\t\tvoid this.flushEmits().finally(() => {\n\t\t\t\tconst reason: StopReason = this.cancelRequested ? \"cancelled\" : \"error\";\n\t\t\t\tthis.pendingTurn?.resolve(reason);\n\t\t\t\tthis.pendingTurn = null;\n\t\t\t});\n\t\t});\n\n\t\treturn turnPromise;\n\t}\n\n\tasync cancel(): Promise<void> {\n\t\tthis.cancelRequested = true;\n\t\tawait this.piSession.abort();\n\t}\n\n\twasCancelRequested(): boolean {\n\t\treturn this.cancelRequested;\n\t}\n\n\t// -----------------------------------------------------------------------\n\t// Internal\n\t// -----------------------------------------------------------------------\n\n\tprivate emit(update: SessionUpdate): void {\n\t\tthis.lastEmit = this.lastEmit\n\t\t\t.then(() => this.conn.sessionUpdate({ sessionId: this.sessionId, update }))\n\t\t\t.catch(() => {});\n\t}\n\n\tprivate async flushEmits(): Promise<void> {\n\t\tawait this.lastEmit;\n\t}\n\n\tprivate handlePiEvent(ev: AgentSessionEvent): void {\n\t\tif (!isAgentEvent(ev)) return;\n\n\t\tswitch (ev.type) {\n\t\t\tcase \"message_update\":\n\t\t\t\tthis.handleMessageUpdate(ev.assistantMessageEvent);\n\t\t\t\tbreak;\n\t\t\tcase \"message_end\":\n\t\t\t\tthis.handleMessageEnd(ev.message);\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_start\":\n\t\t\t\tthis.handleToolStart(ev.toolCallId, ev.toolName, toToolArgs(ev.args));\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_update\":\n\t\t\t\tthis.handleToolUpdate(ev.toolCallId, ev.partialResult);\n\t\t\t\tbreak;\n\t\t\tcase \"tool_execution_end\":\n\t\t\t\tthis.handleToolEnd(ev.toolCallId, ev.result, ev.isError);\n\t\t\t\tbreak;\n\t\t\tcase \"agent_end\":\n\t\t\t\tthis.handleAgentEnd();\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleMessageUpdate(ame: AssistantMessageEvent): void {\n\t\tif (ame.type === \"text_delta\") {\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\tcontent: { type: \"text\", text: ame.delta } satisfies ContentBlock,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (ame.type === \"thinking_delta\") {\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"agent_thought_chunk\",\n\t\t\t\tcontent: { type: \"text\", text: ame.delta } satisfies ContentBlock,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tame.type === \"toolcall_start\" ||\n\t\t\tame.type === \"toolcall_delta\" ||\n\t\t\tame.type === \"toolcall_end\"\n\t\t) {\n\t\t\tconst toolCall = ame.type === \"toolcall_end\" ? ame.toolCall : extractToolCallFromPartial(ame);\n\t\t\tif (!toolCall) return;\n\n\t\t\tconst rawInput = parseToolInput(toolCall);\n\t\t\tconst locations = resolveToolPath(rawInput, this.cwd);\n\t\t\tconst existingStatus = this.currentToolCalls.get(toolCall.id);\n\t\t\tconst status = existingStatus ?? \"pending\";\n\n\t\t\tif (!existingStatus) {\n\t\t\t\tthis.currentToolCalls.set(toolCall.id, \"pending\");\n\t\t\t\tthis.emit({\n\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\ttitle: toolCall.name,\n\t\t\t\t\tkind: toToolKind(toolCall.name),\n\t\t\t\t\tstatus,\n\t\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\t\trawInput,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.emit({\n\t\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\t\ttoolCallId: toolCall.id,\n\t\t\t\t\tstatus,\n\t\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\t\trawInput,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleMessageEnd(msg: AgentMessage): void {\n\t\tif (\"role\" in msg && msg.role === \"assistant\") {\n\t\t\tthis.lastAssistantStopReason = msg.stopReason;\n\t\t}\n\t}\n\n\tprivate handleToolStart(toolCallId: string, toolName: string, args: ToolArgs): void {\n\t\tlet line: number | undefined;\n\n\t\tif (toolName === \"edit\" && args.path !== undefined) {\n\t\t\ttry {\n\t\t\t\tconst abs = isAbsolute(args.path) ? args.path : resolvePath(this.cwd, args.path);\n\t\t\t\tconst oldText = readFileSync(abs, \"utf8\");\n\t\t\t\tthis.editSnapshots.set(toolCallId, { path: abs, oldText });\n\t\t\t\tline = findUniqueLineNumber(oldText, args.oldText ?? \"\");\n\t\t\t} catch {\n\t\t\t\t// snapshot failure is non-fatal\n\t\t\t}\n\t\t}\n\n\t\tconst locations = resolveToolPath(args, this.cwd, line);\n\n\t\tif (!this.currentToolCalls.has(toolCallId)) {\n\t\t\tthis.currentToolCalls.set(toolCallId, \"in_progress\");\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\ttoolCallId,\n\t\t\t\ttitle: toolName,\n\t\t\t\tkind: toToolKind(toolName),\n\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\trawInput: args,\n\t\t\t});\n\t\t} else {\n\t\t\tthis.currentToolCalls.set(toolCallId, \"in_progress\");\n\t\t\tthis.emit({\n\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\ttoolCallId,\n\t\t\t\tstatus: \"in_progress\",\n\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\trawInput: args,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate handleToolUpdate(toolCallId: string, partialResult: unknown): void {\n\t\tconst text = toolResultToText(partialResult);\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\ttoolCallId,\n\t\t\tstatus: \"in_progress\",\n\t\t\tcontent: text\n\t\t\t\t? ([{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[])\n\t\t\t\t: null,\n\t\t\trawOutput: partialResult,\n\t\t});\n\t}\n\n\tprivate handleToolEnd(toolCallId: string, result: unknown, isError: boolean): void {\n\t\tconst text = toolResultToText(result);\n\t\tconst snapshot = this.editSnapshots.get(toolCallId);\n\t\tlet content: ToolCallContent[] | null = null;\n\n\t\tif (!isError && snapshot) {\n\t\t\ttry {\n\t\t\t\tconst newText = readFileSync(snapshot.path, \"utf8\");\n\t\t\t\tif (newText !== snapshot.oldText) {\n\t\t\t\t\tcontent = [\n\t\t\t\t\t\t{ type: \"diff\", path: snapshot.path, oldText: snapshot.oldText, newText },\n\t\t\t\t\t\t...(text\n\t\t\t\t\t\t\t? ([{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[])\n\t\t\t\t\t\t\t: []),\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\t// fall back to text\n\t\t\t}\n\t\t}\n\n\t\tif (!content && text) {\n\t\t\tcontent = [{ type: \"content\", content: { type: \"text\", text } }] satisfies ToolCallContent[];\n\t\t}\n\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\ttoolCallId,\n\t\t\tstatus: isError ? \"failed\" : \"completed\",\n\t\t\tcontent,\n\t\t\trawOutput: result,\n\t\t});\n\n\t\tthis.currentToolCalls.delete(toolCallId);\n\t\tthis.editSnapshots.delete(toolCallId);\n\t}\n\n\tprivate handleAgentEnd(): void {\n\t\tvoid this.flushEmits().finally(() => {\n\t\t\tconst reason: StopReason = this.cancelRequested\n\t\t\t\t? \"cancelled\"\n\t\t\t\t: mapPiStopReason(this.lastAssistantStopReason);\n\t\t\tthis.lastAssistantStopReason = null;\n\t\t\tthis.pendingTurn?.resolve(reason);\n\t\t\tthis.pendingTurn = null;\n\t\t});\n\t}\n}\n\n/**\n * Type guard to narrow AgentSessionEvent to the AgentEvent subset\n * (the variants we handle). Session-specific events like auto_compaction\n * are ignored.\n */\nfunction isAgentEvent(\n\tev: AgentSessionEvent,\n): ev is Extract<\n\tAgentEvent,\n\t| { type: \"message_update\" }\n\t| { type: \"message_end\" }\n\t| { type: \"tool_execution_start\" }\n\t| { type: \"tool_execution_update\" }\n\t| { type: \"tool_execution_end\" }\n\t| { type: \"agent_end\" }\n> {\n\treturn (\n\t\tev.type === \"message_update\" ||\n\t\tev.type === \"message_end\" ||\n\t\tev.type === \"tool_execution_start\" ||\n\t\tev.type === \"tool_execution_update\" ||\n\t\tev.type === \"tool_execution_end\" ||\n\t\tev.type === \"agent_end\"\n\t);\n}\n","/**\n * Extract plain text from pi message content.\n *\n * Pi messages store content as either a string or an array of typed blocks.\n * These helpers extract the text portions for ACP session replay.\n */\n\ninterface TextBlock {\n\ttype: \"text\";\n\ttext: string;\n}\n\nfunction isTextBlock(block: unknown): block is TextBlock {\n\tif (typeof block !== \"object\" || block === null) return false;\n\treturn (\n\t\t\"type\" in block && block.type === \"text\" && \"text\" in block && typeof block.text === \"string\"\n\t);\n}\n\nexport function extractUserMessageText(content: unknown): string {\n\tif (typeof content === \"string\") return content;\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter(isTextBlock)\n\t\t.map((b) => b.text)\n\t\t.join(\"\");\n}\n\nexport function extractAssistantText(content: unknown): string {\n\tif (!Array.isArray(content)) return \"\";\n\treturn content\n\t\t.filter(isTextBlock)\n\t\t.map((b) => b.text)\n\t\t.join(\"\");\n}\n","/**\n * Convert ACP prompt ContentBlocks to a pi-compatible message string and image array.\n */\n\nimport type { ContentBlock } from \"@agentclientprotocol/sdk\";\n\nexport interface PiImage {\n\ttype: \"image\";\n\tmimeType: string;\n\tdata: string;\n}\n\nexport function acpPromptToPiMessage(blocks: ContentBlock[]): {\n\tmessage: string;\n\timages: PiImage[];\n} {\n\tlet message = \"\";\n\tconst images: PiImage[] = [];\n\n\tfor (const block of blocks) {\n\t\tswitch (block.type) {\n\t\t\tcase \"text\":\n\t\t\t\tmessage += block.text;\n\t\t\t\tbreak;\n\n\t\t\tcase \"resource_link\":\n\t\t\t\tmessage += `\\n[Context] ${block.uri}`;\n\t\t\t\tbreak;\n\n\t\t\tcase \"image\":\n\t\t\t\timages.push({\n\t\t\t\t\ttype: \"image\",\n\t\t\t\t\tmimeType: block.mimeType,\n\t\t\t\t\tdata: block.data,\n\t\t\t\t});\n\t\t\t\tbreak;\n\n\t\t\tcase \"resource\": {\n\t\t\t\tconst resource = block.resource;\n\t\t\t\tconst uri = resource.uri;\n\t\t\t\tconst mime = resource.mimeType ?? null;\n\n\t\t\t\tif (\"text\" in resource) {\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri} (${mime ?? \"text/plain\"})\\n${resource.text}`;\n\t\t\t\t} else if (\"blob\" in resource) {\n\t\t\t\t\tconst bytes = Buffer.byteLength(resource.blob, \"base64\");\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri} (${mime ?? \"application/octet-stream\"}, ${bytes} bytes)`;\n\t\t\t\t} else {\n\t\t\t\t\tmessage += `\\n[Embedded Context] ${uri}`;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"audio\": {\n\t\t\t\tconst bytes = Buffer.byteLength(block.data, \"base64\");\n\t\t\t\tmessage += `\\n[Audio] (${block.mimeType}, ${bytes} bytes) not supported`;\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn { message, images };\n}\n","/**\n * Detect whether the user has any pi authentication configured.\n *\n * Checks three sources:\n * 1. auth.json (API keys, OAuth credentials)\n * 2. models.json custom provider apiKey entries\n * 3. Known provider environment variables\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport * as z from \"zod\";\n\nconst modelsConfigSchema = z.object({\n\tproviders: z\n\t\t.record(\n\t\t\tz.string().trim(),\n\t\t\tz.object({\n\t\t\t\tapiKey: z.string().trim().optional(),\n\t\t\t}),\n\t\t)\n\t\t.optional(),\n});\n\nfunction agentDir(): string {\n\tconst env = process.env.PI_CODING_AGENT_DIR;\n\tif (env === undefined) return join(homedir(), \".pi\", \"agent\");\n\tif (env === \"~\") return homedir();\n\tif (env.startsWith(\"~/\")) return homedir() + env.slice(1);\n\treturn env;\n}\n\nfunction readJsonFile(path: string): unknown {\n\ttry {\n\t\tif (!existsSync(path)) return null;\n\t\tconst raw = readFileSync(path, \"utf-8\").trim();\n\t\tif (!raw) return null;\n\t\treturn JSON.parse(raw);\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction hasAuthJson(): boolean {\n\tconst data = readJsonFile(join(agentDir(), \"auth.json\"));\n\treturn typeof data === \"object\" && data !== null && Object.keys(data).length > 0;\n}\n\nfunction hasCustomProviderKey(): boolean {\n\tconst raw = readJsonFile(join(agentDir(), \"models.json\"));\n\tconst result = modelsConfigSchema.safeParse(raw);\n\tif (!result.success || !result.data.providers) return false;\n\n\treturn Object.values(result.data.providers).some(\n\t\t(provider) => typeof provider.apiKey === \"string\" && provider.apiKey.trim().length > 0,\n\t);\n}\n\n/** Environment variables that indicate a configured provider API key. */\nconst PROVIDER_ENV_VARS = [\n\t\"ANTHROPIC_API_KEY\",\n\t\"ANTHROPIC_OAUTH_TOKEN\",\n\t\"OPENAI_API_KEY\",\n\t\"AZURE_OPENAI_API_KEY\",\n\t\"GEMINI_API_KEY\",\n\t\"GROQ_API_KEY\",\n\t\"CEREBRAS_API_KEY\",\n\t\"XAI_API_KEY\",\n\t\"OPENROUTER_API_KEY\",\n\t\"AI_GATEWAY_API_KEY\",\n\t\"ZAI_API_KEY\",\n\t\"MISTRAL_API_KEY\",\n\t\"MINIMAX_API_KEY\",\n\t\"MINIMAX_CN_API_KEY\",\n\t\"HF_TOKEN\",\n\t\"OPENCODE_API_KEY\",\n\t\"KIMI_API_KEY\",\n\t\"COPILOT_GITHUB_TOKEN\",\n\t\"GH_TOKEN\",\n\t\"GITHUB_TOKEN\",\n];\n\nfunction hasProviderEnvVar(): boolean {\n\treturn PROVIDER_ENV_VARS.some((key) => {\n\t\tconst val = process.env[key];\n\t\treturn typeof val === \"string\" && val.trim().length > 0;\n\t});\n}\n\nexport function hasPiAuthConfigured(): boolean {\n\treturn hasAuthJson() || hasCustomProviderKey() || hasProviderEnvVar();\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n\ttype Agent as ACPAgent,\n\ttype AgentSideConnection,\n\ttype AuthenticateRequest,\n\ttype AvailableCommand,\n\ttype CancelNotification,\n\ttype InitializeRequest,\n\ttype InitializeResponse,\n\ttype ListSessionsRequest,\n\ttype ListSessionsResponse,\n\ttype LoadSessionRequest,\n\ttype LoadSessionResponse,\n\ttype ModelInfo,\n\ttype NewSessionRequest,\n\ttype PromptRequest,\n\ttype PromptResponse,\n\tRequestError,\n\ttype SessionConfigOption,\n\ttype SessionInfo,\n\ttype SessionModelState,\n\ttype SessionModeState,\n\ttype SetSessionConfigOptionRequest,\n\ttype SetSessionConfigOptionResponse,\n\ttype SetSessionModelRequest,\n\ttype SetSessionModelResponse,\n\ttype SetSessionModeRequest,\n\ttype SetSessionModeResponse,\n\ttype StopReason,\n} from \"@agentclientprotocol/sdk\";\nimport type { AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessage, ToolResultMessage, UserMessage } from \"@mariozechner/pi-ai\";\nimport {\n\ttype AgentSession,\n\ttype CreateAgentSessionResult,\n\tcreateAgentSession,\n\tVERSION as PI_VERSION,\n\tSessionManager as PiSessionManager,\n} from \"@mariozechner/pi-coding-agent\";\nimport { buildAuthMethods } from \"@pi-acp/acp/auth\";\nimport { quietStartupEnabled, skillCommandsEnabled } from \"@pi-acp/acp/pi-settings\";\nimport { PiAcpSession, SessionManager } from \"@pi-acp/acp/session\";\nimport { extractAssistantText, extractUserMessageText } from \"@pi-acp/acp/translate/pi-messages\";\nimport { toolResultToText } from \"@pi-acp/acp/translate/pi-tools\";\nimport { acpPromptToPiMessage } from \"@pi-acp/acp/translate/prompt\";\nimport { hasPiAuthConfigured } from \"@pi-acp/pi-auth/status\";\n\ntype ThinkingLevel = \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\nfunction builtinAvailableCommands(): AvailableCommand[] {\n\treturn [\n\t\t{\n\t\t\tname: \"compact\",\n\t\t\tdescription: \"Manually compact the session context\",\n\t\t\tinput: { hint: \"optional custom instructions\" },\n\t\t},\n\t\t{\n\t\t\tname: \"autocompact\",\n\t\t\tdescription: \"Toggle automatic context compaction\",\n\t\t\tinput: { hint: \"on|off|toggle\" },\n\t\t},\n\t\t{ name: \"export\", description: \"Export session to an HTML file in the session cwd\" },\n\t\t{ name: \"session\", description: \"Show session stats (messages, tokens, cost, session file)\" },\n\t\t{ name: \"name\", description: \"Set session display name\", input: { hint: \"<name>\" } },\n\t\t{\n\t\t\tname: \"steering\",\n\t\t\tdescription: \"Get/set pi steering message delivery mode\",\n\t\t\tinput: { hint: \"(no args to show) all | one-at-a-time\" },\n\t\t},\n\t\t{\n\t\t\tname: \"follow-up\",\n\t\t\tdescription: \"Get/set pi follow-up message delivery mode\",\n\t\t\tinput: { hint: \"(no args to show) all | one-at-a-time\" },\n\t\t},\n\t\t{ name: \"changelog\", description: \"Show pi changelog\" },\n\t];\n}\n\nfunction mergeCommands(a: AvailableCommand[], b: AvailableCommand[]): AvailableCommand[] {\n\tconst out: AvailableCommand[] = [];\n\tconst seen = new Set<string>();\n\tfor (const c of [...a, ...b]) {\n\t\tif (seen.has(c.name)) continue;\n\t\tseen.add(c.name);\n\t\tout.push(c);\n\t}\n\treturn out;\n}\n\nfunction parseArgs(input: string): string[] {\n\tconst args: string[] = [];\n\tlet current = \"\";\n\tlet quote: string | null = null;\n\n\tfor (const ch of input) {\n\t\tif (quote !== null) {\n\t\t\tif (ch === quote) quote = null;\n\t\t\telse current += ch;\n\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\tquote = ch;\n\t\t} else if (ch === \" \" || ch === \"\\t\") {\n\t\t\tif (current !== \"\") {\n\t\t\t\targs.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tif (current !== \"\") args.push(current);\n\treturn args;\n}\n\nconst pkg = readNearestPackageJson(import.meta.url);\n\nexport class PiAcpAgent implements ACPAgent {\n\tprivate readonly conn: AgentSideConnection;\n\tprivate readonly sessions = new SessionManager();\n\t/** Cache of sessionId → file path, populated by listSessions and newSession. */\n\tprivate readonly sessionPaths = new Map<string, string>();\n\n\tdispose(): void {\n\t\tthis.sessions.disposeAll();\n\t}\n\n\tconstructor(conn: AgentSideConnection, _config?: unknown) {\n\t\tthis.conn = conn;\n\t\tvoid _config;\n\t}\n\n\tasync initialize(params: InitializeRequest): Promise<InitializeResponse> {\n\t\tconst supportedVersion = 1;\n\t\tconst requested = params.protocolVersion;\n\n\t\treturn {\n\t\t\tprotocolVersion: requested === supportedVersion ? requested : supportedVersion,\n\t\t\tagentInfo: {\n\t\t\t\tname: pkg.name,\n\t\t\t\ttitle: \"pi ACP adapter\",\n\t\t\t\tversion: pkg.version,\n\t\t\t},\n\t\t\tauthMethods: buildAuthMethods({\n\t\t\t\tsupportsTerminalAuthMeta: params.clientCapabilities?._meta?.[\"terminal-auth\"] === true,\n\t\t\t}),\n\t\t\tagentCapabilities: {\n\t\t\t\tloadSession: true,\n\t\t\t\tmcpCapabilities: { http: false, sse: false },\n\t\t\t\tpromptCapabilities: {\n\t\t\t\t\timage: true,\n\t\t\t\t\taudio: false,\n\t\t\t\t\tembeddedContext: false,\n\t\t\t\t},\n\t\t\t\tsessionCapabilities: {\n\t\t\t\t\tlist: {},\n\t\t\t\t},\n\t\t\t},\n\t\t};\n\t}\n\n\tasync newSession(params: NewSessionRequest) {\n\t\tif (!isAbsolute(params.cwd)) {\n\t\t\tthrow RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);\n\t\t}\n\n\t\tif (!hasPiAuthConfigured()) {\n\t\t\tthrow RequestError.authRequired(\n\t\t\t\t{ authMethods: buildAuthMethods() },\n\t\t\t\t\"Configure an API key or log in with an OAuth provider.\",\n\t\t\t);\n\t\t}\n\n\t\tlet result: CreateAgentSessionResult;\n\t\ttry {\n\t\t\tresult = await createAgentSession({ cwd: params.cwd });\n\t\t} catch (e: unknown) {\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to create pi session: ${msg}`);\n\t\t}\n\n\t\tconst piSession = result.session;\n\n\t\tconst availableModels = piSession.modelRegistry.getAvailable();\n\t\tif (availableModels.length === 0) {\n\t\t\tpiSession.dispose();\n\t\t\tthrow RequestError.authRequired(\n\t\t\t\t{ authMethods: buildAuthMethods() },\n\t\t\t\t\"Configure an API key or log in with an OAuth provider.\",\n\t\t\t);\n\t\t}\n\n\t\tconst sessionId = piSession.sessionManager.getSessionId();\n\t\tconst sessionFile = piSession.sessionManager.getSessionFile();\n\t\tif (sessionFile !== undefined) {\n\t\t\tthis.sessionPaths.set(sessionId, sessionFile);\n\t\t}\n\n\t\tconst session = new PiAcpSession({\n\t\t\tsessionId,\n\t\t\tcwd: params.cwd,\n\t\t\tmcpServers: params.mcpServers,\n\t\t\tpiSession,\n\t\t\tconn: this.conn,\n\t\t});\n\n\t\tthis.sessions.register(session);\n\n\t\tconst quietStartup = quietStartupEnabled(params.cwd);\n\t\tconst updateNotice = buildUpdateNotice();\n\n\t\tconst preludeText = quietStartup\n\t\t\t? updateNotice !== null\n\t\t\t\t? `${updateNotice}\\n`\n\t\t\t\t: \"\"\n\t\t\t: buildStartupInfo({ cwd: params.cwd, updateNotice });\n\n\t\tif (preludeText) session.setStartupInfo(preludeText);\n\n\t\tthis.sessions.closeAllExcept(session.sessionId);\n\n\t\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tconst response = {\n\t\t\tsessionId: session.sessionId,\n\t\t\tconfigOptions,\n\t\t\tmodes,\n\t\t\tmodels,\n\t\t\t_meta: {\n\t\t\t\tpiAcp: { startupInfo: preludeText || null },\n\t\t\t},\n\t\t};\n\n\t\tif (preludeText) setTimeout(() => session.sendStartupInfoIfPending(), 0);\n\n\t\tconst enableSkillCommands = skillCommandsEnabled(params.cwd);\n\t\tsetTimeout(() => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst commands = buildCommandList(piSession, enableSkillCommands);\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tsessionUpdate: \"available_commands_update\",\n\t\t\t\t\t\t\tavailableCommands: mergeCommands(commands, builtinAvailableCommands()),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch {}\n\t\t\t})();\n\t\t}, 0);\n\n\t\treturn response;\n\t}\n\n\tasync authenticate(_params: AuthenticateRequest) {\n\t\treturn;\n\t}\n\n\tasync prompt(params: PromptRequest): Promise<PromptResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst { message, images } = acpPromptToPiMessage(params.prompt);\n\n\t\tif (images.length === 0 && message.trimStart().startsWith(\"/\")) {\n\t\t\tconst trimmed = message.trim();\n\t\t\tconst space = trimmed.indexOf(\" \");\n\t\t\tconst cmd = space === -1 ? trimmed.slice(1) : trimmed.slice(1, space);\n\t\t\tconst argsString = space === -1 ? \"\" : trimmed.slice(space + 1);\n\t\t\tconst args = parseArgs(argsString);\n\n\t\t\tconst handled = await this.handleBuiltinCommand(session, cmd, args);\n\t\t\tif (handled) return handled;\n\t\t}\n\n\t\tconst result = await session.prompt(message, images);\n\n\t\tconst stopReason: StopReason = result === \"error\" ? \"end_turn\" : result;\n\n\t\treturn { stopReason };\n\t}\n\n\tasync cancel(params: CancelNotification): Promise<void> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tawait session.cancel();\n\t}\n\n\t/**\n\t * Resolve a session ID to a file path.\n\t * Checks the local cache first (populated by listSessions/newSession),\n\t * falls back to a full listAll() scan on cache miss.\n\t */\n\tprivate async resolveSessionFile(sessionId: string): Promise<string | null> {\n\t\tconst cached = this.sessionPaths.get(sessionId);\n\t\tif (cached !== undefined) return cached;\n\n\t\tconst all = await PiSessionManager.listAll();\n\t\tfor (const s of all) {\n\t\t\tthis.sessionPaths.set(s.id, s.path);\n\t\t}\n\n\t\treturn this.sessionPaths.get(sessionId) ?? null;\n\t}\n\n\tasync listSessions(params: ListSessionsRequest): Promise<ListSessionsResponse> {\n\t\tconst cwd = params.cwd;\n\n\t\tconst raw =\n\t\t\tcwd !== undefined && cwd !== null\n\t\t\t\t? await PiSessionManager.list(cwd)\n\t\t\t\t: await PiSessionManager.listAll();\n\n\t\tfor (const s of raw) {\n\t\t\tthis.sessionPaths.set(s.id, s.path);\n\t\t}\n\n\t\tconst sessions = raw.map((s) => ({\n\t\t\tid: s.id,\n\t\t\tcwd: s.cwd,\n\t\t\tname: s.name ?? \"\",\n\t\t\tmodified: s.modified,\n\t\t\tmessageCount: s.messageCount,\n\t\t}));\n\n\t\tif (params.cursor !== undefined && params.cursor !== null) {\n\t\t\tconst parsed = Number.parseInt(params.cursor, 10);\n\t\t\tif (!Number.isFinite(parsed) || parsed < 0) {\n\t\t\t\tthrow RequestError.invalidParams(`Invalid cursor: ${params.cursor}`);\n\t\t\t}\n\t\t}\n\n\t\tconst start =\n\t\t\tparams.cursor !== undefined && params.cursor !== null\n\t\t\t\t? Number.parseInt(params.cursor, 10)\n\t\t\t\t: 0;\n\n\t\tconst PAGE_SIZE = 50;\n\t\tconst page = sessions.slice(start, start + PAGE_SIZE);\n\n\t\tconst acpSessions: SessionInfo[] = page.map((s) => ({\n\t\t\tsessionId: s.id,\n\t\t\tcwd: s.cwd,\n\t\t\ttitle: s.name ?? null,\n\t\t\tupdatedAt: s.modified.toISOString(),\n\t\t}));\n\n\t\tconst nextCursor = start + PAGE_SIZE < sessions.length ? String(start + PAGE_SIZE) : null;\n\n\t\treturn { sessions: acpSessions, nextCursor, _meta: {} };\n\t}\n\n\tasync loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse> {\n\t\tif (!isAbsolute(params.cwd)) {\n\t\t\tthrow RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);\n\t\t}\n\n\t\tthis.sessions.close(params.sessionId);\n\n\t\tconst sessionFile = await this.resolveSessionFile(params.sessionId);\n\t\tif (sessionFile === null) {\n\t\t\tthrow RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);\n\t\t}\n\n\t\tlet result: CreateAgentSessionResult;\n\t\ttry {\n\t\t\tconst sm = PiSessionManager.open(sessionFile);\n\t\t\tresult = await createAgentSession({\n\t\t\t\tcwd: params.cwd,\n\t\t\t\tsessionManager: sm,\n\t\t\t});\n\t\t} catch (e: unknown) {\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to load pi session: ${msg}`);\n\t\t}\n\n\t\tconst piSession = result.session;\n\n\t\tconst session = new PiAcpSession({\n\t\t\tsessionId: params.sessionId,\n\t\t\tcwd: params.cwd,\n\t\t\tmcpServers: params.mcpServers,\n\t\t\tpiSession,\n\t\t\tconn: this.conn,\n\t\t});\n\n\t\tthis.sessions.register(session);\n\t\tthis.sessions.closeAllExcept(session.sessionId);\n\n\t\tconst messages: AgentMessage[] = piSession.messages;\n\t\tfor (const m of messages) {\n\t\t\tif (!(\"role\" in m)) continue;\n\n\t\t\tif (m.role === \"user\") {\n\t\t\t\tconst text = extractUserMessageText((m satisfies UserMessage).content);\n\t\t\t\tif (text) {\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: { sessionUpdate: \"user_message_chunk\", content: { type: \"text\", text } },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m.role === \"assistant\") {\n\t\t\t\tconst text = extractAssistantText((m satisfies AssistantMessage).content);\n\t\t\t\tif (text) {\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (m.role === \"toolResult\") {\n\t\t\t\tconst tr = m satisfies ToolResultMessage;\n\t\t\t\tconst toolName = tr.toolName;\n\t\t\t\tconst toolCallId = tr.toolCallId;\n\t\t\t\tconst isError = tr.isError;\n\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\ttitle: toolName,\n\t\t\t\t\t\tkind:\n\t\t\t\t\t\t\ttoolName === \"read\"\n\t\t\t\t\t\t\t\t? \"read\"\n\t\t\t\t\t\t\t\t: toolName === \"write\" || toolName === \"edit\"\n\t\t\t\t\t\t\t\t\t? \"edit\"\n\t\t\t\t\t\t\t\t\t: \"other\",\n\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\trawInput: null,\n\t\t\t\t\t\trawOutput: m,\n\t\t\t\t\t},\n\t\t\t\t});\n\n\t\t\t\tconst text = toolResultToText(m);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"tool_call_update\",\n\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\tstatus: isError ? \"failed\" : \"completed\",\n\t\t\t\t\t\tcontent: text ? [{ type: \"content\", content: { type: \"text\", text } }] : null,\n\t\t\t\t\t\trawOutput: m,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tconst enableSkillCommands = skillCommandsEnabled(params.cwd);\n\t\tsetTimeout(() => {\n\t\t\tvoid (async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst commands = buildCommandList(piSession, enableSkillCommands);\n\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\tsessionUpdate: \"available_commands_update\",\n\t\t\t\t\t\t\tavailableCommands: mergeCommands(commands, builtinAvailableCommands()),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\t\t\t\t} catch {}\n\t\t\t})();\n\t\t}, 0);\n\n\t\treturn {\n\t\t\tconfigOptions,\n\t\t\tmodes,\n\t\t\tmodels,\n\t\t\t_meta: { piAcp: { startupInfo: null } },\n\t\t};\n\t}\n\n\tasync setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst mode = String(params.modeId);\n\t\tif (!isThinkingLevel(mode)) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modeId: ${mode}`);\n\t\t}\n\n\t\tsession.piSession.setThinkingLevel(mode);\n\n\t\tvoid this.conn.sessionUpdate({\n\t\t\tsessionId: session.sessionId,\n\t\t\tupdate: { sessionUpdate: \"current_mode_update\", currentModeId: mode },\n\t\t});\n\n\t\tthis.emitConfigOptionUpdate(session);\n\n\t\treturn {};\n\t}\n\n\tasync unstable_setSessionModel(\n\t\tparams: SetSessionModelRequest,\n\t): Promise<SetSessionModelResponse | void> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\n\t\tlet provider: string | null = null;\n\t\tlet modelId: string | null = null;\n\n\t\tif (params.modelId.includes(\"/\")) {\n\t\t\tconst [p, ...rest] = params.modelId.split(\"/\");\n\t\t\tprovider = p ?? null;\n\t\t\tmodelId = rest.join(\"/\");\n\t\t} else {\n\t\t\tmodelId = params.modelId;\n\t\t}\n\n\t\tif (provider === null) {\n\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\tconst found = available.find((m) => m.id === modelId);\n\t\t\tif (found) {\n\t\t\t\tprovider = found.provider;\n\t\t\t\tmodelId = found.id;\n\t\t\t}\n\t\t}\n\n\t\tif (provider === null || modelId === null) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modelId: ${params.modelId}`);\n\t\t}\n\n\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\tconst model = available.find((m) => m.provider === provider && m.id === modelId);\n\t\tif (!model) {\n\t\t\tthrow RequestError.invalidParams(`Unknown modelId: ${params.modelId}`);\n\t\t}\n\n\t\tawait session.piSession.setModel(model);\n\t\tthis.emitConfigOptionUpdate(session);\n\t}\n\n\tasync setSessionConfigOption(\n\t\tparams: SetSessionConfigOptionRequest,\n\t): Promise<SetSessionConfigOptionResponse> {\n\t\tconst session = this.sessions.get(params.sessionId);\n\t\tconst configId = String(params.configId);\n\t\tconst value = String(params.value);\n\n\t\tif (configId === \"model\") {\n\t\t\tlet provider: string | null = null;\n\t\t\tlet modelId: string | null = null;\n\n\t\t\tif (value.includes(\"/\")) {\n\t\t\t\tconst [p, ...rest] = value.split(\"/\");\n\t\t\t\tprovider = p ?? null;\n\t\t\t\tmodelId = rest.join(\"/\");\n\t\t\t} else {\n\t\t\t\tmodelId = value;\n\t\t\t}\n\n\t\t\tif (provider === null) {\n\t\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\t\tconst found = available.find((m) => m.id === modelId);\n\t\t\t\tif (found) {\n\t\t\t\t\tprovider = found.provider;\n\t\t\t\t\tmodelId = found.id;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (provider === null || modelId === null) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t}\n\n\t\t\tconst available = session.piSession.modelRegistry.getAvailable();\n\t\t\tconst model = available.find((m) => m.provider === provider && m.id === modelId);\n\t\t\tif (!model) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown model: ${value}`);\n\t\t\t}\n\n\t\t\tawait session.piSession.setModel(model);\n\t\t} else if (configId === \"thought_level\") {\n\t\t\tif (!isThinkingLevel(value)) {\n\t\t\t\tthrow RequestError.invalidParams(`Unknown thinking level: ${value}`);\n\t\t\t}\n\t\t\tsession.piSession.setThinkingLevel(value);\n\t\t} else {\n\t\t\tthrow RequestError.invalidParams(`Unknown config option: ${configId}`);\n\t\t}\n\n\t\tconst modes = buildThinkingModes(session.piSession);\n\t\tconst models = buildModelState(session.piSession);\n\t\treturn { configOptions: buildConfigOptions(modes, models) };\n\t}\n\n\tprivate emitConfigOptionUpdate(session: PiAcpSession): void {\n\t\tconst modes = buildThinkingModes(session.piSession);\n\t\tconst models = buildModelState(session.piSession);\n\t\tconst configOptions = buildConfigOptions(modes, models);\n\n\t\tvoid this.conn.sessionUpdate({\n\t\t\tsessionId: session.sessionId,\n\t\t\tupdate: {\n\t\t\t\tsessionUpdate: \"config_option_update\",\n\t\t\t\tconfigOptions,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async handleBuiltinCommand(\n\t\tsession: PiAcpSession,\n\t\tcmd: string,\n\t\targs: string[],\n\t): Promise<PromptResponse | null> {\n\t\tconst piSession = session.piSession;\n\n\t\tif (cmd === \"compact\") {\n\t\t\tconst customInstructions = args.join(\" \").trim() || undefined;\n\t\t\tconst res = await piSession.compact(customInstructions);\n\n\t\t\tconst headerLines = [\n\t\t\t\t`Compaction completed.${customInstructions !== undefined && customInstructions !== \"\" ? \" (custom instructions applied)\" : \"\"}`,\n\t\t\t\ttypeof res?.tokensBefore === \"number\" ? `Tokens before: ${res.tokensBefore}` : null,\n\t\t\t].filter(Boolean);\n\n\t\t\tconst text = headerLines.join(\"\\n\") + (res?.summary ? `\\n\\n${res.summary}` : \"\");\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"session\") {\n\t\t\tconst stats = piSession.getSessionStats();\n\t\t\tconst lines: string[] = [];\n\t\t\tif (stats.sessionId !== undefined && stats.sessionId !== \"\")\n\t\t\t\tlines.push(`Session: ${stats.sessionId}`);\n\t\t\tif (stats.sessionFile !== undefined && stats.sessionFile !== \"\")\n\t\t\t\tlines.push(`Session file: ${stats.sessionFile}`);\n\t\t\tlines.push(`Messages: ${stats.totalMessages}`);\n\t\t\tlines.push(`Cost: ${stats.cost}`);\n\t\t\tconst t = stats.tokens;\n\t\t\tconst parts: string[] = [];\n\t\t\tif (t.input) parts.push(`in ${t.input}`);\n\t\t\tif (t.output) parts.push(`out ${t.output}`);\n\t\t\tif (t.cacheRead) parts.push(`cache read ${t.cacheRead}`);\n\t\t\tif (t.cacheWrite) parts.push(`cache write ${t.cacheWrite}`);\n\t\t\tif (t.total) parts.push(`total ${t.total}`);\n\t\t\tif (parts.length > 0) lines.push(`Tokens: ${parts.join(\", \")}`);\n\n\t\t\tconst text = lines.join(\"\\n\");\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"name\") {\n\t\t\tconst name = args.join(\" \").trim();\n\t\t\tif (!name) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /name <name>\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tpiSession.setSessionName(name);\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"session_info_update\",\n\t\t\t\t\ttitle: name,\n\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t},\n\t\t\t});\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Session name set: ${name}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"steering\") {\n\t\t\tconst modeRaw = String(args[0] ?? \"\").toLowerCase();\n\t\t\tif (!modeRaw) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Steering mode: ${piSession.steeringMode}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tif (modeRaw !== \"all\" && modeRaw !== \"one-at-a-time\") {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /steering all | /steering one-at-a-time\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tpiSession.setSteeringMode(modeRaw);\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Steering mode set to: ${modeRaw}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"follow-up\") {\n\t\t\tconst modeRaw = String(args[0] ?? \"\").toLowerCase();\n\t\t\tif (!modeRaw) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Follow-up mode: ${piSession.followUpMode}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tif (modeRaw !== \"all\" && modeRaw !== \"one-at-a-time\") {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Usage: /follow-up all | /follow-up one-at-a-time\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\t\t\tpiSession.setFollowUpMode(modeRaw);\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Follow-up mode set to: ${modeRaw}` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"autocompact\") {\n\t\t\tconst mode = (args[0] ?? \"toggle\").toLowerCase();\n\t\t\tlet enabled: boolean | null = null;\n\t\t\tif (mode === \"on\" || mode === \"true\" || mode === \"enable\") enabled = true;\n\t\t\telse if (mode === \"off\" || mode === \"false\" || mode === \"disable\") enabled = false;\n\n\t\t\tif (enabled === null) {\n\t\t\t\tenabled = !piSession.autoCompactionEnabled;\n\t\t\t}\n\n\t\t\tpiSession.setAutoCompactionEnabled(enabled);\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: {\n\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\tcontent: { type: \"text\", text: `Auto-compaction ${enabled ? \"enabled\" : \"disabled\"}.` },\n\t\t\t\t},\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"changelog\") {\n\t\t\tconst changelogPath = findChangelog();\n\t\t\tif (changelogPath === null) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Changelog not found.\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tlet text = \"\";\n\t\t\ttry {\n\t\t\t\ttext = readFileSync(changelogPath, \"utf-8\");\n\t\t\t} catch (e: unknown) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Failed to read changelog: ${msg}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\tconst maxChars = 20_000;\n\t\t\tif (text.length > maxChars) text = `${text.slice(0, maxChars)}\\n\\n...(truncated)...`;\n\n\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\tsessionId: session.sessionId,\n\t\t\t\tupdate: { sessionUpdate: \"agent_message_chunk\", content: { type: \"text\", text } },\n\t\t\t});\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\tif (cmd === \"export\") {\n\t\t\tconst messageCount = piSession.messages.length;\n\t\t\tif (messageCount === 0) {\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Nothing to export yet. Send a prompt first.\" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\treturn { stopReason: \"end_turn\" };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tconst safeSessionId = session.sessionId.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n\t\t\t\tconst outputPath = join(session.cwd, `pi-session-${safeSessionId}.html`);\n\t\t\t\tconst resultPath = await piSession.exportToHtml(outputPath);\n\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: \"Session exported: \" },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: {\n\t\t\t\t\t\t\ttype: \"resource_link\",\n\t\t\t\t\t\t\tname: `pi-session-${safeSessionId}.html`,\n\t\t\t\t\t\t\turi: `file://${resultPath}`,\n\t\t\t\t\t\t\tmimeType: \"text/html\",\n\t\t\t\t\t\t\ttitle: \"Session exported\",\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (e: unknown) {\n\t\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\tcontent: { type: \"text\", text: `Export failed: ${msg}` },\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn { stopReason: \"end_turn\" };\n\t\t}\n\n\t\treturn null;\n\t}\n}\n\nfunction isThinkingLevel(x: string): x is ThinkingLevel {\n\treturn (\n\t\tx === \"off\" || x === \"minimal\" || x === \"low\" || x === \"medium\" || x === \"high\" || x === \"xhigh\"\n\t);\n}\n\nfunction buildThinkingModes(piSession: AgentSession): {\n\tavailableModes: Array<{ id: string; name: string; description?: string | null }>;\n\tcurrentModeId: string;\n} {\n\tconst levels = piSession.getAvailableThinkingLevels();\n\treturn {\n\t\tcurrentModeId: piSession.thinkingLevel,\n\t\tavailableModes: levels.map((id) => ({\n\t\t\tid,\n\t\t\tname: `Thinking: ${id}`,\n\t\t\tdescription: null,\n\t\t})),\n\t};\n}\n\nfunction buildModelState(piSession: AgentSession): SessionModelState {\n\tconst available = piSession.modelRegistry.getAvailable();\n\tconst current = piSession.model;\n\n\tconst availableModels: ModelInfo[] = available.map((m) => ({\n\t\tmodelId: `${m.provider}/${m.id}`,\n\t\tname: `${m.provider}/${m.name ?? m.id}`,\n\t\tdescription: null,\n\t}));\n\n\tlet currentModelId = \"default\";\n\tif (current !== undefined) {\n\t\tcurrentModelId = `${current.provider}/${current.id}`;\n\t} else if (availableModels.length > 0 && availableModels[0] !== undefined) {\n\t\tcurrentModelId = availableModels[0].modelId;\n\t}\n\n\treturn { availableModels, currentModelId };\n}\n\nfunction buildConfigOptions(\n\tmodes: SessionModeState,\n\tmodels: SessionModelState,\n): SessionConfigOption[] {\n\treturn [\n\t\t{\n\t\t\tid: \"model\",\n\t\t\tname: \"Model\",\n\t\t\tdescription: \"AI model to use\",\n\t\t\tcategory: \"model\",\n\t\t\ttype: \"select\" as const,\n\t\t\tcurrentValue: models.currentModelId,\n\t\t\toptions: models.availableModels.map((m) => ({\n\t\t\t\tvalue: m.modelId,\n\t\t\t\tname: m.name,\n\t\t\t\tdescription: m.description ?? null,\n\t\t\t})),\n\t\t},\n\t\t{\n\t\t\tid: \"thought_level\",\n\t\t\tname: \"Thinking Level\",\n\t\t\tdescription: \"Reasoning depth for models that support it\",\n\t\t\tcategory: \"thought_level\",\n\t\t\ttype: \"select\" as const,\n\t\t\tcurrentValue: modes.currentModeId,\n\t\t\toptions: modes.availableModes.map((m) => ({\n\t\t\t\tvalue: m.id,\n\t\t\t\tname: m.name,\n\t\t\t\tdescription: m.description ?? null,\n\t\t\t})),\n\t\t},\n\t];\n}\n\nfunction buildCommandList(\n\tpiSession: AgentSession,\n\tenableSkillCommands: boolean,\n): AvailableCommand[] {\n\tconst commands: AvailableCommand[] = [];\n\n\tfor (const template of piSession.promptTemplates) {\n\t\tcommands.push({\n\t\t\tname: template.name,\n\t\t\tdescription: template.description ?? `(prompt)`,\n\t\t});\n\t}\n\n\tif (enableSkillCommands) {\n\t\tconst skills = piSession.resourceLoader.getSkills();\n\t\tfor (const skill of skills.skills) {\n\t\t\tcommands.push({\n\t\t\t\tname: `skill:${skill.name}`,\n\t\t\t\tdescription: skill.description ?? `(skill)`,\n\t\t\t});\n\t\t}\n\t}\n\n\tconst runner = piSession.extensionRunner;\n\tif (runner) {\n\t\tfor (const cmd of runner.getRegisteredCommands()) {\n\t\t\tcommands.push({\n\t\t\t\tname: cmd.name,\n\t\t\t\tdescription: cmd.description ?? \"(extension)\",\n\t\t\t});\n\t\t}\n\t}\n\n\treturn commands;\n}\n\nfunction buildUpdateNotice(): string | null {\n\ttry {\n\t\tconst installed = PI_VERSION;\n\t\tif (!installed || !isSemver(installed)) return null;\n\n\t\tconst latestRes = spawnSync(\"npm\", [\"view\", \"@mariozechner/pi-coding-agent\", \"version\"], {\n\t\t\tencoding: \"utf-8\",\n\t\t\ttimeout: 800,\n\t\t});\n\t\tconst latest = String(latestRes.stdout ?? \"\")\n\t\t\t.trim()\n\t\t\t.replace(/^v/i, \"\");\n\t\tif (!latest || !isSemver(latest)) return null;\n\t\tif (compareSemver(latest, installed) <= 0) return null;\n\n\t\treturn `New version available: v${latest} (installed v${installed}). Run: \\`npm i -g @mariozechner/pi-coding-agent\\``;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction buildStartupInfo(opts: { cwd: string; updateNotice: string | null }): string {\n\tconst md: string[] = [];\n\n\tif (PI_VERSION) {\n\t\tmd.push(`pi v${PI_VERSION}`);\n\t\tmd.push(\"---\");\n\t\tmd.push(\"\");\n\t}\n\n\tconst addSection = (title: string, items: string[]) => {\n\t\tconst cleaned = items.map((s) => s.trim()).filter(Boolean);\n\t\tif (cleaned.length === 0) return;\n\t\tmd.push(`## ${title}`);\n\t\tfor (const item of cleaned) md.push(`- ${item}`);\n\t\tmd.push(\"\");\n\t};\n\n\tconst contextItems: string[] = [];\n\tconst contextPath = join(opts.cwd, \"AGENTS.md\");\n\tif (existsSync(contextPath)) contextItems.push(contextPath);\n\taddSection(\"Context\", contextItems);\n\n\tif (opts.updateNotice !== undefined && opts.updateNotice !== null) {\n\t\tmd.push(\"---\");\n\t\tmd.push(opts.updateNotice);\n\t\tmd.push(\"\");\n\t}\n\n\treturn `${md.join(\"\\n\").trim()}\\n`;\n}\n\nfunction findChangelog(): string | null {\n\ttry {\n\t\tconst whichCmd = process.platform === \"win32\" ? \"where\" : \"which\";\n\t\tconst which = spawnSync(whichCmd, [\"pi\"], { encoding: \"utf-8\" });\n\t\tconst piPath = String(which.stdout ?? \"\")\n\t\t\t.split(/\\r?\\n/)[0]\n\t\t\t?.trim();\n\t\tif (piPath !== undefined && piPath !== \"\") {\n\t\t\tconst resolved = realpathSync(piPath);\n\t\t\tconst pkgRoot = dirname(dirname(resolved));\n\t\t\tconst p = join(pkgRoot, \"CHANGELOG.md\");\n\t\t\tif (existsSync(p)) return p;\n\t\t}\n\t} catch {}\n\n\ttry {\n\t\tconst npmRoot = spawnSync(\"npm\", [\"root\", \"-g\"], { encoding: \"utf-8\" });\n\t\tconst root = String(npmRoot.stdout ?? \"\").trim();\n\t\tif (root) {\n\t\t\tconst p = join(root, \"@mariozechner\", \"pi-coding-agent\", \"CHANGELOG.md\");\n\t\t\tif (existsSync(p)) return p;\n\t\t}\n\t} catch {}\n\n\treturn null;\n}\n\nfunction isSemver(v: string): boolean {\n\treturn /^\\d+\\.\\d+\\.\\d+(?:[-+].+)?$/.test(v);\n}\n\nfunction compareSemver(a: string, b: string): number {\n\tconst pa = a\n\t\t.split(/[.-]/)\n\t\t.slice(0, 3)\n\t\t.map((n) => Number(n));\n\tconst pb = b\n\t\t.split(/[.-]/)\n\t\t.slice(0, 3)\n\t\t.map((n) => Number(n));\n\tfor (let i = 0; i < 3; i++) {\n\t\tconst da = pa[i] ?? 0;\n\t\tconst db = pb[i] ?? 0;\n\t\tif (da > db) return 1;\n\t\tif (da < db) return -1;\n\t}\n\treturn 0;\n}\n\nfunction readNearestPackageJson(metaUrl: string): { name: string; version: string } {\n\tconst fallback = { name: \"pi-acp\", version: \"0.0.0\" };\n\ttry {\n\t\tlet dir = dirname(fileURLToPath(metaUrl));\n\t\tfor (let i = 0; i < 6; i++) {\n\t\t\tconst p = join(dir, \"package.json\");\n\t\t\tif (existsSync(p)) {\n\t\t\t\tconst raw: unknown = JSON.parse(readFileSync(p, \"utf-8\"));\n\t\t\t\tif (typeof raw !== \"object\" || raw === null) return fallback;\n\t\t\t\tconst name = \"name\" in raw && typeof raw.name === \"string\" ? raw.name : fallback.name;\n\t\t\t\tconst version =\n\t\t\t\t\t\"version\" in raw && typeof raw.version === \"string\" ? raw.version : fallback.version;\n\t\t\t\treturn { name, version };\n\t\t\t}\n\t\t\tdir = dirname(dir);\n\t\t}\n\t} catch {\n\t\t// fall through\n\t}\n\treturn fallback;\n}\n","import { platform } from \"node:os\";\nimport { AgentSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\";\nimport { PiAcpAgent } from \"@pi-acp/acp/agent\";\n\n// Terminal Auth entrypoint: ACP client launches with `--terminal-login`.\nif (process.argv.includes(\"--terminal-login\")) {\n\tconst { spawnSync } = await import(\"node:child_process\");\n\tconst isWindows = platform() === \"win32\";\n\tconst cmd = process.env.PI_ACP_PI_COMMAND ?? (isWindows ? \"pi.cmd\" : \"pi\");\n\tconst res = spawnSync(cmd, [], { stdio: \"inherit\", env: process.env });\n\n\tif (res.error && \"code\" in res.error && res.error.code === \"ENOENT\") {\n\t\tprocess.stderr.write(\n\t\t\t`pi-acp: could not start pi (command not found: ${cmd}). ` +\n\t\t\t\t\"Install via `npm install -g @mariozechner/pi-coding-agent` \" +\n\t\t\t\t\"or ensure `pi` is on your PATH.\\n\",\n\t\t);\n\t\tprocess.exit(1);\n\t}\n\n\tprocess.exit(typeof res.status === \"number\" ? res.status : 1);\n}\n\nconst input = new WritableStream<Uint8Array>({\n\twrite(chunk) {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tif (process.stdout.destroyed || !process.stdout.writable) {\n\t\t\t\tresolve();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tprocess.stdout.write(chunk, () => resolve());\n\t\t\t} catch {\n\t\t\t\tresolve();\n\t\t\t}\n\t\t});\n\t},\n});\n\nconst output = new ReadableStream<Uint8Array>({\n\tstart(controller) {\n\t\tprocess.stdin.on(\"data\", (chunk: Buffer) => controller.enqueue(new Uint8Array(chunk)));\n\t\tprocess.stdin.on(\"end\", () => controller.close());\n\t\tprocess.stdin.on(\"error\", (err) => controller.error(err));\n\t},\n});\n\nconst stream = ndJsonStream(input, output);\nconst agent = new AgentSideConnection((conn) => new PiAcpAgent(conn), stream);\n\nfunction shutdown() {\n\ttry {\n\t\t// AgentSideConnection stores the agent instance internally;\n\t\t// call dispose() on it if available for clean shutdown.\n\t\tif (\"agent\" in agent) {\n\t\t\tconst inner: unknown = agent.agent;\n\t\t\tif (\n\t\t\t\ttypeof inner === \"object\" &&\n\t\t\t\tinner !== null &&\n\t\t\t\t\"dispose\" in inner &&\n\t\t\t\ttypeof inner.dispose === \"function\"\n\t\t\t) {\n\t\t\t\t// eslint-disable-next-line typescript-eslint/no-unsafe-call -- runtime-guarded\n\t\t\t\tinner.dispose();\n\t\t\t}\n\t\t}\n\t} catch {\n\t\t// best-effort cleanup\n\t}\n\tprocess.exit(0);\n}\n\nprocess.stdin.on(\"end\", shutdown);\nprocess.stdin.on(\"close\", shutdown);\nprocess.stdin.resume();\nprocess.on(\"SIGINT\", shutdown);\nprocess.on(\"SIGTERM\", shutdown);\nprocess.stdout.on(\"error\", () => process.exit(0));\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@victor-software-house/pi-acp",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "ACP adapter for pi coding agent",
5
5
  "license": "MIT",
6
6
  "author": "Victor Software House",
@@ -26,9 +26,9 @@
26
26
  "node": ">=20"
27
27
  },
28
28
  "type": "module",
29
- "main": "dist/index.js",
29
+ "main": "dist/index.mjs",
30
30
  "bin": {
31
- "pi-acp": "dist/index.js"
31
+ "pi-acp": "dist/index.mjs"
32
32
  },
33
33
  "files": [
34
34
  "dist"
@@ -49,21 +49,22 @@
49
49
  },
50
50
  "dependencies": {
51
51
  "@agentclientprotocol/sdk": "0.16.1",
52
- "@mariozechner/pi-coding-agent": "^0.61.1",
52
+ "@mariozechner/pi-coding-agent": "^0.62.0",
53
53
  "zod": "^4.3.6"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@biomejs/biome": "^2.4.8",
57
- "@commitlint/cli": "^20.4.4",
58
- "@commitlint/config-conventional": "^20.4.4",
57
+ "@commitlint/cli": "^20.5.0",
58
+ "@commitlint/config-conventional": "^20.5.0",
59
+ "@limegrass/eslint-plugin-import-alias": "^1.6.1",
59
60
  "@semantic-release/changelog": "6",
60
61
  "@semantic-release/git": "10",
61
62
  "@semantic-release/github": "12",
62
63
  "@semantic-release/npm": "13",
63
64
  "@types/bun": "^1.3.11",
64
- "@types/node": "^22.0.0",
65
+ "@types/node": "^25.5.0",
65
66
  "eslint-plugin-zod": "^3.5.0",
66
- "lefthook": "^1.12.0",
67
+ "lefthook": "^2.1.4",
67
68
  "oxlint": "^1.56.0",
68
69
  "oxlint-tsgolint": "^0.17.1",
69
70
  "semantic-release": "25",