openvibe 0.57.1

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 (636) hide show
  1. package/CHANGELOG.md +3041 -0
  2. package/README.md +569 -0
  3. package/dist/cli/args.d.ts +44 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +272 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/config-selector.d.ts +10 -0
  8. package/dist/cli/config-selector.d.ts.map +1 -0
  9. package/dist/cli/config-selector.js +26 -0
  10. package/dist/cli/config-selector.js.map +1 -0
  11. package/dist/cli/file-processor.d.ts +10 -0
  12. package/dist/cli/file-processor.d.ts.map +1 -0
  13. package/dist/cli/file-processor.js +68 -0
  14. package/dist/cli/file-processor.js.map +1 -0
  15. package/dist/cli/list-models.d.ts +3 -0
  16. package/dist/cli/list-models.d.ts.map +1 -0
  17. package/dist/cli/list-models.js +30 -0
  18. package/dist/cli/list-models.js.map +1 -0
  19. package/dist/cli/session-picker.d.ts +5 -0
  20. package/dist/cli/session-picker.d.ts.map +1 -0
  21. package/dist/cli/session-picker.js +30 -0
  22. package/dist/cli/session-picker.js.map +1 -0
  23. package/dist/cli.d.ts +3 -0
  24. package/dist/cli.d.ts.map +1 -0
  25. package/dist/cli.js +31 -0
  26. package/dist/cli.js.map +1 -0
  27. package/dist/config.d.ts +29 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +145 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/core/accelerated-client.d.ts +42 -0
  32. package/dist/core/accelerated-client.d.ts.map +1 -0
  33. package/dist/core/accelerated-client.js +97 -0
  34. package/dist/core/accelerated-client.js.map +1 -0
  35. package/dist/core/accelerated-stream.d.ts +41 -0
  36. package/dist/core/accelerated-stream.d.ts.map +1 -0
  37. package/dist/core/accelerated-stream.js +133 -0
  38. package/dist/core/accelerated-stream.js.map +1 -0
  39. package/dist/core/agent-session.d.ts +566 -0
  40. package/dist/core/agent-session.d.ts.map +1 -0
  41. package/dist/core/agent-session.js +2361 -0
  42. package/dist/core/agent-session.js.map +1 -0
  43. package/dist/core/api-concurrency.d.ts +37 -0
  44. package/dist/core/api-concurrency.d.ts.map +1 -0
  45. package/dist/core/api-concurrency.js +179 -0
  46. package/dist/core/api-concurrency.js.map +1 -0
  47. package/dist/core/auth-storage.d.ts +66 -0
  48. package/dist/core/auth-storage.d.ts.map +1 -0
  49. package/dist/core/auth-storage.js +336 -0
  50. package/dist/core/auth-storage.js.map +1 -0
  51. package/dist/core/bash-executor.d.ts +15 -0
  52. package/dist/core/bash-executor.d.ts.map +1 -0
  53. package/dist/core/bash-executor.js +166 -0
  54. package/dist/core/bash-executor.js.map +1 -0
  55. package/dist/core/branded-ai.d.ts +17 -0
  56. package/dist/core/branded-ai.d.ts.map +1 -0
  57. package/dist/core/branded-ai.js +123 -0
  58. package/dist/core/branded-ai.js.map +1 -0
  59. package/dist/core/compaction/branch-summarization.d.ts +37 -0
  60. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  61. package/dist/core/compaction/branch-summarization.js +158 -0
  62. package/dist/core/compaction/branch-summarization.js.map +1 -0
  63. package/dist/core/compaction/compaction.d.ts +56 -0
  64. package/dist/core/compaction/compaction.d.ts.map +1 -0
  65. package/dist/core/compaction/compaction.js +501 -0
  66. package/dist/core/compaction/compaction.js.map +1 -0
  67. package/dist/core/compaction/index.d.ts +4 -0
  68. package/dist/core/compaction/index.d.ts.map +1 -0
  69. package/dist/core/compaction/index.js +4 -0
  70. package/dist/core/compaction/index.js.map +1 -0
  71. package/dist/core/compaction/utils.d.ts +17 -0
  72. package/dist/core/compaction/utils.d.ts.map +1 -0
  73. package/dist/core/compaction/utils.js +120 -0
  74. package/dist/core/compaction/utils.js.map +1 -0
  75. package/dist/core/defaults.d.ts +3 -0
  76. package/dist/core/defaults.d.ts.map +1 -0
  77. package/dist/core/defaults.js +2 -0
  78. package/dist/core/defaults.js.map +1 -0
  79. package/dist/core/diagnostics.d.ts +15 -0
  80. package/dist/core/diagnostics.d.ts.map +1 -0
  81. package/dist/core/diagnostics.js +2 -0
  82. package/dist/core/diagnostics.js.map +1 -0
  83. package/dist/core/event-bus.d.ts +9 -0
  84. package/dist/core/event-bus.d.ts.map +1 -0
  85. package/dist/core/event-bus.js +25 -0
  86. package/dist/core/event-bus.js.map +1 -0
  87. package/dist/core/exec.d.ts +13 -0
  88. package/dist/core/exec.d.ts.map +1 -0
  89. package/dist/core/exec.js +61 -0
  90. package/dist/core/exec.js.map +1 -0
  91. package/dist/core/export-html/ansi-to-html.d.ts +3 -0
  92. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  93. package/dist/core/export-html/ansi-to-html.js +193 -0
  94. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  95. package/dist/core/export-html/index.d.ts +22 -0
  96. package/dist/core/export-html/index.d.ts.map +1 -0
  97. package/dist/core/export-html/index.js +193 -0
  98. package/dist/core/export-html/index.js.map +1 -0
  99. package/dist/core/export-html/template.css +971 -0
  100. package/dist/core/export-html/template.html +54 -0
  101. package/dist/core/export-html/template.js +1583 -0
  102. package/dist/core/export-html/tool-renderer.d.ts +21 -0
  103. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  104. package/dist/core/export-html/tool-renderer.js +51 -0
  105. package/dist/core/export-html/tool-renderer.js.map +1 -0
  106. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  107. package/dist/core/export-html/vendor/marked.min.js +6 -0
  108. package/dist/core/extensions/index.d.ts +8 -0
  109. package/dist/core/extensions/index.d.ts.map +1 -0
  110. package/dist/core/extensions/index.js +5 -0
  111. package/dist/core/extensions/index.js.map +1 -0
  112. package/dist/core/extensions/loader.d.ts +7 -0
  113. package/dist/core/extensions/loader.d.ts.map +1 -0
  114. package/dist/core/extensions/loader.js +349 -0
  115. package/dist/core/extensions/loader.js.map +1 -0
  116. package/dist/core/extensions/runner.d.ts +124 -0
  117. package/dist/core/extensions/runner.d.ts.map +1 -0
  118. package/dist/core/extensions/runner.js +657 -0
  119. package/dist/core/extensions/runner.js.map +1 -0
  120. package/dist/core/extensions/types.d.ts +1032 -0
  121. package/dist/core/extensions/types.d.ts.map +1 -0
  122. package/dist/core/extensions/types.js +35 -0
  123. package/dist/core/extensions/types.js.map +1 -0
  124. package/dist/core/extensions/wrapper.d.ts +8 -0
  125. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  126. package/dist/core/extensions/wrapper.js +79 -0
  127. package/dist/core/extensions/wrapper.js.map +1 -0
  128. package/dist/core/footer-data-provider.d.ts +19 -0
  129. package/dist/core/footer-data-provider.d.ts.map +1 -0
  130. package/dist/core/footer-data-provider.js +113 -0
  131. package/dist/core/footer-data-provider.js.map +1 -0
  132. package/dist/core/index.d.ts +13 -0
  133. package/dist/core/index.d.ts.map +1 -0
  134. package/dist/core/index.js +11 -0
  135. package/dist/core/index.js.map +1 -0
  136. package/dist/core/keybindings.d.ts +22 -0
  137. package/dist/core/keybindings.d.ts.map +1 -0
  138. package/dist/core/keybindings.js +124 -0
  139. package/dist/core/keybindings.js.map +1 -0
  140. package/dist/core/messages.d.ts +51 -0
  141. package/dist/core/messages.d.ts.map +1 -0
  142. package/dist/core/messages.js +102 -0
  143. package/dist/core/messages.js.map +1 -0
  144. package/dist/core/model-registry.d.ts +26 -0
  145. package/dist/core/model-registry.d.ts.map +1 -0
  146. package/dist/core/model-registry.js +61 -0
  147. package/dist/core/model-registry.js.map +1 -0
  148. package/dist/core/model-resolver.d.ts +20 -0
  149. package/dist/core/model-resolver.d.ts.map +1 -0
  150. package/dist/core/model-resolver.js +47 -0
  151. package/dist/core/model-resolver.js.map +1 -0
  152. package/dist/core/multi-gpu-executor.d.ts +50 -0
  153. package/dist/core/multi-gpu-executor.d.ts.map +1 -0
  154. package/dist/core/multi-gpu-executor.js +201 -0
  155. package/dist/core/multi-gpu-executor.js.map +1 -0
  156. package/dist/core/onboarding.d.ts +3 -0
  157. package/dist/core/onboarding.d.ts.map +1 -0
  158. package/dist/core/onboarding.js +109 -0
  159. package/dist/core/onboarding.js.map +1 -0
  160. package/dist/core/package-manager.d.ts +136 -0
  161. package/dist/core/package-manager.d.ts.map +1 -0
  162. package/dist/core/package-manager.js +1375 -0
  163. package/dist/core/package-manager.js.map +1 -0
  164. package/dist/core/prompt-templates.d.ts +18 -0
  165. package/dist/core/prompt-templates.d.ts.map +1 -0
  166. package/dist/core/prompt-templates.js +204 -0
  167. package/dist/core/prompt-templates.js.map +1 -0
  168. package/dist/core/resolve-config-value.d.ts +4 -0
  169. package/dist/core/resolve-config-value.d.ts.map +1 -0
  170. package/dist/core/resolve-config-value.js +45 -0
  171. package/dist/core/resolve-config-value.js.map +1 -0
  172. package/dist/core/resource-loader.d.ts +184 -0
  173. package/dist/core/resource-loader.d.ts.map +1 -0
  174. package/dist/core/resource-loader.js +661 -0
  175. package/dist/core/resource-loader.js.map +1 -0
  176. package/dist/core/response-accelerator.d.ts +51 -0
  177. package/dist/core/response-accelerator.d.ts.map +1 -0
  178. package/dist/core/response-accelerator.js +149 -0
  179. package/dist/core/response-accelerator.js.map +1 -0
  180. package/dist/core/sdk.d.ts +39 -0
  181. package/dist/core/sdk.d.ts.map +1 -0
  182. package/dist/core/sdk.js +151 -0
  183. package/dist/core/sdk.js.map +1 -0
  184. package/dist/core/session-manager.d.ts +160 -0
  185. package/dist/core/session-manager.d.ts.map +1 -0
  186. package/dist/core/session-manager.js +899 -0
  187. package/dist/core/session-manager.js.map +1 -0
  188. package/dist/core/settings-manager.d.ts +220 -0
  189. package/dist/core/settings-manager.d.ts.map +1 -0
  190. package/dist/core/settings-manager.js +673 -0
  191. package/dist/core/settings-manager.js.map +1 -0
  192. package/dist/core/skills.d.ts +33 -0
  193. package/dist/core/skills.d.ts.map +1 -0
  194. package/dist/core/skills.js +326 -0
  195. package/dist/core/skills.js.map +1 -0
  196. package/dist/core/slash-commands.d.ts +15 -0
  197. package/dist/core/slash-commands.d.ts.map +1 -0
  198. package/dist/core/slash-commands.js +19 -0
  199. package/dist/core/slash-commands.js.map +1 -0
  200. package/dist/core/system-prompt.d.ts +23 -0
  201. package/dist/core/system-prompt.d.ts.map +1 -0
  202. package/dist/core/system-prompt.js +154 -0
  203. package/dist/core/system-prompt.js.map +1 -0
  204. package/dist/core/timings.d.ts +3 -0
  205. package/dist/core/timings.d.ts.map +1 -0
  206. package/dist/core/timings.js +21 -0
  207. package/dist/core/timings.js.map +1 -0
  208. package/dist/core/tools/bash.d.ts +40 -0
  209. package/dist/core/tools/bash.d.ts.map +1 -0
  210. package/dist/core/tools/bash.js +212 -0
  211. package/dist/core/tools/bash.js.map +1 -0
  212. package/dist/core/tools/edit-diff.d.ts +29 -0
  213. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  214. package/dist/core/tools/edit-diff.js +182 -0
  215. package/dist/core/tools/edit-diff.js.map +1 -0
  216. package/dist/core/tools/edit.d.ts +28 -0
  217. package/dist/core/tools/edit.d.ts.map +1 -0
  218. package/dist/core/tools/edit.js +129 -0
  219. package/dist/core/tools/edit.js.map +1 -0
  220. package/dist/core/tools/fast-executor.d.ts +33 -0
  221. package/dist/core/tools/fast-executor.d.ts.map +1 -0
  222. package/dist/core/tools/fast-executor.js +83 -0
  223. package/dist/core/tools/fast-executor.js.map +1 -0
  224. package/dist/core/tools/find.d.ts +28 -0
  225. package/dist/core/tools/find.d.ts.map +1 -0
  226. package/dist/core/tools/find.js +50 -0
  227. package/dist/core/tools/find.js.map +1 -0
  228. package/dist/core/tools/grep.d.ts +37 -0
  229. package/dist/core/tools/grep.d.ts.map +1 -0
  230. package/dist/core/tools/grep.js +233 -0
  231. package/dist/core/tools/grep.js.map +1 -0
  232. package/dist/core/tools/index.d.ts +63 -0
  233. package/dist/core/tools/index.d.ts.map +1 -0
  234. package/dist/core/tools/index.js +52 -0
  235. package/dist/core/tools/index.js.map +1 -0
  236. package/dist/core/tools/local-accelerator.d.ts +65 -0
  237. package/dist/core/tools/local-accelerator.d.ts.map +1 -0
  238. package/dist/core/tools/local-accelerator.js +198 -0
  239. package/dist/core/tools/local-accelerator.js.map +1 -0
  240. package/dist/core/tools/ls.d.ts +31 -0
  241. package/dist/core/tools/ls.d.ts.map +1 -0
  242. package/dist/core/tools/ls.js +109 -0
  243. package/dist/core/tools/ls.js.map +1 -0
  244. package/dist/core/tools/parallel-executor.d.ts +60 -0
  245. package/dist/core/tools/parallel-executor.d.ts.map +1 -0
  246. package/dist/core/tools/parallel-executor.js +257 -0
  247. package/dist/core/tools/parallel-executor.js.map +1 -0
  248. package/dist/core/tools/path-utils.d.ts +4 -0
  249. package/dist/core/tools/path-utils.d.ts.map +1 -0
  250. package/dist/core/tools/path-utils.js +70 -0
  251. package/dist/core/tools/path-utils.js.map +1 -0
  252. package/dist/core/tools/read.d.ts +29 -0
  253. package/dist/core/tools/read.d.ts.map +1 -0
  254. package/dist/core/tools/read.js +146 -0
  255. package/dist/core/tools/read.js.map +1 -0
  256. package/dist/core/tools/truncate.d.ts +28 -0
  257. package/dist/core/tools/truncate.d.ts.map +1 -0
  258. package/dist/core/tools/truncate.js +161 -0
  259. package/dist/core/tools/truncate.js.map +1 -0
  260. package/dist/core/tools/write.d.ts +21 -0
  261. package/dist/core/tools/write.d.ts.map +1 -0
  262. package/dist/core/tools/write.js +69 -0
  263. package/dist/core/tools/write.js.map +1 -0
  264. package/dist/core/user-config.d.ts +26 -0
  265. package/dist/core/user-config.d.ts.map +1 -0
  266. package/dist/core/user-config.js +75 -0
  267. package/dist/core/user-config.js.map +1 -0
  268. package/dist/index.d.ts +27 -0
  269. package/dist/index.d.ts.map +1 -0
  270. package/dist/index.js +42 -0
  271. package/dist/index.js.map +1 -0
  272. package/dist/main.d.ts +2 -0
  273. package/dist/main.d.ts.map +1 -0
  274. package/dist/main.js +609 -0
  275. package/dist/main.js.map +1 -0
  276. package/dist/migrations.d.ts +8 -0
  277. package/dist/migrations.d.ts.map +1 -0
  278. package/dist/migrations.js +197 -0
  279. package/dist/migrations.js.map +1 -0
  280. package/dist/modes/index.d.ts +6 -0
  281. package/dist/modes/index.d.ts.map +1 -0
  282. package/dist/modes/index.js +5 -0
  283. package/dist/modes/index.js.map +1 -0
  284. package/dist/modes/interactive/components/armin.d.ts +31 -0
  285. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  286. package/dist/modes/interactive/components/armin.js +306 -0
  287. package/dist/modes/interactive/components/armin.js.map +1 -0
  288. package/dist/modes/interactive/components/assistant-message.d.ts +13 -0
  289. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  290. package/dist/modes/interactive/components/assistant-message.js +82 -0
  291. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  292. package/dist/modes/interactive/components/bash-execution.d.ts +23 -0
  293. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  294. package/dist/modes/interactive/components/bash-execution.js +126 -0
  295. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  296. package/dist/modes/interactive/components/bordered-loader.d.ts +15 -0
  297. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  298. package/dist/modes/interactive/components/bordered-loader.js +50 -0
  299. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  300. package/dist/modes/interactive/components/branch-summary-message.d.ts +12 -0
  301. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  302. package/dist/modes/interactive/components/branch-summary-message.js +40 -0
  303. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  304. package/dist/modes/interactive/components/compaction-summary-message.d.ts +12 -0
  305. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  306. package/dist/modes/interactive/components/compaction-summary-message.js +41 -0
  307. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  308. package/dist/modes/interactive/components/config-selector.d.ts +68 -0
  309. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  310. package/dist/modes/interactive/components/config-selector.js +451 -0
  311. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  312. package/dist/modes/interactive/components/countdown-timer.d.ts +11 -0
  313. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  314. package/dist/modes/interactive/components/countdown-timer.js +30 -0
  315. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  316. package/dist/modes/interactive/components/custom-editor.d.ts +14 -0
  317. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  318. package/dist/modes/interactive/components/custom-editor.js +52 -0
  319. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  320. package/dist/modes/interactive/components/custom-message.d.ts +16 -0
  321. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  322. package/dist/modes/interactive/components/custom-message.js +66 -0
  323. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  324. package/dist/modes/interactive/components/daxnuts.d.ts +18 -0
  325. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  326. package/dist/modes/interactive/components/daxnuts.js +130 -0
  327. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  328. package/dist/modes/interactive/components/diff.d.ts +5 -0
  329. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  330. package/dist/modes/interactive/components/diff.js +106 -0
  331. package/dist/modes/interactive/components/diff.js.map +1 -0
  332. package/dist/modes/interactive/components/dynamic-border.d.ts +8 -0
  333. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  334. package/dist/modes/interactive/components/dynamic-border.js +12 -0
  335. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  336. package/dist/modes/interactive/components/extension-editor.d.ts +16 -0
  337. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  338. package/dist/modes/interactive/components/extension-editor.js +95 -0
  339. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  340. package/dist/modes/interactive/components/extension-input.d.ts +20 -0
  341. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  342. package/dist/modes/interactive/components/extension-input.js +57 -0
  343. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  344. package/dist/modes/interactive/components/extension-selector.d.ts +20 -0
  345. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  346. package/dist/modes/interactive/components/extension-selector.js +74 -0
  347. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  348. package/dist/modes/interactive/components/footer.d.ts +14 -0
  349. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  350. package/dist/modes/interactive/components/footer.js +78 -0
  351. package/dist/modes/interactive/components/footer.js.map +1 -0
  352. package/dist/modes/interactive/components/index.d.ts +28 -0
  353. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  354. package/dist/modes/interactive/components/index.js +28 -0
  355. package/dist/modes/interactive/components/index.js.map +1 -0
  356. package/dist/modes/interactive/components/keybinding-hints.d.ts +8 -0
  357. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  358. package/dist/modes/interactive/components/keybinding-hints.js +25 -0
  359. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  360. package/dist/modes/interactive/components/onboarding-wizard.d.ts +23 -0
  361. package/dist/modes/interactive/components/onboarding-wizard.d.ts.map +1 -0
  362. package/dist/modes/interactive/components/onboarding-wizard.js +250 -0
  363. package/dist/modes/interactive/components/onboarding-wizard.js.map +1 -0
  364. package/dist/modes/interactive/components/session-selector-search.d.ts +21 -0
  365. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  366. package/dist/modes/interactive/components/session-selector-search.js +149 -0
  367. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  368. package/dist/modes/interactive/components/session-selector.d.ts +89 -0
  369. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  370. package/dist/modes/interactive/components/session-selector.js +786 -0
  371. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  372. package/dist/modes/interactive/components/settings-selector.d.ts +55 -0
  373. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  374. package/dist/modes/interactive/components/settings-selector.js +273 -0
  375. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  376. package/dist/modes/interactive/components/show-images-selector.d.ts +7 -0
  377. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  378. package/dist/modes/interactive/components/show-images-selector.js +28 -0
  379. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  380. package/dist/modes/interactive/components/skill-invocation-message.d.ts +12 -0
  381. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  382. package/dist/modes/interactive/components/skill-invocation-message.js +40 -0
  383. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  384. package/dist/modes/interactive/components/theme-selector.d.ts +8 -0
  385. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  386. package/dist/modes/interactive/components/theme-selector.js +38 -0
  387. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  388. package/dist/modes/interactive/components/thinking-selector.d.ts +8 -0
  389. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  390. package/dist/modes/interactive/components/thinking-selector.js +40 -0
  391. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  392. package/dist/modes/interactive/components/tool-execution.d.ts +54 -0
  393. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  394. package/dist/modes/interactive/components/tool-execution.js +704 -0
  395. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  396. package/dist/modes/interactive/components/tree-selector.d.ts +59 -0
  397. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  398. package/dist/modes/interactive/components/tree-selector.js +929 -0
  399. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  400. package/dist/modes/interactive/components/user-message-selector.d.ts +24 -0
  401. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  402. package/dist/modes/interactive/components/user-message-selector.js +89 -0
  403. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  404. package/dist/modes/interactive/components/user-message.d.ts +6 -0
  405. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  406. package/dist/modes/interactive/components/user-message.js +24 -0
  407. package/dist/modes/interactive/components/user-message.js.map +1 -0
  408. package/dist/modes/interactive/components/visual-truncate.d.ts +6 -0
  409. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  410. package/dist/modes/interactive/components/visual-truncate.js +15 -0
  411. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  412. package/dist/modes/interactive/interactive-mode.d.ts +177 -0
  413. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  414. package/dist/modes/interactive/interactive-mode.js +3037 -0
  415. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  416. package/dist/modes/interactive/theme/dark.json +85 -0
  417. package/dist/modes/interactive/theme/light.json +84 -0
  418. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  419. package/dist/modes/interactive/theme/theme.d.ts +60 -0
  420. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  421. package/dist/modes/interactive/theme/theme.js +852 -0
  422. package/dist/modes/interactive/theme/theme.js.map +1 -0
  423. package/dist/modes/print-mode.d.ts +10 -0
  424. package/dist/modes/print-mode.d.ts.map +1 -0
  425. package/dist/modes/print-mode.js +80 -0
  426. package/dist/modes/print-mode.js.map +1 -0
  427. package/dist/modes/rpc/jsonl.d.ts +4 -0
  428. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  429. package/dist/modes/rpc/jsonl.js +36 -0
  430. package/dist/modes/rpc/jsonl.js.map +1 -0
  431. package/dist/modes/rpc/rpc-client.d.ts +94 -0
  432. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  433. package/dist/modes/rpc/rpc-client.js +262 -0
  434. package/dist/modes/rpc/rpc-client.js.map +1 -0
  435. package/dist/modes/rpc/rpc-mode.d.ts +3 -0
  436. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  437. package/dist/modes/rpc/rpc-mode.js +227 -0
  438. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  439. package/dist/modes/rpc/rpc-types.d.ts +395 -0
  440. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  441. package/dist/modes/rpc/rpc-types.js +2 -0
  442. package/dist/modes/rpc/rpc-types.js.map +1 -0
  443. package/dist/utils/changelog.d.ts +11 -0
  444. package/dist/utils/changelog.d.ts.map +1 -0
  445. package/dist/utils/changelog.js +69 -0
  446. package/dist/utils/changelog.js.map +1 -0
  447. package/dist/utils/clipboard-image.d.ts +11 -0
  448. package/dist/utils/clipboard-image.d.ts.map +1 -0
  449. package/dist/utils/clipboard-image.js +157 -0
  450. package/dist/utils/clipboard-image.js.map +1 -0
  451. package/dist/utils/clipboard-native.d.ts +7 -0
  452. package/dist/utils/clipboard-native.d.ts.map +1 -0
  453. package/dist/utils/clipboard-native.js +14 -0
  454. package/dist/utils/clipboard-native.js.map +1 -0
  455. package/dist/utils/clipboard.d.ts +2 -0
  456. package/dist/utils/clipboard.d.ts.map +1 -0
  457. package/dist/utils/clipboard.js +55 -0
  458. package/dist/utils/clipboard.js.map +1 -0
  459. package/dist/utils/frontmatter.d.ts +8 -0
  460. package/dist/utils/frontmatter.d.ts.map +1 -0
  461. package/dist/utils/frontmatter.js +26 -0
  462. package/dist/utils/frontmatter.js.map +1 -0
  463. package/dist/utils/git.d.ts +10 -0
  464. package/dist/utils/git.d.ts.map +1 -0
  465. package/dist/utils/git.js +156 -0
  466. package/dist/utils/git.js.map +1 -0
  467. package/dist/utils/image-convert.d.ts +5 -0
  468. package/dist/utils/image-convert.d.ts.map +1 -0
  469. package/dist/utils/image-convert.js +28 -0
  470. package/dist/utils/image-convert.js.map +1 -0
  471. package/dist/utils/image-resize.d.ts +19 -0
  472. package/dist/utils/image-resize.d.ts.map +1 -0
  473. package/dist/utils/image-resize.js +152 -0
  474. package/dist/utils/image-resize.js.map +1 -0
  475. package/dist/utils/mime.d.ts +2 -0
  476. package/dist/utils/mime.d.ts.map +1 -0
  477. package/dist/utils/mime.js +26 -0
  478. package/dist/utils/mime.js.map +1 -0
  479. package/dist/utils/photon.d.ts +3 -0
  480. package/dist/utils/photon.d.ts.map +1 -0
  481. package/dist/utils/photon.js +102 -0
  482. package/dist/utils/photon.js.map +1 -0
  483. package/dist/utils/shell.d.ts +8 -0
  484. package/dist/utils/shell.d.ts.map +1 -0
  485. package/dist/utils/shell.js +135 -0
  486. package/dist/utils/shell.js.map +1 -0
  487. package/dist/utils/sleep.d.ts +2 -0
  488. package/dist/utils/sleep.d.ts.map +1 -0
  489. package/dist/utils/sleep.js +14 -0
  490. package/dist/utils/sleep.js.map +1 -0
  491. package/dist/utils/tools-manager.d.ts +3 -0
  492. package/dist/utils/tools-manager.d.ts.map +1 -0
  493. package/dist/utils/tools-manager.js +227 -0
  494. package/dist/utils/tools-manager.js.map +1 -0
  495. package/docs/compaction.md +392 -0
  496. package/docs/custom-provider.md +592 -0
  497. package/docs/development.md +69 -0
  498. package/docs/extensions.md +2023 -0
  499. package/docs/images/doom-extension.png +0 -0
  500. package/docs/images/exy.png +0 -0
  501. package/docs/images/interactive-mode.png +0 -0
  502. package/docs/images/tree-view.png +0 -0
  503. package/docs/json.md +79 -0
  504. package/docs/keybindings.md +182 -0
  505. package/docs/models.md +297 -0
  506. package/docs/packages.md +209 -0
  507. package/docs/prompt-templates.md +67 -0
  508. package/docs/providers.md +188 -0
  509. package/docs/rpc.md +1354 -0
  510. package/docs/sdk.md +968 -0
  511. package/docs/session.md +412 -0
  512. package/docs/settings.md +225 -0
  513. package/docs/shell-aliases.md +13 -0
  514. package/docs/skills.md +231 -0
  515. package/docs/terminal-setup.md +87 -0
  516. package/docs/termux.md +127 -0
  517. package/docs/themes.md +295 -0
  518. package/docs/tmux.md +61 -0
  519. package/docs/tree.md +228 -0
  520. package/docs/tui.md +887 -0
  521. package/docs/windows.md +17 -0
  522. package/examples/README.md +25 -0
  523. package/examples/extensions/README.md +205 -0
  524. package/examples/extensions/antigravity-image-gen.ts +415 -0
  525. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  526. package/examples/extensions/bash-spawn-hook.ts +30 -0
  527. package/examples/extensions/bookmark.ts +50 -0
  528. package/examples/extensions/built-in-tool-renderer.ts +246 -0
  529. package/examples/extensions/claude-rules.ts +86 -0
  530. package/examples/extensions/commands.ts +72 -0
  531. package/examples/extensions/confirm-destructive.ts +59 -0
  532. package/examples/extensions/custom-compaction.ts +114 -0
  533. package/examples/extensions/custom-footer.ts +64 -0
  534. package/examples/extensions/custom-header.ts +73 -0
  535. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  536. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  537. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  538. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  539. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  540. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  541. package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
  542. package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
  543. package/examples/extensions/dirty-repo-guard.ts +56 -0
  544. package/examples/extensions/doom-overlay/README.md +46 -0
  545. package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
  546. package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
  547. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  548. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  549. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  550. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  551. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  552. package/examples/extensions/doom-overlay/index.ts +74 -0
  553. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  554. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  555. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  556. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  557. package/examples/extensions/dynamic-resources/index.ts +15 -0
  558. package/examples/extensions/dynamic-tools.ts +74 -0
  559. package/examples/extensions/event-bus.ts +43 -0
  560. package/examples/extensions/file-trigger.ts +41 -0
  561. package/examples/extensions/git-checkpoint.ts +53 -0
  562. package/examples/extensions/handoff.ts +150 -0
  563. package/examples/extensions/hello.ts +25 -0
  564. package/examples/extensions/inline-bash.ts +94 -0
  565. package/examples/extensions/input-transform.ts +43 -0
  566. package/examples/extensions/interactive-shell.ts +196 -0
  567. package/examples/extensions/mac-system-theme.ts +47 -0
  568. package/examples/extensions/message-renderer.ts +59 -0
  569. package/examples/extensions/minimal-mode.ts +426 -0
  570. package/examples/extensions/modal-editor.ts +85 -0
  571. package/examples/extensions/model-status.ts +31 -0
  572. package/examples/extensions/notify.ts +55 -0
  573. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  574. package/examples/extensions/overlay-test.ts +150 -0
  575. package/examples/extensions/permission-gate.ts +34 -0
  576. package/examples/extensions/pirate.ts +47 -0
  577. package/examples/extensions/plan-mode/README.md +65 -0
  578. package/examples/extensions/plan-mode/index.ts +340 -0
  579. package/examples/extensions/plan-mode/utils.ts +168 -0
  580. package/examples/extensions/preset.ts +398 -0
  581. package/examples/extensions/protected-paths.ts +30 -0
  582. package/examples/extensions/provider-payload.ts +14 -0
  583. package/examples/extensions/qna.ts +119 -0
  584. package/examples/extensions/question.ts +264 -0
  585. package/examples/extensions/questionnaire.ts +427 -0
  586. package/examples/extensions/rainbow-editor.ts +88 -0
  587. package/examples/extensions/reload-runtime.ts +37 -0
  588. package/examples/extensions/rpc-demo.ts +124 -0
  589. package/examples/extensions/sandbox/index.ts +318 -0
  590. package/examples/extensions/sandbox/package-lock.json +92 -0
  591. package/examples/extensions/sandbox/package.json +19 -0
  592. package/examples/extensions/send-user-message.ts +97 -0
  593. package/examples/extensions/session-name.ts +27 -0
  594. package/examples/extensions/shutdown-command.ts +63 -0
  595. package/examples/extensions/snake.ts +343 -0
  596. package/examples/extensions/space-invaders.ts +560 -0
  597. package/examples/extensions/ssh.ts +220 -0
  598. package/examples/extensions/status-line.ts +40 -0
  599. package/examples/extensions/subagent/README.md +172 -0
  600. package/examples/extensions/subagent/agents/planner.md +37 -0
  601. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  602. package/examples/extensions/subagent/agents/scout.md +50 -0
  603. package/examples/extensions/subagent/agents/worker.md +24 -0
  604. package/examples/extensions/subagent/agents.ts +126 -0
  605. package/examples/extensions/subagent/index.ts +964 -0
  606. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  607. package/examples/extensions/subagent/prompts/implement.md +10 -0
  608. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  609. package/examples/extensions/summarize.ts +195 -0
  610. package/examples/extensions/system-prompt-header.ts +17 -0
  611. package/examples/extensions/timed-confirm.ts +70 -0
  612. package/examples/extensions/titlebar-spinner.ts +58 -0
  613. package/examples/extensions/todo.ts +299 -0
  614. package/examples/extensions/tool-override.ts +143 -0
  615. package/examples/extensions/tools.ts +146 -0
  616. package/examples/extensions/trigger-compact.ts +40 -0
  617. package/examples/extensions/truncated-tool.ts +192 -0
  618. package/examples/extensions/widget-placement.ts +17 -0
  619. package/examples/extensions/with-deps/index.ts +32 -0
  620. package/examples/extensions/with-deps/package-lock.json +31 -0
  621. package/examples/extensions/with-deps/package.json +22 -0
  622. package/examples/rpc-extension-ui.ts +632 -0
  623. package/examples/sdk/01-minimal.ts +22 -0
  624. package/examples/sdk/02-custom-model.ts +49 -0
  625. package/examples/sdk/03-custom-prompt.ts +55 -0
  626. package/examples/sdk/04-skills.ts +46 -0
  627. package/examples/sdk/05-tools.ts +56 -0
  628. package/examples/sdk/06-extensions.ts +88 -0
  629. package/examples/sdk/07-context-files.ts +40 -0
  630. package/examples/sdk/08-prompt-templates.ts +47 -0
  631. package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
  632. package/examples/sdk/10-settings.ts +51 -0
  633. package/examples/sdk/11-sessions.ts +48 -0
  634. package/examples/sdk/12-full-control.ts +82 -0
  635. package/examples/sdk/README.md +144 -0
  636. package/package.json +100 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-diff.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"AAIA,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAM/D;AACD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAE9E;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS3D;AACD,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;CAC9B;AACD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA8BhF;AACD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAEvE;AACD,wBAAgB,kBAAkB,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,YAAY,SAAI,GACd;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAuExD;AACD,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AACD,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAC;CACd;AACD,wBAAsB,eAAe,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,cAAc,GAAG,aAAa,CAAC,CAyCzC","sourcesContent":["import * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trimEnd())\n\t\t.join(\"\\n\")\n\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \");\n}\nexport interface FuzzyMatchResult {\n\tfound: boolean;\n\tindex: number;\n\tmatchLength: number;\n\tusedFuzzyMatch: boolean;\n\tcontentForReplacement: string;\n}\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: fuzzyContent,\n\t};\n}\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\t\tif (part.added || part.removed) {\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tif (lastWasChange || nextPartIsChange) {\n\t\t\t\tlet linesToShow = raw;\n\t\t\t\tlet skipStart = 0;\n\t\t\t\tlet skipEnd = 0;\n\t\t\t\tif (!lastWasChange) {\n\t\t\t\t\tskipStart = Math.max(0, raw.length - contextLines);\n\t\t\t\t\tlinesToShow = raw.slice(skipStart);\n\t\t\t\t}\n\t\t\t\tif (!nextPartIsChange && linesToShow.length > contextLines) {\n\t\t\t\t\tskipEnd = linesToShow.length - contextLines;\n\t\t\t\t\tlinesToShow = linesToShow.slice(0, contextLines);\n\t\t\t\t}\n\t\t\t\tif (skipStart > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skipStart;\n\t\t\t\t\tnewLineNum += skipStart;\n\t\t\t\t}\n\t\t\t\tfor (const line of linesToShow) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t\tif (skipEnd > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skipEnd;\n\t\t\t\t\tnewLineNum += skipEnd;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\nexport interface EditDiffError {\n\terror: string;\n}\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\ttry {\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch {\n\t\t\treturn { error: `File not found: ${path}` };\n\t\t}\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst normalizedOldText = normalizeToLF(oldText);\n\t\tconst normalizedNewText = normalizeToLF(newText);\n\t\tconst matchResult = fuzzyFindText(normalizedContent, normalizedOldText);\n\t\tif (!matchResult.found) {\n\t\t\treturn {\n\t\t\t\terror: `Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t};\n\t\t}\n\t\tconst fuzzyContent = normalizeForFuzzyMatch(normalizedContent);\n\t\tconst fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);\n\t\tconst occurrences = fuzzyContent.split(fuzzyOldText).length - 1;\n\t\tif (occurrences > 1) {\n\t\t\treturn {\n\t\t\t\terror: `Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t};\n\t\t}\n\t\tconst baseContent = matchResult.contentForReplacement;\n\t\tconst newContent =\n\t\t\tbaseContent.substring(0, matchResult.index) +\n\t\t\tnormalizedNewText +\n\t\t\tbaseContent.substring(matchResult.index + matchResult.matchLength);\n\t\tif (baseContent === newContent) {\n\t\t\treturn {\n\t\t\t\terror: `No changes would be made to ${path}. The replacement produces identical content.`,\n\t\t\t};\n\t\t}\n\t\treturn generateDiffString(baseContent, newContent);\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n"]}
@@ -0,0 +1,182 @@
1
+ import * as Diff from "diff";
2
+ import { constants } from "fs";
3
+ import { access, readFile } from "fs/promises";
4
+ import { resolveToCwd } from "./path-utils.js";
5
+ export function detectLineEnding(content) {
6
+ const crlfIdx = content.indexOf("\r\n");
7
+ const lfIdx = content.indexOf("\n");
8
+ if (lfIdx === -1)
9
+ return "\n";
10
+ if (crlfIdx === -1)
11
+ return "\n";
12
+ return crlfIdx < lfIdx ? "\r\n" : "\n";
13
+ }
14
+ export function normalizeToLF(text) {
15
+ return text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
16
+ }
17
+ export function restoreLineEndings(text, ending) {
18
+ return ending === "\r\n" ? text.replace(/\n/g, "\r\n") : text;
19
+ }
20
+ export function normalizeForFuzzyMatch(text) {
21
+ return text
22
+ .split("\n")
23
+ .map((line) => line.trimEnd())
24
+ .join("\n")
25
+ .replace(/[\u2018\u2019\u201A\u201B]/g, "'")
26
+ .replace(/[\u201C\u201D\u201E\u201F]/g, '"')
27
+ .replace(/[\u2010\u2011\u2012\u2013\u2014\u2015\u2212]/g, "-")
28
+ .replace(/[\u00A0\u2002-\u200A\u202F\u205F\u3000]/g, " ");
29
+ }
30
+ export function fuzzyFindText(content, oldText) {
31
+ const exactIndex = content.indexOf(oldText);
32
+ if (exactIndex !== -1) {
33
+ return {
34
+ found: true,
35
+ index: exactIndex,
36
+ matchLength: oldText.length,
37
+ usedFuzzyMatch: false,
38
+ contentForReplacement: content,
39
+ };
40
+ }
41
+ const fuzzyContent = normalizeForFuzzyMatch(content);
42
+ const fuzzyOldText = normalizeForFuzzyMatch(oldText);
43
+ const fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);
44
+ if (fuzzyIndex === -1) {
45
+ return {
46
+ found: false,
47
+ index: -1,
48
+ matchLength: 0,
49
+ usedFuzzyMatch: false,
50
+ contentForReplacement: content,
51
+ };
52
+ }
53
+ return {
54
+ found: true,
55
+ index: fuzzyIndex,
56
+ matchLength: fuzzyOldText.length,
57
+ usedFuzzyMatch: true,
58
+ contentForReplacement: fuzzyContent,
59
+ };
60
+ }
61
+ export function stripBom(content) {
62
+ return content.startsWith("\uFEFF") ? { bom: "\uFEFF", text: content.slice(1) } : { bom: "", text: content };
63
+ }
64
+ export function generateDiffString(oldContent, newContent, contextLines = 4) {
65
+ const parts = Diff.diffLines(oldContent, newContent);
66
+ const output = [];
67
+ const oldLines = oldContent.split("\n");
68
+ const newLines = newContent.split("\n");
69
+ const maxLineNum = Math.max(oldLines.length, newLines.length);
70
+ const lineNumWidth = String(maxLineNum).length;
71
+ let oldLineNum = 1;
72
+ let newLineNum = 1;
73
+ let lastWasChange = false;
74
+ let firstChangedLine;
75
+ for (let i = 0; i < parts.length; i++) {
76
+ const part = parts[i];
77
+ const raw = part.value.split("\n");
78
+ if (raw[raw.length - 1] === "") {
79
+ raw.pop();
80
+ }
81
+ if (part.added || part.removed) {
82
+ if (firstChangedLine === undefined) {
83
+ firstChangedLine = newLineNum;
84
+ }
85
+ for (const line of raw) {
86
+ if (part.added) {
87
+ const lineNum = String(newLineNum).padStart(lineNumWidth, " ");
88
+ output.push(`+${lineNum} ${line}`);
89
+ newLineNum++;
90
+ }
91
+ else {
92
+ const lineNum = String(oldLineNum).padStart(lineNumWidth, " ");
93
+ output.push(`-${lineNum} ${line}`);
94
+ oldLineNum++;
95
+ }
96
+ }
97
+ lastWasChange = true;
98
+ }
99
+ else {
100
+ const nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);
101
+ if (lastWasChange || nextPartIsChange) {
102
+ let linesToShow = raw;
103
+ let skipStart = 0;
104
+ let skipEnd = 0;
105
+ if (!lastWasChange) {
106
+ skipStart = Math.max(0, raw.length - contextLines);
107
+ linesToShow = raw.slice(skipStart);
108
+ }
109
+ if (!nextPartIsChange && linesToShow.length > contextLines) {
110
+ skipEnd = linesToShow.length - contextLines;
111
+ linesToShow = linesToShow.slice(0, contextLines);
112
+ }
113
+ if (skipStart > 0) {
114
+ output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
115
+ oldLineNum += skipStart;
116
+ newLineNum += skipStart;
117
+ }
118
+ for (const line of linesToShow) {
119
+ const lineNum = String(oldLineNum).padStart(lineNumWidth, " ");
120
+ output.push(` ${lineNum} ${line}`);
121
+ oldLineNum++;
122
+ newLineNum++;
123
+ }
124
+ if (skipEnd > 0) {
125
+ output.push(` ${"".padStart(lineNumWidth, " ")} ...`);
126
+ oldLineNum += skipEnd;
127
+ newLineNum += skipEnd;
128
+ }
129
+ }
130
+ else {
131
+ oldLineNum += raw.length;
132
+ newLineNum += raw.length;
133
+ }
134
+ lastWasChange = false;
135
+ }
136
+ }
137
+ return { diff: output.join("\n"), firstChangedLine };
138
+ }
139
+ export async function computeEditDiff(path, oldText, newText, cwd) {
140
+ const absolutePath = resolveToCwd(path, cwd);
141
+ try {
142
+ try {
143
+ await access(absolutePath, constants.R_OK);
144
+ }
145
+ catch {
146
+ return { error: `File not found: ${path}` };
147
+ }
148
+ const rawContent = await readFile(absolutePath, "utf-8");
149
+ const { text: content } = stripBom(rawContent);
150
+ const normalizedContent = normalizeToLF(content);
151
+ const normalizedOldText = normalizeToLF(oldText);
152
+ const normalizedNewText = normalizeToLF(newText);
153
+ const matchResult = fuzzyFindText(normalizedContent, normalizedOldText);
154
+ if (!matchResult.found) {
155
+ return {
156
+ error: `Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,
157
+ };
158
+ }
159
+ const fuzzyContent = normalizeForFuzzyMatch(normalizedContent);
160
+ const fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);
161
+ const occurrences = fuzzyContent.split(fuzzyOldText).length - 1;
162
+ if (occurrences > 1) {
163
+ return {
164
+ error: `Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,
165
+ };
166
+ }
167
+ const baseContent = matchResult.contentForReplacement;
168
+ const newContent = baseContent.substring(0, matchResult.index) +
169
+ normalizedNewText +
170
+ baseContent.substring(matchResult.index + matchResult.matchLength);
171
+ if (baseContent === newContent) {
172
+ return {
173
+ error: `No changes would be made to ${path}. The replacement produces identical content.`,
174
+ };
175
+ }
176
+ return generateDiffString(baseContent, newContent);
177
+ }
178
+ catch (err) {
179
+ return { error: err instanceof Error ? err.message : String(err) };
180
+ }
181
+ }
182
+ //# sourceMappingURL=edit-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-diff.js","sourceRoot":"","sources":["../../../src/core/tools/edit-diff.ts"],"names":[],"mappings":"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","sourcesContent":["import * as Diff from \"diff\";\nimport { constants } from \"fs\";\nimport { access, readFile } from \"fs/promises\";\nimport { resolveToCwd } from \"./path-utils.js\";\nexport function detectLineEnding(content: string): \"\\r\\n\" | \"\\n\" {\n\tconst crlfIdx = content.indexOf(\"\\r\\n\");\n\tconst lfIdx = content.indexOf(\"\\n\");\n\tif (lfIdx === -1) return \"\\n\";\n\tif (crlfIdx === -1) return \"\\n\";\n\treturn crlfIdx < lfIdx ? \"\\r\\n\" : \"\\n\";\n}\nexport function normalizeToLF(text: string): string {\n\treturn text.replace(/\\r\\n/g, \"\\n\").replace(/\\r/g, \"\\n\");\n}\nexport function restoreLineEndings(text: string, ending: \"\\r\\n\" | \"\\n\"): string {\n\treturn ending === \"\\r\\n\" ? text.replace(/\\n/g, \"\\r\\n\") : text;\n}\nexport function normalizeForFuzzyMatch(text: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trimEnd())\n\t\t.join(\"\\n\")\n\t\t.replace(/[\\u2018\\u2019\\u201A\\u201B]/g, \"'\")\n\t\t.replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n\t\t.replace(/[\\u2010\\u2011\\u2012\\u2013\\u2014\\u2015\\u2212]/g, \"-\")\n\t\t.replace(/[\\u00A0\\u2002-\\u200A\\u202F\\u205F\\u3000]/g, \" \");\n}\nexport interface FuzzyMatchResult {\n\tfound: boolean;\n\tindex: number;\n\tmatchLength: number;\n\tusedFuzzyMatch: boolean;\n\tcontentForReplacement: string;\n}\nexport function fuzzyFindText(content: string, oldText: string): FuzzyMatchResult {\n\tconst exactIndex = content.indexOf(oldText);\n\tif (exactIndex !== -1) {\n\t\treturn {\n\t\t\tfound: true,\n\t\t\tindex: exactIndex,\n\t\t\tmatchLength: oldText.length,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\tconst fuzzyContent = normalizeForFuzzyMatch(content);\n\tconst fuzzyOldText = normalizeForFuzzyMatch(oldText);\n\tconst fuzzyIndex = fuzzyContent.indexOf(fuzzyOldText);\n\tif (fuzzyIndex === -1) {\n\t\treturn {\n\t\t\tfound: false,\n\t\t\tindex: -1,\n\t\t\tmatchLength: 0,\n\t\t\tusedFuzzyMatch: false,\n\t\t\tcontentForReplacement: content,\n\t\t};\n\t}\n\treturn {\n\t\tfound: true,\n\t\tindex: fuzzyIndex,\n\t\tmatchLength: fuzzyOldText.length,\n\t\tusedFuzzyMatch: true,\n\t\tcontentForReplacement: fuzzyContent,\n\t};\n}\nexport function stripBom(content: string): { bom: string; text: string } {\n\treturn content.startsWith(\"\\uFEFF\") ? { bom: \"\\uFEFF\", text: content.slice(1) } : { bom: \"\", text: content };\n}\nexport function generateDiffString(\n\toldContent: string,\n\tnewContent: string,\n\tcontextLines = 4,\n): { diff: string; firstChangedLine: number | undefined } {\n\tconst parts = Diff.diffLines(oldContent, newContent);\n\tconst output: string[] = [];\n\tconst oldLines = oldContent.split(\"\\n\");\n\tconst newLines = newContent.split(\"\\n\");\n\tconst maxLineNum = Math.max(oldLines.length, newLines.length);\n\tconst lineNumWidth = String(maxLineNum).length;\n\tlet oldLineNum = 1;\n\tlet newLineNum = 1;\n\tlet lastWasChange = false;\n\tlet firstChangedLine: number | undefined;\n\tfor (let i = 0; i < parts.length; i++) {\n\t\tconst part = parts[i];\n\t\tconst raw = part.value.split(\"\\n\");\n\t\tif (raw[raw.length - 1] === \"\") {\n\t\t\traw.pop();\n\t\t}\n\t\tif (part.added || part.removed) {\n\t\t\tif (firstChangedLine === undefined) {\n\t\t\t\tfirstChangedLine = newLineNum;\n\t\t\t}\n\t\t\tfor (const line of raw) {\n\t\t\t\tif (part.added) {\n\t\t\t\t\tconst lineNum = String(newLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`+${lineNum} ${line}`);\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t} else {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(`-${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tlastWasChange = true;\n\t\t} else {\n\t\t\tconst nextPartIsChange = i < parts.length - 1 && (parts[i + 1].added || parts[i + 1].removed);\n\t\t\tif (lastWasChange || nextPartIsChange) {\n\t\t\t\tlet linesToShow = raw;\n\t\t\t\tlet skipStart = 0;\n\t\t\t\tlet skipEnd = 0;\n\t\t\t\tif (!lastWasChange) {\n\t\t\t\t\tskipStart = Math.max(0, raw.length - contextLines);\n\t\t\t\t\tlinesToShow = raw.slice(skipStart);\n\t\t\t\t}\n\t\t\t\tif (!nextPartIsChange && linesToShow.length > contextLines) {\n\t\t\t\t\tskipEnd = linesToShow.length - contextLines;\n\t\t\t\t\tlinesToShow = linesToShow.slice(0, contextLines);\n\t\t\t\t}\n\t\t\t\tif (skipStart > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skipStart;\n\t\t\t\t\tnewLineNum += skipStart;\n\t\t\t\t}\n\t\t\t\tfor (const line of linesToShow) {\n\t\t\t\t\tconst lineNum = String(oldLineNum).padStart(lineNumWidth, \" \");\n\t\t\t\t\toutput.push(` ${lineNum} ${line}`);\n\t\t\t\t\toldLineNum++;\n\t\t\t\t\tnewLineNum++;\n\t\t\t\t}\n\t\t\t\tif (skipEnd > 0) {\n\t\t\t\t\toutput.push(` ${\"\".padStart(lineNumWidth, \" \")} ...`);\n\t\t\t\t\toldLineNum += skipEnd;\n\t\t\t\t\tnewLineNum += skipEnd;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\toldLineNum += raw.length;\n\t\t\t\tnewLineNum += raw.length;\n\t\t\t}\n\t\t\tlastWasChange = false;\n\t\t}\n\t}\n\treturn { diff: output.join(\"\\n\"), firstChangedLine };\n}\nexport interface EditDiffResult {\n\tdiff: string;\n\tfirstChangedLine: number | undefined;\n}\nexport interface EditDiffError {\n\terror: string;\n}\nexport async function computeEditDiff(\n\tpath: string,\n\toldText: string,\n\tnewText: string,\n\tcwd: string,\n): Promise<EditDiffResult | EditDiffError> {\n\tconst absolutePath = resolveToCwd(path, cwd);\n\ttry {\n\t\ttry {\n\t\t\tawait access(absolutePath, constants.R_OK);\n\t\t} catch {\n\t\t\treturn { error: `File not found: ${path}` };\n\t\t}\n\t\tconst rawContent = await readFile(absolutePath, \"utf-8\");\n\t\tconst { text: content } = stripBom(rawContent);\n\t\tconst normalizedContent = normalizeToLF(content);\n\t\tconst normalizedOldText = normalizeToLF(oldText);\n\t\tconst normalizedNewText = normalizeToLF(newText);\n\t\tconst matchResult = fuzzyFindText(normalizedContent, normalizedOldText);\n\t\tif (!matchResult.found) {\n\t\t\treturn {\n\t\t\t\terror: `Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t};\n\t\t}\n\t\tconst fuzzyContent = normalizeForFuzzyMatch(normalizedContent);\n\t\tconst fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);\n\t\tconst occurrences = fuzzyContent.split(fuzzyOldText).length - 1;\n\t\tif (occurrences > 1) {\n\t\t\treturn {\n\t\t\t\terror: `Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t};\n\t\t}\n\t\tconst baseContent = matchResult.contentForReplacement;\n\t\tconst newContent =\n\t\t\tbaseContent.substring(0, matchResult.index) +\n\t\t\tnormalizedNewText +\n\t\t\tbaseContent.substring(matchResult.index + matchResult.matchLength);\n\t\tif (baseContent === newContent) {\n\t\t\treturn {\n\t\t\t\terror: `No changes would be made to ${path}. The replacement produces identical content.`,\n\t\t\t};\n\t\t}\n\t\treturn generateDiffString(baseContent, newContent);\n\t} catch (err) {\n\t\treturn { error: err instanceof Error ? err.message : String(err) };\n\t}\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import type { AgentTool } from "@mariozechner/pi-agent-core";
2
+ import { type Static } from "@sinclair/typebox";
3
+ declare const editSchema: import("@sinclair/typebox").TObject<{
4
+ path: import("@sinclair/typebox").TString;
5
+ oldText: import("@sinclair/typebox").TString;
6
+ newText: import("@sinclair/typebox").TString;
7
+ }>;
8
+ export type EditToolInput = Static<typeof editSchema>;
9
+ export interface EditToolDetails {
10
+ diff: string;
11
+ firstChangedLine?: number;
12
+ }
13
+ export interface EditOperations {
14
+ readFile: (absolutePath: string) => Promise<Buffer>;
15
+ writeFile: (absolutePath: string, content: string) => Promise<void>;
16
+ access: (absolutePath: string) => Promise<void>;
17
+ }
18
+ export interface EditToolOptions {
19
+ operations?: EditOperations;
20
+ }
21
+ export declare function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema>;
22
+ export declare const editTool: AgentTool<import("@sinclair/typebox").TObject<{
23
+ path: import("@sinclair/typebox").TString;
24
+ oldText: import("@sinclair/typebox").TString;
25
+ newText: import("@sinclair/typebox").TString;
26
+ }>, any>;
27
+ export {};
28
+ //# sourceMappingURL=edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAetD,QAAA,MAAM,UAAU;;;;EAId,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AACtD,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AACD,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,MAAM,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAMD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AACD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAiInG;AACD,eAAO,MAAM,QAAQ;;;;QAAgC,CAAC","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess } from \"fs/promises\";\nimport {\n\tdetectLineEnding,\n\tfuzzyFindText,\n\tgenerateDiffString,\n\tnormalizeForFuzzyMatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { acceleratedReadFile, acceleratedWriteFile } from \"./local-accelerator.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\nexport type EditToolInput = Static<typeof editSchema>;\nexport interface EditToolDetails {\n\tdiff: string;\n\tfirstChangedLine?: number;\n}\nexport interface EditOperations {\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\taccess: (absolutePath: string) => Promise<void>;\n}\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => acceleratedReadFile(path),\n\twriteFile: (path, content) => acceleratedWriteFile(path, content),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\nexport interface EditToolOptions {\n\toperations?: EditOperations;\n}\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\t\tparameters: editSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, oldText, newText }: { path: string; oldText: string; newText: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\t\t\treturn new Promise<{\n\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t}>((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet aborted = false;\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\taborted = true;\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t};\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\tconst normalizedOldText = normalizeToLF(oldText);\n\t\t\t\t\t\tconst normalizedNewText = normalizeToLF(newText);\n\t\t\t\t\t\tconst matchResult = fuzzyFindText(normalizedContent, normalizedOldText);\n\t\t\t\t\t\tif (!matchResult.found) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst fuzzyContent = normalizeForFuzzyMatch(normalizedContent);\n\t\t\t\t\t\tconst fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);\n\t\t\t\t\t\tconst occurrences = fuzzyContent.split(fuzzyOldText).length - 1;\n\t\t\t\t\t\tif (occurrences > 1) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst baseContent = matchResult.contentForReplacement;\n\t\t\t\t\t\tconst newContent =\n\t\t\t\t\t\t\tbaseContent.substring(0, matchResult.index) +\n\t\t\t\t\t\t\tnormalizedNewText +\n\t\t\t\t\t\t\tbaseContent.substring(matchResult.index + matchResult.matchLength);\n\t\t\t\t\t\tif (baseContent === newContent) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\ttext: `Successfully replaced text in ${path}.`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t};\n}\nexport const editTool = createEditTool(process.cwd());\n"]}
@@ -0,0 +1,129 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import { constants } from "fs";
3
+ import { access as fsAccess } from "fs/promises";
4
+ import { detectLineEnding, fuzzyFindText, generateDiffString, normalizeForFuzzyMatch, normalizeToLF, restoreLineEndings, stripBom, } from "./edit-diff.js";
5
+ import { acceleratedReadFile, acceleratedWriteFile } from "./local-accelerator.js";
6
+ import { resolveToCwd } from "./path-utils.js";
7
+ const editSchema = Type.Object({
8
+ path: Type.String({ description: "Path to the file to edit (relative or absolute)" }),
9
+ oldText: Type.String({ description: "Exact text to find and replace (must match exactly)" }),
10
+ newText: Type.String({ description: "New text to replace the old text with" }),
11
+ });
12
+ const defaultEditOperations = {
13
+ readFile: (path) => acceleratedReadFile(path),
14
+ writeFile: (path, content) => acceleratedWriteFile(path, content),
15
+ access: (path) => fsAccess(path, constants.R_OK | constants.W_OK),
16
+ };
17
+ export function createEditTool(cwd, options) {
18
+ const ops = options?.operations ?? defaultEditOperations;
19
+ return {
20
+ name: "edit",
21
+ label: "edit",
22
+ description: "Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.",
23
+ parameters: editSchema,
24
+ execute: async (_toolCallId, { path, oldText, newText }, signal) => {
25
+ const absolutePath = resolveToCwd(path, cwd);
26
+ return new Promise((resolve, reject) => {
27
+ if (signal?.aborted) {
28
+ reject(new Error("Operation aborted"));
29
+ return;
30
+ }
31
+ let aborted = false;
32
+ const onAbort = () => {
33
+ aborted = true;
34
+ reject(new Error("Operation aborted"));
35
+ };
36
+ if (signal) {
37
+ signal.addEventListener("abort", onAbort, { once: true });
38
+ }
39
+ (async () => {
40
+ try {
41
+ try {
42
+ await ops.access(absolutePath);
43
+ }
44
+ catch {
45
+ if (signal) {
46
+ signal.removeEventListener("abort", onAbort);
47
+ }
48
+ reject(new Error(`File not found: ${path}`));
49
+ return;
50
+ }
51
+ if (aborted) {
52
+ return;
53
+ }
54
+ const buffer = await ops.readFile(absolutePath);
55
+ const rawContent = buffer.toString("utf-8");
56
+ if (aborted) {
57
+ return;
58
+ }
59
+ const { bom, text: content } = stripBom(rawContent);
60
+ const originalEnding = detectLineEnding(content);
61
+ const normalizedContent = normalizeToLF(content);
62
+ const normalizedOldText = normalizeToLF(oldText);
63
+ const normalizedNewText = normalizeToLF(newText);
64
+ const matchResult = fuzzyFindText(normalizedContent, normalizedOldText);
65
+ if (!matchResult.found) {
66
+ if (signal) {
67
+ signal.removeEventListener("abort", onAbort);
68
+ }
69
+ reject(new Error(`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`));
70
+ return;
71
+ }
72
+ const fuzzyContent = normalizeForFuzzyMatch(normalizedContent);
73
+ const fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);
74
+ const occurrences = fuzzyContent.split(fuzzyOldText).length - 1;
75
+ if (occurrences > 1) {
76
+ if (signal) {
77
+ signal.removeEventListener("abort", onAbort);
78
+ }
79
+ reject(new Error(`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`));
80
+ return;
81
+ }
82
+ if (aborted) {
83
+ return;
84
+ }
85
+ const baseContent = matchResult.contentForReplacement;
86
+ const newContent = baseContent.substring(0, matchResult.index) +
87
+ normalizedNewText +
88
+ baseContent.substring(matchResult.index + matchResult.matchLength);
89
+ if (baseContent === newContent) {
90
+ if (signal) {
91
+ signal.removeEventListener("abort", onAbort);
92
+ }
93
+ reject(new Error(`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`));
94
+ return;
95
+ }
96
+ const finalContent = bom + restoreLineEndings(newContent, originalEnding);
97
+ await ops.writeFile(absolutePath, finalContent);
98
+ if (aborted) {
99
+ return;
100
+ }
101
+ if (signal) {
102
+ signal.removeEventListener("abort", onAbort);
103
+ }
104
+ const diffResult = generateDiffString(baseContent, newContent);
105
+ resolve({
106
+ content: [
107
+ {
108
+ type: "text",
109
+ text: `Successfully replaced text in ${path}.`,
110
+ },
111
+ ],
112
+ details: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },
113
+ });
114
+ }
115
+ catch (error) {
116
+ if (signal) {
117
+ signal.removeEventListener("abort", onAbort);
118
+ }
119
+ if (!aborted) {
120
+ reject(error);
121
+ }
122
+ }
123
+ })();
124
+ });
125
+ },
126
+ };
127
+ }
128
+ export const editTool = createEditTool(process.cwd());
129
+ //# sourceMappingURL=edit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit.js","sourceRoot":"","sources":["../../../src/core/tools/edit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { constants } from \"fs\";\nimport { access as fsAccess } from \"fs/promises\";\nimport {\n\tdetectLineEnding,\n\tfuzzyFindText,\n\tgenerateDiffString,\n\tnormalizeForFuzzyMatch,\n\tnormalizeToLF,\n\trestoreLineEndings,\n\tstripBom,\n} from \"./edit-diff.js\";\nimport { acceleratedReadFile, acceleratedWriteFile } from \"./local-accelerator.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nconst editSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to edit (relative or absolute)\" }),\n\toldText: Type.String({ description: \"Exact text to find and replace (must match exactly)\" }),\n\tnewText: Type.String({ description: \"New text to replace the old text with\" }),\n});\nexport type EditToolInput = Static<typeof editSchema>;\nexport interface EditToolDetails {\n\tdiff: string;\n\tfirstChangedLine?: number;\n}\nexport interface EditOperations {\n\treadFile: (absolutePath: string) => Promise<Buffer>;\n\twriteFile: (absolutePath: string, content: string) => Promise<void>;\n\taccess: (absolutePath: string) => Promise<void>;\n}\nconst defaultEditOperations: EditOperations = {\n\treadFile: (path) => acceleratedReadFile(path),\n\twriteFile: (path, content) => acceleratedWriteFile(path, content),\n\taccess: (path) => fsAccess(path, constants.R_OK | constants.W_OK),\n};\nexport interface EditToolOptions {\n\toperations?: EditOperations;\n}\nexport function createEditTool(cwd: string, options?: EditToolOptions): AgentTool<typeof editSchema> {\n\tconst ops = options?.operations ?? defaultEditOperations;\n\treturn {\n\t\tname: \"edit\",\n\t\tlabel: \"edit\",\n\t\tdescription:\n\t\t\t\"Edit a file by replacing exact text. The oldText must match exactly (including whitespace). Use this for precise, surgical edits.\",\n\t\tparameters: editSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, oldText, newText }: { path: string; oldText: string; newText: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\t\t\treturn new Promise<{\n\t\t\t\tcontent: Array<{ type: \"text\"; text: string }>;\n\t\t\t\tdetails: EditToolDetails | undefined;\n\t\t\t}>((resolve, reject) => {\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tlet aborted = false;\n\t\t\t\tconst onAbort = () => {\n\t\t\t\t\taborted = true;\n\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t};\n\t\t\t\tif (signal) {\n\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t}\n\t\t\t\t(async () => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tawait ops.access(absolutePath);\n\t\t\t\t\t\t} catch {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(new Error(`File not found: ${path}`));\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst buffer = await ops.readFile(absolutePath);\n\t\t\t\t\t\tconst rawContent = buffer.toString(\"utf-8\");\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst { bom, text: content } = stripBom(rawContent);\n\t\t\t\t\t\tconst originalEnding = detectLineEnding(content);\n\t\t\t\t\t\tconst normalizedContent = normalizeToLF(content);\n\t\t\t\t\t\tconst normalizedOldText = normalizeToLF(oldText);\n\t\t\t\t\t\tconst normalizedNewText = normalizeToLF(newText);\n\t\t\t\t\t\tconst matchResult = fuzzyFindText(normalizedContent, normalizedOldText);\n\t\t\t\t\t\tif (!matchResult.found) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`Could not find the exact text in ${path}. The old text must match exactly including all whitespace and newlines.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst fuzzyContent = normalizeForFuzzyMatch(normalizedContent);\n\t\t\t\t\t\tconst fuzzyOldText = normalizeForFuzzyMatch(normalizedOldText);\n\t\t\t\t\t\tconst occurrences = fuzzyContent.split(fuzzyOldText).length - 1;\n\t\t\t\t\t\tif (occurrences > 1) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`Found ${occurrences} occurrences of the text in ${path}. The text must be unique. Please provide more context to make it unique.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst baseContent = matchResult.contentForReplacement;\n\t\t\t\t\t\tconst newContent =\n\t\t\t\t\t\t\tbaseContent.substring(0, matchResult.index) +\n\t\t\t\t\t\t\tnormalizedNewText +\n\t\t\t\t\t\t\tbaseContent.substring(matchResult.index + matchResult.matchLength);\n\t\t\t\t\t\tif (baseContent === newContent) {\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treject(\n\t\t\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t\t\t`No changes made to ${path}. The replacement produced identical content. This might indicate an issue with special characters or the text not existing as expected.`,\n\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst finalContent = bom + restoreLineEndings(newContent, originalEnding);\n\t\t\t\t\t\tawait ops.writeFile(absolutePath, finalContent);\n\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst diffResult = generateDiffString(baseContent, newContent);\n\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\t\t\ttext: `Successfully replaced text in ${path}.`,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdetails: { diff: diffResult.diff, firstChangedLine: diffResult.firstChangedLine },\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t});\n\t\t},\n\t};\n}\nexport const editTool = createEditTool(process.cwd());\n"]}
@@ -0,0 +1,33 @@
1
+ import type { AgentTool, AgentToolResult } from "@mariozechner/pi-agent-core";
2
+ import type { AssistantMessage, ToolResultMessage } from "@mariozechner/pi-ai";
3
+ interface ToolCallInfo {
4
+ id: string;
5
+ name: string;
6
+ args: Record<string, unknown>;
7
+ tool: AgentTool<any> | undefined;
8
+ }
9
+ interface ToolExecutionResult {
10
+ toolCallId: string;
11
+ toolName: string;
12
+ result: AgentToolResult<any>;
13
+ isError: boolean;
14
+ duration: number;
15
+ }
16
+ interface ExecuteToolsOptions {
17
+ parallel?: boolean;
18
+ maxConcurrency?: number;
19
+ priority?: number;
20
+ }
21
+ export declare function extractToolCalls(tools: AgentTool<any>[] | undefined, assistantMessage: AssistantMessage): ToolCallInfo[];
22
+ export declare function executeToolsParallel(tools: AgentTool<any>[] | undefined, assistantMessage: AssistantMessage, signal?: AbortSignal, onProgress?: (result: ToolExecutionResult) => void, options?: ExecuteToolsOptions): Promise<ToolResultMessage[]>;
23
+ export declare function canParallelize(tools: ToolCallInfo[]): boolean;
24
+ export declare function groupToolsByDependency(tools: ToolCallInfo[]): ToolCallInfo[][];
25
+ export declare function getExecutionStats(): Record<string, {
26
+ avg: number;
27
+ min: number;
28
+ max: number;
29
+ count: number;
30
+ }>;
31
+ export declare function resetExecutionStats(): void;
32
+ export {};
33
+ //# sourceMappingURL=fast-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-executor.d.ts","sourceRoot":"","sources":["../../../src/core/tools/fast-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAC9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG/E,UAAU,YAAY;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;CACjC;AACD,UAAU,mBAAmB;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CACjB;AACD,UAAU,mBAAmB;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AACD,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,EACnC,gBAAgB,EAAE,gBAAgB,GAChC,YAAY,EAAE,CAQhB;AAoCD,wBAAsB,oBAAoB,CACzC,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,GAAG,SAAS,EACnC,gBAAgB,EAAE,gBAAgB,EAClC,MAAM,CAAC,EAAE,WAAW,EACpB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,EAClD,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAgB9B;AAYD,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,OAAO,CAE7D;AACD,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,EAAE,CAE9E;AACD,wBAAgB,iBAAiB,IAAI,MAAM,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAE5G;AACD,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C","sourcesContent":["import type { AgentTool, AgentToolResult } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessage, ToolResultMessage } from \"@mariozechner/pi-ai\";\nimport { globalMetrics, parallelExecute } from \"./parallel-executor.js\";\n\ninterface ToolCallInfo {\n\tid: string;\n\tname: string;\n\targs: Record<string, unknown>;\n\ttool: AgentTool<any> | undefined;\n}\ninterface ToolExecutionResult {\n\ttoolCallId: string;\n\ttoolName: string;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tduration: number;\n}\ninterface ExecuteToolsOptions {\n\tparallel?: boolean;\n\tmaxConcurrency?: number;\n\tpriority?: number;\n}\nexport function extractToolCalls(\n\ttools: AgentTool<any>[] | undefined,\n\tassistantMessage: AssistantMessage,\n): ToolCallInfo[] {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\treturn toolCalls.map((tc) => ({\n\t\tid: tc.id,\n\t\tname: tc.name,\n\t\targs: tc.arguments,\n\t\ttool: tools?.find((t) => t.name === tc.name),\n\t}));\n}\nasync function executeSingleTool(\n\ttoolCall: ToolCallInfo,\n\tsignal?: AbortSignal,\n\tonUpdate?: (partialResult: AgentToolResult<any>) => void,\n): Promise<ToolExecutionResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tif (!toolCall.tool) {\n\t\t\tthrow new Error(`Tool ${toolCall.name} not found`);\n\t\t}\n\t\tconst result = await toolCall.tool.execute(toolCall.id, toolCall.args, signal, onUpdate);\n\t\tconst duration = Date.now() - startTime;\n\t\tglobalMetrics.record(`tool:${toolCall.name}`, duration);\n\t\treturn {\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError: false,\n\t\t\tduration,\n\t\t};\n\t} catch (error) {\n\t\tconst duration = Date.now() - startTime;\n\t\tglobalMetrics.record(`tool:${toolCall.name}:error`, duration);\n\t\treturn {\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: error instanceof Error ? error.message : String(error) }],\n\t\t\t\tdetails: {},\n\t\t\t},\n\t\t\tisError: true,\n\t\t\tduration,\n\t\t};\n\t}\n}\nexport async function executeToolsParallel(\n\ttools: AgentTool<any>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal?: AbortSignal,\n\tonProgress?: (result: ToolExecutionResult) => void,\n\toptions: ExecuteToolsOptions = {},\n): Promise<ToolResultMessage[]> {\n\tconst { parallel = true, maxConcurrency = 8 } = options;\n\tconst toolCalls = extractToolCalls(tools, assistantMessage);\n\tif (toolCalls.length === 0) {\n\t\treturn [];\n\t}\n\tif (toolCalls.length === 1 || !parallel) {\n\t\tconst result = await executeSingleTool(toolCalls[0], signal);\n\t\tonProgress?.(result);\n\t\treturn [toToolResultMessage(result)];\n\t}\n\tconst results = await parallelExecute(toolCalls, (tc) => executeSingleTool(tc, signal), {\n\t\tconcurrency: maxConcurrency,\n\t});\n\tresults.forEach((result) => onProgress?.(result));\n\treturn results.map(toToolResultMessage);\n}\nfunction toToolResultMessage(result: ToolExecutionResult): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: result.toolCallId,\n\t\ttoolName: result.toolName,\n\t\tcontent: result.result.content,\n\t\tdetails: result.result.details,\n\t\tisError: result.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\nexport function canParallelize(tools: ToolCallInfo[]): boolean {\n\treturn tools.length > 1;\n}\nexport function groupToolsByDependency(tools: ToolCallInfo[]): ToolCallInfo[][] {\n\treturn [tools];\n}\nexport function getExecutionStats(): Record<string, { avg: number; min: number; max: number; count: number }> {\n\treturn globalMetrics.getAllStats();\n}\nexport function resetExecutionStats(): void {\n\tglobalMetrics.reset();\n}\n"]}
@@ -0,0 +1,83 @@
1
+ import { globalMetrics, parallelExecute } from "./parallel-executor.js";
2
+ export function extractToolCalls(tools, assistantMessage) {
3
+ const toolCalls = assistantMessage.content.filter((c) => c.type === "toolCall");
4
+ return toolCalls.map((tc) => ({
5
+ id: tc.id,
6
+ name: tc.name,
7
+ args: tc.arguments,
8
+ tool: tools?.find((t) => t.name === tc.name),
9
+ }));
10
+ }
11
+ async function executeSingleTool(toolCall, signal, onUpdate) {
12
+ const startTime = Date.now();
13
+ try {
14
+ if (!toolCall.tool) {
15
+ throw new Error(`Tool ${toolCall.name} not found`);
16
+ }
17
+ const result = await toolCall.tool.execute(toolCall.id, toolCall.args, signal, onUpdate);
18
+ const duration = Date.now() - startTime;
19
+ globalMetrics.record(`tool:${toolCall.name}`, duration);
20
+ return {
21
+ toolCallId: toolCall.id,
22
+ toolName: toolCall.name,
23
+ result,
24
+ isError: false,
25
+ duration,
26
+ };
27
+ }
28
+ catch (error) {
29
+ const duration = Date.now() - startTime;
30
+ globalMetrics.record(`tool:${toolCall.name}:error`, duration);
31
+ return {
32
+ toolCallId: toolCall.id,
33
+ toolName: toolCall.name,
34
+ result: {
35
+ content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
36
+ details: {},
37
+ },
38
+ isError: true,
39
+ duration,
40
+ };
41
+ }
42
+ }
43
+ export async function executeToolsParallel(tools, assistantMessage, signal, onProgress, options = {}) {
44
+ const { parallel = true, maxConcurrency = 8 } = options;
45
+ const toolCalls = extractToolCalls(tools, assistantMessage);
46
+ if (toolCalls.length === 0) {
47
+ return [];
48
+ }
49
+ if (toolCalls.length === 1 || !parallel) {
50
+ const result = await executeSingleTool(toolCalls[0], signal);
51
+ onProgress?.(result);
52
+ return [toToolResultMessage(result)];
53
+ }
54
+ const results = await parallelExecute(toolCalls, (tc) => executeSingleTool(tc, signal), {
55
+ concurrency: maxConcurrency,
56
+ });
57
+ results.forEach((result) => onProgress?.(result));
58
+ return results.map(toToolResultMessage);
59
+ }
60
+ function toToolResultMessage(result) {
61
+ return {
62
+ role: "toolResult",
63
+ toolCallId: result.toolCallId,
64
+ toolName: result.toolName,
65
+ content: result.result.content,
66
+ details: result.result.details,
67
+ isError: result.isError,
68
+ timestamp: Date.now(),
69
+ };
70
+ }
71
+ export function canParallelize(tools) {
72
+ return tools.length > 1;
73
+ }
74
+ export function groupToolsByDependency(tools) {
75
+ return [tools];
76
+ }
77
+ export function getExecutionStats() {
78
+ return globalMetrics.getAllStats();
79
+ }
80
+ export function resetExecutionStats() {
81
+ globalMetrics.reset();
82
+ }
83
+ //# sourceMappingURL=fast-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fast-executor.js","sourceRoot":"","sources":["../../../src/core/tools/fast-executor.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool, AgentToolResult } from \"@mariozechner/pi-agent-core\";\nimport type { AssistantMessage, ToolResultMessage } from \"@mariozechner/pi-ai\";\nimport { globalMetrics, parallelExecute } from \"./parallel-executor.js\";\n\ninterface ToolCallInfo {\n\tid: string;\n\tname: string;\n\targs: Record<string, unknown>;\n\ttool: AgentTool<any> | undefined;\n}\ninterface ToolExecutionResult {\n\ttoolCallId: string;\n\ttoolName: string;\n\tresult: AgentToolResult<any>;\n\tisError: boolean;\n\tduration: number;\n}\ninterface ExecuteToolsOptions {\n\tparallel?: boolean;\n\tmaxConcurrency?: number;\n\tpriority?: number;\n}\nexport function extractToolCalls(\n\ttools: AgentTool<any>[] | undefined,\n\tassistantMessage: AssistantMessage,\n): ToolCallInfo[] {\n\tconst toolCalls = assistantMessage.content.filter((c) => c.type === \"toolCall\");\n\treturn toolCalls.map((tc) => ({\n\t\tid: tc.id,\n\t\tname: tc.name,\n\t\targs: tc.arguments,\n\t\ttool: tools?.find((t) => t.name === tc.name),\n\t}));\n}\nasync function executeSingleTool(\n\ttoolCall: ToolCallInfo,\n\tsignal?: AbortSignal,\n\tonUpdate?: (partialResult: AgentToolResult<any>) => void,\n): Promise<ToolExecutionResult> {\n\tconst startTime = Date.now();\n\ttry {\n\t\tif (!toolCall.tool) {\n\t\t\tthrow new Error(`Tool ${toolCall.name} not found`);\n\t\t}\n\t\tconst result = await toolCall.tool.execute(toolCall.id, toolCall.args, signal, onUpdate);\n\t\tconst duration = Date.now() - startTime;\n\t\tglobalMetrics.record(`tool:${toolCall.name}`, duration);\n\t\treturn {\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult,\n\t\t\tisError: false,\n\t\t\tduration,\n\t\t};\n\t} catch (error) {\n\t\tconst duration = Date.now() - startTime;\n\t\tglobalMetrics.record(`tool:${toolCall.name}:error`, duration);\n\t\treturn {\n\t\t\ttoolCallId: toolCall.id,\n\t\t\ttoolName: toolCall.name,\n\t\t\tresult: {\n\t\t\t\tcontent: [{ type: \"text\", text: error instanceof Error ? error.message : String(error) }],\n\t\t\t\tdetails: {},\n\t\t\t},\n\t\t\tisError: true,\n\t\t\tduration,\n\t\t};\n\t}\n}\nexport async function executeToolsParallel(\n\ttools: AgentTool<any>[] | undefined,\n\tassistantMessage: AssistantMessage,\n\tsignal?: AbortSignal,\n\tonProgress?: (result: ToolExecutionResult) => void,\n\toptions: ExecuteToolsOptions = {},\n): Promise<ToolResultMessage[]> {\n\tconst { parallel = true, maxConcurrency = 8 } = options;\n\tconst toolCalls = extractToolCalls(tools, assistantMessage);\n\tif (toolCalls.length === 0) {\n\t\treturn [];\n\t}\n\tif (toolCalls.length === 1 || !parallel) {\n\t\tconst result = await executeSingleTool(toolCalls[0], signal);\n\t\tonProgress?.(result);\n\t\treturn [toToolResultMessage(result)];\n\t}\n\tconst results = await parallelExecute(toolCalls, (tc) => executeSingleTool(tc, signal), {\n\t\tconcurrency: maxConcurrency,\n\t});\n\tresults.forEach((result) => onProgress?.(result));\n\treturn results.map(toToolResultMessage);\n}\nfunction toToolResultMessage(result: ToolExecutionResult): ToolResultMessage {\n\treturn {\n\t\trole: \"toolResult\",\n\t\ttoolCallId: result.toolCallId,\n\t\ttoolName: result.toolName,\n\t\tcontent: result.result.content,\n\t\tdetails: result.result.details,\n\t\tisError: result.isError,\n\t\ttimestamp: Date.now(),\n\t};\n}\nexport function canParallelize(tools: ToolCallInfo[]): boolean {\n\treturn tools.length > 1;\n}\nexport function groupToolsByDependency(tools: ToolCallInfo[]): ToolCallInfo[][] {\n\treturn [tools];\n}\nexport function getExecutionStats(): Record<string, { avg: number; min: number; max: number; count: number }> {\n\treturn globalMetrics.getAllStats();\n}\nexport function resetExecutionStats(): void {\n\tglobalMetrics.reset();\n}\n"]}
@@ -0,0 +1,28 @@
1
+ import type { AgentTool } from "@mariozechner/pi-agent-core";
2
+ import { type Static } from "@sinclair/typebox";
3
+ declare const findSchema: import("@sinclair/typebox").TObject<{
4
+ pattern: import("@sinclair/typebox").TString;
5
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
6
+ }>;
7
+ export type FindToolInput = Static<typeof findSchema>;
8
+ export interface FindToolDetails {
9
+ fileCount?: number;
10
+ }
11
+ export interface FindOperations {
12
+ glob: (pattern: string, options: {
13
+ cwd: string;
14
+ dot: boolean;
15
+ absolute: boolean;
16
+ ignore: string[];
17
+ }) => string[];
18
+ }
19
+ export interface FindToolOptions {
20
+ operations?: FindOperations;
21
+ }
22
+ export declare function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema>;
23
+ export declare const findTool: AgentTool<import("@sinclair/typebox").TObject<{
24
+ pattern: import("@sinclair/typebox").TString;
25
+ path: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TString>;
26
+ }>, any>;
27
+ export {};
28
+ //# sourceMappingURL=find.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../../src/core/tools/find.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,6BAA6B,CAAC;AAC9E,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAOtD,QAAA,MAAM,UAAU;;;EASd,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,MAAM,EAAE,CAAC;CACjH;AAMD,MAAM,WAAW,eAAe;IAC/B,UAAU,CAAC,EAAE,cAAc,CAAC;CAC5B;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,SAAS,CAAC,OAAO,UAAU,CAAC,CAoCnG;AAED,eAAO,MAAM,QAAQ;;;QAAgC,CAAC","sourcesContent":["import type { AgentTool, AgentToolResult } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { existsSync } from \"fs\";\nimport { globSync } from \"glob\";\nimport path from \"path\";\nimport { ensureTool } from \"../../utils/tools-manager.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nconst findSchema = Type.Object({\n\tpattern: Type.String({\n\t\tdescription: \"Glob pattern to match files, e.g. '*.ts', '**/*.json'\",\n\t}),\n\tpath: Type.Optional(\n\t\tType.String({\n\t\t\tdescription: \"Optional directory path to search in. Defaults to current working directory.\",\n\t\t}),\n\t),\n});\n\nexport type FindToolInput = Static<typeof findSchema>;\n\nexport interface FindToolDetails {\n\tfileCount?: number;\n}\n\nexport interface FindOperations {\n\tglob: (pattern: string, options: { cwd: string; dot: boolean; absolute: boolean; ignore: string[] }) => string[];\n}\n\nconst defaultFindOperations: FindOperations = {\n\tglob: (pattern, options) => globSync(pattern, options),\n};\n\nexport interface FindToolOptions {\n\toperations?: FindOperations;\n}\n\nexport function createFindTool(cwd: string, options?: FindToolOptions): AgentTool<typeof findSchema> {\n\tconst customOps = options?.operations;\n\treturn {\n\t\tname: \"find\",\n\t\tlabel: \"find\",\n\t\tdescription: \"Find files matching a glob pattern\",\n\t\tparameters: findSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ pattern, path: searchPath }: { pattern: string; path?: string },\n\t\t\tsignal?: AbortSignal,\n\t\t): Promise<AgentToolResult<FindToolDetails>> => {\n\t\t\tif (signal?.aborted) {\n\t\t\t\tthrow new Error(\"Operation aborted\");\n\t\t\t}\n\t\t\tconst ops = customOps ?? defaultFindOperations;\n\t\t\tconst searchDir = searchPath ? resolveToCwd(searchPath, cwd) : cwd;\n\t\t\tif (!existsSync(searchDir)) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `Error: Path does not exist: ${searchDir}` }],\n\t\t\t\t\tdetails: {},\n\t\t\t\t};\n\t\t\t}\n\t\t\tconst results = ops.glob(pattern, {\n\t\t\t\tcwd: searchDir,\n\t\t\t\tdot: true,\n\t\t\t\tabsolute: true,\n\t\t\t\tignore: [\"**/node_modules/**\", \"**/.git/**\"],\n\t\t\t});\n\t\t\tconst output = results.join(\"\\n\") || \"No files found\";\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: output }],\n\t\t\t\tdetails: { fileCount: results.length },\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport const findTool = createFindTool(process.cwd());\n"]}