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
@@ -0,0 +1,367 @@
1
+ // The per-owner step list behind the `todo` tool. One list lives on each
2
+ // session record (`session.todo`: the Lead session, and each agent session),
3
+ // so it is saved with the session, survives a daemon restart and compaction,
4
+ // and is never shared between a Lead and its agents.
5
+ //
6
+ // Every mutation replaces `session.todo` with a new object: the published
7
+ // snapshot is memoized by that identity, and change listeners republish it.
8
+ import { emitSessionActivityChange } from '../../../shared/session-activity-signal.mjs';
9
+ import { MAX_TODO_ITEMS, MAX_TODO_TEXT_LENGTH, TODO_OPS, TODO_STATUSES } from './todo-tool-defs.mjs';
10
+
11
+ const DEFAULT_TODO_PHASE = 'Tasks';
12
+ const OPEN_STATUSES = new Set(['pending', 'in_progress']);
13
+ const listeners = new Set();
14
+ const snapshots = new WeakMap();
15
+
16
+ const oneLine = (value) =>
17
+ String(value ?? '')
18
+ .replace(/\s+/g, ' ')
19
+ .trim();
20
+
21
+ function itemText(value, what = 'item') {
22
+ const text = oneLine(value);
23
+ if (!text) throw new Error(`todo: ${what} wording is required`);
24
+ if ([...text].length > MAX_TODO_TEXT_LENGTH) {
25
+ throw new Error(`todo: ${what} exceeds ${MAX_TODO_TEXT_LENGTH} characters`);
26
+ }
27
+ return text;
28
+ }
29
+
30
+ function normalizeTask(raw) {
31
+ if (!raw || typeof raw !== 'object') return null;
32
+ const content = oneLine(raw.content);
33
+ if (!content) return null;
34
+ const status = TODO_STATUSES.includes(raw.status) ? raw.status : 'pending';
35
+ const task = { content, status };
36
+ if (status === 'blocked' && oneLine(raw.blocker)) task.blocker = oneLine(raw.blocker);
37
+ if (oneLine(raw.note)) task.note = oneLine(raw.note);
38
+ return task;
39
+ }
40
+
41
+ /** The session's phases, normalized (stored records are untrusted). */
42
+ export function todoPhases(session) {
43
+ const phases = Array.isArray(session?.todo?.phases) ? session.todo.phases : [];
44
+ return phases
45
+ .map((phase) => ({
46
+ name: oneLine(phase?.name) || DEFAULT_TODO_PHASE,
47
+ tasks: (Array.isArray(phase?.tasks) ? phase.tasks : []).map(normalizeTask).filter(Boolean),
48
+ }))
49
+ .filter((phase) => phase.tasks.length > 0);
50
+ }
51
+
52
+ const allTasks = (phases) => phases.flatMap((phase) => phase.tasks);
53
+
54
+ /** Exactly one in_progress while actionable work exists: several keep the
55
+ * earliest, none starts the earliest pending. Blocked never starts itself. */
56
+ function normalizeTodoPhases(phases) {
57
+ const tasks = allTasks(phases);
58
+ const active = tasks.filter((task) => task.status === 'in_progress');
59
+ for (const task of active.slice(1)) task.status = 'pending';
60
+ if (active.length === 0) {
61
+ const next = tasks.find((task) => task.status === 'pending');
62
+ if (next) next.status = 'in_progress';
63
+ }
64
+ return phases.filter((phase) => phase.tasks.length > 0);
65
+ }
66
+
67
+ function todoCounts(phases) {
68
+ const tasks = allTasks(phases);
69
+ return {
70
+ completed: tasks.filter((task) => task.status === 'completed').length,
71
+ abandoned: tasks.filter((task) => task.status === 'abandoned').length,
72
+ total: tasks.length,
73
+ };
74
+ }
75
+
76
+ /** Pending and in-progress items: the work the completion check asks about. */
77
+ export function openTodoItems(session) {
78
+ return allTasks(todoPhases(session)).filter((task) => OPEN_STATUSES.has(task.status));
79
+ }
80
+
81
+ /** Every item not completed or dropped (blocked included): what an agent
82
+ * leaves undone when it ends. */
83
+ export function unfinishedTodoItems(session) {
84
+ return allTasks(todoPhases(session)).filter((task) => task.status !== 'completed' && task.status !== 'abandoned');
85
+ }
86
+
87
+ /** The published session snapshot; null for an empty list. Identity-stable
88
+ * while the list is unchanged. */
89
+ export function todoSnapshot(session) {
90
+ const record = session?.todo;
91
+ if (!record || typeof record !== 'object') return null;
92
+ if (snapshots.has(record)) return snapshots.get(record);
93
+ const phases = todoPhases(session);
94
+ const snapshot = phases.length ? { phases, ...todoCounts(phases) } : null;
95
+ snapshots.set(record, snapshot);
96
+ return snapshot;
97
+ }
98
+
99
+ /** Agent status rows: `{ completed, total, current? }`, or null. */
100
+ export function todoProgress(session) {
101
+ const snapshot = todoSnapshot(session);
102
+ if (!snapshot) return null;
103
+ const current = allTasks(snapshot.phases).find((task) => task.status === 'in_progress')?.content;
104
+ // Rows show completed/total directly, so dropped items leave the total.
105
+ return {
106
+ completed: snapshot.completed,
107
+ total: snapshot.total - snapshot.abandoned,
108
+ ...(current ? { current } : {}),
109
+ };
110
+ }
111
+
112
+ export function onTodoChange(listener) {
113
+ if (typeof listener !== 'function') return () => {};
114
+ listeners.add(listener);
115
+ return () => listeners.delete(listener);
116
+ }
117
+
118
+ /** A list with items, every one completed or dropped. */
119
+ export function todoAllClosed(session) {
120
+ return todoPhases(session).length > 0 && unfinishedTodoItems(session).length === 0;
121
+ }
122
+
123
+ /** Let go of the session's list. */
124
+ export function clearTodo(session, at = Date.now()) {
125
+ session.todo = null;
126
+ session.updatedAt = at;
127
+ publish(session);
128
+ }
129
+
130
+ function commitPhases(session, phases, at = Date.now()) {
131
+ session.todo = { phases, updatedAt: at };
132
+ session.updatedAt = at;
133
+ publish(session);
134
+ }
135
+
136
+ function publish(session) {
137
+ // The Agents pool shows each agent's progress: it re-reads on this pulse.
138
+ emitSessionActivityChange(session.id || '');
139
+ for (const listener of [...listeners]) {
140
+ try {
141
+ listener({ sessionId: session.id || null, todo: todoSnapshot(session) });
142
+ } catch {
143
+ /* a listener never breaks the tool */
144
+ }
145
+ }
146
+ }
147
+
148
+ const MARKS = { completed: 'x', in_progress: '>', pending: ' ', blocked: '!', abandoned: '-' };
149
+
150
+ function progressLabel(phases) {
151
+ const { completed, abandoned, total } = todoCounts(phases);
152
+ return `${completed}/${total - abandoned}`;
153
+ }
154
+
155
+ /** The whole list as text: init/view replies and context re-injection. */
156
+ function renderTodoList(phases) {
157
+ if (!phases.length) return 'todo: empty';
158
+ const lines = [progressLabel(phases)];
159
+ for (const phase of phases) {
160
+ lines.push(phase.name);
161
+ for (const task of phase.tasks) {
162
+ const detail = task.blocker ? ` — blocked: ${task.blocker}` : task.note ? ` — ${task.note}` : '';
163
+ lines.push(` [${MARKS[task.status]}] ${task.content}${detail}`);
164
+ }
165
+ }
166
+ return lines.join('\n');
167
+ }
168
+
169
+ function summaryLine(phases, op, content) {
170
+ const tasks = allTasks(phases);
171
+ const parts = [progressLabel(phases), `${op}: ${content}`];
172
+ const current = tasks.find((task) => task.status === 'in_progress');
173
+ if (current) parts.push(`next: ${current.content}`);
174
+ else if (tasks.some((task) => task.status === 'blocked')) parts.push('next: none (blocked items wait)');
175
+ else parts.push('all closed');
176
+ return parts.join(' · ');
177
+ }
178
+
179
+ function initPhases(args) {
180
+ let source;
181
+ if (Array.isArray(args.phases) && args.phases.length) source = args.phases;
182
+ else if (Array.isArray(args.items) && args.items.length) {
183
+ source = [{ name: oneLine(args.phase) || DEFAULT_TODO_PHASE, items: args.items }];
184
+ } else throw new Error('todo: init requires items or phases');
185
+ const seen = new Set();
186
+ const phaseNames = new Set();
187
+ const phases = source.map((entry) => {
188
+ const name = itemText(entry?.name, 'phase');
189
+ if (phaseNames.has(name)) throw new Error(`todo: duplicate phase "${name}"`);
190
+ phaseNames.add(name);
191
+ const items = Array.isArray(entry?.items) ? entry.items : [];
192
+ if (!items.length) throw new Error(`todo: phase "${name}" has no items`);
193
+ return {
194
+ name,
195
+ tasks: items.map((raw) => {
196
+ const content = itemText(raw);
197
+ if (seen.has(content)) throw new Error(`todo: duplicate item "${content}"`);
198
+ seen.add(content);
199
+ return { content, status: 'pending' };
200
+ }),
201
+ };
202
+ });
203
+ if (seen.size > MAX_TODO_ITEMS) throw new Error(`todo: at most ${MAX_TODO_ITEMS} items`);
204
+ return phases;
205
+ }
206
+
207
+ function findTask(phases, rawContent) {
208
+ const content = oneLine(rawContent);
209
+ if (!content) throw new Error('todo: item (its exact wording) is required');
210
+ for (const phase of phases) {
211
+ const index = phase.tasks.findIndex((task) => task.content === content);
212
+ if (index >= 0) return { phase, index, task: phase.tasks[index] };
213
+ }
214
+ throw new Error(`todo: no item "${content}"; view the list for exact wordings`);
215
+ }
216
+
217
+ const OPS = {
218
+ start(phases, args) {
219
+ const { task } = findTask(phases, args.item);
220
+ if (task.status === 'completed') throw new Error(`todo: "${task.content}" is completed and stays closed`);
221
+ if (task.status === 'blocked') throw new Error(`todo: "${task.content}" is blocked; unblock it first`);
222
+ for (const other of allTasks(phases)) if (other.status === 'in_progress') other.status = 'pending';
223
+ task.status = 'in_progress';
224
+ return task.content;
225
+ },
226
+ done(phases, args) {
227
+ const { task } = findTask(phases, args.item);
228
+ task.status = 'completed';
229
+ delete task.blocker;
230
+ const note = oneLine(args.note);
231
+ if (note) task.note = note;
232
+ return task.content;
233
+ },
234
+ drop(phases, args) {
235
+ const { task } = findTask(phases, args.item);
236
+ if (task.status === 'completed') throw new Error(`todo: "${task.content}" is completed and stays closed`);
237
+ task.status = 'abandoned';
238
+ delete task.blocker;
239
+ return task.content;
240
+ },
241
+ block(phases, args) {
242
+ const { task } = findTask(phases, args.item);
243
+ if (task.status === 'completed' || task.status === 'abandoned') {
244
+ throw new Error(`todo: "${task.content}" is ${task.status}; only open items can block`);
245
+ }
246
+ task.status = 'blocked';
247
+ task.blocker = itemText(args.reason, 'block reason');
248
+ return task.content;
249
+ },
250
+ unblock(phases, args) {
251
+ const { task } = findTask(phases, args.item);
252
+ if (task.status !== 'blocked') throw new Error(`todo: "${task.content}" is not blocked`);
253
+ task.status = 'pending';
254
+ delete task.blocker;
255
+ return task.content;
256
+ },
257
+ append(phases, args) {
258
+ const items = Array.isArray(args.items) ? args.items.map((raw) => itemText(raw)) : [];
259
+ if (!items.length) throw new Error('todo: append requires items');
260
+ const existing = new Set(allTasks(phases).map((task) => task.content));
261
+ for (const content of items) {
262
+ if (existing.has(content)) throw new Error(`todo: item "${content}" already exists`);
263
+ existing.add(content);
264
+ }
265
+ if (existing.size > MAX_TODO_ITEMS) throw new Error(`todo: at most ${MAX_TODO_ITEMS} items`);
266
+ const name = oneLine(args.phase) || phases.at(-1)?.name || DEFAULT_TODO_PHASE;
267
+ let phase = phases.find((candidate) => candidate.name === name);
268
+ if (!phase) {
269
+ phase = { name, tasks: [] };
270
+ phases.push(phase);
271
+ }
272
+ phase.tasks.push(...items.map((content) => ({ content, status: 'pending' })));
273
+ return items.join(', ');
274
+ },
275
+ rm(phases, args) {
276
+ const { phase, index, task } = findTask(phases, args.item);
277
+ phase.tasks.splice(index, 1);
278
+ return task.content;
279
+ },
280
+ };
281
+
282
+ /** Run one `todo` call against the owner session. Returns the reply text. */
283
+ export function executeTodoTool(session, args = {}) {
284
+ if (!session || typeof session !== 'object') throw new Error('todo: no session owns this call');
285
+ const op = oneLine(args?.op).toLowerCase();
286
+ if (!TODO_OPS.includes(op)) throw new Error(`todo: op must be one of ${TODO_OPS.join(', ')}`);
287
+ if (op === 'view') return renderTodoList(todoPhases(session));
288
+ if (op === 'init') {
289
+ // Replacing a list that still has unfinished work would silently erase it
290
+ // (a follow-up ask re-initing mid-request): make the model close each first.
291
+ const unfinished = unfinishedTodoItems(session);
292
+ if (unfinished.length) {
293
+ const named = unfinished.slice(0, 5).map((task) => `"${task.content}"`);
294
+ if (unfinished.length > named.length) named.push(`${unfinished.length - named.length} more`);
295
+ throw new Error(
296
+ `todo: init would erase unfinished items (${named.join(', ')}); done or drop each first, or append to add asks`
297
+ );
298
+ }
299
+ const phases = normalizeTodoPhases(initPhases(args));
300
+ commitPhases(session, phases);
301
+ return renderTodoList(phases);
302
+ }
303
+ const phases = structuredClone(todoPhases(session));
304
+ if (!phases.length) throw new Error('todo: the list is empty; init it first');
305
+ const content = OPS[op](phases, args);
306
+ const next = normalizeTodoPhases(phases);
307
+ commitPhases(session, next);
308
+ return summaryLine(next, op, content);
309
+ }
310
+
311
+ /** Lines naming what an agent leaves undone, '' when nothing is. */
312
+ export function notDoneReport(session) {
313
+ const unfinished = unfinishedTodoItems(session);
314
+ if (!unfinished.length) return '';
315
+ return [
316
+ 'Not done:',
317
+ ...unfinished.map((task) => `- ${task.content}${task.blocker ? ` (blocked: ${task.blocker})` : ''}`),
318
+ ].join('\n');
319
+ }
320
+
321
+ /** The open list as a hidden reminder (after compaction, or appended to a
322
+ * Goal continuation); '' when nothing is open. */
323
+ export function todoContextBlock(session, lead = 'Open todo items (exact wordings):', { whole = false } = {}) {
324
+ const phases = todoPhases(session);
325
+ if (!phases.length) return '';
326
+ if (!whole && !allTasks(phases).some((task) => task.status !== 'completed' && task.status !== 'abandoned')) {
327
+ return '';
328
+ }
329
+ return ['<todo_state>', lead, renderTodoList(phases), '</todo_state>'].join('\n');
330
+ }
331
+
332
+ // Legacy Goal task statuses as todo statuses.
333
+ const LEGACY_GOAL_TASK_STATUS = {
334
+ pending: 'pending',
335
+ in_progress: 'in_progress',
336
+ completed: 'completed',
337
+ dropped: 'abandoned',
338
+ awaiting_approval: 'blocked',
339
+ };
340
+
341
+ /** Move a legacy Goal record's tasks into the session's list (once; the Goal
342
+ * record drops them afterwards). Items already listed keep their state. */
343
+ export function adoptLegacyGoalTasks(session, legacyTasks) {
344
+ if (!session || !Array.isArray(legacyTasks) || !legacyTasks.length) return false;
345
+ const phases = structuredClone(todoPhases(session));
346
+ const existing = new Set(allTasks(phases).map((task) => task.content));
347
+ const adopted = [];
348
+ for (const raw of legacyTasks) {
349
+ // Migrated wording stays whole (old tasks allowed longer text); the
350
+ // length limit applies only to newly authored items.
351
+ const content = oneLine(raw?.text ?? raw?.content);
352
+ if (!content || existing.has(content)) continue;
353
+ existing.add(content);
354
+ const status = LEGACY_GOAL_TASK_STATUS[oneLine(raw?.status).toLowerCase()] || 'pending';
355
+ adopted.push(status === 'blocked' ? { content, status, blocker: 'awaiting user approval' } : { content, status });
356
+ }
357
+ if (!adopted.length) return false;
358
+ const name = phases.length ? 'Goal' : DEFAULT_TODO_PHASE;
359
+ let phase = phases.find((candidate) => candidate.name === name);
360
+ if (!phase) {
361
+ phase = { name, tasks: [] };
362
+ phases.push(phase);
363
+ }
364
+ phase.tasks.push(...adopted);
365
+ commitPhases(session, normalizeTodoPhases(phases));
366
+ return true;
367
+ }
@@ -0,0 +1,47 @@
1
+ // The model-facing `todo` step list. Its description is the only guidance the
2
+ // model gets about it: nothing is added to the system prompt or rules.
3
+ export const TODO_OPS = Object.freeze(['init', 'start', 'done', 'drop', 'block', 'unblock', 'append', 'rm', 'view']);
4
+ export const TODO_STATUSES = Object.freeze(['pending', 'in_progress', 'completed', 'abandoned', 'blocked']);
5
+ export const MAX_TODO_ITEMS = 50;
6
+ export const MAX_TODO_TEXT_LENGTH = 200;
7
+
8
+ const itemList = { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: MAX_TODO_ITEMS };
9
+
10
+ export const TODO_TOOL = Object.freeze({
11
+ name: 'todo',
12
+ title: 'Todo',
13
+ annotations: {
14
+ title: 'Todo',
15
+ readOnlyHint: false,
16
+ destructiveHint: false,
17
+ idempotentHint: false,
18
+ openWorldHint: false,
19
+ agentHidden: false,
20
+ },
21
+ description:
22
+ 'The step list for this request; the Lead and each agent keep their own. Use it whenever the work has three or more steps or several asks (a delegated brief with several parts counts); skip it only for a single step or a plain answer. Create it before the first real action: init with every ask as its own item, in order, covering investigation through verification. A follow-up that adds to the request: append its asks and any steps you discover; init is for a new, unrelated request and refuses while items are open. An item is named by its outcome in 3-8 words and keeps that exact wording; it is how you refer to it — lost the wording: view, never guess. Keep it current while you work, not at the end: the moment an item is finished and its result is read, mark it done with your next call — never batch completions. The runtime keeps exactly one item in progress; done moves it to the next. Send todo beside your next real tool call; when no real call is due, call it alone rather than skip the update. Waiting on the user, an agent or a shell: block it with a reason; unblock when it can move; done only after reading the result.',
23
+ inputSchema: {
24
+ type: 'object',
25
+ properties: {
26
+ op: { type: 'string', enum: TODO_OPS },
27
+ items: { ...itemList, description: 'init (one default phase) / append: item wordings.' },
28
+ phases: {
29
+ type: 'array',
30
+ minItems: 1,
31
+ items: {
32
+ type: 'object',
33
+ properties: { name: { type: 'string' }, items: itemList },
34
+ required: ['name', 'items'],
35
+ additionalProperties: false,
36
+ },
37
+ description: 'init: named phases instead of items.',
38
+ },
39
+ item: { type: 'string', description: 'start/done/drop/block/unblock/rm: exact item wording.' },
40
+ phase: { type: 'string', description: 'append: target phase (default last; new name adds one).' },
41
+ note: { type: 'string', description: 'done: optional one-line evidence.' },
42
+ reason: { type: 'string', description: 'block: what it waits on.' },
43
+ },
44
+ required: ['op'],
45
+ additionalProperties: false,
46
+ },
47
+ });
@@ -0,0 +1,155 @@
1
+ // Settings-gated tool availability for a live session. A session records the
2
+ // gates it was built with in `disallowedTools`; when a gate moves, a
3
+ // conversation is never re-prefixed: an opened tool joins the late deferred
4
+ // catalog (deferredLateToolCatalog — never the boot catalog, whose bytes a
5
+ // native request keeps) and a closed one joins the enforced deny set. The next
6
+ // prompt's deferred_tools_delta names both, and the prompt is folded at the
7
+ // next cache-cold point (promptFoldPending).
8
+ import { clean } from './session-text.mjs';
9
+ import { FEATURE_GATED_TOOL_NAMES, SETTING_GATED_TOOL_NAMES, featureDisallowedToolsFor } from './builtin-features.mjs';
10
+ import { mergePendingDeferredToolDelta } from './deferred-tool-delta.mjs';
11
+ import { sessionAllowlistExcludes } from './deferred-tool-availability.mjs';
12
+ import { isAgentOwner } from '../agent-owner.mjs';
13
+ import { agentMcpToolPermission, connectorPolicyAgentOf, projectMcpToolDisabled } from '../mcp/agent-connectors.mjs';
14
+ import { reactionDisabled } from '../session/manager/session-tool-surface.mjs';
15
+ import { browserBridgeAvailableSync } from '../../../browser-bridge/client.mjs';
16
+ import { computerBridgeAvailableSync } from '../../../computer-bridge/client.mjs';
17
+ import { terminalBridgeAvailableSync } from '../../../terminal-bridge/client.mjs';
18
+
19
+ const GATED = new Set(FEATURE_GATED_TOOL_NAMES);
20
+ const SETTING_GATED = new Set(SETTING_GATED_TOOL_NAMES);
21
+ // web_fetch keeps its gate under the transports it is routed to (pre-dispatch-deny.mjs).
22
+ const FETCH_TRANSPORTS = new Set(['local_fetch', 'image_fetch']);
23
+
24
+ // MCP scope → the live gate list of the session runtime serving it.
25
+ const liveGateSources = new Map();
26
+
27
+ /** A session runtime's live gate list (its in-memory settings) for model
28
+ * calls in its MCP scope. Returns the unregister function. */
29
+ export function registerLiveFeatureGates(scopeId, featureDisallowedTools) {
30
+ const key = scopeId ?? null;
31
+ liveGateSources.set(key, featureDisallowedTools);
32
+ return () => {
33
+ if (liveGateSources.get(key) === featureDisallowedTools) liveGateSources.delete(key);
34
+ };
35
+ }
36
+
37
+ /**
38
+ * The setting that turns off `name` right now, or null. A session's deny set
39
+ * takes moved gates at its next turn start; this covers a turn already
40
+ * running when a setting changed.
41
+ */
42
+ export function settingDisabledTool(name, scopeId) {
43
+ const source = liveGateSources.get(scopeId ?? null);
44
+ return typeof source === 'function' ? settingDisabledIn(name, source()) : null;
45
+ }
46
+
47
+ /** The setting of the live gate list `denied` that turns off `name`, or null. */
48
+ export function settingDisabledIn(name, denied) {
49
+ const gated = FETCH_TRANSPORTS.has(name) ? 'web_fetch' : name;
50
+ return SETTING_GATED.has(gated) && (denied || []).includes(gated) ? gated : null;
51
+ }
52
+
53
+ /** The feature gates as they stand: `config` plus live desktop-bridge presence. */
54
+ export function liveFeatureDisallowedTools(config, { toolProfile } = {}) {
55
+ return featureDisallowedToolsFor(config, {
56
+ browserAvailable: browserBridgeAvailableSync(),
57
+ computerAvailable: computerBridgeAvailableSync(),
58
+ terminalAvailable: terminalBridgeAvailableSync(),
59
+ toolProfile,
60
+ });
61
+ }
62
+
63
+ function knownTools(session) {
64
+ const known = new Map();
65
+ for (const key of ['tools', 'deferredToolCatalog', 'deferredLateToolCatalog']) {
66
+ for (const tool of Array.isArray(session?.[key]) ? session[key] : []) {
67
+ const name = clean(tool?.name);
68
+ if (name && !known.has(name)) known.set(name, tool);
69
+ }
70
+ }
71
+ return known;
72
+ }
73
+
74
+ /**
75
+ * Bring `session`'s settings-gated tools to `featureDenied` (the live gate
76
+ * list) without touching its request prefix. `definitionsFor(names)` supplies
77
+ * definitions for opened tools the session never held. Returns
78
+ * `{ added, removed }` when a gate moved, else null.
79
+ */
80
+ export function stageToolAvailability(session, featureDenied, definitionsFor = () => []) {
81
+ if (!session || !Array.isArray(session.tools)) return null;
82
+ const live = new Set((featureDenied || []).map(String).filter((name) => GATED.has(name)));
83
+ session.featureDeniedTools = [...live].sort();
84
+ const disallowed = (session.disallowedTools || []).map(String);
85
+ const denied = new Set(disallowed);
86
+ // Denials that are not settings: the caller's, and react outside a bot chat.
87
+ const fixed = new Set((session.callerDisallowedTools || []).map(String));
88
+ if (reactionDisabled(session, isAgentOwner(session))) fixed.add('react');
89
+ const closed = [...live].filter((name) => !denied.has(name));
90
+ const opened = disallowed.filter((name) => GATED.has(name) && !live.has(name) && !fixed.has(name));
91
+ if (!closed.length && !opened.length) return null;
92
+ const known = knownTools(session);
93
+ const missing = opened.filter((name) => !known.has(name));
94
+ const fresh = missing.length
95
+ ? (definitionsFor(missing) || []).filter((tool) => missing.includes(clean(tool?.name)))
96
+ : [];
97
+ for (const tool of fresh) {
98
+ if (!known.has(clean(tool.name))) known.set(clean(tool.name), tool);
99
+ }
100
+ if (fresh.length) {
101
+ session.deferredLateToolCatalog = [...(session.deferredLateToolCatalog || []), ...fresh];
102
+ }
103
+ const openedSet = new Set(opened);
104
+ session.disallowedTools = [...disallowed.filter((name) => !openedSet.has(name)), ...closed];
105
+ const visible = (name) => known.has(name) && !sessionAllowlistExcludes(session, name);
106
+ const added = opened.filter(visible);
107
+ const removed = closed.filter(visible);
108
+ mergePendingDeferredToolDelta(session, {
109
+ added: added.map((name) => ({ name, description: known.get(name)?.description || '' })),
110
+ removed,
111
+ });
112
+ // A delegated worker is never folded (agent-profile-fold.mjs): its opened
113
+ // tools are re-announced after a compaction instead (rearmLateDeferredTools).
114
+ if (!isAgentOwner(session)) session.promptFoldPending = true;
115
+ session.updatedAt = Date.now();
116
+ return { added, removed };
117
+ }
118
+
119
+ // The connector tools among the session's known tools that its agent's
120
+ // connector policy and its project's connector switches let it run now.
121
+ function permittedConnectorTools(session, known) {
122
+ const agent = connectorPolicyAgentOf(session);
123
+ return [...known.keys()]
124
+ .filter(
125
+ (name) =>
126
+ name.startsWith('mcp__') &&
127
+ agentMcpToolPermission(agent, name) !== 'disabled' &&
128
+ !projectMcpToolDisabled(session, name)
129
+ )
130
+ .sort();
131
+ }
132
+
133
+ /**
134
+ * Connector switches (an agent's policy, a project's connector off/on) gate
135
+ * MCP tools at call time (pre-dispatch-deny.mjs); this tells the model. The
136
+ * first call records the baseline; later moves join the deferred_tools_delta.
137
+ * Returns `{ added, removed }` when the permitted set moved, else null.
138
+ */
139
+ export function stageConnectorAvailability(session) {
140
+ if (!session || !Array.isArray(session.tools)) return null;
141
+ const known = knownTools(session);
142
+ const permitted = permittedConnectorTools(session, known);
143
+ const previous = session.agentConnectorTools;
144
+ session.agentConnectorTools = permitted;
145
+ if (!Array.isArray(previous)) return null;
146
+ const added = permitted.filter((name) => !previous.includes(name));
147
+ const removed = previous.filter((name) => !permitted.includes(name));
148
+ if (!added.length && !removed.length) return null;
149
+ mergePendingDeferredToolDelta(session, {
150
+ added: added.map((name) => ({ name, description: known.get(name)?.description || '' })),
151
+ removed,
152
+ });
153
+ session.updatedAt = Date.now();
154
+ return { added, removed };
155
+ }
@@ -1,6 +1,7 @@
1
1
  // Canonical route order — the single surface order wherever tools serialize:
2
2
  // locator → path → content → symbol → read → edit → execute.
3
3
  export const ROUTE_TOOL_ORDER = Object.freeze([
4
+ 'explore',
4
5
  'find',
5
6
  'glob',
6
7
  'list',
@@ -44,6 +45,11 @@ export const DEFERRED_DEFAULT_FULL_TOOLS = Object.freeze([
44
45
  'read',
45
46
  'edit',
46
47
  'apply_patch',
48
+ // Loaded up front so looking something up never costs a load_tool hop;
49
+ // web_fetch stays deferred (it usually follows a search).
50
+ 'web_search',
51
+ // Every session's own step list: always loaded, never a load_tool hop.
52
+ 'todo',
47
53
  'Skill',
48
54
  'load_tool',
49
55
  ]);
@@ -54,10 +60,14 @@ export const DEFERRED_DEFAULT_READONLY_TOOLS = Object.freeze([
54
60
  'grep',
55
61
  'code_graph',
56
62
  'read',
63
+ 'web_search',
64
+ 'todo',
57
65
  'Skill',
58
66
  'load_tool',
59
67
  ]);
60
68
  export const DEFERRED_DEFAULT_LEAD_TOOLS = Object.freeze([
69
+ // Present only once Explore has a model (builtin-features.mjs).
70
+ 'explore',
61
71
  'find',
62
72
  'glob',
63
73
  'list',
@@ -80,6 +90,8 @@ export const DEFERRED_DEFAULT_LEAD_TOOLS = Object.freeze([
80
90
  // A bot's reaction, likewise: only a bot's chat with the user has it at all
81
91
  // (session-tool-surface.mjs reactionDisabled).
82
92
  'react',
93
+ 'web_search',
94
+ 'todo',
83
95
  'Skill',
84
96
  'load_tool',
85
97
  ]);