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,156 @@
1
+ import { estimateTokens } from "../util/tokens.js";
2
+ import { readPermissionStates, SUPPORTED_PERMISSIONS, } from "../session/permission.js";
3
+ import { propagateSyncDecision as propagateNotificationSyncDecision, } from "../session/notification.js";
4
+ import { SUPPORTED_DEVICE_APIS } from "../session/device-emu.js";
5
+ import { SESSION_ARG } from "./schemas.js";
6
+ /**
7
+ * Permission-state read + notification policy + device-request read tools:
8
+ * permission_state / set_notification_policy / device_requests. Split out of
9
+ * `session-policy-tools` by cohesive family (RFC 0004 P3 / D3 SRP); registered
10
+ * through the shared `ToolHost` seam in the same source order. The host owns the
11
+ * closures (register / gate / entry).
12
+ */
13
+ export function registerSessionNotificationDeviceTools(host) {
14
+ const { z, register, gateCheck, entryFor } = host;
15
+ register("permission_state", {
16
+ capability: "read",
17
+ description: 'Read the current permission state(s) for an origin via the W3C Permissions API (`navigator.permissions.query` — which reflects the CDP-applied baseline). Returns `{ [permission]: "granted" | "denied" | "prompt" | "unknown" }` per requested name. Defaults the `origin` to the current page\'s origin when omitted. Read-only — does not mutate state. Supported permission names (v1): ' +
18
+ SUPPORTED_PERMISSIONS.join(", ") +
19
+ ". Sibling of `set_permission_policy`.",
20
+ inputSchema: {
21
+ permissions: z
22
+ .array(z.string())
23
+ .min(1)
24
+ .describe('Canonical permission names to query — see tool description for the supported set. Unknown names map to `"unknown"` in the result.'),
25
+ origin: z
26
+ .string()
27
+ .optional()
28
+ .describe('Origin to query (e.g. "https://example.com"). Omit to use the current page\'s origin.'),
29
+ ...SESSION_ARG,
30
+ },
31
+ }, async ({ permissions, origin, session }) => {
32
+ const g = gateCheck("permission_state");
33
+ if (g)
34
+ return g;
35
+ const e = await entryFor(session);
36
+ try {
37
+ const supported = permissions.filter((p) => SUPPORTED_PERMISSIONS.includes(p));
38
+ const states = await readPermissionStates(e.session.page().context(), e.session.page(), supported, origin);
39
+ const out = { ...states };
40
+ for (const p of permissions) {
41
+ if (!(p in out))
42
+ out[p] = "unknown";
43
+ }
44
+ const body = {
45
+ ok: true,
46
+ session: e.id,
47
+ origin: origin ??
48
+ (() => {
49
+ try {
50
+ return new URL(e.session.page().url()).origin;
51
+ }
52
+ catch {
53
+ return null;
54
+ }
55
+ })(),
56
+ states: out,
57
+ tokensEstimate: estimateTokens(JSON.stringify(out)),
58
+ };
59
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
60
+ }
61
+ catch (err) {
62
+ return {
63
+ content: [
64
+ {
65
+ type: "text",
66
+ text: JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }, null, 2),
67
+ },
68
+ ],
69
+ };
70
+ }
71
+ });
72
+ register("set_notification_policy", {
73
+ capability: "action",
74
+ description: "Mutate the session's notification policy at runtime. Governs `new Notification(title, opts)` *constructor* calls — the page actually attempting to display a notification. Distinct from `set_permission_policy` (which gates `Notification.requestPermission` and the `Notification.permission` state); the two policies compose. Modes:\n" +
75
+ ' - "allow" — DEFAULT (browser default). Constructor proceeds; the OS displays per its own settings. Every call is still captured on `ActionResult.notifications[]` for observability.\n' +
76
+ ' - "deny" — Constructor throws `NotAllowedError` (the same exception the browser raises when permission is denied). Use to suppress OS notifications while still observing what the page would have shown.\n' +
77
+ ' - "raise" — Constructor throws AND RECORDS; the next ActionResult flips `ok:false` with `failure:{source:"app", hint:"unhandled notification — set notificationPolicy"}`. Useful when notifications should be a hard signal that the action triggered an unexpected user-facing event.\n' +
78
+ ' - "ask-human" — server blocks on `__browx.confirm(true|false)` (the `await_human({kind:"confirm"})` mechanism), then resolves to allow/deny per the human\'s answer. The constructor returns a stub synchronously (the spec requires a sync return); the real OS notification fires once the human-decision resolves.\n' +
79
+ "Persists across navigation: the init-script is re-injected on every new document within the session. Returns the resolved policy. Captured calls surface on `ActionResult.notifications[] = [{title, body?, icon?, tag?, timestamp, origin?, handledAs}]`.",
80
+ inputSchema: {
81
+ mode: z
82
+ .enum(["allow", "deny", "raise", "ask-human"])
83
+ .describe("Policy mode — see tool description."),
84
+ ...SESSION_ARG,
85
+ },
86
+ }, async (args) => {
87
+ const g = gateCheck("set_notification_policy");
88
+ if (g)
89
+ return g;
90
+ const e = await entryFor(args.session);
91
+ try {
92
+ const next = { mode: args.mode };
93
+ const resolved = e.notification.set(next);
94
+ // Push the new sync-decision hint to every live page so the
95
+ // constructor's throw timing tracks the policy without a reload.
96
+ await propagateNotificationSyncDecision(e.session.page().context(), e.notification).catch(() => undefined);
97
+ const tokensEstimate = estimateTokens(JSON.stringify(resolved));
98
+ const body = { ok: true, session: e.id, policy: resolved, tokensEstimate };
99
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
100
+ }
101
+ catch (err) {
102
+ return {
103
+ content: [
104
+ {
105
+ type: "text",
106
+ text: JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }, null, 2),
107
+ },
108
+ ],
109
+ };
110
+ }
111
+ });
112
+ register("device_requests", {
113
+ capability: "device-emulation",
114
+ description: 'Read-side companion to `emulate_bluetooth` / `emulate_usb` / `emulate_hid`. Returns the buffer of `requestDevice()` calls the page has made on this session — one entry per page-side call, each with `{api, handledAs, returned, filters?, ts}`. Useful for diagnosing "did the page even ask?" when a flow gated on hardware appears stuck. `handledAs`:\n' +
115
+ ' - `"resolved"` — catalog non-empty; picker resolved with the synthetic device (Bluetooth/USB) or device list (HID).\n' +
116
+ ' - `"rejected"` — catalog empty for Bluetooth/USB; picker rejected with `NotFoundError` (user-dismissed shape).\n' +
117
+ ' - `"empty"` — catalog empty for HID; picker resolved with `[]` (HID\'s user-dismissed shape).\n' +
118
+ ' - `"refused"` — capability `device-emulation` was OFF at the time of the call; the wrapper short-circuited. Recorded so the read surfaces "the page asked for hardware and you didn\'t have the capability on".\n' +
119
+ "**Gated behind the off-by-default `device-emulation` capability** — a server without the capability can't even read whether the page tried to ask (same posture class as `eval` / `network-body` / `secrets`). Read-only — does not mutate state.",
120
+ inputSchema: {
121
+ since: z
122
+ .number()
123
+ .int()
124
+ .nonnegative()
125
+ .optional()
126
+ .describe("epoch ms — return only records with `ts >= since`. Default 0 (return everything in the buffer)."),
127
+ ...SESSION_ARG,
128
+ },
129
+ }, async ({ since, session }) => {
130
+ const g = gateCheck("device_requests");
131
+ if (g)
132
+ return g;
133
+ const e = await entryFor(session);
134
+ try {
135
+ const records = e.webDeviceEmulation.since(typeof since === "number" ? since : 0);
136
+ const body = {
137
+ ok: true,
138
+ session: e.id,
139
+ supportedApis: [...SUPPORTED_DEVICE_APIS],
140
+ requests: records,
141
+ };
142
+ body.tokensEstimate = estimateTokens(JSON.stringify(body));
143
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
144
+ }
145
+ catch (err) {
146
+ return {
147
+ content: [
148
+ {
149
+ type: "text",
150
+ text: JSON.stringify({ ok: false, error: err instanceof Error ? err.message : String(err) }, null, 2),
151
+ },
152
+ ],
153
+ };
154
+ }
155
+ });
156
+ }
@@ -0,0 +1,16 @@
1
+ import type { ToolHost } from "./host.js";
2
+ /**
3
+ * Session lifecycle + per-session policy tools — open / close / list sessions and
4
+ * the runtime policy mutators a session is driven with: dialog, permission,
5
+ * file-system-picker, and notification policies, plus the permission-state read
6
+ * and the device-request read companion.
7
+ *
8
+ * RFC 0004 P3 / D3 (SRP): the registrations were split by cohesive family into
9
+ * three sibling modules (lifecycle / dialog-permission-fs-picker /
10
+ * notification-device). This module stays the single entry point `server.ts` +
11
+ * `tool-metadata.ts` call, and invokes each family in the EXACT prior source order
12
+ * so the registered-name set + the derived maps stay byte-identical. The host owns
13
+ * the closures (register / gate / entry / registry / workspace); the family
14
+ * modules own the registrations.
15
+ */
16
+ export declare function registerSessionPolicyTools(host: ToolHost): void;
@@ -0,0 +1,22 @@
1
+ import { registerSessionLifecycleTools } from "./session-lifecycle-tools.js";
2
+ import { registerSessionDialogPermissionTools } from "./session-dialog-permission-tools.js";
3
+ import { registerSessionNotificationDeviceTools } from "./session-notification-device-tools.js";
4
+ /**
5
+ * Session lifecycle + per-session policy tools — open / close / list sessions and
6
+ * the runtime policy mutators a session is driven with: dialog, permission,
7
+ * file-system-picker, and notification policies, plus the permission-state read
8
+ * and the device-request read companion.
9
+ *
10
+ * RFC 0004 P3 / D3 (SRP): the registrations were split by cohesive family into
11
+ * three sibling modules (lifecycle / dialog-permission-fs-picker /
12
+ * notification-device). This module stays the single entry point `server.ts` +
13
+ * `tool-metadata.ts` call, and invokes each family in the EXACT prior source order
14
+ * so the registered-name set + the derived maps stay byte-identical. The host owns
15
+ * the closures (register / gate / entry / registry / workspace); the family
16
+ * modules own the registrations.
17
+ */
18
+ export function registerSessionPolicyTools(host) {
19
+ registerSessionLifecycleTools(host);
20
+ registerSessionDialogPermissionTools(host);
21
+ registerSessionNotificationDeviceTools(host);
22
+ }
@@ -0,0 +1,28 @@
1
+ import { type EngineKind } from "../engine/index.js";
2
+ import "../engine/register-engines.js";
3
+ import { SessionRegistry, type SessionMode } from "../session/registry.js";
4
+ import type { CapabilityConfig } from "../util/capabilities.js";
5
+ import type { ConfigStore, ResolvedConfig } from "../util/config-store.js";
6
+ import type { Workspace } from "../util/workspace.js";
7
+ import type { StartOptions } from "../server.js";
8
+ /** The createServer-owned locals the SessionRegistry factory + teardown close
9
+ * over. Bundled here so the construction expression moves verbatim — every
10
+ * callback body references these exactly as it did inline in `createServer`. */
11
+ export interface SessionRegistryDeps {
12
+ opts: StartOptions;
13
+ resolvedConfig: ResolvedConfig;
14
+ configStore: ConfigStore;
15
+ caps: CapabilityConfig;
16
+ workspace: Workspace;
17
+ serverEngine: EngineKind;
18
+ serverDefaultMode: SessionMode;
19
+ }
20
+ /**
21
+ * Build the per-session `SessionRegistry` — the composition root's session
22
+ * factory + teardown pair. Moved out of `createServer` verbatim: the "default"
23
+ * session is still created lazily on the first browser-touching tool call, and
24
+ * every factory/teardown body is byte-identical to the inline version. The
25
+ * createServer locals each callback references (config, caps, workspace, …)
26
+ * arrive through `deps`.
27
+ */
28
+ export declare function buildSessionRegistry(deps: SessionRegistryDeps): SessionRegistry;
@@ -0,0 +1,427 @@
1
+ import { openManagedSession } from "../session/managed.js";
2
+ import { openByobSession } from "../session/byob.js";
3
+ import { requireCdp } from "../engine/index.js";
4
+ import { engineEntry, byobAttachNeedsEndpoint, } from "../engine/registry.js";
5
+ import "../engine/register-engines.js";
6
+ import { openIncognitoSession } from "../session/incognito.js";
7
+ import { resolveDevice } from "../session/device.js";
8
+ import { newEmulationState } from "../session/emulation.js";
9
+ import { SessionRegistry, DEFAULT_SESSION_ID, } from "../session/registry.js";
10
+ import { newExtensionRegistry } from "../session/extensions.js";
11
+ import { WedgeTracker } from "../session/wedge.js";
12
+ import { SessionMetrics } from "../session/metrics.js";
13
+ import { DialogPolicyState } from "../session/dialog.js";
14
+ import { PermissionPolicyState } from "../session/permission.js";
15
+ import { NotificationPolicyState } from "../session/notification.js";
16
+ import { FsPickerPolicyState } from "../session/fs-picker.js";
17
+ import { DeviceEmulationState as WebDeviceEmulationState } from "../session/device-emu.js";
18
+ import { RefRegistry } from "../page/refs.js";
19
+ import { FrameRegistry } from "../page/frames.js";
20
+ import { RouteRegistry } from "../page/routes.js";
21
+ import { WsInteractiveRegistry } from "../page/ws-interactive.js";
22
+ import { WorkersRegistry } from "../page/workers.js";
23
+ import { EmulationRegistry } from "../page/emulation.js";
24
+ import { ClockRegistry } from "../page/clock.js";
25
+ import { SeededRandomRegistry } from "../page/seed-random.js";
26
+ import { PerfTracingState } from "../page/perf.js";
27
+ import { CoverageTrackerState } from "../page/coverage.js";
28
+ import { RegionRegistry } from "../page/regions.js";
29
+ import { DownloadsRegistry } from "../page/downloads.js";
30
+ import { ArtifactsRegistry } from "../session/artifacts.js";
31
+ import { readStorageStateFile, authLoad } from "../session/storage.js";
32
+ import { SecretRegistry } from "../util/secrets.js";
33
+ import { ClipboardBuffer } from "../page/clipboard.js";
34
+ import { ConsoleBuffer } from "../page/console.js";
35
+ import { newHarRecorderState, buildRecordHarOption, applyHarReplay, resolveHarReplayPaths, } from "../page/har.js";
36
+ import { newVideoRecorderState, buildRecordVideoOption, finalizeVideoOnClose, } from "../page/video.js";
37
+ import { BrowxBridge } from "../helper/bridge.js";
38
+ import { Recorder } from "../page/recording.js";
39
+ import { FeedbackMemory } from "../page/learning.js";
40
+ import { log } from "../util/logging.js";
41
+ /**
42
+ * Build the per-session `SessionRegistry` — the composition root's session
43
+ * factory + teardown pair. Moved out of `createServer` verbatim: the "default"
44
+ * session is still created lazily on the first browser-touching tool call, and
45
+ * every factory/teardown body is byte-identical to the inline version. The
46
+ * createServer locals each callback references (config, caps, workspace, …)
47
+ * arrive through `deps`.
48
+ */
49
+ export function buildSessionRegistry(deps) {
50
+ const { opts, resolvedConfig, configStore, caps, workspace, serverEngine, serverDefaultMode } = deps;
51
+ // This server's OWN post-wire deps (caps / configStore / workspace) — threaded
52
+ // explicitly into `engineEntry(...).postWire(entry, serverPostWireDeps)` per
53
+ // session, never a module-global. A module-global would let a SECOND server in
54
+ // the same process (the in-process SDK transport composes one server per
55
+ // transport) overwrite this server's caps gate + workspace sandbox-root, so its
56
+ // post-wire could install another server's action-gated wrappers / stealth
57
+ // scripts on THIS server's sessions. The closure-owned local makes that
58
+ // impossible: every session this registry opens wires with exactly these deps.
59
+ const serverPostWireDeps = { caps, configStore, workspace };
60
+ // The substrate deps the registry needs to resolve a session's snapshot/network
61
+ // substrates. The registry only ever reads the bundle's `snapshot`/`network`
62
+ // selectors (the action/capture selectors — the only ones that consult
63
+ // ctxFor/describeTarget/save — are resolved in host-build's `substratesFor`, which
64
+ // owns those host locals). snapshot/network read only `e.session`, so the action/
65
+ // capture deps here are deliberately unreachable on this path; making them throw
66
+ // documents that the registry must never drive an action/capture substrate.
67
+ const registrySubstrateDeps = {
68
+ ctxFor: () => {
69
+ throw new Error("session-registry: ctxFor must not be reached — the registry resolves only the " +
70
+ "snapshot/network substrates (action/capture are host-build's concern).");
71
+ },
72
+ describeTarget: () => {
73
+ throw new Error("session-registry: describeTarget must not be reached (capture is host-build's concern).");
74
+ },
75
+ save: () => {
76
+ throw new Error("session-registry: save must not be reached (capture is host-build's concern).");
77
+ },
78
+ };
79
+ return new SessionRegistry(async (id, spec) => {
80
+ const headless = opts.headless ?? resolvedConfig.headless;
81
+ const mode = spec?.mode ?? serverDefaultMode;
82
+ // resolve the gated web-security flag *fresh* per session so a
83
+ // `set_config({disableWebSecurity})` takes effect on the next
84
+ // open_session without a server restart. Off by default.
85
+ const disableWebSecurity = configStore.resolve().disableWebSecurity === true;
86
+ // resolve device/viewport — spec overrides config-store defaults.
87
+ const device = resolveDevice({
88
+ device: spec?.device ?? resolvedConfig.defaultDevice,
89
+ viewport: spec?.viewport ?? resolvedConfig.defaultViewport,
90
+ });
91
+ // Resolve creation-time storageState (inline blob, workspace path, OR
92
+ // named slot). Mutually exclusive. `attached`/BYOB sessions ignore it
93
+ // (not-owned: we don't seed someone else's Chrome).
94
+ let creationStorageState;
95
+ if (spec?.storageState !== undefined && spec?.authState !== undefined) {
96
+ throw new Error(`session "${id}": pass exactly one of \`storageState\` or \`authState\` (not both)`);
97
+ }
98
+ if (spec?.authState !== undefined) {
99
+ creationStorageState = authLoad(workspace.root, spec.authState);
100
+ }
101
+ else if (typeof spec?.storageState === "string") {
102
+ creationStorageState = readStorageStateFile(workspace.root, spec.storageState, "open_session");
103
+ }
104
+ else if (spec?.storageState) {
105
+ creationStorageState = spec.storageState;
106
+ }
107
+ // Resolve HAR recording config (native context-creation primitive). The
108
+ // path is workspace-rooted by construction (resolveWorkspacePath rejects
109
+ // escape) and the parent dir is created up-front. Ignored on attached
110
+ // (we don't mutate the consumer's Chrome).
111
+ let creationRecordHar;
112
+ let creationRecordHarResolved;
113
+ if (spec?.har) {
114
+ const built = buildRecordHarOption(workspace.root, id, spec.har);
115
+ creationRecordHar = built.recordHar;
116
+ creationRecordHarResolved = { path: built.path, mode: built.mode, content: built.content };
117
+ }
118
+ // Resolve replay HAR paths (workspace-escape rejected; missing file
119
+ // errors loudly so a typo doesn't silently fall back to live network).
120
+ let creationReplayHars;
121
+ if (spec?.hars && spec.hars.length) {
122
+ creationReplayHars = resolveHarReplayPaths(workspace.root, spec.hars, "open_session");
123
+ }
124
+ // Resolve video recording config (native context-creation primitive).
125
+ // The target path is workspace-rooted by construction; the staging dir
126
+ // (where Playwright auto-names the file) is also under the workspace.
127
+ // Ignored on attached (we don't mutate the consumer's Chrome).
128
+ let creationRecordVideo;
129
+ let creationRecordVideoResolved;
130
+ if (spec?.recordVideo) {
131
+ const built = buildRecordVideoOption(workspace.root, id, spec.recordVideo);
132
+ creationRecordVideo = built.recordVideo;
133
+ creationRecordVideoResolved = {
134
+ targetPath: built.targetPath,
135
+ stagingDir: built.stagingDir,
136
+ size: built.size,
137
+ };
138
+ }
139
+ let sess;
140
+ if (mode === "attached") {
141
+ // android attach is endpoint-DISCOVERED over adb — it does NOT need
142
+ // BROWX_ATTACH_CDP; the desktop CDP-attach lane still requires it. The
143
+ // android-specific fact lives in the engine layer (`byobAttachNeedsEndpoint`),
144
+ // so this precondition stays engine-agnostic (no `=== "android"` literal).
145
+ if (byobAttachNeedsEndpoint(serverEngine) && !opts.attachCdp) {
146
+ throw new Error(`session "${id}": mode "attached" requires the server to be started with BROWX_ATTACH_CDP (per-session attach isn't supported yet)`);
147
+ }
148
+ if (creationStorageState) {
149
+ log.warn(`session "${id}": ignoring storageState/authState for attached/BYOB session — ` +
150
+ "the consumer's Chrome is not-owned and we don't seed it. Use inject_storage_state " +
151
+ "explicitly if you really mean to overwrite the attached browser's state.");
152
+ }
153
+ if (creationRecordHar) {
154
+ log.warn(`session "${id}": ignoring \`har\` recording for attached/BYOB session — ` +
155
+ "the consumer's Chrome is not-owned and we don't wire context-creation primitives on it. " +
156
+ "Use `start_har` post-attach if you really want HAR on a BYOB session " +
157
+ "(it routes via runtime `routeFromHAR`, with the same finalize-on-context-close caveat).");
158
+ creationRecordHar = undefined;
159
+ creationRecordHarResolved = undefined;
160
+ }
161
+ if (creationRecordVideo) {
162
+ // Hard refusal: video has no runtime fallback (Playwright doesn't
163
+ // expose mid-context video start), so a silent ignore would leave
164
+ // the agent expecting a .webm that never lands. Surface it loudly.
165
+ throw new Error(`session "${id}": \`recordVideo\` is not supported on attached / BYOB sessions — ` +
166
+ "Playwright's `recordVideo` is a context-creation primitive and we don't " +
167
+ "wire context-creation primitives on the consumer's Chrome (not-owned). " +
168
+ 'Open a managed session (open_session({mode:"persistent"}) or {mode:"incognito"}) ' +
169
+ "with {recordVideo:{...}} to record.");
170
+ }
171
+ // Attached Chrome is not-owned: device emulation is best-effort
172
+ // (viewport via Emulation in byob.ts); isMobile/touch/UA can't be
173
+ // retro-applied to an existing context.
174
+ sess = await openByobSession({
175
+ attachCdp: opts.attachCdp,
176
+ headless,
177
+ browserType: serverEngine,
178
+ });
179
+ }
180
+ else if (mode === "incognito") {
181
+ sess = await openIncognitoSession({
182
+ headless,
183
+ device,
184
+ disableWebSecurity,
185
+ storageState: creationStorageState,
186
+ recordHar: creationRecordHar,
187
+ recordVideo: creationRecordVideo,
188
+ browserType: serverEngine,
189
+ });
190
+ }
191
+ else {
192
+ // persistent: the default session keeps the legacy single `profile`
193
+ // dir for back-compat; named/explicit profiles get their own dir so
194
+ // sessions don't share a cookie jar on disk.
195
+ const profileDir = id === DEFAULT_SESSION_ID && !spec?.profile
196
+ ? workspace.sub("profile")
197
+ : workspace.sub(`profiles/${spec?.profile ?? id}`);
198
+ // first launch — no extensions registered yet (the registry is
199
+ // mutated by the `extensions_*` tools post-creation, and a rebuild
200
+ // path materialises the list into launch flags then).
201
+ sess = await openManagedSession({
202
+ headless,
203
+ profileDir,
204
+ device,
205
+ disableWebSecurity,
206
+ storageState: creationStorageState,
207
+ recordHar: creationRecordHar,
208
+ recordVideo: creationRecordVideo,
209
+ browserType: serverEngine,
210
+ });
211
+ }
212
+ // Initialise HAR recorder state. If `recordHar` was wired at context
213
+ // creation, mark the recorder `active + nativeRecord:true` so
214
+ // `start_har` / `stop_har` can refuse cleanly (the native path can't be
215
+ // toggled mid-session — Playwright finalizes it on context.close()).
216
+ const harState = newHarRecorderState();
217
+ // The per-engine substrate bundle — the EngineRegistry resolves it once per
218
+ // session (RFC 0004 D1). The seven selectors (actions/capture/storage/script/
219
+ // emulation/snapshot/network) are the engine's own concern; here we use the
220
+ // snapshot/network pair to wire the session's substrates. A `{ session }`
221
+ // partial is enough for those two (they read only `e.session`); the substrate
222
+ // deps are this server's own (action/capture deps unreachable on this path).
223
+ const substrates = engineEntry(sess.engine).makeSubstrates(registrySubstrateDeps);
224
+ const substrateSeed = { session: sess };
225
+ // safari is the first non-Playwright engine: it has no Playwright Page, no
226
+ // Playwright BrowserContext. The few creation-config steps below that need
227
+ // the per-session creation locals (HAR/video state init, HAR replay) stay in
228
+ // the factory, keyed on the engine's Playwright-Page capability (`!sess.safari`
229
+ // — a capability check, not an engine-name branch). The full post-creation
230
+ // attach set (console / bridge / dialog / permission / notification /
231
+ // fs-picker / downloads / overlay / stealth / device-emulation / ws-interactive
232
+ // / workers) has been RELOCATED into the engine's `postWire` (called after the
233
+ // entry is assembled), so the 17 scattered `!== "safari"` guards collapse into
234
+ // one engine-agnostic call — byte-identical, only owned by the engine now.
235
+ const hasPlaywrightPage = !sess.safari;
236
+ if (creationRecordHarResolved && hasPlaywrightPage) {
237
+ harState.active = true;
238
+ harState.nativeRecord = true;
239
+ harState.path = creationRecordHarResolved.path;
240
+ harState.mode = creationRecordHarResolved.mode;
241
+ harState.content = creationRecordHarResolved.content;
242
+ harState.startedAt = Date.now();
243
+ }
244
+ // Initialise video recorder state. If `recordVideo` was wired at
245
+ // context creation, mark the recorder active so `stop_video` /
246
+ // `get_video` can refer to the reserved target path. The .webm is
247
+ // finalized when the context closes (Playwright constraint) —
248
+ // teardown calls `page.video().saveAs(targetPath)`.
249
+ const videoState = newVideoRecorderState();
250
+ if (creationRecordVideoResolved && hasPlaywrightPage) {
251
+ videoState.active = true;
252
+ videoState.targetPath = creationRecordVideoResolved.targetPath;
253
+ videoState.stagingDir = creationRecordVideoResolved.stagingDir;
254
+ videoState.size = creationRecordVideoResolved.size;
255
+ videoState.startedAt = Date.now();
256
+ }
257
+ // Apply HAR replay file(s) post-create. `routeFromHAR` is wired with
258
+ // `notFound:"fallback"` so a request not in the archive falls through
259
+ // to live network — the safer default. Replay is honoured on every
260
+ // session mode (incl. attached: the consumer's Chrome receives the
261
+ // route handler scoped to its context; warning emitted up-stream).
262
+ if (creationReplayHars && creationReplayHars.length && hasPlaywrightPage) {
263
+ await applyHarReplay(sess.page().context(), creationReplayHars);
264
+ }
265
+ // per-session console buffer. The page/BiDi attach is the engine's job —
266
+ // it runs in `postWire` (Playwright: `console.attach(page)`; Safari: the
267
+ // BiDi `log.entryAdded` bridge), so the buffer is built here and wired below.
268
+ const consoleBuf = new ConsoleBuffer();
269
+ // The network/WS substrate is selected by engine capability via the bundle:
270
+ // chromium (CDP present) gets the verbatim CDP NetworkBuffer/WsBuffer/tap;
271
+ // firefox/webkit get the Playwright context-event buffers; safari the no-op.
272
+ // The session-wide rings attach once here; the action window mints its
273
+ // per-action tap from the substrate and `network_body` fetches through it —
274
+ // so the network tools + the envelope's network slice run on every engine.
275
+ const networkSub = substrates.network(substrateSeed);
276
+ await networkSub.attach();
277
+ const networkBuf = networkSub.http;
278
+ const wsBuf = networkSub.ws;
279
+ // per-session secrets registry. Empty until `register_secret` is
280
+ // called; the egress sinks below all reference this same instance so
281
+ // a later register-call lights up masking globally for the session.
282
+ const secretsReg = new SecretRegistry();
283
+ consoleBuf.setSecrets(secretsReg);
284
+ networkSub.setSecrets(secretsReg);
285
+ const br = new BrowxBridge();
286
+ // dialog / permission / notification / fs-picker policy STATES are built
287
+ // here from the spec (the string parsing happened at the open_session tool
288
+ // layer); their per-context ATTACH lives in the engine's `postWire`.
289
+ const dialogState = new DialogPolicyState(spec?.dialogPolicy ?? { mode: "raise" });
290
+ const permissionState = new PermissionPolicyState(spec?.permissionPolicy ?? { mode: "raise" });
291
+ const notificationState = new NotificationPolicyState(spec?.notificationPolicy ?? { mode: "allow" });
292
+ const fsPickerState = new FsPickerPolicyState(spec?.fsPickerPolicy ?? { mode: "raise" });
293
+ // Per-session download capture. Storage dir is workspace-rooted +
294
+ // per-session — kept off the public profile dir so cleaning up captured
295
+ // artefacts is a single rmdir without touching the profile. The
296
+ // registry is off by default; the `downloads_capture` MCP tool toggles
297
+ // it. The context listener attach lives in the engine's `postWire`.
298
+ const downloadsDir = workspace.sub(`.downloads/${id}`);
299
+ const downloadsReg = new DownloadsRegistry(downloadsDir);
300
+ // Per-session artifact KV. Storage dir is workspace-rooted +
301
+ // per-session; the dir itself is created lazily on first save, and
302
+ // wiped on session teardown (see `teardown` below). Capacity-bounded
303
+ // — 200 entries / 50 MiB, oldest-write evicted.
304
+ const artifactsDir = workspace.sub(`.artifacts/${id}`);
305
+ const artifactsReg = new ArtifactsRegistry(artifactsDir);
306
+ // Fresh per-primitive device-emulation state (locale, timezone,
307
+ // geolocation, colour scheme, reduced motion, user-agent, permissions).
308
+ // Re-applied on every new page in this context so a mid-session-opened
309
+ // tab inherits the overrides — the page-event re-apply attach lives in the
310
+ // engine's `postWire`.
311
+ const deviceEmulation = newEmulationState();
312
+ // Per-session Web Bluetooth / WebUSB / WebHID synthetic-device catalogs
313
+ // (capability `device-emulation`). The init-script wrappers install in
314
+ // `postWire`; the catalog is off by default until the emulate_* tools
315
+ // populate it.
316
+ const webDeviceEmulation = new WebDeviceEmulationState(caps.enabled.has("device-emulation"));
317
+ const entry = {
318
+ id,
319
+ mode,
320
+ session: sess,
321
+ refs: new RefRegistry(),
322
+ // Engine-agnostic snapshot/a11y substrate, resolved from the engine's
323
+ // bundle (chromium → the verbatim CDP substrate; firefox/webkit → the
324
+ // page-side walker; safari → the WebDriver-Classic DOM-walk). Selected by
325
+ // the engine's capability, never an engine-name check. Captured once here
326
+ // so the hot snapshot/find path is a direct delegate, no per-call allocation.
327
+ snapshotSubstrate: substrates.snapshot(substrateSeed),
328
+ // Engine-agnostic network substrate (also from the bundle). `network` / `ws`
329
+ // below ARE this substrate's session-wide rings; the action window mints its
330
+ // per-action tap from it. Captured once here so the hot envelope path is a
331
+ // captured-handle delegate.
332
+ networkSubstrate: networkSub,
333
+ frames: new FrameRegistry(),
334
+ console: consoleBuf,
335
+ network: networkBuf,
336
+ ws: wsBuf,
337
+ bridge: br,
338
+ recorder: new Recorder(),
339
+ feedback: new FeedbackMemory(),
340
+ clipboard: new ClipboardBuffer(),
341
+ routes: new RouteRegistry(),
342
+ // The page-side WS-interactive + workers wrappers install EAGERLY — but
343
+ // that install is a Playwright-Page concern, so it has moved into the
344
+ // engine's `postWire` (capability-gated on `action` / `read`). Here we
345
+ // build the empty registries; `postWire` installs the page wrappers before
346
+ // the session is handed to a tool call (byte-identical eager-install timing).
347
+ wsInteractive: new WsInteractiveRegistry(),
348
+ workers: new WorkersRegistry(),
349
+ regions: new RegionRegistry(),
350
+ emulation: new EmulationRegistry(),
351
+ clock: new ClockRegistry(),
352
+ seededRandom: new SeededRandomRegistry(),
353
+ perf: new PerfTracingState(),
354
+ coverage: new CoverageTrackerState(),
355
+ wedge: new WedgeTracker(),
356
+ metrics: new SessionMetrics(),
357
+ dialog: dialogState,
358
+ permission: permissionState,
359
+ notification: notificationState,
360
+ fsPicker: fsPickerState,
361
+ deviceEmulation,
362
+ webDeviceEmulation,
363
+ har: harState,
364
+ video: videoState,
365
+ secrets: secretsReg,
366
+ extensions: newExtensionRegistry(),
367
+ downloads: downloadsReg,
368
+ artifacts: artifactsReg,
369
+ ...(mode === "persistent" ? { launchProfile: spec?.profile ?? id } : {}),
370
+ openedAt: Date.now(),
371
+ lastActivityAt: Date.now(),
372
+ };
373
+ // Post-creation wiring — the engine owns its own bookkeeping (RFC 0004 D1).
374
+ // The four Playwright engines attach the full console/bridge/policy/download/
375
+ // stealth/device-emulation/ws-interactive/workers set + await it; safari
376
+ // attaches only its BiDi console bridge; a no-Page engine attaches nothing.
377
+ // This is the one call the 17 scattered `!== "safari"` guards collapsed into.
378
+ // The per-server deps are passed explicitly (never a module-global) so a
379
+ // second server in this process can never wire THIS session with its caps or
380
+ // sandbox root.
381
+ await engineEntry(sess.engine).postWire(entry, serverPostWireDeps);
382
+ return entry;
383
+ }, async (e) => {
384
+ // Stop any in-flight perf trace BEFORE closing CDP — otherwise the
385
+ // attached Chrome (BYOB) keeps the trace buffer pinned. Best-effort:
386
+ // a stuck Tracing.end won't block teardown (perf state bounds the wait).
387
+ // Keyed on the Playwright-Page capability (`!e.session.safari`), not an
388
+ // engine-name branch — Safari has no CDP, so `requireCdp` would refuse.
389
+ const teardownHasCdp = !e.session.safari;
390
+ if (teardownHasCdp)
391
+ await e.perf.closeIfRunning(requireCdp(e.session)).catch(() => undefined);
392
+ // also release any in-flight Profiler/CSS coverage on
393
+ // the attached target so a BYOB Chrome doesn't keep coverage state
394
+ // pinned past detach.
395
+ if (teardownHasCdp)
396
+ await e.coverage.closeIfRunning(requireCdp(e.session)).catch(() => undefined);
397
+ // workers registry CDP listeners. Detach before CDP closes
398
+ // so we don't race the parent session shutdown.
399
+ try {
400
+ e.workers.dispose();
401
+ }
402
+ catch {
403
+ /* best-effort */
404
+ }
405
+ await e.bridge.detach().catch(() => undefined);
406
+ // Capture page reference BEFORE close — `page.video()` resolves the
407
+ // Video handle, but the actual .webm is only flushed by the underlying
408
+ // context.close() that `e.session.close()` triggers. `video.saveAs()`
409
+ // (called inside finalizeVideoOnClose) blocks until the page is closed
410
+ // AND the recording is fully written, so the order is: grab page →
411
+ // close context → saveAs to deterministic target path.
412
+ const videoPage = e.video.active ? e.session.page() : undefined;
413
+ await e.session.close().catch(() => undefined);
414
+ if (videoPage) {
415
+ await finalizeVideoOnClose(videoPage, e.video).catch(() => undefined);
416
+ }
417
+ // Clear session-scoped artifacts on teardown. Best-effort: a stuck
418
+ // rm won't block teardown. Sessions that never wrote an artifact
419
+ // never create the dir, so this is a no-op for them.
420
+ try {
421
+ e.artifacts.clear();
422
+ }
423
+ catch {
424
+ /* best-effort */
425
+ }
426
+ });
427
+ }