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
@@ -140,7 +140,7 @@ function resolveRange(text, cells, notes) {
140
140
  }
141
141
 
142
142
  /** The operations that write one measured workbook; formulas and charts come after every sheet's values. */
143
- export function xlsxOperationsFromSheets(sheets, { captures = new Map(), notes = [] } = {}) {
143
+ function xlsxOperationsFromSheets(sheets, { captures = new Map(), notes = [] } = {}) {
144
144
  const first = [];
145
145
  const later = [];
146
146
  const chartData = [];
@@ -49,7 +49,7 @@ function fillRangeCharts() {
49
49
  }
50
50
 
51
51
  /** Artifacts kept beside the workbook: its HTML and the browser's picture of each sheet. */
52
- export function xlsxHtmlArtifacts(target) {
52
+ function xlsxHtmlArtifacts(target) {
53
53
  return {
54
54
  source: `${target}.mixdog-source.html`,
55
55
  shot: (sheet) => `${target}.mixdog-html-sheet-${sheet}.png`,
@@ -430,7 +430,7 @@ function docxStyleDefinitionFault(format, name, operation, index) {
430
430
 
431
431
  // A Word table has two alignments that read alike: `alignment` places the
432
432
  // table on the page and `columnAlignments` sets the text of each column.
433
- // A list written into the first used to be serialized verbatim into the
433
+ // A list written into the first would be serialized verbatim into the
434
434
  // table's justification and refused by Word's schema at finalize.
435
435
  function docxTableAlignmentFaults(format, name, operation, index) {
436
436
  const properties = operation.properties;
@@ -118,7 +118,7 @@ export async function ensureOfficeSessionDesign(
118
118
  session.designRequest = mergeOfficeDesignRequest(session.designRequest, args.design);
119
119
  // A native document stays native: the `design` a later call carries is the
120
120
  // page review (reviewed, reviewToken, critique) or content, not a request
121
- // for a preset. Resolving it as one used to hand a Word or Excel file the
121
+ // for a preset. Resolving it as one would hand a Word or Excel file the
122
122
  // default profile's palette and art direction it never asked for, and put
123
123
  // the preset review's gates in front of finalize.
124
124
  session.design =
@@ -108,9 +108,9 @@ export function normalizeOfficeContentModel(value) {
108
108
  const id = safeId(claim.id, 'claim id', `claim ${index + 1}${claim?.text ? `: ${claim.text}` : ''}`);
109
109
  if (claimIds.has(id)) throw new Error(`Office content model has duplicate claim id ${id}`);
110
110
  claimIds.add(id);
111
- // The references are the point of a claim: naming them "facts" instead of
112
- // factIds used to bind the claim to nothing at all, and the deck then
113
- // reported the figure it carried as unsourced.
111
+ // The references are the point of a claim, so `facts` is accepted as an
112
+ // alias of `factIds`: a claim written with either name stays bound to its
113
+ // sources instead of reporting the figure it carried as unsourced.
114
114
  let references = [];
115
115
  if (Array.isArray(claim.factIds)) references = claim.factIds;
116
116
  else if (Array.isArray(claim.facts)) references = claim.facts;
@@ -39,10 +39,10 @@ function writeSectionHeading(w, section) {
39
39
  function writeSectionList(w, section, sectionKind, blockFollows = false) {
40
40
  const { append, colors, type, bodySize, spacing } = w;
41
41
  const sectionBullets = strings(section.bullets);
42
- // A section that names steps draws them. They used to reach the page only
43
- // when the section also declared kind:'roadmap', so a plan section landed as
44
- // a heading with nothing under it - and the audit reported the orphan heading
45
- // the composer had just written.
42
+ // A section that names steps draws them. Reaching the page only with
43
+ // kind:'roadmap' would land a plan section as a heading with nothing under
44
+ // it - and the audit would report the orphan heading the composer had just
45
+ // written.
46
46
  const sectionSteps = Array.isArray(section.steps) ? section.steps : [];
47
47
  const stepSource = sectionSteps.length ? sectionSteps : sectionBullets;
48
48
  const drewSteps =
@@ -76,8 +76,8 @@ function writeSectionList(w, section, sectionKind, blockFollows = false) {
76
76
  });
77
77
  }
78
78
 
79
- // What a section can carry. A field outside this list used to vanish: a plan written as `roadmap:[…]` reached the
80
- // page as a heading with nothing under it, and the composer reported success.
79
+ // What a section can carry. A field outside this list would vanish: a plan written as `roadmap:[…]` would reach the
80
+ // page as a heading with nothing under it, and the composer would report success.
81
81
  const SECTION_FIELDS = new Set([
82
82
  'heading',
83
83
  'title',
@@ -197,7 +197,7 @@ export function addXlsxDecisionPanel(
197
197
  cursor += 1;
198
198
  });
199
199
  }
200
- // The actions follow the gates rather than stand in for them: given both, the actions used to be dropped.
200
+ // The actions follow the gates rather than stand in for them: given both, the actions would be dropped.
201
201
  if (gateRows.length && strings(actions).length) cursor += 1;
202
202
  for (const action of strings(actions).slice(0, 4)) {
203
203
  mergedBlock(output, {
@@ -417,7 +417,7 @@ function metricLabelStyle({ colors, type, dashboard }) {
417
417
  // metric is the one the strip paints as the headline, so the wider card reads
418
418
  // as emphasis rather than as a card that ran out of room.
419
419
  // More cards than columns wrap onto a second strip rather than pulling the
420
- // canvas past the table: a three-metric strip over a two-column table used to
420
+ // canvas past the table: a three-metric strip over a two-column table would
421
421
  // make every band half again as wide as the table under it.
422
422
  // The text a card's value shows under its number format ("47.0%" for 0.47 under 0.0%, "12명" for 12 under 0"명").
423
423
  function metricDisplayText(metric) {
@@ -9,7 +9,7 @@ import { workerExecArgv } from '../../shared/worker-exec-argv.mjs';
9
9
  const ENGINE_URL = new URL('./ocr-engine-worker.mjs', import.meta.url);
10
10
 
11
11
  /** The start includes the first-use download; without network it fails or hangs. */
12
- export const OCR_ENGINE_START_TIMEOUT_MS = 90_000;
12
+ const OCR_ENGINE_START_TIMEOUT_MS = 90_000;
13
13
 
14
14
  const engines = new Map();
15
15
 
@@ -13,10 +13,10 @@ const HEADING_SIZES = Object.freeze({ 1: 16, 2: 13, 3: 12 });
13
13
 
14
14
  const FLOW_FIELDS = ['before', 'after', 'x', 'width', 'color', 'align'];
15
15
 
16
- // What each block actually takes. A block the writer cannot read used to flow
17
- // as an empty paragraph: a table or a list written under the wrong key left no
18
- // mark on the page and no word in the result, so the report shipped without
19
- // the evidence it was asked for.
16
+ // What each block actually takes. A block the writer cannot read would flow
17
+ // as an empty paragraph: a table or a list written under the wrong key would
18
+ // leave no mark on the page and no word in the result, so the report would ship
19
+ // without the evidence it was asked for.
20
20
  const BLOCK_FIELDS = Object.freeze({
21
21
  paragraph: Object.freeze({ required: ['text'], optional: [...FLOW_FIELDS, 'size', 'lineHeight'] }),
22
22
  heading: Object.freeze({ required: ['text'], optional: [...FLOW_FIELDS, 'size', 'lineHeight', 'level'] }),
@@ -825,8 +825,8 @@ function styledDocxCell(cell, op) {
825
825
  }
826
826
 
827
827
  // A merged cell keeps what it carried (its shading, its borders, the bottom alignment a header row sits on, as Word
828
- // keeps them) and takes the spans; its width becomes the widths it joins. The whole tcPr used to be replaced, and a
829
- // two-level header's merged labels rose to the top of their cells on this backend only. Children stay in schema
828
+ // keeps them) and takes the spans; its width becomes the widths it joins. Replacing the whole tcPr would make a
829
+ // two-level header's merged labels rise to the top of their cells on this backend only. Children stay in schema
830
830
  // order: cnfStyle, tcW, gridSpan, vMerge, then the rest.
831
831
  function mergedCellXml(joined, spans) {
832
832
  const existing = /<w:tcPr(?:\s[^>]*)?>([\s\S]*?)<\/w:tcPr>/.exec(joined[0])?.[1] || '';
@@ -1,6 +1,7 @@
1
1
  import { basename, dirname, extname, join } from 'node:path';
2
2
  import { homedir, tmpdir } from 'node:os';
3
3
  import { execFile, spawn } from 'node:child_process';
4
+ import { treeKillCommand } from '../../agent/orchestrator/mcp/child-tree.mjs';
4
5
  import { redactDirectories } from '../../shared/redact-directories.mjs';
5
6
  import { removeDirectoryWithRetry } from '../../shared/remove-directory.mjs';
6
7
  import { constants as fsConstants, rmSync } from 'node:fs';
@@ -53,11 +54,11 @@ const SOFFICE_KILL_GRACE_MS = 10_000;
53
54
  // launcher leaves running (and holding the files it was given); Windows needs
54
55
  // the whole tree stopped.
55
56
  // The tree is stopped asynchronously and the helper itself is bounded, so a
56
- // cancellation never blocks the event loop or waits on a stuck taskkill.
57
- const SOFFICE_TASKKILL_TIMEOUT_MS = 5_000;
57
+ // cancellation never blocks the event loop or waits on a stuck tree kill.
58
+ const SOFFICE_TREE_KILL_TIMEOUT_MS = 5_000;
58
59
 
59
- // The launcher is killed only once taskkill is done (or out of time): a launcher
60
- // that exits first leaves taskkill with no descendants to find.
60
+ // The launcher is killed only once the tree kill is done (or out of time): a
61
+ // launcher that exits first leaves the tree kill with no descendants to find.
61
62
  function killProcessTree(child) {
62
63
  if (process.platform !== 'win32' || !child.pid) {
63
64
  killQuietly(child);
@@ -71,7 +72,8 @@ function killProcessTree(child) {
71
72
  };
72
73
  let killer = null;
73
74
  try {
74
- killer = spawn('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true, stdio: 'ignore' });
75
+ const { command, args } = treeKillCommand([child.pid]);
76
+ killer = spawn(command, args, { windowsHide: true, stdio: 'ignore' });
75
77
  } catch {
76
78
  killLauncher();
77
79
  return;
@@ -79,7 +81,7 @@ function killProcessTree(child) {
79
81
  const bound = setTimeout(() => {
80
82
  killQuietly(killer);
81
83
  killLauncher();
82
- }, SOFFICE_TASKKILL_TIMEOUT_MS);
84
+ }, SOFFICE_TREE_KILL_TIMEOUT_MS);
83
85
  bound.unref?.();
84
86
  const settle = () => {
85
87
  clearTimeout(bound);
@@ -290,7 +290,7 @@ const VALIDATION_CHOICE_RANGE = /^(?:'[^']+'!|[A-Za-z_][\w.]*!)?\$?[A-Z]{1,3}\$?
290
290
 
291
291
  // A dropdown names its choices — "서울,부산" — or points at the cells holding
292
292
  // them; anything that compares, calls, or tests is a rule the sheet evaluates.
293
- export function listValidationFormula(formula1) {
293
+ function listValidationFormula(formula1) {
294
294
  const text = String(formula1 ?? '')
295
295
  .trim()
296
296
  .replace(/^=/, '');
@@ -34,6 +34,14 @@ export function writeJsonAtomicSync(
34
34
  options?: AtomicFileOptions & { compact?: boolean }
35
35
  ): boolean;
36
36
 
37
+ /** Locked read-modify-write: `mutator` gets the current value (null when
38
+ * missing) and returns the next one, or undefined to leave the file as is. */
39
+ export function updateJsonAtomic<T = unknown>(
40
+ filePath: string,
41
+ mutator: (current: unknown) => T | undefined,
42
+ options?: AtomicFileOptions & { compact?: boolean }
43
+ ): Promise<T | unknown>;
44
+
37
45
  export interface JsonStateOptions<T> {
38
46
  /** Maps the parsed value; throwing marks the file damaged. */
39
47
  validate?: (value: unknown) => T;
@@ -243,8 +243,13 @@ export function getBackgroundTask(taskId, options = {}) {
243
243
  return task;
244
244
  }
245
245
 
246
- function countsAsActive(task, wanted, awaitedOnly) {
247
- return task.status === 'running' && !(awaitedOnly && task.detached === true) && (!wanted || task.surface === wanted);
246
+ function countsAsActive(task, wanted, awaitedOnly, match = null) {
247
+ return (
248
+ task.status === 'running' &&
249
+ !(awaitedOnly && task.detached === true) &&
250
+ (!wanted || task.surface === wanted) &&
251
+ (!match || match(task) === true)
252
+ );
248
253
  }
249
254
 
250
255
  /** Lifetime signal: a session-owned background task remains live
@@ -256,9 +261,14 @@ function countsAsActive(task, wanted, awaitedOnly) {
256
261
  export function hasActiveBackgroundTasks(options = {}) {
257
262
  const wanted = clean(options.surface);
258
263
  const awaitedOnly = options.awaitedOnly === true;
264
+ // Optional caller predicate over the running task (background-wait.mjs).
265
+ const match = typeof options.match === 'function' ? options.match : null;
259
266
  const scope = normalizeTaskScope(options);
260
267
  for (const task of tasks.values()) {
261
- if (countsAsActive(task, wanted, awaitedOnly) && taskMatchesScope(task, scope, { includeUnattributed: false })) {
268
+ if (
269
+ countsAsActive(task, wanted, awaitedOnly, match) &&
270
+ taskMatchesScope(task, scope, { includeUnattributed: false })
271
+ ) {
262
272
  return true;
263
273
  }
264
274
  }
@@ -565,10 +575,18 @@ export function reconcileBackgroundTask(
565
575
 
566
576
  export function renderBackgroundTaskNotification(task) {
567
577
  if (!task) return '';
568
- const result =
578
+ const body =
569
579
  task.surface === 'agent' && typeof task.result?.content === 'string'
570
580
  ? task.result.content
571
581
  : resultTextForTask(task);
582
+ // An owner-supplied trailer (an agent's unfinished todo items).
583
+ let appendix = '';
584
+ try {
585
+ appendix = typeof task.reportAppendix === 'function' ? String(task.reportAppendix() || '') : '';
586
+ } catch {
587
+ appendix = '';
588
+ }
589
+ const result = appendix ? [body, appendix].filter(Boolean).join('\n\n') : body;
572
590
  if (task.surface === 'shell') {
573
591
  const parsed = parseTaskNotification(result);
574
592
  // The completion envelope already carries the result (exit code,
@@ -0,0 +1,66 @@
1
+ // The one rule for "this session is waiting on work that will wake it": an
2
+ // agent it started is still running, or a background shell job it started in
3
+ // the CURRENT user cycle (since its last genuine user prompt) is still
4
+ // running — started with `background: true` or moved to the background after
5
+ // its hold alike; its completion arrives as a task notification. Running jobs
6
+ // from earlier cycles (long-lived servers, watchers) and the processes a
7
+ // finished command left behind (`detached`) never count. The cycle is stamped
8
+ // on the job when it starts (stampShellJobCycle), never read from its command.
9
+ // Shared by the end-of-turn todo completion check and Goal auto-continuation.
10
+ import { clean } from './clean.mjs';
11
+ import { hasActiveBackgroundTasks } from './background-tasks.mjs';
12
+
13
+ // Session id -> its user cycle number. In memory like the shell jobs it
14
+ // stamps: a restarted process has no running jobs from an earlier cycle.
15
+ const userCycles = new Map();
16
+
17
+ /** A genuine user prompt opened a new cycle for `sessionId`. */
18
+ export function beginUserCycle(sessionId) {
19
+ const id = clean(sessionId);
20
+ if (id) userCycles.set(id, (userCycles.get(id) || 0) + 1);
21
+ }
22
+
23
+ const currentUserCycle = (sessionId) => userCycles.get(clean(sessionId)) || 0;
24
+
25
+ /** Record on a starting background shell job the owner's current cycle. */
26
+ export function stampShellJobCycle(task) {
27
+ if (task?.ownerSessionId) task.userCycle = currentUserCycle(task.ownerSessionId);
28
+ return task;
29
+ }
30
+
31
+ const ACTIVE_AGENT_STATUSES = new Set([
32
+ 'connecting',
33
+ 'requesting',
34
+ 'streaming',
35
+ 'tool_running',
36
+ 'running',
37
+ 'cancelling',
38
+ ]);
39
+
40
+ /** A running agent among published status rows (`agentJobs` / `agentWorkers`). */
41
+ function runningAgentWork(agentStatus) {
42
+ const jobs = Array.isArray(agentStatus?.agentJobs) ? agentStatus.agentJobs : [];
43
+ if (jobs.some((job) => clean(job?.status).toLowerCase() === 'running')) return true;
44
+ const workers = Array.isArray(agentStatus?.agentWorkers) ? agentStatus.agentWorkers : [];
45
+ return workers.some((worker) => {
46
+ const status = clean(worker?.status).toLowerCase();
47
+ const stage = clean(worker?.stage || worker?.worker_stage).toLowerCase();
48
+ return ACTIVE_AGENT_STATUSES.has(status) || ACTIVE_AGENT_STATUSES.has(stage);
49
+ });
50
+ }
51
+
52
+ /** Whether `sessionId` waits on an agent or an awaited background shell. */
53
+ export function awaitingBackgroundWork({ sessionId = null, agentStatus = null } = {}) {
54
+ if (runningAgentWork(agentStatus)) return true;
55
+ const id = clean(sessionId);
56
+ if (!id) return false;
57
+ return (
58
+ hasActiveBackgroundTasks({ callerSessionId: id, surface: 'agent' }) ||
59
+ hasActiveBackgroundTasks({
60
+ callerSessionId: id,
61
+ surface: 'shell',
62
+ awaitedOnly: true,
63
+ match: (task) => task.userCycle === currentUserCycle(id),
64
+ })
65
+ );
66
+ }
@@ -1,5 +1,6 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import { randomUUID } from 'node:crypto';
3
+ import { TREE_KILL_DEADLINE_MS, treeKillCommand } from '../agent/orchestrator/mcp/child-tree.mjs';
3
4
  import { positiveInt } from './numbers.mjs';
4
5
  import { isPidAlive } from './pid-liveness.mjs';
5
6
  import { detachedSpawnOpts } from './spawn-flags.mjs';
@@ -46,15 +47,18 @@ function alive(pid) {
46
47
  try { process.kill(pid, 0); return true; }
47
48
  catch (error) { return error && error.code === 'EPERM'; }
48
49
  }
50
+ // Windows: the owner's creation-checked tree kill (child-tree.mjs), built when
51
+ // the child was registered. A signal there is a forced kill either way.
49
52
  function killTarget(target, force) {
50
53
  if (platform === 'win32') {
51
- const systemRoot = process.env.SystemRoot || process.env.WINDIR || 'C:\\\\Windows';
52
- const taskkill = systemRoot + '\\\\System32\\\\taskkill.exe';
53
- if (force) {
54
- try { spawnSync(taskkill, ['/PID', String(target.childPid), '/T', '/F'], { stdio: 'ignore', windowsHide: true }); } catch {}
55
- } else {
56
- try { process.kill(target.childPid, 'SIGTERM'); } catch {}
57
- try { spawnSync(taskkill, ['/PID', String(target.childPid), '/T'], { stdio: 'ignore', windowsHide: true }); } catch {}
54
+ if (target.killCommand) {
55
+ try {
56
+ spawnSync(target.killCommand.command, target.killCommand.args, {
57
+ stdio: 'ignore',
58
+ windowsHide: true,
59
+ timeout: target.killCommand.timeoutMs,
60
+ });
61
+ } catch {}
58
62
  }
59
63
  return;
60
64
  }
@@ -84,6 +88,8 @@ function accept(message) {
84
88
  orphanGraceMs: Math.max(100, Number(message.orphanGraceMs) || 3000),
85
89
  forceGraceMs: Math.max(100, Number(message.forceGraceMs) || 3000),
86
90
  receiptPath: typeof message.receiptPath === 'string' ? message.receiptPath : null,
91
+ killCommand: message.killCommand && typeof message.killCommand.command === 'string'
92
+ && Array.isArray(message.killCommand.args) && message.killCommand.timeoutMs > 0 ? message.killCommand : null,
87
93
  orphanedAt: 0,
88
94
  lastPolledAt: 0,
89
95
  killing: false,
@@ -255,6 +261,10 @@ export function startChildGuardian({
255
261
  orphanGraceMs: Math.max(100, Math.floor(Number(orphanGraceMs) || Number(graceMs) || 3000)),
256
262
  forceGraceMs: Math.max(100, Math.floor(Number(forceGraceMs) || Number(graceMs) || 3000)),
257
263
  receiptPath: typeof receiptPath === 'string' && receiptPath ? receiptPath : null,
264
+ // The child runs now, so its creation time bounds every later kill.
265
+ // Held to the shared deadline, so a hung pass never stalls the guardian.
266
+ killCommand:
267
+ process.platform === 'win32' ? { ...treeKillCommand([child]), timeoutMs: TREE_KILL_DEADLINE_MS } : null,
258
268
  onRemoved: () => {
259
269
  stopped = true;
260
270
  },