@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,23 @@
1
+ import { z } from "zod";
2
+ import type { ToolExecutionOptions } from "./types.ts";
3
+ export declare const SkillTool: {
4
+ name: "Skill";
5
+ };
6
+ declare const inputSchema: z.ZodObject<{
7
+ skill: z.ZodString;
8
+ args: z.ZodOptional<z.ZodString>;
9
+ }, z.core.$strip>;
10
+ type SkillInputSchema = z.infer<typeof inputSchema>;
11
+ export declare function createSkillTool(): Promise<{
12
+ toolDef: {
13
+ description: string;
14
+ inputSchema: z.ZodObject<{
15
+ skill: z.ZodString;
16
+ args: z.ZodOptional<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ };
19
+ display({ skill: skillName }: SkillInputSchema): string;
20
+ execute({ skill: skillName, args }: SkillInputSchema, { abortSignal }: ToolExecutionOptions): Promise<string>;
21
+ }>;
22
+ export {};
23
+ //# sourceMappingURL=skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../source/tools/skill.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,SAAS;;CAErB,CAAC;AAEF,QAAA,MAAM,WAAW;;;iBAKf,CAAC;AAEH,KAAK,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAEpD,wBAAsB,eAAe;;;;;;;;kCAWH,gBAAgB,GAAG,MAAM;wCAIzB,gBAAgB,mBAC3B,oBAAoB,GACpC,OAAO,CAAC,MAAM,CAAC;GA4CrB"}
@@ -0,0 +1,65 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { dirname } from "node:path";
3
+ import { z } from "zod";
4
+ import { loadSkills } from "../skills/index.js";
5
+ import style from "../terminal/style.js";
6
+ import { replaceArgumentPlaceholders } from "../utils/templates.js";
7
+ export const SkillTool = {
8
+ name: "Skill",
9
+ };
10
+ const inputSchema = z.object({
11
+ skill: z
12
+ .string()
13
+ .describe('The skill name. E.g., "commit", "review-pr", or "pdf"'),
14
+ args: z.string().optional().describe("Optional arguments for the skill"),
15
+ });
16
+ export async function createSkillTool() {
17
+ const skills = await loadSkills();
18
+ const modelInvocableSkills = skills.getModelInvocable();
19
+ const description = "Run a skill (e.g., commit, review-pr).";
20
+ return {
21
+ toolDef: {
22
+ description,
23
+ inputSchema,
24
+ },
25
+ display({ skill: skillName }) {
26
+ return style.cyan(skillName);
27
+ },
28
+ async execute({ skill: skillName, args }, { abortSignal }) {
29
+ try {
30
+ if (abortSignal?.aborted) {
31
+ throw new Error("Skill execution aborted");
32
+ }
33
+ // Find the skill
34
+ const skill = modelInvocableSkills.find((s) => s.name === skillName);
35
+ if (!skill) {
36
+ const availableSkillNames = modelInvocableSkills
37
+ .map((s) => s.name)
38
+ .join(", ");
39
+ const errorMsg = `Skill "${skillName}" not found. Available skills: ${availableSkillNames}`;
40
+ return errorMsg;
41
+ }
42
+ if (skill.disableModelInvocation) {
43
+ return `Skill "${skillName}" is not available for model invocation.`;
44
+ }
45
+ // Read the skill file
46
+ const content = await readFile(skill.filePath, "utf8");
47
+ let result = `# Skill Name: ${skill.name}`;
48
+ result += `\n**Base directory**: ${dirname(skill.filePath)}\n\n`;
49
+ result +=
50
+ "Relative paths in this skill (e.g., scripts/, reference/) are relative to this base directory.\n";
51
+ // Parse frontmatter and body
52
+ const yamlStart = content.indexOf("---");
53
+ const yamlEnd = content.indexOf("---", yamlStart + 3);
54
+ const body = yamlEnd !== -1 ? content.slice(yamlEnd + 3).trim() : content;
55
+ const argsArray = args ? args.split(/\s+/).filter(Boolean) : [];
56
+ result += replaceArgumentPlaceholders(body, argsArray);
57
+ return result;
58
+ }
59
+ catch (error) {
60
+ const errorMsg = `${error.message}`;
61
+ return errorMsg;
62
+ }
63
+ },
64
+ };
65
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,SAAS;;CAErB,CAAC;AAWF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;;yBAUT,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,mBACvB,oBAAoB,GACpC,OAAO,CAAC,MAAM,CAAC;CAUrB,CAAC"}
1
+ {"version":3,"file":"think.d.ts","sourceRoot":"","sources":["../../source/tools/think.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,SAAS;;CAErB,CAAC;AAIF,QAAA,MAAM,WAAW;;iBAEf,CAAC;AAGH,eAAO,MAAM,eAAe;;;;;;;;yBAUT,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,mBACvB,oBAAoB,GACpC,OAAO,CAAC,MAAM,CAAC;CAUrB,CAAC"}
@@ -2,14 +2,7 @@ import { z } from "zod";
2
2
  export const ThinkTool = {
3
3
  name: "Think",
4
4
  };
5
- const toolDescription = `Use the tool to think about something. It will not obtain new information or make any changes to the repository, but just log the thought. Use it when complex reasoning or brainstorming is needed.
6
- Common use cases:
7
- 1. When exploring a repository and discovering the source of a bug, call this tool to brainstorm several unique ways of fixing the bug, and assess which change(s) are likely to be simplest and most effective
8
- 2. After receiving test results, use this tool to brainstorm ways to fix failing tests
9
- 3. When planning a complex refactoring, use this tool to outline different approaches and their tradeoffs
10
- 4. When designing a new feature, use this tool to think through architecture decisions and implementation details
11
- 5. When debugging a complex issue, use this tool to organize your thoughts and hypotheses
12
- The tool simply logs your thought process for better transparency and does not execute any code or make changes.`;
5
+ const toolDescription = "Think through a problem step-by-step.";
13
6
  const inputSchema = z.object({
14
7
  thought: z.string().describe("Your thought"),
15
8
  });
@@ -21,7 +14,7 @@ export const createThinkTool = () => {
21
14
  inputSchema,
22
15
  },
23
16
  display() {
24
- return "\n> Logging thought";
17
+ return "Logging thought";
25
18
  },
26
19
  async execute({ thought }, { abortSignal }) {
27
20
  if (abortSignal?.aborted) {
@@ -1,4 +1,6 @@
1
1
  import type { Tool } from "ai";
2
+ import type { CompleteToolSet, CompleteTools } from "./index.ts";
3
+ export declare function toAiSdkTools(tools: CompleteToolSet, includeExecute?: boolean): CompleteTools;
2
4
  export declare function prepareTools(tools: {
3
5
  [toolName: string]: Tool;
4
6
  }): {
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../source/tools/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAG/B,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG;IACjE,KAAK,EACD,SAAS,GACT,KAAK,CAAC;QACJ,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;YAChC,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;KACH,CAAC,CAAC;CACR,CAuBA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../source/tools/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAuB,MAAM,IAAI,CAAC;AAGpD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEjE,wBAAgB,YAAY,CAC1B,KAAK,EAAE,eAAe,EACtB,cAAc,UAAO,GACpB,aAAa,CAYf;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG;IACjE,KAAK,EACD,SAAS,GACT,KAAK,CAAC;QACJ,IAAI,EAAE,UAAU,CAAC;QACjB,QAAQ,EAAE;YACR,IAAI,EAAE,MAAM,CAAC;YACb,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;YAChC,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;KACH,CAAC,CAAC;CACR,CAuBA"}
@@ -1,4 +1,16 @@
1
+ import { tool } from "ai";
1
2
  import z from "zod";
3
+ export function toAiSdkTools(tools, includeExecute = true) {
4
+ return Object.fromEntries(Object.entries(tools).map(([name, toolObj]) => [
5
+ name,
6
+ tool({
7
+ ...toolObj.toolDef,
8
+ execute: (includeExecute
9
+ ? toolObj.execute
10
+ : undefined),
11
+ }),
12
+ ]));
13
+ }
2
14
  export function prepareTools(tools) {
3
15
  const openaiCompatTools = [];
4
16
  for (const tool of Object.entries(tools)) {
@@ -0,0 +1,50 @@
1
+ import { z } from "zod";
2
+ import type { ToolExecutionOptions } from "./types.ts";
3
+ export declare const WebFetchTool: {
4
+ name: "WebFetch";
5
+ };
6
+ /**
7
+ * Input schema for the web fetch tool
8
+ */
9
+ declare const inputSchema: z.ZodObject<{
10
+ url: z.ZodString;
11
+ output: z.ZodDefault<z.ZodEnum<{
12
+ markdown: "markdown";
13
+ text: "text";
14
+ html: "html";
15
+ json: "json";
16
+ }>>;
17
+ jina: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
18
+ timeout: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
19
+ headers: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
20
+ }, z.core.$strip>;
21
+ type WebFetchInputSchema = z.infer<typeof inputSchema>;
22
+ /**
23
+ * Execute web fetch
24
+ */
25
+ export declare function executeWebFetch(options: WebFetchInputSchema, executionOptions: ToolExecutionOptions): Promise<string>;
26
+ /**
27
+ * Create the web fetch tool
28
+ */
29
+ export declare const createWebFetchTool: () => Promise<{
30
+ toolDef: {
31
+ description: string;
32
+ inputSchema: z.ZodObject<{
33
+ url: z.ZodString;
34
+ output: z.ZodDefault<z.ZodEnum<{
35
+ markdown: "markdown";
36
+ text: "text";
37
+ html: "html";
38
+ json: "json";
39
+ }>>;
40
+ jina: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
41
+ timeout: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedNumber<unknown>>>>;
42
+ headers: z.ZodOptional<z.ZodPipe<z.ZodTransform<string | null, unknown>, z.ZodNullable<z.ZodCoercedBoolean<unknown>>>>;
43
+ }, z.core.$strip>;
44
+ };
45
+ display({ url }: WebFetchInputSchema): string;
46
+ execute(options: WebFetchInputSchema, executionOptions: ToolExecutionOptions): Promise<string>;
47
+ }>;
48
+ export type WebFetchTool = Awaited<ReturnType<typeof createWebFetchTool>>;
49
+ export {};
50
+ //# sourceMappingURL=web-fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-fetch.d.ts","sourceRoot":"","sources":["../../source/tools/web-fetch.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,eAAO,MAAM,YAAY;;CAExB,CAAC;AAQF;;GAEG;AACH,QAAA,MAAM,WAAW;;;;;;;;;;;iBAkBf,CAAC;AAEH,KAAK,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AA6bvD;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,mBAAmB,EAC5B,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC,CAiEjB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;qBAQV,mBAAmB;qBAIzB,mBAAmB,oBACV,oBAAoB,GACrC,OAAO,CAAC,MAAM,CAAC;EAIrB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,446 @@
1
+ import { load } from "cheerio";
2
+ import { z } from "zod";
3
+ import style from "../terminal/style.js";
4
+ export const WebFetchTool = {
5
+ name: "WebFetch",
6
+ };
7
+ // Constants
8
+ const DEFAULT_TIMEOUT = 30000; // 30 seconds
9
+ const MAX_REDIRECTS = 5;
10
+ const MAX_URL_LENGTH = 2048;
11
+ const JINA_API_BASE = "https://r.jina.ai";
12
+ /**
13
+ * Input schema for the web fetch tool
14
+ */
15
+ const inputSchema = z.object({
16
+ url: z.string().describe("URL to fetch"),
17
+ output: z
18
+ .enum(["text", "html", "markdown", "json"])
19
+ .default("text")
20
+ .describe("Output format (default: text)"),
21
+ jina: z
22
+ .preprocess((val) => convertNullString(val), z.coerce.boolean().nullable())
23
+ .optional()
24
+ .describe("Use Jina AI for HTML cleaning"),
25
+ timeout: z
26
+ .preprocess((val) => convertNullString(val), z.coerce.number().nullable())
27
+ .optional()
28
+ .describe(`Timeout in milliseconds (default: ${DEFAULT_TIMEOUT}ms)`),
29
+ headers: z
30
+ .preprocess((val) => convertNullString(val), z.coerce.boolean().nullable())
31
+ .optional()
32
+ .describe("Include HTTP headers in output"),
33
+ });
34
+ /**
35
+ * Convert null/undefined to string for preprocessing
36
+ */
37
+ function convertNullString(val) {
38
+ if (val === null ||
39
+ val === undefined ||
40
+ val === "null" ||
41
+ val === "undefined") {
42
+ return null;
43
+ }
44
+ return String(val);
45
+ }
46
+ /**
47
+ * Count tokens (simple estimation: 4 characters per token)
48
+ */
49
+ function countTokens(text) {
50
+ return Math.ceil(text.length / 4);
51
+ }
52
+ /**
53
+ * Validate URL
54
+ */
55
+ function isValidUrl(url) {
56
+ try {
57
+ if (typeof url !== "string" || url.length === 0)
58
+ return false;
59
+ if (url.length > MAX_URL_LENGTH)
60
+ return false;
61
+ const parsed = new URL(url);
62
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ }
68
+ /**
69
+ * Factory function for creating abort handlers.
70
+ * Defined at module level to avoid capturing closure scope.
71
+ */
72
+ function createAbortHandler(ctrl, signal) {
73
+ return () => {
74
+ ctrl.abort(signal?.reason ?? new Error("Aborted"));
75
+ };
76
+ }
77
+ /**
78
+ * Create an AbortSignal that combines a timeout with an optional parent signal
79
+ */
80
+ function createTimeoutSignal(timeoutMs, parentSignal) {
81
+ const controller = new AbortController();
82
+ // Use bind() to avoid capturing scope in timeout callback
83
+ const abort = controller.abort.bind(controller);
84
+ const timeoutId = setTimeout(() => abort(new Error(`Request timed out after ${timeoutMs}ms`)), timeoutMs);
85
+ // Create abort handler using factory to avoid capturing scope
86
+ const abortHandler = createAbortHandler(controller, parentSignal);
87
+ if (parentSignal) {
88
+ if (parentSignal.aborted) {
89
+ abortHandler();
90
+ }
91
+ else {
92
+ parentSignal.addEventListener("abort", abortHandler, { once: true });
93
+ }
94
+ }
95
+ return {
96
+ signal: controller.signal,
97
+ cleanup: () => {
98
+ clearTimeout(timeoutId);
99
+ if (parentSignal) {
100
+ parentSignal.removeEventListener("abort", abortHandler);
101
+ }
102
+ },
103
+ };
104
+ }
105
+ /**
106
+ * Get content type from response headers
107
+ */
108
+ function getContentType(response) {
109
+ const header = response.headers.get("content-type") || "text/plain";
110
+ return header.split(";")[0].trim();
111
+ }
112
+ /**
113
+ * HTML Cleaner class using Cheerio
114
+ */
115
+ class HtmlCleaner {
116
+ html;
117
+ constructor(html) {
118
+ this.html = html;
119
+ }
120
+ static new(html) {
121
+ return new HtmlCleaner(html);
122
+ }
123
+ clean(options = { simplify: true, empty: true }) {
124
+ const { simplify, empty } = options;
125
+ const $ = load(this.html);
126
+ this.removeUnnecessaryElements($);
127
+ if (simplify) {
128
+ this.simplifyStructure($);
129
+ }
130
+ if (empty) {
131
+ this.removeEmptyElements($);
132
+ }
133
+ return $.html()
134
+ .trim()
135
+ .replace(/^\s*[\r\n]/gm, "");
136
+ }
137
+ removeUnnecessaryElements($) {
138
+ $("script").remove();
139
+ $("noscript").remove();
140
+ $("style").remove();
141
+ $('link[rel="stylesheet"]').remove();
142
+ $('link[rel="preload"]').remove();
143
+ $("link").remove();
144
+ $("form").remove();
145
+ $("*")
146
+ .contents()
147
+ .each((_, element) => {
148
+ if (element.type === "comment") {
149
+ $(element).remove();
150
+ }
151
+ });
152
+ $("[style]").removeAttr("style");
153
+ $("[class]").removeAttr("class");
154
+ $("[id]").removeAttr("id");
155
+ }
156
+ simplifyStructure($) {
157
+ $("div div").each((_, element) => {
158
+ const $element = $(element);
159
+ const parent = $element.parent();
160
+ if (parent.children().length === 1 && parent.get(0)?.tagName === "div") {
161
+ $element.unwrap();
162
+ }
163
+ });
164
+ $("span").each((_, element) => {
165
+ const $element = $(element);
166
+ if (!$element.attr() || Object.keys($element.attr() ?? {}).length === 0) {
167
+ const h = $element.html();
168
+ if (h) {
169
+ $element.replaceWith(h);
170
+ }
171
+ }
172
+ });
173
+ }
174
+ removeEmptyElements($) {
175
+ $(":empty").remove();
176
+ }
177
+ }
178
+ /**
179
+ * Convert HTML to Markdown
180
+ */
181
+ function htmlToMarkdown(html) {
182
+ return html
183
+ .replace(/<h1>(.*?)<\/h1>/g, "# $1\n\n")
184
+ .replace(/<h2>(.*?)<\/h2>/g, "## $1\n\n")
185
+ .replace(/<h3>(.*?)<\/h3>/g, "### $1\n\n")
186
+ .replace(/<h4>(.*?)<\/h4>/g, "#### $1\n\n")
187
+ .replace(/<h5>(.*?)<\/h5>/g, "##### $1\n\n")
188
+ .replace(/<h6>(.*?)<\/h6>/g, "###### $1\n\n")
189
+ .replace(/<p>(.*?)<\/p>/g, "$1\n\n")
190
+ .replace(/<br\s*\/?>/g, "\n")
191
+ .replace(/<strong>(.*?)<\/strong>/g, "**$1**")
192
+ .replace(/<b>(.*?)<\/b>/g, "**$1**")
193
+ .replace(/<em>(.*?)<\/em>/g, "*$1*")
194
+ .replace(/<i>(.*?)<\/i>/g, "*$1*")
195
+ .replace(/<a[^>]*href="([^"]*)"[^>]*>(.*?)<\/a>/g, "[$2]($1)")
196
+ .replace(/<li>(.*?)<\/li>/g, "- $1\n")
197
+ .replace(/<ul[^>]*>/g, "\n")
198
+ .replace(/<\/ul>/g, "\n")
199
+ .replace(/<ol[^>]*>/g, "\n")
200
+ .replace(/<\/ol>/g, "\n")
201
+ .replace(/<code>(.*?)<\/code>/g, "`$1`")
202
+ .replace(/<pre>(.*?)<\/pre>/gs, "```\n$1\n```\n")
203
+ .replace(/<[^>]*>/g, "")
204
+ .replace(/\n\n\n+/g, "\n\n")
205
+ .trim();
206
+ }
207
+ /**
208
+ * Fetch using Jina AI reader
209
+ */
210
+ async function fetchWithJina(url, signal) {
211
+ const apiKey = process.env["JINA_READER_API_KEY"];
212
+ if (!apiKey) {
213
+ throw new Error("JINA_READER_API_KEY environment variable is not set");
214
+ }
215
+ const jinaUrl = `${JINA_API_BASE}/${encodeURIComponent(url)}`;
216
+ const response = await fetch(jinaUrl, {
217
+ method: "GET",
218
+ headers: {
219
+ // biome-ignore lint/style/useNamingConvention: HTTP header names are case-sensitive
220
+ Authorization: `Bearer ${apiKey}`,
221
+ "X-With-Generated-Alt": "true",
222
+ "X-With-Links-Summary": "true",
223
+ },
224
+ signal,
225
+ });
226
+ if (!response.ok) {
227
+ const errorText = await response.text();
228
+ throw new Error(`Jina API error: ${response.status} - ${errorText}`);
229
+ }
230
+ const content = await response.text();
231
+ const tokenCount = countTokens(content);
232
+ return {
233
+ content,
234
+ contentType: "text/html",
235
+ sourceUrl: url,
236
+ tokenCount,
237
+ success: true,
238
+ provider: "jina",
239
+ };
240
+ }
241
+ /**
242
+ * Handle HTML response
243
+ */
244
+ async function handleHtmlResponse(response, useJina, signal, verbose = false) {
245
+ const html = await response.text();
246
+ if (useJina) {
247
+ try {
248
+ const jinaResult = await fetchWithJina(response.url, signal);
249
+ return jinaResult;
250
+ }
251
+ catch (error) {
252
+ if (verbose) {
253
+ console.error(`Jina AI failed: ${error instanceof Error ? error.message : String(error)}, falling back to local cleaning`);
254
+ }
255
+ }
256
+ }
257
+ const cleaner = HtmlCleaner.new(html);
258
+ const cleaned = cleaner.clean();
259
+ const tokenCount = countTokens(cleaned);
260
+ return {
261
+ content: cleaned,
262
+ contentType: "text/html",
263
+ sourceUrl: response.url,
264
+ tokenCount,
265
+ success: true,
266
+ provider: "local",
267
+ };
268
+ }
269
+ /**
270
+ * Handle image response (convert to base64 data URL)
271
+ */
272
+ async function handleImageResponse(response, contentType) {
273
+ const arrayBuffer = await response.arrayBuffer();
274
+ const base64 = Buffer.from(arrayBuffer).toString("base64");
275
+ const base64Url = `data:${contentType};base64,${base64}`;
276
+ return {
277
+ content: base64Url,
278
+ contentType,
279
+ sourceUrl: response.url,
280
+ tokenCount: 0,
281
+ success: true,
282
+ provider: "direct",
283
+ };
284
+ }
285
+ /**
286
+ * Handle text response
287
+ */
288
+ async function handleTextResponse(response, contentType) {
289
+ const text = await response.text();
290
+ const tokenCount = countTokens(text);
291
+ return {
292
+ content: text,
293
+ contentType,
294
+ sourceUrl: response.url,
295
+ tokenCount,
296
+ success: true,
297
+ provider: "direct",
298
+ };
299
+ }
300
+ /**
301
+ * Main fetch function with redirect handling
302
+ */
303
+ async function fetchUrl(url, options) {
304
+ const { useJina = false, timeout = DEFAULT_TIMEOUT, verbose = false, headers: includeHeaders = false, abortSignal, } = options;
305
+ let redirectCount = 0;
306
+ let currentUrl = url;
307
+ while (redirectCount < MAX_REDIRECTS) {
308
+ const { signal, cleanup } = createTimeoutSignal(timeout, abortSignal);
309
+ try {
310
+ // Standard browser headers to avoid 403 errors on bot-protected sites
311
+ const requestHeaders = {
312
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
313
+ // biome-ignore lint/style/useNamingConvention: HTTP header name must match specification
314
+ Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
315
+ "Accept-Language": "en-US,en;q=0.9",
316
+ "Accept-Encoding": "gzip, deflate, br",
317
+ // biome-ignore lint/style/useNamingConvention: HTTP header name must match specification
318
+ Connection: "keep-alive",
319
+ "Upgrade-Insecure-Requests": "1",
320
+ "Sec-Fetch-Dest": "document",
321
+ "Sec-Fetch-Mode": "navigate",
322
+ "Sec-Fetch-Site": "none",
323
+ "Sec-Fetch-User": "?1",
324
+ "Cache-Control": "max-age=0",
325
+ };
326
+ const response = await fetch(currentUrl, {
327
+ signal,
328
+ redirect: "manual",
329
+ headers: requestHeaders,
330
+ });
331
+ // Handle redirects
332
+ if (response.status >= 300 && response.status < 400) {
333
+ const location = response.headers.get("location");
334
+ if (location) {
335
+ const redirectUrl = new URL(location, currentUrl).toString();
336
+ if (verbose) {
337
+ console.error(`Redirecting to: ${redirectUrl}`);
338
+ }
339
+ currentUrl = redirectUrl;
340
+ redirectCount++;
341
+ continue;
342
+ }
343
+ }
344
+ if (!response.ok) {
345
+ throw new Error(`HTTP error! status: ${response.status} ${response.statusText}`);
346
+ }
347
+ const contentType = getContentType(response);
348
+ const responseHeaders = {};
349
+ if (includeHeaders) {
350
+ response.headers.forEach((value, key) => {
351
+ responseHeaders[key] = value;
352
+ });
353
+ }
354
+ let result;
355
+ if (contentType.includes("text/html")) {
356
+ result = await handleHtmlResponse(response, useJina, signal, verbose);
357
+ }
358
+ else if (contentType.startsWith("image/")) {
359
+ result = await handleImageResponse(response, contentType);
360
+ }
361
+ else {
362
+ result = await handleTextResponse(response, contentType);
363
+ }
364
+ if (includeHeaders) {
365
+ result.headers = responseHeaders;
366
+ }
367
+ return result;
368
+ }
369
+ finally {
370
+ cleanup();
371
+ }
372
+ }
373
+ throw new Error(`Too many redirects (max: ${MAX_REDIRECTS})`);
374
+ }
375
+ /**
376
+ * Execute web fetch
377
+ */
378
+ export async function executeWebFetch(options, executionOptions) {
379
+ const { url, output = "text", jina = false, timeout, headers = false, } = options;
380
+ if (executionOptions.abortSignal?.aborted) {
381
+ throw new Error("Web fetch aborted");
382
+ }
383
+ if (!isValidUrl(url)) {
384
+ throw new Error("Invalid URL format. URL must start with http:// or https:// and be less than 2048 characters");
385
+ }
386
+ const effectiveTimeout = timeout ?? DEFAULT_TIMEOUT;
387
+ const effectiveJina = jina ?? false;
388
+ const effectiveHeaders = headers ?? false;
389
+ let result;
390
+ try {
391
+ result = await fetchUrl(url, {
392
+ useJina: effectiveJina,
393
+ timeout: effectiveTimeout,
394
+ verbose: false,
395
+ headers: effectiveHeaders,
396
+ abortSignal: executionOptions.abortSignal,
397
+ });
398
+ }
399
+ catch (error) {
400
+ const errorMessage = error instanceof Error ? error.message : String(error);
401
+ throw new Error(`Web fetch failed: ${errorMessage}`);
402
+ }
403
+ switch (output) {
404
+ case "json": {
405
+ const jsonOutput = {
406
+ content: result.content,
407
+ contentType: result.contentType,
408
+ sourceUrl: result.sourceUrl,
409
+ tokenCount: result.tokenCount,
410
+ success: result.success,
411
+ provider: result.provider,
412
+ };
413
+ if (headers && result.headers) {
414
+ jsonOutput["headers"] = result["headers"];
415
+ }
416
+ return JSON.stringify(jsonOutput, null, 2);
417
+ }
418
+ case "html":
419
+ return result.content;
420
+ case "markdown":
421
+ if (result.contentType.includes("text/html")) {
422
+ return htmlToMarkdown(result.content);
423
+ }
424
+ return result.content;
425
+ default:
426
+ return result.content;
427
+ }
428
+ }
429
+ /**
430
+ * Create the web fetch tool
431
+ */
432
+ export const createWebFetchTool = async () => {
433
+ const toolDescription = "Fetch and extract content from a URL.";
434
+ return {
435
+ toolDef: {
436
+ description: toolDescription,
437
+ inputSchema,
438
+ },
439
+ display({ url }) {
440
+ return `🌐 ${style.cyan(url)}`;
441
+ },
442
+ async execute(options, executionOptions) {
443
+ return executeWebFetch(options, executionOptions);
444
+ },
445
+ };
446
+ };