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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "1.4.2",
3
+ "version": "1.4.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Open-source coding agent that matches Codex on Terminal-Bench 2.1 with 63% fewer tokens.",
@@ -144,7 +144,7 @@
144
144
  "arm64"
145
145
  ],
146
146
  "dependencies": {
147
- "@anthropic-ai/sdk": "^0.135.0",
147
+ "@anthropic-ai/sdk": "^0.137.0",
148
148
  "@formulajs/formulajs": "^4.6.1",
149
149
  "@google/generative-ai": "^0.24.1",
150
150
  "@huggingface/transformers": "^4.3.1",
@@ -92,11 +92,19 @@ function parseTree(body) {
92
92
  const treeCache = new Map();
93
93
  const blobCache = new Map();
94
94
  const treeOf = async (sha) => {
95
- if (!treeCache.has(sha)) treeCache.set(sha, read(sha).then(({ body }) => parseTree(body)));
95
+ if (!treeCache.has(sha))
96
+ treeCache.set(
97
+ sha,
98
+ read(sha).then(({ body }) => parseTree(body))
99
+ );
96
100
  return treeCache.get(sha);
97
101
  };
98
102
  const blobOf = async (sha) => {
99
- if (!blobCache.has(sha)) blobCache.set(sha, read(sha).then(({ body }) => body));
103
+ if (!blobCache.has(sha))
104
+ blobCache.set(
105
+ sha,
106
+ read(sha).then(({ body }) => body)
107
+ );
100
108
  return blobCache.get(sha);
101
109
  };
102
110
 
@@ -163,9 +171,10 @@ async function packHistory(dir, entry) {
163
171
  return out;
164
172
  }
165
173
 
166
- async function outputStyleHistory() {
174
+ // Single-file definitions (output styles, orchestration modes): file name -> hashes.
175
+ async function fileHistory(prefix) {
167
176
  const out = {};
168
- for (const [name, versions] of await everVersions('src/output-styles')) {
177
+ for (const [name, versions] of await everVersions(prefix)) {
169
178
  const hashes = [];
170
179
  for (const files of versions) hashes.push(hashText(await blobOf([...files.values()][0])));
171
180
  if (hashes.length) out[name] = unique(hashes);
@@ -188,7 +197,8 @@ async function skillHistory() {
188
197
  const history = {
189
198
  agents: await packHistory('src/agents', 'AGENT.md'),
190
199
  workflows: await packHistory('src/workflows', 'WORKFLOW.md'),
191
- outputStyles: await outputStyleHistory(),
200
+ outputStyles: await fileHistory('src/output-styles'),
201
+ orchestration: await fileHistory('src/orchestration'),
192
202
  skills: await skillHistory(),
193
203
  };
194
204
  catFile.stdin.end();
@@ -36,7 +36,9 @@ import {
36
36
  runPool,
37
37
  saveTimingHistory,
38
38
  } from './lib/gate-scheduler.mjs';
39
+ import { FULL_LOG_LABEL } from './lib/run-node-tests.mjs';
39
40
  import { pruneStaleTempDirs, removeTempDirSync } from './lib/stale-temp.mjs';
41
+ import { SUMMARY_TAG } from './lib/test-failure-summary.mjs';
40
42
 
41
43
  const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
42
44
  const started = Date.now();
@@ -81,8 +83,7 @@ const commonDir = spawnSync('git', ['rev-parse', '--path-format=absolute', '--gi
81
83
  cwd: root,
82
84
  encoding: 'utf8',
83
85
  });
84
- const historyPath =
85
- commonDir.status === 0 ? path.join(commonDir.stdout.trim(), 'mixdog-gate-timings.json') : null;
86
+ const historyPath = commonDir.status === 0 ? path.join(commonDir.stdout.trim(), 'mixdog-gate-timings.json') : null;
86
87
  if (!historyPath) console.warn(`[gate:local] warning: no git common dir, timings not kept: ${commonDir.stderr}`);
87
88
  const history = historyPath ? readTimingHistory(historyPath) : {};
88
89
  const measured = {};
@@ -99,7 +100,8 @@ const testLanes = [
99
100
  const dir = path.join(root, lane.pkg);
100
101
  const command = JSON.parse(fs.readFileSync(path.join(dir, 'package.json'), 'utf8')).scripts[lane.script];
101
102
  const [program, ...args] = command.split(/\s+/);
102
- if (program !== 'node') throw new Error(`${lane.pkg}/package.json "${lane.script}" must be a node command: ${command}`);
103
+ if (program !== 'node')
104
+ throw new Error(`${lane.pkg}/package.json "${lane.script}" must be a node command: ${command}`);
103
105
  const list = spawnSync(process.execPath, [...args, '--list'], { cwd: dir, encoding: 'utf8' });
104
106
  if (list.status !== 0) throw new Error(`${command} --list failed: ${list.stderr}`);
105
107
  const files = list.stdout
@@ -107,7 +109,14 @@ const testLanes = [
107
109
  .filter(Boolean)
108
110
  .map((line) => line.replace(/^\S+\s+/, ''));
109
111
  const key = (file) => path.posix.join(lane.pkg, file);
110
- return { ...lane, dir, args, files, key, estimateOf: (file) => history[key(file)] ?? DEFAULT_ESTIMATE_MS[lane.speed] };
112
+ return {
113
+ ...lane,
114
+ dir,
115
+ args,
116
+ files,
117
+ key,
118
+ estimateOf: (file) => history[key(file)] ?? DEFAULT_ESTIMATE_MS[lane.speed],
119
+ };
111
120
  });
112
121
  const lanesByName = new Map(testLanes.map((lane) => [lane.name, lane]));
113
122
  const commandUnits = [
@@ -136,11 +145,37 @@ function run(command, args, options, fd) {
136
145
  const child = spawn(command, args, { ...options, env, windowsHide: true, stdio: ['ignore', fd, fd] });
137
146
  child.on('error', (error) => {
138
147
  fs.writeSync(fd, `${error.stack}\n`);
139
- resolve(1);
148
+ resolve({ code: 1, signal: null });
140
149
  });
141
- child.on('close', (code) => resolve(code ?? 1));
150
+ child.on('close', (code, signal) => resolve({ code, signal }));
142
151
  });
143
152
  }
153
+ const passed = (exit) => exit.code === 0;
154
+ const ending = (exit) => (exit.signal ? `signal ${exit.signal}` : `exit code ${exit.code}`);
155
+
156
+ // A shard's runner ends every run with its failure summary
157
+ // (scripts/lib/run-node-tests.mjs). One killed from outside (TerminateProcess,
158
+ // SIGKILL) or crashed prints nothing more, and Windows ends its node --test
159
+ // batch and test processes with it, so no reporter flushes either: name how it
160
+ // ended and what its full test log last recorded.
161
+ const DEAD_TAIL_LINES = 12;
162
+ function deadShardReport(unit, exit, output) {
163
+ if (passed(exit) || output.includes(SUMMARY_TAG)) return '';
164
+ const fullLog = output
165
+ .split(/\r?\n/)
166
+ .find((line) => line.startsWith(FULL_LOG_LABEL))
167
+ ?.slice(FULL_LOG_LABEL.length);
168
+ const tail =
169
+ fullLog && fs.existsSync(fullLog)
170
+ ? fs.readFileSync(fullLog, 'utf8').trimEnd().split(/\r?\n/).slice(-DEAD_TAIL_LINES)
171
+ : [];
172
+ return [
173
+ `${SUMMARY_TAG} RUN FAILED: ${unit.id} runner ended by ${ending(exit)} before its failure summary (killed from outside or crashed)`,
174
+ `${SUMMARY_TAG} last ${tail.length} line(s) of ${fullLog ?? 'its full test log (never named)'}:`,
175
+ ...tail.map((line) => ` ${line}`),
176
+ '',
177
+ ].join('\n');
178
+ }
144
179
 
145
180
  const TIMING_REPORTER = new URL('./lib/gate-timing-reporter.mjs', import.meta.url).href;
146
181
  async function runShard(unit, fd) {
@@ -148,7 +183,7 @@ async function runShard(unit, fd) {
148
183
  const timings = path.join(logDir, `${unit.id}.timings.jsonl`);
149
184
  const args = [...lane.args, `--test-reporter=${TIMING_REPORTER}`, `--test-reporter-destination=${timings}`];
150
185
  fs.writeSync(fd, `\n$ (${lane.pkg}) node ${[...args, ...unit.files].join(' ')}\n`);
151
- const code = await run(process.execPath, [...args, ...unit.files], { cwd: lane.dir }, fd);
186
+ const exit = await run(process.execPath, [...args, ...unit.files], { cwd: lane.dir }, fd);
152
187
  const reported = Object.fromEntries(
153
188
  (fs.existsSync(timings) ? fs.readFileSync(timings, 'utf8') : '')
154
189
  .split('\n')
@@ -162,20 +197,19 @@ async function runShard(unit, fd) {
162
197
  for (const [file, ms] of Object.entries(measuredFileTimes(unit.files, reported, Date.now() - unit.start))) {
163
198
  measured[lane.key(file)] = Math.round(ms);
164
199
  }
165
- return code === 0;
200
+ return exit;
166
201
  }
167
202
 
203
+ // The exit of the first command that failed, else of the last one.
168
204
  async function runCommands(unit, fd) {
169
- let ok = true;
205
+ let exit = { code: 0, signal: null };
170
206
  for (const cmd of unit.cmds) {
171
207
  fs.writeSync(fd, `\n$ ${cmd}\n`);
172
- if ((await run(cmd, [], { cwd: root, shell: true }, fd)) !== 0) {
173
- ok = false;
174
- break;
175
- }
208
+ exit = await run(cmd, [], { cwd: root, shell: true }, fd);
209
+ if (!passed(exit)) break;
176
210
  }
177
211
  measured[unit.key] = Date.now() - unit.start;
178
- return ok;
212
+ return exit;
179
213
  }
180
214
 
181
215
  let finished = 0;
@@ -183,18 +217,25 @@ async function runUnit(unit) {
183
217
  const part = path.join(logDir, `${unit.id}.part.log`);
184
218
  const fd = fs.openSync(part, 'w');
185
219
  unit.start = Date.now();
186
- let ok = false;
220
+ let exit = { code: 1, signal: null };
221
+ let dead = '';
187
222
  try {
188
- ok = await (unit.files ? runShard(unit, fd) : runCommands(unit, fd));
223
+ exit = await (unit.files ? runShard(unit, fd) : runCommands(unit, fd));
224
+ if (unit.files) {
225
+ dead = deadShardReport(unit, exit, fs.readFileSync(part, 'utf8'));
226
+ if (dead) fs.writeSync(fd, `\n${dead}`);
227
+ }
189
228
  } finally {
190
229
  fs.closeSync(fd);
191
230
  unit.end = Date.now();
192
231
  fs.appendFileSync(laneLog(unit.lane), fs.readFileSync(part));
193
232
  fs.rmSync(part);
194
233
  }
234
+ const ok = passed(exit);
195
235
  console.log(
196
- `[gate:local] ${ok ? 'ok ' : 'FAIL'} ${unit.id} ${((unit.end - unit.start) / 1000).toFixed(1)}s (${++finished}/${units.length})`
236
+ `[gate:local] ${ok ? 'ok ' : 'FAIL'} ${unit.id} ${((unit.end - unit.start) / 1000).toFixed(1)}s (${++finished}/${units.length})${ok ? '' : ` ${ending(exit)}`}`
197
237
  );
238
+ if (dead) process.stdout.write(dead);
198
239
  return ok;
199
240
  }
200
241
 
@@ -209,7 +250,9 @@ try {
209
250
  // The next run plans from these; work this run did not reach keeps its old time.
210
251
  const keys = [...testLanes.flatMap((lane) => lane.files.map(lane.key)), ...commandUnits.map((unit) => unit.key)];
211
252
  const next = Object.fromEntries(
212
- keys.filter((key) => (measured[key] ?? history[key]) !== undefined).map((key) => [key, measured[key] ?? history[key]])
253
+ keys
254
+ .filter((key) => (measured[key] ?? history[key]) !== undefined)
255
+ .map((key) => [key, measured[key] ?? history[key]])
213
256
  );
214
257
  const saveError = historyPath && saveTimingHistory(historyPath, next);
215
258
  if (saveError) console.warn(`[gate:local] warning: timings not saved (${saveError.message})`);
@@ -232,7 +275,10 @@ for (const name of laneNames) {
232
275
  .filter((l) => /\[failure-summary\] (?:RUN FAILED|HUNG|FAILED|FLAKY)/.test(l));
233
276
  for (const l of lines) console.log(` ${l}`);
234
277
  }
235
- if (notStarted.length) console.log(`Stopped after a failed ${units.find((u) => u.stopOnFail && u.ok === false).lane} check: ${notStarted.length} unit(s) not run`);
278
+ if (notStarted.length)
279
+ console.log(
280
+ `Stopped after a failed ${units.find((u) => u.stopOnFail && u.ok === false).lane} check: ${notStarted.length} unit(s) not run`
281
+ );
236
282
  console.log(
237
283
  'Not covered locally: runtime-macos, computer-backend, desktop-tests computer lane (Windows-only), relay, graph, patch, browser-import, mobile-scripts'
238
284
  );
@@ -6,6 +6,7 @@ import { readFileSync, writeFileSync } from 'node:fs';
6
6
  import { resolve } from 'node:path';
7
7
  import { performance } from 'node:perf_hooks';
8
8
  import { pathToFileURL } from 'node:url';
9
+ import { spawnTreeKill } from '../src/runtime/agent/orchestrator/mcp/child-tree.mjs';
9
10
  import { median, sortedFinite } from './lib/trace-stats.mjs';
10
11
 
11
12
  const USAGE = `usage: node scripts/graph-parity.mjs --old <binary> --new <binary> [--root <dir>] [--files <rel>...] [--json <out>] [--kind-map <path.json>] [--tokens] [--allow-new-languages <ids>] [--max-symbol-loss N] [--max-import-diff N] [--max-token-loss N] [--max-time-ratio 1.10] [--runs 3]
@@ -925,15 +926,19 @@ function reusedMetaLine(rec) {
925
926
  });
926
927
  }
927
928
 
929
+ // Windows: the shared, bounded creation-checked tree kill finds the
930
+ // descendants while the root still runs; the root, owned and alive, is then
931
+ // killed directly once that pass ends or runs out of time (spawnTreeKill).
928
932
  function killProcessTree(proc) {
933
+ if (process.platform === 'win32' && proc.pid && proc.exitCode === null && proc.signalCode === null) {
934
+ spawnTreeKill([proc.pid], { root: proc });
935
+ return;
936
+ }
929
937
  try {
930
938
  proc.kill();
931
939
  } catch {
932
940
  /* ignore */
933
941
  }
934
- if (process.platform === 'win32' && proc.pid) {
935
- spawn('taskkill', ['/pid', String(proc.pid), '/t', '/f'], { windowsHide: true, stdio: 'ignore' });
936
- }
937
942
  }
938
943
 
939
944
  export function runProcess(bin, args, { stdinText = null, timeoutMs = SPAWN_TIMEOUT_MS } = {}) {
@@ -31,7 +31,8 @@ export function gateTestBudget(argv = [], env = process.env, parallelism = avail
31
31
  if (index >= 0) explicit = argv[index].includes('=') ? argv[index].split('=')[1] : (argv[index + 1] ?? '');
32
32
  if (explicit === undefined) return Math.max(1, Math.min(DEFAULT_MAX_WORKERS, Math.floor(parallelism / 2)));
33
33
  const budget = Number(explicit);
34
- if (!Number.isInteger(budget) || budget < 1) throw new Error(`gate test budget must be a positive integer (got "${explicit}")`);
34
+ if (!Number.isInteger(budget) || budget < 1)
35
+ throw new Error(`gate test budget must be a positive integer (got "${explicit}")`);
35
36
  return budget;
36
37
  }
37
38
 
@@ -29,6 +29,8 @@ const TEST_LOG_PREFIX = 'mixdog-test-output-';
29
29
  const TEST_FAILURES_PREFIX = 'mixdog-test-failures-';
30
30
  const TEST_SCRATCH_PREFIX = 'mixdog-test-scratch-';
31
31
  export const RUNNER_TEMP_PREFIXES = [TEST_LOG_PREFIX, TEST_FAILURES_PREFIX, TEST_SCRATCH_PREFIX];
32
+ // Printed first by every run; the local gate finds a dead unit's log by it.
33
+ export const FULL_LOG_LABEL = 'Full test log: ';
32
34
 
33
35
  // Batches keep the file order Node was given; a single path larger than the
34
36
  // budget still gets its own batch rather than being dropped. An empty list
@@ -142,11 +144,19 @@ function capture(command, args) {
142
144
  });
143
145
  }
144
146
 
145
- // Kills a process and every descendant still linked to it. On POSIX a batch
146
- // leads its own process group (spawned detached), so the group goes with it.
147
+ // Kills a live batch and every descendant still linked to it (on Windows the
148
+ // shared creation-checked tree kill). On POSIX a batch leads its own process
149
+ // group (spawned detached), so the group goes with it.
150
+ // Loaded only when a Windows kill runs, so importers that need just this
151
+ // module's constants (the local gate) do not pull in the runtime.
152
+ async function loadKillProcessTrees() {
153
+ const { killProcessTrees } = await import('../../src/runtime/agent/orchestrator/mcp/child-tree.mjs');
154
+ return killProcessTrees;
155
+ }
156
+
147
157
  async function killTree(pid) {
148
158
  if (process.platform === 'win32') {
149
- await capture('taskkill', ['/T', '/F', '/PID', String(pid)]);
159
+ await (await loadKillProcessTrees())([pid]);
150
160
  return;
151
161
  }
152
162
  for (const target of [-pid, pid]) {
@@ -284,12 +294,14 @@ async function reapLeftovers(child, { batch, ledger, scratchDir }) {
284
294
  }
285
295
 
286
296
  async function killOwned(anchors, { scratchDir }) {
297
+ // Every owned process ran when the snapshot was taken.
298
+ const snapshotAt = Date.now();
287
299
  const leftovers = ownedProcesses(await processSnapshot(), anchors, { scratchDir });
288
300
  if (leftovers.length === 0) return;
289
301
  const pids = leftovers.map((entry) => entry.pid);
290
302
  console.error(`Killing ${pids.length} process(es) a test left running: ${pids.join(' ')}`);
291
303
  if (process.platform === 'win32') {
292
- await capture('taskkill', ['/T', '/F', ...pids.flatMap((pid) => ['/PID', String(pid)])]);
304
+ await (await loadKillProcessTrees())(pids, { aliveAt: snapshotAt });
293
305
  return;
294
306
  }
295
307
  for (const pid of pids) {
@@ -387,7 +399,7 @@ export async function runNodeTests(nodeArgs, fileArgs, options = {}) {
387
399
  pruneStaleTempDirs(RUNNER_TEMP_PREFIXES);
388
400
  const outputDir = await mkdtemp(join(tmpdir(), TEST_LOG_PREFIX));
389
401
  const logPath = join(outputDir, 'full.log');
390
- console.error(`Full test log: ${logPath}`);
402
+ console.error(`${FULL_LOG_LABEL}${logPath}`);
391
403
  // Failure records live outside the log directory: the log directory holds
392
404
  // exactly one merged log, and these records are an internal artifact.
393
405
  const failureDir = await mkdtemp(join(tmpdir(), TEST_FAILURES_PREFIX));
@@ -50,14 +50,7 @@ export function policyLine(rerunFailed) {
50
50
  // never "0 failed". `pids` names the node --test processes that exited
51
51
  // non-zero, so a kill can be matched to the "Killing ... <pid>" line of
52
52
  // whatever killed them.
53
- export function formatFailureSummary({
54
- failed = [],
55
- flaky = [],
56
- rerunFailed = 0,
57
- hung = [],
58
- exitCode = 0,
59
- pids = [],
60
- }) {
53
+ export function formatFailureSummary({ failed = [], flaky = [], rerunFailed = 0, hung = [], exitCode = 0, pids = [] }) {
61
54
  const hungCount = hung.length > 0 ? `, ${hung.length} hung batch(es)` : '';
62
55
  const unexplained = exitCode !== 0 && failed.length === 0 && hung.length === 0;
63
56
  const runner = pids.length > 0 ? `node --test pid ${pids.join(' ')}: ` : '';
@@ -5,8 +5,10 @@
5
5
  // nothing.
6
6
  import { ChildProcess } from 'node:child_process';
7
7
  import { appendFileSync, readFileSync } from 'node:fs';
8
+ import { constants } from 'node:os';
8
9
  import { dirname, join } from 'node:path';
9
10
  import { pathToFileURL } from 'node:url';
11
+ import { getSystemErrorMap } from 'node:util';
10
12
  import { FAILURE_RECORDS_ENV, spawnLedgerPath } from './test-failure-records.mjs';
11
13
 
12
14
  // --test-force-exit ends a test file's process once every test registered so
@@ -60,14 +62,43 @@ if (ledger) {
60
62
  // comes before the child's handle is closed, so the pid is still this
61
63
  // child's when the exit is written: from then on another process may hold it.
62
64
  const spawn = ChildProcess.prototype.spawn;
65
+ const exited = new Set();
63
66
  ChildProcess.prototype.spawn = function recordedSpawn(...args) {
64
67
  const before = Date.now();
65
68
  const result = spawn.apply(this, args);
66
69
  if (this.pid) {
67
- const spawned = `${this.pid} ${before} ${Date.now()}`;
70
+ const { pid } = this;
71
+ exited.delete(pid);
72
+ const spawned = `${pid} ${before} ${Date.now()}`;
68
73
  appendFileSync(ledger, `${spawned}\n`);
69
- this.once('exit', () => appendFileSync(ledger, `${spawned} ${Date.now()}\n`));
74
+ this.once('exit', () => {
75
+ exited.add(pid);
76
+ appendFileSync(ledger, `${spawned} ${Date.now()}\n`);
77
+ });
70
78
  }
71
79
  return result;
72
80
  };
81
+ // Once a child's exit is seen its pid is free, and Windows hands it to the
82
+ // next process started within moments — on a loaded gate often a parallel
83
+ // unit's test runner, node --test batch or test file process. A cleanup that
84
+ // signals every pid it recorded (e.g. `after(() => process.kill(pid))`, or a
85
+ // kill(pid, 0) liveness poll) then terminates that process instead, and the
86
+ // whole unit dies without output. Such a signal fails ESRCH here, as for a
87
+ // gone process, and never reaches whatever holds the pid now. Arguments Node
88
+ // rejects (a non-integer pid, an unknown signal) still go to Node, which
89
+ // throws before any signal is sent; this rejects only what it would send.
90
+ const kill = process.kill;
91
+ const [ESRCH] = [...getSystemErrorMap()].find(([, [name]]) => name === 'ESRCH');
92
+ const sendable = (signal) => signal === (signal | 0) || Boolean(constants.signals[signal || 'SIGTERM']);
93
+ process.kill = function killLiveChildOnly(pid, signal) {
94
+ // Only a primitive pid is checked: coercing an object would run its
95
+ // valueOf before Node's own coercion does. Number(pid) === (pid | 0) is
96
+ // Node's `pid == (pid | 0)` integer check.
97
+ const primitive = typeof pid === 'number' || typeof pid === 'string';
98
+ if (primitive && Number(pid) === (pid | 0) && exited.has(pid | 0) && sendable(signal)) {
99
+ // The shape of Node's own failed kill (an ErrnoException).
100
+ throw Object.assign(new Error('kill ESRCH'), { errno: ESRCH, code: 'ESRCH', syscall: 'kill' });
101
+ }
102
+ return kill.call(process, pid, signal);
103
+ };
73
104
  }
@@ -87,9 +87,12 @@ export async function checkFeed({ text, label, version, assets, hashAsset, requi
87
87
  for (const name of requiredFiles) {
88
88
  if (!byUrl.has(name)) problems.push(`${label}: files[] does not list ${name}`);
89
89
  }
90
+ // Every listed asset downloads at once; the problems keep files[] order.
91
+ const fileAssets = feed.files.map((file) => assets.find((candidate) => candidate.name === file.url));
92
+ const digests = await Promise.all(fileAssets.map((asset) => (asset ? hashAsset(asset) : null)));
90
93
  const hashes = new Map();
91
- for (const file of feed.files) {
92
- const asset = assets.find((candidate) => candidate.name === file.url);
94
+ for (const [index, file] of feed.files.entries()) {
95
+ const asset = fileAssets[index];
93
96
  if (!asset) {
94
97
  problems.push(`${label}: ${file.url} is not an uploaded asset`);
95
98
  continue;
@@ -99,7 +102,7 @@ export async function checkFeed({ text, label, version, assets, hashAsset, requi
99
102
  problems.push(`${label}: ${file.url} size ${size} != uploaded ${asset.size}`);
100
103
  }
101
104
  const sha512 = field(file, 'sha512');
102
- const actual = await hashAsset(asset);
105
+ const actual = digests[index];
103
106
  hashes.set(file.url, actual);
104
107
  if (sha512 !== actual) problems.push(`${label}: ${file.url} sha512 does not match the uploaded asset`);
105
108
  }
@@ -233,6 +236,25 @@ export async function detectPublished({ fetchRelease, sleep = defaultSleep, atte
233
236
  }
234
237
  }
235
238
 
239
+ /**
240
+ * Run independent `[name, run]` sections concurrently. Results keep the
241
+ * section order; a thrown section becomes a "check failed" problem.
242
+ */
243
+ export function runSections(sections) {
244
+ return Promise.all(
245
+ sections.map(async ([name, run]) => {
246
+ try {
247
+ const outcome = await run();
248
+ return Array.isArray(outcome)
249
+ ? { name, problems: outcome, warnings: [] }
250
+ : { name, problems: outcome.problems, warnings: outcome.warnings };
251
+ } catch (error) {
252
+ return { name, problems: [`check failed: ${error.message}`], warnings: [] };
253
+ }
254
+ })
255
+ );
256
+ }
257
+
236
258
  async function sha512Base64(url) {
237
259
  const response = await fetch(url, { redirect: 'follow' });
238
260
  if (!response.ok) throw new Error(`download ${url} answered ${response.status}`);
@@ -290,19 +312,7 @@ async function main() {
290
312
  ],
291
313
  ['npm', () => waitForNpm({ name: 'mixdog', version })],
292
314
  ];
293
- const results = [];
294
- for (const [name, run] of sections) {
295
- try {
296
- const outcome = await run();
297
- results.push(
298
- Array.isArray(outcome)
299
- ? { name, problems: outcome, warnings: [] }
300
- : { name, problems: outcome.problems, warnings: outcome.warnings }
301
- );
302
- } catch (error) {
303
- results.push({ name, problems: [`check failed: ${error.message}`], warnings: [] });
304
- }
305
- }
315
+ const results = await runSections(sections);
306
316
 
307
317
  const lines = [`## Post-release check for ${tag}`, ''];
308
318
  for (const { name, problems, warnings } of results) {
@@ -10,7 +10,7 @@
10
10
  // stores. Only the API-key secrets (`secrets/agent.<provider>.apiKey.dpapi`) and the
11
11
  // `agent` section of mixdog-config.json are copied in. OAuth providers (`*-oauth`, whose
12
12
  // refresh tokens could be rotated) are skipped unless `--real-data` is passed, which
13
- // restores the old behaviour of running against the real data dir. The isolated dir is
13
+ // runs against the real data dir instead. The isolated dir is
14
14
  // deleted at the end, after stopping only processes whose executable lives inside it.
15
15
  // Usage: node scripts/provider-pingpong-live.mjs [--suite extended] [--real-data] [case-name ...]
16
16
  import fs from 'node:fs';
@@ -118,7 +118,9 @@ export async function pruneEmbeddingRuntime(packageRoot, options = {}) {
118
118
  }
119
119
  }
120
120
  }
121
- await removeChildrenExcept(ortRoot, new Set(['package.json', 'dist', 'bin', 'node_modules']));
121
+ // npm runs onnxruntime-node's own postinstall (node ./script/install)
122
+ // concurrently with ours, so its script/ helpers must survive the prune.
123
+ await removeChildrenExcept(ortRoot, new Set(['package.json', 'dist', 'bin', 'node_modules', 'script']));
122
124
 
123
125
  // The Node bundle marks onnxruntime-web as an ignored webpack external. Keep
124
126
  // only its manifest so npm's dependency inventory remains coherent.
@@ -51,7 +51,13 @@ const PATCH_GATE_FILES = [
51
51
  // workflow, output-style and bundled-skill trees (scripts/build-shipped-history.mjs)
52
52
  // and committed under src/defaults/. Release re-checks it, so the gate checks
53
53
  // it first instead of letting a stale file fail the deploy late.
54
- const HISTORY_GATE_PREFIXES = ['src/agents/', 'src/workflows/', 'src/output-styles/', 'src/defaults/'];
54
+ const HISTORY_GATE_PREFIXES = [
55
+ 'src/agents/',
56
+ 'src/workflows/',
57
+ 'src/output-styles/',
58
+ 'src/orchestration/',
59
+ 'src/defaults/',
60
+ ];
55
61
  const HISTORY_GATE_FILES = [
56
62
  'scripts/build-shipped-history.mjs',
57
63
  'src/runtime/shared/shipped-definitions.mjs',
@@ -179,6 +179,20 @@
179
179
  "d5f205f3b57c0b9541b8acc237069287"
180
180
  ]
181
181
  },
182
+ "orchestration": {
183
+ "balanced.md": [
184
+ "ad1683ff1626ebabd4e027abe03fe29a"
185
+ ],
186
+ "focused.md": [
187
+ "e73b0d71f544900611b2d06f963472d4"
188
+ ],
189
+ "none.md": [
190
+ "9be4bf61f9ba91c4caf53296adff2e8a"
191
+ ],
192
+ "swarm.md": [
193
+ "7fa3e68e0c53d16203384f5ca645765d"
194
+ ]
195
+ },
182
196
  "skills": {
183
197
  "browser-use": [
184
198
  "00085086a7649ec6631f5cf0a3bbbf60",
@@ -368,6 +382,7 @@
368
382
  ],
369
383
  "setup": [
370
384
  "0357c6d475ced8ba2446e6bda21899b4",
385
+ "0bb692f16b03c66f23af06cea06de51f",
371
386
  "0be31b379e919420e5b8f74926bdf6e5",
372
387
  "0d5c8c6e2349addf71d2ed2b4c1ccb1f",
373
388
  "0d6926aaca2890da9347f15a826546e3",
@@ -378,7 +393,9 @@
378
393
  "242f11864abdef90fa0cc9cb4599a579",
379
394
  "29a347c4d3a2f773fa92c627260301ba",
380
395
  "336ced846a9e4f774cbb109417856c3b",
396
+ "34c5f8fcb6292b8cc5239667d2119e83",
381
397
  "3716b2d2c2d973ae022694ed5cb756ad",
398
+ "398958b6f815bf8ad3f96dd288844333",
382
399
  "3dc990c29cdce1aca4b112d735ad5917",
383
400
  "3f72247651ad9d777b6754bfd46732aa",
384
401
  "50bdf35d06913236855080fdea6b50dc",
@@ -397,6 +414,7 @@
397
414
  "8b829db6b0675b62a71a1432dbd25490",
398
415
  "99d76213e70c6900d6af48ffa4045886",
399
416
  "9a2188ce201e4394bc18182131b7a3e1",
417
+ "9b10b59b27497a126b212df083ace020",
400
418
  "9f90d3872b1ecd312977ce661b770b31",
401
419
  "ade615dd0f6ae6ed1601023e5b9cb692",
402
420
  "b21681ecfeb523c0d7dd89a299ec05a9",
@@ -417,9 +435,11 @@
417
435
  "ff18ac1a9f5961925aec27ffb870bae0"
418
436
  ],
419
437
  "setup-guide": [
438
+ "0968139f1aa26f48f03cfea2e94f45e8",
420
439
  "633e15b84dbe22f2b578b67cc35853d4",
421
440
  "72e474711ecd18cfcae6c8365e08286e",
422
441
  "920d5b29ccfe6c88f623cf0892b29285",
442
+ "dbe3d22991ad4dff6e3906f9101c9b5f",
423
443
  "ec88a82ab5e511c0afb1738162150648",
424
444
  "fa355d4ea5f1823e4b75219ab842c34a"
425
445
  ],
@@ -80,8 +80,8 @@ that a call returned without transport error.
80
80
  Setup changes settings; it does not stop work. Use the tool that owns it:
81
81
  `session` `cancel` (another session's turn, a routine run in a bot's chat, a
82
82
  group room's exchange; a Browser/Computer takeover ends with its turn),
83
- `agent` `cancel`/`close` (sub-agents), `task` (background shell jobs), `goal`
84
- `pause` (an active Goal, at the user's request). Setup only prevents more: `set_automation_enabled false`
83
+ `agent` `cancel`/`close` (sub-agents), `task` (background shell jobs); an
84
+ active Goal is paused or stopped by the user from its controls. Setup only prevents more: `set_automation_enabled false`
85
85
  (future routine runs), `fallbacks: []` (further hops), `cancel_quota_resume`,
86
86
  `set_builtin_enabled` browser/computer off.
87
87
 
@@ -79,7 +79,7 @@ Read this when choosing a `setup` mutation.
79
79
  | Create a workflow, agent, or machine-global user skill | `create_definition` |
80
80
  | Partially edit a workflow, agent, or machine-global user skill | `save_definition` |
81
81
  | Delete a user workflow/agent definition or override | `delete_definition` |
82
- | Save a schedule/webhook; explicitly overwrite to edit. A new one belongs to the calling thread's agent (Mixy = `lead`); `entry.owner` moves it to another agent | `save_automation` |
82
+ | Save a schedule/webhook; explicitly overwrite to edit. A new one belongs to the calling thread's agent (Mixy = `lead`); `entry.owner` moves it to another agent; `entry.executorAgentId` names the workflow sub-agent that carries out each run first (`null`/`""` clears it) | `save_automation` |
83
83
  | Delete an existing schedule/webhook | `delete_automation` |
84
84
  | Enable/disable (pause/resume) a schedule/webhook | `set_automation_enabled` |
85
85
  | Run a schedule once now, or re-run a webhook on its latest received payload; the result posts into the owning agent's thread | `run_automation` |
@@ -377,8 +377,10 @@ markers are read with `status desktop`.
377
377
  (an imported theme id from `status appearance` `colorThemes`, or `"builtin"`).
378
378
  Also `timeFormat` (system|12h|24h), `sidePanelPosition` (right|bottom|auto),
379
379
  `uiScale` (0.85–1.2, step 0.05), `codeSize` (10–20), `codeLigatures`
380
- (bool) and `chatTextSize` (small|default|large|extra-large). The UI label
381
- "Light" is `theme: "white"`.
380
+ (bool) and `chatTextSize` (small|default|large|extra-large). Also
381
+ `composerStyle` (simple|basic|detail; the UI label "Normal" is `basic`) and
382
+ `questionAnswerConfirm` (bool: a single-choice pick waits for Send/Next).
383
+ The UI label "Light" is `theme: "white"`.
382
384
  Importing, exporting or removing a theme file and choosing a skin picture
383
385
  or its plate/accent/photo stay in the UI.
384
386
  - `set_desktop_settings` `desktop.botOverlay` takes `enabled`, `position`
@@ -406,6 +408,17 @@ markers are read with `status desktop`.
406
408
  active is skipped. In an attended bot conversation (chat, room, or work a
407
409
  bot started) the same payment and permanent-delete connectors ask first,
408
410
  allow once or deny only; a coding session is not asked.
411
+ - `entry.executorAgentId` (schedule or webhook) is an enabled workflow
412
+ sub-agent id (Worker, …; never a bot or Mixy; unknown or turned-off ids are
413
+ refused). With it, each run is first carried out by that sub-agent on its own
414
+ route, unattended like the bot's own run (never asks, payments and permanent
415
+ deletes refused, no task sessions), and only its final report reaches the
416
+ owner bot, which relays it in its own words; a report that is exactly
417
+ `ROUTINE_QUIET` wakes nobody. If the sub-agent is later removed or turned
418
+ off, the run fails with that error instead of falling back. Without it the
419
+ owner bot does the work itself. Set it for recurring work a sub-agent suits;
420
+ leave it unset for trivial chat-only routines. `overwrite:true` keeps it
421
+ when omitted.
409
422
  - Enabling or creating automation may start its background worker. This is a
410
423
  persisted automation change, not permission to run an unrelated task now.
411
424
 
@@ -121,6 +121,9 @@ The setup tool does not mutate:
121
121
  per-device view state;
122
122
  - MCP server OAuth sign-in and sign-out (Desktop MCP list/editor, TUI
123
123
  `/mcp login` and `/mcp logout`; remote windows paste the redirect address);
124
+ - the Delegation and Output style instruction texts (Settings → Delegation /
125
+ Output style; revision-checked free text — `set_output_style` only chooses
126
+ the active style);
124
127
  - notification permission and subscription on the receiving device;
125
128
  - web-app pairing credentials and OS permission dialogs;
126
129
  - TUI-local theme palettes (use `/theme`; Desktop themes are separate);
@@ -171,7 +171,12 @@ step; do not insist.
171
171
  addresses one bot; otherwise the Maintainer decides who answers next.
172
172
  - Schedules and webhooks: a timed or incoming-event trigger (`save_automation`).
173
173
  Each run is one turn in its bot's own chat, with that bot's persona, rules,
174
- permissions, memory and model. Without a bot they cannot be used.
174
+ permissions, memory and model. Without a bot they cannot be used. A routine
175
+ can also name an executor sub-agent (`executorAgentId`, e.g. Worker): that
176
+ sub-agent does each run on its own model and the bot only relays its report.
177
+ In the Schedules/Webhooks editor this is the "Executor" field (Korean UI:
178
+ "실행 에이전트"); its default "The bot itself" ("직접 처리") means the bot
179
+ does the run itself.
175
180
  - Approval cards: when a tool needs permission it waits in the chat until the
176
181
  user approves or declines.
177
182
  - Phone remote access: pair a phone under Settings → Connection to follow and