@travisennis/acai 0.0.9 → 0.0.11

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 (403) hide show
  1. package/README.md +51 -760
  2. package/bin/acai +52 -0
  3. package/dist/agent/index.d.ts +12 -2
  4. package/dist/agent/index.d.ts.map +1 -1
  5. package/dist/agent/index.js +380 -199
  6. package/dist/agent/sub-agent.d.ts +23 -0
  7. package/dist/agent/sub-agent.d.ts.map +1 -0
  8. package/dist/agent/sub-agent.js +109 -0
  9. package/dist/cli/index.d.ts +26 -0
  10. package/dist/cli/index.d.ts.map +1 -0
  11. package/dist/{cli.js → cli/index.js} +84 -77
  12. package/dist/{stdin.d.ts → cli/stdin.d.ts} +2 -1
  13. package/dist/cli/stdin.d.ts.map +1 -0
  14. package/dist/{stdin.js → cli/stdin.js} +11 -0
  15. package/dist/commands/copy/index.js +2 -2
  16. package/dist/commands/copy/utils.d.ts.map +1 -1
  17. package/dist/commands/copy/utils.js +15 -13
  18. package/dist/commands/generate-rules/index.d.ts +1 -1
  19. package/dist/commands/generate-rules/index.d.ts.map +1 -1
  20. package/dist/commands/generate-rules/index.js +16 -101
  21. package/dist/commands/generate-rules/service.d.ts +22 -0
  22. package/dist/commands/generate-rules/service.d.ts.map +1 -0
  23. package/dist/commands/generate-rules/service.js +103 -0
  24. package/dist/commands/handoff/index.js +2 -2
  25. package/dist/commands/health/index.js +1 -1
  26. package/dist/commands/health/utils.d.ts +3 -2
  27. package/dist/commands/health/utils.d.ts.map +1 -1
  28. package/dist/commands/health/utils.js +6 -0
  29. package/dist/commands/history/index.d.ts +1 -1
  30. package/dist/commands/history/index.d.ts.map +1 -1
  31. package/dist/commands/history/index.js +17 -18
  32. package/dist/commands/history/types.d.ts +38 -0
  33. package/dist/commands/history/types.d.ts.map +1 -1
  34. package/dist/commands/history/utils.d.ts.map +1 -1
  35. package/dist/commands/history/utils.js +63 -58
  36. package/dist/commands/init/index.d.ts.map +1 -1
  37. package/dist/commands/init/index.js +3 -8
  38. package/dist/commands/init-project/index.d.ts.map +1 -1
  39. package/dist/commands/init-project/index.js +3 -3
  40. package/dist/commands/init-project/utils.d.ts +2 -1
  41. package/dist/commands/init-project/utils.d.ts.map +1 -1
  42. package/dist/commands/init-project/utils.js +10 -2
  43. package/dist/commands/list-tools/index.d.ts.map +1 -1
  44. package/dist/commands/list-tools/index.js +7 -31
  45. package/dist/commands/manager.d.ts +2 -2
  46. package/dist/commands/manager.d.ts.map +1 -1
  47. package/dist/commands/manager.js +55 -33
  48. package/dist/commands/model/index.d.ts.map +1 -1
  49. package/dist/commands/model/index.js +20 -151
  50. package/dist/commands/model/model-panel.d.ts +4 -0
  51. package/dist/commands/model/model-panel.d.ts.map +1 -0
  52. package/dist/commands/model/model-panel.js +144 -0
  53. package/dist/commands/paste/index.d.ts.map +1 -1
  54. package/dist/commands/paste/index.js +59 -62
  55. package/dist/commands/paste/utils.d.ts.map +1 -1
  56. package/dist/commands/paste/utils.js +88 -58
  57. package/dist/commands/pickup/index.d.ts.map +1 -1
  58. package/dist/commands/pickup/index.js +6 -3
  59. package/dist/commands/pickup/utils.js +3 -3
  60. package/dist/commands/resources/index.d.ts.map +1 -1
  61. package/dist/commands/resources/index.js +33 -50
  62. package/dist/commands/review/index.d.ts.map +1 -1
  63. package/dist/commands/review/index.js +3 -117
  64. package/dist/commands/review/review-panel.d.ts +3 -0
  65. package/dist/commands/review/review-panel.d.ts.map +1 -0
  66. package/dist/commands/review/review-panel.js +186 -0
  67. package/dist/commands/review/utils.d.ts +15 -1
  68. package/dist/commands/review/utils.d.ts.map +1 -1
  69. package/dist/commands/review/utils.js +127 -68
  70. package/dist/commands/session/index.d.ts +1 -1
  71. package/dist/commands/session/index.d.ts.map +1 -1
  72. package/dist/commands/session/index.js +124 -135
  73. package/dist/commands/shell/index.d.ts.map +1 -1
  74. package/dist/commands/shell/index.js +16 -1
  75. package/dist/commands/types.d.ts +2 -2
  76. package/dist/commands/types.d.ts.map +1 -1
  77. package/dist/{config.d.ts → config/index.d.ts} +20 -9
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/{config.js → config/index.js} +43 -42
  80. package/dist/execution/index.d.ts.map +1 -1
  81. package/dist/execution/index.js +75 -55
  82. package/dist/index.d.ts +1 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +148 -141
  85. package/dist/middleware/cache.d.ts.map +1 -1
  86. package/dist/middleware/cache.js +18 -36
  87. package/dist/models/ai-config.d.ts +1 -0
  88. package/dist/models/ai-config.d.ts.map +1 -1
  89. package/dist/models/ai-config.js +4 -3
  90. package/dist/models/anthropic-provider.d.ts +2 -5
  91. package/dist/models/anthropic-provider.d.ts.map +1 -1
  92. package/dist/models/anthropic-provider.js +3 -70
  93. package/dist/models/deepseek-provider.d.ts +1 -0
  94. package/dist/models/deepseek-provider.d.ts.map +1 -1
  95. package/dist/models/google-provider.d.ts +2 -3
  96. package/dist/models/google-provider.d.ts.map +1 -1
  97. package/dist/models/google-provider.js +0 -26
  98. package/dist/models/groq-provider.d.ts +1 -0
  99. package/dist/models/groq-provider.d.ts.map +1 -1
  100. package/dist/models/manager.d.ts +13 -2
  101. package/dist/models/manager.d.ts.map +1 -1
  102. package/dist/models/manager.js +20 -8
  103. package/dist/models/openai-provider.d.ts +2 -5
  104. package/dist/models/openai-provider.d.ts.map +1 -1
  105. package/dist/models/openai-provider.js +0 -52
  106. package/dist/models/opencode-go-provider.d.ts +25 -0
  107. package/dist/models/opencode-go-provider.d.ts.map +1 -0
  108. package/dist/models/opencode-go-provider.js +78 -0
  109. package/dist/models/opencode-zen-provider.d.ts +7 -3
  110. package/dist/models/opencode-zen-provider.d.ts.map +1 -1
  111. package/dist/models/opencode-zen-provider.js +49 -10
  112. package/dist/models/openrouter-provider.d.ts +27 -31
  113. package/dist/models/openrouter-provider.d.ts.map +1 -1
  114. package/dist/models/openrouter-provider.js +121 -180
  115. package/dist/models/providers.d.ts +3 -3
  116. package/dist/models/providers.d.ts.map +1 -1
  117. package/dist/models/providers.js +6 -0
  118. package/dist/models/xai-provider.d.ts +4 -3
  119. package/dist/models/xai-provider.d.ts.map +1 -1
  120. package/dist/models/xai-provider.js +18 -18
  121. package/dist/modes/manager.d.ts +24 -0
  122. package/dist/modes/manager.d.ts.map +1 -0
  123. package/dist/modes/manager.js +77 -0
  124. package/dist/modes/prompts.d.ts +2 -0
  125. package/dist/modes/prompts.d.ts.map +1 -0
  126. package/dist/modes/prompts.js +142 -0
  127. package/dist/prompts/mentions.d.ts +11 -0
  128. package/dist/prompts/mentions.d.ts.map +1 -0
  129. package/dist/{mentions.js → prompts/mentions.js} +55 -85
  130. package/dist/{prompts.d.ts → prompts/system-prompt.d.ts} +7 -2
  131. package/dist/prompts/system-prompt.d.ts.map +1 -0
  132. package/dist/{prompts.js → prompts/system-prompt.js} +31 -16
  133. package/dist/repl/index.d.ts +174 -0
  134. package/dist/repl/index.d.ts.map +1 -0
  135. package/dist/{repl-new.js → repl/index.js} +397 -76
  136. package/dist/repl/project-status.d.ts +1 -0
  137. package/dist/repl/project-status.d.ts.map +1 -1
  138. package/dist/repl/project-status.js +4 -1
  139. package/dist/sessions/manager.d.ts +92 -0
  140. package/dist/sessions/manager.d.ts.map +1 -1
  141. package/dist/sessions/manager.js +262 -9
  142. package/dist/sessions/summary.d.ts +4 -0
  143. package/dist/sessions/summary.d.ts.map +1 -0
  144. package/dist/sessions/summary.js +30 -0
  145. package/dist/skills/index.d.ts +29 -0
  146. package/dist/skills/index.d.ts.map +1 -0
  147. package/dist/skills/index.js +294 -0
  148. package/dist/subagents/index.d.ts +16 -0
  149. package/dist/subagents/index.d.ts.map +1 -0
  150. package/dist/subagents/index.js +231 -0
  151. package/dist/terminal/control.d.ts +1 -1
  152. package/dist/terminal/control.d.ts.map +1 -1
  153. package/dist/terminal/control.js +3 -3
  154. package/dist/terminal/east-asian-width.d.ts.map +1 -1
  155. package/dist/terminal/east-asian-width.js +404 -351
  156. package/dist/terminal/keys.d.ts +17 -0
  157. package/dist/terminal/keys.d.ts.map +1 -1
  158. package/dist/terminal/keys.js +37 -0
  159. package/dist/terminal/select-prompt.d.ts.map +1 -1
  160. package/dist/terminal/select-prompt.js +24 -12
  161. package/dist/terminal/string-width.d.ts.map +1 -1
  162. package/dist/terminal/string-width.js +25 -27
  163. package/dist/terminal/style.d.ts.map +1 -1
  164. package/dist/terminal/style.js +4 -7
  165. package/dist/terminal/supports-color.d.ts.map +1 -1
  166. package/dist/terminal/supports-color.js +41 -27
  167. package/dist/terminal/table/cell.d.ts +12 -0
  168. package/dist/terminal/table/cell.d.ts.map +1 -1
  169. package/dist/terminal/table/cell.js +40 -25
  170. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  171. package/dist/terminal/table/layout-manager.js +100 -68
  172. package/dist/terminal/table/utils.d.ts +1 -1
  173. package/dist/terminal/table/utils.d.ts.map +1 -1
  174. package/dist/terminal/table/utils.js +17 -10
  175. package/dist/terminal/wrap-ansi.d.ts.map +1 -1
  176. package/dist/terminal/wrap-ansi.js +174 -105
  177. package/dist/tokens/tracker.d.ts +1 -0
  178. package/dist/tokens/tracker.d.ts.map +1 -1
  179. package/dist/tokens/tracker.js +3 -0
  180. package/dist/tools/agent.d.ts +27 -0
  181. package/dist/tools/agent.d.ts.map +1 -0
  182. package/dist/tools/agent.js +81 -0
  183. package/dist/tools/apply-patch.d.ts +62 -0
  184. package/dist/tools/apply-patch.d.ts.map +1 -0
  185. package/dist/tools/apply-patch.js +377 -0
  186. package/dist/tools/bash.d.ts +4 -3
  187. package/dist/tools/bash.d.ts.map +1 -1
  188. package/dist/tools/bash.js +349 -141
  189. package/dist/tools/directory-tree.d.ts +3 -3
  190. package/dist/tools/directory-tree.d.ts.map +1 -1
  191. package/dist/tools/directory-tree.js +8 -5
  192. package/dist/tools/dynamic-tool-loader.d.ts +3 -6
  193. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  194. package/dist/tools/dynamic-tool-loader.js +20 -4
  195. package/dist/tools/edit-file.d.ts +7 -7
  196. package/dist/tools/edit-file.d.ts.map +1 -1
  197. package/dist/tools/edit-file.js +292 -85
  198. package/dist/tools/glob.d.ts +6 -6
  199. package/dist/tools/glob.d.ts.map +1 -1
  200. package/dist/tools/glob.js +110 -63
  201. package/dist/tools/grep.d.ts +15 -12
  202. package/dist/tools/grep.d.ts.map +1 -1
  203. package/dist/tools/grep.js +315 -193
  204. package/dist/tools/index.d.ts +114 -9
  205. package/dist/tools/index.d.ts.map +1 -1
  206. package/dist/tools/index.js +39 -24
  207. package/dist/tools/ls.d.ts +2 -2
  208. package/dist/tools/ls.d.ts.map +1 -1
  209. package/dist/tools/ls.js +7 -5
  210. package/dist/tools/read-file.d.ts +4 -6
  211. package/dist/tools/read-file.d.ts.map +1 -1
  212. package/dist/tools/read-file.js +84 -39
  213. package/dist/tools/save-file.d.ts +3 -3
  214. package/dist/tools/save-file.d.ts.map +1 -1
  215. package/dist/tools/save-file.js +36 -31
  216. package/dist/tools/skill.d.ts +23 -0
  217. package/dist/tools/skill.d.ts.map +1 -0
  218. package/dist/tools/skill.js +65 -0
  219. package/dist/tools/think.d.ts.map +1 -1
  220. package/dist/tools/think.js +2 -9
  221. package/dist/tools/utils.d.ts +2 -0
  222. package/dist/tools/utils.d.ts.map +1 -1
  223. package/dist/tools/utils.js +12 -0
  224. package/dist/tools/web-fetch.d.ts +50 -0
  225. package/dist/tools/web-fetch.d.ts.map +1 -0
  226. package/dist/tools/web-fetch.js +446 -0
  227. package/dist/tools/web-search.d.ts +44 -0
  228. package/dist/tools/web-search.d.ts.map +1 -0
  229. package/dist/tools/web-search.js +226 -0
  230. package/dist/tui/autocomplete/attachment-provider.d.ts +3 -6
  231. package/dist/tui/autocomplete/attachment-provider.d.ts.map +1 -1
  232. package/dist/tui/autocomplete/attachment-provider.js +25 -78
  233. package/dist/tui/autocomplete/base-provider.d.ts +1 -0
  234. package/dist/tui/autocomplete/base-provider.d.ts.map +1 -1
  235. package/dist/tui/autocomplete/combined-provider.d.ts +1 -4
  236. package/dist/tui/autocomplete/combined-provider.d.ts.map +1 -1
  237. package/dist/tui/autocomplete/combined-provider.js +3 -17
  238. package/dist/tui/autocomplete/command-provider.d.ts +1 -0
  239. package/dist/tui/autocomplete/command-provider.d.ts.map +1 -1
  240. package/dist/tui/autocomplete/command-provider.js +3 -0
  241. package/dist/tui/autocomplete/file-search-provider.d.ts +2 -1
  242. package/dist/tui/autocomplete/file-search-provider.d.ts.map +1 -1
  243. package/dist/tui/autocomplete/file-search-provider.js +37 -17
  244. package/dist/tui/autocomplete/skill-provider.d.ts +17 -0
  245. package/dist/tui/autocomplete/skill-provider.d.ts.map +1 -0
  246. package/dist/tui/autocomplete/skill-provider.js +49 -0
  247. package/dist/tui/autocomplete/utils.d.ts +2 -1
  248. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  249. package/dist/tui/autocomplete/utils.js +25 -23
  250. package/dist/tui/autocomplete.d.ts +2 -2
  251. package/dist/tui/autocomplete.d.ts.map +1 -1
  252. package/dist/tui/autocomplete.js +3 -5
  253. package/dist/tui/components/assistant-message.d.ts.map +1 -1
  254. package/dist/tui/components/assistant-message.js +0 -4
  255. package/dist/tui/components/editor.d.ts +18 -3
  256. package/dist/tui/components/editor.d.ts.map +1 -1
  257. package/dist/tui/components/editor.js +211 -237
  258. package/dist/tui/components/footer.d.ts +6 -4
  259. package/dist/tui/components/footer.d.ts.map +1 -1
  260. package/dist/tui/components/footer.js +49 -25
  261. package/dist/tui/components/markdown.d.ts +10 -7
  262. package/dist/tui/components/markdown.d.ts.map +1 -1
  263. package/dist/tui/components/markdown.js +57 -39
  264. package/dist/tui/components/modal.d.ts.map +1 -1
  265. package/dist/tui/components/modal.js +35 -33
  266. package/dist/tui/components/notification.d.ts +13 -2
  267. package/dist/tui/components/notification.d.ts.map +1 -1
  268. package/dist/tui/components/notification.js +36 -2
  269. package/dist/tui/components/progress-bar.js +1 -1
  270. package/dist/tui/components/select-list.d.ts +1 -0
  271. package/dist/tui/components/select-list.d.ts.map +1 -1
  272. package/dist/tui/components/select-list.js +14 -11
  273. package/dist/tui/components/text.d.ts +16 -0
  274. package/dist/tui/components/text.d.ts.map +1 -1
  275. package/dist/tui/components/text.js +72 -57
  276. package/dist/tui/components/thinking-block.d.ts +9 -0
  277. package/dist/tui/components/thinking-block.d.ts.map +1 -1
  278. package/dist/tui/components/thinking-block.js +43 -11
  279. package/dist/tui/components/tool-execution.d.ts +5 -1
  280. package/dist/tui/components/tool-execution.d.ts.map +1 -1
  281. package/dist/tui/components/tool-execution.js +19 -10
  282. package/dist/tui/components/user-message.d.ts.map +1 -1
  283. package/dist/tui/components/user-message.js +0 -3
  284. package/dist/tui/components/welcome.d.ts +2 -1
  285. package/dist/tui/components/welcome.d.ts.map +1 -1
  286. package/dist/tui/components/welcome.js +2 -2
  287. package/dist/tui/editor-launcher.d.ts +3 -2
  288. package/dist/tui/editor-launcher.d.ts.map +1 -1
  289. package/dist/tui/index.d.ts +0 -1
  290. package/dist/tui/index.d.ts.map +1 -1
  291. package/dist/tui/terminal.d.ts.map +1 -1
  292. package/dist/tui/terminal.js +10 -2
  293. package/dist/tui/tui.d.ts +43 -0
  294. package/dist/tui/tui.d.ts.map +1 -1
  295. package/dist/tui/tui.js +166 -41
  296. package/dist/tui/utils.d.ts +1 -5
  297. package/dist/tui/utils.d.ts.map +1 -1
  298. package/dist/tui/utils.js +271 -44
  299. package/dist/utils/bash/parse.d.ts +19 -0
  300. package/dist/utils/bash/parse.d.ts.map +1 -0
  301. package/dist/utils/bash/parse.js +223 -0
  302. package/dist/utils/bash/quote.d.ts +6 -0
  303. package/dist/utils/bash/quote.d.ts.map +1 -0
  304. package/dist/utils/bash/quote.js +23 -0
  305. package/dist/utils/bash.d.ts.map +1 -1
  306. package/dist/utils/bash.js +211 -126
  307. package/dist/utils/command-protection.d.ts +28 -0
  308. package/dist/utils/command-protection.d.ts.map +1 -0
  309. package/dist/utils/command-protection.js +324 -0
  310. package/dist/utils/dedent.d.ts.map +1 -0
  311. package/dist/utils/env-expand.d.ts +2 -0
  312. package/dist/utils/env-expand.d.ts.map +1 -0
  313. package/dist/utils/env-expand.js +8 -0
  314. package/dist/utils/filesystem/path-display.d.ts +11 -0
  315. package/dist/utils/filesystem/path-display.d.ts.map +1 -0
  316. package/dist/utils/filesystem/path-display.js +32 -0
  317. package/dist/utils/filesystem/security.d.ts +2 -2
  318. package/dist/utils/filesystem/security.d.ts.map +1 -1
  319. package/dist/utils/filesystem/security.js +28 -30
  320. package/dist/utils/formatting.d.ts.map +1 -0
  321. package/dist/{formatting.js → utils/formatting.js} +1 -1
  322. package/dist/utils/git.d.ts +4 -0
  323. package/dist/utils/git.d.ts.map +1 -1
  324. package/dist/utils/git.js +30 -0
  325. package/dist/utils/glob.d.ts +1 -1
  326. package/dist/utils/glob.d.ts.map +1 -1
  327. package/dist/utils/logger.d.ts.map +1 -0
  328. package/dist/{logger.js → utils/logger.js} +1 -1
  329. package/dist/utils/parsing.d.ts.map +1 -0
  330. package/dist/utils/process.d.ts.map +1 -1
  331. package/dist/utils/process.js +90 -37
  332. package/dist/utils/templates.d.ts +2 -0
  333. package/dist/utils/templates.d.ts.map +1 -0
  334. package/dist/utils/templates.js +24 -0
  335. package/dist/utils/version.d.ts.map +1 -0
  336. package/dist/{version.js → utils/version.js} +1 -1
  337. package/package.json +35 -26
  338. package/dist/cli.d.ts +0 -23
  339. package/dist/cli.d.ts.map +0 -1
  340. package/dist/commands/add-directory/types.d.ts +0 -6
  341. package/dist/commands/add-directory/types.d.ts.map +0 -1
  342. package/dist/commands/add-directory/types.js +0 -1
  343. package/dist/commands/copy/types.d.ts +0 -3
  344. package/dist/commands/copy/types.d.ts.map +0 -1
  345. package/dist/commands/copy/types.js +0 -1
  346. package/dist/commands/exit/index.d.ts +0 -10
  347. package/dist/commands/exit/index.d.ts.map +0 -1
  348. package/dist/commands/exit/index.js +0 -21
  349. package/dist/commands/exit/types.d.ts +0 -8
  350. package/dist/commands/exit/types.d.ts.map +0 -1
  351. package/dist/commands/exit/types.js +0 -1
  352. package/dist/commands/exit/utils.d.ts +0 -2
  353. package/dist/commands/exit/utils.d.ts.map +0 -1
  354. package/dist/commands/exit/utils.js +0 -13
  355. package/dist/commands/prompt/index.d.ts +0 -5
  356. package/dist/commands/prompt/index.d.ts.map +0 -1
  357. package/dist/commands/prompt/index.js +0 -122
  358. package/dist/commands/prompt/types.d.ts +0 -15
  359. package/dist/commands/prompt/types.d.ts.map +0 -1
  360. package/dist/commands/prompt/types.js +0 -1
  361. package/dist/commands/prompt/utils.d.ts +0 -12
  362. package/dist/commands/prompt/utils.d.ts.map +0 -1
  363. package/dist/commands/prompt/utils.js +0 -107
  364. package/dist/commands/reset/index.d.ts +0 -3
  365. package/dist/commands/reset/index.d.ts.map +0 -1
  366. package/dist/commands/reset/index.js +0 -25
  367. package/dist/commands/reset/types.d.ts +0 -1
  368. package/dist/commands/reset/types.d.ts.map +0 -1
  369. package/dist/commands/reset/types.js +0 -3
  370. package/dist/commands/review/types.d.ts +0 -12
  371. package/dist/commands/review/types.d.ts.map +0 -1
  372. package/dist/commands/review/types.js +0 -1
  373. package/dist/commands/save/index.d.ts +0 -3
  374. package/dist/commands/save/index.d.ts.map +0 -1
  375. package/dist/commands/save/index.js +0 -19
  376. package/dist/config.d.ts.map +0 -1
  377. package/dist/dedent.d.ts.map +0 -1
  378. package/dist/formatting.d.ts.map +0 -1
  379. package/dist/logger.d.ts.map +0 -1
  380. package/dist/mentions.d.ts +0 -14
  381. package/dist/mentions.d.ts.map +0 -1
  382. package/dist/parsing.d.ts.map +0 -1
  383. package/dist/prompts.d.ts.map +0 -1
  384. package/dist/repl-new.d.ts +0 -65
  385. package/dist/repl-new.d.ts.map +0 -1
  386. package/dist/skills.d.ts +0 -16
  387. package/dist/skills.d.ts.map +0 -1
  388. package/dist/skills.js +0 -233
  389. package/dist/stdin.d.ts.map +0 -1
  390. package/dist/tui/autocomplete/path-provider.d.ts +0 -21
  391. package/dist/tui/autocomplete/path-provider.d.ts.map +0 -1
  392. package/dist/tui/autocomplete/path-provider.js +0 -164
  393. package/dist/utils/iterables.d.ts +0 -2
  394. package/dist/utils/iterables.d.ts.map +0 -1
  395. package/dist/utils/iterables.js +0 -6
  396. package/dist/version.d.ts.map +0 -1
  397. /package/dist/{dedent.d.ts → utils/dedent.d.ts} +0 -0
  398. /package/dist/{dedent.js → utils/dedent.js} +0 -0
  399. /package/dist/{formatting.d.ts → utils/formatting.d.ts} +0 -0
  400. /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
  401. /package/dist/{parsing.d.ts → utils/parsing.d.ts} +0 -0
  402. /package/dist/{parsing.js → utils/parsing.js} +0 -0
  403. /package/dist/{version.d.ts → utils/version.d.ts} +0 -0
@@ -0,0 +1,44 @@
1
+ import { z } from "zod";
2
+ import type { ToolExecutionOptions } from "./types.ts";
3
+ export declare const WebSearchTool: {
4
+ name: "WebSearch";
5
+ };
6
+ /**
7
+ * Input schema for the web search tool
8
+ */
9
+ declare const inputSchema: z.ZodObject<{
10
+ query: z.ZodString;
11
+ numResults: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
12
+ timeout: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
13
+ provider: z.ZodOptional<z.ZodEnum<{
14
+ exa: "exa";
15
+ duckduckgo: "duckduckgo";
16
+ }>>;
17
+ }, z.core.$strip>;
18
+ type WebSearchInputSchema = z.infer<typeof inputSchema>;
19
+ /**
20
+ * Execute web search
21
+ */
22
+ export declare function executeWebSearch(options: WebSearchInputSchema, executionOptions: ToolExecutionOptions): Promise<string>;
23
+ /**
24
+ * Create the web search tool
25
+ */
26
+ export declare const createWebSearchTool: () => Promise<{
27
+ toolDef: {
28
+ description: string;
29
+ inputSchema: z.ZodObject<{
30
+ query: z.ZodString;
31
+ numResults: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
32
+ timeout: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
33
+ provider: z.ZodOptional<z.ZodEnum<{
34
+ exa: "exa";
35
+ duckduckgo: "duckduckgo";
36
+ }>>;
37
+ }, z.core.$strip>;
38
+ };
39
+ display({ query }: WebSearchInputSchema): string;
40
+ execute(options: WebSearchInputSchema, executionOptions: ToolExecutionOptions): Promise<string>;
41
+ }>;
42
+ export type WebSearchTool = Awaited<ReturnType<typeof createWebSearchTool>>;
43
+ export {};
44
+ //# sourceMappingURL=web-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../source/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,aAAa;;CAEzB,CAAC;AAQF;;GAEG;AACH,QAAA,MAAM,WAAW;;;;;;;;iBAkBf,CAAC;AAEH,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AA+MxD;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAwEjB;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;uBAQT,oBAAoB;qBAI5B,oBAAoB,oBACX,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC;EAIrB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,226 @@
1
+ import { z } from "zod";
2
+ import style from "../terminal/style.js";
3
+ export const WebSearchTool = {
4
+ name: "WebSearch",
5
+ };
6
+ // Default search options
7
+ const DEFAULT_NUM_RESULTS = 10;
8
+ const DEFAULT_TIMEOUT = 30000; // 30 seconds
9
+ const EXA_API_BASE = "https://api.exa.ai";
10
+ const EXA_API_VERSION = "2024-05-22";
11
+ /**
12
+ * Input schema for the web search tool
13
+ */
14
+ const inputSchema = z.object({
15
+ query: z.string().describe("The search query to execute"),
16
+ numResults: z
17
+ .preprocess((val) => convertNullString(val), z.coerce.number().nullable())
18
+ .optional()
19
+ .describe(`Number of search results to return (default: ${DEFAULT_NUM_RESULTS}, max: 100)`),
20
+ timeout: z
21
+ .preprocess((val) => convertNullString(val), z.coerce.number().nullable())
22
+ .optional()
23
+ .describe(`Timeout in milliseconds for the search request (default: ${DEFAULT_TIMEOUT}ms)`),
24
+ provider: z
25
+ .enum(["exa", "duckduckgo"])
26
+ .optional()
27
+ .describe("Search provider to use (default: exa with duckduckgo fallback)"),
28
+ });
29
+ /**
30
+ * Convert null/undefined to string for preprocessing
31
+ */
32
+ function convertNullString(val) {
33
+ if (val === null ||
34
+ val === undefined ||
35
+ val === "null" ||
36
+ val === "undefined") {
37
+ return null;
38
+ }
39
+ return String(val);
40
+ }
41
+ /**
42
+ * Factory function for creating abort handlers.
43
+ * Defined at module level to avoid capturing closure scope.
44
+ */
45
+ function createAbortHandler(ctrl, signal) {
46
+ return () => {
47
+ ctrl.abort(signal?.reason ?? new Error("Aborted"));
48
+ };
49
+ }
50
+ /**
51
+ * Create an AbortSignal that combines a timeout with an optional parent signal
52
+ */
53
+ function createTimeoutSignal(timeoutMs, parentSignal) {
54
+ const controller = new AbortController();
55
+ // Use bind() to avoid capturing scope in timeout callback
56
+ const abort = controller.abort.bind(controller);
57
+ const timeoutId = setTimeout(() => abort(new Error(`Request timed out after ${timeoutMs}ms`)), timeoutMs);
58
+ // Create abort handler using factory to avoid capturing scope
59
+ const abortHandler = createAbortHandler(controller, parentSignal);
60
+ if (parentSignal) {
61
+ if (parentSignal.aborted) {
62
+ abortHandler();
63
+ }
64
+ else {
65
+ parentSignal.addEventListener("abort", abortHandler, { once: true });
66
+ }
67
+ }
68
+ return {
69
+ signal: controller.signal,
70
+ cleanup: () => {
71
+ clearTimeout(timeoutId);
72
+ if (parentSignal) {
73
+ parentSignal.removeEventListener("abort", abortHandler);
74
+ }
75
+ },
76
+ };
77
+ }
78
+ /**
79
+ * Fetch from Exa API
80
+ */
81
+ async function fetchExa(query, numResults, signal) {
82
+ const apiKey = process.env["EXA_API_KEY"];
83
+ if (!apiKey) {
84
+ throw new Error("EXA_API_KEY environment variable is not set. Please set it to use Exa API.");
85
+ }
86
+ const response = await fetch(`${EXA_API_BASE}/search`, {
87
+ method: "POST",
88
+ headers: {
89
+ "Content-Type": "application/json",
90
+ "x-api-key": apiKey,
91
+ "exa-version": EXA_API_VERSION,
92
+ },
93
+ body: JSON.stringify({
94
+ query,
95
+ numResults,
96
+ }),
97
+ signal,
98
+ });
99
+ if (!response.ok) {
100
+ const errorText = await response.text();
101
+ throw new Error(`Exa API error: ${response.status} - ${errorText}`);
102
+ }
103
+ const data = await response.json();
104
+ return {
105
+ results: data.results.map((result) => ({
106
+ title: result.title,
107
+ url: result.url,
108
+ snippet: result.body,
109
+ publishedDate: result.publishedDate,
110
+ })),
111
+ provider: "exa",
112
+ query,
113
+ totalResults: data.results.length,
114
+ };
115
+ }
116
+ /**
117
+ * Fetch from DuckDuckGo API (using their instant answer API)
118
+ */
119
+ async function fetchDuckDuckGo(query, numResults, signal) {
120
+ const encodedQuery = encodeURIComponent(query);
121
+ const response = await fetch(`https://api.duckduckgo.com/?q=${encodedQuery}&format=json&no_html=1&skip_disambig=1`, { signal });
122
+ if (!response.ok) {
123
+ throw new Error(`DuckDuckGo API error: ${response.status} - ${response.statusText}`);
124
+ }
125
+ const data = await response.json();
126
+ if (!data.RelatedTopics || data.RelatedTopics.length === 0) {
127
+ return {
128
+ results: [],
129
+ provider: "duckduckgo",
130
+ query,
131
+ };
132
+ }
133
+ const results = data.RelatedTopics.slice(0, numResults)
134
+ // biome-ignore lint/style/useNamingConvention: DuckDuckGo API response uses PascalCase
135
+ .filter((topic) => topic.Result)
136
+ .map((topic) => {
137
+ // Parse the result format: "<a>Title</a> - Description"
138
+ const resultHtml = topic.Result || "";
139
+ const titleMatch = resultHtml.match(/>([^<]+)</);
140
+ const title = titleMatch ? titleMatch[1] : "No title";
141
+ return {
142
+ title,
143
+ url: topic.FirstURL || "",
144
+ snippet: topic.Text || "",
145
+ };
146
+ });
147
+ return {
148
+ results,
149
+ provider: "duckduckgo",
150
+ query,
151
+ totalResults: data.RelatedTopics.length,
152
+ };
153
+ }
154
+ /**
155
+ * Execute web search
156
+ */
157
+ export async function executeWebSearch(options, executionOptions) {
158
+ const { query, numResults = DEFAULT_NUM_RESULTS, timeout = DEFAULT_TIMEOUT, provider = "exa", } = options;
159
+ if (executionOptions.abortSignal?.aborted) {
160
+ throw new Error("Web search aborted");
161
+ }
162
+ if (!query || query.trim().length === 0) {
163
+ throw new Error("Search query cannot be empty");
164
+ }
165
+ const effectiveNumResults = Math.min(Math.max(numResults ?? 1, 1), 100);
166
+ const effectiveTimeout = Math.min(Math.max(timeout ?? 1000, 1000), 60000);
167
+ const { signal, cleanup } = createTimeoutSignal(effectiveTimeout, executionOptions.abortSignal);
168
+ try {
169
+ let response;
170
+ if (provider === "duckduckgo") {
171
+ response = await fetchDuckDuckGo(query, effectiveNumResults, signal);
172
+ }
173
+ else {
174
+ // Try Exa first, fall back to DuckDuckGo
175
+ try {
176
+ response = await fetchExa(query, effectiveNumResults, signal);
177
+ }
178
+ catch (exaError) {
179
+ // Fall back to DuckDuckGo if Exa fails (but not if aborted)
180
+ if (signal.aborted) {
181
+ throw exaError;
182
+ }
183
+ // Provide more helpful error message about Exa failure
184
+ const errorMsg = exaError instanceof Error ? exaError.message : String(exaError);
185
+ if (errorMsg.includes("fetch failed") ||
186
+ errorMsg.includes("ENOTFOUND") ||
187
+ errorMsg.includes("connect")) {
188
+ throw new Error(`Exa API is not accessible (network error). Try using provider="duckduckgo" instead.`);
189
+ }
190
+ response = await fetchDuckDuckGo(query, effectiveNumResults, signal);
191
+ }
192
+ }
193
+ if (response.results.length === 0) {
194
+ return `No search results found for "${query}".`;
195
+ }
196
+ const resultsText = response.results
197
+ .map((result, index) => `${index + 1}. [${result.title}](${result.url})\n ${result.snippet.substring(0, 200)}${result.snippet.length > 200 ? "..." : ""}`)
198
+ .join("\n\n");
199
+ return `Search results for "${query}" (${response.provider}):\n\n${resultsText}\n\nTotal results: ${response.totalResults || response.results.length}`;
200
+ }
201
+ catch (error) {
202
+ const errorMessage = error instanceof Error ? error.message : String(error);
203
+ throw new Error(`Web search failed: ${errorMessage}`);
204
+ }
205
+ finally {
206
+ cleanup();
207
+ }
208
+ }
209
+ /**
210
+ * Create the web search tool
211
+ */
212
+ export const createWebSearchTool = async () => {
213
+ const toolDescription = "Search the web for information.";
214
+ return {
215
+ toolDef: {
216
+ description: toolDescription,
217
+ inputSchema,
218
+ },
219
+ display({ query }) {
220
+ return `🔍 ${style.cyan(query)}`;
221
+ },
222
+ async execute(options, executionOptions) {
223
+ return executeWebSearch(options, executionOptions);
224
+ },
225
+ };
226
+ };
@@ -1,6 +1,7 @@
1
1
  import type { AutocompleteItem } from "./base-provider.ts";
2
- import { PathProvider } from "./path-provider.ts";
3
- export declare class AttachmentProvider extends PathProvider {
2
+ import { FileSearchProvider } from "./file-search-provider.ts";
3
+ export declare class AttachmentProvider extends FileSearchProvider {
4
+ matchesContext(textBeforeCursor: string): boolean;
4
5
  getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
5
6
  items: AutocompleteItem[];
6
7
  prefix: string;
@@ -10,9 +11,5 @@ export declare class AttachmentProvider extends PathProvider {
10
11
  cursorLine: number;
11
12
  cursorCol: number;
12
13
  };
13
- getForceFileSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
14
- items: AutocompleteItem[];
15
- prefix: string;
16
- } | null>;
17
14
  }
18
15
  //# sourceMappingURL=attachment-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/attachment-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,qBAAa,kBAAmB,SAAQ,YAAY;IACnC,cAAc,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAyCvD,eAAe,CACtB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAwB9C,uBAAuB,CACpC,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CA0CjE"}
1
+ {"version":3,"file":"attachment-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/attachment-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,qBAAa,kBAAmB,SAAQ,kBAAkB;IAC/C,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO;IAI3C,cAAc,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA8BvD,eAAe,CACtB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAmB9D"}
@@ -1,103 +1,50 @@
1
1
  import { extname } from "node:path";
2
- import { PathProvider } from "./path-provider.js";
3
- export class AttachmentProvider extends PathProvider {
2
+ import { FileSearchProvider } from "./file-search-provider.js";
3
+ export class AttachmentProvider extends FileSearchProvider {
4
+ matchesContext(textBeforeCursor) {
5
+ return /(?:^|\s)#[^\s]*$/.test(textBeforeCursor);
6
+ }
4
7
  async getSuggestions(lines, cursorLine, cursorCol) {
5
8
  const currentLine = lines[cursorLine] || "";
6
9
  const textBeforeCursor = currentLine.slice(0, cursorCol);
7
- // Only handle @ file attachments
8
- const pathMatch = textBeforeCursor.match(/@([^\s]*)$/);
10
+ const pathMatch = textBeforeCursor.match(/#([^\s]*)$/);
9
11
  if (!pathMatch) {
10
12
  return null;
11
13
  }
12
- let prefix = pathMatch[0]; // Includes the @
13
- // Handle @ file attachment prefix
14
- if (prefix.startsWith("@")) {
15
- prefix = prefix.slice(1); // Remove the @
16
- }
17
- else {
18
- return null;
19
- }
20
- const suggestions = await this.getFileSuggestions(prefix);
14
+ const prefix = pathMatch[0];
15
+ const searchTerm = pathMatch[1];
16
+ const suggestions = await this.searchFiles(searchTerm);
21
17
  if (suggestions.length === 0)
22
18
  return null;
23
- // For @ prefix, filter to only show directories and attachable files
24
- const filteredSuggestions = [];
25
- for (const suggestion of suggestions) {
26
- if (!suggestion.value.endsWith("/") &&
27
- !isAttachableFile(suggestion.value)) {
28
- continue;
29
- }
30
- suggestion.value = `@${suggestion.value}`;
31
- filteredSuggestions.push(suggestion);
32
- }
19
+ const filteredSuggestions = suggestions.filter((s) => isAttachableFile(s.value));
33
20
  if (filteredSuggestions.length === 0)
34
21
  return null;
22
+ for (const suggestion of filteredSuggestions) {
23
+ suggestion.value = `#${suggestion.value}`;
24
+ }
35
25
  return {
36
26
  items: filteredSuggestions,
37
- prefix: pathMatch[0],
27
+ prefix,
38
28
  };
39
29
  }
40
30
  applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
31
+ if (!prefix.startsWith("#")) {
32
+ return { lines, cursorLine, cursorCol };
33
+ }
41
34
  const currentLine = lines[cursorLine] || "";
42
35
  const beforePrefix = currentLine.slice(0, cursorCol - prefix.length);
43
36
  const afterCursor = currentLine.slice(cursorCol);
44
- // Only handle @ file attachment completion if prefix starts with "@"
45
- if (prefix.startsWith("@")) {
46
- // Handle @ file attachment completion
47
- const newLine = `${beforePrefix + item.value} ${afterCursor}`;
48
- const newLines = [...lines];
49
- newLines[cursorLine] = newLine;
50
- return {
51
- lines: newLines,
52
- cursorLine,
53
- cursorCol: beforePrefix.length + item.value.length + 1, // +1 for space
54
- };
55
- }
56
- // If not an @ attachment, let other providers handle it
57
- return { lines, cursorLine, cursorCol };
58
- }
59
- // Force file completion (called on Tab key) - always returns suggestions
60
- async getForceFileSuggestions(lines, cursorLine, cursorCol) {
61
- const currentLine = lines[cursorLine] || "";
62
- const textBeforeCursor = currentLine.slice(0, cursorCol);
63
- // Check for @ file attachment syntax first
64
- const atMatch = textBeforeCursor.match(/@([^\s]*)$/);
65
- const pathMatch = atMatch ? atMatch[0] : null;
66
- console.log("pathMatch", textBeforeCursor, pathMatch);
67
- if (pathMatch !== null) {
68
- let prefix = pathMatch; // Includes the @
69
- // Handle @ file attachment prefix
70
- if (prefix.startsWith("@")) {
71
- prefix = prefix.slice(1); // Remove the @
72
- }
73
- else {
74
- return null;
75
- }
76
- const suggestions = await this.getFileSuggestions(prefix);
77
- if (suggestions.length === 0)
78
- return null;
79
- // For @ prefix, filter to only show directories and attachable files
80
- const filteredSuggestions = [];
81
- for (const suggestion of suggestions) {
82
- if (!suggestion.value.endsWith("/") &&
83
- !isAttachableFile(suggestion.value)) {
84
- continue;
85
- }
86
- suggestion.value = `@${suggestion.value}`;
87
- filteredSuggestions.push(suggestion);
88
- }
89
- if (filteredSuggestions.length === 0)
90
- return null;
91
- return {
92
- items: suggestions,
93
- prefix: pathMatch,
94
- };
95
- }
96
- return null;
37
+ const newLine = `${beforePrefix + item.value} ${afterCursor}`;
38
+ const newLines = [...lines];
39
+ newLines[cursorLine] = newLine;
40
+ return {
41
+ lines: newLines,
42
+ cursorLine,
43
+ cursorCol: beforePrefix.length + item.value.length + 1,
44
+ };
97
45
  }
98
46
  }
99
47
  function isAttachableFile(filePath) {
100
- // Check file extension for common text files that might be misidentified
101
48
  const textExtensions = [
102
49
  ".txt",
103
50
  ".md",
@@ -4,6 +4,7 @@ export interface AutocompleteItem {
4
4
  description?: string;
5
5
  }
6
6
  export interface AutocompleteProvider {
7
+ matchesContext(textBeforeCursor: string): boolean;
7
8
  getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
8
9
  items: AutocompleteItem[];
9
10
  prefix: string;
@@ -1 +1 @@
1
- {"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/base-provider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IAGnC,cAAc,CACZ,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAIjE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D"}
1
+ {"version":3,"file":"base-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/base-provider.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IAGnC,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC;IAIlD,cAAc,CACZ,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAIjE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D"}
@@ -2,6 +2,7 @@ import type { AutocompleteItem, AutocompleteProvider } from "./base-provider.ts"
2
2
  export declare class CombinedProvider implements AutocompleteProvider {
3
3
  private providers;
4
4
  constructor(providers: AutocompleteProvider[]);
5
+ matchesContext(textBeforeCursor: string): boolean;
5
6
  getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
6
7
  items: AutocompleteItem[];
7
8
  prefix: string;
@@ -11,10 +12,6 @@ export declare class CombinedProvider implements AutocompleteProvider {
11
12
  cursorLine: number;
12
13
  cursorCol: number;
13
14
  };
14
- getForceFileSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
15
- items: AutocompleteItem[];
16
- prefix: string;
17
- } | null>;
18
15
  shouldTriggerFileCompletion(lines: string[], cursorLine: number, cursorCol: number): boolean;
19
16
  }
20
17
  //# sourceMappingURL=combined-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"combined-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/combined-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,gBAAiB,YAAW,oBAAoB;IAC3D,OAAO,CAAC,SAAS,CAAyB;gBAE9B,SAAS,EAAE,oBAAoB,EAAE;IAIvC,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAehE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAwBvD,uBAAuB,CAC3B,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAwBhE,2BAA2B,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO;CAmBX"}
1
+ {"version":3,"file":"combined-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/combined-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,qBAAa,gBAAiB,YAAW,oBAAoB;IAC3D,OAAO,CAAC,SAAS,CAAyB;gBAE9B,SAAS,EAAE,oBAAoB,EAAE;IAI7C,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO;IAI3C,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAehE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAwB7D,2BAA2B,CACzB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO;CAmBX"}
@@ -3,6 +3,9 @@ export class CombinedProvider {
3
3
  constructor(providers) {
4
4
  this.providers = providers;
5
5
  }
6
+ matchesContext(textBeforeCursor) {
7
+ return this.providers.some((p) => p.matchesContext(textBeforeCursor));
8
+ }
6
9
  async getSuggestions(lines, cursorLine, cursorCol) {
7
10
  // Try each provider in order until we get suggestions
8
11
  for (const provider of this.providers) {
@@ -27,23 +30,6 @@ export class CombinedProvider {
27
30
  // If no provider handled it, return unchanged
28
31
  return { lines, cursorLine, cursorCol };
29
32
  }
30
- // Force file completion (called on Tab key) - always returns suggestions
31
- async getForceFileSuggestions(lines, cursorLine, cursorCol) {
32
- if (!this.shouldTriggerFileCompletion(lines, cursorLine, cursorCol)) {
33
- return null;
34
- }
35
- // Try each provider that has getForceFileSuggestions method
36
- for (const provider of this.providers) {
37
- if ("getForceFileSuggestions" in provider &&
38
- typeof provider.getForceFileSuggestions === "function") {
39
- const result = await provider.getForceFileSuggestions(lines, cursorLine, cursorCol);
40
- if (result) {
41
- return result;
42
- }
43
- }
44
- }
45
- return null;
46
- }
47
33
  // Check if we should trigger file completion (called on Tab key)
48
34
  shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
49
35
  // Try each provider that has shouldTriggerFileCompletion method
@@ -7,6 +7,7 @@ export interface SlashCommand {
7
7
  export declare class CommandProvider<T extends SlashCommand | AutocompleteItem> implements AutocompleteProvider {
8
8
  private commands;
9
9
  constructor(commands?: T[]);
10
+ matchesContext(textBeforeCursor: string): boolean;
10
11
  getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
11
12
  items: AutocompleteItem[];
12
13
  prefix: string;
@@ -1 +1 @@
1
- {"version":3,"file":"command-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/command-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,sBAAsB,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;CAC5E;AAED,qBAAa,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,gBAAgB,CACpE,YAAW,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAM;gBAEV,QAAQ,GAAE,CAAC,EAAO;IAIxB,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA8DhE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAwC9D"}
1
+ {"version":3,"file":"command-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/command-provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IAGrB,sBAAsB,CAAC,CAAC,cAAc,EAAE,MAAM,GAAG,gBAAgB,EAAE,GAAG,IAAI,CAAC;CAC5E;AAED,qBAAa,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,gBAAgB,CACpE,YAAW,oBAAoB;IAE/B,OAAO,CAAC,QAAQ,CAAM;gBAEV,QAAQ,GAAE,CAAC,EAAO;IAI9B,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO;IAI3C,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IA8DhE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;CAwC9D"}
@@ -3,6 +3,9 @@ export class CommandProvider {
3
3
  constructor(commands = []) {
4
4
  this.commands = commands;
5
5
  }
6
+ matchesContext(textBeforeCursor) {
7
+ return textBeforeCursor.trimStart().startsWith("/");
8
+ }
6
9
  async getSuggestions(lines, cursorLine, cursorCol) {
7
10
  const currentLine = lines[cursorLine] || "";
8
11
  const textBeforeCursor = currentLine.slice(0, cursorCol);
@@ -2,6 +2,7 @@ import type { AutocompleteItem, AutocompleteProvider } from "./base-provider.ts"
2
2
  export declare class FileSearchProvider implements AutocompleteProvider {
3
3
  private maxResults;
4
4
  private maxDepth;
5
+ matchesContext(textBeforeCursor: string): boolean;
5
6
  getSuggestions(lines: string[], cursorLine: number, cursorCol: number): Promise<{
6
7
  items: AutocompleteItem[];
7
8
  prefix: string;
@@ -11,6 +12,6 @@ export declare class FileSearchProvider implements AutocompleteProvider {
11
12
  cursorLine: number;
12
13
  cursorCol: number;
13
14
  };
14
- private searchFiles;
15
+ protected searchFiles(searchTerm: string): Promise<AutocompleteItem[]>;
15
16
  }
16
17
  //# sourceMappingURL=file-search-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"file-search-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/file-search-provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AA+B5B,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,QAAQ,CAAK;IAEf,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAuBhE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;YAqB/C,WAAW;CA+D1B"}
1
+ {"version":3,"file":"file-search-provider.d.ts","sourceRoot":"","sources":["../../../source/tui/autocomplete/file-search-provider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAChB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AA2C5B,qBAAa,kBAAmB,YAAW,oBAAoB;IAC7D,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,QAAQ,CAAK;IAErB,cAAc,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO;IAI3C,cAAc,CAClB,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAuBhE,eAAe,CACb,KAAK,EAAE,MAAM,EAAE,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,MAAM,GACb;QAAE,KAAK,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;cAqB7C,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAoE7E"}
@@ -30,13 +30,27 @@ async function loadGitignorePatterns(cwd) {
30
30
  return [];
31
31
  }
32
32
  }
33
+ function fuzzyScore(filename, searchTerm) {
34
+ const lower = filename.toLowerCase();
35
+ if (lower.startsWith(searchTerm))
36
+ return 0;
37
+ const nameWithoutExt = lower.replace(/\.[^.]+$/, "");
38
+ if (nameWithoutExt.startsWith(searchTerm))
39
+ return 1;
40
+ if (lower.includes(searchTerm))
41
+ return 2;
42
+ return 3;
43
+ }
33
44
  export class FileSearchProvider {
34
45
  maxResults = 20;
35
- maxDepth = 3;
46
+ maxDepth = 8;
47
+ matchesContext(textBeforeCursor) {
48
+ return /(?:^|\s)@[^\s]*$/.test(textBeforeCursor);
49
+ }
36
50
  async getSuggestions(lines, cursorLine, cursorCol) {
37
51
  const currentLine = lines[cursorLine] || "";
38
52
  const textBeforeCursor = currentLine.slice(0, cursorCol);
39
- const pathMatch = textBeforeCursor.match(/#([^\s]*)$/);
53
+ const pathMatch = textBeforeCursor.match(/(?<!@)@([^\s]*)$/);
40
54
  if (!pathMatch) {
41
55
  return null;
42
56
  }
@@ -52,8 +66,8 @@ export class FileSearchProvider {
52
66
  };
53
67
  }
54
68
  applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
55
- // Only handle completions that start with #
56
- if (!prefix.startsWith("#")) {
69
+ // Only handle completions that start with @
70
+ if (!prefix.startsWith("@")) {
57
71
  return { lines, cursorLine, cursorCol };
58
72
  }
59
73
  const currentLine = lines[cursorLine] || "";
@@ -71,7 +85,6 @@ export class FileSearchProvider {
71
85
  async searchFiles(searchTerm) {
72
86
  const results = [];
73
87
  const cwd = process.cwd();
74
- // Build ignore instance with .gitignore patterns + defaults
75
88
  const ig = ignore().add(defaultIgnoredPatterns);
76
89
  const gitignorePatterns = await loadGitignorePatterns(cwd);
77
90
  if (gitignorePatterns.length > 0) {
@@ -97,22 +110,29 @@ export class FileSearchProvider {
97
110
  continue;
98
111
  }
99
112
  const isDirectory = match.endsWith("/");
100
- const pathWithoutTrailingSlash = isDirectory
101
- ? match.slice(0, -1)
102
- : match;
103
- const label = pathWithoutTrailingSlash.split("/").pop() || pathWithoutTrailingSlash;
104
- const parentPath = pathWithoutTrailingSlash
105
- .split("/")
106
- .slice(0, -1)
107
- .join("/");
113
+ const relativePathWithPrefix = relativePath.startsWith("./")
114
+ ? relativePath
115
+ : `./${relativePath}`;
116
+ const relPath = isDirectory
117
+ ? `${relativePathWithPrefix}/`
118
+ : relativePathWithPrefix;
119
+ const label = relativePath.split("/").pop() || relativePath;
120
+ const parentPath = relativePath.split("/").slice(0, -1).join("/");
108
121
  results.push({
109
- value: isDirectory ? `${match} ` : match,
122
+ value: isDirectory ? `${relPath} ` : relPath,
110
123
  label,
111
124
  description: parentPath || ".",
112
125
  });
113
- if (results.length >= this.maxResults) {
114
- break;
115
- }
126
+ }
127
+ results.sort((a, b) => {
128
+ const scoreA = fuzzyScore(a.label, lowerSearchTerm);
129
+ const scoreB = fuzzyScore(b.label, lowerSearchTerm);
130
+ if (scoreA !== scoreB)
131
+ return scoreA - scoreB;
132
+ return a.label.localeCompare(b.label);
133
+ });
134
+ if (results.length > this.maxResults) {
135
+ results.length = this.maxResults;
116
136
  }
117
137
  }
118
138
  catch {