mixdog 1.3.5 → 1.4.1

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 (515) hide show
  1. package/NOTICE.md +2 -2
  2. package/README.md +2 -2
  3. package/package.json +2 -11
  4. package/scripts/check-voice-runtime-inputs.mjs +25 -0
  5. package/scripts/daemon-stub.mjs +1 -1
  6. package/scripts/gate-local.mjs +16 -5
  7. package/scripts/latest-guard.mjs +21 -9
  8. package/scripts/lib/isolated-test-env.mjs +10 -5
  9. package/scripts/lib/run-node-tests.mjs +37 -37
  10. package/scripts/lib/scoped-temp.d.mts +16 -0
  11. package/scripts/lib/scoped-temp.mjs +123 -0
  12. package/scripts/lib/stale-temp.mjs +44 -0
  13. package/scripts/native-release-status.mjs +2 -2
  14. package/scripts/post-release-check.mjs +1 -6
  15. package/scripts/pptx-kit-index.mjs +17 -4
  16. package/scripts/recall-history-cases.json +1 -1
  17. package/scripts/suite-health.mjs +20 -2
  18. package/scripts/test-data-dir.mjs +10 -7
  19. package/scripts/test.mjs +7 -11
  20. package/src/agents/reviewer/AGENT.md +7 -11
  21. package/src/agents/reviewer/agent.json +1 -1
  22. package/src/app.mjs +4 -0
  23. package/src/defaults/shipped-history.json +22 -1
  24. package/src/defaults/skills/browser-use/SKILL.md +62 -12
  25. package/src/defaults/skills/code-tidy/SKILL.md +142 -270
  26. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
  27. package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
  28. package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
  29. package/src/defaults/skills/computer-use/SKILL.md +35 -9
  30. package/src/defaults/skills/setup/SKILL.md +22 -0
  31. package/src/defaults/skills/setup/references/actions.md +39 -5
  32. package/src/defaults/skills/setup/references/surfaces.md +11 -2
  33. package/src/defaults/skills/visualize/SKILL.md +2 -1
  34. package/src/lib/rules-builder.cjs +39 -20
  35. package/src/output-styles/common.md +2 -2
  36. package/src/output-styles/simple.md +1 -1
  37. package/src/rules/agent/AGENT.md +11 -10
  38. package/src/rules/lead/LEAD.md +23 -20
  39. package/src/rules/shared/05-tool-calls.md +5 -6
  40. package/src/rules/shared/10-tool-workflow.md +4 -0
  41. package/src/rules/shared/45-destructive.md +0 -2
  42. package/src/rules/shared/50-execution.md +2 -0
  43. package/src/rules/shared/60-verification.md +7 -5
  44. package/src/rules/shared/70-delivery.md +7 -9
  45. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -6
  46. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
  47. package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
  48. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
  49. package/src/runtime/agent/orchestrator/cache-break-trace.mjs +2 -0
  50. package/src/runtime/agent/orchestrator/config.mjs +17 -1
  51. package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
  52. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +73 -68
  53. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +57 -2
  54. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
  55. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
  56. package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
  57. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +5 -2
  58. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +192 -133
  59. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
  60. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +1 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +7 -3
  62. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +8 -2
  63. package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +6 -2
  65. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -2
  66. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  67. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
  69. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +3 -1
  70. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +159 -69
  71. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
  72. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +70 -33
  73. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -2
  74. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
  75. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
  76. package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
  77. package/src/runtime/agent/orchestrator/providers/command-code-oauth-login.mjs +1 -10
  78. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
  79. package/src/runtime/agent/orchestrator/providers/cursor.mjs +25 -13
  80. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/providers/devin.mjs +3 -0
  82. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +210 -20
  83. package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -11
  84. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +45 -6
  85. package/src/runtime/agent/orchestrator/providers/lib/first-output-window.mjs +58 -0
  86. package/src/runtime/agent/orchestrator/providers/lib/listen-on.mjs +14 -0
  87. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
  88. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
  89. package/src/runtime/agent/orchestrator/providers/mimo-oauth-login.mjs +1 -10
  90. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
  91. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  92. package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
  93. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
  94. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +1 -0
  95. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +9 -2
  96. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +7 -0
  97. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +14 -3
  98. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +4 -2
  99. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +1 -0
  100. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +5 -3
  101. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +16 -3
  102. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +1 -0
  103. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +5 -2
  104. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +13 -3
  105. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +13 -2
  106. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +81 -42
  107. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +8 -0
  108. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +136 -5
  109. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
  110. package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
  111. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
  112. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
  113. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +20 -12
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +7 -1
  116. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +48 -22
  117. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
  118. package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
  119. package/src/runtime/agent/orchestrator/providers/registry.mjs +38 -0
  120. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
  121. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
  122. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +49 -16
  123. package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
  124. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
  125. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
  126. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +7 -6
  127. package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +9 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
  129. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
  130. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +3 -1
  131. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +5 -2
  132. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +1 -3
  133. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +798 -0
  134. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -8
  136. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +23 -0
  137. package/src/runtime/agent/orchestrator/session/compact/observation-supersession.mjs +103 -23
  138. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +280 -45
  139. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
  140. package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
  141. package/src/runtime/agent/orchestrator/session/context-utils.mjs +13 -1
  142. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +163 -22
  143. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +132 -17
  144. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +38 -7
  145. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +3 -0
  146. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +90 -22
  147. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
  148. package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
  149. package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
  150. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
  151. package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
  152. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +51 -25
  153. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +37 -3
  154. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
  155. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
  156. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +13 -5
  158. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +31 -3
  159. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +20 -3
  160. package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
  161. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +5 -4
  162. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  163. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
  164. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +49 -21
  165. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
  166. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
  167. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
  168. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
  169. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
  170. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +3 -3
  171. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +3 -1
  172. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
  173. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
  174. package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +24 -14
  175. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
  176. package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
  177. package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +130 -0
  178. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +27 -9
  179. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +81 -8
  180. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
  181. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +27 -8
  182. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +12 -5
  183. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +9 -4
  185. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +4 -0
  186. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
  187. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +21 -5
  188. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +9 -0
  189. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +24 -9
  190. package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
  191. package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +150 -0
  192. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +154 -0
  193. package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
  194. package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
  195. package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
  196. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
  197. package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
  198. package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
  199. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
  200. package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
  201. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
  202. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +7 -0
  203. package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
  204. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
  205. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +16 -2
  206. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +15 -0
  207. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +81 -22
  208. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +92 -3
  209. package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
  210. package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
  211. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
  212. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
  213. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +79 -3
  214. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
  215. package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
  216. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
  217. package/src/runtime/agent/orchestrator/stall-policy.mjs +23 -0
  218. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
  219. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
  220. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/invocation-plan.mjs +2 -2
  221. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
  222. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  223. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
  224. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/spawn-env.mjs +4 -2
  225. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +31 -6
  226. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +110 -26
  227. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +7 -1
  228. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +31 -5
  229. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +22 -8
  230. package/src/runtime/agent/orchestrator/tools/builtin/lib/scoped-search-flight.mjs +9 -5
  231. package/src/runtime/agent/orchestrator/tools/builtin/read-single-stream.mjs +7 -1
  232. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +6 -3
  233. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-dispatch.mjs +1 -1
  234. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-publication.mjs +23 -12
  235. package/src/runtime/agent/orchestrator/tools/builtin/read-tool/batch-snapshot.mjs +6 -1
  236. package/src/runtime/agent/orchestrator/tools/builtin/read-tool.mjs +1 -8
  237. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
  238. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/federation.mjs +3 -1
  239. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +1 -1
  240. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  241. package/src/runtime/agent/orchestrator/tools/lib/isolated-test-env.mjs +4 -3
  242. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +26 -4
  243. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
  244. package/src/runtime/browser-bridge/action-schema.mjs +13 -2
  245. package/src/runtime/browser-bridge/client.mjs +73 -8
  246. package/src/runtime/browser-bridge/input-fields.mjs +8 -9
  247. package/src/runtime/browser-bridge/mail-links.mjs +107 -0
  248. package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
  249. package/src/runtime/channels/lib/config.mjs +6 -61
  250. package/src/runtime/channels/lib/crash-log.mjs +1 -1
  251. package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
  252. package/src/runtime/channels/lib/event-queue.mjs +3 -18
  253. package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
  254. package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
  255. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
  256. package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
  257. package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
  258. package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
  259. package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
  260. package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
  261. package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
  262. package/src/runtime/channels/lib/scheduler.mjs +33 -147
  263. package/src/runtime/channels/lib/schedules-db.mjs +34 -11
  264. package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
  265. package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
  266. package/src/runtime/channels/lib/webhook/signature.mjs +4 -1
  267. package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
  268. package/src/runtime/channels/lib/whisper-port.mjs +10 -1
  269. package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
  270. package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
  271. package/src/runtime/channels/lib/worker-main.mjs +10 -34
  272. package/src/runtime/computer-bridge/action-schema.mjs +42 -1
  273. package/src/runtime/computer-bridge/actions.mjs +9 -1
  274. package/src/runtime/computer-bridge/client.mjs +180 -8
  275. package/src/runtime/computer-bridge/core-actions.mjs +2 -2
  276. package/src/runtime/computer-bridge/error-recovery.mjs +28 -2
  277. package/src/runtime/computer-bridge/linux-action-capabilities.mjs +24 -5
  278. package/src/runtime/computer-bridge/linux-readiness.d.mts +7 -2
  279. package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
  280. package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
  281. package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
  282. package/src/runtime/connectors/gmail-app-password.mjs +172 -39
  283. package/src/runtime/connectors/google-mcp.mjs +10 -12
  284. package/src/runtime/local-provider/server-process.mjs +2 -1
  285. package/src/runtime/media/adapters/gemini-video.mjs +4 -1
  286. package/src/runtime/media/adapters/xai-media.mjs +2 -1
  287. package/src/runtime/memory/lib/embedding-worker.mjs +6 -3
  288. package/src/runtime/memory/lib/memory-action-handlers/cycle-backfill-action.mjs +1 -7
  289. package/src/runtime/memory/lib/memory-chunk-quality.mjs +1 -6
  290. package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
  291. package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
  292. package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
  293. package/src/runtime/office/authoring/pdf-author-action.mjs +1 -6
  294. package/src/runtime/office/design/design-art-direction.mjs +29 -27
  295. package/src/runtime/office/pdf/pdf-writer.mjs +6 -1
  296. package/src/runtime/office/portable/portable-snapshot-docx.mjs +7 -1
  297. package/src/runtime/office/portable/portable-snapshot-shared.mjs +6 -1
  298. package/src/runtime/office/quality/assurance-rendered.mjs +9 -2
  299. package/src/runtime/office/quality/assurance-structure-docx.mjs +3 -1
  300. package/src/runtime/office/quality/design-review.mjs +1 -5
  301. package/src/runtime/office/quality/document-brief.mjs +1 -5
  302. package/src/runtime/office/quality/forced-break-pages.mjs +9 -6
  303. package/src/runtime/office/quality/quality-pipeline.mjs +1 -1
  304. package/src/runtime/session-search/session-search-db.mjs +73 -9
  305. package/src/runtime/session-search/session-search-ingest.mjs +110 -20
  306. package/src/runtime/shared/abort-race.mjs +89 -0
  307. package/src/runtime/shared/agent-avatar.d.mts +0 -1
  308. package/src/runtime/shared/agent-kind.mjs +4 -3
  309. package/src/runtime/shared/bot-owned-work.mjs +56 -0
  310. package/src/runtime/shared/bounded-download.mjs +8 -3
  311. package/src/runtime/shared/config.mjs +2 -13
  312. package/src/runtime/shared/connector-accounts.mjs +20 -10
  313. package/src/runtime/shared/connector-catalog.d.mts +29 -0
  314. package/src/runtime/shared/connector-catalog.mjs +150 -0
  315. package/src/runtime/shared/connector-triggers.mjs +22 -19
  316. package/src/runtime/shared/defaults-separation.mjs +2 -17
  317. package/src/runtime/shared/delegated-approval-host.mjs +103 -11
  318. package/src/runtime/shared/err-text.mjs +24 -15
  319. package/src/runtime/shared/fetch-safe-listen.d.mts +16 -0
  320. package/src/runtime/shared/fetch-safe-listen.mjs +50 -0
  321. package/src/runtime/shared/file-permissions.d.mts +0 -8
  322. package/src/runtime/shared/file-permissions.mjs +0 -11
  323. package/src/runtime/shared/git-direct.test-support.mjs +19 -0
  324. package/src/runtime/shared/handoff-artifacts.d.mts +2 -1
  325. package/src/runtime/shared/handoff-artifacts.mjs +18 -8
  326. package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
  327. package/src/runtime/shared/heartbeat-interval.mjs +19 -0
  328. package/src/runtime/shared/idle-auto-clear-gate.mjs +126 -0
  329. package/src/runtime/shared/llm/cost.mjs +5 -1
  330. package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
  331. package/src/runtime/shared/loopback-listener.mjs +25 -2
  332. package/src/runtime/shared/mixy-presence.mjs +22 -0
  333. package/src/runtime/shared/model-route-chain.d.mts +7 -2
  334. package/src/runtime/shared/model-route-chain.mjs +22 -4
  335. package/src/runtime/shared/open-url.mjs +10 -0
  336. package/src/runtime/shared/orchestration.d.mts +2 -0
  337. package/src/runtime/shared/pg-schema-db.mjs +27 -16
  338. package/src/runtime/shared/profile-config.cjs +1 -1
  339. package/src/runtime/shared/prompt-origin.d.mts +4 -0
  340. package/src/runtime/shared/prompt-origin.mjs +21 -0
  341. package/src/runtime/shared/provider-accounts.mjs +7 -1
  342. package/src/runtime/shared/provider-display-name.mjs +29 -0
  343. package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
  344. package/src/runtime/shared/routine-trigger.d.mts +2 -0
  345. package/src/runtime/shared/routine-trigger.mjs +10 -0
  346. package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
  347. package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
  348. package/src/runtime/shared/session-activity-signal.mjs +48 -1
  349. package/src/runtime/shared/session-scratch.mjs +37 -0
  350. package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
  351. package/src/runtime/shared/session-sidebar-host.mjs +7 -3
  352. package/src/runtime/shared/session-turn-prelude.mjs +18 -0
  353. package/src/runtime/shared/tool-card-model/agent-surface.mjs +1 -3
  354. package/src/runtime/shared/tool-card-model/card-status.mjs +15 -2
  355. package/src/runtime/shared/tool-result-summary.mjs +2 -15
  356. package/src/runtime/shared/tool-surface.mjs +3 -0
  357. package/src/runtime/shared/tool-work-units.mjs +2 -0
  358. package/src/runtime/shared/turn-snapshot-store.mjs +13 -6
  359. package/src/runtime/shared/worktrees/contract.mjs +4 -1
  360. package/src/runtime/shared/worktrees/git.mjs +15 -0
  361. package/src/runtime/shared/worktrees/manager.mjs +87 -38
  362. package/src/runtime/shared/worktrees/test-support.mjs +14 -13
  363. package/src/runtime/terminal-bridge/client.mjs +10 -1
  364. package/src/runtime/visualize-bridge/client.mjs +29 -8
  365. package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
  366. package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
  367. package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
  368. package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
  369. package/src/session-runtime/agent-home-delivery.mjs +489 -185
  370. package/src/session-runtime/agent-task-sessions.mjs +467 -229
  371. package/src/session-runtime/agent-tool-routing.mjs +8 -41
  372. package/src/session-runtime/boot/apis.mjs +9 -0
  373. package/src/session-runtime/boot/infrastructure.mjs +4 -0
  374. package/src/session-runtime/boot/providers.mjs +3 -0
  375. package/src/session-runtime/boot/tools.mjs +11 -2
  376. package/src/session-runtime/bot-status.mjs +12 -6
  377. package/src/session-runtime/bot-target.mjs +38 -0
  378. package/src/session-runtime/channel-config-api.mjs +6 -1
  379. package/src/session-runtime/config-lifecycle.mjs +6 -0
  380. package/src/session-runtime/connector-merge-migration.mjs +305 -0
  381. package/src/session-runtime/conversation-import/codex-titles.mjs +88 -0
  382. package/src/session-runtime/conversation-import/discovery.mjs +271 -25
  383. package/src/session-runtime/conversation-import/service.mjs +26 -5
  384. package/src/session-runtime/handoff-attachments.mjs +82 -31
  385. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +144 -41
  386. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -0
  387. package/src/session-runtime/internal-tool-executor/reaction-tool.mjs +4 -1
  388. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +8 -2
  389. package/src/session-runtime/lifecycle/cold-heir.mjs +11 -6
  390. package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
  391. package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
  392. package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
  393. package/src/session-runtime/lifecycle/teardown.mjs +23 -5
  394. package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
  395. package/src/session-runtime/mcp-oauth-login.mjs +5 -3
  396. package/src/session-runtime/mixy-heartbeat.mjs +153 -33
  397. package/src/session-runtime/model-route/set-route.mjs +11 -2
  398. package/src/session-runtime/notification-bus.mjs +31 -117
  399. package/src/session-runtime/notification-completion-queue.mjs +54 -0
  400. package/src/session-runtime/notification-listeners.mjs +76 -0
  401. package/src/session-runtime/owned-automation-run.mjs +2 -1
  402. package/src/session-runtime/prewarm/channel-start.mjs +3 -7
  403. package/src/session-runtime/provider-catalog-cache.mjs +82 -36
  404. package/src/session-runtime/provider-models/catalog-load.mjs +23 -6
  405. package/src/session-runtime/provider-models.mjs +4 -2
  406. package/src/session-runtime/resource-mcp-api.mjs +143 -224
  407. package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
  408. package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
  409. package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
  410. package/src/session-runtime/resource-mcp-servers.mjs +78 -0
  411. package/src/session-runtime/resource-mcp-store.mjs +49 -0
  412. package/src/session-runtime/resource-recall-api.mjs +6 -1
  413. package/src/session-runtime/routine-owner.mjs +40 -9
  414. package/src/session-runtime/runtime-feature-gates.mjs +5 -1
  415. package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
  416. package/src/session-runtime/services/agent-tool/execute.mjs +14 -9
  417. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +20 -4
  418. package/src/session-runtime/services/agent-tool/model-select.mjs +48 -7
  419. package/src/session-runtime/services/agent-tool/render.mjs +71 -17
  420. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +13 -4
  421. package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
  422. package/src/session-runtime/services/agent-tool/tool-def.mjs +9 -9
  423. package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
  424. package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
  425. package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
  426. package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
  427. package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
  428. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
  429. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
  430. package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
  431. package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
  432. package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
  433. package/src/session-runtime/services/channel-admin.mjs +7 -13
  434. package/src/session-runtime/services/channel-session-router.mjs +4 -2
  435. package/src/session-runtime/services/provider-admin.mjs +2 -1
  436. package/src/session-runtime/services/seeds.mjs +0 -28
  437. package/src/session-runtime/session-compaction-sync.mjs +27 -0
  438. package/src/session-runtime/session-create/session-options.mjs +1 -0
  439. package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
  440. package/src/session-runtime/settings-compaction-api.mjs +2 -40
  441. package/src/session-runtime/settings-system-api.mjs +13 -1
  442. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
  443. package/src/session-runtime/setup-tool/executor.mjs +145 -22
  444. package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
  445. package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
  446. package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
  447. package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
  448. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
  449. package/src/session-runtime/tool-policy/policy-stage.mjs +17 -2
  450. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
  451. package/src/session-runtime/workflow-agents-api/agent-editor.mjs +5 -1
  452. package/src/session-runtime/workflow-agents-api/agent-route.mjs +15 -4
  453. package/src/session-runtime/workflow-agents-api/onboarding.mjs +3 -3
  454. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
  455. package/src/session-runtime/workspace/transitions.mjs +25 -0
  456. package/src/session-runtime/workspace/worktree-tool.mjs +26 -9
  457. package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
  458. package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
  459. package/src/standalone/channel-transport/client-registry.mjs +24 -163
  460. package/src/standalone/channel-transport.mjs +1 -1
  461. package/src/standalone/daemon-channels-loader.mjs +10 -8
  462. package/src/standalone/daemon-session-control/list-page.mjs +72 -0
  463. package/src/standalone/daemon-session-control/request.mjs +51 -0
  464. package/src/standalone/daemon-session-control/room-host.mjs +57 -0
  465. package/src/standalone/daemon-session-control/route-control.mjs +48 -0
  466. package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
  467. package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
  468. package/src/standalone/daemon-session-control.mjs +142 -190
  469. package/src/standalone/daemon.mjs +26 -3
  470. package/src/standalone/session-client.mjs +7 -3
  471. package/src/standalone/session-protocol.mjs +5 -0
  472. package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
  473. package/src/standalone/session-service/agent-tree/agent-turns.mjs +16 -12
  474. package/src/standalone/session-service/quota-resume.mjs +3 -0
  475. package/src/standalone/session-service/retention/busy.mjs +65 -1
  476. package/src/standalone/session-service/session-calls/session-action.mjs +30 -2
  477. package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
  478. package/src/standalone/session-tool-output.mjs +15 -7
  479. package/src/standalone/session-transport/client-registry/client-grace.mjs +12 -9
  480. package/src/tui/app/app-view/floating-panel.jsx +7 -4
  481. package/src/tui/app/model-options.mjs +3 -28
  482. package/src/tui/app/model-picker/route-selection/fast-parameters.mjs +1 -3
  483. package/src/tui/app/model-picker/route-selection.mjs +5 -6
  484. package/src/tui/app/provider-setup/oauth-actions.mjs +38 -20
  485. package/src/tui/app/provider-setup/provider-items.mjs +8 -2
  486. package/src/tui/app/provider-setup-picker.mjs +9 -5
  487. package/src/tui/components/QuestionPanel.jsx +13 -4
  488. package/src/tui/dist/index.mjs +133 -92
  489. package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
  490. package/src/tui/session/initial-state.mjs +3 -0
  491. package/src/tui/session/notice-surface.mjs +7 -1
  492. package/src/tui/session/queue-helpers.mjs +3 -42
  493. package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
  494. package/src/tui/session/session-api/routes-write.mjs +5 -1
  495. package/src/tui/session/session-api/routes.mjs +1 -0
  496. package/src/tui/session/session-api/settings.mjs +17 -1
  497. package/src/tui/session/session-flow/auto-clear.mjs +4 -33
  498. package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
  499. package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
  500. package/src/tui/session/session-flow/drain-retry.mjs +35 -0
  501. package/src/tui/session/session-flow/drain.mjs +118 -149
  502. package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
  503. package/src/tui/session/session-flow/queue/take-entries.mjs +16 -2
  504. package/src/tui/session/tool-approval-delegation.mjs +64 -0
  505. package/src/tui/session/tool-approval-request.mjs +39 -0
  506. package/src/tui/session/tool-approval-settle.mjs +62 -0
  507. package/src/tui/session/tool-approval.mjs +69 -115
  508. package/src/tui/session/tui-steering-persist.mjs +8 -1
  509. package/src/tui/session/turn-stream.mjs +19 -2
  510. package/src/tui/session/turn.mjs +1 -0
  511. package/src/ui/statusline-agents.mjs +1 -3
  512. package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
  513. package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
  514. package/scripts/code-graph-description-contract.mjs +0 -188
  515. package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
@@ -83,6 +83,9 @@ const SERVER_OPERATIONS = new Set(['daemon', 'instaweb']);
83
83
  // probe into `git rev-parse exited 128` inside a plain directory.
84
84
  const REPO_FREE_OPERATIONS = new Set(['version', 'help']);
85
85
 
86
+ const GIT_DESCRIPTION_HEAD =
87
+ 'Run Git here, never through shell. An array runs in order and stops on failure; batch read-only commands in one. diff for known changes, status to discover them; history only when needed. git diff or git diff -- <paths> includes untracked files. Set include_stage_ids:true to select changes, then action:stage with diff_id/change_ids. Staging rejects stale or cross-Project diffs and returns per-file staged counts.';
88
+
86
89
  export const GIT_TOOL_DEF = {
87
90
  name: 'git',
88
91
  title: 'Git',
@@ -94,8 +97,7 @@ export const GIT_TOOL_DEF = {
94
97
  openWorldHint: true,
95
98
  compressible: true,
96
99
  },
97
- description:
98
- 'Run Git here, never through shell. An array (max 10) runs in order and stops on failure; batch read-only commands in one. diff for known changes, status to discover them; history only when needed. git diff or git diff -- <paths> includes untracked files. Set include_stage_ids:true to select changes, then action:stage with diff_id/change_ids. Staging rejects stale or cross-Project diffs and returns per-file staged counts. Worktrees are managed only: action:worktree (Lead only) moves a session into/out of its managed worktree, merges, removes, lists, prunes; git worktree add/remove/list/prune map to managed operations (add -b keeps the session in place; add --detach makes a read-only snapshot worktree, removed when its turn ends; list --porcelain stays raw git; move/lock/unlock/repair are refused). Merge or remove only when the user asks; carry and large-size answers come from the user; force only on explicit request.',
100
+ description: `${GIT_DESCRIPTION_HEAD} Worktrees are managed only: action:worktree; git worktree add/remove/list/prune map to managed operations (add -b keeps the session in place; add --detach makes a read-only snapshot worktree, removed when its turn ends; list --porcelain stays raw git; move/lock/unlock/repair are refused). Merge or remove only when the user asks.`,
99
101
  inputSchema: {
100
102
  type: 'object',
101
103
  properties: {
@@ -118,14 +120,14 @@ export const GIT_TOOL_DEF = {
118
120
  minimum: 1,
119
121
  maximum: GIT_OUTPUT_LIMIT_MAX,
120
122
  description:
121
- 'Body line cap, max 1000; staging IDs are not capped. Default 500; git log defaults to 100. A cut ends with [output capped …] naming how to continue.',
123
+ 'Body line cap; staging IDs are not capped. Default 500; git log defaults to 100. A cut ends with [output capped …] naming how to continue.',
122
124
  },
123
125
  include_stage_ids: {
124
126
  type: 'boolean',
125
127
  description:
126
128
  'Include staging IDs outside the body cap for git diff or git diff -- <paths> only. Default false.',
127
129
  },
128
- diff_id: { type: 'string', description: 'stage: exact diff_id from git diff with include_stage_ids:true.' },
130
+ diff_id: { type: 'string', description: 'stage: exact diff_id from git diff.' },
129
131
  change_ids: {
130
132
  anyOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: 50 }],
131
133
  description: 'stage: exact change ID or IDs to stage, including new files.',
@@ -158,6 +160,29 @@ export const GIT_TOOL_DEF = {
158
160
  },
159
161
  };
160
162
 
163
+ // Only the Lead host runs enter/return/merge/remove/prune (git-worktree-tool.mjs
164
+ // leadHost); an agent keeps `list`, so its schema omits every field the other
165
+ // operations take.
166
+ const LEAD_ONLY_WORKTREE_FIELDS = ['session_id', 'name', 'branch', 'create', 'carry', 'confirm_large', 'force'];
167
+
168
+ function buildGitAgentToolDef(base) {
169
+ const properties = { ...base.inputSchema.properties };
170
+ for (const field of LEAD_ONLY_WORKTREE_FIELDS) delete properties[field];
171
+ properties.action = {
172
+ ...properties.action,
173
+ description: 'Default command. stage uses diff_id/change_ids instead of command. worktree uses worktree_action.',
174
+ };
175
+ properties.worktree_action = { type: 'string', enum: ['list'], description: 'list only.' };
176
+ return {
177
+ ...base,
178
+ description: `${GIT_DESCRIPTION_HEAD} Worktrees are Lead-managed: only worktree_action:list and git worktree list work; every other worktree operation is refused.`,
179
+ inputSchema: { ...base.inputSchema, properties },
180
+ };
181
+ }
182
+
183
+ /** The git tool as a delegated agent sees it (see bindAgentOwner). */
184
+ export const GIT_AGENT_TOOL_DEF = buildGitAgentToolDef(GIT_TOOL_DEF);
185
+
161
186
  function cleanText(value) {
162
187
  return String(value || '')
163
188
  .replace(/\r\n/g, '\n')
@@ -849,7 +874,8 @@ function snapshotContaining(repo) {
849
874
  }
850
875
  return (
851
876
  Object.values(entries).find(
852
- (record) => record?.kind === WORKTREE_SNAPSHOT_KIND && typeof record.path === 'string' && isWithin(record.path, repo)
877
+ (record) =>
878
+ record?.kind === WORKTREE_SNAPSHOT_KIND && typeof record.path === 'string' && isWithin(record.path, repo)
853
879
  ) ?? null
854
880
  );
855
881
  }
@@ -101,6 +101,8 @@ function worktreeFailureText(code, message, details) {
101
101
  return typeof details.path === 'string' && details.path
102
102
  ? `This branch is already checked out in ${details.path}.`
103
103
  : 'This branch is already checked out in another worktree.';
104
+ case 'WORKTREE_DEFAULT_BRANCH':
105
+ return "The repository's default branch can't be opened in a worktree: the project folder could not switch to it while the worktree exists. Check it out in the project folder, or create a new branch for the worktree.";
104
106
  case 'WORKTREE_REMOVAL_INCOMPLETE':
105
107
  return 'The worktree could not be removed completely because a file is still in use. Close it and remove the worktree again.';
106
108
  case 'WORKTREE_PATH_UNSAFE':
@@ -162,6 +164,8 @@ function nextStep(code, details, { raw }) {
162
164
  return 'The workspace changed meanwhile; call again (the workspace is read afresh).';
163
165
  case 'WORKTREE_BUSY_JOBS':
164
166
  return 'Nothing was changed; try again once the session and its workers are idle.';
167
+ case 'WORKTREE_DEFAULT_BRANCH':
168
+ return 'Nothing was created. Work on a new branch instead (worktree_action:"enter" with branch and create:true), or ask the user to check the default branch out in the project folder.';
165
169
  case 'MERGE_CONFLICT':
166
170
  return 'Nothing was merged or forced. Resolve the conflict in the worktree (merge the target branch into it there), or ask the user.';
167
171
  case 'WORKTREE_DIRTY':
@@ -316,7 +320,8 @@ async function rawAdd(plan, input, options) {
316
320
  throw new Error(`git worktree add: ${value} is not supported for managed worktrees`);
317
321
  }
318
322
  if (ADD_BARE_FLAGS.has(value)) continue;
319
- if (value.startsWith('-')) throw new Error(`git worktree add: option ${value} is not supported for managed worktrees`);
323
+ if (value.startsWith('-'))
324
+ throw new Error(`git worktree add: option ${value} is not supported for managed worktrees`);
320
325
  positional.push(value);
321
326
  }
322
327
  const [path, commitish = null] = positional;
@@ -436,8 +441,9 @@ async function rawPrune(plan, options) {
436
441
  const WORKTREE_HELP = Object.freeze({
437
442
  add: 'git worktree add [-b <branch>] [--detach] <path> [<commit-ish>]: a managed worktree for the branch (the session stays put), or a read-only snapshot for a detached commit.',
438
443
  remove: 'git worktree remove [-f] <path>: the managed removal of that worktree.',
439
- list: 'git worktree list [-v]: managed worktrees plus the repository\'s other worktrees. --porcelain stays raw git.',
440
- prune: 'git worktree prune [-n|--dry-run] [-v]: the managed prune of this repository (clean, merged worktrees no session retains); -n only lists what it would remove.',
444
+ list: "git worktree list [-v]: managed worktrees plus the repository's other worktrees. --porcelain stays raw git.",
445
+ prune:
446
+ 'git worktree prune [-n|--dry-run] [-v]: the managed prune of this repository (clean, merged worktrees no session retains); -n only lists what it would remove.',
441
447
  });
442
448
 
443
449
  /** -h/--help before any `--` (the help answers instead of the operation running). */
@@ -450,7 +456,9 @@ function wantsHelp(args) {
450
456
  function checkListArgs(args) {
451
457
  for (const value of args) {
452
458
  if (value === '-v' || value === '--verbose') continue;
453
- throw new Error(`git worktree list: ${value.startsWith('-') ? `option ${value} is not supported` : `unexpected argument ${value}`}`);
459
+ throw new Error(
460
+ `git worktree list: ${value.startsWith('-') ? `option ${value} is not supported` : `unexpected argument ${value}`}`
461
+ );
454
462
  }
455
463
  }
456
464
 
@@ -466,7 +474,8 @@ export async function executeRawWorktree(plan, input, options = {}) {
466
474
  if (sub === 'list' && plan.args.includes('--porcelain')) return null;
467
475
  try {
468
476
  if (sub === 'list') checkListArgs(plan.args.slice(1));
469
- if (sub === 'list') return { text: okJson({ mapped: plan.command, ...(await listRows(options, plan.cwd)) }), failed: false };
477
+ if (sub === 'list')
478
+ return { text: okJson({ mapped: plan.command, ...(await listRows(options, plan.cwd)) }), failed: false };
470
479
  if (sub === 'add') return { text: await rawAdd(plan, input, options), failed: false };
471
480
  if (sub === 'remove') return { text: await rawRemove(plan, options), failed: false };
472
481
  if (sub === 'prune') return { text: await rawPrune(plan, options), failed: false };
@@ -479,7 +488,9 @@ export async function executeRawWorktree(plan, input, options = {}) {
479
488
  };
480
489
  }
481
490
  return {
482
- text: fail(`git worktree ${sub || '(no subcommand)'} is not supported; use add, remove, list, prune or action:"worktree"`),
491
+ text: fail(
492
+ `git worktree ${sub || '(no subcommand)'} is not supported; use add, remove, list, prune or action:"worktree"`
493
+ ),
483
494
  failed: true,
484
495
  };
485
496
  } catch (error) {
@@ -529,7 +540,8 @@ export async function executeWorktreeAction(input, workDir, options = {}) {
529
540
  if (problem) return fail(problem);
530
541
  const action = input.worktree_action;
531
542
  try {
532
- if (action === 'list') return okJson({ worktree_action: action, ...(await listRows(options, resolve(workDir || process.cwd()))) });
543
+ if (action === 'list')
544
+ return okJson({ worktree_action: action, ...(await listRows(options, resolve(workDir || process.cwd()))) });
533
545
  const host = leadHost(options, `git worktree_action ${action}`);
534
546
  const sessionId = input.session_id?.trim() || null;
535
547
  const request = {
@@ -545,7 +557,9 @@ export async function executeWorktreeAction(input, workDir, options = {}) {
545
557
  }
546
558
  : {}),
547
559
  ...(action === 'remove' ? { force: input.force === true } : {}),
548
- ...(action === 'prune' ? { repoCommonDir: (await repositoryAt(resolve(workDir || process.cwd())))?.repoCommonDir ?? null } : {}),
560
+ ...(action === 'prune'
561
+ ? { repoCommonDir: (await repositoryAt(resolve(workDir || process.cwd())))?.repoCommonDir ?? null }
562
+ : {}),
549
563
  txId: txIdOf(options, action),
550
564
  };
551
565
  const result = await runOn(host, request, options);
@@ -8,11 +8,15 @@ import {
8
8
  // A shared scan's outcome belongs to every subscriber, not only the caller
9
9
  // whose computation won admission. Persisted cache hits contain safe text.
10
10
  export async function runScopedSearchInFlight(key, compute, options, outcome) {
11
- const settled = await runResultCacheInFlight(key, async ({ signal }) => {
12
- const scopedCacheOutcome = createScopedCacheOutcome();
13
- const result = await compute({ signal, scopedCacheOutcome });
14
- return { result, scopedCacheOutcome };
15
- }, options);
11
+ const settled = await runResultCacheInFlight(
12
+ key,
13
+ async ({ signal }) => {
14
+ const scopedCacheOutcome = createScopedCacheOutcome();
15
+ const result = await compute({ signal, scopedCacheOutcome });
16
+ return { result, scopedCacheOutcome };
17
+ },
18
+ options
19
+ );
16
20
  if (typeof settled === 'string') return settled;
17
21
  if (settled.scopedCacheOutcome.complete === false) markScopedCacheIncomplete(outcome);
18
22
  if (settled.scopedCacheOutcome.cacheSafe === false) markScopedCacheUnsafe(outcome);
@@ -53,7 +53,13 @@ export async function streamRangeResult(ctx, { source, fileHandle, prefixBuffer
53
53
  res.firstEmitted && res.lastEmitted ? [{ startLine: res.firstEmitted, endLine: res.lastEmitted }] : [];
54
54
  const snapshotMeta = { source, ranges, rangeHashes: _rangeHashesFromRenderedReadText(res.text, ranges) };
55
55
  if (!res.readSnapshotStat) return res.text;
56
- return await commitStreamResult({ ...ctx, st: res.readSnapshotStat }, res.text, snapshotMeta, res.prefixHash, helpers);
56
+ return await commitStreamResult(
57
+ { ...ctx, st: res.readSnapshotStat },
58
+ res.text,
59
+ snapshotMeta,
60
+ res.prefixHash,
61
+ helpers
62
+ );
57
63
  } catch (err) {
58
64
  return `Error: ${normalizeErrorMessage(err instanceof Error ? err.message : String(err))}`;
59
65
  }
@@ -137,9 +137,12 @@ async function readRangeFromHandle(fh, fullPath, offset, limit, stHint, hooks) {
137
137
  }
138
138
  if (!stop) lines.finishTail();
139
139
  let readSnapshotStat = null;
140
- if (!(await publishReadRangeIndex(rangeIndex, fh, null, checkDeadline, (version) => {
141
- readSnapshotStat = version;
142
- }))) checkDeadline();
140
+ if (
141
+ !(await publishReadRangeIndex(rangeIndex, fh, null, checkDeadline, (version) => {
142
+ readSnapshotStat = version;
143
+ }))
144
+ )
145
+ checkDeadline();
143
146
 
144
147
  ioTraceDone('read_range_stream', traceStart, {
145
148
  pathHash: hashText(fullPath).slice(0, 12),
@@ -41,7 +41,7 @@ async function estimateTaskBytes(entry, workDir) {
41
41
  const st = await stat(resolvePath(workDir || '.', String(entry?.path || ''))).catch(() => null);
42
42
  if (!st?.isFile()) return Infinity;
43
43
  const lines = Math.max(1, st.size / AVG_LINE_BYTES);
44
- let need = st.size + st.size / MIN_LINE_BYTES * LINE_PREFIX_BYTES;
44
+ let need = st.size + (st.size / MIN_LINE_BYTES) * LINE_PREFIX_BYTES;
45
45
  // A coalesced entry reads its whole union window, not only its own slot.
46
46
  const limit = Number(readEntryCoalescedDiskWindow(entry)?.limit ?? entry?.limit);
47
47
  if (Number.isFinite(limit) && limit > 0) need *= Math.min(1, limit / lines);
@@ -85,10 +85,14 @@ export async function runBatchReadSnapshotPublication(executeChildBuiltinTool, h
85
85
  // A numbered row may end halfway through its content at the byte cap.
86
86
  // Only this slot's producer can certify complete lines; another read of
87
87
  // the same path must not authorize hashing this slot's partial text.
88
- return mergeReadRanges(ranges.flatMap((range) => (observation?.ranges ?? []).map((complete) => ({
89
- startLine: Math.max(range.startLine, complete.startLine),
90
- endLine: Math.min(range.endLine, complete.endLine),
91
- }))));
88
+ return mergeReadRanges(
89
+ ranges.flatMap((range) =>
90
+ (observation?.ranges ?? []).map((complete) => ({
91
+ startLine: Math.max(range.startLine, complete.startLine),
92
+ endLine: Math.min(range.endLine, complete.endLine),
93
+ }))
94
+ )
95
+ );
92
96
  },
93
97
  _recordReadSnapshot: (fullPath, _st, scope, meta) => {
94
98
  corrections.set(fullPath, { scope: scope ?? null, meta });
@@ -104,22 +108,29 @@ export async function runBatchReadSnapshotPublication(executeChildBuiltinTool, h
104
108
  }
105
109
  for (const [fullPath, correction] of corrections) {
106
110
  const delivered = tasks.filter((task) => task.fullPath === fullPath && hasRenderedLines(task.body));
107
- const observations = delivered.map((task) => task.records.findLast(
108
- (record) => record.fullPath === fullPath && record.scope === correction.scope
109
- ));
111
+ const observations = delivered.map((task) =>
112
+ task.records.findLast((record) => record.fullPath === fullPath && record.scope === correction.scope)
113
+ );
110
114
  // Never combine different versions or bless stale/missing observations.
111
115
  // The eventual recorder rechecks the retained lease after all awaits.
112
- if (observations.length && observations.every((record) =>
113
- record?.isCurrent() && sameFileVersion(record.identity, observations[0].identity)
114
- )) {
116
+ if (
117
+ observations.length &&
118
+ observations.every(
119
+ (record) => record?.isCurrent() && sameFileVersion(record.identity, observations[0].identity)
120
+ )
121
+ ) {
115
122
  observations[0].publish(correction.meta);
116
123
  }
117
124
  }
118
125
  // Rich media/binary results have no line slices. Preserve their original
119
126
  // evidence, still under the producer's lease rather than the batch's.
120
127
  for (const task of tasks) {
121
- if (hasRenderedLines(task.body) || task.body?.isError === true ||
122
- (typeof task.body === 'string' && helpers.classifyResultKind(task.body) === 'error')) continue;
128
+ if (
129
+ hasRenderedLines(task.body) ||
130
+ task.body?.isError === true ||
131
+ (typeof task.body === 'string' && helpers.classifyResultKind(task.body) === 'error')
132
+ )
133
+ continue;
123
134
  for (const record of task.records) {
124
135
  if (!corrections.has(record.fullPath)) record.publish();
125
136
  }
@@ -69,7 +69,12 @@ async function rawRangeHashes(fullPath, mergedRanges, { _hashText }) {
69
69
 
70
70
  export async function recordSlicedBatchSnapshots(orderedResults, workDir, readStateScope, helpers) {
71
71
  const { _mergeReadRanges, _recordReadSnapshot } = helpers;
72
- const { exactRangesByPath, rangeHashesByPath } = deliveredRangesByPath(orderedResults, workDir, readStateScope, helpers);
72
+ const { exactRangesByPath, rangeHashesByPath } = deliveredRangesByPath(
73
+ orderedResults,
74
+ workDir,
75
+ readStateScope,
76
+ helpers
77
+ );
73
78
  for (const [fullPath, ranges] of exactRangesByPath) {
74
79
  const mergedRanges = _mergeReadRanges(ranges);
75
80
  let rangeHashes = rangeHashesByPath.get(fullPath) || [];
@@ -112,14 +112,7 @@ export async function executeReadTool(args, ...rest) {
112
112
  return `${out}\n[skipped ${skipped.length} more file(s) over the per-call limit: ${skipped.join(', ')} — read them in another call]`;
113
113
  }
114
114
 
115
- async function executeReadToolBody(
116
- args,
117
- workDir,
118
- readStateScope,
119
- executeChildBuiltinTool,
120
- options = {},
121
- helpers = {}
122
- ) {
115
+ async function executeReadToolBody(args, workDir, readStateScope, executeChildBuiltinTool, options = {}, helpers = {}) {
123
116
  const { normalizeInputPath, normaliseReadLineWindowArgs } = helpers;
124
117
  applyFilePathAlias(args);
125
118
  args.path = coerceReadFamilyPathArg(args.path);
@@ -17,6 +17,10 @@ export function setConfiguredShell(value = '') {
17
17
  _resolvedShellByKind.clear();
18
18
  }
19
19
 
20
+ export function getConfiguredShell() {
21
+ return _configuredShell || '';
22
+ }
23
+
20
24
  function shellTypeFor(shell) {
21
25
  const stem = basename(String(shell || ''))
22
26
  .toLowerCase()
@@ -49,7 +53,9 @@ function allExistingPathsFromPath(commandName) {
49
53
  let cwd = '';
50
54
  try {
51
55
  cwd = process.cwd();
52
- } catch {}
56
+ } catch {
57
+ // the working directory may have been removed; search PATH entries only
58
+ }
53
59
  const entries = [cwd, ...rawPath.split(delimiter)]
54
60
  .map((entry) => entry.trim().replace(/^"(.*)"$/, '$1'))
55
61
  .filter(Boolean);
@@ -129,7 +129,9 @@ function federateRoots(name, args, plan, signal, options, execute) {
129
129
  }
130
130
  const runOne = async (root, nextArgs) =>
131
131
  execute(name, nextArgs, root, signal, { ...options, excludedProjectRoots: excludedRootsFor(root, roots) });
132
- const work = _runCodeGraphFederation(roots, runOne, projectArgs, options.scopedCacheOutcome).then((sections) => sections.join('\n\n'));
132
+ const work = _runCodeGraphFederation(roots, runOne, projectArgs, options.scopedCacheOutcome).then((sections) =>
133
+ sections.join('\n\n')
134
+ );
133
135
  return raceAbort(work, signal);
134
136
  }
135
137
 
@@ -26,7 +26,7 @@ export const CODE_GRAPH_TOOL_DEFS = [
26
26
  compressibleLossless: true,
27
27
  },
28
28
  description:
29
- 'Code structure and relations from the parsed graph, no text matching. symbols → file outline rows `[export ]kind name (Lstart-end) signature`; find_symbol returns declaration/body; references adds usages (body opt-in); callers/callees return locations; dependents/impact → importers and blast radius. Exact identifiers: find_symbol/references/callers/callees; keywords: symbol_search/search; literal text and regex belong to grep. Prefer it over read/grep for declarations and relations; every row’s location is a read window. symbols already outlines a file: never pair it with overview for one need.',
29
+ 'Code structure and relations from the parsed graph, no text matching. symbols → file outline rows `[export ]kind name (Lstart-end) signature`; find_symbol returns declaration/body; references adds usages; callers/callees return locations; dependents/impact → importers and blast radius. Exact identifiers: find_symbol/references/callers/callees; keywords: symbol_search/search; literal text and regex belong to grep. Prefer it over read/grep for declarations and relations. symbols already outlines a file: never pair it with overview for one need.',
30
30
  inputSchema: {
31
31
  type: 'object',
32
32
  properties: {
@@ -1,30 +1,30 @@
1
1
  {
2
- "version": "0.1.33",
2
+ "version": "0.1.34",
3
3
  "_comment": "Synced from immutable graph-v release assets.",
4
4
  "assets": {
5
5
  "darwin-arm64": {
6
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-darwin-arm64",
7
- "sha256": "8637d61493eddca3eee80620a64e737f12eead44ea899ad19a18966a3843ff3a"
6
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-darwin-arm64",
7
+ "sha256": "5bcf8c79135224d2e77eec70a57debd06d462bab01418ce1a6c1656a858eedad"
8
8
  },
9
9
  "darwin-x64": {
10
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-darwin-x64",
11
- "sha256": "49ce311687c3df7e7080ecb7694219c9b51bbbb272864aa43d2102a8baa83550"
10
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-darwin-x64",
11
+ "sha256": "2845ea2afa2802841589bd74c8785670cfe8c6b58b2ad5b258ac928afccbaa94"
12
12
  },
13
13
  "linux-arm64": {
14
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-linux-arm64",
15
- "sha256": "2e2a4ea6dccc5b33f583040b0ee6e8d47f93a1e879eb17343acd0b2f9838696f"
14
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-linux-arm64",
15
+ "sha256": "0364bc1c3741683fbdb45ed755f2baabb50a0556e2354c13a05f3d816bc1c461"
16
16
  },
17
17
  "linux-x64": {
18
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-linux-x64",
19
- "sha256": "2cd1caa7f39e183d6fb6f7764f49e9a0643863d137c2bfb5f40bb7ac616c8d73"
18
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-linux-x64",
19
+ "sha256": "4f9091b2c5a89631efade89aae17e5411dda8bfec99e15ff64948906f9fa20d0"
20
20
  },
21
21
  "win32-arm64": {
22
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-win32-arm64.exe",
23
- "sha256": "592dfa7e95e1e91424c7467e74f35d09758de502be403b7d229444b435600392"
22
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-win32-arm64.exe",
23
+ "sha256": "03abef6f09b095b86c5cc32c6bead3f5d82f77961220c31221ab0b3f60974110"
24
24
  },
25
25
  "win32-x64": {
26
- "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.33/mixdog-graph-win32-x64.exe",
27
- "sha256": "0ed17859a39f0160421865f3a3486ce53957b836ee164d606434519b85b90830"
26
+ "url": "https://github.com/tribgames/mixdog/releases/download/graph-v0.1.34/mixdog-graph-win32-x64.exe",
27
+ "sha256": "650cffe82ccbe9898e7ac8fc9b025c92098a810ad3ca95276c0bb8c19a328993"
28
28
  }
29
29
  }
30
30
  }
@@ -1,9 +1,10 @@
1
- import { mkdirSync, mkdtempSync } from 'node:fs';
2
- import { tmpdir } from 'node:os';
1
+ import { mkdirSync } from 'node:fs';
3
2
  import { join } from 'node:path';
3
+ import { makeTempDirSync } from '../../../../../../scripts/lib/scoped-temp.mjs';
4
4
 
5
5
  // Import before runtime modules: several paths are captured at module load.
6
- export const fixtureRoot = mkdtempSync(join(tmpdir(), 'mixdog-shell-fixture-'));
6
+ // Removed when the importing test process exits.
7
+ export const fixtureRoot = makeTempDirSync('shell-fixture');
7
8
  for (const name of [
8
9
  'HOME',
9
10
  'USERPROFILE',
@@ -55,8 +55,13 @@ function _disabled() {
55
55
  return process.env.MIXDOG_SHELL_WARM_STANDBY === '0';
56
56
  }
57
57
 
58
+ // Per-session scratch variables: they differ between sessions by design, so
59
+ // they stay out of the reuse signature and are set in the hand-off prelude.
60
+ const SCRATCH_ENV_KEYS = Object.freeze(['TEMP', 'TMP', 'TMPDIR']);
61
+
58
62
  function envSignature(env) {
59
63
  const entries = Object.entries(env || {})
64
+ .filter(([key]) => !SCRATCH_ENV_KEYS.includes(key))
60
65
  .map(([key, value]) => `${key}=${value}`)
61
66
  .sort()
62
67
  .join('\n');
@@ -67,8 +72,16 @@ function _slotAlive(slot) {
67
72
  return Boolean(slot?.native?.child && slot.native.child.exitCode == null && !slot.native.child.killed);
68
73
  }
69
74
 
70
- function psQuote(value) {
71
- return String(value).replace(/'/g, "''");
75
+ // A PowerShell expression yielding `value` for any text. PowerShell quoting has
76
+ // no safe form for typographic apostrophes and the like, so the value travels
77
+ // as UTF-8 Base64 and is decoded inside the expression.
78
+ function psStringExpr(value) {
79
+ return `[System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${Buffer.from(String(value), 'utf8').toString('base64')}'))`;
80
+ }
81
+
82
+ /** The parked standby slot, for tests. */
83
+ export function _parkedShellStandbyForTest() {
84
+ return _slot;
72
85
  }
73
86
 
74
87
  /** Pre-spawn the next standby (fire-and-forget; a live one is kept). */
@@ -164,9 +177,18 @@ export function takeWarmShellStandby({ shell, env }) {
164
177
  // cwd prelude: the standby was spawned in the daemon cwd. Set-Location
165
178
  // fixes $PWD and native-child working dirs; Environment.CurrentDirectory
166
179
  // fixes .NET relative-path APIs.
167
- const prelude = workDir
168
- ? `Set-Location -LiteralPath '${psQuote(workDir)}'; [System.Environment]::CurrentDirectory = '${psQuote(workDir)}'; `
180
+ const cwdPrelude = workDir
181
+ ? `$__mixdogCwd = ${psStringExpr(workDir)}; Set-Location -LiteralPath $__mixdogCwd; [System.Environment]::CurrentDirectory = $__mixdogCwd; `
169
182
  : '';
183
+ // Scratch prelude: the standby was spawned for whichever session parked
184
+ // it. Set (or clear, when the request has none) the requested values
185
+ // before the command runs, so no other session's scratch path survives.
186
+ const scratchPrelude = SCRATCH_ENV_KEYS.map((key) =>
187
+ typeof env?.[key] === 'string'
188
+ ? `$env:${key} = ${psStringExpr(env[key])}; `
189
+ : `Remove-Item -LiteralPath 'Env:${key}' -ErrorAction SilentlyContinue; `
190
+ ).join('');
191
+ const prelude = scratchPrelude + cwdPrelude;
170
192
  // Single atomic write+EOF: a separate close message can race ahead
171
193
  // of the server's async write thread and feed an empty script.
172
194
  slot.native.child.writeStdin(prelude + String(commandText ?? ''), { close: true });
@@ -112,7 +112,9 @@ function _abortableDelay(ms, signal) {
112
112
  if (onAbort && signal) {
113
113
  try {
114
114
  signal.removeEventListener('abort', onAbort);
115
- } catch {}
115
+ } catch {
116
+ // the abort listener may already be gone
117
+ }
116
118
  }
117
119
  resolveDelay();
118
120
  }, ms);
@@ -173,7 +175,9 @@ async function acquireShellLeaseBounded(
173
175
  } catch {
174
176
  try {
175
177
  ctl.abort();
176
- } catch {}
178
+ } catch {
179
+ // the controller may already be aborted
180
+ }
177
181
  }
178
182
  };
179
183
  if (abortSignal) {
@@ -184,7 +188,9 @@ async function acquireShellLeaseBounded(
184
188
  const deadline = setTimeout(() => {
185
189
  try {
186
190
  ctl.abort(_admissionSaturationError(admission, waitMs, ownerKey));
187
- } catch {}
191
+ } catch {
192
+ // the controller may already be aborted
193
+ }
188
194
  }, waitMs);
189
195
  if (deadline.unref) deadline.unref();
190
196
  try {
@@ -212,7 +218,9 @@ async function acquireShellLeaseBounded(
212
218
  if (abortSignal) {
213
219
  try {
214
220
  abortSignal.removeEventListener('abort', onAbort);
215
- } catch {}
221
+ } catch {
222
+ // the abort listener may already be gone
223
+ }
216
224
  }
217
225
  }
218
226
  }
@@ -238,7 +246,7 @@ async function admitAndSpawn(run, params, { admissionWaitMs, onSaturated }) {
238
246
  run.resourceLease = await acquireShellLeaseBounded(admission, {
239
247
  abortSignal,
240
248
  waitMs: admissionWaitMs,
241
- label: `[task_id: ${run.foregroundRecordId}] ${String(command || '').slice(0, 120)}`,
249
+ label: `[task_id: ${run.foregroundRecordId}] ${String(params.displayCommand ?? command ?? '').slice(0, 120)}`,
242
250
  ownerKey: ownerSessionId,
243
251
  });
244
252
  const policyErr = await _execPolicyBlockMessage(command, elevationApproved === true);
@@ -295,11 +303,11 @@ function queueSaturatedAsTask(run, saturation, spec) {
295
303
  taskId,
296
304
  surface: 'shell',
297
305
  operation: 'shell',
298
- label: String(spec.command || '')
306
+ label: String(spec.displayCommand ?? spec.command ?? '')
299
307
  .replace(/\s+/g, ' ')
300
308
  .slice(0, 120),
301
309
  context: { callerSessionId: spec.ownerSessionId, clientHostPid: spec.clientHostPid },
302
- input: { command: spec.command, cwd: spec.cwd },
310
+ input: { command: spec.displayCommand ?? spec.command, cwd: spec.cwd },
303
311
  meta: { task_id: taskId, stdout: null, stderr: null, cwd: spec.cwd, timeoutMs: spec.backgroundDeadlineMs || 0 },
304
312
  resultType: 'shell_task_result',
305
313
  // While the command runs in the foreground, its abort handler snapshots
@@ -311,7 +319,9 @@ function queueSaturatedAsTask(run, saturation, spec) {
311
319
  if (!promotedJobId) return;
312
320
  try {
313
321
  killShellJob(promotedJobId);
314
- } catch {}
322
+ } catch {
323
+ // the job may already have exited
324
+ }
315
325
  },
316
326
  run: async () => {
317
327
  const result = await execShellCommand({
@@ -332,7 +342,9 @@ function queueSaturatedAsTask(run, saturation, spec) {
332
342
  if (queuedAbort.signal.aborted) {
333
343
  try {
334
344
  killShellJob(promotedJobId);
335
- } catch {}
345
+ } catch {
346
+ // the promoted job may already have exited
347
+ }
336
348
  }
337
349
  return settleQueuedPromotion(promotedJobId);
338
350
  }
@@ -375,7 +387,9 @@ function settleSetupFailure(run, err) {
375
387
  clearForegroundTimers(run);
376
388
  try {
377
389
  treeKill(run.child);
378
- } catch {}
390
+ } catch {
391
+ // the child may already have exited
392
+ }
379
393
  void releaseResourceLease(run);
380
394
  run.resolveResult(failedResult(run, String(err?.message || err), 'spawn failed'));
381
395
  }
@@ -451,7 +465,9 @@ function armProgressTimers(run, { onProgress, onOutputTail }) {
451
465
  const secs = Math.round(elapsedSinceStart(run) / 1000);
452
466
  try {
453
467
  onProgress(`running ${secs}s`);
454
- } catch {}
468
+ } catch {
469
+ // the progress sink is advisory
470
+ }
455
471
  }, 2000);
456
472
  if (run.progressTimer.unref) run.progressTimer.unref();
457
473
  }
@@ -549,7 +565,9 @@ function armDeadlines(
549
565
  };
550
566
  try {
551
567
  abortSignal.addEventListener('abort', run.abortHandler, { once: true });
552
- } catch {}
568
+ } catch {
569
+ // caller cancellation registration is best-effort
570
+ }
553
571
  }
554
572
  }
555
573
 
@@ -588,6 +606,10 @@ export function execShellCommand(options) {
588
606
  // hands the script to the shell out-of-band — see the POSIX env+eval path in
589
607
  // bash-tool.mjs, which keeps the command body out of the child's argv.
590
608
  execScript = null,
609
+ // What the agent passed, when `command` carries execution wrappers (the
610
+ // PowerShell UTF-8 prefix, the filter-tee rewrite). Job labels and
611
+ // records show this text; only the spawn runs `command`.
612
+ displayCommand = null,
591
613
  // The user approved this call's elevation 'ask' decision (runtime-set).
592
614
  elevationApproved = false,
593
615
  } = options;
@@ -612,6 +634,7 @@ export function execShellCommand(options) {
612
634
  abortSignal,
613
635
  directArgv,
614
636
  execScript,
637
+ displayCommand,
615
638
  elevationApproved,
616
639
  ownerSessionId,
617
640
  clientHostPid,
@@ -635,7 +658,7 @@ export function execShellCommand(options) {
635
658
  attachChildExit(run, releasePromotedCapture);
636
659
  const fireAutoBackground = createAutoBackground({
637
660
  run,
638
- command,
661
+ command: displayCommand ?? command,
639
662
  cwd,
640
663
  clientHostPid,
641
664
  ownerSessionId,