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
@@ -6,13 +6,31 @@
6
6
  import { randomUUID } from 'node:crypto';
7
7
  import { publishForegroundShellRecord, retireForegroundShellRecord } from '../builtin/shell-jobs.mjs';
8
8
  import { ShellTextDecoder, TaskOutput, treeKill } from '../shell-exec-output.mjs';
9
- import { createProcessTreeTracker, killAfterSnapshot } from './shell-descendants.mjs';
9
+ import { createContainedTreeTracker, createProcessTreeTracker } from './shell-descendants.mjs';
10
10
  import { registerOwnedShellTree } from './owned-shell-trees.mjs';
11
11
 
12
+ /** The tracker of the run's process tree, created once. A killed tree the
13
+ * spawn server contains is gone on its verified-empty report alone; every
14
+ * other tree (no containment, or a root that exited on its own and left
15
+ * survivors) is observed through the process table. */
16
+ export function runTreeTracker(run) {
17
+ run.terminationTracker =
18
+ run.terminationTracker ||
19
+ (run.killed === true && run.child.contained === true
20
+ ? createContainedTreeTracker({
21
+ outcome: () => run.child.treeOutcome,
22
+ // Survivors the server kept in the job: the kill, by request id.
23
+ cancel: () => treeKill(run.child),
24
+ })
25
+ : createProcessTreeTracker({ pid: run.child.pid, rootCreationTime: run.child.creationTime }));
26
+ return run.terminationTracker;
27
+ }
28
+
12
29
  /** One pre-kill identity read of the run's tree (every kill path shares it):
13
- * resolves true once the capture is complete, false when it failed. */
30
+ * resolves true once the capture is complete, false when it failed. A
31
+ * contained kill needs none: true at once, so the kill is never delayed. */
14
32
  export function capturePreKill(run) {
15
- run.terminationTracker = run.terminationTracker || createProcessTreeTracker({ pid: run.child.pid });
33
+ if (runTreeTracker(run).contained) return true;
16
34
  const rootExited = run.child.exitCode != null || run.child.signalCode != null;
17
35
  return run.terminationTracker.capture({ rootExited }).catch(() => false);
18
36
  }
@@ -32,6 +50,7 @@ export function registerForegroundOwnedTree(run, ownerSessionId) {
32
50
  run.killCause = run.killCause || 'session-close';
33
51
  // Always a fresh read: an earlier one predates what the run started
34
52
  // since. Pending, the kill is sent at the snapshot bound regardless.
53
+ // A contained tree answers true at once: its cancel is sent at once.
35
54
  return capturePreKill(run);
36
55
  },
37
56
  };
@@ -39,7 +58,7 @@ export function registerForegroundOwnedTree(run, ownerSessionId) {
39
58
  }
40
59
 
41
60
  // Treekill + exit confirmation. treeKill alone leaves settle() pending on
42
- // 'close'/'exit'; on Windows a taskkill miss or a grandchild holding stdio
61
+ // 'close'/'exit'; on Windows a missed tree kill or a grandchild holding stdio
43
62
  // fds keeps the dispatch stalled until the upstream ceiling. Covers every
44
63
  // kill path (timeout / pre-aborted / abort / capture-error / size-watchdog)
45
64
  // so the hang risk does not live on outside the timeout branch.
@@ -219,18 +238,23 @@ export function keepTerminationUnconfirmedRecord(run) {
219
238
  // Record the tree's identities while the root is still alive, THEN kill: once
220
239
  // an intermediate dies its children's parent links dangle and a snapshot taken
221
240
  // afterwards can no longer find them.
222
- // The kill waits for the snapshot at most PROCESS_TABLE_READ_BOUND_MS and is
223
- // sent whether the snapshot succeeded, failed or is still pending (a late
224
- // snapshot is still absorbed; a missing one leaves the outcome unknown, so the
225
- // workspace stays held under the observation loop). The confirmation deadline
226
- // starts once the kill is actually issued.
241
+ // The kill waits until the snapshot succeeded or failed, never just for a
242
+ // while: a read still in flight takes its table after a kill sent beside it,
243
+ // finds the root gone, and the tree could never be confirmed terminated (the
244
+ // workspace then stays held until a force-release). A healthy table read takes
245
+ // seconds on a loaded host; a stuck one ends at its enumeration deadline
246
+ // (ENUMERATION_DEADLINE_MS), and the kill is sent then, the outcome unknown.
247
+ // A tree the spawn server contains is killed at once instead: its job holds
248
+ // every descendant, and the server reports when that job is empty.
249
+ // The confirmation deadline starts once the kill is actually issued.
227
250
  function snapshotThenKill(run, afterKill) {
228
- if (!run.child?.pid) {
251
+ const snapshot = run.child?.pid ? capturePreKill(run) : true;
252
+ if (snapshot === true) {
229
253
  treeKill(run.child);
230
254
  afterKill();
231
255
  return;
232
256
  }
233
- void killAfterSnapshot(capturePreKill(run), () => {
257
+ void snapshot.then(() => {
234
258
  treeKill(run.child);
235
259
  afterKill();
236
260
  });
@@ -102,6 +102,8 @@ function ensureWarmShellStandby({ shell, env }) {
102
102
  outputLimit: SHELL_OUTPUT_DISK_CAP,
103
103
  rawOutput: true,
104
104
  stdinPipe: true,
105
+ // The command it is fed runs contained, like a fresh spawn's.
106
+ contain: true,
105
107
  shellType: 'powershell',
106
108
  command: '(warm shell standby)',
107
109
  },
@@ -0,0 +1,26 @@
1
+ // Test support: wait for a real condition on a wall-clock budget. A fixed
2
+ // number of event-loop turns is load-dependent (async record writes and
3
+ // process-table reads take more turns on a busy machine); elapsed time is not.
4
+ // Polls on a short real timer (never a busy loop). The real setTimeout is
5
+ // captured at load, before any test enables mock timers, so a mocked clock
6
+ // cannot freeze the wait.
7
+ import assert from 'node:assert/strict';
8
+
9
+ const realSetTimeout = setTimeout;
10
+ const POLL_MS = 5;
11
+ const tick = () => new Promise((resolve) => realSetTimeout(resolve, POLL_MS));
12
+
13
+ /** Resolves with the first truthy `read()` (sync or async); fails with `what`
14
+ * once `timeoutMs` has passed without one. */
15
+ export async function waitUntil(
16
+ read,
17
+ { timeoutMs = 10_000, what = String(read).replace(/\s+/g, ' ').slice(0, 160) } = {}
18
+ ) {
19
+ const deadline = Date.now() + timeoutMs;
20
+ for (;;) {
21
+ const value = await read();
22
+ if (value) return value;
23
+ if (Date.now() >= deadline) assert.fail(`condition not reached within ${timeoutMs}ms: ${what}`);
24
+ await tick();
25
+ }
26
+ }
@@ -21,10 +21,6 @@ import { spawnShellChild } from './lib/shell-run-spawn.mjs';
21
21
  import { createPromotedCaptureRelease, createSettle } from './lib/shell-run-settle.mjs';
22
22
  import { _abortReasonIsInterrupt, createAutoBackground } from './lib/shell-run-background.mjs';
23
23
 
24
- export {
25
- _maybeEncodePowerShellCommand,
26
- extractPowerShellCommandInner,
27
- } from './shell-powershell.mjs';
28
24
  export { stripAnsi, ExecResult } from './shell-exec-output.mjs';
29
25
 
30
26
  async function _execPolicyBlockMessage(command, elevationApproved = false) {
@@ -432,7 +428,7 @@ function attachChildExit(run, releasePromotedCapture) {
432
428
  // child termination regardless — give 'close' a 3 s grace then
433
429
  // settle anyway. The grace outlives the spawn server's own 2 s drain
434
430
  // deadline, so the real exit status normally still arrives first.
435
- child.once('exit', (code, signal) => {
431
+ const onExit = (code, signal) => {
436
432
  if (!run.rootExitAtMs) run.rootExitAtMs = Date.now();
437
433
  const grace = setTimeout(() => {
438
434
  if (run.settled || run.promotionClose) return;
@@ -449,7 +445,12 @@ function attachChildExit(run, releasePromotedCapture) {
449
445
  run.settle(code == null ? 1 : code, signal);
450
446
  }, 3000);
451
447
  if (grace.unref) grace.unref();
452
- });
448
+ };
449
+ // The spawn awaits the command's workspace lease before these listeners
450
+ // exist; a root that exited meanwhile ('close' is replayed, 'exit' is not)
451
+ // starts its grace now.
452
+ if (child.exitCode != null || child.signalCode != null) onExit(child.exitCode, child.signalCode);
453
+ else child.once('exit', onExit);
453
454
  }
454
455
 
455
456
  // Live-progress heartbeat: every 2 s while the foreground command runs, emit
@@ -1,5 +1,4 @@
1
1
  import { isDangerousDeleteTarget as _isDangerousDeleteTarget } from './shell-policy-danger-target.mjs';
2
- export { isDangerousDeleteTarget } from './shell-policy-danger-target.mjs';
3
2
  // Shell execution security policy — shared constants used by both
4
3
  // destructive-warning.mjs (heuristic classifier) and the shell command
5
4
  // runner (hard block list).
@@ -1,30 +1,30 @@
1
1
  {
2
- "version": "0.1.11",
2
+ "version": "0.1.12",
3
3
  "_comment": "Synced from immutable spawn-v release assets.",
4
4
  "assets": {
5
5
  "darwin-arm64": {
6
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-darwin-arm64",
7
- "sha256": "6f1a7e6597dcc8785d12c5a13c42388110d9f4a2e5378ca2773172adbf50de60"
6
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-darwin-arm64",
7
+ "sha256": "bc2307b1c089e07f829a8a1daf4dfdfc128e3221d8f70609ffbdcc3f8b596806"
8
8
  },
9
9
  "darwin-x64": {
10
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-darwin-x64",
11
- "sha256": "ff755eb9848cb3ce90f3df24136bb84a52f9ff6c67002c4d764beb6d7906e6b2"
10
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-darwin-x64",
11
+ "sha256": "4b1d221a29128046c417cfae5617e2898e1b7bc564dca686b2608b6cb14bf3af"
12
12
  },
13
13
  "linux-arm64": {
14
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-linux-arm64",
15
- "sha256": "3bc0fccde46537046d498a2b953aa92ef4afacc95c96c563ce1d6fb92d74e593"
14
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-linux-arm64",
15
+ "sha256": "2f577f54693726db0d285a16c3af2ad25b73fd705fd2fd4ac5c18ce795f657a9"
16
16
  },
17
17
  "linux-x64": {
18
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-linux-x64",
19
- "sha256": "16dc4e3bf6636335c1325c88bbb5245529731525953466e761d363897b59aac7"
18
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-linux-x64",
19
+ "sha256": "83b52edfe2b810d5cf6544b03ab263eedcf7b2ef3c73107a45a33f6f7871e59e"
20
20
  },
21
21
  "win32-arm64": {
22
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-win32-arm64.exe",
23
- "sha256": "c2fb5499d3d44405e27c79f8db65694299d61ddf029f466df68549fc2f2c5f5c"
22
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-win32-arm64.exe",
23
+ "sha256": "33872113fc0ca3cd2a2f6cf36c33430431388a5e36f254c8a0c6a44932057009"
24
24
  },
25
25
  "win32-x64": {
26
- "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.11/mixdog-spawn-win32-x64.exe",
27
- "sha256": "50531a9f033dc22eff3ec5b2a9d10441ffdfac0e50d9acf9047e4f302e5d70d9"
26
+ "url": "https://github.com/tribgames/mixdog/releases/download/spawn-v0.1.12/mixdog-spawn-win32-x64.exe",
27
+ "sha256": "0070823fa03a50819077d60a407f4f8e26becafe3541ecdfabe522fc5e05a8cb"
28
28
  }
29
29
  }
30
30
  }
@@ -33,7 +33,7 @@ function quotedName(name, fallback) {
33
33
  }
34
34
 
35
35
  /** How much of a PDF reads as text, in words the model can act on. */
36
- export function textLayerLabel(pageCount, textPages) {
36
+ function textLayerLabel(pageCount, textPages) {
37
37
  const pages = Number(pageCount);
38
38
  const withText = Number(textPages);
39
39
  if (!(pages > 0) || !Number.isFinite(withText) || withText < 0) return 'text layer not checked';
@@ -81,7 +81,7 @@ export const PDF_INTAKE_TIMEOUT_MS = 60_000;
81
81
  // least this many non-whitespace characters. A scan often keeps a stamped page
82
82
  // number or a few stray glyphs; those alone do not make its content readable
83
83
  // as text, so such a page still needs its image (or OCR).
84
- export const PDF_TEXT_LAYER_MIN_CHARS = 16;
84
+ const PDF_TEXT_LAYER_MIN_CHARS = 16;
85
85
 
86
86
  /** Whether one page's extracted text is a real text layer (see above). */
87
87
  export function pageHasTextLayer(text) {
@@ -1,4 +1,5 @@
1
1
  export function readAttachmentBuffer(value: string | { attachmentRef?: string }): Buffer;
2
+ export function attachmentBlobSize(value: string | { attachmentRef?: string }, claimed?: number): number;
2
3
  export function isPermanentAttachmentError(error: unknown): boolean;
3
4
  export function isAttachmentReference(value: unknown): boolean;
4
5
  export interface MessageAttachment {
@@ -298,7 +298,7 @@ const ATTACHMENT_INTEGRITY = 'ATTACHMENT_INTEGRITY';
298
298
 
299
299
  // A referenced blob that is gone from disk (retention, manual cleanup, a
300
300
  // copied session) surfaces from readAttachmentBuffer as the stat ENOENT.
301
- export function isMissingAttachmentError(error) {
301
+ function isMissingAttachmentError(error) {
302
302
  return error?.code === 'ENOENT';
303
303
  }
304
304
 
@@ -316,7 +316,7 @@ export function readAttachmentBase64(value) {
316
316
  // Real on-disk size of a referenced blob. Caps must never trust the client's
317
317
  // claimed sizeBytes; a blob that is not on disk cannot be read later either, so
318
318
  // only then does the claimed size stand.
319
- function attachmentBlobSize(value, claimed = 0) {
319
+ export function attachmentBlobSize(value, claimed = 0) {
320
320
  try {
321
321
  return statSync(attachmentPath(typeof value === 'string' ? value : value?.attachmentRef)).size;
322
322
  } catch (error) {
@@ -0,0 +1,42 @@
1
+ // The channels worker's config hot reload (schedules, webhooks, events, voice).
2
+ // It rides the shared config-change subscription: that watches the data
3
+ // directory, so the atomic rename of every write never orphans it, it recovers
4
+ // from watcher errors, and it carries in-process writes and keychain changes.
5
+ // A reload restarts the webhook server and hook tunnel, so only a change of
6
+ // the sections the worker reads (channels: webhook, events, …; voice) reloads;
7
+ // schedules arrive through the reload_config IPC, never through this watch.
8
+ import { readSection, subscribeConfigChange } from '../../shared/config.mjs';
9
+
10
+ function channelsConfigSnapshot() {
11
+ return JSON.stringify([readSection('channels') ?? null, readSection('voice') ?? null]);
12
+ }
13
+
14
+ export function createConfigReloadWatch(reload, { snapshot = channelsConfigSnapshot } = {}) {
15
+ let unsubscribe = null;
16
+ let applied = null;
17
+ const read = () => {
18
+ try {
19
+ return snapshot();
20
+ } catch {
21
+ return null;
22
+ }
23
+ };
24
+ return {
25
+ start() {
26
+ if (unsubscribe) return;
27
+ applied = read();
28
+ unsubscribe = subscribeConfigChange(() => {
29
+ const next = read();
30
+ if (next !== null && next === applied) return;
31
+ applied = next;
32
+ Promise.resolve()
33
+ .then(reload)
34
+ .catch(() => {});
35
+ });
36
+ },
37
+ stop() {
38
+ unsubscribe?.();
39
+ unsubscribe = null;
40
+ },
41
+ };
42
+ }
@@ -1,6 +1,19 @@
1
1
  import { loadConfig } from '../config.mjs';
2
2
 
3
- export function createConfigReloader({ state, getConfig, setConfig, getBridgeRuntimeConnected, scheduler, services }) {
3
+ export function createConfigReloader({
4
+ state,
5
+ getConfig,
6
+ setConfig,
7
+ getBridgeRuntimeConnected,
8
+ scheduler,
9
+ services,
10
+ load = loadConfig,
11
+ }) {
12
+ // Reloads overlap (no debounce), so a slower load of an older config must not
13
+ // be applied over a newer one: only the newest started reload applies, and an
14
+ // older caller waits for it instead.
15
+ let latestStarted = 0;
16
+ let latestReload = null;
4
17
  function reloadScheduler() {
5
18
  // The scheduler must be RE-ARMED by the reload whenever it is supposed to
6
19
  // be running: `restart: false` only destroys the cron/one-shot bindings and
@@ -12,13 +25,20 @@ export function createConfigReloader({ state, getConfig, setConfig, getBridgeRun
12
25
  restart: state.automationRunning || getBridgeRuntimeConnected(),
13
26
  });
14
27
  }
15
- return async function reloadRuntimeConfig() {
16
- setConfig(await loadConfig());
17
- reloadScheduler();
18
- if (getBridgeRuntimeConnected() || state.automationRunning) {
19
- services.syncWebhookAndEventRuntime({ reload: true });
20
- } else {
21
- await services.stopWebhookAndEventRuntime();
22
- }
28
+ return function reloadRuntimeConfig() {
29
+ const ticket = ++latestStarted;
30
+ const run = (async () => {
31
+ const loaded = await load();
32
+ if (ticket !== latestStarted) return latestReload;
33
+ setConfig(loaded);
34
+ reloadScheduler();
35
+ if (getBridgeRuntimeConnected() || state.automationRunning) {
36
+ services.syncWebhookAndEventRuntime({ reload: true });
37
+ } else {
38
+ await services.stopWebhookAndEventRuntime();
39
+ }
40
+ })();
41
+ latestReload = run;
42
+ return run;
23
43
  };
24
44
  }
@@ -9,6 +9,7 @@ import { isPidAlive } from '../../shared/pid-liveness.mjs';
9
9
  import {
10
10
  advanceScheduleCursor,
11
11
  claimScheduleRun,
12
+ getSchedule,
12
13
  markFired,
13
14
  markDone,
14
15
  markScheduleFailure,
@@ -76,6 +77,14 @@ function isCronExpression(time) {
76
77
  return false;
77
78
  }
78
79
  }
80
+ // Two one-shot times name the same instant. The database hands back a new
81
+ // Date on every read, so identity would call an unchanged schedule changed.
82
+ function sameInstant(left, right) {
83
+ if (left == null || right == null) return (left ?? null) === (right ?? null);
84
+ const at = (value) => (value instanceof Date ? value.getTime() : Date.parse(value));
85
+ const [a, b] = [at(left), at(right)];
86
+ return Number.isNaN(a) || Number.isNaN(b) ? String(left) === String(right) : a === b;
87
+ }
79
88
  // True when this fire (started at `since`) ended in an overlap skip.
80
89
  function skippedSince(schedule, since) {
81
90
  const at = schedule.lastSkippedAt ? new Date(schedule.lastSkippedAt).getTime() : 0;
@@ -616,6 +625,30 @@ class Scheduler {
616
625
  }
617
626
  // ── Fire timed schedule ─────────────────────────────────────────────
618
627
  async fireTimed(schedule, opts = {}) {
628
+ // The armed copy may be stale (a reload that failed or has not arrived):
629
+ // the stored row decides whether, and with what prompt, it still fires.
630
+ let row;
631
+ try {
632
+ row = await getSchedule(schedule.name);
633
+ } catch (err) {
634
+ logSchedule(`${schedule.name}: not fired — schedule unreadable: ${err?.message || err}\n`);
635
+ this.notifyFailure(schedule, 'schedule unreadable — fire skipped');
636
+ return false;
637
+ }
638
+ const sameCron = (row?.whenCron ?? null) === (schedule.whenCron ?? null);
639
+ if (
640
+ !row ||
641
+ row.enabled === false ||
642
+ row.status === 'done' ||
643
+ !sameInstant(row.whenAt, schedule.whenAt) ||
644
+ !sameCron
645
+ ) {
646
+ logSchedule(`${schedule.name}: not fired — deleted or changed since it was armed\n`);
647
+ // A skip, not a failed run: the callers record no failure on its row.
648
+ schedule.lastSkippedAt = new Date().toISOString();
649
+ return false;
650
+ }
651
+ schedule.prompt = row.prompt;
619
652
  const prompt = this.resolvePrompt(schedule);
620
653
  if (!prompt) {
621
654
  process.stderr.write(`mixdog scheduler: prompt not found for "${schedule.name}"
@@ -60,6 +60,9 @@ ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS last_skipped_at timesta
60
60
  ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS owner_agent_id text NOT NULL DEFAULT 'lead';
61
61
  -- Legacy columns model, workflow and run_as_agent are no longer read or written (kept, not dropped, to avoid a risky migration).
62
62
  ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS run_as_agent boolean NOT NULL DEFAULT false;
63
+ -- The workflow sub-agent that carries out each fire first (its final report is
64
+ -- what the owner bot relays); NULL = the owner bot does the work itself.
65
+ ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS executor_agent_id text;
63
66
  -- Failed runs in a row: a success or switching it back on resets it; at
64
67
  -- ROUTINE_LIMITS.pauseAfterFailures the schedule switches itself off.
65
68
  ALTER TABLE scheduler.schedules ADD COLUMN IF NOT EXISTS consecutive_failures integer NOT NULL DEFAULT 0;
@@ -101,6 +104,7 @@ function rowToDef(row) {
101
104
  lastFailedAt: row.last_failed_at,
102
105
  lastSkippedAt: row.last_skipped_at,
103
106
  ownerAgentId: row.owner_agent_id || 'lead',
107
+ executorAgentId: row.executor_agent_id || null,
104
108
  consecutiveFailures: Number(row.consecutive_failures) || 0,
105
109
  resultDelivery: row.result_delivery || null,
106
110
  nextFireAt: row.next_fire_at,
@@ -136,7 +140,7 @@ function hasRequiredTargetColumn(db) {
136
140
  }
137
141
 
138
142
  const COLS =
139
- 'name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, last_fired_at, last_scheduled_at, last_started_at, last_success_at, last_failed_at, last_skipped_at, owner_agent_id, consecutive_failures, result_delivery, next_fire_at, deferred_until, skipped_until, created_at, updated_at';
143
+ 'name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, last_fired_at, last_scheduled_at, last_started_at, last_success_at, last_failed_at, last_skipped_at, owner_agent_id, executor_agent_id, consecutive_failures, result_delivery, next_fire_at, deferred_until, skipped_until, created_at, updated_at';
140
144
 
141
145
  // ---------------------------------------------------------------------------
142
146
  // Public API
@@ -176,6 +180,7 @@ export async function upsertSchedule(def, { dataDir } = {}) {
176
180
  def.status ?? 'active',
177
181
  def.nextFireAt ?? null,
178
182
  def.ownerAgentId || 'lead',
183
+ def.executorAgentId || null,
179
184
  ];
180
185
  let legacyTarget = '';
181
186
  let legacyTargetValue = '';
@@ -186,10 +191,11 @@ export async function upsertSchedule(def, { dataDir } = {}) {
186
191
  }
187
192
  const { rows } = await db.query(
188
193
  `INSERT INTO scheduler.schedules
189
- (name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, next_fire_at, owner_agent_id${legacyTarget})
190
- VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13${legacyTargetValue})
194
+ (name, description, when_at, when_cron, timezone, cwd, attachments, delivery, prompt, enabled, status, next_fire_at, owner_agent_id, executor_agent_id${legacyTarget})
195
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14${legacyTargetValue})
191
196
  ON CONFLICT (name) DO UPDATE SET
192
197
  owner_agent_id = EXCLUDED.owner_agent_id,
198
+ executor_agent_id = EXCLUDED.executor_agent_id,
193
199
  description = EXCLUDED.description,
194
200
  when_at = EXCLUDED.when_at,
195
201
  when_cron = EXCLUDED.when_cron,
@@ -235,7 +241,7 @@ export async function renameSchedule(oldName, def, { timingChanged = false, data
235
241
  const { rows } = await db.query(
236
242
  `UPDATE scheduler.schedules SET
237
243
  name = $2, description = $3, when_at = $4, when_cron = $5, timezone = $6, cwd = $7,
238
- attachments = $8, prompt = $9, enabled = $10, owner_agent_id = $11,
244
+ attachments = $8, prompt = $9, enabled = $10, owner_agent_id = $11, executor_agent_id = $13,
239
245
  next_fire_at = CASE WHEN $12::boolean THEN $4::timestamptz ELSE next_fire_at END,
240
246
  status = CASE WHEN $12::boolean THEN 'active' ELSE status END,
241
247
  deferred_until = CASE WHEN $12::boolean THEN NULL ELSE deferred_until END,
@@ -258,6 +264,7 @@ export async function renameSchedule(oldName, def, { timingChanged = false, data
258
264
  def.enabled ?? true,
259
265
  def.ownerAgentId || 'lead',
260
266
  timingChanged === true,
267
+ def.executorAgentId || null,
261
268
  ]
262
269
  );
263
270
  return rowToDef(rows[0]);
@@ -96,6 +96,8 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
96
96
  endpoint: name,
97
97
  // The bot whose chat the run is a turn in.
98
98
  owner: extra.owner || null,
99
+ // The sub-agent that carries the run out first, if the endpoint names one.
100
+ executor: extra.executor || null,
99
101
  deliveryId,
100
102
  event: extra.event || null,
101
103
  },
@@ -108,7 +110,7 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
108
110
 
109
111
  async function dispatchEndpoint({ name, body, headers, res, deliveryId, endpoint }) {
110
112
  try {
111
- const { instructions, cwd, attachments, delivery, ownerAgentId } = endpoint;
113
+ const { instructions, cwd, attachments, delivery, ownerAgentId, executorAgentId } = endpoint;
112
114
  const run = webhookRunPrompt(instructions, body, headers);
113
115
  if (!getBridgeDispatch()) throw new Error(`[webhook] session dispatch requires bridgeDispatch`);
114
116
  // Kept for the app's "Run now", which re-runs the latest event. Losing
@@ -118,6 +120,7 @@ function createWebhookSessionDispatcher({ getBridgeDispatch, store = { recordEnd
118
120
  );
119
121
  await dispatchSessionRun(name, run.prompt, deliveryId, res, {
120
122
  owner: ownerAgentId || null,
123
+ executor: executorAgentId || null,
121
124
  cwd: cwd || null,
122
125
  event: webhookEventSummary(headers, body),
123
126
  attachments: attachments || null,
@@ -45,6 +45,9 @@ ALTER TABLE webhooks.endpoints ALTER COLUMN role SET DEFAULT '';
45
45
  ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS owner_agent_id text NOT NULL DEFAULT 'lead';
46
46
  -- Legacy columns model, workflow and run_as_agent are no longer read or written (kept, not dropped, to avoid a risky migration).
47
47
  ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS run_as_agent boolean NOT NULL DEFAULT false;
48
+ -- The workflow sub-agent that carries out each run first (its final report is
49
+ -- what the owner bot relays); NULL = the owner bot does the work itself.
50
+ ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS executor_agent_id text;
48
51
  -- The latest received event (its payload kept for a manual re-run) and the
49
52
  -- outcome stamps of the runs it started.
50
53
  ALTER TABLE webhooks.endpoints ADD COLUMN IF NOT EXISTS last_event_at timestamptz;
@@ -86,7 +89,7 @@ const getDb = createPgSchemaDb({
86
89
  // The stored payload itself is never projected here (readEndpointLastPayload
87
90
  // is its only read path); rows carry a presence flag.
88
91
  const ENDPOINT_COLS =
89
- 'name, description, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
92
+ 'name, description, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, executor_agent_id, last_event_at, last_success_at, last_failed_at, last_skipped_at, consecutive_failures, result_delivery, (last_payload IS NOT NULL) AS has_last_payload, created_at, updated_at';
90
93
 
91
94
  function rowToEndpoint(row) {
92
95
  if (!row) return null;
@@ -104,6 +107,7 @@ function rowToEndpoint(row) {
104
107
  instructions: row.instructions,
105
108
  enabled: row.enabled,
106
109
  ownerAgentId: row.owner_agent_id || 'lead',
110
+ executorAgentId: row.executor_agent_id || null,
107
111
  lastEventAt: row.last_event_at || null,
108
112
  lastSuccessAt: row.last_success_at || null,
109
113
  lastFailedAt: row.last_failed_at || null,
@@ -187,15 +191,17 @@ export async function upsertEndpoint(def, { dataDir } = {}) {
187
191
  def.instructions ?? '',
188
192
  def.enabled ?? true,
189
193
  def.ownerAgentId || 'lead',
194
+ def.executorAgentId || null,
190
195
  ];
191
196
  // The last event and run stamps survive an edit: they describe deliveries,
192
197
  // not the definition.
193
198
  const { rows } = await db.query(
194
199
  `INSERT INTO webhooks.endpoints
195
- (name, description, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id)
196
- VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)
200
+ (name, description, role, parser, secret, cwd, attachments, delivery, instructions, enabled, owner_agent_id, executor_agent_id)
201
+ VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12)
197
202
  ON CONFLICT (name) DO UPDATE SET
198
203
  owner_agent_id = EXCLUDED.owner_agent_id,
204
+ executor_agent_id = EXCLUDED.executor_agent_id,
199
205
  description = EXCLUDED.description,
200
206
  role = EXCLUDED.role,
201
207
  parser = EXCLUDED.parser,
@@ -48,22 +48,31 @@ function runOwnershipQuery(command, args) {
48
48
  });
49
49
  }
50
50
 
51
+ // Get-NetTCPConnection prints one OwningProcess number per line: no localized words.
52
+ export function listenerPidsInclude(stdout, pid) {
53
+ return stdout.split(/\r?\n/).some((line) => line.trim() === String(pid));
54
+ }
55
+
51
56
  export async function whisperListenerOwned(host, port, pid) {
52
57
  if (!Number.isInteger(pid) || pid <= 0 || !Number.isInteger(port)) return false;
53
58
  try {
54
59
  if (process.platform === 'win32') {
55
60
  const root = process.env.SystemRoot || 'C:\\Windows';
56
- const stdout = await runOwnershipQuery(path.join(root, 'System32', 'netstat.exe'), ['-ano', '-p', 'tcp']);
61
+ // netstat omits listeners when the TCP table is large; the CIM-backed cmdlet does not.
62
+ // The State filter is skipped (it can report an unknown state for live listeners);
63
+ // a listening row is the one with no remote endpoint (RemotePort 0).
64
+ if (!/^[0-9a-fA-F:.]+$/.test(host)) return false;
65
+ const stdout = await runOwnershipQuery(
66
+ path.join(root, 'System32', 'WindowsPowerShell', 'v1.0', 'powershell.exe'),
67
+ [
68
+ '-NoProfile',
69
+ '-NonInteractive',
70
+ '-Command',
71
+ `(Get-NetTCPConnection -LocalAddress '${host}' -LocalPort ${port} -ErrorAction SilentlyContinue | Where-Object RemotePort -eq 0).OwningProcess`,
72
+ ]
73
+ );
57
74
  if (stdout === null) return false;
58
- return stdout.split(/\r?\n/).some((line) => {
59
- const fields = line.trim().split(/\s+/);
60
- return (
61
- fields[0] === 'TCP' &&
62
- fields[1] === `${host}:${port}` &&
63
- fields[3] === 'LISTENING' &&
64
- fields[4] === String(pid)
65
- );
66
- });
75
+ return listenerPidsInclude(stdout, pid);
67
76
  }
68
77
  if (process.platform === 'linux') {
69
78
  const stdout = await runOwnershipQuery('ss', ['-H', '-ltnp', `sport = :${port}`]);