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
@@ -0,0 +1,240 @@
1
+ // Runtime guards against shell-tool misuse, run in the shell tool's validation
2
+ // step before hooks, approvals and execution (tool-exec.mjs) and again, once,
3
+ // for callers that reach executeBashTool without that step:
4
+ // 1. a leading whole-second sleep of 2 s or more is rejected (a wait belongs
5
+ // to background + task wait);
6
+ // 2. a plain leading `cd <dir>` moves into the `cwd` argument;
7
+ // 3. a shell file read (cat/Get-Content/grep/ls …) gets a pointer to the
8
+ // read / grep / list tools — a note now, a rejection when the mode flips.
9
+ import { shellSplitPipelineSegments, shellSplitSegments, shellTokenize } from '../shell-analysis.mjs';
10
+ import { resolveShellFor } from '../shell-runtime.mjs';
11
+ import { formatShellToolFailure } from './result-format.mjs';
12
+
13
+ /** `warn` runs the read with a note; `reject` returns the block without running. */
14
+ export const SHELL_FILE_READ_MODE = 'warn';
15
+ export const SHELL_FILE_READ_NOTE = 'Note: use the read / grep / list tools for files instead of the shell.';
16
+ const SHELL_FILE_READ_BLOCK =
17
+ 'Blocked: use read / grep / list for files instead of the shell (read takes offset/limit for a window of a large file).';
18
+
19
+ const isPlainObject = (value) => value !== null && typeof value === 'object' && !Array.isArray(value);
20
+
21
+ // ── 1. leading sleep ─────────────────────────────────────────────────────────
22
+
23
+ // Sub-2-second pacing stays allowed: only a bare whole-second sleep of 2 or
24
+ // more is refused. Float seconds, `-Milliseconds`, unit suffixes, pipelines,
25
+ // subshells and later statements are not matched.
26
+ const LEADING_SLEEP_MIN_SECONDS = 2;
27
+ // The first statement ends the command or is followed by `;`, `&&` or a newline.
28
+ const STATEMENT_END = String.raw`(?=\s*(?:$|;|&&|\r?\n))`;
29
+ // The argument stays on the command's line: a number on the next line is its own statement.
30
+ // PowerShell takes any prefix of `-Seconds` (`-s`, `-sec`, …) as the seconds parameter.
31
+ const POSIX_SLEEP_RE = new RegExp(String.raw`^\s*sleep[ \t]+(\d+)${STATEMENT_END}`);
32
+ const POWERSHELL_SLEEP_RE = new RegExp(
33
+ String.raw`^\s*(?:start-sleep|sleep)[ \t]+(?:-s(?:e(?:c(?:o(?:n(?:d(?:s)?)?)?)?)?)?[ \t:]+)?(\d+)${STATEMENT_END}`,
34
+ 'i'
35
+ );
36
+
37
+ /** Whole seconds of the sleep the command starts with, or null when it does not start with one. */
38
+ function leadingSleepSeconds(command, shellType) {
39
+ const match = (shellType === 'powershell' ? POWERSHELL_SLEEP_RE : POSIX_SLEEP_RE).exec(String(command ?? ''));
40
+ return match ? Number(match[1]) : null;
41
+ }
42
+
43
+ function leadingSleepFailure(command, shellType) {
44
+ const seconds = leadingSleepSeconds(command, shellType);
45
+ if (seconds === null || seconds < LEADING_SLEEP_MIN_SECONDS) return null;
46
+ return formatShellToolFailure(
47
+ `Blocked: the leading sleep of ${seconds} s was not run. For a long-running command use background:true; its completion arrives automatically. To wait for a specific task when the result is needed now, use task wait — do not poll in a sleep loop. A deliberate delay under ${LEADING_SLEEP_MIN_SECONDS} seconds is allowed.`
48
+ );
49
+ }
50
+
51
+ // ── 2. leading cd → cwd ──────────────────────────────────────────────────────
52
+
53
+ // One plain path token: quoted (no variable or escape characters) or unquoted
54
+ // (no shell metacharacters, glob characters included), then `;` or `&&` and a remainder.
55
+ const CD_RE =
56
+ /^\s*(?:cd|set-location)\s+(?:-path\s+)?(?:"([^"$`]+)"|'([^'$`]+)'|([^\s;&|<>"'`$(){}*?[,@%#!]+))\s*(?:;|&&)\s*(\S[\s\S]*)$/i;
57
+ // `Set-Location -Path` expands wildcards even in a quoted path; a POSIX shell
58
+ // keeps a quoted glob literal, so only PowerShell leaves those unrewritten.
59
+ const POWERSHELL_WILDCARD_RE = /[*?[]/;
60
+ const CD_LIKE_RE = /^(?:cd|set-location|pushd|popd)(?:\s|;|&|$)/i;
61
+
62
+ /** `{ dir, rest }` for a command that starts with a plain `cd <dir>` and more, else null. */
63
+ function splitLeadingCd(command, shellType) {
64
+ const match = CD_RE.exec(String(command ?? ''));
65
+ if (!match) return null;
66
+ const dir = match[1] ?? match[2] ?? match[3];
67
+ const rest = match[4];
68
+ if (CD_LIKE_RE.test(rest)) return null;
69
+ if (dir.trim() === '' || dir.startsWith('-')) return null;
70
+ if (shellType === 'powershell' && POWERSHELL_WILDCARD_RE.test(dir)) return null;
71
+ // `~user` is another account's home in a shell, not a folder named so; a
72
+ // quoted `~` is a literal directory name, only an unquoted one is home.
73
+ if (dir.startsWith('~') && (match[3] === undefined || !/^~(?:[\\/]|$)/.test(dir))) return null;
74
+ // A POSIX backslash escapes; only single quotes keep it literal.
75
+ if (shellType !== 'powershell' && match[2] === undefined && dir.includes('\\')) return null;
76
+ return { dir, rest };
77
+ }
78
+
79
+ // ── 3. shell file reads ──────────────────────────────────────────────────────
80
+
81
+ const POWERSHELL_READERS = {
82
+ 'get-content': 'read',
83
+ gc: 'read',
84
+ cat: 'read',
85
+ type: 'read',
86
+ 'select-string': 'grep',
87
+ sls: 'grep',
88
+ 'get-childitem': 'list',
89
+ gci: 'list',
90
+ ls: 'list',
91
+ dir: 'list',
92
+ rg: 'grep',
93
+ };
94
+ const POSIX_READERS = {
95
+ cat: 'read',
96
+ head: 'read',
97
+ tail: 'read',
98
+ less: 'read',
99
+ grep: 'grep',
100
+ rg: 'grep',
101
+ ls: 'list',
102
+ find: 'list',
103
+ };
104
+ // Flags whose next token is a path or pattern operand, and flags whose next
105
+ // token is a plain value; both are read off the operand count.
106
+ const OPERAND_FLAGS = new Set(['-path', '-literalpath', '-pattern', '-e', '--regexp', '-f', '--file']);
107
+ const VALUE_FLAGS = new Set(['-encoding', '-filter', '-include', '-exclude', '-g', '--glob', '-t', '--type']);
108
+ // A later pipeline stage that only shapes text; anything else is a program
109
+ // the first stage feeds.
110
+ const TEXT_FILTERS = new Set([
111
+ 'select-object',
112
+ 'select',
113
+ 'select-string',
114
+ 'sls',
115
+ 'where-object',
116
+ 'sort-object',
117
+ 'sort',
118
+ 'measure-object',
119
+ 'format-table',
120
+ 'format-list',
121
+ 'ft',
122
+ 'fl',
123
+ 'out-string',
124
+ 'out-host',
125
+ 'head',
126
+ 'tail',
127
+ 'grep',
128
+ 'egrep',
129
+ 'rg',
130
+ 'wc',
131
+ 'uniq',
132
+ 'cut',
133
+ 'findstr',
134
+ ]);
135
+ const FIND_WRITERS = new Set(['-exec', '-execdir', '-ok', '-okdir', '-delete', '-fprint', '-fprintf', '-fls']);
136
+ const BENIGN_REDIRECT_TARGET = /^(?:&\d|\$null|\/dev\/null|nul)$/i;
137
+
138
+ const commandName = (token) =>
139
+ String(token ?? '')
140
+ .toLowerCase()
141
+ .replace(/^.*[\\/]/, '')
142
+ .replace(/\.exe$/, '');
143
+
144
+ // The path/pattern operands of a stage, or null when it writes a file.
145
+ function stageOperands(args) {
146
+ const operands = [];
147
+ for (let i = 0; i < args.length; i++) {
148
+ const token = args[i];
149
+ if (token === '>' || token === '>>') {
150
+ if (!BENIGN_REDIRECT_TARGET.test(args[i + 1] ?? '')) return null;
151
+ i++;
152
+ continue;
153
+ }
154
+ const flag = token.toLowerCase();
155
+ if (flag.startsWith('-') && flag.length > 1) {
156
+ if (OPERAND_FLAGS.has(flag) && i + 1 < args.length) operands.push(args[++i]);
157
+ else if (VALUE_FLAGS.has(flag)) i++;
158
+ continue;
159
+ }
160
+ // A bare count (`head -n 5`, `tail -n +5`) is a flag value, not an operand.
161
+ if (!/^[+-]?\d+$/.test(token)) operands.push(token);
162
+ }
163
+ return operands;
164
+ }
165
+
166
+ /**
167
+ * `{ tool, command }` when the command's first statement starts with a
168
+ * read-only file command on a path — the tool that does that job — else null.
169
+ * A pipeline whose later stage is a program, a write, and a first stage that
170
+ * reads piped input are not file reads.
171
+ */
172
+ function detectShellFileRead(command, shellType) {
173
+ const first = shellSplitSegments(String(command ?? ''))[0];
174
+ if (!first) return null;
175
+ const stages = shellSplitPipelineSegments(first);
176
+ const tokens = shellTokenize(stages[0] ?? '');
177
+ if (!tokens || tokens.length === 0) return null;
178
+ const name = commandName(tokens[0]);
179
+ const tool = (shellType === 'powershell' ? POWERSHELL_READERS : POSIX_READERS)[name];
180
+ if (!tool) return null;
181
+ for (const stage of stages.slice(1)) {
182
+ if (!TEXT_FILTERS.has(commandName(stage.trim().split(/\s+/)[0]))) return null;
183
+ }
184
+ const args = tokens.slice(1);
185
+ if (name === 'find') {
186
+ const lowered = args.map((token) => token.toLowerCase());
187
+ const matchesNames = lowered.some((token) => ['-name', '-iname', '-path', '-regex'].includes(token));
188
+ return matchesNames && !lowered.some((token) => FIND_WRITERS.has(token)) ? { tool, command: name } : null;
189
+ }
190
+ const operands = stageOperands(args);
191
+ if (!operands) return null;
192
+ // A search names its pattern and then the path it reads; with one operand it reads piped input.
193
+ const minOperands = tool === 'grep' ? 2 : 1;
194
+ return operands.length >= minOperands ? { tool, command: name } : null;
195
+ }
196
+
197
+ // ── the guard ────────────────────────────────────────────────────────────────
198
+
199
+ /** The syntax family of the shell a call asks for (`args.shell`, as foreign adapters set it), else the default shell's. */
200
+ export function requestedShellType(args) {
201
+ const requested = typeof args?.shell === 'string' && args.shell ? resolveShellFor(args.shell) : null;
202
+ return (requested ?? resolveShellFor('default'))?.shellType;
203
+ }
204
+
205
+ function recordFileRead(telemetry, entry) {
206
+ if (!telemetry || typeof telemetry !== 'object') return;
207
+ if (!Array.isArray(telemetry.shellMisuse)) telemetry.shellMisuse = [];
208
+ telemetry.shellMisuse.push({ kind: 'file-read', ...entry });
209
+ }
210
+
211
+ /**
212
+ * Apply the three guards to a shell call.
213
+ * @returns {{ failure: string } | { args: object, notes: string[] }} the
214
+ * rejection, or the call to run (a leading `cd` moved into `cwd`) with the
215
+ * lines to add to its result.
216
+ */
217
+ export function guardShellCall(
218
+ args,
219
+ { shellType, fileReadMode = SHELL_FILE_READ_MODE, agent = null, sessionId = null, telemetry = null } = {}
220
+ ) {
221
+ if (!isPlainObject(args) || typeof args.command !== 'string') return { args, notes: [] };
222
+ const notes = [];
223
+ let guarded = args;
224
+ const moved = args.cwd == null ? splitLeadingCd(args.command, shellType) : null;
225
+ if (moved) {
226
+ guarded = { ...args, command: moved.rest, cwd: moved.dir };
227
+ notes.push(`Moved \`cd ${moved.dir}\` into cwd.`);
228
+ }
229
+ if (args.background !== true) {
230
+ const sleepFailure = leadingSleepFailure(guarded.command, shellType);
231
+ if (sleepFailure) return { failure: sleepFailure };
232
+ }
233
+ const read = detectShellFileRead(guarded.command, shellType);
234
+ if (read) {
235
+ recordFileRead(telemetry, { mode: fileReadMode, tool: read.tool, command: read.command, agent, sessionId });
236
+ if (fileReadMode === 'reject') return { failure: formatShellToolFailure(SHELL_FILE_READ_BLOCK) };
237
+ notes.push(SHELL_FILE_READ_NOTE);
238
+ }
239
+ return { args: guarded, notes };
240
+ }
@@ -118,7 +118,7 @@ const _PS_UNIX_EQUIVALENTS = {
118
118
  head: 'Select-Object -First N',
119
119
  tail: 'Select-Object -Last N',
120
120
  wc: 'Measure-Object -Line',
121
- grep: 'Select-String (or the grep tool)',
121
+ grep: 'the grep tool',
122
122
  sed: 'the edit tool',
123
123
  awk: 'ForEach-Object / the edit tool',
124
124
  pgrep: 'Get-Process -Name <name>',
@@ -0,0 +1,38 @@
1
+ // The shell tool's optional `cwd` argument: where one command runs. Omitted,
2
+ // the command runs in the session cwd; a relative value resolves against it.
3
+ import { stat } from 'node:fs/promises';
4
+ import { homedir } from 'node:os';
5
+ import { resolve } from 'node:path';
6
+
7
+ // `~`, `~/x` (and `~\x` on Windows) name the user's home folder.
8
+ function expandHome(path) {
9
+ if (path === '~') return homedir();
10
+ if (path.startsWith('~/') || (process.platform === 'win32' && path.startsWith('~\\'))) {
11
+ return resolve(homedir(), path.slice(2));
12
+ }
13
+ return path;
14
+ }
15
+
16
+ /** The directory a shell call runs in: its `cwd` argument resolved against the session cwd. */
17
+ export function effectiveShellCwd(args, sessionCwd) {
18
+ const requested = args?.cwd;
19
+ // Trim only decides blank; a name with edge spaces is used as given.
20
+ if (typeof requested !== 'string' || requested.trim() === '') return sessionCwd;
21
+ return resolve(sessionCwd || process.cwd(), expandHome(requested));
22
+ }
23
+
24
+ /** The cwd hooks and approvals see for a tool call: the effective one for shell, the session cwd otherwise. */
25
+ export function effectiveToolCwd(toolName, args, sessionCwd) {
26
+ return toolName === 'shell' ? effectiveShellCwd(args, sessionCwd) : sessionCwd;
27
+ }
28
+
29
+ /** An error naming the path when `dir` is not an existing directory, else null. */
30
+ export async function shellCwdError(dir) {
31
+ let info;
32
+ try {
33
+ info = await stat(dir);
34
+ } catch {
35
+ return `shell cwd "${dir}" does not exist`;
36
+ }
37
+ return info.isDirectory() ? null : `shell cwd "${dir}" is not a directory`;
38
+ }
@@ -1,3 +1,4 @@
1
+ import { applySessionScratchEnv } from '../../../../../shared/session-scratch.mjs';
1
2
  import { withSkillLauncherPath } from '../../../../../shared/skill-script-runtime.mjs';
2
3
  import {
3
4
  applyShellEgressPolicy,
@@ -6,7 +7,8 @@ import {
6
7
  scrubRuntimeRootVars,
7
8
  } from '../../env-scrub.mjs';
8
9
 
9
- export function buildShellSpawnEnv(cwd, baseEnv = process.env) {
10
+ // `sessionId` points TEMP/TMP/TMPDIR at that session's scratch directory.
11
+ export function buildShellSpawnEnv(cwd, baseEnv = process.env, sessionId = null) {
10
12
  const spawnEnv = {
11
13
  ...baseEnv,
12
14
  LANG: 'C.UTF-8',
@@ -24,5 +26,5 @@ export function buildShellSpawnEnv(cwd, baseEnv = process.env) {
24
26
  // `mixdog-skill-node` (a skill's ${MIXDOG_SKILL_NODE}) resolves in every
25
27
  // model shell; only this env gets the entry, never the daemon's own.
26
28
  withSkillLauncherPath(spawnEnv);
27
- return spawnEnv;
29
+ return applySessionScratchEnv(spawnEnv, sessionId);
28
30
  }
@@ -25,6 +25,8 @@ import { planShellDeadlines } from './bash-tool/deadline-plan.mjs';
25
25
  import { planShellInvocation } from './bash-tool/invocation-plan.mjs';
26
26
  import { renderBackgroundedResult } from './bash-tool/backgrounded-result.mjs';
27
27
  import { renderCompletedResult } from './bash-tool/completed-result.mjs';
28
+ import { effectiveShellCwd, shellCwdError } from './bash-tool/shell-cwd.mjs';
29
+ import { guardShellCall, requestedShellType } from './bash-tool/misuse-guard.mjs';
28
30
 
29
31
  export {
30
32
  SURVIVING_DESCENDANTS_WARNING,
@@ -64,9 +66,26 @@ function settleMutationCaches(shellEffects, backgroundJobId, runSettled = null)
64
66
  }
65
67
 
66
68
  export async function executeBashTool(args, workDir, options = {}) {
67
- // Every call starts from the current Project root. A command-local `cd`
68
- // never creates a second session cwd authority beside the dedicated cwd tool.
69
- const bashWorkDir = workDir;
69
+ // The tool-exec layer already guarded the call before its hooks ran and left
70
+ // its notes; a direct caller is guarded here.
71
+ const guarded = Array.isArray(options?.shellGuardNotes)
72
+ ? { args, notes: options.shellGuardNotes }
73
+ : guardShellCall(args, {
74
+ shellType: requestedShellType(args),
75
+ agent: options?.agent,
76
+ sessionId: options?.sessionId,
77
+ telemetry: options?.resultTelemetry,
78
+ });
79
+ if (guarded.failure) return guarded.failure;
80
+ args = guarded.args;
81
+ const guardNotes = guarded.notes;
82
+ // A call starts from the current Project root unless it names a `cwd`. A
83
+ // command-local `cd` never creates a second session cwd authority beside it.
84
+ const bashWorkDir = effectiveShellCwd(args, workDir);
85
+ if (bashWorkDir !== workDir) {
86
+ const cwdError = await shellCwdError(bashWorkDir);
87
+ if (cwdError) return formatShellToolFailure(cwdError);
88
+ }
70
89
  // Approval comes from the runtime's options, never from model-supplied args.
71
90
  const elevationApproved = options?.elevationApproved === true;
72
91
  const prepared = prepareShellCommand(args, { elevationApproved });
@@ -97,7 +116,12 @@ export async function executeBashTool(args, workDir, options = {}) {
97
116
  // A queued run, or a foreground tree that may outlive its result, settles later.
98
117
  let runSettled = null;
99
118
  try {
100
- const invocation = await planShellInvocation({ command, resolvedSpec, cwd: bashWorkDir });
119
+ const invocation = await planShellInvocation({
120
+ command,
121
+ resolvedSpec,
122
+ cwd: bashWorkDir,
123
+ sessionId: options?.callerSessionId || options?.sessionId || null,
124
+ });
101
125
  if (invocation.failure) return invocation.failure;
102
126
  combinedAbort = combineAbortSignals(await sessionAbortSignal(options?.sessionId), options?.abortSignal || null);
103
127
  const startedAtMs = Date.now();
@@ -106,6 +130,7 @@ export async function executeBashTool(args, workDir, options = {}) {
106
130
  shellArg: invocation.execShellArg,
107
131
  shellArgs: invocation.execShellArgs,
108
132
  command: invocation.wrappedCommand,
133
+ displayCommand: command,
109
134
  execScript: invocation.execScript,
110
135
  directArgv: invocation.directArgv,
111
136
  elevationApproved,
@@ -147,12 +172,12 @@ export async function executeBashTool(args, workDir, options = {}) {
147
172
  stdout,
148
173
  stderr,
149
174
  };
150
- if (backgrounded) return renderBackgroundedResult(rendering);
175
+ if (backgrounded) return renderBackgroundedResult({ ...rendering, notes: guardNotes.join('\n') });
151
176
  return renderCompletedResult({
152
177
  ...rendering,
153
178
  analysisCommand,
154
179
  timeout: deadlines.timeout,
155
- rewriteNote: [wmicRewrite?.note, bashismRewrite?.note].filter(Boolean).join('\n'),
180
+ rewriteNote: [wmicRewrite?.note, bashismRewrite?.note, ...guardNotes].filter(Boolean).join('\n'),
156
181
  });
157
182
  } finally {
158
183
  inputWake?.dispose();
@@ -5,7 +5,7 @@
5
5
  // behavior, argument shapes, and the usage boundaries that only apply to that
6
6
  // tool; cross-tool policy lives in rules/shared/*.md.
7
7
  // Platform-specific command syntax belongs next to the command argument.
8
- import { GIT_TOOL_DEF } from './git-command-tool.mjs';
8
+ import { GIT_AGENT_TOOL_DEF, GIT_TOOL_DEF } from './git-command-tool.mjs';
9
9
  import { PUBLIC_PATH_BATCH_LIMIT, PUBLIC_READ_WINDOW_MAX } from './arg-guard.mjs';
10
10
  import { GITHUB_TOOL_DEF } from '../../../../github/tool.mjs';
11
11
  import { envFlag } from '../../../../shared/env.mjs';
@@ -27,13 +27,71 @@ export const TASK_WAIT_TIMEOUT_DEFAULT_MS = TASK_WAIT_DEFAULT_MS;
27
27
  export const TASK_WAIT_TIMEOUT_MIN_MS = TASK_WAIT_MIN_MS;
28
28
  export const TASK_WAIT_TIMEOUT_MAX_MS = TASK_WAIT_MAX_MS;
29
29
  const _holdS = budgetSeconds(SHELL_HOLD_DEFAULT_MS);
30
- const _shellSyntaxCheat =
31
- process.platform === 'win32'
32
- ? " PowerShell: ; between independent commands, if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } between dependent ones; no heredoc, </dev/null or | head/tail/wc (Select-Object -First/-Last); multiline python/node via @'…'@ | python - (node -); 2>$null; /c/→C:\\; $PID is reserved."
33
- : ' Bash: chain dependent commands with &&; multiline input via a quoted heredoc delimiter, not extra quoting/escape layers.';
34
30
  // Process-stable switch used to describe foreground-only execution accurately.
35
31
  const _shellBackgroundDisabled = envFlag('MIXDOG_SHELL_DISABLE_BACKGROUND_TASKS');
36
32
 
33
+ // Shell kinds the description is written for: 'powershell' or 'posix' (bash,
34
+ // zsh, sh, Git Bash, WSL), the `shellType` of the runtime's resolved shell.
35
+ // BUILTIN_TOOLS is static, so it carries the platform's default kind; a
36
+ // session whose configured system shell is the other kind gets the matching
37
+ // text through bindShellKind where the session tool schema is assembled.
38
+ const _defaultShellKind = process.platform === 'win32' ? 'powershell' : 'posix';
39
+
40
+ // The kind's banned commands → replacement tool. `edit/apply_patch` is
41
+ // rewritten per model by the edit-dialect surface filter.
42
+ export function buildShellRoutingRules(kind = _defaultShellKind) {
43
+ const pairs =
44
+ kind === 'powershell'
45
+ ? 'Get-Content/gc/cat/type→read; Get-ChildItem/dir/ls→list/glob/find; Select-String/findstr→grep; Set-Content/Add-Content/Out-File/`>`→edit/apply_patch'
46
+ : 'cat/head/tail/less→read; ls/tree→list; find→glob/find; grep/rg/ag→grep; file authoring via sed/awk/echo >/tee/heredoc→edit/apply_patch';
47
+ return `Never use shell commands/scripts for work other tools cover: ${pairs}; git→git (-C <dir> for other folders); code structure→code_graph.`;
48
+ }
49
+
50
+ function buildShellDescription(kind) {
51
+ const run = _shellBackgroundDisabled
52
+ ? 'Commands run in the foreground until completion.'
53
+ : `Holds ${_holdS}s; then, or on input/task notification, backgrounds with task_id (command keeps running). Completion is automatic; never poll, and never sleep/poll-loop inside the shell (background:true or wait_ms instead; for an external job, background a command that exits when it ends). Result needed now: task wait. Independent long runs: background:true; cancel when done.`;
54
+ return `Run programs, builds, tests and computation. ${buildShellRoutingRules(kind)} ${run}`;
55
+ }
56
+
57
+ function buildShellCommandDescription(kind) {
58
+ const cheat =
59
+ kind === 'powershell'
60
+ ? " PowerShell: ; between independent commands, if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } between dependent ones; no Bash heredocs or </dev/null; Select-Object shapes program output, not file reads; multiline python/node via @'…'@ | python - (node -); 2>$null; /c/→C:\\; $PID is reserved."
61
+ : ' Bash: chain dependent commands with &&; multiline input via a quoted heredoc delimiter, not extra quoting/escape layers.';
62
+ return `Command.${cheat}`;
63
+ }
64
+
65
+ // One bound copy per (tool, kind), so a session's shell tool keeps its identity
66
+ // and bytes from turn to turn.
67
+ const _boundShellTools = new WeakMap();
68
+
69
+ /** The shell tool with the text of `kind`, when that differs from the static default. */
70
+ export function bindShellKind(tool, kind) {
71
+ if (tool?.name !== 'shell' || kind === _defaultShellKind || (kind !== 'powershell' && kind !== 'posix')) return tool;
72
+ const cached = _boundShellTools.get(tool)?.get(kind);
73
+ if (cached) return cached;
74
+ const properties = tool.inputSchema?.properties || {};
75
+ const bound = {
76
+ ...tool,
77
+ description: buildShellDescription(kind),
78
+ inputSchema: {
79
+ ...tool.inputSchema,
80
+ properties: {
81
+ ...properties,
82
+ command: { ...properties.command, description: buildShellCommandDescription(kind) },
83
+ },
84
+ },
85
+ };
86
+ if (!_boundShellTools.has(tool)) _boundShellTools.set(tool, new Map());
87
+ _boundShellTools.get(tool).set(kind, bound);
88
+ return bound;
89
+ }
90
+
91
+ function taskTimeoutDescription(defaultMs) {
92
+ return `Wait ceiling in ms; else current output at the ceiling. Default ${defaultMs}; clamped to ${TASK_WAIT_TIMEOUT_MIN_MS}-${TASK_WAIT_TIMEOUT_MAX_MS}.`;
93
+ }
94
+
37
95
  export const BUILTIN_TOOLS = [
38
96
  {
39
97
  name: 'read',
@@ -47,7 +105,7 @@ export const BUILTIN_TOOLS = [
47
105
  compressible: false,
48
106
  },
49
107
  description:
50
- "Read file windows or images. One call per read stage: {file_path, offset, limit} entries for every located site (≤10 files per call), never a whole large file. Content in context is never read again. Missing paths are reported, never replaced. Directories: list. Binaries: bounded hex. Rows carry no line numbers; `[lines a-b]` gives each block's range. Never count rows: before writing a line number, copy it from grep, code_graph or git diff output; otherwise cite path and symbol.",
108
+ "Read file windows or images. One call per read stage: {file_path, offset, limit} entries for every located site, never a whole large file. Content in context is never read again. Missing paths are reported, never replaced. Directories: list. Binaries: bounded hex. Rows carry no line numbers; `[lines a-b]` gives each block's range. Never count rows: before writing a line number, copy it from grep, code_graph or git diff output; otherwise cite path and symbol.",
51
109
  inputSchema: {
52
110
  type: 'object',
53
111
  properties: {
@@ -75,8 +133,7 @@ export const BUILTIN_TOOLS = [
75
133
  },
76
134
  },
77
135
  ],
78
- description:
79
- 'Path(s) or {file_path, offset, limit} entries; overlapping windows of one file merge. A glob fans out to ≤10 newest files, 25 lines each.',
136
+ description: 'Overlapping windows of one file merge. A glob fans out to ≤10 newest files.',
80
137
  },
81
138
  offset: {
82
139
  type: 'integer',
@@ -113,14 +170,11 @@ export const BUILTIN_TOOLS = [
113
170
  compressibleLossless: true,
114
171
  },
115
172
  description:
116
- 'Replace exact text in one file. old_string must match once unless replace_all is true. Every non-overlapping edit of the stage in one response, using existing text, not text another edit creates; many files → one edit per file, all in that response. Widened replacements keep intervening lines verbatim.',
173
+ 'Replace exact text in one file. old_string must match once unless replace_all is true. Every non-overlapping edit of the stage in one response, using existing text, not text another edit creates; many files → one edit per file. Widened replacements keep intervening lines verbatim.',
117
174
  inputSchema: {
118
175
  type: 'object',
119
176
  properties: {
120
- file_path: {
121
- type: 'string',
122
- description: 'Path to the file to modify.',
123
- },
177
+ file_path: { type: 'string' },
124
178
  old_string: {
125
179
  type: 'string',
126
180
  description:
@@ -133,7 +187,7 @@ export const BUILTIN_TOOLS = [
133
187
  replace_all: {
134
188
  type: 'boolean',
135
189
  default: false,
136
- description: 'Replace all occurrences of old_string; default false.',
190
+ description: 'Replace all occurrences of old_string.',
137
191
  },
138
192
  },
139
193
  required: ['file_path', 'old_string', 'new_string'],
@@ -151,11 +205,15 @@ export const BUILTIN_TOOLS = [
151
205
  openWorldHint: true,
152
206
  compressible: true,
153
207
  },
154
- 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.' : `Holds up to ${_holdS}s for the result. Still running at ${_holdS}s, or new user input or a task notification arrives: it moves to the background (never killed) and returns task_id plus output so far. Completion is delivered automatically; task wait only when you need the result now. If no execution slot frees, the command is queued as a background task. Dev servers/watchers: background:true, and stop them with task cancel when done.`}`,
208
+ description: buildShellDescription(_defaultShellKind),
155
209
  inputSchema: {
156
210
  type: 'object',
157
211
  properties: {
158
- command: { type: 'string', description: `Command.${_shellSyntaxCheat}` },
212
+ command: { type: 'string', description: buildShellCommandDescription(_defaultShellKind) },
213
+ cwd: {
214
+ type: 'string',
215
+ description: 'Working directory; default the Project. Use it instead of cd/Set-Location.',
216
+ },
159
217
  timeout_ms: {
160
218
  type: 'integer',
161
219
  minimum: 0,
@@ -165,7 +223,7 @@ export const BUILTIN_TOOLS = [
165
223
  type: 'integer',
166
224
  minimum: SHELL_HOLD_MIN_MS,
167
225
  maximum: SHELL_HOLD_MAX_MS,
168
- description: `Hold in ms before a still-running command moves to the background (default ${SHELL_HOLD_DEFAULT_MS}). Usually omit.`,
226
+ description: `Hold in ms before a still-running command moves to the background (default ${SHELL_HOLD_DEFAULT_MS}). Usually omit; for a long finite command needed next, set up to ${SHELL_HOLD_MAX_MS}.`,
169
227
  },
170
228
  background: {
171
229
  type: 'boolean',
@@ -196,7 +254,7 @@ export const BUILTIN_TOOLS = [
196
254
  openWorldHint: false,
197
255
  },
198
256
  description:
199
- 'Manage shell tasks. Completion is delivered automatically; wait only when you need the result now, never poll with read. wait returns when the task finishes, or when new user input or any task notification arrives (the task keeps running). read/wait return new output, prioritizing the tail on completion. output:tail re-reads recent output without advancing the cursor; use read on the log path for omitted content.',
257
+ 'Manage shell tasks. Completion is delivered automatically; wait only when you need the result now, never poll with read. wait returns when the task finishes, or when new user input or any task notification arrives (the task keeps running). read/wait return new output, prioritizing the tail on completion. Use read on the log path for omitted content.',
200
258
  inputSchema: {
201
259
  type: 'object',
202
260
  properties: {
@@ -209,13 +267,13 @@ export const BUILTIN_TOOLS = [
209
267
  timeout_ms: {
210
268
  type: 'integer',
211
269
  minimum: 0,
212
- description: `Wait ceiling in ms; returns on completion, new user input or a task notification, else current output at the ceiling. Default ${TASK_WAIT_TIMEOUT_DEFAULT_MS} (agents ${AGENT_TASK_WAIT_DEFAULT_MS}); clamped to ${TASK_WAIT_TIMEOUT_MIN_MS}-${TASK_WAIT_TIMEOUT_MAX_MS}.`,
270
+ description: taskTimeoutDescription(TASK_WAIT_TIMEOUT_DEFAULT_MS),
213
271
  },
214
272
  output: {
215
273
  type: 'string',
216
274
  enum: ['new', 'tail'],
217
275
  description:
218
- 'read/wait only. Default new; tail replays recent output after an interruption or context loss. Up to 8 KiB per stream while running, 12 KiB on completion or replay; original logs are preserved.',
276
+ 'read/wait only. Default new; tail re-reads recent output without advancing the cursor, after an interruption or context loss. Up to 8 KiB per stream while running, 12 KiB on completion or replay; original logs are preserved.',
219
277
  },
220
278
  },
221
279
  required: ['action'],
@@ -266,7 +324,7 @@ export const BUILTIN_TOOLS = [
266
324
  description:
267
325
  'Requested results; default 250; 0 unlimited. Context output caps at 40 blocks; continue via the returned offset.',
268
326
  },
269
- offset: { type: 'integer', minimum: 0, description: 'Result offset.' },
327
+ offset: { type: 'integer', minimum: 0 },
270
328
  context: {
271
329
  type: 'integer',
272
330
  minimum: 0,
@@ -298,7 +356,7 @@ export const BUILTIN_TOOLS = [
298
356
  compressible: true,
299
357
  },
300
358
  description:
301
- 'Wildcard file-path lookup under a known directory; directories never match. Omit path for the current Project; no preliminary listing. Unknown base: find first with a known path fragment. Gitignored paths need include_noise:true.',
359
+ 'Wildcard file-path lookup under a known directory; directories never match. No preliminary listing. Unknown base: find first with a known path fragment.',
302
360
  inputSchema: {
303
361
  type: 'object',
304
362
  properties: {
@@ -316,7 +374,7 @@ export const BUILTIN_TOOLS = [
316
374
  description: 'mtime default (newest first); natural = raw walk order, cheaper on huge trees.',
317
375
  },
318
376
  limit: { type: 'integer', minimum: 0, description: 'Max entries; default 100; 0 unlimited.' },
319
- offset: { type: 'integer', minimum: 0, description: 'Entry offset.' },
377
+ offset: { type: 'integer', minimum: 0 },
320
378
  include_noise: {
321
379
  type: 'boolean',
322
380
  description: 'Also search gitignored trees.',
@@ -346,7 +404,7 @@ export const BUILTIN_TOOLS = [
346
404
  type: 'string',
347
405
  minLength: 1,
348
406
  pattern: '\\S',
349
- description: 'Non-empty filename/path fragment; space-separated fragments AND-match within one path.',
407
+ description: 'Filename/path fragment; space-separated fragments AND-match within one path.',
350
408
  },
351
409
  path: { type: 'string', description: 'Base directory; omit for the current Project.' },
352
410
  limit: { type: 'integer', minimum: 0, description: 'Max paths; default 25; 0 unlimited.' },
@@ -387,10 +445,36 @@ export const BUILTIN_TOOLS = [
387
445
  maximum: 100,
388
446
  description: 'Max entries; default 100; 0 = no page cap (absolute cap still applies).',
389
447
  },
390
- offset: { type: 'integer', minimum: 0, description: 'Entry offset.' },
448
+ offset: { type: 'integer', minimum: 0 },
391
449
  },
392
- required: [],
393
450
  additionalProperties: false,
394
451
  },
395
452
  },
396
453
  ];
454
+
455
+ // What a delegated agent's session sees of the tools whose text differs from
456
+ // the Lead's: git (worktree operations are Lead-only) and task (the agent wait
457
+ // default). Keyed by the shared definition, so a rebuilt list binds once.
458
+ const _taskTool = BUILTIN_TOOLS.find((tool) => tool.name === 'task');
459
+ const _agentTaskTool = {
460
+ ..._taskTool,
461
+ inputSchema: {
462
+ ..._taskTool.inputSchema,
463
+ properties: {
464
+ ..._taskTool.inputSchema.properties,
465
+ timeout_ms: {
466
+ ..._taskTool.inputSchema.properties.timeout_ms,
467
+ description: taskTimeoutDescription(AGENT_TASK_WAIT_DEFAULT_MS),
468
+ },
469
+ },
470
+ },
471
+ };
472
+ const _agentToolVariants = new Map([
473
+ [GIT_TOOL_DEF, GIT_AGENT_TOOL_DEF],
474
+ [_taskTool, _agentTaskTool],
475
+ ]);
476
+
477
+ /** The agent-session variant of `tool`, or `tool` itself when it has none. */
478
+ export function bindAgentOwner(tool) {
479
+ return _agentToolVariants.get(tool) ?? tool;
480
+ }
@@ -324,7 +324,13 @@ export function rawContentCacheSet(fullPath, stat, rawBuf, now = Date.now()) {
324
324
  if (!canPublishReadCache(fullPath)) return;
325
325
  if (!fullPath || !Buffer.isBuffer(rawBuf)) return;
326
326
  const version = fileVersion(stat);
327
- if (!version || !canCacheReadFile(version) || rawBuf.length !== version.size || rawBuf.length > RAW_CONTENT_CACHE_MAX_BYTES) return;
327
+ if (
328
+ !version ||
329
+ !canCacheReadFile(version) ||
330
+ rawBuf.length !== version.size ||
331
+ rawBuf.length > RAW_CONTENT_CACHE_MAX_BYTES
332
+ )
333
+ return;
328
334
  const key = canonicalCachePath(fullPath);
329
335
  rawContentCacheDelete(key);
330
336
  RAW_CONTENT_CACHE.set(key, {