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
@@ -139,11 +139,13 @@ export function createHeldRequests({
139
139
  tool: request.name,
140
140
  target: request.outbound?.target || '',
141
141
  reason: request.reason || '',
142
+ // The connector account the call is bound to (tool-exec.mjs).
143
+ account: request.account,
142
144
  ...(request.kind === 'outbound'
143
145
  ? {
144
146
  payload: request.outbound?.payload || '',
145
147
  action: request.outbound?.category,
146
- account: request.outbound?.account,
148
+ account: request.outbound?.account || request.account,
147
149
  editable: request.outbound?.editable,
148
150
  details: request.outbound?.details,
149
151
  }
@@ -8,6 +8,7 @@ import {
8
8
  ASK_USER_MAX_TEXT,
9
9
  } from '../../runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs';
10
10
  import { createCallerContextResolvers } from './caller-context.mjs';
11
+ import { noteTodoUserWait } from '../../runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs';
11
12
  import { runAbortable } from '../../runtime/shared/abort-race.mjs';
12
13
  import {
13
14
  HANDOFF_OUTCOMES as AGENT_OUTCOMES,
@@ -309,6 +310,8 @@ export function createAskUserToolHandlers({ rt }) {
309
310
  normalizeAskUserAnswers(result.answers, questions),
310
311
  normalizeAskUserReply(result.reply)
311
312
  );
313
+ // A question left unanswered: the turn may end waiting on the user.
314
+ noteTodoUserWait(sessionIdFor(callerCtx));
312
315
  return DISMISSED;
313
316
  },
314
317
  };
@@ -68,8 +68,9 @@ export function createBridgeToolHandlers({ rt }) {
68
68
  if (environmentDisabled(callerCtx, 'MIXDOG_FEATURE_VISUALIZE')) {
69
69
  throw new Error('the visualize tool is disabled in this environment');
70
70
  }
71
- // A conversation keeps its frozen tool list, so honor the Settings toggle
72
- // at execution time too (an env override wins, as in builtinFeatureActive).
71
+ // The Settings toggle at execution time too: it reaches a turn already
72
+ // running and callers outside the session's deny set (an env override
73
+ // wins, as in builtinFeatureActive).
73
74
  if (!(featureEnvOverride('MIXDOG_FEATURE_VISUALIZE') ?? moduleEnabled(rt.config, 'visualize', true))) {
74
75
  return {
75
76
  content: [
@@ -1,19 +1,13 @@
1
- // Optional feature tools gated by settings for model-initiated calls: office,
2
- // media and tidy (each loaded on first use), and the setup tool.
1
+ // Optional feature tools: office, media and tidy (each loaded on first use;
2
+ // their settings gates apply in the executor), and the setup tool.
3
3
  import { standaloneDataDir } from '../runtime-paths.mjs';
4
4
  import { createCallerContextResolvers } from './caller-context.mjs';
5
5
 
6
- export function createFeatureToolHandlers({ rt, setupTool, officeToolsEnabled, mediaToolEnabled, tidyToolEnabled }) {
6
+ export function createFeatureToolHandlers({ rt, setupTool }) {
7
7
  const { sessionIdFor, signalFor } = createCallerContextResolvers(rt);
8
- const requireEnabled = (callerCtx, enabled, label) => {
9
- if (callerCtx?.invocationSource === 'model-tool' && !enabled()) {
10
- throw new Error(`${label} is disabled in settings; start a new session to refresh the tool list`);
11
- }
12
- };
13
8
 
14
9
  return {
15
10
  office: async (args, { callerCtx, callerCwd }) => {
16
- requireEnabled(callerCtx, officeToolsEnabled, 'office');
17
11
  const { executeOfficeTool } = await import('../../runtime/office/index.mjs');
18
12
  return await executeOfficeTool(args, {
19
13
  cwd: callerCwd,
@@ -25,7 +19,6 @@ export function createFeatureToolHandlers({ rt, setupTool, officeToolsEnabled, m
25
19
  });
26
20
  },
27
21
  media: async (args, { callerCtx, callerCwd }) => {
28
- requireEnabled(callerCtx, mediaToolEnabled, 'media');
29
22
  const { executeMediaTool } = await import('../../runtime/media/tool.mjs');
30
23
  const { getSession } = await import('../../runtime/agent/orchestrator/session/manager/session-crud.mjs');
31
24
  // Generation spend is attributed to the calling session in the usage ledger.
@@ -38,7 +31,6 @@ export function createFeatureToolHandlers({ rt, setupTool, officeToolsEnabled, m
38
31
  });
39
32
  },
40
33
  tidy: async (args, { callerCtx, callerCwd }) => {
41
- requireEnabled(callerCtx, tidyToolEnabled, 'tidy');
42
34
  const { executeTidyTool } = await import('../../runtime/tidy/tool.mjs');
43
35
  return await executeTidyTool(args, {
44
36
  cwd: callerCwd,
@@ -50,6 +42,8 @@ export function createFeatureToolHandlers({ rt, setupTool, officeToolsEnabled, m
50
42
  await setupTool.execute(args || {}, {
51
43
  signal: signalFor(callerCtx),
52
44
  callerSessionId: callerCtx?.callerSessionId || null,
45
+ requestApproval: callerCtx?.toolApprovalHook || null,
46
+ toolCallId: callerCtx?.toolCallId || null,
53
47
  }),
54
48
  };
55
49
  }
@@ -88,6 +88,14 @@ export function createKnowledgeToolHandlers({
88
88
  if (!codeGraphMod?.executeCodeGraphTool) throw new Error('code_graph runtime is not available');
89
89
  return await codeGraphMod.executeCodeGraphTool(name, args || {}, args?.cwd || callerCwd);
90
90
  },
91
+ explore: async (args, { callerCtx, callerCwd }) => {
92
+ const { runExplore } = await import('../../runtime/explore/tool.mjs');
93
+ return await runExplore(args || {}, {
94
+ cwd: callerCwd,
95
+ signal: signalFor(callerCtx),
96
+ callerSessionId: callerCtx?.callerSessionId || callerCtx?.sessionId || rt.session?.id || null,
97
+ });
98
+ },
91
99
  load_tool: toolSearch,
92
100
  Skill: (args) => skillToolContent(args?.name, activeToolSurface(), rt.mode),
93
101
  };
@@ -17,6 +17,7 @@ import { scheduleCallerScope } from '../services/schedule-access.mjs';
17
17
  import { worktreeCallerScope } from '../services/worktree-access.mjs';
18
18
  import { resolveHandoffAttachments, sessionRoots } from '../handoff-attachments.mjs';
19
19
  import { delegationChainOf } from '../bot-chain.mjs';
20
+ import { openTodoItems } from '../../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
20
21
  import { BOT_TARGET_ACTIONS, resolveBotTarget } from '../bot-target.mjs';
21
22
 
22
23
  const USER_TITLE_ERROR = 'session: the user already titled this session; the title was not changed';
@@ -42,6 +43,140 @@ function callerAttachmentParts(rt, args, callerCwd, surface) {
42
43
  }).parts;
43
44
  }
44
45
 
46
+ /** `session` actions that act on another session through session control
47
+ * (list, bots, read, send, cancel, delete, create, status of a target). */
48
+ async function runSessionControl(
49
+ { rt, executeSessionControl, listBots, getSessionManager },
50
+ args,
51
+ { action, target, callerSessionId, callerCwd }
52
+ ) {
53
+ // `callerAgentId`: the bot whose conversation gets results reported
54
+ // back; `callerBotId`: the bot the caller acts as, attended or not,
55
+ // for what only a bot's own sessions allow (an effort change).
56
+ const callerAgentId = attendedAgentOf(rt.session);
57
+ const acting = resolveSessionMode({ session: rt.session });
58
+ const callerBotId = acting.mode === AGENT_MODE ? acting.agentId : '';
59
+ if (action === 'create' && !callerAgentId) {
60
+ throw new Error(
61
+ 'session: create belongs to a bot conversation; delegated workers, agent task sessions and schedule/webhook runs cannot create agent task sessions'
62
+ );
63
+ }
64
+ // A bot id names that bot's home chat; every check below and in the
65
+ // control runs on the chat it resolves to.
66
+ const sessionTarget = BOT_TARGET_ACTIONS.has(action) && target ? await resolveBotTarget(target, listBots) : target;
67
+ // A task session reaches its agent only through its reported result.
68
+ const origin = rt.session?.taskOrigin;
69
+ if (
70
+ action === 'send' &&
71
+ origin &&
72
+ (sessionTarget === origin.sessionId || agentIdOfHomeSession(sessionTarget) === origin.agentId)
73
+ ) {
74
+ throw new Error('session: a task session reports to its agent only through its result');
75
+ }
76
+ if (typeof executeSessionControl !== 'function') {
77
+ throw new Error('session: cross-session control is unavailable in this runtime');
78
+ }
79
+ const { attachments, ...rest } = args || {};
80
+ if (attachments !== undefined && action !== 'send' && action !== 'create') {
81
+ throw new Error(`session: attachments apply to send and create, not action=${action}`);
82
+ }
83
+ const attachmentParts = callerAttachmentParts(rt, args, callerCwd, 'session');
84
+ return JSON.stringify(
85
+ await executeSessionControl(
86
+ { ...rest, action, ...(sessionTarget !== target ? { session_id: sessionTarget } : {}) },
87
+ {
88
+ callerSessionId,
89
+ callerAgentId,
90
+ callerBotId,
91
+ callerCwd,
92
+ ...(action === 'send' || action === 'create'
93
+ ? {
94
+ callerHop: turnHopOf(rt.session),
95
+ // The bot chain this turn acts in (bot-chain.mjs), checked
96
+ // against the target and carried to the turn it starts —
97
+ // only when the sender is a bot conversation (a bot's chat,
98
+ // room seat or run); any other session hands work to any
99
+ // bot as before, whatever started its turn (the hop limit
100
+ // still bounds a loop).
101
+ callerBotChain: callerBotId
102
+ ? delegationChainOf(callerSessionId, (id) =>
103
+ id === rt.session?.id ? rt.session : getSessionManager()?.getSession?.(id) || null
104
+ )
105
+ : [],
106
+ }
107
+ : {}),
108
+ // Whether a create may provision a worktree (worktree-access.mjs).
109
+ ...(action === 'create' ? { callerScope: worktreeCallerScope(rt.session) } : {}),
110
+ // Which bots and sessions it may see (bot-status.mjs).
111
+ ...(action === 'bots' || action === 'list' ? { callerScope: scheduleCallerScope(rt.session) } : {}),
112
+ ...(attachmentParts.length ? { attachmentParts } : {}),
113
+ }
114
+ )
115
+ );
116
+ }
117
+
118
+ /** `session action=rename`: the AI title of the Lead session, mirrored onto the live session. */
119
+ async function renameSession({ rt, getSessionManager }, action, sessionId, args) {
120
+ if (rt.config?.aiSessionTitles === false) throw new Error('session: AI session titles are disabled in settings');
121
+ const title = clean(args?.title);
122
+ if (!title) throw new Error('session: title is required for action=rename');
123
+ const result = await getSessionManager()?.updateSessionAiTitle(sessionId, title);
124
+ if (!result?.ok) {
125
+ throw new Error(
126
+ result?.reason === 'user-title' ? USER_TITLE_ERROR : `session: rename failed (${result?.reason || 'unavailable'})`
127
+ );
128
+ }
129
+ // Mirror the store's truth onto the live session, never the AI title
130
+ // itself: a manual rename that landed while the save was awaited wins.
131
+ const stored = getSessionManager()?.getSession?.(sessionId);
132
+ if (stored && rt.session?.id === sessionId && stored !== rt.session) {
133
+ rt.session.title = stored.title;
134
+ rt.session.titleLocked = stored.titleLocked;
135
+ rt.session.titleSource = stored.titleSource;
136
+ rt.session.titleUpdatedAt = stored.titleUpdatedAt;
137
+ }
138
+ if (stored && stored.titleSource === 'user') throw new Error(USER_TITLE_ERROR);
139
+ return JSON.stringify({ action, sessionId, title: result.title }, null, 2);
140
+ }
141
+
142
+ /** `session action=fork`: inherit the Lead session into a new one. */
143
+ async function forkSession(getLifecycleApi, action, sessionId, args) {
144
+ const lifecycle = getLifecycleApi();
145
+ if (typeof lifecycle?.inheritToNewSession !== 'function') {
146
+ throw new Error('session: fork is unavailable in this runtime');
147
+ }
148
+ const result = await lifecycle.inheritToNewSession(sessionId, {
149
+ compact: args?.compact === true,
150
+ titleSuffix: ' (Fork)',
151
+ });
152
+ return JSON.stringify(
153
+ { action, sourceSessionId: sessionId, sessionId: result.sessionId, compacted: result.compacted === true },
154
+ null,
155
+ 2
156
+ );
157
+ }
158
+
159
+ /** `session action=status`: the current session's identity, folder and route. */
160
+ function sessionStatusJson(rt, callerCtx, currentCwd) {
161
+ const current = rt.session;
162
+ return JSON.stringify(
163
+ {
164
+ sessionId: callerCtx?.callerSessionId || current?.id || null,
165
+ title: current?.title || null,
166
+ titleSource: current?.titleSource || null,
167
+ cwd: currentCwd,
168
+ project: current?.workspace?.projectPath || current?.desktopSession?.projectPath || currentCwd,
169
+ provider: current?.provider || null,
170
+ model: current?.model || null,
171
+ effort: current?.effort || null,
172
+ autoEffort: current?.autoEffort !== false,
173
+ fast: current?.fast === true,
174
+ },
175
+ null,
176
+ 2
177
+ );
178
+ }
179
+
45
180
  export function createWorkspaceToolHandlers({
46
181
  rt,
47
182
  goalRuntime,
@@ -101,70 +236,12 @@ export function createWorkspaceToolHandlers({
101
236
  (action === 'status' && target)
102
237
  ) {
103
238
  const callerSessionId = assertLead(action, callerCtx);
104
- // `callerAgentId`: the bot whose conversation gets results reported
105
- // back; `callerBotId`: the bot the caller acts as, attended or not,
106
- // for what only a bot's own sessions allow (an effort change).
107
- const callerAgentId = attendedAgentOf(rt.session);
108
- const acting = resolveSessionMode({ session: rt.session });
109
- const callerBotId = acting.mode === AGENT_MODE ? acting.agentId : '';
110
- if (action === 'create' && !callerAgentId) {
111
- throw new Error(
112
- 'session: create belongs to a bot conversation; delegated workers, agent task sessions and schedule/webhook runs cannot create agent task sessions'
113
- );
114
- }
115
- // A bot id names that bot's home chat; every check below and in the
116
- // control runs on the chat it resolves to.
117
- const sessionTarget =
118
- BOT_TARGET_ACTIONS.has(action) && target ? await resolveBotTarget(target, listBots) : target;
119
- // A task session reaches its agent only through its reported result.
120
- const origin = rt.session?.taskOrigin;
121
- if (
122
- action === 'send' &&
123
- origin &&
124
- (sessionTarget === origin.sessionId || agentIdOfHomeSession(sessionTarget) === origin.agentId)
125
- ) {
126
- throw new Error('session: a task session reports to its agent only through its result');
127
- }
128
- if (typeof executeSessionControl !== 'function') {
129
- throw new Error('session: cross-session control is unavailable in this runtime');
130
- }
131
- const { attachments, ...rest } = args || {};
132
- if (attachments !== undefined && action !== 'send' && action !== 'create') {
133
- throw new Error(`session: attachments apply to send and create, not action=${action}`);
134
- }
135
- const attachmentParts = callerAttachmentParts(rt, args, callerCwd, 'session');
136
- return JSON.stringify(
137
- await executeSessionControl(
138
- { ...rest, action, ...(sessionTarget !== target ? { session_id: sessionTarget } : {}) },
139
- {
140
- callerSessionId,
141
- callerAgentId,
142
- callerBotId,
143
- callerCwd,
144
- ...(action === 'send' || action === 'create'
145
- ? {
146
- callerHop: turnHopOf(rt.session),
147
- // The bot chain this turn acts in (bot-chain.mjs), checked
148
- // against the target and carried to the turn it starts —
149
- // only when the sender is a bot conversation (a bot's chat,
150
- // room seat or run); any other session hands work to any
151
- // bot as before, whatever started its turn (the hop limit
152
- // still bounds a loop).
153
- callerBotChain: callerBotId
154
- ? delegationChainOf(callerSessionId, (id) =>
155
- id === rt.session?.id ? rt.session : getSessionManager()?.getSession?.(id) || null
156
- )
157
- : [],
158
- }
159
- : {}),
160
- // Whether a create may provision a worktree (worktree-access.mjs).
161
- ...(action === 'create' ? { callerScope: worktreeCallerScope(rt.session) } : {}),
162
- // Which bots and sessions it may see (bot-status.mjs).
163
- ...(action === 'bots' || action === 'list' ? { callerScope: scheduleCallerScope(rt.session) } : {}),
164
- ...(attachmentParts.length ? { attachmentParts } : {}),
165
- }
166
- )
167
- );
239
+ return runSessionControl({ rt, executeSessionControl, listBots, getSessionManager }, args, {
240
+ action,
241
+ target,
242
+ callerSessionId,
243
+ callerCwd,
244
+ });
168
245
  }
169
246
  // Mixy's proposals to the user (mixy-heartbeat.mjs): kept so none repeats.
170
247
  if (action === 'suggest') {
@@ -184,28 +261,7 @@ export function createWorkspaceToolHandlers({
184
261
  if (action === 'status' || action === 'list-projects' || action === 'set-project') assertLead(action, callerCtx);
185
262
  if (action === 'rename') {
186
263
  const sessionId = assertLead(action, callerCtx);
187
- if (rt.config?.aiSessionTitles === false) throw new Error('session: AI session titles are disabled in settings');
188
- const title = clean(args?.title);
189
- if (!title) throw new Error('session: title is required for action=rename');
190
- const result = await getSessionManager()?.updateSessionAiTitle(sessionId, title);
191
- if (!result?.ok) {
192
- throw new Error(
193
- result?.reason === 'user-title'
194
- ? USER_TITLE_ERROR
195
- : `session: rename failed (${result?.reason || 'unavailable'})`
196
- );
197
- }
198
- // Mirror the store's truth onto the live session, never the AI title
199
- // itself: a manual rename that landed while the save was awaited wins.
200
- const stored = getSessionManager()?.getSession?.(sessionId);
201
- if (stored && rt.session?.id === sessionId && stored !== rt.session) {
202
- rt.session.title = stored.title;
203
- rt.session.titleLocked = stored.titleLocked;
204
- rt.session.titleSource = stored.titleSource;
205
- rt.session.titleUpdatedAt = stored.titleUpdatedAt;
206
- }
207
- if (stored && stored.titleSource === 'user') throw new Error(USER_TITLE_ERROR);
208
- return JSON.stringify({ action, sessionId, title: result.title }, null, 2);
264
+ return renameSession({ rt, getSessionManager }, action, sessionId, args);
209
265
  }
210
266
  if (action === 'compact') {
211
267
  const sessionId = assertLead(action, callerCtx);
@@ -219,38 +275,10 @@ export function createWorkspaceToolHandlers({
219
275
  }
220
276
  if (action === 'fork') {
221
277
  const sessionId = assertLead(action, callerCtx);
222
- const lifecycle = getLifecycleApi();
223
- if (typeof lifecycle?.inheritToNewSession !== 'function') {
224
- throw new Error('session: fork is unavailable in this runtime');
225
- }
226
- const result = await lifecycle.inheritToNewSession(sessionId, {
227
- compact: args?.compact === true,
228
- titleSuffix: ' (Fork)',
229
- });
230
- return JSON.stringify(
231
- { action, sourceSessionId: sessionId, sessionId: result.sessionId, compacted: result.compacted === true },
232
- null,
233
- 2
234
- );
278
+ return forkSession(getLifecycleApi, action, sessionId, args);
235
279
  }
236
280
  if (action === 'status') {
237
- const current = rt.session;
238
- return JSON.stringify(
239
- {
240
- sessionId: callerCtx?.callerSessionId || current?.id || null,
241
- title: current?.title || null,
242
- titleSource: current?.titleSource || null,
243
- cwd: currentCwd,
244
- project: current?.workspace?.projectPath || current?.desktopSession?.projectPath || currentCwd,
245
- provider: current?.provider || null,
246
- model: current?.model || null,
247
- effort: current?.effort || null,
248
- autoEffort: current?.autoEffort !== false,
249
- fast: current?.fast === true,
250
- },
251
- null,
252
- 2
253
- );
281
+ return sessionStatusJson(rt, callerCtx, currentCwd);
254
282
  }
255
283
  if (action === 'list-projects') {
256
284
  return JSON.stringify(
@@ -295,9 +323,21 @@ export function createWorkspaceToolHandlers({
295
323
  goal: async (args, { name, callerCtx }) => {
296
324
  // A Goal keeps working in its session across turns: a heartbeat's would
297
325
  // run on unseen in the hidden session.
298
- if (['create', 'resume'].includes(clean(args?.action).toLowerCase()) && callerIsHeartbeat(callerCtx)) {
326
+ const action = clean(args?.action).toLowerCase();
327
+ if (action === 'create' && callerIsHeartbeat(callerCtx)) {
299
328
  throw new Error(`goal: ${HEARTBEAT_NO_HANDOFF}`);
300
329
  }
330
+ // A completion claim with steps still open in the session's own list
331
+ // has not finished the work it recorded.
332
+ const callerSessionId = callerCtx?.callerSessionId || rt.session?.id || null;
333
+ if (action === 'complete' && rt.session?.id === callerSessionId) {
334
+ const open = openTodoItems(rt.session);
335
+ if (open.length) {
336
+ throw new Error(
337
+ `goal: cannot complete with ${open.length} open todo item(s) (${open.map((task) => task.content).join('; ')}); finish them, or drop or block each with its reason`
338
+ );
339
+ }
340
+ }
301
341
  return await goalRuntime.executeTool(name, args || {}, {
302
342
  callerSessionId: callerCtx?.callerSessionId || rt.session?.id || rt.reservedSessionId || null,
303
343
  });
@@ -308,9 +348,10 @@ export function createWorkspaceToolHandlers({
308
348
  if (['spawn', 'send'].includes((clean(args?.type) || 'spawn').toLowerCase()) && callerIsHeartbeat(callerCtx)) {
309
349
  throw new Error(`agent: ${HEARTBEAT_NO_HANDOFF}`);
310
350
  }
311
- // `attachmentParts` is never the model's to set: only the resolved
312
- // `attachments` reach the agent's turn.
313
- const { attachments, attachmentParts: _ignored, ...rest } = args || {};
351
+ // `attachmentParts` and `skillSelection` are never the model's to set:
352
+ // only the resolved `attachments` reach the agent's turn, and its skills
353
+ // are selected from its whole prompt.
354
+ const { attachments, attachmentParts: _ignored, skillSelection: _selection, ...rest } = args || {};
314
355
  const attachmentParts = callerAttachmentParts(rt, { attachments }, callerCwd, 'agent');
315
356
  return await agentTool.execute(attachmentParts.length ? { ...rest, attachmentParts } : rest, {
316
357
  callerCwd,
@@ -6,6 +6,7 @@
6
6
  * to channel tools.
7
7
  */
8
8
  import { clean } from '../runtime/agent/orchestrator/runtime-core/session-text.mjs';
9
+ import { settingDisabledIn } from '../runtime/agent/orchestrator/runtime-core/tool-availability.mjs';
9
10
  import { createAskUserToolHandlers } from './internal-tool-executor/ask-user-tool.mjs';
10
11
  import { createBridgeToolHandlers } from './internal-tool-executor/bridge-tools.mjs';
11
12
  import { createFeatureToolHandlers } from './internal-tool-executor/feature-tools.mjs';
@@ -19,11 +20,7 @@ export function createInternalToolExecutor({
19
20
  goalRuntime,
20
21
  agentTool,
21
22
  setupTool,
22
- webSearchEnabled,
23
- memoryToolsEnabled,
24
- officeToolsEnabled,
25
- mediaToolEnabled,
26
- tidyToolEnabled = () => true,
23
+ featureDisallowedTools = () => [],
27
24
  getWebSearchModule,
28
25
  getMemoryModule,
29
26
  getCodeGraphModule,
@@ -42,7 +39,7 @@ export function createInternalToolExecutor({
42
39
  ...createBridgeToolHandlers({ rt }),
43
40
  ...createAskUserToolHandlers({ rt }),
44
41
  ...createReactionToolHandlers({ rt }),
45
- ...createFeatureToolHandlers({ rt, setupTool, officeToolsEnabled, mediaToolEnabled, tidyToolEnabled }),
42
+ ...createFeatureToolHandlers({ rt, setupTool }),
46
43
  ...createKnowledgeToolHandlers({
47
44
  rt,
48
45
  getWebSearchModule,
@@ -67,24 +64,20 @@ export function createInternalToolExecutor({
67
64
  }),
68
65
  };
69
66
 
70
- // Settings-disabled features are refused for model-initiated calls before
71
- // any handler runs; the tool list is refreshed by a new session.
72
- const guardModelCall = (name) => {
73
- if ((name === 'web_search' || name === 'web_fetch') && !webSearchEnabled()) {
74
- throw new Error('web search is disabled in settings; start a new session to refresh the tool list');
75
- }
76
- if ((name === 'memory' || name === 'recall') && !memoryToolsEnabled()) {
77
- throw new Error(
78
- 'memory tools are disabled in settings; background memory and manual core memory remain available'
79
- );
80
- }
81
- };
67
+ // A model call of a tool a setting turned off is refused at dispatch
68
+ // (tool-exec/dispatch.mjs settingDisabledTool, built-ins such as git
69
+ // included); a model-tool call reaching this executor directly takes the
70
+ // same check against this runtime's live gate list.
82
71
 
83
72
  return async (name, args, callerCtx = {}) => {
84
73
  const callerCwd = clean(callerCtx?.callerCwd) || rt.currentCwd;
85
74
  // The Reactions setting gates the tool whoever calls it, not only the model.
86
75
  if (name === 'react' && rt.config?.reactions === false) throw new Error('reactions are turned off in settings');
87
- if (callerCtx?.invocationSource === 'model-tool') guardModelCall(name);
76
+ const disabled =
77
+ callerCtx?.invocationSource === 'model-tool' ? settingDisabledIn(name, featureDisallowedTools()) : null;
78
+ if (disabled) {
79
+ throw new Error(`${disabled} is disabled in settings by the user; do not retry unless the user turns it back on`);
80
+ }
88
81
  if (Object.hasOwn(handlers, name)) return handlers[name](args, { name, callerCtx, callerCwd });
89
82
  if (channels.isChannelTool(name)) {
90
83
  return await channels.execute(name, args || {});
@@ -35,9 +35,16 @@ const SOURCE_RUNTIME_FIELDS = [
35
35
  'toolApprovalHook',
36
36
  '_providerPrefixGuardState',
37
37
  'activeTurnCheckpoint',
38
+ // The source's durable transcript identity (store/transcript-durability.mjs).
39
+ 'transcriptEpoch',
40
+ 'turnCoverage',
38
41
  'deferredInitialRefreshPending',
39
42
  'pendingGoalReminder',
40
43
  'goalReminderRevision',
44
+ 'goalStalledNotice',
45
+ // The source's own step list and its reminder cycle.
46
+ 'todo',
47
+ 'todoCheck',
41
48
  'pendingCacheBreakIntent',
42
49
  'contextPressureUnanchoredAfterRestart',
43
50
  'contextPressureUnanchoredReason',
@@ -4,9 +4,9 @@
4
4
  */
5
5
  const INGEST_DEADLINE_MS = 2500;
6
6
 
7
- // Sessions that never compacted had NO session-sourced rows (ingest_session
8
- // previously ran only inside compaction), so recall could not reconstruct
9
- // the most recent conversations. Deadline-capped: the row inserts are fast
7
+ // Sessions that never compacted have no session-sourced rows unless ingested
8
+ // here, and recall could not reconstruct the most recent conversations
9
+ // without them. Deadline-capped: the row inserts are fast
10
10
  // and committed even if the bounded wait elapses during the trailing
11
11
  // embedding flush (the raw-embedding backlog sweep embeds them later). Never
12
12
  // loads the memory runtime just for this — a null module promise means
@@ -14,6 +14,7 @@ import {
14
14
  import { SESSION_ID_PATTERN, closeManagedSession } from '../shared.mjs';
15
15
  import { replacementSessionCwd } from '../../workspace/workspace-state.mjs';
16
16
  import { isHistoricalAutomaticClosure } from '../../../runtime/agent/orchestrator/session/historical-session-closure.mjs';
17
+ import { readSessionSidebarState } from '../../../runtime/shared/session-sidebar-host.mjs';
17
18
 
18
19
  export function createSessionDelete(deps, { cancelBackgroundTasks }) {
19
20
  const {
@@ -38,12 +39,13 @@ export function createSessionDelete(deps, { cancelBackgroundTasks }) {
38
39
  // Availability is one strict read of the session's own file, filtered like
39
40
  // the session catalog (an unreadable, foreign, closed or non-catalogued
40
41
  // record is not deletable). No catalog rebuild, no folder scan.
41
- function isAvailableSession(sessionId) {
42
+ function availableRecord(sessionId) {
42
43
  const stored = _storedSessionFromFile(getStoreDir(), `${sessionId}.json`);
43
- if (!stored || stored === STORED_SESSION_UNREADABLE) return false;
44
- if (stored.closed === true && !isHistoricalAutomaticClosure(stored)) return false;
45
- return leadSessionRow(stored) !== null;
44
+ if (!stored || stored === STORED_SESSION_UNREADABLE) return null;
45
+ if (stored.closed === true && !isHistoricalAutomaticClosure(stored)) return null;
46
+ return leadSessionRow(stored) !== null ? stored : null;
46
47
  }
48
+ const isAvailableSession = (sessionId) => availableRecord(sessionId) !== null;
47
49
 
48
50
  // The deleted task's worktree: the autoCleanup setting decides (clean and
49
51
  // merged → removed; otherwise kept). Off the deletion path; never fails it.
@@ -102,5 +104,51 @@ export function createSessionDelete(deps, { cancelBackgroundTasks }) {
102
104
  return true;
103
105
  }
104
106
 
105
- return { releaseSessionWork, deleteSession };
107
+ /**
108
+ * The desktop's auto-delete of an archived session: only one that is still
109
+ * archived, not a favorite, idle (no turn running, waiting for its ask lock
110
+ * or queued) and unchanged since the caller looked (`expected.lastUsedAt`,
111
+ * which every turn moves). It holds the session's ask lock, which every
112
+ * turn takes, and runs its last checks, the close and the delete in one
113
+ * synchronous stretch, so no turn can start in between. A refusal closes
114
+ * and deletes nothing: `{ deleted: false, reason }`. `isHostedBusy` (the
115
+ * session service) reports queued input in a runtime hosting the session.
116
+ */
117
+ async function deleteSessionIfIdle(id, expected = {}, { isHostedBusy = null } = {}) {
118
+ const sessionId = clean(id);
119
+ const refuse = (reason) => ({ deleted: false, reason });
120
+ if (!sessionId || !SESSION_ID_PATTERN.test(sessionId)) return refuse('invalid');
121
+ if (typeof isHostedBusy !== 'function') return refuse('unguarded');
122
+ if (getSession()?.id === sessionId) return refuse('current');
123
+ const unlock = mgr.tryAcquireSessionLock(sessionId);
124
+ if (!unlock) return refuse('busy');
125
+ try {
126
+ // The archive and favorite flags are the desktop's.
127
+ const sidebar = await readSessionSidebarState();
128
+ if (!sidebar || !Object.hasOwn(sidebar.archived ?? {}, sessionId)) return refuse('not-archived');
129
+ if (Object.hasOwn(sidebar.favorites ?? {}, sessionId)) return refuse('favorite');
130
+ // From here to the delete: synchronous.
131
+ if (mgr.sessionLockContended(sessionId)) return refuse('turn-waiting');
132
+ if (mgr.isSessionTurnInFlight(sessionId) || mgr.hasUnsettledTurn(sessionId)) return refuse('busy');
133
+ if (mgr.hasPendingMessages(sessionId) || isHostedBusy(sessionId)) return refuse('queued');
134
+ const stored = availableRecord(sessionId);
135
+ if (!stored) return refuse('missing');
136
+ if ((Number(stored.lastUsedAt) || 0) !== (Number(expected?.lastUsedAt) || 0)) return refuse('changed');
137
+ const reason = 'desktop-auto-delete';
138
+ // The blocking close: its barrier lands before this stretch yields.
139
+ if (closeManagedSession(mgr, sessionId, reason, { tombstone: false }, false) !== true) {
140
+ return refuse('close-failed');
141
+ }
142
+ agentTool?.forgetLeadSession?.(sessionId);
143
+ releaseSessionWork(sessionId, reason);
144
+ if (mgr.deleteSession(sessionId, { fenceWrites: true }) !== true) return refuse('delete-failed');
145
+ void forgetSessionSearch(sessionId);
146
+ void releaseDeletedWorktree(sessionId);
147
+ return { deleted: true };
148
+ } finally {
149
+ unlock();
150
+ }
151
+ }
152
+
153
+ return { releaseSessionWork, deleteSession, deleteSessionIfIdle };
106
154
  }
@@ -15,7 +15,9 @@ export { resolveResumeCwd } from './session-switch/resume.mjs';
15
15
 
16
16
  export function createSessionSwitching(deps, { ingestSessionIntoMemory, closeSurfaceSession, cancelBackgroundTasks }) {
17
17
  const { mgr, getMode } = deps;
18
- const { releaseSessionWork, deleteSession } = createSessionDelete(deps, { cancelBackgroundTasks });
18
+ const { releaseSessionWork, deleteSession, deleteSessionIfIdle } = createSessionDelete(deps, {
19
+ cancelBackgroundTasks,
20
+ });
19
21
  const { switchContext, newSession } = createContextSwitch(deps, {
20
22
  ingestSessionIntoMemory,
21
23
  closeSurfaceSession,
@@ -41,5 +43,14 @@ export function createSessionSwitching(deps, { ingestSessionIntoMemory, closeSur
41
43
  return mgr.prefetchSession?.(id, toolSpecForMode(getMode())) === true;
42
44
  }
43
45
 
44
- return { listSessions, sessionStoreDir, deleteSession, switchContext, newSession, prefetchSession, resume };
46
+ return {
47
+ listSessions,
48
+ sessionStoreDir,
49
+ deleteSession,
50
+ deleteSessionIfIdle,
51
+ switchContext,
52
+ newSession,
53
+ prefetchSession,
54
+ resume,
55
+ };
45
56
  }