mixdog 0.9.2 → 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 (417) hide show
  1. package/package.json +8 -3
  2. package/scripts/anthropic-maxtokens-test.mjs +119 -0
  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/review-tasks.json +20 -0
  7. package/scripts/bench/round-codex.json +114 -0
  8. package/scripts/bench/round-mixdog-lead-r3.json +269 -0
  9. package/scripts/bench/round-mixdog-lead.json +269 -0
  10. package/scripts/bench/round-mixdog.json +126 -0
  11. package/scripts/bench/round-r10-bigsample.json +679 -0
  12. package/scripts/bench/round-r11-codexalign.json +257 -0
  13. package/scripts/bench/round-r4-codex.json +114 -0
  14. package/scripts/bench/round-r4-mixed.json +225 -0
  15. package/scripts/bench/round-r5-gpt-lead.json +259 -0
  16. package/scripts/bench/round-r6-codex.json +114 -0
  17. package/scripts/bench/round-r6-solo.json +257 -0
  18. package/scripts/bench/round-r7-full.json +254 -0
  19. package/scripts/bench/round-r8-fulldefault.json +255 -0
  20. package/scripts/bench-run.mjs +215 -29
  21. package/scripts/build-tui.mjs +13 -1
  22. package/scripts/explore-bench.mjs +124 -0
  23. package/scripts/freevar-smoke.mjs +95 -0
  24. package/scripts/hook-bus-test.mjs +191 -0
  25. package/scripts/internal-comms-bench.mjs +1 -0
  26. package/scripts/internal-comms-smoke.mjs +10 -9
  27. package/scripts/mouse-probe.mjs +45 -0
  28. package/scripts/output-style-bench.mjs +13 -6
  29. package/scripts/output-style-smoke.mjs +4 -4
  30. package/scripts/path-suffix-test.mjs +57 -0
  31. package/scripts/provider-toolcall-test.mjs +7 -3
  32. package/scripts/recall-bench.mjs +207 -0
  33. package/scripts/recall-usecase-cases.json +18 -0
  34. package/scripts/recall-usecase-probe.json +6 -0
  35. package/scripts/session-bench.mjs +152 -6
  36. package/scripts/tool-smoke.mjs +30 -67
  37. package/scripts/tui-render-smoke.mjs +90 -0
  38. package/scripts/webhook-smoke.mjs +208 -0
  39. package/src/agents/debugger/AGENT.md +5 -2
  40. package/src/agents/heavy-worker/AGENT.md +21 -11
  41. package/src/agents/maintainer/AGENT.md +4 -0
  42. package/src/agents/reviewer/AGENT.md +3 -2
  43. package/src/agents/worker/AGENT.md +21 -11
  44. package/src/lib/rules-builder.cjs +4 -0
  45. package/src/mixdog-session-runtime.mjs +933 -3731
  46. package/src/output-styles/default.md +34 -9
  47. package/src/output-styles/{oneline.md → extreme-minimal.md} +5 -4
  48. package/src/output-styles/minimal.md +4 -1
  49. package/src/output-styles/simple.md +22 -7
  50. package/src/repl.mjs +5 -5
  51. package/src/rules/agent/00-common.md +2 -0
  52. package/src/rules/agent/30-explorer.md +8 -11
  53. package/src/rules/lead/lead-brief.md +12 -0
  54. package/src/rules/lead/lead-tool.md +2 -9
  55. package/src/rules/shared/01-tool.md +11 -5
  56. package/src/runtime/agent/orchestrator/agent-runtime/agent-loop-policy.mjs +25 -0
  57. package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +100 -23
  58. package/src/runtime/agent/orchestrator/agent-runtime/session-builder.mjs +6 -15
  59. package/src/runtime/agent/orchestrator/agent-trace-format.mjs +362 -0
  60. package/src/runtime/agent/orchestrator/agent-trace-io.mjs +410 -0
  61. package/src/runtime/agent/orchestrator/agent-trace.mjs +16 -735
  62. package/src/runtime/agent/orchestrator/config.mjs +69 -2
  63. package/src/runtime/agent/orchestrator/context/collect.mjs +51 -0
  64. package/src/runtime/agent/orchestrator/mcp/client.mjs +6 -2
  65. package/src/runtime/agent/orchestrator/providers/anthropic-effort.mjs +63 -21
  66. package/src/runtime/agent/orchestrator/providers/anthropic-max-tokens.mjs +93 -0
  67. package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +209 -0
  68. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +489 -0
  69. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +97 -1343
  70. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +607 -0
  71. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +78 -10
  72. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +1 -13
  73. package/src/runtime/agent/orchestrator/providers/codex-client-meta.mjs +81 -0
  74. package/src/runtime/agent/orchestrator/providers/gemini-cache.mjs +248 -0
  75. package/src/runtime/agent/orchestrator/providers/gemini-schema.mjs +303 -0
  76. package/src/runtime/agent/orchestrator/providers/gemini-stream.mjs +505 -0
  77. package/src/runtime/agent/orchestrator/providers/gemini.mjs +44 -1014
  78. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +18 -4
  79. package/src/runtime/agent/orchestrator/providers/lib/usage-primitives.mjs +32 -0
  80. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +86 -11
  81. package/src/runtime/agent/orchestrator/providers/model-list-sanitize.mjs +348 -0
  82. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +54 -20
  83. package/src/runtime/agent/orchestrator/providers/openai-codex-model.mjs +108 -0
  84. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +19 -12
  85. package/src/runtime/agent/orchestrator/providers/openai-compat-trace.mjs +58 -0
  86. package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +368 -0
  87. package/src/runtime/agent/orchestrator/providers/openai-compat-xai.mjs +760 -0
  88. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +41 -1142
  89. package/src/runtime/agent/orchestrator/providers/openai-oauth-http-sse.mjs +732 -0
  90. package/src/runtime/agent/orchestrator/providers/openai-oauth-login.mjs +193 -0
  91. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +303 -2119
  92. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +140 -995
  93. package/src/runtime/agent/orchestrator/providers/openai-ws-delta.mjs +227 -0
  94. package/src/runtime/agent/orchestrator/providers/openai-ws-events.mjs +67 -0
  95. package/src/runtime/agent/orchestrator/providers/openai-ws-pool.mjs +436 -0
  96. package/src/runtime/agent/orchestrator/providers/openai-ws-stream.mjs +1105 -0
  97. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +2 -1
  98. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +38 -12
  99. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +7 -8
  100. package/src/runtime/agent/orchestrator/session/compact/budget.mjs +288 -0
  101. package/src/runtime/agent/orchestrator/session/compact/constants.mjs +85 -0
  102. package/src/runtime/agent/orchestrator/session/compact/engine.mjs +749 -0
  103. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +82 -0
  104. package/src/runtime/agent/orchestrator/session/compact/summary-schema.mjs +315 -0
  105. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +643 -0
  106. package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +326 -0
  107. package/src/runtime/agent/orchestrator/session/compact.mjs +40 -2282
  108. package/src/runtime/agent/orchestrator/session/loop/compact-debug.mjs +28 -0
  109. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +274 -0
  110. package/src/runtime/agent/orchestrator/session/loop/completion-guards.mjs +61 -0
  111. package/src/runtime/agent/orchestrator/session/loop/context-overflow.mjs +38 -0
  112. package/src/runtime/agent/orchestrator/session/loop/env.mjs +14 -0
  113. package/src/runtime/agent/orchestrator/session/loop/hidden-agents.mjs +21 -0
  114. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +47 -0
  115. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +182 -0
  116. package/src/runtime/agent/orchestrator/session/loop/steering-ladder.mjs +173 -0
  117. package/src/runtime/agent/orchestrator/session/loop/steering.mjs +63 -0
  118. package/src/runtime/agent/orchestrator/session/loop/stored-tool-args.mjs +100 -0
  119. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +58 -0
  120. package/src/runtime/agent/orchestrator/session/loop/tool-classify.mjs +52 -0
  121. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +239 -0
  122. package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +218 -0
  123. package/src/runtime/agent/orchestrator/session/loop/transcript-repair.mjs +101 -0
  124. package/src/runtime/agent/orchestrator/session/loop/usage.mjs +35 -0
  125. package/src/runtime/agent/orchestrator/session/loop.mjs +409 -1304
  126. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +471 -0
  127. package/src/runtime/agent/orchestrator/session/manager/context-meta.mjs +230 -0
  128. package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +235 -0
  129. package/src/runtime/agent/orchestrator/session/manager/prompt-utils.mjs +149 -0
  130. package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +155 -0
  131. package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +406 -0
  132. package/src/runtime/agent/orchestrator/session/manager/status-telemetry.mjs +80 -0
  133. package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +303 -0
  134. package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +210 -0
  135. package/src/runtime/agent/orchestrator/session/manager.mjs +226 -2114
  136. package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +189 -0
  137. package/src/runtime/agent/orchestrator/session/store.mjs +74 -179
  138. package/src/runtime/agent/orchestrator/stall-policy.mjs +3 -3
  139. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +70 -20
  140. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +22 -2
  141. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +33 -42
  142. package/src/runtime/agent/orchestrator/tools/builtin/external-tool-adapters.mjs +241 -0
  143. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +1 -1
  144. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +40 -0
  145. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +42 -2
  146. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +1 -1
  147. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +11 -4
  148. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +29 -0
  149. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +8 -0
  150. package/src/runtime/agent/orchestrator/tools/builtin/search-path-diagnostics.mjs +126 -0
  151. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +81 -87
  152. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-paths.mjs +161 -0
  153. package/src/runtime/agent/orchestrator/tools/builtin/shell-job-process.mjs +108 -0
  154. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +78 -304
  155. package/src/runtime/agent/orchestrator/tools/builtin.mjs +11 -6
  156. package/src/runtime/agent/orchestrator/tools/code-graph/build.mjs +303 -0
  157. package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +43 -0
  158. package/src/runtime/agent/orchestrator/tools/code-graph/disk-cache.mjs +382 -0
  159. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.mjs +551 -0
  160. package/src/runtime/agent/orchestrator/tools/code-graph/graph-binary.mjs +295 -0
  161. package/src/runtime/agent/orchestrator/tools/code-graph/graph-model.mjs +158 -0
  162. package/src/runtime/agent/orchestrator/tools/code-graph/keyword-match.mjs +82 -0
  163. package/src/runtime/agent/orchestrator/tools/code-graph/lang-predicates.mjs +128 -0
  164. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.mjs +66 -0
  165. package/src/runtime/agent/orchestrator/tools/code-graph/project-root.mjs +44 -0
  166. package/src/runtime/agent/orchestrator/tools/code-graph/search.mjs +1080 -0
  167. package/src/runtime/agent/orchestrator/tools/code-graph/source-access.mjs +81 -0
  168. package/src/runtime/agent/orchestrator/tools/code-graph/span.mjs +19 -0
  169. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-index.mjs +280 -0
  170. package/src/runtime/agent/orchestrator/tools/code-graph/text-columns.mjs +45 -0
  171. package/src/runtime/agent/orchestrator/tools/code-graph/text-mask.mjs +347 -0
  172. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +6 -6
  173. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +36 -4277
  174. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +6 -3
  175. package/src/runtime/agent/orchestrator/tools/patch/constants.mjs +9 -0
  176. package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +171 -0
  177. package/src/runtime/agent/orchestrator/tools/patch/matcher.mjs +471 -0
  178. package/src/runtime/agent/orchestrator/tools/patch/native-server.mjs +436 -0
  179. package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +342 -0
  180. package/src/runtime/agent/orchestrator/tools/patch/parsing.mjs +359 -0
  181. package/src/runtime/agent/orchestrator/tools/patch/paths.mjs +340 -0
  182. package/src/runtime/agent/orchestrator/tools/patch/v4a-convert.mjs +643 -0
  183. package/src/runtime/agent/orchestrator/tools/patch.mjs +36 -2959
  184. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +1 -23
  185. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +10 -74
  186. package/src/runtime/agent/orchestrator/tools/shell-powershell.mjs +77 -0
  187. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +2 -4
  188. package/src/runtime/agent/orchestrator/tools/shell-state.mjs +154 -0
  189. package/src/runtime/channels/backends/discord-access.mjs +32 -0
  190. package/src/runtime/channels/backends/discord-attachments.mjs +65 -0
  191. package/src/runtime/channels/backends/discord-gateway.mjs +233 -0
  192. package/src/runtime/channels/backends/discord.mjs +12 -292
  193. package/src/runtime/channels/index.mjs +241 -894
  194. package/src/runtime/channels/lib/backend-dispatch.mjs +44 -0
  195. package/src/runtime/channels/lib/boot-profile.mjs +23 -0
  196. package/src/runtime/channels/lib/crash-log.mjs +106 -0
  197. package/src/runtime/channels/lib/event-pipeline.mjs +18 -1
  198. package/src/runtime/channels/lib/event-queue.mjs +63 -4
  199. package/src/runtime/channels/lib/inbound-routing.mjs +111 -0
  200. package/src/runtime/channels/lib/index-drop-trace.mjs +72 -0
  201. package/src/runtime/channels/lib/output-forwarder.mjs +9 -1
  202. package/src/runtime/channels/lib/owner-heartbeat.mjs +75 -0
  203. package/src/runtime/channels/lib/parent-bridge.mjs +88 -0
  204. package/src/runtime/channels/lib/runtime-paths.mjs +14 -4
  205. package/src/runtime/channels/lib/session-discovery.mjs +56 -4
  206. package/src/runtime/channels/lib/telegram-format.mjs +19 -22
  207. package/src/runtime/channels/lib/tool-dispatch.mjs +158 -0
  208. package/src/runtime/channels/lib/tool-format.mjs +1 -1
  209. package/src/runtime/channels/lib/transcript-discovery.mjs +4 -4
  210. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +6 -3
  211. package/src/runtime/channels/lib/voice-transcription.mjs +179 -0
  212. package/src/runtime/channels/lib/webhook/deliveries.mjs +312 -0
  213. package/src/runtime/channels/lib/webhook/log.mjs +42 -0
  214. package/src/runtime/channels/lib/webhook/ngrok.mjs +181 -0
  215. package/src/runtime/channels/lib/webhook/signature.mjs +60 -0
  216. package/src/runtime/channels/lib/webhook.mjs +36 -570
  217. package/src/runtime/channels/lib/whisper-language.mjs +42 -0
  218. package/src/runtime/channels/tool-defs.mjs +11 -130
  219. package/src/runtime/memory/index.mjs +258 -2050
  220. package/src/runtime/memory/lib/core-memory-store.mjs +351 -1
  221. package/src/runtime/memory/lib/cycle-llm-adapters.mjs +58 -0
  222. package/src/runtime/memory/lib/cycle-scheduler.mjs +497 -0
  223. package/src/runtime/memory/lib/cycle-signatures.mjs +34 -0
  224. package/src/runtime/memory/lib/embedding-warmup.mjs +58 -0
  225. package/src/runtime/memory/lib/http-wire.mjs +57 -0
  226. package/src/runtime/memory/lib/memory-config-flags.mjs +91 -0
  227. package/src/runtime/memory/lib/memory-cycle.mjs +1 -1
  228. package/src/runtime/memory/lib/memory-cycle2-gate.mjs +515 -0
  229. package/src/runtime/memory/lib/memory-cycle2-mutations.mjs +324 -0
  230. package/src/runtime/memory/lib/memory-cycle2-shared.mjs +18 -0
  231. package/src/runtime/memory/lib/memory-cycle2.mjs +72 -837
  232. package/src/runtime/memory/lib/memory-embed.mjs +149 -0
  233. package/src/runtime/memory/lib/memory-process-lock.mjs +162 -0
  234. package/src/runtime/memory/lib/memory-recall-scope-filter.mjs +24 -0
  235. package/src/runtime/memory/lib/memory-recall-store.mjs +22 -2
  236. package/src/runtime/memory/lib/memory-retrievers.mjs +8 -0
  237. package/src/runtime/memory/lib/memory.mjs +20 -0
  238. package/src/runtime/memory/lib/pg/supervisor.mjs +1 -1
  239. package/src/runtime/memory/lib/promotion-fingerprint.mjs +50 -0
  240. package/src/runtime/memory/lib/query-handlers.mjs +780 -0
  241. package/src/runtime/memory/lib/recall-format.mjs +238 -0
  242. package/src/runtime/memory/lib/runtime-fetcher.mjs +8 -3
  243. package/src/runtime/memory/lib/transcript-ingest.mjs +425 -0
  244. package/src/runtime/memory/tool-defs.mjs +6 -14
  245. package/src/runtime/search/lib/http-fetch.mjs +274 -0
  246. package/src/runtime/search/lib/ssrf-guard.mjs +333 -0
  247. package/src/runtime/search/lib/web-tools.mjs +24 -602
  248. package/src/runtime/shared/abort-controller.mjs +1 -1
  249. package/src/runtime/shared/atomic-file.mjs +26 -1
  250. package/src/runtime/shared/background-tasks.mjs +2 -3
  251. package/src/runtime/shared/buffered-appender.mjs +149 -0
  252. package/src/runtime/shared/launcher-control.mjs +2 -2
  253. package/src/runtime/shared/task-notification-envelope.mjs +98 -0
  254. package/src/runtime/shared/tool-execution-contract.mjs +2 -2
  255. package/src/runtime/shared/tool-primitives.mjs +308 -0
  256. package/src/runtime/shared/tool-result-summary.mjs +515 -0
  257. package/src/runtime/shared/tool-surface.mjs +80 -898
  258. package/src/runtime/shared/transcript-writer.mjs +52 -2
  259. package/src/runtime/shared/update-checker.mjs +7 -4
  260. package/src/session-runtime/config-helpers.mjs +291 -0
  261. package/src/session-runtime/config-lifecycle.mjs +232 -0
  262. package/src/session-runtime/cwd-plugins.mjs +226 -0
  263. package/src/session-runtime/effort.mjs +128 -0
  264. package/src/session-runtime/fs-utils.mjs +10 -0
  265. package/src/session-runtime/mcp-glue.mjs +177 -0
  266. package/src/session-runtime/model-capabilities.mjs +130 -0
  267. package/src/session-runtime/model-recency.mjs +111 -0
  268. package/src/session-runtime/native-search.mjs +247 -0
  269. package/src/session-runtime/output-styles.mjs +126 -0
  270. package/src/session-runtime/plugin-mcp.mjs +114 -0
  271. package/src/session-runtime/prewarm.mjs +142 -0
  272. package/src/session-runtime/provider-models.mjs +278 -0
  273. package/src/session-runtime/provider-usage.mjs +120 -0
  274. package/src/session-runtime/quick-model-rows.mjs +170 -0
  275. package/src/session-runtime/quick-search-models.mjs +46 -0
  276. package/src/session-runtime/session-hooks.mjs +93 -0
  277. package/src/session-runtime/session-text.mjs +100 -0
  278. package/src/session-runtime/settings-api.mjs +319 -0
  279. package/src/session-runtime/statusline-route.mjs +35 -0
  280. package/src/session-runtime/tool-catalog.mjs +720 -0
  281. package/src/session-runtime/tool-defs.mjs +84 -0
  282. package/src/session-runtime/warmup-schedulers.mjs +201 -0
  283. package/src/session-runtime/workflow.mjs +358 -0
  284. package/src/standalone/agent-tool/helpers.mjs +237 -0
  285. package/src/standalone/agent-tool/notify.mjs +107 -0
  286. package/src/standalone/agent-tool/provider-init.mjs +143 -0
  287. package/src/standalone/agent-tool/render.mjs +152 -0
  288. package/src/standalone/agent-tool/tool-def.mjs +55 -0
  289. package/src/standalone/agent-tool.mjs +155 -677
  290. package/src/standalone/channel-worker.mjs +7 -9
  291. package/src/standalone/explore-tool.mjs +40 -12
  292. package/src/standalone/hook-bus/config.mjs +207 -0
  293. package/src/standalone/hook-bus/constants.mjs +90 -0
  294. package/src/standalone/hook-bus/handlers.mjs +481 -0
  295. package/src/standalone/hook-bus/payload.mjs +31 -0
  296. package/src/standalone/hook-bus/rules.mjs +77 -0
  297. package/src/standalone/hook-bus.mjs +110 -746
  298. package/src/standalone/memory-runtime-proxy.mjs +7 -0
  299. package/src/standalone/opencode-go-login.mjs +125 -0
  300. package/src/standalone/provider-admin.mjs +15 -19
  301. package/src/standalone/usage-dashboard.mjs +3 -1
  302. package/src/tui/App.jsx +1163 -7571
  303. package/src/tui/app/app-format.mjs +206 -0
  304. package/src/tui/app/channel-pickers.mjs +510 -0
  305. package/src/tui/app/clipboard.mjs +67 -0
  306. package/src/tui/app/core-memory-picker.mjs +210 -0
  307. package/src/tui/app/extension-pickers.mjs +506 -0
  308. package/src/tui/app/input-parsers.mjs +193 -0
  309. package/src/tui/app/maintenance-pickers.mjs +324 -0
  310. package/src/tui/app/model-options.mjs +330 -0
  311. package/src/tui/app/model-picker.mjs +365 -0
  312. package/src/tui/app/onboarding-steps.mjs +400 -0
  313. package/src/tui/app/project-picker.mjs +247 -0
  314. package/src/tui/app/provider-setup-picker.mjs +580 -0
  315. package/src/tui/app/resume-picker.mjs +55 -0
  316. package/src/tui/app/route-pickers.mjs +419 -0
  317. package/src/tui/app/settings-picker.mjs +490 -0
  318. package/src/tui/app/slash-commands.mjs +101 -0
  319. package/src/tui/app/slash-dispatch.mjs +427 -0
  320. package/src/tui/app/text-layout.mjs +46 -0
  321. package/src/tui/app/theme-effort-pickers.mjs +154 -0
  322. package/src/tui/app/transcript-window.mjs +671 -0
  323. package/src/tui/app/use-mouse-input.mjs +460 -0
  324. package/src/tui/app/use-prompt-handlers.mjs +310 -0
  325. package/src/tui/app/use-transcript-scroll.mjs +510 -0
  326. package/src/tui/app/use-transcript-window.mjs +589 -0
  327. package/src/tui/components/ConfirmBar.jsx +1 -1
  328. package/src/tui/components/Picker.jsx +32 -4
  329. package/src/tui/components/PromptInput.jsx +259 -80
  330. package/src/tui/components/SlashCommandPalette.jsx +8 -1
  331. package/src/tui/components/StatusLine.jsx +63 -12
  332. package/src/tui/components/TextEntryPanel.jsx +11 -0
  333. package/src/tui/components/ToolExecution.jsx +56 -588
  334. package/src/tui/components/TranscriptItem.jsx +105 -0
  335. package/src/tui/components/UsagePanel.jsx +18 -4
  336. package/src/tui/components/prompt-input/edit-helpers.mjs +72 -0
  337. package/src/tui/components/prompt-input/voice-indicator.mjs +39 -0
  338. package/src/tui/components/tool-execution/ResultBody.jsx +56 -0
  339. package/src/tui/components/tool-execution/surface-detail.mjs +405 -0
  340. package/src/tui/components/tool-execution/text-format.mjs +161 -0
  341. package/src/tui/components/tool-output-format.mjs +2 -2
  342. package/src/tui/display-width.mjs +20 -3
  343. package/src/tui/dist/index.mjs +18034 -17188
  344. package/src/tui/engine/agent-envelope.mjs +296 -0
  345. package/src/tui/engine/agent-job-feed.mjs +133 -0
  346. package/src/tui/engine/boot-profile.mjs +21 -0
  347. package/src/tui/engine/labels.mjs +67 -0
  348. package/src/tui/engine/notice-text.mjs +112 -0
  349. package/src/tui/engine/notification-plan.mjs +76 -0
  350. package/src/tui/engine/queue-helpers.mjs +161 -0
  351. package/src/tui/engine/render-timing.mjs +17 -0
  352. package/src/tui/engine/session-stats.mjs +46 -0
  353. package/src/tui/engine/tool-approval.mjs +94 -0
  354. package/src/tui/engine/tool-call-fields.mjs +23 -0
  355. package/src/tui/engine/tool-card-results.mjs +234 -0
  356. package/src/tui/engine/tool-result-status.mjs +135 -0
  357. package/src/tui/engine/tool-result-text.mjs +126 -0
  358. package/src/tui/engine.mjs +405 -1385
  359. package/src/tui/figures.mjs +5 -0
  360. package/src/tui/index.jsx +105 -0
  361. package/src/tui/input-editing.mjs +60 -10
  362. package/src/tui/keyboard-protocol.mjs +2 -2
  363. package/src/tui/lib/voice-recorder.mjs +35 -19
  364. package/src/tui/markdown/format-token.mjs +11 -9
  365. package/src/tui/paste-attachments.mjs +38 -0
  366. package/src/tui/statusline-ansi-bridge.mjs +11 -3
  367. package/src/tui/theme.mjs +6 -0
  368. package/src/tui/themes/base.mjs +2 -2
  369. package/src/tui/themes/kanagawa.mjs +4 -4
  370. package/src/tui/themes/teal.mjs +4 -5
  371. package/src/tui/themes/utils.mjs +1 -1
  372. package/src/ui/statusline-agents.mjs +213 -0
  373. package/src/ui/statusline-format.mjs +146 -0
  374. package/src/ui/statusline-segments.mjs +148 -0
  375. package/src/ui/statusline.mjs +77 -462
  376. package/src/ui/tool-card.mjs +0 -1
  377. package/src/vendor/statusline/bin/statusline-route.mjs +15 -2
  378. package/src/workflows/default/WORKFLOW.md +16 -9
  379. package/src/workflows/sequential/WORKFLOW.md +16 -11
  380. package/src/workflows/solo/WORKFLOW.md +5 -1
  381. package/vendor/ink/build/display-width.js +19 -3
  382. package/vendor/ink/build/ink.js +103 -6
  383. package/vendor/ink/build/log-update.js +17 -3
  384. package/vendor/ink/build/wrap-text.js +125 -0
  385. package/scripts/_test-folder-dialog.mjs +0 -30
  386. package/scripts/fix-brief-fn.mjs +0 -35
  387. package/scripts/fix-format-tool-surface.mjs +0 -24
  388. package/scripts/fix-tool-exec-visible.mjs +0 -42
  389. package/scripts/patch-agent-brief.mjs +0 -48
  390. package/scripts/patch-app.mjs +0 -21
  391. package/scripts/patch-app2.mjs +0 -18
  392. package/scripts/patch-dist-brief.mjs +0 -96
  393. package/scripts/patch-tool-exec.mjs +0 -70
  394. package/src/examples/schedules/SCHEDULE.example.md +0 -32
  395. package/src/examples/webhooks/WEBHOOK.example.md +0 -40
  396. package/src/runtime/agent/orchestrator/session/manager.reactive-persist.test.mjs +0 -107
  397. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.test.mjs +0 -143
  398. package/src/runtime/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -285
  399. package/src/runtime/agent/orchestrator/tools/builtin/open-config-tool.mjs +0 -26
  400. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -45
  401. package/src/runtime/shared/tool-execution-contract.test.mjs +0 -183
  402. package/src/standalone/agent-task-status.test.mjs +0 -76
  403. package/src/tui/components/tool-output-format.test.mjs +0 -399
  404. package/src/tui/display-width.test.mjs +0 -35
  405. package/src/tui/engine-runtime-notification.test.mjs +0 -115
  406. package/src/tui/engine-tool-result-text.test.mjs +0 -75
  407. package/src/tui/markdown/format-token.test.mjs +0 -354
  408. package/src/tui/markdown/render-ansi.test.mjs +0 -108
  409. package/src/tui/markdown/stream-fence.test.mjs +0 -26
  410. package/src/tui/markdown/streaming-markdown.test.mjs +0 -70
  411. package/src/tui/prompt-history-store.test.mjs +0 -52
  412. package/src/tui/statusline-ansi-bridge.test.mjs +0 -159
  413. package/src/tui/transcript-tool-failures.test.mjs +0 -111
  414. package/src/ui/markdown.test.mjs +0 -70
  415. package/src/ui/statusline-context-label.test.mjs +0 -15
  416. package/src/vendor/statusline/bin/statusline-lib.mjs +0 -186
  417. package/src/vendor/statusline/bin/statusline-route.test.mjs +0 -80
@@ -0,0 +1,359 @@
1
+ // V4A + unified-as-V4A patch parsers and format-detection helpers. Moved
2
+ // verbatim from patch.mjs; parsing behavior (V4A/unified) is unchanged.
3
+
4
+ import { stripDiffPrefix } from './paths.mjs';
5
+ import {
6
+ DEV_NULL,
7
+ V4A_EOF_MARKER,
8
+ V4A_MOVE_TO_PREFIX,
9
+ UNIFIED_HUNK_HEADER_RE,
10
+ UNIFIED_HUNK_HEADER_CAPTURE_RE,
11
+ } from './constants.mjs';
12
+
13
+ // Strip BOM + normalize CRLF→LF only. Idempotent and structural — no
14
+ // hunk metadata is rewritten.
15
+ export function prepareInput(patchStr) {
16
+ return String(patchStr).replace(/^\uFEFF/, '').replace(/\r\n/g, '\n');
17
+ }
18
+
19
+ export function isApplyPatchEnvelope(patchStr) {
20
+ const text = prepareInput(patchStr).trimStart();
21
+ return text.startsWith('*** Begin Patch')
22
+ || text.startsWith('*** Add File:')
23
+ || text.startsWith('*** Update File:')
24
+ || text.startsWith('*** Delete File:');
25
+ }
26
+
27
+ export function isV4APatchInput(patchStr, format) {
28
+ return String(format || '').toLowerCase() === 'v4a'
29
+ || isApplyPatchEnvelope(patchStr);
30
+ }
31
+
32
+ export function hasUnifiedBareV4AHunk(patchStr) {
33
+ const text = prepareInput(patchStr);
34
+ if (!/^--- /m.test(text) || !/^\+\+\+ /m.test(text)) return false;
35
+ return text.split('\n').some((line) => line.startsWith('@@') && !UNIFIED_HUNK_HEADER_RE.test(line));
36
+ }
37
+
38
+ export function isUnifiedHunkCountError(err) {
39
+ const message = String(err?.message || err || '');
40
+ return /Hunk at line .*more lines than expected|Hunk at line .*less lines than expected|expected \d+ old lines|line count did not match/i.test(message);
41
+ }
42
+
43
+ export function canFallbackCountedUnified(patchStr, requestedFormat, err) {
44
+ if (requestedFormat === 'unified') return false;
45
+ if (isV4APatchInput(patchStr, requestedFormat)) return false;
46
+ const text = prepareInput(patchStr);
47
+ return /^--- /m.test(text)
48
+ && /^\+\+\+ /m.test(text)
49
+ && UNIFIED_HUNK_HEADER_RE.test(text.split('\n').find((line) => line.startsWith('@@')) || '')
50
+ && isUnifiedHunkCountError(err);
51
+ }
52
+
53
+ function stripPatchPathMetadata(rawPath) {
54
+ let text = String(rawPath || '').trim();
55
+ if (!text) return '';
56
+ const tabIdx = text.indexOf('\t');
57
+ if (tabIdx !== -1) text = text.slice(0, tabIdx).trimEnd();
58
+ const quote = text[0];
59
+ if ((quote === '"' || quote === "'") && text.length > 1) {
60
+ const end = text.indexOf(quote, 1);
61
+ if (end > 0) text = text.slice(1, end);
62
+ }
63
+ return text;
64
+ }
65
+
66
+ function stripV4APathHeader(line, prefix) {
67
+ return stripPatchPathMetadata(String(line || '').slice(prefix.length));
68
+ }
69
+
70
+ export function normaliseV4APath(rawPath) {
71
+ const p = stripPatchPathMetadata(rawPath);
72
+ if (!p) return '';
73
+ return p.replace(/^["']|["']$/g, '').replace(/\\/g, '/');
74
+ }
75
+
76
+ function normaliseV4AAnchor(rawAnchor) {
77
+ return String(rawAnchor || '').replace(/\s*@@\s*$/, '').trim();
78
+ }
79
+
80
+ function stripV4AMovePathHeader(line) {
81
+ return normaliseV4APath(String(line || '').slice(V4A_MOVE_TO_PREFIX.length));
82
+ }
83
+
84
+ export function isV4AEndOfFileMarker(rawLine) {
85
+ return String(rawLine || '').trim() === V4A_EOF_MARKER;
86
+ }
87
+
88
+ function v4aEnsureUpdateHunk(current, pendingAnchors) {
89
+ return { anchors: pendingAnchors.slice(), lines: [] };
90
+ }
91
+
92
+ function v4aPushBlankContextLine(currentHunk, pendingAnchors) {
93
+ if (!currentHunk) currentHunk = v4aEnsureUpdateHunk(null, pendingAnchors);
94
+ currentHunk.lines.push(' ');
95
+ return currentHunk;
96
+ }
97
+
98
+ function v4aMarkHunkEndOfFile(currentHunk, finishHunk) {
99
+ if (!currentHunk || currentHunk.lines.length === 0) {
100
+ throw new Error('V4A update hunk does not contain any lines before *** End of File');
101
+ }
102
+ currentHunk.isEndOfFile = true;
103
+ finishHunk();
104
+ }
105
+
106
+ // Split a patch string into lines, dropping the single trailing empty element
107
+ // produced by the patch's terminal newline. Invariant: a well-formed patch
108
+ // ends with "\n", so `"...\n".split("\n")` always yields a spurious final ""
109
+ // that is a line *terminator*, not a content line. Absorbing it as a blank
110
+ // context line corrupts the last hunk (phantom trailing "" in oldLines) and
111
+ // breaks anchoring whenever the matched source region is not followed by a
112
+ // blank line. A genuine trailing blank context line survives as the
113
+ // second-to-last element, so only the terminator artifact is removed.
114
+ function splitPatchLines(patchStr) {
115
+ const lines = prepareInput(patchStr).split('\n');
116
+ if (lines.length > 0 && lines[lines.length - 1] === '') lines.pop();
117
+ return lines;
118
+ }
119
+
120
+ // Guard against the compacted-history placeholder text leaking back in as
121
+ // literal patch input (models sometimes paste tool-output summaries back as
122
+ // new tool args). Exported so callers (e.g. apply_patch entry) can check
123
+ // this before any format detection / V4A-vs-unified dispatch, so ANY
124
+ // compacted body gets the corrective message regardless of format.
125
+ export const COMPACTED_PLACEHOLDER_RE = /^\s*\[mixdog compacted \w+:/;
126
+
127
+ // Mid-body scan uses the FULL placeholder shape ("<N> chars, sha…") rather
128
+ // than the loose prefix above: V4A tolerates unprefixed context lines, so a
129
+ // loose prefix match on any non-diff line could false-positive a legit edit
130
+ // whose content mentions the placeholder text. The full shape only occurs in
131
+ // actual compacted output leaked back as patch input.
132
+ const COMPACTED_PLACEHOLDER_LINE_RE = /^\s*\[mixdog compacted \w+: \d+ chars, sha\d*:/;
133
+
134
+ export function isCompactedPlaceholderPatch(patchStr) {
135
+ const str = String(patchStr ?? '');
136
+ if (COMPACTED_PLACEHOLDER_RE.test(str)) return true;
137
+ // Whole-patch prefix check above only catches the placeholder as the very
138
+ // first line. Models sometimes paste the placeholder mid-body (e.g. after
139
+ // a "*** Begin Patch" header or between hunks) as a standalone raw line.
140
+ // Scan for that shape too, but only on lines that are NOT diff content
141
+ // (unified +/-/space-prefixed lines), so a legit edit to a file whose
142
+ // real content happens to contain this literal text still parses normally.
143
+ for (const line of str.split('\n')) {
144
+ if (line.startsWith('+') || line.startsWith('-') || line.startsWith(' ')) continue;
145
+ if (COMPACTED_PLACEHOLDER_LINE_RE.test(line)) return true;
146
+ }
147
+ return false;
148
+ }
149
+
150
+ export function parseV4APatch(patchStr) {
151
+ const lines = splitPatchLines(patchStr);
152
+ const files = [];
153
+ let current = null;
154
+ let pendingAnchors = [];
155
+ let currentHunk = null;
156
+
157
+ const finishHunk = () => {
158
+ if (!current || !currentHunk) return;
159
+ if (currentHunk.lines.length > 0) current.hunks.push(currentHunk);
160
+ currentHunk = null;
161
+ };
162
+ const finishFile = () => {
163
+ finishHunk();
164
+ current = null;
165
+ pendingAnchors = [];
166
+ };
167
+ const startFile = (kind, path) => {
168
+ finishFile();
169
+ current = { kind, path: normaliseV4APath(path), hunks: [], lines: [], movePath: null };
170
+ files.push(current);
171
+ };
172
+
173
+ for (const rawLine of lines) {
174
+ if (rawLine === '*** Begin Patch' || rawLine === '*** End Patch') continue;
175
+ if (rawLine.startsWith('*** Update File:')) {
176
+ startFile('update', stripV4APathHeader(rawLine, '*** Update File:'));
177
+ continue;
178
+ }
179
+ if (rawLine.startsWith('*** Add File:')) {
180
+ startFile('add', stripV4APathHeader(rawLine, '*** Add File:'));
181
+ continue;
182
+ }
183
+ if (rawLine.startsWith('*** Delete File:')) {
184
+ startFile('delete', stripV4APathHeader(rawLine, '*** Delete File:'));
185
+ continue;
186
+ }
187
+ if (!current) {
188
+ throw new Error(`V4A patch line appears before a file header: ${rawLine}`);
189
+ }
190
+ if (current.kind === 'update' && rawLine.startsWith(V4A_MOVE_TO_PREFIX)) {
191
+ if (current.movePath) {
192
+ throw new Error(`V4A patch lists multiple ${V4A_MOVE_TO_PREFIX} directives for ${current.path}`);
193
+ }
194
+ const dest = stripV4AMovePathHeader(rawLine);
195
+ if (!dest) throw new Error('V4A patch contains an empty move destination path');
196
+ current.movePath = dest;
197
+ continue;
198
+ }
199
+ if (current.kind === 'add') {
200
+ current.lines.push(rawLine.startsWith('+') ? rawLine.slice(1) : rawLine);
201
+ continue;
202
+ }
203
+ if (current.kind === 'delete') {
204
+ continue;
205
+ }
206
+ if (rawLine === '') {
207
+ if (currentHunk) currentHunk = v4aPushBlankContextLine(currentHunk, pendingAnchors);
208
+ continue;
209
+ }
210
+ if (isV4AEndOfFileMarker(rawLine)) {
211
+ v4aMarkHunkEndOfFile(currentHunk, finishHunk);
212
+ currentHunk = null;
213
+ continue;
214
+ }
215
+ if (rawLine.startsWith('@@')) {
216
+ const anchor = normaliseV4AAnchor(rawLine.slice(2));
217
+ if (currentHunk && currentHunk.lines.length > 0) finishHunk();
218
+ pendingAnchors.push(anchor);
219
+ currentHunk = { anchors: pendingAnchors.slice(), lines: [] };
220
+ pendingAnchors = [];
221
+ continue;
222
+ }
223
+ const tag = rawLine[0];
224
+ if (tag !== ' ' && tag !== '-' && tag !== '+') {
225
+ if (!currentHunk) currentHunk = v4aEnsureUpdateHunk(current, pendingAnchors);
226
+ pendingAnchors = [];
227
+ currentHunk.lines.push(` ${rawLine}`);
228
+ continue;
229
+ }
230
+ if (!currentHunk) currentHunk = v4aEnsureUpdateHunk(current, pendingAnchors);
231
+ currentHunk.lines.push(rawLine);
232
+ }
233
+ finishFile();
234
+ const bad = files.find((file) => !file.path);
235
+ if (bad) throw new Error('V4A patch contains an empty file path');
236
+ if (files.length === 0) throw new Error('V4A patch contained no file sections');
237
+ return files;
238
+ }
239
+
240
+ function stripUnifiedV4APathHeader(line, prefix) {
241
+ return stripDiffPrefix(normaliseV4APath(String(line || '').slice(prefix.length)));
242
+ }
243
+
244
+ // Shared parser for unified-input -> V4A sections. The bare and counted
245
+ // fallbacks are byte-identical except for (a) the error label and (b) how an
246
+ // `@@` line yields its anchor: bare rejects counted headers and takes the raw
247
+ // tail; counted requires a counted header and takes its capture group. The
248
+ // difference is injected as `resolveAnchor`; everything else is shared.
249
+ function parseUnifiedAsV4APatch(patchStr, { label, resolveAnchor }) {
250
+ const lines = splitPatchLines(patchStr);
251
+ const files = [];
252
+ let current = null;
253
+ let pendingAnchors = [];
254
+ let currentHunk = null;
255
+
256
+ const finishHunk = () => {
257
+ if (!current || !currentHunk) return;
258
+ if (current.kind === 'update' && currentHunk.lines.length > 0) current.hunks.push(currentHunk);
259
+ currentHunk = null;
260
+ };
261
+ const finishFile = () => {
262
+ finishHunk();
263
+ current = null;
264
+ pendingAnchors = [];
265
+ };
266
+ const startFile = (oldPath, newPath) => {
267
+ finishFile();
268
+ const oldIsNull = DEV_NULL.test(oldPath || '');
269
+ const newIsNull = DEV_NULL.test(newPath || '');
270
+ const kind = oldIsNull ? 'add' : (newIsNull ? 'delete' : 'update');
271
+ const path = kind === 'add' ? newPath : oldPath;
272
+ current = { kind, path: normaliseV4APath(path), hunks: [], lines: [] };
273
+ files.push(current);
274
+ };
275
+
276
+ for (let i = 0; i < lines.length; i++) {
277
+ const rawLine = lines[i];
278
+ if (rawLine.startsWith('diff --git ') || rawLine.startsWith('index ') || rawLine.startsWith('new file mode ') || rawLine.startsWith('deleted file mode ')) {
279
+ continue;
280
+ }
281
+ if (rawLine.startsWith('--- ')) {
282
+ const next = lines[i + 1] || '';
283
+ if (next.startsWith('+++ ')) {
284
+ startFile(stripUnifiedV4APathHeader(rawLine, '--- '), stripUnifiedV4APathHeader(next, '+++ '));
285
+ i++;
286
+ continue;
287
+ }
288
+ // A real unified file header `--- X` is ALWAYS immediately followed by a
289
+ // `+++ Y` line. Without the pair, outside a file this is a malformed
290
+ // patch (keep the diagnostic); INSIDE a file it is a hunk-body deletion
291
+ // line whose content starts with `-- ` (rawLine `--- foo`) — fall through
292
+ // to body handling instead of misreading it as a file header.
293
+ if (!current) throw new Error(`${label} missing +++ header after: ${rawLine}`);
294
+ }
295
+ if (!current) continue;
296
+ if (rawLine === '') {
297
+ if (current.kind !== 'update') continue;
298
+ if (currentHunk) currentHunk = v4aPushBlankContextLine(currentHunk, pendingAnchors);
299
+ continue;
300
+ }
301
+ if (current.kind === 'update' && isV4AEndOfFileMarker(rawLine)) {
302
+ v4aMarkHunkEndOfFile(currentHunk, finishHunk);
303
+ currentHunk = null;
304
+ continue;
305
+ }
306
+ if (rawLine.startsWith('@@')) {
307
+ const anchor = resolveAnchor(rawLine);
308
+ if (currentHunk && currentHunk.lines.length > 0) finishHunk();
309
+ pendingAnchors.push(anchor);
310
+ currentHunk = { anchors: pendingAnchors.slice(), lines: [] };
311
+ pendingAnchors = [];
312
+ continue;
313
+ }
314
+ if (current.kind === 'add') {
315
+ if (rawLine[0] === '+') current.lines.push(rawLine.slice(1));
316
+ continue;
317
+ }
318
+ if (current.kind === 'delete') {
319
+ continue;
320
+ }
321
+ const tag = rawLine[0];
322
+ if (tag !== ' ' && tag !== '-' && tag !== '+') {
323
+ if (!currentHunk) currentHunk = v4aEnsureUpdateHunk(current, pendingAnchors);
324
+ pendingAnchors = [];
325
+ currentHunk.lines.push(` ${rawLine}`);
326
+ continue;
327
+ }
328
+ if (!currentHunk) currentHunk = v4aEnsureUpdateHunk(current, pendingAnchors);
329
+ currentHunk.lines.push(rawLine);
330
+ }
331
+ finishFile();
332
+ const bad = files.find((file) => !file.path);
333
+ if (bad) throw new Error(`${label} contains an empty file path`);
334
+ if (files.length === 0) throw new Error(`${label} contained no file sections`);
335
+ return files;
336
+ }
337
+
338
+ export function parseUnifiedBareV4APatch(patchStr) {
339
+ return parseUnifiedAsV4APatch(patchStr, {
340
+ label: 'unified bare patch',
341
+ resolveAnchor: (rawLine) => {
342
+ if (UNIFIED_HUNK_HEADER_RE.test(rawLine)) {
343
+ throw new Error('unified bare patch cannot mix counted unified hunks with bare @@ anchors');
344
+ }
345
+ return normaliseV4AAnchor(rawLine.slice(2));
346
+ },
347
+ });
348
+ }
349
+
350
+ export function parseUnifiedCountedAsV4APatch(patchStr) {
351
+ return parseUnifiedAsV4APatch(patchStr, {
352
+ label: 'unified fallback',
353
+ resolveAnchor: (rawLine) => {
354
+ const match = UNIFIED_HUNK_HEADER_CAPTURE_RE.exec(rawLine);
355
+ if (!match) throw new Error(`unified fallback requires counted hunk header: ${rawLine}`);
356
+ return normaliseV4AAnchor(match[1] || '');
357
+ },
358
+ });
359
+ }