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,368 @@
|
|
|
1
|
+
import type { Page } from "playwright-core";
|
|
2
|
+
import type { SnapshotSubstrate } from "./snapshot-substrate.js";
|
|
3
|
+
import type { NetworkSubstrate } from "./network-substrate.js";
|
|
4
|
+
import type { RefRegistry } from "./refs.js";
|
|
5
|
+
import type { NetworkEntry, NetworkSummary, MutationEntry, WsFrame } from "./network.js";
|
|
6
|
+
import type { ConsoleBuffer } from "./console.js";
|
|
7
|
+
import type { SnapshotMode } from "./actionresult-shape.js";
|
|
8
|
+
import type { DialogPolicyState, DialogRecord } from "../session/dialog.js";
|
|
9
|
+
import type { PermissionPolicyState, PermissionRecord } from "../session/permission.js";
|
|
10
|
+
import type { NotificationPolicyState, NotificationRecord } from "../session/notification.js";
|
|
11
|
+
import type { FsPickerPolicyState, FsPickerRecord } from "../session/fs-picker.js";
|
|
12
|
+
export interface DispatchedAction {
|
|
13
|
+
type: string;
|
|
14
|
+
ref?: string;
|
|
15
|
+
selector?: string;
|
|
16
|
+
value?: string;
|
|
17
|
+
url?: string;
|
|
18
|
+
}
|
|
19
|
+
export interface ElementProbe {
|
|
20
|
+
ref?: string;
|
|
21
|
+
stillAttached: boolean;
|
|
22
|
+
focused?: boolean;
|
|
23
|
+
checked?: boolean | "mixed";
|
|
24
|
+
/** Mid-action warnings the body wants surfaced on the ActionResult
|
|
25
|
+
* (e.g. click auto-recovery via `force:true`). Merged into the result's
|
|
26
|
+
* `warnings[]` by `runInActionWindow`. */
|
|
27
|
+
warnings?: string[];
|
|
28
|
+
/** Post-action DOM value of the element (input.value / textarea.value /
|
|
29
|
+
* contenteditable text). Null for elements that don't carry a value.
|
|
30
|
+
* Compare against `valueRequested` to confirm a fill landed without an
|
|
31
|
+
* extra screenshot/snapshot round-trip. */
|
|
32
|
+
value?: string | null;
|
|
33
|
+
/** For `fill`, the string the caller asked us to type. `value ===
|
|
34
|
+
* valueRequested` means the write succeeded as-asked; a mismatch means
|
|
35
|
+
* the field rejected or transformed it (masked input, length cap,
|
|
36
|
+
* controlled-component handler, etc.). */
|
|
37
|
+
valueRequested?: string;
|
|
38
|
+
/** Visible text of the closest labelled wrapper (role attr or
|
|
39
|
+
* `data-testid|test|cy|qa`) up to 4 ancestors above the targeted element,
|
|
40
|
+
* trimmed and capped at 200 chars. Surfaces the *displayed* state for
|
|
41
|
+
* controls that render the result outside `input.value` — chip-style
|
|
42
|
+
* selects, combobox displays, badge pickers, custom dropdowns where the
|
|
43
|
+
* underlying input is cleared on commit. Use when `value` is "" / null
|
|
44
|
+
* but the caller needs to confirm the visible state landed. Null when
|
|
45
|
+
* no labelled ancestor was found. Convenience alias for
|
|
46
|
+
* `ownerControl?.displayTextAfter` when an owner was detected. */
|
|
47
|
+
displayText?: string | null;
|
|
48
|
+
/** state of the logical *owning control* (combobox / listbox /
|
|
49
|
+
* radiogroup / labelled field wrapper) the action targeted. The caller
|
|
50
|
+
* often acts on an inner element (an option, a hidden input), but what
|
|
51
|
+
* *changed* is the owner's displayed state. `displayTextBefore` /
|
|
52
|
+
* `displayTextAfter` are the wrapper's `innerText` captured pre- and
|
|
53
|
+
* post-action; `changed: true` when they differ. Absent when no
|
|
54
|
+
* recognised owning control was found above the target. */
|
|
55
|
+
ownerControl?: {
|
|
56
|
+
label?: string;
|
|
57
|
+
displayTextBefore?: string;
|
|
58
|
+
displayTextAfter?: string;
|
|
59
|
+
changed: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** state of the repeated *container* (row / listitem / article /
|
|
62
|
+
* `<tr>` / `<li>`) the target lives inside. `rowText` is the container's
|
|
63
|
+
* visible text post-action; `changed: true` when it differed pre-vs-post.
|
|
64
|
+
* Lets the caller confirm a row-level save changed the row without
|
|
65
|
+
* re-snapshotting the whole table. Absent when the target isn't in a
|
|
66
|
+
* recognised repeated structure. */
|
|
67
|
+
container?: {
|
|
68
|
+
kind: string;
|
|
69
|
+
rowKey?: string;
|
|
70
|
+
rowText?: string;
|
|
71
|
+
changed?: boolean;
|
|
72
|
+
};
|
|
73
|
+
/** coordinate-action evidence. Only populated for `coords` targets.
|
|
74
|
+
* `before` is `document.elementFromPoint(x, y)` immediately before the
|
|
75
|
+
* action; `after` is the same point after settling (the page may have
|
|
76
|
+
* re-rendered or scrolled). `focusChanged` flags whether the active
|
|
77
|
+
* element shifted. The coord-action analogue of `value`/`displayText`. */
|
|
78
|
+
hit?: {
|
|
79
|
+
before?: HitPoint | null;
|
|
80
|
+
after?: HitPoint | null;
|
|
81
|
+
focusChanged?: boolean;
|
|
82
|
+
};
|
|
83
|
+
/** post-scroll geometry of the relevant scroller (the scrolled
|
|
84
|
+
* container for `scroll` container-mode, else the window/document). Lets a
|
|
85
|
+
* caller assert "the older page prepended" (`scrollHeight` grew),
|
|
86
|
+
* "pinned to bottom" (`atBottom`), etc. without `eval_js`. Only populated
|
|
87
|
+
* by the `scroll` / `set_viewport` actions. */
|
|
88
|
+
scroll?: {
|
|
89
|
+
x: number;
|
|
90
|
+
y: number;
|
|
91
|
+
scrollWidth: number;
|
|
92
|
+
scrollHeight: number;
|
|
93
|
+
clientWidth: number;
|
|
94
|
+
clientHeight: number;
|
|
95
|
+
atTop: boolean;
|
|
96
|
+
atBottom: boolean;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export interface HitPoint {
|
|
100
|
+
tag: string;
|
|
101
|
+
role?: string;
|
|
102
|
+
text?: string;
|
|
103
|
+
ancestorText?: string;
|
|
104
|
+
}
|
|
105
|
+
export interface ActionResult {
|
|
106
|
+
ok: boolean;
|
|
107
|
+
action: DispatchedAction;
|
|
108
|
+
navigation: {
|
|
109
|
+
changed: boolean;
|
|
110
|
+
from: string;
|
|
111
|
+
to: string;
|
|
112
|
+
kind: "full_load" | "spa" | "hash" | null;
|
|
113
|
+
};
|
|
114
|
+
structure: {
|
|
115
|
+
appeared: Array<{
|
|
116
|
+
role: string;
|
|
117
|
+
name?: string;
|
|
118
|
+
ref: string;
|
|
119
|
+
}>;
|
|
120
|
+
removed: Array<{
|
|
121
|
+
role: string;
|
|
122
|
+
name?: string;
|
|
123
|
+
ref: string;
|
|
124
|
+
}>;
|
|
125
|
+
newTabs: Array<{
|
|
126
|
+
url: string;
|
|
127
|
+
title: string;
|
|
128
|
+
}>;
|
|
129
|
+
};
|
|
130
|
+
console: {
|
|
131
|
+
errors: string[];
|
|
132
|
+
warnings: number;
|
|
133
|
+
/** number of chars trimmed from the summarised view of `errors`
|
|
134
|
+
* (long React stack-traces etc). The full message is retained via `console_read`. */
|
|
135
|
+
truncated_chars?: number;
|
|
136
|
+
};
|
|
137
|
+
pageErrors: string[];
|
|
138
|
+
element?: ElementProbe;
|
|
139
|
+
/** Multi-element variant of `element`. Populated by composed primitives
|
|
140
|
+
* that act on more than one target inside a single action window (e.g.
|
|
141
|
+
* multi-field fill). Each entry is the per-target probe in the order the
|
|
142
|
+
* primitive dispatched. `element` (singular) when present alongside refers
|
|
143
|
+
* to the *final* / submit target — kept so single-target consumers don't
|
|
144
|
+
* need to feature-detect. Absent for single-target actions. */
|
|
145
|
+
elements?: ElementProbe[];
|
|
146
|
+
snapshotDelta?: {
|
|
147
|
+
mode: SnapshotMode;
|
|
148
|
+
scope: string;
|
|
149
|
+
tree?: string;
|
|
150
|
+
truncated: boolean;
|
|
151
|
+
};
|
|
152
|
+
network: {
|
|
153
|
+
summary: NetworkSummary;
|
|
154
|
+
requests?: NetworkEntry[];
|
|
155
|
+
/** count of requests in this action window that left
|
|
156
|
+
* `BROWX_ALLOWED_ORIGINS` (0 when no allowlist is set). */
|
|
157
|
+
egressOffAllowlist?: number;
|
|
158
|
+
/** bounded summary of write-shaped requests (POST/PUT/PATCH/DELETE,
|
|
159
|
+
* 2xx) whose response body parsed as JSON. `responseShape` carries the
|
|
160
|
+
* *top-level keys only* — no values, no nested keys. Use to confirm a
|
|
161
|
+
* mutation succeeded and what shape it wrote back, without exposing the
|
|
162
|
+
* full response body. Absent when no mutations landed in the window. */
|
|
163
|
+
mutations?: MutationEntry[];
|
|
164
|
+
/** WebSocket/SSE frames that arrived during this action window
|
|
165
|
+
* (payloads truncated). Absent when none. Use to verify realtime
|
|
166
|
+
* correctness — e.g. that a click produced the expected broadcast. */
|
|
167
|
+
wsFrames?: WsFrame[];
|
|
168
|
+
};
|
|
169
|
+
/** `alert` / `confirm` / `prompt` / `beforeunload` dialogs that fired
|
|
170
|
+
* during this action window. Empty/absent when none. Each carries the
|
|
171
|
+
* dialog kind, the page-supplied message + default value, and what the
|
|
172
|
+
* server's per-session `dialogPolicy` did with it (`accepted`, `dismissed`,
|
|
173
|
+
* or `raised` — see `set_dialog_policy`). Independent of `ok`: a policy
|
|
174
|
+
* of `accept`/`dismiss`/`accept-prompt-with:<text>` handles the dialog
|
|
175
|
+
* and the action proceeds; `raise` mode dismisses server-side AND flips
|
|
176
|
+
* `ok` to false with `failure.source:"app"`. */
|
|
177
|
+
dialogs?: Array<{
|
|
178
|
+
kind: DialogRecord["kind"];
|
|
179
|
+
message: string;
|
|
180
|
+
defaultValue?: string;
|
|
181
|
+
handledAs: DialogRecord["handledAs"];
|
|
182
|
+
}>;
|
|
183
|
+
/** Permission requests that the page made during this action window —
|
|
184
|
+
* `getUserMedia`, `getCurrentPosition`/`watchPosition`, `Notification.
|
|
185
|
+
* requestPermission`, `clipboard.read`/`write`, and the long-tail sensor
|
|
186
|
+
* permissions. Each carries the canonical permission name, the page origin
|
|
187
|
+
* at request time, and what the server's per-session `permissionPolicy`
|
|
188
|
+
* did with it (`allowed`, `denied`, `raised`, or `asked-human` — see
|
|
189
|
+
* `set_permission_policy`). Independent of `ok`: a policy of `allow`/
|
|
190
|
+
* `deny`/`ask-human` resolves the request and the action proceeds;
|
|
191
|
+
* `raise` mode rejects page-side AND flips `ok` to false with
|
|
192
|
+
* `failure.source:"app"`. Empty/absent when no requests fired. */
|
|
193
|
+
permissionRequests?: Array<{
|
|
194
|
+
permission: PermissionRecord["permission"];
|
|
195
|
+
origin?: string;
|
|
196
|
+
handledAs: PermissionRecord["handledAs"];
|
|
197
|
+
}>;
|
|
198
|
+
/** `new Notification(title, opts)` constructor calls the page made during
|
|
199
|
+
* this action window. Each entry carries the constructor arguments
|
|
200
|
+
* (title + the documented subset of `NotificationOptions`: body, icon,
|
|
201
|
+
* tag), the page origin at construction time, and what the server's
|
|
202
|
+
* per-session `notificationPolicy` did with it (`allowed`, `denied`,
|
|
203
|
+
* `raised`, or `asked-human` — see `set_notification_policy`).
|
|
204
|
+
* Independent of `ok`: `allow`/`deny`/`ask-human` resolve the call and
|
|
205
|
+
* the action proceeds; `raise` mode rejects page-side AND flips `ok` to
|
|
206
|
+
* false with `failure.source:"app"`. Empty/absent when none.
|
|
207
|
+
*
|
|
208
|
+
* Coordination with `permissionRequests[]`: the two surfaces are
|
|
209
|
+
* disjoint. `permissionRequests[].permission === "notifications"` is the
|
|
210
|
+
* page asking *whether it MAY notify* (`Notification.requestPermission`);
|
|
211
|
+
* `notifications[]` is the page actually *constructing* a notification
|
|
212
|
+
* (`new Notification(...)`). Both can fire in one action — typical apps
|
|
213
|
+
* call requestPermission once at startup, then construct freely. */
|
|
214
|
+
notifications?: Array<{
|
|
215
|
+
title: string;
|
|
216
|
+
body?: string;
|
|
217
|
+
icon?: string;
|
|
218
|
+
tag?: string;
|
|
219
|
+
timestamp: number;
|
|
220
|
+
origin?: string;
|
|
221
|
+
handledAs: NotificationRecord["handledAs"];
|
|
222
|
+
}>;
|
|
223
|
+
/** File System Access picker calls (`showOpenFilePicker` /
|
|
224
|
+
* `showSaveFilePicker` / `showDirectoryPicker`) the page made during
|
|
225
|
+
* this action window. Each carries the API name, the page-supplied
|
|
226
|
+
* `suggestedName` (save-picker only), and what the server's per-session
|
|
227
|
+
* `fsPickerPolicy` did with it (`allowed`, `denied`, `raised`, or
|
|
228
|
+
* `asked-human` — see `set_fs_picker_policy`). Independent of `ok`: a
|
|
229
|
+
* policy of `allow`/`deny`/`ask-human` resolves the picker and the
|
|
230
|
+
* action proceeds; `raise` mode rejects page-side AND flips `ok` to
|
|
231
|
+
* false with `failure.source:"app"`. Empty/absent when no pickers
|
|
232
|
+
* fired. */
|
|
233
|
+
fsPickerRequests?: Array<{
|
|
234
|
+
api: FsPickerRecord["api"];
|
|
235
|
+
suggestedName?: string;
|
|
236
|
+
handledAs: FsPickerRecord["handledAs"];
|
|
237
|
+
}>;
|
|
238
|
+
/** Files the page initiated as downloads during this action window —
|
|
239
|
+
* populated only when per-session capture has been turned on via
|
|
240
|
+
* `downloads_capture({on:true})` (capability `file-io`); absent otherwise.
|
|
241
|
+
* Each entry persists at a workspace-rooted path under
|
|
242
|
+
* `$BROWX_WORKSPACE/.downloads/<sessionId>/` and can be read back as
|
|
243
|
+
* bytes via `download_get({id})`. Multiple captures share the action
|
|
244
|
+
* window — bulk-downloading agents see one entry per file. */
|
|
245
|
+
downloads?: Array<{
|
|
246
|
+
id: string;
|
|
247
|
+
suggestedFilename: string;
|
|
248
|
+
rawSuggestedFilename?: string;
|
|
249
|
+
mimeType?: string;
|
|
250
|
+
sizeBytes: number;
|
|
251
|
+
path: string;
|
|
252
|
+
}>;
|
|
253
|
+
tokensEstimate: number;
|
|
254
|
+
warnings: string[];
|
|
255
|
+
error?: string;
|
|
256
|
+
/** present only when `ok` is false: did the failure originate in the app
|
|
257
|
+
* (navigation/renderer crash — a real defect signal) or in browxai
|
|
258
|
+
* (context torn down / detached / anti-wedge — NOT an app crash)? Stops
|
|
259
|
+
* agents filing false "page crashed" defects for tool teardown. */
|
|
260
|
+
failure?: import("../util/failure.js").FailureClass;
|
|
261
|
+
/** Set by the server when this session has hit the anti-wedge
|
|
262
|
+
* deadline on several consecutive calls — the session is wedged and
|
|
263
|
+
* retrying it (or raising `timeoutMs`) will not recover it. When present,
|
|
264
|
+
* discard the session (`close_session`) and `open_session` a fresh one.
|
|
265
|
+
* Injected onto the result by the server, not produced by the action
|
|
266
|
+
* body; `sessionWedgedHint` carries the agent-facing recovery text. */
|
|
267
|
+
sessionWedged?: boolean;
|
|
268
|
+
sessionWedgedHint?: string;
|
|
269
|
+
}
|
|
270
|
+
export interface ActionContext {
|
|
271
|
+
page: Page;
|
|
272
|
+
/** Engine-agnostic network substrate. The action window mints
|
|
273
|
+
* its per-action tap from here (`openActionTap()`): chromium → the verbatim
|
|
274
|
+
* CDP NetworkTap; firefox/webkit → the Playwright context-event tap. The
|
|
275
|
+
* network slice of the envelope is built off whichever the engine supplied —
|
|
276
|
+
* so navigate/click/fill carry a real network slice on every engine, not just
|
|
277
|
+
* chromium. Optional so a context with no substrate (defensive — never the
|
|
278
|
+
* live path) still builds the rest of the envelope. */
|
|
279
|
+
network?: NetworkSubstrate;
|
|
280
|
+
/** Engine-agnostic snapshot/a11y substrate. The pre/post
|
|
281
|
+
* `snapshotDelta` trees come from here, so the action window builds its
|
|
282
|
+
* structure diff on chromium (CDP a11y) and firefox (the page-side walker)
|
|
283
|
+
* alike. */
|
|
284
|
+
snapshot: SnapshotSubstrate;
|
|
285
|
+
refs: RefRegistry;
|
|
286
|
+
console: ConsoleBuffer;
|
|
287
|
+
pages: () => Page[];
|
|
288
|
+
/** Configured test-attribute list (sourced from BROWX_TEST_ATTRIBUTES). Threaded
|
|
289
|
+
* through so pre/post a11y trees pick up the same testIds the canonical surface uses. */
|
|
290
|
+
testAttributes: string[];
|
|
291
|
+
/** origin allowlist used to populate `ActionResult.network.egressOffAllowlist`.
|
|
292
|
+
* Empty allow-set means "no allowlist" → egress count is always 0. */
|
|
293
|
+
originPolicy?: import("../policy/origin.js").OriginPolicy;
|
|
294
|
+
/** if a recording is active, the recorder is wired in here so
|
|
295
|
+
* successful actions append to the recording. Best-effort: errors during
|
|
296
|
+
* recording never affect the action's outcome. */
|
|
297
|
+
recorder?: import("./recording.js").Recorder;
|
|
298
|
+
/** session WS/SSE frame ring (the engine's `networkSubstrate.ws`). When
|
|
299
|
+
* present, frames that arrived during the action window are sliced into
|
|
300
|
+
* `ActionResult.network.wsFrames` via `since()`. Engine-agnostic
|
|
301
|
+
* (`SessionWsRing`): the CDP `WsBuffer` and the Playwright `PlaywrightWsBuffer`
|
|
302
|
+
* both satisfy it. */
|
|
303
|
+
ws?: import("./network.js").SessionWsRing;
|
|
304
|
+
/** per-session dialog policy state. When present, dialogs that fired
|
|
305
|
+
* during the action window are sliced into `ActionResult.dialogs[]`; if
|
|
306
|
+
* any fired under `raise` mode the action is marked failed with the
|
|
307
|
+
* documented hint. */
|
|
308
|
+
dialog?: DialogPolicyState;
|
|
309
|
+
/** per-session permission policy state. When present, permission requests
|
|
310
|
+
* that fired during the action window are sliced into
|
|
311
|
+
* `ActionResult.permissionRequests[]`; if any fired under `raise` mode the
|
|
312
|
+
* action is marked failed with the documented hint. */
|
|
313
|
+
permission?: PermissionPolicyState;
|
|
314
|
+
/** per-session notification policy state. When present, `new
|
|
315
|
+
* Notification(...)` constructor calls that fired during the action
|
|
316
|
+
* window are sliced into `ActionResult.notifications[]`; if any fired
|
|
317
|
+
* under `raise` mode the action is marked failed with
|
|
318
|
+
* `UNHANDLED_NOTIFICATION_HINT`. */
|
|
319
|
+
notification?: NotificationPolicyState;
|
|
320
|
+
/** per-session File System Access picker policy state. When present,
|
|
321
|
+
* picker calls (`showOpenFilePicker` / `showSaveFilePicker` /
|
|
322
|
+
* `showDirectoryPicker`) that fired during the action window are
|
|
323
|
+
* sliced into `ActionResult.fsPickerRequests[]`; if any fired under
|
|
324
|
+
* `raise` mode the action is marked failed with the documented hint. */
|
|
325
|
+
fsPicker?: FsPickerPolicyState;
|
|
326
|
+
/** per-session secrets registry (capability `secrets`). When non-null,
|
|
327
|
+
* the action-window NetworkTap masks egressing URLs / mutation
|
|
328
|
+
* responseShape keys against any registered real-values. The action's
|
|
329
|
+
* own dispatched-action descriptor is masked by the action handler
|
|
330
|
+
* (so a `fill({value:"<PASSWORD>"})` records `value:"<PASSWORD>"`, not
|
|
331
|
+
* the materialised real password). */
|
|
332
|
+
secrets?: import("../util/secrets.js").SecretRegistry;
|
|
333
|
+
/** per-session downloads registry. When present, any download fired during
|
|
334
|
+
* the action window AND captured (registry was toggled on) is sliced into
|
|
335
|
+
* `ActionResult.downloads[]`. Always-present-but-off-by-default at the
|
|
336
|
+
* registry level; the action-window only emits entries that actually
|
|
337
|
+
* fired during this window, so a session with capture off contributes
|
|
338
|
+
* nothing to the result. */
|
|
339
|
+
downloads?: import("./downloads.js").DownloadsRegistry;
|
|
340
|
+
}
|
|
341
|
+
export interface ActionWindowOptions {
|
|
342
|
+
mode?: SnapshotMode;
|
|
343
|
+
/** Approx output budget for the elastic part of the result (snapshotDelta.tree). */
|
|
344
|
+
maxResultTokens?: number;
|
|
345
|
+
/** Cap on per-request rows in `network.requests`; default 10. */
|
|
346
|
+
networkRequestCap?: number;
|
|
347
|
+
/** Post-dispatch settle delay in ms — let CDP events / framework reconciliations drain. */
|
|
348
|
+
settleMs?: number;
|
|
349
|
+
/** hard anti-wedge deadline (ms) for the action body. Already clamped
|
|
350
|
+
* to [1, 3_600_000] by the caller. The body is raced against this; on
|
|
351
|
+
* expiry the action returns `ok:false` with the timeout error rather than
|
|
352
|
+
* stalling on a wedged page op. */
|
|
353
|
+
deadlineMs?: number;
|
|
354
|
+
/** if the caller requested an over-ceiling (insane) timeout, this
|
|
355
|
+
* carries the "clamped + that's almost always a mistake" warning so it
|
|
356
|
+
* surfaces in the ActionResult, not just server stderr. */
|
|
357
|
+
deadlineWarning?: string;
|
|
358
|
+
/** extra warnings computed before the action window opened (e.g. a ref
|
|
359
|
+
* re-resolution notice) — seeded into the result's `warnings`. */
|
|
360
|
+
extraWarnings?: string[];
|
|
361
|
+
/** caller-supplied selectorHint info for the recorder. Without
|
|
362
|
+
* this the recorded step has the action + url but no locator for the YAML
|
|
363
|
+
* scaffold; callers should populate it whenever they resolved a target. */
|
|
364
|
+
recordingHint?: {
|
|
365
|
+
selectorHint: string;
|
|
366
|
+
stability?: "high" | "medium" | "low";
|
|
367
|
+
};
|
|
368
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export type { SnapshotMode } from "./actionresult-shape.js";
|
|
2
|
+
export type { DispatchedAction, ElementProbe, HitPoint, ActionResult, ActionContext, ActionWindowOptions, } from "./actionresult-types.js";
|
|
3
|
+
import type { ActionContext, ActionResult, ActionWindowOptions, DispatchedAction, ElementProbe } from "./actionresult-types.js";
|
|
4
|
+
export declare function runInActionWindow(ctx: ActionContext, descriptor: DispatchedAction, opts: ActionWindowOptions, body: () => Promise<ElementProbe | void>): Promise<ActionResult>;
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
// ActionResult builder. Wraps a single action with the action-window machinery
|
|
2
|
+
// (network tap, console slice, navigation detection, structure diff, post-snapshot)
|
|
3
|
+
// and emits the structured result.
|
|
4
|
+
//
|
|
5
|
+
// simplification: `snapshotDelta.mode = "scoped_snapshot"` (default) currently
|
|
6
|
+
// returns the *full* a11y tree with a warning noting that scope-down is pending.
|
|
7
|
+
// The always-on cheap signals (navigation / structure / console / pageErrors / element)
|
|
8
|
+
// are real. `tree_diff` is a follow-on.
|
|
9
|
+
import { estimateTokens } from "../util/tokens.js";
|
|
10
|
+
import { withDeadline, DEFAULT_ACTION_TIMEOUT_MS } from "../util/deadline.js";
|
|
11
|
+
import { invariant } from "../util/invariant.js";
|
|
12
|
+
import { classifyFailure } from "../util/failure.js";
|
|
13
|
+
import { UNHANDLED_DIALOG_HINT } from "../session/dialog.js";
|
|
14
|
+
import { UNHANDLED_PERMISSION_HINT } from "../session/permission.js";
|
|
15
|
+
import { UNHANDLED_NOTIFICATION_HINT } from "../session/notification.js";
|
|
16
|
+
import { UNHANDLED_FS_PICKER_HINT } from "../session/fs-picker.js";
|
|
17
|
+
import { applyPolicyRaise, assembleOptionalBlocks, buildDialogsBlock, buildDownloadsBlock, buildFsPickerRequestsBlock, buildNetworkBlock, buildNotificationsBlock, buildPermissionRequestsBlock, maybeRecord, } from "./actionresult-blocks.js";
|
|
18
|
+
import { buildSnapshotDelta, describeNavigation, diffRegions, sleep, summariseConsoleErrors, topLevelRegions, } from "./actionresult-shape.js";
|
|
19
|
+
/** The network slice when there is no CDP tap (off Chromium, where the
|
|
20
|
+
* Playwright-event network tap is used instead). Matches `NetworkTap.close()`'s
|
|
21
|
+
* shape so the envelope builder downstream is engine-blind: zero requests, zero
|
|
22
|
+
* mutations. Frozen so it is never mutated by a downstream consumer. */
|
|
23
|
+
const EMPTY_NETWORK = Object.freeze({
|
|
24
|
+
summary: { total: 0, byType: {}, failed: 0 },
|
|
25
|
+
requests: [],
|
|
26
|
+
mutations: [],
|
|
27
|
+
});
|
|
28
|
+
/**
|
|
29
|
+
* Run an action inside the action-window machinery.
|
|
30
|
+
*
|
|
31
|
+
* await runInActionWindow(ctx, descriptor, opts, async () => locator.click());
|
|
32
|
+
*
|
|
33
|
+
* The caller's body dispatches the action; this function records pre-state,
|
|
34
|
+
* waits for settle, records post-state, and builds the ActionResult.
|
|
35
|
+
*/
|
|
36
|
+
/** The window's seed warnings: the resolved deadline warning plus any caller
|
|
37
|
+
* extras, in order. Returned as a fresh array the dispatch/policy phases append
|
|
38
|
+
* to in place (same mutation flow as before the extraction). */
|
|
39
|
+
function initialWarnings(opts) {
|
|
40
|
+
const warnings = [];
|
|
41
|
+
if (opts.deadlineWarning)
|
|
42
|
+
warnings.push(opts.deadlineWarning);
|
|
43
|
+
if (opts.extraWarnings)
|
|
44
|
+
warnings.push(...opts.extraWarnings);
|
|
45
|
+
return warnings;
|
|
46
|
+
}
|
|
47
|
+
export async function runInActionWindow(ctx, descriptor, opts, body) {
|
|
48
|
+
// mode / maxResultTokens / networkRequestCap defaults are resolved inside
|
|
49
|
+
// shapeActionResult (the only consumer); the orchestrator needs only the
|
|
50
|
+
// dispatch-phase knobs.
|
|
51
|
+
const deadlineMs = opts.deadlineMs ?? DEFAULT_ACTION_TIMEOUT_MS;
|
|
52
|
+
const settleMs = opts.settleMs ?? 400;
|
|
53
|
+
const warnings = initialWarnings(opts);
|
|
54
|
+
// --- pre-state ---
|
|
55
|
+
const pre = await openActionWindow(ctx);
|
|
56
|
+
const { urlBefore, tabsBefore, tBefore, preTree, preRegions } = pre;
|
|
57
|
+
if (pre.net)
|
|
58
|
+
await pre.net.open();
|
|
59
|
+
// --- dispatch ---
|
|
60
|
+
const dispatch = await dispatchActionBody(body, deadlineMs, descriptor.type, warnings);
|
|
61
|
+
let { ok, error, failure } = dispatch;
|
|
62
|
+
const elementProbe = dispatch.elementProbe;
|
|
63
|
+
// --- settle ---
|
|
64
|
+
await sleep(settleMs);
|
|
65
|
+
try {
|
|
66
|
+
await ctx.page.waitForLoadState("networkidle", { timeout: 1500 });
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
/* noisy SPAs never idle */
|
|
70
|
+
}
|
|
71
|
+
// --- post-state ---
|
|
72
|
+
const frameNavigatedMain = pre.detach();
|
|
73
|
+
const urlAfter = ctx.page.url();
|
|
74
|
+
const postTree = await ctx.snapshot.a11yTree(ctx.refs, ctx.testAttributes).catch(() => null);
|
|
75
|
+
const postRegions = postTree ? topLevelRegions(postTree) : new Map();
|
|
76
|
+
const network = pre.net ? await pre.net.close() : EMPTY_NETWORK;
|
|
77
|
+
// policy capture — dialogs / permission requests / notifications / fs-picker
|
|
78
|
+
// calls that fired in the window; a `raise` flips ok→false (see capturePolicy).
|
|
79
|
+
const policy = capturePolicy(ctx, tBefore, { ok, error, failure });
|
|
80
|
+
({ ok, error, failure } = policy.outcome);
|
|
81
|
+
// --- shape ---
|
|
82
|
+
const shaped = await shapeActionResult({
|
|
83
|
+
ctx,
|
|
84
|
+
descriptor,
|
|
85
|
+
opts,
|
|
86
|
+
warnings,
|
|
87
|
+
tBefore,
|
|
88
|
+
urlBefore,
|
|
89
|
+
urlAfter,
|
|
90
|
+
frameNavigatedMain,
|
|
91
|
+
preTree,
|
|
92
|
+
postTree,
|
|
93
|
+
preRegions,
|
|
94
|
+
postRegions,
|
|
95
|
+
tabsBefore,
|
|
96
|
+
network,
|
|
97
|
+
policy,
|
|
98
|
+
});
|
|
99
|
+
const { navigation, structure, consoleSlice, pageErrors, snapshotDelta, networkBlock, blocks } = shaped;
|
|
100
|
+
// append to recording when the action succeeded, recording is active, and the
|
|
101
|
+
// action is replayable as a flow-file step (see maybeRecord for the coord-mode
|
|
102
|
+
// escape-hatch handling).
|
|
103
|
+
maybeRecord(ctx.recorder, ok, { descriptor, urlAfter, recordingHint: opts.recordingHint }, warnings);
|
|
104
|
+
return {
|
|
105
|
+
ok,
|
|
106
|
+
action: descriptor,
|
|
107
|
+
navigation,
|
|
108
|
+
structure,
|
|
109
|
+
console: consoleSlice,
|
|
110
|
+
pageErrors,
|
|
111
|
+
element: elementProbe,
|
|
112
|
+
snapshotDelta,
|
|
113
|
+
network: networkBlock,
|
|
114
|
+
...blocks,
|
|
115
|
+
tokensEstimate: shaped.tokensEstimate,
|
|
116
|
+
warnings,
|
|
117
|
+
error,
|
|
118
|
+
...(failure ? { failure } : {}),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Open the action window: capture pre-state (url / tabs / time / a11y tree +
|
|
122
|
+
* top-level regions), wire the cross-browser `framenavigated` listener, and mint
|
|
123
|
+
* the per-action network tap from the engine's substrate. `detach()` removes the
|
|
124
|
+
* listener and reports whether the main frame fully navigated. The order
|
|
125
|
+
* (pre-tree → listener → tap) is preserved verbatim from the inline version. */
|
|
126
|
+
async function openActionWindow(ctx) {
|
|
127
|
+
const urlBefore = ctx.page.url();
|
|
128
|
+
const tabsBefore = new Set(ctx.pages().map((p) => p.url()));
|
|
129
|
+
const tBefore = Date.now();
|
|
130
|
+
const preTree = await ctx.snapshot.a11yTree(ctx.refs, ctx.testAttributes).catch(() => null);
|
|
131
|
+
const preRegions = preTree ? topLevelRegions(preTree) : new Map();
|
|
132
|
+
// Playwright's `framenavigated` is cross-browser and fires on the same main-frame
|
|
133
|
+
// nav the CDP `Page.frameNavigated` did, so navigation detection works on every
|
|
134
|
+
// engine (the CDP `Page.enable` + raw listener it replaced was Chromium-only).
|
|
135
|
+
let frameNavigatedMain = false;
|
|
136
|
+
const onFrameNav = (frame) => {
|
|
137
|
+
if (frame === ctx.page.mainFrame())
|
|
138
|
+
frameNavigatedMain = true;
|
|
139
|
+
};
|
|
140
|
+
ctx.page.on("framenavigated", onFrameNav);
|
|
141
|
+
// The per-action network tap comes from the engine's substrate: chromium → the
|
|
142
|
+
// CDP NetworkTap; firefox/webkit → the Playwright context-event tap. Both emit
|
|
143
|
+
// the same `{summary, requests, mutations}` close shape, so the envelope builder
|
|
144
|
+
// is engine-blind. (`ctx.secrets` was wired into the substrate at session
|
|
145
|
+
// creation; the tap inherits it.)
|
|
146
|
+
const net = ctx.network ? ctx.network.openActionTap() : null;
|
|
147
|
+
return {
|
|
148
|
+
urlBefore,
|
|
149
|
+
tabsBefore,
|
|
150
|
+
tBefore,
|
|
151
|
+
preTree,
|
|
152
|
+
preRegions,
|
|
153
|
+
net,
|
|
154
|
+
detach: () => {
|
|
155
|
+
ctx.page.off("framenavigated", onFrameNav);
|
|
156
|
+
return frameNavigatedMain;
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/** Assemble the post-state result blocks (navigation, structure, console,
|
|
161
|
+
* snapshotDelta, network, the optional policy/download blocks, token estimate).
|
|
162
|
+
* Pure shaping over already-captured window data — pulled out of
|
|
163
|
+
* `runInActionWindow` to keep the orchestrator under budget. */
|
|
164
|
+
async function shapeActionResult(p) {
|
|
165
|
+
const { ctx, warnings, tBefore } = p;
|
|
166
|
+
const navigation = describeNavigation(p.urlBefore, p.urlAfter, p.frameNavigatedMain);
|
|
167
|
+
const structure = diffRegions(p.preRegions, p.postRegions);
|
|
168
|
+
for (const page of ctx.pages()) {
|
|
169
|
+
if (!p.tabsBefore.has(page.url())) {
|
|
170
|
+
structure.newTabs.push({ url: page.url(), title: await page.title().catch(() => "") });
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const consoleSlice = buildConsoleSlice(ctx, tBefore, warnings);
|
|
174
|
+
const pageErrors = ctx.console.pageErrorsSince(tBefore);
|
|
175
|
+
const snapshotDelta = computeSnapshotDelta({
|
|
176
|
+
mode: p.opts.mode ?? "scoped_snapshot",
|
|
177
|
+
descriptor: p.descriptor,
|
|
178
|
+
structure,
|
|
179
|
+
preTree: p.preTree,
|
|
180
|
+
postTree: p.postTree,
|
|
181
|
+
urlBefore: p.urlBefore,
|
|
182
|
+
urlAfter: p.urlAfter,
|
|
183
|
+
maxTokens: p.opts.maxResultTokens ?? 600,
|
|
184
|
+
warnings,
|
|
185
|
+
});
|
|
186
|
+
const networkBlock = await buildActionNetworkBlock(ctx, p.network, p.opts.networkRequestCap ?? 10, tBefore, warnings);
|
|
187
|
+
const blocks = assembleOptionalBlocks({
|
|
188
|
+
dialogs: buildDialogsBlock(p.policy.dialogSlice),
|
|
189
|
+
permissionRequests: buildPermissionRequestsBlock(p.policy.permissionSlice),
|
|
190
|
+
notifications: buildNotificationsBlock(p.policy.notificationSlice),
|
|
191
|
+
fsPickerRequests: buildFsPickerRequestsBlock(p.policy.fsPickerSlice),
|
|
192
|
+
downloads: buildDownloadsBlock(ctx.downloads ? ctx.downloads.since(tBefore) : []),
|
|
193
|
+
});
|
|
194
|
+
const tokensEstimate = estimateTokens(JSON.stringify({
|
|
195
|
+
navigation,
|
|
196
|
+
structure,
|
|
197
|
+
console: consoleSlice,
|
|
198
|
+
pageErrors,
|
|
199
|
+
snapshotDelta,
|
|
200
|
+
network: networkBlock,
|
|
201
|
+
...blocks,
|
|
202
|
+
}));
|
|
203
|
+
return {
|
|
204
|
+
navigation,
|
|
205
|
+
structure,
|
|
206
|
+
consoleSlice,
|
|
207
|
+
pageErrors,
|
|
208
|
+
snapshotDelta,
|
|
209
|
+
networkBlock,
|
|
210
|
+
blocks,
|
|
211
|
+
tokensEstimate,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
/** Compute the egress-off-allowlist count + WS slice and fold them into the
|
|
215
|
+
* `network` result block. The egress count feeds the security model's
|
|
216
|
+
* network-egress-visibility surface (docs/threat-model.md §"What browxai
|
|
217
|
+
* defends against" #2); it is 0 when no allowlist is configured. */
|
|
218
|
+
async function buildActionNetworkBlock(ctx, network, requestCap, tBefore, warnings) {
|
|
219
|
+
const egressOffAllowlist = ctx.originPolicy && ctx.originPolicy.allowed.length > 0
|
|
220
|
+
? (await import("../policy/confirm.js")).countEgressOffAllowlist(network.requests, ctx.originPolicy)
|
|
221
|
+
: 0;
|
|
222
|
+
const wsSlice = ctx.ws ? ctx.ws.since(tBefore) : [];
|
|
223
|
+
return buildNetworkBlock(network, wsSlice, egressOffAllowlist, requestCap, warnings);
|
|
224
|
+
}
|
|
225
|
+
/** Run the action body, raced against the hard anti-wedge deadline. A wedged
|
|
226
|
+
* page op (evaluate/CDP ignoring timeouts) becomes a clean ok:false within the
|
|
227
|
+
* deadline instead of an infinite stall. Body-side mid-action warnings (e.g.
|
|
228
|
+
* click auto-recovery) are spliced onto the result warnings and removed from
|
|
229
|
+
* the probe so they don't leak into the `element` block. */
|
|
230
|
+
async function dispatchActionBody(body, deadlineMs, descriptorType, warnings) {
|
|
231
|
+
// L7/L8: the action window is bounded — the body is raced against `deadlineMs`
|
|
232
|
+
// (the anti-wedge bound, deadline.ts) so a wedged page op cannot stall forever.
|
|
233
|
+
// The bound is only meaningful if positive: a non-positive deadline would make
|
|
234
|
+
// `withDeadline` fire instantly (or never), defeating the anti-wedge guarantee.
|
|
235
|
+
// Callers resolve `deadlineMs` from the clamped config timeout (>= 1ms) or the
|
|
236
|
+
// 5000ms default, so it is always positive; the invariant pins the anti-wedge
|
|
237
|
+
// bound's positivity as an asserted contract at the point it is consumed.
|
|
238
|
+
invariant(deadlineMs > 0, `action deadline must be positive, got ${deadlineMs}`);
|
|
239
|
+
try {
|
|
240
|
+
const probe = await withDeadline(Promise.resolve().then(body), deadlineMs, descriptorType);
|
|
241
|
+
let elementProbe;
|
|
242
|
+
if (probe) {
|
|
243
|
+
elementProbe = probe;
|
|
244
|
+
if (probe.warnings && probe.warnings.length > 0) {
|
|
245
|
+
warnings.push(...probe.warnings);
|
|
246
|
+
delete probe.warnings;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return { ok: true, error: undefined, failure: undefined, elementProbe };
|
|
250
|
+
}
|
|
251
|
+
catch (e) {
|
|
252
|
+
const error = e instanceof Error ? e.message : String(e);
|
|
253
|
+
return { ok: false, error, failure: classifyFailure(error), elementProbe: undefined };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
/** Slice the four per-session policy buffers since `tBefore` and apply each
|
|
257
|
+
* `raise` to the outcome (first raise wins, in dialog → permission →
|
|
258
|
+
* notification → fs-picker order). Returns the slices for block-building plus
|
|
259
|
+
* the possibly-flipped outcome. */
|
|
260
|
+
function capturePolicy(ctx, tBefore, start) {
|
|
261
|
+
const dialogSlice = ctx.dialog ? ctx.dialog.since(tBefore) : [];
|
|
262
|
+
const permissionSlice = ctx.permission ? ctx.permission.since(tBefore) : [];
|
|
263
|
+
const notificationSlice = ctx.notification ? ctx.notification.since(tBefore) : [];
|
|
264
|
+
const fsPickerSlice = ctx.fsPicker ? ctx.fsPicker.since(tBefore) : [];
|
|
265
|
+
let outcome = applyPolicyRaise(start, ctx.dialog?.raisedSince(tBefore) ?? false, UNHANDLED_DIALOG_HINT);
|
|
266
|
+
outcome = applyPolicyRaise(outcome, ctx.permission?.raisedSince(tBefore) ?? false, UNHANDLED_PERMISSION_HINT);
|
|
267
|
+
outcome = applyPolicyRaise(outcome, ctx.notification?.raisedSince(tBefore) ?? false, UNHANDLED_NOTIFICATION_HINT);
|
|
268
|
+
outcome = applyPolicyRaise(outcome, ctx.fsPicker?.raisedSince(tBefore) ?? false, UNHANDLED_FS_PICKER_HINT);
|
|
269
|
+
return { outcome, dialogSlice, permissionSlice, notificationSlice, fsPickerSlice };
|
|
270
|
+
}
|
|
271
|
+
/** Summarise long console errors inline. A single React stack-trace is routinely
|
|
272
|
+
* ~50 lines / ~1500 tokens; the agent rarely needs the full thing in an
|
|
273
|
+
* ActionResult, so each error is truncated to its first line + a token-budget
|
|
274
|
+
* cap, and a warning points at `console_read` for the full text. */
|
|
275
|
+
function buildConsoleSlice(ctx, tBefore, warnings) {
|
|
276
|
+
const consoleSlice = summariseConsoleErrors(ctx.console.errorsSince(tBefore), warnings);
|
|
277
|
+
consoleSlice.warnings = ctx.console.warningCountSince(tBefore);
|
|
278
|
+
return consoleSlice;
|
|
279
|
+
}
|
|
280
|
+
/** Compute the snapshotDelta: promote `scoped_snapshot` to `none` when the
|
|
281
|
+
* action produced no nav/structure change (the adopter's common case), then
|
|
282
|
+
* serialise just the action's subtree + appeared regions (scope-down). */
|
|
283
|
+
function computeSnapshotDelta(args) {
|
|
284
|
+
const navigationChanged = args.urlBefore !== args.urlAfter;
|
|
285
|
+
const structureChanged = !!args.postTree &&
|
|
286
|
+
!!args.preTree &&
|
|
287
|
+
(args.structure.appeared.length > 0 || args.structure.removed.length > 0);
|
|
288
|
+
let effectiveMode = args.mode;
|
|
289
|
+
if (args.mode === "scoped_snapshot" && !navigationChanged && !structureChanged) {
|
|
290
|
+
effectiveMode = "none";
|
|
291
|
+
args.warnings.push('snapshotDelta auto-omitted (mode: scoped_snapshot) — no nav/structure change; pass mode:"full" if you need the post-action tree anyway');
|
|
292
|
+
}
|
|
293
|
+
const scopeRefs = [];
|
|
294
|
+
if (args.descriptor.ref)
|
|
295
|
+
scopeRefs.push(args.descriptor.ref);
|
|
296
|
+
for (const r of args.structure.appeared)
|
|
297
|
+
scopeRefs.push(r.ref);
|
|
298
|
+
return buildSnapshotDelta(effectiveMode, args.postTree, args.maxTokens, args.warnings, scopeRefs);
|
|
299
|
+
}
|