mixdog 1.4.1 → 1.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (630) hide show
  1. package/package.json +4 -3
  2. package/scripts/build-shipped-history.mjs +125 -33
  3. package/scripts/gate-local.mjs +220 -63
  4. package/scripts/graph-parity.mjs +8 -3
  5. package/scripts/lib/gate-scheduler.mjs +139 -32
  6. package/scripts/lib/gate-timing-reporter.mjs +16 -0
  7. package/scripts/lib/run-node-tests.mjs +71 -34
  8. package/scripts/lib/scoped-temp.mjs +1 -0
  9. package/scripts/lib/test-failure-records.mjs +14 -1
  10. package/scripts/lib/test-failure-summary.mjs +9 -4
  11. package/scripts/lib/test-spawn-ledger.mjs +43 -3
  12. package/scripts/post-release-check.mjs +26 -16
  13. package/scripts/pptx-kit-index.mjs +5 -6
  14. package/scripts/provider-pingpong-live.mjs +1 -1
  15. package/scripts/prune-embedding-runtime.mjs +3 -1
  16. package/scripts/release-paths.mjs +7 -1
  17. package/scripts/suite-health.mjs +110 -28
  18. package/scripts/test.mjs +9 -14
  19. package/src/agents/advisor/AGENT.md +4 -4
  20. package/src/agents/advisor/agent.json +1 -1
  21. package/src/agents/explore/AGENT.md +22 -0
  22. package/src/agents/explore/agent.json +6 -0
  23. package/src/cli.mjs +7 -0
  24. package/src/defaults/agents.json +7 -0
  25. package/src/defaults/shipped-history.json +38 -2
  26. package/src/defaults/skills/browser-use/SKILL.md +4 -1
  27. package/src/defaults/skills/code-tidy/SKILL.md +71 -102
  28. package/src/defaults/skills/code-tidy/references/agent-cleanup.md +66 -114
  29. package/src/defaults/skills/code-tidy/references/cleanup-report.md +19 -35
  30. package/src/defaults/skills/code-tidy/references/dead-code.md +3 -9
  31. package/src/defaults/skills/code-tidy/references/test-suite-slop.md +16 -27
  32. package/src/defaults/skills/computer-use/SKILL.md +12 -2
  33. package/src/defaults/skills/setup/SKILL.md +2 -2
  34. package/src/defaults/skills/setup/references/actions.md +28 -9
  35. package/src/defaults/skills/setup/references/surfaces.md +5 -2
  36. package/src/defaults/skills/setup-guide/SKILL.md +11 -3
  37. package/src/defaults/skills/setup-guide/model-recommendations.json +13 -0
  38. package/src/defaults/skills/skill-creator/SKILL.md +85 -190
  39. package/src/defaults/skills/skill-creator/references/design.md +70 -162
  40. package/src/defaults/skills/skill-creator/references/evaluation.md +33 -92
  41. package/src/defaults/skills/test-suite/SKILL.md +194 -0
  42. package/src/defaults/skills/test-suite/references/case-management.md +51 -0
  43. package/src/defaults/skills/test-suite/references/flaky-policy.md +39 -0
  44. package/src/defaults/skills/test-suite/references/reliability.md +49 -0
  45. package/src/defaults/skills/test-suite/references/suite-design.md +78 -0
  46. package/src/defaults/skills/test-suite/scripts/inventory.mjs +335 -0
  47. package/src/defaults/skills/visualize/SKILL.md +6 -2
  48. package/src/lib/instruction-text.cjs +36 -0
  49. package/src/lib/rules-builder.cjs +40 -50
  50. package/src/orchestration/balanced.md +23 -0
  51. package/src/orchestration/focused.md +22 -0
  52. package/src/orchestration/none.md +5 -0
  53. package/src/orchestration/swarm.md +24 -0
  54. package/src/rules/agent-mode/AGENT_MODE.md +3 -1
  55. package/src/rules/agent-mode/MIXY.md +2 -2
  56. package/src/rules/lead/LEAD.md +3 -3
  57. package/src/rules/shared/20-research.md +3 -6
  58. package/src/rules/shared/40-editing.md +1 -0
  59. package/src/rules/shared/60-verification.md +10 -9
  60. package/src/rules/shared/70-delivery.md +4 -3
  61. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/abort-link.mjs +5 -1
  62. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +3 -3
  63. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +10 -2
  64. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +132 -21
  65. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +13 -9
  66. package/src/runtime/agent/orchestrator/agent-runtime/heartbeat-completion.mjs +2 -2
  67. package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +4 -1
  68. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +67 -0
  69. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  70. package/src/runtime/agent/orchestrator/config.mjs +12 -7
  71. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +7 -7
  72. package/src/runtime/agent/orchestrator/context/role-instructions.mjs +9 -30
  73. package/src/runtime/agent/orchestrator/internal-agents.mjs +3 -14
  74. package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +124 -12
  75. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +204 -49
  76. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +16 -7
  77. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +157 -57
  78. package/src/runtime/agent/orchestrator/mcp/client.mjs +54 -23
  79. package/src/runtime/agent/orchestrator/mcp/oauth-client.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +8 -2
  81. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +83 -52
  82. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +1 -1
  83. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +14 -0
  84. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +43 -27
  85. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +43 -8
  86. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +30 -28
  87. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +31 -21
  89. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-stop.mjs +3 -3
  90. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-login.mjs +3 -1
  91. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-tokens.mjs +2 -2
  92. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  93. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +40 -0
  95. package/src/runtime/agent/orchestrator/providers/custom-provider-keys.mjs +34 -0
  96. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +3 -0
  97. package/src/runtime/agent/orchestrator/providers/devin-auth.mjs +14 -7
  98. package/src/runtime/agent/orchestrator/providers/devin-wire-transport.mjs +3 -2
  99. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +2 -2
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +48 -31
  103. package/src/runtime/agent/orchestrator/providers/lib/oauth-page.mjs +0 -18
  104. package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +138 -6
  105. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +1 -1
  106. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +100 -33
  107. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/oauth-secret-fields.fixtures.mjs +45 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +4 -6
  110. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2784 -2872
  111. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +5 -8
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +26 -28
  113. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +288 -300
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +3 -1
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-watchdogs.mjs +1 -0
  116. package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +3 -1
  118. package/src/runtime/agent/orchestrator/providers/registry.mjs +33 -2
  119. package/src/runtime/agent/orchestrator/providers/vertex-ai-auth.mjs +622 -0
  120. package/src/runtime/agent/orchestrator/providers/vertex-ai-maas.mjs +185 -0
  121. package/src/runtime/agent/orchestrator/providers/vertex-ai-models.mjs +445 -0
  122. package/src/runtime/agent/orchestrator/providers/vertex-ai.mjs +576 -0
  123. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +10 -30
  124. package/src/runtime/agent/orchestrator/runtime-core/builtin-features.mjs +32 -0
  125. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +0 -11
  126. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +8 -0
  127. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +17 -3
  128. package/src/runtime/agent/orchestrator/runtime-core/goal-control.mjs +47 -27
  129. package/src/runtime/agent/orchestrator/runtime-core/goal-deadlines.mjs +141 -10
  130. package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +26 -63
  131. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +28 -3
  132. package/src/runtime/agent/orchestrator/runtime-core/goal-runtime.mjs +36 -11
  133. package/src/runtime/agent/orchestrator/runtime-core/goal-state.mjs +88 -56
  134. package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +4 -1
  135. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +51 -32
  136. package/src/runtime/agent/orchestrator/runtime-core/goal-text.mjs +45 -145
  137. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-defs.mjs +15 -98
  138. package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +32 -99
  139. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +23 -78
  140. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +69 -47
  141. package/src/runtime/agent/orchestrator/runtime-core/todo-list.mjs +367 -0
  142. package/src/runtime/agent/orchestrator/runtime-core/todo-tool-defs.mjs +47 -0
  143. package/src/runtime/agent/orchestrator/runtime-core/tool-availability.mjs +155 -0
  144. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +12 -0
  145. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +119 -35
  146. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +4 -1
  147. package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +15 -6
  148. package/src/runtime/agent/orchestrator/runtime-core/workflow-ids.mjs +1 -0
  149. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +28 -22
  150. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +30 -0
  151. package/src/runtime/agent/orchestrator/session/agent-room.d.mts +30 -5
  152. package/src/runtime/agent/orchestrator/session/agent-room.mjs +171 -37
  153. package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/cache-warm.mjs +94 -10
  155. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -2
  156. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +1 -1
  157. package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +1 -1
  158. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +3 -0
  159. package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +1 -1
  160. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -12
  161. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +4 -4
  162. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +11 -6
  163. package/src/runtime/agent/orchestrator/session/conversation-import/convert.mjs +6 -6
  164. package/src/runtime/agent/orchestrator/session/conversation-import/imported-session.mjs +7 -3
  165. package/src/runtime/agent/orchestrator/session/conversation-import/turns.mjs +11 -1
  166. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -3
  167. package/src/runtime/agent/orchestrator/session/human-gate/held-message.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +37 -8
  169. package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +1 -1
  170. package/src/runtime/agent/orchestrator/session/image-strip-recovery.mjs +1 -1
  171. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +11 -1
  172. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +5 -3
  174. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +8 -1
  175. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/todo-check.mjs +196 -0
  176. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +116 -50
  177. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +8 -1
  178. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +1 -1
  179. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +1 -1
  180. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -1
  181. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +5 -6
  182. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +27 -3
  183. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +18 -2
  184. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +23 -1
  185. package/src/runtime/agent/orchestrator/session/loop/turn-limits.mjs +13 -8
  186. package/src/runtime/agent/orchestrator/session/loop/turn-report.mjs +35 -0
  187. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +1 -1
  188. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +103 -50
  189. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +9 -7
  190. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +21 -3
  191. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +27 -11
  192. package/src/runtime/agent/orchestrator/session/manager/ask-turn-open.mjs +37 -34
  193. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +15 -0
  194. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +25 -15
  195. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +79 -24
  196. package/src/runtime/agent/orchestrator/session/manager/ask-turn-steering-drain.mjs +3 -0
  197. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +12 -1
  198. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  199. package/src/runtime/agent/orchestrator/session/manager/idle-cleanup.mjs +6 -1
  200. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +9 -1
  201. package/src/runtime/agent/orchestrator/session/manager/pending-spool-path.mjs +2 -2
  202. package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +1 -1
  203. package/src/runtime/agent/orchestrator/session/manager/prompt-settings.mjs +598 -0
  204. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +20 -0
  205. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +22 -14
  206. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +2 -0
  207. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +12 -0
  208. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +1 -1
  210. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +56 -14
  211. package/src/runtime/agent/orchestrator/session/manager/session-lock.mjs +31 -0
  212. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +59 -20
  213. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +2 -0
  214. package/src/runtime/agent/orchestrator/session/manager/session-scratch-environment.mjs +70 -0
  215. package/src/runtime/agent/orchestrator/session/manager/session-tool-surface.mjs +0 -3
  216. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +18 -4
  217. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-context.mjs +8 -9
  218. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +339 -88
  219. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +135 -11
  220. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +377 -104
  221. package/src/runtime/agent/orchestrator/session/manager/turn-durability.mjs +144 -0
  222. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +48 -30
  223. package/src/runtime/agent/orchestrator/session/manager/turn-reap.mjs +125 -0
  224. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +4 -0
  225. package/src/runtime/agent/orchestrator/session/manager.mjs +6 -0
  226. package/src/runtime/agent/orchestrator/session/mixy-name.mjs +12 -6
  227. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +8 -1
  228. package/src/runtime/agent/orchestrator/session/restart-prefix-parity.fixture.mjs +1 -1
  229. package/src/runtime/agent/orchestrator/session/save-session-worker.mjs +5 -1
  230. package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +1 -1
  231. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +2 -2
  232. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +23 -2
  233. package/src/runtime/agent/orchestrator/session/store/sweep/sub-agent-retention.mjs +3 -3
  234. package/src/runtime/agent/orchestrator/session/store/transcript-durability.mjs +88 -0
  235. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +5 -0
  236. package/src/runtime/agent/orchestrator/session/store-summary-log.mjs +1 -1
  237. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +243 -38
  238. package/src/runtime/agent/orchestrator/session/store-transcript-cache.mjs +163 -64
  239. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +177 -8
  240. package/src/runtime/agent/orchestrator/session/store-transcript-worker.mjs +142 -18
  241. package/src/runtime/agent/orchestrator/session/store.mjs +5 -0
  242. package/src/runtime/agent/orchestrator/session/synthetic-user-envelope.mjs +7 -1
  243. package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +9 -1
  244. package/src/runtime/agent/orchestrator/session/transcript-restore/agent-envelope.mjs +1 -1
  245. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +3 -1
  246. package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +2 -2
  247. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -5
  248. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -1
  249. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +6 -2
  250. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +21 -3
  251. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
  252. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/worktree-add-guard.mjs +77 -0
  253. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -1
  254. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +42 -28
  255. package/src/runtime/agent/orchestrator/tools/builtin/git-worktree-tool.mjs +30 -14
  256. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +2 -2
  257. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +58 -20
  258. package/src/runtime/agent/orchestrator/tools/builtin/read-range-index.mjs +1 -1
  259. package/src/runtime/agent/orchestrator/tools/builtin/read-single-fast-paths.mjs +0 -1
  260. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +20 -15
  261. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +0 -10
  262. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +95 -20
  263. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +59 -10
  264. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -24
  265. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary/child-kill.mjs +4 -3
  266. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +1 -2
  267. package/src/runtime/agent/orchestrator/tools/code-graph/modes/calls.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/tools/code-graph/modes/symbols.mjs +2 -2
  269. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +4 -5
  270. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +3 -4
  271. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4 -22
  272. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
  273. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.mjs +99 -2
  274. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +2 -0
  275. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +105 -15
  276. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +3 -1
  277. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +49 -15
  278. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +45 -27
  279. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +35 -11
  280. package/src/runtime/agent/orchestrator/tools/lib/shell-warm-standby.mjs +2 -0
  281. package/src/runtime/agent/orchestrator/tools/lib/wait-until-fixture.mjs +26 -0
  282. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -6
  283. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +0 -1
  284. package/src/runtime/agent/orchestrator/tools/spawn-manifest.json +13 -13
  285. package/src/runtime/attachments/attachment-reference.mjs +1 -1
  286. package/src/runtime/attachments/pdf-extract.mjs +1 -1
  287. package/src/runtime/attachments/store.d.mts +1 -0
  288. package/src/runtime/attachments/store.mjs +2 -2
  289. package/src/runtime/channels/lib/config-reload-watch.mjs +42 -0
  290. package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +29 -9
  291. package/src/runtime/channels/lib/scheduler.mjs +33 -0
  292. package/src/runtime/channels/lib/schedules-db.mjs +11 -4
  293. package/src/runtime/channels/lib/webhook/session-dispatch.mjs +4 -1
  294. package/src/runtime/channels/lib/webhooks-db.mjs +9 -3
  295. package/src/runtime/channels/lib/whisper-port.mjs +19 -10
  296. package/src/runtime/channels/lib/whisper-server.mjs +22 -13
  297. package/src/runtime/channels/lib/worker-main.mjs +9 -31
  298. package/src/runtime/computer-bridge/linux-readiness.mjs +10 -14
  299. package/src/runtime/connectors/connector-accounts-mcp.mjs +372 -103
  300. package/src/runtime/connectors/gmail-app-password.mjs +4 -4
  301. package/src/runtime/connectors/google-mcp.mjs +1 -1
  302. package/src/runtime/effort-judge/judge-client.mjs +2 -2
  303. package/src/runtime/effort-judge/judge-input.mjs +4 -4
  304. package/src/runtime/explore/explorer.mjs +88 -0
  305. package/src/runtime/explore/tool-defs.mjs +35 -0
  306. package/src/runtime/explore/tool.mjs +123 -0
  307. package/src/runtime/local-provider/hardware.mjs +1 -1
  308. package/src/runtime/media/adapters/codex-image.mjs +3 -3
  309. package/src/runtime/media/adapters/gemini-video.mjs +1 -1
  310. package/src/runtime/media/media-usage.mjs +1 -1
  311. package/src/runtime/media/store.mjs +1 -1
  312. package/src/runtime/memory/index.mjs +15 -1
  313. package/src/runtime/memory/lib/embedding-provider.mjs +4 -1
  314. package/src/runtime/memory/lib/embedding-reindex.mjs +27 -0
  315. package/src/runtime/memory/lib/embedding-worker.mjs +4 -0
  316. package/src/runtime/memory/lib/memory-embed.mjs +83 -14
  317. package/src/runtime/memory/lib/memory-process-lock.mjs +159 -36
  318. package/src/runtime/memory/lib/memory-text-utils.mjs +6 -1
  319. package/src/runtime/memory/lib/memory.mjs +17 -0
  320. package/src/runtime/memory/lib/pg/process.mjs +1 -1
  321. package/src/runtime/memory/lib/pg/supervisor.mjs +16 -96
  322. package/src/runtime/memory/lib/recall-hybrid/hybrid-sql.mjs +12 -3
  323. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  324. package/src/runtime/office/authoring/pptx-author-action.mjs +1 -1
  325. package/src/runtime/office/authoring/xlsx-html-build.mjs +1 -1
  326. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  327. package/src/runtime/office/capabilities.mjs +1 -1
  328. package/src/runtime/office/core/office-core.mjs +1 -1
  329. package/src/runtime/office/design/content-model.mjs +3 -3
  330. package/src/runtime/office/design/docx/design-docx/section.mjs +6 -6
  331. package/src/runtime/office/design/xlsx/design-xlsx-components.mjs +1 -1
  332. package/src/runtime/office/design/xlsx/design-xlsx.mjs +1 -1
  333. package/src/runtime/office/pdf/ocr-engine.mjs +1 -1
  334. package/src/runtime/office/pdf/pdf-writer.mjs +4 -4
  335. package/src/runtime/office/portable/portable-docx-operations.mjs +2 -2
  336. package/src/runtime/office/portable/portable-soffice.mjs +8 -6
  337. package/src/runtime/office/portable/xlsx-contract.mjs +1 -1
  338. package/src/runtime/office/quality/assurance-structure-docx.mjs +1 -1
  339. package/src/runtime/shared/agent-route-config.mjs +17 -2
  340. package/src/runtime/shared/atomic-file.d.mts +8 -0
  341. package/src/runtime/shared/atomic-file.mjs +103 -2
  342. package/src/runtime/shared/background-tasks.mjs +37 -10
  343. package/src/runtime/shared/background-wait.mjs +66 -0
  344. package/src/runtime/shared/child-guardian.mjs +17 -7
  345. package/src/runtime/shared/config.mjs +313 -16
  346. package/src/runtime/shared/connector-accounts.mjs +5 -5
  347. package/src/runtime/shared/connector-catalog.d.mts +14 -8
  348. package/src/runtime/shared/connector-catalog.mjs +70 -52
  349. package/src/runtime/shared/custom-provider-keys.mjs +20 -0
  350. package/src/runtime/shared/file-has-data.mjs +26 -2
  351. package/src/runtime/shared/file-lock.mjs +21 -18
  352. package/src/runtime/shared/git-launch.d.mts +9 -0
  353. package/src/runtime/shared/git-launch.mjs +213 -0
  354. package/src/runtime/shared/git-runner-worker.mjs +2 -1
  355. package/src/runtime/shared/git-runner.mjs +7 -2
  356. package/src/runtime/shared/idle-gc.mjs +30 -7
  357. package/src/runtime/shared/llm/cost.mjs +6 -1
  358. package/src/runtime/shared/llm/http-agent.mjs +316 -29
  359. package/src/runtime/shared/llm/model-catalog-projection.mjs +3 -2
  360. package/src/runtime/shared/llm/model-catalog.mjs +46 -6
  361. package/src/runtime/shared/llm/provider-catalog-registry.mjs +3 -0
  362. package/src/runtime/shared/llm/system-proxy.mjs +453 -0
  363. package/src/runtime/shared/llm/usage-ledger-quota.mjs +31 -12
  364. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +84 -8
  365. package/src/runtime/shared/llm/usage-ledger.mjs +3 -0
  366. package/src/runtime/shared/llm/usage-rollup.mjs +48 -0
  367. package/src/runtime/shared/maintenance-schedule.mjs +109 -0
  368. package/src/runtime/shared/process-runner.mjs +8 -4
  369. package/src/runtime/shared/provider-accounts.mjs +52 -2
  370. package/src/runtime/shared/routine-trigger.d.mts +13 -0
  371. package/src/runtime/shared/routine-trigger.mjs +34 -0
  372. package/src/runtime/shared/run-child.d.mts +2 -1
  373. package/src/runtime/shared/run-child.mjs +70 -18
  374. package/src/runtime/shared/session-scratch.mjs +14 -2
  375. package/src/runtime/shared/shipped-definitions.mjs +7 -1
  376. package/src/runtime/shared/staged-install-worker.mjs +5 -0
  377. package/src/runtime/shared/staged-update.mjs +47 -2
  378. package/src/runtime/shared/tool-card-model.golden.json +3 -12
  379. package/src/runtime/shared/tool-execution-contract.mjs +2 -0
  380. package/src/runtime/shared/tool-surface.mjs +110 -36
  381. package/src/runtime/shared/tool-work-units.mjs +35 -6
  382. package/src/runtime/shared/turn-snapshot.mjs +26 -4
  383. package/src/runtime/shared/turn-worktree-snapshot.mjs +409 -54
  384. package/src/runtime/shared/worker-requests.mjs +17 -3
  385. package/src/runtime/shared/worktrees/activity-gate.mjs +215 -318
  386. package/src/runtime/shared/worktrees/activity-ledger-worker.mjs +56 -0
  387. package/src/runtime/shared/worktrees/activity-ledger.mjs +391 -0
  388. package/src/runtime/shared/worktrees/branch-management.mjs +5 -3
  389. package/src/runtime/shared/worktrees/contract.mjs +16 -6
  390. package/src/runtime/shared/worktrees/dependencies.mjs +127 -89
  391. package/src/runtime/shared/worktrees/disk.mjs +79 -2
  392. package/src/runtime/shared/worktrees/git.mjs +97 -7
  393. package/src/runtime/shared/worktrees/include.mjs +6 -4
  394. package/src/runtime/shared/worktrees/maintenance.mjs +422 -30
  395. package/src/runtime/shared/worktrees/manager.mjs +962 -197
  396. package/src/runtime/shared/worktrees/settings.mjs +33 -7
  397. package/src/runtime/shared/worktrees/test-support.mjs +5 -1
  398. package/src/runtime/shared/worktrees/worker-snapshots.mjs +82 -0
  399. package/src/runtime/tidy/install.mjs +95 -15
  400. package/src/runtime/tidy/languages.mjs +17 -15
  401. package/src/runtime/tidy/process.mjs +9 -5
  402. package/src/runtime/tidy/resolve.mjs +19 -16
  403. package/src/runtime/tidy/runners/biome.mjs +3 -3
  404. package/src/runtime/tidy/tool.mjs +1 -1
  405. package/src/runtime/tidy/worktree.mjs +10 -6
  406. package/src/runtime/visualize-bridge/client.mjs +4 -1
  407. package/src/runtime/visualize-bridge/tool-defs.mjs +7 -2
  408. package/src/runtime/web-search/index.mjs +4 -23
  409. package/src/runtime/web-search/lib/web-tools.mjs +2 -2
  410. package/src/runtime/web-search/tool-defs.mjs +17 -26
  411. package/src/session-runtime/agent-profile-changes.mjs +55 -4
  412. package/src/session-runtime/agent-task-sessions.mjs +410 -353
  413. package/src/session-runtime/boot/apis.mjs +27 -4
  414. package/src/session-runtime/boot/begin.mjs +2 -0
  415. package/src/session-runtime/boot/config.mjs +10 -1
  416. package/src/session-runtime/boot/facade.mjs +1 -0
  417. package/src/session-runtime/boot/providers.mjs +70 -3
  418. package/src/session-runtime/boot/session.mjs +2 -0
  419. package/src/session-runtime/boot/tools.mjs +71 -25
  420. package/src/session-runtime/bot-status.mjs +103 -103
  421. package/src/session-runtime/channel-config-api.mjs +1 -0
  422. package/src/session-runtime/config-change-effects.mjs +179 -0
  423. package/src/session-runtime/config-lifecycle/config-writers.mjs +1 -0
  424. package/src/session-runtime/config-lifecycle.mjs +160 -24
  425. package/src/session-runtime/connector-merge-migration.mjs +18 -15
  426. package/src/session-runtime/conversation-import/discovery.mjs +245 -47
  427. package/src/session-runtime/conversation-import/service.mjs +12 -5
  428. package/src/session-runtime/goal-facade-api.mjs +49 -3
  429. package/src/session-runtime/handoff-attachments.mjs +1 -1
  430. package/src/session-runtime/held-requests.mjs +3 -1
  431. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +3 -0
  432. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -2
  433. package/src/session-runtime/internal-tool-executor/feature-tools.mjs +5 -11
  434. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +8 -0
  435. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +161 -120
  436. package/src/session-runtime/internal-tool-executor.mjs +12 -19
  437. package/src/session-runtime/lifecycle/cold-heir.mjs +7 -0
  438. package/src/session-runtime/lifecycle/memory-ingest.mjs +3 -3
  439. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +53 -5
  440. package/src/session-runtime/lifecycle/session-switch.mjs +13 -2
  441. package/src/session-runtime/lifecycle/teardown/session-close.mjs +10 -5
  442. package/src/session-runtime/lifecycle/teardown.mjs +1 -1
  443. package/src/session-runtime/lifecycle-api.mjs +1 -0
  444. package/src/session-runtime/mcp-glue/server-catalog.mjs +27 -10
  445. package/src/session-runtime/mcp-glue/server-connection.mjs +34 -8
  446. package/src/session-runtime/mcp-glue/server-input.mjs +4 -1
  447. package/src/session-runtime/mixy-heartbeat.mjs +1 -1
  448. package/src/session-runtime/model-route/set-route.mjs +40 -7
  449. package/src/session-runtime/native-web-search/routes.mjs +3 -3
  450. package/src/session-runtime/provider-auth/login.mjs +2 -2
  451. package/src/session-runtime/provider-auth/refresh.mjs +6 -3
  452. package/src/session-runtime/provider-auth/setup.mjs +1 -1
  453. package/src/session-runtime/provider-readiness.mjs +53 -4
  454. package/src/session-runtime/resource-api.mjs +1 -1
  455. package/src/session-runtime/resource-extension-sync.mjs +4 -8
  456. package/src/session-runtime/resource-mcp-api.mjs +98 -35
  457. package/src/session-runtime/resource-mcp-connector-accounts.mjs +49 -32
  458. package/src/session-runtime/resource-mcp-secrets.mjs +27 -10
  459. package/src/session-runtime/resource-mcp-servers.mjs +5 -4
  460. package/src/session-runtime/resource-plugins-api.mjs +4 -0
  461. package/src/session-runtime/routine-executor.mjs +152 -0
  462. package/src/session-runtime/routine-home-turn.mjs +46 -5
  463. package/src/session-runtime/runtime-facade.mjs +5 -0
  464. package/src/session-runtime/runtime-feature-gates.mjs +2 -11
  465. package/src/session-runtime/schedule-session-run.mjs +1 -0
  466. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +6 -1
  467. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +7 -0
  468. package/src/session-runtime/services/agent-tool/send-flow.mjs +120 -8
  469. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +12 -0
  470. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-plan.mjs +5 -0
  471. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +8 -3
  472. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +28 -7
  473. package/src/session-runtime/services/agent-tool.mjs +51 -1
  474. package/src/session-runtime/services/agent-watchdog-registry.mjs +32 -4
  475. package/src/session-runtime/services/channel-admin.mjs +18 -0
  476. package/src/session-runtime/services/channel-worker/daemon-spawn.mjs +2 -0
  477. package/src/session-runtime/services/daemon-candidate.mjs +4 -1
  478. package/src/session-runtime/services/hook-bus/command-handler.mjs +7 -11
  479. package/src/session-runtime/services/memory-runtime-proxy/daemon-spawn.mjs +4 -0
  480. package/src/session-runtime/services/plugin-admin.mjs +14 -6
  481. package/src/session-runtime/services/provider-admin.mjs +281 -10
  482. package/src/session-runtime/services/seeds.mjs +7 -0
  483. package/src/session-runtime/services/usage-stats-model.mjs +32 -11
  484. package/src/session-runtime/session-create/materialize.mjs +4 -2
  485. package/src/session-runtime/session-create/session-options.mjs +2 -0
  486. package/src/session-runtime/session-turn-api.mjs +2 -0
  487. package/src/session-runtime/settings-builtin-tools-api.mjs +5 -10
  488. package/src/session-runtime/settings-system-api.mjs +1 -1
  489. package/src/session-runtime/setup-tool/agent-settings-actions.mjs +13 -3
  490. package/src/session-runtime/setup-tool/connector-widen-approval.mjs +96 -0
  491. package/src/session-runtime/setup-tool/executor.mjs +14 -3
  492. package/src/session-runtime/setup-tool/extended-actions.mjs +2 -0
  493. package/src/session-runtime/setup-tool/settings-contract.mjs +28 -0
  494. package/src/session-runtime/setup-tool/tool-defs.mjs +28 -2
  495. package/src/session-runtime/tool-policy/agent-profile-fold.mjs +40 -43
  496. package/src/session-runtime/tool-policy/mode-switch.mjs +1 -1
  497. package/src/session-runtime/tool-policy/policy-stage.mjs +106 -8
  498. package/src/session-runtime/tool-policy/workflow-overlay.mjs +2 -1
  499. package/src/session-runtime/tool-policy-refresh.mjs +182 -5
  500. package/src/session-runtime/tool-surface.mjs +38 -1
  501. package/src/session-runtime/turn/agent-ops.mjs +33 -2
  502. package/src/session-runtime/turn/session-ops.mjs +2 -0
  503. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +5 -0
  504. package/src/session-runtime/turn/turn-run.mjs +1 -1
  505. package/src/session-runtime/webhook-session-run.mjs +2 -0
  506. package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +46 -11
  507. package/src/session-runtime/workflow-agents-api/agent-route.mjs +2 -0
  508. package/src/session-runtime/workflow-agents-api/instruction-files.mjs +165 -0
  509. package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +5 -4
  510. package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +2 -3
  511. package/src/session-runtime/workflow-agents-api.mjs +2 -0
  512. package/src/session-runtime/workspace/activity-guards.mjs +176 -0
  513. package/src/session-runtime/workspace/project-branches.mjs +1 -1
  514. package/src/session-runtime/workspace/session-view.mjs +149 -0
  515. package/src/session-runtime/workspace/side-checkouts.mjs +203 -0
  516. package/src/session-runtime/workspace/transition-runner.mjs +188 -0
  517. package/src/session-runtime/workspace/transitions.mjs +128 -1070
  518. package/src/session-runtime/workspace/workspace-merge.mjs +132 -0
  519. package/src/session-runtime/workspace/worktree-intents.mjs +242 -0
  520. package/src/session-runtime/workspace/worktree-maintenance.mjs +200 -0
  521. package/src/session-runtime/workspace/worktree-setup.mjs +97 -0
  522. package/src/session-runtime/workspace/worktree-tool.mjs +70 -54
  523. package/src/standalone/daemon-agent-control.mjs +25 -8
  524. package/src/standalone/daemon-desktop-runtime.mjs +8 -2
  525. package/src/standalone/daemon-lag-profiler.mjs +7 -7
  526. package/src/standalone/daemon-session-control.mjs +151 -136
  527. package/src/standalone/daemon.mjs +61 -2
  528. package/src/standalone/desktop-service-registry.mjs +9 -0
  529. package/src/standalone/local-session-runtime.mjs +21 -1
  530. package/src/standalone/session-client/daemon-unavailable.mjs +4 -1
  531. package/src/standalone/session-client.mjs +5 -1
  532. package/src/standalone/session-frame-stream.mjs +83 -11
  533. package/src/standalone/session-protocol.mjs +15 -0
  534. package/src/standalone/session-service/agent-route-follow.mjs +23 -20
  535. package/src/standalone/session-service/agent-tree/agent-turns.mjs +18 -6
  536. package/src/standalone/session-service/agent-tree.mjs +45 -9
  537. package/src/standalone/session-service/projection/transcript-window.mjs +700 -64
  538. package/src/standalone/session-service/quota-resume.mjs +9 -0
  539. package/src/standalone/session-service/session-calls/session-action.mjs +51 -1
  540. package/src/standalone/session-service/session-calls/session-turns.mjs +37 -18
  541. package/src/standalone/session-service/session-calls/session-views.mjs +160 -104
  542. package/src/standalone/session-service/session-calls/turn-gate.mjs +34 -0
  543. package/src/standalone/session-service/session-calls.mjs +2 -1
  544. package/src/standalone/session-service/stored-reader.mjs +127 -40
  545. package/src/tui/App.jsx +162 -164
  546. package/src/tui/app/app-view/floating-panel.jsx +3 -0
  547. package/src/tui/app/app-view/text-entry-labels.mjs +1 -0
  548. package/src/tui/app/clipboard.mjs +22 -11
  549. package/src/tui/app/create-app-pickers.mjs +2 -0
  550. package/src/tui/app/doctor.mjs +2 -2
  551. package/src/tui/app/panel-signature.mjs +1 -1
  552. package/src/tui/app/prompt-handlers/use-prompt-history-nav.mjs +1 -1
  553. package/src/tui/app/prompt-handlers/use-prompt-interrupt.mjs +3 -0
  554. package/src/tui/app/prompt-submit/provider-prompts.mjs +3 -1
  555. package/src/tui/app/provider-setup/api-key-actions.mjs +31 -1
  556. package/src/tui/app/provider-setup/oauth-actions.mjs +25 -6
  557. package/src/tui/app/provider-setup-picker.mjs +20 -13
  558. package/src/tui/app/settings-picker.mjs +53 -8
  559. package/src/tui/app/shell-layout/row-budgets.mjs +14 -12
  560. package/src/tui/app/slash-commands.mjs +2 -1
  561. package/src/tui/app/slash-dispatch/route-commands.mjs +1 -1
  562. package/src/tui/app/slash-dispatch/session-commands.mjs +47 -1
  563. package/src/tui/app/slash-dispatch.mjs +1 -1
  564. package/src/tui/app/use-btw-panel.mjs +29 -0
  565. package/src/tui/app/use-context-panel-refresh.mjs +31 -0
  566. package/src/tui/app/use-model-catalog-cache.mjs +13 -10
  567. package/src/tui/app/use-mouse-input.mjs +11 -0
  568. package/src/tui/app/use-onboarding-start.mjs +8 -3
  569. package/src/tui/app/use-panel-transition.mjs +10 -1
  570. package/src/tui/app/use-pasted-buffers.mjs +28 -20
  571. package/src/tui/app/use-prompt-draft-flow.mjs +7 -0
  572. package/src/tui/app/use-prompt-layout-rows.mjs +3 -3
  573. package/src/tui/app/use-prompt-queue-history.mjs +5 -4
  574. package/src/tui/app/use-selection-focus.mjs +11 -2
  575. package/src/tui/app/use-selection-geometry.mjs +18 -9
  576. package/src/tui/app/use-selection-paint.mjs +4 -4
  577. package/src/tui/app/use-selection-stitch.mjs +3 -3
  578. package/src/tui/app/use-slash-palette.mjs +62 -0
  579. package/src/tui/app/use-terminal-chrome.mjs +2 -2
  580. package/src/tui/app/use-transcript-activity.mjs +48 -33
  581. package/src/tui/app/use-transcript-follow.mjs +12 -4
  582. package/src/tui/app/use-transcript-scroll.mjs +46 -17
  583. package/src/tui/app/use-transcript-swap-reset.mjs +27 -0
  584. package/src/tui/app/use-transcript-window/geometry.mjs +20 -6
  585. package/src/tui/app/use-transcript-window/instance-state.mjs +4 -0
  586. package/src/tui/app/use-transcript-window/selection-shift.mjs +5 -1
  587. package/src/tui/app/use-transcript-window.mjs +21 -11
  588. package/src/tui/app/use-tui-ready.mjs +18 -0
  589. package/src/tui/app/use-welcome-prompt-hint.mjs +5 -0
  590. package/src/tui/app/use-workflow-tab-cycle.mjs +5 -3
  591. package/src/tui/components/Picker.jsx +27 -3
  592. package/src/tui/components/SignInUrl.jsx +68 -0
  593. package/src/tui/components/TextEntryPanel.jsx +76 -46
  594. package/src/tui/components/prompt-input/escape-policy.d.mts +0 -1
  595. package/src/tui/components/prompt-input/escape-policy.mjs +1 -1
  596. package/src/tui/components/question-panel-model.mjs +4 -4
  597. package/src/tui/components/sign-in-url-layout.mjs +24 -0
  598. package/src/tui/components/tool-execution/standard-card.jsx +3 -4
  599. package/src/tui/components/user-message-skills.mjs +1 -1
  600. package/src/tui/dist/index.mjs +2205 -1371
  601. package/src/tui/markdown/render-ansi.mjs +1 -1
  602. package/src/tui/session/agent-job-feed/notification-router.mjs +10 -0
  603. package/src/tui/session/agent-job-feed.mjs +2 -0
  604. package/src/tui/session/context-state.mjs +3 -0
  605. package/src/tui/session/goal-turn-state.mjs +6 -2
  606. package/src/tui/session/quota-resume.mjs +1 -1
  607. package/src/tui/session/session-api/controls.mjs +4 -0
  608. package/src/tui/session/session-api/extensions.mjs +8 -0
  609. package/src/tui/session/session-api/intake/abort.mjs +2 -1
  610. package/src/tui/session/session-api/intake.mjs +2 -0
  611. package/src/tui/session/session-api/integrations.mjs +2 -2
  612. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  613. package/src/tui/session/session-api/lifecycle/session-reset.mjs +7 -0
  614. package/src/tui/session/session-api/routes-agent-definitions.mjs +6 -0
  615. package/src/tui/session/session-api/settings.mjs +2 -2
  616. package/src/tui/session/session-api/worktree.mjs +13 -1
  617. package/src/tui/session/session-flow/drain.mjs +11 -14
  618. package/src/tui/session/tool-card-results/grouped-result.mjs +2 -2
  619. package/src/tui/session/transcript-spill/spill-writer.mjs +15 -0
  620. package/src/tui/session/transcript-spill.mjs +92 -4
  621. package/src/tui/session/transcript-store.mjs +2 -0
  622. package/src/tui/session/turn-quiet.mjs +1 -1
  623. package/src/tui/session/turn.mjs +3 -0
  624. package/src/tui/session/worktree-setup-notice.mjs +1 -1
  625. package/src/tui/spinner-meta.mjs +3 -3
  626. package/src/tui/spinner-verbs.mjs +2 -2
  627. package/src/defaults/skills/goal-management/SKILL.md +0 -169
  628. package/src/defaults/skills/skill-creator/references/source-review.md +0 -94
  629. package/src/runtime/agent/orchestrator/runtime-core/goal-tasks.mjs +0 -156
  630. package/src/session-runtime/goal-tasks.mjs +0 -1
@@ -20,6 +20,60 @@ import { assertWorktreeMutationAllowed, worktreeCallerScope } from '../services/
20
20
 
21
21
  const loadManager = () => import('../../runtime/shared/worktrees/manager.mjs');
22
22
 
23
+ async function enter(lane, request) {
24
+ if (request.branch) {
25
+ return lane.call('selectBranch', {
26
+ branch: request.branch,
27
+ create: request.create === true,
28
+ confirmLarge: request.confirmLarge === true,
29
+ txId: request.txId,
30
+ });
31
+ }
32
+ // A valid slug names the worktree; any other text is a hint the slug is made from.
33
+ const name = typeof request.name === 'string' ? request.name.trim() : '';
34
+ const slug = name && !worktreeNameError(name) ? name : null;
35
+ return lane.call('requestWorktree', {
36
+ provision: true,
37
+ name: slug,
38
+ prompt: slug ? '' : name,
39
+ ...(request.carry ? { carryChanges: request.carry } : {}),
40
+ confirmLarge: request.confirmLarge === true,
41
+ txId: request.txId,
42
+ });
43
+ }
44
+
45
+ /** Back to the project folder (the branch checked out there); the worktree stays retained. */
46
+ async function back(lane, request) {
47
+ const menu = await lane.menu();
48
+ const workspace = menu.workspace;
49
+ if (!workspace.worktreeId && samePath(workspace.cwd, workspace.projectPath)) {
50
+ return { revision: workspace.revision, workspace, unchanged: true };
51
+ }
52
+ const projectBranch = menu.occupancy.find((row) => row.kind === 'current')?.branch ?? null;
53
+ if (!projectBranch) {
54
+ throw worktreeError(
55
+ 'WORKTREE_UNSUPPORTED_REPO',
56
+ 'The project folder has no checked-out branch to return to (detached HEAD).'
57
+ );
58
+ }
59
+ return lane.call('selectBranch', {
60
+ branch: projectBranch,
61
+ expectedRevision: workspace.revision,
62
+ txId: request.txId,
63
+ });
64
+ }
65
+
66
+ /** The desktop's "merge": into the confirmed merge target, then the cleanup autoCleanup allows. */
67
+ async function merge(lane) {
68
+ const { workspace } = await lane.menu();
69
+ return lane.call('mergeWorkspace', {
70
+ confirmed: true,
71
+ target: workspace.mergeTarget ?? null,
72
+ expectedRevision: workspace.revision,
73
+ cleanup: true,
74
+ });
75
+ }
76
+
23
77
  /**
24
78
  * @param {object} deps
25
79
  * @param {() => any} deps.getSession The Lead session this runtime hosts (its trusted caller scope).
@@ -61,60 +115,6 @@ export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSes
61
115
  return { own: false, menu: () => control('getBranchMenu'), call: control };
62
116
  }
63
117
 
64
- async function enter(lane, request) {
65
- if (request.branch) {
66
- return lane.call('selectBranch', {
67
- branch: request.branch,
68
- create: request.create === true,
69
- confirmLarge: request.confirmLarge === true,
70
- txId: request.txId,
71
- });
72
- }
73
- // A valid slug names the worktree; any other text is a hint the slug is made from.
74
- const name = typeof request.name === 'string' ? request.name.trim() : '';
75
- const slug = name && !worktreeNameError(name) ? name : null;
76
- return lane.call('requestWorktree', {
77
- provision: true,
78
- name: slug,
79
- prompt: slug ? '' : name,
80
- ...(request.carry ? { carryChanges: request.carry } : {}),
81
- confirmLarge: request.confirmLarge === true,
82
- txId: request.txId,
83
- });
84
- }
85
-
86
- /** Back to the project folder (the branch checked out there); the worktree stays retained. */
87
- async function back(lane, request) {
88
- const menu = await lane.menu();
89
- const workspace = menu.workspace;
90
- if (!workspace.worktreeId && samePath(workspace.cwd, workspace.projectPath)) {
91
- return { revision: workspace.revision, workspace, unchanged: true };
92
- }
93
- const projectBranch = menu.occupancy.find((row) => row.kind === 'current')?.branch ?? null;
94
- if (!projectBranch) {
95
- throw worktreeError(
96
- 'WORKTREE_UNSUPPORTED_REPO',
97
- 'The project folder has no checked-out branch to return to (detached HEAD).'
98
- );
99
- }
100
- return lane.call('selectBranch', {
101
- branch: projectBranch,
102
- expectedRevision: workspace.revision,
103
- txId: request.txId,
104
- });
105
- }
106
-
107
- /** The desktop's "merge": into the confirmed merge target, then the cleanup autoCleanup allows. */
108
- async function merge(lane) {
109
- const { workspace } = await lane.menu();
110
- return lane.call('mergeWorkspace', {
111
- confirmed: true,
112
- target: workspace.mergeTarget ?? null,
113
- expectedRevision: workspace.revision,
114
- cleanup: true,
115
- });
116
- }
117
-
118
118
  /**
119
119
  * The listed worktree matching `predicate` whose owner is gone and that the
120
120
  * list reports removable, or null: no owner lane can remove it.
@@ -147,6 +147,11 @@ export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSes
147
147
  }
148
148
  const lane = laneFor(entry.ownerSessionId, callerSessionId, scope);
149
149
  const menu = await lane.menu();
150
+ // This session's worktree that it does not work in: removed where it is,
151
+ // without entering it (its own running workers elsewhere never block that).
152
+ if (lane.own && menu.workspace?.worktreeId !== entry.id) {
153
+ return workspaceApi().removeOwnedWorktree({ entryId: entry.id, force: request.force === true });
154
+ }
150
155
  if (menu.retainedWorktree?.id !== entry.id) {
151
156
  throw new Error(
152
157
  `git worktree remove: ${entry.path} is not the current worktree of session ${entry.ownerSessionId}; enter it (worktree_action enter, branch ${entry.branch}) first, then remove it`
@@ -174,6 +179,17 @@ export function createWorktreeToolHost({ getSession, getWorkspaceApi, executeSes
174
179
  return merge(lane());
175
180
  case 'remove': {
176
181
  const force = request.force === true;
182
+ if (request.branch) {
183
+ // By branch: the managed worktree of that branch this session owns.
184
+ const rows = await workspaceApi().listWorktrees();
185
+ const row = rows.find((item) => item.branch === request.branch && item.ownerSessionId === callerSessionId);
186
+ if (!row) {
187
+ throw new Error(
188
+ `git worktree remove: this session owns no managed worktree of branch ${request.branch}; git worktree list shows them`
189
+ );
190
+ }
191
+ return removePath({ path: row.path, force }, callerSessionId, scope);
192
+ }
177
193
  if (request.sessionId && request.sessionId !== callerSessionId) {
178
194
  const gone = await orphan((row) => row.ownerSessionId === request.sessionId);
179
195
  if (gone) return workspaceApi().removeOrphanWorktree({ entryId: gone.id, force });
@@ -6,7 +6,7 @@
6
6
  //
7
7
  // Inputs: `getSessionService` / `getSessionRuntimeHost` (both are wired after
8
8
  // this control exists — the host takes `execute` as a constructor option), and
9
- // `cwd`. Output: { canonicalAgentTool, execute }.
9
+ // `cwd`. Output: { canonicalAgentTool, execute, runForeground, dispose }.
10
10
 
11
11
  export function createCanonicalAgentControl({ getSessionService, getSessionRuntimeHost, cwd }) {
12
12
  let canonicalAgentToolPromise = null;
@@ -43,16 +43,33 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
43
43
  return canonicalAgentToolPromise;
44
44
  }
45
45
 
46
- async function execute(args = {}, context = {}) {
47
- const tool = await canonicalAgentTool();
46
+ /** `context` rooted at its caller session (agent-tool: the owner is the caller's root). */
47
+ async function scopeContext(context) {
48
48
  const sessionService = getSessionService();
49
49
  const parentSessionId = String(context?.callerSessionId || '').trim();
50
50
  await sessionService.rehydrateAgentSessions();
51
- const scopedContext = {
52
- ...context,
53
- callerSessionId: parentSessionId || null,
54
- ownerSessionId: sessionService.rootOwnerSessionId(parentSessionId),
51
+ return {
52
+ parentSessionId,
53
+ sessionService,
54
+ scopedContext: {
55
+ ...context,
56
+ callerSessionId: parentSessionId || null,
57
+ ownerSessionId: sessionService.rootOwnerSessionId(parentSessionId),
58
+ },
55
59
  };
60
+ }
61
+
62
+ /** One agent run to its end for a caller with no session to hand it to
63
+ * (routine-executor.mjs): resolves `{ sessionId, content }`. */
64
+ async function runForeground(args = {}, context = {}, options = {}) {
65
+ const tool = await canonicalAgentTool();
66
+ const { scopedContext } = await scopeContext(context);
67
+ return await tool.runToCompletion(args, scopedContext, options);
68
+ }
69
+
70
+ async function execute(args = {}, context = {}) {
71
+ const tool = await canonicalAgentTool();
72
+ const { parentSessionId, sessionService, scopedContext } = await scopeContext(context);
56
73
  if (String(args?.type || '') === '__close_all') {
57
74
  await tool.closeAll?.(String(args?.reason || 'agent owner closed'), {
58
75
  callerSessionId: parentSessionId || null,
@@ -72,5 +89,5 @@ export function createCanonicalAgentControl({ getSessionService, getSessionRunti
72
89
  await tool?.disposeAsync?.({ settle: true });
73
90
  }
74
91
 
75
- return { canonicalAgentTool, execute, dispose };
92
+ return { canonicalAgentTool, execute, runForeground, dispose };
76
93
  }
@@ -12,12 +12,13 @@
12
12
  * this daemon's in-memory turn activity (every session runs inline here, so
13
13
  * it is the single source of truth; worker index files only declare work). */
14
14
  async function loadSessionStoreWithRuntimeActivity() {
15
- const [store, runtime, progress, tasks] = await Promise.all([
15
+ const [store, runtime, progress, tasks, liveState] = await Promise.all([
16
16
  import('../runtime/agent/orchestrator/session/store-summary-reader.mjs'),
17
17
  // The import-free leaf holding the runtime map: no session manager graph.
18
18
  import('../runtime/agent/orchestrator/session/manager/runtime-state.mjs'),
19
19
  import('../runtime/agent/orchestrator/session/agent-pool-progress.mjs'),
20
20
  import('../runtime/shared/background-tasks.mjs'),
21
+ import('../runtime/agent/orchestrator/session/store/live-state.mjs'),
21
22
  ]);
22
23
  return {
23
24
  ...store,
@@ -33,7 +34,10 @@ async function loadSessionStoreWithRuntimeActivity() {
33
34
  });
34
35
  const awaiting = tasks.activeBackgroundTaskSessionIds({ surface: 'shell', awaitedOnly: true });
35
36
  return progress.withTurnProgress(
36
- rows,
37
+ progress.withLiveUsage(
38
+ progress.withLiveTodo(rows, (sessionId) => liveState._liveSessions.get(sessionId)),
39
+ (sessionId) => liveState._liveSessions.get(sessionId)
40
+ ),
37
41
  (sessionId) => runtime.runtimeState.get(sessionId),
38
42
  runtime.isTurnInFlight,
39
43
  (sessionId) => awaiting.has(sessionId)
@@ -66,6 +70,8 @@ export function createDesktopRuntime({ getLocalSessionBridge }) {
66
70
  loadDocumentPreview: () => import('../runtime/office/pdf/document-preview.mjs'),
67
71
  // The desktop service's git children start on this worker, off the loop.
68
72
  loadProcessRunner: () => import('../runtime/shared/process-runner.mjs'),
73
+ // The desktop app on this PC answers this daemon's per-origin proxy lookups.
74
+ loadSystemProxy: () => import('../runtime/shared/llm/system-proxy.mjs'),
69
75
  async executeCodeGraphTool(name, args, cwd) {
70
76
  const graph = await import('../runtime/agent/orchestrator/tools/code-graph/dispatch.mjs');
71
77
  return graph.executeCodeGraphTool(name, args, cwd);
@@ -15,14 +15,14 @@ import path from 'node:path';
15
15
  import { fileURLToPath } from 'node:url';
16
16
 
17
17
  export const LAG_PROFILE_FLAG_FILE = 'lag-profile.on';
18
- export const LAG_PROFILE_DIR_NAME = 'profiles';
19
- export const LAG_PROFILE_KEEP = 10;
20
- export const LAG_PROFILE_TOP = 15;
18
+ const LAG_PROFILE_DIR_NAME = 'profiles';
19
+ const LAG_PROFILE_KEEP = 10;
20
+ const LAG_PROFILE_TOP = 15;
21
21
  export const LAG_PROFILE_SAMPLING_US = 1000;
22
- export const LAG_P99_THRESHOLD_MS = 1000;
22
+ const LAG_P99_THRESHOLD_MS = 1000;
23
23
  // The owner lease's stall threshold: any window holding one logged
24
24
  // `event loop stalled` line is kept.
25
- export const LAG_MAX_THRESHOLD_MS = 1000;
25
+ const LAG_MAX_THRESHOLD_MS = 1000;
26
26
 
27
27
  const PROFILE_FILE_RE = /^daemon-lag-.+\.cpuprofile$/;
28
28
  const SRC_ROOT = fileURLToPath(new URL('..', import.meta.url));
@@ -90,12 +90,12 @@ export function summarizeCpuProfile(profile, { limit = LAG_PROFILE_TOP, srcRoot
90
90
  .slice(0, limit);
91
91
  }
92
92
 
93
- export function formatTopEntries(entries) {
93
+ function formatTopEntries(entries) {
94
94
  return entries.map((entry) => `${entry.label}=${Math.round(entry.ms)}ms`).join(',');
95
95
  }
96
96
 
97
97
  /** Keep only the `keep` newest daemon-lag profiles (names sort by timestamp). */
98
- export async function pruneProfiles(dir, keep = LAG_PROFILE_KEEP) {
98
+ async function pruneProfiles(dir, keep = LAG_PROFILE_KEEP) {
99
99
  const names = (await fsp.readdir(dir)).filter((name) => PROFILE_FILE_RE.test(name)).sort();
100
100
  const stale = names.slice(0, Math.max(0, names.length - keep));
101
101
  for (const name of stale) await fsp.rm(path.join(dir, name), { force: true });
@@ -80,6 +80,154 @@ async function storedTitle(sessionId) {
80
80
  }
81
81
 
82
82
  /** Model-facing session operations over the same service used by desktop and TUI. */
83
+ /** `session action=list`: live sessions first, then the filtered catalog scan. */
84
+ async function listSessions({ service, liveWork, readRow }, args, context, limit) {
85
+ assertListFlags(args);
86
+ // Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
87
+ // list everything with previews, a bot (or its unattended run) lists the
88
+ // same rows (so it can find a session to send to) but only its own carry
89
+ // the bot, activity, preview and working state, anything else the plain
90
+ // rows without previews. Sub-agent sessions (a
91
+ // parent finds its own through the agent tool) and archived ones (the
92
+ // desktop's flag) only on request; the scan pages past the rows left
93
+ // out, so a page is never short while more rows match.
94
+ const own = scopedBot(context.callerScope);
95
+ const archived = (await readSessionSidebarState())?.archived ?? {};
96
+ const keep = listRowFilter(args, archived);
97
+ // Live work is overlaid on every row: a catalog row keeps the status and
98
+ // recency of its last settled turn, so a long-running agent read `idle`
99
+ // and sorted by its first prompt. The first page lists the live rows
100
+ // first (newest sign of work first); a later page keeps catalog order,
101
+ // where such a row may show again (never skipped).
102
+ const live = await liveWork();
103
+ const withLive = liveRowOverlay(live);
104
+ // Each live session's row is read by id (wherever it sits in the
105
+ // catalog), filtered like the listing, and the newest `limit` lead.
106
+ const candidates = liveCandidates(live);
107
+ let pinned = [];
108
+ if (!args.cursor && candidates.length) {
109
+ pinned = pinnedLiveRows(await Promise.all(candidates.map((id) => readRow(id))), keep, withLive, limit);
110
+ }
111
+ const pinnedIds = new Set(pinned.map((row) => row.id));
112
+ const want = limit - pinned.length;
113
+ // Bounded: past 10000 rows scanned with fewer than `limit` matching, the
114
+ // page ends (possibly empty) with a nextCursor to continue from.
115
+ const scan =
116
+ want > 0
117
+ ? await scanCatalog(service, (row) => !pinnedIds.has(row.id) && keep(row), {
118
+ cursor: args.cursor || null,
119
+ want,
120
+ maxRows: 10_000,
121
+ })
122
+ : { rows: [], nextCursor: TOP_CURSOR };
123
+ const sessions = listedSessions(pinned, scan.rows, withLive, archived);
124
+ return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, listOutputOptions(own, pinnedIds));
125
+ }
126
+
127
+ /** `session action=send`: queue a prompt in another session (a room member, a task session or any session). */
128
+ async function sendToSession({ service, agentTasks }, args, context, sessionId, caller) {
129
+ assertSendRequest(args, sessionId);
130
+ // A send to a room's log is a message to one member there (`to`, or a
131
+ // leading @name), run by the desktop room host; the member's turn in
132
+ // its member session is the turn that answers and reports.
133
+ const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
134
+ if (room?.sessionId === caller) throw new Error('session: send must target another session');
135
+ // Work goes on to a bot (a room seat's, or a bot's home) only outside
136
+ // the caller's bot chain (`callerBotChain`, bot-chain.mjs), never back
137
+ // to the caller's own bot; the turn it starts carries that chain on.
138
+ const botChain = botChainOf(context.callerBotChain);
139
+ assertBotChainTarget(
140
+ room ? room.agentId : agentIdOfHomeSession(sessionId),
141
+ { chain: botChain, self: context.callerBotId || context.callerAgentId || '' },
142
+ 'session'
143
+ );
144
+ // An agent conversation's send reports its turn back to the agent's
145
+ // home: a task session it created by its stored origin, any other
146
+ // session by an origin for this send only.
147
+ // Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
148
+ const prompt = handoffContent(room ? room.text : args.prompt, context.attachmentParts);
149
+ const turnSessionId = room ? room.sessionId : sessionId;
150
+ const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
151
+ const submit = room ? roomSubmitter(room, sessionId, prompt, from) : null;
152
+ const addressed = room ? { to: room.agentId } : {};
153
+ let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
154
+ // `effort` is the menu's effort pick on the target: checked now against the
155
+ // levels of its model, applied just before the prompt is queued.
156
+ let applyEffort = async () => {};
157
+ if (args.effort !== undefined) {
158
+ if (room) throw new Error('session: effort applies to a session, not a group room');
159
+ // Any bot, attended or not (`callerBotId`), changes only the task
160
+ // sessions it created; reports go only to a bot conversation.
161
+ const botId = context.callerBotId || context.callerAgentId || '';
162
+ if (botId && (await agentTasks.reportOrigin(sessionId, botId, caller))?.target === 'session') {
163
+ throw new Error('session: a bot may set the effort only of the task sessions it created');
164
+ }
165
+ const target = (await service.readSession({ sessionId, transcriptItemLimit: 1 })).full;
166
+ if (!target) throw new Error(`session: ${sessionId} is unavailable`);
167
+ const level = checkEffort(args.effort, target, await readModelCatalog(service, caller));
168
+ applyEffort = effortApplier(service, sessionId, level);
169
+ }
170
+ // A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
171
+ // another session, extends the chain by one; a bot's own task session
172
+ // only continues it. Refused past the limit, whatever the target.
173
+ const turnHop = Number(context.callerHop) || 0;
174
+ if (origin) {
175
+ const hop = chainedHop(origin.target === 'session' ? turnHop + 1 : turnHop);
176
+ origin = chainedOrigin(origin, hop, botChain);
177
+ // The task session a bot created acts as the sending conversation does
178
+ // from now on (attended chat or run); another's session keeps its own.
179
+ if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
180
+ await applyEffort();
181
+ const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
182
+ return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
183
+ }
184
+ const hop = turnHop > 0 ? chainedHop(turnHop + 1) : 0;
185
+ await applyEffort();
186
+ const chainMeta = { ...(hop > 0 ? { hop } : {}), ...(botChain.length ? { botChain } : {}) };
187
+ let accepted;
188
+ if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
189
+ else {
190
+ // New work from this sender: a delegated target acts as the sender does.
191
+ await rebindDelegation(sessionId, caller);
192
+ const result = await service.submitSession({
193
+ sessionId,
194
+ prompt,
195
+ options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...chainMeta } },
196
+ });
197
+ accepted = result.accepted === true;
198
+ }
199
+ return unreportedSendResult(sessionId, addressed, accepted, hop);
200
+ }
201
+
202
+ /** `session action=status` (and the default read): one session's route, busy state and pending work. */
203
+ async function readSessionStatus({ service, readTitle, pendingWork }, action, sessionId, limit) {
204
+ const result = await service.readSession({
205
+ sessionId,
206
+ transcriptItemLimit: action === 'status' ? 1 : limit,
207
+ transcriptByteBudget: SESSION_TOOL_OUTPUT_BYTES,
208
+ });
209
+ const snapshot = result.full;
210
+ if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
211
+ // The snapshot carries no title: it lives on the session record. Quoted
212
+ // like a listed title.
213
+ const title = await readTitle(sessionId);
214
+ return {
215
+ sessionId,
216
+ title: title ? escapeHarnessTags(truncateToolText(title, SESSION_TITLE_LIMIT)) : null,
217
+ cwd: snapshot.cwd ?? null,
218
+ provider: snapshot.provider ?? null,
219
+ model: snapshot.model ?? null,
220
+ effort: snapshot.effort ?? null,
221
+ autoEffort: snapshot.autoEffort ?? null,
222
+ fast: snapshot.fast ?? null,
223
+ busy: snapshot.busy === true,
224
+ // A Lead idle between turns while its agents run is still working:
225
+ // their results wake it, so `busy` alone would read as stalled.
226
+ agentsWorking: (await pendingWork(sessionId)) === true,
227
+ quotaResume: snapshot.quotaResume ?? null,
228
+ };
229
+ }
230
+
83
231
  export function createSessionControl({
84
232
  getSessionService,
85
233
  agentTasks = createAgentTaskSessions({ getSessionService }),
@@ -108,119 +256,10 @@ export function createSessionControl({
108
256
  const service = getSessionService();
109
257
  if (!service) throw new Error('session: session service is unavailable');
110
258
  if (action === 'list') {
111
- assertListFlags(args);
112
- // Scoped like bots (`callerScope`, bot-status.mjs): the human's sessions
113
- // list everything with previews, a bot (or its unattended run) lists the
114
- // same rows (so it can find a session to send to) but only its own carry
115
- // the bot, activity, preview and working state, anything else the plain
116
- // rows without previews. Sub-agent sessions (a
117
- // parent finds its own through the agent tool) and archived ones (the
118
- // desktop's flag) only on request; the scan pages past the rows left
119
- // out, so a page is never short while more rows match.
120
- const own = scopedBot(context.callerScope);
121
- const archived = (await readSessionSidebarState())?.archived ?? {};
122
- const keep = listRowFilter(args, archived);
123
- // Live work is overlaid on every row: a catalog row keeps the status and
124
- // recency of its last settled turn, so a long-running agent read `idle`
125
- // and sorted by its first prompt. The first page lists the live rows
126
- // first (newest sign of work first); a later page keeps catalog order,
127
- // where such a row may show again (never skipped).
128
- const live = await liveWork();
129
- const withLive = liveRowOverlay(live);
130
- // Each live session's row is read by id (wherever it sits in the
131
- // catalog), filtered like the listing, and the newest `limit` lead.
132
- const candidates = liveCandidates(live);
133
- let pinned = [];
134
- if (!args.cursor && candidates.length) {
135
- pinned = pinnedLiveRows(await Promise.all(candidates.map((id) => readRow(id))), keep, withLive, limit);
136
- }
137
- const pinnedIds = new Set(pinned.map((row) => row.id));
138
- const want = limit - pinned.length;
139
- // Bounded: past 10000 rows scanned with fewer than `limit` matching, the
140
- // page ends (possibly empty) with a nextCursor to continue from.
141
- const scan =
142
- want > 0
143
- ? await scanCatalog(service, (row) => !pinnedIds.has(row.id) && keep(row), {
144
- cursor: args.cursor || null,
145
- want,
146
- maxRows: 10_000,
147
- })
148
- : { rows: [], nextCursor: TOP_CURSOR };
149
- const sessions = listedSessions(pinned, scan.rows, withLive, archived);
150
- return sessionListOutput({ sessions, nextCursor: scan.nextCursor }, limit, listOutputOptions(own, pinnedIds));
259
+ return listSessions({ service, liveWork, readRow }, args, context, limit);
151
260
  }
152
261
  if (action === 'send') {
153
- assertSendRequest(args, sessionId);
154
- // A send to a room's log is a message to one member there (`to`, or a
155
- // leading @name), run by the desktop room host; the member's turn in
156
- // its member session is the turn that answers and reports.
157
- const room = roomIdOfSession(sessionId) ? await roomAddressee(sessionId, args) : null;
158
- if (room?.sessionId === caller) throw new Error('session: send must target another session');
159
- // Work goes on to a bot (a room seat's, or a bot's home) only outside
160
- // the caller's bot chain (`callerBotChain`, bot-chain.mjs), never back
161
- // to the caller's own bot; the turn it starts carries that chain on.
162
- const botChain = botChainOf(context.callerBotChain);
163
- assertBotChainTarget(
164
- room ? room.agentId : agentIdOfHomeSession(sessionId),
165
- { chain: botChain, self: context.callerBotId || context.callerAgentId || '' },
166
- 'session'
167
- );
168
- // An agent conversation's send reports its turn back to the agent's
169
- // home: a task session it created by its stored origin, any other
170
- // session by an origin for this send only.
171
- // Forwarded files ride along as stored attachment parts (workspace-tools.mjs).
172
- const prompt = handoffContent(room ? room.text : args.prompt, context.attachmentParts);
173
- const turnSessionId = room ? room.sessionId : sessionId;
174
- const from = { sessionId: caller, ...(context.callerAgentId ? { agentId: context.callerAgentId } : {}) };
175
- const submit = room ? roomSubmitter(room, sessionId, prompt, from) : null;
176
- const addressed = room ? { to: room.agentId } : {};
177
- let origin = await agentTasks.reportOrigin(turnSessionId, context.callerAgentId, caller);
178
- // `effort` is the menu's effort pick on the target: checked now against the
179
- // levels of its model, applied just before the prompt is queued.
180
- let applyEffort = async () => {};
181
- if (args.effort !== undefined) {
182
- if (room) throw new Error('session: effort applies to a session, not a group room');
183
- // Any bot, attended or not (`callerBotId`), changes only the task
184
- // sessions it created; reports go only to a bot conversation.
185
- const botId = context.callerBotId || context.callerAgentId || '';
186
- if (botId && (await agentTasks.reportOrigin(sessionId, botId, caller))?.target === 'session') {
187
- throw new Error('session: a bot may set the effort only of the task sessions it created');
188
- }
189
- const target = (await service.readSession({ sessionId, transcriptItemLimit: 1 })).full;
190
- if (!target) throw new Error(`session: ${sessionId} is unavailable`);
191
- const level = checkEffort(args.effort, target, await readModelCatalog(service, caller));
192
- applyEffort = effortApplier(service, sessionId, level);
193
- }
194
- // A send made in a bot-descended turn (`callerHop` > 0), or by a bot to
195
- // another session, extends the chain by one; a bot's own task session
196
- // only continues it. Refused past the limit, whatever the target.
197
- const turnHop = Number(context.callerHop) || 0;
198
- if (origin) {
199
- const hop = chainedHop(origin.target === 'session' ? turnHop + 1 : turnHop);
200
- origin = chainedOrigin(origin, hop, botChain);
201
- // The task session a bot created acts as the sending conversation does
202
- // from now on (attended chat or run); another's session keeps its own.
203
- if (origin.target !== 'session') await rebindDelegation(sessionId, caller);
204
- await applyEffort();
205
- const sent = await agentTasks.send(turnSessionId, prompt, origin, submit);
206
- return { sessionId, ...addressed, ...sent, ...(hop > 0 ? { hop } : {}) };
207
- }
208
- const hop = turnHop > 0 ? chainedHop(turnHop + 1) : 0;
209
- await applyEffort();
210
- const chainMeta = { ...(hop > 0 ? { hop } : {}), ...(botChain.length ? { botChain } : {}) };
211
- let accepted;
212
- if (submit) accepted = (await submit(hop > 0 ? { transcriptMeta: { hop } } : {})).accepted;
213
- else {
214
- // New work from this sender: a delegated target acts as the sender does.
215
- await rebindDelegation(sessionId, caller);
216
- const result = await service.submitSession({
217
- sessionId,
218
- prompt,
219
- options: { mode: 'prompt', transcriptMeta: { sender: 'lead', ...chainMeta } },
220
- });
221
- accepted = result.accepted === true;
222
- }
223
- return unreportedSendResult(sessionId, addressed, accepted, hop);
262
+ return sendToSession({ service, agentTasks }, args, context, sessionId, caller);
224
263
  }
225
264
  if (action === 'cancel') {
226
265
  // A room's exchange is run by the desktop room host, so its stop (the UI
@@ -240,31 +279,7 @@ export function createSessionControl({
240
279
  const result = await service.readSession({ sessionId, transcriptRange: { offset, limit } });
241
280
  return sessionReadOutput(sessionId, result.range, { textOffset, itemId: args.item_id });
242
281
  }
243
- const result = await service.readSession({
244
- sessionId,
245
- transcriptItemLimit: action === 'status' ? 1 : limit,
246
- transcriptByteBudget: SESSION_TOOL_OUTPUT_BYTES,
247
- });
248
- const snapshot = result.full;
249
- if (!snapshot) throw new Error(`session: ${sessionId} is unavailable`);
250
- // The snapshot carries no title: it lives on the session record. Quoted
251
- // like a listed title.
252
- const title = await readTitle(sessionId);
253
- return {
254
- sessionId,
255
- title: title ? escapeHarnessTags(truncateToolText(title, SESSION_TITLE_LIMIT)) : null,
256
- cwd: snapshot.cwd ?? null,
257
- provider: snapshot.provider ?? null,
258
- model: snapshot.model ?? null,
259
- effort: snapshot.effort ?? null,
260
- autoEffort: snapshot.autoEffort ?? null,
261
- fast: snapshot.fast ?? null,
262
- busy: snapshot.busy === true,
263
- // A Lead idle between turns while its agents run is still working:
264
- // their results wake it, so `busy` alone would read as stalled.
265
- agentsWorking: (await pendingWork(sessionId)) === true,
266
- quotaResume: snapshot.quotaResume ?? null,
267
- };
282
+ return readSessionStatus({ service, readTitle, pendingWork }, action, sessionId, limit);
268
283
  }
269
284
 
270
285
  return async function executeSessionControl(args = {}, context = {}) {