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
@@ -29,6 +29,7 @@ import { workerStageForStatus } from '../worker-rows.mjs';
29
29
  import { handoffContent } from '../../../handoff-attachments.mjs';
30
30
  import { whileTurnDispatched } from '../../../../runtime/agent/orchestrator/session/manager/runtime-state.mjs';
31
31
  import { takeStoppedShellJobs } from '../../../../runtime/agent/orchestrator/session/manager/turn-reap.mjs';
32
+ import { turnReportText } from '../../../../runtime/agent/orchestrator/session/loop/turn-report.mjs';
32
33
 
33
34
  // Mid-turn worker persistence cadence. The watchdog sweep runs every second;
34
35
  // a transcript save is far more expensive than a bookkeeping stamp, so the
@@ -114,7 +115,7 @@ export function createSpawnRunner({
114
115
  tag,
115
116
  sessionId: session.id,
116
117
  ...presetDescriptor(agent, preset, presetName),
117
- content: result?.content || '',
118
+ content: turnReportText(result),
118
119
  ...(sessionSurface?.canonical === true ? { handoffOnly: true } : {}),
119
120
  ...(abnormalError ? { error: abnormalError } : {}),
120
121
  };
@@ -124,11 +125,24 @@ export function createSpawnRunner({
124
125
  const { args, session, workerCwd } = prepared;
125
126
  // The caller's forwarded files ride along as attachment parts.
126
127
  const prompt = handoffContent(prepared.prompt, args.attachmentParts);
128
+ // Host-set only (a routine executor, routine-executor.mjs): the trusted
129
+ // text skills are selected from, so nothing else in the prompt selects one.
130
+ const selection = typeof args.skillSelection === 'string' ? { skillSelection: args.skillSelection } : {};
127
131
  return whileTurnDispatched(session.id, () => {
128
132
  if (typeof sessionSurface?.runTurn === 'function' && sessionSurface.canRun?.(session) !== false) {
129
- return sessionSurface.runTurn({ session, prompt, context: args.context || null, cwd: workerCwd, ...turnHooks });
133
+ return sessionSurface.runTurn({
134
+ session,
135
+ prompt,
136
+ context: args.context || null,
137
+ cwd: workerCwd,
138
+ ...selection,
139
+ ...turnHooks,
140
+ });
130
141
  }
131
- return mgr.askSession(session.id, prompt, args.context || null, null, workerCwd, null, turnHooks);
142
+ return mgr.askSession(session.id, prompt, args.context || null, null, workerCwd, null, {
143
+ ...turnHooks,
144
+ ...selection,
145
+ });
132
146
  });
133
147
  }
134
148
 
@@ -180,8 +194,8 @@ export function createSpawnRunner({
180
194
  : {}),
181
195
  };
182
196
  const result = await runTurn(prepared, turnHooks);
183
- // The early preview no longer promises body suppression, so the canonical
184
- // notifyTaskCompletion is left to fire exactly once with output via the
197
+ // The early preview does not promise body suppression, so the canonical
198
+ // notifyTaskCompletion fires exactly once with output via the
185
199
  // resolve/reconcile/finally path.
186
200
  const finalValue = completionValue(result);
187
201
  if (job?.status === 'cancelled') {
@@ -220,7 +234,11 @@ export function createSpawnRunner({
220
234
  }
221
235
  finalStatus = 'error';
222
236
  noteStoppedShellJobsOnError(error, await takeStoppedShellJobs(session.id));
223
- reconcileJobStreamStalled(job, error);
237
+ reconcileJobStreamStalled(job, error, {
238
+ tag,
239
+ sessionId: session.id,
240
+ ...presetDescriptor(agent, preset, presetName),
241
+ });
224
242
  throw error;
225
243
  } finally {
226
244
  turnReview.complete();
@@ -2,7 +2,15 @@ import { dirname, resolve } from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { ensureProcessListenerHeadroom } from '../../runtime/shared/process-listener-headroom.mjs';
4
4
  import { AGENT_TOOL } from './agent-tool/tool-def.mjs';
5
- import { agentScope, envTimeoutMs, callerSessionForContext, terminalPidForContext } from './agent-tool/helpers.mjs';
5
+ import { cancelBackgroundTask } from '../../runtime/shared/background-tasks.mjs';
6
+ import { closeManagedSession } from '../lifecycle/shared.mjs';
7
+ import {
8
+ agentScope,
9
+ clean,
10
+ envTimeoutMs,
11
+ callerSessionForContext,
12
+ terminalPidForContext,
13
+ } from './agent-tool/helpers.mjs';
6
14
  import { createTagRegistry } from './agent-tool/tag-registry.mjs';
7
15
  import { createJobViews } from './agent-tool/job-views.mjs';
8
16
  import { liveAgentStatusRow } from './agent-tool/job-views/session-progress.mjs';
@@ -106,6 +114,9 @@ export function createStandaloneAgent({
106
114
  });
107
115
  const sendFlow = createSendFlow({
108
116
  mgr,
117
+ cfgMod,
118
+ dataDir,
119
+ STANDALONE_SOURCE_ROOT,
109
120
  defaultCwd,
110
121
  sessionSurface,
111
122
  canUseSessionSurface,
@@ -129,6 +140,44 @@ export function createStandaloneAgent({
129
140
  listProviderModels,
130
141
  });
131
142
 
143
+ /**
144
+ * Run one workflow agent (`args.agent`, `args.prompt`, optional `cwd` and
145
+ * `attachmentParts`) to completion and resolve `{ sessionId, content }` —
146
+ * for a caller that has no session to hand the result to (a routine's
147
+ * executor, routine-executor.mjs). `context.callerSessionId` is the id the
148
+ * agent is created under: its run stamp and unattended policy come from it.
149
+ * Rejects when the agent fails or is cancelled, or `signal` aborts (which
150
+ * cancels it). The agent's session is closed afterwards.
151
+ */
152
+ async function runToCompletion(args = {}, context = {}, { signal = null } = {}) {
153
+ await awaitKeychainPrewarm();
154
+ const abortError = () =>
155
+ signal?.reason instanceof Error ? signal.reason : new Error(String(signal?.reason || 'agent run aborted'));
156
+ if (signal?.aborted) throw abortError();
157
+ const job = spawnFlow.startDeferredSpawnJob({ ...args, type: 'spawn' }, clean(context.callerCwd), context, context);
158
+ const onAbort = () => cancelBackgroundTask(job.taskId, 'agent run aborted', { notify: false });
159
+ signal?.addEventListener?.('abort', onAbort, { once: true });
160
+ let value = null;
161
+ try {
162
+ value = await job.promise;
163
+ } finally {
164
+ signal?.removeEventListener?.('abort', onAbort);
165
+ }
166
+ const sessionId = clean(job.meta?.sessionId) || clean(value?.sessionId);
167
+ if (sessionId) {
168
+ try {
169
+ await closeManagedSession(mgr, sessionId, 'routine-executor-finished');
170
+ } catch {
171
+ /* the run's result stands; a close that fails is swept with idle agents */
172
+ }
173
+ }
174
+ if (signal?.aborted) throw abortError();
175
+ if (job.status === 'cancelled') throw new Error('the agent run was cancelled');
176
+ if (job.status !== 'completed') throw new Error(job.error || 'the agent run failed');
177
+ const result = value ?? job.result;
178
+ return { sessionId: sessionId || null, content: String(result?.content ?? '') };
179
+ }
180
+
132
181
  function getStatus(context = {}) {
133
182
  if (!isKeychainPrewarmReady()) {
134
183
  void awaitKeychainPrewarm();
@@ -162,6 +211,7 @@ export function createStandaloneAgent({
162
211
  return {
163
212
  tools: [AGENT_TOOL],
164
213
  execute,
214
+ runToCompletion,
165
215
  onStatusChange: (listener) => {
166
216
  if (typeof listener !== 'function') return () => {};
167
217
  statusListeners.add(listener);
@@ -25,6 +25,7 @@ import {
25
25
  } from '../../runtime/channels/lib/webhooks-db.mjs';
26
26
  import { normalizeAutomationAttachments } from '../../runtime/shared/automation-attachments.mjs';
27
27
  import { assertRoutineOwner, routineOwnerProblem } from '../routine-owner.mjs';
28
+ import { assertRoutineExecutor } from '../routine-executor.mjs';
28
29
  import { hasEnabledAutomation } from '../../runtime/shared/automation-presence.mjs';
29
30
  import { resolveScheduleTimezone, validateScheduleCron } from '../../runtime/shared/schedule-time.mjs';
30
31
  import { scheduleNameTakenError, scheduleRenameRunningError } from '../../runtime/channels/lib/schedule-errors.mjs';
@@ -203,6 +204,8 @@ function scheduleToDisplay(s, ownerProblem = '') {
203
204
  instructions: s.prompt,
204
205
  // The bot it belongs to: each run is a turn in that bot's chat.
205
206
  owner: s.ownerAgentId || MIXY_AGENT_ID,
207
+ // The sub-agent that carries each fire out first (routine-executor.mjs); null = the bot itself.
208
+ executorAgentId: s.executorAgentId || null,
206
209
  // Why it is paused for its owner (routine-owner.mjs); absent when it runs.
207
210
  ...(ownerProblem ? { ownerProblem } : {}),
208
211
  nextFireAt: isoOrUndefined(s.nextFireAt),
@@ -250,6 +253,13 @@ function scheduleOwner(owner, existing) {
250
253
  return existing?.ownerAgentId || MIXY_AGENT_ID;
251
254
  }
252
255
 
256
+ // A save's executor: `executorAgentId` undefined keeps the saved one on an
257
+ // overwrite; null or '' clears it; an id must be a delegatable sub-agent.
258
+ async function routineExecutor(executorAgentId, existing) {
259
+ if (executorAgentId === undefined) return existing?.executorAgentId || null;
260
+ return assertRoutineExecutor(executorAgentId);
261
+ }
262
+
253
263
  /** Each owner's problem (routine-owner.mjs) for its stored rows, probed once
254
264
  * per owner. */
255
265
  function ownerProblems() {
@@ -319,6 +329,7 @@ export async function saveSchedule(
319
329
  enabled,
320
330
  instructions,
321
331
  owner,
332
+ executorAgentId,
322
333
  overwrite = false,
323
334
  newName,
324
335
  } = {},
@@ -340,6 +351,7 @@ export async function saveSchedule(
340
351
  }
341
352
  const ownerAgentId = scheduleOwner(owner, existing);
342
353
  await assertRoutineOwner(ownerAgentId);
354
+ const executor = await routineExecutor(executorAgentId, existing);
343
355
  const whenCron = hasTime ? validateScheduleCron(foldDaysIntoCron(normalizeCron(time), days)) : null;
344
356
  const whenAt = hasAt ? parseAtDatetime(at) : null;
345
357
  const scheduleTimezone = hasTime ? resolveScheduleTimezone(timezone) : null;
@@ -356,6 +368,7 @@ export async function saveSchedule(
356
368
  enabled: enabled !== false,
357
369
  nextFireAt: whenAt,
358
370
  ownerAgentId,
371
+ executorAgentId: executor,
359
372
  };
360
373
  let saved;
361
374
  if (renaming) {
@@ -407,6 +420,7 @@ async function listWebhooks() {
407
420
  instructions: ep.instructions,
408
421
  // The bot it belongs to: each run is a turn in that bot's chat.
409
422
  owner: ep.ownerAgentId || MIXY_AGENT_ID,
423
+ executorAgentId: ep.executorAgentId || null,
410
424
  ...(problems[index] ? { ownerProblem: problems[index] } : {}),
411
425
  lastEventAt: isoOrUndefined(ep.lastEventAt),
412
426
  lastSuccessAt: isoOrUndefined(ep.lastSuccessAt),
@@ -428,6 +442,7 @@ export async function saveWebhook({
428
442
  enabled,
429
443
  instructions,
430
444
  owner,
445
+ executorAgentId,
431
446
  overwrite = false,
432
447
  } = {}) {
433
448
  const id = assertName(name, 'webhook name');
@@ -445,6 +460,7 @@ export async function saveWebhook({
445
460
  }
446
461
  const ownerAgentId = scheduleOwner(owner, existing);
447
462
  await assertRoutineOwner(ownerAgentId);
463
+ const executor = await routineExecutor(executorAgentId, existing);
448
464
  // Secret semantics: an explicit value always wins; an EMPTY value on an
449
465
  // overwrite PRESERVES the stored secret (editing instructions must not
450
466
  // silently rotate the key the external service was configured with); only
@@ -464,11 +480,13 @@ export async function saveWebhook({
464
480
  instructions: body,
465
481
  enabled: enabled !== false,
466
482
  ownerAgentId,
483
+ executorAgentId: executor,
467
484
  });
468
485
  automationProbe.invalidate();
469
486
  return {
470
487
  name: id,
471
488
  owner: saved.ownerAgentId || ownerAgentId,
489
+ executorAgentId: saved.executorAgentId || null,
472
490
  description: saved.description,
473
491
  parser: saved.parser,
474
492
  ...(saved.cwd ? { cwd: saved.cwd } : {}),
@@ -1,9 +1,10 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { spawn, spawnSync } from 'node:child_process';
2
+ import { spawn } from 'node:child_process';
3
3
  import { MAX_BUFFER_BYTES } from './constants.mjs';
4
4
  import { handlerTimeoutS } from './handler-timeout.mjs';
5
5
  import { abortReason, throwIfAborted } from '../../../runtime/shared/abort-race.mjs';
6
6
  import { scrubRuntimeRootVars } from '../../../runtime/agent/orchestrator/tools/env-scrub.mjs';
7
+ import { spawnTreeKill } from '../../../runtime/agent/orchestrator/mcp/child-tree.mjs';
7
8
 
8
9
  function resolvePlaceholders(str, projectDir, pluginData, pluginRoot = null) {
9
10
  if (typeof str !== 'string') return str;
@@ -23,17 +24,13 @@ export function defaultShellKind() {
23
24
  return process.platform === 'win32' ? 'powershell' : 'bash';
24
25
  }
25
26
 
26
- // POSIX children share a detached process group; Windows taskkill owns the tree.
27
+ // POSIX children share a detached process group; on Windows the shared
28
+ // creation-checked tree kill owns the tree, off the event loop.
27
29
  function killProcessTree(child, signal = 'SIGTERM') {
28
30
  if (!child || child.pid == null) return;
29
31
  if (process.platform === 'win32') {
30
- try {
31
- spawnSync('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true });
32
- } catch {
33
- try {
34
- child.kill(signal);
35
- } catch {}
36
- }
32
+ if (child.exitCode !== null || child.signalCode !== null) return;
33
+ spawnTreeKill([child.pid], { root: child });
37
34
  return;
38
35
  }
39
36
  try {
@@ -48,8 +45,7 @@ function killProcessTree(child, signal = 'SIGTERM') {
48
45
  const KILL_GRACE_MS = 2000;
49
46
  function terminateTree(child) {
50
47
  killProcessTree(child, 'SIGTERM');
51
- // /F is already a hard termination. A later Windows retry could address a
52
- // recycled PID instead of the process this handler created.
48
+ // The Windows tree kill is already a hard termination.
53
49
  if (process.platform === 'win32') return;
54
50
  const timer = setTimeout(() => killProcessTree(child, 'SIGKILL'), KILL_GRACE_MS);
55
51
  timer.unref?.();
@@ -4,6 +4,7 @@ import { basename, dirname, join, resolve } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
5
  import { createHash, randomUUID } from 'node:crypto';
6
6
  import { readJsonStateSync, updateJsonAtomicSync, withFileLockSync } from '../../runtime/shared/atomic-file.mjs';
7
+ import { announceStoredStateChange } from '../../runtime/shared/config.mjs';
7
8
  import { resolvePluginData } from '../../runtime/shared/plugin-paths.mjs';
8
9
  import { pluginManifest } from '../../runtime/shared/plugin-manifest.mjs';
9
10
  import { pluginMetadata } from '../../runtime/shared/plugin-metadata.mjs';
@@ -60,6 +61,9 @@ function mutateRegistry(dataDir, mutator) {
60
61
  },
61
62
  { secret: true, fsyncDir: true, backup: true }
62
63
  );
64
+ // Other processes connect or drop the plugin's MCP servers on this (the
65
+ // live install's registry only; an explicit dataDir is a separate store).
66
+ if (resolve(dataDir) === resolve(resolvePluginData())) announceStoredStateChange('plugins');
63
67
  return result;
64
68
  }
65
69
 
@@ -127,6 +127,13 @@ export function retireSeededPackCopies({ rootDir, dataDir, backup = makeBackup(d
127
127
  if (![bundled, ...(history.outputStyles[name] || [])].includes(fileHash(copy))) continue;
128
128
  if (backup.move(copy)) retired.push(`output-styles/${name}`);
129
129
  }
130
+ for (const name of childNames(join(dataDir, 'orchestration'), 'md')) {
131
+ const bundled = fileHash(join(rootDir, 'orchestration', name));
132
+ if (!bundled) continue;
133
+ const copy = join(dataDir, 'orchestration', name);
134
+ if (![bundled, ...(history.orchestration[name] || [])].includes(fileHash(copy))) continue;
135
+ if (backup.move(copy)) retired.push(`orchestration/${name}`);
136
+ }
130
137
  return retired;
131
138
  }
132
139
 
@@ -24,8 +24,11 @@
24
24
  import { billableInputTokensForProvider } from '../../runtime/shared/llm/cost.mjs';
25
25
  import { hourlySeries } from './usage-stats-hours.mjs';
26
26
  import {
27
+ FAST_KEY,
27
28
  isConversationUsageSource,
29
+ isFastCall,
28
30
  knownCostTurns,
31
+ sortFastBesideModel,
29
32
  usageRollupDayKey,
30
33
  } from '../../runtime/shared/llm/usage-rollup.mjs';
31
34
 
@@ -132,11 +135,14 @@ function providerBucket(state, provider, kind) {
132
135
  return bucket;
133
136
  }
134
137
 
135
- function modelBucket(provider, model) {
136
- let bucket = provider.models.get(model);
138
+ // A model's Fast-mode calls are their own row beside its normal row.
139
+ function modelBucket(provider, model, fast = false) {
140
+ const key = fast ? model + FAST_KEY : model;
141
+ let bucket = provider.models.get(key);
137
142
  if (!bucket) {
138
143
  bucket = {
139
144
  model,
145
+ fast,
140
146
  turns: 0,
141
147
  input: 0,
142
148
  output: 0,
@@ -146,7 +152,7 @@ function modelBucket(provider, model) {
146
152
  sessions: new Set(),
147
153
  sessionsComplete: true,
148
154
  };
149
- provider.models.set(model, bucket);
155
+ provider.models.set(key, bucket);
150
156
  }
151
157
  return bucket;
152
158
  }
@@ -166,9 +172,9 @@ function addUsage(target, usage) {
166
172
  target.speedMs = (target.speedMs || 0) + (usage.speedMs || 0);
167
173
  }
168
174
 
169
- function foldRoute(state, providerId, modelId, kind, usage) {
175
+ function foldRoute(state, providerId, modelId, kind, usage, fast = false) {
170
176
  const provider = providerBucket(state, providerId, kind);
171
- const model = modelBucket(provider, modelId);
177
+ const model = modelBucket(provider, modelId, fast);
172
178
  for (const bucket of [provider, model]) {
173
179
  addUsage(bucket, usage);
174
180
  if (usage.turns > 0 && (!usage.sessions || usage.sessionsComplete === false)) {
@@ -258,7 +264,7 @@ function foldRollupDay(state, key, day, conversationOnly) {
258
264
  speedOutput: num(raw?.speedOutput),
259
265
  speedMs: num(raw?.speedMs),
260
266
  };
261
- foldRoute(state, providerId, modelId, text(raw?.kind), usage);
267
+ foldRoute(state, providerId, modelId, text(raw?.kind), usage, raw?.fast === true);
262
268
  addDaily(state, key, usage, providerId);
263
269
  }
264
270
 
@@ -313,7 +319,14 @@ function foldEvent(state, key, event, conversationOnly) {
313
319
  speedOutput: timed ? output : 0,
314
320
  speedMs: timed ? durationMs : 0,
315
321
  };
316
- foldRoute(state, providerId, modelId, text(event?.providerKind), usage);
322
+ // Tiers are kept on the record's rates (see makeUsageRecord), not top level.
323
+ const kind = text(event?.providerKind);
324
+ const fast = isFastCall({
325
+ kind,
326
+ requestServiceTier: event?.rates?.requestServiceTier,
327
+ serviceTier: event?.rates?.serviceTier,
328
+ });
329
+ foldRoute(state, providerId, modelId, kind, usage, fast);
317
330
  addDaily(state, key, usage, providerId);
318
331
 
319
332
  if (durationMs > 0) {
@@ -513,9 +526,12 @@ function exportRoute(bucket, totalTokens) {
513
526
  function exportProviders(state, { totalTokens, modelLimit }) {
514
527
  return [...state.providers.values()]
515
528
  .map((bucket) => {
516
- const models = [...bucket.models.values()]
517
- .map((model) => ({ model: model.model, ...exportRoute(model, totalTokens) }))
518
- .sort((a, b) => b.tokens - a.tokens || b.costUsd - a.costUsd);
529
+ const exported = [...bucket.models.values()].map((model) => ({
530
+ model: model.model,
531
+ ...(model.fast ? { fast: true } : {}),
532
+ ...exportRoute(model, totalTokens),
533
+ }));
534
+ const models = sortFastBesideModel(exported, (row) => row.model, ['tokens', 'costUsd']);
519
535
  return {
520
536
  provider: bucket.provider,
521
537
  providerKind: bucket.providerKind,
@@ -535,7 +551,12 @@ function exportUnpricedModels(state) {
535
551
  const rows = [];
536
552
  for (const provider of state.providers.values()) {
537
553
  for (const model of provider.models.values()) {
538
- if (model.turns > 0 && model.costKnownTurns < model.turns)
554
+ // A model's Fast bucket is the same identity as its normal one.
555
+ if (
556
+ model.turns > 0 &&
557
+ model.costKnownTurns < model.turns &&
558
+ !rows.some((row) => row.provider === provider.provider && row.model === model.model)
559
+ )
539
560
  rows.push({ provider: provider.provider, model: model.model });
540
561
  }
541
562
  }
@@ -12,7 +12,7 @@ import { sessionOptions } from './session-options.mjs';
12
12
  * time. A boot connect still mid-handshake is caught on the first user
13
13
  * turn by refreshInitialDeferredMcpSurface (session-turn-api), which
14
14
  * re-folds the live registry before the prompt renders. */
15
- function seedToolSurface(deps, reason) {
15
+ function seedToolSurface(deps, reason, coreMemoryContext) {
16
16
  const { rt, mcpClient, modelStandaloneTools, applyPreSessionToolSelection } = deps;
17
17
  let connectedMcpTools = [];
18
18
  try {
@@ -37,6 +37,8 @@ function seedToolSurface(deps, reason) {
37
37
  // process-wide firstTurnCompleted.
38
38
  rt.session.deferredInitialRefreshPending = !/resume/i.test(String(reason || ''));
39
39
  applyPreSessionToolSelection();
40
+ // Built from the settings as they stand: its first turn need not rebuild it.
41
+ deps.noteToolAvailability?.(rt.session, coreMemoryContext);
40
42
  }
41
43
 
42
44
  /** Adopt the provider session and publish it to hooks and statusline. */
@@ -45,7 +47,7 @@ export function materializeSession(deps, reason, coreMemoryContext) {
45
47
  // adoptSession attaches the hook bridge (boot/infrastructure.mjs sessionAdopter).
46
48
  adoptSession(mgr.createSession(sessionOptions(deps, coreMemoryContext)));
47
49
  rt.reservedSessionId = null;
48
- seedToolSurface(deps, reason);
50
+ seedToolSurface(deps, reason, coreMemoryContext);
49
51
  writeStatuslineRoute(statusRoutes, rt.session, rt.route);
50
52
  hooks.emit('session:create', {
51
53
  sessionId: rt.session.id,
@@ -111,6 +111,8 @@ export function sessionOptions(deps, coreMemoryContext) {
111
111
  cwd: rt.currentCwd,
112
112
  ...(rt.desktopSession && typeof rt.desktopSession === 'object' ? { desktopSession: rt.desktopSession } : {}),
113
113
  coreMemoryContext,
114
+ // Prompt settings from the in-memory config (its disk copy trails it).
115
+ promptConfig: rt.config,
114
116
  workflow,
115
117
  workflowContext,
116
118
  ...(leadWorkflowParts ? { leadWorkflowParts } : {}),
@@ -67,7 +67,6 @@ export function createBuiltinToolSettings(
67
67
  webSearchEnabled,
68
68
  invalidateContextStatusCache,
69
69
  invalidatePreSessionToolSurface,
70
- refreshEmptySessionToolPolicy,
71
70
  },
72
71
  localSettings
73
72
  ) {
@@ -201,19 +200,15 @@ export function createBuiltinToolSettings(
201
200
  async setWebSearchEnabled(enabled) {
202
201
  const config = getConfig();
203
202
  saveConfigAndAdopt(setModuleEnabledInConfig({ ...config }, 'webSearch', enabled !== false));
204
- // Empty/reserved sessions rebuild now so session entry does not still
205
- // advertise web_search. A conversation keeps its frozen schema.
206
- await refreshEmptySessionToolPolicy?.();
207
203
  return this.getToolModuleSettings();
208
204
  },
209
205
  /** Which user instruction files (AGENTS.md / CLAUDE.md) new sessions load:
210
- * 'all' | 'agents' | 'claude' | 'off'. The empty session rebuilds now. */
206
+ * 'all' | 'agents' | 'claude' | 'off'. An empty session rebuilds at its next turn. */
211
207
  async setInstructionFiles(mode) {
212
208
  if (!INSTRUCTION_FILES_MODES.includes(mode)) {
213
209
  throw new TypeError(`Instruction files must be one of ${INSTRUCTION_FILES_MODES.join(', ')}.`);
214
210
  }
215
211
  saveConfigAndAdopt({ ...getConfig(), instructionFiles: mode });
216
- await refreshEmptySessionToolPolicy?.();
217
212
  return this.getToolModuleSettings();
218
213
  },
219
214
  /** The global "Auto reasoning base": the effort Auto works around. */
@@ -238,7 +233,6 @@ export function createBuiltinToolSettings(
238
233
  if (memoryEnabled) nextConfig = setBuiltinInstalledInConfig(nextConfig, 'memory', true);
239
234
  saveConfigAndAdopt(nextConfig);
240
235
  invalidateContextStatusCache();
241
- await refreshEmptySessionToolPolicy?.();
242
236
  return this.getToolModuleSettings();
243
237
  },
244
238
  async setBuiltinToolEnabled(name, enabled) {
@@ -268,7 +262,6 @@ export function createBuiltinToolSettings(
268
262
  }
269
263
  // Turning Auto on loads nothing: the judge starts on its first turn.
270
264
  if (name === 'autoEffort' && enabled === false) await shutdownEffortJudge();
271
- await refreshEmptySessionToolPolicy?.();
272
265
  return this.getToolModuleSettings();
273
266
  },
274
267
  /** Extensions → Built-in Install: run the feature's preparation adapter
@@ -300,7 +293,6 @@ export function createBuiltinToolSettings(
300
293
  await syncLocalProviderRegistry?.(true);
301
294
  }
302
295
  if (name === 'memory') invalidateContextStatusCache();
303
- await refreshEmptySessionToolPolicy?.();
304
296
  return this.getToolModuleSettings();
305
297
  },
306
298
  /** Extensions → Code Tidy: which engines exist, where each one comes from,
@@ -93,4 +93,4 @@ export async function askToWidenConnectorTool(
93
93
  permission: level,
94
94
  note: `The user approved on the card; ${tool} is now ${level}.`,
95
95
  };
96
- }
96
+ }
@@ -92,7 +92,14 @@ const ACTION_APPLIES_TO = {
92
92
  set_heartbeat_interval:
93
93
  "Mixy's heartbeat from the next tick: the next check is due the new interval after the last one; no restart required",
94
94
  set_reactions_enabled:
95
- "bots' chats; while off a reaction is refused at once and new chats are not offered the tool; reactions already left stay visible",
95
+ "bots' chats, this conversation included, from their next turn; while off a reaction is refused at once; reactions already left stay visible",
96
+ set_profile: 'every conversation, this one included, from its next turn',
97
+ set_instruction_files: 'every conversation, this one included, from its next turn',
98
+ set_memory_enabled: 'every conversation, this one included, from its next turn',
99
+ set_web_search_enabled: 'every conversation, this one included, from its next turn',
100
+ set_builtin_enabled: 'every conversation, this one included, from its next turn',
101
+ install_builtin: 'every conversation, this one included, from its next turn',
102
+ set_output_style: 'every conversation, this one included, from its next turn',
96
103
  set_worktree_settings: 'new tasks and worktrees created afterwards; existing worktrees are unchanged',
97
104
  set_system_shell: 'subsequent shell calls',
98
105
  save_automation: 'the automation worker; scheduled runs follow the saved timing',
@@ -307,6 +307,8 @@ export const EXTENDED_SETUP_HANDLERS = Object.freeze({
307
307
  owner: input.owner,
308
308
  });
309
309
  const next = { ...pick(previous, entryKeys), ...input };
310
+ // Omitted keeps the saved executor without checking it again (channel-admin.mjs).
311
+ if (!own(input, 'executorAgentId')) delete next.executorAgentId;
310
312
  if (kind === 'schedule') {
311
313
  if (previous.whenAt && !own(input, 'time') && !own(input, 'at')) {
312
314
  next.at = new Date(previous.whenAt).toISOString();
@@ -212,6 +212,11 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
212
212
  description:
213
213
  "The bot id that owns the schedule or webhook; each run is a turn in that bot's chat, where it replies with the result. The bot must exist (no representative bot yet = refused). New entries default to the bot of the calling thread (the representative bot = lead); on overwrite, omission keeps the owner.",
214
214
  },
215
+ executorAgentId: {
216
+ ...removableText,
217
+ description:
218
+ 'The workflow sub-agent id (Worker, …) that carries out each run first, on its own model; only its final report goes to the owner bot, which relays it in its own words. Must be an enabled workflow sub-agent: never a bot (the representative bot included); unknown or turned-off ids are refused. Set it for recurring work that suits a sub-agent; leave it unset for trivial chat-only routines (the owner bot then does the work itself). null or "" clears it; on overwrite, omission keeps it.',
219
+ },
215
220
  overwrite: { ...boolean, description: 'Explicitly update an existing entry; omitted fields are preserved.' },
216
221
  },
217
222
  ['name']
@@ -238,6 +243,16 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
238
243
  maximum: 400,
239
244
  description: 'Windows only: notification sound volume percent.',
240
245
  },
246
+ sessionAutoArchiveDays: {
247
+ type: 'integer',
248
+ enum: [0, 1, 7, 14, 30, 90],
249
+ description: 'Days without conversation before a session is archived; 0 = never (default 7).',
250
+ },
251
+ sessionAutoDeleteDays: {
252
+ type: 'integer',
253
+ enum: [0, 7, 30, 90],
254
+ description: 'Days archived before a session is deleted; 0 = never (default 90).',
255
+ },
241
256
  botOverlay: object(
242
257
  {
243
258
  enabled: {
@@ -302,6 +317,17 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
302
317
  markdownDefaultView: { type: 'string', enum: ['preview', 'rich', 'source'] },
303
318
  linkPreview: boolean,
304
319
  toolActivityExpansion: { type: 'string', enum: ['collapsed', 'commands', 'all'] },
320
+ composerStyle: {
321
+ type: 'string',
322
+ enum: ['simple', 'basic', 'detail'],
323
+ description:
324
+ 'How much the composer shows: simple = the model only; basic (UI label "Normal") = plus usage; detail = plus workflow and delegation (default detail).',
325
+ },
326
+ questionAnswerConfirm: {
327
+ ...boolean,
328
+ description:
329
+ 'On: picking a single-choice question option only selects it until Send/Next; off: the pick answers at once (default off).',
330
+ },
305
331
  uiFont: { ...text, description: 'Installed font family for the UI; "" restores the built-in font.' },
306
332
  codeFont: { ...text, description: 'Installed font family for code; "" restores the built-in font.' },
307
333
  skinTransparency: {
@@ -377,4 +403,6 @@ export const SETUP_HANDOFFS = Object.freeze({
377
403
  notifications: 'Notification permission/subscription requires a user gesture on the device receiving notifications.',
378
404
  pairing: 'Pairing credentials and OS permission approvals remain in the visible UI.',
379
405
  memoryContent: 'Use the memory tool for Core Memory, not setup.',
406
+ instructionTexts:
407
+ 'The Delegation and Output style instruction texts are edited in Settings → Delegation / Output style (revision-checked free text); choose the active output style with set_output_style.',
380
408
  });
@@ -447,13 +447,38 @@ export const SETUP_TOOL_DEFS = Object.freeze([
447
447
  enum: [...WORKTREE_NEW_TASK_DEFAULTS],
448
448
  description: 'branch = new tasks use the current branch (default); worktree = a new worktree.',
449
449
  },
450
- branchPrefix: { type: 'string', description: 'Ref prefix ending with "/"; default "mixdog/".' },
450
+ branchPrefix: {
451
+ type: 'string',
452
+ description:
453
+ 'Optional ref prefix ending with "/", e.g. "mixdog/"; "" (default) names branches after the task alone.',
454
+ },
451
455
  sizeWarnBytes: {
452
456
  type: 'integer',
453
457
  minimum: 0,
454
458
  description: 'Repository size that asks for confirmation first; 0 never asks.',
455
459
  },
456
460
  autoCleanup: { type: 'boolean', description: 'Remove clean, merged worktrees when their task ends.' },
461
+ maxWorktrees: {
462
+ type: 'integer',
463
+ minimum: 0,
464
+ maximum: 1000,
465
+ description:
466
+ 'With autoCleanup: keep at most this many worktrees, least recently used cleaned first; 0 = no limit. Default 15.',
467
+ },
468
+ unusedDays: {
469
+ type: 'integer',
470
+ minimum: 0,
471
+ maximum: 3650,
472
+ description: 'With autoCleanup: clean up worktrees unused this many days; 0 = never. Default 30.',
473
+ },
474
+ cleanupArchived: {
475
+ type: 'boolean',
476
+ description: 'With autoCleanup: archiving a session cleans up its worktrees. Default true.',
477
+ },
478
+ deleteBranch: {
479
+ type: 'boolean',
480
+ description: 'Cleanup also deletes the branch (its tip stays under a recovery ref). Default false.',
481
+ },
457
482
  },
458
483
  description: 'set_worktree_settings: only the given fields change.',
459
484
  },