mixdog 0.9.3 → 0.9.5

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 (382) hide show
  1. package/README.md +112 -38
  2. package/package.json +10 -3
  3. package/scripts/bench/lead-review-tasks-r3.json +20 -0
  4. package/scripts/bench/lead-review-tasks.json +20 -0
  5. package/scripts/bench/r4-mixed-tasks.json +20 -0
  6. package/scripts/bench/r5-orchestrated-task.json +7 -0
  7. package/scripts/bench/review-tasks.json +20 -0
  8. package/scripts/bench/round-codex.json +114 -0
  9. package/scripts/bench/round-mixdog-lead-r3.json +269 -0
  10. package/scripts/bench/round-mixdog-lead.json +269 -0
  11. package/scripts/bench/round-mixdog.json +126 -0
  12. package/scripts/bench/round-r10-bigsample.json +679 -0
  13. package/scripts/bench/round-r11-codexalign.json +257 -0
  14. package/scripts/bench/round-r13-clientmeta.json +464 -0
  15. package/scripts/bench/round-r14-betafeatures.json +466 -0
  16. package/scripts/bench/round-r15-fulldefault.json +462 -0
  17. package/scripts/bench/round-r16-sessionid.json +466 -0
  18. package/scripts/bench/round-r17-wirebytes.json +456 -0
  19. package/scripts/bench/round-r18-prewarm.json +468 -0
  20. package/scripts/bench/round-r19-clean.json +472 -0
  21. package/scripts/bench/round-r20-prewarm-clean.json +475 -0
  22. package/scripts/bench/round-r21-delta-retry.json +473 -0
  23. package/scripts/bench/round-r22-full-probe.json +693 -0
  24. package/scripts/bench/round-r23-itemprobe.json +701 -0
  25. package/scripts/bench/round-r24-shapefix.json +677 -0
  26. package/scripts/bench/round-r25-serial.json +464 -0
  27. package/scripts/bench/round-r26-parallel3.json +671 -0
  28. package/scripts/bench/round-r27-parallel10.json +894 -0
  29. package/scripts/bench/round-r28-parallel10-stagger.json +882 -0
  30. package/scripts/bench/round-r29-parallel10-stagger166.json +886 -0
  31. package/scripts/bench/round-r30-instid.json +253 -0
  32. package/scripts/bench/round-r31-upgradeprobe.json +256 -0
  33. package/scripts/bench/round-r32-vs-codex-lead.json +254 -0
  34. package/scripts/bench/round-r33-vs-codex-codex.json +115 -0
  35. package/scripts/bench/round-r34-orchestrated.json +120 -0
  36. package/scripts/bench/round-r35-orchestrated-codex.json +61 -0
  37. package/scripts/bench/round-r36-orchestrated-capped.json +128 -0
  38. package/scripts/bench/round-r4-codex.json +114 -0
  39. package/scripts/bench/round-r4-mixed.json +225 -0
  40. package/scripts/bench/round-r5-gpt-lead.json +259 -0
  41. package/scripts/bench/round-r6-codex.json +114 -0
  42. package/scripts/bench/round-r6-solo.json +257 -0
  43. package/scripts/bench/round-r7-full.json +254 -0
  44. package/scripts/bench/round-r8-fulldefault.json +255 -0
  45. package/scripts/bench-run.mjs +251 -32
  46. package/scripts/freevar-smoke.mjs +95 -0
  47. package/scripts/internal-comms-bench.mjs +3 -4
  48. package/scripts/internal-comms-smoke.mjs +10 -9
  49. package/scripts/model-catalog-audit.mjs +209 -0
  50. package/scripts/model-list-sanitize-test.mjs +37 -0
  51. package/scripts/mouse-probe.mjs +45 -0
  52. package/scripts/output-style-bench.mjs +13 -6
  53. package/scripts/output-style-smoke.mjs +4 -4
  54. package/scripts/provider-toolcall-test.mjs +7 -3
  55. package/scripts/recall-bench.mjs +76 -13
  56. package/scripts/recall-quality-cases.json +12 -0
  57. package/scripts/recall-usecase-cases.json +18 -0
  58. package/scripts/session-bench.mjs +152 -6
  59. package/scripts/tool-smoke.mjs +25 -65
  60. package/scripts/tui-render-smoke.mjs +90 -0
  61. package/scripts/webhook-smoke.mjs +208 -0
  62. package/src/agents/debugger/AGENT.md +4 -1
  63. package/src/agents/heavy-worker/AGENT.md +9 -8
  64. package/src/agents/maintainer/AGENT.md +4 -0
  65. package/src/agents/reviewer/AGENT.md +2 -1
  66. package/src/agents/scheduler-task/AGENT.md +2 -3
  67. package/src/agents/webhook-handler/AGENT.md +2 -3
  68. package/src/agents/worker/AGENT.md +10 -7
  69. package/src/app.mjs +12 -1
  70. package/src/headless-role.mjs +7 -1
  71. package/src/lib/rules-builder.cjs +4 -0
  72. package/src/mixdog-session-runtime.mjs +647 -2056
  73. package/src/output-styles/default.md +30 -9
  74. package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
  75. package/src/output-styles/minimal.md +8 -6
  76. package/src/output-styles/simple.md +21 -7
  77. package/src/rules/agent/00-common.md +6 -3
  78. package/src/rules/agent/30-explorer.md +16 -5
  79. package/src/rules/lead/01-general.md +5 -5
  80. package/src/rules/lead/lead-brief.md +15 -0
  81. package/src/rules/lead/lead-tool.md +6 -15
  82. package/src/rules/shared/01-tool.md +17 -21
  83. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +8 -3
  84. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
  85. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
  86. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
  87. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
  88. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
  89. package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
  90. package/src/runtime/agent/orchestrator/config.mjs +69 -2
  91. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +62 -20
  92. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
  93. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
  94. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +81 -1281
  95. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
  96. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +32 -3
  97. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
  98. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
  99. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
  100. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
  101. package/src/runtime/agent/orchestrator/providers/gemini.mjs +43 -1013
  102. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +17 -3
  103. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +105 -11
  104. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +356 -0
  105. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
  106. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
  107. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
  108. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
  109. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +40 -1143
  110. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +740 -0
  111. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
  112. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +349 -2131
  113. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +143 -1002
  114. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +229 -0
  115. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
  116. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +465 -0
  117. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
  118. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
  119. package/src/runtime/agent/orchestrator/providers/provider-catalog-cache.mjs +80 -0
  120. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
  121. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
  122. package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
  123. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
  124. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
  125. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
  126. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
  127. package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
  128. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +14 -2
  129. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
  130. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +1 -3
  131. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +275 -0
  132. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
  133. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
  134. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
  135. package/src/runtime/agent/orchestrator/session/loop.mjs +278 -402
  136. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
  137. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +7 -4
  138. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +12 -0
  139. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
  140. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
  141. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
  142. package/src/runtime/agent/orchestrator/session/manager.mjs +166 -1087
  143. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
  144. package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
  145. package/src/runtime/agent/orchestrator/stall-policy.mjs +20 -1
  146. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
  147. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
  148. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +35 -44
  149. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
  150. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
  151. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
  152. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
  153. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -92
  154. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
  155. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
  156. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +28 -265
  157. package/src/runtime/agent/orchestrator/tools/builtin.mjs +0 -6
  158. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +57 -3
  159. package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
  160. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +10 -122
  161. package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
  162. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  163. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
  164. package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
  165. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
  166. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
  167. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
  168. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
  169. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
  170. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
  171. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
  172. package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
  173. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +0 -21
  174. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +9 -72
  175. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
  176. package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
  177. package/src/runtime/channels/backends/discord-access.mjs +32 -0
  178. package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
  179. package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
  180. package/src/runtime/channels/backends/discord.mjs +27 -318
  181. package/src/runtime/channels/backends/telegram.mjs +8 -12
  182. package/src/runtime/channels/index.mjs +247 -701
  183. package/src/runtime/channels/lib/backend-dispatch.mjs +46 -0
  184. package/src/runtime/channels/lib/config.mjs +37 -149
  185. package/src/runtime/channels/lib/event-pipeline.mjs +22 -5
  186. package/src/runtime/channels/lib/event-queue.mjs +78 -13
  187. package/src/runtime/channels/lib/inbound-routing.mjs +74 -0
  188. package/src/runtime/channels/lib/interaction-workflows.mjs +5 -113
  189. package/src/runtime/channels/lib/output-forwarder.mjs +1 -1
  190. package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
  191. package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
  192. package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
  193. package/src/runtime/channels/lib/scheduler.mjs +27 -113
  194. package/src/runtime/channels/lib/session-discovery.mjs +56 -4
  195. package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
  196. package/src/runtime/channels/lib/tool-format.mjs +1 -1
  197. package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
  198. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
  199. package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
  200. package/src/runtime/channels/lib/webhook/deliveries.mjs +313 -0
  201. package/src/runtime/channels/lib/webhook/log.mjs +42 -0
  202. package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
  203. package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
  204. package/src/runtime/channels/lib/webhook.mjs +43 -616
  205. package/src/runtime/channels/tool-defs.mjs +11 -130
  206. package/src/runtime/memory/index.mjs +210 -1948
  207. package/src/runtime/memory/lib/core-memory-store.mjs +5 -1
  208. package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
  209. package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
  210. package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
  211. package/src/runtime/memory/lib/ko-morph.mjs +195 -0
  212. package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
  213. package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
  214. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
  215. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
  216. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
  217. package/src/runtime/memory/lib/memory-cycle2.mjs +24 -842
  218. package/src/runtime/memory/lib/memory-embed.mjs +149 -0
  219. package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
  220. package/src/runtime/memory/lib/memory-recall-store.mjs +69 -12
  221. package/src/runtime/memory/lib/memory-text-utils.mjs +46 -0
  222. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
  223. package/src/runtime/memory/lib/query-handlers.mjs +802 -0
  224. package/src/runtime/memory/lib/recall-format.mjs +55 -0
  225. package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
  226. package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
  227. package/src/runtime/memory/tool-defs.mjs +5 -13
  228. package/src/runtime/search/lib/http-fetch.mjs +274 -0
  229. package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
  230. package/src/runtime/search/lib/web-tools.mjs +24 -602
  231. package/src/runtime/shared/atomic-file.mjs +26 -1
  232. package/src/runtime/shared/config.mjs +14 -4
  233. package/src/runtime/shared/launcher-control.mjs +2 -2
  234. package/src/runtime/shared/markdown-frontmatter.mjs +19 -0
  235. package/src/runtime/shared/schedules-store.mjs +13 -3
  236. package/src/runtime/shared/tool-execution-contract.mjs +2 -2
  237. package/src/runtime/shared/tool-primitives.mjs +308 -0
  238. package/src/runtime/shared/tool-result-summary.mjs +515 -0
  239. package/src/runtime/shared/tool-surface.mjs +80 -898
  240. package/src/runtime/shared/transcript-writer.mjs +23 -0
  241. package/src/runtime/shared/update-checker.mjs +7 -4
  242. package/src/session-runtime/config-helpers.mjs +119 -2
  243. package/src/session-runtime/config-lifecycle.mjs +232 -0
  244. package/src/session-runtime/cwd-plugins.mjs +226 -0
  245. package/src/session-runtime/mcp-glue.mjs +177 -0
  246. package/src/session-runtime/model-recency.mjs +111 -0
  247. package/src/session-runtime/native-search.mjs +247 -0
  248. package/src/session-runtime/output-styles.mjs +11 -9
  249. package/src/session-runtime/prewarm.mjs +142 -0
  250. package/src/session-runtime/provider-models.mjs +278 -0
  251. package/src/session-runtime/provider-usage.mjs +120 -0
  252. package/src/session-runtime/quick-model-rows.mjs +205 -0
  253. package/src/session-runtime/quick-search-models.mjs +47 -0
  254. package/src/session-runtime/session-hooks.mjs +93 -0
  255. package/src/session-runtime/settings-api.mjs +352 -0
  256. package/src/session-runtime/tool-catalog.mjs +29 -29
  257. package/src/session-runtime/tool-defs.mjs +84 -0
  258. package/src/session-runtime/warmup-schedulers.mjs +201 -0
  259. package/src/session-runtime/workflow.mjs +1 -1
  260. package/src/standalone/agent-tool/helpers.mjs +237 -0
  261. package/src/standalone/agent-tool/notify.mjs +107 -0
  262. package/src/standalone/agent-tool/provider-init.mjs +143 -0
  263. package/src/standalone/agent-tool/render.mjs +152 -0
  264. package/src/standalone/agent-tool/tool-def.mjs +55 -0
  265. package/src/standalone/agent-tool.mjs +138 -669
  266. package/src/standalone/channel-admin.mjs +102 -90
  267. package/src/standalone/channel-worker.mjs +4 -7
  268. package/src/standalone/explore-tool.mjs +64 -14
  269. package/src/standalone/hook-bus/config.mjs +207 -0
  270. package/src/standalone/hook-bus/constants.mjs +90 -0
  271. package/src/standalone/hook-bus/handlers.mjs +481 -0
  272. package/src/standalone/hook-bus/payload.mjs +31 -0
  273. package/src/standalone/hook-bus/rules.mjs +77 -0
  274. package/src/standalone/hook-bus.mjs +77 -870
  275. package/src/standalone/memory-runtime-proxy.mjs +7 -0
  276. package/src/standalone/opencode-go-login.mjs +5 -1
  277. package/src/standalone/provider-admin.mjs +1 -16
  278. package/src/standalone/usage-dashboard.mjs +3 -1
  279. package/src/tui/App.jsx +1059 -8110
  280. package/src/tui/app/app-format.mjs +213 -0
  281. package/src/tui/app/channel-pickers.mjs +508 -0
  282. package/src/tui/app/clipboard.mjs +67 -0
  283. package/src/tui/app/core-memory-picker.mjs +210 -0
  284. package/src/tui/app/extension-pickers.mjs +506 -0
  285. package/src/tui/app/input-parsers.mjs +193 -0
  286. package/src/tui/app/maintenance-pickers.mjs +356 -0
  287. package/src/tui/app/model-options.mjs +334 -0
  288. package/src/tui/app/model-picker.mjs +365 -0
  289. package/src/tui/app/onboarding-steps.mjs +400 -0
  290. package/src/tui/app/project-picker.mjs +247 -0
  291. package/src/tui/app/provider-setup-picker.mjs +580 -0
  292. package/src/tui/app/resume-picker.mjs +55 -0
  293. package/src/tui/app/route-pickers.mjs +419 -0
  294. package/src/tui/app/settings-picker.mjs +489 -0
  295. package/src/tui/app/slash-commands.mjs +101 -0
  296. package/src/tui/app/slash-dispatch.mjs +427 -0
  297. package/src/tui/app/text-layout.mjs +46 -0
  298. package/src/tui/app/theme-effort-pickers.mjs +154 -0
  299. package/src/tui/app/transcript-window.mjs +677 -0
  300. package/src/tui/app/use-mouse-input.mjs +460 -0
  301. package/src/tui/app/use-prompt-handlers.mjs +310 -0
  302. package/src/tui/app/use-transcript-scroll.mjs +512 -0
  303. package/src/tui/app/use-transcript-window.mjs +607 -0
  304. package/src/tui/components/ConfirmBar.jsx +10 -7
  305. package/src/tui/components/Picker.jsx +64 -15
  306. package/src/tui/components/PromptInput.jsx +33 -102
  307. package/src/tui/components/SlashCommandPalette.jsx +8 -1
  308. package/src/tui/components/StatusLine.jsx +69 -15
  309. package/src/tui/components/TextEntryPanel.jsx +11 -0
  310. package/src/tui/components/ToolExecution.jsx +52 -594
  311. package/src/tui/components/TranscriptItem.jsx +105 -0
  312. package/src/tui/components/UsagePanel.jsx +18 -4
  313. package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
  314. package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
  315. package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
  316. package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
  317. package/src/tui/components/tool-execution/text-format.mjs +161 -0
  318. package/src/tui/display-width.mjs +20 -3
  319. package/src/tui/dist/index.mjs +13553 -12384
  320. package/src/tui/engine/agent-job-feed.mjs +133 -0
  321. package/src/tui/engine/notification-plan.mjs +76 -0
  322. package/src/tui/engine/render-timing.mjs +17 -0
  323. package/src/tui/engine/tool-approval.mjs +94 -0
  324. package/src/tui/engine/tool-card-results.mjs +234 -0
  325. package/src/tui/engine/tool-result-status.mjs +135 -0
  326. package/src/tui/engine.mjs +170 -574
  327. package/src/tui/figures.mjs +5 -0
  328. package/src/tui/index.jsx +65 -1
  329. package/src/tui/input-editing.mjs +2 -2
  330. package/src/tui/markdown/format-token.mjs +4 -1
  331. package/src/tui/statusline-ansi-bridge.mjs +11 -3
  332. package/src/tui/theme.mjs +6 -0
  333. package/src/ui/statusline-agents.mjs +213 -0
  334. package/src/ui/statusline-format.mjs +146 -0
  335. package/src/ui/statusline-segments.mjs +148 -0
  336. package/src/ui/statusline.mjs +77 -501
  337. package/src/ui/tool-card.mjs +0 -1
  338. package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
  339. package/src/workflows/default/WORKFLOW.md +16 -18
  340. package/src/workflows/sequential/WORKFLOW.md +16 -18
  341. package/vendor/ink/build/display-width.js +19 -3
  342. package/vendor/ink/build/ink.js +112 -7
  343. package/vendor/ink/build/log-update.js +17 -3
  344. package/vendor/ink/build/wrap-text.js +125 -0
  345. package/scripts/_test-folder-dialog.mjs +0 -30
  346. package/scripts/fix-brief-fn.mjs +0 -35
  347. package/scripts/fix-format-tool-surface.mjs +0 -24
  348. package/scripts/fix-tool-exec-visible.mjs +0 -42
  349. package/scripts/patch-agent-brief.mjs +0 -48
  350. package/scripts/patch-app.mjs +0 -21
  351. package/scripts/patch-app2.mjs +0 -18
  352. package/scripts/patch-dist-brief.mjs +0 -96
  353. package/scripts/patch-tool-exec.mjs +0 -70
  354. package/src/examples/schedules/SCHEDULE.example.md +0 -32
  355. package/src/examples/webhooks/WEBHOOK.example.md +0 -40
  356. package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
  357. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
  358. package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
  359. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.test.mjs +0 -162
  360. package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
  361. package/src/runtime/channels/lib/holidays.mjs +0 -138
  362. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
  363. package/src/runtime/shared/task-notification-envelope.test.mjs +0 -107
  364. package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
  365. package/src/standalone/agent-task-status.test.mjs +0 -76
  366. package/src/tui/components/tool-output-format.test.mjs +0 -399
  367. package/src/tui/display-width.test.mjs +0 -35
  368. package/src/tui/engine-runtime-notification.test.mjs +0 -115
  369. package/src/tui/engine-tool-result-text.test.mjs +0 -75
  370. package/src/tui/input-editing.selection.test.mjs +0 -75
  371. package/src/tui/markdown/format-token.test.mjs +0 -354
  372. package/src/tui/markdown/render-ansi.test.mjs +0 -108
  373. package/src/tui/markdown/stream-fence.test.mjs +0 -26
  374. package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
  375. package/src/tui/paste-fix.test.mjs +0 -119
  376. package/src/tui/prompt-history-store.test.mjs +0 -52
  377. package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
  378. package/src/tui/transcript-tool-failures.test.mjs +0 -111
  379. package/src/ui/markdown.test.mjs +0 -70
  380. package/src/ui/statusline-context-label.test.mjs +0 -15
  381. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
  382. package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
@@ -0,0 +1,462 @@
1
+ {
2
+ "round": "15",
3
+ "runner": "lead",
4
+ "opts": {
5
+ "provider": "openai-oauth",
6
+ "model": "gpt-5.5",
7
+ "effort": null,
8
+ "fast": false,
9
+ "env": {
10
+ "MIXDOG_DATA_DIR": "C:\\Users\\tempe\\.mixdog\\bench-data"
11
+ }
12
+ },
13
+ "tasks": 6,
14
+ "completed": 6,
15
+ "completion_rate": 100,
16
+ "sessions": [
17
+ "sess_20052_1783058612106_1783058612356_363946685eccb22a98de415cf55e2b6b",
18
+ "sess_6636_1783058612119_1783058612368_878b7998c6a201833b0d90d7db428756",
19
+ "sess_32108_1783058612133_1783058612379_16813f439160d71cffa545f046f32444",
20
+ "sess_60200_1783058729488_1783058729715_0addf90688066bfe101c1e912ae350eb",
21
+ "sess_54744_1783058755944_1783058756177_365b216b85254be92613100c34872249",
22
+ "sess_54388_1783058842867_1783058843114_396cad8719025805d423bfec1e2af48c"
23
+ ],
24
+ "results": [
25
+ {
26
+ "id": "r4-debug-forwarding-gap#1",
27
+ "agent": "reviewer",
28
+ "ok": true,
29
+ "ms": 143838,
30
+ "sessionId": "sess_20052_1783058612106_1783058612356_363946685eccb22a98de415cf55e2b6b",
31
+ "output": "sessionId: sess_20052_1783058612106_1783058612356_363946685eccb22a98de415cf55e2b6b\nFindings ordered by impact:\n\n- **Permanent skip on first bind to an existing, non-persisted transcript** — `OutputForwarder.setContext()` seeds `readFileSize` to current EOF when `catchUpFromPersisted` has no same-transcript cursor, so assistant bytes already written before binding are treated as already read; backlog catch-up does **not** recover them. Anchors: `src/runtime/channels/lib/output-forwarder.mjs:117`, `src/runtime/channels/lib/output-forwarder.mjs:122`, `src/runtime/channels/lib/output-forwarder.mjs:126`, `src/runtime/channels/index.mjs:625`, `src/runtime/channels/index.mjs:441`.\n\n- **Bridge active before runtime ownership/connection is ready** — activation writes `bridge-state.json` before `refreshBridgeOwnership()` completes, while `_isOwner()` stays false until `bridgeRuntimeConnected`; output during this interval is delayed, not read/advanced, and is recovered by the post-connect `forwardNewText()` path if the cursor was not already moved to EOF by the bind case above. Anchors: `src/runtime/channels/index.mjs:1735`, `src/runtime/channels/index.mjs:1744`, `src/runtime/channels/index.mjs:776`, `src/runtime/channels/lib/output-forwarder.mjs:351`, `src/runtime/channels/index.mjs:809`.\n\n- **Transcript path known but file not created yet** — `fs.watch()` fails on the missing file, so creation would be missed without the pending re-arm poll; backlog is recovered when the file appears within the 60s poll window, from offset 0 for a new transcript or from the persisted cursor for the same transcript. Anchors: `src/runtime/channels/lib/output-forwarder.mjs:647`, `src/runtime/channels/lib/output-forwarder.mjs:667`, `src/runtime/channels/index.mjs:357`, `src/runtime/channels/index.mjs:376`, `src/runtime/channels/index.mjs:485`.\n\n- **Pre-connect re-arm tick can fire while ownership is still false** — the poll exits when `bridgeRuntimeConnected` is false, so first output is delayed until the post-connect repair re-arms or forwards; recovered after connect, but if the file is still absent and appears after the 60s re-arm deadline, it remains delayed until another rebind/trigger. Anchors: `src/runtime/channels/index.mjs:372`, `src/runtime/channels/index.mjs:384`, `src/runtime/channels/index.mjs:803`, `src/runtime/channels/index.mjs:807`.\n\n- **Watch flush before ownership is established** — `startWatch()` schedules a flush immediately, but `forwardNewText()` returns before reading while `_isOwner()` is false; backlog is recovered by the explicit post-connect `forwardNewText()` and no cursor is advanced during the failed probe. Anchors: `src/runtime/channels/lib/output-forwarder.mjs:665`, `src/runtime/channels/lib/output-forwarder.mjs:724`, `src/runtime/channels/lib/output-forwarder.mjs:351`, `src/runtime/channels/index.mjs:809`.\n\nVerdict: the bridge mostly delays and catches up, but an existing current transcript with no same persisted cursor can still silently drop pre-bind assistant output by binding at EOF.",
32
+ "card": {
33
+ "session": "sess_20052_1783058612106_1783058612356_363946685eccb22a98de415cf55e2b6b",
34
+ "provider": "openai-oauth",
35
+ "model": "gpt-5.5",
36
+ "wall_ms": 133321,
37
+ "turns": 7,
38
+ "tool_calls": 9,
39
+ "tools_per_turn": 1.3,
40
+ "total_tool_ms": 776,
41
+ "llm_stream_ms": 131748,
42
+ "cache_ratio": 0.44157442640570693,
43
+ "cached_tokens": 101888,
44
+ "prompt_tokens": 230738,
45
+ "uncached_tokens": 128850,
46
+ "output_tokens": 9586,
47
+ "cache_weighted_input_10": 139038.8,
48
+ "cache_weighted_input_25": 154322,
49
+ "prompt_growth": 44194,
50
+ "antipatterns": 0,
51
+ "issues": 11,
52
+ "issue_types": [
53
+ "cache",
54
+ "cache_break",
55
+ "cache_miss",
56
+ "service_tier"
57
+ ],
58
+ "read_fragmentation_paths": [],
59
+ "grep_sweep_count": 0
60
+ }
61
+ },
62
+ {
63
+ "id": "r4-impl-usage-summary#1",
64
+ "agent": "worker",
65
+ "ok": true,
66
+ "ms": 263872,
67
+ "sessionId": "sess_6636_1783058612119_1783058612368_878b7998c6a201833b0d90d7db428756",
68
+ "output": "sessionId: sess_6636_1783058612119_1783058612368_878b7998c6a201833b0d90d7db428756\n요청 범위가 명확해 바로 구현 후 검증까지 진행하겠습니다.이미 같은 이름의 스크립트가 있어 요구사항과 맞는지 보정한 뒤 검증하겠습니다.현재 구현이 이미 잡혀 있어 검증과 실제 diff 확인으로 마무리하겠습니다.검증은 통과했고, 추적 상태만 확인해 최종 보고하겠습니다.재영님, 완료했습니다 — `usage:today` 스크립트와 `scripts/usage-today.mjs` 구현이 준비됐고 검증도 통과했습니다.\n\n- **Diff 요약**: `package.json`에 `\"usage:today\": \"node scripts/usage-today.mjs\"` 추가, `scripts/usage-today.mjs`는 오늘 자정 이후 usage rows를 모델별/총합으로 집계합니다.\n\n- **검증**: `node --check scripts/usage-today.mjs` 통과, `npm run usage:today` 실행 완료.\n\n- **실행 결과**: 현재 `MIXDOG_DATA_DIR` 기준 trace에서 `GRAND TOTAL`은 `1371 calls`, `51.03M input`, `49.76M cached`, `1.62M output`, `$89.6468`였습니다.\n\n- **작업 상태**: `package.json`은 수정됨, `scripts/usage-today.mjs`는 새 untracked 파일입니다.",
69
+ "card": {
70
+ "session": "sess_6636_1783058612119_1783058612368_878b7998c6a201833b0d90d7db428756",
71
+ "provider": "openai-oauth",
72
+ "model": "gpt-5.5",
73
+ "wall_ms": 253360,
74
+ "turns": 9,
75
+ "tool_calls": 11,
76
+ "tools_per_turn": 1.2,
77
+ "total_tool_ms": 2515,
78
+ "llm_stream_ms": 65504,
79
+ "cache_ratio": 0.6846480771224215,
80
+ "cached_tokens": 132096,
81
+ "prompt_tokens": 192940,
82
+ "uncached_tokens": 60844,
83
+ "output_tokens": 5124,
84
+ "cache_weighted_input_10": 74053.6,
85
+ "cache_weighted_input_25": 93868,
86
+ "prompt_growth": 27537,
87
+ "antipatterns": 1,
88
+ "issues": 14,
89
+ "issue_types": [
90
+ "cache",
91
+ "cache_break",
92
+ "cache_miss",
93
+ "service_tier",
94
+ "missed_parallelism",
95
+ "tool_churn_cluster"
96
+ ],
97
+ "read_fragmentation_paths": [],
98
+ "grep_sweep_count": 0
99
+ }
100
+ },
101
+ {
102
+ "id": "r4-explain-compact-engine#1",
103
+ "agent": "explore",
104
+ "ok": true,
105
+ "ms": 117362,
106
+ "sessionId": "sess_32108_1783058612133_1783058612379_16813f439160d71cffa545f046f32444",
107
+ "output": "sessionId: sess_32108_1783058612133_1783058612379_16813f439160d71cffa545f046f32444\n완료했습니다. compaction subsystem 요약은 아래와 같습니다.\n\n- **진입점**: public API는 `semanticCompactMessages()`와 `recallFastTrackCompactMessages()`이며 `compact.mjs`가 재수출합니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:278`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:445`, `src/runtime/agent/orchestrator/session/compact.mjs:52-55`\n\n- **주요 호출자**: active loop pre-send에서 recall-fasttrack 또는 semantic을 호출하고, manager runner는 manual/auto-clear compaction에서 같은 엔진을 호출합니다. `src/runtime/agent/orchestrator/session/loop.mjs:414-460`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:207-224`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:280-306`\n\n- **세션 경로**: `askSession()`은 `agentLoop()`로 들어가 pre-send compaction을 통과하며, `compactSessionMessages()`와 `clearSessionMessages()`는 `runSessionCompaction()`으로 수동 실행합니다. `src/runtime/agent/orchestrator/session/manager.mjs:1379-1400`, `src/runtime/agent/orchestrator/session/manager.mjs:1849-1856`, `src/runtime/agent/orchestrator/session/manager.mjs:1943-1957`\n\n- **발화 조건**: loop는 steering을 먼저 주입한 뒤 정책을 만들고, `messageTokensEst + reserveTokens >= triggerTokens`이면 compact합니다. `src/runtime/agent/orchestrator/session/loop.mjs:324-354`, `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:89-148`, `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:170-174`\n\n- **reactive 경로**: provider context overflow가 나면 한 번만 `reactiveOverflowRetryPending`을 세우고 다음 pre-send compact를 강제합니다. `src/runtime/agent/orchestrator/session/loop.mjs:982-1010`, `src/runtime/agent/orchestrator/session/loop.mjs:351-364`\n\n- **manual/auto-clear 조건**: runner는 closed/disabled/no-boundary를 빠져나가고, manual은 force이며 auto는 `pressureTokens < triggerTokens`면 “below threshold”로 종료합니다. `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:143-180`\n\n- **semantic tail 선택**: 먼저 system/protected prefix, previous summary, live를 분리하고, user turn이 있으면 최근 `tailTurns`를 `preserveRecentBudget` 안에서 보존합니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:100-111`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:235-242`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:134-185`\n\n- **no-user tail 선택**: user turn이 없으면 tool result로 시작하지 않는 cut point만 허용하고, 가장 최근부터 예산에 맞는 suffix를 고릅니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:121-127`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:193-232`\n\n- **semantic window 결과**: 선택된 live prefix는 summary 대상 head가 되고 suffix는 verbatim tail로 남으며, tail은 tool pair sanitize/dedup/reconcile을 거칩니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:244-267`\n\n- **recall tail 선택**: recall-fasttrack은 live에서 최근 최대 2 user-anchored turns를 보존하고 cap 초과 시 오래된 turn drop 후 단일 turn을 truncate합니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:467-471`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:593-611`\n\n- **recall no-user tail**: single-turn agent처럼 user가 없는 최신 assistant/tool 구조도 valid tail로 보존합니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:613-619`\n\n- **redaction hook**: semantic은 no-op이면 redaction 없이 sanitized transcript를 반환하고, 실제 compact 시에는 window selection 전에 tool-call secret 값을 redacts합니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:286-314`\n\n- **redaction 적용 범위**: recall-fasttrack도 split 전에 redacts하고, 보존된 system/tail은 redacted form으로 측정·출력됩니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:644-651`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:389-392`\n\n- **redaction 방식**: sensitive key 값과 raw string secret pair만 `[redacted]`로 바꾸며 shape, order, non-sensitive args는 보존합니다. `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:219-229`, `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:291-317`\n\n- **semantic 실패 조건**: provider 없음, empty live, head 없음, prompt fit 실패, empty provider summary, summary fit 실패, final budget 초과가 throw됩니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:278-280`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:254-256`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:315-336`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:371-397`\n\n- **recall 실패 조건**: compactable prior/recall text가 없거나 summary/final result가 budget에 맞지 않으면 throw됩니다. `src/runtime/agent/orchestrator/session/compact/engine.mjs:653-668`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:684-700`\n\n- **fallback**: loop/runner에서 semantic 실패는 `pruneToolOutputsUnanchored()`로 한 번 복구하지만 recall-fasttrack 실패에는 silent prune을 금지합니다. `src/runtime/agent/orchestrator/session/loop.mjs:500-537`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:322-347`\n\n- **recall degraded fallback**: manager runner의 recall-fasttrack 실패는 semantic이 enabled이고 provider가 있으면 semantic compact를 한 번 시도합니다. `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:231-279`\n\n- **hard failure 기록**: fallback도 실패하면 loop는 `overflow_failed` telemetry 후 `AgentContextOverflowError`를 던지고, runner는 `manual_failed`/`post_turn_failed`를 session.compaction에 남깁니다. `src/runtime/agent/orchestrator/session/loop.mjs:546-626`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:348-397`",
108
+ "card": {
109
+ "session": "sess_32108_1783058612133_1783058612379_16813f439160d71cffa545f046f32444",
110
+ "provider": "openai-oauth",
111
+ "model": "gpt-5.5",
112
+ "wall_ms": 106845,
113
+ "turns": 8,
114
+ "tool_calls": 10,
115
+ "tools_per_turn": 1.3,
116
+ "total_tool_ms": 1070,
117
+ "llm_stream_ms": 105884,
118
+ "cache_ratio": 0.7214462101076363,
119
+ "cached_tokens": 153088,
120
+ "prompt_tokens": 212196,
121
+ "uncached_tokens": 59108,
122
+ "output_tokens": 4515,
123
+ "cache_weighted_input_10": 74416.8,
124
+ "cache_weighted_input_25": 97380,
125
+ "prompt_growth": 52013,
126
+ "antipatterns": 0,
127
+ "issues": 10,
128
+ "issue_types": [
129
+ "cache",
130
+ "cache_break",
131
+ "service_tier"
132
+ ],
133
+ "read_fragmentation_paths": [],
134
+ "grep_sweep_count": 0
135
+ }
136
+ },
137
+ {
138
+ "id": "r4-debug-forwarding-gap#2",
139
+ "agent": "reviewer",
140
+ "ok": true,
141
+ "ms": 113378,
142
+ "sessionId": "sess_60200_1783058729488_1783058729715_0addf90688066bfe101c1e912ae350eb",
143
+ "output": "sessionId: sess_60200_1783058729488_1783058729715_0addf90688066bfe101c1e912ae350eb\n조사 결과, 첫 전달 전 창에는 “기존 파일을 EOF로 바인딩”하는 영구 드롭 경로가 있고, 나머지는 대체로 지연 후 catch-up됩니다.\n\n1. **영구 드롭 가능성 — 기존 transcript가 새로 발견되면 EOF부터 시작합니다.** `rebindTranscriptContext()`가 활성화 복구에서 `catchUpFromPersisted`로 바인딩하고, persisted path가 다르면 `setContext()`가 `currentSize`로 커서를 둡니다. 이미 써진 출력은 읽지 않습니다. Catch-up: **복구 안 됨**. `src/runtime/channels/index.mjs:625`, `src/runtime/channels/index.mjs:438`, `src/runtime/channels/lib/output-forwarder.mjs:117`\n\n2. **not-yet-created transcript — `fs.watch` 설치 실패 창은 보정됩니다.** `startWatch()`는 없는 파일에서 catch/close되고, `schedulePendingTranscriptRearm()`가 파일 생성 후 watch를 다시 설치하고 `forwardNewText()`로 backlog를 읽습니다. Catch-up: **60초 내 생성이면 복구, timeout 후 자동 복구 없음**. `src/runtime/channels/index.mjs:339`, `src/runtime/channels/index.mjs:357`, `src/runtime/channels/index.mjs:376`, `src/runtime/channels/index.mjs:384`, `src/runtime/channels/lib/output-forwarder.mjs:647`\n\n3. **bridge-state 이후 backend connect 전 — ownership probe가 fail-closed라 전달이 지연됩니다.** 활성화는 `bridge-state.json`을 먼저 쓰고, binding task는 `backend.connect()` 전 시작되지만 `_isOwner()`는 `bridgeRuntimeConnected` 전까지 false입니다. 커서는 전진하지 않으며 post-connect `forwardNewText()`/rearm가 다시 읽습니다. Catch-up: **복구됨, 단 1번 EOF 바인딩이면 이미 누락**. `src/runtime/channels/index.mjs:1735`, `src/runtime/channels/index.mjs:758`, `src/runtime/channels/index.mjs:776`, `src/runtime/channels/index.mjs:801`, `src/runtime/channels/lib/output-forwarder.mjs:36`\n\n4. **stat 이후 watch 설치 전 쓰기 — 즉시 flush로 보정됩니다.** `setContext()`가 커서를 잡은 뒤 `startWatch()`가 설치되고, 설치 성공 시 `scheduleWatchFlush()`를 호출해 그 사이 추가된 bytes를 읽습니다. Catch-up: **복구됨**. `src/runtime/channels/lib/output-forwarder.mjs:112`, `src/runtime/channels/lib/output-forwarder.mjs:665`, `src/runtime/channels/lib/output-forwarder.mjs:703`, `src/runtime/channels/lib/output-forwarder.mjs:724`\n\n5. **channelId 미해결 — 전달 대상이 없으면 forwarding 자체가 시작되지 않습니다.** 활성 상태에서 persisted channel 또는 main channel fallback이 없으면 bind가 반환되고, `forwardNewText()`도 channel 없이 false입니다. Catch-up: **나중에 채널이 잡혀도 1번 커서 조건에 따라 조건부**. `src/runtime/channels/index.mjs:610`, `src/runtime/channels/index.mjs:624`, `src/runtime/channels/lib/output-forwarder.mjs:351`\n\nVerdict: **가장 위험한 실제 누락 경로는 “이미 존재하지만 persisted cursor가 없는 transcript를 EOF로 바인딩”하는 경우이며, missing-file/watch/ownership 창은 대부분 bounded catch-up으로 복구됩니다.**",
144
+ "card": {
145
+ "session": "sess_60200_1783058729488_1783058729715_0addf90688066bfe101c1e912ae350eb",
146
+ "provider": "openai-oauth",
147
+ "model": "gpt-5.5",
148
+ "wall_ms": 102888,
149
+ "turns": 8,
150
+ "tool_calls": 9,
151
+ "tools_per_turn": 1.1,
152
+ "total_tool_ms": 820,
153
+ "llm_stream_ms": 102098,
154
+ "cache_ratio": 0.7833074378747296,
155
+ "cached_tokens": 164352,
156
+ "prompt_tokens": 209818,
157
+ "uncached_tokens": 45466,
158
+ "output_tokens": 10858,
159
+ "cache_weighted_input_10": 61901.2,
160
+ "cache_weighted_input_25": 86554,
161
+ "prompt_growth": 38295,
162
+ "antipatterns": 1,
163
+ "issues": 12,
164
+ "issue_types": [
165
+ "cache",
166
+ "cache_break",
167
+ "service_tier",
168
+ "missed_parallelism",
169
+ "tool_churn_cluster"
170
+ ],
171
+ "read_fragmentation_paths": [],
172
+ "grep_sweep_count": 0
173
+ }
174
+ },
175
+ {
176
+ "id": "r4-impl-usage-summary#2",
177
+ "agent": "worker",
178
+ "ok": true,
179
+ "ms": 108658,
180
+ "sessionId": "sess_54744_1783058755944_1783058756177_365b216b85254be92613100c34872249",
181
+ "output": "sessionId: sess_54744_1783058755944_1783058756177_365b216b85254be92613100c34872249\n요청 범위가 명확해서 바로 구현하고 검증까지 진행하겠습니다.이미 같은 이름의 스크립트가 있어 요구사항 충족 여부를 확인한 뒤 필요한 보정만 하겠습니다.구현 내용은 이미 작업 트리에 반영되어 있어 문법 검사와 실제 실행으로 확인하겠습니다.검증은 통과했고, 마지막으로 실제 변경 diff만 확인하겠습니다.재영님, 완료되었습니다: `usage:today` 스크립트와 `scripts/usage-today.mjs`가 추가되어 오늘 사용량을 모델별/총합으로 출력합니다.\n\n- **Diff 요약**: `package.json`에 `\"usage:today\": \"node scripts/usage-today.mjs\"` 추가, 새 스크립트는 `MIXDOG_DATA_DIR` 우선으로 `history/agent-trace.jsonl`을 읽습니다.\n\n- **동작**: 로컬 자정 이후 `usage_raw`/`usage` 행을 필터링해 모델별 calls, input/cached/output tokens, `costUsd`와 `GRAND TOTAL`을 출력하며 `--trace`, `--json`도 지원합니다.\n\n- **검증**: `node --check scripts/usage-today.mjs` 통과, `npm run usage:today` 실행 완료로 총 1369 calls / `$89.6468` 출력 확인했습니다.",
182
+ "card": {
183
+ "session": "sess_54744_1783058755944_1783058756177_365b216b85254be92613100c34872249",
184
+ "provider": "openai-oauth",
185
+ "model": "gpt-5.5",
186
+ "wall_ms": 98171,
187
+ "turns": 11,
188
+ "tool_calls": 12,
189
+ "tools_per_turn": 1.1,
190
+ "total_tool_ms": 2881,
191
+ "llm_stream_ms": 95194,
192
+ "cache_ratio": 0.8461555996261597,
193
+ "cached_tokens": 148480,
194
+ "prompt_tokens": 175476,
195
+ "uncached_tokens": 26996,
196
+ "output_tokens": 5479,
197
+ "cache_weighted_input_10": 41844,
198
+ "cache_weighted_input_25": 64116,
199
+ "prompt_growth": 17107,
200
+ "antipatterns": 1,
201
+ "issues": 15,
202
+ "issue_types": [
203
+ "cache",
204
+ "cache_break",
205
+ "cache_miss",
206
+ "service_tier",
207
+ "missed_parallelism",
208
+ "tool_churn_cluster"
209
+ ],
210
+ "read_fragmentation_paths": [],
211
+ "grep_sweep_count": 0
212
+ }
213
+ },
214
+ {
215
+ "id": "r4-explain-compact-engine#2",
216
+ "agent": "explore",
217
+ "ok": true,
218
+ "ms": 85624,
219
+ "sessionId": "sess_54388_1783058842867_1783058843114_396cad8719025805d423bfec1e2af48c",
220
+ "output": "sessionId: sess_54388_1783058842867_1783058843114_396cad8719025805d423bfec1e2af48c\n완료했습니다 — `engine.mjs` 중심 compaction 서브시스템 맵입니다.\n\n- **엔트리/호출자:** 실시간 루프는 `askSession → agentLoop`로 들어오고 pre-send 직전에 compaction을 검사한다 (`src/runtime/agent/orchestrator/session/manager.mjs:1379`, `src/runtime/agent/orchestrator/session/loop.mjs:324`).\n- **수동/clear 경로:** `compactSessionMessages`와 clear-before-compact가 `runSessionCompaction(... force:true)`를 호출한다 (`src/runtime/agent/orchestrator/session/manager.mjs:1849`, `src/runtime/agent/orchestrator/session/manager.mjs:1950`).\n- **발화 조건:** auto가 켜진 policy만 검사하고, 토큰 추정+reserve 압력이 trigger/boundary 이상이거나 reactive overflow면 실행한다 (`src/runtime/agent/orchestrator/session/loop.mjs:329`, `src/runtime/agent/orchestrator/session/loop.mjs:351`, `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:170`).\n- **예산 결정:** compact 목표는 boundary 안에서 target+reserve로 잡고, 실행 시 `compactTargetBudget` 또는 boundary를 쓴다 (`src/runtime/agent/orchestrator/session/loop.mjs:362`, `src/runtime/agent/orchestrator/session/loop/compact-policy.mjs:163`).\n- **타입 분기:** policy가 recall-fasttrack이면 memory recall 기반 compaction, 아니면 semantic compaction으로 간다 (`src/runtime/agent/orchestrator/session/loop.mjs:414`, `src/runtime/agent/orchestrator/session/loop.mjs:439`).\n- **공통 전처리:** engine은 tool pair 정리, 중복 tool result 정리, protected/system prefix 분리, 이전 summary 탐색, live 메시지 추출을 먼저 한다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:100`).\n- **semantic tail:** user turn이 있으면 최근 `tailTurns`를 `preserveRecentBudget` 안에서 보존하고, 최신 turn이 너무 크면 suffix split을 시도한다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:134`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:151`).\n- **no-user semantic tail:** user turn이 없으면 tool result로 시작하지 않는 cut point를 최신→과거로 넓히며 budget에 맞는 tail을 고른다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:121`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:193`).\n- **recall tail:** recall-fasttrack은 live를 turn으로 나누고 최신 최대 2 user turns를 보존하되 cap 초과 시 오래된 turn을 버리고 마지막 turn을 truncate한다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:593`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:601`).\n- **tail budget:** 보존 recent budget은 explicit `preserveRecentTokens/keepTokens` 우선, 아니면 budget의 25%와 기본 keep token을 80% 상한 안에서 선택한다 (`src/runtime/agent/orchestrator/session/compact/budget.mjs:274`).\n- **redaction 위치:** fits-budget no-op은 원본 sanitized를 그대로 반환하지만, 실제 compaction은 window selection 전에 preserved system/tail까지 `redactToolCallSecretsInMessages`로 scrub한다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:286`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:306`).\n- **redaction 범위:** preserved tail redaction은 assistant `toolCalls` argument value만 shape-preserving으로 바꾸며, raw `authorization/password/token`류도 `[redacted]` 처리한다 (`src/runtime/agent/orchestrator/session/compact/text-utils.mjs:217`, `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:323`).\n- **summary prompt:** semantic은 head+previous summary+preserved facts로 prompt를 만들고, tool call metadata는 prompt-side normalizer가 별도 redaction/truncation한다 (`src/runtime/agent/orchestrator/session/compact/summary.mjs:93`, `src/runtime/agent/orchestrator/session/compact/text-utils.mjs:121`).\n- **결과 조립:** semantic은 system + summary + redacted tail을 재정리하고 budget 초과 시 실패하며, recall도 system + recall summary + redacted tail을 같은 방식으로 검증한다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:392`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:695`).\n- **budget fallback:** mandatory system+tail이 목표 budget보다 크면 실패하지 않고 summary 최소 공간만큼 budget을 올린다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:328`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:661`).\n- **semantic 실패:** provider 없음, empty live, compactable prior 없음, prompt fit 실패, empty summary, summary fit 실패, final budget 초과가 hard error다 (`src/runtime/agent/orchestrator/session/compact/engine.mjs:279`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:315`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:335`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:372`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:385`, `src/runtime/agent/orchestrator/session/compact/engine.mjs:395`).\n- **recall fallback:** manual/session runner에서 recall-fasttrack 실패 시 semantic이 가능하면 한 번 degraded fallback을 시도하고 성공한 경우만 history를 교체한다 (`src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:237`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:245`).\n- **prune fallback:** semantic/non-recall 실패는 unanchored old tool output prune으로 한 번 salvage하고, recall-fasttrack 실패에는 이 prune을 적용하지 않는다 (`src/runtime/agent/orchestrator/session/loop.mjs:500`, `src/runtime/agent/orchestrator/session/loop.mjs:517`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:322`).\n- **최종 실패:** 루프 pre-send 실패는 telemetry/event 기록 후 `AgentContextOverflowError`로 승격하고, runner 실패는 session compaction state에 `manual_failed/post_turn_failed`로 기록한다 (`src/runtime/agent/orchestrator/session/loop.mjs:546`, `src/runtime/agent/orchestrator/session/loop.mjs:618`, `src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs:348`).",
221
+ "card": {
222
+ "session": "sess_54388_1783058842867_1783058843114_396cad8719025805d423bfec1e2af48c",
223
+ "provider": "openai-oauth",
224
+ "model": "gpt-5.5",
225
+ "wall_ms": 75113,
226
+ "turns": 8,
227
+ "tool_calls": 8,
228
+ "tools_per_turn": 1,
229
+ "total_tool_ms": 540,
230
+ "llm_stream_ms": 74441,
231
+ "cache_ratio": 0.5597193267910714,
232
+ "cached_tokens": 88064,
233
+ "prompt_tokens": 157336,
234
+ "uncached_tokens": 69272,
235
+ "output_tokens": 3912,
236
+ "cache_weighted_input_10": 78078.4,
237
+ "cache_weighted_input_25": 91288,
238
+ "prompt_growth": 44302,
239
+ "antipatterns": 1,
240
+ "issues": 15,
241
+ "issue_types": [
242
+ "cache",
243
+ "cache_break",
244
+ "cache_miss",
245
+ "broad_tool_result",
246
+ "service_tier",
247
+ "missed_parallelism",
248
+ "tool_churn_cluster"
249
+ ],
250
+ "read_fragmentation_paths": [],
251
+ "grep_sweep_count": 0
252
+ }
253
+ }
254
+ ],
255
+ "task_complete": true,
256
+ "task_errors": [],
257
+ "score_complete": true,
258
+ "score_errors": [],
259
+ "group": {
260
+ "n": 6,
261
+ "wall_ms": 128283,
262
+ "turns": 8.5,
263
+ "tool_calls": 9.8,
264
+ "tools_per_turn": 1.2,
265
+ "total_tool_ms": 1433.7,
266
+ "llm_stream_ms": 95811.5,
267
+ "cache_ratio": 0.7,
268
+ "cached_tokens": 131328,
269
+ "prompt_tokens": 196417.3,
270
+ "uncached_tokens": 65089.3,
271
+ "output_tokens": 6579,
272
+ "cache_weighted_input_10": 78222.1,
273
+ "cache_weighted_input_25": 97921.3,
274
+ "prompt_growth": 37241.3,
275
+ "antipatterns": 0.7,
276
+ "issues": 12.8,
277
+ "grep_sweep_count": 0
278
+ },
279
+ "cards": [
280
+ {
281
+ "session": "sess_20052_1783058612106_1783058612356_363946685eccb22a98de415cf55e2b6b",
282
+ "provider": "openai-oauth",
283
+ "model": "gpt-5.5",
284
+ "wall_ms": 133321,
285
+ "turns": 7,
286
+ "tool_calls": 9,
287
+ "tools_per_turn": 1.3,
288
+ "total_tool_ms": 776,
289
+ "llm_stream_ms": 131748,
290
+ "cache_ratio": 0.44157442640570693,
291
+ "cached_tokens": 101888,
292
+ "prompt_tokens": 230738,
293
+ "uncached_tokens": 128850,
294
+ "output_tokens": 9586,
295
+ "cache_weighted_input_10": 139038.8,
296
+ "cache_weighted_input_25": 154322,
297
+ "prompt_growth": 44194,
298
+ "antipatterns": 0,
299
+ "issues": 11,
300
+ "issue_types": [
301
+ "cache",
302
+ "cache_break",
303
+ "cache_miss",
304
+ "service_tier"
305
+ ],
306
+ "read_fragmentation_paths": [],
307
+ "grep_sweep_count": 0
308
+ },
309
+ {
310
+ "session": "sess_6636_1783058612119_1783058612368_878b7998c6a201833b0d90d7db428756",
311
+ "provider": "openai-oauth",
312
+ "model": "gpt-5.5",
313
+ "wall_ms": 253360,
314
+ "turns": 9,
315
+ "tool_calls": 11,
316
+ "tools_per_turn": 1.2,
317
+ "total_tool_ms": 2515,
318
+ "llm_stream_ms": 65504,
319
+ "cache_ratio": 0.6846480771224215,
320
+ "cached_tokens": 132096,
321
+ "prompt_tokens": 192940,
322
+ "uncached_tokens": 60844,
323
+ "output_tokens": 5124,
324
+ "cache_weighted_input_10": 74053.6,
325
+ "cache_weighted_input_25": 93868,
326
+ "prompt_growth": 27537,
327
+ "antipatterns": 1,
328
+ "issues": 14,
329
+ "issue_types": [
330
+ "cache",
331
+ "cache_break",
332
+ "cache_miss",
333
+ "service_tier",
334
+ "missed_parallelism",
335
+ "tool_churn_cluster"
336
+ ],
337
+ "read_fragmentation_paths": [],
338
+ "grep_sweep_count": 0
339
+ },
340
+ {
341
+ "session": "sess_32108_1783058612133_1783058612379_16813f439160d71cffa545f046f32444",
342
+ "provider": "openai-oauth",
343
+ "model": "gpt-5.5",
344
+ "wall_ms": 106845,
345
+ "turns": 8,
346
+ "tool_calls": 10,
347
+ "tools_per_turn": 1.3,
348
+ "total_tool_ms": 1070,
349
+ "llm_stream_ms": 105884,
350
+ "cache_ratio": 0.7214462101076363,
351
+ "cached_tokens": 153088,
352
+ "prompt_tokens": 212196,
353
+ "uncached_tokens": 59108,
354
+ "output_tokens": 4515,
355
+ "cache_weighted_input_10": 74416.8,
356
+ "cache_weighted_input_25": 97380,
357
+ "prompt_growth": 52013,
358
+ "antipatterns": 0,
359
+ "issues": 10,
360
+ "issue_types": [
361
+ "cache",
362
+ "cache_break",
363
+ "service_tier"
364
+ ],
365
+ "read_fragmentation_paths": [],
366
+ "grep_sweep_count": 0
367
+ },
368
+ {
369
+ "session": "sess_60200_1783058729488_1783058729715_0addf90688066bfe101c1e912ae350eb",
370
+ "provider": "openai-oauth",
371
+ "model": "gpt-5.5",
372
+ "wall_ms": 102888,
373
+ "turns": 8,
374
+ "tool_calls": 9,
375
+ "tools_per_turn": 1.1,
376
+ "total_tool_ms": 820,
377
+ "llm_stream_ms": 102098,
378
+ "cache_ratio": 0.7833074378747296,
379
+ "cached_tokens": 164352,
380
+ "prompt_tokens": 209818,
381
+ "uncached_tokens": 45466,
382
+ "output_tokens": 10858,
383
+ "cache_weighted_input_10": 61901.2,
384
+ "cache_weighted_input_25": 86554,
385
+ "prompt_growth": 38295,
386
+ "antipatterns": 1,
387
+ "issues": 12,
388
+ "issue_types": [
389
+ "cache",
390
+ "cache_break",
391
+ "service_tier",
392
+ "missed_parallelism",
393
+ "tool_churn_cluster"
394
+ ],
395
+ "read_fragmentation_paths": [],
396
+ "grep_sweep_count": 0
397
+ },
398
+ {
399
+ "session": "sess_54744_1783058755944_1783058756177_365b216b85254be92613100c34872249",
400
+ "provider": "openai-oauth",
401
+ "model": "gpt-5.5",
402
+ "wall_ms": 98171,
403
+ "turns": 11,
404
+ "tool_calls": 12,
405
+ "tools_per_turn": 1.1,
406
+ "total_tool_ms": 2881,
407
+ "llm_stream_ms": 95194,
408
+ "cache_ratio": 0.8461555996261597,
409
+ "cached_tokens": 148480,
410
+ "prompt_tokens": 175476,
411
+ "uncached_tokens": 26996,
412
+ "output_tokens": 5479,
413
+ "cache_weighted_input_10": 41844,
414
+ "cache_weighted_input_25": 64116,
415
+ "prompt_growth": 17107,
416
+ "antipatterns": 1,
417
+ "issues": 15,
418
+ "issue_types": [
419
+ "cache",
420
+ "cache_break",
421
+ "cache_miss",
422
+ "service_tier",
423
+ "missed_parallelism",
424
+ "tool_churn_cluster"
425
+ ],
426
+ "read_fragmentation_paths": [],
427
+ "grep_sweep_count": 0
428
+ },
429
+ {
430
+ "session": "sess_54388_1783058842867_1783058843114_396cad8719025805d423bfec1e2af48c",
431
+ "provider": "openai-oauth",
432
+ "model": "gpt-5.5",
433
+ "wall_ms": 75113,
434
+ "turns": 8,
435
+ "tool_calls": 8,
436
+ "tools_per_turn": 1,
437
+ "total_tool_ms": 540,
438
+ "llm_stream_ms": 74441,
439
+ "cache_ratio": 0.5597193267910714,
440
+ "cached_tokens": 88064,
441
+ "prompt_tokens": 157336,
442
+ "uncached_tokens": 69272,
443
+ "output_tokens": 3912,
444
+ "cache_weighted_input_10": 78078.4,
445
+ "cache_weighted_input_25": 91288,
446
+ "prompt_growth": 44302,
447
+ "antipatterns": 1,
448
+ "issues": 15,
449
+ "issue_types": [
450
+ "cache",
451
+ "cache_break",
452
+ "cache_miss",
453
+ "broad_tool_result",
454
+ "service_tier",
455
+ "missed_parallelism",
456
+ "tool_churn_cluster"
457
+ ],
458
+ "read_fragmentation_paths": [],
459
+ "grep_sweep_count": 0
460
+ }
461
+ ]
462
+ }