mixdog 1.4.1 → 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 (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -20,7 +20,7 @@ import { cwdWithinProjects } from '../../../shared/extension-scopes.mjs';
20
20
  import { resolvePluginData } from '../../../shared/plugin-paths.mjs';
21
21
  import { mixyIdentityDir, userDefinitionDir } from '../../../shared/agent-store.mjs';
22
22
  import { isSelfMcpToolName, parseMcpToolName } from '../../../shared/tool-primitives.mjs';
23
- import { connectorToolDefault } from '../../../shared/connector-catalog.mjs';
23
+ import { connectorById, connectorToolDefault } from '../../../shared/connector-catalog.mjs';
24
24
  import { MIXY_AGENT_ID } from '../session/agent-home.mjs';
25
25
  import { AGENT_MODE, sessionModeOf } from '../session/agent-mode.mjs';
26
26
  import { serverConnector } from './server-connectors.mjs';
@@ -214,12 +214,43 @@ export function connectorToolPermission(policy, toolOrName) {
214
214
  const mcp = parseMcpToolName(toolOrName);
215
215
  if (!mcp || isSelfMcpToolName(toolOrName)) return 'auto';
216
216
  if (policy && !connectorEnabled(policy, mcp.server)) return 'disabled';
217
- // An explicit per-tool entry decides; otherwise a catalog connector's
218
- // high-risk tools ask (connectorToolDefault) and any other tool is auto.
219
- return policy?.tools?.[mcp.server]?.[mcp.tool] || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
217
+ // An explicit per-tool entry of the tool's connector decides; otherwise a
218
+ // catalog connector's high-risk tools ask (connectorToolDefault) and any
219
+ // other tool is auto.
220
+ const [own] = connectorToolEntries(policy?.tools, connectorGroupId(mcp.server), mcp.tool);
221
+ return own || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
220
222
  }
221
223
 
222
224
  export const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
225
+
226
+ /** The connector a server (account) belongs to: `gmail-2` → `gmail` for a
227
+ * catalog connector; any other id is its own. A tool's permission is stored
228
+ * once, under this id, and governs every account. */
229
+ export function connectorGroupId(serverId) {
230
+ const base = String(serverId).replace(/-\d+$/, '');
231
+ return base !== serverId && connectorById(base) ? base : serverId;
232
+ }
233
+
234
+ const accountNumber = (id) => Number(/-(\d+)$/.exec(id)?.[1] ?? 0);
235
+
236
+ /** The entries for `tool` under the connector `group` or any of its accounts,
237
+ * topmost first: the connector's own, then the lowest-numbered account. An
238
+ * account only holds one in data saved before permissions were kept per
239
+ * connector; the first entry is the one that applies. */
240
+ export function connectorToolEntries(tools, group, tool) {
241
+ return Object.entries(tools || {})
242
+ .filter(([id, own]) => connectorGroupId(id) === group && CONNECTOR_PERMISSIONS.includes(own?.[tool]))
243
+ .sort(([a], [b]) => accountNumber(a) - accountNumber(b))
244
+ .map(([, own]) => own[tool]);
245
+ }
246
+
247
+ const UNLISTED_ACCOUNT = '\0unlisted account';
248
+
249
+ /** Rank of `tool` on one account of connector `group`: 0 when that account is
250
+ * off, else the topmost entry for the connector, else `unset` (no override:
251
+ * at least asks / at most runs freely). */
252
+ const accountRank = (tools, off, account, group, tool, unset) =>
253
+ off.has(account) ? 0 : (PERMISSION_RANK[connectorToolEntries(tools, group, tool)[0]] ?? unset);
223
254
  export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do without asking; make it on the desktop.';
224
255
 
225
256
  /** Whether replacing the stored policy `before` (a stored value, a parsed
@@ -243,21 +274,102 @@ function connectorPolicyWidens(before, after) {
243
274
  for (const server of offBefore) if (!offAfter.has(server)) return true;
244
275
  const toolsBefore = old.tools || {};
245
276
  const toolsAfter = next.tools || {};
246
- for (const server of new Set([...Object.keys(toolsBefore), ...Object.keys(toolsAfter)])) {
247
- const tools = new Set([...Object.keys(toolsBefore[server] || {}), ...Object.keys(toolsAfter[server] || {})]);
248
- for (const tool of tools) {
249
- // No override: at least asks / at most runs freely.
250
- const was = offBefore.has(server) ? 0 : (PERMISSION_RANK[toolsBefore[server]?.[tool]] ?? 1);
251
- const now = offAfter.has(server) ? 0 : (PERMISSION_RANK[toolsAfter[server]?.[tool]] ?? 2);
277
+ // Judged per connector and tool: the accounts of one connector share them.
278
+ const pairs = new Set(
279
+ [toolsBefore, toolsAfter].flatMap((tools) =>
280
+ Object.entries(tools).flatMap(([id, own]) =>
281
+ Object.keys(own || {}).map((tool) => `${connectorGroupId(id)}\0${tool}`)
282
+ )
283
+ )
284
+ );
285
+ for (const pair of pairs) {
286
+ const [group, tool] = pair.split('\0');
287
+ // Each account on its own: one that is off does not hold back its siblings.
288
+ // Plus one account the policy never names: it is on in both policies, so it
289
+ // stands for every installed account that is not listed.
290
+ const accounts = new Set([
291
+ UNLISTED_ACCOUNT,
292
+ ...[group, ...offBefore, ...offAfter, ...Object.keys(toolsBefore), ...Object.keys(toolsAfter)].filter(
293
+ (id) => connectorGroupId(id) === group
294
+ ),
295
+ ]);
296
+ for (const account of accounts) {
297
+ const was = accountRank(toolsBefore, offBefore, account, group, tool, 1);
298
+ const now = accountRank(toolsAfter, offAfter, account, group, tool, 2);
252
299
  if (now > was) return true;
253
300
  }
254
301
  }
255
302
  return false;
256
303
  }
257
304
 
258
- /** Throws NO_WIDEN_MESSAGE when `after` could widen `before` (see connectorPolicyWidens). */
305
+ /** The `code` of the error a refused widening throws. */
306
+ export const CONNECTOR_POLICY_WIDENS = 'CONNECTOR_POLICY_WIDENS';
307
+ /** An approved tool change met a restriction newer than its request. */
308
+ export const CONNECTOR_TOOL_NARROWED = 'CONNECTOR_TOOL_NARROWED';
309
+ /** An approved tool change found the tool already at that level or more. */
310
+ export const CONNECTOR_TOOL_ALREADY = 'CONNECTOR_TOOL_ALREADY';
311
+
312
+ const codedError = (code, message) => Object.assign(new Error(message), { code });
313
+
314
+ // The one change a person approved on a card (setup-tool connector-widen-approval.mjs),
315
+ // set only for the synchronous stretch of its write.
316
+ let approvedToolChange = null;
317
+
318
+ /** Run `write` (a writer whose noWiden check runs synchronously, before it
319
+ * writes) with one approved change `{ server, tool, from, to }`: its check
320
+ * then lets exactly that tool go to `to`, judged on the stored policy it
321
+ * writes over, and nothing else widen. Returns what `write` returns. */
322
+ export function withApprovedConnectorToolChange(change, write) {
323
+ approvedToolChange = change;
324
+ try {
325
+ return write();
326
+ } finally {
327
+ approvedToolChange = null;
328
+ }
329
+ }
330
+
331
+ // The approved tool's entries (the connector's, and any account's) pinned to
332
+ // one value in both policies, so the comparison judges every other tool and switch.
333
+ const pinTool = (policy, group, tool) => {
334
+ const tools = Object.fromEntries(
335
+ Object.entries(policy?.tools || {}).map(([id, own]) => [
336
+ id,
337
+ connectorGroupId(id) === group ? { ...own, [tool]: 'disabled' } : own,
338
+ ])
339
+ );
340
+ tools[group] = { ...tools[group], [tool]: 'disabled' };
341
+ return { off: policy?.off || [], tools };
342
+ };
343
+
344
+ function assertApprovedToolChange(before, after, { server, tool, from, to }) {
345
+ let old;
346
+ try {
347
+ old = before == null ? { off: [], tools: {} } : parseConnectorPolicy(before);
348
+ } catch {
349
+ throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
350
+ }
351
+ // The approved change is the connector's: its one entry goes to `to`.
352
+ const group = connectorGroupId(server);
353
+ if (old.allow || after?.tools?.[group]?.[tool] !== to) throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
354
+ if (connectorPolicyWidens(pinTool(old, group, tool), pinTool(after, group, tool))) {
355
+ throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
356
+ }
357
+ // No override: it asks at least (as connectorPolicyWidens reads it).
358
+ const was = accountRank(old.tools, new Set(old.off), server, group, tool, 1);
359
+ if (was < PERMISSION_RANK[from]) {
360
+ throw codedError(CONNECTOR_TOOL_NARROWED, 'A newer restriction on this tool landed meanwhile; it was kept.');
361
+ }
362
+ if (was >= PERMISSION_RANK[to]) {
363
+ throw codedError(CONNECTOR_TOOL_ALREADY, 'The tool already has this permission or more; nothing changed.');
364
+ }
365
+ }
366
+
367
+ /** Throws NO_WIDEN_MESSAGE (code CONNECTOR_POLICY_WIDENS) when `after` could
368
+ * widen `before` (see connectorPolicyWidens); inside
369
+ * withApprovedConnectorToolChange, only its approved change may. */
259
370
  export function assertConnectorPolicyNotWidened(before, after) {
260
- if (connectorPolicyWidens(before, after)) throw new Error(NO_WIDEN_MESSAGE);
371
+ if (approvedToolChange) return assertApprovedToolChange(before, after, approvedToolChange);
372
+ if (connectorPolicyWidens(before, after)) throw codedError(CONNECTOR_POLICY_WIDENS, NO_WIDEN_MESSAGE);
261
373
  }
262
374
 
263
375
  let toolPermissionWriter = null;
@@ -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;
@@ -69,8 +80,10 @@ function run(cmd, args, { strict = false, timeoutMs = ENUMERATION_DEADLINE_MS }
69
80
  }
70
81
 
71
82
  // Snapshot the whole process table once: parent map + a per-pid identity
72
- // token (Windows CreationDate, POSIX lstart) so a later kill can prove a pid
73
- // number was not recycled onto a different process before signalling it.
83
+ // token (Windows CreationDate as a UTC FILETIME, POSIX lstart) so a later kill
84
+ // can prove a pid number was not recycled onto a different process before
85
+ // signalling it. The FILETIME form orders against the spawn server's root
86
+ // creation time and carries no local-time offset.
74
87
  // POSIX rows also carry the process group id (Windows has none).
75
88
  async function enumerate({ strict = false } = {}) {
76
89
  const childrenOf = new Map();
@@ -84,7 +97,7 @@ async function enumerate({ strict = false } = {}) {
84
97
  '-NoProfile',
85
98
  '-NonInteractive',
86
99
  '-Command',
87
- `${strict ? "$ErrorActionPreference = 'Stop'; " : ''}Get-CimInstance Win32_Process | ForEach-Object { $created = if ($_.CreationDate) { $_.CreationDate.ToString('o') } else { '' }; "$($_.ProcessId) $($_.ParentProcessId) $($_.Name) $created" }`,
100
+ `${strict ? "$ErrorActionPreference = 'Stop'; " : ''}Get-CimInstance Win32_Process | ForEach-Object { $created = if ($_.CreationDate) { $_.CreationDate.ToFileTimeUtc() } else { '' }; "$($_.ProcessId) $($_.ParentProcessId) $($_.Name) $created" }`,
88
101
  ],
89
102
  { strict, timeoutMs: ENUMERATION_DEADLINE_MS }
90
103
  )
@@ -145,27 +158,41 @@ export function readProcessTable() {
145
158
  return nextTable;
146
159
  }
147
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
+
148
170
  // Walk every descendant pid of rootPid (excludes rootPid).
149
- function descendantsOf(childrenOf, rootPid) {
171
+ function descendantsOf(childrenOf, rootPid, tokenOf) {
150
172
  const result = [];
151
173
  const seen = new Set([rootPid]);
152
174
  const stack = [rootPid];
153
175
  while (stack.length) {
154
176
  const cur = stack.pop();
177
+ const parentCreated = isWin ? createdTicks(tokenOf.get(cur)) : null;
178
+ if (isWin && parentCreated == null) continue;
155
179
  for (const child of childrenOf.get(cur) ?? []) {
156
- if (!seen.has(child)) {
157
- seen.add(child);
158
- result.push(child);
159
- 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;
160
184
  }
185
+ seen.add(child);
186
+ result.push(child);
187
+ stack.push(child);
161
188
  }
162
189
  }
163
190
  return result;
164
191
  }
165
192
 
166
193
  async function collectDescendants(rootPid) {
167
- const { childrenOf } = await enumerate();
168
- return descendantsOf(childrenOf, rootPid);
194
+ const { childrenOf, tokenOf } = await enumerate();
195
+ return descendantsOf(childrenOf, rootPid, tokenOf);
169
196
  }
170
197
 
171
198
  /** Descendant pids WITH their image names and identity tokens (creation
@@ -175,24 +202,163 @@ export async function collectDescendantProcesses(rootPid, { strict = false } = {
175
202
  const { childrenOf, nameOf, tokenOf } = strict
176
203
  ? await snapshot
177
204
  : await snapshot.catch(() => ({ childrenOf: new Map(), nameOf: new Map(), tokenOf: new Map() }));
178
- return descendantsOf(childrenOf, rootPid).map((pid) => ({
205
+ return descendantsOf(childrenOf, rootPid, tokenOf).map((pid) => ({
179
206
  pid,
180
207
  name: nameOf.get(pid) || '',
181
208
  token: tokenOf.get(pid) ?? null,
182
209
  }));
183
210
  }
184
211
 
185
- /** Force-kill whole process trees by pid. Windows batches one taskkill /T /F
186
- * 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
187
352
  * verifies liveness afterwards rather than trusting the signal. */
188
- export async function killProcessTrees(pids) {
189
- const targets = [...new Set((pids || []).map(Number).filter((pid) => Number.isInteger(pid) && pid > 0))];
190
- 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;
191
356
  if (isWin) {
192
- const args = ['/F', '/T'];
193
- for (const pid of targets) args.push('/PID', String(pid));
194
- await run('taskkill', args);
195
- return;
357
+ const { command, args } = treeKillCommand(targets, { aliveAt });
358
+ return runHelper(command, args, TREE_KILL_DEADLINE_MS).then(
359
+ ({ code }) => code,
360
+ () => null
361
+ );
196
362
  }
197
363
  for (const pid of targets) signalQuietly(pid, 'SIGTERM');
198
364
  await delay(300);
@@ -204,10 +370,10 @@ export async function killProcessTrees(pids) {
204
370
  /**
205
371
  * Immediate, non-blocking tree kill for a transport whose MCP handshake never
206
372
  * completed (shutdown-during-connect). Unlike shutdownStdioChild there is no
207
- * grace wait and no identity-checked enumeration on Windows — the ChildProcess
208
- * handle is live, so the pid is current, and taskkill /T reaps the still-
209
- * parented tree. Everything is unref'd/fire-and-forget so the kill can never
210
- * 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).
211
377
  */
212
378
  export function killStdioChildTreeFast(transport) {
213
379
  const proc = transport?._process;
@@ -232,15 +398,7 @@ export function killStdioChildTreeFast(transport) {
232
398
  }
233
399
  }
234
400
  if (isWin) {
235
- try {
236
- const cp = spawn('taskkill', ['/PID', String(pid), '/T', '/F'], {
237
- stdio: 'ignore',
238
- ...detachedSpawnOpts,
239
- });
240
- cp.unref();
241
- } catch {
242
- /* ignore */
243
- }
401
+ spawnTreeKill([pid], { root: proc, detached: true });
244
402
  return true;
245
403
  }
246
404
  // POSIX: cheap ps enumerate, then SIGKILL descendants + root. Best-effort
@@ -306,11 +464,8 @@ async function killVerified(pids, snapshotToken, currentTokens) {
306
464
  const verified = pids.filter((pid) => stillSame(pid, snapshotToken, currentTokens));
307
465
  if (verified.length === 0) return;
308
466
  if (isWin) {
309
- // /T also reaps any still-live children spawned since enumeration;
310
- // every listed /PID was identity-checked just above.
311
- const args = ['/F', '/T'];
312
- for (const p of verified) args.push('/PID', String(p));
313
- await run('taskkill', args);
467
+ // Every listed pid was identity-checked just above.
468
+ await killProcessTrees(verified);
314
469
  return;
315
470
  }
316
471
  // POSIX: terminate, brief wait, then hard-kill survivors. Re-verify with a
@@ -337,7 +492,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
337
492
  // Snapshot #1: tree + identity tokens while it is still fully intact.
338
493
  // Covers children that later get re-parented/orphaned during shutdown.
339
494
  const before = await enumerate().catch(() => empty);
340
- const initial = descendantsOf(before.childrenOf, pid);
495
+ const initial = descendantsOf(before.childrenOf, pid, before.tokenOf);
341
496
  snapshotToken.set(pid, before.tokenOf.get(pid) ?? null);
342
497
  for (const d of initial) snapshotToken.set(d, before.tokenOf.get(d) ?? null);
343
498
  // 1. Close stdin to request a voluntary shutdown.
@@ -351,7 +506,7 @@ export async function shutdownStdioChild(transport, { graceMs = 2000 } = {}) {
351
506
  // 3. Snapshot #2 after the grace: catches children spawned late during
352
507
  // shutdown that were absent from the first snapshot.
353
508
  const after = await enumerate().catch(() => empty);
354
- const fresh = descendantsOf(after.childrenOf, pid);
509
+ const fresh = descendantsOf(after.childrenOf, pid, after.tokenOf);
355
510
  for (const d of fresh) {
356
511
  if (!snapshotToken.has(d)) snapshotToken.set(d, after.tokenOf.get(d) ?? null);
357
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
  };
@@ -307,14 +305,25 @@ export function resolveMcpTransportKind(cfg) {
307
305
  throw new Error(`Invalid config: need autoDetect, type (stdio/http/sse/ws), url (http), or command (stdio)`);
308
306
  }
309
307
 
310
- /** The exact URL OAuth credentials of an HTTP/SSE server config are stored
311
- * under; null for other transports. */
308
+ /** The exact URL an HTTP/SSE server config signs in at with OAuth; null for
309
+ * other transports. */
312
310
  export function resolveMcpOAuthUrl(cfg) {
313
311
  const kind = resolveMcpTransportKind(cfg);
314
312
  if (kind !== 'http' && kind !== 'sse') return null;
315
313
  return normalizeMcpTransportUrl(expandEnvVars(String(cfg.url ?? '')), kind);
316
314
  }
317
315
 
316
+ /** What the OAuth credentials of an HTTP/SSE server config are stored under:
317
+ * its exact URL, or a connector account's own `oauthKey` (another account
318
+ * of the connector signs in at the same URL), whatever the URL. Null for
319
+ * other transports. */
320
+ export function resolveMcpOAuthCredentialKey(cfg) {
321
+ const url = resolveMcpOAuthUrl(cfg);
322
+ if (!url) return null;
323
+ const own = typeof cfg.oauthKey === 'string' ? cfg.oauthKey.trim() : '';
324
+ return own ? `mcp-account:${own}` : url;
325
+ }
326
+
318
327
  // MCP per-tool-call timeout. Default 2min: a hung/unresponsive MCP server
319
328
  // (e.g. a busy editor) must not stall a tool call indefinitely. Genuinely
320
329
  // long-running tools can raise/disable it via MIXDOG_MCP_CALL_TIMEOUT_MS or a