mixdog 1.2.3 → 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 (465) hide show
  1. package/package.json +1 -1
  2. package/scripts/gate-local.mjs +6 -4
  3. package/scripts/lib/gate-scheduler.mjs +29 -11
  4. package/scripts/probe-provider-catalog.mjs +31 -0
  5. package/scripts/provider-pingpong-live.mjs +128 -38
  6. package/scripts/session-sweep.mjs +5 -25
  7. package/src/agents/maintainer/AGENT.md +1 -1
  8. package/src/agents/maintainer/agent.json +1 -1
  9. package/src/agents/reviewer/AGENT.md +2 -4
  10. package/src/agents/security/AGENT.md +1 -2
  11. package/src/agents/writer/AGENT.md +2 -3
  12. package/src/defaults/shipped-history.json +6 -1
  13. package/src/defaults/skills/image/SKILL.md +21 -23
  14. package/src/lib/keychain-cjs.cjs +13 -11
  15. package/src/rules/agent/AGENT.md +7 -5
  16. package/src/rules/lead/LEAD.md +7 -9
  17. package/src/rules/shared/45-destructive.md +4 -0
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  20. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  21. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  22. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  23. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  24. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
  25. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
  26. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  27. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  28. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
  29. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  31. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  32. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
  33. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
  34. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
  35. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
  36. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
  37. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
  38. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  41. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  42. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  43. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
  44. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
  45. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
  46. package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
  47. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
  48. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
  49. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
  50. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
  51. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
  52. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
  53. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  54. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  55. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
  56. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
  57. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
  58. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
  59. package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
  60. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  61. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
  62. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
  63. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  64. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
  65. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
  66. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  67. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
  68. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
  73. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
  74. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
  75. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
  76. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
  77. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  78. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
  79. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  80. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
  81. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
  82. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
  83. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
  84. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
  85. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
  86. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
  87. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
  88. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
  89. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
  90. package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
  91. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
  92. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
  93. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
  94. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
  95. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
  96. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  97. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
  98. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  99. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  100. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  101. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
  102. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  103. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
  104. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
  106. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  107. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  108. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  109. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  110. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  111. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
  112. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  113. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
  114. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  115. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
  116. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  118. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  119. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
  120. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  121. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  122. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
  123. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
  124. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
  125. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  126. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  127. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  128. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
  129. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
  130. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
  131. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  132. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
  133. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
  134. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  135. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
  136. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
  137. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
  138. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  139. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  140. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
  142. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  143. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
  144. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
  145. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  146. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  147. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  148. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  149. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
  150. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  151. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  152. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
  153. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
  155. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  156. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
  157. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  158. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
  159. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  160. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
  161. package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
  162. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
  163. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  164. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  165. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  166. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  167. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  169. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
  170. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  171. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  172. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
  174. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  175. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  176. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  177. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  179. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  180. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
  181. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  182. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  183. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
  184. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  185. package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
  186. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
  187. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
  188. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  189. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
  190. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  191. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  192. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  195. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
  196. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  197. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  198. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  199. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  200. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  201. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  202. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  203. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  205. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  206. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  207. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  208. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  209. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  210. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  211. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  212. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  213. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  214. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  215. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  216. package/src/runtime/attachments/store.d.mts +9 -0
  217. package/src/runtime/attachments/store.mjs +80 -9
  218. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  219. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  220. package/src/runtime/computer-bridge/action-schema.mjs +178 -178
  221. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  222. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  223. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  224. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  225. package/src/runtime/github/tool.mjs +118 -17
  226. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  227. package/src/runtime/media/catalog.mjs +4 -4
  228. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  229. package/src/runtime/media/defaults.mjs +37 -0
  230. package/src/runtime/media/jobs.mjs +12 -2
  231. package/src/runtime/media/lanes.mjs +12 -0
  232. package/src/runtime/media/tool-defs.mjs +15 -4
  233. package/src/runtime/media/tool.mjs +41 -12
  234. package/src/runtime/media/upstream-error.mjs +72 -6
  235. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  236. package/src/runtime/memory/lib/pg/process.mjs +5 -7
  237. package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
  238. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  239. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  240. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  241. package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
  242. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  243. package/src/runtime/office/core/office-write-ledger.mjs +1 -5
  244. package/src/runtime/office/index.mjs +2 -3
  245. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  246. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  247. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  248. package/src/runtime/shared/atomic-file.d.mts +1 -1
  249. package/src/runtime/shared/background-tasks.mjs +6 -1
  250. package/src/runtime/shared/bounded-line-diff.mjs +11 -2
  251. package/src/runtime/shared/browser-launch.mjs +15 -0
  252. package/src/runtime/shared/err-text.mjs +42 -4
  253. package/src/runtime/shared/file-lock.mjs +6 -5
  254. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  255. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  256. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  257. package/src/runtime/shared/model-route-chain.mjs +48 -0
  258. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  259. package/src/runtime/shared/pid-liveness.mjs +12 -0
  260. package/src/runtime/shared/provider-api-key.mjs +6 -0
  261. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  262. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  263. package/src/runtime/shared/quiet-progress.mjs +101 -0
  264. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  265. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  266. package/src/runtime/shared/remote-intent.mjs +2 -42
  267. package/src/runtime/shared/slow-span.mjs +8 -1
  268. package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
  269. package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
  270. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  271. package/src/runtime/shared/tool-result-summary.mjs +16 -2
  272. package/src/runtime/shared/tool-status.mjs +3 -2
  273. package/src/runtime/shared/tool-surface.mjs +2 -3
  274. package/src/runtime/shared/tool-work-units.mjs +22 -15
  275. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  276. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  277. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  278. package/src/runtime/shared/transcript-writer.mjs +14 -4
  279. package/src/runtime/shared/turn-changes.mjs +2 -1
  280. package/src/runtime/shared/turn-snapshot.mjs +11 -3
  281. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  282. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  283. package/src/runtime/shared/worktrees/carry.mjs +6 -4
  284. package/src/runtime/shared/worktrees/contract.mjs +27 -1
  285. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  286. package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
  287. package/src/runtime/shared/worktrees/git-head.mjs +22 -13
  288. package/src/runtime/shared/worktrees/include.mjs +125 -7
  289. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  290. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  291. package/src/runtime/shared/worktrees/manager.mjs +378 -32
  292. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  293. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  294. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  295. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  296. package/src/runtime/terminal-bridge/client.mjs +14 -10
  297. package/src/session-runtime/boot/apis.mjs +7 -1
  298. package/src/session-runtime/boot/config.mjs +2 -0
  299. package/src/session-runtime/boot/facade.mjs +3 -0
  300. package/src/session-runtime/boot/session.mjs +3 -2
  301. package/src/session-runtime/boot/tools.mjs +3 -0
  302. package/src/session-runtime/conversation-import/service.mjs +1 -1
  303. package/src/session-runtime/goal-facade-api.mjs +2 -2
  304. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
  305. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
  306. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
  307. package/src/session-runtime/internal-tool-executor.mjs +2 -0
  308. package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
  309. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
  310. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
  311. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  312. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  313. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  314. package/src/session-runtime/lifecycle/teardown.mjs +7 -16
  315. package/src/session-runtime/media-api.mjs +8 -0
  316. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  317. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  318. package/src/session-runtime/model-route/set-route.mjs +114 -34
  319. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  320. package/src/session-runtime/model-route-api.mjs +4 -2
  321. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  322. package/src/session-runtime/native-web-search.mjs +9 -8
  323. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  324. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  325. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  326. package/src/session-runtime/provider-models.mjs +1 -0
  327. package/src/session-runtime/provider-usage.mjs +4 -0
  328. package/src/session-runtime/route-resolution.mjs +3 -1
  329. package/src/session-runtime/runtime-core.mjs +4 -0
  330. package/src/session-runtime/runtime-facade.mjs +6 -0
  331. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  332. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  333. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  334. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  335. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  336. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  337. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  338. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  339. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  340. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  341. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  342. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  343. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
  344. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  345. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  346. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  347. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  348. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  349. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  350. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  351. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  352. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  353. package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
  354. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  355. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  356. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  357. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  358. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  359. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  360. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  361. package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
  362. package/src/session-runtime/services/agent-tool.mjs +4 -0
  363. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  364. package/src/session-runtime/services/provider-admin.mjs +77 -0
  365. package/src/session-runtime/session-create/session-options.mjs +7 -5
  366. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  367. package/src/session-runtime/session-transcript.mjs +4 -5
  368. package/src/session-runtime/session-turn-api.mjs +3 -9
  369. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
  370. package/src/session-runtime/setup-tool/executor.mjs +23 -5
  371. package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
  372. package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
  373. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
  374. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  375. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  376. package/src/session-runtime/turn/side-question-ops.mjs +1 -4
  377. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
  378. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
  379. package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
  380. package/src/session-runtime/turn/turn-run.mjs +1 -36
  381. package/src/session-runtime/usage-stats-api.mjs +4 -1
  382. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  383. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  384. package/src/session-runtime/workspace/project-branches.mjs +28 -36
  385. package/src/session-runtime/workspace/transition-steps.mjs +96 -95
  386. package/src/session-runtime/workspace/transitions.mjs +248 -68
  387. package/src/standalone/channel-transport.mjs +3 -4
  388. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  389. package/src/standalone/daemon-pg-stop.mjs +1 -3
  390. package/src/standalone/daemon-session-control.mjs +88 -0
  391. package/src/standalone/daemon-stored-session-views.mjs +23 -3
  392. package/src/standalone/daemon.mjs +2 -0
  393. package/src/standalone/local-session-runtime.mjs +11 -12
  394. package/src/standalone/session-protocol.mjs +7 -0
  395. package/src/standalone/session-runtime-inline-host.mjs +2 -0
  396. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  397. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  398. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  399. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  400. package/src/standalone/session-service/agent-tree.mjs +28 -2
  401. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  402. package/src/standalone/session-service/entries.mjs +1 -0
  403. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  404. package/src/standalone/session-service/quota-resume.mjs +28 -13
  405. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  406. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  407. package/src/standalone/session-tool-output.mjs +82 -0
  408. package/src/tui/app/app-view.jsx +2 -1
  409. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  410. package/src/tui/app/provider-setup-picker.mjs +15 -3
  411. package/src/tui/app/slash-commands.mjs +6 -0
  412. package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
  413. package/src/tui/components/Spinner.jsx +4 -0
  414. package/src/tui/components/SpinnerByline.jsx +21 -2
  415. package/src/tui/components/status-line/local-line.mjs +10 -2
  416. package/src/tui/dist/index.mjs +478 -251
  417. package/src/tui/session/active-tool-summary.mjs +1 -1
  418. package/src/tui/session/context-state.mjs +0 -3
  419. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  420. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  421. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  422. package/src/tui/session/quota-resume.mjs +140 -61
  423. package/src/tui/session/session-api/commands.mjs +4 -10
  424. package/src/tui/session/session-api/controls.mjs +12 -0
  425. package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
  426. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  427. package/src/tui/session/session-api/lifecycle.mjs +13 -11
  428. package/src/tui/session/session-api/media.mjs +2 -0
  429. package/src/tui/session/session-api/routes.mjs +81 -57
  430. package/src/tui/session/session-api/settings.mjs +3 -3
  431. package/src/tui/session/session-api/worktree.mjs +3 -2
  432. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  433. package/src/tui/session/session-flow/drain.mjs +6 -4
  434. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  435. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  436. package/src/tui/session/session-flow/queue.mjs +1 -1
  437. package/src/tui/session/tool-approval.mjs +17 -8
  438. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  439. package/src/tui/session/tui-steering-persist.mjs +3 -5
  440. package/src/tui/session/turn-quiet.mjs +53 -0
  441. package/src/tui/session/turn-stream.mjs +5 -1
  442. package/src/tui/session/turn.mjs +38 -31
  443. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  444. package/src/tui/spinner-meta.mjs +10 -0
  445. package/src/tui/spinner-verbs.mjs +3 -0
  446. package/src/ui/statusline.mjs +13 -3
  447. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  448. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  449. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  450. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
  451. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  452. package/src/session-runtime/turn/share-ops.mjs +0 -77
  453. package/src/tui/session/cross-surface-share.mjs +0 -406
  454. package/src/tui/session/live-share/delta.mjs +0 -153
  455. package/src/tui/session/live-share/mirror.mjs +0 -106
  456. package/src/tui/session/live-share/owner.mjs +0 -254
  457. package/src/tui/session/live-share/retry.mjs +0 -54
  458. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  459. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  460. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  461. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  462. package/src/tui/session/live-share/viewer.mjs +0 -99
  463. package/src/tui/session/live-share/wire.mjs +0 -44
  464. package/src/tui/session/live-share.mjs +0 -154
  465. package/src/tui/session/shared-dir-watch.mjs +0 -69
@@ -2,7 +2,12 @@
2
2
  // standby fast path, the spawn-burst gate around process creation, and the
3
3
  // delayed live foreground record once the command has reached a shell.
4
4
  import { acquire as acquireChildSpawnSlot } from '../../../../shared/child-spawn-gate.mjs';
5
- import { publishForegroundShellRecord, trackForegroundShellJob } from '../builtin/shell-jobs.mjs';
5
+ import {
6
+ killShellJob,
7
+ publishForegroundShellRecord,
8
+ trackForegroundShellJob,
9
+ waitForShellJob,
10
+ } from '../builtin/shell-jobs.mjs';
6
11
  import {
7
12
  nativeSpawnFileCaptureReady,
8
13
  nativeSpawnSupportsStdinPipe,
@@ -13,6 +18,11 @@ import { _maybeEncodePowerShellCommand } from '../shell-powershell.mjs';
13
18
  import { spawnShellWithRetry as _spawnShellWithRetry } from './shell-spawn-retry.mjs';
14
19
  import { STANDBY_ARGS, takeWarmShellStandby } from './shell-warm-standby.mjs';
15
20
  import { SHELL_OUTPUT_DISK_CAP } from '../shell-exec-output.mjs';
21
+ import { admitWorkspaceActivity, tryAdmitWorkspaceActivity } from '../../../../shared/worktrees/activity-gate.mjs';
22
+ import { worktreeError } from '../../../../shared/worktrees/contract.mjs';
23
+ import { capturePreKill, registerForegroundOwnedTree, treeKillForceSettle } from './shell-run-state.mjs';
24
+ import { releaseAdmissionOnConfirmedTermination } from './shell-run-settle.mjs';
25
+ import { killAfterSnapshot } from './shell-descendants.mjs';
16
26
 
17
27
  // Foreground visibility threshold. Every shell readout (CLI statusline,
18
28
  // desktop island) scans the on-disk job records, so a foreground command is
@@ -148,7 +158,7 @@ async function gatedSpawn({
148
158
  * the moment the command reached it. Throws on spawn failure; the caller
149
159
  * turns that into the spawn-failed result.
150
160
  */
151
- export async function spawnShellChild({
161
+ async function spawnAdmittedShellChild({
152
162
  run,
153
163
  shell,
154
164
  shellArg,
@@ -163,6 +173,9 @@ export async function spawnShellChild({
163
173
  clientHostPid,
164
174
  }) {
165
175
  const { useDirectArgv, spawnCommand, argv } = shapeArgv({ directArgv, shellArg, shellArgs, command, execScript });
176
+ // Set before any child exists: a startup that fails after the child is
177
+ // created still publishes a visible record and an owned termination hold.
178
+ run.foregroundRecordInput = { command, cwd, ownerSessionId, clientHostPid };
166
179
  const onChildError = (err) => {
167
180
  run.spawnError = run.spawnError || err;
168
181
  run.failurePhase = 'tool';
@@ -209,10 +222,22 @@ export async function spawnShellChild({
209
222
  clientHostPid,
210
223
  }));
211
224
  run.child = spawned.child;
225
+ registerForegroundOwnedTree(run, ownerSessionId);
226
+ const parentAdmission = run.workspaceAdmission;
227
+ const childAdmission = tryAdmitWorkspaceActivity(ownerSessionId || run.foregroundRecordId, cwd || process.cwd(), {
228
+ pid: Number(run.child.pid) || process.pid,
229
+ kind: 'command',
230
+ });
231
+ if (!childAdmission) throw worktreeError('WORKTREE_BUSY_JOBS', 'The command workspace changed during spawn.');
232
+ run.workspaceAdmission = () => {
233
+ childAdmission();
234
+ parentAdmission();
235
+ };
212
236
  spawned.attachErrorHandler(onChildError);
213
237
  // Feed the script only after the error handler is attached; server
214
238
  // messages cannot be processed before this synchronous block yields.
215
239
  // Single atomic write+EOF, as for the standby.
240
+ abortSignal?.throwIfAborted();
216
241
  if (standby) standby.feed(spawnCommand, cwd);
217
242
  else if (stdinScript !== null) spawned.child.writeStdin(stdinScript, { close: true });
218
243
  // The command has now reached a shell. This is the start moment every
@@ -224,15 +249,56 @@ export async function spawnShellChild({
224
249
  run.foregroundRecordTimer = null;
225
250
  if (run.settled || run.autoBackgrounded || !run.child?.pid) return;
226
251
  run.foregroundRecordPublished = true;
227
- publishForegroundShellRecord({
228
- jobId: run.foregroundRecordId,
229
- command,
230
- cwd,
231
- pid: run.child.pid,
232
- startedAtMs: run.commandStartedAtMs,
233
- ownerSessionId,
234
- clientHostPid,
235
- });
252
+ try {
253
+ publishForegroundShellRecord({
254
+ ...run.foregroundRecordInput,
255
+ jobId: run.foregroundRecordId,
256
+ pid: run.child.pid,
257
+ startedAtMs: run.commandStartedAtMs,
258
+ });
259
+ } catch (error) {
260
+ run.spawnError = error;
261
+ run.failureReason = 'workspace publication failed';
262
+ treeKillForceSettle(run, 'workspace-publication-failed');
263
+ }
236
264
  }, FOREGROUND_RECORD_DELAY_MS);
237
265
  run.foregroundRecordTimer.unref?.();
238
266
  }
267
+
268
+ /** Admission precedes both native process creation and feeding a warm shell. */
269
+ export async function spawnShellChild(input) {
270
+ input.run.workspaceAdmission = await admitWorkspaceActivity(
271
+ input.ownerSessionId || input.run.foregroundRecordId,
272
+ input.cwd || process.cwd(),
273
+ input.abortSignal,
274
+ { kind: 'command' }
275
+ );
276
+ try {
277
+ input.abortSignal?.throwIfAborted();
278
+ return await spawnAdmittedShellChild(input);
279
+ } catch (error) {
280
+ if (!input.run.child) {
281
+ input.run.workspaceAdmission();
282
+ input.run.workspaceAdmission = null;
283
+ } else {
284
+ try {
285
+ // Identities first: the kill may break the parent chain.
286
+ // Bounded: the kill is sent even if the snapshot hangs or fails.
287
+ await killAfterSnapshot(capturePreKill(input.run), () => killShellJob(input.run.foregroundRecordId));
288
+ const detail = await waitForShellJob(input.run.foregroundRecordId);
289
+ if (!detail || !['completed', 'failed', 'cancelled'].includes(detail.nativeStatus)) {
290
+ throw new Error('The child termination could not be confirmed; workspace admission is retained.');
291
+ }
292
+ input.run.workspaceAdmission?.();
293
+ input.run.workspaceAdmission = null;
294
+ } catch (cleanupError) {
295
+ input.run.killUnconfirmed = true;
296
+ // No settle will ever run for this run; the reservation is released
297
+ // only once the child has exited and its descendants are gone.
298
+ releaseAdmissionOnConfirmedTermination(input.run);
299
+ throw new AggregateError([error, cleanupError], 'Shell startup failed and workspace cleanup remains blocked.');
300
+ }
301
+ }
302
+ throw error;
303
+ }
304
+ }
@@ -4,8 +4,37 @@
4
4
  // tree-kill. The spawn, settle and auto-background phases live in their own
5
5
  // modules and read/write this one record.
6
6
  import { randomUUID } from 'node:crypto';
7
- import { retireForegroundShellRecord } from '../builtin/shell-jobs.mjs';
7
+ import { publishForegroundShellRecord, retireForegroundShellRecord } from '../builtin/shell-jobs.mjs';
8
8
  import { ShellTextDecoder, TaskOutput, treeKill } from '../shell-exec-output.mjs';
9
+ import { createProcessTreeTracker, killAfterSnapshot } from './shell-descendants.mjs';
10
+ import { registerOwnedShellTree } from './owned-shell-trees.mjs';
11
+
12
+ /** One pre-kill identity read of the run's tree (every kill path shares it):
13
+ * resolves true once the capture is complete, false when it failed. */
14
+ export function capturePreKill(run) {
15
+ run.terminationTracker = run.terminationTracker || createProcessTreeTracker({ pid: run.child.pid });
16
+ const rootExited = run.child.exitCode != null || run.child.signalCode != null;
17
+ return run.terminationTracker.capture({ rootExited }).catch(() => false);
18
+ }
19
+
20
+ /** Session close cancels every tree its session owns. For a foreground run
21
+ * that cancel must snapshot the identities first, exactly like the run's own
22
+ * kill, and mark the run owner-cancelled so its settle completes on confirmed
23
+ * termination instead of on the root's exit. */
24
+ export function registerForegroundOwnedTree(run, ownerSessionId) {
25
+ if (!ownerSessionId) return;
26
+ run.ownedTree = {
27
+ ownerSessionId,
28
+ prepareKill: () => {
29
+ if (run.settled || run.autoBackgrounded || !run.child?.pid) return true;
30
+ run.killed = true;
31
+ run.ownerCancelled = true;
32
+ run.killCause = run.killCause || 'session-close';
33
+ return run.terminationTracker?.complete === true || capturePreKill(run);
34
+ },
35
+ };
36
+ registerOwnedShellTree(run.foregroundRecordId, run.ownedTree);
37
+ }
9
38
 
10
39
  // Treekill + exit confirmation. treeKill alone leaves settle() pending on
11
40
  // 'close'/'exit'; on Windows a taskkill miss or a grandchild holding stdio
@@ -85,6 +114,12 @@ export function createShellRun({ abortSignal, resolve, jobId = null }) {
85
114
  foregroundRecordId: jobId || `job_${Date.now()}_${randomUUID().slice(0, 6)}`,
86
115
  foregroundRecordTimer: null,
87
116
  foregroundRecordPublished: false,
117
+ // Command/cwd/owner the live record is published with.
118
+ foregroundRecordInput: null,
119
+ // Process identities captured before a kill, and the stop() of the
120
+ // observation loop that holds the workspace until they are gone.
121
+ terminationTracker: null,
122
+ stopTerminationWatch: null,
88
123
  };
89
124
  }
90
125
 
@@ -149,6 +184,49 @@ export function clearForegroundRecord(run) {
149
184
  // Runtime of the COMMAND (see startMs).
150
185
  export const elapsedSinceStart = (run) => Math.max(0, Date.now() - (run.commandStartedAtMs || run.startMs));
151
186
 
187
+ /** The command's result is reported, but its processes are not confirmed
188
+ * gone: the live record stays — now marked unconfirmed — until the
189
+ * termination watch retires it. */
190
+ export function keepTerminationUnconfirmedRecord(run) {
191
+ if (run.foregroundRecordTimer) {
192
+ clearTimeout(run.foregroundRecordTimer);
193
+ run.foregroundRecordTimer = null;
194
+ }
195
+ if (!run.foregroundRecordInput || !run.child?.pid) return;
196
+ try {
197
+ publishForegroundShellRecord({
198
+ ...run.foregroundRecordInput,
199
+ jobId: run.foregroundRecordId,
200
+ pid: run.child.pid,
201
+ startedAtMs: run.commandStartedAtMs,
202
+ terminationUnconfirmed: true,
203
+ });
204
+ run.foregroundRecordPublished = true;
205
+ } catch {
206
+ /* the record is presentation; the workspace admission stays held */
207
+ }
208
+ }
209
+
210
+ // Record the tree's identities while the root is still alive, THEN kill: once
211
+ // an intermediate dies its children's parent links dangle and a snapshot taken
212
+ // afterwards can no longer find them.
213
+ // The kill waits for the snapshot at most PROCESS_TABLE_READ_BOUND_MS and is
214
+ // sent whether the snapshot succeeded, failed or is still pending (a late
215
+ // snapshot is still absorbed; a missing one leaves the outcome unknown, so the
216
+ // workspace stays held under the observation loop). The confirmation deadline
217
+ // starts once the kill is actually issued.
218
+ function snapshotThenKill(run, afterKill) {
219
+ if (!run.child?.pid) {
220
+ treeKill(run.child);
221
+ afterKill();
222
+ return;
223
+ }
224
+ void killAfterSnapshot(capturePreKill(run), () => {
225
+ treeKill(run.child);
226
+ afterKill();
227
+ });
228
+ }
229
+
152
230
  export function treeKillForceSettle(run, cause) {
153
231
  run.killed = true;
154
232
  run.killCause = run.killCause || cause || 'runtime-guard';
@@ -161,8 +239,7 @@ export function treeKillForceSettle(run, cause) {
161
239
  if (run.child?.exitCode != null || run.child?.signalCode != null) return;
162
240
  attempts += 1;
163
241
  if (attempts < KILL_CONFIRM_ATTEMPTS) {
164
- treeKill(run.child);
165
- armConfirmation();
242
+ snapshotThenKill(run, armConfirmation);
166
243
  return;
167
244
  }
168
245
  run.partialOutput = true;
@@ -172,6 +249,5 @@ export function treeKillForceSettle(run, cause) {
172
249
  }, KILL_CONFIRM_INTERVAL_MS);
173
250
  if (deadline.unref) deadline.unref();
174
251
  };
175
- treeKill(run.child);
176
- armConfirmation();
252
+ snapshotThenKill(run, armConfirmation);
177
253
  }
@@ -1,3 +1,12 @@
1
1
  export function readAttachmentBuffer(value: string | { attachmentRef?: string }): Buffer;
2
2
  export function isPermanentAttachmentError(error: unknown): boolean;
3
3
  export function isAttachmentReference(value: unknown): boolean;
4
+ export interface MessageAttachment {
5
+ id: string;
6
+ attachmentRef: string;
7
+ kind: 'image' | 'file' | 'text';
8
+ name: string;
9
+ mimeType: string;
10
+ size: number;
11
+ }
12
+ export function attachmentsForIntake(prompt: unknown, options?: unknown): MessageAttachment[];
@@ -2,8 +2,8 @@
2
2
  * Content-addressed prompt attachment store.
3
3
  *
4
4
  * Renderer/TUI inputs carry the bytes exactly once to the daemon intake. From
5
- * that boundary onward queues, checkpoints, session JSON, live-share frames,
6
- * and desktop snapshots carry only a sha256 reference plus byte-free metadata.
5
+ * that boundary onward queues, checkpoints, session JSON and desktop
6
+ * snapshots carry only a sha256 reference plus byte-free metadata.
7
7
  * Provider lowering resolves the reference at the last possible boundary.
8
8
  */
9
9
  import { createHash, randomBytes } from 'node:crypto';
@@ -214,11 +214,13 @@ export function storeInlineDocumentPart(part) {
214
214
  if (source?.type !== 'base64' || typeof source.data !== 'string') return null;
215
215
  data = source.data;
216
216
  const { source: _source, type: _type, mimeType: _mimeType, mediaType: _mediaType, ...rest } = part;
217
- const mimeType = String(source.media_type || source.mediaType || part.mimeType || part.mediaType || 'application/pdf')
218
- .trim()
219
- .toLowerCase() || 'application/pdf';
217
+ const mimeType =
218
+ String(source.media_type || source.mediaType || part.mimeType || part.mediaType || 'application/pdf')
219
+ .trim()
220
+ .toLowerCase() || 'application/pdf';
220
221
  metadata = { ...rest, type: 'file', mimeType };
221
- const filename = (typeof part.title === 'string' && part.title) || (typeof part.filename === 'string' && part.filename) || '';
222
+ const filename =
223
+ (typeof part.title === 'string' && part.title) || (typeof part.filename === 'string' && part.filename) || '';
222
224
  if (filename) metadata.filename = filename;
223
225
  } else if (part.type === 'file' && typeof part.data === 'string') {
224
226
  const { data: inline, ...rest } = part;
@@ -282,9 +284,7 @@ export function isMissingAttachmentError(error) {
282
284
  // never become readable. EBUSY/EPERM/EACCES/EMFILE and friends are transient:
283
285
  // callers must let them propagate rather than rewrite history around them.
284
286
  export function isPermanentAttachmentError(error) {
285
- return (
286
- isMissingAttachmentError(error) || error?.code === ATTACHMENT_INVALID || error?.code === ATTACHMENT_INTEGRITY
287
- );
287
+ return isMissingAttachmentError(error) || error?.code === ATTACHMENT_INVALID || error?.code === ATTACHMENT_INTEGRITY;
288
288
  }
289
289
 
290
290
  export function readAttachmentBase64(value) {
@@ -534,6 +534,77 @@ export function materializePromptSubmission(prompt, options = {}) {
534
534
  };
535
535
  }
536
536
 
537
+ const MAX_MESSAGE_ATTACHMENTS = 64;
538
+
539
+ /**
540
+ * The user-attachment records of one materialized submission, for the message
541
+ * metadata (`meta.transcript.attachments`): every image, file and
542
+ * pasted/attached text that lives in the store, by its content hash. The id IS
543
+ * the `attachmentRef`; the record repeats it under that key so the store's
544
+ * mark-and-sweep census (which scans persisted sessions for `"attachmentRef"`)
545
+ * keeps the blob for as long as the message exists, even after compaction
546
+ * dropped the content part. Plain long prompt text (no `textKind`) is not an
547
+ * attachment.
548
+ */
549
+ export function attachmentsForIntake(prompt, options = {}) {
550
+ const found = new Map();
551
+ const add = (ref, info) => {
552
+ if (!ATTACHMENT_REF_RE.test(String(ref || '')) || found.has(ref) || found.size >= MAX_MESSAGE_ATTACHMENTS) return;
553
+ found.set(ref, info);
554
+ };
555
+ const named = (raw, fallback) => String(raw?.filename || raw?.name || fallback).slice(0, 200);
556
+ const pastedImages = Object.values(options?.pastedImages || {}).filter((raw) => raw && typeof raw === 'object');
557
+ const pastedTexts = Object.values(options?.pastedTexts || {}).filter((raw) => raw && typeof raw === 'object');
558
+ const parts = Array.isArray(prompt) ? prompt : [];
559
+ for (const part of parts) {
560
+ if (!isAttachmentReference(part)) continue;
561
+ const mimeType = String(part.mimeType || part.mediaType || '').slice(0, 100);
562
+ if (part.type === 'image') {
563
+ const meta = pastedImages.find((raw) => raw.attachmentRef === part.attachmentRef);
564
+ add(part.attachmentRef, {
565
+ kind: 'image',
566
+ name: named(meta || part, 'image'),
567
+ mimeType: mimeType || String(meta?.mediaType || 'image/png'),
568
+ size: attachmentBlobSize(part, part.sizeBytes),
569
+ });
570
+ } else if (part.type === 'file') {
571
+ add(part.attachmentRef, {
572
+ kind: 'file',
573
+ name: named(part, 'attachment'),
574
+ mimeType: mimeType || 'application/octet-stream',
575
+ size: attachmentBlobSize(part, part.sizeBytes),
576
+ });
577
+ } else if (part.type === 'text' && (part.textKind === 'paste' || part.textKind === 'file')) {
578
+ add(part.attachmentRef, {
579
+ kind: 'text',
580
+ name: named(part, part.textKind === 'paste' ? 'pasted-text.txt' : 'attachment.txt'),
581
+ mimeType: mimeType || 'text/plain',
582
+ size: attachmentBlobSize(part, part.sizeBytes),
583
+ });
584
+ }
585
+ }
586
+ // Images the prompt carries only by side table (no matching content part).
587
+ for (const raw of pastedImages) {
588
+ if (!isAttachmentReference(raw)) continue;
589
+ add(raw.attachmentRef, {
590
+ kind: 'image',
591
+ name: named(raw, 'image'),
592
+ mimeType: String(raw.mediaType || 'image/png').slice(0, 100),
593
+ size: attachmentBlobSize(raw, raw.sizeBytes),
594
+ });
595
+ }
596
+ for (const raw of pastedTexts) {
597
+ if (!isAttachmentReference(raw)) continue;
598
+ add(raw.attachmentRef, {
599
+ kind: 'text',
600
+ name: named(raw, raw.source === 'file' ? 'attachment.txt' : 'pasted-text.txt'),
601
+ mimeType: String(raw.mimeType || 'text/plain').slice(0, 100),
602
+ size: attachmentBlobSize(raw, raw.sizeBytes),
603
+ });
604
+ }
605
+ return [...found].map(([ref, info]) => ({ id: ref, attachmentRef: ref, ...info }));
606
+ }
607
+
537
608
  /**
538
609
  * Whether a provider takes a PDF as a native document block. Decided by the
539
610
  * provider's wire protocol: each adapter class declares `nativePdf`; a provider
@@ -1,7 +1,6 @@
1
1
  export const BROWSER_ACTIONS: readonly string[];
2
2
  export const BROWSER_DEVTOOLS_ACTIONS: readonly string[];
3
3
  export const BROWSER_PAGE_ACTIONS: readonly string[];
4
- export const BROWSER_TOOL_NAMES: readonly string[];
5
4
  export function browserToolForAction(action: string): string;
6
5
  export const BROWSER_OBSERVATION_ACTIONS: readonly string[];
7
6
  export const BROWSER_POSTCONDITION_ACTIONS: readonly string[];
@@ -57,8 +57,6 @@ export const BROWSER_PAGE_ACTIONS = Object.freeze(
57
57
 
58
58
  const BROWSER_TOOL_NAME = 'browser';
59
59
  const BROWSER_DEVTOOLS_TOOL_NAME = 'browser_devtools';
60
- /** Both tools drive the same bridge, pages, and sign-in. */
61
- export const BROWSER_TOOL_NAMES = Object.freeze([BROWSER_TOOL_NAME, BROWSER_DEVTOOLS_TOOL_NAME]);
62
60
 
63
61
  export function browserToolForAction(action) {
64
62
  return BROWSER_DEVTOOLS_ACTIONS.includes(action) ? BROWSER_DEVTOOLS_TOOL_NAME : BROWSER_TOOL_NAME;