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
@@ -33,7 +33,7 @@ const MD_SYNTAX_RE = /[#*`|[>\-_~]|\n\n|(?:^|\n)\d+[.)] |(?:^|\n)\+ |(?:^|\n)={2
33
33
 
34
34
  // GFM strikethrough, pair-only. marked's default `del` also accepts a SINGLE
35
35
  // tilde, which turns approximation prose ("~100", "1~2개") into struck text —
36
- // the reason this tokenizer used to be disabled outright. Requiring `~~` keeps
36
+ // so the default tokenizer cannot be used as is. Requiring `~~` keeps
37
37
  // real strikethrough working and lockstep with the desktop pipeline
38
38
  // (remark-gfm singleTilde:false).
39
39
  const DEL_RE = /^~~(?=[^\s~])([\s\S]*?[^\s~])~~(?!~)/;
@@ -2,6 +2,10 @@ import { parseAgentJob } from '../agent-envelope.mjs';
2
2
  import { notificationQueueKey, resolveTuiRuntimeNotificationDelivery } from '../notification-plan.mjs';
3
3
  import { isTerminalExecutionStatus } from './agent-status-refresh.mjs';
4
4
 
5
+ // The runtime's setup-changed action after an empty session's settings
6
+ // reconcile (session-runtime/boot/tools.mjs CONTEXT_STATUS_REFRESHED_ACTION).
7
+ const CONTEXT_STATUS_REFRESHED = 'context_status_refreshed';
8
+
5
9
  // Routes one runtime notification by its delivery plan: UI-only kinds patch
6
10
  // the store or raise a notice, execution envelopes go through the execution
7
11
  // delivery, everything else becomes a model-visible task notification.
@@ -13,6 +17,7 @@ export function createNotificationRouter({
13
17
  statusRefresh,
14
18
  executionDelivery,
15
19
  modelNotification,
20
+ refreshContextStats = null,
16
21
  getAdmission = () => 'open',
17
22
  }) {
18
23
  let uiOpenSeq = 0;
@@ -20,6 +25,11 @@ export function createNotificationRouter({
20
25
  const uiActions = {
21
26
  'setup-ui': (delivery) => set({ setupUiRequest: { id: delivery.id, at: Date.now() } }),
22
27
  'setup-changed': (delivery) => {
28
+ // An empty session took moved settings: the context gauge re-reads.
29
+ if (delivery.setupAction === CONTEXT_STATUS_REFRESHED) {
30
+ refreshContextStats?.();
31
+ return;
32
+ }
23
33
  // Monotonic like ui-open: consecutive changes by the same action must
24
34
  // each refresh the attached surfaces.
25
35
  setupChangeSeq += 1;
@@ -37,6 +37,7 @@ export function createAgentJobFeed({
37
37
  displayedExecutionNotificationKeys,
38
38
  itemIndexById,
39
39
  pushNotice,
40
+ refreshContextStats = null,
40
41
  now = () => Date.now(),
41
42
  executionResumeTombstoneTtlMs = 30_000,
42
43
  executionResumeTombstoneLimit = 128,
@@ -79,6 +80,7 @@ export function createAgentJobFeed({
79
80
  statusRefresh,
80
81
  executionDelivery,
81
82
  modelNotification,
83
+ refreshContextStats,
82
84
  getAdmission,
83
85
  });
84
86
 
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import { contextMeasurementStats } from '../../runtime/shared/context-measurement.mjs';
9
9
  import { goalStateSnapshot } from '../../runtime/agent/orchestrator/runtime-core/goal-state.mjs';
10
+ import { todoSnapshot } from '../../runtime/agent/orchestrator/runtime-core/todo-list.mjs';
10
11
 
11
12
  export function createContextState({
12
13
  runtime,
@@ -92,6 +93,8 @@ export function createContextState({
92
93
  // The daemon-queued quota resume of this session id (identity-stable while
93
94
  // unchanged), so a resume or session switch republishes it with the route.
94
95
  quotaResume: typeof getQuotaResume === 'function' ? getQuotaResume() : null,
96
+ // The session's own step list (identity-stable while unchanged); null when empty.
97
+ todo: todoSnapshot(runtime.session),
95
98
  });
96
99
 
97
100
  const routeState = () => {
@@ -1,11 +1,15 @@
1
1
  // A steering handoff cancels a turn, not its durable Goal. Record the explicit
2
2
  // abort path against its turn epoch instead of guessing intent from error text.
3
- export function abortGoalTurn(runtime, flags, hasPendingSteering, reason = 'user-cancel') {
3
+ export function abortGoalTurn(runtime, flags, hasPendingSteering, reason = 'user-cancel', { timeout = false } = {}) {
4
4
  const previous = flags.goalSteeringAbortEpoch;
5
5
  const epoch = flags.leadTurnEpoch;
6
6
  flags.goalSteeringAbortEpoch = hasPendingSteering ? epoch : null;
7
7
  try {
8
- const result = runtime.abort(hasPendingSteering ? 'interrupt' : reason);
8
+ // A steering interrupt outranks a timeout: the turn was redirected, not abandoned.
9
+ const result =
10
+ timeout && !hasPendingSteering
11
+ ? runtime.abort(reason, { timeout: true })
12
+ : runtime.abort(hasPendingSteering ? 'interrupt' : reason);
9
13
  if (result === false) flags.goalSteeringAbortEpoch = previous;
10
14
  return result;
11
15
  } catch (error) {
@@ -57,7 +57,7 @@ export function latestQuotaFailure(items) {
57
57
 
58
58
  /** The turn key of the failed turndone that ends the transcript, when no
59
59
  * later turn has begun; '' otherwise. */
60
- export function latestFailedTurnKey(items) {
60
+ function latestFailedTurnKey(items) {
61
61
  const transcript = Array.isArray(items) ? items : [];
62
62
  for (let index = transcript.length - 1; index >= 0; index -= 1) {
63
63
  const item = transcript[index];
@@ -67,6 +67,10 @@ export function createSessionControlsApi(bag) {
67
67
  stopShellJob: async (taskId) => {
68
68
  return (await runtime.stopShellJob?.(taskId)) ?? { stopped: false, error: 'shell job control is unavailable' };
69
69
  },
70
+ // `/stop`: this session's background shells, and stopping all of them:
71
+ // { jobs } and { stopped, stopping }.
72
+ listStoppableShellJobs: async () => (await runtime.listStoppableShellJobs?.()) ?? { jobs: [] },
73
+ stopShellJobs: async () => (await runtime.stopShellJobs?.()) ?? { stopped: 0, stopping: 0 },
70
74
  // Explicit force-release of a shell whose termination is unconfirmed:
71
75
  // { released, error? }. Surfaces confirm with the user before calling.
72
76
  releaseShellJob: async (taskId) => {
@@ -54,6 +54,14 @@ export function createSessionExtensionsApi(bag) {
54
54
  (input) => runtime.addMcpServer?.(input),
55
55
  (result, input) => [`mcp added: ${result?.name || input?.name || 'server'}`]
56
56
  ),
57
+ // No command lock: the runtime serializes adds per connector
58
+ // (oneAddAtATime), so concurrent adds each succeed with their own key.
59
+ addConnectorAccount: async (input) => {
60
+ const result = await runtime.addConnectorAccount?.(input);
61
+ refreshRouteStats();
62
+ pushNotice(`mcp account added: ${result?.account || input?.connector || 'connector'}`);
63
+ return result;
64
+ },
57
65
  saveMcpServer: lockedChange(
58
66
  (input) => runtime.saveMcpServer?.(input),
59
67
  (result, input) => [`mcp saved: ${result?.name || input?.name || 'server'}`]
@@ -172,7 +172,8 @@ export function createAbortAction(bag) {
172
172
  runtime,
173
173
  flags,
174
174
  hasPendingSteering,
175
- keepsPrompt ? USER_CANCEL_KEEP_PROMPT_REASON : reason
175
+ keepsPrompt ? USER_CANCEL_KEEP_PROMPT_REASON : reason,
176
+ { timeout: options?.timeout === true }
176
177
  );
177
178
  if (restoreState) {
178
179
  // A user Stop consumes this input even when no draft is requested.
@@ -20,6 +20,7 @@ export function createSessionIntakeApi(bag) {
20
20
  patchItem,
21
21
  restoreOlderTranscript,
22
22
  restoreNewerTranscript,
23
+ readSpilledTranscript,
23
24
  routeState,
24
25
  restoreQueued,
25
26
  prioritizeQueued,
@@ -32,6 +33,7 @@ export function createSessionIntakeApi(bag) {
32
33
  patchItem,
33
34
  restoreOlderTranscript,
34
35
  restoreNewerTranscript,
36
+ ...(typeof readSpilledTranscript === 'function' ? { readSpilledTranscript } : {}),
35
37
  subscribe: (listener) => {
36
38
  listeners.add(listener);
37
39
  return () => listeners.delete(listener);
@@ -129,8 +129,8 @@ export function createSessionIntegrationsApi(bag, { oauthFlows }) {
129
129
  getOAuthProviderLoginStatus: (flowId) => oauthFlows.status(flowId),
130
130
  completeOAuthProviderLogin: async (flowId, code) => oauthFlows.complete(flowId, code),
131
131
  cancelOAuthProviderLogin: async (flowId) => oauthFlows.cancel(flowId),
132
- saveProviderApiKey: async (provider, secret) => {
133
- const result = await runtime.saveProviderApiKey(provider, secret);
132
+ saveProviderApiKey: async (provider, secret, options) => {
133
+ const result = await runtime.saveProviderApiKey(provider, secret, options);
134
134
  pushNotice(`provider api key saved: ${result.provider}`, 'info');
135
135
  return true;
136
136
  },
@@ -34,6 +34,7 @@ export function createDisposeAction(bag, { oauthFlows }) {
34
34
  'unsubscribeCompletionWakeGate',
35
35
  'unsubscribeGitHeadWatch',
36
36
  'unsubscribeWorktreeSetup',
37
+ 'unsubscribeTodo',
37
38
  ]) {
38
39
  try {
39
40
  lifecycle[key]?.();
@@ -122,6 +122,13 @@ export function createSessionResetActions(bag) {
122
122
  throw error;
123
123
  }
124
124
  }),
125
+ // The desktop's auto-delete (session-delete.mjs deleteSessionIfIdle): never
126
+ // the current session, so no reset of this one's view.
127
+ deleteSessionIfIdle: async (id, expected, guards) => {
128
+ const result = await runtime.deleteSessionIfIdle(id, expected, guards);
129
+ if (result?.deleted === true) bag.supersedeQuotaResume?.(id);
130
+ return result;
131
+ },
125
132
  switchContext: (options) =>
126
133
  withResetLock(async () => {
127
134
  const rollbackSnapshot = beginTuiReset();
@@ -27,6 +27,11 @@ export function createAgentDefinitionApi(runtime) {
27
27
  createWorkflow: async (payload) => runtime.createWorkflow?.(payload) ?? null,
28
28
  deleteWorkflow: async (workflowId) => runtime.deleteWorkflow?.(workflowId) ?? null,
29
29
  getAgentDefinition: (agentId) => runtime.getAgentDefinition?.(agentId) ?? null,
30
+ listInstructionFiles: () => runtime.listInstructionFiles?.() ?? [],
31
+ getInstructionFile: (group, id) => runtime.getInstructionFile?.(group, id) ?? null,
32
+ saveInstructionFile: async (payload) => runtime.saveInstructionFile?.(payload) ?? null,
33
+ resetInstructionFile: async (group, id, expectedRevision) =>
34
+ runtime.resetInstructionFile?.(group, id, expectedRevision) ?? null,
30
35
  getAgentAvatarImage: (agentId) => runtime.getAgentAvatarImage?.(agentId) ?? null,
31
36
  getAgentConnectors: (agentId) => runtime.getAgentConnectors?.(agentId) ?? [],
32
37
  listConnectors: () => runtime.listConnectors?.() ?? [],
@@ -43,6 +48,7 @@ export function createAgentDefinitionApi(runtime) {
43
48
  setAgentConnectorToolPermission: async (agentId, connectorId, toolName, permission, options) =>
44
49
  runtime.setAgentConnectorToolPermission?.(agentId, connectorId, toolName, permission, options) ?? null,
45
50
  getAgentAlwaysAllowedTools: (agentId) => runtime.getAgentAlwaysAllowedTools?.(agentId) ?? [],
51
+ getAgentConnectorTools: (agentId) => runtime.getAgentConnectorTools?.(agentId) ?? [],
46
52
  // Per-agent action-kind permissions (ask / allow / block) for the profile.
47
53
  getAgentPermissions: async (agentId) =>
48
54
  (await import('../../../runtime/agent/orchestrator/session/human-gate/store.mjs')).agentPermissions(agentId),
@@ -113,13 +113,13 @@ export function createSessionSettingsApi(bag) {
113
113
  return await runtime.setAiSessionTitles?.(enabled);
114
114
  }),
115
115
  getCacheWarmingSettings: () => {
116
- return runtime.getCacheWarmingSettings?.() || { enabled: true };
116
+ return runtime.getCacheWarmingSettings?.() || { enabled: false };
117
117
  },
118
118
  setCacheWarmingEnabled: withCommandLock(async (enabled) => {
119
119
  return await runtime.setCacheWarmingEnabled?.(enabled);
120
120
  }),
121
121
  getHeartbeatSettings: () => {
122
- return runtime.getHeartbeatSettings?.() || { heartbeat: true, intervalMinutes: 60 };
122
+ return runtime.getHeartbeatSettings?.() || { heartbeat: false, intervalMinutes: 60 };
123
123
  },
124
124
  setHeartbeatEnabled: withCommandLock(async (enabled) => {
125
125
  return await runtime.setHeartbeatEnabled?.(enabled);
@@ -23,7 +23,15 @@
23
23
  * (expectedRevision: WORKTREE_REVISION_CONFLICT when the session moved on)
24
24
  * (WORKTREE_REMOVAL_INCOMPLETE: partly removed; call again to finish)
25
25
  * listWorktrees() → every managed worktree with its retention
26
- * pruneWorktrees() → reconcile report (never a retained worktree) */
26
+ * pruneWorktrees() → reconcile report (with autoCleanup on, also the
27
+ * count/age limits and archive rules of the automatic cleanup)
28
+ * previewWorktreeCleanup({ repoCommonDir? }) → { hasCandidates } (whether pruneWorktrees could act on
29
+ * anything; read-only, no git verification)
30
+ * deleteWorktree({ entryId, force? }) → { removed, entryId, path } (Settings → Worktrees;
31
+ * refuses one in use, dirty or unmerged work unless `force`)
32
+ * getSessionWorktreeWork({ sessionIds }) → { sessionIds } owning a worktree removal would refuse
33
+ * setArchivedSessionWorktrees({ sessionIds, archived }) → { changed } (autoCleanup on: archived
34
+ * sessions' worktrees become disposable for the startup reconcile / prune; a restore unmarks) */
27
35
  import { worktreeError } from '../../../runtime/shared/worktrees/contract.mjs';
28
36
 
29
37
  /** Session actions of the Lead worktree feature (settings live in settings.mjs). */
@@ -40,6 +48,10 @@ export const SESSION_WORKTREE_ACTIONS = Object.freeze([
40
48
  'removeWorktree',
41
49
  'listWorktrees',
42
50
  'pruneWorktrees',
51
+ 'previewWorktreeCleanup',
52
+ 'deleteWorktree',
53
+ 'getSessionWorktreeWork',
54
+ 'setArchivedSessionWorktrees',
43
55
  ]);
44
56
 
45
57
  export function createSessionWorktreeApi({ runtime, set, routeState } = {}) {
@@ -29,16 +29,13 @@ function earliestSubmittedAt(batch) {
29
29
 
30
30
  function renderBatchItems(batch, pushUserOrSyntheticItem) {
31
31
  for (const entry of batch) {
32
- // Async-completion twins (queued model-visible wrapper) used to be
33
- // display-skipped here on the assumption the live notification push
34
- // already rendered a card. That push is event-ephemeral and can be
35
- // missed (listener race, dedupe state from another surface, daemon
36
- // restart), which left completions with NO transcript card at all
37
- // (2026-08-17 field report: bench shell output never appeared).
38
- // Render the wrapper through the synthetic path instead — the
39
- // task_id upsert in upsertSyntheticToolItem patches an
40
- // already-rendered card, so the double-delivery case stays
41
- // duplicate-free. Non-wrapper entries keep the old skip.
32
+ // Async-completion twins (queued model-visible wrapper) are rendered
33
+ // through the synthetic path rather than display-skipped: the live
34
+ // notification push is event-ephemeral and can be missed (listener race,
35
+ // dedupe state from another surface, daemon restart), which would leave
36
+ // the completion with NO transcript card at all. The task_id upsert in
37
+ // upsertSyntheticToolItem patches an already-rendered card, so the
38
+ // double-delivery case stays duplicate-free. Non-wrapper entries are skipped.
42
39
  if (entry.mode === 'pending-resume' || entry.suppressDisplay) {
43
40
  const twin = typeof entry.content === 'string' ? entry.content : String(entry.text || '');
44
41
  if (parseModelVisibleCompletionWrapper(twin)) {
@@ -145,10 +142,10 @@ export function turnOptionsForBatch(batch, steering) {
145
142
  Array.isArray(entry?.resumeCompletionKeys) ? entry.resumeCompletionKeys : []
146
143
  ),
147
144
  transcriptMeta: completionWakeTranscriptMeta(batch),
148
- // Only a routine turn names its selection text (never its payload).
149
- ...(batch[0]?.mode === 'routine' && typeof batch[0].skillSelection === 'string'
150
- ? { skillSelection: batch[0].skillSelection }
151
- : {}),
145
+ // Only host code names a selection text (queue/entry-shape.mjs): a
146
+ // routine turn, or a routine's executor sub-agent turn — its trusted
147
+ // instructions, never a payload.
148
+ ...(typeof batch[0]?.skillSelection === 'string' ? { skillSelection: batch[0].skillSelection } : {}),
152
149
  context:
153
150
  batch
154
151
  .map((entry) => String(entry.context || '').trim())
@@ -49,8 +49,8 @@ function applyAgentJobFields(ctx, patch, { itemId, group, text, rawText, isError
49
49
  const body = String(text || rawText || '').trim();
50
50
  if (body) patch.rawResult = text || rawText;
51
51
  if (parseAgentJob(rawText)) ctx.set(ctx.agentStatusState({ force: true }));
52
- // The two calls previously wrote the same card back-to-back with different
53
- // result/text strings, producing the visible L1/L2 flash. The agent fields
52
+ // Writing the same card back-to-back with different result/text strings
53
+ // produces a visible L1/L2 flash, so a single patch is written. The agent fields
54
54
  // win (final display) while patch keeps the completion metadata
55
55
  // (count/completedCount/completedAt/rawResult) for expand.
56
56
  Object.assign(patch, ctx.buildAgentJobCardPatch(itemId, rawText, isError));
@@ -10,6 +10,8 @@
10
10
  // Pages are self-contained files named by the owner, so a restart continues
11
11
  // the same spill directory with nothing to hand over.
12
12
  import { randomUUID } from 'node:crypto';
13
+ import { mkdirSync } from 'node:fs';
14
+ import { dirname } from 'node:path';
13
15
 
14
16
  const MAX_ATTEMPTS = 2;
15
17
  const SPILL_WRITER_IDLE_MS = 10_000;
@@ -67,6 +69,11 @@ export function createSpillWriter({ workerFactory, writeTimeoutMs = 5000, idleMs
67
69
  if (record.cancelled) return;
68
70
  record.attempts += 1;
69
71
  if (record.attempts <= MAX_ATTEMPTS) {
72
+ // The spill folder vanished (TEMP cleaned): the retry recreates it. Only
73
+ // the parent does this, synchronously right before it posts the retry
74
+ // and only for a live record, so a reset or cleanup (which cancels the
75
+ // record first) can never have its folder resurrected by a late write.
76
+ record.recreateDir = /ENOENT/.test(String(error));
70
77
  queue.unshift(record);
71
78
  return;
72
79
  }
@@ -159,6 +166,14 @@ export function createSpillWriter({ workerFactory, writeTimeoutMs = 5000, idleMs
159
166
  queueMicrotask(pump);
160
167
  return;
161
168
  }
169
+ if (active.recreateDir) {
170
+ active.recreateDir = false;
171
+ try {
172
+ mkdirSync(dirname(active.path), { recursive: true });
173
+ } catch {
174
+ /* the retry reports the failure */
175
+ }
176
+ }
162
177
  // Pages are capped at chunkSize, so the structured-clone post cost is
163
178
  // bounded; the retry payload is identical to the first attempt.
164
179
  const tempPath = `${active.path}.attempt-${active.attempts}-${randomUUID()}.tmp`;
@@ -20,6 +20,13 @@ export const tuiDebug = (msg) => {
20
20
  } catch {}
21
21
  };
22
22
 
23
+ /** Normal-level spill warning for the daemon: its stderr is daemon.log. */
24
+ export const spillWarningToStderr = (message) => {
25
+ try {
26
+ process.stderr.write(`[transcript-spill] ${message}\n`);
27
+ } catch {}
28
+ };
29
+
23
30
  // Item ids outlive the process (queued-input mirror, turn change records), so
24
31
  // a restarted process never issues an id again.
25
32
  const ID_PREFIX = `it_${randomBytes(4).toString('hex')}_`;
@@ -41,6 +48,48 @@ export function sweepStaleTranscriptSpillDirsOnce() {
41
48
  cleanupStaleTranscriptSpillDirs();
42
49
  }
43
50
 
51
+ const decodePage = (record) => record.pendingItems || JSON.parse(readFileSync(record.path, 'utf8'));
52
+
53
+ /** Spilled rows `[stop - limit, stop)` of `pages` (`spilledRows` rows in all),
54
+ * `stop` being `end` clamped to the spilled rows, read newest page first;
55
+ * `broken` when a page cannot be read whole. */
56
+ function readSpilledRows(pages, spilledRows, end, limit) {
57
+ const stop = Math.max(0, Math.min(Number(end) || 0, spilledRows));
58
+ const begin = Math.max(0, stop - Math.max(0, Number(limit) || 0));
59
+ const parts = [];
60
+ const result = (broken) => {
61
+ const items = parts.reverse().flat();
62
+ return { items, start: stop - items.length, broken };
63
+ };
64
+ // The page holding row `stop - 1`, by binary search over the pages' first
65
+ // rows: a read touches only the pages it returns rows from, at any depth.
66
+ let low = 0;
67
+ let high = pages.length - 1;
68
+ let last = -1;
69
+ while (low <= high) {
70
+ const middle = (low + high) >> 1;
71
+ if (pages[middle].start < stop) {
72
+ last = middle;
73
+ low = middle + 1;
74
+ } else high = middle - 1;
75
+ }
76
+ for (let index = last; index >= 0; index -= 1) {
77
+ const record = pages[index];
78
+ const pageStart = record.start;
79
+ const pageEnd = pageStart + record.count;
80
+ if (pageEnd <= begin) break;
81
+ let items = null;
82
+ try {
83
+ items = decodePage(record);
84
+ } catch {
85
+ items = null;
86
+ }
87
+ if (!Array.isArray(items) || items.length !== record.count) return result(true);
88
+ parts.push(items.slice(Math.max(begin, pageStart) - pageStart, Math.min(stop, pageEnd) - pageStart));
89
+ }
90
+ return result(false);
91
+ }
92
+
44
93
  // Serialized pages deliberately release the old item object graph while
45
94
  // keeping every byte restorable. Only `items` is render-live and walkable.
46
95
  // This buffer owns the page list, the reading cursor and snapshots; the spill
@@ -65,6 +114,21 @@ export function createTranscriptSpillBuffer({
65
114
  let cursor = null;
66
115
  let spillDir = null;
67
116
  let pageSequence = 0;
117
+ // Spilled rows in this page list, and its epoch: it moves whenever the list
118
+ // is replaced (reset, restored snapshot, dispose), so an absolute row index
119
+ // names one row only within an epoch. Cursor-independent.
120
+ let spilledRows = 0;
121
+ let epoch = 0;
122
+ let spilledInfo = { rows: 0, epoch: 0 };
123
+ // Each page's first absolute row (`start`) within the current page list.
124
+ const replaced = () => {
125
+ spilledRows = 0;
126
+ for (const record of pages) {
127
+ record.start = spilledRows;
128
+ spilledRows += record.count;
129
+ }
130
+ epoch += 1;
131
+ };
68
132
  let warningEmitted = false;
69
133
  let spillDisabled = false;
70
134
  const snapshots = new Set();
@@ -96,6 +160,7 @@ export function createTranscriptSpillBuffer({
96
160
  const record = {
97
161
  id: pageSequence,
98
162
  path: page,
163
+ count: items.length,
99
164
  pendingItems: items,
100
165
  cancelled: false,
101
166
  attempts: 0,
@@ -104,11 +169,10 @@ export function createTranscriptSpillBuffer({
104
169
  writer.enqueue(record);
105
170
  return record;
106
171
  };
107
- const decode = (record) => record.pendingItems || JSON.parse(readFileSync(record.path, 'utf8'));
108
172
  const restoredWithOverlap = (liveItems) => {
109
- const restored = decode(pages[cursor]);
173
+ const restored = decodePage(pages[cursor]);
110
174
  let following = Array.isArray(liveItems) ? liveItems : [];
111
- if (cursor + 1 < pages.length) following = decode(pages[cursor + 1]);
175
+ if (cursor + 1 < pages.length) following = decodePage(pages[cursor + 1]);
112
176
  return [...restored, ...following.slice(0, TRANSCRIPT_RESTORE_OVERLAP_ITEMS)];
113
177
  };
114
178
  return {
@@ -118,6 +182,14 @@ export function createTranscriptSpillBuffer({
118
182
  get hasNewer() {
119
183
  return cursor != null;
120
184
  },
185
+ /** `{ rows, epoch }`: how many rows were spilled above the live ones, in
186
+ * which page list. The same object while neither changes. */
187
+ get spilled() {
188
+ if (spilledInfo.rows !== spilledRows || spilledInfo.epoch !== epoch) {
189
+ spilledInfo = { rows: spilledRows, epoch };
190
+ }
191
+ return spilledInfo;
192
+ },
121
193
  reset() {
122
194
  const retained = [...snapshots].some((snapshot) => snapshot.spillDir === spillDir);
123
195
  const oldPages = pages.splice(0);
@@ -127,6 +199,7 @@ export function createTranscriptSpillBuffer({
127
199
  pageSequence = 0;
128
200
  spillDisabled = false;
129
201
  warningEmitted = false;
202
+ replaced();
130
203
  if (!retained) cleanupRecords(oldPages, oldDir);
131
204
  },
132
205
  snapshot() {
@@ -155,6 +228,7 @@ export function createTranscriptSpillBuffer({
155
228
  pageSequence = snapshot.pageSequence;
156
229
  spillDisabled = snapshot.spillDisabled === true;
157
230
  warningEmitted = snapshot.warningEmitted === true;
231
+ replaced();
158
232
  snapshots.delete(snapshot);
159
233
  return true;
160
234
  },
@@ -169,6 +243,7 @@ export function createTranscriptSpillBuffer({
169
243
  if (snapshot.spillDir !== spillDir) cleanupRecords(snapshot.pages, snapshot.spillDir);
170
244
  }
171
245
  pages.length = 0;
246
+ replaced();
172
247
  snapshots.clear();
173
248
  cursor = null;
174
249
  spillDir = null;
@@ -191,11 +266,24 @@ export function createTranscriptSpillBuffer({
191
266
  let live = Array.isArray(items) ? items : [];
192
267
  if (spillDisabled) return live;
193
268
  while (live.length > cap) {
194
- pages.push(encode(live.slice(0, chunkSize)));
269
+ const record = encode(live.slice(0, chunkSize));
270
+ record.start = spilledRows;
271
+ pages.push(record);
272
+ spilledRows += chunkSize;
195
273
  live = live.slice(chunkSize);
196
274
  }
197
275
  return live;
198
276
  },
277
+ /** Spilled rows `[start, end)` by absolute index (0 = the first row ever
278
+ * spilled in this `epoch`), at most `limit` ending at `end`, exactly as
279
+ * they were spilled. Reads pages in order without moving the reading
280
+ * cursor. Null for another epoch. A page that cannot be read whole (gone,
281
+ * not JSON, not an array of its recorded length) ends the spilled
282
+ * history there: `broken`, with only the rows below it. */
283
+ readSpilled({ epoch: wanted, end = spilledRows, limit = 0 } = {}) {
284
+ if (wanted !== epoch) return null;
285
+ return readSpilledRows(pages, spilledRows, end, limit);
286
+ },
199
287
  restoreOlder(liveItems) {
200
288
  const nextCursor = cursor == null ? pages.length - 1 : cursor - 1;
201
289
  if (nextCursor < 0) return null;
@@ -21,6 +21,8 @@ export function createTranscriptStore({ draft, store, flags, transcriptSpill, it
21
21
  const transcriptHistoryFlags = () => ({
22
22
  transcriptHistoryBefore: transcriptSpill.hasOlder,
23
23
  transcriptHistoryAfter: transcriptSpill.hasNewer,
24
+ // Paged views read spilled rows by this, never by the TUI reading cursor.
25
+ transcriptSpilled: transcriptSpill.spilled,
24
26
  });
25
27
  const restoreOlderTranscript = () => {
26
28
  const transcriptViewItems = transcriptSpill.restoreOlder(draft.state.items);
@@ -9,7 +9,7 @@ import { resolveAgentStallThresholds } from '../../runtime/agent/orchestrator/st
9
9
  const QUIET_POLL_MS = 1_000;
10
10
 
11
11
  /** The lead's stall-watchdog warn point, in ms. */
12
- export function leadStallWarnMs() {
12
+ function leadStallWarnMs() {
13
13
  return resolveAgentStallThresholds('lead').warn * 1000;
14
14
  }
15
15
 
@@ -549,6 +549,8 @@ export function failTurn(ctx, error) {
549
549
  if (record.quota) turn.quota = record.quota;
550
550
  turn.failureDetail = record.detail;
551
551
  turn.failureDiagnostic = record.errorDetails;
552
+ // Answers the turn went on past before it failed (turn-report.mjs).
553
+ if (typeof error?.carriedReport === 'string') turn.carriedReport = error.carriedReport;
552
554
  pushNotice(turn.failureDetail, 'error', { owner: 'transcript' });
553
555
  }
554
556
 
@@ -661,6 +663,7 @@ async function settleTurn(ctx) {
661
663
  session: runtime.session || null,
662
664
  error: turn.failureDetail || null,
663
665
  errorKind: turn.failed ? turn.errorKind || null : null,
666
+ ...(turn.failed && turn.carriedReport ? { carriedReport: turn.carriedReport } : {}),
664
667
  };
665
668
  // Publish termination before optional Goal work can delay the caller.
666
669
  bag.settleSteeredSubmissions?.(turn.epoch, detail);
@@ -12,7 +12,7 @@ const ENDINGS = {
12
12
  const INCOMPLETE = 'Some worktree dependencies were not installed; the agent has the details.';
13
13
 
14
14
  /** Notice text and tone for one install progress event. */
15
- export function worktreeSetupNotice(event) {
15
+ function worktreeSetupNotice(event) {
16
16
  if (event.final) {
17
17
  const text = ENDINGS[event.status] ?? INCOMPLETE;
18
18
  return { text, tone: event.status === 'completed' ? 'info' : 'warn' };
@@ -17,7 +17,7 @@ const compactNumberFormatter = new Intl.NumberFormat('en-US', {
17
17
  minimumFractionDigits: 0,
18
18
  });
19
19
 
20
- export function formatSpinnerTokens(value) {
20
+ function formatSpinnerTokens(value) {
21
21
  const tokens = Math.max(0, Number(value || 0));
22
22
  if (tokens >= 1000) return compactNumberFormatter.format(tokens).toLowerCase();
23
23
  return String(Math.round(tokens));
@@ -84,8 +84,8 @@ export function buildSpinnerMeta({
84
84
  thinkingParts,
85
85
  tokensText: tokens > 0 ? `${formatSpinnerTokens(tokens)} tokens` : '',
86
86
  // The count appears with the FIRST token (user: 30초가 아니라 바로).
87
- // Elapsed was never gated, so the byline used to grow a second field
88
- // mid-turn for no reason the reader could see; now both arrive together.
87
+ // Elapsed is never gated, so showing tokens with the first token keeps the
88
+ // byline from growing a second field mid-turn; both arrive together.
89
89
  showTokens: tokens > 0,
90
90
  thinkingText,
91
91
  thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
@@ -199,13 +199,13 @@ export const SPINNER_VERBS = [
199
199
  ];
200
200
 
201
201
  /** How long one phrase holds before the pool advances. */
202
- export const SPINNER_VERB_ROTATE_MS = 30_000;
202
+ const SPINNER_VERB_ROTATE_MS = 30_000;
203
203
 
204
204
  /** Odds that a 30s boundary actually swaps the phrase (user: 바꿀지 말지만
205
205
  * 랜덤 돌리면 되잖아). Below 1 the window stretches: ~half the boundaries
206
206
  * hold, so a phrase lives 30s, 60s, 90s… and the rhythm stops being a
207
207
  * metronome. */
208
- export const SPINNER_VERB_CHANGE_ODDS = 0.5;
208
+ const SPINNER_VERB_CHANGE_ODDS = 0.5;
209
209
 
210
210
  /**
211
211
  * Deterministic coin for ONE (turn, boundary) pair.