@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,123 @@
1
+ import {
2
+ formatModelInfo,
3
+ getModelsByCategory,
4
+ isValidModel,
5
+ type ModelName,
6
+ type ModelProvider,
7
+ modelRegistry,
8
+ models,
9
+ providers,
10
+ } from "../models/providers.ts";
11
+ import type { CommandOptions, ReplCommand } from "./types.ts";
12
+
13
+ export function modelCommand(options: CommandOptions): ReplCommand {
14
+ const { terminal, modelManager } = options;
15
+
16
+ function switchModel(newModelName: ModelName) {
17
+ try {
18
+ // Get current and new model configs
19
+ const currentModelConfig = modelManager.getModelMetadata("repl");
20
+ const newModelConfig = modelRegistry[newModelName]; // Ensure modelRegistry is available
21
+
22
+ if (!newModelConfig) {
23
+ terminal.error(`Model configuration not found for: ${newModelName}`);
24
+ return;
25
+ }
26
+
27
+ // Check for capability differences
28
+ if (
29
+ currentModelConfig.supportsToolCalling &&
30
+ !newModelConfig.supportsToolCalling
31
+ ) {
32
+ terminal.warn(
33
+ "The new model doesn't support tool calling, which may limit functionality.",
34
+ );
35
+ }
36
+ if (
37
+ currentModelConfig.supportsReasoning &&
38
+ !newModelConfig.supportsReasoning
39
+ ) {
40
+ terminal.warn(
41
+ "The new model doesn't support reasoning, which may change response quality.",
42
+ );
43
+ }
44
+
45
+ // Update model in ModelManager
46
+ modelManager.setModel("repl", newModelName);
47
+
48
+ // Assuming ModelManager handles the actual model instance switching internally.
49
+ terminal.info(`Model set to ${newModelName}.`); // Simplified message
50
+ } catch (error) {
51
+ terminal.error(`Failed to switch model: ${(error as Error).message}`);
52
+ }
53
+ }
54
+
55
+ return {
56
+ command: "/model",
57
+ description:
58
+ "List available models or switch to a different model. Usage: /model [provider:model-name|category|provider]",
59
+ result: "continue",
60
+ getSubCommands: () => Promise.resolve(models as unknown as string[]),
61
+ async execute(args: string[]): Promise<void> {
62
+ const arg = args.join(" ").trim();
63
+ const modelConfig = modelManager.getModelMetadata("repl");
64
+
65
+ // No args - display current model and list available models by category
66
+ if (!arg) {
67
+ const currentModel = modelConfig.id;
68
+ terminal.header(`Current model: ${currentModel}`);
69
+ terminal.header("Available models by category:");
70
+
71
+ // Display models by category
72
+ for (const category of ["fast", "balanced", "powerful"] as const) {
73
+ // Use 'as const' for stricter typing
74
+ terminal.writeln(
75
+ `\n${category.charAt(0).toUpperCase() + category.slice(1)} models:`,
76
+ );
77
+ for (const model of getModelsByCategory(category)) {
78
+ terminal.writeln(formatModelInfo(model));
79
+ }
80
+ }
81
+ return;
82
+ }
83
+
84
+ // Switch to a specific model
85
+ if (isValidModel(arg)) {
86
+ // Call the standalone switchModel function
87
+ switchModel(arg as ModelName);
88
+ return;
89
+ }
90
+
91
+ // Display models by category
92
+ const categories = ["fast", "balanced", "powerful"];
93
+ if (categories.includes(arg)) {
94
+ terminal.header(
95
+ `${arg.charAt(0).toUpperCase() + arg.slice(1)} models:`,
96
+ );
97
+ // Need to assert arg is a valid category if the check passes
98
+ for (const model of getModelsByCategory(
99
+ arg as "fast" | "balanced" | "powerful",
100
+ )) {
101
+ terminal.writeln(formatModelInfo(model));
102
+ }
103
+ return;
104
+ }
105
+
106
+ // Display models by provider
107
+ if (providers.includes(arg as ModelProvider)) {
108
+ terminal.header(`Models from ${arg}:`);
109
+ // Need to ensure modelRegistry is accessible and correctly typed
110
+ for (const model of Object.values(modelRegistry).filter(
111
+ (m) => m.provider === arg,
112
+ )) {
113
+ terminal.writeln(formatModelInfo(model));
114
+ }
115
+ return;
116
+ }
117
+
118
+ // Invalid model name
119
+ terminal.error(`Invalid model name or category: ${arg}`);
120
+ terminal.info("Usage: /model [provider:model-name|category|provider]");
121
+ },
122
+ };
123
+ }
@@ -0,0 +1,62 @@
1
+ import Clipboard from "@crosscopy/clipboard";
2
+ import { formatBlock } from "../formatting.ts";
3
+ import { logger } from "../logger.ts";
4
+ import type { CommandOptions, ReplCommand } from "./types.ts";
5
+
6
+ const base64UrlRegex = /^data:(.*?);base64,/;
7
+
8
+ export const pasteCommand = ({
9
+ terminal,
10
+ modelManager,
11
+ promptManager,
12
+ }: CommandOptions): ReplCommand => {
13
+ return {
14
+ command: "/paste",
15
+ description:
16
+ "Pastes image or text content from the clipboard into the next prompt.",
17
+ result: "continue" as const,
18
+ getSubCommands: () => Promise.resolve([]),
19
+ execute: async () => {
20
+ try {
21
+ if (Clipboard.hasImage()) {
22
+ const base64DataUrl = await Clipboard.getImageBase64();
23
+ const mimeTypeMatch = base64DataUrl.match(base64UrlRegex);
24
+ const mimeType = mimeTypeMatch ? mimeTypeMatch[1] : "image/png";
25
+
26
+ promptManager.addContext({
27
+ type: "image",
28
+ image: base64DataUrl,
29
+ mediaType: mimeType,
30
+ });
31
+
32
+ terminal.success(
33
+ "Image from clipboard will be added to your next prompt.",
34
+ );
35
+ return;
36
+ }
37
+
38
+ const clipboardContent = await Clipboard.getText();
39
+ if (!clipboardContent || clipboardContent.trim() === "") {
40
+ terminal.warn("Clipboard is empty.");
41
+ return;
42
+ }
43
+
44
+ promptManager.addContext(
45
+ formatBlock(
46
+ clipboardContent,
47
+ "clipboard",
48
+ modelManager.getModelMetadata("repl").promptFormat,
49
+ ),
50
+ );
51
+
52
+ terminal.success(
53
+ "Clipboard content will be added to your next prompt.",
54
+ );
55
+ } catch (error) {
56
+ const message = error instanceof Error ? error.message : String(error);
57
+ terminal.error(`Error processing clipboard content: ${message}`);
58
+ logger.error(error, "Paste command error:");
59
+ }
60
+ },
61
+ };
62
+ };
@@ -0,0 +1,150 @@
1
+ import { readdir, readFile } from "node:fs/promises";
2
+ import path, { basename } from "node:path";
3
+ import { processPrompt } from "../mentions.ts";
4
+ import type { CommandOptions, ReplCommand } from "./types.ts";
5
+
6
+ export const promptCommand = ({
7
+ terminal,
8
+ modelManager,
9
+ promptManager,
10
+ config,
11
+ }: CommandOptions): ReplCommand => {
12
+ return {
13
+ command: "/prompt",
14
+ description:
15
+ "Loads and executes prompts. Project prompts override user prompts with the same name.",
16
+ result: "use" as const,
17
+ getSubCommands: async (): Promise<string[]> => {
18
+ const getPromptNamesFromDir = async (
19
+ dirPath: string,
20
+ ): Promise<string[]> => {
21
+ try {
22
+ const dirents = await readdir(dirPath, { withFileTypes: true });
23
+ return dirents
24
+ .filter((dirent) => dirent.isFile() && dirent.name.endsWith(".md"))
25
+ .map((dirent) => basename(dirent.name, ".md"));
26
+ } catch (error) {
27
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") {
28
+ return []; // Directory doesn't exist, return empty array
29
+ }
30
+ terminal.error(`Error reading prompts from ${dirPath}: ${error}`);
31
+ return []; // Return empty on other errors too, but log them
32
+ }
33
+ };
34
+
35
+ const userPromptDir = config.app.ensurePathSync("prompts"); // User prompts are global (~/.acai/prompts)
36
+ const projectPromptDir = config.project.ensurePathSync("prompts"); // Project prompts are local (./.acai/prompts)
37
+
38
+ const userPrompts = await getPromptNamesFromDir(userPromptDir);
39
+ const projectPrompts = await getPromptNamesFromDir(projectPromptDir);
40
+
41
+ // Combine and deduplicate, with project prompts taking precedence
42
+ const allPrompts = new Set([...userPrompts, ...projectPrompts]);
43
+ return Array.from(allPrompts).sort();
44
+ },
45
+ execute: async (args: string[]) => {
46
+ const promptName = args?.[0];
47
+ if (!promptName) {
48
+ terminal.warn(
49
+ "Please provide a prompt name. Usage: /prompt <prompt-name> [input...]",
50
+ );
51
+ return;
52
+ }
53
+
54
+ // Check for old format and provide helpful error
55
+ if (promptName.includes(":")) {
56
+ terminal.warn(
57
+ "The old format (user:name or project:name) is no longer supported. Use: /prompt <prompt-name> [input...]",
58
+ );
59
+ return;
60
+ }
61
+
62
+ try {
63
+ const promptResult = await findPrompt(promptName, config);
64
+
65
+ if (!promptResult) {
66
+ terminal.error(
67
+ `Prompt not found: ${promptName}. Available prompts can be seen with tab completion.`,
68
+ );
69
+ return;
70
+ }
71
+
72
+ let promptContent: string;
73
+ try {
74
+ promptContent = await readFile(promptResult.path, "utf8");
75
+ } catch (error) {
76
+ if ((error as NodeJS.ErrnoException).code === "ENOENT") {
77
+ terminal.error(
78
+ `Prompt file not found: ${promptName} at ${promptResult.path}`,
79
+ );
80
+ return;
81
+ }
82
+ throw error;
83
+ }
84
+
85
+ // Combine remaining arguments into a single string for input
86
+ const inputArgs = args.slice(1);
87
+ const inputString = inputArgs.join(" ");
88
+
89
+ // Replace {{INPUT}} placeholder with the input string
90
+ if (promptContent.includes("{{INPUT}}")) {
91
+ promptContent = promptContent.replace(/{{INPUT}}/g, inputString);
92
+ }
93
+
94
+ terminal.info(`Loaded ${promptResult.type} prompt: ${promptName}`);
95
+ if (inputArgs.length > 0) {
96
+ terminal.info(`Input: "${inputString}"`);
97
+ }
98
+
99
+ const processedPrompt = await processPrompt(promptContent, {
100
+ baseDir: process.cwd(),
101
+ model: modelManager.getModelMetadata("repl"),
102
+ });
103
+
104
+ for (const context of processedPrompt.context) {
105
+ promptManager.addContext(context);
106
+ }
107
+ promptManager.set(processedPrompt.message);
108
+ } catch (error) {
109
+ terminal.error(`Error loading prompt: ${(error as Error).message}`);
110
+ }
111
+ },
112
+ };
113
+ };
114
+
115
+ async function findPrompt(
116
+ promptName: string,
117
+ config: CommandOptions["config"],
118
+ ): Promise<{ path: string; type: "project" | "user" } | null> {
119
+ // Check project prompts first (they take precedence)
120
+ const projectPath = path.join(
121
+ config.project.ensurePathSync("prompts"),
122
+ `${promptName}.md`,
123
+ );
124
+
125
+ try {
126
+ await readFile(projectPath, "utf8");
127
+ return { path: projectPath, type: "project" };
128
+ } catch (error) {
129
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
130
+ throw error; // Re-throw non-file-not-found errors
131
+ }
132
+ }
133
+
134
+ // Check user prompts if not found in project
135
+ const userPath = path.join(
136
+ config.app.ensurePathSync("prompts"),
137
+ `${promptName}.md`,
138
+ );
139
+
140
+ try {
141
+ await readFile(userPath, "utf8");
142
+ return { path: userPath, type: "user" };
143
+ } catch (error) {
144
+ if ((error as NodeJS.ErrnoException).code !== "ENOENT") {
145
+ throw error; // Re-throw non-file-not-found errors
146
+ }
147
+ }
148
+
149
+ return null; // Prompt not found in either location
150
+ }
@@ -0,0 +1,22 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+
3
+ export const resetCommand = ({
4
+ terminal,
5
+ messageHistory,
6
+ }: CommandOptions): ReplCommand => {
7
+ return {
8
+ command: "/reset",
9
+ description: "Saves the chat history and then resets it.",
10
+ result: "continue" as const,
11
+ getSubCommands: () => Promise.resolve([]),
12
+ execute: async () => {
13
+ if (!messageHistory.isEmpty()) {
14
+ await messageHistory.save();
15
+ messageHistory.clear();
16
+ }
17
+ terminal.setTitle(`acai: ${process.cwd()}`);
18
+
19
+ terminal.clear();
20
+ },
21
+ };
22
+ };
@@ -0,0 +1,76 @@
1
+ import { editor } from "@inquirer/prompts";
2
+ import { config } from "../config.ts";
3
+ import type { CommandOptions, ReplCommand } from "./types.ts";
4
+
5
+ export const rulesCommand = ({ terminal }: CommandOptions): ReplCommand => {
6
+ return {
7
+ command: "/rules",
8
+ description:
9
+ "View, add, or edit rules. Usage: /rules [view|add <text>|edit]",
10
+ result: "continue" as const,
11
+ getSubCommands: () => Promise.resolve(["view", "add", "edit"]),
12
+ execute: async (args: string[]) => {
13
+ const subCommand = args[0] ?? "view"; // Default to 'view'
14
+ const commandArgs = args.slice(1).join(" ");
15
+
16
+ try {
17
+ switch (subCommand) {
18
+ case "view": {
19
+ const currentContent = await config.readAgentsFile();
20
+ if (currentContent) {
21
+ terminal.writeln("--- Current Rules ---");
22
+ terminal.writeln(currentContent);
23
+ terminal.writeln("---------------------");
24
+ } else {
25
+ terminal.writeln(
26
+ "No rules defined yet. Use '/rules add' or '/rules edit'.",
27
+ );
28
+ }
29
+ break;
30
+ }
31
+
32
+ case "add": {
33
+ const newMemory = commandArgs.trim();
34
+ if (!newMemory) {
35
+ terminal.error("Error: Memory text cannot be empty for 'add'.");
36
+ terminal.writeln("Usage: /memory add <new memory text>");
37
+ return;
38
+ }
39
+ const currentContent = await config.readAgentsFile();
40
+ const updatedContent = currentContent
41
+ ? `${currentContent.trim()}\n- ${newMemory}` // Ensure space after dash
42
+ : `- ${newMemory}`; // Start with dash if new file
43
+ await config.writeAgentsFile(updatedContent);
44
+ break;
45
+ }
46
+
47
+ case "edit": {
48
+ const currentContent = await config.readAgentsFile();
49
+ const updatedContent = await editor({
50
+ message: "Edit rules:",
51
+ postfix: "md",
52
+ default: currentContent,
53
+ });
54
+ // Check if the user cancelled the edit (editor returns the original content)
55
+ // Or if the content is actually different
56
+ if (updatedContent !== currentContent) {
57
+ await config.writeAgentsFile(updatedContent);
58
+ } else {
59
+ terminal.writeln("Edit cancelled or no changes made.");
60
+ }
61
+ break;
62
+ }
63
+
64
+ default:
65
+ terminal.writeln(
66
+ "Invalid subcommand. Usage: /rules [view|add <text>|edit]",
67
+ );
68
+ break;
69
+ }
70
+ } catch (_error) {
71
+ // Errors from read/write helpers are already logged
72
+ terminal.error("Failed to execute memory command.");
73
+ }
74
+ },
75
+ };
76
+ };
@@ -0,0 +1,20 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+
3
+ export const saveCommand = ({
4
+ messageHistory,
5
+ terminal,
6
+ }: CommandOptions): ReplCommand => {
7
+ return {
8
+ command: "/save",
9
+ description: "Saves the chat history.",
10
+ result: "continue" as const,
11
+ getSubCommands: () => Promise.resolve([]),
12
+ execute: async () => {
13
+ if (!messageHistory.isEmpty()) {
14
+ await messageHistory.save();
15
+ }
16
+
17
+ terminal.info("Message history saved.");
18
+ },
19
+ };
20
+ };
@@ -0,0 +1,28 @@
1
+ import type { ConfigManager } from "../config.ts";
2
+ import type { MessageHistory } from "../messages.ts";
3
+ import type { ModelManager } from "../models/manager.ts";
4
+ import type { PromptManager } from "../prompts/manager.ts";
5
+ import type { Terminal } from "../terminal/index.ts";
6
+ import type { TokenTracker } from "../token-tracker.ts";
7
+ import type { TokenCounter } from "../token-utils.ts";
8
+ import type { Message } from "../tools/types.ts";
9
+
10
+ export interface ReplCommand {
11
+ command: string;
12
+ aliases?: string[];
13
+ description: string;
14
+ result: "break" | "continue" | "use";
15
+ getSubCommands: () => Promise<string[]>;
16
+ execute: (args: string[]) => Promise<void>;
17
+ }
18
+
19
+ export interface CommandOptions {
20
+ promptManager: PromptManager;
21
+ modelManager: ModelManager;
22
+ terminal: Terminal;
23
+ messageHistory: MessageHistory;
24
+ tokenTracker: TokenTracker;
25
+ config: ConfigManager;
26
+ tokenCounter: TokenCounter;
27
+ toolEvents: Map<string, Message[]>;
28
+ }
@@ -0,0 +1,26 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+
3
+ export function usageCommand({
4
+ terminal,
5
+ tokenTracker,
6
+ }: CommandOptions): ReplCommand {
7
+ return {
8
+ command: "/usage",
9
+ description: "Show token usage breakdown",
10
+ result: "continue",
11
+ getSubCommands: () => Promise.resolve([]),
12
+ execute() {
13
+ const entries = Object.entries(tokenTracker.getUsageBreakdown());
14
+ if (entries.length === 0) {
15
+ terminal.info("No usage yet.");
16
+ } else {
17
+ terminal.table(entries, {
18
+ header: ["App", "Tokens"],
19
+ colWidths: [30, 70],
20
+ });
21
+ }
22
+
23
+ return Promise.resolve();
24
+ },
25
+ };
26
+ }