@travisennis/acai 0.0.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 (439) hide show
  1. package/.acai/acai.json +9 -0
  2. package/.acai/prompts/add-openrouter-model.md +13 -0
  3. package/.acai/prompts/project-status.md +4 -0
  4. package/.acai/prompts/update-architecture-document.md +9 -0
  5. package/.acai/rules/learned-rules.md +9 -0
  6. package/.ai/docs/available-tools.txt +3 -0
  7. package/.ai/docs/cognitive_complexity_refactoring_progress.md +65 -0
  8. package/.ai/docs/deleted_tools.md +168 -0
  9. package/.ai/docs/deleted_tools_88ced9ef.md +56 -0
  10. package/.ai/docs/image-pasting.md +46 -0
  11. package/.ai/docs/initialize-app.md +117 -0
  12. package/.ai/docs/issue-4-plan.md +44 -0
  13. package/.ai/docs/marked-renderer-debug.md +15 -0
  14. package/.ai/docs/marked-renderer-refactor-plan.md +64 -0
  15. package/.ai/docs/memory-use-cases.md +55 -0
  16. package/.ai/docs/prompt-consistency.md +31 -0
  17. package/.ai/docs/refactoring-tools.md +98 -0
  18. package/.ai/docs/system-prompt-update.md +174 -0
  19. package/.ai/docs/system_prompt.txt +210 -0
  20. package/.ai/docs/tasks.md +49 -0
  21. package/.ai/plan.md +131 -0
  22. package/.ai/prompt.md +1 -0
  23. package/.ai/scripts/fetch_models.js +27 -0
  24. package/.ai/scripts/generateSystemPrompt.ts +15 -0
  25. package/.ai/scripts/list-tools.mjs +4 -0
  26. package/.ai/scripts/p5_geometric_shapes.js +149 -0
  27. package/.husky/commit-msg +1 -0
  28. package/.husky/pre-commit +3 -0
  29. package/.husky/pre-push +1 -0
  30. package/.ignore +4 -0
  31. package/AGENTS.md +25 -0
  32. package/ARCHITECTURE.md +304 -0
  33. package/LICENSE +21 -0
  34. package/README.md +392 -0
  35. package/TODO.md +2 -0
  36. package/biome.json +61 -0
  37. package/commitlint.config.js +3 -0
  38. package/dist/cli.d.ts +19 -0
  39. package/dist/cli.js +116 -0
  40. package/dist/commands/application-log-command.d.ts +2 -0
  41. package/dist/commands/application-log-command.js +43 -0
  42. package/dist/commands/clear-command.d.ts +2 -0
  43. package/dist/commands/clear-command.js +12 -0
  44. package/dist/commands/compact-command.d.ts +2 -0
  45. package/dist/commands/compact-command.js +51 -0
  46. package/dist/commands/copy-command.d.ts +2 -0
  47. package/dist/commands/copy-command.js +51 -0
  48. package/dist/commands/edit-command.d.ts +2 -0
  49. package/dist/commands/edit-command.js +53 -0
  50. package/dist/commands/edit-prompt-command.d.ts +2 -0
  51. package/dist/commands/edit-prompt-command.js +25 -0
  52. package/dist/commands/exit-command.d.ts +2 -0
  53. package/dist/commands/exit-command.js +14 -0
  54. package/dist/commands/files-command.d.ts +2 -0
  55. package/dist/commands/files-command.js +63 -0
  56. package/dist/commands/generate-rules-command.d.ts +2 -0
  57. package/dist/commands/generate-rules-command.js +61 -0
  58. package/dist/commands/help-command.d.ts +2 -0
  59. package/dist/commands/help-command.js +19 -0
  60. package/dist/commands/init-command.d.ts +2 -0
  61. package/dist/commands/init-command.js +40 -0
  62. package/dist/commands/last-log-command.d.ts +2 -0
  63. package/dist/commands/last-log-command.js +76 -0
  64. package/dist/commands/manager.d.ts +22 -0
  65. package/dist/commands/manager.js +123 -0
  66. package/dist/commands/model-command.d.ts +2 -0
  67. package/dist/commands/model-command.js +84 -0
  68. package/dist/commands/paste-command.d.ts +2 -0
  69. package/dist/commands/paste-command.js +40 -0
  70. package/dist/commands/prompt-command.d.ts +2 -0
  71. package/dist/commands/prompt-command.js +111 -0
  72. package/dist/commands/reset-command.d.ts +2 -0
  73. package/dist/commands/reset-command.js +16 -0
  74. package/dist/commands/rules-command.d.ts +2 -0
  75. package/dist/commands/rules-command.js +68 -0
  76. package/dist/commands/save-command.d.ts +2 -0
  77. package/dist/commands/save-command.js +14 -0
  78. package/dist/commands/types.d.ts +26 -0
  79. package/dist/commands/types.js +1 -0
  80. package/dist/commands/usage-command.d.ts +2 -0
  81. package/dist/commands/usage-command.js +21 -0
  82. package/dist/config.d.ts +60 -0
  83. package/dist/config.js +193 -0
  84. package/dist/conversation-analyzer.d.ts +10 -0
  85. package/dist/conversation-analyzer.js +88 -0
  86. package/dist/dedent.d.ts +3 -0
  87. package/dist/dedent.js +38 -0
  88. package/dist/formatting.d.ts +17 -0
  89. package/dist/formatting.js +103 -0
  90. package/dist/index.d.ts +18 -0
  91. package/dist/index.js +213 -0
  92. package/dist/logger.d.ts +2 -0
  93. package/dist/logger.js +24 -0
  94. package/dist/mentions.d.ts +9 -0
  95. package/dist/mentions.js +182 -0
  96. package/dist/messages.d.ts +69 -0
  97. package/dist/messages.js +261 -0
  98. package/dist/middleware/audit-message.d.ts +5 -0
  99. package/dist/middleware/audit-message.js +95 -0
  100. package/dist/middleware/index.d.ts +2 -0
  101. package/dist/middleware/index.js +2 -0
  102. package/dist/middleware/rate-limit.d.ts +4 -0
  103. package/dist/middleware/rate-limit.js +17 -0
  104. package/dist/models/ai-config.d.ts +12 -0
  105. package/dist/models/ai-config.js +87 -0
  106. package/dist/models/anthropic-provider.d.ts +25 -0
  107. package/dist/models/anthropic-provider.js +184 -0
  108. package/dist/models/deepseek-provider.d.ts +20 -0
  109. package/dist/models/deepseek-provider.js +42 -0
  110. package/dist/models/google-provider.d.ts +19 -0
  111. package/dist/models/google-provider.js +56 -0
  112. package/dist/models/manager.d.ts +15 -0
  113. package/dist/models/manager.js +48 -0
  114. package/dist/models/openai-provider.d.ts +22 -0
  115. package/dist/models/openai-provider.js +70 -0
  116. package/dist/models/openrouter-provider.d.ts +36 -0
  117. package/dist/models/openrouter-provider.js +276 -0
  118. package/dist/models/providers.d.ts +33 -0
  119. package/dist/models/providers.js +116 -0
  120. package/dist/models/xai-provider.d.ts +20 -0
  121. package/dist/models/xai-provider.js +47 -0
  122. package/dist/parsing.d.ts +2 -0
  123. package/dist/parsing.js +18 -0
  124. package/dist/prompts/manager.d.ts +19 -0
  125. package/dist/prompts/manager.js +71 -0
  126. package/dist/prompts.d.ts +4 -0
  127. package/dist/prompts.js +158 -0
  128. package/dist/repl-prompt.d.ts +14 -0
  129. package/dist/repl-prompt.js +147 -0
  130. package/dist/repl.d.ts +27 -0
  131. package/dist/repl.js +431 -0
  132. package/dist/source/cli.d.ts +19 -0
  133. package/dist/source/cli.js +116 -0
  134. package/dist/source/commands/application-log-command.d.ts +2 -0
  135. package/dist/source/commands/application-log-command.js +43 -0
  136. package/dist/source/commands/clear-command.d.ts +2 -0
  137. package/dist/source/commands/clear-command.js +12 -0
  138. package/dist/source/commands/compact-command.d.ts +2 -0
  139. package/dist/source/commands/compact-command.js +51 -0
  140. package/dist/source/commands/copy-command.d.ts +2 -0
  141. package/dist/source/commands/copy-command.js +51 -0
  142. package/dist/source/commands/edit-command.d.ts +2 -0
  143. package/dist/source/commands/edit-command.js +53 -0
  144. package/dist/source/commands/edit-prompt-command.d.ts +2 -0
  145. package/dist/source/commands/edit-prompt-command.js +25 -0
  146. package/dist/source/commands/exit-command.d.ts +2 -0
  147. package/dist/source/commands/exit-command.js +14 -0
  148. package/dist/source/commands/files-command.d.ts +2 -0
  149. package/dist/source/commands/files-command.js +63 -0
  150. package/dist/source/commands/generate-rules-command.d.ts +2 -0
  151. package/dist/source/commands/generate-rules-command.js +61 -0
  152. package/dist/source/commands/help-command.d.ts +2 -0
  153. package/dist/source/commands/help-command.js +19 -0
  154. package/dist/source/commands/init-command.d.ts +2 -0
  155. package/dist/source/commands/init-command.js +40 -0
  156. package/dist/source/commands/last-log-command.d.ts +2 -0
  157. package/dist/source/commands/last-log-command.js +76 -0
  158. package/dist/source/commands/manager.d.ts +22 -0
  159. package/dist/source/commands/manager.js +123 -0
  160. package/dist/source/commands/model-command.d.ts +2 -0
  161. package/dist/source/commands/model-command.js +84 -0
  162. package/dist/source/commands/paste-command.d.ts +2 -0
  163. package/dist/source/commands/paste-command.js +40 -0
  164. package/dist/source/commands/prompt-command.d.ts +2 -0
  165. package/dist/source/commands/prompt-command.js +111 -0
  166. package/dist/source/commands/reset-command.d.ts +2 -0
  167. package/dist/source/commands/reset-command.js +16 -0
  168. package/dist/source/commands/rules-command.d.ts +2 -0
  169. package/dist/source/commands/rules-command.js +68 -0
  170. package/dist/source/commands/save-command.d.ts +2 -0
  171. package/dist/source/commands/save-command.js +14 -0
  172. package/dist/source/commands/types.d.ts +26 -0
  173. package/dist/source/commands/types.js +1 -0
  174. package/dist/source/commands/usage-command.d.ts +2 -0
  175. package/dist/source/commands/usage-command.js +21 -0
  176. package/dist/source/config.d.ts +60 -0
  177. package/dist/source/config.js +193 -0
  178. package/dist/source/conversation-analyzer.d.ts +10 -0
  179. package/dist/source/conversation-analyzer.js +88 -0
  180. package/dist/source/dedent.d.ts +3 -0
  181. package/dist/source/dedent.js +38 -0
  182. package/dist/source/formatting.d.ts +17 -0
  183. package/dist/source/formatting.js +103 -0
  184. package/dist/source/index.d.ts +18 -0
  185. package/dist/source/index.js +213 -0
  186. package/dist/source/logger.d.ts +2 -0
  187. package/dist/source/logger.js +24 -0
  188. package/dist/source/mentions.d.ts +9 -0
  189. package/dist/source/mentions.js +182 -0
  190. package/dist/source/messages.d.ts +69 -0
  191. package/dist/source/messages.js +261 -0
  192. package/dist/source/middleware/audit-message.d.ts +5 -0
  193. package/dist/source/middleware/audit-message.js +95 -0
  194. package/dist/source/middleware/index.d.ts +2 -0
  195. package/dist/source/middleware/index.js +2 -0
  196. package/dist/source/middleware/rate-limit.d.ts +4 -0
  197. package/dist/source/middleware/rate-limit.js +17 -0
  198. package/dist/source/models/ai-config.d.ts +12 -0
  199. package/dist/source/models/ai-config.js +87 -0
  200. package/dist/source/models/anthropic-provider.d.ts +25 -0
  201. package/dist/source/models/anthropic-provider.js +184 -0
  202. package/dist/source/models/deepseek-provider.d.ts +20 -0
  203. package/dist/source/models/deepseek-provider.js +42 -0
  204. package/dist/source/models/google-provider.d.ts +19 -0
  205. package/dist/source/models/google-provider.js +56 -0
  206. package/dist/source/models/manager.d.ts +15 -0
  207. package/dist/source/models/manager.js +48 -0
  208. package/dist/source/models/openai-provider.d.ts +22 -0
  209. package/dist/source/models/openai-provider.js +70 -0
  210. package/dist/source/models/openrouter-provider.d.ts +36 -0
  211. package/dist/source/models/openrouter-provider.js +276 -0
  212. package/dist/source/models/providers.d.ts +33 -0
  213. package/dist/source/models/providers.js +116 -0
  214. package/dist/source/models/xai-provider.d.ts +20 -0
  215. package/dist/source/models/xai-provider.js +47 -0
  216. package/dist/source/parsing.d.ts +2 -0
  217. package/dist/source/parsing.js +18 -0
  218. package/dist/source/prompts/manager.d.ts +19 -0
  219. package/dist/source/prompts/manager.js +71 -0
  220. package/dist/source/prompts.d.ts +4 -0
  221. package/dist/source/prompts.js +158 -0
  222. package/dist/source/repl-prompt.d.ts +14 -0
  223. package/dist/source/repl-prompt.js +147 -0
  224. package/dist/source/repl.d.ts +27 -0
  225. package/dist/source/repl.js +431 -0
  226. package/dist/source/terminal/formatting.d.ts +37 -0
  227. package/dist/source/terminal/formatting.js +106 -0
  228. package/dist/source/terminal/index.d.ts +94 -0
  229. package/dist/source/terminal/index.js +420 -0
  230. package/dist/source/terminal/markdown-utils.d.ts +2 -0
  231. package/dist/source/terminal/markdown-utils.js +81 -0
  232. package/dist/source/terminal/markdown.d.ts +1 -0
  233. package/dist/source/terminal/markdown.js +111 -0
  234. package/dist/source/terminal/types.d.ts +71 -0
  235. package/dist/source/terminal/types.js +1 -0
  236. package/dist/source/terminal-output.d.ts +8 -0
  237. package/dist/source/terminal-output.js +213 -0
  238. package/dist/source/terminal-output.test.d.ts +8 -0
  239. package/dist/source/terminal-output.test.js +213 -0
  240. package/dist/source/token-tracker.d.ts +14 -0
  241. package/dist/source/token-tracker.js +53 -0
  242. package/dist/source/token-utils.d.ts +7 -0
  243. package/dist/source/token-utils.js +13 -0
  244. package/dist/source/tools/agent.d.ts +17 -0
  245. package/dist/source/tools/agent.js +87 -0
  246. package/dist/source/tools/bash.d.ts +19 -0
  247. package/dist/source/tools/bash.js +294 -0
  248. package/dist/source/tools/code-interpreter.d.ts +12 -0
  249. package/dist/source/tools/code-interpreter.js +131 -0
  250. package/dist/source/tools/command-validation.d.ts +8 -0
  251. package/dist/source/tools/command-validation.js +69 -0
  252. package/dist/source/tools/delete-file.d.ts +12 -0
  253. package/dist/source/tools/delete-file.js +56 -0
  254. package/dist/source/tools/directory-tree.d.ts +12 -0
  255. package/dist/source/tools/directory-tree.js +38 -0
  256. package/dist/source/tools/edit-file.d.ts +19 -0
  257. package/dist/source/tools/edit-file.js +107 -0
  258. package/dist/source/tools/filesystem-utils.d.ts +22 -0
  259. package/dist/source/tools/filesystem-utils.js +191 -0
  260. package/dist/source/tools/git-utils.d.ts +14 -0
  261. package/dist/source/tools/git-utils.js +64 -0
  262. package/dist/source/tools/grep.d.ts +17 -0
  263. package/dist/source/tools/grep.js +138 -0
  264. package/dist/source/tools/index.d.ts +161 -0
  265. package/dist/source/tools/index.js +209 -0
  266. package/dist/source/tools/memory-read.d.ts +13 -0
  267. package/dist/source/tools/memory-read.js +135 -0
  268. package/dist/source/tools/memory-write.d.ts +12 -0
  269. package/dist/source/tools/memory-write.js +83 -0
  270. package/dist/source/tools/move-file.d.ts +13 -0
  271. package/dist/source/tools/move-file.js +44 -0
  272. package/dist/source/tools/read-file.d.ts +17 -0
  273. package/dist/source/tools/read-file.js +86 -0
  274. package/dist/source/tools/read-multiple-files.d.ts +14 -0
  275. package/dist/source/tools/read-multiple-files.js +55 -0
  276. package/dist/source/tools/save-file.d.ts +17 -0
  277. package/dist/source/tools/save-file.js +98 -0
  278. package/dist/source/tools/think.d.ts +11 -0
  279. package/dist/source/tools/think.js +45 -0
  280. package/dist/source/tools/types.d.ts +29 -0
  281. package/dist/source/tools/types.js +14 -0
  282. package/dist/source/tools/web-fetch.d.ts +47 -0
  283. package/dist/source/tools/web-fetch.js +246 -0
  284. package/dist/source/tools/web-search.d.ts +13 -0
  285. package/dist/source/tools/web-search.js +80 -0
  286. package/dist/source/utils/process.d.ts +36 -0
  287. package/dist/source/utils/process.js +75 -0
  288. package/dist/source/version.d.ts +1 -0
  289. package/dist/source/version.js +21 -0
  290. package/dist/terminal/formatting.d.ts +37 -0
  291. package/dist/terminal/formatting.js +106 -0
  292. package/dist/terminal/index.d.ts +94 -0
  293. package/dist/terminal/index.js +420 -0
  294. package/dist/terminal/markdown-utils.d.ts +2 -0
  295. package/dist/terminal/markdown-utils.js +81 -0
  296. package/dist/terminal/markdown.d.ts +1 -0
  297. package/dist/terminal/markdown.js +111 -0
  298. package/dist/terminal/types.d.ts +71 -0
  299. package/dist/terminal/types.js +1 -0
  300. package/dist/terminal-output.d.ts +8 -0
  301. package/dist/terminal-output.js +213 -0
  302. package/dist/token-tracker.d.ts +14 -0
  303. package/dist/token-tracker.js +53 -0
  304. package/dist/token-utils.d.ts +7 -0
  305. package/dist/token-utils.js +13 -0
  306. package/dist/tools/agent.d.ts +17 -0
  307. package/dist/tools/agent.js +87 -0
  308. package/dist/tools/bash.d.ts +19 -0
  309. package/dist/tools/bash.js +294 -0
  310. package/dist/tools/code-interpreter.d.ts +12 -0
  311. package/dist/tools/code-interpreter.js +131 -0
  312. package/dist/tools/command-validation.d.ts +8 -0
  313. package/dist/tools/command-validation.js +69 -0
  314. package/dist/tools/delete-file.d.ts +12 -0
  315. package/dist/tools/delete-file.js +56 -0
  316. package/dist/tools/directory-tree.d.ts +12 -0
  317. package/dist/tools/directory-tree.js +38 -0
  318. package/dist/tools/edit-file.d.ts +19 -0
  319. package/dist/tools/edit-file.js +107 -0
  320. package/dist/tools/filesystem-utils.d.ts +22 -0
  321. package/dist/tools/filesystem-utils.js +191 -0
  322. package/dist/tools/git-utils.d.ts +14 -0
  323. package/dist/tools/git-utils.js +64 -0
  324. package/dist/tools/grep.d.ts +17 -0
  325. package/dist/tools/grep.js +138 -0
  326. package/dist/tools/index.d.ts +161 -0
  327. package/dist/tools/index.js +209 -0
  328. package/dist/tools/memory-read.d.ts +13 -0
  329. package/dist/tools/memory-read.js +135 -0
  330. package/dist/tools/memory-write.d.ts +12 -0
  331. package/dist/tools/memory-write.js +83 -0
  332. package/dist/tools/move-file.d.ts +13 -0
  333. package/dist/tools/move-file.js +44 -0
  334. package/dist/tools/read-file.d.ts +17 -0
  335. package/dist/tools/read-file.js +86 -0
  336. package/dist/tools/read-multiple-files.d.ts +14 -0
  337. package/dist/tools/read-multiple-files.js +55 -0
  338. package/dist/tools/save-file.d.ts +17 -0
  339. package/dist/tools/save-file.js +98 -0
  340. package/dist/tools/think.d.ts +11 -0
  341. package/dist/tools/think.js +45 -0
  342. package/dist/tools/types.d.ts +29 -0
  343. package/dist/tools/types.js +14 -0
  344. package/dist/tools/web-fetch.d.ts +47 -0
  345. package/dist/tools/web-fetch.js +246 -0
  346. package/dist/tools/web-search.d.ts +13 -0
  347. package/dist/tools/web-search.js +80 -0
  348. package/dist/utils/process.d.ts +36 -0
  349. package/dist/utils/process.js +75 -0
  350. package/dist/version.d.ts +1 -0
  351. package/dist/version.js +21 -0
  352. package/knip.json +5 -0
  353. package/package.json +83 -0
  354. package/source/cli.ts +172 -0
  355. package/source/commands/application-log-command.ts +53 -0
  356. package/source/commands/clear-command.ts +14 -0
  357. package/source/commands/compact-command.ts +64 -0
  358. package/source/commands/copy-command.ts +55 -0
  359. package/source/commands/edit-command.ts +63 -0
  360. package/source/commands/edit-prompt-command.ts +31 -0
  361. package/source/commands/exit-command.ts +18 -0
  362. package/source/commands/files-command.ts +85 -0
  363. package/source/commands/generate-rules-command.ts +82 -0
  364. package/source/commands/help-command.ts +27 -0
  365. package/source/commands/init-command.ts +48 -0
  366. package/source/commands/last-log-command.ts +88 -0
  367. package/source/commands/manager.ts +151 -0
  368. package/source/commands/model-command.ts +123 -0
  369. package/source/commands/paste-command.ts +62 -0
  370. package/source/commands/prompt-command.ts +150 -0
  371. package/source/commands/reset-command.ts +22 -0
  372. package/source/commands/rules-command.ts +76 -0
  373. package/source/commands/save-command.ts +20 -0
  374. package/source/commands/types.ts +28 -0
  375. package/source/commands/usage-command.ts +26 -0
  376. package/source/config.ts +223 -0
  377. package/source/conversation-analyzer.ts +115 -0
  378. package/source/dedent.ts +53 -0
  379. package/source/formatting.ts +132 -0
  380. package/source/index.ts +240 -0
  381. package/source/logger.ts +29 -0
  382. package/source/mentions.ts +227 -0
  383. package/source/messages.ts +360 -0
  384. package/source/middleware/audit-message.ts +133 -0
  385. package/source/middleware/index.ts +2 -0
  386. package/source/middleware/rate-limit.ts +24 -0
  387. package/source/models/ai-config.ts +109 -0
  388. package/source/models/anthropic-provider.ts +199 -0
  389. package/source/models/deepseek-provider.ts +53 -0
  390. package/source/models/google-provider.ts +68 -0
  391. package/source/models/manager.ts +84 -0
  392. package/source/models/openai-provider.ts +81 -0
  393. package/source/models/openrouter-provider.ts +288 -0
  394. package/source/models/providers.ts +197 -0
  395. package/source/models/xai-provider.ts +59 -0
  396. package/source/parsing.ts +20 -0
  397. package/source/prompts/manager.ts +90 -0
  398. package/source/prompts.ts +172 -0
  399. package/source/repl-prompt.ts +196 -0
  400. package/source/repl.ts +572 -0
  401. package/source/terminal/formatting.ts +121 -0
  402. package/source/terminal/index.ts +518 -0
  403. package/source/terminal/markdown-utils.ts +89 -0
  404. package/source/terminal/markdown.ts +155 -0
  405. package/source/terminal/types.ts +84 -0
  406. package/source/terminal-output.test.ts +266 -0
  407. package/source/token-tracker.ts +78 -0
  408. package/source/token-utils.ts +17 -0
  409. package/source/tools/agent.ts +107 -0
  410. package/source/tools/bash.ts +367 -0
  411. package/source/tools/code-interpreter.ts +172 -0
  412. package/source/tools/command-validation.ts +81 -0
  413. package/source/tools/delete-file.ts +71 -0
  414. package/source/tools/directory-tree.ts +54 -0
  415. package/source/tools/edit-file.ts +155 -0
  416. package/source/tools/filesystem-utils.ts +265 -0
  417. package/source/tools/git-utils.ts +70 -0
  418. package/source/tools/grep.ts +184 -0
  419. package/source/tools/index.ts +278 -0
  420. package/source/tools/memory-read.ts +174 -0
  421. package/source/tools/memory-write.ts +105 -0
  422. package/source/tools/move-file.ts +59 -0
  423. package/source/tools/read-file.ts +129 -0
  424. package/source/tools/read-multiple-files.ts +80 -0
  425. package/source/tools/save-file.ts +147 -0
  426. package/source/tools/think.ts +51 -0
  427. package/source/tools/types.ts +58 -0
  428. package/source/tools/web-fetch.ts +327 -0
  429. package/source/tools/web-search.ts +101 -0
  430. package/source/utils/process.ts +121 -0
  431. package/source/version.ts +21 -0
  432. package/test/commands/copy-command.test.ts +69 -0
  433. package/test/config.test.ts +200 -0
  434. package/test/terminal/markdown-utils.test.ts +124 -0
  435. package/test/tools/bash-tool.test.ts +58 -0
  436. package/test/tools/code-interpreter.test.ts +91 -0
  437. package/test/tools/command-validation.test.ts +48 -0
  438. package/tsconfig.build.json +9 -0
  439. package/tsconfig.json +30 -0
@@ -0,0 +1,367 @@
1
+ import path from "node:path";
2
+ import { input, select } from "@inquirer/prompts";
3
+ import { tool } from "ai";
4
+ import chalk from "chalk";
5
+ import { z } from "zod";
6
+ import { config } from "../config.ts";
7
+ import type { Terminal } from "../terminal/index.ts";
8
+ import type { TokenCounter } from "../token-utils.ts";
9
+ import { executeCommand } from "../utils/process.ts";
10
+ import { CommandValidation } from "./command-validation.ts";
11
+ import type { SendData } from "./types.ts";
12
+
13
+ export const BashTool = {
14
+ name: "bash" as const,
15
+ };
16
+
17
+ type Token = { raw: string; unquoted: string };
18
+
19
+ function tokenize(inputStr: string): Token[] {
20
+ const tokens: Token[] = [];
21
+ let current = "";
22
+ let inSingle = false;
23
+ let inDouble = false;
24
+ for (let i = 0; i < inputStr.length; i++) {
25
+ const ch: string = inputStr[i] as string;
26
+ if (ch === "'" && !inDouble) {
27
+ inSingle = !inSingle;
28
+ current += ch;
29
+ continue;
30
+ }
31
+ if (ch === '"' && !inSingle) {
32
+ inDouble = !inDouble;
33
+ current += ch;
34
+ continue;
35
+ }
36
+ if (!inSingle && !inDouble && /\s/.test(ch)) {
37
+ if (current.length > 0) {
38
+ const raw = current;
39
+ const unquoted = raw.replace(/^['"]|['"]$/g, "");
40
+ tokens.push({ raw, unquoted });
41
+ current = "";
42
+ }
43
+ continue;
44
+ }
45
+ if (ch === "\\" && inDouble && i + 1 < inputStr.length) {
46
+ const next = inputStr[i + 1];
47
+ if (next === '"' || next === "\\") {
48
+ current += next;
49
+ i++;
50
+ continue;
51
+ }
52
+ }
53
+ current += ch;
54
+ }
55
+ if (current.length > 0) {
56
+ const raw = current;
57
+ const unquoted = raw.replace(/^['"]|['"]$/g, "");
58
+ tokens.push({ raw, unquoted });
59
+ }
60
+ return tokens;
61
+ }
62
+
63
+ function shouldSkipPathValidation(tokens: Token[], index: number): boolean {
64
+ if (index === 0) return false;
65
+ const cmd = tokens[0]?.unquoted;
66
+ if (cmd !== "git") return false;
67
+ const sub = tokens[1]?.unquoted;
68
+ if (
69
+ sub !== "commit" &&
70
+ sub !== "tag" &&
71
+ !(sub === "notes" && tokens[2]?.unquoted === "add")
72
+ ) {
73
+ return false;
74
+ }
75
+ const prev = tokens[index - 1]?.unquoted;
76
+ if (prev === "-m" || prev === "--message") return true;
77
+ return false;
78
+ }
79
+
80
+ function looksLikeUrl(str: string): boolean {
81
+ return str.startsWith("http://") || str.startsWith("https://");
82
+ }
83
+
84
+ // Whitelist of allowed commands
85
+ const ALLOWED_COMMANDS = [
86
+ "chmod",
87
+ "ls",
88
+ "pwd",
89
+ "cat",
90
+ "grep",
91
+ "find",
92
+ "echo",
93
+ "mkdir",
94
+ "touch",
95
+ "cp",
96
+ "mv",
97
+ "pwd",
98
+ "wc",
99
+ "diff",
100
+ "sort",
101
+ "head",
102
+ "tail",
103
+ "sleep",
104
+ "npm",
105
+ "npx",
106
+ "node",
107
+ "git",
108
+ "gh",
109
+ "rg",
110
+ "jq",
111
+ "sed",
112
+ "awk",
113
+ ];
114
+
115
+ // Command execution timeout in milliseconds
116
+ const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
117
+
118
+ // Initialize command validator with allowed commands
119
+ const commandValidator = new CommandValidation(ALLOWED_COMMANDS);
120
+
121
+ // Ensure path is within base directory
122
+ function isPathWithinBaseDir(requestedPath: string, baseDir: string): boolean {
123
+ const normalizedRequestedPath = path.normalize(requestedPath);
124
+ const normalizedBaseDir = path.normalize(baseDir);
125
+
126
+ return normalizedRequestedPath.startsWith(normalizedBaseDir);
127
+ }
128
+
129
+ export const createBashTool = ({
130
+ baseDir,
131
+ sendData,
132
+ tokenCounter,
133
+ terminal,
134
+ autoAcceptAll,
135
+ }: {
136
+ baseDir: string;
137
+ sendData?: SendData | undefined;
138
+ tokenCounter: TokenCounter;
139
+ terminal?: Terminal;
140
+ autoAcceptAll: boolean;
141
+ }) => {
142
+ let autoAcceptCommands = autoAcceptAll;
143
+ return {
144
+ [BashTool.name]: tool({
145
+ description: `Execute bash commands and return their output. Limited to a whitelist of safe commands: ${ALLOWED_COMMANDS.join(", ")}. Commands will only execute within the project directory for security. Always specify absolute paths to avoid errors.`,
146
+ inputSchema: z.object({
147
+ command: z
148
+ .string()
149
+ .describe(
150
+ "Full CLI command to execute. Must be from the allowed list without chaining operators.",
151
+ ),
152
+ cwd: z
153
+ .string()
154
+ .nullable()
155
+ .describe(
156
+ "Working directory (default: project root). Must be within the project directory.",
157
+ ),
158
+ timeout: z
159
+ .number()
160
+ .nullable()
161
+ .describe(
162
+ `Command execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT}ms`,
163
+ ),
164
+ }),
165
+ execute: async ({ command, cwd, timeout }, { toolCallId }) => {
166
+ // Guard against null cwd and timeout
167
+ const safeCwd = cwd == null ? baseDir : cwd;
168
+ const safeTimeout = timeout == null ? DEFAULT_TIMEOUT : timeout;
169
+
170
+ sendData?.({
171
+ event: "tool-init",
172
+ id: toolCallId,
173
+ data: `Executing: ${chalk.cyan(command)} in ${chalk.cyan(safeCwd)}`,
174
+ });
175
+
176
+ // Validate command using CommandValidation
177
+ if (!commandValidator.isValid(command)) {
178
+ const errorMsg = `Command not allowed. Ensure all sub-commands are in the approved list: ${ALLOWED_COMMANDS.join(", ")} and no unsafe operators (>, <, \`, $()) are used.`;
179
+ sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
180
+ return errorMsg;
181
+ }
182
+
183
+ // Validate working directory
184
+ if (!isPathWithinBaseDir(safeCwd, baseDir)) {
185
+ const errorMsg = `Working directory must be within the project directory: ${baseDir}`;
186
+ sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
187
+ return errorMsg;
188
+ }
189
+
190
+ // Validate command arguments for paths outside baseDir
191
+ const tokens = tokenize(command);
192
+ for (let i = 0; i < tokens.length; i++) {
193
+ const token = tokens[i];
194
+ if (token == null) continue;
195
+ const part = token.unquoted;
196
+
197
+ if (shouldSkipPathValidation(tokens, i)) {
198
+ continue;
199
+ }
200
+
201
+ if (looksLikeUrl(part)) {
202
+ continue;
203
+ }
204
+
205
+ if (
206
+ part.startsWith("/") ||
207
+ part.includes("../") ||
208
+ part.includes("./") ||
209
+ (part.includes("/") && !part.startsWith("-"))
210
+ ) {
211
+ try {
212
+ const resolvedPath = path.resolve(safeCwd, part);
213
+ if (!isPathWithinBaseDir(resolvedPath, baseDir)) {
214
+ const errorMsg = `Command argument references path outside the project directory: ${part} (resolved to ${resolvedPath})`;
215
+ sendData?.({
216
+ event: "tool-error",
217
+ id: toolCallId,
218
+ data: errorMsg,
219
+ });
220
+ return errorMsg;
221
+ }
222
+ } catch (e) {
223
+ console.info(
224
+ `Could not resolve potential path argument: ${part}`,
225
+ e as unknown as string,
226
+ );
227
+ }
228
+ }
229
+ }
230
+
231
+ // Prompt user for command execution approval (only in interactive mode)
232
+ if (terminal) {
233
+ if (!autoAcceptCommands) {
234
+ await new Promise((resolve) => setTimeout(resolve, 1000));
235
+ }
236
+ terminal.lineBreak();
237
+ terminal.writeln(
238
+ `${chalk.blue.bold("●")} About to execute command: ${chalk.cyan(command)}`,
239
+ );
240
+ terminal.writeln(`${chalk.gray("Working directory:")} ${safeCwd}`);
241
+ terminal.lineBreak();
242
+
243
+ let userChoice: string;
244
+ if (autoAcceptCommands) {
245
+ terminal.writeln(
246
+ chalk.green(
247
+ "✓ Auto-accepting command (all future commands will be accepted)",
248
+ ),
249
+ );
250
+ userChoice = "accept";
251
+ } else {
252
+ userChoice = await select({
253
+ message: "What would you like to do with this command?",
254
+ choices: [
255
+ { name: "Execute this command", value: "accept" },
256
+ {
257
+ name: "Execute all future commands (including this)",
258
+ value: "accept-all",
259
+ },
260
+ { name: "Reject this command", value: "reject" },
261
+ ],
262
+ default: "accept",
263
+ });
264
+ }
265
+
266
+ terminal.lineBreak();
267
+
268
+ if (userChoice === "accept-all") {
269
+ autoAcceptCommands = true;
270
+ terminal.writeln(
271
+ chalk.yellow(
272
+ "✓ Auto-accept mode enabled for all future commands",
273
+ ),
274
+ );
275
+ terminal.lineBreak();
276
+ }
277
+
278
+ if (userChoice === "reject") {
279
+ const reason = await input({ message: "Feedback: " });
280
+ terminal.lineBreak();
281
+
282
+ const rejectionMsg = `Command rejected by user. Reason: ${reason}`;
283
+ sendData?.({
284
+ event: "tool-completion",
285
+ id: toolCallId,
286
+ data: rejectionMsg,
287
+ });
288
+ return rejectionMsg;
289
+ }
290
+ }
291
+
292
+ try {
293
+ const result = await executeCommand(command, {
294
+ cwd: safeCwd,
295
+ timeout: safeTimeout,
296
+ shell: true,
297
+ throwOnError: false,
298
+ });
299
+
300
+ if (result.signal === "SIGTERM") {
301
+ const timeoutMessage = `Command timed out after ${safeTimeout}ms. This might be because the command is waiting for input.`;
302
+ sendData?.({
303
+ event: "tool-error",
304
+ id: toolCallId,
305
+ data: timeoutMessage,
306
+ });
307
+ return timeoutMessage;
308
+ }
309
+
310
+ const formattedResult = format(result);
311
+
312
+ sendData?.({
313
+ event: "tool-update",
314
+ id: toolCallId,
315
+ data: {
316
+ primary: "Result",
317
+ secondary: formattedResult.split("\n").slice(-5),
318
+ },
319
+ });
320
+
321
+ let tokenCount = 0;
322
+ try {
323
+ tokenCount = tokenCounter.count(formattedResult);
324
+ } catch (tokenError) {
325
+ console.error("Error calculating token count:", tokenError);
326
+ // Log or handle error, but don't block file return
327
+ }
328
+
329
+ const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
330
+ // Adjust max token check message if line selection was used
331
+ const maxTokenMessage = `Output of commmand (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}). Please adjust how you call the command to get back more specific results`;
332
+
333
+ const finalResult =
334
+ tokenCount <= maxTokens ? formattedResult : maxTokenMessage;
335
+
336
+ sendData?.({
337
+ event: "tool-completion",
338
+ id: toolCallId,
339
+ data:
340
+ tokenCount <= maxTokens
341
+ ? "Command executed successfully."
342
+ : `Output of commmand (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}).`,
343
+ });
344
+ return finalResult;
345
+ } catch (error) {
346
+ sendData?.({
347
+ event: "tool-error",
348
+ id: toolCallId,
349
+ data: `Command failed: ${(error as Error).message}`,
350
+ });
351
+ return `Command failed: ${(error as Error).message}`;
352
+ }
353
+ },
354
+ }),
355
+ };
356
+ };
357
+
358
+ function format({
359
+ stdout,
360
+ stderr,
361
+ }: {
362
+ stdout: string;
363
+ stderr: string;
364
+ code: number;
365
+ }) {
366
+ return `${stdout}\n${stderr}`;
367
+ }
@@ -0,0 +1,172 @@
1
+ import { spawn } from "node:child_process";
2
+ import { randomUUID } from "node:crypto";
3
+ import { mkdir, rm, writeFile } from "node:fs/promises";
4
+ import { join } from "node:path";
5
+ import process from "node:process";
6
+ import { tool } from "ai";
7
+ import { z } from "zod";
8
+ import type { SendData } from "./types.ts";
9
+
10
+ export const CodeInterpreterTool = {
11
+ name: "codeInterpreter" as const,
12
+ };
13
+
14
+ export const createCodeInterpreterTool = ({
15
+ sendData,
16
+ }: Readonly<{
17
+ sendData?: SendData | undefined;
18
+ }>) => {
19
+ return {
20
+ [CodeInterpreterTool.name]: tool({
21
+ description:
22
+ "Executes JavaScript code in a separate Node.js process using Node's Permission Model. By default, the child process has no permissions except read/write within the current working directory. The tool returns stdout, stderr, and exitCode. Use console.log/console.error to produce output. Timeout defaults to 5 seconds and can be extended up to 60 seconds.",
23
+ inputSchema: z.object({
24
+ code: z.string().describe("JavaScript code to be executed."),
25
+ timeoutSeconds: z
26
+ .number()
27
+ .int()
28
+ .min(1)
29
+ .max(60)
30
+ .nullable()
31
+ .describe("Execution timeout in seconds (1-60). Default 5."),
32
+ }),
33
+ execute: async ({ code, timeoutSeconds }, { toolCallId }) => {
34
+ const workingDirectory = process.cwd();
35
+
36
+ try {
37
+ sendData?.({
38
+ event: "tool-init",
39
+ id: toolCallId,
40
+ data: "Initializing code interpreter environment",
41
+ });
42
+
43
+ sendData?.({
44
+ event: "tool-update",
45
+ id: toolCallId,
46
+ data: {
47
+ primary: "Executing...",
48
+ secondary: [
49
+ `${"`".repeat(3)} javascript\n${code.slice(0, 500)}${"`".repeat(3)}`,
50
+ ],
51
+ },
52
+ });
53
+
54
+ if (code.trim().length === 0) {
55
+ throw new Error("No code provided");
56
+ }
57
+
58
+ const timeoutMs = Math.min(
59
+ Math.max((timeoutSeconds ?? 5) * 1000, 1000),
60
+ 60000,
61
+ );
62
+
63
+ const tmpBase = join(workingDirectory, ".acai-ci-tmp");
64
+ await mkdir(tmpBase, { recursive: true });
65
+ const scriptPath = join(
66
+ tmpBase,
67
+ `temp_script_${Date.now()}_${randomUUID()}.mjs`,
68
+ );
69
+
70
+ await writeFile(scriptPath, code, { encoding: "utf8" });
71
+
72
+ const args = [
73
+ "--permission",
74
+ `--allow-fs-read=${workingDirectory}`,
75
+ `--allow-fs-write=${workingDirectory}`,
76
+ scriptPath,
77
+ ];
78
+
79
+ const child = spawn(process.execPath, args, {
80
+ cwd: workingDirectory,
81
+ // do not rely solely on spawn's timeout; we implement manual timeout below
82
+ stdio: "pipe",
83
+ env: Object.assign({}, process.env, {
84
+ // biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
85
+ NO_COLOR: "true",
86
+ // biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
87
+ NODE_OPTIONS: "",
88
+ } as Record<string, string>),
89
+ });
90
+
91
+ let stdout = "";
92
+ let stderr = "";
93
+ let timedOut = false;
94
+
95
+ const timer = setTimeout(() => {
96
+ timedOut = true;
97
+ try {
98
+ child.kill("SIGKILL");
99
+ } catch {}
100
+ }, timeoutMs);
101
+
102
+ child.stdout.setEncoding("utf8");
103
+ child.stderr.setEncoding("utf8");
104
+
105
+ child.stdout.on("data", (chunk) => {
106
+ stdout += String(chunk);
107
+ });
108
+ child.stderr.on("data", (chunk) => {
109
+ stderr += String(chunk);
110
+ });
111
+
112
+ const completed = await new Promise<{
113
+ code: number | null;
114
+ signal: NodeJS.Signals | null;
115
+ }>((resolve, reject) => {
116
+ child.on("error", (err) => reject(err));
117
+ child.on("close", (code, signal) => resolve({ code, signal }));
118
+ });
119
+
120
+ clearTimeout(timer);
121
+
122
+ // Cleanup temp file/directory
123
+ await rm(scriptPath, { force: true });
124
+ await rm(tmpBase, { force: true, recursive: true });
125
+
126
+ if (timedOut) {
127
+ throw new Error("Script timed out");
128
+ }
129
+
130
+ if (completed.code === null) {
131
+ throw new Error(
132
+ `Process terminated by signal ${completed.signal ?? "unknown"}`,
133
+ );
134
+ }
135
+
136
+ if (completed.code !== 0) {
137
+ const message = `Process exited with code ${completed.code}. Stderr: ${stderr.trim()}`;
138
+ throw new Error(message);
139
+ }
140
+
141
+ const result = {
142
+ stdout: stdout.trim(),
143
+ stderr: stderr.trim(),
144
+ exitCode: completed.code ?? -1,
145
+ };
146
+
147
+ sendData?.({
148
+ event: "tool-completion",
149
+ id: toolCallId,
150
+ data: "Code execution completed successfully",
151
+ });
152
+
153
+ return JSON.stringify(result, null, 2);
154
+ } catch (err) {
155
+ const errorMessage =
156
+ (err as Error).name === "ETIMEDOUT" ||
157
+ (err as Error).message.includes("timed out")
158
+ ? "Script timed out"
159
+ : `Error: ${(err as Error).message}`;
160
+
161
+ sendData?.({
162
+ event: "tool-error",
163
+ id: toolCallId,
164
+ data: errorMessage,
165
+ });
166
+
167
+ return errorMessage;
168
+ }
169
+ },
170
+ }),
171
+ };
172
+ };
@@ -0,0 +1,81 @@
1
+ export class CommandValidation {
2
+ private readonly allowedCommands: string[];
3
+ private readonly unsafeOperatorPatterns: RegExp[];
4
+
5
+ constructor(allowedCommands: string[]) {
6
+ this.allowedCommands = allowedCommands;
7
+ this.unsafeOperatorPatterns = [
8
+ /`/, // backticks
9
+ /\$\(/, // $(
10
+ />/, // redirect out
11
+ /</, // redirect in
12
+ ];
13
+ }
14
+
15
+ private isCommandAllowed(command: string): boolean {
16
+ const baseCommand = command.split(" ")[0] || "";
17
+ return this.allowedCommands.includes(baseCommand);
18
+ }
19
+
20
+ private hasUnsafeOperators(command: string): boolean {
21
+ // Remove all quoted segments first
22
+ const stripped = command
23
+ .replace(/'([^'\\]|\\.)*'/g, "")
24
+ .replace(/"([^"\\]|\\.)*"/g, "");
25
+
26
+ // Check for unsafe operators only in unquoted portions
27
+ return this.unsafeOperatorPatterns.some((re) => re.test(stripped));
28
+ }
29
+
30
+ isValid(command: string): boolean {
31
+ if (!command.trim()) return false;
32
+
33
+ // First check for unsafe operators in unquoted portions
34
+ if (this.hasUnsafeOperators(command)) {
35
+ return false;
36
+ }
37
+
38
+ // Process command while preserving quoted strings
39
+ const subCommands: string[] = [];
40
+ let currentSegment = "";
41
+ let inSingleQuote = false;
42
+ let inDoubleQuote = false;
43
+
44
+ for (let i = 0; i < command.length; i++) {
45
+ const char = command[i];
46
+
47
+ // Handle quote states
48
+ if (char === "'" && !inDoubleQuote) inSingleQuote = !inSingleQuote;
49
+ if (char === '"' && !inSingleQuote) inDoubleQuote = !inDoubleQuote;
50
+
51
+ // Split on operators only when not in quotes
52
+ if (
53
+ !inSingleQuote &&
54
+ !inDoubleQuote &&
55
+ (char === "&" || char === "|" || char === ";")
56
+ ) {
57
+ if (currentSegment.trim()) {
58
+ subCommands.push(currentSegment.trim());
59
+ currentSegment = "";
60
+ }
61
+ // Skip the operator and any subsequent same operators (like && or ||)
62
+ while (
63
+ i + 1 < command.length &&
64
+ ["&", "|", ";"].includes(command[i + 1] ?? "")
65
+ ) {
66
+ i++;
67
+ }
68
+ } else {
69
+ currentSegment += char;
70
+ }
71
+ }
72
+
73
+ // Add the last segment
74
+ if (currentSegment.trim()) {
75
+ subCommands.push(currentSegment.trim());
76
+ }
77
+
78
+ // Validate all sub-commands
79
+ return subCommands.every((cmd) => this.isCommandAllowed(cmd));
80
+ }
81
+ }
@@ -0,0 +1,71 @@
1
+ import { existsSync } from "node:fs";
2
+ import fs from "node:fs/promises";
3
+ import { tool } from "ai";
4
+ import chalk from "chalk";
5
+ import { z } from "zod";
6
+ import { joinWorkingDir, validatePath } from "./filesystem-utils.ts";
7
+ import type { SendData } from "./types.ts";
8
+
9
+ export const DeleteFileTool = {
10
+ name: "deleteFile" as const,
11
+ };
12
+
13
+ export const createDeleteFileTool = async ({
14
+ workingDir,
15
+ sendData,
16
+ }: {
17
+ workingDir: string;
18
+ sendData?: SendData;
19
+ }) => {
20
+ const allowedDirectory = workingDir;
21
+ return {
22
+ [DeleteFileTool.name]: tool({
23
+ description: "Delete a file permanently.",
24
+ inputSchema: z.object({
25
+ path: z.string().describe("Absolute path to the file to delete"),
26
+ }),
27
+ execute: async ({ path: userPath }, { toolCallId }) => {
28
+ sendData?.({
29
+ id: toolCallId,
30
+ event: "tool-init",
31
+ data: `Deleting file: ${chalk.cyan(userPath)}`,
32
+ });
33
+ try {
34
+ const filePath = await validatePath(
35
+ joinWorkingDir(userPath, workingDir),
36
+ allowedDirectory,
37
+ );
38
+
39
+ // Check if file exists before attempting delete
40
+ if (!existsSync(filePath)) {
41
+ throw new Error(`File not found: ${filePath}`);
42
+ }
43
+
44
+ // Ensure it's a file, not a directory
45
+ const stats = await fs.stat(filePath);
46
+ if (stats.isDirectory()) {
47
+ throw new Error(`Path is a directory, not a file: ${filePath}`);
48
+ }
49
+
50
+ // Delete the original file
51
+ await fs.unlink(filePath);
52
+
53
+ sendData?.({
54
+ id: toolCallId,
55
+ event: "tool-completion",
56
+ data: `File deleted successfully: ${userPath}`,
57
+ });
58
+ return `Successfully deleted ${filePath}`;
59
+ } catch (error) {
60
+ const errorMessage = `Failed to delete file: ${(error as Error).message}`;
61
+ sendData?.({
62
+ id: toolCallId,
63
+ event: "tool-error",
64
+ data: errorMessage,
65
+ });
66
+ return errorMessage;
67
+ }
68
+ },
69
+ }),
70
+ };
71
+ };