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,226 @@
|
|
|
1
|
+
// The ENGINE-dimension tool gate. It composes with the
|
|
2
|
+
// per-tool capability system in util/capabilities.ts (which answers "is this
|
|
3
|
+
// tool's CAPABILITY in the active set?") by answering a second, orthogonal
|
|
4
|
+
// question: "can the ENGINE backing this session run this tool at all?"
|
|
5
|
+
//
|
|
6
|
+
// The classification covers the ~19 CDP-hard tools plus the tools whose
|
|
7
|
+
// Playwright Firefox lane has no live equivalent. All of them need the raw-CDP
|
|
8
|
+
// escape hatch. On an engine that declares `deep: false` (Firefox — measured:
|
|
9
|
+
// `newCDPSession` throws) they structured-refuse with a hint naming the engine,
|
|
10
|
+
// exactly like the
|
|
11
|
+
// `pdf_save`-on-BYOB and `extensions`-on-incognito refusals already shipped —
|
|
12
|
+
// not by letting `requireCdp` throw an opaque error mid-call.
|
|
13
|
+
//
|
|
14
|
+
// Three tools the critic re-resolved per the spec facts, reflected in
|
|
15
|
+
// the per-engine reason map below:
|
|
16
|
+
// - pdf_save → `browsingContext.print` exists, but Playwright's
|
|
17
|
+
// `page.pdf()` throws off-Chromium (measured: "PDF
|
|
18
|
+
// generation is only supported for Headless Chromium").
|
|
19
|
+
// Gated on Firefox with a Firefox-specific hint — it does
|
|
20
|
+
// NOT crash the session.
|
|
21
|
+
// - network_emulate → spec'd over BiDi (`emulation.setNetworkConditions`) but
|
|
22
|
+
// UNIMPLEMENTED in this Playwright/Juggler build → gated,
|
|
23
|
+
// reason "refuse-pending".
|
|
24
|
+
// - set_user_agent → BiDi `emulation.setUserAgentOverride` is spec'd, but the
|
|
25
|
+
// Playwright Juggler lane has NO live UA setter (measured:
|
|
26
|
+
// `context.setUserAgent` / `page.setUserAgent` are
|
|
27
|
+
// undefined) and the current impl uses CDP
|
|
28
|
+
// `Network.setUserAgentOverride` → gated on Firefox, with a
|
|
29
|
+
// hint pointing at context-creation UA + the BiDi lane.
|
|
30
|
+
import { capabilitiesFor } from "./capabilities.js";
|
|
31
|
+
import { engineCapabilities } from "./capability-registry.js";
|
|
32
|
+
const DEEP_TOOLS_SET = new Set();
|
|
33
|
+
/** Record that a tool needs the raw-CDP (`deep`) escape hatch, from its colocated
|
|
34
|
+
* `host.register({ deep: true })` metadata (RFC 0004 P2). The only writer of the
|
|
35
|
+
* derived `DEEP_TOOLS` set. Idempotent. */
|
|
36
|
+
export function declareDeepTool(tool) {
|
|
37
|
+
DEEP_TOOLS_SET.add(tool);
|
|
38
|
+
}
|
|
39
|
+
/** Lazy-collection seam (RFC 0004 P2), mirroring `installToolMetadataCollector`
|
|
40
|
+
* in capabilities.ts: the tools layer installs a collector that runs the
|
|
41
|
+
* registration metadata once and populates this set. `tool-gate.ts` (engine
|
|
42
|
+
* layer) cannot import the tools layer, so the dependency is inverted here. */
|
|
43
|
+
let deepToolsCollector;
|
|
44
|
+
let deepToolsLoaded = false;
|
|
45
|
+
/** True while the collector is mid-run — a re-entrant `DEEP_TOOLS` read during
|
|
46
|
+
* collection tolerates the partial set without tripping the fail-safe. */
|
|
47
|
+
let deepToolsCollecting = false;
|
|
48
|
+
export function installDeepToolsCollector(collect) {
|
|
49
|
+
deepToolsCollector = collect;
|
|
50
|
+
deepToolsLoaded = false;
|
|
51
|
+
}
|
|
52
|
+
function ensureDeepToolsLoaded() {
|
|
53
|
+
if (deepToolsLoaded || deepToolsCollector === undefined)
|
|
54
|
+
return;
|
|
55
|
+
deepToolsLoaded = true;
|
|
56
|
+
deepToolsCollecting = true;
|
|
57
|
+
try {
|
|
58
|
+
deepToolsCollector();
|
|
59
|
+
}
|
|
60
|
+
finally {
|
|
61
|
+
deepToolsCollecting = false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* D1 fail-safe (RFC 0004 P2, SECURITY-CRITICAL): the ENGINE gate must NEVER fail
|
|
66
|
+
* OPEN. `assertEngineSupports` reads `DEEP_TOOLS.has(tool)` — an empty,
|
|
67
|
+
* unbootstrapped set makes EVERY deep tool look cross-browser, so
|
|
68
|
+
* `assertEngineSupports("perf_start", "firefox")` returns null (un-gated) when
|
|
69
|
+
* the tools-layer bootstrap never ran. Rather than silently un-gate, throw a
|
|
70
|
+
* structured error. The guaranteed bootstrap (`tool-metadata.ts`, reached by
|
|
71
|
+
* every real entry point) keeps this from firing in production; this is the
|
|
72
|
+
* backstop. Suppressed only during collection (the collector's own read sees a
|
|
73
|
+
* partial set legitimately).
|
|
74
|
+
*/
|
|
75
|
+
function assertEngineGateBootstrapped() {
|
|
76
|
+
if (DEEP_TOOLS_SET.size > 0 || deepToolsCollecting)
|
|
77
|
+
return;
|
|
78
|
+
throw new Error("browxai engine gate read before the tool-metadata bootstrap ran: the derived " +
|
|
79
|
+
"DEEP_TOOLS set is empty and no collector was installed. Refusing to fail OPEN " +
|
|
80
|
+
"(which would let every CDP-deep tool run on a non-deep engine). Import the package " +
|
|
81
|
+
'entry ("browxai") or call createServer before reading the engine gate. (RFC 0004 P2 / D1.)');
|
|
82
|
+
}
|
|
83
|
+
/** Tools that require the raw-CDP (`deep`) escape hatch and therefore cannot run
|
|
84
|
+
* on an engine that declares `deep: false`. DERIVED (RFC 0004 P2 / D2) from each
|
|
85
|
+
* tool's `host.register({ deep: true })` metadata; any access drives the lazy
|
|
86
|
+
* collection. A `Proxy` over the live `Set` so membership, `.size`, and
|
|
87
|
+
* iteration all see the derived contents (and the `ReadonlySet<string>` type is
|
|
88
|
+
* inferred from the target, not hand-rolled). */
|
|
89
|
+
/** The membership / size / iteration surfaces an external consumer reads to
|
|
90
|
+
* answer "is this an engine-gated tool?". A read of one of these on an empty
|
|
91
|
+
* unbootstrapped set is the fail-open hazard, so they run the D1 fail-safe;
|
|
92
|
+
* internal/other property reads (Symbol.toStringTag, etc.) pass through. */
|
|
93
|
+
const DEEP_TOOLS_GATE_READS = new Set([
|
|
94
|
+
"has",
|
|
95
|
+
"size",
|
|
96
|
+
"keys",
|
|
97
|
+
"values",
|
|
98
|
+
"entries",
|
|
99
|
+
"forEach",
|
|
100
|
+
Symbol.iterator,
|
|
101
|
+
]);
|
|
102
|
+
export const DEEP_TOOLS = new Proxy(DEEP_TOOLS_SET, {
|
|
103
|
+
get(target, prop) {
|
|
104
|
+
ensureDeepToolsLoaded();
|
|
105
|
+
if (DEEP_TOOLS_GATE_READS.has(prop))
|
|
106
|
+
assertEngineGateBootstrapped();
|
|
107
|
+
// Read off the real Set (not via the Proxy receiver): `size` and the iterator
|
|
108
|
+
// methods touch internal slots and throw on an incompatible receiver, and the
|
|
109
|
+
// methods must keep `this` bound to the backing Set.
|
|
110
|
+
const value = target[prop];
|
|
111
|
+
return typeof value === "function"
|
|
112
|
+
? value.bind(target)
|
|
113
|
+
: value;
|
|
114
|
+
},
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* The pre-P2 hand-maintained `DEEP_TOOLS` block, retained verbatim BELOW as a
|
|
118
|
+
* documentation appendix — the per-tool rationale (which CDP surface each gates,
|
|
119
|
+
* the three critic-re-resolved tools) is preserved, even though the live
|
|
120
|
+
* membership now derives from each `host.register({ deep: true })` call. This
|
|
121
|
+
* block is comment-only. (Reference — not the source of truth.)
|
|
122
|
+
*
|
|
123
|
+
* export const DEEP_TOOLS: ReadonlySet<string> = new Set<string>([
|
|
124
|
+
* // perf / tracing (CDP `Tracing.*`) — Chrome trace-event format, engine-specific
|
|
125
|
+
* "perf_start",
|
|
126
|
+
* "perf_stop",
|
|
127
|
+
* "perf_insights",
|
|
128
|
+
* "perf_audit",
|
|
129
|
+
* "layout_thrash_trace",
|
|
130
|
+
* // coverage (CDP `Profiler.*` / `CSS.*RuleUsageTracking`) — V8/Blink-specific
|
|
131
|
+
* "coverage_start",
|
|
132
|
+
* "coverage_stop",
|
|
133
|
+
* // heap (CDP `HeapProfiler.*`) — V8 `.heapsnapshot` format
|
|
134
|
+
* "heap_snapshot",
|
|
135
|
+
* "heap_retainers",
|
|
136
|
+
* "memory_diff",
|
|
137
|
+
* // CPU throttle (CDP `Emulation.setCPUThrottlingRate`) — Blink-only
|
|
138
|
+
* "cpu_emulate",
|
|
139
|
+
* // network throttle — `emulation.setNetworkConditions` spec'd over BiDi but
|
|
140
|
+
* // not implemented in this Playwright build (reason: refuse-pending)
|
|
141
|
+
* "network_emulate",
|
|
142
|
+
* // Service-Worker fetch interception (CDP `Fetch.*` on the SW target)
|
|
143
|
+
* "sw_intercept_fetch",
|
|
144
|
+
* "sw_unintercept_fetch",
|
|
145
|
+
* // virtual time clock (CDP `Emulation.setVirtualTimePolicy`)
|
|
146
|
+
* "clock",
|
|
147
|
+
* // Chromium extension management (launch flags + CDP) — no Playwright Firefox API
|
|
148
|
+
* "extensions_install",
|
|
149
|
+
* "extensions_list",
|
|
150
|
+
* "extensions_reload",
|
|
151
|
+
* "extensions_trigger",
|
|
152
|
+
* "extensions_uninstall",
|
|
153
|
+
* // print to PDF — Playwright `page.pdf()` throws off Headless Chromium (measured)
|
|
154
|
+
* "pdf_save",
|
|
155
|
+
* // live locale / timezone / UA override (CDP `Emulation.*` / `Network.*`) —
|
|
156
|
+
* // Playwright bakes these at context creation; no live off-Chromium setter
|
|
157
|
+
* "set_locale",
|
|
158
|
+
* "set_timezone",
|
|
159
|
+
* "set_user_agent",
|
|
160
|
+
* // coordinate-space wheel + the touch/gesture family (CDP `Input.dispatch*`)
|
|
161
|
+
* "mouse_wheel",
|
|
162
|
+
* "touch_start",
|
|
163
|
+
* "touch_move",
|
|
164
|
+
* "touch_end",
|
|
165
|
+
* "gesture_pinch",
|
|
166
|
+
* "gesture_swipe",
|
|
167
|
+
* // closed-shadow piercing — CDP `DOM.getDocument({pierce:true})` is the only
|
|
168
|
+
* // automation-protocol path into closed shadow roots; no off-Chromium
|
|
169
|
+
* // equivalent (the one true feature-level loss). The open-shadow
|
|
170
|
+
* // half is portable, but the tool's headline (closed-shadow introspection) is
|
|
171
|
+
* // CDP-bound, so the whole tool gates off Chromium.
|
|
172
|
+
* "shadow_trees",
|
|
173
|
+
* ]);
|
|
174
|
+
*/
|
|
175
|
+
/** Per-tool reason fragment appended to the refusal hint. Most tools share the
|
|
176
|
+
* generic "needs raw CDP" reason; the three the critic re-resolved carry a
|
|
177
|
+
* more specific note so the agent knows the per-engine path (or its absence). */
|
|
178
|
+
const TOOL_REASON = {
|
|
179
|
+
network_emulate: "Link-condition throttling is spec'd over WebDriver BiDi " +
|
|
180
|
+
"(`emulation.setNetworkConditions`) but not yet implemented in this Playwright build " +
|
|
181
|
+
"— refuse-pending. Route-level `delayMs` approximations still work cross-engine.",
|
|
182
|
+
set_user_agent: "Playwright has no live user-agent setter off Chromium (the current path uses " +
|
|
183
|
+
"CDP `Network.setUserAgentOverride`). Bake the UA at session creation instead: " +
|
|
184
|
+
'`open_session({ device: { userAgent: "…" } })`. Live BiDi UA override ' +
|
|
185
|
+
"(`emulation.setUserAgentOverride`) arrives with the stock-Firefox BiDi lane.",
|
|
186
|
+
pdf_save: "Playwright `page.pdf()` is Headless-Chromium-only and throws on Firefox " +
|
|
187
|
+
"(`browsingContext.print` over BiDi is the eventual path). Open a chromium session to print.",
|
|
188
|
+
set_locale: "Live locale override uses CDP `Emulation.setLocaleOverride`. Bake it at session " +
|
|
189
|
+
"creation (`open_session({ locale })`) or use a chromium session for mid-session override.",
|
|
190
|
+
set_timezone: "Live timezone override uses CDP `Emulation.setTimezoneOverride`. Bake it at session " +
|
|
191
|
+
"creation (`open_session({ timezone })`) or use a chromium session for mid-session override.",
|
|
192
|
+
};
|
|
193
|
+
const GENERIC_REASON = "This tool needs the raw-CDP escape hatch (perf / coverage / heap / CPU+network " +
|
|
194
|
+
"throttle / SW interception / virtual clock / extensions / CDP input dispatch), which " +
|
|
195
|
+
"exists only on chromium. These tools are gated, not ported, per engine.";
|
|
196
|
+
/** Returns a structured refusal when `tool` cannot run on `engine`, else null.
|
|
197
|
+
* Null is the fast path on chromium (the only engine with `deep`) and on every
|
|
198
|
+
* cross-browser tool regardless of engine — a single Set lookup + a capability
|
|
199
|
+
* read, no allocation on the supported path. */
|
|
200
|
+
export function assertEngineSupports(tool, engine) {
|
|
201
|
+
// D1 fail-safe FIRST: a `DEEP_TOOLS.has` on an empty unbootstrapped set returns
|
|
202
|
+
// false for every tool, so the early `return null` below would un-gate the
|
|
203
|
+
// whole engine matrix. Assert the gate is bootstrapped before trusting the
|
|
204
|
+
// membership read. (`DEEP_TOOLS.has` drives the lazy collection.)
|
|
205
|
+
ensureDeepToolsLoaded();
|
|
206
|
+
assertEngineGateBootstrapped();
|
|
207
|
+
if (!DEEP_TOOLS.has(tool))
|
|
208
|
+
return null;
|
|
209
|
+
// Prefer the EngineRegistry's capability record (RFC 0004 P1) — it is the source
|
|
210
|
+
// of truth post-D1 and is what gates an engine registered ONLY at runtime (e.g.
|
|
211
|
+
// the synthetic contract-test engine, whose `deep:false` is declared at
|
|
212
|
+
// registration, not in the central `capabilitiesFor` table). Fall back to the
|
|
213
|
+
// central declaration for any engine queried before its registration runs.
|
|
214
|
+
const caps = engineCapabilities(engine) ?? capabilitiesFor(engine);
|
|
215
|
+
// An engine with the deep escape hatch (chromium) runs everything; an engine
|
|
216
|
+
// whose declaration hasn't landed yet is left to the launch path to reject.
|
|
217
|
+
if (!caps || caps.deep)
|
|
218
|
+
return null;
|
|
219
|
+
const reason = TOOL_REASON[tool] ?? GENERIC_REASON;
|
|
220
|
+
return {
|
|
221
|
+
error: `tool "${tool}" is not supported on the "${engine}" engine`,
|
|
222
|
+
hint: `${reason} ` +
|
|
223
|
+
`Re-run on a chromium session (browserType:"chromium", the default), or check the ` +
|
|
224
|
+
`per-engine capability matrix in docs/ai-context/architecture/engine-adapters.md.`,
|
|
225
|
+
};
|
|
226
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Browser, BrowserContext, CDPSession, Page } from "playwright-core";
|
|
2
|
+
/** The browser engines this port targets. chromium / firefox / webkit are the
|
|
3
|
+
* desktop engines. `android` is real Chrome-on-Android attached
|
|
4
|
+
* over adb + CDP — it IS Chromium, so it reuses the CDP substrates verbatim and
|
|
5
|
+
* declares `deep: true` (every tool, including the CDP-deep ones, works). It is
|
|
6
|
+
* a DISTINCT kind, not `chromium`, because its launch model is attach-only
|
|
7
|
+
* (adb socket discovery → `connectOverCDP`) and managed/ephemeral launch on a
|
|
8
|
+
* phone is not a thing the desktop adapters' shape covers. */
|
|
9
|
+
export type EngineKind = "chromium" | "firefox" | "webkit" | "android" | "safari";
|
|
10
|
+
export declare const ENGINE_KINDS: readonly EngineKind[];
|
|
11
|
+
/** Capability-segregated sub-interfaces of the port. An adapter declares which
|
|
12
|
+
* ones it supports via `EngineCapabilities`; a tool that needs `deep` (CDP) is
|
|
13
|
+
* refused on an engine that lacks it through the existing capability gate.
|
|
14
|
+
*
|
|
15
|
+
* The method set is derived from what the session layer + tools ACTUALLY call
|
|
16
|
+
* today — interface segregation means each sub-interface is only what real
|
|
17
|
+
* callers need, not a speculative superset.
|
|
18
|
+
*
|
|
19
|
+
* Today the live port surface is intentionally thin: the session layer is the
|
|
20
|
+
* only consumer, so the port exposes the lifecycle handles the rest of the
|
|
21
|
+
* server already builds on (`Page`, `BrowserContext`, optional `CDPSession`).
|
|
22
|
+
* The sub-interface NAMES below are the typed map of where each engine-specific
|
|
23
|
+
* behavior lives as adapters grow; they are documented on
|
|
24
|
+
* `EngineCapabilities`, not yet split into separate method bundles, because
|
|
25
|
+
* splitting before the second adapter exists would be the speculative
|
|
26
|
+
* generality the doctrine forbids. */
|
|
27
|
+
export type EngineSubInterface = "lifecycle" | "navigation" | "snapshot" | "input" | "network" | "storage" | "script" | "emulation" | "capture" | "page";
|
|
28
|
+
/** Declares what an adapter supports. Composes with the existing per-tool
|
|
29
|
+
* capability system (util/capabilities.ts) — this is the ENGINE dimension.
|
|
30
|
+
* Chromium declares every sub-interface plus `deep`, so nothing is newly gated
|
|
31
|
+
* today. An adapter that lacks `deep` (no CDP escape hatch) declares
|
|
32
|
+
* `deep: false`; the ~19 CDP-hard tools are then refused on it
|
|
33
|
+
* through the capability gate, not by throwing a vague error mid-call. */
|
|
34
|
+
export interface EngineCapabilities {
|
|
35
|
+
readonly engine: EngineKind;
|
|
36
|
+
/** Sub-interfaces this adapter implements. Chromium: all of them. */
|
|
37
|
+
readonly subInterfaces: ReadonlySet<EngineSubInterface>;
|
|
38
|
+
/** Whether the adapter exposes the `Deep` (raw-CDP) escape hatch — the typed
|
|
39
|
+
* home for the ~19 CDP-hard operations. Chromium: true. Firefox/WebKit will
|
|
40
|
+
* declare false and gate those tools. */
|
|
41
|
+
readonly deep: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** A live engine-backed session. The adapter owns engine selection + launch;
|
|
44
|
+
* the rest of the server consumes these handles exactly as it did before the
|
|
45
|
+
* seam existed — `page()` / `context()` are the cross-browser surface, `cdp()`
|
|
46
|
+
* is the engine-specific (Chromium) escape hatch and is now OPTIONAL.
|
|
47
|
+
*
|
|
48
|
+
* `cdp()` was a mandatory member of `BrowserSession`; that single line hard-
|
|
49
|
+
* gated multi-engine because `newCDPSession` throws off-Chromium. It is now a
|
|
50
|
+
* capability the adapter exposes: present + fully functional on Chromium,
|
|
51
|
+
* absent on engines without CDP. Consumers that need it go through
|
|
52
|
+
* `requireCdp()` (see ./session-cdp.ts), which asserts presence with a
|
|
53
|
+
* structured, engine-naming error — never a silent failure. */
|
|
54
|
+
export interface EngineSession {
|
|
55
|
+
readonly engine: EngineKind;
|
|
56
|
+
readonly capabilities: EngineCapabilities;
|
|
57
|
+
page(): Page;
|
|
58
|
+
context(): BrowserContext;
|
|
59
|
+
/** Raw CDP handle. Present only when `capabilities.deep` is true (Chromium).
|
|
60
|
+
* Undefined on engines without a CDP escape hatch. */
|
|
61
|
+
cdp?(): CDPSession;
|
|
62
|
+
close(): Promise<void>;
|
|
63
|
+
}
|
|
64
|
+
/** Internal handles an adapter wires up at launch, before the session-layer
|
|
65
|
+
* bookkeeping (buffers, bridge, policies) attaches to them. */
|
|
66
|
+
export interface EngineLaunchHandles {
|
|
67
|
+
browser?: Browser;
|
|
68
|
+
context: BrowserContext;
|
|
69
|
+
page: Page;
|
|
70
|
+
cdp?: CDPSession;
|
|
71
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// The BrowserEngine port — the seam beneath the session layer that lets browxai
|
|
2
|
+
// drive engines other than Chromium without rewriting the ~139 tools that
|
|
3
|
+
// already speak only Playwright's cross-browser surface. See
|
|
4
|
+
// docs/ai-context/architecture/engine-adapters.md for the strangler-fig design.
|
|
5
|
+
//
|
|
6
|
+
// Today Chromium is the only implemented engine. The port exists so the second
|
|
7
|
+
// engine (Firefox) lands as a new adapter, not a core rewrite — the proven-seam
|
|
8
|
+
// test in architecture-principles.md is satisfied because Firefox/WebKit are the
|
|
9
|
+
// committed next engines and every coupling seam is already named.
|
|
10
|
+
export const ENGINE_KINDS = [
|
|
11
|
+
"chromium",
|
|
12
|
+
"firefox",
|
|
13
|
+
"webkit",
|
|
14
|
+
"android",
|
|
15
|
+
"safari",
|
|
16
|
+
];
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { BrowserContext } from "playwright-core";
|
|
2
|
+
export interface BrowxSignal {
|
|
3
|
+
name: string;
|
|
4
|
+
data: unknown;
|
|
5
|
+
ts: number;
|
|
6
|
+
/** URL of the page that emitted it (best-effort). */
|
|
7
|
+
url?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare class BrowxBridge {
|
|
10
|
+
private cap;
|
|
11
|
+
private signals;
|
|
12
|
+
private waiters;
|
|
13
|
+
private pollers;
|
|
14
|
+
private bindingOk;
|
|
15
|
+
/** track attached contexts so detach() can install in-page opt-out
|
|
16
|
+
* markers and known-disconnect handlers can stop nagging the user with
|
|
17
|
+
* "function not exposed" console noise after our session ends. */
|
|
18
|
+
private contexts;
|
|
19
|
+
/** once true, our exposeBinding handler quietly drops incoming
|
|
20
|
+
* payloads and the page script's `send()` is told (via `__browx_no_binding`)
|
|
21
|
+
* to skip the binding and use the DOM-attribute path. */
|
|
22
|
+
private detached;
|
|
23
|
+
constructor(cap?: number);
|
|
24
|
+
attach(context: BrowserContext): Promise<void>;
|
|
25
|
+
/** Stop all pollers, reject outstanding waiters, and flip the
|
|
26
|
+
* in-page `__browx_no_binding` flag so any subsequent `__browx.signal()`
|
|
27
|
+
* / `.confirm()` etc. from the page goes through the DOM-attribute path
|
|
28
|
+
* instead of the now-detached `__browx_send` exposeBinding glue —
|
|
29
|
+
* silencing the "Function `__browx_send` is not exposed" console errors
|
|
30
|
+
* that the shared-CDP verification run flagged. */
|
|
31
|
+
detach(): Promise<void>;
|
|
32
|
+
/** test introspection — true once detach() has fired. */
|
|
33
|
+
isDetached(): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Wait for the next signal matching `name` (or any signal if `name` is omitted).
|
|
36
|
+
* `timeoutMs > 0` rejects with a timeout error; `0` waits indefinitely.
|
|
37
|
+
*/
|
|
38
|
+
awaitSignal(name?: string, timeoutMs?: number): Promise<BrowxSignal>;
|
|
39
|
+
private onSignal;
|
|
40
|
+
/**
|
|
41
|
+
* DOM-attribute fallback: every ~250ms, read `documentElement.dataset.browxSignal`,
|
|
42
|
+
* and if it differs from the last seen value, dispatch + clear. Lets the in-page
|
|
43
|
+
* helper still talk to us when the CDP binding is clobbered.
|
|
44
|
+
*/
|
|
45
|
+
private startPolling;
|
|
46
|
+
/** True if the CDP binding installed cleanly. (Polling fallback runs either way.) */
|
|
47
|
+
bindingHealthy(): boolean;
|
|
48
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// Server-side `__browx` bridge. Wires the in-page script + the `__browx_send`
|
|
2
|
+
// CDP binding, queues signals, and exposes `awaitSignal(name, timeout)` that
|
|
3
|
+
// resolves on the next matching `__browx.signal()` / `proceed()` / `abort()` /
|
|
4
|
+
// `done()` call from the page.
|
|
5
|
+
//
|
|
6
|
+
// scope:
|
|
7
|
+
// ✓ signal queue + awaitSignal (the site-docs `manual-capture` use case is
|
|
8
|
+
// `awaitHuman({kind:"acknowledge"})` → human calls `__browx.proceed()` →
|
|
9
|
+
// server unblocks).
|
|
10
|
+
// ✓ DOM-attribute-polling fallback for environments where `exposeBinding`
|
|
11
|
+
// gets clobbered (BYOB multi-attach — Playwright #34359).
|
|
12
|
+
// ✗ Shadow-DOM banner UI; `confirm` / `choose` / `input` / `pick_element`
|
|
13
|
+
// kinds — polish.
|
|
14
|
+
import { BROWX_PAGE_SCRIPT } from "./browx-page.js";
|
|
15
|
+
import { log } from "../util/logging.js";
|
|
16
|
+
export class BrowxBridge {
|
|
17
|
+
cap;
|
|
18
|
+
signals = [];
|
|
19
|
+
waiters = [];
|
|
20
|
+
pollers = new Map();
|
|
21
|
+
bindingOk = false;
|
|
22
|
+
/** track attached contexts so detach() can install in-page opt-out
|
|
23
|
+
* markers and known-disconnect handlers can stop nagging the user with
|
|
24
|
+
* "function not exposed" console noise after our session ends. */
|
|
25
|
+
contexts = [];
|
|
26
|
+
/** once true, our exposeBinding handler quietly drops incoming
|
|
27
|
+
* payloads and the page script's `send()` is told (via `__browx_no_binding`)
|
|
28
|
+
* to skip the binding and use the DOM-attribute path. */
|
|
29
|
+
detached = false;
|
|
30
|
+
constructor(cap = 200) {
|
|
31
|
+
this.cap = cap;
|
|
32
|
+
}
|
|
33
|
+
async attach(context) {
|
|
34
|
+
this.contexts.push(context);
|
|
35
|
+
try {
|
|
36
|
+
await context.exposeBinding("__browx_send", (source, payload) => {
|
|
37
|
+
if (this.detached)
|
|
38
|
+
return; // quiet drop after detach.
|
|
39
|
+
try {
|
|
40
|
+
const o = JSON.parse(payload);
|
|
41
|
+
if (o.kind === "signal")
|
|
42
|
+
this.onSignal({ name: o.name, data: o.data, ts: Date.now(), url: source.page?.url() });
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
log.warn("browx-bridge: bad payload", {
|
|
46
|
+
error: e instanceof Error ? e.message : String(e),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
this.bindingOk = true;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
log.warn("browx-bridge: exposeBinding failed; will use DOM-attribute polling only", {
|
|
54
|
+
error: e instanceof Error ? e.message : String(e),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
await context.addInitScript({ content: BROWX_PAGE_SCRIPT });
|
|
58
|
+
// Re-inject into pages that already exist.
|
|
59
|
+
for (const page of context.pages()) {
|
|
60
|
+
await page.evaluate(BROWX_PAGE_SCRIPT).catch(() => undefined);
|
|
61
|
+
this.startPolling(page);
|
|
62
|
+
}
|
|
63
|
+
context.on("page", (page) => {
|
|
64
|
+
page.evaluate(BROWX_PAGE_SCRIPT).catch(() => undefined);
|
|
65
|
+
this.startPolling(page);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Stop all pollers, reject outstanding waiters, and flip the
|
|
69
|
+
* in-page `__browx_no_binding` flag so any subsequent `__browx.signal()`
|
|
70
|
+
* / `.confirm()` etc. from the page goes through the DOM-attribute path
|
|
71
|
+
* instead of the now-detached `__browx_send` exposeBinding glue —
|
|
72
|
+
* silencing the "Function `__browx_send` is not exposed" console errors
|
|
73
|
+
* that the shared-CDP verification run flagged. */
|
|
74
|
+
detach() {
|
|
75
|
+
this.detached = true;
|
|
76
|
+
for (const t of this.pollers.values())
|
|
77
|
+
clearInterval(t);
|
|
78
|
+
this.pollers.clear();
|
|
79
|
+
for (const w of this.waiters) {
|
|
80
|
+
if (w.timeout)
|
|
81
|
+
clearTimeout(w.timeout);
|
|
82
|
+
w.reject(new Error("bridge detached"));
|
|
83
|
+
}
|
|
84
|
+
this.waiters = [];
|
|
85
|
+
const setOptOut = () => {
|
|
86
|
+
const w = Reflect.get(globalThis, "window");
|
|
87
|
+
if (w)
|
|
88
|
+
w.__browx_no_binding = true;
|
|
89
|
+
};
|
|
90
|
+
for (const ctx of this.contexts) {
|
|
91
|
+
try {
|
|
92
|
+
for (const page of ctx.pages()) {
|
|
93
|
+
page.evaluate(setOptOut).catch(() => undefined);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
/* context already torn down */
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
this.contexts = [];
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
103
|
+
/** test introspection — true once detach() has fired. */
|
|
104
|
+
isDetached() {
|
|
105
|
+
return this.detached;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Wait for the next signal matching `name` (or any signal if `name` is omitted).
|
|
109
|
+
* `timeoutMs > 0` rejects with a timeout error; `0` waits indefinitely.
|
|
110
|
+
*/
|
|
111
|
+
awaitSignal(name, timeoutMs = 0) {
|
|
112
|
+
// Already-queued signal? (rare — usually we install the waiter before the
|
|
113
|
+
// human acts, but acknowledge-mode might pre-fire if the human is fast.)
|
|
114
|
+
if (name) {
|
|
115
|
+
const idx = this.signals.findIndex((s) => s.name === name);
|
|
116
|
+
if (idx >= 0)
|
|
117
|
+
return Promise.resolve(this.signals.splice(idx, 1)[0]);
|
|
118
|
+
}
|
|
119
|
+
else if (this.signals.length) {
|
|
120
|
+
return Promise.resolve(this.signals.shift());
|
|
121
|
+
}
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const w = { name, resolve, reject };
|
|
124
|
+
if (timeoutMs > 0) {
|
|
125
|
+
w.timeout = setTimeout(() => {
|
|
126
|
+
const i = this.waiters.indexOf(w);
|
|
127
|
+
if (i >= 0)
|
|
128
|
+
this.waiters.splice(i, 1);
|
|
129
|
+
reject(new Error(`awaitHuman timed out after ${timeoutMs}ms`));
|
|
130
|
+
}, timeoutMs);
|
|
131
|
+
}
|
|
132
|
+
this.waiters.push(w);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
onSignal(sig) {
|
|
136
|
+
log.info("browx-bridge: signal", { name: sig.name, url: sig.url });
|
|
137
|
+
// Match the *first* waiter wanting this name (FIFO). If none, queue.
|
|
138
|
+
for (let i = 0; i < this.waiters.length; i++) {
|
|
139
|
+
const w = this.waiters[i];
|
|
140
|
+
if (!w.name || w.name === sig.name) {
|
|
141
|
+
this.waiters.splice(i, 1);
|
|
142
|
+
if (w.timeout)
|
|
143
|
+
clearTimeout(w.timeout);
|
|
144
|
+
w.resolve(sig);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
this.signals.push(sig);
|
|
149
|
+
if (this.signals.length > this.cap)
|
|
150
|
+
this.signals.shift();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* DOM-attribute fallback: every ~250ms, read `documentElement.dataset.browxSignal`,
|
|
154
|
+
* and if it differs from the last seen value, dispatch + clear. Lets the in-page
|
|
155
|
+
* helper still talk to us when the CDP binding is clobbered.
|
|
156
|
+
*/
|
|
157
|
+
startPolling(page) {
|
|
158
|
+
if (this.pollers.has(page))
|
|
159
|
+
return;
|
|
160
|
+
let lastSeen = null;
|
|
161
|
+
const tick = async () => {
|
|
162
|
+
try {
|
|
163
|
+
const raw = await page.evaluate(() => {
|
|
164
|
+
// Runs in page context; cast through unknown to keep ts happy server-side.
|
|
165
|
+
const doc = globalThis.document;
|
|
166
|
+
if (!doc)
|
|
167
|
+
return null;
|
|
168
|
+
const v = doc.documentElement.getAttribute("data-browx-signal");
|
|
169
|
+
if (v)
|
|
170
|
+
doc.documentElement.removeAttribute("data-browx-signal");
|
|
171
|
+
return v;
|
|
172
|
+
});
|
|
173
|
+
if (raw && raw !== lastSeen) {
|
|
174
|
+
lastSeen = raw;
|
|
175
|
+
const o = JSON.parse(raw);
|
|
176
|
+
if (o.kind === "signal")
|
|
177
|
+
this.onSignal({ name: o.name, data: o.data, ts: o.ts, url: page.url() });
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Page may have closed / navigated mid-poll.
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const t = setInterval(() => {
|
|
185
|
+
void tick();
|
|
186
|
+
}, 250);
|
|
187
|
+
this.pollers.set(page, t);
|
|
188
|
+
page.on("close", () => {
|
|
189
|
+
const it = this.pollers.get(page);
|
|
190
|
+
if (it) {
|
|
191
|
+
clearInterval(it);
|
|
192
|
+
this.pollers.delete(page);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/** True if the CDP binding installed cleanly. (Polling fallback runs either way.) */
|
|
197
|
+
bindingHealthy() {
|
|
198
|
+
return this.bindingOk;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const BROWX_PAGE_SCRIPT = "(() => {\n if (window.__browx) return;\n function viaAttribute(kind, name, data) {\n try {\n document.documentElement.setAttribute(\n \"data-browx-signal\",\n JSON.stringify({ kind: kind, name: name, data: data == null ? null : data, ts: Date.now() })\n );\n } catch (_) {}\n }\n function send(kind, name, data) {\n // when our bridge has detached (set window.__browx_no_binding = true),\n // skip the now-detached __browx_send exposeBinding glue entirely \u2014 it would\n // emit \"Function __browx_send is not exposed\" console errors on every call.\n if (window.__browx_no_binding || typeof window.__browx_send !== \"function\") {\n viaAttribute(kind, name, data);\n return;\n }\n try { window.__browx_send(JSON.stringify({ kind: kind, name: name, data: data == null ? null : data })); }\n catch (e) { /* binding may have been clobbered (CDP multi-attach); fall back to DOM-attribute path */\n viaAttribute(kind, name, data);\n }\n }\n window.__browx = {\n signal: function (name, data) { send(\"signal\", name, data); },\n proceed: function (data) { send(\"signal\", \"proceed\", data == null ? null : data); },\n abort: function (reason) { send(\"signal\", \"abort\", reason == null ? null : reason); },\n done: function (what, data) { send(\"signal\", \"did\", { what: what, data: data == null ? null : data }); },\n // typed responses to await_human({kind:\"confirm|choose|input\"}). The\n // human reads the prompt from the runbook / terminal stderr, then calls one\n // of these from DevTools (or a future shadow-DOM banner UI will call them).\n respond: function (value) { send(\"signal\", \"respond\", value); },\n confirm: function (yes) { send(\"signal\", \"respond\", { kind: \"confirm\", value: !!yes }); },\n choose: function (idx) { send(\"signal\", \"respond\", { kind: \"choose\", value: idx }); },\n input: function (text) { send(\"signal\", \"respond\", { kind: \"input\", value: String(text == null ? \"\" : text) }); },\n status: function () { return { state: \"ready\" }; },\n };\n try { console.info(\"[browxai] __browx ready. window.__browx.proceed() releases any awaiting tool. For await_human kinds: confirm(true|false) / choose(idx) / input(text).\"); } catch (_) {}\n})();";
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// In-page script that defines window.__browx. Injected via addInitScript so it
|
|
2
|
+
// runs on every navigation / new document, and evaluated directly on already-open
|
|
3
|
+
// pages at attach time. Tiny and self-contained — no framework, no DOM banner
|
|
4
|
+
// (the shadow-DOM banner UI is a polish; for now we log a one-line
|
|
5
|
+
// hint to the console so a human in DevTools knows the API is there).
|
|
6
|
+
//
|
|
7
|
+
// stringified so it can be passed as a script source. Keep the contents
|
|
8
|
+
// browser-only JS — no TS-only syntax.
|
|
9
|
+
export const BROWX_PAGE_SCRIPT = `(() => {
|
|
10
|
+
if (window.__browx) return;
|
|
11
|
+
function viaAttribute(kind, name, data) {
|
|
12
|
+
try {
|
|
13
|
+
document.documentElement.setAttribute(
|
|
14
|
+
"data-browx-signal",
|
|
15
|
+
JSON.stringify({ kind: kind, name: name, data: data == null ? null : data, ts: Date.now() })
|
|
16
|
+
);
|
|
17
|
+
} catch (_) {}
|
|
18
|
+
}
|
|
19
|
+
function send(kind, name, data) {
|
|
20
|
+
// when our bridge has detached (set window.__browx_no_binding = true),
|
|
21
|
+
// skip the now-detached __browx_send exposeBinding glue entirely — it would
|
|
22
|
+
// emit "Function __browx_send is not exposed" console errors on every call.
|
|
23
|
+
if (window.__browx_no_binding || typeof window.__browx_send !== "function") {
|
|
24
|
+
viaAttribute(kind, name, data);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
try { window.__browx_send(JSON.stringify({ kind: kind, name: name, data: data == null ? null : data })); }
|
|
28
|
+
catch (e) { /* binding may have been clobbered (CDP multi-attach); fall back to DOM-attribute path */
|
|
29
|
+
viaAttribute(kind, name, data);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
window.__browx = {
|
|
33
|
+
signal: function (name, data) { send("signal", name, data); },
|
|
34
|
+
proceed: function (data) { send("signal", "proceed", data == null ? null : data); },
|
|
35
|
+
abort: function (reason) { send("signal", "abort", reason == null ? null : reason); },
|
|
36
|
+
done: function (what, data) { send("signal", "did", { what: what, data: data == null ? null : data }); },
|
|
37
|
+
// typed responses to await_human({kind:"confirm|choose|input"}). The
|
|
38
|
+
// human reads the prompt from the runbook / terminal stderr, then calls one
|
|
39
|
+
// of these from DevTools (or a future shadow-DOM banner UI will call them).
|
|
40
|
+
respond: function (value) { send("signal", "respond", value); },
|
|
41
|
+
confirm: function (yes) { send("signal", "respond", { kind: "confirm", value: !!yes }); },
|
|
42
|
+
choose: function (idx) { send("signal", "respond", { kind: "choose", value: idx }); },
|
|
43
|
+
input: function (text) { send("signal", "respond", { kind: "input", value: String(text == null ? "" : text) }); },
|
|
44
|
+
status: function () { return { state: "ready" }; },
|
|
45
|
+
};
|
|
46
|
+
try { console.info("[browxai] __browx ready. window.__browx.proceed() releases any awaiting tool. For await_human kinds: confirm(true|false) / choose(idx) / input(text)."); } catch (_) {}
|
|
47
|
+
})();`;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BrowserContext } from "playwright-core";
|
|
2
|
+
/** Build the init-script body for the given selectors. Selectors are embedded
|
|
3
|
+
* as JSON string literals (no expression interpolation) and written via
|
|
4
|
+
* `style.textContent` (not parsed as HTML), so a hostile selector can at
|
|
5
|
+
* worst break its own CSS rule — it cannot escape into script. */
|
|
6
|
+
export declare function buildOverlayHideScript(selectors: string[]): string;
|
|
7
|
+
/** Register the overlay-hide init script on a context and apply it to any
|
|
8
|
+
* already-open pages. No-op when `selectors` is empty (feature off). */
|
|
9
|
+
export declare function applyOverlayHide(context: BrowserContext, selectors: string[]): Promise<void>;
|