mixdog 1.4.2 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (417) hide show
  1. package/package.json +2 -2
  2. package/scripts/build-shipped-history.mjs +15 -5
  3. package/scripts/gate-local.mjs +65 -19
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +2 -1
  6. package/scripts/lib/run-node-tests.mjs +17 -5
  7. package/scripts/lib/test-failure-summary.mjs +1 -8
  8. package/scripts/lib/test-spawn-ledger.mjs +33 -2
  9. package/scripts/post-release-check.mjs +26 -16
  10. package/scripts/provider-pingpong-live.mjs +1 -1
  11. package/scripts/prune-embedding-runtime.mjs +3 -1
  12. package/scripts/release-paths.mjs +7 -1
  13. package/src/defaults/shipped-history.json +20 -0
  14. package/src/defaults/skills/setup/SKILL.md +2 -2
  15. package/src/defaults/skills/setup/references/actions.md +16 -3
  16. package/src/defaults/skills/setup/references/surfaces.md +3 -0
  17. package/src/defaults/skills/setup-guide/SKILL.md +6 -1
  18. package/src/lib/instruction-text.cjs +36 -0
  19. package/src/lib/rules-builder.cjs +34 -20
  20. package/src/orchestration/balanced.md +23 -0
  21. package/src/orchestration/focused.md +22 -0
  22. package/src/orchestration/none.md +5 -0
  23. package/src/orchestration/swarm.md +24 -0
  24. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  25. package/src/rules/agent-mode/MIXY.md +2 -2
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +0 -1
  28. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +4 -2
  29. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +0 -9
  30. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  31. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  32. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  33. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +4 -4
  34. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -1
  35. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +199 -46
  36. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +3 -5
  37. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +9 -3
  38. package/src/runtime/agent/orchestrator/mcp/client.mjs +3 -5
  39. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  40. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  41. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  42. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  43. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  46. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  48. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  49. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  50. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  51. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  52. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +10 -1
  53. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  54. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +30 -0
  55. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  56. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  57. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  58. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  59. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  60. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  61. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  62. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  63. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  64. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  65. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  66. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  67. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  68. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  69. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  70. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -48
  71. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  72. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  73. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  74. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +9 -0
  75. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  76. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +1 -1
  77. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  79. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  80. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  81. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +2 -2
  82. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  83. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  86. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  88. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +1 -1
  89. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +1 -1
  91. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  92. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +1 -2
  94. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  96. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  97. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  99. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  100. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  101. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  102. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  104. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  106. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +6 -1
  107. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
  108. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  109. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  110. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +57 -26
  111. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  112. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  113. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  114. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  115. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  116. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  117. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  118. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  119. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  120. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  121. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  122. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  123. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  124. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  125. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  126. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +19 -0
  127. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +19 -10
  128. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +5 -0
  129. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  130. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +31 -0
  131. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  132. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +42 -6
  133. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  134. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +11 -1
  135. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  136. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  137. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  138. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  139. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  140. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +1 -1
  141. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  142. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  143. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  145. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  146. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  148. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  149. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  150. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  151. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  152. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  153. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +14 -5
  154. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +2 -2
  155. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  156. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  157. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  158. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  159. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  160. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  161. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  162. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  163. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  164. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  165. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  166. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  167. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +7 -3
  168. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +27 -9
  169. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  170. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  172. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  173. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1 -2
  174. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  175. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  176. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  177. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  179. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  180. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  181. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  182. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +2 -2
  183. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +1 -1
  184. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +0 -4
  185. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  186. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  187. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  188. package/src/runtime/attachments/store.d.mts +1 -0
  189. package/src/runtime/attachments/store.mjs +2 -2
  190. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  191. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  192. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  193. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  194. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  195. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  196. package/src/runtime/channels/lib/whisper-server.mjs +12 -12
  197. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  198. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  199. package/src/runtime/connectors/connector-accounts-mcp.mjs +169 -33
  200. package/src/runtime/connectors/gmail-app-password.mjs +2 -2
  201. package/src/runtime/connectors/google-mcp.mjs +1 -1
  202. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  203. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  204. package/src/runtime/explore/explorer.mjs +0 -5
  205. package/src/runtime/explore/tool.mjs +3 -3
  206. package/src/runtime/local-provider/hardware.mjs +1 -1
  207. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  208. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  209. package/src/runtime/media/media-usage.mjs +1 -1
  210. package/src/runtime/media/store.mjs +1 -1
  211. package/src/runtime/memory/index.mjs +11 -1
  212. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  213. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  214. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  215. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  216. package/src/runtime/memory/lib/memory.mjs +17 -0
  217. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  218. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  219. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  220. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  221. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  222. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  223. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  224. package/src/runtime/office/capabilities.mjs +1 -1
  225. package/src/runtime/office/core/office-core.mjs +1 -1
  226. package/src/runtime/office/design/content-model.mjs +3 -3
  227. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  228. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  229. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  230. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  231. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  232. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  233. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  234. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  235. package/src/runtime/shared/atomic-file.d.mts +8 -0
  236. package/src/runtime/shared/background-tasks.mjs +22 -4
  237. package/src/runtime/shared/background-wait.mjs +66 -0
  238. package/src/runtime/shared/child-guardian.mjs +17 -7
  239. package/src/runtime/shared/config.mjs +313 -16
  240. package/src/runtime/shared/connector-catalog.d.mts +4 -5
  241. package/src/runtime/shared/connector-catalog.mjs +11 -1
  242. package/src/runtime/shared/file-lock.mjs +8 -3
  243. package/src/runtime/shared/git-runner.mjs +7 -2
  244. package/src/runtime/shared/idle-gc.mjs +30 -7
  245. package/src/runtime/shared/llm/http-agent.mjs +8 -5
  246. package/src/runtime/shared/llm/system-proxy.mjs +2 -1
  247. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  248. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  249. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  250. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  251. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  252. package/src/runtime/shared/process-runner.mjs +8 -4
  253. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  254. package/src/runtime/shared/routine-trigger.mjs +34 -0
  255. package/src/runtime/shared/run-child.d.mts +2 -1
  256. package/src/runtime/shared/run-child.mjs +70 -18
  257. package/src/runtime/shared/session-scratch.mjs +14 -2
  258. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  259. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  260. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  261. package/src/runtime/shared/tool-work-units.mjs +31 -6
  262. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  263. package/src/runtime/shared/turn-worktree-snapshot.mjs +6 -11
  264. package/src/runtime/shared/worker-requests.mjs +17 -3
  265. package/src/runtime/shared/worktrees/branch-management.mjs +1 -5
  266. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  267. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  268. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  269. package/src/runtime/shared/worktrees/git.mjs +44 -11
  270. package/src/runtime/shared/worktrees/include.mjs +6 -4
  271. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  272. package/src/runtime/shared/worktrees/manager.mjs +772 -75
  273. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  274. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  275. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  276. package/src/runtime/tidy/process.mjs +2 -1
  277. package/src/runtime/web-search/index.mjs +3 -22
  278. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  279. package/src/runtime/web-search/tool-defs.mjs +17 -26
  280. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  281. package/src/session-runtime/boot/apis.mjs +27 -4
  282. package/src/session-runtime/boot/begin.mjs +2 -0
  283. package/src/session-runtime/boot/config.mjs +10 -1
  284. package/src/session-runtime/boot/facade.mjs +1 -0
  285. package/src/session-runtime/boot/providers.mjs +70 -3
  286. package/src/session-runtime/boot/session.mjs +2 -0
  287. package/src/session-runtime/boot/tools.mjs +69 -25
  288. package/src/session-runtime/channel-config-api.mjs +1 -0
  289. package/src/session-runtime/config-change-effects.mjs +179 -0
  290. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  291. package/src/session-runtime/config-lifecycle.mjs +160 -24
  292. package/src/session-runtime/conversation-import/discovery.mjs +86 -7
  293. package/src/session-runtime/conversation-import/service.mjs +3 -2
  294. package/src/session-runtime/goal-facade-api.mjs +49 -3
  295. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  296. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  297. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +3 -11
  298. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +18 -4
  299. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  300. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  301. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  302. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  303. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  304. package/src/session-runtime/lifecycle/teardown/session-close.mjs +4 -4
  305. package/src/session-runtime/lifecycle-api.mjs +1 -0
  306. package/src/session-runtime/mcp-glue/server-catalog.mjs +14 -3
  307. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  308. package/src/session-runtime/model-route/set-route.mjs +40 -7
  309. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  310. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  311. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  312. package/src/session-runtime/provider-readiness.mjs +53 -4
  313. package/src/session-runtime/resource-api.mjs +1 -1
  314. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  315. package/src/session-runtime/resource-mcp-connector-accounts.mjs +5 -1
  316. package/src/session-runtime/resource-mcp-secrets.mjs +3 -3
  317. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  318. package/src/session-runtime/routine-executor.mjs +152 -0
  319. package/src/session-runtime/routine-home-turn.mjs +46 -5
  320. package/src/session-runtime/runtime-facade.mjs +5 -0
  321. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  322. package/src/session-runtime/schedule-session-run.mjs +1 -0
  323. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  324. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  325. package/src/session-runtime/services/agent-tool/send-flow.mjs +110 -6
  326. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  327. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  328. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +24 -6
  329. package/src/session-runtime/services/agent-tool.mjs +51 -1
  330. package/src/session-runtime/services/channel-admin.mjs +18 -0
  331. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  332. package/src/session-runtime/services/plugin-admin.mjs +4 -0
  333. package/src/session-runtime/services/seeds.mjs +7 -0
  334. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  335. package/src/session-runtime/session-create/materialize.mjs +4 -2
  336. package/src/session-runtime/session-create/session-options.mjs +2 -0
  337. package/src/session-runtime/settings-builtin-tools-api.mjs +1 -9
  338. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +1 -1
  339. package/src/session-runtime/setup-tool/executor.mjs +8 -1
  340. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  341. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  342. package/src/session-runtime/setup-tool/tool-defs.mjs +26 -1
  343. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  344. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  345. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  346. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  347. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  348. package/src/session-runtime/tool-surface.mjs +38 -1
  349. package/src/session-runtime/turn/agent-ops.mjs +10 -2
  350. package/src/session-runtime/turn/session-ops.mjs +2 -0
  351. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  352. package/src/session-runtime/turn/turn-run.mjs +1 -1
  353. package/src/session-runtime/webhook-session-run.mjs +2 -0
  354. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +1 -4
  355. package/src/session-runtime/workflow-agents-api/agent-route.mjs +3 -10
  356. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  357. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  358. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  359. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  360. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  361. package/src/session-runtime/workspace/session-view.mjs +1 -1
  362. package/src/session-runtime/workspace/transitions.mjs +20 -4
  363. package/src/session-runtime/workspace/worktree-maintenance.mjs +126 -6
  364. package/src/session-runtime/workspace/worktree-setup.mjs +13 -1
  365. package/src/session-runtime/workspace/worktree-tool.mjs +16 -0
  366. package/src/standalone/daemon-agent-control.mjs +25 -8
  367. package/src/standalone/daemon-desktop-runtime.mjs +6 -2
  368. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  369. package/src/standalone/daemon.mjs +54 -2
  370. package/src/standalone/local-session-runtime.mjs +16 -0
  371. package/src/standalone/session-client/daemon-unavailable.mjs +1 -1
  372. package/src/standalone/session-protocol.mjs +11 -0
  373. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  374. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  375. package/src/standalone/session-service/quota-resume.mjs +9 -0
  376. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  377. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  378. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  379. package/src/standalone/session-service/session-calls.mjs +2 -1
  380. package/src/tui/App.jsx +8 -0
  381. package/src/tui/app/clipboard.mjs +1 -1
  382. package/src/tui/app/create-app-pickers.mjs +2 -0
  383. package/src/tui/app/doctor.mjs +2 -2
  384. package/src/tui/app/panel-signature.mjs +1 -1
  385. package/src/tui/app/settings-picker.mjs +53 -8
  386. package/src/tui/app/shell-layout/row-budgets.mjs +2 -2
  387. package/src/tui/app/slash-commands.mjs +1 -1
  388. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  389. package/src/tui/app/slash-dispatch/session-commands.mjs +1 -1
  390. package/src/tui/app/use-prompt-queue-history.mjs +2 -2
  391. package/src/tui/app/use-transcript-activity.mjs +1 -1
  392. package/src/tui/app/use-transcript-window/geometry.mjs +1 -1
  393. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  394. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  395. package/src/tui/components/question-panel-model.mjs +4 -4
  396. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  397. package/src/tui/components/user-message-skills.mjs +1 -1
  398. package/src/tui/dist/index.mjs +309 -30
  399. package/src/tui/markdown/render-ansi.mjs +1 -1
  400. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  401. package/src/tui/session/agent-job-feed.mjs +2 -0
  402. package/src/tui/session/context-state.mjs +3 -0
  403. package/src/tui/session/quota-resume.mjs +1 -1
  404. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  405. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  406. package/src/tui/session/session-api/routes-agent-definitions.mjs +5 -0
  407. package/src/tui/session/session-api/worktree.mjs +13 -1
  408. package/src/tui/session/session-flow/drain.mjs +11 -14
  409. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  410. package/src/tui/session/turn-quiet.mjs +1 -1
  411. package/src/tui/session/turn.mjs +3 -0
  412. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  413. package/src/tui/spinner-meta.mjs +3 -3
  414. package/src/tui/spinner-verbs.mjs +2 -2
  415. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  416. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  417. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -260,7 +260,7 @@ export function isStatusOnlyAgentCompletionNotification(text) {
260
260
  return !(hasAgentResponseResultText(result) || hasAgentResponseResultText(text));
261
261
  }
262
262
 
263
- export function hasAgentResponseResultText(text) {
263
+ function hasAgentResponseResultText(text) {
264
264
  const value = String(text || '').trim();
265
265
  if (!value) return false;
266
266
  const notification = parseTaskNotification(value);
@@ -685,7 +685,9 @@ export function restoreTranscriptItems(messages, { sessionId = 'session', itemLi
685
685
  export function sessionContextSnapshotProjection(session, contextStatus) {
686
686
  if (!contextStatus) return {};
687
687
  return {
688
- stats: contextMeasurementStats(contextStatus),
688
+ // The composer's usage readout reads the session totals from the same
689
+ // stats a live runtime publishes; a cold open has no runtime to add them.
690
+ stats: { ...contextMeasurementStats(contextStatus), usageReadout: contextStatus.usage?.usageReadout ?? null },
689
691
  contextWindow: Math.max(0, Number(session?.contextWindow || contextStatus.effectiveContextWindow || 0)),
690
692
  rawContextWindow: Math.max(0, Number(session?.rawContextWindow || contextStatus.rawContextWindow || 0)),
691
693
  effectiveContextWindowPercent: Number(
@@ -99,7 +99,7 @@ function feedbackDisplay(body) {
99
99
  return lines.join('\n');
100
100
  }
101
101
 
102
- export function withVisualizeFeedbackDisplay(text) {
102
+ function withVisualizeFeedbackDisplay(text) {
103
103
  const value = String(text ?? '');
104
104
  if (!value.includes(FEEDBACK_OPEN)) return value;
105
105
  return value.replace(FEEDBACK_BLOCK, (_block, body) => feedbackDisplay(body));
@@ -121,7 +121,7 @@ const PASTED_LINES = /· (\d+) lines?$/;
121
121
  const PASTED_TEXT_MAX_BYTES = 1024 * 1024;
122
122
  /** Blob bytes one transcript load may read to count the lines of pastes
123
123
  * whose stored name does not carry the count (pastes stored before it did). */
124
- export const PASTED_LINE_READ_BUDGET_BYTES = 4 * 1024 * 1024;
124
+ const PASTED_LINE_READ_BUDGET_BYTES = 4 * 1024 * 1024;
125
125
 
126
126
  /** A stored plain-text prompt part's text within the load's byte budget, else ''. */
127
127
  function offloadedPromptText(part, budget) {
@@ -137,11 +137,9 @@ export const PROVIDER_SSE_IDLE_TIMEOUT_MS = resolveTimeoutMs('MIXDOG_PROVIDER_SS
137
137
  // silent-window token rate a steady ~92 tok/s, i.e. live generation, not a
138
138
  // wedge). So a "semantic-silent" stream is NOT necessarily dead.
139
139
  //
140
- // 2026-08-03 v3 postmortem: this window used to be DERIVED from the agent
141
- // stall budget (warn − tick ≈ 285s). A harness that tightened STALL_TIMEOUT_S
142
- // to 300s silently collapsed it to 135s, which deterministically beheaded
143
- // live long-thinking turns (regex-chess / circuit-fibsqrt: ttft ~1.5s, then
144
- // killed at exactly 135s of silent thinking, 4 attempts ≈ 552s per turn).
140
+ // Deriving this window from the agent stall budget (warn − tick ≈ 285s) would
141
+ // let a harness that tightens STALL_TIMEOUT_S to 300s collapse it to 135s,
142
+ // which deterministically beheads live long-thinking turns.
145
143
  // Reference behavior: abort only after a 300s single-gap silence, and fall
146
144
  // back to non-streaming instead of killing the turn. The default is
147
145
  // therefore a FIXED 300s, decoupled from the warn math. The only remaining
@@ -1,4 +1,5 @@
1
1
  import { registerBackgroundTask, renderBackgroundTask } from '../../../../../shared/background-tasks.mjs';
2
+ import { stampShellJobCycle } from '../../../../../shared/background-wait.mjs';
2
3
  import { killShellJob, watchBackgroundShellJob } from '../shell-jobs.mjs';
3
4
  import { renderBackgroundPartialOutput } from '../shell-output.mjs';
4
5
  import { readShellTaskOutput } from '../lib/shell-task-output.mjs';
@@ -65,7 +66,9 @@ export function renderBackgroundedResult({
65
66
  }) {
66
67
  let task = null;
67
68
  if (result.jobId) {
68
- task = registerPromotedTask({ result, command, cwd, options, startedAtMs });
69
+ // The owner's user cycle at start decides whether it is waited on
70
+ // (background-wait.mjs), however the job reached the background.
71
+ task = stampShellJobCycle(registerPromotedTask({ result, command, cwd, options, startedAtMs }));
69
72
  try {
70
73
  watchBackgroundShellJob(result.jobId, {
71
74
  notifyFn: typeof options?.notifyFn === 'function' ? options.notifyFn : null,
@@ -5,13 +5,16 @@
5
5
  // to background + task wait);
6
6
  // 2. a plain leading `cd <dir>` moves into the `cwd` argument;
7
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.
8
+ // read / grep / list tools — a note now, a rejection when the mode flips;
9
+ // 4. a command mentioning `git … worktree add` is rejected (worktrees go
10
+ // through the git tool; a textual check, so mentions as data are too).
9
11
  import { shellSplitPipelineSegments, shellSplitSegments, shellTokenize } from '../shell-analysis.mjs';
10
12
  import { resolveShellFor } from '../shell-runtime.mjs';
11
13
  import { formatShellToolFailure } from './result-format.mjs';
14
+ import { addsUnmanagedWorktree } from './worktree-add-guard.mjs';
12
15
 
13
16
  /** `warn` runs the read with a note; `reject` returns the block without running. */
14
- export const SHELL_FILE_READ_MODE = 'warn';
17
+ const SHELL_FILE_READ_MODE = 'warn';
15
18
  export const SHELL_FILE_READ_NOTE = 'Note: use the read / grep / list tools for files instead of the shell.';
16
19
  const SHELL_FILE_READ_BLOCK =
17
20
  'Blocked: use read / grep / list for files instead of the shell (read takes offset/limit for a window of a large file).';
@@ -194,6 +197,20 @@ function detectShellFileRead(command, shellType) {
194
197
  return operands.length >= minOperands ? { tool, command: name } : null;
195
198
  }
196
199
 
200
+ // ── 4. unmanaged worktrees ───────────────────────────────────────────────────
201
+
202
+ // A worktree added from the shell is invisible to the managed cleanup and
203
+ // outlives the session that made it, so `git … worktree add` never runs here.
204
+ // The check is textual (worktree-add-guard.mjs): a command that only mentions
205
+ // the phrase is refused too, so the message says how to go on either way.
206
+ const SHELL_WORKTREE_ADD_BLOCK =
207
+ 'Blocked: this shell command mentions `git … worktree add`, which does not run from the shell; ' +
208
+ 'Mixdog manages worktrees so they are cleaned up. To create one, use the git tool: command ' +
209
+ '"git worktree add --detach <path> [<commit>]" makes a read-only snapshot (removed when the turn ends; ' +
210
+ 'delegated workers too), and the Lead uses "git worktree add -b <branch> <path>" or action:"worktree" for a ' +
211
+ 'branch worktree. The check is textual: to search for that text use the grep tool, and keep the phrase out ' +
212
+ 'of shell commands (echo, commit messages, heredocs).';
213
+
197
214
  // ── the guard ────────────────────────────────────────────────────────────────
198
215
 
199
216
  /** The syntax family of the shell a call asks for (`args.shell`, as foreign adapters set it), else the default shell's. */
@@ -209,7 +226,7 @@ function recordFileRead(telemetry, entry) {
209
226
  }
210
227
 
211
228
  /**
212
- * Apply the three guards to a shell call.
229
+ * Apply the four guards to a shell call.
213
230
  * @returns {{ failure: string } | { args: object, notes: string[] }} the
214
231
  * rejection, or the call to run (a leading `cd` moved into `cwd`) with the
215
232
  * lines to add to its result.
@@ -230,6 +247,7 @@ export function guardShellCall(
230
247
  const sleepFailure = leadingSleepFailure(guarded.command, shellType);
231
248
  if (sleepFailure) return { failure: sleepFailure };
232
249
  }
250
+ if (addsUnmanagedWorktree(guarded.command)) return { failure: formatShellToolFailure(SHELL_WORKTREE_ADD_BLOCK) };
233
251
  const read = detectShellFileRead(guarded.command, shellType);
234
252
  if (read) {
235
253
  recordFileRead(telemetry, { mode: fileReadMode, tool: read.tool, command: read.command, agent, sessionId });
@@ -75,7 +75,7 @@ export function _finalizeShellResult(completedExit, text) {
75
75
 
76
76
  export function _shellFailureStatus(result, timeout) {
77
77
  // Prefer the signal reported by the process. `killed` is only a fallback
78
- // for platforms (notably taskkill on Windows) that close without one.
78
+ // for platforms (notably a Windows tree kill) that close without one.
79
79
  const signal = result.signal || (result.killed ? 'SIGKILL' : null);
80
80
  const exitCode = signal ? null : result.exitCode;
81
81
  const shellToolFailed = result.failurePhase === 'tool' || !!result.outputCaptureError;
@@ -0,0 +1,77 @@
1
+ // Whether a shell command mentions `git … worktree add`. A worktree added from
2
+ // the shell is invisible to the managed cleanup and outlives the session that
3
+ // made it, so the shell guard refuses it and points to the git tool.
4
+ //
5
+ // Deliberately textual, conservative and linear-time: no shell is parsed. The
6
+ // command is normalized once (escape and quote characters of every shell
7
+ // dropped, whitespace collapsed; a PowerShell -EncodedCommand decoded), then
8
+ // refused when `git` is followed anywhere later by `worktree … add`. Commands
9
+ // that only mention the phrase as data (echo, grep, a heredoc, a commit
10
+ // message) are refused too; the refusal says how to proceed.
11
+
12
+ const QUOTES = /['"\u2018\u2019\u201a\u201b\u201c\u201d\u201e]/g;
13
+ const GIT_WORD = /\bgit\b/i;
14
+ // `worktree` ending a token that is not an option: `worktree`, `$(worktree`, `alias.wa=worktree`.
15
+ const WORKTREE_TOKEN = /(?:^|[^\w-])worktree$/i;
16
+ const ADD_TOKEN = /^add\b/i;
17
+ // powershell/pwsh -EncodedCommand (any accepted prefix: -e, -ec, -enc, …) and its base64 argument.
18
+ const ENCODED_COMMAND = /(?:^|[\s'"])[-/]e(?:c|n[a-z]*)?\s+['"]?([A-Za-z0-9+/]{4,}={0,2})/gi;
19
+
20
+ /** The command with every shell's escapes and quotes dropped and whitespace collapsed.
21
+ * `joiner` replaces a line continuation: '' as POSIX joins `a\<newline>dd` into one
22
+ * word, ' ' where the continuation separates words. */
23
+ function normalize(text, joiner) {
24
+ return (
25
+ text
26
+ .replace(/[\\`]\r?\n/g, joiner)
27
+ // Hex escapes ($'\x61dd', "\x61dd").
28
+ .replace(/\\x([0-9a-fA-F]{2})/g, (_, hex) => String.fromCharCode(Number.parseInt(hex, 16)))
29
+ // The `$` of a POSIX $'…' / $"…" string.
30
+ .replace(/\$(?=['"])/g, '')
31
+ // PowerShell backtick and cmd caret escapes.
32
+ .replace(/[`^]/g, '')
33
+ .replace(QUOTES, '')
34
+ .replace(/\s+/g, ' ')
35
+ );
36
+ }
37
+
38
+ /** True when some `git` word comes before a `worktree … add` in `text`. One pass
39
+ * over the tokens: options (`-…`) between `worktree` and `add` are skipped and
40
+ * never start a match, so every token is visited once. */
41
+ function gitThenWorktreeAdd(text) {
42
+ const tokens = text.split(/[\s,]+/);
43
+ let gitSeen = false;
44
+ for (let i = 0; i < tokens.length; i += 1) {
45
+ const token = tokens[i];
46
+ if (!gitSeen) {
47
+ gitSeen = GIT_WORD.test(token);
48
+ continue;
49
+ }
50
+ if (token.startsWith('-') || !WORKTREE_TOKEN.test(token)) continue;
51
+ let next = i + 1;
52
+ while (next < tokens.length && tokens[next].startsWith('-')) next += 1;
53
+ if (next < tokens.length && ADD_TOKEN.test(tokens[next])) return true;
54
+ i = next - 1;
55
+ }
56
+ return false;
57
+ }
58
+
59
+ /** True when `command` would (or might) run `git … worktree add`. */
60
+ export function addsUnmanagedWorktree(command) {
61
+ const raw = String(command ?? '');
62
+ const texts = [raw];
63
+ for (const [, encoded] of raw.matchAll(ENCODED_COMMAND)) {
64
+ texts.push(Buffer.from(encoded, 'base64').toString('utf16le'));
65
+ }
66
+ return texts.some((text) =>
67
+ ['', ' '].some((joiner) => {
68
+ const normalized = normalize(text, joiner);
69
+ // A backslash is a POSIX escape (`a\dd` is `add`) or a Windows path separator
70
+ // (`C:\Git\cmd\git.exe`): both readings are checked.
71
+ return (
72
+ gitThenWorktreeAdd(normalized.replace(/\\(?=[A-Za-z])/g, '')) ||
73
+ gitThenWorktreeAdd(normalized.replaceAll('\\', '/'))
74
+ );
75
+ })
76
+ );
77
+ }
@@ -32,7 +32,6 @@ export {
32
32
  SURVIVING_DESCENDANTS_WARNING,
33
33
  SURVIVING_DESCENDANTS_UNREACHABLE_WARNING,
34
34
  _backgroundResultLines,
35
- getDedupedDestructiveWarnings,
36
35
  _placeDestructiveWarningsAfterStatus,
37
36
  formatShellToolFailure,
38
37
  _shellFailureStatus,
@@ -98,7 +98,7 @@ export const GIT_TOOL_DEF = {
98
98
  openWorldHint: true,
99
99
  compressible: true,
100
100
  },
101
- 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.`,
101
+ 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, and is the one add a delegated worker may run; list --porcelain stays raw git; move/lock/unlock/repair are refused). Merge or remove only when the user asks.`,
102
102
  inputSchema: {
103
103
  type: 'object',
104
104
  properties: {
@@ -144,7 +144,10 @@ export const GIT_TOOL_DEF = {
144
144
  description: 'enter/return/merge/remove: another session (it must be idle); default the caller.',
145
145
  },
146
146
  name: { type: 'string', description: 'enter: the new worktree name (branch <prefix><name>).' },
147
- branch: { type: 'string', description: 'enter: use the worktree of this branch instead.' },
147
+ branch: {
148
+ type: 'string',
149
+ description: "enter: use the worktree of this branch instead. remove: this session's worktree of that branch.",
150
+ },
148
151
  create: { type: 'boolean', description: 'enter with branch: create that branch.' },
149
152
  carry: {
150
153
  type: 'string',
@@ -580,7 +583,8 @@ function commandFailure(plan, result, limit = GIT_OUTPUT_LINES_DEFAULT) {
580
583
  function runGit(plan, argv, options = {}) {
581
584
  return startGit(
582
585
  gitToolEnvironment(!options.readOnly),
583
- (command, env) => runProcess(command, [...plan.globalArgs, ...argv], { cwd: plan.cwd, signal: options.signal, env }),
586
+ (command, env) =>
587
+ runProcess(command, [...plan.globalArgs, ...argv], { cwd: plan.cwd, signal: options.signal, env }),
584
588
  (result) => result.error
585
589
  );
586
590
  }
@@ -15,7 +15,9 @@
15
15
  *
16
16
  * Every operation but `list` belongs to the Lead: the session runtime that
17
17
  * hosts the caller registers its host (shared/worktrees/tool-host.mjs); a
18
- * caller no host claims (a delegated worker) is refused.
18
+ * caller no host claims (a delegated worker) is refused, except for a
19
+ * read-only `add --detach` snapshot held by its own session and removed when
20
+ * its turn settles (shared/worktrees/worker-snapshots.mjs).
19
21
  */
20
22
  import { basename, resolve } from 'node:path';
21
23
  import { isPlainObject } from '../../../../shared/object.mjs';
@@ -23,6 +25,7 @@ import { WORKTREE_REFUSAL_REASONS } from '../../../../shared/worktrees/contract.
23
25
  import { firstLine, listWorktrees, runGit } from '../../../../shared/worktrees/git.mjs';
24
26
  import { canonicalPath, samePath } from '../../../../shared/worktrees/paths.mjs';
25
27
  import { worktreeToolHost } from '../../../../shared/worktrees/tool-host.mjs';
28
+ import { createWorkerSnapshot } from '../../../../shared/worktrees/worker-snapshots.mjs';
26
29
 
27
30
  export const WORKTREE_TOOL_ACTIONS = Object.freeze(['enter', 'return', 'merge', 'remove', 'list', 'prune']);
28
31
  const CARRY_CHOICES = ['leave', 'carry'];
@@ -327,7 +330,12 @@ async function rawAdd(plan, input, options) {
327
330
  const [path, commitish = null] = positional;
328
331
  if (!path || positional.length > 2) throw new Error('git worktree add requires <path> [<commit-ish>]');
329
332
  if (detach && branch) throw new Error('git worktree add: --detach excludes -b/-B');
330
- const host = leadHost(options, 'git worktree add');
333
+ const host = worktreeToolHost(options?.sessionId);
334
+ if (!host && !detach) {
335
+ throw new Error(
336
+ 'git worktree add belongs to the Lead session; a delegated worker may only make a read-only snapshot: git worktree add --detach <path> [<commit>]'
337
+ );
338
+ }
331
339
  const repo = await repositoryAt(plan.cwd);
332
340
  if (!repo) throw new Error(`git worktree add: ${plan.cwd} is not a git repository`);
333
341
  const confirmLarge = input.confirm_large === true;
@@ -340,11 +348,16 @@ async function rawAdd(plan, input, options) {
340
348
  if (snapshotCommit) {
341
349
  const commit = await commitIn(plan.cwd, snapshotCommit);
342
350
  if (!commit) throw new Error(`git worktree add: ${snapshotCommit} is not a commit`);
343
- const entry = await runOn(
344
- host,
345
- { op: 'snapshot', commit, confirmLarge, txId, repoCommonDir: repo.repoCommonDir },
346
- options
347
- );
351
+ // A delegated worker's snapshot is held by its own session and removed when its turn settles.
352
+ const entry = host
353
+ ? await runOn(host, { op: 'snapshot', commit, confirmLarge, txId, repoCommonDir: repo.repoCommonDir }, options)
354
+ : await createWorkerSnapshot({
355
+ sessionId: options?.sessionId,
356
+ projectPath: plan.cwd,
357
+ commit,
358
+ txId,
359
+ confirmLarge,
360
+ });
348
361
  return okJson({
349
362
  ...mapped,
350
363
  snapshot: true,
@@ -512,7 +525,7 @@ function worktreeInputError(input) {
512
525
  const misplaced =
513
526
  only('session_id', ['enter', 'return', 'merge', 'remove']) ||
514
527
  only('name', ['enter']) ||
515
- only('branch', ['enter']) ||
528
+ only('branch', ['enter', 'remove']) ||
516
529
  only('create', ['enter']) ||
517
530
  only('carry', ['enter']) ||
518
531
  only('confirm_large', ['enter']) ||
@@ -529,6 +542,9 @@ function worktreeInputError(input) {
529
542
  return 'branch excludes name and carry (the branch names the worktree; changes stay in the project folder)';
530
543
  }
531
544
  if (input.carry !== undefined && !CARRY_CHOICES.includes(input.carry)) return 'carry must be leave or carry';
545
+ if (action === 'remove' && input.branch !== undefined && input.session_id !== undefined) {
546
+ return "branch names one of this session's own worktrees; it excludes session_id";
547
+ }
532
548
  return null;
533
549
  }
534
550
 
@@ -554,7 +570,9 @@ export async function executeWorktreeAction(input, workDir, options = {}) {
554
570
  confirmLarge: input.confirm_large === true,
555
571
  }
556
572
  : {}),
557
- ...(action === 'remove' ? { force: input.force === true } : {}),
573
+ ...(action === 'remove'
574
+ ? { force: input.force === true, ...(input.branch?.trim() ? { branch: input.branch.trim() } : {}) }
575
+ : {}),
558
576
  ...(action === 'prune'
559
577
  ? { repoCommonDir: (await repositoryAt(resolve(workDir || process.cwd())))?.repoCommonDir ?? null }
560
578
  : {}),
@@ -34,7 +34,7 @@ export function uniqueStrings(values) {
34
34
  return Array.from(new Set(values.filter((value) => typeof value === 'string' && value)));
35
35
  }
36
36
 
37
- export function coerceNonNegInt(value) {
37
+ function coerceNonNegInt(value) {
38
38
  if (value === undefined || value === null || value === '') return null;
39
39
  const n = Number(value);
40
40
  if (!Number.isFinite(n) || n < 0) return NaN;
@@ -49,7 +49,7 @@ export function stringList(value) {
49
49
 
50
50
  // head_limit shared by the single-path flow and the path[] fan-out:
51
51
  // absent → the default cap, 0 → unlimited, otherwise the coerced integer.
52
- export function resolveHeadLimit(coerced, defaultLimit) {
52
+ function resolveHeadLimit(coerced, defaultLimit) {
53
53
  if (coerced === null) return defaultLimit;
54
54
  return coerced === 0 ? Infinity : coerced;
55
55
  }
@@ -293,7 +293,7 @@ function requestReadRangeIndexPersist(key, job) {
293
293
  })();
294
294
  }
295
295
 
296
- export function scheduleReadRangeIndexPersist(index) {
296
+ function scheduleReadRangeIndexPersist(index) {
297
297
  if (!READ_RANGE_INDEX_DISK_DIR || !currentReadRangeIndex(index)) return;
298
298
  const key = canonicalCachePath(index.fullPath);
299
299
  const inflight = READ_RANGE_INDEX_INFLIGHT.get(key);
@@ -11,7 +11,6 @@ import { invalidateBuiltinResultCache } from './cache-layers.mjs';
11
11
  import { getReadSnapshot } from './read-snapshot-runtime.mjs';
12
12
  import { snapshotCoversFullFile, statMatchesSnapshot } from './snapshot-helpers.mjs';
13
13
  import { canCacheReadFile, READ_PREFIX_HASH_BYTES } from './read-cache-policy.mjs';
14
- export { READ_PREFIX_HASH_BYTES } from './read-cache-policy.mjs';
15
14
 
16
15
  // A mutation snapshot claims the full file because it knows the bytes it
17
16
  // wrote; it proves the session holds the body only when bodyDelivered says so.
@@ -1,12 +1,2 @@
1
- export {
2
- _suggestIndexedPaths,
3
- basePathDiagnostic,
4
- buildNotFoundHint,
5
- isUncOrSmbPath,
6
- relativePathPrefix,
7
- relativeSearchResultPath,
8
- resolveSearchScope,
9
- uncRefusalMessage,
10
- } from './search-path-diagnostics.mjs';
11
1
  export { executeGrepTool } from './search-grep-tool.mjs';
12
2
  export { executeGlobTool } from './search-glob-tool.mjs';
@@ -209,8 +209,7 @@ async function trackShellJobRecord(task, options) {
209
209
  // settle does. A killed one relies on the snapshot taken before the kill.
210
210
  const killed = entry.killed || detail.killed || detail.timedOut || String(detail.status) === 'cancelled';
211
211
  if (!killed) tracker.acceptExitObservation();
212
- const watched =
213
- contained && (killed || detail.treeOutcome === 'empty') ? containedJobTracker(jobId) : tracker;
212
+ const watched = contained && (killed || detail.treeOutcome === 'empty') ? containedJobTracker(jobId) : tracker;
214
213
  // The completion notice is already on its way (watchBackgroundShellJob);
215
214
  // the record — and with it the workspace admission — completes only once
216
215
  // every process is confirmed gone, or the user releases it explicitly.
@@ -97,30 +97,12 @@ import {
97
97
  streamSmartReadSummary as _streamSmartReadSummaryImpl,
98
98
  } from './builtin/read-streaming.mjs';
99
99
  export {
100
- coerceShapeFlex,
101
100
  normalizeInputPath,
102
101
  normalizeOutputPath,
103
- posixPathToWindowsPath,
104
102
  resolveAgainstCwd,
105
- toDisplayPath,
106
103
  } from './builtin/path-utils.mjs';
107
- export {
108
- buildGlobCacheKey,
109
- buildGrepCacheKey,
110
- buildGrepRgArgs,
111
- buildListCacheKey,
112
- } from './builtin/search-builders.mjs';
113
- export {
114
- analyzeShellCommandEffects,
115
- preflightShellLargeFileProbe,
116
- } from './builtin/shell-analysis.mjs';
117
- export { BUILTIN_TOOLS } from './builtin/builtin-tools.mjs';
118
104
  export { withBuiltinPathLocks } from './builtin/path-locks.mjs';
119
- export {
120
- getCachedReadOnlyStat,
121
- invalidateBuiltinResultCache,
122
- } from './builtin/cache-layers.mjs';
123
- export { atomicWrite } from './builtin/atomic-write.mjs';
105
+ export { invalidateBuiltinResultCache } from './builtin/cache-layers.mjs';
124
106
  // User-cwd persistence hook: writes user-cwd.txt on SessionStart so
125
107
  // the MCP server (spawned from cache dir) resolves the correct sandbox root.
126
108
  // Helper extracted to src/shared/user-cwd.mjs so server-main.mjs can import
@@ -616,8 +598,3 @@ export function clearReadSnapshotForPath(fullPath, _scope) {
616
598
  _deleteReadSnapshotPathEverywhere(fullPath);
617
599
  } catch {}
618
600
  }
619
-
620
- // Re-export from the side-effect-free code-graph definition source so callers that already import other
621
- // helpers from builtin.mjs (result-compression.mjs) can pick up the tool
622
- // def list from the same module without a parallel path.
623
- export { CODE_GRAPH_TOOL_DEFS } from './code-graph-tool-defs.mjs';
@@ -1,6 +1,7 @@
1
1
  // Kill escalation for a spawned native child: SIGTERM first, then after a
2
- // grace period a forced kill (taskkill /t /f on Windows, SIGKILL elsewhere).
3
- import { spawn } from 'node:child_process';
2
+ // grace period a forced kill (the shared creation-checked tree kill on
3
+ // Windows, SIGKILL elsewhere).
4
+ import { spawnTreeKill } from '../../../mcp/child-tree.mjs';
4
5
 
5
6
  const KILL_GRACE_MS = 3000;
6
7
 
@@ -14,7 +15,7 @@ export function createChildKiller(proc) {
14
15
  if (!pid) return;
15
16
  try {
16
17
  if (process.platform === 'win32') {
17
- spawn('taskkill', ['/pid', String(pid), '/t', '/f'], { windowsHide: true, stdio: 'ignore' });
18
+ spawnTreeKill([pid], { root: proc });
18
19
  } else {
19
20
  try {
20
21
  proc.kill('SIGKILL');
@@ -23,8 +23,7 @@ function _graphBinaryPath() {
23
23
  const moduleDir = dirname(fileURLToPath(import.meta.url));
24
24
  const binName = process.platform === 'win32' ? 'mixdog-graph.exe' : 'mixdog-graph';
25
25
  // Prefer a local cargo build, then a previously fetched/cached prebuilt.
26
- // This module is one dir deeper than the legacy code-graph.mjs, so the
27
- // relative walk to repo-root native/ needs six `../` hops
26
+ // The relative walk to repo-root native/ needs six `../` hops
28
27
  // (code-graph → tools → orchestrator → agent → runtime → src → root).
29
28
  const localBuild = pathResolve(moduleDir, '../../../../../../native/mixdog-graph/target/release', binName);
30
29
  if (existsSync(localBuild)) return localBuild;
@@ -128,7 +128,7 @@ export async function callers(ctx) {
128
128
  const depth = Math.max(1, Math.min(5, Math.floor(Number(args?.depth) || 1)));
129
129
  if (depth > 1) {
130
130
  // Scope and limit are honoured at every level: a file/directory anchor
131
- // and an explicit limit used to be dropped for depth>1.
131
+ // and an explicit limit apply for depth>1 too.
132
132
  return _formatTransitiveCallers(graph, symbol, cwd, {
133
133
  language: lang,
134
134
  depth,
@@ -132,8 +132,8 @@ export async function symbolSearch(ctx) {
132
132
  if (!keywords.length) throw new Error('code_graph symbol_search: "symbol" (or "symbols[]") is required.');
133
133
  // Native graph symbols answer without source text at all: nodes without
134
134
  // them have no keyword matches to contribute, so nothing is read here.
135
- // Honour the file/directory anchor: symbol_search used to scan the whole
136
- // graph even when the caller scoped the call.
135
+ // Honour the file/directory anchor: a scoped symbol_search must not scan
136
+ // the whole graph.
137
137
  if (rel && !node) return fileNotFound('symbol_search', ctx);
138
138
  const search = (kw) => _searchSymbolsByKeyword(graph, kw, cwd, { language, limit, fileRel: rel, scopeRelPrefix });
139
139
  if (keywords.length === 1) return search(keywords[0]);
@@ -407,12 +407,11 @@ export function _findSymbolHits(graph, symbol, { language = null } = {}) {
407
407
  return _findSymbolHitsOnNodes(graph, cleanSymbol, candidateNodes, { language });
408
408
  }
409
409
 
410
- // Declarations come from the native record ONLY. The regex declaration
411
- // matchers that used to run for files without symbols are gone: they marked
410
+ // Declarations come from the native record ONLY. A regex fallback would mark
412
411
  // `declarationLike` on lines the extractor never called a declaration, so the
413
- // hit ranking (and, through it, the caller/callee anchors) depended on which
414
- // path produced the hit. A file with no symbols still yields reference hits —
415
- // it just declares nothing.
412
+ // hit ranking (and, through it, the caller/callee anchors) would depend on
413
+ // which path produced the hit. A file with no symbols still yields reference
414
+ // hits — it just declares nothing.
416
415
  function _findSymbolHitsOnNodes(graph, cleanSymbol, candidateNodes, { language = null } = {}) {
417
416
  if (!cleanSymbol) return [];
418
417
  const escaped = _escapeRegExp(cleanSymbol);
@@ -5,10 +5,9 @@
5
5
  // Symbols and tokens have NO text fallback. `node.symbols` (record v2:
6
6
  // {name, kind, startLine, endLine, startCol, endCol, exported?, sig?, parent?})
7
7
  // and `node.tokenSymbols` are the only sources; a node that carries neither
8
- // contributes nothing to an outline or a candidate set. The cheap regex outline
9
- // matchers and the JS identifier re-tokenizer that used to stand in for them
10
- // are gone — they disagreed with the extractor, so an answer's content depended
11
- // on which of the two produced it.
8
+ // contributes nothing to an outline or a candidate set. A regex outline or JS
9
+ // identifier re-tokenizer would disagree with the extractor, so an answer's
10
+ // content would depend on which of the two produced it.
12
11
  import { _langUsesDollarInIdentifiers, _langAllowsBangQuestionSuffix } from './lang-predicates.mjs';
13
12
  import { EXTRACTION_SYMBOL_LANGS } from './constants.mjs';
14
13
  import { _getSourceTextForNode, _graphRel } from './source-access.mjs';
@@ -4,35 +4,17 @@
4
4
  // build, search, dispatch).
5
5
  //
6
6
  // Public surface:
7
- // markCodeGraphDirtyPaths, CODE_GRAPH_TOOL_DEFS,
8
- // _pruneCodeGraphMemoryCache, _pruneCodeGraphManifestForBudget,
9
- // drainCodeGraphCache, prewarmCodeGraph, prewarmCodeGraphSymbols,
10
- // prewarmCodeGraphIfProject, buildCodeGraphAsync, _lookupCandidateNodes,
11
- // _buildCodeGraph and _postCodeGraphWorkerSuccess (worker-only),
12
- // executeCodeGraphTool, isCodeGraphTool.
7
+ // prewarmCodeGraphIfProject (read through the lazy module namespace in
8
+ // session-runtime/prewarm), _buildCodeGraph and _postCodeGraphWorkerSuccess
9
+ // (worker-only), executeCodeGraphTool.
13
10
  //
14
11
  // NOTE: code-graph-prewarm-worker.mjs imports { _buildCodeGraph } from THIS
15
12
  // facade; the facade re-exports it from ./code-graph/build.mjs, and the async
16
13
  // build path spawns that worker via a path RELATIVE to build.mjs — so no
17
14
  // module dynamically imports its own path.
18
- export { markCodeGraphDirtyPaths } from './code-graph-state.mjs';
19
- export { CODE_GRAPH_TOOL_DEFS } from './code-graph-tool-defs.mjs';
20
-
21
- export { _pruneCodeGraphMemoryCache } from './code-graph/memory-cache.mjs';
22
15
  export {
23
- _pruneCodeGraphManifestForBudget,
24
- drainCodeGraphCache,
25
- } from './code-graph/disk-cache.mjs';
26
- export { _lookupCandidateNodes } from './code-graph/symbol-index.mjs';
27
- export {
28
- prewarmCodeGraph,
29
- prewarmCodeGraphSymbols,
30
16
  prewarmCodeGraphIfProject,
31
- buildCodeGraphAsync,
32
17
  _buildCodeGraph,
33
18
  _postCodeGraphWorkerSuccess,
34
19
  } from './code-graph/build.mjs';
35
- export {
36
- executeCodeGraphTool,
37
- isCodeGraphTool,
38
- } from './code-graph/dispatch.mjs';
20
+ export { executeCodeGraphTool } from './code-graph/dispatch.mjs';
@@ -242,8 +242,8 @@ export function createContainedTreeTracker({ outcome, cancel }) {
242
242
  * excepted: they are witnesses, never workers). These are processes of a tree
243
243
  * that was KILLED — they escaped its process group (setsid, job control, a
244
244
  * double fork that kept its parent link) or outlived the root on Windows —
245
- * so the kill is not finished while they run. Windows: taskkill /T /F;
246
- * POSIX: SIGTERM, then SIGKILL after a short grace. */
245
+ * so the kill is not finished while they run. Windows: taskkill /F of each
246
+ * and its descendants; POSIX: SIGTERM, then SIGKILL after a short grace. */
247
247
  export function sweepLiveIdentities(tracker) {
248
248
  const targets = tracker.live
249
249
  .filter((entry) => entry.token != null && !CONSOLE_HOST.test(entry.name))
@@ -58,7 +58,7 @@ export function registerForegroundOwnedTree(run, ownerSessionId) {
58
58
  }
59
59
 
60
60
  // Treekill + exit confirmation. treeKill alone leaves settle() pending on
61
- // 'close'/'exit'; on Windows a taskkill miss or a grandchild holding stdio
61
+ // 'close'/'exit'; on Windows a missed tree kill or a grandchild holding stdio
62
62
  // fds keeps the dispatch stalled until the upstream ceiling. Covers every
63
63
  // kill path (timeout / pre-aborted / abort / capture-error / size-watchdog)
64
64
  // so the hang risk does not live on outside the timeout branch.
@@ -21,10 +21,6 @@ import { spawnShellChild } from './lib/shell-run-spawn.mjs';
21
21
  import { createPromotedCaptureRelease, createSettle } from './lib/shell-run-settle.mjs';
22
22
  import { _abortReasonIsInterrupt, createAutoBackground } from './lib/shell-run-background.mjs';
23
23
 
24
- export {
25
- _maybeEncodePowerShellCommand,
26
- extractPowerShellCommandInner,
27
- } from './shell-powershell.mjs';
28
24
  export { stripAnsi, ExecResult } from './shell-exec-output.mjs';
29
25
 
30
26
  async function _execPolicyBlockMessage(command, elevationApproved = false) {
@@ -1,5 +1,4 @@
1
1
  import { isDangerousDeleteTarget as _isDangerousDeleteTarget } from './shell-policy-danger-target.mjs';
2
- export { isDangerousDeleteTarget } from './shell-policy-danger-target.mjs';
3
2
  // Shell execution security policy — shared constants used by both
4
3
  // destructive-warning.mjs (heuristic classifier) and the shell command
5
4
  // runner (hard block list).