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,46 @@
1
+ /** The minimal WebSocket surface this client uses — satisfied by Node 22's global
2
+ * `WebSocket` and by the test double. */
3
+ export interface WebSocketLike {
4
+ send(data: string): void;
5
+ close(): void;
6
+ addEventListener(type: "open" | "message" | "error" | "close", listener: (ev: {
7
+ data?: string;
8
+ }) => void): void;
9
+ }
10
+ export type WebSocketFactory = (url: string) => WebSocketLike;
11
+ /** A BiDi event payload (`{type:"event", method, params}`) dispatched to `on()`
12
+ * handlers — e.g. `log.entryAdded`, `browsingContext.load`. */
13
+ export type BidiEventHandler = (params: Record<string, unknown>) => void;
14
+ /** A BiDi command error (`{type:"error", error, message}`) surfaced as a
15
+ * structured throw — never a silent failure. */
16
+ export declare class BidiError extends Error {
17
+ readonly bidiError: string;
18
+ constructor(bidiError: string, message: string);
19
+ }
20
+ export declare class SafariBidiClient {
21
+ private readonly url;
22
+ private readonly wsFactory;
23
+ private readonly commandTimeoutMs;
24
+ private ws;
25
+ private nextId;
26
+ private readonly pending;
27
+ private readonly handlers;
28
+ constructor(opts: {
29
+ url: string;
30
+ wsFactory?: WebSocketFactory;
31
+ commandTimeoutMs?: number;
32
+ });
33
+ /** Open the socket. Resolves on `open`, rejects on a connect-time `error`. */
34
+ connect(): Promise<void>;
35
+ /** Send a BiDi command and await its correlated reply. Rejects with a
36
+ * `BidiError` on an error reply (e.g. `unknown command` for a module Safari
37
+ * does not implement) and on timeout. */
38
+ send(method: string, params?: Record<string, unknown>): Promise<unknown>;
39
+ /** Subscribe to BiDi events (`session.subscribe`). The corresponding `on()`
40
+ * handlers then fire as events arrive. */
41
+ subscribe(events: string[]): Promise<void>;
42
+ /** Register a handler for a BiDi event method (e.g. `log.entryAdded`). */
43
+ on(method: string, handler: BidiEventHandler): void;
44
+ close(): void;
45
+ private onMessage;
46
+ }
@@ -0,0 +1,130 @@
1
+ // SafariBidiClient — the WebDriver-BiDi WebSocket client beneath the
2
+ // SafaridriverHybridAdapter. This is the ADDITIVE half of the
3
+ // hybrid: live probing found
4
+ // Safari 26.5 opens a real BiDi socket ONLY behind the vendor cap
5
+ // `safari:experimentalWebSocketUrl:true`, and that socket serves a PARTIAL but
6
+ // real surface — `script` (evaluate/callFunction/getRealms/addPreloadScript),
7
+ // `browsingContext` navigation/lifecycle/setViewport/create/activate, and the
8
+ // events that fired (`browsingContext.navigation*`/`load`, `log.entryAdded`).
9
+ // It does NOT serve input/network/emulation/screenshot/locateNodes/storage — the
10
+ // adapter routes those through WebDriver Classic (SafariWebDriverClient) or gates
11
+ // them. Because the experimental cap can disappear in any Safari point release,
12
+ // this client is STRICTLY OPTIONAL: the adapter runs Classic-only when there is
13
+ // no ws:// URL, so nothing here is on the critical path.
14
+ //
15
+ // Node's global `WebSocket` (v22+) is the transport — no `ws` dependency, exactly
16
+ // as the probe used. The factory is injected (`WebSocketFactory`) so the
17
+ // request/response correlation + event dispatch unit-test without a real socket.
18
+ /** A BiDi command error (`{type:"error", error, message}`) surfaced as a
19
+ * structured throw — never a silent failure. */
20
+ export class BidiError extends Error {
21
+ bidiError;
22
+ constructor(bidiError, message) {
23
+ super(`safari-bidi: ${bidiError}: ${message}`);
24
+ this.name = "BidiError";
25
+ this.bidiError = bidiError;
26
+ }
27
+ }
28
+ export class SafariBidiClient {
29
+ url;
30
+ wsFactory;
31
+ commandTimeoutMs;
32
+ ws;
33
+ nextId = 1;
34
+ pending = new Map();
35
+ handlers = new Map();
36
+ constructor(opts) {
37
+ this.url = opts.url;
38
+ // Node 22's global WebSocket is structurally a WebSocketLike.
39
+ this.wsFactory = opts.wsFactory ?? ((u) => new WebSocket(u));
40
+ this.commandTimeoutMs = opts.commandTimeoutMs ?? 10_000;
41
+ }
42
+ /** Open the socket. Resolves on `open`, rejects on a connect-time `error`. */
43
+ connect() {
44
+ return new Promise((resolve, reject) => {
45
+ const ws = this.wsFactory(this.url);
46
+ this.ws = ws;
47
+ ws.addEventListener("open", () => resolve());
48
+ ws.addEventListener("error", (ev) => reject(new Error(`safari-bidi: socket error ${describe(ev)}`)));
49
+ ws.addEventListener("message", (ev) => this.onMessage(ev.data));
50
+ });
51
+ }
52
+ /** Send a BiDi command and await its correlated reply. Rejects with a
53
+ * `BidiError` on an error reply (e.g. `unknown command` for a module Safari
54
+ * does not implement) and on timeout. */
55
+ send(method, params = {}) {
56
+ if (!this.ws)
57
+ return Promise.reject(new Error("safari-bidi: not connected"));
58
+ const id = this.nextId++;
59
+ const ws = this.ws;
60
+ return new Promise((resolve, reject) => {
61
+ const timer = setTimeout(() => {
62
+ this.pending.delete(id);
63
+ reject(new Error(`safari-bidi: command timed out after ${this.commandTimeoutMs}ms: ${method}`));
64
+ }, this.commandTimeoutMs);
65
+ this.pending.set(id, { resolve, reject, timer });
66
+ ws.send(JSON.stringify({ id, method, params }));
67
+ });
68
+ }
69
+ /** Subscribe to BiDi events (`session.subscribe`). The corresponding `on()`
70
+ * handlers then fire as events arrive. */
71
+ async subscribe(events) {
72
+ await this.send("session.subscribe", { events });
73
+ }
74
+ /** Register a handler for a BiDi event method (e.g. `log.entryAdded`). */
75
+ on(method, handler) {
76
+ let set = this.handlers.get(method);
77
+ if (!set) {
78
+ set = new Set();
79
+ this.handlers.set(method, set);
80
+ }
81
+ set.add(handler);
82
+ }
83
+ close() {
84
+ for (const { reject, timer } of this.pending.values()) {
85
+ clearTimeout(timer);
86
+ reject(new Error("safari-bidi: client closed"));
87
+ }
88
+ this.pending.clear();
89
+ this.ws?.close();
90
+ this.ws = undefined;
91
+ }
92
+ onMessage(data) {
93
+ if (data === undefined)
94
+ return;
95
+ let msg;
96
+ try {
97
+ msg = JSON.parse(data);
98
+ }
99
+ catch {
100
+ return;
101
+ }
102
+ if (msg.type === "event" && msg.method) {
103
+ const set = this.handlers.get(msg.method);
104
+ if (set)
105
+ for (const h of set)
106
+ h(msg.params ?? {});
107
+ return;
108
+ }
109
+ if (typeof msg.id === "number") {
110
+ const entry = this.pending.get(msg.id);
111
+ if (!entry)
112
+ return;
113
+ this.pending.delete(msg.id);
114
+ clearTimeout(entry.timer);
115
+ if (msg.type === "error") {
116
+ entry.reject(new BidiError(msg.error ?? "unknown error", msg.message ?? ""));
117
+ }
118
+ else {
119
+ entry.resolve(msg.result);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ /** Best-effort description of a socket error event for the connect rejection. */
125
+ function describe(ev) {
126
+ if (ev && typeof ev === "object" && "message" in ev) {
127
+ return String(ev.message);
128
+ }
129
+ return "";
130
+ }
@@ -0,0 +1,56 @@
1
+ /** Canonical safaridriver path (the symlink in /usr/bin resolves into the Safari
2
+ * cryptex). Overridable in tests via `SafariLaunchDeps.driverPath`. */
3
+ export declare const SAFARIDRIVER_PATH = "/usr/bin/safaridriver";
4
+ /** The minimal child-process surface the launcher owns. Satisfied by Node's
5
+ * `ChildProcess`; the test double records the kill. */
6
+ export interface ProcessLike {
7
+ readonly pid?: number;
8
+ kill(): boolean;
9
+ }
10
+ export type SpawnLike = (cmd: string, args: string[]) => ProcessLike;
11
+ /** Raised when Safari automation cannot run on this host at all — not macOS, or
12
+ * safaridriver is absent. Structured (no vague crash) per the doctrine, naming
13
+ * the fix. */
14
+ export declare class SafariUnavailableError extends Error {
15
+ constructor(reason: string);
16
+ }
17
+ /** Raised when safaridriver never reaches readiness within the poll window. */
18
+ export declare class SafariLaunchTimeoutError extends Error {
19
+ constructor(ms: number);
20
+ }
21
+ /** Injectable IO seams (defaults shell out / probe for real). */
22
+ export interface SafariLaunchDeps {
23
+ spawnImpl?: SpawnLike;
24
+ /** Resolve a free loopback port (defaults to adb.ts's `pickFreePort`). */
25
+ pickPort?: () => Promise<number>;
26
+ /** Probe whether a driver at `baseUrl` is ready (defaults to a real GET
27
+ * /status). Injected so the poll loop tests without a driver. */
28
+ probeReady?: (baseUrl: string) => Promise<boolean>;
29
+ /** Whether the safaridriver binary exists (defaults to a real `statSync`). */
30
+ binaryExists?: (path: string) => boolean;
31
+ /** The host platform (defaults to `process.platform`). */
32
+ platform?: NodeJS.Platform;
33
+ /** Override the driver path (tests). */
34
+ driverPath?: string;
35
+ /** Sleep between readiness polls (injected so tests don't wait). */
36
+ sleep?: (ms: number) => Promise<void>;
37
+ readinessTimeoutMs?: number;
38
+ pollIntervalMs?: number;
39
+ }
40
+ /** A running safaridriver. `baseUrl` is the WebDriver HTTP endpoint; `stop()`
41
+ * kills the process. */
42
+ export interface SafariDriverProcess {
43
+ baseUrl: string;
44
+ httpPort: number;
45
+ process: ProcessLike;
46
+ stop(): void;
47
+ }
48
+ /** Platform + binary precheck. Throws `SafariUnavailableError` off-macOS or when
49
+ * safaridriver is absent — the launch fast-fails with a clear reason rather than
50
+ * spawning a doomed process. */
51
+ export declare function assertSafariAvailable(deps?: SafariLaunchDeps): void;
52
+ /** Spawn safaridriver and poll it to readiness. Pre-checks availability, picks a
53
+ * free HTTP port (+ a BiDi port), spawns `safaridriver -p <http> --bidi <bidi>`,
54
+ * then polls GET /status until ready or the timeout — killing the process if it
55
+ * never comes up (no leaked driver). */
56
+ export declare function launchSafaridriver(deps?: SafariLaunchDeps): Promise<SafariDriverProcess>;
@@ -0,0 +1,104 @@
1
+ // safaridriver process lifecycle for the SafaridriverHybridAdapter
2
+ // — spawn the driver, poll it to readiness, and own its teardown. Split into a
3
+ // platform/binary precheck + the spawn/poll, with the IO seams (spawn, the
4
+ // readiness probe, the sleep) injected so the orchestration unit-tests WITHOUT a
5
+ // real safaridriver — the same discipline as adb.ts. The real IO path is covered
6
+ // by the Safari-gated keystone.
7
+ //
8
+ // safaridriver is macOS-only and ships inside the Safari cryptex
9
+ // (`/usr/bin/safaridriver` → `/System/Cryptexes/App/usr/bin/safaridriver`). It
10
+ // is launched as `safaridriver -p <httpPort> --bidi <bidiPort>`: the HTTP port
11
+ // serves WebDriver Classic + session creation; `--bidi` enables BiDi for hosted
12
+ // sessions (the actual ws:// socket is allocated dynamically and reported in the
13
+ // granted caps, NOT bound to the passed port value).
14
+ import { execFile } from "node:child_process";
15
+ import { statSync } from "node:fs";
16
+ import { SafariWebDriverClient } from "./webdriver-client.js";
17
+ /** Canonical safaridriver path (the symlink in /usr/bin resolves into the Safari
18
+ * cryptex). Overridable in tests via `SafariLaunchDeps.driverPath`. */
19
+ export const SAFARIDRIVER_PATH = "/usr/bin/safaridriver";
20
+ /** Raised when Safari automation cannot run on this host at all — not macOS, or
21
+ * safaridriver is absent. Structured (no vague crash) per the doctrine, naming
22
+ * the fix. */
23
+ export class SafariUnavailableError extends Error {
24
+ constructor(reason) {
25
+ super(`safari-unavailable: ${reason}. Real Safari automation needs macOS with safaridriver ` +
26
+ `(${SAFARIDRIVER_PATH}).`);
27
+ this.name = "SafariUnavailableError";
28
+ }
29
+ }
30
+ /** Raised when safaridriver never reaches readiness within the poll window. */
31
+ export class SafariLaunchTimeoutError extends Error {
32
+ constructor(ms) {
33
+ super(`safari-launch-timeout: safaridriver did not become ready within ${ms}ms`);
34
+ this.name = "SafariLaunchTimeoutError";
35
+ }
36
+ }
37
+ function defaultBinaryExists(path) {
38
+ try {
39
+ statSync(path);
40
+ return true;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ function defaultSpawn(cmd, args) {
47
+ // detached:false — the driver dies with the parent; stdio ignored (we talk to
48
+ // it over HTTP, not its stdout).
49
+ return execFile(cmd, args, () => undefined);
50
+ }
51
+ function defaultSleep(ms) {
52
+ return new Promise((r) => setTimeout(r, ms));
53
+ }
54
+ /** Platform + binary precheck. Throws `SafariUnavailableError` off-macOS or when
55
+ * safaridriver is absent — the launch fast-fails with a clear reason rather than
56
+ * spawning a doomed process. */
57
+ export function assertSafariAvailable(deps = {}) {
58
+ const platform = deps.platform ?? process.platform;
59
+ if (platform !== "darwin") {
60
+ throw new SafariUnavailableError(`host platform is "${platform}", not macOS`);
61
+ }
62
+ const driverPath = deps.driverPath ?? SAFARIDRIVER_PATH;
63
+ const exists = deps.binaryExists ?? defaultBinaryExists;
64
+ if (!exists(driverPath)) {
65
+ throw new SafariUnavailableError(`safaridriver not found at ${driverPath}`);
66
+ }
67
+ }
68
+ /** Spawn safaridriver and poll it to readiness. Pre-checks availability, picks a
69
+ * free HTTP port (+ a BiDi port), spawns `safaridriver -p <http> --bidi <bidi>`,
70
+ * then polls GET /status until ready or the timeout — killing the process if it
71
+ * never comes up (no leaked driver). */
72
+ export async function launchSafaridriver(deps = {}) {
73
+ assertSafariAvailable(deps);
74
+ const { pickFreePort } = await import("../adb.js");
75
+ const pickPort = deps.pickPort ?? pickFreePort;
76
+ const spawnImpl = deps.spawnImpl ?? defaultSpawn;
77
+ const sleep = deps.sleep ?? defaultSleep;
78
+ const timeoutMs = deps.readinessTimeoutMs ?? 10_000;
79
+ const intervalMs = deps.pollIntervalMs ?? 150;
80
+ const driverPath = deps.driverPath ?? SAFARIDRIVER_PATH;
81
+ const httpPort = await pickPort();
82
+ const bidiPort = await pickPort();
83
+ const baseUrl = `http://127.0.0.1:${httpPort}`;
84
+ const probeReady = deps.probeReady ??
85
+ ((url) => new SafariWebDriverClient({ baseUrl: url }).status().then((s) => s.ready));
86
+ const proc = spawnImpl(driverPath, ["-p", String(httpPort), "--bidi", String(bidiPort)]);
87
+ const stop = () => {
88
+ try {
89
+ proc.kill();
90
+ }
91
+ catch {
92
+ /* already dead */
93
+ }
94
+ };
95
+ const deadline = timeoutMs / intervalMs;
96
+ for (let attempt = 0; attempt < deadline; attempt++) {
97
+ if (await probeReady(baseUrl)) {
98
+ return { baseUrl, httpPort, process: proc, stop };
99
+ }
100
+ await sleep(intervalMs);
101
+ }
102
+ stop();
103
+ throw new SafariLaunchTimeoutError(timeoutMs);
104
+ }
@@ -0,0 +1,102 @@
1
+ /** The subset of the global `fetch` signature this client uses. Injected so the
2
+ * unit tests pass a mock and the orchestration is exercised driver-free. */
3
+ export type FetchLike = (url: string, init: {
4
+ method: string;
5
+ headers: Record<string, string>;
6
+ body?: string;
7
+ }) => Promise<{
8
+ ok: boolean;
9
+ status: number;
10
+ json(): Promise<unknown>;
11
+ }>;
12
+ /** A WebDriver cookie (the fields the cookie tools round-trip). */
13
+ export interface WebDriverCookie {
14
+ name: string;
15
+ value: string;
16
+ domain?: string;
17
+ path?: string;
18
+ secure?: boolean;
19
+ httpOnly?: boolean;
20
+ expiry?: number;
21
+ sameSite?: "Lax" | "Strict" | "None";
22
+ }
23
+ /** The granted-capabilities shape this client cares about — `webSocketUrl` is a
24
+ * real `ws://` string ONLY when the session was created with
25
+ * `safari:experimentalWebSocketUrl:true` (otherwise it is a boolean placeholder
26
+ * and no BiDi socket exists — see reference 06). */
27
+ export interface NewSessionResult {
28
+ sessionId: string;
29
+ capabilities: Record<string, unknown>;
30
+ /** The BiDi WebSocket URL, present only when the experimental cap negotiated a
31
+ * real socket. A boolean or undefined means "no BiDi" — run Classic-only. */
32
+ webSocketUrl: string | undefined;
33
+ }
34
+ /** A WebDriver protocol error surfaced as a structured throw (never a vague
35
+ * mid-call failure — the doctrine's no-silent-failure rule). `error` is the W3C
36
+ * error code (e.g. `session not created`, `no such element`). */
37
+ export declare class WebDriverError extends Error {
38
+ readonly code: string;
39
+ readonly httpStatus: number;
40
+ constructor(code: string, message: string, httpStatus: number);
41
+ }
42
+ /** Whether a request body is an experimental-cap BiDi request (for the
43
+ * capability negotiation the adapter does at session create). */
44
+ export interface SessionCapabilities {
45
+ /** Request a BiDi socket. Pairs with `experimentalWebSocketUrl` on Safari. */
46
+ webSocketUrl?: boolean;
47
+ /** Safari vendor cap — REQUIRED to actually open a BiDi socket on Safari 26.5
48
+ * (plain `webSocketUrl:true` returns a boolean placeholder). */
49
+ experimentalWebSocketUrl?: boolean;
50
+ }
51
+ export declare class SafariWebDriverClient {
52
+ private readonly baseUrl;
53
+ private readonly fetchImpl;
54
+ constructor(opts: {
55
+ baseUrl: string;
56
+ fetchImpl?: FetchLike;
57
+ });
58
+ /** `GET /status` — readiness probe (used by the launch poll). Never throws on a
59
+ * protocol error; returns `{ready:false}` so the poll can retry. */
60
+ status(): Promise<{
61
+ ready: boolean;
62
+ message: string;
63
+ }>;
64
+ /** `POST /session` — create a session. On Safari, passing
65
+ * `{webSocketUrl:true, experimentalWebSocketUrl:true}` negotiates a real BiDi
66
+ * socket; the granted `webSocketUrl` is a `ws://` STRING when (and only when)
67
+ * the experimental cap took (reference 06). A boolean/absent value => no BiDi. */
68
+ newSession(caps?: SessionCapabilities): Promise<NewSessionResult>;
69
+ deleteSession(sessionId: string): Promise<void>;
70
+ navigate(sessionId: string, url: string): Promise<void>;
71
+ /** Current document URL — the Classic substitute for `page.url()` (which the
72
+ * Safari session cannot provide, having no Playwright Page). */
73
+ currentUrl(sessionId: string): Promise<string>;
74
+ /** Full-page screenshot as base64 PNG (Classic — BiDi captureScreenshot is
75
+ * absent on Safari 26.5). */
76
+ screenshot(sessionId: string): Promise<string>;
77
+ /** Find the first matching element; null when none (no-such-element is a normal
78
+ * "not found", not a protocol failure, so it is mapped to null). */
79
+ findElement(sessionId: string, using: string, value: string): Promise<string | null>;
80
+ findElements(sessionId: string, using: string, value: string): Promise<string[]>;
81
+ elementClick(sessionId: string, elementId: string): Promise<void>;
82
+ elementClear(sessionId: string, elementId: string): Promise<void>;
83
+ /** sendKeys. The W3C body carries both `text` and the legacy `value` array;
84
+ * safaridriver accepts `text`. */
85
+ elementValue(sessionId: string, elementId: string, text: string): Promise<void>;
86
+ elementText(sessionId: string, elementId: string): Promise<string>;
87
+ /** Get Element Property — the LIVE DOM property (e.g. an input's current
88
+ * `value`), as opposed to the static HTML attribute. Used to read back what a
89
+ * fill landed. Returns null when the property is absent. */
90
+ elementProperty(sessionId: string, elementId: string, name: string): Promise<string | null>;
91
+ getCookies(sessionId: string): Promise<WebDriverCookie[]>;
92
+ addCookie(sessionId: string, cookie: WebDriverCookie): Promise<void>;
93
+ /** `POST /execute/sync` — run page-context JS and return its value. This is the
94
+ * seam the Safari snapshot substrate ships browxai's DOM-walk PAGE_SCRIPT
95
+ * through (spike-confirmed identical to Playwright frame.evaluate —
96
+ * reference 07 §4). `script` is a function BODY; `args` map to `arguments`. */
97
+ executeScript(sessionId: string, script: string, args?: unknown[]): Promise<unknown>;
98
+ /** The single request primitive: POST/GET/DELETE a WebDriver endpoint, unwrap
99
+ * the `{value}` envelope, and turn an error envelope into a structured
100
+ * `WebDriverError`. */
101
+ private send;
102
+ }
@@ -0,0 +1,175 @@
1
+ // SafariWebDriverClient — the WebDriver-Classic HTTP client beneath the
2
+ // SafaridriverHybridAdapter. Classic is the COMPLETE workhorse for
3
+ // real Safari: a live probe against the shipping safaridriver
4
+ // confirmed navigate / screenshot / findElement / element click+value+text /
5
+ // cookies / executeScript all work on the shipping safaridriver, whereas the
6
+ // experimental BiDi layer (SafariBidiClient) is the additive bidirectional half
7
+ // (console + nav events) and is gated behind a vendor cap. So the adapter leans
8
+ // on THIS client for the element/screenshot/cookie/exec surface and treats BiDi
9
+ // as strictly optional.
10
+ //
11
+ // This is pure `fetch` over loopback (safaridriver's REST endpoints), with the
12
+ // HTTP transport injected (`FetchLike`) so the orchestration unit-tests without a
13
+ // real driver — the same IO-seam discipline as adb.ts (AdbRunner/Fetcher). It
14
+ // implements ONLY the endpoints the adapter + the Safari snapshot/action seams
15
+ // actually call (interface segregation), not the whole WebDriver surface.
16
+ /** The W3C element-reference key — the property name a WebDriver server uses to
17
+ * carry an element handle in JSON. safaridriver returns this key (and also the
18
+ * legacy `ELEMENT`); we read either. */
19
+ const ELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf";
20
+ /** A WebDriver protocol error surfaced as a structured throw (never a vague
21
+ * mid-call failure — the doctrine's no-silent-failure rule). `error` is the W3C
22
+ * error code (e.g. `session not created`, `no such element`). */
23
+ export class WebDriverError extends Error {
24
+ code;
25
+ httpStatus;
26
+ constructor(code, message, httpStatus) {
27
+ super(`safari-webdriver: ${code}: ${message}`);
28
+ this.name = "WebDriverError";
29
+ this.code = code;
30
+ this.httpStatus = httpStatus;
31
+ }
32
+ }
33
+ export class SafariWebDriverClient {
34
+ baseUrl;
35
+ fetchImpl;
36
+ constructor(opts) {
37
+ // Trim a trailing slash so path joins are unambiguous.
38
+ this.baseUrl = opts.baseUrl.replace(/\/$/, "");
39
+ // globalThis.fetch is structurally assignable to FetchLike (a looser shape).
40
+ this.fetchImpl = opts.fetchImpl ?? globalThis.fetch;
41
+ }
42
+ /** `GET /status` — readiness probe (used by the launch poll). Never throws on a
43
+ * protocol error; returns `{ready:false}` so the poll can retry. */
44
+ async status() {
45
+ try {
46
+ const value = (await this.send("GET", "/status"));
47
+ return { ready: value?.ready ?? false, message: value?.message ?? "" };
48
+ }
49
+ catch {
50
+ return { ready: false, message: "unreachable" };
51
+ }
52
+ }
53
+ /** `POST /session` — create a session. On Safari, passing
54
+ * `{webSocketUrl:true, experimentalWebSocketUrl:true}` negotiates a real BiDi
55
+ * socket; the granted `webSocketUrl` is a `ws://` STRING when (and only when)
56
+ * the experimental cap took (reference 06). A boolean/absent value => no BiDi. */
57
+ async newSession(caps = {}) {
58
+ const alwaysMatch = { browserName: "safari" };
59
+ if (caps.webSocketUrl)
60
+ alwaysMatch["webSocketUrl"] = true;
61
+ if (caps.experimentalWebSocketUrl)
62
+ alwaysMatch["safari:experimentalWebSocketUrl"] = true;
63
+ const value = (await this.send("POST", "/session", { capabilities: { alwaysMatch } }));
64
+ const granted = value.capabilities ?? {};
65
+ const ws = granted["webSocketUrl"];
66
+ return {
67
+ sessionId: value.sessionId,
68
+ capabilities: granted,
69
+ // ONLY a string ws:// URL counts as a live BiDi socket; the boolean
70
+ // placeholder (experimental cap off) means Classic-only.
71
+ webSocketUrl: typeof ws === "string" ? ws : undefined,
72
+ };
73
+ }
74
+ async deleteSession(sessionId) {
75
+ await this.send("DELETE", `/session/${sessionId}`);
76
+ }
77
+ async navigate(sessionId, url) {
78
+ await this.send("POST", `/session/${sessionId}/url`, { url });
79
+ }
80
+ /** Current document URL — the Classic substitute for `page.url()` (which the
81
+ * Safari session cannot provide, having no Playwright Page). */
82
+ async currentUrl(sessionId) {
83
+ return (await this.send("GET", `/session/${sessionId}/url`));
84
+ }
85
+ /** Full-page screenshot as base64 PNG (Classic — BiDi captureScreenshot is
86
+ * absent on Safari 26.5). */
87
+ async screenshot(sessionId) {
88
+ return (await this.send("GET", `/session/${sessionId}/screenshot`));
89
+ }
90
+ /** Find the first matching element; null when none (no-such-element is a normal
91
+ * "not found", not a protocol failure, so it is mapped to null). */
92
+ async findElement(sessionId, using, value) {
93
+ try {
94
+ const v = (await this.send("POST", `/session/${sessionId}/element`, {
95
+ using,
96
+ value,
97
+ }));
98
+ return v[ELEMENT_KEY] ?? v["ELEMENT"] ?? null;
99
+ }
100
+ catch (err) {
101
+ if (err instanceof WebDriverError && err.code === "no such element")
102
+ return null;
103
+ throw err;
104
+ }
105
+ }
106
+ async findElements(sessionId, using, value) {
107
+ const v = (await this.send("POST", `/session/${sessionId}/elements`, {
108
+ using,
109
+ value,
110
+ }));
111
+ return v.map((e) => e[ELEMENT_KEY] ?? e["ELEMENT"]).filter((id) => Boolean(id));
112
+ }
113
+ // Click the element via execute/sync rather than the W3C `/element/{id}/click`
114
+ // endpoint: on the shipping safaridriver the protocol Element Click does not
115
+ // reliably dispatch the page's `click` handlers (a button's `onclick` never
116
+ // fires), whereas a script-driven `arguments[0].click()` does — the same
117
+ // execute/sync seam the snapshot substrate is spike-confirmed on (reference 07).
118
+ // The resolved element id is passed as a web-element reference so the exact
119
+ // element this client found is the one clicked.
120
+ async elementClick(sessionId, elementId) {
121
+ await this.executeScript(sessionId, "arguments[0].click();", [{ [ELEMENT_KEY]: elementId }]);
122
+ }
123
+ async elementClear(sessionId, elementId) {
124
+ await this.send("POST", `/session/${sessionId}/element/${elementId}/clear`, {});
125
+ }
126
+ /** sendKeys. The W3C body carries both `text` and the legacy `value` array;
127
+ * safaridriver accepts `text`. */
128
+ async elementValue(sessionId, elementId, text) {
129
+ await this.send("POST", `/session/${sessionId}/element/${elementId}/value`, {
130
+ text,
131
+ value: text.split(""),
132
+ });
133
+ }
134
+ async elementText(sessionId, elementId) {
135
+ return (await this.send("GET", `/session/${sessionId}/element/${elementId}/text`));
136
+ }
137
+ /** Get Element Property — the LIVE DOM property (e.g. an input's current
138
+ * `value`), as opposed to the static HTML attribute. Used to read back what a
139
+ * fill landed. Returns null when the property is absent. */
140
+ async elementProperty(sessionId, elementId, name) {
141
+ const v = await this.send("GET", `/session/${sessionId}/element/${elementId}/property/${name}`);
142
+ return typeof v === "string" ? v : null;
143
+ }
144
+ async getCookies(sessionId) {
145
+ return (await this.send("GET", `/session/${sessionId}/cookie`));
146
+ }
147
+ async addCookie(sessionId, cookie) {
148
+ await this.send("POST", `/session/${sessionId}/cookie`, { cookie });
149
+ }
150
+ /** `POST /execute/sync` — run page-context JS and return its value. This is the
151
+ * seam the Safari snapshot substrate ships browxai's DOM-walk PAGE_SCRIPT
152
+ * through (spike-confirmed identical to Playwright frame.evaluate —
153
+ * reference 07 §4). `script` is a function BODY; `args` map to `arguments`. */
154
+ async executeScript(sessionId, script, args = []) {
155
+ return await this.send("POST", `/session/${sessionId}/execute/sync`, { script, args });
156
+ }
157
+ /** The single request primitive: POST/GET/DELETE a WebDriver endpoint, unwrap
158
+ * the `{value}` envelope, and turn an error envelope into a structured
159
+ * `WebDriverError`. */
160
+ async send(method, path, body) {
161
+ const res = await this.fetchImpl(`${this.baseUrl}${path}`, {
162
+ method,
163
+ headers: { "Content-Type": "application/json" },
164
+ ...(body !== undefined ? { body: JSON.stringify(body) } : {}),
165
+ });
166
+ const payload = (await res.json());
167
+ const value = payload?.value;
168
+ // WebDriver signals errors with HTTP 4xx/5xx AND a `value.error` code.
169
+ if (!res.ok || (value && typeof value === "object" && "error" in value)) {
170
+ const v = (value ?? {});
171
+ throw new WebDriverError(v.error ?? `http ${res.status}`, v.message ?? "", res.status);
172
+ }
173
+ return value;
174
+ }
175
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,52 @@
1
+ // Safari engine registration (RFC 0004 D1 + D5). Safari is the first
2
+ // non-Playwright, no-Page engine — real Safari.app over safaridriver. Its
3
+ // `EngineEntry` is what closes the Safari LSP leak: the engine declares no `page`
4
+ // sub-interface (capabilities.ts), supplies the Safari `SubstrateBundle` (every
5
+ // selector reads the Safari-native handle, never a Page/CDP), and its `postWire`
6
+ // attaches ONLY the BiDi console bridge — omitting every Playwright-only step. So
7
+ // the 17 scattered `sess.engine !== "safari"` guards have no reason to exist, and
8
+ // the `page()`-throws fallback in safari-session.ts is never reached on the
9
+ // relocated path.
10
+ import { log } from "../../util/logging.js";
11
+ import { registerEngine } from "../registry.js";
12
+ import { capabilitiesFor } from "../capabilities.js";
13
+ import { SafaridriverHybridAdapter } from "./safaridriver-hybrid.js";
14
+ import { buildSafariSession } from "../../session/safari-session.js";
15
+ import { safariSubstrateBundle } from "../../page/substrate-bundle-safari.js";
16
+ import { safariPostWire } from "../../session/safari-post-wire.js";
17
+ async function makeSafariAdapter(opts) {
18
+ const mode = opts.launchMode ?? "managed";
19
+ if (mode === "incognito") {
20
+ // safari runs ISOLATED automation windows via the default managed session
21
+ // (safaridriver already isolates each session). Incognito (a separate
22
+ // in-browser context) is a Playwright concept safaridriver has no equivalent
23
+ // for, so refuse rather than silently launch a managed window.
24
+ throw new Error("safari-incognito-not-supported: the safari engine runs isolated automation windows via the " +
25
+ "default managed session (safaridriver isolates each session by construction). Incognito (a " +
26
+ "separate browser context) is a Playwright concept safaridriver has no equivalent for. Open a " +
27
+ "managed session instead.");
28
+ }
29
+ if (mode === "byob") {
30
+ // safari cannot attach to a live browser at all — safaridriver hard-isolates
31
+ // each session into a clean ephemeral automation window. Surface the adapter's
32
+ // structured `safari-attach-not-supported`.
33
+ await new SafaridriverHybridAdapter().attach();
34
+ throw new Error("unreachable: safari attach always refuses");
35
+ }
36
+ // managed IS the safari model (no headless Safari, no separate-context
37
+ // incognito) — an isolated automation window over safaridriver, whose page()
38
+ // throws; Safari-capable tools route through session.safari().
39
+ const handle = await new SafaridriverHybridAdapter().launchManaged();
40
+ log.info("session.managed: safari session ready", {
41
+ sessionId: handle.sessionId,
42
+ hasBidi: handle.hasBidi,
43
+ });
44
+ return buildSafariSession(handle);
45
+ }
46
+ registerEngine({
47
+ kind: "safari",
48
+ capabilities: capabilitiesFor("safari"),
49
+ makeAdapter: makeSafariAdapter,
50
+ makeSubstrates: (deps) => safariSubstrateBundle(deps),
51
+ postWire: (entry, deps) => safariPostWire(entry, deps),
52
+ });