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
@@ -48,31 +48,39 @@ function usePastedBufferSlice({ toEntry, formatRef }) {
48
48
  setBuffers(next);
49
49
  }, []);
50
50
 
51
- const register = useCallback((input) => {
52
- const id = nextIdRef.current;
53
- const entry = toEntry(input, id);
54
- if (!entry) return '';
55
- nextIdRef.current = id + 1;
56
- buffersRef.current = { ...buffersRef.current, [id]: entry };
57
- setBuffers(buffersRef.current);
58
- return formatRef(entry);
59
- }, []);
51
+ const register = useCallback(
52
+ (input) => {
53
+ const id = nextIdRef.current;
54
+ const entry = toEntry(input, id);
55
+ if (!entry) return '';
56
+ nextIdRef.current = id + 1;
57
+ buffersRef.current = { ...buffersRef.current, [id]: entry };
58
+ setBuffers(buffersRef.current);
59
+ return formatRef(entry);
60
+ },
61
+ [toEntry, formatRef]
62
+ );
60
63
 
61
64
  return { buffersRef, nextIdRef, install, clearSnapshot, register };
62
65
  }
63
66
 
67
+ // Module-level slice specs keep toEntry/formatRef identities stable, so
68
+ // `register` is created once per mount.
69
+ const IMAGE_SLICE = {
70
+ toEntry: (image, id) => (image?.type === 'image' && image.content ? { ...image, id } : null),
71
+ formatRef: (entry) => formatImageRef(entry.id),
72
+ };
73
+ const TEXT_SLICE = {
74
+ toEntry: (text, id) => {
75
+ const value = String(text ?? '');
76
+ return value ? { id, text: value } : null;
77
+ },
78
+ formatRef: (entry) => formatPastedTextRef(entry.id, entry.text),
79
+ };
80
+
64
81
  export function usePastedBuffers() {
65
- const images = usePastedBufferSlice({
66
- toEntry: (image, id) => (image?.type === 'image' && image.content ? { ...image, id } : null),
67
- formatRef: (entry) => formatImageRef(entry.id),
68
- });
69
- const texts = usePastedBufferSlice({
70
- toEntry: (text, id) => {
71
- const value = String(text ?? '');
72
- return value ? { id, text: value } : null;
73
- },
74
- formatRef: (entry) => formatPastedTextRef(entry.id, entry.text),
75
- });
82
+ const images = usePastedBufferSlice(IMAGE_SLICE);
83
+ const texts = usePastedBufferSlice(TEXT_SLICE);
76
84
 
77
85
  return {
78
86
  pastedImagesRef: images.buffersRef,
@@ -65,6 +65,13 @@ export function usePromptDraftFlow({
65
65
  showPromptHint,
66
66
  slashDismissedFor,
67
67
  syncPromptLayoutRows,
68
+ promptHistoryDraftChangeRef,
69
+ promptHistoryNavRef,
70
+ setPromptDraft,
71
+ setPromptDraftOverride,
72
+ promptHintActiveRef,
73
+ promptHintTimerRef,
74
+ setSlashDismissedFor,
68
75
  ]
69
76
  );
70
77
 
@@ -21,11 +21,11 @@ export function usePromptLayoutRows({
21
21
  const nextRows = promptContentRows(text, promptContentColumns);
22
22
  setPromptLayoutRows((prev) => (prev === nextRows ? prev : nextRows));
23
23
  },
24
- [promptContentColumns]
24
+ [promptContentColumns, promptLayoutValueRef, setPromptLayoutRows]
25
25
  );
26
26
  useEffect(() => {
27
27
  syncPromptLayoutRows(promptLayoutValueRef.current);
28
- }, [syncPromptLayoutRows]);
28
+ }, [syncPromptLayoutRows, promptLayoutValueRef]);
29
29
  useEffect(() => {
30
30
  const kind = String(settingsPrompt?.kind || '');
31
31
  if (!CORE_MULTILINE_TEXT_ENTRY_KINDS.has(kind)) {
@@ -34,6 +34,6 @@ export function usePromptLayoutRows({
34
34
  }
35
35
  const cols = Math.max(1, frameColumns - 4 - stringWidth('Sentence > '));
36
36
  setTextEntryLayoutRows(textEntryReservedRows(settingsPrompt?.initialValue, cols, 8));
37
- }, [settingsPrompt?.kind, settingsPrompt?.initialValue, frameColumns]);
37
+ }, [settingsPrompt?.kind, settingsPrompt?.initialValue, frameColumns, setTextEntryLayoutRows]);
38
38
  return syncPromptLayoutRows;
39
39
  }
@@ -53,7 +53,7 @@ export function usePromptQueueHistory({
53
53
  exit();
54
54
  });
55
55
  }, 60);
56
- }, [store, exit]);
56
+ }, [store, exit, exitRequestedRef, setExiting]);
57
57
 
58
58
  const restoreQueuedToPrompt = useCallback(
59
59
  (options = {}) =>
@@ -74,6 +74,7 @@ export function usePromptQueueHistory({
74
74
  store,
75
75
  state?.queued,
76
76
  promptDraft,
77
+ promptValueRef,
77
78
  showPromptHint,
78
79
  clearPromptHint,
79
80
  installPastedImages,
@@ -85,8 +86,8 @@ export function usePromptQueueHistory({
85
86
 
86
87
  const recentPromptHistory = useMemo(() => {
87
88
  // The engine maintains this list incrementally (rebuilt only when a user
88
- // item is appended or the transcript is bulk-swapped), so App no longer
89
- // rescans all items on every transcript change. Fall back to a local scan
89
+ // item is appended or the transcript is bulk-swapped), so App does not
90
+ // rescan all items on every transcript change. Fall back to a local scan
90
91
  // only if the engine did not publish it (older snapshot).
91
92
  if (Array.isArray(state.promptHistoryList)) return state.promptHistoryList;
92
93
  return scanPromptHistory(Array.isArray(state.items) ? state.items : []);
@@ -94,7 +95,7 @@ export function usePromptQueueHistory({
94
95
 
95
96
  const resetPromptHistoryNav = useCallback(() => {
96
97
  promptHistoryNavRef.current = { active: false, index: -1, seed: '', lastValue: '' };
97
- }, []);
98
+ }, [promptHistoryNavRef]);
98
99
 
99
100
  return { requestExit, restoreQueuedToPrompt, recentPromptHistory, resetPromptHistoryNav };
100
101
  }
@@ -31,7 +31,7 @@ export function useSelectionFocusMove({
31
31
  const shiftedRect = dragRef.current.rect;
32
32
  return { anchor: shiftedRect ? { x: shiftedRect.x1, y: shiftedRect.y1 } : null };
33
33
  },
34
- [scrollTranscriptRows]
34
+ [dragRef, scrollTargetRef, scrollTranscriptRows]
35
35
  );
36
36
 
37
37
  const moveSelectionFocus = useCallback(
@@ -120,7 +120,16 @@ export function useSelectionFocusMove({
120
120
  dragNow.last = { x: col, y: row };
121
121
  return true;
122
122
  },
123
- [applySelectionRect, statusBandRows, transcriptViewportRows, selectionMaxColAtRow, scrollFocusPastEdge]
123
+ [
124
+ dragRef,
125
+ scrollTargetRef,
126
+ transcriptBottomSlackRowsRef,
127
+ applySelectionRect,
128
+ statusBandRows,
129
+ transcriptViewportRows,
130
+ selectionMaxColAtRow,
131
+ scrollFocusPastEdge,
132
+ ]
124
133
  );
125
134
 
126
135
  return moveSelectionFocus;
@@ -22,13 +22,16 @@ export function useSelectionGeometry({
22
22
  transcriptViewportRef,
23
23
  dragRef,
24
24
  }) {
25
- const selectionPointAtCurrentScroll = useCallback((point, pointScroll = 0) => {
26
- if (!point) return null;
27
- return {
28
- x: point.x,
29
- y: point.y + (Number(scrollTargetRef.current) || 0) - (Number(pointScroll) || 0),
30
- };
31
- }, []);
25
+ const selectionPointAtCurrentScroll = useCallback(
26
+ (point, pointScroll = 0) => {
27
+ if (!point) return null;
28
+ return {
29
+ x: point.x,
30
+ y: point.y + (Number(scrollTargetRef.current) || 0) - (Number(pointScroll) || 0),
31
+ };
32
+ },
33
+ [scrollTargetRef]
34
+ );
32
35
 
33
36
  // Grow a word/line multi-click selection from its anchor span out to the
34
37
  // word/line under the cursor. Shared by the mouse handler (motion/release)
@@ -68,9 +71,15 @@ export function useSelectionGeometry({
68
71
  [store, frameColumns, selectionPointAtCurrentScroll]
69
72
  );
70
73
 
71
- const transcriptViewportRows = useCallback(() => transcriptViewportRowRange(transcriptViewportRef.current), []);
74
+ const transcriptViewportRows = useCallback(
75
+ () => transcriptViewportRowRange(transcriptViewportRef.current),
76
+ [transcriptViewportRef]
77
+ );
72
78
 
73
- const statusBandRows = useCallback(() => statusBandRowRange(frameRowsRef.current, statuslineBandRows), []);
79
+ const statusBandRows = useCallback(
80
+ () => statusBandRowRange(frameRowsRef.current, statuslineBandRows),
81
+ [frameRowsRef, statuslineBandRows]
82
+ );
74
83
 
75
84
  const selectionMaxColAtRow = useCallback(
76
85
  (row) => {
@@ -54,12 +54,12 @@ export function useSelectionPaint({
54
54
  .catch(() => {
55
55
  /* best-effort capture: Ctrl+C falls back to the render-time text */
56
56
  });
57
- }, [store]);
57
+ }, [store, selectionTextRef]);
58
58
 
59
59
  // Clip band + theming: use-selection-paint/selection-clip.mjs.
60
60
  const selectionClip = useCallback(
61
61
  () => selectionClipBand({ dragRef, frameRowsRef, transcriptViewportRef, statuslineBandRows }),
62
- [statuslineBandRows]
62
+ [dragRef, frameRowsRef, transcriptViewportRef, statuslineBandRows]
63
63
  );
64
64
 
65
65
  const withSelectionClip = useCallback(
@@ -98,7 +98,7 @@ export function useSelectionPaint({
98
98
  cancelPendingSelectionPaint();
99
99
  paintSelectionRect(clippedRect, { rememberText: true });
100
100
  },
101
- [paintSelectionRect, withSelectionClip, clearStitchBuffer, cancelPendingSelectionPaint]
101
+ [dragRef, selectionTextRef, paintSelectionRect, withSelectionClip, clearStitchBuffer, cancelPendingSelectionPaint]
102
102
  );
103
103
 
104
104
  const applySelectionRectThrottled = useCallback(
@@ -111,7 +111,7 @@ export function useSelectionPaint({
111
111
  cancelPending: cancelPendingSelectionPaint,
112
112
  });
113
113
  },
114
- [paintSelectionRect, withSelectionClip, cancelPendingSelectionPaint]
114
+ [dragRef, paintSelectionRect, withSelectionClip, cancelPendingSelectionPaint]
115
115
  );
116
116
 
117
117
  return {
@@ -64,7 +64,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
64
64
  if (!Array.isArray(rows)) return;
65
65
  storeStitchRows(stitchBufferRef.current, rows, stitchHarvestScrollRef.current);
66
66
  }, 0);
67
- }, [store]);
67
+ }, [store, dragRef, scrollTargetRef]);
68
68
 
69
69
  // Synchronous sibling: snapshot the rows CURRENTLY under the selection
70
70
  // immediately, keyed by the given (pre-scroll) offset. Called right before
@@ -80,7 +80,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
80
80
  if (!Array.isArray(rows)) return;
81
81
  storeStitchRows(stitchBufferRef.current, rows, Number(scroll) || 0);
82
82
  },
83
- [store]
83
+ [store, dragRef]
84
84
  );
85
85
 
86
86
  // Map the CURRENT rect + current scrollTarget onto the content-key range and
@@ -122,7 +122,7 @@ export function useSelectionStitchBuffer({ store, dragRef, scrollTargetRef }) {
122
122
  }
123
123
  const text = logical.map((l) => l.replace(/\s+$/u, '')).join('\n');
124
124
  return text.trim() ? { text, complete } : empty;
125
- }, []);
125
+ }, [dragRef, scrollTargetRef]);
126
126
 
127
127
  return { clearStitchBuffer, harvestStitchRowsSoon, harvestStitchRowsNow, getStitchedSelectionText };
128
128
  }
@@ -0,0 +1,62 @@
1
+ /*
2
+ * app/use-slash-palette.mjs — the slash / `$skill` palette above the prompt.
3
+ *
4
+ * useSlashPaletteState owns the selection index, the dismissed-draft marker
5
+ * and the live open/count ref the mouse handler reads; it is declared early
6
+ * because the mouse and draft hooks need the setters. useSlashPalette derives
7
+ * the palette for this render from the prompt and the surfaces that suppress
8
+ * it, publishes it to that ref, and keeps the index inside the list.
9
+ */
10
+ import { useEffect, useRef, useState } from 'react';
11
+ import { deriveSlashPalette } from './slash-palette.mjs';
12
+ import { skillMentionQuery, useSkillMentionSkills } from './skill-mention-palette.mjs';
13
+
14
+ export function useSlashPaletteState() {
15
+ const [slashIndex, setSlashIndex] = useState(0);
16
+ const [slashDismissedFor, setSlashDismissedFor] = useState('');
17
+ const slashPaletteRef = useRef({ open: false, count: 0 });
18
+ return { slashIndex, setSlashIndex, slashDismissedFor, setSlashDismissedFor, slashPaletteRef };
19
+ }
20
+
21
+ export function useSlashPalette({
22
+ store,
23
+ slashPaletteRef,
24
+ setSlashIndex,
25
+ slashDismissedFor,
26
+ promptDraft,
27
+ promptCaret,
28
+ providerPrompt,
29
+ settingsPrompt,
30
+ toolApproval,
31
+ contextPanel,
32
+ usagePanel,
33
+ picker,
34
+ exiting,
35
+ commandBusy,
36
+ }) {
37
+ const mentionSkills = useSkillMentionSkills(store, skillMentionQuery(promptDraft, promptCaret) !== null);
38
+ const palette = deriveSlashPalette({
39
+ providerPrompt,
40
+ settingsPrompt,
41
+ toolApproval,
42
+ contextPanel,
43
+ usagePanel,
44
+ picker,
45
+ exiting,
46
+ commandBusy,
47
+ promptDraft,
48
+ slashDismissedFor,
49
+ skills: mentionSkills,
50
+ promptCaret,
51
+ });
52
+ const { activeSlashQuery, slashCommands, slashPaletteOpen } = palette;
53
+ slashPaletteRef.current = { open: slashPaletteOpen, count: slashCommands.length };
54
+
55
+ // A query change re-clamps even when the list length stays the same.
56
+ // biome-ignore lint/correctness/useExhaustiveDependencies(activeSlashQuery): query-change re-clamp trigger
57
+ useEffect(() => {
58
+ setSlashIndex((index) => Math.min(index, Math.max(0, slashCommands.length - 1)));
59
+ }, [slashCommands.length, activeSlashQuery, setSlashIndex]);
60
+
61
+ return palette;
62
+ }
@@ -47,7 +47,7 @@ export function useTerminalChrome({ stdout, isRawModeSupported, setResizeState }
47
47
  if (trailing) clearTimeout(trailing);
48
48
  stdout.off('resize', onResize);
49
49
  };
50
- }, [stdout]);
50
+ }, [stdout, setResizeState]);
51
51
 
52
52
  // Enable extended keyboard reporting (kitty + xterm modifyOtherKeys)
53
53
  // SYNCHRONOUSLY, ONCE, with NO query/round-trip. ink
@@ -61,7 +61,7 @@ export function useTerminalChrome({ stdout, isRawModeSupported, setResizeState }
61
61
  // \x1b[27;5;13~ (or kitty \x1b[13;5u) instead of a bare \r — fixing the old
62
62
  // "first Ctrl+Enter submits, second works" race. Teardown lives in index.jsx's
63
63
  // restoreTerminal(). The empty dep array makes this run exactly once on mount.
64
- // eslint-disable-next-line react-hooks/exhaustive-deps
64
+ // biome-ignore lint/correctness/useExhaustiveDependencies: one-shot mount enable; teardown is owned by restoreTerminal()
65
65
  useEffect(() => {
66
66
  if (!isRawModeSupported || !stdout?.write) return;
67
67
  if (!supportsExtendedKeys()) return;
@@ -59,7 +59,7 @@ export function useTranscriptActivity({ state }) {
59
59
  // the StatusLine effect only re-fires when the numbers actually change.
60
60
  const activeToolsSignature = useMemo(() => {
61
61
  // The engine maintains this signature incrementally (updated on tool
62
- // start/early-complete/result/turn-end), so App no longer scans every
62
+ // start/early-complete/result/turn-end), so App does not scan every
63
63
  // transcript item on each change. Prefer it; fall back to the local scan
64
64
  // only when the engine did not publish it (older snapshot).
65
65
  if (state.activeToolSummary !== undefined) return state.activeToolSummary || '';
@@ -105,38 +105,53 @@ export function useTranscriptActivity({ state }) {
105
105
  // StatusLine only reads a small stats subset; engine clones the full stats
106
106
  // object on many updates. Memoize by field value so identical usage keeps
107
107
  // the same object reference and React.memo / effect deps stay quiet.
108
- const statuslineStats = useMemo(() => {
109
- const s = state.stats || {};
110
- return {
111
- currentContextSource: s.currentContextSource ?? null,
112
- currentEstimatedContextTokens: s.currentEstimatedContextTokens ?? 0,
113
- currentContextTokens: s.currentContextTokens ?? null,
114
- contextTokens: s.contextTokens ?? 0,
115
- latestPromptTokens: s.latestPromptTokens ?? 0,
116
- latestInputTokens: s.latestInputTokens ?? 0,
117
- latestCachedTokens: s.latestCachedTokens ?? 0,
118
- latestCacheWriteTokens: s.latestCacheWriteTokens ?? 0,
119
- inputTokens: s.inputTokens ?? 0,
120
- cachedTokens: s.cachedTokens ?? 0,
121
- cacheWriteTokens: s.cacheWriteTokens ?? 0,
122
- promptTokens: s.promptTokens ?? 0,
123
- turns: s.turns ?? 0,
124
- };
125
- }, [
126
- state.stats?.currentContextSource,
127
- state.stats?.currentEstimatedContextTokens,
128
- state.stats?.currentContextTokens,
129
- state.stats?.contextTokens,
130
- state.stats?.latestPromptTokens,
131
- state.stats?.latestInputTokens,
132
- state.stats?.latestCachedTokens,
133
- state.stats?.latestCacheWriteTokens,
134
- state.stats?.inputTokens,
135
- state.stats?.cachedTokens,
136
- state.stats?.cacheWriteTokens,
137
- state.stats?.promptTokens,
138
- state.stats?.turns,
139
- ]);
108
+ const {
109
+ currentContextSource,
110
+ currentEstimatedContextTokens,
111
+ currentContextTokens,
112
+ contextTokens,
113
+ latestPromptTokens,
114
+ latestInputTokens,
115
+ latestCachedTokens,
116
+ latestCacheWriteTokens,
117
+ inputTokens,
118
+ cachedTokens,
119
+ cacheWriteTokens,
120
+ promptTokens,
121
+ turns,
122
+ } = state.stats || {};
123
+ const statuslineStats = useMemo(
124
+ () => ({
125
+ currentContextSource: currentContextSource ?? null,
126
+ currentEstimatedContextTokens: currentEstimatedContextTokens ?? 0,
127
+ currentContextTokens: currentContextTokens ?? null,
128
+ contextTokens: contextTokens ?? 0,
129
+ latestPromptTokens: latestPromptTokens ?? 0,
130
+ latestInputTokens: latestInputTokens ?? 0,
131
+ latestCachedTokens: latestCachedTokens ?? 0,
132
+ latestCacheWriteTokens: latestCacheWriteTokens ?? 0,
133
+ inputTokens: inputTokens ?? 0,
134
+ cachedTokens: cachedTokens ?? 0,
135
+ cacheWriteTokens: cacheWriteTokens ?? 0,
136
+ promptTokens: promptTokens ?? 0,
137
+ turns: turns ?? 0,
138
+ }),
139
+ [
140
+ currentContextSource,
141
+ currentEstimatedContextTokens,
142
+ currentContextTokens,
143
+ contextTokens,
144
+ latestPromptTokens,
145
+ latestInputTokens,
146
+ latestCachedTokens,
147
+ latestCacheWriteTokens,
148
+ inputTokens,
149
+ cachedTokens,
150
+ cacheWriteTokens,
151
+ promptTokens,
152
+ turns,
153
+ ]
154
+ );
140
155
 
141
156
  return { agentRevision, activeTools, statuslineStats };
142
157
  }
@@ -44,11 +44,11 @@ export function useTranscriptFollow({
44
44
  setScrollOffset(Math.max(0, Math.round(scrollPositionRef.current)));
45
45
  }, 16);
46
46
  scrollAnimationRef.current.unref?.();
47
- }, [stopSmoothScroll]);
47
+ }, [scrollPositionRef, scrollTargetRef, followingRef, setScrollOffset, stopSmoothScroll]);
48
48
 
49
49
  const cancelTranscriptFollow = useCallback(() => {
50
50
  followingRef.current = false;
51
- }, []);
51
+ }, [followingRef]);
52
52
 
53
53
  const resetTranscriptScroll = useCallback(() => {
54
54
  stopSmoothScroll();
@@ -65,7 +65,15 @@ export function useTranscriptFollow({
65
65
  // and every new row piled up below the fold.
66
66
  followingRef.current = true;
67
67
  setScrollOffset(0);
68
- }, [stopSmoothScroll]);
68
+ }, [
69
+ scrollPositionRef,
70
+ scrollTargetRef,
71
+ followingRef,
72
+ transcriptAnchorRef,
73
+ transcriptAnchorDirtyRef,
74
+ setScrollOffset,
75
+ stopSmoothScroll,
76
+ ]);
69
77
 
70
78
  const armTranscriptFollow = useCallback(() => {
71
79
  // Do not mutate scrollOffset here. During prompt submit the transcript rows
@@ -78,7 +86,7 @@ export function useTranscriptFollow({
78
86
  pendingReadbackRowsRef.current = 0;
79
87
  followingRef.current = true;
80
88
  stopSmoothScroll();
81
- }, [stopSmoothScroll]);
89
+ }, [followingRef, transcriptAnchorRef, transcriptAnchorDirtyRef, stopSmoothScroll]);
82
90
 
83
91
  return {
84
92
  pendingReadbackRowsRef,
@@ -141,7 +141,7 @@ export function useTranscriptScroll({
141
141
  if (!anchor) return;
142
142
  transcriptAnchorRef.current = anchor;
143
143
  transcriptAnchorDirtyRef.current = false;
144
- }, []);
144
+ }, [transcriptGeomRef, scrollTargetRef, transcriptAnchorRef, transcriptAnchorDirtyRef]);
145
145
 
146
146
  // A manual scroll moves the reading position. Capture the new anchor
147
147
  // SYNCHRONOUSLY from the latest published geometry so the very next render
@@ -149,20 +149,23 @@ export function useTranscriptScroll({
149
149
  // streaming growth could lurch the view. Only at the true bottom drop the
150
150
  // anchor so the bottom-follow path owns the viewport again: a positive
151
151
  // wheel offset is an explicit reading position, even inside the old slack.
152
- const captureReadingAnchor = useCallback((target) => {
153
- if (target === 0) {
154
- transcriptAnchorRef.current = null;
155
- transcriptAnchorDirtyRef.current = false;
156
- return;
157
- }
158
- const anchor = readingAnchorAt(transcriptGeomRef.current || {}, target);
159
- if (anchor) {
160
- transcriptAnchorRef.current = anchor;
161
- transcriptAnchorDirtyRef.current = false;
162
- } else {
163
- transcriptAnchorDirtyRef.current = true;
164
- }
165
- }, []);
152
+ const captureReadingAnchor = useCallback(
153
+ (target) => {
154
+ if (target === 0) {
155
+ transcriptAnchorRef.current = null;
156
+ transcriptAnchorDirtyRef.current = false;
157
+ return;
158
+ }
159
+ const anchor = readingAnchorAt(transcriptGeomRef.current || {}, target);
160
+ if (anchor) {
161
+ transcriptAnchorRef.current = anchor;
162
+ transcriptAnchorDirtyRef.current = false;
163
+ } else {
164
+ transcriptAnchorDirtyRef.current = true;
165
+ }
166
+ },
167
+ [transcriptGeomRef, transcriptAnchorRef, transcriptAnchorDirtyRef]
168
+ );
166
169
 
167
170
  // Scrolling past the oldest/newest loaded edge pages transcript history
168
171
  // instead of moving the target. Returns true when the edge owned the
@@ -190,7 +193,15 @@ export function useTranscriptScroll({
190
193
  }
191
194
  return true;
192
195
  },
193
- [store, captureRestoreAnchor, stopSmoothScroll, cancelTranscriptFollow]
196
+ [
197
+ store,
198
+ scrollTargetRef,
199
+ scrollPositionRef,
200
+ setScrollOffset,
201
+ captureRestoreAnchor,
202
+ stopSmoothScroll,
203
+ cancelTranscriptFollow,
204
+ ]
194
205
  );
195
206
 
196
207
  // Keep a live selection on its content after the viewport moved. An active
@@ -229,7 +240,14 @@ export function useTranscriptScroll({
229
240
  // (Ctrl+C after scrolling then copied just that fragment).
230
241
  paintSelectionRect(clippedRect, { rememberText: false });
231
242
  },
232
- [buildSpanRect, selectionPointAtCurrentScroll, withSelectionClip, cancelPendingSelectionPaint, paintSelectionRect]
243
+ [
244
+ dragRef,
245
+ buildSpanRect,
246
+ selectionPointAtCurrentScroll,
247
+ withSelectionClip,
248
+ cancelPendingSelectionPaint,
249
+ paintSelectionRect,
250
+ ]
233
251
  );
234
252
 
235
253
  const scrollTranscriptRows = useCallback(
@@ -294,6 +312,17 @@ export function useTranscriptScroll({
294
312
  setScrollOffset(Math.round(target));
295
313
  },
296
314
  [
315
+ maxScrollRowsRef,
316
+ transcriptGeomRef,
317
+ scrollTargetRef,
318
+ scrollPositionRef,
319
+ pendingReadbackRowsRef,
320
+ dragRef,
321
+ transcriptAnchorRef,
322
+ transcriptAnchorDirtyRef,
323
+ followingRef,
324
+ selectionLayoutRef,
325
+ setScrollOffset,
297
326
  pageTranscriptHistory,
298
327
  captureReadingAnchor,
299
328
  rebuildSelectionAfterScroll,
@@ -0,0 +1,27 @@
1
+ /*
2
+ * app/use-transcript-swap-reset.mjs — returns the viewport to the live tail
3
+ * when the transcript items are bulk-swapped.
4
+ *
5
+ * Item-count changes never infer follow permission from scrollTarget=0. A
6
+ * first read-back input can be waiting one frame for committed row geometry;
7
+ * only prompt submit, session reset, or an explicit return to bottom arms
8
+ * follow. Pure streaming height growth is handled in the row-delta effect.
9
+ */
10
+ import { useLayoutEffect } from 'react';
11
+ import { transcriptSwapReturnsToTail } from './transcript-window.mjs';
12
+
13
+ export function useTranscriptSwapReset({ items, lastItemsCountRef, lastFirstItemIdRef, resetTranscriptScroll }) {
14
+ useLayoutEffect(() => {
15
+ const count = items.length;
16
+ const previousCount = lastItemsCountRef.current;
17
+ lastItemsCountRef.current = count;
18
+ const firstId = count > 0 ? (items[0]?.id ?? null) : null;
19
+ const previousFirstId = lastFirstItemIdRef.current;
20
+ lastFirstItemIdRef.current = firstId;
21
+ // A bulk swap (compaction included) is an explicit return to the tail: the
22
+ // rows the reader was anchored to no longer exist.
23
+ if (transcriptSwapReturnsToTail({ count, previousCount, firstId, previousFirstId })) {
24
+ resetTranscriptScroll();
25
+ }
26
+ }, [items, lastItemsCountRef, lastFirstItemIdRef, resetTranscriptScroll]);
27
+ }