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
@@ -6,9 +6,12 @@
6
6
  // grandchildren (uv.exe -> mcp-for-unity.exe -> python.exe) orphaned. This
7
7
  // module implements the MCP spec shutdown order over the whole process tree:
8
8
  // close stdin -> grace wait for voluntary exit -> force-kill the recorded
9
- // tree (taskkill /T /F on Windows, SIGTERM->SIGKILL of every descendant on
10
- // POSIX). No external dependencies.
11
- import { spawn } from 'node:child_process';
9
+ // tree (the creation-checked tree kill below on Windows, SIGTERM->SIGKILL of
10
+ // every descendant on POSIX). No external dependencies.
11
+ //
12
+ // It also owns Mixdog's one Windows process-tree kill (treeKillCommand), which
13
+ // every other Windows tree kill runs, sync, async or detached.
14
+ import { spawn, spawnSync } from 'node:child_process';
12
15
  import { runProcessOffThread } from '../../../shared/process-runner.mjs';
13
16
  import { detachedSpawnOpts } from '../../../shared/spawn-flags.mjs';
14
17
 
@@ -49,13 +52,21 @@ export const ENUMERATION_DEADLINE_MS = 20_000;
49
52
  // Output bound of one helper command: a process table is tens of KB.
50
53
  const HELPER_MAX_BYTES = 64 * 1024 * 1024;
51
54
 
52
- // Run a helper command off the event loop (process-runner.mjs: under load one
53
- // PowerShell start blocked the daemon's loop for seconds) and resolve its
54
- // stdout. Past `timeoutMs` (default ENUMERATION_DEADLINE_MS) the helper is
55
- // killed and the call settles. Strict: a failed, non-zero or timed-out run
56
- // rejects; otherwise it resolves '' (non-zero exits keep their stdout).
55
+ // Run a helper command (a process-table read or a tree kill) off the event
56
+ // loop (process-runner.mjs: under load one PowerShell start blocked the
57
+ // daemon's loop for seconds). Past `timeoutMs` the helper itself is killed
58
+ // directly: it starts nothing worth walking, and a tree kill of it would be
59
+ // one more pass on the same stuck table read, with a deadline of its own.
60
+ function runHelper(cmd, args, timeoutMs) {
61
+ return runProcessOffThread(cmd, args, { timeoutMs, maxBytes: HELPER_MAX_BYTES, killTree: false });
62
+ }
63
+
64
+ // A process-table helper's stdout. Past `timeoutMs` (default
65
+ // ENUMERATION_DEADLINE_MS) the helper is killed and the call settles. Strict:
66
+ // a failed, non-zero or timed-out run rejects; otherwise it resolves ''
67
+ // (non-zero exits keep their stdout).
57
68
  function run(cmd, args, { strict = false, timeoutMs = ENUMERATION_DEADLINE_MS } = {}) {
58
- return runProcessOffThread(cmd, args, { timeoutMs, maxBytes: HELPER_MAX_BYTES }).then(
69
+ return runHelper(cmd, args, timeoutMs).then(
59
70
  ({ code, stdout }) => {
60
71
  if (strict && code !== 0) throw new Error(`Process enumeration failed (${code}).`);
61
72
  return stdout;
@@ -147,27 +158,41 @@ export function readProcessTable() {
147
158
  return nextTable;
148
159
  }
149
160
 
161
+ // Windows keeps a dead parent's pid in its children and hands that pid to new
162
+ // processes, so an older process can look like a newer one's child: wininit.exe
163
+ // still names its boot-time parent's pid, and a tree walked from whatever holds
164
+ // that pid now reaches services.exe and every service host under it. A child is
165
+ // never created before its parent, so on Windows a link is followed only from a
166
+ // process whose creation time is known, to one created no earlier. POSIX
167
+ // reparents orphans, so its links never dangle.
168
+ const createdTicks = (token) => (typeof token === 'string' && /^\d+$/.test(token) ? BigInt(token) : null);
169
+
150
170
  // Walk every descendant pid of rootPid (excludes rootPid).
151
- function descendantsOf(childrenOf, rootPid) {
171
+ function descendantsOf(childrenOf, rootPid, tokenOf) {
152
172
  const result = [];
153
173
  const seen = new Set([rootPid]);
154
174
  const stack = [rootPid];
155
175
  while (stack.length) {
156
176
  const cur = stack.pop();
177
+ const parentCreated = isWin ? createdTicks(tokenOf.get(cur)) : null;
178
+ if (isWin && parentCreated == null) continue;
157
179
  for (const child of childrenOf.get(cur) ?? []) {
158
- if (!seen.has(child)) {
159
- seen.add(child);
160
- result.push(child);
161
- stack.push(child);
180
+ if (seen.has(child)) continue;
181
+ if (isWin) {
182
+ const childCreated = createdTicks(tokenOf.get(child));
183
+ if (childCreated == null || childCreated < parentCreated) continue;
162
184
  }
185
+ seen.add(child);
186
+ result.push(child);
187
+ stack.push(child);
163
188
  }
164
189
  }
165
190
  return result;
166
191
  }
167
192
 
168
193
  async function collectDescendants(rootPid) {
169
- const { childrenOf } = await enumerate();
170
- return descendantsOf(childrenOf, rootPid);
194
+ const { childrenOf, tokenOf } = await enumerate();
195
+ return descendantsOf(childrenOf, rootPid, tokenOf);
171
196
  }
172
197
 
173
198
  /** Descendant pids WITH their image names and identity tokens (creation
@@ -177,24 +202,163 @@ export async function collectDescendantProcesses(rootPid, { strict = false } = {
177
202
  const { childrenOf, nameOf, tokenOf } = strict
178
203
  ? await snapshot
179
204
  : await snapshot.catch(() => ({ childrenOf: new Map(), nameOf: new Map(), tokenOf: new Map() }));
180
- return descendantsOf(childrenOf, rootPid).map((pid) => ({
205
+ return descendantsOf(childrenOf, rootPid, tokenOf).map((pid) => ({
181
206
  pid,
182
207
  name: nameOf.get(pid) || '',
183
208
  token: tokenOf.get(pid) ?? null,
184
209
  }));
185
210
  }
186
211
 
187
- /** Force-kill whole process trees by pid. Windows batches one taskkill /T /F
188
- * for every pid; POSIX escalates SIGTERM → SIGKILL. Best-effort: the caller
212
+ const positivePids = (pids) => [...new Set((pids || []).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0))];
213
+
214
+ // The Windows tree kill, one PowerShell pass. taskkill /T is never used: it
215
+ // walks parent ids with no creation times, so it follows the dangling links
216
+ // descendantsOf refuses (on 2026-10-30 one such kill ended every user-owned
217
+ // service host and sihost.exe). A root counts only if it was created no later
218
+ // than -AliveAt (a pid taken over after the caller saw its process is not
219
+ // that process); a descendant only if created no earlier than its parent.
220
+ // Each process is ended through a handle whose start time matches the table.
221
+ // Exit: 0 ended, 128 no root matched (gone or a different process), 1 a root
222
+ // survived; a failed or timed-out table read fails the pass. The table read
223
+ // times out on its own (a pass detached from an exiting caller still ends);
224
+ // every spawn from Node is also held to TREE_KILL_DEADLINE_MS. -Table/-List: tests only, a
225
+ // stand-in table whose member pids are printed instead of ended.
226
+ export const TREE_KILL_SCRIPT = `param([int[]]$Pids, [long]$AliveAt, [object[]]$Table, [switch]$List)
227
+ $ErrorActionPreference = 'Stop'
228
+ $limit = [DateTime]::FromFileTimeUtc($AliveAt)
229
+ if ($Table) {
230
+ $rows = @(foreach ($t in $Table) { [pscustomobject]@{ Id = [int]$t.Id; Parent = [int]$t.Parent; Created = [DateTime]::FromFileTimeUtc([long]$t.Created) } })
231
+ } else {
232
+ $rows = @(Get-CimInstance Win32_Process -OperationTimeoutSec 10 | Where-Object CreationDate | ForEach-Object { [pscustomobject]@{ Id = [int]$_.ProcessId; Parent = [int]$_.ParentProcessId; Created = $_.CreationDate.ToUniversalTime() } })
233
+ }
234
+ $byId = @{}
235
+ $byParent = @{}
236
+ foreach ($r in $rows) {
237
+ $byId[$r.Id] = $r
238
+ if (-not $byParent.ContainsKey($r.Parent)) { $byParent[$r.Parent] = [Collections.Generic.List[object]]::new() }
239
+ $byParent[$r.Parent].Add($r)
240
+ }
241
+ $members = [Collections.Generic.List[object]]::new()
242
+ foreach ($id in $Pids) {
243
+ $r = $byId[$id]
244
+ if ($r -and $r.Created -le $limit -and -not $members.Contains($r)) { $members.Add($r) }
245
+ }
246
+ $roots = $members.Count
247
+ if ($roots -eq 0) { exit 128 }
248
+ for ($i = 0; $i -lt $members.Count; $i++) {
249
+ $parent = $members[$i]
250
+ if (-not $byParent.ContainsKey($parent.Id)) { continue }
251
+ foreach ($child in $byParent[$parent.Id]) {
252
+ if ($child.Created -ge $parent.Created -and -not $members.Contains($child)) { $members.Add($child) }
253
+ }
254
+ }
255
+ if ($List) { foreach ($m in $members) { $m.Id }; exit 0 }
256
+ $survived = $false
257
+ for ($i = 0; $i -lt $members.Count; $i++) {
258
+ $m = $members[$i]
259
+ try { $p = [Diagnostics.Process]::GetProcessById($m.Id) } catch { continue }
260
+ try { $same = [math]::Abs(($p.StartTime.ToUniversalTime() - $m.Created).TotalMilliseconds) -lt 1 } catch { $same = $null }
261
+ if ($same -eq $false) { continue }
262
+ # A start time that cannot be read proves nothing: the process is left alone,
263
+ # and a root left alone counts as surviving.
264
+ if ($null -eq $same) { if ($i -lt $roots) { $survived = $true }; continue }
265
+ try { $p.Kill() } catch {}
266
+ if ($i -lt $roots) { try { if (-not $p.WaitForExit(2000)) { $survived = $true } } catch { $survived = $true } }
267
+ }
268
+ if ($survived) { exit 1 }
269
+ exit 0`;
270
+
271
+ const fileTime = (ms) => BigInt(Math.floor(Number(ms))) * 10_000n + 116_444_736_000_000_000n;
272
+
273
+ /** The command of one Windows tree kill of `pids` (see TREE_KILL_SCRIPT), for
274
+ * callers that spawn it themselves: awaited, synchronous, or detached and
275
+ * unref'd so it outlives an exiting caller. `aliveAt` (epoch ms): when the
276
+ * caller last knew each pid was its process (a live child handle: now; a
277
+ * pid file: when it was written). `table`: tests only, rows { pid, ppid,
278
+ * created (epoch ms) } standing in for the live table; the command then
279
+ * prints the member pids instead of ending them. */
280
+ export function treeKillCommand(pids, { aliveAt = Date.now(), table = null } = {}) {
281
+ const rows = table
282
+ ? ` -List -Table @(${table.map((row) => `@{Id=${row.pid};Parent=${row.ppid};Created=${fileTime(row.created)}}`).join(',')})`
283
+ : '';
284
+ const source = `& {\n${TREE_KILL_SCRIPT}\n} -Pids @(${positivePids(pids).join(',')}) -AliveAt ${fileTime(aliveAt)}${rows}`;
285
+ const systemRoot = process.env.SystemRoot || process.env.WINDIR || 'C:\\Windows';
286
+ return {
287
+ command: `${systemRoot}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`,
288
+ args: ['-NoProfile', '-NonInteractive', '-EncodedCommand', Buffer.from(source, 'utf16le').toString('base64')],
289
+ };
290
+ }
291
+
292
+ /** The hard lifetime of one tree-kill pass, enforced from Node whatever the
293
+ * table read does (its own timeout is 10 s). */
294
+ export const TREE_KILL_DEADLINE_MS = 15_000;
295
+
296
+ /** The tree kill run synchronously (Windows only): its exit status (see
297
+ * TREE_KILL_SCRIPT), or null when it could not run or outlived `timeoutMs`. */
298
+ export function killProcessTreesSync(pids, { aliveAt = Date.now(), timeoutMs = TREE_KILL_DEADLINE_MS } = {}) {
299
+ const { command, args } = treeKillCommand(pids, { aliveAt });
300
+ return spawnSync(command, args, { stdio: 'ignore', windowsHide: true, timeout: timeoutMs }).status;
301
+ }
302
+
303
+ /** The tree kill spawned (Windows only) and held to TREE_KILL_DEADLINE_MS:
304
+ * past it the pass is killed. `root`: the caller's own ChildProcess, alive
305
+ * now; it is killed directly once the pass has ended, failed or run out of
306
+ * time, so a hung pass never keeps it alive. `detached`: the pass outlives
307
+ * an exiting caller and is bounded only by its own table-read timeout.
308
+ * Neither the pass nor its deadline keeps the caller's event loop alive.
309
+ * Returns the pass's ChildProcess, or null when it could not be spawned. */
310
+ export function spawnTreeKill(pids, { aliveAt = Date.now(), root = null, detached = false } = {}) {
311
+ const killRoot = () => {
312
+ try {
313
+ root?.kill();
314
+ } catch {
315
+ /* already gone */
316
+ }
317
+ };
318
+ let pass;
319
+ try {
320
+ const { command, args } = treeKillCommand(pids, { aliveAt });
321
+ pass = spawn(command, args, { stdio: 'ignore', ...detachedSpawnOpts });
322
+ } catch {
323
+ killRoot();
324
+ return null;
325
+ }
326
+ pass.unref?.();
327
+ if (detached) {
328
+ pass.once('error', killRoot);
329
+ return pass;
330
+ }
331
+ const deadline = setTimeout(() => {
332
+ try {
333
+ pass.kill();
334
+ } catch {
335
+ /* already gone */
336
+ }
337
+ killRoot();
338
+ }, TREE_KILL_DEADLINE_MS);
339
+ deadline.unref?.();
340
+ const settle = () => {
341
+ clearTimeout(deadline);
342
+ killRoot();
343
+ };
344
+ pass.once('error', settle);
345
+ pass.once('exit', settle);
346
+ return pass;
347
+ }
348
+
349
+ /** Force-kill whole process trees by pid. Windows runs the tree kill off the
350
+ * event loop and resolves to its exit status (null: it could not run or
351
+ * timed out); POSIX escalates SIGTERM → SIGKILL. Best-effort: the caller
189
352
  * verifies liveness afterwards rather than trusting the signal. */
190
- export async function killProcessTrees(pids) {
191
- const targets = [...new Set((pids || []).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0))];
192
- if (targets.length === 0) return;
353
+ export async function killProcessTrees(pids, { aliveAt = Date.now() } = {}) {
354
+ const targets = positivePids(pids);
355
+ if (targets.length === 0) return isWin ? 128 : undefined;
193
356
  if (isWin) {
194
- const args = ['/F', '/T'];
195
- for (const pid of targets) args.push('/PID', String(pid));
196
- await run('taskkill', args);
197
- return;
357
+ const { command, args } = treeKillCommand(targets, { aliveAt });
358
+ return runHelper(command, args, TREE_KILL_DEADLINE_MS).then(
359
+ ({ code }) => code,
360
+ () => null
361
+ );
198
362
  }
199
363
  for (const pid of targets) signalQuietly(pid, 'SIGTERM');
200
364
  await delay(300);
@@ -206,10 +370,10 @@ export async function killProcessTrees(pids) {
206
370
  /**
207
371
  * Immediate, non-blocking tree kill for a transport whose MCP handshake never
208
372
  * completed (shutdown-during-connect). Unlike shutdownStdioChild there is no
209
- * grace wait and no identity-checked enumeration on Windows — the ChildProcess
210
- * handle is live, so the pid is current, and taskkill /T reaps the still-
211
- * parented tree. Everything is unref'd/fire-and-forget so the kill can never
212
- * hold the caller's event loop open (the caller is a process about to exit).
373
+ * grace wait and no enumeration here — the ChildProcess handle is live, so the
374
+ * pid is current, and a detached tree kill reaps the still-parented tree after
375
+ * the caller is gone. Everything is unref'd/fire-and-forget so the kill can
376
+ * never hold the caller's event loop open (the caller is a process about to exit).
213
377
  */
214
378
  export function killStdioChildTreeFast(transport) {
215
379
  const proc = transport?._process;
@@ -234,15 +398,7 @@ export function killStdioChildTreeFast(transport) {
234
398
  }
235
399
  }
236
400
  if (isWin) {
237
- try {
238
- const cp = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], {
239
- stdio: 'ignore',
240
- ...detachedSpawnOpts,
241
- });
242
- cp.unref();
243
- } catch {
244
- /* ignore */
245
- }
401
+ spawnTreeKill([pid], { root: proc, detached: true });
246
402
  return true;
247
403
  }
248
404
  // POSIX: cheap ps enumerate, then SIGKILL descendants + root. Best-effort
@@ -308,11 +464,8 @@ async function killVerified(pids, snapshotToken, currentTokens) {
308
464
  const verified = pids.filter((pid) => stillSame(pid, snapshotToken, currentTokens));
309
465
  if (verified.length === 0) return;
310
466
  if (isWin) {
311
- // /T also reaps any still-live children spawned since enumeration;
312
- // every listed /PID was identity-checked just above.
313
- const args = ['/F', '/T'];
314
- for (const p of verified) args.push('/PID', String(p));
315
- await run('taskkill', args);
467
+ // Every listed pid was identity-checked just above.
468
+ await killProcessTrees(verified);
316
469
  return;
317
470
  }
318
471
  // POSIX: terminate, brief wait, then hard-kill survivors. Re-verify with a
@@ -339,7 +492,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
339
492
  // Snapshot #1: tree + identity tokens while it is still fully intact.
340
493
  // Covers children that later get re-parented/orphaned during shutdown.
341
494
  const before = await enumerate().catch(() => empty);
342
- const initial = descendantsOf(before.childrenOf, pid);
495
+ const initial = descendantsOf(before.childrenOf, pid, before.tokenOf);
343
496
  snapshotToken.set(pid, before.tokenOf.get(pid) ?? null);
344
497
  for (const d of initial) snapshotToken.set(d, before.tokenOf.get(d) ?? null);
345
498
  // 1. Close stdin to request a voluntary shutdown.
@@ -353,7 +506,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
353
506
  // 3. Snapshot #2 after the grace: catches children spawned late during
354
507
  // shutdown that were absent from the first snapshot.
355
508
  const after = await enumerate().catch(() => empty);
356
- const fresh = descendantsOf(after.childrenOf, pid);
509
+ const fresh = descendantsOf(after.childrenOf, pid, after.tokenOf);
357
510
  for (const d of fresh) {
358
511
  if (!snapshotToken.has(d)) snapshotToken.set(d, after.tokenOf.get(d) ?? null);
359
512
  }
@@ -8,11 +8,9 @@ import { rememberMcpToolIdentity } from '../../../shared/tool-primitives.mjs';
8
8
 
9
9
  /** Known auto-detect targets: the discovery-advert service name and the MCP
10
10
  * endpoint path on its port.
11
- * Note: `mixdog` used to self-loopback via active-instance.json's
12
- * httpPort, but that path went through channels' owner HTTP server which
13
- * only exposes a subset of tools. The plugin's own tools are now injected
14
- * in-process through agent's toolExecutor (see orchestrator/internal-tools),
15
- * so this registry is for genuinely external port-based MCP targets only. */
11
+ * The plugin's own tools are injected in-process through agent's
12
+ * toolExecutor (see orchestrator/internal-tools), so this registry is for
13
+ * genuinely external port-based MCP targets only. */
16
14
  export const AUTO_DETECT_PORTS = {
17
15
  'mixdog-memory': { discovery: 'memory', endpoint: '/mcp' },
18
16
  };
@@ -10,6 +10,8 @@ import { googleMcpService, withGoogleMcp } from '../../../connectors/google-mcp.
10
10
  import { gmailAppPasswordService, withGmailAppPasswordMcp } from '../../../connectors/gmail-app-password.mjs';
11
11
  import { withConnectorAccountsMcp } from '../../../connectors/connector-accounts-mcp.mjs';
12
12
  import {
13
+ connectorAccountEnabled,
14
+ connectorAccountId,
13
15
  connectorAccountsOf,
14
16
  connectorLiveAccountServers,
15
17
  gmailAppPasswordAccount,
@@ -271,9 +273,13 @@ function missingEnvWarnings(name, cfg, strictEnv, log) {
271
273
  // A connector server: one server, every account behind it (its account choice
272
274
  // on `connectorAccounts`); closing the transport closes every account client.
273
275
  function connectorAccountsTransport({ name, cfg, Transport, url, accountServers, sdk, oauthOptions, log }) {
274
- const accounts = accountServers.map((accountCfg) =>
275
- connectorAccountClient(name, accountCfg, { sdk, log, oauthOptions })
276
- );
276
+ // `accountServers` are the switched-on stored accounts, in order.
277
+ const stored = connectorAccountsOf(cfg).filter(connectorAccountEnabled);
278
+ const accounts = accountServers.map((accountCfg, index) => {
279
+ const account = connectorAccountClient(name, accountCfg, { sdk, log, oauthOptions });
280
+ account.id = connectorAccountId(cfg, stored[index]);
281
+ return account;
282
+ });
277
283
  const fetchImpl = withConnectorAccountsMcp({ connector: cfg.connector, accounts });
278
284
  const transport = new Transport(new URL(url), { fetch: fetchImpl });
279
285
  transport.connectorAccounts = fetchImpl.connectorAccounts;
@@ -54,8 +54,9 @@ import {
54
54
  export { probeMcpServerAuth } from './oauth-probe.mjs';
55
55
 
56
56
  // Config interpretation (transport kind, URL policy, env expansion, headers,
57
- // timeouts, log scrubbing) lives in client-config.mjs; re-exported so every
58
- // existing importer resolves unchanged.
57
+ // timeouts, log scrubbing) lives in client-config.mjs; the names importers
58
+ // use (including through namespace loads such as boot.mcpClient) are
59
+ // re-exported here.
59
60
  export {
60
61
  normalizeMcpTransportUrl,
61
62
  mcpUrlForLog,
@@ -64,9 +65,6 @@ export {
64
65
  resolveMcpHttpHeaders,
65
66
  resolveMcpTransportKind,
66
67
  resolveMcpStartupTimeoutMs,
67
- resolveMcpCallTimeoutMs,
68
- resolveMcpMaxTotalTimeoutMs,
69
- resolveMcpRequestTimeouts,
70
68
  } from './client-config.mjs';
71
69
  const servers = new Map();
72
70
  const reconnects = createKeyedSingleflight();
@@ -6,7 +6,7 @@
6
6
  // - else the catalog connector's (connector-catalog.mjs `oauthClient`), with
7
7
  // its scopes and the provider's offline-access parameter.
8
8
  import { createHash } from 'node:crypto';
9
- import keychain from '../../../../lib/keychain-cjs.cjs';
9
+ import { keychainSecretStore as keychain } from '../../../shared/config.mjs';
10
10
  import { connectorById, connectorOfServer, gmailAppPasswordAccount } from '../../../shared/connector-catalog.mjs';
11
11
  import { GOOGLE_AUTH_PARAMS, googleOAuthClient } from '../../../shared/google-oauth-client.mjs';
12
12
  import { normalizeMcpTransportUrl } from './client-config.mjs';
@@ -145,11 +145,16 @@ export function createCredentialCache({ url, credentialStore, account }) {
145
145
  }
146
146
  exists = Boolean(saved);
147
147
  }
148
+ const signedIn = Boolean(creds.tokens);
148
149
  change();
149
150
  hold();
151
+ // Other processes follow a refresh through the revision marker; only a
152
+ // sign-in or sign-out is announced as a settings change (it may let a
153
+ // server that needed sign-in connect, or end its connection).
154
+ const announce = remove ? signedIn : Boolean(creds.tokens) !== signedIn;
150
155
  if (remove) {
151
156
  await writeRevisionMarker(account, null);
152
- if (exists) await credentialStore.deleteSecretAsync(account);
157
+ if (exists) await credentialStore.deleteSecretAsync(account, { announce });
153
158
  await writeIdentityFile(account, null);
154
159
  creds.observed = null;
155
160
  } else {
@@ -158,7 +163,8 @@ export function createCredentialCache({ url, credentialStore, account }) {
158
163
  const { tokens, clientInformation, redirectUrl, discovery, identity } = creds;
159
164
  await credentialStore.setSecretAsync(
160
165
  account,
161
- JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity })
166
+ JSON.stringify({ url, revision, tokens, clientInformation, redirectUrl, discovery, identity }),
167
+ { announce }
162
168
  );
163
169
  await writeIdentityFile(account, creds);
164
170
  creds.observed = revision;
@@ -12,7 +12,7 @@ import {
12
12
  } from './client-config.mjs';
13
13
  import { hasConfiguredMcpAuth } from './client-transport.mjs';
14
14
 
15
- export const MCP_AUTH_PROBE_TIMEOUT_MS = 10_000;
15
+ const MCP_AUTH_PROBE_TIMEOUT_MS = 10_000;
16
16
 
17
17
  const INITIALIZE_PROBE = JSON.stringify({
18
18
  jsonrpc: '2.0',
@@ -145,6 +145,20 @@ export function createOAuthProvider({ cache, flow, lifetimeSignal, client = null
145
145
  // access_type=offline, without which no refresh token is issued).
146
146
  if (client?.scopes) target.searchParams.set('scope', client.scopes.join(' '));
147
147
  for (const [key, value] of Object.entries(client?.authParams || {})) target.searchParams.set(key, value);
148
+ // A dynamically registered client asks for offline access when the
149
+ // authorization server lists it (MCP SEP-2207): the SDK sends only the
150
+ // resource's scopes (Vercel's `openid`), and without `offline_access`
151
+ // such a server issues no refresh token, so the sign-in ends within the
152
+ // hour. `prompt=consent` is what the SDK adds beside that scope. An
153
+ // empty scope stays empty: the server's default scopes would be lost.
154
+ if (!client) {
155
+ const scope = target.searchParams.get('scope');
156
+ const offered = creds.discovery?.authorizationServerMetadata?.scopes_supported;
157
+ if (scope && offered?.includes('offline_access') && !scope.split(' ').includes('offline_access')) {
158
+ target.searchParams.set('scope', `${scope} offline_access`);
159
+ target.searchParams.append('prompt', 'consent');
160
+ }
161
+ }
148
162
  // The explicit sign-in's account mode (mcp-oauth-login.mjs) decides the
149
163
  // provider's documented account-choice parameter, if any.
150
164
  await flow.launchBrowser(withAccountParams(target.href, flow.launchBrowser.accountMode || 'connect').href);
@@ -1,6 +1,6 @@
1
1
  import { createHash, randomBytes } from 'node:crypto';
2
2
  import { readFileSync } from 'node:fs';
3
- import keychain from '../../../../lib/keychain-cjs.cjs';
3
+ import { keychainSecretStore as keychain } from '../../../shared/config.mjs';
4
4
  import { openInBrowser } from '../../../shared/open-url.mjs';
5
5
  import { normalizeMcpTransportUrl } from './client-config.mjs';
6
6
  import {
@@ -10,7 +10,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
10
10
  // source release just to advance the user-agent version.
11
11
  // Claude Opus 5.5 requires 2.1.280 or newer. The release workflow raises this
12
12
  // to the published CLI version (scripts/sync-client-version-floors.mjs).
13
- export const DEFAULT_CLI_VERSION = '2.1.312';
13
+ export const DEFAULT_CLI_VERSION = '2.1.316';
14
14
  export const CLAUDE_CLI_NPM_PACKAGE = '@anthropic-ai/claude-code';
15
15
 
16
16
  const CACHE_SCHEMA_VERSION = 1;
@@ -7,9 +7,9 @@
7
7
  import { makeInvalidToolArgsMarker } from '../../lib/openai-tool-args.mjs';
8
8
  import { OAUTH_STREAM_LABELS } from '../../lib/anthropic-stream-labels.mjs';
9
9
 
10
- // Bare JSON.parse used to throw straight up into the surrounding broad catch,
11
- // which swallowed the whole tool_call — the loop never saw it and the
12
- // assistant turn ended with an unmatched tool_use id. A malformed input still
10
+ // A bare JSON.parse would throw into the surrounding broad catch, which
11
+ // swallows the whole tool_call — the loop never sees it and the assistant
12
+ // turn ends with an unmatched tool_use id. A malformed input still
13
13
  // produces a tool_call (with an invalid-args marker and a logged error)
14
14
  // instead of a silent drop or accidental `{}` dispatch. Tool arguments must
15
15
  // be a plain object: Anthropic's tool_use input is always a JSON object, but
@@ -20,7 +20,7 @@ import { createNpmVersionSource, maxSemver } from './npm-cli-version.mjs';
20
20
  // version (gpt-6.1-sol requires >= 0.159.0, measured 2026-10-09), so the
21
21
  // release workflow raises this to the published CLI version on every release
22
22
  // (scripts/sync-client-version-floors.mjs).
23
- export const CODEX_CLIENT_VERSION_FLOOR = '0.165.0';
23
+ export const CODEX_CLIENT_VERSION_FLOOR = '0.166.0';
24
24
  export const CODEX_CLI_NPM_PACKAGE = '@openai/codex';
25
25
  const live = createNpmVersionSource(CODEX_CLI_NPM_PACKAGE, { persistKey: 'codex-cli' });
26
26
 
@@ -52,7 +52,7 @@ function budgetSpec(model) {
52
52
 
53
53
  // Levels documented for models whose ladder differs from the generic wire
54
54
  // vocabulary (a catalog ladder, when declared, still takes precedence).
55
- function documentedThinkingLevels(model) {
55
+ export function geminiDocumentedThinkingLevels(model) {
56
56
  const bare = String(model || '')
57
57
  .replace(/^models\//i, '')
58
58
  .toLowerCase();
@@ -105,7 +105,7 @@ export function geminiThinkingConfig(model, opts = {}, { includeThoughts, provid
105
105
  }
106
106
  config.thinkingBudget = spec.efforts[level];
107
107
  } else if (level) {
108
- const supported = catalogThinkingLevels(model, provider) ?? documentedThinkingLevels(model) ?? LEVELS;
108
+ const supported = catalogThinkingLevels(model, provider) ?? geminiDocumentedThinkingLevels(model) ?? LEVELS;
109
109
  if (!supported.includes(level)) {
110
110
  throw new TypeError(`${model} supports thinking levels ${supported.join(', ')}; received ${level}.`);
111
111
  }
@@ -234,12 +234,10 @@ export function normalizeCompatChatResponse({
234
234
  model: response.model || useModel,
235
235
  toolCalls,
236
236
  stopReason,
237
- // P1 audit fix: a text-only completion that hit finish_reason=
238
- // 'length' (no tool calls, so not thrown above as
239
- // ProviderIncompleteError) previously returned as an ordinary
240
- // success with no signal that the content is a mid-sentence
241
- // cutoff. Flag it so loop.mjs can surface a one-line warning
242
- // instead of silently treating a truncated answer as complete.
237
+ // A text-only completion that hit finish_reason='length' (no tool
238
+ // calls, so not thrown above as ProviderIncompleteError) is flagged so
239
+ // loop.mjs can surface a one-line warning instead of silently treating
240
+ // a mid-sentence cutoff as complete.
243
241
  ...(stopReason === 'length' && (assembled.content || '').length > 0 ? { truncated: true } : {}),
244
242
  ...(reasoningContent !== null ? { reasoningContent } : {}),
245
243
  ...(Object.keys(providerMetadata).length ? { providerMetadata } : {}),