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
@@ -0,0 +1,599 @@
1
+ // Live ping-pong across providers.
2
+ // Basic suite (default): three turns - a forced read, a no-tool replay of that history,
3
+ // and two parallel reads.
4
+ // Extended suite (`--suite extended`): after those, tool error, file write, shell, a
5
+ // 3-step tool chain, image input, mid-stream cancel + follow-up. Per-turn usage is
6
+ // captured to report prompt-cache reads on turns 2+.
7
+ //
8
+ // Isolation (default): the runs use a fresh temp MIXDOG_HOME/MIXDOG_DATA_DIR, never the
9
+ // installed app's ~/.mixdog data, so no session, catalog or worker rows reach the real
10
+ // stores. Only the API-key secrets (`secrets/agent.<provider>.apiKey.dpapi`) and the
11
+ // `agent` section of mixdog-config.json are copied in. OAuth providers (`*-oauth`, whose
12
+ // refresh tokens could be rotated) are skipped unless `--real-data` is passed, which
13
+ // restores the old behaviour of running against the real data dir. The isolated dir is
14
+ // deleted at the end, after stopping only processes whose executable lives inside it.
15
+ // Usage: node scripts/provider-pingpong-live.mjs [--suite extended] [--real-data] [case-name ...]
16
+ import fs from 'node:fs';
17
+ import os from 'node:os';
18
+ import path from 'node:path';
19
+ import zlib from 'node:zlib';
20
+ import { fileURLToPath } from 'node:url';
21
+ import { spawn, spawnSync } from 'node:child_process';
22
+
23
+ const self = fileURLToPath(import.meta.url);
24
+ const TURN_TIMEOUT_MS = 150_000;
25
+
26
+ const textOf = (response) => {
27
+ const content = response?.result?.content ?? response?.text ?? '';
28
+ if (Array.isArray(content)) return content.map((p) => (typeof p === 'string' ? p : p?.text || '')).join('');
29
+ return String(content);
30
+ };
31
+
32
+ // Solid-colour PNG (8-bit RGB) built from scratch so no image dependency is needed.
33
+ function solidPng(width, height, [r, g, b]) {
34
+ const crcTable = Array.from({ length: 256 }, (_, n) => {
35
+ let c = n;
36
+ for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
37
+ return c >>> 0;
38
+ });
39
+ const crc32 = (buf) => {
40
+ let c = 0xffffffff;
41
+ for (const byte of buf) c = crcTable[(c ^ byte) & 0xff] ^ (c >>> 8);
42
+ return (c ^ 0xffffffff) >>> 0;
43
+ };
44
+ const chunk = (type, data) => {
45
+ const body = Buffer.concat([Buffer.from(type, 'ascii'), data]);
46
+ const out = Buffer.alloc(body.length + 8);
47
+ out.writeUInt32BE(data.length, 0);
48
+ body.copy(out, 4);
49
+ out.writeUInt32BE(crc32(body), body.length + 4);
50
+ return out;
51
+ };
52
+ const ihdr = Buffer.alloc(13);
53
+ ihdr.writeUInt32BE(width, 0);
54
+ ihdr.writeUInt32BE(height, 4);
55
+ ihdr[8] = 8; // bit depth
56
+ ihdr[9] = 2; // RGB
57
+ const row = Buffer.concat([Buffer.from([0]), Buffer.from(Array.from({ length: width }, () => [r, g, b]).flat())]);
58
+ const raw = Buffer.concat(Array.from({ length: height }, () => row));
59
+ return Buffer.concat([
60
+ Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
61
+ chunk('IHDR', ihdr),
62
+ chunk('IDAT', zlib.deflateSync(raw)),
63
+ chunk('IEND', Buffer.alloc(0)),
64
+ ]);
65
+ }
66
+
67
+ const withTimeout = (promise, ms, onTimeout) =>
68
+ new Promise((resolve, reject) => {
69
+ const timer = setTimeout(() => {
70
+ onTimeout?.();
71
+ reject(new Error(`timeout after ${ms}ms`));
72
+ }, ms);
73
+ promise.then(
74
+ (v) => {
75
+ clearTimeout(timer);
76
+ resolve(v);
77
+ },
78
+ (e) => {
79
+ clearTimeout(timer);
80
+ reject(e);
81
+ }
82
+ );
83
+ });
84
+
85
+ // Failures caused by the account (limits, billing, entitlement) rather than the provider code.
86
+ const ACCOUNT_RE =
87
+ /quota|billing|\b(?:402|403|429)\b|rate.?limit|usage limit|insufficient|payment|credit|too many requests|exhaust|subscription|plan limit|not entitled|resource_exhausted/i;
88
+
89
+ if (process.argv[2] === '--child') {
90
+ const spec = JSON.parse(process.argv[3]);
91
+ const extended = spec.suite === 'extended';
92
+ const { resolvePluginData } = await import('../src/runtime/shared/plugin-paths.mjs');
93
+ if (spec.dataDir && path.resolve(resolvePluginData()) !== path.resolve(spec.dataDir)) {
94
+ console.log(
95
+ `RESULT ${JSON.stringify({ name: spec.name, error: `refusing to run: data dir ${resolvePluginData()} is not the isolated ${spec.dataDir}` })}`
96
+ );
97
+ process.exit(0);
98
+ }
99
+ const { createMixdogSessionRuntime } = await import('../src/session-runtime/runtime-core.mjs');
100
+ const { materializePromptSubmission } = await import('../src/runtime/attachments/store.mjs');
101
+ const { getModelMetadataSync } = await import('../src/runtime/shared/llm/model-catalog.mjs');
102
+ let runtime;
103
+ const out = {
104
+ name: spec.name,
105
+ provider: spec.provider,
106
+ model: spec.model,
107
+ effort: spec.effort,
108
+ turns: {},
109
+ order: [],
110
+ };
111
+ const readDisk = (file) => {
112
+ try {
113
+ return fs.readFileSync(path.join(spec.cwd, file), 'utf8');
114
+ } catch {
115
+ return null;
116
+ }
117
+ };
118
+
119
+ // Runs one ask() and records calls/text/usage under `key`. Errors are recorded, not thrown,
120
+ // so later scenarios still run; an ACCOUNT error stops the case (everything after would fail alike).
121
+ const turn = async (key, prompt, options = {}) => {
122
+ const rec = {
123
+ calls: [],
124
+ text: '',
125
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
126
+ models: [],
127
+ };
128
+ out.turns[key] = rec;
129
+ out.order.push(key);
130
+ const startedAt = Date.now();
131
+ try {
132
+ const response = await withTimeout(
133
+ runtime.ask(prompt, {
134
+ ...options,
135
+ onAssistantToolCallObserved: (call) => rec.calls.push(call.name || call.tool),
136
+ onUsageDelta: (d) => {
137
+ rec.usage.events++;
138
+ rec.usage.input += d.deltaInput || 0;
139
+ rec.usage.output += d.deltaOutput || 0;
140
+ rec.usage.cacheRead += d.deltaCachedRead || 0;
141
+ rec.usage.cacheWrite += d.deltaCacheWrite || 0;
142
+ if (d.model && !rec.models.includes(d.model)) rec.models.push(d.model);
143
+ },
144
+ }),
145
+ TURN_TIMEOUT_MS,
146
+ () => runtime.abort('pingpong-timeout')
147
+ );
148
+ rec.text = textOf(response).trim().slice(0, 300);
149
+ } catch (error) {
150
+ rec.error = String(error?.message || error).slice(0, 400);
151
+ if (ACCOUNT_RE.test(rec.error)) out.stopped = 'account';
152
+ }
153
+ rec.ms = Date.now() - startedAt;
154
+ return rec;
155
+ };
156
+
157
+ try {
158
+ runtime = await createMixdogSessionRuntime({
159
+ provider: spec.provider,
160
+ model: spec.model,
161
+ ...(spec.effort ? { effort: spec.effort } : {}),
162
+ cwd: spec.cwd,
163
+ toolMode: 'full',
164
+ autoWakeCompletions: false,
165
+ });
166
+ const steps = [
167
+ ['t1', 'Use the read tool on package.json, then reply with only the value of "name".'],
168
+ ['t2', 'Without using tools, reply with only that same name in uppercase.'],
169
+ [
170
+ 't3',
171
+ 'Read a.txt and b.txt with two read calls issued together in one step, then reply with only their two contents joined by "+".',
172
+ ],
173
+ ];
174
+ for (const [key, prompt] of steps) {
175
+ await turn(key, prompt);
176
+ if (out.stopped) break;
177
+ }
178
+
179
+ if (extended && !out.stopped) {
180
+ await turn(
181
+ 'er',
182
+ 'Use the read tool on does-not-exist.txt. Whatever happens, then tell me in one short sentence whether that file exists.'
183
+ );
184
+ }
185
+ if (extended && !out.stopped) {
186
+ const rec = await turn(
187
+ 'wr',
188
+ 'Using the file edit/write tool (not the shell), create a new file c.txt in the working directory containing exactly the text gamma. Reply "done" when finished.'
189
+ );
190
+ rec.disk = readDisk('c.txt');
191
+ }
192
+ if (extended && !out.stopped) {
193
+ await turn('sh', 'Use the shell tool to run exactly: node -e "console.log(6*7)" and reply with only its output.');
194
+ }
195
+ if (extended && !out.stopped) {
196
+ const rec = await turn(
197
+ 'ml',
198
+ 'Do these in order, each as its own tool call, one after another: (1) read a.txt, (2) create a new file d.txt using the file edit/write tool containing the contents of a.txt with its characters reversed and no trailing newline, (3) read d.txt. Then reply with only the text in d.txt.'
199
+ );
200
+ rec.disk = readDisk('d.txt');
201
+ }
202
+ if (extended && !out.stopped) {
203
+ const vision = getModelMetadataSync(spec.model, spec.provider)?.supportsVision;
204
+ if (vision === false) {
205
+ out.turns.im = { skipped: 'catalog says no vision', calls: [], text: '' };
206
+ out.order.push('im');
207
+ } else {
208
+ const png = solidPng(64, 64, [255, 0, 0]).toString('base64');
209
+ // Same intake the session service applies before runtime.ask: inline image
210
+ // parts become content-addressed attachment references.
211
+ const intake = materializePromptSubmission([
212
+ { type: 'text', text: 'What single colour fills this image? Reply with only the colour name in English.' },
213
+ { type: 'image', data: png, mimeType: 'image/png' },
214
+ ]);
215
+ const rec = await turn('im', intake.prompt, intake.options);
216
+ rec.visionFlag = vision === undefined ? 'unknown' : 'true';
217
+ }
218
+ }
219
+ if (extended && !out.stopped) {
220
+ // Real cancel path: runtime.abort() -> abortRuntime -> turn controller + mgr.abortSessionTurn.
221
+ const rec = {
222
+ calls: [],
223
+ text: '',
224
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
225
+ models: [],
226
+ };
227
+ out.turns.ca = rec;
228
+ out.order.push('ca');
229
+ let deltas = 0;
230
+ let abortResult;
231
+ let aborted = false;
232
+ const doAbort = () => {
233
+ if (aborted) return;
234
+ aborted = true;
235
+ abortResult = runtime.abort('user-cancel');
236
+ };
237
+ const fallback = setTimeout(doAbort, 30_000);
238
+ const onDelta = () => {
239
+ if (++deltas >= 5) doAbort();
240
+ };
241
+ const startedAt = Date.now();
242
+ const pending = runtime
243
+ .ask(
244
+ 'Write a very long numbered list from 1 to 300, one item per line, each item a full sentence about a different animal. Do not use tools.',
245
+ {
246
+ onTextDelta: onDelta,
247
+ onUsageDelta: (d) => {
248
+ rec.usage.events++;
249
+ rec.usage.input += d.deltaInput || 0;
250
+ rec.usage.output += d.deltaOutput || 0;
251
+ rec.usage.cacheRead += d.deltaCachedRead || 0;
252
+ rec.usage.cacheWrite += d.deltaCacheWrite || 0;
253
+ },
254
+ }
255
+ )
256
+ .then(
257
+ (r) => ({ ok: true, text: textOf(r).trim() }),
258
+ (e) => ({ ok: false, error: String(e?.message || e) })
259
+ );
260
+ const settled = await Promise.race([pending, new Promise((r) => setTimeout(() => r({ hang: true }), 120_000))]);
261
+ clearTimeout(fallback);
262
+ rec.ms = Date.now() - startedAt;
263
+ rec.deltas = deltas;
264
+ rec.abortResult = abortResult;
265
+ rec.abortedAfterMs = rec.ms;
266
+ if (settled.hang) rec.settle = 'hang';
267
+ else rec.settle = settled.ok ? 'resolved' : 'rejected';
268
+ rec.text = String(settled.text || '').slice(0, 120);
269
+ rec.error = settled.error ? settled.error.slice(0, 300) : undefined;
270
+ rec.chars = String(settled.text || '').length;
271
+ if (settled.hang) out.stopped = 'hang';
272
+ else if (rec.error && ACCOUNT_RE.test(rec.error) && !aborted) out.stopped = 'account';
273
+ if (!out.stopped) await turn('fu', 'Reply with only the word READY.');
274
+ }
275
+ } catch (error) {
276
+ out.error = String(error?.message || error).slice(0, 400);
277
+ } finally {
278
+ await runtime?.close('provider-pingpong-live').catch(() => {});
279
+ }
280
+ console.log(`RESULT ${JSON.stringify(out)}`);
281
+ process.exit(0);
282
+ }
283
+
284
+ // [name, provider, model, effort]; each route runs at a low and a high reasoning setting.
285
+ const routes = [
286
+ ['openrouter-claude', 'openrouter', 'anthropic/claude-haiku-5.5', ['low', 'max']],
287
+ ['openrouter-gpt', 'openrouter', 'openai/gpt-6-luna', ['none', 'xhigh']],
288
+ ['openrouter-gemini', 'openrouter', 'google/gemini-3.5-flash-lite', ['minimal', 'high']],
289
+ ['openrouter-deepseek', 'openrouter', 'deepseek/deepseek-v4.1-flash', ['low', 'max']],
290
+ ['deepseek', 'deepseek', 'deepseek-flash', ['low', 'max']],
291
+ ['deepseek-pro', 'deepseek', 'deepseek-v4-pro', ['high']],
292
+ ['opencode-go-gemini', 'opencode-go', 'gemini-4-argon-contributor', ['low', 'high']],
293
+ ['opencode-go-deepseek', 'opencode-go', 'deepseek-v4.1-flash', ['low', 'max']],
294
+ ['opencode-go-claude', 'opencode-go', 'claude-haiku-5-5', ['low', 'max']],
295
+ ['opencode-go-gpt', 'opencode-go', 'gpt-6-luna', ['none', 'xhigh']],
296
+ ['opencode-go-glm', 'opencode-go', 'glm-5.3-flash', ['low', 'max']],
297
+ ['opencode-go-qwen', 'opencode-go', 'qwen3.8-flash', ['low', 'xhigh']],
298
+ ['opencode-go-kimi', 'opencode-go', 'kimi-k3', ['max']],
299
+ ['opencode-go-minimax', 'opencode-go', 'minimax-m3', [null]],
300
+ ['opencode-go-grok', 'opencode-go', 'grok-4.7', ['low']],
301
+ ['anthropic-api', 'anthropic', 'claude-haiku-5-5', ['low', 'max']],
302
+ ['gemini-api', 'gemini', 'gemini-3.5-flash-lite', ['minimal', 'high']],
303
+ ['grok-oauth', 'grok-oauth', 'grok-4.7', ['low', 'xhigh']],
304
+ ['openai-oauth', 'openai-oauth', 'gpt-6-luna', ['none', 'xhigh']],
305
+ ['anthropic-oauth', 'anthropic-oauth', 'claude-haiku-5-5', ['low', 'max']],
306
+ ['antigravity-oauth', 'antigravity-oauth', 'gemini-3.8-flash', ['low', 'high']],
307
+ ['cursor-auto', 'cursor-oauth', 'auto', [null]],
308
+ ['cursor-composer', 'cursor-oauth', 'composer-2.5', [null]],
309
+ ['cursor-claude', 'cursor-oauth', 'claude-opus-5-5', [null]],
310
+ ['cursor-grok', 'cursor-oauth', 'grok-4.7', [null]],
311
+ ];
312
+ const cases = routes.flatMap(([name, provider, model, efforts]) =>
313
+ efforts.map((effort) => [`${name}${effort ? `@${effort}` : ''}`, provider, model, effort])
314
+ );
315
+ const args = process.argv.slice(2);
316
+ const suiteAt = args.findIndex((a) => a === '--suite' || a.startsWith('--suite='));
317
+ let suite = 'basic';
318
+ if (suiteAt >= 0) suite = args[suiteAt].includes('=') ? args[suiteAt].split('=')[1] : args[suiteAt + 1];
319
+ const extended = suite === 'extended';
320
+ const realData = args.includes('--real-data');
321
+ const only = args.filter(
322
+ (a, i) =>
323
+ a !== '--real-data' &&
324
+ !a.startsWith('--suite') &&
325
+ !(suiteAt >= 0 && i === suiteAt + 1 && args[suiteAt] === '--suite')
326
+ );
327
+ const chosen = only.length ? cases.filter(([name]) => only.includes(name)) : cases;
328
+ // Refresh-capable OAuth logins are never exercised from an isolated copy.
329
+ const isOauth = ([, provider]) => /-oauth$/.test(provider);
330
+ const selected = realData ? chosen : chosen.filter((c) => !isOauth(c));
331
+ for (const c of chosen)
332
+ if (!selected.includes(c))
333
+ console.log(`SKIP ${c[0]} (OAuth provider; pass --real-data to run against the real data dir)`);
334
+ if (!selected.length) {
335
+ console.log('nothing to run');
336
+ process.exit(0);
337
+ }
338
+
339
+ // Isolated MIXDOG_HOME for the child runtimes: a fresh temp dir holding only the API-key
340
+ // secrets of the selected providers and the `agent` section of the real config.
341
+ let isolated = null;
342
+ if (!realData) {
343
+ const realDataDir =
344
+ process.env.MIXDOG_DATA_DIR || path.join(process.env.MIXDOG_HOME || path.join(os.homedir(), '.mixdog'), 'data');
345
+ const home = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-pp-home-'));
346
+ const dataDir = path.join(home, 'data');
347
+ fs.mkdirSync(path.join(dataDir, 'secrets'), { recursive: true });
348
+ const config = JSON.parse(fs.readFileSync(path.join(realDataDir, 'mixdog-config.json'), 'utf8'));
349
+ fs.writeFileSync(path.join(dataDir, 'mixdog-config.json'), JSON.stringify({ agent: config.agent ?? {} }, null, 2));
350
+ for (const provider of new Set(selected.map(([, p]) => p))) {
351
+ const secret = `agent.${provider}.apiKey.dpapi`;
352
+ const from = path.join(realDataDir, 'secrets', secret);
353
+ if (fs.existsSync(from)) fs.copyFileSync(from, path.join(dataDir, 'secrets', secret));
354
+ else console.log(`WARN no ${secret} in the real data dir; ${provider} cases will fail to authenticate`);
355
+ }
356
+ isolated = {
357
+ home,
358
+ dataDir,
359
+ env: { MIXDOG_HOME: home, MIXDOG_DATA_DIR: dataDir, MIXDOG_RUNTIME_ROOT: path.join(home, 'runtime-root') },
360
+ };
361
+ }
362
+
363
+ // Stops only processes whose executable path is inside `root` (e.g. the isolated memory
364
+ // postgres), then removes the dir. Windows-only lookup, like the DPAPI secrets.
365
+ const removeIsolated = () => {
366
+ if (!isolated) return;
367
+ const { home } = isolated;
368
+ isolated = null;
369
+ if (process.platform === 'win32') {
370
+ const root = home.replace(/'/g, "''");
371
+ spawnSync(
372
+ 'powershell.exe',
373
+ [
374
+ '-NoProfile',
375
+ '-Command',
376
+ `$root='${root}\\'; Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -and $_.ExecutablePath.StartsWith($root, [StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`,
377
+ ],
378
+ { stdio: 'ignore' }
379
+ );
380
+ }
381
+ fs.rmSync(home, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });
382
+ };
383
+
384
+ // One fixture dir per case: concurrent children write c.txt/d.txt and must not collide.
385
+ const tempDirs = new Set();
386
+ const removeTemp = () => {
387
+ for (const dir of tempDirs) fs.rmSync(dir, { recursive: true, force: true });
388
+ tempDirs.clear();
389
+ removeIsolated();
390
+ };
391
+ process.on('exit', removeTemp);
392
+ const makeCwd = (name) => {
393
+ const cwd = fs.mkdtempSync(path.join(os.tmpdir(), `mixdog-pingpong-${name.replace(/[^a-z0-9]+/gi, '-')}-`));
394
+ tempDirs.add(cwd);
395
+ fs.writeFileSync(
396
+ path.join(cwd, 'package.json'),
397
+ JSON.stringify({ name: 'pingpong-probe', version: '1.0.0' }, null, 2)
398
+ );
399
+ fs.writeFileSync(path.join(cwd, 'a.txt'), 'alpha\n');
400
+ fs.writeFileSync(path.join(cwd, 'b.txt'), 'beta\n');
401
+ return cwd;
402
+ };
403
+
404
+ const runOne = ([name, provider, model, effort]) =>
405
+ new Promise((resolve) => {
406
+ const cwd = makeCwd(name);
407
+ const child = spawn(
408
+ process.execPath,
409
+ [
410
+ self,
411
+ '--child',
412
+ JSON.stringify({
413
+ name,
414
+ provider,
415
+ model,
416
+ effort,
417
+ cwd,
418
+ dataDir: isolated?.dataDir,
419
+ suite: extended ? 'extended' : 'basic',
420
+ }),
421
+ ],
422
+ { stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, ...isolated?.env } }
423
+ );
424
+ let stdout = '';
425
+ let stderr = '';
426
+ child.stdout.on('data', (d) => (stdout += d));
427
+ child.stderr.on('data', (d) => (stderr += d));
428
+ const timer = setTimeout(() => child.kill(), extended ? 900_000 : 240_000);
429
+ child.on('close', () => {
430
+ clearTimeout(timer);
431
+ fs.rmSync(cwd, { recursive: true, force: true });
432
+ tempDirs.delete(cwd);
433
+ const line = stdout.split('\n').find((l) => l.startsWith('RESULT '));
434
+ resolve(
435
+ line ? JSON.parse(line.slice(7)) : { name, provider, model, effort, error: `no result: ${stderr.slice(-300)}` }
436
+ );
437
+ });
438
+ });
439
+
440
+ // Bounded concurrency keeps per-provider rate limits from masking real failures.
441
+ const results = [];
442
+ const queue = [...selected];
443
+ await Promise.all(
444
+ Array.from({ length: 8 }, async () => {
445
+ while (queue.length) results.push(await runOne(queue.shift()));
446
+ })
447
+ );
448
+ results.sort((a, b) => a.name.localeCompare(b.name));
449
+
450
+ const has = (t, re) => re.test(t?.text || '');
451
+ const called = (t, name) => (t?.calls || []).includes(name);
452
+ const wroteVia = (t) => (t?.calls || []).some((c) => /edit|write|patch/i.test(c));
453
+ // [key, label, check(turn, result)] ; check returns true/false.
454
+ const scenarios = [
455
+ ['t1', 't1', (t) => called(t, 'read') && has(t, /pingpong-probe/i)],
456
+ ['t2', 't2', (t) => has(t, /PINGPONG-PROBE/)],
457
+ ['t3', 't3', (t) => (t.calls || []).filter((c) => c === 'read').length >= 1 && has(t, /alpha/i) && has(t, /beta/i)],
458
+ // The reply language follows the user's profile (may be Korean), so the wording check is bilingual.
459
+ [
460
+ 'er',
461
+ 'err',
462
+ (t) =>
463
+ called(t, 'read') &&
464
+ has(
465
+ t,
466
+ /missing|not exist|doesn.?t exist|does not|no such|not found|nonexistent|isn.?t|cannot|can.?t|존재하지|없|찾을 수|않/i
467
+ ),
468
+ ],
469
+ ['wr', 'wr', (t) => wroteVia(t) && String(t.disk ?? '').trim() === 'gamma'],
470
+ ['sh', 'sh', (t) => called(t, 'shell') && has(t, /42/)],
471
+ [
472
+ 'ml',
473
+ 'ml',
474
+ (t) => {
475
+ const c = t.calls || [];
476
+ const firstRead = c.indexOf('read');
477
+ const write = c.findIndex((n, i) => i > firstRead && /edit|write|patch/i.test(n));
478
+ const lastRead = c.lastIndexOf('read');
479
+ return (
480
+ firstRead >= 0 &&
481
+ write > firstRead &&
482
+ lastRead > write &&
483
+ String(t.disk ?? '').trim() === 'ahpla' &&
484
+ has(t, /ahpla/)
485
+ );
486
+ },
487
+ ],
488
+ ['im', 'img', (t) => has(t, /red/i)],
489
+ ['ca', 'can', (t) => t.settle && t.settle !== 'hang' && t.abortResult === true],
490
+ ['fu', 'fu', (t) => has(t, /READY/i)],
491
+ ];
492
+
493
+ const short = (s, n = 60) =>
494
+ String(s || '')
495
+ .replace(/\s+/g, ' ')
496
+ .slice(0, n);
497
+ const evidence = (key, t) => {
498
+ if (!t) return 'no turn';
499
+ if (t.error && key !== 'ca') return `error: ${short(t.error, 90)}`;
500
+ const base = `[${(t.calls || []).join(',')}] "${short(t.text)}"`;
501
+ if (key === 'wr' || key === 'ml') return `${base} disk=${JSON.stringify(short(t.disk ?? null, 20))}`;
502
+ if (key === 'ca')
503
+ return `abort=${t.abortResult} settle=${t.settle} deltas=${t.deltas} chars=${t.chars} ${t.error ? `err="${short(t.error, 70)}"` : ''}`;
504
+ return base;
505
+ };
506
+
507
+ const details = [];
508
+ for (const r of results) {
509
+ const marks = [];
510
+ const evid = [];
511
+ let anyFail = false;
512
+ let anyAccount = false;
513
+ for (const [key, label, check] of scenarios) {
514
+ if (!extended && !['t1', 't2', 't3'].includes(key)) continue;
515
+ const t = r.turns?.[key];
516
+ // A cancelled turn is expected to reject, so only 'ca' tolerates an error.
517
+ const ok = t && (key === 'ca' || !t.error) && check(t, r);
518
+ const accountish = t
519
+ ? ACCOUNT_RE.test(t.error || t.text || '')
520
+ : r.stopped === 'account' || ACCOUNT_RE.test(r.error || '');
521
+ let mark;
522
+ if (t?.skipped) mark = '-';
523
+ else if (ok) mark = '✓';
524
+ else if (accountish) mark = 'A';
525
+ // The catalog is silent on vision for this model: a wrong answer may just be a text-only
526
+ // model, so it is flagged for manual review instead of counted as a failure.
527
+ else if (key === 'im' && t?.visionFlag === 'unknown') mark = '?';
528
+ else mark = '✗';
529
+ marks.push(`${label}${mark}`);
530
+ if (mark === '✗') anyFail = true;
531
+ if (mark === 'A') anyAccount = true;
532
+ if (mark !== '✓' && mark !== '-') {
533
+ evid.push(`${label}${mark}: ${evidence(key, t)}`);
534
+ details.push({ r, key, label, mark, t });
535
+ }
536
+ }
537
+ const turns = Object.entries(r.turns || {});
538
+ const later = (r.order || [])
539
+ .slice(1)
540
+ .map((k) => r.turns[k])
541
+ .filter((t) => t?.usage);
542
+ const sum = (f) => later.reduce((n, t) => n + f(t.usage), 0);
543
+ const events = (r.order || []).reduce((n, k) => n + (r.turns[k]?.usage?.events || 0), 0);
544
+ const cache =
545
+ !turns.length || !events
546
+ ? 'cache=NO-USAGE'
547
+ : `cache r=${sum((u) => u.cacheRead)} w=${sum((u) => u.cacheWrite)} in=${sum((u) => u.input)} cr/turn=[${later.map((t) => t.usage.cacheRead).join(',')}]`;
548
+ let verdict = 'PASS';
549
+ if (r.error && !turns.length) verdict = ACCOUNT_RE.test(r.error) ? 'ACCOUNT' : 'FAIL';
550
+ else if (anyFail) verdict = 'FAIL';
551
+ else if (anyAccount) verdict = 'ACCOUNT';
552
+ if (extended) {
553
+ console.log(`${verdict.padEnd(7)} ${r.name.padEnd(30)} ${marks.join(' ')} ${cache}`);
554
+ if (r.error) console.log(` error=${r.error}`);
555
+ for (const e of evid) console.log(` ${e}`);
556
+ } else {
557
+ const turn = (key, label) => {
558
+ const t = r.turns?.[key];
559
+ const ok = t && !t.error && scenarios.find((s) => s[0] === key)[2](t, r);
560
+ return `${label}${ok ? '✓' : '✗'} ${t?.ms}ms [${t?.calls}] "${short(t?.text)}"`;
561
+ };
562
+ const pass = !r.error && verdict === 'PASS';
563
+ let label = 'FAIL';
564
+ if (pass) label = 'PASS';
565
+ else if (verdict === 'ACCOUNT') label = 'ACCOUNT';
566
+ console.log(
567
+ `${label} ${r.name.padEnd(30)} ` +
568
+ (r.error ? `error=${r.error}` : `${turn('t1', 't1')} | ${turn('t2', 't2')} | ${turn('t3', 't3')}`)
569
+ );
570
+ }
571
+ }
572
+
573
+ if (extended) {
574
+ // Oddities worth a manual look: model identity, usage presence, notices mixed into answers.
575
+ console.log('\n--- NON-PASS DETAILS (raw) ---');
576
+ const markNames = { A: 'ACCOUNT', '?': 'UNVERIFIED' };
577
+ for (const { r, label, mark, t } of details) {
578
+ console.log(
579
+ `[${markNames[mark] ?? 'FAIL'}] ${r.provider}/${r.model} effort=${r.effort ?? '-'} ${label}: ` +
580
+ `error=${JSON.stringify(t?.error ?? null)} text=${JSON.stringify(t?.text ?? null)} calls=${JSON.stringify(t?.calls ?? null)} disk=${JSON.stringify(t?.disk ?? null)}`
581
+ );
582
+ }
583
+ console.log('\n--- ODDITIES ---');
584
+ for (const r of results) {
585
+ for (const key of r.order || []) {
586
+ const t = r.turns[key];
587
+ if (
588
+ t?.models?.length &&
589
+ !t.models.some((m) => m === r.model || m.endsWith(`/${r.model}`) || m.includes(r.model) || r.model.includes(m))
590
+ )
591
+ console.log(`${r.name} ${key}: served model ${JSON.stringify(t.models)} != requested ${r.model}`);
592
+ if (/notice|overloaded|retrying|fallback|server error|temporarily/i.test(t?.text || ''))
593
+ console.log(`${r.name} ${key}: notice-like text ${JSON.stringify(t.text)}`);
594
+ if (t && !t.skipped && !t.error && t.usage && t.usage.events === 0)
595
+ console.log(`${r.name} ${key}: no usage events`);
596
+ }
597
+ }
598
+ }
599
+ removeTemp();
@@ -152,22 +152,6 @@ function fmtTs(ms) {
152
152
  }
153
153
  }
154
154
 
155
- // `.hb` sidecar bytes are attributed to their session so reclaimable bytes
156
- // reflect the full on-disk footprint of a session.
157
- function collectHbSidecarSizes(dir, files) {
158
- const hbSizeById = new Map();
159
- for (const f of files) {
160
- if (!f.endsWith('.hb')) continue;
161
- const id = f.slice(0, -3);
162
- try {
163
- hbSizeById.set(id, statSync(join(dir, f)).size || 0);
164
- } catch {
165
- /* ignore */
166
- }
167
- }
168
- return hbSizeById;
169
- }
170
-
171
155
  // Authoritative per-file lifecycle via cheap top-level scan; the summary
172
156
  // index is stale here (most on-disk files are unindexed), so the file
173
157
  // itself — not the index — decides closed/age. Fall back to the index
@@ -200,7 +184,7 @@ function classifySessionFile({ full, mtimeMs, row, now, maxAgeMs, minClosedAgeMs
200
184
 
201
185
  // Disk scan for sizes + mtime fallback, then the retention verdict per file
202
186
  // rolled into the totals the report prints.
203
- function collectRetention({ dir, jsonFiles, hbSizeById, rowById, now, maxAgeMs, minClosedAgeMs }) {
187
+ function collectRetention({ dir, jsonFiles, rowById, now, maxAgeMs, minClosedAgeMs }) {
204
188
  let totalFiles = 0;
205
189
  let totalBytes = 0;
206
190
  const candidates = []; // { id, reason, updatedAt, bytes, inIndex }
@@ -218,17 +202,15 @@ function collectRetention({ dir, jsonFiles, hbSizeById, rowById, now, maxAgeMs,
218
202
  const id = f.slice(0, -5);
219
203
  fileIds.add(id);
220
204
  const full = join(dir, f);
221
- let size = 0;
205
+ let bytes = 0;
222
206
  let mtimeMs = 0;
223
207
  try {
224
208
  const st = statSync(full);
225
- size = st.size || 0;
209
+ bytes = st.size || 0;
226
210
  mtimeMs = st.mtimeMs || 0;
227
211
  } catch {
228
212
  /* skip */
229
213
  }
230
- const hb = hbSizeById.get(id) || 0;
231
- const bytes = size + hb;
232
214
  totalFiles += 1;
233
215
  totalBytes += bytes;
234
216
 
@@ -346,10 +328,8 @@ function main() {
346
328
  const rowById = new Map();
347
329
  for (const r of rows) if (r?.id) rowById.set(r.id, r);
348
330
 
349
- const files = readdirSync(dir);
350
- const jsonFiles = files.filter((f) => f.endsWith('.json'));
351
- const hbSizeById = collectHbSidecarSizes(dir, files);
352
- const retention = collectRetention({ dir, jsonFiles, hbSizeById, rowById, now, maxAgeMs, minClosedAgeMs });
331
+ const jsonFiles = readdirSync(dir).filter((f) => f.endsWith('.json'));
332
+ const retention = collectRetention({ dir, jsonFiles, rowById, now, maxAgeMs, minClosedAgeMs });
353
333
  process.stdout.write(renderReport({ dir, rows, now, maxAgeDays, minClosedAgeDays, retention }));
354
334
  }
355
335
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: Advisor
3
- description: Use on non-trivial work after orientation and before committing to an approach, when stuck or results do not converge, before changing approach, and for requested second opinions. Skip for low-difficulty work. Advisory analysis only; the final check belongs to Reviewer.
3
+ description: "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions."
4
4
  ---
5
5
 
6
6
  Independent technical advisor.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "advisor",
3
3
  "name": "Advisor",
4
- "description": "Use on non-trivial work after orientation and before committing to an approach, when stuck or results do not converge, before changing approach, and for requested second opinions. Skip for low-difficulty work. Advisory analysis only; the final check belongs to Reviewer.",
4
+ "description": "Use by difficulty: on any work beyond a simple one- or two-step change, after orientation and before committing to an approach, when errors recur or results stop converging, before changing approach, and for requested second opinions.",
5
5
  "entry": "AGENT.md"
6
6
  }