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
@@ -0,0 +1,410 @@
1
+ import { readFileSync, existsSync, mkdirSync, appendFileSync, statSync, renameSync } from 'fs';
2
+ import { appendFile } from 'fs/promises';
3
+ import { dirname, join } from 'path';
4
+ import os from 'os';
5
+ import { getPluginData } from './config.mjs';
6
+
7
+ const WARNED_KEYS = new Set();
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // In-memory buffer + HTTP flush to memory-service /admin/trace-record
11
+ // ---------------------------------------------------------------------------
12
+ let _buffer = [];
13
+ const _BUFFER_MAX = 2000;
14
+ const _FLUSH_INTERVAL_MS = 5000;
15
+ const _FLUSH_BATCH_SIZE = 500;
16
+ let _flushTimer = null;
17
+ let _serviceUrl = null;
18
+ let _flushInFlight = false;
19
+ let _localTracePath = null;
20
+ let _localTraceBuffer = [];
21
+ let _localTraceTimer = null;
22
+ let _localTraceFlushInFlight = false;
23
+ let _toolFailurePath = null;
24
+ let _toolFailureBuffer = [];
25
+ let _toolFailureTimer = null;
26
+ let _toolFailureFlushInFlight = false;
27
+ const _LOCAL_TRACE_FLUSH_LINES = 100;
28
+ const _LOCAL_TRACE_FLUSH_MS = 1000;
29
+ const _LOCAL_TRACE_MAX_BYTES = 10 * 1024 * 1024; // 10 MB — rotate to .1/.2/.3 above this.
30
+ // Rotation generations kept on disk (.1 newest … .N oldest). A single .1
31
+ // generation proved too short a window — bench rounds (session-bench /
32
+ // task-bench re-scoring) were losing their raw turn rows to a second rotation
33
+ // within hours. 3 generations ≈ 40 MB worst case per log. Env-overridable via
34
+ // MIXDOG_AGENT_TRACE_ROTATE_KEEP (positive integer).
35
+ const _LOCAL_TRACE_ROTATE_KEEP = (() => {
36
+ const v = parseInt(process.env.MIXDOG_AGENT_TRACE_ROTATE_KEEP, 10);
37
+ return Number.isFinite(v) && v > 0 ? v : 3;
38
+ })();
39
+ const _TOOL_FAILURE_FLUSH_LINES = 50;
40
+ const _TOOL_FAILURE_FLUSH_MS = 1000;
41
+ // Throttle interval for local rotation stat checks. statSync on every flush
42
+ // is unnecessary — rotation is a best-effort size guard. First flush always
43
+ // checks; subsequent checks wait at least this many ms. Tune via env
44
+ // MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS (default 60000 ms, positive integer).
45
+ const MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS = (() => {
46
+ const v = parseInt(process.env.MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS, 10);
47
+ return Number.isFinite(v) && v > 0 ? v : 60000;
48
+ })();
49
+ let _lastRotateCheckMs = 0;
50
+ let _lastToolFailureRotateCheckMs = 0;
51
+
52
+ function warnAgentOnce(key, message) {
53
+ if (!key || WARNED_KEYS.has(key)) return;
54
+ WARNED_KEYS.add(key);
55
+ try {
56
+ process.stderr.write(`${message}\n`);
57
+ }
58
+ catch {
59
+ // Ignore logging failures.
60
+ }
61
+ }
62
+
63
+ function normalizeSessionId(sessionId) {
64
+ return sessionId ? String(sessionId) : 'no-session';
65
+ }
66
+
67
+ function _rotateLocalTraceIfNeeded(path) {
68
+ try {
69
+ const stat = statSync(path);
70
+ if (stat && stat.size > _LOCAL_TRACE_MAX_BYTES) {
71
+ try {
72
+ // Shift generations oldest-first: .2 → .3, .1 → .2, live → .1.
73
+ // The oldest (.KEEP) is overwritten by the rename below it.
74
+ for (let gen = _LOCAL_TRACE_ROTATE_KEEP - 1; gen >= 1; gen -= 1) {
75
+ const src = `${path}.${gen}`;
76
+ if (existsSync(src)) renameSync(src, `${path}.${gen + 1}`);
77
+ }
78
+ renameSync(path, `${path}.1`);
79
+ }
80
+ catch (err) {
81
+ warnAgentOnce('agent-trace:local-rotate', `[agent-trace] local rotate failed (${err?.message})`);
82
+ }
83
+ }
84
+ } catch {
85
+ // File missing or unstattable — nothing to rotate.
86
+ }
87
+ }
88
+
89
+ function _resolveLocalTracePath() {
90
+ if (process.env.MIXDOG_AGENT_TRACE_LOCAL_DISABLE === '1') return null;
91
+ if (_localTracePath) return _localTracePath;
92
+ try {
93
+ _localTracePath = process.env.MIXDOG_AGENT_TRACE_PATH
94
+ || join(getPluginData(), 'history', 'agent-trace.jsonl');
95
+ // R4 data-at-rest: trace rows may carry tool payloads / prompts;
96
+ // clamp dir to owner-only on POSIX (advisory on Windows).
97
+ mkdirSync(dirname(_localTracePath), { recursive: true, mode: 0o700 });
98
+ return _localTracePath;
99
+ } catch {
100
+ return null;
101
+ }
102
+ }
103
+
104
+ function _appendLocalTrace(row) {
105
+ if (!_resolveLocalTracePath()) return;
106
+ try {
107
+ _localTraceBuffer.push(`${JSON.stringify(row)}\n`);
108
+ if (_localTraceBuffer.length >= _LOCAL_TRACE_FLUSH_LINES) {
109
+ _flushLocalTrace();
110
+ } else if (!_localTraceTimer) {
111
+ _localTraceTimer = setTimeout(_flushLocalTrace, _LOCAL_TRACE_FLUSH_MS);
112
+ _localTraceTimer.unref?.();
113
+ }
114
+ } catch (err) {
115
+ warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
116
+ }
117
+ }
118
+
119
+ function _flushLocalTrace() {
120
+ if (_localTraceTimer) {
121
+ clearTimeout(_localTraceTimer);
122
+ _localTraceTimer = null;
123
+ }
124
+ if (_localTraceBuffer.length === 0) return;
125
+ if (_localTraceFlushInFlight) {
126
+ _localTraceTimer = setTimeout(_flushLocalTrace, 25);
127
+ _localTraceTimer.unref?.();
128
+ return;
129
+ }
130
+ const path = _resolveLocalTracePath();
131
+ if (!path) return;
132
+ const chunk = _localTraceBuffer.join('');
133
+ _localTraceBuffer = [];
134
+ try {
135
+ // Throttle rotation stat checks to avoid unnecessary statSync calls
136
+ // on every flush. First flush (_lastRotateCheckMs === 0) always checks.
137
+ const now = Date.now();
138
+ if (_lastRotateCheckMs === 0 || now - _lastRotateCheckMs >= MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) {
139
+ _rotateLocalTraceIfNeeded(path);
140
+ _lastRotateCheckMs = now;
141
+ }
142
+ } catch (err) {
143
+ warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
144
+ return;
145
+ }
146
+ // mode only applies on file creation; existing files keep their mode.
147
+ // Windows ignores POSIX bits — ACL governs there.
148
+ _localTraceFlushInFlight = true;
149
+ appendFile(path, chunk, { encoding: 'utf8', mode: 0o600 })
150
+ .catch((err) => {
151
+ warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
152
+ })
153
+ .finally(() => {
154
+ _localTraceFlushInFlight = false;
155
+ if (_localTraceBuffer.length > 0) {
156
+ _localTraceTimer = setTimeout(_flushLocalTrace, 0);
157
+ _localTraceTimer.unref?.();
158
+ }
159
+ });
160
+ }
161
+
162
+ function _flushLocalTraceSync() {
163
+ if (_localTraceTimer) {
164
+ clearTimeout(_localTraceTimer);
165
+ _localTraceTimer = null;
166
+ }
167
+ if (_localTraceBuffer.length === 0) return;
168
+ const path = _resolveLocalTracePath();
169
+ if (!path) return;
170
+ const chunk = _localTraceBuffer.join('');
171
+ _localTraceBuffer = [];
172
+ try {
173
+ const now = Date.now();
174
+ if (_lastRotateCheckMs === 0 || now - _lastRotateCheckMs >= MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) {
175
+ _rotateLocalTraceIfNeeded(path);
176
+ _lastRotateCheckMs = now;
177
+ }
178
+ appendFileSync(path, chunk, { encoding: 'utf8', mode: 0o600 });
179
+ } catch (err) {
180
+ warnAgentOnce('agent-trace:local-spool', `[agent-trace] local spool failed (${err?.message})`);
181
+ }
182
+ }
183
+
184
+ try {
185
+ process.on('beforeExit', () => {
186
+ _flushLocalTraceSync();
187
+ _flushToolFailuresSync();
188
+ });
189
+ process.on('exit', () => {
190
+ _flushLocalTraceSync();
191
+ _flushToolFailuresSync();
192
+ });
193
+ } catch {
194
+ // Ignore lifecycle hook failures in embedded runtimes.
195
+ }
196
+
197
+ function _resolveServiceUrl() {
198
+ if (_serviceUrl) return _serviceUrl;
199
+ try {
200
+ const runtimeRoot = process.env.MIXDOG_RUNTIME_ROOT
201
+ ? join(process.env.MIXDOG_RUNTIME_ROOT)
202
+ : join(os.tmpdir(), 'mixdog');
203
+ const activeFile = join(runtimeRoot, 'active-instance.json');
204
+ if (!existsSync(activeFile)) return null;
205
+ const active = JSON.parse(readFileSync(activeFile, 'utf-8'));
206
+ const port = Number(active && active.memory_port);
207
+ if (!Number.isFinite(port) || port <= 0) return null;
208
+ _serviceUrl = `http://127.0.0.1:${port}`;
209
+ return _serviceUrl;
210
+ } catch {
211
+ return null;
212
+ }
213
+ }
214
+
215
+ async function _flush() {
216
+ _flushTimer = null;
217
+ if (_buffer.length === 0) return;
218
+ if (_flushInFlight) {
219
+ if (!_flushTimer) { _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS); _flushTimer.unref?.(); }
220
+ return;
221
+ }
222
+ _flushInFlight = true;
223
+ try {
224
+ const url = _resolveServiceUrl();
225
+ if (!url) {
226
+ // Service not up yet — keep buffer, retry next timer tick
227
+ if (!_flushTimer) { _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS); _flushTimer.unref?.(); }
228
+ return;
229
+ }
230
+ const batch = _buffer.splice(0, _FLUSH_BATCH_SIZE);
231
+ try {
232
+ const resp = await fetch(`${url}/admin/trace-record`, {
233
+ method: 'POST',
234
+ headers: { 'Content-Type': 'application/json' },
235
+ body: JSON.stringify({ events: batch }),
236
+ signal: AbortSignal.timeout(5000),
237
+ });
238
+ // Always drain the body. An undrained response body keeps the
239
+ // underlying keep-alive socket referenced, which can hold the event
240
+ // loop open and make a short-lived process (smoke scripts / one-shot
241
+ // agent tasks) appear to hang for seconds after its work is done.
242
+ try { await resp.arrayBuffer(); } catch { /* body already gone */ }
243
+ if (!resp.ok) {
244
+ warnAgentOnce('agent-trace:flush-error', `[agent-trace] /admin/trace-record returned ${resp.status} — dropping batch`);
245
+ }
246
+ } catch (err) {
247
+ _serviceUrl = null;
248
+ warnAgentOnce('agent-trace:flush-fetch', `[agent-trace] flush fetch failed (${err?.message}) — dropping batch`);
249
+ }
250
+ if (_buffer.length >= _FLUSH_BATCH_SIZE) {
251
+ // More pending — schedule another flush immediately
252
+ setImmediate(_flush);
253
+ }
254
+ } finally {
255
+ _flushInFlight = false;
256
+ }
257
+ }
258
+
259
+ function _scheduleFlush(immediate = false) {
260
+ if (immediate) {
261
+ if (_flushTimer) { clearTimeout(_flushTimer); _flushTimer = null; }
262
+ setImmediate(_flush);
263
+ } else if (!_flushTimer) {
264
+ _flushTimer = setTimeout(_flush, _FLUSH_INTERVAL_MS);
265
+ // Never let the periodic trace flush keep the event loop alive: a
266
+ // ref'd 5s timer prevented short-lived processes (smoke scripts, agent
267
+ // tasks) from exiting naturally after their work was done — they hung
268
+ // until an external timeout/kill. exit/beforeExit drains still flush
269
+ // the buffer, so unref loses no data.
270
+ _flushTimer.unref?.();
271
+ }
272
+ }
273
+
274
+ async function drainAgentTrace() {
275
+ if (!_resolveServiceUrl()) return;
276
+ if (_flushTimer) { clearTimeout(_flushTimer); _flushTimer = null; }
277
+ for (let i = 0; i < 10 && _buffer.length > 0; i++) {
278
+ await _flush();
279
+ }
280
+ }
281
+ process.on('exit', drainAgentTrace);
282
+
283
+ function appendAgentTrace(record = {}) {
284
+ // Test isolation — when run-all-tests.mjs sets this env, skip entirely.
285
+ if (process.env.MIXDOG_AGENT_TRACE_DISABLE === '1') return;
286
+ try {
287
+ // Coerce ts to epoch ms integer at enqueue time
288
+ let ts = record.ts || Date.now();
289
+ if (typeof ts === 'string') ts = Date.parse(ts);
290
+ ts = Number(ts);
291
+ if (!Number.isFinite(ts)) ts = Date.now();
292
+
293
+ const row = {
294
+ ...record,
295
+ ts,
296
+ session_id: record.session_id ?? normalizeSessionId(record.sessionId),
297
+ payload: record.payload ?? {},
298
+ };
299
+ // Drop actor-facing alias to keep schema tidy
300
+ delete row.sessionId;
301
+
302
+ if (_buffer.length >= _BUFFER_MAX) {
303
+ _buffer.shift(); // drop oldest
304
+ warnAgentOnce('agent-trace:buffer-full', '[agent-trace] buffer full (2000) — dropping oldest event');
305
+ }
306
+ _appendLocalTrace(row);
307
+ _buffer.push(row);
308
+ _scheduleFlush(_buffer.length >= _FLUSH_BATCH_SIZE);
309
+ }
310
+ catch {
311
+ // Never break agent execution for telemetry
312
+ }
313
+ }
314
+
315
+ function _resolveToolFailurePath() {
316
+ if (process.env.MIXDOG_TOOL_FAILURE_LOG_DISABLE === '1') return null;
317
+ if (_toolFailurePath) return _toolFailurePath;
318
+ try {
319
+ _toolFailurePath = process.env.MIXDOG_TOOL_FAILURE_LOG_PATH
320
+ || join(getPluginData(), 'history', 'tool-failures.jsonl');
321
+ mkdirSync(dirname(_toolFailurePath), { recursive: true, mode: 0o700 });
322
+ return _toolFailurePath;
323
+ } catch {
324
+ return null;
325
+ }
326
+ }
327
+
328
+ function _scheduleToolFailureFlush(delayMs = _TOOL_FAILURE_FLUSH_MS) {
329
+ if (_toolFailureTimer) return;
330
+ _toolFailureTimer = setTimeout(_flushToolFailures, delayMs);
331
+ _toolFailureTimer.unref?.();
332
+ }
333
+
334
+ function _maybeRotateToolFailureLog(path) {
335
+ const now = Date.now();
336
+ if (_lastToolFailureRotateCheckMs !== 0 && now - _lastToolFailureRotateCheckMs < MIXDOG_AGENT_TRACE_ROTATE_CHECK_MS) return;
337
+ _rotateLocalTraceIfNeeded(path);
338
+ _lastToolFailureRotateCheckMs = now;
339
+ }
340
+
341
+ function _appendToolFailureRow(row) {
342
+ if (!_resolveToolFailurePath()) return;
343
+ try {
344
+ _toolFailureBuffer.push(`${JSON.stringify(row)}\n`);
345
+ if (_toolFailureBuffer.length >= _TOOL_FAILURE_FLUSH_LINES) {
346
+ _flushToolFailures();
347
+ } else {
348
+ _scheduleToolFailureFlush();
349
+ }
350
+ } catch (err) {
351
+ warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
352
+ }
353
+ }
354
+
355
+ function _flushToolFailures() {
356
+ if (_toolFailureTimer) {
357
+ clearTimeout(_toolFailureTimer);
358
+ _toolFailureTimer = null;
359
+ }
360
+ if (_toolFailureBuffer.length === 0) return;
361
+ if (_toolFailureFlushInFlight) {
362
+ _scheduleToolFailureFlush(25);
363
+ return;
364
+ }
365
+ const path = _resolveToolFailurePath();
366
+ if (!path) return;
367
+ const chunk = _toolFailureBuffer.join('');
368
+ _toolFailureBuffer = [];
369
+ try {
370
+ _maybeRotateToolFailureLog(path);
371
+ } catch (err) {
372
+ warnAgentOnce('tool-failure-log:rotate', `[tool-failure-log] rotate check failed (${err?.message})`);
373
+ }
374
+ _toolFailureFlushInFlight = true;
375
+ appendFile(path, chunk, { encoding: 'utf8', mode: 0o600 })
376
+ .catch((err) => {
377
+ warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
378
+ })
379
+ .finally(() => {
380
+ _toolFailureFlushInFlight = false;
381
+ if (_toolFailureBuffer.length > 0) _scheduleToolFailureFlush(0);
382
+ });
383
+ }
384
+
385
+ function _flushToolFailuresSync() {
386
+ if (_toolFailureTimer) {
387
+ clearTimeout(_toolFailureTimer);
388
+ _toolFailureTimer = null;
389
+ }
390
+ if (_toolFailureBuffer.length === 0) return;
391
+ const path = _resolveToolFailurePath();
392
+ if (!path) return;
393
+ const chunk = _toolFailureBuffer.join('');
394
+ _toolFailureBuffer = [];
395
+ try {
396
+ _maybeRotateToolFailureLog(path);
397
+ appendFileSync(path, chunk, { encoding: 'utf8', mode: 0o600 });
398
+ } catch (err) {
399
+ warnAgentOnce('tool-failure-log:append', `[tool-failure-log] append failed (${err?.message})`);
400
+ }
401
+ }
402
+
403
+ export {
404
+ appendAgentTrace,
405
+ drainAgentTrace,
406
+ normalizeSessionId,
407
+ warnAgentOnce,
408
+ _resolveToolFailurePath,
409
+ _appendToolFailureRow,
410
+ };