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,377 @@
|
|
|
1
|
+
// perf_audit — capability `read`. The headline tool.
|
|
2
|
+
//
|
|
3
|
+
// Promotes browxai's perf surface from *measurement* (`perf_start/stop/insights`)
|
|
4
|
+
// to *actionable* — agents get a structured audit with remediation hints, not
|
|
5
|
+
// a raw 100MB trace blob.
|
|
6
|
+
//
|
|
7
|
+
// Internally pluggable: each category is an `AuditCategoryAnalyser` function
|
|
8
|
+
// in the registry below. Adding a category = adding a registry entry. The
|
|
9
|
+
// public MCP surface is unchanged.
|
|
10
|
+
//
|
|
11
|
+
// Output budget: `format:"summary"` (default) MUST stay under 2000 tokens.
|
|
12
|
+
// `truncateSummaryToBudget` drops the lowest-severity issues + records a
|
|
13
|
+
// warning when the cap binds. `format:"full"` is unbounded — the caller
|
|
14
|
+
// opts in.
|
|
15
|
+
import { estimateTokens } from "../util/tokens.js";
|
|
16
|
+
import { invariant } from "../util/invariant.js";
|
|
17
|
+
import { ANALYSERS, ALL_AUDIT_CATEGORIES } from "./perf-audit-analysers.js";
|
|
18
|
+
export { ANALYSERS, ALL_AUDIT_CATEGORIES, analyseRenderBlocking, analyseUnusedCode, analyseOversizeImages, analyseLayoutThrashing, analyseLongTasks, analyseLeakSuspects, analyseCacheOpportunities, analyseFontLoading, } from "./perf-audit-analysers.js";
|
|
19
|
+
const SEVERITY_WEIGHT = { high: 10, medium: 4, low: 1 };
|
|
20
|
+
export const SUMMARY_TOKEN_BUDGET = 2000;
|
|
21
|
+
const MAX_PER_CATEGORY_SUMMARY = 3;
|
|
22
|
+
// L7 (bounded everything) — the summary-budget trim is bounded on BOTH axes:
|
|
23
|
+
//
|
|
24
|
+
// * Iteration: every trim loop drops at least one entry per iteration (or
|
|
25
|
+
// breaks), so the total iteration count is bounded by the number of
|
|
26
|
+
// droppable entries. `TRIM_ITERATION_CAP` is the explicit hard ceiling — a
|
|
27
|
+
// belt-and-braces bound so a future estimator change can never turn the trim
|
|
28
|
+
// into an unbounded `while`. The audit flagged the old `while (!withinBudget)`
|
|
29
|
+
// as the one loop in the bounded inventory lacking an explicit cap.
|
|
30
|
+
// * Size: even when the report cannot be trimmed under the soft 2000-token
|
|
31
|
+
// budget (a single high-severity issue with a long title — or a ~1MB resource
|
|
32
|
+
// URL stored in `details`/`target` — can exceed it alone), the RETURNED summary
|
|
33
|
+
// never exceeds `SUMMARY_TOKEN_HARD_CEILING` (2.5× the soft budget). The trim
|
|
34
|
+
// drops whole entries until at or under the ceiling, then `enforceHardCeiling`
|
|
35
|
+
// GUARANTEES the ceiling BY CONSTRUCTION: it deep-truncates EVERY string-bearing
|
|
36
|
+
// field (titles, remediation action/target, every string in `details`, warnings
|
|
37
|
+
// — recursively) and, for the structural-floor case, drops content. The ceiling
|
|
38
|
+
// is a guarantee, not a hope — a valid audit never refuses due to size.
|
|
39
|
+
export const SUMMARY_BUDGET_CEILING_FACTOR = 2.5;
|
|
40
|
+
export const SUMMARY_TOKEN_HARD_CEILING = Math.ceil(SUMMARY_TOKEN_BUDGET * SUMMARY_BUDGET_CEILING_FACTOR);
|
|
41
|
+
const TRIM_ITERATION_CAP = 10_000;
|
|
42
|
+
/** Compose an audit report from already-collected context. The category set
|
|
43
|
+
* is the categories the caller asked for (default = all). `format`
|
|
44
|
+
* controls whether each category's `issues`/`remediations` are capped at
|
|
45
|
+
* 3 (summary mode) or unbounded (full mode). The summary itself (the
|
|
46
|
+
* short `summary.topIssues` list + score) always exists; in summary mode
|
|
47
|
+
* the per-category bodies are also capped.
|
|
48
|
+
*
|
|
49
|
+
* Token-budget enforcement: when `format:"summary"`, the function checks
|
|
50
|
+
* estimated token count and drops lowest-severity issues + remediations
|
|
51
|
+
* until under 2000. If even after total trimming the body exceeds the
|
|
52
|
+
* cap, a `warnings[]` entry surfaces it. */
|
|
53
|
+
export function composeReport(ctx, categories, format) {
|
|
54
|
+
const byCategory = {};
|
|
55
|
+
const allIssues = [];
|
|
56
|
+
const warnings = [];
|
|
57
|
+
for (const cat of categories) {
|
|
58
|
+
const analyser = ANALYSERS[cat];
|
|
59
|
+
if (!analyser)
|
|
60
|
+
continue;
|
|
61
|
+
try {
|
|
62
|
+
const result = analyser(ctx);
|
|
63
|
+
byCategory[cat] =
|
|
64
|
+
format === "summary" ? capCategory(result, MAX_PER_CATEGORY_SUMMARY) : result;
|
|
65
|
+
for (const i of result.issues)
|
|
66
|
+
allIssues.push(i);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
warnings.push(`Category ${cat} analyser threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
70
|
+
byCategory[cat] = { issues: [], remediations: [] };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Score: 100 - sum of severity-weighted issue counts, floored at 0.
|
|
74
|
+
const penalty = allIssues.reduce((s, i) => s + SEVERITY_WEIGHT[i.severity], 0);
|
|
75
|
+
const score = Math.max(0, 100 - penalty);
|
|
76
|
+
const topIssues = pickTopIssues(allIssues);
|
|
77
|
+
const report = {
|
|
78
|
+
summary: { score, topIssues },
|
|
79
|
+
byCategory,
|
|
80
|
+
warnings,
|
|
81
|
+
};
|
|
82
|
+
if (format === "summary") {
|
|
83
|
+
return enforceSummaryBudget(report);
|
|
84
|
+
}
|
|
85
|
+
return report;
|
|
86
|
+
}
|
|
87
|
+
function capCategory(r, n) {
|
|
88
|
+
// Cap by severity-weighted ordering — high first, then medium, then low.
|
|
89
|
+
const sortedIssues = [...r.issues].sort((a, b) => SEVERITY_WEIGHT[b.severity] - SEVERITY_WEIGHT[a.severity]);
|
|
90
|
+
const keptIssues = sortedIssues.slice(0, n);
|
|
91
|
+
// Remediations don't have severity directly — keep the first N.
|
|
92
|
+
const keptRems = [];
|
|
93
|
+
for (const rem of r.remediations) {
|
|
94
|
+
if (keptRems.length >= n)
|
|
95
|
+
break;
|
|
96
|
+
keptRems.push(rem);
|
|
97
|
+
}
|
|
98
|
+
return { issues: keptIssues, remediations: keptRems };
|
|
99
|
+
}
|
|
100
|
+
function pickTopIssues(all) {
|
|
101
|
+
const sorted = [...all].sort((a, b) => SEVERITY_WEIGHT[b.severity] - SEVERITY_WEIGHT[a.severity]);
|
|
102
|
+
const top = sorted.slice(0, 10);
|
|
103
|
+
return top.map((i) => ({ category: i.category, severity: i.severity, title: i.title }));
|
|
104
|
+
}
|
|
105
|
+
const SEVERITY_ORDER = ["low", "medium", "high"];
|
|
106
|
+
/** Returns true once the report is within budget. */
|
|
107
|
+
function withinBudget(report) {
|
|
108
|
+
return estimateTokens(JSON.stringify(report)) <= SUMMARY_TOKEN_BUDGET;
|
|
109
|
+
}
|
|
110
|
+
/** One severity pass — drop `sev` issues across categories + paired remediations
|
|
111
|
+
* + matching topIssues until within budget. Returns the count dropped. */
|
|
112
|
+
function dropSeverityPass(report, sev) {
|
|
113
|
+
let dropped = 0;
|
|
114
|
+
for (const cat of Object.keys(report.byCategory)) {
|
|
115
|
+
const r = report.byCategory[cat];
|
|
116
|
+
const newIssues = [];
|
|
117
|
+
for (const i of r.issues) {
|
|
118
|
+
if (i.severity === sev && !withinBudget(report)) {
|
|
119
|
+
dropped++;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
newIssues.push(i);
|
|
123
|
+
}
|
|
124
|
+
r.issues = newIssues;
|
|
125
|
+
if (r.remediations.length > r.issues.length) {
|
|
126
|
+
r.remediations = r.remediations.slice(0, Math.max(1, r.issues.length));
|
|
127
|
+
}
|
|
128
|
+
if (withinBudget(report))
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
// The summary's cross-category topIssues list can dominate the budget alone.
|
|
132
|
+
if (!withinBudget(report)) {
|
|
133
|
+
const before = report.summary.topIssues.length;
|
|
134
|
+
report.summary.topIssues = report.summary.topIssues.filter((t) => t.severity !== sev);
|
|
135
|
+
dropped += before - report.summary.topIssues.length;
|
|
136
|
+
}
|
|
137
|
+
return dropped;
|
|
138
|
+
}
|
|
139
|
+
/** Final aggressive trim — pop topIssues then per-category issues until within
|
|
140
|
+
* budget or nothing left to drop. Returns the count dropped.
|
|
141
|
+
*
|
|
142
|
+
* L7: bounded by `TRIM_ITERATION_CAP`. Every iteration of the second loop drops
|
|
143
|
+
* at least one entry (or sets `trimmed = false` and breaks), so it terminates in
|
|
144
|
+
* at most (total issues across categories) iterations — the explicit cap is the
|
|
145
|
+
* hard ceiling that makes termination a property the code GUARANTEES rather than
|
|
146
|
+
* relies on the `trimmed` flag for. A `termination` invariant fires if the cap is
|
|
147
|
+
* ever hit (it cannot be on any real report; the bounded-resource property test
|
|
148
|
+
* exercises an adversarial report to prove it). */
|
|
149
|
+
function trimAggressively(report) {
|
|
150
|
+
let dropped = 0;
|
|
151
|
+
// cap: at most `TRIM_ITERATION_CAP` pops — each removes one topIssue.
|
|
152
|
+
let iterations = 0;
|
|
153
|
+
while (report.summary.topIssues.length > 1 && !withinBudget(report)) {
|
|
154
|
+
invariant(iterations++ < TRIM_ITERATION_CAP, "perf-audit topIssues trim exceeded iteration cap");
|
|
155
|
+
report.summary.topIssues.pop();
|
|
156
|
+
dropped++;
|
|
157
|
+
}
|
|
158
|
+
// cap: at most `TRIM_ITERATION_CAP` passes — each pass that does not break drops
|
|
159
|
+
// at least one per-category issue, so the loop is bounded by the entry count.
|
|
160
|
+
iterations = 0;
|
|
161
|
+
while (!withinBudget(report)) {
|
|
162
|
+
invariant(iterations++ < TRIM_ITERATION_CAP, "perf-audit per-category trim exceeded iteration cap");
|
|
163
|
+
let trimmed = false;
|
|
164
|
+
for (const cat of Object.keys(report.byCategory)) {
|
|
165
|
+
const r = report.byCategory[cat];
|
|
166
|
+
if (r.issues.length > 0) {
|
|
167
|
+
r.issues.pop();
|
|
168
|
+
if (r.remediations.length > r.issues.length)
|
|
169
|
+
r.remediations.pop();
|
|
170
|
+
dropped++;
|
|
171
|
+
trimmed = true;
|
|
172
|
+
if (withinBudget(report))
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
if (!trimmed)
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
return dropped;
|
|
180
|
+
}
|
|
181
|
+
const TRUNCATION_NOTE = "summary truncated to honour the hard token ceiling.";
|
|
182
|
+
/** Collect a mutable handle on EVERY human-readable / data string in the report —
|
|
183
|
+
* topIssue titles; per-category issue titles + every string value in their
|
|
184
|
+
* `details` (recursively, where a ~1MB resource URL can hide); remediation
|
|
185
|
+
* `action` + `target`; and the warnings. This is the exhaustive set the hard
|
|
186
|
+
* ceiling truncates, so no string-bearing field can keep the report over the
|
|
187
|
+
* ceiling. */
|
|
188
|
+
function collectStringRefs(report) {
|
|
189
|
+
const refs = [];
|
|
190
|
+
for (let i = 0; i < report.summary.topIssues.length; i++) {
|
|
191
|
+
refs.push({
|
|
192
|
+
get: () => report.summary.topIssues[i].title,
|
|
193
|
+
set: (s) => (report.summary.topIssues[i].title = s),
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
for (const cat of Object.keys(report.byCategory)) {
|
|
197
|
+
const r = report.byCategory[cat];
|
|
198
|
+
for (let i = 0; i < r.issues.length; i++) {
|
|
199
|
+
refs.push({
|
|
200
|
+
get: () => r.issues[i].title,
|
|
201
|
+
set: (s) => (r.issues[i].title = s),
|
|
202
|
+
});
|
|
203
|
+
collectRecordStringRefs(r.issues[i].details, refs);
|
|
204
|
+
}
|
|
205
|
+
for (let i = 0; i < r.remediations.length; i++) {
|
|
206
|
+
const rem = r.remediations[i];
|
|
207
|
+
refs.push({ get: () => rem.action, set: (s) => (rem.action = s) });
|
|
208
|
+
if (typeof rem.target === "string") {
|
|
209
|
+
refs.push({ get: () => rem.target, set: (s) => (rem.target = s) });
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
for (let i = 0; i < report.warnings.length; i++) {
|
|
214
|
+
refs.push({
|
|
215
|
+
get: () => report.warnings[i],
|
|
216
|
+
set: (s) => (report.warnings[i] = s),
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
return refs;
|
|
220
|
+
}
|
|
221
|
+
/** Recursively gather string-valued fields in a free-form `details` record (and
|
|
222
|
+
* nested records/arrays) so a long URL or message inside `details` is reachable
|
|
223
|
+
* by the truncator — `details` is `Record<string, unknown>`, so a string field
|
|
224
|
+
* can hide at any depth. Bounded by the (finite) structure of the value. */
|
|
225
|
+
function collectRecordStringRefs(value, refs) {
|
|
226
|
+
if (Array.isArray(value)) {
|
|
227
|
+
for (let i = 0; i < value.length; i++) {
|
|
228
|
+
const arr = value;
|
|
229
|
+
if (typeof arr[i] === "string") {
|
|
230
|
+
refs.push({ get: () => arr[i], set: (s) => (arr[i] = s) });
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
collectRecordStringRefs(arr[i], refs);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (value && typeof value === "object") {
|
|
239
|
+
const rec = value;
|
|
240
|
+
for (const key of Object.keys(rec)) {
|
|
241
|
+
if (typeof rec[key] === "string") {
|
|
242
|
+
refs.push({ get: () => rec[key], set: (s) => (rec[key] = s) });
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
collectRecordStringRefs(rec[key], refs);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
/** L7 hard-ceiling enforcement — the last line of defence, GUARANTEED BY
|
|
251
|
+
* CONSTRUCTION. The returned report is ALWAYS ≤ `SUMMARY_TOKEN_HARD_CEILING`:
|
|
252
|
+
*
|
|
253
|
+
* 1. Deep-truncate every string-bearing field (titles, remediation
|
|
254
|
+
* action/target, every string in `details`, warnings — recursively), halving
|
|
255
|
+
* the longest each pass until the estimate is within the ceiling. A single
|
|
256
|
+
* irreducible long entry (e.g. a ~1MB resource URL stored in `details`/`target`)
|
|
257
|
+
* is shrunk here, not refused.
|
|
258
|
+
* 2. If after every string is driven to its 1-char floor the report is STILL
|
|
259
|
+
* over (the structural-floor case — thousands of warnings / issues whose KEYS
|
|
260
|
+
* and numbers alone exceed the ceiling), drop structural content (warnings,
|
|
261
|
+
* then per-category issues + remediations, then topIssues) until within the
|
|
262
|
+
* ceiling, appending one short truncation note.
|
|
263
|
+
*
|
|
264
|
+
* The ceiling is therefore a post-condition established by construction — a valid
|
|
265
|
+
* audit NEVER refuses due to size. The TERMINATION cap below is the real L7
|
|
266
|
+
* protection (it asserts the bounded loop terminates); the ceiling post-condition
|
|
267
|
+
* is kept as a defensive sanity but is unreachable. */
|
|
268
|
+
function enforceHardCeiling(report) {
|
|
269
|
+
// Phase 1 — halve the longest string until within the ceiling or nothing left
|
|
270
|
+
// to shorten. cap: each pass at least halves the single longest string, so the
|
|
271
|
+
// string mass shrinks geometrically; bounded by `TRIM_ITERATION_CAP`.
|
|
272
|
+
let iterations = 0;
|
|
273
|
+
while (estimateTokens(JSON.stringify(report)) > SUMMARY_TOKEN_HARD_CEILING) {
|
|
274
|
+
invariant(iterations++ < TRIM_ITERATION_CAP, "perf-audit hard-ceiling string-truncation exceeded iteration cap");
|
|
275
|
+
if (!shortenLongestString(report))
|
|
276
|
+
break; // every string at its 1-char floor
|
|
277
|
+
}
|
|
278
|
+
// Phase 2 — structural floor: strings are minimized but the skeleton (keys +
|
|
279
|
+
// numbers across thousands of entries) still exceeds the ceiling. Drop content
|
|
280
|
+
// until within it, then note the truncation once. cap: each pass drops at least
|
|
281
|
+
// one structural element (or breaks), so it is bounded by the entry count.
|
|
282
|
+
iterations = 0;
|
|
283
|
+
let noted = false;
|
|
284
|
+
while (estimateTokens(JSON.stringify(report)) > SUMMARY_TOKEN_HARD_CEILING) {
|
|
285
|
+
invariant(iterations++ < TRIM_ITERATION_CAP, "perf-audit hard-ceiling structural-drop exceeded iteration cap");
|
|
286
|
+
if (!noted) {
|
|
287
|
+
report.warnings = [TRUNCATION_NOTE];
|
|
288
|
+
noted = true;
|
|
289
|
+
}
|
|
290
|
+
if (!dropStructuralContent(report))
|
|
291
|
+
break; // nothing structural left to drop
|
|
292
|
+
}
|
|
293
|
+
// Defensive post-condition — unreachable: phase 2 drives the report to an empty
|
|
294
|
+
// skeleton (far under the ceiling) if phase 1 could not. Kept as a sanity guard.
|
|
295
|
+
invariant(estimateTokens(JSON.stringify(report)) <= SUMMARY_TOKEN_HARD_CEILING, `perf-audit summary exceeded hard ceiling (${SUMMARY_TOKEN_HARD_CEILING} tokens)`);
|
|
296
|
+
}
|
|
297
|
+
/** Halve the single longest string anywhere in the report. Returns false when no
|
|
298
|
+
* string is longer than its 1-char floor — i.e. nothing left to shorten. */
|
|
299
|
+
function shortenLongestString(report) {
|
|
300
|
+
let longest = null;
|
|
301
|
+
for (const ref of collectStringRefs(report)) {
|
|
302
|
+
const len = ref.get().length;
|
|
303
|
+
if (len > 1 && (!longest || len > longest.len))
|
|
304
|
+
longest = { ref, len };
|
|
305
|
+
}
|
|
306
|
+
if (!longest)
|
|
307
|
+
return false;
|
|
308
|
+
const cur = longest.ref.get();
|
|
309
|
+
longest.ref.set(cur.slice(0, Math.max(1, Math.floor(cur.length / 2))) + "…");
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
/** Drop one unit of structural content for the structural-floor case — warnings
|
|
313
|
+
* beyond the note first, then per-category issues + their paired remediations,
|
|
314
|
+
* then topIssues. Returns false when only the empty skeleton remains. */
|
|
315
|
+
function dropStructuralContent(report) {
|
|
316
|
+
if (report.warnings.length > 1) {
|
|
317
|
+
report.warnings = report.warnings.slice(0, 1);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
for (const cat of Object.keys(report.byCategory)) {
|
|
321
|
+
const r = report.byCategory[cat];
|
|
322
|
+
if (r.issues.length > 0) {
|
|
323
|
+
r.issues.pop();
|
|
324
|
+
if (r.remediations.length > 0)
|
|
325
|
+
r.remediations.pop();
|
|
326
|
+
return true;
|
|
327
|
+
}
|
|
328
|
+
if (r.remediations.length > 0) {
|
|
329
|
+
r.remediations.pop();
|
|
330
|
+
return true;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (report.summary.topIssues.length > 0) {
|
|
334
|
+
report.summary.topIssues.pop();
|
|
335
|
+
return true;
|
|
336
|
+
}
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
/** Drop lowest-severity issues across all categories until estimated tokens
|
|
340
|
+
* are within the summary budget. Adds a warnings[] entry if the cap binds. */
|
|
341
|
+
export function enforceSummaryBudget(report) {
|
|
342
|
+
if (withinBudget(report))
|
|
343
|
+
return report;
|
|
344
|
+
let dropped = 0;
|
|
345
|
+
for (const sev of SEVERITY_ORDER) {
|
|
346
|
+
if (withinBudget(report))
|
|
347
|
+
break;
|
|
348
|
+
dropped += dropSeverityPass(report, sev);
|
|
349
|
+
}
|
|
350
|
+
dropped += trimAggressively(report);
|
|
351
|
+
if (dropped > 0) {
|
|
352
|
+
report.warnings.push(`summary token budget enforced (${SUMMARY_TOKEN_BUDGET}): dropped ${dropped} low/medium severity entries. Re-run with format:"full" for the full report.`);
|
|
353
|
+
}
|
|
354
|
+
// L7: the soft trim above drops WHOLE entries; a single irreducible large entry
|
|
355
|
+
// (e.g. a ~1MB resource URL in `details`/`target`) can still exceed the budget.
|
|
356
|
+
// `enforceHardCeiling` GUARANTEES BY CONSTRUCTION that the RETURNED report is
|
|
357
|
+
// within the hard ceiling — it deep-truncates every string-bearing field and,
|
|
358
|
+
// for the structural-floor case, drops content — so a valid audit NEVER refuses
|
|
359
|
+
// due to size. Always run it last, even when the soft trim already fit, so the
|
|
360
|
+
// hard ceiling is an unconditional postcondition.
|
|
361
|
+
enforceHardCeiling(report);
|
|
362
|
+
return report;
|
|
363
|
+
}
|
|
364
|
+
/** Resolve the requested category set — empty/undefined → all. Unknown
|
|
365
|
+
* category names are dropped silently. */
|
|
366
|
+
export function resolveCategories(requested) {
|
|
367
|
+
if (!requested || requested.length === 0)
|
|
368
|
+
return [...ALL_AUDIT_CATEGORIES];
|
|
369
|
+
const out = [];
|
|
370
|
+
for (const c of requested) {
|
|
371
|
+
if (ALL_AUDIT_CATEGORIES.includes(c))
|
|
372
|
+
out.push(c);
|
|
373
|
+
}
|
|
374
|
+
if (out.length === 0)
|
|
375
|
+
return [...ALL_AUDIT_CATEGORIES];
|
|
376
|
+
return out;
|
|
377
|
+
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import type { CDPSession } from "playwright-core";
|
|
2
|
+
/** Default trace categories — covers the cases DevTools' Performance panel
|
|
3
|
+
* uses for its core insights (frames, paint, layout, long tasks, user
|
|
4
|
+
* timing, loading). Smaller than the everything-on default to keep traces
|
|
5
|
+
* manageable. */
|
|
6
|
+
export declare const DEFAULT_TRACE_CATEGORIES: string[];
|
|
7
|
+
/** Trace event row, as emitted by chromium tracing. We only care about a few
|
|
8
|
+
* fields; everything else passes through. */
|
|
9
|
+
export interface TraceEvent {
|
|
10
|
+
name?: string;
|
|
11
|
+
cat?: string;
|
|
12
|
+
ph?: string;
|
|
13
|
+
ts?: number;
|
|
14
|
+
dur?: number;
|
|
15
|
+
pid?: number;
|
|
16
|
+
tid?: number;
|
|
17
|
+
args?: Record<string, unknown>;
|
|
18
|
+
[k: string]: unknown;
|
|
19
|
+
}
|
|
20
|
+
/** Insights summary — small, structured, agent-friendly. */
|
|
21
|
+
export interface PerfInsights {
|
|
22
|
+
/** Long tasks (≥50 ms blocking the main thread). DevTools' surface metric
|
|
23
|
+
* for "main thread was busy here". Sorted longest-first. */
|
|
24
|
+
longTasks: Array<{
|
|
25
|
+
startMs: number;
|
|
26
|
+
durationMs: number;
|
|
27
|
+
}>;
|
|
28
|
+
/** Cumulative + per-shift LayoutShift entries. CLS-relevant. */
|
|
29
|
+
layoutShifts: Array<{
|
|
30
|
+
startMs: number;
|
|
31
|
+
score: number;
|
|
32
|
+
hadRecentInput?: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
/** Resources that blocked the renderer (CSS / sync JS in the critical
|
|
35
|
+
* rendering path). Sorted by duration descending. */
|
|
36
|
+
renderBlocking: Array<{
|
|
37
|
+
url: string;
|
|
38
|
+
durationMs: number;
|
|
39
|
+
type?: string;
|
|
40
|
+
}>;
|
|
41
|
+
/** Largest-Contentful-Paint candidates — every `largestContentfulPaint::Candidate`
|
|
42
|
+
* event the trace recorded. The final candidate (latest `startMs`) is the
|
|
43
|
+
* effective LCP. */
|
|
44
|
+
lcpCandidates: Array<{
|
|
45
|
+
startMs: number;
|
|
46
|
+
size?: number;
|
|
47
|
+
url?: string;
|
|
48
|
+
nodeName?: string;
|
|
49
|
+
}>;
|
|
50
|
+
/** Navigation timing milestones, if a navigationStart is present. */
|
|
51
|
+
navigation?: {
|
|
52
|
+
navigationStartMs: number;
|
|
53
|
+
firstPaintMs?: number;
|
|
54
|
+
firstContentfulPaintMs?: number;
|
|
55
|
+
domContentLoadedMs?: number;
|
|
56
|
+
loadEventMs?: number;
|
|
57
|
+
};
|
|
58
|
+
/** Aggregate counts — useful as a one-glance overview. */
|
|
59
|
+
totals: {
|
|
60
|
+
events: number;
|
|
61
|
+
longTaskCount: number;
|
|
62
|
+
layoutShiftCount: number;
|
|
63
|
+
layoutShiftScoreSum: number;
|
|
64
|
+
renderBlockingCount: number;
|
|
65
|
+
};
|
|
66
|
+
/** Non-fatal extraction warnings (unknown event shapes, etc.). */
|
|
67
|
+
warnings?: string[];
|
|
68
|
+
}
|
|
69
|
+
/** Per-session trace state machine. One instance per SessionEntry. */
|
|
70
|
+
export declare class PerfTracingState {
|
|
71
|
+
private running;
|
|
72
|
+
private events;
|
|
73
|
+
/** Hook teardowns from the most recent `start`. */
|
|
74
|
+
private listeners;
|
|
75
|
+
/** Resolved-when the in-flight `Tracing.end` flushes all events. */
|
|
76
|
+
private completePromise;
|
|
77
|
+
private completeResolve;
|
|
78
|
+
/** Categories the current/last trace was started with — surfaced on stop. */
|
|
79
|
+
private categories;
|
|
80
|
+
private startedAt;
|
|
81
|
+
/** True iff a trace is currently being collected. */
|
|
82
|
+
isRunning(): boolean;
|
|
83
|
+
/** Start tracing on `cdp`. If a trace is already running, stops it cleanly
|
|
84
|
+
* first (events discarded) — guarantees the caller never gets stuck in a
|
|
85
|
+
* "tracing already started" CDP error from a stale start. */
|
|
86
|
+
start(cdp: CDPSession, opts?: {
|
|
87
|
+
categories?: string[];
|
|
88
|
+
}): Promise<{
|
|
89
|
+
categories: string[];
|
|
90
|
+
restarted: boolean;
|
|
91
|
+
}>;
|
|
92
|
+
/** Stop tracing and return the buffered events. Safe to call when no trace
|
|
93
|
+
* is running — returns `notRunning:true` with an empty event list. */
|
|
94
|
+
stop(cdp: CDPSession): Promise<{
|
|
95
|
+
notRunning?: true;
|
|
96
|
+
events: TraceEvent[];
|
|
97
|
+
categories: string[];
|
|
98
|
+
durationMs: number;
|
|
99
|
+
}>;
|
|
100
|
+
/** Force-clean teardown for session close paths. Tolerates double calls. */
|
|
101
|
+
closeIfRunning(cdp: CDPSession): Promise<void>;
|
|
102
|
+
/** Internal stop: send `Tracing.end`, wait for the `tracingComplete` flush,
|
|
103
|
+
* detach listeners. Guarantees `running=false` even on errors so the
|
|
104
|
+
* next start always works. */
|
|
105
|
+
private stopInternal;
|
|
106
|
+
}
|
|
107
|
+
export declare function resolvePerfTracePath(workspaceRoot: string, p: string, tool: string): string;
|
|
108
|
+
/** Default trace filename under `<workspace>/perf-traces/<sessionId>-<ts>.json`. */
|
|
109
|
+
export declare function defaultTracePath(workspaceRoot: string, sessionId: string): string;
|
|
110
|
+
/** Write a trace event array as a chrome-tracing-compatible JSON file. The
|
|
111
|
+
* format the chromium ecosystem expects is `{ traceEvents: [...] }`; we
|
|
112
|
+
* also include `metadata` so a roundtrip through tracingControl tools is
|
|
113
|
+
* cleanly identifiable. */
|
|
114
|
+
export declare function writeTraceFile(workspaceRoot: string, filePath: string, events: TraceEvent[], meta: {
|
|
115
|
+
categories: string[];
|
|
116
|
+
sessionId: string;
|
|
117
|
+
durationMs: number;
|
|
118
|
+
}, tool: string): {
|
|
119
|
+
resolved: string;
|
|
120
|
+
bytes: number;
|
|
121
|
+
};
|
|
122
|
+
/** Read a trace file and return the event array. */
|
|
123
|
+
export declare function readTraceFile(workspaceRoot: string, filePath: string, tool: string): {
|
|
124
|
+
events: TraceEvent[];
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
};
|
|
127
|
+
export declare function extractInsights(events: TraceEvent[]): PerfInsights;
|