mixdog 1.2.2 → 1.2.4

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 (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -1,16 +1,22 @@
1
1
  // Per-turn streaming state for the lead TUI turn: the assistant text
2
2
  // segments, the thinking (reasoning) timer, and the frame-batched flush that
3
- // publishes completed visible lines and thinking transitions to the store.
3
+ // publishes completed visible lines and thinking transitions to the store,
4
+ // plus the desktop-only unfinished line (`streamingPartial`, see partialNow).
4
5
  // `createTurnStream` returns one explicit state object (deps + mutable
5
6
  // scalars); every function here takes it as its first argument.
6
7
  import { TUI_FRAME_MS, yieldToRenderer } from './render-timing.mjs';
7
8
  import { retryStatusLine } from '../../runtime/shared/err-text.mjs';
9
+ import { MODEL_THINKING_STAGE } from '../../runtime/shared/quiet-progress.mjs';
8
10
  import { newTranscriptMessageId } from '../../runtime/shared/transcript-metadata.mjs';
9
11
 
10
12
  // Share Ink's exact 120fps cadence with the frame-batched store. A separate
11
13
  // 16ms timer left every other terminal frame idle, so completed script lines
12
14
  // accumulated and then climbed into view in coarse two-step chunks.
13
15
  const STREAM_BATCH_INTERVAL_MS = TUI_FRAME_MS;
16
+ // The desktop's unfinished-line channel (see partialNow): at most one
17
+ // publication per interval, the first chunk after an idle gap on the next
18
+ // frame. Forced flushes (tool calls, notices, finalization) publish at once.
19
+ const PARTIAL_INTERVAL_MS = 40;
14
20
 
15
21
  // deps: getState, set, nextId, updateStreamingTail, settleStreamingTail,
16
22
  // clearStreamingTail, isCurrentTurn, transcriptMeta, routeMeta, sealToolBlock.
@@ -53,42 +59,59 @@ export function createTurnStream(deps) {
53
59
  publishedThinkingActive: false,
54
60
  // Live countdown of a reconnect wait (see startReconnectCountdown).
55
61
  reconnectTimer: null,
62
+ // The row identity (id, time, message id) claimed before the row exists,
63
+ // while only the desktop's partial line shows it; the row takes it over.
64
+ assistantIdentity: null,
65
+ // Desktop partial-line publication timer and last publish time.
66
+ partialTimer: null,
67
+ partialPublishedAt: 0,
68
+ // This segment's partial is on screen / was cleared by a transcript
69
+ // replacement (and must not come back).
70
+ partialShown: false,
71
+ partialDropped: false,
56
72
  };
57
73
  }
58
74
 
75
+ function claimAssistantIdentity(stream) {
76
+ if (stream.assistantIdentity) return stream.assistantIdentity;
77
+ const id = stream.nextId();
78
+ const meta = stream.transcriptMeta;
79
+ // A non-streaming continuation was persisted before its text reached this
80
+ // row: the runtime left that message's id and time (ask-session
81
+ // takeAssistant), and the row carries them instead of minting new ones.
82
+ const persisted = stream.claimPersistedAssistant ? meta.persistedAssistant : null;
83
+ if (persisted) meta.persistedAssistant = null;
84
+ let assistantAt = persisted?.at;
85
+ let messageId = persisted?.messageId;
86
+ if (!persisted) {
87
+ assistantAt =
88
+ Number.isFinite(Number(meta.assistantAt)) && Number(meta.assistantAt) > 0 ? Number(meta.assistantAt) : Date.now();
89
+ meta.assistantAt = assistantAt;
90
+ // The reply this segment becomes is persisted with this stable id (the
91
+ // runtime takes it with assistantAt), so a compaction that drops the
92
+ // reply greys this row.
93
+ if (!(typeof meta.assistantMessageId === 'string' && meta.assistantMessageId)) {
94
+ meta.assistantMessageId = newTranscriptMessageId();
95
+ }
96
+ messageId = meta.assistantMessageId;
97
+ }
98
+ stream.assistantIdentity = { id, at: assistantAt, messageId };
99
+ return stream.assistantIdentity;
100
+ }
101
+
59
102
  function ensureAssistant(stream, initialText = '') {
60
103
  if (!stream.currentAssistantId) {
61
- stream.currentAssistantId = stream.nextId();
62
- const meta = stream.transcriptMeta;
63
- // A non-streaming continuation was persisted before its text reached this
64
- // row: the runtime left that message's id and time (ask-session
65
- // takeAssistant), and the row carries them instead of minting new ones.
66
- const persisted = stream.claimPersistedAssistant ? meta.persistedAssistant : null;
67
- if (persisted) meta.persistedAssistant = null;
68
- let assistantAt = persisted?.at;
69
- let messageId = persisted?.messageId;
70
- if (!persisted) {
71
- assistantAt =
72
- Number.isFinite(Number(meta.assistantAt)) && Number(meta.assistantAt) > 0
73
- ? Number(meta.assistantAt)
74
- : Date.now();
75
- meta.assistantAt = assistantAt;
76
- // The reply this segment becomes is persisted with this stable id (the
77
- // runtime takes it with assistantAt), so a compaction that drops the
78
- // reply greys this row.
79
- if (!(typeof meta.assistantMessageId === 'string' && meta.assistantMessageId)) {
80
- meta.assistantMessageId = newTranscriptMessageId();
81
- }
82
- messageId = meta.assistantMessageId;
83
- }
104
+ const { id, at, messageId } = claimAssistantIdentity(stream);
105
+ stream.assistantIdentity = null;
106
+ stream.currentAssistantId = id;
84
107
  // Do NOT reset currentAssistantText here: the first onTextDelta has
85
108
  // already accumulated the opening chunk before this batched flush runs.
86
109
  // Segment resets are owned by closeAssistantSegment(). Seed the new row
87
110
  // with the already-visible text so the ● gutter and the first body line
88
111
  // appear in the SAME set()/emit() — no empty "●-only" row.
89
- stream.updateStreamingTail(stream.currentAssistantId, {
112
+ stream.updateStreamingTail(id, {
90
113
  text: String(initialText || ''),
91
- at: assistantAt,
114
+ at,
92
115
  messageId,
93
116
  ...stream.routeMeta,
94
117
  });
@@ -96,6 +119,85 @@ function ensureAssistant(stream, initialText = '') {
96
119
  return stream.currentAssistantId;
97
120
  }
98
121
 
122
+ // The desktop paints streamed text before its line completes; the terminal
123
+ // keeps the line-gated tail below. `streamingPartial` is the unfinished line
124
+ // beyond the published tail text (`from` is that text's length), cut from the
125
+ // same leak-guarded text the tail is, never raw provider output. Before the
126
+ // row's first completed line there is no tail: the partial then carries all
127
+ // visible text so far plus the row identity (`tail`) the row will take over.
128
+ // Terminal projections drop the field (session-proxy/projection.mjs).
129
+ function partialNow(stream) {
130
+ const text = stream.currentAssistantText;
131
+ const id = stream.currentAssistantId;
132
+ if (id != null) {
133
+ const tail = stream.getState().streamingTail;
134
+ if (!tail || tail.id !== id) return null;
135
+ const shown = typeof tail.text === 'string' ? tail.text : '';
136
+ if (text.length <= shown.length || !text.startsWith(shown)) return null;
137
+ return { id, from: shown.length, text: text.slice(shown.length) };
138
+ }
139
+ // Same rule as the row itself: nothing appears before visible content.
140
+ if (!text.trim()) return null;
141
+ const identity = claimAssistantIdentity(stream);
142
+ return {
143
+ id: identity.id,
144
+ from: 0,
145
+ text,
146
+ tail: {
147
+ kind: 'assistant',
148
+ id: identity.id,
149
+ streaming: true,
150
+ at: identity.at,
151
+ messageId: identity.messageId,
152
+ ...stream.routeMeta,
153
+ },
154
+ };
155
+ }
156
+
157
+ function samePartial(left, right) {
158
+ if (left === right) return true;
159
+ if (!left || !right) return false;
160
+ return left.id === right.id && left.from === right.from && left.text === right.text && !left.tail === !right.tail;
161
+ }
162
+
163
+ function clearPartialTimer(stream) {
164
+ if (stream.partialTimer === null) return;
165
+ clearTimeout(stream.partialTimer);
166
+ stream.partialTimer = null;
167
+ }
168
+
169
+ function publishPartial(stream) {
170
+ clearPartialTimer(stream);
171
+ if (!stream.isCurrentTurn()) return;
172
+ const current = stream.getState().streamingPartial ?? null;
173
+ // A transcript replacement cleared the partial this segment showed: the
174
+ // segment stays gone, like a tail the replacement dropped.
175
+ if (stream.partialShown && current === null) stream.partialDropped = true;
176
+ if (stream.partialDropped) return;
177
+ const next = partialNow(stream);
178
+ stream.partialShown = next !== null;
179
+ if (samePartial(current, next)) return;
180
+ stream.partialPublishedAt = Date.now();
181
+ stream.set({ streamingPartial: next });
182
+ }
183
+
184
+ function schedulePartial(stream) {
185
+ if (stream.partialTimer !== null) return;
186
+ const wait = Math.max(STREAM_BATCH_INTERVAL_MS, PARTIAL_INTERVAL_MS - (Date.now() - stream.partialPublishedAt));
187
+ stream.partialTimer = setTimeout(() => {
188
+ stream.partialTimer = null;
189
+ flushStreamBatch(stream);
190
+ }, wait);
191
+ stream.partialTimer?.unref?.();
192
+ }
193
+
194
+ // The segment's text settled (or was dropped): no partial line outlives it.
195
+ function clearPartial(stream) {
196
+ clearPartialTimer(stream);
197
+ stream.partialShown = false;
198
+ if (stream.getState().streamingPartial != null && stream.isCurrentTurn()) stream.set({ streamingPartial: null });
199
+ }
200
+
99
201
  function resetLineScan(stream) {
100
202
  stream.scanLen = 0;
101
203
  stream.lastNewlineIdx = -1;
@@ -107,7 +209,10 @@ function closeAssistantSegment(stream) {
107
209
  stream.currentAssistantId = null;
108
210
  stream.currentAssistantText = '';
109
211
  stream.claimPersistedAssistant = false;
212
+ stream.assistantIdentity = null;
110
213
  resetLineScan(stream);
214
+ clearPartial(stream);
215
+ stream.partialDropped = false;
111
216
  }
112
217
 
113
218
  export function commitAssistantSegment(stream, { sealToolBlock = false } = {}) {
@@ -173,12 +278,14 @@ function flushTextBatch(stream) {
173
278
  const { getState, set } = stream;
174
279
  const visibleText = streamingVisibleTextNow(stream);
175
280
  const patch = {};
281
+ let rowCreated = false;
176
282
  // Do NOT create the assistant row (and scroll the transcript) before there
177
283
  // is a completed line with VISIBLE content: the row appears together with
178
284
  // its first visible line. `.trim()` also guards a response that opens with
179
285
  // leading newlines, whose blank first line would reserve rows and scroll
180
286
  // onto an empty band until a non-blank line lands.
181
287
  if (stream.currentAssistantId || visibleText.trim()) {
288
+ rowCreated = !stream.currentAssistantId;
182
289
  const id = ensureAssistant(stream, visibleText);
183
290
  const current = getState().streamingTail;
184
291
  if (!current || current.id !== id || !Object.is(current.text, visibleText)) {
@@ -214,6 +321,9 @@ function flushTextBatch(stream) {
214
321
  set(patch);
215
322
  }
216
323
  stream.pendingThinkingLastEndedAt = 0;
324
+ // A completed line created or moved the tail: the partial line restarts
325
+ // after it in the same frame, so the two never disagree on screen.
326
+ if (rowCreated || patch.streamingTail) publishPartial(stream);
217
327
  }
218
328
 
219
329
  function thinkingSpinnerPatch(stream, thinkingElapsedMs) {
@@ -256,7 +366,7 @@ function flushThinkBatch(stream) {
256
366
  stream.publishedThinkingActive = nextThinkingActive;
257
367
  }
258
368
 
259
- export function flushStreamBatch(stream) {
369
+ function flushPendingBatches(stream) {
260
370
  if (stream.batchTimer !== null) {
261
371
  clearTimeout(stream.batchTimer);
262
372
  stream.batchTimer = null;
@@ -265,6 +375,7 @@ export function flushStreamBatch(stream) {
265
375
  stream.pendingTextFlush = false;
266
376
  stream.pendingThinkFlush = false;
267
377
  stream.pendingThinkingLastEndedAt = 0;
378
+ clearPartialTimer(stream);
268
379
  return;
269
380
  }
270
381
  if (stream.pendingTextFlush) {
@@ -277,9 +388,17 @@ export function flushStreamBatch(stream) {
277
388
  }
278
389
  }
279
390
 
391
+ // A forced flush is a boundary (tool call, notice, finalization, error, or
392
+ // the partial-line tick): the line-gated batch lands, and so does the
393
+ // desktop's unfinished line.
394
+ export function flushStreamBatch(stream) {
395
+ flushPendingBatches(stream);
396
+ publishPartial(stream);
397
+ }
398
+
280
399
  function scheduleStreamFlush(stream) {
281
400
  if (stream.batchTimer !== null) return; // already scheduled; do not re-arm
282
- stream.batchTimer = setTimeout(() => flushStreamBatch(stream), STREAM_BATCH_INTERVAL_MS);
401
+ stream.batchTimer = setTimeout(() => flushPendingBatches(stream), STREAM_BATCH_INTERVAL_MS);
283
402
  stream.batchTimer?.unref?.(); // don't prevent process exit
284
403
  }
285
404
 
@@ -306,6 +425,7 @@ export function appendTextDelta(stream, textChunk) {
306
425
  stream.pendingTextFlush = true;
307
426
  if (thinkingLastEndedAt) stream.pendingThinkingLastEndedAt = thinkingLastEndedAt;
308
427
  scheduleStreamFlush(stream);
428
+ schedulePartial(stream);
309
429
  }
310
430
 
311
431
  // Mid-turn assistant text that precedes a tool call from a provider that only
@@ -320,6 +440,9 @@ export function appendAssistantText(stream, full, { committed = false } = {}) {
320
440
  // id. Any other text (a tool preamble published before its message commits)
321
441
  // leaves an earlier recorded id unclaimed, so drop it.
322
442
  stream.claimPersistedAssistant = committed;
443
+ // A committed message's row takes its persisted identity, never one claimed
444
+ // earlier for partial text that has since been retracted.
445
+ if (committed && !stream.currentAssistantId) stream.assistantIdentity = null;
323
446
  if (!committed && stream.transcriptMeta && typeof stream.transcriptMeta === 'object') {
324
447
  stream.transcriptMeta.persistedAssistant = null;
325
448
  }
@@ -364,6 +487,8 @@ export function resetStreamedText(stream, { chars, reasoning } = {}) {
364
487
  stream.currentAssistantId = null;
365
488
  }
366
489
  }
490
+ // The retraction applies to the desktop's partial line in the same frame.
491
+ publishPartial(stream);
367
492
  return true;
368
493
  }
369
494
 
@@ -466,9 +591,12 @@ export async function applyStageChange(stream, stage, detail = null) {
466
591
  await yieldToRenderer();
467
592
  return;
468
593
  }
469
- if (value === 'requesting' || value === 'streaming') stream.compactingActive = false;
594
+ if (value === 'requesting' || value === 'streaming' || value === MODEL_THINKING_STAGE) {
595
+ stream.compactingActive = false;
596
+ }
470
597
  let mode = null;
471
598
  if (value === 'requesting') mode = 'requesting';
599
+ else if (value === MODEL_THINKING_STAGE) mode = 'model-thinking';
472
600
  else if (value === 'streaming') mode = getState().spinner.thinking ? 'thinking' : 'responding';
473
601
  if (!mode || getState().spinner.mode === mode) return;
474
602
  set({ spinner: { ...getState().spinner, mode } });
@@ -508,18 +636,37 @@ export function settleFinalText(stream, finalText) {
508
636
  text: stream.currentAssistantText || stream.assistantText,
509
637
  });
510
638
  }
639
+ clearPartial(stream);
511
640
  }
512
641
 
513
642
  // On abort, preserve only the still-open segment: tool boundaries already
514
643
  // sealed prior progress segments into their own rows, and replaying the
515
644
  // turn-global text would create one giant duplicate after the cancelled card.
516
645
  export function settleOpenSegmentOnCancel(stream) {
517
- if (!stream.currentAssistantText.trim()) return;
518
- const id = stream.currentAssistantId || ensureAssistant(stream, stream.currentAssistantText);
519
- stream.settleStreamingTail(id, { text: stream.currentAssistantText });
646
+ if (stream.currentAssistantText.trim()) {
647
+ const id = stream.currentAssistantId || ensureAssistant(stream, stream.currentAssistantText);
648
+ stream.settleStreamingTail(id, { text: stream.currentAssistantText });
649
+ }
650
+ clearPartial(stream);
651
+ }
652
+
653
+ // A segment that never completed a line has no tail, only the partial row the
654
+ // desktop shows. A turn that ends without finalizing it (provider error,
655
+ // aborted tool loop) keeps that text as its row, like cancellation does. A
656
+ // transcript replacement cleared the partial, and then the text stays gone.
657
+ function settlePartialOnlySegment(stream) {
658
+ const identity = stream.assistantIdentity;
659
+ const open = stream.getState().streamingPartial;
660
+ if (stream.currentAssistantId || stream.partialDropped || !identity || open?.id !== identity.id) return;
661
+ if (!stream.isCurrentTurn()) return;
662
+ const text = stream.currentAssistantText;
663
+ if (!text.trim()) return;
664
+ stream.settleStreamingTail(ensureAssistant(stream, text), { text });
520
665
  }
521
666
 
522
667
  export function settleStreamingTailAtClose(stream) {
668
+ settlePartialOnlySegment(stream);
669
+ clearPartial(stream);
523
670
  const id = stream.currentAssistantId;
524
671
  if (!id || stream.getState().streamingTail?.id !== id) return;
525
672
  if (stream.currentAssistantText.trim()) stream.settleStreamingTail(id, { text: stream.currentAssistantText });
@@ -7,18 +7,20 @@
7
7
  * turn record below that finalization publishes as the turndone item.
8
8
  */
9
9
  import { applyUsageDelta } from './session-stats.mjs';
10
+ import {
11
+ createTranscriptRouteMetadata,
12
+ transcriptRouteMetadataFields,
13
+ } from '../../runtime/shared/transcript-metadata.mjs';
14
+ import { publishModelSwitch } from './session-api/routes.mjs';
10
15
  import { compactEventLabel } from '../../runtime/shared/compact-event-label.mjs';
11
16
  import { pickVerb, pickDoneVerb, compactEventDetail } from './labels.mjs';
12
- import { toolErrorDisplay } from './tool-result-text.mjs';
13
- import { errText, isCancelLikeError } from '../../runtime/shared/err-text.mjs';
17
+ import { isCancelLikeError } from '../../runtime/shared/err-text.mjs';
14
18
  import { preserveGoalStateAfterTurn } from './goal-turn-state.mjs';
15
19
  export { preserveGoalStateAfterTurn } from './goal-turn-state.mjs';
16
20
  export { transcriptToolCallDisplayMode } from './turn-tool-cards.mjs';
17
- import { isRejected429, safeErrorDetails } from '../../runtime/shared/error-presentation.mjs';
18
- import {
19
- QUOTA_KINDS,
20
- providerErrorKind,
21
- } from '../../runtime/agent/orchestrator/providers/provider-error-kind.mjs';
21
+ import { isRejected429 } from '../../runtime/shared/error-presentation.mjs';
22
+ import { QUOTA_KINDS, providerErrorKind } from '../../runtime/agent/orchestrator/providers/provider-error-kind.mjs';
23
+ import { turnFailureRecord } from '../../runtime/agent/orchestrator/session/turn-failure.mjs';
22
24
  import { registerTaskWaitSteeringCheck } from '../../runtime/agent/orchestrator/session/task-wait-control.mjs';
23
25
  import { promptDisplayText, STEERING_SUPPRESSED_DISPLAY } from './queue-helpers.mjs';
24
26
  import { yieldToRenderer } from './render-timing.mjs';
@@ -50,6 +52,7 @@ import {
50
52
  collectClosingCards,
51
53
  startLiveTail,
52
54
  } from './turn-tool-cards.mjs';
55
+ import { startQuietWatch } from './turn-quiet.mjs';
53
56
 
54
57
  // A usage limit is exactly a spent quota, a plan-gated feature or a billing
55
58
  // refusal; overloads, rate limits and server faults recover by waiting.
@@ -97,6 +100,13 @@ function streamingTailStore({ updateStreamingTail, settleStreamingTail, clearStr
97
100
 
98
101
  // The turn record: identity, transcript metadata, and the outcome fields
99
102
  // finalization publishes.
103
+ export function applyTurnRouteMetadata(ctx, session) {
104
+ const metadata = transcriptRouteMetadataFields(createTranscriptRouteMetadata(session));
105
+ Object.assign(ctx.turn.transcriptMeta, metadata);
106
+ Object.assign(ctx.turn.routeMeta, metadata);
107
+ for (const id of ctx.turn.submittedIds) ctx.patchItem(id, metadata);
108
+ }
109
+
100
110
  function beginTurn({ flags, getState, transcriptRouteMetadata }, options) {
101
111
  const index = getState().stats.turns || 0;
102
112
  const startedAt = Date.now();
@@ -105,6 +115,7 @@ function beginTurn({ flags, getState, transcriptRouteMetadata }, options) {
105
115
  ...(flags.pendingTranscriptMeta || transcriptRouteMetadata?.(startedAt) || { at: startedAt }),
106
116
  ...(options.transcriptMeta && typeof options.transcriptMeta === 'object' ? options.transcriptMeta : {}),
107
117
  completionVerb,
118
+ attemptId: globalThis.crypto.randomUUID(),
108
119
  };
109
120
  flags.pendingTranscriptMeta = null;
110
121
  // The prompt's own time and stable id stay on the prompt row.
@@ -394,7 +405,15 @@ export function streamHandlers(ctx) {
394
405
  const { isCurrentTurn, stream } = ctx;
395
406
  return {
396
407
  onStageChange: async (stage, detail = null) => {
397
- if (isCurrentTurn()) await applyStageChange(stream, stage, detail);
408
+ if (!isCurrentTurn()) return;
409
+ // A runtime notice (e.g. a tool the provider left out of the request)
410
+ // becomes a transcript notice the TUI and desktop render.
411
+ if (stage === 'notice') {
412
+ flushStreamBatch(stream);
413
+ ctx.pushNotice(detail?.message, detail?.tone === 'warn' ? 'warn' : 'info', { transcript: true });
414
+ return;
415
+ }
416
+ await applyStageChange(stream, stage, detail);
398
417
  },
399
418
  onTextDelta: (chunk) => {
400
419
  const textChunk = String(chunk ?? '');
@@ -452,34 +471,13 @@ export function failTurn(ctx, error) {
452
471
  }
453
472
  turn.failed = true;
454
473
  cards.aggregates.finalizeToolHeaders();
455
- // Presentation only: legacy untyped failure text may still name a usage limit.
456
- const errorKind = providerErrorKind(error, { legacyQuotaWording: true });
474
+ const record = turnFailureRecord(error, { provider: turn.routeMeta?.provider, model: turn.routeMeta?.model });
457
475
  // The UI reads this descriptor instead of re-parsing the error text.
458
- turn.errorKind = {
459
- kind: errorKind.kind,
460
- code: errorKind.code,
461
- status: errorKind.status,
462
- retryAfterMs: errorKind.retryAfterMs,
463
- resetAt: errorKind.resetAt,
464
- };
465
- turn.usageLimited = isUsageLimitError(error, errorKind);
466
- const exhausted = error?.quotaExhausted;
467
- // Quota metadata: the pool's validated exhaustion, or a spent quota whose
468
- // provider named the real reset time.
469
- const resetKnown = errorKind.kind === 'quota_exhausted' && Number.isFinite(errorKind.resetAt);
470
- if ((exhausted && typeof exhausted === 'object') || resetKnown) {
471
- const source = exhausted && typeof exhausted === 'object' ? exhausted : {};
472
- let resetAt = null;
473
- if (Number.isFinite(source.resetAt)) resetAt = source.resetAt;
474
- else if (Number.isFinite(errorKind.resetAt)) resetAt = errorKind.resetAt;
475
- turn.quota = {
476
- provider: String(source.provider || turn.routeMeta?.provider || ''),
477
- model: String(source.model || turn.routeMeta?.model || ''),
478
- resetAt,
479
- };
480
- }
481
- turn.failureDetail = toolErrorDisplay(error, 'turn').replace(/^Error:\s*/i, '');
482
- turn.failureDiagnostic = safeErrorDetails(errText(error));
476
+ turn.errorKind = record.errorKind;
477
+ turn.usageLimited = isUsageLimitError(error, record.providerKind);
478
+ if (record.quota) turn.quota = record.quota;
479
+ turn.failureDetail = record.detail;
480
+ turn.failureDiagnostic = record.errorDetails;
483
481
  pushNotice(turn.failureDetail, 'error', { owner: 'transcript' });
484
482
  }
485
483
 
@@ -649,6 +647,8 @@ export function createRunTurn(bag) {
649
647
  set({
650
648
  busy: true,
651
649
  lastTurn: null,
650
+ // A turn that unwound stale never cleared its desktop partial line.
651
+ ...(getState().streamingPartial ? { streamingPartial: null } : {}),
652
652
  spinner: {
653
653
  active: true,
654
654
  verb: pickVerb(turn.index),
@@ -676,7 +676,12 @@ export function createRunTurn(bag) {
676
676
  routeMeta: turn.routeMeta,
677
677
  sealToolBlock: cards.aggregates.clearAggregateContinuation,
678
678
  });
679
- const stopLiveTail = startLiveTail(cards);
679
+ const stopToolTail = startLiveTail(cards);
680
+ const stopQuietWatch = startQuietWatch({ runtime, getState, set, isCurrentTurn });
681
+ const stopLiveTail = () => {
682
+ stopToolTail();
683
+ stopQuietWatch();
684
+ };
680
685
  const ctx = {
681
686
  ...bag,
682
687
  bag,
@@ -696,11 +701,20 @@ export function createRunTurn(bag) {
696
701
  submittedAt: options.submittedAt,
697
702
  promptSource: options.promptSource,
698
703
  retryFailedTurn: options.retryFailedTurn === true,
704
+ retryTurnId: options.retryTurnId,
705
+ retryAttemptId: options.retryAttemptId,
699
706
  transcriptMeta: turn.transcriptMeta,
700
707
  context: options.context || null,
701
708
  ...turnHandlers(ctx),
702
709
  ...toolHandlers(ctx),
703
710
  ...streamHandlers(ctx),
711
+ onRouteApplied: (session) => {
712
+ if (isCurrentTurn()) applyTurnRouteMetadata(ctx, session);
713
+ },
714
+ onModelSwitch: (boundary) => {
715
+ if (!isCurrentTurn()) return;
716
+ publishModelSwitch(bag, boundary);
717
+ },
704
718
  });
705
719
  if (!isCurrentTurn()) turn.cancelled = true;
706
720
  else completeTurn(ctx, result, session);
@@ -0,0 +1,38 @@
1
+ /**
2
+ * src/tui/session/worktree-setup-notice.mjs - the one-line transcript notice
3
+ * shown while a new worktree's dependencies install (runtime.onWorktreeSetup).
4
+ * Only runs that install anything reach it; one notice per run, patched in
5
+ * place, so every surface showing the transcript (TUI, desktop, remote) sees
6
+ * the same line. The details (output, failures, skips) go to the agent only.
7
+ */
8
+ const ENDINGS = {
9
+ completed: 'Worktree dependencies installed.',
10
+ cancelled: 'Installing worktree dependencies was cancelled.',
11
+ };
12
+ const INCOMPLETE = 'Some worktree dependencies were not installed; the agent has the details.';
13
+
14
+ /** Notice text and tone for one install progress event. */
15
+ export function worktreeSetupNotice(event) {
16
+ if (event.final) {
17
+ const text = ENDINGS[event.status] ?? INCOMPLETE;
18
+ return { text, tone: event.status === 'completed' ? 'info' : 'warn' };
19
+ }
20
+ const what = event.label || event.command;
21
+ return { text: `Installing worktree dependencies [${event.index + 1}/${event.total}]: ${what}`, tone: 'info' };
22
+ }
23
+
24
+ export function createWorktreeSetupNotices({ pushItem, patchItem, nextId }) {
25
+ const items = new Map();
26
+ return (event) => {
27
+ const notice = worktreeSetupNotice(event);
28
+ const itemId = items.get(event.id);
29
+ if (itemId === undefined) {
30
+ const id = nextId();
31
+ items.set(event.id, id);
32
+ pushItem({ kind: 'notice', id, ...notice });
33
+ } else {
34
+ patchItem(itemId, notice);
35
+ }
36
+ if (event.final) items.delete(event.id);
37
+ };
38
+ }
@@ -9,6 +9,8 @@
9
9
  * for 30s. One builder, one answer.
10
10
  */
11
11
 
12
+ import { quietProgressLabel, quietProgressParts } from '../runtime/shared/quiet-progress.mjs';
13
+
12
14
  const compactNumberFormatter = new Intl.NumberFormat('en-US', {
13
15
  notation: 'compact',
14
16
  maximumFractionDigits: 1,
@@ -67,9 +69,13 @@ export function buildSpinnerMeta({
67
69
  thinkingSince = 0,
68
70
  thinkingMs = 0,
69
71
  effort = '',
72
+ // The turn's published quiet state (`spinner.quiet`) and the clock it is read at.
73
+ quiet = null,
74
+ now = Date.now(),
70
75
  verbose: _verbose = false,
71
76
  } = {}) {
72
77
  const tokens = Math.max(0, Number(outputTokens) || 0);
78
+ const quietParts = quietProgressParts(quiet, now, quiet?.warnMs);
73
79
  const thinkingParts = spinnerThinkingParts({ thinking, thinkingSince, thinkingMs, effort });
74
80
  const thinkingText = spinnerThinkingLabel({ thinking, thinkingSince, thinkingMs, effort });
75
81
  return {
@@ -83,6 +89,10 @@ export function buildSpinnerMeta({
83
89
  showTokens: tokens > 0,
84
90
  thinkingText,
85
91
  thinkingActive: Boolean(thinking || Number(thinkingSince) > 0),
92
+ // Quiet-time cue: structured for the desktop's i18n, English for the TUI;
93
+ // `escalated` once the silence reaches the stall watchdog's warn point.
94
+ quietParts,
95
+ quietText: quietProgressLabel(quietParts),
86
96
  };
87
97
  }
88
98
 
@@ -247,6 +247,9 @@ export const SPINNER_MODE_OVERRIDE_VERBS = {
247
247
  'auto-clear': 'Auto-clearing conversation',
248
248
  resuming: 'Resuming conversation',
249
249
  'task-wait': '작업 대기 중',
250
+ // The request is sent and its response headers are pending: the model is
251
+ // queued or thinking server-side.
252
+ 'model-thinking': 'Model thinking',
250
253
  };
251
254
 
252
255
  /**
@@ -31,7 +31,11 @@ import {
31
31
  num,
32
32
  formatElapsed,
33
33
  } from '../runtime/shared/statusline/statusline-format.mjs';
34
- import { shellJobsStatus, memoryCycleStatus } from '../runtime/shared/statusline/statusline-segments.mjs';
34
+ import {
35
+ shellJobsStatus,
36
+ memoryCycleStatus,
37
+ unconfirmedShellCount,
38
+ } from '../runtime/shared/statusline/statusline-segments.mjs';
35
39
  import {
36
40
  agentStatuslinePayload,
37
41
  classifyAgentWorkers,
@@ -397,10 +401,16 @@ function activitySegments({ sessionId, clientHostPid, agentWorkers, agentJobs, a
397
401
  const n = runningWorkers.length;
398
402
  segment(`Running ${n} Agent${n === 1 ? '' : 's'}`, agentsElapsed(runningWorkers));
399
403
  }
400
- if (shellStatus.count > 0) {
401
- const n = shellStatus.count;
404
+ const unconfirmed = unconfirmedShellCount(shellStatus);
405
+ if (shellStatus.count - unconfirmed > 0) {
406
+ const n = shellStatus.count - unconfirmed;
402
407
  segment(`Running ${n} Shell${n === 1 ? '' : 's'}`, shellStatus.elapsedLabel);
403
408
  }
409
+ if (unconfirmed > 0) {
410
+ parts.push(
411
+ `${YLW}⚠ ${unconfirmed} Shell${unconfirmed === 1 ? '' : 's'} termination unconfirmed${R} ${D}·${R} /shells`
412
+ );
413
+ }
404
414
  const webSearch = webSearchActivity(activeTools, { sessionId, clientHostPid });
405
415
  if (webSearch.count > 0) segment('Web Searching', webSearch.elapsed);
406
416
  // Memory cycle segment — single unified "Memory" wording for all states:
@@ -6,7 +6,9 @@ description: "Handle tasks as requested."
6
6
 
7
7
  Consult the user and build the work plan together. Explicit read-only requests
8
8
  proceed immediately. When file edits, state mutation, or delegation are
9
- required, investigate and plan only until the user approves the latest plan.
9
+ required, investigate and plan only until the user approves the latest plan. If the
10
+ plan leaves the user a choice among clear options, ask it with `ask_user`
11
+ before asking for approval.
10
12
 
11
13
  When user input is required, park only the affected work and continue
12
14
  unaffected approved work. Ask pending questions together once no such work
@@ -1 +0,0 @@
1
- export * from '../../../shared/llm/model-pricing-rates.mjs';