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,237 @@
|
|
|
1
|
+
// Per-session Chrome extension management (capability `extensions`).
|
|
2
|
+
//
|
|
3
|
+
// Chrome extensions in Playwright/Chromium are a LAUNCH-TIME concern: they
|
|
4
|
+
// only attach to a context that was started with `--load-extension=<paths>`
|
|
5
|
+
// (and `--disable-extensions-except=<paths>` to keep the rest of the user's
|
|
6
|
+
// extensions off in a managed profile). There is no Playwright API to add /
|
|
7
|
+
// remove an extension on a live context.
|
|
8
|
+
//
|
|
9
|
+
// Consequences this module's contract makes load-bearing:
|
|
10
|
+
//
|
|
11
|
+
// 1. Headed-only. Chromium has historically required a head for extensions;
|
|
12
|
+
// `--headless=new` improved coverage but service-worker MV3 backgrounds
|
|
13
|
+
// remain fragile. We refuse install on a session whose context was
|
|
14
|
+
// launched with `headless:true`.
|
|
15
|
+
//
|
|
16
|
+
// 2. Persistent (managed) sessions only. Incognito mode does not load
|
|
17
|
+
// extensions in Chromium (they require an "allowed in incognito"
|
|
18
|
+
// per-extension flag that the Playwright launch API cannot toggle), and
|
|
19
|
+
// attached/BYOB sessions are not-owned (the human's Chrome already has
|
|
20
|
+
// its own extension set; we don't mutate it).
|
|
21
|
+
//
|
|
22
|
+
// 3. install/reload/uninstall mutate the session's extension list and then
|
|
23
|
+
// REBUILD the underlying browser context. This is a destructive
|
|
24
|
+
// operation: the page navigates to about:blank, open refs invalidate,
|
|
25
|
+
// console/network buffers reset. Profile state on disk (cookies,
|
|
26
|
+
// localStorage, IndexedDB) survives — it lives in the profile dir.
|
|
27
|
+
// Callers must treat install/reload/uninstall as "session restart with
|
|
28
|
+
// new extension set", not as Playwright-style hot reload.
|
|
29
|
+
//
|
|
30
|
+
// 4. `trigger` invokes an extension's keyboard command or browser-action
|
|
31
|
+
// popup via the Chrome DevTools Protocol. Best-effort — many extensions
|
|
32
|
+
// lack a browser-action surface, and command bindings are
|
|
33
|
+
// keyboard-shortcut-only on the user's profile.
|
|
34
|
+
//
|
|
35
|
+
// The 5 tool primitives live in src/server.ts; this module supplies the pure
|
|
36
|
+
// helpers (manifest parsing, registry mutation, launch-arg construction) and
|
|
37
|
+
// the rebuild seam.
|
|
38
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
39
|
+
import { isAbsolute, join, resolve, sep } from "node:path";
|
|
40
|
+
export function newExtensionRegistry() {
|
|
41
|
+
return { loaded: [] };
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Resolve a caller-supplied `path` to an absolute workspace-rooted directory
|
|
45
|
+
* containing an MV3 (or MV2) manifest. Rejects:
|
|
46
|
+
* - empty / whitespace
|
|
47
|
+
* - traversal segments (`..`) that escape the workspace
|
|
48
|
+
* - absolute paths pointing outside the workspace
|
|
49
|
+
* - non-existent paths
|
|
50
|
+
* - paths that are files (not a directory)
|
|
51
|
+
* - directories missing `manifest.json`
|
|
52
|
+
*
|
|
53
|
+
* Returns the resolved absolute path. Throws `Error` with a structured message
|
|
54
|
+
* on any rejection — the tool handler converts that to the `ok:false` envelope.
|
|
55
|
+
*/
|
|
56
|
+
export function resolveExtensionPath(workspaceRoot, p, tool) {
|
|
57
|
+
const raw = (p ?? "").trim();
|
|
58
|
+
if (!raw) {
|
|
59
|
+
throw new Error(`${tool}: \`path\` is required (workspace-rooted directory containing manifest.json)`);
|
|
60
|
+
}
|
|
61
|
+
// Resolve under the workspace root. An absolute path outside the workspace
|
|
62
|
+
// is detected by the post-resolve prefix check below — `resolve()` on an
|
|
63
|
+
// absolute path ignores the workspace base, so we don't need a separate
|
|
64
|
+
// branch for it.
|
|
65
|
+
const resolved = isAbsolute(raw) ? resolve(raw) : resolve(workspaceRoot, raw);
|
|
66
|
+
if (resolved !== workspaceRoot && !resolved.startsWith(workspaceRoot + sep)) {
|
|
67
|
+
throw new Error(`${tool}: \`path\` must resolve inside $BROWX_WORKSPACE — got "${p}" (resolved to "${resolved}"). ` +
|
|
68
|
+
`Stage the unpacked extension directory under the workspace.`);
|
|
69
|
+
}
|
|
70
|
+
if (!existsSync(resolved)) {
|
|
71
|
+
throw new Error(`${tool}: extension directory not found at "${resolved}"`);
|
|
72
|
+
}
|
|
73
|
+
let st;
|
|
74
|
+
try {
|
|
75
|
+
st = statSync(resolved);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
throw new Error(`${tool}: cannot stat "${resolved}" (${err instanceof Error ? err.message : String(err)})`);
|
|
79
|
+
}
|
|
80
|
+
if (!st.isDirectory()) {
|
|
81
|
+
throw new Error(`${tool}: "${resolved}" is not a directory. Unpacked extensions are directories containing manifest.json (a .crx file must be unpacked first).`);
|
|
82
|
+
}
|
|
83
|
+
if (!existsSync(join(resolved, "manifest.json"))) {
|
|
84
|
+
throw new Error(`${tool}: no manifest.json found in "${resolved}". Pass the unpacked extension directory, not a parent.`);
|
|
85
|
+
}
|
|
86
|
+
return resolved;
|
|
87
|
+
}
|
|
88
|
+
export function readManifest(extPath, tool) {
|
|
89
|
+
const manifestPath = join(extPath, "manifest.json");
|
|
90
|
+
let raw;
|
|
91
|
+
try {
|
|
92
|
+
raw = readFileSync(manifestPath, "utf8");
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
throw new Error(`${tool}: cannot read manifest.json at "${manifestPath}" (${err instanceof Error ? err.message : String(err)})`);
|
|
96
|
+
}
|
|
97
|
+
let parsed;
|
|
98
|
+
try {
|
|
99
|
+
parsed = JSON.parse(raw);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
throw new Error(`${tool}: manifest.json at "${manifestPath}" is not valid JSON (${err instanceof Error ? err.message : String(err)})`);
|
|
103
|
+
}
|
|
104
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
105
|
+
throw new Error(`${tool}: manifest.json at "${manifestPath}" must be a JSON object`);
|
|
106
|
+
}
|
|
107
|
+
const obj = parsed;
|
|
108
|
+
const name = typeof obj.name === "string" ? obj.name : "(unnamed)";
|
|
109
|
+
const version = typeof obj.version === "string" ? obj.version : "0.0.0";
|
|
110
|
+
const mv = typeof obj.manifest_version === "number" ? obj.manifest_version : 0;
|
|
111
|
+
return { name, version, manifestVersion: mv };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Compute a deterministic, stable id for an unpacked extension keyed off its
|
|
115
|
+
* absolute path. Chrome's real algorithm hashes the path with SHA-256 and
|
|
116
|
+
* maps the first 16 bytes onto the alphabet `a-p` (32 chars). We approximate
|
|
117
|
+
* with a 32-char alpha hash that's deterministic across runs given the same
|
|
118
|
+
* path; the *exact* Chrome id is not required for our use cases (list /
|
|
119
|
+
* reload / uninstall / trigger all key off the path or our own id mapping).
|
|
120
|
+
*
|
|
121
|
+
* The hash uses Node's built-in `node:crypto` — no extra dep.
|
|
122
|
+
*/
|
|
123
|
+
export function extensionIdFromPath(absPath) {
|
|
124
|
+
// Avoid importing crypto at the module top; lazy-require keeps the module
|
|
125
|
+
// tree-shakeable and the helpers cheap to import in tests.
|
|
126
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
127
|
+
const { createHash } = require("node:crypto");
|
|
128
|
+
const digest = createHash("sha256").update(absPath).digest();
|
|
129
|
+
const ALPHABET = "abcdefghijklmnop"; // matches Chrome's encoding alphabet
|
|
130
|
+
let out = "";
|
|
131
|
+
for (let i = 0; i < 16; i++) {
|
|
132
|
+
const byte = digest[i] ?? 0;
|
|
133
|
+
out += ALPHABET[(byte >> 4) & 0x0f];
|
|
134
|
+
out += ALPHABET[byte & 0x0f];
|
|
135
|
+
}
|
|
136
|
+
return out;
|
|
137
|
+
}
|
|
138
|
+
/** Build the Chromium launch arguments for a given set of enabled extensions.
|
|
139
|
+
* Empty list → empty args (no extension flags). Returns a frozen array. */
|
|
140
|
+
export function buildLaunchArgs(loaded) {
|
|
141
|
+
const paths = loaded.filter((e) => e.enabled).map((e) => e.path);
|
|
142
|
+
if (paths.length === 0)
|
|
143
|
+
return [];
|
|
144
|
+
const joined = paths.join(",");
|
|
145
|
+
return [`--disable-extensions-except=${joined}`, `--load-extension=${joined}`];
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Pure refusal predicate — returns null when the session can host extensions,
|
|
149
|
+
* else a structured rejection. Mirrors the gate pattern in server.ts but is
|
|
150
|
+
* pure (testable without launching Chrome).
|
|
151
|
+
*/
|
|
152
|
+
export function refuseIfUnsupported(input) {
|
|
153
|
+
if (input.mode === "attached") {
|
|
154
|
+
return {
|
|
155
|
+
ok: false,
|
|
156
|
+
error: `${input.tool}: extension management is refused on attached/BYOB sessions`,
|
|
157
|
+
hint: "The human's Chrome (attached over CDP) already has its own extension set installed by the human. " +
|
|
158
|
+
"browxai is not-owned on attached sessions — we don't install or uninstall extensions there. " +
|
|
159
|
+
"Use a managed (persistent) session if you need to drive an extension via browxai.",
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
if (input.mode === "incognito") {
|
|
163
|
+
return {
|
|
164
|
+
ok: false,
|
|
165
|
+
error: `${input.tool}: extension management is refused on incognito sessions`,
|
|
166
|
+
hint: "Chromium does not load unpacked extensions in incognito launches (the per-extension 'allowed in incognito' " +
|
|
167
|
+
"flag is not togglable from the Playwright launch API). Open a `persistent` (managed) session and install " +
|
|
168
|
+
"the extension there.",
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
if (input.headless) {
|
|
172
|
+
return {
|
|
173
|
+
ok: false,
|
|
174
|
+
error: `${input.tool}: extension management requires a headed session (headless:false)`,
|
|
175
|
+
hint: "Chromium extension loading via --load-extension is reliable only in headed mode. " +
|
|
176
|
+
"Set `headless:false` via set_config({scope, patch:{headless:false}}) or BROWX_HEADLESS=0, " +
|
|
177
|
+
"then open_session a fresh session. The current session's headless flag is fixed at launch.",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* In-place mutation helper for the install operation. Pure — given the
|
|
184
|
+
* current registry and a resolved + parsed install request, returns the new
|
|
185
|
+
* registry. Throws on duplicate path. The tool layer is responsible for the
|
|
186
|
+
* rebuild step that materialises the change.
|
|
187
|
+
*/
|
|
188
|
+
export function applyInstall(reg, install, tool) {
|
|
189
|
+
if (reg.loaded.some((e) => e.path === install.path)) {
|
|
190
|
+
throw new Error(`${tool}: extension at "${install.path}" is already loaded; call extensions_reload to re-parse its manifest`);
|
|
191
|
+
}
|
|
192
|
+
const id = extensionIdFromPath(install.path);
|
|
193
|
+
if (reg.loaded.some((e) => e.id === id)) {
|
|
194
|
+
throw new Error(`${tool}: extension id collision for "${install.path}" (id "${id}") — this should not happen; report it.`);
|
|
195
|
+
}
|
|
196
|
+
const next = {
|
|
197
|
+
id,
|
|
198
|
+
name: install.name,
|
|
199
|
+
version: install.version,
|
|
200
|
+
path: install.path,
|
|
201
|
+
enabled: true,
|
|
202
|
+
};
|
|
203
|
+
return { id, loaded: [...reg.loaded, next] };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Pure helper for uninstall — returns the next loaded list, throws when the
|
|
207
|
+
* id isn't loaded.
|
|
208
|
+
*/
|
|
209
|
+
export function applyUninstall(reg, id, tool) {
|
|
210
|
+
const idx = reg.loaded.findIndex((e) => e.id === id);
|
|
211
|
+
if (idx < 0) {
|
|
212
|
+
throw new Error(`${tool}: no extension with id "${id}" is loaded in this session (call extensions_list to see ids)`);
|
|
213
|
+
}
|
|
214
|
+
const removed = reg.loaded[idx];
|
|
215
|
+
return { loaded: reg.loaded.filter((_, i) => i !== idx), removed };
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Pure helper for reload — re-parses the manifest at the loaded path and
|
|
219
|
+
* returns the next loaded list with updated name/version. The browser-context
|
|
220
|
+
* rebuild is what actually re-injects content scripts; this helper just keeps
|
|
221
|
+
* the registry consistent.
|
|
222
|
+
*/
|
|
223
|
+
export function applyReload(reg, id, parsed, tool) {
|
|
224
|
+
const idx = reg.loaded.findIndex((e) => e.id === id);
|
|
225
|
+
if (idx < 0) {
|
|
226
|
+
throw new Error(`${tool}: no extension with id "${id}" is loaded in this session`);
|
|
227
|
+
}
|
|
228
|
+
const prev = reg.loaded[idx];
|
|
229
|
+
const next = {
|
|
230
|
+
...prev,
|
|
231
|
+
name: parsed.name,
|
|
232
|
+
version: parsed.version,
|
|
233
|
+
};
|
|
234
|
+
const loaded = reg.loaded.slice();
|
|
235
|
+
loaded[idx] = next;
|
|
236
|
+
return { loaded, entry: next };
|
|
237
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type { BrowserContext } from "playwright-core";
|
|
2
|
+
export type FsPickerMode = "allow" | "deny" | "raise" | "ask-human";
|
|
3
|
+
/** The three File System Access API entry points browxai governs. v1 set.
|
|
4
|
+
* Re-exported in `fs_picker_policy` tool docs + tool-reference.md. */
|
|
5
|
+
export declare const SUPPORTED_FS_PICKER_APIS: readonly ["showOpenFilePicker", "showSaveFilePicker", "showDirectoryPicker"];
|
|
6
|
+
export type FsPickerApi = (typeof SUPPORTED_FS_PICKER_APIS)[number];
|
|
7
|
+
/** Public, runtime-mutable policy shape. Top-level `mode` is the default;
|
|
8
|
+
* the per-API map wins when present. */
|
|
9
|
+
export interface FsPickerPolicy {
|
|
10
|
+
mode: FsPickerMode;
|
|
11
|
+
perAPI?: Partial<Record<FsPickerApi, FsPickerMode>>;
|
|
12
|
+
}
|
|
13
|
+
/** Agent-supplied file payload for `fs_picker_respond`. Either inline
|
|
14
|
+
* `{contents, name}` (base64 bytes the page reads via `getFile()`; for
|
|
15
|
+
* save-pickers the page writes nowhere) or a workspace-rooted `{path}`
|
|
16
|
+
* (for open-pickers: bytes are read once at respond-time; for save-pickers:
|
|
17
|
+
* the destination for `createWritable()`-driven writes; for directory-
|
|
18
|
+
* pickers: the dir name surfaces as `.name` and the rest is a stub). */
|
|
19
|
+
export interface FsPickerFile {
|
|
20
|
+
/** Workspace-rooted file (or dir) path. Mutually exclusive with `contents`. */
|
|
21
|
+
path?: string;
|
|
22
|
+
/** base64 file content. Mutually exclusive with `path`. Pass `name` to set
|
|
23
|
+
* the filename the page sees. Read-only on the page side (the page can
|
|
24
|
+
* call `getFile()` to obtain a `File`; `createWritable()` is a no-op stub). */
|
|
25
|
+
contents?: string;
|
|
26
|
+
/** Filename presented to the page when `contents` is used. Default
|
|
27
|
+
* `"browxai-virtual"`. Ignored when `path` is used (basename of `path`
|
|
28
|
+
* is taken). */
|
|
29
|
+
name?: string;
|
|
30
|
+
/** MIME type for the synthetic `File` exposed to the page. Default
|
|
31
|
+
* `"application/octet-stream"`. */
|
|
32
|
+
mimeType?: string;
|
|
33
|
+
}
|
|
34
|
+
/** One captured picker call, exposed on `ActionResult.fsPickerRequests[]`. */
|
|
35
|
+
export interface FsPickerRecord {
|
|
36
|
+
api: FsPickerApi;
|
|
37
|
+
/** `suggestedName` from `showSaveFilePicker` options (undefined for open /
|
|
38
|
+
* directory). Captured so the agent can see what filename the page
|
|
39
|
+
* proposed. */
|
|
40
|
+
suggestedName?: string;
|
|
41
|
+
/** What the server actually did. `"raised"` means the stub threw AND
|
|
42
|
+
* the policy was `raise`, so the action will be marked failed. */
|
|
43
|
+
handledAs: "allowed" | "denied" | "raised" | "asked-human";
|
|
44
|
+
/** epoch ms — used by the action-window slice. */
|
|
45
|
+
ts: number;
|
|
46
|
+
}
|
|
47
|
+
/** Hint emitted on `ActionResult.failure.hint` when `raise` mode fired.
|
|
48
|
+
* Stable, agent-facing string — referenced in docs/tool-reference.md. */
|
|
49
|
+
export declare const UNHANDLED_FS_PICKER_HINT: string;
|
|
50
|
+
/** Mutable per-session state. The page-side stubs read `current(api)` on
|
|
51
|
+
* every call, so a `set_fs_picker_policy` call takes effect on the very
|
|
52
|
+
* next picker without page reload. */
|
|
53
|
+
export declare class FsPickerPolicyState {
|
|
54
|
+
private policy;
|
|
55
|
+
/** Bounded record ring (shared `PolicyRecordBuffer` — the hard cap so a chatty
|
|
56
|
+
* page can't grow this without bound; the per-action slice is the only
|
|
57
|
+
* consumer, older records are noise). */
|
|
58
|
+
private readonly records;
|
|
59
|
+
/** Per-API response queue. `fs_picker_respond` pushes; the binding
|
|
60
|
+
* dequeues on the next matching picker call. Per-API so a queued
|
|
61
|
+
* open-file response doesn't satisfy a save-file picker (different
|
|
62
|
+
* semantics, different agent intent). */
|
|
63
|
+
private responses;
|
|
64
|
+
/** Contexts we've already installed the init-script + binding on.
|
|
65
|
+
* Idempotent install guard — BYOB reconnect / context rebuild MUST not
|
|
66
|
+
* double-wire. */
|
|
67
|
+
private wired;
|
|
68
|
+
constructor(initial?: FsPickerPolicy, cap?: number);
|
|
69
|
+
/** Resolved policy snapshot. */
|
|
70
|
+
current(): FsPickerPolicy;
|
|
71
|
+
/** Effective mode for one API — per-API map wins, else top-level. */
|
|
72
|
+
modeFor(api: FsPickerApi): FsPickerMode;
|
|
73
|
+
set(next: FsPickerPolicy): FsPickerPolicy;
|
|
74
|
+
/** Append a request record. Caps the buffer at `cap`. */
|
|
75
|
+
record(rec: FsPickerRecord): void;
|
|
76
|
+
/** Slice records with `ts >= since`. Used by the action-window. */
|
|
77
|
+
since(since: number): FsPickerRecord[];
|
|
78
|
+
/** True if any record in `[since, now]` was handled in `raise` mode.
|
|
79
|
+
* When true, the action-window flips the result to `ok:false`. */
|
|
80
|
+
raisedSince(since: number): boolean;
|
|
81
|
+
/** Queue an agent-supplied response for the next picker of `api`.
|
|
82
|
+
* Pushed by `fs_picker_respond`; consumed by the binding on the next
|
|
83
|
+
* matching call. */
|
|
84
|
+
pushResponse(api: FsPickerApi, files: FsPickerFile[]): void;
|
|
85
|
+
/** Dequeue the next agent-supplied response for `api`. Returns
|
|
86
|
+
* `undefined` when the queue is empty (the binding falls back to a
|
|
87
|
+
* best-effort empty file list so the page still gets a usable
|
|
88
|
+
* shape — not deadlocking is the contract). */
|
|
89
|
+
dequeueResponse(api: FsPickerApi): FsPickerFile[] | undefined;
|
|
90
|
+
/** Has this context already been wired? Idempotent install guard. */
|
|
91
|
+
hasContext(c: BrowserContext): boolean;
|
|
92
|
+
/** Mark a context as wired. */
|
|
93
|
+
markContext(c: BrowserContext): void;
|
|
94
|
+
}
|
|
95
|
+
/** Parse the spec's compact string form for the top-level mode, or accept
|
|
96
|
+
* the object form. Idempotent. */
|
|
97
|
+
export declare function parseFsPickerPolicyArg(v: string | FsPickerPolicy | undefined): FsPickerPolicy;
|
|
98
|
+
/** Resolve + validate a workspace-rooted file path. Mirrors the workspace-
|
|
99
|
+
* escape rejection in `src/page/upload.ts`. Exported for tests; used by
|
|
100
|
+
* the binding install + by `fs_picker_respond`. */
|
|
101
|
+
export declare function resolveWorkspaceFsPath(workspaceRoot: string, path: string): string;
|
|
102
|
+
/** Bridge callback type for `ask-human` mode. The server-side binding wires
|
|
103
|
+
* this to await-human; the page-side stub consults it before deciding
|
|
104
|
+
* whether to call through. Returns either the agent-supplied file list (the
|
|
105
|
+
* human approved + the agent staged a response) or `null` (denied). */
|
|
106
|
+
export type FsPickerAskHandler = (api: FsPickerApi, suggestedName: string | undefined) => Promise<FsPickerFile[] | null>;
|
|
107
|
+
/** Init script that replaces the page-side File System Access entry points
|
|
108
|
+
* with stubs that route through the per-session policy. Stringified so it
|
|
109
|
+
* can be passed to `addInitScript` and `page.evaluate`. Keep browser-only
|
|
110
|
+
* JS — no TS-only syntax. Re-injected on `framenavigated` (idempotent:
|
|
111
|
+
* guards on `window.__browx_fs_picker_installed`).
|
|
112
|
+
*
|
|
113
|
+
* The stubs consult `window.__browx_fs_picker_check({api, suggestedName})`
|
|
114
|
+
* (an exposeBinding callable from page context) — it returns one of:
|
|
115
|
+
* - `{decision:"allow", files:[{handleId, name, mimeType, contents?}]}`:
|
|
116
|
+
* the agent staged file(s); the stub builds synthetic
|
|
117
|
+
* `FileSystemFileHandle` / `FileSystemDirectoryHandle` objects whose
|
|
118
|
+
* `getFile()` returns a synthetic `File` and `createWritable()` returns
|
|
119
|
+
* a synthetic writable stream routed through
|
|
120
|
+
* `__browx_fs_picker_write({handleId, op, data?})`.
|
|
121
|
+
* - `{decision:"deny"}`: the stub throws `NotAllowedError`.
|
|
122
|
+
*
|
|
123
|
+
* Stubs are written to be browser-only JS (no TS-only syntax). The
|
|
124
|
+
* install guards on `window.__browx_fs_picker_installed`. */
|
|
125
|
+
export declare const FS_PICKER_PAGE_SCRIPT = "(() => {\n if (window.__browx_fs_picker_installed) return;\n window.__browx_fs_picker_installed = true;\n\n function check(api, suggestedName) {\n try {\n if (typeof window.__browx_fs_picker_check === \"function\") {\n return Promise.resolve(window.__browx_fs_picker_check(JSON.stringify({\n api: api, suggestedName: suggestedName,\n })));\n }\n } catch (_) {}\n // Binding missing \u2014 safe-by-default deny so the page never deadlocks.\n return Promise.resolve(JSON.stringify({ decision: \"deny\" }));\n }\n\n function notAllowed(msg) {\n var e = new Error(msg || \"The user aborted a request.\");\n try { e.name = \"NotAllowedError\"; } catch (_) {}\n return e;\n }\n\n function b64ToBytes(b64) {\n try {\n var binary = atob(b64);\n var len = binary.length;\n var bytes = new Uint8Array(len);\n for (var i = 0; i < len; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n } catch (_) {\n return new Uint8Array(0);\n }\n }\n\n function syntheticFile(spec) {\n var name = spec.name || \"browxai-virtual\";\n var mimeType = spec.mimeType || \"application/octet-stream\";\n var bytes = spec.contents ? b64ToBytes(spec.contents) : new Uint8Array(0);\n try {\n return new File([bytes], name, { type: mimeType });\n } catch (_) {\n // Fallback Blob-shaped object for environments without File (test\n // pages); the constructor is universally available on real browsers.\n var blob = new Blob([bytes], { type: mimeType });\n blob.name = name;\n return blob;\n }\n }\n\n function syntheticWritable(handleId) {\n // Route every operation through the server-side binding. Each call is\n // ack'd by the binding so we surface back-pressure to a determined page\n // (await stream.write(buf) resolves only after the write hit disk).\n function call(op, data) {\n try {\n if (typeof window.__browx_fs_picker_write === \"function\") {\n return Promise.resolve(window.__browx_fs_picker_write(JSON.stringify({\n handleId: handleId, op: op, data: data == null ? null : data,\n })));\n }\n } catch (_) {}\n return Promise.resolve(undefined);\n }\n return {\n write: function (data) {\n // Accept BufferSource | Blob | string | { type:\"write\"|\"seek\"|\"truncate\", \u2026 }\n if (data == null) return Promise.resolve(undefined);\n if (typeof data === \"string\") return call(\"write\", data);\n if (data.type === \"seek\") return call(\"seek\", String(data.position || 0));\n if (data.type === \"truncate\") return call(\"truncate\", String(data.size || 0));\n if (data.type === \"write\" && data.data != null) return call(\"write\", encodeForBinding(data.data));\n return call(\"write\", encodeForBinding(data));\n },\n seek: function (position) { return call(\"seek\", String(position || 0)); },\n truncate: function (size) { return call(\"truncate\", String(size || 0)); },\n close: function () { return call(\"close\"); },\n abort: function () { return call(\"abort\"); },\n };\n }\n\n function encodeForBinding(data) {\n // base64-encode any BufferSource / Blob / string for binding transport.\n // exposeBinding payloads are strings; we wrap as \"b64:<base64>\" so the\n // server side can distinguish from a literal text write.\n function bytesToB64(bytes) {\n var s = \"\";\n for (var i = 0; i < bytes.length; i++) s += String.fromCharCode(bytes[i]);\n try { return \"b64:\" + btoa(s); } catch (_) { return \"b64:\"; }\n }\n if (typeof data === \"string\") return data;\n if (data instanceof ArrayBuffer) return bytesToB64(new Uint8Array(data));\n if (ArrayBuffer.isView && ArrayBuffer.isView(data)) {\n return bytesToB64(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));\n }\n if (data instanceof Blob) {\n // Synchronous-from-page Promise; the binding awaits.\n return data.arrayBuffer().then(function (ab) { return bytesToB64(new Uint8Array(ab)); });\n }\n return String(data);\n }\n\n function syntheticFileHandle(spec) {\n var handleId = spec.handleId;\n var name = spec.name || \"browxai-virtual\";\n return {\n kind: \"file\",\n name: name,\n getFile: function () { return Promise.resolve(syntheticFile(spec)); },\n createWritable: function () { return Promise.resolve(syntheticWritable(handleId)); },\n // Minimal queryPermission / requestPermission \u2014 the page often probes\n // before reading. Always \"granted\" for our virtual handles.\n queryPermission: function () { return Promise.resolve(\"granted\"); },\n requestPermission: function () { return Promise.resolve(\"granted\"); },\n // Comparison helper expected by some libraries.\n isSameEntry: function (other) { return Promise.resolve(other === this); },\n };\n }\n\n function syntheticDirectoryHandle(spec) {\n var name = spec.name || \"browxai-virtual\";\n // MVP scope: empty directory. Most editors will fall back to per-file\n // pickers when iteration yields nothing.\n var empty = {\n next: function () { return Promise.resolve({ value: undefined, done: true }); },\n return: function () { return Promise.resolve({ value: undefined, done: true }); },\n };\n var emptyIter = { __asyncIterator__: true };\n emptyIter[Symbol.asyncIterator] = function () { return empty; };\n return {\n kind: \"directory\",\n name: name,\n entries: function () { return emptyIter; },\n values: function () { return emptyIter; },\n keys: function () { return emptyIter; },\n getFileHandle: function () { return Promise.reject(notAllowed(\"Not found in virtual directory\")); },\n getDirectoryHandle: function () { return Promise.reject(notAllowed(\"Not found in virtual directory\")); },\n removeEntry: function () { return Promise.resolve(undefined); },\n resolve: function () { return Promise.resolve(null); },\n queryPermission: function () { return Promise.resolve(\"granted\"); },\n requestPermission: function () { return Promise.resolve(\"granted\"); },\n isSameEntry: function (other) { return Promise.resolve(other === this); },\n [Symbol.asyncIterator]: function () { return empty; },\n };\n }\n\n function installStub(apiName, isDirectory, isMulti) {\n Object.defineProperty(window, apiName, {\n configurable: true,\n writable: true,\n value: function (options) {\n var suggestedName = options && options.suggestedName ? String(options.suggestedName) : undefined;\n return check(apiName, suggestedName).then(function (raw) {\n var resp;\n try { resp = typeof raw === \"string\" ? JSON.parse(raw) : (raw || {}); } catch (_) { resp = { decision: \"deny\" }; }\n if (resp.decision !== \"allow\") {\n throw notAllowed(\"The user aborted a \" + apiName + \" request.\");\n }\n var files = Array.isArray(resp.files) ? resp.files : [];\n if (isDirectory) {\n var dirSpec = files[0] || { handleId: resp.handleIdFallback || \"dir-0\", name: \"browxai-virtual\" };\n return syntheticDirectoryHandle(dirSpec);\n }\n if (isMulti) {\n return files.map(function (f) { return syntheticFileHandle(f); });\n }\n var spec = files[0] || { handleId: resp.handleIdFallback || \"file-0\", name: \"browxai-virtual\" };\n return syntheticFileHandle(spec);\n });\n },\n });\n }\n\n // showOpenFilePicker: returns Array<FileSystemFileHandle> (multi by default).\n installStub(\"showOpenFilePicker\", false, true);\n // showSaveFilePicker: returns FileSystemFileHandle (single).\n installStub(\"showSaveFilePicker\", false, false);\n // showDirectoryPicker: returns FileSystemDirectoryHandle (single).\n installStub(\"showDirectoryPicker\", true, false);\n})();";
|
|
126
|
+
/** Server-side wire-up. Installs:
|
|
127
|
+
* - `__browx_fs_picker_check` exposeBinding: synchronous-from-page consult
|
|
128
|
+
* that records the request, dequeues an agent-staged response when the
|
|
129
|
+
* policy is `allow` (or routes ask-human via `askHandler`), and returns
|
|
130
|
+
* `{decision, files?}`. Files carry a `handleId` the page-side stub
|
|
131
|
+
* uses to route subsequent `createWritable()` ops back to the right
|
|
132
|
+
* target.
|
|
133
|
+
* - `__browx_fs_picker_write` exposeBinding: target of every
|
|
134
|
+
* `createWritable()`-driven write. Writes append-mode to the
|
|
135
|
+
* workspace-rooted path the agent supplied. `close` / `abort` clean
|
|
136
|
+
* up the per-handle target.
|
|
137
|
+
* - The page-side init script (see above), re-injected by Playwright on
|
|
138
|
+
* every new document.
|
|
139
|
+
*
|
|
140
|
+
* Idempotent on the same context. Errors during install are logged and
|
|
141
|
+
* swallowed — the page-side stub falls back to safe-by-default deny when
|
|
142
|
+
* the binding is missing, so the page still doesn't deadlock.
|
|
143
|
+
*/
|
|
144
|
+
export declare function attachFsPickerPolicy(context: BrowserContext, state: FsPickerPolicyState, workspaceRoot: string, askHandler: FsPickerAskHandler): Promise<void>;
|