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,453 @@
1
+ // Action primitives. Each wraps a Playwright `Locator` action in the
2
+ // action-window machinery from actionresult.ts so callers always get a
3
+ // structured `ActionResult` instead of a bare "ok".
4
+ import { runInActionWindow, } from "./actionresult.js";
5
+ import { locatorFor, resolveTargetChecked } from "./locator.js";
6
+ import { preProbe, probe, captureHit, captureFocusedRef } from "./actions-probe.js";
7
+ import { windowScrollGeometry, elementScrollGeometry, } from "./actions-scroll.js";
8
+ // aligned with the anti-wedge default (5s). Inner Playwright ops use
9
+ // the per-call `deadlineMs` when provided so a raised `timeoutMs` is honoured
10
+ // by the inner op too (not just the outer race in runInActionWindow).
11
+ const DEFAULT_TIMEOUT_MS = 5_000;
12
+ export async function click(ctx, args) {
13
+ const descriptor = { type: "click", ...targetDescriptor(args.target) };
14
+ const { resolved, warning } = await resolveTargetChecked(ctx.page, ctx.refs, args.target);
15
+ const opts = warning
16
+ ? { ...args, extraWarnings: [...(args.extraWarnings ?? []), warning] }
17
+ : args;
18
+ return runInActionWindow(ctx, descriptor, opts, async () => {
19
+ if (resolved.kind === "coords") {
20
+ const hitBefore = await captureHit(ctx.page, resolved.x, resolved.y);
21
+ const focusBefore = await captureFocusedRef(ctx.page);
22
+ await ctx.page.mouse.click(resolved.x, resolved.y, args.button ? { button: args.button } : undefined);
23
+ const hitAfter = await captureHit(ctx.page, resolved.x, resolved.y);
24
+ const focusAfter = await captureFocusedRef(ctx.page);
25
+ return {
26
+ stillAttached: true,
27
+ hit: {
28
+ before: hitBefore,
29
+ after: hitAfter,
30
+ focusChanged: focusBefore !== focusAfter,
31
+ },
32
+ };
33
+ }
34
+ const pre = await preProbe(resolved.loc);
35
+ // Click strategy: try the standard actionability path first with a
36
+ // SHORTER budget than the outer action deadline, so the auto-recovery
37
+ // pass with `force: true` has headroom. The recovery surfaces a
38
+ // warning so the caller knows the click-only pre-dispatch path was
39
+ // bypassed. Explicit `force:true` from the caller skips the strategy
40
+ // entirely.
41
+ //
42
+ // RCA (adopter, 2026-06-08): the busy-SPA cost is Playwright's
43
+ // mousedown hit-target interceptor — the one pre-dispatch check
44
+ // `click` does that `hover` does not (~500ms hover vs ~4s click on
45
+ // the same provably-actionable static element). Visibility /
46
+ // stability / receives-events / bbox aren't the culprit. `force: true`
47
+ // skips the interceptor.
48
+ const fullTimeout = args.deadlineMs ?? DEFAULT_TIMEOUT_MS;
49
+ if (args.force) {
50
+ await resolved.loc.click({ timeout: fullTimeout, button: args.button, force: true });
51
+ return probe(resolved.loc, args.target, undefined, pre);
52
+ }
53
+ // Reserve ~30% of the deadline for the recovery click; the rest is
54
+ // the actionability budget. Floor at 500ms each so neither path is
55
+ // unreasonably short on tiny custom deadlines.
56
+ const recoveryMs = Math.max(500, Math.floor(fullTimeout * 0.3));
57
+ const actionabilityMs = Math.max(500, fullTimeout - recoveryMs);
58
+ try {
59
+ await resolved.loc.click({ timeout: actionabilityMs, button: args.button });
60
+ }
61
+ catch (e) {
62
+ const msg = e instanceof Error ? e.message : String(e);
63
+ const isActionabilityTimeout = /Timeout|exceeded|element is not stable|element is not visible|element is outside of the viewport|element is not enabled|intercepts pointer events|did not receive/i.test(msg);
64
+ if (!isActionabilityTimeout)
65
+ throw e;
66
+ // Auto-recovery: the actionability check timed out. Try once with
67
+ // `force: true` — common on busy SPAs (perpetual rAF / WS keepalives /
68
+ // re-renders) where the stability check thrashes forever but the
69
+ // element IS clickable. Surface the recovery via an extra warning so
70
+ // the caller doesn't silently get a force-click they didn't opt into.
71
+ await resolved.loc.click({ timeout: recoveryMs, button: args.button, force: true });
72
+ const probed = await probe(resolved.loc, args.target, undefined, pre);
73
+ // Stamp the recovery warning on the probe — `runInActionWindow`
74
+ // splices probe.warnings[] onto the result's top-level warnings.
75
+ probed.warnings = [
76
+ `click: actionability path exceeded ${actionabilityMs}ms — recovered via \`force: true\` (bypasses Playwright's mousedown hit-target interceptor, the click-specific pre-dispatch check that loops/retries on busy SPAs). The page-side click event DID fire (trusted). Pass \`force: true\` explicitly on known-clickable targets to skip the auto-recovery and dispatch immediately. RCA reference: \`hover\` on the same element takes ~500ms vs \`click\` ~4s — the cost is entirely the click-only interceptor, not stability/visibility/receives-events.`,
77
+ ];
78
+ return probed;
79
+ }
80
+ return probe(resolved.loc, args.target, undefined, pre);
81
+ });
82
+ }
83
+ export async function fill(ctx, args) {
84
+ // Secrets materialisation: a `<NAME>`-shaped `value` is swapped for the
85
+ // registered real string AT dispatch. The descriptor records the alias
86
+ // (`<NAME>`), NEVER the real value — so `ActionResult.action.value`, any
87
+ // recorder appendage, and the post-probe's `valueRequested` echo the
88
+ // alias. Plain strings pass through unchanged.
89
+ const mat = materialiseValue(ctx, args.value);
90
+ if (!mat.ok)
91
+ return failedFill(args, mat.error);
92
+ const descriptorValue = mat.alias ? `<${mat.alias}>` : args.value;
93
+ const descriptor = {
94
+ type: "fill",
95
+ value: descriptorValue,
96
+ ...refOrSelector(args.target),
97
+ };
98
+ return runInActionWindow(ctx, descriptor, args, async () => {
99
+ const loc = locatorFor(ctx.page, ctx.refs, args.target);
100
+ const pre = await preProbe(loc);
101
+ await loc.fill(mat.value, { timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
102
+ // pass the alias as `valueRequested` so `value === valueRequested`
103
+ // comparison still works without the real secret reaching the probe.
104
+ const probed = await probe(loc, args.target, descriptorValue, pre);
105
+ // Defence-in-depth: the field's DOM value reflects what we typed, so
106
+ // `probed.value` carries the secret. Mask before returning — the
107
+ // action-window will surface it on the ActionResult otherwise.
108
+ return maskProbe(probed, ctx);
109
+ });
110
+ }
111
+ export async function navigate(ctx, args) {
112
+ const descriptor = { type: "navigate", url: args.url };
113
+ return runInActionWindow(ctx, descriptor, args, async () => {
114
+ await ctx.page.goto(args.url, {
115
+ waitUntil: "domcontentloaded",
116
+ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS,
117
+ });
118
+ });
119
+ }
120
+ export async function press(ctx, args) {
121
+ // Secrets materialisation on `key` — mirrors `fill`. The realistic case is
122
+ // a one-shot OTP/passphrase that the agent needs to "press" into a focused
123
+ // field. Playwright's `press` accepts modifier+key strings ("Shift+A") and
124
+ // single chars; the `<NAME>` shape doesn't collide with either, so the
125
+ // alias detection in the registry is unambiguous.
126
+ const mat = materialiseValue(ctx, args.key);
127
+ if (!mat.ok)
128
+ return failedPress(args, mat.error);
129
+ const descriptorValue = mat.alias ? `<${mat.alias}>` : args.key;
130
+ const descriptor = {
131
+ type: "press",
132
+ value: descriptorValue,
133
+ ...(args.target ? refOrSelector(args.target) : {}),
134
+ };
135
+ return runInActionWindow(ctx, descriptor, args, async () => {
136
+ if (args.target) {
137
+ const loc = locatorFor(ctx.page, ctx.refs, args.target);
138
+ const pre = await preProbe(loc);
139
+ await loc.press(mat.value, { timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
140
+ const probed = await probe(loc, args.target, undefined, pre);
141
+ return maskProbe(probed, ctx);
142
+ }
143
+ else {
144
+ await ctx.page.keyboard.press(mat.value);
145
+ }
146
+ });
147
+ }
148
+ export async function hover(ctx, args) {
149
+ const descriptor = { type: "hover", ...targetDescriptor(args.target) };
150
+ const { resolved, warning } = await resolveTargetChecked(ctx.page, ctx.refs, args.target);
151
+ const opts = warning
152
+ ? { ...args, extraWarnings: [...(args.extraWarnings ?? []), warning] }
153
+ : args;
154
+ return runInActionWindow(ctx, descriptor, opts, async () => {
155
+ if (resolved.kind === "coords") {
156
+ const hitBefore = await captureHit(ctx.page, resolved.x, resolved.y);
157
+ await ctx.page.mouse.move(resolved.x, resolved.y);
158
+ const hitAfter = await captureHit(ctx.page, resolved.x, resolved.y);
159
+ return { stillAttached: true, hit: { before: hitBefore, after: hitAfter } };
160
+ }
161
+ const pre = await preProbe(resolved.loc);
162
+ await resolved.loc.hover({ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
163
+ return probe(resolved.loc, args.target, undefined, pre);
164
+ });
165
+ }
166
+ export async function select(ctx, args) {
167
+ const descriptor = {
168
+ type: "select",
169
+ value: args.values.join(", "),
170
+ ...refOrSelector(args.target),
171
+ };
172
+ return runInActionWindow(ctx, descriptor, args, async () => {
173
+ const loc = locatorFor(ctx.page, ctx.refs, args.target);
174
+ const pre = await preProbe(loc);
175
+ await loc.selectOption(args.values, { timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
176
+ return probe(loc, args.target, undefined, pre);
177
+ });
178
+ }
179
+ export async function waitFor(ctx, args) {
180
+ const timeout = args.timeoutMs ?? DEFAULT_TIMEOUT_MS;
181
+ if (args.text !== undefined) {
182
+ const descriptor = { type: "waitFor", value: `text:${args.text}` };
183
+ const wanted = args.text;
184
+ return runInActionWindow(ctx, descriptor, args, async () => {
185
+ // true substring match (case-insensitive, whitespace-trimmed)
186
+ // — `getByText(string)` is substring by default. The earlier
187
+ // `locator('text="…"')` form lowered to Playwright's quoted/exact-ish
188
+ // engine, contradicting the documented "substring" contract (a short
189
+ // token inside a longer string timed out). Visible-only; throws on
190
+ // timeout (caught by the action window → ok:false).
191
+ await ctx.page.getByText(wanted).first().waitFor({ state: "visible", timeout });
192
+ return { stillAttached: true };
193
+ });
194
+ }
195
+ if (!args.target) {
196
+ throw new Error("wait_for: pass a `target` (ref/selector/named/coords) or `text`");
197
+ }
198
+ const target = args.target;
199
+ const descriptor = { type: "waitFor", ...refOrSelector(target) };
200
+ return runInActionWindow(ctx, descriptor, args, async () => {
201
+ const loc = locatorFor(ctx.page, ctx.refs, target);
202
+ await loc.waitFor({ state: "visible", timeout });
203
+ return probe(loc, target);
204
+ });
205
+ }
206
+ /**
207
+ * Resolve which of the four scroll behaviours a `ScrollArgs` selects, or throw
208
+ * a clear error for a no-op call. Pure — exported for unit tests.
209
+ *
210
+ * - target + (no to/by) | intoView:true → scroll the element into view
211
+ * - target + (to|by) + intoView:false → scroll *within* the container
212
+ * - coords target → wheel scroll at the point
213
+ * - no target + (to|by) → window scroll
214
+ */
215
+ export function scrollMode(args) {
216
+ if (args.target?.coords)
217
+ return { kind: "wheel-at" };
218
+ if (args.target) {
219
+ const wantsInto = args.intoView ?? (args.to === undefined && args.by === undefined);
220
+ return wantsInto ? { kind: "into-view" } : { kind: "container" };
221
+ }
222
+ if (args.to === undefined && args.by === undefined) {
223
+ throw new Error("scroll: no-op — pass `to` (top|bottom|left|right) or `by` {x,y}, or a `target` to scroll into view");
224
+ }
225
+ return { kind: "window" };
226
+ }
227
+ export async function scroll(ctx, args) {
228
+ const descriptor = {
229
+ type: "scroll",
230
+ value: args.to ?? (args.by ? `by ${args.by.x ?? 0},${args.by.y ?? 0}` : "into-view"),
231
+ ...(args.target ? refOrSelector(args.target) : {}),
232
+ };
233
+ return runInActionWindow(ctx, descriptor, args, async () => {
234
+ const mode = scrollMode(args);
235
+ if (mode.kind === "wheel-at") {
236
+ const c = args.target.coords;
237
+ await ctx.page.mouse.move(c.x, c.y);
238
+ await ctx.page.mouse.wheel(args.by?.x ?? 0, args.by?.y ?? 0);
239
+ return { stillAttached: true, scroll: await windowScrollGeometry(ctx.page) };
240
+ }
241
+ if (mode.kind === "into-view") {
242
+ const loc = locatorFor(ctx.page, ctx.refs, args.target);
243
+ await loc.scrollIntoViewIfNeeded({ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
244
+ const p = await probe(loc, args.target);
245
+ p.scroll = await windowScrollGeometry(ctx.page);
246
+ return p;
247
+ }
248
+ if (mode.kind === "container") {
249
+ const loc = locatorFor(ctx.page, ctx.refs, args.target);
250
+ await loc.evaluate((el, a) => {
251
+ if (a.to === "top")
252
+ el.scrollTop = 0;
253
+ else if (a.to === "bottom")
254
+ el.scrollTop = el.scrollHeight;
255
+ else if (a.to === "left")
256
+ el.scrollLeft = 0;
257
+ else if (a.to === "right")
258
+ el.scrollLeft = el.scrollWidth;
259
+ if (a.by)
260
+ el.scrollBy(a.by.x ?? 0, a.by.y ?? 0);
261
+ }, { to: args.to, by: args.by });
262
+ const p = await probe(loc, args.target);
263
+ p.scroll = await elementScrollGeometry(loc);
264
+ return p;
265
+ }
266
+ // window
267
+ await ctx.page.evaluate((a) => {
268
+ const g = globalThis;
269
+ const w = g;
270
+ const doc = w.document?.documentElement;
271
+ if (a.to === "top")
272
+ w.scrollTo(w.scrollX, 0);
273
+ else if (a.to === "bottom")
274
+ w.scrollTo(w.scrollX, doc ? doc.scrollHeight : 1e9);
275
+ else if (a.to === "left")
276
+ w.scrollTo(0, w.scrollY);
277
+ else if (a.to === "right")
278
+ w.scrollTo(doc ? doc.scrollWidth : 1e9, w.scrollY);
279
+ if (a.by)
280
+ w.scrollBy(a.by.x ?? 0, a.by.y ?? 0);
281
+ }, { to: args.to, by: args.by });
282
+ return { stillAttached: true, scroll: await windowScrollGeometry(ctx.page) };
283
+ });
284
+ }
285
+ /** mid-session viewport resize. `page.setViewportSize` re-lays-out and
286
+ * often triggers responsive re-render / lazy-load — wrapped in the action
287
+ * window so `structure` / `network` / `snapshotDelta` show what changed.
288
+ * Device emulation (isMobile/touch/UA/DPR) is creation-time only; this only
289
+ * changes the size. */
290
+ export async function setViewport(ctx, args) {
291
+ const descriptor = {
292
+ type: "setViewport",
293
+ value: `${args.width}x${args.height}`,
294
+ };
295
+ return runInActionWindow(ctx, descriptor, args, async () => {
296
+ await ctx.page.setViewportSize({ width: args.width, height: args.height });
297
+ return { stillAttached: true };
298
+ });
299
+ }
300
+ /**
301
+ * `choose_option` primitive. Generic combobox/listbox/menu selection
302
+ * for custom controls that aren't native `<select>` (so the existing `select`
303
+ * tool can't drive them). The pattern: open the target control, wait for a
304
+ * visible listbox/menu/portal, find the option element by exact text, click
305
+ * it, return the probe on the *trigger* so `ownerControl.displayText`
306
+ * shows the committed selection.
307
+ *
308
+ * Falls back across `role=option` → `role=menuitem` → `getByText` so works
309
+ * on any reasonable combobox shape. Does **not** simulate keyboard navigation
310
+ * (type-and-press-Enter) — that's a different primitive and prone to picking
311
+ * the wrong option in dense lists.
312
+ */
313
+ export async function chooseOption(ctx, args) {
314
+ const descriptor = {
315
+ type: "chooseOption",
316
+ value: args.option,
317
+ ...targetDescriptor(args.target),
318
+ };
319
+ return runInActionWindow(ctx, descriptor, args, async () => {
320
+ if (args.target.coords) {
321
+ throw new Error("choose_option requires a ref/selector/named target (the combobox/menu trigger), not coords");
322
+ }
323
+ const trigger = locatorFor(ctx.page, ctx.refs, args.target);
324
+ const pre = await preProbe(trigger);
325
+ // Open the control if not already expanded. `aria-expanded` is the strongest
326
+ // signal; absence isn't proof it's closed, so we still click if false-or-missing.
327
+ const isExpanded = await trigger
328
+ .evaluate((el) => !!el.getAttribute && el.getAttribute("aria-expanded") === "true")
329
+ .catch(() => false);
330
+ if (!isExpanded) {
331
+ await trigger.click({ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
332
+ }
333
+ const optionLoc = await resolveOption(ctx.page, args.option, args.exact ?? true);
334
+ await optionLoc.click({ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS });
335
+ return probe(trigger, args.target, undefined, pre);
336
+ });
337
+ }
338
+ /** Resolve the option element by exact text across the three common shapes a
339
+ * custom combobox/listbox emits. Tries each in order, returning the first
340
+ * attempt that has a non-zero count. Last attempt is returned even if empty
341
+ * so the subsequent `click()` produces a clean timeout error instead of
342
+ * silently doing nothing. */
343
+ async function resolveOption(page, text, exact) {
344
+ const attempts = [
345
+ () => page.getByRole("option", { name: text, exact }).first(),
346
+ () => page.getByRole("menuitem", { name: text, exact }).first(),
347
+ () => page.getByText(text, { exact }).first(),
348
+ ];
349
+ for (const make of attempts) {
350
+ const loc = make();
351
+ const count = await loc.count().catch(() => 0);
352
+ if (count > 0)
353
+ return loc;
354
+ }
355
+ return attempts[0]();
356
+ }
357
+ export async function goBack(ctx, args = {}) {
358
+ return runInActionWindow(ctx, { type: "goBack" }, args, async () => {
359
+ await ctx.page.goBack({
360
+ waitUntil: "domcontentloaded",
361
+ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS,
362
+ });
363
+ });
364
+ }
365
+ export async function goForward(ctx, args = {}) {
366
+ return runInActionWindow(ctx, { type: "goForward" }, args, async () => {
367
+ await ctx.page.goForward({
368
+ waitUntil: "domcontentloaded",
369
+ timeout: args.deadlineMs ?? DEFAULT_TIMEOUT_MS,
370
+ });
371
+ });
372
+ }
373
+ // ---------- helpers ----------
374
+ /** Dispatch-side secret materialisation. Wraps `SecretRegistry.materialize`
375
+ * with a no-registry fallback so non-secrets callers don't need to feature-
376
+ * detect. Exported for composing primitives (e.g. multi-field fill). */
377
+ export function materialiseValue(ctx, raw) {
378
+ if (!ctx.secrets)
379
+ return { ok: true, value: raw };
380
+ const m = ctx.secrets.materialize(raw, ctx.page.url());
381
+ if (!m.ok)
382
+ return { ok: false, error: m.error };
383
+ return m.alias ? { ok: true, value: m.value, alias: m.alias } : { ok: true, value: m.value };
384
+ }
385
+ /** Build a clean ActionResult-shaped failure for a secrets-materialisation
386
+ * rejection (no Playwright op ever runs). Mirrors the action-window error
387
+ * envelope so the agent sees a consistent shape. */
388
+ function failedFill(args, message) {
389
+ return secretsFailure({ type: "fill", value: args.value, ...refOrSelector(args.target) }, message);
390
+ }
391
+ function failedPress(args, message) {
392
+ return secretsFailure({ type: "press", value: args.key, ...(args.target ? refOrSelector(args.target) : {}) }, message);
393
+ }
394
+ function secretsFailure(action, message) {
395
+ return {
396
+ ok: false,
397
+ action,
398
+ navigation: { changed: false, from: "", to: "", kind: null },
399
+ structure: { appeared: [], removed: [], newTabs: [] },
400
+ console: { errors: [], warnings: 0 },
401
+ pageErrors: [],
402
+ network: { summary: { total: 0, byType: {}, failed: 0 } },
403
+ tokensEstimate: 0,
404
+ warnings: [],
405
+ error: message,
406
+ };
407
+ }
408
+ /** Post-probe defence-in-depth: mask any registered real-value that leaked
409
+ * into the probe's `value` / `displayText` / `ownerControl` / `container`
410
+ * string fields. The fill / press path is the canonical source of these
411
+ * leaks — the field's DOM value reflects what we just typed.
412
+ * Exported for composing primitives (e.g. multi-field fill). */
413
+ export function maskProbe(probed, ctx) {
414
+ if (!probed || !ctx.secrets)
415
+ return probed;
416
+ const out = { ...probed };
417
+ if (typeof out.value === "string")
418
+ out.value = ctx.secrets.applyMaskInText(out.value);
419
+ if (typeof out.displayText === "string")
420
+ out.displayText = ctx.secrets.applyMaskInText(out.displayText);
421
+ if (out.ownerControl) {
422
+ const oc = { ...out.ownerControl };
423
+ if (oc.displayTextBefore)
424
+ oc.displayTextBefore = ctx.secrets.applyMaskInText(oc.displayTextBefore);
425
+ if (oc.displayTextAfter)
426
+ oc.displayTextAfter = ctx.secrets.applyMaskInText(oc.displayTextAfter);
427
+ if (oc.label)
428
+ oc.label = ctx.secrets.applyMaskInText(oc.label);
429
+ out.ownerControl = oc;
430
+ }
431
+ if (out.container) {
432
+ const c = { ...out.container };
433
+ if (c.rowKey)
434
+ c.rowKey = ctx.secrets.applyMaskInText(c.rowKey);
435
+ if (c.rowText)
436
+ c.rowText = ctx.secrets.applyMaskInText(c.rowText);
437
+ out.container = c;
438
+ }
439
+ return out;
440
+ }
441
+ function refOrSelector(t) {
442
+ if (t.ref)
443
+ return { ref: t.ref };
444
+ if (t.selector)
445
+ return { selector: t.selector };
446
+ return {};
447
+ }
448
+ function targetDescriptor(t) {
449
+ // DispatchedAction's `ref`/`selector` fields are advisory metadata for the
450
+ // recording layer; coords targets simply omit them.
451
+ return refOrSelector(t);
452
+ }
453
+ export { preProbe, probe, captureHit, captureFocusedRef } from "./actions-probe.js";
@@ -0,0 +1,39 @@
1
+ /** One linked resource the discovery script found. `kind` drives subdir
2
+ * placement in directory mode + content-type inference in single-file mode. */
3
+ export interface DiscoveredResource {
4
+ url: string;
5
+ kind: "image" | "font" | "script" | "stylesheet" | "media" | "other";
6
+ /** Original attribute text the discovery script saw — used to rewrite the
7
+ * HTML to point at the asset sidecar in directory mode. */
8
+ rawRef: string;
9
+ }
10
+ /** Fetch one URL from inside the page, returning base64 + a content-type
11
+ * guess. Used in single-file mode (data: URIs) and as the byte source for
12
+ * directory mode. Failures are caught — the caller drops + counts. */
13
+ export declare function buildFetchScript(url: string): string;
14
+ export interface FetchedResource {
15
+ ok: boolean;
16
+ base64?: string;
17
+ contentType?: string;
18
+ bytes?: number;
19
+ status?: number;
20
+ error?: string;
21
+ }
22
+ /** Slugify a URL into a filesystem-safe asset filename. The hash prefix
23
+ * disambiguates same-name resources from different origins. */
24
+ export declare function assetFilename(url: string, kind: DiscoveredResource["kind"], contentType: string): string;
25
+ export declare function subdirForKind(kind: DiscoveredResource["kind"]): string;
26
+ /** Rewrite raw HTML — replace every recorded `rawRef` with the relative
27
+ * asset path the file has been written to. We do a literal substring
28
+ * replacement (anchored to quote boundaries where possible) rather than
29
+ * parsing the HTML: parsing introduces fidelity risk, and the discovery
30
+ * script captured exactly the raw attribute text we'll see in `outerHTML`.
31
+ *
32
+ * The order matters — replace longer `rawRef`s before shorter ones so a
33
+ * prefix-substring of a different URL isn't accidentally matched. */
34
+ export declare function rewriteHtml(html: string, replacements: Array<{
35
+ rawRef: string;
36
+ replacement: string;
37
+ }>): string;
38
+ export declare function mimeFromKind(kind: DiscoveredResource["kind"]): string;
39
+ export declare function directorySize(dir: string): number;
@@ -0,0 +1,187 @@
1
+ // page_archive asset helpers — the per-URL page-side fetch script, the
2
+ // filename/mime/ext/subdir naming, HTML rewriting, and directory-size walk.
3
+ // Split out of archive.ts so the orchestrator stays under the size budget;
4
+ // behavior-identical.
5
+ import { extname, sep } from "node:path";
6
+ import { statSync, readdirSync } from "node:fs";
7
+ /** Fetch one URL from inside the page, returning base64 + a content-type
8
+ * guess. Used in single-file mode (data: URIs) and as the byte source for
9
+ * directory mode. Failures are caught — the caller drops + counts. */
10
+ export function buildFetchScript(url) {
11
+ // page.evaluate(string) treats the string as an expression — `await` only
12
+ // works inside an async IIFE. Encode the URL once at compose time.
13
+ const literal = JSON.stringify(url);
14
+ return `(async () => {
15
+ try {
16
+ var r = await fetch(${literal}, { credentials: 'include', cache: 'no-store' });
17
+ if (!r.ok) return { ok: false, status: r.status, contentType: r.headers.get('content-type') || '' };
18
+ var ct = r.headers.get('content-type') || '';
19
+ var buf = await r.arrayBuffer();
20
+ var bytes = new Uint8Array(buf);
21
+ // chunked base64 — TextDecoder + btoa for portability inside the page
22
+ var CHUNK = 0x8000, parts = [];
23
+ for (var i = 0; i < bytes.length; i += CHUNK) {
24
+ parts.push(String.fromCharCode.apply(null, bytes.subarray(i, i + CHUNK)));
25
+ }
26
+ return { ok: true, base64: btoa(parts.join('')), contentType: ct, bytes: bytes.length };
27
+ } catch (e) {
28
+ return { ok: false, error: (e && e.message) ? String(e.message) : String(e) };
29
+ }
30
+ })()`;
31
+ }
32
+ /** Slugify a URL into a filesystem-safe asset filename. The hash prefix
33
+ * disambiguates same-name resources from different origins. */
34
+ export function assetFilename(url, kind, contentType) {
35
+ let stem;
36
+ let urlExt = "";
37
+ try {
38
+ const u = new URL(url);
39
+ const last = u.pathname.split("/").filter(Boolean).pop() ?? "asset";
40
+ urlExt = extname(last);
41
+ stem = last.replace(/[^A-Za-z0-9._-]/g, "_") || "asset";
42
+ if (urlExt)
43
+ stem = stem.slice(0, -urlExt.length);
44
+ }
45
+ catch {
46
+ stem = "asset";
47
+ }
48
+ // 8-char hash from the URL to disambiguate collisions across origins.
49
+ const hash = simpleHash(url);
50
+ const ext = urlExt || guessExtFromContentType(contentType) || guessExtFromKind(kind);
51
+ return `${stem}-${hash}${ext}`;
52
+ }
53
+ function simpleHash(s) {
54
+ // tiny non-cryptographic hash — collision risk is negligible at archive
55
+ // resource counts (low hundreds) and we want zero deps.
56
+ let h = 0x811c9dc5;
57
+ for (let i = 0; i < s.length; i++) {
58
+ h = (h ^ s.charCodeAt(i)) >>> 0;
59
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
60
+ }
61
+ return h.toString(16).padStart(8, "0");
62
+ }
63
+ function guessExtFromContentType(ct) {
64
+ const c = ct.split(";")[0].trim().toLowerCase();
65
+ const map = {
66
+ "text/html": ".html",
67
+ "text/css": ".css",
68
+ "text/javascript": ".js",
69
+ "application/javascript": ".js",
70
+ "application/json": ".json",
71
+ "image/png": ".png",
72
+ "image/jpeg": ".jpg",
73
+ "image/gif": ".gif",
74
+ "image/svg+xml": ".svg",
75
+ "image/webp": ".webp",
76
+ "image/x-icon": ".ico",
77
+ "font/woff": ".woff",
78
+ "font/woff2": ".woff2",
79
+ "font/ttf": ".ttf",
80
+ "font/otf": ".otf",
81
+ "application/font-woff": ".woff",
82
+ "application/font-woff2": ".woff2",
83
+ "video/mp4": ".mp4",
84
+ "audio/mpeg": ".mp3",
85
+ };
86
+ return map[c] ?? "";
87
+ }
88
+ function guessExtFromKind(kind) {
89
+ switch (kind) {
90
+ case "image":
91
+ return ".bin";
92
+ case "font":
93
+ return ".font";
94
+ case "script":
95
+ return ".js";
96
+ case "stylesheet":
97
+ return ".css";
98
+ case "media":
99
+ return ".media";
100
+ default:
101
+ return ".bin";
102
+ }
103
+ }
104
+ export function subdirForKind(kind) {
105
+ switch (kind) {
106
+ case "image":
107
+ return "images";
108
+ case "font":
109
+ return "fonts";
110
+ case "script":
111
+ return "scripts";
112
+ case "stylesheet":
113
+ return "styles";
114
+ case "media":
115
+ return "media";
116
+ default:
117
+ return "other";
118
+ }
119
+ }
120
+ /** Rewrite raw HTML — replace every recorded `rawRef` with the relative
121
+ * asset path the file has been written to. We do a literal substring
122
+ * replacement (anchored to quote boundaries where possible) rather than
123
+ * parsing the HTML: parsing introduces fidelity risk, and the discovery
124
+ * script captured exactly the raw attribute text we'll see in `outerHTML`.
125
+ *
126
+ * The order matters — replace longer `rawRef`s before shorter ones so a
127
+ * prefix-substring of a different URL isn't accidentally matched. */
128
+ export function rewriteHtml(html, replacements) {
129
+ const sorted = [...replacements].sort((a, b) => b.rawRef.length - a.rawRef.length);
130
+ let out = html;
131
+ for (const { rawRef, replacement } of sorted) {
132
+ if (!rawRef)
133
+ continue;
134
+ // Wrap in quote-anchored patterns first so `path="/foo"` doesn't catch
135
+ // a stray `/foo` substring in inline text.
136
+ const quoted = [`"${rawRef}"`, `'${rawRef}'`];
137
+ for (const q of quoted) {
138
+ const replWith = q[0] + replacement + q[0];
139
+ out = out.split(q).join(replWith);
140
+ }
141
+ // Fall through — some `srcset` / `style` references don't wear quotes.
142
+ // Bounded literal replace to avoid the regex-cost trap.
143
+ if (rawRef.length >= 4)
144
+ out = out.split(rawRef).join(replacement);
145
+ }
146
+ return out;
147
+ }
148
+ export function mimeFromKind(kind) {
149
+ // Fallback MIME when the response carried no Content-Type. Use a concrete
150
+ // type the browser can render rather than a wildcard (which is not valid
151
+ // in a `data:` URI). These are best-guesses, not authoritative — the
152
+ // upstream response should be carrying Content-Type in any sane setup.
153
+ switch (kind) {
154
+ case "image":
155
+ return "image/png";
156
+ case "font":
157
+ return "font/woff2";
158
+ case "script":
159
+ return "application/javascript";
160
+ case "stylesheet":
161
+ return "text/css";
162
+ case "media":
163
+ return "video/mp4";
164
+ default:
165
+ return "application/octet-stream";
166
+ }
167
+ }
168
+ export function directorySize(dir) {
169
+ let total = 0;
170
+ const walk = (d) => {
171
+ for (const entry of readdirSync(d, { withFileTypes: true })) {
172
+ const p = d + sep + entry.name;
173
+ if (entry.isDirectory())
174
+ walk(p);
175
+ else if (entry.isFile()) {
176
+ try {
177
+ total += statSync(p).size;
178
+ }
179
+ catch {
180
+ /* best-effort */
181
+ }
182
+ }
183
+ }
184
+ };
185
+ walk(dir);
186
+ return total;
187
+ }