@oh-my-pi/pi-coding-agent 16.3.0 → 16.3.3

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 (163) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/dist/cli.js +3855 -3798
  3. package/dist/types/cli/update-cli.d.ts +1 -0
  4. package/dist/types/cli/update-cli.test.d.ts +1 -0
  5. package/dist/types/commands/update.d.ts +5 -0
  6. package/dist/types/config/config-file.d.ts +1 -1
  7. package/dist/types/config/settings-schema.d.ts +20 -0
  8. package/dist/types/dap/client.d.ts +9 -1
  9. package/dist/types/discovery/helpers.d.ts +2 -0
  10. package/dist/types/edit/file-snapshot-store.d.ts +9 -1
  11. package/dist/types/edit/hashline/execute.d.ts +1 -1
  12. package/dist/types/edit/hashline/params.d.ts +3 -6
  13. package/dist/types/edit/renderer.d.ts +1 -0
  14. package/dist/types/extensibility/plugins/parser.d.ts +2 -1
  15. package/dist/types/hindsight/client.d.ts +15 -11
  16. package/dist/types/hindsight/client.test.d.ts +1 -0
  17. package/dist/types/irc/bus.d.ts +5 -4
  18. package/dist/types/mcp/smithery-registry.d.ts +1 -0
  19. package/dist/types/mcp/smithery-registry.test.d.ts +1 -0
  20. package/dist/types/modes/components/advisor-message.d.ts +4 -2
  21. package/dist/types/modes/components/tool-execution.d.ts +9 -6
  22. package/dist/types/modes/components/transcript-container.d.ts +1 -0
  23. package/dist/types/modes/theme/theme.d.ts +1 -1
  24. package/dist/types/session/agent-session.d.ts +13 -13
  25. package/dist/types/session/indexed-session-storage.d.ts +2 -2
  26. package/dist/types/session/session-storage.d.ts +31 -3
  27. package/dist/types/ssh/__tests__/connection-manager-timeout.test.d.ts +1 -0
  28. package/dist/types/ssh/__tests__/sshfs-mount.test.d.ts +1 -0
  29. package/dist/types/ssh/connection-manager.d.ts +19 -0
  30. package/dist/types/ssh/sshfs-mount.d.ts +10 -1
  31. package/dist/types/subprocess/worker-client.d.ts +20 -6
  32. package/dist/types/task/discovery.d.ts +5 -2
  33. package/dist/types/task/renderer.d.ts +1 -0
  34. package/dist/types/tools/ast-grep.d.ts +4 -2
  35. package/dist/types/tools/bash.d.ts +27 -0
  36. package/dist/types/tools/browser/render.d.ts +2 -0
  37. package/dist/types/tools/debug.d.ts +1 -0
  38. package/dist/types/tools/eval-render.d.ts +2 -0
  39. package/dist/types/tools/glob.d.ts +4 -2
  40. package/dist/types/tools/grep.d.ts +4 -3
  41. package/dist/types/tools/path-utils.d.ts +7 -0
  42. package/dist/types/tools/renderers.d.ts +24 -0
  43. package/dist/types/tools/ssh.d.ts +4 -1
  44. package/dist/types/tts/index.d.ts +2 -0
  45. package/dist/types/tts/speakable.d.ts +47 -0
  46. package/dist/types/tts/speech-enhancer.d.ts +46 -0
  47. package/dist/types/tts/streaming-player.d.ts +1 -2
  48. package/dist/types/tts/tts-client.d.ts +11 -10
  49. package/dist/types/tts/tts-protocol.d.ts +7 -0
  50. package/dist/types/tts/vocalizer.d.ts +15 -8
  51. package/dist/types/utils/fetch-timeout.d.ts +4 -0
  52. package/dist/types/utils/git.d.ts +2 -0
  53. package/dist/types/web/search/providers/base.d.ts +1 -0
  54. package/dist/types/web/search/providers/gemini.d.ts +1 -0
  55. package/package.json +12 -12
  56. package/scripts/generate-legacy-pi-bundled-registry.ts +8 -2
  57. package/src/advisor/__tests__/advisor.test.ts +1 -1
  58. package/src/cli/gallery-fixtures/fs.ts +2 -2
  59. package/src/cli/gallery-fixtures/search.ts +2 -2
  60. package/src/cli/models-cli.ts +19 -0
  61. package/src/cli/update-cli.test.ts +28 -0
  62. package/src/cli/update-cli.ts +35 -8
  63. package/src/cli.ts +27 -5
  64. package/src/commands/update.ts +8 -2
  65. package/src/config/config-file.ts +6 -6
  66. package/src/config/model-resolver.ts +31 -10
  67. package/src/config/settings-schema.ts +21 -0
  68. package/src/cursor.ts +1 -1
  69. package/src/dap/client.ts +134 -36
  70. package/src/discovery/helpers.ts +8 -0
  71. package/src/edit/file-snapshot-store.ts +12 -1
  72. package/src/edit/hashline/diff.ts +4 -13
  73. package/src/edit/hashline/execute.ts +1 -1
  74. package/src/edit/hashline/params.ts +5 -12
  75. package/src/edit/renderer.ts +4 -2
  76. package/src/edit/streaming.ts +15 -5
  77. package/src/export/html/tool-views.generated.js +34 -34
  78. package/src/extensibility/custom-tools/loader.ts +3 -3
  79. package/src/extensibility/extensions/loader.ts +10 -3
  80. package/src/extensibility/legacy-pi-coding-agent-shim.ts +2 -2
  81. package/src/extensibility/plugins/installer.ts +12 -3
  82. package/src/extensibility/plugins/legacy-pi-compat.ts +87 -11
  83. package/src/extensibility/plugins/loader.ts +30 -1
  84. package/src/extensibility/plugins/manager.ts +32 -8
  85. package/src/extensibility/plugins/parser.ts +7 -5
  86. package/src/extensibility/tool-event-input.ts +1 -1
  87. package/src/hindsight/client.test.ts +33 -0
  88. package/src/hindsight/client.ts +42 -22
  89. package/src/internal-urls/docs-index.generated.txt +1 -1
  90. package/src/irc/bus.ts +5 -4
  91. package/src/main.ts +7 -1
  92. package/src/mcp/oauth-flow.ts +93 -4
  93. package/src/mcp/smithery-auth.ts +3 -0
  94. package/src/mcp/smithery-connect.ts +9 -0
  95. package/src/mcp/smithery-registry.test.ts +51 -0
  96. package/src/mcp/smithery-registry.ts +27 -4
  97. package/src/modes/components/__tests__/move-overlay.test.ts +72 -1
  98. package/src/modes/components/advisor-message.ts +13 -10
  99. package/src/modes/components/assistant-message.ts +1 -1
  100. package/src/modes/components/move-overlay.ts +35 -23
  101. package/src/modes/components/status-line/component.ts +11 -4
  102. package/src/modes/components/tool-execution.ts +119 -20
  103. package/src/modes/components/transcript-container.ts +26 -0
  104. package/src/modes/components/tree-selector.ts +10 -3
  105. package/src/modes/controllers/event-controller.ts +23 -3
  106. package/src/modes/controllers/tool-args-reveal.ts +1 -1
  107. package/src/modes/interactive-mode.ts +1 -0
  108. package/src/modes/rpc/rpc-client.ts +29 -16
  109. package/src/modes/theme/shimmer.ts +49 -15
  110. package/src/modes/theme/theme.ts +7 -0
  111. package/src/prompts/goals/goal-mode-context.md +4 -0
  112. package/src/prompts/goals/goal-todo-context.md +10 -2
  113. package/src/prompts/system/speech-rewrite.md +15 -0
  114. package/src/prompts/system/tiny-title-system.md +1 -1
  115. package/src/prompts/system/title-system-marker.md +2 -1
  116. package/src/prompts/system/title-system.md +2 -1
  117. package/src/prompts/tools/ast-grep.md +3 -3
  118. package/src/prompts/tools/glob.md +1 -1
  119. package/src/prompts/tools/grep.md +1 -1
  120. package/src/sdk.ts +8 -5
  121. package/src/session/agent-session.ts +329 -79
  122. package/src/session/indexed-session-storage.ts +40 -3
  123. package/src/session/session-history-format.ts +6 -2
  124. package/src/session/session-manager.ts +83 -14
  125. package/src/session/session-storage.ts +112 -26
  126. package/src/slash-commands/helpers/usage-report.ts +6 -1
  127. package/src/ssh/__tests__/connection-manager-timeout.test.ts +61 -0
  128. package/src/ssh/__tests__/sshfs-mount.test.ts +13 -0
  129. package/src/ssh/connection-manager.ts +44 -11
  130. package/src/ssh/sshfs-mount.ts +27 -4
  131. package/src/subprocess/worker-client.ts +161 -10
  132. package/src/task/discovery.ts +25 -2
  133. package/src/task/executor.ts +24 -4
  134. package/src/task/render.ts +26 -12
  135. package/src/task/renderer.ts +1 -0
  136. package/src/task/worktree.ts +144 -16
  137. package/src/tiny/text.ts +109 -17
  138. package/src/tools/ast-grep.ts +20 -17
  139. package/src/tools/bash.ts +46 -9
  140. package/src/tools/browser/render.ts +2 -0
  141. package/src/tools/debug.ts +1 -0
  142. package/src/tools/eval-render.ts +5 -2
  143. package/src/tools/gh-renderer.ts +3 -0
  144. package/src/tools/glob.ts +24 -20
  145. package/src/tools/grep.ts +39 -37
  146. package/src/tools/path-utils.ts +55 -10
  147. package/src/tools/read.ts +23 -6
  148. package/src/tools/renderers.ts +24 -0
  149. package/src/tools/ssh.ts +25 -7
  150. package/src/tts/index.ts +2 -0
  151. package/src/tts/speakable.ts +382 -0
  152. package/src/tts/speech-enhancer.ts +204 -0
  153. package/src/tts/streaming-player.ts +71 -16
  154. package/src/tts/tts-client.ts +11 -10
  155. package/src/tts/tts-protocol.ts +14 -5
  156. package/src/tts/tts-worker.ts +52 -49
  157. package/src/tts/vocalizer.ts +277 -46
  158. package/src/utils/clipboard.ts +49 -12
  159. package/src/utils/fetch-timeout.ts +10 -0
  160. package/src/utils/git.ts +8 -0
  161. package/src/web/search/index.ts +8 -0
  162. package/src/web/search/providers/base.ts +1 -0
  163. package/src/web/search/providers/gemini.ts +23 -6
@@ -19,6 +19,7 @@ export interface BinaryReplacementOptions {
19
19
  export declare function parseUpdateArgs(args: string[]): {
20
20
  force: boolean;
21
21
  check: boolean;
22
+ plugins: boolean;
22
23
  } | undefined;
23
24
  type UpdateMethod = "brew" | "mise" | "bun" | "binary";
24
25
  interface UpdateMethodResolutionOptions {
@@ -0,0 +1 @@
1
+ export {};
@@ -15,6 +15,11 @@ export default class Update extends Command {
15
15
  description: string;
16
16
  default: boolean;
17
17
  };
18
+ plugins: import("@oh-my-pi/pi-utils/cli").FlagDescriptor<"boolean"> & {
19
+ char: string;
20
+ description: string;
21
+ default: boolean;
22
+ };
18
23
  };
19
24
  run(): Promise<void>;
20
25
  }
@@ -1,4 +1,4 @@
1
- import type { Type } from "arktype";
1
+ import { type Type } from "arktype";
2
2
  /** Minimal subset of the AJV ConfigSchemaError shape this module actually relies on. */
3
3
  interface ConfigSchemaError {
4
4
  instancePath: string;
@@ -4586,6 +4586,16 @@ export declare const SETTINGS_SCHEMA: {
4586
4586
  readonly description: "Providers that web_search should never use, even as fallbacks";
4587
4587
  };
4588
4588
  };
4589
+ readonly "providers.webSearchGeminiModel": {
4590
+ readonly type: "string";
4591
+ readonly default: undefined;
4592
+ readonly ui: {
4593
+ readonly tab: "providers";
4594
+ readonly group: "Services";
4595
+ readonly label: "Gemini web_search model";
4596
+ readonly description: "Model ID for Gemini Google Search grounding. Defaults to gemini-2.5-flash.";
4597
+ };
4598
+ };
4589
4599
  readonly "providers.antigravityEndpoint": {
4590
4600
  readonly type: "enum";
4591
4601
  readonly values: readonly ["auto", "production", "sandbox"];
@@ -4752,6 +4762,16 @@ export declare const SETTINGS_SCHEMA: {
4752
4762
  }];
4753
4763
  };
4754
4764
  };
4765
+ readonly "speech.enhanced": {
4766
+ readonly type: "boolean";
4767
+ readonly default: false;
4768
+ readonly ui: {
4769
+ readonly tab: "providers";
4770
+ readonly group: "Services";
4771
+ readonly label: "Enhanced Speech Rewriting";
4772
+ readonly description: "Rewrite assistant output into natural spoken prose with the tiny/smol model before synthesis (describes code, drops links and markdown). Falls back to mechanical cleanup on failure";
4773
+ };
4774
+ };
4755
4775
  readonly "speech.voice": {
4756
4776
  readonly type: "enum";
4757
4777
  readonly values: readonly string[];
@@ -2,6 +2,14 @@ import type { DapCapabilities, DapClientState, DapEventMessage, DapInitializeArg
2
2
  interface DapSpawnOptions {
3
3
  adapter: DapResolvedAdapter;
4
4
  cwd: string;
5
+ /**
6
+ * Cap on how long the socket-mode helpers wait for the adapter to open its
7
+ * socket (unix) or dial back into our listener (TCP). Exposed for tests;
8
+ * production callers rely on the default.
9
+ *
10
+ * @internal
11
+ */
12
+ socketReadyTimeoutMs?: number;
5
13
  }
6
14
  /** Minimal write interface shared by Bun.FileSink and Bun TCP sockets. */
7
15
  interface DapWriteSink {
@@ -22,7 +30,7 @@ export declare class DapClient {
22
30
  end(): void;
23
31
  };
24
32
  });
25
- static spawn({ adapter, cwd }: DapSpawnOptions): Promise<DapClient>;
33
+ static spawn({ adapter, cwd, socketReadyTimeoutMs }: DapSpawnOptions): Promise<DapClient>;
26
34
  get capabilities(): DapCapabilities | undefined;
27
35
  get lastActivity(): number;
28
36
  isAlive(): boolean;
@@ -236,6 +236,8 @@ export declare function resolveActiveProjectRegistryPath(cwd: string): Promise<s
236
236
  * never alias as the project registry.
237
237
  */
238
238
  export declare function resolveOrDefaultProjectRegistryPath(cwd: string): Promise<string | undefined>;
239
+ /** Register a process-global plugin cache invalidator called whenever plugin roots are cleared. */
240
+ export declare function registerPluginCacheInvalidator(invalidator: () => void): void;
239
241
  /**
240
242
  * List all installed Claude Code plugin roots from the plugin cache.
241
243
  * Reads ~/.claude/plugins/installed_plugins.json and ~/.omp/plugins/installed_plugins.json,
@@ -59,6 +59,14 @@ export declare function recordSeenLines(session: FileSnapshotStoreOwner, absolut
59
59
  * can reject edits anchored on lines the model never saw. Best-effort: a no-op
60
60
  * when the body has no numbered rows or the snapshot already aged out. `tag`
61
61
  * must be the tag returned when this exact content was recorded.
62
+ *
63
+ * `excludedLines` prunes 1-indexed line numbers whose displayed text was
64
+ * column-truncated (or otherwise not shown in full). A column-clipped row
65
+ * still carries a `NN:` prefix — the parser sees the number and would
66
+ * otherwise mark the line "seen" even though only its prefix ever reached
67
+ * the model. Producers that apply per-line column truncation MUST supply
68
+ * the clipped line set so the patcher's seen-line guard keeps rejecting
69
+ * edits against those lines until a full-width read of them occurs.
62
70
  */
63
- export declare function recordSeenLinesFromBody(session: FileSnapshotStoreOwner, absolutePath: string, tag: string, body: string): void;
71
+ export declare function recordSeenLinesFromBody(session: FileSnapshotStoreOwner, absolutePath: string, tag: string, body: string, excludedLines?: ReadonlySet<number>): void;
64
72
  export {};
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Coding-agent runner that drives the hashline {@link Patcher} on behalf of
3
- * the `edit` tool. Converts a `{input}` tool-call payload into a
3
+ * the `edit` tool. Converts an `{input}` tool-call payload into a
4
4
  * fully-applied patch, wraps the result in the agent's
5
5
  * {@link AgentToolResult} shape, and attaches LSP diagnostics + `outputMeta`
6
6
  * for the renderer.
@@ -1,7 +1,4 @@
1
- export declare const hashlineEditParamsSchema: import("arktype/internal/variants/object.ts").ObjectType<(In: {
2
- input?: string | undefined;
3
- _input?: string | undefined;
4
- }) => import("arktype/internal/attributes.ts").To<{
1
+ export declare const hashlineEditParamsSchema: import("arktype/internal/variants/object.ts").ObjectType<{
5
2
  input: string;
6
- }>, {}>;
7
- export type HashlineParams = Parameters<typeof hashlineEditParamsSchema.assert>[0];
3
+ }, {}>;
4
+ export type HashlineParams = typeof hashlineEditParamsSchema.infer;
@@ -67,6 +67,7 @@ interface EditRenderArgs {
67
67
  newText?: string;
68
68
  patch?: string;
69
69
  input?: string;
70
+ _input?: string;
70
71
  all?: boolean;
71
72
  op?: Operation;
72
73
  rename?: string;
@@ -41,12 +41,13 @@ export declare function parsePluginSpec(spec: string): ParsedPluginSpec;
41
41
  */
42
42
  export declare function formatPluginSpec(spec: ParsedPluginSpec): string;
43
43
  /**
44
- * Extract the base package name without version specifier.
44
+ * Extract the dependency key from an npm package specifier.
45
45
  * Used for path lookups after npm install.
46
46
  *
47
47
  * @example
48
48
  * extractPackageName("lodash@4.17.21") // "lodash"
49
49
  * extractPackageName("@scope/pkg@1.0.0") // "@scope/pkg"
50
50
  * extractPackageName("@scope/pkg") // "@scope/pkg"
51
+ * extractPackageName("npm:lodash") // "lodash"
51
52
  */
52
53
  export declare function extractPackageName(specifier: string): string;
@@ -17,6 +17,10 @@ export interface HindsightApiOptions {
17
17
  apiKey?: string;
18
18
  userAgent?: string;
19
19
  }
20
+ /** Caller cancellation shared by Hindsight request option bags. */
21
+ export interface HindsightRequestOptions {
22
+ signal?: AbortSignal;
23
+ }
20
24
  export interface RecallResult {
21
25
  id?: string;
22
26
  text: string;
@@ -61,7 +65,7 @@ export interface MemoryItemInput {
61
65
  strategy?: string;
62
66
  updateMode?: UpdateMode;
63
67
  }
64
- export interface RetainOptions {
68
+ export interface RetainOptions extends HindsightRequestOptions {
65
69
  timestamp?: Date | string;
66
70
  context?: string;
67
71
  metadata?: Record<string, string>;
@@ -70,42 +74,42 @@ export interface RetainOptions {
70
74
  tags?: string[];
71
75
  updateMode?: UpdateMode;
72
76
  }
73
- export interface RetainBatchOptions {
77
+ export interface RetainBatchOptions extends HindsightRequestOptions {
74
78
  /** Document id applied to every item that doesn't carry its own. */
75
79
  documentId?: string;
76
80
  /** Tags attached to the resulting document(s), not individual items. */
77
81
  documentTags?: string[];
78
82
  async?: boolean;
79
83
  }
80
- export interface RecallOptions {
84
+ export interface RecallOptions extends HindsightRequestOptions {
81
85
  types?: string[];
82
86
  maxTokens?: number;
83
87
  budget?: Budget;
84
88
  tags?: string[];
85
89
  tagsMatch?: TagsMatch;
86
90
  }
87
- export interface ReflectOptions {
91
+ export interface ReflectOptions extends HindsightRequestOptions {
88
92
  context?: string;
89
93
  budget?: Budget;
90
94
  tags?: string[];
91
95
  tagsMatch?: TagsMatch;
92
96
  }
93
- export interface CreateBankOptions {
97
+ export interface CreateBankOptions extends HindsightRequestOptions {
94
98
  reflectMission?: string;
95
99
  retainMission?: string;
96
100
  }
97
- export interface ListMemoriesOptions {
101
+ export interface ListMemoriesOptions extends HindsightRequestOptions {
98
102
  limit?: number;
99
103
  offset?: number;
100
104
  type?: string;
101
105
  q?: string;
102
106
  consolidationState?: ConsolidationState;
103
107
  }
104
- export interface ListDocumentsOptions {
108
+ export interface ListDocumentsOptions extends HindsightRequestOptions {
105
109
  limit?: number;
106
110
  offset?: number;
107
111
  }
108
- export interface UpdateDocumentOptions {
112
+ export interface UpdateDocumentOptions extends HindsightRequestOptions {
109
113
  tags?: string[];
110
114
  }
111
115
  export type MentalModelDetail = "metadata" | "content" | "full";
@@ -137,7 +141,7 @@ export interface MentalModelHistoryEntry {
137
141
  changed_at: string;
138
142
  [key: string]: unknown;
139
143
  }
140
- export interface CreateMentalModelOptions {
144
+ export interface CreateMentalModelOptions extends HindsightRequestOptions {
141
145
  id?: string;
142
146
  tags?: string[];
143
147
  maxTokens?: number;
@@ -151,10 +155,10 @@ export interface RefreshMentalModelResponse {
151
155
  operation_id?: string;
152
156
  [key: string]: unknown;
153
157
  }
154
- export interface ListMentalModelsOptions {
158
+ export interface ListMentalModelsOptions extends HindsightRequestOptions {
155
159
  detail?: MentalModelDetail;
156
160
  }
157
- export interface GetMentalModelOptions {
161
+ export interface GetMentalModelOptions extends HindsightRequestOptions {
158
162
  detail?: MentalModelDetail;
159
163
  }
160
164
  export declare class HindsightError extends Error {
@@ -0,0 +1 @@
1
+ export {};
@@ -8,10 +8,11 @@
8
8
  * agents receive the message as a non-interrupting aside at the next step
9
9
  * boundary (see AgentSession.deliverIrcMessage). Replies are real turns by
10
10
  * the recipient, observed via `wait` — with one exception: when the sender
11
- * awaits a reply and the recipient is mid-turn with async execution
12
- * disabled, the recipient session generates an ephemeral side-channel
13
- * auto-reply (it may be blocked in a synchronous task spawn whose batch
14
- * includes the sender, so a real turn could never happen in time).
11
+ * awaits a reply and the recipient cannot run a real reply turn in time
12
+ * (mid-turn with async execution disabled possibly blocked in a
13
+ * synchronous task spawn whose batch includes the sender or idle in plan
14
+ * mode, where autonomous wake turns are suppressed), the recipient session
15
+ * generates an ephemeral side-channel auto-reply.
15
16
  */
16
17
  import { AgentLifecycleManager } from "../registry/agent-lifecycle";
17
18
  import { AgentRegistry } from "../registry/agent-registry";
@@ -41,6 +41,7 @@ export interface SmitherySearchOptions {
41
41
  limit?: number;
42
42
  apiKey?: string;
43
43
  includeSemantic?: boolean;
44
+ signal?: AbortSignal;
44
45
  }
45
46
  export declare class SmitheryRegistryError extends Error {
46
47
  status: number;
@@ -0,0 +1 @@
1
+ export {};
@@ -3,7 +3,9 @@ import type { AdvisorMessageDetails } from "../../advisor";
3
3
  import type { Theme } from "../theme/theme";
4
4
  /**
5
5
  * Display-only transcript card for advisor notes injected into the primary
6
- * session. Mirrors the IRC card's glyph + quote-border conventions so passive
7
- * advice reads as a distinct, non-interrupting aside rather than a user turn.
6
+ * session. Styled as a distinct voice so notes never blend into thinking
7
+ * output (whose `thinkingText` color equals `toolOutput` in most themes):
8
+ * a bold `customMessageLabel` header tag (skill-card convention), a heavy
9
+ * rail tinted per-note severity, and the note body on the default text color.
8
10
  */
9
11
  export declare function createAdvisorMessageCard(details: AdvisorMessageDetails | undefined, getExpanded: () => boolean, uiTheme: Theme): Component;
@@ -33,12 +33,14 @@ export interface ToolExecutionHandle {
33
33
  setArgsComplete(toolCallId?: string): void;
34
34
  setExpanded(expanded: boolean): void;
35
35
  }
36
- /** Drive pending-tool redraws at 30fps for live tool headers and displaceable
37
- * poll blocks. The TUI throttles at the same cadence, and static frames diff to
38
- * a no-op redraw at ~zero cost. */
39
- export declare const SPINNER_RENDER_INTERVAL_MS: number;
40
- /** Advance the spinner glyph at its classic ~12.5fps step, decoupled from the
41
- * render cadence (mirrors `Loader`). */
36
+ /** Redraw live tool blocks at the spinner's glyph-advance rate. Rendering more
37
+ * often produced identical frames the previous 30fps cadence emitted ~2.4
38
+ * paints per glyph step, and although the terminal I/O layer dedupes those, the
39
+ * compose pipeline still ran end-to-end per frame (issue #4353). Matching the
40
+ * render tick to the glyph tick halves the paints during tool execution with no
41
+ * visible change. */
42
+ export declare const SPINNER_RENDER_INTERVAL_MS = 80;
43
+ /** Advance the spinner glyph at its classic ~12.5fps step (mirrors `Loader`). */
42
44
  export declare const SPINNER_GLYPH_ADVANCE_MS = 80;
43
45
  /** Phase-locked spinner glyph index shared by every live tool block so parallel
44
46
  * spinners advance in lockstep instead of each tracking its own start time. */
@@ -121,4 +123,5 @@ export declare class ToolExecutionComponent extends Container implements NativeS
121
123
  setExpanded(expanded: boolean): void;
122
124
  setShowImages(show: boolean): void;
123
125
  invalidate(): void;
126
+ render(width: number): readonly string[];
124
127
  }
@@ -31,6 +31,7 @@ export declare class TranscriptContainer extends Container implements NativeScro
31
31
  getNativeScrollbackLiveRegionStart(): number | undefined;
32
32
  getNativeScrollbackCommitSafeEnd(): number | undefined;
33
33
  getNativeScrollbackSnapshotSafeEnd(): number | undefined;
34
+ getNativeScrollbackOfferSafeEnd(): number | undefined;
34
35
  /**
35
36
  * Whether `component` sits below a still-mutating block — i.e. inside the
36
37
  * live region, where its rows cannot have been committed to native
@@ -6,7 +6,7 @@ export type SymbolPreset = "unicode" | "nerd" | "ascii";
6
6
  /**
7
7
  * All available symbol keys organized by category.
8
8
  */
9
- export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "status.done" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.worktree" | "icon.search" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.ghost" | "icon.agents" | "icon.job" | "icon.cache" | "icon.cacheMiss" | "icon.input" | "icon.output" | "icon.throughput" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "icon.camera" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "radio.selected" | "radio.unselected" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.julia" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.files" | "tab.shell" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers" | "tool.write" | "tool.edit" | "tool.bash" | "tool.ssh" | "tool.lsp" | "tool.gh" | "tool.webSearch" | "tool.exa" | "tool.browser" | "tool.eval" | "tool.debug" | "tool.mcp" | "tool.job" | "tool.task" | "tool.todo" | "tool.memory" | "tool.ask" | "tool.resolve" | "tool.review" | "tool.inspectImage" | "tool.goal" | "tool.irc" | "tool.delete" | "tool.move";
9
+ export type SymbolKey = "status.success" | "status.error" | "status.warning" | "status.info" | "status.pending" | "status.disabled" | "status.enabled" | "status.running" | "status.shadowed" | "status.aborted" | "status.done" | "nav.cursor" | "nav.selected" | "nav.expand" | "nav.collapse" | "nav.back" | "tree.branch" | "tree.last" | "tree.vertical" | "tree.horizontal" | "tree.hook" | "boxRound.topLeft" | "boxRound.topRight" | "boxRound.bottomLeft" | "boxRound.bottomRight" | "boxRound.horizontal" | "boxRound.vertical" | "boxSharp.topLeft" | "boxSharp.topRight" | "boxSharp.bottomLeft" | "boxSharp.bottomRight" | "boxSharp.horizontal" | "boxSharp.vertical" | "boxSharp.cross" | "boxSharp.teeDown" | "boxSharp.teeUp" | "boxSharp.teeRight" | "boxSharp.teeLeft" | "sep.powerline" | "sep.powerlineThin" | "sep.powerlineLeft" | "sep.powerlineRight" | "sep.powerlineThinLeft" | "sep.powerlineThinRight" | "sep.block" | "sep.space" | "sep.asciiLeft" | "sep.asciiRight" | "sep.dot" | "sep.slash" | "sep.pipe" | "icon.model" | "icon.plan" | "icon.goal" | "icon.pause" | "icon.loop" | "icon.folder" | "icon.worktree" | "icon.search" | "icon.scratchFolder" | "icon.file" | "icon.git" | "icon.branch" | "icon.pr" | "icon.tokens" | "icon.context" | "icon.cost" | "icon.time" | "icon.pi" | "icon.ghost" | "icon.agents" | "icon.job" | "icon.cache" | "icon.cacheMiss" | "icon.input" | "icon.output" | "icon.throughput" | "icon.host" | "icon.session" | "icon.package" | "icon.warning" | "icon.rewind" | "icon.auto" | "icon.fast" | "icon.extensionSkill" | "icon.extensionTool" | "icon.extensionSlashCommand" | "icon.extensionMcp" | "icon.extensionRule" | "icon.extensionHook" | "icon.extensionPrompt" | "icon.extensionContextFile" | "icon.extensionInstruction" | "icon.mic" | "icon.camera" | "thinking.minimal" | "thinking.low" | "thinking.medium" | "thinking.high" | "thinking.xhigh" | "thinking.autoPending" | "checkbox.checked" | "checkbox.unchecked" | "radio.selected" | "radio.unselected" | "format.bullet" | "format.dash" | "format.bracketLeft" | "format.bracketRight" | "md.quoteBorder" | "md.hrChar" | "md.bullet" | "md.colorSwatch" | "advisor.rail" | "lang.default" | "lang.typescript" | "lang.javascript" | "lang.python" | "lang.rust" | "lang.go" | "lang.java" | "lang.c" | "lang.cpp" | "lang.csharp" | "lang.ruby" | "lang.julia" | "lang.php" | "lang.swift" | "lang.kotlin" | "lang.shell" | "lang.html" | "lang.css" | "lang.json" | "lang.yaml" | "lang.markdown" | "lang.sql" | "lang.docker" | "lang.lua" | "lang.text" | "lang.env" | "lang.toml" | "lang.xml" | "lang.ini" | "lang.conf" | "lang.log" | "lang.csv" | "lang.tsv" | "lang.image" | "lang.pdf" | "lang.archive" | "lang.binary" | "tab.appearance" | "tab.model" | "tab.interaction" | "tab.context" | "tab.files" | "tab.shell" | "tab.tools" | "tab.memory" | "tab.tasks" | "tab.providers" | "tool.write" | "tool.edit" | "tool.bash" | "tool.ssh" | "tool.lsp" | "tool.gh" | "tool.webSearch" | "tool.exa" | "tool.browser" | "tool.eval" | "tool.debug" | "tool.mcp" | "tool.job" | "tool.task" | "tool.todo" | "tool.memory" | "tool.ask" | "tool.resolve" | "tool.review" | "tool.inspectImage" | "tool.goal" | "tool.irc" | "tool.delete" | "tool.move";
10
10
  export type SpinnerType = "status" | "activity";
11
11
  export type ThemeColor = "accent" | "border" | "borderAccent" | "borderMuted" | "success" | "error" | "warning" | "muted" | "dim" | "text" | "thinkingText" | "userMessageText" | "customMessageText" | "customMessageLabel" | "toolTitle" | "toolOutput" | "mdHeading" | "mdLink" | "mdLinkUrl" | "mdCode" | "mdCodeBlock" | "mdCodeBlockBorder" | "mdQuote" | "mdQuoteBorder" | "mdHr" | "mdListBullet" | "toolDiffAdded" | "toolDiffRemoved" | "toolDiffContext" | "syntaxComment" | "syntaxKeyword" | "syntaxFunction" | "syntaxVariable" | "syntaxString" | "syntaxNumber" | "syntaxType" | "syntaxOperator" | "syntaxPunctuation" | "thinkingOff" | "thinkingMinimal" | "thinkingLow" | "thinkingMedium" | "thinkingHigh" | "thinkingXhigh" | "bashMode" | "pythonMode" | "statusLineSep" | "statusLineModel" | "statusLinePath" | "statusLineGitClean" | "statusLineGitDirty" | "statusLineContext" | "statusLineSpend" | "statusLineStaged" | "statusLineDirty" | "statusLineUntracked" | "statusLineOutput" | "statusLineCost" | "statusLineSubagents";
12
12
  /** Check if a string is a valid ThemeColor value */
@@ -882,12 +882,10 @@ export declare class AgentSession {
882
882
  /**
883
883
  * Set model directly.
884
884
  * Validates that a credential source is configured (synchronously, without
885
- * refreshing OAuth or running command-backed key programs). The active
886
- * session switches by default; when `currentContextTokens` is provided and
887
- * exceeds the refreshed candidate's context window, the live switch is
888
- * skipped while role persistence still runs. Returns whether the active
889
- * model actually switched, computed against the refreshed metadata so
890
- * dynamic providers (e.g. llama.cpp) honor their post-load contextWindow.
885
+ * refreshing OAuth or running command-backed key programs). Active switches
886
+ * always take effect; if the current transcript is too large for the target
887
+ * model, the next prompt's compaction/error path owns that recovery instead
888
+ * of leaving the session pinned to the old model.
891
889
  * @throws Error if no API key available for the model
892
890
  */
893
891
  setModel(model: Model, role?: string, options?: {
@@ -1163,18 +1161,20 @@ export declare class AgentSession {
1163
1161
  *
1164
1162
  * - mid-turn → queued on the aside channel and folded in at the next step
1165
1163
  * boundary (non-interrupting, like async-result deliveries) → "injected";
1164
+ * - idle in plan mode → appended into context without waking an autonomous
1165
+ * turn (convergence stays user-driven) → "injected";
1166
1166
  * - idle → starts a real turn with the message so the recipient wakes
1167
1167
  * → "woken".
1168
1168
  *
1169
1169
  * Never blocks on the recipient's turn: the wake turn is fire-and-forget.
1170
1170
  *
1171
- * When the sender expects a reply (`send await:true`) and this session is
1172
- * mid-turn with async execution disabled, the next step boundary may be
1173
- * gated on the sender's own batch finishing (blocking task spawns), so a
1174
- * real reply turn can never happen in time. In that case an ephemeral
1175
- * side-channel auto-reply is generated from the current context (the old
1176
- * `respondAsBackground` path) and sent back over the bus on this agent's
1177
- * behalf.
1171
+ * When the sender expects a reply (`send await:true`) and this session
1172
+ * cannot produce a real reply turn in time mid-turn with async execution
1173
+ * disabled (the next step boundary may be gated on the sender's own batch
1174
+ * finishing), or idle in plan mode (wake turns are suppressed) an
1175
+ * ephemeral side-channel auto-reply is generated from the current context
1176
+ * (the old `respondAsBackground` path) and sent back over the bus on this
1177
+ * agent's behalf.
1178
1178
  */
1179
1179
  deliverIrcMessage(msg: IrcMessage, opts?: {
1180
1180
  expectsReply?: boolean;
@@ -1,4 +1,4 @@
1
- import type { SessionStorage, SessionStorageStat, SessionStorageWriter } from "./session-storage";
1
+ import type { SessionStorage, SessionStorageStat, SessionStorageWriter, WriteTextAtomicOptions } from "./session-storage";
2
2
  import { type SessionTitleUpdate } from "./session-title-slot";
3
3
  export interface SessionStorageIndexEntry {
4
4
  path: string;
@@ -36,7 +36,7 @@ export declare class IndexedSessionStorage implements SessionStorage {
36
36
  readText(path: string): Promise<string>;
37
37
  readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
38
38
  writeText(path: string, content: string): Promise<void>;
39
- writeTextAtomic(path: string, content: string): Promise<void>;
39
+ writeTextAtomic(path: string, content: string, options?: WriteTextAtomicOptions): Promise<void>;
40
40
  rename(src: string, dst: string): Promise<void>;
41
41
  unlink(path: string): Promise<void>;
42
42
  deleteSessionWithArtifacts(sessionPath: string): Promise<void>;
@@ -19,6 +19,17 @@ export interface SessionStorageWriter {
19
19
  close(): Promise<void>;
20
20
  getError(): Error | undefined;
21
21
  }
22
+ /**
23
+ * Optional guard applied by {@link SessionStorage.writeTextAtomic}. The
24
+ * backend MUST call `commitGuard()` synchronously immediately before it makes
25
+ * the staged content visible at `path`. If it returns `false`, the staged
26
+ * write is discarded and the target is left untouched. Backends MUST NOT
27
+ * yield between calling the guard and publishing the write, so a concurrent
28
+ * synchronous rewrite that took over cannot be overwritten by a stale body.
29
+ */
30
+ export interface WriteTextAtomicOptions {
31
+ commitGuard?: () => boolean;
32
+ }
22
33
  export interface SessionStorage {
23
34
  ensureDirSync(dir: string): void;
24
35
  existsSync(path: string): boolean;
@@ -38,7 +49,7 @@ export interface SessionStorage {
38
49
  /** Read the requested UTF-8 byte windows from the head and tail of the file. */
39
50
  readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
40
51
  writeText(path: string, content: string): Promise<void>;
41
- writeTextAtomic(path: string, content: string): Promise<void>;
52
+ writeTextAtomic(path: string, content: string, options?: WriteTextAtomicOptions): Promise<void>;
42
53
  rename(path: string, nextPath: string): Promise<void>;
43
54
  unlink(path: string): Promise<void>;
44
55
  deleteSessionWithArtifacts(sessionPath: string): Promise<void>;
@@ -46,6 +57,15 @@ export interface SessionStorage {
46
57
  flags?: "a" | "w";
47
58
  onError?: (err: Error) => void;
48
59
  }): SessionStorageWriter;
60
+ /**
61
+ * Wait for every backing write scheduled by this storage to become durably
62
+ * visible. Sync backends (file, memory) return immediately because their
63
+ * writes complete in-body; async backends (Redis/SQL via
64
+ * {@link IndexedSessionStorage}) await their per-path queues so a caller
65
+ * driving a graceful shutdown does not exit while a fire-and-forget
66
+ * `writeTextSync` publish is still on the wire.
67
+ */
68
+ drain(): Promise<void>;
49
69
  }
50
70
  export declare class FileSessionStorage implements SessionStorage {
51
71
  #private;
@@ -59,9 +79,16 @@ export declare class FileSessionStorage implements SessionStorage {
59
79
  readText(path: string): Promise<string>;
60
80
  readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
61
81
  writeText(path: string, content: string): Promise<void>;
62
- writeTextAtomic(fpath: string, content: string): Promise<void>;
82
+ writeTextAtomic(fpath: string, content: string, options?: WriteTextAtomicOptions): Promise<void>;
83
+ /**
84
+ * Sync rename hook. Split from `rename` so `writeTextAtomic` can perform its
85
+ * guard-then-publish step without a yield, and so tests can inject
86
+ * Windows-style EPERM at the sync layer used by the atomic path.
87
+ */
88
+ renameSync(source: string, target: string): void;
63
89
  rename(path: string, nextPath: string): Promise<void>;
64
90
  unlink(path: string): Promise<void>;
91
+ drain(): Promise<void>;
65
92
  openWriter(path: string, options?: {
66
93
  flags?: "a" | "w";
67
94
  onError?: (err: Error) => void;
@@ -90,10 +117,11 @@ export declare class MemorySessionStorage implements SessionStorage {
90
117
  readText(path: string): Promise<string>;
91
118
  readTextSlices(path: string, prefixBytes: number, suffixBytes: number): Promise<[string, string]>;
92
119
  writeText(path: string, content: string): Promise<void>;
93
- writeTextAtomic(path: string, content: string): Promise<void>;
120
+ writeTextAtomic(path: string, content: string, options?: WriteTextAtomicOptions): Promise<void>;
94
121
  rename(path: string, nextPath: string): Promise<void>;
95
122
  unlink(path: string): Promise<void>;
96
123
  deleteSessionWithArtifacts(_sessionPath: string): Promise<void>;
124
+ drain(): Promise<void>;
97
125
  openWriter(path: string, options?: {
98
126
  flags?: "a" | "w";
99
127
  onError?: (err: Error) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -31,6 +31,25 @@ interface SSHArgsOptions {
31
31
  /** When true, omit `-n` so the remote command can read from our piped stdin. */
32
32
  allowStdin?: boolean;
33
33
  }
34
+ declare function runSshSync(args: string[], timeoutMs?: number): Promise<{
35
+ exitCode: number | null;
36
+ stderr: string;
37
+ }>;
38
+ declare function runSshCaptureSync(args: string[], timeoutMs?: number): Promise<{
39
+ exitCode: number | null;
40
+ stdout: string;
41
+ stderr: string;
42
+ }>;
43
+ /**
44
+ * Test-only surface for exercising the pre-command SSH helpers against a
45
+ * fake `ssh` binary with a shortened timeout. External code MUST NOT depend
46
+ * on this — call `ensureConnection` / `ensureHostInfo` instead.
47
+ * @internal
48
+ */
49
+ export declare const _sshHelpersForTests: {
50
+ runSshSync: typeof runSshSync;
51
+ runSshCaptureSync: typeof runSshCaptureSync;
52
+ };
34
53
  /**
35
54
  * Parse a raw cache-file value (or any unknown) into a normalized
36
55
  * {@link SSHHostInfo}, dropping fields that don't pass the per-field guards.
@@ -1,6 +1,15 @@
1
1
  import { type SSHConnectionTarget } from "./connection-manager";
2
+ type MountPointStatReader = (filePath: string) => Promise<{
3
+ dev: number;
4
+ }>;
5
+ interface MountCheckOptions {
6
+ platform?: NodeJS.Platform;
7
+ stat?: MountPointStatReader;
8
+ which?: (command: string) => string | null;
9
+ }
2
10
  export declare function hasSshfs(): boolean;
3
- export declare function isMounted(path: string): Promise<boolean>;
11
+ export declare function isMounted(mountPath: string, options?: MountCheckOptions): Promise<boolean>;
4
12
  export declare function mountRemote(host: SSHConnectionTarget, remotePath?: string): Promise<string | undefined>;
5
13
  export declare function unmountRemote(host: SSHConnectionTarget): Promise<boolean>;
6
14
  export declare function unmountAll(): Promise<void>;
15
+ export {};
@@ -55,7 +55,7 @@ export interface RefCountedWorkerHandle<Inbound, Outbound> extends WorkerHandle<
55
55
  }
56
56
  /** The raw spawned subprocess plus the parent-side fan-out sets. */
57
57
  export interface SpawnedSubprocess<Outbound> {
58
- proc: Subprocess<"ignore", "ignore", "ignore">;
58
+ proc: Subprocess<"ignore", "ignore", number | "ignore">;
59
59
  inbound: Set<(message: Outbound) => void>;
60
60
  errors: Set<(error: Error) => void>;
61
61
  /**
@@ -67,6 +67,14 @@ export interface SpawnedSubprocess<Outbound> {
67
67
  intentionalExit: {
68
68
  value: boolean;
69
69
  };
70
+ /**
71
+ * Resolves when the file-backed stderr capture has drained after worker
72
+ * exit. `onExit` waits on this before surfacing the crash so the exit-error
73
+ * carries the *whole* tail, not whatever happened to be flushed before the
74
+ * exit event fired. Tests can await it deterministically instead of racing
75
+ * wall-clock timers.
76
+ */
77
+ stderrDrained: Promise<void>;
70
78
  }
71
79
  export interface WorkerSpawnCommand {
72
80
  cmd: string[];
@@ -94,11 +102,17 @@ export declare function resolveWorkerSpawnCmd(workerArg: string): WorkerSpawnCom
94
102
  */
95
103
  export declare function workerEnvFromParent(overlay?: Record<string, string>): Record<string, string>;
96
104
  /**
97
- * Spawn an inference worker subprocess and wire its IPC fan-out. The child
98
- * inherits no stdio (native model runtimes may otherwise print progress or
99
- * decoded text and corrupt the chat scrollback) and is `unref`'d outside `bun
100
- * test` so an idle worker never blocks process exit. `exitLabel` prefixes the
101
- * worker-error message surfaced for an unexpected (non-intentional) exit.
105
+ * Spawn an inference worker subprocess and wire its IPC fan-out. Stdio is
106
+ * captured (stderr redirected to a temp file, stdout ignored) so native
107
+ * runtimes can't corrupt the chat scrollback while the crash reason still
108
+ * reaches the parent. The file-backed capture deliberately avoids Bun
109
+ * `ReadableStream` pipes: even an unref'd child with a piped stderr stream can
110
+ * keep the parent event loop alive. After the worker exits, the last
111
+ * {@link STDERR_TAIL_LIMIT_BYTES} are appended to the `onExit` error so
112
+ * `tts/mnemopi/…: worker error` lines carry the actual stack instead of a bare
113
+ * exit code (issue #4324). The child is `unref`'d outside `bun test` so an idle
114
+ * worker never blocks process exit. `exitLabel` prefixes the worker-error
115
+ * message surfaced for an unexpected (non-intentional) exit.
102
116
  */
103
117
  export declare function createWorkerSubprocess<Outbound>(options: {
104
118
  spawnCommand: WorkerSpawnCommand;
@@ -6,8 +6,11 @@ export interface DiscoveryResult {
6
6
  }
7
7
  /**
8
8
  * Discover agents from filesystem and merge with bundled agents.
9
- *
10
- * Precedence (highest wins): project .omp, user .omp, Claude plugin agents, then bundled
9
+ * Precedence (highest wins): project `.omp/agents`, user `.omp/agents`,
10
+ * OMP extension-package agents in `listOmpExtensionRoots` source order
11
+ * (CLI roots > project `extensions:` settings > user `extensions:` settings >
12
+ * installed npm/link plugins), Claude marketplace plugin agents (project
13
+ * scope before user), then bundled.
11
14
  * @param cwd - Current working directory for project agent discovery
12
15
  */
13
16
  export declare function discoverAgents(cwd: string, home?: string): Promise<DiscoveryResult>;
@@ -10,4 +10,5 @@ export declare const taskToolRenderer: {
10
10
  readonly renderCall: typeof renderCall;
11
11
  readonly renderResult: typeof renderResult;
12
12
  readonly mergeCallAndResult: true;
13
+ readonly animatedPartialResult: true;
13
14
  };