@agentrhq/webcmd 0.1.1 → 0.1.2

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 (415) hide show
  1. package/README.md +317 -24
  2. package/dist/src/adapter-shadow.d.ts +11 -0
  3. package/dist/src/adapter-shadow.js +72 -0
  4. package/dist/src/adapter-shadow.test.d.ts +1 -0
  5. package/dist/src/adapter-shadow.test.js +49 -0
  6. package/dist/src/adapter-source.d.ts +11 -0
  7. package/dist/src/adapter-source.js +24 -0
  8. package/dist/src/adapter-source.test.d.ts +1 -0
  9. package/dist/src/adapter-source.test.js +29 -0
  10. package/dist/src/brand.d.ts +9 -0
  11. package/dist/src/brand.js +9 -0
  12. package/dist/src/brand.test.d.ts +1 -0
  13. package/dist/src/brand.test.js +15 -0
  14. package/dist/src/browser/analyze.d.ts +118 -0
  15. package/dist/src/browser/analyze.js +405 -0
  16. package/dist/src/browser/analyze.test.d.ts +1 -0
  17. package/dist/src/browser/analyze.test.js +209 -0
  18. package/dist/src/browser/article-extract.d.ts +57 -0
  19. package/dist/src/browser/article-extract.e2e.test.d.ts +1 -0
  20. package/dist/src/browser/article-extract.e2e.test.js +105 -0
  21. package/dist/src/browser/article-extract.js +169 -0
  22. package/dist/src/browser/article-extract.test.d.ts +1 -0
  23. package/dist/src/browser/article-extract.test.js +94 -0
  24. package/dist/src/browser/ax-snapshot.d.ts +37 -0
  25. package/dist/src/browser/ax-snapshot.js +217 -0
  26. package/dist/src/browser/ax-snapshot.test.d.ts +1 -0
  27. package/dist/src/browser/ax-snapshot.test.js +91 -0
  28. package/dist/src/browser/base-page.d.ts +151 -0
  29. package/dist/src/browser/base-page.js +1060 -0
  30. package/dist/src/browser/base-page.test.d.ts +1 -0
  31. package/dist/src/browser/base-page.test.js +803 -0
  32. package/dist/src/browser/bridge-readiness.d.ts +14 -0
  33. package/dist/src/browser/bridge-readiness.js +24 -0
  34. package/dist/src/browser/bridge-readiness.test.d.ts +1 -0
  35. package/dist/src/browser/bridge-readiness.test.js +58 -0
  36. package/dist/src/browser/bridge.d.ts +26 -0
  37. package/dist/src/browser/bridge.js +58 -0
  38. package/dist/src/browser/cdp-click-fixture.test.d.ts +1 -0
  39. package/dist/src/browser/cdp-click-fixture.test.js +87 -0
  40. package/dist/src/browser/cdp.d.ts +46 -0
  41. package/dist/src/browser/cdp.js +536 -0
  42. package/dist/src/browser/cdp.test.d.ts +1 -0
  43. package/dist/src/browser/cdp.test.js +79 -0
  44. package/dist/src/browser/compound.d.ts +59 -0
  45. package/dist/src/browser/compound.js +112 -0
  46. package/dist/src/browser/compound.test.d.ts +1 -0
  47. package/dist/src/browser/compound.test.js +175 -0
  48. package/dist/src/browser/config.d.ts +2 -0
  49. package/dist/src/browser/config.js +14 -0
  50. package/dist/src/browser/daemon-client.d.ts +32 -0
  51. package/dist/src/browser/daemon-client.js +135 -0
  52. package/dist/src/browser/daemon-client.test.d.ts +1 -0
  53. package/dist/src/browser/daemon-client.test.js +326 -0
  54. package/dist/src/browser/daemon-lifecycle.d.ts +37 -0
  55. package/dist/src/browser/daemon-lifecycle.js +147 -0
  56. package/dist/src/browser/daemon-transport.d.ts +54 -0
  57. package/dist/src/browser/daemon-transport.js +68 -0
  58. package/dist/src/browser/daemon-version.d.ts +4 -0
  59. package/dist/src/browser/daemon-version.js +12 -0
  60. package/dist/src/browser/dom-helpers.d.ts +41 -0
  61. package/dist/src/browser/dom-helpers.js +239 -0
  62. package/dist/src/browser/dom-helpers.test.d.ts +1 -0
  63. package/dist/src/browser/dom-helpers.test.js +106 -0
  64. package/dist/src/browser/dom-snapshot.d.ts +93 -0
  65. package/dist/src/browser/dom-snapshot.js +894 -0
  66. package/dist/src/browser/dom-snapshot.test.d.ts +11 -0
  67. package/dist/src/browser/dom-snapshot.test.js +313 -0
  68. package/dist/src/browser/errors.d.ts +38 -0
  69. package/dist/src/browser/errors.js +79 -0
  70. package/dist/src/browser/errors.test.d.ts +1 -0
  71. package/dist/src/browser/errors.test.js +60 -0
  72. package/dist/src/browser/extract.d.ts +69 -0
  73. package/dist/src/browser/extract.js +132 -0
  74. package/dist/src/browser/extract.test.d.ts +1 -0
  75. package/dist/src/browser/extract.test.js +129 -0
  76. package/dist/src/browser/find.d.ts +84 -0
  77. package/dist/src/browser/find.js +398 -0
  78. package/dist/src/browser/find.test.d.ts +1 -0
  79. package/dist/src/browser/find.test.js +180 -0
  80. package/dist/src/browser/html-tree.d.ts +75 -0
  81. package/dist/src/browser/html-tree.js +112 -0
  82. package/dist/src/browser/html-tree.test.d.ts +1 -0
  83. package/dist/src/browser/html-tree.test.js +181 -0
  84. package/dist/src/browser/index.d.ts +14 -0
  85. package/dist/src/browser/index.js +12 -0
  86. package/dist/src/browser/network-cache.d.ts +49 -0
  87. package/dist/src/browser/network-cache.js +78 -0
  88. package/dist/src/browser/network-cache.test.d.ts +1 -0
  89. package/dist/src/browser/network-cache.test.js +75 -0
  90. package/dist/src/browser/network-interceptor.d.ts +11 -0
  91. package/dist/src/browser/network-interceptor.js +11 -0
  92. package/dist/src/browser/network-key.d.ts +22 -0
  93. package/dist/src/browser/network-key.js +66 -0
  94. package/dist/src/browser/network-key.test.d.ts +1 -0
  95. package/dist/src/browser/network-key.test.js +49 -0
  96. package/dist/src/browser/page.d.ts +83 -0
  97. package/dist/src/browser/page.js +453 -0
  98. package/dist/src/browser/page.test.d.ts +1 -0
  99. package/dist/src/browser/page.test.js +406 -0
  100. package/dist/src/browser/profile.d.ts +14 -0
  101. package/dist/src/browser/profile.js +86 -0
  102. package/dist/src/browser/protocol.d.ts +63 -0
  103. package/dist/src/browser/protocol.js +1 -0
  104. package/dist/src/browser/runtime/local-cloak/actions.d.ts +3 -0
  105. package/dist/src/browser/runtime/local-cloak/actions.js +240 -0
  106. package/dist/src/browser/runtime/local-cloak/downloads.d.ts +3 -0
  107. package/dist/src/browser/runtime/local-cloak/downloads.js +28 -0
  108. package/dist/src/browser/runtime/local-cloak/network.d.ts +28 -0
  109. package/dist/src/browser/runtime/local-cloak/network.js +120 -0
  110. package/dist/src/browser/runtime/local-cloak/network.test.d.ts +1 -0
  111. package/dist/src/browser/runtime/local-cloak/network.test.js +124 -0
  112. package/dist/src/browser/runtime/local-cloak/profiles.d.ts +6 -0
  113. package/dist/src/browser/runtime/local-cloak/profiles.js +17 -0
  114. package/dist/src/browser/runtime/local-cloak/profiles.test.d.ts +1 -0
  115. package/dist/src/browser/runtime/local-cloak/profiles.test.js +19 -0
  116. package/dist/src/browser/runtime/local-cloak/provider.d.ts +15 -0
  117. package/dist/src/browser/runtime/local-cloak/provider.js +27 -0
  118. package/dist/src/browser/runtime/local-cloak/provider.test.d.ts +1 -0
  119. package/dist/src/browser/runtime/local-cloak/provider.test.js +244 -0
  120. package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +77 -0
  121. package/dist/src/browser/runtime/local-cloak/session-manager.js +280 -0
  122. package/dist/src/browser/runtime/local-cloak/session-manager.test.d.ts +1 -0
  123. package/dist/src/browser/runtime/local-cloak/session-manager.test.js +92 -0
  124. package/dist/src/browser/runtime/provider.d.ts +9 -0
  125. package/dist/src/browser/runtime/provider.js +1 -0
  126. package/dist/src/browser/runtime/provider.test.d.ts +2 -0
  127. package/dist/src/browser/runtime/provider.test.js +49 -0
  128. package/dist/src/browser/shape-filter.d.ts +52 -0
  129. package/dist/src/browser/shape-filter.js +101 -0
  130. package/dist/src/browser/shape-filter.test.d.ts +1 -0
  131. package/dist/src/browser/shape-filter.test.js +101 -0
  132. package/dist/src/browser/shape.d.ts +23 -0
  133. package/dist/src/browser/shape.js +95 -0
  134. package/dist/src/browser/shape.test.d.ts +1 -0
  135. package/dist/src/browser/shape.test.js +82 -0
  136. package/dist/src/browser/stealth.d.ts +11 -0
  137. package/dist/src/browser/stealth.js +359 -0
  138. package/dist/src/browser/stealth.test.d.ts +1 -0
  139. package/dist/src/browser/stealth.test.js +134 -0
  140. package/dist/src/browser/tabs.d.ts +13 -0
  141. package/dist/src/browser/tabs.js +70 -0
  142. package/dist/src/browser/target-errors.d.ts +39 -0
  143. package/dist/src/browser/target-errors.js +45 -0
  144. package/dist/src/browser/target-errors.test.d.ts +1 -0
  145. package/dist/src/browser/target-errors.test.js +94 -0
  146. package/dist/src/browser/target-resolver.d.ts +158 -0
  147. package/dist/src/browser/target-resolver.js +570 -0
  148. package/dist/src/browser/target-resolver.test.d.ts +1 -0
  149. package/dist/src/browser/target-resolver.test.js +118 -0
  150. package/dist/src/browser/utils.d.ts +20 -0
  151. package/dist/src/browser/utils.js +64 -0
  152. package/dist/src/browser/utils.test.d.ts +1 -0
  153. package/dist/src/browser/utils.test.js +29 -0
  154. package/dist/src/browser/verify-fixture.d.ts +65 -0
  155. package/dist/src/browser/verify-fixture.js +318 -0
  156. package/dist/src/browser/verify-fixture.test.d.ts +1 -0
  157. package/dist/src/browser/verify-fixture.test.js +219 -0
  158. package/dist/src/browser/visual-refs.d.ts +11 -0
  159. package/dist/src/browser/visual-refs.js +108 -0
  160. package/dist/src/browser.test.d.ts +1 -0
  161. package/dist/src/browser.test.js +297 -0
  162. package/dist/src/build-manifest.d.ts +103 -0
  163. package/dist/src/build-manifest.js +363 -0
  164. package/dist/src/build-manifest.test.d.ts +1 -0
  165. package/dist/src/build-manifest.test.js +341 -0
  166. package/dist/src/capabilityRouting.d.ts +19 -0
  167. package/dist/src/capabilityRouting.js +56 -0
  168. package/dist/src/capabilityRouting.test.d.ts +1 -0
  169. package/dist/src/capabilityRouting.test.js +63 -0
  170. package/dist/src/cli-argv-preprocess.d.ts +63 -0
  171. package/dist/src/cli-argv-preprocess.js +303 -0
  172. package/dist/src/cli-argv-preprocess.test.d.ts +1 -0
  173. package/dist/src/cli-argv-preprocess.test.js +304 -0
  174. package/dist/src/cli.d.ts +79 -0
  175. package/dist/src/cli.js +3350 -0
  176. package/dist/src/cli.test.d.ts +1 -0
  177. package/dist/src/cli.test.js +3041 -0
  178. package/dist/src/commanderAdapter.d.ts +21 -0
  179. package/dist/src/commanderAdapter.js +208 -0
  180. package/dist/src/commanderAdapter.test.d.ts +1 -0
  181. package/dist/src/commanderAdapter.test.js +352 -0
  182. package/dist/src/commands/auth.d.ts +40 -0
  183. package/dist/src/commands/auth.js +434 -0
  184. package/dist/src/commands/auth.test.d.ts +1 -0
  185. package/dist/src/commands/auth.test.js +252 -0
  186. package/dist/src/commands/daemon.d.ts +9 -0
  187. package/dist/src/commands/daemon.js +91 -0
  188. package/dist/src/commands/daemon.test.d.ts +1 -0
  189. package/dist/src/commands/daemon.test.js +293 -0
  190. package/dist/src/completion-fast.d.ts +22 -0
  191. package/dist/src/completion-fast.js +88 -0
  192. package/dist/src/completion-shared.d.ts +13 -0
  193. package/dist/src/completion-shared.js +61 -0
  194. package/dist/src/completion.d.ts +21 -0
  195. package/dist/src/completion.js +68 -0
  196. package/dist/src/completion.test.d.ts +1 -0
  197. package/dist/src/completion.test.js +24 -0
  198. package/dist/src/constants.d.ts +18 -0
  199. package/dist/src/constants.js +41 -0
  200. package/dist/src/convention-audit.d.ts +50 -0
  201. package/dist/src/convention-audit.js +553 -0
  202. package/dist/src/convention-audit.test.d.ts +1 -0
  203. package/dist/src/convention-audit.test.js +255 -0
  204. package/dist/src/daemon/server.d.ts +13 -0
  205. package/dist/src/daemon/server.js +185 -0
  206. package/dist/src/daemon/server.test.d.ts +1 -0
  207. package/dist/src/daemon/server.test.js +132 -0
  208. package/dist/src/daemon-utils.d.ts +18 -0
  209. package/dist/src/daemon-utils.js +37 -0
  210. package/dist/src/daemon.d.ts +1 -0
  211. package/dist/src/daemon.js +27 -0
  212. package/dist/src/daemon.test.d.ts +1 -0
  213. package/dist/src/daemon.test.js +60 -0
  214. package/dist/src/discovery.d.ts +46 -0
  215. package/dist/src/discovery.js +341 -0
  216. package/dist/src/doctor.d.ts +39 -0
  217. package/dist/src/doctor.js +168 -0
  218. package/dist/src/doctor.test.d.ts +1 -0
  219. package/dist/src/doctor.test.js +302 -0
  220. package/dist/src/download/article-download.d.ts +72 -0
  221. package/dist/src/download/article-download.js +305 -0
  222. package/dist/src/download/article-download.test.d.ts +1 -0
  223. package/dist/src/download/article-download.test.js +235 -0
  224. package/dist/src/download/index.d.ts +71 -0
  225. package/dist/src/download/index.js +363 -0
  226. package/dist/src/download/index.test.d.ts +1 -0
  227. package/dist/src/download/index.test.js +174 -0
  228. package/dist/src/download/media-download.d.ts +49 -0
  229. package/dist/src/download/media-download.js +127 -0
  230. package/dist/src/download/media-download.test.d.ts +1 -0
  231. package/dist/src/download/media-download.test.js +112 -0
  232. package/dist/src/download/progress.d.ts +36 -0
  233. package/dist/src/download/progress.js +120 -0
  234. package/dist/src/download/progress.test.d.ts +1 -0
  235. package/dist/src/download/progress.test.js +36 -0
  236. package/dist/src/electron-apps.d.ts +31 -0
  237. package/dist/src/electron-apps.js +91 -0
  238. package/dist/src/electron-apps.test.d.ts +1 -0
  239. package/dist/src/electron-apps.test.js +76 -0
  240. package/dist/src/engine.test.d.ts +1 -0
  241. package/dist/src/engine.test.js +312 -0
  242. package/dist/src/errors.d.ts +114 -0
  243. package/dist/src/errors.js +174 -0
  244. package/dist/src/errors.test.d.ts +1 -0
  245. package/dist/src/errors.test.js +109 -0
  246. package/dist/src/execution.d.ts +24 -0
  247. package/dist/src/execution.js +509 -0
  248. package/dist/src/execution.test.d.ts +1 -0
  249. package/dist/src/execution.test.js +645 -0
  250. package/dist/src/external.d.ts +49 -0
  251. package/dist/src/external.js +211 -0
  252. package/dist/src/external.test.d.ts +1 -0
  253. package/dist/src/external.test.js +110 -0
  254. package/dist/src/help.d.ts +88 -0
  255. package/dist/src/help.js +556 -0
  256. package/dist/src/help.test.d.ts +1 -0
  257. package/dist/src/help.test.js +58 -0
  258. package/dist/src/hooks.d.ts +46 -0
  259. package/dist/src/hooks.js +58 -0
  260. package/dist/src/hooks.test.d.ts +4 -0
  261. package/dist/src/hooks.test.js +92 -0
  262. package/dist/src/interceptor.d.ts +44 -0
  263. package/dist/src/interceptor.js +183 -0
  264. package/dist/src/interceptor.test.d.ts +4 -0
  265. package/dist/src/interceptor.test.js +81 -0
  266. package/dist/src/launcher.d.ts +41 -0
  267. package/dist/src/launcher.js +226 -0
  268. package/dist/src/launcher.test.d.ts +1 -0
  269. package/dist/src/launcher.test.js +153 -0
  270. package/dist/src/logger.d.ts +26 -0
  271. package/dist/src/logger.js +49 -0
  272. package/dist/src/main.d.ts +5 -0
  273. package/dist/src/main.js +177 -0
  274. package/dist/src/manifest-types.d.ts +43 -0
  275. package/dist/src/manifest-types.js +9 -0
  276. package/dist/src/node-network.d.ts +10 -0
  277. package/dist/src/node-network.js +174 -0
  278. package/dist/src/node-network.test.d.ts +1 -0
  279. package/dist/src/node-network.test.js +55 -0
  280. package/dist/src/observation/artifact.d.ts +16 -0
  281. package/dist/src/observation/artifact.js +260 -0
  282. package/dist/src/observation/artifact.test.d.ts +1 -0
  283. package/dist/src/observation/artifact.test.js +121 -0
  284. package/dist/src/observation/events.d.ts +89 -0
  285. package/dist/src/observation/events.js +1 -0
  286. package/dist/src/observation/index.d.ts +7 -0
  287. package/dist/src/observation/index.js +7 -0
  288. package/dist/src/observation/manager.d.ts +9 -0
  289. package/dist/src/observation/manager.js +27 -0
  290. package/dist/src/observation/manager.test.d.ts +1 -0
  291. package/dist/src/observation/manager.test.js +13 -0
  292. package/dist/src/observation/redaction.d.ts +11 -0
  293. package/dist/src/observation/redaction.js +81 -0
  294. package/dist/src/observation/redaction.test.d.ts +1 -0
  295. package/dist/src/observation/redaction.test.js +32 -0
  296. package/dist/src/observation/retention.d.ts +32 -0
  297. package/dist/src/observation/retention.js +160 -0
  298. package/dist/src/observation/retention.test.d.ts +1 -0
  299. package/dist/src/observation/retention.test.js +118 -0
  300. package/dist/src/observation/ring-buffer.d.ts +22 -0
  301. package/dist/src/observation/ring-buffer.js +45 -0
  302. package/dist/src/observation/ring-buffer.test.d.ts +1 -0
  303. package/dist/src/observation/ring-buffer.test.js +22 -0
  304. package/dist/src/observation/session.d.ts +25 -0
  305. package/dist/src/observation/session.js +50 -0
  306. package/dist/src/output.d.ts +14 -0
  307. package/dist/src/output.js +152 -0
  308. package/dist/src/output.test.d.ts +1 -0
  309. package/dist/src/output.test.js +53 -0
  310. package/dist/src/package-exports.test.d.ts +1 -0
  311. package/dist/src/package-exports.test.js +112 -0
  312. package/dist/src/package-paths.d.ts +8 -0
  313. package/dist/src/package-paths.js +41 -0
  314. package/dist/src/pipeline/executor.d.ts +11 -0
  315. package/dist/src/pipeline/executor.js +93 -0
  316. package/dist/src/pipeline/executor.test.d.ts +4 -0
  317. package/dist/src/pipeline/executor.test.js +182 -0
  318. package/dist/src/pipeline/index.d.ts +5 -0
  319. package/dist/src/pipeline/index.js +5 -0
  320. package/dist/src/pipeline/registry.d.ts +28 -0
  321. package/dist/src/pipeline/registry.js +55 -0
  322. package/dist/src/pipeline/steps/browser.d.ts +13 -0
  323. package/dist/src/pipeline/steps/browser.js +86 -0
  324. package/dist/src/pipeline/steps/download.d.ts +18 -0
  325. package/dist/src/pipeline/steps/download.js +252 -0
  326. package/dist/src/pipeline/steps/download.test.d.ts +1 -0
  327. package/dist/src/pipeline/steps/download.test.js +102 -0
  328. package/dist/src/pipeline/steps/fetch.d.ts +5 -0
  329. package/dist/src/pipeline/steps/fetch.js +122 -0
  330. package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
  331. package/dist/src/pipeline/steps/fetch.test.js +117 -0
  332. package/dist/src/pipeline/steps/intercept.d.ts +5 -0
  333. package/dist/src/pipeline/steps/intercept.js +50 -0
  334. package/dist/src/pipeline/steps/tap.d.ts +12 -0
  335. package/dist/src/pipeline/steps/tap.js +93 -0
  336. package/dist/src/pipeline/steps/transform.d.ts +9 -0
  337. package/dist/src/pipeline/steps/transform.js +70 -0
  338. package/dist/src/pipeline/template.d.ts +17 -0
  339. package/dist/src/pipeline/template.js +344 -0
  340. package/dist/src/pipeline/template.test.d.ts +4 -0
  341. package/dist/src/pipeline/template.test.js +197 -0
  342. package/dist/src/pipeline/transform.test.d.ts +4 -0
  343. package/dist/src/pipeline/transform.test.js +133 -0
  344. package/dist/src/plugin-manifest.d.ts +70 -0
  345. package/dist/src/plugin-manifest.js +160 -0
  346. package/dist/src/plugin-manifest.test.d.ts +4 -0
  347. package/dist/src/plugin-manifest.test.js +179 -0
  348. package/dist/src/plugin-scaffold.d.ts +28 -0
  349. package/dist/src/plugin-scaffold.js +143 -0
  350. package/dist/src/plugin-scaffold.test.d.ts +4 -0
  351. package/dist/src/plugin-scaffold.test.js +83 -0
  352. package/dist/src/plugin.d.ts +146 -0
  353. package/dist/src/plugin.js +1303 -0
  354. package/dist/src/plugin.test.d.ts +4 -0
  355. package/dist/src/plugin.test.js +1363 -0
  356. package/dist/src/registry-api.d.ts +13 -0
  357. package/dist/src/registry-api.js +10 -0
  358. package/dist/src/registry.d.ts +123 -0
  359. package/dist/src/registry.js +125 -0
  360. package/dist/src/registry.test.d.ts +4 -0
  361. package/dist/src/registry.test.js +209 -0
  362. package/dist/src/runtime-copy.test.d.ts +1 -0
  363. package/dist/src/runtime-copy.test.js +29 -0
  364. package/dist/src/runtime-detect.d.ts +31 -0
  365. package/dist/src/runtime-detect.js +47 -0
  366. package/dist/src/runtime-detect.test.d.ts +1 -0
  367. package/dist/src/runtime-detect.test.js +39 -0
  368. package/dist/src/runtime-identity.test.d.ts +1 -0
  369. package/dist/src/runtime-identity.test.js +18 -0
  370. package/dist/src/runtime.d.ts +47 -0
  371. package/dist/src/runtime.js +54 -0
  372. package/dist/src/scripts/framework.d.ts +7 -0
  373. package/dist/src/scripts/framework.js +25 -0
  374. package/dist/src/scripts/interact.d.ts +4 -0
  375. package/dist/src/scripts/interact.js +20 -0
  376. package/dist/src/scripts/store.d.ts +13 -0
  377. package/dist/src/scripts/store.js +48 -0
  378. package/dist/src/serialization.d.ts +42 -0
  379. package/dist/src/serialization.js +103 -0
  380. package/dist/src/serialization.test.d.ts +1 -0
  381. package/dist/src/serialization.test.js +78 -0
  382. package/dist/src/skills.d.ts +14 -0
  383. package/dist/src/skills.js +127 -0
  384. package/dist/src/skills.test.d.ts +1 -0
  385. package/dist/src/skills.test.js +71 -0
  386. package/dist/src/snapshotFormatter.d.ts +11 -0
  387. package/dist/src/snapshotFormatter.js +338 -0
  388. package/dist/src/snapshotFormatter.test.d.ts +7 -0
  389. package/dist/src/snapshotFormatter.test.js +521 -0
  390. package/dist/src/tui.d.ts +28 -0
  391. package/dist/src/tui.js +179 -0
  392. package/dist/src/tui.test.d.ts +1 -0
  393. package/dist/src/tui.test.js +19 -0
  394. package/dist/src/types.d.ts +236 -0
  395. package/dist/src/types.js +7 -0
  396. package/dist/src/update-check.d.ts +66 -0
  397. package/dist/src/update-check.js +206 -0
  398. package/dist/src/update-check.test.d.ts +1 -0
  399. package/dist/src/update-check.test.js +117 -0
  400. package/dist/src/utils.d.ts +57 -0
  401. package/dist/src/utils.js +152 -0
  402. package/dist/src/utils.test.d.ts +1 -0
  403. package/dist/src/utils.test.js +155 -0
  404. package/dist/src/validate.d.ts +21 -0
  405. package/dist/src/validate.js +130 -0
  406. package/dist/src/validate.test.d.ts +9 -0
  407. package/dist/src/validate.test.js +90 -0
  408. package/dist/src/verify.d.ts +26 -0
  409. package/dist/src/verify.js +67 -0
  410. package/dist/src/version.d.ts +4 -0
  411. package/dist/src/version.js +22 -0
  412. package/dist/src/weixin-download.test.d.ts +1 -0
  413. package/dist/src/weixin-download.test.js +45 -0
  414. package/package.json +4 -3
  415. package/scripts/check-package-bin.mjs +95 -0
@@ -0,0 +1,118 @@
1
+ /**
2
+ * `browser analyze <url>` — turn site-recon guesswork into deterministic CLI output.
3
+ *
4
+ * When an agent starts a new adapter, the first question is "which pattern am
5
+ * I looking at?" (A/B/C/D/E from site-recon docs) and "will Node-side fetch
6
+ * work, or will anti-bot middleware block me?". Today the agent has to open
7
+ * the page, poke `network`, try cURL, fail, guess again. This module condenses
8
+ * that into one call that returns a classification + evidence.
9
+ *
10
+ * Kept pure (no page imports) so the bulk is unit-testable; the CLI wrapper
11
+ * drives a real page, feeds the resulting signals here, and prints the verdict.
12
+ */
13
+ import type { CliCommand } from '../registry.js';
14
+ export interface PageSignals {
15
+ /** URL we navigated to (may redirect; both fields help agents notice that). */
16
+ requestedUrl: string;
17
+ finalUrl: string;
18
+ /** document.cookie split into names; value not needed for detection. */
19
+ cookieNames: string[];
20
+ /**
21
+ * Response bodies captured during the navigation + first few seconds.
22
+ * We only need enough body text to spot WAF markers; the CLI truncates
23
+ * per-entry before feeding us.
24
+ */
25
+ networkEntries: Array<{
26
+ url: string;
27
+ status: number;
28
+ contentType: string;
29
+ /** First N chars of body; null when not available. */
30
+ bodyPreview: string | null;
31
+ }>;
32
+ /**
33
+ * Which globals the page exposes on `window`. We don't care about the values,
34
+ * just presence — distinguishes Pattern B (SSR state) from Pattern A.
35
+ */
36
+ initialState: {
37
+ __INITIAL_STATE__: boolean;
38
+ __NUXT__: boolean;
39
+ __NEXT_DATA__: boolean;
40
+ __APOLLO_STATE__: boolean;
41
+ };
42
+ /** Document title — only for the human-debug `summary` field. */
43
+ title: string;
44
+ }
45
+ export type EndpointEvidenceVerdict = 'likely_data' | 'maybe_data' | 'noise' | 'blocked';
46
+ export interface EndpointEvidence {
47
+ url: string;
48
+ status: number;
49
+ contentType: string;
50
+ real_data_score: number;
51
+ verdict: EndpointEvidenceVerdict;
52
+ reasons: string[];
53
+ sample_paths: string[];
54
+ }
55
+ export type AntiBotVendor = 'aliyun_waf' | 'cloudflare' | 'akamai' | 'geetest' | 'unknown';
56
+ export interface AntiBotVerdict {
57
+ detected: boolean;
58
+ vendor: AntiBotVendor | null;
59
+ evidence: string[];
60
+ /** One-line imperative instruction for the agent. */
61
+ implication: string;
62
+ }
63
+ export declare function detectAntiBot(signals: PageSignals): AntiBotVerdict;
64
+ export type Pattern = 'A' | 'B' | 'C' | 'D' | 'E' | 'unknown';
65
+ export interface PatternVerdict {
66
+ pattern: Pattern;
67
+ reason: string;
68
+ /** How many JSON XHR/fetch responses we saw during navigation. */
69
+ json_responses: number;
70
+ /** How many observed responses look like real business data, not telemetry. */
71
+ real_data_candidates: number;
72
+ /** Count of non-2xx API responses — hint for token-gated (Pattern D). */
73
+ auth_failures: number;
74
+ }
75
+ export declare function scoreEndpointEvidence(entry: PageSignals['networkEntries'][number]): EndpointEvidence;
76
+ export declare function scoreNetworkEvidence(signals: PageSignals): EndpointEvidence[];
77
+ /**
78
+ * Apply the decision tree from `site-recon.md` mechanically.
79
+ *
80
+ * B beats A when initial-state globals are present: even if the page fetches
81
+ * more data via XHR afterwards, the SSR payload is the highest-leverage source.
82
+ * D (token-gated) dominates when we see 401/403 on what looks like API
83
+ * endpoints — without that, an authenticated route looks identical to A.
84
+ */
85
+ export declare function classifyPattern(signals: PageSignals): PatternVerdict;
86
+ export interface NearestAdapter {
87
+ site: string;
88
+ example_commands: string[];
89
+ reason: string;
90
+ }
91
+ /**
92
+ * Find existing adapters that target the same site.
93
+ *
94
+ * Keep the hostname match simple — agents extend naming conventions
95
+ * differently per site, so we match on the registered `domain` field and fall
96
+ * back to site-name containment. Returning `null` is fine; agents can always
97
+ * read site-memory docs.
98
+ */
99
+ export declare function findNearestAdapter(finalUrl: string, registry: Map<string, CliCommand>): NearestAdapter | null;
100
+ export interface AnalyzeReport {
101
+ requested_url: string;
102
+ final_url: string;
103
+ title: string;
104
+ pattern: PatternVerdict;
105
+ anti_bot: AntiBotVerdict;
106
+ initial_state: PageSignals['initialState'];
107
+ api_candidates: EndpointEvidence[];
108
+ nearest_adapter: NearestAdapter | null;
109
+ recommended_next_step: string;
110
+ }
111
+ /**
112
+ * Synthesize the verdict from collected signals + registry.
113
+ *
114
+ * The `recommended_next_step` is deliberately a single imperative
115
+ * sentence — agents act on it directly instead of re-deriving advice from
116
+ * the structured fields.
117
+ */
118
+ export declare function analyzeSite(signals: PageSignals, registry: Map<string, CliCommand>): AnalyzeReport;
@@ -0,0 +1,405 @@
1
+ /**
2
+ * `browser analyze <url>` — turn site-recon guesswork into deterministic CLI output.
3
+ *
4
+ * When an agent starts a new adapter, the first question is "which pattern am
5
+ * I looking at?" (A/B/C/D/E from site-recon docs) and "will Node-side fetch
6
+ * work, or will anti-bot middleware block me?". Today the agent has to open
7
+ * the page, poke `network`, try cURL, fail, guess again. This module condenses
8
+ * that into one call that returns a classification + evidence.
9
+ *
10
+ * Kept pure (no page imports) so the bulk is unit-testable; the CLI wrapper
11
+ * drives a real page, feeds the resulting signals here, and prints the verdict.
12
+ */
13
+ /**
14
+ * WAF vendors we can reliably detect from cookies + response body markers
15
+ * alone. Signals are orthogonal per vendor — so when two vendors match
16
+ * simultaneously (rare), we keep all evidence and report the higher-signal
17
+ * vendor first.
18
+ */
19
+ const WAF_SIGNATURES = [
20
+ {
21
+ vendor: 'aliyun_waf',
22
+ cookiePatterns: [/^acw_sc__v2$/, /^acw_tc$/, /^ssxmod_itna/],
23
+ bodyPatterns: [/arg1\s*=\s*['"][0-9A-F]{30,}/, /\/ntc_captcha\//i],
24
+ implication: 'Direct Node-side fetch/curl will return the slider HTML. Validate the endpoint in browser context first; HTML COOKIE adapters still finish with Node-side fetch + page.getCookies.',
25
+ },
26
+ {
27
+ vendor: 'cloudflare',
28
+ cookiePatterns: [/^__cf_bm$/, /^cf_clearance$/, /^__cfduid$/],
29
+ bodyPatterns: [/Cloudflare Ray ID/i, /Checking your browser before accessing/i, /cf-chl-/i],
30
+ implication: 'Cloudflare bot check. Start from a real browser session; probe in browser context first. HTML COOKIE adapters still finish with Node-side fetch + page.getCookies.',
31
+ },
32
+ {
33
+ vendor: 'akamai',
34
+ cookiePatterns: [/^_abck$/, /^bm_sz$/, /^bm_sv$/],
35
+ bodyPatterns: [/akamai/i],
36
+ implication: 'Akamai Bot Manager. Probe in browser context first; keep final HTML COOKIE adapters on Node-side fetch + page.getCookies.',
37
+ },
38
+ {
39
+ vendor: 'geetest',
40
+ cookiePatterns: [],
41
+ bodyPatterns: [/geetest/i, /gt_captcha/i],
42
+ implication: 'Geetest slider/puzzle captcha. Agent cannot bypass programmatically — requires UI strategy or human-in-loop.',
43
+ },
44
+ ];
45
+ export function detectAntiBot(signals) {
46
+ const evidence = [];
47
+ let match = null;
48
+ for (const sig of WAF_SIGNATURES) {
49
+ const hits = [];
50
+ for (const pat of sig.cookiePatterns) {
51
+ const hit = signals.cookieNames.find((c) => pat.test(c));
52
+ if (hit)
53
+ hits.push(`cookie:${hit}`);
54
+ }
55
+ for (const pat of sig.bodyPatterns) {
56
+ for (const entry of signals.networkEntries) {
57
+ if (entry.bodyPreview && pat.test(entry.bodyPreview)) {
58
+ hits.push(`body:${entry.url}`);
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ if (hits.length > 0 && !match) {
64
+ match = sig;
65
+ evidence.push(...hits);
66
+ }
67
+ }
68
+ if (!match) {
69
+ return {
70
+ detected: false,
71
+ vendor: null,
72
+ evidence: [],
73
+ implication: 'No known anti-bot signatures. Try Node-side COOKIE fetch first; if endpoint validation is blocked, retry from browser context.',
74
+ };
75
+ }
76
+ return {
77
+ detected: true,
78
+ vendor: match.vendor,
79
+ evidence,
80
+ implication: match.implication,
81
+ };
82
+ }
83
+ const NOISE_URL_RE = /(?:analytics|beacon|collect|telemetry|tracking|sentry|doubleclick|google-analytics|googletagmanager|adservice|\/ads?(?:[/?#]|$)|metrics?|pixel|personalization|experiment|\/events?(?:[/?#]|$))/i;
84
+ const BUSINESS_KEY_RE = /^(?:data|items?|results?|records?|list|rows?|edges?|nodes?|timeline|users?|title|name|text|content|body|price|amount|id|url|avatar|nickname|desc|comments?|likes?|shares?|total|page|cursor|next|rank|score|date|time|author)$/i;
85
+ const TRACKING_KEY_RE = /^(?:event|events|trace|traceid|sessionid|clientid|visitorid|experiment|abtest|beacon|analytics|metrics?|pixel|log|logs)$/i;
86
+ function clampScore(value) {
87
+ return Math.max(0, Math.min(1, Math.round(value * 100) / 100));
88
+ }
89
+ function parseBodyPreview(preview) {
90
+ if (!preview)
91
+ return null;
92
+ const trimmed = preview.trim();
93
+ if (!trimmed)
94
+ return null;
95
+ try {
96
+ return JSON.parse(trimmed);
97
+ }
98
+ catch {
99
+ return trimmed;
100
+ }
101
+ }
102
+ function collectJsonPaths(value, prefix = '$', out = [], depth = 0) {
103
+ if (depth > 4 || out.length >= 24)
104
+ return out;
105
+ if (Array.isArray(value)) {
106
+ out.push(`${prefix}:array(${value.length})`);
107
+ if (value.length > 0)
108
+ collectJsonPaths(value[0], `${prefix}[0]`, out, depth + 1);
109
+ return out;
110
+ }
111
+ if (!value || typeof value !== 'object') {
112
+ out.push(`${prefix}:${typeof value}`);
113
+ return out;
114
+ }
115
+ const entries = Object.entries(value).slice(0, 12);
116
+ for (const [key, child] of entries) {
117
+ out.push(`${prefix}.${key}`);
118
+ if (Array.isArray(child))
119
+ out.push(`${prefix}.${key}:array(${child.length})`);
120
+ else if (child && typeof child === 'object')
121
+ collectJsonPaths(child, `${prefix}.${key}`, out, depth + 1);
122
+ else
123
+ out.push(`${prefix}.${key}:${typeof child}`);
124
+ }
125
+ return out;
126
+ }
127
+ function countKeys(value, predicate, depth = 0) {
128
+ if (depth > 4 || !value || typeof value !== 'object')
129
+ return 0;
130
+ if (Array.isArray(value))
131
+ return value.slice(0, 3).reduce((sum, item) => sum + countKeys(item, predicate, depth + 1), 0);
132
+ return Object.entries(value).reduce((sum, [key, child]) => (sum + (predicate(key) ? 1 : 0) + countKeys(child, predicate, depth + 1)), 0);
133
+ }
134
+ function hasNonEmptyArray(value, depth = 0) {
135
+ if (depth > 4 || !value || typeof value !== 'object')
136
+ return false;
137
+ if (Array.isArray(value))
138
+ return value.length > 0;
139
+ return Object.values(value).some((child) => hasNonEmptyArray(child, depth + 1));
140
+ }
141
+ export function scoreEndpointEvidence(entry) {
142
+ const reasons = [];
143
+ const body = parseBodyPreview(entry.bodyPreview);
144
+ let score = 0;
145
+ if (entry.status >= 200 && entry.status < 300) {
146
+ score += 0.15;
147
+ reasons.push('2xx status');
148
+ }
149
+ else if (entry.status === 401 || entry.status === 403) {
150
+ return {
151
+ url: entry.url,
152
+ status: entry.status,
153
+ contentType: entry.contentType,
154
+ real_data_score: 0.05,
155
+ verdict: 'blocked',
156
+ reasons: ['auth-blocked status'],
157
+ sample_paths: [],
158
+ };
159
+ }
160
+ else {
161
+ reasons.push(`non-2xx status ${entry.status}`);
162
+ }
163
+ if (/json/i.test(entry.contentType)) {
164
+ score += 0.2;
165
+ reasons.push('json content-type');
166
+ }
167
+ else if (/html/i.test(entry.contentType)) {
168
+ score -= 0.25;
169
+ reasons.push('html content-type');
170
+ }
171
+ else if (/javascript|text/i.test(entry.contentType)) {
172
+ score += 0.05;
173
+ reasons.push('text/script content-type');
174
+ }
175
+ if (NOISE_URL_RE.test(entry.url)) {
176
+ score -= 0.3;
177
+ reasons.push('telemetry-like url');
178
+ }
179
+ const samplePaths = collectJsonPaths(body).slice(0, 8);
180
+ if (typeof body === 'string') {
181
+ if (/^\s*</.test(body) || /<!doctype html|<html/i.test(body)) {
182
+ score -= 0.25;
183
+ reasons.push('html body');
184
+ }
185
+ else if (body.trim().length > 20) {
186
+ score += 0.05;
187
+ reasons.push('non-empty text body');
188
+ }
189
+ }
190
+ else if (Array.isArray(body)) {
191
+ if (body.length > 0) {
192
+ score += 0.3;
193
+ reasons.push('non-empty top-level array');
194
+ }
195
+ else {
196
+ score -= 0.15;
197
+ reasons.push('empty array');
198
+ }
199
+ }
200
+ else if (body && typeof body === 'object') {
201
+ const keys = Object.keys(body);
202
+ if (keys.length === 0) {
203
+ score -= 0.15;
204
+ reasons.push('empty object');
205
+ }
206
+ else {
207
+ score += 0.12;
208
+ reasons.push('json object body');
209
+ }
210
+ const businessKeys = countKeys(body, (key) => BUSINESS_KEY_RE.test(key));
211
+ if (businessKeys > 0) {
212
+ score += Math.min(0.3, businessKeys * 0.05);
213
+ reasons.push(`${businessKeys} business-like key${businessKeys === 1 ? '' : 's'}`);
214
+ }
215
+ if (hasNonEmptyArray(body)) {
216
+ score += 0.2;
217
+ reasons.push('nested non-empty array');
218
+ }
219
+ const trackingKeys = countKeys(body, (key) => TRACKING_KEY_RE.test(key));
220
+ if (trackingKeys > 0 && businessKeys === 0) {
221
+ score -= Math.min(0.25, trackingKeys * 0.08);
222
+ reasons.push(`${trackingKeys} tracking-like key${trackingKeys === 1 ? '' : 's'} without business keys`);
223
+ }
224
+ }
225
+ const realDataScore = clampScore(score);
226
+ const verdict = realDataScore >= 0.65
227
+ ? 'likely_data'
228
+ : realDataScore >= 0.35
229
+ ? 'maybe_data'
230
+ : 'noise';
231
+ return {
232
+ url: entry.url,
233
+ status: entry.status,
234
+ contentType: entry.contentType,
235
+ real_data_score: realDataScore,
236
+ verdict,
237
+ reasons,
238
+ sample_paths: samplePaths,
239
+ };
240
+ }
241
+ export function scoreNetworkEvidence(signals) {
242
+ return signals.networkEntries
243
+ .map(scoreEndpointEvidence)
244
+ .filter((evidence) => evidence.verdict !== 'noise' || evidence.real_data_score > 0)
245
+ .sort((a, b) => b.real_data_score - a.real_data_score)
246
+ .slice(0, 8);
247
+ }
248
+ /**
249
+ * Apply the decision tree from `site-recon.md` mechanically.
250
+ *
251
+ * B beats A when initial-state globals are present: even if the page fetches
252
+ * more data via XHR afterwards, the SSR payload is the highest-leverage source.
253
+ * D (token-gated) dominates when we see 401/403 on what looks like API
254
+ * endpoints — without that, an authenticated route looks identical to A.
255
+ */
256
+ export function classifyPattern(signals) {
257
+ const jsonEntries = signals.networkEntries.filter((e) => /json/i.test(e.contentType));
258
+ const endpointEvidence = scoreNetworkEvidence(signals);
259
+ const realDataCandidates = endpointEvidence.filter((e) => e.verdict === 'likely_data' || e.verdict === 'maybe_data').length;
260
+ const authFailures = signals.networkEntries.filter((e) => e.status === 401 || e.status === 403).length;
261
+ const hasInitialState = signals.initialState.__INITIAL_STATE__ ||
262
+ signals.initialState.__NUXT__ ||
263
+ signals.initialState.__NEXT_DATA__ ||
264
+ signals.initialState.__APOLLO_STATE__;
265
+ if (authFailures >= 2 && jsonEntries.length >= 1) {
266
+ return {
267
+ pattern: 'D',
268
+ reason: `${authFailures} auth-failing API responses seen — endpoint is token-gated`,
269
+ json_responses: jsonEntries.length,
270
+ real_data_candidates: realDataCandidates,
271
+ auth_failures: authFailures,
272
+ };
273
+ }
274
+ if (hasInitialState) {
275
+ const which = Object.entries(signals.initialState)
276
+ .filter(([, v]) => v)
277
+ .map(([k]) => k);
278
+ return {
279
+ pattern: 'B',
280
+ reason: `SSR state global present: ${which.join(', ')}`,
281
+ json_responses: jsonEntries.length,
282
+ real_data_candidates: realDataCandidates,
283
+ auth_failures: authFailures,
284
+ };
285
+ }
286
+ if (realDataCandidates >= 1) {
287
+ return {
288
+ pattern: 'A',
289
+ reason: `${realDataCandidates} captured response${realDataCandidates === 1 ? '' : 's'} look like real data — inspect api_candidates before choosing a strategy`,
290
+ json_responses: jsonEntries.length,
291
+ real_data_candidates: realDataCandidates,
292
+ auth_failures: authFailures,
293
+ };
294
+ }
295
+ // No API, no SSR state — probably static HTML or a bundled SPA that lazy-loads.
296
+ // Pattern C (HTML scrape) is the default fallback; E (streaming) we can't
297
+ // reliably detect without watching WebSocket frames, so we label 'C' and
298
+ // leave the agent to upgrade to E manually if they see WS traffic.
299
+ return {
300
+ pattern: 'C',
301
+ reason: jsonEntries.length > 0
302
+ ? `${jsonEntries.length} JSON response${jsonEntries.length === 1 ? '' : 's'} observed, but none look like target data — likely telemetry/side-channel; treat as HTML/DOM until an endpoint validates`
303
+ : 'No JSON XHR and no SSR state — HTML scrape (Pattern C); escalate to E manually if WebSocket traffic appears',
304
+ json_responses: jsonEntries.length,
305
+ real_data_candidates: realDataCandidates,
306
+ auth_failures: authFailures,
307
+ };
308
+ }
309
+ /**
310
+ * Find existing adapters that target the same site.
311
+ *
312
+ * Keep the hostname match simple — agents extend naming conventions
313
+ * differently per site, so we match on the registered `domain` field and fall
314
+ * back to site-name containment. Returning `null` is fine; agents can always
315
+ * read site-memory docs.
316
+ */
317
+ export function findNearestAdapter(finalUrl, registry) {
318
+ let host;
319
+ try {
320
+ host = new URL(finalUrl).hostname;
321
+ }
322
+ catch {
323
+ return null;
324
+ }
325
+ // Strip leading www.; 'www' as a site identifier is never what an adapter uses.
326
+ const cleanedHost = host.replace(/^www\./, '');
327
+ // Extract apex (xx.com) and registrable parts for fuzzy match.
328
+ const parts = cleanedHost.split('.');
329
+ const apex = parts.slice(-2).join('.');
330
+ const siteKey = parts.length > 1 ? parts[parts.length - 2] : cleanedHost;
331
+ const hits = new Map();
332
+ for (const cmd of registry.values()) {
333
+ const domain = cmd.domain?.toLowerCase();
334
+ const siteMatches = (domain && (cleanedHost.endsWith(domain) || domain.endsWith(apex))) ||
335
+ cmd.site.toLowerCase() === siteKey?.toLowerCase() ||
336
+ cleanedHost.includes(cmd.site.toLowerCase());
337
+ if (siteMatches) {
338
+ const list = hits.get(cmd.site) ?? [];
339
+ list.push(cmd);
340
+ hits.set(cmd.site, list);
341
+ }
342
+ }
343
+ if (hits.size === 0)
344
+ return null;
345
+ // Pick the site with the most commands — likely the most-developed adapter,
346
+ // and the best reference for a new command on the same host.
347
+ let best = null;
348
+ for (const entry of hits) {
349
+ if (!best || entry[1].length > best[1].length)
350
+ best = entry;
351
+ }
352
+ if (!best)
353
+ return null;
354
+ return {
355
+ site: best[0],
356
+ example_commands: best[1].slice(0, 5).map((c) => `${c.site} ${c.name}`),
357
+ reason: `${best[1].length} existing adapter${best[1].length === 1 ? '' : 's'} target this site — reuse strategy/cookie config`,
358
+ };
359
+ }
360
+ /**
361
+ * Synthesize the verdict from collected signals + registry.
362
+ *
363
+ * The `recommended_next_step` is deliberately a single imperative
364
+ * sentence — agents act on it directly instead of re-deriving advice from
365
+ * the structured fields.
366
+ */
367
+ export function analyzeSite(signals, registry) {
368
+ const pattern = classifyPattern(signals);
369
+ const antiBot = detectAntiBot(signals);
370
+ const apiCandidates = scoreNetworkEvidence(signals);
371
+ const nearest = findNearestAdapter(signals.finalUrl, registry);
372
+ let next;
373
+ if (antiBot.detected) {
374
+ next = antiBot.implication;
375
+ }
376
+ else if (pattern.pattern === 'A') {
377
+ next = 'Inspect `api_candidates`, then replay the best endpoint and record the status/content-type/sample shape in your strategy note; do not choose API strategy from XHR count alone.';
378
+ }
379
+ else if (pattern.pattern === 'B') {
380
+ next = 'Read the SSR global via `webcmd browser eval "JSON.stringify(window.__INITIAL_STATE__ ?? window.__NUXT__ ?? window.__NEXT_DATA__ ?? window.__APOLLO_STATE__)"` — no API needed.';
381
+ }
382
+ else if (pattern.pattern === 'C') {
383
+ next = 'No API visible — use SSR HTML scrape (e.g. `webcmd browser extract`) against the rendered page.';
384
+ }
385
+ else if (pattern.pattern === 'D') {
386
+ next = 'Endpoints need auth. Re-open the page from a signed-in session, then retry analyze; see `field-decode-playbook` §4 for token tracing.';
387
+ }
388
+ else if (pattern.pattern === 'E') {
389
+ next = 'WebSocket stream detected — find the underlying HTTP poll/long-poll endpoint; raw WS is not supported.';
390
+ }
391
+ else {
392
+ next = 'No strong signal. Manually inspect `webcmd browser network --all` and pick a pattern.';
393
+ }
394
+ return {
395
+ requested_url: signals.requestedUrl,
396
+ final_url: signals.finalUrl,
397
+ title: signals.title,
398
+ pattern,
399
+ anti_bot: antiBot,
400
+ initial_state: signals.initialState,
401
+ api_candidates: apiCandidates,
402
+ nearest_adapter: nearest,
403
+ recommended_next_step: next,
404
+ };
405
+ }
@@ -0,0 +1 @@
1
+ export {};