mixdog 0.9.63 → 0.9.65

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 (408) hide show
  1. package/README.md +3 -0
  2. package/package.json +9 -2
  3. package/scripts/code-graph-description-contract.mjs +3 -3
  4. package/scripts/verify-release-assets.mjs +2 -2
  5. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +11 -14
  6. package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -6
  7. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -2
  8. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +1 -0
  9. package/src/runtime/agent/orchestrator/config.mjs +19 -124
  10. package/src/runtime/agent/orchestrator/context/collect.mjs +6 -6
  11. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +2 -2
  12. package/src/runtime/agent/orchestrator/internal-agents.mjs +2 -2
  13. package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +1 -1
  14. package/src/runtime/agent/orchestrator/mcp/client.mjs +4 -4
  15. package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +2 -2
  16. package/src/runtime/agent/orchestrator/providers/anthropic-betas.mjs +4 -4
  17. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +2 -2
  18. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +4 -4
  19. package/src/runtime/agent/orchestrator/providers/anthropic-messages.mjs +333 -0
  20. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +2 -2
  21. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -4
  22. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +1 -1
  23. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +3 -277
  24. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +2 -2
  25. package/src/runtime/agent/orchestrator/providers/custom-tool-wire.mjs +1 -1
  26. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +2 -2
  27. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +6 -6
  28. package/src/runtime/agent/orchestrator/providers/grok-oauth-login.mjs +196 -0
  29. package/src/runtime/agent/orchestrator/providers/grok-oauth-tokens.mjs +460 -0
  30. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +14 -593
  31. package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +1 -1
  32. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +1 -1
  33. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +1 -1
  34. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +4 -4
  35. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2 -2
  36. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +5 -280
  37. package/src/runtime/agent/orchestrator/providers/openai-responses-payload.mjs +357 -0
  38. package/src/runtime/agent/orchestrator/providers/openai-ws-headers.mjs +216 -0
  39. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +2 -188
  40. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +2 -2
  41. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -2
  42. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +1 -1
  43. package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +1 -1
  44. package/src/runtime/agent/orchestrator/providers/registry.mjs +1 -1
  45. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +2 -2
  46. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +1 -1
  48. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +3 -3
  49. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +2 -2
  50. package/src/runtime/agent/orchestrator/session/compact/file-reattach.mjs +2 -2
  51. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +1 -1
  52. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +1 -1
  53. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +2 -2
  54. package/src/runtime/agent/orchestrator/session/context-utils.mjs +4 -4
  55. package/src/runtime/agent/orchestrator/session/loop/deferred-call-through.mjs +1 -1
  56. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +17 -0
  57. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +1 -1
  58. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +18 -26
  59. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +1 -1
  60. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +3 -3
  61. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +1 -0
  62. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +1 -1
  63. package/src/runtime/agent/orchestrator/session/manager/delivered-completions.mjs +1 -1
  64. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +1 -1
  65. package/src/runtime/agent/orchestrator/session/store/live-state.mjs +49 -0
  66. package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +49 -0
  67. package/src/runtime/agent/orchestrator/session/store/save-worker.mjs +260 -0
  68. package/src/runtime/agent/orchestrator/session/store/serialize.mjs +72 -0
  69. package/src/runtime/agent/orchestrator/session/store/summary-cache.mjs +163 -0
  70. package/src/runtime/agent/orchestrator/session/store/write-guards.mjs +1 -1
  71. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +1 -1
  72. package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +4 -1
  73. package/src/runtime/agent/orchestrator/session/store.mjs +9 -561
  74. package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +1 -1
  75. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +2 -2
  76. package/src/runtime/agent/orchestrator/stall-policy.mjs +11 -11
  77. package/src/runtime/agent/orchestrator/tools/bash-policy-scan.mjs +1 -1
  78. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +2 -2
  79. package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +1 -1
  80. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +2 -2
  81. package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +1 -1
  82. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +2 -154
  83. package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +1 -1
  84. package/src/runtime/agent/orchestrator/tools/builtin/cwd-utils.mjs +1 -1
  85. package/src/runtime/agent/orchestrator/tools/builtin/fs-reachability.mjs +1 -1
  86. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
  87. package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +1 -1
  88. package/src/runtime/agent/orchestrator/tools/builtin/path-locks.mjs +1 -1
  89. package/src/runtime/agent/orchestrator/tools/builtin/path-utils.mjs +1 -1
  90. package/src/runtime/agent/orchestrator/tools/builtin/read-args.mjs +2 -2
  91. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +2 -3
  92. package/src/runtime/agent/orchestrator/tools/builtin/read-image-resize.mjs +4 -4
  93. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +1 -1
  94. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +1 -1
  95. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +2 -2
  96. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +5 -5
  97. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
  98. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +2 -2
  99. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +2 -2
  100. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-spawn.mjs +519 -0
  101. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +5 -449
  102. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +1 -1
  103. package/src/runtime/agent/orchestrator/tools/builtin/task-tool.mjs +212 -0
  104. package/src/runtime/agent/orchestrator/tools/builtin.mjs +1 -1
  105. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +1 -7
  106. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +9 -36
  107. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +15 -3
  108. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.mjs +429 -0
  109. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +2 -395
  110. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +2 -2
  111. package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +1 -1
  112. package/src/runtime/agent/orchestrator/tools/code-graph/trusted-roots.mjs +1 -1
  113. package/src/runtime/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +1 -1
  114. package/src/runtime/agent/orchestrator/tools/code-graph-state.mjs +3 -3
  115. package/src/runtime/agent/orchestrator/tools/mutation-planner.mjs +5 -5
  116. package/src/runtime/agent/orchestrator/tools/next-call-utils.mjs +1 -1
  117. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +1 -1
  118. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +7 -7
  119. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +72 -9
  120. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +4 -4
  121. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +1 -1
  122. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +1 -1
  123. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +4 -4
  124. package/src/runtime/agent/orchestrator/tools/patch.mjs +1 -1
  125. package/src/runtime/agent/orchestrator/tools/result-compression.mjs +3 -3
  126. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +2 -444
  127. package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +505 -0
  128. package/src/runtime/agent/orchestrator/tools/shell-exec-policy.mjs +2 -2
  129. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +1 -1
  130. package/src/runtime/channels/lib/backend-dispatch.mjs +20 -5
  131. package/src/runtime/channels/lib/scheduler.mjs +1 -1
  132. package/src/runtime/channels/lib/telegram-format.mjs +1 -1
  133. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +4 -4
  134. package/src/runtime/channels/tool-defs.mjs +2 -3
  135. package/src/runtime/memory/index.mjs +1 -5
  136. package/src/runtime/memory/lib/core-memory-candidates.mjs +357 -0
  137. package/src/runtime/memory/lib/core-memory-store.mjs +7 -357
  138. package/src/runtime/memory/lib/cycle-signatures.mjs +1 -1
  139. package/src/runtime/memory/lib/embedding-model-config.mjs +1 -1
  140. package/src/runtime/memory/lib/embedding-provider.mjs +1 -5
  141. package/src/runtime/memory/lib/embedding-worker.mjs +1 -5
  142. package/src/runtime/memory/lib/ko-morph.mjs +2 -2
  143. package/src/runtime/memory/lib/memory-config-flags.mjs +2 -5
  144. package/src/runtime/memory/lib/memory-cycle-requests.mjs +3 -7
  145. package/src/runtime/memory/lib/memory-cycle1.mjs +4 -8
  146. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +1 -1
  147. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +1 -1
  148. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +2 -5
  149. package/src/runtime/memory/lib/memory-cycle3.mjs +1 -5
  150. package/src/runtime/memory/lib/memory-embed.mjs +2 -6
  151. package/src/runtime/memory/lib/memory-log.mjs +8 -0
  152. package/src/runtime/memory/lib/memory-ops-policy.mjs +4 -8
  153. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +1 -1
  154. package/src/runtime/memory/lib/memory-recall-store.mjs +2 -193
  155. package/src/runtime/memory/lib/memory-score.mjs +1 -1
  156. package/src/runtime/memory/lib/memory-text-utils.mjs +2 -2
  157. package/src/runtime/memory/lib/memory.mjs +2 -6
  158. package/src/runtime/memory/lib/pg/adapter.mjs +2 -6
  159. package/src/runtime/memory/lib/pg/process.mjs +1 -5
  160. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -5
  161. package/src/runtime/memory/lib/recall-format.mjs +2 -2
  162. package/src/runtime/memory/lib/recall-scoring.mjs +195 -0
  163. package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -5
  164. package/src/runtime/memory/lib/trace-store.mjs +2 -6
  165. package/src/runtime/search/lib/http-fetch.mjs +6 -6
  166. package/src/runtime/search/lib/web-tools.mjs +2 -2
  167. package/src/runtime/shared/buffered-appender.mjs +1 -1
  168. package/src/runtime/shared/child-guardian.mjs +1 -1
  169. package/src/runtime/shared/child-spawn-gate.mjs +1 -1
  170. package/src/runtime/shared/config.mjs +4 -4
  171. package/src/runtime/shared/launcher-control.mjs +9 -10
  172. package/src/runtime/shared/llm/index.mjs +5 -20
  173. package/src/runtime/shared/markdown-frontmatter.mjs +1 -1
  174. package/src/runtime/shared/memory-snapshot.mjs +4 -4
  175. package/src/runtime/shared/pristine-execution.mjs +1 -1
  176. package/src/runtime/shared/process-lifecycle.mjs +0 -1
  177. package/src/runtime/shared/process-shutdown.mjs +1 -1
  178. package/src/runtime/shared/resource-admission.mjs +2 -2
  179. package/src/runtime/shared/schedule-session-run.mjs +1 -1
  180. package/src/runtime/shared/schedules-db.mjs +1 -1
  181. package/src/runtime/shared/service-discovery.mjs +2 -2
  182. package/src/runtime/shared/staged-update.mjs +6 -6
  183. package/src/runtime/shared/tool-execution-contract.mjs +1 -1
  184. package/src/runtime/shared/tool-primitives.mjs +1 -1
  185. package/src/runtime/shared/tool-surface.mjs +2 -2
  186. package/src/runtime/shared/turn-snapshot.mjs +184 -0
  187. package/src/runtime/shared/update-checker.mjs +1 -1
  188. package/src/runtime/shared/user-cwd.mjs +3 -3
  189. package/src/runtime/shared/user-data-guard.mjs +4 -4
  190. package/src/runtime/shared/workspace-router.mjs +5 -5
  191. package/src/session-runtime/config-helpers.mjs +2 -3
  192. package/src/session-runtime/config-lifecycle.mjs +1 -1
  193. package/src/session-runtime/hitch-profile.mjs +1 -1
  194. package/src/session-runtime/lifecycle-api.mjs +6 -4
  195. package/src/session-runtime/model-recency.mjs +5 -5
  196. package/src/session-runtime/plugin-mcp.mjs +1 -1
  197. package/src/session-runtime/provider-request-snapshot.mjs +338 -0
  198. package/src/session-runtime/runtime-core.mjs +4 -0
  199. package/src/session-runtime/session-text.mjs +4 -4
  200. package/src/session-runtime/session-turn-api.mjs +7 -0
  201. package/src/session-runtime/tool-catalog-schema.mjs +197 -0
  202. package/src/session-runtime/tool-catalog.mjs +6 -483
  203. package/src/session-runtime/tool-defs.mjs +1 -1
  204. package/src/standalone/agent-task-status.mjs +1 -1
  205. package/src/standalone/agent-tool/helpers.mjs +2 -2
  206. package/src/standalone/channel-admin.mjs +4 -4
  207. package/src/standalone/explore-tool.mjs +3 -3
  208. package/src/standalone/hook-bus/config.mjs +1 -1
  209. package/src/standalone/hook-bus/constants.mjs +1 -1
  210. package/src/standalone/hook-bus/rules.mjs +1 -1
  211. package/src/standalone/projects.mjs +1 -1
  212. package/src/standalone/provider-admin.mjs +2 -2
  213. package/src/tui/App.jsx +1 -1
  214. package/src/tui/app/app-format.mjs +2 -2
  215. package/src/tui/app/clipboard.mjs +3 -3
  216. package/src/tui/app/input-parsers.mjs +1 -1
  217. package/src/tui/app/text-layout.mjs +1 -1
  218. package/src/tui/app/transcript-row-estimate.mjs +360 -0
  219. package/src/tui/app/transcript-window.mjs +5 -347
  220. package/src/tui/app/use-mouse-input.mjs +1 -1
  221. package/src/tui/app/use-prompt-handlers.mjs +1 -1
  222. package/src/tui/components/tool-execution/surface-detail.mjs +9 -9
  223. package/src/tui/components/tool-execution/text-format.mjs +2 -2
  224. package/src/tui/components/tool-output-format.mjs +7 -7
  225. package/src/tui/display-width.mjs +4 -4
  226. package/src/tui/dist/index.mjs +187 -99
  227. package/src/tui/engine/agent-envelope.mjs +5 -5
  228. package/src/tui/engine/live-share.mjs +100 -0
  229. package/src/tui/engine/notification-plan.mjs +1 -1
  230. package/src/tui/engine/queue-helpers.mjs +3 -3
  231. package/src/tui/engine/render-timing.mjs +4 -5
  232. package/src/tui/engine/session-api-ext.mjs +6 -3
  233. package/src/tui/engine/tool-result-status.mjs +5 -5
  234. package/src/tui/engine/tool-result-text.mjs +1 -1
  235. package/src/tui/engine/transcript-spill.mjs +585 -0
  236. package/src/tui/engine/tui-steering-persist.mjs +1 -1
  237. package/src/tui/engine.mjs +29 -474
  238. package/src/tui/lib/voice-setup.mjs +1 -1
  239. package/src/tui/markdown/format-token.mjs +1 -1
  240. package/src/tui/markdown/render-ansi.mjs +1 -1
  241. package/src/tui/markdown/table-layout.mjs +4 -4
  242. package/src/tui/paste-attachments.mjs +1 -1
  243. package/src/tui/prompt-history-store.mjs +3 -3
  244. package/src/tui/statusline-ansi-bridge.mjs +2 -2
  245. package/src/tui/theme.mjs +1 -1
  246. package/src/tui/transcript-tool-failures.mjs +2 -2
  247. package/src/ui/ansi.mjs +0 -9
  248. package/src/ui/statusline-format.mjs +2 -4
  249. package/scripts/_bench-cwc.json +0 -20
  250. package/scripts/_jitter-fuzz.jsx +0 -42
  251. package/scripts/_jitter-fuzz2.jsx +0 -30
  252. package/scripts/_jitter-probe.jsx +0 -35
  253. package/scripts/_jp2.jsx +0 -16
  254. package/scripts/_smoke_wd.mjs +0 -7
  255. package/scripts/abort-recovery-test.mjs +0 -175
  256. package/scripts/agent-dispatch-abort-compose-test.mjs +0 -31
  257. package/scripts/agent-live-arg-guard-smoke.mjs +0 -20
  258. package/scripts/agent-live-path-suffix-smoke.mjs +0 -34
  259. package/scripts/agent-live-toolcall-args-smoke.mjs +0 -45
  260. package/scripts/agent-loop-policy-test.mjs +0 -37
  261. package/scripts/agent-model-liveness-test.mjs +0 -763
  262. package/scripts/agent-parallel-smoke.mjs +0 -435
  263. package/scripts/agent-route-batch-test.mjs +0 -40
  264. package/scripts/agent-tag-reuse-smoke.mjs +0 -441
  265. package/scripts/agent-terminal-reap-test.mjs +0 -252
  266. package/scripts/agent-trace-io-test.mjs +0 -133
  267. package/scripts/ansi-color-capability-test.mjs +0 -90
  268. package/scripts/anthropic-admission-retry-integration-test.mjs +0 -119
  269. package/scripts/anthropic-maxtokens-test.mjs +0 -119
  270. package/scripts/anthropic-oauth-refresh-race-test.mjs +0 -397
  271. package/scripts/anthropic-transport-policy-test.mjs +0 -726
  272. package/scripts/apply-patch-edit-smoke.mjs +0 -71
  273. package/scripts/arg-guard-test.mjs +0 -93
  274. package/scripts/async-notify-settlement-test.mjs +0 -99
  275. package/scripts/atomic-lock-tryonce-test.mjs +0 -125
  276. package/scripts/background-task-meta-smoke.mjs +0 -38
  277. package/scripts/bench-run.mjs +0 -508
  278. package/scripts/boot-smoke.mjs +0 -137
  279. package/scripts/build-runtime-windows.ps1 +0 -242
  280. package/scripts/channel-daemon-smoke.mjs +0 -1103
  281. package/scripts/code-graph-aggregate-cwd-test.mjs +0 -158
  282. package/scripts/code-graph-disk-hit-test.mjs +0 -290
  283. package/scripts/code-graph-dispatch-test.mjs +0 -96
  284. package/scripts/code-graph-root-federation-test.mjs +0 -273
  285. package/scripts/compact-active-turn-test.mjs +0 -68
  286. package/scripts/compact-file-reattach-test.mjs +0 -88
  287. package/scripts/compact-pressure-test.mjs +0 -788
  288. package/scripts/compact-prior-context-flatten-test.mjs +0 -252
  289. package/scripts/compact-recall-digest-test.mjs +0 -57
  290. package/scripts/compact-smoke.mjs +0 -1017
  291. package/scripts/compact-trigger-migration-smoke.mjs +0 -261
  292. package/scripts/compacted-placeholder-scrub-test.mjs +0 -63
  293. package/scripts/context-mcp-metering-test.mjs +0 -1406
  294. package/scripts/debounced-skills-async-save-test.mjs +0 -57
  295. package/scripts/deferred-tool-loading-test.mjs +0 -250
  296. package/scripts/desktop-session-bridge-test.mjs +0 -1013
  297. package/scripts/dispatch-persist-recovery-test.mjs +0 -141
  298. package/scripts/embedding-worker-exit-test.mjs +0 -76
  299. package/scripts/execution-completion-dedup-test.mjs +0 -205
  300. package/scripts/execution-pending-resume-kick-test.mjs +0 -151
  301. package/scripts/execution-resume-esc-integration-test.mjs +0 -176
  302. package/scripts/explore-bench-tmp.mjs +0 -36
  303. package/scripts/explore-bench.mjs +0 -248
  304. package/scripts/explore-prompt-policy-test.mjs +0 -256
  305. package/scripts/explore-timeout-cancel-test.mjs +0 -345
  306. package/scripts/find-fuzzy-hidden-test.mjs +0 -267
  307. package/scripts/forwarder-rebind-tail-test.mjs +0 -67
  308. package/scripts/freevar-smoke.mjs +0 -98
  309. package/scripts/gemini-provider-test.mjs +0 -1448
  310. package/scripts/generate-oc-icons.mjs +0 -11
  311. package/scripts/grok-oauth-refresh-race-test.mjs +0 -273
  312. package/scripts/headless-pristine-execution-test.mjs +0 -614
  313. package/scripts/hook-bus-test.mjs +0 -552
  314. package/scripts/ingest-pure-conversation-smoke.mjs +0 -175
  315. package/scripts/internal-comms-bench-test.mjs +0 -226
  316. package/scripts/internal-comms-bench.mjs +0 -853
  317. package/scripts/internal-comms-smoke.mjs +0 -277
  318. package/scripts/internal-tools-normalization-test.mjs +0 -62
  319. package/scripts/interrupted-turn-history-test.mjs +0 -399
  320. package/scripts/lead-workflow-smoke.mjs +0 -592
  321. package/scripts/lifecycle-api-test.mjs +0 -137
  322. package/scripts/live-share-test.mjs +0 -148
  323. package/scripts/live-worker-smoke.mjs +0 -333
  324. package/scripts/log-writer-guard-smoke.mjs +0 -131
  325. package/scripts/maintenance-default-routes-test.mjs +0 -164
  326. package/scripts/max-output-recovery-persist-test.mjs +0 -81
  327. package/scripts/max-output-recovery-test.mjs +0 -368
  328. package/scripts/mcp-client-normalization-test.mjs +0 -45
  329. package/scripts/mcp-grace-deferred-test.mjs +0 -225
  330. package/scripts/memory-core-input-test.mjs +0 -167
  331. package/scripts/memory-cycle-routing-test.mjs +0 -111
  332. package/scripts/memory-meta-concurrency-test.mjs +0 -20
  333. package/scripts/memory-pg-recovery-test.mjs +0 -59
  334. package/scripts/memory-rule-contract-test.mjs +0 -93
  335. package/scripts/model-list-sanitize-test.mjs +0 -37
  336. package/scripts/mouse-tracking-restore-smoke.mjs +0 -107
  337. package/scripts/native-edit-wire-test.mjs +0 -152
  338. package/scripts/notify-completion-mirror-test.mjs +0 -73
  339. package/scripts/openai-oauth-refresh-race-test.mjs +0 -120
  340. package/scripts/openai-oauth-ws-1006-retry-test.mjs +0 -954
  341. package/scripts/openai-ws-early-settle-test.mjs +0 -216
  342. package/scripts/output-style-bench.mjs +0 -292
  343. package/scripts/output-style-smoke.mjs +0 -145
  344. package/scripts/parent-abort-link-test.mjs +0 -90
  345. package/scripts/patch-binary-cache-test.mjs +0 -181
  346. package/scripts/path-suffix-test.mjs +0 -57
  347. package/scripts/pending-completion-drop-test.mjs +0 -239
  348. package/scripts/pending-messages-lock-nonblocking-test.mjs +0 -62
  349. package/scripts/pretool-ask-runtime-test.mjs +0 -54
  350. package/scripts/process-lifecycle-test.mjs +0 -461
  351. package/scripts/prompt-immediate-render-test.mjs +0 -89
  352. package/scripts/prompt-input-parity-test.mjs +0 -145
  353. package/scripts/provider-admission-scheduler-test.mjs +0 -681
  354. package/scripts/provider-contract-test.mjs +0 -632
  355. package/scripts/provider-stream-stall-test.mjs +0 -276
  356. package/scripts/provider-toolcall-test.mjs +0 -3063
  357. package/scripts/reactive-compact-persist-smoke.mjs +0 -203
  358. package/scripts/recall-bench.mjs +0 -359
  359. package/scripts/resource-admission-test.mjs +0 -792
  360. package/scripts/result-classification-test.mjs +0 -75
  361. package/scripts/rg-runner-test.mjs +0 -240
  362. package/scripts/routing-corpus-test.mjs +0 -349
  363. package/scripts/sanitize-tool-pairs-test.mjs +0 -260
  364. package/scripts/session-bench-cache-break-test.mjs +0 -102
  365. package/scripts/session-bench.mjs +0 -1708
  366. package/scripts/session-context-bench.mjs +0 -344
  367. package/scripts/session-heartbeat-lifecycle-test.mjs +0 -68
  368. package/scripts/session-ingest-compaction-smoke.mjs +0 -279
  369. package/scripts/session-ingest-smoke.mjs +0 -177
  370. package/scripts/session-orphan-sweep-test.mjs +0 -109
  371. package/scripts/set-effort-config-test.mjs +0 -41
  372. package/scripts/shell-failure-diagnostics-test.mjs +0 -280
  373. package/scripts/shell-hardening-test.mjs +0 -209
  374. package/scripts/shell-jobs-windows-hide-test.mjs +0 -164
  375. package/scripts/ship-mode-test.mjs +0 -98
  376. package/scripts/smoke-loop-failure-summary-test.mjs +0 -38
  377. package/scripts/smoke-loop-failure-summary.mjs +0 -16
  378. package/scripts/smoke-loop-report.mjs +0 -221
  379. package/scripts/smoke-loop.mjs +0 -202
  380. package/scripts/smoke-runtime-negative.ps1 +0 -106
  381. package/scripts/statusline-quota-hysteresis-test.mjs +0 -62
  382. package/scripts/steering-drain-buckets-test.mjs +0 -467
  383. package/scripts/steering-fold-provenance-test.mjs +0 -71
  384. package/scripts/streaming-tail-window-test.mjs +0 -175
  385. package/scripts/submit-commandbusy-race-test.mjs +0 -257
  386. package/scripts/task-bench.mjs +0 -205
  387. package/scripts/terminal-bench-isolation-guards-test.mjs +0 -102
  388. package/scripts/termio-input-smoke.mjs +0 -199
  389. package/scripts/tool-result-hook-test.mjs +0 -48
  390. package/scripts/tool-smoke.mjs +0 -2453
  391. package/scripts/tool-tui-presentation-test.mjs +0 -286
  392. package/scripts/toolcall-args-test.mjs +0 -239
  393. package/scripts/tui-ambiguous-width-test.mjs +0 -113
  394. package/scripts/tui-background-failure-smoke.mjs +0 -73
  395. package/scripts/tui-perf-run.ps1 +0 -26
  396. package/scripts/tui-render-smoke.mjs +0 -90
  397. package/scripts/tui-runtime-load-bench-entry.jsx +0 -608
  398. package/scripts/tui-runtime-load-bench.mjs +0 -50
  399. package/scripts/tui-store-frame-batch-test.mjs +0 -99
  400. package/scripts/tui-transcript-jitter-harness-entry.jsx +0 -383
  401. package/scripts/tui-transcript-perf-test.mjs +0 -934
  402. package/scripts/usage-metrics-epoch-smoke.mjs +0 -114
  403. package/scripts/verify-release-assets-test.mjs +0 -281
  404. package/scripts/web-fetch-routing-test.mjs +0 -158
  405. package/scripts/webhook-smoke.mjs +0 -201
  406. package/scripts/windows-hide-spawn-options-test.mjs +0 -19
  407. package/scripts/worker-notify-rejection-test.mjs +0 -51
  408. package/scripts/write-backpressure-test.mjs +0 -147
@@ -294,7 +294,7 @@ export function updateConfig(updater) {
294
294
  return saved
295
295
  }
296
296
 
297
- export function writeSection(section, data) {
297
+ function writeSection(section, data) {
298
298
  withConfigLock(() => {
299
299
  const all = readAllForRmW()
300
300
  all[section] = stripGeneratedMarker(data)
@@ -383,7 +383,7 @@ export function updateConfigAsync(updater) {
383
383
  })
384
384
  }
385
385
 
386
- export function writeSectionAsync(section, data) {
386
+ function writeSectionAsync(section, data) {
387
387
  return trackConfigWrite(() => withConfigLockAsync(async () => {
388
388
  const all = readAllForRmW()
389
389
  all[section] = stripGeneratedMarker(data)
@@ -427,7 +427,7 @@ function readCapabilities() {
427
427
  // Convenience alias requested by B2 call-site plumbing. Returns the
428
428
  // same object shape as readCapabilities(); callers that only need a
429
429
  // boolean can read `.homeAccess` directly.
430
- export function getCapabilities() {
430
+ function getCapabilities() {
431
431
  return readCapabilities()
432
432
  }
433
433
 
@@ -443,7 +443,7 @@ export const SECRET_ACCOUNTS = Object.freeze({
443
443
  opencodeGoAuthCookie: 'agent.opencode-go.authCookie',
444
444
  })
445
445
 
446
- export function isDiscordSnowflake(value) {
446
+ function isDiscordSnowflake(value) {
447
447
  return /^\d{17,20}$/.test(String(value || '').trim())
448
448
  }
449
449
 
@@ -47,12 +47,11 @@ const RECORD_SEP = '\x1e';
47
47
 
48
48
  // Names the env vars the launcher must set on the child so this module's
49
49
  // managedLaunchId() resolves inside the MCP server.
50
- export const LAUNCHER_ENV = Object.freeze({ ENV_LAUNCH_ID, ENV_MANAGED });
51
50
 
52
51
  // Mirror of channels/lib/runtime-paths.mjs RUNTIME_ROOT resolution so the
53
52
  // launcher and the MCP server agree on the queue location without importing
54
53
  // the channels layer into setup/.
55
- export function launcherRuntimeRoot() {
54
+ function launcherRuntimeRoot() {
56
55
  return process.env.MIXDOG_RUNTIME_ROOT
57
56
  ? resolve(process.env.MIXDOG_RUNTIME_ROOT)
58
57
  : join(tmpdir(), 'mixdog');
@@ -62,7 +61,7 @@ function sanitize(value) {
62
61
  return String(value).replace(/[^a-zA-Z0-9._-]/g, '_');
63
62
  }
64
63
 
65
- export function launcherQueueDir(launchId) {
64
+ function launcherQueueDir(launchId) {
66
65
  return join(launcherRuntimeRoot(), `launch-cmds-${sanitize(launchId)}`);
67
66
  }
68
67
 
@@ -118,7 +117,7 @@ function nativeLaunchPrebuiltPath() {
118
117
  }
119
118
 
120
119
  let _nativeBinCache; // undefined = unresolved, string|null = resolved
121
- export function nativeLaunchBin() {
120
+ function nativeLaunchBin() {
122
121
  if (_nativeBinCache !== undefined) return _nativeBinCache;
123
122
  // Opt-out for tests / forced-JS parity checks.
124
123
  if (/^(0|false|no|off|js)$/i.test(String(process.env.MIXDOG_LAUNCH_NATIVE || ''))) {
@@ -141,7 +140,7 @@ export function nativeLaunchBin() {
141
140
  // Returns true when the native mixdog-launch binary's `bridge` subcommand is
142
141
  // available for this platform (exit 0). The launcher uses this to gate the
143
142
  // managed-launch interactive path — no JS stdin pipe bridge fallback.
144
- export function nativeBridgeAvailable() {
143
+ function nativeBridgeAvailable() {
145
144
  const bin = nativeLaunchBin();
146
145
  if (!bin) return false;
147
146
  const r = spawnSync(bin, ['bridge', '--probe'], {
@@ -151,7 +150,7 @@ export function nativeBridgeAvailable() {
151
150
  return r.status === 0;
152
151
  }
153
152
 
154
- export function newLaunchId() {
153
+ function newLaunchId() {
155
154
  return `${process.pid}-${randomUUID().slice(0, 8)}`;
156
155
  }
157
156
 
@@ -159,7 +158,7 @@ export function newLaunchId() {
159
158
  // `mixdog`-launched session that engaged the control bridge, else null. The
160
159
  // launcher only sets MIXDOG_LAUNCH_ID once the bridge is live, so presence is
161
160
  // sufficient — there is no half-managed state to disambiguate.
162
- export function managedLaunchId() {
161
+ function managedLaunchId() {
163
162
  const id = process.env[ENV_LAUNCH_ID];
164
163
  return id && String(id).length > 0 ? String(id) : null;
165
164
  }
@@ -170,7 +169,7 @@ let enqueueSequence = 0;
170
169
  // launcher to deliver. Prefers the canonical Rust backend; the JS writer (temp
171
170
  // name + rename so the watcher never sees a partial file) is the fallback.
172
171
  // Returns the published path.
173
- export function enqueueLauncherCommand(launchId, command) {
172
+ function enqueueLauncherCommand(launchId, command) {
174
173
  const dir = launcherQueueDir(launchId);
175
174
  mkdirSync(dir, { recursive: true });
176
175
  const bin = nativeLaunchBin();
@@ -196,7 +195,7 @@ export function enqueueLauncherCommand(launchId, command) {
196
195
  // Launcher side: drain queued commands oldest-first (lexical sort on the
197
196
  // timestamp-prefixed name), deleting each as it is read. Prefers the canonical
198
197
  // Rust backend; the JS reader is the fallback.
199
- export function drainLauncherCommands(launchId) {
198
+ function drainLauncherCommands(launchId) {
200
199
  const dir = launcherQueueDir(launchId);
201
200
  const bin = nativeLaunchBin();
202
201
  if (bin) {
@@ -236,7 +235,7 @@ export function drainLauncherCommands(launchId) {
236
235
  // platforms (and miss atomic-rename publishes on some) that a short poll is the
237
236
  // robust choice for this low-rate control path. Returns a stop() that also
238
237
  // removes the queue directory.
239
- export function watchLauncherCommands(launchId, onCommand, { intervalMs = 150 } = {}) {
238
+ function watchLauncherCommands(launchId, onCommand, { intervalMs = 150 } = {}) {
240
239
  mkdirSync(launcherQueueDir(launchId), { recursive: true });
241
240
  let stopped = false;
242
241
  const timer = setInterval(() => {
@@ -26,37 +26,22 @@ function loadAgentConfig() {
26
26
  /**
27
27
  * Resolve the maintenance model ROUTE for a given task from agent-config.
28
28
  *
29
- * Maintenance slots now store a direct `{provider, model, effort?, fast?}`
30
- * route (parity with `agents.<role>`). This returns that route object. For
31
- * backward compatibility a slot still holding a legacy preset-NAME string is
32
- * resolved against config.presets and returned as a route. Falls back to the
33
- * canonical DEFAULT_MAINTENANCE route. Returns null only when nothing resolves.
29
+ * Maintenance slots store a direct `{provider, model, effort?, fast?}` route
30
+ * (parity with `agents.<role>`). This returns that route object, falling back
31
+ * to the canonical DEFAULT_MAINTENANCE route. Returns null only when nothing
32
+ * resolves.
34
33
  *
35
34
  * The returned value is passed straight through as `opts.preset` to
36
- * makeAgentDispatch, whose resolveMaintenanceRoute()/maintenanceRouteToPreset()
37
- * accept either a route object or a legacy name string.
35
+ * makeAgentDispatch (resolveMaintenanceRoute()/maintenanceRouteToPreset()).
38
36
  */
39
37
  export function resolveMaintenancePreset(task, agentConfig) {
40
38
  const cfg = agentConfig || loadAgentConfig()
41
39
  const maint = cfg?.maintenance || {}
42
- const presets = cfg?.presets || []
43
40
  const slot = maint[task]
44
- // Preferred: slot already holds a direct route object.
45
41
  if (slot && typeof slot === 'object' && !Array.isArray(slot)
46
42
  && slot.provider && slot.model) {
47
43
  return { ...slot }
48
44
  }
49
- // Legacy: slot holds a preset-NAME string — resolve it to a route.
50
- const name = String(slot || '').trim()
51
- if (name) {
52
- const preset = presets.find(p => p && (p.id === name || p.name === name))
53
- if (preset && preset.provider && preset.model) {
54
- const route = { provider: preset.provider, model: preset.model }
55
- if (preset.effort) route.effort = preset.effort
56
- if (preset.fast === true) route.fast = true
57
- return route
58
- }
59
- }
60
45
  // Canonical default route (DEFAULT_MAINTENANCE is now route-shaped).
61
46
  const def = DEFAULT_MAINTENANCE[task]
62
47
  if (def && def.provider && def.model) return { ...def }
@@ -33,7 +33,7 @@ export function parseMarkdownFrontmatter(markdown) {
33
33
  return meta;
34
34
  }
35
35
 
36
- export function stripMarkdownFrontmatter(markdown) {
36
+ function stripMarkdownFrontmatter(markdown) {
37
37
  return String(markdown || '').replace(FRONTMATTER_RE, '').trim();
38
38
  }
39
39
 
@@ -14,7 +14,7 @@ import { withFileLock } from './atomic-file.mjs';
14
14
  import { resolvePluginData } from './plugin-paths.mjs';
15
15
 
16
16
  const execFileAsync = promisify(execFile);
17
- export const MEMORY_PRESSURE_SNAPSHOT_MAX_BYTES = 64 * 1024;
17
+ const MEMORY_PRESSURE_SNAPSHOT_MAX_BYTES = 64 * 1024;
18
18
  const SNAPSHOT_NAME = 'memory-pressure.jsonl';
19
19
  const SNAPSHOT_INTERVAL_MS = 10 * 60 * 1000;
20
20
  const SNAPSHOT_INTERVAL_JITTER_MS = 60 * 1000;
@@ -196,7 +196,7 @@ function baseSnapshot(reason) {
196
196
  * Collect a full attribution snapshot. Process enumeration failures are
197
197
  * intentionally omitted from the record, rather than surfacing to callers.
198
198
  */
199
- export async function captureMemoryPressureSnapshot(reason = 'memory-pressure') {
199
+ async function captureMemoryPressureSnapshot(reason = 'memory-pressure') {
200
200
  if (!enabled()) return false;
201
201
  const entry = baseSnapshot(reason);
202
202
  const processes = await topProcesses();
@@ -229,7 +229,7 @@ export function requestMemoryPressureSnapshot(reason) {
229
229
  }
230
230
  }
231
231
 
232
- export function armMemoryPressureSampling() {
232
+ function armMemoryPressureSampling() {
233
233
  if (!enabled() || periodicTimer) return false;
234
234
  periodicTimer = setInterval(() => {
235
235
  void capturePeriodicMemorySnapshot().catch(() => {});
@@ -238,7 +238,7 @@ export function armMemoryPressureSampling() {
238
238
  return true;
239
239
  }
240
240
 
241
- export function memoryPressureSnapshotPath() {
241
+ function memoryPressureSnapshotPath() {
242
242
  return snapshotPaths().snapshot;
243
243
  }
244
244
 
@@ -97,7 +97,7 @@ function cloneJson(value) {
97
97
  return JSON.parse(JSON.stringify(value));
98
98
  }
99
99
 
100
- export function createSelectedProviderPristineLoader({
100
+ function createSelectedProviderPristineLoader({
101
101
  config,
102
102
  provider,
103
103
  apiKey = null,
@@ -22,7 +22,6 @@ import { resolvePluginData } from './plugin-paths.mjs';
22
22
 
23
23
  const execFileAsync = promisify(execFile);
24
24
  export const LIFECYCLE_LEDGER_MAX_BYTES = 64 * 1024;
25
- export const LIFECYCLE_LEDGER_KEEP_FILES = 2;
26
25
  const LEDGER_NAME = 'process-lifecycle.jsonl';
27
26
  const MARKER_DIR_NAME = 'process-lifecycle.active';
28
27
  const LEGACY_MARKER_NAME = 'process-lifecycle.active.json';
@@ -20,7 +20,7 @@ function writeStderr(line) {
20
20
  try { process.stderr.write(`${line}\n`); } catch {}
21
21
  }
22
22
 
23
- export function signalExitCode(signal, fallback = 1) {
23
+ function signalExitCode(signal, fallback = 1) {
24
24
  return SIGNAL_EXIT_CODES[signal] || fallback;
25
25
  }
26
26
 
@@ -50,7 +50,7 @@ function abortError(signal) {
50
50
  : new Error(String(signal?.reason || 'resource admission canceled'));
51
51
  }
52
52
 
53
- export class ResourcePressureError extends Error {
53
+ class ResourcePressureError extends Error {
54
54
  constructor(message, details = {}) {
55
55
  super(`resource pressure: ${message}`);
56
56
  this.name = 'ResourcePressureError';
@@ -59,7 +59,7 @@ export class ResourcePressureError extends Error {
59
59
  }
60
60
  }
61
61
 
62
- export class ResourceAdmissionQueueFullError extends ResourcePressureError {
62
+ class ResourceAdmissionQueueFullError extends ResourcePressureError {
63
63
  constructor(maxQueue) {
64
64
  super(`high-load admission queue full (maximum ${maxQueue}); retry after running work completes`, {
65
65
  maxQueue,
@@ -12,7 +12,7 @@ import { askSession } from '../agent/orchestrator/session/manager/ask-session.mj
12
12
  import { parseScheduleModelRef } from './schedule-model-ref.mjs';
13
13
 
14
14
  /** Resolve schedule.model into a {provider,model,effort?,fast?} route. */
15
- export function scheduleRouteFromModelRef(modelRef, config = null) {
15
+ function scheduleRouteFromModelRef(modelRef, config = null) {
16
16
  const ref = parseScheduleModelRef(modelRef);
17
17
  if (ref && typeof ref === 'object') return ref;
18
18
  const cfg = config || loadConfig({ secrets: false });
@@ -220,7 +220,7 @@ export async function setSkippedUntil(name, ts, { dataDir } = {}) {
220
220
  * next_fire_at at/before `now`, and not currently deferred or skipped past
221
221
  * `now`.
222
222
  */
223
- export async function listDue(now = new Date(), { dataDir } = {}) {
223
+ async function listDue(now = new Date(), { dataDir } = {}) {
224
224
  const db = await getDb(dataDir);
225
225
  const { rows } = await db.query(
226
226
  `SELECT ${COLS} FROM scheduler.schedules
@@ -15,7 +15,7 @@ import { tmpdir } from 'node:os'
15
15
  import { join, resolve } from 'node:path'
16
16
  import { writeJsonAtomicSync } from './atomic-file.mjs'
17
17
 
18
- export function discoveryRoot() {
18
+ function discoveryRoot() {
19
19
  const root = process.env.MIXDOG_RUNTIME_ROOT
20
20
  ? resolve(process.env.MIXDOG_RUNTIME_ROOT)
21
21
  : join(tmpdir(), 'mixdog')
@@ -152,7 +152,7 @@ export function writeServiceAdvert(service, fields = {}) {
152
152
  // advertises a port, the file is removed (clean shutdown). Read-modify-write is
153
153
  // race-free enough for a genuine single owner (only the service's supervisor
154
154
  // writes its own file).
155
- export function patchServiceAdvert(service, fields = {}) {
155
+ function patchServiceAdvert(service, fields = {}) {
156
156
  const cur = readServiceAdvert(service) ?? {}
157
157
  const merged = { ...cur }
158
158
  for (const [k, v] of Object.entries(fields)) {
@@ -116,7 +116,7 @@ export function unregisterLiveSession() {
116
116
  try { unlinkSync(selfPidFile()); } catch { /* already gone */ }
117
117
  }
118
118
 
119
- export function otherLiveSessionExists() {
119
+ function otherLiveSessionExists() {
120
120
  let entries;
121
121
  try { entries = readdirSync(liveSessionsDir()); } catch { return false; }
122
122
  let alive = false;
@@ -278,7 +278,7 @@ export function spawnStagedInstall(version) {
278
278
  * bestStagedVersion(currentVersion) — highest completed staged version strictly
279
279
  * newer than current, with a valid self-contained package dir; else null.
280
280
  */
281
- export function bestStagedVersion(currentVersion) {
281
+ function bestStagedVersion(currentVersion) {
282
282
  const cur = String(currentVersion || localPackageVersion());
283
283
  let best = null;
284
284
  let entries;
@@ -303,7 +303,7 @@ export function bestStagedVersion(currentVersion) {
303
303
  * success; on failure of the second rename the backup is rolled back into
304
304
  * place. Returns true only when the new version is live. Never throws.
305
305
  */
306
- export function swapStagedIntoGlobal({ globalPkgRoot, pkgDir, expectedVersion, _rename } = {}) {
306
+ function swapStagedIntoGlobal({ globalPkgRoot, pkgDir, expectedVersion, _rename } = {}) {
307
307
  if (!globalPkgRoot || !pkgDir) return false;
308
308
  // `_rename` is a test seam; production always uses renameWithRetrySync.
309
309
  const rename = typeof _rename === 'function' ? _rename : renameWithRetrySync;
@@ -366,7 +366,7 @@ function globalPopulated(root) {
366
366
  * cleanupStaging(currentVersion) — remove superseded/stale staging dirs and any
367
367
  * leftover swap backups. Best-effort; never throws.
368
368
  */
369
- export function cleanupStaging(currentVersion) {
369
+ function cleanupStaging(currentVersion) {
370
370
  const cur = String(currentVersion || localPackageVersion());
371
371
  try {
372
372
  for (const name of readdirSync(stagingRootDir())) {
@@ -458,7 +458,7 @@ export function performPendingSwap() {
458
458
  // present + size-stable package; otherwise print a one-line notice and
459
459
  // process.exit(1). Exported so the swap-safety proof can exercise the exact
460
460
  // production decision.
461
- export function ensureGlobalStableOrExit(root, timeoutMs = 3000) {
461
+ function ensureGlobalStableOrExit(root, timeoutMs = 3000) {
462
462
  if (ensureGlobalStable(root, timeoutMs) && globalPopulated(root)) return true;
463
463
  process.stderr.write('mixdog: update in progress — retry in a moment.\n');
464
464
  process.exit(1);
@@ -479,7 +479,7 @@ function currentGlobalVersion() {
479
479
  // Block until the swap lock file disappears (owner finished) or the deadline
480
480
  // passes. A dead/abandoned owner is reaped and treated as cleared. Returns true
481
481
  // if the lock is gone, false if it timed out with a live owner still holding.
482
- export function waitForSwapLockClear(lock, timeoutMs) {
482
+ function waitForSwapLockClear(lock, timeoutMs) {
483
483
  const deadline = Date.now() + Math.max(0, timeoutMs);
484
484
  while (Date.now() < deadline) {
485
485
  if (!existsSync(lock)) return true;
@@ -135,7 +135,7 @@ export function toolCompletionInstruction({ surface = 'tool', id, status, detail
135
135
  return `The async ${label} ${id || ''} has finished${statusText} - review this result in your next step.`;
136
136
  }
137
137
 
138
- export function toolCompletionMeta({
138
+ function toolCompletionMeta({
139
139
  surface = 'tool',
140
140
  id,
141
141
  status,
@@ -37,7 +37,7 @@ export function isMcpToolName(name) {
37
37
  // (mcp__plugin_mixdog_mixdog__<tool>). Those must render as their stripped
38
38
  // builtin names, not as external "MCP" calls. Define the server id once here
39
39
  // and reuse everywhere a display path branches on MCP-ness.
40
- export const SELF_MCP_SERVER = 'plugin_mixdog_mixdog';
40
+ const SELF_MCP_SERVER = 'plugin_mixdog_mixdog';
41
41
 
42
42
  export function isSelfMcpToolName(name) {
43
43
  const mcp = parseMcpToolName(name);
@@ -317,7 +317,7 @@ export function formatToolSurface(name, args, opts = {}) {
317
317
 
318
318
  // ── Aggregate tool-card classification & formatting ──────────────
319
319
 
320
- export const CATEGORY_ORDER = [
320
+ const CATEGORY_ORDER = [
321
321
  'Read', 'Search', 'Load', 'MCP', 'Skill', 'Web Research', 'Memory', 'Explore',
322
322
  'Patch', 'Shell', 'Agent', 'Task', 'Schedule', 'Channel', 'Setup', 'Other',
323
323
  ];
@@ -400,7 +400,7 @@ const CATEGORY_COPY = new Map([
400
400
  ]);
401
401
 
402
402
  /** Active gerund for a category (e.g. "Reading" for "Read"). */
403
- export function activeCategoryLabel(category) {
403
+ function activeCategoryLabel(category) {
404
404
  return CATEGORY_COPY.get(category)?.active || category;
405
405
  }
406
406
 
@@ -0,0 +1,184 @@
1
+ // Turn-scoped worktree snapshots over a SHADOW git repository.
2
+ //
3
+ // A per-worktree bare repo lives under <data>/turn-snapshots/<hash>; `git
4
+ // --git-dir <shadow> --work-tree <project>` add/write-tree captures the whole
5
+ // worktree as a tree object WITHOUT touching the project's own git state (or
6
+ // requiring the project to be a git repo at all). Diffing the turn-start tree
7
+ // against the current tree therefore reports EVERYTHING a turn changed —
8
+ // lead edits, subagent edits, background shell jobs, even external editors —
9
+ // which transcript-parsed patches structurally cannot see.
10
+ //
11
+ // Costs: the first track() of a project hashes the worktree once (mitigated
12
+ // by reusing the project's own .git objects via alternates); every later
13
+ // track() is an index stat-scan. All entry points are best-effort and never
14
+ // throw into the turn path. MIXDOG_TURN_SNAPSHOT=0 disables the feature.
15
+ import { execFile } from 'child_process';
16
+ import { createHash } from 'crypto';
17
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
18
+ import { join, resolve } from 'path';
19
+ import { resolvePluginData } from './plugin-paths.mjs';
20
+
21
+ const DISABLED = /^(0|false|off)$/i.test(String(process.env.MIXDOG_TURN_SNAPSHOT || ''));
22
+ const GIT_TIMEOUT_MS = 120_000;
23
+ const BEGIN_WAIT_CAP_MS = 1_500;
24
+ const MAX_PATCH_BYTES = 2_000_000;
25
+ const BASE_CACHE_MAX = 32;
26
+ const FAILURE_BACKOFF_MS = 5 * 60_000;
27
+
28
+ const _queues = new Map(); // gitdir → tail promise (serialize per repo)
29
+ const _baseBySession = new Map(); // sessionId → { worktree, tree, at }
30
+ const _failedUntil = new Map(); // gitdir → timestamp
31
+
32
+ function _worktreeKey(worktree) {
33
+ const raw = String(worktree || '').trim();
34
+ if (!raw) return '';
35
+ const full = resolve(raw);
36
+ return process.platform === 'win32' ? full.toLowerCase() : full;
37
+ }
38
+
39
+ function _gitDirFor(worktreeKey) {
40
+ const hash = createHash('sha1').update(worktreeKey).digest('hex').slice(0, 20);
41
+ return join(resolvePluginData(), 'turn-snapshots', hash);
42
+ }
43
+
44
+ function _git(args, { cwd } = {}) {
45
+ return new Promise((resolveExec) => {
46
+ execFile('git', args, {
47
+ cwd: cwd || undefined,
48
+ windowsHide: true,
49
+ timeout: GIT_TIMEOUT_MS,
50
+ maxBuffer: 64 * 1024 * 1024,
51
+ }, (error, stdout, stderr) => {
52
+ resolveExec({ code: error ? (error.code ?? 1) : 0, stdout: String(stdout || ''), stderr: String(stderr || '') });
53
+ });
54
+ });
55
+ }
56
+
57
+ // Serialize all git operations per shadow repo: concurrent index writes would
58
+ // corrupt each other, and turn-start/track/diff can overlap freely otherwise.
59
+ function _enqueue(gitdir, task) {
60
+ const tail = (_queues.get(gitdir) || Promise.resolve()).then(task, task);
61
+ _queues.set(gitdir, tail.catch(() => {}));
62
+ return tail;
63
+ }
64
+
65
+ async function _ensureRepo(worktree, gitdir) {
66
+ if (existsSync(join(gitdir, 'HEAD'))) return true;
67
+ mkdirSync(gitdir, { recursive: true });
68
+ const init = await _git(['init', '--bare', '--quiet', gitdir]);
69
+ if (init.code !== 0) return false;
70
+ // The shadow repo indexes the project via --work-tree; never let it descend
71
+ // into the project's real .git, and keep bytes stable/gc quiet.
72
+ await _git(['--git-dir', gitdir, 'config', 'core.bare', 'false']);
73
+ await _git(['--git-dir', gitdir, 'config', 'core.autocrlf', 'false']);
74
+ await _git(['--git-dir', gitdir, 'config', 'gc.auto', '0']);
75
+ try {
76
+ mkdirSync(join(gitdir, 'info'), { recursive: true });
77
+ writeFileSync(join(gitdir, 'info', 'exclude'), '.git/\n');
78
+ // First-snapshot cost: reuse the project's own git objects so unchanged
79
+ // blobs need no re-hash/store (the opencode chromium lesson).
80
+ const projectObjects = join(worktree, '.git', 'objects');
81
+ if (existsSync(projectObjects)) {
82
+ mkdirSync(join(gitdir, 'objects', 'info'), { recursive: true });
83
+ writeFileSync(join(gitdir, 'objects', 'info', 'alternates'), `${projectObjects}\n`);
84
+ }
85
+ } catch { /* exclusions/alternates are optimizations, not requirements */ }
86
+ return true;
87
+ }
88
+
89
+ // Capture the current worktree as a tree object; null on any failure.
90
+ async function _trackTree(worktree) {
91
+ const key = _worktreeKey(worktree);
92
+ if (!key || !existsSync(key)) return null;
93
+ const gitdir = _gitDirFor(key);
94
+ const failedUntil = _failedUntil.get(gitdir) || 0;
95
+ if (Date.now() < failedUntil) return null;
96
+ return _enqueue(gitdir, async () => {
97
+ if (!(await _ensureRepo(key, gitdir))) {
98
+ _failedUntil.set(gitdir, Date.now() + FAILURE_BACKOFF_MS);
99
+ return null;
100
+ }
101
+ const base = ['--git-dir', gitdir, '--work-tree', key];
102
+ const add = await _git([...base, 'add', '-A', '--', '.'], { cwd: key });
103
+ if (add.code !== 0) {
104
+ _failedUntil.set(gitdir, Date.now() + FAILURE_BACKOFF_MS);
105
+ return null;
106
+ }
107
+ const tree = await _git([...base, 'write-tree'], { cwd: key });
108
+ if (tree.code !== 0) return null;
109
+ const hash = tree.stdout.trim();
110
+ return /^[0-9a-f]{40,64}$/.test(hash) ? hash : null;
111
+ });
112
+ }
113
+
114
+ /** Fire-and-forget shadow-repo warmup so a project's first turn never pays
115
+ * the initial full snapshot inline. */
116
+ export function prewarmTurnSnapshot(worktree) {
117
+ if (DISABLED || !worktree) return;
118
+ void _trackTree(worktree).catch(() => {});
119
+ }
120
+
121
+ /** Capture the turn base tree for a session. Waits at most BEGIN_WAIT_CAP_MS
122
+ * so a cold first snapshot cannot stall the turn; a slower capture still
123
+ * lands through the shared promise and applies to this turn retroactively. */
124
+ export async function beginTurnSnapshot(worktree, sessionId) {
125
+ if (DISABLED || !worktree || !sessionId) return;
126
+ const key = _worktreeKey(worktree);
127
+ const capture = _trackTree(worktree).then((tree) => {
128
+ if (!tree) return;
129
+ _baseBySession.delete(sessionId);
130
+ _baseBySession.set(sessionId, { worktree: key, tree, at: Date.now() });
131
+ while (_baseBySession.size > BASE_CACHE_MAX) {
132
+ const oldest = _baseBySession.keys().next().value;
133
+ if (oldest === undefined) break;
134
+ _baseBySession.delete(oldest);
135
+ }
136
+ }).catch(() => {});
137
+ await Promise.race([capture, new Promise((r) => { const t = setTimeout(r, BEGIN_WAIT_CAP_MS); t.unref?.(); })]);
138
+ }
139
+
140
+ /** Diff the session's turn-start tree against the CURRENT worktree state.
141
+ * Returns { supported, files:[{name, additions, deletions}], patch }. */
142
+ export async function getTurnReviewDiff(worktree, sessionId) {
143
+ if (DISABLED) return { supported: false, files: [], patch: '' };
144
+ const key = _worktreeKey(worktree);
145
+ const base = sessionId ? _baseBySession.get(sessionId) : null;
146
+ if (!key) return { supported: false, files: [], patch: '' };
147
+ if (!base || base.worktree !== key) {
148
+ return { supported: true, files: [], patch: '', reason: 'no-base' };
149
+ }
150
+ const head = await _trackTree(worktree);
151
+ if (!head) return { supported: false, files: [], patch: '' };
152
+ if (head === base.tree) return { supported: true, files: [], patch: '', baseTree: base.tree, headTree: head };
153
+ const gitdir = _gitDirFor(key);
154
+ const argsBase = ['--git-dir', gitdir];
155
+ const [numstat, patch] = await Promise.all([
156
+ _git([...argsBase, 'diff-tree', '-r', '--numstat', '-z', base.tree, head]),
157
+ _git([...argsBase, 'diff-tree', '-r', '-p', '--no-color', base.tree, head]),
158
+ ]);
159
+ if (numstat.code !== 0) return { supported: false, files: [], patch: '' };
160
+ const files = [];
161
+ const fields = numstat.stdout.split('\0').filter(Boolean);
162
+ for (const row of fields) {
163
+ const match = row.match(/^(\d+|-)\t(\d+|-)\t([\s\S]+)$/);
164
+ if (!match) continue;
165
+ files.push({
166
+ name: match[3],
167
+ additions: match[1] === '-' ? 0 : Number(match[1]),
168
+ deletions: match[2] === '-' ? 0 : Number(match[2]),
169
+ });
170
+ }
171
+ let patchText = patch.code === 0 ? patch.stdout : '';
172
+ if (patchText.length > MAX_PATCH_BYTES) {
173
+ patchText = patchText.slice(0, MAX_PATCH_BYTES);
174
+ const cut = patchText.lastIndexOf('\ndiff --git ');
175
+ if (cut > 0) patchText = patchText.slice(0, cut + 1);
176
+ }
177
+ return { supported: true, files, patch: patchText, baseTree: base.tree, headTree: head };
178
+ }
179
+
180
+ export function _resetTurnSnapshotForTest() {
181
+ _queues.clear();
182
+ _baseBySession.clear();
183
+ _failedUntil.clear();
184
+ }
@@ -252,7 +252,7 @@ export function npmCliJsPath() {
252
252
  * npm-cli.js cannot be located. Resolves once the child exits; never throws —
253
253
  * failures come back as {ok:false, error}.
254
254
  */
255
- export function runGlobalUpdate() {
255
+ function runGlobalUpdate() {
256
256
  return new Promise((resolvePromise) => {
257
257
  let child;
258
258
  try {
@@ -44,7 +44,7 @@ function _dataFile(name) {
44
44
  // back to the home dir: a missing session signal then surfaces as ENOENT
45
45
  // (absolute paths required) rather than a silent stale read. Invariant check
46
46
  // (exact path equality with the known root), not a path-substring heuristic.
47
- export function _safeProcessCwd() {
47
+ function _safeProcessCwd() {
48
48
  const cwd = process.cwd()
49
49
  try { if (resolve(cwd) === resolve(mixdogRoot())) return homedir() } catch { /* fall through to cwd */ }
50
50
  return cwd
@@ -143,7 +143,7 @@ export function captureOriginalUserCwd() {
143
143
  * Used by the cwd-tool auto-init path to avoid self-reference when
144
144
  * deciding whether to seed MIXDOG_SESSION_CWD from disk.
145
145
  */
146
- export function rawUserCwd() {
146
+ function rawUserCwd() {
147
147
  try {
148
148
  const txt = readFileSync(_dataFile('user-cwd.txt'), 'utf8').trim()
149
149
  return _normalizePlatformCwd(txt) || startRootCwd() || _safeProcessCwd()
@@ -208,7 +208,7 @@ export function readLastSessionCwd(keyPid) {
208
208
  * Run fn inside an async context where pwd() returns cwd.
209
209
  * All descendant async calls within fn see cwd as their working directory.
210
210
  */
211
- export function runWithCwdOverride(cwd, fn) {
211
+ function runWithCwdOverride(cwd, fn) {
212
212
  return _cwdOverride.run(cwd, fn)
213
213
  }
214
214
 
@@ -23,7 +23,7 @@ function mixdogConfigBaseDir() {
23
23
  return process.env.MIXDOG_CONFIG_DIR || join(homedir(), '.mixdog');
24
24
  }
25
25
 
26
- export function getBackupRoot() {
26
+ function getBackupRoot() {
27
27
  return process.env.MIXDOG_USER_DATA_BACKUP_ROOT
28
28
  || join(mixdogConfigBaseDir(), 'backups', 'user-data');
29
29
  }
@@ -64,7 +64,7 @@ export function hasUserDataInitMarker(dataDir) {
64
64
  }
65
65
 
66
66
  /** Skip single-section wipe remnants (e.g. `{ search: … }` only). */
67
- export function isStructurallyCompleteMixdogConfigBackup(parsed) {
67
+ function isStructurallyCompleteMixdogConfigBackup(parsed) {
68
68
  if (!isPlainObject(parsed)) return false;
69
69
  if (Object.keys(parsed).length <= 1) return false;
70
70
  if (!parsed.agent && !parsed.channels) return false;
@@ -224,7 +224,7 @@ export async function backupUserDataAsync(dataDir, reason = 'snapshot') {
224
224
  return { dir: copied.length > 0 ? backupDir : null, copied };
225
225
  }
226
226
 
227
- export function shouldSeedMissingUserData(dataDir, rel) {
227
+ function shouldSeedMissingUserData(dataDir, rel) {
228
228
  if (!dataDir) return true;
229
229
  if (existsSync(join(dataDir, rel))) {
230
230
  markUserDataInitialized(dataDir);
@@ -275,7 +275,7 @@ function normCase(p) {
275
275
  * @param {string} [ownedSubdir] the single owned subdir name (default '.deps')
276
276
  * @returns {string} the resolved owned path (only on allow)
277
277
  */
278
- export function assertSafeOwnedDir(targetDir, dataDir, op = 'destructive op', ownedSubdir = OWNED_SUBDIR) {
278
+ function assertSafeOwnedDir(targetDir, dataDir, op = 'destructive op', ownedSubdir = OWNED_SUBDIR) {
279
279
  if (!targetDir) throw new Error(`[data-guard] ${op} refused: empty target dir`);
280
280
  if (!dataDir) throw new Error(`[data-guard] ${op} refused: empty data dir`);
281
281