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,9 +1,15 @@
1
1
  /**
2
2
  * Projection of the durable worker indexes (agent-workers.json,
3
- * lead-workers.json) and the heartbeat sidecars into the process-global
4
- * active pool: the status vocabulary, the 2-minute heartbeat lease and its
5
- * authority rules, cancel ranking, frozen idle stamps, the per-file session
6
- * header cache and the orphan-child prune.
3
+ * lead-workers.json) into the process-global active pool: the status
4
+ * vocabulary, the live-work evidence a working row needs, frozen idle stamps,
5
+ * the per-file session header cache and the orphan-child prune.
6
+ *
7
+ * Whether a session is working is the daemon's in-memory turn activity (every
8
+ * session runs inline there), handed in as `runningSessionIds`: a running
9
+ * session is working whatever its durable row declares, except that an
10
+ * explicit cancel outranks it. A declared-working row the daemon does not
11
+ * report as in flight reads `unknown` — without the daemon's answer nothing
12
+ * is guessed.
7
13
  *
8
14
  * Assembly order lives in store-agent-worker-pool.mjs; this module owns the
9
15
  * row-level truth each projected row carries. Every status string, index
@@ -16,33 +22,30 @@ import { readJsonProjection } from '../../../shared/pending-json-projection.mjs'
16
22
  import { listStoredAgentWorkers as assembleStoredAgentWorkers } from './store-agent-worker-pool.mjs';
17
23
  import {
18
24
  TAG_TOMBSTONE_TTL_MS,
25
+ agentPaneVisible,
19
26
  findTagTombstone,
20
27
  tagTombstoneKey,
21
28
  tombstoneBlocksWork,
22
29
  } from '../../../shared/agent-reap-state.mjs';
23
- import {
24
- dataDir,
25
- sessionHeartbeatMtimes,
26
- storedAgentWorkerIndexPath,
27
- storedLeadWorkerIndexPath,
28
- } from './store-summary-locations.mjs';
30
+ import { dataDir, storedAgentWorkerIndexPath, storedLeadWorkerIndexPath } from './store-summary-locations.mjs';
29
31
  import { cleanValue, isStoredSessionId, positiveNumber } from './store-summary-fields.mjs';
30
32
  import { sessionUsageTotals } from '../../../shared/session-usage-totals.mjs';
31
33
 
32
- const DEAD_AGENT_STATUS =
33
- /^(?:done|complete|completed|success|closed|error|fail|failed|cancelled|canceled|killed|timeout)$/i;
34
- const LIVING_AGENT_STATUS =
35
- /^(?:idle|connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
36
34
  const WORKING_AGENT_STATUS =
37
35
  /^(?:connecting|requesting|streaming|tool[-_\s]?running|running|queued|pending|starting|cancelling)$/i;
38
- // Confirmed cancel vs a cancel whose stop is not proven. The heartbeat lease
39
- // must never rewrite either as `running`, and the two must stay distinct:
40
- // `cancel-unconfirmed` is the honest Windows git-bash-survivor answer, not a
41
- // successful cancel.
36
+ // Confirmed cancel vs a cancel whose stop is not proven. Neither is ever
37
+ // shown as `running`, and the two must stay distinct: `cancel-unconfirmed` is
38
+ // the honest Windows git-bash-survivor answer, not a successful cancel.
42
39
  const CANCELLED_AGENT_STATUS = /^(?:cancelled|canceled|killed)$/i;
43
40
  // Bare `cancelling` is still working (ACTIVE_STAGES). Only an explicit
44
41
  // unconfirmed/pending cancel is a distinct terminal-unconfirmed outcome.
45
42
  const CANCEL_UNCONFIRMED_AGENT_STATUS = /^(?:cancel[-_\s]?(?:unconfirmed|pending))$/i;
43
+ // A turn that did not finish (error, timeout, watchdog stop, dead runtime):
44
+ // dead like a completion, but it stays visible as the failure it is.
45
+ const FAILED_AGENT_STATUS = /^(?:error|fail|failed|timeout)$/i;
46
+ // A turn that finished normally. The row rests as `idle` (or an equivalent
47
+ // done status) and is listed as `completed` for the pane window.
48
+ const COMPLETED_AGENT_STATUS = /^(?:idle|done|complete|completed|success)$/i;
46
49
  const SESSION_CANCEL_FIELDS = [
47
50
  'cancelStatus',
48
51
  'status',
@@ -52,19 +55,6 @@ const SESSION_CANCEL_FIELDS = [
52
55
  'outcome',
53
56
  'terminationReason',
54
57
  ];
55
- const AGENT_POOL_HEARTBEAT_FRESH_MS = 2 * 60 * 1000;
56
-
57
- function runtimeAlive(pid) {
58
- const id = positiveNumber(pid, 0);
59
- if (id <= 0 || id === process.pid) return true;
60
- try {
61
- process.kill(id, 0);
62
- return true;
63
- } catch (error) {
64
- return error?.code === 'EPERM';
65
- }
66
- }
67
-
68
58
  function workerOwnerSessionId(row, session) {
69
59
  return (
70
60
  cleanValue(row?.ownerSessionId || session?.ownerSessionId || row?.parentSessionId || session?.parentSessionId) ||
@@ -100,12 +90,6 @@ function frozenIdleSince(sessionId, working, fallback) {
100
90
  return value;
101
91
  }
102
92
 
103
- function agentStatusValues(row) {
104
- return [row?.stage, row?.status]
105
- .map(cleanValue)
106
- .filter((status, index, values) => Boolean(status) && values.indexOf(status) === index);
107
- }
108
-
109
93
  /** The worker's lifecycle. `status` decides; `stage` is only the runtime phase
110
94
  * copied in by the progress sweep, so mid-work it may read idle/done/error
111
95
  * beside a worker that is still running. Only a row with no status falls
@@ -114,17 +98,8 @@ function workerLifecycle(row) {
114
98
  return cleanValue(row?.status) || cleanValue(row?.stage);
115
99
  }
116
100
 
117
- function activeAgentWorker(row) {
118
- // A cancel in either field ends the work (bare `cancelling` is still work).
119
- if (
120
- agentStatusValues(row).some(
121
- (status) => CANCELLED_AGENT_STATUS.test(status) || CANCEL_UNCONFIRMED_AGENT_STATUS.test(status)
122
- )
123
- ) {
124
- return false;
125
- }
126
- const lifecycle = workerLifecycle(row);
127
- return Boolean(lifecycle) && !DEAD_AGENT_STATUS.test(lifecycle) && LIVING_AGENT_STATUS.test(lifecycle);
101
+ function failedAgentWorker(row) {
102
+ return FAILED_AGENT_STATUS.test(workerLifecycle(row));
128
103
  }
129
104
 
130
105
  function stampMs(value) {
@@ -137,42 +112,58 @@ function stampMs(value) {
137
112
  return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
138
113
  }
139
114
 
140
- function workStampMs(row) {
141
- if (!row || typeof row !== 'object') return 0;
142
- return Math.max(stampMs(row.turnStartedAt), stampMs(row.startedAt));
115
+ function workStampMs(source) {
116
+ if (!source || typeof source !== 'object') return 0;
117
+ return Math.max(stampMs(source.turnStartedAt), stampMs(source.startedAt));
143
118
  }
144
119
 
145
- function cancelStampMs(row) {
146
- if (!row || typeof row !== 'object') return 0;
147
- return Math.max(stampMs(row.cancelledAt), stampMs(row.finishedAt));
120
+ function cancelStampMs(source) {
121
+ if (!source || typeof source !== 'object') return 0;
122
+ return Math.max(stampMs(source.cancelledAt), stampMs(source.finishedAt));
148
123
  }
149
124
 
150
- /** Confirmed cancel yields to unconfirmed when both are present so a
151
- * still-tearing-down or unobservable stop is never reported as success.
152
- * `cancelling` alone is working and is not a cancel. */
153
- function sessionCancelState(row) {
154
- if (!row || typeof row !== 'object') return null;
155
- const statuses = SESSION_CANCEL_FIELDS.map((key) => cleanValue(row[key])).filter(
156
- (status, index, values) => Boolean(status) && values.indexOf(status) === index
157
- );
125
+ /** When a settled agent finished: its finish/cancel/failure stamp, else its
126
+ * last update. The index row decides; the session header only fills a gap. */
127
+ function finishedAtMs(row, session = null) {
128
+ return cancelStampMs(row) || stampMs(row?.updatedAt) || cancelStampMs(session) || stampMs(session?.updatedAt);
129
+ }
130
+
131
+ /** The cancel one source (index row or session header) records, or null.
132
+ * An unconfirmed stop outranks a confirmed one so a stop that was never
133
+ * proven is not reported as success. `cancelling` alone is working and is
134
+ * not a cancel. */
135
+ function cancelState(source) {
136
+ if (!source || typeof source !== 'object') return null;
137
+ const statuses = SESSION_CANCEL_FIELDS.map((key) => cleanValue(source[key])).filter(Boolean);
158
138
  const status =
159
139
  statuses.find((value) => CANCEL_UNCONFIRMED_AGENT_STATUS.test(value)) ||
160
140
  statuses.find((value) => CANCELLED_AGENT_STATUS.test(value)) ||
161
141
  '';
162
- if (!status) return null;
163
- return { status, at: cancelStampMs(row) };
142
+ return status ? { status, at: cancelStampMs(source) } : null;
143
+ }
144
+
145
+ /** The cancel that still holds across the index row and its session header:
146
+ * the unconfirmed one when the sources disagree (the row first otherwise).
147
+ * Only demonstrably newer work — a turn/start stamp strictly after a stamped
148
+ * cancel — supersedes it; an unstamped cancel is never superseded. */
149
+ function effectiveCancel(row, session) {
150
+ const rowCancel = cancelState(row);
151
+ const sessionCancel = cancelState(session);
152
+ const cancel =
153
+ rowCancel && sessionCancel && CANCEL_UNCONFIRMED_AGENT_STATUS.test(sessionCancel.status)
154
+ ? CANCEL_UNCONFIRMED_AGENT_STATUS.test(rowCancel.status)
155
+ ? rowCancel
156
+ : sessionCancel
157
+ : rowCancel || sessionCancel;
158
+ if (!cancel) return null;
159
+ const newerWork = cancel.at > 0 && Math.max(workStampMs(row), workStampMs(session)) > cancel.at;
160
+ return newerWork ? null : cancel;
164
161
  }
165
162
 
166
- /** Rank two cancel states: an unconfirmed stop always outranks a confirmed
167
- * one, so no source can report success for a kill another source could not
168
- * prove. Same-class states keep the index row (`a`) as the richer source. */
169
- function preferUnconfirmedCancel(a, b) {
170
- if (!a) return b || null;
171
- if (!b) return a;
172
- const aUnconfirmed = CANCEL_UNCONFIRMED_AGENT_STATUS.test(a.status);
173
- const bUnconfirmed = CANCEL_UNCONFIRMED_AGENT_STATUS.test(b.status);
174
- if (aUnconfirmed === bUnconfirmed) return a;
175
- return aUnconfirmed ? a : b;
163
+ /** The stage shown beside a cancel: a stage that itself names the cancel (or
164
+ * the `cancelling` phase) is kept, any other phase is the cancel. */
165
+ function cancelStage(cancel, declaredStage) {
166
+ return /^cancel/i.test(declaredStage) || CANCELLED_AGENT_STATUS.test(declaredStage) ? declaredStage : cancel.status;
176
167
  }
177
168
 
178
169
  function storedAgentWorkerIndex() {
@@ -293,37 +284,61 @@ function leadConversationHeader(header) {
293
284
  return owner !== 'agent' && (agent === 'lead' || cleanValue(header.sourceType).toLowerCase() === 'lead');
294
285
  }
295
286
 
296
- const withinPoolWindow = (at, now) => at > 0 && now - at <= AGENT_POOL_HEARTBEAT_FRESH_MS;
287
+ /** Whether the daemon reports the session's turn in flight. */
288
+ function sessionRunning(sessionId, { runningSessionIds }) {
289
+ return runningSessionIds instanceof Set && runningSessionIds.has(sessionId);
290
+ }
297
291
 
298
- /** Live-work proof for an already projected row: a fresh heartbeat sidecar, or
299
- * a working status whose own stamp is still inside the pool window. */
300
- function poolRowWorking(row, heartbeatMtimes, now) {
301
- if (withinPoolWindow(heartbeatMtimes.get(cleanValue(row?.sessionId)) || 0, now)) return true;
302
- if (!WORKING_AGENT_STATUS.test(workerLifecycle(row))) return false;
303
- return withinPoolWindow(Date.parse(cleanValue(row?.updatedAt)) || 0, now);
292
+ /** An already projected row is live work: its projected status is working
293
+ * only when the daemon reported it running (otherwise it reads `unknown`). */
294
+ function poolRowWorking(row) {
295
+ return WORKING_AGENT_STATUS.test(workerLifecycle(row));
304
296
  }
305
297
 
306
- /** A child worker-index row projected into the pool, or null. Cancelled rows
307
- * stay visible so the 2-minute heartbeat lease cannot resurrect them as
308
- * `running` once DEAD_AGENT_STATUS would have dropped them from the map;
309
- * unconfirmed cancels are not dead, but also must not be overwritten by the
310
- * sidecar. */
311
- function projectChildWorkerRow(row, { now, heartbeatMtimes }) {
298
+ /** A child worker-index row projected into the pool, or null. A finished
299
+ * child — completed, cancelled or failed — stays listed for the pane window
300
+ * after its finish stamp so consumers see the outcome instead of the row
301
+ * vanishing; unconfirmed cancels are not dead and keep their own status. */
302
+ function projectChildWorkerRow(row, context) {
312
303
  if (!row || typeof row !== 'object') return null;
313
- if (!activeAgentWorker(row) && !sessionCancelState(row)) return null;
314
304
  if (cleanValue(row.agent).toLowerCase() === 'lead') return null;
315
305
  const sessionId = cleanValue(row.sessionId);
316
306
  const tag = cleanValue(row.tag);
317
307
  if (!sessionId || !tag || !isStoredSessionId(sessionId)) return null;
318
- // A new row may precede its first session save (null header).
308
+ // A stale done/error row does not hide a child the daemon is running. The
309
+ // header is read before any pane-window cutoff: an expired row can still sit
310
+ // beside a header that records a cancel-unconfirmed (possibly running)
311
+ // process. A new row may precede its first session save (null header).
319
312
  const session = readWorkerSessionHeader(sessionId);
320
313
  const declaredStatus = cleanValue(row.status) || 'running';
321
314
  const declaredStage = cleanValue(row.stage || row.status) || 'running';
322
315
  const declaredWorking = WORKING_AGENT_STATUS.test(workerLifecycle(row) || 'running');
323
- const heartbeatFresh = withinPoolWindow(heartbeatMtimes.get(sessionId) || 0, now);
324
- const recentlyUpdated = withinPoolWindow(Date.parse(cleanValue(row.updatedAt)) || 0, now);
325
- const runtimePid = positiveNumber(row.runtimePid, 0);
326
- const working = declaredWorking && (!runtimePid || runtimeAlive(runtimePid)) && (heartbeatFresh || recentlyUpdated);
316
+ // A cancel in the row (any field, stage included) or in the durable session
317
+ // header holds until demonstrably newer work supersedes it.
318
+ const cancel = effectiveCancel(row, session);
319
+ // The daemon's in-memory run state is authoritative: a running session is
320
+ // working whatever the durable row says. Only an explicit cancel outranks it.
321
+ const working = !cancel && sessionRunning(sessionId, context);
322
+ const completed = COMPLETED_AGENT_STATUS.test(workerLifecycle(row));
323
+ const unconfirmedCancel = Boolean(cancel) && CANCEL_UNCONFIRMED_AGENT_STATUS.test(cancel.status);
324
+ if (!working && !unconfirmedCancel && (cancel || !declaredWorking)) {
325
+ // Settled: only a completed, failed or cancelled outcome is listed, and
326
+ // only inside the pane window.
327
+ if (!cancel && !completed && !failedAgentWorker(row)) return null;
328
+ if (!agentPaneVisible(finishedAtMs(row, session), context.now)) return null;
329
+ }
330
+ let shownStatus = declaredStatus;
331
+ let shownStage = declaredStage;
332
+ if (cancel) {
333
+ shownStatus = cancel.status;
334
+ shownStage = cancelStage(cancel, declaredStage);
335
+ } else if (working) {
336
+ if (!declaredWorking) shownStatus = shownStage = 'running';
337
+ } else if (declaredWorking) {
338
+ shownStatus = shownStage = 'unknown';
339
+ } else if (completed) {
340
+ shownStatus = shownStage = 'completed';
341
+ }
327
342
  return {
328
343
  tag,
329
344
  sessionId,
@@ -339,11 +354,15 @@ function projectChildWorkerRow(row, { now, heartbeatMtimes }) {
339
354
  effort: cleanValue(row.effort || session?.effort) || null,
340
355
  fast: row.fast === true || session?.fast === true,
341
356
  ...(row.autoEffort === false || session?.autoEffort === false ? { autoEffort: false } : {}),
342
- status: declaredWorking && !working ? 'unknown' : declaredStatus,
343
- stage: declaredWorking && !working ? 'unknown' : declaredStage,
357
+ status: shownStatus,
358
+ stage: shownStage,
344
359
  // A live turn blocked on the user's approval (persisted by the agent
345
360
  // tool's worker index); never carried by a row that is no longer working.
346
361
  ...(working && row.awaitingUser === 'approval' ? { awaitingUser: 'approval' } : {}),
362
+ // Why a settled failed row failed; a row working again has no failure.
363
+ ...(!working && failedAgentWorker(row) && cleanValue(row.failureReason)
364
+ ? { failureReason: cleanValue(row.failureReason) }
365
+ : {}),
347
366
  startedAt: row.startedAt || row.createdAt || session?.createdAt || null,
348
367
  turnStartedAt: working ? row.turnStartedAt || null : null,
349
368
  createdAt: row.createdAt || session?.createdAt || null,
@@ -357,82 +376,6 @@ function projectChildWorkerRow(row, { now, heartbeatMtimes }) {
357
376
  };
358
377
  }
359
378
 
360
- /** The row a fresh heartbeat sidecar publishes over the current index row. */
361
- function sidecarWorkerRow(
362
- current,
363
- session,
364
- { sessionId, heartbeatAt, ownerSessionId, parentSessionId, agent, status }
365
- ) {
366
- return {
367
- ...current,
368
- tag: cleanValue(session?.agentTag) || cleanValue(current.tag) || `${agent || 'agent'}:${sessionId}`,
369
- sessionId,
370
- ownerSessionId,
371
- parentSessionId,
372
- title: cleanValue(session?.title) || current.title || null,
373
- agent: agent || current.agent || null,
374
- provider: cleanValue(session?.provider) || current.provider || null,
375
- model: cleanValue(session?.model) || current.model || null,
376
- effort: cleanValue(session?.effort) || current.effort || null,
377
- fast: session?.fast === true || current.fast === true,
378
- ...(session?.autoEffort === false || current.autoEffort === false ? { autoEffort: false } : {}),
379
- status,
380
- stage: status,
381
- startedAt: session?.createdAt || current.startedAt || heartbeatAt,
382
- turnStartedAt: current.turnStartedAt || null,
383
- createdAt: session?.createdAt || current.createdAt || null,
384
- updatedAt: heartbeatAt,
385
- cwd: cleanValue(session?.cwd) || current.cwd || null,
386
- clientHostPid: positiveNumber(session?.clientHostPid, 0) || current.clientHostPid || null,
387
- taskId: cleanValue(session?.task_id || session?.taskId) || current.taskId || null,
388
- ...sessionUsageTotals(session),
389
- };
390
- }
391
-
392
- /** Promote one fresh heartbeat sidecar into the pool.
393
- *
394
- * The durable index row is authoritative for FINISHED work: a worker's
395
- * runtime unloads at turn end but its heartbeat sidecar stays fresh for up to
396
- * the 2-minute window, and overwriting an idle row to `running` here made
397
- * every completed agent show as working and then flip back — the dock read as
398
- * blinking (user: 유휴인데 계속 살아있고 깜빡인다). The sidecar promotes only
399
- * rows the index does not already mark idle. A cancel is the same class of
400
- * authority: the lease must not rewrite cancelled / cancel-unconfirmed as
401
- * running at any point. Bare `cancelling` stays working. Genuinely new work is
402
- * a strictly later turn/start stamp, not a heartbeat-rewritten updatedAt. */
403
- function promoteHeartbeatSidecar(bySessionId, sessionId, heartbeatAt) {
404
- const session = readWorkerSessionHeader(sessionId);
405
- if (!session) return;
406
- const current = bySessionId.get(sessionId) || {};
407
- const ownerSessionId = workerOwnerSessionId(current, session);
408
- const parentSessionId = workerParentSessionId(current, session);
409
- const owner = cleanValue(session?.owner).toLowerCase();
410
- const agent = cleanValue(session?.agent);
411
- if (!ownerSessionId || (owner !== 'agent' && (!agent || agent === 'lead'))) return;
412
- const identity = { sessionId, heartbeatAt, ownerSessionId, parentSessionId, agent };
413
- // An UNCONFIRMED cancel outranks a confirmed one whichever side holds it.
414
- // Taking the index row first let a row still stamped `cancelled` MASK the
415
- // durable `cancel-unconfirmed` on the session, reporting a stop that was
416
- // never proven as a success. Never the reverse: a confirmed row only wins
417
- // when the session is not unconfirmed.
418
- const currentCancel = sessionCancelState(current);
419
- const cancel = preferUnconfirmedCancel(currentCancel, sessionCancelState(session));
420
- const newerWork = Boolean(cancel?.at) && (workStampMs(current) > cancel.at || workStampMs(session) > cancel.at);
421
- if (cancel && !newerWork) {
422
- // A cancel outranks a leftover heartbeat. Newer work is only a strictly
423
- // later turn/start stamp — never updatedAt, which the sidecar rewrites
424
- // every tick.
425
- if (currentCancel) return;
426
- bySessionId.set(sessionId, sidecarWorkerRow(current, session, { ...identity, status: cancel.status }));
427
- return;
428
- }
429
- const currentStatus = workerLifecycle(current);
430
- if (currentStatus && !WORKING_AGENT_STATUS.test(currentStatus)) return;
431
- // The sidecar is the live lease. Durable child sessions are intentionally
432
- // detached/closed while their external owner runs.
433
- bySessionId.set(sessionId, sidecarWorkerRow(current, session, { ...identity, status: 'running' }));
434
- }
435
-
436
379
  function storedLeadWorkerRows() {
437
380
  const path = storedLeadWorkerIndexPath();
438
381
  let parsed = readJsonProjection(path);
@@ -456,19 +399,24 @@ function leadRowOwnedByAgent(sessionId) {
456
399
  }
457
400
 
458
401
  /** A Lead worker-index row projected into the pool, or null. */
459
- function projectLeadWorkerRow(row, { now, heartbeatMtimes }) {
402
+ function projectLeadWorkerRow(row, context) {
403
+ const { now } = context;
460
404
  if (!row || typeof row !== 'object') return null;
461
405
  const sessionId = cleanValue(row.sessionId);
462
406
  if (!sessionId || !isStoredSessionId(sessionId)) return null;
463
407
  if (leadRowOwnedByAgent(sessionId)) return null;
464
- const heartbeatAt = heartbeatMtimes.get(sessionId) || 0;
465
- const heartbeatFresh = withinPoolWindow(heartbeatAt, now);
466
- const recentlyUpdated = withinPoolWindow(Date.parse(cleanValue(row.updatedAt)) || 0, now);
467
408
  const declaredStatus = workerLifecycle(row) || 'idle';
468
- const working = WORKING_AGENT_STATUS.test(declaredStatus) && (heartbeatFresh || recentlyUpdated);
469
- const reapAt = Date.parse(cleanValue(row.reapAt)) || 0;
470
- if (!heartbeatFresh && reapAt > 0 && now >= reapAt) return null;
471
- const shownStatus = !working && WORKING_AGENT_STATUS.test(declaredStatus) ? 'unknown' : declaredStatus;
409
+ const declaredWorking = WORKING_AGENT_STATUS.test(declaredStatus);
410
+ // As for child rows: an explicit cancel outranks the daemon's running report.
411
+ const cancel = effectiveCancel(row, null);
412
+ const working = !cancel && sessionRunning(sessionId, context);
413
+ // Live work outlasts the pane window; a settled Lead is listed for it after
414
+ // its finish stamp, whatever its provider reap window is.
415
+ if (!working && !agentPaneVisible(finishedAtMs(row), now)) return null;
416
+ let shownStatus = declaredStatus;
417
+ if (cancel) shownStatus = cancel.status;
418
+ else if (working) shownStatus = declaredWorking ? declaredStatus : 'running';
419
+ else if (declaredWorking) shownStatus = 'unknown';
472
420
  return {
473
421
  tag: `lead:${sessionId}`,
474
422
  sessionId,
@@ -485,7 +433,7 @@ function projectLeadWorkerRow(row, { now, heartbeatMtimes }) {
485
433
  startedAt: row.startedAt || row.createdAt || null,
486
434
  turnStartedAt: working ? row.turnStartedAt || null : null,
487
435
  createdAt: row.createdAt || null,
488
- updatedAt: working ? heartbeatAt || row.updatedAt || null : row.updatedAt || null,
436
+ updatedAt: row.updatedAt || null,
489
437
  idleSince: frozenIdleSince(sessionId, working, row.finishedAt || row.updatedAt || null),
490
438
  cwd: cleanValue(row.cwd) || null,
491
439
  clientHostPid: positiveNumber(row.clientHostPid, 0) || null,
@@ -500,26 +448,23 @@ function projectLeadWorkerRow(row, { now, heartbeatMtimes }) {
500
448
  * above it (user report). Only a Lead CONVERSATION owner is judged — and a
501
449
  * child that is still working always stays, so live work never disappears
502
450
  * from the window. */
503
- function pruneOrphanChildRows(bySessionId, { liveLeadSessionIds, heartbeatMtimes, now }) {
451
+ function pruneOrphanChildRows(bySessionId, { liveLeadSessionIds }) {
504
452
  for (const [sessionId, row] of [...bySessionId]) {
505
453
  if (cleanValue(row.agent).toLowerCase() === 'lead') continue;
506
454
  const ownerSessionId = cleanValue(row.ownerSessionId);
507
455
  if (!ownerSessionId || liveLeadSessionIds.has(ownerSessionId)) continue;
508
456
  if (!leadConversationHeader(readWorkerSessionHeader(ownerSessionId))) continue;
509
- if (poolRowWorking(row, heartbeatMtimes, now)) continue;
457
+ if (poolRowWorking(row)) continue;
510
458
  bySessionId.delete(sessionId);
511
459
  }
512
460
  }
513
461
 
514
- /** Process-global active agent pool. Fresh child heartbeat sidecars are the
515
- * cross-process running source even when their durable session is detached
516
- * (`closed`) and a terminal reaper has already removed the worker-index row.
517
- * The child and Lead indexes remain additive for living rows (running or idle)
518
- * published before the heartbeat or by runtimes without a sidecar. No runtime
519
- * starts and durable session history is never projected into either pool. */
520
- export function listStoredAgentWorkers() {
462
+ /** Process-global active agent pool: the living rows (running or idle) of the
463
+ * child and Lead indexes. No runtime starts and durable session history is
464
+ * never projected into either pool. `runningSessionIds` is the daemon's set of
465
+ * sessions whose turn is in flight; omitted, no row is shown as running. */
466
+ export function listStoredAgentWorkers({ runningSessionIds = null } = {}) {
521
467
  const now = Date.now();
522
- const heartbeatMtimes = sessionHeartbeatMtimes();
523
468
  const index = storedAgentWorkerIndex();
524
469
  const rows = workerRows(index);
525
470
  const byId = new Map(rows.map((row) => [cleanValue(row.sessionId), row]));
@@ -544,14 +489,9 @@ export function listStoredAgentWorkers() {
544
489
  };
545
490
  return assembleStoredAgentWorkers({
546
491
  now,
547
- heartbeatMtimes,
492
+ runningSessionIds,
548
493
  storedAgentWorkerIndexRows: () => rows.filter((row) => !isReaped(cleanValue(row.sessionId))),
549
494
  projectChildWorkerRow,
550
- promoteHeartbeatSidecar: (bySessionId, sessionId, heartbeatAt) => {
551
- if (withinPoolWindow(heartbeatAt, now) && !isReaped(sessionId)) {
552
- promoteHeartbeatSidecar(bySessionId, sessionId, heartbeatAt);
553
- }
554
- },
555
495
  storedLeadWorkerRows,
556
496
  projectLeadWorkerRow,
557
497
  pruneOrphanChildRows,
@@ -7,13 +7,17 @@
7
7
  * `label`, `agent`, `provider`, `model`, `effort`, `fast`, `finished`) and the
8
8
  * "\n\nResult:\n" marker are the wire format the notification writer emits;
9
9
  * they are matched verbatim.
10
+ *
11
+ * Only the parent(s) named by metadata are read — never the sessions
12
+ * directory: every vanished id reaches this path (deleted Lead records too),
13
+ * and a synchronous scan of every session file froze the daemon loop.
10
14
  */
11
- import { readFileSync, readdirSync } from 'node:fs';
15
+ import { readFile } from 'node:fs/promises';
12
16
  import { join } from 'node:path';
13
- import { probePath, PROBE_PRESENT } from './store/fs-probe.mjs';
14
17
  import { readTopLevelLifecycleRecord, isLifecycleUnreadable } from './lifecycle-scan.mjs';
15
18
  import { dataDir } from './store-summary-locations.mjs';
16
- import { cleanValue, desktopSession, positiveNumber } from './store-summary-fields.mjs';
19
+ import { listStoredAgentWorkerLinks } from './store-agent-worker-rows.mjs';
20
+ import { cleanValue, desktopSession, isStoredSessionId, positiveNumber } from './store-summary-fields.mjs';
17
21
 
18
22
  function archivedAgentNotification(content, sessionId) {
19
23
  const text = typeof content === 'string' ? content : '';
@@ -52,23 +56,38 @@ function archivedAgentNotification(content, sessionId) {
52
56
  };
53
57
  }
54
58
 
59
+ /** Parent session ids metadata names for `sessionId`: its agent-workers.json
60
+ * link and its summary-catalog row (`catalogRow(id)`, optional). */
61
+ function parentSessionIds(sessionId, catalogRow) {
62
+ const parents = new Set();
63
+ for (const link of listStoredAgentWorkerLinks()) {
64
+ if (link.sessionId !== sessionId) continue;
65
+ parents.add(link.parentSessionId);
66
+ parents.add(link.ownerSessionId);
67
+ }
68
+ const row = typeof catalogRow === 'function' ? catalogRow(sessionId) : null;
69
+ if (row) {
70
+ parents.add(cleanValue(row.parentSessionId));
71
+ parents.add(cleanValue(row.ownerSessionId));
72
+ }
73
+ parents.delete(sessionId);
74
+ return [...parents].filter(isStoredSessionId);
75
+ }
76
+
55
77
  /** Legacy recovery for child transcripts already unlinked by terminal reaping.
56
- * The parent owns one canonical body-carrying completion notification, so scan
57
- * only files containing the exact child id and project the newest valid body. */
58
- export function readArchivedAgentResult(sessionId) {
78
+ * The parent owns one canonical body-carrying completion notification: read
79
+ * only the parent(s) metadata links the child to, asynchronously, and project
80
+ * the newest valid body. An id with no parent link (a deleted Lead record)
81
+ * resolves to null without touching any session file. */
82
+ export async function readArchivedAgentResult(sessionId, { catalogRow } = {}) {
83
+ const parents = parentSessionIds(sessionId, catalogRow);
84
+ if (parents.length === 0) return null;
59
85
  const dir = join(dataDir(), 'sessions');
60
- if (probePath(dir).state !== PROBE_PRESENT) return null;
61
- let files;
62
- try {
63
- files = readdirSync(dir).filter((file) => file.endsWith('.json'));
64
- } catch {
65
- return null;
66
- }
67
86
  let best = null;
68
- for (const file of files) {
87
+ for (const parentId of parents) {
69
88
  let raw;
70
89
  try {
71
- raw = readFileSync(join(dir, file), 'utf8');
90
+ raw = await readFile(join(dir, `${parentId}.json`), 'utf8');
72
91
  } catch {
73
92
  continue;
74
93
  }