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,304 @@
1
+ // Trace-export: lower a session's recorded action trace into a runnable
2
+ // `@playwright/test` spec file. Adjacent to `export_session_report` (which
3
+ // bundles QA evidence) and to `end_recording` (which emits the site-docs
4
+ // flow-file YAML); this one emits TypeScript a code-as-action consumer can
5
+ // run as the seed for a skill-compilation loop.
6
+ //
7
+ // Lowering principles:
8
+ // - Each recorded step lowers to ONE Playwright call. We deliberately do not
9
+ // re-synthesise the wider browxai action envelope (ActionResult /
10
+ // snapshotDelta / network slice) — a `.spec.ts` is a single deterministic
11
+ // walk, not an observed session.
12
+ // - Locator strings reuse the recorded `selectorHint` (the BEST stable
13
+ // selector resolved at action time). Mirrors `parseSelectorHint` in
14
+ // `./locator.ts` so an exported call resolves the same way browxai itself
15
+ // would: attribute → `page.locator('[attr="..."]')`, role+name → `page
16
+ // .getByRole('role', { name: '...' })`, role-only → `page.getByRole('role')`,
17
+ // anything else → `page.locator('<raw>')`.
18
+ // - Selector stability is surfaced in-source. A recorded `stability: "low"`
19
+ // (or any step where the recorder had to fall back to tier-5 / role-only)
20
+ // gets a `// TODO: fragile selector — review before relying on this in
21
+ // CI` comment above the call, so the consumer SEES the brittle spots
22
+ // rather than having to cross-reference the YAML.
23
+ // - Coords-mode actions are not recorded by the action window (see
24
+ // actions.ts: NON_TARGETED_ACTIONS / hasReplayableTarget), so the export
25
+ // never has to lower a non-replayable target — by construction.
26
+ //
27
+ // Output shape: a single `.spec.ts` source string. The caller can return it
28
+ // inline AND/OR write it to a workspace-rooted path (same posture as
29
+ // `dump_storage_state` — workspace-rooted, escape-rejected).
30
+ /** Lower a recorded trace to a Playwright spec source string. Pure; the
31
+ * caller decides whether to write it to disk. */
32
+ export function lowerTraceToSpec(flowName, steps) {
33
+ const body = [];
34
+ let handled = 0;
35
+ let unhandled = 0;
36
+ let fragile = 0;
37
+ if (steps.length === 0) {
38
+ body.push(" // No steps recorded. Run actions while a recording is active,");
39
+ body.push(" // then re-export to populate this spec.");
40
+ }
41
+ for (const step of steps) {
42
+ const lowered = lowerStep(step);
43
+ if (lowered.fragile) {
44
+ fragile += 1;
45
+ body.push(" // TODO: fragile selector — review before relying on this in CI " +
46
+ "(recorded stability: " +
47
+ (step.stability ?? "unknown") +
48
+ ").");
49
+ }
50
+ for (const line of lowered.lines) {
51
+ body.push(" " + line);
52
+ }
53
+ if (lowered.handled)
54
+ handled += 1;
55
+ else
56
+ unhandled += 1;
57
+ }
58
+ const source = renderSpec(flowName, body);
59
+ return {
60
+ source,
61
+ stats: { steps: steps.length, handled, unhandled, fragile },
62
+ };
63
+ }
64
+ /** Pure step lowering. Exported for the unit tests. */
65
+ /** Navigation/history actions need no target. Returns null for non-nav types. */
66
+ function lowerNavigation(a) {
67
+ switch (a.type) {
68
+ case "navigate":
69
+ return handledLines([`await page.goto(${jsString(a.url ?? "")});`]);
70
+ case "goBack":
71
+ return handledLines(["await page.goBack();"]);
72
+ case "goForward":
73
+ return handledLines(["await page.goForward();"]);
74
+ default:
75
+ return null;
76
+ }
77
+ }
78
+ export function lowerStep(step) {
79
+ const a = step.action;
80
+ const nav = lowerNavigation(a);
81
+ if (nav)
82
+ return nav;
83
+ switch (a.type) {
84
+ case "click":
85
+ return targeted(step, (loc) => [`await ${loc}.click();`]);
86
+ case "fill":
87
+ return targeted(step, (loc) => [`await ${loc}.fill(${jsString(a.value ?? "")});`]);
88
+ case "hover":
89
+ return targeted(step, (loc) => [`await ${loc}.hover();`]);
90
+ case "select":
91
+ return lowerSelect(step, a.value ?? "");
92
+ case "press":
93
+ return lowerPress(step, a.value ?? "");
94
+ case "waitFor":
95
+ return lowerWaitFor(step, a.value ?? "");
96
+ case "chooseOption":
97
+ return lowerChooseOption(step, a.value ?? "");
98
+ default:
99
+ // Unknown action type — emit a TODO placeholder so the spec still parses,
100
+ // and bump the `unhandled` counter so the caller sees the gap.
101
+ return {
102
+ lines: [
103
+ `// TODO: unhandled action type "${a.type}" — no Playwright lowering wired. ` +
104
+ `Original descriptor: ${JSON.stringify(a)}.`,
105
+ ],
106
+ fragile: false,
107
+ handled: false,
108
+ };
109
+ }
110
+ }
111
+ /** `select` records values as a comma-joined string; lower to `selectOption([...])`
112
+ * (the array form is unambiguous and accepts a single value too). */
113
+ function lowerSelect(step, value) {
114
+ const values = value
115
+ .split(",")
116
+ .map((v) => v.trim())
117
+ .filter((v) => v.length > 0);
118
+ const literal = "[" + values.map(jsString).join(", ") + "]";
119
+ return targeted(step, (loc) => [`await ${loc}.selectOption(${literal});`]);
120
+ }
121
+ /** `press` may target an element (`locator.press`) or the page (`page.keyboard.press`). */
122
+ function lowerPress(step, key) {
123
+ if (step.selectorHint) {
124
+ return targeted(step, (loc) => [`await ${loc}.press(${jsString(key)});`]);
125
+ }
126
+ return handledLines([`await page.keyboard.press(${jsString(key)});`]);
127
+ }
128
+ /** `waitFor` lowers to a page-level visible-text wait (`text:<...>`) or an
129
+ * element-visible wait. */
130
+ function lowerWaitFor(step, value) {
131
+ if (value.startsWith("text:")) {
132
+ const text = value.slice("text:".length);
133
+ return handledLines([
134
+ `await page.getByText(${jsString(text)}).first().waitFor({ state: "visible" });`,
135
+ ]);
136
+ }
137
+ return targeted(step, (loc) => [`await ${loc}.waitFor({ state: "visible" });`]);
138
+ }
139
+ /** `choose_option` is a compound (open-trigger → click-option) emitted as two
140
+ * clicks with a review-the-wait comment. */
141
+ function lowerChooseOption(step, optionText) {
142
+ const loc = locatorExprFor(step);
143
+ return {
144
+ lines: [
145
+ "// choose_option lowered as trigger-click + option-click; review the wait between them.",
146
+ `await ${loc}.click();`,
147
+ `await page.getByRole("option", { name: ${jsString(optionText)} }).first().click();`,
148
+ ],
149
+ fragile: isFragile(step),
150
+ handled: true,
151
+ };
152
+ }
153
+ function targeted(step, build) {
154
+ if (!step.selectorHint) {
155
+ // The recorder only stores a step without a selectorHint for
156
+ // navigation-class actions, which are handled above. If we land here
157
+ // it's a target-shaped action whose target the recorder couldn't
158
+ // resolve (extremely unusual — guard anyway).
159
+ return {
160
+ lines: [
161
+ `// TODO: target action "${step.action.type}" has no recorded selectorHint — ` +
162
+ `cannot lower to a Playwright locator; replace this line manually.`,
163
+ ],
164
+ fragile: true,
165
+ handled: false,
166
+ };
167
+ }
168
+ const loc = locatorExprFor(step);
169
+ return { lines: build(loc), fragile: isFragile(step), handled: true };
170
+ }
171
+ function handledLines(lines) {
172
+ return { lines, fragile: false, handled: true };
173
+ }
174
+ function isFragile(step) {
175
+ const s = step.stability;
176
+ return s === "low";
177
+ }
178
+ /** Lower a recorded `selectorHint` into a Playwright locator expression
179
+ * rooted at the `page` identifier. Mirrors `parseSelectorHint` in
180
+ * `./locator.ts`. */
181
+ export function locatorExprFor(step) {
182
+ const hint = step.selectorHint ?? "";
183
+ return locatorExprFromHint(hint);
184
+ }
185
+ /** Pure; exported for unit tests. */
186
+ export function locatorExprFromHint(hint) {
187
+ const s = hint.trim();
188
+ // Attribute form — `[data-testid="..."]` and the wider attribute family
189
+ // find() emits (`data-cy`, `data-test`, etc.). Pass the whole hint through
190
+ // as a CSS selector; Playwright's `.locator()` handles it natively.
191
+ const attrMatch = s.match(/^\[([a-zA-Z][a-zA-Z0-9-]*)=("([^"]*)"|'([^']*)')\]$/);
192
+ if (attrMatch) {
193
+ return `page.locator(${jsString(s)})`;
194
+ }
195
+ // Role + name form — `role=button[name="Submit"]`. Lower to `getByRole`
196
+ // with the unescaped name; same parse used by `parseSelectorHint`.
197
+ const roleNameMatch = s.match(/^role=([a-zA-Z][a-zA-Z0-9-]*)\[name=("((?:\\.|[^"\\])*)"|'((?:\\.|[^'\\])*)')\]$/);
198
+ if (roleNameMatch) {
199
+ const role = roleNameMatch[1];
200
+ const rawName = roleNameMatch[3] ?? roleNameMatch[4] ?? "";
201
+ const name = rawName.replace(/\\"/g, '"').replace(/\\'/g, "'").replace(/\\\\/g, "\\");
202
+ return `page.getByRole(${jsString(role)}, { name: ${jsString(name)} })`;
203
+ }
204
+ // Role-only — `role=button`. Tier-5 / low-stability shape.
205
+ const roleOnlyMatch = s.match(/^role=([a-zA-Z][a-zA-Z0-9-]*)$/);
206
+ if (roleOnlyMatch) {
207
+ return `page.getByRole(${jsString(roleOnlyMatch[1])})`;
208
+ }
209
+ // Fallthrough — raw locator string.
210
+ return `page.locator(${jsString(s)})`;
211
+ }
212
+ /** TypeScript double-quoted string literal. Escapes the JSON-unsafe subset
213
+ * plus `$` and backticks (not needed for double quotes, but cheap to be
214
+ * conservative — the output round-trips through `JSON.stringify` which
215
+ * already handles `"` and `\`). */
216
+ function jsString(value) {
217
+ return JSON.stringify(value);
218
+ }
219
+ /** Render the final `.spec.ts` source. Body lines are inserted verbatim
220
+ * (already indented by the caller). */
221
+ function renderSpec(flowName, bodyLines) {
222
+ const safeName = flowName.replace(/[\r\n]/g, " ").replace(/`/g, "\\`");
223
+ const lines = [
224
+ `import { test, expect } from "@playwright/test";`,
225
+ ``,
226
+ `// Generated by browxai \`export_playwright_script\`. Each step below was`,
227
+ `// lowered from a recorded browxai action; selectors come from the`,
228
+ `// recorder's selectorHint at the time of the call. \`// TODO: fragile`,
229
+ `// selector\` comments flag tier-5 / role-only fallbacks — review before`,
230
+ `// relying on this spec in CI.`,
231
+ `//`,
232
+ `// \`expect\` is imported so adding assertions does not require editing`,
233
+ `// the import line; the generated body does not assert by itself.`,
234
+ `void expect;`,
235
+ ``,
236
+ `test(${jsString(safeName)}, async ({ page }) => {`,
237
+ ...bodyLines,
238
+ `});`,
239
+ ``,
240
+ ];
241
+ return lines.join("\n");
242
+ }
243
+ /** Skip a comment or string token starting at `i`; returns the index just past
244
+ * it, or `i` unchanged when `i` doesn't start a comment/string. */
245
+ function skipCommentOrString(source, i) {
246
+ const c = source[i];
247
+ if (c === "/" && source[i + 1] === "/") {
248
+ const nl = source.indexOf("\n", i);
249
+ return nl === -1 ? source.length : nl + 1;
250
+ }
251
+ if (c === "/" && source[i + 1] === "*") {
252
+ const end = source.indexOf("*/", i + 2);
253
+ return end === -1 ? source.length : end + 2;
254
+ }
255
+ if (c === '"' || c === "'" || c === "`") {
256
+ let j = i + 1;
257
+ while (j < source.length && source[j] !== c)
258
+ j += source[j] === "\\" ? 2 : 1;
259
+ return j + 1;
260
+ }
261
+ return i;
262
+ }
263
+ const OPEN_DELIMS = { "(": "paren", "{": "brace", "[": "bracket" };
264
+ const CLOSE_DELIMS = { ")": "paren", "}": "brace", "]": "bracket" };
265
+ /** Apply one character's delimiter effect to `depth`. */
266
+ function applyDelimiter(c, depth) {
267
+ const open = OPEN_DELIMS[c];
268
+ if (open)
269
+ depth[open] += 1;
270
+ const close = CLOSE_DELIMS[c];
271
+ if (close)
272
+ depth[close] -= 1;
273
+ }
274
+ export function parseCheck(source) {
275
+ if (!source.startsWith('import { test, expect } from "@playwright/test";')) {
276
+ return { ok: false, reason: "missing @playwright/test import header" };
277
+ }
278
+ if (!/\ntest\(/.test(source)) {
279
+ return { ok: false, reason: "missing test(...) shell" };
280
+ }
281
+ // matched-delimiter pass — strings + comments are skipped so a `{` inside a
282
+ // string literal isn't a false positive.
283
+ let i = 0;
284
+ const depth = { paren: 0, brace: 0, bracket: 0 };
285
+ while (i < source.length) {
286
+ const skipped = skipCommentOrString(source, i);
287
+ if (skipped !== i) {
288
+ i = skipped;
289
+ continue;
290
+ }
291
+ applyDelimiter(source[i], depth);
292
+ if (depth.paren < 0 || depth.brace < 0 || depth.bracket < 0) {
293
+ return { ok: false, reason: `unbalanced delimiter at offset ${i}` };
294
+ }
295
+ i += 1;
296
+ }
297
+ if (depth.paren !== 0 || depth.brace !== 0 || depth.bracket !== 0) {
298
+ return {
299
+ ok: false,
300
+ reason: `unbalanced delimiters at EOF (paren=${depth.paren}, brace=${depth.brace}, bracket=${depth.bracket})`,
301
+ };
302
+ }
303
+ return { ok: true };
304
+ }
@@ -0,0 +1,22 @@
1
+ import type { Locator, Page } from "playwright-core";
2
+ import { type A11yNode } from "./a11y.js";
3
+ import type { RefRegistry } from "./refs.js";
4
+ import type { ExtractSchema, ExtractEvidence } from "./extract-types.js";
5
+ /** Pure-ish resolution entry point. Exported for unit testing — `extract()`
6
+ * composes the snapshot and resolves scope, then delegates here. */
7
+ export declare function resolveAgainstTree(args: {
8
+ schema: ExtractSchema;
9
+ page: Page;
10
+ scopeTree: A11yNode;
11
+ scopeLocator?: Locator;
12
+ }): Promise<{
13
+ data: unknown;
14
+ evidence: ExtractEvidence;
15
+ requiredMisses: string[];
16
+ }>;
17
+ export declare function scanTreeForBestMatch(tree: A11yNode, query: string): A11yNode | undefined;
18
+ export declare function coerceLeaf(raw: unknown, type: ExtractSchema["type"]): unknown;
19
+ /** Best-effort Locator for a ref — mirrors the lighter case in locator.ts
20
+ * without hard-coupling here; we don't need full provenance routing for
21
+ * extraction (the tree-walk does most of the work). */
22
+ export declare function locatorForRef(page: Page, refs: RefRegistry, ref: string): Locator | undefined;
@@ -0,0 +1,341 @@
1
+ // Deterministic extraction resolution engine — resolves an `ExtractSchema`
2
+ // against a captured a11y subtree (+ optional backing Locators). Split out of
3
+ // extract.ts to keep that file under the size budget; behavior-identical, and
4
+ // the public entry points are re-exported through `./extract.js`.
5
+ import { walk } from "./a11y.js";
6
+ import { IMPLICIT_QUERY } from "./extract-types.js";
7
+ import { warnExplicitNlQueryRetired } from "./extract-warnings.js";
8
+ import { collectUnknownHintKeys } from "./extract-schema.js";
9
+ /** Pure-ish resolution entry point. Exported for unit testing — `extract()`
10
+ * composes the snapshot and resolves scope, then delegates here. */
11
+ export async function resolveAgainstTree(args) {
12
+ const evidence = { refsUsed: [], selectorsUsed: [], partialMisses: [] };
13
+ const requiredMisses = [];
14
+ // Surface unknown `x-browx-source` keys up-front so the agent sees the
15
+ // typo before deciding whether the silently-wrong leaf value is "good
16
+ // enough". Pure additive diagnostic — does not change `ok` outcome.
17
+ collectUnknownHintKeys(args.schema, "", evidence.partialMisses);
18
+ const data = await resolveSchema({
19
+ schema: args.schema,
20
+ path: "",
21
+ page: args.page,
22
+ scopeTree: args.scopeTree,
23
+ scopeLocator: args.scopeLocator,
24
+ evidence,
25
+ requiredMisses,
26
+ });
27
+ return { data, evidence, requiredMisses };
28
+ }
29
+ async function resolveSchema(ctx) {
30
+ const { schema } = ctx;
31
+ switch (schema.type) {
32
+ case "object":
33
+ return resolveObject(ctx);
34
+ case "array":
35
+ return resolveArray(ctx);
36
+ case "string":
37
+ case "number":
38
+ case "boolean":
39
+ return resolveLeaf(ctx);
40
+ }
41
+ }
42
+ async function resolveObject(ctx) {
43
+ const out = {};
44
+ const props = ctx.schema.properties ?? {};
45
+ for (const [name, subSchema] of Object.entries(props)) {
46
+ const subPath = ctx.path ? `${ctx.path}.${name}` : name;
47
+ // implicit query = the property name; merged with explicit hint if any.
48
+ const childSchema = { ...subSchema };
49
+ if (!childSchema["x-browx-source"]?.query &&
50
+ !childSchema["x-browx-source"]?.selector &&
51
+ !childSchema["x-browx-source"]?.collection) {
52
+ const hint = { ...(childSchema["x-browx-source"] ?? {}), query: name };
53
+ // Mark the implicit-lowering case so resolveLeaf knows this query
54
+ // came from the property name (not a user-authored prose query) and
55
+ // skips the RETIRED-query warning. The marker is a module-private
56
+ // Symbol — won't leak into serialised schemas.
57
+ hint[IMPLICIT_QUERY] = true;
58
+ childSchema["x-browx-source"] = hint;
59
+ }
60
+ const value = await resolveSchema({
61
+ ...ctx,
62
+ schema: childSchema,
63
+ path: subPath,
64
+ });
65
+ if (value !== MISS) {
66
+ out[name] = value;
67
+ }
68
+ else if (subSchema.default !== undefined) {
69
+ out[name] = subSchema.default;
70
+ }
71
+ }
72
+ return out;
73
+ }
74
+ const MISS = Symbol.for("browxai.extract.miss");
75
+ async function resolveArray(ctx) {
76
+ const hint = ctx.schema["x-browx-source"];
77
+ if (!hint?.collection) {
78
+ ctx.evidence.partialMisses.push(`${ctx.path}: array needs \`x-browx-source.collection\` ` +
79
+ `(a CSS selector or NL query for the row container; ` +
80
+ `each match becomes a per-row scope for \`items\`)`);
81
+ if (ctx.schema.required)
82
+ ctx.requiredMisses.push(ctx.path);
83
+ return [];
84
+ }
85
+ const items = ctx.schema.items;
86
+ // Try CSS selector first; if it doesn't match, fall back to a tree-scan
87
+ // by query (find()-style ranking restricted to repeated containers).
88
+ const collectionLocators = await resolveCollection(ctx.page, ctx.scopeLocator, ctx.scopeTree, hint.collection);
89
+ ctx.evidence.selectorsUsed.push(hint.collection);
90
+ if (collectionLocators.length === 0) {
91
+ ctx.evidence.partialMisses.push(`${ctx.path}: collection "${hint.collection}" matched 0 elements`);
92
+ if (ctx.schema.required)
93
+ ctx.requiredMisses.push(ctx.path);
94
+ return [];
95
+ }
96
+ const out = [];
97
+ for (let i = 0; i < collectionLocators.length; i++) {
98
+ const entry = collectionLocators[i];
99
+ const itemValue = await resolveSchema({
100
+ ...ctx,
101
+ schema: items,
102
+ path: `${ctx.path}[${i}]`,
103
+ scopeTree: entry.subTree ?? ctx.scopeTree,
104
+ scopeLocator: entry.loc,
105
+ });
106
+ if (itemValue !== MISS)
107
+ out.push(itemValue);
108
+ }
109
+ return out;
110
+ }
111
+ async function resolveCollection(page, scope, scopeTree, collection) {
112
+ // Try as a CSS selector first.
113
+ const root = scope ?? page;
114
+ try {
115
+ const loc = root.locator(collection);
116
+ const count = await loc.count();
117
+ if (count > 0) {
118
+ const out = [];
119
+ for (let i = 0; i < count; i++)
120
+ out.push({ loc: loc.nth(i) });
121
+ return out;
122
+ }
123
+ }
124
+ catch {
125
+ /* fall through to tree-scan */
126
+ }
127
+ // Fallback: tree-scan for nodes matching the query (containers in repeated
128
+ // structures pick up `context.collection`). No backing Locator — the
129
+ // sub-schema resolves over the subtree alone. Adopters needing
130
+ // attr/prop reads inside a list should use the CSS-selector form.
131
+ const matches = scanTreeForCollection(scopeTree, collection);
132
+ return matches.map((node) => ({ subTree: node }));
133
+ }
134
+ /** Shared a11y-tree search combinator (RFC 0004 P3 / D4). Folds `visit` over
135
+ * every node `walk` yields, threading an accumulator — the one traversal both
136
+ * `scanTreeForCollection` (accumulate all matches) and `scanTreeForBestMatch`
137
+ * (score and keep the best) drive, instead of two hand-rolled `for … of walk`
138
+ * loops. `walk` is already the shared depth-first generator; this names the fold
139
+ * on top of it so a third tree query reuses the same shape. */
140
+ function treeSearch(tree, initial, visit) {
141
+ let acc = initial;
142
+ for (const { node } of walk(tree))
143
+ acc = visit(acc, node);
144
+ return acc;
145
+ }
146
+ function scanTreeForCollection(tree, query) {
147
+ const lower = query.toLowerCase();
148
+ return treeSearch(tree, [], (out, node) => {
149
+ const hay = `${node.role}|${node.name ?? ""}|${node.testId ?? ""}`.toLowerCase();
150
+ if (hay.includes(lower))
151
+ out.push(node);
152
+ return out;
153
+ });
154
+ }
155
+ async function resolveLeaf(ctx) {
156
+ const hint = ctx.schema["x-browx-source"] ?? {};
157
+ // 1. selector path: resolve a Locator directly within scope.
158
+ if (hint.selector) {
159
+ ctx.evidence.selectorsUsed.push(hint.selector);
160
+ const root = ctx.scopeLocator ?? ctx.page;
161
+ let loc;
162
+ try {
163
+ loc = root.locator(hint.selector).first();
164
+ }
165
+ catch {
166
+ return missLeaf(ctx);
167
+ }
168
+ return readLeafFromLocator(ctx, loc, hint);
169
+ }
170
+ // 2. query path: tree-scan within scopeTree.
171
+ const query = hint.query ?? "";
172
+ // Collection-item leaf with no selector/query (e.g. `{text:true}` / `{attr}`):
173
+ // read directly from the per-item Locator that `resolveCollection` scoped onto
174
+ // this item, instead of treating "no selector" as a definitive miss. Without
175
+ // this, an array whose items are `{type:string, x-browx-source:{text:true}}`
176
+ // resolves every element to a partialMiss even though the collection matched.
177
+ if (!query && ctx.scopeLocator) {
178
+ return readLeafFromLocator(ctx, ctx.scopeLocator, hint);
179
+ }
180
+ if (!query)
181
+ return missLeaf(ctx);
182
+ // R-5 (v0.3.3): explicit per-field `query` is RETIRED. The implicit
183
+ // name-as-query lowering still flows through here (marked via
184
+ // IMPLICIT_QUERY) and works fine on testid-rich pages; the prose-style
185
+ // explicit query path is the unreliable one we're deprecating. Emit a
186
+ // one-shot warn + a per-call partialMisses entry that names the field,
187
+ // so the caller / authoring LLM gets a concrete signal — then fall
188
+ // through to the existing tree-scan resolution (graceful deprecation,
189
+ // never hard-break adopters).
190
+ const isImplicit = hint[IMPLICIT_QUERY] === true;
191
+ if (!isImplicit) {
192
+ warnExplicitNlQueryRetired();
193
+ ctx.evidence.partialMisses.push(`${ctx.path}: \`x-browx-source.query\` is RETIRED (v0.3.3) — ` +
194
+ "the NL tree-scan ranker is unreliable for explicit per-field " +
195
+ "queries. Use `x-browx-source.selector` (raw CSS) instead.");
196
+ }
197
+ ctx.evidence.selectorsUsed.push(query);
198
+ const node = scanTreeForBestMatch(ctx.scopeTree, query);
199
+ if (!node)
200
+ return missLeaf(ctx);
201
+ ctx.evidence.refsUsed.push(node.ref);
202
+ // Without a Locator we can only read the a11y-derived text/value. The
203
+ // overwhelming majority of deterministic extract use-cases land here —
204
+ // it's why the tree-walk is the primary path.
205
+ return readLeafFromNode(ctx, node, hint);
206
+ }
207
+ function missLeaf(ctx) {
208
+ ctx.evidence.partialMisses.push(ctx.path);
209
+ if (ctx.schema.required)
210
+ ctx.requiredMisses.push(ctx.path);
211
+ return MISS;
212
+ }
213
+ /** Pick the best node in the tree for a `query` — exact-name wins, else
214
+ * testId-equals, else substring on name/testId. */
215
+ /** Relevance score of one node for a lowercased query — exact name/testId wins,
216
+ * then testId/name substring, role-equals, then per-token substring. */
217
+ function scoreMatch(node, q) {
218
+ const name = (node.name ?? "").toLowerCase();
219
+ const tid = (node.testId ?? "").toLowerCase();
220
+ const role = node.role.toLowerCase();
221
+ let s = 0;
222
+ if (name === q || tid === q)
223
+ s += 100;
224
+ if (tid && tid.includes(q))
225
+ s += 30;
226
+ if (name && name.includes(q))
227
+ s += 20;
228
+ if (role === q)
229
+ s += 5;
230
+ for (const t of q.split(/\s+/).filter((x) => x.length >= 2)) {
231
+ if (tid.includes(t))
232
+ s += 5;
233
+ if (name.includes(t))
234
+ s += 3;
235
+ }
236
+ return s;
237
+ }
238
+ export function scanTreeForBestMatch(tree, query) {
239
+ const q = query.toLowerCase();
240
+ const best = treeSearch(tree, undefined, (acc, node) => {
241
+ const s = scoreMatch(node, q);
242
+ if (s > 0 && (!acc || s > acc.score))
243
+ return { node, score: s };
244
+ return acc;
245
+ });
246
+ return best?.node;
247
+ }
248
+ async function readLeafFromLocator(ctx, loc, hint) {
249
+ try {
250
+ const count = await loc.count();
251
+ if (count === 0)
252
+ return missLeaf(ctx);
253
+ if (hint.attr) {
254
+ const v = await loc.getAttribute(hint.attr);
255
+ if (v === null)
256
+ return missLeaf(ctx);
257
+ return coerceLeaf(v, ctx.schema.type);
258
+ }
259
+ if (hint.prop || hint.value) {
260
+ const propName = hint.prop ?? "value";
261
+ const v = await loc.evaluate((el, p) => el[p], propName);
262
+ if (v === undefined || v === null)
263
+ return missLeaf(ctx);
264
+ return coerceLeaf(v, ctx.schema.type);
265
+ }
266
+ // Default: visible text.
267
+ const text = (await loc.innerText().catch(() => "")).trim();
268
+ if (!text)
269
+ return missLeaf(ctx);
270
+ return coerceLeaf(text, ctx.schema.type);
271
+ }
272
+ catch {
273
+ return missLeaf(ctx);
274
+ }
275
+ }
276
+ function readLeafFromNode(ctx, node, hint) {
277
+ // No live Locator; the tree-only path covers what the snapshot carries.
278
+ if (hint.attr || hint.prop) {
279
+ // Annotation needs a page; record the miss so the caller knows the
280
+ // tree-walk couldn't satisfy it. (The locator path would have, given
281
+ // an explicit selector.)
282
+ return missLeaf(ctx);
283
+ }
284
+ // value-bearing nodes carry CDP-side `value` on the a11y node.
285
+ if (hint.value && node.value !== undefined) {
286
+ return coerceLeaf(node.value, ctx.schema.type);
287
+ }
288
+ const txt = (node.name ?? node.value ?? node.text ?? "").toString().trim();
289
+ if (!txt)
290
+ return missLeaf(ctx);
291
+ return coerceLeaf(txt, ctx.schema.type);
292
+ }
293
+ const TRUTHY_TOKENS = new Set(["true", 1, "1", "yes", "on"]);
294
+ const FALSY_TOKENS = new Set(["false", 0, "0", "no", "off"]);
295
+ function coerceNumber(raw) {
296
+ if (typeof raw === "number")
297
+ return raw;
298
+ const n = Number(String(raw).replace(/[^0-9.\-eE]/g, ""));
299
+ return Number.isFinite(n) ? n : null;
300
+ }
301
+ function coerceBoolean(raw) {
302
+ if (typeof raw === "boolean")
303
+ return raw;
304
+ if (TRUTHY_TOKENS.has(raw))
305
+ return true;
306
+ if (FALSY_TOKENS.has(raw))
307
+ return false;
308
+ return Boolean(raw);
309
+ }
310
+ export function coerceLeaf(raw, type) {
311
+ switch (type) {
312
+ case "string":
313
+ return typeof raw === "string" ? raw : String(raw);
314
+ case "number":
315
+ return coerceNumber(raw);
316
+ case "boolean":
317
+ return coerceBoolean(raw);
318
+ case "object":
319
+ case "array":
320
+ return raw;
321
+ }
322
+ }
323
+ /** Best-effort Locator for a ref — mirrors the lighter case in locator.ts
324
+ * without hard-coupling here; we don't need full provenance routing for
325
+ * extraction (the tree-walk does most of the work). */
326
+ export function locatorForRef(page, refs, ref) {
327
+ const inputs = refs.locatorOf(ref);
328
+ if (!inputs)
329
+ return undefined;
330
+ if (inputs.testId) {
331
+ const attr = inputs.testIdAttr ?? "data-testid";
332
+ return page.locator(`[${attr}=${JSON.stringify(inputs.testId)}]`).first();
333
+ }
334
+ if (inputs.cssPath)
335
+ return page.locator(inputs.cssPath).first();
336
+ if (inputs.name)
337
+ return page
338
+ .getByRole(inputs.role, { name: inputs.name })
339
+ .first();
340
+ return page.getByRole(inputs.role).first();
341
+ }
@@ -0,0 +1,20 @@
1
+ import type { ExtractSchema, ExtractFailure, ExtractResult } from "./extract-types.js";
2
+ export declare function fail(failure: ExtractFailure): ExtractResult;
3
+ export declare function dedupe<T>(arr: T[]): T[];
4
+ export declare function applySchemaRelaxations(schema: ExtractSchema, path: string, notes: string[]): void;
5
+ /** Deep clone the caller-supplied schema before in-place mutation, so we
6
+ * don't surprise an adopter holding a reference. Uses JSON for the
7
+ * round-trip — schemas are plain data (no functions, no Dates). */
8
+ export declare function cloneSchema(schema: unknown): ExtractSchema;
9
+ /** Pure-tree validation. Returns a description of the first invariant
10
+ * violation, or null when the schema is well-formed enough to attempt. */
11
+ export declare function validateSchema(schema: ExtractSchema | undefined, path: string): string | null;
12
+ /** Walk the schema tree and emit one diagnostic per unknown
13
+ * `x-browx-source` key. Pure inspection — does not modify the schema.
14
+ * Adopters who use, e.g., `attribute` instead of `attr` today see the
15
+ * schema "succeed" with silently-wrong leaf values (wrightxai trial-1
16
+ * turn 6: `url` came back as the title text because `attribute:"href"`
17
+ * was silently dropped). The diagnostic surfaces the typo in
18
+ * `evidence.partialMisses` so the agent can self-correct on the next
19
+ * turn without a third "what shape does this take?" probe. */
20
+ export declare function collectUnknownHintKeys(schema: ExtractSchema, path: string, out: string[]): void;