@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
package/dist/repl.js ADDED
@@ -0,0 +1,431 @@
1
+ import { isNumber, isRecord } from "@travisennis/stdlib/typeguards";
2
+ import { generateObject, NoSuchToolError, stepCountIs, streamText, } from "ai";
3
+ import chalk from "chalk";
4
+ import { config as configManager } from "./config.js";
5
+ import { logger } from "./logger.js";
6
+ import { processPrompt } from "./mentions.js";
7
+ import { AiConfig } from "./models/ai-config.js";
8
+ import { systemPrompt } from "./prompts.js";
9
+ import { ReplPrompt } from "./repl-prompt.js";
10
+ import { isMarkdown } from "./terminal/markdown-utils.js";
11
+ import { getCurrentBranch, getDiffStat, hasUncommittedChanges, inGitDirectory, } from "./tools/git-utils.js"; // Modified import
12
+ import { initAgents, initTools } from "./tools/index.js";
13
+ export class Repl {
14
+ options;
15
+ constructor(options) {
16
+ this.options = options;
17
+ }
18
+ async run() {
19
+ const { config, promptManager, terminal, modelManager, tokenTracker, messageHistory, commands, tokenCounter, toolEvents, autoAcceptAll, } = this.options;
20
+ logger.info(config, "Config:");
21
+ terminal.displayWelcome();
22
+ const promptHistory = [];
23
+ let currentContextWindow = 0;
24
+ messageHistory.on("clear-history", () => {
25
+ currentContextWindow = 0;
26
+ });
27
+ let prevCb = null;
28
+ while (true) {
29
+ const abortController = new AbortController();
30
+ const { signal } = abortController;
31
+ const cb = () => {
32
+ abortController.abort();
33
+ };
34
+ if (prevCb) {
35
+ process.removeListener("SIGINT", prevCb);
36
+ }
37
+ // Handle Ctrl+C (SIGINT)
38
+ process.on("SIGINT", cb);
39
+ prevCb = cb;
40
+ const langModel = modelManager.getModel("repl");
41
+ const modelConfig = modelManager.getModelMetadata("repl");
42
+ const currentDir = process.cwd().split("/").pop() || process.cwd();
43
+ const branch = await getCurrentBranch();
44
+ let branchDisplay = "";
45
+ if (branch) {
46
+ const hasChanges = await hasUncommittedChanges();
47
+ const asterisk = hasChanges ? "*" : "";
48
+ branchDisplay = ` ${chalk.gray(branch + asterisk)}`;
49
+ }
50
+ terminal.hr();
51
+ terminal.writeln(`${chalk.blue(currentDir)}${branchDisplay}`);
52
+ terminal.writeln(chalk.dim(langModel.modelId));
53
+ terminal.displayProgressBar(currentContextWindow, modelConfig.contextWindow);
54
+ if (!promptManager.isPending()) {
55
+ // For interactive input
56
+ const prompt = new ReplPrompt({ commands, history: promptHistory });
57
+ const userInput = await prompt.input();
58
+ prompt.close();
59
+ // see if the userInput contains a command
60
+ const commandResult = await commands.handle({ userInput });
61
+ if (commandResult.break) {
62
+ break;
63
+ }
64
+ if (commandResult.continue) {
65
+ terminal.lineBreak();
66
+ continue;
67
+ }
68
+ if (!userInput.trim()) {
69
+ continue;
70
+ }
71
+ // if there is no pending prompt then use the user's input. otherwise, the prompt was loaded from a command
72
+ if (!promptManager.isPending()) {
73
+ const processedPrompt = await processPrompt(userInput, {
74
+ baseDir: process.cwd(),
75
+ model: modelConfig,
76
+ });
77
+ for (const context of processedPrompt.context) {
78
+ promptManager.addContext(context);
79
+ }
80
+ promptManager.set(processedPrompt.message);
81
+ }
82
+ terminal.lineBreak();
83
+ }
84
+ // flag to see if the user prompt has added context
85
+ const hasAddedContext = promptManager.hasContext();
86
+ if (hasAddedContext) {
87
+ terminal.info("Context will be added to prompt.");
88
+ terminal.lineBreak();
89
+ }
90
+ const userPrompt = promptManager.get();
91
+ const userMsg = promptManager.getUserMessage();
92
+ messageHistory.appendUserMessage(userMsg);
93
+ const finalSystemPrompt = await systemPrompt({
94
+ supportsToolCalling: modelConfig.supportsToolCalling,
95
+ });
96
+ const aiConfig = new AiConfig({
97
+ modelMetadata: modelConfig,
98
+ prompt: userPrompt,
99
+ });
100
+ const maxTokens = aiConfig.getMaxTokens();
101
+ const tools = modelConfig.supportsToolCalling
102
+ ? {
103
+ ...(await initTools({
104
+ terminal,
105
+ tokenCounter,
106
+ autoAcceptAll,
107
+ events: toolEvents,
108
+ })),
109
+ ...(await initAgents({
110
+ terminal,
111
+ modelManager,
112
+ tokenTracker,
113
+ tokenCounter,
114
+ events: toolEvents,
115
+ })),
116
+ }
117
+ : undefined;
118
+ try {
119
+ const result = streamText({
120
+ model: langModel,
121
+ maxOutputTokens: maxTokens,
122
+ messages: [
123
+ {
124
+ role: "system",
125
+ content: finalSystemPrompt,
126
+ providerOptions: {
127
+ anthropic: { cacheControl: { type: "ephemeral" } },
128
+ },
129
+ },
130
+ ...messageHistory.get(),
131
+ ],
132
+ temperature: modelConfig.defaultTemperature,
133
+ stopWhen: stepCountIs(60),
134
+ maxRetries: 2,
135
+ providerOptions: aiConfig.getProviderOptions(),
136
+ tools,
137
+ // biome-ignore lint/style/useNamingConvention: third-party controlled
138
+ experimental_repairToolCall: modelConfig.supportsToolCalling
139
+ ? toolCallRepair(modelManager, terminal)
140
+ : undefined,
141
+ abortSignal: signal,
142
+ onFinish: async (result) => {
143
+ logger.debug("onFinish called");
144
+ if (result.response.messages.length > 0) {
145
+ messageHistory.appendResponseMessages(result.response.messages);
146
+ }
147
+ terminal.hr();
148
+ // Notify if configured in project config (acai.json)
149
+ const projectConfig = await configManager.readProjectConfig();
150
+ if (projectConfig.notify) {
151
+ terminal.alert();
152
+ }
153
+ // Create a more visual representation of steps/tool usage
154
+ this.displayToolUse(result, terminal);
155
+ if (await inGitDirectory()) {
156
+ // Added check
157
+ const stats = await getDiffStat();
158
+ terminal.writeln(`${chalk.dim("Files changed:")} ${chalk.yellow(stats.filesChanged)} ` +
159
+ `${chalk.green(`+${stats.insertions}`)} ` + // Insertions first (green)
160
+ `${chalk.red(`-${stats.deletions}`)}`);
161
+ }
162
+ const total = result.totalUsage ??
163
+ result.usage;
164
+ const outgoingTokens = isNumber(total.inputTokens)
165
+ ? total.inputTokens
166
+ : 0;
167
+ const incomingTokens = isNumber(total.outputTokens)
168
+ ? total.outputTokens
169
+ : 0;
170
+ const tokenSummary = `Tokens: ↑ ${outgoingTokens} ↓ ${incomingTokens}`;
171
+ terminal.writeln(chalk.dim(tokenSummary));
172
+ // Track aggregate usage across all steps when available
173
+ tokenTracker.trackUsage("repl", total);
174
+ // Derive current context window from final step usage
175
+ const finalTotalTokens = result.usage.totalTokens;
176
+ if (isNumber(finalTotalTokens)) {
177
+ currentContextWindow = finalTotalTokens ?? 0;
178
+ }
179
+ else {
180
+ // Fallback: find the stopped step
181
+ for (const step of result.steps) {
182
+ if (step.finishReason === "stop") {
183
+ const usage = step.usage;
184
+ currentContextWindow = Number.isNaN(usage.totalTokens)
185
+ ? 0
186
+ : (usage.totalTokens ?? 0);
187
+ }
188
+ }
189
+ }
190
+ // comment out auto-summarization for now. it's been causing issues.
191
+ // if (currentContextWindow > 70000) {
192
+ // logger.info(
193
+ // `Condensing history from ${currentContextWindow} to 0`,
194
+ // );
195
+ // await messageHistory.summarizeAndReset();
196
+ // }
197
+ terminal.hr();
198
+ },
199
+ onError: ({ error }) => {
200
+ logger.error(error, // Log the full error object
201
+ "Error on REPL streamText");
202
+ terminal.error(error.message.length > 100
203
+ ? `${error.message.slice(0, 100)}...`
204
+ : error.message);
205
+ },
206
+ });
207
+ let accumulatedText = "";
208
+ let lastType = null;
209
+ for await (const chunk of result.fullStream) {
210
+ // Handle text-related chunks (reasoning or text-delta)
211
+ if (chunk.type === "reasoning-delta" || chunk.type === "text-delta") {
212
+ if (chunk.type === "reasoning-delta") {
213
+ if (lastType !== "reasoning") {
214
+ terminal.writeln(chalk.dim("<think>"));
215
+ }
216
+ terminal.write(chalk.dim(chunk.text)); // Stream reasoning directly
217
+ lastType = "reasoning";
218
+ }
219
+ else if (chunk.type === "text-delta") {
220
+ if (lastType === "reasoning") {
221
+ // Finishing reasoning: Print </think>
222
+ terminal.writeln(chalk.dim("\n</think>\n"));
223
+ }
224
+ accumulatedText += chunk.text;
225
+ lastType = "text";
226
+ }
227
+ }
228
+ else if (chunk.type === "tool-result") {
229
+ const messages = toolEvents.get(chunk.toolCallId);
230
+ if (messages) {
231
+ displayToolMessages(messages, terminal);
232
+ toolEvents.delete(chunk.toolCallId);
233
+ }
234
+ else {
235
+ logger.warn(`No tool events found for ${chunk.toolCallId}`);
236
+ }
237
+ }
238
+ else {
239
+ // Close thinking tags when moving from reasoning to any other chunk type
240
+ if (lastType === "reasoning") {
241
+ terminal.write(chalk.dim("\n</think>\n\n"));
242
+ }
243
+ // if there is accumulatedText, display it
244
+ if (accumulatedText) {
245
+ terminal.writeln(`${chalk.blue.bold("●")} Response:`);
246
+ terminal.display(accumulatedText, true);
247
+ terminal.lineBreak();
248
+ }
249
+ accumulatedText = "";
250
+ lastType = null;
251
+ }
252
+ }
253
+ // Ensure the final closing tag for reasoning is written if it was the last type
254
+ if (lastType === "reasoning") {
255
+ terminal.write(chalk.gray("\n</think>\n\n"));
256
+ }
257
+ // if there is accumulatedText, display it
258
+ if (accumulatedText) {
259
+ terminal.writeln(`${chalk.green.bold("●")} Response:`);
260
+ terminal.display(accumulatedText, true);
261
+ terminal.lineBreak();
262
+ }
263
+ terminal.lineBreak(); // Add a final newline for clarity
264
+ await result.consumeStream();
265
+ }
266
+ catch (e) {
267
+ if (isRecord(e) && isRecord(e["data"]) && "error" in e["data"]) {
268
+ terminal.error(e["data"]["error"].message);
269
+ }
270
+ else {
271
+ terminal.error(e.message.length > 100
272
+ ? `${e.message.slice(0, 100)}...`
273
+ : e.message);
274
+ }
275
+ terminal.lineBreak();
276
+ if (e instanceof Error) {
277
+ logger.error(e);
278
+ }
279
+ else {
280
+ logger.error(JSON.stringify(e, null, 2));
281
+ }
282
+ }
283
+ }
284
+ }
285
+ displayToolUse(result, terminal) {
286
+ const toolsCalled = [];
287
+ const toolColors = new Map();
288
+ const chalkColors = [
289
+ "red",
290
+ "green",
291
+ "yellow",
292
+ "blue",
293
+ "magenta",
294
+ "cyan",
295
+ "white",
296
+ "gray",
297
+ "redBright",
298
+ "greenBright",
299
+ "yellowBright",
300
+ "blueBright",
301
+ "magentaBright",
302
+ "cyanBright",
303
+ "whiteBright",
304
+ "blackBright",
305
+ ];
306
+ terminal.writeln(chalk.dim(`Steps: ${result.steps.length}`));
307
+ for (const step of result.steps) {
308
+ let currentToolCalls = [];
309
+ if (step.toolResults.length > 0) {
310
+ currentToolCalls = step.toolResults;
311
+ }
312
+ else if (step.toolCalls.length > 0) {
313
+ currentToolCalls = step.toolCalls;
314
+ }
315
+ for (const toolCallOrResult of currentToolCalls) {
316
+ const toolName = toolCallOrResult.toolName;
317
+ if (!toolColors.has(toolName)) {
318
+ const availableColors = chalkColors.filter((color) => !Array.from(toolColors.values()).some((c) => c === chalk[color]));
319
+ const color = availableColors.length > 0
320
+ ? (availableColors[Math.floor(Math.random() * availableColors.length)] ?? "white")
321
+ : "white";
322
+ toolColors.set(toolName, chalk[color]);
323
+ }
324
+ toolsCalled.push(toolName);
325
+ }
326
+ }
327
+ if (toolsCalled.length > 0) {
328
+ terminal.writeln(chalk.dim("Tools:"));
329
+ for (const toolCalled of toolsCalled) {
330
+ const colorFn = toolColors.get(toolCalled) ?? chalk.white;
331
+ terminal.write(`${colorFn("██")} `);
332
+ }
333
+ terminal.lineBreak();
334
+ const uniqueTools = new Set(toolsCalled);
335
+ for (const [index, toolCalled] of Array.from(uniqueTools).entries()) {
336
+ const colorFn = toolColors.get(toolCalled) ?? chalk.white;
337
+ terminal.write(colorFn(toolCalled));
338
+ if (index < new Set(toolsCalled).size - 1) {
339
+ terminal.write(" - ");
340
+ }
341
+ }
342
+ terminal.lineBreak();
343
+ terminal.lineBreak();
344
+ }
345
+ }
346
+ }
347
+ function displayToolMessages(messages, terminal) {
348
+ const isError = messages[messages.length - 1]?.event === "tool-error";
349
+ const indicator = isError ? chalk.red.bold("●") : chalk.blue.bold("●");
350
+ const initMessage = messages.find((m) => m.event === "tool-init")?.data ?? "Tool Execution";
351
+ terminal.write(`${indicator} `); // Write indicator without newline (sync)
352
+ terminal.display(initMessage); // Display initial message (async)
353
+ for (const msg of messages) {
354
+ switch (msg.event) {
355
+ case "tool-update":
356
+ _handleToolUpdateMessage(msg.data, terminal);
357
+ break;
358
+ case "tool-completion":
359
+ _handleToolCompletionMessage(msg.data, terminal);
360
+ break;
361
+ case "tool-error":
362
+ _handleToolErrorMessage(msg.data, terminal);
363
+ break;
364
+ // 'tool-init' is handled before the loop, so no case needed here.
365
+ default:
366
+ // Optional: Log an unexpected event type for debugging, or do nothing.
367
+ logger.debug(`Unhandled tool message event: ${msg.event}`);
368
+ break;
369
+ }
370
+ }
371
+ terminal.lineBreak();
372
+ }
373
+ // Helper function to handle tool update messages
374
+ function _handleToolUpdateMessage(data, terminal) {
375
+ if (data.secondary && data.secondary.length > 0) {
376
+ const content = data.secondary.join("\n");
377
+ if (content.trim().length !== 0) {
378
+ terminal.display(`└── ${data.primary}`);
379
+ terminal.hr();
380
+ if (isMarkdown(content)) {
381
+ terminal.display(content, true);
382
+ }
383
+ else {
384
+ terminal.write(chalk.green(content));
385
+ terminal.lineBreak();
386
+ }
387
+ terminal.hr();
388
+ }
389
+ }
390
+ else {
391
+ terminal.display(`└── ${data.primary}`);
392
+ }
393
+ }
394
+ // Helper function to handle tool completion messages
395
+ function _handleToolCompletionMessage(data, terminal) {
396
+ terminal.display(`└── ${data}`);
397
+ }
398
+ // Helper function to handle tool error messages
399
+ function _handleToolErrorMessage(data, terminal) {
400
+ terminal.write("└── ");
401
+ terminal.error(data);
402
+ }
403
+ const toolCallRepair = (modelManager, terminal) => {
404
+ const fn = async ({ toolCall, tools, inputSchema, error, }) => {
405
+ if (NoSuchToolError.isInstance(error)) {
406
+ return null; // do not attempt to fix invalid tool names
407
+ }
408
+ terminal.warn(`Attempting to repair tool call: ${toolCall.toolName}.`);
409
+ terminal.lineBreak();
410
+ const tool = tools[toolCall.toolName];
411
+ try {
412
+ const { object: repairedArgs } = await generateObject({
413
+ model: modelManager.getModel("tool-repair"),
414
+ schema: tool.inputSchema,
415
+ prompt: [
416
+ `The model tried to call the tool "${toolCall.toolName}" with the following arguments:`,
417
+ JSON.stringify(toolCall.input),
418
+ "The tool accepts the following schema:",
419
+ JSON.stringify(inputSchema(toolCall)),
420
+ "Please fix the arguments.",
421
+ ].join("\n"),
422
+ });
423
+ return { ...toolCall, args: JSON.stringify(repairedArgs) };
424
+ }
425
+ catch (err) {
426
+ logger.error(err, `Failed to repair tool call: ${toolCall.toolName}.`);
427
+ return null;
428
+ }
429
+ };
430
+ return fn;
431
+ };
@@ -0,0 +1,19 @@
1
+ import type { MessageHistory } from "./messages.ts";
2
+ import type { ModelManager } from "./models/manager.js";
3
+ import type { PromptManager } from "./prompts/manager.ts";
4
+ import type { TokenTracker } from "./token-tracker.ts";
5
+ import type { TokenCounter } from "./token-utils.ts";
6
+ interface CliOptions {
7
+ messageHistory: MessageHistory;
8
+ promptManager: PromptManager;
9
+ modelManager: ModelManager;
10
+ tokenTracker: TokenTracker;
11
+ config: Record<PropertyKey, unknown>;
12
+ tokenCounter: TokenCounter;
13
+ }
14
+ export declare class Cli {
15
+ private options;
16
+ constructor(options: CliOptions);
17
+ run(): Promise<void>;
18
+ }
19
+ export {};
@@ -0,0 +1,116 @@
1
+ import { generateObject, generateText, NoSuchToolError, stepCountIs, } from "ai";
2
+ import { logger } from "./logger.js";
3
+ import { AiConfig } from "./models/ai-config.js";
4
+ import { minSystemPrompt } from "./prompts.js";
5
+ import { DeleteFileTool } from "./tools/delete-file.js";
6
+ import { EditFileTool } from "./tools/edit-file.js";
7
+ import { initCliTools } from "./tools/index.js";
8
+ import { MoveFileTool } from "./tools/move-file.js";
9
+ import { SaveFileTool } from "./tools/save-file.js";
10
+ import { ThinkTool } from "./tools/think.js";
11
+ export class Cli {
12
+ options;
13
+ constructor(options) {
14
+ this.options = options;
15
+ }
16
+ async run() {
17
+ const { config, promptManager, modelManager, tokenTracker, messageHistory, tokenCounter, } = this.options;
18
+ logger.info(config, "Config:");
19
+ const abortController = new AbortController();
20
+ const { signal } = abortController;
21
+ const cb = () => {
22
+ abortController.abort();
23
+ };
24
+ // Handle Ctrl+C (SIGINT)
25
+ process.on("SIGINT", cb);
26
+ const langModel = modelManager.getModel("cli");
27
+ const modelConfig = modelManager.getModelMetadata("cli");
28
+ const userPrompt = promptManager.get();
29
+ const userMsg = promptManager.getUserMessage();
30
+ messageHistory.appendUserMessage(userMsg);
31
+ const finalSystemPrompt = await minSystemPrompt();
32
+ const aiConfig = new AiConfig({
33
+ modelMetadata: modelConfig,
34
+ prompt: userPrompt,
35
+ });
36
+ const maxTokens = aiConfig.getMaxTokens();
37
+ const tools = modelConfig.supportsToolCalling
38
+ ? await initCliTools({ tokenCounter })
39
+ : undefined;
40
+ try {
41
+ const result = await generateText({
42
+ model: langModel,
43
+ maxOutputTokens: maxTokens,
44
+ messages: [
45
+ {
46
+ role: "system",
47
+ content: finalSystemPrompt,
48
+ providerOptions: {
49
+ anthropic: { cacheControl: { type: "ephemeral" } },
50
+ },
51
+ },
52
+ ...messageHistory.get(),
53
+ ],
54
+ temperature: modelConfig.defaultTemperature,
55
+ stopWhen: stepCountIs(60),
56
+ maxRetries: 2,
57
+ providerOptions: aiConfig.getProviderOptions(),
58
+ tools,
59
+ // biome-ignore lint/style/useNamingConvention: third-party controlled
60
+ experimental_activeTools: [
61
+ EditFileTool.name,
62
+ SaveFileTool.name,
63
+ MoveFileTool.name,
64
+ DeleteFileTool.name,
65
+ ThinkTool.name,
66
+ ],
67
+ // biome-ignore lint/style/useNamingConvention: third-party controlled
68
+ experimental_repairToolCall: modelConfig.supportsToolCalling
69
+ ? toolCallRepair(modelManager)
70
+ : undefined,
71
+ abortSignal: signal,
72
+ });
73
+ if (result.response.messages.length > 0) {
74
+ messageHistory.appendResponseMessages(result.response.messages);
75
+ }
76
+ // this tracks the usage of every step in the call to streamText. it's a cumulative usage.
77
+ tokenTracker.trackUsage("cli", result.usage);
78
+ process.stdout.end(result.text.endsWith("\n") ? result.text : `${result.text}\n`);
79
+ }
80
+ catch (e) {
81
+ if (e instanceof Error) {
82
+ logger.error(e);
83
+ }
84
+ else {
85
+ logger.error(JSON.stringify(e, null, 2));
86
+ }
87
+ }
88
+ }
89
+ }
90
+ const toolCallRepair = (modelManager) => {
91
+ const fn = async ({ toolCall, tools, inputSchema, error, }) => {
92
+ if (NoSuchToolError.isInstance(error)) {
93
+ return null; // do not attempt to fix invalid tool names
94
+ }
95
+ const tool = tools[toolCall.toolName];
96
+ try {
97
+ const { object: repairedArgs } = await generateObject({
98
+ model: modelManager.getModel("tool-repair"),
99
+ schema: tool.inputSchema,
100
+ prompt: [
101
+ `The model tried to call the tool "${toolCall.toolName}" with the following arguments:`,
102
+ JSON.stringify(toolCall.input),
103
+ "The tool accepts the following schema:",
104
+ JSON.stringify(inputSchema(toolCall)),
105
+ "Please fix the arguments.",
106
+ ].join("\n"),
107
+ });
108
+ return { ...toolCall, args: JSON.stringify(repairedArgs) };
109
+ }
110
+ catch (err) {
111
+ logger.error(err, `Failed to repair tool call: ${toolCall.toolName}.`);
112
+ return null;
113
+ }
114
+ };
115
+ return fn;
116
+ };
@@ -0,0 +1,2 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+ export declare const applicationLogCommand: ({ terminal, }: CommandOptions) => ReplCommand;
@@ -0,0 +1,43 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { editor } from "@inquirer/prompts";
3
+ import { config } from "../config.js";
4
+ export const applicationLogCommand = ({ terminal, }) => {
5
+ return {
6
+ command: "/application-logs",
7
+ description: "Opens the application log file defined in acai.json in the editor.",
8
+ result: "continue",
9
+ getSubCommands: () => Promise.resolve([]),
10
+ execute: async () => {
11
+ let logFilePath;
12
+ try {
13
+ const projectConfig = await config.readProjectConfig();
14
+ logFilePath = projectConfig.logs?.path;
15
+ if (!logFilePath) {
16
+ terminal.error("Application log path is not defined in .acai/acai.json under the 'logs.path' key.");
17
+ return;
18
+ }
19
+ const content = await readFile(logFilePath, { encoding: "utf8" });
20
+ // Use the editor prompt to display the content (read-only)
21
+ await editor({
22
+ message: `Viewing ${logFilePath}`,
23
+ // Attempt to infer postfix from file extension, default otherwise
24
+ postfix: logFilePath.includes(".")
25
+ ? `.${logFilePath.split(".").pop()}`
26
+ : ".log",
27
+ default: content,
28
+ // By not providing an onSubmit or similar handler to write the file,
29
+ // and not calling writeFileSync after, this effectively becomes read-only.
30
+ });
31
+ terminal.info(`Closed log view for: ${logFilePath}`);
32
+ }
33
+ catch (error) {
34
+ if (logFilePath && error.code === "ENOENT") {
35
+ terminal.error(`Application log file not found at: ${logFilePath}`);
36
+ }
37
+ else {
38
+ terminal.error(`Error reading or displaying log file ${logFilePath ?? "specified in config"}: ${error}`);
39
+ }
40
+ }
41
+ },
42
+ };
43
+ };
@@ -0,0 +1,2 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+ export declare const clearCommand: ({ terminal }: CommandOptions) => ReplCommand;
@@ -0,0 +1,12 @@
1
+ export const clearCommand = ({ terminal }) => {
2
+ return {
3
+ command: "/clear",
4
+ description: "Clears the terminal screen.",
5
+ result: "continue", // Keep the REPL running
6
+ getSubCommands: () => Promise.resolve([]),
7
+ execute: () => {
8
+ terminal.clear();
9
+ return Promise.resolve();
10
+ },
11
+ };
12
+ };
@@ -0,0 +1,2 @@
1
+ import type { CommandOptions, ReplCommand } from "./types.ts";
2
+ export declare const compactCommand: (options: CommandOptions) => ReplCommand;