mixdog 0.7.18 → 0.8.0

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 (844) hide show
  1. package/README.md +37 -331
  2. package/package.json +67 -99
  3. package/scripts/boot-smoke.mjs +94 -0
  4. package/scripts/build-tui.mjs +52 -0
  5. package/scripts/compact-smoke.mjs +199 -0
  6. package/scripts/lead-workflow-smoke.mjs +598 -0
  7. package/scripts/live-worker-smoke.mjs +239 -0
  8. package/scripts/output-style-smoke.mjs +101 -0
  9. package/scripts/smoke-loop-report.mjs +221 -0
  10. package/scripts/smoke-loop.mjs +201 -0
  11. package/scripts/smoke.mjs +113 -0
  12. package/scripts/tool-failures.mjs +143 -0
  13. package/scripts/tool-smoke.mjs +456 -0
  14. package/src/agents/debugger/AGENT.md +3 -0
  15. package/src/agents/debugger/agent.json +6 -0
  16. package/src/agents/explore/AGENT.md +4 -0
  17. package/src/agents/explore/agent.json +6 -0
  18. package/src/agents/heavy-worker/AGENT.md +3 -0
  19. package/src/agents/heavy-worker/agent.json +6 -0
  20. package/src/agents/maintainer/AGENT.md +3 -0
  21. package/src/agents/maintainer/agent.json +6 -0
  22. package/src/agents/reviewer/AGENT.md +3 -0
  23. package/src/agents/reviewer/agent.json +6 -0
  24. package/src/agents/scheduler-task.md +3 -0
  25. package/src/agents/web-researcher/AGENT.md +3 -0
  26. package/src/agents/web-researcher/agent.json +6 -0
  27. package/src/agents/webhook-handler.md +3 -0
  28. package/src/agents/worker/AGENT.md +3 -0
  29. package/src/agents/worker/agent.json +6 -0
  30. package/src/app.mjs +90 -0
  31. package/src/cli.mjs +11 -0
  32. package/src/defaults/hidden-roles.json +72 -0
  33. package/src/defaults/mixdog-config.template.json +15 -0
  34. package/src/hooks/lib/permission-evaluator.cjs +488 -0
  35. package/src/hooks/lib/settings-loader.cjs +112 -0
  36. package/src/lib/keychain-cjs.cjs +332 -0
  37. package/src/lib/plugin-paths.cjs +28 -0
  38. package/src/lib/rules-builder.cjs +315 -0
  39. package/src/mixdog-session-runtime.mjs +3704 -0
  40. package/src/output-styles/default.md +38 -0
  41. package/src/output-styles/extreme-simple.md +17 -0
  42. package/src/output-styles/simple.md +17 -0
  43. package/src/repl.mjs +322 -0
  44. package/src/rules/bridge/00-common.md +5 -0
  45. package/src/rules/bridge/20-skip-protocol.md +11 -0
  46. package/src/rules/bridge/30-explorer.md +4 -0
  47. package/src/rules/bridge/40-cycle1-agent.md +28 -0
  48. package/src/rules/bridge/41-cycle2-agent.md +59 -0
  49. package/src/rules/lead/00-tool-lead.md +5 -0
  50. package/src/rules/lead/01-general.md +5 -0
  51. package/src/rules/lead/02-channels.md +3 -0
  52. package/src/rules/lead/04-workflow.md +12 -0
  53. package/src/rules/shared/00-language.md +3 -0
  54. package/src/rules/shared/01-tool.md +3 -0
  55. package/src/runtime/agent/orchestrator/bridge-trace.mjs +814 -0
  56. package/src/runtime/agent/orchestrator/cache-mtime.mjs +60 -0
  57. package/src/runtime/agent/orchestrator/config.mjs +446 -0
  58. package/src/runtime/agent/orchestrator/context/collect.mjs +796 -0
  59. package/src/runtime/agent/orchestrator/dispatch-persist.mjs +417 -0
  60. package/src/runtime/agent/orchestrator/internal-roles.mjs +188 -0
  61. package/src/runtime/agent/orchestrator/internal-tools.mjs +88 -0
  62. package/src/runtime/agent/orchestrator/mcp/client.mjs +345 -0
  63. package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +2104 -0
  64. package/src/runtime/agent/orchestrator/providers/anthropic.mjs +784 -0
  65. package/src/runtime/agent/orchestrator/providers/api-usage.mjs +341 -0
  66. package/src/runtime/agent/orchestrator/providers/gemini.mjs +1679 -0
  67. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +959 -0
  68. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +213 -0
  69. package/src/runtime/agent/orchestrator/providers/model-cache.mjs +38 -0
  70. package/src/runtime/agent/orchestrator/providers/model-catalog.mjs +471 -0
  71. package/src/runtime/agent/orchestrator/providers/oauth-usage.mjs +615 -0
  72. package/src/runtime/agent/orchestrator/providers/openai-compat-stream.mjs +808 -0
  73. package/src/runtime/agent/orchestrator/providers/openai-compat.mjs +1719 -0
  74. package/src/runtime/agent/orchestrator/providers/openai-oauth-ws.mjs +2587 -0
  75. package/src/runtime/agent/orchestrator/providers/openai-oauth.mjs +1953 -0
  76. package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +136 -0
  77. package/src/runtime/agent/orchestrator/providers/opencode-go-usage.mjs +317 -0
  78. package/src/runtime/agent/orchestrator/providers/opencode-go.mjs +109 -0
  79. package/src/runtime/agent/orchestrator/providers/registry.mjs +247 -0
  80. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +332 -0
  81. package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +11 -0
  82. package/src/runtime/agent/orchestrator/providers/trace-utils.mjs +50 -0
  83. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  84. package/src/runtime/agent/orchestrator/session/cache/read-cache.mjs +318 -0
  85. package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +367 -0
  86. package/src/runtime/agent/orchestrator/session/compact.mjs +882 -0
  87. package/src/runtime/agent/orchestrator/session/context-utils.mjs +233 -0
  88. package/src/runtime/agent/orchestrator/session/loop.mjs +2320 -0
  89. package/src/runtime/agent/orchestrator/session/manager.mjs +2960 -0
  90. package/src/runtime/agent/orchestrator/session/result-classification.mjs +65 -0
  91. package/src/runtime/agent/orchestrator/session/store.mjs +663 -0
  92. package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  93. package/src/runtime/agent/orchestrator/smart-bridge/bridge-llm.mjs +339 -0
  94. package/src/runtime/agent/orchestrator/smart-bridge/cache-strategy.mjs +419 -0
  95. package/src/runtime/agent/orchestrator/stall-policy.mjs +227 -0
  96. package/src/runtime/agent/orchestrator/tool-loop-guard.mjs +235 -0
  97. package/src/runtime/agent/orchestrator/tools/bash-session.mjs +723 -0
  98. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +389 -0
  99. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +637 -0
  100. package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +165 -0
  101. package/src/runtime/agent/orchestrator/tools/builtin/fuzzy-match.mjs +104 -0
  102. package/src/runtime/agent/orchestrator/tools/builtin/glob-walk.mjs +194 -0
  103. package/src/runtime/agent/orchestrator/tools/builtin/list-tool.mjs +596 -0
  104. package/src/runtime/agent/orchestrator/tools/builtin/native-edit-runner.mjs +110 -0
  105. package/src/runtime/agent/orchestrator/tools/builtin/path-diagnostics.mjs +153 -0
  106. package/src/runtime/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  107. package/src/runtime/agent/orchestrator/tools/builtin/read-open.mjs +189 -0
  108. package/src/runtime/agent/orchestrator/tools/builtin/read-single-tool.mjs +731 -0
  109. package/src/runtime/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +168 -0
  110. package/src/runtime/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  111. package/src/runtime/agent/orchestrator/tools/builtin/rg-runner.mjs +465 -0
  112. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.mjs +160 -0
  113. package/src/runtime/agent/orchestrator/tools/builtin/search-tool.mjs +982 -0
  114. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +1087 -0
  115. package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +231 -0
  116. package/src/runtime/agent/orchestrator/tools/builtin/snapshot-store.mjs +223 -0
  117. package/src/runtime/agent/orchestrator/tools/builtin.mjs +478 -0
  118. package/src/runtime/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  119. package/src/runtime/agent/orchestrator/tools/code-graph.mjs +4102 -0
  120. package/src/runtime/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  121. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.mjs +154 -0
  122. package/src/runtime/agent/orchestrator/tools/graph-manifest.json +26 -0
  123. package/src/runtime/agent/orchestrator/tools/patch-binary-fetcher.mjs +143 -0
  124. package/src/runtime/agent/orchestrator/tools/patch-tool-defs.mjs +18 -0
  125. package/src/runtime/agent/orchestrator/tools/patch.mjs +2772 -0
  126. package/src/runtime/agent/orchestrator/tools/progress-message.mjs +114 -0
  127. package/src/runtime/agent/orchestrator/tools/shell-command.mjs +880 -0
  128. package/src/runtime/agent/orchestrator/tools/shell-snapshot.mjs +312 -0
  129. package/src/runtime/channels/backends/discord.mjs +781 -0
  130. package/src/runtime/channels/data/voice-runtime-manifest.json +138 -0
  131. package/src/runtime/channels/index.mjs +3309 -0
  132. package/src/runtime/channels/lib/config.mjs +285 -0
  133. package/src/runtime/channels/lib/drop-trace.mjs +71 -0
  134. package/src/runtime/channels/lib/event-pipeline.mjs +81 -0
  135. package/src/runtime/channels/lib/holidays.mjs +138 -0
  136. package/src/runtime/channels/lib/hook-pipe-server.mjs +671 -0
  137. package/src/runtime/channels/lib/output-forwarder.mjs +765 -0
  138. package/src/runtime/channels/lib/runtime-paths.mjs +497 -0
  139. package/src/runtime/channels/lib/scheduler.mjs +710 -0
  140. package/src/runtime/channels/lib/session-discovery.mjs +102 -0
  141. package/src/runtime/channels/lib/state-file.mjs +68 -0
  142. package/src/runtime/channels/lib/status-snapshot.mjs +224 -0
  143. package/src/runtime/channels/lib/tool-format.mjs +124 -0
  144. package/src/runtime/channels/lib/transcript-discovery.mjs +195 -0
  145. package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +734 -0
  146. package/src/runtime/channels/lib/webhook.mjs +1288 -0
  147. package/src/runtime/channels/tool-defs.mjs +177 -0
  148. package/src/runtime/lib/keychain-cjs.cjs +289 -0
  149. package/src/runtime/memory/data/runtime-manifest.json +40 -0
  150. package/src/runtime/memory/index.mjs +3600 -0
  151. package/src/runtime/memory/lib/core-memory-store.mjs +336 -0
  152. package/src/runtime/memory/lib/embedding-provider.mjs +275 -0
  153. package/src/runtime/memory/lib/embedding-worker.mjs +331 -0
  154. package/src/runtime/memory/lib/memory-cycle-requests.mjs +276 -0
  155. package/src/runtime/memory/lib/memory-cycle1.mjs +783 -0
  156. package/src/runtime/memory/lib/memory-cycle2.mjs +1389 -0
  157. package/src/runtime/memory/lib/memory-cycle3.mjs +646 -0
  158. package/src/runtime/memory/lib/memory-embed.mjs +300 -0
  159. package/src/runtime/memory/lib/memory-ops-policy.mjs +149 -0
  160. package/src/runtime/memory/lib/memory-recall-store.mjs +644 -0
  161. package/src/runtime/memory/lib/memory.mjs +418 -0
  162. package/src/runtime/memory/lib/pg/adapter.mjs +314 -0
  163. package/src/runtime/memory/lib/pg/process.mjs +366 -0
  164. package/src/runtime/memory/lib/pg/supervisor.mjs +495 -0
  165. package/src/runtime/memory/lib/runtime-fetcher.mjs +464 -0
  166. package/src/runtime/memory/lib/trace-store.mjs +734 -0
  167. package/src/runtime/memory/tool-defs.mjs +79 -0
  168. package/src/runtime/search/index.mjs +925 -0
  169. package/src/runtime/search/lib/config.mjs +61 -0
  170. package/src/runtime/search/lib/web-tools.mjs +1278 -0
  171. package/src/runtime/search/tool-defs.mjs +64 -0
  172. package/src/runtime/shared/atomic-file.mjs +435 -0
  173. package/src/runtime/shared/background-tasks.mjs +376 -0
  174. package/src/runtime/shared/child-guardian.mjs +98 -0
  175. package/src/runtime/shared/config.mjs +393 -0
  176. package/src/runtime/shared/err-text.mjs +121 -0
  177. package/src/runtime/shared/launcher-control.mjs +259 -0
  178. package/src/runtime/shared/llm/http-agent.mjs +129 -0
  179. package/src/runtime/shared/open-url.mjs +37 -0
  180. package/src/runtime/shared/plugin-paths.mjs +25 -0
  181. package/src/runtime/shared/process-shutdown.mjs +147 -0
  182. package/src/runtime/shared/schedules-store.mjs +70 -0
  183. package/src/runtime/shared/tool-execution-contract.mjs +104 -0
  184. package/src/runtime/shared/tool-surface.mjs +950 -0
  185. package/src/runtime/shared/user-cwd.mjs +221 -0
  186. package/src/runtime/shared/user-data-guard.mjs +232 -0
  187. package/src/runtime/shared/workspace-router.mjs +259 -0
  188. package/src/standalone/bridge-tool.mjs +1414 -0
  189. package/src/standalone/channel-admin.mjs +366 -0
  190. package/src/standalone/channel-worker-preload.cjs +3 -0
  191. package/src/standalone/channel-worker.mjs +353 -0
  192. package/src/standalone/explore-tool.mjs +233 -0
  193. package/src/standalone/hook-bus.mjs +246 -0
  194. package/src/standalone/plugin-admin.mjs +247 -0
  195. package/src/standalone/provider-admin.mjs +338 -0
  196. package/src/standalone/seeds.mjs +94 -0
  197. package/src/standalone/usage-dashboard.mjs +510 -0
  198. package/src/tui/App.jsx +5438 -0
  199. package/src/tui/components/AnsiText.jsx +199 -0
  200. package/src/tui/components/ContextPanel.jsx +217 -0
  201. package/src/tui/components/Markdown.jsx +205 -0
  202. package/src/tui/components/MarkdownTable.jsx +204 -0
  203. package/src/tui/components/Message.jsx +103 -0
  204. package/src/tui/components/Picker.jsx +317 -0
  205. package/src/tui/components/PromptInput.jsx +584 -0
  206. package/src/tui/components/QueuedCommands.jsx +47 -0
  207. package/src/tui/components/SlashCommandPalette.jsx +114 -0
  208. package/src/tui/components/Spinner.jsx +317 -0
  209. package/src/tui/components/StatusLine.jsx +87 -0
  210. package/src/tui/components/TextEntryPanel.jsx +323 -0
  211. package/src/tui/components/ToolExecution.jsx +772 -0
  212. package/src/tui/components/TurnDone.jsx +78 -0
  213. package/src/tui/components/UsagePanel.jsx +331 -0
  214. package/src/tui/dist/index.mjs +12359 -0
  215. package/src/tui/engine.mjs +2410 -0
  216. package/src/tui/figures.mjs +50 -0
  217. package/src/tui/hooks/useEngine.mjs +16 -0
  218. package/src/tui/index.jsx +254 -0
  219. package/src/tui/input-editing.mjs +242 -0
  220. package/src/tui/markdown/format-token.mjs +194 -0
  221. package/src/tui/paste-attachments.mjs +198 -0
  222. package/src/tui/runtime/shared/process-shutdown.mjs +1 -0
  223. package/src/tui/spinner-verbs.mjs +45 -0
  224. package/src/tui/theme.mjs +67 -0
  225. package/src/tui/time-format.mjs +53 -0
  226. package/src/ui/ansi.mjs +115 -0
  227. package/src/ui/markdown.mjs +195 -0
  228. package/src/ui/statusline.mjs +730 -0
  229. package/src/ui/tool-card.mjs +101 -0
  230. package/src/vendor/statusline/bin/statusline-lib.mjs +805 -0
  231. package/src/vendor/statusline/bin/statusline-route.mjs +596 -0
  232. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +285 -0
  233. package/src/vendor/statusline/src/gateway/claude-current.mjs +320 -0
  234. package/src/vendor/statusline/src/gateway/route-meta.mjs +753 -0
  235. package/src/vendor/statusline/src/gateway/session-routes.mjs +244 -0
  236. package/src/workflows/default/WORKFLOW.md +7 -0
  237. package/src/workflows/default/workflow.json +14 -0
  238. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  239. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  240. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  241. package/vendor/ink/build/colorize.d.ts +3 -0
  242. package/vendor/ink/build/colorize.js +48 -0
  243. package/vendor/ink/build/colorize.js.map +1 -0
  244. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  245. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  246. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  247. package/vendor/ink/build/components/AnimationContext.d.ts +9 -0
  248. package/vendor/ink/build/components/AnimationContext.js +13 -0
  249. package/vendor/ink/build/components/AnimationContext.js.map +1 -0
  250. package/vendor/ink/build/components/App.d.ts +24 -0
  251. package/vendor/ink/build/components/App.js +554 -0
  252. package/vendor/ink/build/components/App.js.map +1 -0
  253. package/vendor/ink/build/components/AppContext.d.ts +80 -0
  254. package/vendor/ink/build/components/AppContext.js +25 -0
  255. package/vendor/ink/build/components/AppContext.js.map +1 -0
  256. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  257. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  258. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  259. package/vendor/ink/build/components/Box.d.ts +130 -0
  260. package/vendor/ink/build/components/Box.js +34 -0
  261. package/vendor/ink/build/components/Box.js.map +1 -0
  262. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  263. package/vendor/ink/build/components/CursorContext.js +8 -0
  264. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  265. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  266. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  267. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  268. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  269. package/vendor/ink/build/components/ErrorOverview.js +90 -0
  270. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  271. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  272. package/vendor/ink/build/components/FocusContext.js +17 -0
  273. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  274. package/vendor/ink/build/components/Newline.d.ts +13 -0
  275. package/vendor/ink/build/components/Newline.js +8 -0
  276. package/vendor/ink/build/components/Newline.js.map +1 -0
  277. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  278. package/vendor/ink/build/components/Spacer.js +11 -0
  279. package/vendor/ink/build/components/Spacer.js.map +1 -0
  280. package/vendor/ink/build/components/Static.d.ts +24 -0
  281. package/vendor/ink/build/components/Static.js +28 -0
  282. package/vendor/ink/build/components/Static.js.map +1 -0
  283. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  284. package/vendor/ink/build/components/StderrContext.js +13 -0
  285. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  286. package/vendor/ink/build/components/StdinContext.d.ts +28 -0
  287. package/vendor/ink/build/components/StdinContext.js +20 -0
  288. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  289. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  290. package/vendor/ink/build/components/StdoutContext.js +13 -0
  291. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  292. package/vendor/ink/build/components/Text.d.ts +55 -0
  293. package/vendor/ink/build/components/Text.js +50 -0
  294. package/vendor/ink/build/components/Text.js.map +1 -0
  295. package/vendor/ink/build/components/Transform.d.ts +16 -0
  296. package/vendor/ink/build/components/Transform.js +15 -0
  297. package/vendor/ink/build/components/Transform.js.map +1 -0
  298. package/vendor/ink/build/cursor-helpers.d.ts +39 -0
  299. package/vendor/ink/build/cursor-helpers.js +62 -0
  300. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  301. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  302. package/vendor/ink/build/devtools-window-polyfill.js +68 -0
  303. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  304. package/vendor/ink/build/devtools.d.ts +1 -0
  305. package/vendor/ink/build/devtools.js +36 -0
  306. package/vendor/ink/build/devtools.js.map +1 -0
  307. package/vendor/ink/build/dom.d.ts +62 -0
  308. package/vendor/ink/build/dom.js +143 -0
  309. package/vendor/ink/build/dom.js.map +1 -0
  310. package/vendor/ink/build/get-max-width.d.ts +3 -0
  311. package/vendor/ink/build/get-max-width.js +10 -0
  312. package/vendor/ink/build/get-max-width.js.map +1 -0
  313. package/vendor/ink/build/hooks/use-animation.d.ts +49 -0
  314. package/vendor/ink/build/hooks/use-animation.js +87 -0
  315. package/vendor/ink/build/hooks/use-animation.js.map +1 -0
  316. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  317. package/vendor/ink/build/hooks/use-app.js +8 -0
  318. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  319. package/vendor/ink/build/hooks/use-box-metrics.d.ts +59 -0
  320. package/vendor/ink/build/hooks/use-box-metrics.js +81 -0
  321. package/vendor/ink/build/hooks/use-box-metrics.js.map +1 -0
  322. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  323. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  324. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  325. package/vendor/ink/build/hooks/use-focus-manager.d.ts +43 -0
  326. package/vendor/ink/build/hooks/use-focus-manager.js +18 -0
  327. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  328. package/vendor/ink/build/hooks/use-focus.d.ts +30 -0
  329. package/vendor/ink/build/hooks/use-focus.js +43 -0
  330. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  331. package/vendor/ink/build/hooks/use-input.d.ts +132 -0
  332. package/vendor/ink/build/hooks/use-input.js +126 -0
  333. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  334. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +6 -0
  335. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +12 -0
  336. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  337. package/vendor/ink/build/hooks/use-paste.d.ts +35 -0
  338. package/vendor/ink/build/hooks/use-paste.js +62 -0
  339. package/vendor/ink/build/hooks/use-paste.js.map +1 -0
  340. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  341. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  342. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  343. package/vendor/ink/build/hooks/use-stdin.d.ts +7 -0
  344. package/vendor/ink/build/hooks/use-stdin.js +9 -0
  345. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  346. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  347. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  348. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  349. package/vendor/ink/build/hooks/use-window-size.d.ts +18 -0
  350. package/vendor/ink/build/hooks/use-window-size.js +22 -0
  351. package/vendor/ink/build/hooks/use-window-size.js.map +1 -0
  352. package/vendor/ink/build/index.d.ts +42 -0
  353. package/vendor/ink/build/index.js +24 -0
  354. package/vendor/ink/build/index.js.map +1 -0
  355. package/vendor/ink/build/ink.d.ts +146 -0
  356. package/vendor/ink/build/ink.js +1022 -0
  357. package/vendor/ink/build/ink.js.map +1 -0
  358. package/vendor/ink/build/input-parser.d.ts +10 -0
  359. package/vendor/ink/build/input-parser.js +194 -0
  360. package/vendor/ink/build/input-parser.js.map +1 -0
  361. package/vendor/ink/build/instances.d.ts +3 -0
  362. package/vendor/ink/build/instances.js +8 -0
  363. package/vendor/ink/build/instances.js.map +1 -0
  364. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  365. package/vendor/ink/build/kitty-keyboard.js +32 -0
  366. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  367. package/vendor/ink/build/log-update.d.ts +20 -0
  368. package/vendor/ink/build/log-update.js +261 -0
  369. package/vendor/ink/build/log-update.js.map +1 -0
  370. package/vendor/ink/build/measure-element.d.ts +20 -0
  371. package/vendor/ink/build/measure-element.js +13 -0
  372. package/vendor/ink/build/measure-element.js.map +1 -0
  373. package/vendor/ink/build/measure-text.d.ts +6 -0
  374. package/vendor/ink/build/measure-text.js +21 -0
  375. package/vendor/ink/build/measure-text.js.map +1 -0
  376. package/vendor/ink/build/output.d.ts +35 -0
  377. package/vendor/ink/build/output.js +328 -0
  378. package/vendor/ink/build/output.js.map +1 -0
  379. package/vendor/ink/build/parse-keypress.d.ts +20 -0
  380. package/vendor/ink/build/parse-keypress.js +495 -0
  381. package/vendor/ink/build/parse-keypress.js.map +1 -0
  382. package/vendor/ink/build/reconciler.d.ts +4 -0
  383. package/vendor/ink/build/reconciler.js +306 -0
  384. package/vendor/ink/build/reconciler.js.map +1 -0
  385. package/vendor/ink/build/render-background.d.ts +4 -0
  386. package/vendor/ink/build/render-background.js +25 -0
  387. package/vendor/ink/build/render-background.js.map +1 -0
  388. package/vendor/ink/build/render-border.d.ts +4 -0
  389. package/vendor/ink/build/render-border.js +84 -0
  390. package/vendor/ink/build/render-border.js.map +1 -0
  391. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  392. package/vendor/ink/build/render-node-to-output.js +162 -0
  393. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  394. package/vendor/ink/build/render-to-string.d.ts +38 -0
  395. package/vendor/ink/build/render-to-string.js +116 -0
  396. package/vendor/ink/build/render-to-string.js.map +1 -0
  397. package/vendor/ink/build/render.d.ts +176 -0
  398. package/vendor/ink/build/render.js +71 -0
  399. package/vendor/ink/build/render.js.map +1 -0
  400. package/vendor/ink/build/renderer.d.ts +8 -0
  401. package/vendor/ink/build/renderer.js +64 -0
  402. package/vendor/ink/build/renderer.js.map +1 -0
  403. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  404. package/vendor/ink/build/sanitize-ansi.js +27 -0
  405. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  406. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  407. package/vendor/ink/build/squash-text-nodes.js +36 -0
  408. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  409. package/vendor/ink/build/styles.d.ts +302 -0
  410. package/vendor/ink/build/styles.js +303 -0
  411. package/vendor/ink/build/styles.js.map +1 -0
  412. package/vendor/ink/build/utils.d.ts +9 -0
  413. package/vendor/ink/build/utils.js +19 -0
  414. package/vendor/ink/build/utils.js.map +1 -0
  415. package/vendor/ink/build/wrap-text.d.ts +3 -0
  416. package/vendor/ink/build/wrap-text.js +38 -0
  417. package/vendor/ink/build/wrap-text.js.map +1 -0
  418. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  419. package/vendor/ink/build/write-synchronized.js +9 -0
  420. package/vendor/ink/build/write-synchronized.js.map +1 -0
  421. package/vendor/ink/license +10 -0
  422. package/vendor/ink/package.json +137 -0
  423. package/.claude-plugin/marketplace.json +0 -34
  424. package/.claude-plugin/plugin.json +0 -20
  425. package/.gitattributes +0 -34
  426. package/.mcp.json +0 -14
  427. package/ARCHITECTURE.md +0 -77
  428. package/CHANGELOG.md +0 -30
  429. package/CONTRIBUTING.md +0 -45
  430. package/DATA-FLOW.md +0 -79
  431. package/LICENSE +0 -21
  432. package/SECURITY.md +0 -138
  433. package/UNINSTALL.md +0 -115
  434. package/agents/maintenance.md +0 -5
  435. package/agents/memory-classification.md +0 -30
  436. package/agents/scheduler-task.md +0 -18
  437. package/agents/webhook-handler.md +0 -27
  438. package/agents/worker.md +0 -24
  439. package/bin/bridge +0 -133
  440. package/bin/statusline-launcher.mjs +0 -82
  441. package/bin/statusline-lib.mjs +0 -581
  442. package/bin/statusline-route.mjs +0 -273
  443. package/bin/statusline.mjs +0 -638
  444. package/bun.lock +0 -927
  445. package/commands/config.md +0 -16
  446. package/commands/doctor.md +0 -13
  447. package/commands/model.md +0 -61
  448. package/commands/setup.md +0 -17
  449. package/defaults/hidden-roles.json +0 -68
  450. package/defaults/memory-chunk-prompt.md +0 -63
  451. package/defaults/mixdog-config.template.json +0 -27
  452. package/defaults/user-workflow.json +0 -8
  453. package/defaults/user-workflow.md +0 -17
  454. package/hooks/hooks.json +0 -73
  455. package/hooks/lib/active-instance.cjs +0 -77
  456. package/hooks/lib/permission-evaluator.cjs +0 -411
  457. package/hooks/lib/permission-route.cjs +0 -63
  458. package/hooks/lib/settings-loader.cjs +0 -117
  459. package/hooks/post-tool-use.cjs +0 -84
  460. package/hooks/pre-mcp-sandbox.cjs +0 -158
  461. package/hooks/pre-tool-subagent.cjs +0 -258
  462. package/hooks/session-start.cjs +0 -1493
  463. package/hooks/shim-launcher.cjs +0 -65
  464. package/hooks/turn-timer.cjs +0 -82
  465. package/lib/claude-md-writer.cjs +0 -386
  466. package/lib/keychain-cjs.cjs +0 -290
  467. package/lib/plugin-paths.cjs +0 -69
  468. package/lib/rules-builder.cjs +0 -241
  469. package/native/README.md +0 -117
  470. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  471. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  472. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  473. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  474. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  475. package/prompts/code-review.txt +0 -16
  476. package/prompts/security-audit.txt +0 -17
  477. package/rules/bridge/00-common.md +0 -39
  478. package/rules/bridge/20-skip-protocol.md +0 -18
  479. package/rules/bridge/30-explorer.md +0 -33
  480. package/rules/bridge/40-cycle1-agent.md +0 -52
  481. package/rules/bridge/41-cycle2-agent.md +0 -62
  482. package/rules/lead/00-tool-lead.md +0 -61
  483. package/rules/lead/01-general.md +0 -26
  484. package/rules/lead/02-channels.md +0 -49
  485. package/rules/lead/03-team.md +0 -27
  486. package/rules/lead/04-workflow.md +0 -20
  487. package/rules/shared/00-language.md +0 -14
  488. package/rules/shared/01-tool.md +0 -138
  489. package/scripts/bootstrap.mjs +0 -130
  490. package/scripts/bridge-unify-smoke.mjs +0 -308
  491. package/scripts/build-runtime-linux.sh +0 -348
  492. package/scripts/build-runtime-macos.sh +0 -217
  493. package/scripts/build-runtime-windows.ps1 +0 -242
  494. package/scripts/builtin-utils-smoke.mjs +0 -398
  495. package/scripts/bump.mjs +0 -80
  496. package/scripts/check-json.mjs +0 -45
  497. package/scripts/check-syntax-changed.mjs +0 -102
  498. package/scripts/check-syntax.mjs +0 -58
  499. package/scripts/code-graph-batch.test.mjs +0 -33
  500. package/scripts/config-preserve-smoke.mjs +0 -180
  501. package/scripts/doctor.mjs +0 -489
  502. package/scripts/edit-normalize-fuzz.mjs +0 -130
  503. package/scripts/edit-normalize-smoke.mjs +0 -401
  504. package/scripts/edit-operation-smoke.mjs +0 -369
  505. package/scripts/edit2-smoke.mjs +0 -63
  506. package/scripts/ensure-deps.mjs +0 -259
  507. package/scripts/fuzzy-e2e.mjs +0 -28
  508. package/scripts/fuzzy-smoke.mjs +0 -26
  509. package/scripts/gateway-model.mjs +0 -596
  510. package/scripts/generate-runtime-manifest.mjs +0 -166
  511. package/scripts/guard-smoke.mjs +0 -66
  512. package/scripts/hidden-role-schema-smoke.mjs +0 -162
  513. package/scripts/hook-routing-smoke.mjs +0 -29
  514. package/scripts/inject-input.ps1 +0 -204
  515. package/scripts/io-complex-smoke.mjs +0 -667
  516. package/scripts/io-explore-bench.mjs +0 -424
  517. package/scripts/io-guardrails-smoke.mjs +0 -205
  518. package/scripts/io-mini-bench-baseline.json +0 -11
  519. package/scripts/io-mini-bench.mjs +0 -216
  520. package/scripts/io-route-harness.mjs +0 -933
  521. package/scripts/io-telemetry-report.mjs +0 -691
  522. package/scripts/lib/gateway-inventory.mjs +0 -178
  523. package/scripts/lib/gateway-settings.mjs +0 -78
  524. package/scripts/mutation-bench.mjs +0 -564
  525. package/scripts/mutation-io-smoke.mjs +0 -1097
  526. package/scripts/native-patch-bridge-smoke.mjs +0 -288
  527. package/scripts/native-patch-smoke.mjs +0 -304
  528. package/scripts/openai-oauth-catalog-smoke.mjs +0 -53
  529. package/scripts/patch-interior-context-smoke.mjs +0 -49
  530. package/scripts/patch-newline-utf8-smoke.mjs +0 -157
  531. package/scripts/perf-hook-smoke.mjs +0 -71
  532. package/scripts/permission-eval-smoke.mjs +0 -443
  533. package/scripts/prep-patch.mjs +0 -53
  534. package/scripts/prep-shim.mjs +0 -96
  535. package/scripts/provider-cache-smoke.mjs +0 -687
  536. package/scripts/report-runtime-health.mjs +0 -132
  537. package/scripts/resolve-bun.mjs +0 -60
  538. package/scripts/run-mcp.mjs +0 -1473
  539. package/scripts/salvage-v4a-shatter.test.mjs +0 -58
  540. package/scripts/scoped-cache-io-smoke.mjs +0 -103
  541. package/scripts/shell-policy-round3-smoke.mjs +0 -46
  542. package/scripts/smoke-runtime-negative.ps1 +0 -100
  543. package/scripts/smoke-runtime-negative.sh +0 -95
  544. package/scripts/stall-policy-smoke.mjs +0 -50
  545. package/scripts/start-memory-worker.mjs +0 -23
  546. package/scripts/statusline-launcher-smoke.mjs +0 -235
  547. package/scripts/stress-atomic-write.mjs +0 -1028
  548. package/scripts/test-fault-inject.mjs +0 -164
  549. package/scripts/test-large-file.mjs +0 -174
  550. package/scripts/tool-edge-smoke.mjs +0 -209
  551. package/scripts/uninstall.mjs +0 -238
  552. package/scripts/webhook-selfheal-smoke.mjs +0 -27
  553. package/scripts/write-overwrite-guard-smoke.mjs +0 -56
  554. package/server-main.mjs +0 -3350
  555. package/server.mjs +0 -468
  556. package/setup/config-merge.mjs +0 -246
  557. package/setup/install.mjs +0 -574
  558. package/setup/launch-core.mjs +0 -617
  559. package/setup/launch.mjs +0 -101
  560. package/setup/locate-claude.mjs +0 -56
  561. package/setup/mixdog-cli.mjs +0 -122
  562. package/setup/setup-server.mjs +0 -3305
  563. package/setup/setup.html +0 -3740
  564. package/setup/tui.mjs +0 -325
  565. package/skills/retro-skill-proposer/SKILL.md +0 -92
  566. package/skills/schedule-add/SKILL.md +0 -77
  567. package/skills/setup/SKILL.md +0 -356
  568. package/skills/webhook-add/SKILL.md +0 -81
  569. package/src/agent/bridge-stall-watchdog.mjs +0 -337
  570. package/src/agent/index.mjs +0 -2229
  571. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +0 -1010
  572. package/src/agent/orchestrator/bridge-retry.mjs +0 -220
  573. package/src/agent/orchestrator/bridge-trace.mjs +0 -601
  574. package/src/agent/orchestrator/cache-mtime.mjs +0 -58
  575. package/src/agent/orchestrator/config.mjs +0 -405
  576. package/src/agent/orchestrator/context/collect.mjs +0 -651
  577. package/src/agent/orchestrator/dispatch-persist.mjs +0 -549
  578. package/src/agent/orchestrator/drain-registry.mjs +0 -50
  579. package/src/agent/orchestrator/explore-validator.mjs +0 -8
  580. package/src/agent/orchestrator/internal-roles.mjs +0 -118
  581. package/src/agent/orchestrator/internal-tools.mjs +0 -88
  582. package/src/agent/orchestrator/jobs.mjs +0 -116
  583. package/src/agent/orchestrator/mcp/client.mjs +0 -364
  584. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +0 -1884
  585. package/src/agent/orchestrator/providers/anthropic.mjs +0 -598
  586. package/src/agent/orchestrator/providers/gemini.mjs +0 -1530
  587. package/src/agent/orchestrator/providers/grok-oauth.mjs +0 -779
  588. package/src/agent/orchestrator/providers/model-catalog.mjs +0 -374
  589. package/src/agent/orchestrator/providers/openai-compat-stream.mjs +0 -366
  590. package/src/agent/orchestrator/providers/openai-compat.mjs +0 -1511
  591. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -1891
  592. package/src/agent/orchestrator/providers/openai-oauth.mjs +0 -1456
  593. package/src/agent/orchestrator/providers/openai-ws.mjs +0 -127
  594. package/src/agent/orchestrator/providers/registry.mjs +0 -192
  595. package/src/agent/orchestrator/providers/retry-classifier.mjs +0 -325
  596. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +0 -142
  597. package/src/agent/orchestrator/session/cache/read-cache.mjs +0 -319
  598. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +0 -361
  599. package/src/agent/orchestrator/session/loop.mjs +0 -1619
  600. package/src/agent/orchestrator/session/manager.mjs +0 -1991
  601. package/src/agent/orchestrator/session/result-classification.mjs +0 -65
  602. package/src/agent/orchestrator/session/store.mjs +0 -632
  603. package/src/agent/orchestrator/session/stream-watchdog.mjs +0 -130
  604. package/src/agent/orchestrator/session/tool-result-offload.mjs +0 -166
  605. package/src/agent/orchestrator/session/trim.mjs +0 -491
  606. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +0 -115
  607. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +0 -331
  608. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +0 -150
  609. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +0 -228
  610. package/src/agent/orchestrator/smart-bridge/index.mjs +0 -215
  611. package/src/agent/orchestrator/smart-bridge/profiles.mjs +0 -37
  612. package/src/agent/orchestrator/smart-bridge/registry.mjs +0 -348
  613. package/src/agent/orchestrator/stall-policy.mjs +0 -201
  614. package/src/agent/orchestrator/tool-loop-guard.mjs +0 -75
  615. package/src/agent/orchestrator/tools/bash-session.mjs +0 -722
  616. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +0 -511
  617. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -480
  618. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +0 -256
  619. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +0 -58
  620. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +0 -240
  621. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +0 -113
  622. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +0 -74
  623. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +0 -242
  624. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +0 -211
  625. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +0 -1364
  626. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +0 -126
  627. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +0 -141
  628. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +0 -194
  629. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +0 -60
  630. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +0 -168
  631. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +0 -173
  632. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +0 -48
  633. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -99
  634. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +0 -193
  635. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +0 -597
  636. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
  637. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +0 -300
  638. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +0 -152
  639. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -118
  640. package/src/agent/orchestrator/tools/builtin/read-open.mjs +0 -190
  641. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +0 -728
  642. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +0 -173
  643. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +0 -602
  644. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +0 -196
  645. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +0 -422
  646. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +0 -158
  647. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +0 -869
  648. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +0 -962
  649. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +0 -223
  650. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +0 -206
  651. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +0 -401
  652. package/src/agent/orchestrator/tools/builtin.mjs +0 -503
  653. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +0 -24
  654. package/src/agent/orchestrator/tools/code-graph.mjs +0 -4095
  655. package/src/agent/orchestrator/tools/cwd-tool.mjs +0 -298
  656. package/src/agent/orchestrator/tools/destructive-warning.mjs +0 -323
  657. package/src/agent/orchestrator/tools/edit-normalize.mjs +0 -603
  658. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +0 -154
  659. package/src/agent/orchestrator/tools/graph-manifest.json +0 -26
  660. package/src/agent/orchestrator/tools/host-input.mjs +0 -204
  661. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +0 -143
  662. package/src/agent/orchestrator/tools/patch-manifest.json +0 -26
  663. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +0 -20
  664. package/src/agent/orchestrator/tools/patch.mjs +0 -2754
  665. package/src/agent/orchestrator/tools/progress-message.mjs +0 -118
  666. package/src/agent/orchestrator/tools/shell-command.mjs +0 -865
  667. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +0 -7
  668. package/src/agent/orchestrator/tools/shell-snapshot.mjs +0 -313
  669. package/src/agent/orchestrator/workflow-store.mjs +0 -93
  670. package/src/agent/tool-defs.mjs +0 -110
  671. package/src/channels/backends/discord.mjs +0 -784
  672. package/src/channels/data/voice-runtime-manifest.json +0 -138
  673. package/src/channels/index.mjs +0 -3268
  674. package/src/channels/lib/config.mjs +0 -292
  675. package/src/channels/lib/drop-trace.mjs +0 -71
  676. package/src/channels/lib/event-pipeline.mjs +0 -81
  677. package/src/channels/lib/holidays.mjs +0 -138
  678. package/src/channels/lib/hook-pipe-server.mjs +0 -822
  679. package/src/channels/lib/output-forwarder.mjs +0 -765
  680. package/src/channels/lib/runtime-paths.mjs +0 -552
  681. package/src/channels/lib/scheduler.mjs +0 -723
  682. package/src/channels/lib/session-discovery.mjs +0 -103
  683. package/src/channels/lib/state-file.mjs +0 -68
  684. package/src/channels/lib/status-snapshot.mjs +0 -219
  685. package/src/channels/lib/tool-format.mjs +0 -140
  686. package/src/channels/lib/transcript-discovery.mjs +0 -195
  687. package/src/channels/lib/voice-runtime-fetcher.mjs +0 -734
  688. package/src/channels/lib/webhook.mjs +0 -1318
  689. package/src/channels/tool-defs.mjs +0 -170
  690. package/src/daemon/host.mjs +0 -118
  691. package/src/daemon/mcp-transport.mjs +0 -47
  692. package/src/daemon/session.mjs +0 -100
  693. package/src/daemon/thin-client.mjs +0 -71
  694. package/src/daemon/transport.mjs +0 -163
  695. package/src/gateway/claude-current.mjs +0 -255
  696. package/src/gateway/oauth-usage.mjs +0 -598
  697. package/src/gateway/route-meta.mjs +0 -629
  698. package/src/gateway/server.mjs +0 -713
  699. package/src/memory/data/runtime-manifest.json +0 -40
  700. package/src/memory/index.mjs +0 -3332
  701. package/src/memory/lib/core-memory-store.mjs +0 -330
  702. package/src/memory/lib/embedding-provider.mjs +0 -269
  703. package/src/memory/lib/embedding-worker.mjs +0 -323
  704. package/src/memory/lib/memory-cycle1.mjs +0 -645
  705. package/src/memory/lib/memory-cycle2.mjs +0 -1284
  706. package/src/memory/lib/memory-cycle3.mjs +0 -540
  707. package/src/memory/lib/memory-embed.mjs +0 -299
  708. package/src/memory/lib/memory-ops-policy.mjs +0 -190
  709. package/src/memory/lib/memory-recall-store.mjs +0 -638
  710. package/src/memory/lib/memory.mjs +0 -412
  711. package/src/memory/lib/pg/adapter.mjs +0 -308
  712. package/src/memory/lib/pg/process.mjs +0 -360
  713. package/src/memory/lib/pg/supervisor.mjs +0 -396
  714. package/src/memory/lib/runtime-fetcher.mjs +0 -458
  715. package/src/memory/lib/trace-store.mjs +0 -728
  716. package/src/memory/tool-defs.mjs +0 -79
  717. package/src/search/index.mjs +0 -1173
  718. package/src/search/lib/backends/anthropic-oauth.mjs +0 -98
  719. package/src/search/lib/backends/exa.mjs +0 -50
  720. package/src/search/lib/backends/firecrawl.mjs +0 -61
  721. package/src/search/lib/backends/gemini-api.mjs +0 -83
  722. package/src/search/lib/backends/grok-oauth.mjs +0 -86
  723. package/src/search/lib/backends/index.mjs +0 -150
  724. package/src/search/lib/backends/openai-api.mjs +0 -144
  725. package/src/search/lib/backends/openai-oauth.mjs +0 -102
  726. package/src/search/lib/backends/openai-web-search.mjs +0 -76
  727. package/src/search/lib/backends/tavily.mjs +0 -55
  728. package/src/search/lib/backends/xai-api.mjs +0 -113
  729. package/src/search/lib/config.mjs +0 -192
  730. package/src/search/lib/provider-usage.mjs +0 -67
  731. package/src/search/lib/providers.mjs +0 -47
  732. package/src/search/lib/search-intent.mjs +0 -109
  733. package/src/search/lib/setup-handler.mjs +0 -261
  734. package/src/search/lib/web-tools.mjs +0 -1219
  735. package/src/search/tool-defs.mjs +0 -83
  736. package/src/setup/defender-exclusion.mjs +0 -183
  737. package/src/shared/atomic-file.mjs +0 -436
  738. package/src/shared/config.mjs +0 -372
  739. package/src/shared/daemon-recycle.mjs +0 -108
  740. package/src/shared/disable-claude-builtins.mjs +0 -91
  741. package/src/shared/err-text.mjs +0 -12
  742. package/src/shared/llm/http-agent.mjs +0 -123
  743. package/src/shared/open-url.mjs +0 -62
  744. package/src/shared/plugin-paths.mjs +0 -58
  745. package/src/shared/schedules-store.mjs +0 -70
  746. package/src/shared/seed.mjs +0 -161
  747. package/src/shared/user-cwd.mjs +0 -225
  748. package/src/shared/user-data-guard.mjs +0 -244
  749. package/src/status/aggregator.mjs +0 -584
  750. package/src/status/server.mjs +0 -413
  751. package/tools.json +0 -1671
  752. /package/{defaults → src/defaults}/cycle3-review-prompt.md +0 -0
  753. /package/{defaults → src/defaults}/memory-promote-prompt.md +0 -0
  754. /package/{hooks → src/hooks}/lib/permission-rules.cjs +0 -0
  755. /package/{lib → src/lib}/config-cjs.cjs +0 -0
  756. /package/{lib → src/lib}/hook-pipe-path.cjs +0 -0
  757. /package/{lib → src/lib}/mixdog-debug.cjs +0 -0
  758. /package/{lib → src/lib}/text-utils.cjs +0 -0
  759. /package/{rules → src/rules}/bridge/42-cycle3-agent.md +0 -0
  760. /package/src/{agent → runtime/agent}/orchestrator/activity-bus.mjs +0 -0
  761. /package/src/{agent → runtime/agent}/orchestrator/providers/anthropic-betas.mjs +0 -0
  762. /package/src/{agent → runtime/agent}/orchestrator/session/abort-lookup.mjs +0 -0
  763. /package/src/{agent → runtime/agent}/orchestrator/session/cache/post-edit-marks.mjs +0 -0
  764. /package/src/{agent → runtime/agent}/orchestrator/session/cache/scoped-cache-outcome.mjs +0 -0
  765. /package/src/{agent → runtime/agent}/orchestrator/session/cache/util.mjs +0 -0
  766. /package/src/{agent → runtime/agent}/orchestrator/session/read-dedup.mjs +0 -0
  767. /package/src/{agent → runtime/agent}/orchestrator/session/save-session-worker.mjs +0 -0
  768. /package/src/{agent → runtime/agent}/orchestrator/smart-bridge/session-builder.mjs +0 -0
  769. /package/src/{agent → runtime/agent}/orchestrator/tools/bash-policy-scan.mjs +0 -0
  770. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/advisory-lock.mjs +0 -0
  771. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/atomic-write.mjs +0 -0
  772. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/binary-file.mjs +0 -0
  773. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cache-layers.mjs +0 -0
  774. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cwd-utils.mjs +0 -0
  775. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/device-paths.mjs +0 -0
  776. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -0
  777. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diff-utils.mjs +0 -0
  778. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/fs-reachability.mjs +0 -0
  779. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/grep-formatting.mjs +0 -0
  780. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/hash-utils.mjs +0 -0
  781. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/list-formatting.mjs +0 -0
  782. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/open-config-tool.mjs +0 -0
  783. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-locks.mjs +0 -0
  784. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-utils.mjs +0 -0
  785. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-args.mjs +0 -0
  786. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-batch.mjs +0 -0
  787. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-constants.mjs +0 -0
  788. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image-resize.mjs +0 -0
  789. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image.mjs +0 -0
  790. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-lines.mjs +0 -0
  791. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-mode-tool.mjs +0 -0
  792. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-range-index.mjs +0 -0
  793. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-ranges.mjs +0 -0
  794. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-special-files.mjs +0 -0
  795. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-tool.mjs +0 -0
  796. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-windows.mjs +0 -0
  797. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-analysis.mjs +0 -0
  798. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-output.mjs +0 -0
  799. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-helpers.mjs +0 -0
  800. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-validation.mjs +0 -0
  801. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/text-stats.mjs +0 -0
  802. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/windows-roots.mjs +0 -0
  803. /package/src/{agent → runtime/agent}/orchestrator/tools/code-graph-prewarm-worker.mjs +0 -0
  804. /package/src/{agent → runtime/agent}/orchestrator/tools/env-scrub.mjs +0 -0
  805. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-content-cache.mjs +0 -0
  806. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-planner.mjs +0 -0
  807. /package/src/{agent → runtime/agent}/orchestrator/tools/next-call-utils.mjs +0 -0
  808. /package/src/{agent → runtime/agent}/orchestrator/tools/result-compression.mjs +0 -0
  809. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-exec-policy.mjs +0 -0
  810. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy-danger-target.mjs +0 -0
  811. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy.mjs +0 -0
  812. /package/src/{channels → runtime/channels}/lib/cli-worker-host.mjs +0 -0
  813. /package/src/{channels → runtime/channels}/lib/config-lock.mjs +0 -0
  814. /package/src/{channels → runtime/channels}/lib/event-queue.mjs +0 -0
  815. /package/src/{channels → runtime/channels}/lib/executor.mjs +0 -0
  816. /package/src/{channels → runtime/channels}/lib/format.mjs +0 -0
  817. /package/src/{channels → runtime/channels}/lib/interaction-workflows.mjs +0 -0
  818. /package/src/{channels → runtime/channels}/lib/memory-client.mjs +0 -0
  819. /package/src/{channels → runtime/channels}/lib/session-control.mjs +0 -0
  820. /package/src/{channels → runtime/channels}/lib/settings.mjs +0 -0
  821. /package/src/{channels → runtime/channels}/lib/whisper-server.mjs +0 -0
  822. /package/src/{memory → runtime/memory}/lib/agent-ipc.mjs +0 -0
  823. /package/src/{memory → runtime/memory}/lib/bridge-trace-queries.mjs +0 -0
  824. /package/src/{memory → runtime/memory}/lib/llm-worker-host.mjs +0 -0
  825. /package/src/{memory → runtime/memory}/lib/memory-cycle.mjs +0 -0
  826. /package/src/{memory → runtime/memory}/lib/memory-extraction.mjs +0 -0
  827. /package/src/{memory → runtime/memory}/lib/memory-maintenance-store.mjs +0 -0
  828. /package/src/{memory → runtime/memory}/lib/memory-recall-id-patch.mjs +0 -0
  829. /package/src/{memory → runtime/memory}/lib/memory-recall-read-query.mjs +0 -0
  830. /package/src/{memory → runtime/memory}/lib/memory-recall-scope-filter.mjs +0 -0
  831. /package/src/{memory → runtime/memory}/lib/memory-retrievers.mjs +0 -0
  832. /package/src/{memory → runtime/memory}/lib/memory-score.mjs +0 -0
  833. /package/src/{memory → runtime/memory}/lib/memory-text-utils.mjs +0 -0
  834. /package/src/{memory → runtime/memory}/lib/model-profile.mjs +0 -0
  835. /package/src/{memory → runtime/memory}/lib/project-id-resolver.mjs +0 -0
  836. /package/src/{search → runtime/search}/lib/cache.mjs +0 -0
  837. /package/src/{search → runtime/search}/lib/formatter.mjs +0 -0
  838. /package/src/{search → runtime/search}/lib/state.mjs +0 -0
  839. /package/src/{shared → runtime/shared}/abort-controller.mjs +0 -0
  840. /package/src/{shared → runtime/shared}/llm/cost.mjs +0 -0
  841. /package/src/{shared → runtime/shared}/llm/index.mjs +0 -0
  842. /package/src/{shared → runtime/shared}/llm/pid-cleanup.mjs +0 -0
  843. /package/src/{shared → runtime/shared}/llm/usage-log.mjs +0 -0
  844. /package/src/{shared → runtime/shared}/wsl.mjs +0 -0
@@ -1,1097 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
- import { spawnSync } from 'node:child_process';
3
- import { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
4
- import { tmpdir } from 'node:os';
5
- import { dirname, join } from 'node:path';
6
- import { fileURLToPath, pathToFileURL } from 'node:url';
7
-
8
- const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
9
- process.env.CLAUDE_PLUGIN_ROOT ||= ROOT;
10
- const DATA_DIR = join(tmpdir(), `mixdog-mutation-io-smoke-data-${process.pid}`);
11
- process.env.CLAUDE_PLUGIN_DATA = DATA_DIR;
12
- process.env.MIXDOG_HINT_LEVEL ||= 'normal';
13
-
14
- const { executeBuiltinTool, recordReadSnapshotForPath } = await import(pathToFileURL(join(ROOT, 'src/agent/orchestrator/tools/builtin.mjs')).href);
15
- const { executePatchTool } = await import(pathToFileURL(join(ROOT, 'src/agent/orchestrator/tools/patch.mjs')).href);
16
-
17
- const LINE_SEP = '→';
18
- const dir = await mkdtemp(join(tmpdir(), 'mixdog-mutation-io-smoke-'));
19
-
20
- function assertOk(label, out) {
21
- if (/^Error/.test(String(out))) throw new Error(`${label}: ${out}`);
22
- }
23
-
24
- function assertError(label, out, wanted = 'Error') {
25
- if (!String(out).startsWith(wanted)) throw new Error(`${label}: expected ${wanted}, got ${out}`);
26
- }
27
-
28
- function assertHas(label, text, wanted) {
29
- if (!String(text).includes(wanted)) throw new Error(`${label}: missing ${JSON.stringify(wanted)} in ${JSON.stringify(String(text).slice(0, 300))}`);
30
- }
31
-
32
- function assertNotHas(label, text, unwanted) {
33
- if (String(text).includes(unwanted)) throw new Error(`${label}: unexpected ${JSON.stringify(unwanted)} in ${JSON.stringify(String(text).slice(0, 300))}`);
34
- }
35
-
36
- async function expectFile(path, expected) {
37
- const got = await readFile(join(dir, path), 'utf8');
38
- if (got !== expected) throw new Error(`${path}: got ${JSON.stringify(got)}, expected ${JSON.stringify(expected)}`);
39
- }
40
-
41
- async function expectBytes(path, expected) {
42
- const got = await readFile(join(dir, path));
43
- if (!got.equals(expected)) throw new Error(`${path}: got ${got.toString('hex')}, expected ${expected.toString('hex')}`);
44
- }
45
-
46
- function expectNodeCheck(path) {
47
- const fullPath = join(dir, path);
48
- const out = spawnSync(process.execPath, ['--check', fullPath], { encoding: 'utf8' });
49
- if (out.status !== 0) {
50
- throw new Error(`${path}: node --check failed\n${out.stdout || ''}${out.stderr || ''}`);
51
- }
52
- }
53
-
54
- function hashBytes(buf) {
55
- return createHash('sha256').update(buf).digest('hex');
56
- }
57
-
58
- function patchText(lines) {
59
- return `${lines.join('\n')}\n`;
60
- }
61
-
62
- async function patchAndCheck(label, file, patch, expected) {
63
- const out = await executePatchTool('apply_patch', { patch, base_path: dir }, dir, { readStateScope: `patch-${label}` });
64
- assertOk(`patch ${label}`, out);
65
- await expectFile(file, expected);
66
- }
67
-
68
- async function warmRead(path, scope, offset = 0, limit = 20) {
69
- assertOk(`read ${path}`, await executeBuiltinTool('read', { path, offset, limit }, dir, { readStateScope: scope }));
70
- }
71
-
72
- async function rmTree(path) {
73
- // Windows CI occasionally keeps a just-used temp file locked briefly after the
74
- // owning JS/native subprocess exits (EACCES/EBUSY/EPERM). Cleanup is not part
75
- // of the smoke invariant, so retry with backoff and make final teardown
76
- // best-effort instead of turning a passed mutation suite red.
77
- const delays = [50, 100, 200, 400, 800];
78
- let lastErr = null;
79
- for (let i = 0; i <= delays.length; i++) {
80
- try {
81
- await rm(path, { recursive: true, force: true, maxRetries: 3, retryDelay: 50 });
82
- return;
83
- } catch (err) {
84
- lastErr = err;
85
- if (!['EACCES', 'EBUSY', 'EPERM', 'ENOTEMPTY'].includes(err?.code)) break;
86
- if (i < delays.length) await new Promise((resolve) => setTimeout(resolve, delays[i]));
87
- }
88
- }
89
- console.warn(`mutation-io smoke cleanup warning: failed to remove ${path}: ${lastErr?.code || ''} ${lastErr?.message || lastErr}`);
90
- }
91
-
92
- try {
93
- await writeFile(join(dir, 'patch.txt'), 'a\nb\nc\n', 'utf8');
94
- await patchAndCheck('replace', 'patch.txt', patchText([
95
- '--- a/patch.txt',
96
- '+++ b/patch.txt',
97
- '@@ -2,1 +2,1 @@',
98
- '-b',
99
- '+B',
100
- ]), 'a\nB\nc\n');
101
-
102
- await writeFile(join(dir, 'delete.txt'), 'a\nb\nc\n', 'utf8');
103
- await patchAndCheck('delete', 'delete.txt', patchText([
104
- '--- a/delete.txt',
105
- '+++ b/delete.txt',
106
- '@@ -2,1 +2,0 @@',
107
- '-b',
108
- ]), 'a\nc\n');
109
-
110
- await writeFile(join(dir, 'crlf.txt'), 'a\r\nb\r\nc\r\n', 'utf8');
111
- await patchAndCheck('crlf', 'crlf.txt', patchText([
112
- '--- a/crlf.txt',
113
- '+++ b/crlf.txt',
114
- '@@ -2,1 +2,1 @@',
115
- '-b',
116
- '+B',
117
- ]), 'a\r\nB\r\nc\r\n');
118
-
119
- await writeFile(join(dir, 'crlf-delete.txt'), 'a\r\nb\r\nc\r\n', 'utf8');
120
- await patchAndCheck('crlf-delete', 'crlf-delete.txt', patchText([
121
- '--- a/crlf-delete.txt',
122
- '+++ b/crlf-delete.txt',
123
- '@@ -2,1 +2,0 @@',
124
- '-b',
125
- ]), 'a\r\nc\r\n');
126
-
127
- await writeFile(join(dir, 'binary-ish.txt'), Buffer.from([0xff, 0xfe, 0x0a, 0x61, 0x0a, 0x62, 0x0a]));
128
- const binaryPatch = await executePatchTool('apply_patch', { patch: patchText([
129
- '--- a/binary-ish.txt',
130
- '+++ b/binary-ish.txt',
131
- '@@ -2,1 +2,1 @@',
132
- '-a',
133
- '+A',
134
- ]), base_path: dir }, dir, { readStateScope: 'patch-binary-ish' });
135
- assertOk('patch binary-ish exact byte splice', binaryPatch);
136
- await expectBytes('binary-ish.txt', Buffer.from([0xff, 0xfe, 0x0a, 0x41, 0x0a, 0x62, 0x0a]));
137
-
138
- await writeFile(join(dir, 'delete-eof-no-newline.txt'), 'a\nb', 'utf8');
139
- await patchAndCheck('delete eof no newline', 'delete-eof-no-newline.txt', patchText([
140
- '--- a/delete-eof-no-newline.txt',
141
- '+++ b/delete-eof-no-newline.txt',
142
- '@@ -2,1 +2,0 @@',
143
- '-b',
144
- '\',
145
- ]), 'a\n');
146
-
147
- await writeFile(join(dir, 'insert.txt'), 'a\nc\n', 'utf8');
148
- await patchAndCheck('insert only', 'insert.txt', patchText([
149
- '--- a/insert.txt',
150
- '+++ b/insert.txt',
151
- '@@ -1,0 +2,1 @@',
152
- '+b',
153
- ]), 'a\nb\nc\n');
154
-
155
- await writeFile(join(dir, 'crlf-insert.txt'), 'a\r\nc\r\n', 'utf8');
156
- await patchAndCheck('crlf insert only', 'crlf-insert.txt', patchText([
157
- '--- a/crlf-insert.txt',
158
- '+++ b/crlf-insert.txt',
159
- '@@ -1,0 +2,1 @@',
160
- '+b',
161
- ]), 'a\r\nb\r\nc\r\n');
162
-
163
- await writeFile(join(dir, 'v4a-update.txt'), 'class Foo\n function bar\n const x = 1;\n return x;\n', 'utf8');
164
- const v4aUpdate = await executePatchTool('apply_patch', { patch: patchText([
165
- '*** Begin Patch',
166
- '*** Update File: "v4a-update.txt"\t2026-05-21',
167
- '@@ class Foo',
168
- '@@ function bar',
169
- ' const x = 1;',
170
- '- return x;',
171
- '+ return x + 1;',
172
- '*** End Patch',
173
- ]), base_path: dir }, dir, { readStateScope: 'patch-v4a-update' });
174
- assertOk('patch v4a update', v4aUpdate);
175
- await expectFile('v4a-update.txt', 'class Foo\n function bar\n const x = 1;\n return x + 1;\n');
176
-
177
- // V4A real paths under a top-level `a/` or `b/` directory must not be
178
- // diff-prefix-stripped (those prefixes are a unified-diff convention only).
179
- // Regression: stripping rewrote `a/foo.txt` -> `foo.txt`, hitting the wrong
180
- // file (ENOENT on update, phantom create on add).
181
- await mkdir(join(dir, 'a'), { recursive: true });
182
- await writeFile(join(dir, 'a', 'v4a-ab.txt'), 'class Foo\n const x = 1;\n return x;\n', 'utf8');
183
- const v4aTopLevelA = await executePatchTool('apply_patch', { patch: patchText([
184
- '*** Begin Patch',
185
- '*** Update File: a/v4a-ab.txt',
186
- '@@ class Foo',
187
- ' const x = 1;',
188
- '- return x;',
189
- '+ return x + 1;',
190
- '*** End Patch',
191
- ]), base_path: dir }, dir, { readStateScope: 'patch-v4a-toplevel-a' });
192
- assertOk('patch v4a update under top-level a/', v4aTopLevelA);
193
- await expectFile(join('a', 'v4a-ab.txt'), 'class Foo\n const x = 1;\n return x + 1;\n');
194
- assertNotHas('no phantom strip of top-level a/', v4aTopLevelA, 'unreadable');
195
- await mkdir(join(dir, 'b'), { recursive: true });
196
- const v4aTopLevelB = await executePatchTool('apply_patch', { patch: patchText([
197
- '*** Begin Patch',
198
- '*** Add File: b/v4a-new.txt',
199
- '+hello',
200
- '+world',
201
- '*** End Patch',
202
- ]), base_path: dir }, dir, { readStateScope: 'patch-v4a-toplevel-b' });
203
- assertOk('patch v4a add under top-level b/', v4aTopLevelB);
204
- await expectFile(join('b', 'v4a-new.txt'), 'hello\nworld\n');
205
-
206
- await writeFile(join(dir, 'v4a-tolerant-context.txt'), 'function pick\nconst x = 1;\nreturn x;\n', 'utf8');
207
- const v4aTolerantContext = await executePatchTool('apply_patch', { patch: patchText([
208
- '*** Begin Patch',
209
- '*** Update File: v4a-tolerant-context.txt',
210
- '@@ function pick @@',
211
- 'const x = 1;',
212
- '-return x;',
213
- '+return x + 1;',
214
- '*** End Patch',
215
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-tolerant-context' });
216
- assertOk('patch v4a accepts trailing anchor marker and bare context', v4aTolerantContext);
217
- await expectFile('v4a-tolerant-context.txt', 'function pick\nconst x = 1;\nreturn x + 1;\n');
218
-
219
- await writeFile(join(dir, 'v4a-js-syntax.mjs'), [
220
- 'export function pick(ok) {',
221
- ' if (ok) {',
222
- ' return 1;',
223
- ' }',
224
- ' return 0;',
225
- '}',
226
- '',
227
- ].join('\n'), 'utf8');
228
- const v4aSyntax = await executePatchTool('apply_patch', { patch: patchText([
229
- '*** Begin Patch',
230
- '*** Update File: v4a-js-syntax.mjs',
231
- '@@ function pick',
232
- ' if (ok) {',
233
- '- return 1;',
234
- '+ return 2;',
235
- ' }',
236
- '*** End Patch',
237
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-js-syntax' });
238
- assertOk('patch v4a keeps js syntax', v4aSyntax);
239
- await expectFile('v4a-js-syntax.mjs', [
240
- 'export function pick(ok) {',
241
- ' if (ok) {',
242
- ' return 2;',
243
- ' }',
244
- ' return 0;',
245
- '}',
246
- '',
247
- ].join('\n'));
248
- expectNodeCheck('v4a-js-syntax.mjs');
249
-
250
- await writeFile(join(dir, 'v4a-reject-no-partial.mjs'), 'export function f() {\n return 1;\n}\n', 'utf8');
251
- let v4aReject;
252
- try {
253
- v4aReject = await executePatchTool('apply_patch', { patch: patchText([
254
- '*** Begin Patch',
255
- '*** Update File: v4a-reject-no-partial.mjs',
256
- '@@ function f',
257
- '- return missing;',
258
- '+ return 2;',
259
- '*** End Patch',
260
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-reject-no-partial' });
261
- } catch (err) {
262
- v4aReject = `Error: ${err?.message || String(err)}`;
263
- }
264
- assertError('patch v4a rejects missing context', v4aReject);
265
- assertHas('patch v4a missing context hint includes expected line', v4aReject, 'expected first old line');
266
- assertHas('patch v4a missing context hint includes nearest line', v4aReject, 'nearest line');
267
- await expectFile('v4a-reject-no-partial.mjs', 'export function f() {\n return 1;\n}\n');
268
- expectNodeCheck('v4a-reject-no-partial.mjs');
269
-
270
- await writeFile(join(dir, 'v4a-insert.txt'), 'class Foo\n function bar\n return x;\n', 'utf8');
271
- const v4aInsert = await executePatchTool('apply_patch', { patch: patchText([
272
- '*** Begin Patch',
273
- '*** Update File: v4a-insert.txt',
274
- '@@ function bar',
275
- '+ const y = 2;',
276
- '*** End Patch',
277
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-insert' });
278
- assertOk('patch v4a insert', v4aInsert);
279
- await expectFile('v4a-insert.txt', 'class Foo\n function bar\n const y = 2;\n return x;\n');
280
-
281
- await writeFile(join(dir, 'v4a-missing-anchor-insert.txt'), 'class Foo\n function bar\n return x;\n', 'utf8');
282
- let v4aMissingAnchorInsert;
283
- try {
284
- v4aMissingAnchorInsert = await executePatchTool('apply_patch', { patch: patchText([
285
- '*** Begin Patch',
286
- '*** Update File: v4a-missing-anchor-insert.txt',
287
- '@@ function missing',
288
- '+ const nope = true;',
289
- '*** End Patch',
290
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-missing-anchor-insert' });
291
- } catch (err) {
292
- v4aMissingAnchorInsert = `Error: ${err?.message || String(err)}`;
293
- }
294
- assertError('patch v4a missing anchor insert rejects', v4aMissingAnchorInsert);
295
- assertHas('patch v4a missing anchor insert guidance', v4aMissingAnchorInsert, 'anchor not found');
296
- assertHas('patch v4a missing anchor nearest guidance', v4aMissingAnchorInsert, 'nearest anchor candidate');
297
- assertHas('patch v4a missing anchor nearest line', v4aMissingAnchorInsert, 'function bar');
298
- await expectFile('v4a-missing-anchor-insert.txt', 'class Foo\n function bar\n return x;\n');
299
-
300
- await writeFile(join(dir, 'bare-unified-anchor.txt'), 'class Foo\n function bar\n return x;\n', 'utf8');
301
- const bareUnifiedAnchor = await executePatchTool('apply_patch', { patch: patchText([
302
- '--- a/bare-unified-anchor.txt',
303
- '+++ b/bare-unified-anchor.txt',
304
- '@@ function bar',
305
- '- return x;',
306
- '+ return x + 2;',
307
- ]), base_path: dir }, dir, { readStateScope: 'patch-bare-unified-anchor' });
308
- assertOk('patch bare unified anchor', bareUnifiedAnchor);
309
- await expectFile('bare-unified-anchor.txt', 'class Foo\n function bar\n return x + 2;\n');
310
-
311
- let strictBareUnified;
312
- try {
313
- strictBareUnified = await executePatchTool('apply_patch', { patch: patchText([
314
- '--- a/bare-unified-anchor.txt',
315
- '+++ b/bare-unified-anchor.txt',
316
- '@@ function bar',
317
- '- return x + 2;',
318
- '+ return x + 3;',
319
- ]), base_path: dir, format: 'unified' }, dir, { readStateScope: 'patch-strict-bare-unified' });
320
- } catch (err) {
321
- strictBareUnified = `Error: ${err?.message || String(err)}`;
322
- }
323
- assertError('patch strict unified bare hunk guidance rejects', strictBareUnified);
324
- assertHas('patch strict unified bare hunk counted hint', strictBareUnified, '@@ -A,B +C,D @@');
325
- assertNotHas('patch strict unified bare hunk v4a hint removed', strictBareUnified, 'remove format:"unified"');
326
- await expectFile('bare-unified-anchor.txt', 'class Foo\n function bar\n return x + 2;\n');
327
-
328
- await writeFile(join(dir, 'unified-nearest-hint.txt'), 'alpha\nbeta current\ngamma\n', 'utf8');
329
- const unifiedNearestHint = await executePatchTool('apply_patch', { patch: patchText([
330
- '--- a/unified-nearest-hint.txt',
331
- '+++ b/unified-nearest-hint.txt',
332
- '@@ -2,1 +2,1 @@',
333
- '-beta stale',
334
- '+beta done',
335
- ]), base_path: dir, reject_partial: false }, dir, { readStateScope: 'patch-unified-nearest-hint' });
336
- assertError('patch unified hunk nearest hint rejects', unifiedNearestHint);
337
- assertHas('patch unified hunk nearest expected line', unifiedNearestHint, 'expected first old/context line');
338
- assertHas('patch unified hunk nearest current line', unifiedNearestHint, 'nearest line 2');
339
- await expectFile('unified-nearest-hint.txt', 'alpha\nbeta current\ngamma\n');
340
-
341
- await writeFile(join(dir, 'dry-run-context-preview.txt'), 'actual\n', 'utf8');
342
- const dryRunContextPreview = await executePatchTool('apply_patch', { patch: patchText([
343
- '--- a/dry-run-context-preview.txt',
344
- '+++ b/dry-run-context-preview.txt',
345
- '@@ -1,1 +1,2 @@',
346
- ' stale context',
347
- '+inserted',
348
- ]), base_path: dir, dry_run: true, fuzzy: false, reject_partial: false }, dir, { readStateScope: 'patch-dry-run-context-preview' });
349
- assertError('patch dry-run context mismatch reports without writing', dryRunContextPreview);
350
- assertHas('patch dry-run context mismatch expected line', dryRunContextPreview, 'expected first old/context line');
351
- assertHas('patch dry-run context mismatch context line', dryRunContextPreview, 'stale context');
352
- assertHas('patch dry-run context mismatch current line marker', dryRunContextPreview, 'nearest line 1');
353
- assertHas('patch dry-run context mismatch current line', dryRunContextPreview, 'actual');
354
- assertNotHas('patch dry-run context mismatch retry block removed', dryRunContextPreview, '*** Update File: dry-run-context-preview.txt');
355
- assertNotHas('patch dry-run context mismatch retry hint removed', dryRunContextPreview, 'read({path,line,context})');
356
- await expectFile('dry-run-context-preview.txt', 'actual\n');
357
-
358
- const bareUnifiedAdd = await executePatchTool('apply_patch', { patch: patchText([
359
- '--- /dev/null',
360
- '+++ b/bare-unified-add.txt',
361
- '@@',
362
- '+made',
363
- ]), base_path: dir }, dir, { readStateScope: 'patch-bare-unified-add' });
364
- assertOk('patch bare unified add', bareUnifiedAdd);
365
- await expectFile('bare-unified-add.txt', 'made\n');
366
-
367
- await writeFile(join(dir, 'bare-unified-delete.txt'), 'remove\nme\n', 'utf8');
368
- const bareUnifiedDelete = await executePatchTool('apply_patch', { patch: patchText([
369
- '--- a/bare-unified-delete.txt',
370
- '+++ /dev/null',
371
- '@@',
372
- '-remove',
373
- '-me',
374
- ]), base_path: dir }, dir, { readStateScope: 'patch-bare-unified-delete' });
375
- assertOk('patch bare unified delete', bareUnifiedDelete);
376
- try {
377
- await readFile(join(dir, 'bare-unified-delete.txt'), 'utf8');
378
- throw new Error('bare unified delete left file on disk');
379
- } catch (err) {
380
- if (err?.code !== 'ENOENT') throw err;
381
- }
382
-
383
- const v4aAdd = await executePatchTool('apply_patch', { patch: patchText([
384
- '*** Begin Patch',
385
- '*** Add File: v4a-add.txt',
386
- '+hello',
387
- '+',
388
- '+world',
389
- '*** End Patch',
390
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-add' });
391
- assertOk('patch v4a add', v4aAdd);
392
- await expectFile('v4a-add.txt', 'hello\n\nworld\n');
393
-
394
- await writeFile(join(dir, 'v4a-empty-delete.txt'), '', 'utf8');
395
- const v4aDeleteEmpty = await executePatchTool('apply_patch', { patch: patchText([
396
- '*** Begin Patch',
397
- '*** Delete File: v4a-empty-delete.txt',
398
- '*** End Patch',
399
- ]), base_path: dir, format: 'v4a' }, dir, { readStateScope: 'patch-v4a-delete-empty' });
400
- assertOk('patch v4a empty delete', v4aDeleteEmpty);
401
- try {
402
- await readFile(join(dir, 'v4a-empty-delete.txt'), 'utf8');
403
- throw new Error('v4a empty delete left file on disk');
404
- } catch (err) {
405
- if (err?.code !== 'ENOENT') throw err;
406
- }
407
-
408
- await writeFile(join(dir, 'unified-empty-delete.txt'), '', 'utf8');
409
- const unifiedEmptyDelete = await executePatchTool('apply_patch', { patch: patchText([
410
- '--- a/unified-empty-delete.txt',
411
- '+++ /dev/null',
412
- '@@ -1,0 +0,0 @@',
413
- ]), base_path: dir }, dir, { readStateScope: 'patch-unified-empty-delete' });
414
- assertOk('patch unified zero-length empty delete', unifiedEmptyDelete);
415
- try {
416
- await readFile(join(dir, 'unified-empty-delete.txt'), 'utf8');
417
- throw new Error('unified empty delete left file on disk');
418
- } catch (err) {
419
- if (err?.code !== 'ENOENT') throw err;
420
- }
421
-
422
- await writeFile(join(dir, 'unified-nonempty-zero-delete.txt'), 'still here\n', 'utf8');
423
- const unifiedNonemptyZeroDelete = await executePatchTool('apply_patch', { patch: patchText([
424
- '--- a/unified-nonempty-zero-delete.txt',
425
- '+++ /dev/null',
426
- '@@ -1,0 +0,0 @@',
427
- ]), base_path: dir }, dir, { readStateScope: 'patch-unified-nonempty-zero-delete' });
428
- assertError('patch unified zero-length non-empty delete rejects', unifiedNonemptyZeroDelete);
429
- assertHas('patch unified zero-length non-empty delete residual hint', unifiedNonemptyZeroDelete, 'residual byte');
430
- await expectFile('unified-nonempty-zero-delete.txt', 'still here\n');
431
-
432
- await writeFile(join(dir, 'mf-a.txt'), 'a\nb\n', 'utf8');
433
- await writeFile(join(dir, 'mf-b.txt'), 'x\ny\n', 'utf8');
434
- const multifileOut = await executePatchTool('apply_patch', { patch: patchText([
435
- '--- a/mf-a.txt',
436
- '+++ b/mf-a.txt',
437
- '@@ -2,1 +2,1 @@',
438
- '-b',
439
- '+B',
440
- '--- a/mf-b.txt',
441
- '+++ b/mf-b.txt',
442
- '@@ -2,1 +2,1 @@',
443
- '-y',
444
- '+Y',
445
- ]), base_path: dir }, dir, { readStateScope: 'patch-multifile' });
446
- assertOk('patch multifile', multifileOut);
447
- await expectFile('mf-a.txt', 'a\nB\n');
448
- await expectFile('mf-b.txt', 'x\nY\n');
449
-
450
- await writeFile(join(dir, 'patch-edit-chain.txt'), 'before\nneedle\n', 'utf8');
451
- const patchEditScope = 'patch-edit-chain';
452
- assertOk('patch edit chain patch', await executePatchTool('apply_patch', {
453
- patch: patchText([
454
- '--- a/patch-edit-chain.txt',
455
- '+++ b/patch-edit-chain.txt',
456
- '@@ -1,2 +1,2 @@',
457
- '-before',
458
- '+after',
459
- ' needle',
460
- ]),
461
- base_path: dir,
462
- reject_partial: false,
463
- }, dir, { readStateScope: patchEditScope }));
464
- assertOk('patch edit chain edit', await executeBuiltinTool('edit', {
465
- path: 'patch-edit-chain.txt',
466
- old_string: 'needle',
467
- new_string: 'done',
468
- }, dir, { readStateScope: patchEditScope }));
469
- await expectFile('patch-edit-chain.txt', 'after\ndone\n');
470
-
471
- await writeFile(join(dir, 'delete-snapshot.txt'), 'same\n', 'utf8');
472
- await warmRead('delete-snapshot.txt', 'patch-delete-snapshot');
473
- const deleteSnapshotOut = await executePatchTool('apply_patch', { patch: patchText([
474
- '--- a/delete-snapshot.txt',
475
- '+++ /dev/null',
476
- '@@ -1,1 +0,0 @@',
477
- '-same',
478
- ]), base_path: dir }, dir, { readStateScope: 'patch-delete-snapshot' });
479
- assertOk('patch delete clears snapshot', deleteSnapshotOut);
480
- await writeFile(join(dir, 'delete-snapshot.txt'), 'same\n', 'utf8');
481
- const staleWrite = await executeBuiltinTool('write', {
482
- path: 'delete-snapshot.txt',
483
- content: 'clobbered\n',
484
- }, dir, { readStateScope: 'patch-delete-snapshot' });
485
- assertError('deleted file snapshot cleared before overwrite', staleWrite, 'Error [code 6]');
486
- await expectFile('delete-snapshot.txt', 'same\n');
487
-
488
- assertOk('write seeds edit snapshot/cache', await executeBuiltinTool('write', {
489
- path: 'write-edit-cache.txt',
490
- content: 'alpha\nbeta\ngamma\n',
491
- }, dir, { readStateScope: 'write-edit-cache' }));
492
- assertOk('edit after write without read', await executeBuiltinTool('edit', {
493
- path: 'write-edit-cache.txt',
494
- old_string: 'beta',
495
- new_string: 'BETA',
496
- }, dir, { readStateScope: 'write-edit-cache' }));
497
- await expectFile('write-edit-cache.txt', 'alpha\nBETA\ngamma\n');
498
-
499
- await writeFile(join(dir, 'read-edit-invalidate.txt'), 'one\ntwo\nthree\n', 'utf8');
500
- const readEditBefore = await executeBuiltinTool('read', {
501
- path: 'read-edit-invalidate.txt',
502
- offset: 1,
503
- limit: 1,
504
- }, dir, { readStateScope: 'read-edit-invalidate' });
505
- assertHas('read before edit cache seed', readEditBefore, `2${LINE_SEP}two`);
506
- assertOk('edit invalidates same read cache key', await executeBuiltinTool('edit', {
507
- path: 'read-edit-invalidate.txt',
508
- old_string: 'two',
509
- new_string: 'TWO',
510
- }, dir, { readStateScope: 'read-edit-invalidate' }));
511
- const readEditAfter = await executeBuiltinTool('read', {
512
- path: 'read-edit-invalidate.txt',
513
- offset: 1,
514
- limit: 1,
515
- }, dir, { readStateScope: 'read-edit-invalidate' });
516
- assertHas('read after edit sees fresh content', readEditAfter, `2${LINE_SEP}TWO`);
517
- if (String(readEditAfter).includes(`2${LINE_SEP}two`)) {
518
- throw new Error(`read cache returned stale pre-edit content:\n${readEditAfter}`);
519
- }
520
-
521
- await writeFile(join(dir, 'read-patch-invalidate.txt'), 'one\ntwo\nthree\n', 'utf8');
522
- const readPatchBefore = await executeBuiltinTool('read', {
523
- path: 'read-patch-invalidate.txt',
524
- offset: 1,
525
- limit: 1,
526
- }, dir, { readStateScope: 'read-patch-invalidate' });
527
- assertHas('read before patch cache seed', readPatchBefore, `2${LINE_SEP}two`);
528
- assertOk('apply_patch invalidates same read cache key', await executePatchTool('apply_patch', {
529
- patch: patchText([
530
- '--- a/read-patch-invalidate.txt',
531
- '+++ b/read-patch-invalidate.txt',
532
- '@@ -2,1 +2,1 @@',
533
- '-two',
534
- '+TWO',
535
- ]),
536
- base_path: dir,
537
- }, dir, { readStateScope: 'read-patch-invalidate' }));
538
- const readPatchAfter = await executeBuiltinTool('read', {
539
- path: 'read-patch-invalidate.txt',
540
- offset: 1,
541
- limit: 1,
542
- }, dir, { readStateScope: 'read-patch-invalidate' });
543
- assertHas('read after patch sees fresh content', readPatchAfter, `2${LINE_SEP}TWO`);
544
- if (String(readPatchAfter).includes(`2${LINE_SEP}two`)) {
545
- throw new Error(`read cache returned stale pre-patch content:\n${readPatchAfter}`);
546
- }
547
-
548
- assertOk('batch write seeds edit snapshot/cache', await executeBuiltinTool('write', {
549
- writes: [
550
- { path: 'batch-write-cache-a.txt', content: 'one\ntwo\n' },
551
- { path: 'batch-write-cache-b.txt', content: 'red\nblue\n' },
552
- ],
553
- }, dir, { readStateScope: 'batch-write-cache' }));
554
- assertOk('edit after batch write without read', await executeBuiltinTool('edit', {
555
- path: 'batch-write-cache-b.txt',
556
- old_string: 'blue',
557
- new_string: 'BLUE',
558
- }, dir, { readStateScope: 'batch-write-cache' }));
559
- await expectFile('batch-write-cache-b.txt', 'red\nBLUE\n');
560
-
561
- await writeFile(join(dir, 'io-cache-stress.txt'), 'alpha\nbeta\ngamma\n', 'utf8');
562
- const stressScope = 'io-cache-stress';
563
- const stressRead = await executeBuiltinTool('read', { path: 'io-cache-stress.txt' }, dir, { readStateScope: stressScope });
564
- assertHas('stress read seeds snapshot', stressRead, `2${LINE_SEP}beta`);
565
- assertOk('stress edit invalidates cache', await executeBuiltinTool('edit', {
566
- path: 'io-cache-stress.txt',
567
- old_string: 'beta',
568
- new_string: 'BETA',
569
- }, dir, { readStateScope: stressScope }));
570
- assertOk('stress patch after edit', await executePatchTool('apply_patch', { patch: patchText([
571
- '--- a/io-cache-stress.txt',
572
- '+++ b/io-cache-stress.txt',
573
- '@@ -3,1 +3,1 @@',
574
- '-gamma',
575
- '+GAMMA',
576
- ]), base_path: dir }, dir, { readStateScope: stressScope }));
577
- const stressAfterPatch = await executeBuiltinTool('read', {
578
- path: 'io-cache-stress.txt',
579
- offset: 0,
580
- limit: 3,
581
- }, dir, { readStateScope: stressScope });
582
- assertHas('stress read after patch fresh', stressAfterPatch, `3${LINE_SEP}GAMMA`);
583
- assertOk('stress write after patch snapshot', await executeBuiltinTool('write', {
584
- path: 'io-cache-stress.txt',
585
- content: 'final\n',
586
- }, dir, { readStateScope: stressScope }));
587
- const stressFinal = await executeBuiltinTool('read', { path: 'io-cache-stress.txt' }, dir, { readStateScope: stressScope });
588
- assertHas('stress final read fresh', stressFinal, `1${LINE_SEP}final`);
589
-
590
- await writeFile(join(dir, 'dry-run-keeps-cache.txt'), 'target\n', 'utf8');
591
- assertOk('dry-run cache warm read', await executeBuiltinTool('read', { path: 'dry-run-keeps-cache.txt' }, dir, { readStateScope: 'dry-run-keeps-cache' }));
592
- assertOk('dry-run does not write', await executePatchTool('apply_patch', { patch: patchText([
593
- '--- a/dry-run-keeps-cache.txt',
594
- '+++ b/dry-run-keeps-cache.txt',
595
- '@@ -1,1 +1,1 @@',
596
- '-target',
597
- '+DRY-RUN',
598
- ]), base_path: dir, dry_run: true }, dir, { readStateScope: 'dry-run-keeps-cache' }));
599
- assertOk('edit still works after dry-run', await executeBuiltinTool('edit', {
600
- path: 'dry-run-keeps-cache.txt',
601
- old_string: 'target',
602
- new_string: 'DONE',
603
- }, dir, { readStateScope: 'dry-run-keeps-cache' }));
604
- await expectFile('dry-run-keeps-cache.txt', 'DONE\n');
605
-
606
- const readMissingPath = await executeBuiltinTool('read', {}, dir, { readStateScope: 'read-missing-path' });
607
- assertError('read missing path concise', readMissingPath);
608
- assertNotHas('read missing path no call shape', readMissingPath, 'read({path');
609
- const editMissingPath = await executeBuiltinTool('edit', {
610
- old_string: 'x',
611
- new_string: 'y',
612
- }, dir, { readStateScope: 'edit-missing-path' });
613
- assertError('edit missing path concise', editMissingPath);
614
- assertNotHas('edit missing path no call shape', editMissingPath, 'edit({path');
615
-
616
- await writeFile(join(dir, 'glob-async-stat.js'), 'console.log("ok");\n', 'utf8');
617
- await writeFile(join(dir, 'glob-async-stat.txt'), 'nope\n', 'utf8');
618
- const globOut = await executeBuiltinTool('glob', {
619
- pattern: '*.js',
620
- path: dir,
621
- head_limit: 5,
622
- }, dir, { readStateScope: 'glob-async-stat' });
623
- assertOk('glob async stat path', globOut);
624
- assertHas('glob async stat result', globOut, 'glob-async-stat.js');
625
-
626
- const grepLines = Array.from({ length: 300 }, (_, i) => `needle-${i + 1}`).join('\n') + '\n';
627
- await writeFile(join(dir, 'grep-window.txt'), grepLines, 'utf8');
628
- const grepWindow = await executeBuiltinTool('grep', {
629
- pattern: 'needle',
630
- path: 'grep-window.txt',
631
- output_mode: 'content',
632
- head_limit: 5,
633
- }, dir, { readStateScope: 'grep-window' });
634
- assertOk('grep windowed stream', grepWindow);
635
- assertHas('grep windowed first result', grepWindow, 'needle-1');
636
- assertHas('grep windowed more-matches truncation', grepWindow, 'more matches exist');
637
- assertHas('grep windowed count-mode hint', grepWindow, "output_mode:'count'");
638
- if (String(grepWindow).includes('needle-200')) {
639
- throw new Error('grep windowed stream collected far beyond the requested window');
640
- }
641
- const grepMissingPattern = await executeBuiltinTool('grep', {
642
- path: dir,
643
- }, dir, { readStateScope: 'grep-missing-pattern' });
644
- assertError('grep missing pattern concise', grepMissingPattern, 'Error: grep requires pattern');
645
- assertNotHas('grep missing pattern no example', grepMissingPattern, 'grep({ pattern');
646
- const grepMissingPath = await executeBuiltinTool('grep', {
647
- pattern: 'needle',
648
- path: 'missing-root',
649
- }, dir, { readStateScope: 'grep-missing-path' });
650
- assertError('grep missing path concise', grepMissingPath, 'Error: path does not exist');
651
- assertNotHas('grep missing path no existing-root hint', grepMissingPath, 'existing search root');
652
- assertNotHas('grep missing path no next-call example', grepMissingPath, 'grep({pattern:"needle"');
653
- await writeFile(join(dir, 'grep-quote-minimal.txt'), 'quoteNeedle\nregexNeedle\n', 'utf8');
654
- const grepQuotedPattern = await executeBuiltinTool('grep', {
655
- pattern: "'quoteNeedle'",
656
- path: 'grep-quote-minimal.txt',
657
- output_mode: 'content',
658
- }, dir, { readStateScope: 'grep-quoted-pattern' });
659
- assertOk('grep quoted pattern no-match minimal', grepQuotedPattern);
660
- assertHas('grep quoted pattern no-match marker', grepQuotedPattern, '(no matches)');
661
- assertNotHas('grep quoted pattern no hint', grepQuotedPattern, 'without surrounding quotes');
662
- const grepRegexLiteralPattern = await executeBuiltinTool('grep', {
663
- pattern: '/regexNeedle/',
664
- path: 'grep-quote-minimal.txt',
665
- output_mode: 'content',
666
- }, dir, { readStateScope: 'grep-regex-literal-pattern' });
667
- assertOk('grep regex literal no-match minimal', grepRegexLiteralPattern);
668
- assertNotHas('grep regex literal no hint', grepRegexLiteralPattern, 'without slashes or flags');
669
- const grepUnknownType = await executeBuiltinTool('grep', {
670
- pattern: 'quoteNeedle',
671
- path: 'grep-quote-minimal.txt',
672
- type: 'definitely-not-a-type',
673
- }, dir, { readStateScope: 'grep-unknown-type' });
674
- assertError('grep unknown type concise', grepUnknownType);
675
- assertNotHas('grep unknown type no glob alternative', grepUnknownType, 'glob:"*.mjs"');
676
- await mkdir(join(dir, 'scripts'));
677
- await writeFile(join(dir, 'scripts', 'one.mjs'), 'needle via path glob\n', 'utf8');
678
- const grepGlobPath = await executeBuiltinTool('grep', {
679
- pattern: 'needle',
680
- path: 'scripts/*.mjs',
681
- output_mode: 'content',
682
- }, dir, { readStateScope: 'grep-glob-path' });
683
- assertOk('grep path glob auto-lift', grepGlobPath);
684
- assertHas('grep path glob auto-lift result', grepGlobPath, 'needle via path glob');
685
- const grepGlobFallback = await executeBuiltinTool('grep', {
686
- path: 'scripts/*.mjs',
687
- }, dir, { readStateScope: 'grep-glob-fallback' });
688
- assertError('grep path glob without pattern stays strict', grepGlobFallback, 'Error: grep requires pattern');
689
- const globPathFallback = await executeBuiltinTool('glob', {
690
- path: 'scripts/*.mjs',
691
- head_limit: 5,
692
- }, dir, { readStateScope: 'glob-path-fallback' });
693
- assertOk('glob path fallback', globPathFallback);
694
- assertHas('glob path fallback result', globPathFallback, 'scripts/one.mjs');
695
- const globQuotedPattern = await executeBuiltinTool('glob', {
696
- pattern: "'*.mjs'",
697
- path: 'scripts',
698
- head_limit: 5,
699
- }, dir, { readStateScope: 'glob-quoted-pattern' });
700
- assertOk('glob quoted pattern no-files minimal', globQuotedPattern);
701
- assertHas('glob quoted pattern marker', globQuotedPattern, '(no files found)');
702
- assertNotHas('glob quoted pattern no hint', globQuotedPattern, 'without surrounding quotes');
703
- const globCommaPattern = await executeBuiltinTool('glob', {
704
- pattern: '*.mjs,*.txt',
705
- path: 'scripts',
706
- head_limit: 5,
707
- }, dir, { readStateScope: 'glob-comma-pattern' });
708
- assertOk('glob comma pattern no-files minimal', globCommaPattern);
709
- assertNotHas('glob comma pattern no hint', globCommaPattern, 'pattern array or brace glob');
710
- const globMissingPath = await executeBuiltinTool('glob', {
711
- pattern: '*.mjs',
712
- path: 'missing-scripts',
713
- head_limit: 5,
714
- }, dir, { readStateScope: 'glob-missing-path' });
715
- assertError('glob missing path concise', globMissingPath, 'Error: path does not exist');
716
- assertNotHas('glob missing path no existing-root hint', globMissingPath, 'existing base directory');
717
- assertNotHas('glob missing path no next-call example', globMissingPath, 'glob({pattern:"*.mjs"');
718
- const findPathFallback = await executeBuiltinTool('list', {
719
- mode: 'find',
720
- path: 'scripts/*.mjs',
721
- type: 'file',
722
- head_limit: 5,
723
- }, dir, { readStateScope: 'find-path-fallback' });
724
- assertOk('find_files path fallback', findPathFallback);
725
- assertHas('find_files path fallback result', findPathFallback, 'scripts/one.mjs');
726
- const listPathFallback = await executeBuiltinTool('list', {
727
- path: 'scripts/*.mjs',
728
- type: 'file',
729
- head_limit: 5,
730
- }, dir, { readStateScope: 'list-path-fallback' });
731
- assertOk('list path glob fallback', listPathFallback);
732
- assertHas('list path glob fallback result', listPathFallback, 'scripts/one.mjs');
733
- await mkdir(join(dir, 'scripts', 'sub'));
734
- await writeFile(join(dir, 'scripts', 'sub', 'two.mjs'), 'nested\n', 'utf8');
735
- const listRecursivePathFallback = await executeBuiltinTool('list', {
736
- path: 'scripts/**/*.mjs',
737
- type: 'file',
738
- head_limit: 10,
739
- }, dir, { readStateScope: 'list-recursive-path-fallback' });
740
- assertOk('list recursive path glob fallback', listRecursivePathFallback);
741
- assertHas('list recursive path glob root result', listRecursivePathFallback, 'scripts/one.mjs');
742
- assertHas('list recursive path glob nested result', listRecursivePathFallback, 'scripts/sub/two.mjs');
743
- await Promise.all(Array.from({ length: 20 }, (_, i) =>
744
- writeFile(join(dir, `grep-count-${String(i + 1).padStart(2, '0')}.txt`), 'countneedle\n', 'utf8')));
745
- const grepCountWindow = await executeBuiltinTool('grep', {
746
- pattern: 'countneedle',
747
- path: dir,
748
- glob: 'grep-count-*.txt',
749
- output_mode: 'count',
750
- head_limit: 5,
751
- }, dir, { readStateScope: 'grep-count-window' });
752
- assertOk('grep count windowed stream', grepCountWindow);
753
- assertHas('grep count more-matches truncation', grepCountWindow, 'more matches exist');
754
- assertHas('grep count count-mode hint', grepCountWindow, "output_mode:'count'");
755
- assertHas('grep count displayed summary', grepCountWindow, 'total 5 matches across 5 files');
756
-
757
- await writeFile(join(dir, 'find-batched-stat-a.txt'), 'a\n', 'utf8');
758
- await writeFile(join(dir, 'find-batched-stat-b.txt'), 'b\n', 'utf8');
759
- const findBatched = await executeBuiltinTool('list', {
760
- mode: 'find',
761
- path: dir,
762
- name: 'find-batched-stat-*.txt',
763
- type: 'file',
764
- head_limit: 5,
765
- }, dir, { readStateScope: 'find-batched-stat' });
766
- assertOk('find_files batched stat path', findBatched);
767
- assertHas('find_files batched stat result', findBatched, 'find-batched-stat-a.txt');
768
-
769
- const listStatDir = join(dir, 'list-batched-stat');
770
- await mkdir(listStatDir);
771
- await writeFile(join(listStatDir, 'small.txt'), 'x\n', 'utf8');
772
- await writeFile(join(listStatDir, 'large.txt'), 'x'.repeat(4096), 'utf8');
773
- const listBatched = await executeBuiltinTool('list', {
774
- path: listStatDir,
775
- type: 'file',
776
- sort: 'size',
777
- head_limit: 1,
778
- }, dir, { readStateScope: 'list-batched-stat' });
779
- assertOk('list batched stat path', listBatched);
780
- assertHas('list batched stat sorted result', listBatched.split('\n')[0], 'large.txt');
781
-
782
- await writeFile(join(dir, 'edit.txt'), 'alpha\nbeta\ngamma\n', 'utf8');
783
- await warmRead('edit.txt', 'edit');
784
- assertOk('edit byte exact', await executeBuiltinTool('edit', {
785
- path: 'edit.txt',
786
- old_string: 'beta',
787
- new_string: 'BETA',
788
- }, dir, { readStateScope: 'edit' }));
789
- await expectFile('edit.txt', 'alpha\nBETA\ngamma\n');
790
-
791
- // 0xC3 followed by a non-continuation byte: invalid UTF-8 with NO UTF-16
792
- // BOM, so the generic non-UTF-8 branch (not the BOM-aware one) is hit.
793
- const editBinaryBytes = Buffer.from([0xc3, 0x28, 0x0a, 0x61, 0x0a, 0x62, 0x0a]);
794
- await writeFile(join(dir, 'edit-binary-ish.txt'), editBinaryBytes);
795
- recordReadSnapshotForPath(join(dir, 'edit-binary-ish.txt'), 'edit-binary-ish', {
796
- source: 'test',
797
- contentHash: hashBytes(editBinaryBytes),
798
- });
799
- assertError('edit binary-ish refuses non-UTF-8', await executeBuiltinTool('edit', {
800
- path: 'edit-binary-ish.txt',
801
- old_string: 'a',
802
- new_string: 'A',
803
- }, dir, { readStateScope: 'edit-binary-ish' }), 'Error: file appears to be non-UTF-8');
804
- await expectBytes('edit-binary-ish.txt', editBinaryBytes);
805
-
806
- const editUtf16Bytes = Buffer.concat([Buffer.from([0xff, 0xfe]), Buffer.from('a\nb\n', 'utf16le')]);
807
- await writeFile(join(dir, 'edit-utf16.txt'), editUtf16Bytes);
808
- recordReadSnapshotForPath(join(dir, 'edit-utf16.txt'), 'edit-utf16', {
809
- source: 'test',
810
- contentHash: hashBytes(editUtf16Bytes),
811
- });
812
- assertError('edit utf16 refuses with BOM-aware message', await executeBuiltinTool('edit', {
813
- path: 'edit-utf16.txt',
814
- old_string: 'a',
815
- new_string: 'A',
816
- }, dir, { readStateScope: 'edit-utf16' }), 'Error: file is UTF-16LE (BOM FF FE)');
817
- await expectBytes('edit-utf16.txt', editUtf16Bytes);
818
-
819
- await writeFile(join(dir, 'edit-replace-all.txt'), 'x\nx\nx\n', 'utf8');
820
- await warmRead('edit-replace-all.txt', 'edit-replace-all');
821
- assertOk('edit replace_all byte exact', await executeBuiltinTool('edit', {
822
- path: 'edit-replace-all.txt',
823
- old_string: 'x',
824
- new_string: 'X',
825
- replace_all: true,
826
- }, dir, { readStateScope: 'edit-replace-all' }));
827
- await expectFile('edit-replace-all.txt', 'X\nX\nX\n');
828
-
829
- await writeFile(join(dir, 'edit-multi.txt'), 'left\nmiddle\nright\n', 'utf8');
830
- await warmRead('edit-multi.txt', 'edit-multi');
831
- assertOk('edit multi byte exact', await executeBuiltinTool('edit', {
832
- path: 'edit-multi.txt',
833
- edits: [
834
- { old_string: 'left', new_string: 'LEFT' },
835
- { old_string: 'right', new_string: 'RIGHT' },
836
- ],
837
- }, dir, { readStateScope: 'edit-multi' }));
838
- await expectFile('edit-multi.txt', 'LEFT\nmiddle\nRIGHT\n');
839
-
840
- const multiBinaryBytes = Buffer.from([0xc3, 0x28, 0x0a, 0x6c, 0x65, 0x66, 0x74, 0x0a, 0x72, 0x69, 0x67, 0x68, 0x74, 0x0a]);
841
- await writeFile(join(dir, 'edit-multi-binary-ish.txt'), multiBinaryBytes);
842
- recordReadSnapshotForPath(join(dir, 'edit-multi-binary-ish.txt'), 'edit-multi-binary-ish', {
843
- source: 'test',
844
- contentHash: hashBytes(multiBinaryBytes),
845
- });
846
- assertError('edit multi binary-ish refuses non-UTF-8', await executeBuiltinTool('edit', {
847
- path: 'edit-multi-binary-ish.txt',
848
- edits: [
849
- { old_string: 'left', new_string: 'LEFT' },
850
- { old_string: 'right', new_string: 'RIGHT' },
851
- ],
852
- }, dir, { readStateScope: 'edit-multi-binary-ish' }), 'Error: file appears to be non-UTF-8');
853
- await expectBytes('edit-multi-binary-ish.txt', multiBinaryBytes);
854
-
855
- const multiBinaryMissBytes = Buffer.from([0xc3, 0x28, 0x0a, 0x61, 0x0a]);
856
- await writeFile(join(dir, 'edit-multi-binary-miss.txt'), multiBinaryMissBytes);
857
- recordReadSnapshotForPath(join(dir, 'edit-multi-binary-miss.txt'), 'edit-multi-binary-miss', {
858
- source: 'test',
859
- contentHash: hashBytes(multiBinaryMissBytes),
860
- });
861
- const multiBinaryMiss = await executeBuiltinTool('edit', {
862
- path: 'edit-multi-binary-miss.txt',
863
- edits: [
864
- { old_string: 'missing', new_string: 'MISSING' },
865
- ],
866
- }, dir, { readStateScope: 'edit-multi-binary-miss' });
867
- assertError('edit multi binary-ish fallback reject', multiBinaryMiss, 'Error: file appears to be non-UTF-8');
868
- await expectBytes('edit-multi-binary-miss.txt', multiBinaryMissBytes);
869
-
870
- await writeFile(join(dir, 'edit-crlf-multi.txt'), 'a\r\nb\r\nc\r\n', 'utf8');
871
- await warmRead('edit-crlf-multi.txt', 'edit-crlf-multi');
872
- assertOk('edit crlf multi byte exact', await executeBuiltinTool('edit', {
873
- path: 'edit-crlf-multi.txt',
874
- edits: [
875
- { old_string: 'a', new_string: 'A' },
876
- { old_string: 'c', new_string: 'C' },
877
- ],
878
- }, dir, { readStateScope: 'edit-crlf-multi' }));
879
- await expectFile('edit-crlf-multi.txt', 'A\r\nb\r\nC\r\n');
880
-
881
- await writeFile(join(dir, 'edit-overlap.txt'), 'abcde\n', 'utf8');
882
- await warmRead('edit-overlap.txt', 'edit-overlap');
883
- const overlap = await executeBuiltinTool('edit', {
884
- path: 'edit-overlap.txt',
885
- edits: [
886
- { old_string: 'abc', new_string: 'XXX' },
887
- { old_string: 'bcd', new_string: 'YYY' },
888
- ],
889
- }, dir, { readStateScope: 'edit-overlap' });
890
- assertError('edit overlap reject', overlap, 'Error [code 8]');
891
- await expectFile('edit-overlap.txt', 'abcde\n');
892
-
893
- await writeFile(join(dir, 'partial-replace-all.txt'), 'TARGET\nseen\nmiddle\nTARGET\n', 'utf8');
894
- await warmRead('partial-replace-all.txt', 'partial-replace-all', 0, 2);
895
- const partialReplaceAll = await executeBuiltinTool('edit', {
896
- path: 'partial-replace-all.txt',
897
- old_string: 'TARGET',
898
- new_string: 'DONE',
899
- replace_all: true,
900
- }, dir, { readStateScope: 'partial-replace-all' });
901
- assertOk('partial replace_all now succeeds (read-window gate retired)', partialReplaceAll);
902
- await expectFile('partial-replace-all.txt', 'DONE\nseen\nmiddle\nDONE\n');
903
-
904
- await writeFile(join(dir, 'batch-read.txt'), Array.from({ length: 300 }, (_, i) => `line-${i + 1}`).join('\n') + '\n', 'utf8');
905
- const batchRead = await executeBuiltinTool('read', {
906
- path: [
907
- { path: 'batch-read.txt', offset: 10, limit: 3 },
908
- { path: 'batch-read.txt', offset: 40, limit: 2 },
909
- ],
910
- }, dir, { readStateScope: 'batch-read' });
911
- assertHas('batch read first slice', batchRead, `11${LINE_SEP}line-11`);
912
- assertHas('batch read second slice', batchRead, `42${LINE_SEP}line-42`);
913
- assertOk('batch read snapshot edit', await executeBuiltinTool('edit', {
914
- path: 'batch-read.txt',
915
- old_string: 'line-41',
916
- new_string: 'LINE-41',
917
- }, dir, { readStateScope: 'batch-read' }));
918
- const readLineWindow = await executeBuiltinTool('read', {
919
- path: 'batch-read.txt',
920
- line: 42,
921
- context: 1,
922
- }, dir, { readStateScope: 'read-line-window' });
923
- assertHas('read line window before', readLineWindow, `41${LINE_SEP}LINE-41`);
924
- assertHas('read line window center', readLineWindow, `42${LINE_SEP}line-42`);
925
- assertHas('read line window after', readLineWindow, `43${LINE_SEP}line-43`);
926
- const readPathLine = await executeBuiltinTool('read', {
927
- path: 'batch-read.txt:120',
928
- }, dir, { readStateScope: 'read-path-line' });
929
- assertHas('read path:line center', readPathLine, `120${LINE_SEP}line-120`);
930
- const readGrepCoordinate = await executeBuiltinTool('read', {
931
- path: 'batch-read.txt:121:line-121',
932
- context: 0,
933
- }, dir, { readStateScope: 'read-grep-coordinate' });
934
- assertHas('read grep coordinate exact line', readGrepCoordinate, `121${LINE_SEP}line-121`);
935
- const batchReadLineSpec = await executeBuiltinTool('read', {
936
- path: [
937
- { path: 'batch-read.txt:122', context: 0 },
938
- { path: 'batch-read.txt', line: 123, context: 0 },
939
- ],
940
- }, dir, { readStateScope: 'batch-read-line-spec' });
941
- assertHas('batch read path:line spec', batchReadLineSpec, `122${LINE_SEP}line-122`);
942
- assertHas('batch read line spec', batchReadLineSpec, `123${LINE_SEP}line-123`);
943
- const readHashLineRange = await executeBuiltinTool('read', {
944
- path: 'batch-read.txt#L124-L126',
945
- }, dir, { readStateScope: 'read-hash-line-range' });
946
- assertHas('read #L range start', readHashLineRange, `124${LINE_SEP}line-124`);
947
- assertHas('read #L range end', readHashLineRange, `126${LINE_SEP}line-126`);
948
- if (String(readHashLineRange).includes(`127${LINE_SEP}line-127`)) {
949
- throw new Error(`read #L range was not exact:\n${readHashLineRange}`);
950
- }
951
- const readColonLineRange = await executeBuiltinTool('read', {
952
- path: 'batch-read.txt:127-128',
953
- }, dir, { readStateScope: 'read-colon-line-range' });
954
- assertHas('read colon range start', readColonLineRange, `127${LINE_SEP}line-127`);
955
- assertHas('read colon range end', readColonLineRange, `128${LINE_SEP}line-128`);
956
-
957
- await writeFile(join(dir, 'edit-delete.txt'), 'a\nb\nc\n', 'utf8');
958
- await warmRead('edit-delete.txt', 'edit-delete');
959
- assertOk('edit delete absorb', await executeBuiltinTool('edit', {
960
- path: 'edit-delete.txt',
961
- old_string: 'b',
962
- new_string: '',
963
- }, dir, { readStateScope: 'edit-delete' }));
964
- await expectFile('edit-delete.txt', 'a\nc\n');
965
-
966
- await writeFile(join(dir, 'edit-coordinate.txt'), 'one\ntwo\nthree\n', 'utf8');
967
- await warmRead('edit-coordinate.txt', 'edit-coordinate');
968
- assertOk('edit path:line coordinate absorb', await executeBuiltinTool('edit', {
969
- path: 'edit-coordinate.txt:2',
970
- old_string: 'two',
971
- new_string: 'TWO',
972
- }, dir, { readStateScope: 'edit-coordinate' }));
973
- await expectFile('edit-coordinate.txt', 'one\nTWO\nthree\n');
974
-
975
- await writeFile(join(dir, 'multi-edit-coordinate.txt'), 'alpha\nbeta\ngamma\n', 'utf8');
976
- await warmRead('multi-edit-coordinate.txt', 'multi-edit-coordinate');
977
- assertOk('multi edit path:line coordinate absorb', await executeBuiltinTool('edit', {
978
- edits: [
979
- { path: 'multi-edit-coordinate.txt:1', old_string: 'alpha', new_string: 'ALPHA' },
980
- { path: 'multi-edit-coordinate.txt:2', old_string: 'beta', new_string: 'BETA' },
981
- ],
982
- }, dir, { readStateScope: 'multi-edit-coordinate' }));
983
- await expectFile('multi-edit-coordinate.txt', 'ALPHA\nBETA\ngamma\n');
984
-
985
- await writeFile(join(dir, 'ambig.txt'), 'x\nx\n', 'utf8');
986
- await warmRead('ambig.txt', 'ambig');
987
- const ambig = await executeBuiltinTool('edit', {
988
- path: 'ambig.txt',
989
- old_string: 'x',
990
- new_string: 'X',
991
- }, dir, { readStateScope: 'ambig' });
992
- if (!String(ambig).startsWith('Error [code 9]')) throw new Error(`ambiguous edit did not return code 9: ${ambig}`);
993
-
994
- const lines = Array.from({ length: 12000 }, (_, i) => `line-${i + 1}`).join('\n') + '\n';
995
- await writeFile(join(dir, 'large.txt'), lines, 'utf8');
996
- const firstTail = await executeBuiltinTool('read', { path: 'large.txt', offset: 8000, limit: 3 }, dir, { readStateScope: 'read-a' });
997
- assertHas('read tail first', firstTail, `8001${LINE_SEP}line-8001`);
998
- const cachedTail = await executeBuiltinTool('read', { path: 'large.txt', offset: 10000, limit: 2 }, dir, { readStateScope: 'read-b' });
999
- assertHas('read tail cached', cachedTail, `10001${LINE_SEP}line-10001`);
1000
- const compactMediumLines = Array.from({ length: 8000 }, (_, i) => `compact-${i + 1}`).join('\n') + '\n';
1001
- await writeFile(join(dir, 'compact-medium.txt'), compactMediumLines, 'utf8');
1002
- const compactMediumDefault = await executeBuiltinTool('read', { path: 'compact-medium.txt' }, dir, { readStateScope: 'read-compact-medium-default' });
1003
- assertHas('compact medium default marker', compactMediumDefault, 'TRUNCATED');
1004
- assertHas('compact medium default head', compactMediumDefault, `1${LINE_SEP}compact-1`);
1005
- assertHas('compact medium default tail', compactMediumDefault, `8000${LINE_SEP}compact-8000`);
1006
- if (String(compactMediumDefault).includes(`4000${LINE_SEP}compact-4000`)) {
1007
- throw new Error('compact medium default read included a middle line that should have been elided');
1008
- }
1009
- const smartSnapshotRows = Array.from({ length: 700 }, (_, i) => i === 349 ? 'M' : `smart-snapshot-${i + 1}`);
1010
- await writeFile(join(dir, 'smart-snapshot.txt'), smartSnapshotRows.join('\n') + '\n', 'utf8');
1011
- const smartSnapshotRead = await executeBuiltinTool('read', { path: 'smart-snapshot.txt' }, dir, { readStateScope: 'read-smart-snapshot' });
1012
- assertHas('smart snapshot default read marker', smartSnapshotRead, 'TRUNCATED');
1013
- assertNotHas('smart snapshot default read no narrow hint', smartSnapshotRead, 'read({path,line,context})');
1014
- const smartHiddenEdit = await executeBuiltinTool('edit', {
1015
- path: 'smart-snapshot.txt',
1016
- old_string: 'M',
1017
- new_string: 'N',
1018
- }, dir, { readStateScope: 'read-smart-snapshot' });
1019
- assertOk('smart snapshot hidden middle edit now succeeds (read-window gate retired)', smartHiddenEdit);
1020
- await expectFile('smart-snapshot.txt', smartSnapshotRows.map((row) => (row === 'M' ? 'N' : row)).join('\n') + '\n');
1021
- const midRangeLines = Array.from({ length: 20000 }, (_, i) => `midrange-${i + 1}`).join('\n') + '\n';
1022
- await writeFile(join(dir, 'mid-range.txt'), midRangeLines, 'utf8');
1023
- const midRange = await executeBuiltinTool('read', { path: 'mid-range.txt', offset: 15000, limit: 2 }, dir, { readStateScope: 'read-mid-range-stream' });
1024
- assertHas('mid range streamed slice first', midRange, `15001${LINE_SEP}midrange-15001`);
1025
- assertHas('mid range streamed slice footer', midRange, 'range limit reached; next offset: 15002');
1026
- const mediumHeadLines = Array.from({ length: 100000 }, (_, i) => `head-${i + 1}`).join('\n') + '\n';
1027
- await writeFile(join(dir, 'medium-head.txt'), mediumHeadLines, 'utf8');
1028
- const mediumHead = await executeBuiltinTool('read', { path: 'medium-head.txt', mode: 'head', n: 2 }, dir, { readStateScope: 'read-medium-head' });
1029
- assertHas('medium head first', mediumHead, `1${LINE_SEP}head-1`);
1030
- assertHas('medium head second', mediumHead, `2${LINE_SEP}head-2`);
1031
- const mediumTail = await executeBuiltinTool('read', { path: 'medium-head.txt', mode: 'tail', n: 2 }, dir, { readStateScope: 'read-medium-tail' });
1032
- assertHas('medium tail first', mediumTail, `99999${LINE_SEP}head-99999`);
1033
- assertHas('medium tail second', mediumTail, `100000${LINE_SEP}head-100000`);
1034
- const mediumCount = await executeBuiltinTool('read', { path: 'medium-head.txt', mode: 'count' }, dir, { readStateScope: 'read-medium-count' });
1035
- assertHas('medium count lines', mediumCount, 'lines\t100000');
1036
- assertHas('medium count words', mediumCount, 'words\t100000');
1037
- const mediumDefault = await executeBuiltinTool('read', { path: 'medium-head.txt' }, dir, { readStateScope: 'read-medium-default' });
1038
- assertHas('medium default first', mediumDefault, `1${LINE_SEP}head-1`);
1039
- assertHas('medium default marker', mediumDefault, 'TRUNCATED');
1040
- assertNotHas('medium default no narrow hint', mediumDefault, 'read({path,line,context})');
1041
- assertHas('medium default tail', mediumDefault, `100000${LINE_SEP}head-100000`);
1042
- if (String(mediumDefault).includes(`50000${LINE_SEP}head-50000`)) {
1043
- throw new Error('medium default read streamed a middle line that should have been elided');
1044
- }
1045
- assertOk('medium default visible-tail edit', await executeBuiltinTool('edit', {
1046
- path: 'medium-head.txt',
1047
- old_string: 'head-99999',
1048
- new_string: 'HEAD-99999',
1049
- }, dir, { readStateScope: 'read-medium-default' }));
1050
- const farBatch = await executeBuiltinTool('read', {
1051
- path: [
1052
- { path: 'large.txt', offset: 10, limit: 2 },
1053
- { path: 'large.txt', offset: 10000, limit: 2 },
1054
- ],
1055
- }, dir, { readStateScope: 'read-far-batch' });
1056
- assertHas('far batch read head slice', farBatch, `11${LINE_SEP}line-11`);
1057
- assertHas('far batch read tail slice', farBatch, `10001${LINE_SEP}line-10001`);
1058
- const reverseFarBatch = await executeBuiltinTool('read', {
1059
- path: [
1060
- { path: 'large.txt', offset: 10000, limit: 1 },
1061
- { path: 'large.txt', offset: 10, limit: 1 },
1062
- ],
1063
- }, dir, { readStateScope: 'read-far-batch-reverse' });
1064
- const reverseTailIdx = String(reverseFarBatch).indexOf(`10001${LINE_SEP}line-10001`);
1065
- const reverseHeadIdx = String(reverseFarBatch).indexOf(`11${LINE_SEP}line-11`);
1066
- if (reverseTailIdx === -1 || reverseHeadIdx === -1 || reverseTailIdx > reverseHeadIdx) {
1067
- throw new Error(`far batch output order changed unexpectedly:\n${reverseFarBatch}`);
1068
- }
1069
- const byteCapRows = Array.from({ length: 1800 }, (_, i) => `bytecap-${i + 1}-${'x'.repeat(54)}`);
1070
- byteCapRows[9] = `bytecap-repeat-${'x'.repeat(50)}`;
1071
- byteCapRows[1699] = `bytecap-repeat-${'x'.repeat(50)}`;
1072
- const byteCapLines = byteCapRows.join('\n') + '\n';
1073
- await writeFile(join(dir, 'byte-cap-read.txt'), byteCapLines, 'utf8');
1074
- const byteCapRead = await executeBuiltinTool('read', { path: 'byte-cap-read.txt', offset: 0, limit: 1800 }, dir, { readStateScope: 'read-byte-cap' });
1075
- assertHas('byte-cap read truncation marker', byteCapRead, 'output truncated');
1076
- const byteCapHiddenEdit = await executeBuiltinTool('edit', {
1077
- path: 'byte-cap-read.txt',
1078
- old_string: `bytecap-repeat-${'x'.repeat(50)}`,
1079
- new_string: 'BYTECAP-HIDDEN',
1080
- }, dir, { readStateScope: 'read-byte-cap' });
1081
- assertError('byte-cap ambiguous hidden tail edit blocked by ambiguity gate (code 9, not read-window)', byteCapHiddenEdit, 'Error [code 9]');
1082
- await expectFile('byte-cap-read.txt', byteCapLines);
1083
-
1084
- await writeFile(join(dir, 'large.txt'), lines.replace('line-10001', 'changed-10001'), 'utf8');
1085
- const invalidated = await executeBuiltinTool('read', { path: 'large.txt', offset: 10000, limit: 1 }, dir, { readStateScope: 'read-c' });
1086
- assertHas('read cache invalidation', invalidated, `10001${LINE_SEP}changed-10001`);
1087
-
1088
- console.log('mutation-io smoke passed');
1089
- } finally {
1090
- await rmTree(dir);
1091
- await rmTree(DATA_DIR);
1092
- }
1093
- // Imported builtin/read-dedup/offload modules keep a background flush timer
1094
- // alive, so without an explicit exit the process hangs after all checks pass
1095
- // (same as guard-smoke / builtin-utils-smoke). A thrown assertion above exits
1096
- // non-zero before reaching here.
1097
- process.exit(0);