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,162 @@
|
|
|
1
|
+
// Confirmation hooks — policy. Routes potentially-irreversible operations
|
|
2
|
+
// through `await_human({kind:"confirm"})` before they dispatch. See `docs/threat-model.md`
|
|
3
|
+
// "The capability set" → confirm_required.
|
|
4
|
+
//
|
|
5
|
+
// Hooks defined:
|
|
6
|
+
// - navigate_off_allowlist: navigate() to a URL outside BROWX_ALLOWED_ORIGINS
|
|
7
|
+
// - byob_action: any action while attached over BROWX_ATTACH_CDP
|
|
8
|
+
// - file_download / file_upload: (slot reserved; future tools)
|
|
9
|
+
//
|
|
10
|
+
// Configuring via env: BROWX_CONFIRM_REQUIRED (handled in src/util/capabilities.ts).
|
|
11
|
+
import { isOriginAllowed } from "./origin.js";
|
|
12
|
+
import { log } from "../util/logging.js";
|
|
13
|
+
/**
|
|
14
|
+
* session-scoped pre-approvals. The non-Claude verification path
|
|
15
|
+
* surfaced that `__browx.confirm(true)` is operator-driven — a non-Claude MCP
|
|
16
|
+
* client can't drive it from inside a blocked action call. This store lets
|
|
17
|
+
* the client pre-approve confirm scopes for a TTL window. Each grant +
|
|
18
|
+
* consume is logged for audit.
|
|
19
|
+
*
|
|
20
|
+
* Pre-approval is *not* an override; the confirm hook still runs, finds the
|
|
21
|
+
* grant, and returns ok:true with `reason: "pre-approved"`. The page-side
|
|
22
|
+
* channel is the fallback when no pre-approval covers the scope.
|
|
23
|
+
*/
|
|
24
|
+
export class ApprovalStore {
|
|
25
|
+
grants = new Map();
|
|
26
|
+
/** Grant a scope for `ttlSeconds`. Overwrites any prior grant for the same scope. */
|
|
27
|
+
grant(scope, ttlSeconds) {
|
|
28
|
+
const ttl = Math.max(1, Math.floor(ttlSeconds));
|
|
29
|
+
const expiresAt = Date.now() + ttl * 1000;
|
|
30
|
+
this.grants.set(scope, { expiresAt, grantedAt: Date.now(), uses: 0 });
|
|
31
|
+
log.info(`approve_actions: scope="${scope}" ttl=${ttl}s expires=${new Date(expiresAt).toISOString()}`);
|
|
32
|
+
}
|
|
33
|
+
/** Revoke a previously-granted scope. Returns true if a live grant existed. */
|
|
34
|
+
revoke(scope) {
|
|
35
|
+
const had = this.grants.delete(scope);
|
|
36
|
+
if (had)
|
|
37
|
+
log.info(`approve_actions: revoked scope="${scope}"`);
|
|
38
|
+
return had;
|
|
39
|
+
}
|
|
40
|
+
/** Check (and consume) a grant. Returns true when an unexpired grant covers
|
|
41
|
+
* the scope — the call is counted toward audit. Returns false (and evicts
|
|
42
|
+
* the grant) when the grant has expired. */
|
|
43
|
+
consume(scope) {
|
|
44
|
+
const grant = this.grants.get(scope);
|
|
45
|
+
if (!grant)
|
|
46
|
+
return false;
|
|
47
|
+
if (Date.now() > grant.expiresAt) {
|
|
48
|
+
this.grants.delete(scope);
|
|
49
|
+
log.info(`approve_actions: scope="${scope}" expired`);
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
grant.uses++;
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
/** Snapshot of live grants for audit / `list_approvals` style tooling. */
|
|
56
|
+
list() {
|
|
57
|
+
const now = Date.now();
|
|
58
|
+
const out = [];
|
|
59
|
+
for (const [scope, grant] of this.grants) {
|
|
60
|
+
if (now > grant.expiresAt)
|
|
61
|
+
continue;
|
|
62
|
+
out.push({
|
|
63
|
+
scope,
|
|
64
|
+
grantedAt: grant.grantedAt,
|
|
65
|
+
expiresAt: grant.expiresAt,
|
|
66
|
+
uses: grant.uses,
|
|
67
|
+
remainingMs: grant.expiresAt - now,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Decide whether navigate() may proceed. If the URL is on-allowlist (or there's no
|
|
75
|
+
* allowlist), proceeds without asking. If off-allowlist:
|
|
76
|
+
* - if `navigate_off_allowlist` is in `hooks`, asks for human confirm via the bridge;
|
|
77
|
+
* - otherwise proceeds with a stderr warning.
|
|
78
|
+
*
|
|
79
|
+
* Returns `{ ok: false }` only when the human declined; never auto-denies (this is
|
|
80
|
+
* defense-in-depth, not a boundary).
|
|
81
|
+
*/
|
|
82
|
+
export async function confirmNavigation(url, ctx) {
|
|
83
|
+
if (isOriginAllowed(url, ctx.policy)) {
|
|
84
|
+
return { ok: true, reason: "on-allowlist", asked: false };
|
|
85
|
+
}
|
|
86
|
+
if (!ctx.hooks.has("navigate_off_allowlist")) {
|
|
87
|
+
log.warn(`navigate: ${url} is off the allowed-origins list; no confirm hook set, proceeding`);
|
|
88
|
+
return { ok: true, reason: "off-allowlist; no hook", asked: false };
|
|
89
|
+
}
|
|
90
|
+
if (ctx.approvals?.consume("navigate_off_allowlist")) {
|
|
91
|
+
return { ok: true, reason: "pre-approved", asked: false };
|
|
92
|
+
}
|
|
93
|
+
if (!ctx.bridge) {
|
|
94
|
+
// No bridge means no way to confirm — fail closed.
|
|
95
|
+
return {
|
|
96
|
+
ok: false,
|
|
97
|
+
reason: "off-allowlist; no helper bridge to confirm; blocked",
|
|
98
|
+
asked: false,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
log.info(`confirm navigate (off-allowlist): ${url} — call __browx.confirm(true) to proceed`);
|
|
102
|
+
try {
|
|
103
|
+
const sig = await ctx.bridge.awaitSignal("respond", 5 * 60_000);
|
|
104
|
+
const value = sig.data && typeof sig.data === "object" && "value" in sig.data
|
|
105
|
+
? sig.data.value
|
|
106
|
+
: sig.data;
|
|
107
|
+
return value === true
|
|
108
|
+
? { ok: true, reason: "human-approved", asked: true }
|
|
109
|
+
: { ok: false, reason: "human-declined", asked: true };
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
reason: `confirm timed out / failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
115
|
+
asked: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Decide whether a generic action may proceed in BYOB mode. Returns ok:true when not
|
|
121
|
+
* in BYOB, or when the hook isn't set. Otherwise blocks on human confirm.
|
|
122
|
+
*
|
|
123
|
+
* Note: this is a *coarse* gate — every action in BYOB hits it. In practice most
|
|
124
|
+
* adopters either set the hook (and confirm once per session) or omit it (and trust
|
|
125
|
+
* the BYOB attach decision they already opted into).
|
|
126
|
+
*/
|
|
127
|
+
export async function confirmByobAction(toolName, ctx) {
|
|
128
|
+
if (!ctx.isByob)
|
|
129
|
+
return { ok: true, reason: "not byob", asked: false };
|
|
130
|
+
if (!ctx.hooks.has("byob_action")) {
|
|
131
|
+
return { ok: true, reason: "byob; no confirm hook", asked: false };
|
|
132
|
+
}
|
|
133
|
+
if (ctx.approvals?.consume("byob_action")) {
|
|
134
|
+
return { ok: true, reason: "pre-approved", asked: false };
|
|
135
|
+
}
|
|
136
|
+
if (!ctx.bridge) {
|
|
137
|
+
return { ok: false, reason: "byob; no helper bridge to confirm; blocked", asked: false };
|
|
138
|
+
}
|
|
139
|
+
log.info(`confirm byob ${toolName} — call __browx.confirm(true) to proceed`);
|
|
140
|
+
try {
|
|
141
|
+
const sig = await ctx.bridge.awaitSignal("respond", 5 * 60_000);
|
|
142
|
+
const value = sig.data && typeof sig.data === "object" && "value" in sig.data
|
|
143
|
+
? sig.data.value
|
|
144
|
+
: sig.data;
|
|
145
|
+
return value === true
|
|
146
|
+
? { ok: true, reason: "human-approved", asked: true }
|
|
147
|
+
: { ok: false, reason: "human-declined", asked: true };
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
return {
|
|
151
|
+
ok: false,
|
|
152
|
+
reason: `confirm timed out / failed: ${e instanceof Error ? e.message : String(e)}`,
|
|
153
|
+
asked: true,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/** Count of requests in an action window whose origin escaped the allowlist. */
|
|
158
|
+
export function countEgressOffAllowlist(requests, policy) {
|
|
159
|
+
if (policy.allowed.length === 0)
|
|
160
|
+
return 0;
|
|
161
|
+
return requests.filter((r) => !isOriginAllowed(r.url, policy)).length;
|
|
162
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface OriginPolicy {
|
|
2
|
+
/** Empty allowlist = no restriction ( default). */
|
|
3
|
+
readonly allowed: ReadonlyArray<OriginPattern>;
|
|
4
|
+
/** Blocked overrides allowed: an origin in `blocked` returns false even if in `allowed`. */
|
|
5
|
+
readonly blocked: ReadonlyArray<OriginPattern>;
|
|
6
|
+
}
|
|
7
|
+
export interface OriginPattern {
|
|
8
|
+
/** The original string, kept for error messages. */
|
|
9
|
+
raw: string;
|
|
10
|
+
/** Pre-compiled matcher: protocol exact, host wildcard-aware. */
|
|
11
|
+
test(originUrl: URL): boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare function resolveOriginPolicy(env?: NodeJS.ProcessEnv): OriginPolicy;
|
|
14
|
+
/** Returns true iff the URL is *allowed* under the policy (and not blocked). */
|
|
15
|
+
export declare function isOriginAllowed(url: string | URL, policy: OriginPolicy): boolean;
|
|
16
|
+
/** Pretty-print for startup log. */
|
|
17
|
+
export declare function describePolicy(policy: OriginPolicy): string;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// Origin allow/blocklist — defense-in-depth gate (NOT a security boundary).
|
|
2
|
+
// See `docs/threat-model.md` for the framing: this is a blast-radius reducer + a hook
|
|
3
|
+
// point for confirmation prompts, *not* a guarantee that off-allowlist requests can't
|
|
4
|
+
// happen (page-initiated redirects, JS-driven nav, BYOB-mode etc. can still escape).
|
|
5
|
+
//
|
|
6
|
+
// Configuring:
|
|
7
|
+
// BROWX_ALLOWED_ORIGINS=https://app.example.com,https://api.example.com,https://*.cdn.example.com
|
|
8
|
+
// BROWX_BLOCKED_ORIGINS=https://*.tracking.example.com,https://ads.example.com
|
|
9
|
+
export function resolveOriginPolicy(env = process.env) {
|
|
10
|
+
const allowed = parseList(env.BROWX_ALLOWED_ORIGINS?.trim() ?? "");
|
|
11
|
+
const blocked = parseList(env.BROWX_BLOCKED_ORIGINS?.trim() ?? "");
|
|
12
|
+
return { allowed, blocked };
|
|
13
|
+
}
|
|
14
|
+
function parseList(raw) {
|
|
15
|
+
if (!raw)
|
|
16
|
+
return [];
|
|
17
|
+
return raw
|
|
18
|
+
.split(",")
|
|
19
|
+
.map((s) => s.trim())
|
|
20
|
+
.filter(Boolean)
|
|
21
|
+
.map(parsePattern);
|
|
22
|
+
}
|
|
23
|
+
function parsePattern(raw) {
|
|
24
|
+
// Accept `https://app.example.com`, `https://*.example.com`, `http://localhost:3000`.
|
|
25
|
+
let url;
|
|
26
|
+
try {
|
|
27
|
+
url = new URL(raw);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
throw new Error(`origin policy: invalid URL "${raw}". Expected e.g. "https://app.example.com".`);
|
|
31
|
+
}
|
|
32
|
+
const protocol = url.protocol;
|
|
33
|
+
const hostPattern = url.hostname;
|
|
34
|
+
const port = url.port; // may be ""
|
|
35
|
+
const isWild = hostPattern.startsWith("*.");
|
|
36
|
+
const wildSuffix = isWild ? hostPattern.slice(1) : ""; // ".example.com" for "*.example.com"
|
|
37
|
+
const test = (candidate) => {
|
|
38
|
+
if (candidate.protocol !== protocol)
|
|
39
|
+
return false;
|
|
40
|
+
if (port && candidate.port && candidate.port !== port)
|
|
41
|
+
return false;
|
|
42
|
+
if (isWild) {
|
|
43
|
+
// Match exact suffix domain or sub-domain (not the bare suffix itself).
|
|
44
|
+
return (candidate.hostname.endsWith(wildSuffix) && candidate.hostname.length > wildSuffix.length);
|
|
45
|
+
}
|
|
46
|
+
return candidate.hostname === hostPattern;
|
|
47
|
+
};
|
|
48
|
+
return { raw, test };
|
|
49
|
+
}
|
|
50
|
+
/** Returns true iff the URL is *allowed* under the policy (and not blocked). */
|
|
51
|
+
export function isOriginAllowed(url, policy) {
|
|
52
|
+
const parsed = typeof url === "string" ? safeUrl(url) : url;
|
|
53
|
+
if (!parsed)
|
|
54
|
+
return false; // unparseable URLs aren't trusted
|
|
55
|
+
if (policy.blocked.some((p) => p.test(parsed)))
|
|
56
|
+
return false;
|
|
57
|
+
if (policy.allowed.length === 0)
|
|
58
|
+
return true; // no allowlist = no restriction
|
|
59
|
+
return policy.allowed.some((p) => p.test(parsed));
|
|
60
|
+
}
|
|
61
|
+
function safeUrl(s) {
|
|
62
|
+
try {
|
|
63
|
+
return new URL(s);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/** Pretty-print for startup log. */
|
|
70
|
+
export function describePolicy(policy) {
|
|
71
|
+
if (policy.allowed.length === 0 && policy.blocked.length === 0)
|
|
72
|
+
return "(none)";
|
|
73
|
+
const bits = [];
|
|
74
|
+
if (policy.allowed.length)
|
|
75
|
+
bits.push(`allowed=[${policy.allowed.map((p) => p.raw).join(", ")}]`);
|
|
76
|
+
if (policy.blocked.length)
|
|
77
|
+
bits.push(`blocked=[${policy.blocked.map((p) => p.raw).join(", ")}]`);
|
|
78
|
+
return bits.join(" ");
|
|
79
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type Capability } from "../util/capabilities.js";
|
|
2
|
+
import type { SdkTransport } from "./transport.js";
|
|
3
|
+
import type { BrowxaiClient } from "./types.js";
|
|
4
|
+
/** Error message tag used by the SDK boundary's runtime gate. Tested by the
|
|
5
|
+
* capability-enforcement spec. Stable string — adopters can match on it. */
|
|
6
|
+
export declare const NOT_EXPOSED_ERROR = "BROWXAI_SDK_NOT_EXPOSED";
|
|
7
|
+
export interface BuildClientOptions {
|
|
8
|
+
readonly transport: SdkTransport;
|
|
9
|
+
readonly capabilities: ReadonlySet<Capability>;
|
|
10
|
+
readonly session?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Build a BrowxaiClient over a ready transport. Method-name → MCP-tool-name
|
|
14
|
+
* is 1:1 (the registry walker emits a wrapper per stable tool); a thin
|
|
15
|
+
* `callTool(name, args)` escape hatch exists for typed-but-unwrapped tools
|
|
16
|
+
* (notably the capability-gated ones).
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildClient(opts: BuildClientOptions): BrowxaiClient;
|
|
19
|
+
/** Default capability set when the caller did not pass one. Mirrors the MCP
|
|
20
|
+
* server defaults (read + navigation + action + human). */
|
|
21
|
+
export declare function defaultSdkCapabilities(): ReadonlySet<Capability>;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
// BrowxaiClient implementation. The exposed-method walker, the capability
|
|
2
|
+
// gate filter at the SDK boundary, and the typed `callTool` escape hatch
|
|
3
|
+
// all live here.
|
|
4
|
+
import { DEFAULT_CAPABILITIES } from "../util/capabilities.js";
|
|
5
|
+
import { ALWAYS_EXPOSED, SDK_TOOLS, capabilityFor } from "./registry.js";
|
|
6
|
+
/** Error message tag used by the SDK boundary's runtime gate. Tested by the
|
|
7
|
+
* capability-enforcement spec. Stable string — adopters can match on it. */
|
|
8
|
+
export const NOT_EXPOSED_ERROR = "BROWXAI_SDK_NOT_EXPOSED";
|
|
9
|
+
/**
|
|
10
|
+
* Build a BrowxaiClient over a ready transport. Method-name → MCP-tool-name
|
|
11
|
+
* is 1:1 (the registry walker emits a wrapper per stable tool); a thin
|
|
12
|
+
* `callTool(name, args)` escape hatch exists for typed-but-unwrapped tools
|
|
13
|
+
* (notably the capability-gated ones).
|
|
14
|
+
*/
|
|
15
|
+
export function buildClient(opts) {
|
|
16
|
+
const { transport, capabilities, session } = opts;
|
|
17
|
+
// The set of tool names this SDK instance will expose. The walker runs
|
|
18
|
+
// ONCE at construction; runtime `callTool` re-checks against the same set
|
|
19
|
+
// so even `(client as any).fooBar` indexing cannot bypass the gate.
|
|
20
|
+
const exposed = new Set();
|
|
21
|
+
for (const name of SDK_TOOLS) {
|
|
22
|
+
if (ALWAYS_EXPOSED.has(name)) {
|
|
23
|
+
exposed.add(name);
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
const cap = capabilityFor(name);
|
|
27
|
+
// `human` capability is implicit — it's always on. Otherwise the cap
|
|
28
|
+
// must be in the SDK's opted-in set for the tool to be exposed.
|
|
29
|
+
if (cap === "human" || capabilities.has(cap)) {
|
|
30
|
+
exposed.add(name);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
let closed = false;
|
|
34
|
+
/** Apply the session default + dispatch. */
|
|
35
|
+
const dispatch = async (toolName, args) => {
|
|
36
|
+
if (closed)
|
|
37
|
+
throw new Error(`browxai-sdk: ${toolName} called on a closed client`);
|
|
38
|
+
const merged = { ...(args ?? {}) };
|
|
39
|
+
if (session !== undefined && merged.session === undefined) {
|
|
40
|
+
merged.session = session;
|
|
41
|
+
}
|
|
42
|
+
return transport.dispatch(toolName, merged);
|
|
43
|
+
};
|
|
44
|
+
/** Runtime gate — the immutable barrier for capability-gated tools. */
|
|
45
|
+
const callTool = async (name, args) => {
|
|
46
|
+
if (!exposed.has(name)) {
|
|
47
|
+
const cap = capabilityFor(name);
|
|
48
|
+
const error = new Error(`${NOT_EXPOSED_ERROR}: tool "${name}" is not exposed on this SDK client. ` +
|
|
49
|
+
`Required capability: "${cap}". Active capabilities: [${[...capabilities].join(", ")}]. ` +
|
|
50
|
+
`Pass it in \`createBrowxai({ capabilities: ["${cap}"] })\` to opt in. ` +
|
|
51
|
+
`Posture-broadening capabilities (eval / network-body / secrets / file-io / extensions / stealth / captcha / credentials / clipboard / byob-attach) are OFF-by-default by design — same posture as the MCP server's capability gates.`);
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
return dispatch(name, args);
|
|
55
|
+
};
|
|
56
|
+
// Per-tool wrappers — typed methods listed in BrowxaiClient. Each forwards
|
|
57
|
+
// through `dispatch` for exposed tools, or refuses early via the same
|
|
58
|
+
// walker check used by `callTool`. We emit ALL the typed methods (every
|
|
59
|
+
// SDK_TOOLS name) regardless of exposure: when a capability is off, the
|
|
60
|
+
// method exists at the type level but throws BROWXAI_SDK_NOT_EXPOSED at
|
|
61
|
+
// call time. This makes `client.eval_js?.(...)` a tractable refactor when
|
|
62
|
+
// the operator later opts the capability in.
|
|
63
|
+
//
|
|
64
|
+
// The runtime wrapper is intentionally `(args?: BrowxaiArgs) => …` — the
|
|
65
|
+
// dispatch path is shape-agnostic. The per-tool TypeScript signatures
|
|
66
|
+
// declared on `BrowxaiClient` specialise this at the type layer only; the
|
|
67
|
+
// cast below assigns one generic factory output to each typed slot without
|
|
68
|
+
// duplicating the wrapper N times.
|
|
69
|
+
// The runtime fn signature is uniform; the per-method TS signatures on
|
|
70
|
+
// `BrowxaiClient` narrow it. `<F>` lets each call site project the wrapper
|
|
71
|
+
// into the exact typed slot without per-method duplication.
|
|
72
|
+
const guarded = (toolName) => (async (args) => callTool(toolName, args));
|
|
73
|
+
// namespaced caller for plugin tools. Every tool the
|
|
74
|
+
// server exposes whose name contains a `.` is a plugin tool; the
|
|
75
|
+
// client surfaces it lazily under `client.plugins[namespace][tool]`
|
|
76
|
+
// so an adopter can write `client.plugins.figma.moveNode({...})`
|
|
77
|
+
// without manually round-tripping through `callTool`.
|
|
78
|
+
//
|
|
79
|
+
// The plugin tools an SDK client sees are sourced from the
|
|
80
|
+
// transport's introspection: at construction time the SDK doesn't
|
|
81
|
+
// know which plugin tools the server has registered (the in-process
|
|
82
|
+
// transport COULD inspect the handler map, but for parity with
|
|
83
|
+
// socket/stdio-child we defer to a lazy first-access pattern —
|
|
84
|
+
// every namespaced access just dispatches via `callTool`, which
|
|
85
|
+
// round-trips to the server and surfaces a clear error if the tool
|
|
86
|
+
// doesn't exist).
|
|
87
|
+
const plugins = new Proxy({}, {
|
|
88
|
+
get(_target, namespace) {
|
|
89
|
+
if (typeof namespace !== "string")
|
|
90
|
+
return undefined;
|
|
91
|
+
return new Proxy({}, {
|
|
92
|
+
get(_t2, toolName) {
|
|
93
|
+
if (typeof toolName !== "string")
|
|
94
|
+
return undefined;
|
|
95
|
+
return (args) =>
|
|
96
|
+
// Mirror tool naming: `namespace.tool`. Convert camelCase
|
|
97
|
+
// tool name back to snake_case? No — the SDK uses the
|
|
98
|
+
// tool name as-is. Plugin authors declare e.g.
|
|
99
|
+
// `figma.move_node` AND `figma.moveNode`'s caller hits
|
|
100
|
+
// `figma.moveNode` — so the JS-style access maps 1:1 to
|
|
101
|
+
// whatever the plugin registered. Plugin authors who
|
|
102
|
+
// want snake_case at the wire and camelCase at the JS
|
|
103
|
+
// level can ship a `.d.ts` wrapper (documented).
|
|
104
|
+
callTool(`${namespace}.${toolName}`, args);
|
|
105
|
+
},
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
const client = {
|
|
110
|
+
// read
|
|
111
|
+
snapshot: guarded("snapshot"),
|
|
112
|
+
find: guarded("find"),
|
|
113
|
+
frames_list: guarded("frames_list"),
|
|
114
|
+
screenshot: guarded("screenshot"),
|
|
115
|
+
console_read: guarded("console_read"),
|
|
116
|
+
network_read: guarded("network_read"),
|
|
117
|
+
ws_read: guarded("ws_read"),
|
|
118
|
+
inspect: guarded("inspect"),
|
|
119
|
+
text_search: guarded("text_search"),
|
|
120
|
+
extract: guarded("extract"),
|
|
121
|
+
verify_visible: guarded("verify_visible"),
|
|
122
|
+
verify_text: guarded("verify_text"),
|
|
123
|
+
verify_value: guarded("verify_value"),
|
|
124
|
+
verify_count: guarded("verify_count"),
|
|
125
|
+
verify_attribute: guarded("verify_attribute"),
|
|
126
|
+
verify_predicate: guarded("verify_predicate"),
|
|
127
|
+
generate_locator: guarded("generate_locator"),
|
|
128
|
+
plan: guarded("plan"),
|
|
129
|
+
// navigation
|
|
130
|
+
navigate: guarded("navigate"),
|
|
131
|
+
go_back: guarded("go_back"),
|
|
132
|
+
go_forward: guarded("go_forward"),
|
|
133
|
+
scroll: guarded("scroll"),
|
|
134
|
+
set_viewport: guarded("set_viewport"),
|
|
135
|
+
// action
|
|
136
|
+
click: guarded("click"),
|
|
137
|
+
fill: guarded("fill"),
|
|
138
|
+
press: guarded("press"),
|
|
139
|
+
shortcut: guarded("shortcut"),
|
|
140
|
+
hover: guarded("hover"),
|
|
141
|
+
select: guarded("select"),
|
|
142
|
+
choose_option: guarded("choose_option"),
|
|
143
|
+
fill_form: guarded("fill_form"),
|
|
144
|
+
wait_for: guarded("wait_for"),
|
|
145
|
+
execute: guarded("execute"),
|
|
146
|
+
// coordination
|
|
147
|
+
await_human: guarded("await_human"),
|
|
148
|
+
name_ref: guarded("name_ref"),
|
|
149
|
+
// session lifecycle
|
|
150
|
+
open_session: guarded("open_session"),
|
|
151
|
+
close_session: guarded("close_session"),
|
|
152
|
+
close_sessions: guarded("close_sessions"),
|
|
153
|
+
list_sessions: guarded("list_sessions"),
|
|
154
|
+
// escape hatch + introspection
|
|
155
|
+
callTool,
|
|
156
|
+
exposedTools: [...exposed].sort(),
|
|
157
|
+
capabilities,
|
|
158
|
+
session,
|
|
159
|
+
// namespaced plugin caller (proxy-based; see comment above).
|
|
160
|
+
plugins,
|
|
161
|
+
close: async () => {
|
|
162
|
+
if (closed)
|
|
163
|
+
return;
|
|
164
|
+
closed = true;
|
|
165
|
+
await transport.close();
|
|
166
|
+
},
|
|
167
|
+
};
|
|
168
|
+
return client;
|
|
169
|
+
}
|
|
170
|
+
/** Default capability set when the caller did not pass one. Mirrors the MCP
|
|
171
|
+
* server defaults (read + navigation + action + human). */
|
|
172
|
+
export function defaultSdkCapabilities() {
|
|
173
|
+
return new Set([...DEFAULT_CAPABILITIES]);
|
|
174
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import "../tools/tool-metadata.js";
|
|
2
|
+
import "./transport-in-process.js";
|
|
3
|
+
import "./transport-socket.js";
|
|
4
|
+
import "./transport-stdio-child.js";
|
|
5
|
+
import type { BrowxaiClient, BrowxaiSdkOptions } from "./types.js";
|
|
6
|
+
export type { BrowxaiArgs, BrowxaiClient, BrowxaiContentItem, BrowxaiResult, BrowxaiSdkOptions, } from "./types.js";
|
|
7
|
+
export type { ActionOpts, ActionResult, ActionResultData, Coords, RefTarget, SessionArg, SnapshotMode, Stability, Target, TimeoutArg, BBox, ChooseOptionArgs, ChooseOptionResult, ConsoleReadArgs, ConsoleReadResult, ConsoleReadResultData, ConsoleRow, ExtractArgs, ExtractEvidence, ExtractFail, ExtractOk, ExtractResult, ExtractResultData, FindArgs, FindCandidate, FindCandidateContext, FindResult, FindResultData, FrameInfo, FramesListArgs, FramesListData, FramesListResult, GenerateLocatorArgs, GenerateLocatorFail, GenerateLocatorOk, GenerateLocatorResult, GenerateLocatorResultData, InspectArgs, InspectResult, InspectResultData, LocatorComponent, NetworkReadArgs, NetworkReadResult, NetworkReadResultData, NetworkRequestRow, ScreenshotArgs, ScreenshotResult, SnapshotArgs, SnapshotResult, TextSearchArgs, TextSearchMatch, TextSearchResult, TextSearchResultData, VerifyAttributeArgs, VerifyCountArgs, VerifyFail, VerifyFailure, VerifyOk, VerifyPredicateArgs, VerifyResult, VerifyResultData, VerifyTextArgs, VerifyValueArgs, VerifyVisibleArgs, WsFrame, WsReadArgs, WsReadResult, WsReadResultData, ActionDescriptor, ExecuteArgs, ExecuteResult, PlanArgs, PlanFail, PlanOk, PlanResult, PlanResultData, PlanVerb, PlanVerbArgs, ClickArgs, ClickResult, FillArgs, FillFormArgs, FillFormFieldArg, FillFormResult, FillFormSubmitArg, FillResult, GoBackArgs, GoBackResult, GoForwardArgs, GoForwardResult, HoverArgs, HoverResult, NavigateArgs, NavigateResult, PressArgs, PressResult, ScrollArgs, ScrollResult, SelectArgs, SelectResult, SetViewportArgs, SetViewportResult, WaitForArgs, WaitForResult, AwaitHumanArgs, AwaitHumanResult, AwaitHumanResultData, CloseSessionArgs, CloseSessionResult, CloseSessionResultData, CloseSessionsArgs, CloseSessionsResult, CloseSessionsResultData, ListSessionsArgs, ListSessionsResult, ListSessionsResultData, ListSessionsRow, NameRefArgs, NameRefResult, NameRefResultData, OpenSessionArgs, OpenSessionResult, OpenSessionResultData, SessionMode, Actionable, EvalJsArgs, EvalJsFail, EvalJsOk, EvalJsResult, EvalJsResultData, NetworkBodyArgs, NetworkBodyResult, NetworkBodyResultData, RegisterSecretArgs, RegisterSecretResult, RegisterSecretResultData, UploadFileArgs, UploadFileResult, UploadFileResultData, } from "./tool-types.js";
|
|
8
|
+
export { NOT_EXPOSED_ERROR } from "./client.js";
|
|
9
|
+
export { resolveEndpointPath } from "./transport-socket.js";
|
|
10
|
+
export type { BrowxaiClientWithPlugins, PluginSchema } from "./plugin-types.js";
|
|
11
|
+
/**
|
|
12
|
+
* Create a typed `BrowxaiClient`. The transport is chosen by these rules:
|
|
13
|
+
*
|
|
14
|
+
* 1. `opts.transport === "socket"` OR `opts.endpoint` set → socket-attach
|
|
15
|
+
* to a running browxai server. Endpoint scheme MUST be `unix://` or
|
|
16
|
+
* `pipe://`; other schemes are rejected. SDK does NOT own the server
|
|
17
|
+
* lifecycle on this path.
|
|
18
|
+
*
|
|
19
|
+
* 2. `opts.transport === "stdio-child"` → spawn `browxai` (or the command
|
|
20
|
+
* given via `opts.command`) as a child process and speak MCP-over-stdio.
|
|
21
|
+
* SDK owns the child lifecycle; `close()` ends it.
|
|
22
|
+
*
|
|
23
|
+
* 3. Otherwise → run the server in-process. SDK owns the lifecycle;
|
|
24
|
+
* `close()` calls `server.shutdown()`.
|
|
25
|
+
*
|
|
26
|
+
* In every mode the capability set passed in `opts.capabilities` is
|
|
27
|
+
* authoritative for which methods are exposed AND callable on the returned
|
|
28
|
+
* client (see `buildClient`). Posture-broadening capabilities (`eval`,
|
|
29
|
+
* `network-body`, `secrets`, `file-io`, `extensions`, `stealth`, `captcha`,
|
|
30
|
+
* `credentials`, `clipboard`, `byob-attach`) remain off-by-default.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createBrowxai(opts?: BrowxaiSdkOptions): Promise<BrowxaiClient>;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// browxai SDK — typed programmatic surface over the same tool registry the
|
|
2
|
+
// MCP path exposes. See docs/sdk.md (or src/sdk/types.ts) for the public
|
|
3
|
+
// types, and `test/sdk/` for executable specs.
|
|
4
|
+
//
|
|
5
|
+
// Mental model: a `BrowxaiClient` is a thin, typed driver over ONE of three
|
|
6
|
+
// transports. Whichever transport the caller picks, every dispatch goes
|
|
7
|
+
// through the same server-side handler registry, so capability gates, the
|
|
8
|
+
// URL sanitiser, the `<SECRET_NAME>` substitution, and per-session isolation
|
|
9
|
+
// are enforced once at the server and trusted by the SDK.
|
|
10
|
+
// RFC 0004 P2 / D1 (SECURITY-CRITICAL): the SDK client's capability gate
|
|
11
|
+
// (`buildClient` → `capabilityFor` → `TOOL_CAPABILITY`) reads the derived map.
|
|
12
|
+
// The SOCKET transport never calls `createServer`, so without this side-effect
|
|
13
|
+
// import the gate would read an empty (fail-open) map. Importing the bootstrap
|
|
14
|
+
// here EAGERLY populates the derived maps for every `createBrowxai` transport —
|
|
15
|
+
// the SDK entry is one of the four real entry points the bootstrap guarantees.
|
|
16
|
+
import "../tools/tool-metadata.js";
|
|
17
|
+
import { buildClient, defaultSdkCapabilities } from "./client.js";
|
|
18
|
+
// Importing the three transport modules runs their side-effect
|
|
19
|
+
// `registerTransport(...)` calls (RFC 0004 P4 / D6), populating the transport
|
|
20
|
+
// registry below. `createBrowxai` then dispatches through `openTransport`
|
|
21
|
+
// rather than a `switch (mode)` — a fourth transport is add-only.
|
|
22
|
+
import "./transport-in-process.js";
|
|
23
|
+
import "./transport-socket.js";
|
|
24
|
+
import "./transport-stdio-child.js";
|
|
25
|
+
import { openTransport } from "./transport-registry.js";
|
|
26
|
+
export { NOT_EXPOSED_ERROR } from "./client.js";
|
|
27
|
+
export { resolveEndpointPath } from "./transport-socket.js";
|
|
28
|
+
/**
|
|
29
|
+
* Create a typed `BrowxaiClient`. The transport is chosen by these rules:
|
|
30
|
+
*
|
|
31
|
+
* 1. `opts.transport === "socket"` OR `opts.endpoint` set → socket-attach
|
|
32
|
+
* to a running browxai server. Endpoint scheme MUST be `unix://` or
|
|
33
|
+
* `pipe://`; other schemes are rejected. SDK does NOT own the server
|
|
34
|
+
* lifecycle on this path.
|
|
35
|
+
*
|
|
36
|
+
* 2. `opts.transport === "stdio-child"` → spawn `browxai` (or the command
|
|
37
|
+
* given via `opts.command`) as a child process and speak MCP-over-stdio.
|
|
38
|
+
* SDK owns the child lifecycle; `close()` ends it.
|
|
39
|
+
*
|
|
40
|
+
* 3. Otherwise → run the server in-process. SDK owns the lifecycle;
|
|
41
|
+
* `close()` calls `server.shutdown()`.
|
|
42
|
+
*
|
|
43
|
+
* In every mode the capability set passed in `opts.capabilities` is
|
|
44
|
+
* authoritative for which methods are exposed AND callable on the returned
|
|
45
|
+
* client (see `buildClient`). Posture-broadening capabilities (`eval`,
|
|
46
|
+
* `network-body`, `secrets`, `file-io`, `extensions`, `stealth`, `captcha`,
|
|
47
|
+
* `credentials`, `clipboard`, `byob-attach`) remain off-by-default.
|
|
48
|
+
*/
|
|
49
|
+
export async function createBrowxai(opts = {}) {
|
|
50
|
+
const capabilities = opts.capabilities && opts.capabilities.length
|
|
51
|
+
? new Set([...opts.capabilities])
|
|
52
|
+
: defaultSdkCapabilities();
|
|
53
|
+
const mode = opts.transport ?? (opts.endpoint ? "socket" : "in-process");
|
|
54
|
+
// Resolve the transport via the add-only registry. `openTransport` returns the
|
|
55
|
+
// SAME transport the old `switch (mode)` constructed for each mode (the per-
|
|
56
|
+
// transport argument mapping + the socket endpoint guard now live in each
|
|
57
|
+
// transport file's `registerTransport(...)`), and throws the same structured
|
|
58
|
+
// error for an unknown mode.
|
|
59
|
+
const transport = await openTransport(mode, opts);
|
|
60
|
+
return buildClient({ transport, capabilities, session: opts.session });
|
|
61
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { BrowxaiArgs, BrowxaiClient, BrowxaiResult } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* The lattice plugin authors implement. Each top-level key is a
|
|
4
|
+
* plugin namespace; each inner key is a tool name; each inner value is
|
|
5
|
+
* a function-returning-promise. Intentionally permissive — concrete
|
|
6
|
+
* plugin schemas are typed precisely while composed types
|
|
7
|
+
* (intersections of multiple plugin schemas) stay assignable.
|
|
8
|
+
*/
|
|
9
|
+
export type PluginSchema = Record<string, Record<string, (...args: never[]) => Promise<BrowxaiResult>>>;
|
|
10
|
+
export type _PluginSchemaArgs = BrowxaiArgs;
|
|
11
|
+
/**
|
|
12
|
+
* A {@link BrowxaiClient} typed against a composition of one or more
|
|
13
|
+
* plugin schemas. Use at the point you `createBrowxai()` — the runtime
|
|
14
|
+
* surface is unchanged; this only widens the `plugins` namespace at
|
|
15
|
+
* the type layer.
|
|
16
|
+
*
|
|
17
|
+
* import type { FigmaPlugin } from "@browxai/plugin-figma";
|
|
18
|
+
* import type { ExamplePlugin } from "@browxai/plugin-example";
|
|
19
|
+
*
|
|
20
|
+
* type Schema = FigmaPlugin & ExamplePlugin;
|
|
21
|
+
*
|
|
22
|
+
* const client = (await createBrowxai({...})) as BrowxaiClientWithPlugins<Schema>;
|
|
23
|
+
* await client.plugins.figma.moveNode({nodeId: "n1", dx: 10, dy: 20});
|
|
24
|
+
* await client.plugins.example.echo({msg: "hi"});
|
|
25
|
+
*
|
|
26
|
+
* The type parameter is intentionally unconstrained — interface
|
|
27
|
+
* schemas (which lack TS's "string index signature") still compose
|
|
28
|
+
* cleanly. The runtime is shape-agnostic; the typing layer just
|
|
29
|
+
* widens the `plugins` namespace.
|
|
30
|
+
*/
|
|
31
|
+
export type BrowxaiClientWithPlugins<P> = Omit<BrowxaiClient, "plugins"> & {
|
|
32
|
+
readonly plugins: P & BrowxaiClient["plugins"];
|
|
33
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// typed SDK seam for plugin tools.
|
|
2
|
+
//
|
|
3
|
+
// Plugin authors ship a TypeScript declaration shaped like:
|
|
4
|
+
//
|
|
5
|
+
// export interface MyPluginSchema {
|
|
6
|
+
// readonly figma: {
|
|
7
|
+
// moveNode(args: { nodeId: string; dx: number; dy: number }): Promise<BrowxaiResult>;
|
|
8
|
+
// resizeNode(args: { nodeId: string; width: number; height: number }): Promise<BrowxaiResult>;
|
|
9
|
+
// };
|
|
10
|
+
// }
|
|
11
|
+
//
|
|
12
|
+
// Consumers compose multiple plugin schemas via the {@link
|
|
13
|
+
// BrowxaiClientWithPlugins} helper and get full autocomplete on every
|
|
14
|
+
// plugin tool — `client.plugins.figma.moveNode({nodeId, dx, dy})` —
|
|
15
|
+
// while the underlying runtime still rides the same `callTool`
|
|
16
|
+
// dispatch path the in-process / socket / stdio-child transports use.
|
|
17
|
+
//
|
|
18
|
+
// The typing surface is purely additive — passing zero schemas leaves
|
|
19
|
+
// the plugin caller as the permissive
|
|
20
|
+
// `Record<string, Record<string, (args?) => Promise<BrowxaiResult>>>`
|
|
21
|
+
// from {@link BrowxaiClient.plugins}.
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type Capability } from "../util/capabilities.js";
|
|
2
|
+
/** Tools the SDK exposes as typed methods on `BrowxaiClient`. */
|
|
3
|
+
export declare const SDK_TOOLS: readonly ["snapshot", "find", "screenshot", "console_read", "network_read", "ws_read", "inspect", "text_search", "extract", "verify_visible", "verify_text", "verify_value", "verify_count", "verify_attribute", "verify_predicate", "generate_locator", "plan", "navigate", "go_back", "go_forward", "scroll", "set_viewport", "click", "fill", "press", "shortcut", "hover", "select", "choose_option", "fill_form", "wait_for", "execute", "await_human", "name_ref", "open_session", "close_session", "close_sessions", "list_sessions", "eval_js", "network_body", "upload_file", "register_secret", "diagnostics_note", "diagnostics_search", "diagnostics_report"];
|
|
4
|
+
export type SdkToolName = (typeof SDK_TOOLS)[number];
|
|
5
|
+
/**
|
|
6
|
+
* Tool → capability lookup the SDK uses to decide which methods to expose.
|
|
7
|
+
* Pulled from the same `TOOL_CAPABILITY` map the MCP server uses so the two
|
|
8
|
+
* paths cannot drift.
|
|
9
|
+
*/
|
|
10
|
+
export declare function capabilityFor(tool: string): Capability | "human";
|
|
11
|
+
/**
|
|
12
|
+
* SDK methods always exposed regardless of capability set — these are the
|
|
13
|
+
* coordination / session-management primitives whose capability is `human`
|
|
14
|
+
* (always-enabled by the server) plus the SDK lifecycle method itself.
|
|
15
|
+
* Used by the registry walker to short-circuit the gate check.
|
|
16
|
+
*/
|
|
17
|
+
export declare const ALWAYS_EXPOSED: ReadonlySet<string>;
|