@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,294 @@
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.js";
7
+ import { executeCommand } from "../utils/process.js";
8
+ import { CommandValidation } from "./command-validation.js";
9
+ export const BashTool = {
10
+ name: "bash",
11
+ };
12
+ function tokenize(inputStr) {
13
+ const tokens = [];
14
+ let current = "";
15
+ let inSingle = false;
16
+ let inDouble = false;
17
+ for (let i = 0; i < inputStr.length; i++) {
18
+ const ch = inputStr[i];
19
+ if (ch === "'" && !inDouble) {
20
+ inSingle = !inSingle;
21
+ current += ch;
22
+ continue;
23
+ }
24
+ if (ch === '"' && !inSingle) {
25
+ inDouble = !inDouble;
26
+ current += ch;
27
+ continue;
28
+ }
29
+ if (!inSingle && !inDouble && /\s/.test(ch)) {
30
+ if (current.length > 0) {
31
+ const raw = current;
32
+ const unquoted = raw.replace(/^['"]|['"]$/g, "");
33
+ tokens.push({ raw, unquoted });
34
+ current = "";
35
+ }
36
+ continue;
37
+ }
38
+ if (ch === "\\" && inDouble && i + 1 < inputStr.length) {
39
+ const next = inputStr[i + 1];
40
+ if (next === '"' || next === "\\") {
41
+ current += next;
42
+ i++;
43
+ continue;
44
+ }
45
+ }
46
+ current += ch;
47
+ }
48
+ if (current.length > 0) {
49
+ const raw = current;
50
+ const unquoted = raw.replace(/^['"]|['"]$/g, "");
51
+ tokens.push({ raw, unquoted });
52
+ }
53
+ return tokens;
54
+ }
55
+ function shouldSkipPathValidation(tokens, index) {
56
+ if (index === 0)
57
+ return false;
58
+ const cmd = tokens[0]?.unquoted;
59
+ if (cmd !== "git")
60
+ return false;
61
+ const sub = tokens[1]?.unquoted;
62
+ if (sub !== "commit" &&
63
+ sub !== "tag" &&
64
+ !(sub === "notes" && tokens[2]?.unquoted === "add")) {
65
+ return false;
66
+ }
67
+ const prev = tokens[index - 1]?.unquoted;
68
+ if (prev === "-m" || prev === "--message")
69
+ return true;
70
+ return false;
71
+ }
72
+ function looksLikeUrl(str) {
73
+ return str.startsWith("http://") || str.startsWith("https://");
74
+ }
75
+ // Whitelist of allowed commands
76
+ const ALLOWED_COMMANDS = [
77
+ "chmod",
78
+ "ls",
79
+ "pwd",
80
+ "cat",
81
+ "grep",
82
+ "find",
83
+ "echo",
84
+ "mkdir",
85
+ "touch",
86
+ "cp",
87
+ "mv",
88
+ "pwd",
89
+ "wc",
90
+ "diff",
91
+ "sort",
92
+ "head",
93
+ "tail",
94
+ "sleep",
95
+ "npm",
96
+ "npx",
97
+ "node",
98
+ "git",
99
+ "gh",
100
+ "rg",
101
+ "jq",
102
+ "sed",
103
+ "awk",
104
+ ];
105
+ // Command execution timeout in milliseconds
106
+ const DEFAULT_TIMEOUT = 1.5 * 60 * 1000; // 1.5 minutes
107
+ // Initialize command validator with allowed commands
108
+ const commandValidator = new CommandValidation(ALLOWED_COMMANDS);
109
+ // Ensure path is within base directory
110
+ function isPathWithinBaseDir(requestedPath, baseDir) {
111
+ const normalizedRequestedPath = path.normalize(requestedPath);
112
+ const normalizedBaseDir = path.normalize(baseDir);
113
+ return normalizedRequestedPath.startsWith(normalizedBaseDir);
114
+ }
115
+ export const createBashTool = ({ baseDir, sendData, tokenCounter, terminal, autoAcceptAll, }) => {
116
+ let autoAcceptCommands = autoAcceptAll;
117
+ return {
118
+ [BashTool.name]: tool({
119
+ 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.`,
120
+ inputSchema: z.object({
121
+ command: z
122
+ .string()
123
+ .describe("Full CLI command to execute. Must be from the allowed list without chaining operators."),
124
+ cwd: z
125
+ .string()
126
+ .nullable()
127
+ .describe("Working directory (default: project root). Must be within the project directory."),
128
+ timeout: z
129
+ .number()
130
+ .nullable()
131
+ .describe(`Command execution timeout in milliseconds. Default: ${DEFAULT_TIMEOUT}ms`),
132
+ }),
133
+ execute: async ({ command, cwd, timeout }, { toolCallId }) => {
134
+ // Guard against null cwd and timeout
135
+ const safeCwd = cwd == null ? baseDir : cwd;
136
+ const safeTimeout = timeout == null ? DEFAULT_TIMEOUT : timeout;
137
+ sendData?.({
138
+ event: "tool-init",
139
+ id: toolCallId,
140
+ data: `Executing: ${chalk.cyan(command)} in ${chalk.cyan(safeCwd)}`,
141
+ });
142
+ // Validate command using CommandValidation
143
+ if (!commandValidator.isValid(command)) {
144
+ const errorMsg = `Command not allowed. Ensure all sub-commands are in the approved list: ${ALLOWED_COMMANDS.join(", ")} and no unsafe operators (>, <, \`, $()) are used.`;
145
+ sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
146
+ return errorMsg;
147
+ }
148
+ // Validate working directory
149
+ if (!isPathWithinBaseDir(safeCwd, baseDir)) {
150
+ const errorMsg = `Working directory must be within the project directory: ${baseDir}`;
151
+ sendData?.({ event: "tool-error", id: toolCallId, data: errorMsg });
152
+ return errorMsg;
153
+ }
154
+ // Validate command arguments for paths outside baseDir
155
+ const tokens = tokenize(command);
156
+ for (let i = 0; i < tokens.length; i++) {
157
+ const token = tokens[i];
158
+ if (token == null)
159
+ continue;
160
+ const part = token.unquoted;
161
+ if (shouldSkipPathValidation(tokens, i)) {
162
+ continue;
163
+ }
164
+ if (looksLikeUrl(part)) {
165
+ continue;
166
+ }
167
+ if (part.startsWith("/") ||
168
+ part.includes("../") ||
169
+ part.includes("./") ||
170
+ (part.includes("/") && !part.startsWith("-"))) {
171
+ try {
172
+ const resolvedPath = path.resolve(safeCwd, part);
173
+ if (!isPathWithinBaseDir(resolvedPath, baseDir)) {
174
+ const errorMsg = `Command argument references path outside the project directory: ${part} (resolved to ${resolvedPath})`;
175
+ sendData?.({
176
+ event: "tool-error",
177
+ id: toolCallId,
178
+ data: errorMsg,
179
+ });
180
+ return errorMsg;
181
+ }
182
+ }
183
+ catch (e) {
184
+ console.info(`Could not resolve potential path argument: ${part}`, e);
185
+ }
186
+ }
187
+ }
188
+ // Prompt user for command execution approval (only in interactive mode)
189
+ if (terminal) {
190
+ if (!autoAcceptCommands) {
191
+ await new Promise((resolve) => setTimeout(resolve, 1000));
192
+ }
193
+ terminal.lineBreak();
194
+ terminal.writeln(`${chalk.blue.bold("●")} About to execute command: ${chalk.cyan(command)}`);
195
+ terminal.writeln(`${chalk.gray("Working directory:")} ${safeCwd}`);
196
+ terminal.lineBreak();
197
+ let userChoice;
198
+ if (autoAcceptCommands) {
199
+ terminal.writeln(chalk.green("✓ Auto-accepting command (all future commands will be accepted)"));
200
+ userChoice = "accept";
201
+ }
202
+ else {
203
+ userChoice = await select({
204
+ message: "What would you like to do with this command?",
205
+ choices: [
206
+ { name: "Execute this command", value: "accept" },
207
+ {
208
+ name: "Execute all future commands (including this)",
209
+ value: "accept-all",
210
+ },
211
+ { name: "Reject this command", value: "reject" },
212
+ ],
213
+ default: "accept",
214
+ });
215
+ }
216
+ terminal.lineBreak();
217
+ if (userChoice === "accept-all") {
218
+ autoAcceptCommands = true;
219
+ terminal.writeln(chalk.yellow("✓ Auto-accept mode enabled for all future commands"));
220
+ terminal.lineBreak();
221
+ }
222
+ if (userChoice === "reject") {
223
+ const reason = await input({ message: "Feedback: " });
224
+ terminal.lineBreak();
225
+ const rejectionMsg = `Command rejected by user. Reason: ${reason}`;
226
+ sendData?.({
227
+ event: "tool-completion",
228
+ id: toolCallId,
229
+ data: rejectionMsg,
230
+ });
231
+ return rejectionMsg;
232
+ }
233
+ }
234
+ try {
235
+ const result = await executeCommand(command, {
236
+ cwd: safeCwd,
237
+ timeout: safeTimeout,
238
+ shell: true,
239
+ throwOnError: false,
240
+ });
241
+ if (result.signal === "SIGTERM") {
242
+ const timeoutMessage = `Command timed out after ${safeTimeout}ms. This might be because the command is waiting for input.`;
243
+ sendData?.({
244
+ event: "tool-error",
245
+ id: toolCallId,
246
+ data: timeoutMessage,
247
+ });
248
+ return timeoutMessage;
249
+ }
250
+ const formattedResult = format(result);
251
+ sendData?.({
252
+ event: "tool-update",
253
+ id: toolCallId,
254
+ data: {
255
+ primary: "Result",
256
+ secondary: formattedResult.split("\n").slice(-5),
257
+ },
258
+ });
259
+ let tokenCount = 0;
260
+ try {
261
+ tokenCount = tokenCounter.count(formattedResult);
262
+ }
263
+ catch (tokenError) {
264
+ console.error("Error calculating token count:", tokenError);
265
+ // Log or handle error, but don't block file return
266
+ }
267
+ const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
268
+ // Adjust max token check message if line selection was used
269
+ 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`;
270
+ const finalResult = tokenCount <= maxTokens ? formattedResult : maxTokenMessage;
271
+ sendData?.({
272
+ event: "tool-completion",
273
+ id: toolCallId,
274
+ data: tokenCount <= maxTokens
275
+ ? "Command executed successfully."
276
+ : `Output of commmand (${tokenCount} tokens) exceeds maximum allowed tokens (${maxTokens}).`,
277
+ });
278
+ return finalResult;
279
+ }
280
+ catch (error) {
281
+ sendData?.({
282
+ event: "tool-error",
283
+ id: toolCallId,
284
+ data: `Command failed: ${error.message}`,
285
+ });
286
+ return `Command failed: ${error.message}`;
287
+ }
288
+ },
289
+ }),
290
+ };
291
+ };
292
+ function format({ stdout, stderr, }) {
293
+ return `${stdout}\n${stderr}`;
294
+ }
@@ -0,0 +1,12 @@
1
+ import type { SendData } from "./types.ts";
2
+ export declare const CodeInterpreterTool: {
3
+ name: "codeInterpreter";
4
+ };
5
+ export declare const createCodeInterpreterTool: ({ sendData, }: Readonly<{
6
+ sendData?: SendData | undefined;
7
+ }>) => {
8
+ codeInterpreter: import("ai").Tool<{
9
+ code: string;
10
+ timeoutSeconds: number | null;
11
+ }, string>;
12
+ };
@@ -0,0 +1,131 @@
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
+ export const CodeInterpreterTool = {
9
+ name: "codeInterpreter",
10
+ };
11
+ export const createCodeInterpreterTool = ({ sendData, }) => {
12
+ return {
13
+ [CodeInterpreterTool.name]: tool({
14
+ description: "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.",
15
+ inputSchema: z.object({
16
+ code: z.string().describe("JavaScript code to be executed."),
17
+ timeoutSeconds: z
18
+ .number()
19
+ .int()
20
+ .min(1)
21
+ .max(60)
22
+ .nullable()
23
+ .describe("Execution timeout in seconds (1-60). Default 5."),
24
+ }),
25
+ execute: async ({ code, timeoutSeconds }, { toolCallId }) => {
26
+ const workingDirectory = process.cwd();
27
+ try {
28
+ sendData?.({
29
+ event: "tool-init",
30
+ id: toolCallId,
31
+ data: "Initializing code interpreter environment",
32
+ });
33
+ sendData?.({
34
+ event: "tool-update",
35
+ id: toolCallId,
36
+ data: {
37
+ primary: "Executing...",
38
+ secondary: [
39
+ `${"`".repeat(3)} javascript\n${code.slice(0, 500)}${"`".repeat(3)}`,
40
+ ],
41
+ },
42
+ });
43
+ if (code.trim().length === 0) {
44
+ throw new Error("No code provided");
45
+ }
46
+ const timeoutMs = Math.min(Math.max((timeoutSeconds ?? 5) * 1000, 1000), 60000);
47
+ const tmpBase = join(workingDirectory, ".acai-ci-tmp");
48
+ await mkdir(tmpBase, { recursive: true });
49
+ const scriptPath = join(tmpBase, `temp_script_${Date.now()}_${randomUUID()}.mjs`);
50
+ await writeFile(scriptPath, code, { encoding: "utf8" });
51
+ const args = [
52
+ "--permission",
53
+ `--allow-fs-read=${workingDirectory}`,
54
+ `--allow-fs-write=${workingDirectory}`,
55
+ scriptPath,
56
+ ];
57
+ const child = spawn(process.execPath, args, {
58
+ cwd: workingDirectory,
59
+ // do not rely solely on spawn's timeout; we implement manual timeout below
60
+ stdio: "pipe",
61
+ env: Object.assign({}, process.env, {
62
+ // biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
63
+ NO_COLOR: "true",
64
+ // biome-ignore lint/style/useNamingConvention: Environment variable keys are uppercase by convention
65
+ NODE_OPTIONS: "",
66
+ }),
67
+ });
68
+ let stdout = "";
69
+ let stderr = "";
70
+ let timedOut = false;
71
+ const timer = setTimeout(() => {
72
+ timedOut = true;
73
+ try {
74
+ child.kill("SIGKILL");
75
+ }
76
+ catch { }
77
+ }, timeoutMs);
78
+ child.stdout.setEncoding("utf8");
79
+ child.stderr.setEncoding("utf8");
80
+ child.stdout.on("data", (chunk) => {
81
+ stdout += String(chunk);
82
+ });
83
+ child.stderr.on("data", (chunk) => {
84
+ stderr += String(chunk);
85
+ });
86
+ const completed = await new Promise((resolve, reject) => {
87
+ child.on("error", (err) => reject(err));
88
+ child.on("close", (code, signal) => resolve({ code, signal }));
89
+ });
90
+ clearTimeout(timer);
91
+ // Cleanup temp file/directory
92
+ await rm(scriptPath, { force: true });
93
+ await rm(tmpBase, { force: true, recursive: true });
94
+ if (timedOut) {
95
+ throw new Error("Script timed out");
96
+ }
97
+ if (completed.code === null) {
98
+ throw new Error(`Process terminated by signal ${completed.signal ?? "unknown"}`);
99
+ }
100
+ if (completed.code !== 0) {
101
+ const message = `Process exited with code ${completed.code}. Stderr: ${stderr.trim()}`;
102
+ throw new Error(message);
103
+ }
104
+ const result = {
105
+ stdout: stdout.trim(),
106
+ stderr: stderr.trim(),
107
+ exitCode: completed.code ?? -1,
108
+ };
109
+ sendData?.({
110
+ event: "tool-completion",
111
+ id: toolCallId,
112
+ data: "Code execution completed successfully",
113
+ });
114
+ return JSON.stringify(result, null, 2);
115
+ }
116
+ catch (err) {
117
+ const errorMessage = err.name === "ETIMEDOUT" ||
118
+ err.message.includes("timed out")
119
+ ? "Script timed out"
120
+ : `Error: ${err.message}`;
121
+ sendData?.({
122
+ event: "tool-error",
123
+ id: toolCallId,
124
+ data: errorMessage,
125
+ });
126
+ return errorMessage;
127
+ }
128
+ },
129
+ }),
130
+ };
131
+ };
@@ -0,0 +1,8 @@
1
+ export declare class CommandValidation {
2
+ private readonly allowedCommands;
3
+ private readonly unsafeOperatorPatterns;
4
+ constructor(allowedCommands: string[]);
5
+ private isCommandAllowed;
6
+ private hasUnsafeOperators;
7
+ isValid(command: string): boolean;
8
+ }
@@ -0,0 +1,69 @@
1
+ export class CommandValidation {
2
+ allowedCommands;
3
+ unsafeOperatorPatterns;
4
+ constructor(allowedCommands) {
5
+ this.allowedCommands = allowedCommands;
6
+ this.unsafeOperatorPatterns = [
7
+ /`/, // backticks
8
+ /\$\(/, // $(
9
+ />/, // redirect out
10
+ /</, // redirect in
11
+ ];
12
+ }
13
+ isCommandAllowed(command) {
14
+ const baseCommand = command.split(" ")[0] || "";
15
+ return this.allowedCommands.includes(baseCommand);
16
+ }
17
+ hasUnsafeOperators(command) {
18
+ // Remove all quoted segments first
19
+ const stripped = command
20
+ .replace(/'([^'\\]|\\.)*'/g, "")
21
+ .replace(/"([^"\\]|\\.)*"/g, "");
22
+ // Check for unsafe operators only in unquoted portions
23
+ return this.unsafeOperatorPatterns.some((re) => re.test(stripped));
24
+ }
25
+ isValid(command) {
26
+ if (!command.trim())
27
+ return false;
28
+ // First check for unsafe operators in unquoted portions
29
+ if (this.hasUnsafeOperators(command)) {
30
+ return false;
31
+ }
32
+ // Process command while preserving quoted strings
33
+ const subCommands = [];
34
+ let currentSegment = "";
35
+ let inSingleQuote = false;
36
+ let inDoubleQuote = false;
37
+ for (let i = 0; i < command.length; i++) {
38
+ const char = command[i];
39
+ // Handle quote states
40
+ if (char === "'" && !inDoubleQuote)
41
+ inSingleQuote = !inSingleQuote;
42
+ if (char === '"' && !inSingleQuote)
43
+ inDoubleQuote = !inDoubleQuote;
44
+ // Split on operators only when not in quotes
45
+ if (!inSingleQuote &&
46
+ !inDoubleQuote &&
47
+ (char === "&" || char === "|" || char === ";")) {
48
+ if (currentSegment.trim()) {
49
+ subCommands.push(currentSegment.trim());
50
+ currentSegment = "";
51
+ }
52
+ // Skip the operator and any subsequent same operators (like && or ||)
53
+ while (i + 1 < command.length &&
54
+ ["&", "|", ";"].includes(command[i + 1] ?? "")) {
55
+ i++;
56
+ }
57
+ }
58
+ else {
59
+ currentSegment += char;
60
+ }
61
+ }
62
+ // Add the last segment
63
+ if (currentSegment.trim()) {
64
+ subCommands.push(currentSegment.trim());
65
+ }
66
+ // Validate all sub-commands
67
+ return subCommands.every((cmd) => this.isCommandAllowed(cmd));
68
+ }
69
+ }
@@ -0,0 +1,12 @@
1
+ import type { SendData } from "./types.ts";
2
+ export declare const DeleteFileTool: {
3
+ name: "deleteFile";
4
+ };
5
+ export declare const createDeleteFileTool: ({ workingDir, sendData, }: {
6
+ workingDir: string;
7
+ sendData?: SendData;
8
+ }) => Promise<{
9
+ deleteFile: import("ai").Tool<{
10
+ path: string;
11
+ }, string>;
12
+ }>;
@@ -0,0 +1,56 @@
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.js";
7
+ export const DeleteFileTool = {
8
+ name: "deleteFile",
9
+ };
10
+ export const createDeleteFileTool = async ({ workingDir, sendData, }) => {
11
+ const allowedDirectory = workingDir;
12
+ return {
13
+ [DeleteFileTool.name]: tool({
14
+ description: "Delete a file permanently.",
15
+ inputSchema: z.object({
16
+ path: z.string().describe("Absolute path to the file to delete"),
17
+ }),
18
+ execute: async ({ path: userPath }, { toolCallId }) => {
19
+ sendData?.({
20
+ id: toolCallId,
21
+ event: "tool-init",
22
+ data: `Deleting file: ${chalk.cyan(userPath)}`,
23
+ });
24
+ try {
25
+ const filePath = await validatePath(joinWorkingDir(userPath, workingDir), allowedDirectory);
26
+ // Check if file exists before attempting delete
27
+ if (!existsSync(filePath)) {
28
+ throw new Error(`File not found: ${filePath}`);
29
+ }
30
+ // Ensure it's a file, not a directory
31
+ const stats = await fs.stat(filePath);
32
+ if (stats.isDirectory()) {
33
+ throw new Error(`Path is a directory, not a file: ${filePath}`);
34
+ }
35
+ // Delete the original file
36
+ await fs.unlink(filePath);
37
+ sendData?.({
38
+ id: toolCallId,
39
+ event: "tool-completion",
40
+ data: `File deleted successfully: ${userPath}`,
41
+ });
42
+ return `Successfully deleted ${filePath}`;
43
+ }
44
+ catch (error) {
45
+ const errorMessage = `Failed to delete file: ${error.message}`;
46
+ sendData?.({
47
+ id: toolCallId,
48
+ event: "tool-error",
49
+ data: errorMessage,
50
+ });
51
+ return errorMessage;
52
+ }
53
+ },
54
+ }),
55
+ };
56
+ };
@@ -0,0 +1,12 @@
1
+ import type { SendData } from "./types.ts";
2
+ export declare const DirectoryTreeTool: {
3
+ name: "directoryTree";
4
+ };
5
+ export declare const createDirectoryTreeTool: ({ workingDir, sendData, }: {
6
+ workingDir: string;
7
+ sendData?: SendData;
8
+ }) => Promise<{
9
+ directoryTree: import("ai").Tool<{
10
+ path: string;
11
+ }, string>;
12
+ }>;
@@ -0,0 +1,38 @@
1
+ import { tool } from "ai";
2
+ import chalk from "chalk";
3
+ import { z } from "zod";
4
+ import { directoryTree, joinWorkingDir, validatePath, } from "./filesystem-utils.js";
5
+ export const DirectoryTreeTool = {
6
+ name: "directoryTree",
7
+ };
8
+ export const createDirectoryTreeTool = async ({ workingDir, sendData, }) => {
9
+ const allowedDirectory = workingDir;
10
+ return {
11
+ [DirectoryTreeTool.name]: tool({
12
+ description: "Get a directory tree structure for a given path. This tool will ignore any directories or files listed in a .gitignore file. Use this tool when you need to see a complete directory tree for a project. This can be used to get an understanding of how a project is organized and what files are available before using other file system tools.",
13
+ inputSchema: z.object({
14
+ path: z.string().describe("The path."),
15
+ }),
16
+ execute: async ({ path }, { toolCallId }) => {
17
+ let validPath;
18
+ try {
19
+ sendData?.({
20
+ id: toolCallId,
21
+ event: "tool-init",
22
+ data: `Listing directory tree: ${chalk.cyan(path)}`,
23
+ });
24
+ validPath = await validatePath(joinWorkingDir(path, workingDir), allowedDirectory);
25
+ sendData?.({
26
+ id: toolCallId,
27
+ event: "tool-completion",
28
+ data: "Done",
29
+ });
30
+ }
31
+ catch (error) {
32
+ return `Failed to show directory tree: ${error.message}`;
33
+ }
34
+ return directoryTree(validPath);
35
+ },
36
+ }),
37
+ };
38
+ };
@@ -0,0 +1,19 @@
1
+ import type { Terminal } from "../terminal/index.ts";
2
+ import type { SendData } from "./types.ts";
3
+ export declare const EditFileTool: {
4
+ name: "editFile";
5
+ };
6
+ export declare const createEditFileTool: ({ workingDir, terminal, sendData, autoAcceptAll, }: {
7
+ workingDir: string;
8
+ terminal?: Terminal;
9
+ sendData?: SendData;
10
+ autoAcceptAll: boolean;
11
+ }) => Promise<{
12
+ editFile: import("ai").Tool<{
13
+ path: string;
14
+ edits: {
15
+ oldText: string;
16
+ newText: string;
17
+ }[];
18
+ }, string>;
19
+ }>;