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.
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/THIRD_PARTY_NOTICES.md +45 -0
- package/dist/cli/chrome.d.ts +1 -0
- package/dist/cli/chrome.js +130 -0
- package/dist/cli/command-registry.d.ts +15 -0
- package/dist/cli/command-registry.js +35 -0
- package/dist/cli/doctor-plugins.d.ts +18 -0
- package/dist/cli/doctor-plugins.js +338 -0
- package/dist/cli/doctor.d.ts +9 -0
- package/dist/cli/doctor.js +407 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +200 -0
- package/dist/cli/register-commands.d.ts +1 -0
- package/dist/cli/register-commands.js +22 -0
- package/dist/cli/serve.d.ts +14 -0
- package/dist/cli/serve.js +151 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +129 -0
- package/dist/engine/adapters/adb.d.ts +72 -0
- package/dist/engine/adapters/adb.js +200 -0
- package/dist/engine/adapters/android-cdp.d.ts +54 -0
- package/dist/engine/adapters/android-cdp.js +110 -0
- package/dist/engine/adapters/android.engine.d.ts +1 -0
- package/dist/engine/adapters/android.engine.js +31 -0
- package/dist/engine/adapters/chromium.engine.d.ts +1 -0
- package/dist/engine/adapters/chromium.engine.js +44 -0
- package/dist/engine/adapters/firefox.engine.d.ts +1 -0
- package/dist/engine/adapters/firefox.engine.js +43 -0
- package/dist/engine/adapters/playwright-chromium.d.ts +43 -0
- package/dist/engine/adapters/playwright-chromium.js +56 -0
- package/dist/engine/adapters/playwright-firefox.d.ts +52 -0
- package/dist/engine/adapters/playwright-firefox.js +97 -0
- package/dist/engine/adapters/playwright-webkit.d.ts +40 -0
- package/dist/engine/adapters/playwright-webkit.js +79 -0
- package/dist/engine/adapters/safari/bidi-client.d.ts +46 -0
- package/dist/engine/adapters/safari/bidi-client.js +130 -0
- package/dist/engine/adapters/safari/launch.d.ts +56 -0
- package/dist/engine/adapters/safari/launch.js +104 -0
- package/dist/engine/adapters/safari/webdriver-client.d.ts +102 -0
- package/dist/engine/adapters/safari/webdriver-client.js +175 -0
- package/dist/engine/adapters/safari.engine.d.ts +1 -0
- package/dist/engine/adapters/safari.engine.js +52 -0
- package/dist/engine/adapters/safaridriver-hybrid.d.ts +56 -0
- package/dist/engine/adapters/safaridriver-hybrid.js +127 -0
- package/dist/engine/adapters/webkit.engine.d.ts +1 -0
- package/dist/engine/adapters/webkit.engine.js +47 -0
- package/dist/engine/capabilities.d.ts +53 -0
- package/dist/engine/capabilities.js +122 -0
- package/dist/engine/capability-registry.d.ts +9 -0
- package/dist/engine/capability-registry.js +20 -0
- package/dist/engine/index.d.ts +18 -0
- package/dist/engine/index.js +14 -0
- package/dist/engine/register-engines.d.ts +5 -0
- package/dist/engine/register-engines.js +16 -0
- package/dist/engine/registry.d.ts +145 -0
- package/dist/engine/registry.js +67 -0
- package/dist/engine/select.d.ts +48 -0
- package/dist/engine/select.js +128 -0
- package/dist/engine/session-cdp.d.ts +13 -0
- package/dist/engine/session-cdp.js +22 -0
- package/dist/engine/tool-gate.d.ts +19 -0
- package/dist/engine/tool-gate.js +226 -0
- package/dist/engine/types.d.ts +71 -0
- package/dist/engine/types.js +16 -0
- package/dist/helper/bridge.d.ts +48 -0
- package/dist/helper/bridge.js +200 -0
- package/dist/helper/browx-page.d.ts +1 -0
- package/dist/helper/browx-page.js +47 -0
- package/dist/helper/overlay-hide.d.ts +9 -0
- package/dist/helper/overlay-hide.js +49 -0
- package/dist/helper/stealth.d.ts +10 -0
- package/dist/helper/stealth.js +88 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +15 -0
- package/dist/page/a11y.d.ts +81 -0
- package/dist/page/a11y.js +219 -0
- package/dist/page/action-substrate.d.ts +64 -0
- package/dist/page/action-substrate.js +118 -0
- package/dist/page/actionresult-blocks.d.ts +99 -0
- package/dist/page/actionresult-blocks.js +144 -0
- package/dist/page/actionresult-shape.d.ts +48 -0
- package/dist/page/actionresult-shape.js +155 -0
- package/dist/page/actionresult-types.d.ts +368 -0
- package/dist/page/actionresult-types.js +4 -0
- package/dist/page/actionresult.d.ts +4 -0
- package/dist/page/actionresult.js +299 -0
- package/dist/page/actions-probe.d.ts +32 -0
- package/dist/page/actions-probe.js +294 -0
- package/dist/page/actions-scroll.d.ts +40 -0
- package/dist/page/actions-scroll.js +53 -0
- package/dist/page/actions.d.ts +132 -0
- package/dist/page/actions.js +453 -0
- package/dist/page/archive-assets.d.ts +39 -0
- package/dist/page/archive-assets.js +187 -0
- package/dist/page/archive.d.ts +47 -0
- package/dist/page/archive.js +349 -0
- package/dist/page/asset-export.d.ts +122 -0
- package/dist/page/asset-export.js +376 -0
- package/dist/page/await_network.d.ts +16 -0
- package/dist/page/await_network.js +23 -0
- package/dist/page/bbox.d.ts +37 -0
- package/dist/page/bbox.js +115 -0
- package/dist/page/canvas-capture.d.ts +82 -0
- package/dist/page/canvas-capture.js +257 -0
- package/dist/page/canvas-diff.d.ts +51 -0
- package/dist/page/canvas-diff.js +131 -0
- package/dist/page/canvas-gesture.d.ts +53 -0
- package/dist/page/canvas-gesture.js +167 -0
- package/dist/page/canvas-transform.d.ts +96 -0
- package/dist/page/canvas-transform.js +150 -0
- package/dist/page/canvas.d.ts +8 -0
- package/dist/page/canvas.js +50 -0
- package/dist/page/capture-substrate.d.ts +111 -0
- package/dist/page/capture-substrate.js +139 -0
- package/dist/page/clipboard.d.ts +25 -0
- package/dist/page/clipboard.js +50 -0
- package/dist/page/clock.d.ts +36 -0
- package/dist/page/clock.js +167 -0
- package/dist/page/compose.d.ts +55 -0
- package/dist/page/compose.js +169 -0
- package/dist/page/console.d.ts +39 -0
- package/dist/page/console.js +73 -0
- package/dist/page/coverage.d.ts +97 -0
- package/dist/page/coverage.js +280 -0
- package/dist/page/dom-export.d.ts +41 -0
- package/dist/page/dom-export.js +193 -0
- package/dist/page/dom-walk.d.ts +91 -0
- package/dist/page/dom-walk.js +267 -0
- package/dist/page/dom_diff.d.ts +48 -0
- package/dist/page/dom_diff.js +121 -0
- package/dist/page/downloads.d.ts +80 -0
- package/dist/page/downloads.js +244 -0
- package/dist/page/drop-files.d.ts +78 -0
- package/dist/page/drop-files.js +310 -0
- package/dist/page/element-export-discovery.d.ts +64 -0
- package/dist/page/element-export-discovery.js +346 -0
- package/dist/page/element-export.d.ts +46 -0
- package/dist/page/element-export.js +251 -0
- package/dist/page/emulation-substrate.d.ts +53 -0
- package/dist/page/emulation-substrate.js +87 -0
- package/dist/page/emulation.d.ts +60 -0
- package/dist/page/emulation.js +162 -0
- package/dist/page/export-playwright-script.d.ts +47 -0
- package/dist/page/export-playwright-script.js +304 -0
- package/dist/page/extract-resolve.d.ts +22 -0
- package/dist/page/extract-resolve.js +341 -0
- package/dist/page/extract-schema.d.ts +20 -0
- package/dist/page/extract-schema.js +200 -0
- package/dist/page/extract-types.d.ts +127 -0
- package/dist/page/extract-types.js +8 -0
- package/dist/page/extract-warnings.d.ts +8 -0
- package/dist/page/extract-warnings.js +56 -0
- package/dist/page/extract.d.ts +9 -0
- package/dist/page/extract.js +174 -0
- package/dist/page/fill-form.d.ts +58 -0
- package/dist/page/fill-form.js +261 -0
- package/dist/page/find.d.ts +158 -0
- package/dist/page/find.js +470 -0
- package/dist/page/frames.d.ts +45 -0
- package/dist/page/frames.js +133 -0
- package/dist/page/generate-locator.d.ts +57 -0
- package/dist/page/generate-locator.js +136 -0
- package/dist/page/gestures.d.ts +128 -0
- package/dist/page/gestures.js +198 -0
- package/dist/page/har.d.ts +91 -0
- package/dist/page/har.js +174 -0
- package/dist/page/heap.d.ts +97 -0
- package/dist/page/heap.js +285 -0
- package/dist/page/inspect.d.ts +34 -0
- package/dist/page/inspect.js +75 -0
- package/dist/page/layout-thrash.d.ts +34 -0
- package/dist/page/layout-thrash.js +232 -0
- package/dist/page/learning.d.ts +21 -0
- package/dist/page/learning.js +84 -0
- package/dist/page/locator.d.ts +54 -0
- package/dist/page/locator.js +142 -0
- package/dist/page/memory-diff.d.ts +48 -0
- package/dist/page/memory-diff.js +105 -0
- package/dist/page/network-mask.d.ts +8 -0
- package/dist/page/network-mask.js +18 -0
- package/dist/page/network-playwright.d.ts +96 -0
- package/dist/page/network-playwright.js +353 -0
- package/dist/page/network-substrate-select.d.ts +18 -0
- package/dist/page/network-substrate-select.js +32 -0
- package/dist/page/network-substrate.d.ts +109 -0
- package/dist/page/network-substrate.js +161 -0
- package/dist/page/network-ws.d.ts +46 -0
- package/dist/page/network-ws.js +113 -0
- package/dist/page/network.d.ts +194 -0
- package/dist/page/network.js +415 -0
- package/dist/page/overflow-detect.d.ts +102 -0
- package/dist/page/overflow-detect.js +449 -0
- package/dist/page/pdf.d.ts +69 -0
- package/dist/page/pdf.js +109 -0
- package/dist/page/perf-audit-analysers.d.ts +40 -0
- package/dist/page/perf-audit-analysers.js +369 -0
- package/dist/page/perf-audit-runner.d.ts +20 -0
- package/dist/page/perf-audit-runner.js +195 -0
- package/dist/page/perf-audit-types.d.ts +41 -0
- package/dist/page/perf-audit-types.js +5 -0
- package/dist/page/perf-audit.d.ts +37 -0
- package/dist/page/perf-audit.js +377 -0
- package/dist/page/perf.d.ts +127 -0
- package/dist/page/perf.js +373 -0
- package/dist/page/plan.d.ts +192 -0
- package/dist/page/plan.js +308 -0
- package/dist/page/point_probe.d.ts +46 -0
- package/dist/page/point_probe.js +99 -0
- package/dist/page/recording.d.ts +67 -0
- package/dist/page/recording.js +172 -0
- package/dist/page/refs.d.ts +92 -0
- package/dist/page/refs.js +134 -0
- package/dist/page/regions.d.ts +23 -0
- package/dist/page/regions.js +32 -0
- package/dist/page/routes.d.ts +40 -0
- package/dist/page/routes.js +87 -0
- package/dist/page/safari-actions.d.ts +12 -0
- package/dist/page/safari-actions.js +144 -0
- package/dist/page/sample.d.ts +64 -0
- package/dist/page/sample.js +216 -0
- package/dist/page/screenshot-on.d.ts +51 -0
- package/dist/page/screenshot-on.js +150 -0
- package/dist/page/screenshot-save.d.ts +36 -0
- package/dist/page/screenshot-save.js +53 -0
- package/dist/page/screenshot-schedule.d.ts +50 -0
- package/dist/page/screenshot-schedule.js +155 -0
- package/dist/page/script-substrate.d.ts +32 -0
- package/dist/page/script-substrate.js +47 -0
- package/dist/page/seed-random.d.ts +45 -0
- package/dist/page/seed-random.js +144 -0
- package/dist/page/set-of-marks.d.ts +96 -0
- package/dist/page/set-of-marks.js +245 -0
- package/dist/page/shadow.d.ts +136 -0
- package/dist/page/shadow.js +400 -0
- package/dist/page/shortcut.d.ts +50 -0
- package/dist/page/shortcut.js +147 -0
- package/dist/page/snapshot-substrate-safari.d.ts +30 -0
- package/dist/page/snapshot-substrate-safari.js +84 -0
- package/dist/page/snapshot-substrate-select.d.ts +24 -0
- package/dist/page/snapshot-substrate-select.js +34 -0
- package/dist/page/snapshot-substrate.d.ts +58 -0
- package/dist/page/snapshot-substrate.js +135 -0
- package/dist/page/snapshot.d.ts +24 -0
- package/dist/page/snapshot.js +162 -0
- package/dist/page/solve-captcha.d.ts +76 -0
- package/dist/page/solve-captcha.js +286 -0
- package/dist/page/storage-substrate-types.d.ts +221 -0
- package/dist/page/storage-substrate-types.js +6 -0
- package/dist/page/storage-substrate.d.ts +215 -0
- package/dist/page/storage-substrate.js +280 -0
- package/dist/page/structural.d.ts +9 -0
- package/dist/page/structural.js +152 -0
- package/dist/page/substrate-bundle-safari.d.ts +8 -0
- package/dist/page/substrate-bundle-safari.js +42 -0
- package/dist/page/substrate-bundle.d.ts +6 -0
- package/dist/page/substrate-bundle.js +53 -0
- package/dist/page/text_search.d.ts +44 -0
- package/dist/page/text_search.js +90 -0
- package/dist/page/upload.d.ts +28 -0
- package/dist/page/upload.js +62 -0
- package/dist/page/verify.d.ts +63 -0
- package/dist/page/verify.js +451 -0
- package/dist/page/video.d.ts +115 -0
- package/dist/page/video.js +169 -0
- package/dist/page/visibility.d.ts +22 -0
- package/dist/page/visibility.js +94 -0
- package/dist/page/watch.d.ts +29 -0
- package/dist/page/watch.js +99 -0
- package/dist/page/workers.d.ts +126 -0
- package/dist/page/workers.js +490 -0
- package/dist/page/ws-interactive.d.ts +82 -0
- package/dist/page/ws-interactive.js +318 -0
- package/dist/plugin/cli.d.ts +45 -0
- package/dist/plugin/cli.js +496 -0
- package/dist/plugin/command-registry.d.ts +9 -0
- package/dist/plugin/command-registry.js +23 -0
- package/dist/plugin/depgraph.d.ts +37 -0
- package/dist/plugin/depgraph.js +186 -0
- package/dist/plugin/manifest.d.ts +182 -0
- package/dist/plugin/manifest.js +219 -0
- package/dist/plugin/package-manager.d.ts +22 -0
- package/dist/plugin/package-manager.js +40 -0
- package/dist/plugin/resolver.d.ts +85 -0
- package/dist/plugin/resolver.js +166 -0
- package/dist/plugin/runtime.d.ts +77 -0
- package/dist/plugin/runtime.js +402 -0
- package/dist/plugin/types.d.ts +113 -0
- package/dist/plugin/types.js +4 -0
- package/dist/policy/confirm.d.ts +76 -0
- package/dist/policy/confirm.js +162 -0
- package/dist/policy/origin.d.ts +17 -0
- package/dist/policy/origin.js +79 -0
- package/dist/sdk/client.d.ts +21 -0
- package/dist/sdk/client.js +174 -0
- package/dist/sdk/index.d.ts +32 -0
- package/dist/sdk/index.js +61 -0
- package/dist/sdk/plugin-types.d.ts +33 -0
- package/dist/sdk/plugin-types.js +22 -0
- package/dist/sdk/registry.d.ts +17 -0
- package/dist/sdk/registry.js +94 -0
- package/dist/sdk/socket-transport.d.ts +20 -0
- package/dist/sdk/socket-transport.js +90 -0
- package/dist/sdk/tool-types.d.ts +634 -0
- package/dist/sdk/tool-types.js +28 -0
- package/dist/sdk/transport-in-process.d.ts +21 -0
- package/dist/sdk/transport-in-process.js +44 -0
- package/dist/sdk/transport-registry.d.ts +19 -0
- package/dist/sdk/transport-registry.js +31 -0
- package/dist/sdk/transport-socket.d.ts +12 -0
- package/dist/sdk/transport-socket.js +77 -0
- package/dist/sdk/transport-stdio-child.d.ts +10 -0
- package/dist/sdk/transport-stdio-child.js +47 -0
- package/dist/sdk/transport.d.ts +10 -0
- package/dist/sdk/transport.js +35 -0
- package/dist/sdk/types.d.ts +176 -0
- package/dist/sdk/types.js +10 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.js +327 -0
- package/dist/session/artifacts.d.ts +52 -0
- package/dist/session/artifacts.js +177 -0
- package/dist/session/byob-attach.d.ts +26 -0
- package/dist/session/byob-attach.js +187 -0
- package/dist/session/byob.d.ts +8 -0
- package/dist/session/byob.js +20 -0
- package/dist/session/cache-storage.d.ts +100 -0
- package/dist/session/cache-storage.js +166 -0
- package/dist/session/device-emu.d.ts +149 -0
- package/dist/session/device-emu.js +545 -0
- package/dist/session/device.d.ts +14 -0
- package/dist/session/device.js +44 -0
- package/dist/session/dialog.d.ts +62 -0
- package/dist/session/dialog.js +164 -0
- package/dist/session/emulation.d.ts +69 -0
- package/dist/session/emulation.js +168 -0
- package/dist/session/extensions.d.ts +113 -0
- package/dist/session/extensions.js +237 -0
- package/dist/session/fs-picker.d.ts +144 -0
- package/dist/session/fs-picker.js +666 -0
- package/dist/session/idb-storage.d.ts +86 -0
- package/dist/session/idb-storage.js +229 -0
- package/dist/session/incognito.d.ts +3 -0
- package/dist/session/incognito.js +20 -0
- package/dist/session/launch-options.d.ts +41 -0
- package/dist/session/launch-options.js +200 -0
- package/dist/session/managed.d.ts +3 -0
- package/dist/session/managed.js +16 -0
- package/dist/session/metrics.d.ts +45 -0
- package/dist/session/metrics.js +75 -0
- package/dist/session/notification.d.ts +122 -0
- package/dist/session/notification.js +426 -0
- package/dist/session/permission.d.ts +144 -0
- package/dist/session/permission.js +600 -0
- package/dist/session/playwright-post-wire.d.ts +8 -0
- package/dist/session/playwright-post-wire.js +148 -0
- package/dist/session/policy-buffer.d.ts +21 -0
- package/dist/session/policy-buffer.js +47 -0
- package/dist/session/profile-snapshot.d.ts +11 -0
- package/dist/session/profile-snapshot.js +53 -0
- package/dist/session/registry.d.ts +365 -0
- package/dist/session/registry.js +98 -0
- package/dist/session/safari-post-wire.d.ts +8 -0
- package/dist/session/safari-post-wire.js +28 -0
- package/dist/session/safari-session.d.ts +10 -0
- package/dist/session/safari-session.js +39 -0
- package/dist/session/storage.d.ts +148 -0
- package/dist/session/storage.js +350 -0
- package/dist/session/types.d.ts +113 -0
- package/dist/session/types.js +5 -0
- package/dist/session/wedge.d.ts +15 -0
- package/dist/session/wedge.js +41 -0
- package/dist/tools/action-core-tools.d.ts +13 -0
- package/dist/tools/action-core-tools.js +156 -0
- package/dist/tools/action-form-tools.d.ts +12 -0
- package/dist/tools/action-form-tools.js +179 -0
- package/dist/tools/action-gesture-tools.d.ts +9 -0
- package/dist/tools/action-gesture-tools.js +115 -0
- package/dist/tools/action-history-tools.d.ts +8 -0
- package/dist/tools/action-history-tools.js +67 -0
- package/dist/tools/action-tool.d.ts +42 -0
- package/dist/tools/action-tool.js +58 -0
- package/dist/tools/action-tools.d.ts +20 -0
- package/dist/tools/action-tools.js +28 -0
- package/dist/tools/batch-act-tools.d.ts +10 -0
- package/dist/tools/batch-act-tools.js +276 -0
- package/dist/tools/batch-human-tools.d.ts +8 -0
- package/dist/tools/batch-human-tools.js +148 -0
- package/dist/tools/canvas-tools.d.ts +40 -0
- package/dist/tools/canvas-tools.js +368 -0
- package/dist/tools/capture-report-diagnostics-tools.d.ts +7 -0
- package/dist/tools/capture-report-diagnostics-tools.js +318 -0
- package/dist/tools/capture-report-element-export-tools.d.ts +8 -0
- package/dist/tools/capture-report-element-export-tools.js +197 -0
- package/dist/tools/capture-report-export-tools.d.ts +8 -0
- package/dist/tools/capture-report-export-tools.js +246 -0
- package/dist/tools/capture-report-marks-tools.d.ts +9 -0
- package/dist/tools/capture-report-marks-tools.js +221 -0
- package/dist/tools/capture-report-upload-tools.d.ts +8 -0
- package/dist/tools/capture-report-upload-tools.js +277 -0
- package/dist/tools/config-approval-tools.d.ts +8 -0
- package/dist/tools/config-approval-tools.js +166 -0
- package/dist/tools/deep-coverage-tools.d.ts +8 -0
- package/dist/tools/deep-coverage-tools.js +325 -0
- package/dist/tools/deep-determinism-tools.d.ts +8 -0
- package/dist/tools/deep-determinism-tools.js +276 -0
- package/dist/tools/deep-perf-tools.d.ts +19 -0
- package/dist/tools/deep-perf-tools.js +324 -0
- package/dist/tools/device-emulation-tools.d.ts +9 -0
- package/dist/tools/device-emulation-tools.js +137 -0
- package/dist/tools/extensions-batch-tools.d.ts +18 -0
- package/dist/tools/extensions-batch-tools.js +24 -0
- package/dist/tools/extensions-rebuild.d.ts +22 -0
- package/dist/tools/extensions-rebuild.js +208 -0
- package/dist/tools/extensions-tools.d.ts +2 -0
- package/dist/tools/extensions-tools.js +331 -0
- package/dist/tools/forms-fill-tools.d.ts +8 -0
- package/dist/tools/forms-fill-tools.js +109 -0
- package/dist/tools/forms-plan-tools.d.ts +7 -0
- package/dist/tools/forms-plan-tools.js +159 -0
- package/dist/tools/forms-recording-mode-tools.d.ts +8 -0
- package/dist/tools/forms-recording-mode-tools.js +71 -0
- package/dist/tools/forms-recording-tools.d.ts +14 -0
- package/dist/tools/forms-recording-tools.js +22 -0
- package/dist/tools/forms-refs-tools.d.ts +8 -0
- package/dist/tools/forms-refs-tools.js +90 -0
- package/dist/tools/gesture-coord-tools.d.ts +8 -0
- package/dist/tools/gesture-coord-tools.js +168 -0
- package/dist/tools/gesture-emulation-tools.d.ts +8 -0
- package/dist/tools/gesture-emulation-tools.js +135 -0
- package/dist/tools/gesture-network-tools.d.ts +17 -0
- package/dist/tools/gesture-network-tools.js +27 -0
- package/dist/tools/gesture-route-tools.d.ts +8 -0
- package/dist/tools/gesture-route-tools.js +142 -0
- package/dist/tools/gesture-websocket-tools.d.ts +8 -0
- package/dist/tools/gesture-websocket-tools.js +122 -0
- package/dist/tools/gesture-worker-tools.d.ts +9 -0
- package/dist/tools/gesture-worker-tools.js +200 -0
- package/dist/tools/host-build.d.ts +76 -0
- package/dist/tools/host-build.js +516 -0
- package/dist/tools/host.d.ts +287 -0
- package/dist/tools/host.js +1 -0
- package/dist/tools/input-tools.d.ts +10 -0
- package/dist/tools/input-tools.js +176 -0
- package/dist/tools/live-emulation-tools.d.ts +9 -0
- package/dist/tools/live-emulation-tools.js +353 -0
- package/dist/tools/plugin-runtime.d.ts +36 -0
- package/dist/tools/plugin-runtime.js +274 -0
- package/dist/tools/read-observe-buffer-tools.d.ts +9 -0
- package/dist/tools/read-observe-buffer-tools.js +385 -0
- package/dist/tools/read-observe-capture-tools.d.ts +12 -0
- package/dist/tools/read-observe-capture-tools.js +376 -0
- package/dist/tools/read-observe-dom-tools.d.ts +8 -0
- package/dist/tools/read-observe-dom-tools.js +308 -0
- package/dist/tools/read-observe-extract-tools.d.ts +8 -0
- package/dist/tools/read-observe-extract-tools.js +232 -0
- package/dist/tools/read-observe-verify-tools.d.ts +8 -0
- package/dist/tools/read-observe-verify-tools.js +316 -0
- package/dist/tools/schemas.d.ts +29 -0
- package/dist/tools/schemas.js +58 -0
- package/dist/tools/secrets-captcha-tools.d.ts +9 -0
- package/dist/tools/secrets-captcha-tools.js +231 -0
- package/dist/tools/session-dialog-permission-tools.d.ts +9 -0
- package/dist/tools/session-dialog-permission-tools.js +287 -0
- package/dist/tools/session-lifecycle-tools.d.ts +8 -0
- package/dist/tools/session-lifecycle-tools.js +314 -0
- package/dist/tools/session-notification-device-tools.d.ts +9 -0
- package/dist/tools/session-notification-device-tools.js +156 -0
- package/dist/tools/session-policy-tools.d.ts +16 -0
- package/dist/tools/session-policy-tools.js +22 -0
- package/dist/tools/session-registry.d.ts +28 -0
- package/dist/tools/session-registry.js +427 -0
- package/dist/tools/storage-artifact-har-video-tools.d.ts +8 -0
- package/dist/tools/storage-artifact-har-video-tools.js +311 -0
- package/dist/tools/storage-cache-idb-tools.d.ts +8 -0
- package/dist/tools/storage-cache-idb-tools.js +347 -0
- package/dist/tools/storage-state-cookies-tools.d.ts +8 -0
- package/dist/tools/storage-state-cookies-tools.js +223 -0
- package/dist/tools/storage-tools.d.ts +17 -0
- package/dist/tools/storage-tools.js +25 -0
- package/dist/tools/storage-web-auth-tools.d.ts +10 -0
- package/dist/tools/storage-web-auth-tools.js +230 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/dist/tools/tool-metadata.js +185 -0
- package/dist/util/batch.d.ts +83 -0
- package/dist/util/batch.js +191 -0
- package/dist/util/capabilities.d.ts +504 -0
- package/dist/util/capabilities.js +254 -0
- package/dist/util/config-store.d.ts +103 -0
- package/dist/util/config-store.js +206 -0
- package/dist/util/config.d.ts +11 -0
- package/dist/util/config.js +28 -0
- package/dist/util/credentials.d.ts +136 -0
- package/dist/util/credentials.js +622 -0
- package/dist/util/deadline.d.ts +22 -0
- package/dist/util/deadline.js +62 -0
- package/dist/util/diagnostics.d.ts +161 -0
- package/dist/util/diagnostics.js +579 -0
- package/dist/util/egress-sanitiser.d.ts +29 -0
- package/dist/util/egress-sanitiser.js +52 -0
- package/dist/util/failure.d.ts +8 -0
- package/dist/util/failure.js +50 -0
- package/dist/util/flake-check.d.ts +109 -0
- package/dist/util/flake-check.js +342 -0
- package/dist/util/invariant.d.ts +25 -0
- package/dist/util/invariant.js +66 -0
- package/dist/util/logging.d.ts +6 -0
- package/dist/util/logging.js +12 -0
- package/dist/util/predicates.d.ts +62 -0
- package/dist/util/predicates.js +340 -0
- package/dist/util/secrets.d.ts +104 -0
- package/dist/util/secrets.js +219 -0
- package/dist/util/tokens.d.ts +6 -0
- package/dist/util/tokens.js +24 -0
- package/dist/util/url-sanitizer.d.ts +19 -0
- package/dist/util/url-sanitizer.js +70 -0
- package/dist/util/version.d.ts +2 -0
- package/dist/util/version.js +21 -0
- package/dist/util/workspace.d.ts +7 -0
- package/dist/util/workspace.js +22 -0
- package/package.json +120 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
// Performance tracing — capability `action` (writes a file).
|
|
2
|
+
//
|
|
3
|
+
// "This click took 4s — why?" has no diagnostic surface in browxai's read-only
|
|
4
|
+
// tools: a screenshot/snapshot/network slice shows *what* happened, not *why*
|
|
5
|
+
// it was slow. CDP `Tracing.start` / `Tracing.end` produces a chromium trace
|
|
6
|
+
// blob that's the same shape Lighthouse / DevTools Performance consume; this
|
|
7
|
+
// module wraps it as a per-session lifecycle and pairs it with a minimal
|
|
8
|
+
// insights extractor over the resulting JSON so the agent gets a structured
|
|
9
|
+
// summary (long tasks, layout shifts, render-blocking resources, LCP /
|
|
10
|
+
// navigation timing candidates) without having to ship a megabyte of trace
|
|
11
|
+
// back through the MCP channel.
|
|
12
|
+
//
|
|
13
|
+
// Lifecycle (per session):
|
|
14
|
+
// - perf_start({categories?}) → enables tracing on the CDP target.
|
|
15
|
+
// - perf_stop({path?}) → flushes events to a workspace-rooted file
|
|
16
|
+
// (default `<workspace>/perf-traces/<id>-<ts>.json`),
|
|
17
|
+
// returns the path + a tiny inline summary.
|
|
18
|
+
// Always idempotent: a second `perf_stop`
|
|
19
|
+
// without a matching `perf_start` returns
|
|
20
|
+
// `notRunning:true`, not an error.
|
|
21
|
+
// - perf_insights({tracePath}) → reads the trace JSON and returns
|
|
22
|
+
// structured insights.
|
|
23
|
+
//
|
|
24
|
+
// Idempotency guarantee (invariant 6): `perf_start` while a trace is already
|
|
25
|
+
// running first cleanly stops the in-flight one (events discarded) before
|
|
26
|
+
// starting fresh, so an agent that lost track of state can always recover by
|
|
27
|
+
// just calling `perf_start` again. `perf_stop` is safe to call any number of
|
|
28
|
+
// times.
|
|
29
|
+
import { readFileSync, writeFileSync, mkdirSync, existsSync } from "node:fs";
|
|
30
|
+
import { join, dirname, resolve, sep } from "node:path";
|
|
31
|
+
/** Default trace categories — covers the cases DevTools' Performance panel
|
|
32
|
+
* uses for its core insights (frames, paint, layout, long tasks, user
|
|
33
|
+
* timing, loading). Smaller than the everything-on default to keep traces
|
|
34
|
+
* manageable. */
|
|
35
|
+
export const DEFAULT_TRACE_CATEGORIES = [
|
|
36
|
+
"devtools.timeline",
|
|
37
|
+
"loading",
|
|
38
|
+
"blink.user_timing",
|
|
39
|
+
"disabled-by-default-devtools.timeline",
|
|
40
|
+
"disabled-by-default-devtools.timeline.frame",
|
|
41
|
+
"latencyInfo",
|
|
42
|
+
];
|
|
43
|
+
/** Per-session trace state machine. One instance per SessionEntry. */
|
|
44
|
+
export class PerfTracingState {
|
|
45
|
+
running = false;
|
|
46
|
+
events = [];
|
|
47
|
+
/** Hook teardowns from the most recent `start`. */
|
|
48
|
+
listeners = [];
|
|
49
|
+
/** Resolved-when the in-flight `Tracing.end` flushes all events. */
|
|
50
|
+
completePromise = null;
|
|
51
|
+
completeResolve = null;
|
|
52
|
+
/** Categories the current/last trace was started with — surfaced on stop. */
|
|
53
|
+
categories = [];
|
|
54
|
+
startedAt = 0;
|
|
55
|
+
/** True iff a trace is currently being collected. */
|
|
56
|
+
isRunning() {
|
|
57
|
+
return this.running;
|
|
58
|
+
}
|
|
59
|
+
/** Start tracing on `cdp`. If a trace is already running, stops it cleanly
|
|
60
|
+
* first (events discarded) — guarantees the caller never gets stuck in a
|
|
61
|
+
* "tracing already started" CDP error from a stale start. */
|
|
62
|
+
async start(cdp, opts = {}) {
|
|
63
|
+
let restarted = false;
|
|
64
|
+
if (this.running) {
|
|
65
|
+
restarted = true;
|
|
66
|
+
// Clean restart: stop the in-flight trace; throw away its events.
|
|
67
|
+
await this.stopInternal(cdp).catch(() => undefined);
|
|
68
|
+
}
|
|
69
|
+
const categories = opts.categories && opts.categories.length > 0 ? opts.categories : DEFAULT_TRACE_CATEGORIES;
|
|
70
|
+
this.events = [];
|
|
71
|
+
this.categories = [...categories];
|
|
72
|
+
this.startedAt = Date.now();
|
|
73
|
+
const onData = (e) => {
|
|
74
|
+
if (Array.isArray(e?.value)) {
|
|
75
|
+
for (const ev of e.value)
|
|
76
|
+
this.events.push(ev);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
const onComplete = () => {
|
|
80
|
+
if (this.completeResolve)
|
|
81
|
+
this.completeResolve();
|
|
82
|
+
};
|
|
83
|
+
cdp.on("Tracing.dataCollected", onData);
|
|
84
|
+
cdp.on("Tracing.tracingComplete", onComplete);
|
|
85
|
+
this.listeners = [
|
|
86
|
+
() => cdp.off("Tracing.dataCollected", onData),
|
|
87
|
+
() => cdp.off("Tracing.tracingComplete", onComplete),
|
|
88
|
+
];
|
|
89
|
+
// Tracing.start with traceConfig — pass `includedCategories` for fine
|
|
90
|
+
// control. CDP also accepts a comma-separated `categories` string for
|
|
91
|
+
// legacy; the typed `traceConfig` is the supported shape.
|
|
92
|
+
await cdp.send("Tracing.start", {
|
|
93
|
+
transferMode: "ReportEvents",
|
|
94
|
+
traceConfig: {
|
|
95
|
+
recordMode: "recordContinuously",
|
|
96
|
+
includedCategories: [...categories],
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
this.running = true;
|
|
100
|
+
return { categories: [...categories], restarted };
|
|
101
|
+
}
|
|
102
|
+
/** Stop tracing and return the buffered events. Safe to call when no trace
|
|
103
|
+
* is running — returns `notRunning:true` with an empty event list. */
|
|
104
|
+
async stop(cdp) {
|
|
105
|
+
if (!this.running) {
|
|
106
|
+
return { notRunning: true, events: [], categories: [...this.categories], durationMs: 0 };
|
|
107
|
+
}
|
|
108
|
+
const durationMs = Date.now() - this.startedAt;
|
|
109
|
+
await this.stopInternal(cdp);
|
|
110
|
+
const evts = this.events;
|
|
111
|
+
this.events = [];
|
|
112
|
+
return { events: evts, categories: [...this.categories], durationMs };
|
|
113
|
+
}
|
|
114
|
+
/** Force-clean teardown for session close paths. Tolerates double calls. */
|
|
115
|
+
async closeIfRunning(cdp) {
|
|
116
|
+
if (!this.running)
|
|
117
|
+
return;
|
|
118
|
+
await this.stopInternal(cdp).catch(() => undefined);
|
|
119
|
+
this.events = [];
|
|
120
|
+
}
|
|
121
|
+
/** Internal stop: send `Tracing.end`, wait for the `tracingComplete` flush,
|
|
122
|
+
* detach listeners. Guarantees `running=false` even on errors so the
|
|
123
|
+
* next start always works. */
|
|
124
|
+
async stopInternal(cdp) {
|
|
125
|
+
this.completePromise = new Promise((res) => {
|
|
126
|
+
this.completeResolve = res;
|
|
127
|
+
});
|
|
128
|
+
try {
|
|
129
|
+
await cdp.send("Tracing.end").catch(() => undefined);
|
|
130
|
+
// Bounded wait: the `tracingComplete` flush is normally near-instant
|
|
131
|
+
// but a runaway target shouldn't deadlock us. 30s is generous.
|
|
132
|
+
await Promise.race([
|
|
133
|
+
this.completePromise,
|
|
134
|
+
new Promise((res) => setTimeout(res, 30_000)),
|
|
135
|
+
]);
|
|
136
|
+
}
|
|
137
|
+
finally {
|
|
138
|
+
for (const off of this.listeners) {
|
|
139
|
+
try {
|
|
140
|
+
off();
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
/* listener removal is best-effort */
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
this.listeners = [];
|
|
147
|
+
this.completePromise = null;
|
|
148
|
+
this.completeResolve = null;
|
|
149
|
+
this.running = false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Workspace path helper. Mirrors `resolveWorkspacePath` in session/storage.ts
|
|
155
|
+
// but kept local so this module doesn't reach across page → session.
|
|
156
|
+
export function resolvePerfTracePath(workspaceRoot, p, tool) {
|
|
157
|
+
const resolved = resolve(workspaceRoot, p);
|
|
158
|
+
if (resolved !== workspaceRoot && !resolved.startsWith(workspaceRoot + sep)) {
|
|
159
|
+
throw new Error(`${tool}: \`path\` must resolve inside $BROWX_WORKSPACE — got "${p}".`);
|
|
160
|
+
}
|
|
161
|
+
return resolved;
|
|
162
|
+
}
|
|
163
|
+
/** Default trace filename under `<workspace>/perf-traces/<sessionId>-<ts>.json`. */
|
|
164
|
+
export function defaultTracePath(workspaceRoot, sessionId) {
|
|
165
|
+
// sanitize the session id for the filename — only safe chars survive.
|
|
166
|
+
const safe = (sessionId || "default").replace(/[^A-Za-z0-9._-]/g, "_");
|
|
167
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
168
|
+
return join(workspaceRoot, "perf-traces", `${safe}-${ts}.json`);
|
|
169
|
+
}
|
|
170
|
+
/** Write a trace event array as a chrome-tracing-compatible JSON file. The
|
|
171
|
+
* format the chromium ecosystem expects is `{ traceEvents: [...] }`; we
|
|
172
|
+
* also include `metadata` so a roundtrip through tracingControl tools is
|
|
173
|
+
* cleanly identifiable. */
|
|
174
|
+
export function writeTraceFile(workspaceRoot, filePath, events, meta, tool) {
|
|
175
|
+
// Path is workspace-rooted by construction via `resolvePerfTracePath`.
|
|
176
|
+
const resolved = resolvePerfTracePath(workspaceRoot, filePath, tool);
|
|
177
|
+
const parent = dirname(resolved);
|
|
178
|
+
// ws.sub-style: ensure parent exists under workspace.root.
|
|
179
|
+
if (parent && !existsSync(parent))
|
|
180
|
+
mkdirSync(parent, { recursive: true });
|
|
181
|
+
const payload = JSON.stringify({
|
|
182
|
+
traceEvents: events,
|
|
183
|
+
metadata: {
|
|
184
|
+
source: "browxai",
|
|
185
|
+
sessionId: meta.sessionId,
|
|
186
|
+
categories: meta.categories,
|
|
187
|
+
durationMs: meta.durationMs,
|
|
188
|
+
eventCount: events.length,
|
|
189
|
+
capturedAt: new Date().toISOString(),
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
// ws.root-rooted path — see resolvePerfTracePath above for the guard.
|
|
193
|
+
writeFileSync(resolved, payload, "utf8");
|
|
194
|
+
return { resolved, bytes: Buffer.byteLength(payload, "utf8") };
|
|
195
|
+
}
|
|
196
|
+
/** Read a trace file and return the event array. */
|
|
197
|
+
export function readTraceFile(workspaceRoot, filePath, tool) {
|
|
198
|
+
const resolved = resolvePerfTracePath(workspaceRoot, filePath, tool);
|
|
199
|
+
if (!existsSync(resolved)) {
|
|
200
|
+
throw new Error(`${tool}: trace file not found at "${resolved}" — call perf_stop first`);
|
|
201
|
+
}
|
|
202
|
+
const raw = readFileSync(resolved, "utf8");
|
|
203
|
+
let parsed;
|
|
204
|
+
try {
|
|
205
|
+
parsed = JSON.parse(raw);
|
|
206
|
+
}
|
|
207
|
+
catch (err) {
|
|
208
|
+
throw new Error(`${tool}: trace file "${resolved}" is not valid JSON (${err instanceof Error ? err.message : String(err)})`);
|
|
209
|
+
}
|
|
210
|
+
if (Array.isArray(parsed)) {
|
|
211
|
+
return { events: parsed };
|
|
212
|
+
}
|
|
213
|
+
if (parsed &&
|
|
214
|
+
typeof parsed === "object" &&
|
|
215
|
+
Array.isArray(parsed.traceEvents)) {
|
|
216
|
+
const obj = parsed;
|
|
217
|
+
return { events: obj.traceEvents, metadata: obj.metadata };
|
|
218
|
+
}
|
|
219
|
+
throw new Error(`${tool}: trace file "${resolved}" doesn't look like a chrome trace (missing traceEvents array)`);
|
|
220
|
+
}
|
|
221
|
+
// ---------------------------------------------------------------------------
|
|
222
|
+
// Minimal insights extractor over the trace event array.
|
|
223
|
+
//
|
|
224
|
+
// We deliberately avoid pulling in chrome-devtools-frontend's full Insights
|
|
225
|
+
// pipeline (it would dominate the dependency tree). The four extracts below
|
|
226
|
+
// cover the cases an agent diagnosing "why was that slow" actually asks:
|
|
227
|
+
// - Long tasks: blocking work on the main thread
|
|
228
|
+
// - Layout shifts: visual instability (CLS contributors)
|
|
229
|
+
// - Render-blocking resources: critical-path CSS / sync JS
|
|
230
|
+
// - LCP candidates: which element + when
|
|
231
|
+
const LONG_TASK_THRESHOLD_MS = 50;
|
|
232
|
+
const MAX_LIST_ENTRIES = 50;
|
|
233
|
+
/** Extract structured insights from a trace event array. Pure — exported for
|
|
234
|
+
* unit tests. */
|
|
235
|
+
/** chromium trace ts is microseconds; surface ms for the agent. */
|
|
236
|
+
function usToMs(us) {
|
|
237
|
+
return typeof us === "number" ? us / 1000 : 0;
|
|
238
|
+
}
|
|
239
|
+
function handleLayoutShift(acc, ts, data) {
|
|
240
|
+
const score = typeof data.score === "number"
|
|
241
|
+
? data.score
|
|
242
|
+
: typeof data.weighted_score_delta === "number"
|
|
243
|
+
? data.weighted_score_delta
|
|
244
|
+
: 0;
|
|
245
|
+
const entry = { startMs: ts, score };
|
|
246
|
+
if (data.had_recent_input === true)
|
|
247
|
+
entry.hadRecentInput = true;
|
|
248
|
+
acc.layoutShifts.push(entry);
|
|
249
|
+
}
|
|
250
|
+
/** Render-blocking resources are stitched: a `blocking`/`in_body_parser_blocking`
|
|
251
|
+
* `ResourceSendRequest` records the start; the matching `ResourceFinish` emits
|
|
252
|
+
* the duration. */
|
|
253
|
+
function handleResourceEvent(acc, name, ts, data) {
|
|
254
|
+
const requestId = typeof data.requestId === "string" ? data.requestId : undefined;
|
|
255
|
+
if (!requestId)
|
|
256
|
+
return;
|
|
257
|
+
if (name === "ResourceSendRequest") {
|
|
258
|
+
const url = typeof data.url === "string" ? data.url : "";
|
|
259
|
+
const blocking = typeof data.renderBlocking === "string" ? data.renderBlocking : "";
|
|
260
|
+
if (url && (blocking === "blocking" || blocking === "in_body_parser_blocking")) {
|
|
261
|
+
acc.sendStartByRequestId.set(requestId, {
|
|
262
|
+
url,
|
|
263
|
+
tsMs: ts,
|
|
264
|
+
blocking,
|
|
265
|
+
type: typeof data.resourceType === "string" ? data.resourceType : undefined,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else if (name === "ResourceFinish" && acc.sendStartByRequestId.has(requestId)) {
|
|
270
|
+
const start = acc.sendStartByRequestId.get(requestId);
|
|
271
|
+
acc.renderBlocking.push({ url: start.url, type: start.type, durationMs: ts - start.tsMs });
|
|
272
|
+
acc.sendStartByRequestId.delete(requestId);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function handleLcpCandidate(acc, ts, data) {
|
|
276
|
+
const entry = { startMs: ts };
|
|
277
|
+
if (typeof data.size === "number")
|
|
278
|
+
entry.size = data.size;
|
|
279
|
+
if (typeof data.DOMNodeId === "number")
|
|
280
|
+
entry.nodeName = `#${String(data.DOMNodeId)}`;
|
|
281
|
+
if (typeof data.nodeName === "string")
|
|
282
|
+
entry.nodeName = data.nodeName;
|
|
283
|
+
if (typeof data.url === "string")
|
|
284
|
+
entry.url = data.url;
|
|
285
|
+
acc.lcpCandidates.push(entry);
|
|
286
|
+
}
|
|
287
|
+
const NAV_MILESTONE_BY_NAME = {
|
|
288
|
+
navigationStart: "navigationStartMs",
|
|
289
|
+
firstPaint: "firstPaintMs",
|
|
290
|
+
firstContentfulPaint: "firstContentfulPaintMs",
|
|
291
|
+
MarkDOMContent: "domContentLoadedMs",
|
|
292
|
+
domContentLoadedEventEnd: "domContentLoadedMs",
|
|
293
|
+
MarkLoad: "loadEventMs",
|
|
294
|
+
loadEventEnd: "loadEventMs",
|
|
295
|
+
};
|
|
296
|
+
/** Dispatch one trace event into the accumulator. */
|
|
297
|
+
function ingestEvent(acc, e) {
|
|
298
|
+
if (!e || typeof e !== "object")
|
|
299
|
+
return;
|
|
300
|
+
const name = typeof e.name === "string" ? e.name : "";
|
|
301
|
+
if (!name)
|
|
302
|
+
return;
|
|
303
|
+
const ts = usToMs(e.ts);
|
|
304
|
+
const data = ((e.args ?? {}).data ?? {});
|
|
305
|
+
// Long tasks: `RunTask` / `LongTask` on the main thread with dur ≥ threshold.
|
|
306
|
+
if ((name === "RunTask" || name === "LongTask") && usToMs(e.dur) >= LONG_TASK_THRESHOLD_MS) {
|
|
307
|
+
acc.longTasks.push({ startMs: ts, durationMs: usToMs(e.dur) });
|
|
308
|
+
}
|
|
309
|
+
else if (name === "LayoutShift") {
|
|
310
|
+
handleLayoutShift(acc, ts, data);
|
|
311
|
+
}
|
|
312
|
+
else if (name === "ResourceSendRequest" || name === "ResourceFinish") {
|
|
313
|
+
handleResourceEvent(acc, name, ts, data);
|
|
314
|
+
}
|
|
315
|
+
else if (name === "largestContentfulPaint::Candidate") {
|
|
316
|
+
handleLcpCandidate(acc, ts, data);
|
|
317
|
+
}
|
|
318
|
+
const navKey = NAV_MILESTONE_BY_NAME[name];
|
|
319
|
+
if (navKey)
|
|
320
|
+
acc.nav[navKey] = ts;
|
|
321
|
+
}
|
|
322
|
+
/** Relativise navigation timing against navigationStart — raw monotonic ts
|
|
323
|
+
* numbers aren't interpretable; offsets are. */
|
|
324
|
+
function buildNavigation(nav) {
|
|
325
|
+
if (nav.navigationStartMs === undefined)
|
|
326
|
+
return undefined;
|
|
327
|
+
const start = nav.navigationStartMs;
|
|
328
|
+
const out = { navigationStartMs: start };
|
|
329
|
+
if (nav.firstPaintMs !== undefined)
|
|
330
|
+
out.firstPaintMs = nav.firstPaintMs - start;
|
|
331
|
+
if (nav.firstContentfulPaintMs !== undefined)
|
|
332
|
+
out.firstContentfulPaintMs = nav.firstContentfulPaintMs - start;
|
|
333
|
+
if (nav.domContentLoadedMs !== undefined)
|
|
334
|
+
out.domContentLoadedMs = nav.domContentLoadedMs - start;
|
|
335
|
+
if (nav.loadEventMs !== undefined)
|
|
336
|
+
out.loadEventMs = nav.loadEventMs - start;
|
|
337
|
+
return out;
|
|
338
|
+
}
|
|
339
|
+
export function extractInsights(events) {
|
|
340
|
+
const acc = {
|
|
341
|
+
longTasks: [],
|
|
342
|
+
layoutShifts: [],
|
|
343
|
+
renderBlocking: [],
|
|
344
|
+
lcpCandidates: [],
|
|
345
|
+
sendStartByRequestId: new Map(),
|
|
346
|
+
nav: {},
|
|
347
|
+
};
|
|
348
|
+
for (const e of events)
|
|
349
|
+
ingestEvent(acc, e);
|
|
350
|
+
// Sort by impact (top contributors first). LCP candidates stay in input order
|
|
351
|
+
// (chronological) — the final candidate is the effective LCP.
|
|
352
|
+
acc.longTasks.sort((a, b) => b.durationMs - a.durationMs);
|
|
353
|
+
acc.renderBlocking.sort((a, b) => b.durationMs - a.durationMs);
|
|
354
|
+
acc.layoutShifts.sort((a, b) => b.score - a.score);
|
|
355
|
+
const cap = (arr) => arr.length > MAX_LIST_ENTRIES ? arr.slice(0, MAX_LIST_ENTRIES) : arr;
|
|
356
|
+
const insights = {
|
|
357
|
+
longTasks: cap(acc.longTasks),
|
|
358
|
+
layoutShifts: cap(acc.layoutShifts),
|
|
359
|
+
renderBlocking: cap(acc.renderBlocking),
|
|
360
|
+
lcpCandidates: cap(acc.lcpCandidates),
|
|
361
|
+
totals: {
|
|
362
|
+
events: events.length,
|
|
363
|
+
longTaskCount: acc.longTasks.length,
|
|
364
|
+
layoutShiftCount: acc.layoutShifts.length,
|
|
365
|
+
layoutShiftScoreSum: acc.layoutShifts.reduce((s, l) => s + l.score, 0),
|
|
366
|
+
renderBlockingCount: acc.renderBlocking.length,
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
const navigation = buildNavigation(acc.nav);
|
|
370
|
+
if (navigation)
|
|
371
|
+
insights.navigation = navigation;
|
|
372
|
+
return insights;
|
|
373
|
+
}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import type { CDPSession, Page } from "playwright-core";
|
|
2
|
+
import { type FindCandidate } from "./find.js";
|
|
3
|
+
import type { SnapshotSubstrate } from "./snapshot-substrate.js";
|
|
4
|
+
import type { RefRegistry } from "./refs.js";
|
|
5
|
+
import type { ActionContext, ActionResult } from "./actionresult.js";
|
|
6
|
+
/** Action verbs `plan()`/`execute()` understand. Single-target verbs only —
|
|
7
|
+
* page-level / multi-step verbs (`navigate`, `scroll`, `wait_for`, `choose_option`)
|
|
8
|
+
* are out of scope here; they're either trivially planned (`navigate(url)` doesn't
|
|
9
|
+
* need a ranked candidate) or expand into multiple action-window dispatches and
|
|
10
|
+
* belong in their own primitives. */
|
|
11
|
+
export declare const PLAN_VERBS: readonly ["click", "fill", "hover", "press", "select"];
|
|
12
|
+
export type PlanVerb = (typeof PLAN_VERBS)[number];
|
|
13
|
+
/** Per-verb args envelope. `value` is the typed-in string for `fill`, `values`
|
|
14
|
+
* the option list for `select`, `key` the Playwright key syntax for `press`,
|
|
15
|
+
* `button` the mouse button for `click`. Click / hover have no extra args
|
|
16
|
+
* beyond the descriptor's bound `ref`. */
|
|
17
|
+
export interface PlanVerbArgs {
|
|
18
|
+
/** `fill` value. */
|
|
19
|
+
value?: string;
|
|
20
|
+
/** `select` option labels/values. */
|
|
21
|
+
values?: string[];
|
|
22
|
+
/** `press` key. */
|
|
23
|
+
key?: string;
|
|
24
|
+
/** `click` mouse button (default left). */
|
|
25
|
+
button?: "left" | "right" | "middle";
|
|
26
|
+
}
|
|
27
|
+
/** The plan/execute envelope. The agent receives one, may inspect it, may
|
|
28
|
+
* cache it, and later hands it back verbatim to `execute()`. */
|
|
29
|
+
export interface ActionDescriptor {
|
|
30
|
+
/** Stable id for this descriptor (not a ref — a descriptor id; useful for
|
|
31
|
+
* caches that key on "this plan attempt"). */
|
|
32
|
+
id: string;
|
|
33
|
+
/** The bound element ref. Uses the **same** `eN` namespace as `find()` /
|
|
34
|
+
* `snapshot()` / `name_ref` — descriptors do NOT have a parallel id system. */
|
|
35
|
+
ref: string;
|
|
36
|
+
/** Action verb to dispatch. */
|
|
37
|
+
verb: PlanVerb;
|
|
38
|
+
/** Verb-specific args. Empty `{}` for click/hover with default button. */
|
|
39
|
+
args: PlanVerbArgs;
|
|
40
|
+
/** Evidence captured at plan time so the caller can decide whether to execute. */
|
|
41
|
+
evidence: PlanEvidence;
|
|
42
|
+
/** Epoch-ms past which `execute()` returns a structured "descriptor expired"
|
|
43
|
+
* failure. Defaults to `plan() + 60_000`. */
|
|
44
|
+
expiresAt: number;
|
|
45
|
+
}
|
|
46
|
+
export interface PlanEvidence {
|
|
47
|
+
query: string;
|
|
48
|
+
/** The top candidate's selectorHint — the same string `find()` would emit. */
|
|
49
|
+
selectorHint: string;
|
|
50
|
+
/** Tier (1–5) and stability (high/medium/low) of the picked locator. */
|
|
51
|
+
selectorTier: 1 | 2 | 3 | 4 | 5;
|
|
52
|
+
stability: FindCandidate["stability"];
|
|
53
|
+
/** The picked candidate's role / name / testId. */
|
|
54
|
+
role: string;
|
|
55
|
+
name?: string;
|
|
56
|
+
testId?: string;
|
|
57
|
+
/** The picked candidate's score under `find()`'s ranker. */
|
|
58
|
+
score: number;
|
|
59
|
+
/** Whether the candidate was visible+enabled+on-screen at plan time. */
|
|
60
|
+
actionable: FindCandidate["actionable"];
|
|
61
|
+
/** Whether `find()` issued any warnings (low confidence, no visible
|
|
62
|
+
* candidate, etc.). Caller can refuse to execute on this signal. */
|
|
63
|
+
warnings: string[];
|
|
64
|
+
/** Up to 4 lower-ranked alternatives (without `selectorHint` repetition).
|
|
65
|
+
* Useful when an agent wants to retry against a sibling after a failure. */
|
|
66
|
+
alternatives: Array<{
|
|
67
|
+
ref: string;
|
|
68
|
+
role: string;
|
|
69
|
+
name?: string;
|
|
70
|
+
testId?: string;
|
|
71
|
+
score: number;
|
|
72
|
+
}>;
|
|
73
|
+
}
|
|
74
|
+
export interface PlanOptions {
|
|
75
|
+
query: string;
|
|
76
|
+
verb: PlanVerb;
|
|
77
|
+
/** Verb args. Required ones (value for fill, key for press, values for
|
|
78
|
+
* select) are validated by `plan()` itself, not at `execute()` time — the
|
|
79
|
+
* point is to fail fast at capture, not at dispatch. */
|
|
80
|
+
verbArgs?: PlanVerbArgs;
|
|
81
|
+
/** Same semantics as `find()`'s `contextRef` — scope the candidate walk
|
|
82
|
+
* to this ref's subtree. */
|
|
83
|
+
contextRef?: string;
|
|
84
|
+
/** Same semantics as `find()` — return no descriptor if no candidate
|
|
85
|
+
* scored above the floor. Default 0 (off). */
|
|
86
|
+
confidenceFloor?: number;
|
|
87
|
+
/** Descriptor lifetime in ms. Default 60_000 (1 minute). Clamped to
|
|
88
|
+
* [1_000, 30 * 60_000] (1s..30min) — anything longer is almost certainly
|
|
89
|
+
* a misuse (the page WILL have moved on; re-plan instead). */
|
|
90
|
+
ttlMs?: number;
|
|
91
|
+
/** Configured test-attribute list, same as `find()`. */
|
|
92
|
+
testAttributes: string[];
|
|
93
|
+
/** Capability-aware fallback hints for the underlying `find()` call. */
|
|
94
|
+
fallbackHints?: {
|
|
95
|
+
coords: boolean;
|
|
96
|
+
evalJs: boolean;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export type PlanOutcome = {
|
|
100
|
+
ok: true;
|
|
101
|
+
descriptor: ActionDescriptor;
|
|
102
|
+
warnings: string[];
|
|
103
|
+
tokensEstimate: number;
|
|
104
|
+
} | {
|
|
105
|
+
ok: false;
|
|
106
|
+
error: string;
|
|
107
|
+
warnings: string[];
|
|
108
|
+
tokensEstimate: number;
|
|
109
|
+
};
|
|
110
|
+
/** Validate per-verb args at plan time so a bad descriptor can never reach
|
|
111
|
+
* `execute()`. Pure; exported for tests. */
|
|
112
|
+
export declare function validateVerbArgs(verb: PlanVerb, args: PlanVerbArgs | undefined): string | null;
|
|
113
|
+
/** Clamp a caller-supplied ttl into the sane range. Pure; exported for tests. */
|
|
114
|
+
export declare function clampTtl(ttlMs: number | undefined): number;
|
|
115
|
+
/** Project a `find()` candidate into a descriptor's `evidence` block.
|
|
116
|
+
* Pure; exported for tests. */
|
|
117
|
+
export declare function evidenceFromCandidate(query: string, picked: FindCandidate, alternatives: FindCandidate[], warnings: string[]): PlanEvidence;
|
|
118
|
+
/** Build a descriptor from a resolved candidate + caller args. Pure; exported
|
|
119
|
+
* for tests. */
|
|
120
|
+
export declare function buildDescriptor(args: {
|
|
121
|
+
picked: FindCandidate;
|
|
122
|
+
alternatives: FindCandidate[];
|
|
123
|
+
query: string;
|
|
124
|
+
verb: PlanVerb;
|
|
125
|
+
verbArgs: PlanVerbArgs;
|
|
126
|
+
warnings: string[];
|
|
127
|
+
ttlMs: number;
|
|
128
|
+
now?: number;
|
|
129
|
+
}): ActionDescriptor;
|
|
130
|
+
/** rough JSON-byte/4 token estimate for a descriptor — matches the
|
|
131
|
+
* shape `tokensEstimate` uses across other tools. Pure; exported for tests. */
|
|
132
|
+
export declare function estimateDescriptorTokens(d: ActionDescriptor): number;
|
|
133
|
+
/**
|
|
134
|
+
* `plan()`: rank `query` against the live tree, pick the top candidate,
|
|
135
|
+
* validate the verb's args, return a serialisable descriptor (no dispatch).
|
|
136
|
+
*
|
|
137
|
+
* Returns `{ ok: false }` with structured reasons when:
|
|
138
|
+
* - the verb's required args are missing/wrong-shape (validated up front),
|
|
139
|
+
* - `find()` returned no candidates (or none above `confidenceFloor`).
|
|
140
|
+
*
|
|
141
|
+
* Note: a descriptor IS returned even if the top candidate is non-actionable
|
|
142
|
+
* (off-screen / disabled). The caller can inspect `evidence.actionable` and
|
|
143
|
+
* decide; we don't silently refuse to plan against a hidden modal, because
|
|
144
|
+
* sometimes that's exactly what the caller wants to confirm.
|
|
145
|
+
*/
|
|
146
|
+
export declare function plan(page: Page, substrate: SnapshotSubstrate, refs: RefRegistry, opts: PlanOptions,
|
|
147
|
+
/** CDP handle for find()'s visible-rect bbox fast path — chromium only. */
|
|
148
|
+
cdp?: CDPSession): Promise<PlanOutcome>;
|
|
149
|
+
/** structured `execute()` failure shape — distinguishes a *dispatched*
|
|
150
|
+
* ActionResult (the dispatch ran; ok=true|false reflects the action's outcome)
|
|
151
|
+
* from a *refused* dispatch (descriptor expired / ref gone) where the action
|
|
152
|
+
* was never attempted. */
|
|
153
|
+
export type ExecuteOutcome = {
|
|
154
|
+
ok: true;
|
|
155
|
+
result: ActionResult;
|
|
156
|
+
tokensEstimate: number;
|
|
157
|
+
} | {
|
|
158
|
+
ok: false;
|
|
159
|
+
error: string;
|
|
160
|
+
reason: "expired" | "ref-gone" | "invalid";
|
|
161
|
+
tokensEstimate: number;
|
|
162
|
+
};
|
|
163
|
+
/** Reasons we may refuse to dispatch a descriptor without ever running it. */
|
|
164
|
+
export type ExecuteRefusal = Exclude<ExecuteOutcome, {
|
|
165
|
+
ok: true;
|
|
166
|
+
}>;
|
|
167
|
+
export interface ExecuteOptions {
|
|
168
|
+
/** Optional dispatch-window overrides (mode/maxResultTokens/timeoutMs/
|
|
169
|
+
* recordingHint flow through to the underlying action). Mirrors
|
|
170
|
+
* `ActionWindowOptions` but the descriptor itself is the source of truth
|
|
171
|
+
* for the target. */
|
|
172
|
+
mode?: import("./actionresult.js").SnapshotMode;
|
|
173
|
+
maxResultTokens?: number;
|
|
174
|
+
deadlineMs?: number;
|
|
175
|
+
deadlineWarning?: string;
|
|
176
|
+
recordingHint?: {
|
|
177
|
+
selectorHint: string;
|
|
178
|
+
stability?: FindCandidate["stability"];
|
|
179
|
+
};
|
|
180
|
+
/** Override "now" — for tests of expiry semantics. */
|
|
181
|
+
now?: number;
|
|
182
|
+
}
|
|
183
|
+
/** Static descriptor validation (shape only — does not touch the page).
|
|
184
|
+
* Pure; exported for tests. */
|
|
185
|
+
export declare function validateDescriptor(d: unknown): {
|
|
186
|
+
ok: true;
|
|
187
|
+
descriptor: ActionDescriptor;
|
|
188
|
+
} | {
|
|
189
|
+
ok: false;
|
|
190
|
+
error: string;
|
|
191
|
+
};
|
|
192
|
+
export declare function execute(ctx: ActionContext, rawDescriptor: unknown, opts?: ExecuteOptions): Promise<ExecuteOutcome>;
|