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
@@ -44,10 +44,12 @@ export function _publishLiveSession(session) {
44
44
 
45
45
  _setLiveSessionPublisher(_publishLiveSession);
46
46
 
47
- export function _runSessionPurgeHooks(id) {
47
+ /** `context` (optional, e.g. `{ cwds }`: working folders the session is known
48
+ * to have used) is passed to every hook as its second argument. */
49
+ export function _runSessionPurgeHooks(id, context) {
48
50
  for (const hook of _sessionPurgeHooks) {
49
51
  try {
50
- hook(id);
52
+ hook(id, context);
51
53
  } catch {
52
54
  /* a cleanup hook never breaks delete */
53
55
  }
@@ -0,0 +1,59 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { getPluginData } from '../../config.mjs';
4
+
5
+ // Session file paths are rebuilt on every load/save/sidecar probe. Memoize the
6
+ // joined strings per data dir: a changed data dir (MIXDOG_DATA_DIR switch)
7
+ // drops the whole memo, and the per-extension maps are bounded.
8
+ const SESSION_PATH_MEMO_LIMIT = 4096;
9
+ let _memoDataDir = null;
10
+ let _memoStoreDir = null;
11
+ const _memoFilePaths = new Map(); // extension → Map<id, path>
12
+
13
+ function _storeDirPath() {
14
+ const dataDir = getPluginData();
15
+ if (dataDir !== _memoDataDir) {
16
+ _memoDataDir = dataDir;
17
+ _memoStoreDir = join(dataDir, 'sessions');
18
+ _memoFilePaths.clear();
19
+ }
20
+ return _memoStoreDir;
21
+ }
22
+
23
+ function _memoFilePath(dir, id, extension) {
24
+ let byId = _memoFilePaths.get(extension);
25
+ if (!byId) {
26
+ byId = new Map();
27
+ _memoFilePaths.set(extension, byId);
28
+ }
29
+ let path = byId.get(id);
30
+ if (path === undefined) {
31
+ path = join(dir, _sessionFileName(id, extension));
32
+ if (byId.size >= SESSION_PATH_MEMO_LIMIT) byId.clear();
33
+ byId.set(id, path);
34
+ }
35
+ return path;
36
+ }
37
+ export function getStoreDir() {
38
+ const dir = _storeDirPath();
39
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
40
+ return dir;
41
+ }
42
+ function _sessionFileName(id, extension) {
43
+ return `${id}${extension}`;
44
+ }
45
+ // Enforce minted session-id shape before using it in a path to prevent
46
+ // `../` traversal. session IDs are generated by createSession as
47
+ // `sess_<timestamp>_<hex>` — reject anything that doesn't match.
48
+ function _assertSessionId(id) {
49
+ if (!id || typeof id !== 'string' || !/^[A-Za-z0-9_-]+$/.test(id)) {
50
+ throw new Error(`[session-store] invalid session id: ${JSON.stringify(id)}`);
51
+ }
52
+ }
53
+ function _sessionFilePath(id, extension) {
54
+ _assertSessionId(id);
55
+ return _memoFilePath(getStoreDir(), id, extension);
56
+ }
57
+ export function sessionPath(id) {
58
+ return _sessionFilePath(id, '.json');
59
+ }
@@ -1,7 +1,7 @@
1
1
  import { readdirSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { getPluginData } from '../../config.mjs';
4
- import { getStoreDir } from './paths-heartbeat.mjs';
4
+ import { getStoreDir } from './session-paths.mjs';
5
5
  import { probePath, PROBE_PRESENT, PROBE_ABSENT } from './fs-probe.mjs';
6
6
  import { STORED_SESSION_UNREADABLE, _storedSessionFromFile } from './serialize.mjs';
7
7
  import {
@@ -4,7 +4,7 @@
4
4
  // sidecars. The generator yields between records so cooperative hosts never
5
5
  // hold the event loop for a whole directory scan; the synchronous wrapper
6
6
  // drains it in one go.
7
- import { getStoreDir } from '../paths-heartbeat.mjs';
7
+ import { getStoreDir } from '../session-paths.mjs';
8
8
  import { probePath, PROBE_PRESENT } from '../fs-probe.mjs';
9
9
  import { persistSweepRecordCache, pruneSweepRecordCache } from './sweep-record.mjs';
10
10
  import { collectSweepRows, createSweepTally, resolveSweepPlan } from './sweep-plan.mjs';
@@ -1,12 +1,13 @@
1
1
  // sweep/sweep-finish.mjs
2
2
  // What runs after every row has its verdict: the resumable-open retention
3
- // cap, the orphan sidecar reap, and the one batched summary-index prune.
3
+ // cap, the legacy/orphan sidecar reap, and the one batched summary-index prune.
4
4
  import { readdirSync, unlinkSync } from 'node:fs';
5
5
  import { join } from 'node:path';
6
6
  import { probePath, PROBE_PRESENT, PROBE_ABSENT } from '../fs-probe.mjs';
7
7
  import { _queueSummaryIndexPrune } from '../summary-cache.mjs';
8
8
  import { deleteSession } from '../session-delete.mjs';
9
9
  import { COMPACTION_ARCHIVE_SUFFIX } from '../../compaction-archive.mjs';
10
+ import { LEGACY_MARKER_SUFFIXES, readLegacyMarker } from '../liveness-veto.mjs';
10
11
 
11
12
  /** Retention cap: prune resumable open (non-tombstone) sessions newest-first
12
13
  * — keep the most recent openMaxCount, prune anything older than openMaxAgeMs
@@ -32,8 +33,7 @@ export function pruneOpenCandidates({ plan, now, tally }) {
32
33
  deleteSession(c.id, {
33
34
  deferSummaryUpdate: true,
34
35
  isSessionLive: plan.isSessionLive,
35
- heartbeatSnapshotMtime: c.heartbeatSnapshotMtime,
36
- heartbeatFreshMs: c.heartbeatFreshMs,
36
+ legacyOwnerVeto: true,
37
37
  })
38
38
  ) {
39
39
  tally.openPruned++;
@@ -48,34 +48,40 @@ export function pruneOpenCandidates({ plan, now, tally }) {
48
48
  }
49
49
  }
50
50
 
51
- /** Orphan .hb/.own/compaction-archive reap: a sidecar whose .json no longer
51
+ /** Legacy `.hb` heartbeat and `.own` presence sidecars are written by no
52
+ * current build, but an older Mixdog process still running mid-upgrade keeps
53
+ * publishing them. One is reaped only once it holds nothing: its recorded
54
+ * owner pid is dead or it went stale; a fresh marker of a live (or
55
+ * unrecorded) owner is kept. Orphan compaction-archive reap: an archive whose .json no longer
52
56
  * exists is dead weight once it is also stale (older than maxAge) — the
53
- * session JSON was swept/closed but the sidecar lingered (crashed owner or
54
- * pre-fix orphan). The staleness gate avoids nuking the sidecar of a session
55
- * mid-create whose .json write has not landed yet. Yields between sidecars
56
- * like the row loop. */
57
+ * session JSON was swept/closed but the archive lingered. The staleness gate
58
+ * avoids nuking the archive of a session mid-create whose .json write has not
59
+ * landed yet. Yields between sidecars like the row loop. */
57
60
  export function* reapOrphanSidecars({ plan, dir, now, tally }) {
58
- const recordOf = (sidecar) =>
59
- sidecar.endsWith(COMPACTION_ARCHIVE_SUFFIX)
60
- ? `${sidecar.slice(0, -COMPACTION_ARCHIVE_SUFFIX.length)}.json`
61
- : sidecar.replace(/\.(hb|own)$/, '.json');
61
+ const recordOf = (sidecar) => `${sidecar.slice(0, -COMPACTION_ARCHIVE_SUFFIX.length)}.json`;
62
+ const unlinkSidecar = (h) => {
63
+ try {
64
+ unlinkSync(join(dir, h));
65
+ tally.cleaned++;
66
+ } catch {
67
+ /* ignore */
68
+ }
69
+ };
62
70
  try {
63
71
  for (const h of readdirSync(dir).filter(
64
72
  (f) => f.endsWith('.hb') || f.endsWith('.own') || f.endsWith(COMPACTION_ARCHIVE_SUFFIX)
65
73
  )) {
66
74
  yield undefined;
67
- // Only a PROVEN-absent session file makes its sidecar an orphan.
75
+ if (LEGACY_MARKER_SUFFIXES.some((suffix) => h.endsWith(suffix))) {
76
+ const marker = readLegacyMarker(join(dir, h), now);
77
+ if (marker && (marker.ownerDead || !marker.fresh)) unlinkSidecar(h);
78
+ continue;
79
+ }
80
+ // Only a PROVEN-absent session file makes its archive an orphan.
68
81
  if (probePath(join(dir, recordOf(h))).state !== PROBE_ABSENT) continue;
69
82
  const sidecarProbe = probePath(join(dir, h));
70
83
  if (sidecarProbe.state !== PROBE_PRESENT) continue;
71
- if (now - sidecarProbe.mtimeMs > plan.maxAge) {
72
- try {
73
- unlinkSync(join(dir, h));
74
- tally.cleaned++;
75
- } catch {
76
- /* ignore */
77
- }
78
- }
84
+ if (now - sidecarProbe.mtimeMs > plan.maxAge) unlinkSidecar(h);
79
85
  }
80
86
  } catch {
81
87
  /* dir scan failure — non-fatal */
@@ -2,7 +2,6 @@
2
2
  // One sweep's resolved options (what to sweep and with which bounds), the
3
3
  // candidate rows it visits, and the tally it fills in.
4
4
  import { readdirSync } from 'node:fs';
5
- import { loadConfig } from '../../../config.mjs';
6
5
  import { listStoredSessionSummaries } from '../listing.mjs';
7
6
  import { DEFAULT_SESSION_TTL_MS, RESUMABLE_OPEN_MAX_AGE_MS, RESUMABLE_OPEN_MAX_COUNT } from './sweep-record.mjs';
8
7
 
@@ -11,12 +10,6 @@ export function resolveSweepPlan(ttlMs, options = {}) {
11
10
  options = ttlMs;
12
11
  ttlMs = options.ttlMs;
13
12
  }
14
- let terminalReapConfig = null;
15
- try {
16
- terminalReapConfig = loadConfig({ secrets: false });
17
- } catch {
18
- /* built-ins remain available */
19
- }
20
13
  const sweepIdle = options.sweepIdle !== false;
21
14
  const tombstoneMaxAgeMs = Number(options.tombstoneMaxAgeMs);
22
15
  const optAge = Number(options.openMaxAgeMs);
@@ -24,7 +17,6 @@ export function resolveSweepPlan(ttlMs, options = {}) {
24
17
  return {
25
18
  maxAge: ttlMs || DEFAULT_SESSION_TTL_MS,
26
19
  sweepIdle,
27
- terminalReapConfig,
28
20
  tombstoneMaxAgeMs,
29
21
  sweepTombstones: Number.isFinite(tombstoneMaxAgeMs) && tombstoneMaxAgeMs > 0,
30
22
  // Retention cap for resumable open sessions runs only on the idle sweep
@@ -1,18 +1,14 @@
1
1
  // sweep/sweep-record.mjs
2
2
  // What the stale-session sweep reads per record and the bounds it decides
3
- // with: the fingerprint-cached lifecycle record, the linked-agent retention
4
- // rule, and the idle / retention / blank-scratch thresholds.
3
+ // with: the fingerprint-cached lifecycle record and the
4
+ // idle / retention / blank-scratch thresholds.
5
5
  import { readFileSync } from 'node:fs';
6
6
  import { join } from 'node:path';
7
7
  import { writeJsonAtomicSync } from '../../../../../shared/atomic-file.mjs';
8
8
  import { getPluginData } from '../../../config.mjs';
9
- import { isAgentOwner } from '../../../agent-owner.mjs';
10
9
  import { readTopLevelLifecycleRecord, isLifecycleUnreadable } from '../../lifecycle-scan.mjs';
11
- import { sessionPath } from '../paths-heartbeat.mjs';
12
- import { probePath, PROBE_ABSENT } from '../fs-probe.mjs';
13
10
 
14
11
  export const DEFAULT_SESSION_TTL_MS = 5 * 60 * 1000; // 5 minutes idle — aligned with Anthropic 5m messages tier and OpenAI in-memory cache window
15
- export const AGENT_TERMINAL_STATUSES = new Set(['idle', 'done', 'error']);
16
12
  // Hard wall-clock ceiling for sessions stuck in status='running'. The
17
13
  // stream-watchdog should abort stalled streams within ~120s, but if it misses
18
14
  // one (process crash, watchdog not started, provider never returned), this
@@ -52,7 +48,7 @@ export const BLANK_SCRATCH_MAX_AGE_MS = 60 * 60 * 1000; // 1h
52
48
  // running is still parsed again.
53
49
  const sweepRecordCache = new Map();
54
50
  const SWEEP_RECORD_CACHE_FILE = 'session-sweep-records.json';
55
- const SWEEP_RECORD_CACHE_VERSION = 1;
51
+ const SWEEP_RECORD_CACHE_VERSION = 2;
56
52
  let sweepRecordCacheDataDir = null;
57
53
  let sweepRecordCacheDirty = false;
58
54
  let sweepRecordParses = 0;
@@ -86,11 +82,13 @@ function syncSweepRecordCache() {
86
82
  }
87
83
 
88
84
  // The only document fields sweep-row reads (effectiveFields, the closed
89
- // check and retainedLinkedAgent). Caching the whole top-level document kept
85
+ // check). Caching the whole top-level document kept
90
86
  // every session's tool catalogs, schemas and provider state alive — one
91
87
  // entry per session file, measured at ~290MB of a 470MB daemon heap.
92
88
  const SWEEP_DOC_FIELDS = [
93
89
  'id',
90
+ 'closed',
91
+ 'closedReason',
94
92
  'owner',
95
93
  'status',
96
94
  'provider',
@@ -172,13 +170,3 @@ export function sweepRecordCacheStats() {
172
170
  syncSweepRecordCache();
173
171
  return { entries: sweepRecordCache.size, parses: sweepRecordParses };
174
172
  }
175
-
176
- /** Child-agent transcripts share their visible parent's retention boundary.
177
- * Presence (including a tombstone or unreadable file) preserves the child;
178
- * only proven parent absence releases it to ordinary cleanup. */
179
- export function retainedLinkedAgent(session) {
180
- if (!session || !isAgentOwner(session)) return false;
181
- const parentId = String(session.ownerSessionId || session.parentSessionId || '').trim();
182
- if (!/^[A-Za-z0-9_-]+$/.test(parentId) || parentId === session.id) return false;
183
- return probePath(sessionPath(parentId)).state !== PROBE_ABSENT;
184
- }
@@ -5,30 +5,14 @@
5
5
  // top-level id/closed/generation, foreign id) is left EXACTLY as it is — not
6
6
  // deleted, not closed, not repaired.
7
7
  import { readFileSync } from 'node:fs';
8
- import { join } from 'node:path';
9
- import { isAgentOwner } from '../../../agent-owner.mjs';
8
+ import { isHistoricalAutomaticClosure } from '../../historical-session-closure.mjs';
10
9
  import { readTopLevelLifecycleRecord, isLifecycleUnreadable } from '../../lifecycle-scan.mjs';
11
- import { resolveAgentTerminalReapMs } from '../../../runtime-core/config-helpers.mjs';
12
- import { sessionPath } from '../paths-heartbeat.mjs';
10
+ import { sessionPath } from '../session-paths.mjs';
13
11
  import { probePath, PROBE_PRESENT, PROBE_ABSENT } from '../fs-probe.mjs';
14
12
  import { _queueSessionSummaryUpsert, _queueSessionSummaryRemoval } from '../summary-cache.mjs';
15
13
  import { deleteSession } from '../session-delete.mjs';
16
14
  import { markSessionClosed } from '../lifecycle-barriers.mjs';
17
- import {
18
- AGENT_TERMINAL_STATUSES,
19
- BLANK_SCRATCH_MAX_AGE_MS,
20
- RUNNING_STALL_MS,
21
- readSweepRecord,
22
- retainedLinkedAgent,
23
- } from './sweep-record.mjs';
24
-
25
- /** The .hb sidecar mtime: 0 when proven absent, null when its liveness cannot
26
- * be judged (an unreadable sidecar makes the record no sweep candidate). */
27
- const heartbeatMtimeOf = (dir, id) => {
28
- const probe = probePath(join(dir, `${id}.hb`));
29
- if (probe.state === PROBE_PRESENT) return probe.mtimeMs || 0;
30
- return probe.state === PROBE_ABSENT ? 0 : null;
31
- };
15
+ import { BLANK_SCRATCH_MAX_AGE_MS, RUNNING_STALL_MS, readSweepRecord } from './sweep-record.mjs';
32
16
 
33
17
  /** The AUTHORITATIVE on-disk fields, falling back to the best-effort (and
34
18
  * possibly stale) summary row only where the record lacks them — a stale row
@@ -56,7 +40,7 @@ function sweepClosedRecord(ctx, row, actual, jsonPath) {
56
40
  return;
57
41
  }
58
42
  // Closed sessions are EXEMPT from the freshness gate: a tombstone whose
59
- // file/hb mtime keeps getting bumped would otherwise stay perpetually
43
+ // file mtime keeps getting bumped would otherwise stay perpetually
60
44
  // "fresh" and never mature. Maturity is governed ONLY by the ORIGINAL
61
45
  // close time (disk updatedAt, not row.updatedAt which a stale row may
62
46
  // carry from before the close).
@@ -64,7 +48,7 @@ function sweepClosedRecord(ctx, row, actual, jsonPath) {
64
48
  const age = now - closedAt;
65
49
  if (plan.sweepTombstones && Number.isFinite(closedAt) && age >= plan.tombstoneMaxAgeMs) {
66
50
  try {
67
- if (deleteSession(row.id, { deferSummaryUpdate: true })) {
51
+ if (deleteSession(row.id, { deferSummaryUpdate: true, legacyOwnerVeto: true })) {
68
52
  tally.tombstonesCleaned++;
69
53
  tally.tombstoneDetails.push({ id: row.id, ageSeconds: Math.floor(age / 1000) });
70
54
  return;
@@ -96,14 +80,15 @@ function sweepClosedRecord(ctx, row, actual, jsonPath) {
96
80
  * that permanence is a blank scratch: ZERO user/assistant conversation
97
81
  * (engine boot artifact, force-killed window, crashed host) has nothing to
98
82
  * preserve, and relaunch storms otherwise pile hundreds of "(blank)" rows
99
- * that no sweep may touch. Reap once cold; liveness/heartbeat vetoes inside
100
- * deleteSession still protect an in-flight boot. */
101
- function sweepUserOwnedRecord(ctx, row, record, eff, heartbeatMtime) {
83
+ * that no sweep may touch. Reap once cold; the liveness veto inside
84
+ * deleteSession still protects an in-flight boot, local or in a live older
85
+ * process. */
86
+ function sweepUserOwnedRecord(ctx, row, record, eff) {
102
87
  const { plan, now, tally } = ctx;
103
88
  const conversationCount = Number.isFinite(record.conversationCount)
104
89
  ? record.conversationCount
105
90
  : Number(row.messageCount) || 0;
106
- const lastActive = Math.max(eff.updatedAt, eff.lastHeartbeatAt, eff.createdAt, heartbeatMtime || 0);
91
+ const lastActive = Math.max(eff.updatedAt, eff.lastHeartbeatAt, eff.createdAt);
107
92
  if (
108
93
  plan.sweepIdle &&
109
94
  conversationCount === 0 &&
@@ -115,8 +100,7 @@ function sweepUserOwnedRecord(ctx, row, record, eff, heartbeatMtime) {
115
100
  deleteSession(row.id, {
116
101
  deferSummaryUpdate: true,
117
102
  isSessionLive: plan.isSessionLive,
118
- heartbeatSnapshotMtime: heartbeatMtime,
119
- heartbeatFreshMs: BLANK_SCRATCH_MAX_AGE_MS,
103
+ legacyOwnerVeto: true,
120
104
  })
121
105
  ) {
122
106
  tally.openPruned++;
@@ -130,32 +114,17 @@ function sweepUserOwnedRecord(ctx, row, record, eff, heartbeatMtime) {
130
114
  tally.remaining++;
131
115
  }
132
116
 
133
- /** Closes an idle session. Close is destructive and the earlier heartbeat
134
- * stat can race a different process publishing fresh liveness, so both the
135
- * local runtime ownership and the sidecar are re-checked at the commit edge. */
136
- function closeIdleRecord(ctx, row, eff, { lastActive, sessionMaxAge, heartbeatMtime }) {
137
- const { plan, dir, now, tally } = ctx;
117
+ /** Closes an idle session. Close is destructive, so the in-memory runtime
118
+ * ownership is re-checked at the commit edge. */
119
+ function closeIdleRecord(ctx, row, eff, { lastActive }) {
120
+ const { plan, now, tally } = ctx;
138
121
  if (plan.isSessionLive?.(row.id)) {
139
122
  tally.remaining++;
140
123
  return;
141
124
  }
142
- const preCloseHeartbeatMtime = heartbeatMtimeOf(dir, row.id);
143
- if (preCloseHeartbeatMtime === null) {
144
- // Unknown liveness at the destructive edge: do not close.
145
- tally.remaining++;
146
- return;
147
- }
148
- if (preCloseHeartbeatMtime > 0 && now - preCloseHeartbeatMtime <= sessionMaxAge) {
149
- tally.remaining++;
150
- return;
151
- }
152
125
  let closeResult = null;
153
126
  try {
154
- closeResult = markSessionClosed(row.id, 'idle-sweep', {
155
- isSessionLive: plan.isSessionLive,
156
- heartbeatSnapshotMtime: heartbeatMtime,
157
- heartbeatFreshMs: sessionMaxAge,
158
- });
127
+ closeResult = markSessionClosed(row.id, 'idle-sweep', { isSessionLive: plan.isSessionLive, legacyOwnerVeto: true });
159
128
  } catch (err) {
160
129
  process.stderr.write(`[session-store] idle-sweep close failed for ${row.id}: ${err?.message}\n`);
161
130
  return;
@@ -174,51 +143,29 @@ function closeIdleRecord(ctx, row, eff, { lastActive, sessionMaxAge, heartbeatMt
174
143
 
175
144
  /** An open record: the freshness gate, then user permanence, the running
176
145
  * backstop, the idle close, or a retention-cap candidacy. */
177
- function sweepOpenRecord(ctx, row, record, { jsonMtime, heartbeatMtime }) {
146
+ function sweepOpenRecord(ctx, row, record, { jsonMtime }) {
178
147
  const { plan, now, tally } = ctx;
179
148
  const eff = effectiveFields(record.doc, row);
180
- const ownerRef = { owner: eff.owner };
181
149
  const ownerNamed = typeof eff.owner === 'string' && eff.owner.length > 0;
182
- // Completed agents use their provider's Advanced terminal duration rather
183
- // than the general sweep cadence, so it is resolved before the freshness
184
- // gate: a short provider override must not be hidden behind the default
185
- // 5-minute gate.
186
- const isCompletedAgent = isAgentOwner(ownerRef) && AGENT_TERMINAL_STATUSES.has(eff.status);
187
- const terminalReapMs = isCompletedAgent ? resolveAgentTerminalReapMs(plan.terminalReapConfig, eff.provider) : null;
188
- if (isCompletedAgent && terminalReapMs == null) {
189
- tally.remaining++;
190
- return;
191
- }
192
150
  // Freshness gate — recently-touched open sessions are skipped cheaply here.
193
151
  let freshnessGateMs = 0;
194
- if (plan.sweepIdle) freshnessGateMs = terminalReapMs ?? plan.maxAge;
152
+ if (plan.sweepIdle) freshnessGateMs = plan.maxAge;
195
153
  else if (plan.sweepTombstones) freshnessGateMs = plan.tombstoneMaxAgeMs;
196
- const newestKnown = Math.max(
197
- row.updatedAt || 0,
198
- row.lastHeartbeatAt || 0,
199
- row.createdAt || 0,
200
- jsonMtime,
201
- heartbeatMtime
202
- );
154
+ const newestKnown = Math.max(row.updatedAt || 0, row.lastHeartbeatAt || 0, row.createdAt || 0, jsonMtime);
203
155
  if (freshnessGateMs > 0 && newestKnown > 0 && now - newestKnown <= freshnessGateMs) {
204
156
  // Fresh agent/legacy sessions survive idle close but still participate
205
157
  // in the resumable-open retention cap. The cap performs its own
206
158
  // commit-edge liveness veto before deletion.
207
- if (plan.retainOpen && plan.sweepIdle && (!ownerNamed || isAgentOwner(ownerRef))) {
208
- tally.openCandidates.push({
209
- id: row.id,
210
- lastActive: newestKnown,
211
- heartbeatSnapshotMtime: heartbeatMtime,
212
- heartbeatFreshMs: terminalReapMs ?? plan.maxAge,
213
- });
159
+ if (plan.retainOpen && plan.sweepIdle && !ownerNamed) {
160
+ tally.openCandidates.push({ id: row.id, lastActive: newestKnown });
214
161
  }
215
162
  tally.remaining++;
216
163
  return;
217
164
  }
218
- // Sweep agent-owned and ownerless (legacy) sessions; explicit user sessions
219
- // never feed the retention cap and are only ever reaped as blank scratch.
220
- if (ownerNamed && !isAgentOwner(ownerRef)) {
221
- sweepUserOwnedRecord(ctx, row, record, eff, heartbeatMtime);
165
+ // Every explicitly owned conversation has the same retention policy.
166
+ // Only ownerless legacy records enter idle closure and the retention cap.
167
+ if (ownerNamed) {
168
+ sweepUserOwnedRecord(ctx, row, record, eff);
222
169
  return;
223
170
  }
224
171
  if (!plan.sweepIdle) {
@@ -227,17 +174,13 @@ function sweepOpenRecord(ctx, row, record, { jsonMtime, heartbeatMtime }) {
227
174
  }
228
175
  // The manager may sweep while unrelated sessions are active. Protect this
229
176
  // specific locally-current/in-flight session regardless of stale on-disk
230
- // timestamps; its controller/heartbeat owner decides when it is safe to
231
- // become an idle-sweep candidate.
177
+ // timestamps; its in-memory runtime decides when it is safe to become an
178
+ // idle-sweep candidate.
232
179
  if (plan.isSessionLive?.(row.id)) {
233
180
  tally.remaining++;
234
181
  return;
235
182
  }
236
- // Prefer .hb sidecar mtime — updated at tight cadence (≤5s) without
237
- // serialising the full JSON, so it reflects true liveness more accurately
238
- // than the JSON timestamp fields.
239
- let lastActive = eff.lastHeartbeatAt || eff.updatedAt || eff.createdAt || 0;
240
- if (heartbeatMtime) lastActive = Math.max(lastActive, heartbeatMtime);
183
+ const lastActive = eff.lastHeartbeatAt || eff.updatedAt || eff.createdAt || 0;
241
184
  // Running sessions are normally reaped by the stream-watchdog within
242
185
  // ~120s. Skip them here unless they've been silent past RUNNING_STALL_MS,
243
186
  // at which point they are treated as zombies.
@@ -245,19 +188,11 @@ function sweepOpenRecord(ctx, row, record, { jsonMtime, heartbeatMtime }) {
245
188
  tally.remaining++;
246
189
  return;
247
190
  }
248
- const sessionMaxAge = terminalReapMs ?? plan.maxAge;
249
- if (now - lastActive > sessionMaxAge) {
250
- closeIdleRecord(ctx, row, eff, { lastActive, sessionMaxAge, heartbeatMtime });
191
+ if (now - lastActive > plan.maxAge) {
192
+ closeIdleRecord(ctx, row, eff, { lastActive });
251
193
  return;
252
194
  }
253
- if (plan.retainOpen) {
254
- tally.openCandidates.push({
255
- id: row.id,
256
- lastActive,
257
- heartbeatSnapshotMtime: heartbeatMtime,
258
- heartbeatFreshMs: sessionMaxAge,
259
- });
260
- }
195
+ if (plan.retainOpen) tally.openCandidates.push({ id: row.id, lastActive });
261
196
  tally.remaining++;
262
197
  }
263
198
 
@@ -277,11 +212,6 @@ export function sweepRow(ctx, row) {
277
212
  tally.remaining++;
278
213
  return;
279
214
  }
280
- const heartbeatMtime = heartbeatMtimeOf(ctx.dir, row.id);
281
- if (heartbeatMtime === null) {
282
- tally.remaining++;
283
- return;
284
- }
285
215
  // Truth source: the summary index is a deferred/best-effort sidecar, so a
286
216
  // row can still claim status='idle'/open while the session JSON was
287
217
  // already tombstoned. Read the real session JSON BEFORE the freshness gate
@@ -299,10 +229,7 @@ export function sweepRow(ctx, row) {
299
229
  // One strict parse for the whole record: every decision below reads the
300
230
  // SAME authoritative document (owner/status/timestamps/messages).
301
231
  const actual = record.doc;
302
- if (retainedLinkedAgent(actual)) {
303
- // Parent-owned agent transcripts are task history, not ephemeral worker
304
- // cache. This covers both new open sessions and tombstones created by
305
- // older Mixdog versions.
232
+ if (isHistoricalAutomaticClosure(actual)) {
306
233
  tally.remaining++;
307
234
  return;
308
235
  }
@@ -310,5 +237,5 @@ export function sweepRow(ctx, row) {
310
237
  sweepClosedRecord(ctx, row, actual, jsonPath);
311
238
  return;
312
239
  }
313
- sweepOpenRecord(ctx, row, record, { jsonMtime: jsonProbe.mtimeMs || 0, heartbeatMtime });
240
+ sweepOpenRecord(ctx, row, record, { jsonMtime: jsonProbe.mtimeMs || 0 });
314
241
  }
@@ -5,7 +5,7 @@
5
5
  * that decide whether bytes may be committed — no queueing, no commit, no
6
6
  * markers — which is why they stay out of the write pipeline itself.
7
7
  */
8
- import { sessionPath } from './paths-heartbeat.mjs';
8
+ import { sessionPath } from './session-paths.mjs';
9
9
  import {
10
10
  readCanonicalSessionRecord as _readCanonicalRecord,
11
11
  CANONICAL_RECORD_UNREADABLE as LIFECYCLE_AMBIGUOUS,
@@ -14,6 +14,7 @@ import {
14
14
  } from './canonical-reader.mjs';
15
15
  import { isCancelledWrite as _isCancelledWrite } from './write-guards.mjs';
16
16
  import { _setSessionWriteAuthorityCheck } from './save-worker.mjs';
17
+ import { isSessionWriteFenced } from './live-state.mjs';
17
18
 
18
19
  const _observeStamp = (target) => {
19
20
  try {
@@ -71,7 +72,7 @@ function _writeAuthorityRecord(target, attempt) {
71
72
  * under their own authority read).
72
73
  */
73
74
  export function _shouldDrop(id, opts, attempt = null) {
74
- if (_isCancelledWrite(opts)) return true;
75
+ if (_isCancelledWrite(opts) || isSessionWriteFenced(id)) return true;
75
76
  const expected = typeof opts?.expectedGeneration === 'number' ? opts.expectedGeneration : null;
76
77
  const target = sessionPath(id);
77
78
  let record;
@@ -126,6 +127,7 @@ export function _shouldDrop(id, opts, attempt = null) {
126
127
  // under the lock by _shouldDrop.
127
128
  export function _sessionWriteAuthorityRefusal(id, attempt = null) {
128
129
  if (!id) return null;
130
+ if (isSessionWriteFenced(id)) return 'deleted';
129
131
  let authority;
130
132
  try {
131
133
  // A synchronous save passes its `attempt`: its pre-admission is then the
@@ -5,30 +5,27 @@
5
5
  */
6
6
  export function listStoredAgentWorkers({
7
7
  now,
8
- heartbeatMtimes,
8
+ runningSessionIds,
9
9
  storedAgentWorkerIndexRows,
10
10
  projectChildWorkerRow,
11
- promoteHeartbeatSidecar,
12
11
  storedLeadWorkerRows,
13
12
  projectLeadWorkerRow,
14
13
  pruneOrphanChildRows,
15
14
  }) {
15
+ const context = { now, runningSessionIds };
16
16
  const bySessionId = new Map();
17
17
  for (const row of storedAgentWorkerIndexRows()) {
18
- const projected = projectChildWorkerRow(row, { now, heartbeatMtimes });
18
+ const projected = projectChildWorkerRow(row, context);
19
19
  if (projected) bySessionId.set(projected.sessionId, projected);
20
20
  }
21
- for (const [sessionId, heartbeatAt] of heartbeatMtimes) {
22
- promoteHeartbeatSidecar(bySessionId, sessionId, heartbeatAt);
23
- }
24
21
  const liveLeadSessionIds = new Set();
25
22
  for (const row of storedLeadWorkerRows()) {
26
- const projected = projectLeadWorkerRow(row, { now, heartbeatMtimes });
23
+ const projected = projectLeadWorkerRow(row, context);
27
24
  if (!projected) continue;
28
25
  liveLeadSessionIds.add(projected.sessionId);
29
26
  bySessionId.set(projected.sessionId, projected);
30
27
  }
31
- pruneOrphanChildRows(bySessionId, { liveLeadSessionIds, heartbeatMtimes, now });
28
+ pruneOrphanChildRows(bySessionId, { liveLeadSessionIds });
32
29
  return [...bySessionId.values()].sort((left, right) => {
33
30
  const leftTime = Date.parse(String(left.startedAt || '')) || 0;
34
31
  const rightTime = Date.parse(String(right.startedAt || '')) || 0;