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,324 @@
1
+ // Entry-mutation + phase_merge cluster extracted from memory-cycle2.mjs.
2
+ // DB status/update/merge writers plus the cosine-similarity dedup pass.
3
+ // Facade (memory-cycle2.mjs) re-exports the public members unchanged.
4
+ import { deleteRootEmbedding, syncRootEmbedding } from './memory-embed.mjs'
5
+ import { callAgentDispatch } from './agent-ipc.mjs'
6
+ import { __mixdogMemoryLog, throwIfAborted } from './memory-cycle2-shared.mjs'
7
+
8
+ const TIER1_THRESHOLD = 0.78
9
+ const TIER2_LOW = 0.65
10
+ const LLM_JUDGE_CAP = 20
11
+
12
+ // Batch CTE UPDATE for status-only verdicts (active/archived from pending or active rows).
13
+ // Trigger handles score recompute automatically — no app-side score writes.
14
+ export async function applyBatchStatusVerdicts(db, batch, nowMs) {
15
+ if (!batch || batch.length === 0) return { promoted: 0, archived: 0 }
16
+ const valueRows = batch.map((item, i) => {
17
+ const base = i * 3
18
+ return `($${base + 1}::bigint, $${base + 2}::text, $${base + 3}::boolean)`
19
+ })
20
+ const params = []
21
+ for (const item of batch) {
22
+ params.push(item.entry_id, item.new_status, item.was_pending)
23
+ }
24
+ params.push(nowMs)
25
+ const lastParam = `$${params.length}`
26
+ const res = await db.query(
27
+ `WITH actions(entry_id, new_status, was_pending) AS (
28
+ VALUES ${valueRows.join(', ')}
29
+ )
30
+ UPDATE entries
31
+ SET status = a.new_status::entry_status,
32
+ last_seen_at = ${lastParam},
33
+ promoted_at = CASE
34
+ WHEN a.was_pending AND a.new_status = 'active' THEN ${lastParam}
35
+ ELSE promoted_at
36
+ END
37
+ FROM actions a
38
+ WHERE entries.id = a.entry_id AND entries.is_root = 1
39
+ RETURNING entries.id, entries.status, a.was_pending, a.new_status`,
40
+ params,
41
+ )
42
+ let promoted = 0
43
+ let archived = 0
44
+ for (const r of (res.rows ?? [])) {
45
+ if (r.was_pending && r.new_status === 'active') promoted += 1
46
+ else if (r.new_status === 'archived') archived += 1
47
+ }
48
+ return { promoted, archived }
49
+ }
50
+
51
+ // Generic status update for archived/active terminal transitions.
52
+ export async function applySimpleStatus(db, entryId, nextStatus) {
53
+ const res = await db.query(
54
+ `UPDATE entries SET status = $1 WHERE id = $2 AND is_root = 1`,
55
+ [nextStatus, entryId],
56
+ )
57
+ return Number(res.rowCount ?? res.affectedRows ?? 0) > 0
58
+ }
59
+
60
+ export async function applyUpdate(db, entryId, element, summary, options = {}) {
61
+ const setClauses = []
62
+ const params = []
63
+ let paramIdx = 1
64
+ const newElement = (typeof element === 'string' && element.trim()) ? element.trim() : null
65
+ const newSummary = (typeof summary === 'string' && summary.trim()) ? summary.trim() : null
66
+ if (newElement) {
67
+ setClauses.push(`element = $${paramIdx++}`); params.push(newElement)
68
+ }
69
+ if (newSummary) {
70
+ setClauses.push(`summary = $${paramIdx++}`); params.push(newSummary)
71
+ setClauses.push('summary_hash = NULL')
72
+ }
73
+ if (setClauses.length === 0) return false
74
+ params.push(entryId)
75
+ const res = await db.query(
76
+ `UPDATE entries SET ${setClauses.join(', ')} WHERE id = $${paramIdx} AND is_root = 1`,
77
+ params,
78
+ )
79
+ if (Number(res.rowCount ?? res.affectedRows ?? 0) === 0) return false
80
+ await syncRootEmbedding(db, entryId, options)
81
+ return true
82
+ }
83
+
84
+ export async function applyMerge(db, targetId, sourceIds, options = {}) {
85
+ const signal = options?.signal
86
+ throwIfAborted(signal)
87
+ if (!Number.isFinite(targetId)) return 0
88
+ const targetRes = await db.query(
89
+ `SELECT id, project_id FROM entries WHERE id = $1 AND is_root = 1`,
90
+ [targetId],
91
+ )
92
+ throwIfAborted(signal)
93
+ const target = targetRes.rows[0]
94
+ if (!target) return 0
95
+ let moved = 0
96
+ for (const src of sourceIds) {
97
+ throwIfAborted(signal)
98
+ const sid = Number(src)
99
+ if (!Number.isFinite(sid) || sid === targetId) continue
100
+ const srcRes = await db.query(
101
+ `SELECT id, project_id, status FROM entries WHERE id = $1 AND is_root = 1`,
102
+ [sid],
103
+ )
104
+ throwIfAborted(signal)
105
+ const srcRow = srcRes.rows[0]
106
+ if (!srcRow) continue
107
+ if (target.project_id !== srcRow.project_id) {
108
+ __mixdogMemoryLog(
109
+ `[cycle2] merge rejected: cross-pool (target=${targetId} project_id=${target.project_id ?? 'COMMON'} src=${sid} project_id=${srcRow.project_id ?? 'COMMON'})\n`,
110
+ )
111
+ continue
112
+ }
113
+ try {
114
+ // One source merge is the mutation unit: DB reassignment/archive plus
115
+ // embedding cleanup. The next abort checkpoint is before the next source.
116
+ await db.transaction(async (tx) => {
117
+ await tx.query(
118
+ `UPDATE entries SET chunk_root = $1, project_id = $2 WHERE chunk_root = $3 AND id != $4 AND is_root = 0`,
119
+ [targetId, target.project_id, sid, sid],
120
+ )
121
+ await tx.query(
122
+ `UPDATE entries SET status = 'archived' WHERE id = $1 AND is_root = 1`,
123
+ [sid],
124
+ )
125
+ })
126
+ await deleteRootEmbedding(db, sid)
127
+ moved += 1
128
+ } catch (err) {
129
+ __mixdogMemoryLog(`[cycle2] merge failed (target=${targetId} src=${sid}): ${err.message}\n`)
130
+ }
131
+ }
132
+ return moved
133
+ }
134
+
135
+ // ─── phase_merge: cosine-similarity dedup pass ───────────────────────────────
136
+
137
+ function _pickKeeper(a, b) {
138
+ if ((a.score ?? 0) !== (b.score ?? 0)) return (a.score ?? 0) > (b.score ?? 0) ? a : b
139
+ if ((a.last_seen_at ?? 0) !== (b.last_seen_at ?? 0)) return (a.last_seen_at ?? 0) > (b.last_seen_at ?? 0) ? a : b
140
+ return a.id < b.id ? a : b
141
+ }
142
+
143
+ async function _llmJudgePair(summaryA, summaryB, siblingContext = [], options = {}) {
144
+ const signal = options?.signal
145
+ throwIfAborted(signal)
146
+ const llmCall = typeof options?.callLlm === 'function' ? options.callLlm : callAgentDispatch
147
+ const siblings = Array.isArray(siblingContext) && siblingContext.length > 0
148
+ ? `\n\nSibling near-matches (recall context only — do not absorb these into the verdict):\n${siblingContext.slice(0, 5).map((p, i) => `${i + 1}. ${String(p.a?.summary ?? '')} ↔ ${String(p.b?.summary ?? '')}`).join('\n')}`
149
+ : ''
150
+ const prompt =
151
+ `Two memory entries below. Are they restating the same principle? Reply ONE WORD: merge or distinct.\n\nA: ${summaryA}\nB: ${summaryB}${siblings}`
152
+ try {
153
+ const raw = await llmCall({
154
+ agent: 'cycle2-agent',
155
+ taskType: 'maintenance',
156
+ mode: 'cycle2-phase_merge_judge',
157
+ preset: 'HAIKU',
158
+ timeout: 30000,
159
+ cwd: null,
160
+ }, prompt)
161
+ throwIfAborted(signal)
162
+ return String(raw ?? '').trim().toLowerCase().startsWith('merge')
163
+ } catch (err) {
164
+ if (signal?.aborted) throw signal.reason ?? err
165
+ __mixdogMemoryLog(`[cycle2] phase_merge llm-judge error: ${err.message}\n`)
166
+ return false
167
+ }
168
+ }
169
+
170
+ export async function runPhaseMerge(db, options = {}) {
171
+ const signal = options?.signal
172
+ throwIfAborted(signal)
173
+ // PG-side lateral nearest-neighbor via HNSW index — replaces JS O(n²) double loop.
174
+ const pairRes = await db.query(
175
+ `WITH active AS (
176
+ SELECT id, category, summary, score, last_seen_at, status, embedding, project_id
177
+ FROM entries
178
+ WHERE is_root = 1 AND status = 'active' AND embedding IS NOT NULL
179
+ )
180
+ SELECT a.id AS a_id, a.category AS a_category, a.summary AS a_summary, a.score AS a_score, a.last_seen_at AS a_last_seen_at, a.status AS a_status,
181
+ b.id AS b_id, b.category AS b_category, b.summary AS b_summary, b.score AS b_score, b.last_seen_at AS b_last_seen_at, b.status AS b_status,
182
+ 1 - (a.embedding <=> b.embedding)::float8 AS sim
183
+ FROM active a
184
+ CROSS JOIN LATERAL (
185
+ SELECT id, category, summary, score, last_seen_at, status, embedding
186
+ FROM active inner_b
187
+ WHERE inner_b.id != a.id AND inner_b.category = a.category
188
+ AND inner_b.project_id IS NOT DISTINCT FROM a.project_id
189
+ ORDER BY inner_b.embedding <=> a.embedding
190
+ LIMIT 8
191
+ ) b
192
+ WHERE a.id < b.id
193
+ AND 1 - (a.embedding <=> b.embedding) >= $1
194
+ ORDER BY sim DESC`,
195
+ [TIER2_LOW],
196
+ )
197
+ throwIfAborted(signal)
198
+
199
+ const tier1Pairs = []
200
+ const tier2Pairs = []
201
+ for (const row of pairRes.rows) {
202
+ throwIfAborted(signal)
203
+ const a = { id: row.a_id, category: row.a_category, summary: row.a_summary, score: row.a_score, last_seen_at: row.a_last_seen_at, status: row.a_status }
204
+ const b = { id: row.b_id, category: row.b_category, summary: row.b_summary, score: row.b_score, last_seen_at: row.b_last_seen_at, status: row.b_status }
205
+ if (row.sim >= TIER1_THRESHOLD) tier1Pairs.push({ a, b, sim: row.sim })
206
+ else tier2Pairs.push({ a, b, sim: row.sim })
207
+ }
208
+
209
+ // No active/active similarity pairs is NOT a reason to skip the
210
+ // core_entries overlap sweep below — that pass archives active entries
211
+ // that restate a user-curated core row and is independent of intra-
212
+ // entry pairing. Falling through with merged=0 keeps the cross-table
213
+ // sweep running and the per-phase log shape intact.
214
+ let merged = 0
215
+ let llmCalls = 0
216
+ const mergedIds = new Set()
217
+
218
+ const doMerge = async (a, b, sim) => {
219
+ throwIfAborted(signal)
220
+ if (mergedIds.has(a.id) || mergedIds.has(b.id)) return
221
+ const keeper = _pickKeeper(a, b)
222
+ const loser = keeper.id === a.id ? b : a
223
+ const moved = await applyMerge(db, keeper.id, [loser.id], { signal })
224
+ if (moved > 0) {
225
+ merged += moved
226
+ mergedIds.add(loser.id)
227
+ __mixdogMemoryLog(
228
+ `[cycle2] phase_merge merged id=${loser.id} -> keeper=${keeper.id} category=${keeper.category} sim=${typeof sim === 'number' ? sim.toFixed(3) : '?'}\n`,
229
+ )
230
+ }
231
+ }
232
+
233
+ // Only tier1 pairs enter the LLM judge. Tier2 pairs (0.65 ≤ sim < 0.78)
234
+ // are recall context only — passed as sibling examples to the judge, never
235
+ // as judge input themselves, and never archived here.
236
+ for (const pair of tier1Pairs) {
237
+ throwIfAborted(signal)
238
+ if (llmCalls >= LLM_JUDGE_CAP) break
239
+ if (mergedIds.has(pair.a.id) || mergedIds.has(pair.b.id)) continue
240
+ llmCalls++
241
+ const shouldMerge = await _llmJudgePair(
242
+ String(pair.a.summary ?? ''),
243
+ String(pair.b.summary ?? ''),
244
+ tier2Pairs,
245
+ { signal },
246
+ )
247
+ throwIfAborted(signal)
248
+ if (shouldMerge) await doMerge(pair.a, pair.b, pair.sim)
249
+ }
250
+
251
+ // Cross-table sweep: surface every active entry whose embedding sits near
252
+ // a user-curated core_entries row (sim ≥ TIER2_LOW for broad recall) and
253
+ // ask the LLM whether the entry is a restatement of that user rule. Only
254
+ // the LLM verdict moves the entry to archived — embedding sim alone is
255
+ // never authoritative. Project-scoped core only matches the same pool;
256
+ // COMMON core is global and may absorb duplicate generated project memory.
257
+ throwIfAborted(signal)
258
+ const coreOverlapRes = await db.query(
259
+ `WITH active_e AS (
260
+ SELECT id, project_id, summary, embedding
261
+ FROM entries
262
+ WHERE is_root = 1 AND status = 'active' AND embedding IS NOT NULL
263
+ )
264
+ SELECT e.id AS entry_id, e.summary AS entry_summary, c.core_id, c.core_summary, c.sim
265
+ FROM active_e e
266
+ CROSS JOIN LATERAL (
267
+ SELECT inner_c.id AS core_id, inner_c.summary AS core_summary,
268
+ 1 - (e.embedding <=> inner_c.embedding)::float8 AS sim
269
+ FROM core_entries inner_c
270
+ WHERE inner_c.embedding IS NOT NULL
271
+ AND (inner_c.project_id IS NULL OR inner_c.project_id IS NOT DISTINCT FROM e.project_id)
272
+ ORDER BY
273
+ CASE WHEN inner_c.project_id IS NOT DISTINCT FROM e.project_id THEN 0 ELSE 1 END,
274
+ inner_c.embedding <=> e.embedding
275
+ LIMIT 1
276
+ ) c
277
+ WHERE c.sim >= $1`,
278
+ [TIER1_THRESHOLD],
279
+ )
280
+ throwIfAborted(signal)
281
+ let coreOverlap = 0
282
+ for (const row of coreOverlapRes.rows) {
283
+ throwIfAborted(signal)
284
+ if (llmCalls >= LLM_JUDGE_CAP) break
285
+ llmCalls++
286
+ const verdictMerge = await _llmJudgePair(
287
+ String(row.entry_summary ?? ''),
288
+ String(row.core_summary ?? ''),
289
+ [],
290
+ { signal },
291
+ )
292
+ throwIfAborted(signal)
293
+ if (!verdictMerge) continue
294
+ // Archiving one overlap and deleting its embedding is one mutation unit;
295
+ // cancellation resumes at the next row boundary.
296
+ const r = await db.query(
297
+ // Clear a live core-candidate flag on the same UPDATE: an archived root
298
+ // must not stay listed as a candidate or keep eating CANDIDATE_CAP. Set
299
+ // it to 'dismissed' (terminal) since the fact already restates a core row.
300
+ `UPDATE entries
301
+ SET status = 'archived',
302
+ core_candidate_status = CASE WHEN core_candidate_status = 'candidate' THEN 'dismissed' ELSE core_candidate_status END
303
+ WHERE id = $1 AND is_root = 1 AND status = 'active'`,
304
+ [Number(row.entry_id)],
305
+ )
306
+ if (Number(r.rowCount ?? r.affectedRows ?? 0) > 0) {
307
+ coreOverlap++
308
+ await deleteRootEmbedding(db, Number(row.entry_id))
309
+ }
310
+ }
311
+ throwIfAborted(signal)
312
+ if (coreOverlap > 0) {
313
+ __mixdogMemoryLog(
314
+ `[cycle2] phase_merge core_overlap archived=${coreOverlap} (LLM-judged restatements of user-curated core_entries)\n`,
315
+ )
316
+ }
317
+
318
+ __mixdogMemoryLog(
319
+ `[cycle2] phase_merge tier1_pairs=${tier1Pairs.length} tier2_pairs=${tier2Pairs.length}` +
320
+ ` llm_calls=${llmCalls} merged=${merged} core_overlap=${coreOverlap}\n`,
321
+ )
322
+
323
+ return { merged, llm_calls: llmCalls, tier1_pairs: tier1Pairs.length, tier2_pairs: tier2Pairs.length, core_overlap: coreOverlap }
324
+ }
@@ -0,0 +1,18 @@
1
+ // Shared low-level helpers for the cycle2 cluster (extracted from
2
+ // memory-cycle2.mjs). Logging shim, abort check, and resource-dir resolution.
3
+ // No cycle2 business logic; safe to import from any cycle2 sub-module.
4
+ import { fileURLToPath } from 'url'
5
+
6
+ const __mixdogMemoryStderrWrite = process.stderr.write.bind(process.stderr)
7
+ export function __mixdogMemoryLog(...args) {
8
+ if (process.env.MIXDOG_QUIET_MEMORY_LOG) return true
9
+ return __mixdogMemoryStderrWrite(...args)
10
+ }
11
+
12
+ export function throwIfAborted(signal) {
13
+ if (signal?.aborted) throw signal.reason ?? new Error('aborted')
14
+ }
15
+
16
+ export function resourceDir() {
17
+ return process.env.MIXDOG_ROOT || fileURLToPath(new URL('../../../..', import.meta.url))
18
+ }