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,449 @@
1
+ /// <reference lib="dom" />
2
+ // `overflow_detect` — diagnose page-layout overflow.
3
+ //
4
+ // The silent UI-breakage primitive: clipped buttons, ellipsis-truncated
5
+ // labels, horizontal-scrollbar-on-mobile bugs. Agents repeatedly miss
6
+ // these because a screenshot looks "fine" (the clipped pixel doesn't
7
+ // shout) and `find()` doesn't surface "the element rendered but its
8
+ // content was lost". This tool walks the DOM, applies four overflow
9
+ // shape detectors, and returns one finding per offending element.
10
+ //
11
+ // Detector taxonomy (all four enabled by default; opt out via `types`):
12
+ //
13
+ // - `layout` — `scrollWidth/Height > clientWidth/Height` on
14
+ // an element whose computed `overflow` is
15
+ // `auto`/`scroll`. The platform IS providing a
16
+ // scrollbar but content overflows the visible
17
+ // padding box. Subtler than `clipped` (content
18
+ // is recoverable) but still worth surfacing.
19
+ // - `clipped` — same dimensional check, but `overflow-x|y` is
20
+ // `hidden`/`clip`. Content extending past the
21
+ // box is invisible with no scrollbar to
22
+ // recover. The high-value "the button got cut
23
+ // off" finding.
24
+ // - `text-ellipsis` — `text-overflow: ellipsis` AND
25
+ // `scrollWidth > clientWidth` on the text node
26
+ // itself. Carries `visibleText` (best-effort
27
+ // heuristic — the offsetWidth-bounded prefix)
28
+ // plus `fullText` (the truth the agent reads).
29
+ // - `viewport-horizontal` — singleton check: `documentElement.scrollWidth
30
+ // > documentElement.clientWidth`. The "horizontal
31
+ // scrollbar on body" mobile-layout bug. One
32
+ // finding at most; selector `"html"`; evidence
33
+ // surfaces the overrun amount + the widest
34
+ // overrunning descendant when cheaply identifiable.
35
+ //
36
+ // EPSILON = 1 CSS px tolerates sub-pixel rounding noise — without it,
37
+ // pages that scale fonts or run on a fractional devicePixelRatio routinely
38
+ // trip false positives by ≤0.5 px.
39
+ //
40
+ // Bounded walk: `MAX_ELEMENTS_SCANNED = 10000`. When the cap is hit, the
41
+ // result carries `warnings:["scan stopped at MAX_ELEMENTS_SCANNED…"]` so
42
+ // the agent can re-run with `scope:"viewport"` for a narrower pass.
43
+ //
44
+ // Page-side function is passed as a REAL function literal (not a
45
+ // stringified arrow) so Playwright's `Page.evaluate(fn, arg)` path
46
+ // serializes the source and invokes in-page with the arg. The same trap
47
+ // burned `dom_export`'s `PAGE_WALK_FN` and `element_export`'s discovery
48
+ // function — a stringified `(args) => {...}` evaluates to the function
49
+ // value uncalled, which CDP can't serialize → undefined.
50
+ const ALL_TYPES = ["layout", "clipped", "text-ellipsis", "viewport-horizontal"];
51
+ const DEFAULT_LIMIT = 50;
52
+ const MAX_LIMIT = 500;
53
+ const MAX_ELEMENTS_SCANNED = 10000;
54
+ /** Selector synthesis tiers (page-side mirror in `PAGE_DETECT_FN`):
55
+ *
56
+ * 1. `[data-testid="..."]`
57
+ * 2. `[role="..."][aria-label="..."]` (both stable)
58
+ * 3. nth-of-type CSS path bounded at 5 levels
59
+ * 4. `tag.classes` (up to 3 classes)
60
+ *
61
+ * Capped at 200 chars; longer falls through to `tag` only with an
62
+ * `evidence.selectorTruncated` flag.
63
+ *
64
+ * Exported for unit tests against fixture mock elements.
65
+ */
66
+ const SELECTOR_MAX_LEN = 200;
67
+ export function synthesiseSelector(el) {
68
+ const tag = (el.tagName || "").toLowerCase();
69
+ let raw;
70
+ // Tier 1 — data-testid.
71
+ if (el.testId) {
72
+ raw = `[data-testid="${escapeAttrValue(el.testId)}"]`;
73
+ }
74
+ else if (el.role && el.ariaLabel) {
75
+ // Tier 2 — role + accessible name (both stable).
76
+ raw = `[role="${escapeAttrValue(el.role)}"][aria-label="${escapeAttrValue(el.ariaLabel)}"]`;
77
+ }
78
+ else if (el.parentChain && el.parentChain.length > 0 && typeof el.nthOfType === "number") {
79
+ // Tier 3 — nth-of-type CSS path, bounded at 5 levels.
80
+ const levels = [];
81
+ const chain = el.parentChain.slice(0, 5);
82
+ for (let i = chain.length - 1; i >= 0; i--) {
83
+ const a = chain[i];
84
+ levels.push(`${a.tagName.toLowerCase()}:nth-of-type(${a.nthOfType})`);
85
+ }
86
+ levels.push(`${tag}:nth-of-type(${el.nthOfType})`);
87
+ raw = levels.join(" > ");
88
+ }
89
+ else if (el.classList.length > 0) {
90
+ // Tier 4 — tag.classes (up to 3).
91
+ const classes = el.classList.slice(0, 3).map(escapeClassName);
92
+ raw = `${tag}.${classes.join(".")}`;
93
+ }
94
+ else {
95
+ raw = tag || "*";
96
+ }
97
+ if (raw.length <= SELECTOR_MAX_LEN) {
98
+ return { selector: raw, truncated: false, originalLength: raw.length };
99
+ }
100
+ return { selector: tag || "*", truncated: true, originalLength: raw.length };
101
+ }
102
+ function escapeAttrValue(v) {
103
+ return v.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
104
+ }
105
+ function escapeClassName(c) {
106
+ // CSS identifier escape — limited to characters classlist actually surfaces;
107
+ // we don't try to encode arbitrary text-of-the-rainbow class names, just
108
+ // the ones a synthesised selector needs to round-trip.
109
+ return c.replace(/([^A-Za-z0-9_-])/g, "\\$1");
110
+ }
111
+ /** Pure helper: cap findings at `limit`, set `truncated` when exceeded.
112
+ * Exported for unit tests. */
113
+ export function applyLimit(findings, limit) {
114
+ if (findings.length <= limit) {
115
+ return { kept: findings, truncated: false };
116
+ }
117
+ return { kept: findings.slice(0, limit), truncated: true };
118
+ }
119
+ /** Pure helper: which detector mask should be active. Empty array →
120
+ * all four (an empty filter is treated as "default", not "exclude
121
+ * everything" — the latter would be a usage error with no signal). */
122
+ export function resolveTypes(requested) {
123
+ if (!requested || requested.length === 0)
124
+ return new Set(ALL_TYPES);
125
+ // Filter to the known set so a typo doesn't silently turn into a
126
+ // useless filter; unknowns are dropped.
127
+ const out = new Set();
128
+ for (const t of requested) {
129
+ if (ALL_TYPES.includes(t))
130
+ out.add(t);
131
+ }
132
+ if (out.size === 0)
133
+ return new Set(ALL_TYPES);
134
+ return out;
135
+ }
136
+ /** Pure helper for the EPSILON math — returns true when content actually
137
+ * overruns its container past the sub-pixel-noise tolerance. Centralised
138
+ * so the unit tests can pin the threshold + so changes flow through one
139
+ * site instead of four detector branches. */
140
+ export const OVERFLOW_EPSILON = 1;
141
+ export function overflows(scrollDim, clientDim, epsilon = OVERFLOW_EPSILON) {
142
+ return scrollDim > clientDim + epsilon;
143
+ }
144
+ /** Page-side detector. Receives the resolved type mask + scope + scan
145
+ * budget; returns raw findings + a `scanCapped` flag. Walk is bounded
146
+ * by `MAX_ELEMENTS_SCANNED`. Passed as a real function literal — see
147
+ * the file-header note on the stringified-arrow trap. */
148
+ const PAGE_DETECT_FN = (args) => {
149
+ const wantLayout = args.types.indexOf("layout") !== -1;
150
+ const wantClipped = args.types.indexOf("clipped") !== -1;
151
+ const wantEllipsis = args.types.indexOf("text-ellipsis") !== -1;
152
+ const wantVpHorizontal = args.types.indexOf("viewport-horizontal") !== -1;
153
+ const epsilon = args.epsilon;
154
+ const selectorMaxLen = args.selectorMaxLen;
155
+ const findings = [];
156
+ function escapeAttr(v) {
157
+ return v.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
158
+ }
159
+ function escapeCls(c) {
160
+ return c.replace(/([^A-Za-z0-9_-])/g, "\\$1");
161
+ }
162
+ function nthOfType(node) {
163
+ let n = 1;
164
+ let prev = node.previousElementSibling;
165
+ while (prev) {
166
+ if (prev.tagName === node.tagName)
167
+ n++;
168
+ prev = prev.previousElementSibling;
169
+ }
170
+ return n;
171
+ }
172
+ /** Tier 3 — nth-of-type CSS path (≤5 levels), else a class selector, else the
173
+ * bare tag. */
174
+ function synthTier3(el, tag) {
175
+ const path = [];
176
+ let cur = el;
177
+ for (let i = 0; i < 5 && cur && cur.nodeType === 1 && cur !== document.documentElement; i++) {
178
+ const ctag = (cur.tagName || "").toLowerCase();
179
+ path.unshift(ctag + ":nth-of-type(" + nthOfType(cur) + ")");
180
+ cur = cur.parentElement;
181
+ }
182
+ if (path.length > 0)
183
+ return path.join(" > ");
184
+ if (el.classList && el.classList.length > 0) {
185
+ const cls = [];
186
+ for (let i = 0; i < el.classList.length && i < 3; i++)
187
+ cls.push(escapeCls(el.classList[i]));
188
+ return tag + "." + cls.join(".");
189
+ }
190
+ return tag || "*";
191
+ }
192
+ /** Compute the raw (un-truncated) selector via the tiered preference:
193
+ * data-testid → role+aria-label → tier-3 path. */
194
+ function synthRaw(el, tag) {
195
+ const testId = el.getAttribute("data-testid");
196
+ if (testId)
197
+ return '[data-testid="' + escapeAttr(testId) + '"]';
198
+ const role = el.getAttribute("role");
199
+ const ariaLabel = el.getAttribute("aria-label");
200
+ if (role && ariaLabel) {
201
+ return '[role="' + escapeAttr(role) + '"][aria-label="' + escapeAttr(ariaLabel) + '"]';
202
+ }
203
+ return synthTier3(el, tag);
204
+ }
205
+ function synth(el) {
206
+ const tag = (el.tagName || "").toLowerCase();
207
+ const raw = synthRaw(el, tag);
208
+ if (raw.length <= selectorMaxLen) {
209
+ return { selector: raw, truncated: false, originalLength: raw.length };
210
+ }
211
+ return { selector: tag || "*", truncated: true, originalLength: raw.length };
212
+ }
213
+ function bboxOf(el) {
214
+ try {
215
+ const r = el.getBoundingClientRect();
216
+ if (!r)
217
+ return null;
218
+ return { x: r.x, y: r.y, w: r.width, h: r.height };
219
+ }
220
+ catch (_) {
221
+ return null;
222
+ }
223
+ }
224
+ function inViewport(el) {
225
+ try {
226
+ const r = el.getBoundingClientRect();
227
+ const vw = window.innerWidth || document.documentElement.clientWidth || 0;
228
+ const vh = window.innerHeight || document.documentElement.clientHeight || 0;
229
+ // Fully off-screen if right<=0 OR bottom<=0 OR left>=vw OR top>=vh.
230
+ if (r.right <= 0 || r.bottom <= 0 || r.left >= vw || r.top >= vh)
231
+ return false;
232
+ return true;
233
+ }
234
+ catch (_) {
235
+ return true;
236
+ }
237
+ }
238
+ // 1. viewport-horizontal — singleton finding before the element walk.
239
+ let scanCapped = false;
240
+ if (wantVpHorizontal)
241
+ detectViewportHorizontal();
242
+ // 2. Element walk for layout / clipped / text-ellipsis.
243
+ if (wantLayout || wantClipped || wantEllipsis) {
244
+ let all;
245
+ try {
246
+ all = document.querySelectorAll("*");
247
+ }
248
+ catch (_) {
249
+ return { findings, scanCapped: false };
250
+ }
251
+ const totalCount = all.length;
252
+ const scanLimit = totalCount < args.maxElements ? totalCount : args.maxElements;
253
+ if (totalCount > args.maxElements)
254
+ scanCapped = true;
255
+ for (let i = 0; i < scanLimit; i++) {
256
+ const el = all[i];
257
+ if (el.nodeType !== 1)
258
+ continue;
259
+ if (args.scope === "viewport" && !inViewport(el))
260
+ continue;
261
+ let cs = null;
262
+ try {
263
+ cs = getComputedStyle(el);
264
+ }
265
+ catch (_) {
266
+ continue;
267
+ }
268
+ if (!cs)
269
+ continue;
270
+ classifyElement(el, cs);
271
+ }
272
+ }
273
+ return { findings, scanCapped };
274
+ // --- nested classifiers (must stay nested for page serialization) ---
275
+ /** Find the widest descendant whose bbox overruns the viewport (bounded scan
276
+ * of the first 500 candidates so the singleton stays cheap). */
277
+ function widestOverrunDescendant(cw) {
278
+ let widestSel;
279
+ let widestW = 0;
280
+ try {
281
+ const candidates = document.body
282
+ ? document.body.querySelectorAll("*")
283
+ : [];
284
+ const max = candidates.length < 500 ? candidates.length : 500;
285
+ for (let i = 0; i < max; i++) {
286
+ const c = candidates[i];
287
+ const r = c.getBoundingClientRect();
288
+ if (r.right > cw + epsilon && r.width > widestW) {
289
+ widestW = r.width;
290
+ widestSel = synth(c).selector;
291
+ }
292
+ }
293
+ }
294
+ catch {
295
+ // best-effort widest-descendant scan; leave widestSel undefined on failure
296
+ }
297
+ return { sel: widestSel, w: widestW };
298
+ }
299
+ /** viewport-horizontal singleton — the document scrolls horizontally past the
300
+ * viewport. Best-effort; skips on hostile docs. */
301
+ function detectViewportHorizontal() {
302
+ try {
303
+ const docEl = document.documentElement;
304
+ if (!docEl)
305
+ return;
306
+ const sw = docEl.scrollWidth;
307
+ const cw = docEl.clientWidth;
308
+ if (sw <= cw + epsilon)
309
+ return;
310
+ const widest = widestOverrunDescendant(cw);
311
+ findings.push({
312
+ selector: "html",
313
+ selectorTruncated: false,
314
+ selectorOriginalLength: 4,
315
+ bbox: { x: 0, y: 0, w: cw, h: docEl.clientHeight },
316
+ type: "viewport-horizontal",
317
+ evidence: {
318
+ documentScrollWidth: sw,
319
+ viewportWidth: cw,
320
+ overrunPx: sw - cw,
321
+ ...(widest.sel
322
+ ? { widestDescendantSelector: widest.sel, widestDescendantWidth: widest.w }
323
+ : {}),
324
+ },
325
+ });
326
+ }
327
+ catch {
328
+ // best-effort viewport-overflow probe; skip section on hostile docs
329
+ }
330
+ }
331
+ function classifyElement(el, cs) {
332
+ const geom = {
333
+ sw: el.scrollWidth,
334
+ sh: el.scrollHeight,
335
+ cw: el.clientWidth,
336
+ ch: el.clientHeight,
337
+ };
338
+ const overX = geom.sw > geom.cw + epsilon;
339
+ const overY = geom.sh > geom.ch + epsilon;
340
+ if (!overX && !overY && !wantEllipsis)
341
+ return;
342
+ const ox = cs.overflowX || "";
343
+ const oy = cs.overflowY || "";
344
+ detectLayoutClip(el, geom, { overX, overY, ox, oy });
345
+ detectEllipsis(el, cs, geom, overX);
346
+ }
347
+ /** Layout (overflow on a scrollable axis) + clipped (overflow on a hidden/clip
348
+ * axis) findings share the same evidence shape; emit whichever matches. */
349
+ function detectLayoutClip(el, geom, o) {
350
+ const isScroll = (v) => v === "auto" || v === "scroll";
351
+ const isClip = (v) => v === "hidden" || v === "clip";
352
+ const evidence = {
353
+ scrollWidth: geom.sw,
354
+ clientWidth: geom.cw,
355
+ scrollHeight: geom.sh,
356
+ clientHeight: geom.ch,
357
+ overflowX: o.ox,
358
+ overflowY: o.oy,
359
+ };
360
+ if (wantLayout && ((o.overX && isScroll(o.ox)) || (o.overY && isScroll(o.oy)))) {
361
+ pushFinding(el, "layout", evidence);
362
+ }
363
+ if (wantClipped && ((o.overX && isClip(o.ox)) || (o.overY && isClip(o.oy)))) {
364
+ pushFinding(el, "clipped", evidence);
365
+ }
366
+ }
367
+ function detectEllipsis(el, cs, geom, overX) {
368
+ if (!wantEllipsis || (cs.textOverflow || "") !== "ellipsis" || !overX)
369
+ return;
370
+ // full text (DOM truth) + a heuristic visible prefix proportional to
371
+ // clientWidth/scrollWidth; the agent reads `fullText` for the truth.
372
+ const fullText = (el.textContent || "").replace(/\s+/g, " ").trim();
373
+ let visibleText = fullText;
374
+ if (geom.sw > 0 && geom.cw > 0 && fullText.length > 0) {
375
+ const cutoff = Math.max(0, Math.floor(fullText.length * (geom.cw / geom.sw)));
376
+ visibleText = fullText.slice(0, cutoff);
377
+ }
378
+ pushFinding(el, "text-ellipsis", {
379
+ scrollWidth: geom.sw,
380
+ clientWidth: geom.cw,
381
+ visibleText,
382
+ fullText,
383
+ });
384
+ }
385
+ function pushFinding(el, type, evidence) {
386
+ const s = synth(el);
387
+ findings.push({
388
+ selector: s.selector,
389
+ selectorTruncated: s.truncated,
390
+ selectorOriginalLength: s.originalLength,
391
+ bbox: bboxOf(el),
392
+ type,
393
+ evidence,
394
+ });
395
+ }
396
+ };
397
+ export async function detectOverflow(page, args = {}) {
398
+ const scope = args.scope ?? "document";
399
+ const typeSet = resolveTypes(args.types);
400
+ const rawLimit = args.limit ?? DEFAULT_LIMIT;
401
+ if (!(rawLimit > 0)) {
402
+ throw new Error(`overflow_detect: limit must be > 0 — got ${rawLimit}.`);
403
+ }
404
+ const limit = Math.min(rawLimit, MAX_LIMIT);
405
+ const raw = await page.evaluate(PAGE_DETECT_FN, {
406
+ types: Array.from(typeSet),
407
+ scope,
408
+ maxElements: MAX_ELEMENTS_SCANNED,
409
+ epsilon: OVERFLOW_EPSILON,
410
+ selectorMaxLen: SELECTOR_MAX_LEN,
411
+ });
412
+ const findings = [];
413
+ for (const rf of raw.findings) {
414
+ // If selector was truncated, fold the original-length note into
415
+ // evidence — the agent shouldn't have to guess why the selector is
416
+ // a bare tag.
417
+ if (rf.selectorTruncated) {
418
+ findings.push({
419
+ selector: rf.selector,
420
+ bbox: rf.bbox,
421
+ type: rf.type,
422
+ evidence: {
423
+ selectorTruncated: true,
424
+ originalLength: rf.selectorOriginalLength,
425
+ },
426
+ });
427
+ }
428
+ else {
429
+ findings.push({
430
+ selector: rf.selector,
431
+ bbox: rf.bbox,
432
+ type: rf.type,
433
+ evidence: rf.evidence,
434
+ });
435
+ }
436
+ }
437
+ const { kept, truncated } = applyLimit(findings, limit);
438
+ const warnings = [];
439
+ if (raw.scanCapped) {
440
+ warnings.push(`scan stopped at MAX_ELEMENTS_SCANNED (${MAX_ELEMENTS_SCANNED}) — re-run with scope:viewport for a narrower pass`);
441
+ }
442
+ return {
443
+ ok: true,
444
+ scope,
445
+ findings: kept,
446
+ truncated,
447
+ warnings,
448
+ };
449
+ }
@@ -0,0 +1,69 @@
1
+ import type { Page } from "playwright-core";
2
+ /** Paper format presets Playwright's `page.pdf()` accepts. The full Playwright
3
+ * set; surface every one rather than re-curating — adopters that need
4
+ * jurisdiction-specific paper get it without a roundtrip back to us. */
5
+ export type PdfFormat = "Letter" | "Legal" | "Tabloid" | "Ledger" | "A0" | "A1" | "A2" | "A3" | "A4" | "A5" | "A6";
6
+ export interface PdfSaveArgs {
7
+ /** Workspace-rooted file path. Default `pdfs/<sessionId>-<ts>.pdf`. Caller
8
+ * supplies a path → it's resolved inside `$BROWX_WORKSPACE` (escape
9
+ * rejected); caller omits it → see `defaultPdfPath`. */
10
+ path?: string;
11
+ /** Paper format. Default "A4". */
12
+ format?: PdfFormat;
13
+ /** Render scale. Default 1. Playwright clamps to `[0.1, 2.0]`; values
14
+ * outside that range are rejected up-front for a clearer error. */
15
+ scale?: number;
16
+ /** Include CSS `background-color` / `background-image` in the rendered
17
+ * output. Default `false` (matches browser-print's default; caller opts
18
+ * in when the artefact needs styled backgrounds). */
19
+ printBackground?: boolean;
20
+ }
21
+ export interface PdfSaveResult {
22
+ ok: true;
23
+ /** Absolute, workspace-rooted path the bytes were written to. */
24
+ path: string;
25
+ /** Final on-disk size, in bytes. */
26
+ bytes: number;
27
+ /** Paper format actually used. */
28
+ format: PdfFormat;
29
+ /** Scale actually used. */
30
+ scale: number;
31
+ /** Whether CSS backgrounds were printed. */
32
+ printBackground: boolean;
33
+ }
34
+ /** Refusal context — what the tool layer hands `assertPdfSupported`. */
35
+ export interface PdfSupportContext {
36
+ /** Session mode (`registry.ts` vocabulary: `persistent` / `incognito` /
37
+ * `attached`). `attached` is BYOB. */
38
+ mode: "persistent" | "incognito" | "attached";
39
+ }
40
+ /** Structured refusal — matches the shape `extensionRefusal` returns so the
41
+ * tool layer can wrap it uniformly. */
42
+ export interface PdfRefusal {
43
+ error: string;
44
+ hint: string;
45
+ }
46
+ /** Refuse PDF generation on session modes Playwright `page.pdf()` doesn't
47
+ * support. BYOB (`attached`) is the only refusal today: printing on a
48
+ * human's own Chrome would surface a print dialog / mutate window state, and
49
+ * `page.pdf()` itself only works against a Chromium we own. Managed
50
+ * `persistent` and `incognito` sessions are both supported (headed and
51
+ * headless — the Playwright headless-only constraint applies to legacy
52
+ * bundles; the bundle browxai ships against handles headed managed Chromium
53
+ * fine).
54
+ *
55
+ * Returns `null` when supported; a `{error, hint}` envelope when refused. */
56
+ export declare function assertPdfSupported(ctx: PdfSupportContext): PdfRefusal | null;
57
+ /** Default output path when the caller doesn't supply one. Workspace-rooted
58
+ * under `pdfs/<sessionId>-<ts>.pdf` — matches the `perf_stop` /
59
+ * `start_har` "subdir per artefact kind" convention. */
60
+ export declare function defaultPdfPath(sessionId: string): string;
61
+ /** Write `page.pdf()` to a workspace-rooted path. The caller has already
62
+ * verified the session mode supports PDF (`assertPdfSupported`); this layer
63
+ * resolves the path, validates inputs, and dispatches to Playwright.
64
+ *
65
+ * Throws on:
66
+ * - `path` escaping `$BROWX_WORKSPACE` (via `resolveWorkspacePath`).
67
+ * - `scale` outside `[0.1, 2.0]`.
68
+ * - Underlying `page.pdf()` failure (re-thrown with original message). */
69
+ export declare function pdfSave(page: Page, workspaceRoot: string, sessionId: string, args?: PdfSaveArgs): Promise<PdfSaveResult>;
@@ -0,0 +1,109 @@
1
+ // `pdf_save` — print the current page to a workspace-rooted PDF.
2
+ //
3
+ // The mirror of `upload_file`: `upload_file` reads workspace-rooted bytes INTO
4
+ // the page, `pdf_save` writes the page's print output OUT to workspace-rooted
5
+ // bytes. Wraps Playwright's `page.pdf()` (CDP `Page.printToPDF` under the hood)
6
+ // — the first-class alternative to "screenshot the page and OCR it back" or to
7
+ // driving the browser's print-to-file dialog with `shortcut`.
8
+ //
9
+ // Workspace-rooted by construction: every path runs through
10
+ // `resolveWorkspacePath` (same helper `start_har` / `dump_storage_state` /
11
+ // `export_playwright_script` use). A path escaping `$BROWX_WORKSPACE` is
12
+ // rejected — no on-disk trace ever lands outside the workspace.
13
+ //
14
+ // Defaults match what an agent reaching for "save the page as a PDF" expects
15
+ // without reading the docs: A4 paper, scale 1, `printBackground:false` (matches
16
+ // browser-print's default — caller opts in when background colour/imagery
17
+ // matters for the artefact).
18
+ //
19
+ // **Chromium constraint:** `page.pdf()` is Chromium-only and refuses on
20
+ // browser-side `attached` (BYOB) sessions — printing on a human's own Chrome
21
+ // would surface a print dialog / mutate the human's window state. The tool
22
+ // layer refuses cleanly with a structured error before we ever call into
23
+ // Playwright (see `assertPdfSupported`).
24
+ import { resolve as resolvePath } from "node:path";
25
+ import { statSync } from "node:fs";
26
+ import { resolveWorkspacePath } from "../session/storage.js";
27
+ /** Refuse PDF generation on session modes Playwright `page.pdf()` doesn't
28
+ * support. BYOB (`attached`) is the only refusal today: printing on a
29
+ * human's own Chrome would surface a print dialog / mutate window state, and
30
+ * `page.pdf()` itself only works against a Chromium we own. Managed
31
+ * `persistent` and `incognito` sessions are both supported (headed and
32
+ * headless — the Playwright headless-only constraint applies to legacy
33
+ * bundles; the bundle browxai ships against handles headed managed Chromium
34
+ * fine).
35
+ *
36
+ * Returns `null` when supported; a `{error, hint}` envelope when refused. */
37
+ export function assertPdfSupported(ctx) {
38
+ if (ctx.mode === "attached") {
39
+ return {
40
+ error: "pdf_save: not supported on attached / BYOB sessions — page.pdf() " +
41
+ "drives Chromium's PrintToPDF and would surface a print dialog / " +
42
+ "mutate the human's Chrome window state",
43
+ hint: 'open a managed session (open_session({mode:"persistent"}) or ' +
44
+ '{mode:"incognito"}) and re-run pdf_save against that.',
45
+ };
46
+ }
47
+ return null;
48
+ }
49
+ /** Default output path when the caller doesn't supply one. Workspace-rooted
50
+ * under `pdfs/<sessionId>-<ts>.pdf` — matches the `perf_stop` /
51
+ * `start_har` "subdir per artefact kind" convention. */
52
+ export function defaultPdfPath(sessionId) {
53
+ // Sanitise sessionId for filesystem use (the registry already constrains
54
+ // ids to a safe character set; this is belt-and-braces against future
55
+ // changes there). Same posture as `defaultTracePath`.
56
+ const safe = sessionId.replace(/[^A-Za-z0-9._-]/g, "_") || "default";
57
+ const ts = new Date().toISOString().replace(/[:.]/g, "-");
58
+ return `pdfs/${safe}-${ts}.pdf`;
59
+ }
60
+ /** Write `page.pdf()` to a workspace-rooted path. The caller has already
61
+ * verified the session mode supports PDF (`assertPdfSupported`); this layer
62
+ * resolves the path, validates inputs, and dispatches to Playwright.
63
+ *
64
+ * Throws on:
65
+ * - `path` escaping `$BROWX_WORKSPACE` (via `resolveWorkspacePath`).
66
+ * - `scale` outside `[0.1, 2.0]`.
67
+ * - Underlying `page.pdf()` failure (re-thrown with original message). */
68
+ export async function pdfSave(page, workspaceRoot, sessionId, args = {}) {
69
+ const format = args.format ?? "A4";
70
+ const scale = args.scale ?? 1;
71
+ const printBackground = args.printBackground ?? false;
72
+ if (scale < 0.1 || scale > 2.0) {
73
+ throw new Error(`pdf_save: scale must be in [0.1, 2.0] — got ${scale}. ` +
74
+ `Playwright's page.pdf() clamps the value at the underlying CDP layer; ` +
75
+ `we reject up-front for a clearer error.`);
76
+ }
77
+ const relPath = args.path ?? defaultPdfPath(sessionId);
78
+ const resolved = resolveWorkspacePath(workspaceRoot, relPath, "pdf_save");
79
+ const fsMod = await import("node:fs");
80
+ const pathMod = await import("node:path");
81
+ // Ensure parent dir exists — `resolved` is rooted in BROWX_WORKSPACE by
82
+ // construction (resolveWorkspacePath rejects escapes); Playwright's
83
+ // `page.pdf({path})` writes synchronously and fails if the dir is missing.
84
+ fsMod.mkdirSync(pathMod.dirname(resolved), { recursive: true });
85
+ await page.pdf({
86
+ path: resolved,
87
+ format,
88
+ scale,
89
+ printBackground,
90
+ });
91
+ let bytes = 0;
92
+ try {
93
+ bytes = statSync(resolved).size;
94
+ }
95
+ catch {
96
+ /* best-effort */
97
+ }
98
+ // Belt-and-braces: re-run resolve to surface the absolute path in the
99
+ // result (the input may have been relative).
100
+ const absolute = resolvePath(resolved);
101
+ return {
102
+ ok: true,
103
+ path: absolute,
104
+ bytes,
105
+ format,
106
+ scale,
107
+ printBackground,
108
+ };
109
+ }
@@ -0,0 +1,40 @@
1
+ import type { AuditContext, CategoryResult } from "./perf-audit-types.js";
2
+ /** The audit category registry — the ONE place a category is declared. Each
3
+ * key is a category name; each value is its analyser. `as const satisfies`
4
+ * pins the keys as string literals (so `AuditCategory` derives a closed union)
5
+ * while still type-checking every value against the analyser signature.
6
+ *
7
+ * Order is meaningful — issues are surfaced in this order when severity ties. */
8
+ export declare const ANALYSERS: {
9
+ readonly "render-blocking": typeof analyseRenderBlocking;
10
+ readonly "unused-code": typeof analyseUnusedCode;
11
+ readonly "oversize-images": typeof analyseOversizeImages;
12
+ readonly "layout-thrashing": typeof analyseLayoutThrashing;
13
+ readonly "long-tasks": typeof analyseLongTasks;
14
+ readonly "leak-suspects": typeof analyseLeakSuspects;
15
+ readonly "cache-opportunities": typeof analyseCacheOpportunities;
16
+ readonly "font-loading": typeof analyseFontLoading;
17
+ };
18
+ /** The closed audit-category vocabulary — DERIVED from `ANALYSERS`'s keys, never
19
+ * hand-listed. A category exists iff it has an analyser. */
20
+ export type AuditCategory = keyof typeof ANALYSERS;
21
+ /** Every audit category, in declaration order — DERIVED from `ANALYSERS`. The
22
+ * `Object.keys` cast is sound because the keys ARE the `AuditCategory` union. */
23
+ export declare const ALL_AUDIT_CATEGORIES: AuditCategory[];
24
+ export declare function analyseRenderBlocking(ctx: AuditContext): CategoryResult;
25
+ /** unused-code — scripts + CSS files with `usagePercent < 30`. Severity tied
26
+ * to absolute waste (bytes), not percent, because a 90%-dead 2KB file
27
+ * doesn't matter. */
28
+ export declare function analyseUnusedCode(ctx: AuditContext): CategoryResult;
29
+ /** oversize-images — images > 500KB. */
30
+ export declare function analyseOversizeImages(ctx: AuditContext): CategoryResult;
31
+ /** layout-thrashing — > 5 forced sync layouts. */
32
+ export declare function analyseLayoutThrashing(ctx: AuditContext): CategoryResult;
33
+ /** long-tasks — `RunTask` events > 50ms. */
34
+ export declare function analyseLongTasks(ctx: AuditContext): CategoryResult;
35
+ /** leak-suspects — retainer-growth rows with deltaPercent > 10. */
36
+ export declare function analyseLeakSuspects(ctx: AuditContext): CategoryResult;
37
+ /** cache-opportunities — static assets missing `Cache-Control` header. */
38
+ export declare function analyseCacheOpportunities(ctx: AuditContext): CategoryResult;
39
+ /** font-loading — fonts loaded > 200ms after document start. */
40
+ export declare function analyseFontLoading(ctx: AuditContext): CategoryResult;