@victor-software-house/pi-acp 0.1.0

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.
@@ -0,0 +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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"}
package/package.json ADDED
@@ -0,0 +1,73 @@
1
+ {
2
+ "name": "@victor-software-house/pi-acp",
3
+ "version": "0.1.0",
4
+ "description": "ACP adapter for pi coding agent",
5
+ "license": "MIT",
6
+ "author": "Victor Software House",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/victor-software-house/pi-acp.git"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public",
13
+ "provenance": true
14
+ },
15
+ "bugs": {
16
+ "url": "https://github.com/victor-software-house/pi-acp/issues"
17
+ },
18
+ "homepage": "https://github.com/victor-software-house/pi-acp#readme",
19
+ "keywords": [
20
+ "acp",
21
+ "agent-client-protocol",
22
+ "pi-coding-agent",
23
+ "adapter"
24
+ ],
25
+ "engines": {
26
+ "node": ">=20"
27
+ },
28
+ "type": "module",
29
+ "main": "dist/index.js",
30
+ "bin": {
31
+ "pi-acp": "dist/index.js"
32
+ },
33
+ "files": [
34
+ "dist"
35
+ ],
36
+ "scripts": {
37
+ "dev": "bun src/index.ts",
38
+ "build": "tsdown",
39
+ "start": "node dist/index.js",
40
+ "typecheck": "tsc --noEmit",
41
+ "lint": "bun run lint:biome && bun run lint:oxlint",
42
+ "lint:biome": "biome check .",
43
+ "lint:oxlint": "oxlint --import-plugin --type-aware --tsconfig=./tsconfig.json src/",
44
+ "lint:fix": "biome check --write .",
45
+ "format": "biome format --write .",
46
+ "test": "bun test",
47
+ "prepack": "bun run build",
48
+ "prepublishOnly": "bun test && bun run build"
49
+ },
50
+ "dependencies": {
51
+ "@agentclientprotocol/sdk": "0.16.1",
52
+ "@mariozechner/pi-coding-agent": "^0.61.1",
53
+ "zod": "^4.3.6"
54
+ },
55
+ "devDependencies": {
56
+ "@biomejs/biome": "^2.4.8",
57
+ "@commitlint/cli": "^20.4.4",
58
+ "@commitlint/config-conventional": "^20.4.4",
59
+ "@semantic-release/changelog": "6",
60
+ "@semantic-release/git": "10",
61
+ "@semantic-release/github": "12",
62
+ "@semantic-release/npm": "13",
63
+ "@types/bun": "^1.3.11",
64
+ "@types/node": "^22.0.0",
65
+ "eslint-plugin-zod": "^3.5.0",
66
+ "lefthook": "^1.12.0",
67
+ "oxlint": "^1.56.0",
68
+ "oxlint-tsgolint": "^0.17.1",
69
+ "semantic-release": "25",
70
+ "tsdown": "^0.21.4",
71
+ "typescript": "^5.9.3"
72
+ }
73
+ }