mixdog 0.9.3 → 0.9.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (329) hide show
  1. package/package.json +7 -3
  2. package/scripts/bench/lead-review-tasks-r3.json +20 -0
  3. package/scripts/bench/lead-review-tasks.json +20 -0
  4. package/scripts/bench/r4-mixed-tasks.json +20 -0
  5. package/scripts/bench/review-tasks.json +20 -0
  6. package/scripts/bench/round-codex.json +114 -0
  7. package/scripts/bench/round-mixdog-lead-r3.json +269 -0
  8. package/scripts/bench/round-mixdog-lead.json +269 -0
  9. package/scripts/bench/round-mixdog.json +126 -0
  10. package/scripts/bench/round-r10-bigsample.json +679 -0
  11. package/scripts/bench/round-r11-codexalign.json +257 -0
  12. package/scripts/bench/round-r4-codex.json +114 -0
  13. package/scripts/bench/round-r4-mixed.json +225 -0
  14. package/scripts/bench/round-r5-gpt-lead.json +259 -0
  15. package/scripts/bench/round-r6-codex.json +114 -0
  16. package/scripts/bench/round-r6-solo.json +257 -0
  17. package/scripts/bench/round-r7-full.json +254 -0
  18. package/scripts/bench/round-r8-fulldefault.json +255 -0
  19. package/scripts/bench-run.mjs +215 -29
  20. package/scripts/freevar-smoke.mjs +95 -0
  21. package/scripts/internal-comms-bench.mjs +1 -0
  22. package/scripts/internal-comms-smoke.mjs +10 -9
  23. package/scripts/mouse-probe.mjs +45 -0
  24. package/scripts/output-style-bench.mjs +13 -6
  25. package/scripts/output-style-smoke.mjs +4 -4
  26. package/scripts/provider-toolcall-test.mjs +7 -3
  27. package/scripts/recall-usecase-cases.json +18 -0
  28. package/scripts/recall-usecase-probe.json +6 -0
  29. package/scripts/session-bench.mjs +152 -6
  30. package/scripts/tool-smoke.mjs +23 -63
  31. package/scripts/tui-render-smoke.mjs +90 -0
  32. package/scripts/webhook-smoke.mjs +208 -0
  33. package/src/agents/debugger/AGENT.md +4 -1
  34. package/src/agents/heavy-worker/AGENT.md +6 -5
  35. package/src/agents/maintainer/AGENT.md +4 -0
  36. package/src/agents/reviewer/AGENT.md +2 -1
  37. package/src/agents/worker/AGENT.md +8 -4
  38. package/src/lib/rules-builder.cjs +4 -0
  39. package/src/mixdog-session-runtime.mjs +632 -2042
  40. package/src/output-styles/default.md +34 -9
  41. package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
  42. package/src/output-styles/minimal.md +4 -1
  43. package/src/output-styles/simple.md +22 -7
  44. package/src/rules/agent/00-common.md +2 -0
  45. package/src/rules/lead/lead-brief.md +12 -0
  46. package/src/rules/lead/lead-tool.md +0 -11
  47. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
  48. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
  49. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
  50. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
  51. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
  52. package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
  53. package/src/runtime/agent/orchestrator/config.mjs +69 -2
  54. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
  55. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
  56. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
  57. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
  58. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
  59. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
  60. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
  61. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
  62. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
  63. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
  64. package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
  65. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
  66. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
  67. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
  68. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
  69. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
  70. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
  71. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
  73. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +297 -2123
  76. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +130 -1002
  77. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
  78. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
  79. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
  80. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
  81. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
  82. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
  83. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
  84. package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
  85. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
  86. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
  87. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
  88. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
  89. package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
  90. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
  91. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
  92. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
  93. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
  94. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
  95. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
  96. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
  97. package/src/runtime/agent/orchestrator/session/loop.mjs +251 -397
  98. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
  99. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
  100. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
  101. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
  102. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
  103. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
  104. package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
  105. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
  106. package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
  107. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
  108. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
  109. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +32 -41
  110. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
  111. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
  112. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
  113. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
  114. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
  115. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
  116. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
  118. package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
  119. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
  120. package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
  121. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
  122. package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
  123. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  124. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
  125. package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
  126. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
  127. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
  128. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
  129. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
  130. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
  131. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
  132. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
  133. package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
  134. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
  135. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
  136. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
  137. package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
  138. package/src/runtime/channels/backends/discord-access.mjs +32 -0
  139. package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
  140. package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
  141. package/src/runtime/channels/backends/discord.mjs +12 -292
  142. package/src/runtime/channels/index.mjs +229 -663
  143. package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
  144. package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
  145. package/src/runtime/channels/lib/event-queue.mjs +63 -4
  146. package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
  147. package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
  148. package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
  149. package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
  150. package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
  151. package/src/runtime/channels/lib/session-discovery.mjs +56 -4
  152. package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
  153. package/src/runtime/channels/lib/tool-format.mjs +1 -1
  154. package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
  155. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
  156. package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
  157. package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
  158. package/src/runtime/channels/lib/webhook/log.mjs +42 -0
  159. package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
  160. package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
  161. package/src/runtime/channels/lib/webhook.mjs +36 -570
  162. package/src/runtime/channels/tool-defs.mjs +11 -130
  163. package/src/runtime/memory/index.mjs +201 -1948
  164. package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
  165. package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
  166. package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
  167. package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
  168. package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
  169. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
  170. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
  171. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
  172. package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
  173. package/src/runtime/memory/lib/memory-embed.mjs +149 -0
  174. package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
  175. package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
  176. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
  177. package/src/runtime/memory/lib/query-handlers.mjs +780 -0
  178. package/src/runtime/memory/lib/recall-format.mjs +55 -0
  179. package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
  180. package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
  181. package/src/runtime/memory/tool-defs.mjs +5 -13
  182. package/src/runtime/search/lib/http-fetch.mjs +274 -0
  183. package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
  184. package/src/runtime/search/lib/web-tools.mjs +24 -602
  185. package/src/runtime/shared/atomic-file.mjs +26 -1
  186. package/src/runtime/shared/launcher-control.mjs +2 -2
  187. package/src/runtime/shared/tool-primitives.mjs +308 -0
  188. package/src/runtime/shared/tool-result-summary.mjs +515 -0
  189. package/src/runtime/shared/tool-surface.mjs +80 -898
  190. package/src/runtime/shared/transcript-writer.mjs +23 -0
  191. package/src/runtime/shared/update-checker.mjs +7 -4
  192. package/src/session-runtime/config-helpers.mjs +84 -2
  193. package/src/session-runtime/config-lifecycle.mjs +232 -0
  194. package/src/session-runtime/cwd-plugins.mjs +226 -0
  195. package/src/session-runtime/mcp-glue.mjs +177 -0
  196. package/src/session-runtime/model-recency.mjs +111 -0
  197. package/src/session-runtime/native-search.mjs +247 -0
  198. package/src/session-runtime/output-styles.mjs +11 -9
  199. package/src/session-runtime/prewarm.mjs +142 -0
  200. package/src/session-runtime/provider-models.mjs +278 -0
  201. package/src/session-runtime/provider-usage.mjs +120 -0
  202. package/src/session-runtime/quick-model-rows.mjs +170 -0
  203. package/src/session-runtime/quick-search-models.mjs +46 -0
  204. package/src/session-runtime/session-hooks.mjs +93 -0
  205. package/src/session-runtime/settings-api.mjs +319 -0
  206. package/src/session-runtime/tool-catalog.mjs +29 -29
  207. package/src/session-runtime/tool-defs.mjs +84 -0
  208. package/src/session-runtime/warmup-schedulers.mjs +201 -0
  209. package/src/standalone/agent-tool/helpers.mjs +237 -0
  210. package/src/standalone/agent-tool/notify.mjs +107 -0
  211. package/src/standalone/agent-tool/provider-init.mjs +143 -0
  212. package/src/standalone/agent-tool/render.mjs +152 -0
  213. package/src/standalone/agent-tool/tool-def.mjs +55 -0
  214. package/src/standalone/agent-tool.mjs +110 -671
  215. package/src/standalone/channel-worker.mjs +4 -7
  216. package/src/standalone/explore-tool.mjs +30 -9
  217. package/src/standalone/hook-bus/config.mjs +207 -0
  218. package/src/standalone/hook-bus/constants.mjs +90 -0
  219. package/src/standalone/hook-bus/handlers.mjs +481 -0
  220. package/src/standalone/hook-bus/payload.mjs +31 -0
  221. package/src/standalone/hook-bus/rules.mjs +77 -0
  222. package/src/standalone/hook-bus.mjs +77 -870
  223. package/src/standalone/memory-runtime-proxy.mjs +7 -0
  224. package/src/standalone/opencode-go-login.mjs +5 -1
  225. package/src/standalone/provider-admin.mjs +1 -16
  226. package/src/standalone/usage-dashboard.mjs +3 -1
  227. package/src/tui/App.jsx +945 -8094
  228. package/src/tui/app/app-format.mjs +206 -0
  229. package/src/tui/app/channel-pickers.mjs +510 -0
  230. package/src/tui/app/clipboard.mjs +67 -0
  231. package/src/tui/app/core-memory-picker.mjs +210 -0
  232. package/src/tui/app/extension-pickers.mjs +506 -0
  233. package/src/tui/app/input-parsers.mjs +193 -0
  234. package/src/tui/app/maintenance-pickers.mjs +324 -0
  235. package/src/tui/app/model-options.mjs +330 -0
  236. package/src/tui/app/model-picker.mjs +365 -0
  237. package/src/tui/app/onboarding-steps.mjs +400 -0
  238. package/src/tui/app/project-picker.mjs +247 -0
  239. package/src/tui/app/provider-setup-picker.mjs +580 -0
  240. package/src/tui/app/resume-picker.mjs +55 -0
  241. package/src/tui/app/route-pickers.mjs +419 -0
  242. package/src/tui/app/settings-picker.mjs +490 -0
  243. package/src/tui/app/slash-commands.mjs +101 -0
  244. package/src/tui/app/slash-dispatch.mjs +427 -0
  245. package/src/tui/app/text-layout.mjs +46 -0
  246. package/src/tui/app/theme-effort-pickers.mjs +154 -0
  247. package/src/tui/app/transcript-window.mjs +671 -0
  248. package/src/tui/app/use-mouse-input.mjs +460 -0
  249. package/src/tui/app/use-prompt-handlers.mjs +310 -0
  250. package/src/tui/app/use-transcript-scroll.mjs +510 -0
  251. package/src/tui/app/use-transcript-window.mjs +589 -0
  252. package/src/tui/components/ConfirmBar.jsx +1 -1
  253. package/src/tui/components/Picker.jsx +32 -4
  254. package/src/tui/components/PromptInput.jsx +23 -101
  255. package/src/tui/components/SlashCommandPalette.jsx +8 -1
  256. package/src/tui/components/StatusLine.jsx +63 -12
  257. package/src/tui/components/TextEntryPanel.jsx +11 -0
  258. package/src/tui/components/ToolExecution.jsx +52 -594
  259. package/src/tui/components/TranscriptItem.jsx +105 -0
  260. package/src/tui/components/UsagePanel.jsx +18 -4
  261. package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
  262. package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
  263. package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
  264. package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
  265. package/src/tui/components/tool-execution/text-format.mjs +161 -0
  266. package/src/tui/display-width.mjs +20 -3
  267. package/src/tui/dist/index.mjs +19652 -18630
  268. package/src/tui/engine/agent-job-feed.mjs +133 -0
  269. package/src/tui/engine/notification-plan.mjs +76 -0
  270. package/src/tui/engine/render-timing.mjs +17 -0
  271. package/src/tui/engine/tool-approval.mjs +94 -0
  272. package/src/tui/engine/tool-card-results.mjs +234 -0
  273. package/src/tui/engine/tool-result-status.mjs +135 -0
  274. package/src/tui/engine.mjs +122 -562
  275. package/src/tui/figures.mjs +5 -0
  276. package/src/tui/index.jsx +105 -0
  277. package/src/tui/input-editing.mjs +2 -2
  278. package/src/tui/markdown/format-token.mjs +4 -1
  279. package/src/tui/statusline-ansi-bridge.mjs +11 -3
  280. package/src/tui/theme.mjs +6 -0
  281. package/src/ui/statusline-agents.mjs +213 -0
  282. package/src/ui/statusline-format.mjs +146 -0
  283. package/src/ui/statusline-segments.mjs +148 -0
  284. package/src/ui/statusline.mjs +67 -501
  285. package/src/ui/tool-card.mjs +0 -1
  286. package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
  287. package/src/workflows/default/WORKFLOW.md +1 -1
  288. package/src/workflows/sequential/WORKFLOW.md +1 -1
  289. package/vendor/ink/build/display-width.js +19 -3
  290. package/vendor/ink/build/ink.js +103 -6
  291. package/vendor/ink/build/log-update.js +17 -3
  292. package/vendor/ink/build/wrap-text.js +125 -0
  293. package/scripts/_test-folder-dialog.mjs +0 -30
  294. package/scripts/fix-brief-fn.mjs +0 -35
  295. package/scripts/fix-format-tool-surface.mjs +0 -24
  296. package/scripts/fix-tool-exec-visible.mjs +0 -42
  297. package/scripts/patch-agent-brief.mjs +0 -48
  298. package/scripts/patch-app.mjs +0 -21
  299. package/scripts/patch-app2.mjs +0 -18
  300. package/scripts/patch-dist-brief.mjs +0 -96
  301. package/scripts/patch-tool-exec.mjs +0 -70
  302. package/src/examples/schedules/SCHEDULE.example.md +0 -32
  303. package/src/examples/webhooks/WEBHOOK.example.md +0 -40
  304. package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
  305. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
  306. package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
  307. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
  308. package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
  309. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
  310. package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
  311. package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
  312. package/src/standalone/agent-task-status.test.mjs +0 -76
  313. package/src/tui/components/tool-output-format.test.mjs +0 -399
  314. package/src/tui/display-width.test.mjs +0 -35
  315. package/src/tui/engine-runtime-notification.test.mjs +0 -115
  316. package/src/tui/engine-tool-result-text.test.mjs +0 -75
  317. package/src/tui/input-editing.selection.test.mjs +0 -75
  318. package/src/tui/markdown/format-token.test.mjs +0 -354
  319. package/src/tui/markdown/render-ansi.test.mjs +0 -108
  320. package/src/tui/markdown/stream-fence.test.mjs +0 -26
  321. package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
  322. package/src/tui/paste-fix.test.mjs +0 -119
  323. package/src/tui/prompt-history-store.test.mjs +0 -52
  324. package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
  325. package/src/tui/transcript-tool-failures.test.mjs +0 -111
  326. package/src/ui/markdown.test.mjs +0 -70
  327. package/src/ui/statusline-context-label.test.mjs +0 -15
  328. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
  329. package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -33,7 +33,7 @@
33
33
  "prepack": "npm run build:tui",
34
34
  "start": "node src/cli.mjs",
35
35
  "smoke": "node scripts/smoke.mjs",
36
- "smoke:all": "npm run smoke && npm run smoke:boot && npm run smoke:tools && npm run smoke:output",
36
+ "smoke:all": "npm run smoke && npm run smoke:boot && npm run smoke:tools && npm run smoke:output && npm run smoke:tui && npm run smoke:freevars",
37
37
  "smoke:boot": "node scripts/boot-smoke.mjs",
38
38
  "smoke:compact": "node scripts/compact-smoke.mjs",
39
39
  "smoke:loop": "node scripts/smoke-loop.mjs",
@@ -41,6 +41,8 @@
41
41
  "smoke:loop:report": "node scripts/smoke-loop-report.mjs",
42
42
  "smoke:tools": "node scripts/tool-smoke.mjs",
43
43
  "smoke:output": "node scripts/output-style-smoke.mjs",
44
+ "smoke:tui": "node scripts/tui-render-smoke.mjs",
45
+ "smoke:freevars": "node scripts/freevar-smoke.mjs",
44
46
  "test:toolcall": "node --test scripts/toolcall-args-test.mjs",
45
47
  "test:providers": "node --test scripts/provider-toolcall-test.mjs",
46
48
  "failures": "node scripts/tool-failures.mjs",
@@ -92,6 +94,8 @@
92
94
  }
93
95
  },
94
96
  "devDependencies": {
95
- "esbuild": "^0.28.1"
97
+ "acorn": "^8.17.0",
98
+ "esbuild": "^0.28.1",
99
+ "eslint-scope": "^9.1.2"
96
100
  }
97
101
  }
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "id": "lead-review-session-runtime",
4
+ "agent": "reviewer",
5
+ "cwd": "C:/Project/mixdog-bench",
6
+ "prompt": "READ-ONLY review task: you and any delegated agents must NOT modify, create, or delete any files - report findings only. Review the folder src/session-runtime/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: broken imports, undefined identifiers, race conditions, wrong fallbacks, data loss paths. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
7
+ },
8
+ {
9
+ "id": "lead-review-channels-lib",
10
+ "agent": "reviewer",
11
+ "cwd": "C:/Project/mixdog-bench",
12
+ "prompt": "READ-ONLY review task: you and any delegated agents must NOT modify, create, or delete any files - report findings only. Review the folder src/runtime/channels/lib/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: message loss, double-forwarding, ownership races, watcher leaks, unsafe input handling. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
13
+ },
14
+ {
15
+ "id": "lead-review-compact",
16
+ "agent": "reviewer",
17
+ "cwd": "C:/Project/mixdog-bench",
18
+ "prompt": "READ-ONLY review task: you and any delegated agents must NOT modify, create, or delete any files - report findings only. Review the folder src/runtime/agent/orchestrator/session/compact/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: schema validation gaps, data corruption on summarize, lossy round-trips, error swallowing. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
19
+ }
20
+ ]
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "id": "lead-review-session-runtime",
4
+ "agent": "reviewer",
5
+ "cwd": "C:/Project/mixdog-bench",
6
+ "prompt": "Review the folder src/session-runtime/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: broken imports, undefined identifiers, race conditions, wrong fallbacks, data loss paths. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
7
+ },
8
+ {
9
+ "id": "lead-review-channels-lib",
10
+ "agent": "reviewer",
11
+ "cwd": "C:/Project/mixdog-bench",
12
+ "prompt": "Review the folder src/runtime/channels/lib/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: message loss, double-forwarding, ownership races, watcher leaks, unsafe input handling. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
13
+ },
14
+ {
15
+ "id": "lead-review-compact",
16
+ "agent": "reviewer",
17
+ "cwd": "C:/Project/mixdog-bench",
18
+ "prompt": "Review the folder src/runtime/agent/orchestrator/session/compact/ for correctness, regression, and security risks. Delegate exploration/reading to your workflow agents where useful and synthesize their findings. Focus on real actionable bugs: schema validation gaps, data corruption on summarize, lossy round-trips, error swallowing. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
19
+ }
20
+ ]
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "id": "r4-debug-forwarding-gap",
4
+ "agent": "reviewer",
5
+ "cwd": "C:/Project/mixdog-bench",
6
+ "prompt": "Investigate a real reliability question in this repo: when the Discord channel bridge activates (bridge-state.json written) there can be a window where assistant output is not yet forwarded to the channel - transcript binding, fs.watch on a not-yet-created transcript file, and ownership probes are involved. Trace the full path from bridge activation to first forwarded message in src/runtime/channels/ (index.mjs, lib/output-forwarder.mjs), identify every gap where output produced during the window would be silently dropped or delayed, and state for each gap whether backlog catch-up recovers it. Report findings ordered by impact with file:line anchors. End with a one-line verdict."
7
+ },
8
+ {
9
+ "id": "r4-impl-usage-summary",
10
+ "agent": "worker",
11
+ "cwd": "C:/Project/mixdog-bench",
12
+ "prompt": "Implement a small feature: add a `usage:today` npm script backed by a new scripts/usage-today.mjs that reads ~/.mixdog/data/history/agent-trace.jsonl (respect MIXDOG_DATA_DIR), filters usage rows from local midnight, and prints per-model calls, input/cached/output tokens, and costUsd totals plus a grand total line. Follow the style of scripts/session-bench.mjs arg parsing. Verify with node --check and run it once. Report the diff summary."
13
+ },
14
+ {
15
+ "id": "r4-explain-compact-engine",
16
+ "agent": "explore",
17
+ "cwd": "C:/Project/mixdog-bench",
18
+ "prompt": "Map the compaction subsystem: starting from src/runtime/agent/orchestrator/session/compact/engine.mjs, produce a concise architecture brief - entry points and callers, the decision flow for when compaction fires, how the preserved tail is chosen, where redaction hooks in, and the failure/fallback paths. Anchor every claim with file:line. Keep it under 40 lines."
19
+ }
20
+ ]
@@ -0,0 +1,20 @@
1
+ [
2
+ {
3
+ "id": "review-session-runtime",
4
+ "agent": "reviewer",
5
+ "cwd": "C:/Project/mixdog",
6
+ "prompt": "Review the folder src/session-runtime/ for correctness, regression, and security risks. Focus on real actionable bugs: broken imports, undefined identifiers, race conditions, wrong fallbacks, data loss paths. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
7
+ },
8
+ {
9
+ "id": "review-channels-lib",
10
+ "agent": "reviewer",
11
+ "cwd": "C:/Project/mixdog",
12
+ "prompt": "Review the folder src/runtime/channels/lib/ for correctness, regression, and security risks. Focus on real actionable bugs: message loss, double-forwarding, ownership races, watcher leaks, unsafe input handling. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
13
+ },
14
+ {
15
+ "id": "review-compact",
16
+ "agent": "reviewer",
17
+ "cwd": "C:/Project/mixdog",
18
+ "prompt": "Review the folder src/runtime/agent/orchestrator/session/compact/ for correctness, regression, and security risks. Focus on real actionable bugs: schema validation gaps, data corruption on summarize, lossy round-trips, error swallowing. Report findings ordered by severity, one line each, with file:line anchors. Skip style nits. End with a one-line verdict."
19
+ }
20
+ ]
@@ -0,0 +1,114 @@
1
+ {
2
+ "round": "1",
3
+ "runner": "codex",
4
+ "opts": {
5
+ "provider": "openai-oauth",
6
+ "model": "gpt-5.5",
7
+ "effort": "high",
8
+ "fast": false,
9
+ "env": {}
10
+ },
11
+ "tasks": 3,
12
+ "completed": 3,
13
+ "completion_rate": 100,
14
+ "sessions": [
15
+ "019f24e5-98ee-7cf0-afb0-a1a80ac81702",
16
+ "019f24e5-98f3-7f12-9638-7a899028c7e3",
17
+ "019f24e5-98f3-7f22-902c-934f0f7cbfb0"
18
+ ],
19
+ "results": [
20
+ {
21
+ "id": "review-session-runtime",
22
+ "agent": "reviewer",
23
+ "ok": true,
24
+ "ms": 300087,
25
+ "sessionId": "019f24e5-98ee-7cf0-afb0-a1a80ac81702",
26
+ "card": {
27
+ "session": "019f24e5-98ee-7cf0-afb0-a1a80ac81702",
28
+ "wall_ms": 300087,
29
+ "uncached_in": 157635,
30
+ "cached_in": 1071360,
31
+ "out_tokens": 8581,
32
+ "cache_ratio": 0.872,
33
+ "completed": 1
34
+ },
35
+ "output": "- High: `src/session-runtime/plugin-mcp.mjs:40` project `.mcp.json` stdio entries can set `cwd` to `..` or an absolute path outside the project, bypassing the stricter project-root guard in `normalizeMcpServerInput` and letting repo-local MCP config run with access scoped outside the opened repo.\n- Medium: `src/session-runtime/workflow.mjs:276` invalid persisted `effort` values throw from read paths like `summarizeWorkflowRoutes`/`agentRouteFromConfig` instead of being ignored, so one bad config entry can break onboarding status or agent listing.\n- Low: `src/session-runtime/provider-models.mjs:42` cached `{id, provider}` fallback metadata is returned before honoring `allowFetch`, so a prior non-fetch lookup prevents a later forced lookup from ever retrieving real model capabilities.\n\nVerdict: no broken imports found, but fix the project MCP cwd escape before trusting repo-local MCP configs."
36
+ },
37
+ {
38
+ "id": "review-channels-lib",
39
+ "agent": "reviewer",
40
+ "ok": true,
41
+ "ms": 172813,
42
+ "sessionId": "019f24e5-98f3-7f12-9638-7a899028c7e3",
43
+ "card": {
44
+ "session": "019f24e5-98f3-7f12-9638-7a899028c7e3",
45
+ "wall_ms": 172813,
46
+ "uncached_in": 136264,
47
+ "cached_in": 1237376,
48
+ "out_tokens": 8502,
49
+ "cache_ratio": 0.901,
50
+ "completed": 1
51
+ },
52
+ "output": "- High `src/runtime/channels/lib/webhook/deliveries.mjs:255`: delivery rows are appended asynchronously but the in-memory dedup state advances immediately, so crashes, append failures, out-of-order status writes, or compaction can lose/reorder `received/pending/done` rows and allow duplicate webhook dispatch or permanent dedup blockage.\n- High `src/runtime/channels/lib/event-queue.mjs:239`: queued events are moved to processed at `:241` after a fire-and-forget `injectFn`; if parent IPC drops/fails, the claimed event is acknowledged anyway and the message is lost.\n- Medium `src/runtime/channels/lib/output-forwarder.mjs:316`: actual backend send does not re-check `_isOwner()` at send time, so an ownership handoff during an in-flight drain can let the old owner send while the new owner tails the same transcript, causing double-forwarding.\n- Medium `src/runtime/channels/lib/output-forwarder.mjs:690`: `closeWatcher()` clears `sendRetryTimer` but leaves queued failed items in `finalLane/streamLane`, so transcript rebind/watch error during backoff can strand unsent messages until unrelated new activity kicks the drain.\n- Medium `src/runtime/channels/lib/webhook.mjs:530`: `startNgrok()` schedules `waitAndStart` timers that `stop()` at `:585` never cancels, so reload/stop during the delay can spawn a stale ngrok process after shutdown.\n- Low `src/runtime/channels/lib/inbound-routing.mjs:35`: stale dedup marker files are treated as non-duplicates but never refreshed/replaced, so cross-process duplicate inbound messages after TTL can bypass dedup repeatedly.\n\nVerdict: Not clean yet; I found real message-loss, double-forwarding, and lifecycle leak risks worth fixing before shipping."
53
+ },
54
+ {
55
+ "id": "review-compact",
56
+ "agent": "reviewer",
57
+ "ok": true,
58
+ "ms": 140945,
59
+ "sessionId": "019f24e5-98f3-7f22-902c-934f0f7cbfb0",
60
+ "card": {
61
+ "session": "019f24e5-98f3-7f22-902c-934f0f7cbfb0",
62
+ "wall_ms": 140945,
63
+ "uncached_in": 102061,
64
+ "cached_in": 416512,
65
+ "out_tokens": 7120,
66
+ "cache_ratio": 0.803,
67
+ "completed": 1
68
+ },
69
+ "output": "- High `src/runtime/agent/orchestrator/session/compact/engine.mjs:588` - `recallTailStartIndex()` relies on object identity, so when `fitSingleRecallTurnToCap()` clones/truncates the first tail user message, `indexOf()` fails and the fallback can misplace the tail, duplicating summarized user content and dropping/reordering recent messages.\n- High `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:269` - `redactMessageToolCallSecrets()` returns unchanged unless `m.toolCalls` exists, leaving Anthropic-style `content` / `assistantBlocks` `tool_use` inputs unredacted in preserved tails.\n- High `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:12` - the sensitive-key regex misses common camelCase token keys like `accessToken`, `idToken`, and `sessionToken`, so those secrets survive both prompt summaries and verbatim tail redaction.\n- Medium `src/runtime/agent/orchestrator/session/compact/budget.mjs:79` - `drainSessionCycle1()` swallows `cycle1` errors and returns a “successful” partial drain, so callers can proceed with raw pending rows while diagnostics lose the actual failure.\n- Medium `src/runtime/agent/orchestrator/session/compact/summary-schema.mjs:68` - semantic schema validation only checks top-level `##` anchors, while `truncateSummaryBySections()` can drop required `### Done/In Progress/Blocked` progress structure and still treat the summary as valid.\n\nVerdict: Needs fixes before compaction can be considered secure and loss-safe."
70
+ }
71
+ ],
72
+ "task_complete": true,
73
+ "task_errors": [],
74
+ "score_complete": true,
75
+ "score_errors": [],
76
+ "group": {
77
+ "n": 3,
78
+ "wall_ms": 204615,
79
+ "uncached_in": 131986.7,
80
+ "cached_in": 908416,
81
+ "out_tokens": 8067.7,
82
+ "cache_ratio": 0.9,
83
+ "completed": 1
84
+ },
85
+ "cards": [
86
+ {
87
+ "session": "019f24e5-98ee-7cf0-afb0-a1a80ac81702",
88
+ "wall_ms": 300087,
89
+ "uncached_in": 157635,
90
+ "cached_in": 1071360,
91
+ "out_tokens": 8581,
92
+ "cache_ratio": 0.872,
93
+ "completed": 1
94
+ },
95
+ {
96
+ "session": "019f24e5-98f3-7f12-9638-7a899028c7e3",
97
+ "wall_ms": 172813,
98
+ "uncached_in": 136264,
99
+ "cached_in": 1237376,
100
+ "out_tokens": 8502,
101
+ "cache_ratio": 0.901,
102
+ "completed": 1
103
+ },
104
+ {
105
+ "session": "019f24e5-98f3-7f22-902c-934f0f7cbfb0",
106
+ "wall_ms": 140945,
107
+ "uncached_in": 102061,
108
+ "cached_in": 416512,
109
+ "out_tokens": 7120,
110
+ "cache_ratio": 0.803,
111
+ "completed": 1
112
+ }
113
+ ]
114
+ }
@@ -0,0 +1,269 @@
1
+ {
2
+ "round": "3",
3
+ "runner": "lead",
4
+ "opts": {
5
+ "provider": null,
6
+ "model": null,
7
+ "effort": null,
8
+ "fast": false,
9
+ "env": {
10
+ "MIXDOG_DATA_DIR": "C:\\Users\\tempe\\.mixdog\\bench-data"
11
+ }
12
+ },
13
+ "tasks": 3,
14
+ "completed": 3,
15
+ "completion_rate": 100,
16
+ "sessions": [
17
+ "sess_44376_1783036165596_1783036165772_a77d5225c11eaee87b9509c9611c40c3",
18
+ "sess_53612_1783036165611_1783036165786_6799f6b975f8c1531cf1766d5802f647",
19
+ "sess_40692_1783036165624_1783036165796_a84440b9682c554ba565b3270485c54d"
20
+ ],
21
+ "results": [
22
+ {
23
+ "id": "lead-review-session-runtime",
24
+ "agent": "reviewer",
25
+ "ok": true,
26
+ "ms": 396471,
27
+ "sessionId": "sess_44376_1783036165596_1783036165772_a77d5225c11eaee87b9509c9611c40c3",
28
+ "output": "sessionId: sess_44376_1783036165596_1783036165772_a77d5225c11eaee87b9509c9611c40c3\n4개 리뷰 모두 완료. 보고 전에 핵심 발견들을 직접 교차 검증하겠습니다.리뷰 4건을 모두 회수하고 핵심 주장(특히 High 2건)을 직접 교차 검증했습니다. review-mcp의 High 1건은 오탐으로 판정해 제외했습니다.\n\n**발견 사항 (심각도순)**\n\n- **High** `src/session-runtime/provider-usage.mjs:54` — in-flight `providerSetupPromise`가 `invalidateProviderCaches()` 이후에도 `.then`에서 `providerSetupCache`를 재기록해, 로그인/키 변경 직후 무효화된 provider·auth 스냅샷이 되살아나는 레이스 (provider-models의 `providerModelsLoadSeq` 같은 시퀀스 가드 부재, `mixdog-session-runtime.mjs:1050-1062`에서 확인).\n\n- **Medium** `src/session-runtime/provider-models.mjs:211` — `collectSearchProviderModels` force 경로가 시퀀스 가드 없이 `searchProviderModelsCache`를 덮어써, 무효화 이전에 시작된 새로고침이 stale 검색 모델 목록을 복원할 수 있음 (같은 파일 227행의 가드 패턴과 비대칭).\n\n- **Medium** `src/session-runtime/config-helpers.mjs:49,66` — preset에 `provider`가 없으면 `resolveDefaultProvider(config)` 대신 하드코딩 `DEFAULT_PROVIDER`('anthropic-oauth')로 떨어져, `config.defaultProvider` 설정을 무시하고 잘못된 provider로 라우팅 (79행의 비-preset 경로와 모순).\n\n- **Low** `src/session-runtime/effort.mjs:87` — reasoning 메타데이터가 전혀 없는 모델이 provider 전체 effort 옵션으로 폴백해, 비-reasoning 모델(quick/static 행)에 effort 선택·저장이 노출됨.\n\n**기각한 보고**: `native-search.mjs:207`의 \"openai nativeTools 무시\" High는 오탐 — `openai`는 registry에서 `OpenAIDirectProvider`(openai-ws.mjs)로 라우팅되고, 이는 `buildRequestBody`(openai-oauth.mjs:546-550)를 통해 `nativeTools`를 전달하며, compat 프리셋 provider들은 애초에 `SEARCH_CAPABLE_PROVIDERS`에 없습니다. tool-catalog/workflow/warmup-schedulers/mcp 계열 파일들은 깨진 import·미정의 식별자 없이 깨끗했습니다.\n\n**평결**: 깨진 import나 데이터 손실 경로는 없으며, 실질 리스크는 캐시 무효화 레이스 1건(High)과 폴백 불일치 2건 수준입니다.",
29
+ "card": {
30
+ "session": "sess_44376_1783036165596_1783036165772_a77d5225c11eaee87b9509c9611c40c3",
31
+ "provider": "anthropic-oauth",
32
+ "model": "claude-fable-5",
33
+ "wall_ms": 385974,
34
+ "turns": 72,
35
+ "tool_calls": 99,
36
+ "tools_per_turn": 1.4,
37
+ "total_tool_ms": 5723,
38
+ "llm_stream_ms": 625711,
39
+ "cache_ratio": 0.797586432611301,
40
+ "cached_tokens": 1938608,
41
+ "prompt_tokens": 2430593,
42
+ "uncached_tokens": 116796,
43
+ "output_tokens": 12031,
44
+ "cache_weighted_input_10": 310656.80000000005,
45
+ "cache_weighted_input_25": 601448,
46
+ "prompt_growth": 78094,
47
+ "antipatterns": 2,
48
+ "issues": 23,
49
+ "issue_types": [
50
+ "readonly_stall",
51
+ "cache",
52
+ "cache_break",
53
+ "tool_error",
54
+ "broad_tool_result",
55
+ "service_tier",
56
+ "missed_parallelism",
57
+ "tool_churn_cluster"
58
+ ],
59
+ "read_fragmentation_paths": [],
60
+ "grep_sweep_count": 0
61
+ }
62
+ },
63
+ {
64
+ "id": "lead-review-channels-lib",
65
+ "agent": "reviewer",
66
+ "ok": true,
67
+ "ms": 287195,
68
+ "sessionId": "sess_53612_1783036165611_1783036165786_6799f6b975f8c1531cf1766d5802f647",
69
+ "output": "sessionId: sess_53612_1783036165611_1783036165786_6799f6b975f8c1531cf1766d5802f647\n핵심 High 항목들을 직접 교차 검증하겠습니다.4개 리뷰 스코프 결과를 받아 High 항목을 코드로 직접 교차 검증했습니다(event-queue 배칭, output-forwarder drain, webhook fail-open, PowerShell 인젝션, cron 덮어쓰기 모두 확인됨).\n\n**High**\n- `event-queue.mjs:198` — 저순위 배칭이 `item.name`만으로 그룹핑 후 `claimedPairs[0].item`(:219)으로 발송해, 같은 이름의 다른 채널/지시 이벤트가 첫 채널로 병합·오배송되고 나머지는 유실됨.\n- `output-forwarder.mjs:575` — `forwardFinalText()`가 finally에서 `sending`만 해제하고 drain을 재기동하지 않아, 전송 중 큐잉된 항목의 `_kickDrain()`이 :436에서 no-op 되어 다음 활동 전까지 좌초됨.\n- `webhook.mjs:338` — `secret`/`parser` 없는 config 등록 엔드포인트는 경고만 남기고 통과(fail-open)해 무서명 POST가 특권 디스패치로 주입 가능.\n- `webhook/deliveries.mjs:255` — 전송 dedup 상태가 durable write 전에 성공 처리되어, flush 전 크래시 시 재시작 후 재배달/이중 디스패치 가능.\n- `runtime-paths.mjs:247` — UI-heartbeat-stale 판정 시 `prev=null`로 처리돼 좀비 워커가 `ui_heartbeat_at` 없이 오너 상태를 즉시 재게시, 테이크오버를 차단할 수 있음.\n- `runtime-paths.mjs:73` — 오너 생존 판정이 PID만 신뢰해 PID 재사용 시 stale `active-instance.json`이 무기한 고정되어 인수 불가.\n- `voice-runtime-fetcher.mjs:432` — PowerShell `-Command`에 JSON 이중따옴표 경로를 삽입해 경로 내 `$()`/백틱이 설치 중 명령 실행으로 이어지는 인젝션.\n- `voice-runtime-fetcher.mjs:174` — 락 해제가 `lockPath`를 무조건 삭제해, age 기반 재클레임 후 구 설치자가 새 오너의 락을 지워 동시 설치/손상 허용.\n- `scheduler.mjs:368` — 중복 스케줄 이름이 `cronJobs` 엔트리를 덮어써 이전 `ScheduledTask`가 누수, `destroyCronJobs()` 후에도 이중 발화.\n\n**Medium**\n- `event-queue.mjs:77` — 시작 시 `in-progress/` 전체를 나이/오너 확인 없이 재큐잉해, 핸드오프 중 구 오너가 처리 중인 파일이 중복 주입될 수 있음.\n- `backend-dispatch.mjs:17` — `dispatchReply()`가 부분 전송 실패 시 `resumeToken`을 버려, 재시도 때 이미 전송된 청크를 재발송(이중 게시).\n- `webhook.mjs:139` — 요청 바디 스트림에 `error`/`aborted` 핸들러가 없어 클라이언트 리셋 시 요청이 미해결로 남거나 스트림 에러가 unhandled로 표면화.\n- `session-control.mjs:15` — 동시 `controlClaudeSession()` 호출이 하나의 컨트롤 파일을 공유해 나중 명령이 미판독 명령을 덮어씀(첫 호출 타임아웃/유실).\n- `status-snapshot.mjs:218` — `stopSnapshotWriter()`가 전역 스냅샷을 무조건 unlink해 핸드오프 중 구 오너가 새 오너의 스냅샷을 삭제.\n- `session-discovery.mjs:26` — parent PID 캐시가 만료 없이 PID만으로 키잉되어 PID 재사용 시 stale 세션/트랜스크립트에 바인딩.\n- `webhook/signature.mjs:32` — Stripe 검증이 첫 `v1=` 서명만 확인해 시크릿 로테이션 중 유효 전송이 거부됨.\n- `whisper-server.m",
70
+ "card": {
71
+ "session": "sess_53612_1783036165611_1783036165786_6799f6b975f8c1531cf1766d5802f647",
72
+ "provider": "anthropic-oauth",
73
+ "model": "claude-fable-5",
74
+ "wall_ms": 276579,
75
+ "turns": 49,
76
+ "tool_calls": 67,
77
+ "tools_per_turn": 1.4,
78
+ "total_tool_ms": 4244,
79
+ "llm_stream_ms": 672149,
80
+ "cache_ratio": 0.6616259058956849,
81
+ "cached_tokens": 1003052,
82
+ "prompt_tokens": 1516041,
83
+ "uncached_tokens": 139818,
84
+ "output_tokens": 14174,
85
+ "cache_weighted_input_10": 240123.2,
86
+ "cache_weighted_input_25": 390581,
87
+ "prompt_growth": 75338,
88
+ "antipatterns": 1,
89
+ "issues": 16,
90
+ "issue_types": [
91
+ "cache",
92
+ "cache_break",
93
+ "broad_tool_result",
94
+ "readonly_stall",
95
+ "service_tier",
96
+ "missed_parallelism",
97
+ "tool_churn_cluster"
98
+ ],
99
+ "read_fragmentation_paths": [],
100
+ "grep_sweep_count": 0
101
+ }
102
+ },
103
+ {
104
+ "id": "lead-review-compact",
105
+ "agent": "reviewer",
106
+ "ok": true,
107
+ "ms": 426500,
108
+ "sessionId": "sess_40692_1783036165624_1783036165796_a84440b9682c554ba565b3270485c54d",
109
+ "output": "sessionId: sess_40692_1783036165624_1783036165796_a84440b9682c554ba565b3270485c54d\n세 결과를 받았으니 핵심 앵커들을 직접 확인해 검증하겠습니다.주요 주장들을 앵커에서 직접 검증하겠습니다.리뷰 완료 — 에이전트 결과를 앵커에서 직접 검증했고, 아래는 확인된 이슈만 심각도순으로 정리한 것입니다.\n\n- **High** `text-utils.mjs:295` — `redactMessageToolCallSecrets`가 `m.toolCalls`만 스크럽하고 content 배열의 `tool_use` 블록 `input`은 건너뜀(해당 형태 존재는 `context-utils.mjs:551` 주석이 확인) → 보존 tail에 시크릿이 미리댁션 상태로 잔존.\n\n- **High** `engine.mjs:93` — `splitTurnStartIndexForBudget`가 tool-role 인덱스를 컷 지점으로 반환 가능(비교: `findValidCutIndices`는 tool 제외) → 고아 tool result가 head에서도 tail에서도 빠져 무음 손실.\n\n- **High** `text-utils.mjs:29` — camel 정규식의 `s?$`가 주석(\"`maxOutputTokens`는 매치 안 됨\")과 모순, `maxOutputTokens`/`budgetTokens`/`completionTokens`가 `[redacted]`로 치환돼 보존 tool-call 인자가 손상됨.\n\n- **Medium** `summary.mjs:427` (동일 패턴 `:577`) — prior 요약을 remainingTokens 전체로 먼저 이진탐색 최대화한 뒤 recall을 끼워 넣어, 토큰 압박 시 신규 recall 블록이 전부 탈락하고 stale prior만 남음.\n\n- **Medium** `budget.mjs:203` — `pruneToolOutputText`가 maxChars 무시하고 고정 1000/600 슬라이스 사용; `maxToolOutputChars < ~1700`이면 프루닝 결과가 원본보다 커져 예산 회복 실패(head/tail 중복 포함).\n\n- **Medium** `engine.mjs:588` — `recallTailStartIndex`가 객체 동일성(`indexOf`) 의존, fitting이 첫 tail 메시지를 클론하면 `live.length - tail.length` 폴백이 잘못된 경계를 선택해 head/tail 분할이 어긋남.\n\n- **Low** `summary-schema.mjs:71` — 검증이 최상위 `##` 앵커만 확인해 `### Done/In Progress/Blocked` 누락이 통과하고, `:309`의 섹션 중간절단이 서브헤딩을 잘라도 여전히 유효 판정됨.\n\n- **Low** `summary.mjs:400` — `stripNestedSummaryHeaderLines`가 `:318`의 `semantic=true provider=... model=...` 라인을 안 지워 반복 컴팩션 시 합성 메타데이터가 prior 본문에 누적.\n\n- **Low** `text-utils.mjs:118` — `truncateMiddle`이 UTF-16 코드유닛 단위로 잘라 서로게이트 쌍 분리 가능(같은 패턴 `budget.mjs:203-204`).\n\n핵심 컴팩션 경로 자체는 견고하나, 시크릿 리댁션 우회와 턴 분할 시 tool result 무음 손실 두 건은 실사용 전 수정이 필요합니다.",
110
+ "card": {
111
+ "session": "sess_40692_1783036165624_1783036165796_a84440b9682c554ba565b3270485c54d",
112
+ "provider": "anthropic-oauth",
113
+ "model": "claude-fable-5",
114
+ "wall_ms": 416022,
115
+ "turns": 33,
116
+ "tool_calls": 45,
117
+ "tools_per_turn": 1.4,
118
+ "total_tool_ms": 1888,
119
+ "llm_stream_ms": 569465,
120
+ "cache_ratio": 0.767026954989235,
121
+ "cached_tokens": 667631,
122
+ "prompt_tokens": 870414,
123
+ "uncached_tokens": 53129,
124
+ "output_tokens": 10398,
125
+ "cache_weighted_input_10": 119892.1,
126
+ "cache_weighted_input_25": 220036.75,
127
+ "prompt_growth": 49784,
128
+ "antipatterns": 2,
129
+ "issues": 12,
130
+ "issue_types": [
131
+ "cache",
132
+ "cache_break",
133
+ "broad_tool_result",
134
+ "readonly_stall",
135
+ "service_tier",
136
+ "duplicate_tool",
137
+ "missed_parallelism",
138
+ "tool_churn_cluster"
139
+ ],
140
+ "read_fragmentation_paths": [],
141
+ "grep_sweep_count": 0
142
+ }
143
+ }
144
+ ],
145
+ "task_complete": true,
146
+ "task_errors": [],
147
+ "score_complete": true,
148
+ "score_errors": [],
149
+ "group": {
150
+ "n": 3,
151
+ "wall_ms": 359525,
152
+ "turns": 51.3,
153
+ "tool_calls": 70.3,
154
+ "tools_per_turn": 1.4,
155
+ "total_tool_ms": 3951.7,
156
+ "llm_stream_ms": 622441.7,
157
+ "cache_ratio": 0.7,
158
+ "cached_tokens": 1203097,
159
+ "prompt_tokens": 1605682.7,
160
+ "uncached_tokens": 103247.7,
161
+ "output_tokens": 12201,
162
+ "cache_weighted_input_10": 223557.4,
163
+ "cache_weighted_input_25": 404021.9,
164
+ "prompt_growth": 67738.7,
165
+ "antipatterns": 1.7,
166
+ "issues": 17,
167
+ "grep_sweep_count": 0
168
+ },
169
+ "cards": [
170
+ {
171
+ "session": "sess_44376_1783036165596_1783036165772_a77d5225c11eaee87b9509c9611c40c3",
172
+ "provider": "anthropic-oauth",
173
+ "model": "claude-fable-5",
174
+ "wall_ms": 385974,
175
+ "turns": 72,
176
+ "tool_calls": 99,
177
+ "tools_per_turn": 1.4,
178
+ "total_tool_ms": 5723,
179
+ "llm_stream_ms": 625711,
180
+ "cache_ratio": 0.797586432611301,
181
+ "cached_tokens": 1938608,
182
+ "prompt_tokens": 2430593,
183
+ "uncached_tokens": 116796,
184
+ "output_tokens": 12031,
185
+ "cache_weighted_input_10": 310656.80000000005,
186
+ "cache_weighted_input_25": 601448,
187
+ "prompt_growth": 78094,
188
+ "antipatterns": 2,
189
+ "issues": 23,
190
+ "issue_types": [
191
+ "readonly_stall",
192
+ "cache",
193
+ "cache_break",
194
+ "tool_error",
195
+ "broad_tool_result",
196
+ "service_tier",
197
+ "missed_parallelism",
198
+ "tool_churn_cluster"
199
+ ],
200
+ "read_fragmentation_paths": [],
201
+ "grep_sweep_count": 0
202
+ },
203
+ {
204
+ "session": "sess_53612_1783036165611_1783036165786_6799f6b975f8c1531cf1766d5802f647",
205
+ "provider": "anthropic-oauth",
206
+ "model": "claude-fable-5",
207
+ "wall_ms": 276579,
208
+ "turns": 49,
209
+ "tool_calls": 67,
210
+ "tools_per_turn": 1.4,
211
+ "total_tool_ms": 4244,
212
+ "llm_stream_ms": 672149,
213
+ "cache_ratio": 0.6616259058956849,
214
+ "cached_tokens": 1003052,
215
+ "prompt_tokens": 1516041,
216
+ "uncached_tokens": 139818,
217
+ "output_tokens": 14174,
218
+ "cache_weighted_input_10": 240123.2,
219
+ "cache_weighted_input_25": 390581,
220
+ "prompt_growth": 75338,
221
+ "antipatterns": 1,
222
+ "issues": 16,
223
+ "issue_types": [
224
+ "cache",
225
+ "cache_break",
226
+ "broad_tool_result",
227
+ "readonly_stall",
228
+ "service_tier",
229
+ "missed_parallelism",
230
+ "tool_churn_cluster"
231
+ ],
232
+ "read_fragmentation_paths": [],
233
+ "grep_sweep_count": 0
234
+ },
235
+ {
236
+ "session": "sess_40692_1783036165624_1783036165796_a84440b9682c554ba565b3270485c54d",
237
+ "provider": "anthropic-oauth",
238
+ "model": "claude-fable-5",
239
+ "wall_ms": 416022,
240
+ "turns": 33,
241
+ "tool_calls": 45,
242
+ "tools_per_turn": 1.4,
243
+ "total_tool_ms": 1888,
244
+ "llm_stream_ms": 569465,
245
+ "cache_ratio": 0.767026954989235,
246
+ "cached_tokens": 667631,
247
+ "prompt_tokens": 870414,
248
+ "uncached_tokens": 53129,
249
+ "output_tokens": 10398,
250
+ "cache_weighted_input_10": 119892.1,
251
+ "cache_weighted_input_25": 220036.75,
252
+ "prompt_growth": 49784,
253
+ "antipatterns": 2,
254
+ "issues": 12,
255
+ "issue_types": [
256
+ "cache",
257
+ "cache_break",
258
+ "broad_tool_result",
259
+ "readonly_stall",
260
+ "service_tier",
261
+ "duplicate_tool",
262
+ "missed_parallelism",
263
+ "tool_churn_cluster"
264
+ ],
265
+ "read_fragmentation_paths": [],
266
+ "grep_sweep_count": 0
267
+ }
268
+ ]
269
+ }