@oh-my-pi/pi-coding-agent 17.1.5 → 17.1.7

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 (244) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/{CHANGELOG-qs3vd6xf.md → CHANGELOG-5k4dq4g6.md} +54 -0
  3. package/dist/cli.js +3342 -3274
  4. package/dist/types/capability/index.d.ts +1 -1
  5. package/dist/types/capability/types.d.ts +23 -1
  6. package/dist/types/config/settings-schema.d.ts +39 -2
  7. package/dist/types/cursor.d.ts +2 -1
  8. package/dist/types/extensibility/extensions/runner.d.ts +4 -0
  9. package/dist/types/extensibility/shared-events.d.ts +18 -1
  10. package/dist/types/internal-urls/mcp-protocol.d.ts +3 -2
  11. package/dist/types/internal-urls/parse.d.ts +12 -0
  12. package/dist/types/internal-urls/router.d.ts +6 -0
  13. package/dist/types/internal-urls/types.d.ts +6 -0
  14. package/dist/types/lsp/config.d.ts +1 -0
  15. package/dist/types/lsp/types.d.ts +2 -0
  16. package/dist/types/mcp/manager.d.ts +5 -0
  17. package/dist/types/mcp/tool-bridge.d.ts +13 -0
  18. package/dist/types/modes/components/custom-editor.d.ts +5 -0
  19. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  20. package/dist/types/modes/rpc/rpc-mode.d.ts +2 -0
  21. package/dist/types/sdk.d.ts +3 -1
  22. package/dist/types/session/agent-session-types.d.ts +8 -6
  23. package/dist/types/session/agent-session.d.ts +28 -1
  24. package/dist/types/session/model-controls.d.ts +4 -1
  25. package/dist/types/session/session-advisors.d.ts +7 -1
  26. package/dist/types/session/session-tools.d.ts +44 -6
  27. package/dist/types/session/streaming-output.d.ts +7 -2
  28. package/dist/types/session/tool-choice-queue.d.ts +6 -4
  29. package/dist/types/session/turn-recovery.d.ts +5 -3
  30. package/dist/types/task/index.d.ts +1 -1
  31. package/dist/types/task/types.d.ts +3 -11
  32. package/dist/types/thinking.d.ts +21 -2
  33. package/dist/types/tools/index.d.ts +8 -3
  34. package/dist/types/tools/output-meta.d.ts +5 -0
  35. package/dist/types/tools/read.d.ts +9 -1
  36. package/dist/types/tools/xdev.d.ts +53 -67
  37. package/dist/types/utils/cpuprofile.d.ts +51 -0
  38. package/dist/types/utils/inspect-image-mode.d.ts +29 -0
  39. package/dist/types/utils/profile-tree.d.ts +47 -0
  40. package/dist/types/utils/sample-profile.d.ts +67 -0
  41. package/dist/types/utils/title-generator.d.ts +17 -16
  42. package/package.json +12 -12
  43. package/src/capability/index.ts +43 -12
  44. package/src/capability/mcp.ts +21 -0
  45. package/src/capability/types.ts +20 -1
  46. package/src/cli/read-cli.ts +44 -2
  47. package/src/config/settings-schema.ts +42 -2
  48. package/src/config/settings.ts +35 -0
  49. package/src/cursor.ts +4 -3
  50. package/src/discovery/builtin-rules/index.ts +2 -0
  51. package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
  52. package/src/eval/py/runner.py +16 -2
  53. package/src/extensibility/extensions/runner.ts +117 -5
  54. package/src/extensibility/extensions/types.ts +0 -1
  55. package/src/extensibility/extensions/wrapper.ts +74 -42
  56. package/src/extensibility/hooks/tool-wrapper.ts +11 -4
  57. package/src/extensibility/hooks/types.ts +0 -1
  58. package/src/extensibility/shared-events.ts +18 -1
  59. package/src/internal-urls/mcp-protocol.ts +17 -3
  60. package/src/internal-urls/parse.ts +31 -0
  61. package/src/internal-urls/router.ts +24 -4
  62. package/src/internal-urls/types.ts +6 -0
  63. package/src/live/transport.ts +2 -2
  64. package/src/lsp/client.ts +2 -2
  65. package/src/lsp/config.ts +4 -0
  66. package/src/lsp/types.ts +2 -0
  67. package/src/mcp/config.ts +26 -14
  68. package/src/mcp/manager.ts +26 -9
  69. package/src/mcp/tool-bridge.ts +52 -1
  70. package/src/memories/index.ts +25 -6
  71. package/src/modes/components/custom-editor.ts +39 -16
  72. package/src/modes/components/status-line/segments.ts +3 -1
  73. package/src/modes/components/tips.txt +2 -1
  74. package/src/modes/components/tool-execution.ts +8 -7
  75. package/src/modes/controllers/command-controller.ts +10 -10
  76. package/src/modes/controllers/extension-ui-controller.ts +7 -7
  77. package/src/modes/controllers/selector-controller.ts +7 -2
  78. package/src/modes/rpc/rpc-mode.ts +60 -47
  79. package/src/prompts/steering/user-interjection.md +2 -5
  80. package/src/prompts/tools/task.md +4 -2
  81. package/src/sdk.ts +64 -58
  82. package/src/session/agent-session-types.ts +8 -5
  83. package/src/session/agent-session.ts +144 -11
  84. package/src/session/model-controls.ts +48 -12
  85. package/src/session/session-advisors.ts +30 -14
  86. package/src/session/session-listing.ts +66 -4
  87. package/src/session/session-tools.ts +162 -54
  88. package/src/session/streaming-output.ts +18 -6
  89. package/src/session/tool-choice-queue.ts +19 -4
  90. package/src/session/turn-recovery.ts +25 -6
  91. package/src/slash-commands/builtin-registry.ts +69 -0
  92. package/src/task/executor.ts +11 -3
  93. package/src/task/index.ts +43 -32
  94. package/src/task/types.ts +12 -17
  95. package/src/thinking.ts +68 -5
  96. package/src/tools/bash.ts +16 -9
  97. package/src/tools/index.ts +36 -16
  98. package/src/tools/output-meta.ts +20 -0
  99. package/src/tools/read.ts +89 -15
  100. package/src/tools/write.ts +16 -7
  101. package/src/tools/xdev.ts +198 -210
  102. package/src/utils/cpuprofile.ts +235 -0
  103. package/src/utils/inspect-image-mode.ts +39 -0
  104. package/src/utils/profile-tree.ts +111 -0
  105. package/src/utils/sample-profile.ts +437 -0
  106. package/src/utils/title-generator.ts +88 -34
  107. package/dist/types/advisor/__tests__/advisor.test.d.ts +0 -1
  108. package/dist/types/advisor/__tests__/config.test.d.ts +0 -1
  109. package/dist/types/advisor/__tests__/emission-guard.test.d.ts +0 -1
  110. package/dist/types/cli/__tests__/auth-gateway-catalog.test.d.ts +0 -1
  111. package/dist/types/cli/update-cli.test.d.ts +0 -1
  112. package/dist/types/config/__tests__/model-registry.test.d.ts +0 -1
  113. package/dist/types/eval/__tests__/agent-bridge.test.d.ts +0 -1
  114. package/dist/types/eval/__tests__/bridge-timeout.test.d.ts +0 -1
  115. package/dist/types/eval/__tests__/budget-bridge.test.d.ts +0 -1
  116. package/dist/types/eval/__tests__/completion-bridge.test.d.ts +0 -1
  117. package/dist/types/eval/__tests__/helpers-local-roots.test.d.ts +0 -1
  118. package/dist/types/eval/__tests__/idle-timeout.test.d.ts +0 -1
  119. package/dist/types/eval/__tests__/js-context-manager.test.d.ts +0 -1
  120. package/dist/types/eval/__tests__/julia-prelude.test.d.ts +0 -1
  121. package/dist/types/eval/__tests__/kernel-spawn.test.d.ts +0 -1
  122. package/dist/types/eval/__tests__/prelude-agent.test.d.ts +0 -1
  123. package/dist/types/eval/__tests__/process-entry-import.test.d.ts +0 -1
  124. package/dist/types/eval/py/__tests__/prelude.test.d.ts +0 -1
  125. package/dist/types/eval/py/__tests__/runner-shell-output.test.d.ts +0 -1
  126. package/dist/types/hindsight/client.test.d.ts +0 -1
  127. package/dist/types/internal-urls/__tests__/agent-protocol-nested.test.d.ts +0 -1
  128. package/dist/types/internal-urls/__tests__/ssh-protocol.test.d.ts +0 -1
  129. package/dist/types/launch/broker-list-order.test.d.ts +0 -1
  130. package/dist/types/launch/broker-output-snapshot.test.d.ts +0 -1
  131. package/dist/types/launch/protocol.test.d.ts +0 -1
  132. package/dist/types/launch/spawn-options.test.d.ts +0 -1
  133. package/dist/types/launch/terminal-output.test.d.ts +0 -1
  134. package/dist/types/live/protocol.test.d.ts +0 -1
  135. package/dist/types/mcp/config-writer.test.d.ts +0 -1
  136. package/dist/types/mcp/smithery-auth.test.d.ts +0 -1
  137. package/dist/types/mcp/smithery-registry.test.d.ts +0 -1
  138. package/dist/types/mcp/transports/stdio.test.d.ts +0 -1
  139. package/dist/types/modes/components/__tests__/dynamic-border.test.d.ts +0 -1
  140. package/dist/types/modes/components/__tests__/move-overlay.test.d.ts +0 -1
  141. package/dist/types/modes/components/__tests__/pause-screen.test.d.ts +0 -1
  142. package/dist/types/modes/components/__tests__/skill-message.test.d.ts +0 -1
  143. package/dist/types/modes/components/custom-editor-plugin-ctor.test.d.ts +0 -1
  144. package/dist/types/modes/components/custom-editor.test.d.ts +0 -1
  145. package/dist/types/modes/components/login-dialog.test.d.ts +0 -1
  146. package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +0 -1
  147. package/dist/types/modes/components/status-line/component.test.d.ts +0 -1
  148. package/dist/types/modes/components/tool-execution.test.d.ts +0 -1
  149. package/dist/types/modes/controllers/extension-ui-controller.test.d.ts +0 -1
  150. package/dist/types/modes/noninteractive-dispose.test.d.ts +0 -1
  151. package/dist/types/modes/print-mode.test.d.ts +0 -1
  152. package/dist/types/modes/session-teardown.test.d.ts +0 -1
  153. package/dist/types/modes/theme/mermaid-rendering.test.d.ts +0 -1
  154. package/dist/types/modes/utils/transcript-render-helpers.test.d.ts +0 -1
  155. package/dist/types/modes/warp-events.test.d.ts +0 -1
  156. package/dist/types/plan-mode/approved-plan-prompt.test.d.ts +0 -1
  157. package/dist/types/plan-mode/model-transition.test.d.ts +0 -1
  158. package/dist/types/plan-mode/reentry-prompt.test.d.ts +0 -1
  159. package/dist/types/session/agent-session-error-log.test.d.ts +0 -1
  160. package/dist/types/session/blob-store.test.d.ts +0 -1
  161. package/dist/types/session/messages.test.d.ts +0 -1
  162. package/dist/types/session/session-context.test.d.ts +0 -1
  163. package/dist/types/ssh/__tests__/connection-manager-args.test.d.ts +0 -1
  164. package/dist/types/ssh/__tests__/connection-manager-timeout.test.d.ts +0 -1
  165. package/dist/types/ssh/__tests__/file-transfer-posix-guard.test.d.ts +0 -1
  166. package/dist/types/ssh/__tests__/sshfs-mount.test.d.ts +0 -1
  167. package/dist/types/system-prompt.test.d.ts +0 -1
  168. package/dist/types/task/render.test.d.ts +0 -1
  169. package/dist/types/task/spawn-policy.test.d.ts +0 -1
  170. package/dist/types/tools/__tests__/eval-description.test.d.ts +0 -1
  171. package/dist/types/tools/__tests__/glob.test.d.ts +0 -1
  172. package/dist/types/tools/__tests__/json-tree.test.d.ts +0 -1
  173. package/dist/types/tools/__tests__/vibe-render.test.d.ts +0 -1
  174. package/dist/types/tools/hub/launch-compat.test.d.ts +0 -1
  175. package/dist/types/vibe/__tests__/token-rate.test.d.ts +0 -1
  176. package/src/advisor/__tests__/advisor.test.ts +0 -4889
  177. package/src/advisor/__tests__/config.test.ts +0 -349
  178. package/src/advisor/__tests__/emission-guard.test.ts +0 -147
  179. package/src/cli/__tests__/auth-gateway-catalog.test.ts +0 -111
  180. package/src/cli/update-cli.test.ts +0 -28
  181. package/src/config/__tests__/model-registry.test.ts +0 -182
  182. package/src/eval/__tests__/agent-bridge.test.ts +0 -1509
  183. package/src/eval/__tests__/bridge-timeout.test.ts +0 -170
  184. package/src/eval/__tests__/budget-bridge.test.ts +0 -80
  185. package/src/eval/__tests__/completion-bridge.test.ts +0 -412
  186. package/src/eval/__tests__/helpers-local-roots.test.ts +0 -55
  187. package/src/eval/__tests__/idle-timeout.test.ts +0 -80
  188. package/src/eval/__tests__/js-context-manager.test.ts +0 -456
  189. package/src/eval/__tests__/julia-prelude.test.ts +0 -66
  190. package/src/eval/__tests__/kernel-spawn.test.ts +0 -115
  191. package/src/eval/__tests__/prelude-agent.test.ts +0 -156
  192. package/src/eval/__tests__/process-entry-import.test.ts +0 -137
  193. package/src/eval/py/__tests__/prelude.test.ts +0 -104
  194. package/src/eval/py/__tests__/runner-shell-output.test.ts +0 -157
  195. package/src/hindsight/client.test.ts +0 -75
  196. package/src/internal-urls/__tests__/agent-protocol-nested.test.ts +0 -141
  197. package/src/internal-urls/__tests__/ssh-protocol.test.ts +0 -331
  198. package/src/launch/broker-list-order.test.ts +0 -89
  199. package/src/launch/broker-output-snapshot.test.ts +0 -126
  200. package/src/launch/protocol.test.ts +0 -59
  201. package/src/launch/spawn-options.test.ts +0 -31
  202. package/src/launch/terminal-output.test.ts +0 -107
  203. package/src/live/protocol.test.ts +0 -140
  204. package/src/mcp/config-writer.test.ts +0 -43
  205. package/src/mcp/smithery-auth.test.ts +0 -29
  206. package/src/mcp/smithery-registry.test.ts +0 -51
  207. package/src/mcp/transports/stdio.test.ts +0 -427
  208. package/src/modes/components/__tests__/dynamic-border.test.ts +0 -55
  209. package/src/modes/components/__tests__/move-overlay.test.ts +0 -252
  210. package/src/modes/components/__tests__/pause-screen.test.ts +0 -143
  211. package/src/modes/components/__tests__/skill-message.test.ts +0 -94
  212. package/src/modes/components/custom-editor-plugin-ctor.test.ts +0 -36
  213. package/src/modes/components/custom-editor.test.ts +0 -510
  214. package/src/modes/components/login-dialog.test.ts +0 -56
  215. package/src/modes/components/status-line/component.jj-cache.test.ts +0 -229
  216. package/src/modes/components/status-line/component.test.ts +0 -84
  217. package/src/modes/components/tool-execution.test.ts +0 -162
  218. package/src/modes/controllers/extension-ui-controller.test.ts +0 -250
  219. package/src/modes/noninteractive-dispose.test.ts +0 -73
  220. package/src/modes/print-mode.test.ts +0 -71
  221. package/src/modes/session-teardown.test.ts +0 -219
  222. package/src/modes/theme/mermaid-rendering.test.ts +0 -53
  223. package/src/modes/utils/transcript-render-helpers.test.ts +0 -38
  224. package/src/modes/warp-events.test.ts +0 -794
  225. package/src/plan-mode/approved-plan-prompt.test.ts +0 -36
  226. package/src/plan-mode/model-transition.test.ts +0 -60
  227. package/src/plan-mode/reentry-prompt.test.ts +0 -41
  228. package/src/session/agent-session-error-log.test.ts +0 -59
  229. package/src/session/blob-store.test.ts +0 -56
  230. package/src/session/messages.test.ts +0 -282
  231. package/src/session/session-context.test.ts +0 -384
  232. package/src/ssh/__tests__/connection-manager-args.test.ts +0 -191
  233. package/src/ssh/__tests__/connection-manager-timeout.test.ts +0 -61
  234. package/src/ssh/__tests__/file-transfer-posix-guard.test.ts +0 -105
  235. package/src/ssh/__tests__/sshfs-mount.test.ts +0 -13
  236. package/src/system-prompt.test.ts +0 -236
  237. package/src/task/render.test.ts +0 -290
  238. package/src/task/spawn-policy.test.ts +0 -62
  239. package/src/tools/__tests__/eval-description.test.ts +0 -18
  240. package/src/tools/__tests__/glob.test.ts +0 -37
  241. package/src/tools/__tests__/json-tree.test.ts +0 -35
  242. package/src/tools/__tests__/vibe-render.test.ts +0 -210
  243. package/src/tools/hub/launch-compat.test.ts +0 -40
  244. package/src/vibe/__tests__/token-rate.test.ts +0 -96
@@ -11,7 +11,7 @@ export declare function registerProvider<T>(capabilityId: string, provider: Prov
11
11
  /**
12
12
  * Load a capability by ID.
13
13
  */
14
- export declare function loadCapability<T>(capabilityId: string, options?: LoadOptions): Promise<CapabilityResult<T>>;
14
+ export declare function loadCapability<T>(capabilityId: string, options?: LoadOptions<T>): Promise<CapabilityResult<T>>;
15
15
  /**
16
16
  * Initialize capability system with settings manager for persistence.
17
17
  * Call this once on startup to enable persistent provider state.
@@ -51,7 +51,7 @@ export interface Provider<T> {
51
51
  /**
52
52
  * Options for loading a capability.
53
53
  */
54
- export interface LoadOptions {
54
+ export interface LoadOptions<T = unknown> {
55
55
  /** Only use these providers (by ID). Default: all registered */
56
56
  providers?: string[];
57
57
  /** Exclude these providers (by ID). Default: none */
@@ -64,6 +64,26 @@ export interface LoadOptions {
64
64
  includeDisabled?: boolean;
65
65
  /** Explicit disabled extension IDs to apply instead of settings. */
66
66
  disabledExtensions?: string[];
67
+ /**
68
+ * Drop items before deduplication as if they never existed (e.g. scope
69
+ * exclusions). A dropped item neither survives nor claims its dedupe key,
70
+ * so it cannot shadow anything. Receives the item with its attached
71
+ * `_source`.
72
+ */
73
+ filter?(item: T & {
74
+ _source: SourceMeta;
75
+ }): boolean;
76
+ /**
77
+ * Exclude items from the results while letting them claim their dedupe key.
78
+ * A suppressed higher-priority item still shadows same-key lower-priority
79
+ * items (a disabled project server keeps the same-named user server off),
80
+ * but never equivalence-shadows a differently-keyed survivor — so a
81
+ * suppressed alias cannot starve an enabled equivalent connection.
82
+ * Return `true` to suppress. Receives the item with its attached `_source`.
83
+ */
84
+ suppress?(item: T & {
85
+ _source: SourceMeta;
86
+ }): boolean;
67
87
  }
68
88
  /**
69
89
  * Source metadata attached to every loaded item.
@@ -112,6 +132,8 @@ export interface Capability<T> {
112
132
  * Return undefined to never deduplicate (all items kept).
113
133
  */
114
134
  key(item: T): string | undefined;
135
+ /** Treat items with different keys as aliases; the first equivalent item wins. */
136
+ equivalent?(left: T, right: T): boolean;
115
137
  /**
116
138
  * Optional validation. Return error message if invalid, undefined if valid.
117
139
  */
@@ -846,7 +846,7 @@ export declare const SETTINGS_SCHEMA: {
846
846
  readonly tab: "appearance";
847
847
  readonly group: "Display";
848
848
  readonly label: "Terminal Title Run State";
849
- readonly description: "Show the agent run state in the terminal title's separator — an animated spinner while working, '>' when it's your turn, '!' when the agent is waiting on you";
849
+ readonly description: "Show the agent run state in the terminal title's separator — an animated spinner while working (a static ':' on Windows), '>' when it's your turn, '!' when the agent is waiting on you";
850
850
  };
851
851
  };
852
852
  readonly "tui.hyperlinks": {
@@ -3941,11 +3941,26 @@ export declare const SETTINGS_SCHEMA: {
3941
3941
  readonly "inspect_image.enabled": {
3942
3942
  readonly type: "boolean";
3943
3943
  readonly default: false;
3944
+ };
3945
+ readonly "inspect_image.mode": {
3946
+ readonly type: "enum";
3947
+ readonly values: readonly ["auto", "on", "off"];
3948
+ readonly default: "auto";
3944
3949
  readonly ui: {
3945
3950
  readonly tab: "tools";
3946
3951
  readonly group: "Available Tools";
3947
3952
  readonly label: "Inspect Image";
3948
- readonly description: "Enable the inspect_image tool, delegating image understanding to a vision-capable model";
3953
+ readonly description: "Controls the inspect_image tool, which delegates image understanding to a vision-capable model. 'auto' exposes it only when the active model lacks native image input; 'on' always exposes it; 'off' never does.";
3954
+ readonly options: readonly [{
3955
+ readonly value: "auto";
3956
+ readonly label: "Auto (only for models without vision)";
3957
+ }, {
3958
+ readonly value: "on";
3959
+ readonly label: "On";
3960
+ }, {
3961
+ readonly value: "off";
3962
+ readonly label: "Off";
3963
+ }];
3949
3964
  };
3950
3965
  };
3951
3966
  readonly "computer.enabled": {
@@ -4577,6 +4592,16 @@ export declare const SETTINGS_SCHEMA: {
4577
4592
  readonly description: "Switch the task tool to its batch shape: one call carries { context, tasks[] } — one subagent per item, with an optional per-item agent (defaulting to the session spawn-policy agent), per-item isolation, and a required shared context prepended to every assignment. With async.enabled=true, each spawn runs as an independent background agent with the normal idle/parked lifecycle; otherwise the call blocks for merged results. Disable to restore the flat single-spawn schema.";
4578
4593
  };
4579
4594
  };
4595
+ readonly "task.enableEffort": {
4596
+ readonly type: "boolean";
4597
+ readonly default: false;
4598
+ readonly ui: {
4599
+ readonly tab: "tasks";
4600
+ readonly group: "Subagents";
4601
+ readonly label: "Per-Task Effort";
4602
+ readonly description: "Expose the optional effort parameter on task spawns, allowing callers to override each subagent's thinking level";
4603
+ };
4604
+ };
4580
4605
  readonly "task.maxConcurrency": {
4581
4606
  readonly type: "number";
4582
4607
  readonly default: 32;
@@ -4719,6 +4744,18 @@ export declare const SETTINGS_SCHEMA: {
4719
4744
  readonly description: "Inject one steering notice when a subagent crosses its soft request budget, asking it to wrap up before the 1.5x forced-yield stop.";
4720
4745
  };
4721
4746
  };
4747
+ readonly "task.maxEffort": {
4748
+ readonly type: "enum";
4749
+ readonly values: readonly import("@oh-my-pi/pi-catalog").Effort[];
4750
+ readonly default: "max";
4751
+ readonly ui: {
4752
+ readonly tab: "tasks";
4753
+ readonly group: "Subagents";
4754
+ readonly label: "Maximum Per-Spawn Effort";
4755
+ readonly description: "Maximum reasoning effort allowed for the task tool's per-spawn effort hint. Lower values prevent callers from escalating subagents above this ceiling; the default preserves the model's full range.";
4756
+ readonly options: import("../thinking.js").ThinkingLevelMetadata[];
4757
+ };
4758
+ };
4722
4759
  readonly "task.disabledAgents": {
4723
4760
  readonly type: "array";
4724
4761
  readonly default: string[];
@@ -5,7 +5,8 @@ interface CursorExecBridgeOptions {
5
5
  cwd: string;
6
6
  getCwd?: () => string;
7
7
  tools: Map<string, AgentTool>;
8
- getTool?: (name: string) => AgentTool | undefined;
8
+ /** Resolves execution overrides (mounted-device permission wrappers) before the canonical map. */
9
+ getExecutableTool?: (name: string) => AgentTool | undefined;
9
10
  getToolContext?: () => AgentToolContext | undefined;
10
11
  emitEvent?: (event: AgentEvent) => void;
11
12
  /**
@@ -69,6 +69,10 @@ export declare class ExtensionRunner {
69
69
  private readonly modelRegistry;
70
70
  private readonly settings?;
71
71
  private readonly localProtocolOptions?;
72
+ /** Records that the loop already emitted `tool_call` for this dispatch. */
73
+ markToolCallEmitted(toolCallId: string, toolName: string): void;
74
+ /** Consumes a {@link markToolCallEmitted} marker; true when the loop already emitted. */
75
+ consumeToolCallEmitted(toolCallId: string, toolName: string): boolean;
72
76
  constructor(extensions: Extension[], runtime: ExtensionRuntime, cwd: string, sessionManager: SessionManager, modelRegistry: ModelRegistry, getMemory?: () => MemoryRuntimeContext | undefined, settings?: Settings | undefined, localProtocolOptions?: LocalProtocolOptions | undefined);
73
77
  initialize(actions: ExtensionActions, contextActions: ExtensionContextActions, commandContextActions?: ExtensionCommandContextActions, uiContext?: ExtensionUIContext): void;
74
78
  /**
@@ -228,13 +228,30 @@ export interface TodoReminderEvent {
228
228
  }
229
229
  /**
230
230
  * Return type for `tool_call` handlers.
231
- * Allows handlers to block tool execution.
231
+ * Allows handlers to block tool execution or revise the input the tool runs with.
232
232
  */
233
233
  export interface ToolCallEventResult {
234
234
  /** If true, block the tool from executing */
235
235
  block?: boolean;
236
236
  /** Reason for blocking (returned to LLM as error) */
237
237
  reason?: string;
238
+ /**
239
+ * Replacement input the tool executes with, instead of the original arguments. Ignored when
240
+ * `block` is true. This is the raw execution input passed to the tool's `execute` (the handler
241
+ * owns its correctness) — not the normalized `event.input` view, which may carry derived
242
+ * gate-only fields (e.g. hashline `edit` `path`/`paths`) that are not real parameters. When
243
+ * multiple handlers set `input`, the last one wins; handlers do not observe each other's
244
+ * revisions (each sees the original `event.input`). Not applied to `computer` tool calls.
245
+ *
246
+ * For model-issued tool calls the event fires at arg-prep time in the agent loop, before
247
+ * concurrency scheduling, `tool_execution_start`, and the approval gate: the revision is
248
+ * revalidated against the tool schema and becomes what the loop schedules, displays, persists,
249
+ * and executes — the user always approves what actually runs. For dispatches the loop never
250
+ * sees (nested `write xd://` device calls, Cursor direct execution) the tool wrapper applies
251
+ * the revision before its own approval gate; a revised nested xd:// input forfeits the outer
252
+ * write gate's approval and faces the full prompt again.
253
+ */
254
+ input?: Record<string, unknown>;
238
255
  }
239
256
  /**
240
257
  * Return type for `tool_result` handlers.
@@ -1,9 +1,10 @@
1
1
  import type { InternalResource, InternalUrl, ProtocolHandler } from "./types.js";
2
2
  /**
3
- * Protocol handler for mcp:// URLs.
3
+ * Protocol handler for MCP resources.
4
4
  *
5
- * URL form:
5
+ * URL forms:
6
6
  * - mcp://<resource-uri> (e.g. mcp://test://notes, mcp://ibkr://portfolio/positions)
7
+ * - A resource's native URI when its scheme has no OMP handler (e.g. ags://capabilities/current-host)
7
8
  */
8
9
  export declare class McpProtocolHandler implements ProtocolHandler {
9
10
  readonly scheme = "mcp";
@@ -10,6 +10,18 @@
10
10
  * MUST use this function instead of calling `new URL()` directly.
11
11
  */
12
12
  import type { InternalUrl } from "./types.js";
13
+ /**
14
+ * Extract the lowercased scheme from a URI-shaped input, or `undefined` when
15
+ * the input does not look like a URI.
16
+ *
17
+ * Accepts both hierarchical (`scheme://…`) and opaque (`scheme:rest`) forms —
18
+ * MCP resource URIs may be opaque (`urn:example:document`, `custom:item`).
19
+ * The opaque form is guarded against path-like false positives:
20
+ * - Windows drive paths (`C:\…`, `C:/…`, `C:foo`) — single-letter scheme.
21
+ * - Filenames with extensions (`foo.ts:50`) — dot in the scheme segment.
22
+ * - Read-tool selector tails (`Makefile:12`, `README:raw:1-20`).
23
+ */
24
+ export declare function extractUriScheme(input: string): string | undefined;
13
25
  /**
14
26
  * Parse an internal URL into an InternalUrl.
15
27
  *
@@ -10,6 +10,12 @@ export declare class InternalUrlRouter {
10
10
  unregister(scheme: string): boolean;
11
11
  getHandler(scheme: string): ProtocolHandler | undefined;
12
12
  canHandle(input: string): boolean;
13
+ /**
14
+ * Whether read can resolve this URL through either a native handler or the
15
+ * MCP resource fallback. MCP resources may use arbitrary custom schemes and
16
+ * may be opaque (`urn:example:document`) rather than hierarchical.
17
+ */
18
+ canResolve(input: string): boolean;
13
19
  /** Schemes whose handler supports host/path autocomplete. */
14
20
  completionSchemes(): string[];
15
21
  /**
@@ -66,6 +66,12 @@ export interface InternalUrl extends URL {
66
66
  * Raw pathname extracted from input, preserving traversal markers before URL normalization.
67
67
  */
68
68
  rawPathname?: string;
69
+ /**
70
+ * Exact input string this URL was parsed from, before any normalization.
71
+ * Set by `parseInternalUrl`; used where byte-exact URI matching matters
72
+ * (e.g. MCP resource URIs compared by string equality).
73
+ */
74
+ rawHref?: string;
69
75
  }
70
76
  /**
71
77
  * Caller-supplied context that the router threads into protocol handlers.
@@ -52,6 +52,7 @@ export declare function resolveCommand(command: string, cwd: string, options?: R
52
52
  * "command": "/path/to/server",
53
53
  * "args": ["--stdio"],
54
54
  * "fileTypes": [".xyz"],
55
+ * "languageId": "xyz",
55
56
  * "rootMarkers": [".xyz-project"]
56
57
  * }
57
58
  * }
@@ -200,6 +200,8 @@ export interface ServerConfig {
200
200
  command: string;
201
201
  args?: string[];
202
202
  fileTypes: string[];
203
+ /** LSP language identifier sent in didOpen; inferred from the file path when omitted. */
204
+ languageId?: string;
203
205
  rootMarkers: string[];
204
206
  initOptions?: Record<string, unknown>;
205
207
  settings?: Record<string, unknown>;
@@ -174,6 +174,11 @@ export declare class MCPManager {
174
174
  * Refresh resources from a specific server.
175
175
  */
176
176
  refreshServerResources(name: string): Promise<void>;
177
+ /**
178
+ * Wait until a connected server's resource catalog has been loaded.
179
+ * Coalesces with initial loading and notification-driven refreshes.
180
+ */
181
+ ensureServerResources(name: string): Promise<void>;
177
182
  /**
178
183
  * Refresh prompts from a specific server.
179
184
  */
@@ -35,6 +35,19 @@ export interface MCPToolDetails {
35
35
  meta?: OutputMeta;
36
36
  }
37
37
  export declare function createMCPToolName(serverName: string, toolName: string): string;
38
+ /**
39
+ * Keeps one MCP tool per minted name and logs collisions between distinct MCP
40
+ * origins. The winner is chosen by a stable origin key (server name + original
41
+ * tool name), NOT array order: MCPManager re-appends a reconnecting server's
42
+ * tools, so insertion order is mutable across reconnects and first-wins would
43
+ * silently flip ownership of the minted name. Non-MCP tools pass through
44
+ * unchanged.
45
+ */
46
+ export declare function deduplicateMCPToolsByName<T extends {
47
+ name: string;
48
+ mcpServerName?: unknown;
49
+ mcpToolName?: unknown;
50
+ }>(tools: readonly T[]): T[];
38
51
  /**
39
52
  * Parse an MCP tool name back to server and tool components.
40
53
  *
@@ -103,6 +103,11 @@ export declare class CustomEditor extends Editor {
103
103
  * reset the editor text and all pending draft-image state. The shared tail of
104
104
  * every "message submitted" path; pass no argument for a plain discard. */
105
105
  clearDraft(historyText?: string): void;
106
+ /** Replace the composer draft with a restored historical prompt: sets the text and
107
+ * re-attaches the message's images so positional `[Image #N]` markers resolve on
108
+ * resubmit instead of degrading to literal text (esc-esc branch, `/tree`). Source
109
+ * links are unknown for restored drafts, so every link slot is `undefined`. */
110
+ setDraft(text: string, images?: readonly ImageContent[]): void;
106
111
  /** Treat image/paste markers as indivisible: a stray backspace deletes the whole token
107
112
  * instead of corrupting `[Paste #1, +30 lines]` into plain text. */
108
113
  atomicTokenPattern: RegExp;
@@ -54,7 +54,7 @@ export declare class ExtensionUiController {
54
54
  /**
55
55
  * Show a confirmation dialog for hooks.
56
56
  */
57
- showHookConfirm(title: string, message: string): Promise<boolean>;
57
+ showHookConfirm(title: string, message: string, dialogOptions?: ExtensionUIDialogOptions): Promise<boolean>;
58
58
  /**
59
59
  * Show a text input for hooks.
60
60
  */
@@ -158,6 +158,8 @@ export declare function handleRpcSessionChange(session: RpcSessionChangeSession,
158
158
  export declare function requestRpcEditor(pendingRequests: Map<string, PendingExtensionRequest>, output: RpcOutput, title: string, prefill?: string, dialogOptions?: ExtensionUIDialogOptions, editorOptions?: {
159
159
  promptStyle?: boolean;
160
160
  }): Promise<string | undefined>;
161
+ /** Sends an RPC extension dialog and cancels the remote presentation when its signal aborts. */
162
+ export declare function requestRpcDialog<T>(pendingRequests: Map<string, PendingExtensionRequest>, output: RpcOutput, opts: ExtensionUIDialogOptions | undefined, defaultValue: T, request: Record<string, unknown>, parseResponse: (response: RpcExtensionUIResponse) => T): Promise<T>;
161
163
  /**
162
164
  * Run in RPC mode.
163
165
  * Listens for JSON commands on stdin, outputs events and responses on stdout.
@@ -1,5 +1,5 @@
1
1
  import { Agent, type AgentOptions, type AgentTelemetryConfig, type AgentTool, type ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import type { Model, SimpleStreamOptions } from "@oh-my-pi/pi-ai";
2
+ import type { Effort, Model, SimpleStreamOptions } from "@oh-my-pi/pi-ai";
3
3
  import type { Dialect } from "@oh-my-pi/pi-ai/dialect";
4
4
  import { type Rule } from "./capability/rule.js";
5
5
  import { ModelRegistry } from "./config/model-registry.js";
@@ -52,6 +52,8 @@ export interface CreateAgentSessionOptions {
52
52
  modelPatternDefaultFallbackChain?: string[];
53
53
  /** Thinking selector. Default: from settings, else unset */
54
54
  thinkingLevel?: ConfiguredThinkingLevel;
55
+ /** Hard ceiling on the session's thinking effort (e.g. a task spawn's `task.maxEffort`-capped hint); retry-fallback recovery re-clamps to it. */
56
+ thinkingLevelCeiling?: Effort;
55
57
  /** Models available for cycling (Ctrl+P in interactive mode) */
56
58
  scopedModels?: Array<{
57
59
  model: Model;
@@ -1,5 +1,5 @@
1
1
  import type { Agent, AgentMessage, AgentTool, StreamFn, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
- import type { Context, ImageContent, Message, MessageAttribution, Model, OAuthAccountSummary, ServiceTierByFamily, SimpleStreamOptions, ToolChoice } from "@oh-my-pi/pi-ai";
2
+ import type { Context, Effort, ImageContent, Message, MessageAttribution, Model, OAuthAccountSummary, ServiceTierByFamily, SimpleStreamOptions, ToolChoice } from "@oh-my-pi/pi-ai";
3
3
  import type { postmortem } from "@oh-my-pi/pi-utils";
4
4
  import type { AdvisorConfig } from "../advisor/index.js";
5
5
  import type { AsyncJob, AsyncJobDeliveryState, AsyncJobManager } from "../async/index.js";
@@ -15,7 +15,7 @@ import type { Skill, SkillWarning } from "../extensibility/skills.js";
15
15
  import type { FileSlashCommand } from "../extensibility/slash-commands.js";
16
16
  import type { SecretObfuscator } from "../secrets/obfuscator.js";
17
17
  import type { ConfiguredThinkingLevel } from "../thinking.js";
18
- import type { XdevRegistry } from "../tools/xdev.js";
18
+ import type { XdevState } from "../tools/xdev.js";
19
19
  import type { SessionManager } from "./session-manager.js";
20
20
  /** Maximum time the interactive shutdown path waits for Mnemopi consolidation. */
21
21
  export declare const SHUTDOWN_CONSOLIDATE_BUDGET_MS = 1500;
@@ -88,6 +88,8 @@ export interface AgentSessionConfig {
88
88
  }>;
89
89
  /** Initial session thinking selector. */
90
90
  thinkingLevel?: ConfiguredThinkingLevel;
91
+ /** Hard ceiling on the session's thinking effort (e.g. a task spawn's `task.maxEffort`-capped hint); every later change, including retry-fallback recovery, is re-clamped to it. */
92
+ thinkingLevelCeiling?: Effort;
91
93
  /** Retry chain ownership when startup selected one of its fallback entries. */
92
94
  initialRetryFallback?: InitialRetryFallbackState;
93
95
  /** Prewalk from the starting model to a fast/cheap target after implementation begins. */
@@ -119,6 +121,8 @@ export interface AgentSessionConfig {
119
121
  createMemoryTools?: () => Promise<AgentTool[]>;
120
122
  /** Creates the built-in `computer` tool for session-scoped runtime enablement (see {@link AgentSession.setComputerToolEnabled}). */
121
123
  createComputerTool?: () => Promise<AgentTool | null>;
124
+ /** Creates the built-in `inspect_image` tool for session-scoped runtime enablement (see {@link AgentSession.setInspectImageMode}). */
125
+ createInspectImageTool?: () => Promise<AgentTool | null>;
122
126
  /** Model registry for API key resolution and model discovery. */
123
127
  modelRegistry: ModelRegistry;
124
128
  /** Tool registry for LSP and settings. */
@@ -162,10 +166,8 @@ export interface AgentSessionConfig {
162
166
  name: string;
163
167
  summary: string;
164
168
  }>;
165
- /** Session-owned `xd://` registry. */
166
- xdevRegistry?: XdevRegistry;
167
- /** Discoverable tools mounted under `xd://` in the initial enabled set. */
168
- initialMountedXdevToolNames?: string[];
169
+ /** `xd://` presentation state backed by the canonical tool map. */
170
+ xdev?: XdevState;
169
171
  /** Names pinned top-level during runtime repartitioning. */
170
172
  presentationPinnedToolNames?: ReadonlySet<string>;
171
173
  /** Accessor for live MCP server instructions. */
@@ -46,6 +46,7 @@ import { type AskToolDetails, type AskToolInput } from "../tools/ask.js";
46
46
  import type { CheckpointState, CompletedRewindState } from "../tools/checkpoint.js";
47
47
  import { type PlanProposalHandler } from "../tools/resolve.js";
48
48
  import type { TodoPhase } from "../tools/todo.js";
49
+ import type { InspectImageMode } from "../utils/inspect-image-mode.js";
49
50
  import type { VibeModeState } from "../vibe/state.js";
50
51
  import type { AgentSessionEventListener } from "./agent-session-events.js";
51
52
  import type { AgentSessionConfig, AgentSessionDisposeOptions, AsyncJobSnapshot, CommandMetadataChangedListener, ContextUsageBreakdown, FollowUpOptions, FreshSessionResult, HandoffResult, ModelCycleResult, Prewalk, PromptOptions, ResolvedRoleModel, RestoredQueuedMessage, RoleModelCycle, RoleModelCycleResult, SessionHandoffOptions, SessionOAuthAccountList, SessionStats, UsageFallbackConfirmation } from "./agent-session-types.js";
@@ -283,6 +284,26 @@ export declare class AgentSession {
283
284
  * tool (e.g. restricted child sessions have no factory).
284
285
  */
285
286
  setComputerToolEnabled(enabled: boolean): Promise<boolean>;
287
+ /**
288
+ * Session-scoped inspect_image mode (`/vision`). `auto` clears the override
289
+ * and returns to the persisted `inspect_image.mode` setting; `on`/`off`
290
+ * force the tool for this session only. See {@link SessionTools.setInspectImageMode}.
291
+ */
292
+ setInspectImageMode(mode: InspectImageMode): Promise<boolean>;
293
+ /** Effective inspect_image state for `/vision status`. */
294
+ inspectImageState(): {
295
+ mode: InspectImageMode;
296
+ active: boolean;
297
+ model: string | undefined;
298
+ };
299
+ /** Session-scoped `/vision` override; undefined means "follow the persisted setting". */
300
+ getInspectImageModeOverride(): InspectImageMode | undefined;
301
+ /**
302
+ * Reconciles the inspect_image tool set after the persisted
303
+ * `inspect_image.mode` setting changed (e.g. via the settings selector), so
304
+ * the new value takes effect immediately instead of on the next model switch.
305
+ */
306
+ applyInspectImageModeChange(): Promise<boolean>;
286
307
  /** Cancels the local rollout-memory startup owned by this session. */
287
308
  cancelLocalMemoryStartup(): void;
288
309
  /** Starts a new local rollout-memory generation and cancels its predecessor. */
@@ -766,10 +787,12 @@ export declare class AgentSession {
766
787
  * @param entryId ID of the entry to branch from
767
788
  * @returns Object with:
768
789
  * - selectedText: The text of the selected user message (for editor pre-fill)
790
+ * - selectedImages: Image attachments of the selected user message (for editor draft restore)
769
791
  * - cancelled: True if a hook cancelled the branch
770
792
  */
771
793
  branch(entryId: string): Promise<{
772
794
  selectedText: string;
795
+ selectedImages: ImageContent[];
773
796
  cancelled: boolean;
774
797
  }>;
775
798
  branchFromBtw(question: string, assistantMessage: AssistantMessage): Promise<{
@@ -783,7 +806,7 @@ export declare class AgentSession {
783
806
  * @param targetId The entry ID to navigate to
784
807
  * @param options.summarize Whether user wants to summarize abandoned branch
785
808
  * @param options.customInstructions Custom instructions for summarizer
786
- * @returns Result with editorText (if user message) and cancelled status
809
+ * @returns Result with editorText/editorImages (if user message) and cancelled status
787
810
  */
788
811
  navigateTree(targetId: string, options?: {
789
812
  summarize?: boolean;
@@ -810,6 +833,8 @@ export declare class AgentSession {
810
833
  reanswerAskResult?: AgentToolResult<AskToolDetails>;
811
834
  }): Promise<{
812
835
  editorText?: string;
836
+ /** Image attachments of the target user message, parallel to the positional `[Image #N]` markers in {@link editorText}. */
837
+ editorImages?: ImageContent[];
813
838
  cancelled: boolean;
814
839
  aborted?: boolean;
815
840
  summaryEntry?: BranchSummaryEntry;
@@ -1011,6 +1036,8 @@ export declare class AgentSession {
1011
1036
  status: AdvisorRuntimeStatus;
1012
1037
  }[];
1013
1038
  };
1039
+ /** Return cumulative cost recorded for the current session's advisor activity. */
1040
+ getAdvisorCost(): number;
1014
1041
  /**
1015
1042
  * Return structured advisor stats for the status command and TUI panel.
1016
1043
  */
@@ -21,7 +21,7 @@ export interface ModelControlsHost {
21
21
  promptGeneration(): number;
22
22
  resolveActiveEditMode(): EditMode;
23
23
  syncAfterModelChange(previousEditMode: EditMode): Promise<void>;
24
- setModelWithProviderSessionReset(model: Model): void;
24
+ setModelWithProviderSessionReset(model: Model): Promise<void>;
25
25
  clearActiveRetryFallback(): void;
26
26
  clearInheritedProviderPromptCacheKey(): void;
27
27
  magicKeywordEnabled(keyword: "orchestrate" | "ultrathink" | "workflow"): boolean;
@@ -38,10 +38,13 @@ export declare class ModelControls {
38
38
  thinkingLevel?: ThinkingLevel;
39
39
  }>;
40
40
  thinkingLevel?: ConfiguredThinkingLevel;
41
+ thinkingLevelCeiling?: Effort;
41
42
  serviceTierByFamily?: ServiceTierByFamily;
42
43
  });
43
44
  /** Effective metadata-clamped thinking level applied to the agent. */
44
45
  get thinkingLevel(): ThinkingLevel | undefined;
46
+ /** Hard per-session effort ceiling every thinking-level change is clamped to. */
47
+ get thinkingLevelCeiling(): Effort | undefined;
45
48
  /** Configured selector, preserving `auto` while classification is active. */
46
49
  configuredThinkingLevel(): ConfiguredThinkingLevel | undefined;
47
50
  /** Whether per-turn automatic thinking classification is enabled. */
@@ -121,7 +121,11 @@ export declare class SessionAdvisors {
121
121
  /** Detaches and drains recorder feeds before transcript artifacts are removed. */
122
122
  detachAndCloseRecorders(): Promise<void>;
123
123
  /** Re-primes advisor transcript views across a conversation boundary. */
124
- resetSessionState(): void;
124
+ resetSessionState(options?: {
125
+ preserveCost?: boolean;
126
+ }): void;
127
+ /** Drop the recorded spend once a conversation boundary has committed. */
128
+ clearCost(): void;
125
129
  /**
126
130
  * Rebind every live advisor to the active primary conversation's provider
127
131
  * identity (session id, prompt-cache key, credential + metadata resolvers,
@@ -216,6 +220,8 @@ export declare class SessionAdvisors {
216
220
  status: AdvisorRuntimeStatus;
217
221
  }[];
218
222
  };
223
+ /** Return cumulative advisor cost recorded for the current session. */
224
+ getAdvisorCost(): number;
219
225
  /**
220
226
  * Return structured advisor stats for the status command and TUI panel.
221
227
  */
@@ -7,8 +7,9 @@ import type { ExtensionRunner } from "../extensibility/extensions/index.js";
7
7
  import { type Skill, type SkillWarning } from "../extensibility/skills.js";
8
8
  import { type LocalProtocolOptions } from "../internal-urls/index.js";
9
9
  import type { MemoryBackendStartOptions } from "../memory-backend/types.js";
10
- import { type XdevRegistry } from "../tools/xdev.js";
10
+ import { type XdevState } from "../tools/xdev.js";
11
11
  import { type EditMode } from "../utils/edit-mode.js";
12
+ import { type InspectImageMode } from "../utils/inspect-image-mode.js";
12
13
  import type { ClientBridge } from "./client-bridge.js";
13
14
  import type { CustomMessage } from "./messages.js";
14
15
  import type { SessionManager } from "./session-manager.js";
@@ -33,12 +34,17 @@ export interface SessionToolsHost {
33
34
  emitNotice(level: "info" | "warning" | "error", message: string, source?: string): void;
34
35
  notifyCommandMetadataChanged(): void;
35
36
  localProtocolOptions(): LocalProtocolOptions;
37
+ /** Session-scoped `/vision` override; undefined means "follow the persisted setting". */
38
+ getInspectImageModeOverride(): InspectImageMode | undefined;
39
+ setInspectImageModeOverride(mode: InspectImageMode | undefined): void;
36
40
  }
37
41
  interface SessionToolsOptions {
38
42
  autoApprove?: boolean;
39
43
  toolRegistry?: Map<string, AgentTool>;
40
44
  createVibeTools?: () => AgentTool[];
41
45
  createComputerTool?: () => Promise<AgentTool | null>;
46
+ /** Creates the built-in `inspect_image` tool for session-scoped runtime enablement (see {@link SessionTools.setInspectImageMode}). */
47
+ createInspectImageTool?: () => Promise<AgentTool | null>;
42
48
  builtInToolNames?: Iterable<string>;
43
49
  presentationPinnedToolNames?: ReadonlySet<string>;
44
50
  ensureWriteRegistered?: () => Promise<boolean>;
@@ -47,8 +53,7 @@ interface SessionToolsOptions {
47
53
  }>;
48
54
  getLocalCalendarDate?: () => string;
49
55
  getMcpServerInstructions?: () => Map<string, string> | undefined;
50
- xdevRegistry?: XdevRegistry;
51
- initialMountedXdevToolNames?: string[];
56
+ xdev?: XdevState;
52
57
  setActiveToolNames?: (names: Iterable<string>) => void;
53
58
  baseSystemPrompt: string[];
54
59
  skills?: Skill[];
@@ -99,13 +104,13 @@ export declare class SessionTools {
99
104
  get skillsSettings(): SkillsSettings | undefined;
100
105
  /** Drops cached per-session ACP `allow_always`/`reject_always` decisions. */
101
106
  clearAcpPermissionDecisions(): void;
102
- /** Re-wraps active and mounted tools after the ACP client changes. */
107
+ /** Drops cached ACP decisions and re-wraps active tools after the client changes. */
103
108
  refreshAcpPermissionGates(): void;
104
109
  /** Names of tools currently exposed at the top level. */
105
110
  getActiveToolNames(): string[];
106
111
  /** Enabled top-level and discoverable tool names. */
107
112
  getEnabledToolNames(): string[];
108
- /** Names of dynamic tools mounted under `xd://`. */
113
+ /** Names currently presented as `xd://` devices. */
109
114
  getMountedXdevToolNames(): string[];
110
115
  /** Whether the edit tool is registered. */
111
116
  get hasEditTool(): boolean;
@@ -139,7 +144,7 @@ export declare class SessionTools {
139
144
  * Restore an enabled tool set with its exact top-level versus `xd://` partition.
140
145
  *
141
146
  * Both inputs are required because {@link setActiveToolsByName} only receives the
142
- * enabled name list and classifies mounts from the current `#mountedXdevToolNames`.
147
+ * enabled name list and classifies mounts from the current presentation set.
143
148
  * Rollback/restore callers must pass the snapshotted mounted subset so names that
144
149
  * were top-level stay pinned (`#runtimeSelectedToolNames`) and names that were under
145
150
  * `xd://` remain mount-eligible, even when the live mount set has drifted.
@@ -166,6 +171,39 @@ export declare class SessionTools {
166
171
  * tool (e.g. restricted child sessions have no factory).
167
172
  */
168
173
  setComputerToolEnabled(enabled: boolean): Promise<boolean>;
174
+ /** Current effective inspect_image state for `/vision status`. */
175
+ inspectImageState(): {
176
+ mode: InspectImageMode;
177
+ active: boolean;
178
+ model: string | undefined;
179
+ };
180
+ /**
181
+ * Brings the active tool set in line with the effective inspect_image state
182
+ * (mode setting, `/vision` override, active-model image capability).
183
+ * Mirrors {@link setComputerToolEnabled}: enabling builds the tool through
184
+ * the config factory on first use and reuses the registry entry afterwards.
185
+ * Idempotent — safe to call from every model/settings change path.
186
+ *
187
+ * @returns false when the tool should be active but this session cannot
188
+ * build it (e.g. restricted child sessions have no factory).
189
+ */
190
+ reconcileInspectImageTool(): Promise<boolean>;
191
+ /**
192
+ * Reconciles inspect_image after a model change and surfaces a notice when
193
+ * the visible tool set actually flipped. Called from every model-change
194
+ * path — including retry-fallback switches that bypass
195
+ * {@link syncAfterModelChange}.
196
+ */
197
+ reconcileInspectImageAfterModelChange(): Promise<void>;
198
+ /**
199
+ * Session-scoped `/vision` override. `auto` clears the override so the
200
+ * persisted `inspect_image.mode` setting (itself possibly `auto`) decides;
201
+ * `on`/`off` force the tool for this session only. Takes effect before the
202
+ * next model call.
203
+ *
204
+ * @returns false when `on` was requested but the tool cannot be built here.
205
+ */
206
+ setInspectImageMode(mode: InspectImageMode): Promise<boolean>;
169
207
  /** Rebuilds the stable base prompt for the current tools and model. */
170
208
  refreshBaseSystemPrompt(): Promise<void>;
171
209
  /** Applies one-turn memory prompt injection before an agent run. */
@@ -34,12 +34,17 @@ export interface OutputSummary {
34
34
  export interface OutputSinkOptions {
35
35
  artifactPath?: string;
36
36
  artifactId?: string;
37
- /** Tail buffer budget (bytes). Default DEFAULT_MAX_BYTES. */
37
+ /**
38
+ * Total inline body budget (bytes). Default DEFAULT_MAX_BYTES. The head
39
+ * window and rolling tail window share this budget, so a composed
40
+ * `dump()` body never exceeds it (plus the elision marker).
41
+ */
38
42
  spillThreshold?: number;
39
43
  /**
40
44
  * When > 0, the sink keeps the first `headBytes` of output in addition to
41
45
  * the rolling tail window. Output between the two windows is elided
42
- * (middle elision). Default 0 = tail-only behavior.
46
+ * (middle elision). Clamped to `spillThreshold / 2` so the tail keeps at
47
+ * least half the inline budget. Default 0 = tail-only behavior.
43
48
  */
44
49
  headBytes?: number;
45
50
  /**