mixdog 1.2.2 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (692) hide show
  1. package/README.md +18 -0
  2. package/package.json +2 -1
  3. package/scripts/gate-local.mjs +6 -4
  4. package/scripts/lib/gate-scheduler.mjs +29 -11
  5. package/scripts/probe-provider-catalog.mjs +31 -0
  6. package/scripts/provider-pingpong-live.mjs +599 -0
  7. package/scripts/session-sweep.mjs +5 -25
  8. package/src/agents/advisor/AGENT.md +1 -1
  9. package/src/agents/advisor/agent.json +1 -1
  10. package/src/agents/maintainer/AGENT.md +1 -1
  11. package/src/agents/maintainer/agent.json +1 -1
  12. package/src/agents/reviewer/AGENT.md +2 -4
  13. package/src/agents/security/AGENT.md +1 -2
  14. package/src/agents/writer/AGENT.md +2 -3
  15. package/src/defaults/shipped-history.json +11 -1
  16. package/src/defaults/skills/image/SKILL.md +21 -23
  17. package/src/defaults/skills/setup/SKILL.md +6 -1
  18. package/src/defaults/skills/setup/references/actions.md +44 -22
  19. package/src/defaults/skills/setup/references/surfaces.md +10 -8
  20. package/src/headless-exec.mjs +15 -8
  21. package/src/lib/keychain-cjs.cjs +20 -15
  22. package/src/output-styles/common.md +11 -10
  23. package/src/rules/agent/AGENT.md +6 -4
  24. package/src/rules/lead/LEAD.md +7 -9
  25. package/src/rules/shared/45-destructive.md +4 -0
  26. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  28. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  29. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +92 -61
  30. package/src/runtime/agent/orchestrator/cache-mtime.mjs +10 -1
  31. package/src/runtime/agent/orchestrator/config-providers-merge.mjs +7 -0
  32. package/src/runtime/agent/orchestrator/config.mjs +5 -0
  33. package/src/runtime/agent/orchestrator/context/collect.mjs +1 -0
  34. package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +26 -7
  35. package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +112 -7
  36. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  37. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  38. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  39. package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +48 -20
  40. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +3 -1
  41. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +24 -17
  42. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +9 -9
  43. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  45. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +31 -15
  46. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-blocks.mjs +20 -1
  47. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-delta.mjs +15 -2
  48. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/content-block-start.mjs +11 -4
  49. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events/message-events.mjs +3 -0
  50. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-events.mjs +12 -5
  51. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-outcome.mjs +1 -0
  52. package/src/runtime/agent/orchestrator/providers/anthropic-sse-turn/turn-state.mjs +14 -0
  53. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +2 -0
  54. package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +9 -0
  55. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +10 -0
  56. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  57. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  58. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +131 -9
  59. package/src/runtime/agent/orchestrator/providers/antigravity-response.mjs +29 -10
  60. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +125 -8
  61. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +12 -62
  62. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +117 -41
  63. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +117 -72
  65. package/src/runtime/agent/orchestrator/providers/compat-request-policy.mjs +78 -2
  66. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +39 -5
  67. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  68. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  69. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  70. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  71. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  72. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +42 -11
  73. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +109 -6
  74. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +17 -4
  75. package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -2
  76. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +73 -7
  77. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +75 -6
  78. package/src/runtime/agent/orchestrator/providers/custom-reasoning.mjs +34 -7
  79. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +32 -6
  80. package/src/runtime/agent/orchestrator/providers/deepseek.mjs +67 -0
  81. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +29 -5
  82. package/src/runtime/agent/orchestrator/providers/gemini-cache-policy.mjs +11 -4
  83. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +36 -13
  84. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +101 -11
  85. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +41 -5
  86. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  87. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  88. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +19 -14
  89. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +371 -41
  90. package/src/runtime/agent/orchestrator/providers/gemini-sdk-request.mjs +1 -2
  91. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +97 -49
  92. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +81 -10
  93. package/src/runtime/agent/orchestrator/providers/gemini.mjs +35 -8
  94. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +1 -0
  96. package/src/runtime/agent/orchestrator/providers/lib/action-input-contract.mjs +60 -0
  97. package/src/runtime/agent/orchestrator/providers/lib/anthropic-native-blocks.mjs +1 -0
  98. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +253 -42
  99. package/src/runtime/agent/orchestrator/providers/lib/anthropic-server-tool-usage.mjs +18 -0
  100. package/src/runtime/agent/orchestrator/providers/lib/anthropic-system-blocks.mjs +27 -6
  101. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +392 -0
  102. package/src/runtime/agent/orchestrator/providers/lib/inclusive-usage.mjs +54 -0
  103. package/src/runtime/agent/orchestrator/providers/lib/origin-bound-fetch.mjs +16 -0
  104. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  105. package/src/runtime/agent/orchestrator/providers/lib/responses-terminal-fields.mjs +11 -0
  106. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +8 -0
  107. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +50 -22
  108. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +133 -21
  109. package/src/runtime/agent/orchestrator/providers/mimo-oauth-profile.mjs +13 -15
  110. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  111. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +1 -1
  112. package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
  113. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +92 -16
  114. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +13 -13
  115. package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +2 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +133 -62
  117. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/chunk-events.mjs +35 -14
  118. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-result.mjs +5 -2
  119. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +39 -7
  120. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/tool-call-acc.mjs +2 -9
  121. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  122. package/src/runtime/agent/orchestrator/providers/openai-compat-error-contract.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +84 -2
  124. package/src/runtime/agent/orchestrator/providers/openai-compat-options.mjs +47 -25
  125. package/src/runtime/agent/orchestrator/providers/openai-compat-presets.mjs +5 -1
  126. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +155 -0
  127. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +40 -24
  128. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-events.mjs +63 -25
  129. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-head-parity.json +2901 -0
  130. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +183 -0
  131. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +87 -6
  132. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  133. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +7 -1
  134. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +2 -0
  135. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +103 -26
  136. package/src/runtime/agent/orchestrator/providers/openai-compat-xai-send.mjs +23 -4
  137. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +11 -6
  138. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +17 -2
  139. package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +15 -23
  140. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  141. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/output-items.mjs +23 -10
  142. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +28 -5
  143. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events.mjs +10 -0
  144. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-items.mjs +18 -7
  145. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-outcome.mjs +4 -0
  146. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-state.mjs +5 -0
  147. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/text-relay.mjs +9 -1
  148. package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +80 -0
  149. package/src/runtime/agent/orchestrator/providers/openai-oauth-dispatch.mjs +3 -1
  150. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +7 -0
  151. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +7 -1
  152. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +72 -24
  153. package/src/runtime/agent/orchestrator/providers/openai-responses-payload-parity.fixture.json +323 -0
  154. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +50 -16
  155. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +7 -19
  156. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/refusals.mjs +60 -0
  157. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +51 -36
  158. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state.mjs +30 -0
  159. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/event-switch.mjs +12 -0
  160. package/src/runtime/agent/orchestrator/providers/openai-ws-stream/terminal-frames.mjs +25 -6
  161. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +18 -9
  162. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +181 -0
  163. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +78 -70
  164. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +74 -0
  165. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +150 -10
  166. package/src/runtime/agent/orchestrator/providers/registry.mjs +13 -2
  167. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +7 -1
  168. package/src/runtime/agent/orchestrator/providers/transport-scope.d.mts +6 -0
  169. package/src/runtime/agent/orchestrator/providers/transport-scope.mjs +28 -0
  170. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +164 -0
  171. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +522 -0
  172. package/src/runtime/agent/orchestrator/providers/xai-tool-search-head-parity.json +1131 -0
  173. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +195 -0
  174. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +104 -0
  175. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  176. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +24 -0
  177. package/src/runtime/agent/orchestrator/runtime-core/effort.mjs +15 -0
  178. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  179. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  180. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  181. package/src/runtime/agent/orchestrator/runtime-core/provider-request-snapshot.mjs +7 -3
  182. package/src/runtime/agent/orchestrator/runtime-core/session-title.mjs +21 -1
  183. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +16 -3
  184. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  185. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +526 -0
  186. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-data.mjs +3 -0
  187. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog-schema.mjs +10 -7
  188. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +178 -71
  189. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +102 -12
  190. package/src/runtime/agent/orchestrator/runtime-core/tool-exposure.mjs +96 -0
  191. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  192. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  193. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  194. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  195. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  196. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +5 -11
  197. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  198. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +3 -2
  199. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +16 -93
  200. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  201. package/src/runtime/agent/orchestrator/session/compact/summary-anchor.mjs +5 -0
  202. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +148 -0
  203. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  204. package/src/runtime/agent/orchestrator/session/context-tool-schema.mjs +17 -2
  205. package/src/runtime/agent/orchestrator/session/context-utils.mjs +8 -4
  206. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  207. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  208. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +3 -2
  209. package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +6 -1
  210. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  211. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  212. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +89 -1
  213. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +1 -1
  214. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +56 -0
  215. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +18 -8
  216. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +1 -27
  217. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  218. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  219. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  220. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +24 -10
  221. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +135 -0
  222. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +31 -4
  223. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  224. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +67 -20
  225. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +10 -10
  226. package/src/runtime/agent/orchestrator/session/loop/tool-call-resolution.mjs +95 -0
  227. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  228. package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +30 -3
  229. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +29 -5
  230. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +15 -1
  231. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +147 -0
  232. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +7 -5
  233. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  234. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  235. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +23 -2
  236. package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +34 -12
  237. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +54 -13
  238. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  239. package/src/runtime/agent/orchestrator/session/manager/ask-turn-loop-options.mjs +57 -25
  240. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +11 -0
  241. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +22 -0
  242. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  243. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +8 -0
  244. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  245. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  246. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  247. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +231 -16
  248. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  249. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  250. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +47 -17
  251. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +26 -4
  252. package/src/runtime/agent/orchestrator/session/manager/session-fallback-title.mjs +82 -0
  253. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +36 -35
  254. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  255. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +6 -3
  256. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +4 -1
  257. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  258. package/src/runtime/agent/orchestrator/session/manager.mjs +4 -10
  259. package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +6 -0
  260. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  261. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +17 -1
  262. package/src/runtime/agent/orchestrator/session/side-question-store.mjs +96 -0
  263. package/src/runtime/agent/orchestrator/session/side-question.mjs +197 -0
  264. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +22 -15
  265. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  266. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  267. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  268. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +23 -0
  269. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  270. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  271. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  272. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +44 -37
  273. package/src/runtime/agent/orchestrator/session/store/session-observers.mjs +4 -2
  274. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  275. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  276. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  277. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -21
  278. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  279. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  280. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  281. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +4 -2
  282. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  283. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  284. package/src/runtime/agent/orchestrator/session/store-summary-archived-agent.mjs +34 -15
  285. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +53 -115
  286. package/src/runtime/agent/orchestrator/session/store-summary-fields.mjs +8 -0
  287. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +10 -1
  288. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  289. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  290. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +17 -10
  291. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  292. package/src/runtime/agent/orchestrator/session/store.mjs +22 -19
  293. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +12 -12
  294. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +38 -14
  295. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  296. package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +1 -1
  297. package/src/runtime/agent/orchestrator/session/tool-batch/state.mjs +7 -1
  298. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +4 -0
  299. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +79 -0
  300. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  301. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  302. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  303. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +8 -2
  304. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/command-preflight.mjs +3 -3
  305. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  306. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  307. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +4 -1
  308. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +218 -20
  309. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  310. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  311. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  312. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  313. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  314. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  315. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  316. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +247 -49
  317. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  318. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  319. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.mjs +23 -1
  320. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  321. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  322. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch/root-resolution.mjs +1 -1
  323. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1 -1
  324. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  325. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  326. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  327. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  328. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  329. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  330. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  331. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  332. package/src/runtime/agent/orchestrator/tools/patch/ui-diff.mjs +73 -39
  333. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +18 -1
  334. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +7 -4
  335. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +88 -12
  336. package/src/runtime/agent/orchestrator/tools/shell-policy.mjs +2 -0
  337. package/src/runtime/attachments/store.d.mts +9 -0
  338. package/src/runtime/attachments/store.mjs +80 -9
  339. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  340. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  341. package/src/runtime/computer-bridge/action-schema.mjs +219 -196
  342. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  343. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  344. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  345. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  346. package/src/runtime/github/tool.mjs +208 -17
  347. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  348. package/src/runtime/media/catalog.mjs +4 -4
  349. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  350. package/src/runtime/media/defaults.mjs +37 -0
  351. package/src/runtime/media/jobs.mjs +12 -2
  352. package/src/runtime/media/lanes.mjs +12 -0
  353. package/src/runtime/media/tool-defs.mjs +15 -4
  354. package/src/runtime/media/tool.mjs +41 -12
  355. package/src/runtime/media/upstream-error.mjs +72 -6
  356. package/src/runtime/memory/index.mjs +1 -0
  357. package/src/runtime/memory/lib/http-router/ingest-routes.mjs +22 -1
  358. package/src/runtime/memory/lib/ingest/transcript-offsets.mjs +2 -0
  359. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  360. package/src/runtime/memory/lib/pg/adapter.mjs +98 -1
  361. package/src/runtime/memory/lib/pg/process.mjs +36 -33
  362. package/src/runtime/memory/lib/pg/run-child.mjs +49 -0
  363. package/src/runtime/memory/lib/pg/supervisor.mjs +112 -4
  364. package/src/runtime/memory/lib/runtime-fetcher.mjs +12 -13
  365. package/src/runtime/memory/lib/transcript-ingest.mjs +14 -0
  366. package/src/runtime/office/README.md +1 -1
  367. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  368. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  369. package/src/runtime/office/authoring/html-document-author.mjs +2 -0
  370. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  371. package/src/runtime/office/authoring/pptx-contact-sheet.mjs +2 -0
  372. package/src/runtime/office/authoring/pptx-html-measure.mjs +3 -1
  373. package/src/runtime/office/authoring/pptx-html-runner.mjs +2 -0
  374. package/src/runtime/office/authoring/xlsx-html-runner.mjs +3 -1
  375. package/src/runtime/office/core/office-actions-read.mjs +3 -0
  376. package/src/runtime/office/core/office-render-preview.mjs +2 -0
  377. package/src/runtime/office/core/office-session-dispatch.mjs +7 -0
  378. package/src/runtime/office/core/office-sessionless-actions.mjs +8 -0
  379. package/src/runtime/office/core/office-sessions.mjs +5 -0
  380. package/src/runtime/office/core/office-transactions.mjs +3 -0
  381. package/src/runtime/office/core/office-write-ledger.mjs +94 -0
  382. package/src/runtime/office/design/library/templates/mixdog-executive.mixdog-edit.pptx +0 -0
  383. package/src/runtime/office/index.mjs +29 -0
  384. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  385. package/src/runtime/office/pdf/pdf-edit-document.mjs +2 -0
  386. package/src/runtime/office/pdf/pdf-render.mjs +23 -7
  387. package/src/runtime/office/pdf/pdf-security.mjs +2 -0
  388. package/src/runtime/office/portable/portable-opc.mjs +4 -1
  389. package/src/runtime/office/quality/visual-diff.mjs +2 -0
  390. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  391. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  392. package/src/runtime/shared/atomic-file.d.mts +1 -1
  393. package/src/runtime/shared/background-tasks.mjs +6 -1
  394. package/src/runtime/shared/bounded-file-read.mjs +13 -0
  395. package/src/runtime/shared/bounded-line-diff.mjs +191 -0
  396. package/src/runtime/shared/browser-launch.mjs +15 -0
  397. package/src/runtime/shared/buffered-appender.mjs +18 -0
  398. package/src/runtime/shared/config.mjs +78 -18
  399. package/src/runtime/shared/err-text.mjs +48 -4
  400. package/src/runtime/shared/file-lock.mjs +6 -5
  401. package/src/runtime/shared/file-permissions.d.mts +6 -1
  402. package/src/runtime/shared/file-permissions.mjs +54 -6
  403. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  404. package/src/runtime/shared/llm/anthropic-effort.mjs +6 -0
  405. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  406. package/src/runtime/shared/llm/usage-accounting.mjs +5 -2
  407. package/src/runtime/shared/llm/usage-ledger-rollup.mjs +3 -0
  408. package/src/runtime/shared/loopback-listener.mjs +9 -0
  409. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  410. package/src/runtime/shared/model-route-chain.mjs +48 -0
  411. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  412. package/src/runtime/shared/pid-liveness.mjs +12 -0
  413. package/src/runtime/shared/provider-api-key.mjs +8 -0
  414. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  415. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  416. package/src/runtime/shared/quiet-progress.mjs +101 -0
  417. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  418. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  419. package/src/runtime/shared/remote-intent.mjs +2 -42
  420. package/src/runtime/shared/review-diff.mjs +52 -0
  421. package/src/runtime/shared/session-sidebar-host.d.mts +4 -0
  422. package/src/runtime/shared/session-sidebar-host.mjs +38 -0
  423. package/src/runtime/shared/slow-span.mjs +121 -0
  424. package/src/runtime/shared/statusline/statusline-segments.mjs +52 -6
  425. package/src/runtime/shared/tool-card-model/card-header.mjs +7 -1
  426. package/src/runtime/shared/tool-card-model/generic-detail.mjs +39 -5
  427. package/src/runtime/shared/tool-card-model.mjs +5 -2
  428. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  429. package/src/runtime/shared/tool-output-limit.mjs +4 -0
  430. package/src/runtime/shared/tool-primitives.mjs +13 -0
  431. package/src/runtime/shared/tool-result-summary.mjs +22 -1
  432. package/src/runtime/shared/tool-status.mjs +3 -2
  433. package/src/runtime/shared/tool-surface.mjs +20 -6
  434. package/src/runtime/shared/tool-work-units.mjs +54 -11
  435. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  436. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  437. package/src/runtime/shared/transcript-writer/purge.mjs +74 -0
  438. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  439. package/src/runtime/shared/transcript-writer.mjs +24 -6
  440. package/src/runtime/shared/turn-changes.mjs +269 -100
  441. package/src/runtime/shared/turn-review-reply.mjs +8 -39
  442. package/src/runtime/shared/turn-snapshot-store.mjs +19 -108
  443. package/src/runtime/shared/turn-snapshot.mjs +865 -683
  444. package/src/runtime/shared/turn-worktree-snapshot.mjs +183 -255
  445. package/src/runtime/shared/user-data-guard.mjs +262 -49
  446. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  447. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  448. package/src/runtime/shared/worktrees/carry.mjs +533 -0
  449. package/src/runtime/shared/worktrees/contract.mjs +60 -0
  450. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  451. package/src/runtime/shared/worktrees/file-recovery.mjs +84 -0
  452. package/src/runtime/shared/worktrees/git-head.mjs +214 -0
  453. package/src/runtime/shared/worktrees/git.mjs +8 -3
  454. package/src/runtime/shared/worktrees/include.mjs +125 -7
  455. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  456. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  457. package/src/runtime/shared/worktrees/manager.mjs +525 -31
  458. package/src/runtime/shared/worktrees/merge.mjs +31 -21
  459. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  460. package/src/runtime/shared/worktrees/paths.d.mts +6 -0
  461. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  462. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  463. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  464. package/src/runtime/terminal-bridge/client.mjs +57 -20
  465. package/src/runtime/terminal-bridge/tool-defs.mjs +13 -6
  466. package/src/runtime/tidy/apply.mjs +47 -2
  467. package/src/runtime/tidy/run-engines.mjs +11 -5
  468. package/src/session-runtime/agent-tool-routing.mjs +19 -13
  469. package/src/session-runtime/boot/apis.mjs +20 -6
  470. package/src/session-runtime/boot/config.mjs +2 -0
  471. package/src/session-runtime/boot/facade.mjs +4 -0
  472. package/src/session-runtime/boot/infrastructure.mjs +6 -1
  473. package/src/session-runtime/boot/session.mjs +3 -3
  474. package/src/session-runtime/boot/tools.mjs +7 -1
  475. package/src/session-runtime/conversation-import/service.mjs +1 -1
  476. package/src/session-runtime/cwd-plugins/cwd-apply.mjs +12 -5
  477. package/src/session-runtime/goal-facade-api.mjs +2 -2
  478. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +91 -0
  479. package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +3 -1
  480. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +15 -5
  481. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +137 -26
  482. package/src/session-runtime/internal-tool-executor.mjs +8 -2
  483. package/src/session-runtime/lifecycle/cold-heir.mjs +187 -0
  484. package/src/session-runtime/lifecycle/inheritance.mjs +71 -27
  485. package/src/session-runtime/lifecycle/session-catalog.mjs +25 -18
  486. package/src/session-runtime/lifecycle/session-switch/resume.mjs +6 -0
  487. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +36 -48
  488. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  489. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  490. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  491. package/src/session-runtime/lifecycle/teardown.mjs +70 -14
  492. package/src/session-runtime/lifecycle-api.mjs +1 -0
  493. package/src/session-runtime/mcp-glue/connect.mjs +17 -5
  494. package/src/session-runtime/media-api.mjs +8 -0
  495. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  496. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  497. package/src/session-runtime/model-route/set-route.mjs +116 -36
  498. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  499. package/src/session-runtime/model-route-api.mjs +4 -2
  500. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  501. package/src/session-runtime/native-web-search-usage.mjs +51 -0
  502. package/src/session-runtime/native-web-search.mjs +19 -9
  503. package/src/session-runtime/new-session-config.mjs +4 -2
  504. package/src/session-runtime/provider-auth/login.mjs +4 -0
  505. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  506. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  507. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  508. package/src/session-runtime/provider-models.mjs +1 -0
  509. package/src/session-runtime/provider-usage.mjs +4 -0
  510. package/src/session-runtime/resource-scope-decorate.mjs +10 -3
  511. package/src/session-runtime/route-resolution.mjs +3 -1
  512. package/src/session-runtime/runtime-core.mjs +4 -0
  513. package/src/session-runtime/runtime-facade.mjs +6 -0
  514. package/src/session-runtime/runtime-review-api.mjs +8 -2
  515. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  516. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  517. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  518. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  519. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  520. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  521. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  522. package/src/session-runtime/services/agent-tool/index-write-queue.mjs +81 -20
  523. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  524. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  525. package/src/session-runtime/services/agent-tool/lead-worker-index/forgotten-leads.mjs +29 -0
  526. package/src/session-runtime/services/agent-tool/lead-worker-index/index-file.mjs +1 -1
  527. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  528. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  529. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  530. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +82 -13
  531. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  532. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  533. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  534. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  535. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  536. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  537. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  538. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  539. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  540. package/src/session-runtime/services/agent-tool/tag-registry.mjs +18 -10
  541. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  542. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  543. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  544. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  545. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  546. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  547. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  548. package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +10 -1
  549. package/src/session-runtime/services/agent-tool/worker-index.mjs +74 -15
  550. package/src/session-runtime/services/agent-tool.mjs +7 -0
  551. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  552. package/src/session-runtime/services/channel-admin.mjs +19 -3
  553. package/src/session-runtime/services/memory-runtime-proxy/calls.mjs +4 -0
  554. package/src/session-runtime/services/memory-runtime-proxy.mjs +1 -0
  555. package/src/session-runtime/services/provider-admin.mjs +158 -15
  556. package/src/session-runtime/session-create/session-options.mjs +7 -5
  557. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  558. package/src/session-runtime/session-transcript-purge.mjs +32 -0
  559. package/src/session-runtime/session-transcript.mjs +4 -5
  560. package/src/session-runtime/session-turn-api.mjs +17 -14
  561. package/src/session-runtime/settings-builtin-tools-api.mjs +18 -6
  562. package/src/session-runtime/setup-tool/executor.mjs +57 -9
  563. package/src/session-runtime/setup-tool/extended-actions.mjs +86 -6
  564. package/src/session-runtime/setup-tool/settings-contract.mjs +18 -3
  565. package/src/session-runtime/setup-tool/tool-defs.mjs +25 -4
  566. package/src/session-runtime/skills-api.mjs +3 -5
  567. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  568. package/src/session-runtime/tool-surface.mjs +5 -1
  569. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  570. package/src/session-runtime/turn/compaction-gate.mjs +25 -0
  571. package/src/session-runtime/turn/session-ops.mjs +7 -5
  572. package/src/session-runtime/turn/side-question-ops.mjs +19 -0
  573. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +7 -1
  574. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +12 -3
  575. package/src/session-runtime/turn/turn-run/turn-settle.mjs +18 -2
  576. package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
  577. package/src/session-runtime/turn/turn-run.mjs +26 -45
  578. package/src/session-runtime/usage-stats-api.mjs +46 -11
  579. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  580. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  581. package/src/session-runtime/workspace/project-branches.mjs +35 -41
  582. package/src/session-runtime/workspace/transition-steps.mjs +215 -116
  583. package/src/session-runtime/workspace/transitions.mjs +428 -73
  584. package/src/standalone/channel-transport.mjs +3 -4
  585. package/src/standalone/daemon-agent-control.mjs +9 -1
  586. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  587. package/src/standalone/daemon-local-session-bridge.mjs +14 -1
  588. package/src/standalone/daemon-owner.mjs +17 -4
  589. package/src/standalone/daemon-pg-stop.mjs +49 -0
  590. package/src/standalone/daemon-session-control.mjs +88 -0
  591. package/src/standalone/daemon-stop-budget.d.mts +2 -0
  592. package/src/standalone/daemon-stop-budget.mjs +18 -0
  593. package/src/standalone/daemon-stored-session-views.mjs +25 -3
  594. package/src/standalone/daemon-telemetry.mjs +19 -0
  595. package/src/standalone/daemon.mjs +63 -1
  596. package/src/standalone/desktop-service-registry.mjs +5 -0
  597. package/src/standalone/local-session-runtime.mjs +80 -30
  598. package/src/standalone/session-client.mjs +42 -0
  599. package/src/standalone/session-protocol.mjs +14 -0
  600. package/src/standalone/session-proxy/projection.mjs +41 -4
  601. package/src/standalone/session-runtime-inline-host/boot-loaders.mjs +15 -1
  602. package/src/standalone/session-runtime-inline-host.mjs +3 -0
  603. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  604. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  605. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  606. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  607. package/src/standalone/session-service/agent-tree.mjs +28 -2
  608. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  609. package/src/standalone/session-service/entries.mjs +1 -0
  610. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  611. package/src/standalone/session-service/quota-resume.mjs +28 -13
  612. package/src/standalone/session-service/session-calls/session-action.mjs +18 -3
  613. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  614. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  615. package/src/standalone/session-service-api.mjs +6 -1
  616. package/src/standalone/session-state-patch.d.mts +2 -1
  617. package/src/standalone/session-state-patch.mjs +41 -1
  618. package/src/standalone/session-tool-output.mjs +82 -0
  619. package/src/tui/App.jsx +25 -0
  620. package/src/tui/app/app-view/floating-panel.jsx +26 -1
  621. package/src/tui/app/app-view.jsx +2 -1
  622. package/src/tui/app/btw-controller.mjs +118 -0
  623. package/src/tui/app/create-app-pickers.mjs +2 -0
  624. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  625. package/src/tui/app/provider-setup-picker.mjs +15 -3
  626. package/src/tui/app/shell-layout/row-budgets.mjs +11 -1
  627. package/src/tui/app/shell-layout/surfaces.mjs +3 -1
  628. package/src/tui/app/slash-commands.mjs +19 -3
  629. package/src/tui/app/slash-dispatch/session-commands.mjs +68 -6
  630. package/src/tui/app/use-global-key-input/approval-shortcut.mjs +12 -0
  631. package/src/tui/app/use-global-key-input.mjs +5 -12
  632. package/src/tui/app/use-prompt-handlers.mjs +11 -0
  633. package/src/tui/components/BtwPanel.jsx +53 -0
  634. package/src/tui/components/QuestionPanel.jsx +275 -0
  635. package/src/tui/components/Spinner.jsx +4 -0
  636. package/src/tui/components/SpinnerByline.jsx +21 -2
  637. package/src/tui/components/question-panel-model.mjs +156 -0
  638. package/src/tui/components/status-line/local-line.mjs +10 -2
  639. package/src/tui/dist/index.mjs +2897 -1722
  640. package/src/tui/session/active-tool-summary.mjs +1 -1
  641. package/src/tui/session/context-state.mjs +4 -5
  642. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  643. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  644. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  645. package/src/tui/session/quota-resume.mjs +140 -61
  646. package/src/tui/session/session-api/commands.mjs +14 -10
  647. package/src/tui/session/session-api/controls.mjs +14 -2
  648. package/src/tui/session/session-api/integrations.mjs +9 -2
  649. package/src/tui/session/session-api/lifecycle/dispose.mjs +3 -9
  650. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  651. package/src/tui/session/session-api/lifecycle.mjs +14 -11
  652. package/src/tui/session/session-api/media.mjs +2 -0
  653. package/src/tui/session/session-api/routes.mjs +81 -57
  654. package/src/tui/session/session-api/settings.mjs +9 -3
  655. package/src/tui/session/session-api/worktree.mjs +3 -2
  656. package/src/tui/session/session-api.mjs +1 -0
  657. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  658. package/src/tui/session/session-flow/drain.mjs +6 -4
  659. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  660. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  661. package/src/tui/session/session-flow/queue.mjs +1 -1
  662. package/src/tui/session/tool-approval.mjs +20 -8
  663. package/src/tui/session/transcript-spill.mjs +14 -7
  664. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  665. package/src/tui/session/tui-steering-persist.mjs +3 -5
  666. package/src/tui/session/turn-quiet.mjs +53 -0
  667. package/src/tui/session/turn-stream.mjs +179 -32
  668. package/src/tui/session/turn.mjs +50 -36
  669. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  670. package/src/tui/spinner-meta.mjs +10 -0
  671. package/src/tui/spinner-verbs.mjs +3 -0
  672. package/src/ui/statusline.mjs +13 -3
  673. package/src/workflows/default/WORKFLOW.md +3 -1
  674. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  675. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  676. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  677. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -246
  678. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  679. package/src/session-runtime/turn/share-ops.mjs +0 -77
  680. package/src/tui/session/cross-surface-share.mjs +0 -406
  681. package/src/tui/session/live-share/delta.mjs +0 -153
  682. package/src/tui/session/live-share/mirror.mjs +0 -106
  683. package/src/tui/session/live-share/owner.mjs +0 -254
  684. package/src/tui/session/live-share/retry.mjs +0 -54
  685. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  686. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  687. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  688. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  689. package/src/tui/session/live-share/viewer.mjs +0 -99
  690. package/src/tui/session/live-share/wire.mjs +0 -44
  691. package/src/tui/session/live-share.mjs +0 -154
  692. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -1,7 +1,7 @@
1
1
  // Tag registry: owns the tag maps (tag -> sessionId/agent/cwd) and every
2
2
  // resolution/mutation path — resolve/next/bind/forget and the session-index
3
3
  // refresh. Worker-index persistence lives in worker-index.mjs and terminal
4
- // tombstones/reap timers in terminal-reaper.mjs; the tag maps are shared by
4
+ // tombstones in terminal-reaper.mjs; the tag maps are shared by
5
5
  // reference so all three sides see the same live state.
6
6
  import { agentTagOf } from './helpers.mjs';
7
7
  import { createLeadWorkerIndex } from './lead-worker-index.mjs';
@@ -27,9 +27,10 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
27
27
  dataDir,
28
28
  cfgMod,
29
29
  workerRowFromSession: index.workerRowFromSession,
30
+ isSessionRunning: (sessionId) => mgr.isSessionTurnInFlight?.(sessionId) === true,
30
31
  });
31
32
 
32
- const { upsertLeadSession, updateLeadWorkerCwd } = leadIndex;
33
+ const { upsertLeadSession, updateLeadWorkerCwd, forgetLeadSession } = leadIndex;
33
34
 
34
35
  function dispose(options) {
35
36
  try {
@@ -39,6 +40,17 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
39
40
  }
40
41
  }
41
42
 
43
+ /** Drain every queued index write (batches included) without disposing. */
44
+ async function flushIndexWrites() {
45
+ await Promise.all([index.flushWorkerIndexWrites(), leadIndex.flushLeadWorkerIndexWrites()]);
46
+ }
47
+
48
+ async function disposeAsync(options) {
49
+ const results = await Promise.allSettled([index.disposeAsync(), leadIndex.disposeAsync(options)]);
50
+ const failed = results.find((result) => result.status === 'rejected');
51
+ if (failed) throw failed.reason;
52
+ }
53
+
42
54
  function getLiveSession(sessionId) {
43
55
  if (!sessionId) return null;
44
56
  const session = mgr.getSession(sessionId);
@@ -55,7 +67,7 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
55
67
  return null;
56
68
  }
57
69
 
58
- const reaper = createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession, tagForSession });
70
+ const reaper = createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession });
59
71
 
60
72
  function wantsSessionScan(args = {}) {
61
73
  return args.recover === true || args.scanSessions === true || args.scan_sessions === true;
@@ -91,10 +103,10 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
91
103
  removeWorkerRow({ tag, sessionId });
92
104
  }
93
105
 
94
- reaper.recoverTerminalReaps();
95
-
96
106
  return {
97
107
  dispose,
108
+ disposeAsync,
109
+ flushIndexWrites,
98
110
  readAllTagTombstones: index.readAllTagTombstones,
99
111
  readTagTombstones: index.readTagTombstones,
100
112
  readWorkerRows,
@@ -104,12 +116,12 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
104
116
  upsertWorkerSessionDeferred,
105
117
  upsertLeadSession,
106
118
  updateLeadWorkerCwd,
119
+ forgetLeadSession,
107
120
  removeWorkerRow,
108
121
  refreshTagsFromIndex,
109
122
  tags,
110
123
  tagAgents: tagMaps.tagAgents,
111
124
  tagCwds: tagMaps.tagCwds,
112
- reapTimers: reaper.reapTimers,
113
125
  wantsSessionScan,
114
126
  resolveTag,
115
127
  getLiveSession,
@@ -124,10 +136,6 @@ export function createTagRegistry({ dataDir, cfgMod, mgr }) {
124
136
  tombstoneTerminalSession: reaper.tombstoneTerminalSession,
125
137
  tagTombstoneForTag: reaper.tagTombstoneForTag,
126
138
  consumeTagTombstone: reaper.consumeTagTombstone,
127
- cancelReap: reaper.cancelReap,
128
- clearScheduledReaps: reaper.clearScheduledReaps,
129
- scheduleReap: reaper.scheduleReap,
130
- recoverTerminalReaps: reaper.recoverTerminalReaps,
131
139
  transitionStaleNonterminalRows: reaper.transitionStaleNonterminalRows,
132
140
  };
133
141
  }
@@ -1,13 +1,11 @@
1
1
  // Session-scan admission: whether a scan may (re)index a session, and how a
2
- // terminal session's frozen stamps translate into the reap deadline that the
3
- // scan then settles through the timers.
4
- import { agentTagOf, clean, stampMs } from '../helpers.mjs';
2
+ // terminal session's frozen stamps are re-emitted onto its row.
3
+ import { clean, stampMs } from '../helpers.mjs';
5
4
  import { isTerminalWorkerStatus } from '../worker-rows.mjs';
6
5
  import { ACTIVE_STAGES } from '../tool-def.mjs';
7
- import { resolveAgentTerminalReapMs } from '../../../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
8
6
  import { sessionActivityAt } from './row-helpers.mjs';
9
7
 
10
- export function createScanAdmission({ cfgMod, mgr, index, tombstoneBlocksScan, timers }) {
8
+ export function createScanAdmission({ mgr, index, tombstoneBlocksScan }) {
11
9
  const { readWorkerRows, upsertWorkerSessionDeferred } = index;
12
10
 
13
11
  function scanSessionIsTerminal(session) {
@@ -23,7 +21,7 @@ export function createScanAdmission({ cfgMod, mgr, index, tombstoneBlocksScan, t
23
21
  /** Extra fields for a scan/rebind upsert of an already-terminal session. The
24
22
  * default row build stamps updatedAt = now and clears reapAt, which restarts
25
23
  * the lease from the read instead of from the work: a terminal session owns
26
- * its frozen stamps, and its deadline is derived from them. Returns null for
24
+ * its frozen stamps, which are kept as-is with no reap deadline. Returns null for
27
25
  * running/active sessions so they keep the normal (now-based) behavior. */
28
26
  function terminalScanExtra(session) {
29
27
  if (!scanSessionIsTerminal(session)) return null;
@@ -34,56 +32,25 @@ export function createScanAdmission({ cfgMod, mgr, index, tombstoneBlocksScan, t
34
32
  const stamp = new Date(terminalAtMs).toISOString();
35
33
  const sessionId = clean(session?.id);
36
34
  const existing = readWorkerRows().find((row) => clean(row.sessionId) === sessionId) || null;
37
- const reapMs = resolveAgentTerminalReapMs(
38
- cfgMod.loadConfig(),
39
- clean(existing?.provider) || clean(session?.provider)
40
- );
41
- // An existing lease is authoritative: a read must never extend or reset it.
42
- const existingReapMs = stampMs(existing?.reapAt);
43
- let reapAt = null;
44
- if (existingReapMs > 0) reapAt = new Date(existingReapMs).toISOString();
45
- else if (reapMs != null) reapAt = new Date(terminalAtMs + reapMs).toISOString();
46
35
  const finishedMs = stampMs(session?.finishedAt) || stampMs(existing?.finishedAt);
47
36
  return {
48
37
  // Stamps are re-emitted as ISO so a numeric session stamp cannot leak an
49
38
  // unparseable value into the row store.
50
39
  updatedAt: stamp,
51
40
  finishedAt: finishedMs > 0 ? new Date(finishedMs).toISOString() : stamp,
52
- reapAt,
41
+ reapAt: null,
53
42
  };
54
43
  }
55
44
 
56
45
  // Shared session-scan admission: returns false when the scan must not
57
46
  // resurrect this session, otherwise indexes it (terminal sessions with their
58
- // own stamps) and records any terminal deadline for settlement.
59
- function scanUpsertSession(session, tag, tombstones, pendingTerminal) {
47
+ // own stamps).
48
+ function scanUpsertSession(session, tag, tombstones) {
60
49
  if (tombstoneBlocksScan(session, tag, tombstones)) return false;
61
50
  const extra = terminalScanExtra(session);
62
51
  upsertWorkerSessionDeferred(session, tag, extra || {});
63
- if (extra?.reapAt) {
64
- pendingTerminal.push({
65
- tag: agentTagOf(session) || clean(tag),
66
- sessionId: clean(session.id),
67
- reapAt: extra.reapAt,
68
- });
69
- }
70
52
  return true;
71
53
  }
72
54
 
73
- /** Arm (or immediately run) the reap for rows a scan just (re)indexed. An
74
- * already-elapsed deadline is reaped now instead of buying a new window. */
75
- function settleScannedTerminalRows(pendingTerminal) {
76
- if (!pendingTerminal.length) return;
77
- const now = Date.now();
78
- for (const row of pendingTerminal) {
79
- const deadline = stampMs(row.reapAt);
80
- if (!deadline) continue;
81
- // reapTerminalRow -> tombstoneTerminalSession flushes the deferred upsert
82
- // first, so the row it matches on is the one this scan just wrote.
83
- if (deadline <= now) timers.reapTerminalRow(row);
84
- else if (!timers.isArmedFor(row.sessionId, row.reapAt)) timers.schedulePersistedReap(row);
85
- }
86
- }
87
-
88
- return { scanUpsertSession, settleScannedTerminalRows };
55
+ return { scanUpsertSession };
89
56
  }
@@ -1,5 +1,5 @@
1
1
  // Stale non-terminal rows: an index row whose session is gone and whose
2
- // heartbeat is older than the reap window becomes a tombstone so its tag is
2
+ // last row stamp is older than the reap window becomes a tombstone so its tag is
3
3
  // freed instead of blocking spawn forever.
4
4
  import { clean, positiveInt } from '../helpers.mjs';
5
5
  import { TAG_TOMBSTONE_TTL_MS, isLeadPoolAgent, workerRowTime } from '../worker-rows.mjs';
@@ -16,9 +16,9 @@ export function createStaleRowTransition({ cfgMod, tagMaps, index, getLiveSessio
16
16
  if (getLiveSession(clean(row.sessionId))) return false;
17
17
  const rowTime = workerRowTime(row);
18
18
  const reapMs = resolveAgentTerminalReapMs(cfgMod.loadConfig(), row.provider);
19
- // A row with no timestamp has no usable heartbeat at all. Explicitly
19
+ // A row with no timestamp has no usable stamp at all. Explicitly
20
20
  // disabled terminal reaping still gets the tombstone TTL as a finite
21
- // stale-heartbeat bound, so malformed/running index rows cannot block a
21
+ // staleness bound, so malformed/running index rows cannot block a
22
22
  // tag forever.
23
23
  return rowTime <= 0 || Date.now() - rowTime >= (reapMs ?? TAG_TOMBSTONE_TTL_MS);
24
24
  });
@@ -1,46 +1,29 @@
1
- // Terminal-session reaping for the agent tag registry: tag tombstones, the
2
- // scan admission guard they impose, the delayed reap timers and their
3
- // recovery after a restart. Reaping expires only the tag/runtime lease — the
4
- // session record stays open so the transcript remains visible from the parent
5
- // task. Each concern lives under ./terminal-reaper/; this file wires them.
1
+ // Terminal-session bookkeeping for the agent tag registry: tag tombstones, the
2
+ // scan admission guard they impose and stale worker-row transitions. Terminal
3
+ // sessions are never closed on a timer — the session record stays open so the
4
+ // transcript remains visible from the parent task. Each concern lives under
5
+ // ./terminal-reaper/; this file wires them.
6
6
  import { createTagTombstones } from './terminal-reaper/tombstones.mjs';
7
- import { createReapTimers } from './terminal-reaper/reap-timers.mjs';
8
7
  import { createScanAdmission } from './terminal-reaper/scan-admission.mjs';
9
8
  import { createStaleRowTransition } from './terminal-reaper/stale-rows.mjs';
10
9
 
11
- export function createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession, tagForSession }) {
10
+ export function createTerminalReaper({ cfgMod, mgr, tagMaps, index, getLiveSession }) {
12
11
  const tombstones = createTagTombstones({ tagMaps, index });
13
- const timers = createReapTimers({
14
- cfgMod,
15
- mgr,
16
- index,
17
- getLiveSession,
18
- tagForSession,
19
- tombstoneTerminalSession: tombstones.tombstoneTerminalSession,
20
- });
21
12
  const scan = createScanAdmission({
22
- cfgMod,
23
13
  mgr,
24
14
  index,
25
15
  tombstoneBlocksScan: tombstones.tombstoneBlocksScan,
26
- timers,
27
16
  });
28
17
  const { transitionStaleNonterminalRows } = createStaleRowTransition({ cfgMod, tagMaps, index, getLiveSession });
29
18
 
30
19
  return {
31
- reapTimers: timers.reapTimers,
32
20
  tagTombstoneIndex: tombstones.tagTombstoneIndex,
33
21
  tombstoneBlocksScan: tombstones.tombstoneBlocksScan,
34
22
  scanUpsertSession: scan.scanUpsertSession,
35
- settleScannedTerminalRows: scan.settleScannedTerminalRows,
36
23
  forgetTerminalSession: tombstones.forgetTerminalSession,
37
24
  tombstoneTerminalSession: tombstones.tombstoneTerminalSession,
38
25
  tagTombstoneForTag: tombstones.tagTombstoneForTag,
39
26
  consumeTagTombstone: tombstones.consumeTagTombstone,
40
- clearScheduledReaps: timers.clearScheduledReaps,
41
- cancelReap: timers.cancelReap,
42
- scheduleReap: timers.scheduleReap,
43
- recoverTerminalReaps: timers.recoverTerminalReaps,
44
27
  transitionStaleNonterminalRows,
45
28
  };
46
29
  }
@@ -31,7 +31,6 @@ export function createTerminalTrace({ registry }) {
31
31
  if (!row) return false;
32
32
  registry.refreshTagsFromSessions({ context });
33
33
  const sessionId = clean(row.sessionId);
34
- if (sessionId) registry.cancelReap(sessionId);
35
34
  registry.forgetTerminalSession(value, sessionId);
36
35
  return true;
37
36
  }
@@ -53,6 +53,13 @@ export const AGENT_TOOL = {
53
53
  file: { type: 'string', description: 'Path to task text; alternative to prompt/message for spawn/send.' },
54
54
  cwd: { type: 'string', description: 'Project directory for a new or respawned agent.' },
55
55
  context: { type: 'string', description: 'Extra context for the spawn/send turn.' },
56
+ model: {
57
+ type: 'string',
58
+ description:
59
+ "Spawn only, and only when the user explicitly names a model: runs this one spawn on it instead of the agent's preset route, which stays the default (omit otherwise). Id, display name, or words of it; ambiguous or unknown names fail with candidates. The agent still supplies role and permissions.",
60
+ },
61
+ provider: { type: 'string', description: 'Narrows model to one provider; requires model.' },
62
+ effort: { type: 'string', description: 'Reasoning effort for an explicit model.' },
56
63
  },
57
64
  required: ['type'],
58
65
  additionalProperties: false,
@@ -1,9 +1,6 @@
1
1
  // worker-index/row-liveness.mjs
2
2
  // Whether an active-looking row still has a live worker behind it, and how a
3
- // row settles back to idle when it does not.
4
- import { statSync } from 'node:fs';
5
- import { resolve } from 'node:path';
6
-
3
+ // row settles (idle, or failed when its runtime died) when it does not.
7
4
  import { resolveAgentTerminalReapMs } from '../../../../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
8
5
  import { clean, positiveInt, runtimeAlive } from '../helpers.mjs';
9
6
 
@@ -25,24 +22,33 @@ export const isActiveWorkerRow = (row) =>
25
22
  * with that process (daemon restart), so the flag must not stick. */
26
23
  export const isStaleApprovalWait = (row) => Boolean(row?.awaitingUser) && !runtimeAlive(row.runtimePid);
27
24
 
28
- export function createRowLiveness({ dataDir, cfgMod }) {
29
- function heartbeatFresh(sessionId, now) {
30
- const id = clean(sessionId);
31
- if (!dataDir || !id) return false;
32
- try {
33
- const mtimeMs = statSync(resolve(dataDir, 'sessions', `${id}.hb`)).mtimeMs || 0;
34
- return mtimeMs > 0 && now - mtimeMs <= WORKER_POOL_FRESH_MS;
35
- } catch {
36
- return false;
37
- }
38
- }
25
+ /** The process that ran the row's turn is gone (a restart or crash ended it). */
26
+ export const runtimeDied = (row) => Boolean(positiveInt(row?.runtimePid)) && !runtimeAlive(row.runtimePid);
27
+
28
+ /** The row's turn ended because the process running it went away. */
29
+ export const PROCESS_RESTART_FAILURE = 'process-restart';
39
30
 
40
- /** Active status, but its runtime pid is dead, or neither its heartbeat nor
41
- * its own update stamp is fresh. */
31
+ /** The row's turn was stopped by the progress (stall) watchdog. */
32
+ export const WATCHDOG_STALL_FAILURE = 'stalled';
33
+
34
+ /** A turn's settled row status and failure reason: a watchdog stop is a
35
+ * failure whatever partial output it handed back (`finalStatus` may still
36
+ * read `idle` for the job's sake); everything else keeps `finalStatus`. */
37
+ export function settledWorkerStatus(finalStatus, stalled) {
38
+ return stalled
39
+ ? { status: 'failed', stage: 'failed', failureReason: WATCHDOG_STALL_FAILURE }
40
+ : { status: finalStatus, stage: finalStatus };
41
+ }
42
+
43
+ /** `isSessionRunning(sessionId)`: the daemon's in-memory answer to whether
44
+ * that session's turn is in flight (every session runs in this process). */
45
+ export function createRowLiveness({ cfgMod, isSessionRunning = () => false }) {
46
+ /** Active status, but its runtime pid is dead, or its turn is not running
47
+ * here and its own update stamp is not fresh either. */
42
48
  function isStaleActive(row, now) {
43
49
  if (!isActiveWorkerRow(row)) return false;
44
- if (positiveInt(row.runtimePid) && !runtimeAlive(row.runtimePid)) return true;
45
- if (heartbeatFresh(row.sessionId, now)) return false;
50
+ if (runtimeDied(row)) return true;
51
+ if (isSessionRunning(clean(row.sessionId))) return false;
46
52
  const updated = Date.parse(clean(row.updatedAt)) || 0;
47
53
  return !(updated > 0 && now - updated <= WORKER_POOL_FRESH_MS);
48
54
  }
@@ -74,5 +80,11 @@ export function createRowLiveness({ dataDir, cfgMod }) {
74
80
  };
75
81
  }
76
82
 
77
- return { isStaleActive, idleRow };
83
+ /** The row settled as failed: its turn never finished, and `failureReason`
84
+ * says why. Stamps settle exactly as idleRow's. */
85
+ function failedRow(row, now, failureReason, touch = false) {
86
+ return { ...idleRow(row, now, touch), status: 'failed', stage: 'failed', failureReason };
87
+ }
88
+
89
+ return { isStaleActive, idleRow, failedRow };
78
90
  }
@@ -52,6 +52,9 @@ export function normalizeWorkerRows(value) {
52
52
  cwd: clean(row.cwd) || null,
53
53
  task_id: clean(row.task_id || row.taskId) || null,
54
54
  error: clean(row.error) || null,
55
+ // Why a `failed` row failed (row-liveness, a watchdog stop). Always
56
+ // present, so a later whole-row write clears a stale reason.
57
+ failureReason: clean(row.failureReason) || null,
55
58
  permission: clean(row.permission) || null,
56
59
  toolPermission: clean(row.toolPermission) || null,
57
60
  messages: positiveInt(row.messages) || 0,
@@ -101,14 +104,14 @@ export function workerRowFromSession(session, fallbackTag = '', extra = {}, getS
101
104
  // Turn dispatch stamps this; terminal upserts leave it null and the
102
105
  // merge in applyWorkerRowUpsert preserves the running turn's value.
103
106
  turnStartedAt: clean(extra.turnStartedAt) || null,
104
- // Active/new work clears the previous lease. Terminal settlement writes
105
- // the new absolute deadline immediately afterwards via scheduleReap().
107
+ // Kept for compatibility with older worker rows; no timer consumes it.
106
108
  reapAt: clean(extra.reapAt) || null,
107
109
  clientHostPid: positiveInt(extra.clientHostPid) || positiveInt(session?.clientHostPid),
108
110
  runtimePid: positiveInt(extra.runtimePid) || process.pid,
109
111
  cwd: clean(session?.cwd) || clean(extra.cwd) || null,
110
112
  task_id: clean(extra.task_id || extra.taskId) || null,
111
113
  error: clean(extra.error) || null,
114
+ failureReason: clean(extra.failureReason) || null,
112
115
  permission: clean(session?.permission) || null,
113
116
  toolPermission: clean(session?.toolPermission) || null,
114
117
  messages: Array.isArray(session?.messages) ? session.messages.length : 0,
@@ -157,6 +157,7 @@ export function createWorkerRowStore(file) {
157
157
  flush: queue.flush,
158
158
  /** Exit path: persist what is still queued, synchronously. */
159
159
  flushSync: queue.flushSync,
160
+ hasUnpersisted: queue.hasUnpersisted,
160
161
  invalidate: () => {
161
162
  dirty = true;
162
163
  },
@@ -183,7 +184,15 @@ export function acquireWorkerRowStore(file) {
183
184
  if (released) return;
184
185
  released = true;
185
186
  entry.refs -= 1;
186
- if (entry.refs === 0 && sharedStores.get(key) === entry) sharedStores.delete(key);
187
+ const dropIfIdle = () => {
188
+ if (entry.refs === 0 && !entry.store.hasUnpersisted() && sharedStores.get(key) === entry) {
189
+ sharedStores.delete(key);
190
+ }
191
+ };
192
+ // A store still holding unpersisted writes stays shared (a new holder
193
+ // must see them) until its queue drains.
194
+ if (entry.refs === 0 && entry.store.hasUnpersisted()) entry.store.flush().then(dropIfIdle, () => {});
195
+ else dropIfIdle();
187
196
  },
188
197
  };
189
198
  }
@@ -18,7 +18,13 @@ import {
18
18
  registerApprovalWaitWriter,
19
19
  } from './worker-index/approval-wait.mjs';
20
20
  import { createMutationBatch } from './worker-index/mutation-batch.mjs';
21
- import { createRowLiveness, isActiveWorkerRow, isStaleApprovalWait } from './worker-index/row-liveness.mjs';
21
+ import {
22
+ createRowLiveness,
23
+ isActiveWorkerRow,
24
+ isStaleApprovalWait,
25
+ PROCESS_RESTART_FAILURE,
26
+ runtimeDied,
27
+ } from './worker-index/row-liveness.mjs';
22
28
  import { normalizeWorkerRows, workerRowFromSession } from './worker-index/row-shape.mjs';
23
29
  import { acquireWorkerRowStore } from './worker-index/row-store.mjs';
24
30
  import { findTagTombstone, tagTombstoneKey, tombstoneBlocksWork } from '../../../runtime/shared/agent-reap-state.mjs';
@@ -35,9 +41,13 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
35
41
  unreconciled.clear();
36
42
  for (const id of ids) reconcileAwaitingUser(id);
37
43
  });
38
- const liveness = createRowLiveness({ dataDir, cfgMod });
39
- // Rows this process marked active; settled to idle on exit so a crash of
40
- // the host never leaves them "running" forever.
44
+ const liveness = createRowLiveness({
45
+ cfgMod,
46
+ isSessionRunning: (sessionId) => mgr.isSessionTurnInFlight?.(sessionId) === true,
47
+ });
48
+ // Rows this process marked active; settled as failed on exit (their turn
49
+ // dies with the process) so a crash of the host never leaves them
50
+ // "running" forever.
41
51
  const activeWorkerKeys = new Set();
42
52
 
43
53
  function readWorkerRows(context = {}) {
@@ -144,13 +154,17 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
144
154
  for (const key of keys) {
145
155
  const current = byKey.get(key);
146
156
  if (!current || positiveInt(current.runtimePid) !== process.pid) continue;
147
- if (isActiveWorkerRow(current)) byKey.set(key, liveness.idleRow(current, now, true));
157
+ if (isActiveWorkerRow(current)) {
158
+ byKey.set(key, liveness.failedRow(current, now, PROCESS_RESTART_FAILURE, true));
159
+ }
148
160
  }
149
161
  });
150
162
  }
151
163
 
152
- // Startup recovery: stale active rows settle to idle, and an approval wait
153
- // left behind by a runtime that is gone (daemon restart) is cleared.
164
+ // Startup recovery: stale active rows settle — as failed when the process
165
+ // that ran their turn is gone (the turn never finished), otherwise to idle —
166
+ // and an approval wait left behind by a runtime that is gone (daemon
167
+ // restart) is cleared.
154
168
  function recoverStaleWorkerRows() {
155
169
  const now = Date.now();
156
170
  const rows = store.readAll();
@@ -162,7 +176,13 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
162
176
  for (const row of staleActive) {
163
177
  const key = workerRowKey(row);
164
178
  const current = byKey.get(key);
165
- if (current && liveness.isStaleActive(current, now)) byKey.set(key, liveness.idleRow(current, now));
179
+ if (!current || !liveness.isStaleActive(current, now)) continue;
180
+ byKey.set(
181
+ key,
182
+ runtimeDied(current)
183
+ ? liveness.failedRow(current, now, PROCESS_RESTART_FAILURE)
184
+ : liveness.idleRow(current, now)
185
+ );
166
186
  }
167
187
  });
168
188
  }
@@ -173,7 +193,9 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
173
193
  function flushWorkerIndexOnExit() {
174
194
  batch.flush();
175
195
  flushActiveWorkerRows();
176
- // Writes are persisted by an async queue; the loop is gone at exit.
196
+ // Writes are persisted by an async queue; the loop is gone at exit. This
197
+ // is the best-effort last resort: a persist still running is left alone
198
+ // (the graceful shutdown path drains before exit).
177
199
  store.flushSync();
178
200
  }
179
201
 
@@ -181,25 +203,62 @@ export function createWorkerIndex({ dataDir, cfgMod, mgr, tags, tagAgents, tagCw
181
203
  const unregisterExitFlush = registerExitFlush(flushWorkerIndexOnExit);
182
204
  const unregisterApprovalWaits = registerApprovalWaitWriter(file, setAwaitingUser);
183
205
  let disposed = false;
206
+ let disposePromise = null;
207
+
208
+ function teardown() {
209
+ unregisterExitFlush();
210
+ unregisterApprovalWaits();
211
+ releaseStore();
212
+ }
213
+
214
+ async function drainThenTeardown() {
215
+ batch.flush();
216
+ await store.flush();
217
+ teardown();
218
+ }
184
219
 
185
220
  /** Persist queued rows, then release the exit registration. Active rows are
186
221
  * NOT settled: they are keyed by process pid, which every inline runtime in
187
- * the daemon shares, so settling here would idle other runtimes' workers. */
222
+ * the daemon shares, so settling here would idle other runtimes' workers.
223
+ * When the sync flush cannot run (this process's async writer holds the
224
+ * lock) the exit hook and store ref stay until the async drain settles. */
188
225
  function dispose() {
189
226
  if (disposed) return;
190
227
  disposed = true;
228
+ let flushed = false;
191
229
  try {
192
230
  batch.flush();
193
- store.flushSync();
194
- } finally {
195
- unregisterExitFlush();
196
- unregisterApprovalWaits();
197
- releaseStore();
231
+ flushed = store.flushSync();
232
+ } catch {}
233
+ if (flushed) {
234
+ teardown();
235
+ return;
236
+ }
237
+ disposePromise = drainThenTeardown().catch(reopenAfterFailedDrain);
238
+ }
239
+
240
+ /** A failed drain tears nothing down; allow a later dispose to retry it. */
241
+ function reopenAfterFailedDrain() {
242
+ disposed = false;
243
+ disposePromise = null;
244
+ }
245
+
246
+ /** Awaitable dispose: drain everything, then tear down. A failed drain
247
+ * rejects and leaves the registrations in place. */
248
+ function disposeAsync() {
249
+ if (!disposePromise) {
250
+ disposed = true;
251
+ disposePromise = drainThenTeardown().catch((error) => {
252
+ reopenAfterFailedDrain();
253
+ throw error;
254
+ });
198
255
  }
256
+ return disposePromise;
199
257
  }
200
258
 
201
259
  return {
202
260
  dispose,
261
+ disposeAsync,
203
262
  workerIndexPath: () => file,
204
263
  invalidateWorkerRowsCache: store.invalidate,
205
264
  readAllWorkerRows: store.readAll,
@@ -42,6 +42,9 @@ export function createStandaloneAgent({
42
42
  sessionSurface = null,
43
43
  awaitKeychainPrewarm = async () => {},
44
44
  isKeychainPrewarmReady = () => true,
45
+ // Provider model catalog for user-pinned spawn models; absent on surfaces
46
+ // without one, where only exact provider + model pass.
47
+ listProviderModels = null,
45
48
  }) {
46
49
  const canUseSessionSurface = (session) =>
47
50
  typeof sessionSurface?.runTurn === 'function' && sessionSurface.canRun?.(session) !== false;
@@ -105,6 +108,7 @@ export function createStandaloneAgent({
105
108
  sendFlow,
106
109
  closeFlow,
107
110
  terminalTrace,
111
+ listProviderModels,
108
112
  });
109
113
 
110
114
  function getStatus(context = {}) {
@@ -147,7 +151,10 @@ export function createStandaloneAgent({
147
151
  recoverWorkers,
148
152
  upsertLeadSession: registry.upsertLeadSession,
149
153
  updateLeadWorkerCwd: registry.updateLeadWorkerCwd,
154
+ forgetLeadSession: registry.forgetLeadSession,
150
155
  closeAll: closeFlow.closeAll,
151
156
  dispose: (options) => registry.dispose(options),
157
+ disposeAsync: (options) => registry.disposeAsync(options),
158
+ flushIndexWrites: () => registry.flushIndexWrites(),
152
159
  };
153
160
  }
@@ -18,6 +18,8 @@ export function getProgressWatchdogState(mgr, sessionId) {
18
18
  registered: Boolean(state?.linked && !state.controller.signal.aborted),
19
19
  lastCheckedAt: state?.lastCheckedAt || null,
20
20
  error: state?.error || null,
21
+ // The policy this session's watchdog actually enforces.
22
+ policy: state?.watchdogPolicy || null,
21
23
  };
22
24
  }
23
25
 
@@ -26,6 +26,8 @@ import { normalizeAutomationAttachments } from '../../runtime/shared/automation-
26
26
  import { migrateCodexModelRef } from '../../runtime/agent/orchestrator/providers/openai-oauth-catalog-store.mjs';
27
27
  import { hasEnabledAutomation } from '../../runtime/shared/automation-presence.mjs';
28
28
  import { resolveScheduleTimezone, validateScheduleCron } from '../../runtime/shared/schedule-time.mjs';
29
+ import { pgClusterExists } from '../../runtime/memory/lib/pg/adapter.mjs';
30
+ import { resolvePluginData } from '../../runtime/shared/plugin-paths.mjs';
29
31
  import { readHookPublicBase } from '../../runtime/channels/lib/webhook/relay-tunnel.mjs';
30
32
  import { WEBHOOK_TEST_FIELD, WEBHOOK_TEST_HEADER } from '../../runtime/channels/lib/webhook/request-handler.mjs';
31
33
 
@@ -463,10 +465,20 @@ export async function testWebhook(name) {
463
465
  // and webhooks run sessions, so they must not require Discord/Telegram
464
466
  // tokens or an explicit remote toggle.
465
467
  async function checkActiveAutomation() {
466
- const [schedules, webhooks] = await Promise.all([listSchedules(), listWebhooks()]);
468
+ const { schedules, webhooks } = await readAutomationRows();
467
469
  return hasEnabledAutomation({ schedules, webhooks });
468
470
  }
469
471
 
472
+ // Read-only views (channel setup, the automation probe) never bring
473
+ // PostgreSQL up for the first time: before initdb ran no schedule or webhook
474
+ // can exist, and that first start — runtime download/extract plus initdb — is
475
+ // seconds of work no catalog read should wait on. Writes still start it.
476
+ async function readAutomationRows() {
477
+ if (!pgClusterExists(resolvePluginData())) return { schedules: [], webhooks: [] };
478
+ const [schedules, webhooks] = await Promise.all([listSchedules(), listWebhooks()]);
479
+ return { schedules, webhooks };
480
+ }
481
+
470
482
  // Every session runtime in the process asks this at boot. Concurrent callers
471
483
  // join one in-flight check and a settled answer is reused for ttlMs, so N
472
484
  // runtimes booting together cost one PG query (and at most one PG boot)
@@ -519,8 +531,12 @@ export function hasActiveAutomation() {
519
531
  return automationProbe.probe();
520
532
  }
521
533
 
534
+ // The daemon opens both stores in the background once ready (it settles
535
+ // hasActiveAutomation), so on an existing cluster this read joins a
536
+ // PostgreSQL start already under way instead of being the one that starts it.
522
537
  export async function channelSetup(config = null) {
523
538
  const cfg = normalizeChannelsConfig(config || readSection('channels'));
539
+ const { schedules, webhooks } = await readAutomationRows();
524
540
  return {
525
541
  webhook: {
526
542
  ...(cfg.webhook || {}),
@@ -528,7 +544,7 @@ export async function channelSetup(config = null) {
528
544
  // connects and mints its hook identity).
529
545
  publicUrl: readHookPublicBase(),
530
546
  },
531
- schedules: await listSchedules(),
532
- webhooks: await listWebhooks(),
547
+ schedules,
548
+ webhooks,
533
549
  };
534
550
  }
@@ -41,6 +41,9 @@ export function createMemoryCalls({ state, cwd, start, discovery, registry }) {
41
41
  ...(transcriptCwd ? { cwd: transcriptCwd } : {}),
42
42
  });
43
43
  }
44
+ async function forgetTranscripts(filePaths = []) {
45
+ return await requestMemoryPath('/transcript/forget', { filePaths }, { timeoutMs: 10_000 });
46
+ }
44
47
  async function recordTraceEvents(events = []) {
45
48
  return await requestMemoryPath('/admin/trace-record', { events }, { timeoutMs: 5_000 });
46
49
  }
@@ -120,6 +123,7 @@ export function createMemoryCalls({ state, cwd, start, discovery, registry }) {
120
123
  retain,
121
124
  appendEntry,
122
125
  ingestTranscript,
126
+ forgetTranscripts,
123
127
  recordTraceEvents,
124
128
  handleToolCall,
125
129
  buildSessionCoreMemoryPayload,