mixdog 0.7.17 → 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 (836) 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/cost.mjs +66 -0
  179. package/src/runtime/shared/llm/http-agent.mjs +129 -0
  180. package/src/runtime/shared/open-url.mjs +37 -0
  181. package/src/runtime/shared/plugin-paths.mjs +25 -0
  182. package/src/runtime/shared/process-shutdown.mjs +147 -0
  183. package/src/runtime/shared/schedules-store.mjs +70 -0
  184. package/src/runtime/shared/tool-execution-contract.mjs +104 -0
  185. package/src/runtime/shared/tool-surface.mjs +950 -0
  186. package/src/runtime/shared/user-cwd.mjs +221 -0
  187. package/src/runtime/shared/user-data-guard.mjs +232 -0
  188. package/src/runtime/shared/workspace-router.mjs +259 -0
  189. package/src/standalone/bridge-tool.mjs +1414 -0
  190. package/src/standalone/channel-admin.mjs +366 -0
  191. package/src/standalone/channel-worker-preload.cjs +3 -0
  192. package/src/standalone/channel-worker.mjs +353 -0
  193. package/src/standalone/explore-tool.mjs +233 -0
  194. package/src/standalone/hook-bus.mjs +246 -0
  195. package/src/standalone/plugin-admin.mjs +247 -0
  196. package/src/standalone/provider-admin.mjs +338 -0
  197. package/src/standalone/seeds.mjs +94 -0
  198. package/src/standalone/usage-dashboard.mjs +510 -0
  199. package/src/tui/App.jsx +5438 -0
  200. package/src/tui/components/AnsiText.jsx +199 -0
  201. package/src/tui/components/ContextPanel.jsx +217 -0
  202. package/src/tui/components/Markdown.jsx +205 -0
  203. package/src/tui/components/MarkdownTable.jsx +204 -0
  204. package/src/tui/components/Message.jsx +103 -0
  205. package/src/tui/components/Picker.jsx +317 -0
  206. package/src/tui/components/PromptInput.jsx +584 -0
  207. package/src/tui/components/QueuedCommands.jsx +47 -0
  208. package/src/tui/components/SlashCommandPalette.jsx +114 -0
  209. package/src/tui/components/Spinner.jsx +317 -0
  210. package/src/tui/components/StatusLine.jsx +87 -0
  211. package/src/tui/components/TextEntryPanel.jsx +323 -0
  212. package/src/tui/components/ToolExecution.jsx +772 -0
  213. package/src/tui/components/TurnDone.jsx +78 -0
  214. package/src/tui/components/UsagePanel.jsx +331 -0
  215. package/src/tui/dist/index.mjs +12359 -0
  216. package/src/tui/engine.mjs +2410 -0
  217. package/src/tui/figures.mjs +50 -0
  218. package/src/tui/hooks/useEngine.mjs +16 -0
  219. package/src/tui/index.jsx +254 -0
  220. package/src/tui/input-editing.mjs +242 -0
  221. package/src/tui/markdown/format-token.mjs +194 -0
  222. package/src/tui/paste-attachments.mjs +198 -0
  223. package/src/tui/runtime/shared/process-shutdown.mjs +1 -0
  224. package/src/tui/spinner-verbs.mjs +45 -0
  225. package/src/tui/theme.mjs +67 -0
  226. package/src/tui/time-format.mjs +53 -0
  227. package/src/ui/ansi.mjs +115 -0
  228. package/src/ui/markdown.mjs +195 -0
  229. package/src/ui/statusline.mjs +730 -0
  230. package/src/ui/tool-card.mjs +101 -0
  231. package/src/vendor/statusline/bin/statusline-lib.mjs +805 -0
  232. package/src/vendor/statusline/bin/statusline-route.mjs +596 -0
  233. package/src/vendor/statusline/scripts/lib/gateway-settings.mjs +285 -0
  234. package/src/vendor/statusline/src/gateway/claude-current.mjs +320 -0
  235. package/src/vendor/statusline/src/gateway/route-meta.mjs +753 -0
  236. package/src/vendor/statusline/src/gateway/session-routes.mjs +244 -0
  237. package/src/workflows/default/WORKFLOW.md +7 -0
  238. package/src/workflows/default/workflow.json +14 -0
  239. package/vendor/ink/build/ansi-tokenizer.d.ts +38 -0
  240. package/vendor/ink/build/ansi-tokenizer.js +316 -0
  241. package/vendor/ink/build/ansi-tokenizer.js.map +1 -0
  242. package/vendor/ink/build/colorize.d.ts +3 -0
  243. package/vendor/ink/build/colorize.js +48 -0
  244. package/vendor/ink/build/colorize.js.map +1 -0
  245. package/vendor/ink/build/components/AccessibilityContext.d.ts +3 -0
  246. package/vendor/ink/build/components/AccessibilityContext.js +5 -0
  247. package/vendor/ink/build/components/AccessibilityContext.js.map +1 -0
  248. package/vendor/ink/build/components/AnimationContext.d.ts +9 -0
  249. package/vendor/ink/build/components/AnimationContext.js +13 -0
  250. package/vendor/ink/build/components/AnimationContext.js.map +1 -0
  251. package/vendor/ink/build/components/App.d.ts +24 -0
  252. package/vendor/ink/build/components/App.js +554 -0
  253. package/vendor/ink/build/components/App.js.map +1 -0
  254. package/vendor/ink/build/components/AppContext.d.ts +80 -0
  255. package/vendor/ink/build/components/AppContext.js +25 -0
  256. package/vendor/ink/build/components/AppContext.js.map +1 -0
  257. package/vendor/ink/build/components/BackgroundContext.d.ts +4 -0
  258. package/vendor/ink/build/components/BackgroundContext.js +3 -0
  259. package/vendor/ink/build/components/BackgroundContext.js.map +1 -0
  260. package/vendor/ink/build/components/Box.d.ts +130 -0
  261. package/vendor/ink/build/components/Box.js +34 -0
  262. package/vendor/ink/build/components/Box.js.map +1 -0
  263. package/vendor/ink/build/components/CursorContext.d.ts +11 -0
  264. package/vendor/ink/build/components/CursorContext.js +8 -0
  265. package/vendor/ink/build/components/CursorContext.js.map +1 -0
  266. package/vendor/ink/build/components/ErrorBoundary.d.ts +18 -0
  267. package/vendor/ink/build/components/ErrorBoundary.js +23 -0
  268. package/vendor/ink/build/components/ErrorBoundary.js.map +1 -0
  269. package/vendor/ink/build/components/ErrorOverview.d.ts +6 -0
  270. package/vendor/ink/build/components/ErrorOverview.js +90 -0
  271. package/vendor/ink/build/components/ErrorOverview.js.map +1 -0
  272. package/vendor/ink/build/components/FocusContext.d.ts +16 -0
  273. package/vendor/ink/build/components/FocusContext.js +17 -0
  274. package/vendor/ink/build/components/FocusContext.js.map +1 -0
  275. package/vendor/ink/build/components/Newline.d.ts +13 -0
  276. package/vendor/ink/build/components/Newline.js +8 -0
  277. package/vendor/ink/build/components/Newline.js.map +1 -0
  278. package/vendor/ink/build/components/Spacer.d.ts +7 -0
  279. package/vendor/ink/build/components/Spacer.js +11 -0
  280. package/vendor/ink/build/components/Spacer.js.map +1 -0
  281. package/vendor/ink/build/components/Static.d.ts +24 -0
  282. package/vendor/ink/build/components/Static.js +28 -0
  283. package/vendor/ink/build/components/Static.js.map +1 -0
  284. package/vendor/ink/build/components/StderrContext.d.ts +15 -0
  285. package/vendor/ink/build/components/StderrContext.js +13 -0
  286. package/vendor/ink/build/components/StderrContext.js.map +1 -0
  287. package/vendor/ink/build/components/StdinContext.d.ts +28 -0
  288. package/vendor/ink/build/components/StdinContext.js +20 -0
  289. package/vendor/ink/build/components/StdinContext.js.map +1 -0
  290. package/vendor/ink/build/components/StdoutContext.d.ts +15 -0
  291. package/vendor/ink/build/components/StdoutContext.js +13 -0
  292. package/vendor/ink/build/components/StdoutContext.js.map +1 -0
  293. package/vendor/ink/build/components/Text.d.ts +55 -0
  294. package/vendor/ink/build/components/Text.js +50 -0
  295. package/vendor/ink/build/components/Text.js.map +1 -0
  296. package/vendor/ink/build/components/Transform.d.ts +16 -0
  297. package/vendor/ink/build/components/Transform.js +15 -0
  298. package/vendor/ink/build/components/Transform.js.map +1 -0
  299. package/vendor/ink/build/cursor-helpers.d.ts +39 -0
  300. package/vendor/ink/build/cursor-helpers.js +62 -0
  301. package/vendor/ink/build/cursor-helpers.js.map +1 -0
  302. package/vendor/ink/build/devtools-window-polyfill.d.ts +1 -0
  303. package/vendor/ink/build/devtools-window-polyfill.js +68 -0
  304. package/vendor/ink/build/devtools-window-polyfill.js.map +1 -0
  305. package/vendor/ink/build/devtools.d.ts +1 -0
  306. package/vendor/ink/build/devtools.js +36 -0
  307. package/vendor/ink/build/devtools.js.map +1 -0
  308. package/vendor/ink/build/dom.d.ts +62 -0
  309. package/vendor/ink/build/dom.js +143 -0
  310. package/vendor/ink/build/dom.js.map +1 -0
  311. package/vendor/ink/build/get-max-width.d.ts +3 -0
  312. package/vendor/ink/build/get-max-width.js +10 -0
  313. package/vendor/ink/build/get-max-width.js.map +1 -0
  314. package/vendor/ink/build/hooks/use-animation.d.ts +49 -0
  315. package/vendor/ink/build/hooks/use-animation.js +87 -0
  316. package/vendor/ink/build/hooks/use-animation.js.map +1 -0
  317. package/vendor/ink/build/hooks/use-app.d.ts +5 -0
  318. package/vendor/ink/build/hooks/use-app.js +8 -0
  319. package/vendor/ink/build/hooks/use-app.js.map +1 -0
  320. package/vendor/ink/build/hooks/use-box-metrics.d.ts +59 -0
  321. package/vendor/ink/build/hooks/use-box-metrics.js +81 -0
  322. package/vendor/ink/build/hooks/use-box-metrics.js.map +1 -0
  323. package/vendor/ink/build/hooks/use-cursor.d.ts +12 -0
  324. package/vendor/ink/build/hooks/use-cursor.js +29 -0
  325. package/vendor/ink/build/hooks/use-cursor.js.map +1 -0
  326. package/vendor/ink/build/hooks/use-focus-manager.d.ts +43 -0
  327. package/vendor/ink/build/hooks/use-focus-manager.js +18 -0
  328. package/vendor/ink/build/hooks/use-focus-manager.js.map +1 -0
  329. package/vendor/ink/build/hooks/use-focus.d.ts +30 -0
  330. package/vendor/ink/build/hooks/use-focus.js +43 -0
  331. package/vendor/ink/build/hooks/use-focus.js.map +1 -0
  332. package/vendor/ink/build/hooks/use-input.d.ts +132 -0
  333. package/vendor/ink/build/hooks/use-input.js +126 -0
  334. package/vendor/ink/build/hooks/use-input.js.map +1 -0
  335. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.d.ts +6 -0
  336. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js +12 -0
  337. package/vendor/ink/build/hooks/use-is-screen-reader-enabled.js.map +1 -0
  338. package/vendor/ink/build/hooks/use-paste.d.ts +35 -0
  339. package/vendor/ink/build/hooks/use-paste.js +62 -0
  340. package/vendor/ink/build/hooks/use-paste.js.map +1 -0
  341. package/vendor/ink/build/hooks/use-stderr.d.ts +5 -0
  342. package/vendor/ink/build/hooks/use-stderr.js +8 -0
  343. package/vendor/ink/build/hooks/use-stderr.js.map +1 -0
  344. package/vendor/ink/build/hooks/use-stdin.d.ts +7 -0
  345. package/vendor/ink/build/hooks/use-stdin.js +9 -0
  346. package/vendor/ink/build/hooks/use-stdin.js.map +1 -0
  347. package/vendor/ink/build/hooks/use-stdout.d.ts +5 -0
  348. package/vendor/ink/build/hooks/use-stdout.js +8 -0
  349. package/vendor/ink/build/hooks/use-stdout.js.map +1 -0
  350. package/vendor/ink/build/hooks/use-window-size.d.ts +18 -0
  351. package/vendor/ink/build/hooks/use-window-size.js +22 -0
  352. package/vendor/ink/build/hooks/use-window-size.js.map +1 -0
  353. package/vendor/ink/build/index.d.ts +42 -0
  354. package/vendor/ink/build/index.js +24 -0
  355. package/vendor/ink/build/index.js.map +1 -0
  356. package/vendor/ink/build/ink.d.ts +146 -0
  357. package/vendor/ink/build/ink.js +1022 -0
  358. package/vendor/ink/build/ink.js.map +1 -0
  359. package/vendor/ink/build/input-parser.d.ts +10 -0
  360. package/vendor/ink/build/input-parser.js +194 -0
  361. package/vendor/ink/build/input-parser.js.map +1 -0
  362. package/vendor/ink/build/instances.d.ts +3 -0
  363. package/vendor/ink/build/instances.js +8 -0
  364. package/vendor/ink/build/instances.js.map +1 -0
  365. package/vendor/ink/build/kitty-keyboard.d.ts +23 -0
  366. package/vendor/ink/build/kitty-keyboard.js +32 -0
  367. package/vendor/ink/build/kitty-keyboard.js.map +1 -0
  368. package/vendor/ink/build/log-update.d.ts +20 -0
  369. package/vendor/ink/build/log-update.js +261 -0
  370. package/vendor/ink/build/log-update.js.map +1 -0
  371. package/vendor/ink/build/measure-element.d.ts +20 -0
  372. package/vendor/ink/build/measure-element.js +13 -0
  373. package/vendor/ink/build/measure-element.js.map +1 -0
  374. package/vendor/ink/build/measure-text.d.ts +6 -0
  375. package/vendor/ink/build/measure-text.js +21 -0
  376. package/vendor/ink/build/measure-text.js.map +1 -0
  377. package/vendor/ink/build/output.d.ts +35 -0
  378. package/vendor/ink/build/output.js +328 -0
  379. package/vendor/ink/build/output.js.map +1 -0
  380. package/vendor/ink/build/parse-keypress.d.ts +20 -0
  381. package/vendor/ink/build/parse-keypress.js +495 -0
  382. package/vendor/ink/build/parse-keypress.js.map +1 -0
  383. package/vendor/ink/build/reconciler.d.ts +4 -0
  384. package/vendor/ink/build/reconciler.js +306 -0
  385. package/vendor/ink/build/reconciler.js.map +1 -0
  386. package/vendor/ink/build/render-background.d.ts +4 -0
  387. package/vendor/ink/build/render-background.js +25 -0
  388. package/vendor/ink/build/render-background.js.map +1 -0
  389. package/vendor/ink/build/render-border.d.ts +4 -0
  390. package/vendor/ink/build/render-border.js +84 -0
  391. package/vendor/ink/build/render-border.js.map +1 -0
  392. package/vendor/ink/build/render-node-to-output.d.ts +14 -0
  393. package/vendor/ink/build/render-node-to-output.js +162 -0
  394. package/vendor/ink/build/render-node-to-output.js.map +1 -0
  395. package/vendor/ink/build/render-to-string.d.ts +38 -0
  396. package/vendor/ink/build/render-to-string.js +116 -0
  397. package/vendor/ink/build/render-to-string.js.map +1 -0
  398. package/vendor/ink/build/render.d.ts +176 -0
  399. package/vendor/ink/build/render.js +71 -0
  400. package/vendor/ink/build/render.js.map +1 -0
  401. package/vendor/ink/build/renderer.d.ts +8 -0
  402. package/vendor/ink/build/renderer.js +64 -0
  403. package/vendor/ink/build/renderer.js.map +1 -0
  404. package/vendor/ink/build/sanitize-ansi.d.ts +2 -0
  405. package/vendor/ink/build/sanitize-ansi.js +27 -0
  406. package/vendor/ink/build/sanitize-ansi.js.map +1 -0
  407. package/vendor/ink/build/squash-text-nodes.d.ts +3 -0
  408. package/vendor/ink/build/squash-text-nodes.js +36 -0
  409. package/vendor/ink/build/squash-text-nodes.js.map +1 -0
  410. package/vendor/ink/build/styles.d.ts +302 -0
  411. package/vendor/ink/build/styles.js +303 -0
  412. package/vendor/ink/build/styles.js.map +1 -0
  413. package/vendor/ink/build/utils.d.ts +9 -0
  414. package/vendor/ink/build/utils.js +19 -0
  415. package/vendor/ink/build/utils.js.map +1 -0
  416. package/vendor/ink/build/wrap-text.d.ts +3 -0
  417. package/vendor/ink/build/wrap-text.js +38 -0
  418. package/vendor/ink/build/wrap-text.js.map +1 -0
  419. package/vendor/ink/build/write-synchronized.d.ts +4 -0
  420. package/vendor/ink/build/write-synchronized.js +9 -0
  421. package/vendor/ink/build/write-synchronized.js.map +1 -0
  422. package/vendor/ink/license +10 -0
  423. package/vendor/ink/package.json +137 -0
  424. package/.claude-plugin/marketplace.json +0 -34
  425. package/.claude-plugin/plugin.json +0 -20
  426. package/.gitattributes +0 -34
  427. package/.mcp.json +0 -14
  428. package/ARCHITECTURE.md +0 -77
  429. package/CHANGELOG.md +0 -30
  430. package/CONTRIBUTING.md +0 -45
  431. package/DATA-FLOW.md +0 -79
  432. package/LICENSE +0 -21
  433. package/SECURITY.md +0 -138
  434. package/UNINSTALL.md +0 -112
  435. package/agents/maintenance.md +0 -5
  436. package/agents/memory-classification.md +0 -30
  437. package/agents/scheduler-task.md +0 -18
  438. package/agents/webhook-handler.md +0 -27
  439. package/agents/worker.md +0 -24
  440. package/bin/bridge +0 -133
  441. package/bin/statusline-launcher.mjs +0 -82
  442. package/bin/statusline-lib.mjs +0 -558
  443. package/bin/statusline.mjs +0 -615
  444. package/bun.lock +0 -927
  445. package/commands/config.md +0 -16
  446. package/commands/doctor.md +0 -13
  447. package/commands/setup.md +0 -17
  448. package/defaults/hidden-roles.json +0 -68
  449. package/defaults/memory-chunk-prompt.md +0 -63
  450. package/defaults/mixdog-config.template.json +0 -27
  451. package/defaults/user-workflow.json +0 -8
  452. package/defaults/user-workflow.md +0 -17
  453. package/hooks/hooks.json +0 -73
  454. package/hooks/lib/active-instance.cjs +0 -77
  455. package/hooks/lib/permission-evaluator.cjs +0 -411
  456. package/hooks/lib/permission-route.cjs +0 -63
  457. package/hooks/lib/settings-loader.cjs +0 -117
  458. package/hooks/post-tool-use.cjs +0 -84
  459. package/hooks/pre-mcp-sandbox.cjs +0 -158
  460. package/hooks/pre-tool-subagent.cjs +0 -258
  461. package/hooks/session-start.cjs +0 -1479
  462. package/hooks/shim-launcher.cjs +0 -65
  463. package/hooks/turn-timer.cjs +0 -82
  464. package/lib/claude-md-writer.cjs +0 -386
  465. package/lib/keychain-cjs.cjs +0 -290
  466. package/lib/plugin-paths.cjs +0 -69
  467. package/lib/rules-builder.cjs +0 -241
  468. package/native/README.md +0 -117
  469. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  470. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  471. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  472. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  473. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  474. package/prompts/code-review.txt +0 -16
  475. package/prompts/security-audit.txt +0 -17
  476. package/rules/bridge/00-common.md +0 -39
  477. package/rules/bridge/20-skip-protocol.md +0 -18
  478. package/rules/bridge/30-explorer.md +0 -33
  479. package/rules/bridge/40-cycle1-agent.md +0 -52
  480. package/rules/bridge/41-cycle2-agent.md +0 -62
  481. package/rules/lead/00-tool-lead.md +0 -61
  482. package/rules/lead/01-general.md +0 -23
  483. package/rules/lead/02-channels.md +0 -49
  484. package/rules/lead/03-team.md +0 -27
  485. package/rules/lead/04-workflow.md +0 -20
  486. package/rules/shared/00-language.md +0 -14
  487. package/rules/shared/01-tool.md +0 -138
  488. package/scripts/bootstrap.mjs +0 -130
  489. package/scripts/bridge-unify-smoke.mjs +0 -308
  490. package/scripts/build-runtime-linux.sh +0 -348
  491. package/scripts/build-runtime-macos.sh +0 -217
  492. package/scripts/build-runtime-windows.ps1 +0 -242
  493. package/scripts/builtin-utils-smoke.mjs +0 -398
  494. package/scripts/bump.mjs +0 -80
  495. package/scripts/check-json.mjs +0 -45
  496. package/scripts/check-syntax-changed.mjs +0 -102
  497. package/scripts/check-syntax.mjs +0 -58
  498. package/scripts/code-graph-batch.test.mjs +0 -33
  499. package/scripts/config-preserve-smoke.mjs +0 -180
  500. package/scripts/doctor.mjs +0 -489
  501. package/scripts/edit-normalize-fuzz.mjs +0 -130
  502. package/scripts/edit-normalize-smoke.mjs +0 -401
  503. package/scripts/edit-operation-smoke.mjs +0 -369
  504. package/scripts/edit2-smoke.mjs +0 -63
  505. package/scripts/ensure-deps.mjs +0 -259
  506. package/scripts/fuzzy-e2e.mjs +0 -28
  507. package/scripts/fuzzy-smoke.mjs +0 -26
  508. package/scripts/generate-runtime-manifest.mjs +0 -166
  509. package/scripts/guard-smoke.mjs +0 -66
  510. package/scripts/hidden-role-schema-smoke.mjs +0 -162
  511. package/scripts/hook-routing-smoke.mjs +0 -29
  512. package/scripts/inject-input.ps1 +0 -204
  513. package/scripts/io-complex-smoke.mjs +0 -667
  514. package/scripts/io-explore-bench.mjs +0 -424
  515. package/scripts/io-guardrails-smoke.mjs +0 -205
  516. package/scripts/io-mini-bench-baseline.json +0 -11
  517. package/scripts/io-mini-bench.mjs +0 -216
  518. package/scripts/io-route-harness.mjs +0 -933
  519. package/scripts/io-telemetry-report.mjs +0 -691
  520. package/scripts/mutation-bench.mjs +0 -564
  521. package/scripts/mutation-io-smoke.mjs +0 -1097
  522. package/scripts/native-patch-bridge-smoke.mjs +0 -288
  523. package/scripts/native-patch-smoke.mjs +0 -304
  524. package/scripts/openai-oauth-catalog-smoke.mjs +0 -53
  525. package/scripts/patch-interior-context-smoke.mjs +0 -49
  526. package/scripts/patch-newline-utf8-smoke.mjs +0 -157
  527. package/scripts/perf-hook-smoke.mjs +0 -71
  528. package/scripts/permission-eval-smoke.mjs +0 -443
  529. package/scripts/prep-patch.mjs +0 -53
  530. package/scripts/prep-shim.mjs +0 -96
  531. package/scripts/provider-cache-smoke.mjs +0 -687
  532. package/scripts/report-runtime-health.mjs +0 -132
  533. package/scripts/resolve-bun.mjs +0 -60
  534. package/scripts/run-mcp.mjs +0 -1448
  535. package/scripts/salvage-v4a-shatter.test.mjs +0 -58
  536. package/scripts/scoped-cache-io-smoke.mjs +0 -103
  537. package/scripts/shell-policy-round3-smoke.mjs +0 -46
  538. package/scripts/smoke-runtime-negative.ps1 +0 -100
  539. package/scripts/smoke-runtime-negative.sh +0 -95
  540. package/scripts/stall-policy-smoke.mjs +0 -50
  541. package/scripts/start-memory-worker.mjs +0 -23
  542. package/scripts/statusline-launcher-smoke.mjs +0 -82
  543. package/scripts/stress-atomic-write.mjs +0 -1028
  544. package/scripts/test-fault-inject.mjs +0 -164
  545. package/scripts/test-large-file.mjs +0 -174
  546. package/scripts/tool-edge-smoke.mjs +0 -209
  547. package/scripts/uninstall.mjs +0 -201
  548. package/scripts/webhook-selfheal-smoke.mjs +0 -27
  549. package/scripts/write-overwrite-guard-smoke.mjs +0 -56
  550. package/server-main.mjs +0 -3109
  551. package/server.mjs +0 -468
  552. package/setup/config-merge.mjs +0 -246
  553. package/setup/install.mjs +0 -574
  554. package/setup/launch-core.mjs +0 -617
  555. package/setup/launch.mjs +0 -101
  556. package/setup/locate-claude.mjs +0 -56
  557. package/setup/mixdog-cli.mjs +0 -122
  558. package/setup/setup-server.mjs +0 -3305
  559. package/setup/setup.html +0 -3740
  560. package/setup/tui.mjs +0 -325
  561. package/skills/retro-skill-proposer/SKILL.md +0 -92
  562. package/skills/schedule-add/SKILL.md +0 -77
  563. package/skills/setup/SKILL.md +0 -356
  564. package/skills/webhook-add/SKILL.md +0 -81
  565. package/src/agent/bridge-stall-watchdog.mjs +0 -337
  566. package/src/agent/index.mjs +0 -2138
  567. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +0 -1010
  568. package/src/agent/orchestrator/bridge-retry.mjs +0 -220
  569. package/src/agent/orchestrator/bridge-trace.mjs +0 -583
  570. package/src/agent/orchestrator/cache-mtime.mjs +0 -58
  571. package/src/agent/orchestrator/config.mjs +0 -405
  572. package/src/agent/orchestrator/context/collect.mjs +0 -651
  573. package/src/agent/orchestrator/dispatch-persist.mjs +0 -549
  574. package/src/agent/orchestrator/drain-registry.mjs +0 -50
  575. package/src/agent/orchestrator/explore-validator.mjs +0 -8
  576. package/src/agent/orchestrator/internal-roles.mjs +0 -118
  577. package/src/agent/orchestrator/internal-tools.mjs +0 -88
  578. package/src/agent/orchestrator/jobs.mjs +0 -116
  579. package/src/agent/orchestrator/mcp/client.mjs +0 -364
  580. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +0 -1881
  581. package/src/agent/orchestrator/providers/anthropic.mjs +0 -594
  582. package/src/agent/orchestrator/providers/gemini.mjs +0 -1530
  583. package/src/agent/orchestrator/providers/grok-oauth.mjs +0 -779
  584. package/src/agent/orchestrator/providers/model-catalog.mjs +0 -374
  585. package/src/agent/orchestrator/providers/openai-compat-stream.mjs +0 -366
  586. package/src/agent/orchestrator/providers/openai-compat.mjs +0 -1511
  587. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +0 -1891
  588. package/src/agent/orchestrator/providers/openai-oauth.mjs +0 -1456
  589. package/src/agent/orchestrator/providers/openai-ws.mjs +0 -127
  590. package/src/agent/orchestrator/providers/registry.mjs +0 -192
  591. package/src/agent/orchestrator/providers/retry-classifier.mjs +0 -325
  592. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +0 -142
  593. package/src/agent/orchestrator/session/cache/read-cache.mjs +0 -319
  594. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +0 -361
  595. package/src/agent/orchestrator/session/loop.mjs +0 -1478
  596. package/src/agent/orchestrator/session/manager.mjs +0 -1991
  597. package/src/agent/orchestrator/session/result-classification.mjs +0 -65
  598. package/src/agent/orchestrator/session/store.mjs +0 -632
  599. package/src/agent/orchestrator/session/stream-watchdog.mjs +0 -130
  600. package/src/agent/orchestrator/session/tool-result-offload.mjs +0 -166
  601. package/src/agent/orchestrator/session/trim.mjs +0 -491
  602. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +0 -115
  603. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +0 -331
  604. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +0 -150
  605. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +0 -228
  606. package/src/agent/orchestrator/smart-bridge/index.mjs +0 -215
  607. package/src/agent/orchestrator/smart-bridge/profiles.mjs +0 -37
  608. package/src/agent/orchestrator/smart-bridge/registry.mjs +0 -348
  609. package/src/agent/orchestrator/stall-policy.mjs +0 -201
  610. package/src/agent/orchestrator/tool-loop-guard.mjs +0 -75
  611. package/src/agent/orchestrator/tools/bash-session.mjs +0 -722
  612. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +0 -455
  613. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +0 -480
  614. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +0 -256
  615. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +0 -58
  616. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +0 -240
  617. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +0 -113
  618. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +0 -74
  619. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +0 -242
  620. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +0 -211
  621. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +0 -1364
  622. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +0 -126
  623. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +0 -141
  624. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +0 -194
  625. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +0 -60
  626. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +0 -168
  627. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +0 -173
  628. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +0 -48
  629. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +0 -99
  630. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +0 -193
  631. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +0 -597
  632. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +0 -110
  633. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +0 -300
  634. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +0 -152
  635. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +0 -118
  636. package/src/agent/orchestrator/tools/builtin/read-open.mjs +0 -190
  637. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +0 -728
  638. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +0 -173
  639. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +0 -602
  640. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +0 -196
  641. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +0 -422
  642. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +0 -158
  643. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +0 -869
  644. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +0 -962
  645. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +0 -223
  646. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +0 -206
  647. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +0 -401
  648. package/src/agent/orchestrator/tools/builtin.mjs +0 -503
  649. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +0 -24
  650. package/src/agent/orchestrator/tools/code-graph.mjs +0 -4095
  651. package/src/agent/orchestrator/tools/cwd-tool.mjs +0 -298
  652. package/src/agent/orchestrator/tools/destructive-warning.mjs +0 -323
  653. package/src/agent/orchestrator/tools/edit-normalize.mjs +0 -603
  654. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +0 -154
  655. package/src/agent/orchestrator/tools/graph-manifest.json +0 -26
  656. package/src/agent/orchestrator/tools/host-input.mjs +0 -204
  657. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +0 -143
  658. package/src/agent/orchestrator/tools/patch-manifest.json +0 -26
  659. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +0 -20
  660. package/src/agent/orchestrator/tools/patch.mjs +0 -2754
  661. package/src/agent/orchestrator/tools/progress-message.mjs +0 -118
  662. package/src/agent/orchestrator/tools/shell-command.mjs +0 -865
  663. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +0 -7
  664. package/src/agent/orchestrator/tools/shell-snapshot.mjs +0 -313
  665. package/src/agent/orchestrator/workflow-store.mjs +0 -93
  666. package/src/agent/tool-defs.mjs +0 -103
  667. package/src/channels/backends/discord.mjs +0 -784
  668. package/src/channels/data/voice-runtime-manifest.json +0 -138
  669. package/src/channels/index.mjs +0 -3268
  670. package/src/channels/lib/config.mjs +0 -292
  671. package/src/channels/lib/drop-trace.mjs +0 -71
  672. package/src/channels/lib/event-pipeline.mjs +0 -81
  673. package/src/channels/lib/holidays.mjs +0 -138
  674. package/src/channels/lib/hook-pipe-server.mjs +0 -822
  675. package/src/channels/lib/output-forwarder.mjs +0 -765
  676. package/src/channels/lib/runtime-paths.mjs +0 -517
  677. package/src/channels/lib/scheduler.mjs +0 -723
  678. package/src/channels/lib/session-discovery.mjs +0 -103
  679. package/src/channels/lib/state-file.mjs +0 -68
  680. package/src/channels/lib/status-snapshot.mjs +0 -219
  681. package/src/channels/lib/tool-format.mjs +0 -140
  682. package/src/channels/lib/transcript-discovery.mjs +0 -195
  683. package/src/channels/lib/voice-runtime-fetcher.mjs +0 -734
  684. package/src/channels/lib/webhook.mjs +0 -1318
  685. package/src/channels/tool-defs.mjs +0 -170
  686. package/src/daemon/host.mjs +0 -118
  687. package/src/daemon/mcp-transport.mjs +0 -47
  688. package/src/daemon/session.mjs +0 -100
  689. package/src/daemon/thin-client.mjs +0 -71
  690. package/src/daemon/transport.mjs +0 -163
  691. package/src/memory/data/runtime-manifest.json +0 -40
  692. package/src/memory/index.mjs +0 -3332
  693. package/src/memory/lib/core-memory-store.mjs +0 -330
  694. package/src/memory/lib/embedding-provider.mjs +0 -269
  695. package/src/memory/lib/embedding-worker.mjs +0 -323
  696. package/src/memory/lib/memory-cycle1.mjs +0 -645
  697. package/src/memory/lib/memory-cycle2.mjs +0 -1284
  698. package/src/memory/lib/memory-cycle3.mjs +0 -540
  699. package/src/memory/lib/memory-embed.mjs +0 -299
  700. package/src/memory/lib/memory-ops-policy.mjs +0 -190
  701. package/src/memory/lib/memory-recall-store.mjs +0 -638
  702. package/src/memory/lib/memory.mjs +0 -412
  703. package/src/memory/lib/pg/adapter.mjs +0 -308
  704. package/src/memory/lib/pg/process.mjs +0 -360
  705. package/src/memory/lib/pg/supervisor.mjs +0 -396
  706. package/src/memory/lib/runtime-fetcher.mjs +0 -458
  707. package/src/memory/lib/trace-store.mjs +0 -728
  708. package/src/memory/tool-defs.mjs +0 -79
  709. package/src/search/index.mjs +0 -1173
  710. package/src/search/lib/backends/anthropic-oauth.mjs +0 -98
  711. package/src/search/lib/backends/exa.mjs +0 -50
  712. package/src/search/lib/backends/firecrawl.mjs +0 -61
  713. package/src/search/lib/backends/gemini-api.mjs +0 -83
  714. package/src/search/lib/backends/grok-oauth.mjs +0 -86
  715. package/src/search/lib/backends/index.mjs +0 -150
  716. package/src/search/lib/backends/openai-api.mjs +0 -144
  717. package/src/search/lib/backends/openai-oauth.mjs +0 -102
  718. package/src/search/lib/backends/openai-web-search.mjs +0 -76
  719. package/src/search/lib/backends/tavily.mjs +0 -55
  720. package/src/search/lib/backends/xai-api.mjs +0 -113
  721. package/src/search/lib/config.mjs +0 -192
  722. package/src/search/lib/provider-usage.mjs +0 -67
  723. package/src/search/lib/providers.mjs +0 -47
  724. package/src/search/lib/search-intent.mjs +0 -109
  725. package/src/search/lib/setup-handler.mjs +0 -261
  726. package/src/search/lib/web-tools.mjs +0 -1219
  727. package/src/search/tool-defs.mjs +0 -83
  728. package/src/setup/defender-exclusion.mjs +0 -183
  729. package/src/shared/atomic-file.mjs +0 -436
  730. package/src/shared/config.mjs +0 -372
  731. package/src/shared/daemon-recycle.mjs +0 -108
  732. package/src/shared/disable-claude-builtins.mjs +0 -91
  733. package/src/shared/err-text.mjs +0 -12
  734. package/src/shared/llm/cost.mjs +0 -66
  735. package/src/shared/llm/http-agent.mjs +0 -123
  736. package/src/shared/open-url.mjs +0 -62
  737. package/src/shared/plugin-paths.mjs +0 -58
  738. package/src/shared/schedules-store.mjs +0 -70
  739. package/src/shared/seed.mjs +0 -136
  740. package/src/shared/user-cwd.mjs +0 -225
  741. package/src/shared/user-data-guard.mjs +0 -244
  742. package/src/status/aggregator.mjs +0 -584
  743. package/src/status/server.mjs +0 -413
  744. package/tools.json +0 -1653
  745. /package/{defaults → src/defaults}/cycle3-review-prompt.md +0 -0
  746. /package/{defaults → src/defaults}/memory-promote-prompt.md +0 -0
  747. /package/{hooks → src/hooks}/lib/permission-rules.cjs +0 -0
  748. /package/{lib → src/lib}/config-cjs.cjs +0 -0
  749. /package/{lib → src/lib}/hook-pipe-path.cjs +0 -0
  750. /package/{lib → src/lib}/mixdog-debug.cjs +0 -0
  751. /package/{lib → src/lib}/text-utils.cjs +0 -0
  752. /package/{rules → src/rules}/bridge/42-cycle3-agent.md +0 -0
  753. /package/src/{agent → runtime/agent}/orchestrator/activity-bus.mjs +0 -0
  754. /package/src/{agent → runtime/agent}/orchestrator/providers/anthropic-betas.mjs +0 -0
  755. /package/src/{agent → runtime/agent}/orchestrator/session/abort-lookup.mjs +0 -0
  756. /package/src/{agent → runtime/agent}/orchestrator/session/cache/post-edit-marks.mjs +0 -0
  757. /package/src/{agent → runtime/agent}/orchestrator/session/cache/scoped-cache-outcome.mjs +0 -0
  758. /package/src/{agent → runtime/agent}/orchestrator/session/cache/util.mjs +0 -0
  759. /package/src/{agent → runtime/agent}/orchestrator/session/read-dedup.mjs +0 -0
  760. /package/src/{agent → runtime/agent}/orchestrator/session/save-session-worker.mjs +0 -0
  761. /package/src/{agent → runtime/agent}/orchestrator/smart-bridge/session-builder.mjs +0 -0
  762. /package/src/{agent → runtime/agent}/orchestrator/tools/bash-policy-scan.mjs +0 -0
  763. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/advisory-lock.mjs +0 -0
  764. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/atomic-write.mjs +0 -0
  765. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/binary-file.mjs +0 -0
  766. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cache-layers.mjs +0 -0
  767. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/cwd-utils.mjs +0 -0
  768. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/device-paths.mjs +0 -0
  769. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diagnostics-tool.mjs +0 -0
  770. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/diff-utils.mjs +0 -0
  771. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/fs-reachability.mjs +0 -0
  772. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/grep-formatting.mjs +0 -0
  773. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/hash-utils.mjs +0 -0
  774. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/list-formatting.mjs +0 -0
  775. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/open-config-tool.mjs +0 -0
  776. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-locks.mjs +0 -0
  777. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/path-utils.mjs +0 -0
  778. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-args.mjs +0 -0
  779. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-batch.mjs +0 -0
  780. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-constants.mjs +0 -0
  781. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image-resize.mjs +0 -0
  782. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-image.mjs +0 -0
  783. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-lines.mjs +0 -0
  784. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-mode-tool.mjs +0 -0
  785. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-range-index.mjs +0 -0
  786. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-ranges.mjs +0 -0
  787. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-special-files.mjs +0 -0
  788. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-tool.mjs +0 -0
  789. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/read-windows.mjs +0 -0
  790. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-analysis.mjs +0 -0
  791. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/shell-output.mjs +0 -0
  792. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-helpers.mjs +0 -0
  793. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/snapshot-validation.mjs +0 -0
  794. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/text-stats.mjs +0 -0
  795. /package/src/{agent → runtime/agent}/orchestrator/tools/builtin/windows-roots.mjs +0 -0
  796. /package/src/{agent → runtime/agent}/orchestrator/tools/code-graph-prewarm-worker.mjs +0 -0
  797. /package/src/{agent → runtime/agent}/orchestrator/tools/env-scrub.mjs +0 -0
  798. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-content-cache.mjs +0 -0
  799. /package/src/{agent → runtime/agent}/orchestrator/tools/mutation-planner.mjs +0 -0
  800. /package/src/{agent → runtime/agent}/orchestrator/tools/next-call-utils.mjs +0 -0
  801. /package/src/{agent → runtime/agent}/orchestrator/tools/result-compression.mjs +0 -0
  802. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-exec-policy.mjs +0 -0
  803. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy-danger-target.mjs +0 -0
  804. /package/src/{agent → runtime/agent}/orchestrator/tools/shell-policy.mjs +0 -0
  805. /package/src/{channels → runtime/channels}/lib/cli-worker-host.mjs +0 -0
  806. /package/src/{channels → runtime/channels}/lib/config-lock.mjs +0 -0
  807. /package/src/{channels → runtime/channels}/lib/event-queue.mjs +0 -0
  808. /package/src/{channels → runtime/channels}/lib/executor.mjs +0 -0
  809. /package/src/{channels → runtime/channels}/lib/format.mjs +0 -0
  810. /package/src/{channels → runtime/channels}/lib/interaction-workflows.mjs +0 -0
  811. /package/src/{channels → runtime/channels}/lib/memory-client.mjs +0 -0
  812. /package/src/{channels → runtime/channels}/lib/session-control.mjs +0 -0
  813. /package/src/{channels → runtime/channels}/lib/settings.mjs +0 -0
  814. /package/src/{channels → runtime/channels}/lib/whisper-server.mjs +0 -0
  815. /package/src/{memory → runtime/memory}/lib/agent-ipc.mjs +0 -0
  816. /package/src/{memory → runtime/memory}/lib/bridge-trace-queries.mjs +0 -0
  817. /package/src/{memory → runtime/memory}/lib/llm-worker-host.mjs +0 -0
  818. /package/src/{memory → runtime/memory}/lib/memory-cycle.mjs +0 -0
  819. /package/src/{memory → runtime/memory}/lib/memory-extraction.mjs +0 -0
  820. /package/src/{memory → runtime/memory}/lib/memory-maintenance-store.mjs +0 -0
  821. /package/src/{memory → runtime/memory}/lib/memory-recall-id-patch.mjs +0 -0
  822. /package/src/{memory → runtime/memory}/lib/memory-recall-read-query.mjs +0 -0
  823. /package/src/{memory → runtime/memory}/lib/memory-recall-scope-filter.mjs +0 -0
  824. /package/src/{memory → runtime/memory}/lib/memory-retrievers.mjs +0 -0
  825. /package/src/{memory → runtime/memory}/lib/memory-score.mjs +0 -0
  826. /package/src/{memory → runtime/memory}/lib/memory-text-utils.mjs +0 -0
  827. /package/src/{memory → runtime/memory}/lib/model-profile.mjs +0 -0
  828. /package/src/{memory → runtime/memory}/lib/project-id-resolver.mjs +0 -0
  829. /package/src/{search → runtime/search}/lib/cache.mjs +0 -0
  830. /package/src/{search → runtime/search}/lib/formatter.mjs +0 -0
  831. /package/src/{search → runtime/search}/lib/state.mjs +0 -0
  832. /package/src/{shared → runtime/shared}/abort-controller.mjs +0 -0
  833. /package/src/{shared → runtime/shared}/llm/index.mjs +0 -0
  834. /package/src/{shared → runtime/shared}/llm/pid-cleanup.mjs +0 -0
  835. /package/src/{shared → runtime/shared}/llm/usage-log.mjs +0 -0
  836. /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);