@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,184 @@
1
+ import { execSync } from "node:child_process";
2
+ import { inspect } from "node:util";
3
+ import { tool } from "ai";
4
+ import chalk from "chalk";
5
+ import { z } from "zod";
6
+ import type { SendData } from "./types.ts";
7
+
8
+ export const GrepTool = {
9
+ name: "grepFiles" as const,
10
+ };
11
+
12
+ export const createGrepTool = (
13
+ options: { sendData?: SendData | undefined } = {},
14
+ ) => {
15
+ const { sendData } = options;
16
+ return {
17
+ [GrepTool.name]: tool({
18
+ description: "Search files for patterns using ripgrep",
19
+ inputSchema: z.object({
20
+ pattern: z.string().describe("The regex pattern to search for"),
21
+ path: z.string().describe("The path to search in"),
22
+ recursive: z
23
+ .boolean()
24
+ .nullable()
25
+ .describe("Pass null to use the default (true, search recursively)."),
26
+ ignoreCase: z
27
+ .boolean()
28
+ .nullable()
29
+ .describe(
30
+ "Pass null to use the default (false, case-sensitive search).",
31
+ ),
32
+ filePattern: z
33
+ .string()
34
+ .nullable()
35
+ .describe("Pass null if no file pattern filter is needed."),
36
+ contextLines: z
37
+ .number()
38
+ .nullable()
39
+ .describe("Pass null if no context lines are needed."),
40
+ searchIgnored: z
41
+ .boolean()
42
+ .nullable()
43
+ .describe(
44
+ "Pass null to use the default (false, don't search ignored files).",
45
+ ),
46
+ }),
47
+ execute: (
48
+ {
49
+ pattern,
50
+ path,
51
+ recursive,
52
+ ignoreCase,
53
+ filePattern,
54
+ contextLines,
55
+ searchIgnored,
56
+ },
57
+ { toolCallId },
58
+ ) => {
59
+ try {
60
+ sendData?.({
61
+ event: "tool-init",
62
+ id: toolCallId,
63
+ data: `Searching codebase for "${chalk.cyan(inspect(pattern))}" in ${chalk.cyan(path)}`,
64
+ });
65
+ const result = grepFiles(pattern, path, {
66
+ recursive,
67
+ ignoreCase,
68
+ filePattern,
69
+ contextLines,
70
+ searchIgnored,
71
+ });
72
+
73
+ const matchCount =
74
+ result === "No matches found."
75
+ ? 0
76
+ : result
77
+ .trim()
78
+ .split("\n")
79
+ .filter((line) => {
80
+ if (line === "--") {
81
+ return false;
82
+ }
83
+ // A match line from ripgrep with --line-number has the format:
84
+ // path:linenumber:match
85
+ // A context line has the format:
86
+ // path-linenumber-match
87
+ // This regex distinguishes between them by looking for the colon after the line number.
88
+ return /^(.+?):(\d+):(.*)$/.test(line);
89
+ }).length;
90
+
91
+ sendData?.({
92
+ event: "tool-completion",
93
+ id: toolCallId,
94
+ data: `Found ${chalk.cyan(matchCount)} matches.`,
95
+ });
96
+ return Promise.resolve(result);
97
+ } catch (error) {
98
+ sendData?.({
99
+ event: "tool-error",
100
+ id: toolCallId,
101
+ data: `Error searching for "${pattern}" in ${path}`,
102
+ });
103
+ return Promise.resolve((error as Error).message);
104
+ }
105
+ },
106
+ }),
107
+ };
108
+ };
109
+
110
+ interface GrepOptions {
111
+ recursive?: boolean | null;
112
+ ignoreCase?: boolean | null;
113
+ filePattern?: string | null;
114
+ contextLines?: number | null;
115
+ searchIgnored?: boolean | null;
116
+ }
117
+
118
+ /**
119
+ * Search files for patterns using ripgrep
120
+ *
121
+ * @param pattern - The regex pattern to search for
122
+ * @param path - The path to search in
123
+ * @param options - Additional options for the grep command
124
+ * @returns The result of the grep command
125
+ */
126
+ function grepFiles(
127
+ pattern: string,
128
+ path: string,
129
+ options: GrepOptions = {},
130
+ ): string {
131
+ try {
132
+ // Handle null values by providing defaults
133
+ const effectiveRecursive =
134
+ options.recursive === null ? true : options.recursive;
135
+ const effectiveIgnoreCase =
136
+ options.ignoreCase === null ? false : options.ignoreCase;
137
+ const effectiveSearchIgnored =
138
+ options.searchIgnored === null ? false : options.searchIgnored;
139
+ const effectiveFilePattern = options.filePattern;
140
+ const effectiveContextLines = options.contextLines;
141
+
142
+ // Build the ripgrep command
143
+ let command = "rg --line-number";
144
+
145
+ // Ripgrep is recursive by default, so we only need to add
146
+ // --no-recursive if effectiveRecursive is explicitly false
147
+ if (effectiveRecursive === false) {
148
+ command += " --max-depth=0";
149
+ }
150
+
151
+ if (effectiveIgnoreCase) {
152
+ command += " --ignore-case";
153
+ }
154
+
155
+ if (effectiveContextLines !== null && effectiveContextLines !== undefined) {
156
+ command += ` --context=${effectiveContextLines}`;
157
+ }
158
+
159
+ // Add pattern (escaped for shell)
160
+ command += ` ${JSON.stringify(pattern)}`;
161
+
162
+ // Add path
163
+ command += ` ${path}`;
164
+
165
+ // Add file pattern if specified
166
+ if (effectiveFilePattern !== null && effectiveFilePattern !== undefined) {
167
+ command += ` --glob=${JSON.stringify(effectiveFilePattern)}`;
168
+ }
169
+
170
+ if (effectiveSearchIgnored) {
171
+ command += " --no-ignore";
172
+ }
173
+
174
+ // Execute the command
175
+ const result = execSync(command, { encoding: "utf-8" });
176
+ return result;
177
+ } catch (error) {
178
+ if (error instanceof Error && "status" in error && error.status === 1) {
179
+ // Status 1 in ripgrep just means "no matches found"
180
+ return "No matches found.";
181
+ }
182
+ throw new Error(`Error executing ripgrep: ${(error as Error).message}`);
183
+ }
184
+ }
@@ -0,0 +1,278 @@
1
+ import type { ModelManager } from "../models/manager.ts";
2
+ import type { Terminal } from "../terminal/index.ts";
3
+ import type { TokenTracker } from "../token-tracker.ts";
4
+ import type { TokenCounter } from "../token-utils.ts";
5
+ import { createAgentTools } from "./agent.ts";
6
+ import { createBashTool } from "./bash.ts";
7
+ import { createCodeInterpreterTool } from "./code-interpreter.ts";
8
+ import { createDeleteFileTool } from "./delete-file.ts";
9
+ import { createDirectoryTreeTool } from "./directory-tree.ts";
10
+ import { createEditFileTool } from "./edit-file.ts";
11
+ import { createGrepTool } from "./grep.ts";
12
+ import { createMemoryReadTool } from "./memory-read.ts";
13
+ import { createMemoryWriteTool } from "./memory-write.ts";
14
+ import { createMoveFileTool } from "./move-file.ts";
15
+ import { createReadFileTool } from "./read-file.ts";
16
+ import { createReadMultipleFilesTool } from "./read-multiple-files.ts";
17
+ import { createSaveFileTool } from "./save-file.ts";
18
+ import { createThinkTool } from "./think.ts";
19
+ import type { Message } from "./types.ts";
20
+ import { createWebFetchTool } from "./web-fetch.ts";
21
+ import { createWebSearchTool } from "./web-search.ts";
22
+
23
+ const sendDataHandler = (events: Map<string, Message[]>) => {
24
+ const msgStore: Map<string, Message[]> = events;
25
+ return (msg: Message) => {
26
+ if (msgStore.has(msg.id)) {
27
+ msgStore.get(msg.id)?.push(msg);
28
+ } else {
29
+ msgStore.set(msg.id, [msg]);
30
+ }
31
+ };
32
+ };
33
+
34
+ export async function initTools({
35
+ terminal,
36
+ tokenCounter,
37
+ events,
38
+ autoAcceptAll,
39
+ }: {
40
+ terminal: Terminal;
41
+ tokenCounter: TokenCounter;
42
+ events: Map<string, Message[]>;
43
+ autoAcceptAll: boolean;
44
+ }) {
45
+ const sendDataFn = sendDataHandler(events);
46
+
47
+ const readFileTool = await createReadFileTool({
48
+ workingDir: process.cwd(),
49
+ sendData: sendDataFn,
50
+ tokenCounter,
51
+ });
52
+
53
+ const readMultipleFilesTool = await createReadMultipleFilesTool({
54
+ workingDir: process.cwd(),
55
+ sendData: sendDataFn,
56
+ tokenCounter,
57
+ });
58
+
59
+ const editFileTool = await createEditFileTool({
60
+ workingDir: process.cwd(),
61
+ terminal,
62
+ sendData: sendDataFn,
63
+ autoAcceptAll,
64
+ });
65
+
66
+ const saveFileTool = await createSaveFileTool({
67
+ workingDir: process.cwd(),
68
+ sendData: sendDataFn,
69
+ terminal,
70
+ autoAcceptAll,
71
+ });
72
+
73
+ const moveFileTool = await createMoveFileTool({
74
+ workingDir: process.cwd(),
75
+ sendData: sendDataFn,
76
+ });
77
+
78
+ const directoryTreeTool = await createDirectoryTreeTool({
79
+ workingDir: process.cwd(),
80
+ sendData: sendDataFn,
81
+ });
82
+
83
+ const deleteFileTool = await createDeleteFileTool({
84
+ workingDir: process.cwd(),
85
+ sendData: sendDataFn,
86
+ });
87
+
88
+ const codeInterpreterTool = createCodeInterpreterTool({
89
+ sendData: sendDataFn,
90
+ });
91
+
92
+ const grepTool = createGrepTool({
93
+ sendData: sendDataFn,
94
+ });
95
+
96
+ const thinkTool = createThinkTool({
97
+ sendData: sendDataFn,
98
+ });
99
+
100
+ const webFetchTool = createWebFetchTool({
101
+ sendData: sendDataFn,
102
+ tokenCounter,
103
+ });
104
+
105
+ const webSearchTool = createWebSearchTool({
106
+ sendData: sendDataFn,
107
+ tokenCounter,
108
+ });
109
+
110
+ const bashTool = createBashTool({
111
+ baseDir: process.cwd(),
112
+ sendData: sendDataFn,
113
+ tokenCounter,
114
+ terminal,
115
+ autoAcceptAll,
116
+ });
117
+
118
+ const memoryReadTool = createMemoryReadTool({
119
+ sendData: sendDataFn,
120
+ });
121
+
122
+ const memoryWriteTool = createMemoryWriteTool({
123
+ sendData: sendDataFn,
124
+ });
125
+
126
+ const tools = {
127
+ ...readFileTool,
128
+ ...readMultipleFilesTool,
129
+ ...editFileTool,
130
+ ...saveFileTool,
131
+ ...moveFileTool,
132
+ ...directoryTreeTool,
133
+ ...deleteFileTool,
134
+ ...codeInterpreterTool,
135
+ ...grepTool,
136
+ ...thinkTool,
137
+ ...webFetchTool,
138
+ ...bashTool,
139
+ ...webSearchTool,
140
+ ...memoryReadTool,
141
+ ...memoryWriteTool,
142
+ } as const;
143
+
144
+ return tools;
145
+ }
146
+
147
+ export async function initCliTools({
148
+ tokenCounter,
149
+ }: {
150
+ tokenCounter: TokenCounter;
151
+ }) {
152
+ const readFileTool = await createReadFileTool({
153
+ workingDir: process.cwd(),
154
+ sendData: undefined,
155
+ tokenCounter,
156
+ });
157
+
158
+ const readMultipleFilesTool = await createReadMultipleFilesTool({
159
+ workingDir: process.cwd(),
160
+ sendData: undefined,
161
+ tokenCounter,
162
+ });
163
+
164
+ const editFileTool = await createEditFileTool({
165
+ workingDir: process.cwd(),
166
+ terminal: undefined,
167
+ sendData: undefined,
168
+ autoAcceptAll: true,
169
+ });
170
+
171
+ const saveFileTool = await createSaveFileTool({
172
+ workingDir: process.cwd(),
173
+ sendData: undefined,
174
+ terminal: undefined,
175
+ autoAcceptAll: true,
176
+ });
177
+
178
+ const moveFileTool = await createMoveFileTool({
179
+ workingDir: process.cwd(),
180
+ sendData: undefined,
181
+ });
182
+
183
+ const directoryTreeTool = await createDirectoryTreeTool({
184
+ workingDir: process.cwd(),
185
+ sendData: undefined,
186
+ });
187
+
188
+ const deleteFileTool = await createDeleteFileTool({
189
+ workingDir: process.cwd(),
190
+ sendData: undefined,
191
+ });
192
+
193
+ const codeInterpreterTool = createCodeInterpreterTool({
194
+ sendData: undefined,
195
+ });
196
+
197
+ const grepTool = createGrepTool({
198
+ sendData: undefined,
199
+ });
200
+
201
+ const thinkTool = createThinkTool({
202
+ sendData: undefined,
203
+ });
204
+
205
+ const webFetchTool = createWebFetchTool({
206
+ sendData: undefined,
207
+ tokenCounter,
208
+ });
209
+
210
+ const webSearchTool = createWebSearchTool({
211
+ sendData: undefined,
212
+ tokenCounter,
213
+ });
214
+
215
+ const bashTool = createBashTool({
216
+ baseDir: process.cwd(),
217
+ sendData: undefined,
218
+ tokenCounter,
219
+ terminal: undefined,
220
+ autoAcceptAll: true,
221
+ });
222
+
223
+ const memoryReadTool = createMemoryReadTool({
224
+ sendData: undefined,
225
+ });
226
+
227
+ const memoryWriteTool = createMemoryWriteTool({
228
+ sendData: undefined,
229
+ });
230
+
231
+ const tools = {
232
+ ...readFileTool,
233
+ ...readMultipleFilesTool,
234
+ ...editFileTool,
235
+ ...saveFileTool,
236
+ ...moveFileTool,
237
+ ...directoryTreeTool,
238
+ ...deleteFileTool,
239
+ ...codeInterpreterTool,
240
+ ...grepTool,
241
+ ...thinkTool,
242
+ ...webFetchTool,
243
+ ...bashTool,
244
+ ...webSearchTool,
245
+ ...memoryReadTool,
246
+ ...memoryWriteTool,
247
+ } as const;
248
+
249
+ return tools;
250
+ }
251
+
252
+ export async function initAgents({
253
+ modelManager,
254
+ tokenTracker,
255
+ tokenCounter,
256
+ events,
257
+ }: {
258
+ terminal: Terminal;
259
+ modelManager: ModelManager;
260
+ tokenTracker: TokenTracker;
261
+ tokenCounter: TokenCounter;
262
+ events: Map<string, Message[]>;
263
+ }) {
264
+ const sendDataFn = sendDataHandler(events);
265
+
266
+ const agentTools = createAgentTools({
267
+ modelManager,
268
+ tokenTracker,
269
+ tokenCounter,
270
+ sendData: sendDataFn,
271
+ });
272
+
273
+ const tools = {
274
+ ...agentTools,
275
+ };
276
+
277
+ return tools;
278
+ }
@@ -0,0 +1,174 @@
1
+ import { access, lstat, mkdir, readdir, readFile } from "node:fs/promises";
2
+ import { isAbsolute, join, normalize, resolve, sep } from "node:path";
3
+ import { tool } from "ai";
4
+ import { z } from "zod";
5
+ import { config } from "../config.ts";
6
+ import type { SendData } from "./types.ts";
7
+
8
+ export const MemoryReadTool = {
9
+ name: "memoryRead" as const,
10
+ };
11
+
12
+ const MEMORY_DIR = config.app.ensurePathSync("memory");
13
+
14
+ // Helper to check if a file exists
15
+ // Moved to module level as it does not use sendData
16
+ async function fileExists(filePath: string): Promise<boolean> {
17
+ try {
18
+ await access(filePath);
19
+ return true;
20
+ } catch {
21
+ return false;
22
+ }
23
+ }
24
+
25
+ // Helper function, does not use sendData directly
26
+ const _readSpecificMemoryFile = async (
27
+ resolvedMemoryDir: string,
28
+ filePath: string,
29
+ ) => {
30
+ const normalizedRelativePath = normalize(filePath);
31
+
32
+ if (
33
+ normalizedRelativePath.startsWith("..") ||
34
+ normalizedRelativePath.includes("..") ||
35
+ isAbsolute(normalizedRelativePath)
36
+ ) {
37
+ throw new Error(
38
+ `Error: Invalid filePath "${filePath}". Must be a relative path and cannot use '..'.`,
39
+ );
40
+ }
41
+
42
+ const fullPath = join(resolvedMemoryDir, normalizedRelativePath);
43
+
44
+ if (
45
+ !fullPath.startsWith(resolvedMemoryDir + sep) &&
46
+ fullPath !== resolvedMemoryDir
47
+ ) {
48
+ throw new Error(
49
+ `Error: Path "${filePath}" resolves outside the allowed memory directory.`,
50
+ );
51
+ }
52
+ if (!(await fileExists(fullPath))) {
53
+ throw new Error(`Error: Memory file '${filePath}' does not exist.`);
54
+ }
55
+ const stats = await lstat(fullPath);
56
+ if (stats.isDirectory()) {
57
+ throw new Error(
58
+ `Error: '${filePath}' is a directory. Please provide a path to a file to read.`,
59
+ );
60
+ }
61
+ const content = await readFile(fullPath, "utf-8");
62
+ return { filePath, content };
63
+ };
64
+
65
+ // Helper function, does not use sendData directly
66
+ const _listMemoryFilesAndIndex = async (resolvedMemoryDir: string) => {
67
+ const entries = await readdir(resolvedMemoryDir, {
68
+ recursive: true,
69
+ withFileTypes: true,
70
+ });
71
+ const filesOnly = entries
72
+ .filter((entry) => entry.isFile())
73
+ .map((entry) => join(entry.parentPath ?? resolvedMemoryDir, entry.name)); // entry.path is available with recursive
74
+
75
+ const fileListString =
76
+ filesOnly.length > 0
77
+ ? filesOnly
78
+ .map((p) => `- ${normalize(p.replace(resolvedMemoryDir + sep, ""))}`)
79
+ .join("\n") // Show relative paths
80
+ : "No files in memory.";
81
+
82
+ const indexPath = join(resolvedMemoryDir, "index.md");
83
+ let indexContent = "(empty)";
84
+ if (await fileExists(indexPath)) {
85
+ const stats = await lstat(indexPath);
86
+ if (stats.isFile()) {
87
+ indexContent = await readFile(indexPath, "utf-8");
88
+ }
89
+ }
90
+
91
+ const output = `Root memory file (index.md):
92
+ '''
93
+ ${indexContent}
94
+ '''
95
+
96
+ Files in the memory directory:
97
+ ${fileListString}`;
98
+ return { content: output };
99
+ };
100
+
101
+ export const createMemoryReadTool = (
102
+ options: { sendData?: SendData | undefined } = {},
103
+ ) => {
104
+ const { sendData } = options;
105
+
106
+ const memoryReadTool = tool({
107
+ description:
108
+ 'Read from memory files. If no path is provided, lists all files and shows content of "index.md".',
109
+ inputSchema: z.object({
110
+ filePath: z
111
+ .string()
112
+ .nullable()
113
+ .describe(
114
+ 'Optional path to a specific memory file to read, relative to the memory directory. Cannot use ".." or absolute paths.',
115
+ ),
116
+ }),
117
+ execute: async (
118
+ { filePath }: { filePath: string | null },
119
+ { toolCallId },
120
+ ) => {
121
+ sendData?.({
122
+ event: "tool-init",
123
+ id: toolCallId,
124
+ data: "Initializing memory read...",
125
+ });
126
+
127
+ const resolvedMemoryDir = resolve(MEMORY_DIR);
128
+
129
+ try {
130
+ await mkdir(resolvedMemoryDir, { recursive: true });
131
+
132
+ let result: { content: string };
133
+ if (filePath) {
134
+ sendData?.({
135
+ event: "tool-update",
136
+ id: toolCallId,
137
+ data: { primary: "Reading file:", secondary: [filePath] },
138
+ });
139
+ result = await _readSpecificMemoryFile(resolvedMemoryDir, filePath);
140
+ } else {
141
+ sendData?.({
142
+ event: "tool-update",
143
+ id: toolCallId,
144
+ data: { primary: "Listing memory files and index" },
145
+ });
146
+ result = await _listMemoryFilesAndIndex(resolvedMemoryDir);
147
+ }
148
+
149
+ sendData?.({
150
+ event: "tool-completion",
151
+ id: toolCallId,
152
+ data: "Done",
153
+ });
154
+
155
+ return result;
156
+ } catch (error: unknown) {
157
+ let errorMsg = "Error reading memory: An unknown error occurred";
158
+ if (error instanceof Error) {
159
+ errorMsg = `Error reading memory: ${error.message}`;
160
+ }
161
+ sendData?.({
162
+ event: "tool-error",
163
+ id: toolCallId,
164
+ data: errorMsg,
165
+ });
166
+ return errorMsg;
167
+ }
168
+ },
169
+ });
170
+
171
+ return {
172
+ [MemoryReadTool.name]: memoryReadTool,
173
+ };
174
+ };