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
@@ -1,98 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import test from 'node:test';
3
- import { createRequire } from 'node:module';
4
- import { tmpdir } from 'node:os';
5
- import { join } from 'node:path';
6
-
7
- const require = createRequire(import.meta.url);
8
- const debug = require('../src/lib/mixdog-debug.cjs');
9
-
10
- const MODE_ENVS = [
11
- 'MIXDOG_MODE',
12
- 'MIXDOG_SHIP',
13
- 'MIXDOG_DIAGNOSTICS',
14
- 'MIXDOG_DEBUG',
15
- 'MIXDOG_DEBUG_SESSION_START',
16
- 'MIXDOG_AGENT_TRACE_LOCAL_DISABLE',
17
- 'MIXDOG_AGENT_TRACE_PATH',
18
- 'MIXDOG_TOOL_FAILURE_LOG_DISABLE',
19
- 'MIXDOG_TOOL_FAILURE_LOG_PATH',
20
- ];
21
-
22
- function withEnv(overrides, fn) {
23
- const prev = {};
24
- for (const k of MODE_ENVS) prev[k] = process.env[k];
25
- for (const k of MODE_ENVS) delete process.env[k];
26
- for (const [k, v] of Object.entries(overrides)) process.env[k] = v;
27
- try { return fn(); }
28
- finally {
29
- for (const k of MODE_ENVS) {
30
- if (prev[k] == null) delete process.env[k];
31
- else process.env[k] = prev[k];
32
- }
33
- }
34
- }
35
-
36
- test('MIXDOG_MODE=ship forces shipping mode with diagnostics off', () => {
37
- withEnv({ MIXDOG_MODE: 'ship' }, () => {
38
- assert.equal(debug.resolveMixdogMode(), 'ship');
39
- assert.equal(debug.isShippingMode(), true);
40
- assert.equal(debug.isDevMode(), false);
41
- assert.equal(debug.isDiagnosticIOEnabled(), false);
42
- });
43
- });
44
-
45
- test('MIXDOG_MODE=dev forces dev mode with diagnostics on', () => {
46
- withEnv({ MIXDOG_MODE: 'dev' }, () => {
47
- assert.equal(debug.resolveMixdogMode(), 'dev');
48
- assert.equal(debug.isDiagnosticIOEnabled(), true);
49
- });
50
- });
51
-
52
- test('MIXDOG_DEBUG implies dev mode', () => {
53
- withEnv({ MIXDOG_MODE: 'ship', MIXDOG_DEBUG: '1' }, () => {
54
- // explicit MIXDOG_MODE=ship still wins over debug flag by precedence
55
- assert.equal(debug.resolveMixdogMode(), 'ship');
56
- });
57
- withEnv({ MIXDOG_DEBUG: '1' }, () => {
58
- assert.equal(debug.resolveMixdogMode(), 'dev');
59
- assert.equal(debug.isDiagnosticIOEnabled(), true);
60
- });
61
- });
62
-
63
- test('MIXDOG_DIAGNOSTICS force-enables diagnostic IO under shipping', () => {
64
- withEnv({ MIXDOG_MODE: 'ship', MIXDOG_DIAGNOSTICS: '1' }, () => {
65
- assert.equal(debug.isShippingMode(), true);
66
- assert.equal(debug.isDiagnosticIOEnabled(), true);
67
- });
68
- });
69
-
70
- test('shipping mode suppresses default diagnostic file paths', async () => {
71
- const io = await import('../src/runtime/agent/orchestrator/agent-trace-io.mjs?ship-default');
72
- withEnv({ MIXDOG_MODE: 'ship' }, () => {
73
- assert.equal(io._resolveLocalTracePath(), null);
74
- assert.equal(io._resolveToolFailurePath(), null);
75
- });
76
- });
77
-
78
- test('explicit diagnostic file paths opt in under shipping mode', async () => {
79
- const io = await import('../src/runtime/agent/orchestrator/agent-trace-io.mjs?ship-explicit-path');
80
- const base = join(tmpdir(), `mixdog-ship-mode-test-${process.pid}`);
81
- const tracePath = join(base, 'explicit-agent-trace.jsonl');
82
- const failuresPath = join(base, 'explicit-tool-failures.jsonl');
83
- withEnv({
84
- MIXDOG_MODE: 'ship',
85
- MIXDOG_AGENT_TRACE_PATH: tracePath,
86
- MIXDOG_TOOL_FAILURE_LOG_PATH: failuresPath,
87
- }, () => {
88
- assert.equal(io._resolveLocalTracePath(), tracePath);
89
- assert.equal(io._resolveToolFailurePath(), failuresPath);
90
- });
91
- });
92
-
93
- test('git checkout default stays dev for local diagnostics', () => {
94
- withEnv({}, () => {
95
- assert.equal(debug.resolveMixdogMode(), 'dev');
96
- assert.equal(debug.isDiagnosticIOEnabled(), true);
97
- });
98
- });
@@ -1,38 +0,0 @@
1
- import assert from 'node:assert/strict';
2
- import test from 'node:test';
3
- import { actionableFailureCount } from './smoke-loop-failure-summary.mjs';
4
-
5
- test('returns a numeric actionable failure count', () => {
6
- assert.equal(actionableFailureCount('{"actionable_failures":{"matched":0}}'), 0);
7
- assert.equal(actionableFailureCount('{"actionable_failures":{"matched":1}}'), 1);
8
- });
9
-
10
- test('rejects malformed tool-failures JSON', () => {
11
- assert.throws(
12
- () => actionableFailureCount('{'),
13
- /tool failures returned malformed JSON/,
14
- );
15
- });
16
-
17
- test('rejects a missing or malformed actionable failure count', () => {
18
- assert.throws(
19
- () => actionableFailureCount('{}'),
20
- /tool failures returned malformed result schema/,
21
- );
22
- assert.throws(
23
- () => actionableFailureCount('{"actionable_failures":{"matched":"0"}}'),
24
- /tool failures returned malformed result schema/,
25
- );
26
- assert.throws(
27
- () => actionableFailureCount('{"actionable_failures":{"matched":-1}}'),
28
- /tool failures returned malformed result schema/,
29
- );
30
- assert.throws(
31
- () => actionableFailureCount('{"actionable_failures":{"matched":0.5}}'),
32
- /tool failures returned malformed result schema/,
33
- );
34
- assert.throws(
35
- () => actionableFailureCount('{"actionable_failures":{"matched":1e999}}'),
36
- /tool failures returned malformed result schema/,
37
- );
38
- });
@@ -1,16 +0,0 @@
1
- export function actionableFailureCount(stdout) {
2
- let summary;
3
- try {
4
- summary = JSON.parse(stdout);
5
- } catch {
6
- throw new Error(`tool failures returned malformed JSON:\n${stdout}`);
7
- }
8
-
9
- const matched = summary?.actionable_failures?.matched;
10
- if (!Number.isInteger(matched) || matched < 0) {
11
- throw new Error(
12
- `tool failures returned malformed result schema: expected actionable_failures.matched to be a non-negative integer:\n${stdout}`,
13
- );
14
- }
15
- return matched;
16
- }
@@ -1,221 +0,0 @@
1
- #!/usr/bin/env node
2
- import { existsSync, readFileSync } from 'node:fs';
3
- import { resolve } from 'node:path';
4
-
5
- function argValue(name, fallback = null) {
6
- const idx = process.argv.indexOf(name);
7
- if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
8
- const prefix = `${name}=`;
9
- const hit = process.argv.find((arg) => arg.startsWith(prefix));
10
- return hit ? hit.slice(prefix.length) : fallback;
11
- }
12
-
13
- function parseNumber(value, fallback = null) {
14
- if (value == null || value === '') return fallback;
15
- const n = Number(value);
16
- return Number.isFinite(n) ? n : fallback;
17
- }
18
-
19
- function parseDuration(value, fallback = null) {
20
- const raw = String(value || '').trim();
21
- if (!raw) return fallback;
22
- if (/^\d+$/.test(raw)) return Number(raw);
23
- const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/i);
24
- if (!match) throw new Error(`invalid duration: ${raw}`);
25
- const n = Number(match[1]);
26
- const unit = match[2].toLowerCase();
27
- const mult = unit === 'ms' ? 1 : unit === 's' ? 1000 : unit === 'm' ? 60_000 : 3_600_000;
28
- return Math.max(1, Math.floor(n * mult));
29
- }
30
-
31
- function argValues(name) {
32
- const values = [];
33
- const prefix = `${name}=`;
34
- for (let i = 0; i < process.argv.length; i += 1) {
35
- const arg = process.argv[i];
36
- if (arg === name && i + 1 < process.argv.length) values.push(process.argv[i + 1]);
37
- else if (arg.startsWith(prefix)) values.push(arg.slice(prefix.length));
38
- }
39
- return values;
40
- }
41
-
42
- function parseStepCaps(values) {
43
- const caps = new Map();
44
- for (const value of values) {
45
- const raw = String(value || '').trim();
46
- if (!raw) continue;
47
- const idx = raw.lastIndexOf('=');
48
- if (idx <= 0) throw new Error(`invalid --max-step-ms value: ${raw}`);
49
- const name = raw.slice(0, idx).trim().replace(/^scripts\//, '');
50
- const cap = Number(raw.slice(idx + 1).trim());
51
- if (!name || !Number.isFinite(cap) || cap < 0) throw new Error(`invalid --max-step-ms value: ${raw}`);
52
- caps.set(name, cap);
53
- }
54
- return caps;
55
- }
56
-
57
- function summarize(values) {
58
- if (!values.length) return { min: 0, max: 0, avg: 0 };
59
- const min = Math.min(...values);
60
- const max = Math.max(...values);
61
- const avg = values.reduce((sum, value) => sum + value, 0) / values.length;
62
- return {
63
- min: Math.round(min * 10) / 10,
64
- max: Math.round(max * 10) / 10,
65
- avg: Math.round(avg * 10) / 10,
66
- };
67
- }
68
-
69
- function readRows(path) {
70
- if (!existsSync(path)) throw new Error(`smoke loop log not found: ${path}`);
71
- return readFileSync(path, 'utf8')
72
- .split(/\r?\n/)
73
- .filter(Boolean)
74
- .map((line, index) => {
75
- try {
76
- return JSON.parse(line);
77
- } catch (error) {
78
- return { type: 'parse_error', line: index + 1, error: error?.message || String(error), raw: line };
79
- }
80
- });
81
- }
82
-
83
- function formatDuration(ms) {
84
- const total = Math.max(0, Math.round(Number(ms) || 0));
85
- const h = Math.floor(total / 3_600_000);
86
- const m = Math.floor((total % 3_600_000) / 60_000);
87
- const s = Math.floor((total % 60_000) / 1000);
88
- if (h > 0) return `${h}h ${m}m ${s}s`;
89
- if (m > 0) return `${m}m ${s}s`;
90
- return `${s}s`;
91
- }
92
-
93
- function summarizeSteps(iterations) {
94
- const byScript = new Map();
95
- for (const row of iterations) {
96
- if (!Array.isArray(row.steps)) continue;
97
- for (const step of row.steps) {
98
- const script = String(step?.script || '').replace(/^scripts\//, '');
99
- const ms = Number(step?.ms);
100
- if (!script || !Number.isFinite(ms)) continue;
101
- const values = byScript.get(script) || [];
102
- values.push(ms);
103
- byScript.set(script, values);
104
- }
105
- }
106
- return Object.fromEntries([...byScript.entries()].map(([script, values]) => [script, summarize(values)]));
107
- }
108
-
109
- const logPath = resolve(argValue('--log', '.mixdog/data/history/smoke-loop.jsonl'));
110
- const pidArg = parseNumber(argValue('--pid', null), null);
111
- const minIterations = parseNumber(argValue('--min-iterations', null), null);
112
- const minElapsedMs = parseDuration(argValue('--min-elapsed', null), null);
113
- const maxGapMs = parseDuration(argValue('--max-gap', null), null);
114
- const maxStaleMs = parseDuration(argValue('--max-stale', null), null);
115
- const maxSmokeMs = parseNumber(argValue('--max-smoke-ms', null), null);
116
- const maxAvgSmokeMs = parseNumber(argValue('--max-avg-smoke-ms', null), null);
117
- const maxStepMs = parseStepCaps(argValues('--max-step-ms'));
118
- const maxRssMb = parseNumber(argValue('--max-rss-mb', null), null);
119
- const maxRssGrowthMb = parseNumber(argValue('--max-rss-growth-mb', null), null);
120
- const jsonMode = process.argv.includes('--json');
121
- const requireComplete = process.argv.includes('--require-complete');
122
-
123
- const rows = readRows(logPath);
124
- const startRows = rows.filter((row) => row?.type === 'start' && (pidArg == null || Number(row.pid) === pidArg));
125
- const start = startRows.at(-1);
126
- if (!start) throw new Error(pidArg == null ? 'no smoke loop start row found' : `no smoke loop start row found for pid ${pidArg}`);
127
-
128
- const startIndex = rows.lastIndexOf(start);
129
- const runRows = rows.slice(startIndex).filter((row) => Number(row.pid) === Number(start.pid));
130
- const iterations = runRows.filter((row) => row?.type === 'iteration');
131
- const errors = runRows.filter((row) => row?.type === 'error' || row?.type === 'parse_error');
132
- const summaryRows = runRows.filter((row) => row?.type === 'summary');
133
- const last = iterations.at(-1) || null;
134
- const smoke = summarize(iterations.map((row) => Number(row.smoke_ms)).filter(Number.isFinite));
135
- const stepMs = summarizeSteps(iterations);
136
- const rss = summarize(iterations.map((row) => Number(row.rss_mb)).filter(Number.isFinite));
137
- const startRss = Number(start.rss_mb);
138
- const lastRss = Number(last?.rss_mb);
139
- const rssGrowth = Number.isFinite(startRss) && Number.isFinite(lastRss)
140
- ? Math.round((lastRss - startRss) * 10) / 10
141
- : 0;
142
- const elapsedMs = Number(last?.elapsed_ms || summaryRows.at(-1)?.elapsed_ms || 0);
143
- const durationMs = Number(start.duration_ms || 0);
144
- const remainingMs = durationMs > 0 ? Math.max(0, durationMs - elapsedMs) : null;
145
- const startTs = Date.parse(start.ts);
146
- const finishAt = durationMs > 0 && Number.isFinite(startTs)
147
- ? new Date(startTs + durationMs).toISOString()
148
- : null;
149
- const iterationsPerHour = elapsedMs > 0
150
- ? Math.round((iterations.length / (elapsedMs / 3_600_000)) * 10) / 10
151
- : 0;
152
- const gaps = [];
153
- for (let i = 1; i < iterations.length; i += 1) {
154
- const prev = Date.parse(iterations[i - 1].ts);
155
- const cur = Date.parse(iterations[i].ts);
156
- if (Number.isFinite(prev) && Number.isFinite(cur)) gaps.push(cur - prev);
157
- }
158
- const gapSummary = summarize(gaps);
159
- const lastTs = Date.parse(last?.ts || '');
160
- const staleMs = Number.isFinite(lastTs) ? Date.now() - lastTs : null;
161
-
162
- const failures = [];
163
- if (errors.length > 0) failures.push(`errors=${errors.length}`);
164
- if (requireComplete && summaryRows.length === 0) failures.push('loop has no completed summary row');
165
- if (minIterations != null && iterations.length < minIterations) failures.push(`iterations ${iterations.length} < ${minIterations}`);
166
- if (minElapsedMs != null && elapsedMs < minElapsedMs) failures.push(`elapsed ${formatDuration(elapsedMs)} < ${formatDuration(minElapsedMs)}`);
167
- if (maxGapMs != null && gapSummary.max > maxGapMs) failures.push(`max gap ${formatDuration(gapSummary.max)} > ${formatDuration(maxGapMs)}`);
168
- if (maxStaleMs != null && staleMs != null && staleMs > maxStaleMs) failures.push(`latest iteration stale ${formatDuration(staleMs)} > ${formatDuration(maxStaleMs)}`);
169
- if (maxSmokeMs != null && smoke.max > maxSmokeMs) failures.push(`smoke max ${smoke.max}ms > ${maxSmokeMs}ms`);
170
- if (maxAvgSmokeMs != null && smoke.avg > maxAvgSmokeMs) failures.push(`smoke avg ${smoke.avg}ms > ${maxAvgSmokeMs}ms`);
171
- for (const [script, cap] of maxStepMs.entries()) {
172
- const stats = stepMs[script];
173
- if (stats && stats.max > cap) failures.push(`${script} max ${stats.max}ms > ${cap}ms`);
174
- }
175
- if (maxRssMb != null && rss.max > maxRssMb) failures.push(`rss max ${rss.max}MB > ${maxRssMb}MB`);
176
- if (maxRssGrowthMb != null && rssGrowth > maxRssGrowthMb) failures.push(`rss growth ${rssGrowth}MB > ${maxRssGrowthMb}MB`);
177
-
178
- const report = {
179
- ok: failures.length === 0,
180
- pid: start.pid,
181
- started_at: start.ts,
182
- finish_at: finishAt,
183
- elapsed_ms: elapsedMs,
184
- elapsed: formatDuration(elapsedMs),
185
- remaining_ms: remainingMs,
186
- remaining: remainingMs == null ? null : formatDuration(remainingMs),
187
- min_elapsed_ms: minElapsedMs,
188
- iterations: iterations.length,
189
- iterations_per_hour: iterationsPerHour,
190
- duration_ms: start.duration_ms,
191
- interval_ms: start.interval_ms,
192
- smoke_ms: smoke,
193
- step_ms: stepMs,
194
- max_step_ms: Object.fromEntries(maxStepMs.entries()),
195
- rss_mb: rss,
196
- rss_growth_mb: rssGrowth,
197
- gap_ms: gapSummary,
198
- stale_ms: staleMs,
199
- errors: errors.length,
200
- completed: summaryRows.length > 0,
201
- require_complete: requireComplete,
202
- latest_iteration: last?.iteration || 0,
203
- failures,
204
- };
205
-
206
- if (jsonMode) {
207
- console.log(JSON.stringify(report, null, 2));
208
- } else {
209
- console.log(`smoke loop report pid=${report.pid} ok=${report.ok}`);
210
- console.log(`started=${report.started_at} finish=${report.finish_at || '-'} elapsed=${report.elapsed} remaining=${report.remaining || '-'} iterations=${report.iterations} rate=${iterationsPerHour}/h completed=${report.completed}`);
211
- console.log(`smoke_ms min=${smoke.min} avg=${smoke.avg} max=${smoke.max}`);
212
- for (const [script, stats] of Object.entries(stepMs)) {
213
- console.log(`${script} min=${stats.min} avg=${stats.avg} max=${stats.max}`);
214
- }
215
- console.log(`rss_mb min=${rss.min} avg=${rss.avg} max=${rss.max} growth=${rssGrowth}`);
216
- console.log(`gap_ms min=${gapSummary.min} avg=${gapSummary.avg} max=${gapSummary.max} stale=${staleMs == null ? '-' : staleMs}`);
217
- console.log(`errors=${errors.length}`);
218
- if (failures.length) console.log(`failures: ${failures.join('; ')}`);
219
- }
220
-
221
- if (failures.length) process.exit(1);
@@ -1,202 +0,0 @@
1
- #!/usr/bin/env node
2
- import { appendFileSync, mkdirSync } from 'node:fs';
3
- import { spawnSync } from 'node:child_process';
4
- import { dirname, isAbsolute, resolve } from 'node:path';
5
- import { fileURLToPath } from 'node:url';
6
- import { actionableFailureCount } from './smoke-loop-failure-summary.mjs';
7
-
8
- const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
9
- const DEFAULT_DURATION_MS = 5 * 60 * 60 * 1000;
10
-
11
- function argValue(name, fallback = null) {
12
- const idx = process.argv.indexOf(name);
13
- if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
14
- const prefix = `${name}=`;
15
- const hit = process.argv.find((arg) => arg.startsWith(prefix));
16
- return hit ? hit.slice(prefix.length) : fallback;
17
- }
18
-
19
- function argFlag(name) {
20
- return process.argv.includes(name);
21
- }
22
-
23
- function parseDuration(value, fallback) {
24
- const raw = String(value || '').trim();
25
- if (!raw) return fallback;
26
- if (/^\d+$/.test(raw)) return Number(raw);
27
- const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)$/i);
28
- if (!match) throw new Error(`invalid duration: ${raw}`);
29
- const n = Number(match[1]);
30
- const unit = match[2].toLowerCase();
31
- const mult = unit === 'ms' ? 1 : unit === 's' ? 1000 : unit === 'm' ? 60_000 : 3_600_000;
32
- return Math.max(1, Math.floor(n * mult));
33
- }
34
-
35
- function resolveOptionalPath(value, fallback) {
36
- const raw = String(value || '').trim();
37
- const picked = raw || fallback;
38
- if (!picked) return null;
39
- return isAbsolute(picked) ? picked : resolve(root, picked);
40
- }
41
-
42
- function runNode(args, label, timeoutMs = 180_000) {
43
- const startedAt = performance.now();
44
- const result = spawnSync(process.execPath, args, {
45
- cwd: root,
46
- encoding: 'utf8',
47
- stdio: ['ignore', 'pipe', 'pipe'],
48
- timeout: timeoutMs,
49
- windowsHide: true,
50
- });
51
- const ms = performance.now() - startedAt;
52
- if (result.status !== 0) {
53
- const out = `${result.error ? `${result.error}\n` : ''}${result.stdout || ''}${result.stderr || ''}`.trim();
54
- throw new Error(`${label} failed in ${ms.toFixed(1)}ms:\n${out}`);
55
- }
56
- return { ms, stdout: result.stdout || '', stderr: result.stderr || '' };
57
- }
58
-
59
- function runSmokeAll(iteration) {
60
- let totalMs = 0;
61
- const steps = [];
62
- for (const script of ['scripts/smoke.mjs', 'scripts/boot-smoke.mjs']) {
63
- const result = runNode([script], `${script} iteration ${iteration}`);
64
- totalMs += result.ms;
65
- steps.push({
66
- script,
67
- ms: Math.round(result.ms * 10) / 10,
68
- });
69
- }
70
- return { ms: totalMs, steps };
71
- }
72
-
73
- function sleep(ms) {
74
- return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
75
- }
76
-
77
- function rssMb() {
78
- return Math.round((process.memoryUsage().rss / 1024 / 1024) * 10) / 10;
79
- }
80
-
81
- function summarize(values) {
82
- if (!values.length) return { min: 0, max: 0, avg: 0 };
83
- const min = Math.min(...values);
84
- const max = Math.max(...values);
85
- const avg = values.reduce((sum, value) => sum + value, 0) / values.length;
86
- return {
87
- min: Math.round(min * 10) / 10,
88
- max: Math.round(max * 10) / 10,
89
- avg: Math.round(avg * 10) / 10,
90
- };
91
- }
92
-
93
- function serializeError(error) {
94
- return {
95
- name: error?.name || 'Error',
96
- message: error?.message || String(error),
97
- stack: error?.stack || null,
98
- };
99
- }
100
-
101
- const durationMs = parseDuration(argValue('--duration', process.env.MIXDOG_SMOKE_LOOP_DURATION), DEFAULT_DURATION_MS);
102
- const intervalMs = parseDuration(argValue('--interval', process.env.MIXDOG_SMOKE_LOOP_INTERVAL), 0);
103
- const maxIterations = Number(argValue('--iterations', process.env.MIXDOG_SMOKE_LOOP_ITERATIONS || 0)) || Infinity;
104
- const logPath = argFlag('--no-log')
105
- ? null
106
- : resolveOptionalPath(
107
- argValue('--log', process.env.MIXDOG_SMOKE_LOOP_LOG),
108
- '.mixdog/data/history/smoke-loop.jsonl',
109
- );
110
- const startedAt = Date.now();
111
- const since = new Date(startedAt).toISOString();
112
- const deadline = startedAt + durationMs;
113
- let iteration = 0;
114
- const smokeTimes = [];
115
- const rssSamples = [];
116
-
117
- function writeLoopLog(row) {
118
- if (!logPath) return;
119
- mkdirSync(dirname(logPath), { recursive: true });
120
- appendFileSync(logPath, `${JSON.stringify({
121
- ts: new Date().toISOString(),
122
- pid: process.pid,
123
- ...row,
124
- })}\n`, { encoding: 'utf8', mode: 0o600 });
125
- }
126
-
127
- function writeFatalLog(error) {
128
- writeLoopLog({
129
- type: 'error',
130
- iteration,
131
- elapsed_ms: Date.now() - startedAt,
132
- error: serializeError(error),
133
- });
134
- }
135
-
136
- process.on('uncaughtException', (error) => {
137
- writeFatalLog(error);
138
- process.stderr.write(`${error?.stack || error}\n`);
139
- process.exit(1);
140
- });
141
-
142
- process.on('unhandledRejection', (reason) => {
143
- const error = reason instanceof Error ? reason : new Error(String(reason));
144
- writeFatalLog(error);
145
- process.stderr.write(`${error.stack || error}\n`);
146
- process.exit(1);
147
- });
148
-
149
- const startRss = rssMb();
150
- writeLoopLog({
151
- type: 'start',
152
- duration_ms: durationMs,
153
- interval_ms: intervalMs,
154
- max_iterations: Number.isFinite(maxIterations) ? maxIterations : null,
155
- since,
156
- rss_mb: startRss,
157
- });
158
- process.stdout.write(`smoke loop start duration=${durationMs}ms interval=${intervalMs}ms since=${since} rss_mb=${startRss} log=${logPath || 'off'}\n`);
159
-
160
- while (Date.now() < deadline && iteration < maxIterations) {
161
- iteration += 1;
162
- const iterStartedAt = Date.now();
163
- const smoke = runSmokeAll(iteration);
164
- smokeTimes.push(smoke.ms);
165
- const failure = runNode(['scripts/tool-failures.mjs', '--since', since, '--limit', '1', '--json'], `failures iteration ${iteration}`, 60_000);
166
- if (actionableFailureCount(failure.stdout) > 0) {
167
- throw new Error(`tool failures appeared after loop start:\n${failure.stdout}`);
168
- }
169
- const currentRss = rssMb();
170
- rssSamples.push(currentRss);
171
- const elapsedMs = Date.now() - startedAt;
172
- writeLoopLog({
173
- type: 'iteration',
174
- iteration,
175
- smoke_ms: Math.round(smoke.ms * 10) / 10,
176
- steps: smoke.steps,
177
- rss_mb: currentRss,
178
- elapsed_ms: elapsedMs,
179
- });
180
- const stepSummary = smoke.steps.map((step) => `${step.script.replace(/^scripts\//, '')}=${step.ms}ms`).join(' ');
181
- process.stdout.write(`iteration ${iteration} ok smoke_ms=${smoke.ms.toFixed(1)} ${stepSummary} rss_mb=${currentRss} elapsed_ms=${elapsedMs}\n`);
182
- const remaining = deadline - Date.now();
183
- if (remaining <= 0 || iteration >= maxIterations) break;
184
- if (intervalMs > 0) await sleep(Math.min(intervalMs, remaining));
185
- if (Date.now() === iterStartedAt) await sleep(1);
186
- }
187
-
188
- const smokeSummary = summarize(smokeTimes);
189
- const rssSummary = summarize(rssSamples);
190
- const totalElapsedMs = Date.now() - startedAt;
191
- writeLoopLog({
192
- type: 'summary',
193
- iterations: iteration,
194
- elapsed_ms: totalElapsedMs,
195
- smoke_ms: smokeSummary,
196
- rss_mb: rssSummary,
197
- });
198
- process.stdout.write(
199
- `smoke loop passed iterations=${iteration} elapsed_ms=${totalElapsedMs} `
200
- + `smoke_ms=min:${smokeSummary.min},avg:${smokeSummary.avg},max:${smokeSummary.max} `
201
- + `rss_mb=min:${rssSummary.min},avg:${rssSummary.avg},max:${rssSummary.max}\n`,
202
- );
@@ -1,106 +0,0 @@
1
- # smoke-runtime-negative.ps1 — Negative-path tests against released win32-x64
2
- # runtime tarball. Validates: download, sha256, corrupt-tarball, fresh-extract
3
- # boot, double-init refusal, hostile-env survival.
4
- #
5
- # Env: TAG / OS / ARCH / RUNTIME_RELEASE_REPOSITORY (default tribgames/mixdog)
6
-
7
- $ErrorActionPreference = 'Stop'
8
-
9
- $Tag = if ($env:TAG) { $env:TAG } else { 'runtime-v0.4.0' }
10
- $Os = if ($env:OS) { $env:OS } else { 'win32' }
11
- $Arch = if ($env:ARCH) { $env:ARCH } else { 'x64' }
12
- $ReleaseRepo = if ($env:RUNTIME_RELEASE_REPOSITORY) { $env:RUNTIME_RELEASE_REPOSITORY } else { 'tribgames/mixdog' }
13
- $PgVer = '16.4'
14
- $PgvectorVer = '0.8.2'
15
-
16
- $Asset = "mixdog-runtime-${Os}-${Arch}-pg${PgVer}-pgvector${PgvectorVer}.tar.gz"
17
- $Url = "https://github.com/${ReleaseRepo}/releases/download/${Tag}/${Asset}"
18
-
19
- $Work = New-Item -ItemType Directory -Force -Path "$env:TEMP\smoke-$([guid]::NewGuid().ToString('N'))" | Select-Object -ExpandProperty FullName
20
-
21
- try {
22
- Write-Host "==> Negative-path smoke for ${Os}-${Arch} from $Url"
23
-
24
- Write-Host "==> Test 1: HEAD reaches release asset"
25
- $resp = Invoke-WebRequest -Uri $Url -Method Head -UseBasicParsing -ErrorAction Stop
26
- Write-Host " HTTP $($resp.StatusCode)"
27
-
28
- Write-Host "==> Test 2: full download + sha256"
29
- $TarPath = Join-Path $Work $Asset
30
- Invoke-WebRequest -Uri $Url -OutFile $TarPath -UseBasicParsing
31
- $sha = (Get-FileHash -Algorithm SHA256 $TarPath).Hash.ToLower()
32
- Write-Host " sha256=$sha"
33
-
34
- Write-Host "==> Test 3: corrupt tarball — flip a byte and ensure tar errors"
35
- $CorruptPath = "$Work\corrupt.tar.gz"
36
- Copy-Item $TarPath $CorruptPath
37
- $bytes = [byte[]]::new(1); $rand = [System.Random]::new(); $rand.NextBytes($bytes)
38
- $stream = [System.IO.File]::OpenWrite($CorruptPath)
39
- $stream.Position = 102400
40
- $stream.Write($bytes, 0, 1)
41
- $stream.Close()
42
- $CorruptDir = "$Work\corrupt"
43
- New-Item -ItemType Directory -Force -Path $CorruptDir | Out-Null
44
- $TarProc = Start-Process -FilePath tar -ArgumentList @('-xzf', $CorruptPath, '-C', $CorruptDir.Replace('\','/')) -Wait:$false -PassThru -WindowStyle Hidden
45
- if (-not $TarProc.WaitForExit(15000)) {
46
- Stop-Process -Id $TarProc.Id -Force -ErrorAction SilentlyContinue
47
- Write-Host " PASS: corrupted tarball extraction timed out and was stopped"
48
- } elseif ($TarProc.ExitCode -eq 0) {
49
- Write-Host " WARN: corrupted tarball extracted without error (tar gzip recovery)"
50
- } else {
51
- Write-Host " PASS: corrupted tarball rejected by tar (exit $($TarProc.ExitCode))"
52
- }
53
-
54
- Write-Host "==> Test 4: fresh-extract boot (extension load + distance query)"
55
- $FreshDir = "$Work\fresh"
56
- New-Item -ItemType Directory -Force -Path $FreshDir | Out-Null
57
- & tar -xzf $TarPath -C ($FreshDir.Replace('\','/'))
58
- if ($LASTEXITCODE -ne 0) { throw "fresh extract failed" }
59
-
60
- $PgBin = "$FreshDir\bin"
61
- $Data = "$FreshDir\pgdata"
62
- $Log = "$FreshDir\pg.log"
63
- $Port = 55897
64
-
65
- # Hostile env: minimal PATH (System32 only), no PGROOT/PGDATA
66
- $SavedPath = $env:PATH
67
- $SavedPgRoot = $env:PGROOT
68
- $env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
69
- $env:PGROOT = $null
70
- $env:PGDATA = $null
71
-
72
- try {
73
- & "$PgBin\postgres.exe" --version
74
- if ($LASTEXITCODE -ne 0) { throw "FAIL: postgres --version" }
75
- & "$PgBin\initdb.exe" -D $Data --username=postgres --auth-local=trust --no-locale -E UTF8 | Out-Null
76
- if ($LASTEXITCODE -ne 0) { throw "FAIL: initdb" }
77
- & "$PgBin\pg_ctl.exe" -D $Data -o "-p $Port -h 127.0.0.1" -l $Log -w start
78
- if ($LASTEXITCODE -ne 0) { Get-Content $Log | Select-Object -Last 30; throw "FAIL: pg_ctl start" }
79
-
80
- try {
81
- & "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -c "CREATE EXTENSION vector;" | Out-Null
82
- if ($LASTEXITCODE -ne 0) { throw "FAIL: CREATE EXTENSION" }
83
- $ExtV = & "$PgBin\psql.exe" -h 127.0.0.1 -p $Port -U postgres -d postgres -tAc "SELECT extversion FROM pg_extension WHERE extname='vector';"
84
- if ($ExtV.Trim() -ne $PgvectorVer) { throw "FAIL: extversion='$ExtV' expected='$PgvectorVer'" }
85
- Write-Host " PASS: fresh-extract boot + vector extension"
86
- } finally {
87
- & "$PgBin\pg_ctl.exe" -D $Data -m fast stop 2>$null | Out-Null
88
- }
89
-
90
- Write-Host "==> Test 5: second initdb on initialized dir refused"
91
- $rc = (Start-Process -FilePath "$PgBin\initdb.exe" -ArgumentList "-D",$Data,"-U","postgres" -Wait -PassThru -NoNewWindow).ExitCode
92
- if ($rc -eq 0) {
93
- Write-Host " WARN: second initdb succeeded (unexpected)"
94
- } else {
95
- Write-Host " PASS: second initdb refused (exit $rc)"
96
- }
97
- } finally {
98
- $env:PATH = $SavedPath
99
- $env:PGROOT = $SavedPgRoot
100
- }
101
-
102
- Write-Host "==> All negative-path smokes: PASS"
103
- }
104
- finally {
105
- Remove-Item -Recurse -Force $Work -ErrorAction SilentlyContinue
106
- }