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,600 @@
1
+ // Per-session permission policy. Sibling of `dialog_policy`. Plugs the
2
+ // runtime-permission blind spot: camera / microphone / geolocation / clipboard /
3
+ // notification (and the long tail of sensor permissions) requests fire from the
4
+ // page asynchronously; without a server-side interceptor the request either
5
+ // silently sits forever (default Chromium policy in headless: "denied" via no
6
+ // user-gesture infobar) or — worse — pre-grants from `grant_permissions` change
7
+ // app behavior silently. This module wires a four-mode policy mirroring
8
+ // `dialog_policy`'s posture:
9
+ //
10
+ // - "allow" — pre-grant via CDP `Browser.setPermission`; in-page wrappers
11
+ // call through. The app sees a granted permission.
12
+ // - "deny" — pre-deny via CDP; in-page wrappers reject with the standard
13
+ // `NotAllowedError`. The app sees a denied permission.
14
+ // - "raise" — DEFAULT (deterministic anti-deadlock). Pre-deny via CDP +
15
+ // in-page wrappers reject AND RECORD the request as
16
+ // `handledAs:"raised"`. The next ActionResult flips `ok:false`
17
+ // with a stable hint pointing at `set_permission_policy`.
18
+ // Mirrors `dialog_policy`'s `raise` — the page never blocks,
19
+ // but a permission request never silently changes app state
20
+ // under an unaware caller either.
21
+ // - "ask-human" — server records the request, blocks on
22
+ // `bridge.awaitSignal("respond")` (the `await_human({kind:
23
+ // "confirm"})` mechanism), then calls through or rejects per
24
+ // the human's answer.
25
+ //
26
+ // Per-permission override map. The top-level `mode` is the default; the
27
+ // per-permission map (`perPermission: { camera: "allow", … }`) overrides it for
28
+ // a specific permission name. Mirrors how Playwright's permission set is
29
+ // per-name. The `current(name)` accessor handles the fallback chain.
30
+ //
31
+ // Per-action capture. Every page-side request is appended to a buffer with a
32
+ // timestamp. `since(ts)` slices for the action window — same pattern as
33
+ // `dialog_policy`'s buffer; the `raisedSince(ts)` flag drives the
34
+ // ok:false flip.
35
+ //
36
+ // Why two layers (CDP setPermission + init-script wrappers) ?
37
+ // - CDP `Browser.setPermission` controls the *state* the browser reports
38
+ // (granted / denied) — `navigator.permissions.query({name:"camera"})`
39
+ // reads this state without ever invoking our wrappers; without setting it
40
+ // we get the wrong reading. But CDP can't record *when* the page asked.
41
+ // - Init-script wrappers around `getUserMedia`, `getCurrentPosition`,
42
+ // etc. capture the request moment for `permissionRequests[]` AND let
43
+ // `ask-human` block until the human responds (CDP setPermission has no
44
+ // await-human integration).
45
+ // - For `allow` the wrapper calls through (CDP already granted); for
46
+ // `deny`/`raise` it throws (CDP denial backstops it if the wrapper is
47
+ // somehow bypassed); for `ask-human` it consults the server, which blocks
48
+ // until the human answers and then returns allow/deny.
49
+ import { log } from "../util/logging.js";
50
+ import { PolicyRecordBuffer } from "./policy-buffer.js";
51
+ /** Canonical name set for v1. Aligned with Playwright/Chromium permission names.
52
+ * USB/Bluetooth/HID are deliberately NOT in v1 ('s `device-emulation`).
53
+ * Re-exported in `permission_state` tool docs + tool-reference.md. */
54
+ export const SUPPORTED_PERMISSIONS = [
55
+ "camera",
56
+ "microphone",
57
+ "geolocation",
58
+ "notifications",
59
+ "clipboard-read",
60
+ "clipboard-write",
61
+ "midi",
62
+ "midi-sysex",
63
+ "payment-handler",
64
+ "background-sync",
65
+ "accelerometer",
66
+ "gyroscope",
67
+ "magnetometer",
68
+ ];
69
+ /** Subset of names CDP `Browser.setPermission` accepts. Maps our canonical
70
+ * names to the CDP descriptor names (most are 1:1; midi vs midi-sysex,
71
+ * notifications vs background-sync etc. all match CDP's permission enum). */
72
+ const CDP_PERMISSION_NAME = {
73
+ camera: "videoCapture",
74
+ microphone: "audioCapture",
75
+ geolocation: "geolocation",
76
+ notifications: "notifications",
77
+ "clipboard-read": "clipboardReadWrite",
78
+ "clipboard-write": "clipboardSanitizedWrite",
79
+ midi: "midi",
80
+ "midi-sysex": "midiSysex",
81
+ "payment-handler": "paymentHandler",
82
+ "background-sync": "backgroundSync",
83
+ accelerometer: "sensors",
84
+ gyroscope: "sensors",
85
+ magnetometer: "sensors",
86
+ };
87
+ /** Hint emitted on `ActionResult.failure.hint` when `raise` mode fired.
88
+ * Stable, agent-facing string — referenced in docs/tool-reference.md. */
89
+ export const UNHANDLED_PERMISSION_HINT = "unhandled permission request — set permissionPolicy (open_session/set_permission_policy) " +
90
+ 'to "allow", "deny", or "ask-human" before driving an action that may trigger one. ' +
91
+ "The request was rejected page-side (NotAllowedError) so the page is not deadlocked, but " +
92
+ "the app effect is the deny branch.";
93
+ /** BYOB warning surfaced when policy is set on `attached` sessions. CDP
94
+ * `Browser.setPermission` mutates the human's Chrome and is not cleanly
95
+ * revertable on detach — same posture class as the BYOB emulation warning. */
96
+ export const BYOB_PERMISSION_WARNING = "BYOB caveat: this permission policy is enforced via CDP `Browser.setPermission` " +
97
+ "on an attached (not-owned) Chrome. The override PERSISTS on that browser after " +
98
+ "browxai detaches; the human's Chrome must navigate / restart to fully clear it.";
99
+ /** Mutable per-session state. The page-side check binding reads `current(name)`
100
+ * on every request, so a `set_permission_policy` call takes effect on the
101
+ * very next request without page reload. */
102
+ export class PermissionPolicyState {
103
+ policy;
104
+ /** Bounded record ring (shared `PolicyRecordBuffer` — the hard cap so a chatty
105
+ * page can't grow this without bound; the per-action slice is the only
106
+ * consumer, older records are noise). */
107
+ records;
108
+ /** Contexts we've already installed the init-script + binding on. Idempotent
109
+ * install guard — BYOB reconnect / context rebuild MUST not double-wire. */
110
+ wired = new WeakSet();
111
+ constructor(initial = { mode: "raise" }, cap = 200) {
112
+ this.policy = normalise(initial);
113
+ this.records = new PolicyRecordBuffer(cap);
114
+ }
115
+ /** Resolved policy snapshot. */
116
+ current() {
117
+ return {
118
+ mode: this.policy.mode,
119
+ ...(this.policy.perPermission ? { perPermission: { ...this.policy.perPermission } } : {}),
120
+ };
121
+ }
122
+ /** Effective mode for a single permission — per-permission map wins, else
123
+ * top-level. Unknown permissions fall through to top-level (we still want
124
+ * a deterministic answer for whatever the page asked for). */
125
+ modeFor(name) {
126
+ const override = this.policy.perPermission?.[name];
127
+ return override ?? this.policy.mode;
128
+ }
129
+ set(next) {
130
+ this.policy = normalise(next);
131
+ return this.current();
132
+ }
133
+ /** Append a request record. Caps the buffer at `cap`. */
134
+ record(rec) {
135
+ this.records.record(rec);
136
+ }
137
+ /** Slice records with `ts >= since`. Used by the action-window. */
138
+ since(since) {
139
+ return this.records.since(since);
140
+ }
141
+ /** True if any record in `[since, now]` was handled in `raise` mode.
142
+ * When true, the action-window flips the result to `ok:false`. */
143
+ raisedSince(since) {
144
+ return this.records.matchedSince(since, (r) => r.handledAs === "raised");
145
+ }
146
+ /** Has this context already been wired? Idempotent install guard. */
147
+ hasContext(c) {
148
+ return this.wired.has(c);
149
+ }
150
+ /** Mark a context as wired. */
151
+ markContext(c) {
152
+ this.wired.add(c);
153
+ }
154
+ }
155
+ /** Idempotent normaliser. Rejects unknown top-level modes; per-permission map
156
+ * is validated per-entry (an unknown permission name in the map throws so the
157
+ * caller gets a fast error instead of silent fallthrough). */
158
+ function normalise(p) {
159
+ if (!isPolicyMode(p.mode)) {
160
+ throw new Error(`permissionPolicy: invalid mode "${String(p.mode)}" — expected "allow" | "deny" | "raise" | "ask-human"`);
161
+ }
162
+ if (p.perPermission) {
163
+ const cleaned = {};
164
+ for (const [name, mode] of Object.entries(p.perPermission)) {
165
+ if (!SUPPORTED_PERMISSIONS.includes(name)) {
166
+ throw new Error(`permissionPolicy.perPermission: unknown permission "${name}" — supported: ${SUPPORTED_PERMISSIONS.join(", ")}`);
167
+ }
168
+ if (mode === undefined)
169
+ continue;
170
+ if (!isPolicyMode(mode)) {
171
+ throw new Error(`permissionPolicy.perPermission["${name}"]: invalid mode "${String(mode)}" — expected "allow" | "deny" | "raise" | "ask-human"`);
172
+ }
173
+ cleaned[name] = mode;
174
+ }
175
+ return { mode: p.mode, perPermission: cleaned };
176
+ }
177
+ return { mode: p.mode };
178
+ }
179
+ function isPolicyMode(m) {
180
+ return m === "allow" || m === "deny" || m === "raise" || m === "ask-human";
181
+ }
182
+ /** Parse the spec's compact string form for the top-level mode, or accept the
183
+ * object form. Idempotent. */
184
+ export function parsePermissionPolicyArg(v) {
185
+ if (!v)
186
+ return { mode: "raise" };
187
+ if (typeof v === "object")
188
+ return normalise(v);
189
+ if (isPolicyMode(v))
190
+ return { mode: v };
191
+ throw new Error(`permissionPolicy: invalid value "${v}" — expected "allow" | "deny" | "raise" | "ask-human"`);
192
+ }
193
+ /** Map a canonical permission name to the CDP `Browser.setPermission`
194
+ * descriptor name. */
195
+ export function cdpPermissionName(p) {
196
+ return CDP_PERMISSION_NAME[p];
197
+ }
198
+ /** Compute the CDP setting (granted/denied) for a permission given the active
199
+ * policy. `raise` / `deny` → "denied"; `allow` → "granted"; `ask-human` →
200
+ * "prompt" (CDP returns to the page-script wrapper which then asks the human).
201
+ *
202
+ * Kept as a pure function so registry.test.ts can assert the mapping without
203
+ * launching Chromium. */
204
+ export function cdpSettingFor(mode) {
205
+ switch (mode) {
206
+ case "allow":
207
+ return "granted";
208
+ case "ask-human":
209
+ return "prompt";
210
+ case "deny":
211
+ case "raise":
212
+ default:
213
+ return "denied";
214
+ }
215
+ }
216
+ /** Init script that wraps the page-side permission APIs. Stringified so it can
217
+ * be passed to `addInitScript` and `page.evaluate`. Keep browser-only JS — no
218
+ * TS-only syntax. Re-injected on `framenavigated` (idempotent: guards on
219
+ * `window.__browx_permission_installed`).
220
+ *
221
+ * The wrappers consult `window.__browx_permission_check({permission, origin})`
222
+ * (an exposeBinding callable from page context) — it returns `"allow" |
223
+ * "deny"`. The server's binding implementation records the request + (for
224
+ * `ask-human`) blocks on the bridge before answering. */
225
+ export const PERMISSION_PAGE_SCRIPT = `(() => {
226
+ if (window.__browx_permission_installed) return;
227
+ window.__browx_permission_installed = true;
228
+ // Detect whether the exposeBinding is available. If not (BYOB multi-attach
229
+ // clobber, or the binding install failed), the wrappers fall back to
230
+ // call-through — the CDP setPermission baseline still enforces grant/deny.
231
+ function check(permission) {
232
+ try {
233
+ if (typeof window.__browx_permission_check === "function") {
234
+ return Promise.resolve(window.__browx_permission_check(JSON.stringify({
235
+ permission: permission, origin: location.origin,
236
+ })));
237
+ }
238
+ } catch (_) {}
239
+ return Promise.resolve("allow");
240
+ }
241
+ function notAllowed(msg) {
242
+ var e = new Error(msg || "permission denied by browxai permissionPolicy");
243
+ try { e.name = "NotAllowedError"; } catch (_) {}
244
+ return e;
245
+ }
246
+
247
+ // --- navigator.mediaDevices.getUserMedia (camera + microphone) ---
248
+ try {
249
+ var md = navigator.mediaDevices;
250
+ if (md && typeof md.getUserMedia === "function") {
251
+ var origGUM = md.getUserMedia.bind(md);
252
+ md.getUserMedia = function (constraints) {
253
+ var wantsVideo = !!(constraints && constraints.video);
254
+ var wantsAudio = !!(constraints && constraints.audio);
255
+ var perm = wantsVideo ? "camera" : (wantsAudio ? "microphone" : "camera");
256
+ return check(perm).then(function (decision) {
257
+ if (decision === "deny") return Promise.reject(notAllowed("Permission denied"));
258
+ return origGUM(constraints);
259
+ });
260
+ };
261
+ }
262
+ } catch (_) {}
263
+
264
+ // --- navigator.geolocation (getCurrentPosition + watchPosition) ---
265
+ // watchPosition is long-lived (the callback may fire many times) — we gate
266
+ // the *initial* permission check at watch-installation time, then if allowed
267
+ // pass through to the native API which itself manages the callback stream.
268
+ try {
269
+ var geo = navigator.geolocation;
270
+ if (geo && typeof geo.getCurrentPosition === "function") {
271
+ var origGet = geo.getCurrentPosition.bind(geo);
272
+ geo.getCurrentPosition = function (success, error, options) {
273
+ check("geolocation").then(function (decision) {
274
+ if (decision === "deny") {
275
+ if (typeof error === "function") {
276
+ try { error({ code: 1, message: "User denied geolocation", PERMISSION_DENIED: 1, POSITION_UNAVAILABLE: 2, TIMEOUT: 3 }); } catch (_) {}
277
+ }
278
+ return;
279
+ }
280
+ try { origGet(success, error, options); } catch (e) {
281
+ if (typeof error === "function") { try { error(e); } catch (_) {} }
282
+ }
283
+ });
284
+ };
285
+ }
286
+ if (geo && typeof geo.watchPosition === "function") {
287
+ var origWatch = geo.watchPosition.bind(geo);
288
+ // Return a synthetic watch id when denied so callers calling
289
+ // clearWatch(id) still see a valid (no-op) integer. Native ids are
290
+ // small positive integers; we use negatives starting at -1 to avoid
291
+ // colliding with any in-flight native watch.
292
+ var synthCounter = 0;
293
+ geo.watchPosition = function (success, error, options) {
294
+ var pending = true;
295
+ var synthId = --synthCounter;
296
+ check("geolocation").then(function (decision) {
297
+ pending = false;
298
+ if (decision === "deny") {
299
+ if (typeof error === "function") {
300
+ try { error({ code: 1, message: "User denied geolocation", PERMISSION_DENIED: 1, POSITION_UNAVAILABLE: 2, TIMEOUT: 3 }); } catch (_) {}
301
+ }
302
+ return;
303
+ }
304
+ // Allowed — install the native watch. We've already returned the
305
+ // synthetic id to the caller; the native id is held internally and
306
+ // proxied through clearWatch below.
307
+ try {
308
+ var nativeId = origWatch(success, error, options);
309
+ geo.__browx_watch_map = geo.__browx_watch_map || {};
310
+ geo.__browx_watch_map[synthId] = nativeId;
311
+ } catch (e) {
312
+ if (typeof error === "function") { try { error(e); } catch (_) {} }
313
+ }
314
+ });
315
+ return synthId;
316
+ };
317
+ var origClear = typeof geo.clearWatch === "function" ? geo.clearWatch.bind(geo) : null;
318
+ if (origClear) {
319
+ geo.clearWatch = function (id) {
320
+ var map = geo.__browx_watch_map || {};
321
+ if (id in map) {
322
+ try { origClear(map[id]); } catch (_) {}
323
+ delete map[id];
324
+ return;
325
+ }
326
+ try { origClear(id); } catch (_) {}
327
+ };
328
+ }
329
+ }
330
+ } catch (_) {}
331
+
332
+ // --- Notification.requestPermission ---
333
+ try {
334
+ if (typeof Notification !== "undefined" && typeof Notification.requestPermission === "function") {
335
+ var origReq = Notification.requestPermission.bind(Notification);
336
+ Notification.requestPermission = function (cb) {
337
+ return check("notifications").then(function (decision) {
338
+ var result = decision === "deny" ? "denied" : "granted";
339
+ if (decision === "deny") {
340
+ try { Object.defineProperty(Notification, "permission", { get: function () { return "denied"; }, configurable: true }); } catch (_) {}
341
+ if (typeof cb === "function") { try { cb(result); } catch (_) {} }
342
+ return result;
343
+ }
344
+ // Allowed — delegate to native; the CDP setPermission baseline has
345
+ // already pre-granted, so the native call resolves immediately.
346
+ try {
347
+ var r = origReq(cb);
348
+ return r && typeof r.then === "function" ? r : Promise.resolve(result);
349
+ } catch (_) {
350
+ return result;
351
+ }
352
+ });
353
+ };
354
+ }
355
+ } catch (_) {}
356
+
357
+ // --- navigator.clipboard (read / write / readText / writeText) ---
358
+ try {
359
+ var clip = navigator.clipboard;
360
+ if (clip) {
361
+ var wrap = function (name, perm) {
362
+ var orig = typeof clip[name] === "function" ? clip[name].bind(clip) : null;
363
+ if (!orig) return;
364
+ clip[name] = function () {
365
+ var args = arguments;
366
+ return check(perm).then(function (decision) {
367
+ if (decision === "deny") return Promise.reject(notAllowed("Clipboard " + name + " denied"));
368
+ return orig.apply(null, args);
369
+ });
370
+ };
371
+ };
372
+ wrap("read", "clipboard-read");
373
+ wrap("readText", "clipboard-read");
374
+ wrap("write", "clipboard-write");
375
+ wrap("writeText", "clipboard-write");
376
+ }
377
+ } catch (_) {}
378
+
379
+ // --- navigator.permissions.query — read-side. Force the wrapper's view of
380
+ // state through us so a query() honoured a "raise" policy returns "denied"
381
+ // (matching the wrapper rejection) and a "ask-human" returns "prompt" (the
382
+ // native query would otherwise see the CDP "prompt" setting and skip our
383
+ // recording). Falls back to native when the queried name isn't one we govern.
384
+ try {
385
+ var permsApi = navigator.permissions;
386
+ if (permsApi && typeof permsApi.query === "function") {
387
+ var origQuery = permsApi.query.bind(permsApi);
388
+ permsApi.query = function (desc) {
389
+ var name = desc && desc.name;
390
+ // pass through to native — we don't override the query result, just
391
+ // record that the page asked, so the next ActionResult shows it. The
392
+ // native value still reflects the CDP-set state (granted/denied/prompt).
393
+ if (typeof window.__browx_permission_observe === "function") {
394
+ try { window.__browx_permission_observe(JSON.stringify({ permission: name, origin: location.origin })); } catch (_) {}
395
+ }
396
+ return origQuery(desc);
397
+ };
398
+ }
399
+ } catch (_) {}
400
+ })();`;
401
+ /** Server-side wire-up. Installs:
402
+ * - `__browx_permission_check` exposeBinding: synchronous-from-page consult
403
+ * that records the request, runs the ask-human handler if the policy is
404
+ * `ask-human`, and returns the resolved decision (`"allow"` / `"deny"`).
405
+ * - `__browx_permission_observe` exposeBinding: read-side notice that the
406
+ * page called `navigator.permissions.query` (no decision returned).
407
+ * - The page-side init script (see above), re-injected by Playwright on
408
+ * every new document via `addInitScript`.
409
+ *
410
+ * Idempotent on the same context (the state's `WeakSet<BrowserContext>` guard).
411
+ * Errors during install are logged and swallowed — the CDP setPermission baseline
412
+ * still enforces grant/deny even when the in-page wrappers fail to wire.
413
+ */
414
+ export async function attachPermissionPolicy(context, state, askHandler) {
415
+ if (state.hasContext(context))
416
+ return;
417
+ state.markContext(context);
418
+ // exposeBinding — synchronous-from-page from Playwright's perspective:
419
+ // page-side awaits the Promise the binding returns. Errors thrown here
420
+ // bubble back to the page as a rejected promise; the wrapper script catches
421
+ // and falls back to "allow" (CDP backstop still enforces).
422
+ try {
423
+ await context.exposeBinding("__browx_permission_check", async (_source, payload) => {
424
+ try {
425
+ const o = JSON.parse(payload);
426
+ const name = o.permission;
427
+ const origin = o.origin;
428
+ const cdpName = name && SUPPORTED_PERMISSIONS.includes(name)
429
+ ? name
430
+ : undefined;
431
+ if (!cdpName) {
432
+ // Unknown permission name — record under "geolocation" sentinel? No:
433
+ // just allow through. Anything outside the v1 set is best-effort.
434
+ return "allow";
435
+ }
436
+ const mode = state.modeFor(cdpName);
437
+ const ts = Date.now();
438
+ switch (mode) {
439
+ case "allow":
440
+ state.record({ permission: cdpName, origin, handledAs: "allowed", ts });
441
+ return "allow";
442
+ case "deny":
443
+ state.record({ permission: cdpName, origin, handledAs: "denied", ts });
444
+ return "deny";
445
+ case "ask-human": {
446
+ const decision = await askHandler(cdpName, origin).catch(() => "deny");
447
+ state.record({ permission: cdpName, origin, handledAs: "asked-human", ts });
448
+ return decision;
449
+ }
450
+ case "raise":
451
+ default:
452
+ state.record({ permission: cdpName, origin, handledAs: "raised", ts });
453
+ return "deny";
454
+ }
455
+ }
456
+ catch (err) {
457
+ log.warn("session.permission: check handler error", {
458
+ error: err instanceof Error ? err.message : String(err),
459
+ });
460
+ return "allow";
461
+ }
462
+ });
463
+ await context.exposeBinding("__browx_permission_observe", (_source, _payload) => {
464
+ // Read-side breadcrumb only — no decision, no record (the page calling
465
+ // permissions.query() is too noisy to record per-call).
466
+ return undefined;
467
+ });
468
+ }
469
+ catch (err) {
470
+ log.warn("session.permission: exposeBinding install failed; CDP baseline still enforces", {
471
+ error: err instanceof Error ? err.message : String(err),
472
+ });
473
+ }
474
+ // Init-script — Playwright re-runs it on every new document, including the
475
+ // post-`framenavigated` reload of the same page. Idempotent via the
476
+ // `__browx_permission_installed` guard inside the script.
477
+ try {
478
+ await context.addInitScript({ content: PERMISSION_PAGE_SCRIPT });
479
+ for (const page of context.pages()) {
480
+ await page.evaluate(PERMISSION_PAGE_SCRIPT).catch(() => undefined);
481
+ }
482
+ }
483
+ catch (err) {
484
+ log.warn("session.permission: addInitScript failed", {
485
+ error: err instanceof Error ? err.message : String(err),
486
+ });
487
+ }
488
+ }
489
+ /** Apply the policy's baseline by computing the set of permissions that should
490
+ * be GRANTED (mode `allow`) and routing them through Playwright's
491
+ * `context.grantPermissions`. Permissions in `deny`/`raise`/`ask-human` are
492
+ * NOT granted — the in-page wrapper rejects them at request time before the
493
+ * native code runs.
494
+ *
495
+ * Why not CDP `Browser.setPermission` directly: the underlying CDP method
496
+ * takes a W3C PermissionDescriptor name (e.g. `geolocation`, `camera`) and
497
+ * the descriptor schema varies by Chromium build. Playwright's
498
+ * `grantPermissions` carries the canonical mapping (see Playwright's
499
+ * `webPermissionToProtocol`) and falls back across Chromium versions —
500
+ * delegating means we don't have to track the protocol versions ourselves.
501
+ *
502
+ * Note: `clearPermissions` first then `grantPermissions` is the Playwright
503
+ * idiom for "REPLACE the granted set" (the underlying CDP call is
504
+ * `Browser.resetPermissions` + `Browser.grantPermissions`). Both are
505
+ * context-wide on Chromium so the policy applies to every page.
506
+ *
507
+ * Best-effort: errors are logged and don't throw — the in-page wrapper still
508
+ * enforces grant/deny even if the baseline application fails. Re-applied on
509
+ * `set_permission_policy` and re-attach paths. */
510
+ export async function applyCdpBaseline(context, state) {
511
+ const allowList = [];
512
+ for (const name of SUPPORTED_PERMISSIONS) {
513
+ if (state.modeFor(name) === "allow")
514
+ allowList.push(name);
515
+ }
516
+ try {
517
+ // Clear first so a previous policy's grants don't leak when the next
518
+ // policy reduces the allow list.
519
+ await context.clearPermissions();
520
+ }
521
+ catch (err) {
522
+ log.warn("session.permission: clearPermissions failed", {
523
+ error: err instanceof Error ? err.message : String(err),
524
+ });
525
+ }
526
+ if (allowList.length === 0)
527
+ return;
528
+ try {
529
+ await context.grantPermissions(allowList);
530
+ }
531
+ catch (err) {
532
+ log.warn("session.permission: grantPermissions failed", {
533
+ permissions: allowList,
534
+ error: err instanceof Error ? err.message : String(err),
535
+ });
536
+ }
537
+ }
538
+ /** Read-side via the page's native `navigator.permissions.query` (W3C
539
+ * Permissions API). Returns `{ [name]: "granted"|"denied"|"prompt"|"unknown" }`.
540
+ * Per-permission errors populate the entry with `"unknown"` so the caller
541
+ * sees a deterministic shape.
542
+ *
543
+ * Why the Permissions API and not CDP `Browser.getPermissionState`: the CDP
544
+ * method's PermissionDescriptor schema varies across Chromium builds and
545
+ * several of our supported names (e.g. `clipboard-write` → `clipboardSan…`)
546
+ * don't map cleanly. The Permissions API takes the canonical web spec name
547
+ * directly and is supported across versions. The state it reports reflects
548
+ * whatever the CDP-level baseline set, so it's the right read-side mirror
549
+ * for `applyCdpBaseline`.
550
+ *
551
+ * Note: the in-page wrapper script is a no-op for query() (passes through);
552
+ * it doesn't override the resulting state, so this read is the canonical
553
+ * browser-reported state, not a wrapper-side guess. */
554
+ export async function readPermissionStates(context, page, names, origin) {
555
+ const out = {};
556
+ // origin parameter: for now we only support querying the current page's
557
+ // origin (Permissions API has no cross-origin query). When origin is set
558
+ // but doesn't match the page, return unknown for the whole set — the
559
+ // caller can navigate / open a new tab if they need cross-origin state.
560
+ if (origin) {
561
+ try {
562
+ const pageOrigin = new URL(page.url()).origin;
563
+ if (pageOrigin !== origin) {
564
+ for (const n of names)
565
+ out[n] = "unknown";
566
+ return out;
567
+ }
568
+ }
569
+ catch {
570
+ for (const n of names)
571
+ out[n] = "unknown";
572
+ return out;
573
+ }
574
+ }
575
+ void context; // signature-compat: takes context so a future cross-origin
576
+ // CDP path can adopt it without breaking callers.
577
+ for (const n of names) {
578
+ try {
579
+ const state = await page
580
+ .evaluate(async (perm) => {
581
+ try {
582
+ const perms = globalThis.navigator?.permissions;
583
+ if (!perms?.query)
584
+ return "unknown";
585
+ const res = await perms.query({ name: perm });
586
+ return res.state;
587
+ }
588
+ catch {
589
+ return "unknown";
590
+ }
591
+ }, n)
592
+ .catch(() => "unknown");
593
+ out[n] = state === "granted" || state === "denied" || state === "prompt" ? state : "unknown";
594
+ }
595
+ catch {
596
+ out[n] = "unknown";
597
+ }
598
+ }
599
+ return out;
600
+ }
@@ -0,0 +1,8 @@
1
+ import type { SessionEntry } from "./registry.js";
2
+ import type { PostWireDeps } from "../engine/registry.js";
3
+ /** Attach the full Playwright post-creation bookkeeping to a freshly-built
4
+ * SessionEntry, using the per-server `deps` (caps / configStore / workspace) the
5
+ * composition root threads in. Returns the promise the session factory awaits, so
6
+ * every context attach completes before the session is handed to a tool call —
7
+ * byte-identical to the pre-relocation inline awaits. */
8
+ export declare function playwrightPostWire(entry: SessionEntry, deps: PostWireDeps): Promise<void>;