@oh-my-pi/pi-coding-agent 15.12.3 → 15.12.4

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.
Files changed (231) hide show
  1. package/CHANGELOG.md +43 -1
  2. package/dist/cli.js +1120 -870
  3. package/dist/types/autoresearch/tools/init-experiment.d.ts +1 -1
  4. package/dist/types/autoresearch/tools/log-experiment.d.ts +1 -1
  5. package/dist/types/autoresearch/tools/run-experiment.d.ts +1 -1
  6. package/dist/types/autoresearch/tools/update-notes.d.ts +1 -1
  7. package/dist/types/cli/args.d.ts +0 -1
  8. package/dist/types/cli/models-cli.d.ts +49 -0
  9. package/dist/types/commands/launch.d.ts +0 -3
  10. package/dist/types/commands/models.d.ts +33 -0
  11. package/dist/types/commands/token.d.ts +25 -0
  12. package/dist/types/commit/agentic/tools/analyze-file.d.ts +1 -1
  13. package/dist/types/commit/agentic/tools/git-file-diff.d.ts +1 -1
  14. package/dist/types/commit/agentic/tools/git-hunk.d.ts +1 -1
  15. package/dist/types/commit/agentic/tools/git-overview.d.ts +1 -1
  16. package/dist/types/commit/agentic/tools/propose-changelog.d.ts +1 -1
  17. package/dist/types/commit/agentic/tools/propose-commit.d.ts +1 -1
  18. package/dist/types/commit/agentic/tools/recent-commits.d.ts +1 -1
  19. package/dist/types/commit/agentic/tools/schemas.d.ts +1 -1
  20. package/dist/types/commit/agentic/tools/split-commit.d.ts +1 -1
  21. package/dist/types/commit/changelog/generate.d.ts +1 -1
  22. package/dist/types/commit/shared-llm.d.ts +1 -1
  23. package/dist/types/config/model-registry.d.ts +7 -0
  24. package/dist/types/config/models-config-schema.d.ts +1 -1
  25. package/dist/types/config/settings-schema.d.ts +20 -0
  26. package/dist/types/edit/hashline/params.d.ts +1 -1
  27. package/dist/types/edit/modes/apply-patch.d.ts +1 -1
  28. package/dist/types/edit/modes/patch.d.ts +1 -1
  29. package/dist/types/edit/modes/replace.d.ts +1 -1
  30. package/dist/types/extensibility/custom-commands/types.d.ts +2 -2
  31. package/dist/types/extensibility/custom-tools/types.d.ts +2 -2
  32. package/dist/types/extensibility/extensions/types.d.ts +2 -2
  33. package/dist/types/extensibility/hooks/types.d.ts +2 -2
  34. package/dist/types/goals/tools/goal-tool.d.ts +1 -1
  35. package/dist/types/lsp/types.d.ts +1 -1
  36. package/dist/types/mcp/manager.d.ts +8 -0
  37. package/dist/types/mnemopi/config.d.ts +28 -0
  38. package/dist/types/modes/acp/acp-agent.d.ts +1 -2
  39. package/dist/types/modes/components/index.d.ts +1 -0
  40. package/dist/types/modes/components/logout-account-selector.d.ts +8 -0
  41. package/dist/types/modes/components/status-line/component.d.ts +9 -5
  42. package/dist/types/modes/components/status-line/types.d.ts +2 -1
  43. package/dist/types/modes/controllers/event-controller.d.ts +0 -17
  44. package/dist/types/modes/interactive-mode.d.ts +0 -3
  45. package/dist/types/modes/types.d.ts +0 -5
  46. package/dist/types/session/agent-session.d.ts +14 -33
  47. package/dist/types/session/agent-storage.d.ts +2 -1
  48. package/dist/types/session/indexed-session-storage.d.ts +1 -0
  49. package/dist/types/session/messages.d.ts +8 -10
  50. package/dist/types/session/session-manager.d.ts +15 -0
  51. package/dist/types/session/session-storage.d.ts +5 -0
  52. package/dist/types/slash-commands/helpers/logout.d.ts +15 -0
  53. package/dist/types/task/types.d.ts +1 -1
  54. package/dist/types/tools/ask.d.ts +1 -1
  55. package/dist/types/tools/ast-edit.d.ts +1 -1
  56. package/dist/types/tools/ast-grep.d.ts +1 -1
  57. package/dist/types/tools/bash.d.ts +1 -1
  58. package/dist/types/tools/browser/cmux/cmux-tab.d.ts +202 -0
  59. package/dist/types/tools/browser/cmux/rpc.d.ts +70 -0
  60. package/dist/types/tools/browser/cmux/socket-client.d.ts +19 -0
  61. package/dist/types/tools/browser/registry.d.ts +16 -3
  62. package/dist/types/tools/browser/render.d.ts +2 -0
  63. package/dist/types/tools/browser/tab-protocol.d.ts +2 -0
  64. package/dist/types/tools/browser/tab-supervisor.d.ts +16 -4
  65. package/dist/types/tools/browser.d.ts +3 -1
  66. package/dist/types/tools/checkpoint.d.ts +1 -1
  67. package/dist/types/tools/debug.d.ts +1 -1
  68. package/dist/types/tools/eval.d.ts +1 -1
  69. package/dist/types/tools/find.d.ts +1 -1
  70. package/dist/types/tools/gh.d.ts +1 -1
  71. package/dist/types/tools/image-gen.d.ts +1 -1
  72. package/dist/types/tools/index.d.ts +3 -1
  73. package/dist/types/tools/inspect-image.d.ts +1 -1
  74. package/dist/types/tools/irc.d.ts +1 -1
  75. package/dist/types/tools/job.d.ts +1 -1
  76. package/dist/types/tools/memory-edit.d.ts +1 -1
  77. package/dist/types/tools/memory-recall.d.ts +1 -1
  78. package/dist/types/tools/memory-reflect.d.ts +1 -1
  79. package/dist/types/tools/memory-retain.d.ts +1 -1
  80. package/dist/types/tools/read.d.ts +1 -1
  81. package/dist/types/tools/render-mermaid.d.ts +1 -1
  82. package/dist/types/tools/resolve.d.ts +1 -1
  83. package/dist/types/tools/review.d.ts +1 -1
  84. package/dist/types/tools/search-tool-bm25.d.ts +1 -1
  85. package/dist/types/tools/search.d.ts +1 -1
  86. package/dist/types/tools/ssh.d.ts +1 -1
  87. package/dist/types/tools/todo.d.ts +1 -1
  88. package/dist/types/tools/tts.d.ts +1 -1
  89. package/dist/types/tools/write.d.ts +1 -1
  90. package/dist/types/utils/clipboard.d.ts +4 -3
  91. package/dist/types/utils/image-loading.d.ts +18 -1
  92. package/dist/types/utils/thinking-display.d.ts +17 -0
  93. package/dist/types/web/search/index.d.ts +1 -1
  94. package/package.json +14 -14
  95. package/src/autoresearch/storage.ts +2 -1
  96. package/src/autoresearch/tools/init-experiment.ts +1 -1
  97. package/src/autoresearch/tools/log-experiment.ts +1 -1
  98. package/src/autoresearch/tools/run-experiment.ts +1 -1
  99. package/src/autoresearch/tools/update-notes.ts +1 -1
  100. package/src/cli/args.ts +0 -8
  101. package/src/cli/auth-gateway-cli.ts +1 -1
  102. package/src/cli/bench-cli.ts +1 -1
  103. package/src/cli/dry-balance-cli.ts +1 -1
  104. package/src/cli/models-cli.ts +427 -0
  105. package/src/cli-commands.ts +2 -0
  106. package/src/collab/host.ts +9 -12
  107. package/src/commands/launch.ts +0 -3
  108. package/src/commands/models.ts +61 -0
  109. package/src/commands/token.ts +89 -0
  110. package/src/commit/agentic/tools/analyze-file.ts +1 -1
  111. package/src/commit/agentic/tools/git-file-diff.ts +1 -1
  112. package/src/commit/agentic/tools/git-hunk.ts +1 -1
  113. package/src/commit/agentic/tools/git-overview.ts +1 -1
  114. package/src/commit/agentic/tools/propose-changelog.ts +1 -1
  115. package/src/commit/agentic/tools/propose-commit.ts +1 -1
  116. package/src/commit/agentic/tools/recent-commits.ts +1 -1
  117. package/src/commit/agentic/tools/schemas.ts +1 -1
  118. package/src/commit/agentic/tools/split-commit.ts +1 -1
  119. package/src/commit/analysis/summary.ts +1 -1
  120. package/src/commit/changelog/generate.ts +1 -1
  121. package/src/commit/shared-llm.ts +1 -1
  122. package/src/config/model-registry.ts +15 -12
  123. package/src/config/model-resolver.ts +2 -2
  124. package/src/config/models-config-schema.ts +1 -1
  125. package/src/config/settings-schema.ts +18 -0
  126. package/src/edit/hashline/params.ts +1 -1
  127. package/src/edit/modes/apply-patch.ts +1 -1
  128. package/src/edit/modes/patch.ts +1 -1
  129. package/src/edit/modes/replace.ts +1 -1
  130. package/src/eval/agent-bridge.ts +1 -1
  131. package/src/eval/completion-bridge.ts +1 -1
  132. package/src/export/html/template.js +24 -2
  133. package/src/export/html/tool-views.generated.js +2 -2
  134. package/src/extensibility/custom-commands/loader.ts +1 -1
  135. package/src/extensibility/custom-commands/types.ts +2 -2
  136. package/src/extensibility/custom-tools/loader.ts +1 -1
  137. package/src/extensibility/custom-tools/types.ts +2 -2
  138. package/src/extensibility/extensions/loader.ts +2 -2
  139. package/src/extensibility/extensions/types.ts +2 -2
  140. package/src/extensibility/hooks/loader.ts +1 -1
  141. package/src/extensibility/hooks/types.ts +2 -2
  142. package/src/extensibility/skills.ts +18 -3
  143. package/src/goals/tools/goal-tool.ts +1 -1
  144. package/src/internal-urls/docs-index.generated.ts +5 -2
  145. package/src/lsp/types.ts +1 -1
  146. package/src/main.ts +0 -25
  147. package/src/mcp/config-writer.ts +7 -3
  148. package/src/mcp/manager.ts +11 -0
  149. package/src/memories/index.ts +3 -1
  150. package/src/memories/storage.ts +2 -1
  151. package/src/mnemopi/config.ts +95 -11
  152. package/src/modes/acp/acp-agent.ts +5 -48
  153. package/src/modes/acp/acp-event-mapper.ts +5 -1
  154. package/src/modes/components/agent-hub.ts +2 -1
  155. package/src/modes/components/assistant-message.ts +8 -7
  156. package/src/modes/components/index.ts +1 -0
  157. package/src/modes/components/logout-account-selector.ts +130 -0
  158. package/src/modes/components/mcp-add-wizard.ts +1 -1
  159. package/src/modes/components/model-selector.ts +2 -2
  160. package/src/modes/components/status-line/component.ts +54 -157
  161. package/src/modes/components/status-line/segments.ts +1 -1
  162. package/src/modes/components/status-line/types.ts +2 -1
  163. package/src/modes/controllers/command-controller.ts +0 -12
  164. package/src/modes/controllers/event-controller.ts +23 -62
  165. package/src/modes/controllers/input-controller.ts +53 -30
  166. package/src/modes/controllers/mcp-command-controller.ts +44 -3
  167. package/src/modes/controllers/selector-controller.ts +56 -10
  168. package/src/modes/controllers/streaming-reveal.ts +4 -3
  169. package/src/modes/interactive-mode.ts +2 -8
  170. package/src/modes/theme/theme.ts +1 -1
  171. package/src/modes/types.ts +0 -5
  172. package/src/modes/utils/ui-helpers.ts +2 -1
  173. package/src/prompts/system/empty-stop-retry.md +4 -6
  174. package/src/sdk.ts +15 -19
  175. package/src/session/agent-session.ts +125 -234
  176. package/src/session/agent-storage.ts +18 -9
  177. package/src/session/history-storage.ts +2 -1
  178. package/src/session/indexed-session-storage.ts +7 -0
  179. package/src/session/messages.ts +9 -11
  180. package/src/session/session-dump-format.ts +4 -2
  181. package/src/session/session-manager.ts +116 -0
  182. package/src/session/session-storage.ts +20 -0
  183. package/src/slash-commands/builtin-registry.ts +15 -1
  184. package/src/slash-commands/helpers/logout.ts +88 -0
  185. package/src/task/types.ts +1 -1
  186. package/src/tools/ask.ts +1 -1
  187. package/src/tools/ast-edit.ts +1 -1
  188. package/src/tools/ast-grep.ts +1 -1
  189. package/src/tools/bash.ts +1 -1
  190. package/src/tools/browser/cmux/cmux-tab.ts +1264 -0
  191. package/src/tools/browser/cmux/rpc.ts +156 -0
  192. package/src/tools/browser/cmux/socket-client.ts +309 -0
  193. package/src/tools/browser/registry.ts +37 -3
  194. package/src/tools/browser/render.ts +6 -1
  195. package/src/tools/browser/tab-protocol.ts +2 -0
  196. package/src/tools/browser/tab-supervisor.ts +189 -18
  197. package/src/tools/browser/tab-worker.ts +1 -1
  198. package/src/tools/browser.ts +16 -1
  199. package/src/tools/checkpoint.ts +1 -1
  200. package/src/tools/debug.ts +1 -1
  201. package/src/tools/eval.ts +11 -6
  202. package/src/tools/fetch.ts +13 -2
  203. package/src/tools/find.ts +1 -1
  204. package/src/tools/gh.ts +1 -1
  205. package/src/tools/github-cache.ts +2 -1
  206. package/src/tools/image-gen.ts +1 -1
  207. package/src/tools/index.ts +3 -1
  208. package/src/tools/inspect-image.ts +3 -1
  209. package/src/tools/irc.ts +1 -1
  210. package/src/tools/job.ts +1 -1
  211. package/src/tools/memory-edit.ts +1 -1
  212. package/src/tools/memory-recall.ts +1 -1
  213. package/src/tools/memory-reflect.ts +1 -1
  214. package/src/tools/memory-retain.ts +1 -1
  215. package/src/tools/read.ts +8 -2
  216. package/src/tools/render-mermaid.ts +1 -1
  217. package/src/tools/report-tool-issue.ts +3 -2
  218. package/src/tools/resolve.ts +1 -1
  219. package/src/tools/review.ts +1 -1
  220. package/src/tools/search-tool-bm25.ts +1 -1
  221. package/src/tools/search.ts +1 -1
  222. package/src/tools/ssh.ts +1 -1
  223. package/src/tools/todo.ts +1 -1
  224. package/src/tools/tts.ts +1 -1
  225. package/src/tools/write.ts +1 -1
  226. package/src/utils/clipboard.ts +35 -18
  227. package/src/utils/image-loading.ts +35 -4
  228. package/src/utils/thinking-display.ts +37 -0
  229. package/src/web/search/index.ts +1 -1
  230. package/dist/types/cli/list-models.d.ts +0 -30
  231. package/src/cli/list-models.ts +0 -194
@@ -357,16 +357,6 @@ export declare class AgentSession {
357
357
  /** Unconditionally clear the silent-abort flag. Idempotent: safe when the
358
358
  * flag was never set OR was already consumed by `#handleAgentEvent`. */
359
359
  clearPlanCompactAbortPending(): void;
360
- /** Register a compact display string for a custom message that the caller is
361
- * about to dispatch via `promptCustomMessage` / `sendCustomMessage`.
362
- * Returns a stable tag the caller MUST embed in
363
- * `CustomMessage.details.__pendingDisplayTag` so the agent-side
364
- * `message_start` handler can remove the matching display entry when the
365
- * queued message is consumed.
366
- *
367
- * Does NOT push to the agent's steering/followUp queue — that happens
368
- * separately inside `sendCustomMessage`. */
369
- enqueueCustomMessageDisplay(text: string, mode: "steer" | "followUp"): string;
370
360
  getAsyncJobSnapshot(options?: {
371
361
  recentLimit?: number;
372
362
  }): AsyncJobSnapshot | null;
@@ -421,6 +411,7 @@ export declare class AgentSession {
421
411
  get serviceTier(): ServiceTier | undefined;
422
412
  /** Whether agent is currently streaming a response */
423
413
  get isStreaming(): boolean;
414
+ get isAborting(): boolean;
424
415
  /** Wait until streaming and deferred recovery work are fully settled. */
425
416
  waitForIdle(): Promise<void>;
426
417
  drainAsyncJobDeliveriesForAcp(options?: {
@@ -595,7 +586,9 @@ export declare class AgentSession {
595
586
  * the ACP agent) use this to know whether to expect an `agent_end` event.
596
587
  */
597
588
  prompt(text: string, options?: PromptOptions): Promise<boolean>;
598
- promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice">): Promise<void>;
589
+ promptCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: Pick<PromptOptions, "streamingBehavior" | "toolChoice"> & {
590
+ queueChipText?: string;
591
+ }): Promise<void>;
599
592
  /**
600
593
  * Queue a steering message to interrupt the agent mid-run.
601
594
  */
@@ -616,6 +609,7 @@ export declare class AgentSession {
616
609
  sendCustomMessage<T = unknown>(message: Pick<CustomMessage<T>, "customType" | "content" | "display" | "details" | "attribution">, options?: {
617
610
  triggerTurn?: boolean;
618
611
  deliverAs?: "steer" | "followUp" | "nextTurn";
612
+ queueChipText?: string;
619
613
  }): Promise<void>;
620
614
  /**
621
615
  * Send a user message to the agent.
@@ -627,22 +621,13 @@ export declare class AgentSession {
627
621
  sendUserMessage(content: string | (TextContent | ImageContent)[], options?: {
628
622
  deliverAs?: "steer" | "followUp";
629
623
  }): Promise<void>;
630
- /**
631
- * Clear queued messages and return them (text plus any attached images).
632
- * Useful for restoring to editor when user aborts. The internal entry
633
- * arrays are handed out as-is — a `tag` (if any) is inert once the record
634
- * leaves the queue.
635
- */
624
+ /** Clear queued messages and return them (text plus any attached images). */
636
625
  clearQueue(): {
637
626
  steering: RestoredQueuedMessage[];
638
627
  followUp: RestoredQueuedMessage[];
639
628
  };
640
- /** Number of pending messages (includes steering, follow-up, and next-turn messages) */
629
+ /** Number of pending displayable messages (includes steering, follow-up, and next-turn messages) */
641
630
  get queuedMessageCount(): number;
642
- /** Get pending messages (read-only). Returns the public text-only view;
643
- * internal `{text, tag?}` records are mapped to `.text` so callers
644
- * (`updatePendingMessagesDisplay`, `restoreQueuedMessagesToEditor`) see
645
- * the unchanged historical shape. */
646
631
  getQueuedMessages(): {
647
632
  steering: readonly string[];
648
633
  followUp: readonly string[];
@@ -650,8 +635,6 @@ export declare class AgentSession {
650
635
  /**
651
636
  * Pop the last queued message (steering first, then follow-up).
652
637
  * Used by dequeue keybinding to restore messages to editor one at a time.
653
- * Returns the popped entry's text and images; the tag (if any) dies with
654
- * the record — no orphan state can outlive the queue entry.
655
638
  */
656
639
  popLastQueuedMessage(): RestoredQueuedMessage | undefined;
657
640
  get skillsSettings(): SkillsSettings | undefined;
@@ -673,13 +656,6 @@ export declare class AgentSession {
673
656
  goalReason?: "interrupted" | "internal";
674
657
  reason?: string;
675
658
  }): Promise<void>;
676
- /**
677
- * Abort active work, then immediately resume the agent so queued steer/follow-up
678
- * messages drain instead of waiting for another natural turn boundary.
679
- */
680
- interruptAndFlushQueuedMessages(options?: {
681
- reason?: string;
682
- }): Promise<void>;
683
659
  /**
684
660
  * Start a new session, optionally with initial messages and parent tracking.
685
661
  * Clears all messages and starts a new session.
@@ -701,7 +677,10 @@ export declare class AgentSession {
701
677
  fork(): Promise<boolean>;
702
678
  /**
703
679
  * Set model directly.
704
- * Validates API key and saves to the active session. Persists settings only when requested.
680
+ * Validates that a credential source is configured (synchronously, without
681
+ * refreshing OAuth or running command-backed key programs) and saves to the
682
+ * active session. Persists settings only when requested. The concrete key is
683
+ * resolved lazily per request, so switching never blocks the event loop.
705
684
  * @throws Error if no API key available for the model
706
685
  */
707
686
  setModel(model: Model, role?: string, options?: {
@@ -711,7 +690,9 @@ export declare class AgentSession {
711
690
  }): Promise<void>;
712
691
  /**
713
692
  * Set model temporarily (for this session only).
714
- * Validates API key, saves to session log but NOT to settings.
693
+ * Validates that a credential source is configured (synchronously, without
694
+ * refreshing OAuth or running command-backed key programs), saves to session
695
+ * log but NOT to settings.
715
696
  * @throws Error if no API key available for the model
716
697
  */
717
698
  setModelTemporary(model: Model, thinkingLevel?: ThinkingLevel, options?: {
@@ -10,7 +10,8 @@ export declare class AgentStorage {
10
10
  private constructor();
11
11
  /**
12
12
  * Returns singleton instance for the given database path, creating if needed.
13
- * Retries on SQLITE_BUSY with exponential backoff.
13
+ * Retries on the `SQLITE_BUSY` family (including `SQLITE_BUSY_RECOVERY`) with
14
+ * exponential backoff. See issue #2421.
14
15
  * @param dbPath - Path to the SQLite database file (defaults to config path)
15
16
  * @returns AgentStorage instance for the given path
16
17
  */
@@ -53,6 +53,7 @@ declare class IndexedSessionStorageWriter implements SessionStorageWriter {
53
53
  writeLine(line: string): Promise<void>;
54
54
  flush(): Promise<void>;
55
55
  fsync(): Promise<void>;
56
+ fsyncSync(): void;
56
57
  close(): Promise<void>;
57
58
  getError(): Error | undefined;
58
59
  }
@@ -16,13 +16,11 @@ export interface SkillPromptDetails {
16
16
  path: string;
17
17
  args?: string;
18
18
  lineCount: number;
19
- /** Internal: tag used by AgentSession to remove the pending-display chip
20
- * from `#steeringMessages` / `#followUpMessages` when the agent consumes
21
- * this message. Not surfaced to renderers; the `__` prefix signals
22
- * "private". Optional — non-streaming skill prompts never set it. Stripped
23
- * from persisted `details` by `SessionManager.appendCustomMessageEntry`
24
- * via the `INTERNAL_DETAILS_FIELDS` allowlist below. */
25
- __pendingDisplayTag?: string;
19
+ /** Internal: compact label shown for a queued custom message. Optional —
20
+ * non-streaming skill prompts never set it. Stripped from persisted
21
+ * `details` by `SessionManager.appendCustomMessageEntry` via the
22
+ * `INTERNAL_DETAILS_FIELDS` allowlist below. */
23
+ __queueChipText?: string;
26
24
  }
27
25
  /** Sentinel value for `AssistantMessage.errorMessage` indicating that the abort
28
26
  * was an *expected internal transition* (plan-mode → execution compaction)
@@ -55,16 +53,16 @@ export declare function shouldRenderAbortReason(errorMessage: string | undefined
55
53
  * `shouldRenderAbortReason` before rendering when user interrupts should stay
56
54
  * visually quiet. */
57
55
  export declare function resolveAbortLabel(errorMessage: string | undefined, retryAttempt?: number): string;
58
- /** Extract the optional `__pendingDisplayTag` field from a CustomMessage's
56
+ /** Extract the optional `__queueChipText` field from a CustomMessage's
59
57
  * `details` blob. Safe over `unknown`; returns undefined when the field is
60
58
  * absent or non-string. */
61
- export declare function readPendingDisplayTag(details: unknown): string | undefined;
59
+ export declare function readQueueChipText(details: unknown): string | undefined;
62
60
  /** Explicit allowlist of `details` field names that are AgentSession-internal
63
61
  * transient bookkeeping and MUST be removed before SessionManager persists
64
62
  * the CustomMessageEntry to disk. Scoped intentionally narrow: only fields
65
63
  * declared here are stripped. Adding a new entry is a deliberate, reviewed
66
64
  * change — unrelated future payload fields are never silently dropped. */
67
- export declare const INTERNAL_DETAILS_FIELDS: readonly ["__pendingDisplayTag"];
65
+ export declare const INTERNAL_DETAILS_FIELDS: readonly ["__queueChipText"];
68
66
  /** Return a `details` copy with every key in `INTERNAL_DETAILS_FIELDS`
69
67
  * removed. Returns the input unchanged when there is nothing to strip
70
68
  * (null/non-object, or no listed fields present) so callers don't pay a
@@ -353,6 +353,21 @@ export declare class SessionManager {
353
353
  ensureOnDisk(): Promise<void>;
354
354
  /** Flush pending writes to disk. Call before switching sessions or on shutdown. */
355
355
  flush(): Promise<void>;
356
+ /**
357
+ * Synchronously flush all in-memory entries to disk and fsync.
358
+ * Use when the process may exit before an async flush settles (e.g. Ctrl+C
359
+ * in the TUI, where raw mode consumes the keystroke so postmortem's SIGINT
360
+ * handler never fires).
361
+ *
362
+ * Hot path: the persist writer is open and flushed, so a single fsyncSync
363
+ * pushes the page-cache data to physical disk.
364
+ *
365
+ * Cold path: entries are only in memory (session just started, or a rewrite
366
+ * is pending). Writes all entries to a temp file, fsyncs, and atomically
367
+ * renames over the session file — then re-opens an append writer so the
368
+ * hot path resumes on subsequent `_persist` calls.
369
+ */
370
+ flushSync(): void;
356
371
  /** Close the persistent writer after flushing all pending data. */
357
372
  close(): Promise<void>;
358
373
  getCwd(): string;
@@ -15,6 +15,11 @@ export interface SessionStorageWriter {
15
15
  writeLineSync(line: string): void;
16
16
  flush(): Promise<void>;
17
17
  fsync(): Promise<void>;
18
+ /**
19
+ * Synchronously fsync the underlying file descriptor. Returns once the data
20
+ * is on the physical disk. Throws synchronously on I/O error.
21
+ */
22
+ fsyncSync(): void;
18
23
  close(): Promise<void>;
19
24
  getError(): Error | undefined;
20
25
  }
@@ -0,0 +1,15 @@
1
+ import type { OAuthAccountIdentity, StoredAuthCredential } from "../../session/auth-storage";
2
+ export interface LogoutAccount {
3
+ credentialId: number;
4
+ provider: string;
5
+ label: string;
6
+ detail: string;
7
+ type: "api_key" | "oauth";
8
+ active: boolean;
9
+ }
10
+ interface LogoutAccountOptions {
11
+ activeIdentity?: OAuthAccountIdentity;
12
+ activeApiKey?: boolean;
13
+ }
14
+ export declare function toLogoutAccounts(provider: string, credentials: StoredAuthCredential[], options?: LogoutAccountOptions): LogoutAccount[];
15
+ export {};
@@ -1,6 +1,6 @@
1
1
  import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
2
  import type { Usage } from "@oh-my-pi/pi-ai";
3
- import * as z from "zod/v4";
3
+ import { z } from "zod/v4";
4
4
  import type { AgentSessionEvent } from "../session/agent-session";
5
5
  import type { NestedRepoPatch } from "./worktree";
6
6
  /** Source of an agent definition */
@@ -16,7 +16,7 @@
16
16
  */
17
17
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
18
18
  import { type Component } from "@oh-my-pi/pi-tui";
19
- import * as z from "zod/v4";
19
+ import { z } from "zod/v4";
20
20
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
21
21
  import { type Theme } from "../modes/theme/theme";
22
22
  import type { ToolSession } from ".";
@@ -1,6 +1,6 @@
1
1
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
2
2
  import type { Component } from "@oh-my-pi/pi-tui";
3
- import * as z from "zod/v4";
3
+ import { z } from "zod/v4";
4
4
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
5
5
  import type { Theme } from "../modes/theme/theme";
6
6
  import type { ToolSession } from ".";
@@ -1,6 +1,6 @@
1
1
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback } from "@oh-my-pi/pi-agent-core";
2
2
  import type { Component } from "@oh-my-pi/pi-tui";
3
- import * as z from "zod/v4";
3
+ import { z } from "zod/v4";
4
4
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
5
5
  import type { Theme } from "../modes/theme/theme";
6
6
  import type { ToolSession } from ".";
@@ -1,6 +1,6 @@
1
1
  import type { AgentTool, AgentToolContext, AgentToolResult, AgentToolUpdateCallback, ToolApprovalDecision } from "@oh-my-pi/pi-agent-core";
2
2
  import type { Component } from "@oh-my-pi/pi-tui";
3
- import * as z from "zod/v4";
3
+ import { z } from "zod/v4";
4
4
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
5
5
  import { type Theme } from "../modes/theme/theme";
6
6
  import type { ToolSession } from ".";
@@ -0,0 +1,202 @@
1
+ import { JsRuntime } from "../../../eval/js/shared/runtime";
2
+ import type { ToolSession } from "../../../sdk";
3
+ import { type ReadableFormat } from "../readable";
4
+ import type { Observation, ReadyInfo, RunResultOk, ScreenshotResult, SessionSnapshot } from "../tab-protocol";
5
+ import type { CmuxSocketClient } from "./socket-client";
6
+ interface ScreenshotOptions {
7
+ selector?: string;
8
+ fullPage?: boolean;
9
+ save?: string;
10
+ silent?: boolean;
11
+ encoding?: "base64" | "binary";
12
+ }
13
+ interface ObserveOptions {
14
+ includeAll?: boolean;
15
+ viewportOnly?: boolean;
16
+ }
17
+ interface RunContext {
18
+ session: SessionSnapshot;
19
+ displays: RunResultOk["displays"];
20
+ screenshots: ScreenshotResult[];
21
+ signal?: AbortSignal;
22
+ timeoutMs: number;
23
+ }
24
+ type WaitUntil = "load" | "domcontentloaded" | "networkidle0" | "networkidle2";
25
+ type DragTarget = string | {
26
+ readonly x: number;
27
+ readonly y: number;
28
+ };
29
+ interface BoundingBox {
30
+ x: number;
31
+ y: number;
32
+ width: number;
33
+ height: number;
34
+ }
35
+ interface CmuxResponseRecord {
36
+ id: number;
37
+ url: string;
38
+ status: number;
39
+ statusText: string;
40
+ headers: Record<string, string>;
41
+ body: string;
42
+ }
43
+ interface ViewportOptions {
44
+ width: number;
45
+ height: number;
46
+ deviceScaleFactor?: number;
47
+ }
48
+ export interface RunCmuxCodeOptions {
49
+ code: string;
50
+ timeoutMs: number;
51
+ signal?: AbortSignal;
52
+ session: ToolSession;
53
+ snapshot: SessionSnapshot;
54
+ }
55
+ export declare class CmuxTab {
56
+ #private;
57
+ constructor(opts: {
58
+ client: CmuxSocketClient;
59
+ surfaceId: string;
60
+ url?: string;
61
+ title?: string;
62
+ });
63
+ get surfaceId(): string;
64
+ get page(): CmuxPageFacade;
65
+ get browser(): CmuxBrowserFacade;
66
+ viewport(): ReadyInfo["viewport"];
67
+ setViewport(viewport: ViewportOptions): Promise<void>;
68
+ url(): string;
69
+ title(): Promise<string>;
70
+ readyInfo(viewport?: ReadyInfo["viewport"]): Promise<ReadyInfo>;
71
+ setRunContext(context: RunContext): void;
72
+ clearRunContext(): void;
73
+ goto(url: string, opts?: {
74
+ waitUntil?: WaitUntil;
75
+ timeoutMs?: number;
76
+ }): Promise<void>;
77
+ observe(opts?: ObserveOptions): Promise<Observation>;
78
+ click(selector: string): Promise<void>;
79
+ dblclick(selector: string): Promise<void>;
80
+ hover(selector: string): Promise<void>;
81
+ focus(selector: string): Promise<void>;
82
+ check(selector: string): Promise<void>;
83
+ uncheck(selector: string): Promise<void>;
84
+ type(selector: string, text: string): Promise<void>;
85
+ fill(selector: string, value: string): Promise<void>;
86
+ press(key: string, opts?: {
87
+ selector?: string;
88
+ }): Promise<void>;
89
+ scroll(dx: number, dy: number): Promise<void>;
90
+ waitFor(selector: string, opts?: {
91
+ timeout?: number;
92
+ }): Promise<CmuxElementHandle>;
93
+ evaluate<TResult, TArgs extends unknown[]>(fn: string | ((...args: TArgs) => TResult | Promise<TResult>), ...args: TArgs): Promise<TResult>;
94
+ scrollIntoView(selector: string): Promise<void>;
95
+ select(selector: string, ...values: string[]): Promise<string[]>;
96
+ extract(format?: ReadableFormat): Promise<string>;
97
+ screenshot(opts?: ScreenshotOptions): Promise<ScreenshotResult>;
98
+ waitForUrl(pattern: string | RegExp, opts?: {
99
+ timeout?: number;
100
+ }): Promise<string>;
101
+ drag(from: DragTarget, to: DragTarget): Promise<void>;
102
+ uploadFile(selector: string, ...filePaths: string[]): Promise<void>;
103
+ waitForResponse(pattern: string | RegExp | ((response: CmuxResponse) => boolean | Promise<boolean>), opts?: {
104
+ timeout?: number;
105
+ }): Promise<CmuxResponse>;
106
+ id(id: number): Promise<CmuxElementHandle>;
107
+ ensureRuntime(session: SessionSnapshot): JsRuntime;
108
+ elementHandle(selector: string): CmuxElementHandle;
109
+ elementExists(selector: string): Promise<boolean>;
110
+ elementBox(selector: string): Promise<BoundingBox | null>;
111
+ evaluateOnSelector<TResult>(selector: string, source: string, args: unknown[]): Promise<TResult>;
112
+ pageContent(): Promise<string>;
113
+ pageScreenshot(opts?: ScreenshotOptions): Promise<Buffer | string>;
114
+ waitForFunction(fn: string | ((...args: unknown[]) => unknown | Promise<unknown>), opts: {
115
+ timeout?: number;
116
+ polling?: number;
117
+ } | undefined, ...args: unknown[]): Promise<unknown>;
118
+ }
119
+ declare class CmuxResponse {
120
+ #private;
121
+ constructor(record: CmuxResponseRecord);
122
+ url(): string;
123
+ status(): number;
124
+ statusText(): string;
125
+ headers(): Record<string, string>;
126
+ text(): Promise<string>;
127
+ json(): Promise<unknown>;
128
+ }
129
+ declare class CmuxElementHandle {
130
+ #private;
131
+ constructor(tab: CmuxTab, selector: string);
132
+ click(): Promise<void>;
133
+ type(text: string): Promise<void>;
134
+ fill(value: string): Promise<void>;
135
+ focus(): Promise<void>;
136
+ hover(): Promise<void>;
137
+ evaluate<TResult, TArgs extends unknown[]>(fn: (element: unknown, ...args: TArgs) => TResult | Promise<TResult>, ...args: TArgs): Promise<TResult>;
138
+ boundingBox(): Promise<BoundingBox | null>;
139
+ uploadFile(...paths: string[]): Promise<void>;
140
+ dispose(): Promise<void>;
141
+ }
142
+ declare class CmuxLocator {
143
+ #private;
144
+ constructor(tab: CmuxTab, selector: string);
145
+ setTimeout(timeoutMs: number): this;
146
+ click(): Promise<void>;
147
+ fill(value: string): Promise<void>;
148
+ waitHandle(): Promise<CmuxElementHandle>;
149
+ }
150
+ declare class CmuxPageFacade {
151
+ #private;
152
+ readonly keyboard: {
153
+ press: (key: string) => Promise<void>;
154
+ };
155
+ readonly mouse: {
156
+ wheel: (delta: {
157
+ deltaX?: number;
158
+ deltaY?: number;
159
+ }) => Promise<void>;
160
+ move: (x: number, y: number) => Promise<void>;
161
+ down: () => Promise<void>;
162
+ up: () => Promise<void>;
163
+ };
164
+ constructor(tab: CmuxTab);
165
+ url(): string;
166
+ title(): Promise<string>;
167
+ viewport(): ReadyInfo["viewport"];
168
+ setViewport(viewport: ViewportOptions): Promise<void>;
169
+ goto(url: string, opts?: {
170
+ waitUntil?: WaitUntil;
171
+ timeout?: number;
172
+ }): Promise<{
173
+ url: string;
174
+ }>;
175
+ evaluate<TResult, TArgs extends unknown[]>(fn: string | ((...args: TArgs) => TResult | Promise<TResult>), ...args: TArgs): Promise<TResult>;
176
+ content(): Promise<string>;
177
+ locator(selector: string): CmuxLocator;
178
+ $(selector: string): Promise<CmuxElementHandle | null>;
179
+ waitForSelector(selector: string, opts?: {
180
+ timeout?: number;
181
+ }): Promise<CmuxElementHandle>;
182
+ waitForFunction(fn: string | ((...args: unknown[]) => unknown | Promise<unknown>), opts?: {
183
+ timeout?: number;
184
+ polling?: number;
185
+ }, ...args: unknown[]): Promise<unknown>;
186
+ waitForResponse(pattern: string | RegExp | ((response: CmuxResponse) => boolean | Promise<boolean>), opts?: {
187
+ timeout?: number;
188
+ }): Promise<CmuxResponse>;
189
+ screenshot(opts?: ScreenshotOptions): Promise<Buffer | string>;
190
+ }
191
+ declare class CmuxBrowserFacade {
192
+ #private;
193
+ connected: boolean;
194
+ constructor(tab: CmuxTab);
195
+ pages(): Promise<CmuxPageFacade[]>;
196
+ version(): Promise<string>;
197
+ wsEndpoint(): string;
198
+ disconnect(): void;
199
+ close(): Promise<void>;
200
+ }
201
+ export declare function runCmuxCode(tab: CmuxTab, opts: RunCmuxCodeOptions): Promise<RunResultOk>;
202
+ export {};
@@ -0,0 +1,70 @@
1
+ import type { Observation } from "../tab-protocol";
2
+ export interface CmuxKind {
3
+ kind: "cmux";
4
+ socketPath: string;
5
+ password?: string;
6
+ surface?: string;
7
+ }
8
+ export interface CmuxOpenSplitResult {
9
+ surface_id?: unknown;
10
+ url?: unknown;
11
+ workspace_id?: unknown;
12
+ created_split?: unknown;
13
+ placement_strategy?: unknown;
14
+ }
15
+ export interface CmuxSnapshotRef {
16
+ role?: unknown;
17
+ name?: unknown;
18
+ }
19
+ export interface CmuxSnapshotPage {
20
+ title?: unknown;
21
+ url?: unknown;
22
+ ready_state?: unknown;
23
+ text?: unknown;
24
+ html?: unknown;
25
+ }
26
+ export interface CmuxSnapshotResult {
27
+ snapshot?: unknown;
28
+ refs?: Record<string, CmuxSnapshotRef>;
29
+ page?: CmuxSnapshotPage;
30
+ url?: unknown;
31
+ title?: unknown;
32
+ ready_state?: unknown;
33
+ surface_id?: unknown;
34
+ }
35
+ export interface CmuxEvalResult {
36
+ value?: unknown;
37
+ surface_id?: unknown;
38
+ content_world?: unknown;
39
+ }
40
+ export interface CmuxUrlGetResult {
41
+ url?: unknown;
42
+ surface_id?: unknown;
43
+ workspace_id?: unknown;
44
+ }
45
+ export interface CmuxScreenshotResult {
46
+ png_base64?: unknown;
47
+ path?: unknown;
48
+ url?: unknown;
49
+ surface_id?: unknown;
50
+ width?: unknown;
51
+ height?: unknown;
52
+ }
53
+ export interface CmuxGeometry {
54
+ innerWidth: number;
55
+ innerHeight: number;
56
+ dpr: number;
57
+ scrollX: number;
58
+ scrollY: number;
59
+ scrollWidth: number;
60
+ scrollHeight: number;
61
+ }
62
+ export declare const GEOMETRY_SCRIPT = "(() => ({ innerWidth: window.innerWidth, innerHeight: window.innerHeight, dpr: window.devicePixelRatio||1, scrollX: window.scrollX, scrollY: window.scrollY, scrollWidth: document.documentElement.scrollWidth, scrollHeight: document.documentElement.scrollHeight }))()";
63
+ export declare function cmuxSnapshotToObservation(result: CmuxSnapshotResult, viewport: Observation["viewport"], geometry: CmuxGeometry): Observation;
64
+ export declare function serializeEval(fn: string | ((...args: unknown[]) => unknown), args: unknown[]): string;
65
+ export declare function mapWaitUntil(waitUntil: string | undefined): "interactive" | "complete";
66
+ export interface ResolveCmuxKindOptions {
67
+ surface?: string;
68
+ settingEnabled?: boolean;
69
+ }
70
+ export declare function resolveCmuxKind(options?: ResolveCmuxKindOptions | null, env?: Record<string, string | undefined>): CmuxKind | null;
@@ -0,0 +1,19 @@
1
+ type CmuxErrorPayload = {
2
+ code?: unknown;
3
+ message?: unknown;
4
+ details?: unknown;
5
+ };
6
+ export declare function formatCmuxError(error: CmuxErrorPayload | undefined): string;
7
+ export declare class CmuxSocketClient {
8
+ #private;
9
+ constructor(opts: {
10
+ socketPath: string;
11
+ password?: string;
12
+ });
13
+ connect(): Promise<void>;
14
+ request(method: string, params: Record<string, unknown>, opts?: {
15
+ timeoutMs?: number;
16
+ }): Promise<Record<string, unknown>>;
17
+ close(): void;
18
+ }
19
+ export {};
@@ -1,7 +1,9 @@
1
1
  import type { Subprocess } from "bun";
2
2
  import type { Browser, CDPSession } from "puppeteer-core";
3
+ import type { CmuxKind } from "./cmux/rpc";
4
+ import { CmuxSocketClient } from "./cmux/socket-client";
3
5
  import { type UserAgentOverride } from "./launch";
4
- export type BrowserKind = {
6
+ export type PuppeteerBrowserKind = {
5
7
  kind: "headless";
6
8
  headless: boolean;
7
9
  } | {
@@ -11,20 +13,30 @@ export type BrowserKind = {
11
13
  kind: "connected";
12
14
  cdpUrl: string;
13
15
  };
16
+ export type BrowserKind = PuppeteerBrowserKind | CmuxKind;
14
17
  export type BrowserKindTag = BrowserKind["kind"];
15
- export interface BrowserHandle {
18
+ interface BrowserHandleCommon {
16
19
  key: string;
17
20
  kind: BrowserKind;
21
+ refCount: number;
22
+ }
23
+ export interface PuppeteerBrowserHandle extends BrowserHandleCommon {
24
+ kind: PuppeteerBrowserKind;
18
25
  browser: Browser;
19
26
  cdpUrl?: string;
20
27
  pid?: number;
21
28
  subprocess?: Subprocess;
22
- refCount: number;
23
29
  stealth: {
24
30
  browserSession: CDPSession | null;
25
31
  override: UserAgentOverride | null;
26
32
  };
27
33
  }
34
+ export interface CmuxBrowserHandle extends BrowserHandleCommon {
35
+ kind: CmuxKind;
36
+ client: CmuxSocketClient;
37
+ surface?: string;
38
+ }
39
+ export type BrowserHandle = PuppeteerBrowserHandle | CmuxBrowserHandle;
28
40
  export interface AcquireBrowserOptions {
29
41
  cwd: string;
30
42
  viewport?: {
@@ -41,3 +53,4 @@ export declare function holdBrowser(handle: BrowserHandle): void;
41
53
  export declare function releaseBrowser(handle: BrowserHandle, opts: {
42
54
  kill: boolean;
43
55
  }): Promise<void>;
56
+ export {};
@@ -20,6 +20,8 @@ interface BrowserRenderArgs {
20
20
  path?: string;
21
21
  cdp_url?: string;
22
22
  target?: string;
23
+ cmux?: boolean;
24
+ surface?: string;
23
25
  };
24
26
  viewport?: {
25
27
  width: number;
@@ -37,6 +37,8 @@ export interface ScreenshotResult {
37
37
  export interface SessionSnapshot {
38
38
  cwd: string;
39
39
  browserScreenshotDir?: string;
40
+ /** Force non-WebP screenshot encoding (e.g. for Ollama). Unset honors `OMP_NO_WEBP`. */
41
+ excludeWebP?: boolean;
40
42
  }
41
43
  export type WorkerInitPayload = {
42
44
  mode: "headless";