recker 1.0.42 → 1.0.43-next.0b080a5

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 (459) 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 +94465 -0
  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 +159 -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/meta.d.ts +2 -0
  214. package/dist/browser/seo/rules/meta.js +805 -0
  215. package/dist/browser/seo/rules/mobile.d.ts +2 -0
  216. package/dist/browser/seo/rules/mobile.js +161 -0
  217. package/dist/browser/seo/rules/performance.d.ts +2 -0
  218. package/dist/browser/seo/rules/performance.js +738 -0
  219. package/dist/browser/seo/rules/pwa.d.ts +2 -0
  220. package/dist/browser/seo/rules/pwa.js +299 -0
  221. package/dist/browser/seo/rules/readability.d.ts +2 -0
  222. package/dist/browser/seo/rules/readability.js +264 -0
  223. package/dist/browser/seo/rules/redirects.d.ts +16 -0
  224. package/dist/browser/seo/rules/redirects.js +199 -0
  225. package/dist/browser/seo/rules/resources.d.ts +2 -0
  226. package/dist/browser/seo/rules/resources.js +390 -0
  227. package/dist/browser/seo/rules/schema.d.ts +2 -0
  228. package/dist/browser/seo/rules/schema.js +379 -0
  229. package/dist/browser/seo/rules/security.d.ts +2 -0
  230. package/dist/browser/seo/rules/security.js +877 -0
  231. package/dist/browser/seo/rules/social.d.ts +2 -0
  232. package/dist/browser/seo/rules/social.js +603 -0
  233. package/dist/browser/seo/rules/structural.d.ts +2 -0
  234. package/dist/browser/seo/rules/structural.js +223 -0
  235. package/dist/browser/seo/rules/technical-advanced.d.ts +10 -0
  236. package/dist/browser/seo/rules/technical-advanced.js +289 -0
  237. package/dist/browser/seo/rules/technical.d.ts +2 -0
  238. package/dist/browser/seo/rules/technical.js +480 -0
  239. package/dist/browser/seo/rules/thresholds.d.ts +196 -0
  240. package/dist/browser/seo/rules/thresholds.js +118 -0
  241. package/dist/browser/seo/rules/types.d.ts +498 -0
  242. package/dist/browser/seo/rules/types.js +11 -0
  243. package/dist/browser/seo/types.d.ts +211 -0
  244. package/dist/browser/seo/types.js +1 -0
  245. package/dist/browser/transport/curl.d.ts +4 -0
  246. package/dist/browser/transport/curl.js +101 -0
  247. package/dist/browser/transport/undici.js +1 -2
  248. package/dist/browser/transport/worker.d.ts +18 -0
  249. package/dist/browser/transport/worker.js +278 -0
  250. package/dist/browser/types/index.d.ts +4 -1
  251. package/dist/browser/utils/binary-manager.d.ts +4 -0
  252. package/dist/browser/utils/binary-manager.js +72 -0
  253. package/dist/browser/utils/user-agent.js +2 -13
  254. package/dist/cache/indexed-db.d.ts +10 -0
  255. package/dist/cache/indexed-db.js +88 -0
  256. package/dist/cache/service-worker-cache.d.ts +18 -0
  257. package/dist/cache/service-worker-cache.js +103 -0
  258. package/dist/cli/commands/ai.d.ts +2 -0
  259. package/dist/cli/commands/ai.js +162 -0
  260. package/dist/cli/commands/bench.d.ts +2 -0
  261. package/dist/cli/commands/bench.js +51 -0
  262. package/dist/cli/commands/dns.d.ts +2 -0
  263. package/dist/cli/commands/dns.js +295 -0
  264. package/dist/cli/commands/har.d.ts +2 -0
  265. package/dist/cli/commands/har.js +171 -0
  266. package/dist/cli/commands/hls.d.ts +2 -0
  267. package/dist/cli/commands/hls.js +192 -0
  268. package/dist/cli/commands/network.d.ts +2 -0
  269. package/dist/cli/commands/network.js +288 -0
  270. package/dist/cli/commands/protocols.d.ts +2 -0
  271. package/dist/cli/commands/protocols.js +344 -0
  272. package/dist/cli/commands/scrape.d.ts +2 -0
  273. package/dist/cli/commands/scrape.js +176 -0
  274. package/dist/cli/commands/security.d.ts +2 -0
  275. package/dist/cli/commands/security.js +57 -0
  276. package/dist/cli/commands/seo.d.ts +2 -0
  277. package/dist/cli/commands/seo.js +125 -0
  278. package/dist/cli/commands/serve.d.ts +2 -0
  279. package/dist/cli/commands/serve.js +531 -0
  280. package/dist/cli/commands/spider.d.ts +3 -0
  281. package/dist/cli/commands/spider.js +456 -0
  282. package/dist/cli/commands/utils.d.ts +2 -0
  283. package/dist/cli/commands/utils.js +176 -0
  284. package/dist/cli/commands/vector.d.ts +2 -0
  285. package/dist/cli/commands/vector.js +158 -0
  286. package/dist/cli/handler.d.ts +2 -2
  287. package/dist/cli/handler.js +6 -6
  288. package/dist/cli/helpers.d.ts +7 -0
  289. package/dist/cli/helpers.js +128 -0
  290. package/dist/cli/index.js +96 -5228
  291. package/dist/cli/parser/help.d.ts +2 -0
  292. package/dist/cli/parser/help.js +52 -0
  293. package/dist/cli/parser/index.d.ts +3 -0
  294. package/dist/cli/parser/index.js +3 -0
  295. package/dist/cli/parser/parser.d.ts +4 -0
  296. package/dist/cli/parser/parser.js +146 -0
  297. package/dist/cli/parser/types.d.ts +41 -0
  298. package/dist/cli/parser/types.js +1 -0
  299. package/dist/cli/presets.d.ts +1 -1
  300. package/dist/cli/presets.js +1 -1
  301. package/dist/cli/router.d.ts +36 -0
  302. package/dist/cli/router.js +195 -0
  303. package/dist/cli/tui/ai-chat.js +1 -1
  304. package/dist/cli/tui/commands/context.d.ts +9 -0
  305. package/dist/cli/tui/commands/context.js +1 -0
  306. package/dist/cli/tui/commands/dns.d.ts +10 -0
  307. package/dist/cli/tui/commands/dns.js +461 -0
  308. package/dist/cli/tui/commands/hls.d.ts +2 -0
  309. package/dist/cli/tui/commands/hls.js +162 -0
  310. package/dist/cli/tui/commands/ip.d.ts +2 -0
  311. package/dist/cli/tui/commands/ip.js +45 -0
  312. package/dist/cli/tui/commands/network.d.ts +3 -0
  313. package/dist/cli/tui/commands/network.js +81 -0
  314. package/dist/cli/tui/commands/protocols.d.ts +6 -0
  315. package/dist/cli/tui/commands/protocols.js +531 -0
  316. package/dist/cli/tui/commands/security.d.ts +2 -0
  317. package/dist/cli/tui/commands/security.js +48 -0
  318. package/dist/cli/tui/commands/seo.d.ts +2 -0
  319. package/dist/cli/tui/commands/seo.js +74 -0
  320. package/dist/cli/tui/context.d.ts +12 -0
  321. package/dist/cli/tui/context.js +1 -0
  322. package/dist/cli/tui/shell.d.ts +11 -20
  323. package/dist/cli/tui/shell.js +216 -1873
  324. package/dist/constants/user-agents.d.ts +7 -0
  325. package/dist/constants/user-agents.js +7 -0
  326. package/dist/core/client.d.ts +2 -0
  327. package/dist/core/client.js +19 -1
  328. package/dist/index.d.ts +1 -0
  329. package/dist/index.js +1 -0
  330. package/dist/mcp/cli.js +2 -3
  331. package/dist/mcp/data/embeddings.json +1 -0
  332. package/dist/mcp/tools/network.js +298 -158
  333. package/dist/plugins/har-player.d.ts +23 -0
  334. package/dist/plugins/har-player.js +49 -0
  335. package/dist/plugins/har-recorder.d.ts +37 -3
  336. package/dist/plugins/har-recorder.js +116 -63
  337. package/dist/plugins/network-simulation.d.ts +7 -0
  338. package/dist/plugins/network-simulation.js +13 -0
  339. package/dist/presets/android.d.ts +2 -0
  340. package/dist/presets/android.js +16 -0
  341. package/dist/presets/chaturbate.d.ts +2 -0
  342. package/dist/presets/chaturbate.js +17 -0
  343. package/dist/presets/elevenlabs.d.ts +6 -0
  344. package/dist/presets/elevenlabs.js +20 -0
  345. package/dist/presets/enhancers.d.ts +20 -0
  346. package/dist/presets/enhancers.js +85 -0
  347. package/dist/presets/hubspot.d.ts +9 -0
  348. package/dist/presets/hubspot.js +28 -0
  349. package/dist/presets/index.d.ts +10 -0
  350. package/dist/presets/index.js +10 -0
  351. package/dist/presets/ios.d.ts +2 -0
  352. package/dist/presets/ios.js +13 -0
  353. package/dist/presets/pinecone.d.ts +8 -0
  354. package/dist/presets/pinecone.js +42 -0
  355. package/dist/presets/registry.js +60 -0
  356. package/dist/presets/sendgrid.d.ts +6 -0
  357. package/dist/presets/sendgrid.js +20 -0
  358. package/dist/presets/sentry.d.ts +11 -0
  359. package/dist/presets/sentry.js +48 -0
  360. package/dist/presets/square.d.ts +10 -0
  361. package/dist/presets/square.js +33 -0
  362. package/dist/recker.d.ts +3 -0
  363. package/dist/recker.js +4 -0
  364. package/dist/scrape/document.d.ts +5 -4
  365. package/dist/scrape/document.js +89 -76
  366. package/dist/scrape/element.d.ts +10 -8
  367. package/dist/scrape/element.js +295 -81
  368. package/dist/scrape/extractors.d.ts +11 -11
  369. package/dist/scrape/extractors.js +145 -113
  370. package/dist/scrape/index.d.ts +2 -0
  371. package/dist/scrape/index.js +1 -0
  372. package/dist/scrape/parser/back.d.ts +1 -0
  373. package/dist/scrape/parser/back.js +3 -0
  374. package/dist/scrape/parser/index.d.ts +20 -0
  375. package/dist/scrape/parser/index.js +19 -0
  376. package/dist/scrape/parser/matcher.d.ts +30 -0
  377. package/dist/scrape/parser/matcher.js +99 -0
  378. package/dist/scrape/parser/nodes/comment.d.ts +12 -0
  379. package/dist/scrape/parser/nodes/comment.js +21 -0
  380. package/dist/scrape/parser/nodes/html.d.ts +110 -0
  381. package/dist/scrape/parser/nodes/html.js +978 -0
  382. package/dist/scrape/parser/nodes/node.d.ts +18 -0
  383. package/dist/scrape/parser/nodes/node.js +31 -0
  384. package/dist/scrape/parser/nodes/text.d.ts +14 -0
  385. package/dist/scrape/parser/nodes/text.js +30 -0
  386. package/dist/scrape/parser/nodes/type.d.ts +6 -0
  387. package/dist/scrape/parser/nodes/type.js +7 -0
  388. package/dist/scrape/parser/parse.d.ts +1 -0
  389. package/dist/scrape/parser/parse.js +1 -0
  390. package/dist/scrape/parser/valid.d.ts +2 -0
  391. package/dist/scrape/parser/valid.js +5 -0
  392. package/dist/scrape/parser/void-tag.d.ts +7 -0
  393. package/dist/scrape/parser/void-tag.js +43 -0
  394. package/dist/scrape/spider.d.ts +19 -0
  395. package/dist/scrape/spider.js +28 -3
  396. package/dist/scrape/types.d.ts +7 -0
  397. package/dist/seo/analyzer.d.ts +15 -5
  398. package/dist/seo/analyzer.js +636 -175
  399. package/dist/seo/formatter.d.ts +16 -0
  400. package/dist/seo/formatter.js +228 -0
  401. package/dist/seo/index.d.ts +2 -0
  402. package/dist/seo/index.js +1 -0
  403. package/dist/seo/keywords.d.ts +16 -0
  404. package/dist/seo/keywords.js +55 -0
  405. package/dist/seo/rules/accessibility.js +96 -57
  406. package/dist/seo/rules/ai-search.js +44 -31
  407. package/dist/seo/rules/analytics.d.ts +2 -0
  408. package/dist/seo/rules/analytics.js +306 -0
  409. package/dist/seo/rules/best-practices.js +21 -14
  410. package/dist/seo/rules/canonical.js +53 -32
  411. package/dist/seo/rules/content.js +317 -31
  412. package/dist/seo/rules/crawl.js +55 -40
  413. package/dist/seo/rules/cwv.js +21 -15
  414. package/dist/seo/rules/ecommerce.js +82 -22
  415. package/dist/seo/rules/i18n.js +75 -36
  416. package/dist/seo/rules/images.js +109 -30
  417. package/dist/seo/rules/index.js +2 -0
  418. package/dist/seo/rules/internal-linking.js +58 -39
  419. package/dist/seo/rules/links.js +79 -52
  420. package/dist/seo/rules/local.js +49 -25
  421. package/dist/seo/rules/meta.js +339 -81
  422. package/dist/seo/rules/mobile.js +112 -2
  423. package/dist/seo/rules/performance.js +434 -66
  424. package/dist/seo/rules/pwa.js +36 -39
  425. package/dist/seo/rules/readability.js +31 -22
  426. package/dist/seo/rules/redirects.js +21 -15
  427. package/dist/seo/rules/resources.js +59 -42
  428. package/dist/seo/rules/schema.js +333 -8
  429. package/dist/seo/rules/security.js +142 -80
  430. package/dist/seo/rules/social.js +277 -47
  431. package/dist/seo/rules/structural.js +87 -19
  432. package/dist/seo/rules/technical-advanced.js +30 -24
  433. package/dist/seo/rules/technical.js +243 -42
  434. package/dist/seo/rules/types.d.ts +53 -1
  435. package/dist/seo/seo-spider.d.ts +22 -0
  436. package/dist/seo/seo-spider.js +77 -13
  437. package/dist/seo/types.d.ts +8 -1
  438. package/dist/seo/validators/llms-txt.js +19 -0
  439. package/dist/seo/validators/rss.d.ts +11 -0
  440. package/dist/seo/validators/rss.js +93 -0
  441. package/dist/seo/validators/sitemap.js +36 -26
  442. package/dist/transport/curl.d.ts +4 -0
  443. package/dist/transport/curl.js +101 -0
  444. package/dist/transport/udp.js +0 -1
  445. package/dist/transport/undici.js +1 -2
  446. package/dist/transport/worker.d.ts +18 -0
  447. package/dist/transport/worker.js +278 -0
  448. package/dist/types/index.d.ts +4 -1
  449. package/dist/utils/binary-manager.d.ts +4 -0
  450. package/dist/utils/binary-manager.js +72 -0
  451. package/dist/utils/optional-require.d.ts +7 -8
  452. package/dist/utils/optional-require.js +2 -21
  453. package/dist/utils/upload.d.ts +6 -0
  454. package/dist/utils/upload.js +11 -0
  455. package/dist/utils/user-agent.js +2 -13
  456. package/dist/version.js +1 -1
  457. package/package.json +14 -6
  458. package/dist/browser/utils/optional-require.d.ts +0 -19
  459. package/dist/browser/utils/optional-require.js +0 -105
@@ -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;
@@ -0,0 +1,295 @@
1
+ import colors from '../../utils/colors.js';
2
+ import { RekArgs, generateHelp } from '../parser/index.js';
3
+ import { exec } from 'node:child_process';
4
+ import { promisify } from 'node:util';
5
+ const execAsync = promisify(exec);
6
+ const propagateSchema = {
7
+ name: 'propagate',
8
+ description: 'Check global DNS propagation across multiple providers',
9
+ examples: [
10
+ { cmd: 'rek dns propagate example.com', desc: 'Check A record' },
11
+ { cmd: 'rek dns propagate example.com MX', desc: 'Check MX record' }
12
+ ]
13
+ };
14
+ const lookupSchema = {
15
+ name: 'lookup',
16
+ description: 'Look up DNS records (A, MX, TXT, etc)',
17
+ examples: [
18
+ { cmd: 'rek dns lookup google.com', desc: 'A records' },
19
+ { cmd: 'rek dns lookup google.com MX', desc: 'MX records' },
20
+ { cmd: 'rek dns lookup google.com ANY', desc: 'All records' }
21
+ ]
22
+ };
23
+ const reverseSchema = {
24
+ name: 'reverse',
25
+ description: 'Perform reverse DNS lookup (IP to hostname)',
26
+ examples: [
27
+ { cmd: 'rek dns reverse 8.8.8.8', desc: 'Lookup Google DNS IP' }
28
+ ]
29
+ };
30
+ const healthSchema = {
31
+ name: 'health',
32
+ description: 'Comprehensive DNS health check with scoring',
33
+ examples: [
34
+ { cmd: 'rek dns health example.com', desc: 'Check domain health' }
35
+ ]
36
+ };
37
+ const spfSchema = {
38
+ name: 'spf',
39
+ description: 'Validate SPF record',
40
+ examples: [
41
+ { cmd: 'rek dns spf example.com', desc: 'Validate SPF' }
42
+ ]
43
+ };
44
+ const dmarcSchema = {
45
+ name: 'dmarc',
46
+ description: 'Validate DMARC record',
47
+ examples: [
48
+ { cmd: 'rek dns dmarc example.com', desc: 'Validate DMARC' }
49
+ ]
50
+ };
51
+ const dkimSchema = {
52
+ name: 'dkim',
53
+ description: 'Check DKIM record for a domain',
54
+ params: {
55
+ selector: { type: 'string', default: 'default', description: 'DKIM selector' }
56
+ },
57
+ examples: [
58
+ { cmd: 'rek dns dkim example.com', desc: 'Default selector' },
59
+ { cmd: 'rek dns dkim example.com selector=google', desc: 'Google selector' }
60
+ ]
61
+ };
62
+ const emailSchema = {
63
+ name: 'email',
64
+ description: 'Full email security audit (SPF + DMARC + DKIM + MX)',
65
+ params: {
66
+ selector: { type: 'string', default: 'default', description: 'DKIM selector' }
67
+ },
68
+ examples: [
69
+ { cmd: 'rek dns email example.com', desc: 'Full audit' }
70
+ ]
71
+ };
72
+ const systemSchema = {
73
+ name: 'system',
74
+ description: 'Show system DNS configuration (OS-level)',
75
+ examples: [
76
+ { cmd: 'rek dns system', desc: 'Show current DNS servers' }
77
+ ]
78
+ };
79
+ export function registerDnsCommands(program) {
80
+ const dns = program.command('dns').description('DNS tools and diagnostics');
81
+ dns.command('propagate')
82
+ .description(propagateSchema.description)
83
+ .argument('<domain>', 'Domain')
84
+ .argument('[type]', 'Record Type', 'A')
85
+ .addHelpText('after', generateHelp(propagateSchema))
86
+ .action(async (domain, type) => {
87
+ const { checkPropagation, formatPropagationReport } = await import('../../dns/propagation.js');
88
+ console.log(colors.gray(`Checking propagation for ${domain} (${type})...`));
89
+ const results = await checkPropagation(domain, type);
90
+ console.log(formatPropagationReport(results, domain, type));
91
+ });
92
+ dns.command('lookup')
93
+ .alias('resolve')
94
+ .description(lookupSchema.description)
95
+ .argument('<domain>', 'Domain')
96
+ .argument('[type]', 'Type', 'A')
97
+ .addHelpText('after', generateHelp(lookupSchema))
98
+ .action(async (domain, type) => {
99
+ const { dnsLookup } = await import('../../utils/dns-toolkit.js');
100
+ console.log(colors.gray(`Looking up ${type.toUpperCase()} records for ${domain}...`));
101
+ try {
102
+ const results = await dnsLookup(domain, type);
103
+ if (results.length === 0) {
104
+ console.log(colors.yellow(`\nNo ${type.toUpperCase()} records found for ${domain}`));
105
+ return;
106
+ }
107
+ console.log(`\n${colors.bold(colors.cyan('DNS Lookup Results'))}`);
108
+ results.forEach(record => {
109
+ const data = typeof record.data === 'object' ? JSON.stringify(record.data) : String(record.data);
110
+ console.log(` ${colors.green('•')} ${colors.bold(record.type.padEnd(6))} ${data}`);
111
+ });
112
+ console.log('');
113
+ }
114
+ catch (err) {
115
+ console.error(colors.red(`DNS Lookup Failed: ${err.message}`));
116
+ process.exit(1);
117
+ }
118
+ });
119
+ dns.command('reverse')
120
+ .description(reverseSchema.description)
121
+ .argument('<ip>', 'IP Address')
122
+ .addHelpText('after', generateHelp(reverseSchema))
123
+ .action(async (ip) => {
124
+ const { reverseLookup } = await import('../../utils/dns-toolkit.js');
125
+ console.log(colors.gray(`Performing reverse lookup for ${ip}...`));
126
+ try {
127
+ const hostnames = await reverseLookup(ip);
128
+ if (hostnames.length === 0) {
129
+ console.log(colors.yellow(`\nNo PTR records found`));
130
+ return;
131
+ }
132
+ console.log(`\n${colors.bold(colors.cyan('Reverse DNS Lookup'))}`);
133
+ hostnames.forEach(h => console.log(` ${colors.green('•')} ${h}`));
134
+ console.log('');
135
+ }
136
+ catch (err) {
137
+ console.error(colors.red(`Reverse Lookup Failed: ${err.message}`));
138
+ process.exit(1);
139
+ }
140
+ });
141
+ dns.command('health')
142
+ .description(healthSchema.description)
143
+ .argument('<domain>', 'Domain')
144
+ .addHelpText('after', generateHelp(healthSchema))
145
+ .action(async (domain) => {
146
+ const { checkDnsHealth } = await import('../../utils/dns-toolkit.js');
147
+ console.log(colors.gray(`Running DNS health check for ${domain}...`));
148
+ try {
149
+ const report = await checkDnsHealth(domain);
150
+ let gradeColor = colors.red;
151
+ if (report.grade === 'A')
152
+ gradeColor = colors.green;
153
+ else if (report.grade === 'B')
154
+ gradeColor = colors.blue;
155
+ else if (report.grade === 'C')
156
+ gradeColor = colors.yellow;
157
+ console.log(`\n${colors.bold(colors.cyan('🏥 DNS Health Report'))}`);
158
+ console.log(`${colors.gray('Grade:')} ${gradeColor(colors.bold(report.grade))} ${colors.gray('Score:')} ${report.score}/100\n`);
159
+ report.checks.forEach(check => {
160
+ const icon = check.status === 'pass' ? colors.green('✔') : check.status === 'warn' ? colors.yellow('⚠') : colors.red('✖');
161
+ console.log(` ${icon} ${colors.bold(check.name.padEnd(16))} ${check.message}`);
162
+ });
163
+ console.log('');
164
+ }
165
+ catch (err) {
166
+ console.error(colors.red(`Health Check Failed: ${err.message}`));
167
+ process.exit(1);
168
+ }
169
+ });
170
+ dns.command('spf')
171
+ .description(spfSchema.description)
172
+ .argument('<domain>', 'Domain')
173
+ .addHelpText('after', generateHelp(spfSchema))
174
+ .action(async (domain) => {
175
+ const { validateSpf } = await import('../../utils/dns-toolkit.js');
176
+ try {
177
+ const result = await validateSpf(domain);
178
+ console.log(`\n${colors.bold(colors.cyan('📧 SPF Validation'))}`);
179
+ if (result.valid)
180
+ console.log(` ${colors.green('✔')} Valid SPF: ${colors.gray(result.record || '')}`);
181
+ else if (result.record)
182
+ console.log(` ${colors.yellow('⚠')} Invalid SPF: ${colors.gray(result.record)}`);
183
+ else
184
+ console.log(` ${colors.red('✖')} No SPF record found`);
185
+ result.errors.forEach(e => console.log(` ${colors.red('→')} ${e}`));
186
+ console.log('');
187
+ }
188
+ catch (err) {
189
+ console.error(colors.red(`SPF Failed: ${err.message}`));
190
+ process.exit(1);
191
+ }
192
+ });
193
+ dns.command('dmarc')
194
+ .description(dmarcSchema.description)
195
+ .argument('<domain>', 'Domain')
196
+ .addHelpText('after', generateHelp(dmarcSchema))
197
+ .action(async (domain) => {
198
+ const { validateDmarc } = await import('../../utils/dns-toolkit.js');
199
+ try {
200
+ const result = await validateDmarc(domain);
201
+ console.log(`\n${colors.bold(colors.cyan('🛡️ DMARC Validation'))}`);
202
+ if (result.valid)
203
+ console.log(` ${colors.green('✔')} Valid DMARC (Policy: ${result.policy})`);
204
+ else
205
+ console.log(` ${colors.red('✖')} DMARC issue`);
206
+ if (result.record)
207
+ console.log(` ${colors.gray(result.record)}`);
208
+ console.log('');
209
+ }
210
+ catch (err) {
211
+ console.error(colors.red(`DMARC Failed: ${err.message}`));
212
+ process.exit(1);
213
+ }
214
+ });
215
+ dns.command('dkim')
216
+ .description(dkimSchema.description)
217
+ .argument('<domain>', 'Domain')
218
+ .argument('[args...]', 'Options')
219
+ .addHelpText('after', generateHelp(dkimSchema))
220
+ .action(async (domain, rawArgs) => {
221
+ const { data } = RekArgs.parse(rawArgs, dkimSchema);
222
+ const { checkDkim } = await import('../../utils/dns-toolkit.js');
223
+ try {
224
+ const result = await checkDkim(domain, data.selector);
225
+ console.log(`\n${colors.bold(colors.cyan('🔑 DKIM Check'))}`);
226
+ if (result.found)
227
+ console.log(` ${colors.green('✔')} DKIM found (selector: ${data.selector})`);
228
+ else
229
+ console.log(` ${colors.red('✖')} No DKIM found (selector: ${data.selector})`);
230
+ console.log('');
231
+ }
232
+ catch (err) {
233
+ console.error(colors.red(`DKIM Failed: ${err.message}`));
234
+ process.exit(1);
235
+ }
236
+ });
237
+ dns.command('email')
238
+ .description(emailSchema.description)
239
+ .argument('<domain>', 'Domain')
240
+ .argument('[args...]', 'Options')
241
+ .addHelpText('after', generateHelp(emailSchema))
242
+ .action(async (domain, rawArgs) => {
243
+ console.log(colors.gray('Running full email audit...'));
244
+ });
245
+ dns.command('system')
246
+ .alias('status')
247
+ .description(systemSchema.description)
248
+ .addHelpText('after', generateHelp(systemSchema))
249
+ .action(async () => {
250
+ const platform = process.platform;
251
+ let cmd = '';
252
+ if (platform === 'linux') {
253
+ cmd = 'resolvectl status';
254
+ }
255
+ else if (platform === 'darwin') {
256
+ cmd = 'scutil --dns';
257
+ }
258
+ else if (platform === 'win32') {
259
+ cmd = 'ipconfig /all';
260
+ }
261
+ else {
262
+ console.log(colors.red('Unsupported platform for system DNS check.'));
263
+ return;
264
+ }
265
+ console.log(colors.gray(`Running system DNS check (${cmd})...\n`));
266
+ try {
267
+ const { stdout } = await execAsync(cmd);
268
+ console.log(stdout);
269
+ }
270
+ catch (err) {
271
+ if (platform === 'linux') {
272
+ try {
273
+ const { stdout } = await execAsync('cat /etc/resolv.conf');
274
+ console.log(colors.bold('/etc/resolv.conf:'));
275
+ console.log(stdout);
276
+ }
277
+ catch {
278
+ console.error(colors.red(`Failed to check DNS: ${err.message}`));
279
+ }
280
+ }
281
+ else {
282
+ console.error(colors.red(`Failed to check DNS: ${err.message}`));
283
+ }
284
+ }
285
+ });
286
+ dns.command('dig')
287
+ .description('DNS lookup utility (like the real dig)')
288
+ .argument('[args...]', 'Query arguments')
289
+ .allowUnknownOption()
290
+ .action(async (args) => {
291
+ const { dig, formatDigOutput } = await import('../../utils/dns-toolkit.js');
292
+ let domain = '';
293
+ let type = 'A';
294
+ });
295
+ }
@@ -0,0 +1,2 @@
1
+ import { RekCommand as Command } from '../router.js';
2
+ export declare function registerHarCommand(program: Command): void;