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,105 @@
1
+ /**
2
+ * TranscriptItem.jsx — per-item transcript renderer (Item) + the hook-denial
3
+ * tool card. Extracted verbatim from App.jsx.
4
+ */
5
+ import React from 'react';
6
+ import { Box, Text } from 'ink';
7
+ import stringWidth from 'string-width';
8
+ import stripAnsi from 'strip-ansi';
9
+ import { theme, TURN_MARKER, RESULT_GUTTER } from '../theme.mjs';
10
+ import { AssistantMessage, UserMessage, NoticeMessage } from './Message.jsx';
11
+ import { ToolExecution } from './ToolExecution.jsx';
12
+ import { StatusDone, TurnDone } from './TurnDone.jsx';
13
+ import { ItemRightHintOverprint } from './ItemRightHintOverprint.jsx';
14
+ import { formatToolSurface } from '../../runtime/shared/tool-surface.mjs';
15
+ import {
16
+ formatHookDenialDetail,
17
+ isHookApprovalDenialToolItem,
18
+ shouldSuppressFullyFailedToolItem,
19
+ toolItemResultText,
20
+ } from '../transcript-tool-failures.mjs';
21
+
22
+ export function ToolHookDenialCard({ item, columns = 80 }) {
23
+ const { label, summary } = formatToolSurface(item.name, item.args);
24
+ const detail = formatHookDenialDetail(toolItemResultText(item));
25
+ const safeLabel = stripAnsi(String(label || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
26
+ const safeSummary = stripAnsi(String(summary || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
27
+ const safeDetail = stripAnsi(String(detail || '')).replace(/[\u0000-\u001F\u007F]/g, ' ').replace(/\s+/g, ' ').trim();
28
+ const summaryText = safeSummary ? ` (${safeSummary})` : '';
29
+ const rowWidth = Math.max(1, Number(columns || 80));
30
+ const detailWidth = Math.max(1, rowWidth - stringWidth(RESULT_GUTTER));
31
+ return (
32
+ <Box flexDirection="column" marginTop={1} width={rowWidth} overflow="hidden">
33
+ <Box flexDirection="row" width={rowWidth} overflow="hidden">
34
+ <Box flexShrink={0} minWidth={2}>
35
+ <Text color={theme.error}>{TURN_MARKER}</Text>
36
+ </Box>
37
+ <Box flexGrow={1} flexShrink={1} overflow="hidden" minWidth={0}>
38
+ <Text wrap="truncate">
39
+ <Text bold color={theme.text}>{safeLabel}</Text>
40
+ {summaryText ? <Text color={theme.text}>{summaryText}</Text> : null}
41
+ <Text color={theme.error}> · Denied</Text>
42
+ </Text>
43
+ </Box>
44
+ </Box>
45
+ {safeDetail ? (
46
+ <Box flexDirection="row" width={rowWidth} overflow="hidden">
47
+ <Box flexShrink={0} width={stringWidth(RESULT_GUTTER)}>
48
+ <Text color={theme.subtle}>{RESULT_GUTTER}</Text>
49
+ </Box>
50
+ <Box flexShrink={0} width={detailWidth} overflow="hidden">
51
+ <Text color={theme.error} wrap="truncate">{safeDetail}</Text>
52
+ </Box>
53
+ </Box>
54
+ ) : null}
55
+ </Box>
56
+ );
57
+ }
58
+
59
+ // `themeEpoch` is read but not used in the body: it is a memo-busting prop. The
60
+ // active theme mutates `theme` in-place, so a switch must force every mounted
61
+ // transcript row (which reads theme.* directly) to re-render. Threading the
62
+ // epoch through Item → AssistantMessage/UserMessage/ToolExecution breaks
63
+ // React.memo's shallow equality on a theme change without a broad refactor.
64
+ export const Item = React.memo(function Item({ item, prevKind, columns, toolOutputExpanded, rightMessage = '', rightTone = 'info', rightMessageWidth = 24, themeEpoch = 0 }) {
65
+ const hintOnTurnDoneRow = item.kind === 'turndone' || item.kind === 'statusdone';
66
+ let node = null;
67
+ switch (item.kind) {
68
+ case 'user':
69
+ node = <UserMessage text={item.text} attached={prevKind === 'user'} columns={columns} themeEpoch={themeEpoch} />;
70
+ break;
71
+ case 'assistant':
72
+ node = <AssistantMessage text={item.text} streaming={item.streaming} columns={columns} themeEpoch={themeEpoch} assistantId={item.id} />;
73
+ break;
74
+ case 'tool': {
75
+ if (shouldSuppressFullyFailedToolItem(item)) return null;
76
+ if (isHookApprovalDenialToolItem(item)) {
77
+ node = <ToolHookDenialCard item={item} columns={columns} />;
78
+ break;
79
+ }
80
+ node = <ToolExecution name={item.name} args={item.args} result={item.result} rawResult={item.rawResult} isError={item.isError} errorCount={item.errorCount} expanded={toolOutputExpanded || item.expanded} columns={columns} attached={false} count={item.count} completedCount={item.completedCount} startedAt={item.startedAt} completedAt={item.completedAt} aggregate={item.aggregate} categories={item.categories} headerFinalized={item.headerFinalized} deferredDisplayReady={item.deferredDisplayReady} themeEpoch={themeEpoch} />;
81
+ break;
82
+ }
83
+ case 'notice':
84
+ node = <NoticeMessage text={item.text} tone={item.tone} columns={columns} />;
85
+ break;
86
+ case 'turndone':
87
+ node = <TurnDone elapsedMs={item.elapsedMs} status={item.status} outputTokens={item.outputTokens} thinkingElapsedMs={item.thinkingElapsedMs} verb={item.verb} rightMessage={rightMessage} rightTone={rightTone} rightMessageWidth={rightMessageWidth} />;
88
+ break;
89
+ case 'statusdone':
90
+ node = <StatusDone label={item.label} detail={item.detail} rightMessage={rightMessage} rightTone={rightTone} rightMessageWidth={rightMessageWidth} />;
91
+ break;
92
+ default:
93
+ return null;
94
+ }
95
+ if (!node || hintOnTurnDoneRow || !rightMessage) return node;
96
+ return (
97
+ <ItemRightHintOverprint
98
+ rightMessage={rightMessage}
99
+ rightTone={rightTone}
100
+ rightMessageWidth={rightMessageWidth}
101
+ >
102
+ {node}
103
+ </ItemRightHintOverprint>
104
+ );
105
+ });
@@ -108,6 +108,12 @@ function windowValue(w) {
108
108
  const limitCredits = Number(w?.limitCredits);
109
109
  const usedPct = Number(w?.usedPct);
110
110
  const prefix = estimated ? 'est ' : '';
111
+ // Percent first: windows that carry usedPct (OAuth quotas, OpenCode Go
112
+ // console) all render as "5H 17%" so provider rows stay uniform; dollar
113
+ // remaining is the fallback for billing-style windows without a percent.
114
+ if (hasFiniteNumber(w?.usedPct)) {
115
+ return { text: `${prefix}${Math.round(usedPct)}%`, color: estimated ? theme.warning : pctColor(usedPct) };
116
+ }
111
117
  if (hasFiniteNumber(w?.remainingUsd)) {
112
118
  return { text: `${prefix}${money(remainingUsd)}`, color: estimated ? theme.warning : remainingUsdColor(remainingUsd) };
113
119
  }
@@ -123,9 +129,6 @@ function windowValue(w) {
123
129
  if (hasFiniteNumber(w?.usedCredits) && hasFiniteNumber(w?.limitCredits)) {
124
130
  return { text: `${prefix}${compactNumber(usedCredits)}/${compactNumber(limitCredits)}`, color: estimated ? theme.warning : creditsColor(w) };
125
131
  }
126
- if (hasFiniteNumber(w?.usedPct)) {
127
- return { text: `${prefix}${Math.round(usedPct)}%`, color: estimated ? theme.warning : pctColor(usedPct) };
128
- }
129
132
  return { text: '', color: theme.subtle };
130
133
  }
131
134
 
@@ -171,7 +174,15 @@ function rowStatusParts(row, columns = 80, statusWidth = 0) {
171
174
  const showCredit = hasCredit && (columns >= 80 || windows.length === 0);
172
175
  if (windows.length || showCredit) {
173
176
  const maxWindows = windows.length ? maxStatusWindows(columns, statusWidth, showCredit) : 0;
174
- const visibleWindows = windows.slice(0, maxWindows);
177
+ let visibleWindows = windows.slice(0, maxWindows);
178
+ if (windows.length > maxWindows && maxWindows > 0) {
179
+ // Don't let an actively-used window (e.g. monthly at 17%) get cut in
180
+ // favor of idle 0% windows; keep the top-usage windows in list order.
181
+ const ranked = [...windows]
182
+ .sort((a, b) => (Number(b?.usedPct) || 0) - (Number(a?.usedPct) || 0))
183
+ .slice(0, maxWindows);
184
+ visibleWindows = windows.filter((w) => ranked.includes(w));
185
+ }
175
186
  for (const window of visibleWindows) {
176
187
  pushStatusSeparator(parts);
177
188
  parts.push(...windowSegmentParts(window));
@@ -186,6 +197,9 @@ function rowStatusParts(row, columns = 80, statusWidth = 0) {
186
197
  case 'checking':
187
198
  return [{ text: 'checking...', color: theme.inactive }];
188
199
  case 'hidden':
200
+ // Provider balance can't be accurately refreshed (no/failed balance
201
+ // API): show an explicit "-" placeholder instead of a blank cell.
202
+ return [{ text: row?.primary || '-', color: theme.inactive }];
189
203
  case 'missing':
190
204
  case 'local':
191
205
  case 'error':
@@ -0,0 +1,72 @@
1
+ /**
2
+ * components/prompt-input/edit-helpers.mjs — pure prompt-editor helpers (no
3
+ * React): hint styling, insert/draft-compare, pasted-text normalization, and
4
+ * modified-Enter (kitty / modifyOtherKeys) sequence recognition. Extracted
5
+ * verbatim from PromptInput.jsx — behavior unchanged.
6
+ */
7
+ import { theme } from '../../theme.mjs';
8
+ import { replaceSelection } from '../../input-editing.mjs';
9
+
10
+ export function hintStyle(tone) {
11
+ if (tone === 'error') return { textColor: theme.error };
12
+ if (tone === 'warn' || tone === 'cancel') return { textColor: theme.warning };
13
+ if (tone === 'plain') return { textColor: theme.subtle };
14
+ return { textColor: theme.inactive };
15
+ }
16
+
17
+ export function insertText(draft, input) {
18
+ if (!input) return draft;
19
+ return replaceSelection(draft, input);
20
+ }
21
+
22
+ export function normalizePastedText(text) {
23
+ return String(text ?? '').replace(/\r\n?/g, '\n');
24
+ }
25
+
26
+ export function singleTrailingLineBreakPrefix(text) {
27
+ const normalized = normalizePastedText(text);
28
+ if (!normalized.endsWith('\n')) return null;
29
+ const prefix = normalized.slice(0, -1);
30
+ return prefix.includes('\n') ? null : prefix;
31
+ }
32
+
33
+ export function draftStateEqual(a, b) {
34
+ return (
35
+ a.value === b.value
36
+ && a.cursor === b.cursor
37
+ && a.selectionAnchor === b.selectionAnchor
38
+ );
39
+ }
40
+
41
+ // Recognize a MODIFIED Enter delivered via the kitty keyboard protocol
42
+ // (\x1b[13;<mod>u) or modifyOtherKeys (\x1b[27;<mod>;13~). The xterm modifier
43
+ // param is (1 + bitmask) where the bitmask bits are shift=1, alt=2, ctrl=4. We
44
+ // treat Ctrl+Enter AND Shift+Enter (the two common "insert newline" chords) as a
45
+ // newline, so we match when the shift OR ctrl bit is set. Ctrl+J is handled
46
+ // separately as the protocol-independent fallback.
47
+ const MODIFIED_ENTER_SHIFT_OR_CTRL = 1 | 4;
48
+
49
+ export function isModifiedEnterSequence(input) {
50
+ const text = String(input ?? '');
51
+ const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
52
+ if (!body) return false;
53
+ const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
54
+ if (kitty) return ((Number(kitty[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0;
55
+ const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
56
+ return Boolean(modifyOtherKeys && (((Number(modifyOtherKeys[1]) - 1) & MODIFIED_ENTER_SHIFT_OR_CTRL) !== 0));
57
+ }
58
+
59
+ // Recognize ANY modified Enter (any modifier bitmask, e.g. Alt+Enter \x1b[13;3u
60
+ // / \x1b[27;3;13~). Used to CONSUME modified-Enter sequences we don't map to a
61
+ // newline (Alt-only, etc.) so they aren't typed into the prompt as raw CSI text
62
+ // under modifyOtherKeys. Plain Enter (mod param = 1, bitmask 0) is intentionally
63
+ // NOT matched, so it still submits.
64
+ export function isAnyModifiedEnterSequence(input) {
65
+ const text = String(input ?? '');
66
+ const body = text.startsWith('\x1b[') ? text.slice(2) : text.startsWith('[') ? text.slice(1) : '';
67
+ if (!body) return false;
68
+ const kitty = /^13;(\d+)(?::\d+)?(?:;[\d:]+)?u$/.exec(body);
69
+ if (kitty) return (Number(kitty[1]) - 1) !== 0;
70
+ const modifyOtherKeys = /^27;(\d+);13~$/.exec(body);
71
+ return Boolean(modifyOtherKeys && ((Number(modifyOtherKeys[1]) - 1) !== 0));
72
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * components/prompt-input/voice-indicator.mjs — voice-indicator glyph frames,
3
+ * timing constants, and frame-selection helper for the prompt box right edge.
4
+ * Pure (no React). Extracted verbatim from PromptInput.jsx — behavior unchanged.
5
+ */
6
+
7
+ // Monotone voice indicator glyphs — right end of the prompt box. All frames
8
+ // are 1-cell-wide (no emoji, no string-width special-casing needed). Modes:
9
+ // 'off' — voice disabled and no install in flight: renders nothing,
10
+ // zero reserved columns.
11
+ // 'installing' — voice-runtime download in progress (progressHint active):
12
+ // braille spinner only.
13
+ // 'idle' — voice enabled, recorder idle: a STATIC ○ glyph. No
14
+ // animation — an animated idle reads as "something is
15
+ // running" when nothing is, and the old pulse frames
16
+ // (◎ ◍ ◉ ◍) rendered as tofu/odd-width glyphs in common
17
+ // Windows Terminal fonts (◍ U+25CD especially).
18
+ // 'recording' — steady ● + a braille spinner riding next to it (2 cells).
19
+ // 'transcribing' — braille spinner only (recording just stopped, awaiting
20
+ // the whisper-server round-trip).
21
+ // A single ~120ms interval drives the braille cycle, and it only exists
22
+ // while an ANIMATED mode is active (installing/recording/transcribing) —
23
+ // 'idle' and 'off' need no timer at all.
24
+ export const VOICE_BRAILLE_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧'];
25
+ export const VOICE_IDLE_GLYPH = '○';
26
+ export const VOICE_TICK_MS = 120;
27
+
28
+ // Resolve the indicator glyph text for a given mode + animation tick. Returns
29
+ // '' (rendered as null / zero reserved columns) when the indicator is hidden.
30
+ export function voiceIndicatorTextFor(mode, tick) {
31
+ const voiceBrailleFrame = VOICE_BRAILLE_FRAMES[tick % VOICE_BRAILLE_FRAMES.length];
32
+ return mode === 'installing' || mode === 'transcribing'
33
+ ? voiceBrailleFrame
34
+ : mode === 'recording'
35
+ ? `●${voiceBrailleFrame}`
36
+ : mode === 'idle'
37
+ ? VOICE_IDLE_GLYPH
38
+ : '';
39
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * components/tool-execution/ResultBody.jsx — the multi-line result body under
3
+ * the ⎿ gutter (COLLAPSED fitted summary or EXPANDED raw). Extracted verbatim
4
+ * from ToolExecution.jsx — behavior unchanged.
5
+ */
6
+ import React from 'react';
7
+ import { Box, Text } from 'ink';
8
+ import { theme, RESULT_GUTTER, RESULT_GUTTER_CONT } from '../../theme.mjs';
9
+ import { formatExpandedResult, wrapExpandedResultLines } from '../tool-output-format.mjs';
10
+ import { deltaTextParts, fitResultLine } from './text-format.mjs';
11
+
12
+ export function renderDeltaText(text) {
13
+ return deltaTextParts(text).map((part, index) => (
14
+ part.color ? <Text key={index} color={part.color}>{part.text}</Text> : part.text
15
+ ));
16
+ }
17
+
18
+ // Shared multi-line result body: `└` on the first row, `│` continuation rail on
19
+ // every following row, body text in one flex column so wrapping stays aligned
20
+ // under the head gutter.
21
+ //
22
+ // Two render paths:
23
+ // - COLLAPSED (raw=false): a single fitted summary line, diff(+/-) colored via
24
+ // renderDeltaText.
25
+ // - EXPANDED (raw=true): formatExpandedResult then wrapExpandedResultLines so
26
+ // each physical row fits the body width before render (rail rows stay 1:1;
27
+ // ink does not re-wrap). Physical row mount cap: MIXDOG_TUI_TOOL_OUTPUT_MAX_RENDER_LINES
28
+ // (default 600; 0 disables). Shell/script bodies keep the newest tail when capped.
29
+ export function ResultBody({ lines, rawText, pathArg = '', isShell = false, columns, color, raw }) {
30
+ const renderLines = raw
31
+ ? wrapExpandedResultLines(
32
+ formatExpandedResult(rawText, { pathArg, isShell }),
33
+ columns,
34
+ { isShell },
35
+ )
36
+ : (lines || []);
37
+ if (!renderLines || renderLines.length === 0) return null;
38
+ return (
39
+ <Box flexDirection="row">
40
+ <Box flexShrink={0} flexDirection="column">
41
+ {renderLines.map((_, i) => (
42
+ <Text key={i} color={theme.subtle}>{i === 0 ? RESULT_GUTTER : RESULT_GUTTER_CONT}</Text>
43
+ ))}
44
+ </Box>
45
+ <Box flexDirection="column" flexShrink={1} flexGrow={1}>
46
+ {renderLines.map((line, i) => (
47
+ <Text key={i} color={raw ? undefined : color} wrap="truncate">
48
+ {raw
49
+ ? (line || ' ')
50
+ : renderDeltaText(fitResultLine(line || ' ', columns))}
51
+ </Text>
52
+ ))}
53
+ </Box>
54
+ </Box>
55
+ );
56
+ }