mixdog 1.2.3 → 1.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (465) hide show
  1. package/package.json +1 -1
  2. package/scripts/gate-local.mjs +6 -4
  3. package/scripts/lib/gate-scheduler.mjs +29 -11
  4. package/scripts/probe-provider-catalog.mjs +31 -0
  5. package/scripts/provider-pingpong-live.mjs +128 -38
  6. package/scripts/session-sweep.mjs +5 -25
  7. package/src/agents/maintainer/AGENT.md +1 -1
  8. package/src/agents/maintainer/agent.json +1 -1
  9. package/src/agents/reviewer/AGENT.md +2 -4
  10. package/src/agents/security/AGENT.md +1 -2
  11. package/src/agents/writer/AGENT.md +2 -3
  12. package/src/defaults/shipped-history.json +6 -1
  13. package/src/defaults/skills/image/SKILL.md +21 -23
  14. package/src/lib/keychain-cjs.cjs +13 -11
  15. package/src/rules/agent/AGENT.md +7 -5
  16. package/src/rules/lead/LEAD.md +7 -9
  17. package/src/rules/shared/45-destructive.md +4 -0
  18. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +1 -0
  19. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +28 -7
  20. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -11
  21. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +101 -23
  22. package/src/runtime/agent/orchestrator/providers/account-pool.mjs +2 -0
  23. package/src/runtime/agent/orchestrator/providers/anthropic-api-key-fetch.mjs +36 -0
  24. package/src/runtime/agent/orchestrator/providers/anthropic-error-contract.mjs +1 -1
  25. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +2 -3
  26. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
  27. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +26 -44
  28. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2 -5
  29. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +4 -0
  30. package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +41 -12
  31. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.mjs +13 -1
  32. package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +81 -10
  33. package/src/runtime/agent/orchestrator/providers/antigravity-retry-policy.mjs +109 -5
  34. package/src/runtime/agent/orchestrator/providers/antigravity-stream.mjs +2 -1
  35. package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +107 -37
  36. package/src/runtime/agent/orchestrator/providers/command-code-oauth.mjs +4 -1
  37. package/src/runtime/agent/orchestrator/providers/cursor-auth.mjs +3 -1
  38. package/src/runtime/agent/orchestrator/providers/cursor-client-version.mjs +1 -1
  39. package/src/runtime/agent/orchestrator/providers/cursor-native-context.mjs +48 -0
  40. package/src/runtime/agent/orchestrator/providers/cursor-wire-exec.mjs +144 -34
  41. package/src/runtime/agent/orchestrator/providers/cursor-wire-protobuf.mjs +28 -4
  42. package/src/runtime/agent/orchestrator/providers/cursor-wire-request.mjs +8 -4
  43. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-bridge.mjs +41 -11
  44. package/src/runtime/agent/orchestrator/providers/cursor-wire-stream-messages.mjs +67 -5
  45. package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +14 -4
  46. package/src/runtime/agent/orchestrator/providers/cursor.mjs +14 -1
  47. package/src/runtime/agent/orchestrator/providers/custom-provider-config.mjs +9 -6
  48. package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +7 -2
  49. package/src/runtime/agent/orchestrator/providers/effort-configuration.mjs +26 -4
  50. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +12 -6
  51. package/src/runtime/agent/orchestrator/providers/gemini-error-contract.mjs +14 -6
  52. package/src/runtime/agent/orchestrator/providers/gemini-request-body.mjs +4 -4
  53. package/src/runtime/agent/orchestrator/providers/gemini-response.mjs +1 -0
  54. package/src/runtime/agent/orchestrator/providers/gemini-rest-stream/watchdogs.mjs +16 -5
  55. package/src/runtime/agent/orchestrator/providers/gemini-retry-policy.mjs +6 -1
  56. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +22 -10
  57. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +4 -2
  58. package/src/runtime/agent/orchestrator/providers/gemini-thinking.mjs +33 -7
  59. package/src/runtime/agent/orchestrator/providers/gemini.mjs +11 -2
  60. package/src/runtime/agent/orchestrator/providers/grok-client-version.mjs +1 -1
  61. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +9 -2
  62. package/src/runtime/agent/orchestrator/providers/lib/claude-bridge-schema.mjs +9 -5
  63. package/src/runtime/agent/orchestrator/providers/lib/request-compression.mjs +86 -0
  64. package/src/runtime/agent/orchestrator/providers/lib/wire-pairing.mjs +4 -2
  65. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -5
  66. package/src/runtime/agent/orchestrator/providers/mimo-oauth.mjs +7 -1
  67. package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +60 -16
  68. package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +11 -13
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-send.mjs +30 -19
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream/stream-state.mjs +3 -1
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-chat-stream.mjs +5 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +42 -5
  73. package/src/runtime/agent/orchestrator/providers/openai-compat-reasoning-field.mjs +13 -9
  74. package/src/runtime/agent/orchestrator/providers/openai-compat-response-normalization.mjs +1 -3
  75. package/src/runtime/agent/orchestrator/providers/openai-compat-responses-parity.fixtures.mjs +18 -7
  76. package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +36 -3
  77. package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +51 -3
  78. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +11 -1
  79. package/src/runtime/agent/orchestrator/providers/openai-http-sse-request.mjs +64 -52
  80. package/src/runtime/agent/orchestrator/providers/openai-http-sse-response-state/response-events/terminal-frames.mjs +3 -1
  81. package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +2 -1
  82. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +7 -1
  83. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +1 -4
  84. package/src/runtime/agent/orchestrator/providers/openai-ws-response-state/tool-calls.mjs +0 -1
  85. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +7 -6
  86. package/src/runtime/agent/orchestrator/providers/opencode-go-gemini.mjs +13 -2
  87. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +4 -1
  88. package/src/runtime/agent/orchestrator/providers/openrouter.mjs +1 -2
  89. package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +5 -4
  90. package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -1
  91. package/src/runtime/agent/orchestrator/providers/retry-classification.mjs +2 -1
  92. package/src/runtime/agent/orchestrator/providers/wire-gateway.mjs +11 -4
  93. package/src/runtime/agent/orchestrator/providers/wire-route.mjs +14 -4
  94. package/src/runtime/agent/orchestrator/providers/xai-tool-search.fixtures.mjs +15 -3
  95. package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +6 -2
  96. package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +8 -6
  97. package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-availability.mjs +4 -1
  98. package/src/runtime/agent/orchestrator/runtime-core/goal-store.mjs +30 -2
  99. package/src/runtime/agent/orchestrator/runtime-core/goal-turns.mjs +3 -2
  100. package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +8 -3
  101. package/src/runtime/agent/orchestrator/runtime-core/skill-tool-loading.mjs +3 -1
  102. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge-contract.mjs +6 -0
  103. package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +10 -10
  104. package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +3 -1
  105. package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +46 -8
  106. package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +10 -8
  107. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +1 -2
  108. package/src/runtime/agent/orchestrator/session/agent-pool-progress.mjs +24 -0
  109. package/src/runtime/agent/orchestrator/session/cache/tool-result-reuse.mjs +10 -2
  110. package/src/runtime/agent/orchestrator/session/catalog-db/index.mjs +2 -3
  111. package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +3 -11
  112. package/src/runtime/agent/orchestrator/session/catalog-db/worker.mjs +6 -22
  113. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -0
  114. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +16 -2
  115. package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +28 -0
  116. package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/session/conversation-import/claude.mjs +0 -6
  118. package/src/runtime/agent/orchestrator/session/conversation-import/codex.mjs +0 -6
  119. package/src/runtime/agent/orchestrator/session/eager-dispatch/admission.mjs +1 -1
  120. package/src/runtime/agent/orchestrator/session/historical-session-closure.mjs +10 -0
  121. package/src/runtime/agent/orchestrator/session/loop/assistant-commit.mjs +2 -5
  122. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +2 -4
  123. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +3 -3
  124. package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +0 -27
  125. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/output-limit.mjs +1 -1
  126. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn/segments.mjs +4 -10
  127. package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +2 -9
  128. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +4 -1
  129. package/src/runtime/agent/orchestrator/session/loop/provider-tool-exclusions.mjs +4 -1
  130. package/src/runtime/agent/orchestrator/session/loop/request-boundary.mjs +1 -4
  131. package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +76 -0
  132. package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +5 -1
  133. package/src/runtime/agent/orchestrator/session/loop/step-auto-effort.mjs +8 -9
  134. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +6 -0
  135. package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +15 -2
  136. package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +1 -4
  137. package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +3 -4
  138. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +33 -3
  139. package/src/runtime/agent/orchestrator/session/manager/ask-support.mjs +0 -4
  140. package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +21 -1
  141. package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +38 -13
  142. package/src/runtime/agent/orchestrator/session/manager/ask-turn-failure.mjs +33 -0
  143. package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +5 -0
  144. package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +19 -1
  145. package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +57 -13
  146. package/src/runtime/agent/orchestrator/session/manager/failed-turn-rewind.mjs +16 -0
  147. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +6 -120
  148. package/src/runtime/agent/orchestrator/session/manager/pending-persist-queue.mjs +1 -1
  149. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +29 -8
  150. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +42 -49
  151. package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +50 -0
  152. package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +32 -14
  153. package/src/runtime/agent/orchestrator/session/manager/session-crud.mjs +1 -1
  154. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +17 -33
  155. package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +29 -13
  156. package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +3 -3
  157. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-recovery.mjs +45 -0
  158. package/src/runtime/agent/orchestrator/session/manager.mjs +2 -9
  159. package/src/runtime/agent/orchestrator/session/send-instrumentation.mjs +2 -1
  160. package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -2
  161. package/src/runtime/agent/orchestrator/session/side-question.mjs +12 -7
  162. package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +5 -12
  163. package/src/runtime/agent/orchestrator/session/store/lifecycle-read.mjs +1 -1
  164. package/src/runtime/agent/orchestrator/session/store/listing.mjs +2 -6
  165. package/src/runtime/agent/orchestrator/session/store/live-cache-eviction.mjs +1 -1
  166. package/src/runtime/agent/orchestrator/session/store/liveness-veto.mjs +46 -37
  167. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +1 -1
  168. package/src/runtime/agent/orchestrator/session/store/load-session.mjs +1 -1
  169. package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +5 -11
  170. package/src/runtime/agent/orchestrator/session/store/session-paths.mjs +59 -0
  171. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +1 -1
  172. package/src/runtime/agent/orchestrator/session/store/sweep/stale-sweep.mjs +1 -1
  173. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-finish.mjs +27 -32
  174. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-plan.mjs +0 -8
  175. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +6 -18
  176. package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +33 -106
  177. package/src/runtime/agent/orchestrator/session/store/write-admission.mjs +1 -1
  178. package/src/runtime/agent/orchestrator/session/store-agent-worker-pool.mjs +5 -8
  179. package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +136 -196
  180. package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +50 -116
  181. package/src/runtime/agent/orchestrator/session/store-summary-locations.mjs +3 -29
  182. package/src/runtime/agent/orchestrator/session/store-summary-reader-catalog-fixture.mjs +1 -1
  183. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +7 -8
  184. package/src/runtime/agent/orchestrator/session/store-transcript-projection.mjs +9 -20
  185. package/src/runtime/agent/orchestrator/session/store.mjs +3 -16
  186. package/src/runtime/agent/orchestrator/session/tool-batch/execute-call.mjs +11 -12
  187. package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +37 -13
  188. package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +15 -4
  189. package/src/runtime/agent/orchestrator/session/tool-schema-rejection.mjs +4 -2
  190. package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +72 -15
  191. package/src/runtime/agent/orchestrator/session/turn-failure.mjs +45 -0
  192. package/src/runtime/agent/orchestrator/stall-policy.mjs +50 -0
  193. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +5 -1
  194. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/inline-hoist.mjs +6 -2
  195. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +204 -10
  196. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.mjs +160 -39
  197. package/src/runtime/agent/orchestrator/tools/builtin/git-partial-stage.mjs +7 -5
  198. package/src/runtime/agent/orchestrator/tools/builtin/grep-formatting.mjs +14 -5
  199. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-context-expander.mjs +4 -3
  200. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-output.mjs +2 -1
  201. package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +48 -44
  202. package/src/runtime/agent/orchestrator/tools/builtin/lib/search-input-helpers.mjs +10 -3
  203. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +200 -17
  204. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-task-output.mjs +5 -4
  205. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +6 -1
  206. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +20 -0
  207. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +101 -2
  208. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  209. package/src/runtime/agent/orchestrator/tools/lib/owned-shell-trees.mjs +67 -0
  210. package/src/runtime/agent/orchestrator/tools/lib/process-table-fixture.mjs +50 -0
  211. package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +303 -63
  212. package/src/runtime/agent/orchestrator/tools/lib/shell-run-background/promote-job.mjs +2 -0
  213. package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +108 -18
  214. package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +77 -11
  215. package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +81 -5
  216. package/src/runtime/attachments/store.d.mts +9 -0
  217. package/src/runtime/attachments/store.mjs +80 -9
  218. package/src/runtime/browser-bridge/browser-action-contract.d.mts +0 -1
  219. package/src/runtime/browser-bridge/browser-action-contract.mjs +0 -2
  220. package/src/runtime/computer-bridge/action-schema.mjs +178 -178
  221. package/src/runtime/computer-bridge/linux-readiness.d.mts +0 -2
  222. package/src/runtime/computer-bridge/linux-readiness.mjs +0 -16
  223. package/src/runtime/effort-judge/judge-client.mjs +21 -4
  224. package/src/runtime/effort-judge/judge-worker.mjs +4 -1
  225. package/src/runtime/github/tool.mjs +118 -17
  226. package/src/runtime/media/adapters/codex-image.mjs +140 -21
  227. package/src/runtime/media/catalog.mjs +4 -4
  228. package/src/runtime/media/chatgpt-usage.mjs +55 -0
  229. package/src/runtime/media/defaults.mjs +37 -0
  230. package/src/runtime/media/jobs.mjs +12 -2
  231. package/src/runtime/media/lanes.mjs +12 -0
  232. package/src/runtime/media/tool-defs.mjs +15 -4
  233. package/src/runtime/media/tool.mjs +41 -12
  234. package/src/runtime/media/upstream-error.mjs +72 -6
  235. package/src/runtime/memory/lib/ingest/transcript-rows.mjs +1 -0
  236. package/src/runtime/memory/lib/pg/process.mjs +5 -7
  237. package/src/runtime/memory/lib/pg/supervisor.mjs +4 -1
  238. package/src/runtime/office/authoring/docx-html-runner.mjs +1 -1
  239. package/src/runtime/office/authoring/html-browser.mjs +18 -8
  240. package/src/runtime/office/authoring/pdf-html-runner.mjs +1 -1
  241. package/src/runtime/office/authoring/pptx-html-measure.mjs +1 -1
  242. package/src/runtime/office/authoring/xlsx-html-runner.mjs +1 -1
  243. package/src/runtime/office/core/office-write-ledger.mjs +1 -5
  244. package/src/runtime/office/index.mjs +2 -3
  245. package/src/runtime/office/pdf/pdf-analysis.mjs +0 -68
  246. package/src/runtime/session-search/session-search-ingest.mjs +1 -1
  247. package/src/runtime/shared/agent-reap-state.mjs +13 -0
  248. package/src/runtime/shared/atomic-file.d.mts +1 -1
  249. package/src/runtime/shared/background-tasks.mjs +6 -1
  250. package/src/runtime/shared/bounded-line-diff.mjs +11 -2
  251. package/src/runtime/shared/browser-launch.mjs +15 -0
  252. package/src/runtime/shared/err-text.mjs +42 -4
  253. package/src/runtime/shared/file-lock.mjs +6 -5
  254. package/src/runtime/shared/llm/anthropic-betas.mjs +1 -2
  255. package/src/runtime/shared/llm/provider-model-identities.mjs +1 -0
  256. package/src/runtime/shared/model-route-chain.d.mts +8 -0
  257. package/src/runtime/shared/model-route-chain.mjs +48 -0
  258. package/src/runtime/shared/model-route-fallback.mjs +22 -0
  259. package/src/runtime/shared/pid-liveness.mjs +12 -0
  260. package/src/runtime/shared/provider-api-key.mjs +6 -0
  261. package/src/runtime/shared/provider-timeout-phase.mjs +17 -0
  262. package/src/runtime/shared/quiet-progress.d.mts +35 -0
  263. package/src/runtime/shared/quiet-progress.mjs +101 -0
  264. package/src/runtime/shared/quota-resume-store.mjs +32 -1
  265. package/src/runtime/shared/read-row-numbers.mjs +44 -0
  266. package/src/runtime/shared/remote-intent.mjs +2 -42
  267. package/src/runtime/shared/slow-span.mjs +8 -1
  268. package/src/runtime/shared/statusline/statusline-segments.mjs +24 -2
  269. package/src/runtime/shared/tool-card-model/card-header.mjs +2 -1
  270. package/src/runtime/shared/tool-output-budget.mjs +2 -0
  271. package/src/runtime/shared/tool-result-summary.mjs +16 -2
  272. package/src/runtime/shared/tool-status.mjs +3 -2
  273. package/src/runtime/shared/tool-surface.mjs +2 -3
  274. package/src/runtime/shared/tool-work-units.mjs +22 -15
  275. package/src/runtime/shared/transcript-metadata.mjs +49 -1
  276. package/src/runtime/shared/transcript-turn-keys.mjs +33 -0
  277. package/src/runtime/shared/transcript-writer/transcript-file.mjs +10 -1
  278. package/src/runtime/shared/transcript-writer.mjs +14 -4
  279. package/src/runtime/shared/turn-changes.mjs +2 -1
  280. package/src/runtime/shared/turn-snapshot.mjs +11 -3
  281. package/src/runtime/shared/worktrees/activity-gate.mjs +175 -0
  282. package/src/runtime/shared/worktrees/branch-management.mjs +179 -0
  283. package/src/runtime/shared/worktrees/carry.mjs +6 -4
  284. package/src/runtime/shared/worktrees/contract.mjs +27 -1
  285. package/src/runtime/shared/worktrees/dependencies.mjs +456 -0
  286. package/src/runtime/shared/worktrees/file-recovery.mjs +29 -13
  287. package/src/runtime/shared/worktrees/git-head.mjs +22 -13
  288. package/src/runtime/shared/worktrees/include.mjs +125 -7
  289. package/src/runtime/shared/worktrees/lock.mjs +1 -1
  290. package/src/runtime/shared/worktrees/maintenance.mjs +20 -2
  291. package/src/runtime/shared/worktrees/manager.mjs +378 -32
  292. package/src/runtime/shared/worktrees/owner.mjs +2 -1
  293. package/src/runtime/shared/worktrees/preparation-report.mjs +79 -0
  294. package/src/runtime/shared/worktrees/setup-commands.mjs +232 -0
  295. package/src/runtime/shared/worktrees/workspace-visibility.mjs +17 -0
  296. package/src/runtime/terminal-bridge/client.mjs +14 -10
  297. package/src/session-runtime/boot/apis.mjs +7 -1
  298. package/src/session-runtime/boot/config.mjs +2 -0
  299. package/src/session-runtime/boot/facade.mjs +3 -0
  300. package/src/session-runtime/boot/session.mjs +3 -2
  301. package/src/session-runtime/boot/tools.mjs +3 -0
  302. package/src/session-runtime/conversation-import/service.mjs +1 -1
  303. package/src/session-runtime/goal-facade-api.mjs +2 -2
  304. package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +44 -18
  305. package/src/session-runtime/internal-tool-executor/knowledge-tools.mjs +4 -1
  306. package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +22 -8
  307. package/src/session-runtime/internal-tool-executor.mjs +2 -0
  308. package/src/session-runtime/lifecycle/cold-heir.mjs +0 -1
  309. package/src/session-runtime/lifecycle/session-catalog.mjs +14 -16
  310. package/src/session-runtime/lifecycle/session-switch/session-delete.mjs +18 -53
  311. package/src/session-runtime/lifecycle/session-switch.mjs +1 -1
  312. package/src/session-runtime/lifecycle/shared.mjs +5 -6
  313. package/src/session-runtime/lifecycle/teardown/session-close.mjs +6 -5
  314. package/src/session-runtime/lifecycle/teardown.mjs +7 -16
  315. package/src/session-runtime/media-api.mjs +8 -0
  316. package/src/session-runtime/model-route/route-ownership.mjs +60 -0
  317. package/src/session-runtime/model-route/route-persist.mjs +3 -2
  318. package/src/session-runtime/model-route/set-route.mjs +114 -34
  319. package/src/session-runtime/model-route/web-search-route.mjs +7 -2
  320. package/src/session-runtime/model-route-api.mjs +4 -2
  321. package/src/session-runtime/native-web-search/routes.mjs +37 -24
  322. package/src/session-runtime/native-web-search.mjs +9 -8
  323. package/src/session-runtime/provider-auth/setup.mjs +4 -0
  324. package/src/session-runtime/provider-models/catalog-load.mjs +9 -0
  325. package/src/session-runtime/provider-models/web-search-catalog.mjs +23 -3
  326. package/src/session-runtime/provider-models.mjs +1 -0
  327. package/src/session-runtime/provider-usage.mjs +4 -0
  328. package/src/session-runtime/route-resolution.mjs +3 -1
  329. package/src/session-runtime/runtime-core.mjs +4 -0
  330. package/src/session-runtime/runtime-facade.mjs +6 -0
  331. package/src/session-runtime/services/agent-task-status.mjs +2 -0
  332. package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +0 -3
  333. package/src/session-runtime/services/agent-tool/close-flow.mjs +6 -7
  334. package/src/session-runtime/services/agent-tool/execute-send.mjs +2 -2
  335. package/src/session-runtime/services/agent-tool/execute-spawn.mjs +36 -3
  336. package/src/session-runtime/services/agent-tool/execute.mjs +9 -1
  337. package/src/session-runtime/services/agent-tool/helpers.mjs +30 -7
  338. package/src/session-runtime/services/agent-tool/job-task-reconcile.mjs +7 -2
  339. package/src/session-runtime/services/agent-tool/job-views/session-progress.mjs +6 -3
  340. package/src/session-runtime/services/agent-tool/lead-worker-index/lead-rows.mjs +3 -4
  341. package/src/session-runtime/services/agent-tool/lead-worker-index/reap-timers.mjs +9 -3
  342. package/src/session-runtime/services/agent-tool/lead-worker-index/row-settlement.mjs +7 -18
  343. package/src/session-runtime/services/agent-tool/lead-worker-index.mjs +9 -6
  344. package/src/session-runtime/services/agent-tool/model-select.mjs +82 -0
  345. package/src/session-runtime/services/agent-tool/send-flow.mjs +24 -6
  346. package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +3 -1
  347. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +19 -5
  348. package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +5 -4
  349. package/src/session-runtime/services/agent-tool/spawn-flow.mjs +2 -1
  350. package/src/session-runtime/services/agent-tool/spawn-preset.mjs +3 -0
  351. package/src/session-runtime/services/agent-tool/tag-registry/tag-lookup.mjs +1 -3
  352. package/src/session-runtime/services/agent-tool/tag-registry/tag-refresh.mjs +1 -3
  353. package/src/session-runtime/services/agent-tool/tag-registry.mjs +3 -9
  354. package/src/session-runtime/services/agent-tool/terminal-reaper/scan-admission.mjs +8 -41
  355. package/src/session-runtime/services/agent-tool/terminal-reaper/stale-rows.mjs +3 -3
  356. package/src/session-runtime/services/agent-tool/terminal-reaper.mjs +6 -23
  357. package/src/session-runtime/services/agent-tool/terminal-trace.mjs +0 -1
  358. package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
  359. package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +32 -20
  360. package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +5 -2
  361. package/src/session-runtime/services/agent-tool/worker-index.mjs +28 -8
  362. package/src/session-runtime/services/agent-tool.mjs +4 -0
  363. package/src/session-runtime/services/agent-watchdog-registry.mjs +2 -0
  364. package/src/session-runtime/services/provider-admin.mjs +77 -0
  365. package/src/session-runtime/session-create/session-options.mjs +7 -5
  366. package/src/session-runtime/session-create/session-start-hook.mjs +2 -1
  367. package/src/session-runtime/session-transcript.mjs +4 -5
  368. package/src/session-runtime/session-turn-api.mjs +3 -9
  369. package/src/session-runtime/settings-builtin-tools-api.mjs +9 -6
  370. package/src/session-runtime/setup-tool/executor.mjs +23 -5
  371. package/src/session-runtime/setup-tool/extended-actions.mjs +6 -6
  372. package/src/session-runtime/setup-tool/settings-contract.mjs +7 -2
  373. package/src/session-runtime/setup-tool/tool-defs.mjs +13 -1
  374. package/src/session-runtime/tool-policy-refresh.mjs +83 -32
  375. package/src/session-runtime/turn/agent-ops.mjs +49 -2
  376. package/src/session-runtime/turn/side-question-ops.mjs +1 -4
  377. package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +2 -0
  378. package/src/session-runtime/turn/turn-run/turn-prepare.mjs +4 -0
  379. package/src/session-runtime/turn/turn-run/turn-settle.mjs +8 -2
  380. package/src/session-runtime/turn/turn-run.mjs +1 -36
  381. package/src/session-runtime/usage-stats-api.mjs +4 -1
  382. package/src/session-runtime/workflow-agents-api/agent-route.mjs +16 -1
  383. package/src/session-runtime/workspace/admission-gate.mjs +44 -15
  384. package/src/session-runtime/workspace/project-branches.mjs +28 -36
  385. package/src/session-runtime/workspace/transition-steps.mjs +96 -95
  386. package/src/session-runtime/workspace/transitions.mjs +248 -68
  387. package/src/standalone/channel-transport.mjs +3 -4
  388. package/src/standalone/daemon-desktop-runtime.mjs +32 -1
  389. package/src/standalone/daemon-pg-stop.mjs +1 -3
  390. package/src/standalone/daemon-session-control.mjs +88 -0
  391. package/src/standalone/daemon-stored-session-views.mjs +23 -3
  392. package/src/standalone/daemon.mjs +2 -0
  393. package/src/standalone/local-session-runtime.mjs +11 -12
  394. package/src/standalone/session-protocol.mjs +7 -0
  395. package/src/standalone/session-runtime-inline-host.mjs +2 -0
  396. package/src/standalone/session-service/agent-tree/agent-cancel.mjs +91 -49
  397. package/src/standalone/session-service/agent-tree/agent-child.mjs +19 -1
  398. package/src/standalone/session-service/agent-tree/agent-registry.mjs +25 -0
  399. package/src/standalone/session-service/agent-tree/agent-turns.mjs +9 -1
  400. package/src/standalone/session-service/agent-tree.mjs +28 -2
  401. package/src/standalone/session-service/entries/session-loads.mjs +16 -5
  402. package/src/standalone/session-service/entries.mjs +1 -0
  403. package/src/standalone/session-service/projection/transcript-window.mjs +39 -0
  404. package/src/standalone/session-service/quota-resume.mjs +28 -13
  405. package/src/standalone/session-service/session-calls/session-turns.mjs +17 -6
  406. package/src/standalone/session-service/session-calls/session-views.mjs +6 -0
  407. package/src/standalone/session-tool-output.mjs +82 -0
  408. package/src/tui/app/app-view.jsx +2 -1
  409. package/src/tui/app/provider-setup/provider-items.mjs +8 -0
  410. package/src/tui/app/provider-setup-picker.mjs +15 -3
  411. package/src/tui/app/slash-commands.mjs +6 -0
  412. package/src/tui/app/slash-dispatch/session-commands.mjs +49 -0
  413. package/src/tui/components/Spinner.jsx +4 -0
  414. package/src/tui/components/SpinnerByline.jsx +21 -2
  415. package/src/tui/components/status-line/local-line.mjs +10 -2
  416. package/src/tui/dist/index.mjs +478 -251
  417. package/src/tui/session/active-tool-summary.mjs +1 -1
  418. package/src/tui/session/context-state.mjs +0 -3
  419. package/src/tui/session/goal-continuation/continuation-queue.mjs +2 -3
  420. package/src/tui/session/goal-continuation/deadline-delivery.mjs +4 -2
  421. package/src/tui/session/goal-continuation/session-boundary.mjs +21 -0
  422. package/src/tui/session/quota-resume.mjs +140 -61
  423. package/src/tui/session/session-api/commands.mjs +4 -10
  424. package/src/tui/session/session-api/controls.mjs +12 -0
  425. package/src/tui/session/session-api/lifecycle/dispose.mjs +2 -9
  426. package/src/tui/session/session-api/lifecycle/resume.mjs +2 -7
  427. package/src/tui/session/session-api/lifecycle.mjs +13 -11
  428. package/src/tui/session/session-api/media.mjs +2 -0
  429. package/src/tui/session/session-api/routes.mjs +81 -57
  430. package/src/tui/session/session-api/settings.mjs +3 -3
  431. package/src/tui/session/session-api/worktree.mjs +3 -2
  432. package/src/tui/session/session-flow/auto-clear.mjs +1 -3
  433. package/src/tui/session/session-flow/drain.mjs +6 -4
  434. package/src/tui/session/session-flow/queue/entry-shape.mjs +2 -0
  435. package/src/tui/session/session-flow/queue/take-entries.mjs +2 -1
  436. package/src/tui/session/session-flow/queue.mjs +1 -1
  437. package/src/tui/session/tool-approval.mjs +17 -8
  438. package/src/tui/session/transcript-store/streaming-tail.mjs +1 -1
  439. package/src/tui/session/tui-steering-persist.mjs +3 -5
  440. package/src/tui/session/turn-quiet.mjs +53 -0
  441. package/src/tui/session/turn-stream.mjs +5 -1
  442. package/src/tui/session/turn.mjs +38 -31
  443. package/src/tui/session/worktree-setup-notice.mjs +38 -0
  444. package/src/tui/spinner-meta.mjs +10 -0
  445. package/src/tui/spinner-verbs.mjs +3 -0
  446. package/src/ui/statusline.mjs +13 -3
  447. package/src/runtime/agent/orchestrator/providers/model-pricing-rates.mjs +0 -1
  448. package/src/runtime/agent/orchestrator/session/manager/foreign-pending-messages.mjs +0 -346
  449. package/src/runtime/agent/orchestrator/session/manager/session-owner-liveness.mjs +0 -117
  450. package/src/runtime/agent/orchestrator/session/store/paths-heartbeat.mjs +0 -302
  451. package/src/session-runtime/services/agent-tool/terminal-reaper/reap-timers.mjs +0 -142
  452. package/src/session-runtime/turn/share-ops.mjs +0 -77
  453. package/src/tui/session/cross-surface-share.mjs +0 -406
  454. package/src/tui/session/live-share/delta.mjs +0 -153
  455. package/src/tui/session/live-share/mirror.mjs +0 -106
  456. package/src/tui/session/live-share/owner.mjs +0 -254
  457. package/src/tui/session/live-share/retry.mjs +0 -54
  458. package/src/tui/session/live-share/viewer/frame-router.mjs +0 -32
  459. package/src/tui/session/live-share/viewer/pipe-client.mjs +0 -108
  460. package/src/tui/session/live-share/viewer/submit-acks.mjs +0 -65
  461. package/src/tui/session/live-share/viewer/sync-waiters.mjs +0 -53
  462. package/src/tui/session/live-share/viewer.mjs +0 -99
  463. package/src/tui/session/live-share/wire.mjs +0 -44
  464. package/src/tui/session/live-share.mjs +0 -154
  465. package/src/tui/session/shared-dir-watch.mjs +0 -69
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Open-source coding agent that matches Codex on Terminal-Bench 2.1 with 63% fewer tokens.",
@@ -41,11 +41,13 @@ if (build.status !== 0) {
41
41
  const logDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-gate-local-'));
42
42
  const resourceDir = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-gate-resources-'));
43
43
  const budget = gateTestBudget();
44
+ // weight: relative worker share, roughly each leg's measured duration x its 3 workers
45
+ // (runtime ~440s, runtime-slow ~545s, desktop fast ~390s, desktop slow ~280s).
44
46
  const legs = [
45
- { name: 'runtime', cmds: ['npm test', 'npm run smoke:patch'] },
46
- { name: 'desktop-tests-fast', cmds: ['npm test --prefix apps/desktop'] },
47
- { name: 'runtime-slow', cmds: ['npm run test:slow'] },
48
- { name: 'desktop-tests-slow', cmds: ['npm run test:slow --prefix apps/desktop'] },
47
+ { name: 'runtime', weight: 3, cmds: ['npm test', 'npm run smoke:patch'] },
48
+ { name: 'desktop-tests-fast', weight: 3, cmds: ['npm test --prefix apps/desktop'] },
49
+ { name: 'runtime-slow', weight: 4, cmds: ['npm run test:slow'] },
50
+ { name: 'desktop-tests-slow', weight: 2, cmds: ['npm run test:slow --prefix apps/desktop'] },
49
51
  { name: 'desktop', cmds: ['npm run build --prefix apps/desktop', 'npm run test:daemon:e2e --prefix apps/desktop'] },
50
52
  ];
51
53
 
@@ -8,17 +8,35 @@ export function gateTestBudget(env = process.env, parallelism = availableParalle
8
8
  return argument ? Number(argument.split('=')[1]) : Math.min(6, parallelism);
9
9
  }
10
10
 
11
+ // Splits the budget across legs in proportion to leg.weight (default 1), at least
12
+ // one worker each. Spare workers go one at a time to the leg with the highest
13
+ // weight per worker, so longer legs get more. Needs budget >= legs.length.
14
+ export function allocateWorkers(legs, budget) {
15
+ const shares = legs.map(() => 1);
16
+ for (let spare = budget - legs.length; spare > 0; spare--) {
17
+ let best = 0;
18
+ for (let i = 1; i < legs.length; i++) {
19
+ if ((legs[i].weight ?? 1) / shares[i] > (legs[best].weight ?? 1) / shares[best]) best = i;
20
+ }
21
+ shares[best]++;
22
+ }
23
+ return shares;
24
+ }
25
+
26
+ // The test runners read their worker count when spawned, so it cannot grow
27
+ // mid-run: shares are static. With fewer workers than legs, each worker runs
28
+ // legs one after another.
11
29
  export async function runGateLegs(legs, budget, runLeg) {
12
30
  if (!Number.isInteger(budget) || budget < 1) throw new Error('gate test budget must be a positive integer');
13
- const slots = Math.min(legs.length, budget);
14
- let next = 0;
15
- await Promise.all(
16
- Array.from({ length: slots }, async (_, index) => {
17
- const concurrency = Math.floor(budget / slots) + (index < budget % slots ? 1 : 0);
18
- while (next < legs.length) {
19
- const leg = legs[next++];
20
- await runLeg(leg, concurrency);
21
- }
22
- })
23
- );
31
+ if (budget < legs.length) {
32
+ let next = 0;
33
+ await Promise.all(
34
+ Array.from({ length: budget }, async () => {
35
+ while (next < legs.length) await runLeg(legs[next++], 1);
36
+ })
37
+ );
38
+ return;
39
+ }
40
+ const shares = allocateWorkers(legs, budget);
41
+ await Promise.all(legs.map((leg, index) => runLeg(leg, shares[index])));
24
42
  }
@@ -0,0 +1,31 @@
1
+ // Prints each named provider's raw listModels() outcome with the real ~/.mixdog data.
2
+ import os from 'node:os';
3
+ import { createMixdogSessionRuntime } from '../src/session-runtime/runtime-core.mjs';
4
+ import { getProvider } from '../src/runtime/agent/orchestrator/providers/registry.mjs';
5
+ import { listCompatModels } from '../src/runtime/agent/orchestrator/providers/openai-compat-models.mjs';
6
+
7
+ const names = process.argv.slice(2);
8
+ const runtime = await createMixdogSessionRuntime({ provider: 'deepseek', model: 'deepseek-flash', cwd: os.tmpdir() });
9
+ await runtime.listProviderModels?.({ force: true }).catch(() => {});
10
+ for (const name of names) {
11
+ const provider = getProvider(name);
12
+ if (!provider) {
13
+ console.log(name, 'NOT REGISTERED');
14
+ continue;
15
+ }
16
+ try {
17
+ const models =
18
+ name === 'xai' ? await listCompatModels(provider, { throwOnError: true }) : await provider.listModels();
19
+ console.log(
20
+ name,
21
+ 'models',
22
+ models.length,
23
+ models.fallback ? '(fallback)' : '',
24
+ models.slice(0, 5).map((m) => m.id)
25
+ );
26
+ } catch (error) {
27
+ console.log(name, 'ERROR', error?.status || '', String(error?.message || error).slice(0, 300));
28
+ }
29
+ }
30
+ await runtime.close('probe-provider-catalog');
31
+ process.exit(0);
@@ -71,8 +71,14 @@ const withTimeout = (promise, ms, onTimeout) =>
71
71
  reject(new Error(`timeout after ${ms}ms`));
72
72
  }, ms);
73
73
  promise.then(
74
- (v) => (clearTimeout(timer), resolve(v)),
75
- (e) => (clearTimeout(timer), reject(e))
74
+ (v) => {
75
+ clearTimeout(timer);
76
+ resolve(v);
77
+ },
78
+ (e) => {
79
+ clearTimeout(timer);
80
+ reject(e);
81
+ }
76
82
  );
77
83
  });
78
84
 
@@ -85,14 +91,23 @@ if (process.argv[2] === '--child') {
85
91
  const extended = spec.suite === 'extended';
86
92
  const { resolvePluginData } = await import('../src/runtime/shared/plugin-paths.mjs');
87
93
  if (spec.dataDir && path.resolve(resolvePluginData()) !== path.resolve(spec.dataDir)) {
88
- console.log(`RESULT ${JSON.stringify({ name: spec.name, error: `refusing to run: data dir ${resolvePluginData()} is not the isolated ${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
+ );
89
97
  process.exit(0);
90
98
  }
91
99
  const { createMixdogSessionRuntime } = await import('../src/session-runtime/runtime-core.mjs');
92
100
  const { materializePromptSubmission } = await import('../src/runtime/attachments/store.mjs');
93
101
  const { getModelMetadataSync } = await import('../src/runtime/shared/llm/model-catalog.mjs');
94
102
  let runtime;
95
- const out = { name: spec.name, provider: spec.provider, model: spec.model, effort: spec.effort, turns: {}, order: [] };
103
+ const out = {
104
+ name: spec.name,
105
+ provider: spec.provider,
106
+ model: spec.model,
107
+ effort: spec.effort,
108
+ turns: {},
109
+ order: [],
110
+ };
96
111
  const readDisk = (file) => {
97
112
  try {
98
113
  return fs.readFileSync(path.join(spec.cwd, file), 'utf8');
@@ -104,7 +119,12 @@ if (process.argv[2] === '--child') {
104
119
  // Runs one ask() and records calls/text/usage under `key`. Errors are recorded, not thrown,
105
120
  // so later scenarios still run; an ACCOUNT error stops the case (everything after would fail alike).
106
121
  const turn = async (key, prompt, options = {}) => {
107
- const rec = { calls: [], text: '', usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 }, models: [] };
122
+ const rec = {
123
+ calls: [],
124
+ text: '',
125
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
126
+ models: [],
127
+ };
108
128
  out.turns[key] = rec;
109
129
  out.order.push(key);
110
130
  const startedAt = Date.now();
@@ -146,7 +166,10 @@ if (process.argv[2] === '--child') {
146
166
  const steps = [
147
167
  ['t1', 'Use the read tool on package.json, then reply with only the value of "name".'],
148
168
  ['t2', 'Without using tools, reply with only that same name in uppercase.'],
149
- ['t3', 'Read a.txt and b.txt with two read calls issued together in one step, then reply with only their two contents joined by "+".'],
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
+ ],
150
173
  ];
151
174
  for (const [key, prompt] of steps) {
152
175
  await turn(key, prompt);
@@ -195,7 +218,12 @@ if (process.argv[2] === '--child') {
195
218
  }
196
219
  if (extended && !out.stopped) {
197
220
  // Real cancel path: runtime.abort() -> abortRuntime -> turn controller + mgr.abortSessionTurn.
198
- const rec = { calls: [], text: '', usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 }, models: [] };
221
+ const rec = {
222
+ calls: [],
223
+ text: '',
224
+ usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, events: 0 },
225
+ models: [],
226
+ };
199
227
  out.turns.ca = rec;
200
228
  out.order.push('ca');
201
229
  let deltas = 0;
@@ -212,16 +240,19 @@ if (process.argv[2] === '--child') {
212
240
  };
213
241
  const startedAt = Date.now();
214
242
  const pending = runtime
215
- .ask('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.', {
216
- onTextDelta: onDelta,
217
- onUsageDelta: (d) => {
218
- rec.usage.events++;
219
- rec.usage.input += d.deltaInput || 0;
220
- rec.usage.output += d.deltaOutput || 0;
221
- rec.usage.cacheRead += d.deltaCachedRead || 0;
222
- rec.usage.cacheWrite += d.deltaCacheWrite || 0;
223
- },
224
- })
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
+ )
225
256
  .then(
226
257
  (r) => ({ ok: true, text: textOf(r).trim() }),
227
258
  (e) => ({ ok: false, error: String(e?.message || e) })
@@ -232,7 +263,8 @@ if (process.argv[2] === '--child') {
232
263
  rec.deltas = deltas;
233
264
  rec.abortResult = abortResult;
234
265
  rec.abortedAfterMs = rec.ms;
235
- rec.settle = settled.hang ? 'hang' : settled.ok ? 'resolved' : 'rejected';
266
+ if (settled.hang) rec.settle = 'hang';
267
+ else rec.settle = settled.ok ? 'resolved' : 'rejected';
236
268
  rec.text = String(settled.text || '').slice(0, 120);
237
269
  rec.error = settled.error ? settled.error.slice(0, 300) : undefined;
238
270
  rec.chars = String(settled.text || '').length;
@@ -282,17 +314,23 @@ const cases = routes.flatMap(([name, provider, model, efforts]) =>
282
314
  );
283
315
  const args = process.argv.slice(2);
284
316
  const suiteAt = args.findIndex((a) => a === '--suite' || a.startsWith('--suite='));
285
- const suite = suiteAt < 0 ? 'basic' : args[suiteAt].includes('=') ? args[suiteAt].split('=')[1] : args[suiteAt + 1];
317
+ let suite = 'basic';
318
+ if (suiteAt >= 0) suite = args[suiteAt].includes('=') ? args[suiteAt].split('=')[1] : args[suiteAt + 1];
286
319
  const extended = suite === 'extended';
287
320
  const realData = args.includes('--real-data');
288
321
  const only = args.filter(
289
- (a, i) => a !== '--real-data' && !a.startsWith('--suite') && !(suiteAt >= 0 && i === suiteAt + 1 && args[suiteAt] === '--suite')
322
+ (a, i) =>
323
+ a !== '--real-data' &&
324
+ !a.startsWith('--suite') &&
325
+ !(suiteAt >= 0 && i === suiteAt + 1 && args[suiteAt] === '--suite')
290
326
  );
291
327
  const chosen = only.length ? cases.filter(([name]) => only.includes(name)) : cases;
292
328
  // Refresh-capable OAuth logins are never exercised from an isolated copy.
293
329
  const isOauth = ([, provider]) => /-oauth$/.test(provider);
294
330
  const selected = realData ? chosen : chosen.filter((c) => !isOauth(c));
295
- for (const c of chosen) if (!selected.includes(c)) console.log(`SKIP ${c[0]} (OAuth provider; pass --real-data to run against the real data dir)`);
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)`);
296
334
  if (!selected.length) {
297
335
  console.log('nothing to run');
298
336
  process.exit(0);
@@ -302,7 +340,8 @@ if (!selected.length) {
302
340
  // secrets of the selected providers and the `agent` section of the real config.
303
341
  let isolated = null;
304
342
  if (!realData) {
305
- const realDataDir = process.env.MIXDOG_DATA_DIR || path.join(process.env.MIXDOG_HOME || path.join(os.homedir(), '.mixdog'), 'data');
343
+ const realDataDir =
344
+ process.env.MIXDOG_DATA_DIR || path.join(process.env.MIXDOG_HOME || path.join(os.homedir(), '.mixdog'), 'data');
306
345
  const home = fs.mkdtempSync(path.join(os.tmpdir(), 'mixdog-pp-home-'));
307
346
  const dataDir = path.join(home, 'data');
308
347
  fs.mkdirSync(path.join(dataDir, 'secrets'), { recursive: true });
@@ -353,7 +392,10 @@ process.on('exit', removeTemp);
353
392
  const makeCwd = (name) => {
354
393
  const cwd = fs.mkdtempSync(path.join(os.tmpdir(), `mixdog-pingpong-${name.replace(/[^a-z0-9]+/gi, '-')}-`));
355
394
  tempDirs.add(cwd);
356
- fs.writeFileSync(path.join(cwd, 'package.json'), JSON.stringify({ name: 'pingpong-probe', version: '1.0.0' }, null, 2));
395
+ fs.writeFileSync(
396
+ path.join(cwd, 'package.json'),
397
+ JSON.stringify({ name: 'pingpong-probe', version: '1.0.0' }, null, 2)
398
+ );
357
399
  fs.writeFileSync(path.join(cwd, 'a.txt'), 'alpha\n');
358
400
  fs.writeFileSync(path.join(cwd, 'b.txt'), 'beta\n');
359
401
  return cwd;
@@ -364,7 +406,19 @@ const runOne = ([name, provider, model, effort]) =>
364
406
  const cwd = makeCwd(name);
365
407
  const child = spawn(
366
408
  process.execPath,
367
- [self, '--child', JSON.stringify({ name, provider, model, effort, cwd, dataDir: isolated?.dataDir, suite: extended ? 'extended' : 'basic' })],
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
+ ],
368
422
  { stdio: ['ignore', 'pipe', 'pipe'], env: { ...process.env, ...isolated?.env } }
369
423
  );
370
424
  let stdout = '';
@@ -377,7 +431,9 @@ const runOne = ([name, provider, model, effort]) =>
377
431
  fs.rmSync(cwd, { recursive: true, force: true });
378
432
  tempDirs.delete(cwd);
379
433
  const line = stdout.split('\n').find((l) => l.startsWith('RESULT '));
380
- resolve(line ? JSON.parse(line.slice(7)) : { name, provider, model, effort, error: `no result: ${stderr.slice(-300)}` });
434
+ resolve(
435
+ line ? JSON.parse(line.slice(7)) : { name, provider, model, effort, error: `no result: ${stderr.slice(-300)}` }
436
+ );
381
437
  });
382
438
  });
383
439
 
@@ -400,7 +456,16 @@ const scenarios = [
400
456
  ['t2', 't2', (t) => has(t, /PINGPONG-PROBE/)],
401
457
  ['t3', 't3', (t) => (t.calls || []).filter((c) => c === 'read').length >= 1 && has(t, /alpha/i) && has(t, /beta/i)],
402
458
  // The reply language follows the user's profile (may be Korean), so the wording check is bilingual.
403
- ['er', 'err', (t) => called(t, 'read') && has(t, /missing|not exist|doesn.?t exist|does not|no such|not found|nonexistent|isn.?t|cannot|can.?t|존재하지|없|찾을 수|않/i)],
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
+ ],
404
469
  ['wr', 'wr', (t) => wroteVia(t) && String(t.disk ?? '').trim() === 'gamma'],
405
470
  ['sh', 'sh', (t) => called(t, 'shell') && has(t, /42/)],
406
471
  [
@@ -411,7 +476,13 @@ const scenarios = [
411
476
  const firstRead = c.indexOf('read');
412
477
  const write = c.findIndex((n, i) => i > firstRead && /edit|write|patch/i.test(n));
413
478
  const lastRead = c.lastIndexOf('read');
414
- return firstRead >= 0 && write > firstRead && lastRead > write && String(t.disk ?? '').trim() === 'ahpla' && has(t, /ahpla/);
479
+ return (
480
+ firstRead >= 0 &&
481
+ write > firstRead &&
482
+ lastRead > write &&
483
+ String(t.disk ?? '').trim() === 'ahpla' &&
484
+ has(t, /ahpla/)
485
+ );
415
486
  },
416
487
  ],
417
488
  ['im', 'img', (t) => has(t, /red/i)],
@@ -419,13 +490,17 @@ const scenarios = [
419
490
  ['fu', 'fu', (t) => has(t, /READY/i)],
420
491
  ];
421
492
 
422
- const short = (s, n = 60) => String(s || '').replace(/\s+/g, ' ').slice(0, n);
493
+ const short = (s, n = 60) =>
494
+ String(s || '')
495
+ .replace(/\s+/g, ' ')
496
+ .slice(0, n);
423
497
  const evidence = (key, t) => {
424
498
  if (!t) return 'no turn';
425
499
  if (t.error && key !== 'ca') return `error: ${short(t.error, 90)}`;
426
500
  const base = `[${(t.calls || []).join(',')}] "${short(t.text)}"`;
427
501
  if (key === 'wr' || key === 'ml') return `${base} disk=${JSON.stringify(short(t.disk ?? null, 20))}`;
428
- if (key === 'ca') return `abort=${t.abortResult} settle=${t.settle} deltas=${t.deltas} chars=${t.chars} ${t.error ? `err="${short(t.error, 70)}"` : ''}`;
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)}"` : ''}`;
429
504
  return base;
430
505
  };
431
506
 
@@ -460,13 +535,20 @@ for (const r of results) {
460
535
  }
461
536
  }
462
537
  const turns = Object.entries(r.turns || {});
463
- const later = (r.order || []).slice(1).map((k) => r.turns[k]).filter((t) => t?.usage);
538
+ const later = (r.order || [])
539
+ .slice(1)
540
+ .map((k) => r.turns[k])
541
+ .filter((t) => t?.usage);
464
542
  const sum = (f) => later.reduce((n, t) => n + f(t.usage), 0);
465
543
  const events = (r.order || []).reduce((n, k) => n + (r.turns[k]?.usage?.events || 0), 0);
466
- const cache = !turns.length || !events
467
- ? 'cache=NO-USAGE'
468
- : `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(',')}]`;
469
- const verdict = r.error && !turns.length ? (ACCOUNT_RE.test(r.error) ? 'ACCOUNT' : 'FAIL') : anyFail ? 'FAIL' : anyAccount ? 'ACCOUNT' : 'PASS';
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';
470
552
  if (extended) {
471
553
  console.log(`${verdict.padEnd(7)} ${r.name.padEnd(30)} ${marks.join(' ')} ${cache}`);
472
554
  if (r.error) console.log(` error=${r.error}`);
@@ -478,8 +560,11 @@ for (const r of results) {
478
560
  return `${label}${ok ? '✓' : '✗'} ${t?.ms}ms [${t?.calls}] "${short(t?.text)}"`;
479
561
  };
480
562
  const pass = !r.error && verdict === 'PASS';
563
+ let label = 'FAIL';
564
+ if (pass) label = 'PASS';
565
+ else if (verdict === 'ACCOUNT') label = 'ACCOUNT';
481
566
  console.log(
482
- `${pass ? 'PASS' : verdict === 'ACCOUNT' ? 'ACCOUNT' : 'FAIL'} ${r.name.padEnd(30)} ` +
567
+ `${label} ${r.name.padEnd(30)} ` +
483
568
  (r.error ? `error=${r.error}` : `${turn('t1', 't1')} | ${turn('t2', 't2')} | ${turn('t3', 't3')}`)
484
569
  );
485
570
  }
@@ -488,9 +573,10 @@ for (const r of results) {
488
573
  if (extended) {
489
574
  // Oddities worth a manual look: model identity, usage presence, notices mixed into answers.
490
575
  console.log('\n--- NON-PASS DETAILS (raw) ---');
576
+ const markNames = { A: 'ACCOUNT', '?': 'UNVERIFIED' };
491
577
  for (const { r, label, mark, t } of details) {
492
578
  console.log(
493
- `[${mark === 'A' ? 'ACCOUNT' : mark === '?' ? 'UNVERIFIED' : 'FAIL'}] ${r.provider}/${r.model} effort=${r.effort ?? '-'} ${label}: ` +
579
+ `[${markNames[mark] ?? 'FAIL'}] ${r.provider}/${r.model} effort=${r.effort ?? '-'} ${label}: ` +
494
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)}`
495
581
  );
496
582
  }
@@ -498,11 +584,15 @@ if (extended) {
498
584
  for (const r of results) {
499
585
  for (const key of r.order || []) {
500
586
  const t = r.turns[key];
501
- if (t?.models?.length && !t.models.some((m) => m === r.model || m.endsWith(`/${r.model}`) || m.includes(r.model) || r.model.includes(m)))
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
+ )
502
591
  console.log(`${r.name} ${key}: served model ${JSON.stringify(t.models)} != requested ${r.model}`);
503
592
  if (/notice|overloaded|retrying|fallback|server error|temporarily/i.test(t?.text || ''))
504
593
  console.log(`${r.name} ${key}: notice-like text ${JSON.stringify(t.text)}`);
505
- if (t && !t.skipped && !t.error && t.usage && t.usage.events === 0) console.log(`${r.name} ${key}: no usage events`);
594
+ if (t && !t.skipped && !t.error && t.usage && t.usage.events === 0)
595
+ console.log(`${r.name} ${key}: no usage events`);
506
596
  }
507
597
  }
508
598
  }
@@ -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: Maintainer
3
- description: Use for internal Git operations, memory upkeep, session naming, and other Mixdog background operations.
3
+ description: Use for memory upkeep, session naming, and other Mixdog background operations.
4
4
  permission: read-write
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "maintainer",
3
3
  "name": "Maintainer",
4
- "description": "Use for internal Git operations, memory upkeep, session naming, and other Mixdog background operations.",
4
+ "description": "Use for memory upkeep, session naming, and other Mixdog background operations.",
5
5
  "entry": "AGENT.md"
6
6
  }
@@ -13,7 +13,5 @@ criteria with independent judgment. Run the necessary builds, tests, lint, or
13
13
  runtime checks and actively seek regressions, unsupported assumptions, security
14
14
  risks, and counterexamples.
15
15
 
16
- Do not modify files or reimplement the change. Report actionable findings first,
17
- severity-ordered, one line per finding with evidence located by path and
18
- function or symbol. If clean, say so
19
- in one line and include only material residual risk.
16
+ Do not modify files or reimplement the change. Result lists actionable
17
+ findings first, severity-ordered, one line each; if clean, say so in one line.
@@ -10,6 +10,5 @@ data flow. Base every finding on concrete evidence and distinguish confirmed
10
10
  vulnerabilities from residual risk. Do not modify files during an audit unless
11
11
  the brief explicitly requests remediation.
12
12
 
13
- Report severity, exploitability, evidence located by path and function or
14
- symbol, impact, and the
13
+ Each finding in Result adds severity, exploitability, impact, and the
15
14
  smallest actionable recommendation. Avoid speculation and exaggerated claims.
@@ -9,6 +9,5 @@ Preserve meaning, facts, terminology, formatting, and intended audience while
9
9
  making the writing natural and consistent with the document's tone. Translate
10
10
  idiomatically rather than word-for-word.
11
11
 
12
- Do not invent facts or add commentary. Return final copy
13
- only unless the brief explicitly assigns file edits; then hand off changed
14
- paths.
12
+ Do not invent facts or add commentary. Result is the final copy, unless the
13
+ brief assigns file edits; then Evidence lists the changed paths.
@@ -20,12 +20,14 @@
20
20
  "f1662590203b5ad1521f8a8a78236521"
21
21
  ],
22
22
  "maintainer": [
23
+ "55f78dc59d7bc517bec44c6c59e99540",
23
24
  "602a50f142a4e244912547298ad8e512",
24
25
  "62b2ecd8496b64b4653f031ec75b0e50",
25
26
  "c25f03972df1ccfd2ed602ab23d2afae"
26
27
  ],
27
28
  "reviewer": [
28
29
  "07643b62440d3eba29b7360b8a33f09f",
30
+ "0d45f8d9a2a67373462840e8bf930694",
29
31
  "25b44b46269490e26ca31c1852925171",
30
32
  "a60ea68f9287d55489e92e5450432f62",
31
33
  "a61cb4557def4e7ed647d4bdacbb72e4",
@@ -36,7 +38,8 @@
36
38
  ],
37
39
  "security": [
38
40
  "50d9fd43dab8deff3b90c5b1096167e3",
39
- "54de597d001d4965c4b846f90960ebf2"
41
+ "54de597d001d4965c4b846f90960ebf2",
42
+ "b8ef431ca17f35e48837f8942eab7e4e"
40
43
  ],
41
44
  "webhook-handler": [
42
45
  "bd6765c2188681ff5a8114edcb3a21be"
@@ -48,6 +51,7 @@
48
51
  ],
49
52
  "writer": [
50
53
  "8273086982cacdd090e3bd129cd5fa0b",
54
+ "9ce2d5bc1f61bb6be8894b1c59097ec8",
51
55
  "bb1784ff9a28c1b4c96db706a24ddab6"
52
56
  ]
53
57
  },
@@ -248,6 +252,7 @@
248
252
  ],
249
253
  "image": [
250
254
  "2052d09860dfa293f239952d6e91d051",
255
+ "26b6574dffea7efefb8062b6be75bd8c",
251
256
  "c1a7863f99f8c57bd6c6dc4f05228d06",
252
257
  "de167d9432b970379e4ba6819416ebbc",
253
258
  "e30b8db5872d14039f3ce96a48a0e711",