mixdog 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (557) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/scripts/provider-pingpong-live.mjs +509 -0
  6. package/src/agents/advisor/AGENT.md +1 -1
  7. package/src/agents/advisor/agent.json +1 -1
  8. package/src/agents/reviewer/AGENT.md +3 -3
  9. package/src/agents/reviewer/agent.json +1 -1
  10. package/src/defaults/shipped-history.json +6 -0
  11. package/src/defaults/skills/setup/SKILL.md +6 -1
  12. package/src/defaults/skills/setup/references/actions.md +44 -22
  13. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  14. package/src/headless-exec.mjs +15 -8
  15. package/src/lib/keychain-cjs.cjs +7 -4
  16. package/src/output-styles/common.md +11 -10
  17. package/src/repl/slash-commands.mjs +16 -1
  18. package/src/rules/agent/AGENT.md +5 -5
  19. package/src/rules/lead/LEAD.md +5 -5
  20. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  21. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  22. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  23. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  24. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
  33. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  36. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  37. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  38. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  39. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  40. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  41. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  43. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  44. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  45. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
  46. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  47. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  48. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
  49. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
  50. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  51. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  54. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
  58. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  59. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  63. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  65. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  66. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
  70. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  71. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  72. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
  73. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
  74. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
  75. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
  76. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
  77. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  79. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  80. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
  81. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  83. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
  84. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
  85. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  86. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
  87. package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
  88. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
  89. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
  90. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  91. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  92. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  93. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
  94. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  95. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
  96. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
  97. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  98. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  99. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  100. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  102. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
  103. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
  104. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
  105. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
  106. package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
  107. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  109. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
  110. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
  113. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  114. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  115. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
  116. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  117. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  118. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  119. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  120. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
  121. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
  122. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  123. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  124. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  125. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  126. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  127. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
  128. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  129. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  138. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  140. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  141. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
  142. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
  143. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
  144. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  145. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  147. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
  148. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  150. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
  151. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  152. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
  153. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
  154. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
  155. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
  156. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
  157. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  158. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  159. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  160. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
  161. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  163. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
  164. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  165. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
  166. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  167. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  168. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  169. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  170. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
  171. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
  172. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  173. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
  174. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
  175. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  176. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
  177. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  178. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
  179. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  180. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  181. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
  182. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  183. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  184. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  185. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  186. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  187. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  188. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
  189. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
  190. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
  191. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
  192. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
  193. package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
  194. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  195. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
  196. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  197. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  198. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  199. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  200. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  201. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
  202. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
  203. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  204. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
  205. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
  206. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  207. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
  208. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  210. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  211. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  212. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
  213. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  214. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  215. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
  216. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  217. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  218. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  219. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
  220. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
  221. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  222. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
  223. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  224. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
  225. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  226. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
  227. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  228. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  229. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
  230. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  231. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
  232. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  233. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  234. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  235. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
  236. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
  237. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
  238. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
  239. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  240. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
  241. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  242. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  243. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
  244. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  245. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
  246. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
  248. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
  249. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
  250. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  251. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
  252. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  253. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  254. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  255. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  256. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
  257. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
  258. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
  259. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
  260. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  261. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
  262. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
  263. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  264. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  265. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
  266. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  267. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
  268. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  269. package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
  270. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
  271. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  272. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
  273. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  274. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
  275. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  276. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
  277. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
  278. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  279. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  280. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  281. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
  282. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
  283. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
  284. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
  285. package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
  286. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
  287. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
  288. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  289. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  290. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  291. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
  292. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
  293. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  294. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  295. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  296. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  297. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  298. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  299. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
  300. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
  301. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  302. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  303. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  304. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  305. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  306. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  307. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  308. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  309. package/src/runtime/computer-bridge/action-schema.mjs +44 -21
  310. package/src/runtime/github/tool.mjs +92 -2
  311. package/src/runtime/memory/index.mjs +1 -0
  312. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  313. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  314. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  315. package/src/runtime/memory/lib/pg/process.mjs +65 -50
  316. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  317. package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
  318. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  319. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  320. package/src/runtime/office/README.md +2 -2
  321. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  322. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  323. package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
  324. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  325. package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
  326. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  327. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  328. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  329. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  330. package/src/runtime/office/core/office-sessions.mjs +5 -0
  331. package/src/runtime/office/core/office-transactions.mjs +3 -0
  332. package/src/runtime/office/core/office-write-ledger.mjs +98 -0
  333. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  334. package/src/runtime/office/index.mjs +30 -0
  335. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  336. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  337. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  338. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  339. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  340. package/src/runtime/office/shared/values.mjs +0 -5
  341. package/src/runtime/shared/background-tasks.mjs +92 -14
  342. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  343. package/src/runtime/shared/bounded-line-diff.mjs +182 -0
  344. package/src/runtime/shared/buffered-appender.mjs +18 -0
  345. package/src/runtime/shared/config.mjs +78 -18
  346. package/src/runtime/shared/err-text.mjs +31 -0
  347. package/src/runtime/shared/error-presentation.mjs +159 -19
  348. package/src/runtime/shared/file-permissions.d.mts +6 -1
  349. package/src/runtime/shared/file-permissions.mjs +54 -6
  350. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  351. package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
  352. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  353. package/src/runtime/shared/llm/model-catalog.mjs +53 -40
  354. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  355. package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
  356. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  357. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  358. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  359. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  360. package/src/runtime/shared/loopback-listener.mjs +9 -0
  361. package/src/runtime/shared/model-display.mjs +13 -0
  362. package/src/runtime/shared/provider-api-key.mjs +2 -0
  363. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  364. package/src/runtime/shared/review-diff.mjs +52 -0
  365. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  366. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  367. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  368. package/src/runtime/shared/slow-span.mjs +114 -0
  369. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  370. package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
  371. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  372. package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
  373. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  374. package/src/runtime/shared/tool-card-model.mjs +5 -2
  375. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  376. package/src/runtime/shared/tool-primitives.mjs +13 -0
  377. package/src/runtime/shared/tool-result-summary.mjs +8 -1
  378. package/src/runtime/shared/tool-surface.mjs +18 -3
  379. package/src/runtime/shared/tool-work-units.mjs +40 -4
  380. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  381. package/src/runtime/shared/transcript-writer.mjs +10 -2
  382. package/src/runtime/shared/turn-changes.mjs +670 -274
  383. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  384. package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
  385. package/src/runtime/shared/turn-snapshot.mjs +986 -690
  386. package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
  387. package/src/runtime/shared/user-data-guard.mjs +262 -49
  388. package/src/runtime/shared/worktrees/carry.mjs +531 -0
  389. package/src/runtime/shared/worktrees/contract.mjs +34 -24
  390. package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
  391. package/src/runtime/shared/worktrees/git-head.mjs +205 -0
  392. package/src/runtime/shared/worktrees/git.mjs +8 -3
  393. package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
  394. package/src/runtime/shared/worktrees/manager.mjs +156 -8
  395. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  396. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  397. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  398. package/src/runtime/terminal-bridge/client.mjs +44 -11
  399. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  400. package/src/runtime/tidy/apply.mjs +47 -2
  401. package/src/runtime/tidy/run-engines.mjs +11 -5
  402. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  403. package/src/session-runtime/boot/apis.mjs +19 -5
  404. package/src/session-runtime/boot/facade.mjs +1 -0
  405. package/src/session-runtime/boot/infrastructure.mjs +12 -1
  406. package/src/session-runtime/boot/session.mjs +0 -1
  407. package/src/session-runtime/boot/tools.mjs +4 -1
  408. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  409. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
  410. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  411. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
  412. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
  413. package/src/session-runtime/internal-tool-executor.mjs +6 -2
  414. package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
  415. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  416. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
  417. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  418. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
  419. package/src/session-runtime/lifecycle/teardown.mjs +73 -8
  420. package/src/session-runtime/lifecycle-api.mjs +1 -0
  421. package/src/session-runtime/mcp-glue/connect.mjs +46 -14
  422. package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
  423. package/src/session-runtime/mcp-glue.mjs +3 -0
  424. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  425. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  426. package/src/session-runtime/model-route/set-route.mjs +85 -17
  427. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  428. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  429. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  430. package/src/session-runtime/native-web-search.mjs +10 -1
  431. package/src/session-runtime/new-session-config.mjs +4 -2
  432. package/src/session-runtime/provider-auth/login.mjs +4 -0
  433. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  434. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  435. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  436. package/src/session-runtime/resource-extension-sync.mjs +4 -0
  437. package/src/session-runtime/resource-mcp-api.mjs +98 -2
  438. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  439. package/src/session-runtime/runtime-review-api.mjs +21 -2
  440. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  441. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  442. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  443. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  444. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  445. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
  446. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  447. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  448. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  449. package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
  450. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  451. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  452. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  453. package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
  454. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  455. package/src/session-runtime/services/agent-tool.mjs +3 -0
  456. package/src/session-runtime/services/channel-admin.mjs +19 -3
  457. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  458. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  459. package/src/session-runtime/services/provider-admin.mjs +81 -15
  460. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  461. package/src/session-runtime/session-turn-api.mjs +14 -5
  462. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
  463. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  464. package/src/session-runtime/setup-tool/executor.mjs +36 -6
  465. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  466. package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
  467. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
  468. package/src/session-runtime/skills-api.mjs +3 -5
  469. package/src/session-runtime/tool-surface.mjs +5 -1
  470. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  471. package/src/session-runtime/turn/session-ops.mjs +7 -5
  472. package/src/session-runtime/turn/side-question-ops.mjs +22 -0
  473. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
  474. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
  475. package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
  476. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  477. package/src/session-runtime/turn/turn-run.mjs +25 -9
  478. package/src/session-runtime/usage-stats-api.mjs +43 -11
  479. package/src/session-runtime/workspace/project-branches.mjs +7 -5
  480. package/src/session-runtime/workspace/transition-steps.mjs +129 -31
  481. package/src/session-runtime/workspace/transitions.mjs +190 -15
  482. package/src/standalone/daemon-agent-control.mjs +9 -1
  483. package/src/standalone/daemon-drain-policy.mjs +8 -0
  484. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  485. package/src/standalone/daemon-owner.mjs +17 -4
  486. package/src/standalone/daemon-pg-stop.mjs +51 -0
  487. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  488. package/src/standalone/daemon-stop-budget.mjs +18 -0
  489. package/src/standalone/daemon-stored-session-views.mjs +2 -0
  490. package/src/standalone/daemon-telemetry.mjs +74 -0
  491. package/src/standalone/daemon.mjs +64 -8
  492. package/src/standalone/desktop-service-registry.mjs +5 -0
  493. package/src/standalone/local-session-runtime.mjs +70 -19
  494. package/src/standalone/session-client.mjs +42 -0
  495. package/src/standalone/session-protocol.mjs +14 -0
  496. package/src/standalone/session-proxy/projection.mjs +41 -4
  497. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  498. package/src/standalone/session-runtime-inline-host.mjs +1 -0
  499. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  500. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  501. package/src/standalone/session-service/agent-tree.mjs +12 -0
  502. package/src/standalone/session-service/quota-resume.mjs +8 -0
  503. package/src/standalone/session-service/retention/busy.mjs +15 -1
  504. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  505. package/src/standalone/session-service-api.mjs +11 -1
  506. package/src/standalone/session-service.mjs +1 -0
  507. package/src/standalone/session-state-patch.d.mts +2 -1
  508. package/src/standalone/session-state-patch.mjs +41 -1
  509. package/src/tui/App.jsx +25 -0
  510. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  511. package/src/tui/app/app-view.jsx +1 -0
  512. package/src/tui/app/btw-controller.mjs +118 -0
  513. package/src/tui/app/create-app-pickers.mjs +6 -0
  514. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  515. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  516. package/src/tui/app/extension-pickers.mjs +2 -1
  517. package/src/tui/app/model-options.mjs +11 -16
  518. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  519. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  520. package/src/tui/app/slash-commands.mjs +20 -5
  521. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  522. package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
  523. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  524. package/src/tui/app/use-global-key-input.mjs +5 -12
  525. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  526. package/src/tui/components/BtwPanel.jsx +53 -0
  527. package/src/tui/components/QuestionPanel.jsx +275 -0
  528. package/src/tui/components/StatusLine.jsx +2 -0
  529. package/src/tui/components/question-panel-model.mjs +156 -0
  530. package/src/tui/components/status-line/local-line.mjs +5 -2
  531. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  532. package/src/tui/dist/index.mjs +3221 -1500
  533. package/src/tui/session/context-state.mjs +4 -2
  534. package/src/tui/session/quota-resume.mjs +46 -14
  535. package/src/tui/session/session-api/commands.mjs +43 -24
  536. package/src/tui/session/session-api/controls.mjs +2 -2
  537. package/src/tui/session/session-api/extensions.mjs +22 -0
  538. package/src/tui/session/session-api/integrations.mjs +16 -2
  539. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  540. package/src/tui/session/session-api/lifecycle.mjs +7 -2
  541. package/src/tui/session/session-api/routes.mjs +71 -7
  542. package/src/tui/session/session-api/settings.mjs +11 -14
  543. package/src/tui/session/session-api.mjs +1 -0
  544. package/src/tui/session/session-flow/drain.mjs +7 -1
  545. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  546. package/src/tui/session/tool-approval.mjs +10 -7
  547. package/src/tui/session/transcript-spill.mjs +14 -7
  548. package/src/tui/session/turn-stream.mjs +174 -31
  549. package/src/tui/session/turn.mjs +46 -16
  550. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  551. package/src/ui/statusline-agents.mjs +15 -4
  552. package/src/ui/statusline.mjs +7 -3
  553. package/src/ui/streaming-markdown-heal.mjs +34 -3
  554. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  555. package/src/workflows/default/WORKFLOW.md +3 -1
  556. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  557. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -250,6 +250,14 @@ function storedSessionMetadata(sessionId, session) {
250
250
  };
251
251
  }
252
252
 
253
+ /** A record that is gone may be a reaped agent child: its parent is resolved
254
+ * from metadata only (worker link, summary-index row), never by a scan. */
255
+ function readVanishedSessionTranscript(sessionId) {
256
+ return readArchivedAgentResult(sessionId, {
257
+ catalogRow: (id) => ordinaryCatalog.loadIndex().rowsById.get(id) || null,
258
+ });
259
+ }
260
+
253
261
  /** The two files a stored transcript projection is built from. */
254
262
  function storedTranscriptInputPaths(sessionId) {
255
263
  return {
@@ -375,7 +383,7 @@ export async function readStoredSessionTranscript(id, options = {}) {
375
383
  // Phase durations of the parse this call ran (absent on a cache hit).
376
384
  const timing = {};
377
385
  const recordStat = probePath(recordPath);
378
- if (recordStat.state === PROBE_ABSENT) return readArchivedAgentResult(sessionId);
386
+ if (recordStat.state === PROBE_ABSENT) return readVanishedSessionTranscript(sessionId);
379
387
  if (recordStat.state !== PROBE_PRESENT) return null;
380
388
  const checkpoint = probePath(checkpointPath);
381
389
  const archive = probePath(archivePath);
@@ -441,7 +449,7 @@ export async function readStoredSessionTranscript(id, options = {}) {
441
449
  produce: (text) => produceStoredTranscript(text, readStamp, produceContext),
442
450
  });
443
451
  // The record vanished between stat and read: same answer as an absent probe.
444
- if (readState === PROBE_ABSENT) return readArchivedAgentResult(sessionId);
452
+ if (readState === PROBE_ABSENT) return readVanishedSessionTranscript(sessionId);
445
453
  if (typeof options.trace === 'function') {
446
454
  options.trace({
447
455
  sessionId,
@@ -3,7 +3,7 @@
3
3
  * Sessions are saved to disk so CLI and MCP server can share state,
4
4
  * and sessions survive server restarts (resume).
5
5
  */
6
- import { writeFileSync } from 'node:fs';
6
+ import { closeSync, fsyncSync, openSync, writeFileSync } from 'node:fs';
7
7
  import * as fsp from 'node:fs/promises';
8
8
  import { randomBytes } from 'node:crypto';
9
9
  import { sessionPath } from './store/paths-heartbeat.mjs';
@@ -354,7 +354,15 @@ function _doSaveSync(payload) {
354
354
  attempted = JSON.stringify(disk);
355
355
  // The lifecycle these exact bytes carry, recorded with the commit stamp.
356
356
  const lifecycle = _lifecycleOfSessionDocument(disk);
357
- writeFileSync(tmp, attempted, 'utf-8');
357
+ // fsync before the rename: without it an OS crash can publish the
358
+ // renamed file with its data blocks never written (all-NUL record).
359
+ const fd = openSync(tmp, 'w');
360
+ try {
361
+ writeFileSync(fd, attempted, 'utf-8');
362
+ fsyncSync(fd);
363
+ } finally {
364
+ closeSync(fd);
365
+ }
358
366
  if (_shouldDrop(id, opts, attempt)) {
359
367
  _discardSaveTmp(tmp);
360
368
  if (mayMutate()) _recordSaveDrop(id, epoch);
@@ -636,7 +644,14 @@ async function _doSave(payload) {
636
644
  attempted = JSON.stringify(disk);
637
645
  // Captured before the await: the lifecycle of exactly these bytes.
638
646
  const lifecycle = _lifecycleOfSessionDocument(disk);
639
- await fsp.writeFile(tmp, attempted, 'utf-8');
647
+ // fsync before the rename (see _doSaveSync).
648
+ const handle = await fsp.open(tmp, 'w');
649
+ try {
650
+ await handle.writeFile(attempted, 'utf-8');
651
+ await handle.sync();
652
+ } finally {
653
+ await handle.close();
654
+ }
640
655
  // Second check: between the temp write and the rename, closeSession()
641
656
  // may have planted a tombstone. Re-check on disk; if a newer tombstone
642
657
  // now exists, discard our temp file rather than let rename clobber it.
@@ -706,6 +721,7 @@ export { loadSession } from './store/load-session.mjs';
706
721
  // Hard delete + owned-agent enumeration live in store/session-delete.mjs;
707
722
  // re-exported here so prior importers of store.mjs stay unchanged.
708
723
  export { deleteSession, listOwnedAgentSessionIds } from './store/session-delete.mjs';
724
+ export { fenceSessionWrites } from './store/live-state.mjs';
709
725
 
710
726
  // Listing / summaries live in store/listing.mjs and the stale sweep in
711
727
  // store/sweep/stale-sweep.mjs; re-exported here so importers keep one
@@ -208,6 +208,7 @@ function invocationOptions(batch, call, exec) {
208
208
  iteration: batch.iterations,
209
209
  localSearchTelemetry: exec.localSearchTelemetry || {},
210
210
  resultTelemetry: exec.resultTelemetry,
211
+ ...(call.wireCall ? { bridgeWireCall: call.wireCall } : {}),
211
212
  };
212
213
  }
213
214
 
@@ -319,7 +319,7 @@ function stagePostProcessingFailure(batch, completed, postErr, postprocessStarte
319
319
  if (sessionRef?._scopedCacheOutcomeByCallId instanceof Map && call?.id) {
320
320
  sessionRef._scopedCacheOutcomeByCallId.delete(call.id);
321
321
  }
322
- if (call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.calls, call.id);
322
+ if (call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.wireCalls, call.id);
323
323
  const message = `Error: tool result post-processing failed for "${call.name}": ${postErr instanceof Error ? postErr.message : String(postErr)}`;
324
324
  traceAgentToolFailure({
325
325
  sessionId: batch.sessionId,
@@ -46,7 +46,7 @@ export async function recordCallOutcome(batch, call, exec, sigs, ctSig) {
46
46
  // otherwise hide behind a `[mixdog compacted …]` placeholder). Restored
47
47
  // immediately so an abort or post-processing throw cannot leave it
48
48
  // compacted; early-skipped calls stay compacted.
49
- if (executed && failed && call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.calls, call.id);
49
+ if (executed && failed && call?.id) restoreToolCallBodyForId(batch.assistantTurnMsg, batch.wireCalls, call.id);
50
50
  if (sessionId && _stripMcpPrefix(call.name) === 'apply_patch') {
51
51
  if (exec.executeOk && exec.resultKind === 'normal') invalidateAfterPatch(sessionId, call, cwd);
52
52
  // Mutation tools invalidate even on returned-error/partial-fail — the
@@ -4,11 +4,17 @@
4
4
  // live here so processToolBatch can hand them back.
5
5
  import { executeTool } from '../loop/tool-exec.mjs';
6
6
  import { planToolBatch } from './plan.mjs';
7
+ import { bridgeClassificationTools, resolveExecutionToolCalls } from '../loop/tool-call-resolution.mjs';
7
8
 
8
9
  export function createBatchState(ctx) {
9
- const { calls, tools, assistantTurnMsg, sessionRef } = ctx;
10
+ const { assistantTurnMsg, sessionRef } = ctx;
11
+ // Bridged call_tool requests run as their targets from here on; the wire
12
+ // calls stay authoritative for the transcript and failed-argument restore.
13
+ const calls = resolveExecutionToolCalls(ctx.calls, sessionRef);
14
+ const tools = bridgeClassificationTools(ctx.tools, calls);
10
15
  return {
11
16
  calls,
17
+ wireCalls: ctx.calls,
12
18
  messages: ctx.messages,
13
19
  tools,
14
20
  cwd: ctx.cwd,
@@ -19,8 +19,10 @@ import { getPluginData } from '../config.mjs';
19
19
  import { countSplitLines, normalizeOutputPath } from '../tools/builtin/path-utils.mjs';
20
20
  import { classifyResultKind } from './result-classification.mjs';
21
21
  import { registerSessionPurgeHook } from './store.mjs';
22
+ import { SETUP_OUTPUT_MAX_BYTES } from '../../../shared/tool-output-limit.mjs';
22
23
 
23
24
  const TOOL_RESULT_OFFLOAD_THRESHOLD_CHARS = 50_000;
25
+ const TOOL_RESULT_SETUP_THRESHOLD_CHARS = SETUP_OUTPUT_MAX_BYTES;
24
26
  const TOOL_RESULT_PREVIEW_CHARS = 512;
25
27
  const TOOL_RESULT_SHELL_THRESHOLD_CHARS = 30_000;
26
28
  const TOOL_RESULT_SEARCH_THRESHOLD_CHARS = 50_000;
@@ -61,6 +63,7 @@ const INLINE_THRESHOLD_BY_TOOL = new Map([
61
63
  ['bash_session', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
62
64
  ['terminal', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
63
65
  ['task', TOOL_RESULT_SHELL_THRESHOLD_CHARS],
66
+ ['setup', TOOL_RESULT_SETUP_THRESHOLD_CHARS],
64
67
  ]);
65
68
 
66
69
  function getOffloadThreshold(toolName) {
@@ -554,6 +557,7 @@ export const _internals = {
554
557
  TOOL_RESULT_SHELL_THRESHOLD_CHARS,
555
558
  TOOL_RESULT_SEARCH_THRESHOLD_CHARS,
556
559
  TOOL_RESULT_GREP_THRESHOLD_CHARS,
560
+ TOOL_RESULT_SETUP_THRESHOLD_CHARS,
557
561
  getOffloadThreshold,
558
562
  TOOL_RESULT_PREVIEW_CHARS,
559
563
  TOOL_RESULT_MESSAGE_MAX_CHARS,
@@ -0,0 +1,77 @@
1
+ // A provider 400 that names one tool's input schema (Anthropic
2
+ // `tools.3.custom.input_schema`, OpenAI `Invalid schema for function 'x'` /
3
+ // `tools[3].parameters`, Gemini `function_declarations[3]`): which tool of the
4
+ // request it is, so the session can drop it instead of failing every turn.
5
+ import { providerToolExclusionReason } from './loop/provider-tool-exclusions.mjs';
6
+ import { providerNativeToolPrefixCount } from '../runtime-core/provider-request-tools.mjs';
7
+
8
+ const MAX_REASON_CHARS = 240;
9
+
10
+ const text = (value) => (typeof value === 'string' ? value : '');
11
+
12
+ // Provider-structured places a rejection names its field, best evidence first:
13
+ // OpenAI `param` (also nested under `error`), Anthropic / OpenAI `error.message`,
14
+ // Google `details[].fieldViolations[].field`, then a JSON body, then the
15
+ // error's own message.
16
+ function evidence(error) {
17
+ const nested = [error?.error, error?.providerError, error?.response?.data?.error, error?.response?.data];
18
+ const violations = [error?.details, error?.error?.details, error?.errorDetails]
19
+ .flatMap((details) => (Array.isArray(details) ? details : []))
20
+ .flatMap((detail) => (Array.isArray(detail?.fieldViolations) ? detail.fieldViolations : []))
21
+ .flatMap((violation) => [text(violation?.field), text(violation?.description)]);
22
+ const bodies = [error?.body, error?.responseBody].map((body) => {
23
+ if (typeof body !== 'string') return [];
24
+ try {
25
+ const parsed = JSON.parse(body);
26
+ return [text(parsed?.error?.param), text(parsed?.error?.message), text(parsed?.message)];
27
+ } catch {
28
+ return [body];
29
+ }
30
+ });
31
+ return [
32
+ error?.param,
33
+ ...nested.map((entry) => entry?.param),
34
+ ...nested.map((entry) => entry?.message),
35
+ ...violations,
36
+ ...bodies.flat(),
37
+ error?.message,
38
+ error?.cause?.message,
39
+ ].filter((entry) => typeof entry === 'string' && entry);
40
+ }
41
+
42
+ // One piece of evidence -> which tool: a wire index (`byIndex`, with the
43
+ // OpenAI Responses hosted-tool offset when `shifted`) or a function name.
44
+ function target(entry) {
45
+ let match = /\btools\.(\d+)\.(?:custom\.)?input_schema/.exec(entry);
46
+ if (match) return { index: Number(match[1]) };
47
+ match = /\btools(?:\[(\d+)\]|\.(\d+))\.(?:function\.)?parameters/.exec(entry);
48
+ if (match) return { index: Number(match[1] ?? match[2]), shifted: true };
49
+ match = /\b(?:function_declarations|functionDeclarations)(?:\[(\d+)\]|\.(\d+))/.exec(entry);
50
+ if (match) return { index: Number(match[1] ?? match[2]) };
51
+ match = /Invalid schema for function ['"`]([^'"`]+)['"`]/.exec(entry);
52
+ if (match) return { name: match[1] };
53
+ return null;
54
+ }
55
+
56
+ /** `{ name, pointer, reason }` of the tool a schema 400 points at, or null (any
57
+ * other error, or a tool that is not part of the request's own tools). */
58
+ export function rejectedToolSchema(error, { sendTools, sessionRef, opts }) {
59
+ if ((error?.httpStatus ?? error?.status ?? error?.statusCode) !== 400) return null;
60
+ const tools = Array.isArray(sendTools) ? sendTools : [];
61
+ const nativeCount = providerNativeToolPrefixCount(tools);
62
+ // The wire list: the request's tools minus those the wire left out.
63
+ const wire = tools.filter((tool) => !providerToolExclusionReason(sessionRef, tool?.name));
64
+ const hosted = sessionRef?.wireRoute?.wire !== 'chat' && Array.isArray(opts?.nativeTools) ? opts.nativeTools.length : 0;
65
+ const entries = evidence(error);
66
+ let name = '';
67
+ for (const entry of entries) {
68
+ const found = target(entry);
69
+ if (!found) continue;
70
+ const tool = found.name ? wire.find((t) => t?.name === found.name) : wire[found.index - (found.shifted ? hosted : 0)];
71
+ name = typeof tool?.name === 'string' ? tool.name : '';
72
+ if (name) break;
73
+ }
74
+ if (!name || tools.findIndex((t) => t?.name === name) < nativeCount) return null;
75
+ const detail = entries.join(' ').replace(/\s+/g, ' ').trim().slice(0, MAX_REASON_CHARS);
76
+ return { name, pointer: '/', reason: `the provider rejected it with HTTP 400: ${detail}` };
77
+ }
@@ -286,7 +286,9 @@ function mergeRestoredToolItems(items) {
286
286
  }
287
287
 
288
288
  function restoredMessageItemUpperBound(message) {
289
- const boundaries = Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances.length : 0;
289
+ const boundaries =
290
+ (Array.isArray(message?.meta?.sessionInheritances) ? message.meta.sessionInheritances.length : 0) +
291
+ (Array.isArray(message?.meta?.modelSwitches) ? message.meta.modelSwitches.length : 0);
290
292
  if (message?.role === 'user') return 1 + boundaries;
291
293
  if (message?.role !== 'assistant') return boundaries;
292
294
  const calls = restoredMessageToolCalls(message);
@@ -377,6 +379,19 @@ function restoredUserTranscriptItems(message, nextId) {
377
379
  return [restoredNotificationToolItem(synthetic, text, message, nextId, /^(failed|error|killed|cancelled)$/i)];
378
380
  }
379
381
 
382
+ /** The transcript row of an in-place model switch (live and restored). */
383
+ export function modelSwitchItem(id, boundary) {
384
+ return {
385
+ kind: 'statusdone',
386
+ id,
387
+ status: 'model-switched',
388
+ label: 'Model switched',
389
+ provider: boundary.provider,
390
+ modelId: boundary.modelId,
391
+ at: boundary.at,
392
+ };
393
+ }
394
+
380
395
  function restoreTranscriptRange(messages, start, sessionId) {
381
396
  const items = [];
382
397
  const pendingToolCalls = new Map();
@@ -408,6 +423,10 @@ function restoreTranscriptRange(messages, start, sessionId) {
408
423
  at: boundary.at,
409
424
  });
410
425
  }
426
+ for (const boundary of Array.isArray(message?.meta?.modelSwitches) ? message.meta.modelSwitches : []) {
427
+ if (!boundary?.provider || !boundary?.modelId) continue;
428
+ items.push(modelSwitchItem(restoredId(), boundary));
429
+ }
411
430
  }
412
431
  return mergeRestoredToolItems(items);
413
432
  }
@@ -68,6 +68,12 @@ export function buildBashPolicyScanTargets(command) {
68
68
  return out;
69
69
  }
70
70
 
71
- export function checkExecPolicyMessage(command) {
72
- return formatExecPolicyBlockMessage(evaluateExecPolicyFromTargets(buildBashPolicyScanTargets(command)));
71
+ export function evaluateExecPolicy(command) {
72
+ return evaluateExecPolicyFromTargets(buildBashPolicyScanTargets(command));
73
+ }
74
+
75
+ // `elevationApproved` is runtime-supplied: the user approved this call's
76
+ // 'ask' (elevation) decision. It never lifts a deny.
77
+ export function checkExecPolicyMessage(command, { elevationApproved = false } = {}) {
78
+ return formatExecPolicyBlockMessage(evaluateExecPolicy(command), { elevationApproved });
73
79
  }
@@ -786,9 +786,9 @@ function guardShell(a) {
786
786
  }
787
787
  // Over-max is an unambiguous "wait as long as allowed"; clamp like the other
788
788
  // saturating integer args instead of failing the call.
789
- if (hasOwn(a, 'wait_ms') && Number.isInteger(a.wait_ms) && a.wait_ms > 120000) a.wait_ms = 120000;
789
+ if (hasOwn(a, 'wait_ms') && Number.isInteger(a.wait_ms) && a.wait_ms > 30000) a.wait_ms = 30000;
790
790
  if (hasOwn(a, 'wait_ms') && (!Number.isInteger(a.wait_ms) || a.wait_ms < 1000)) {
791
- return `Error: shell arg "wait_ms" must be an integer from 15000 to 120000, e.g. wait_ms:30000 (got ${JSON.stringify(a.wait_ms)})`;
791
+ return `Error: shell arg "wait_ms" must be an integer from 10000 to 30000, e.g. wait_ms:20000 (got ${JSON.stringify(a.wait_ms)})`;
792
792
  }
793
793
  if (!hasOwn(a, 'command')) {
794
794
  return 'Error: shell requires "command"';
@@ -8,11 +8,11 @@ import { formatShellToolFailure } from './result-format.mjs';
8
8
  // Policy + shell-specific rewrites before any shell dispatch. Returns either
9
9
  // `{ failure }` (a formatted tool failure) or the command to run with the
10
10
  // resolved shell spec and the wmic rewrite (if any).
11
- export function prepareShellCommand(args) {
11
+ export function prepareShellCommand(args, { elevationApproved = false } = {}) {
12
12
  // Run hard-block policy before any shell dispatch.
13
13
  const rawCmd = String(args && args.command != null ? args.command : '');
14
14
  if (rawCmd) {
15
- const policyBlock = checkExecPolicyMessage(rawCmd);
15
+ const policyBlock = checkExecPolicyMessage(rawCmd, { elevationApproved });
16
16
  if (policyBlock) return { failure: formatShellToolFailure(policyBlock) };
17
17
  }
18
18
  let command = args.command;
@@ -52,7 +52,7 @@ export function prepareShellCommand(args) {
52
52
  : null;
53
53
  if (bashismRewrite) command = bashismRewrite.command;
54
54
 
55
- const execPolicyBlock = checkExecPolicyMessage(command);
55
+ const execPolicyBlock = checkExecPolicyMessage(command, { elevationApproved });
56
56
  if (execPolicyBlock) return { failure: formatShellToolFailure(execPolicyBlock) };
57
57
  return { command, analysisCommand, resolvedSpec, wmicRewrite, bashismRewrite };
58
58
  }
@@ -1,12 +1,12 @@
1
1
  // Commands start in the foreground. Only work still running after the
2
- // 15 s coordination budget is promoted to a tracked background task.
2
+ // 10 s coordination budget is promoted to a tracked background task.
3
3
  // Short commands therefore complete in the original tool turn, while longer
4
4
  // work returns partial output plus task_id and finishes by notification.
5
- // 15 s because a command promoted moments before it ends costs a whole
6
- // follow-up request on `task wait`. Session logs (2026-09-30..10-05), the 260
7
- // promoted commands with a recorded duration: 108 had ended within 10 s, 144
8
- // within 15 s and only 152 within 20 s.
9
- export const DEFAULT_SHELL_AUTO_BACKGROUND_MS = 15_000;
5
+ // A per-call wait_ms may stretch the window for a command whose result should
6
+ // return in the same call, never past 30 s, so the conversation is never held
7
+ // open long; anything longer finishes by notification.
8
+ export const DEFAULT_SHELL_AUTO_BACKGROUND_MS = 10_000;
9
+ export const MAX_SHELL_WAIT_MS = 30_000;
10
10
 
11
11
  // JS timers (setTimeout) and PS WaitForExit(ms) are 32-bit: a delay above
12
12
  // 2^31-1 wraps to a tiny/negative value and fires immediately. Clamp the
@@ -17,17 +17,14 @@ const TIMER_MAX_MS = 2_147_483_647;
17
17
 
18
18
  // Main-agent blocking budget. A timeout is the command's total deadline, not
19
19
  // permission to hold the conversation open for that whole duration: after
20
- // 15 s a still-running command becomes a tracked background task and
20
+ // 10 s a still-running command becomes a tracked background task and
21
21
  // completion is pushed to the owner. MIXDOG_SHELL_AUTO_BACKGROUND_MS
22
22
  // overrides; an explicit 0 disables. Gated on backgroundOnTimeout so
23
23
  // disabled background tasks remain foreground.
24
- // A per-call wait_ms extends that default for the call, capped by the
25
- // foreground maximum; it never shortens it. A shorter window promotes a
26
- // command that would have returned its result in the starting call and spends
27
- // a whole follow-up request on `task wait`. Session logs (2026-09-30..10-05,
28
- // 3062 shell calls): 329 passed a wait_ms under the default (53% of one model
29
- // family's calls), 256 of those were promoted, and 108 of the 192 with a
30
- // recorded duration had finished inside the default window (10 s then).
24
+ // A per-call wait_ms extends that default for the call, capped by
25
+ // MAX_SHELL_WAIT_MS and the foreground maximum; it never shortens it. A
26
+ // shorter window promotes a command that would have returned its result in
27
+ // the starting call and spends a whole follow-up request on `task wait`.
31
28
  function autoBackgroundBudget(backgroundOnTimeout, timeout, waitMs, maxForegroundMs) {
32
29
  const raw = process.env.MIXDOG_SHELL_AUTO_BACKGROUND_MS;
33
30
  const parsed = Number(raw);
@@ -35,7 +32,7 @@ function autoBackgroundBudget(backgroundOnTimeout, timeout, waitMs, maxForegroun
35
32
  raw != null && String(raw).trim() !== '' && Number.isFinite(parsed) && parsed >= 0
36
33
  ? Math.floor(parsed)
37
34
  : DEFAULT_SHELL_AUTO_BACKGROUND_MS;
38
- if (waitMs > 0) defaultMs = Math.max(defaultMs, Math.min(waitMs, maxForegroundMs));
35
+ if (waitMs > 0) defaultMs = Math.max(defaultMs, Math.min(waitMs, MAX_SHELL_WAIT_MS, maxForegroundMs));
39
36
  if (!backgroundOnTimeout || defaultMs <= 0) return 0;
40
37
  return timeout > 0 ? Math.min(defaultMs, timeout) : defaultMs;
41
38
  }
@@ -61,7 +61,9 @@ export async function executeBashTool(args, workDir, options = {}) {
61
61
  // Every call starts from the current Project root. A command-local `cd`
62
62
  // never creates a second session cwd authority beside the dedicated cwd tool.
63
63
  const bashWorkDir = workDir;
64
- const prepared = prepareShellCommand(args);
64
+ // Approval comes from the runtime's options, never from model-supplied args.
65
+ const elevationApproved = options?.elevationApproved === true;
66
+ const prepared = prepareShellCommand(args, { elevationApproved });
65
67
  if (prepared.failure) return prepared.failure;
66
68
  const { resolvedSpec, wmicRewrite, bashismRewrite } = prepared;
67
69
  // Effects are analyzed on the command as the caller meant it, before the
@@ -97,6 +99,7 @@ export async function executeBashTool(args, workDir, options = {}) {
97
99
  command: invocation.wrappedCommand,
98
100
  execScript: invocation.execScript,
99
101
  directArgv: invocation.directArgv,
102
+ elevationApproved,
100
103
  env: invocation.spawnEnv,
101
104
  cwd: bashWorkDir,
102
105
  timeoutMs: deadlines.timeout,
@@ -146,7 +146,7 @@ export const BUILTIN_TOOLS = [
146
146
  openWorldHint: true,
147
147
  compressible: true,
148
148
  },
149
- description: `Run programs, builds, tests and computation. Never use shell commands or scripts for work covered by dedicated tools: cat/head/tail→read, ls→list, find→glob, filename lookup→find, grep/rg→grep, code structure→code_graph, file edits/writes (sed/awk/redirection)→edit/apply_patch, Git→git when that tool is on the surface. Tool names are not shell commands. ${_shellBackgroundDisabled ? 'Commands run in the foreground until completion.' : 'After a 15s foreground window (not a timeout; wait_ms extends it up to 120s for one call, e.g. a test suite), unfinished work continues under task_id; use task wait, not read polling. If no execution slot frees within the admission wait, the command is queued as a background task with a task_id. Dev servers/watchers: pass timeout_ms or stop them with task cancel when done.'}`,
149
+ description: `Run programs, builds, tests and computation. Never use shell commands or scripts for work covered by dedicated tools: cat/head/tail→read, ls→list, find→glob, filename lookup→find, grep/rg→grep, code structure→code_graph, file edits/writes (sed/awk/redirection)→edit/apply_patch, Git→git when that tool is on the surface. Tool names are not shell commands. ${_shellBackgroundDisabled ? 'Commands run in the foreground until completion.' : 'After a 10s foreground window (not a timeout; omit wait_ms by default, set it up to 30s only for a command you expect to finish in 10–30s, e.g. one test file), unfinished work continues under task_id; use task wait, not read polling. If no execution slot frees within the admission wait, the command is queued as a background task with a task_id. Dev servers/watchers: pass timeout_ms or stop them with task cancel when done.'}`,
150
150
  inputSchema: {
151
151
  type: 'object',
152
152
  properties: {
@@ -155,14 +155,14 @@ export const BUILTIN_TOOLS = [
155
155
  type: 'integer',
156
156
  minimum: 0,
157
157
  description:
158
- 'Hard kill deadline in ms (omit or 0 = none), separate from the 15s foreground window; set one for throwaway probes so a slow check fails fast.',
158
+ 'Hard kill deadline in ms (omit or 0 = none), separate from the 10s foreground window; set one for throwaway probes so a slow check fails fast.',
159
159
  },
160
160
  wait_ms: {
161
161
  type: 'integer',
162
- minimum: 15000,
163
- maximum: 120000,
162
+ minimum: 10000,
163
+ maximum: 30000,
164
164
  description:
165
- 'Foreground wait in ms before unfinished work continues as a background task (default 15000); raise it for a command that should return its result in this call.',
165
+ 'Foreground wait in ms before unfinished work continues as a background task (default 10000). Omit it by default. Set it only when you expect the command to finish within 10–30s (e.g. one test file or a small build step); never for work expected to take longer, which finishes by notification.',
166
166
  },
167
167
  },
168
168
  required: ['command'],
@@ -37,6 +37,7 @@ import { decodeValidUtf8OrNull, detectPatchTargetCodec, nearestPatchLineMatch }
37
37
  import { hashText } from './hash-utils.mjs';
38
38
  import { invalidateBuiltinResultCache } from './cache-layers.mjs';
39
39
  import { markCodeGraphDirtyPaths } from '../code-graph-state.mjs';
40
+ import { reviewFileContent } from '../../../../shared/bounded-file-read.mjs';
40
41
 
41
42
  const STR_REPLACE_NAMES = new Set(['edit', 'strreplace', 'str_replace', 'str_replace_editor', 'search_replace']);
42
43
  const WRITE_NAMES = new Set(['write', 'create_file', 'createfile']);
@@ -189,26 +190,27 @@ function recordEditSnapshot(fullPath, options, contentHash = null, preMutationSt
189
190
  // UI diff parity with apply_patch: register the before/after pair on the
190
191
  // shared per-call side channel so tool cards render edit results with the
191
192
  // same diff markup. Lazy import breaks the orchestrator→builtin→adapters
192
- // module cycle; failures never affect the edit result.
193
- async function recordEditUiDiff(options, workDir, fullPath, before, after, encoding) {
193
+ // module cycle; failures never affect the edit result. `sides()` yields the
194
+ // file's `{ before, after }` content (null = absent).
195
+ async function recordToolUiDiff(options, workDir, fullPath, sides) {
194
196
  const callId = options?.toolCallId;
195
197
  const sessionId = options?.sessionId || options?.readStateScope;
196
198
  if (!callId || !sessionId) return;
197
199
  try {
198
200
  const { registerEditToolUiDiff } = await import('../patch/orchestrator.mjs');
199
- registerEditToolUiDiff({
200
- callId,
201
- sessionId,
202
- basePath: workDir,
203
- fullPath,
204
- before: before === null ? null : encodeEditContent(before, encoding),
205
- after: after === null ? null : encodeEditContent(after, encoding),
206
- });
201
+ registerEditToolUiDiff({ callId, sessionId, basePath: workDir, fullPath, ...sides() });
207
202
  } catch {
208
203
  /* best-effort display channel */
209
204
  }
210
205
  }
211
206
 
207
+ async function recordEditUiDiff(options, workDir, fullPath, before, after, encoding) {
208
+ await recordToolUiDiff(options, workDir, fullPath, () => ({
209
+ before: before === null ? null : encodeEditContent(before, encoding),
210
+ after: after === null ? null : encodeEditContent(after, encoding),
211
+ }));
212
+ }
213
+
212
214
  // The 0-based line the failure excerpt centres on, or -1: the engine's
213
215
  // "nearest match" hint, else the exact old_string, else its longest tokens,
214
216
  // else the fuzzy line scorer.
@@ -828,6 +830,7 @@ async function adaptWrite(args, workDir, options) {
828
830
  if (target.error) return target.error;
829
831
  const fullPath = target.full;
830
832
  const existed = existsSync(fullPath);
833
+ const before = existed ? reviewFileContent(fullPath) : null;
831
834
  try {
832
835
  mkdirSync(dirname(fullPath), { recursive: true });
833
836
  } catch {
@@ -835,6 +838,7 @@ async function adaptWrite(args, workDir, options) {
835
838
  }
836
839
  await atomicWrite(fullPath, contents, { sessionId: editScope(options) });
837
840
  invalidateAfterWrite(fullPath);
841
+ await recordToolUiDiff(options, workDir, fullPath, () => ({ before, after: contents }));
838
842
  return `${existed ? 'Updated' : 'Created'} ${fullPath} (${Buffer.byteLength(contents, 'utf8')} bytes)`;
839
843
  }
840
844