@travisennis/acai 0.0.5 → 0.0.7

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 (421) hide show
  1. package/README.md +190 -19
  2. package/bin/acai-wrapper.js +26 -0
  3. package/dist/agent/index.d.ts +132 -0
  4. package/dist/agent/index.d.ts.map +1 -0
  5. package/dist/agent/index.js +434 -0
  6. package/dist/api/exa/index.js +1 -1
  7. package/dist/cli.d.ts +4 -1
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +67 -40
  10. package/dist/commands/add-directory-command.d.ts +3 -0
  11. package/dist/commands/add-directory-command.d.ts.map +1 -0
  12. package/dist/commands/add-directory-command.js +54 -0
  13. package/dist/commands/application-log-command.d.ts +1 -1
  14. package/dist/commands/application-log-command.d.ts.map +1 -1
  15. package/dist/commands/application-log-command.js +18 -20
  16. package/dist/commands/clear-command.d.ts +1 -1
  17. package/dist/commands/clear-command.d.ts.map +1 -1
  18. package/dist/commands/clear-command.js +7 -3
  19. package/dist/commands/compact-command.d.ts.map +1 -1
  20. package/dist/commands/compact-command.js +9 -5
  21. package/dist/commands/context-command.d.ts +3 -0
  22. package/dist/commands/context-command.d.ts.map +1 -0
  23. package/dist/commands/context-command.js +124 -0
  24. package/dist/commands/copy-command.d.ts.map +1 -1
  25. package/dist/commands/copy-command.js +14 -5
  26. package/dist/commands/edit-command.d.ts +1 -1
  27. package/dist/commands/edit-command.d.ts.map +1 -1
  28. package/dist/commands/edit-command.js +21 -34
  29. package/dist/commands/edit-prompt-command.d.ts +1 -1
  30. package/dist/commands/edit-prompt-command.d.ts.map +1 -1
  31. package/dist/commands/edit-prompt-command.js +18 -15
  32. package/dist/commands/exit-command.d.ts +1 -4
  33. package/dist/commands/exit-command.d.ts.map +1 -1
  34. package/dist/commands/exit-command.js +9 -5
  35. package/dist/commands/files-command.d.ts +1 -1
  36. package/dist/commands/files-command.d.ts.map +1 -1
  37. package/dist/commands/files-command.js +20 -16
  38. package/dist/commands/generate-rules-command.d.ts +1 -1
  39. package/dist/commands/generate-rules-command.d.ts.map +1 -1
  40. package/dist/commands/generate-rules-command.js +307 -39
  41. package/dist/commands/handoff-command.d.ts +3 -0
  42. package/dist/commands/handoff-command.d.ts.map +1 -0
  43. package/dist/commands/handoff-command.js +191 -0
  44. package/dist/commands/health-command.d.ts +1 -1
  45. package/dist/commands/health-command.d.ts.map +1 -1
  46. package/dist/commands/health-command.js +49 -27
  47. package/dist/commands/help-command.d.ts +1 -1
  48. package/dist/commands/help-command.d.ts.map +1 -1
  49. package/dist/commands/help-command.js +25 -5
  50. package/dist/commands/history-command.d.ts +3 -0
  51. package/dist/commands/history-command.d.ts.map +1 -0
  52. package/dist/commands/history-command.js +458 -0
  53. package/dist/commands/init-command.d.ts +1 -1
  54. package/dist/commands/init-command.d.ts.map +1 -1
  55. package/dist/commands/init-command.js +40 -22
  56. package/dist/commands/last-log-command.d.ts +1 -1
  57. package/dist/commands/last-log-command.d.ts.map +1 -1
  58. package/dist/commands/last-log-command.js +15 -15
  59. package/dist/commands/list-directories-command.d.ts +3 -0
  60. package/dist/commands/list-directories-command.d.ts.map +1 -0
  61. package/dist/commands/list-directories-command.js +35 -0
  62. package/dist/commands/list-tools-command.d.ts.map +1 -1
  63. package/dist/commands/list-tools-command.js +61 -21
  64. package/dist/commands/manager.d.ts +9 -4
  65. package/dist/commands/manager.d.ts.map +1 -1
  66. package/dist/commands/manager.js +64 -39
  67. package/dist/commands/model-command.d.ts.map +1 -1
  68. package/dist/commands/model-command.js +201 -66
  69. package/dist/commands/paste-command.d.ts +1 -1
  70. package/dist/commands/paste-command.d.ts.map +1 -1
  71. package/dist/commands/paste-command.js +23 -9
  72. package/dist/commands/pickup-command.d.ts +3 -0
  73. package/dist/commands/pickup-command.d.ts.map +1 -0
  74. package/dist/commands/pickup-command.js +109 -0
  75. package/dist/commands/prompt-command.d.ts +19 -1
  76. package/dist/commands/prompt-command.d.ts.map +1 -1
  77. package/dist/commands/prompt-command.js +191 -98
  78. package/dist/commands/remove-directory-command.d.ts +3 -0
  79. package/dist/commands/remove-directory-command.d.ts.map +1 -0
  80. package/dist/commands/remove-directory-command.js +55 -0
  81. package/dist/commands/reset-command.d.ts +1 -1
  82. package/dist/commands/reset-command.d.ts.map +1 -1
  83. package/dist/commands/reset-command.js +8 -5
  84. package/dist/commands/rules-command.d.ts +1 -1
  85. package/dist/commands/rules-command.d.ts.map +1 -1
  86. package/dist/commands/rules-command.js +25 -22
  87. package/dist/commands/save-command.d.ts +1 -1
  88. package/dist/commands/save-command.d.ts.map +1 -1
  89. package/dist/commands/save-command.js +8 -3
  90. package/dist/commands/shell-command.d.ts.map +1 -1
  91. package/dist/commands/shell-command.js +45 -24
  92. package/dist/commands/types.d.ts +9 -7
  93. package/dist/commands/types.d.ts.map +1 -1
  94. package/dist/commands/usage-command.d.ts +1 -1
  95. package/dist/commands/usage-command.d.ts.map +1 -1
  96. package/dist/commands/usage-command.js +18 -7
  97. package/dist/config.d.ts +21 -11
  98. package/dist/config.d.ts.map +1 -1
  99. package/dist/config.js +90 -63
  100. package/dist/execution/index.d.ts +17 -2
  101. package/dist/execution/index.d.ts.map +1 -1
  102. package/dist/execution/index.js +62 -20
  103. package/dist/formatting.d.ts +127 -0
  104. package/dist/formatting.d.ts.map +1 -1
  105. package/dist/formatting.js +201 -0
  106. package/dist/index.d.ts +7 -2
  107. package/dist/index.d.ts.map +1 -1
  108. package/dist/index.js +263 -102
  109. package/dist/logger.d.ts.map +1 -1
  110. package/dist/logger.js +47 -18
  111. package/dist/mentions.d.ts +2 -1
  112. package/dist/mentions.d.ts.map +1 -1
  113. package/dist/mentions.js +16 -1
  114. package/dist/messages.d.ts +11 -0
  115. package/dist/messages.d.ts.map +1 -1
  116. package/dist/messages.js +122 -21
  117. package/dist/middleware/cache.d.ts +3 -0
  118. package/dist/middleware/cache.d.ts.map +1 -0
  119. package/dist/middleware/cache.js +53 -0
  120. package/dist/middleware/index.d.ts +1 -0
  121. package/dist/middleware/index.d.ts.map +1 -1
  122. package/dist/middleware/index.js +1 -0
  123. package/dist/models/ai-config.d.ts +4 -2
  124. package/dist/models/ai-config.d.ts.map +1 -1
  125. package/dist/models/ai-config.js +12 -2
  126. package/dist/models/anthropic-provider.d.ts.map +1 -1
  127. package/dist/models/anthropic-provider.js +3 -67
  128. package/dist/models/deepseek-provider.d.ts.map +1 -1
  129. package/dist/models/deepseek-provider.js +0 -2
  130. package/dist/models/google-provider.d.ts.map +1 -1
  131. package/dist/models/google-provider.js +0 -3
  132. package/dist/models/groq-provider.d.ts.map +1 -1
  133. package/dist/models/groq-provider.js +0 -1
  134. package/dist/models/manager.d.ts +2 -1
  135. package/dist/models/manager.d.ts.map +1 -1
  136. package/dist/models/manager.js +26 -2
  137. package/dist/models/openai-provider.d.ts.map +1 -1
  138. package/dist/models/openai-provider.js +0 -4
  139. package/dist/models/openrouter-provider.d.ts +16 -22
  140. package/dist/models/openrouter-provider.d.ts.map +1 -1
  141. package/dist/models/openrouter-provider.js +175 -236
  142. package/dist/models/providers.d.ts +4 -14
  143. package/dist/models/providers.d.ts.map +1 -1
  144. package/dist/models/providers.js +1 -57
  145. package/dist/models/xai-provider.d.ts.map +1 -1
  146. package/dist/models/xai-provider.js +0 -2
  147. package/dist/prompts.d.ts +10 -4
  148. package/dist/prompts.d.ts.map +1 -1
  149. package/dist/prompts.js +447 -70
  150. package/dist/repl/project-status-line.d.ts +3 -0
  151. package/dist/repl/project-status-line.d.ts.map +1 -0
  152. package/dist/repl/project-status-line.js +61 -0
  153. package/dist/repl/tool-call-repair.d.ts.map +1 -1
  154. package/dist/repl/tool-call-repair.js +8 -4
  155. package/dist/repl-new.d.ts +51 -0
  156. package/dist/repl-new.d.ts.map +1 -0
  157. package/dist/repl-new.js +354 -0
  158. package/dist/skills.d.ts +20 -0
  159. package/dist/skills.d.ts.map +1 -0
  160. package/dist/skills.js +192 -0
  161. package/dist/terminal/control.d.ts +55 -0
  162. package/dist/terminal/control.d.ts.map +1 -0
  163. package/dist/terminal/control.js +109 -0
  164. package/dist/terminal/default-theme.d.ts +1 -1
  165. package/dist/terminal/default-theme.d.ts.map +1 -1
  166. package/dist/terminal/default-theme.js +24 -28
  167. package/dist/terminal/formatting.d.ts +23 -25
  168. package/dist/terminal/formatting.d.ts.map +1 -1
  169. package/dist/terminal/formatting.js +35 -52
  170. package/dist/terminal/highlight/index.d.ts.map +1 -1
  171. package/dist/terminal/highlight/index.js +3 -6
  172. package/dist/terminal/highlight/theme.d.ts.map +1 -1
  173. package/dist/terminal/highlight/theme.js +2 -6
  174. package/dist/terminal/index.d.ts +2 -94
  175. package/dist/terminal/index.d.ts.map +1 -1
  176. package/dist/terminal/index.js +2 -370
  177. package/dist/terminal/markdown.js +10 -5
  178. package/dist/terminal/select-prompt.d.ts +2 -2
  179. package/dist/terminal/select-prompt.d.ts.map +1 -1
  180. package/dist/terminal/select-prompt.js +47 -39
  181. package/dist/terminal/strip-ansi.js +4 -4
  182. package/dist/terminal/table/cell.d.ts +114 -0
  183. package/dist/terminal/table/cell.d.ts.map +1 -0
  184. package/dist/terminal/table/cell.js +407 -0
  185. package/dist/terminal/table/debug.d.ts +15 -0
  186. package/dist/terminal/table/debug.d.ts.map +1 -0
  187. package/dist/terminal/table/debug.js +32 -0
  188. package/dist/terminal/table/index.d.ts +3 -0
  189. package/dist/terminal/table/index.d.ts.map +1 -0
  190. package/dist/terminal/table/index.js +2 -0
  191. package/dist/terminal/table/layout-manager.d.ts +27 -0
  192. package/dist/terminal/table/layout-manager.d.ts.map +1 -0
  193. package/dist/terminal/table/layout-manager.js +257 -0
  194. package/dist/terminal/table/table.d.ts +9 -0
  195. package/dist/terminal/table/table.d.ts.map +1 -0
  196. package/dist/terminal/table/table.js +97 -0
  197. package/dist/terminal/table/utils.d.ts +63 -0
  198. package/dist/terminal/table/utils.d.ts.map +1 -0
  199. package/dist/terminal/table/utils.js +326 -0
  200. package/dist/tokens/threshold.d.ts +20 -0
  201. package/dist/tokens/threshold.d.ts.map +1 -0
  202. package/dist/tokens/threshold.js +67 -0
  203. package/dist/tools/advanced-edit-file.d.ts +69 -0
  204. package/dist/tools/advanced-edit-file.d.ts.map +1 -0
  205. package/dist/tools/advanced-edit-file.js +285 -0
  206. package/dist/tools/agent.d.ts +16 -5
  207. package/dist/tools/agent.d.ts.map +1 -1
  208. package/dist/tools/agent.js +86 -59
  209. package/dist/tools/bash.d.ts +23 -12
  210. package/dist/tools/bash.d.ts.map +1 -1
  211. package/dist/tools/bash.js +243 -128
  212. package/dist/tools/batch.d.ts +34 -0
  213. package/dist/tools/batch.d.ts.map +1 -0
  214. package/dist/tools/batch.js +174 -0
  215. package/dist/tools/code-interpreter.d.ts +21 -9
  216. package/dist/tools/code-interpreter.d.ts.map +1 -1
  217. package/dist/tools/code-interpreter.js +151 -134
  218. package/dist/tools/delete-file.d.ts +17 -10
  219. package/dist/tools/delete-file.d.ts.map +1 -1
  220. package/dist/tools/delete-file.js +60 -97
  221. package/dist/tools/directory-tree.d.ts +17 -12
  222. package/dist/tools/directory-tree.d.ts.map +1 -1
  223. package/dist/tools/directory-tree.js +57 -48
  224. package/dist/tools/dynamic-tool-loader.d.ts +16 -10
  225. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  226. package/dist/tools/dynamic-tool-loader.js +122 -130
  227. package/dist/tools/dynamic-tool-parser.d.ts +1 -0
  228. package/dist/tools/dynamic-tool-parser.d.ts.map +1 -1
  229. package/dist/tools/dynamic-tool-parser.js +1 -0
  230. package/dist/tools/edit-file.d.ts +35 -15
  231. package/dist/tools/edit-file.d.ts.map +1 -1
  232. package/dist/tools/edit-file.js +127 -114
  233. package/dist/tools/glob.d.ts +36 -0
  234. package/dist/tools/glob.d.ts.map +1 -0
  235. package/dist/tools/glob.js +154 -0
  236. package/dist/tools/grep.d.ts +73 -12
  237. package/dist/tools/grep.d.ts.map +1 -1
  238. package/dist/tools/grep.js +425 -165
  239. package/dist/tools/index.d.ts +220 -126
  240. package/dist/tools/index.d.ts.map +1 -1
  241. package/dist/tools/index.js +284 -135
  242. package/dist/tools/llm-edit-fixer.d.ts +24 -0
  243. package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
  244. package/dist/tools/llm-edit-fixer.js +136 -0
  245. package/dist/tools/move-file.d.ts +19 -7
  246. package/dist/tools/move-file.d.ts.map +1 -1
  247. package/dist/tools/move-file.js +48 -34
  248. package/dist/tools/read-file.d.ts +47 -9
  249. package/dist/tools/read-file.d.ts.map +1 -1
  250. package/dist/tools/read-file.js +84 -70
  251. package/dist/tools/read-multiple-files.d.ts +17 -6
  252. package/dist/tools/read-multiple-files.d.ts.map +1 -1
  253. package/dist/tools/read-multiple-files.js +132 -72
  254. package/dist/tools/save-file.d.ts +45 -12
  255. package/dist/tools/save-file.d.ts.map +1 -1
  256. package/dist/tools/save-file.js +76 -101
  257. package/dist/tools/think.d.ts +15 -7
  258. package/dist/tools/think.d.ts.map +1 -1
  259. package/dist/tools/think.js +34 -20
  260. package/dist/tools/types.d.ts +8 -10
  261. package/dist/tools/types.d.ts.map +1 -1
  262. package/dist/tools/types.js +9 -0
  263. package/dist/tools/utils.d.ts +14 -0
  264. package/dist/tools/utils.d.ts.map +1 -0
  265. package/dist/tools/utils.js +16 -0
  266. package/dist/tools/web-fetch.d.ts +11 -4
  267. package/dist/tools/web-fetch.d.ts.map +1 -1
  268. package/dist/tools/web-fetch.js +39 -38
  269. package/dist/tools/web-search.d.ts +15 -6
  270. package/dist/tools/web-search.d.ts.map +1 -1
  271. package/dist/tools/web-search.js +64 -31
  272. package/dist/tui/autocomplete.d.ts +44 -0
  273. package/dist/tui/autocomplete.d.ts.map +1 -0
  274. package/dist/tui/autocomplete.js +466 -0
  275. package/dist/tui/components/assistant-message.d.ts +18 -0
  276. package/dist/tui/components/assistant-message.d.ts.map +1 -0
  277. package/dist/tui/components/assistant-message.js +29 -0
  278. package/dist/tui/components/box.d.ts +20 -0
  279. package/dist/tui/components/box.d.ts.map +1 -0
  280. package/dist/tui/components/box.js +81 -0
  281. package/dist/tui/components/editor.d.ts +106 -0
  282. package/dist/tui/components/editor.d.ts.map +1 -0
  283. package/dist/tui/components/editor.js +1220 -0
  284. package/dist/tui/components/footer.d.ts +12 -0
  285. package/dist/tui/components/footer.d.ts.map +1 -0
  286. package/dist/tui/components/footer.js +209 -0
  287. package/dist/tui/components/header.d.ts +21 -0
  288. package/dist/tui/components/header.d.ts.map +1 -0
  289. package/dist/tui/components/header.js +63 -0
  290. package/dist/tui/components/input.d.ts +14 -0
  291. package/dist/tui/components/input.d.ts.map +1 -0
  292. package/dist/tui/components/input.js +122 -0
  293. package/dist/tui/components/loader.d.ts +23 -0
  294. package/dist/tui/components/loader.d.ts.map +1 -0
  295. package/dist/tui/components/loader.js +45 -0
  296. package/dist/tui/components/markdown.d.ts +106 -0
  297. package/dist/tui/components/markdown.d.ts.map +1 -0
  298. package/dist/tui/components/markdown.js +586 -0
  299. package/dist/tui/components/modal.d.ts +29 -0
  300. package/dist/tui/components/modal.d.ts.map +1 -0
  301. package/dist/tui/components/modal.js +263 -0
  302. package/dist/tui/components/progress-bar.d.ts +19 -0
  303. package/dist/tui/components/progress-bar.d.ts.map +1 -0
  304. package/dist/tui/components/progress-bar.js +78 -0
  305. package/dist/tui/components/prompt-status.d.ts +17 -0
  306. package/dist/tui/components/prompt-status.d.ts.map +1 -0
  307. package/dist/tui/components/prompt-status.js +26 -0
  308. package/dist/tui/components/select-list.d.ts +48 -0
  309. package/dist/tui/components/select-list.d.ts.map +1 -0
  310. package/dist/tui/components/select-list.js +207 -0
  311. package/dist/tui/components/spacer.d.ts +16 -0
  312. package/dist/tui/components/spacer.d.ts.map +1 -0
  313. package/dist/tui/components/spacer.js +27 -0
  314. package/dist/tui/components/table.d.ts +27 -0
  315. package/dist/tui/components/table.d.ts.map +1 -0
  316. package/dist/tui/components/table.js +125 -0
  317. package/dist/tui/components/text.d.ts +26 -0
  318. package/dist/tui/components/text.d.ts.map +1 -0
  319. package/dist/tui/components/text.js +143 -0
  320. package/dist/tui/components/thinking-block.d.ts +14 -0
  321. package/dist/tui/components/thinking-block.d.ts.map +1 -0
  322. package/dist/tui/components/thinking-block.js +33 -0
  323. package/dist/tui/components/tool-execution.d.ts +21 -0
  324. package/dist/tui/components/tool-execution.d.ts.map +1 -0
  325. package/dist/tui/components/tool-execution.js +161 -0
  326. package/dist/tui/components/user-message.d.ts +9 -0
  327. package/dist/tui/components/user-message.d.ts.map +1 -0
  328. package/dist/tui/components/user-message.js +23 -0
  329. package/dist/tui/components/welcome.d.ts +6 -0
  330. package/dist/tui/components/welcome.d.ts.map +1 -0
  331. package/dist/tui/components/welcome.js +30 -0
  332. package/dist/tui/index.d.ts +18 -0
  333. package/dist/tui/index.d.ts.map +1 -0
  334. package/dist/tui/index.js +22 -0
  335. package/dist/tui/terminal.d.ts +38 -0
  336. package/dist/tui/terminal.d.ts.map +1 -0
  337. package/dist/tui/terminal.js +94 -0
  338. package/dist/tui/tui.d.ts +69 -0
  339. package/dist/tui/tui.d.ts.map +1 -0
  340. package/dist/tui/tui.js +204 -0
  341. package/dist/tui/utils.d.ts +24 -0
  342. package/dist/tui/utils.d.ts.map +1 -0
  343. package/dist/tui/utils.js +111 -0
  344. package/dist/utils/bash.d.ts +7 -0
  345. package/dist/utils/bash.d.ts.map +1 -0
  346. package/dist/{tools/bash-utils.js → utils/bash.js} +31 -12
  347. package/dist/utils/{filesystem.d.ts → filesystem/operations.d.ts} +1 -1
  348. package/dist/utils/filesystem/operations.d.ts.map +1 -0
  349. package/dist/utils/filesystem/security.d.ts +9 -0
  350. package/dist/utils/filesystem/security.d.ts.map +1 -0
  351. package/dist/{tools/filesystem-utils.js → utils/filesystem/security.js} +93 -21
  352. package/dist/utils/funcs.d.ts +6 -0
  353. package/dist/utils/funcs.d.ts.map +1 -0
  354. package/dist/utils/funcs.js +6 -0
  355. package/dist/utils/generators.d.ts +3 -0
  356. package/dist/utils/generators.d.ts.map +1 -0
  357. package/dist/utils/generators.js +25 -0
  358. package/dist/{tools/git-utils.d.ts → utils/git.d.ts} +1 -1
  359. package/dist/utils/git.d.ts.map +1 -0
  360. package/dist/{tools/git-utils.js → utils/git.js} +0 -6
  361. package/dist/utils/glob.js +1 -1
  362. package/dist/utils/iterables.d.ts +2 -0
  363. package/dist/utils/iterables.d.ts.map +1 -0
  364. package/dist/utils/iterables.js +6 -0
  365. package/dist/utils/{zod-utils.d.ts → zod.d.ts} +1 -1
  366. package/dist/utils/zod.d.ts.map +1 -0
  367. package/package.json +21 -21
  368. package/dist/conversation-analyzer.d.ts +0 -11
  369. package/dist/conversation-analyzer.d.ts.map +0 -1
  370. package/dist/conversation-analyzer.js +0 -88
  371. package/dist/repl/display-tool-messages.d.ts +0 -4
  372. package/dist/repl/display-tool-messages.d.ts.map +0 -1
  373. package/dist/repl/display-tool-messages.js +0 -55
  374. package/dist/repl/display-tool-use.d.ts +0 -14
  375. package/dist/repl/display-tool-use.d.ts.map +0 -1
  376. package/dist/repl/display-tool-use.js +0 -63
  377. package/dist/repl/get-prompt-header.d.ts +0 -8
  378. package/dist/repl/get-prompt-header.d.ts.map +0 -1
  379. package/dist/repl/get-prompt-header.js +0 -38
  380. package/dist/repl-prompt.d.ts +0 -15
  381. package/dist/repl-prompt.d.ts.map +0 -1
  382. package/dist/repl-prompt.js +0 -147
  383. package/dist/repl.d.ts +0 -31
  384. package/dist/repl.d.ts.map +0 -1
  385. package/dist/repl.js +0 -310
  386. package/dist/terminal/checkbox-prompt.d.ts +0 -36
  387. package/dist/terminal/checkbox-prompt.d.ts.map +0 -1
  388. package/dist/terminal/checkbox-prompt.js +0 -362
  389. package/dist/terminal/editor-prompt.d.ts +0 -10
  390. package/dist/terminal/editor-prompt.d.ts.map +0 -1
  391. package/dist/terminal/editor-prompt.js +0 -61
  392. package/dist/terminal/errors.d.ts +0 -19
  393. package/dist/terminal/errors.d.ts.map +0 -1
  394. package/dist/terminal/errors.js +0 -37
  395. package/dist/terminal/input-prompt.d.ts +0 -16
  396. package/dist/terminal/input-prompt.d.ts.map +0 -1
  397. package/dist/terminal/input-prompt.js +0 -181
  398. package/dist/terminal/search-prompt.d.ts +0 -20
  399. package/dist/terminal/search-prompt.d.ts.map +0 -1
  400. package/dist/terminal/search-prompt.js +0 -279
  401. package/dist/terminal/types.d.ts +0 -35
  402. package/dist/terminal/types.d.ts.map +0 -1
  403. package/dist/terminal/types.js +0 -1
  404. package/dist/tokens/manage-output.d.ts +0 -34
  405. package/dist/tokens/manage-output.d.ts.map +0 -1
  406. package/dist/tokens/manage-output.js +0 -44
  407. package/dist/tool-executor.d.ts +0 -28
  408. package/dist/tool-executor.d.ts.map +0 -1
  409. package/dist/tool-executor.js +0 -74
  410. package/dist/tools/bash-utils.d.ts +0 -7
  411. package/dist/tools/bash-utils.d.ts.map +0 -1
  412. package/dist/tools/file-editing-utils.d.ts +0 -2
  413. package/dist/tools/file-editing-utils.d.ts.map +0 -1
  414. package/dist/tools/file-editing-utils.js +0 -135
  415. package/dist/tools/filesystem-utils.d.ts +0 -7
  416. package/dist/tools/filesystem-utils.d.ts.map +0 -1
  417. package/dist/tools/git-utils.d.ts.map +0 -1
  418. package/dist/utils/filesystem.d.ts.map +0 -1
  419. package/dist/utils/zod-utils.d.ts.map +0 -1
  420. /package/dist/utils/{filesystem.js → filesystem/operations.js} +0 -0
  421. /package/dist/utils/{zod-utils.js → zod.js} +0 -0
@@ -0,0 +1,466 @@
1
+ import { readdir, realpath, stat } from "node:fs/promises";
2
+ import { basename, dirname, extname, isAbsolute, join, relative, resolve, } from "node:path";
3
+ // Cache for directory listings to improve performance
4
+ class DirectoryCache {
5
+ cache = new Map();
6
+ ttl = 3000; // 3 seconds
7
+ async get(dir) {
8
+ const cached = this.cache.get(dir);
9
+ if (cached && Date.now() - cached.timestamp < this.ttl) {
10
+ return cached.entries;
11
+ }
12
+ return null;
13
+ }
14
+ set(dir, entries) {
15
+ this.cache.set(dir, { entries, timestamp: Date.now() });
16
+ }
17
+ clear() {
18
+ this.cache.clear();
19
+ }
20
+ }
21
+ const directoryCache = new DirectoryCache();
22
+ // Helper function to get directory entries with caching and timeout
23
+ async function getDirectoryEntries(dir) {
24
+ const cached = await directoryCache.get(dir);
25
+ if (cached) {
26
+ return cached;
27
+ }
28
+ try {
29
+ // Add timeout to prevent hanging on slow file systems
30
+ const entries = await Promise.race([
31
+ readdir(dir, { withFileTypes: true }),
32
+ new Promise((_, reject) => setTimeout(() => reject(new Error("Directory read timeout")), 2000)),
33
+ ]);
34
+ directoryCache.set(dir, entries);
35
+ return entries;
36
+ }
37
+ catch (_e) {
38
+ return [];
39
+ }
40
+ }
41
+ function isAttachableFile(filePath) {
42
+ // Check file extension for common text files that might be misidentified
43
+ const textExtensions = [
44
+ ".txt",
45
+ ".md",
46
+ ".markdown",
47
+ ".js",
48
+ ".ts",
49
+ ".tsx",
50
+ ".jsx",
51
+ ".py",
52
+ ".java",
53
+ ".c",
54
+ ".cpp",
55
+ ".h",
56
+ ".hpp",
57
+ ".cs",
58
+ ".php",
59
+ ".rb",
60
+ ".go",
61
+ ".rs",
62
+ ".swift",
63
+ ".kt",
64
+ ".scala",
65
+ ".sh",
66
+ ".bash",
67
+ ".zsh",
68
+ ".fish",
69
+ ".html",
70
+ ".htm",
71
+ ".css",
72
+ ".scss",
73
+ ".sass",
74
+ ".less",
75
+ ".xml",
76
+ ".json",
77
+ ".yaml",
78
+ ".yml",
79
+ ".toml",
80
+ ".ini",
81
+ ".cfg",
82
+ ".conf",
83
+ ".log",
84
+ ".sql",
85
+ ".r",
86
+ ".R",
87
+ ".m",
88
+ ".pl",
89
+ ".lua",
90
+ ".vim",
91
+ ".dockerfile",
92
+ ".makefile",
93
+ ".cmake",
94
+ ".gradle",
95
+ ".maven",
96
+ ".properties",
97
+ ".env",
98
+ ];
99
+ const ext = extname(filePath).toLowerCase();
100
+ return textExtensions.includes(ext);
101
+ }
102
+ // Combined provider that handles both slash commands and file paths
103
+ export class CombinedAutocompleteProvider {
104
+ commands;
105
+ allowedDirs;
106
+ constructor(commands = [], allowedDirs = [process.cwd()]) {
107
+ this.commands = commands;
108
+ this.allowedDirs = allowedDirs;
109
+ }
110
+ async getSuggestions(lines, cursorLine, cursorCol) {
111
+ const currentLine = lines[cursorLine] || "";
112
+ const textBeforeCursor = currentLine.slice(0, cursorCol);
113
+ // Check for slash commands
114
+ if (textBeforeCursor.startsWith("/")) {
115
+ const spaceIndex = textBeforeCursor.indexOf(" ");
116
+ if (spaceIndex === -1) {
117
+ // No space yet - complete command names
118
+ const prefix = textBeforeCursor.slice(1); // Remove the "/"
119
+ const filtered = this.commands
120
+ .filter((cmd) => {
121
+ const name = "name" in cmd ? cmd.name : cmd.value; // Check if SlashCommand or AutocompleteItem
122
+ return name?.toLowerCase().startsWith(prefix.toLowerCase());
123
+ })
124
+ .map((cmd) => ({
125
+ value: "name" in cmd ? cmd.name : cmd.value,
126
+ label: "name" in cmd ? cmd.name : cmd.label,
127
+ ...(cmd.description && { description: cmd.description }),
128
+ }));
129
+ if (filtered.length === 0)
130
+ return null;
131
+ return {
132
+ items: filtered,
133
+ prefix: prefix, // Return the actual prefix used for filtering (without "/")
134
+ };
135
+ }
136
+ // Space found - complete command arguments
137
+ const commandName = textBeforeCursor.slice(1, spaceIndex); // Command without "/"
138
+ const argumentText = textBeforeCursor.slice(spaceIndex + 1); // Text after space
139
+ const command = this.commands.find((cmd) => {
140
+ const name = "name" in cmd ? cmd.name : cmd.value;
141
+ return name === commandName;
142
+ });
143
+ if (!command ||
144
+ !("getArgumentCompletions" in command) ||
145
+ !command.getArgumentCompletions) {
146
+ return null; // No argument completion for this command
147
+ }
148
+ const argumentSuggestions = command.getArgumentCompletions?.(argumentText);
149
+ if (!argumentSuggestions || argumentSuggestions.length === 0) {
150
+ return null;
151
+ }
152
+ return {
153
+ items: argumentSuggestions,
154
+ prefix: argumentText,
155
+ };
156
+ }
157
+ // Check for file paths - triggered by Tab or if we detect a path pattern
158
+ const pathMatch = this.extractPathPrefix(textBeforeCursor, false);
159
+ if (pathMatch !== null) {
160
+ const suggestions = await this.getFileSuggestions(pathMatch);
161
+ if (suggestions.length === 0)
162
+ return null;
163
+ return {
164
+ items: suggestions,
165
+ prefix: pathMatch,
166
+ };
167
+ }
168
+ return null;
169
+ }
170
+ applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
171
+ const currentLine = lines[cursorLine] || "";
172
+ const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
173
+ const afterCursor = currentLine.slice(cursorCol);
174
+ const textBeforeCursor = currentLine.slice(0, cursorCol);
175
+ // Check if we're completing a slash command (prefix doesn't start with "/" but we're in slash command context)
176
+ if (textBeforeCursor.startsWith("/") && !textBeforeCursor.includes(" ")) {
177
+ // This is a command name completion
178
+ const newLine = `${beforePrefix}${item.value} ${afterCursor}`;
179
+ const newLines = [...lines];
180
+ newLines[cursorLine] = newLine;
181
+ return {
182
+ lines: newLines,
183
+ cursorLine,
184
+ cursorCol: beforePrefix.length + item.value.length + 1, // +1 for space
185
+ };
186
+ }
187
+ // Check if we're completing a file attachment (prefix starts with "@")
188
+ if (prefix.startsWith("@")) {
189
+ // This is a file attachment completion
190
+ const newLine = `${beforePrefix + item.value} ${afterCursor}`;
191
+ const newLines = [...lines];
192
+ newLines[cursorLine] = newLine;
193
+ return {
194
+ lines: newLines,
195
+ cursorLine,
196
+ cursorCol: beforePrefix.length + item.value.length + 1, // +1 for space
197
+ };
198
+ }
199
+ // Check if we're in a slash command context (beforePrefix contains "/command ")
200
+ if (textBeforeCursor.includes("/") && textBeforeCursor.includes(" ")) {
201
+ // This is likely a command argument completion
202
+ const newLine = beforePrefix + item.value + afterCursor;
203
+ const newLines = [...lines];
204
+ newLines[cursorLine] = newLine;
205
+ return {
206
+ lines: newLines,
207
+ cursorLine,
208
+ cursorCol: beforePrefix.length + item.value.length,
209
+ };
210
+ }
211
+ // For file paths, complete the path
212
+ const newLine = beforePrefix + item.value + afterCursor;
213
+ const newLines = [...lines];
214
+ newLines[cursorLine] = newLine;
215
+ return {
216
+ lines: newLines,
217
+ cursorLine,
218
+ cursorCol: beforePrefix.length + item.value.length,
219
+ };
220
+ }
221
+ // Extract a path-like prefix from the text before cursor
222
+ extractPathPrefix(text, forceExtract = false) {
223
+ // Check for @ file attachment syntax first
224
+ const atMatch = text.match(/@([^\s]*)$/);
225
+ if (atMatch) {
226
+ // For forced extraction, always return the @ prefix
227
+ if (forceExtract) {
228
+ return atMatch[0];
229
+ }
230
+ // For natural triggers, always return @ prefixes (they're always file-related)
231
+ return atMatch[0];
232
+ }
233
+ // Match paths - more conservative approach to avoid matching already completed paths
234
+ // This regex captures:
235
+ // - Paths starting from beginning of line or after space
236
+ // - Optional ./ or ../ or ~/ prefix
237
+ // - The path itself (must contain at least one / or start with ./ or ../ or ~/)
238
+ const matches = text.match(/(?:^|\s)((?:\.{1,2}\/|~\/)?(?:[^\s]*\/)*[^\s/]*)$/);
239
+ if (!matches) {
240
+ // If forced extraction and no matches, return empty string to trigger from current dir
241
+ return forceExtract ? "" : null;
242
+ }
243
+ const pathPrefix = matches[1] || "";
244
+ // For forced extraction (Tab key), always return something
245
+ if (forceExtract) {
246
+ // If we're not in a clear path context and we're at the end of a word,
247
+ // return empty string to complete from current directory
248
+ if (!pathPrefix.includes("/") &&
249
+ !pathPrefix.endsWith("/") &&
250
+ !pathPrefix.startsWith(".") &&
251
+ !pathPrefix.startsWith("~/")) {
252
+ // Only return empty string if we're at the beginning or after space
253
+ // This prevents completing "source" as empty string
254
+ if (text === "" || text.endsWith(" ")) {
255
+ return "";
256
+ }
257
+ }
258
+ return pathPrefix;
259
+ }
260
+ // For natural triggers, be more conservative:
261
+ // Only trigger if we have a clear path indicator
262
+ const hasPathIndicator = pathPrefix.includes("/") ||
263
+ pathPrefix.endsWith("/") ||
264
+ pathPrefix.startsWith(".") ||
265
+ pathPrefix.startsWith("~/");
266
+ if (!hasPathIndicator) {
267
+ return null;
268
+ }
269
+ // Additional check: don't trigger if the path looks like it's already completed
270
+ // (i.e., doesn't end with a partial filename)
271
+ // Only apply this check for paths that don't have clear path indicators
272
+ // and look like single directory names (no path separators)
273
+ if (!pathPrefix.includes("/") &&
274
+ !pathPrefix.includes(".") &&
275
+ !pathPrefix.startsWith("./") &&
276
+ !pathPrefix.startsWith("../") &&
277
+ !pathPrefix.startsWith("~/") &&
278
+ pathPrefix.length > 3) {
279
+ // This might be a completed directory name, not a partial path
280
+ return null;
281
+ }
282
+ return pathPrefix;
283
+ }
284
+ // Check if a path is within any allowed directory
285
+ async isPathWithinAllowedDirs(requestedPath) {
286
+ for (const allowedDir of this.allowedDirs) {
287
+ // Resolve both paths to handle relative paths and symlinks
288
+ const absRequested = resolve(requestedPath);
289
+ const absAllowed = resolve(allowedDir);
290
+ let target = absRequested;
291
+ try {
292
+ // Try to resolve symlinks for the target path
293
+ target = await realpath(absRequested);
294
+ }
295
+ catch {
296
+ // If target doesn't exist, use the intended path
297
+ }
298
+ const rel = relative(absAllowed, target);
299
+ if (rel === "" || (!rel.startsWith("..") && !isAbsolute(rel))) {
300
+ return true;
301
+ }
302
+ }
303
+ return false;
304
+ }
305
+ // Get file/directory suggestions for a given path prefix
306
+ async getFileSuggestions(prefix) {
307
+ try {
308
+ let searchDir;
309
+ let searchPrefix;
310
+ let expandedPrefix = prefix;
311
+ let isAtPrefix = false;
312
+ // Handle @ file attachment prefix
313
+ if (prefix.startsWith("@")) {
314
+ isAtPrefix = true;
315
+ expandedPrefix = prefix.slice(1); // Remove the @
316
+ }
317
+ // Remove home directory expansion - not allowed
318
+ if (expandedPrefix.startsWith("~")) {
319
+ // Home directory access not allowed - return empty suggestions
320
+ return [];
321
+ }
322
+ // Check if we're trying to access root - not allowed
323
+ if (expandedPrefix.startsWith("/")) {
324
+ // Root access not allowed - return empty suggestions
325
+ return [];
326
+ }
327
+ if (expandedPrefix === "" ||
328
+ expandedPrefix === "./" ||
329
+ expandedPrefix === "../" ||
330
+ prefix === "@") {
331
+ // Start from primary directory
332
+ searchDir = this.allowedDirs[0];
333
+ searchPrefix = "";
334
+ }
335
+ else if (expandedPrefix.endsWith("/")) {
336
+ // If prefix ends with /, show contents of that directory
337
+ // Try to find which allowed directory this path belongs to
338
+ const resolvedPath = join(this.allowedDirs[0], expandedPrefix);
339
+ const isWithinAllowed = await this.isPathWithinAllowedDirs(resolvedPath);
340
+ if (!isWithinAllowed) {
341
+ return [];
342
+ }
343
+ searchDir = resolvedPath;
344
+ searchPrefix = "";
345
+ }
346
+ else {
347
+ // Split into directory and file prefix
348
+ const dir = dirname(expandedPrefix);
349
+ const file = basename(expandedPrefix);
350
+ const resolvedPath = join(this.allowedDirs[0], dir);
351
+ // Check if the resolved path is within allowed directories
352
+ const isWithinAllowed = await this.isPathWithinAllowedDirs(resolvedPath);
353
+ if (!isWithinAllowed) {
354
+ return [];
355
+ }
356
+ searchDir = resolvedPath;
357
+ searchPrefix = file;
358
+ }
359
+ const entries = await getDirectoryEntries(searchDir);
360
+ const suggestions = [];
361
+ for (const entry of entries) {
362
+ const entryName = entry.name;
363
+ if (!entryName.toLowerCase().startsWith(searchPrefix.toLowerCase())) {
364
+ continue;
365
+ }
366
+ const fullPath = join(searchDir, entryName);
367
+ let isDirectory = false;
368
+ try {
369
+ // Add timeout to prevent hanging on slow file systems
370
+ const stats = await Promise.race([
371
+ stat(fullPath),
372
+ new Promise((_, reject) => setTimeout(() => reject(new Error("File stat timeout")), 1000)),
373
+ ]);
374
+ isDirectory = stats.isDirectory();
375
+ }
376
+ catch {
377
+ // If stat fails or times out, skip this entry
378
+ continue;
379
+ }
380
+ // For @ prefix, filter to only show directories and attachable files
381
+ if (isAtPrefix && !isDirectory && !isAttachableFile(fullPath)) {
382
+ continue;
383
+ }
384
+ // Check if the resulting path is within allowed directories
385
+ if (!(await this.isPathWithinAllowedDirs(fullPath))) {
386
+ continue;
387
+ }
388
+ let relativePath;
389
+ // Handle @ prefix path construction
390
+ if (isAtPrefix) {
391
+ const pathWithoutAt = expandedPrefix;
392
+ if (pathWithoutAt.endsWith("/")) {
393
+ relativePath = `@${pathWithoutAt}${entryName}`;
394
+ }
395
+ else if (pathWithoutAt.includes("/")) {
396
+ relativePath = `@${join(dirname(pathWithoutAt), entryName)}`;
397
+ }
398
+ else {
399
+ relativePath = `@${entryName}`;
400
+ }
401
+ }
402
+ else if (prefix.endsWith("/")) {
403
+ // If prefix ends with /, append entry to the prefix
404
+ relativePath = prefix + entryName;
405
+ }
406
+ else if (prefix.includes("/")) {
407
+ relativePath = join(dirname(prefix), entryName);
408
+ }
409
+ else {
410
+ relativePath = entryName;
411
+ }
412
+ suggestions.push({
413
+ value: isDirectory ? `${relativePath}/` : relativePath,
414
+ label: entryName,
415
+ description: isDirectory ? "directory" : "file",
416
+ });
417
+ }
418
+ // Sort directories first, then alphabetically
419
+ suggestions.sort((a, b) => {
420
+ const aIsDir = a.description === "directory";
421
+ const bIsDir = b.description === "directory";
422
+ if (aIsDir && !bIsDir)
423
+ return -1;
424
+ if (!aIsDir && bIsDir)
425
+ return 1;
426
+ return a.label.localeCompare(b.label);
427
+ });
428
+ return suggestions;
429
+ }
430
+ catch (_e) {
431
+ // Directory doesn't exist or not accessible
432
+ return [];
433
+ }
434
+ }
435
+ // Force file completion (called on Tab key) - always returns suggestions
436
+ async getForceFileSuggestions(lines, cursorLine, cursorCol) {
437
+ const currentLine = lines[cursorLine] || "";
438
+ const textBeforeCursor = currentLine.slice(0, cursorCol);
439
+ // Don't trigger if we're in a slash command
440
+ if (textBeforeCursor.startsWith("/") && !textBeforeCursor.includes(" ")) {
441
+ return null;
442
+ }
443
+ // Force extract path prefix - this will always return something
444
+ const pathMatch = this.extractPathPrefix(textBeforeCursor, true);
445
+ if (pathMatch !== null) {
446
+ const suggestions = await this.getFileSuggestions(pathMatch);
447
+ if (suggestions.length === 0)
448
+ return null;
449
+ return {
450
+ items: suggestions,
451
+ prefix: pathMatch,
452
+ };
453
+ }
454
+ return null;
455
+ }
456
+ // Check if we should trigger file completion (called on Tab key)
457
+ shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
458
+ const currentLine = lines[cursorLine] || "";
459
+ const textBeforeCursor = currentLine.slice(0, cursorCol);
460
+ // Don't trigger if we're in a slash command
461
+ if (textBeforeCursor.startsWith("/") && !textBeforeCursor.includes(" ")) {
462
+ return false;
463
+ }
464
+ return true;
465
+ }
466
+ }
@@ -0,0 +1,18 @@
1
+ import { Container } from "../tui.ts";
2
+ /**
3
+ * Component that renders a complete assistant message
4
+ */
5
+ export declare class AssistantMessageComponent extends Container {
6
+ private contentContainer;
7
+ constructor(message?: {
8
+ type: "message-start" | "message" | "message-end";
9
+ role: "assistant";
10
+ content: string;
11
+ });
12
+ updateContent(message: {
13
+ type: "message-start" | "message" | "message-end";
14
+ role: "assistant";
15
+ content: string;
16
+ }): void;
17
+ }
18
+ //# sourceMappingURL=assistant-message.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assistant-message.d.ts","sourceRoot":"","sources":["../../../source/tui/components/assistant-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,SAAS;IACtD,OAAO,CAAC,gBAAgB,CAAY;gBAExB,OAAO,CAAC,EAAE;QACpB,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,aAAa,CAAC;QAClD,IAAI,EAAE,WAAW,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB;IAYD,aAAa,CAAC,OAAO,EAAE;QACrB,IAAI,EAAE,eAAe,GAAG,SAAS,GAAG,aAAa,CAAC;QAClD,IAAI,EAAE,WAAW,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI;CAeT"}
@@ -0,0 +1,29 @@
1
+ import { Container } from "../tui.js";
2
+ import { Markdown } from "./markdown.js";
3
+ import { Spacer } from "./spacer.js";
4
+ /**
5
+ * Component that renders a complete assistant message
6
+ */
7
+ export class AssistantMessageComponent extends Container {
8
+ contentContainer;
9
+ constructor(message) {
10
+ super();
11
+ // Container for text/thinking content
12
+ this.contentContainer = new Container();
13
+ this.addChild(this.contentContainer);
14
+ if (message) {
15
+ this.updateContent(message);
16
+ }
17
+ }
18
+ updateContent(message) {
19
+ // Clear content container
20
+ this.contentContainer.clear();
21
+ if (message.content.length > 0) {
22
+ this.contentContainer.addChild(new Spacer(1));
23
+ }
24
+ const content = message.content;
25
+ // Assistant text messages with no background - trim the text
26
+ // Set paddingY=0 to avoid extra spacing before tool executions
27
+ this.contentContainer.addChild(new Markdown(content.trim(), { paddingX: 1, paddingY: 0 }));
28
+ }
29
+ }
@@ -0,0 +1,20 @@
1
+ import type { Component } from "../tui.ts";
2
+ /**
3
+ * Box component - displays content in a bordered box with header
4
+ */
5
+ export declare class BoxComponent implements Component {
6
+ private header;
7
+ private content;
8
+ private width;
9
+ private cachedOutput?;
10
+ private cachedHeader?;
11
+ private cachedContent?;
12
+ private cachedWidth?;
13
+ constructor(header: string, content: string, width?: number);
14
+ setHeader(header: string): void;
15
+ setContent(content: string): void;
16
+ setWidth(width: number): void;
17
+ private invalidateCache;
18
+ render(width: number): string[];
19
+ }
20
+ //# sourceMappingURL=box.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../../source/tui/components/box.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAS;IAGtB,OAAO,CAAC,YAAY,CAAC,CAAW;IAChC,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAC,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAC,CAAS;gBAEjB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAM3D,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAK/B,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAKjC,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAK7B,OAAO,CAAC,eAAe;IAOvB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAuDhC"}
@@ -0,0 +1,81 @@
1
+ import { getTerminalSize } from "../../terminal/control.js";
2
+ import { applyMarkdown } from "../../terminal/markdown.js";
3
+ import stripAnsi from "../../terminal/strip-ansi.js";
4
+ import wrapAnsi from "../../terminal/wrap-ansi.js";
5
+ /**
6
+ * Box component - displays content in a bordered box with header
7
+ */
8
+ export class BoxComponent {
9
+ header;
10
+ content;
11
+ width;
12
+ // Cache for rendered output
13
+ cachedOutput;
14
+ cachedHeader;
15
+ cachedContent;
16
+ cachedWidth;
17
+ constructor(header, content, width) {
18
+ this.header = header;
19
+ this.content = content;
20
+ this.width = width || 0;
21
+ }
22
+ setHeader(header) {
23
+ this.header = header;
24
+ this.invalidateCache();
25
+ }
26
+ setContent(content) {
27
+ this.content = content;
28
+ this.invalidateCache();
29
+ }
30
+ setWidth(width) {
31
+ this.width = width;
32
+ this.invalidateCache();
33
+ }
34
+ invalidateCache() {
35
+ this.cachedOutput = undefined;
36
+ this.cachedHeader = undefined;
37
+ this.cachedContent = undefined;
38
+ this.cachedWidth = undefined;
39
+ }
40
+ render(width) {
41
+ // Use provided width if specified, otherwise use component width or terminal size
42
+ let renderWidth = width || this.width;
43
+ if (renderWidth === 0) {
44
+ const { columns } = getTerminalSize();
45
+ const cols = columns > 0 ? columns : 80;
46
+ renderWidth = Math.max(4, cols - 4);
47
+ }
48
+ // Check cache
49
+ if (this.cachedOutput &&
50
+ this.cachedHeader === this.header &&
51
+ this.cachedContent === this.content &&
52
+ this.cachedWidth === renderWidth) {
53
+ return this.cachedOutput;
54
+ }
55
+ const paddedHeader = ` ${this.header} `;
56
+ const headerVisibleLen = stripAnsi(paddedHeader).length;
57
+ const headerStartPos = 1;
58
+ // Top border with header (use visible header length)
59
+ const leftDashes = headerStartPos;
60
+ const rightDashes = Math.max(0, renderWidth - leftDashes - headerVisibleLen);
61
+ const topBorder = `┌${"─".repeat(leftDashes)}${paddedHeader}${"─".repeat(rightDashes)}┐`;
62
+ // Prepare inner content: format markdown first, then wrap to inner width
63
+ const innerWidth = Math.max(1, renderWidth - 2);
64
+ const formatted = applyMarkdown(this.content);
65
+ const wrapped = wrapAnsi(formatted, innerWidth, { trim: false });
66
+ const contentLines = wrapped.split("\n").map((line) => {
67
+ const visibleLen = stripAnsi(line).length;
68
+ const padCount = Math.max(0, innerWidth - visibleLen);
69
+ return `│ ${line}${" ".repeat(padCount)} │`;
70
+ });
71
+ // Bottom border
72
+ const bottomBorder = `└${"─".repeat(renderWidth)}┘`;
73
+ const result = [topBorder, ...contentLines, bottomBorder];
74
+ // Update cache
75
+ this.cachedOutput = result;
76
+ this.cachedHeader = this.header;
77
+ this.cachedContent = this.content;
78
+ this.cachedWidth = renderWidth;
79
+ return result;
80
+ }
81
+ }