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
@@ -124,6 +124,15 @@ export function createQuotaResumeScheduler({
124
124
  function tick() {
125
125
  if (running) return running;
126
126
  running = (async () => {
127
+ // The setting turned off anywhere (another process, a hand edit), not
128
+ // only through setQuotaAutoResumeEnabled here: nothing pending resumes.
129
+ if (store.quotaAutoResumeEnabled?.() === false) {
130
+ if (store.listQuotaResumeEntries().length) {
131
+ store.cancelAllQuotaResumeEntries();
132
+ log('quota resume off: pending resumes cancelled');
133
+ }
134
+ return;
135
+ }
127
136
  for (const entry of store.listQuotaResumeEntries()) {
128
137
  if (isClosed()) return;
129
138
  if (entry.resetAt > now() || !isCurrent(store, entry)) continue;
@@ -5,6 +5,7 @@ import { SESSION_CONFIGURE_ACTION_SET, SESSION_READ_ACTION_SET } from '../../ses
5
5
  import { annotateSpan, markPhase } from '../../../runtime/shared/slow-span.mjs';
6
6
  import { sanitizeForWire } from '../../session-wire-values.mjs';
7
7
  import { botWorkBySession } from '../../../runtime/shared/bot-owned-work.mjs';
8
+ import { createSessionTurnGate } from './turn-gate.mjs';
8
9
 
9
10
  /** Reads a session without a live runtime answers from disk (readStoredReview). */
10
11
  const STORED_REVIEW_ACTIONS = new Set([
@@ -43,6 +44,9 @@ export function createSessionActionCalls(ctx) {
43
44
  const { bodyForClient } = ctx.projection;
44
45
  const { retainUnwatched, awaitingApprovalSessionKinds, roomHandoffQuestions } = ctx.retention;
45
46
  const { assertAvailable, hostedEntryForSession, entryForSession } = ctx.entries;
47
+ const { stateBusy } = ctx.retention;
48
+ const sessionOwner = ctx.projection?.sessionOwner;
49
+ const turnGate = ctx.turnGate ?? createSessionTurnGate();
46
50
 
47
51
  /** A cold session's review, read from its durable turn record (the same
48
52
  * source a runtime loaded only to answer it would read). Bodiless: the
@@ -82,7 +86,12 @@ export function createSessionActionCalls(ctx) {
82
86
  if (storedReview && !hosted) return storedReviewResult(id, name, args, baseRevision);
83
87
  const entry = hosted || (await entryForSession(id, openHints || {}));
84
88
  assertAvailable(entry);
85
- const target = entry.runtime[name];
89
+ // A remote read of the context status waits for an empty session's
90
+ // settings reconcile; the local accessor stays synchronous.
91
+ const target =
92
+ name === 'contextStatus' && typeof entry.runtime.contextStatusSettled === 'function'
93
+ ? entry.runtime.contextStatusSettled
94
+ : entry.runtime[name];
86
95
  if (typeof target !== 'function') throw new TypeError(`session action ${name} is unavailable`);
87
96
  markPhase('load');
88
97
  const value = await target.apply(entry.runtime, Array.isArray(args) ? args : []);
@@ -162,9 +171,50 @@ export function createSessionActionCalls(ctx) {
162
171
  };
163
172
  }
164
173
 
174
+ /** The desktop's auto-delete through the control session (`sessionId`):
175
+ * `args` = [target id, { lastUsedAt }]. The target is closed to service
176
+ * turn starts while the runtime's idle-only delete checks and acts
177
+ * (session-delete.mjs deleteSessionIfIdle); one being admitted refuses it. */
178
+ async function deleteIdleSession({ sessionId, args = [], open: openHints = {}, baseRevision = null } = {}) {
179
+ assertAvailable();
180
+ const controlId = String(sessionId || '');
181
+ if (!controlId) throw new TypeError('sessionId is required');
182
+ const [target, expected] = Array.isArray(args) ? args : [];
183
+ const id = String(target || '');
184
+ const entry = await entryForSession(controlId, openHints || {});
185
+ assertAvailable(entry);
186
+ if (typeof entry.runtime.deleteSessionIfIdle !== 'function') {
187
+ throw new TypeError('session action deleteSessionIfIdle is unavailable');
188
+ }
189
+ let value;
190
+ const reopen = id ? turnGate.fence(id) : null;
191
+ if (!reopen) value = { deleted: false, reason: id ? 'turn-starting' : 'invalid' };
192
+ else {
193
+ try {
194
+ value = await entry.runtime.deleteSessionIfIdle(id, expected ?? {}, {
195
+ isHostedBusy: (sessionIdToCheck) => {
196
+ const owner = sessionOwner?.(sessionIdToCheck);
197
+ return Boolean(owner) && stateBusy(owner.runtime?.getState?.());
198
+ },
199
+ });
200
+ } finally {
201
+ reopen();
202
+ }
203
+ }
204
+ log(`session action deleteSessionIfIdle session=${id} result=${resultSummary(value?.deleted ?? value)}`);
205
+ const step = advanceForCaller(entry);
206
+ retainUnwatched(entry);
207
+ return {
208
+ value: sanitizeForWire(value) ?? null,
209
+ sessionId: responseSessionId(entry, controlId),
210
+ ...bodyForClient(step, Number.isInteger(baseRevision) ? baseRevision : null),
211
+ };
212
+ }
213
+
165
214
  async function configureSession(params = {}, callCtx = null) {
166
215
  const revision = Math.max(0, Number(callCtx?.revision) || 0);
167
216
  const action = params?.action;
217
+ if (action === 'deleteSessionIfIdle') return deleteIdleSession(params);
168
218
  // Revision 0 desktop adapters routed some reads through configure because
169
219
  // their local read list lagged the session surface. A newer daemon accepts
170
220
  // those reads without weakening the current revision's finite lanes.
@@ -4,6 +4,7 @@
4
4
  // sessions that carry an active Goal after daemon replacement is wired in from
5
5
  // ./goal-recovery.mjs.
6
6
  import { createGoalRecovery } from './goal-recovery.mjs';
7
+ import { createSessionTurnGate } from './turn-gate.mjs';
7
8
  import {
8
9
  attachmentsForIntake,
9
10
  materializePromptSubmission,
@@ -54,6 +55,8 @@ export function createSessionTurnCalls(ctx) {
54
55
  const { log, readStoredGoal, listStoredActiveGoalSessionIds, hasAgentSession, sessionResult, advanceForCaller } = ctx;
55
56
  const { retainUnwatched } = ctx.retention;
56
57
  const { entryForSession } = ctx.entries;
58
+ // One gate per service, shared with the idle-only delete (session-calls.mjs).
59
+ const turnGate = ctx.turnGate ?? createSessionTurnGate();
57
60
 
58
61
  /** Publishes the step an action produced and keeps the entry on the retention clock. */
59
62
  const settleAction = (entry, reason) => {
@@ -66,16 +69,26 @@ export function createSessionTurnCalls(ctx) {
66
69
  // attachment conversion that has not yet become a turn.
67
70
  const intakeAborts = new Map();
68
71
 
69
- async function submitSession({
70
- sessionId,
71
- prompt,
72
- options = {},
73
- open: openHints = {},
74
- baseRevision = null,
75
- signal = null,
76
- } = {}) {
77
- const id = String(sessionId || '');
72
+ /** Run `start` as an admitted turn start of `sessionId` (turn-gate.mjs). */
73
+ async function admitted(sessionId, start) {
74
+ const leave = turnGate.enter(sessionId);
75
+ try {
76
+ return await start();
77
+ } finally {
78
+ leave();
79
+ }
80
+ }
81
+
82
+ async function submitSession(params = {}) {
83
+ const id = String(params?.sessionId || '');
78
84
  if (!id) throw new TypeError('sessionId is required');
85
+ return admitted(id, () => submitAdmitted(id, params));
86
+ }
87
+
88
+ async function submitAdmitted(
89
+ id,
90
+ { prompt, options = {}, open: openHints = {}, baseRevision = null, signal = null } = {}
91
+ ) {
79
92
  const entry = await entryForSession(id, openHints || {});
80
93
  const target = entry.runtime.submitAsync;
81
94
  if (typeof target !== 'function') throw new TypeError('session runtime must implement submitAsync');
@@ -150,9 +163,12 @@ export function createSessionTurnCalls(ctx) {
150
163
  async function materializeSession(sessionId, openHints = {}) {
151
164
  const id = String(sessionId || '');
152
165
  if (!id) throw new TypeError('sessionId is required');
153
- const entry = await entryForSession(id, openHints || {});
154
- retainUnwatched(entry, 'daemon session owner');
155
- return entry.runtime;
166
+ // Its callers start work on the runtime (Goal and quota resumes, bots).
167
+ return admitted(id, async () => {
168
+ const entry = await entryForSession(id, openHints || {});
169
+ retainUnwatched(entry, 'daemon session owner');
170
+ return entry.runtime;
171
+ });
156
172
  }
157
173
 
158
174
  const recoverActiveGoals = createGoalRecovery({
@@ -196,12 +212,15 @@ export function createSessionTurnCalls(ctx) {
196
212
  async function approveSession({ sessionId, approvalId, decision, open: openHints = {}, baseRevision = null } = {}) {
197
213
  const id = String(sessionId || '');
198
214
  if (!id) throw new TypeError('sessionId is required');
199
- const entry = await entryForSession(id, openHints || {});
200
- const target = entry.runtime.resolveToolApproval;
201
- if (typeof target !== 'function') {
202
- throw new TypeError('session action resolveToolApproval is unavailable');
203
- }
204
- const approved = await target.call(entry.runtime, approvalId, decision);
215
+ // An answer resumes the turn: an admitted start.
216
+ const { entry, approved } = await admitted(id, async () => {
217
+ const hosted = await entryForSession(id, openHints || {});
218
+ const target = hosted.runtime.resolveToolApproval;
219
+ if (typeof target !== 'function') {
220
+ throw new TypeError('session action resolveToolApproval is unavailable');
221
+ }
222
+ return { entry: hosted, approved: await target.call(hosted.runtime, approvalId, decision) };
223
+ });
205
224
  const step = settleAction(entry, 'headless session approval');
206
225
  return sessionResult(entry, step, baseRevision, { approved: approved === true });
207
226
  }
@@ -6,60 +6,26 @@ import { SESSION_READ_ACTION_SET } from '../../session-protocol.mjs';
6
6
  import { SESSION_ID_PATTERN } from '../agent-tree.mjs';
7
7
  import {
8
8
  loadLiveTranscriptHead,
9
+ readTranscriptHistory,
9
10
  readTranscriptRange,
10
11
  rebudgetTranscriptWindow,
12
+ requestedTranscriptHistory,
11
13
  requestedHeldTranscript,
12
14
  requestedTranscriptWindow,
13
15
  requestLiveTranscriptWindow,
16
+ restartTranscriptWindow,
17
+ transcriptAnswerBounds,
14
18
  transcriptPageBody,
19
+ transcriptWindowOversized,
15
20
  } from '../projection/transcript-window.mjs';
16
21
 
17
- export function createSessionViewCalls(ctx) {
18
- const { log, readStoredSession, externalViewEntries, runSessionAction, sessionResult, advanceForCaller } = ctx;
19
- const { currentSessionId, externalEntryForView, projectionResult, unchangedProjectionResult, sessionOwner } =
20
- ctx.projection;
21
- /** The owner a concurrent materialization may have produced while a disk
22
- * read was in flight: a daemon-owned runtime outranks an external view. */
23
- const lateOwnerFor = (id) => sessionOwner(id) || externalEntryForView(id);
24
- const {
25
- subscriberToken,
26
- addSubscriber,
27
- trackPendingViewer,
28
- dropPendingViewer,
29
- adoptPendingViewers,
30
- notePrependViewer,
31
- } = ctx.viewers;
32
- const { sessionBusy, retainUnwatched, releaseProjection, startEvictionSweep } = ctx.retention;
33
- const {
34
- assertAvailable,
35
- createEntry,
36
- getOrCreateSessionEntry,
37
- entryForSession,
38
- liveEntryForView,
39
- bindExternalSessionView,
40
- destroy,
41
- } = ctx.entries;
42
- const {
43
- storedSessionProjection,
44
- storedProjectionUnchanged,
45
- requestedMessageSlice,
46
- forgetStoredSession,
47
- releaseStoredSession,
48
- } = ctx.storedReader;
49
-
50
- /** A read/subscribe names the transcript window its view wants (none: the
51
- * whole transcript). A window grown past what a resumed runtime holds is
52
- * completed from durable history, which a live session never keeps cached. */
53
- async function applyTranscriptRequest(entry, params, sessionId) {
54
- const request = requestedTranscriptWindow(params);
55
- // A model-message read (messageStart) is not a view and leaves the window.
56
- if (request || !Number.isInteger(params.messageStart)) requestLiveTranscriptWindow(entry, request);
57
- // No baseline the next step can patch: this caller receives the window
58
- // whole, so it goes out within its byte budget.
59
- if (request && params.baseRevision !== entry.revision) rebudgetTranscriptWindow(entry);
60
- if (await loadLiveTranscriptHead(entry, sessionId, readStoredSession)) forgetStoredSession(sessionId);
61
- assertAvailable(entry);
62
- }
22
+ /** Creating (reserving) a session. */
23
+ function createSessionCreation(ctx) {
24
+ const { log, sessionResult, advanceForCaller } = ctx;
25
+ const { currentSessionId } = ctx.projection;
26
+ const { addSubscriber, adoptPendingViewers } = ctx.viewers;
27
+ const { retainUnwatched } = ctx.retention;
28
+ const { assertAvailable, createEntry, getOrCreateSessionEntry, destroy } = ctx.entries;
63
29
 
64
30
  async function createReservedSession(params, viewer, reservedSessionId) {
65
31
  const entry = await createEntry({ ...params, sessionId: reservedSessionId }, viewer);
@@ -103,6 +69,138 @@ export function createSessionViewCalls(ctx) {
103
69
  return sessionResult(entry, step);
104
70
  }
105
71
 
72
+ return { createSession };
73
+ }
74
+
75
+ /** The transcript window a live view is answered through: requesting it,
76
+ * bounding the answer, and attaching a subscriber to a live entry. */
77
+ function createLiveTranscriptAnswers(ctx) {
78
+ const { readStoredSession, sessionResult, advanceForCaller } = ctx;
79
+ const { currentSessionId } = ctx.projection;
80
+ const { addSubscriber } = ctx.viewers;
81
+ const { assertAvailable } = ctx.entries;
82
+
83
+ /** A read/subscribe names the transcript window its view wants (none: the
84
+ * whole transcript). A window grown past what a resumed runtime holds is
85
+ * completed from durable history, sliced from the store's cached display
86
+ * history of the record's content. */
87
+ async function applyTranscriptRequest(entry, params, sessionId) {
88
+ const request = requestedTranscriptWindow(params);
89
+ // A model-message read (messageStart) is not a view and leaves the window.
90
+ if (request || !Number.isInteger(params.messageStart)) requestLiveTranscriptWindow(entry, request);
91
+ // No baseline the next step can patch: this caller receives the window
92
+ // whole, so it goes out within its byte budget.
93
+ if (request && params.baseRevision !== entry.revision) rebudgetTranscriptWindow(entry);
94
+ await loadLiveTranscriptHead(entry, sessionId, readStoredSession);
95
+ assertAvailable(entry);
96
+ }
97
+
98
+ /** The caller's answer for `step`, reduced to a page when it proves the rows
99
+ * it holds and they fit one answer. A window that would go out whole past
100
+ * the request's bounds (transcriptAnswerBounds) does not: a caller already
101
+ * at this revision needs no body; any other gets a bounded recovery
102
+ * snapshot — the window restarts from a fresh tail, which the views
103
+ * attached receive as a step too. */
104
+ function boundedSessionResult(entry, step, params, baseRevision, extra) {
105
+ const prepend = params.transcriptPrepend === true;
106
+ const bounds = transcriptAnswerBounds(requestedTranscriptWindow(params));
107
+ const result = transcriptPageBody(
108
+ sessionResult(entry, step, baseRevision, extra, { prepend }),
109
+ requestedHeldTranscript(params),
110
+ { byteBudget: bounds.byteBudget }
111
+ );
112
+ if (!transcriptWindowOversized(entry, result.full, bounds)) return result;
113
+ if (baseRevision === step.revision) {
114
+ const { full: _full, ...bodiless } = result;
115
+ return bodiless;
116
+ }
117
+ restartTranscriptWindow(entry, bounds.maxItems);
118
+ return sessionResult(entry, advanceForCaller(entry), baseRevision, extra, { prepend });
119
+ }
120
+
121
+ /** Publish BEFORE attaching: the views already there get the frame, the new
122
+ * one gets the same revision once in its reply. */
123
+ const subscribeLive = async (entry, params, viewer, baseRevision) => {
124
+ await applyTranscriptRequest(entry, params, currentSessionId(entry) || String(params.sessionId || ''));
125
+ const prepend = params.transcriptPrepend === true;
126
+ let step = advanceForCaller(entry);
127
+ // Bounded like a read (boundedSessionResult), before attaching: the new
128
+ // view receives the restarted tail once, in its reply.
129
+ const bounds = transcriptAnswerBounds(requestedTranscriptWindow(params));
130
+ if (transcriptWindowOversized(entry, sessionResult(entry, step, baseRevision, {}, { prepend }).full, bounds)) {
131
+ restartTranscriptWindow(entry, bounds.maxItems);
132
+ step = advanceForCaller(entry);
133
+ }
134
+ addSubscriber(entry, viewer);
135
+ return sessionResult(entry, step, baseRevision, { subscribed: true }, { prepend });
136
+ };
137
+
138
+ return { applyTranscriptRequest, boundedSessionResult, subscribeLive };
139
+ }
140
+
141
+ /** Detaching a view from a live or cold session. */
142
+ function createSessionUnsubscribe(ctx) {
143
+ const { log, externalViewEntries } = ctx;
144
+ const { externalEntryForView, sessionOwner } = ctx.projection;
145
+ const { subscriberToken, dropPendingViewer } = ctx.viewers;
146
+ const { sessionBusy, releaseProjection, startEvictionSweep } = ctx.retention;
147
+ const { destroy } = ctx.entries;
148
+ const { releaseStoredSession } = ctx.storedReader;
149
+
150
+ async function unsubscribeSession({ sessionId } = {}, viewer = null) {
151
+ const id = String(sessionId || '');
152
+ if (!id) throw new TypeError('sessionId is required');
153
+ const coldViewers = dropPendingViewer(id, viewer);
154
+ const owner = sessionOwner(id);
155
+ if (!owner) {
156
+ const external = externalEntryForView(id);
157
+ if (external) {
158
+ const token = subscriberToken(viewer);
159
+ if (token) external.subscribers?.delete(token);
160
+ if ((external.subscribers?.size || 0) === 0) externalViewEntries.delete(id);
161
+ }
162
+ // The last cold view left: its disk projection turns idle, kept within
163
+ // the store's idle budget so a revisit skips the parse.
164
+ if (!coldViewers) releaseStoredSession(id);
165
+ return { sessionId: id, unsubscribed: true };
166
+ }
167
+ const entry = owner;
168
+ const token = subscriberToken(viewer);
169
+ if (token) entry.subscribers?.delete(token);
170
+ if ((entry.subscribers?.size || 0) === 0) {
171
+ entry.transcriptView = null;
172
+ if (entry.reservedOnly && !sessionBusy(entry)) {
173
+ await destroy(entry, 'unclaimed session reservation', {
174
+ keepBackgroundWork: true,
175
+ });
176
+ return { sessionId: id, unsubscribed: true };
177
+ }
178
+ entry.retainedAt = Date.now();
179
+ releaseProjection(entry);
180
+ startEvictionSweep();
181
+ }
182
+ log(`session unsubscribed session=${id}${token ? ` client=${token}` : ''}`);
183
+ return { sessionId: id, unsubscribed: true };
184
+ }
185
+
186
+ return { unsubscribeSession };
187
+ }
188
+
189
+ export function createSessionViewCalls(ctx) {
190
+ const { readStoredSession, runSessionAction, advanceForCaller } = ctx;
191
+ const { externalEntryForView, projectionResult, unchangedProjectionResult, sessionOwner } = ctx.projection;
192
+ /** The owner a concurrent materialization may have produced while a disk
193
+ * read was in flight: a daemon-owned runtime outranks an external view. */
194
+ const lateOwnerFor = (id) => sessionOwner(id) || externalEntryForView(id);
195
+ const { trackPendingViewer, dropPendingViewer, notePrependViewer } = ctx.viewers;
196
+ const { retainUnwatched } = ctx.retention;
197
+ const { assertAvailable, entryForSession, liveEntryForView, bindExternalSessionView } = ctx.entries;
198
+ const { storedSessionProjection, storedProjectionUnchanged, storedPageOnly, requestedMessageSlice } =
199
+ ctx.storedReader;
200
+ const { createSession } = createSessionCreation(ctx);
201
+ const { applyTranscriptRequest, boundedSessionResult, subscribeLive } = createLiveTranscriptAnswers(ctx);
202
+ const { unsubscribeSession } = createSessionUnsubscribe(ctx);
203
+
106
204
  async function liveSessionReadResult(entry, params, sessionId, baseRevision) {
107
205
  assertAvailable(entry);
108
206
  await applyTranscriptRequest(entry, params, sessionId);
@@ -110,11 +208,7 @@ export function createSessionViewCalls(ctx) {
110
208
  retainUnwatched(entry, 'headless session read');
111
209
  const messages = await requestedMessageSlice(params, sessionId);
112
210
  assertAvailable(entry);
113
- const prepend = params.transcriptPrepend === true;
114
- return transcriptPageBody(
115
- sessionResult(entry, step, baseRevision, messages, { prepend }),
116
- requestedHeldTranscript(params)
117
- );
211
+ return boundedSessionResult(entry, step, params, baseRevision, messages);
118
212
  }
119
213
 
120
214
  /** The live entry a view can attach to: the owner, an external view, or a
@@ -146,6 +240,13 @@ export function createSessionViewCalls(ctx) {
146
240
  assertAvailable(live);
147
241
  return { range };
148
242
  }
243
+ const historyRequest = requestedTranscriptHistory(params);
244
+ if (historyRequest) {
245
+ // Read-only: no window, baseline or revision of any view moves.
246
+ const history = await readTranscriptHistory(live, id, readStoredSession, historyRequest);
247
+ assertAvailable(live);
248
+ return { history };
249
+ }
149
250
  if (live) {
150
251
  return liveSessionReadResult(live, params, id, baseRevision);
151
252
  }
@@ -162,7 +263,8 @@ export function createSessionViewCalls(ctx) {
162
263
  const lateOwner = lateOwnerFor(id);
163
264
  return lateOwner ? liveSessionReadResult(lateOwner, params, id, baseRevision) : held;
164
265
  }
165
- const projection = await storedSessionProjection(id, openHints, window);
266
+ const heldRows = requestedHeldTranscript(params);
267
+ const projection = await storedSessionProjection(id, openHints, window, heldRows, baseProjectionStamp);
166
268
  assertAvailable();
167
269
  const lateOwner = lateOwnerFor(id);
168
270
  if (lateOwner) {
@@ -179,28 +281,18 @@ export function createSessionViewCalls(ctx) {
179
281
  });
180
282
  const messages = await requestedMessageSlice(params, id);
181
283
  assertAvailable();
182
- return { ...transcriptPageBody(result, requestedHeldTranscript(params)), ...messages };
284
+ // The stored reader already proved (or disproved) the held rows, and
285
+ // its projection then carries only the page above them.
286
+ const page = storedPageOnly(projection)
287
+ ? transcriptPageBody(result, heldRows, { proven: true, byteBudget: window?.byteBudget, pageOnly: true })
288
+ : result;
289
+ return { ...page, ...messages };
183
290
  }
184
291
  // Embedders without a store reader keep the legacy load-on-read seam.
185
292
  const entry = await entryForSession(id, openHints || {});
186
293
  return liveSessionReadResult(entry, params, id, baseRevision);
187
294
  }
188
295
 
189
- /** Publish BEFORE attaching: the views already there get the frame, the new
190
- * one gets the same revision once in its reply. */
191
- const subscribeLive = async (entry, params, viewer, baseRevision) => {
192
- await applyTranscriptRequest(entry, params, currentSessionId(entry) || String(params.sessionId || ''));
193
- const step = advanceForCaller(entry);
194
- addSubscriber(entry, viewer);
195
- return sessionResult(
196
- entry,
197
- step,
198
- baseRevision,
199
- { subscribed: true },
200
- { prepend: params.transcriptPrepend === true }
201
- );
202
- };
203
-
204
296
  async function subscribeSession(params = {}, viewer = null) {
205
297
  const { sessionId, open: openHints = {}, baseRevision = null } = params;
206
298
  assertAvailable();
@@ -236,41 +328,5 @@ export function createSessionViewCalls(ctx) {
236
328
  return subscribeLive(entry, params, viewer, baseRevision);
237
329
  }
238
330
 
239
- async function unsubscribeSession({ sessionId } = {}, viewer = null) {
240
- const id = String(sessionId || '');
241
- if (!id) throw new TypeError('sessionId is required');
242
- const coldViewers = dropPendingViewer(id, viewer);
243
- const owner = sessionOwner(id);
244
- if (!owner) {
245
- const external = externalEntryForView(id);
246
- if (external) {
247
- const token = subscriberToken(viewer);
248
- if (token) external.subscribers?.delete(token);
249
- if ((external.subscribers?.size || 0) === 0) externalViewEntries.delete(id);
250
- }
251
- // The last cold view left: its disk projection turns idle, kept within
252
- // the store's idle budget so a revisit skips the parse.
253
- if (!coldViewers) releaseStoredSession(id);
254
- return { sessionId: id, unsubscribed: true };
255
- }
256
- const entry = owner;
257
- const token = subscriberToken(viewer);
258
- if (token) entry.subscribers?.delete(token);
259
- if ((entry.subscribers?.size || 0) === 0) {
260
- entry.transcriptView = null;
261
- if (entry.reservedOnly && !sessionBusy(entry)) {
262
- await destroy(entry, 'unclaimed session reservation', {
263
- keepBackgroundWork: true,
264
- });
265
- return { sessionId: id, unsubscribed: true };
266
- }
267
- entry.retainedAt = Date.now();
268
- releaseProjection(entry);
269
- startEvictionSweep();
270
- }
271
- log(`session unsubscribed session=${id}${token ? ` client=${token}` : ''}`);
272
- return { sessionId: id, unsubscribed: true };
273
- }
274
-
275
331
  return { createSession, readSession, subscribeSession, unsubscribeSession };
276
332
  }
@@ -0,0 +1,34 @@
1
+ // session-calls/turn-gate.mjs
2
+ // The service's turn starts per session (a submit's intake, an approval that
3
+ // resumes a turn, a materialization for a Goal or quota resume) against the
4
+ // desktop's idle-only delete: the delete closes a session to new starts only
5
+ // while none is being admitted, and a start refuses while it is closed.
6
+ import { SessionClosedError } from '../../../runtime/agent/orchestrator/session/manager/session-errors.mjs';
7
+
8
+ export function createSessionTurnGate() {
9
+ const starting = new Map(); // sessionId -> admissions in flight
10
+ const fenced = new Set();
11
+ return {
12
+ /** Admit a turn start of `sessionId`; the returned release ends it. */
13
+ enter(sessionId) {
14
+ if (fenced.has(sessionId)) {
15
+ throw new SessionClosedError(sessionId, 'session is being deleted', 'auto-retention-delete');
16
+ }
17
+ starting.set(sessionId, (starting.get(sessionId) || 0) + 1);
18
+ let left = false;
19
+ return () => {
20
+ if (left) return;
21
+ left = true;
22
+ const count = (starting.get(sessionId) || 1) - 1;
23
+ if (count > 0) starting.set(sessionId, count);
24
+ else starting.delete(sessionId);
25
+ };
26
+ },
27
+ /** Close `sessionId` to turn starts; null while one is being admitted. */
28
+ fence(sessionId) {
29
+ if (starting.has(sessionId) || fenced.has(sessionId)) return null;
30
+ fenced.add(sessionId);
31
+ return () => fenced.delete(sessionId);
32
+ },
33
+ };
34
+ }
@@ -14,6 +14,7 @@
14
14
  import { createSessionActionCalls } from './session-calls/session-action.mjs';
15
15
  import { createSessionTurnCalls } from './session-calls/session-turns.mjs';
16
16
  import { createSessionViewCalls } from './session-calls/session-views.mjs';
17
+ import { createSessionTurnGate } from './session-calls/turn-gate.mjs';
17
18
 
18
19
  /**
19
20
  * @param {object} deps
@@ -54,7 +55,7 @@ export function createSessionCalls(deps) {
54
55
  return step;
55
56
  }
56
57
 
57
- const ctx = { ...deps, sessionResult, responseSessionId, advanceForCaller };
58
+ const ctx = { ...deps, sessionResult, responseSessionId, advanceForCaller, turnGate: createSessionTurnGate() };
58
59
  const actions = createSessionActionCalls(ctx);
59
60
  const views = createSessionViewCalls({ ...ctx, runSessionAction: actions.runSessionAction });
60
61
  const turns = createSessionTurnCalls(ctx);