recker 1.0.43 → 1.0.44-next.084c2ef

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 (464) hide show
  1. package/README.md +47 -0
  2. package/dist/bin/recker-linux-x64 +0 -0
  3. package/dist/bin/recker-macos-x64 +0 -0
  4. package/dist/bin/recker-win-x64.exe +0 -0
  5. package/dist/bin/rek.cjs +85617 -99560
  6. package/dist/browser/ai/adaptive-timeout.d.ts +50 -0
  7. package/dist/browser/ai/adaptive-timeout.js +208 -0
  8. package/dist/browser/ai/client.d.ts +22 -0
  9. package/dist/browser/ai/client.js +294 -0
  10. package/dist/browser/ai/index.d.ts +14 -0
  11. package/dist/browser/ai/index.js +11 -0
  12. package/dist/browser/ai/providers/anthropic.d.ts +63 -0
  13. package/dist/browser/ai/providers/anthropic.js +370 -0
  14. package/dist/browser/ai/providers/base.d.ts +48 -0
  15. package/dist/browser/ai/providers/base.js +150 -0
  16. package/dist/browser/ai/providers/google.d.ts +59 -0
  17. package/dist/browser/ai/providers/google.js +305 -0
  18. package/dist/browser/ai/providers/ollama.d.ts +44 -0
  19. package/dist/browser/ai/providers/ollama.js +240 -0
  20. package/dist/browser/ai/providers/openai.d.ts +64 -0
  21. package/dist/browser/ai/providers/openai.js +298 -0
  22. package/dist/browser/ai/rate-limiter.d.ts +43 -0
  23. package/dist/browser/ai/rate-limiter.js +215 -0
  24. package/dist/browser/ai/vector/index.d.ts +2 -0
  25. package/dist/browser/ai/vector/index.js +2 -0
  26. package/dist/browser/ai/vector/similarity.d.ts +2 -0
  27. package/dist/browser/ai/vector/similarity.js +27 -0
  28. package/dist/browser/ai/vector/store.d.ts +27 -0
  29. package/dist/browser/ai/vector/store.js +82 -0
  30. package/dist/browser/browser/cache.d.ts +2 -40
  31. package/dist/browser/browser/cache.js +2 -199
  32. package/dist/browser/browser/index.d.ts +8 -0
  33. package/dist/browser/browser/index.js +8 -0
  34. package/dist/browser/browser/recker.d.ts +8 -1
  35. package/dist/browser/browser/recker.js +8 -2
  36. package/dist/browser/cache/indexed-db.d.ts +10 -0
  37. package/dist/browser/cache/indexed-db.js +88 -0
  38. package/dist/browser/cache/service-worker-cache.d.ts +18 -0
  39. package/dist/browser/cache/service-worker-cache.js +103 -0
  40. package/dist/browser/cache.d.ts +2 -40
  41. package/dist/browser/cache.js +2 -199
  42. package/dist/browser/constants/user-agents.d.ts +7 -0
  43. package/dist/browser/constants/user-agents.js +7 -0
  44. package/dist/browser/core/client.d.ts +2 -0
  45. package/dist/browser/core/client.js +19 -1
  46. package/dist/browser/index.d.ts +8 -0
  47. package/dist/browser/index.js +8 -0
  48. package/dist/browser/plugins/har-recorder.d.ts +40 -0
  49. package/dist/browser/plugins/har-recorder.js +120 -0
  50. package/dist/browser/plugins/network-simulation.d.ts +7 -0
  51. package/dist/browser/plugins/network-simulation.js +13 -0
  52. package/dist/browser/presets/android.d.ts +2 -0
  53. package/dist/browser/presets/android.js +16 -0
  54. package/dist/browser/presets/anthropic.d.ts +8 -0
  55. package/dist/browser/presets/anthropic.js +27 -0
  56. package/dist/browser/presets/aws.d.ts +19 -0
  57. package/dist/browser/presets/aws.js +68 -0
  58. package/dist/browser/presets/azure-openai.d.ts +10 -0
  59. package/dist/browser/presets/azure-openai.js +35 -0
  60. package/dist/browser/presets/azure.d.ts +41 -0
  61. package/dist/browser/presets/azure.js +104 -0
  62. package/dist/browser/presets/chaturbate.d.ts +2 -0
  63. package/dist/browser/presets/chaturbate.js +17 -0
  64. package/dist/browser/presets/cloudflare.d.ts +12 -0
  65. package/dist/browser/presets/cloudflare.js +39 -0
  66. package/dist/browser/presets/cohere.d.ts +7 -0
  67. package/dist/browser/presets/cohere.js +22 -0
  68. package/dist/browser/presets/deepseek.d.ts +7 -0
  69. package/dist/browser/presets/deepseek.js +22 -0
  70. package/dist/browser/presets/digitalocean.d.ts +5 -0
  71. package/dist/browser/presets/digitalocean.js +16 -0
  72. package/dist/browser/presets/discord.d.ts +6 -0
  73. package/dist/browser/presets/discord.js +17 -0
  74. package/dist/browser/presets/elevenlabs.d.ts +6 -0
  75. package/dist/browser/presets/elevenlabs.js +20 -0
  76. package/dist/browser/presets/enhancers.d.ts +20 -0
  77. package/dist/browser/presets/enhancers.js +85 -0
  78. package/dist/browser/presets/fireworks.d.ts +7 -0
  79. package/dist/browser/presets/fireworks.js +22 -0
  80. package/dist/browser/presets/gcp.d.ts +34 -0
  81. package/dist/browser/presets/gcp.js +91 -0
  82. package/dist/browser/presets/gemini.d.ts +7 -0
  83. package/dist/browser/presets/gemini.js +23 -0
  84. package/dist/browser/presets/github.d.ts +6 -0
  85. package/dist/browser/presets/github.js +17 -0
  86. package/dist/browser/presets/gitlab.d.ts +6 -0
  87. package/dist/browser/presets/gitlab.js +16 -0
  88. package/dist/browser/presets/groq.d.ts +7 -0
  89. package/dist/browser/presets/groq.js +22 -0
  90. package/dist/browser/presets/hubspot.d.ts +9 -0
  91. package/dist/browser/presets/hubspot.js +28 -0
  92. package/dist/browser/presets/huggingface.d.ts +7 -0
  93. package/dist/browser/presets/huggingface.js +23 -0
  94. package/dist/browser/presets/index.d.ts +47 -0
  95. package/dist/browser/presets/index.js +47 -0
  96. package/dist/browser/presets/ios.d.ts +2 -0
  97. package/dist/browser/presets/ios.js +13 -0
  98. package/dist/browser/presets/linear.d.ts +5 -0
  99. package/dist/browser/presets/linear.js +16 -0
  100. package/dist/browser/presets/mailgun.d.ts +7 -0
  101. package/dist/browser/presets/mailgun.js +20 -0
  102. package/dist/browser/presets/meta.d.ts +10 -0
  103. package/dist/browser/presets/meta.js +33 -0
  104. package/dist/browser/presets/mistral.d.ts +7 -0
  105. package/dist/browser/presets/mistral.js +22 -0
  106. package/dist/browser/presets/notion.d.ts +6 -0
  107. package/dist/browser/presets/notion.js +17 -0
  108. package/dist/browser/presets/openai.d.ts +9 -0
  109. package/dist/browser/presets/openai.js +30 -0
  110. package/dist/browser/presets/oracle.d.ts +19 -0
  111. package/dist/browser/presets/oracle.js +117 -0
  112. package/dist/browser/presets/perplexity.d.ts +7 -0
  113. package/dist/browser/presets/perplexity.js +22 -0
  114. package/dist/browser/presets/pinecone.d.ts +8 -0
  115. package/dist/browser/presets/pinecone.js +42 -0
  116. package/dist/browser/presets/registry.d.ts +23 -0
  117. package/dist/browser/presets/registry.js +519 -0
  118. package/dist/browser/presets/replicate.d.ts +7 -0
  119. package/dist/browser/presets/replicate.js +23 -0
  120. package/dist/browser/presets/sendgrid.d.ts +6 -0
  121. package/dist/browser/presets/sendgrid.js +20 -0
  122. package/dist/browser/presets/sentry.d.ts +11 -0
  123. package/dist/browser/presets/sentry.js +48 -0
  124. package/dist/browser/presets/sinch.d.ts +9 -0
  125. package/dist/browser/presets/sinch.js +39 -0
  126. package/dist/browser/presets/slack.d.ts +5 -0
  127. package/dist/browser/presets/slack.js +16 -0
  128. package/dist/browser/presets/square.d.ts +10 -0
  129. package/dist/browser/presets/square.js +33 -0
  130. package/dist/browser/presets/stripe.d.ts +7 -0
  131. package/dist/browser/presets/stripe.js +23 -0
  132. package/dist/browser/presets/supabase.d.ts +6 -0
  133. package/dist/browser/presets/supabase.js +18 -0
  134. package/dist/browser/presets/tiktok.d.ts +10 -0
  135. package/dist/browser/presets/tiktok.js +38 -0
  136. package/dist/browser/presets/together.d.ts +7 -0
  137. package/dist/browser/presets/together.js +22 -0
  138. package/dist/browser/presets/twilio.d.ts +6 -0
  139. package/dist/browser/presets/twilio.js +17 -0
  140. package/dist/browser/presets/vercel.d.ts +6 -0
  141. package/dist/browser/presets/vercel.js +23 -0
  142. package/dist/browser/presets/vultr.d.ts +5 -0
  143. package/dist/browser/presets/vultr.js +16 -0
  144. package/dist/browser/presets/xai.d.ts +8 -0
  145. package/dist/browser/presets/xai.js +23 -0
  146. package/dist/browser/presets/youtube.d.ts +5 -0
  147. package/dist/browser/presets/youtube.js +20 -0
  148. package/dist/browser/recker.d.ts +8 -1
  149. package/dist/browser/recker.js +8 -2
  150. package/dist/browser/scrape/document.d.ts +5 -4
  151. package/dist/browser/scrape/document.js +89 -76
  152. package/dist/browser/scrape/element.d.ts +10 -8
  153. package/dist/browser/scrape/element.js +295 -81
  154. package/dist/browser/scrape/extractors.d.ts +11 -11
  155. package/dist/browser/scrape/extractors.js +145 -113
  156. package/dist/browser/scrape/parser/back.d.ts +1 -0
  157. package/dist/browser/scrape/parser/back.js +3 -0
  158. package/dist/browser/scrape/parser/index.d.ts +20 -0
  159. package/dist/browser/scrape/parser/index.js +19 -0
  160. package/dist/browser/scrape/parser/matcher.d.ts +30 -0
  161. package/dist/browser/scrape/parser/matcher.js +99 -0
  162. package/dist/browser/scrape/parser/nodes/comment.d.ts +12 -0
  163. package/dist/browser/scrape/parser/nodes/comment.js +21 -0
  164. package/dist/browser/scrape/parser/nodes/html.d.ts +110 -0
  165. package/dist/browser/scrape/parser/nodes/html.js +978 -0
  166. package/dist/browser/scrape/parser/nodes/node.d.ts +18 -0
  167. package/dist/browser/scrape/parser/nodes/node.js +31 -0
  168. package/dist/browser/scrape/parser/nodes/text.d.ts +14 -0
  169. package/dist/browser/scrape/parser/nodes/text.js +30 -0
  170. package/dist/browser/scrape/parser/nodes/type.d.ts +6 -0
  171. package/dist/browser/scrape/parser/nodes/type.js +7 -0
  172. package/dist/browser/scrape/parser/parse.d.ts +1 -0
  173. package/dist/browser/scrape/parser/parse.js +1 -0
  174. package/dist/browser/scrape/parser/valid.d.ts +2 -0
  175. package/dist/browser/scrape/parser/valid.js +5 -0
  176. package/dist/browser/scrape/parser/void-tag.d.ts +7 -0
  177. package/dist/browser/scrape/parser/void-tag.js +43 -0
  178. package/dist/browser/scrape/types.d.ts +7 -0
  179. package/dist/browser/seo/analyzer.d.ts +59 -0
  180. package/dist/browser/seo/analyzer.js +1399 -0
  181. package/dist/browser/seo/keywords.d.ts +16 -0
  182. package/dist/browser/seo/keywords.js +55 -0
  183. package/dist/browser/seo/rules/accessibility.d.ts +2 -0
  184. package/dist/browser/seo/rules/accessibility.js +733 -0
  185. package/dist/browser/seo/rules/ai-search.d.ts +2 -0
  186. package/dist/browser/seo/rules/ai-search.js +436 -0
  187. package/dist/browser/seo/rules/analytics.d.ts +2 -0
  188. package/dist/browser/seo/rules/analytics.js +306 -0
  189. package/dist/browser/seo/rules/best-practices.d.ts +2 -0
  190. package/dist/browser/seo/rules/best-practices.js +195 -0
  191. package/dist/browser/seo/rules/canonical.d.ts +12 -0
  192. package/dist/browser/seo/rules/canonical.js +270 -0
  193. package/dist/browser/seo/rules/content.d.ts +2 -0
  194. package/dist/browser/seo/rules/content.js +522 -0
  195. package/dist/browser/seo/rules/crawl.d.ts +2 -0
  196. package/dist/browser/seo/rules/crawl.js +435 -0
  197. package/dist/browser/seo/rules/cwv.d.ts +2 -0
  198. package/dist/browser/seo/rules/cwv.js +248 -0
  199. package/dist/browser/seo/rules/ecommerce.d.ts +2 -0
  200. package/dist/browser/seo/rules/ecommerce.js +312 -0
  201. package/dist/browser/seo/rules/i18n.d.ts +2 -0
  202. package/dist/browser/seo/rules/i18n.js +288 -0
  203. package/dist/browser/seo/rules/images.d.ts +2 -0
  204. package/dist/browser/seo/rules/images.js +255 -0
  205. package/dist/browser/seo/rules/index.d.ts +52 -0
  206. package/dist/browser/seo/rules/index.js +163 -0
  207. package/dist/browser/seo/rules/internal-linking.d.ts +2 -0
  208. package/dist/browser/seo/rules/internal-linking.js +394 -0
  209. package/dist/browser/seo/rules/links.d.ts +2 -0
  210. package/dist/browser/seo/rules/links.js +498 -0
  211. package/dist/browser/seo/rules/local.d.ts +2 -0
  212. package/dist/browser/seo/rules/local.js +289 -0
  213. package/dist/browser/seo/rules/manifest.d.ts +2 -0
  214. package/dist/browser/seo/rules/manifest.js +621 -0
  215. package/dist/browser/seo/rules/meta.d.ts +2 -0
  216. package/dist/browser/seo/rules/meta.js +805 -0
  217. package/dist/browser/seo/rules/mobile.d.ts +2 -0
  218. package/dist/browser/seo/rules/mobile.js +161 -0
  219. package/dist/browser/seo/rules/performance.d.ts +2 -0
  220. package/dist/browser/seo/rules/performance.js +738 -0
  221. package/dist/browser/seo/rules/pwa.d.ts +2 -0
  222. package/dist/browser/seo/rules/pwa.js +299 -0
  223. package/dist/browser/seo/rules/readability.d.ts +2 -0
  224. package/dist/browser/seo/rules/readability.js +264 -0
  225. package/dist/browser/seo/rules/redirects.d.ts +16 -0
  226. package/dist/browser/seo/rules/redirects.js +199 -0
  227. package/dist/browser/seo/rules/resources.d.ts +2 -0
  228. package/dist/browser/seo/rules/resources.js +390 -0
  229. package/dist/browser/seo/rules/schema.d.ts +2 -0
  230. package/dist/browser/seo/rules/schema.js +379 -0
  231. package/dist/browser/seo/rules/security.d.ts +2 -0
  232. package/dist/browser/seo/rules/security.js +877 -0
  233. package/dist/browser/seo/rules/social.d.ts +2 -0
  234. package/dist/browser/seo/rules/social.js +603 -0
  235. package/dist/browser/seo/rules/structural.d.ts +2 -0
  236. package/dist/browser/seo/rules/structural.js +223 -0
  237. package/dist/browser/seo/rules/technical-advanced.d.ts +10 -0
  238. package/dist/browser/seo/rules/technical-advanced.js +289 -0
  239. package/dist/browser/seo/rules/technical.d.ts +3 -0
  240. package/dist/browser/seo/rules/technical.js +509 -0
  241. package/dist/browser/seo/rules/thresholds.d.ts +196 -0
  242. package/dist/browser/seo/rules/thresholds.js +118 -0
  243. package/dist/browser/seo/rules/types.d.ts +518 -0
  244. package/dist/browser/seo/rules/types.js +11 -0
  245. package/dist/browser/seo/types.d.ts +211 -0
  246. package/dist/browser/seo/types.js +1 -0
  247. package/dist/browser/transport/curl.d.ts +4 -0
  248. package/dist/browser/transport/curl.js +101 -0
  249. package/dist/browser/transport/undici.js +1 -2
  250. package/dist/browser/transport/worker.d.ts +18 -0
  251. package/dist/browser/transport/worker.js +278 -0
  252. package/dist/browser/types/index.d.ts +4 -1
  253. package/dist/browser/utils/binary-manager.d.ts +4 -0
  254. package/dist/browser/utils/binary-manager.js +72 -0
  255. package/dist/browser/utils/user-agent.js +2 -13
  256. package/dist/cache/indexed-db.d.ts +10 -0
  257. package/dist/cache/indexed-db.js +88 -0
  258. package/dist/cache/service-worker-cache.d.ts +18 -0
  259. package/dist/cache/service-worker-cache.js +103 -0
  260. package/dist/cli/commands/ai.d.ts +2 -0
  261. package/dist/cli/commands/ai.js +162 -0
  262. package/dist/cli/commands/bench.d.ts +2 -0
  263. package/dist/cli/commands/bench.js +51 -0
  264. package/dist/cli/commands/dns.d.ts +2 -0
  265. package/dist/cli/commands/dns.js +295 -0
  266. package/dist/cli/commands/har.d.ts +2 -0
  267. package/dist/cli/commands/har.js +171 -0
  268. package/dist/cli/commands/hls.d.ts +2 -0
  269. package/dist/cli/commands/hls.js +192 -0
  270. package/dist/cli/commands/network.d.ts +2 -0
  271. package/dist/cli/commands/network.js +288 -0
  272. package/dist/cli/commands/protocols.d.ts +2 -0
  273. package/dist/cli/commands/protocols.js +344 -0
  274. package/dist/cli/commands/scrape.d.ts +2 -0
  275. package/dist/cli/commands/scrape.js +176 -0
  276. package/dist/cli/commands/security.d.ts +2 -0
  277. package/dist/cli/commands/security.js +57 -0
  278. package/dist/cli/commands/seo.d.ts +2 -0
  279. package/dist/cli/commands/seo.js +125 -0
  280. package/dist/cli/commands/serve.d.ts +2 -0
  281. package/dist/cli/commands/serve.js +531 -0
  282. package/dist/cli/commands/spider.d.ts +3 -0
  283. package/dist/cli/commands/spider.js +478 -0
  284. package/dist/cli/commands/utils.d.ts +2 -0
  285. package/dist/cli/commands/utils.js +176 -0
  286. package/dist/cli/commands/vector.d.ts +2 -0
  287. package/dist/cli/commands/vector.js +158 -0
  288. package/dist/cli/handler.d.ts +2 -2
  289. package/dist/cli/handler.js +6 -6
  290. package/dist/cli/helpers.d.ts +7 -0
  291. package/dist/cli/helpers.js +128 -0
  292. package/dist/cli/index.js +96 -5228
  293. package/dist/cli/parser/help.d.ts +2 -0
  294. package/dist/cli/parser/help.js +52 -0
  295. package/dist/cli/parser/index.d.ts +3 -0
  296. package/dist/cli/parser/index.js +3 -0
  297. package/dist/cli/parser/parser.d.ts +4 -0
  298. package/dist/cli/parser/parser.js +146 -0
  299. package/dist/cli/parser/types.d.ts +41 -0
  300. package/dist/cli/parser/types.js +1 -0
  301. package/dist/cli/presets.d.ts +1 -1
  302. package/dist/cli/presets.js +1 -1
  303. package/dist/cli/router.d.ts +36 -0
  304. package/dist/cli/router.js +195 -0
  305. package/dist/cli/tui/ai-chat.js +1 -1
  306. package/dist/cli/tui/commands/context.d.ts +9 -0
  307. package/dist/cli/tui/commands/context.js +1 -0
  308. package/dist/cli/tui/commands/dns.d.ts +10 -0
  309. package/dist/cli/tui/commands/dns.js +461 -0
  310. package/dist/cli/tui/commands/hls.d.ts +2 -0
  311. package/dist/cli/tui/commands/hls.js +162 -0
  312. package/dist/cli/tui/commands/ip.d.ts +2 -0
  313. package/dist/cli/tui/commands/ip.js +45 -0
  314. package/dist/cli/tui/commands/network.d.ts +3 -0
  315. package/dist/cli/tui/commands/network.js +81 -0
  316. package/dist/cli/tui/commands/protocols.d.ts +6 -0
  317. package/dist/cli/tui/commands/protocols.js +531 -0
  318. package/dist/cli/tui/commands/security.d.ts +2 -0
  319. package/dist/cli/tui/commands/security.js +48 -0
  320. package/dist/cli/tui/commands/seo.d.ts +2 -0
  321. package/dist/cli/tui/commands/seo.js +74 -0
  322. package/dist/cli/tui/context.d.ts +12 -0
  323. package/dist/cli/tui/context.js +1 -0
  324. package/dist/cli/tui/shell.d.ts +11 -20
  325. package/dist/cli/tui/shell.js +216 -1873
  326. package/dist/constants/user-agents.d.ts +7 -0
  327. package/dist/constants/user-agents.js +7 -0
  328. package/dist/core/client.d.ts +2 -0
  329. package/dist/core/client.js +19 -1
  330. package/dist/index.d.ts +1 -0
  331. package/dist/index.js +1 -0
  332. package/dist/mcp/cli.js +2 -3
  333. package/dist/mcp/data/embeddings.json +1 -1
  334. package/dist/mcp/tools/network.js +298 -158
  335. package/dist/plugins/har-player.d.ts +23 -0
  336. package/dist/plugins/har-player.js +49 -0
  337. package/dist/plugins/har-recorder.d.ts +37 -3
  338. package/dist/plugins/har-recorder.js +116 -63
  339. package/dist/plugins/network-simulation.d.ts +7 -0
  340. package/dist/plugins/network-simulation.js +13 -0
  341. package/dist/presets/android.d.ts +2 -0
  342. package/dist/presets/android.js +16 -0
  343. package/dist/presets/chaturbate.d.ts +2 -0
  344. package/dist/presets/chaturbate.js +17 -0
  345. package/dist/presets/elevenlabs.d.ts +6 -0
  346. package/dist/presets/elevenlabs.js +20 -0
  347. package/dist/presets/enhancers.d.ts +20 -0
  348. package/dist/presets/enhancers.js +85 -0
  349. package/dist/presets/hubspot.d.ts +9 -0
  350. package/dist/presets/hubspot.js +28 -0
  351. package/dist/presets/index.d.ts +10 -0
  352. package/dist/presets/index.js +10 -0
  353. package/dist/presets/ios.d.ts +2 -0
  354. package/dist/presets/ios.js +13 -0
  355. package/dist/presets/pinecone.d.ts +8 -0
  356. package/dist/presets/pinecone.js +42 -0
  357. package/dist/presets/registry.js +60 -0
  358. package/dist/presets/sendgrid.d.ts +6 -0
  359. package/dist/presets/sendgrid.js +20 -0
  360. package/dist/presets/sentry.d.ts +11 -0
  361. package/dist/presets/sentry.js +48 -0
  362. package/dist/presets/square.d.ts +10 -0
  363. package/dist/presets/square.js +33 -0
  364. package/dist/recker.d.ts +3 -0
  365. package/dist/recker.js +4 -0
  366. package/dist/scrape/document.d.ts +5 -4
  367. package/dist/scrape/document.js +89 -76
  368. package/dist/scrape/element.d.ts +10 -8
  369. package/dist/scrape/element.js +295 -81
  370. package/dist/scrape/extractors.d.ts +11 -11
  371. package/dist/scrape/extractors.js +145 -113
  372. package/dist/scrape/index.d.ts +2 -0
  373. package/dist/scrape/index.js +1 -0
  374. package/dist/scrape/parser/back.d.ts +1 -0
  375. package/dist/scrape/parser/back.js +3 -0
  376. package/dist/scrape/parser/index.d.ts +20 -0
  377. package/dist/scrape/parser/index.js +19 -0
  378. package/dist/scrape/parser/matcher.d.ts +30 -0
  379. package/dist/scrape/parser/matcher.js +99 -0
  380. package/dist/scrape/parser/nodes/comment.d.ts +12 -0
  381. package/dist/scrape/parser/nodes/comment.js +21 -0
  382. package/dist/scrape/parser/nodes/html.d.ts +110 -0
  383. package/dist/scrape/parser/nodes/html.js +978 -0
  384. package/dist/scrape/parser/nodes/node.d.ts +18 -0
  385. package/dist/scrape/parser/nodes/node.js +31 -0
  386. package/dist/scrape/parser/nodes/text.d.ts +14 -0
  387. package/dist/scrape/parser/nodes/text.js +30 -0
  388. package/dist/scrape/parser/nodes/type.d.ts +6 -0
  389. package/dist/scrape/parser/nodes/type.js +7 -0
  390. package/dist/scrape/parser/parse.d.ts +1 -0
  391. package/dist/scrape/parser/parse.js +1 -0
  392. package/dist/scrape/parser/valid.d.ts +2 -0
  393. package/dist/scrape/parser/valid.js +5 -0
  394. package/dist/scrape/parser/void-tag.d.ts +7 -0
  395. package/dist/scrape/parser/void-tag.js +43 -0
  396. package/dist/scrape/spider.d.ts +19 -0
  397. package/dist/scrape/spider.js +28 -3
  398. package/dist/scrape/types.d.ts +7 -0
  399. package/dist/seo/analyzer.d.ts +15 -5
  400. package/dist/seo/analyzer.js +636 -175
  401. package/dist/seo/formatter.d.ts +16 -0
  402. package/dist/seo/formatter.js +228 -0
  403. package/dist/seo/index.d.ts +2 -0
  404. package/dist/seo/index.js +1 -0
  405. package/dist/seo/keywords.d.ts +16 -0
  406. package/dist/seo/keywords.js +55 -0
  407. package/dist/seo/rules/accessibility.js +96 -57
  408. package/dist/seo/rules/ai-search.js +44 -31
  409. package/dist/seo/rules/analytics.d.ts +2 -0
  410. package/dist/seo/rules/analytics.js +306 -0
  411. package/dist/seo/rules/best-practices.js +21 -14
  412. package/dist/seo/rules/canonical.js +53 -32
  413. package/dist/seo/rules/content.js +317 -31
  414. package/dist/seo/rules/crawl.js +55 -40
  415. package/dist/seo/rules/cwv.js +21 -15
  416. package/dist/seo/rules/ecommerce.js +82 -22
  417. package/dist/seo/rules/i18n.js +75 -36
  418. package/dist/seo/rules/images.js +109 -30
  419. package/dist/seo/rules/index.js +7 -1
  420. package/dist/seo/rules/internal-linking.js +58 -39
  421. package/dist/seo/rules/links.js +79 -52
  422. package/dist/seo/rules/local.js +49 -25
  423. package/dist/seo/rules/manifest.d.ts +2 -0
  424. package/dist/seo/rules/manifest.js +621 -0
  425. package/dist/seo/rules/meta.js +339 -81
  426. package/dist/seo/rules/mobile.js +112 -2
  427. package/dist/seo/rules/performance.js +434 -66
  428. package/dist/seo/rules/pwa.js +36 -39
  429. package/dist/seo/rules/readability.js +31 -22
  430. package/dist/seo/rules/redirects.js +21 -15
  431. package/dist/seo/rules/resources.js +59 -42
  432. package/dist/seo/rules/schema.js +333 -8
  433. package/dist/seo/rules/security.js +142 -80
  434. package/dist/seo/rules/social.js +277 -47
  435. package/dist/seo/rules/structural.js +87 -19
  436. package/dist/seo/rules/technical-advanced.js +30 -24
  437. package/dist/seo/rules/technical.d.ts +1 -0
  438. package/dist/seo/rules/technical.js +272 -42
  439. package/dist/seo/rules/types.d.ts +74 -2
  440. package/dist/seo/seo-spider.d.ts +35 -0
  441. package/dist/seo/seo-spider.js +152 -13
  442. package/dist/seo/types.d.ts +8 -1
  443. package/dist/seo/validators/llms-txt.js +19 -0
  444. package/dist/seo/validators/rss.d.ts +11 -0
  445. package/dist/seo/validators/rss.js +93 -0
  446. package/dist/seo/validators/sitemap.js +36 -26
  447. package/dist/transport/curl.d.ts +4 -0
  448. package/dist/transport/curl.js +101 -0
  449. package/dist/transport/udp.js +0 -1
  450. package/dist/transport/undici.js +1 -2
  451. package/dist/transport/worker.d.ts +18 -0
  452. package/dist/transport/worker.js +278 -0
  453. package/dist/types/index.d.ts +4 -1
  454. package/dist/utils/binary-manager.d.ts +4 -0
  455. package/dist/utils/binary-manager.js +72 -0
  456. package/dist/utils/optional-require.d.ts +7 -8
  457. package/dist/utils/optional-require.js +2 -21
  458. package/dist/utils/upload.d.ts +6 -0
  459. package/dist/utils/upload.js +11 -0
  460. package/dist/utils/user-agent.js +2 -13
  461. package/dist/version.js +1 -1
  462. package/package.json +12 -6
  463. package/dist/browser/utils/optional-require.d.ts +0 -19
  464. package/dist/browser/utils/optional-require.js +0 -105
@@ -0,0 +1,72 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { homedir, platform, arch } from 'node:os';
4
+ import { spawn } from 'node:child_process';
5
+ import { createWriteStream } from 'node:fs';
6
+ import { Readable } from 'node:stream';
7
+ import { finished } from 'node:stream/promises';
8
+ const BIN_DIR = join(homedir(), '.recker', 'bin');
9
+ const VERSION = 'v0.6.1';
10
+ export function getCurlBinName() {
11
+ return 'curl-impersonate-chrome';
12
+ }
13
+ export function getCurlPath() {
14
+ return join(BIN_DIR, getCurlBinName());
15
+ }
16
+ export async function hasImpersonate() {
17
+ try {
18
+ await fs.access(getCurlPath());
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ function getDownloadUrl() {
26
+ const p = platform();
27
+ const a = arch();
28
+ const baseUrl = `https://github.com/lwthiker/curl-impersonate/releases/download/${VERSION}`;
29
+ if (p === 'linux') {
30
+ if (a === 'x64')
31
+ return `${baseUrl}/curl-impersonate-${VERSION}.x86_64-linux-gnu.tar.gz`;
32
+ if (a === 'arm64')
33
+ return `${baseUrl}/curl-impersonate-${VERSION}.aarch64-linux-gnu.tar.gz`;
34
+ }
35
+ if (p === 'darwin') {
36
+ throw new Error('Auto-install not yet supported on macOS. Please install curl-impersonate manually.');
37
+ }
38
+ if (p === 'win32') {
39
+ throw new Error('Auto-install not yet supported on Windows.');
40
+ }
41
+ throw new Error(`Unsupported platform: ${p} ${a}`);
42
+ }
43
+ export async function installCurlImpersonate(logger = console) {
44
+ const url = getDownloadUrl();
45
+ const tarPath = join(BIN_DIR, 'curl-impersonate.tar.gz');
46
+ await fs.mkdir(BIN_DIR, { recursive: true });
47
+ logger.log(`Downloading curl-impersonate from ${url}...`);
48
+ const res = await fetch(url);
49
+ if (!res.ok)
50
+ throw new Error(`Failed to download: ${res.statusText}`);
51
+ if (!res.body)
52
+ throw new Error('Empty body');
53
+ const fileStream = createWriteStream(tarPath);
54
+ await finished(Readable.fromWeb(res.body).pipe(fileStream));
55
+ logger.log('Extracting...');
56
+ await new Promise((resolve, reject) => {
57
+ const tar = spawn('tar', ['-xzf', tarPath, '-C', BIN_DIR]);
58
+ tar.on('close', (code) => {
59
+ if (code === 0)
60
+ resolve();
61
+ else
62
+ reject(new Error(`Tar exited with code ${code}`));
63
+ });
64
+ });
65
+ await fs.unlink(tarPath);
66
+ if (await hasImpersonate()) {
67
+ logger.log(`✅ Installed to ${getCurlPath()}`);
68
+ }
69
+ else {
70
+ throw new Error('Installation failed: Binary not found after extraction');
71
+ }
72
+ }
@@ -1,17 +1,6 @@
1
- import { readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- let RECKER_VERSION = '1.0.0';
4
- try {
5
- const pkgPath = join(process.cwd(), 'package.json');
6
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
7
- if (pkg.name === 'recker' && pkg.version) {
8
- RECKER_VERSION = pkg.version;
9
- }
10
- }
11
- catch {
12
- }
1
+ const VERSION = '0.0.0-dev';
13
2
  export function getDefaultUserAgent() {
14
- return `recker/${RECKER_VERSION}`;
3
+ return `recker/${VERSION}`;
15
4
  }
16
5
  export const USER_AGENT_PRESETS = {
17
6
  chrome_windows: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
@@ -0,0 +1,10 @@
1
+ import type { CacheStorage, CacheEntry } from '../types/index.js';
2
+ export declare class IndexedDBStorage implements CacheStorage {
3
+ private dbPromise;
4
+ constructor(dbName?: string);
5
+ private openDB;
6
+ get(key: string): Promise<CacheEntry | undefined | null>;
7
+ set(key: string, value: CacheEntry, ttl: number): Promise<void>;
8
+ delete(key: string): Promise<void>;
9
+ clear(): Promise<void>;
10
+ }
@@ -0,0 +1,88 @@
1
+ const DB_NAME = 'recker-cache';
2
+ const STORE_NAME = 'entries';
3
+ const DB_VERSION = 1;
4
+ export class IndexedDBStorage {
5
+ dbPromise;
6
+ constructor(dbName = DB_NAME) {
7
+ this.dbPromise = this.openDB(dbName);
8
+ }
9
+ openDB(dbName) {
10
+ return new Promise((resolve, reject) => {
11
+ if (typeof indexedDB === 'undefined') {
12
+ reject(new Error('IndexedDB is not supported in this environment'));
13
+ return;
14
+ }
15
+ const request = indexedDB.open(dbName, DB_VERSION);
16
+ request.onupgradeneeded = (event) => {
17
+ const db = event.target.result;
18
+ if (!db.objectStoreNames.contains(STORE_NAME)) {
19
+ db.createObjectStore(STORE_NAME, { keyPath: 'key' });
20
+ }
21
+ };
22
+ request.onsuccess = (event) => {
23
+ resolve(event.target.result);
24
+ };
25
+ request.onerror = (event) => {
26
+ reject(event.target.error);
27
+ };
28
+ });
29
+ }
30
+ async get(key) {
31
+ const db = await this.dbPromise;
32
+ return new Promise((resolve, reject) => {
33
+ const transaction = db.transaction(STORE_NAME, 'readonly');
34
+ const store = transaction.objectStore(STORE_NAME);
35
+ const request = store.get(key);
36
+ request.onsuccess = () => {
37
+ const result = request.result;
38
+ if (!result) {
39
+ resolve(null);
40
+ return;
41
+ }
42
+ if (result.expiresAt && Date.now() > result.expiresAt) {
43
+ this.delete(key).catch(() => { });
44
+ resolve(null);
45
+ return;
46
+ }
47
+ resolve(result.value);
48
+ };
49
+ request.onerror = () => reject(request.error);
50
+ });
51
+ }
52
+ async set(key, value, ttl) {
53
+ const db = await this.dbPromise;
54
+ return new Promise((resolve, reject) => {
55
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
56
+ const store = transaction.objectStore(STORE_NAME);
57
+ const expiresAt = Date.now() + ttl;
58
+ const item = {
59
+ key,
60
+ value,
61
+ expiresAt
62
+ };
63
+ const request = store.put(item);
64
+ request.onsuccess = () => resolve();
65
+ request.onerror = () => reject(request.error);
66
+ });
67
+ }
68
+ async delete(key) {
69
+ const db = await this.dbPromise;
70
+ return new Promise((resolve, reject) => {
71
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
72
+ const store = transaction.objectStore(STORE_NAME);
73
+ const request = store.delete(key);
74
+ request.onsuccess = () => resolve();
75
+ request.onerror = () => reject(request.error);
76
+ });
77
+ }
78
+ async clear() {
79
+ const db = await this.dbPromise;
80
+ return new Promise((resolve, reject) => {
81
+ const transaction = db.transaction(STORE_NAME, 'readwrite');
82
+ const store = transaction.objectStore(STORE_NAME);
83
+ const request = store.clear();
84
+ request.onsuccess = () => resolve();
85
+ request.onerror = () => reject(request.error);
86
+ });
87
+ }
88
+ }
@@ -0,0 +1,18 @@
1
+ import type { CacheStorage, CacheEntry } from '../types/index.js';
2
+ export declare class ServiceWorkerCache implements CacheStorage {
3
+ private cacheName;
4
+ private cachePromise;
5
+ constructor(options?: {
6
+ cacheName?: string;
7
+ });
8
+ static isSupported(): boolean;
9
+ private getCache;
10
+ private keyToUrl;
11
+ get(key: string): Promise<CacheEntry | undefined | null>;
12
+ set(key: string, value: CacheEntry, ttl: number): Promise<void>;
13
+ delete(key: string): Promise<void>;
14
+ clear(): Promise<void>;
15
+ keys(): Promise<string[]>;
16
+ size(): Promise<number>;
17
+ prune(): Promise<number>;
18
+ }
@@ -0,0 +1,103 @@
1
+ const CACHE_NAME = 'recker-cache-v1';
2
+ export class ServiceWorkerCache {
3
+ cacheName;
4
+ cachePromise = null;
5
+ constructor(options = {}) {
6
+ this.cacheName = options.cacheName || CACHE_NAME;
7
+ }
8
+ static isSupported() {
9
+ return typeof caches !== 'undefined';
10
+ }
11
+ async getCache() {
12
+ if (!this.cachePromise) {
13
+ if (!ServiceWorkerCache.isSupported()) {
14
+ throw new Error('Cache API is not supported in this environment');
15
+ }
16
+ this.cachePromise = caches.open(this.cacheName);
17
+ }
18
+ return this.cachePromise;
19
+ }
20
+ keyToUrl(key) {
21
+ return `https://recker-cache.local/${encodeURIComponent(key)}`;
22
+ }
23
+ async get(key) {
24
+ try {
25
+ const cache = await this.getCache();
26
+ const url = this.keyToUrl(key);
27
+ const response = await cache.match(url);
28
+ if (!response) {
29
+ return null;
30
+ }
31
+ const data = await response.json();
32
+ if (data.expiresAt && Date.now() > data.expiresAt) {
33
+ this.delete(key).catch(() => { });
34
+ return null;
35
+ }
36
+ return data.entry;
37
+ }
38
+ catch {
39
+ return null;
40
+ }
41
+ }
42
+ async set(key, value, ttl) {
43
+ const cache = await this.getCache();
44
+ const url = this.keyToUrl(key);
45
+ const item = {
46
+ entry: value,
47
+ expiresAt: Date.now() + ttl,
48
+ };
49
+ const response = new Response(JSON.stringify(item), {
50
+ headers: {
51
+ 'Content-Type': 'application/json',
52
+ 'X-Recker-Cache': 'true',
53
+ 'X-Recker-Expires': String(item.expiresAt),
54
+ },
55
+ });
56
+ await cache.put(url, response);
57
+ }
58
+ async delete(key) {
59
+ const cache = await this.getCache();
60
+ const url = this.keyToUrl(key);
61
+ await cache.delete(url);
62
+ }
63
+ async clear() {
64
+ await caches.delete(this.cacheName);
65
+ this.cachePromise = null;
66
+ }
67
+ async keys() {
68
+ const cache = await this.getCache();
69
+ const requests = await cache.keys();
70
+ return requests
71
+ .map((req) => {
72
+ const url = new URL(req.url);
73
+ return decodeURIComponent(url.pathname.slice(1));
74
+ })
75
+ .filter((key) => key.length > 0);
76
+ }
77
+ async size() {
78
+ const keys = await this.keys();
79
+ return keys.length;
80
+ }
81
+ async prune() {
82
+ const cache = await this.getCache();
83
+ const requests = await cache.keys();
84
+ let removed = 0;
85
+ for (const request of requests) {
86
+ const response = await cache.match(request);
87
+ if (response) {
88
+ try {
89
+ const data = await response.json();
90
+ if (data.expiresAt && Date.now() > data.expiresAt) {
91
+ await cache.delete(request);
92
+ removed++;
93
+ }
94
+ }
95
+ catch {
96
+ await cache.delete(request);
97
+ removed++;
98
+ }
99
+ }
100
+ }
101
+ return removed;
102
+ }
103
+ }
@@ -0,0 +1,2 @@
1
+ import { RekCommand as Command } from '../router.js';
2
+ export declare function registerAiCommand(program: Command): void;
@@ -0,0 +1,162 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import colors from '../../utils/colors.js';
4
+ import { loadEnvFile } from '../helpers.js';
5
+ import { resolvePreset } from '../presets.js';
6
+ export function registerAiCommand(program) {
7
+ program
8
+ .command('ai')
9
+ .alias('chat')
10
+ .alias('ask')
11
+ .description('Chat with AI models (OpenAI, Claude, Groq, etc)')
12
+ .argument('<preset>', 'AI preset to use (e.g., @openai, @anthropic, @groq)')
13
+ .argument('<prompt...>', 'The prompt and options: "prompt text" model=<model> temperature=<temp> max-tokens=<tokens> wait json env=<path>')
14
+ .addHelpText('after', `
15
+ ${colors.bold(colors.blue('What it does:'))}
16
+ Sends a prompt to an AI language model and streams the response back.
17
+ Supports all major AI providers including OpenAI, Anthropic, Google, Groq,
18
+ Mistral, and more. API keys are loaded from environment variables.
19
+
20
+ Each provider uses sensible defaults but you can override the model,
21
+ temperature, and max tokens. Responses stream in real-time by default.
22
+
23
+ ${colors.bold(colors.yellow('Options:'))}
24
+ ${colors.cyan('model=<model>')} Override default model
25
+ ${colors.cyan('temperature=<temp>')} Temperature (0-1, default: 0.7)
26
+ ${colors.cyan('max-tokens=<tokens>')} Max tokens in response (default: 2048)
27
+ ${colors.cyan('wait')} Wait for full response (disable streaming)
28
+ ${colors.cyan('json')} Output raw JSON response
29
+ ${colors.cyan('env=<path>')} Load .env file (auto-loads from cwd if exists)
30
+
31
+ ${colors.bold(colors.yellow('Examples:'))}
32
+ ${colors.green('$ rek ai @openai "What is the capital of France?"')}
33
+ ${colors.green('$ rek ai @anthropic "Explain quantum computing" model=claude-sonnet-4-20250514')}
34
+ ${colors.green('$ rek ai @groq "Write a haiku" wait')}
35
+ ${colors.green('$ rek ai @openai "Translate to Spanish: Hello world"')}
36
+
37
+ ${colors.bold(colors.yellow('Available AI Presets:'))}
38
+ ${colors.cyan('@openai')} OpenAI (GPT-4o, GPT-5.1)
39
+ ${colors.cyan('@anthropic')} Anthropic (Claude)
40
+ ${colors.cyan('@groq')} Groq (fast inference)
41
+ ${colors.cyan('@google')} Google (Gemini)
42
+ ${colors.cyan('@xai')} xAI (Grok)
43
+ ${colors.cyan('@mistral')} Mistral AI
44
+ ${colors.cyan('@cohere')} Cohere
45
+ ${colors.cyan('@deepseek')} DeepSeek
46
+ ${colors.cyan('@perplexity')} Perplexity
47
+ ${colors.cyan('@together')} Together AI
48
+ ${colors.cyan('@fireworks')} Fireworks AI
49
+ ${colors.cyan('@replicate')} Replicate
50
+ ${colors.cyan('@huggingface')} Hugging Face
51
+
52
+ ${colors.bold(colors.yellow('Note:'))}
53
+ This command sends a single prompt without conversation memory.
54
+ For chat with memory, use: ${colors.cyan('rek shell')} then ${colors.cyan('@openai Your message')}
55
+ `)
56
+ .action(async (preset, promptParts) => {
57
+ let model;
58
+ let temperature = '0.7';
59
+ let maxTokens = '2048';
60
+ let wait = false;
61
+ let jsonOutput = false;
62
+ let envPath;
63
+ const actualPromptParts = [];
64
+ for (const part of promptParts) {
65
+ if (part.startsWith('model='))
66
+ model = part.split('=')[1];
67
+ else if (part.startsWith('temperature='))
68
+ temperature = part.split('=')[1];
69
+ else if (part.startsWith('max-tokens='))
70
+ maxTokens = part.split('=')[1];
71
+ else if (part === 'wait')
72
+ wait = true;
73
+ else if (part === 'json')
74
+ jsonOutput = true;
75
+ else if (part.startsWith('env='))
76
+ envPath = part.split('=')[1];
77
+ else if (part === 'env')
78
+ envPath = true;
79
+ else
80
+ actualPromptParts.push(part);
81
+ }
82
+ if (envPath !== undefined) {
83
+ await loadEnvFile(envPath);
84
+ }
85
+ else {
86
+ try {
87
+ const envFilePath = join(process.cwd(), '.env');
88
+ await fs.access(envFilePath);
89
+ await loadEnvFile(true);
90
+ }
91
+ catch {
92
+ }
93
+ }
94
+ let presetName = preset;
95
+ if (presetName.startsWith('@')) {
96
+ presetName = presetName.slice(1);
97
+ }
98
+ const presetConfig = await resolvePreset(presetName);
99
+ if (!presetConfig) {
100
+ console.error(colors.red(`Unknown AI preset: @${presetName}`));
101
+ console.log(colors.gray('Available AI presets: @openai, @anthropic, @groq, @google, @xai, @mistral, @cohere'));
102
+ process.exit(1);
103
+ }
104
+ if (!presetConfig._aiConfig) {
105
+ console.error(colors.red(`Preset @${presetName} does not support AI features.`));
106
+ console.log(colors.gray('Use an AI preset like @openai, @anthropic, @groq, etc.'));
107
+ process.exit(1);
108
+ }
109
+ const prompt = actualPromptParts.join(' ');
110
+ if (!prompt.trim()) {
111
+ console.error(colors.red('Error: Prompt is required'));
112
+ process.exit(1);
113
+ }
114
+ try {
115
+ const { createClient } = await import('../../core/client.js');
116
+ const client = createClient(presetConfig);
117
+ if (model) {
118
+ client.ai.setMemoryConfig({ systemPrompt: undefined });
119
+ client._aiConfig.model = model;
120
+ }
121
+ if (!jsonOutput) {
122
+ console.log(colors.gray(`Using @${presetName} (${client._aiConfig.model})...
123
+ `));
124
+ }
125
+ if (wait || jsonOutput) {
126
+ const response = await client.ai.prompt(prompt);
127
+ if (jsonOutput) {
128
+ console.log(JSON.stringify({
129
+ content: response.content,
130
+ model: response.model,
131
+ usage: response.usage,
132
+ finishReason: response.finishReason,
133
+ }, null, 2));
134
+ }
135
+ else {
136
+ console.log(response.content);
137
+ if (response.usage) {
138
+ console.log(colors.gray(`
139
+ ─────────────────────────────────────────`));
140
+ console.log(colors.gray(`Tokens: ${response.usage.inputTokens} in / ${response.usage.outputTokens} out`));
141
+ }
142
+ }
143
+ }
144
+ else {
145
+ const stream = await client.ai.promptStream(prompt);
146
+ for await (const event of stream) {
147
+ if (event.type === 'text') {
148
+ process.stdout.write(event.content);
149
+ }
150
+ }
151
+ console.log('');
152
+ }
153
+ }
154
+ catch (error) {
155
+ console.error(colors.red(`AI request failed: ${error.message}`));
156
+ if (error.cause) {
157
+ console.error(colors.gray(error.cause.message || error.cause));
158
+ }
159
+ process.exit(1);
160
+ }
161
+ });
162
+ }
@@ -0,0 +1,2 @@
1
+ import { RekCommand as Command } from '../router.js';
2
+ export declare function registerBenchCommand(program: Command): void;
@@ -0,0 +1,51 @@
1
+ import colors from '../../utils/colors.js';
2
+ import { RekArgs, generateHelp } from '../parser/index.js';
3
+ const loadSchema = {
4
+ name: 'load',
5
+ description: 'Run a load test with real-time dashboard',
6
+ params: {
7
+ users: { type: 'number', default: 50, description: 'Number of concurrent users' },
8
+ duration: { type: 'number', default: 300, description: 'Test duration in seconds' },
9
+ ramp: { type: 'number', default: 5, description: 'Ramp-up time in seconds' },
10
+ mode: { type: 'string', default: 'throughput', choices: ['throughput', 'stress', 'realistic'], description: 'Test mode' },
11
+ },
12
+ flags: {
13
+ http2: { description: 'Force HTTP/2', default: false }
14
+ },
15
+ examples: [
16
+ { cmd: 'rek bench load httpbin.org/get users=100 duration=60', desc: '100 users for 60s' },
17
+ { cmd: 'rek bench load https://api.com/heavy mode=stress', desc: 'Stress test' }
18
+ ]
19
+ };
20
+ export function registerBenchCommand(program) {
21
+ const bench = program.command('bench').description('Performance benchmarking tools');
22
+ bench
23
+ .command('load')
24
+ .description(loadSchema.description)
25
+ .argument('[args...]', 'URL and options (users=10 duration=10s...)')
26
+ .addHelpText('after', generateHelp(loadSchema))
27
+ .action(async (rawArgs) => {
28
+ const { data, options, args } = RekArgs.parse(rawArgs, loadSchema);
29
+ let url = '';
30
+ for (const arg of args) {
31
+ if (typeof arg === 'string' && !url && (arg.includes('.') || arg.includes('localhost'))) {
32
+ url = arg;
33
+ }
34
+ }
35
+ if (!url) {
36
+ console.error(colors.red('Error: URL is required. Example: rek bench load httpbin.org users=50'));
37
+ process.exit(1);
38
+ }
39
+ if (!url.startsWith('http'))
40
+ url = `https://${url}`;
41
+ const { startLoadDashboard } = await import('../tui/load-dashboard.js');
42
+ await startLoadDashboard({
43
+ url,
44
+ users: data.users,
45
+ duration: data.duration,
46
+ mode: data.mode,
47
+ http2: !!(options.http2 || data.http2),
48
+ rampUp: data.ramp
49
+ });
50
+ });
51
+ }
@@ -0,0 +1,2 @@
1
+ import { RekCommand as Command } from '../router.js';
2
+ export declare function registerDnsCommands(program: Command): void;