@victor-software-house/pi-acp 0.1.2 → 0.2.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.
package/README.md CHANGED
@@ -13,8 +13,9 @@ Active development. ACP compliance is improving steadily. Development is centere
13
13
  - Streams assistant output as ACP `agent_message_chunk`
14
14
  - Streams thinking output as ACP `agent_thought_chunk`
15
15
  - Maps pi tool execution to ACP `tool_call` / `tool_call_update`
16
+ - Descriptive tool titles (`Read src/index.ts`, `Run ls -la`, `Edit config.ts`)
16
17
  - Tool call locations surfaced for follow-along features in clients like Zed
17
- - For `edit`, emits ACP structured diffs (`oldText`/`newText`) with inferred line numbers
18
+ - For `edit` and `write`, emits ACP structured diffs (`oldText`/`newText`)
18
19
  - Tool kinds: `read`, `edit`, `execute` (bash), `other`
19
20
  - Session configuration via ACP `configOptions`
20
21
  - Model selector (category: `model`)
@@ -22,11 +23,16 @@ Active development. ACP compliance is improving steadily. Development is centere
22
23
  - Also advertises `modes` and `models` for backward compatibility
23
24
  - `session/set_config_option` for changing model or thinking level
24
25
  - `config_option_update` emitted when configuration changes
25
- - Session persistence and history
26
+ - Session persistence and lifecycle
27
+ - Multiple concurrent sessions supported
26
28
  - pi manages sessions in `~/.pi/agent/sessions/...`
27
- - `session/list` uses pi's `SessionManager` directly
28
- - `session/load` replays full conversation history
29
+ - `session/list` with title fallback from first user message
30
+ - `session/load` replays structured history (text, thinking, tool calls)
31
+ - `unstable_closeSession`, `unstable_resumeSession`, `unstable_forkSession`
29
32
  - Sessions can be resumed in both `pi` CLI and ACP clients
33
+ - Usage and cost tracking
34
+ - `usage_update` emitted after each agent turn with context size and cost
35
+ - `PromptResponse.usage` includes per-turn token counts
30
36
  - Slash commands
31
37
  - File-based prompt templates from `~/.pi/agent/prompts/` and `<cwd>/.pi/prompts/`
32
38
  - Extension commands from pi extensions
@@ -163,7 +169,7 @@ test/
163
169
 
164
170
  ### MUST-level gaps
165
171
 
166
- - **MCP servers** -- accepted in `session/new` and `session/load` params but not wired through to pi. ACP requires agents to connect to all provided MCP servers. This is the main compliance gap.
172
+ - **MCP servers** -- accepted in `session/new` and `session/load` params but not wired through to pi. ACP requires agents to connect to all provided MCP servers. This is the main compliance gap (upstream pi SDK limitation).
167
173
 
168
174
  ### SHOULD-level gaps
169
175
 
@@ -171,8 +177,7 @@ test/
171
177
 
172
178
  ### Not implemented (MAY / client capabilities)
173
179
 
174
- - **`session_info_update`** -- partially implemented (emitted by `/name` command); not emitted automatically for other metadata changes.
175
- - **`agent_plan`** -- plan updates not emitted before tool execution.
180
+ - **`agent_plan`** -- plan updates not emitted before tool execution. pi has no equivalent planning surface.
176
181
  - **ACP filesystem delegation** (`fs/read_text_file`, `fs/write_text_file`) -- pi reads/writes locally. Not advertised.
177
182
  - **ACP terminal delegation** (`terminal/*`) -- pi executes commands locally. Not advertised.
178
183
 
@@ -180,8 +185,9 @@ test/
180
185
 
181
186
  - pi does not have real session modes (ask/architect/code). The `modes` field exposes thinking levels for backward compatibility with clients that do not support `configOptions`.
182
187
  - `configOptions` is the preferred configuration mechanism. Zed uses it exclusively when present.
188
+ - pi-acp uses direct filesystem access rather than delegating reads/writes to the ACP client. This means pi reads on-disk file versions, not unsaved editor buffers.
183
189
 
184
- See [TODO.md](TODO.md) for full gap inventory and [ROADMAP.md](ROADMAP.md) for priorities.
190
+ See [docs/engineering/acp-conformance.md](docs/engineering/acp-conformance.md) for detailed conformance status.
185
191
 
186
192
  ## Release
187
193
 
package/dist/index.mjs CHANGED
@@ -41,6 +41,29 @@ function resolveTerminalLaunchCommand() {
41
41
  };
42
42
  }
43
43
  //#endregion
44
+ //#region src/acp/auth-required.ts
45
+ /**
46
+ * Detect common auth/credential errors from pi and surface them as ACP AUTH_REQUIRED.
47
+ */
48
+ const AUTH_ERROR_PATTERNS = [
49
+ "api key",
50
+ "apikey",
51
+ "missing key",
52
+ "no key",
53
+ "not configured",
54
+ "unauthorized",
55
+ "authentication",
56
+ "permission denied",
57
+ "forbidden",
58
+ "401",
59
+ "403"
60
+ ];
61
+ function detectAuthError(err) {
62
+ const lower = (err instanceof Error ? err.message : String(err ?? "")).toLowerCase();
63
+ if (!AUTH_ERROR_PATTERNS.some((p) => lower.includes(p))) return null;
64
+ return RequestError.authRequired({ authMethods: buildAuthMethods() }, "Configure an API key or log in with an OAuth provider.");
65
+ }
66
+ //#endregion
44
67
  //#region src/acp/pi-settings.ts
45
68
  /**
46
69
  * Read pi settings from global and project config files.
@@ -191,6 +214,30 @@ function toToolKind(toolName) {
191
214
  default: return "other";
192
215
  }
193
216
  }
217
+ const MAX_TITLE_LEN = 80;
218
+ function truncateTitle(text) {
219
+ const oneLine = text.replace(/\n/g, " ").trim();
220
+ if (oneLine.length <= MAX_TITLE_LEN) return oneLine;
221
+ return `${oneLine.slice(0, MAX_TITLE_LEN - 1)}…`;
222
+ }
223
+ /**
224
+ * Build a descriptive tool title from tool name and args.
225
+ *
226
+ * Returns a short human-readable label like "Read src/index.ts" or "Run ls -la".
227
+ */
228
+ function buildToolTitle(toolName, args) {
229
+ const p = args.path;
230
+ switch (toolName) {
231
+ case "read": return p !== void 0 ? `Read ${p}` : "Read";
232
+ case "write": return p !== void 0 ? `Write ${p}` : "Write";
233
+ case "edit": return p !== void 0 ? `Edit ${p}` : "Edit";
234
+ case "bash": {
235
+ const command = typeof args["command"] === "string" ? args["command"] : typeof args["cmd"] === "string" ? args["cmd"] : void 0;
236
+ return command !== void 0 ? truncateTitle(`Run ${command}`) : "bash";
237
+ }
238
+ default: return toolName;
239
+ }
240
+ }
194
241
  /**
195
242
  * Map pi assistant stopReason to ACP StopReason.
196
243
  * pi: "stop" | "length" | "toolUse" | "error" | "aborted"
@@ -382,7 +429,7 @@ var PiAcpSession = class {
382
429
  this.emit({
383
430
  sessionUpdate: "tool_call",
384
431
  toolCallId: toolCall.id,
385
- title: toolCall.name,
432
+ title: buildToolTitle(toolCall.name, rawInput),
386
433
  kind: toToolKind(toolCall.name),
387
434
  status,
388
435
  ...locations ? { locations } : {},
@@ -402,14 +449,17 @@ var PiAcpSession = class {
402
449
  }
403
450
  handleToolStart(toolCallId, toolName, args) {
404
451
  let line;
405
- if (toolName === "edit" && args.path !== void 0) try {
452
+ if ((toolName === "edit" || toolName === "write") && args.path !== void 0) try {
406
453
  const abs = isAbsolute(args.path) ? args.path : resolve(this.cwd, args.path);
407
- const oldText = readFileSync(abs, "utf8");
454
+ let oldText = "";
455
+ try {
456
+ oldText = readFileSync(abs, "utf8");
457
+ } catch {}
408
458
  this.editSnapshots.set(toolCallId, {
409
459
  path: abs,
410
460
  oldText
411
461
  });
412
- line = findUniqueLineNumber(oldText, args.oldText ?? "");
462
+ if (toolName === "edit") line = findUniqueLineNumber(oldText, args.oldText ?? "");
413
463
  } catch {}
414
464
  const locations = resolveToolPath(args, this.cwd, line);
415
465
  if (!this.currentToolCalls.has(toolCallId)) {
@@ -417,7 +467,7 @@ var PiAcpSession = class {
417
467
  this.emit({
418
468
  sessionUpdate: "tool_call",
419
469
  toolCallId,
420
- title: toolName,
470
+ title: buildToolTitle(toolName, args),
421
471
  kind: toToolKind(toolName),
422
472
  status: "in_progress",
423
473
  ...locations ? { locations } : {},
@@ -428,6 +478,7 @@ var PiAcpSession = class {
428
478
  this.emit({
429
479
  sessionUpdate: "tool_call_update",
430
480
  toolCallId,
481
+ title: buildToolTitle(toolName, args),
431
482
  status: "in_progress",
432
483
  ...locations ? { locations } : {},
433
484
  rawInput: args
@@ -487,6 +538,7 @@ var PiAcpSession = class {
487
538
  this.editSnapshots.delete(toolCallId);
488
539
  }
489
540
  handleAgentEnd() {
541
+ this.emitUsageUpdate();
490
542
  this.flushEmits().finally(() => {
491
543
  const reason = this.cancelRequested ? "cancelled" : mapPiStopReason(this.lastAssistantStopReason);
492
544
  this.lastAssistantStopReason = null;
@@ -494,6 +546,42 @@ var PiAcpSession = class {
494
546
  this.pendingTurn = null;
495
547
  });
496
548
  }
549
+ /**
550
+ * Emit a usage_update notification with current context and cost data.
551
+ */
552
+ emitUsageUpdate() {
553
+ const contextUsage = this.piSession.getContextUsage?.();
554
+ const stats = this.piSession.getSessionStats();
555
+ const used = contextUsage?.tokens ?? 0;
556
+ const size = contextUsage?.contextWindow ?? 0;
557
+ this.emit({
558
+ sessionUpdate: "usage_update",
559
+ used,
560
+ size,
561
+ cost: stats.cost > 0 ? {
562
+ amount: stats.cost,
563
+ currency: "USD"
564
+ } : null
565
+ });
566
+ }
567
+ /**
568
+ * Build ACP Usage data from pi session stats for prompt response.
569
+ */
570
+ getUsage() {
571
+ const stats = this.piSession.getSessionStats();
572
+ return {
573
+ inputTokens: stats.tokens.input,
574
+ outputTokens: stats.tokens.output,
575
+ cachedReadTokens: stats.tokens.cacheRead,
576
+ cachedWriteTokens: stats.tokens.cacheWrite
577
+ };
578
+ }
579
+ /**
580
+ * Get cumulative session cost.
581
+ */
582
+ getCost() {
583
+ return this.piSession.getSessionStats().cost;
584
+ }
497
585
  };
498
586
  /**
499
587
  * Type guard to narrow AgentSessionEvent to the AgentEvent subset
@@ -514,10 +602,6 @@ function extractUserMessageText(content) {
514
602
  if (!Array.isArray(content)) return "";
515
603
  return content.filter(isTextBlock).map((b) => b.text).join("");
516
604
  }
517
- function extractAssistantText(content) {
518
- if (!Array.isArray(content)) return "";
519
- return content.filter(isTextBlock).map((b) => b.text).join("");
520
- }
521
605
  //#endregion
522
606
  //#region src/acp/translate/prompt.ts
523
607
  function acpPromptToPiMessage(blocks) {
@@ -699,6 +783,14 @@ function parseArgs(input) {
699
783
  if (current !== "") args.push(current);
700
784
  return args;
701
785
  }
786
+ const SESSION_TITLE_MAX = 100;
787
+ function truncateSessionTitle(text) {
788
+ const trimmed = text.trim();
789
+ if (trimmed === "") return null;
790
+ const oneLine = trimmed.replace(/\n/g, " ");
791
+ if (oneLine.length <= SESSION_TITLE_MAX) return oneLine;
792
+ return `${oneLine.slice(0, SESSION_TITLE_MAX - 1)}…`;
793
+ }
702
794
  const pkg = readNearestPackageJson(import.meta.url);
703
795
  var PiAcpAgent = class {
704
796
  conn;
@@ -731,9 +823,14 @@ var PiAcpAgent = class {
731
823
  promptCapabilities: {
732
824
  image: true,
733
825
  audio: false,
734
- embeddedContext: false
826
+ embeddedContext: true
735
827
  },
736
- sessionCapabilities: { list: {} }
828
+ sessionCapabilities: {
829
+ list: {},
830
+ close: {},
831
+ resume: {},
832
+ fork: {}
833
+ }
737
834
  }
738
835
  };
739
836
  }
@@ -744,6 +841,8 @@ var PiAcpAgent = class {
744
841
  try {
745
842
  result = await createAgentSession({ cwd: params.cwd });
746
843
  } catch (e) {
844
+ const authErr = detectAuthError(e);
845
+ if (authErr !== null) throw authErr;
747
846
  const msg = e instanceof Error ? e.message : String(e);
748
847
  throw RequestError.internalError({}, `Failed to create pi session: ${msg}`);
749
848
  }
@@ -770,7 +869,6 @@ var PiAcpAgent = class {
770
869
  updateNotice
771
870
  });
772
871
  if (preludeText) session.setStartupInfo(preludeText);
773
- this.sessions.closeAllExcept(session.sessionId);
774
872
  const modes = buildThinkingModes(piSession);
775
873
  const models = buildModelState(piSession);
776
874
  const configOptions = buildConfigOptions(modes, models);
@@ -799,7 +897,9 @@ var PiAcpAgent = class {
799
897
  }, 0);
800
898
  return response;
801
899
  }
802
- async authenticate(_params) {}
900
+ async authenticate(_params) {
901
+ return {};
902
+ }
803
903
  async prompt(params) {
804
904
  const session = this.sessions.get(params.sessionId);
805
905
  const { message, images } = acpPromptToPiMessage(params.prompt);
@@ -812,7 +912,23 @@ var PiAcpAgent = class {
812
912
  if (handled) return handled;
813
913
  }
814
914
  const result = await session.prompt(message, images);
815
- return { stopReason: result === "error" ? "end_turn" : result };
915
+ const stopReason = result === "error" ? "end_turn" : result;
916
+ const usage = session.getUsage();
917
+ const cost = session.getCost();
918
+ return {
919
+ stopReason,
920
+ usage: {
921
+ inputTokens: usage.inputTokens,
922
+ outputTokens: usage.outputTokens,
923
+ cachedReadTokens: usage.cachedReadTokens,
924
+ cachedWriteTokens: usage.cachedWriteTokens,
925
+ totalTokens: usage.inputTokens + usage.outputTokens
926
+ },
927
+ _meta: cost > 0 ? { cost: {
928
+ amount: cost,
929
+ currency: "USD"
930
+ } } : {}
931
+ };
816
932
  }
817
933
  async cancel(params) {
818
934
  await this.sessions.get(params.sessionId).cancel();
@@ -829,61 +945,16 @@ var PiAcpAgent = class {
829
945
  for (const s of all) this.sessionPaths.set(s.id, s.path);
830
946
  return this.sessionPaths.get(sessionId) ?? null;
831
947
  }
832
- async listSessions(params) {
833
- const cwd = params.cwd;
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) => ({
837
- id: s.id,
838
- cwd: s.cwd,
839
- name: s.name ?? "",
840
- modified: s.modified,
841
- messageCount: s.messageCount
842
- }));
843
- if (params.cursor !== void 0 && params.cursor !== null) {
844
- const parsed = Number.parseInt(params.cursor, 10);
845
- if (!Number.isFinite(parsed) || parsed < 0) throw RequestError.invalidParams(`Invalid cursor: ${params.cursor}`);
846
- }
847
- const start = params.cursor !== void 0 && params.cursor !== null ? Number.parseInt(params.cursor, 10) : 0;
848
- const PAGE_SIZE = 50;
849
- return {
850
- sessions: sessions.slice(start, start + PAGE_SIZE).map((s) => ({
851
- sessionId: s.id,
852
- cwd: s.cwd,
853
- title: s.name ?? null,
854
- updatedAt: s.modified.toISOString()
855
- })),
856
- nextCursor: start + PAGE_SIZE < sessions.length ? String(start + PAGE_SIZE) : null,
857
- _meta: {}
858
- };
859
- }
860
- async loadSession(params) {
861
- if (!isAbsolute(params.cwd)) throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
862
- this.sessions.close(params.sessionId);
863
- const sessionFile = await this.resolveSessionFile(params.sessionId);
864
- if (sessionFile === null) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
865
- let result;
866
- try {
867
- const sm = SessionManager.open(sessionFile);
868
- result = await createAgentSession({
869
- cwd: params.cwd,
870
- sessionManager: sm
871
- });
872
- } catch (e) {
873
- const msg = e instanceof Error ? e.message : String(e);
874
- throw RequestError.internalError({}, `Failed to load pi session: ${msg}`);
875
- }
876
- const piSession = result.session;
877
- const session = new PiAcpSession({
878
- sessionId: params.sessionId,
879
- cwd: params.cwd,
880
- mcpServers: params.mcpServers,
881
- piSession,
882
- conn: this.conn
883
- });
884
- this.sessions.register(session);
885
- this.sessions.closeAllExcept(session.sessionId);
886
- const messages = piSession.messages;
948
+ /**
949
+ * Replay persisted session messages as ACP session updates.
950
+ *
951
+ * Iterates through the message history, emitting structured updates for each
952
+ * content block type: text, thinking, tool calls, and tool results. A map of
953
+ * tool call IDs to their invocation data (from assistant messages) is built
954
+ * to enrich subsequent tool result updates with rawInput and locations.
955
+ */
956
+ async replaySessionHistory(session, messages) {
957
+ const toolCallMap = /* @__PURE__ */ new Map();
887
958
  for (const m of messages) {
888
959
  if (!("role" in m)) continue;
889
960
  if (m.role === "user") {
@@ -898,32 +969,67 @@ var PiAcpAgent = class {
898
969
  }
899
970
  }
900
971
  });
972
+ continue;
901
973
  }
902
974
  if (m.role === "assistant") {
903
- const text = extractAssistantText(m.content);
904
- if (text) await this.conn.sessionUpdate({
975
+ const am = m;
976
+ for (const block of am.content) if (block.type === "text" && block.text) await this.conn.sessionUpdate({
905
977
  sessionId: session.sessionId,
906
978
  update: {
907
979
  sessionUpdate: "agent_message_chunk",
908
980
  content: {
909
981
  type: "text",
910
- text
982
+ text: block.text
983
+ }
984
+ }
985
+ });
986
+ else if (block.type === "thinking" && block.thinking) await this.conn.sessionUpdate({
987
+ sessionId: session.sessionId,
988
+ update: {
989
+ sessionUpdate: "agent_thought_chunk",
990
+ content: {
991
+ type: "text",
992
+ text: block.thinking
911
993
  }
912
994
  }
913
995
  });
996
+ else if (block.type === "toolCall") {
997
+ const args = toToolArgs(block.arguments);
998
+ toolCallMap.set(block.id, {
999
+ name: block.name,
1000
+ args
1001
+ });
1002
+ const locations = resolveToolPath(args, session.cwd);
1003
+ await this.conn.sessionUpdate({
1004
+ sessionId: session.sessionId,
1005
+ update: {
1006
+ sessionUpdate: "tool_call",
1007
+ toolCallId: block.id,
1008
+ title: buildToolTitle(block.name, args),
1009
+ kind: toToolKind(block.name),
1010
+ status: "completed",
1011
+ rawInput: args,
1012
+ ...locations ? { locations } : {}
1013
+ }
1014
+ });
1015
+ }
1016
+ continue;
914
1017
  }
915
1018
  if (m.role === "toolResult") {
916
1019
  const tr = m;
917
1020
  const toolName = tr.toolName;
918
1021
  const toolCallId = tr.toolCallId;
919
1022
  const isError = tr.isError;
920
- await this.conn.sessionUpdate({
1023
+ const invocation = toolCallMap.get(toolCallId);
1024
+ const args = invocation?.args;
1025
+ const locations = args !== void 0 ? resolveToolPath(args, session.cwd) : void 0;
1026
+ if (invocation === void 0) await this.conn.sessionUpdate({
921
1027
  sessionId: session.sessionId,
922
1028
  update: {
923
1029
  sessionUpdate: "tool_call",
924
1030
  toolCallId,
925
- title: toolName,
926
- kind: toolName === "read" ? "read" : toolName === "write" || toolName === "edit" ? "edit" : "other",
1031
+ title: buildToolTitle(toolName, {}),
1032
+ kind: toToolKind(toolName),
927
1033
  status: "completed",
928
1034
  rawInput: null,
929
1035
  rawOutput: m
@@ -943,11 +1049,70 @@ var PiAcpAgent = class {
943
1049
  text
944
1050
  }
945
1051
  }] : null,
946
- rawOutput: m
1052
+ rawOutput: m,
1053
+ ...locations ? { locations } : {}
947
1054
  }
948
1055
  });
949
1056
  }
950
1057
  }
1058
+ }
1059
+ async listSessions(params) {
1060
+ const cwd = params.cwd;
1061
+ const raw = cwd !== void 0 && cwd !== null ? await SessionManager.list(cwd) : await SessionManager.listAll();
1062
+ for (const s of raw) this.sessionPaths.set(s.id, s.path);
1063
+ const sessions = raw.map((s) => ({
1064
+ id: s.id,
1065
+ cwd: s.cwd,
1066
+ name: s.name,
1067
+ firstMessage: s.firstMessage,
1068
+ modified: s.modified,
1069
+ messageCount: s.messageCount
1070
+ }));
1071
+ if (params.cursor !== void 0 && params.cursor !== null) {
1072
+ const parsed = Number.parseInt(params.cursor, 10);
1073
+ if (!Number.isFinite(parsed) || parsed < 0) throw RequestError.invalidParams(`Invalid cursor: ${params.cursor}`);
1074
+ }
1075
+ const start = params.cursor !== void 0 && params.cursor !== null ? Number.parseInt(params.cursor, 10) : 0;
1076
+ const PAGE_SIZE = 50;
1077
+ return {
1078
+ sessions: sessions.slice(start, start + PAGE_SIZE).map((s) => ({
1079
+ sessionId: s.id,
1080
+ cwd: s.cwd,
1081
+ title: (s.name !== void 0 && s.name !== "" ? s.name : null) ?? truncateSessionTitle(s.firstMessage) ?? null,
1082
+ updatedAt: s.modified.toISOString()
1083
+ })),
1084
+ nextCursor: start + PAGE_SIZE < sessions.length ? String(start + PAGE_SIZE) : null,
1085
+ _meta: {}
1086
+ };
1087
+ }
1088
+ async loadSession(params) {
1089
+ if (!isAbsolute(params.cwd)) throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
1090
+ this.sessions.close(params.sessionId);
1091
+ const sessionFile = await this.resolveSessionFile(params.sessionId);
1092
+ if (sessionFile === null) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
1093
+ let result;
1094
+ try {
1095
+ const sm = SessionManager.open(sessionFile);
1096
+ result = await createAgentSession({
1097
+ cwd: params.cwd,
1098
+ sessionManager: sm
1099
+ });
1100
+ } catch (e) {
1101
+ const authErr = detectAuthError(e);
1102
+ if (authErr !== null) throw authErr;
1103
+ const msg = e instanceof Error ? e.message : String(e);
1104
+ throw RequestError.internalError({}, `Failed to load pi session: ${msg}`);
1105
+ }
1106
+ const piSession = result.session;
1107
+ const session = new PiAcpSession({
1108
+ sessionId: params.sessionId,
1109
+ cwd: params.cwd,
1110
+ mcpServers: params.mcpServers,
1111
+ piSession,
1112
+ conn: this.conn
1113
+ });
1114
+ this.sessions.register(session);
1115
+ await this.replaySessionHistory(session, piSession.messages);
951
1116
  const modes = buildThinkingModes(piSession);
952
1117
  const models = buildModelState(piSession);
953
1118
  const configOptions = buildConfigOptions(modes, models);
@@ -973,6 +1138,124 @@ var PiAcpAgent = class {
973
1138
  _meta: { piAcp: { startupInfo: null } }
974
1139
  };
975
1140
  }
1141
+ async unstable_closeSession(params) {
1142
+ if (this.sessions.maybeGet(params.sessionId) === void 0) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
1143
+ this.sessions.close(params.sessionId);
1144
+ return {};
1145
+ }
1146
+ async unstable_resumeSession(params) {
1147
+ if (!isAbsolute(params.cwd)) throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
1148
+ const existing = this.sessions.maybeGet(params.sessionId);
1149
+ if (existing !== void 0) {
1150
+ const modes = buildThinkingModes(existing.piSession);
1151
+ const models = buildModelState(existing.piSession);
1152
+ return {
1153
+ configOptions: buildConfigOptions(modes, models),
1154
+ modes,
1155
+ models
1156
+ };
1157
+ }
1158
+ const sessionFile = await this.resolveSessionFile(params.sessionId);
1159
+ if (sessionFile === null) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
1160
+ let result;
1161
+ try {
1162
+ const sm = SessionManager.open(sessionFile);
1163
+ result = await createAgentSession({
1164
+ cwd: params.cwd,
1165
+ sessionManager: sm
1166
+ });
1167
+ } catch (e) {
1168
+ const authErr = detectAuthError(e);
1169
+ if (authErr !== null) throw authErr;
1170
+ const msg = e instanceof Error ? e.message : String(e);
1171
+ throw RequestError.internalError({}, `Failed to resume pi session: ${msg}`);
1172
+ }
1173
+ const piSession = result.session;
1174
+ const session = new PiAcpSession({
1175
+ sessionId: params.sessionId,
1176
+ cwd: params.cwd,
1177
+ mcpServers: params.mcpServers ?? [],
1178
+ piSession,
1179
+ conn: this.conn
1180
+ });
1181
+ this.sessions.register(session);
1182
+ this.sessionPaths.set(params.sessionId, sessionFile);
1183
+ const enableSkillCommands = skillCommandsEnabled(params.cwd);
1184
+ setTimeout(() => {
1185
+ (async () => {
1186
+ try {
1187
+ const commands = buildCommandList(piSession, enableSkillCommands);
1188
+ await this.conn.sessionUpdate({
1189
+ sessionId: session.sessionId,
1190
+ update: {
1191
+ sessionUpdate: "available_commands_update",
1192
+ availableCommands: mergeCommands(commands, builtinAvailableCommands())
1193
+ }
1194
+ });
1195
+ } catch {}
1196
+ })();
1197
+ }, 0);
1198
+ const modes = buildThinkingModes(piSession);
1199
+ const models = buildModelState(piSession);
1200
+ return {
1201
+ configOptions: buildConfigOptions(modes, models),
1202
+ modes,
1203
+ models
1204
+ };
1205
+ }
1206
+ async unstable_forkSession(params) {
1207
+ if (!isAbsolute(params.cwd)) throw RequestError.invalidParams(`cwd must be an absolute path: ${params.cwd}`);
1208
+ const sourceFile = await this.resolveSessionFile(params.sessionId);
1209
+ if (sourceFile === null) throw RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);
1210
+ let result;
1211
+ try {
1212
+ const sm = SessionManager.forkFrom(sourceFile, params.cwd);
1213
+ result = await createAgentSession({
1214
+ cwd: params.cwd,
1215
+ sessionManager: sm
1216
+ });
1217
+ } catch (e) {
1218
+ const authErr = detectAuthError(e);
1219
+ if (authErr !== null) throw authErr;
1220
+ const msg = e instanceof Error ? e.message : String(e);
1221
+ throw RequestError.internalError({}, `Failed to fork pi session: ${msg}`);
1222
+ }
1223
+ const piSession = result.session;
1224
+ const newSessionId = piSession.sessionManager.getSessionId();
1225
+ const newSessionFile = piSession.sessionManager.getSessionFile();
1226
+ if (newSessionFile !== void 0) this.sessionPaths.set(newSessionId, newSessionFile);
1227
+ const session = new PiAcpSession({
1228
+ sessionId: newSessionId,
1229
+ cwd: params.cwd,
1230
+ mcpServers: params.mcpServers ?? [],
1231
+ piSession,
1232
+ conn: this.conn
1233
+ });
1234
+ this.sessions.register(session);
1235
+ const enableSkillCommands = skillCommandsEnabled(params.cwd);
1236
+ setTimeout(() => {
1237
+ (async () => {
1238
+ try {
1239
+ const commands = buildCommandList(piSession, enableSkillCommands);
1240
+ await this.conn.sessionUpdate({
1241
+ sessionId: session.sessionId,
1242
+ update: {
1243
+ sessionUpdate: "available_commands_update",
1244
+ availableCommands: mergeCommands(commands, builtinAvailableCommands())
1245
+ }
1246
+ });
1247
+ } catch {}
1248
+ })();
1249
+ }, 0);
1250
+ const modes = buildThinkingModes(piSession);
1251
+ const models = buildModelState(piSession);
1252
+ return {
1253
+ sessionId: newSessionId,
1254
+ configOptions: buildConfigOptions(modes, models),
1255
+ modes,
1256
+ models
1257
+ };
1258
+ }
976
1259
  async setSessionMode(params) {
977
1260
  const session = this.sessions.get(params.sessionId);
978
1261
  const mode = String(params.modeId);
@@ -1414,10 +1697,15 @@ function buildCommandList(piSession, enableSkillCommands) {
1414
1697
  });
1415
1698
  return commands;
1416
1699
  }
1700
+ let cachedUpdateNotice;
1417
1701
  function buildUpdateNotice() {
1702
+ if (cachedUpdateNotice !== void 0) return cachedUpdateNotice;
1418
1703
  try {
1419
1704
  const installed = VERSION;
1420
- if (!installed || !isSemver(installed)) return null;
1705
+ if (!installed || !isSemver(installed)) {
1706
+ cachedUpdateNotice = null;
1707
+ return null;
1708
+ }
1421
1709
  const latestRes = spawnSync("npm", [
1422
1710
  "view",
1423
1711
  "@mariozechner/pi-coding-agent",
@@ -1427,10 +1715,18 @@ function buildUpdateNotice() {
1427
1715
  timeout: 800
1428
1716
  });
1429
1717
  const latest = String(latestRes.stdout ?? "").trim().replace(/^v/i, "");
1430
- if (!latest || !isSemver(latest)) return null;
1431
- if (compareSemver(latest, installed) <= 0) return null;
1432
- return `New version available: v${latest} (installed v${installed}). Run: \`npm i -g @mariozechner/pi-coding-agent\``;
1718
+ if (!latest || !isSemver(latest)) {
1719
+ cachedUpdateNotice = null;
1720
+ return null;
1721
+ }
1722
+ if (compareSemver(latest, installed) <= 0) {
1723
+ cachedUpdateNotice = null;
1724
+ return null;
1725
+ }
1726
+ cachedUpdateNotice = `New version available: v${latest} (installed v${installed}). Run: \`npm i -g @mariozechner/pi-coding-agent\``;
1727
+ return cachedUpdateNotice;
1433
1728
  } catch {
1729
+ cachedUpdateNotice = null;
1434
1730
  return null;
1435
1731
  }
1436
1732
  }
@@ -1 +1 @@
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":";;;;;;;;;;AASA,MAAa,iBAAiB;AAM9B,SAAgB,iBAAiB,MAAwC;CACxE,MAAM,2BAA2B,MAAM,4BAA4B;CAEnE,MAAM,SAAqB;EAC1B,IAAI;EACJ,MAAM;EACN,aAAa;EACb,MAAM;EACN,MAAM,CAAC,mBAAmB;EAC1B,KAAK,EAAE;EACP;AAED,KAAI,0BAA0B;EAC7B,MAAM,SAAS,8BAA8B;AAC7C,SAAO,QAAQ,EACd,iBAAiB;GAChB,GAAG;GACH,OAAO;GACP,EACD;;AAGF,QAAO,CAAC,OAAO;;AAGhB,SAAS,+BAAoE;CAC5E,MAAM,QAAQ,QAAQ,KAAK,MAAM;CACjC,MAAM,QAAQ,QAAQ,KAAK;AAE3B,KAAI,UAAU,KAAA,KAAa,MAAM,SAAS,OAAO,IAAI,MAAM,SAAS,MAAM,CACzE,QAAO;EAAE,SAAS;EAAO,MAAM,CAAC,OAAO,mBAAmB;EAAE;AAG7D,QAAO;EAAE,SAAS;EAAU,MAAM,CAAC,mBAAmB;EAAE;;;;;;;;;;;;AClCzD,MAAM,mBAAmB,EAAE,OAAO;CACjC,qBAAqB,EAAE,SAAS,CAAC,UAAU;CAC3C,cAAc,EAAE,SAAS,CAAC,UAAU;CACpC,YAAY,EAAE,SAAS,CAAC,UAAU;CAClC,QAAQ,EACN,OAAO,EACP,qBAAqB,EAAE,SAAS,CAAC,UAAU,EAC3C,CAAC,CACD,UAAU;CACZ,CAAC;AAIF,SAAS,SAAS,GAA0C;AAC3D,QAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,EAAE;;AAGhE,SAAS,MACR,MACA,UAC0B;CAC1B,MAAM,SAAkC,EAAE,GAAG,MAAM;AACnD,MAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,SAAS,EAAE;EAClD,MAAM,WAAW,OAAO;AACxB,MAAI,SAAS,SAAS,IAAI,SAAS,IAAI,CACtC,QAAO,OAAO,MAAM,UAAU,IAAI;MAElC,QAAO,OAAO;;AAGhB,QAAO;;AAGR,SAAS,SAAS,MAAuC;AACxD,KAAI;AACH,MAAI,CAAC,WAAW,KAAK,CAAE,QAAO,EAAE;EAChC,MAAM,OAAgB,KAAK,MAAM,aAAa,MAAM,QAAQ,CAAC;AAC7D,SAAO,SAAS,KAAK,GAAG,OAAO,EAAE;SAC1B;AACP,SAAO,EAAE;;;AAIX,SAAgB,aAAqB;AACpC,QAAO,QAAQ,IAAI,wBAAwB,KAAA,IACxC,QAAQ,QAAQ,IAAI,oBAAoB,GACxC,KAAK,SAAS,EAAE,OAAO,QAAQ;;AAGnC,SAAS,iBAAiB,KAAyB;CAClD,MAAM,aAAa,KAAK,YAAY,EAAE,gBAAgB;CACtD,MAAM,cAAc,QAAQ,KAAK,OAAO,gBAAgB;CACxD,MAAM,SAAS,MAAM,SAAS,WAAW,EAAE,SAAS,YAAY,CAAC;CACjE,MAAM,SAAS,iBAAiB,UAAU,OAAO;AACjD,QAAO,OAAO,UAAU,OAAO,OAAO,EAAE;;AAGzC,SAAgB,qBAAqB,KAAsB;CAC1D,MAAM,WAAW,iBAAiB,IAAI;AAEtC,KAAI,OAAO,SAAS,wBAAwB,UAC3C,QAAO,SAAS;AAGjB,KAAI,OAAO,SAAS,QAAQ,wBAAwB,UACnD,QAAO,SAAS,OAAO;AAGxB,QAAO;;AAGR,SAAgB,oBAAoB,KAAsB;CACzD,MAAM,WAAW,iBAAiB,IAAI;AAEtC,KAAI,OAAO,SAAS,iBAAiB,UACpC,QAAO,SAAS;AAGjB,KAAI,OAAO,SAAS,eAAe,UAClC,QAAO,SAAS;AAGjB,QAAO;;;;;;;;;;;ACtFR,MAAM,kBAAkB,EAAE,OAAO;CAChC,MAAM,EAAE,QAAQ,OAAO;CACvB,MAAM,EAAE,QAAQ;CAChB,CAAC;AAEF,MAAM,oBAAoB,EAAE,OAAO;CAClC,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,CAAC;AAEF,MAAM,mBAAmB,EAAE,OAAO;CACjC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,UAAU;CACxC,SAAS,kBAAkB,UAAU;CACrC,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,QAAQ,EAAE,QAAQ,CAAC,UAAU;CAC7B,UAAU,EAAE,QAAQ,CAAC,UAAU;CAC/B,MAAM,EAAE,QAAQ,CAAC,UAAU;CAC3B,CAAC;AAEF,SAAgB,iBAAiB,QAAyB;AACzD,KAAI,WAAW,QAAQ,WAAW,KAAA,KAAa,OAAO,WAAW,SAAU,QAAO;CAElF,MAAM,SAAS,iBAAiB,UAAU,OAAO;AACjD,KAAI,CAAC,OAAO,QACX,KAAI;AACH,SAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;SAC/B;AACP,SAAO,OAAO,OAAO;;CAIvB,MAAM,IAAI,OAAO;AAEjB,KAAI,EAAE,YAAY,KAAA,GAAW;EAC5B,MAAM,QAAQ,EAAE,QACd,KAAK,UAAU,gBAAgB,UAAU,MAAM,CAAC,CAChD,QAAQ,QAAQ,IAAI,QAAQ,CAC5B,KAAK,QAAQ,IAAI,KAAK,KAAK;AAC7B,MAAI,MAAM,SAAS,EAAG,QAAO,MAAM,KAAK,GAAG;;CAG5C,MAAM,IAAI,EAAE;CAEZ,MAAM,OAAO,GAAG;AAChB,KAAI,SAAS,KAAA,KAAa,KAAK,MAAM,KAAK,GAAI,QAAO;CAErD,MAAM,SAAS,GAAG,UAAU,EAAE,UAAU,GAAG,UAAU,EAAE;CACvD,MAAM,SAAS,GAAG,UAAU,EAAE;CAC9B,MAAM,WAAW,GAAG,YAAY,EAAE,YAAY,GAAG,QAAQ,EAAE;CAE3D,MAAM,YAAY,WAAW,KAAA,KAAa,OAAO,MAAM,KAAK;CAC5D,MAAM,YAAY,WAAW,KAAA,KAAa,OAAO,MAAM,KAAK;AAE5D,KAAI,aAAa,WAAW;EAC3B,MAAM,QAAkB,EAAE;AAC1B,MAAI,UAAW,OAAM,KAAK,OAAO;AACjC,MAAI,UAAW,OAAM,KAAK,YAAY,SAAS;AAC/C,MAAI,aAAa,KAAA,EAAW,OAAM,KAAK,cAAc,WAAW;AAChE,SAAO,MAAM,KAAK,OAAO,CAAC,SAAS;;AAGpC,KAAI;AACH,SAAO,KAAK,UAAU,QAAQ,MAAM,EAAE;SAC/B;AACP,SAAO,OAAO,OAAO;;;;;ACvDvB,SAAS,qBAAqB,MAAc,QAAoC;AAC/E,KAAI,CAAC,OAAQ,QAAO,KAAA;CACpB,MAAM,QAAQ,KAAK,QAAQ,OAAO;AAClC,KAAI,QAAQ,EAAG,QAAO,KAAA;AACtB,KAAI,KAAK,QAAQ,QAAQ,QAAQ,OAAO,OAAO,IAAI,EAAG,QAAO,KAAA;CAE7D,IAAI,OAAO;AACX,MAAK,IAAI,IAAI,GAAG,IAAI,OAAO,IAC1B,KAAI,KAAK,WAAW,EAAE,KAAK,GAAI;AAEhC,QAAO;;AASR,SAAS,gBACR,MACA,KACA,MACiC;CACjC,MAAM,IAAI,KAAK;AACf,KAAI,MAAM,KAAA,EAAW,QAAO,KAAA;AAG5B,QAAO,CAAC;EAAE,MADO,WAAW,EAAE,GAAG,IAAIA,QAAY,KAAK,EAAE;EAC9B,GAAI,OAAO,SAAS,WAAW,EAAE,MAAM,GAAG,EAAE;EAAG,CAAC;;AAG3E,SAAS,WAAW,UAA4B;AAC/C,SAAQ,UAAR;EACC,KAAK,OACJ,QAAO;EACR,KAAK;EACL,KAAK,OACJ,QAAO;EACR,KAAK,OACJ,QAAO;EACR,QACC,QAAO;;;;;;;;AASV,SAAS,gBAAgB,UAAqC;AAC7D,SAAQ,UAAR;EACC,KAAK;EACL,KAAK,UACJ,QAAO;EACR,KAAK,SACJ,QAAO;EACR,KAAK,UACJ,QAAO;EACR,KAAK,QACJ,QAAO;EACR,QACC,QAAO;;;AAIV,SAAS,2BAA2B,KAAkD;AACrF,KAAI,EAAE,aAAa,KAAM,QAAO,KAAA;CAGhC,MAAM,QAFU,IAAI,QAAQ,QAChB,kBAAkB,MAAM,IAAI,eAAe;AAEvD,KAAI,SAAS,UAAU,SAAS,MAAM,SAAS,WAAY,QAAO;;AAInE,SAAS,eAAe,IAAwB;AAC/C,QAAO,GAAG;;AAGX,MAAM,iBAAiB,EACrB,OAAO;CACP,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;CAClC,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU;CACrC,CAAC,CACD,OAAO;AAET,SAAS,WAAW,KAAwB;CAC3C,MAAM,SAAS,eAAe,UAAU,IAAI;AAC5C,QAAO,OAAO,UAAU,OAAO,OAAO,EAAE;;AAOzC,IAAaC,mBAAb,MAA4B;CAC3B,2BAAmB,IAAI,KAA2B;CAElD,aAAmB;AAClB,OAAK,MAAM,MAAM,KAAK,SAAS,MAAM,CAAE,MAAK,MAAM,GAAG;;CAGtD,SAAS,WAA6C;AACrD,SAAO,KAAK,SAAS,IAAI,UAAU;;CAGpC,MAAM,WAAyB;EAC9B,MAAM,IAAI,KAAK,SAAS,IAAI,UAAU;AACtC,MAAI,CAAC,EAAG;AACR,MAAI;AACH,KAAE,SAAS;UACJ;AAGR,OAAK,SAAS,OAAO,UAAU;;CAGhC,eAAe,eAA6B;AAC3C,OAAK,MAAM,MAAM,KAAK,SAAS,MAAM,CACpC,KAAI,OAAO,cAAe,MAAK,MAAM,GAAG;;CAI1C,SAAS,SAA6B;AACrC,OAAK,SAAS,IAAI,QAAQ,WAAW,QAAQ;;CAG9C,IAAI,WAAiC;EACpC,MAAM,IAAI,KAAK,SAAS,IAAI,UAAU;AACtC,MAAI,CAAC,EAAG,OAAM,aAAa,cAAc,sBAAsB,YAAY;AAC3E,SAAO;;;AAgBT,IAAa,eAAb,MAA0B;CACzB;CACA;CACA;CACA;CAEA,cAAqC;CACrC,kBAA0B;CAC1B;CAEA,kBAA0B;CAC1B,cACC;CAED,mCAA2B,IAAI,KAAwC;CACvE,gCAAwB,IAAI,KAAgD;CAC5E,0BAAiD;CACjD,WAAkC,QAAQ,SAAS;CACnD;CAEA,YAAY,MAAwB;AACnC,OAAK,YAAY,KAAK;AACtB,OAAK,MAAM,KAAK;AAChB,OAAK,aAAa,KAAK;AACvB,OAAK,YAAY,KAAK;AACtB,OAAK,OAAO,KAAK;AACjB,OAAK,cAAc,KAAK,UAAU,WAAW,OAA0B,KAAK,cAAc,GAAG,CAAC;;CAG/F,UAAgB;AACf,OAAK,eAAe;AACpB,OAAK,UAAU,SAAS;;CAGzB,eAAe,MAAoB;AAClC,OAAK,cAAc;;CAGpB,2BAAiC;AAChC,MAAI,KAAK,mBAAmB,KAAK,gBAAgB,KAAM;AACvD,OAAK,kBAAkB;AACvB,OAAK,KAAK;GACT,eAAe;GACf,SAAS;IAAE,MAAM;IAAQ,MAAM,KAAK;IAAa;GACjD,CAAC;;CAGH,MAAM,OAAO,SAAiB,SAAoB,EAAE,EAAuB;EAC1E,MAAM,cAAc,IAAI,SAAqB,SAAS,WAAW;AAChE,QAAK,kBAAkB;AACvB,QAAK,cAAc;IAAE;IAAS;IAAQ;IACrC;EAEF,MAAM,gBAAgB,MAAM,QAAQ,OAAO,GACxC,OAAO,QACN,QACA,OAAO,QAAQ,YAAY,QAAQ,QAAQ,UAAU,OAAO,IAAI,SAAS,QAC1E,GACA,EAAE;AAEL,OAAK,UAAU,OAAO,SAAS,EAAE,QAAQ,eAAe,CAAC,CAAC,YAAY;AAChE,QAAK,YAAY,CAAC,cAAc;IACpC,MAAM,SAAqB,KAAK,kBAAkB,cAAc;AAChE,SAAK,aAAa,QAAQ,OAAO;AACjC,SAAK,cAAc;KAClB;IACD;AAEF,SAAO;;CAGR,MAAM,SAAwB;AAC7B,OAAK,kBAAkB;AACvB,QAAM,KAAK,UAAU,OAAO;;CAG7B,qBAA8B;AAC7B,SAAO,KAAK;;CAOb,KAAa,QAA6B;AACzC,OAAK,WAAW,KAAK,SACnB,WAAW,KAAK,KAAK,cAAc;GAAE,WAAW,KAAK;GAAW;GAAQ,CAAC,CAAC,CAC1E,YAAY,GAAG;;CAGlB,MAAc,aAA4B;AACzC,QAAM,KAAK;;CAGZ,cAAsB,IAA6B;AAClD,MAAI,CAAC,aAAa,GAAG,CAAE;AAEvB,UAAQ,GAAG,MAAX;GACC,KAAK;AACJ,SAAK,oBAAoB,GAAG,sBAAsB;AAClD;GACD,KAAK;AACJ,SAAK,iBAAiB,GAAG,QAAQ;AACjC;GACD,KAAK;AACJ,SAAK,gBAAgB,GAAG,YAAY,GAAG,UAAU,WAAW,GAAG,KAAK,CAAC;AACrE;GACD,KAAK;AACJ,SAAK,iBAAiB,GAAG,YAAY,GAAG,cAAc;AACtD;GACD,KAAK;AACJ,SAAK,cAAc,GAAG,YAAY,GAAG,QAAQ,GAAG,QAAQ;AACxD;GACD,KAAK;AACJ,SAAK,gBAAgB;AACrB;GACD,QACC;;;CAIH,oBAA4B,KAAkC;AAC7D,MAAI,IAAI,SAAS,cAAc;AAC9B,QAAK,KAAK;IACT,eAAe;IACf,SAAS;KAAE,MAAM;KAAQ,MAAM,IAAI;KAAO;IAC1C,CAAC;AACF;;AAGD,MAAI,IAAI,SAAS,kBAAkB;AAClC,QAAK,KAAK;IACT,eAAe;IACf,SAAS;KAAE,MAAM;KAAQ,MAAM,IAAI;KAAO;IAC1C,CAAC;AACF;;AAGD,MACC,IAAI,SAAS,oBACb,IAAI,SAAS,oBACb,IAAI,SAAS,gBACZ;GACD,MAAM,WAAW,IAAI,SAAS,iBAAiB,IAAI,WAAW,2BAA2B,IAAI;AAC7F,OAAI,CAAC,SAAU;GAEf,MAAM,WAAW,eAAe,SAAS;GACzC,MAAM,YAAY,gBAAgB,UAAU,KAAK,IAAI;GACrD,MAAM,iBAAiB,KAAK,iBAAiB,IAAI,SAAS,GAAG;GAC7D,MAAM,SAAS,kBAAkB;AAEjC,OAAI,CAAC,gBAAgB;AACpB,SAAK,iBAAiB,IAAI,SAAS,IAAI,UAAU;AACjD,SAAK,KAAK;KACT,eAAe;KACf,YAAY,SAAS;KACrB,OAAO,SAAS;KAChB,MAAM,WAAW,SAAS,KAAK;KAC/B;KACA,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;KAClC;KACA,CAAC;SAEF,MAAK,KAAK;IACT,eAAe;IACf,YAAY,SAAS;IACrB;IACA,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;IAClC;IACA,CAAC;;;CAKL,iBAAyB,KAAyB;AACjD,MAAI,UAAU,OAAO,IAAI,SAAS,YACjC,MAAK,0BAA0B,IAAI;;CAIrC,gBAAwB,YAAoB,UAAkB,MAAsB;EACnF,IAAI;AAEJ,MAAI,aAAa,UAAU,KAAK,SAAS,KAAA,EACxC,KAAI;GACH,MAAM,MAAM,WAAW,KAAK,KAAK,GAAG,KAAK,OAAOD,QAAY,KAAK,KAAK,KAAK,KAAK;GAChF,MAAM,UAAU,aAAa,KAAK,OAAO;AACzC,QAAK,cAAc,IAAI,YAAY;IAAE,MAAM;IAAK;IAAS,CAAC;AAC1D,UAAO,qBAAqB,SAAS,KAAK,WAAW,GAAG;UACjD;EAKT,MAAM,YAAY,gBAAgB,MAAM,KAAK,KAAK,KAAK;AAEvD,MAAI,CAAC,KAAK,iBAAiB,IAAI,WAAW,EAAE;AAC3C,QAAK,iBAAiB,IAAI,YAAY,cAAc;AACpD,QAAK,KAAK;IACT,eAAe;IACf;IACA,OAAO;IACP,MAAM,WAAW,SAAS;IAC1B,QAAQ;IACR,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;IAClC,UAAU;IACV,CAAC;SACI;AACN,QAAK,iBAAiB,IAAI,YAAY,cAAc;AACpD,QAAK,KAAK;IACT,eAAe;IACf;IACA,QAAQ;IACR,GAAI,YAAY,EAAE,WAAW,GAAG,EAAE;IAClC,UAAU;IACV,CAAC;;;CAIJ,iBAAyB,YAAoB,eAA8B;EAC1E,MAAM,OAAO,iBAAiB,cAAc;AAC5C,OAAK,KAAK;GACT,eAAe;GACf;GACA,QAAQ;GACR,SAAS,OACL,CAAC;IAAE,MAAM;IAAW,SAAS;KAAE,MAAM;KAAQ;KAAM;IAAE,CAAC,GACvD;GACH,WAAW;GACX,CAAC;;CAGH,cAAsB,YAAoB,QAAiB,SAAwB;EAClF,MAAM,OAAO,iBAAiB,OAAO;EACrC,MAAM,WAAW,KAAK,cAAc,IAAI,WAAW;EACnD,IAAI,UAAoC;AAExC,MAAI,CAAC,WAAW,SACf,KAAI;GACH,MAAM,UAAU,aAAa,SAAS,MAAM,OAAO;AACnD,OAAI,YAAY,SAAS,QACxB,WAAU,CACT;IAAE,MAAM;IAAQ,MAAM,SAAS;IAAM,SAAS,SAAS;IAAS;IAAS,EACzE,GAAI,OACA,CAAC;IAAE,MAAM;IAAW,SAAS;KAAE,MAAM;KAAQ;KAAM;IAAE,CAAC,GACvD,EAAE,CACL;UAEK;AAKT,MAAI,CAAC,WAAW,KACf,WAAU,CAAC;GAAE,MAAM;GAAW,SAAS;IAAE,MAAM;IAAQ;IAAM;GAAE,CAAC;AAGjE,OAAK,KAAK;GACT,eAAe;GACf;GACA,QAAQ,UAAU,WAAW;GAC7B;GACA,WAAW;GACX,CAAC;AAEF,OAAK,iBAAiB,OAAO,WAAW;AACxC,OAAK,cAAc,OAAO,WAAW;;CAGtC,iBAA+B;AACzB,OAAK,YAAY,CAAC,cAAc;GACpC,MAAM,SAAqB,KAAK,kBAC7B,cACA,gBAAgB,KAAK,wBAAwB;AAChD,QAAK,0BAA0B;AAC/B,QAAK,aAAa,QAAQ,OAAO;AACjC,QAAK,cAAc;IAClB;;;;;;;;AASJ,SAAS,aACR,IASC;AACD,QACC,GAAG,SAAS,oBACZ,GAAG,SAAS,iBACZ,GAAG,SAAS,0BACZ,GAAG,SAAS,2BACZ,GAAG,SAAS,wBACZ,GAAG,SAAS;;;;AC7cd,SAAS,YAAY,OAAoC;AACxD,KAAI,OAAO,UAAU,YAAY,UAAU,KAAM,QAAO;AACxD,QACC,UAAU,SAAS,MAAM,SAAS,UAAU,UAAU,SAAS,OAAO,MAAM,SAAS;;AAIvF,SAAgB,uBAAuB,SAA0B;AAChE,KAAI,OAAO,YAAY,SAAU,QAAO;AACxC,KAAI,CAAC,MAAM,QAAQ,QAAQ,CAAE,QAAO;AACpC,QAAO,QACL,OAAO,YAAY,CACnB,KAAK,MAAM,EAAE,KAAK,CAClB,KAAK,GAAG;;AAGX,SAAgB,qBAAqB,SAA0B;AAC9D,KAAI,CAAC,MAAM,QAAQ,QAAQ,CAAE,QAAO;AACpC,QAAO,QACL,OAAO,YAAY,CACnB,KAAK,MAAM,EAAE,KAAK,CAClB,KAAK,GAAG;;;;ACrBX,SAAgB,qBAAqB,QAGnC;CACD,IAAI,UAAU;CACd,MAAM,SAAoB,EAAE;AAE5B,MAAK,MAAM,SAAS,OACnB,SAAQ,MAAM,MAAd;EACC,KAAK;AACJ,cAAW,MAAM;AACjB;EAED,KAAK;AACJ,cAAW,eAAe,MAAM;AAChC;EAED,KAAK;AACJ,UAAO,KAAK;IACX,MAAM;IACN,UAAU,MAAM;IAChB,MAAM,MAAM;IACZ,CAAC;AACF;EAED,KAAK,YAAY;GAChB,MAAM,WAAW,MAAM;GACvB,MAAM,MAAM,SAAS;GACrB,MAAM,OAAO,SAAS,YAAY;AAElC,OAAI,UAAU,SACb,YAAW,wBAAwB,IAAI,IAAI,QAAQ,aAAa,KAAK,SAAS;YACpE,UAAU,UAAU;IAC9B,MAAM,QAAQ,OAAO,WAAW,SAAS,MAAM,SAAS;AACxD,eAAW,wBAAwB,IAAI,IAAI,QAAQ,2BAA2B,IAAI,MAAM;SAExF,YAAW,wBAAwB;AAEpC;;EAGD,KAAK,SAAS;GACb,MAAM,QAAQ,OAAO,WAAW,MAAM,MAAM,SAAS;AACrD,cAAW,cAAc,MAAM,SAAS,IAAI,MAAM;AAClD;;EAGD,QACC;;AAIH,QAAO;EAAE;EAAS;EAAQ;;;;;;;;;;;;AClD3B,MAAM,qBAAqB,EAAE,OAAO,EACnC,WAAW,EACT,OACA,EAAE,QAAQ,CAAC,MAAM,EACjB,EAAE,OAAO,EACR,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,UAAU,EACpC,CAAC,CACF,CACA,UAAU,EACZ,CAAC;AAEF,SAAS,WAAmB;CAC3B,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,QAAQ,KAAA,EAAW,QAAO,KAAK,SAAS,EAAE,OAAO,QAAQ;AAC7D,KAAI,QAAQ,IAAK,QAAO,SAAS;AACjC,KAAI,IAAI,WAAW,KAAK,CAAE,QAAO,SAAS,GAAG,IAAI,MAAM,EAAE;AACzD,QAAO;;AAGR,SAAS,aAAa,MAAuB;AAC5C,KAAI;AACH,MAAI,CAAC,WAAW,KAAK,CAAE,QAAO;EAC9B,MAAM,MAAM,aAAa,MAAM,QAAQ,CAAC,MAAM;AAC9C,MAAI,CAAC,IAAK,QAAO;AACjB,SAAO,KAAK,MAAM,IAAI;SACf;AACP,SAAO;;;AAIT,SAAS,cAAuB;CAC/B,MAAM,OAAO,aAAa,KAAK,UAAU,EAAE,YAAY,CAAC;AACxD,QAAO,OAAO,SAAS,YAAY,SAAS,QAAQ,OAAO,KAAK,KAAK,CAAC,SAAS;;AAGhF,SAAS,uBAAgC;CACxC,MAAM,MAAM,aAAa,KAAK,UAAU,EAAE,cAAc,CAAC;CACzD,MAAM,SAAS,mBAAmB,UAAU,IAAI;AAChD,KAAI,CAAC,OAAO,WAAW,CAAC,OAAO,KAAK,UAAW,QAAO;AAEtD,QAAO,OAAO,OAAO,OAAO,KAAK,UAAU,CAAC,MAC1C,aAAa,OAAO,SAAS,WAAW,YAAY,SAAS,OAAO,MAAM,CAAC,SAAS,EACrF;;;AAIF,MAAM,oBAAoB;CACzB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AAED,SAAS,oBAA6B;AACrC,QAAO,kBAAkB,MAAM,QAAQ;EACtC,MAAM,MAAM,QAAQ,IAAI;AACxB,SAAO,OAAO,QAAQ,YAAY,IAAI,MAAM,CAAC,SAAS;GACrD;;AAGH,SAAgB,sBAA+B;AAC9C,QAAO,aAAa,IAAI,sBAAsB,IAAI,mBAAmB;;;;ACvCtE,SAAS,2BAA+C;AACvD,QAAO;EACN;GACC,MAAM;GACN,aAAa;GACb,OAAO,EAAE,MAAM,gCAAgC;GAC/C;EACD;GACC,MAAM;GACN,aAAa;GACb,OAAO,EAAE,MAAM,iBAAiB;GAChC;EACD;GAAE,MAAM;GAAU,aAAa;GAAqD;EACpF;GAAE,MAAM;GAAW,aAAa;GAA6D;EAC7F;GAAE,MAAM;GAAQ,aAAa;GAA4B,OAAO,EAAE,MAAM,UAAU;GAAE;EACpF;GACC,MAAM;GACN,aAAa;GACb,OAAO,EAAE,MAAM,yCAAyC;GACxD;EACD;GACC,MAAM;GACN,aAAa;GACb,OAAO,EAAE,MAAM,yCAAyC;GACxD;EACD;GAAE,MAAM;GAAa,aAAa;GAAqB;EACvD;;AAGF,SAAS,cAAc,GAAuB,GAA2C;CACxF,MAAM,MAA0B,EAAE;CAClC,MAAM,uBAAO,IAAI,KAAa;AAC9B,MAAK,MAAM,KAAK,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE;AAC7B,MAAI,KAAK,IAAI,EAAE,KAAK,CAAE;AACtB,OAAK,IAAI,EAAE,KAAK;AAChB,MAAI,KAAK,EAAE;;AAEZ,QAAO;;AAGR,SAAS,UAAU,OAAyB;CAC3C,MAAM,OAAiB,EAAE;CACzB,IAAI,UAAU;CACd,IAAI,QAAuB;AAE3B,MAAK,MAAM,MAAM,MAChB,KAAI,UAAU,KACb,KAAI,OAAO,MAAO,SAAQ;KACrB,YAAW;UACN,OAAO,QAAO,OAAO,IAC/B,SAAQ;UACE,OAAO,OAAO,OAAO;MAC3B,YAAY,IAAI;AACnB,QAAK,KAAK,QAAQ;AAClB,aAAU;;OAGX,YAAW;AAIb,KAAI,YAAY,GAAI,MAAK,KAAK,QAAQ;AACtC,QAAO;;AAGR,MAAM,MAAM,uBAAuB,OAAO,KAAK,IAAI;AAEnD,IAAa,aAAb,MAA4C;CAC3C;CACA,WAA4B,IAAIE,kBAAgB;;CAEhD,+BAAgC,IAAI,KAAqB;CAEzD,UAAgB;AACf,OAAK,SAAS,YAAY;;CAG3B,YAAY,MAA2B,SAAmB;AACzD,OAAK,OAAO;;CAIb,MAAM,WAAW,QAAwD;EACxE,MAAM,mBAAmB;EACzB,MAAM,YAAY,OAAO;AAEzB,SAAO;GACN,iBAAiB,cAAc,mBAAmB,YAAY;GAC9D,WAAW;IACV,MAAM,IAAI;IACV,OAAO;IACP,SAAS,IAAI;IACb;GACD,aAAa,iBAAiB,EAC7B,0BAA0B,OAAO,oBAAoB,QAAQ,qBAAqB,MAClF,CAAC;GACF,mBAAmB;IAClB,aAAa;IACb,iBAAiB;KAAE,MAAM;KAAO,KAAK;KAAO;IAC5C,oBAAoB;KACnB,OAAO;KACP,OAAO;KACP,iBAAiB;KACjB;IACD,qBAAqB,EACpB,MAAM,EAAE,EACR;IACD;GACD;;CAGF,MAAM,WAAW,QAA2B;AAC3C,MAAI,CAAC,WAAW,OAAO,IAAI,CAC1B,OAAM,aAAa,cAAc,iCAAiC,OAAO,MAAM;AAGhF,MAAI,CAAC,qBAAqB,CACzB,OAAM,aAAa,aAClB,EAAE,aAAa,kBAAkB,EAAE,EACnC,yDACA;EAGF,IAAI;AACJ,MAAI;AACH,YAAS,MAAM,mBAAmB,EAAE,KAAK,OAAO,KAAK,CAAC;WAC9C,GAAY;GACpB,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,SAAM,aAAa,cAAc,EAAE,EAAE,gCAAgC,MAAM;;EAG5E,MAAM,YAAY,OAAO;AAGzB,MADwB,UAAU,cAAc,cAAc,CAC1C,WAAW,GAAG;AACjC,aAAU,SAAS;AACnB,SAAM,aAAa,aAClB,EAAE,aAAa,kBAAkB,EAAE,EACnC,yDACA;;EAGF,MAAM,YAAY,UAAU,eAAe,cAAc;EACzD,MAAM,cAAc,UAAU,eAAe,gBAAgB;AAC7D,MAAI,gBAAgB,KAAA,EACnB,MAAK,aAAa,IAAI,WAAW,YAAY;EAG9C,MAAM,UAAU,IAAI,aAAa;GAChC;GACA,KAAK,OAAO;GACZ,YAAY,OAAO;GACnB;GACA,MAAM,KAAK;GACX,CAAC;AAEF,OAAK,SAAS,SAAS,QAAQ;EAE/B,MAAM,eAAe,oBAAoB,OAAO,IAAI;EACpD,MAAM,eAAe,mBAAmB;EAExC,MAAM,cAAc,eACjB,iBAAiB,OAChB,GAAG,aAAa,MAChB,KACD,iBAAiB;GAAE,KAAK,OAAO;GAAK;GAAc,CAAC;AAEtD,MAAI,YAAa,SAAQ,eAAe,YAAY;AAEpD,OAAK,SAAS,eAAe,QAAQ,UAAU;EAE/C,MAAM,QAAQ,mBAAmB,UAAU;EAC3C,MAAM,SAAS,gBAAgB,UAAU;EACzC,MAAM,gBAAgB,mBAAmB,OAAO,OAAO;EAEvD,MAAM,WAAW;GAChB,WAAW,QAAQ;GACnB;GACA;GACA;GACA,OAAO,EACN,OAAO,EAAE,aAAa,eAAe,MAAM,EAC3C;GACD;AAED,MAAI,YAAa,kBAAiB,QAAQ,0BAA0B,EAAE,EAAE;EAExE,MAAM,sBAAsB,qBAAqB,OAAO,IAAI;AAC5D,mBAAiB;AAChB,IAAM,YAAY;AACjB,QAAI;KACH,MAAM,WAAW,iBAAiB,WAAW,oBAAoB;AACjE,WAAM,KAAK,KAAK,cAAc;MAC7B,WAAW,QAAQ;MACnB,QAAQ;OACP,eAAe;OACf,mBAAmB,cAAc,UAAU,0BAA0B,CAAC;OACtE;MACD,CAAC;YACK;OACL;KACF,EAAE;AAEL,SAAO;;CAGR,MAAM,aAAa,SAA8B;CAIjD,MAAM,OAAO,QAAgD;EAC5D,MAAM,UAAU,KAAK,SAAS,IAAI,OAAO,UAAU;EACnD,MAAM,EAAE,SAAS,WAAW,qBAAqB,OAAO,OAAO;AAE/D,MAAI,OAAO,WAAW,KAAK,QAAQ,WAAW,CAAC,WAAW,IAAI,EAAE;GAC/D,MAAM,UAAU,QAAQ,MAAM;GAC9B,MAAM,QAAQ,QAAQ,QAAQ,IAAI;GAClC,MAAM,MAAM,UAAU,KAAK,QAAQ,MAAM,EAAE,GAAG,QAAQ,MAAM,GAAG,MAAM;GAErE,MAAM,OAAO,UADM,UAAU,KAAK,KAAK,QAAQ,MAAM,QAAQ,EAAE,CAC7B;GAElC,MAAM,UAAU,MAAM,KAAK,qBAAqB,SAAS,KAAK,KAAK;AACnE,OAAI,QAAS,QAAO;;EAGrB,MAAM,SAAS,MAAM,QAAQ,OAAO,SAAS,OAAO;AAIpD,SAAO,EAAE,YAFsB,WAAW,UAAU,aAAa,QAE5C;;CAGtB,MAAM,OAAO,QAA2C;AAEvD,QADgB,KAAK,SAAS,IAAI,OAAO,UAAU,CACrC,QAAQ;;;;;;;CAQvB,MAAc,mBAAmB,WAA2C;EAC3E,MAAM,SAAS,KAAK,aAAa,IAAI,UAAU;AAC/C,MAAI,WAAW,KAAA,EAAW,QAAO;EAEjC,MAAM,MAAM,MAAMC,eAAiB,SAAS;AAC5C,OAAK,MAAM,KAAK,IACf,MAAK,aAAa,IAAI,EAAE,IAAI,EAAE,KAAK;AAGpC,SAAO,KAAK,aAAa,IAAI,UAAU,IAAI;;CAG5C,MAAM,aAAa,QAA4D;EAC9E,MAAM,MAAM,OAAO;EAEnB,MAAM,MACL,QAAQ,KAAA,KAAa,QAAQ,OAC1B,MAAMA,eAAiB,KAAK,IAAI,GAChC,MAAMA,eAAiB,SAAS;AAEpC,OAAK,MAAM,KAAK,IACf,MAAK,aAAa,IAAI,EAAE,IAAI,EAAE,KAAK;EAGpC,MAAM,WAAW,IAAI,KAAK,OAAO;GAChC,IAAI,EAAE;GACN,KAAK,EAAE;GACP,MAAM,EAAE,QAAQ;GAChB,UAAU,EAAE;GACZ,cAAc,EAAE;GAChB,EAAE;AAEH,MAAI,OAAO,WAAW,KAAA,KAAa,OAAO,WAAW,MAAM;GAC1D,MAAM,SAAS,OAAO,SAAS,OAAO,QAAQ,GAAG;AACjD,OAAI,CAAC,OAAO,SAAS,OAAO,IAAI,SAAS,EACxC,OAAM,aAAa,cAAc,mBAAmB,OAAO,SAAS;;EAItE,MAAM,QACL,OAAO,WAAW,KAAA,KAAa,OAAO,WAAW,OAC9C,OAAO,SAAS,OAAO,QAAQ,GAAG,GAClC;EAEJ,MAAM,YAAY;AAYlB,SAAO;GAAE,UAXI,SAAS,MAAM,OAAO,QAAQ,UAAU,CAEb,KAAK,OAAO;IACnD,WAAW,EAAE;IACb,KAAK,EAAE;IACP,OAAO,EAAE,QAAQ;IACjB,WAAW,EAAE,SAAS,aAAa;IACnC,EAAE;GAI6B,YAFb,QAAQ,YAAY,SAAS,SAAS,OAAO,QAAQ,UAAU,GAAG;GAEzC,OAAO,EAAE;GAAE;;CAGxD,MAAM,YAAY,QAA0D;AAC3E,MAAI,CAAC,WAAW,OAAO,IAAI,CAC1B,OAAM,aAAa,cAAc,iCAAiC,OAAO,MAAM;AAGhF,OAAK,SAAS,MAAM,OAAO,UAAU;EAErC,MAAM,cAAc,MAAM,KAAK,mBAAmB,OAAO,UAAU;AACnE,MAAI,gBAAgB,KACnB,OAAM,aAAa,cAAc,sBAAsB,OAAO,YAAY;EAG3E,IAAI;AACJ,MAAI;GACH,MAAM,KAAKA,eAAiB,KAAK,YAAY;AAC7C,YAAS,MAAM,mBAAmB;IACjC,KAAK,OAAO;IACZ,gBAAgB;IAChB,CAAC;WACM,GAAY;GACpB,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,SAAM,aAAa,cAAc,EAAE,EAAE,8BAA8B,MAAM;;EAG1E,MAAM,YAAY,OAAO;EAEzB,MAAM,UAAU,IAAI,aAAa;GAChC,WAAW,OAAO;GAClB,KAAK,OAAO;GACZ,YAAY,OAAO;GACnB;GACA,MAAM,KAAK;GACX,CAAC;AAEF,OAAK,SAAS,SAAS,QAAQ;AAC/B,OAAK,SAAS,eAAe,QAAQ,UAAU;EAE/C,MAAM,WAA2B,UAAU;AAC3C,OAAK,MAAM,KAAK,UAAU;AACzB,OAAI,EAAE,UAAU,GAAI;AAEpB,OAAI,EAAE,SAAS,QAAQ;IACtB,MAAM,OAAO,uBAAwB,EAAyB,QAAQ;AACtE,QAAI,KACH,OAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MAAE,eAAe;MAAsB,SAAS;OAAE,MAAM;OAAQ;OAAM;MAAE;KAChF,CAAC;;AAIJ,OAAI,EAAE,SAAS,aAAa;IAC3B,MAAM,OAAO,qBAAsB,EAA8B,QAAQ;AACzE,QAAI,KACH,OAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MAAE,eAAe;MAAuB,SAAS;OAAE,MAAM;OAAQ;OAAM;MAAE;KACjF,CAAC;;AAIJ,OAAI,EAAE,SAAS,cAAc;IAC5B,MAAM,KAAK;IACX,MAAM,WAAW,GAAG;IACpB,MAAM,aAAa,GAAG;IACtB,MAAM,UAAU,GAAG;AAEnB,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf;MACA,OAAO;MACP,MACC,aAAa,SACV,SACA,aAAa,WAAW,aAAa,SACpC,SACA;MACL,QAAQ;MACR,UAAU;MACV,WAAW;MACX;KACD,CAAC;IAEF,MAAM,OAAO,iBAAiB,EAAE;AAChC,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf;MACA,QAAQ,UAAU,WAAW;MAC7B,SAAS,OAAO,CAAC;OAAE,MAAM;OAAW,SAAS;QAAE,MAAM;QAAQ;QAAM;OAAE,CAAC,GAAG;MACzE,WAAW;MACX;KACD,CAAC;;;EAIJ,MAAM,QAAQ,mBAAmB,UAAU;EAC3C,MAAM,SAAS,gBAAgB,UAAU;EACzC,MAAM,gBAAgB,mBAAmB,OAAO,OAAO;EAEvD,MAAM,sBAAsB,qBAAqB,OAAO,IAAI;AAC5D,mBAAiB;AAChB,IAAM,YAAY;AACjB,QAAI;KACH,MAAM,WAAW,iBAAiB,WAAW,oBAAoB;AACjE,WAAM,KAAK,KAAK,cAAc;MAC7B,WAAW,QAAQ;MACnB,QAAQ;OACP,eAAe;OACf,mBAAmB,cAAc,UAAU,0BAA0B,CAAC;OACtE;MACD,CAAC;YACK;OACL;KACF,EAAE;AAEL,SAAO;GACN;GACA;GACA;GACA,OAAO,EAAE,OAAO,EAAE,aAAa,MAAM,EAAE;GACvC;;CAGF,MAAM,eAAe,QAAgE;EACpF,MAAM,UAAU,KAAK,SAAS,IAAI,OAAO,UAAU;EACnD,MAAM,OAAO,OAAO,OAAO,OAAO;AAClC,MAAI,CAAC,gBAAgB,KAAK,CACzB,OAAM,aAAa,cAAc,mBAAmB,OAAO;AAG5D,UAAQ,UAAU,iBAAiB,KAAK;AAEnC,OAAK,KAAK,cAAc;GAC5B,WAAW,QAAQ;GACnB,QAAQ;IAAE,eAAe;IAAuB,eAAe;IAAM;GACrE,CAAC;AAEF,OAAK,uBAAuB,QAAQ;AAEpC,SAAO,EAAE;;CAGV,MAAM,yBACL,QAC0C;EAC1C,MAAM,UAAU,KAAK,SAAS,IAAI,OAAO,UAAU;EAEnD,IAAI,WAA0B;EAC9B,IAAI,UAAyB;AAE7B,MAAI,OAAO,QAAQ,SAAS,IAAI,EAAE;GACjC,MAAM,CAAC,GAAG,GAAG,QAAQ,OAAO,QAAQ,MAAM,IAAI;AAC9C,cAAW,KAAK;AAChB,aAAU,KAAK,KAAK,IAAI;QAExB,WAAU,OAAO;AAGlB,MAAI,aAAa,MAAM;GAEtB,MAAM,QADY,QAAQ,UAAU,cAAc,cAAc,CACxC,MAAM,MAAM,EAAE,OAAO,QAAQ;AACrD,OAAI,OAAO;AACV,eAAW,MAAM;AACjB,cAAU,MAAM;;;AAIlB,MAAI,aAAa,QAAQ,YAAY,KACpC,OAAM,aAAa,cAAc,oBAAoB,OAAO,UAAU;EAIvE,MAAM,QADY,QAAQ,UAAU,cAAc,cAAc,CACxC,MAAM,MAAM,EAAE,aAAa,YAAY,EAAE,OAAO,QAAQ;AAChF,MAAI,CAAC,MACJ,OAAM,aAAa,cAAc,oBAAoB,OAAO,UAAU;AAGvE,QAAM,QAAQ,UAAU,SAAS,MAAM;AACvC,OAAK,uBAAuB,QAAQ;;CAGrC,MAAM,uBACL,QAC0C;EAC1C,MAAM,UAAU,KAAK,SAAS,IAAI,OAAO,UAAU;EACnD,MAAM,WAAW,OAAO,OAAO,SAAS;EACxC,MAAM,QAAQ,OAAO,OAAO,MAAM;AAElC,MAAI,aAAa,SAAS;GACzB,IAAI,WAA0B;GAC9B,IAAI,UAAyB;AAE7B,OAAI,MAAM,SAAS,IAAI,EAAE;IACxB,MAAM,CAAC,GAAG,GAAG,QAAQ,MAAM,MAAM,IAAI;AACrC,eAAW,KAAK;AAChB,cAAU,KAAK,KAAK,IAAI;SAExB,WAAU;AAGX,OAAI,aAAa,MAAM;IAEtB,MAAM,QADY,QAAQ,UAAU,cAAc,cAAc,CACxC,MAAM,MAAM,EAAE,OAAO,QAAQ;AACrD,QAAI,OAAO;AACV,gBAAW,MAAM;AACjB,eAAU,MAAM;;;AAIlB,OAAI,aAAa,QAAQ,YAAY,KACpC,OAAM,aAAa,cAAc,kBAAkB,QAAQ;GAI5D,MAAM,QADY,QAAQ,UAAU,cAAc,cAAc,CACxC,MAAM,MAAM,EAAE,aAAa,YAAY,EAAE,OAAO,QAAQ;AAChF,OAAI,CAAC,MACJ,OAAM,aAAa,cAAc,kBAAkB,QAAQ;AAG5D,SAAM,QAAQ,UAAU,SAAS,MAAM;aAC7B,aAAa,iBAAiB;AACxC,OAAI,CAAC,gBAAgB,MAAM,CAC1B,OAAM,aAAa,cAAc,2BAA2B,QAAQ;AAErE,WAAQ,UAAU,iBAAiB,MAAM;QAEzC,OAAM,aAAa,cAAc,0BAA0B,WAAW;AAKvE,SAAO,EAAE,eAAe,mBAFV,mBAAmB,QAAQ,UAAU,EACpC,gBAAgB,QAAQ,UAAU,CACQ,EAAE;;CAG5D,uBAA+B,SAA6B;EAG3D,MAAM,gBAAgB,mBAFR,mBAAmB,QAAQ,UAAU,EACpC,gBAAgB,QAAQ,UAAU,CACM;AAElD,OAAK,KAAK,cAAc;GAC5B,WAAW,QAAQ;GACnB,QAAQ;IACP,eAAe;IACf;IACA;GACD,CAAC;;CAGH,MAAc,qBACb,SACA,KACA,MACiC;EACjC,MAAM,YAAY,QAAQ;AAE1B,MAAI,QAAQ,WAAW;GACtB,MAAM,qBAAqB,KAAK,KAAK,IAAI,CAAC,MAAM,IAAI,KAAA;GACpD,MAAM,MAAM,MAAM,UAAU,QAAQ,mBAAmB;GAOvD,MAAM,OALc,CACnB,wBAAwB,uBAAuB,KAAA,KAAa,uBAAuB,KAAK,mCAAmC,MAC3H,OAAO,KAAK,iBAAiB,WAAW,kBAAkB,IAAI,iBAAiB,KAC/E,CAAC,OAAO,QAAQ,CAEQ,KAAK,KAAK,IAAI,KAAK,UAAU,OAAO,IAAI,YAAY;AAE7E,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KAAE,eAAe;KAAuB,SAAS;MAAE,MAAM;MAAQ;MAAM;KAAE;IACjF,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,WAAW;GACtB,MAAM,QAAQ,UAAU,iBAAiB;GACzC,MAAM,QAAkB,EAAE;AAC1B,OAAI,MAAM,cAAc,KAAA,KAAa,MAAM,cAAc,GACxD,OAAM,KAAK,YAAY,MAAM,YAAY;AAC1C,OAAI,MAAM,gBAAgB,KAAA,KAAa,MAAM,gBAAgB,GAC5D,OAAM,KAAK,iBAAiB,MAAM,cAAc;AACjD,SAAM,KAAK,aAAa,MAAM,gBAAgB;AAC9C,SAAM,KAAK,SAAS,MAAM,OAAO;GACjC,MAAM,IAAI,MAAM;GAChB,MAAM,QAAkB,EAAE;AAC1B,OAAI,EAAE,MAAO,OAAM,KAAK,MAAM,EAAE,QAAQ;AACxC,OAAI,EAAE,OAAQ,OAAM,KAAK,OAAO,EAAE,SAAS;AAC3C,OAAI,EAAE,UAAW,OAAM,KAAK,cAAc,EAAE,YAAY;AACxD,OAAI,EAAE,WAAY,OAAM,KAAK,eAAe,EAAE,aAAa;AAC3D,OAAI,EAAE,MAAO,OAAM,KAAK,SAAS,EAAE,QAAQ;AAC3C,OAAI,MAAM,SAAS,EAAG,OAAM,KAAK,WAAW,MAAM,KAAK,KAAK,GAAG;GAE/D,MAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KAAE,eAAe;KAAuB,SAAS;MAAE,MAAM;MAAQ;MAAM;KAAE;IACjF,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,QAAQ;GACnB,MAAM,OAAO,KAAK,KAAK,IAAI,CAAC,MAAM;AAClC,OAAI,CAAC,MAAM;AACV,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAAuB;MACtD;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAGlC,aAAU,eAAe,KAAK;AAE9B,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KACP,eAAe;KACf,OAAO;KACP,4BAAW,IAAI,MAAM,EAAC,aAAa;KACnC;IACD,CAAC;AACF,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KACP,eAAe;KACf,SAAS;MAAE,MAAM;MAAQ,MAAM,qBAAqB;MAAQ;KAC5D;IACD,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,YAAY;GACvB,MAAM,UAAU,OAAO,KAAK,MAAM,GAAG,CAAC,aAAa;AACnD,OAAI,CAAC,SAAS;AACb,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM,kBAAkB,UAAU;OAAgB;MAC3E;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAElC,OAAI,YAAY,SAAS,YAAY,iBAAiB;AACrD,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAAkD;MACjF;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAElC,aAAU,gBAAgB,QAAQ;AAClC,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KACP,eAAe;KACf,SAAS;MAAE,MAAM;MAAQ,MAAM,yBAAyB;MAAW;KACnE;IACD,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,aAAa;GACxB,MAAM,UAAU,OAAO,KAAK,MAAM,GAAG,CAAC,aAAa;AACnD,OAAI,CAAC,SAAS;AACb,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM,mBAAmB,UAAU;OAAgB;MAC5E;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAElC,OAAI,YAAY,SAAS,YAAY,iBAAiB;AACrD,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAAoD;MACnF;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAElC,aAAU,gBAAgB,QAAQ;AAClC,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KACP,eAAe;KACf,SAAS;MAAE,MAAM;MAAQ,MAAM,0BAA0B;MAAW;KACpE;IACD,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,eAAe;GAC1B,MAAM,QAAQ,KAAK,MAAM,UAAU,aAAa;GAChD,IAAI,UAA0B;AAC9B,OAAI,SAAS,QAAQ,SAAS,UAAU,SAAS,SAAU,WAAU;YAC5D,SAAS,SAAS,SAAS,WAAW,SAAS,UAAW,WAAU;AAE7E,OAAI,YAAY,KACf,WAAU,CAAC,UAAU;AAGtB,aAAU,yBAAyB,QAAQ;AAE3C,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KACP,eAAe;KACf,SAAS;MAAE,MAAM;MAAQ,MAAM,mBAAmB,UAAU,YAAY,WAAW;MAAI;KACvF;IACD,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,aAAa;GACxB,MAAM,gBAAgB,eAAe;AACrC,OAAI,kBAAkB,MAAM;AAC3B,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAAwB;MACvD;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;GAGlC,IAAI,OAAO;AACX,OAAI;AACH,WAAO,aAAa,eAAe,QAAQ;YACnC,GAAY;IACpB,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM,6BAA6B;OAAO;MACnE;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;GAGlC,MAAM,WAAW;AACjB,OAAI,KAAK,SAAS,SAAU,QAAO,GAAG,KAAK,MAAM,GAAG,SAAS,CAAC;AAE9D,SAAM,KAAK,KAAK,cAAc;IAC7B,WAAW,QAAQ;IACnB,QAAQ;KAAE,eAAe;KAAuB,SAAS;MAAE,MAAM;MAAQ;MAAM;KAAE;IACjF,CAAC;AACF,UAAO,EAAE,YAAY,YAAY;;AAGlC,MAAI,QAAQ,UAAU;AAErB,OADqB,UAAU,SAAS,WACnB,GAAG;AACvB,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAA+C;MAC9E;KACD,CAAC;AACF,WAAO,EAAE,YAAY,YAAY;;AAGlC,OAAI;IACH,MAAM,gBAAgB,QAAQ,UAAU,QAAQ,mBAAmB,IAAI;IACvE,MAAM,aAAa,KAAK,QAAQ,KAAK,cAAc,cAAc,OAAO;IACxE,MAAM,aAAa,MAAM,UAAU,aAAa,WAAW;AAE3D,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM;OAAsB;MACrD;KACD,CAAC;AACF,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OACR,MAAM;OACN,MAAM,cAAc,cAAc;OAClC,KAAK,UAAU;OACf,UAAU;OACV,OAAO;OACP;MACD;KACD,CAAC;YACM,GAAY;IACpB,MAAM,MAAM,aAAa,QAAQ,EAAE,UAAU,OAAO,EAAE;AACtD,UAAM,KAAK,KAAK,cAAc;KAC7B,WAAW,QAAQ;KACnB,QAAQ;MACP,eAAe;MACf,SAAS;OAAE,MAAM;OAAQ,MAAM,kBAAkB;OAAO;MACxD;KACD,CAAC;;AAEH,UAAO,EAAE,YAAY,YAAY;;AAGlC,SAAO;;;AAIT,SAAS,gBAAgB,GAA+B;AACvD,QACC,MAAM,SAAS,MAAM,aAAa,MAAM,SAAS,MAAM,YAAY,MAAM,UAAU,MAAM;;AAI3F,SAAS,mBAAmB,WAG1B;CACD,MAAM,SAAS,UAAU,4BAA4B;AACrD,QAAO;EACN,eAAe,UAAU;EACzB,gBAAgB,OAAO,KAAK,QAAQ;GACnC;GACA,MAAM,aAAa;GACnB,aAAa;GACb,EAAE;EACH;;AAGF,SAAS,gBAAgB,WAA4C;CACpE,MAAM,YAAY,UAAU,cAAc,cAAc;CACxD,MAAM,UAAU,UAAU;CAE1B,MAAM,kBAA+B,UAAU,KAAK,OAAO;EAC1D,SAAS,GAAG,EAAE,SAAS,GAAG,EAAE;EAC5B,MAAM,GAAG,EAAE,SAAS,GAAG,EAAE,QAAQ,EAAE;EACnC,aAAa;EACb,EAAE;CAEH,IAAI,iBAAiB;AACrB,KAAI,YAAY,KAAA,EACf,kBAAiB,GAAG,QAAQ,SAAS,GAAG,QAAQ;UACtC,gBAAgB,SAAS,KAAK,gBAAgB,OAAO,KAAA,EAC/D,kBAAiB,gBAAgB,GAAG;AAGrC,QAAO;EAAE;EAAiB;EAAgB;;AAG3C,SAAS,mBACR,OACA,QACwB;AACxB,QAAO,CACN;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,UAAU;EACV,MAAM;EACN,cAAc,OAAO;EACrB,SAAS,OAAO,gBAAgB,KAAK,OAAO;GAC3C,OAAO,EAAE;GACT,MAAM,EAAE;GACR,aAAa,EAAE,eAAe;GAC9B,EAAE;EACH,EACD;EACC,IAAI;EACJ,MAAM;EACN,aAAa;EACb,UAAU;EACV,MAAM;EACN,cAAc,MAAM;EACpB,SAAS,MAAM,eAAe,KAAK,OAAO;GACzC,OAAO,EAAE;GACT,MAAM,EAAE;GACR,aAAa,EAAE,eAAe;GAC9B,EAAE;EACH,CACD;;AAGF,SAAS,iBACR,WACA,qBACqB;CACrB,MAAM,WAA+B,EAAE;AAEvC,MAAK,MAAM,YAAY,UAAU,gBAChC,UAAS,KAAK;EACb,MAAM,SAAS;EACf,aAAa,SAAS,eAAe;EACrC,CAAC;AAGH,KAAI,qBAAqB;EACxB,MAAM,SAAS,UAAU,eAAe,WAAW;AACnD,OAAK,MAAM,SAAS,OAAO,OAC1B,UAAS,KAAK;GACb,MAAM,SAAS,MAAM;GACrB,aAAa,MAAM,eAAe;GAClC,CAAC;;CAIJ,MAAM,SAAS,UAAU;AACzB,KAAI,OACH,MAAK,MAAM,OAAO,OAAO,uBAAuB,CAC/C,UAAS,KAAK;EACb,MAAM,IAAI;EACV,aAAa,IAAI,eAAe;EAChC,CAAC;AAIJ,QAAO;;AAGR,SAAS,oBAAmC;AAC3C,KAAI;EACH,MAAM,YAAYC;AAClB,MAAI,CAAC,aAAa,CAAC,SAAS,UAAU,CAAE,QAAO;EAE/C,MAAM,YAAY,UAAU,OAAO;GAAC;GAAQ;GAAiC;GAAU,EAAE;GACxF,UAAU;GACV,SAAS;GACT,CAAC;EACF,MAAM,SAAS,OAAO,UAAU,UAAU,GAAG,CAC3C,MAAM,CACN,QAAQ,OAAO,GAAG;AACpB,MAAI,CAAC,UAAU,CAAC,SAAS,OAAO,CAAE,QAAO;AACzC,MAAI,cAAc,QAAQ,UAAU,IAAI,EAAG,QAAO;AAElD,SAAO,2BAA2B,OAAO,eAAe,UAAU;SAC3D;AACP,SAAO;;;AAIT,SAAS,iBAAiB,MAA4D;CACrF,MAAM,KAAe,EAAE;AAEvB,KAAIA,SAAY;AACf,KAAG,KAAK,OAAOA,UAAa;AAC5B,KAAG,KAAK,MAAM;AACd,KAAG,KAAK,GAAG;;CAGZ,MAAM,cAAc,OAAe,UAAoB;EACtD,MAAM,UAAU,MAAM,KAAK,MAAM,EAAE,MAAM,CAAC,CAAC,OAAO,QAAQ;AAC1D,MAAI,QAAQ,WAAW,EAAG;AAC1B,KAAG,KAAK,MAAM,QAAQ;AACtB,OAAK,MAAM,QAAQ,QAAS,IAAG,KAAK,KAAK,OAAO;AAChD,KAAG,KAAK,GAAG;;CAGZ,MAAM,eAAyB,EAAE;CACjC,MAAM,cAAc,KAAK,KAAK,KAAK,YAAY;AAC/C,KAAI,WAAW,YAAY,CAAE,cAAa,KAAK,YAAY;AAC3D,YAAW,WAAW,aAAa;AAEnC,KAAI,KAAK,iBAAiB,KAAA,KAAa,KAAK,iBAAiB,MAAM;AAClE,KAAG,KAAK,MAAM;AACd,KAAG,KAAK,KAAK,aAAa;AAC1B,KAAG,KAAK,GAAG;;AAGZ,QAAO,GAAG,GAAG,KAAK,KAAK,CAAC,MAAM,CAAC;;AAGhC,SAAS,gBAA+B;AACvC,KAAI;EAEH,MAAM,QAAQ,UADG,QAAQ,aAAa,UAAU,UAAU,SACxB,CAAC,KAAK,EAAE,EAAE,UAAU,SAAS,CAAC;EAChE,MAAM,SAAS,OAAO,MAAM,UAAU,GAAG,CACvC,MAAM,QAAQ,CAAC,IACd,MAAM;AACT,MAAI,WAAW,KAAA,KAAa,WAAW,IAAI;GAG1C,MAAM,IAAI,KADM,QAAQ,QADP,aAAa,OAAO,CACI,CAAC,EAClB,eAAe;AACvC,OAAI,WAAW,EAAE,CAAE,QAAO;;SAEpB;AAER,KAAI;EACH,MAAM,UAAU,UAAU,OAAO,CAAC,QAAQ,KAAK,EAAE,EAAE,UAAU,SAAS,CAAC;EACvE,MAAM,OAAO,OAAO,QAAQ,UAAU,GAAG,CAAC,MAAM;AAChD,MAAI,MAAM;GACT,MAAM,IAAI,KAAK,MAAM,iBAAiB,mBAAmB,eAAe;AACxE,OAAI,WAAW,EAAE,CAAE,QAAO;;SAEpB;AAER,QAAO;;AAGR,SAAS,SAAS,GAAoB;AACrC,QAAO,6BAA6B,KAAK,EAAE;;AAG5C,SAAS,cAAc,GAAW,GAAmB;CACpD,MAAM,KAAK,EACT,MAAM,OAAO,CACb,MAAM,GAAG,EAAE,CACX,KAAK,MAAM,OAAO,EAAE,CAAC;CACvB,MAAM,KAAK,EACT,MAAM,OAAO,CACb,MAAM,GAAG,EAAE,CACX,KAAK,MAAM,OAAO,EAAE,CAAC;AACvB,MAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;EAC3B,MAAM,KAAK,GAAG,MAAM;EACpB,MAAM,KAAK,GAAG,MAAM;AACpB,MAAI,KAAK,GAAI,QAAO;AACpB,MAAI,KAAK,GAAI,QAAO;;AAErB,QAAO;;AAGR,SAAS,uBAAuB,SAAoD;CACnF,MAAM,WAAW;EAAE,MAAM;EAAU,SAAS;EAAS;AACrD,KAAI;EACH,IAAI,MAAM,QAAQ,cAAc,QAAQ,CAAC;AACzC,OAAK,IAAI,IAAI,GAAG,IAAI,GAAG,KAAK;GAC3B,MAAM,IAAI,KAAK,KAAK,eAAe;AACnC,OAAI,WAAW,EAAE,EAAE;IAClB,MAAM,MAAe,KAAK,MAAM,aAAa,GAAG,QAAQ,CAAC;AACzD,QAAI,OAAO,QAAQ,YAAY,QAAQ,KAAM,QAAO;AAIpD,WAAO;KAAE,MAHI,UAAU,OAAO,OAAO,IAAI,SAAS,WAAW,IAAI,OAAO,SAAS;KAGlE,SADd,aAAa,OAAO,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU,SAAS;KACtD;;AAEzB,SAAM,QAAQ,IAAI;;SAEZ;AAGR,QAAO;;;;ACxkCR,IAAI,QAAQ,KAAK,SAAS,mBAAmB,EAAE;CAC9C,MAAM,EAAE,cAAc,MAAM,OAAO;CACnC,MAAM,YAAY,UAAU,KAAK;CACjC,MAAM,MAAM,QAAQ,IAAI,sBAAsB,YAAY,WAAW;CACrE,MAAM,MAAM,UAAU,KAAK,EAAE,EAAE;EAAE,OAAO;EAAW,KAAK,QAAQ;EAAK,CAAC;AAEtE,KAAI,IAAI,SAAS,UAAU,IAAI,SAAS,IAAI,MAAM,SAAS,UAAU;AACpE,UAAQ,OAAO,MACd,kDAAkD,IAAI;EAGtD;AACD,UAAQ,KAAK,EAAE;;AAGhB,SAAQ,KAAK,OAAO,IAAI,WAAW,WAAW,IAAI,SAAS,EAAE;;AA4B9D,MAAM,QAAQ,IAAI,qBAAqB,SAAS,IAAI,WAAW,KAAK,EADrD,aAxBD,IAAI,eAA2B,EAC5C,MAAM,OAAO;AACZ,QAAO,IAAI,SAAe,YAAY;AACrC,MAAI,QAAQ,OAAO,aAAa,CAAC,QAAQ,OAAO,UAAU;AACzD,YAAS;AACT;;AAED,MAAI;AACH,WAAQ,OAAO,MAAM,aAAa,SAAS,CAAC;UACrC;AACP,YAAS;;GAET;GAEH,CAAC,EAEa,IAAI,eAA2B,EAC7C,MAAM,YAAY;AACjB,SAAQ,MAAM,GAAG,SAAS,UAAkB,WAAW,QAAQ,IAAI,WAAW,MAAM,CAAC,CAAC;AACtF,SAAQ,MAAM,GAAG,aAAa,WAAW,OAAO,CAAC;AACjD,SAAQ,MAAM,GAAG,UAAU,QAAQ,WAAW,MAAM,IAAI,CAAC;GAE1D,CAAC,CAEwC,CACmC;AAE7E,SAAS,WAAW;AACnB,KAAI;AAGH,MAAI,WAAW,OAAO;GACrB,MAAM,QAAiB,MAAM;AAC7B,OACC,OAAO,UAAU,YACjB,UAAU,QACV,aAAa,SACb,OAAO,MAAM,YAAY,WAGzB,OAAM,SAAS;;SAGV;AAGR,SAAQ,KAAK,EAAE;;AAGhB,QAAQ,MAAM,GAAG,OAAO,SAAS;AACjC,QAAQ,MAAM,GAAG,SAAS,SAAS;AACnC,QAAQ,MAAM,QAAQ;AACtB,QAAQ,GAAG,UAAU,SAAS;AAC9B,QAAQ,GAAG,WAAW,SAAS;AAC/B,QAAQ,OAAO,GAAG,eAAe,QAAQ,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":["resolvePath","SessionManager","SessionManager","PiSessionManager","PI_VERSION"],"sources":["../src/acp/auth.ts","../src/acp/auth-required.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 * Detect common auth/credential errors from pi and surface them as ACP AUTH_REQUIRED.\n */\n\nimport { RequestError } from \"@agentclientprotocol/sdk\";\nimport { buildAuthMethods } from \"@pi-acp/acp/auth\";\n\nconst AUTH_ERROR_PATTERNS = [\n\t\"api key\",\n\t\"apikey\",\n\t\"missing key\",\n\t\"no key\",\n\t\"not configured\",\n\t\"unauthorized\",\n\t\"authentication\",\n\t\"permission denied\",\n\t\"forbidden\",\n\t\"401\",\n\t\"403\",\n];\n\nexport function detectAuthError(err: unknown): RequestError | null {\n\tconst text = err instanceof Error ? err.message : String(err ?? \"\");\n\tconst lower = text.toLowerCase();\n\n\tconst isAuthRelated = AUTH_ERROR_PATTERNS.some((p) => lower.includes(p));\n\tif (!isAuthRelated) return null;\n\n\treturn RequestError.authRequired(\n\t\t{ authMethods: buildAuthMethods() },\n\t\t\"Configure an API key or log in with an OAuth provider.\",\n\t);\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\nexport interface ToolArgs {\n\tpath?: string | undefined;\n\toldText?: string | undefined;\n\t[key: string]: unknown;\n}\n\nexport function 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\nexport function 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\nconst MAX_TITLE_LEN = 80;\n\nfunction truncateTitle(text: string): string {\n\tconst oneLine = text.replace(/\\n/g, \" \").trim();\n\tif (oneLine.length <= MAX_TITLE_LEN) return oneLine;\n\treturn `${oneLine.slice(0, MAX_TITLE_LEN - 1)}…`;\n}\n\n/**\n * Build a descriptive tool title from tool name and args.\n *\n * Returns a short human-readable label like \"Read src/index.ts\" or \"Run ls -la\".\n */\nexport function buildToolTitle(toolName: string, args: ToolArgs): string {\n\tconst p = args.path;\n\n\tswitch (toolName) {\n\t\tcase \"read\":\n\t\t\treturn p !== undefined ? `Read ${p}` : \"Read\";\n\t\tcase \"write\":\n\t\t\treturn p !== undefined ? `Write ${p}` : \"Write\";\n\t\tcase \"edit\":\n\t\t\treturn p !== undefined ? `Edit ${p}` : \"Edit\";\n\t\tcase \"bash\": {\n\t\t\tconst command =\n\t\t\t\ttypeof args[\"command\"] === \"string\"\n\t\t\t\t\t? args[\"command\"]\n\t\t\t\t\t: typeof args[\"cmd\"] === \"string\"\n\t\t\t\t\t\t? args[\"cmd\"]\n\t\t\t\t\t\t: undefined;\n\t\t\treturn command !== undefined ? truncateTitle(`Run ${command}`) : \"bash\";\n\t\t}\n\t\tdefault:\n\t\t\treturn toolName;\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\nexport function 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: buildToolTitle(toolCall.name, rawInput),\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\" || toolName === \"write\") && 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\tlet oldText = \"\";\n\t\t\t\ttry {\n\t\t\t\t\toldText = readFileSync(abs, \"utf8\");\n\t\t\t\t} catch {\n\t\t\t\t\t// File may not exist yet for write -- treat as empty.\n\t\t\t\t}\n\t\t\t\tthis.editSnapshots.set(toolCallId, { path: abs, oldText });\n\t\t\t\tif (toolName === \"edit\") {\n\t\t\t\t\tline = findUniqueLineNumber(oldText, args.oldText ?? \"\");\n\t\t\t\t}\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: buildToolTitle(toolName, args),\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\ttitle: buildToolTitle(toolName, args),\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\tthis.emitUsageUpdate();\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\t/**\n\t * Emit a usage_update notification with current context and cost data.\n\t */\n\tprivate emitUsageUpdate(): void {\n\t\tconst contextUsage = this.piSession.getContextUsage?.();\n\t\tconst stats = this.piSession.getSessionStats();\n\n\t\tconst used = contextUsage?.tokens ?? 0;\n\t\tconst size = contextUsage?.contextWindow ?? 0;\n\n\t\tthis.emit({\n\t\t\tsessionUpdate: \"usage_update\",\n\t\t\tused,\n\t\t\tsize,\n\t\t\tcost: stats.cost > 0 ? { amount: stats.cost, currency: \"USD\" } : null,\n\t\t});\n\t}\n\n\t/**\n\t * Build ACP Usage data from pi session stats for prompt response.\n\t */\n\tgetUsage(): {\n\t\tinputTokens: number;\n\t\toutputTokens: number;\n\t\tcachedReadTokens: number;\n\t\tcachedWriteTokens: number;\n\t} {\n\t\tconst stats = this.piSession.getSessionStats();\n\t\treturn {\n\t\t\tinputTokens: stats.tokens.input,\n\t\t\toutputTokens: stats.tokens.output,\n\t\t\tcachedReadTokens: stats.tokens.cacheRead,\n\t\t\tcachedWriteTokens: stats.tokens.cacheWrite,\n\t\t};\n\t}\n\n\t/**\n\t * Get cumulative session cost.\n\t */\n\tgetCost(): number {\n\t\treturn this.piSession.getSessionStats().cost;\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 CloseSessionRequest,\n\ttype CloseSessionResponse,\n\ttype ForkSessionRequest,\n\ttype ForkSessionResponse,\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 ResumeSessionRequest,\n\ttype ResumeSessionResponse,\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 { detectAuthError } from \"@pi-acp/acp/auth-required\";\nimport { quietStartupEnabled, skillCommandsEnabled } from \"@pi-acp/acp/pi-settings\";\nimport {\n\tbuildToolTitle,\n\tPiAcpSession,\n\tresolveToolPath,\n\tSessionManager,\n\ttype ToolArgs,\n\ttoToolArgs,\n\ttoToolKind,\n} from \"@pi-acp/acp/session\";\nimport { 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 SESSION_TITLE_MAX = 100;\n\nfunction truncateSessionTitle(text: string): string | null {\n\tconst trimmed = text.trim();\n\tif (trimmed === \"\") return null;\n\tconst oneLine = trimmed.replace(/\\n/g, \" \");\n\tif (oneLine.length <= SESSION_TITLE_MAX) return oneLine;\n\treturn `${oneLine.slice(0, SESSION_TITLE_MAX - 1)}…`;\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: true,\n\t\t\t\t},\n\t\t\t\tsessionCapabilities: {\n\t\t\t\t\tlist: {},\n\t\t\t\t\tclose: {},\n\t\t\t\t\tresume: {},\n\t\t\t\t\tfork: {},\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 authErr = detectAuthError(e);\n\t\t\tif (authErr !== null) throw authErr;\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\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\t\tconst usage = session.getUsage();\n\t\tconst cost = session.getCost();\n\n\t\treturn {\n\t\t\tstopReason,\n\t\t\tusage: {\n\t\t\t\tinputTokens: usage.inputTokens,\n\t\t\t\toutputTokens: usage.outputTokens,\n\t\t\t\tcachedReadTokens: usage.cachedReadTokens,\n\t\t\t\tcachedWriteTokens: usage.cachedWriteTokens,\n\t\t\t\ttotalTokens: usage.inputTokens + usage.outputTokens,\n\t\t\t},\n\t\t\t_meta: cost > 0 ? { cost: { amount: cost, currency: \"USD\" } } : {},\n\t\t};\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\t/**\n\t * Replay persisted session messages as ACP session updates.\n\t *\n\t * Iterates through the message history, emitting structured updates for each\n\t * content block type: text, thinking, tool calls, and tool results. A map of\n\t * tool call IDs to their invocation data (from assistant messages) is built\n\t * to enrich subsequent tool result updates with rawInput and locations.\n\t */\n\tprivate async replaySessionHistory(\n\t\tsession: PiAcpSession,\n\t\tmessages: AgentMessage[],\n\t): Promise<void> {\n\t\tconst toolCallMap = new Map<string, { name: string; args: ToolArgs }>();\n\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\tcontinue;\n\t\t\t}\n\n\t\t\tif (m.role === \"assistant\") {\n\t\t\t\tconst am = m satisfies AssistantMessage;\n\t\t\t\tfor (const block of am.content) {\n\t\t\t\t\tif (block.type === \"text\" && block.text) {\n\t\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\tsessionUpdate: \"agent_message_chunk\",\n\t\t\t\t\t\t\t\tcontent: { type: \"text\", text: block.text },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"thinking\" && block.thinking) {\n\t\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\tsessionUpdate: \"agent_thought_chunk\",\n\t\t\t\t\t\t\t\tcontent: { type: \"text\", text: block.thinking },\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t} else if (block.type === \"toolCall\") {\n\t\t\t\t\t\tconst args = toToolArgs(block.arguments);\n\t\t\t\t\t\ttoolCallMap.set(block.id, { name: block.name, args });\n\t\t\t\t\t\tconst locations = resolveToolPath(args, session.cwd);\n\n\t\t\t\t\t\tawait this.conn.sessionUpdate({\n\t\t\t\t\t\t\tsessionId: session.sessionId,\n\t\t\t\t\t\t\tupdate: {\n\t\t\t\t\t\t\t\tsessionUpdate: \"tool_call\",\n\t\t\t\t\t\t\t\ttoolCallId: block.id,\n\t\t\t\t\t\t\t\ttitle: buildToolTitle(block.name, args),\n\t\t\t\t\t\t\t\tkind: toToolKind(block.name),\n\t\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\t\trawInput: args,\n\t\t\t\t\t\t\t\t...(locations ? { locations } : {}),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcontinue;\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\t// Enrich from the preceding assistant tool call if available.\n\t\t\t\tconst invocation = toolCallMap.get(toolCallId);\n\t\t\t\tconst args = invocation?.args;\n\t\t\t\tconst locations = args !== undefined ? resolveToolPath(args, session.cwd) : undefined;\n\n\t\t\t\t// If no tool_call was emitted from the assistant message (e.g. older\n\t\t\t\t// session format without structured assistant content), emit one now.\n\t\t\t\tif (invocation === undefined) {\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: \"tool_call\",\n\t\t\t\t\t\t\ttoolCallId,\n\t\t\t\t\t\t\ttitle: buildToolTitle(toolName, {}),\n\t\t\t\t\t\t\tkind: toToolKind(toolName),\n\t\t\t\t\t\t\tstatus: \"completed\",\n\t\t\t\t\t\t\trawInput: null,\n\t\t\t\t\t\t\trawOutput: m,\n\t\t\t\t\t\t},\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\t...(locations ? { locations } : {}),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t}\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\tfirstMessage: s.firstMessage,\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:\n\t\t\t\t(s.name !== undefined && s.name !== \"\" ? s.name : null) ??\n\t\t\t\ttruncateSessionTitle(s.firstMessage) ??\n\t\t\t\tnull,\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 authErr = detectAuthError(e);\n\t\t\tif (authErr !== null) throw authErr;\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\n\t\tawait this.replaySessionHistory(session, piSession.messages);\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 unstable_closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse> {\n\t\tconst session = this.sessions.maybeGet(params.sessionId);\n\t\tif (session === undefined) {\n\t\t\tthrow RequestError.invalidParams(`Unknown sessionId: ${params.sessionId}`);\n\t\t}\n\t\tthis.sessions.close(params.sessionId);\n\t\treturn {};\n\t}\n\n\tasync unstable_resumeSession(params: ResumeSessionRequest): Promise<ResumeSessionResponse> {\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\t// If the session is already live, reuse it.\n\t\tconst existing = this.sessions.maybeGet(params.sessionId);\n\t\tif (existing !== undefined) {\n\t\t\tconst modes = buildThinkingModes(existing.piSession);\n\t\t\tconst models = buildModelState(existing.piSession);\n\t\t\treturn {\n\t\t\t\tconfigOptions: buildConfigOptions(modes, models),\n\t\t\t\tmodes,\n\t\t\t\tmodels,\n\t\t\t};\n\t\t}\n\n\t\t// Otherwise, load from disk (same path as loadSession but without replay).\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 authErr = detectAuthError(e);\n\t\t\tif (authErr !== null) throw authErr;\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to resume 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.sessionPaths.set(params.sessionId, sessionFile);\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\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\treturn {\n\t\t\tconfigOptions: buildConfigOptions(modes, models),\n\t\t\tmodes,\n\t\t\tmodels,\n\t\t};\n\t}\n\n\tasync unstable_forkSession(params: ForkSessionRequest): Promise<ForkSessionResponse> {\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\tconst sourceFile = await this.resolveSessionFile(params.sessionId);\n\t\tif (sourceFile === 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.forkFrom(sourceFile, params.cwd);\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 authErr = detectAuthError(e);\n\t\t\tif (authErr !== null) throw authErr;\n\t\t\tconst msg = e instanceof Error ? e.message : String(e);\n\t\t\tthrow RequestError.internalError({}, `Failed to fork pi session: ${msg}`);\n\t\t}\n\n\t\tconst piSession = result.session;\n\n\t\tconst newSessionId = piSession.sessionManager.getSessionId();\n\t\tconst newSessionFile = piSession.sessionManager.getSessionFile();\n\t\tif (newSessionFile !== undefined) {\n\t\t\tthis.sessionPaths.set(newSessionId, newSessionFile);\n\t\t}\n\n\t\tconst session = new PiAcpSession({\n\t\t\tsessionId: newSessionId,\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 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\tconst modes = buildThinkingModes(piSession);\n\t\tconst models = buildModelState(piSession);\n\t\treturn {\n\t\t\tsessionId: newSessionId,\n\t\t\tconfigOptions: buildConfigOptions(modes, models),\n\t\t\tmodes,\n\t\t\tmodels,\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\nlet cachedUpdateNotice: string | null | undefined;\n\nfunction buildUpdateNotice(): string | null {\n\tif (cachedUpdateNotice !== undefined) return cachedUpdateNotice;\n\ttry {\n\t\tconst installed = PI_VERSION;\n\t\tif (!installed || !isSemver(installed)) {\n\t\t\tcachedUpdateNotice = null;\n\t\t\treturn null;\n\t\t}\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)) {\n\t\t\tcachedUpdateNotice = null;\n\t\t\treturn null;\n\t\t}\n\t\tif (compareSemver(latest, installed) <= 0) {\n\t\t\tcachedUpdateNotice = null;\n\t\t\treturn null;\n\t\t}\n\n\t\tcachedUpdateNotice = `New version available: v${latest} (installed v${installed}). Run: \\`npm i -g @mariozechner/pi-coding-agent\\``;\n\t\treturn cachedUpdateNotice;\n\t} catch {\n\t\tcachedUpdateNotice = null;\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.2",
3
+ "version": "0.2.0",
4
4
  "description": "ACP adapter for pi coding agent",
5
5
  "license": "MIT",
6
6
  "author": "Victor Software House",