@oh-my-pi/pi-coding-agent 15.10.0 → 15.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/CHANGELOG.md +142 -1
  2. package/dist/types/cli/dry-balance-cli.d.ts +15 -1
  3. package/dist/types/cli/startup-cwd.d.ts +2 -0
  4. package/dist/types/commands/launch.d.ts +3 -0
  5. package/dist/types/commit/analysis/conventional.d.ts +2 -2
  6. package/dist/types/commit/analysis/summary.d.ts +2 -2
  7. package/dist/types/commit/changelog/generate.d.ts +2 -2
  8. package/dist/types/commit/changelog/index.d.ts +2 -2
  9. package/dist/types/commit/map-reduce/index.d.ts +3 -3
  10. package/dist/types/commit/map-reduce/map-phase.d.ts +2 -2
  11. package/dist/types/commit/map-reduce/reduce-phase.d.ts +2 -2
  12. package/dist/types/commit/model-selection.d.ts +10 -4
  13. package/dist/types/config/api-key-resolver.d.ts +34 -0
  14. package/dist/types/config/keybindings.d.ts +2 -2
  15. package/dist/types/config/model-provider-priority.d.ts +1 -0
  16. package/dist/types/config/model-registry.d.ts +17 -1
  17. package/dist/types/config/model-resolver.d.ts +4 -1
  18. package/dist/types/config/settings-schema.d.ts +9 -0
  19. package/dist/types/config/settings.d.ts +7 -2
  20. package/dist/types/dap/config.d.ts +14 -1
  21. package/dist/types/dap/types.d.ts +10 -0
  22. package/dist/types/debug/report-bundle.d.ts +3 -0
  23. package/dist/types/edit/file-snapshot-store.d.ts +18 -10
  24. package/dist/types/eval/py/__tests__/prelude.test.d.ts +1 -0
  25. package/dist/types/extensibility/extensions/types.d.ts +4 -1
  26. package/dist/types/lsp/client.d.ts +10 -0
  27. package/dist/types/lsp/utils.d.ts +3 -2
  28. package/dist/types/main.d.ts +3 -9
  29. package/dist/types/mcp/tool-bridge.d.ts +2 -0
  30. package/dist/types/modes/components/chat-block.d.ts +64 -0
  31. package/dist/types/modes/components/custom-editor.d.ts +4 -1
  32. package/dist/types/modes/components/overlay-box.d.ts +17 -0
  33. package/dist/types/modes/components/plan-review-overlay.d.ts +59 -0
  34. package/dist/types/modes/components/plan-toc.d.ts +41 -0
  35. package/dist/types/modes/components/read-tool-group.d.ts +2 -0
  36. package/dist/types/modes/components/status-line.d.ts +2 -0
  37. package/dist/types/modes/components/transcript-container.d.ts +11 -0
  38. package/dist/types/modes/controllers/command-controller.d.ts +1 -0
  39. package/dist/types/modes/controllers/event-controller.d.ts +17 -1
  40. package/dist/types/modes/controllers/extension-ui-controller.d.ts +0 -1
  41. package/dist/types/modes/controllers/input-controller.d.ts +1 -1
  42. package/dist/types/modes/controllers/streaming-reveal.d.ts +22 -0
  43. package/dist/types/modes/controllers/tan-command-controller.d.ts +6 -0
  44. package/dist/types/modes/interactive-mode.d.ts +16 -5
  45. package/dist/types/modes/magic-keywords.d.ts +1 -1
  46. package/dist/types/modes/markdown-prose.d.ts +1 -1
  47. package/dist/types/modes/theme/theme.d.ts +1 -1
  48. package/dist/types/modes/types.d.ts +21 -5
  49. package/dist/types/modes/utils/copy-targets.d.ts +21 -1
  50. package/dist/types/modes/workflow.d.ts +3 -3
  51. package/dist/types/plan-mode/approved-plan.d.ts +27 -8
  52. package/dist/types/plan-mode/plan-protection.d.ts +4 -4
  53. package/dist/types/sdk.d.ts +2 -0
  54. package/dist/types/session/agent-session.d.ts +21 -0
  55. package/dist/types/session/auth-storage.d.ts +1 -1
  56. package/dist/types/session/messages.d.ts +12 -0
  57. package/dist/types/session/session-manager.d.ts +8 -3
  58. package/dist/types/slash-commands/types.d.ts +4 -6
  59. package/dist/types/task/executor.d.ts +17 -0
  60. package/dist/types/task/index.d.ts +1 -0
  61. package/dist/types/task/render.d.ts +3 -2
  62. package/dist/types/tools/archive-reader.d.ts +5 -0
  63. package/dist/types/tools/ast-edit.d.ts +3 -0
  64. package/dist/types/tools/ast-grep.d.ts +3 -0
  65. package/dist/types/tools/bash.d.ts +1 -0
  66. package/dist/types/tools/eval.d.ts +8 -0
  67. package/dist/types/tools/find.d.ts +8 -4
  68. package/dist/types/tools/gh-cache-invalidation.d.ts +6 -0
  69. package/dist/types/tools/github-cache.d.ts +12 -0
  70. package/dist/types/tools/grouped-file-output.d.ts +95 -12
  71. package/dist/types/tools/memory-render.d.ts +4 -1
  72. package/dist/types/tools/path-utils.d.ts +8 -0
  73. package/dist/types/tools/plan-mode-guard.d.ts +8 -9
  74. package/dist/types/tools/render-utils.d.ts +5 -9
  75. package/dist/types/tools/search.d.ts +6 -2
  76. package/dist/types/tools/sqlite-reader.d.ts +1 -0
  77. package/dist/types/tools/todo.d.ts +3 -2
  78. package/dist/types/tools/write.d.ts +3 -0
  79. package/dist/types/tools/yield.d.ts +8 -0
  80. package/dist/types/tui/output-block.d.ts +16 -4
  81. package/dist/types/tui/status-line.d.ts +3 -0
  82. package/dist/types/utils/enhanced-paste.d.ts +20 -0
  83. package/dist/types/web/search/providers/kimi.d.ts +1 -1
  84. package/package.json +9 -9
  85. package/src/auto-thinking/classifier.ts +5 -1
  86. package/src/cli/args.ts +3 -1
  87. package/src/cli/dry-balance-cli.ts +54 -21
  88. package/src/cli/gallery-cli.ts +4 -1
  89. package/src/cli/gallery-fixtures/misc.ts +29 -0
  90. package/src/cli/startup-cwd.ts +68 -0
  91. package/src/commands/launch.ts +3 -0
  92. package/src/commit/analysis/conventional.ts +2 -2
  93. package/src/commit/analysis/summary.ts +2 -2
  94. package/src/commit/changelog/generate.ts +2 -2
  95. package/src/commit/changelog/index.ts +2 -2
  96. package/src/commit/map-reduce/index.ts +3 -3
  97. package/src/commit/map-reduce/map-phase.ts +2 -2
  98. package/src/commit/map-reduce/reduce-phase.ts +2 -2
  99. package/src/commit/model-selection.ts +36 -11
  100. package/src/commit/pipeline.ts +4 -4
  101. package/src/config/api-key-resolver.ts +58 -0
  102. package/src/config/model-provider-priority.ts +55 -0
  103. package/src/config/model-registry.ts +29 -24
  104. package/src/config/model-resolver.ts +39 -7
  105. package/src/config/settings-schema.ts +10 -0
  106. package/src/config/settings.ts +106 -43
  107. package/src/dap/config.ts +41 -2
  108. package/src/dap/defaults.json +1 -0
  109. package/src/dap/session.ts +1 -0
  110. package/src/dap/types.ts +10 -0
  111. package/src/debug/index.ts +47 -53
  112. package/src/debug/raw-sse-buffer.ts +7 -4
  113. package/src/debug/report-bundle.ts +9 -0
  114. package/src/edit/file-snapshot-store.ts +33 -1
  115. package/src/edit/hashline/filesystem.ts +2 -1
  116. package/src/edit/renderer.ts +82 -78
  117. package/src/eval/__tests__/llm-bridge.test.ts +110 -31
  118. package/src/eval/js/context-manager.ts +32 -15
  119. package/src/eval/llm-bridge.ts +22 -6
  120. package/src/eval/py/__tests__/prelude.test.ts +19 -0
  121. package/src/eval/py/executor.ts +23 -11
  122. package/src/eval/py/prelude.py +1 -1
  123. package/src/extensibility/extensions/types.ts +10 -1
  124. package/src/goals/tools/goal-tool.ts +36 -26
  125. package/src/internal-urls/docs-index.generated.ts +8 -8
  126. package/src/lsp/client.ts +23 -11
  127. package/src/lsp/config.ts +11 -1
  128. package/src/lsp/index.ts +61 -9
  129. package/src/lsp/utils.ts +3 -2
  130. package/src/main.ts +100 -72
  131. package/src/mcp/tool-bridge.ts +2 -0
  132. package/src/memories/index.ts +14 -7
  133. package/src/mnemopi/backend.ts +5 -1
  134. package/src/modes/acp/acp-agent.ts +33 -26
  135. package/src/modes/components/assistant-message.ts +2 -9
  136. package/src/modes/components/chat-block.ts +111 -0
  137. package/src/modes/components/copy-selector.ts +1 -44
  138. package/src/modes/components/custom-editor.ts +164 -109
  139. package/src/modes/components/custom-message.ts +1 -3
  140. package/src/modes/components/execution-shared.ts +1 -2
  141. package/src/modes/components/hook-message.ts +1 -3
  142. package/src/modes/components/model-selector.ts +59 -13
  143. package/src/modes/components/oauth-selector.ts +33 -7
  144. package/src/modes/components/overlay-box.ts +108 -0
  145. package/src/modes/components/plan-review-overlay.ts +799 -0
  146. package/src/modes/components/plan-toc.ts +138 -0
  147. package/src/modes/components/read-tool-group.ts +20 -4
  148. package/src/modes/components/skill-message.ts +0 -1
  149. package/src/modes/components/status-line.ts +19 -4
  150. package/src/modes/components/tips.txt +2 -1
  151. package/src/modes/components/todo-reminder.ts +0 -2
  152. package/src/modes/components/tool-execution.ts +68 -88
  153. package/src/modes/components/transcript-container.ts +84 -24
  154. package/src/modes/components/user-message.ts +2 -3
  155. package/src/modes/controllers/command-controller-shared.ts +7 -6
  156. package/src/modes/controllers/command-controller.ts +57 -55
  157. package/src/modes/controllers/event-controller.ts +67 -40
  158. package/src/modes/controllers/extension-ui-controller.ts +10 -73
  159. package/src/modes/controllers/input-controller.ts +170 -126
  160. package/src/modes/controllers/mcp-command-controller.ts +69 -60
  161. package/src/modes/controllers/selector-controller.ts +23 -25
  162. package/src/modes/controllers/streaming-reveal.ts +212 -0
  163. package/src/modes/controllers/tan-command-controller.ts +173 -0
  164. package/src/modes/interactive-mode.ts +274 -112
  165. package/src/modes/magic-keywords.ts +1 -1
  166. package/src/modes/markdown-prose.ts +1 -1
  167. package/src/modes/setup-wizard/wizard-overlay.ts +1 -1
  168. package/src/modes/theme/shimmer.ts +20 -9
  169. package/src/modes/theme/theme-schema.json +1 -1
  170. package/src/modes/theme/theme.ts +8 -4
  171. package/src/modes/types.ts +21 -7
  172. package/src/modes/utils/copy-targets.ts +133 -27
  173. package/src/modes/utils/ui-helpers.ts +44 -46
  174. package/src/modes/workflow.ts +10 -10
  175. package/src/plan-mode/approved-plan.ts +66 -43
  176. package/src/plan-mode/plan-protection.ts +4 -4
  177. package/src/prompts/system/background-tan-dispatch.md +8 -0
  178. package/src/prompts/system/plan-mode-active.md +67 -58
  179. package/src/prompts/system/plan-mode-approved.md +1 -1
  180. package/src/prompts/system/workflow-notice.md +1 -1
  181. package/src/prompts/tools/bash.md +9 -0
  182. package/src/prompts/tools/browser.md +1 -1
  183. package/src/prompts/tools/eval.md +2 -1
  184. package/src/prompts/tools/read.md +2 -2
  185. package/src/sdk.ts +37 -46
  186. package/src/session/agent-session.ts +119 -18
  187. package/src/session/auth-storage.ts +2 -0
  188. package/src/session/messages.ts +26 -0
  189. package/src/session/session-manager.ts +109 -28
  190. package/src/slash-commands/builtin-registry.ts +36 -9
  191. package/src/slash-commands/types.ts +4 -6
  192. package/src/task/executor.ts +76 -38
  193. package/src/task/index.ts +4 -0
  194. package/src/task/render.ts +211 -147
  195. package/src/tools/archive-reader.ts +64 -0
  196. package/src/tools/ask.ts +119 -164
  197. package/src/tools/ast-edit.ts +98 -71
  198. package/src/tools/ast-grep.ts +37 -43
  199. package/src/tools/bash.ts +57 -6
  200. package/src/tools/browser/tab-supervisor.ts +13 -1
  201. package/src/tools/browser/tab-worker.ts +33 -4
  202. package/src/tools/debug.ts +20 -8
  203. package/src/tools/eval.ts +13 -2
  204. package/src/tools/fetch.ts +297 -7
  205. package/src/tools/find.ts +51 -30
  206. package/src/tools/gh-cache-invalidation.ts +200 -0
  207. package/src/tools/gh-renderer.ts +81 -42
  208. package/src/tools/github-cache.ts +25 -0
  209. package/src/tools/grouped-file-output.ts +272 -48
  210. package/src/tools/image-gen.ts +150 -103
  211. package/src/tools/inspect-image-renderer.ts +63 -41
  212. package/src/tools/inspect-image.ts +10 -3
  213. package/src/tools/job.ts +3 -4
  214. package/src/tools/memory-render.ts +4 -1
  215. package/src/tools/path-utils.ts +28 -2
  216. package/src/tools/plan-mode-guard.ts +66 -39
  217. package/src/tools/read.ts +48 -28
  218. package/src/tools/render-utils.ts +21 -37
  219. package/src/tools/resolve.ts +14 -0
  220. package/src/tools/search-tool-bm25.ts +36 -23
  221. package/src/tools/search.ts +118 -81
  222. package/src/tools/sqlite-reader.ts +9 -12
  223. package/src/tools/todo.ts +118 -52
  224. package/src/tools/write.ts +83 -64
  225. package/src/tools/yield.ts +10 -1
  226. package/src/tui/output-block.ts +60 -13
  227. package/src/tui/status-line.ts +5 -1
  228. package/src/utils/commit-message-generator.ts +11 -3
  229. package/src/utils/enhanced-paste.ts +230 -0
  230. package/src/utils/title-generator.ts +2 -1
  231. package/src/web/search/providers/anthropic.ts +25 -19
  232. package/src/web/search/providers/codex.ts +37 -8
  233. package/src/web/search/providers/exa.ts +11 -3
  234. package/src/web/search/providers/kimi.ts +28 -17
  235. package/src/web/search/providers/parallel.ts +35 -24
  236. package/src/web/search/providers/synthetic.ts +8 -6
  237. package/src/web/search/providers/tavily.ts +9 -8
  238. package/src/web/search/providers/zai.ts +8 -6
@@ -8,7 +8,7 @@ import type { ExtensionUIContext, ExtensionUIDialogOptions, ExtensionUISelectIte
8
8
  import type { CompactOptions } from "../extensibility/extensions/types";
9
9
  import type { MCPManager } from "../mcp";
10
10
  import type { PlanApprovalDetails } from "../plan-mode/approved-plan";
11
- import type { AgentSession, AgentSessionEvent } from "../session/agent-session";
11
+ import type { AgentSession } from "../session/agent-session";
12
12
  import type { HistoryStorage } from "../session/history-storage";
13
13
  import type { SessionContext, SessionManager } from "../session/session-manager";
14
14
  import type { ShakeMode } from "../session/shake-types";
@@ -51,6 +51,7 @@ export type TodoPhase = {
51
51
  };
52
52
  export interface InteractiveModeInitOptions {
53
53
  suppressWelcomeIntro?: boolean;
54
+ clearInitialTerminalHistory?: boolean;
54
55
  }
55
56
  export type InteractiveSelectorDialogOptions = ExtensionUIDialogOptions & Pick<HookSelectorOptions, "disabledIndices">;
56
57
  export interface InteractiveModeContext {
@@ -76,7 +77,6 @@ export interface InteractiveModeContext {
76
77
  mcpManager?: MCPManager;
77
78
  lspServers?: LspStartupServerInfo[];
78
79
  isInitialized: boolean;
79
- isBackgrounded: boolean;
80
80
  isBashMode: boolean;
81
81
  toolOutputExpanded: boolean;
82
82
  todoExpanded: boolean;
@@ -126,9 +126,21 @@ export interface InteractiveModeContext {
126
126
  checkShutdownRequested(): Promise<void>;
127
127
  setToolUIContext(uiContext: ExtensionUIContext, hasUI: boolean): void;
128
128
  initializeHookRunner(uiContext: ExtensionUIContext, hasUI: boolean): void;
129
- createBackgroundUiContext(): ExtensionUIContext;
130
129
  setEditorComponent(factory: ((tui: TUI, theme: EditorTheme, keybindings: KeybindingsManager) => CustomEditor) | undefined): void;
131
- handleBackgroundEvent(event: AgentSessionEvent): Promise<void>;
130
+ /**
131
+ * Mount transcript content and repaint once. The single sink for "show this in
132
+ * chat": producers build and return a `Component` (or a `ChatBlock` carrying
133
+ * its own lifecycle) and hand it here instead of touching `chatContainer` /
134
+ * `ui.requestRender()` directly. `ChatBlock`s are mounted (their `onMount`
135
+ * runs) so their timers/subscriptions start.
136
+ */
137
+ present(content: Component | readonly Component[]): void;
138
+ /**
139
+ * Dispose every live block in the transcript (stopping timers/subscriptions)
140
+ * and clear it. Used before a full rebuild so animated/streaming blocks do not
141
+ * leak.
142
+ */
143
+ resetTranscript(): void;
132
144
  showStatus(message: string, options?: {
133
145
  dim?: boolean;
134
146
  }): void;
@@ -147,6 +159,9 @@ export interface InteractiveModeContext {
147
159
  flushPendingModelSwitch(): Promise<void>;
148
160
  setWorkingMessage(message?: string): void;
149
161
  applyPendingWorkingMessage(): void;
162
+ /** Acknowledge a user interrupt (Esc) by switching the loader to an
163
+ * "Interrupting…" label until the agent turn unwinds. */
164
+ notifyInterrupting(): void;
150
165
  ensureLoadingAnimation(): void;
151
166
  startPendingSubmission(input: {
152
167
  text: string;
@@ -208,6 +223,7 @@ export interface InteractiveModeContext {
208
223
  handleDumpCommand(): void;
209
224
  handleDebugTranscriptCommand(): Promise<void>;
210
225
  handleClearCommand(): Promise<void>;
226
+ handleFreshCommand(): Promise<void>;
211
227
  handleDropCommand(): Promise<void>;
212
228
  handleForkCommand(): Promise<void>;
213
229
  handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
@@ -248,9 +264,9 @@ export interface InteractiveModeContext {
248
264
  handleCtrlD(): void;
249
265
  handleCtrlZ(): void;
250
266
  handleDequeue(): void;
251
- handleBackgroundCommand(): void;
252
267
  handleImagePaste(): Promise<boolean>;
253
268
  handleBtwCommand(question: string): Promise<void>;
269
+ handleTanCommand(work: string): Promise<void>;
254
270
  hasActiveBtw(): boolean;
255
271
  handleBtwEscape(): boolean;
256
272
  handleOmfgCommand(complaint: string): Promise<void>;
@@ -6,6 +6,17 @@ export interface CodeBlock {
6
6
  /** Block body with the trailing newline stripped. */
7
7
  code: string;
8
8
  }
9
+ /** A blockquote block: a maximal run of `>`-prefixed lines from markdown. */
10
+ export interface QuoteBlock {
11
+ /** Block body with each line's `>` marker (and one optional space) removed. */
12
+ text: string;
13
+ }
14
+ /** A drillable block within an assistant message, in document order. */
15
+ export type MessageBlock = ({
16
+ kind: "code";
17
+ } & CodeBlock) | ({
18
+ kind: "quote";
19
+ } & QuoteBlock);
9
20
  /** A runnable command found in the transcript. */
10
21
  export interface LastCommand {
11
22
  kind: "bash" | "eval";
@@ -19,7 +30,7 @@ export interface LastCommand {
19
30
  * `children` to drill into.
20
31
  */
21
32
  export interface CopyTarget {
22
- /** Stable identifier (e.g. "msg:1", "msg:1:code:0", "msg:1:all", "cmd:1"). */
33
+ /** Stable id (e.g. "msg:1", "msg:1:code:0", "msg:1:quote:0", "msg:1:all", "cmd:1"). */
23
34
  id: string;
24
35
  label: string;
25
36
  /** Dim annotation: line/block counts, language, or tool name. */
@@ -40,8 +51,17 @@ export interface CopySource {
40
51
  readonly messages: readonly AgentMessage[];
41
52
  getLastVisibleHandoffText(): string | undefined;
42
53
  }
54
+ /**
55
+ * Split assistant markdown into drillable blocks — fenced code and `>`-quoted
56
+ * runs — in document order. Fences mask their bodies, so a `>` line inside a
57
+ * code block is never mistaken for a quote. An unclosed fence is treated as
58
+ * ordinary text, matching the fenced-block grammar.
59
+ */
60
+ export declare function extractBlocks(text: string): MessageBlock[];
43
61
  /** Extract fenced code blocks from assistant markdown, in document order. */
44
62
  export declare function extractCodeBlocks(text: string): CodeBlock[];
63
+ /** Extract `>`-quoted blocks from assistant markdown, in document order. */
64
+ export declare function extractQuoteBlocks(text: string): QuoteBlock[];
45
65
  /** Walk the transcript backwards for the most recent bash command or eval code. */
46
66
  export declare function extractLastCommand(messages: readonly AgentMessage[]): LastCommand | undefined;
47
67
  /**
@@ -1,14 +1,14 @@
1
1
  import { type KeywordHighlighter } from "./gradient-highlight";
2
- /** Hidden system notice appended after a user message that mentions "workflow". */
2
+ /** Hidden system notice appended after a user message that mentions "workflowz". */
3
3
  export declare const WORKFLOW_NOTICE: string;
4
4
  /**
5
- * Whether `text` contains the standalone keyword "workflow"/"workflows"
5
+ * Whether `text` contains the standalone keyword "workflowz"
6
6
  * (lowercase, whitespace-delimited) in prose — never inside a code block, inline
7
7
  * code span, or XML/HTML section.
8
8
  */
9
9
  export declare function containsWorkflow(text: string): boolean;
10
10
  /**
11
- * Highlight every standalone "workflow"/"workflows" in `text` for editor display
11
+ * Highlight every standalone "workflowz" in `text` for editor display
12
12
  * with a warm amber→green gradient (hue 30..150), visually distinct from
13
13
  * ultrathink's rainbow and orchestrate's teal→violet.
14
14
  */
@@ -1,9 +1,10 @@
1
1
  /** Shape forwarded from the plan-mode resolve handler to InteractiveMode's
2
2
  * approval popup. Populated by the standing handler that the resolve tool
3
- * dispatches to when the agent submits `resolve { action: "apply" }`. */
3
+ * dispatches to when the agent submits `resolve { action: "apply" }`.
4
+ * `planFilePath` is the agent-chosen `local://<slug>-plan.md` artifact — it is
5
+ * never renamed on approval, so links to it stay valid for the session. */
4
6
  export interface PlanApprovalDetails {
5
7
  planFilePath: string;
6
- finalPlanFilePath: string;
7
8
  title: string;
8
9
  planExists: boolean;
9
10
  }
@@ -39,11 +40,29 @@ export declare function resolvePlanTitle(input: {
39
40
  * Replaces `-`/`_` separators with spaces and capitalizes the first letter.
40
41
  * Returns an empty string when the input collapses to whitespace. */
41
42
  export declare function humanizePlanTitle(title: string): string;
42
- interface RenameApprovedPlanFileOptions {
43
+ /** The `local://` URL a plan slug maps to. The agent writes the plan here and
44
+ * passes the slug to `resolve`; the file is never renamed, so this URL — and
45
+ * any hyperlink to it — stays valid for the life of the session. */
46
+ export declare function planFileUrlForSlug(slug: string): string;
47
+ export interface ResolveApprovedPlanInput {
48
+ /** The agent's `extra.title` from the `resolve` call, if any. */
49
+ suppliedTitle?: unknown;
50
+ /** The plan path recorded in plan-mode state (the entry default or a prior plan). */
51
+ statePlanFilePath: string;
52
+ /** Read a plan `local://` URL, returning null when the file does not exist. */
53
+ readPlan: (planUrl: string) => Promise<string | null>;
54
+ /** Optional fallback: list candidate plan `local://` URLs (newest first) so a
55
+ * plan whose name can't be reconstructed (e.g. a dropped `extra.title`) is
56
+ * still found. */
57
+ listPlanFiles?: () => Promise<string[]>;
58
+ }
59
+ export interface ResolvedApprovedPlan {
43
60
  planFilePath: string;
44
- finalPlanFilePath: string;
45
- getArtifactsDir: () => string | null;
46
- getSessionId: () => string | null;
61
+ planContent: string;
62
+ title: string;
47
63
  }
48
- export declare function renameApprovedPlanFile(options: RenameApprovedPlanFileOptions): Promise<void>;
49
- export {};
64
+ /** Locate the plan file the agent wrote and finalize its title — without
65
+ * renaming anything. Tries, in order: the slug derived from `extra.title`
66
+ * (`local://<slug>-plan.md`), the plan path from plan-mode state, then a scan
67
+ * of recent plan files. Throws a `ToolError` guiding the agent when none exist. */
68
+ export declare function resolveApprovedPlan(input: ResolveApprovedPlanInput): Promise<ResolvedApprovedPlan>;
@@ -3,10 +3,10 @@ import { type ProtectedToolContext } from "@oh-my-pi/pi-agent-core/compaction/to
3
3
  * Build a compaction protection matcher that keeps `read` results for the active
4
4
  * plan file intact through prune/shake — the plan analog of skill-read
5
5
  * protection. Matches both the canonical `local://PLAN.md` alias and the
6
- * session's current plan reference path (e.g. a titled `local://<title>.md`), so
7
- * the plan survives compaction whether the agent reads it by alias or by title.
6
+ * session's current plan reference path (the agent-chosen `local://<slug>-plan.md`),
7
+ * so the plan survives compaction whether the agent reads it by alias or by name.
8
8
  *
9
- * `getPlanReferencePath` is evaluated at match time so a mid-session retitle
10
- * (plan approval renames `PLAN.md` → `<title>.md`) is honored immediately.
9
+ * `getPlanReferencePath` is evaluated at match time so the plan path set on
10
+ * approval is honored immediately.
11
11
  */
12
12
  export declare function createPlanReadMatcher(getPlanReferencePath: () => string): (context: ProtectedToolContext) => boolean;
@@ -51,6 +51,8 @@ export interface CreateAgentSessionOptions {
51
51
  /** Optional provider-facing session identifier for prompt caches and sticky auth selection.
52
52
  * Keeps persisted session files isolated while reusing provider-side caches. */
53
53
  providerSessionId?: string;
54
+ /** Optional provider-facing prompt cache key, distinct from request lineage. */
55
+ providerPromptCacheKey?: string;
54
56
  /** Custom tools to register (in addition to built-in tools). Accepts both CustomTool and ToolDefinition. */
55
57
  customTools?: (CustomTool | ToolDefinition)[];
56
58
  /** Inline extensions (merged with discovery). */
@@ -294,6 +294,11 @@ export interface SessionStats {
294
294
  premiumRequests: number;
295
295
  cost: number;
296
296
  }
297
+ export interface FreshSessionResult {
298
+ previousSessionId: string;
299
+ sessionId: string;
300
+ closedProviderSessions: number;
301
+ }
297
302
  export declare const ANTHROPIC_TOOL_CALL_BATCH_CAP = 4;
298
303
  export declare function resolveToolCallBatchCapForModel(model: Model | undefined): number | undefined;
299
304
  export declare class AgentSession {
@@ -308,6 +313,8 @@ export declare class AgentSession {
308
313
  constructor(config: AgentSessionConfig);
309
314
  /** Model registry for API key resolution and model discovery */
310
315
  get modelRegistry(): ModelRegistry;
316
+ get asyncJobManager(): AsyncJobManager | undefined;
317
+ getAgentId(): string | undefined;
311
318
  /** Advance the tool-choice queue and return the next directive for the upcoming LLM call. */
312
319
  nextToolChoice(): ToolChoice | undefined;
313
320
  /**
@@ -378,6 +385,7 @@ export declare class AgentSession {
378
385
  * Call this when completely done with the session.
379
386
  */
380
387
  dispose(): Promise<void>;
388
+ freshSession(): FreshSessionResult | undefined;
381
389
  /** Full agent state */
382
390
  get state(): AgentState;
383
391
  /** Current model (may be undefined if not yet selected) */
@@ -609,9 +617,22 @@ export declare class AgentSession {
609
617
  setTodoPhases(phases: TodoPhase[]): void;
610
618
  /**
611
619
  * Abort current operation and wait for agent to become idle.
620
+ *
621
+ * `reason` (e.g. `USER_INTERRUPT_LABEL`) rides the agent's `AbortController`
622
+ * and surfaces verbatim on the aborted assistant message's `errorMessage`, so
623
+ * the transcript can distinguish a deliberate user interrupt from an opaque
624
+ * abort. Omit it for internal/lifecycle aborts.
612
625
  */
613
626
  abort(options?: {
614
627
  goalReason?: "interrupted" | "internal";
628
+ reason?: string;
629
+ }): Promise<void>;
630
+ /**
631
+ * Abort active work, then immediately resume the agent so queued steer/follow-up
632
+ * messages drain instead of waiting for another natural turn boundary.
633
+ */
634
+ interruptAndFlushQueuedMessages(options?: {
635
+ reason?: string;
615
636
  }): Promise<void>;
616
637
  /**
617
638
  * Start a new session, optionally with initial messages and parent tracking.
@@ -2,5 +2,5 @@
2
2
  * Re-exports from @oh-my-pi/pi-ai.
3
3
  * All credential storage types and the AuthStorage class now live in the ai package.
4
4
  */
5
- export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, OAuthCredential, SerializedAuthStorage, SnapshotResponse, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
5
+ export type { ApiKeyCredential, AuthCredential, AuthCredentialEntry, AuthCredentialStore, AuthStorageData, AuthStorageOptions, CredentialOrigin, CredentialOriginKind, OAuthCredential, SerializedAuthStorage, SnapshotResponse, StoredAuthCredential, } from "@oh-my-pi/pi-ai";
6
6
  export { AuthBrokerClient, AuthStorage, DEFAULT_SNAPSHOT_CACHE_TTL_MS, REMOTE_REFRESH_SENTINEL, RemoteAuthCredentialStore, readAuthBrokerSnapshotCache, SqliteAuthCredentialStore, writeAuthBrokerSnapshotCache, } from "@oh-my-pi/pi-ai";
@@ -40,6 +40,18 @@ export declare const SILENT_ABORT_MARKER = "__omp.silent_abort__";
40
40
  * than string-comparing inline so refactors to the marker constant (e.g.,
41
41
  * namespacing changes) propagate through every consumer in lockstep. */
42
42
  export declare function isSilentAbort(errorMessage: string | undefined): boolean;
43
+ /** Reason threaded through `AbortController.abort(reason)` when the user aborts
44
+ * the turn with Esc (see `AgentSession.abort`). The agent surfaces it verbatim
45
+ * on the aborted assistant message's `errorMessage`, so the transcript reads as
46
+ * a deliberate user interrupt instead of an opaque failure. */
47
+ export declare const USER_INTERRUPT_LABEL = "Interrupted by user";
48
+ /** Resolve the operator-facing label for an aborted assistant turn. A custom
49
+ * abort reason (e.g. `USER_INTERRUPT_LABEL`) threaded onto `errorMessage` is
50
+ * shown verbatim; aborts with no threaded reason fall back to the retry-aware
51
+ * generic label. Centralizes the live-stream (`EventController`), replay
52
+ * (`ui-helpers`), and component (`AssistantMessageComponent`) render paths so
53
+ * they stay in lockstep. */
54
+ export declare function resolveAbortLabel(errorMessage: string | undefined, retryAttempt?: number): string;
43
55
  /** Extract the optional `__pendingDisplayTag` field from a CustomMessage's
44
56
  * `details` blob. Safe over `unknown`; returns undefined when the field is
45
57
  * absent or non-string. */
@@ -317,9 +317,11 @@ export declare class SessionManager {
317
317
  /**
318
318
  * Move the session to a new working directory.
319
319
  * Moves session files and artifacts on disk, updates all internal references,
320
- * and rewrites the session header with the new cwd.
320
+ * and rewrites the session header with the new cwd. When provided,
321
+ * `targetSessionDir` is used instead of deriving the default directory for
322
+ * the new cwd (for `--continue --session-dir` / `--resume --session-dir`).
321
323
  */
322
- moveTo(newCwd: string): Promise<void>;
324
+ moveTo(newCwd: string, targetSessionDir?: string): Promise<void>;
323
325
  isPersisted(): boolean;
324
326
  /**
325
327
  * Force-persist all current entries to disk, even when no assistant message exists yet.
@@ -407,6 +409,7 @@ export declare class SessionManager {
407
409
  /** The source that set the session name: "user" (manual /rename or RPC) or "auto" (generated title). */
408
410
  get titleSource(): "auto" | "user" | undefined;
409
411
  getSessionName(): string | undefined;
412
+ onSessionNameChanged(cb: () => void): () => void;
410
413
  /**
411
414
  * Set the session display name.
412
415
  * @param source - "user" for explicit renames (/rename command, RPC); "auto" for generated titles.
@@ -565,7 +568,9 @@ export declare class SessionManager {
565
568
  * Fork a session into the current project directory.
566
569
  * Copies history from another session file while creating a new session file in the current sessionDir.
567
570
  */
568
- static forkFrom(sourcePath: string, cwd: string, sessionDir?: string, storage?: SessionStorage): Promise<SessionManager>;
571
+ static forkFrom(sourcePath: string, cwd: string, sessionDir?: string, storage?: SessionStorage, options?: {
572
+ suppressBreadcrumb?: boolean;
573
+ }): Promise<SessionManager>;
569
574
  /**
570
575
  * Open a specific session file.
571
576
  * @param path Path to session file
@@ -69,15 +69,13 @@ export interface SlashCommandRuntime {
69
69
  }
70
70
  /**
71
71
  * Runtime visible to TUI-only handlers (`handleTui`). Carries the interactive
72
- * mode context plus the background-detach hook. Intentionally narrower than
73
- * `SlashCommandRuntime` so existing callers can keep building it from just
74
- * `{ ctx, handleBackgroundCommand }`; when the TUI dispatcher needs to invoke
75
- * a `handle` (no `handleTui` override), it synthesizes a `SlashCommandRuntime`
76
- * from `ctx`.
72
+ * mode context. Intentionally narrower than `SlashCommandRuntime` so existing
73
+ * callers can keep building it from just `{ ctx }`; when the TUI dispatcher
74
+ * needs to invoke a `handle` (no `handleTui` override), it synthesizes a
75
+ * `SlashCommandRuntime` from `ctx`.
77
76
  */
78
77
  export interface TuiSlashCommandRuntime {
79
78
  ctx: InteractiveModeContext;
80
- handleBackgroundCommand: () => void;
81
79
  }
82
80
  /** Unified slash-command spec consumed by both TUI and ACP dispatchers. */
83
81
  export interface SlashCommandSpec extends BuiltinSlashCommand {
@@ -7,6 +7,8 @@ import type { AgentTelemetryConfig, ThinkingLevel } from "@oh-my-pi/pi-agent-cor
7
7
  import { ModelRegistry } from "../config/model-registry";
8
8
  import type { PromptTemplate } from "../config/prompt-templates";
9
9
  import { Settings } from "../config/settings";
10
+ import { type SettingPath } from "../config/settings-schema";
11
+ import type { CustomTool } from "../extensibility/custom-tools/types";
10
12
  import { type Skill } from "../extensibility/skills";
11
13
  import type { HindsightSessionState } from "../hindsight/state";
12
14
  import type { LocalProtocolOptions } from "../internal-urls";
@@ -100,6 +102,15 @@ export interface YieldItem {
100
102
  data?: unknown;
101
103
  status?: "success" | "aborted";
102
104
  error?: string;
105
+ /**
106
+ * Set by the in-tool yield validator when it exhausted its retry budget
107
+ * (MAX_SCHEMA_RETRIES) and accepted a schema-invalid payload anyway.
108
+ * `finalizeSubprocessOutput` honors this by serializing the payload and
109
+ * surfacing a stderr warning, instead of re-emitting `schema_violation`
110
+ * — which would silently swap the subagent's "accepted" view for a
111
+ * different, opaque error blob in the parent's view of the result.
112
+ */
113
+ schemaOverridden?: boolean;
103
114
  }
104
115
  interface FinalizeSubprocessOutputArgs {
105
116
  rawOutput: string;
@@ -118,9 +129,15 @@ interface FinalizeSubprocessOutputResult {
118
129
  abortedViaYield: boolean;
119
130
  hasYield: boolean;
120
131
  }
132
+ export declare const SUBAGENT_WARNING_SCHEMA_OVERRIDDEN = "SYSTEM WARNING: Subagent exhausted schema-retry budget; result was accepted despite failing the output schema.";
121
133
  export declare const SUBAGENT_WARNING_NULL_YIELD = "SYSTEM WARNING: Subagent called yield with null data.";
122
134
  export declare const SUBAGENT_WARNING_MISSING_YIELD = "SYSTEM WARNING: Subagent exited without calling yield tool after 3 reminders.";
123
135
  export declare function finalizeSubprocessOutput(args: FinalizeSubprocessOutputArgs): FinalizeSubprocessOutputResult;
136
+ /**
137
+ * Create proxy tools that reuse the parent's MCP connections.
138
+ */
139
+ export declare function createMCPProxyTools(mcpManager: MCPManager): CustomTool[];
140
+ export declare function createSubagentSettings(baseSettings: Settings, overrides?: Partial<Record<SettingPath, unknown>>): Settings;
124
141
  /**
125
142
  * Run a single agent in-process.
126
143
  */
@@ -29,6 +29,7 @@ export declare class TaskTool implements AgentTool<TaskToolSchemaInstance, TaskT
29
29
  readonly strict = true;
30
30
  readonly loadMode = "discoverable";
31
31
  readonly renderResult: typeof renderResult;
32
+ readonly mergeCallAndResult = true;
32
33
  get parameters(): TaskToolSchemaInstance;
33
34
  renderCall(args: unknown, options: Parameters<typeof renderTaskCall>[1], theme: Theme): import("@oh-my-pi/pi-tui").Component;
34
35
  /** Dynamic description that reflects current disabled-agent settings */
@@ -1,6 +1,6 @@
1
1
  import type { Component } from "@oh-my-pi/pi-tui";
2
2
  import type { RenderResultOptions } from "../extensibility/custom-tools/types";
3
- import type { Theme } from "../modes/theme/theme";
3
+ import { type Theme } from "../modes/theme/theme";
4
4
  import type { TaskParams, TaskToolDetails } from "./types";
5
5
  /**
6
6
  * Render the tool call arguments.
@@ -19,8 +19,9 @@ export declare function renderResult(result: {
19
19
  text?: string;
20
20
  }>;
21
21
  details?: TaskToolDetails;
22
- }, options: RenderResultOptions, theme: Theme): Component;
22
+ }, options: RenderResultOptions, theme: Theme, args?: TaskParams): Component;
23
23
  export declare const taskToolRenderer: {
24
24
  renderCall: typeof renderCall;
25
25
  renderResult: typeof renderResult;
26
+ mergeCallAndResult: boolean;
26
27
  };
@@ -31,6 +31,8 @@ type EntryStorage = TarStorage | ZipStorage;
31
31
  interface ArchiveIndexEntry extends ArchiveNode {
32
32
  storage?: EntryStorage;
33
33
  }
34
+ export declare function formatArchiveEntryLines(entries: readonly ArchiveDirectoryEntry[]): string[];
35
+ export declare function sniffArchiveFormat(bytes: Uint8Array): ArchiveFormat | undefined;
34
36
  export declare function parseArchivePathCandidates(filePath: string): ArchivePathCandidate[];
35
37
  export declare class ArchiveReader {
36
38
  #private;
@@ -41,4 +43,7 @@ export declare class ArchiveReader {
41
43
  readFile(subPath: string): Promise<ExtractedArchiveFile>;
42
44
  }
43
45
  export declare function openArchive(filePath: string): Promise<ArchiveReader>;
46
+ export declare function listArchiveRoot(bytes: Uint8Array, format: ArchiveFormat, opts?: {
47
+ limit?: number;
48
+ }): Promise<string>;
44
49
  export {};
@@ -34,6 +34,9 @@ export interface AstEditToolDetails {
34
34
  /** Absolute base directory used during the edit. Used by the renderer to resolve
35
35
  * display-relative paths to absolute paths for OSC 8 hyperlinks. */
36
36
  searchPath?: string;
37
+ /** Session cwd at edit time. Display header paths are cwd-relative, so the
38
+ * renderer resolves them against this; `searchPath` is the scope target. */
39
+ cwd?: string;
37
40
  }
38
41
  export declare class AstEditTool implements AgentTool<typeof astEditSchema, AstEditToolDetails> {
39
42
  private readonly session;
@@ -31,6 +31,9 @@ export interface AstGrepToolDetails {
31
31
  /** Absolute base directory used during search. Used by the renderer to resolve
32
32
  * display-relative paths to absolute paths for OSC 8 hyperlinks. */
33
33
  searchPath?: string;
34
+ /** Session cwd at search time. Display header/match paths are cwd-relative, so
35
+ * the renderer resolves them against this; `searchPath` is the scope target. */
36
+ cwd?: string;
34
37
  }
35
38
  export declare class AstGrepTool implements AgentTool<typeof astGrepSchema, AstGrepToolDetails> {
36
39
  private readonly session;
@@ -99,6 +99,7 @@ export interface ShellRendererConfig<TArgs> {
99
99
  resolveCommand?: (args: TArgs | undefined) => string | undefined;
100
100
  resolveCwd?: (args: TArgs | undefined) => string | undefined;
101
101
  resolveEnv?: (args: TArgs | undefined) => Record<string, string> | undefined;
102
+ showHeader?: boolean;
102
103
  }
103
104
  export declare function getBashEnvForDisplay(args: BashRenderArgs): Record<string, string> | undefined;
104
105
  /**
@@ -42,6 +42,14 @@ export type EvalProxyExecutor = (params: EvalToolParams, signal?: AbortSignal) =
42
42
  export interface EvalToolDescriptionOptions {
43
43
  py?: boolean;
44
44
  js?: boolean;
45
+ /**
46
+ * Whether `agent()` is allowed in this session. Driven by the parent's
47
+ * spawn policy (`getSessionSpawns`). Defaults to `true` for backward
48
+ * compatibility — when the session forbids spawning, the prelude doc
49
+ * omits the `agent()` entry so the model does not promise itself a
50
+ * helper that will only ever throw "spawns disabled".
51
+ */
52
+ spawns?: boolean;
45
53
  }
46
54
  export declare function getEvalToolDescription(options?: EvalToolDescriptionOptions): string;
47
55
  export interface EvalToolOptions {
@@ -15,10 +15,14 @@ declare const findSchema: z.ZodObject<{
15
15
  }, z.core.$strict>;
16
16
  export type FindToolInput = z.infer<typeof findSchema>;
17
17
  /**
18
- * Group find matches by their directory so the model doesn't pay repeated
19
- * tokens for shared path prefixes. Preserves the input order: groups appear in
20
- * the order their first member was emitted (mtime-desc for native glob), and
21
- * within a group entries keep their relative order.
18
+ * Group find matches into a multi-level directory tree so the model doesn't pay
19
+ * repeated tokens for shared path prefixes. Single-child directory chains fold
20
+ * into one header (`# a/b/c/`), so a common prefix including an absolute root
21
+ * for out-of-cwd results — collapses to a single line. Each level adds one `#`;
22
+ * files are listed bare under the deepest directory header that owns them.
23
+ *
24
+ * Order follows the input (mtime-desc for native glob): a directory appears when
25
+ * its first member is emitted, and a node's own files precede its subdirectories.
22
26
  */
23
27
  export declare function formatFindGroupedOutput(paths: readonly string[]): string;
24
28
  export interface FindToolDetails {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Drop `github-cache` rows for any `gh issue|pr <mutating-subcmd>` call
3
+ * embedded in `command`. Safe to invoke unconditionally; no-op when the
4
+ * command does not touch GitHub state.
5
+ */
6
+ export declare function invalidateGithubCacheForBashCommand(command: string): void;
@@ -55,6 +55,18 @@ export interface PutCachedInput<T = unknown> {
55
55
  export declare function putCached<T = unknown>(input: PutCachedInput<T>): void;
56
56
  /** Drop a specific cache entry. */
57
57
  export declare function invalidate(repo: string, kind: CacheKind, number: number, includeComments?: boolean, authKey?: string): void;
58
+ /**
59
+ * Drop every cached row for a given issue/PR number, regardless of repo,
60
+ * auth key, include_comments flag, or row kind ({@link CacheKind}). Best-effort:
61
+ * swallows DB failures the same way {@link invalidate} does.
62
+ *
63
+ * Used by the bash-side detector that reacts to `gh issue close` / `gh pr merge`
64
+ * style mutations. Repo + auth-key narrowing is intentionally skipped because
65
+ * the bash command often does not name the repo (defaults to cwd's `gh`
66
+ * config) and resolving the *current* repo from `cwd` for every bash call would
67
+ * be far more expensive than a write-amplified DELETE.
68
+ */
69
+ export declare function invalidateAllForNumber(number: number, repo?: string): void;
58
70
  /** Drop every cached row. Test helper. */
59
71
  export declare function clearAll(): void;
60
72
  /**