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,496 @@
|
|
|
1
|
+
// `browxai plugin` CLI subcommands — install, remove, list, info,
|
|
2
|
+
// upgrade, sync. Shells out to a package manager against the
|
|
3
|
+
// workspace-rooted install dir: `pnpm` when available (the project's
|
|
4
|
+
// native manager), falling back to `npm` for adopters who installed
|
|
5
|
+
// browxai with npm and have no pnpm on PATH. Never auto-restarts the
|
|
6
|
+
// server — every command emits a "Server restart required" advisory.
|
|
7
|
+
//
|
|
8
|
+
// Reproducibility surface:
|
|
9
|
+
// - <workspace>/plugins.json declarative truth
|
|
10
|
+
// - <workspace>/plugins-lock.json auto-generated pin + sha256
|
|
11
|
+
// - <workspace>/plugins/ install dir (with node_modules/)
|
|
12
|
+
//
|
|
13
|
+
// The lock file format is documented inline below — kept small and
|
|
14
|
+
// hand-readable.
|
|
15
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
16
|
+
import { createHash } from "node:crypto";
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
18
|
+
import { join, relative, sep } from "node:path";
|
|
19
|
+
import { resolveWorkspace } from "../util/workspace.js";
|
|
20
|
+
import { log } from "../util/logging.js";
|
|
21
|
+
import { pluginPaths } from "./resolver.js";
|
|
22
|
+
import { packageManagerAdapter, packageManagerAdaptersByPriority, } from "./package-manager.js";
|
|
23
|
+
import { registerPluginCommand, pluginCommandFor } from "./command-registry.js";
|
|
24
|
+
const RESTART_NOTICE = "Server restart required — plugins are resolved ONCE at server start, so changes only take effect after a fresh `browxai` start.";
|
|
25
|
+
function readPluginsJson(paths) {
|
|
26
|
+
if (!existsSync(paths.declarationFile))
|
|
27
|
+
return { plugins: {} };
|
|
28
|
+
try {
|
|
29
|
+
const raw = JSON.parse(readFileSync(paths.declarationFile, "utf8"));
|
|
30
|
+
if (raw && typeof raw === "object" && raw !== null) {
|
|
31
|
+
const r = raw;
|
|
32
|
+
if (Array.isArray(r.plugins)) {
|
|
33
|
+
// Normalise array → object form.
|
|
34
|
+
const obj = {};
|
|
35
|
+
for (const n of r.plugins) {
|
|
36
|
+
if (typeof n === "string")
|
|
37
|
+
obj[n] = { enabled: true };
|
|
38
|
+
}
|
|
39
|
+
return { plugins: obj };
|
|
40
|
+
}
|
|
41
|
+
if (r.plugins && typeof r.plugins === "object") {
|
|
42
|
+
return { plugins: r.plugins };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
/* fall through */
|
|
48
|
+
}
|
|
49
|
+
return { plugins: {} };
|
|
50
|
+
}
|
|
51
|
+
function writePluginsJson(paths, data) {
|
|
52
|
+
mkdirSync(paths.root, { recursive: true });
|
|
53
|
+
writeFileSync(paths.declarationFile, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
54
|
+
}
|
|
55
|
+
/** Tolerant lock read — also consumed by `browxai doctor` for lock-health checks. */
|
|
56
|
+
export function readLock(paths) {
|
|
57
|
+
if (!existsSync(paths.lockFile))
|
|
58
|
+
return { lockfileVersion: 1, entries: {} };
|
|
59
|
+
try {
|
|
60
|
+
const raw = JSON.parse(readFileSync(paths.lockFile, "utf8"));
|
|
61
|
+
if (raw && raw.lockfileVersion === 1 && raw.entries) {
|
|
62
|
+
return { lockfileVersion: 1, entries: raw.entries };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
/* fall through */
|
|
67
|
+
}
|
|
68
|
+
return { lockfileVersion: 1, entries: {} };
|
|
69
|
+
}
|
|
70
|
+
function writeLock(paths, data) {
|
|
71
|
+
mkdirSync(paths.root, { recursive: true });
|
|
72
|
+
writeFileSync(paths.lockFile, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
73
|
+
}
|
|
74
|
+
/** Content pin over an installed package — the same hash `plugins-lock.json`
|
|
75
|
+
* stores as `contentSha256`. Exported so `browxai doctor` can recompute it
|
|
76
|
+
* and detect drift against the pinned value. */
|
|
77
|
+
export function sha256OfPackage(pkgRoot) {
|
|
78
|
+
const hash = createHash("sha256");
|
|
79
|
+
// Hash package.json verbatim + every file referenced by `files`/`main`/
|
|
80
|
+
// `browxai.register`. Falls back to walking package.json + main entry
|
|
81
|
+
// when the field isn't there. Keep small + deterministic.
|
|
82
|
+
const pkgJsonPath = join(pkgRoot, "package.json");
|
|
83
|
+
if (!existsSync(pkgJsonPath))
|
|
84
|
+
return "";
|
|
85
|
+
const pkgJson = readFileSync(pkgJsonPath);
|
|
86
|
+
hash.update(pkgJson);
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(pkgJson.toString("utf8"));
|
|
89
|
+
const targets = new Set();
|
|
90
|
+
if (parsed.browxai?.register)
|
|
91
|
+
targets.add(parsed.browxai.register);
|
|
92
|
+
if (parsed.main)
|
|
93
|
+
targets.add(parsed.main);
|
|
94
|
+
for (const f of parsed.files ?? [])
|
|
95
|
+
targets.add(f);
|
|
96
|
+
for (const rel of [...targets].sort()) {
|
|
97
|
+
const abs = join(pkgRoot, rel);
|
|
98
|
+
if (!existsSync(abs))
|
|
99
|
+
continue;
|
|
100
|
+
const st = statSync(abs);
|
|
101
|
+
if (st.isFile()) {
|
|
102
|
+
hash.update(rel);
|
|
103
|
+
hash.update(readFileSync(abs));
|
|
104
|
+
}
|
|
105
|
+
else if (st.isDirectory()) {
|
|
106
|
+
for (const sub of walkDir(abs)) {
|
|
107
|
+
const subRel = relative(pkgRoot, sub).split(sep).join("/");
|
|
108
|
+
hash.update(subRel);
|
|
109
|
+
hash.update(readFileSync(sub));
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
/* fall through — partial hash is still meaningful for drift detection */
|
|
116
|
+
}
|
|
117
|
+
return hash.digest("hex");
|
|
118
|
+
}
|
|
119
|
+
function* walkDir(dir) {
|
|
120
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
121
|
+
const p = join(dir, entry.name);
|
|
122
|
+
if (entry.isFile())
|
|
123
|
+
yield p;
|
|
124
|
+
else if (entry.isDirectory())
|
|
125
|
+
yield* walkDir(p);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Emitted when neither pnpm nor npm is on PATH — actionable, names the
|
|
129
|
+
* requirement. Exported for the CLI tests. */
|
|
130
|
+
export const NO_PACKAGE_MANAGER_ERROR = "browxai plugin: no package manager found. Managing workspace plugins requires `pnpm` (preferred) or `npm` on PATH — install one (https://pnpm.io/installation or https://nodejs.org) and re-run.";
|
|
131
|
+
function canSpawn(cmd) {
|
|
132
|
+
const r = spawnSync(cmd, ["--version"], { stdio: "ignore" });
|
|
133
|
+
return !r.error && r.status === 0;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Probe for an available package manager. The adapters are walked in ascending
|
|
137
|
+
* probe priority (pnpm at 0 wins — it is the project's declared manager and what
|
|
138
|
+
* CI uses; npm at 1 is the fallback so `npm install -g browxai` adopters aren't
|
|
139
|
+
* dead-ended with a bare ENOENT). Returns null when none is on PATH. Adding a
|
|
140
|
+
* manager is a new adapter registration, not an edit here.
|
|
141
|
+
*/
|
|
142
|
+
export function detectPackageManager(probe = canSpawn) {
|
|
143
|
+
for (const adapter of packageManagerAdaptersByPriority()) {
|
|
144
|
+
if (probe(adapter.name))
|
|
145
|
+
return adapter.name;
|
|
146
|
+
}
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
/** Translate an operation (+ optional target spec) into manager argv. */
|
|
150
|
+
export function pmArgs(pm, op, target) {
|
|
151
|
+
const adapter = packageManagerAdapter(pm);
|
|
152
|
+
if (!adapter)
|
|
153
|
+
throw new Error(`browxai plugin: no adapter registered for package manager "${pm}"`);
|
|
154
|
+
const verb = adapter.verbs[op];
|
|
155
|
+
return target === undefined ? [verb] : [verb, target];
|
|
156
|
+
}
|
|
157
|
+
async function runPm(paths, op, target) {
|
|
158
|
+
const pm = detectPackageManager();
|
|
159
|
+
if (pm === null) {
|
|
160
|
+
process.stderr.write(`${NO_PACKAGE_MANAGER_ERROR}\n`);
|
|
161
|
+
return 127;
|
|
162
|
+
}
|
|
163
|
+
// paths.installDir is workspace-rooted by construction (see
|
|
164
|
+
// pluginPaths() in resolver.ts — `<workspace>/plugins/`).
|
|
165
|
+
mkdirSync(paths.installDir, { recursive: true });
|
|
166
|
+
// Create a stub package.json so the manager has a project root to write into.
|
|
167
|
+
const stub = join(paths.installDir, "package.json");
|
|
168
|
+
if (!existsSync(stub)) {
|
|
169
|
+
writeFileSync(stub, JSON.stringify({ name: "browxai-plugins", version: "0.0.0", private: true }, null, 2) + "\n", "utf8");
|
|
170
|
+
}
|
|
171
|
+
const args = pmArgs(pm, op, target);
|
|
172
|
+
return new Promise((resolve) => {
|
|
173
|
+
const child = spawn(pm, [...args], {
|
|
174
|
+
cwd: paths.installDir,
|
|
175
|
+
stdio: "inherit",
|
|
176
|
+
});
|
|
177
|
+
child.on("exit", (code) => resolve(code ?? 1));
|
|
178
|
+
child.on("error", (err) => {
|
|
179
|
+
log.error(`browxai plugin: ${pm} spawn failed — ${err.message}`);
|
|
180
|
+
process.stderr.write(`${NO_PACKAGE_MANAGER_ERROR}\n`);
|
|
181
|
+
resolve(127);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Pin entry for `plugins-lock.json` — recompute version + sha256 after
|
|
187
|
+
* an install / upgrade / sync operation.
|
|
188
|
+
*/
|
|
189
|
+
function pinEntry(paths, name, source) {
|
|
190
|
+
const pkgRoot = join(paths.nodeModulesDir, name);
|
|
191
|
+
const pkgJsonPath = join(pkgRoot, "package.json");
|
|
192
|
+
if (!existsSync(pkgJsonPath))
|
|
193
|
+
return null;
|
|
194
|
+
try {
|
|
195
|
+
const parsed = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
196
|
+
return {
|
|
197
|
+
name,
|
|
198
|
+
version: parsed.version ?? "0.0.0",
|
|
199
|
+
source,
|
|
200
|
+
contentSha256: sha256OfPackage(pkgRoot),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function inferTrustFromSource(source) {
|
|
208
|
+
if (source.startsWith("file:"))
|
|
209
|
+
return "local";
|
|
210
|
+
if (source.startsWith("@browxai/"))
|
|
211
|
+
return "kalebtec";
|
|
212
|
+
return "community";
|
|
213
|
+
}
|
|
214
|
+
/** Resolve the plugin name a `pnpm add` spec installs.
|
|
215
|
+
* Heuristic: drop a leading `file:` (the dir name is what npm uses);
|
|
216
|
+
* otherwise strip a trailing `@<version>` range. The CLI logs the
|
|
217
|
+
* resolved name before writing it to plugins.json so an operator can
|
|
218
|
+
* see what was added. */
|
|
219
|
+
function resolveInstalledName(source) {
|
|
220
|
+
if (source.startsWith("file:")) {
|
|
221
|
+
const rel = source.slice("file:".length).replace(/\/+$/, "");
|
|
222
|
+
const base = rel.split("/").pop() ?? rel;
|
|
223
|
+
// For file: installs, the actual installed name in node_modules is
|
|
224
|
+
// the package's `name` field — not the directory base. Walk
|
|
225
|
+
// node_modules afterward and find the match. Best-effort fallback:
|
|
226
|
+
// use the dir base if the package.json isn't reachable yet.
|
|
227
|
+
return base;
|
|
228
|
+
}
|
|
229
|
+
// Strip trailing `@version` (but tolerate scoped names that start with `@`).
|
|
230
|
+
const at = source.lastIndexOf("@");
|
|
231
|
+
if (at <= 0)
|
|
232
|
+
return source;
|
|
233
|
+
// e.g. `@scope/pkg@^1.0.0` → keep `@scope/pkg`
|
|
234
|
+
return source.slice(0, at);
|
|
235
|
+
}
|
|
236
|
+
function findActualPackageName(paths, hint) {
|
|
237
|
+
// For file: installs the directory base may not match the package
|
|
238
|
+
// name — walk node_modules looking for a package.json whose own
|
|
239
|
+
// path matches.
|
|
240
|
+
const direct = join(paths.nodeModulesDir, hint, "package.json");
|
|
241
|
+
if (existsSync(direct))
|
|
242
|
+
return hint;
|
|
243
|
+
// Scoped: search one level deeper.
|
|
244
|
+
if (existsSync(paths.nodeModulesDir)) {
|
|
245
|
+
for (const entry of readdirSync(paths.nodeModulesDir, { withFileTypes: true })) {
|
|
246
|
+
if (!entry.isDirectory())
|
|
247
|
+
continue;
|
|
248
|
+
if (entry.name.startsWith("@")) {
|
|
249
|
+
const scopeDir = join(paths.nodeModulesDir, entry.name);
|
|
250
|
+
for (const sub of readdirSync(scopeDir, { withFileTypes: true })) {
|
|
251
|
+
if (sub.isDirectory()) {
|
|
252
|
+
const full = `${entry.name}/${sub.name}`;
|
|
253
|
+
const pj = join(paths.nodeModulesDir, full, "package.json");
|
|
254
|
+
if (existsSync(pj)) {
|
|
255
|
+
try {
|
|
256
|
+
const parsed = JSON.parse(readFileSync(pj, "utf8"));
|
|
257
|
+
if (parsed.name === hint || sub.name === hint)
|
|
258
|
+
return full;
|
|
259
|
+
}
|
|
260
|
+
catch {
|
|
261
|
+
/* */
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else {
|
|
268
|
+
const pj = join(paths.nodeModulesDir, entry.name, "package.json");
|
|
269
|
+
if (existsSync(pj)) {
|
|
270
|
+
try {
|
|
271
|
+
const parsed = JSON.parse(readFileSync(pj, "utf8"));
|
|
272
|
+
if (parsed.name === hint)
|
|
273
|
+
return entry.name;
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
/* */
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return hint;
|
|
283
|
+
}
|
|
284
|
+
async function cmdInstall(spec) {
|
|
285
|
+
const ws = resolveWorkspace();
|
|
286
|
+
const paths = pluginPaths(ws.root);
|
|
287
|
+
process.stderr.write(`browxai plugin: installing "${spec}" into ${paths.installDir}\n`);
|
|
288
|
+
const code = await runPm(paths, "add", spec);
|
|
289
|
+
if (code !== 0) {
|
|
290
|
+
process.stderr.write(`browxai plugin: install failed (exit ${code})\n`);
|
|
291
|
+
return code;
|
|
292
|
+
}
|
|
293
|
+
const hintName = resolveInstalledName(spec);
|
|
294
|
+
const name = findActualPackageName(paths, hintName);
|
|
295
|
+
// Persist into plugins.json.
|
|
296
|
+
const data = readPluginsJson(paths);
|
|
297
|
+
const trust = inferTrustFromSource(spec.startsWith("file:") ? spec : name);
|
|
298
|
+
data.plugins[name] = { enabled: true, ...(trust === "local" ? { trust: "local" } : {}) };
|
|
299
|
+
writePluginsJson(paths, data);
|
|
300
|
+
// Persist into plugins-lock.json.
|
|
301
|
+
const lock = readLock(paths);
|
|
302
|
+
const pinned = pinEntry(paths, name, spec);
|
|
303
|
+
if (pinned)
|
|
304
|
+
lock.entries[name] = pinned;
|
|
305
|
+
writeLock(paths, lock);
|
|
306
|
+
process.stderr.write(`browxai plugin: installed ${name}@${pinned?.version ?? "?"} (trust=${trust})\n`);
|
|
307
|
+
process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
|
|
308
|
+
return 0;
|
|
309
|
+
}
|
|
310
|
+
async function cmdRemove(name) {
|
|
311
|
+
const ws = resolveWorkspace();
|
|
312
|
+
const paths = pluginPaths(ws.root);
|
|
313
|
+
process.stderr.write(`browxai plugin: removing "${name}"\n`);
|
|
314
|
+
const code = await runPm(paths, "remove", name);
|
|
315
|
+
if (code !== 0) {
|
|
316
|
+
process.stderr.write(`browxai plugin: remove failed (exit ${code})\n`);
|
|
317
|
+
return code;
|
|
318
|
+
}
|
|
319
|
+
const data = readPluginsJson(paths);
|
|
320
|
+
delete data.plugins[name];
|
|
321
|
+
writePluginsJson(paths, data);
|
|
322
|
+
const lock = readLock(paths);
|
|
323
|
+
delete lock.entries[name];
|
|
324
|
+
writeLock(paths, lock);
|
|
325
|
+
process.stderr.write(`browxai plugin: removed ${name}\n`);
|
|
326
|
+
process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
|
|
327
|
+
return 0;
|
|
328
|
+
}
|
|
329
|
+
function cmdList() {
|
|
330
|
+
const ws = resolveWorkspace();
|
|
331
|
+
const paths = pluginPaths(ws.root);
|
|
332
|
+
const data = readPluginsJson(paths);
|
|
333
|
+
const lock = readLock(paths);
|
|
334
|
+
const names = Object.keys(data.plugins).sort();
|
|
335
|
+
if (names.length === 0) {
|
|
336
|
+
process.stdout.write("browxai plugin: no plugins declared\n");
|
|
337
|
+
return 0;
|
|
338
|
+
}
|
|
339
|
+
process.stdout.write(`browxai plugin: ${names.length} declared\n`);
|
|
340
|
+
for (const name of names) {
|
|
341
|
+
const entry = data.plugins[name];
|
|
342
|
+
const pin = lock.entries[name];
|
|
343
|
+
const installed = pin ? `${pin.version}` : "(not installed)";
|
|
344
|
+
const enabled = entry.enabled === false ? " [disabled]" : "";
|
|
345
|
+
const trust = entry.trust ? ` trust=${entry.trust}` : "";
|
|
346
|
+
process.stdout.write(` - ${name}@${installed}${trust}${enabled}\n`);
|
|
347
|
+
}
|
|
348
|
+
return 0;
|
|
349
|
+
}
|
|
350
|
+
function cmdInfo(name) {
|
|
351
|
+
const ws = resolveWorkspace();
|
|
352
|
+
const paths = pluginPaths(ws.root);
|
|
353
|
+
const data = readPluginsJson(paths);
|
|
354
|
+
const lock = readLock(paths);
|
|
355
|
+
const entry = data.plugins[name];
|
|
356
|
+
if (!entry) {
|
|
357
|
+
process.stderr.write(`browxai plugin: "${name}" is not declared in plugins.json\n`);
|
|
358
|
+
return 1;
|
|
359
|
+
}
|
|
360
|
+
const pkgJsonPath = join(paths.nodeModulesDir, name, "package.json");
|
|
361
|
+
let manifestSummary = null;
|
|
362
|
+
if (existsSync(pkgJsonPath)) {
|
|
363
|
+
try {
|
|
364
|
+
const parsed = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
|
|
365
|
+
manifestSummary = {
|
|
366
|
+
name: parsed.name,
|
|
367
|
+
version: parsed.version,
|
|
368
|
+
description: parsed.description,
|
|
369
|
+
browxai: parsed.browxai,
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
manifestSummary = { error: "package.json malformed" };
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
const info = {
|
|
377
|
+
declared: entry,
|
|
378
|
+
lock: lock.entries[name] ?? null,
|
|
379
|
+
manifest: manifestSummary,
|
|
380
|
+
notes: manifestSummary === null
|
|
381
|
+
? "Not installed. Run `browxai plugin install` or `browxai plugin sync`."
|
|
382
|
+
: null,
|
|
383
|
+
};
|
|
384
|
+
process.stdout.write(JSON.stringify(info, null, 2) + "\n");
|
|
385
|
+
return 0;
|
|
386
|
+
}
|
|
387
|
+
async function cmdUpgrade(name) {
|
|
388
|
+
const ws = resolveWorkspace();
|
|
389
|
+
const paths = pluginPaths(ws.root);
|
|
390
|
+
process.stderr.write(`browxai plugin: ${name ? `upgrading ${name}` : "upgrading all"}\n`);
|
|
391
|
+
const code = await runPm(paths, "update", name);
|
|
392
|
+
if (code !== 0) {
|
|
393
|
+
process.stderr.write(`browxai plugin: upgrade failed (exit ${code})\n`);
|
|
394
|
+
return code;
|
|
395
|
+
}
|
|
396
|
+
// Re-pin the lock for affected entries.
|
|
397
|
+
const lock = readLock(paths);
|
|
398
|
+
const targets = name ? [name] : Object.keys(lock.entries);
|
|
399
|
+
for (const t of targets) {
|
|
400
|
+
const prevSource = lock.entries[t]?.source ?? t;
|
|
401
|
+
const pinned = pinEntry(paths, t, prevSource);
|
|
402
|
+
if (pinned)
|
|
403
|
+
lock.entries[t] = pinned;
|
|
404
|
+
}
|
|
405
|
+
writeLock(paths, lock);
|
|
406
|
+
process.stderr.write(`browxai plugin: ${RESTART_NOTICE}\n`);
|
|
407
|
+
return 0;
|
|
408
|
+
}
|
|
409
|
+
async function cmdSync() {
|
|
410
|
+
const ws = resolveWorkspace();
|
|
411
|
+
const paths = pluginPaths(ws.root);
|
|
412
|
+
const data = readPluginsJson(paths);
|
|
413
|
+
const declared = Object.keys(data.plugins);
|
|
414
|
+
if (declared.length === 0) {
|
|
415
|
+
process.stdout.write("browxai plugin: nothing to sync (no plugins declared)\n");
|
|
416
|
+
return 0;
|
|
417
|
+
}
|
|
418
|
+
process.stderr.write(`browxai plugin: syncing ${declared.length} declared plugin(s)\n`);
|
|
419
|
+
// Run a single bare `install` so the package manager reconciles
|
|
420
|
+
// everything against the install dir's package.json (covers file:
|
|
421
|
+
// entries, whose original spec we don't know).
|
|
422
|
+
const code = await runPm(paths, "install");
|
|
423
|
+
if (code !== 0) {
|
|
424
|
+
process.stderr.write(`browxai plugin: sync install failed (exit ${code})\n`);
|
|
425
|
+
return code;
|
|
426
|
+
}
|
|
427
|
+
// Refresh lock for everything.
|
|
428
|
+
const lock = readLock(paths);
|
|
429
|
+
for (const name of declared) {
|
|
430
|
+
const prevSource = lock.entries[name]?.source ?? name;
|
|
431
|
+
const pinned = pinEntry(paths, name, prevSource);
|
|
432
|
+
if (pinned)
|
|
433
|
+
lock.entries[name] = pinned;
|
|
434
|
+
}
|
|
435
|
+
writeLock(paths, lock);
|
|
436
|
+
process.stderr.write(`browxai plugin: sync done. ${RESTART_NOTICE}\n`);
|
|
437
|
+
return 0;
|
|
438
|
+
}
|
|
439
|
+
function help() {
|
|
440
|
+
process.stdout.write(`Usage: browxai plugin <subcommand>\n\n` +
|
|
441
|
+
` install <pkg> install a plugin from npm (or file:./path) into the workspace\n` +
|
|
442
|
+
` remove <pkg> remove a plugin\n` +
|
|
443
|
+
` list list declared plugins\n` +
|
|
444
|
+
` info <pkg> full manifest + lock entry for one plugin\n` +
|
|
445
|
+
` upgrade [<pkg>] upgrade one plugin (or all when omitted)\n` +
|
|
446
|
+
` sync reconcile installed node_modules with plugins.json\n\n` +
|
|
447
|
+
`Every command writes to <workspace>/. Plugin lifecycle is\n` +
|
|
448
|
+
`resolved ONCE at server start — restart the server after any change.\n`);
|
|
449
|
+
return 0;
|
|
450
|
+
}
|
|
451
|
+
// RFC 0004 P4 / D6 — the extensibility verbs are an add-only registry. Each
|
|
452
|
+
// handler owns its OWN argument validation (the install/remove/info missing-arg
|
|
453
|
+
// checks the old `case` performed) and returns the SAME exit code, so the
|
|
454
|
+
// dispatch in `runPlugin` is a pure registry lookup. Adding a verb is one
|
|
455
|
+
// `registerPluginCommand(...)` line here, not a new `switch` arm.
|
|
456
|
+
registerPluginCommand("install", (rest) => {
|
|
457
|
+
if (!rest[0]) {
|
|
458
|
+
process.stderr.write("browxai plugin install: missing <pkg> argument\n");
|
|
459
|
+
return 1;
|
|
460
|
+
}
|
|
461
|
+
return cmdInstall(rest[0]);
|
|
462
|
+
});
|
|
463
|
+
registerPluginCommand("remove", (rest) => {
|
|
464
|
+
if (!rest[0]) {
|
|
465
|
+
process.stderr.write("browxai plugin remove: missing <pkg> argument\n");
|
|
466
|
+
return 1;
|
|
467
|
+
}
|
|
468
|
+
return cmdRemove(rest[0]);
|
|
469
|
+
});
|
|
470
|
+
registerPluginCommand("list", () => cmdList());
|
|
471
|
+
registerPluginCommand("info", (rest) => {
|
|
472
|
+
if (!rest[0]) {
|
|
473
|
+
process.stderr.write("browxai plugin info: missing <pkg> argument\n");
|
|
474
|
+
return 1;
|
|
475
|
+
}
|
|
476
|
+
return cmdInfo(rest[0]);
|
|
477
|
+
});
|
|
478
|
+
registerPluginCommand("upgrade", (rest) => cmdUpgrade(rest[0]));
|
|
479
|
+
registerPluginCommand("sync", () => cmdSync());
|
|
480
|
+
/** CLI dispatcher — invoked by `src/cli.ts` for the `plugin` subcommand. The
|
|
481
|
+
* help branch (no verb / `help` / `--help` / `-h`) and the unknown-verb
|
|
482
|
+
* diagnostic stay inline — they are the subcommand's fixed contract; the
|
|
483
|
+
* extensibility verbs resolve through the add-only registry above. */
|
|
484
|
+
export async function runPlugin(args) {
|
|
485
|
+
const [sub, ...rest] = args;
|
|
486
|
+
if (sub === undefined || sub === "help" || sub === "--help" || sub === "-h") {
|
|
487
|
+
return help();
|
|
488
|
+
}
|
|
489
|
+
const handler = pluginCommandFor(sub);
|
|
490
|
+
if (handler) {
|
|
491
|
+
return handler(rest);
|
|
492
|
+
}
|
|
493
|
+
process.stderr.write(`browxai plugin: unknown subcommand "${sub}"\n`);
|
|
494
|
+
help();
|
|
495
|
+
return 2;
|
|
496
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** A plugin subcommand handler: receives the argv after the verb token, returns
|
|
2
|
+
* the process exit code. */
|
|
3
|
+
export type PluginCommandHandler = (rest: string[]) => Promise<number> | number;
|
|
4
|
+
/** Register a plugin subcommand handler. Add-only: a new verb is one
|
|
5
|
+
* `registerPluginCommand(...)` call, never a new `case` in `runPlugin`. */
|
|
6
|
+
export declare function registerPluginCommand(name: string, handler: PluginCommandHandler): void;
|
|
7
|
+
/** Resolve a plugin subcommand handler, or `undefined` when the token is not a
|
|
8
|
+
* registered verb (the caller then runs the help / unknown-verb path). */
|
|
9
|
+
export declare function pluginCommandFor(name: string): PluginCommandHandler | undefined;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// `browxai plugin` subcommand registry (RFC 0004 P4 / D6) — the add-only
|
|
2
|
+
// `Map<string, PluginCommandHandler>` that replaces the extensibility arms of
|
|
3
|
+
// the `switch (sub)` in `runPlugin` (`plugin/cli.ts`).
|
|
4
|
+
//
|
|
5
|
+
// Scope: the EXTENSIBILITY verbs (`install` / `remove` / `list` / `info` /
|
|
6
|
+
// `upgrade` / `sync`) — the ones a future verb is added alongside. The
|
|
7
|
+
// `undefined` / `help` / `--help` / `-h` help branch and the unknown-verb
|
|
8
|
+
// diagnostic stay inline in `runPlugin`: they are the subcommand's fixed CLI
|
|
9
|
+
// contract, not extension points. Each handler receives the argv after the verb
|
|
10
|
+
// token (`rest`) and returns the exit code, owning its OWN argument validation
|
|
11
|
+
// (the `install`/`remove`/`info` missing-arg checks moved into their handlers),
|
|
12
|
+
// so the dispatch resolves the SAME handler the old `case` did.
|
|
13
|
+
const PLUGIN_COMMANDS = new Map();
|
|
14
|
+
/** Register a plugin subcommand handler. Add-only: a new verb is one
|
|
15
|
+
* `registerPluginCommand(...)` call, never a new `case` in `runPlugin`. */
|
|
16
|
+
export function registerPluginCommand(name, handler) {
|
|
17
|
+
PLUGIN_COMMANDS.set(name, handler);
|
|
18
|
+
}
|
|
19
|
+
/** Resolve a plugin subcommand handler, or `undefined` when the token is not a
|
|
20
|
+
* registered verb (the caller then runs the help / unknown-verb path). */
|
|
21
|
+
export function pluginCommandFor(name) {
|
|
22
|
+
return PLUGIN_COMMANDS.get(name);
|
|
23
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface DepGraphInput {
|
|
2
|
+
/** Plugin name → list of plugin names it depends on (declared, direct). */
|
|
3
|
+
readonly directDeps: ReadonlyMap<string, ReadonlyArray<string>>;
|
|
4
|
+
}
|
|
5
|
+
export interface DepGraphResult {
|
|
6
|
+
/**
|
|
7
|
+
* Plugin names in load order (deps before dependents). Acyclic graphs
|
|
8
|
+
* always produce a result; cyclic ones throw.
|
|
9
|
+
*/
|
|
10
|
+
readonly loadOrder: ReadonlyArray<string>;
|
|
11
|
+
/**
|
|
12
|
+
* For each plugin, the FULL transitive set of plugins it may call into
|
|
13
|
+
* (its declared dependsOn, plus everything those deps reach). Does NOT
|
|
14
|
+
* include the plugin itself — a plugin calling its own tools is
|
|
15
|
+
* trivially allowed at the call-graph layer.
|
|
16
|
+
*/
|
|
17
|
+
readonly transitiveDeps: ReadonlyMap<string, ReadonlySet<string>>;
|
|
18
|
+
}
|
|
19
|
+
export declare class DepGraphCycleError extends Error {
|
|
20
|
+
readonly cycles: ReadonlyArray<ReadonlyArray<string>>;
|
|
21
|
+
constructor(cycles: ReadonlyArray<ReadonlyArray<string>>);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Build the dep graph result. Throws {@link DepGraphCycleError} if any
|
|
25
|
+
* non-trivial strongly-connected component is found. The error names
|
|
26
|
+
* every plugin in every cycle.
|
|
27
|
+
*
|
|
28
|
+
* Self-edges (`pluginA -> pluginA`) are tolerated and ignored — a
|
|
29
|
+
* self-edge encodes "this plugin can call its own tools" which is
|
|
30
|
+
* always-true and harmless.
|
|
31
|
+
*
|
|
32
|
+
* Edges pointing at plugins that aren't in `directDeps.keys()` are
|
|
33
|
+
* tolerated at this layer; the runtime separately validates that
|
|
34
|
+
* dependsOn targets exist + satisfy their semver range. We only model
|
|
35
|
+
* what's in the graph here.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildDepGraph(input: DepGraphInput): DepGraphResult;
|