browxai 0.7.0

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 (520) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/THIRD_PARTY_NOTICES.md +45 -0
  4. package/dist/cli/chrome.d.ts +1 -0
  5. package/dist/cli/chrome.js +130 -0
  6. package/dist/cli/command-registry.d.ts +15 -0
  7. package/dist/cli/command-registry.js +35 -0
  8. package/dist/cli/doctor-plugins.d.ts +18 -0
  9. package/dist/cli/doctor-plugins.js +338 -0
  10. package/dist/cli/doctor.d.ts +9 -0
  11. package/dist/cli/doctor.js +407 -0
  12. package/dist/cli/init.d.ts +1 -0
  13. package/dist/cli/init.js +200 -0
  14. package/dist/cli/register-commands.d.ts +1 -0
  15. package/dist/cli/register-commands.js +22 -0
  16. package/dist/cli/serve.d.ts +14 -0
  17. package/dist/cli/serve.js +151 -0
  18. package/dist/cli.d.ts +3 -0
  19. package/dist/cli.js +129 -0
  20. package/dist/engine/adapters/adb.d.ts +72 -0
  21. package/dist/engine/adapters/adb.js +200 -0
  22. package/dist/engine/adapters/android-cdp.d.ts +54 -0
  23. package/dist/engine/adapters/android-cdp.js +110 -0
  24. package/dist/engine/adapters/android.engine.d.ts +1 -0
  25. package/dist/engine/adapters/android.engine.js +31 -0
  26. package/dist/engine/adapters/chromium.engine.d.ts +1 -0
  27. package/dist/engine/adapters/chromium.engine.js +44 -0
  28. package/dist/engine/adapters/firefox.engine.d.ts +1 -0
  29. package/dist/engine/adapters/firefox.engine.js +43 -0
  30. package/dist/engine/adapters/playwright-chromium.d.ts +43 -0
  31. package/dist/engine/adapters/playwright-chromium.js +56 -0
  32. package/dist/engine/adapters/playwright-firefox.d.ts +52 -0
  33. package/dist/engine/adapters/playwright-firefox.js +97 -0
  34. package/dist/engine/adapters/playwright-webkit.d.ts +40 -0
  35. package/dist/engine/adapters/playwright-webkit.js +79 -0
  36. package/dist/engine/adapters/safari/bidi-client.d.ts +46 -0
  37. package/dist/engine/adapters/safari/bidi-client.js +130 -0
  38. package/dist/engine/adapters/safari/launch.d.ts +56 -0
  39. package/dist/engine/adapters/safari/launch.js +104 -0
  40. package/dist/engine/adapters/safari/webdriver-client.d.ts +102 -0
  41. package/dist/engine/adapters/safari/webdriver-client.js +175 -0
  42. package/dist/engine/adapters/safari.engine.d.ts +1 -0
  43. package/dist/engine/adapters/safari.engine.js +52 -0
  44. package/dist/engine/adapters/safaridriver-hybrid.d.ts +56 -0
  45. package/dist/engine/adapters/safaridriver-hybrid.js +127 -0
  46. package/dist/engine/adapters/webkit.engine.d.ts +1 -0
  47. package/dist/engine/adapters/webkit.engine.js +47 -0
  48. package/dist/engine/capabilities.d.ts +53 -0
  49. package/dist/engine/capabilities.js +122 -0
  50. package/dist/engine/capability-registry.d.ts +9 -0
  51. package/dist/engine/capability-registry.js +20 -0
  52. package/dist/engine/index.d.ts +18 -0
  53. package/dist/engine/index.js +14 -0
  54. package/dist/engine/register-engines.d.ts +5 -0
  55. package/dist/engine/register-engines.js +16 -0
  56. package/dist/engine/registry.d.ts +145 -0
  57. package/dist/engine/registry.js +67 -0
  58. package/dist/engine/select.d.ts +48 -0
  59. package/dist/engine/select.js +128 -0
  60. package/dist/engine/session-cdp.d.ts +13 -0
  61. package/dist/engine/session-cdp.js +22 -0
  62. package/dist/engine/tool-gate.d.ts +19 -0
  63. package/dist/engine/tool-gate.js +226 -0
  64. package/dist/engine/types.d.ts +71 -0
  65. package/dist/engine/types.js +16 -0
  66. package/dist/helper/bridge.d.ts +48 -0
  67. package/dist/helper/bridge.js +200 -0
  68. package/dist/helper/browx-page.d.ts +1 -0
  69. package/dist/helper/browx-page.js +47 -0
  70. package/dist/helper/overlay-hide.d.ts +9 -0
  71. package/dist/helper/overlay-hide.js +49 -0
  72. package/dist/helper/stealth.d.ts +10 -0
  73. package/dist/helper/stealth.js +88 -0
  74. package/dist/index.d.ts +7 -0
  75. package/dist/index.js +15 -0
  76. package/dist/page/a11y.d.ts +81 -0
  77. package/dist/page/a11y.js +219 -0
  78. package/dist/page/action-substrate.d.ts +64 -0
  79. package/dist/page/action-substrate.js +118 -0
  80. package/dist/page/actionresult-blocks.d.ts +99 -0
  81. package/dist/page/actionresult-blocks.js +144 -0
  82. package/dist/page/actionresult-shape.d.ts +48 -0
  83. package/dist/page/actionresult-shape.js +155 -0
  84. package/dist/page/actionresult-types.d.ts +368 -0
  85. package/dist/page/actionresult-types.js +4 -0
  86. package/dist/page/actionresult.d.ts +4 -0
  87. package/dist/page/actionresult.js +299 -0
  88. package/dist/page/actions-probe.d.ts +32 -0
  89. package/dist/page/actions-probe.js +294 -0
  90. package/dist/page/actions-scroll.d.ts +40 -0
  91. package/dist/page/actions-scroll.js +53 -0
  92. package/dist/page/actions.d.ts +132 -0
  93. package/dist/page/actions.js +453 -0
  94. package/dist/page/archive-assets.d.ts +39 -0
  95. package/dist/page/archive-assets.js +187 -0
  96. package/dist/page/archive.d.ts +47 -0
  97. package/dist/page/archive.js +349 -0
  98. package/dist/page/asset-export.d.ts +122 -0
  99. package/dist/page/asset-export.js +376 -0
  100. package/dist/page/await_network.d.ts +16 -0
  101. package/dist/page/await_network.js +23 -0
  102. package/dist/page/bbox.d.ts +37 -0
  103. package/dist/page/bbox.js +115 -0
  104. package/dist/page/canvas-capture.d.ts +82 -0
  105. package/dist/page/canvas-capture.js +257 -0
  106. package/dist/page/canvas-diff.d.ts +51 -0
  107. package/dist/page/canvas-diff.js +131 -0
  108. package/dist/page/canvas-gesture.d.ts +53 -0
  109. package/dist/page/canvas-gesture.js +167 -0
  110. package/dist/page/canvas-transform.d.ts +96 -0
  111. package/dist/page/canvas-transform.js +150 -0
  112. package/dist/page/canvas.d.ts +8 -0
  113. package/dist/page/canvas.js +50 -0
  114. package/dist/page/capture-substrate.d.ts +111 -0
  115. package/dist/page/capture-substrate.js +139 -0
  116. package/dist/page/clipboard.d.ts +25 -0
  117. package/dist/page/clipboard.js +50 -0
  118. package/dist/page/clock.d.ts +36 -0
  119. package/dist/page/clock.js +167 -0
  120. package/dist/page/compose.d.ts +55 -0
  121. package/dist/page/compose.js +169 -0
  122. package/dist/page/console.d.ts +39 -0
  123. package/dist/page/console.js +73 -0
  124. package/dist/page/coverage.d.ts +97 -0
  125. package/dist/page/coverage.js +280 -0
  126. package/dist/page/dom-export.d.ts +41 -0
  127. package/dist/page/dom-export.js +193 -0
  128. package/dist/page/dom-walk.d.ts +91 -0
  129. package/dist/page/dom-walk.js +267 -0
  130. package/dist/page/dom_diff.d.ts +48 -0
  131. package/dist/page/dom_diff.js +121 -0
  132. package/dist/page/downloads.d.ts +80 -0
  133. package/dist/page/downloads.js +244 -0
  134. package/dist/page/drop-files.d.ts +78 -0
  135. package/dist/page/drop-files.js +310 -0
  136. package/dist/page/element-export-discovery.d.ts +64 -0
  137. package/dist/page/element-export-discovery.js +346 -0
  138. package/dist/page/element-export.d.ts +46 -0
  139. package/dist/page/element-export.js +251 -0
  140. package/dist/page/emulation-substrate.d.ts +53 -0
  141. package/dist/page/emulation-substrate.js +87 -0
  142. package/dist/page/emulation.d.ts +60 -0
  143. package/dist/page/emulation.js +162 -0
  144. package/dist/page/export-playwright-script.d.ts +47 -0
  145. package/dist/page/export-playwright-script.js +304 -0
  146. package/dist/page/extract-resolve.d.ts +22 -0
  147. package/dist/page/extract-resolve.js +341 -0
  148. package/dist/page/extract-schema.d.ts +20 -0
  149. package/dist/page/extract-schema.js +200 -0
  150. package/dist/page/extract-types.d.ts +127 -0
  151. package/dist/page/extract-types.js +8 -0
  152. package/dist/page/extract-warnings.d.ts +8 -0
  153. package/dist/page/extract-warnings.js +56 -0
  154. package/dist/page/extract.d.ts +9 -0
  155. package/dist/page/extract.js +174 -0
  156. package/dist/page/fill-form.d.ts +58 -0
  157. package/dist/page/fill-form.js +261 -0
  158. package/dist/page/find.d.ts +158 -0
  159. package/dist/page/find.js +470 -0
  160. package/dist/page/frames.d.ts +45 -0
  161. package/dist/page/frames.js +133 -0
  162. package/dist/page/generate-locator.d.ts +57 -0
  163. package/dist/page/generate-locator.js +136 -0
  164. package/dist/page/gestures.d.ts +128 -0
  165. package/dist/page/gestures.js +198 -0
  166. package/dist/page/har.d.ts +91 -0
  167. package/dist/page/har.js +174 -0
  168. package/dist/page/heap.d.ts +97 -0
  169. package/dist/page/heap.js +285 -0
  170. package/dist/page/inspect.d.ts +34 -0
  171. package/dist/page/inspect.js +75 -0
  172. package/dist/page/layout-thrash.d.ts +34 -0
  173. package/dist/page/layout-thrash.js +232 -0
  174. package/dist/page/learning.d.ts +21 -0
  175. package/dist/page/learning.js +84 -0
  176. package/dist/page/locator.d.ts +54 -0
  177. package/dist/page/locator.js +142 -0
  178. package/dist/page/memory-diff.d.ts +48 -0
  179. package/dist/page/memory-diff.js +105 -0
  180. package/dist/page/network-mask.d.ts +8 -0
  181. package/dist/page/network-mask.js +18 -0
  182. package/dist/page/network-playwright.d.ts +96 -0
  183. package/dist/page/network-playwright.js +353 -0
  184. package/dist/page/network-substrate-select.d.ts +18 -0
  185. package/dist/page/network-substrate-select.js +32 -0
  186. package/dist/page/network-substrate.d.ts +109 -0
  187. package/dist/page/network-substrate.js +161 -0
  188. package/dist/page/network-ws.d.ts +46 -0
  189. package/dist/page/network-ws.js +113 -0
  190. package/dist/page/network.d.ts +194 -0
  191. package/dist/page/network.js +415 -0
  192. package/dist/page/overflow-detect.d.ts +102 -0
  193. package/dist/page/overflow-detect.js +449 -0
  194. package/dist/page/pdf.d.ts +69 -0
  195. package/dist/page/pdf.js +109 -0
  196. package/dist/page/perf-audit-analysers.d.ts +40 -0
  197. package/dist/page/perf-audit-analysers.js +369 -0
  198. package/dist/page/perf-audit-runner.d.ts +20 -0
  199. package/dist/page/perf-audit-runner.js +195 -0
  200. package/dist/page/perf-audit-types.d.ts +41 -0
  201. package/dist/page/perf-audit-types.js +5 -0
  202. package/dist/page/perf-audit.d.ts +37 -0
  203. package/dist/page/perf-audit.js +377 -0
  204. package/dist/page/perf.d.ts +127 -0
  205. package/dist/page/perf.js +373 -0
  206. package/dist/page/plan.d.ts +192 -0
  207. package/dist/page/plan.js +308 -0
  208. package/dist/page/point_probe.d.ts +46 -0
  209. package/dist/page/point_probe.js +99 -0
  210. package/dist/page/recording.d.ts +67 -0
  211. package/dist/page/recording.js +172 -0
  212. package/dist/page/refs.d.ts +92 -0
  213. package/dist/page/refs.js +134 -0
  214. package/dist/page/regions.d.ts +23 -0
  215. package/dist/page/regions.js +32 -0
  216. package/dist/page/routes.d.ts +40 -0
  217. package/dist/page/routes.js +87 -0
  218. package/dist/page/safari-actions.d.ts +12 -0
  219. package/dist/page/safari-actions.js +144 -0
  220. package/dist/page/sample.d.ts +64 -0
  221. package/dist/page/sample.js +216 -0
  222. package/dist/page/screenshot-on.d.ts +51 -0
  223. package/dist/page/screenshot-on.js +150 -0
  224. package/dist/page/screenshot-save.d.ts +36 -0
  225. package/dist/page/screenshot-save.js +53 -0
  226. package/dist/page/screenshot-schedule.d.ts +50 -0
  227. package/dist/page/screenshot-schedule.js +155 -0
  228. package/dist/page/script-substrate.d.ts +32 -0
  229. package/dist/page/script-substrate.js +47 -0
  230. package/dist/page/seed-random.d.ts +45 -0
  231. package/dist/page/seed-random.js +144 -0
  232. package/dist/page/set-of-marks.d.ts +96 -0
  233. package/dist/page/set-of-marks.js +245 -0
  234. package/dist/page/shadow.d.ts +136 -0
  235. package/dist/page/shadow.js +400 -0
  236. package/dist/page/shortcut.d.ts +50 -0
  237. package/dist/page/shortcut.js +147 -0
  238. package/dist/page/snapshot-substrate-safari.d.ts +30 -0
  239. package/dist/page/snapshot-substrate-safari.js +84 -0
  240. package/dist/page/snapshot-substrate-select.d.ts +24 -0
  241. package/dist/page/snapshot-substrate-select.js +34 -0
  242. package/dist/page/snapshot-substrate.d.ts +58 -0
  243. package/dist/page/snapshot-substrate.js +135 -0
  244. package/dist/page/snapshot.d.ts +24 -0
  245. package/dist/page/snapshot.js +162 -0
  246. package/dist/page/solve-captcha.d.ts +76 -0
  247. package/dist/page/solve-captcha.js +286 -0
  248. package/dist/page/storage-substrate-types.d.ts +221 -0
  249. package/dist/page/storage-substrate-types.js +6 -0
  250. package/dist/page/storage-substrate.d.ts +215 -0
  251. package/dist/page/storage-substrate.js +280 -0
  252. package/dist/page/structural.d.ts +9 -0
  253. package/dist/page/structural.js +152 -0
  254. package/dist/page/substrate-bundle-safari.d.ts +8 -0
  255. package/dist/page/substrate-bundle-safari.js +42 -0
  256. package/dist/page/substrate-bundle.d.ts +6 -0
  257. package/dist/page/substrate-bundle.js +53 -0
  258. package/dist/page/text_search.d.ts +44 -0
  259. package/dist/page/text_search.js +90 -0
  260. package/dist/page/upload.d.ts +28 -0
  261. package/dist/page/upload.js +62 -0
  262. package/dist/page/verify.d.ts +63 -0
  263. package/dist/page/verify.js +451 -0
  264. package/dist/page/video.d.ts +115 -0
  265. package/dist/page/video.js +169 -0
  266. package/dist/page/visibility.d.ts +22 -0
  267. package/dist/page/visibility.js +94 -0
  268. package/dist/page/watch.d.ts +29 -0
  269. package/dist/page/watch.js +99 -0
  270. package/dist/page/workers.d.ts +126 -0
  271. package/dist/page/workers.js +490 -0
  272. package/dist/page/ws-interactive.d.ts +82 -0
  273. package/dist/page/ws-interactive.js +318 -0
  274. package/dist/plugin/cli.d.ts +45 -0
  275. package/dist/plugin/cli.js +496 -0
  276. package/dist/plugin/command-registry.d.ts +9 -0
  277. package/dist/plugin/command-registry.js +23 -0
  278. package/dist/plugin/depgraph.d.ts +37 -0
  279. package/dist/plugin/depgraph.js +186 -0
  280. package/dist/plugin/manifest.d.ts +182 -0
  281. package/dist/plugin/manifest.js +219 -0
  282. package/dist/plugin/package-manager.d.ts +22 -0
  283. package/dist/plugin/package-manager.js +40 -0
  284. package/dist/plugin/resolver.d.ts +85 -0
  285. package/dist/plugin/resolver.js +166 -0
  286. package/dist/plugin/runtime.d.ts +77 -0
  287. package/dist/plugin/runtime.js +402 -0
  288. package/dist/plugin/types.d.ts +113 -0
  289. package/dist/plugin/types.js +4 -0
  290. package/dist/policy/confirm.d.ts +76 -0
  291. package/dist/policy/confirm.js +162 -0
  292. package/dist/policy/origin.d.ts +17 -0
  293. package/dist/policy/origin.js +79 -0
  294. package/dist/sdk/client.d.ts +21 -0
  295. package/dist/sdk/client.js +174 -0
  296. package/dist/sdk/index.d.ts +32 -0
  297. package/dist/sdk/index.js +61 -0
  298. package/dist/sdk/plugin-types.d.ts +33 -0
  299. package/dist/sdk/plugin-types.js +22 -0
  300. package/dist/sdk/registry.d.ts +17 -0
  301. package/dist/sdk/registry.js +94 -0
  302. package/dist/sdk/socket-transport.d.ts +20 -0
  303. package/dist/sdk/socket-transport.js +90 -0
  304. package/dist/sdk/tool-types.d.ts +634 -0
  305. package/dist/sdk/tool-types.js +28 -0
  306. package/dist/sdk/transport-in-process.d.ts +21 -0
  307. package/dist/sdk/transport-in-process.js +44 -0
  308. package/dist/sdk/transport-registry.d.ts +19 -0
  309. package/dist/sdk/transport-registry.js +31 -0
  310. package/dist/sdk/transport-socket.d.ts +12 -0
  311. package/dist/sdk/transport-socket.js +77 -0
  312. package/dist/sdk/transport-stdio-child.d.ts +10 -0
  313. package/dist/sdk/transport-stdio-child.js +47 -0
  314. package/dist/sdk/transport.d.ts +10 -0
  315. package/dist/sdk/transport.js +35 -0
  316. package/dist/sdk/types.d.ts +176 -0
  317. package/dist/sdk/types.js +10 -0
  318. package/dist/server.d.ts +33 -0
  319. package/dist/server.js +327 -0
  320. package/dist/session/artifacts.d.ts +52 -0
  321. package/dist/session/artifacts.js +177 -0
  322. package/dist/session/byob-attach.d.ts +26 -0
  323. package/dist/session/byob-attach.js +187 -0
  324. package/dist/session/byob.d.ts +8 -0
  325. package/dist/session/byob.js +20 -0
  326. package/dist/session/cache-storage.d.ts +100 -0
  327. package/dist/session/cache-storage.js +166 -0
  328. package/dist/session/device-emu.d.ts +149 -0
  329. package/dist/session/device-emu.js +545 -0
  330. package/dist/session/device.d.ts +14 -0
  331. package/dist/session/device.js +44 -0
  332. package/dist/session/dialog.d.ts +62 -0
  333. package/dist/session/dialog.js +164 -0
  334. package/dist/session/emulation.d.ts +69 -0
  335. package/dist/session/emulation.js +168 -0
  336. package/dist/session/extensions.d.ts +113 -0
  337. package/dist/session/extensions.js +237 -0
  338. package/dist/session/fs-picker.d.ts +144 -0
  339. package/dist/session/fs-picker.js +666 -0
  340. package/dist/session/idb-storage.d.ts +86 -0
  341. package/dist/session/idb-storage.js +229 -0
  342. package/dist/session/incognito.d.ts +3 -0
  343. package/dist/session/incognito.js +20 -0
  344. package/dist/session/launch-options.d.ts +41 -0
  345. package/dist/session/launch-options.js +200 -0
  346. package/dist/session/managed.d.ts +3 -0
  347. package/dist/session/managed.js +16 -0
  348. package/dist/session/metrics.d.ts +45 -0
  349. package/dist/session/metrics.js +75 -0
  350. package/dist/session/notification.d.ts +122 -0
  351. package/dist/session/notification.js +426 -0
  352. package/dist/session/permission.d.ts +144 -0
  353. package/dist/session/permission.js +600 -0
  354. package/dist/session/playwright-post-wire.d.ts +8 -0
  355. package/dist/session/playwright-post-wire.js +148 -0
  356. package/dist/session/policy-buffer.d.ts +21 -0
  357. package/dist/session/policy-buffer.js +47 -0
  358. package/dist/session/profile-snapshot.d.ts +11 -0
  359. package/dist/session/profile-snapshot.js +53 -0
  360. package/dist/session/registry.d.ts +365 -0
  361. package/dist/session/registry.js +98 -0
  362. package/dist/session/safari-post-wire.d.ts +8 -0
  363. package/dist/session/safari-post-wire.js +28 -0
  364. package/dist/session/safari-session.d.ts +10 -0
  365. package/dist/session/safari-session.js +39 -0
  366. package/dist/session/storage.d.ts +148 -0
  367. package/dist/session/storage.js +350 -0
  368. package/dist/session/types.d.ts +113 -0
  369. package/dist/session/types.js +5 -0
  370. package/dist/session/wedge.d.ts +15 -0
  371. package/dist/session/wedge.js +41 -0
  372. package/dist/tools/action-core-tools.d.ts +13 -0
  373. package/dist/tools/action-core-tools.js +156 -0
  374. package/dist/tools/action-form-tools.d.ts +12 -0
  375. package/dist/tools/action-form-tools.js +179 -0
  376. package/dist/tools/action-gesture-tools.d.ts +9 -0
  377. package/dist/tools/action-gesture-tools.js +115 -0
  378. package/dist/tools/action-history-tools.d.ts +8 -0
  379. package/dist/tools/action-history-tools.js +67 -0
  380. package/dist/tools/action-tool.d.ts +42 -0
  381. package/dist/tools/action-tool.js +58 -0
  382. package/dist/tools/action-tools.d.ts +20 -0
  383. package/dist/tools/action-tools.js +28 -0
  384. package/dist/tools/batch-act-tools.d.ts +10 -0
  385. package/dist/tools/batch-act-tools.js +276 -0
  386. package/dist/tools/batch-human-tools.d.ts +8 -0
  387. package/dist/tools/batch-human-tools.js +148 -0
  388. package/dist/tools/canvas-tools.d.ts +40 -0
  389. package/dist/tools/canvas-tools.js +368 -0
  390. package/dist/tools/capture-report-diagnostics-tools.d.ts +7 -0
  391. package/dist/tools/capture-report-diagnostics-tools.js +318 -0
  392. package/dist/tools/capture-report-element-export-tools.d.ts +8 -0
  393. package/dist/tools/capture-report-element-export-tools.js +197 -0
  394. package/dist/tools/capture-report-export-tools.d.ts +8 -0
  395. package/dist/tools/capture-report-export-tools.js +246 -0
  396. package/dist/tools/capture-report-marks-tools.d.ts +9 -0
  397. package/dist/tools/capture-report-marks-tools.js +221 -0
  398. package/dist/tools/capture-report-upload-tools.d.ts +8 -0
  399. package/dist/tools/capture-report-upload-tools.js +277 -0
  400. package/dist/tools/config-approval-tools.d.ts +8 -0
  401. package/dist/tools/config-approval-tools.js +166 -0
  402. package/dist/tools/deep-coverage-tools.d.ts +8 -0
  403. package/dist/tools/deep-coverage-tools.js +325 -0
  404. package/dist/tools/deep-determinism-tools.d.ts +8 -0
  405. package/dist/tools/deep-determinism-tools.js +276 -0
  406. package/dist/tools/deep-perf-tools.d.ts +19 -0
  407. package/dist/tools/deep-perf-tools.js +324 -0
  408. package/dist/tools/device-emulation-tools.d.ts +9 -0
  409. package/dist/tools/device-emulation-tools.js +137 -0
  410. package/dist/tools/extensions-batch-tools.d.ts +18 -0
  411. package/dist/tools/extensions-batch-tools.js +24 -0
  412. package/dist/tools/extensions-rebuild.d.ts +22 -0
  413. package/dist/tools/extensions-rebuild.js +208 -0
  414. package/dist/tools/extensions-tools.d.ts +2 -0
  415. package/dist/tools/extensions-tools.js +331 -0
  416. package/dist/tools/forms-fill-tools.d.ts +8 -0
  417. package/dist/tools/forms-fill-tools.js +109 -0
  418. package/dist/tools/forms-plan-tools.d.ts +7 -0
  419. package/dist/tools/forms-plan-tools.js +159 -0
  420. package/dist/tools/forms-recording-mode-tools.d.ts +8 -0
  421. package/dist/tools/forms-recording-mode-tools.js +71 -0
  422. package/dist/tools/forms-recording-tools.d.ts +14 -0
  423. package/dist/tools/forms-recording-tools.js +22 -0
  424. package/dist/tools/forms-refs-tools.d.ts +8 -0
  425. package/dist/tools/forms-refs-tools.js +90 -0
  426. package/dist/tools/gesture-coord-tools.d.ts +8 -0
  427. package/dist/tools/gesture-coord-tools.js +168 -0
  428. package/dist/tools/gesture-emulation-tools.d.ts +8 -0
  429. package/dist/tools/gesture-emulation-tools.js +135 -0
  430. package/dist/tools/gesture-network-tools.d.ts +17 -0
  431. package/dist/tools/gesture-network-tools.js +27 -0
  432. package/dist/tools/gesture-route-tools.d.ts +8 -0
  433. package/dist/tools/gesture-route-tools.js +142 -0
  434. package/dist/tools/gesture-websocket-tools.d.ts +8 -0
  435. package/dist/tools/gesture-websocket-tools.js +122 -0
  436. package/dist/tools/gesture-worker-tools.d.ts +9 -0
  437. package/dist/tools/gesture-worker-tools.js +200 -0
  438. package/dist/tools/host-build.d.ts +76 -0
  439. package/dist/tools/host-build.js +516 -0
  440. package/dist/tools/host.d.ts +287 -0
  441. package/dist/tools/host.js +1 -0
  442. package/dist/tools/input-tools.d.ts +10 -0
  443. package/dist/tools/input-tools.js +176 -0
  444. package/dist/tools/live-emulation-tools.d.ts +9 -0
  445. package/dist/tools/live-emulation-tools.js +353 -0
  446. package/dist/tools/plugin-runtime.d.ts +36 -0
  447. package/dist/tools/plugin-runtime.js +274 -0
  448. package/dist/tools/read-observe-buffer-tools.d.ts +9 -0
  449. package/dist/tools/read-observe-buffer-tools.js +385 -0
  450. package/dist/tools/read-observe-capture-tools.d.ts +12 -0
  451. package/dist/tools/read-observe-capture-tools.js +376 -0
  452. package/dist/tools/read-observe-dom-tools.d.ts +8 -0
  453. package/dist/tools/read-observe-dom-tools.js +308 -0
  454. package/dist/tools/read-observe-extract-tools.d.ts +8 -0
  455. package/dist/tools/read-observe-extract-tools.js +232 -0
  456. package/dist/tools/read-observe-verify-tools.d.ts +8 -0
  457. package/dist/tools/read-observe-verify-tools.js +316 -0
  458. package/dist/tools/schemas.d.ts +29 -0
  459. package/dist/tools/schemas.js +58 -0
  460. package/dist/tools/secrets-captcha-tools.d.ts +9 -0
  461. package/dist/tools/secrets-captcha-tools.js +231 -0
  462. package/dist/tools/session-dialog-permission-tools.d.ts +9 -0
  463. package/dist/tools/session-dialog-permission-tools.js +287 -0
  464. package/dist/tools/session-lifecycle-tools.d.ts +8 -0
  465. package/dist/tools/session-lifecycle-tools.js +314 -0
  466. package/dist/tools/session-notification-device-tools.d.ts +9 -0
  467. package/dist/tools/session-notification-device-tools.js +156 -0
  468. package/dist/tools/session-policy-tools.d.ts +16 -0
  469. package/dist/tools/session-policy-tools.js +22 -0
  470. package/dist/tools/session-registry.d.ts +28 -0
  471. package/dist/tools/session-registry.js +427 -0
  472. package/dist/tools/storage-artifact-har-video-tools.d.ts +8 -0
  473. package/dist/tools/storage-artifact-har-video-tools.js +311 -0
  474. package/dist/tools/storage-cache-idb-tools.d.ts +8 -0
  475. package/dist/tools/storage-cache-idb-tools.js +347 -0
  476. package/dist/tools/storage-state-cookies-tools.d.ts +8 -0
  477. package/dist/tools/storage-state-cookies-tools.js +223 -0
  478. package/dist/tools/storage-tools.d.ts +17 -0
  479. package/dist/tools/storage-tools.js +25 -0
  480. package/dist/tools/storage-web-auth-tools.d.ts +10 -0
  481. package/dist/tools/storage-web-auth-tools.js +230 -0
  482. package/dist/tools/tool-metadata.d.ts +8 -0
  483. package/dist/tools/tool-metadata.js +185 -0
  484. package/dist/util/batch.d.ts +83 -0
  485. package/dist/util/batch.js +191 -0
  486. package/dist/util/capabilities.d.ts +504 -0
  487. package/dist/util/capabilities.js +254 -0
  488. package/dist/util/config-store.d.ts +103 -0
  489. package/dist/util/config-store.js +206 -0
  490. package/dist/util/config.d.ts +11 -0
  491. package/dist/util/config.js +28 -0
  492. package/dist/util/credentials.d.ts +136 -0
  493. package/dist/util/credentials.js +622 -0
  494. package/dist/util/deadline.d.ts +22 -0
  495. package/dist/util/deadline.js +62 -0
  496. package/dist/util/diagnostics.d.ts +161 -0
  497. package/dist/util/diagnostics.js +579 -0
  498. package/dist/util/egress-sanitiser.d.ts +29 -0
  499. package/dist/util/egress-sanitiser.js +52 -0
  500. package/dist/util/failure.d.ts +8 -0
  501. package/dist/util/failure.js +50 -0
  502. package/dist/util/flake-check.d.ts +109 -0
  503. package/dist/util/flake-check.js +342 -0
  504. package/dist/util/invariant.d.ts +25 -0
  505. package/dist/util/invariant.js +66 -0
  506. package/dist/util/logging.d.ts +6 -0
  507. package/dist/util/logging.js +12 -0
  508. package/dist/util/predicates.d.ts +62 -0
  509. package/dist/util/predicates.js +340 -0
  510. package/dist/util/secrets.d.ts +104 -0
  511. package/dist/util/secrets.js +219 -0
  512. package/dist/util/tokens.d.ts +6 -0
  513. package/dist/util/tokens.js +24 -0
  514. package/dist/util/url-sanitizer.d.ts +19 -0
  515. package/dist/util/url-sanitizer.js +70 -0
  516. package/dist/util/version.d.ts +2 -0
  517. package/dist/util/version.js +21 -0
  518. package/dist/util/workspace.d.ts +7 -0
  519. package/dist/util/workspace.js +22 -0
  520. package/package.json +120 -0
@@ -0,0 +1,490 @@
1
+ // Web Workers + Service Workers visibility — capability `read` for listing
2
+ // and reading messages; `action` for sending messages and registering fetch
3
+ // interceptors. Sibling of `ws-interactive.ts` on the worker channel.
4
+ //
5
+ // • `workers_list({type})` — enumerate live workers (Web + SW).
6
+ // • `worker_message_send({workerId, message})` — `postMessage` to a worker.
7
+ // • `worker_messages_read({workerId?})` — drain the FROM-worker ring.
8
+ // • `sw_intercept_fetch({pattern, response})` — fulfil a SW-handled fetch.
9
+ //
10
+ // Two completely different transport stories under one façade:
11
+ //
12
+ // **Web Workers.** No CDP primitive lets us call `postMessage` on a worker we
13
+ // didn't construct. So we install a page-side wrapper of `window.Worker` at
14
+ // document-start (`Page.addInitScript`) — same shape as `ws-interactive.ts`'s
15
+ // `__browxWs`. The wrapper:
16
+ // • Assigns each worker a monotonic id (`ww-1`, `ww-2`, …).
17
+ // • Mirrors every message FROM the worker into a page-side ring
18
+ // (`window.__browxWorkers.drain(id?)` — server reads it via `evaluate`).
19
+ // • Exposes `__browxWorkers.post(id, msg)` which calls the underlying
20
+ // `Worker.prototype.postMessage` — the worker's `onmessage` sees a real
21
+ // event, not a synthetic one.
22
+ // This is the same trade-off `ws-interactive.ts` made: CDP attach-to-worker
23
+ // adds a separate session per worker for a feature (postMessage IPC) that's
24
+ // fundamentally page-side. The in-page proxy keeps the message ring naturally
25
+ // co-located with the IPC surface.
26
+ //
27
+ // **Service Workers.** SWs are independent CDP targets — `addInitScript`
28
+ // doesn't reach them, and the page-side wrapper of `Worker` is a no-op (SWs
29
+ // register via `navigator.serviceWorker.register`, not `new Worker`). So:
30
+ // • Enumerate via CDP `ServiceWorker.enable` + `ServiceWorker.workerVersionUpdated`.
31
+ // • Attach to each SW target via `Target.setAutoAttach({autoAttach:true,
32
+ // waitForDebuggerOnStart:false, flatten:true})`, then on the attached
33
+ // session run `Fetch.enable` with our pattern, and on `Fetch.requestPaused`
34
+ // call `Fetch.fulfillRequest` with the canned response. The intercept fires
35
+ // ONLY when the SW's fetch handler actually runs — i.e. the SW chose to
36
+ // intercept this URL — which is the right semantic.
37
+ // • For postMessage to a SW, the SW target has `Runtime.evaluate` so we
38
+ // dispatch a `MessageEvent` into the SW global; FROM-SW messages come back
39
+ // via a `Runtime.bindingCalled` shuttle installed on the SW session.
40
+ //
41
+ // All four primitives lazily install the page-side wrapper + lazily attach the
42
+ // CDP listeners on first call, so a session that never uses workers pays zero
43
+ // overhead.
44
+ import { globToRegex } from "./ws-interactive.js";
45
+ // ---------------------------------------------------------------------------
46
+ // Page-side wrapper script — wraps `window.Worker` exactly once. Mirrors the
47
+ // shape of `WS_PAGE_SCRIPT` in `ws-interactive.ts`. Browser-only JS, no
48
+ // TS-only syntax — this string is shipped verbatim into the page via
49
+ // `Page.addInitScript`.
50
+ export const WORKERS_PAGE_SCRIPT = `(() => {
51
+ if (window.__browxWorkers) return;
52
+ var NativeWorker = window.Worker;
53
+ if (!NativeWorker) return;
54
+ var nativePost = NativeWorker.prototype.postMessage;
55
+ var workers = new Map(); // wwId -> Worker
56
+ var messages = []; // {workerId, data, at} ring (capped at 500)
57
+ var MAX = 500;
58
+ var nextId = 1;
59
+
60
+ function recordMessage(id, payload) {
61
+ var data;
62
+ try {
63
+ data = typeof payload === "string" ? payload : JSON.stringify(payload);
64
+ } catch (_) {
65
+ data = "[unserialisable]";
66
+ }
67
+ if (data && data.length > 4000) data = data.slice(0, 4000) + "…";
68
+ messages.push({ workerId: id, data: data, at: Date.now() });
69
+ if (messages.length > MAX) messages.splice(0, messages.length - MAX);
70
+ }
71
+
72
+ function Wrapped(scriptURL, opts) {
73
+ var w = arguments.length > 1 ? new NativeWorker(scriptURL, opts) : new NativeWorker(scriptURL);
74
+ var id = "ww-" + (nextId++);
75
+ workers.set(id, w);
76
+ try { w.__browxId = id; } catch (_) {}
77
+ // Mirror every message-from-worker into the ring. We use addEventListener
78
+ // (not onmessage) so we don't fight with app-side onmessage handlers.
79
+ try {
80
+ w.addEventListener("message", function (ev) { recordMessage(id, ev.data); });
81
+ } catch (_) {}
82
+ return w;
83
+ }
84
+ Wrapped.prototype = NativeWorker.prototype;
85
+ try { Object.defineProperty(Wrapped, "name", { value: "Worker" }); } catch (_) {}
86
+ window.Worker = Wrapped;
87
+
88
+ window.__browxWorkers = {
89
+ list: function () {
90
+ var out = [];
91
+ workers.forEach(function (w, id) {
92
+ // We can't get the scriptURL back from a Worker after construction
93
+ // in all browsers — fall back to the recorded url if we tracked it,
94
+ // else the empty string. (Chromium DOES expose it via internal slot
95
+ // but not via any public API; we track it at construction via the
96
+ // initial scriptURL argument — see __browxWorkers._urls.
97
+ var url = (window.__browxWorkers._urls && window.__browxWorkers._urls.get(id)) || "";
98
+ out.push({ workerId: id, url: url });
99
+ });
100
+ return out;
101
+ },
102
+ _urls: new Map(),
103
+ post: function (id, msg) {
104
+ var w = workers.get(id);
105
+ if (!w) return { ok: false, error: "no worker with id " + id };
106
+ try {
107
+ nativePost.call(w, msg);
108
+ return { ok: true };
109
+ } catch (e) {
110
+ return { ok: false, error: e && e.message ? e.message : String(e) };
111
+ }
112
+ },
113
+ drain: function (id) {
114
+ var out;
115
+ if (id) {
116
+ out = [];
117
+ var kept = [];
118
+ for (var i = 0; i < messages.length; i++) {
119
+ if (messages[i].workerId === id) out.push(messages[i]);
120
+ else kept.push(messages[i]);
121
+ }
122
+ messages = kept;
123
+ } else {
124
+ out = messages.slice();
125
+ messages.length = 0;
126
+ }
127
+ return out;
128
+ },
129
+ };
130
+
131
+ // Track scriptURL at construction. We can't get it post-hoc on most engines.
132
+ var origWrapped = Wrapped;
133
+ window.Worker = function (scriptURL, opts) {
134
+ var w = arguments.length > 1 ? origWrapped(scriptURL, opts) : origWrapped(scriptURL);
135
+ try {
136
+ var id = w.__browxId;
137
+ if (id) {
138
+ var url = "";
139
+ try { url = String(scriptURL && scriptURL.href ? scriptURL.href : scriptURL || ""); } catch (_) {}
140
+ window.__browxWorkers._urls.set(id, url);
141
+ }
142
+ } catch (_) {}
143
+ return w;
144
+ };
145
+ window.Worker.prototype = NativeWorker.prototype;
146
+ try { Object.defineProperty(window.Worker, "name", { value: "Worker" }); } catch (_) {}
147
+ })();`;
148
+ const SW_RING_MAX = 500;
149
+ const SW_PAYLOAD_MAX = 4000;
150
+ export class WorkersRegistry {
151
+ /** SW attachments keyed by CDP sessionId. */
152
+ swAttached = new Map();
153
+ /** Stable monotonic id for the SW listing — `sw-1`, `sw-2`, …. Keyed by
154
+ * CDP sessionId so the id survives status transitions on the same SW. */
155
+ swIdBySession = new Map();
156
+ nextSwId = 1;
157
+ /** Active fetch interceptors. Re-add of the same pattern replaces. */
158
+ fetchInterceptors = new Map();
159
+ /** Server-side ring of FROM-SW messages (we relay these via a CDP
160
+ * `Runtime.bindingCalled` shuttle on each SW session). */
161
+ swMessages = [];
162
+ /** True once the page-side wrapper has been installed. */
163
+ pageInstalled = false;
164
+ /** True once we've called `ServiceWorker.enable` + wired the auto-attach
165
+ * on the top-level CDP session. */
166
+ swEnabled = false;
167
+ /** Detach functions for cleanup. */
168
+ detachers = [];
169
+ /** Install the page-side `Worker` wrapper. Idempotent. Called eagerly at
170
+ * session creation (under capability `read`) so workers opened by the
171
+ * initial document are seen — same posture as `WsInteractiveRegistry`. */
172
+ async installPageWrapper(page) {
173
+ if (this.pageInstalled)
174
+ return;
175
+ this.pageInstalled = true;
176
+ await page.context().addInitScript({ content: WORKERS_PAGE_SCRIPT });
177
+ // re-inject for the current document — addInitScript only fires on
178
+ // future navigations.
179
+ for (const p of page.context().pages()) {
180
+ await p.evaluate(WORKERS_PAGE_SCRIPT).catch(() => undefined);
181
+ }
182
+ }
183
+ /** Enable the CDP ServiceWorker domain on the session's top-level CDP and
184
+ * wire `Target.setAutoAttach` so newly-registered SWs auto-attach as child
185
+ * sessions. Idempotent. */
186
+ /** Register a CDP event handler + push its detacher onto `this.detachers`.
187
+ * The event name is dynamic here, so the strongly-typed per-event `on`/`off`
188
+ * overloads are bridged through a single untyped seam. */
189
+ onCdp(cdp, event, handler) {
190
+ const c = cdp;
191
+ c.on(event, handler);
192
+ this.detachers.push(() => c.off(event, handler));
193
+ }
194
+ /** `ServiceWorker.workerVersionUpdated` — refresh url/status on the matching
195
+ * attachment(s). */
196
+ registerVersionUpdated(cdp) {
197
+ this.onCdp(cdp, "ServiceWorker.workerVersionUpdated", (raw) => {
198
+ const e = raw;
199
+ for (const v of e.versions ?? []) {
200
+ if (!v.targetId)
201
+ continue;
202
+ for (const att of this.swAttached.values()) {
203
+ if (att.targetId === v.targetId) {
204
+ att.url = v.scriptURL || att.url;
205
+ att.status = v.runningStatus || att.status;
206
+ }
207
+ }
208
+ }
209
+ });
210
+ }
211
+ /** `Target.attachedToTarget` / `detachedFromTarget` — track the SW attachment
212
+ * map, arming any already-armed fetch interceptors on a new SW. */
213
+ registerAttachDetach(cdp) {
214
+ this.onCdp(cdp, "Target.attachedToTarget", (raw) => {
215
+ const e = raw;
216
+ if (e.targetInfo.type !== "service_worker")
217
+ return;
218
+ const att = {
219
+ targetId: e.targetInfo.targetId,
220
+ sessionId: e.sessionId,
221
+ url: e.targetInfo.url,
222
+ status: "running",
223
+ fetchEnabled: false,
224
+ };
225
+ this.swAttached.set(e.sessionId, att);
226
+ this.swIdBySession.set(e.sessionId, `sw-${this.nextSwId++}`);
227
+ if (this.fetchInterceptors.size > 0)
228
+ void this.applyFetchEnable(cdp, att).catch(() => undefined);
229
+ });
230
+ this.onCdp(cdp, "Target.detachedFromTarget", (raw) => {
231
+ const { sessionId } = raw;
232
+ this.swAttached.delete(sessionId);
233
+ this.swIdBySession.delete(sessionId);
234
+ });
235
+ }
236
+ /** `Fetch.requestPaused` (TOP session; flatten routes child events up by
237
+ * `sessionId`) — fulfill against a matching interceptor, else continue. */
238
+ registerRequestPaused(cdp) {
239
+ this.onCdp(cdp, "Fetch.requestPaused", (raw) => {
240
+ void this.handleRequestPaused(cdp, raw);
241
+ });
242
+ }
243
+ async handleRequestPaused(cdp, e) {
244
+ let hit;
245
+ for (const ic of this.fetchInterceptors.values()) {
246
+ if (ic.regex.test(e.request.url)) {
247
+ hit = ic;
248
+ break;
249
+ }
250
+ }
251
+ if (!hit) {
252
+ await cdp
253
+ .send("Fetch.continueRequest", {
254
+ requestId: e.requestId,
255
+ ...(e.sessionId ? { sessionId: e.sessionId } : {}),
256
+ })
257
+ .catch(() => undefined);
258
+ return;
259
+ }
260
+ const r = hit.response;
261
+ const headers = [
262
+ { name: "content-type", value: r.contentType ?? "application/json" },
263
+ ...Object.entries(r.headers ?? {}).map(([name, value]) => ({ name, value })),
264
+ ];
265
+ await cdp
266
+ .send("Fetch.fulfillRequest", {
267
+ requestId: e.requestId,
268
+ responseCode: r.status ?? 200,
269
+ responseHeaders: headers,
270
+ body: Buffer.from(r.body ?? "", "utf-8").toString("base64"),
271
+ ...(e.sessionId ? { sessionId: e.sessionId } : {}),
272
+ })
273
+ .catch(() => undefined);
274
+ }
275
+ async installSwListener(cdp) {
276
+ if (this.swEnabled)
277
+ return;
278
+ this.swEnabled = true;
279
+ // Enumerate + monitor running versions; auto-attach for a child session per SW.
280
+ await cdp.send("ServiceWorker.enable").catch(() => undefined);
281
+ await cdp
282
+ .send("Target.setAutoAttach", {
283
+ autoAttach: true,
284
+ waitForDebuggerOnStart: false,
285
+ flatten: true,
286
+ })
287
+ .catch(() => undefined);
288
+ this.registerVersionUpdated(cdp);
289
+ this.registerAttachDetach(cdp);
290
+ this.registerRequestPaused(cdp);
291
+ }
292
+ async applyFetchEnable(cdp, att) {
293
+ if (att.fetchEnabled)
294
+ return;
295
+ // CDP send routed to the child session: in flatten mode, the standard
296
+ // CDPSession.send doesn't directly target a child session — but for our
297
+ // workers use case Playwright doesn't expose per-child sessions through
298
+ // the public surface. We rely on the parent CDP and the auto-attach
299
+ // routing the Fetch events up with `sessionId` set.
300
+ // We enable Fetch on the parent so all child Fetch events route up.
301
+ await cdp
302
+ .send("Fetch.enable", {
303
+ patterns: [{ urlPattern: "*", requestStage: "Request" }],
304
+ })
305
+ .catch(() => undefined);
306
+ att.fetchEnabled = true;
307
+ }
308
+ // -------------------------------------------------------------------------
309
+ // Tool surface.
310
+ async list(page, cdp, filter = "all") {
311
+ await this.installPageWrapper(page);
312
+ await this.installSwListener(cdp);
313
+ const out = [];
314
+ if (filter === "all" || filter === "web") {
315
+ try {
316
+ const ws = await page.evaluate(() => {
317
+ const w = globalThis.__browxWorkers;
318
+ return w ? w.list() : [];
319
+ });
320
+ for (const e of ws)
321
+ out.push({ workerId: e.workerId, type: "web", url: e.url });
322
+ }
323
+ catch {
324
+ /* page navigation race — empty is fine */
325
+ }
326
+ }
327
+ if (filter === "all" || filter === "service") {
328
+ for (const [sessionId, att] of this.swAttached) {
329
+ const id = this.swIdBySession.get(sessionId) ?? `sw-${this.nextSwId++}`;
330
+ this.swIdBySession.set(sessionId, id);
331
+ out.push({ workerId: id, type: "service", url: att.url, state: att.status });
332
+ }
333
+ }
334
+ return out;
335
+ }
336
+ async sendMessage(page, cdp, args) {
337
+ if (args.workerId.startsWith("ww-")) {
338
+ await this.installPageWrapper(page);
339
+ const r = await page.evaluate(({ id, msg }) => {
340
+ const w = globalThis.__browxWorkers;
341
+ if (!w)
342
+ return { ok: false, error: "__browxWorkers not installed (init-script race?)" };
343
+ return w.post(id, msg);
344
+ }, { id: args.workerId, msg: args.message });
345
+ return { ...r, workerId: args.workerId };
346
+ }
347
+ if (args.workerId.startsWith("sw-")) {
348
+ await this.installSwListener(cdp);
349
+ // Find the SW attachment for this id.
350
+ const sessionId = [...this.swIdBySession].find(([, id]) => id === args.workerId)?.[0];
351
+ if (!sessionId)
352
+ return {
353
+ ok: false,
354
+ workerId: args.workerId,
355
+ error: `no service worker with id ${args.workerId}`,
356
+ };
357
+ // Dispatch a MessageEvent into the SW global by running JS in the SW
358
+ // context. Playwright doesn't surface child-session sends as a public
359
+ // API; we use the parent CDP's Runtime.evaluate routed via the
360
+ // sessionId field (flatten mode).
361
+ const payload = JSON.stringify(args.message);
362
+ const sendOpts = {
363
+ expression: `self.dispatchEvent(new MessageEvent('message', { data: ${payload} })); true;`,
364
+ returnByValue: true,
365
+ };
366
+ try {
367
+ // `sessionId` is a flatten-mode routing field absent from the generated
368
+ // `evaluateParameters` type; spread it the same way the Fetch handlers
369
+ // above do so the literal isn't excess-property-checked.
370
+ await cdp.send("Runtime.evaluate", { ...sendOpts, ...(sessionId ? { sessionId } : {}) });
371
+ return { ok: true, workerId: args.workerId };
372
+ }
373
+ catch (err) {
374
+ return {
375
+ ok: false,
376
+ workerId: args.workerId,
377
+ error: err instanceof Error ? err.message : String(err),
378
+ };
379
+ }
380
+ }
381
+ return {
382
+ ok: false,
383
+ workerId: args.workerId,
384
+ error: `unknown workerId prefix (expected ww-* or sw-*): ${args.workerId}`,
385
+ };
386
+ }
387
+ async readMessages(page, args) {
388
+ await this.installPageWrapper(page);
389
+ const out = [];
390
+ // Web Worker messages — drain from the page ring.
391
+ if (!args.workerId || args.workerId.startsWith("ww-")) {
392
+ try {
393
+ const drained = await page.evaluate(({ id }) => {
394
+ const w = globalThis.__browxWorkers;
395
+ if (!w)
396
+ return [];
397
+ return w.drain(id ?? undefined);
398
+ }, { id: args.workerId ?? null });
399
+ for (const m of drained)
400
+ out.push({ workerId: m.workerId, data: m.data, at: m.at });
401
+ }
402
+ catch {
403
+ /* race — empty is fine */
404
+ }
405
+ }
406
+ // Service Worker messages — drain from the server-side ring.
407
+ if (!args.workerId || args.workerId.startsWith("sw-")) {
408
+ const matching = [];
409
+ const remaining = [];
410
+ for (const m of this.swMessages) {
411
+ if (!args.workerId || m.workerId === args.workerId)
412
+ matching.push(m);
413
+ else
414
+ remaining.push(m);
415
+ }
416
+ this.swMessages = remaining;
417
+ out.push(...matching);
418
+ }
419
+ return out;
420
+ }
421
+ async addFetchIntercept(cdp, spec) {
422
+ await this.installSwListener(cdp);
423
+ const key = spec.pattern;
424
+ this.fetchInterceptors.set(key, {
425
+ pattern: key,
426
+ regex: globToRegex(key),
427
+ response: spec.response,
428
+ });
429
+ // Enable Fetch on every currently-attached SW (and on the parent — we
430
+ // need the parent Fetch.enable so child Fetch events route up).
431
+ await cdp
432
+ .send("Fetch.enable", {
433
+ patterns: [{ urlPattern: "*", requestStage: "Request" }],
434
+ })
435
+ .catch(() => undefined);
436
+ for (const att of this.swAttached.values()) {
437
+ await this.applyFetchEnable(cdp, att).catch(() => undefined);
438
+ }
439
+ return { key, active: this.listFetchIntercepts() };
440
+ }
441
+ async removeFetchIntercept(cdp, sel) {
442
+ await this.installSwListener(cdp);
443
+ let removed;
444
+ if (sel.pattern === undefined) {
445
+ removed = [...this.fetchInterceptors.keys()];
446
+ this.fetchInterceptors.clear();
447
+ }
448
+ else if (this.fetchInterceptors.has(sel.pattern)) {
449
+ removed = [sel.pattern];
450
+ this.fetchInterceptors.delete(sel.pattern);
451
+ }
452
+ else {
453
+ removed = [];
454
+ }
455
+ if (this.fetchInterceptors.size === 0) {
456
+ // Disable Fetch so we don't pause every request for no reason.
457
+ await cdp.send("Fetch.disable").catch(() => undefined);
458
+ for (const att of this.swAttached.values())
459
+ att.fetchEnabled = false;
460
+ }
461
+ return { removed, active: this.listFetchIntercepts() };
462
+ }
463
+ listFetchIntercepts() {
464
+ return [...this.fetchInterceptors.keys()];
465
+ }
466
+ /** Append a FROM-SW message to the server-side ring. Currently unused by
467
+ * the production path (the SW side message-relay is left as a future
468
+ * follow-up — see report); kept for symmetry + future use. */
469
+ recordSwMessage(workerId, data) {
470
+ let trimmed = data;
471
+ if (trimmed.length > SW_PAYLOAD_MAX)
472
+ trimmed = trimmed.slice(0, SW_PAYLOAD_MAX) + "…";
473
+ this.swMessages.push({ workerId, data: trimmed, at: Date.now() });
474
+ if (this.swMessages.length > SW_RING_MAX) {
475
+ this.swMessages.splice(0, this.swMessages.length - SW_RING_MAX);
476
+ }
477
+ }
478
+ /** Release all CDP listeners. Called from the session teardown. */
479
+ dispose() {
480
+ for (const off of this.detachers) {
481
+ try {
482
+ off();
483
+ }
484
+ catch {
485
+ /* tolerate */
486
+ }
487
+ }
488
+ this.detachers = [];
489
+ }
490
+ }
@@ -0,0 +1,82 @@
1
+ import type { Page } from "playwright-core";
2
+ export declare function globToRegex(pat: string): RegExp;
3
+ export type WsInterceptMode = "drop" | "echo" | "replace";
4
+ export interface WsInterceptSpec {
5
+ /** Glob pattern matched against the WebSocket's `url` at frame time. */
6
+ pattern: string;
7
+ /** `"drop"`, `"echo"`, or `{ data: "<replacement payload>" }`. */
8
+ response: "drop" | "echo" | {
9
+ data: string;
10
+ };
11
+ }
12
+ /** Per-session interactive-WS registry. Tracks the active interceptors so
13
+ * `unintercept` / `list` can answer locally; the page-side wrapper is the
14
+ * authoritative runtime, but each server-side call mirrors the change
15
+ * into this table before evaluating so a re-`add` of the same pattern
16
+ * cleanly replaces the prior entry on both sides. */
17
+ export declare class WsInteractiveRegistry {
18
+ private interceptors;
19
+ /** Idempotent — installs the init script + (best-effort) re-injects into
20
+ * the current document so the wrapper is live BEFORE `ws_send`
21
+ * / `ws_intercept` is called. Safe to call multiple times: the in-page
22
+ * guard `if (window.__browxWs) return;` short-circuits a re-run, and
23
+ * `addInitScript` accumulates harmlessly across calls.
24
+ *
25
+ * Called lazily by `send`/`intercept` so a session that never uses the
26
+ * interactive primitives pays zero overhead. */
27
+ install(page: Page): Promise<void>;
28
+ /** Send `message` on the page-side WS identified by `wsId`. Returns
29
+ * `{ ok:true, wsId, url, bytes }` on success; `{ ok:false, error }`
30
+ * if the wrapper didn't find the id or the socket isn't OPEN. */
31
+ send(page: Page, args: {
32
+ wsId: string;
33
+ message: string;
34
+ }): Promise<{
35
+ ok: boolean;
36
+ wsId: string;
37
+ url?: string;
38
+ bytes?: number;
39
+ error?: string;
40
+ }>;
41
+ addInterceptor(page: Page, spec: WsInterceptSpec): Promise<{
42
+ key: string;
43
+ active: string[];
44
+ }>;
45
+ removeInterceptor(page: Page, sel: {
46
+ pattern?: string;
47
+ }): Promise<{
48
+ removed: string[];
49
+ active: string[];
50
+ }>;
51
+ /** Server-side mirror of the active patterns — order = insertion. */
52
+ list(): string[];
53
+ /** Read the page-side `__browxWs.list()` registry to surface live WS
54
+ * endpoints + their `wsId`. Best-effort: returns `[]` if the wrapper
55
+ * isn't installed (`install` is the lazy installer; this method is
56
+ * for `ws_send` discoverability and shouldn't itself force install). */
57
+ listSockets(page: Page): Promise<Array<{
58
+ wsId: string;
59
+ url: string;
60
+ readyState: number;
61
+ }>>;
62
+ }
63
+ interface BrowxWsApi {
64
+ send(id: string, msg: string): {
65
+ ok: boolean;
66
+ url?: string;
67
+ bytes?: number;
68
+ error?: string;
69
+ };
70
+ intercept(pattern: string, mode: WsInterceptMode, replacement?: string | null): void;
71
+ unintercept(pattern?: string): void;
72
+ list(): Array<{
73
+ wsId: string;
74
+ url: string;
75
+ readyState: number;
76
+ }>;
77
+ }
78
+ declare global {
79
+ var __browxWs: BrowxWsApi | undefined;
80
+ }
81
+ export declare const WS_PAGE_SCRIPT = "(() => {\n if (window.__browxWs) return;\n var NativeWebSocket = window.WebSocket;\n if (!NativeWebSocket) return;\n var nativeSend = NativeWebSocket.prototype.send;\n var sockets = new Map(); // wsId -> WebSocket\n var nextId = 1;\n var interceptors = []; // { pattern, regex, mode, replacement }\n\n function globToRegex(pat) {\n var out = \"^\";\n for (var i = 0; i < pat.length; i++) {\n var c = pat[i];\n if (c === \"*\") {\n if (pat[i + 1] === \"*\") { out += \".*\"; i++; }\n else { out += \"[^/]*\"; }\n } else if (\"\\\\^$.+?()[]{}|\".indexOf(c) >= 0) {\n out += \"\\\\\" + c;\n } else { out += c; }\n }\n out += \"$\";\n return new RegExp(out);\n }\n\n function matchOne(url) {\n for (var i = 0; i < interceptors.length; i++) {\n if (interceptors[i].regex.test(url)) return interceptors[i];\n }\n return null;\n }\n\n function Wrapped(url, protocols) {\n var sock = arguments.length > 1 ? new NativeWebSocket(url, protocols) : new NativeWebSocket(url);\n var id = \"ws-\" + (nextId++);\n sockets.set(id, sock);\n sock.__browxId = id;\n // Wrap message dispatch. We replace addEventListener(\"message\", \u2026) AND\n // onmessage so both registration paths route through the interceptor.\n var liveListeners = [];\n var origAdd = sock.addEventListener.bind(sock);\n var origRemove = sock.removeEventListener.bind(sock);\n sock.addEventListener = function (type, listener, opts) {\n if (type === \"message\" && typeof listener === \"function\") {\n liveListeners.push(listener);\n return; // we'll dispatch ourselves\n }\n return origAdd(type, listener, opts);\n };\n sock.removeEventListener = function (type, listener, opts) {\n if (type === \"message\" && typeof listener === \"function\") {\n var i = liveListeners.indexOf(listener);\n if (i >= 0) liveListeners.splice(i, 1);\n return;\n }\n return origRemove(type, listener, opts);\n };\n var onmessageFn = null;\n Object.defineProperty(sock, \"onmessage\", {\n configurable: true,\n get: function () { return onmessageFn; },\n set: function (v) { onmessageFn = typeof v === \"function\" ? v : null; },\n });\n function dispatch(payload) {\n var ev = new MessageEvent(\"message\", { data: payload });\n for (var i = 0; i < liveListeners.length; i++) {\n try { liveListeners[i].call(sock, ev); } catch (_) {}\n }\n if (onmessageFn) {\n try { onmessageFn.call(sock, ev); } catch (_) {}\n }\n }\n origAdd(\"message\", function (ev) {\n var hit = matchOne(sock.url || \"\");\n if (!hit) { dispatch(ev.data); return; }\n if (hit.mode === \"drop\") return;\n if (hit.mode === \"echo\") {\n try { nativeSend.call(sock, ev.data); } catch (_) {}\n dispatch(ev.data);\n return;\n }\n // replace\n dispatch(hit.replacement == null ? \"\" : hit.replacement);\n });\n // Expose the id post-construction; the agent reads it via __browxWs.list().\n return sock;\n }\n // Preserve constants + name so feature-detection (`'OPEN' in WebSocket`) keeps working.\n Wrapped.CONNECTING = NativeWebSocket.CONNECTING;\n Wrapped.OPEN = NativeWebSocket.OPEN;\n Wrapped.CLOSING = NativeWebSocket.CLOSING;\n Wrapped.CLOSED = NativeWebSocket.CLOSED;\n Wrapped.prototype = NativeWebSocket.prototype;\n try { Object.defineProperty(Wrapped, \"name\", { value: \"WebSocket\" }); } catch (_) {}\n window.WebSocket = Wrapped;\n\n window.__browxWs = {\n send: function (id, msg) {\n var sock = sockets.get(id);\n if (!sock) return { ok: false, error: \"no socket with id \" + id };\n if (sock.readyState !== 1) return { ok: false, error: \"socket \" + id + \" is not OPEN (readyState=\" + sock.readyState + \")\" };\n try {\n nativeSend.call(sock, msg);\n return { ok: true, url: sock.url || \"\", bytes: typeof msg === \"string\" ? msg.length : 0 };\n } catch (e) {\n return { ok: false, error: e && e.message ? e.message : String(e) };\n }\n },\n intercept: function (pattern, mode, replacement) {\n // Replace any prior interceptor on the same pattern (server-side\n // mirror does the same).\n for (var i = interceptors.length - 1; i >= 0; i--) {\n if (interceptors[i].pattern === pattern) interceptors.splice(i, 1);\n }\n interceptors.push({\n pattern: pattern,\n regex: globToRegex(pattern),\n mode: mode,\n replacement: replacement == null ? null : replacement,\n });\n },\n unintercept: function (pattern) {\n if (pattern === undefined || pattern === null) {\n interceptors.length = 0;\n return;\n }\n for (var i = interceptors.length - 1; i >= 0; i--) {\n if (interceptors[i].pattern === pattern) interceptors.splice(i, 1);\n }\n },\n list: function () {\n var out = [];\n sockets.forEach(function (sock, id) {\n out.push({ wsId: id, url: sock.url || \"\", readyState: sock.readyState });\n });\n return out;\n },\n };\n})();";
82
+ export {};