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,325 @@
1
+ import { requireCdp } from "../engine/index.js";
2
+ import { estimateTokens } from "../util/tokens.js";
3
+ import { runLayoutThrashTrace } from "../page/layout-thrash.js";
4
+ import { diffHeapSnapshots } from "../page/memory-diff.js";
5
+ import { takeHeapSnapshot, defaultHeapSnapshotPath, writeHeapSnapshotFile, readHeapSnapshotFile, queryRetainers, } from "../page/heap.js";
6
+ import { SESSION_ARG } from "./schemas.js";
7
+ /**
8
+ * Deep tools — coverage, layout-thrash, and V8 heap. `coverage_start` /
9
+ * `coverage_stop`, `layout_thrash_trace`, `memory_diff`, `heap_snapshot`, and
10
+ * `heap_retainers`. All CDP-deep (refused off Chromium). Registered through the
11
+ * shared `ToolHost` seam.
12
+ */
13
+ export function registerDeepCoverageTools(host) {
14
+ const { z, register, gateCheck, engineGate, entryFor, workspace } = host;
15
+ register("coverage_start", {
16
+ capability: "action",
17
+ batchable: true,
18
+ deep: true,
19
+ description: "Arm precise JS + CSS coverage tracking on this session — wraps CDP `Profiler.startPreciseCoverage` (per-script byte-level use counts) + `CSS.startRuleUsageTracking` (per-stylesheet rule-level use counts) in lockstep. Use to identify dead JS + dead CSS that ships but boot never executes. Pairs with `coverage_stop` (returns the parsed report). Per-session; one lifecycle in flight at a time. **Idempotent restart:** calling `coverage_start` while a tracker is already running cleanly stops the in-flight one (results discarded) and starts fresh. Captures stylesheet metadata (URL + length) via the `CSS.styleSheetAdded` event stream during the tracking window. Capability `action` (mutates target state). The audit tool `perf_audit` calls this internally — only use the direct primitives when you want the raw report or want a longer window than the audit's default.",
20
+ inputSchema: {
21
+ ...SESSION_ARG,
22
+ },
23
+ }, async ({ session }) => {
24
+ const g = gateCheck("coverage_start");
25
+ if (g)
26
+ return g;
27
+ const e = await entryFor(session);
28
+ const eg = engineGate("coverage_start", e);
29
+ if (eg)
30
+ return eg;
31
+ try {
32
+ const r = await e.coverage.start(requireCdp(e.session));
33
+ const body = {
34
+ ok: true,
35
+ running: true,
36
+ startedAt: r.startedAt,
37
+ restarted: r.restarted,
38
+ hint: "Drive your action(s), then call coverage_stop to get the {jsCoverage, cssCoverage} report.",
39
+ };
40
+ if (r.restarted) {
41
+ body.warning =
42
+ "A prior coverage_start was still active — it has been cleanly stopped (results discarded) and a fresh tracker started.";
43
+ }
44
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
45
+ return {
46
+ content: [
47
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
48
+ ],
49
+ };
50
+ }
51
+ catch (err) {
52
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
53
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
54
+ return {
55
+ content: [
56
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
57
+ ],
58
+ };
59
+ }
60
+ });
61
+ register("coverage_stop", {
62
+ capability: "read",
63
+ batchable: true,
64
+ deep: true,
65
+ description: "Stop precise JS + CSS coverage tracking and return the parsed report. Calls `Profiler.takePreciseCoverage` + `CSS.stopRuleUsageTracking` then aggregates the raw byte-range output into per-script + per-stylesheet entries. Returns `{ok, jsCoverage:[{url, totalBytes, usedBytes, usagePercent, deadRanges?}], cssCoverage:[{url, totalBytes, usedBytes, usedRules, totalRules, usagePercent, deadRules?}], durationMs}`. `usagePercent` is the agent's scan metric — `<30` indicates substantial dead code (the audit's `unused-code` analyser flags it). `deadRanges` / `deadRules` are top-50 byte ranges per file. **Safe to call any number of times:** if no tracker is running, returns `notRunning:true` rather than an error. Pure parsing + composition past the CDP fetches — no file written; the caller decides whether to persist the report. Capability `read`.",
66
+ inputSchema: {
67
+ ...SESSION_ARG,
68
+ },
69
+ }, async ({ session }) => {
70
+ const g = gateCheck("coverage_stop");
71
+ if (g)
72
+ return g;
73
+ const e = await entryFor(session);
74
+ const eg = engineGate("coverage_stop", e);
75
+ if (eg)
76
+ return eg;
77
+ try {
78
+ const r = await e.coverage.stop(requireCdp(e.session));
79
+ if (r.notRunning) {
80
+ const body = {
81
+ ok: true,
82
+ notRunning: true,
83
+ hint: "No coverage was active for this session — coverage_stop is idempotent; call coverage_start first.",
84
+ };
85
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
86
+ return {
87
+ content: [
88
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
89
+ ],
90
+ };
91
+ }
92
+ const body = {
93
+ ok: true,
94
+ jsCoverage: r.jsCoverage,
95
+ cssCoverage: r.cssCoverage,
96
+ durationMs: r.durationMs,
97
+ };
98
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
99
+ return {
100
+ content: [
101
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
102
+ ],
103
+ };
104
+ }
105
+ catch (err) {
106
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
107
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
108
+ return {
109
+ content: [
110
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
111
+ ],
112
+ };
113
+ }
114
+ });
115
+ register("layout_thrash_trace", {
116
+ capability: "read",
117
+ batchable: true,
118
+ deep: true,
119
+ description: 'Record a focused CDP trace for `durationMs` (default 5000, max 30000) that captures forced synchronous layouts + LayoutShift + Recalc Style events, then aggregate by originating call-stack so the agent sees `"this rAF loop fired 200 forced layouts"` at a glance instead of paging through a 100MB chromium trace. Returns `{ok, forcedLayoutsCount, layoutShiftsCount, eventsByOrigin:[{originatingStack, count, totalDurationMs}], tracePath, durationMs}`. `originatingStack` reads from the trace\'s `stackTrace` field on each event (chromium populates it when DevTools is attached) — `"<anonymous>"` when no stack was attached. `tracePath` is a workspace-rooted JSON file under `<workspace>/perf/<sessionId>-layout-thrash-<ts>.json` — loadable in DevTools\' Performance panel for the full visual. Capped at the top 50 origins, sorted by count desc. Capability `read`.',
120
+ inputSchema: {
121
+ durationMs: z
122
+ .number()
123
+ .int()
124
+ .positive()
125
+ .max(30_000)
126
+ .optional()
127
+ .describe("Trace recording window in ms. Default 5000, max 30000."),
128
+ ...SESSION_ARG,
129
+ },
130
+ }, async ({ durationMs, session }) => {
131
+ const g = gateCheck("layout_thrash_trace");
132
+ if (g)
133
+ return g;
134
+ const e = await entryFor(session);
135
+ const eg = engineGate("layout_thrash_trace", e);
136
+ if (eg)
137
+ return eg;
138
+ try {
139
+ const r = await runLayoutThrashTrace(requireCdp(e.session), workspace.root, e.id, {
140
+ durationMs,
141
+ });
142
+ const body = {
143
+ ok: true,
144
+ forcedLayoutsCount: r.forcedLayoutsCount,
145
+ layoutShiftsCount: r.layoutShiftsCount,
146
+ eventsByOrigin: r.eventsByOrigin,
147
+ tracePath: r.tracePath,
148
+ durationMs: r.durationMs,
149
+ };
150
+ if (e.mode === "attached") {
151
+ body.warning =
152
+ "BYOB / attached Chrome: trace buffer on the human's Chrome has been released. The JSON file remains under $BROWX_WORKSPACE.";
153
+ }
154
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
155
+ return {
156
+ content: [
157
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
158
+ ],
159
+ };
160
+ }
161
+ catch (err) {
162
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
163
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
164
+ return {
165
+ content: [
166
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
167
+ ],
168
+ };
169
+ }
170
+ });
171
+ register("memory_diff", {
172
+ capability: "read",
173
+ batchable: true,
174
+ deep: true,
175
+ description: "Diff two V8 heap snapshots (paths to existing `.heapsnapshot` files from `heap_snapshot`) and report retainer growth per node-type group. Pure function — no browser interaction; no CDP touch; reads + parses two existing JSON-shaped V8 heap snapshots on disk and emits the structured diff. **Inputs:** `beforePath` + `afterPath`, both workspace-rooted (path-escape rejected). **Output:** `{ok, retainerGrowth:[{node, type, sizeBefore, sizeAfter, deltaBytes, deltaPercent}], summary:{totalGrowth, top3Growers}}`. `node` is the V8 `${type}:${name}` display (matches `heap_retainers`'s shape). Groups whose `|deltaBytes| < 1024` are dropped as noise. Sorted by `deltaBytes` desc, capped at 100 rows. Typical leak-detection flow: `heap_snapshot` (before suspect interaction) → drive the action → `heap_snapshot` (after) → `memory_diff({beforePath, afterPath})`. The audit's `leak-suspects` analyser consumes this shape directly. Capability `read`.",
176
+ inputSchema: {
177
+ beforePath: z
178
+ .string()
179
+ .describe("Workspace-rooted path to a `.heapsnapshot` file (the 'before' snapshot)."),
180
+ afterPath: z
181
+ .string()
182
+ .describe("Workspace-rooted path to a `.heapsnapshot` file (the 'after' snapshot)."),
183
+ ...SESSION_ARG,
184
+ },
185
+ }, async ({ beforePath, afterPath, session: _session }) => {
186
+ const g = gateCheck("memory_diff");
187
+ if (g)
188
+ return g;
189
+ // Pure file read + parse — no session touch required. SESSION_ARG
190
+ // honoured for surface consistency with the sibling `perf_insights`.
191
+ try {
192
+ const r = diffHeapSnapshots(workspace.root, beforePath, afterPath, "memory_diff");
193
+ const body = {
194
+ ok: true,
195
+ retainerGrowth: r.retainerGrowth,
196
+ summary: r.summary,
197
+ };
198
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
199
+ return {
200
+ content: [
201
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
202
+ ],
203
+ };
204
+ }
205
+ catch (err) {
206
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
207
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
208
+ return {
209
+ content: [
210
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
211
+ ],
212
+ };
213
+ }
214
+ });
215
+ // -------- V8 heap snapshots --------
216
+ register("heap_snapshot", {
217
+ capability: "action",
218
+ batchable: true,
219
+ deep: true,
220
+ description: "Take a V8 heap snapshot on this session's target — wraps CDP `HeapProfiler.takeHeapSnapshot`. The output file is the same `.heapsnapshot` JSON DevTools' Memory panel and `chrome://inspect` consume on drag-and-drop. Use to diagnose memory leaks: pair with `heap_retainers({snapshotPath, query})` to ask \"who's still pointing to objects named X / typed Y\" — the answer is invisible in `snapshot` / `find` because the leaked nodes are no longer in the DOM. Per-session; one-shot (a heap snapshot is a point-in-time capture, not a recording window). Default file path: `<workspace>/heap-snapshots/<sessionId>-<ts>.heapsnapshot` — explicit `path` is rejected if it escapes `$BROWX_WORKSPACE`. Snapshots are heavy (often tens to hundreds of MiB on a real page); don't take them in a tight loop.",
221
+ inputSchema: {
222
+ path: z
223
+ .string()
224
+ .optional()
225
+ .describe("Workspace-rooted output path for the .heapsnapshot file. Default: <workspace>/heap-snapshots/<sessionId>-<ts>.heapsnapshot. Rejected if it escapes $BROWX_WORKSPACE."),
226
+ ...SESSION_ARG,
227
+ },
228
+ }, async ({ path, session }) => {
229
+ const g = gateCheck("heap_snapshot");
230
+ if (g)
231
+ return g;
232
+ const e = await entryFor(session);
233
+ const eg = engineGate("heap_snapshot", e);
234
+ if (eg)
235
+ return eg;
236
+ try {
237
+ const snapshotJson = await takeHeapSnapshot(requireCdp(e.session));
238
+ const targetPath = path ?? defaultHeapSnapshotPath(workspace.root, e.id);
239
+ const written = writeHeapSnapshotFile(workspace.root, targetPath, snapshotJson, "heap_snapshot");
240
+ const body = {
241
+ ok: true,
242
+ path: written.resolved,
243
+ bytes: written.bytes,
244
+ hint: "Call heap_retainers({snapshotPath, query:{name|type}}) to find what's holding suspect objects alive. Drag-and-drop this file onto chrome://inspect's Memory panel for the full interactive view.",
245
+ };
246
+ if (e.mode === "attached") {
247
+ body.warning =
248
+ "BYOB / attached Chrome: the snapshot was captured against the human's Chrome. The .heapsnapshot file remains under $BROWX_WORKSPACE.";
249
+ }
250
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
251
+ return {
252
+ content: [
253
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
254
+ ],
255
+ };
256
+ }
257
+ catch (err) {
258
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
259
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
260
+ return {
261
+ content: [
262
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
263
+ ],
264
+ };
265
+ }
266
+ });
267
+ register("heap_retainers", {
268
+ capability: "action",
269
+ batchable: true,
270
+ deep: true,
271
+ description: 'Run a retainer query against a written `.heapsnapshot` file. Returns the top retainers (sorted by retainer self-size desc, capped at 50) of nodes whose display name and/or V8 type matches the query — directly answers "who\'s holding these objects alive?" without paging through DevTools\' Memory panel. Pure file read + in-process parse, no CDP touch. `query.name` defaults to exact match against the node\'s string-table name (use `nameMatch:"substring"` for containment); `query.type` filters by V8 node-type (`"closure"`, `"object"`, `"hidden"`, …). At least one of `name` / `type` is required — a match-everything query is never the right answer. `snapshotPath` is workspace-rooted; rejected if it escapes `$BROWX_WORKSPACE`. Same JSON format `heap_snapshot` writes — bring-your-own snapshot (downloaded from DevTools, saved by a CI run) works too.',
272
+ inputSchema: {
273
+ snapshotPath: z
274
+ .string()
275
+ .describe("Workspace-rooted path to a .heapsnapshot file (the path returned by heap_snapshot)."),
276
+ query: z
277
+ .object({
278
+ name: z
279
+ .string()
280
+ .optional()
281
+ .describe('Match against the V8 string-table name of a node (e.g. "Cache", "MyLeakyClass").'),
282
+ type: z
283
+ .string()
284
+ .optional()
285
+ .describe('Match against V8 node-type (e.g. "closure", "object", "hidden").'),
286
+ nameMatch: z
287
+ .enum(["exact", "substring"])
288
+ .optional()
289
+ .describe('Default "exact". Use "substring" for containment matching against `name`.'),
290
+ })
291
+ .describe("At least one of `name` or `type` is required."),
292
+ ...SESSION_ARG,
293
+ },
294
+ }, async ({ snapshotPath, query, session: _session }) => {
295
+ const g = gateCheck("heap_retainers");
296
+ if (g)
297
+ return g;
298
+ // Pure file read + parse — no session touch needed. We still honour
299
+ // SESSION_ARG for consistency with the sibling `perf_insights`.
300
+ try {
301
+ const { parsed, resolved } = readHeapSnapshotFile(workspace.root, snapshotPath, "heap_retainers");
302
+ const result = queryRetainers(parsed, query);
303
+ const body = {
304
+ ok: true,
305
+ snapshotPath: resolved,
306
+ ...result,
307
+ };
308
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
309
+ return {
310
+ content: [
311
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
312
+ ],
313
+ };
314
+ }
315
+ catch (err) {
316
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
317
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
318
+ return {
319
+ content: [
320
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
321
+ ],
322
+ };
323
+ }
324
+ });
325
+ }
@@ -0,0 +1,8 @@
1
+ import type { ToolHost } from "./host.js";
2
+ /**
3
+ * Deep tools — determinism injection & compound network waits. `clock` (virtual
4
+ * time), `seed_random` (deterministic Math.random), `act_and_wait_for_network`
5
+ * (one action then a settle-window), and `poll_eval`. Registered through the
6
+ * shared `ToolHost` seam.
7
+ */
8
+ export declare function registerDeepDeterminismTools(host: ToolHost): void;
@@ -0,0 +1,276 @@
1
+ import { requireCdp } from "../engine/index.js";
2
+ import { withDeadline } from "../util/deadline.js";
3
+ import { estimateTokens } from "../util/tokens.js";
4
+ import { matchesResponse } from "../page/await_network.js";
5
+ import { sanitizeUrl } from "../util/url-sanitizer.js";
6
+ import { SESSION_ARG } from "./schemas.js";
7
+ /** Wrap a JSON body as a tool text response — the shape the determinism handlers
8
+ * return. */
9
+ function determinismJson(body) {
10
+ return { content: [{ type: "text", text: JSON.stringify(body, null, 2) }] };
11
+ }
12
+ /** A structured `{ok:false, error}` envelope. */
13
+ function determinismJsonError(error) {
14
+ return determinismJson({ ok: false, error });
15
+ }
16
+ /**
17
+ * Deep tools — determinism injection & compound network waits. `clock` (virtual
18
+ * time), `seed_random` (deterministic Math.random), `act_and_wait_for_network`
19
+ * (one action then a settle-window), and `poll_eval`. Registered through the
20
+ * shared `ToolHost` seam.
21
+ */
22
+ export function registerDeepDeterminismTools(host) {
23
+ const { z, register, gateCheck, engineGate, entryFor, batchAllowedTools: BATCH_ALLOWED_TOOLS, toolHandlers, } = host;
24
+ register("clock", {
25
+ capability: "action",
26
+ batchable: true,
27
+ deep: true,
28
+ description: 'Control the page\'s virtual clock via CDP `Emulation.setVirtualTimePolicy` — deterministic testing of date-sensitive flows (renewal dates, "today" filters, scheduling, expiry edges) without changing the OS clock. Three modes: `freeze` pauses virtual time at `atIso` (or wall-clock now if omitted); `advance` jumps the clock by `byMs` or to an absolute `atIso`, then re-pins; `release` resumes real time. Per-session; persists across navigation (re-applied on main-frame nav in case CDP drops it). Independent of `network_emulate` / `cpu_emulate` — compose freely. **BYOB:** the policy stays in effect on the attached Chrome until released, reloaded, or closed; a `warning` field surfaces this in `attached` mode.',
29
+ inputSchema: {
30
+ mode: z
31
+ .enum(["freeze", "advance", "release"])
32
+ .describe("freeze: pause virtual time at `atIso` (or now). advance: jump by `byMs` or to `atIso`. release: resume real time."),
33
+ atIso: z
34
+ .string()
35
+ .optional()
36
+ .describe("ISO-8601 instant. freeze → pin time here; advance → jump to this absolute instant. Mutually exclusive with `byMs` on advance."),
37
+ byMs: z
38
+ .number()
39
+ .int()
40
+ .positive()
41
+ .max(365 * 24 * 60 * 60 * 1000)
42
+ .optional()
43
+ .describe("Advance only — relative jump in ms (max 1 year). Mutually exclusive with `atIso`."),
44
+ ...SESSION_ARG,
45
+ },
46
+ }, async ({ mode, atIso, byMs, session }) => {
47
+ const g = gateCheck("clock");
48
+ if (g)
49
+ return g;
50
+ const e = await entryFor(session);
51
+ const eg = engineGate("clock", e);
52
+ if (eg)
53
+ return eg;
54
+ try {
55
+ const { state, mode: appliedMode, appliedAtIso, } = await e.clock.apply(requireCdp(e.session), e.session.page(), { mode, atIso, byMs });
56
+ const body = {
57
+ ok: true,
58
+ applied: {
59
+ mode: appliedMode,
60
+ nowIso: appliedAtIso,
61
+ paused: state?.paused ?? false,
62
+ },
63
+ };
64
+ if (e.mode === "attached") {
65
+ body.warning =
66
+ 'BYOB / attached Chrome: this virtual-clock policy stays in effect on the attached browser even after browxai detaches — release it (mode:"release"), reload, or close the page when you\'re done. A page with a frozen wall clock is a debugging trap.';
67
+ }
68
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
69
+ return {
70
+ content: [
71
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
72
+ ],
73
+ };
74
+ }
75
+ catch (err) {
76
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
77
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
78
+ return {
79
+ content: [
80
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
81
+ ],
82
+ };
83
+ }
84
+ });
85
+ register("seed_random", {
86
+ capability: "action",
87
+ batchable: true,
88
+ description: "Override the page's `Math.random` with a deterministic Mulberry32 PRNG seeded from `seed`. For flake-repros where unseeded randomness drives id generation, dice / card / A-B picks, or jittered retry timing. Injected via Playwright `addInitScript`, so every new document in the session — including subsequent navigations — bootstraps the same override; the current page's main realm is re-seeded immediately so the effect is visible without navigating. Per-session; persists across navigation (re-applied on main-frame `framenavigated` for symmetry with `network_emulate` / `clock`). **MVP scope:** only `Math.random` is overridden — `crypto.randomUUID` / `crypto.getRandomValues` are NOT touched (web-crypto is a much bigger deterministic-stub surface; revisit later). Workers are out of scope (the init script runs in document realms, not worker realms). **BYOB:** the override is installed on the attached Chrome's context for as long as the context lives; surfaced as a `warning` in `attached` session mode.",
89
+ inputSchema: {
90
+ seed: z
91
+ .number()
92
+ .int()
93
+ .min(0)
94
+ .max(0xffffffff)
95
+ .describe("Non-negative integer in [0, 2^32 - 1]. The Mulberry32 state domain — 0 is valid."),
96
+ ...SESSION_ARG,
97
+ },
98
+ }, async ({ seed, session }) => {
99
+ const g = gateCheck("seed_random");
100
+ if (g)
101
+ return g;
102
+ const e = await entryFor(session);
103
+ try {
104
+ const { state } = await e.seededRandom.apply(e.session.page().context(), e.session.page(), {
105
+ seed,
106
+ });
107
+ const body = { ok: true, applied: state };
108
+ if (e.mode === "attached") {
109
+ body.warning =
110
+ "BYOB / attached Chrome: this Math.random override is installed on the attached browser's context and stays in effect for as long as the context lives — close the tab / context when you're done to drop it.";
111
+ }
112
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
113
+ return {
114
+ content: [
115
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
116
+ ],
117
+ };
118
+ }
119
+ catch (err) {
120
+ const body = { ok: false, error: err instanceof Error ? err.message : String(err) };
121
+ const tokensEstimate = estimateTokens(JSON.stringify(body));
122
+ return {
123
+ content: [
124
+ { type: "text", text: JSON.stringify({ ...body, tokensEstimate }, null, 2) },
125
+ ],
126
+ };
127
+ }
128
+ });
129
+ register("act_and_wait_for_network", {
130
+ capability: "read",
131
+ description: "Run ONE action and wait for a specific network response to complete — async SPAs fire follow-up requests after the action-result window, so `ActionResult.network` misses them. The waiter is armed BEFORE the action dispatches (no race). `action` is `{tool,args}` from the batch whitelist. `match` selects the response: `urlPattern` (case-insensitive substring), `method`, `status` — at least one required. Returns `{ action: <inner result>, network: { matched, method?, url?, status? } }` (url redacted, same as `network_read`). `timeoutMs` is the max wait (default 10000).",
132
+ inputSchema: {
133
+ action: z.object({
134
+ tool: z.string().describe("Inner tool name (batch whitelist)."),
135
+ args: z.record(z.unknown()).optional(),
136
+ }),
137
+ match: z
138
+ .object({
139
+ urlPattern: z
140
+ .string()
141
+ .optional()
142
+ .describe("Case-insensitive substring of the request URL."),
143
+ method: z.string().optional(),
144
+ status: z.number().int().optional(),
145
+ })
146
+ .describe("At least one field required."),
147
+ timeoutMs: z
148
+ .number()
149
+ .int()
150
+ .positive()
151
+ .max(120_000)
152
+ .optional()
153
+ .describe("Max wait for the matching response (default 10000)."),
154
+ ...SESSION_ARG,
155
+ },
156
+ }, async (args) => {
157
+ const g = gateCheck("act_and_wait_for_network");
158
+ if (g)
159
+ return g;
160
+ const innerTool = args.action.tool;
161
+ if (!BATCH_ALLOWED_TOOLS.has(innerTool) || innerTool === "act_and_wait_for_network") {
162
+ return determinismJsonError(`act_and_wait_for_network: inner tool "${innerTool}" not allowed (batch whitelist; no batch / await_human / recording / self)`);
163
+ }
164
+ const ig = gateCheck(innerTool);
165
+ if (ig)
166
+ return ig;
167
+ if (args.match.urlPattern === undefined &&
168
+ args.match.method === undefined &&
169
+ args.match.status === undefined) {
170
+ return determinismJsonError("act_and_wait_for_network: `match` needs at least one of urlPattern / method / status");
171
+ }
172
+ const e = await entryFor(args.session);
173
+ const timeout = args.timeoutMs ?? 10_000;
174
+ const parseInner = (resp) => {
175
+ const first = resp.content[0];
176
+ if (!first || first.type !== "text" || first.text === undefined)
177
+ return first ?? null;
178
+ try {
179
+ return JSON.parse(first.text);
180
+ }
181
+ catch {
182
+ return first.text;
183
+ }
184
+ };
185
+ // arm the waiter BEFORE dispatching the action so a fast response can't slip past.
186
+ const waitP = e.session
187
+ .page()
188
+ .waitForResponse((r) => matchesResponse({ url: r.url(), method: r.request().method(), status: r.status() }, args.match), { timeout })
189
+ .then((r) => ({
190
+ matched: true,
191
+ method: r.request().method(),
192
+ url: sanitizeUrl(r.url()),
193
+ status: r.status(),
194
+ }), () => ({ matched: false }));
195
+ const innerArgs = { ...(args.action.args ?? {}), session: args.session };
196
+ const [aRes, network] = await Promise.all([toolHandlers[innerTool](innerArgs), waitP]);
197
+ return {
198
+ content: [
199
+ {
200
+ type: "text",
201
+ text: JSON.stringify({ action: parseInner(aRes), network }, null, 2),
202
+ },
203
+ ],
204
+ };
205
+ });
206
+ register("poll_eval", {
207
+ capability: "eval",
208
+ description: "Repeatedly evaluate a JS expression in the page until it returns a truthy value or `timeoutMs` elapses — for waiting on async job completion / store updates without ad-hoc in-page loops (a long in-page promise would trip the anti-wedge deadline). The value is page-controlled — treat it as untrusted, like `eval_js`. Capability: `eval`. Returns `{ ok, truthy, value, polls, elapsedMs, timedOut }`.",
209
+ inputSchema: {
210
+ expr: z
211
+ .string()
212
+ .describe("JS expression; must be JSON-serializable. Wrap statements in `(() => { … })()`."),
213
+ intervalMs: z
214
+ .number()
215
+ .int()
216
+ .min(50)
217
+ .max(10_000)
218
+ .optional()
219
+ .describe("Poll interval (default 250, min 50)."),
220
+ timeoutMs: z
221
+ .number()
222
+ .int()
223
+ .positive()
224
+ .max(120_000)
225
+ .optional()
226
+ .describe("Total budget (default 5000)."),
227
+ ...SESSION_ARG,
228
+ },
229
+ }, async ({ expr, intervalMs, timeoutMs, session }) => {
230
+ const g = gateCheck("poll_eval");
231
+ if (g)
232
+ return g;
233
+ const s = (await entryFor(session)).session;
234
+ const interval = intervalMs ?? 250;
235
+ const budget = timeoutMs ?? 5000;
236
+ const perPoll = Math.min(budget, 5000);
237
+ const start = Date.now();
238
+ let polls = 0;
239
+ let value;
240
+ while (Date.now() - start < budget) {
241
+ polls++;
242
+ try {
243
+ value = await withDeadline(s.page().evaluate(expr), perPoll, "poll_eval");
244
+ }
245
+ catch (err) {
246
+ return determinismJson({
247
+ ok: false,
248
+ error: err instanceof Error ? err.message : String(err),
249
+ polls,
250
+ elapsedMs: Date.now() - start,
251
+ });
252
+ }
253
+ if (value) {
254
+ return determinismJson({
255
+ ok: true,
256
+ truthy: true,
257
+ value,
258
+ polls,
259
+ elapsedMs: Date.now() - start,
260
+ timedOut: false,
261
+ });
262
+ }
263
+ if (Date.now() - start + interval >= budget)
264
+ break;
265
+ await new Promise((r) => setTimeout(r, interval));
266
+ }
267
+ return determinismJson({
268
+ ok: true,
269
+ truthy: false,
270
+ value,
271
+ polls,
272
+ elapsedMs: Date.now() - start,
273
+ timedOut: true,
274
+ });
275
+ });
276
+ }
@@ -0,0 +1,19 @@
1
+ import type { ToolHost } from "./host.js";
2
+ /**
3
+ * Deep-diagnostics tools — the heavyweight observation surface an agent reaches
4
+ * for when a flow is slow, leaky, or non-deterministic: performance tracing
5
+ * (perf_start / perf_stop / perf_insights), the orchestrated perf_audit, JS+CSS
6
+ * coverage, layout-thrash tracing, V8 heap snapshots + retainer / memory-diff
7
+ * queries, the virtual clock + seeded RNG determinism knobs, and the
8
+ * network-aware act_and_wait_for_network / poll_eval waiters. Every block is
9
+ * registered through the shared `ToolHost` seam; the host owns the closures
10
+ * (gate, engine-gate, session, workspace, batch dispatch), this module owns the
11
+ * registrations.
12
+ */
13
+ /**
14
+ * Deep tools — performance tracing & audit. `perf_start` / `perf_stop` (Chromium
15
+ * trace capture), `perf_insights` (post-hoc trace analysis), and `perf_audit`
16
+ * (the category-driven optimisation pass). All CDP-deep (refused off Chromium).
17
+ * Registered through the shared `ToolHost` seam.
18
+ */
19
+ export declare function registerDeepPerfTools(host: ToolHost): void;