mixdog 1.2.1 → 1.2.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 (557) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +19 -3
  4. package/scripts/model-catalog-audit.mjs +1 -15
  5. package/scripts/provider-pingpong-live.mjs +509 -0
  6. package/src/agents/advisor/AGENT.md +1 -1
  7. package/src/agents/advisor/agent.json +1 -1
  8. package/src/agents/reviewer/AGENT.md +3 -3
  9. package/src/agents/reviewer/agent.json +1 -1
  10. package/src/defaults/shipped-history.json +6 -0
  11. package/src/defaults/skills/setup/SKILL.md +6 -1
  12. package/src/defaults/skills/setup/references/actions.md +44 -22
  13. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  14. package/src/headless-exec.mjs +15 -8
  15. package/src/lib/keychain-cjs.cjs +7 -4
  16. package/src/output-styles/common.md +11 -10
  17. package/src/repl/slash-commands.mjs +16 -1
  18. package/src/rules/agent/AGENT.md +5 -5
  19. package/src/rules/lead/LEAD.md +5 -5
  20. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +29 -4
  21. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +10 -0
  22. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  23. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  24. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  25. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  26. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  28. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  29. package/src/runtime/agent/orchestrator/mcp/client-config.mjs +36 -7
  30. package/src/runtime/agent/orchestrator/mcp/client-handshake.mjs +49 -10
  31. package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +40 -3
  32. package/src/runtime/agent/orchestrator/mcp/client.mjs +230 -96
  33. package/src/runtime/agent/orchestrator/mcp/oauth-callback.mjs +103 -0
  34. package/src/runtime/agent/orchestrator/mcp/oauth-credentials.mjs +150 -0
  35. package/src/runtime/agent/orchestrator/mcp/oauth-login.mjs +111 -0
  36. package/src/runtime/agent/orchestrator/mcp/oauth-probe.mjs +87 -0
  37. package/src/runtime/agent/orchestrator/mcp/oauth-provider.mjs +95 -0
  38. package/src/runtime/agent/orchestrator/mcp/oauth-request.mjs +122 -0
  39. package/src/runtime/agent/orchestrator/mcp/oauth-shared.mjs +9 -0
  40. package/src/runtime/agent/orchestrator/mcp/oauth.mjs +229 -0
  41. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +188 -29
  42. package/src/runtime/agent/orchestrator/providers/anthropic-api-recovery.mjs +2 -1
  43. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  44. package/src/runtime/agent/orchestrator/providers/anthropic-api-transport.mjs +94 -31
  45. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +98 -0
  46. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.mjs +39 -18
  47. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens-recovery.mjs +55 -0
  48. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +48 -37
  49. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +10 -7
  50. package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +18 -4
  51. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +13 -1
  52. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-midstream.mjs +10 -1
  54. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-recovery.mjs +23 -9
  55. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/initial-status.mjs +46 -20
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request.mjs +14 -9
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +102 -45
  58. package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +69 -0
  59. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.mjs +4 -0
  60. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  61. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  62. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  63. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  65. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  66. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +10 -1
  68. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +40 -7
  70. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +30 -9
  71. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +7 -0
  72. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +88 -21
  73. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +30 -10
  74. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +106 -0
  75. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +10 -61
  76. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +94 -15
  77. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  79. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  80. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +75 -10
  81. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/providers/cursor-wire-guards.mjs +97 -2
  83. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +103 -23
  84. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +43 -2
  85. package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +103 -33
  86. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +32 -6
  87. package/src/runtime/agent/orchestrator/providers/cursor.mjs +27 -3
  88. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +64 -1
  89. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +70 -6
  90. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  91. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  92. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  93. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +80 -18
  94. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  95. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +46 -8
  96. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +273 -0
  97. package/src/runtime/agent/orchestrator/providers/gemini-family.mjs +9 -0
  98. package/src/runtime/agent/orchestrator/providers/gemini-history-signatures.mjs +9 -4
  99. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  100. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +3 -1
  101. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +180 -0
  102. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +369 -112
  103. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +3 -1
  104. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +140 -35
  105. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +70 -24
  106. package/src/runtime/agent/orchestrator/providers/gemini.mjs +80 -29
  107. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  108. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +3 -0
  109. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +69 -19
  110. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  111. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  112. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +246 -42
  113. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  114. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  115. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +388 -0
  116. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  117. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  118. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  119. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  120. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +48 -22
  121. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +119 -18
  122. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  123. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +3 -0
  124. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +2 -1
  125. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  126. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  127. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +33 -1
  128. package/src/runtime/agent/orchestrator/providers/muse-code-oauth.mjs +4 -9
  129. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +123 -61
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +27 -2
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +37 -7
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +1 -0
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +50 -0
  138. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +47 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  140. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  141. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +151 -0
  142. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +64 -23
  143. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +79 -33
  144. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  145. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +172 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-state.mjs +3 -2
  147. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +144 -15
  148. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +193 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-compat-stream-common.mjs +66 -2
  150. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +9 -2
  151. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  152. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +109 -26
  153. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +27 -6
  154. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +34 -20
  155. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +23 -4
  156. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +37 -28
  157. package/src/runtime/agent/orchestrator/providers/openai-error-contract.mjs +274 -0
  158. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +72 -32
  159. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  160. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +43 -15
  161. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  162. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  163. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +5 -2
  164. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-stamps.mjs +2 -2
  165. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +7 -3
  166. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  167. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state.mjs +2 -2
  168. package/src/runtime/agent/orchestrator/providers/openai-http-sse-watchdogs.mjs +1 -3
  169. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  170. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +37 -4
  171. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +12 -1
  172. package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +22 -2
  173. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +12 -1
  174. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +76 -33
  175. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  176. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +44 -16
  177. package/src/runtime/agent/orchestrator/providers/openai-retry-policy.mjs +9 -0
  178. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -16
  179. package/src/runtime/agent/orchestrator/providers/openai-ws-handshake.mjs +16 -8
  180. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  181. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -35
  182. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  183. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +1 -2
  184. package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/policy.mjs +25 -14
  185. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  186. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  187. package/src/runtime/agent/orchestrator/providers/openai-ws-terminal.mjs +18 -11
  188. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +41 -22
  189. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +170 -0
  190. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +75 -70
  191. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +75 -0
  192. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +720 -0
  193. package/src/runtime/agent/orchestrator/providers/registry.mjs +4 -1
  194. package/src/runtime/agent/orchestrator/providers/retry-backoff.mjs +46 -7
  195. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +123 -219
  196. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -0
  197. package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +148 -45
  198. package/src/runtime/agent/orchestrator/providers/retry-midstream.mjs +81 -16
  199. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  200. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  201. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +157 -0
  202. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +512 -0
  203. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  204. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +183 -0
  205. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +100 -0
  206. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +3 -0
  207. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +21 -0
  208. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  209. package/src/runtime/agent/orchestrator/runtime-core/goal-reminder.mjs +0 -18
  210. package/src/runtime/agent/orchestrator/runtime-core/model-capabilities.mjs +57 -28
  211. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +19 -16
  212. package/src/runtime/agent/orchestrator/runtime-core/plugin-mcp.mjs +1 -97
  213. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  214. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  215. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +14 -3
  216. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  217. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  218. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  219. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +176 -71
  220. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +62 -10
  221. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  222. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -1
  223. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  224. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +14 -93
  225. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  226. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +120 -0
  227. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  228. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  229. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +2 -1
  230. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  231. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +91 -1
  232. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  233. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  234. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  235. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -0
  236. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +21 -10
  237. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +132 -0
  238. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +30 -0
  239. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  240. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +104 -19
  241. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  242. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  243. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -4
  244. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  245. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +150 -0
  246. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -2
  247. package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +30 -2
  248. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +11 -2
  249. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +2 -1
  250. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  251. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +57 -21
  252. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  253. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
  254. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
  255. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  256. package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +5 -10
  257. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +208 -14
  258. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +16 -4
  259. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +25 -3
  260. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  261. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +19 -2
  262. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -0
  263. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  264. package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +18 -7
  265. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -1
  266. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  267. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +168 -29
  268. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  269. package/src/runtime/agent/orchestrator/session/side-question.mjs +192 -0
  270. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +17 -3
  271. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  272. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +58 -2
  273. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +6 -3
  274. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +41 -28
  275. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  276. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +12 -1
  277. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +3 -1
  278. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +16 -0
  279. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +22 -10
  280. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  281. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +6 -0
  282. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +13 -0
  283. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +13 -1
  284. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +10 -2
  285. package/src/runtime/agent/orchestrator/session/store.mjs +19 -3
  286. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +1 -0
  287. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +1 -1
  288. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  289. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  290. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  291. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +77 -0
  292. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +20 -1
  293. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  294. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  295. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  296. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/deadline-plan.mjs +12 -15
  297. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  298. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +5 -5
  299. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +14 -10
  300. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +49 -34
  301. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  302. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  303. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  304. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  305. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  306. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  307. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  308. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  309. package/src/runtime/computer-bridge/action-schema.mjs +44 -21
  310. package/src/runtime/github/tool.mjs +92 -2
  311. package/src/runtime/memory/index.mjs +1 -0
  312. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  313. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  314. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  315. package/src/runtime/memory/lib/pg/process.mjs +65 -50
  316. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  317. package/src/runtime/memory/lib/pg/supervisor.mjs +124 -16
  318. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  319. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  320. package/src/runtime/office/README.md +2 -2
  321. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  322. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  323. package/src/runtime/office/authoring/pptx-html-measure.mjs +2 -0
  324. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  325. package/src/runtime/office/authoring/xlsx-html-runner.mjs +2 -0
  326. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  327. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  328. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  329. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  330. package/src/runtime/office/core/office-sessions.mjs +5 -0
  331. package/src/runtime/office/core/office-transactions.mjs +3 -0
  332. package/src/runtime/office/core/office-write-ledger.mjs +98 -0
  333. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  334. package/src/runtime/office/index.mjs +30 -0
  335. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  336. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  337. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  338. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  339. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  340. package/src/runtime/office/shared/values.mjs +0 -5
  341. package/src/runtime/shared/background-tasks.mjs +92 -14
  342. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  343. package/src/runtime/shared/bounded-line-diff.mjs +182 -0
  344. package/src/runtime/shared/buffered-appender.mjs +18 -0
  345. package/src/runtime/shared/config.mjs +78 -18
  346. package/src/runtime/shared/err-text.mjs +31 -0
  347. package/src/runtime/shared/error-presentation.mjs +159 -19
  348. package/src/runtime/shared/file-permissions.d.mts +6 -1
  349. package/src/runtime/shared/file-permissions.mjs +54 -6
  350. package/src/runtime/shared/llm/anthropic-betas.mjs +4 -3
  351. package/src/runtime/shared/llm/anthropic-effort.mjs +129 -134
  352. package/src/runtime/shared/llm/anthropic-thinking-contract.mjs +50 -14
  353. package/src/runtime/shared/llm/model-catalog.mjs +53 -40
  354. package/src/runtime/shared/llm/openai-daybreak.mjs +4 -16
  355. package/src/runtime/shared/llm/provider-catalog-registry.mjs +11 -0
  356. package/src/runtime/shared/llm/provider-model-identities.mjs +13 -4
  357. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  358. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  359. package/src/runtime/shared/llm/usage-rollup.mjs +0 -1
  360. package/src/runtime/shared/loopback-listener.mjs +9 -0
  361. package/src/runtime/shared/model-display.mjs +13 -0
  362. package/src/runtime/shared/provider-api-key.mjs +2 -0
  363. package/src/runtime/shared/quota-resume-store.mjs +11 -0
  364. package/src/runtime/shared/review-diff.mjs +52 -0
  365. package/src/runtime/shared/session-baseline-store.mjs +960 -0
  366. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  367. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  368. package/src/runtime/shared/slow-span.mjs +114 -0
  369. package/src/runtime/shared/statusline/statusline-format.mjs +4 -4
  370. package/src/runtime/shared/statusline/statusline-segments.mjs +28 -4
  371. package/src/runtime/shared/task-notification-envelope.mjs +2 -2
  372. package/src/runtime/shared/tool-card-model/card-header.mjs +6 -1
  373. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  374. package/src/runtime/shared/tool-card-model.mjs +5 -2
  375. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  376. package/src/runtime/shared/tool-primitives.mjs +13 -0
  377. package/src/runtime/shared/tool-result-summary.mjs +8 -1
  378. package/src/runtime/shared/tool-surface.mjs +18 -3
  379. package/src/runtime/shared/tool-work-units.mjs +40 -4
  380. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  381. package/src/runtime/shared/transcript-writer.mjs +10 -2
  382. package/src/runtime/shared/turn-changes.mjs +670 -274
  383. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  384. package/src/runtime/shared/turn-snapshot-store.mjs +94 -2
  385. package/src/runtime/shared/turn-snapshot.mjs +986 -690
  386. package/src/runtime/shared/turn-worktree-snapshot.mjs +279 -262
  387. package/src/runtime/shared/user-data-guard.mjs +262 -49
  388. package/src/runtime/shared/worktrees/carry.mjs +531 -0
  389. package/src/runtime/shared/worktrees/contract.mjs +34 -24
  390. package/src/runtime/shared/worktrees/file-recovery.mjs +68 -0
  391. package/src/runtime/shared/worktrees/git-head.mjs +205 -0
  392. package/src/runtime/shared/worktrees/git.mjs +8 -3
  393. package/src/runtime/shared/worktrees/maintenance.mjs +1 -1
  394. package/src/runtime/shared/worktrees/manager.mjs +156 -8
  395. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  396. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  397. package/src/runtime/shared/worktrees/test-support.mjs +19 -4
  398. package/src/runtime/terminal-bridge/client.mjs +44 -11
  399. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  400. package/src/runtime/tidy/apply.mjs +47 -2
  401. package/src/runtime/tidy/run-engines.mjs +11 -5
  402. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  403. package/src/session-runtime/boot/apis.mjs +19 -5
  404. package/src/session-runtime/boot/facade.mjs +1 -0
  405. package/src/session-runtime/boot/infrastructure.mjs +12 -1
  406. package/src/session-runtime/boot/session.mjs +0 -1
  407. package/src/session-runtime/boot/tools.mjs +4 -1
  408. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  409. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +65 -0
  410. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  411. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +11 -4
  412. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +115 -18
  413. package/src/session-runtime/internal-tool-executor.mjs +6 -2
  414. package/src/session-runtime/lifecycle/cold-heir.mjs +188 -0
  415. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  416. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -3
  417. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  418. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +29 -6
  419. package/src/session-runtime/lifecycle/teardown.mjs +73 -8
  420. package/src/session-runtime/lifecycle-api.mjs +1 -0
  421. package/src/session-runtime/mcp-glue/connect.mjs +46 -14
  422. package/src/session-runtime/mcp-glue/server-catalog.mjs +20 -3
  423. package/src/session-runtime/mcp-glue.mjs +3 -0
  424. package/src/session-runtime/mcp-oauth-login.mjs +174 -0
  425. package/src/session-runtime/model-route/model-switch-target.mjs +34 -0
  426. package/src/session-runtime/model-route/set-route.mjs +85 -17
  427. package/src/session-runtime/model-route/web-search-route.mjs +1 -1
  428. package/src/session-runtime/native-web-search/routes.mjs +22 -3
  429. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  430. package/src/session-runtime/native-web-search.mjs +10 -1
  431. package/src/session-runtime/new-session-config.mjs +4 -2
  432. package/src/session-runtime/provider-auth/login.mjs +4 -0
  433. package/src/session-runtime/provider-models/model-meta.mjs +12 -3
  434. package/src/session-runtime/quick-model-rows/web-search-rows.mjs +13 -8
  435. package/src/session-runtime/quick-web-search-models.mjs +13 -38
  436. package/src/session-runtime/resource-extension-sync.mjs +4 -0
  437. package/src/session-runtime/resource-mcp-api.mjs +98 -2
  438. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  439. package/src/session-runtime/runtime-review-api.mjs +21 -2
  440. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  441. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +13 -1
  442. package/src/session-runtime/services/agent-tool/job-views/agent-list.mjs +7 -2
  443. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  444. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  445. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +73 -7
  446. package/src/session-runtime/services/agent-tool/send-flow.mjs +22 -4
  447. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +2 -0
  448. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +22 -5
  449. package/src/session-runtime/services/agent-tool/tag-registry.mjs +15 -1
  450. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +8 -1
  451. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -2
  452. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  453. package/src/session-runtime/services/agent-tool/worker-index.mjs +46 -7
  454. package/src/session-runtime/services/agent-tool/worker-rows.mjs +17 -0
  455. package/src/session-runtime/services/agent-tool.mjs +3 -0
  456. package/src/session-runtime/services/channel-admin.mjs +19 -3
  457. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  458. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  459. package/src/session-runtime/services/provider-admin.mjs +81 -15
  460. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  461. package/src/session-runtime/session-turn-api.mjs +14 -5
  462. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -0
  463. package/src/session-runtime/settings-compaction-api.mjs +1 -0
  464. package/src/session-runtime/setup-tool/executor.mjs +36 -6
  465. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  466. package/src/session-runtime/setup-tool/settings-contract.mjs +13 -3
  467. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -4
  468. package/src/session-runtime/skills-api.mjs +3 -5
  469. package/src/session-runtime/tool-surface.mjs +5 -1
  470. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  471. package/src/session-runtime/turn/session-ops.mjs +7 -5
  472. package/src/session-runtime/turn/side-question-ops.mjs +22 -0
  473. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +5 -1
  474. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +8 -3
  475. package/src/session-runtime/turn/turn-run/turn-settle.mjs +10 -0
  476. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  477. package/src/session-runtime/turn/turn-run.mjs +25 -9
  478. package/src/session-runtime/usage-stats-api.mjs +43 -11
  479. package/src/session-runtime/workspace/project-branches.mjs +7 -5
  480. package/src/session-runtime/workspace/transition-steps.mjs +129 -31
  481. package/src/session-runtime/workspace/transitions.mjs +190 -15
  482. package/src/standalone/daemon-agent-control.mjs +9 -1
  483. package/src/standalone/daemon-drain-policy.mjs +8 -0
  484. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  485. package/src/standalone/daemon-owner.mjs +17 -4
  486. package/src/standalone/daemon-pg-stop.mjs +51 -0
  487. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  488. package/src/standalone/daemon-stop-budget.mjs +18 -0
  489. package/src/standalone/daemon-stored-session-views.mjs +2 -0
  490. package/src/standalone/daemon-telemetry.mjs +74 -0
  491. package/src/standalone/daemon.mjs +64 -8
  492. package/src/standalone/desktop-service-registry.mjs +5 -0
  493. package/src/standalone/local-session-runtime.mjs +70 -19
  494. package/src/standalone/session-client.mjs +42 -0
  495. package/src/standalone/session-protocol.mjs +14 -0
  496. package/src/standalone/session-proxy/projection.mjs +41 -4
  497. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  498. package/src/standalone/session-runtime-inline-host.mjs +1 -0
  499. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +33 -2
  500. package/src/standalone/session-service/agent-tree/agent-turns.mjs +26 -10
  501. package/src/standalone/session-service/agent-tree.mjs +12 -0
  502. package/src/standalone/session-service/quota-resume.mjs +8 -0
  503. package/src/standalone/session-service/retention/busy.mjs +15 -1
  504. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  505. package/src/standalone/session-service-api.mjs +11 -1
  506. package/src/standalone/session-service.mjs +1 -0
  507. package/src/standalone/session-state-patch.d.mts +2 -1
  508. package/src/standalone/session-state-patch.mjs +41 -1
  509. package/src/tui/App.jsx +25 -0
  510. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  511. package/src/tui/app/app-view.jsx +1 -0
  512. package/src/tui/app/btw-controller.mjs +118 -0
  513. package/src/tui/app/create-app-pickers.mjs +6 -0
  514. package/src/tui/app/extension-pickers/mcp-login.mjs +107 -0
  515. package/src/tui/app/extension-pickers/mcp-servers-picker.mjs +2 -1
  516. package/src/tui/app/extension-pickers.mjs +2 -1
  517. package/src/tui/app/model-options.mjs +11 -16
  518. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  519. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  520. package/src/tui/app/slash-commands.mjs +20 -5
  521. package/src/tui/app/slash-dispatch/panel-commands.mjs +16 -1
  522. package/src/tui/app/slash-dispatch/session-commands.mjs +19 -6
  523. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  524. package/src/tui/app/use-global-key-input.mjs +5 -12
  525. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  526. package/src/tui/components/BtwPanel.jsx +53 -0
  527. package/src/tui/components/QuestionPanel.jsx +275 -0
  528. package/src/tui/components/StatusLine.jsx +2 -0
  529. package/src/tui/components/question-panel-model.mjs +156 -0
  530. package/src/tui/components/status-line/local-line.mjs +5 -2
  531. package/src/tui/components/status-line/use-statusline-text.mjs +7 -1
  532. package/src/tui/dist/index.mjs +3221 -1500
  533. package/src/tui/session/context-state.mjs +4 -2
  534. package/src/tui/session/quota-resume.mjs +46 -14
  535. package/src/tui/session/session-api/commands.mjs +43 -24
  536. package/src/tui/session/session-api/controls.mjs +2 -2
  537. package/src/tui/session/session-api/extensions.mjs +22 -0
  538. package/src/tui/session/session-api/integrations.mjs +16 -2
  539. package/src/tui/session/session-api/lifecycle/dispose.mjs +1 -0
  540. package/src/tui/session/session-api/lifecycle.mjs +7 -2
  541. package/src/tui/session/session-api/routes.mjs +71 -7
  542. package/src/tui/session/session-api/settings.mjs +11 -14
  543. package/src/tui/session/session-api.mjs +1 -0
  544. package/src/tui/session/session-flow/drain.mjs +7 -1
  545. package/src/tui/session/session-flow/failed-turn-rewind.mjs +10 -4
  546. package/src/tui/session/tool-approval.mjs +10 -7
  547. package/src/tui/session/transcript-spill.mjs +14 -7
  548. package/src/tui/session/turn-stream.mjs +174 -31
  549. package/src/tui/session/turn.mjs +46 -16
  550. package/src/tui/statusline-ansi-bridge.mjs +1 -1
  551. package/src/ui/statusline-agents.mjs +15 -4
  552. package/src/ui/statusline.mjs +7 -3
  553. package/src/ui/streaming-markdown-heal.mjs +34 -3
  554. package/src/vendor/statusline/src/gateway/claude-current.mjs +14 -4
  555. package/src/workflows/default/WORKFLOW.md +3 -1
  556. package/src/runtime/memory/lib/memory-session-merge.mjs +0 -32
  557. package/src/runtime/shared/llm/usage-session-history.mjs +0 -266
@@ -10,7 +10,6 @@ export function createSessionOps(deps) {
10
10
  const {
11
11
  getSession,
12
12
  setSession,
13
- getCurrentCwd,
14
13
  setMode,
15
14
  getActiveTurnCount,
16
15
  mgr,
@@ -18,7 +17,7 @@ export function createSessionOps(deps) {
18
17
  agentTool,
19
18
  invalidatePreSessionToolSurface,
20
19
  refreshEmptySessionToolPolicy,
21
- applyResolvedCwd,
20
+ switchProject,
22
21
  resolveCwdPath,
23
22
  agentStatusState,
24
23
  getReservedSessionId,
@@ -122,9 +121,12 @@ export function createSessionOps(deps) {
122
121
  return { messageCount: list.length, messages: list.slice(start) };
123
122
  }
124
123
 
125
- function setCwd(path) {
126
- applyResolvedCwd(resolveCwdPath(path), { persistProjectSelection: true });
127
- return getCurrentCwd();
124
+ // The desktop/remote Project switch: refused while a turn runs or the
125
+ // session works in a managed worktree (switchProject); resolves once the
126
+ // prompt refresh landed. Its target is a registered Project or the task
127
+ // workspace, classified by desktop membership.
128
+ async function setCwd(path) {
129
+ return switchProject(resolveCwdPath(path), { classifyByMembership: true });
128
130
  }
129
131
 
130
132
  return {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * src/session-runtime/turn/side-question-ops.mjs - /btw side questions on the
3
+ * runtime's current session. They run beside an in-progress turn and touch no
4
+ * session state (see orchestrator/session/side-question.mjs).
5
+ */
6
+ import {
7
+ askSideQuestion,
8
+ cancelSideQuestion,
9
+ } from '../../runtime/agent/orchestrator/session/side-question.mjs';
10
+
11
+ export function createSideQuestionOps({ getSession, getReservedSessionId }) {
12
+ const sessionId = () => getSession()?.id || getReservedSessionId?.() || '';
13
+ return {
14
+ /** @returns {Promise<{ text: string }>} */
15
+ askSide: (question) => askSideQuestion(sessionId(), question),
16
+ /** Abort the side question of `targetSessionId` (the session it was
17
+ * asked in), or of the current session when omitted. */
18
+ cancelSide: (targetSessionId) => {
19
+ cancelSideQuestion(typeof targetSessionId === 'string' && targetSessionId ? targetSessionId : sessionId());
20
+ },
21
+ };
22
+ }
@@ -1,4 +1,5 @@
1
1
  import { isVisibleStreamProgress } from '../../../runtime/shared/stream-progress.mjs';
2
+ import { toolCallDisplayIdentity } from '../../../runtime/shared/tool-primitives.mjs';
2
3
 
3
4
  // The askSession callback bridge: caller callbacks pass through, with the
4
5
  // transcript, first-visible timing, title release and warmup arming folded in.
@@ -6,10 +7,13 @@ export function createAskCallbacks({ transcript, notifyFnForSession, scheduleSea
6
7
  function plannedToolCalls(session0, options) {
7
8
  return async (iter, calls) => {
8
9
  for (const call of calls || []) {
10
+ // A bridged call reports the tool it runs; the transcript keeps the wire call.
11
+ const identity = toolCallDisplayIdentity(call?.name, call?.arguments);
9
12
  hooks.emit('tool:planned', {
10
13
  sessionId: session0.id,
11
- name: call?.name || 'tool',
14
+ name: identity.name || 'tool',
12
15
  callId: call?.id || null,
16
+ ...(identity.via ? { via: identity.via } : {}),
13
17
  });
14
18
  }
15
19
  if (typeof options.onToolCall === 'function') {
@@ -49,9 +49,9 @@ export function createTurnPreparation({
49
49
  // Slower servers remain available through the late-tool path; a reconnect
50
50
  // in flight gets the same short TTFT grace BEFORE folding the catalog so it
51
51
  // cannot hold the provider request. No reconnect in flight → no-op.
52
- const awaitGrace = async () => {
52
+ const awaitGrace = async (options) => {
53
53
  try {
54
- await turn.awaitTurn(() => turn.timing.awaitMcpGrace());
54
+ await turn.awaitTurn(() => turn.timing.awaitMcpGrace(options));
55
55
  } catch {
56
56
  /* gate must never break the turn */
57
57
  }
@@ -64,7 +64,12 @@ export function createTurnPreparation({
64
64
  // One-shot: cleared before the fold so a throw still never re-runs it,
65
65
  // and a resumed session (flag unset) skips straight to the late path.
66
66
  session0.deferredInitialRefreshPending = false;
67
- await awaitGrace();
67
+ // A spawned agent runtime owns a fresh MCP scope whose connect starts at
68
+ // its boot, so the 0 ms default grace would hide every MCP tool from the
69
+ // agent's first (often only) turn. Agents are not on the user's TTFT
70
+ // path: wait for the initial connect within the server startup budget.
71
+ const agentOwned = session0.owner === 'agent' || session0.visibility === 'agent-only';
72
+ await awaitGrace({ untilConnected: agentOwned });
68
73
  try {
69
74
  refreshInitialDeferredMcpSurface(session0, scopedMcpTools(session0));
70
75
  } catch {
@@ -28,6 +28,8 @@ export function createTurnSettlement({
28
28
  setFirstTurnCompleted,
29
29
  scheduleProviderWarmup,
30
30
  scheduleProviderModelWarmup,
31
+ takePendingCompact,
32
+ runPendingCompact,
31
33
  }) {
32
34
  async function completeTurn(turn, session0, result) {
33
35
  throwIfAborted(turn.signal);
@@ -99,6 +101,14 @@ export function createTurnSettlement({
99
101
  /* lead pool must never break turn teardown */
100
102
  }
101
103
  setActiveTurnCount(Math.max(0, getActiveTurnCount() - 1));
104
+ // A compaction the model scheduled (session tool) runs once the turn is over.
105
+ // Only while the settled session is still the live one; otherwise it stays
106
+ // pending for that session and never compacts another. The runner chains
107
+ // the compaction so the next turn waits on it.
108
+ const settledId = turn.session0?.id;
109
+ if (getActiveTurnCount() === 0 && settledId && getSession()?.id === settledId && takePendingCompact?.(settledId)) {
110
+ runPendingCompact?.(settledId);
111
+ }
102
112
  if (!isFirstTurnCompleted()) {
103
113
  setFirstTurnCompleted(true);
104
114
  scheduleProviderWarmup();
@@ -38,11 +38,12 @@ export function createTurnTimingFactory({ getSession, awaitInitialMcpConnect, mc
38
38
  /* timing telemetry must never affect a turn */
39
39
  }
40
40
  };
41
- // Give an in-flight MCP connect only a short TTFT grace.
42
- timing.awaitMcpGrace = async () => {
41
+ // Give an in-flight MCP connect only a short TTFT grace. untilConnected
42
+ // waits for the initial connect bounded only by the server startup budget.
43
+ timing.awaitMcpGrace = async ({ untilConnected = false } = {}) => {
43
44
  const graceStartedAt = performance.now();
44
45
  try {
45
- await awaitInitialMcpConnect?.(mcpTurnGraceMs);
46
+ await awaitInitialMcpConnect?.(untilConnected ? undefined : mcpTurnGraceMs);
46
47
  } finally {
47
48
  timing.mcpWaitMs += performance.now() - graceStartedAt;
48
49
  }
@@ -13,6 +13,7 @@ import { createSnapshotTrackerFactory } from './turn-run/snapshot-tracker.mjs';
13
13
  import { createTurnOpener } from './turn-run/turn-open.mjs';
14
14
  import { createTurnPreparation } from './turn-run/turn-prepare.mjs';
15
15
  import { createAskCallbacks } from './turn-run/ask-callbacks.mjs';
16
+ import { registerNativeWebSearchUsageSink } from '../native-web-search-usage.mjs';
16
17
  import { createTurnSettlement } from './turn-run/turn-settle.mjs';
17
18
 
18
19
  export function createTurnRunner(deps) {
@@ -94,15 +95,30 @@ export function createTurnRunner(deps) {
94
95
  try {
95
96
  const session0 = await prepareSession(turn, prompt, options);
96
97
  const turnContext = await dispatchPromptSubmit(turn, session0, prompt, options);
97
- const result = await mgr.askSession(
98
- session0.id,
99
- prompt,
100
- turnContext || null,
101
- plannedToolCalls(session0, options),
102
- getCurrentCwd(),
103
- options.prefetch || null,
104
- askCallbacks(turn, session0, options)
105
- );
98
+ const callbacks = askCallbacks(turn, session0, options);
99
+ // Register only once askSession's session lock is held: the first
100
+ // provider send of this turn. A turn queued behind another on the same
101
+ // session id therefore never receives the running turn's search usage.
102
+ let releaseWebSearchUsage = null;
103
+ const providerSendStarted = callbacks.onProviderSendStarted;
104
+ callbacks.onProviderSendStarted = (...args) => {
105
+ releaseWebSearchUsage ??= registerNativeWebSearchUsageSink(session0.id, options.onNativeWebSearchUsage);
106
+ return providerSendStarted(...args);
107
+ };
108
+ let result;
109
+ try {
110
+ result = await mgr.askSession(
111
+ session0.id,
112
+ prompt,
113
+ turnContext || null,
114
+ plannedToolCalls(session0, options),
115
+ getCurrentCwd(),
116
+ options.prefetch || null,
117
+ callbacks
118
+ );
119
+ } finally {
120
+ releaseWebSearchUsage?.();
121
+ }
106
122
  return await completeTurn(turn, session0, result);
107
123
  } catch (error) {
108
124
  reportTurnError(turn, error);
@@ -82,22 +82,43 @@ function accountsInUse(accountPool) {
82
82
  return inUse;
83
83
  }
84
84
 
85
- // Every id a session's spend was recorded under: its own, and the per-account
86
- // provider session each subscription account sent it under before account
87
- // sends recorded the visible session.
88
- function sessionUsageIds(sessionId, accountPool) {
89
- const ids = [sessionId];
85
+ // Each subscription provider's account ids, read once per request.
86
+ function accountScopes(accountPool) {
87
+ const scopes = [];
90
88
  for (const provider of ACCOUNT_PROVIDERS) {
91
89
  try {
92
- for (const account of accountPool(provider).accounts)
93
- ids.push(accountScopedSessionId(provider, account.id, sessionId));
90
+ scopes.push([provider, accountPool(provider).accounts.map((account) => account.id)]);
94
91
  } catch {
95
92
  /* an unreadable pool leaves that provider's older records out */
96
93
  }
97
94
  }
95
+ return scopes;
96
+ }
97
+
98
+ // Every id a session's spend was recorded under: its own, and the per-account
99
+ // provider session each subscription account sent it under before account
100
+ // sends recorded the visible session.
101
+ function sessionUsageIdsFor(scopes, sessionId) {
102
+ const ids = [sessionId];
103
+ for (const [provider, accounts] of scopes) {
104
+ for (const account of accounts) ids.push(accountScopedSessionId(provider, account, sessionId));
105
+ }
98
106
  return ids;
99
107
  }
100
108
 
109
+ // Other sessions a caller asks about beside its own (the composer island's
110
+ // agent sessions): bounded, distinct, never the caller's own id.
111
+ const MAX_SESSION_USAGE_IDS = 64;
112
+ function otherSessionIds(options, sessionId) {
113
+ const ids = Array.isArray(options?.sessionIds) ? options.sessionIds : [];
114
+ const unique = new Set();
115
+ for (const id of ids) {
116
+ if (typeof id === 'string' && id && id !== sessionId) unique.add(id);
117
+ if (unique.size >= MAX_SESSION_USAGE_IDS) break;
118
+ }
119
+ return [...unique];
120
+ }
121
+
101
122
  /** `null` = all time. `0` = today. Anything else is a trailing day count. */
102
123
  function normalizeDays(value) {
103
124
  if (value === null || value === undefined || value === 'all') return null;
@@ -213,15 +234,26 @@ export function createUsageStatsApi({
213
234
  return snapshot;
214
235
  },
215
236
 
216
- /** This runtime's session from its first request, compactions included; null before it has one. */
217
- async getSessionUsage() {
237
+ /**
238
+ * This runtime's session from its first request, compactions included; null before it has one.
239
+ * `sessionIds` adds the same totals for each named session (the agents it spawned) under
240
+ * `sessions`, each read by its own id only.
241
+ */
242
+ async getSessionUsage(options = {}) {
218
243
  const sessionId = getSessionId();
219
244
  if (!sessionId) return null;
220
245
  const store = ledger();
221
246
  if (!store) throw new Error('Usage ledger is unavailable');
222
247
  await store.settleWrites();
223
- const usage = await store.sessionUsageAsync(sessionUsageIds(sessionId, accountPool));
224
- return { sessionId, ...sessionUsageSnapshot(usage) };
248
+ const scopes = accountScopes(accountPool);
249
+ const usage = await store.sessionUsageAsync(sessionUsageIdsFor(scopes, sessionId));
250
+ const result = { sessionId, ...sessionUsageSnapshot(usage) };
251
+ const others = otherSessionIds(options, sessionId);
252
+ if (!others.length) return result;
253
+ const totals = await Promise.all(
254
+ others.map(async (id) => [id, sessionUsageSnapshot(await store.sessionUsageAsync(sessionUsageIdsFor(scopes, id)))])
255
+ );
256
+ return { ...result, sessions: Object.fromEntries(totals) };
225
257
  },
226
258
 
227
259
  /**
@@ -54,12 +54,14 @@ export function createProjectBranchOps({ backend, inspectProject, findRegistered
54
54
  const path = await registeredProject(projectPath);
55
55
  const project = await inspectProject(path);
56
56
  const menu = await (await backend()).listBranchOccupancy({ projectPath: path, sessionId: null });
57
+ const workspace = projectWorkspace({
58
+ projectPath: path,
59
+ repoCommonDir: project.repoCommonDir,
60
+ branch: project.currentBranch,
61
+ });
57
62
  return {
58
- workspace: projectWorkspace({
59
- projectPath: path,
60
- repoCommonDir: project.repoCommonDir,
61
- branch: project.currentBranch,
62
- }),
63
+ // Detached: branch null and the checked-out commit in baseCommit.
64
+ workspace: project.currentBranch ? workspace : { ...workspace, baseCommit: project.headCommit ?? null },
63
65
  branches: branchMenuEntries(menu.branches, menu.occupancy),
64
66
  occupancy: menu.occupancy,
65
67
  retainedWorktree: null,
@@ -18,7 +18,9 @@ import { checkoutFolder, projectSubdirOf, samePath } from '../../runtime/shared/
18
18
  import { setWorkspaceCwdLock, workspaceCwdLock } from './admission-gate.mjs';
19
19
  import { copyProjectIdentity } from './workspace-state.mjs';
20
20
 
21
- const PROMPT_FIELDS = ['bp3EnvironmentContext', 'bp3CoreContext', 'sessionStartMetaInjected'];
21
+ // workspaceReroot: the staged working-folder change and its pending notice
22
+ // (prompt-utils stageWorkspaceReroot); a rollback drops the notice with it.
23
+ const PROMPT_FIELDS = ['bp3EnvironmentContext', 'bp3CoreContext', 'sessionStartMetaInjected', 'workspaceReroot'];
22
24
 
23
25
  /** Everything a prompt refresh rewrites on `target`, restorable exactly. */
24
26
  function snapshotPrompt(target) {
@@ -90,6 +92,8 @@ export function createTransitionSteps({
90
92
  inspectProject,
91
93
  runtimeToken,
92
94
  getCurrentCwd,
95
+ getDesktopSession,
96
+ setDesktopSession,
93
97
  applyResolvedCwd,
94
98
  persistSession,
95
99
  refreshWorkspaceContext,
@@ -97,11 +101,19 @@ export function createTransitionSteps({
97
101
  updateLeadWorkerCwd,
98
102
  workersOf,
99
103
  withProjectFolder,
104
+ assertCheckoutQuiet = async () => {},
100
105
  }) {
101
106
  const owner = (sessionId) => ({ sessionId, runtimeToken, pid: process.pid });
107
+ const moveLeadRow = (sessionId, cwd) => {
108
+ try {
109
+ updateLeadWorkerCwd(sessionId, cwd);
110
+ } catch {
111
+ /* the Lead pool must never break a transition */
112
+ }
113
+ };
102
114
 
103
115
  /** Point this Lead's idle workers at the new root so a reused worker never keeps an old workspace. */
104
- async function retargetWorkers(session, cwd, journal) {
116
+ async function retargetWorkers(session, cwd, journal, move = null) {
105
117
  for (const worker of workersOf(session)) {
106
118
  if (samePath(worker.cwd || '', cwd)) continue;
107
119
  const priorCwd = worker.cwd;
@@ -113,7 +125,7 @@ export function createTransitionSteps({
113
125
  persistSession(worker);
114
126
  });
115
127
  worker.cwd = cwd;
116
- await refreshWorkspaceContext(worker, cwd);
128
+ await refreshWorkspaceContext(worker, cwd, move);
117
129
  worker.updatedAt = Date.now();
118
130
  persistSession(worker);
119
131
  }
@@ -123,16 +135,10 @@ export function createTransitionSteps({
123
135
  * Apply the new workspace: runtime cwd, record, worker lock, prompt context
124
136
  * of the Lead and its idle workers, persistence. Journals the exact undo
125
137
  * (cwd, record, lock, prompts, worker roots) for a transaction that fails
126
- * after this point.
138
+ * after this point. `move` ({ from, changes }: a move out of the project
139
+ * folder into a worktree) extends the prompt's working-folder notice.
127
140
  */
128
- async function commit(session, previous, fields, journal) {
129
- const moveLeadRow = (cwd) => {
130
- try {
131
- updateLeadWorkerCwd(session.id, cwd);
132
- } catch {
133
- /* the Lead pool must never break a transition */
134
- }
135
- };
141
+ async function commit(session, previous, fields, journal, move = null) {
136
142
  const next = normalizeSessionWorkspace({
137
143
  ...fields,
138
144
  revision: nextRevision(previous),
@@ -153,22 +159,70 @@ export function createTransitionSteps({
153
159
  prior.prompt();
154
160
  session.updatedAt = Date.now();
155
161
  persistSession(session);
156
- moveLeadRow(prior.sessionCwd || prior.cwd);
162
+ moveLeadRow(session.id, prior.sessionCwd || prior.cwd);
157
163
  invalidateCaches();
158
164
  });
159
165
  applyResolvedCwd(next.cwd);
160
166
  session.cwd = next.cwd;
161
167
  session.workspace = next;
162
- moveLeadRow(next.cwd);
168
+ moveLeadRow(session.id, next.cwd);
163
169
  setWorkspaceCwdLock(session.id, isWorktreeBound(next) ? next.cwd : null);
164
- await refreshWorkspaceContext(session, next.cwd);
165
- await retargetWorkers(session, next.cwd, journal);
170
+ await refreshWorkspaceContext(session, next.cwd, move);
171
+ await retargetWorkers(session, next.cwd, journal, move);
166
172
  session.updatedAt = Date.now();
167
- persistSession(session);
173
+ // Awaited: a failed save fails the transaction (and its journal undoes it).
174
+ await persistSession(session);
168
175
  invalidateCaches();
169
176
  return { revision: next.revision, workspace: next };
170
177
  }
171
178
 
179
+ /**
180
+ * A Project switch (session set-project, the desktop/remote setCwd): the
181
+ * runtime cwd, session.cwd, workspace record and desktop classification
182
+ * move together (applyResolvedCwd with persistProjectSelection), then the
183
+ * prompt context of the Lead and its idle workers follows, awaited, before
184
+ * the switch completes. Journals the exact undo, so a failed refresh puts
185
+ * everything back and the failure reaches the caller.
186
+ */
187
+ async function switchProject(session, cwd, journal, { classifyByMembership = false } = {}) {
188
+ const sessionFields = ['cwd', 'workspace', 'desktopSession'].map((name) => [
189
+ name,
190
+ Object.hasOwn(session, name),
191
+ session[name],
192
+ ]);
193
+ const prior = {
194
+ cwd: getCurrentCwd(),
195
+ desktop: getDesktopSession(),
196
+ lock: workspaceCwdLock([session.id]),
197
+ prompt: snapshotPrompt(session),
198
+ };
199
+ journal.push(() => {
200
+ applyResolvedCwd(prior.cwd);
201
+ for (const [name, had, value] of sessionFields) {
202
+ if (had) session[name] = value;
203
+ else delete session[name];
204
+ }
205
+ setDesktopSession(prior.desktop);
206
+ setWorkspaceCwdLock(session.id, prior.lock);
207
+ prior.prompt();
208
+ session.updatedAt = Date.now();
209
+ persistSession(session);
210
+ moveLeadRow(session.id, session.cwd || prior.cwd);
211
+ invalidateCaches();
212
+ });
213
+ const changed = !samePath(prior.cwd || '', cwd);
214
+ applyResolvedCwd(cwd, { persistProjectSelection: true, classifyByMembership });
215
+ if (changed) {
216
+ moveLeadRow(session.id, cwd);
217
+ await refreshWorkspaceContext(session, cwd);
218
+ await retargetWorkers(session, cwd, journal);
219
+ session.updatedAt = Date.now();
220
+ persistSession(session);
221
+ }
222
+ invalidateCaches();
223
+ return { cwd: getCurrentCwd(), workspace: session.workspace ?? null };
224
+ }
225
+
172
226
  async function releaseOwner(backendApi, entryId, sessionId) {
173
227
  try {
174
228
  await backendApi.releaseWorktreeOwner(entryId, owner(sessionId));
@@ -178,7 +232,14 @@ export function createTransitionSteps({
178
232
  }
179
233
  }
180
234
 
181
- async function enterWorktree(session, previous, { name, nameHint, confirmLarge, signal, txId, journal }) {
235
+ /**
236
+ * `changes` (a new worktree only): the project folder's uncommitted
237
+ * changes — `ask` refuses with WORKTREE_DIRTY_CHOICE while there are any,
238
+ * `leave` keeps them there, `carry` moves them into the worktree while the
239
+ * project folder is held (refused while other sessions work in it);
240
+ * omitted, they are not examined (lazy provisioning).
241
+ */
242
+ async function enterWorktree(session, previous, { name, nameHint, confirmLarge, changes, signal, txId, journal }) {
182
243
  const backendApi = await backend();
183
244
  const projectPath = previous.projectPath;
184
245
  const project = await inspectProject(projectPath, { signal });
@@ -197,16 +258,39 @@ export function createTransitionSteps({
197
258
  // The backend resolves the base branch commit (from the project
198
259
  // folder's checked-out branch), sizes and creates the checkout; the
199
260
  // txId makes a retried or duplicate send return the same worktree.
200
- entry = await backendApi.createManagedWorktree({
201
- projectPath,
202
- sessionId: session.id,
203
- runtimeToken,
204
- baseBranch: project.currentBranch,
205
- nameHint: name ?? nameHint ?? '',
206
- confirmLarge: confirmLarge === true,
207
- txId,
208
- signal,
209
- });
261
+ const create = () =>
262
+ backendApi.createManagedWorktree({
263
+ projectPath,
264
+ sessionId: session.id,
265
+ runtimeToken,
266
+ baseBranch: project.currentBranch,
267
+ nameHint: name ?? nameHint ?? '',
268
+ confirmLarge: confirmLarge === true,
269
+ txId,
270
+ signal,
271
+ carryChanges: changes ?? null,
272
+ });
273
+ // A carry clears the project folder: it is held, and every session
274
+ // sharing it must be quiet (no turn, agents or background shells).
275
+ entry =
276
+ changes === 'carry'
277
+ ? await withProjectFolder(session.id, project.topLevel || projectPath, async () => {
278
+ await assertCheckoutQuiet(session, project.topLevel || projectPath);
279
+ return create();
280
+ })
281
+ : await create();
282
+ const recoveryRef = entry.changes?.recoveryRef;
283
+ if (recoveryRef) {
284
+ // Anything that fails before the move is committed puts the changes
285
+ // back into the project folder and drops the worktree made for them;
286
+ // a restore that is refused keeps both (and the recovery ref).
287
+ const created = entry;
288
+ journal.push(async () => {
289
+ await backendApi.restoreCarriedChanges({ projectPath, recoveryRef });
290
+ await backendApi.removeManagedWorktree({ entryId: created.id, force: true });
291
+ await backendApi.dropCarryRecoveryRef({ projectPath, recoveryRef });
292
+ });
293
+ }
210
294
  }
211
295
  // Cancelled after the worktree exists: it stays retained (same txId on
212
296
  // retry), the session does not move.
@@ -228,10 +312,24 @@ export function createTransitionSteps({
228
312
  baseCommit: entry.baseCommit,
229
313
  mergeTarget: project.currentBranch,
230
314
  },
231
- journal
315
+ journal,
316
+ // The tail notice: what happened to the uncommitted changes, and how
317
+ // the project-folder paths of the conversation so far map to the worktree.
318
+ isWorktreeBound(previous) ? null : { from: previous.cwd, changes: entry.changes?.mode ?? null }
232
319
  );
320
+ // The move is committed and persisted: the carried changes' recovery ref
321
+ // has done its job (a failure to drop it only leaves a spare ref).
322
+ if (entry.changes?.recoveryRef) {
323
+ await backendApi
324
+ .dropCarryRecoveryRef({ projectPath, recoveryRef: entry.changes.recoveryRef })
325
+ .catch(() => {});
326
+ }
233
327
  // Creation notes (submodules, include entries missing or already present).
234
- return { ...entered, warnings: Array.isArray(entry.warnings) ? [...entry.warnings] : [] };
328
+ return {
329
+ ...entered,
330
+ warnings: Array.isArray(entry.warnings) ? [...entry.warnings] : [],
331
+ ...(entry.changes ? { changes: { mode: entry.changes.mode, count: entry.changes.count } } : {}),
332
+ };
235
333
  }
236
334
 
237
335
  async function enterProjectBranch(session, previous, { branch, create, signal, journal }) {
@@ -360,5 +458,5 @@ export function createTransitionSteps({
360
458
  return { ...result, removed };
361
459
  }
362
460
 
363
- return { enterWorktree, enterProjectBranch, removeRetainedWorktree };
461
+ return { enterWorktree, enterProjectBranch, removeRetainedWorktree, switchProject };
364
462
  }