@oh-my-pi/pi-coding-agent 16.2.12 → 16.3.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.
Files changed (171) hide show
  1. package/CHANGELOG.md +115 -7
  2. package/dist/cli.js +5996 -5945
  3. package/dist/types/advisor/config.d.ts +4 -2
  4. package/dist/types/collab/host.d.ts +16 -0
  5. package/dist/types/collab/protocol.d.ts +9 -3
  6. package/dist/types/commit/model-selection.d.ts +5 -0
  7. package/dist/types/config/model-resolver.d.ts +12 -10
  8. package/dist/types/config/models-config-schema.d.ts +12 -0
  9. package/dist/types/config/models-config.d.ts +9 -0
  10. package/dist/types/config/settings-schema.d.ts +28 -5
  11. package/dist/types/edit/modes/patch.d.ts +11 -0
  12. package/dist/types/eval/agent-bridge.d.ts +5 -1
  13. package/dist/types/exec/bash-executor.d.ts +1 -0
  14. package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +86 -2
  15. package/dist/types/extensibility/skills.d.ts +2 -1
  16. package/dist/types/mnemopi/state.d.ts +12 -0
  17. package/dist/types/modes/components/agent-hub.d.ts +9 -5
  18. package/dist/types/modes/components/status-line/component.test.d.ts +1 -0
  19. package/dist/types/modes/components/usage-row.d.ts +1 -1
  20. package/dist/types/modes/controllers/command-controller.d.ts +0 -1
  21. package/dist/types/modes/controllers/extension-ui-controller.d.ts +6 -0
  22. package/dist/types/modes/controllers/streaming-reveal.d.ts +17 -1
  23. package/dist/types/modes/controllers/tool-args-reveal.d.ts +30 -3
  24. package/dist/types/modes/interactive-mode.d.ts +12 -7
  25. package/dist/types/modes/rpc/rpc-client.d.ts +5 -0
  26. package/dist/types/modes/rpc/rpc-mode.d.ts +64 -1
  27. package/dist/types/modes/session-teardown.d.ts +63 -0
  28. package/dist/types/modes/session-teardown.test.d.ts +1 -0
  29. package/dist/types/modes/theme/theme.d.ts +9 -4
  30. package/dist/types/modes/types.d.ts +2 -3
  31. package/dist/types/modes/utils/copy-targets.d.ts +2 -0
  32. package/dist/types/plan-mode/approved-plan-prompt.test.d.ts +1 -0
  33. package/dist/types/sdk.d.ts +9 -0
  34. package/dist/types/session/agent-session.d.ts +46 -13
  35. package/dist/types/session/exit-diagnostics.d.ts +48 -0
  36. package/dist/types/session/session-loader.d.ts +5 -0
  37. package/dist/types/task/executor.d.ts +12 -5
  38. package/dist/types/task/parallel.d.ts +1 -0
  39. package/dist/types/task/render.test.d.ts +1 -0
  40. package/dist/types/thinking.d.ts +2 -0
  41. package/dist/types/tools/checkpoint.d.ts +8 -0
  42. package/dist/types/tools/eval-render.d.ts +1 -0
  43. package/dist/types/tools/fetch.d.ts +11 -1
  44. package/dist/types/tools/index.d.ts +3 -1
  45. package/dist/types/tools/irc.d.ts +1 -0
  46. package/dist/types/tools/output-meta.d.ts +7 -0
  47. package/dist/types/tools/output-schema-validator.d.ts +7 -4
  48. package/dist/types/tools/path-utils.d.ts +16 -0
  49. package/dist/types/tools/render-utils.d.ts +4 -1
  50. package/dist/types/utils/git.d.ts +47 -2
  51. package/dist/types/web/search/provider.d.ts +7 -0
  52. package/dist/types/web/search/types.d.ts +1 -1
  53. package/package.json +12 -12
  54. package/src/advisor/config.ts +4 -2
  55. package/src/cli/bench-cli.ts +7 -2
  56. package/src/collab/guest.ts +94 -5
  57. package/src/collab/host.ts +80 -3
  58. package/src/collab/protocol.ts +9 -2
  59. package/src/commit/model-selection.ts +8 -2
  60. package/src/config/keybindings.ts +3 -1
  61. package/src/config/model-discovery.ts +66 -2
  62. package/src/config/model-registry.ts +7 -3
  63. package/src/config/model-resolver.ts +51 -23
  64. package/src/config/models-config-schema.ts +13 -0
  65. package/src/config/settings-schema.ts +44 -14
  66. package/src/edit/hashline/diff.ts +13 -2
  67. package/src/edit/index.ts +58 -8
  68. package/src/edit/modes/patch.ts +53 -18
  69. package/src/edit/streaming.ts +7 -6
  70. package/src/eval/__tests__/agent-bridge.test.ts +57 -1
  71. package/src/eval/agent-bridge.ts +15 -5
  72. package/src/exec/bash-executor.ts +7 -12
  73. package/src/extensibility/legacy-pi-coding-agent-shim.ts +534 -16
  74. package/src/extensibility/skills.ts +29 -6
  75. package/src/goals/guided-setup.ts +4 -3
  76. package/src/internal-urls/docs-index.generated.txt +1 -1
  77. package/src/lsp/client.ts +11 -14
  78. package/src/main.ts +38 -10
  79. package/src/mnemopi/state.ts +43 -7
  80. package/src/modes/acp/acp-agent.ts +1 -1
  81. package/src/modes/components/agent-hub.ts +10 -2
  82. package/src/modes/components/agent-transcript-viewer.ts +39 -7
  83. package/src/modes/components/assistant-message.ts +16 -10
  84. package/src/modes/components/chat-transcript-builder.ts +11 -1
  85. package/src/modes/components/custom-editor.test.ts +20 -0
  86. package/src/modes/components/hook-selector.ts +44 -25
  87. package/src/modes/components/model-selector.ts +1 -1
  88. package/src/modes/components/status-line/component.test.ts +44 -0
  89. package/src/modes/components/status-line/component.ts +9 -1
  90. package/src/modes/components/status-line/segments.ts +3 -3
  91. package/src/modes/components/usage-row.ts +16 -2
  92. package/src/modes/controllers/command-controller.ts +6 -21
  93. package/src/modes/controllers/event-controller.ts +11 -9
  94. package/src/modes/controllers/extension-ui-controller.ts +84 -3
  95. package/src/modes/controllers/input-controller.ts +16 -13
  96. package/src/modes/controllers/selector-controller.ts +3 -8
  97. package/src/modes/controllers/streaming-reveal.ts +75 -53
  98. package/src/modes/controllers/tool-args-reveal.ts +340 -10
  99. package/src/modes/interactive-mode.ts +122 -79
  100. package/src/modes/rpc/rpc-client.ts +21 -0
  101. package/src/modes/rpc/rpc-mode.ts +197 -46
  102. package/src/modes/session-teardown.test.ts +219 -0
  103. package/src/modes/session-teardown.ts +82 -0
  104. package/src/modes/setup-wizard/scenes/theme.ts +2 -2
  105. package/src/modes/skill-command.ts +7 -20
  106. package/src/modes/theme/theme.ts +29 -15
  107. package/src/modes/types.ts +2 -3
  108. package/src/modes/utils/copy-targets.ts +12 -0
  109. package/src/modes/utils/ui-helpers.ts +19 -2
  110. package/src/plan-mode/approved-plan-prompt.test.ts +36 -0
  111. package/src/prompts/advisor/system.md +1 -1
  112. package/src/prompts/agents/tester.md +6 -2
  113. package/src/prompts/skills/autoload.md +8 -0
  114. package/src/prompts/skills/user-invocation.md +11 -0
  115. package/src/prompts/steering/parent-irc.md +5 -0
  116. package/src/prompts/system/irc-incoming.md +2 -0
  117. package/src/prompts/system/mid-run-todo-nudge.md +3 -0
  118. package/src/prompts/system/plan-mode-approved.md +7 -10
  119. package/src/prompts/system/plan-mode-compact-instructions.md +2 -1
  120. package/src/prompts/system/plan-mode-reference.md +3 -4
  121. package/src/prompts/system/rewind-report.md +6 -0
  122. package/src/prompts/system/subagent-system-prompt.md +3 -0
  123. package/src/prompts/tools/irc.md +2 -1
  124. package/src/prompts/tools/job.md +2 -2
  125. package/src/prompts/tools/rewind.md +3 -2
  126. package/src/prompts/tools/ssh.md +1 -0
  127. package/src/prompts/tools/task.md +4 -0
  128. package/src/sdk.ts +18 -4
  129. package/src/session/agent-session.ts +660 -114
  130. package/src/session/exit-diagnostics.ts +202 -0
  131. package/src/session/session-context.ts +25 -13
  132. package/src/session/session-loader.ts +58 -25
  133. package/src/session/session-manager.ts +0 -1
  134. package/src/session/session-persistence.ts +30 -4
  135. package/src/session/settings-stream-fn.ts +14 -0
  136. package/src/slash-commands/builtin-registry.ts +35 -3
  137. package/src/system-prompt.ts +15 -1
  138. package/src/task/executor.ts +31 -8
  139. package/src/task/index.ts +31 -9
  140. package/src/task/isolation-runner.ts +18 -2
  141. package/src/task/parallel.ts +7 -2
  142. package/src/task/render.test.ts +121 -0
  143. package/src/task/render.ts +48 -2
  144. package/src/task/worktree.ts +12 -13
  145. package/src/task/yield-assembly.ts +8 -5
  146. package/src/thinking.ts +5 -0
  147. package/src/tools/ask.ts +188 -9
  148. package/src/tools/ast-edit.ts +7 -0
  149. package/src/tools/ast-grep.ts +11 -0
  150. package/src/tools/bash.ts +6 -30
  151. package/src/tools/checkpoint.ts +15 -1
  152. package/src/tools/eval-render.ts +15 -0
  153. package/src/tools/fetch.ts +82 -18
  154. package/src/tools/gh.ts +1 -1
  155. package/src/tools/grep.ts +45 -27
  156. package/src/tools/index.ts +3 -1
  157. package/src/tools/irc.ts +24 -9
  158. package/src/tools/output-meta.ts +50 -0
  159. package/src/tools/output-schema-validator.ts +152 -15
  160. package/src/tools/path-utils.ts +55 -10
  161. package/src/tools/read.ts +1 -1
  162. package/src/tools/render-utils.ts +5 -3
  163. package/src/tools/ssh.ts +8 -1
  164. package/src/tools/yield.ts +41 -1
  165. package/src/utils/commit-message-generator.ts +2 -2
  166. package/src/utils/git.ts +271 -29
  167. package/src/utils/thinking-display.ts +13 -0
  168. package/src/web/search/index.ts +9 -28
  169. package/src/web/search/provider.ts +26 -1
  170. package/src/web/search/providers/duckduckgo.ts +1 -1
  171. package/src/web/search/types.ts +5 -1
@@ -1,8 +1,10 @@
1
1
  /**
2
2
  * One advisor declared in a `WATCHDOG.yml` file. `model` is a model selector
3
3
  * with an optional `:level` thinking suffix (e.g. `x-ai/grok-code-fast:high`),
4
- * resolved exactly like any other model override; `tools` is a subset of the
5
- * read-only investigative tool names (default: all). `instructions` is the
4
+ * resolved exactly like any other model override; `tools` is a subset of
5
+ * `BUILTIN_TOOL_NAMES` any built-in name, including mutating tools such as
6
+ * `edit`/`write`/`bash` (the advisor is a full agent). Omitted or empty falls
7
+ * back to the default `read`/`grep`/`glob` subset. `instructions` is the
6
8
  * advisor's specialization, appended to the shared baseline.
7
9
  */
8
10
  export interface AdvisorConfig {
@@ -8,8 +8,23 @@
8
8
  * agent-registry snapshots (Agent Hub table), hub chat/kill/revive commands,
9
9
  * and incremental subagent-transcript reads.
10
10
  */
11
+ import type { CollabUiRequestDraft, CollabUiResponseValue } from "@oh-my-pi/pi-wire";
11
12
  import type { InteractiveModeContext } from "../modes/types";
12
13
  import { type CollabParticipant } from "./protocol";
14
+ /** Max bytes served per fetch-transcript reply (guest re-requests from `newSize`). */
15
+ export declare const TRANSCRIPT_READ_CAP: number;
16
+ /**
17
+ * Outcome of {@link CollabHost.requestGuestUi}. `answered` carries the guest's
18
+ * response (an `undefined` value is a genuine guest cancel); `unavailable`
19
+ * means the collab channel went away (teardown, relay drop) or the request was
20
+ * aborted before any guest answered — callers MUST NOT treat it as a cancel.
21
+ */
22
+ export type CollabGuestUiResult = {
23
+ kind: "answered";
24
+ value: CollabUiResponseValue;
25
+ } | {
26
+ kind: "unavailable";
27
+ };
13
28
  export declare class CollabHost {
14
29
  #private;
15
30
  constructor(ctx: InteractiveModeContext);
@@ -21,6 +36,7 @@ export declare class CollabHost {
21
36
  /** Read-only variant of {@link webLink}. */
22
37
  get webViewLink(): string;
23
38
  get participants(): CollabParticipant[];
39
+ requestGuestUi(request: CollabUiRequestDraft, signal?: AbortSignal): Promise<CollabGuestUiResult> | null;
24
40
  start(relayUrl: string, webUrl?: string): Promise<void>;
25
41
  /** Broadcast a goodbye, detach all taps, and close the socket. */
26
42
  stop(reason: string): Promise<void>;
@@ -7,12 +7,12 @@
7
7
  * control messages that carry no session data.
8
8
  */
9
9
  import type { ImageContent, Model } from "@oh-my-pi/pi-ai";
10
- import type { BusChannel, GuestFrame, ParsedCollabLink, Participant, SessionState, AgentSnapshot as WireAgentSnapshot } from "@oh-my-pi/pi-wire";
10
+ import type { BusChannel, CollabUiRequest, GuestFrame, ParsedCollabLink, Participant, SessionState, AgentSnapshot as WireAgentSnapshot } from "@oh-my-pi/pi-wire";
11
11
  import { DEFAULT_RELAY_URL, ENVELOPE_HEADER_LENGTH, ROOM_ID_BYTES } from "@oh-my-pi/pi-wire";
12
12
  import type { ContextUsage } from "../extensibility/extensions/types";
13
13
  import type { AgentSessionEvent } from "../session/agent-session";
14
14
  import type { SessionEntry, SessionHeader } from "../session/session-entries";
15
- export type { CollabPromptDetails, ParsedCollabLink, RelayControlMessage, RelayControlToGuest, RelayControlToHost, } from "@oh-my-pi/pi-wire";
15
+ export type { CollabPromptDetails, CollabUiRequest, CollabUiRequestDraft, CollabUiResponseValue, CollabUiSelectItem, ParsedCollabLink, RelayControlMessage, RelayControlToGuest, RelayControlToHost, } from "@oh-my-pi/pi-wire";
16
16
  export { COLLAB_PROMPT_MESSAGE_TYPE, COLLAB_PROTO } from "@oh-my-pi/pi-wire";
17
17
  export { DEFAULT_RELAY_URL, ENVELOPE_HEADER_LENGTH, ROOM_ID_BYTES };
18
18
  export type CollabParticipant = Participant;
@@ -86,8 +86,14 @@ export type CollabFrame = Exclude<GuestFrame, {
86
86
  | {
87
87
  t: "agents";
88
88
  agents: AgentSnapshot[];
89
+ } | {
90
+ t: "ui-request";
91
+ request: CollabUiRequest;
92
+ } | {
93
+ t: "ui-request-end";
94
+ reqId: number;
89
95
  }
90
- /** Targeted reply to fetch-transcript; `text` is decoded JSONL from `fromByte`, `newSize` the next offset base. */
96
+ /** Targeted reply to fetch-transcript; `error` marks a terminal read failure that guests must surface without hot retrying. */
91
97
  | {
92
98
  t: "transcript";
93
99
  reqId: number;
@@ -11,6 +11,11 @@ export interface ResolvedCommitModel {
11
11
  * central force-refresh + account-rotation policy.
12
12
  */
13
13
  apiKey: ApiKey;
14
+ /**
15
+ * Commit-time inference is stateless: session-level auto classification
16
+ * isn't available, so an explicit `:auto` selector collapses to "no
17
+ * override" and the model's own default level fills in.
18
+ */
14
19
  thinkingLevel?: ThinkingLevel;
15
20
  }
16
21
  type CommitModelRegistry = ModelLookupRegistry & ApiKeyResolverRegistry & {
@@ -16,6 +16,7 @@
16
16
  */
17
17
  import { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
18
18
  import type { Api, Effort, Model } from "@oh-my-pi/pi-ai";
19
+ import { type ConfiguredThinkingLevel } from "../thinking";
19
20
  import { type ModelRegistry } from "./model-registry";
20
21
  import { type ModelRole } from "./model-roles";
21
22
  import type { Settings } from "./settings";
@@ -34,6 +35,7 @@ export interface ScopedModel {
34
35
  }
35
36
  interface ThinkingSuffixOptions {
36
37
  allowMaxAlias?: boolean;
38
+ allowAutoAlias?: boolean;
37
39
  }
38
40
  interface ModelStringParseOptions extends ThinkingSuffixOptions {
39
41
  isLiteralModelId?: (provider: string, id: string) => boolean;
@@ -45,14 +47,14 @@ interface ModelStringParseOptions extends ThinkingSuffixOptions {
45
47
  export declare function parseModelString(modelStr: string, options?: ModelStringParseOptions): {
46
48
  provider: string;
47
49
  id: string;
48
- thinkingLevel?: ThinkingLevel;
50
+ thinkingLevel?: ConfiguredThinkingLevel;
49
51
  } | undefined;
50
52
  /**
51
53
  * Format a model as "provider/modelId" string.
52
54
  */
53
55
  export declare function formatModelString(model: Model<Api>): string;
54
56
  export declare function formatModelStringWithRouting(model: Model<Api>): string;
55
- export declare function formatModelSelectorValue(selector: string, thinkingLevel: ThinkingLevel | undefined): string;
57
+ export declare function formatModelSelectorValue(selector: string, thinkingLevel: ConfiguredThinkingLevel | undefined): string;
56
58
  /**
57
59
  * Split a trailing `@<upstream>` provider-routing selector off a model pattern.
58
60
  *
@@ -83,7 +85,7 @@ export declare function getModelMatchPreferences(settings?: Partial<Pick<Setting
83
85
  export interface ParsedModelResult {
84
86
  model: Model<Api> | undefined;
85
87
  /** Thinking level if explicitly specified in pattern, undefined otherwise */
86
- thinkingLevel?: ThinkingLevel;
88
+ thinkingLevel?: ConfiguredThinkingLevel;
87
89
  /** Upstream provider slug from an `@upstream` routing selector, if present. */
88
90
  upstream?: string;
89
91
  warning: string | undefined;
@@ -110,7 +112,7 @@ export declare function resolveAgentModelPatterns(options: AgentModelPatternReso
110
112
  */
111
113
  export interface ResolvedModelRoleValue {
112
114
  model: Model<Api> | undefined;
113
- thinkingLevel?: ThinkingLevel;
115
+ thinkingLevel?: ConfiguredThinkingLevel;
114
116
  explicitThinkingLevel: boolean;
115
117
  warning: string | undefined;
116
118
  }
@@ -121,7 +123,7 @@ export declare function resolveModelRoleValue(roleValue: string | undefined, ava
121
123
  interface ExplicitThinkingSelectorOptions {
122
124
  isLiteralModelId?: (provider: string, id: string) => boolean;
123
125
  }
124
- export declare function extractExplicitThinkingSelector(value: string | undefined, settings?: Settings, options?: ExplicitThinkingSelectorOptions): ThinkingLevel | undefined;
126
+ export declare function extractExplicitThinkingSelector(value: string | undefined, settings?: Settings, options?: ExplicitThinkingSelectorOptions): ConfiguredThinkingLevel | undefined;
125
127
  /**
126
128
  * Resolve a model identifier or pattern to a Model instance.
127
129
  */
@@ -140,7 +142,7 @@ export declare function resolveModelFromSettings(options: {
140
142
  */
141
143
  export declare function resolveModelOverride(modelPatterns: string[], modelRegistry: ModelLookupRegistry, settings?: Settings): {
142
144
  model?: Model<Api>;
143
- thinkingLevel?: ThinkingLevel;
145
+ thinkingLevel?: ConfiguredThinkingLevel;
144
146
  explicitThinkingLevel: boolean;
145
147
  };
146
148
  /**
@@ -166,7 +168,7 @@ export declare function resolveModelOverride(modelPatterns: string[], modelRegis
166
168
  */
167
169
  export declare function resolveModelOverrideWithAuthFallback(modelPatterns: string[], parentActiveModelPattern: string | undefined, modelRegistry: ModelLookupRegistry & Pick<ModelRegistry, "getApiKey">, settings?: Settings): Promise<{
168
170
  model?: Model<Api>;
169
- thinkingLevel?: ThinkingLevel;
171
+ thinkingLevel?: ConfiguredThinkingLevel;
170
172
  explicitThinkingLevel: boolean;
171
173
  authFallbackUsed: boolean;
172
174
  }>;
@@ -175,7 +177,7 @@ export declare function resolveModelOverrideWithAuthFallback(modelPatterns: stri
175
177
  */
176
178
  export declare function resolveRoleSelection(roles: readonly string[], settings: Settings, availableModels: Model<Api>[]): {
177
179
  model: Model<Api>;
178
- thinkingLevel?: ThinkingLevel;
180
+ thinkingLevel?: ConfiguredThinkingLevel;
179
181
  } | undefined;
180
182
  /**
181
183
  * Resolve the model for the `advisor` role. A configured `modelRoles.advisor`
@@ -187,7 +189,7 @@ export declare function resolveRoleSelection(roles: readonly string[], settings:
187
189
  */
188
190
  export declare function resolveAdvisorRoleSelection(settings: Settings, availableModels: Model<Api>[]): {
189
191
  model: Model<Api>;
190
- thinkingLevel?: ThinkingLevel;
192
+ thinkingLevel?: ConfiguredThinkingLevel;
191
193
  } | undefined;
192
194
  /**
193
195
  * Resolve model patterns to actual Model objects with optional thinking levels
@@ -234,7 +236,7 @@ export declare function filterAvailableModelsByEnabledPatterns(available: Model<
234
236
  export interface ResolveCliModelResult {
235
237
  model: Model<Api> | undefined;
236
238
  selector?: string;
237
- thinkingLevel?: ThinkingLevel;
239
+ thinkingLevel?: ConfiguredThinkingLevel;
238
240
  warning: string | undefined;
239
241
  error: string | undefined;
240
242
  }
@@ -245,6 +245,9 @@ export declare const ModelOverrideSchema: import("arktype/internal/variants/obje
245
245
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
246
246
  endpoint?: string | undefined;
247
247
  model?: string | undefined;
248
+ v2StreamingEnabled?: boolean | undefined;
249
+ v2Endpoint?: string | undefined;
250
+ streamingEndpoint?: string | undefined;
248
251
  } | undefined;
249
252
  }, {}>;
250
253
  export type ModelOverride = typeof ModelOverrideSchema.infer;
@@ -368,6 +371,9 @@ export declare const ModelsConfigSchema: import("arktype/internal/variants/objec
368
371
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
369
372
  endpoint?: string | undefined;
370
373
  model?: string | undefined;
374
+ v2StreamingEnabled?: boolean | undefined;
375
+ v2Endpoint?: string | undefined;
376
+ streamingEndpoint?: string | undefined;
371
377
  } | undefined;
372
378
  authHeader?: boolean | undefined;
373
379
  auth?: "apiKey" | "none" | "oauth" | undefined;
@@ -524,6 +530,9 @@ export declare const ModelsConfigSchema: import("arktype/internal/variants/objec
524
530
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
525
531
  endpoint?: string | undefined;
526
532
  model?: string | undefined;
533
+ v2StreamingEnabled?: boolean | undefined;
534
+ v2Endpoint?: string | undefined;
535
+ streamingEndpoint?: string | undefined;
527
536
  } | undefined;
528
537
  }[] | undefined;
529
538
  modelOverrides?: {
@@ -674,6 +683,9 @@ export declare const ModelsConfigSchema: import("arktype/internal/variants/objec
674
683
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
675
684
  endpoint?: string | undefined;
676
685
  model?: string | undefined;
686
+ v2StreamingEnabled?: boolean | undefined;
687
+ v2Endpoint?: string | undefined;
688
+ streamingEndpoint?: string | undefined;
677
689
  } | undefined;
678
690
  };
679
691
  } | undefined;
@@ -141,6 +141,9 @@ export declare const ModelsConfigFile: ConfigFile<{
141
141
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
142
142
  endpoint?: string | undefined;
143
143
  model?: string | undefined;
144
+ v2StreamingEnabled?: boolean | undefined;
145
+ v2Endpoint?: string | undefined;
146
+ streamingEndpoint?: string | undefined;
144
147
  } | undefined;
145
148
  authHeader?: boolean | undefined;
146
149
  auth?: "apiKey" | "none" | "oauth" | undefined;
@@ -282,6 +285,9 @@ export declare const ModelsConfigFile: ConfigFile<{
282
285
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
283
286
  endpoint?: string | undefined;
284
287
  model?: string | undefined;
288
+ v2StreamingEnabled?: boolean | undefined;
289
+ v2Endpoint?: string | undefined;
290
+ streamingEndpoint?: string | undefined;
285
291
  } | undefined;
286
292
  }[] | undefined;
287
293
  modelOverrides?: {
@@ -417,6 +423,9 @@ export declare const ModelsConfigFile: ConfigFile<{
417
423
  api?: "anthropic-messages" | "azure-openai-responses" | "google-gemini-cli" | "google-generative-ai" | "google-vertex" | "openai-codex-responses" | "openai-completions" | "openai-responses" | undefined;
418
424
  endpoint?: string | undefined;
419
425
  model?: string | undefined;
426
+ v2StreamingEnabled?: boolean | undefined;
427
+ v2Endpoint?: string | undefined;
428
+ streamingEndpoint?: string | undefined;
420
429
  } | undefined;
421
430
  };
422
431
  } | undefined;
@@ -85,7 +85,7 @@ interface StringDef {
85
85
  }
86
86
  interface NumberDef {
87
87
  type: "number";
88
- default: number;
88
+ default: number | undefined;
89
89
  ui?: UiNumber;
90
90
  }
91
91
  interface EnumDef<T extends readonly string[]> {
@@ -1401,6 +1401,16 @@ export declare const SETTINGS_SCHEMA: {
1401
1401
  }];
1402
1402
  };
1403
1403
  };
1404
+ readonly "providers.anthropic.serverSideFallback": {
1405
+ readonly type: "boolean";
1406
+ readonly default: false;
1407
+ readonly ui: {
1408
+ readonly tab: "model";
1409
+ readonly group: "Retry & Fallback";
1410
+ readonly label: "Anthropic Server-Side Fallback (Fable 5)";
1411
+ readonly description: "When a Claude Fable 5 / Mythos 5 request is blocked by Anthropic's safety classifier, retry it on Claude Opus 4.8 server-side (Anthropic `server-side-fallback-2026-06-01` beta). Opt-in — leaving this off preserves the pre-fallback behavior for every request.";
1412
+ };
1413
+ };
1404
1414
  readonly steeringMode: {
1405
1415
  readonly type: "enum";
1406
1416
  readonly values: readonly ["all", "one-at-a-time"];
@@ -2071,7 +2081,7 @@ export declare const SETTINGS_SCHEMA: {
2071
2081
  };
2072
2082
  readonly "compaction.reserveTokens": {
2073
2083
  readonly type: "number";
2074
- readonly default: 16384;
2084
+ readonly default: undefined;
2075
2085
  };
2076
2086
  readonly "compaction.keepRecentTokens": {
2077
2087
  readonly type: "number";
@@ -4286,7 +4296,7 @@ export declare const SETTINGS_SCHEMA: {
4286
4296
  readonly tab: "tasks";
4287
4297
  readonly group: "Subagents";
4288
4298
  readonly label: "Soft Subagent Request Budget";
4289
- readonly description: "Soft per-subagent request budget (assistant requests per run). Crossing it injects one steering notice asking the subagent to wrap up; at 1.5x the budget the run is aborted gracefully, salvaging partial output. 0 disables the guard. Bundled explore/sonic agents use a lower built-in budget.";
4299
+ readonly description: "Soft per-subagent request budget (assistant requests per run). Crossing it can inject a steering notice when task.softRequestBudgetNotice is enabled; at 1.5x the budget the run is aborted gracefully, salvaging partial output. 0 disables the guard. Bundled explore/sonic agents use a lower built-in budget.";
4290
4300
  readonly options: readonly [{
4291
4301
  readonly value: "0";
4292
4302
  readonly label: "Disabled";
@@ -4303,6 +4313,16 @@ export declare const SETTINGS_SCHEMA: {
4303
4313
  }];
4304
4314
  };
4305
4315
  };
4316
+ readonly "task.softRequestBudgetNotice": {
4317
+ readonly type: "boolean";
4318
+ readonly default: false;
4319
+ readonly ui: {
4320
+ readonly tab: "tasks";
4321
+ readonly group: "Subagents";
4322
+ readonly label: "Soft Request Budget Notice";
4323
+ readonly description: "Inject one steering notice when a subagent crosses its soft request budget. Off by default; enabling it asks the child to wrap up before the 1.5x graceful abort guard.";
4324
+ };
4325
+ };
4306
4326
  readonly "task.disabledAgents": {
4307
4327
  readonly type: "array";
4308
4328
  readonly default: string[];
@@ -4552,7 +4572,7 @@ export declare const SETTINGS_SCHEMA: {
4552
4572
  }, {
4553
4573
  readonly value: "duckduckgo";
4554
4574
  readonly label: "DuckDuckGo";
4555
- readonly description: "Scrapes the DuckDuckGo HTML frontend (no API key)";
4575
+ readonly description: "Credential-free best-effort fallback; may be bot-challenged on datacenter/shared-egress IPs";
4556
4576
  }];
4557
4577
  };
4558
4578
  };
@@ -5414,6 +5434,9 @@ export type SettingValue<P extends SettingPath> = Schema[P] extends {
5414
5434
  type: "string";
5415
5435
  } ? string | undefined : Schema[P] extends {
5416
5436
  type: "number";
5437
+ default: undefined;
5438
+ } ? number | undefined : Schema[P] extends {
5439
+ type: "number";
5417
5440
  } ? number : Schema[P] extends {
5418
5441
  type: "enum";
5419
5442
  values: infer V;
@@ -5449,7 +5472,7 @@ export interface CompactionSettings {
5449
5472
  strategy: "context-full" | "handoff" | "shake" | "snapcompact" | "off";
5450
5473
  thresholdPercent: number;
5451
5474
  thresholdTokens: number;
5452
- reserveTokens: number;
5475
+ reserveTokens: number | undefined;
5453
5476
  keepRecentTokens: number;
5454
5477
  midTurnEnabled: boolean;
5455
5478
  handoffSaveToDisk: boolean;
@@ -40,6 +40,14 @@ export interface ApplyPatchOptions {
40
40
  fuzzyThreshold?: number;
41
41
  allowFuzzy?: boolean;
42
42
  fs?: FileSystem;
43
+ /**
44
+ * Permit `op: "create"` to replace an existing file (full-file overwrite).
45
+ * The JSON `patch` edit mode sanctions create-as-overwrite for major
46
+ * restructures (see prompts/tools/patch.md); the Codex `apply_patch`
47
+ * envelope documents `*** Add File` as strictly non-overwriting and must
48
+ * leave this unset.
49
+ */
50
+ allowCreateOverwrite?: boolean;
43
51
  }
44
52
  /** Default filesystem implementation using Bun APIs */
45
53
  export declare const defaultFileSystem: FileSystem;
@@ -54,6 +62,7 @@ export declare function previewPatch(input: PatchInput, options: ApplyPatchOptio
54
62
  export declare function computePatchDiff(input: PatchInput, cwd: string, options?: {
55
63
  fuzzyThreshold?: number;
56
64
  allowFuzzy?: boolean;
65
+ allowCreateOverwrite?: boolean;
57
66
  }): Promise<{
58
67
  diff: string;
59
68
  firstChangedLine: number | undefined;
@@ -83,6 +92,8 @@ export interface ExecutePatchSingleOptions {
83
92
  batchRequest?: LspBatchRequest;
84
93
  allowFuzzy: boolean;
85
94
  fuzzyThreshold: number;
95
+ /** See {@link ApplyPatchOptions.allowCreateOverwrite}; set by the JSON `patch` mode only. */
96
+ allowCreateOverwrite?: boolean;
86
97
  writethrough: WritethroughCallback;
87
98
  beginDeferredDiagnosticsForPath: (path: string) => WritethroughDeferredHandle;
88
99
  }
@@ -4,7 +4,11 @@ import type { JsStatusEvent } from "./js/shared/types";
4
4
  import "../tools/review";
5
5
  /** Synthetic bridge name reserved for the `agent()` helper across both runtimes. */
6
6
  export declare const EVAL_AGENT_BRIDGE_NAME = "__agent__";
7
- /** Hard recursion limit for eval-driven subagents. */
7
+ /**
8
+ * Hard recursion ceiling for eval-driven subagents. The user setting
9
+ * `task.maxRecursionDepth` is honored on top of this — whichever is tighter
10
+ * wins, so a maintainer-friendly cap can't get raised by a user setting.
11
+ */
8
12
  export declare const EVAL_AGENT_MAX_DEPTH = 3;
9
13
  export interface EvalAgentBridgeOptions {
10
14
  session: ToolSession;
@@ -38,6 +38,7 @@ export interface BashResult {
38
38
  outputLines: number;
39
39
  outputBytes: number;
40
40
  artifactId?: string;
41
+ workingDir?: string;
41
42
  }
42
43
  /** Translate `ShellMinimizerSettings` into native `MinimizerOptions`, or `undefined` when disabled. */
43
44
  export declare function buildMinimizerOptions(group: ShellMinimizerSettings): MinimizerOptions | undefined;
@@ -14,18 +14,102 @@
14
14
  import type { TSchema } from "@oh-my-pi/pi-ai";
15
15
  import { Settings } from "../config/settings";
16
16
  import type { ToolDefinition } from "./extensions/types";
17
- import { Type } from "./typebox";
17
+ export interface BashSpawnContext {
18
+ command: string;
19
+ cwd: string;
20
+ env: NodeJS.ProcessEnv;
21
+ }
22
+ export type BashSpawnHook = (context: BashSpawnContext) => BashSpawnContext;
23
+ export interface BashOperations {
24
+ exec: (command: string, cwd: string, options: {
25
+ onData: (data: Buffer) => void;
26
+ signal?: AbortSignal;
27
+ timeout?: number;
28
+ env?: NodeJS.ProcessEnv;
29
+ }) => Promise<{
30
+ exitCode: number | null;
31
+ }>;
32
+ }
33
+ export interface BashToolOptions {
34
+ operations?: BashOperations;
35
+ commandPrefix?: string;
36
+ spawnHook?: BashSpawnHook;
37
+ }
38
+ export interface ReadToolOptions {
39
+ /** Auto-resize large images; maps onto the `images.autoResize` setting. Default: true. */
40
+ autoResizeImages?: boolean;
41
+ }
42
+ export interface GrepToolOptions {
43
+ /**
44
+ * Unsupported. The historical grep operations seam (isDirectory/readFile for
45
+ * context lines) never delegated the search itself — ripgrep always ran
46
+ * locally — and the built-in native grep tool exposes no filesystem seam at
47
+ * all. Supplying operations throws at tool creation instead of silently
48
+ * searching the local filesystem.
49
+ */
50
+ operations?: unknown;
51
+ }
52
+ export interface FindOperations {
53
+ exists: (absolutePath: string) => Promise<boolean> | boolean;
54
+ glob: (pattern: string, cwd: string, options: {
55
+ ignore: string[];
56
+ limit: number;
57
+ }) => Promise<string[]> | string[];
58
+ }
59
+ export interface FindToolOptions {
60
+ operations?: FindOperations;
61
+ }
62
+ export interface LsOperations {
63
+ exists: (absolutePath: string) => Promise<boolean> | boolean;
64
+ stat: (absolutePath: string) => Promise<{
65
+ isDirectory(): boolean;
66
+ }> | {
67
+ isDirectory(): boolean;
68
+ };
69
+ readdir: (absolutePath: string) => Promise<string[]> | string[];
70
+ }
71
+ export interface LsToolOptions {
72
+ operations?: LsOperations;
73
+ }
74
+ /** Parse frontmatter using the historical Pi package-root helper. */
18
75
  export interface ParsedFrontmatter<T extends Record<string, unknown> = Record<string, unknown>> {
19
76
  frontmatter: T;
20
77
  body: string;
21
78
  }
79
+ /** Parse YAML frontmatter and throw on invalid metadata. */
22
80
  export declare function parseFrontmatter<T extends Record<string, unknown> = Record<string, unknown>>(content: string): ParsedFrontmatter<T>;
81
+ /** Return content without YAML frontmatter. */
23
82
  export declare function stripFrontmatter(content: string): string;
83
+ /** Mark an extension-authored tool as a Pi-compatible tool definition. */
24
84
  export declare function defineTool<TParams extends TSchema = TSchema, TDetails = unknown>(tool: ToolDefinition<TParams, TDetails>): ToolDefinition<TParams, TDetails>;
85
+ /** Create the legacy read tool definition. */
86
+ export declare function createReadToolDefinition(cwd: string, options?: ReadToolOptions): ToolDefinition;
87
+ /** Create the legacy read tool. */
88
+ export declare function createReadTool(cwd: string, options?: ReadToolOptions): ToolDefinition;
89
+ /** Create the legacy bash tool definition. */
90
+ export declare function createBashToolDefinition(cwd: string, options?: BashToolOptions): ToolDefinition;
91
+ /** Create the legacy bash tool. */
92
+ export declare function createBashTool(cwd: string, options?: BashToolOptions): ToolDefinition;
93
+ /** Create the legacy grep tool definition. */
94
+ export declare function createGrepToolDefinition(cwd: string, options?: GrepToolOptions): ToolDefinition;
95
+ /** Create the legacy grep tool. */
96
+ export declare function createGrepTool(cwd: string, options?: GrepToolOptions): ToolDefinition;
97
+ /** Create the legacy find tool definition. */
98
+ export declare function createFindToolDefinition(cwd: string, options?: FindToolOptions): ToolDefinition;
99
+ /** Create the legacy find tool. */
100
+ export declare function createFindTool(cwd: string, options?: FindToolOptions): ToolDefinition;
101
+ /** Create the legacy ls tool definition. */
102
+ export declare function createLsToolDefinition(cwd: string, options?: LsToolOptions): ToolDefinition;
103
+ /** Create the legacy ls tool. */
104
+ export declare function createLsTool(cwd: string, options?: LsToolOptions): ToolDefinition;
105
+ /** Create legacy read, bash, edit, and write tools. */
25
106
  export declare function createCodingTools(cwd: string): ToolDefinition[];
107
+ /** Create legacy read, grep, find, and ls tools. */
108
+ export declare function createReadOnlyTools(cwd: string): ToolDefinition[];
26
109
  export declare const SettingsManager: {
27
110
  readonly create: (cwd: string, agentDir?: string) => Promise<Settings>;
28
111
  readonly inMemory: () => Settings;
29
112
  };
30
113
  export * from "../index";
31
- export { Type };
114
+ export { formatBytes as formatSize } from "../tools/render-utils";
115
+ export { Type } from "./typebox";
@@ -93,4 +93,5 @@ export interface ParsedSkillInvocation {
93
93
  * meant as skill invocations.
94
94
  */
95
95
  export declare function parseSkillInvocation(text: string): ParsedSkillInvocation | undefined;
96
- export declare function buildSkillPromptMessage(skill: Pick<Skill, "name" | "filePath">, args: string): Promise<BuiltSkillPromptMessage>;
96
+ export type SkillInvocationKind = "user" | "autoload";
97
+ export declare function buildSkillPromptMessage(skill: Pick<Skill, "name" | "filePath" | "baseDir">, args: string, invocation?: SkillInvocationKind): Promise<BuiltSkillPromptMessage>;
@@ -108,9 +108,21 @@ export declare class MnemopiSessionState {
108
108
  * e.g. `mnemopiBackend.clear` — pass `{ consolidate: false }` to skip the
109
109
  * extraction/sleep pass, since spending tokens on memories that will be
110
110
  * wiped on the next line is wasted work (PR #2327 review).
111
+ *
112
+ * `timeoutMs` caps how long the consolidate await blocks the caller
113
+ * (the user-visible `/quit` / `/exit` shutdown path passes this so
114
+ * dispose returns within a UX budget — issue #3641). When the cap is
115
+ * hit, dispose returns immediately and detaches the still-in-flight
116
+ * consolidate; the SQLite handles are closed in the background once
117
+ * the consolidate settles so writes never race a closed handle, and
118
+ * any pending embeddings are SIGKILL'd along with the embed worker
119
+ * (a tolerable loss — working memory rows are durable; only the
120
+ * episodic promotion / embedding for the LAST few turns is skipped,
121
+ * and `maybeRetainOnAgentEnd` has already retained earlier turns).
111
122
  */
112
123
  dispose(options?: {
113
124
  consolidate?: boolean;
125
+ timeoutMs?: number;
114
126
  }): Promise<void>;
115
127
  }
116
128
  export declare function getMnemopiScopedDbPaths(config: MnemopiBackendConfig): readonly string[];
@@ -6,16 +6,20 @@ import { IrcBus } from "../../irc/bus";
6
6
  import { AgentLifecycleManager } from "../../registry/agent-lifecycle";
7
7
  import { AgentRegistry } from "../../registry/agent-registry";
8
8
  import type { SessionObserverRegistry } from "../session-observer-registry";
9
+ /** Result of one host-backed transcript read for the Agent Hub viewer. */
10
+ export interface AgentHubRemoteTranscript {
11
+ text: string;
12
+ newSize: number;
13
+ /** Terminal read failure reported by the host; guests should surface it instead of retrying hot. */
14
+ error?: string;
15
+ }
9
16
  /** Guest-side proxy for hub actions executed on the collab host. */
10
17
  export interface AgentHubRemote {
11
18
  chat(id: string, text: string): void;
12
19
  kill(id: string): void;
13
20
  revive(id: string): void;
14
- /** Mirrors readFileIncremental: text from fromByte (complete JSONL lines), newSize = next fromByte base; null = unavailable. */
15
- readTranscript(id: string, fromByte: number): Promise<{
16
- text: string;
17
- newSize: number;
18
- } | null>;
21
+ /** Mirrors readFileIncremental: text from fromByte (complete JSONL lines), newSize = next fromByte base; null = temporarily unavailable. */
22
+ readTranscript(id: string, fromByte: number): Promise<AgentHubRemoteTranscript | null>;
19
23
  }
20
24
  export interface AgentHubDeps {
21
25
  /** Progress/status snapshot source (task lifecycle + progress channels). */
@@ -1,3 +1,3 @@
1
1
  import type { Usage } from "@oh-my-pi/pi-ai";
2
2
  import { Container } from "@oh-my-pi/pi-tui";
3
- export declare function createUsageRowBlock(usage: Usage): Container;
3
+ export declare function createUsageRowBlock(usage: Usage, durationMs?: number, ttftMs?: number): Container;
@@ -48,7 +48,6 @@ export declare class CommandController {
48
48
  * `images` strips image blocks. Rebuilds the chat and reports counts.
49
49
  */
50
50
  handleShakeCommand(mode: ShakeMode): Promise<void>;
51
- handleSkillCommand(skillPath: string, args: string): Promise<void>;
52
51
  executeCompaction(customInstructionsOrOptions?: string | CompactOptions, isAuto?: boolean, beforeFlush?: (outcome: CompactionOutcome) => void | Promise<void>, mode?: CompactMode): Promise<CompactionOutcome>;
53
52
  handleHandoffCommand(customInstructions?: string): Promise<void>;
54
53
  }
@@ -26,6 +26,12 @@ export declare class ExtensionUiController {
26
26
  * Set hook status text in the footer.
27
27
  */
28
28
  setHookStatus(key: string, text: string | undefined): void;
29
+ showCollabAwareSelector(title: string, options: ExtensionUISelectItem[], dialogOptions?: InteractiveSelectorDialogOptions, extra?: {
30
+ slider?: HookSelectorSlider;
31
+ }): Promise<string | undefined>;
32
+ showCollabAwareEditor(title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
33
+ promptStyle?: boolean;
34
+ }): Promise<string | undefined>;
29
35
  /**
30
36
  * Show a selector for hooks.
31
37
  */
@@ -4,14 +4,30 @@ export declare const STREAMING_REVEAL_FRAME_MS: number;
4
4
  export declare const MIN_STEP = 3;
5
5
  export declare const CATCHUP_FRAMES = 8;
6
6
  type StreamingRevealComponent = Pick<AssistantMessageComponent, "updateContent">;
7
+ type GraphemeSlicer = (index: number, text: string, units: number) => string;
7
8
  type StreamingRevealControllerOptions = {
8
9
  getSmoothStreaming(): boolean;
9
10
  getHideThinkingBlock(): boolean;
10
11
  getProseOnlyThinking(): boolean;
11
12
  requestRender(): void;
12
13
  };
14
+ /** Memoizes per-block grapheme counts across reveal ticks. Streaming blocks only
15
+ * grow by appending, and an append can only alter the final grapheme cluster of
16
+ * the previous text, so only the suffix from that cluster needs re-segmenting. */
17
+ export declare class BlockUnitCounter {
18
+ #private;
19
+ count(index: number, text: string): number;
20
+ reset(): void;
21
+ /** Slice `text` to its first `units` graphemes. Memoized across reveal ticks:
22
+ * streaming blocks grow only by appending and the reveal target advances
23
+ * monotonically, so a previously sliced prefix is reused and only the suffix
24
+ * from the boundary cluster is re-segmented. Only an exact (text, units) hit
25
+ * skips segmentation entirely — an append can extend the boundary cluster, so
26
+ * the incremental path still re-segments from that cluster's start. */
27
+ slice(index: number, text: string, units: number): string;
28
+ }
13
29
  export declare function visibleUnits(message: AssistantMessage, hideThinking: boolean, proseOnly?: boolean): number;
14
- export declare function buildDisplayMessage(target: AssistantMessage, revealed: number, hideThinking: boolean, proseOnly?: boolean, countOf?: (index: number, text: string) => number): AssistantMessage;
30
+ export declare function buildDisplayMessage(target: AssistantMessage, revealed: number, hideThinking: boolean, proseOnly?: boolean, countOf?: (index: number, text: string) => number, sliceOf?: GraphemeSlicer): AssistantMessage;
15
31
  export declare function nextStep(backlog: number): number;
16
32
  export declare class StreamingRevealController {
17
33
  #private;