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
@@ -14,8 +14,13 @@ function listOf(status, key) {
14
14
  }
15
15
 
16
16
  export function createScopeDecorators({ getConfig, getCurrentCwd }) {
17
- function scopeInfo(kind, name, pluginId = '', cwd = getCurrentCwd()) {
18
- const scopes = extensionScopesFromConfig(getConfig());
17
+ function scopeInfo(
18
+ kind,
19
+ name,
20
+ pluginId = '',
21
+ cwd = getCurrentCwd(),
22
+ scopes = extensionScopesFromConfig(getConfig())
23
+ ) {
19
24
  const scope = extensionScopeProjects(scopes, kind, name);
20
25
  const inheritedScope = pluginId ? extensionScopeProjects(scopes, 'plugins', pluginId) : null;
21
26
  const activeHere =
@@ -35,11 +40,13 @@ export function createScopeDecorators({ getConfig, getCurrentCwd }) {
35
40
  },
36
41
  /** `cwd`: decide `activeHere` for that folder instead of the current one. */
37
42
  skills(status, cwd = getCurrentCwd()) {
43
+ // One scope read for the whole list, not one per skill.
44
+ const scopes = extensionScopesFromConfig(getConfig());
38
45
  return {
39
46
  ...status,
40
47
  skills: listOf(status, 'skills').map((skill) => ({
41
48
  ...skill,
42
- ...scopeInfo('skills', skill.name, skill?.owner?.kind === 'plugin' ? clean(skill.owner.id) : '', cwd),
49
+ ...scopeInfo('skills', skill.name, skill?.owner?.kind === 'plugin' ? clean(skill.owner.id) : '', cwd, scopes),
43
50
  })),
44
51
  };
45
52
  },
@@ -35,7 +35,7 @@ export function createRouteResolution({ rt, collectProviderModels, ensureProvide
35
35
  return rt.route;
36
36
  }
37
37
 
38
- async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null, signal = null) {
38
+ async function refreshRouteEffort(modelMetaOverride = null, expectedRoute = null, signal = null, lease = null) {
39
39
  const targetRoute = expectedRoute || rt.route;
40
40
  await runAbortable(signal, () => ensureProvidersReady(ensureProviderEnabled(rt.config, targetRoute.provider)));
41
41
  const modelMeta =
@@ -43,7 +43,9 @@ export function createRouteResolution({ rt, collectProviderModels, ensureProvide
43
43
  throwIfAborted(signal);
44
44
  // A rapid second resume/model change can replace the route while provider
45
45
  // metadata is loading. Never let the older completion overwrite it.
46
+ // A selection whose session was replaced while this loaded owns nothing.
46
47
  if (expectedRoute && rt.route !== expectedRoute) return null;
48
+ if (lease && !lease.valid()) return null;
47
49
  const { effectiveEffort, fastCapable } = resolveRouteEffortState(targetRoute, modelMeta);
48
50
  const contextState = resolveRouteContextState(targetRoute, modelMeta);
49
51
  const contextValue = clean(targetRoute.modelParameters?.context);
@@ -18,6 +18,7 @@ function bootParams({
18
18
  model,
19
19
  effort,
20
20
  fast,
21
+ autoEffort,
21
22
  modelParameters,
22
23
  contextPercent,
23
24
  contextTokens,
@@ -33,12 +34,14 @@ function bootParams({
33
34
  sessionProfile = null,
34
35
  worktree = null,
35
36
  executeAgentControl = null,
37
+ executeSessionControl = null,
36
38
  } = {}) {
37
39
  return {
38
40
  provider,
39
41
  model,
40
42
  effort,
41
43
  fast,
44
+ autoEffort,
42
45
  modelParameters,
43
46
  contextPercent,
44
47
  contextTokens,
@@ -55,6 +58,7 @@ function bootParams({
55
58
  // Creation-time worktree intent (workspace/transitions.mjs creationIntent).
56
59
  worktree,
57
60
  executeAgentControl,
61
+ executeSessionControl,
58
62
  };
59
63
  }
60
64
 
@@ -31,6 +31,7 @@ export function createRuntimeFacade({
31
31
  const currentSessionId = () => state.session?.id || state.reservedSessionId || state.addressedSessionId || null;
32
32
  return {
33
33
  ...leadingApi,
34
+ isSessionTerminal: () => state.admission === 'terminal',
34
35
  /** Bind the durable address to the conversation this runtime just
35
36
  * loaded (resume / load-on-demand). Idempotent for the same id. */
36
37
  bindSessionAddress(sessionId) {
@@ -135,6 +136,11 @@ export function createRuntimeFacade({
135
136
  get session() {
136
137
  return state.session;
137
138
  },
139
+ /** Advances whenever another conversation (or none) is installed; a route
140
+ * selection captures it when enqueued (see model-route/route-ownership). */
141
+ get sessionGeneration() {
142
+ return state.sessionGeneration;
143
+ },
138
144
  contextStatus(options) {
139
145
  return getContextStatus(options);
140
146
  },
@@ -3,8 +3,10 @@ import { turnReviewReply } from '../runtime/shared/turn-review-reply.mjs';
3
3
  import {
4
4
  clearSessionChangeHistory,
5
5
  getSessionReviewDiff,
6
+ getSessionReviewFilePatch,
6
7
  getTurnChanges,
7
8
  getTurnReviewDiff,
9
+ getTurnReviewFilePatch,
8
10
  reapplyTurnChanges,
9
11
  revertTurnChanges,
10
12
  revertTurnReview,
@@ -24,8 +26,9 @@ registerSessionPurgeHook((sessionId) => {
24
26
  });
25
27
 
26
28
  // Tool writes (apply_patch, mutating shell commands, git, watcher events)
27
- // reach the live review snapshot as its change signal: a review poll right
28
- // after them captures the worktree, an unsignaled poll may reuse the last one.
29
+ // reach the turn's worktree snapshot as its change signal: a session review
30
+ // read right after them captures the worktree, an unsignaled one may reuse
31
+ // the last capture.
29
32
  registerCacheInvalidationListener((paths) => noteTurnWorktreeChange(paths));
30
33
 
31
34
  export function createRuntimeReviewApi({ getCwd, getSessionId }) {
@@ -35,6 +38,9 @@ export function createRuntimeReviewApi({ getCwd, getSessionId }) {
35
38
  getTurnReviewDiff: (options = {}) =>
36
39
  turnReviewReply((reviewOptions) => getTurnReviewDiff(getCwd(), getSessionId(), reviewOptions), options),
37
40
  getSessionReviewDiff: () => getSessionReviewDiff(getCwd(), getSessionId()),
41
+ // One listed file's whole patch (a reply lists a large one `patchOmitted`).
42
+ getSessionReviewFilePatch: (file, oldPath) => getSessionReviewFilePatch(getCwd(), getSessionId(), file, oldPath),
43
+ getTurnReviewFilePatch: (file) => getTurnReviewFilePatch(getCwd(), getSessionId(), file),
38
44
  revertTurnReview: (checkpointId) => revertTurnReview(getCwd(), getSessionId(), checkpointId),
39
45
  revertTurnReviewFile: (file, checkpointId) => revertTurnReviewFile(getCwd(), getSessionId(), file, checkpointId),
40
46
  // Historical per-turn changes, addressed by checkpointId (TurnChangesReply).
@@ -111,6 +111,7 @@ function cleanStage(value) {
111
111
  }
112
112
 
113
113
  function describeLastProgress({ stage, snapshot, runtime, silentFor, lastToolCall, now }) {
114
+ if (snapshot?.awaitingModelResponse) return 'model thinking (request sent; awaiting response headers)';
114
115
  if (snapshot?.waitingForTransport) return 'awaiting model transport';
115
116
  if (snapshot?.waitingForFirstSemantic) {
116
117
  return 'transport active; awaiting first model event';
@@ -169,6 +170,7 @@ function describeAgentDiagnostic({ taskStatus, sessionStatus, stage, snapshot, s
169
170
  if (abortErr) return `stale: ${abortErr.message.replace(/^agent /i, '')}`;
170
171
  }
171
172
 
173
+ if (snapshot?.awaitingModelResponse) return 'model thinking; request sent, response headers pending';
172
174
  if (snapshot?.waitingForTransport) return 'waiting for model transport';
173
175
  if (snapshot?.waitingForFirstSemantic) {
174
176
  return 'transport healthy; waiting for first semantic model event';
@@ -10,9 +10,6 @@ export function createCloseAll({ registry, close }) {
10
10
  const { tags, tagAgents, tagCwds } = registry;
11
11
 
12
12
  function resetLocalTagState() {
13
- for (const timer of registry.reapTimers.values()) clearTimeout(timer);
14
- registry.reapTimers.clear();
15
- registry.clearScheduledReaps();
16
13
  tags.clear();
17
14
  tagAgents.clear();
18
15
  tagCwds.clear();
@@ -58,21 +58,20 @@ export function createCloseFlow({ mgr, registry, views }) {
58
58
  if (isLeadPoolAgent(registry.getLiveSession(sessionId)?.agent)) {
59
59
  throw new Error(`agent close: target "${target}" is a Lead session`);
60
60
  }
61
- registry.cancelReap(sessionId);
62
61
  const descendantSessionIds =
63
62
  typeof mgr.descendantSessionIds === 'function' ? mgr.descendantSessionIds(sessionId) : [];
64
63
  const tag = registry.tagForSession(sessionId);
65
64
  clearAgentStatuslineRoute(sessionId);
66
65
  cancelSessionTasks(sessionId, target, scopedContext);
67
- // Close (and stamp cancelStatus) BEFORE dropping the worker row. Removing
68
- // the row first left the next pool read with only a leftover heartbeat,
69
- // which republished the session as `running`. The explicit task_id cancel
66
+ // Close (and stamp cancelStatus) BEFORE dropping the worker row, so the
67
+ // row never outlives an unrecorded cancel. The explicit task_id cancel
70
68
  // below is an idempotent no-op fallback once terminal.
71
- const ok = await mgr.closeSession(sessionId, 'cli-agent-close');
69
+ // Closing a runtime cancels its work; only explicit session deletion
70
+ // may tombstone the conversation.
71
+ const ok = await mgr.closeSession(sessionId, 'cli-agent-close', { tombstone: false });
72
72
  if (task?.taskId) cancelBackgroundTask(task.taskId, CLOSE_REASON);
73
73
  // Drop the row only once the cancellation is DURABLY recorded: a failed
74
- // close that still forgot the row left a fresh heartbeat with no cancelled
75
- // state — the exact lingering row this path exists to prevent.
74
+ // close that still forgot the row would leave no cancelled state behind.
76
75
  if (ok) {
77
76
  registry.forgetTerminalSession(tag, sessionId);
78
77
  for (const descendantSessionId of descendantSessionIds) {
@@ -38,8 +38,8 @@ export function createSendDispatch({ registry, defaultCwd, sendFlow, spawnFlow,
38
38
  if (inherited.tombstone) registry.consumeTagTombstone(inherited.tombstone);
39
39
  }
40
40
 
41
- // Reaped/dead-tag fallback: with the 5m terminal-reap window a same-scope
42
- // follow-up often lands after the session is gone. Instead of bouncing an
41
+ // Dead-tag fallback: a same-scope follow-up can land after its session was
42
+ // closed or deleted. Instead of bouncing an
43
43
  // error back to Lead (who would just re-issue the same content as a spawn),
44
44
  // respawn a FRESH session under the same tag with the message as its brief.
45
45
  // `respawned: true` in the result tells Lead the worker has no prior session
@@ -1,4 +1,22 @@
1
1
  import { clean, rowMatchesContext } from './helpers.mjs';
2
+ import { resolveRequestedModel } from './model-select.mjs';
3
+
4
+ // What an explicit (already resolved) spawn asks a reused session to change:
5
+ // the model, the tuning, or both — only what it names, or null when it names
6
+ // nothing. It is a partial request: the session's route write completes it
7
+ // against the latest selected route (and drops it when nothing differs), so
8
+ // no descriptor snapshot decides what the other tuning becomes.
9
+ function requestedRoute(args) {
10
+ const model = clean(args.model);
11
+ const effort = clean(args.effort);
12
+ const route = {
13
+ ...(model ? { provider: clean(args.provider), model } : {}),
14
+ ...(effort ? { effort } : {}),
15
+ ...(args.fast === undefined ? {} : { fast: args.fast === true }),
16
+ ...(args.autoEffort === undefined ? {} : { autoEffort: args.autoEffort !== false }),
17
+ };
18
+ return Object.keys(route).length ? route : null;
19
+ }
2
20
 
3
21
  // Spawn request dispatch: deciding what an explicitly tagged spawn means before
4
22
  // a job is started, and starting it.
@@ -6,7 +24,14 @@ import { clean, rowMatchesContext } from './helpers.mjs';
6
24
  // Inputs: `registry` (tag resolution, live sessions, tombstones),
7
25
  // `terminalTrace`, `sendFlow` (reuse path), `spawnFlow`, and `spawnResult`
8
26
  // (job -> rendered tool output). Output: { spawn }.
9
- export function createSpawnDispatch({ registry, terminalTrace, sendFlow, spawnFlow, spawnResult }) {
27
+ export function createSpawnDispatch({
28
+ registry,
29
+ terminalTrace,
30
+ sendFlow,
31
+ spawnFlow,
32
+ spawnResult,
33
+ listProviderModels = null,
34
+ }) {
10
35
  // Explicit-tag spawn priority (auto nextTag always creates a fresh session):
11
36
  // 1) live + busy -> queue the prompt (reuse)
12
37
  // 2) live + idle -> continue existing session (reuse)
@@ -26,7 +51,12 @@ export function createSpawnDispatch({ registry, terminalTrace, sendFlow, spawnFl
26
51
  }
27
52
  if (liveSessionId && registry.getLiveSession(liveSessionId)) {
28
53
  const prepared = await sendFlow.prepareSend({ ...args, tag: explicitTag }, scopedContext);
29
- return { reused: sendFlow.dispatchToExistingSession(prepared, notifyContext, { reused: true }) };
54
+ const route = requestedRoute(args);
55
+ return {
56
+ reused: sendFlow.dispatchToExistingSession(route ? { ...prepared, route } : prepared, notifyContext, {
57
+ reused: true,
58
+ }),
59
+ };
30
60
  }
31
61
  if (terminalTrace.hasTerminalTrace(explicitTag, scopedContext)) {
32
62
  terminalTrace.reapTerminalTraceForTag(explicitTag, scopedContext);
@@ -52,7 +82,10 @@ export function createSpawnDispatch({ registry, terminalTrace, sendFlow, spawnFl
52
82
  return { spawnArgs: args, respawned: false };
53
83
  }
54
84
 
55
- async function spawn(args, request) {
85
+ async function spawn(requestArgs, request) {
86
+ // Resolve a user-pinned model before deferring, so a miss or an ambiguous
87
+ // name answers this call instead of failing the background job.
88
+ const args = await resolveRequestedModel(requestArgs, listProviderModels);
56
89
  const explicitTag = clean(args.tag);
57
90
  let spawnArgs = args;
58
91
  let respawned = false;
@@ -17,6 +17,7 @@ export function createAgentExecute({
17
17
  sendFlow,
18
18
  closeFlow,
19
19
  terminalTrace,
20
+ listProviderModels = null,
20
21
  }) {
21
22
  const spawnResult = (job) => renderResult(views.renderJob(job, false));
22
23
 
@@ -30,7 +31,14 @@ export function createAgentExecute({
30
31
  }
31
32
 
32
33
  const { send } = createSendDispatch({ registry, defaultCwd, sendFlow, spawnFlow, spawnResult });
33
- const { spawn } = createSpawnDispatch({ registry, terminalTrace, sendFlow, spawnFlow, spawnResult });
34
+ const { spawn } = createSpawnDispatch({
35
+ registry,
36
+ terminalTrace,
37
+ sendFlow,
38
+ spawnFlow,
39
+ spawnResult,
40
+ listProviderModels,
41
+ });
34
42
 
35
43
  return async function execute(args = {}, context = {}) {
36
44
  try {
@@ -316,29 +316,52 @@ function agentDefinitionFiles(cleanAgent, dataDir, standaloneSourceRoot) {
316
316
  return candidates;
317
317
  }
318
318
 
319
- export function readAgentFrontmatterPermission(agent, dataDir, standaloneSourceRoot) {
319
+ const _frontmatterFirstResponseCache = new Map(); // key -> { value, atMs }
320
+
321
+ // The first definition (in precedence order) whose frontmatter yields a value
322
+ // through `pick`, cached per agent for the frontmatter TTL.
323
+ function cachedFrontmatterValue(cache, agent, dataDir, standaloneSourceRoot, pick) {
320
324
  const cleanAgent = clean(agent);
321
325
  if (!cleanAgent) return null;
322
326
  if (agentDeleted(cleanAgent, dataDir)) return null;
323
327
  const cacheKey = `${dataDir || ''}\u0000${cleanAgent}`;
324
- const cached = _frontmatterPermCache.get(cacheKey);
328
+ const cached = cache.get(cacheKey);
325
329
  if (cached && Date.now() - cached.atMs < FRONTMATTER_PERM_CACHE_TTL_MS) {
326
330
  return cached.value;
327
331
  }
328
332
  let resolved = null;
329
333
  for (const file of agentDefinitionFiles(cleanAgent, dataDir, standaloneSourceRoot)) {
330
334
  if (!existsSync(file)) continue;
331
- const fm = parseMarkdownFrontmatter(readFileSync(file, 'utf8'));
332
- const permission = normalizeAgentPermissionOrNone(fm.permission);
333
- if (permission) {
334
- resolved = permission;
335
+ const value = pick(parseMarkdownFrontmatter(readFileSync(file, 'utf8')));
336
+ if (value != null) {
337
+ resolved = value;
335
338
  break;
336
339
  }
337
340
  }
338
- _frontmatterPermCache.set(cacheKey, { value: resolved, atMs: Date.now() });
341
+ cache.set(cacheKey, { value: resolved, atMs: Date.now() });
339
342
  return resolved;
340
343
  }
341
344
 
345
+ export function readAgentFrontmatterPermission(agent, dataDir, standaloneSourceRoot) {
346
+ return cachedFrontmatterValue(
347
+ _frontmatterPermCache,
348
+ agent,
349
+ dataDir,
350
+ standaloneSourceRoot,
351
+ (fm) => normalizeAgentPermissionOrNone(fm.permission) || null
352
+ );
353
+ }
354
+
355
+ /** The agent definition's `firstResponseTimeoutMs` (a non-negative integer;
356
+ * 0 disables the first-response deadline), or null when it sets none. */
357
+ export function readAgentFirstResponseTimeoutMs(agent, dataDir, standaloneSourceRoot) {
358
+ return cachedFrontmatterValue(_frontmatterFirstResponseCache, agent, dataDir, standaloneSourceRoot, (fm) => {
359
+ const raw = String(fm.firstResponseTimeoutMs ?? '').trim();
360
+ const ms = Number(raw);
361
+ return raw && Number.isFinite(ms) && ms >= 0 ? Math.floor(ms) : null;
362
+ });
363
+ }
364
+
342
365
  // Agents are global definitions (agents/<id>/ under the data dir or the
343
366
  // shipped source root). A spawn of an id with no definition anywhere —
344
367
  // typically a custom agent deleted in settings — must fail loudly instead of
@@ -20,6 +20,7 @@ import { registerJsonProjection } from '../../../runtime/shared/pending-json-pro
20
20
  import { sleep } from '../../../runtime/shared/sleep.mjs';
21
21
 
22
22
  const RETRY_DELAYS_MS = [50, 250, 1000];
23
+ const RETRY_AFTER_FAILURE_MS = 15_000;
23
24
  const unsettled = new Set(); // queues holding unpersisted writes
24
25
  // Exit is the one place a bounded synchronous lock wait is acceptable: the
25
26
  // loop is gone, and a dropped settlement would leave rows "running" forever.
@@ -122,8 +123,15 @@ function replayBatch(batch, args, mergeSet) {
122
123
  replayRun();
123
124
  }
124
125
 
126
+ // A write that cannot reach disk loses a state change other processes rely on
127
+ // (e.g. a deleted Lead row that never leaves the pool), so every failure is
128
+ // reported. In the daemon stderr IS daemon.log (daemon-log.mjs installRedirect).
125
129
  function reportFailure(file, what, error) {
126
- process.stderr.write(`[index-write] ${file}: ${what}: ${error?.message || error}\n`);
130
+ try {
131
+ process.stderr.write(`[index-write] ${file}: ${what}: ${error?.message || error}\n`);
132
+ } catch {
133
+ /* logging is best effort */
134
+ }
127
135
  }
128
136
 
129
137
  /**
@@ -151,9 +159,15 @@ export function createIndexWriteQueue({
151
159
  let pending = []; // op sets not yet handed to a job
152
160
  let inflight = []; // op sets of the running job
153
161
  let running = null;
162
+ const failures = new WeakMap(); // settled job → the error that failed it
154
163
  let timer = null;
164
+ let retryTimer = null;
155
165
 
156
166
  function clearTimer() {
167
+ if (retryTimer) {
168
+ clearTimeout(retryTimer);
169
+ retryTimer = null;
170
+ }
157
171
  if (!timer) return;
158
172
  clearImmediate(timer);
159
173
  timer = null;
@@ -173,8 +187,8 @@ export function createIndexWriteQueue({
173
187
  return;
174
188
  } catch (error) {
175
189
  if (attempt >= RETRY_DELAYS_MS.length) {
176
- reportFailure(file, `dropped ${batch.length} unpersisted write(s)`, error);
177
- return;
190
+ reportFailure(file, `${batch.length} unpersisted write(s) kept queued after retries`, error);
191
+ throw error;
178
192
  }
179
193
  await sleep(RETRY_DELAYS_MS[attempt]);
180
194
  }
@@ -187,23 +201,45 @@ export function createIndexWriteQueue({
187
201
  inflight = pending;
188
202
  pending = [];
189
203
  const batch = inflight;
190
- running = persist(batch).then(() => {
191
- inflight = [];
192
- running = null;
193
- onPersisted();
194
- if (pending.length === 0) {
195
- projection = null;
196
- unsettled.delete(self);
204
+ const job = persist(batch).then(
205
+ () => {
206
+ inflight = [];
207
+ running = null;
208
+ onPersisted();
209
+ if (pending.length === 0) {
210
+ projection = null;
211
+ unsettled.delete(self);
212
+ }
213
+ schedule();
214
+ },
215
+ (error) => {
216
+ // Persistent failure: nothing reached disk. Requeue the batch ahead of
217
+ // newer writes (the projection and `unsettled` keep covering it) so a
218
+ // later flush, write or exit flush retries. Do not reschedule at once,
219
+ // a held foreign lock would otherwise be hammered; a slow unref'd retry
220
+ // keeps a failed LAST write (a delete) from waiting for unrelated traffic.
221
+ failures.set(job, error);
222
+ pending = [...batch, ...pending];
223
+ inflight = [];
224
+ running = null;
225
+ retryTimer = setTimeout(() => {
226
+ retryTimer = null;
227
+ schedule();
228
+ }, RETRY_AFTER_FAILURE_MS);
229
+ retryTimer.unref?.();
197
230
  }
198
- schedule();
199
- });
231
+ );
232
+ running = job;
200
233
  }
201
234
 
202
- /** Resolves once everything written so far is on disk (or dropped). */
235
+ /** Resolves once everything written so far is on disk; rejects when a persist
236
+ * failed for good (the writes stay queued for a later flush). */
203
237
  async function flush() {
204
238
  for (;;) {
205
239
  if (running) {
206
- await running;
240
+ const job = running;
241
+ await job;
242
+ if (failures.has(job)) throw failures.get(job);
207
243
  continue;
208
244
  }
209
245
  if (pending.length === 0) return;
@@ -212,10 +248,16 @@ export function createIndexWriteQueue({
212
248
  }
213
249
  }
214
250
 
215
- /** Exit path: persist inflight + pending ops synchronously (bounded lock wait). */
251
+ /** Persist pending ops synchronously (bounded lock wait). While an async job
252
+ * runs it owns the lock (and its ops are in flight): never wait on it, take
253
+ * over its lock, or replay its ops — report false and let that job and its
254
+ * follow-ups drain. At the last-resort process 'exit' hook that is
255
+ * best-effort: the graceful shutdown path drains before exit. */
216
256
  function flushSync() {
217
- const ops = [...inflight, ...pending];
218
- if (!file || ops.length === 0) return true;
257
+ if (!file) return true;
258
+ if (running) return false;
259
+ const ops = pending;
260
+ if (ops.length === 0) return true;
219
261
  clearTimer();
220
262
  pending = [];
221
263
  try {
@@ -225,10 +267,10 @@ export function createIndexWriteQueue({
225
267
  });
226
268
  } catch (error) {
227
269
  reportFailure(file, `synchronous flush of ${ops.length} write(s) failed; kept queued`, error);
228
- pending = ops;
270
+ pending = [...ops, ...pending];
271
+ schedule();
229
272
  return false;
230
273
  }
231
- inflight = [];
232
274
  projection = null;
233
275
  unsettled.delete(self);
234
276
  onPersisted();
@@ -251,9 +293,11 @@ export function createIndexWriteQueue({
251
293
  version += 1;
252
294
  pending.push(rerun ? mutator : ops);
253
295
  unsettled.add(self);
296
+ installProcessExitFlush();
254
297
  schedule();
255
298
  return next;
256
- } catch {
299
+ } catch (error) {
300
+ reportFailure(file, 'write rejected (mutator or document rewrite threw); nothing queued', error);
257
301
  return null;
258
302
  }
259
303
  },
@@ -266,6 +310,23 @@ export function createIndexWriteQueue({
266
310
  };
267
311
  }
268
312
 
313
+ let processExitFlushInstalled = false;
314
+
315
+ /** The process owns last-resort exit flushing of every queue holding unpersisted
316
+ * writes, so a disposed (e.g. evicted) runtime needs no exit callback of its
317
+ * own. Best effort: a persist still running is left to the graceful drain. */
318
+ function installProcessExitFlush() {
319
+ if (processExitFlushInstalled) return;
320
+ processExitFlushInstalled = true;
321
+ process.on('exit', () => {
322
+ try {
323
+ flushAllIndexWritesSync();
324
+ } catch {
325
+ /* exit flush is best effort */
326
+ }
327
+ });
328
+ }
329
+
269
330
  /** Synchronous variant (exit paths, tests that read the file directly). */
270
331
  export function flushAllIndexWritesSync() {
271
332
  for (const queue of [...unsettled]) queue.flushSync();
@@ -57,13 +57,18 @@ export function terminalResultHook({ job, turnReview, completionValue, notifyEar
57
57
  };
58
58
  }
59
59
 
60
- /** Watchdog stall that still recovered a partial handoff: a completion. */
60
+ /** Watchdog stall that still recovered a partial handoff: the turn never
61
+ * finished, so the owner is told it FAILED (stalled), with the partial
62
+ * output it produced before the stop. */
63
+ export const WATCHDOG_STOP_ERROR = 'stalled: the progress watchdog stopped the turn';
64
+
61
65
  export function reconcileJobWatchdogPartial(job, value) {
62
66
  if (!job?.taskId) return;
63
67
  try {
64
68
  reconcileBackgroundTask(job.taskId, {
65
- status: 'completed',
69
+ status: 'failed',
66
70
  result: value,
71
+ error: WATCHDOG_STOP_ERROR,
67
72
  terminalReason: 'agent-watchdog-partial',
68
73
  });
69
74
  } catch {}
@@ -38,7 +38,7 @@ export function terminalJobFrozenFields(status, now = Date.now()) {
38
38
  }
39
39
 
40
40
  /** A worker/job row as the published session state carries it. That state
41
- * (statusline, desktop, phone, live-share viewers) re-reads agent status on a
41
+ * (statusline, desktop, phone) re-reads agent status on a
42
42
  * 2s pulse, and these fields are the agent card's diagnostics, derived from
43
43
  * the read time or the last stream delta: they changed on every read while
44
44
  * nothing a surface shows did, so each pulse re-sent both row lists. Surfaces
@@ -64,7 +64,10 @@ export function createSessionProgress({ mgr }) {
64
64
  const runtime = mgr.getSessionRuntime?.(sessionId) || null;
65
65
  const snapshot =
66
66
  typeof mgr.getSessionProgressSnapshot === 'function' ? mgr.getSessionProgressSnapshot(sessionId) : null;
67
- const policy = role ? resolveAgentWatchdogPolicy(role) : null;
67
+ // The armed watchdog's own policy (agent definition and provider budget
68
+ // applied); the role default only when none is registered.
69
+ const watchdogState = getProgressWatchdogState(mgr, sessionId);
70
+ const policy = watchdogState.policy || (role ? resolveAgentWatchdogPolicy(role) : null);
68
71
  const queuedFollowups =
69
72
  typeof mgr.getSessionPendingMessageDepth === 'function' ? mgr.getSessionPendingMessageDepth(sessionId) : null;
70
73
  return buildAgentTaskProgressFields({
@@ -74,7 +77,7 @@ export function createSessionProgress({ mgr }) {
74
77
  snapshot,
75
78
  runtime,
76
79
  policy,
77
- watchdogState: getProgressWatchdogState(mgr, sessionId),
80
+ watchdogState,
78
81
  queuedFollowups,
79
82
  taskStatus,
80
83
  lastToolCall: runtime?.lastToolCall || null,
@@ -0,0 +1,29 @@
1
+ // Ids of deleted Leads, shared by every lead-index instance of the process that
2
+ // uses one data dir. The delete runs in the control runtime while the deleted
3
+ // session's own (still loaded) runtime keeps settling turns through ITS index
4
+ // instance; a per-instance set never sees the delete, so that late idle upsert
5
+ // wrote the row back. The store's write fence (explicit deletes) is consulted
6
+ // as well, so a fenced id can never be added whichever instance asks.
7
+ import { resolve } from 'node:path';
8
+ import { isSessionWriteFenced } from '../../../../runtime/agent/orchestrator/session/store/live-state.mjs';
9
+
10
+ const FORGOTTEN_LEADS_MAX = 1024;
11
+ const registries = new Map(); // resolved data dir -> Set<sessionId>
12
+
13
+ export function createForgottenLeads(dataDir) {
14
+ const key = dataDir ? resolve(dataDir) : '';
15
+ let ids = registries.get(key);
16
+ if (!ids) {
17
+ ids = new Set();
18
+ registries.set(key, ids);
19
+ }
20
+ return {
21
+ /** A deleted Lead must never be written to the index again. */
22
+ forget(sessionId) {
23
+ ids.delete(sessionId);
24
+ ids.add(sessionId);
25
+ if (ids.size > FORGOTTEN_LEADS_MAX) ids.delete(ids.values().next().value);
26
+ },
27
+ isForgotten: (sessionId) => ids.has(sessionId) || isSessionWriteFenced(sessionId),
28
+ };
29
+ }
@@ -42,7 +42,7 @@ export function createLeadIndexFile({ dataDir }) {
42
42
  return parsed ? normalizeLeadRows(parsed) : [];
43
43
  }
44
44
 
45
- const write = (mutator) => queue.write(mutator);
45
+ const write = (mutator, options) => queue.write(mutator, options);
46
46
 
47
47
  return { path, read, write, flush: queue.flush, flushSync: queue.flushSync };
48
48
  }
@@ -6,10 +6,9 @@ import { leadPoolTag } from '../worker-rows.mjs';
6
6
  export const ACTIVE_LEAD_STATUS =
7
7
  /^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
8
8
 
9
- // Mirror of the pool reader's freshness window (store-summary-reader): a row is
10
- // only believed to be working while its heartbeat sidecar or its own stamp sits
11
- // inside this window. Recovery applies the SAME rule, so the index can never
12
- // keep claiming work the panel has already stopped believing.
9
+ // Recovery's freshness window: an active row whose turn is not in flight in
10
+ // this daemon is only believed while its own stamp sits inside this window
11
+ // (it covers a row written just before its turn's runtime entry exists).
13
12
  export const LEAD_POOL_FRESH_MS = 2 * 60 * 1000;
14
13
 
15
14
  export const isActiveLeadRow = (row) => ACTIVE_LEAD_STATUS.test(clean(row?.status || row?.stage));