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
@@ -0,0 +1,82 @@
1
+ import { encodeCatalogCursor } from '../runtime/agent/orchestrator/session/catalog-db/schema.mjs';
2
+ import { truncateToolText } from '../runtime/shared/tool-primitives.mjs';
3
+ import { summarizeToolResult } from '../runtime/shared/tool-result-summary.mjs';
4
+
5
+ import { TOOL_OUTPUT_PAGE_BYTES, TOOL_OUTPUT_TAIL_BYTES } from '../runtime/shared/tool-output-budget.mjs';
6
+
7
+ export const SESSION_TOOL_OUTPUT_BYTES = TOOL_OUTPUT_TAIL_BYTES;
8
+ const MESSAGE_TEXT_LIMIT = 2000;
9
+ const outputBytes = (value) => Buffer.byteLength(JSON.stringify(value), 'utf8');
10
+
11
+ /** Keep catalog paging authoritative even when the output budget shortens a page. */
12
+ export function sessionListOutput(page, limit) {
13
+ const raw = page.sessions;
14
+ const sessions = raw.slice(0, limit).map((row) => ({
15
+ id: row.id,
16
+ ...(row.title || row.preview ? { title: truncateToolText(row.title || row.preview, 160) } : {}),
17
+ ...(row.status ? { status: row.status } : {}),
18
+ ...(row.cwd ? { cwd: row.cwd } : {}),
19
+ }));
20
+ const result = { sessions, nextCursor: page.nextCursor ?? null };
21
+ for (;;) {
22
+ if (sessions.length < raw.length && sessions.length) {
23
+ result.nextCursor = encodeCatalogCursor(raw[sessions.length - 1]);
24
+ }
25
+ if (outputBytes(result) <= TOOL_OUTPUT_PAGE_BYTES) return result;
26
+ if (sessions.length <= 1) throw new Error('session: one catalog row exceeds the output budget');
27
+ sessions.pop();
28
+ }
29
+ }
30
+
31
+ function conversationItem(item, offset, textOffset) {
32
+ const row = { kind: item.kind, offset, ...(item.id != null ? { id: item.id } : {}) };
33
+ if (item.name) row.name = item.name;
34
+ if (item.status) row.status = item.status;
35
+ if (item.isError === true) row.isError = true;
36
+ let text = item.text || item.detail || item.label || '';
37
+ if (item.kind === 'tool') {
38
+ const value = item.rawResult ?? item.result ?? '';
39
+ const raw = typeof value === 'string' ? value : JSON.stringify(value);
40
+ text = raw || summarizeToolResult(item.name, item.args, raw, item.isError === true) || text;
41
+ }
42
+ if (text) {
43
+ // Conversation indentation is significant; do not trim code/prose like a title.
44
+ if (
45
+ textOffset > 0 &&
46
+ /[\uDC00-\uDFFF]/.test(text[textOffset] || '') &&
47
+ /[\uD800-\uDBFF]/.test(text[textOffset - 1])
48
+ )
49
+ throw new Error('session: text_offset splits a surrogate pair');
50
+ let end = Math.min(text.length, textOffset + MESSAGE_TEXT_LIMIT);
51
+ if (end < text.length && /[\uD800-\uDBFF]/.test(text[end - 1])) end--;
52
+ row.text = text.slice(textOffset, end);
53
+ if (end < text.length) row.nextTextOffset = end;
54
+ }
55
+ const attachments = item.attachments ?? item.imageRefs ?? item.images;
56
+ if (attachments?.length) row.attachments = attachments.length;
57
+ return row;
58
+ }
59
+
60
+ /** Service windows can be sticky/shared; enforce this tool call's limits locally. */
61
+ export function sessionReadOutput(sessionId, range, { textOffset = 0, itemId } = {}) {
62
+ const byteLimit = range.offset === 0 && textOffset === 0 ? TOOL_OUTPUT_TAIL_BYTES : TOOL_OUTPUT_PAGE_BYTES;
63
+ const source = range.items;
64
+ if (itemId !== undefined && (source.length !== 1 || source[0].id !== itemId)) {
65
+ throw new Error('session: stale item position; read the tail again');
66
+ }
67
+ const items = source.map((item, index) =>
68
+ conversationItem(item, range.offset + source.length - index - 1, textOffset)
69
+ );
70
+ const result = {
71
+ sessionId,
72
+ offset: range.offset,
73
+ items,
74
+ nextOffset: null,
75
+ };
76
+ for (;;) {
77
+ result.nextOffset = range.hasOlder || items.length < source.length ? range.offset + items.length : null;
78
+ if (outputBytes(result) <= byteLimit) return result;
79
+ if (items.length <= 1) throw new Error('session: one transcript item exceeds the output budget');
80
+ items.shift();
81
+ }
82
+ }
package/src/tui/App.jsx CHANGED
@@ -21,6 +21,7 @@ import { useApp, useStdin, useStdout } from 'ink';
21
21
  import { useSession } from './hooks/useSession.mjs';
22
22
  import { pickFolder } from '../standalone/folder-dialog.mjs';
23
23
  import { deriveSlashPalette } from './app/slash-palette.mjs';
24
+ import { createBtwController } from './app/btw-controller.mjs';
24
25
  import { skillMentionQuery, useSkillMentionSkills } from './app/skill-mention-palette.mjs';
25
26
  import { shouldSupersedePanelEpoch, supersedePanelEpoch } from './app/panel-epoch.mjs';
26
27
  import { createPanelSurface } from './app/panel-surface.mjs';
@@ -152,6 +153,24 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
152
153
  livePickerRef.current = picker;
153
154
  const [contextPanel, setContextPanel] = useState(null);
154
155
  const [usagePanel, setUsagePanel] = useState(null);
156
+ const [btwPanel, setBtwPanel] = useState(null);
157
+ const btwRef = useRef(null);
158
+ const sessionIdRef = useRef('');
159
+ sessionIdRef.current = state.sessionId || '';
160
+ if (!btwRef.current) {
161
+ btwRef.current = createBtwController({
162
+ getStore: () => store,
163
+ setPanel: setBtwPanel,
164
+ getSessionId: () => sessionIdRef.current,
165
+ });
166
+ }
167
+ const btw = btwRef.current;
168
+ // A side answer belongs to the conversation it was asked in: drop it on a
169
+ // session change (new/resume/clear/switch) and cancel it on unmount.
170
+ useEffect(() => {
171
+ btw.sync();
172
+ }, [btw, state.sessionId]);
173
+ useEffect(() => () => btw.dispose(), [btw]);
155
174
  // OWNING LAYER (app/panel-surface.mjs): the three sinks above are handed over
156
175
  // exactly once and never leave that module. Every panel factory below gets
157
176
  // `surface` instead, so painting or delegating without a claim that proves
@@ -310,6 +329,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
310
329
  setSettingsPrompt,
311
330
  setOnboardingActive,
312
331
  closeUsagePanel,
332
+ btw,
313
333
  oauthSubmitRef,
314
334
  clearModelCaches,
315
335
  onboardingRef,
@@ -518,6 +538,8 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
518
538
  usagePanel,
519
539
  closeUsagePanel,
520
540
  contextPanel,
541
+ btwPanel,
542
+ closeBtwPanel: btw.close,
521
543
  installPastedImages,
522
544
  clearPastedImagesSnapshot,
523
545
  registerPastedImage,
@@ -650,6 +672,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
650
672
  toolApproval: !!toolApproval,
651
673
  contextPanel: !!contextPanel,
652
674
  usagePanel: !!usagePanel,
675
+ btwPanel: !!btwPanel,
653
676
  providerPrompt: !!providerPrompt,
654
677
  settingsPrompt: !!settingsPrompt,
655
678
  };
@@ -711,6 +734,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
711
734
  picker,
712
735
  contextPanel,
713
736
  usagePanel,
737
+ btwPanel,
714
738
  slashPaletteOpen,
715
739
  tuiReady,
716
740
  state,
@@ -822,6 +846,7 @@ export function App({ store, initialStatusLine = '', forceOnboarding = false, on
822
846
  activeSlashQuery,
823
847
  activeTools,
824
848
  agentRevision,
849
+ btwPanel,
825
850
  cancelProviderPrompt,
826
851
  cancelSettingsPrompt,
827
852
  cancelSlashPalette,
@@ -10,9 +10,12 @@
10
10
  import { theme } from '../../theme.mjs';
11
11
  import { toolApprovalDescription } from '../app-format.mjs';
12
12
  import { Picker } from '../../components/Picker.jsx';
13
+ import { QuestionPanel } from '../../components/QuestionPanel.jsx';
14
+ import { questionsOf } from '../../components/question-panel-model.mjs';
13
15
  import { SlashCommandPalette } from '../../components/SlashCommandPalette.jsx';
14
16
  import { ContextPanel } from '../../components/ContextPanel.jsx';
15
17
  import { UsagePanel } from '../../components/UsagePanel.jsx';
18
+ import { BtwPanel } from '../../components/BtwPanel.jsx';
16
19
  import { TextEntryPanel } from '../../components/TextEntryPanel.jsx';
17
20
  import { textEntryClearsByEmpty } from '../text-entry-policy.mjs';
18
21
  import { withPickerEnterLatch } from '../picker-enter-latch.mjs';
@@ -24,7 +27,23 @@ const SKILL_PALETTE_TEXT = {
24
27
  help: '↑/↓ select · Enter insert · Esc cancel',
25
28
  };
26
29
 
27
- function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionPanel }) {
30
+ function renderToolApproval({ toolApproval, store, frameColumns, expandedOptionPanel, floatingPanelRows }) {
31
+ if (toolApproval.kind === 'question') {
32
+ return (
33
+ <QuestionPanel
34
+ key={toolApproval.id}
35
+ questions={questionsOf(toolApproval)}
36
+ columns={frameColumns}
37
+ rows={floatingPanelRows}
38
+ onSubmit={(answers) =>
39
+ store.resolveToolApproval?.(toolApproval.id, { approved: true, reason: 'answered by user', answers })
40
+ }
41
+ onDismiss={() =>
42
+ store.resolveToolApproval?.(toolApproval.id, { approved: false, reason: 'dismissed by user' })
43
+ }
44
+ />
45
+ );
46
+ }
28
47
  const resolve = (approved) => {
29
48
  store.resolveToolApproval?.(toolApproval.id, {
30
49
  approved,
@@ -144,6 +163,7 @@ export function renderFloatingPanel(ctx) {
144
163
  slashPaletteOpen,
145
164
  toolApproval,
146
165
  usagePanel,
166
+ btwPanel,
147
167
  } = ctx;
148
168
  if (toolApproval) return renderToolApproval(ctx);
149
169
  if (picker) return renderPicker(ctx);
@@ -227,5 +247,10 @@ export function renderFloatingPanel(ctx) {
227
247
  />
228
248
  );
229
249
  }
250
+ if (btwPanel) {
251
+ return (
252
+ <BtwPanel panel={btwPanel} columns={frameColumns} panelRows={floatingPanelRows} themeEpoch={ctx.state?.themeEpoch || 0} />
253
+ );
254
+ }
230
255
  return null;
231
256
  }
@@ -138,6 +138,7 @@ export function renderAppView(ctx) {
138
138
  thinkingActiveSince={liveSpinner?.thinkingSegmentStartedAt ?? 0}
139
139
  thinkingMs={liveSpinner?.thinkingAccumulatedMs ?? 0}
140
140
  effort={state.effort || ''}
141
+ quiet={liveSpinner?.quiet ?? null}
141
142
  hasActiveTools={!!activeTools?.web_search?.count}
142
143
  paused={!!toolApproval}
143
144
  interruptible={!!(state.busy && state.spinner?.active)}
@@ -230,7 +231,7 @@ export function renderAppView(ctx) {
230
231
  ) : null}
231
232
  <StatusLine
232
233
  sessionId={state.sessionId}
233
- clientHostPid={state.ownerClientHostPid || state.clientHostPid}
234
+ clientHostPid={state.clientHostPid}
234
235
  provider={state.provider}
235
236
  model={state.model}
236
237
  effort={state.effort}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * app/btw-controller.mjs — the transient `/btw` side-question panel.
3
+ *
4
+ * The answer lives only in this panel (never the transcript). `ask` replaces
5
+ * any existing panel, `close` (Esc) cancels a pending request, and a result
6
+ * that arrives after a replace/close is ignored via the request sequence.
7
+ */
8
+ import { measureMarkdownRenderedRows } from '../markdown/measure-rendered-rows.mjs';
9
+
10
+ export const BTW_USAGE_HINT = 'usage: /btw <question>';
11
+ // Border (2) + header (1) + footer (1).
12
+ export const BTW_CHROME_ROWS = 4;
13
+ const BTW_MAX_BODY_ROWS = 10;
14
+
15
+ /** Rendered row count of the answer body (the scrollable content height). */
16
+ export function btwContentRows(panel, columns) {
17
+ const body =
18
+ panel.status === 'done'
19
+ ? measureMarkdownRenderedRows(panel.text, Math.max(1, columns - 4))
20
+ : String(panel.text || '').split('\n').length;
21
+ return Math.max(1, body);
22
+ }
23
+
24
+ export function btwPanelRows(panel, columns) {
25
+ if (!panel) return 0;
26
+ return BTW_CHROME_ROWS + Math.min(BTW_MAX_BODY_ROWS, btwContentRows(panel, columns));
27
+ }
28
+
29
+ /** Largest scroll offset for `total` content rows shown through `visible` rows. */
30
+ export function btwScrollMax(total, visible) {
31
+ return Math.max(0, total - Math.max(1, visible));
32
+ }
33
+
34
+ /** Next scroll offset for a PageUp/PageDown key (other keys leave it unchanged). */
35
+ export function btwScrollOffset(key, offset, visible, total) {
36
+ const max = btwScrollMax(total, visible);
37
+ const page = Math.max(1, visible - 1);
38
+ if (key.pageUp) return Math.max(0, Math.min(max, offset) - page);
39
+ if (key.pageDown) return Math.min(max, offset + page);
40
+ return Math.min(max, offset);
41
+ }
42
+
43
+ /**
44
+ * Each request is bound to the session it was asked in. A settlement whose
45
+ * session no longer matches is ignored; `sync` (session change) and `dispose`
46
+ * (unmount) cancel a pending request for its originating session.
47
+ */
48
+ export function createBtwController({ getStore, setPanel, getSessionId = () => '' }) {
49
+ let seq = 0;
50
+ let pending = null; // { sessionId, dispatched } while a request is queued or in flight
51
+ let origin = null; // session the visible panel was asked in
52
+
53
+ const cancelPending = () => {
54
+ if (!pending) return;
55
+ const { sessionId, dispatched } = pending;
56
+ pending = null;
57
+ // Not dispatched yet: dropping `pending` stops the queued request, so
58
+ // there is nothing to cancel (a cancel sent first would not hit it).
59
+ if (!dispatched) return;
60
+ try {
61
+ const result = getStore().cancelSide?.(sessionId);
62
+ if (result?.catch) void result.catch(() => {});
63
+ } catch {
64
+ /* best-effort cancel */
65
+ }
66
+ };
67
+
68
+ const ask = (question) => {
69
+ cancelPending();
70
+ const id = ++seq;
71
+ const sessionId = getSessionId();
72
+ const request = { sessionId, dispatched: false };
73
+ pending = request;
74
+ origin = sessionId;
75
+ setPanel({ question, status: 'pending', text: '' });
76
+ const settle = (next) => {
77
+ if (id !== seq || getSessionId() !== sessionId) return;
78
+ pending = null;
79
+ setPanel({ question, ...next });
80
+ };
81
+ Promise.resolve()
82
+ .then(() => {
83
+ // askSide runs against the store's current session, so only dispatch
84
+ // while this ask is still live and still in its origin session.
85
+ if (pending !== request || id !== seq || getSessionId() !== sessionId) {
86
+ if (pending === request) pending = null;
87
+ return undefined; // dropped, never sent; `settle` ignores it (stale id/session)
88
+ }
89
+ request.dispatched = true;
90
+ return getStore().askSide(question);
91
+ })
92
+ .then(
93
+ (result) => settle({ status: 'done', text: String(result?.text ?? '') }),
94
+ (error) => settle({ status: 'error', text: String(error?.message || error || 'side question failed') })
95
+ );
96
+ };
97
+
98
+ const close = () => {
99
+ cancelPending();
100
+ seq += 1;
101
+ origin = null;
102
+ setPanel(null);
103
+ };
104
+
105
+ /** Session changed: a panel from another conversation is cancelled and cleared. */
106
+ const sync = () => {
107
+ if (origin !== null && getSessionId() !== origin) close();
108
+ };
109
+
110
+ /** Unmount: cancel without touching React state. */
111
+ const dispose = () => {
112
+ cancelPending();
113
+ seq += 1;
114
+ origin = null;
115
+ };
116
+
117
+ return { ask, close, sync, dispose };
118
+ }
@@ -37,6 +37,7 @@ export function createAppPickers({
37
37
  setSettingsPrompt,
38
38
  setOnboardingActive,
39
39
  closeUsagePanel,
40
+ btw,
40
41
  oauthSubmitRef,
41
42
  clearModelCaches,
42
43
  onboardingRef,
@@ -207,6 +208,7 @@ export function createAppPickers({
207
208
  normalizeSlashCommandName,
208
209
  surface,
209
210
  closeUsagePanel,
211
+ btw,
210
212
  openModelPicker: (...a) => openModelPicker(...a),
211
213
  modelSwitchNotice,
212
214
  openWebSearchPicker: (...a) => openWebSearchPicker(...a),
@@ -77,6 +77,14 @@ export function buildProviderItems(setup) {
77
77
  _authenticated: p.authenticated,
78
78
  });
79
79
  }
80
+ if (setup.managedByClient === true) {
81
+ for (const p of setup.local || []) {
82
+ providerItems.push({
83
+ value: `local:${p.id}`, label: p.name, meta: providerStatusLabel(p), description: '',
84
+ _type: 'local', _providerId: p.id, _providerName: p.name, _provider: p,
85
+ });
86
+ }
87
+ }
80
88
  providerItems.sort((a, b) => {
81
89
  const rank = providerItemRank(a) - providerItemRank(b);
82
90
  if (rank !== 0) return rank;
@@ -54,7 +54,7 @@ export function createProviderSetupPicker({
54
54
  });
55
55
  try {
56
56
  await new Promise((resolve) => setTimeout(resolve, 0));
57
- return await store.getProviderSetup();
57
+ return await store.getProviderSetup(options.forceRefresh ? { force: true } : undefined);
58
58
  } catch (e) {
59
59
  store.pushNotice(`providers failed: ${e?.message || e}`, 'error');
60
60
  return null;
@@ -98,6 +98,9 @@ export function createProviderSetupPicker({
98
98
  });
99
99
  }
100
100
  items.push(...buildProviderItems(setup));
101
+ if (setup.managedByClient === true) {
102
+ items.push({ value: 'refresh-client-providers', label: 'Refresh', _type: 'refresh-client-providers' });
103
+ }
101
104
 
102
105
  const flow = {
103
106
  store,
@@ -127,10 +130,13 @@ export function createProviderSetupPicker({
127
130
 
128
131
  flow.paint({
129
132
  title: options.title || 'Providers',
130
- description: options.description || 'Choose a provider. Enter opens provider actions.',
133
+ description: setup.managedByClient === true
134
+ ? 'Manage provider sign-ins and accounts in the local desktop window. Refresh to update availability.'
135
+ : options.description || 'Choose a provider. Enter opens provider actions.',
131
136
  footer: providerFooter,
132
137
  footerGapRows: 1,
133
- help: options.confirmBar ? undefined : '↑/↓ Select · Enter Open · Esc Back',
138
+ help: options.confirmBar ? undefined : setup.managedByClient === true
139
+ ? '↑/↓ Select · Enter Refresh · Esc Back' : '↑/↓ Select · Enter Open · Esc Back',
134
140
  indexMode: 'always',
135
141
  labelWidth: 18,
136
142
  metaWidth: 12,
@@ -142,6 +148,12 @@ export function createProviderSetupPicker({
142
148
  if (item?._providerId) flow.rememberProviderSelection(item);
143
149
  },
144
150
  onSelect: (_value, item) => {
151
+ if (setup.managedByClient === true && item._type !== 'continue') {
152
+ if (item._type === 'refresh-client-providers') {
153
+ void openProviderSetupPicker({ ...options, preloadedSetup: null, forceRefresh: true });
154
+ }
155
+ return;
156
+ }
145
157
  // In-flow navigation (Enter on a provider row): the flow keeps the
146
158
  // surface, so clear-and-continue — own.close() would supersede this
147
159
  // very flow and paintProviders would then reject the action panel the
@@ -5,7 +5,9 @@
5
5
  */
6
6
  import { isLiveSpinnerMetaVisible } from '../live-spinner-visibility.mjs';
7
7
  import { promptContentRows, wrappedDetailRows, queuedBandRows } from '../text-layout.mjs';
8
+ import { questionPanelRows, questionsOf } from '../../components/question-panel-model.mjs';
8
9
  import { CORE_MULTILINE_TEXT_ENTRY_KINDS } from '../panel-signature.mjs';
10
+ import { btwPanelRows } from '../btw-controller.mjs';
9
11
 
10
12
  const SCROLL_HINT_ROWS = 0;
11
13
  const LIVE_STATUS_ROWS = 0;
@@ -114,20 +116,25 @@ function floatingPanelBudget({
114
116
  picker,
115
117
  contextPanel,
116
118
  usagePanel,
119
+ btwPanel,
117
120
  slashPaletteOpen,
118
121
  hasTextEntryPrompt,
119
122
  TEXT_ENTRY_ROWS,
120
123
  OPTION_PANEL_EXTRA_ROWS,
121
124
  maxFloatingPanelRows,
125
+ frameColumns,
122
126
  }) {
123
127
  let desiredFloatingPanelRows = 0;
124
- if (toolApproval) desiredFloatingPanelRows = PANEL_CHROME_ROWS + 2 + OPTION_PANEL_EXTRA_ROWS;
128
+ if (toolApproval?.kind === 'question' && questionsOf(toolApproval).length > 0) {
129
+ desiredFloatingPanelRows = questionPanelRows(questionsOf(toolApproval), frameColumns);
130
+ } else if (toolApproval) desiredFloatingPanelRows = PANEL_CHROME_ROWS + 2 + OPTION_PANEL_EXTRA_ROWS;
125
131
  else if (picker?.fillAvailable) desiredFloatingPanelRows = maxFloatingPanelRows;
126
132
  else if (picker) desiredFloatingPanelRows = PANEL_BASE_ROWS + OPTION_PANEL_EXTRA_ROWS;
127
133
  else if (contextPanel) desiredFloatingPanelRows = PANEL_BASE_ROWS + OPTION_PANEL_EXTRA_ROWS + 3;
128
134
  else if (usagePanel) desiredFloatingPanelRows = PANEL_BASE_ROWS + OPTION_PANEL_EXTRA_ROWS;
129
135
  else if (slashPaletteOpen) desiredFloatingPanelRows = SLASH_PALETTE_ROWS;
130
136
  else if (hasTextEntryPrompt) desiredFloatingPanelRows = TEXT_ENTRY_ROWS;
137
+ else if (btwPanel) desiredFloatingPanelRows = btwPanelRows(btwPanel, frameColumns);
131
138
  const floatingPanelRows = desiredFloatingPanelRows > 0 ? Math.min(desiredFloatingPanelRows, maxFloatingPanelRows) : 0;
132
139
  // Give the list every content row the panel exposes. The panel already grew
133
140
  // by OPTION_PANEL_EXTRA_ROWS; previously that growth was subtracted back out
@@ -174,6 +181,7 @@ export function computeRowBudgets({
174
181
  picker,
175
182
  contextPanel,
176
183
  usagePanel,
184
+ btwPanel,
177
185
  slashPaletteOpen,
178
186
  }) {
179
187
  const { textEntryPrompt, hasTextEntryPrompt, hasFloatingPanel, expandedOptionPanel, inputBoxHidden } = surfaces;
@@ -211,11 +219,13 @@ export function computeRowBudgets({
211
219
  picker,
212
220
  contextPanel,
213
221
  usagePanel,
222
+ btwPanel,
214
223
  slashPaletteOpen,
215
224
  hasTextEntryPrompt,
216
225
  TEXT_ENTRY_ROWS: textEntry.TEXT_ENTRY_ROWS,
217
226
  OPTION_PANEL_EXTRA_ROWS,
218
227
  maxFloatingPanelRows,
228
+ frameColumns,
219
229
  });
220
230
  const rows = {
221
231
  floatingPanelRows: panel.floatingPanelRows,
@@ -10,6 +10,7 @@ export function deriveSurfaces({
10
10
  picker,
11
11
  contextPanel,
12
12
  usagePanel,
13
+ btwPanel,
13
14
  slashPaletteOpen,
14
15
  tuiReady,
15
16
  state,
@@ -24,7 +25,8 @@ export function deriveSurfaces({
24
25
  contextPanel ||
25
26
  usagePanel ||
26
27
  slashPaletteOpen ||
27
- hasTextEntryPrompt
28
+ hasTextEntryPrompt ||
29
+ btwPanel
28
30
  );
29
31
  const expandedOptionPanel = !!(toolApproval || picker || contextPanel || usagePanel || hasTextEntryPrompt);
30
32
  if (panelTransitionRef.current.signature.includes('picker:project') && !picker) {
@@ -15,6 +15,12 @@ export const SLASH_COMMANDS = [
15
15
  description: 'Switch working directory (project)',
16
16
  },
17
17
  { name: 'compact', usage: '/compact', description: 'Compact older conversation context' },
18
+ {
19
+ name: 'btw',
20
+ usage: '/btw',
21
+ params: '<question>',
22
+ description: 'Ask a quick side question without interrupting the current work',
23
+ },
18
24
  {
19
25
  name: 'goal',
20
26
  usage: '/goal',
@@ -30,9 +36,18 @@ export const SLASH_COMMANDS = [
30
36
  { name: 'resume', usage: '/resume', params: '[id]', description: 'Resume a saved chat' },
31
37
  { name: 'context', usage: '/context', description: 'Show current context surface' },
32
38
  {
33
- name: 'inherit',
34
- usage: '/inherit',
35
- description: 'Carry this conversation into a new session on the current model',
39
+ name: 'shells',
40
+ usage: '/shells',
41
+ params: '[release <task_id> [--confirm]]',
42
+ description: 'List shells; release one whose termination is unconfirmed',
43
+ },
44
+ {
45
+ name: 'fork',
46
+ usage: '/fork',
47
+ aliases: ['inherit'],
48
+ aliasUsage: ['inherit'],
49
+ showAliasUsage: false,
50
+ description: 'Fork this conversation into a new session on the current model',
36
51
  },
37
52
  { name: 'usage', usage: '/usage', params: '[refresh]', description: 'Show total provider quota / balance' },
38
53
  { name: 'model', usage: '/model', params: '[name|refresh]', description: 'Switch model for subsequent turns' },
@@ -109,6 +124,7 @@ export function overlayBlocksGlobalTranscriptScroll(owner = {}) {
109
124
  owner.toolApproval ||
110
125
  owner.contextPanel ||
111
126
  owner.usagePanel ||
127
+ owner.btwPanel ||
112
128
  owner.providerPrompt ||
113
129
  owner.settingsPrompt
114
130
  );
@@ -1,8 +1,9 @@
1
1
  // slash-dispatch/session-commands.mjs
2
2
  // Slash commands that act on the session itself: clear/new, compact, goal,
3
- // resume, inherit, doctor and quit. Busy guards refuse the destructive ones
3
+ // resume, fork (alias inherit), doctor and quit. Busy guards refuse the destructive ones
4
4
  // while a turn or session command is running.
5
5
  import { presentErrorText } from '../../../runtime/shared/err-text.mjs';
6
+ import { BTW_USAGE_HINT } from '../btw-controller.mjs';
6
7
 
7
8
  function compactFailureNotice(error) {
8
9
  if (error == null || String(error).trim() === '') return 'Compact failed.';
@@ -63,6 +64,18 @@ export const sessionCommands = {
63
64
  return true;
64
65
  },
65
66
 
67
+ // Side question: allowed mid-turn; never queued, steered, or interrupting.
68
+ btw(ctx, arg) {
69
+ const { store, deps } = ctx;
70
+ const question = String(arg || '').trim();
71
+ if (!question) {
72
+ store.pushNotice(BTW_USAGE_HINT, 'warn');
73
+ return true;
74
+ }
75
+ deps.btw.ask(question);
76
+ return true;
77
+ },
78
+
66
79
  goal(ctx, arg) {
67
80
  const { store } = ctx;
68
81
  void Promise.resolve(store.goalControl?.({ command: arg }))
@@ -91,18 +104,67 @@ export const sessionCommands = {
91
104
  return true;
92
105
  },
93
106
 
94
- inherit(ctx) {
107
+ fork(ctx, _arg, rawName) {
95
108
  const { state, store } = ctx;
96
- if (state.busy) return refuseWhileBusy(store, 'inherit');
109
+ if (state.busy) return refuseWhileBusy(store, rawName === 'inherit' ? 'inherit' : 'fork');
97
110
  void Promise.resolve(store.inheritSession?.())
98
111
  .then((result) => {
99
112
  if (!result) {
100
- store.pushNotice('nothing to inherit', 'warn');
113
+ store.pushNotice('nothing to fork', 'warn');
101
114
  return;
102
115
  }
103
- store.pushNotice(`inherited ${result.messages} messages into ${result.sessionId}`, 'info');
116
+ store.pushNotice(`forked ${result.messages} messages into ${result.sessionId}`, 'info');
104
117
  })
105
- .catch((e) => store.pushNotice(`inherit failed: ${e?.message || e}`, 'error'));
118
+ .catch((e) => store.pushNotice(`fork failed: ${e?.message || e}`, 'error'));
119
+ return true;
120
+ },
121
+
122
+ // /shells — this session's shells, each marked running or "termination
123
+ // unconfirmed". `/shells release <id>` explains what releasing means and
124
+ // asks for `--confirm`; only then is the workspace hold dropped.
125
+ shells(ctx, arg) {
126
+ const { store } = ctx;
127
+ const [action, taskId, flag] = String(arg || '')
128
+ .trim()
129
+ .split(/\s+/)
130
+ .filter(Boolean);
131
+ if (!action) {
132
+ void Promise.resolve(store.listShellJobs?.())
133
+ .then((result) => {
134
+ const jobs = Array.isArray(result?.jobs) ? result.jobs : [];
135
+ if (!jobs.length) {
136
+ store.pushNotice('No shells are running.', 'info');
137
+ return;
138
+ }
139
+ const lines = jobs.map(
140
+ (job) =>
141
+ `${job.taskId} ${job.terminationUnconfirmed ? 'termination unconfirmed' : 'running'} ${job.command}`
142
+ );
143
+ const held = jobs.some((job) => job.terminationUnconfirmed);
144
+ if (held) lines.push('Release a held shell with /shells release <task_id>.');
145
+ store.pushNotice(lines.join('\n'), held ? 'warn' : 'info');
146
+ })
147
+ .catch((error) => store.pushNotice(`Couldn’t list shells: ${error?.message || error}`, 'error'));
148
+ return true;
149
+ }
150
+ if (action !== 'release' || !taskId) {
151
+ store.pushNotice('usage: /shells [release <task_id> [--confirm]]', 'warn');
152
+ return true;
153
+ }
154
+ if (flag !== '--confirm') {
155
+ store.pushNotice(
156
+ `Releasing ${taskId} unlocks its folder although its processes may still be running. To proceed, run /shells release ${taskId} --confirm`,
157
+ 'warn'
158
+ );
159
+ return true;
160
+ }
161
+ void Promise.resolve(store.releaseShellJob?.(taskId))
162
+ .then((result) =>
163
+ result?.released
164
+ ? store.pushNotice(`Released ${taskId}.`, 'info')
165
+ : store.pushNotice(`Couldn’t release ${taskId}: ${result?.error || 'unavailable'}`, 'warn')
166
+ )
167
+ .catch((error) => store.pushNotice(`Couldn’t release ${taskId}: ${error?.message || error}`, 'error'));
106
168
  return true;
107
169
  },
108
170
 
@@ -0,0 +1,12 @@
1
+ // Global tool-approval shortcuts: Esc/d/n deny, a/y approve. Returns the
2
+ // decision to resolve with, or null. Question approvals (ask_user) are
3
+ // answered only inside QuestionPanel, so typed letters and Esc never reach here.
4
+ export function approvalShortcutDecision(toolApproval, input, key) {
5
+ if (!toolApproval || toolApproval.kind === 'question') return null;
6
+ const value = String(input || '')
7
+ .trim()
8
+ .toLowerCase();
9
+ if (key.escape || value === 'd' || value === 'n') return { approved: false, reason: 'denied by user' };
10
+ if (value === 'a' || value === 'y') return { approved: true, reason: 'approved by user' };
11
+ return null;
12
+ }