@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
@@ -1,159 +1,187 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import { inspect } from "node:util";
3
- import { tool } from "ai";
4
3
  import { z } from "zod";
5
4
  import { config } from "../config.js";
6
5
  import style from "../terminal/style.js";
7
- import { manageOutput } from "../tokens/manage-output.js";
6
+ import { manageTokenLimit, TokenLimitExceededError, } from "../tokens/threshold.js";
8
7
  export const GrepTool = {
9
8
  name: "grepFiles",
10
9
  };
10
+ const inputSchema = z.object({
11
+ pattern: z
12
+ .string()
13
+ .describe("The search pattern (regex by default, or fixed-string if literal=true or auto-detected as unbalanced)"),
14
+ path: z.string().describe("The path to search in"),
15
+ recursive: z.coerce
16
+ .boolean()
17
+ .nullable()
18
+ .describe("Search recursively. (default: true))"),
19
+ ignoreCase: z.coerce
20
+ .boolean()
21
+ .nullable()
22
+ .describe("Use case-sensitive search. (default: false)"),
23
+ filePattern: z.coerce
24
+ .string()
25
+ .nullable()
26
+ .describe("Glob pattern to filter files (e.g., '*.ts', '**/*.test.js'). (Default: no filtering)"),
27
+ contextLines: z.coerce
28
+ .number()
29
+ .nullable()
30
+ .describe("The number of context lines needed in search results. (Default: 0)"),
31
+ searchIgnored: z.coerce
32
+ .boolean()
33
+ .nullable()
34
+ .describe("Search ignored files. (Default: false)"),
35
+ literal: z.coerce
36
+ .boolean()
37
+ .nullable()
38
+ .describe("Pass true for fixed-string search (-F), false for regex, (Default: auto-detects unbalanced patterns like mismatched parentheses/brackets.)"),
39
+ maxResults: z.coerce
40
+ .number()
41
+ .nullable()
42
+ .describe("Maximum number of matches to return. Set to 0 for no limit. (Default: configured value)"),
43
+ });
11
44
  export const createGrepTool = (options) => {
12
- const { sendData, tokenCounter } = options;
45
+ const { tokenCounter } = options;
13
46
  return {
14
- [GrepTool.name]: tool({
15
- description: `Search files for patterns using ripgrep (rg). Uses glob patterns for file filtering (e.g., "*.ts", "**/*.test.ts"). Auto-detects unbalanced regex patterns and falls back to fixed-string search for safety.`,
16
- inputSchema: z.object({
17
- pattern: z
18
- .string()
19
- .describe("The search pattern (regex by default, or fixed-string if literal=true or auto-detected as unbalanced)"),
20
- path: z.string().describe("The path to search in"),
21
- recursive: z.coerce
22
- .boolean()
23
- .nullable()
24
- .describe("Search recursively. (default: true))"),
25
- ignoreCase: z.coerce
26
- .boolean()
27
- .nullable()
28
- .describe("Use case-sensitive search. (default: false)"),
29
- filePattern: z
30
- .string()
31
- .nullable()
32
- .describe("Glob pattern to filter files (e.g., '*.ts', '**/*.test.js'). (Default: no filtering)"),
33
- contextLines: z.coerce
34
- .number()
35
- .nullable()
36
- .describe("The number of context lines needed in search results. (Default: 0)"),
37
- searchIgnored: z.coerce
38
- .boolean()
39
- .nullable()
40
- .describe("Search ignored files. (Default: false)"),
41
- literal: z.coerce
42
- .boolean()
43
- .nullable()
44
- .describe("Pass true for fixed-string search (-F), false for regex, (Default: auto-detects unbalanced patterns like mismatched parentheses/brackets.)"),
45
- }),
46
- execute: async ({ pattern, path, recursive, ignoreCase, filePattern, contextLines, searchIgnored, literal, }, { toolCallId, abortSignal }) => {
47
- // Check if execution has been aborted
48
- if (abortSignal?.aborted) {
49
- throw new Error("Grep search aborted");
47
+ toolDef: {
48
+ description: `Search files for patterns using ripgrep (rg). Uses glob patterns for file filtering (e.g., "*.ts", "**/*.test.ts"). Auto-detects unbalanced regex patterns and falls back to fixed-string search for safety. Results are limited to prevent overwhelming output; configure via maxResults parameter.`,
49
+ inputSchema,
50
+ },
51
+ async *execute({ pattern, path, recursive, ignoreCase, filePattern, contextLines, searchIgnored, literal, maxResults, }, { toolCallId, abortSignal }) {
52
+ // Check if execution has been aborted
53
+ if (abortSignal?.aborted) {
54
+ throw new Error("Grep search aborted");
55
+ }
56
+ try {
57
+ // grok doesn't follow my instructions
58
+ const safeFilePattern = filePattern === "null" || filePattern === "undefined"
59
+ ? null
60
+ : filePattern;
61
+ // Enhanced tool-init with detailed search parameters
62
+ let initMessage = `${style.cyan(inspect(pattern))} in ${style.cyan(path)}`;
63
+ if (safeFilePattern) {
64
+ initMessage += ` ${style.dim(`(filter: ${safeFilePattern})`)}`;
50
65
  }
51
- try {
52
- // grok doesn't follow my instructions
53
- const safeFilePattern = filePattern === "null" ? null : filePattern;
54
- sendData?.({
55
- event: "tool-init",
56
- id: toolCallId,
57
- data: `Searching codebase for ${style.cyan(inspect(pattern))}${safeFilePattern ? ` with file pattern ${style.cyan(safeFilePattern)}` : ""} in ${style.cyan(path)}`,
58
- });
59
- // Normalize literal option: if null => auto-detect using heuristic
60
- let effectiveLiteral = null;
61
- if (literal === true) {
62
- effectiveLiteral = true;
63
- }
64
- else if (literal === false) {
65
- effectiveLiteral = false;
66
- }
67
- else {
68
- // auto-detect
69
- try {
70
- if (likelyUnbalancedRegex(pattern)) {
71
- effectiveLiteral = true;
72
- sendData?.({
73
- event: "tool-update",
74
- id: toolCallId,
75
- data: {
76
- primary: "Pattern appears to contain unbalanced regex metacharacters; using fixed-string mode (-F).",
77
- },
78
- });
79
- }
80
- else {
81
- effectiveLiteral = false;
82
- }
66
+ if (recursive === false) {
67
+ initMessage += ` ${style.dim("(non-recursive)")}`;
68
+ }
69
+ if (ignoreCase) {
70
+ initMessage += ` ${style.dim("(case-insensitive)")}`;
71
+ }
72
+ if (contextLines && contextLines > 0) {
73
+ initMessage += ` ${style.dim(`(with ${contextLines} context line${contextLines === 1 ? "" : "s"})`)}`;
74
+ }
75
+ yield {
76
+ name: GrepTool.name,
77
+ event: "tool-init",
78
+ id: toolCallId,
79
+ data: initMessage,
80
+ };
81
+ // Normalize literal option: if null => auto-detect using heuristic
82
+ let effectiveLiteral = null;
83
+ if (literal === true) {
84
+ effectiveLiteral = true;
85
+ }
86
+ else if (literal === false) {
87
+ effectiveLiteral = false;
88
+ }
89
+ else {
90
+ // auto-detect
91
+ try {
92
+ if (likelyUnbalancedRegex(pattern)) {
93
+ effectiveLiteral = true;
83
94
  }
84
- catch (_err) {
95
+ else {
85
96
  effectiveLiteral = false;
86
97
  }
87
98
  }
88
- const rawResult = grepFiles(pattern, path, {
89
- recursive,
90
- ignoreCase,
91
- filePattern: safeFilePattern,
92
- contextLines,
93
- searchIgnored,
94
- literal: effectiveLiteral,
95
- });
96
- const maxTokens = (await config.readProjectConfig()).tools.maxTokens;
97
- const managed = manageOutput(rawResult, {
98
- tokenCounter,
99
- threshold: maxTokens,
100
- });
101
- if (managed.truncated) {
102
- sendData?.({
103
- event: "tool-update",
104
- id: toolCallId,
105
- data: { primary: managed.warning },
106
- });
99
+ catch (_err) {
100
+ effectiveLiteral = false;
107
101
  }
108
- // Extract and filter matches from the content
109
- const extractMatches = (content) => {
110
- if (content === "No matches found.") {
111
- return [];
112
- }
113
- return content
114
- .trim()
115
- .split("\n")
116
- .filter((line) => {
117
- if (line === "--") {
118
- return false;
119
- }
120
- return /^(.+?):(\d+):(.*)$/.test(line);
121
- });
122
- };
123
- const matches = extractMatches(managed.content);
124
- const matchCount = matches.length;
125
- // Show the last 10 matches as a preview
126
- if (matchCount > 0) {
127
- const previewMatches = matches.slice(-10); // Get last 10 matches
128
- sendData?.({
129
- event: "tool-update",
130
- id: toolCallId,
131
- data: {
132
- primary: `Last ${previewMatches.length} matches:`,
133
- secondary: previewMatches,
134
- },
135
- });
102
+ }
103
+ const projectConfig = await config.getConfig();
104
+ const configMaxResults = projectConfig.tools.maxResults;
105
+ const effectiveMaxResults = maxResults ?? configMaxResults;
106
+ const grepResult = grepFilesStructured(pattern, path, {
107
+ recursive,
108
+ ignoreCase,
109
+ filePattern: safeFilePattern,
110
+ contextLines,
111
+ searchIgnored,
112
+ literal: effectiveLiteral,
113
+ maxResults: effectiveMaxResults,
114
+ });
115
+ try {
116
+ const result = await manageTokenLimit(grepResult.rawOutput, tokenCounter, "Grep", "Use maxResults parameter, more specific patterns, or contextLines=0 to reduce output");
117
+ const matchCount = grepResult.matchCount;
118
+ // Build completion message with preview information
119
+ let completionMessage = `Found ${style.cyan(matchCount)} match${matchCount === 1 ? "" : "es"}`;
120
+ if (matchCount === 0) {
121
+ completionMessage = "Search completed - no matches found";
122
+ }
123
+ // Calculate unique files with matches
124
+ const filesWithMatches = new Set(grepResult.parsedMatches
125
+ .filter((match) => match.isMatch && !match.isContext && match.file)
126
+ .map((match) => match.file)).size;
127
+ if (filesWithMatches > 0) {
128
+ completionMessage += ` across ${style.cyan(filesWithMatches)} file${filesWithMatches === 1 ? "" : "s"}`;
129
+ }
130
+ if (grepResult.contextCount > 0) {
131
+ completionMessage += ` with ${style.cyan(grepResult.contextCount)} context line${grepResult.contextCount === 1 ? "" : "s"}`;
136
132
  }
137
- sendData?.({
133
+ completionMessage += ` (${result.tokenCount} tokens)`;
134
+ yield {
135
+ name: GrepTool.name,
138
136
  event: "tool-completion",
139
137
  id: toolCallId,
140
- data: `Found ${style.cyan(matchCount)} matches. (${managed.tokenCount} tokens)`,
141
- });
142
- return Promise.resolve(managed.content);
138
+ data: completionMessage,
139
+ };
140
+ yield result.content;
143
141
  }
144
142
  catch (error) {
145
- sendData?.({
146
- event: "tool-error",
147
- id: toolCallId,
148
- data: `Error searching for "${pattern}" in ${path}`,
149
- });
150
- return Promise.resolve(error.message);
143
+ if (error instanceof TokenLimitExceededError) {
144
+ yield {
145
+ name: GrepTool.name,
146
+ event: "tool-error",
147
+ id: toolCallId,
148
+ data: error.message,
149
+ };
150
+ yield error.message;
151
+ return;
152
+ }
153
+ throw error;
154
+ }
155
+ }
156
+ catch (error) {
157
+ const errorMessage = error.message;
158
+ let userFriendlyError = `Error searching for "${pattern}" in ${path}: ${errorMessage}`;
159
+ // Provide more helpful error messages for common cases
160
+ if (errorMessage.includes("No such file or directory")) {
161
+ userFriendlyError = `Path not found: "${path}"`;
162
+ if (filePattern) {
163
+ userFriendlyError += ` with file pattern "${filePattern}"`;
164
+ }
165
+ userFriendlyError += " - check if the path exists and is accessible";
166
+ }
167
+ else if (errorMessage.includes("permission denied")) {
168
+ userFriendlyError = `Permission denied accessing "${path}"`;
169
+ }
170
+ else if (errorMessage.includes("Regex parse error")) {
171
+ userFriendlyError = `Invalid search pattern "${pattern}" - try using literal=true for fixed-string search`;
151
172
  }
152
- },
153
- }),
173
+ yield {
174
+ name: GrepTool.name,
175
+ event: "tool-error",
176
+ id: toolCallId,
177
+ data: userFriendlyError,
178
+ };
179
+ yield errorMessage;
180
+ }
181
+ },
154
182
  };
155
183
  };
156
- function likelyUnbalancedRegex(pattern) {
184
+ export function likelyUnbalancedRegex(pattern) {
157
185
  const counts = {
158
186
  openParen: 0,
159
187
  closeParen: 0,
@@ -163,6 +191,7 @@ function likelyUnbalancedRegex(pattern) {
163
191
  closeBrace: 0,
164
192
  };
165
193
  let escaped = false;
194
+ let inCharacterClass = false;
166
195
  for (let i = 0; i < pattern.length; i++) {
167
196
  const ch = pattern[i];
168
197
  if (escaped) {
@@ -173,32 +202,105 @@ function likelyUnbalancedRegex(pattern) {
173
202
  escaped = true;
174
203
  continue;
175
204
  }
176
- switch (ch) {
177
- case "(":
178
- counts.openParen++;
179
- break;
180
- case ")":
181
- counts.closeParen++;
182
- break;
183
- case "[":
184
- counts.openBracket++;
185
- break;
186
- case "]":
187
- counts.closeBracket++;
188
- break;
189
- case "{":
190
- counts.openBrace++;
191
- break;
192
- case "}":
193
- counts.closeBrace++;
194
- break;
195
- default:
196
- break;
205
+ // Track character class boundaries
206
+ if (ch === "[" && !inCharacterClass) {
207
+ inCharacterClass = true;
208
+ counts.openBracket++;
209
+ continue;
210
+ }
211
+ if (ch === "]" && inCharacterClass) {
212
+ inCharacterClass = false;
213
+ counts.closeBracket++;
214
+ continue;
215
+ }
216
+ // Only count brackets/parens/braces outside of character classes
217
+ if (!inCharacterClass) {
218
+ switch (ch) {
219
+ case "(":
220
+ counts.openParen++;
221
+ break;
222
+ case ")":
223
+ counts.closeParen++;
224
+ break;
225
+ case "{":
226
+ counts.openBrace++;
227
+ break;
228
+ case "}":
229
+ counts.closeBrace++;
230
+ break;
231
+ default:
232
+ break;
233
+ }
234
+ }
235
+ }
236
+ // Check for unbalanced brackets, parentheses, and braces
237
+ const hasUnbalancedBrackets = counts.openBracket !== counts.closeBracket;
238
+ const hasUnbalancedParens = counts.openParen !== counts.closeParen;
239
+ const hasUnbalancedBraces = counts.openBrace !== counts.closeBrace;
240
+ // Also check for invalid repetition operators (e.g., {n}, {n,}, {n,m}) outside of character classes
241
+ let hasInvalidRepetition = false;
242
+ {
243
+ let escaped2 = false;
244
+ let inClass2 = false;
245
+ for (let i = 0; i < pattern.length; i++) {
246
+ const ch = pattern[i];
247
+ if (escaped2) {
248
+ escaped2 = false;
249
+ continue;
250
+ }
251
+ if (ch === "\\") {
252
+ escaped2 = true;
253
+ continue;
254
+ }
255
+ if (ch === "[" && !inClass2) {
256
+ inClass2 = true;
257
+ continue;
258
+ }
259
+ if (ch === "]" && inClass2) {
260
+ inClass2 = false;
261
+ continue;
262
+ }
263
+ if (inClass2) {
264
+ continue;
265
+ }
266
+ if (ch === "{") {
267
+ let j = i + 1;
268
+ let hasDigits = false;
269
+ let hasComma = false;
270
+ while (j < pattern.length && pattern[j] !== "}") {
271
+ const c = pattern[j];
272
+ if (c >= "0" && c <= "9") {
273
+ hasDigits = true;
274
+ }
275
+ else if (c === "," && !hasComma) {
276
+ hasComma = true;
277
+ }
278
+ else {
279
+ break;
280
+ }
281
+ j++;
282
+ }
283
+ if (j >= pattern.length || pattern[j] !== "}") {
284
+ hasInvalidRepetition = true;
285
+ break;
286
+ }
287
+ // At this point we have a closing brace at j
288
+ if (!hasDigits) {
289
+ // Heuristic: treat empty {} as non-quantifier when it doesn't follow a likely atom
290
+ const prev = i > 0 ? pattern[i - 1] : undefined;
291
+ if (prev !== undefined && /\S/.test(prev)) {
292
+ hasInvalidRepetition = true;
293
+ break;
294
+ }
295
+ // else ignore as literal braces
296
+ }
297
+ }
197
298
  }
198
299
  }
199
- return (counts.openParen !== counts.closeParen ||
200
- counts.openBracket !== counts.closeBracket ||
201
- counts.openBrace !== counts.closeBrace);
300
+ return (hasUnbalancedBrackets ||
301
+ hasUnbalancedParens ||
302
+ hasUnbalancedBraces ||
303
+ hasInvalidRepetition);
202
304
  }
203
305
  /**
204
306
  * Search files for patterns using ripgrep
@@ -246,21 +348,179 @@ export function buildGrepCommand(pattern, path, options = {}) {
246
348
  command += " -F";
247
349
  }
248
350
  command += ` ${JSON.stringify(pattern)}`;
249
- command += ` ${path}`;
351
+ command += ` ${JSON.stringify(path)}`;
250
352
  return command;
251
353
  }
252
- function grepFiles(pattern, path, options = {}) {
354
+ /**
355
+ * Parse ripgrep output and extract structured match information
356
+ */
357
+ export function parseRipgrepOutput(content) {
358
+ if (content === "No matches found.") {
359
+ return [];
360
+ }
361
+ const lines = content.trim().split("\n");
362
+ const parsed = [];
363
+ for (const line of lines) {
364
+ if (line === "--") {
365
+ // Separator between file groups - skip
366
+ continue;
367
+ }
368
+ if (line.trim() === "") {
369
+ // Empty line - skip
370
+ continue;
371
+ }
372
+ // Try multi-file format: file:line:content
373
+ const multiFileMatch = line.match(/^([^:]+):(\d+):(.+)$/);
374
+ if (multiFileMatch) {
375
+ parsed.push({
376
+ file: multiFileMatch[1],
377
+ line: Number.parseInt(multiFileMatch[2], 10),
378
+ content: multiFileMatch[3],
379
+ isMatch: true,
380
+ });
381
+ continue;
382
+ }
383
+ // Try single-file format: line:content
384
+ const singleFileMatch = line.match(/^(\d+):(.+)$/);
385
+ if (singleFileMatch) {
386
+ parsed.push({
387
+ line: Number.parseInt(singleFileMatch[1], 10),
388
+ content: singleFileMatch[2],
389
+ isMatch: true,
390
+ });
391
+ continue;
392
+ }
393
+ // Try context line format: file-line-context
394
+ const contextMatch = line.match(/^([^:]+)-(\d+)-(.+)$/);
395
+ if (contextMatch) {
396
+ parsed.push({
397
+ file: contextMatch[1],
398
+ line: Number.parseInt(contextMatch[2], 10),
399
+ content: contextMatch[3],
400
+ isMatch: false,
401
+ isContext: true,
402
+ });
403
+ continue;
404
+ }
405
+ // Try context line format without file: line-context
406
+ const contextNoFileMatch = line.match(/^(\d+)-(.+)$/);
407
+ if (contextNoFileMatch) {
408
+ parsed.push({
409
+ line: Number.parseInt(contextNoFileMatch[1], 10),
410
+ content: contextNoFileMatch[2],
411
+ isMatch: false,
412
+ isContext: true,
413
+ });
414
+ continue;
415
+ }
416
+ // If we get here, it's an unrecognized format - treat as match for backwards compatibility
417
+ parsed.push({
418
+ content: line,
419
+ line: 0,
420
+ isMatch: true,
421
+ });
422
+ }
423
+ return parsed;
424
+ }
425
+ /**
426
+ * Count actual matches (excluding context lines)
427
+ */
428
+ export function countActualMatches(parsed) {
429
+ return parsed.filter((match) => match.isMatch && !match.isContext).length;
430
+ }
431
+ /**
432
+ * Count context lines
433
+ */
434
+ export function countContextLines(parsed) {
435
+ return parsed.filter((match) => match.isContext).length;
436
+ }
437
+ /**
438
+ * Truncate matches to a maximum number of results
439
+ */
440
+ export function truncateMatches(matches, maxResults) {
441
+ if (!maxResults || maxResults <= 0) {
442
+ return { truncated: matches, isTruncated: false };
443
+ }
444
+ const actualMatches = matches.filter((m) => m.isMatch && !m.isContext);
445
+ if (actualMatches.length <= maxResults) {
446
+ return { truncated: matches, isTruncated: false };
447
+ }
448
+ const truncated = [];
449
+ let matchesKept = 0;
450
+ for (const match of matches) {
451
+ if (match.isMatch && !match.isContext) {
452
+ if (matchesKept < maxResults) {
453
+ truncated.push(match);
454
+ matchesKept++;
455
+ }
456
+ else {
457
+ break;
458
+ }
459
+ }
460
+ }
461
+ return {
462
+ truncated,
463
+ isTruncated: true,
464
+ };
465
+ }
466
+ /**
467
+ * Extract matches from content (backwards compatibility wrapper)
468
+ */
469
+ export function extractMatches(content) {
470
+ const parsed = parseRipgrepOutput(content);
471
+ const matches = parsed.filter((match) => match.isMatch && !match.isContext);
472
+ // Convert back to original string format for backwards compatibility
473
+ return matches.map((match) => {
474
+ if (match.file) {
475
+ return `${match.file}:${match.line}:${match.content}`;
476
+ }
477
+ return `${match.line}:${match.content}`;
478
+ });
479
+ }
480
+ export function grepFiles(pattern, path, options = {}) {
481
+ const result = grepFilesStructured(pattern, path, options);
482
+ return result.rawOutput;
483
+ }
484
+ export function grepFilesStructured(pattern, path, options = {}) {
253
485
  try {
254
486
  const command = buildGrepCommand(pattern, path, options);
255
- const result = execSync(command, { encoding: "utf-8" });
256
- return result;
487
+ const rawOutput = execSync(command, {
488
+ encoding: "utf-8",
489
+ stdio: ["pipe", "pipe", "pipe"],
490
+ });
491
+ const parsedMatches = parseRipgrepOutput(rawOutput);
492
+ const matchCount = countActualMatches(parsedMatches);
493
+ const { truncated, isTruncated } = truncateMatches(parsedMatches, options.maxResults);
494
+ const displayedCount = countActualMatches(truncated);
495
+ const displayedContextCount = countContextLines(truncated);
496
+ return {
497
+ rawOutput,
498
+ parsedMatches: truncated,
499
+ matchCount,
500
+ displayedCount,
501
+ contextCount: displayedContextCount,
502
+ hasMatches: matchCount > 0,
503
+ isTruncated,
504
+ };
257
505
  }
258
506
  catch (error) {
259
- if (error instanceof Error &&
260
- "status" in error &&
261
- error.status === 1) {
262
- return "No matches found.";
507
+ const execError = error;
508
+ const exitCode = execError?.status;
509
+ if (exitCode === 1) {
510
+ return {
511
+ rawOutput: "No matches found.",
512
+ parsedMatches: [],
513
+ matchCount: 0,
514
+ contextCount: 0,
515
+ hasMatches: false,
516
+ };
517
+ }
518
+ if (exitCode === 2) {
519
+ const stderrStr = typeof execError.stderr === "string"
520
+ ? execError.stderr
521
+ : (execError.stderr?.toString("utf-8") ?? execError.message);
522
+ throw new Error(`Regex parse error in pattern "${pattern}": ${stderrStr}`);
263
523
  }
264
- throw new Error(`Error executing ripgrep: ${error.message}`);
524
+ throw new Error(`Error executing ripgrep: ${execError.message}`);
265
525
  }
266
526
  }