@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.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 (285) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +1 -1
  3. package/dist/cli.js +4659 -4261
  4. package/dist/types/async/job-manager.d.ts +37 -1
  5. package/dist/types/cli/args.d.ts +2 -0
  6. package/dist/types/cli/bench-cli.d.ts +41 -0
  7. package/dist/types/commands/bench.d.ts +15 -3
  8. package/dist/types/commands/launch.d.ts +4 -0
  9. package/dist/types/config/model-registry.d.ts +3 -1
  10. package/dist/types/config/models-config-schema.d.ts +18 -6
  11. package/dist/types/config/models-config.d.ts +14 -5
  12. package/dist/types/config/provider-globals.d.ts +2 -2
  13. package/dist/types/config/service-tier.d.ts +5 -1
  14. package/dist/types/config/settings-schema.d.ts +316 -47
  15. package/dist/types/config/settings.d.ts +7 -0
  16. package/dist/types/dap/client.d.ts +20 -0
  17. package/dist/types/exec/bash-executor.d.ts +38 -0
  18. package/dist/types/exec/direnv.d.ts +33 -0
  19. package/dist/types/export/html/args.d.ts +15 -0
  20. package/dist/types/export/html/index.d.ts +11 -26
  21. package/dist/types/export/html/web-palette.d.ts +55 -116
  22. package/dist/types/extensibility/extensions/loader.d.ts +3 -0
  23. package/dist/types/extensibility/extensions/types.d.ts +17 -2
  24. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
  25. package/dist/types/live/controller.d.ts +40 -0
  26. package/dist/types/live/protocol.d.ts +85 -0
  27. package/dist/types/live/protocol.test.d.ts +1 -0
  28. package/dist/types/live/transport.d.ts +48 -0
  29. package/dist/types/live/visualizer.d.ts +33 -0
  30. package/dist/types/lsp/client.d.ts +16 -1
  31. package/dist/types/mcp/config-writer.test.d.ts +1 -0
  32. package/dist/types/mcp/oauth-discovery.d.ts +2 -0
  33. package/dist/types/mcp/smithery-auth.d.ts +1 -1
  34. package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
  35. package/dist/types/memory-backend/tool-names.d.ts +2 -0
  36. package/dist/types/modes/components/login-dialog.d.ts +2 -2
  37. package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
  38. package/dist/types/modes/components/settings-defs.d.ts +7 -1
  39. package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
  40. package/dist/types/modes/components/tool-execution.d.ts +9 -1
  41. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  42. package/dist/types/modes/controllers/event-controller.d.ts +6 -1
  43. package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
  44. package/dist/types/modes/interactive-mode.d.ts +5 -0
  45. package/dist/types/modes/theme/theme.d.ts +1 -1
  46. package/dist/types/modes/types.d.ts +3 -1
  47. package/dist/types/modes/utils/context-usage.d.ts +12 -2
  48. package/dist/types/plan-mode/plan-files.d.ts +10 -0
  49. package/dist/types/registry/agent-lifecycle.d.ts +21 -9
  50. package/dist/types/registry/agent-registry.d.ts +11 -4
  51. package/dist/types/sdk.d.ts +15 -1
  52. package/dist/types/secrets/index.d.ts +15 -2
  53. package/dist/types/secrets/obfuscator.d.ts +113 -15
  54. package/dist/types/session/acp-permission-gate.d.ts +19 -0
  55. package/dist/types/session/agent-session-events.d.ts +84 -0
  56. package/dist/types/session/agent-session-types.d.ts +314 -0
  57. package/dist/types/session/agent-session.d.ts +118 -755
  58. package/dist/types/session/async-job-delivery.d.ts +28 -0
  59. package/dist/types/session/bash-runner.d.ts +75 -0
  60. package/dist/types/session/blob-store.d.ts +11 -1
  61. package/dist/types/session/blob-store.test.d.ts +1 -0
  62. package/dist/types/session/checkpoint-entries.d.ts +28 -0
  63. package/dist/types/session/eval-runner.d.ts +49 -0
  64. package/dist/types/session/irc-bridge.d.ts +46 -0
  65. package/dist/types/session/messages.d.ts +22 -0
  66. package/dist/types/session/model-controls.d.ts +180 -0
  67. package/dist/types/session/prewalk.d.ts +46 -0
  68. package/dist/types/session/queued-messages.d.ts +22 -0
  69. package/dist/types/session/redis-session-storage.d.ts +1 -0
  70. package/dist/types/session/retry-fallback-chains.d.ts +74 -0
  71. package/dist/types/session/role-models.d.ts +15 -0
  72. package/dist/types/session/session-advisors.d.ts +228 -0
  73. package/dist/types/session/session-entries.d.ts +8 -0
  74. package/dist/types/session/session-handoff.d.ts +70 -0
  75. package/dist/types/session/session-history-format.d.ts +6 -1
  76. package/dist/types/session/session-maintenance.d.ts +246 -0
  77. package/dist/types/session/session-manager.d.ts +41 -0
  78. package/dist/types/session/session-memory.d.ts +56 -0
  79. package/dist/types/session/session-provider-boundary.d.ts +62 -0
  80. package/dist/types/session/session-stats.d.ts +48 -0
  81. package/dist/types/session/session-tools.d.ts +143 -0
  82. package/dist/types/session/session-workspace.d.ts +32 -0
  83. package/dist/types/session/stream-guards.d.ts +44 -0
  84. package/dist/types/session/todo-tracker.d.ts +56 -0
  85. package/dist/types/session/ttsr-coordinator.d.ts +51 -0
  86. package/dist/types/session/turn-recovery.d.ts +225 -0
  87. package/dist/types/system-prompt.d.ts +2 -0
  88. package/dist/types/task/executor.d.ts +4 -1
  89. package/dist/types/task/output-manager.d.ts +3 -1
  90. package/dist/types/tools/approval.d.ts +1 -0
  91. package/dist/types/tools/browser/launch.d.ts +5 -0
  92. package/dist/types/tools/image-gen.d.ts +4 -4
  93. package/dist/types/tools/image-providers.d.ts +38 -0
  94. package/dist/types/tools/index.d.ts +5 -0
  95. package/dist/types/tools/path-utils.d.ts +8 -0
  96. package/dist/types/tools/todo.d.ts +10 -4
  97. package/dist/types/tools/xdev.d.ts +5 -1
  98. package/dist/types/tts/streaming-player.d.ts +14 -0
  99. package/dist/types/tts/vocalizer.d.ts +5 -0
  100. package/dist/types/utils/jj.d.ts +29 -0
  101. package/dist/types/utils/lang-from-path.d.ts +1 -0
  102. package/dist/types/utils/title-generator.d.ts +30 -0
  103. package/dist/types/vibe/runtime.d.ts +36 -8
  104. package/dist/types/web/search/index.d.ts +1 -1
  105. package/dist/types/web/search/provider.d.ts +15 -5
  106. package/dist/types/web/search/types.d.ts +94 -0
  107. package/package.json +12 -12
  108. package/scripts/generate-share-viewer.ts +4 -6
  109. package/src/advisor/__tests__/advisor.test.ts +643 -0
  110. package/src/advisor/runtime.ts +144 -43
  111. package/src/async/job-manager.ts +90 -2
  112. package/src/cli/args.ts +2 -0
  113. package/src/cli/auth-gateway-cli.ts +18 -3
  114. package/src/cli/bench-cli.ts +395 -29
  115. package/src/cli/flag-tables.ts +3 -0
  116. package/src/cli/gc-cli.ts +2 -2
  117. package/src/cli/usage-cli.ts +10 -1
  118. package/src/collab/host.ts +3 -2
  119. package/src/commands/bench.ts +18 -4
  120. package/src/commands/launch.ts +4 -0
  121. package/src/config/model-registry.ts +10 -2
  122. package/src/config/models-config-schema.ts +15 -4
  123. package/src/config/provider-globals.ts +9 -9
  124. package/src/config/service-tier.ts +26 -1
  125. package/src/config/settings-schema.ts +209 -51
  126. package/src/config/settings.ts +81 -2
  127. package/src/dap/client.ts +37 -4
  128. package/src/edit/index.ts +49 -12
  129. package/src/eval/py/executor.ts +103 -33
  130. package/src/exec/bash-executor.ts +89 -6
  131. package/src/exec/direnv.ts +145 -0
  132. package/src/export/html/args.ts +20 -0
  133. package/src/export/html/index.ts +45 -47
  134. package/src/export/html/template.css +19 -1
  135. package/src/export/html/template.html +6 -0
  136. package/src/export/html/template.js +21 -0
  137. package/src/export/html/tool-views.generated.js +31 -31
  138. package/src/export/html/web-palette.ts +116 -132
  139. package/src/export/share.ts +249 -49
  140. package/src/extensibility/extensions/loader.ts +29 -1
  141. package/src/extensibility/extensions/runner.ts +6 -0
  142. package/src/extensibility/extensions/types.ts +33 -2
  143. package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
  144. package/src/hindsight/state.ts +64 -6
  145. package/src/internal-urls/local-protocol.ts +2 -1
  146. package/src/internal-urls/memory-protocol.ts +2 -2
  147. package/src/internal-urls/skill-protocol.ts +2 -2
  148. package/src/internal-urls/ssh-protocol.ts +2 -1
  149. package/src/internal-urls/vault-protocol.ts +2 -1
  150. package/src/live/audio-worklet.txt +59 -0
  151. package/src/live/browser-runtime.txt +221 -0
  152. package/src/live/controller.ts +464 -0
  153. package/src/live/prompts/agent-final-message.md +3 -0
  154. package/src/live/prompts/live-instructions.md +23 -0
  155. package/src/live/protocol.test.ts +140 -0
  156. package/src/live/protocol.ts +233 -0
  157. package/src/live/transport.ts +490 -0
  158. package/src/live/visualizer.ts +234 -0
  159. package/src/lsp/client.ts +29 -9
  160. package/src/lsp/index.ts +19 -4
  161. package/src/main.ts +8 -1
  162. package/src/mcp/config-writer.test.ts +43 -0
  163. package/src/mcp/config-writer.ts +109 -82
  164. package/src/mcp/oauth-discovery.ts +10 -2
  165. package/src/mcp/smithery-auth.test.ts +29 -0
  166. package/src/mcp/smithery-auth.ts +3 -2
  167. package/src/memories/index.ts +40 -20
  168. package/src/memory-backend/tool-names.ts +2 -0
  169. package/src/mnemopi/backend.ts +24 -7
  170. package/src/modes/acp/acp-agent.ts +56 -10
  171. package/src/modes/acp/acp-event-mapper.ts +8 -1
  172. package/src/modes/components/agent-hub.ts +1 -1
  173. package/src/modes/components/login-dialog.ts +14 -4
  174. package/src/modes/components/plan-review-overlay.ts +350 -35
  175. package/src/modes/components/settings-defs.ts +23 -1
  176. package/src/modes/components/settings-selector.ts +169 -1
  177. package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
  178. package/src/modes/components/status-line/component.ts +123 -2
  179. package/src/modes/components/tool-execution.ts +11 -2
  180. package/src/modes/controllers/command-controller.ts +56 -15
  181. package/src/modes/controllers/event-controller.ts +111 -16
  182. package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
  183. package/src/modes/controllers/extension-ui-controller.ts +20 -4
  184. package/src/modes/controllers/live-command-controller.ts +178 -0
  185. package/src/modes/controllers/mcp-command-controller.ts +10 -1
  186. package/src/modes/controllers/omfg-controller.ts +44 -40
  187. package/src/modes/controllers/selector-controller.ts +18 -10
  188. package/src/modes/controllers/session-focus-controller.ts +6 -1
  189. package/src/modes/interactive-mode.ts +157 -38
  190. package/src/modes/runtime-init.ts +2 -0
  191. package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
  192. package/src/modes/theme/theme.ts +1 -1
  193. package/src/modes/types.ts +3 -1
  194. package/src/modes/utils/context-usage.ts +23 -7
  195. package/src/modes/utils/ui-helpers.ts +10 -5
  196. package/src/plan-mode/plan-files.ts +40 -0
  197. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  198. package/src/prompts/bench/cache-prefix.md +3 -0
  199. package/src/prompts/bench/cache-suffix.md +1 -0
  200. package/src/prompts/system/custom-system-prompt.md +1 -1
  201. package/src/prompts/system/project-prompt.md +8 -1
  202. package/src/prompts/system/subagent-async-pending.md +6 -0
  203. package/src/prompts/system/system-prompt.md +1 -1
  204. package/src/prompts/system/workflow-notice.md +48 -40
  205. package/src/prompts/system/xdev-mount-notice.md +4 -0
  206. package/src/prompts/tools/todo.md +3 -1
  207. package/src/registry/agent-lifecycle.ts +116 -46
  208. package/src/registry/agent-registry.ts +35 -8
  209. package/src/registry/persisted-agents.ts +26 -2
  210. package/src/sdk.ts +210 -136
  211. package/src/secrets/index.ts +127 -4
  212. package/src/secrets/obfuscator.ts +2328 -105
  213. package/src/session/acp-permission-gate.ts +165 -0
  214. package/src/session/agent-session-error-log.test.ts +1 -1
  215. package/src/session/agent-session-events.ts +66 -0
  216. package/src/session/agent-session-types.ts +334 -0
  217. package/src/session/agent-session.ts +1892 -12226
  218. package/src/session/artifacts.ts +6 -5
  219. package/src/session/async-job-delivery.ts +74 -0
  220. package/src/session/bash-runner.ts +326 -0
  221. package/src/session/blob-store.test.ts +56 -0
  222. package/src/session/blob-store.ts +18 -2
  223. package/src/session/checkpoint-entries.ts +81 -0
  224. package/src/session/eval-runner.ts +212 -0
  225. package/src/session/indexed-session-storage.ts +9 -2
  226. package/src/session/irc-bridge.ts +203 -0
  227. package/src/session/messages.ts +263 -1
  228. package/src/session/model-controls.ts +714 -0
  229. package/src/session/prewalk.ts +252 -0
  230. package/src/session/queued-messages.ts +93 -0
  231. package/src/session/redis-session-storage.ts +51 -11
  232. package/src/session/retry-fallback-chains.ts +455 -0
  233. package/src/session/role-models.ts +85 -0
  234. package/src/session/session-advisors.ts +1679 -0
  235. package/src/session/session-context.ts +6 -3
  236. package/src/session/session-entries.ts +8 -0
  237. package/src/session/session-handoff.ts +308 -0
  238. package/src/session/session-history-format.ts +20 -9
  239. package/src/session/session-loader.ts +0 -46
  240. package/src/session/session-maintenance.ts +2983 -0
  241. package/src/session/session-manager.ts +390 -30
  242. package/src/session/session-memory.ts +222 -0
  243. package/src/session/session-provider-boundary.ts +307 -0
  244. package/src/session/session-stats.ts +293 -0
  245. package/src/session/session-tools.ts +943 -0
  246. package/src/session/session-workspace.ts +53 -0
  247. package/src/session/stream-guards.ts +417 -0
  248. package/src/session/todo-tracker.ts +380 -0
  249. package/src/session/ttsr-coordinator.ts +496 -0
  250. package/src/session/turn-recovery.ts +1629 -0
  251. package/src/slash-commands/builtin-registry.ts +92 -11
  252. package/src/slash-commands/helpers/usage-report.ts +22 -3
  253. package/src/system-prompt.ts +41 -17
  254. package/src/task/executor.ts +285 -70
  255. package/src/task/index.ts +98 -105
  256. package/src/task/output-manager.ts +25 -3
  257. package/src/task/persisted-revive.ts +4 -3
  258. package/src/task/structured-subagent.ts +1 -0
  259. package/src/tools/approval.ts +55 -10
  260. package/src/tools/bash-interactive.ts +26 -0
  261. package/src/tools/bash-skill-urls.ts +28 -2
  262. package/src/tools/bash.ts +339 -123
  263. package/src/tools/browser/launch.ts +9 -1
  264. package/src/tools/browser/tab-supervisor.ts +8 -5
  265. package/src/tools/browser.ts +94 -47
  266. package/src/tools/image-gen.ts +20 -28
  267. package/src/tools/image-providers.ts +50 -0
  268. package/src/tools/index.ts +9 -0
  269. package/src/tools/path-utils.ts +49 -2
  270. package/src/tools/read.ts +156 -88
  271. package/src/tools/renderers.ts +7 -1
  272. package/src/tools/todo.ts +101 -11
  273. package/src/tools/vibe.ts +1 -2
  274. package/src/tools/write.ts +51 -1
  275. package/src/tools/xdev.ts +67 -3
  276. package/src/tts/streaming-player.ts +62 -4
  277. package/src/tts/vocalizer.ts +18 -1
  278. package/src/utils/jj.ts +125 -4
  279. package/src/utils/lang-from-path.ts +7 -0
  280. package/src/utils/title-generator.ts +137 -1
  281. package/src/vibe/runtime.ts +852 -72
  282. package/src/web/search/index.ts +3 -6
  283. package/src/web/search/provider.ts +31 -16
  284. package/src/web/search/providers/xai.ts +7 -1
  285. package/src/web/search/types.ts +3 -0
@@ -0,0 +1,225 @@
1
+ import { type Agent, type AgentMessage, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
+ import type { AssistantMessage, CodexCompactionContext, Model, ToolChoice } from "@oh-my-pi/pi-ai";
3
+ import type { ModelRegistry } from "../config/model-registry.js";
4
+ import type { Settings } from "../config/settings.js";
5
+ import type { ConfiguredThinkingLevel } from "../thinking.js";
6
+ import type { AgentSessionEvent } from "./agent-session-events.js";
7
+ import type { InitialRetryFallbackState } from "./agent-session-types.js";
8
+ import { type RetryFallbackSelector } from "./retry-fallback-chains.js";
9
+ import type { SessionManager } from "./session-manager.js";
10
+ /** Result shape shared with automatic maintenance recovery. */
11
+ export interface RecoveryCompactionResult {
12
+ deferredHandoff: boolean;
13
+ continuationScheduled: boolean;
14
+ automaticContinuationBlocked?: boolean;
15
+ historyRewritten?: boolean;
16
+ }
17
+ /** Capabilities borrowed from the owning AgentSession. */
18
+ export interface TurnRecoveryHost {
19
+ agent: Agent;
20
+ sessionManager: SessionManager;
21
+ settings: Settings;
22
+ modelRegistry: ModelRegistry;
23
+ configWarnings: string[];
24
+ model(): Model | undefined;
25
+ thinkingLevel(): ThinkingLevel | undefined;
26
+ configuredThinkingLevel(): ConfiguredThinkingLevel | undefined;
27
+ setThinkingLevel(level: ConfiguredThinkingLevel | undefined): void;
28
+ isDisposed(): boolean;
29
+ isStreaming(): boolean;
30
+ isCompacting(): boolean;
31
+ abortInProgress(): boolean;
32
+ streamingEditAbortTriggered(): boolean;
33
+ promptGeneration(): number;
34
+ sessionId(): string;
35
+ emitSessionEvent(event: AgentSessionEvent): Promise<void>;
36
+ scheduleAgentContinue(options: {
37
+ delayMs?: number;
38
+ generation?: number;
39
+ }): void;
40
+ waitForSessionMessagePersistence(message: AssistantMessage): Promise<void>;
41
+ appendSessionMessage(message: AssistantMessage): void;
42
+ sessionMessageAlreadyPersisted(message: AssistantMessage): boolean;
43
+ setModelWithProviderSessionReset(model: Model): void;
44
+ resetCurrentResponsesProviderSession(reason: string): void;
45
+ maybeAutoRedeemCodexReset(): Promise<boolean>;
46
+ runAutoCompaction(reason: "overflow" | "threshold" | "idle" | "incomplete", willRetry: boolean, deferred?: boolean, allowDefer?: boolean, options?: {
47
+ autoContinue?: boolean;
48
+ triggerContextTokens?: number;
49
+ suppressContinuation?: boolean;
50
+ suppressHandoff?: boolean;
51
+ phase?: CodexCompactionContext["phase"];
52
+ terminalTextAnswer?: boolean;
53
+ }): Promise<RecoveryCompactionResult>;
54
+ withBashBranchTransition<T>(operation: () => T): T;
55
+ }
56
+ /** Construction-time retry state restored from model selection. */
57
+ export interface TurnRecoveryOptions {
58
+ initialRetryFallback?: InitialRetryFallbackState;
59
+ }
60
+ /** Owns terminal-stop recovery, automatic retries, and fallback routing. */
61
+ export declare class TurnRecovery {
62
+ #private;
63
+ constructor(host: TurnRecoveryHost, options?: TurnRecoveryOptions);
64
+ /** Current automatic retry attempt. */
65
+ get attempt(): number;
66
+ /** Promise settled when the active retry saga finishes. */
67
+ get retryPromise(): Promise<void> | undefined;
68
+ /** Resolved selector while fallback routing owns the current model. */
69
+ get retryFallbackModel(): string | undefined;
70
+ /** Resets per-prompt recovery counters and terminal-stop acceptance. */
71
+ resetForNewPrompt(): void;
72
+ /** Sets whether one terminal empty stop is accepted for the current prompt. */
73
+ setAcceptTerminalEmptyStop(accept: boolean): void;
74
+ /** Closes a successful retry saga and annotates recovered persisted errors. */
75
+ onAssistantSettledSuccessfully(message: AssistantMessage): Promise<void>;
76
+ /** Closes a failed retry saga when no compaction continuation took ownership. */
77
+ onErrorSettledWithoutRetry(message: AssistantMessage, compaction: RecoveryCompactionResult): Promise<void>;
78
+ /** Persists an otherwise skipped terminal empty error turn. */
79
+ persistTerminalEmptyErrorTurn(message: AssistantMessage): Promise<void>;
80
+ /** Handles empty terminal assistant turns and schedules bounded recovery. */
81
+ handleEmptyAssistantStop(message: AssistantMessage): Promise<boolean>;
82
+ /** Classifies suspicious terminal stops and schedules bounded recovery. */
83
+ handleUnexpectedAssistantStop(message: AssistantMessage): Promise<boolean>;
84
+ /** Removes a persisted failed assistant turn after its persistence slot settles. */
85
+ dropPersistedAssistantTurn(message: AssistantMessage): Promise<void>;
86
+ /** Runs recovery compaction and restores the failed turn when no rewrite occurs. */
87
+ runRecoveryCompactionWithRollback(reason: "overflow" | "incomplete", message: AssistantMessage, allowDefer: boolean, options: {
88
+ autoContinue: boolean;
89
+ triggerContextTokens?: number;
90
+ }): Promise<RecoveryCompactionResult>;
91
+ /** Restores the configured primary after fallback cooldown expiry. */
92
+ maybeRestoreRetryFallbackPrimary(): Promise<void>;
93
+ /** Applies automatic retry, credential rotation, and model fallback policy. */
94
+ handleRetryableError(message: AssistantMessage, options?: {
95
+ allowModelFallback?: boolean;
96
+ fireworksFastFallback?: boolean;
97
+ hardErrorFallback?: boolean;
98
+ preserveFailedTurn?: boolean;
99
+ }): Promise<boolean>;
100
+ /** Prompts after transient overlap with a prior agent run. */
101
+ promptAgentWithIdleRetry(messages: AgentMessage[], options?: {
102
+ toolChoice?: ToolChoice;
103
+ }): Promise<void>;
104
+ /** Parses provider retry and rate-limit reset hints into a delay. */
105
+ parseRetryAfterMsFromError(errorMessage: string): number | undefined;
106
+ /** Resolve the pending retry promise */
107
+ resolveRetry(): void;
108
+ removeAssistantMessageFromActiveContext(assistantMessage: AssistantMessage, reason?: string): void;
109
+ /**
110
+ * Drop an assistant turn from BOTH the live agent context and the persisted
111
+ * session branch (reparenting the leaf to the turn's parent), so a discarded
112
+ * turn does not resurface on reload. Used for empty/reasoning-only stops and
113
+ * the Gemini header-runaway interrupt, which must not replay a partial,
114
+ * loop-fueling thinking block.
115
+ */
116
+ discardAssistantTurn(assistantMessage: AssistantMessage): void;
117
+ /**
118
+ * Retry an empty, reason-less provider abort: a turn with no content that
119
+ * carries the generic sentinel (bare `abort()`), whether the provider
120
+ * finalized it as `stopReason: "aborted"` or leaked it as `stopReason:
121
+ * "error"` (a stalled/dropped stream reported as an error rather than an
122
+ * abort — issue #5375). Only fires while the session is neither aborting nor
123
+ * tearing down. A user/lifecycle abort (`#abortInProgress`), a dispose-driven
124
+ * abort (`#isDisposed`), or a session-induced streaming-edit guard abort
125
+ * (`StreamingEditGuard.abortTriggered` — auto-generated-file guard or failed-patch
126
+ * preview) is deliberate and MUST settle the turn instead: routing it through
127
+ * retry would orphan `#retryPromise` on a continuation the guard skips
128
+ * (hanging the in-flight `prompt()`) or silently undo the guard's intended
129
+ * abort. Deliberate user interrupts (`UserInterrupt`) and silent aborts carry
130
+ * their own marker, not the generic sentinel, so they never match here.
131
+ */
132
+ isRetryableReasonlessAbort(message: AssistantMessage): boolean;
133
+ /**
134
+ * Check if an error is retryable (transient errors or usage limits).
135
+ * Context overflow is NOT retryable (handled by compaction instead).
136
+ * Usage-limit errors are retryable because the retry handler performs credential switching.
137
+ */
138
+ isRetryableError(message: AssistantMessage): boolean;
139
+ /**
140
+ * Resume a stalled turn after every emitted tool call has produced a result.
141
+ * Cursor calls must also carry the server-execution marker. The failed
142
+ * assistant/tool-result pair stays in context so completed side effects are
143
+ * continued from rather than replayed.
144
+ */
145
+ canResumeResolvedStreamStall(message: AssistantMessage): boolean;
146
+ /** Checks whether a provider error represents a classifier refusal. */
147
+ isClassifierRefusal(message: AssistantMessage): boolean;
148
+ /** Clears fallback ownership after an explicit model change. */
149
+ clearActiveRetryFallback(): void;
150
+ /** Checks whether a fallback selector remains in cooldown. */
151
+ isRetryFallbackSelectorSuppressed(selector: RetryFallbackSelector): boolean;
152
+ /** Records the cooldown that should suppress a failing selector. */
153
+ noteRetryFallbackCooldown(currentSelector: string, retryAfterMs: number | undefined, errorMessage: string): void;
154
+ /**
155
+ * Map the failing model selector to the chain key that owns it, by
156
+ * specificity: an exact model-selector key, then a `provider/*` wildcard,
157
+ * then a model role whose current assignment matches, then `default`.
158
+ * Model-oriented keys win over roles so a chain follows the model across
159
+ * role reassignments.
160
+ */
161
+ resolveRetryFallbackRole(currentSelector: string, currentModel?: Model | null | undefined): string | undefined;
162
+ /** Finds fallback candidates that follow the active selector. */
163
+ findRetryFallbackCandidates(role: string, currentSelector: string, currentModel?: Model | null | undefined): RetryFallbackSelector[];
164
+ applyRetryFallbackCandidate(role: string, selector: RetryFallbackSelector, currentSelector: string, options?: {
165
+ pinFallback?: boolean;
166
+ apiKey?: string;
167
+ signal?: AbortSignal;
168
+ }): Promise<void>;
169
+ /**
170
+ * True when the current turn failed on a Fireworks Fast (`-fast`) model in a
171
+ * way that should degrade to the reliable base (Standard) model. Fast is a
172
+ * speed-optimized router with no SLA, so any *pre-content* failure — a
173
+ * transient overload/5xx or a hard "router/model not found / unsupported" —
174
+ * is worth retrying on the base id. Skips failures the base model shares:
175
+ * context overflow (compaction's job), usage limits and auth errors (same
176
+ * account/key), and turns that already emitted a tool call (replaying would
177
+ * duplicate work). Requires the base model to exist in the registry.
178
+ */
179
+ isFireworksFastFallbackEligible(message: AssistantMessage): boolean;
180
+ /**
181
+ * True when a turn failed with a hard (non-retryable) provider error but a
182
+ * configured `retry.fallbackChains` entry covers the active model: the same
183
+ * model is not worth retrying, yet a DIFFERENT model is a fresh chance, so
184
+ * the chain is consulted before the error becomes final. Skips failures a
185
+ * model switch cannot fix or must not replay: cancellations (abort-flavored
186
+ * errors are not model faults), context overflow (compaction's job),
187
+ * classifier refusals (chain consult is handled on the retryable path with
188
+ * `pinFallback`), and turns that already emitted a tool call (replaying
189
+ * could duplicate work).
190
+ */
191
+ isHardErrorFallbackEligible(message: AssistantMessage): boolean;
192
+ /**
193
+ * Cancel in-progress retry.
194
+ */
195
+ abortRetry(): void;
196
+ /** Whether auto-retry is currently in progress */
197
+ get isRetrying(): boolean;
198
+ /** Whether auto-retry is enabled */
199
+ get autoRetryEnabled(): boolean;
200
+ /**
201
+ * Toggle auto-retry setting.
202
+ */
203
+ setAutoRetryEnabled(enabled: boolean): void;
204
+ /**
205
+ * Manually retry the last failed assistant turn.
206
+ * Removes the error message from active agent state when present and
207
+ * re-attempts with a fresh retry budget.
208
+ *
209
+ * A stream that stalls or aborts mid-tool-call ends the turn with
210
+ * `stopReason: "error" | "aborted"` and then appends one synthetic
211
+ * {@link isSyntheticToolResultMessage tool_result} per emitted tool call to
212
+ * preserve the provider's tool_use/tool_result pairing (see
213
+ * `createAbortedToolResult` in `agent-loop.ts`). Those placeholders trail the
214
+ * failed assistant turn, so the retry lookback walks back over them before
215
+ * checking the assistant message; it strips both the placeholders and the
216
+ * failed turn before re-attempting.
217
+ *
218
+ * A restored session deliberately omits failed assistant turns from provider
219
+ * context. In that case, the persisted display transcript remains the source
220
+ * of truth for whether the current branch has a retryable failed tail.
221
+ *
222
+ * @returns true if retry was initiated, false if no failed turn to retry or agent is busy
223
+ */
224
+ retry(): Promise<boolean>;
225
+ }
@@ -72,6 +72,8 @@ export interface BuildSystemPromptOptions {
72
72
  skillsSettings?: SkillsSettings;
73
73
  /** Working directory. Default: getProjectDir() */
74
74
  cwd?: string;
75
+ /** Additional workspace directories beyond cwd (multi-root), absolute. Injected into the project prompt. */
76
+ additionalWorkspaceRoots?: string[];
75
77
  /** Pre-loaded context files (skips discovery if provided). */
76
78
  contextFiles?: Array<{
77
79
  path: string;
@@ -17,6 +17,7 @@ import type { HindsightSessionState } from "../hindsight/state.js";
17
17
  import type { LocalProtocolOptions } from "../internal-urls/index.js";
18
18
  import type { MCPManager } from "../mcp/manager.js";
19
19
  import type { MnemopiSessionState } from "../mnemopi/state.js";
20
+ import { type AgentReviver } from "../registry/agent-lifecycle.js";
20
21
  import type { AgentSession } from "../session/agent-session.js";
21
22
  import type { ArtifactManager } from "../session/artifacts.js";
22
23
  import type { AuthStorage } from "../session/auth-storage.js";
@@ -44,6 +45,8 @@ export declare function buildBudgetNotice(requests: number, budget: number): str
44
45
  /** Options for subagent execution */
45
46
  export interface ExecutorOptions {
46
47
  cwd: string;
48
+ /** Additional workspace directories to seed on the subagent session (multi-root). */
49
+ additionalDirectories?: string[];
47
50
  worktree?: string;
48
51
  agent: AgentDefinition;
49
52
  task: string;
@@ -249,7 +252,7 @@ export declare function finalizeSubagentLifecycle(args: {
249
252
  keepAlive: boolean;
250
253
  isolated: boolean;
251
254
  agentIdleTtlMs: number;
252
- reviveSession: (() => Promise<AgentSession>) | null;
255
+ reviveSession: AgentReviver | null;
253
256
  }): Promise<void>;
254
257
  /** Options for {@link runSubagentFollowUpTurn}. */
255
258
  export interface FollowUpTurnOptions {
@@ -3,13 +3,15 @@
3
3
  *
4
4
  * The first allocation of a given name keeps the name as-is; subsequent
5
5
  * allocations of the same name get a `-2`, `-3`, … suffix. On resume, scans
6
- * existing output files so previously written outputs are never overwritten.
6
+ * existing output and child-session files so prior state is never overwritten.
7
7
  */
8
8
  export declare class AgentOutputManager {
9
9
  #private;
10
10
  constructor(getArtifactsDir: () => string | null, options?: {
11
11
  parentPrefix?: string;
12
12
  });
13
+ /** Reserve final IDs discovered outside the output directory scan. */
14
+ reserve(ids: Iterable<string>): Promise<void>;
13
15
  /**
14
16
  * Allocate a unique ID.
15
17
  *
@@ -16,6 +16,7 @@ export interface ResolvedApproval {
16
16
  tier: ToolTier;
17
17
  reason?: string;
18
18
  override: boolean;
19
+ source?: "tool" | "user" | "mode";
19
20
  }
20
21
  /**
21
22
  * Evaluate a tool's own approval declaration against `args` and return the
@@ -14,6 +14,7 @@ export declare const BROWSER_PROTOCOL_TIMEOUT_MS = 60000;
14
14
  export declare function loadPuppeteer(): Promise<typeof Puppeteer>;
15
15
  export declare function loadPuppeteerInWorker(safeDir: string): Promise<typeof Puppeteer>;
16
16
  export declare function ensureChromiumExecutable(): Promise<string | undefined>;
17
+ /** Options shared by headless Chromium consumers. */
17
18
  export interface LaunchHeadlessOptions {
18
19
  headless: boolean;
19
20
  viewport?: {
@@ -21,6 +22,10 @@ export interface LaunchHeadlessOptions {
21
22
  height: number;
22
23
  deviceScaleFactor?: number;
23
24
  };
25
+ /** Additional Chromium arguments merged with the centralized launch defaults. */
26
+ args?: readonly string[];
27
+ /** Additional exact Puppeteer default arguments to suppress. */
28
+ ignoreDefaultArgs?: readonly string[];
24
29
  }
25
30
  export declare function launchHeadlessBrowser(opts: LaunchHeadlessOptions): Promise<Browser>;
26
31
  export declare function applyViewport(page: Page, viewport?: {
@@ -1,7 +1,8 @@
1
1
  import { type Model } from "@oh-my-pi/pi-ai";
2
2
  import { type ModelRegistry } from "../config/model-registry.js";
3
3
  import type { CustomTool } from "../extensibility/custom-tools/types.js";
4
- export type ImageProvider = "antigravity" | "gemini" | "openai" | "openai-codex" | "openrouter" | "xai";
4
+ import { type ImageProvider } from "./image-providers.js";
5
+ export type { ImageProvider } from "./image-providers.js";
5
6
  export type ImageProviderPreference = ImageProvider | "auto";
6
7
  declare const responseModalitySchema: import("arktype/internal/variants/string.ts").StringType<"IMAGE" | "TEXT", {}>;
7
8
  export declare const imageGenSchema: import("arktype/internal/variants/object.ts").ObjectType<{
@@ -59,9 +60,8 @@ interface InlineImageData {
59
60
  mimeType: string;
60
61
  }
61
62
  export declare function isImageProviderPreference(value: unknown): value is ImageProviderPreference;
62
- /** Set the preferred image provider from settings */
63
- export declare function setPreferredImageProvider(provider: ImageProviderPreference): void;
63
+ /** Set the configured image-provider priority from settings; invalid IDs are dropped. */
64
+ export declare function setImageProviderOrder(providers: readonly string[]): void;
64
65
  export declare const imageGenTool: CustomTool<typeof imageGenSchema, ImageGenToolDetails>;
65
66
  export declare function getImageGenTools(_modelRegistry?: ModelRegistry, _activeModel?: Model): Promise<Array<CustomTool<typeof imageGenSchema, ImageGenToolDetails>>>;
66
67
  export declare function getImageGenToolsWithRegistry(_modelRegistry: ModelRegistry, _activeModel?: Model): Promise<Array<CustomTool<typeof imageGenSchema, ImageGenToolDetails>>>;
67
- export {};
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Image Generation Providers
3
+ *
4
+ * Leaf module (no runtime deps) shared by the image_gen tool, the settings
5
+ * schema, and settings migrations — mirrors `web/search/types.ts` so the
6
+ * provider list, auto order, and settings choices never drift apart.
7
+ */
8
+ /** Image generation backends, in settings/tool vocabulary. */
9
+ export type ImageProvider = "antigravity" | "gemini" | "openai" | "openai-codex" | "openrouter" | "xai";
10
+ /** Auto-resolution fallback order when no configured entry or session provider matches. */
11
+ export declare const AUTO_IMAGE_PROVIDER_ORDER: readonly ImageProvider[];
12
+ /** Settings choices for `providers.imageOrder` (labels shared with the retired single-preference enum). */
13
+ export declare const IMAGE_PROVIDER_CHOICES: readonly [{
14
+ readonly value: "openai";
15
+ readonly label: "OpenAI";
16
+ readonly description: "OPENAI_API_KEY (gpt-image-2) or active GPT model; falls back to a connected Codex subscription";
17
+ }, {
18
+ readonly value: "openai-codex";
19
+ readonly label: "OpenAI Codex (ChatGPT)";
20
+ readonly description: "Uses a connected Codex / ChatGPT subscription — no OPENAI_API_KEY needed";
21
+ }, {
22
+ readonly value: "antigravity";
23
+ readonly label: "Antigravity";
24
+ readonly description: "Requires google-antigravity OAuth";
25
+ }, {
26
+ readonly value: "xai";
27
+ readonly label: "xAI Grok Imagine";
28
+ readonly description: "Requires xAI Grok OAuth or XAI_API_KEY";
29
+ }, {
30
+ readonly value: "gemini";
31
+ readonly label: "Gemini";
32
+ readonly description: "Requires GEMINI_API_KEY";
33
+ }, {
34
+ readonly value: "openrouter";
35
+ readonly label: "OpenRouter";
36
+ readonly description: "Requires OPENROUTER_API_KEY";
37
+ }];
38
+ export declare function isImageProviderId(value: unknown): value is ImageProvider;
@@ -19,6 +19,7 @@ import type { ArtifactManager } from "../session/artifacts.js";
19
19
  import type { ClientBridge } from "../session/client-bridge.js";
20
20
  import type { CustomMessage } from "../session/messages.js";
21
21
  import type { UsageStatistics } from "../session/session-entries.js";
22
+ import type { SessionManager } from "../session/session-manager.js";
22
23
  import type { ToolChoiceQueue } from "../session/tool-choice-queue.js";
23
24
  import type { AgentOutputManager } from "../task/output-manager.js";
24
25
  import { type StructuredSubagentSchemaMode } from "../task/types.js";
@@ -106,6 +107,8 @@ export interface DeferredDiagnosticsEntry {
106
107
  export interface ToolSession {
107
108
  /** Current working directory */
108
109
  cwd: string;
110
+ /** Additional workspace directories beyond cwd (multi-root), forwarded to subagents. */
111
+ additionalDirectories?: string[];
109
112
  /** Whether UI is available */
110
113
  hasUI: boolean;
111
114
  /**
@@ -177,6 +180,8 @@ export interface ToolSession {
177
180
  getEvalSessionId?: () => string | null;
178
181
  /** Get session file */
179
182
  getSessionFile: () => string | null;
183
+ /** Parent session journal used by tools that persist runtime lifecycle state. */
184
+ sessionManager?: Pick<SessionManager, "appendCustomEntry" | "ensureOnDisk" | "flush" | "getBranch" | "getEntries">;
180
185
  /** Get eval kernel owner ID for session-scoped retained-kernel cleanup. */
181
186
  getEvalKernelOwnerId?: () => string | null;
182
187
  /** Reject new eval work once session disposal has started. */
@@ -236,6 +236,14 @@ export declare function partitionExistingPaths(items: string[], cwd: string, spl
236
236
  basePath: string;
237
237
  }): Promise<PartitionedPaths>;
238
238
  export declare function resolveReadPath(filePath: string, cwd: string): string;
239
+ /**
240
+ * Find a unique workspace entry whose trailing path matches a missing authored path.
241
+ * Returns `null` for no match, ambiguity, timeout, or scan failure.
242
+ */
243
+ export declare function findUniqueWorkspaceSuffix(rawPath: string, cwd: string, signal?: AbortSignal): Promise<{
244
+ absolutePath: string;
245
+ displayPath: string;
246
+ } | null>;
239
247
  /** Local file materialized from a readable external URL for shared tool-scope resolution. */
240
248
  export interface ResolvedExternalSearchUrl {
241
249
  /** Absolute or cwd-relative file path to search. */
@@ -5,17 +5,21 @@ import type { RenderResultOptions } from "../extensibility/custom-tools/types.js
5
5
  import type { Theme } from "../modes/theme/theme.js";
6
6
  import type { ToolSession } from "../sdk.js";
7
7
  import type { SessionEntry } from "../session/session-entries.js";
8
- export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned";
8
+ export type TodoStatus = "pending" | "in_progress" | "completed" | "abandoned" | "blocked";
9
9
  /** Operation names accepted by the todo tool and echoed in successful result details. */
10
- export type TodoOperation = "init" | "start" | "done" | "rm" | "drop" | "append" | "view";
10
+ export type TodoOperation = "init" | "start" | "done" | "rm" | "drop" | "block" | "unblock" | "append" | "view";
11
11
  export interface TodoItem {
12
12
  content: string;
13
13
  status: TodoStatus;
14
+ /** When `status === "blocked"`, an optional note on what the task is waiting for. */
15
+ blocker?: string;
14
16
  }
15
17
  export interface TodoPhase {
16
18
  name: string;
17
19
  tasks: TodoItem[];
18
20
  }
21
+ /** Whether an unknown value is a persisted todo phase. */
22
+ export declare function isTodoPhase(value: unknown): value is TodoPhase;
19
23
  export interface TodoCompletionTransition {
20
24
  phase: string;
21
25
  content: string;
@@ -28,7 +32,7 @@ export interface TodoToolDetails {
28
32
  completedTasks?: TodoCompletionTransition[];
29
33
  }
30
34
  declare const todoSchema: import("arktype/internal/variants/object.ts").ObjectType<{
31
- op: "append" | "done" | "drop" | "init" | "rm" | "start" | "view";
35
+ op: "append" | "block" | "done" | "drop" | "init" | "rm" | "start" | "unblock" | "view";
32
36
  list?: {
33
37
  phase: string;
34
38
  items: string[];
@@ -36,6 +40,7 @@ declare const todoSchema: import("arktype/internal/variants/object.ts").ObjectTy
36
40
  task?: string | undefined;
37
41
  phase?: string | undefined;
38
42
  items?: string[] | undefined;
43
+ reason?: string | undefined;
39
44
  }, {}>;
40
45
  type TodoParams = TodoSchema;
41
46
  type TodoSchema = typeof todoSchema.infer;
@@ -107,7 +112,7 @@ export declare class TodoTool implements AgentTool<typeof todoSchema, TodoToolDe
107
112
  readonly summary = "Write a structured todo list to track progress within a session";
108
113
  readonly description: string;
109
114
  readonly parameters: import("arktype/internal/variants/object.ts").ObjectType<{
110
- op: "append" | "done" | "drop" | "init" | "rm" | "start" | "view";
115
+ op: "append" | "block" | "done" | "drop" | "init" | "rm" | "start" | "unblock" | "view";
111
116
  list?: {
112
117
  phase: string;
113
118
  items: string[];
@@ -115,6 +120,7 @@ export declare class TodoTool implements AgentTool<typeof todoSchema, TodoToolDe
115
120
  task?: string | undefined;
116
121
  phase?: string | undefined;
117
122
  items?: string[] | undefined;
123
+ reason?: string | undefined;
118
124
  }, {}>;
119
125
  readonly concurrency = "exclusive";
120
126
  readonly strict = true;
@@ -47,6 +47,8 @@ export declare const XDEV_KEEP_TOP_LEVEL: Record<string, true>;
47
47
  * declared `loadMode`.
48
48
  */
49
49
  export declare const XDEV_TRANSPORT_TOOLS: Record<string, true>;
50
+ /** Controls which mounted-device docs are inlined into the system prompt. */
51
+ export type XdevDocsMode = "inline" | "builtins" | "catalog";
50
52
  /**
51
53
  * Whether an enabled tool is presented under `xd://` (rather than top-level)
52
54
  * while the `xd://` transport is active. Discoverable tools mount unless they
@@ -120,7 +122,9 @@ export declare class XdevRegistry {
120
122
  * Dynamic mounts embed at most {@link EXTERNAL_DESCRIPTION_CAP} description
121
123
  * chars (schema always intact); `read xd://<tool>` returns the full text.
122
124
  */
123
- docsAll(): string;
125
+ docsAll(mode?: XdevDocsMode, inlinePatterns?: readonly string[]): string;
126
+ /** Docs for selected mounted devices under the configured prompt-doc policy. */
127
+ docsFor(names: Iterable<string>, mode: XdevDocsMode, inlinePatterns?: readonly string[]): string;
124
128
  /**
125
129
  * Execute a device write: `content` is the JSON args object (empty, `?`, or
126
130
  * `help` returns docs). Args validate against the wrapped tool's schema —
@@ -18,6 +18,19 @@ export interface StreamingPlayerLookup {
18
18
  * - win32: none (PowerShell `SoundPlayer` is file-only).
19
19
  */
20
20
  export declare function streamingPlayerCommandsFor(platform: NodeJS.Platform, sampleRate: number, lookup?: StreamingPlayerLookup): PlayerCommand[];
21
+ /**
22
+ * Test seams for {@link StreamingAudioPlayer}: override backend discovery and
23
+ * the per-file fallback so playback logic can be exercised without a real audio
24
+ * device. Both default to the platform lookup and {@link playAudioFile}.
25
+ */
26
+ export interface StreamingPlayerOptions {
27
+ /** Ordered backend commands for a sample rate; defaults to {@link streamingPlayerCommandsFor}. */
28
+ commandsFor?: (sampleRate: number) => PlayerCommand[];
29
+ /** Per-file fallback playback; defaults to {@link playAudioFile}. */
30
+ playAudio?: (wavPath: string, signal: AbortSignal) => Promise<void>;
31
+ /** Max seconds of streamed PCM retained for the nonzero-exit replay; defaults to {@link REPLAY_RETENTION_SECONDS}. */
32
+ replayRetentionSeconds?: number;
33
+ }
21
34
  /**
22
35
  * Single-session gapless player. Lifecycle: {@link start} once, {@link write}
23
36
  * chunks in order, then {@link end} to drain or {@link stop} to abort. Not
@@ -25,6 +38,7 @@ export declare function streamingPlayerCommandsFor(platform: NodeJS.Platform, sa
25
38
  */
26
39
  export declare class StreamingAudioPlayer {
27
40
  #private;
41
+ constructor(options?: StreamingPlayerOptions);
28
42
  /** Pick a backend and begin draining. Idempotent; the first call's rate wins. */
29
43
  start(sampleRate: number): void;
30
44
  /** Queue a mono float32 PCM chunk for playback in arrival order. */
@@ -11,6 +11,11 @@ export declare class Vocalizer {
11
11
  constructor(createPlayer?: () => VocalizerPlayer);
12
12
  /** Wire (or drop) the per-session enhanced-rewrite service. */
13
13
  setEnhancer(enhancer: SpeechEnhancer | null): void;
14
+ /**
15
+ * Suppress new vocalization until the returned idempotent release function runs.
16
+ * Existing synthesis and playback stop immediately; nested scopes release independently.
17
+ */
18
+ suspend(): () => void;
14
19
  /**
15
20
  * Stream a delta of assistant text into the pipeline. No-op when
16
21
  * vocalization is disabled. The synthesis session (worker, player) is only
@@ -1,3 +1,4 @@
1
+ import * as git from "./git.js";
1
2
  /** Result from a completed `jj` subprocess invocation. */
2
3
  export interface JjCommandResult {
3
4
  /** Process exit code reported by `jj`. */
@@ -32,14 +33,41 @@ export declare class JjCommandError extends Error {
32
33
  /** Create an error for a failed checked `jj` command. */
33
34
  constructor(args: readonly string[], result: JjCommandResult);
34
35
  }
36
+ declare function parseWorkingCopyLabel(raw: string): string | null;
37
+ declare function parseStatusSummary(raw: string): git.GitStatusSummary;
35
38
  /** Run `jj diff --git` for the current workspace commit and return the raw Git-format diff text. */
36
39
  export declare const diff: ((cwd: string, options?: DiffOptions) => Promise<string>) & {
37
40
  /** List changed file paths. */
38
41
  changedFiles(cwd: string, options?: Pick<DiffOptions, "files" | "signal">): Promise<string[]>;
39
42
  };
43
+ /** Jujutsu working-copy metadata used by status displays. */
44
+ export declare const workingCopy: {
45
+ /**
46
+ * Label `@` with its nearest bookmark, falling back to its short change ID.
47
+ * Returns `null` when `jj` is unavailable or the query fails.
48
+ */
49
+ label(cwd: string, signal?: AbortSignal): Promise<string | null>;
50
+ /** Parse working-copy label query output. */
51
+ parseLabel: typeof parseWorkingCopyLabel;
52
+ };
53
+ /** Jujutsu working-copy status derived from the changes in `@`. */
54
+ export declare const status: {
55
+ /**
56
+ * Count changes in `@` relative to its parent using the Git status shape.
57
+ * Jujutsu has no index, so `staged` is always zero.
58
+ */
59
+ summary(cwd: string, signal?: AbortSignal): Promise<git.GitStatusSummary | null>;
60
+ /** Parse `jj diff --summary` output into status counts. */
61
+ parse: typeof parseStatusSummary;
62
+ };
40
63
  export declare const repo: {
41
64
  /** Clear cached workspace roots. Intended for tests that mutate JJ metadata under an existing path. */
42
65
  clearRootCache(): void;
66
+ /**
67
+ * Resolve the current workspace root synchronously from on-disk metadata.
68
+ * Intended for render paths that cannot await filesystem I/O.
69
+ */
70
+ rootSync(cwd: string): string | null;
43
71
  /** Resolve the current Jujutsu workspace root, or `null` when `cwd` is not in a JJ repository. */
44
72
  root(cwd: string): Promise<string | null>;
45
73
  /** Full Jujutsu workspace metadata. */
@@ -72,3 +100,4 @@ export declare const repo: {
72
100
  * - `false` for directories backed by neither tool.
73
101
  */
74
102
  export declare function isPureJjRepo(cwd: string): Promise<boolean>;
103
+ export {};
@@ -2,6 +2,7 @@
2
2
  * Language id for syntax highlighting and UI (icons, read tool), or undefined if unknown.
3
3
  */
4
4
  export declare function getLanguageFromPath(filePath: string): string | undefined;
5
+ export declare function isMarkdownPath(filePath: string): boolean;
5
6
  /**
6
7
  * LSP language identifier; falls back to `plaintext`.
7
8
  */
@@ -24,6 +24,36 @@ export declare function formatSessionTerminalTitle(sessionName: string | undefin
24
24
  */
25
25
  export declare function setTerminalTitle(title: string): void;
26
26
  export declare function setSessionTerminalTitle(sessionName: string | undefined, cwd?: string): void;
27
+ /**
28
+ * Set a terminal title from an extension's `setTitle()`. Unlike the session base
29
+ * title, this owns the terminal verbatim: the run-state separator will not rewrite
30
+ * it on the next spinner tick or state change. Cleared when the app next sets an
31
+ * authoritative session title via {@link setSessionTerminalTitle}.
32
+ */
33
+ export declare function setExtensionTerminalTitle(title: string): void;
34
+ export type TerminalTitleState = "idle" | "working" | "attention";
35
+ /**
36
+ * Compose the terminal title from the `π` brand, a state-carrying SEPARATOR, and
37
+ * the session label. The brand never gains a prefix glyph — the separator slot
38
+ * expresses the run state instead. Pure (no I/O) so the state→separator contract
39
+ * is unit-testable:
40
+ * - `idle` (user's turn): `π > label` — reads like a prompt awaiting input;
41
+ * - `working`: `π ⠋ label` — spinner frames animate the separator;
42
+ * - `attention`: `π ! label` — agent blocked on the user;
43
+ * - disabled: `π: label` — the pre-state layout.
44
+ * Without a label the separator trails the brand (`π >`) so the state stays visible.
45
+ */
46
+ export declare function buildTerminalTitleWithState(label: string | undefined, state: TerminalTitleState, frame: number, enabled: boolean): string;
47
+ /**
48
+ * Reflect the agent run state in the terminal title's separator: `working`
49
+ * animates spinner frames in the separator slot, `idle` shows `>` (your turn),
50
+ * `attention` shows `!` (agent blocked on you). Gated off by `tui.titleState`.
51
+ */
52
+ export declare function setTerminalTitleState(state: TerminalTitleState): void;
53
+ /** Enable/disable the run-state separator (driven by the `tui.titleState` setting). */
54
+ export declare function setTerminalTitleStateEnabled(enabled: boolean): void;
55
+ /** Stop the spinner timer; call on session/UI teardown. */
56
+ export declare function disposeTerminalTitleState(): void;
27
57
  /**
28
58
  * Save the current terminal title on terminals that support xterm window ops.
29
59
  */