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,216 +0,0 @@
1
- // Regression: OpenAI OAuth WS early tool-call settle.
2
- //
3
- // A tool-call response can be fully formed (function_call_arguments.done +
4
- // output_item.done) yet the server never emits the terminal
5
- // response.completed/response.done frame. Before the fix _streamResponse
6
- // coasted on that silence until a stall error (gated out of the loop via
7
- // pendingToolUse) or the 30-min agent watchdog, and -- because the socket was
8
- // still pooled -- the missing terminal frame later leaked onto the NEXT request
9
- // as orphan bytes (http_status=0 wedge). The fix resolves early with the
10
- // captured tool call and flags `closeSocket` so the pool discards the socket.
11
- import test from 'node:test';
12
- import assert from 'node:assert/strict';
13
- import { EventEmitter } from 'node:events';
14
- import { _streamResponse } from '../src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs';
15
- import { classifyMidstreamError, MIDSTREAM_RETRY_POLICY } from '../src/runtime/agent/orchestrator/providers/retry-classifier.mjs';
16
-
17
- // Minimal fake WS: matches the .on/.off/.close/.ping surface _streamResponse
18
- // uses. close() is a no-op here -- the early-settle path sets done=true before
19
- // calling it, so the real closeHandler would short-circuit anyway.
20
- class FakeSocket extends EventEmitter {
21
- constructor() {
22
- super();
23
- this.readyState = 1;
24
- this.closed = null;
25
- }
26
- close(code, reason) { this.closed = { code, reason }; }
27
- ping() {}
28
- feed(events) { for (const e of events) this.emit('message', JSON.stringify(e)); }
29
- }
30
-
31
- const FAST_TIMEOUTS = { interChunkMs: 40, preResponseCreatedMs: 5000, firstMeaningfulMs: 5000 };
32
-
33
- const TOOL_CALL_EVENTS = [
34
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
35
- { type: 'response.output_item.added', item: { type: 'function_call', id: 'fc_1', name: 'explore', call_id: 'call_1' } },
36
- { type: 'response.function_call_arguments.delta', item_id: 'fc_1', delta: '{"query"' },
37
- { type: 'response.function_call_arguments.done', item_id: 'fc_1', arguments: '{"query":"x"}', call_id: 'call_1', name: 'explore' },
38
- { type: 'response.output_item.done', item: { type: 'function_call', id: 'fc_1', name: 'explore', call_id: 'call_1', arguments: '{"query":"x"}' } },
39
- ];
40
-
41
- test('ws early settle: complete tool call resolves without response.completed and flags closeSocket', async () => {
42
- const socket = new FakeSocket();
43
- const state = {};
44
- const emitted = [];
45
- const p = _streamResponse({
46
- entry: { socket },
47
- state,
48
- onToolCall: (c) => emitted.push(c),
49
- _timeouts: FAST_TIMEOUTS,
50
- });
51
- socket.feed(TOOL_CALL_EVENTS);
52
- const result = await p;
53
- assert.equal(result.closeSocket, true, 'socket must be dropped, not pooled');
54
- assert.ok(Array.isArray(result.toolCalls) && result.toolCalls.length === 1);
55
- assert.equal(result.toolCalls[0].id, 'call_1');
56
- assert.equal(result.toolCalls[0].name, 'explore');
57
- assert.deepEqual(result.toolCalls[0].arguments, { query: 'x' });
58
- assert.equal(emitted.length, 1, 'tool call dispatched exactly once');
59
- assert.equal(state.wsEarlySettle, 'inter_chunk');
60
- assert.ok(socket.closed, 'socket.close() invoked so it is never reused');
61
- });
62
-
63
- test('ws early settle: normal response.completed path keeps the socket (no closeSocket)', async () => {
64
- const socket = new FakeSocket();
65
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
66
- socket.feed([
67
- ...TOOL_CALL_EVENTS,
68
- {
69
- type: 'response.completed',
70
- response: {
71
- id: 'resp_1',
72
- model: 'gpt-5.5',
73
- output: [{ type: 'function_call', id: 'fc_1', name: 'explore', call_id: 'call_1', arguments: '{"query":"x"}' }],
74
- },
75
- },
76
- ]);
77
- const result = await p;
78
- assert.equal(result.closeSocket, undefined, 'normal completion must not mark closeSocket');
79
- assert.equal(result.toolCalls.length, 1);
80
- });
81
-
82
- test('ws early settle: deferred salvage still pending does NOT early-settle (fails as stall)', async () => {
83
- const socket = new FakeSocket();
84
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
85
- // No output_item.added -> pendingCalls empty; args.done carries no call_id/name
86
- // -> a deferred placeholder that only response.completed could salvage.
87
- socket.feed([
88
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
89
- { type: 'response.function_call_arguments.delta', item_id: 'fc_1', delta: '{"query"' },
90
- { type: 'response.function_call_arguments.done', item_id: 'fc_1', arguments: '{"query":"x"}' },
91
- ]);
92
- await assert.rejects(p, /inter-chunk inactivity/);
93
- });
94
-
95
- test('ws early settle: complete tool then partial second tool does NOT early-settle', async () => {
96
- const socket = new FakeSocket();
97
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
98
- socket.feed([
99
- ...TOOL_CALL_EVENTS,
100
- { type: 'response.output_item.added', item: { type: 'function_call', id: 'fc_2', name: 'grep', call_id: 'call_2' } },
101
- { type: 'response.function_call_arguments.delta', item_id: 'fc_2', delta: '{"pattern"' },
102
- ]);
103
- await assert.rejects(p, /inter-chunk inactivity/);
104
- assert.equal(socket.closed?.reason, 'inter_chunk_timeout', 'partial second tool must use stall path, not early settle');
105
- });
106
-
107
- test('ws early settle: complete tool_search_call clears in-flight and can early-settle', async () => {
108
- const socket = new FakeSocket();
109
- const state = {};
110
- const p = _streamResponse({ entry: { socket }, state, _timeouts: FAST_TIMEOUTS });
111
- socket.feed([
112
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
113
- { type: 'response.output_item.added', item: { type: 'tool_search_call', id: 'ts_1' } },
114
- { type: 'response.output_item.done', item: { type: 'tool_search_call', id: 'ts_1', arguments: '{"query":"fetch"}' } },
115
- ]);
116
- const result = await p;
117
- assert.equal(result.closeSocket, true);
118
- assert.equal(result.toolCalls[0].id, 'ts_1');
119
- assert.equal(result.toolCalls[0].name, 'load_tool');
120
- assert.deepEqual(result.toolCalls[0].arguments, { query: 'fetch' });
121
- assert.equal(state.wsEarlySettle, 'inter_chunk');
122
- });
123
-
124
- test('ws early settle: complete tool_search_call plus partial custom tool does NOT early-settle', async () => {
125
- const socket = new FakeSocket();
126
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
127
- socket.feed([
128
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
129
- { type: 'response.output_item.added', item: { type: 'tool_search_call', id: 'ts_1' } },
130
- { type: 'response.output_item.done', item: { type: 'tool_search_call', id: 'ts_1', arguments: '{"query":"fetch"}' } },
131
- { type: 'response.output_item.added', item: { type: 'custom_tool_call', id: 'ct_2', call_id: 'call_custom_2', name: 'apply_patch' } },
132
- { type: 'response.custom_tool_call_input.delta', item_id: 'ct_2', delta: '*** Begin Patch' },
133
- ]);
134
- await assert.rejects(p, /inter-chunk inactivity/);
135
- assert.equal(socket.closed?.reason, 'inter_chunk_timeout', 'partial custom tool must keep stall path');
136
- });
137
-
138
- test('ws early settle: output_item.done salvages deferred function_call and can early-settle', async () => {
139
- const socket = new FakeSocket();
140
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
141
- socket.feed([
142
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
143
- { type: 'response.function_call_arguments.delta', item_id: 'fc_salvage', delta: '{"query"' },
144
- { type: 'response.function_call_arguments.done', item_id: 'fc_salvage', arguments: '{"query":"x"}' },
145
- { type: 'response.output_item.done', item: { type: 'function_call', id: 'fc_salvage', name: 'explore', call_id: 'call_salvage', arguments: '{"query":"x"}' } },
146
- ]);
147
- const result = await p;
148
- assert.equal(result.closeSocket, true);
149
- assert.equal(result.toolCalls[0].id, 'call_salvage');
150
- assert.equal(result.toolCalls[0].name, 'explore');
151
- assert.deepEqual(result.toolCalls[0].arguments, { query: 'x' });
152
- });
153
-
154
- test('ws early settle: call_id-only tool_search done clears id-tracked active item', async () => {
155
- const socket = new FakeSocket();
156
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
157
- socket.feed([
158
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
159
- { type: 'response.output_item.added', item: { type: 'tool_search_call', id: 'ts_added', call_id: 'ts_call' } },
160
- { type: 'response.output_item.done', item: { type: 'tool_search_call', call_id: 'ts_call', arguments: '{"query":"fetch"}' } },
161
- ]);
162
- const result = await p;
163
- assert.equal(result.closeSocket, true);
164
- assert.equal(result.toolCalls[0].id, 'ts_call');
165
- });
166
-
167
- test('ws early settle: function args.done without item.done does NOT early-settle', async () => {
168
- const socket = new FakeSocket();
169
- const p = _streamResponse({ entry: { socket }, state: {}, _timeouts: FAST_TIMEOUTS });
170
- socket.feed([
171
- { type: 'response.created', response: { id: 'resp_1', model: 'gpt-5.5' } },
172
- { type: 'response.output_item.added', item: { type: 'function_call', id: 'fc_empty', name: 'explore', call_id: 'call_empty' } },
173
- { type: 'response.function_call_arguments.done', item_id: 'fc_empty', arguments: '{}', call_id: 'call_empty', name: 'explore' },
174
- ]);
175
- await assert.rejects(p, /inter-chunk inactivity/);
176
- assert.equal(socket.closed?.reason, 'inter_chunk_timeout', 'function item must stay active until output_item.done');
177
- });
178
-
179
- test('OpenAI WS rejects an oversized Buffer before UTF-8 conversion and marks it retryable', async () => {
180
- const socket = new FakeSocket();
181
- const state = { attemptIndex: 0 };
182
- const payload = Buffer.alloc(33);
183
- payload.toString = () => { throw new Error('oversized Buffer was decoded'); };
184
- const p = _streamResponse({
185
- entry: { socket },
186
- state,
187
- _timeouts: { ...FAST_TIMEOUTS, maxIncomingFrameBytes: 32 },
188
- });
189
- socket.emit('message', payload);
190
- await assert.rejects(p, (error) => {
191
- assert.equal(error.code, 'EOPENAIWSFRAMETOOLARGE');
192
- assert.equal(error.retryable, true);
193
- assert.match(error.message, /33 bytes; limit 32 bytes.*retryable/);
194
- assert.equal(
195
- classifyMidstreamError(error, state, MIDSTREAM_RETRY_POLICY.ws),
196
- 'ws_frame_too_large',
197
- );
198
- return true;
199
- });
200
- assert.deepEqual(socket.closed, { code: 1009, reason: 'frame_too_large' });
201
- });
202
-
203
- test('OpenAI WS preserves normal-size Buffer handling', async () => {
204
- const socket = new FakeSocket();
205
- const p = _streamResponse({
206
- entry: { socket },
207
- state: {},
208
- _timeouts: { ...FAST_TIMEOUTS, maxIncomingFrameBytes: 1024 },
209
- });
210
- socket.emit('message', Buffer.from(JSON.stringify({
211
- type: 'response.completed',
212
- response: { id: 'resp_normal', model: 'gpt-5.5', output: [] },
213
- })));
214
- const result = await p;
215
- assert.equal(result.responseId, 'resp_normal');
216
- });
@@ -1,292 +0,0 @@
1
- #!/usr/bin/env node
2
- // Lead output-style verbosity bench (default >= simple >= minimal >= extreme-minimal).
3
- import { createRequire } from 'node:module';
4
- import { execFileSync } from 'node:child_process';
5
- import {
6
- copyFileSync,
7
- existsSync,
8
- mkdirSync,
9
- mkdtempSync,
10
- readdirSync,
11
- readFileSync,
12
- rmSync,
13
- writeFileSync,
14
- } from 'node:fs';
15
- import { homedir } from 'node:os';
16
- import { dirname, join, resolve } from 'node:path';
17
- import { fileURLToPath, pathToFileURL } from 'node:url';
18
-
19
- const __dir = dirname(fileURLToPath(import.meta.url));
20
- const REPO_ROOT = resolve(__dir, '..');
21
- const PLUGIN_ROOT = join(REPO_ROOT, 'src');
22
- const STYLES = ['default', 'simple', 'minimal', 'extreme-minimal'];
23
- const DEFAULT_PROMPT =
24
- 'Reply in plain English only. What is 2+2? Give a short summary suitable for a status report (no tools, no file reads).';
25
- const MODEL_ALIASES = {
26
- opus: { provider: 'anthropic-oauth', model: 'claude-opus-4-8' },
27
- sonnet: { provider: 'anthropic-oauth', model: 'claude-sonnet-5' },
28
- gpt: { provider: 'openai-oauth', model: 'gpt-5.5' },
29
- 'gpt-5.5': { provider: 'openai-oauth', model: 'gpt-5.5' },
30
- grok: { provider: 'grok-oauth', model: 'grok-composer-2.5-fast' },
31
- };
32
- // Filenames verified in provider ensureAuth / token paths (resolvePluginData / getPluginData).
33
- const AUTH_ARTIFACT_BY_PROVIDER = {
34
- 'grok-oauth': ['grok-oauth.json', 'grok-oauth-models.json'],
35
- 'anthropic-oauth': ['anthropic-oauth-credentials.json', 'anthropic-oauth-models.json'],
36
- 'openai-oauth': ['openai-oauth.json', 'openai-oauth-models.json'],
37
- };
38
-
39
- function argValue(name, fallback = null) {
40
- const idx = process.argv.indexOf(name);
41
- if (idx >= 0 && idx + 1 < process.argv.length) return process.argv[idx + 1];
42
- const pref = `${name}=`;
43
- const hit = process.argv.find((a) => a.startsWith(pref));
44
- return hit ? hit.slice(pref.length) : fallback;
45
- }
46
- function hasFlag(name) { return process.argv.includes(name); }
47
- function resolveModelOpts(modelArg, providerArg) {
48
- const key = String(modelArg || '').trim().toLowerCase();
49
- if (MODEL_ALIASES[key] && !providerArg) return { ...MODEL_ALIASES[key] };
50
- return { provider: providerArg || null, model: modelArg || null };
51
- }
52
- function defaultUserDataDir() {
53
- return process.env.MIXDOG_DATA_DIR || join(process.env.MIXDOG_HOME || join(homedir(), '.mixdog'), 'data');
54
- }
55
- function readUnifiedConfig(dataDir) {
56
- try {
57
- const unified = JSON.parse(readFileSync(join(dataDir, 'mixdog-config.json'), 'utf8'));
58
- return unified && typeof unified === 'object' ? unified : {};
59
- } catch { return {}; }
60
- }
61
- function outputStyleBodyFromMeta(meta) {
62
- const marker = '# Output Style';
63
- const idx = String(meta || '').lastIndexOf(marker);
64
- return idx < 0 ? '' : String(meta).slice(idx).trim();
65
- }
66
- function measureOutputText(text) {
67
- const trimmed = String(text || '').trim();
68
- const lines = trimmed ? trimmed.split(/\r?\n/) : [];
69
- const bullets = lines.filter((l) => /^\s*[-*•]\s+/.test(l)).length;
70
- const withoutCode = trimmed.replace(/`[^`]*`/g, '');
71
- const sentenceMarks = withoutCode.match(/[.!?。!?]+(?=\s|$)/g) || [];
72
- return {
73
- chars: trimmed.length,
74
- lines: lines.length,
75
- bullets,
76
- sentences: sentenceMarks.length || (trimmed ? 1 : 0),
77
- text: trimmed,
78
- };
79
- }
80
- function runInjectionScaffold() {
81
- const rulesBuilder = createRequire(import.meta.url)(join(PLUGIN_ROOT, 'lib', 'rules-builder.cjs'));
82
- const baseDir = mkdtempSync(join(REPO_ROOT, '.tmp-output-style-bench-'));
83
- const templatePath = join(PLUGIN_ROOT, 'defaults', 'mixdog-config.template.json');
84
- const baseConfig = existsSync(templatePath)
85
- ? JSON.parse(readFileSync(templatePath, 'utf8'))
86
- : { outputStyle: 'default' };
87
- const markers = {
88
- default: 'most detailed style',
89
- simple: 'Practical concise',
90
- minimal: 'a very short summary',
91
- 'extreme-minimal': 'exactly one sentence',
92
- };
93
- const snippets = {};
94
- try {
95
- for (const styleId of STYLES) {
96
- const dataDir = join(baseDir, styleId);
97
- mkdirSync(dataDir, { recursive: true });
98
- writeFileSync(join(dataDir, 'mixdog-config.json'), JSON.stringify({ ...baseConfig, outputStyle: styleId }, null, 2));
99
- snippets[styleId] = outputStyleBodyFromMeta(rulesBuilder.buildLeadMetaContent({ PLUGIN_ROOT, DATA_DIR: dataDir }));
100
- if (!snippets[styleId].includes(markers[styleId])) throw new Error(`${styleId} injection marker missing`);
101
- }
102
- if (new Set(STYLES.map((id) => snippets[id])).size !== STYLES.length) throw new Error('injection bodies not distinct');
103
- return { snippets };
104
- } finally {
105
- rmSync(baseDir, { recursive: true, force: true });
106
- }
107
- }
108
- function authArtifactNamesForSandbox(realDataDir, provider) {
109
- const names = new Set();
110
- for (const file of AUTH_ARTIFACT_BY_PROVIDER[provider] || []) names.add(file);
111
- try {
112
- for (const entry of readdirSync(realDataDir, { withFileTypes: true })) {
113
- if (!entry.isFile() || !entry.name.endsWith('.json')) continue;
114
- if (/oauth/i.test(entry.name) || /credentials/i.test(entry.name)) names.add(entry.name);
115
- }
116
- } catch { /* missing real data dir */ }
117
- return [...names];
118
- }
119
- function copyAuthArtifacts(realDataDir, sandboxDataDir, provider) {
120
- const copied = [];
121
- const skipped = [];
122
- for (const name of authArtifactNamesForSandbox(realDataDir, provider)) {
123
- const src = join(realDataDir, name);
124
- const dest = join(sandboxDataDir, name);
125
- if (!existsSync(src)) {
126
- skipped.push(name);
127
- continue;
128
- }
129
- try {
130
- copyFileSync(src, dest);
131
- copied.push(name);
132
- } catch {
133
- skipped.push(name);
134
- }
135
- }
136
- return { copied, skipped };
137
- }
138
- function prepareStyleSandbox(baseSandbox, styleId, userUnified, realDataDir, provider) {
139
- const dataDir = join(baseSandbox, styleId);
140
- mkdirSync(dataDir, { recursive: true });
141
- writeFileSync(join(dataDir, 'mixdog-config.json'), JSON.stringify({ ...userUnified, outputStyle: styleId }, null, 2));
142
- copyAuthArtifacts(realDataDir, dataDir, provider);
143
- return dataDir;
144
- }
145
- function findPresetRoute(config, key) {
146
- const wanted = String(key || '').trim().toLowerCase();
147
- if (!wanted) return null;
148
- const presets = Array.isArray(config?.presets) ? config.presets : [];
149
- return presets.find((p) => {
150
- const id = String(p?.id || '').trim().toLowerCase();
151
- const name = String(p?.name || '').trim().toLowerCase();
152
- return id === wanted || name === wanted;
153
- }) || null;
154
- }
155
- function resolveLeadProviderModel(userUnified, cli) {
156
- if (cli.provider && cli.model) return { provider: cli.provider, model: cli.model };
157
- const leadPreset = findPresetRoute(userUnified, 'workflow-lead')
158
- || findPresetRoute(userUnified, userUnified.default)
159
- || findPresetRoute(userUnified, 'gpt-5.5');
160
- if (leadPreset?.provider && leadPreset?.model) return { provider: leadPreset.provider, model: leadPreset.model };
161
- const alias = MODEL_ALIASES.gpt;
162
- return { provider: cli.provider || alias.provider, model: cli.model || alias.model };
163
- }
164
- function runLiveLeadTurn({ dataDir, prompt, provider, model, cwd, effort, fast }) {
165
- const cfgUrl = pathToFileURL(join(PLUGIN_ROOT, 'runtime/agent/orchestrator/config.mjs')).href;
166
- const regUrl = pathToFileURL(join(PLUGIN_ROOT, 'runtime/agent/orchestrator/providers/registry.mjs')).href;
167
- const mgrUrl = pathToFileURL(join(PLUGIN_ROOT, 'runtime/agent/orchestrator/session/manager.mjs')).href;
168
- const driver = [
169
- `import * as cfgMod from ${JSON.stringify(cfgUrl)};`,
170
- `import * as reg from ${JSON.stringify(regUrl)};`,
171
- `import { createSession, askSession, closeSession } from ${JSON.stringify(mgrUrl)};`,
172
- `const config = cfgMod.loadConfig({ secrets: true });`,
173
- `await reg.initProviders(config.providers || {});`,
174
- `const sessionOpts = { provider: ${JSON.stringify(provider)}, model: ${JSON.stringify(model)},`,
175
- ` owner: 'cli', agent: 'lead', lane: 'cli', sourceType: 'lead', sourceName: 'output-style-bench',`,
176
- ` cwd: ${JSON.stringify(cwd)}, tools: 'full', fast: ${fast ? 'true' : 'false'} };`,
177
- effort ? `sessionOpts.effort = ${JSON.stringify(effort)};` : '',
178
- `const session = createSession(sessionOpts);`,
179
- `let result;`,
180
- `try { result = await askSession(session.id, ${JSON.stringify(prompt)}, null, null, ${JSON.stringify(cwd)}); }`,
181
- `finally { try { closeSession(session.id, 'output-style-bench'); } catch {} }`,
182
- // Pooled provider sockets (e.g. openai-oauth WS, 20-min idle TTL) keep the
183
- // child alive after the turn; flush JSON then force-exit so execFileSync
184
- // returns as soon as the turn completes.
185
- `const payload = JSON.stringify({ text: String(result?.text || result?.content || '').trim(), sessionId: session.id });`,
186
- `await new Promise((r) => process.stdout.write(payload, r));`,
187
- `process.exit(0);`,
188
- ].filter(Boolean).join('\n');
189
- const raw = execFileSync('node', ['--input-type=module', '-e', driver], {
190
- encoding: 'utf8',
191
- maxBuffer: 64 * 1024 * 1024,
192
- timeout: Number(process.env.OUTPUT_STYLE_BENCH_TURN_TIMEOUT_MS || 10 * 60_000),
193
- killSignal: 'SIGKILL',
194
- env: { ...process.env, MIXDOG_ROOT: PLUGIN_ROOT, MIXDOG_DATA_DIR: dataDir },
195
- });
196
- const jsonStart = raw.lastIndexOf('{');
197
- if (jsonStart < 0) throw new Error(`live driver failed: ${raw.slice(0, 400)}`);
198
- return JSON.parse(raw.slice(jsonStart));
199
- }
200
- function styleCharCountsFromResults(results) {
201
- return Object.fromEntries(
202
- STYLES.map((id) => [id, results.find((r) => r.style === id)?.metrics.chars ?? 0]),
203
- );
204
- }
205
- function evaluateVerbosityOrdering(results) {
206
- const counts = STYLES.map((id) => results.find((r) => r.style === id)?.metrics.chars ?? 0);
207
- let orderingOk = true;
208
- for (let i = 1; i < counts.length; i += 1) {
209
- if (counts[i - 1] < counts[i]) orderingOk = false;
210
- }
211
- const chain = STYLES.map((id, i) => `${id}=${counts[i]}`).join(' ');
212
- const passLabel = STYLES.map((id) => `chars(${id})`).join(' >= ');
213
- const verdict = orderingOk
214
- ? `PASS ${passLabel}`
215
- : `WARN ordering violated: ${chain}`;
216
- return { orderingOk, verdict, counts: styleCharCountsFromResults(results) };
217
- }
218
- function printUsage() {
219
- process.stdout.write(`output-style-bench — Lead verbosity ladder (default >= simple >= minimal >= extreme-minimal).
220
-
221
- Output style is Lead-only (buildLeadMetaContent when owner is not agent).
222
- runHeadlessRole worker paths (owner=agent) do NOT inject outputStyle.
223
-
224
- Usage:
225
- node scripts/output-style-bench.mjs [--json]
226
- node scripts/output-style-bench.mjs --run [--model gpt] [--provider P] [--effort E] [--fast] [--prompt "..."] [--json]
227
-
228
- --run required for live calls. Temp MIXDOG_DATA_DIR: outputStyle override + read-only copy of OAuth/credential JSON from your real data dir.
229
- `);
230
- }
231
- function main() {
232
- const jsonMode = hasFlag('--json');
233
- const doRun = hasFlag('--run');
234
- const prompt = argValue('--prompt', DEFAULT_PROMPT);
235
- const cli = resolveModelOpts(argValue('--model', null), argValue('--provider', null));
236
- const effort = argValue('--effort', null);
237
- const fast = hasFlag('--fast');
238
- const cwd = process.cwd();
239
- let scaffold;
240
- try { scaffold = runInjectionScaffold(); }
241
- catch (e) { process.stderr.write(`[output-style-bench] scaffold FAILED: ${e.message}\n`); process.exit(1); }
242
- if (!doRun) {
243
- printUsage();
244
- const charCounts = Object.fromEntries(STYLES.map((id) => [id, scaffold.snippets[id].length]));
245
- if (jsonMode) {
246
- console.log(JSON.stringify({ mode: 'scaffold', role: 'lead', owner: 'cli', charCounts, liveCommand: 'node scripts/output-style-bench.mjs --run --model gpt' }, null, 2));
247
- } else {
248
- process.stdout.write(`[output-style-bench] scaffold ok: ${STYLES.map((id) => `${id}=${charCounts[id]}`).join(', ')}\n`);
249
- }
250
- process.exit(0);
251
- }
252
- const realDataDir = defaultUserDataDir();
253
- const userUnified = readUnifiedConfig(realDataDir);
254
- const route = resolveLeadProviderModel(userUnified, cli);
255
- const baseSandbox = mkdtempSync(join(REPO_ROOT, '.tmp-output-style-bench-live-'));
256
- const results = [];
257
- try {
258
- for (const styleId of STYLES) {
259
- const dataDir = prepareStyleSandbox(baseSandbox, styleId, userUnified, realDataDir, route.provider);
260
- process.stderr.write(`[output-style-bench] style=${styleId} ${route.provider}/${route.model}\n`);
261
- try {
262
- const live = runLiveLeadTurn({ dataDir, prompt, ...route, cwd, effort, fast });
263
- const metrics = measureOutputText(live.text);
264
- results.push({ style: styleId, ok: true, sessionId: live.sessionId, metrics, raw: metrics.text });
265
- } catch (err) {
266
- results.push({
267
- style: styleId,
268
- ok: false,
269
- error: String(err.stdout || err.stderr || err.message).slice(0, 2000),
270
- metrics: measureOutputText(''),
271
- });
272
- }
273
- }
274
- } finally {
275
- rmSync(baseSandbox, { recursive: true, force: true });
276
- }
277
- const { orderingOk, verdict } = evaluateVerbosityOrdering(results);
278
- if (jsonMode) {
279
- console.log(JSON.stringify({ mode: 'live', role: 'lead', prompt, route, results, verdict, orderingOk }, null, 2));
280
- } else {
281
- console.log(`live role=lead ${route.provider}/${route.model}`);
282
- for (const r of results) {
283
- const m = r.metrics;
284
- console.log(`- ${r.style}: ${r.ok ? 'ok' : 'FAIL'} chars=${m.chars} lines=${m.lines} bullets=${m.bullets} sentences=${m.sentences}`);
285
- if (r.ok) console.log(` ${m.text}`);
286
- else console.log(` error: ${String(r.error || '').slice(0, 300)}`);
287
- }
288
- console.log(verdict);
289
- }
290
- process.exit(results.every((r) => r.ok) ? 0 : 1);
291
- }
292
- main();
@@ -1,145 +0,0 @@
1
- #!/usr/bin/env node
2
- import { createRequire } from 'node:module';
3
- import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
4
- import { tmpdir } from 'node:os';
5
- import { dirname, join, resolve } from 'node:path';
6
- import { fileURLToPath } from 'node:url';
7
-
8
- const root = resolve(dirname(fileURLToPath(import.meta.url)), '..');
9
- const require = createRequire(import.meta.url);
10
- const rulesBuilder = require('../src/lib/rules-builder.cjs');
11
-
12
- function assert(condition, message) {
13
- if (!condition) throw new Error(message);
14
- }
15
-
16
- const DEFAULT_REPORT_LABELS = new Set(['Changes', 'Verification', 'Risks / next steps', '\uBC14\uB010 \uC810', '\uD655\uC778\uD55C \uAC83', '\uB0A8\uC740 \uB9AC\uC2A4\uD06C/\uB2E4\uC74C \uB2E8\uACC4', '\uB2E4\uC74C \uB2E8\uACC4']);
17
-
18
- function assertCleanOutput(name, value, { maxLines = 3, maxBullets = 3, allowedLabels = new Set() } = {}) {
19
- const text = String(value || '').trim();
20
- assert(text, `${name}: empty output`);
21
- assert(!/\n\s*\n/.test(text), `${name}: multiple paragraphs are not compact`);
22
- assert(!/^\s*#{1,6}\s/m.test(text), `${name}: heading found`);
23
- assert(!/^\s*\d+[.)]\s/m.test(text), `${name}: numbered list found`);
24
- assert(!/^\s{2,}[-*]\s/m.test(text), `${name}: nested bullet found`);
25
- for (const line of text.split(/\r?\n/)) {
26
- const match = line.match(/^\s*(?:[-*]\s+)?([\p{L}\p{N}][\p{L}\p{N} _/-]{0,30}):\s/u);
27
- if (match) assert(allowedLabels.has(match[1]), `${name}: disallowed report label found`);
28
- }
29
- assert(!/\b(?:tool trace|session metadata|model metadata|searched-path list)\b/i.test(text), `${name}: tool/meta trace found`);
30
- assert(!/\b(?:Mapped|Searched|Read|Called) for \d/i.test(text), `${name}: timing/tool status found`);
31
- assert(!/^(?:\uB124|\uC608|\uB9DE\uC544\uC694|\uC88B\uC544\uC694|\uC54C\uACA0\uC2B5\uB2C8\uB2E4|Sure|Okay|Understood)[,.\s]/i.test(text), `${name}: acknowledgment preface found`);
32
- assert(!/(.+)(?:\n|\s{2,})\1/.test(text), `${name}: repeated conclusion found`);
33
-
34
- const lines = text.split(/\r?\n/).filter((line) => line.trim());
35
- const bulletLines = lines.filter((line) => /^\s*[-*]\s+/.test(line));
36
- if (bulletLines.length > 0) {
37
- assert(bulletLines.length === lines.length, `${name}: mixed prose and bullets`);
38
- assert(bulletLines.length <= maxBullets, `${name}: too many bullets`);
39
- return;
40
- }
41
- assert(lines.length <= maxLines, `${name}: too many lines`);
42
-
43
- const withoutCode = text.replace(/`[^`]*`/g, '');
44
- const sentenceMarks = withoutCode.match(/[.!?。!?]|\uB2E4\.|\uC694\./g) || [];
45
- assert(sentenceMarks.length <= 2, `${name}: too many sentences`);
46
- }
47
-
48
- const defaultStyle = readFileSync(join(root, 'src', 'output-styles', 'default.md'), 'utf8');
49
- for (const required of [
50
- 'name: default',
51
- 'Concise engineering summaries',
52
- 'Mixdog default — the most detailed style',
53
- 'State conclusions, not reasoning',
54
- 'Use labels such as',
55
- '`Changes`, `Verification`,',
56
- 'Synthesize agent or retrieval results',
57
- 'Do not hide blockers',
58
- ]) {
59
- assert(defaultStyle.includes(required), `default.md missing: ${required}`);
60
- }
61
- assert(!defaultStyle.includes('Claude Code-compact'), 'default.md must not reference the old compact style name');
62
- assert(!defaultStyle.includes('Hard cap user-visible replies'), 'default.md must not hard-cap replies to two short sentences');
63
- assert(!defaultStyle.includes('Be short and direct.'), 'default.md must not keep the old generic concise preset');
64
- assert(!defaultStyle.includes('Practical concise — outcome-first handoffs'), 'default.md must not use the simple preset body');
65
-
66
- const simpleStyle = readFileSync(join(root, 'src', 'output-styles', 'simple.md'), 'utf8');
67
- for (const required of [
68
- 'name: simple',
69
- 'Outcome-first concise handoffs for coding work',
70
- 'Practical concise — outcome-first handoffs',
71
- 'file_path:line_number',
72
- 'Controlled detail',
73
- 'Synthesize agent or retrieval results',
74
- 'Do not hide blockers',
75
- 'verification was not run, say so once',
76
- ]) {
77
- assert(simpleStyle.includes(required), `simple.md missing: ${required}`);
78
- }
79
- assert(!simpleStyle.includes('Mixdog default — the most detailed of the three styles'), 'simple.md must not duplicate default preset body');
80
- for (const [name, style] of Object.entries({
81
- default: defaultStyle,
82
- simple: simpleStyle,
83
- minimal: readFileSync(join(root, 'src', 'output-styles', 'minimal.md'), 'utf8'),
84
- 'extreme-minimal': readFileSync(join(root, 'src', 'output-styles', 'extreme-minimal.md'), 'utf8'),
85
- })) {
86
- assert(!style.includes('pre-tool preamble'), `${name} output style must not own language preamble rules`);
87
- assert(!style.includes('selected/default user language'), `${name} output style must not duplicate profile language rules`);
88
- }
89
-
90
- const dataDir = mkdtempSync(join(tmpdir(), 'mixdog-output-style-smoke-'));
91
- try {
92
- writeFileSync(join(dataDir, 'user-workflow.md'), 'workflow context should not override output style\n');
93
- const leadRules = rulesBuilder.buildInjectionContent({ PLUGIN_ROOT: join(root, 'src'), DATA_DIR: dataDir });
94
- const outputStyleIndex = leadRules.lastIndexOf('# Output Style');
95
- assert(outputStyleIndex >= 0, 'Lead output style missing');
96
- assert(outputStyleIndex > leadRules.lastIndexOf('# User Workflow'), 'Lead output style must be injected after workflow/user context');
97
-
98
- mkdirSync(join(dataDir, 'output-styles'), { recursive: true });
99
- writeFileSync(join(dataDir, 'mixdog-config.json'), JSON.stringify({
100
- agent: { profile: { title: '\uD64D\uAE38\uB3D9\uB2D8', language: 'system' } },
101
- outputStyle: 'custom-smoke',
102
- }));
103
- writeFileSync(join(dataDir, 'output-styles', 'custom-smoke.md'), '---\nname: custom-smoke\n---\n\n# Custom Output Style\n\ncustom smoke style\n');
104
- const customRules = rulesBuilder.buildInjectionContent({ PLUGIN_ROOT: join(root, 'src'), DATA_DIR: dataDir });
105
- assert(customRules.includes('# Custom Output Style'), 'configured outputStyle must select custom style');
106
- assert(!customRules.includes('Mixdog default — the most detailed of the three styles'), 'custom outputStyle should not append default style');
107
- const profileMeta = rulesBuilder.buildLeadMetaContent({ PLUGIN_ROOT: join(root, 'src'), DATA_DIR: dataDir });
108
- assert(profileMeta.includes('Use "\uD64D\uAE38\uB3D9\uB2D8" when directly addressing the user'), 'profile title must inject into Lead BP3 meta');
109
- assert(profileMeta.includes('do not repeat it in routine progress updates or pre-tool preambles'), 'profile title must not encourage title in preambles');
110
- assert(/Default user-facing response language from system locale/.test(profileMeta), 'system profile language must resolve from system locale');
111
- assert(profileMeta.includes('pre-tool preambles (even single-line)'), 'profile language must cover pre-tool preambles');
112
- } finally {
113
- rmSync(dataDir, { recursive: true, force: true });
114
- }
115
-
116
- // assertCleanOutput encodes the Simple style compact contract (not Default, which may be longer).
117
- const goodOutputs = {
118
- explanation: 'Simple \uC2A4\uD0C0\uC77C\uC740 \uACB0\uACFC \uD55C \uC904\uACFC \uADFC\uAC70 \uD55C \uAC00\uC9C0\uB85C \uB05D\uB0B4\uACE0, \uCD5C\uC885 handoff\uB9CC \uC9E7\uC740 bullet \uB77C\uBCA8\uC744 \uC501\uB2C8\uB2E4.',
119
- implementation: '- \uBC14\uB010 \uC810: `scripts/output-style-smoke.mjs`\uC758 default/simple \uBB38\uC790\uC5F4 \uAC80\uC99D\uC744 \uD604\uC7AC \uD504\uB9AC\uC14B\uC5D0 \uB9DE\uCDC4\uC2B5\uB2C8\uB2E4.\n- \uD655\uC778\uD55C \uAC83: `node scripts/output-style-smoke.mjs`\uB97C \uC2E4\uD589\uD588\uC2B5\uB2C8\uB2E4.',
120
- crowded: '- \uBC14\uB010 \uC810: compact guardrail\uC740 Simple handoff\uC6A9 controlled detail\uC744 \uAC80\uC99D\uD569\uB2C8\uB2E4.\n- \uD655\uC778\uD55C \uAC83: bad \uC0D8\uD50C \uAC70\uBD80 \uADDC\uCE59\uC740 \uADF8\uB300\uB85C\uC785\uB2C8\uB2E4.',
121
- blocker: '`scripts/output-style-smoke.mjs`\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4 \uBCC0\uACBD\uC774 \uB9C9\uD614\uC2B5\uB2C8\uB2E4.',
122
- semicolon: '\uC2A4\uBAA8\uD06C \uC2A4\uD06C\uB9BD\uD2B8\uB97C \uAC31\uC2E0\uD588\uACE0; Simple \uACC4\uC57D\uC5D0 \uB9DE\uB294 \uC608\uC2DC \uC751\uB2F5\uB9CC \uD1B5\uACFC\uD569\uB2C8\uB2E4.',
123
- };
124
- for (const [name, output] of Object.entries(goodOutputs)) assertCleanOutput(name, output, { allowedLabels: DEFAULT_REPORT_LABELS });
125
-
126
- const badOutputs = {
127
- heading: '## Summary\nDone.',
128
- label: 'Changed: updated default style.',
129
- koreanLabel: '\uBCC0\uACBD: default \uC2A4\uD0C0\uC77C\uC744 \uC218\uC815\uD588\uC2B5\uB2C8\uB2E4.\n\uAC80\uC99D: \uC2A4\uBAA8\uD06C\uB97C \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4.',
130
- numbered: '1. Updated style\n2. Ran smoke',
131
- paragraphs: 'Done.\n\nDone again.',
132
- nested: '- Updated\n - Nested detail',
133
- ack: '\uB124, default \uC2A4\uD0C0\uC77C\uC744 \uC218\uC815\uD588\uC2B5\uB2C8\uB2E4.',
134
- timing: 'Mapped for 2m 32s\n\ndefault \uC2A4\uD0C0\uC77C\uC744 \uC218\uC815\uD588\uC2B5\uB2C8\uB2E4.',
135
- tooManySentences: '\uC218\uC815\uD588\uC2B5\uB2C8\uB2E4. \uAC80\uC99D\uD588\uC2B5\uB2C8\uB2E4. \uBCF4\uACE0\uD588\uC2B5\uB2C8\uB2E4.',
136
- mixed: '\uC218\uC815\uD588\uC2B5\uB2C8\uB2E4.\n- \uAC80\uC99D\uD588\uC2B5\uB2C8\uB2E4.',
137
- tooManyBullets: '- \uBC14\uB010 \uC810: A\n- \uD655\uC778\uD55C \uAC83: B\n- \uB2E4\uC74C \uB2E8\uACC4: C\n- \uB0A8\uC740 \uB9AC\uC2A4\uD06C/\uB2E4\uC74C \uB2E8\uACC4: D',
138
- };
139
- for (const [name, output] of Object.entries(badOutputs)) {
140
- let failed = false;
141
- try { assertCleanOutput(`bad:${name}`, output, { allowedLabels: DEFAULT_REPORT_LABELS }); } catch { failed = true; }
142
- assert(failed, `bad sample unexpectedly passed: ${name}`);
143
- }
144
-
145
- process.stdout.write(`output style smoke passed samples=${Object.keys(goodOutputs).length}\n`);