@agentrhq/webcmd 0.1.1 → 0.1.2
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/README.md +317 -24
- package/dist/src/adapter-shadow.d.ts +11 -0
- package/dist/src/adapter-shadow.js +72 -0
- package/dist/src/adapter-shadow.test.d.ts +1 -0
- package/dist/src/adapter-shadow.test.js +49 -0
- package/dist/src/adapter-source.d.ts +11 -0
- package/dist/src/adapter-source.js +24 -0
- package/dist/src/adapter-source.test.d.ts +1 -0
- package/dist/src/adapter-source.test.js +29 -0
- package/dist/src/brand.d.ts +9 -0
- package/dist/src/brand.js +9 -0
- package/dist/src/brand.test.d.ts +1 -0
- package/dist/src/brand.test.js +15 -0
- package/dist/src/browser/analyze.d.ts +118 -0
- package/dist/src/browser/analyze.js +405 -0
- package/dist/src/browser/analyze.test.d.ts +1 -0
- package/dist/src/browser/analyze.test.js +209 -0
- package/dist/src/browser/article-extract.d.ts +57 -0
- package/dist/src/browser/article-extract.e2e.test.d.ts +1 -0
- package/dist/src/browser/article-extract.e2e.test.js +105 -0
- package/dist/src/browser/article-extract.js +169 -0
- package/dist/src/browser/article-extract.test.d.ts +1 -0
- package/dist/src/browser/article-extract.test.js +94 -0
- package/dist/src/browser/ax-snapshot.d.ts +37 -0
- package/dist/src/browser/ax-snapshot.js +217 -0
- package/dist/src/browser/ax-snapshot.test.d.ts +1 -0
- package/dist/src/browser/ax-snapshot.test.js +91 -0
- package/dist/src/browser/base-page.d.ts +151 -0
- package/dist/src/browser/base-page.js +1060 -0
- package/dist/src/browser/base-page.test.d.ts +1 -0
- package/dist/src/browser/base-page.test.js +803 -0
- package/dist/src/browser/bridge-readiness.d.ts +14 -0
- package/dist/src/browser/bridge-readiness.js +24 -0
- package/dist/src/browser/bridge-readiness.test.d.ts +1 -0
- package/dist/src/browser/bridge-readiness.test.js +58 -0
- package/dist/src/browser/bridge.d.ts +26 -0
- package/dist/src/browser/bridge.js +58 -0
- package/dist/src/browser/cdp-click-fixture.test.d.ts +1 -0
- package/dist/src/browser/cdp-click-fixture.test.js +87 -0
- package/dist/src/browser/cdp.d.ts +46 -0
- package/dist/src/browser/cdp.js +536 -0
- package/dist/src/browser/cdp.test.d.ts +1 -0
- package/dist/src/browser/cdp.test.js +79 -0
- package/dist/src/browser/compound.d.ts +59 -0
- package/dist/src/browser/compound.js +112 -0
- package/dist/src/browser/compound.test.d.ts +1 -0
- package/dist/src/browser/compound.test.js +175 -0
- package/dist/src/browser/config.d.ts +2 -0
- package/dist/src/browser/config.js +14 -0
- package/dist/src/browser/daemon-client.d.ts +32 -0
- package/dist/src/browser/daemon-client.js +135 -0
- package/dist/src/browser/daemon-client.test.d.ts +1 -0
- package/dist/src/browser/daemon-client.test.js +326 -0
- package/dist/src/browser/daemon-lifecycle.d.ts +37 -0
- package/dist/src/browser/daemon-lifecycle.js +147 -0
- package/dist/src/browser/daemon-transport.d.ts +54 -0
- package/dist/src/browser/daemon-transport.js +68 -0
- package/dist/src/browser/daemon-version.d.ts +4 -0
- package/dist/src/browser/daemon-version.js +12 -0
- package/dist/src/browser/dom-helpers.d.ts +41 -0
- package/dist/src/browser/dom-helpers.js +239 -0
- package/dist/src/browser/dom-helpers.test.d.ts +1 -0
- package/dist/src/browser/dom-helpers.test.js +106 -0
- package/dist/src/browser/dom-snapshot.d.ts +93 -0
- package/dist/src/browser/dom-snapshot.js +894 -0
- package/dist/src/browser/dom-snapshot.test.d.ts +11 -0
- package/dist/src/browser/dom-snapshot.test.js +313 -0
- package/dist/src/browser/errors.d.ts +38 -0
- package/dist/src/browser/errors.js +79 -0
- package/dist/src/browser/errors.test.d.ts +1 -0
- package/dist/src/browser/errors.test.js +60 -0
- package/dist/src/browser/extract.d.ts +69 -0
- package/dist/src/browser/extract.js +132 -0
- package/dist/src/browser/extract.test.d.ts +1 -0
- package/dist/src/browser/extract.test.js +129 -0
- package/dist/src/browser/find.d.ts +84 -0
- package/dist/src/browser/find.js +398 -0
- package/dist/src/browser/find.test.d.ts +1 -0
- package/dist/src/browser/find.test.js +180 -0
- package/dist/src/browser/html-tree.d.ts +75 -0
- package/dist/src/browser/html-tree.js +112 -0
- package/dist/src/browser/html-tree.test.d.ts +1 -0
- package/dist/src/browser/html-tree.test.js +181 -0
- package/dist/src/browser/index.d.ts +14 -0
- package/dist/src/browser/index.js +12 -0
- package/dist/src/browser/network-cache.d.ts +49 -0
- package/dist/src/browser/network-cache.js +78 -0
- package/dist/src/browser/network-cache.test.d.ts +1 -0
- package/dist/src/browser/network-cache.test.js +75 -0
- package/dist/src/browser/network-interceptor.d.ts +11 -0
- package/dist/src/browser/network-interceptor.js +11 -0
- package/dist/src/browser/network-key.d.ts +22 -0
- package/dist/src/browser/network-key.js +66 -0
- package/dist/src/browser/network-key.test.d.ts +1 -0
- package/dist/src/browser/network-key.test.js +49 -0
- package/dist/src/browser/page.d.ts +83 -0
- package/dist/src/browser/page.js +453 -0
- package/dist/src/browser/page.test.d.ts +1 -0
- package/dist/src/browser/page.test.js +406 -0
- package/dist/src/browser/profile.d.ts +14 -0
- package/dist/src/browser/profile.js +86 -0
- package/dist/src/browser/protocol.d.ts +63 -0
- package/dist/src/browser/protocol.js +1 -0
- package/dist/src/browser/runtime/local-cloak/actions.d.ts +3 -0
- package/dist/src/browser/runtime/local-cloak/actions.js +240 -0
- package/dist/src/browser/runtime/local-cloak/downloads.d.ts +3 -0
- package/dist/src/browser/runtime/local-cloak/downloads.js +28 -0
- package/dist/src/browser/runtime/local-cloak/network.d.ts +28 -0
- package/dist/src/browser/runtime/local-cloak/network.js +120 -0
- package/dist/src/browser/runtime/local-cloak/network.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/network.test.js +124 -0
- package/dist/src/browser/runtime/local-cloak/profiles.d.ts +6 -0
- package/dist/src/browser/runtime/local-cloak/profiles.js +17 -0
- package/dist/src/browser/runtime/local-cloak/profiles.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/profiles.test.js +19 -0
- package/dist/src/browser/runtime/local-cloak/provider.d.ts +15 -0
- package/dist/src/browser/runtime/local-cloak/provider.js +27 -0
- package/dist/src/browser/runtime/local-cloak/provider.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/provider.test.js +244 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.d.ts +77 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.js +280 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.test.d.ts +1 -0
- package/dist/src/browser/runtime/local-cloak/session-manager.test.js +92 -0
- package/dist/src/browser/runtime/provider.d.ts +9 -0
- package/dist/src/browser/runtime/provider.js +1 -0
- package/dist/src/browser/runtime/provider.test.d.ts +2 -0
- package/dist/src/browser/runtime/provider.test.js +49 -0
- package/dist/src/browser/shape-filter.d.ts +52 -0
- package/dist/src/browser/shape-filter.js +101 -0
- package/dist/src/browser/shape-filter.test.d.ts +1 -0
- package/dist/src/browser/shape-filter.test.js +101 -0
- package/dist/src/browser/shape.d.ts +23 -0
- package/dist/src/browser/shape.js +95 -0
- package/dist/src/browser/shape.test.d.ts +1 -0
- package/dist/src/browser/shape.test.js +82 -0
- package/dist/src/browser/stealth.d.ts +11 -0
- package/dist/src/browser/stealth.js +359 -0
- package/dist/src/browser/stealth.test.d.ts +1 -0
- package/dist/src/browser/stealth.test.js +134 -0
- package/dist/src/browser/tabs.d.ts +13 -0
- package/dist/src/browser/tabs.js +70 -0
- package/dist/src/browser/target-errors.d.ts +39 -0
- package/dist/src/browser/target-errors.js +45 -0
- package/dist/src/browser/target-errors.test.d.ts +1 -0
- package/dist/src/browser/target-errors.test.js +94 -0
- package/dist/src/browser/target-resolver.d.ts +158 -0
- package/dist/src/browser/target-resolver.js +570 -0
- package/dist/src/browser/target-resolver.test.d.ts +1 -0
- package/dist/src/browser/target-resolver.test.js +118 -0
- package/dist/src/browser/utils.d.ts +20 -0
- package/dist/src/browser/utils.js +64 -0
- package/dist/src/browser/utils.test.d.ts +1 -0
- package/dist/src/browser/utils.test.js +29 -0
- package/dist/src/browser/verify-fixture.d.ts +65 -0
- package/dist/src/browser/verify-fixture.js +318 -0
- package/dist/src/browser/verify-fixture.test.d.ts +1 -0
- package/dist/src/browser/verify-fixture.test.js +219 -0
- package/dist/src/browser/visual-refs.d.ts +11 -0
- package/dist/src/browser/visual-refs.js +108 -0
- package/dist/src/browser.test.d.ts +1 -0
- package/dist/src/browser.test.js +297 -0
- package/dist/src/build-manifest.d.ts +103 -0
- package/dist/src/build-manifest.js +363 -0
- package/dist/src/build-manifest.test.d.ts +1 -0
- package/dist/src/build-manifest.test.js +341 -0
- package/dist/src/capabilityRouting.d.ts +19 -0
- package/dist/src/capabilityRouting.js +56 -0
- package/dist/src/capabilityRouting.test.d.ts +1 -0
- package/dist/src/capabilityRouting.test.js +63 -0
- package/dist/src/cli-argv-preprocess.d.ts +63 -0
- package/dist/src/cli-argv-preprocess.js +303 -0
- package/dist/src/cli-argv-preprocess.test.d.ts +1 -0
- package/dist/src/cli-argv-preprocess.test.js +304 -0
- package/dist/src/cli.d.ts +79 -0
- package/dist/src/cli.js +3350 -0
- package/dist/src/cli.test.d.ts +1 -0
- package/dist/src/cli.test.js +3041 -0
- package/dist/src/commanderAdapter.d.ts +21 -0
- package/dist/src/commanderAdapter.js +208 -0
- package/dist/src/commanderAdapter.test.d.ts +1 -0
- package/dist/src/commanderAdapter.test.js +352 -0
- package/dist/src/commands/auth.d.ts +40 -0
- package/dist/src/commands/auth.js +434 -0
- package/dist/src/commands/auth.test.d.ts +1 -0
- package/dist/src/commands/auth.test.js +252 -0
- package/dist/src/commands/daemon.d.ts +9 -0
- package/dist/src/commands/daemon.js +91 -0
- package/dist/src/commands/daemon.test.d.ts +1 -0
- package/dist/src/commands/daemon.test.js +293 -0
- package/dist/src/completion-fast.d.ts +22 -0
- package/dist/src/completion-fast.js +88 -0
- package/dist/src/completion-shared.d.ts +13 -0
- package/dist/src/completion-shared.js +61 -0
- package/dist/src/completion.d.ts +21 -0
- package/dist/src/completion.js +68 -0
- package/dist/src/completion.test.d.ts +1 -0
- package/dist/src/completion.test.js +24 -0
- package/dist/src/constants.d.ts +18 -0
- package/dist/src/constants.js +41 -0
- package/dist/src/convention-audit.d.ts +50 -0
- package/dist/src/convention-audit.js +553 -0
- package/dist/src/convention-audit.test.d.ts +1 -0
- package/dist/src/convention-audit.test.js +255 -0
- package/dist/src/daemon/server.d.ts +13 -0
- package/dist/src/daemon/server.js +185 -0
- package/dist/src/daemon/server.test.d.ts +1 -0
- package/dist/src/daemon/server.test.js +132 -0
- package/dist/src/daemon-utils.d.ts +18 -0
- package/dist/src/daemon-utils.js +37 -0
- package/dist/src/daemon.d.ts +1 -0
- package/dist/src/daemon.js +27 -0
- package/dist/src/daemon.test.d.ts +1 -0
- package/dist/src/daemon.test.js +60 -0
- package/dist/src/discovery.d.ts +46 -0
- package/dist/src/discovery.js +341 -0
- package/dist/src/doctor.d.ts +39 -0
- package/dist/src/doctor.js +168 -0
- package/dist/src/doctor.test.d.ts +1 -0
- package/dist/src/doctor.test.js +302 -0
- package/dist/src/download/article-download.d.ts +72 -0
- package/dist/src/download/article-download.js +305 -0
- package/dist/src/download/article-download.test.d.ts +1 -0
- package/dist/src/download/article-download.test.js +235 -0
- package/dist/src/download/index.d.ts +71 -0
- package/dist/src/download/index.js +363 -0
- package/dist/src/download/index.test.d.ts +1 -0
- package/dist/src/download/index.test.js +174 -0
- package/dist/src/download/media-download.d.ts +49 -0
- package/dist/src/download/media-download.js +127 -0
- package/dist/src/download/media-download.test.d.ts +1 -0
- package/dist/src/download/media-download.test.js +112 -0
- package/dist/src/download/progress.d.ts +36 -0
- package/dist/src/download/progress.js +120 -0
- package/dist/src/download/progress.test.d.ts +1 -0
- package/dist/src/download/progress.test.js +36 -0
- package/dist/src/electron-apps.d.ts +31 -0
- package/dist/src/electron-apps.js +91 -0
- package/dist/src/electron-apps.test.d.ts +1 -0
- package/dist/src/electron-apps.test.js +76 -0
- package/dist/src/engine.test.d.ts +1 -0
- package/dist/src/engine.test.js +312 -0
- package/dist/src/errors.d.ts +114 -0
- package/dist/src/errors.js +174 -0
- package/dist/src/errors.test.d.ts +1 -0
- package/dist/src/errors.test.js +109 -0
- package/dist/src/execution.d.ts +24 -0
- package/dist/src/execution.js +509 -0
- package/dist/src/execution.test.d.ts +1 -0
- package/dist/src/execution.test.js +645 -0
- package/dist/src/external.d.ts +49 -0
- package/dist/src/external.js +211 -0
- package/dist/src/external.test.d.ts +1 -0
- package/dist/src/external.test.js +110 -0
- package/dist/src/help.d.ts +88 -0
- package/dist/src/help.js +556 -0
- package/dist/src/help.test.d.ts +1 -0
- package/dist/src/help.test.js +58 -0
- package/dist/src/hooks.d.ts +46 -0
- package/dist/src/hooks.js +58 -0
- package/dist/src/hooks.test.d.ts +4 -0
- package/dist/src/hooks.test.js +92 -0
- package/dist/src/interceptor.d.ts +44 -0
- package/dist/src/interceptor.js +183 -0
- package/dist/src/interceptor.test.d.ts +4 -0
- package/dist/src/interceptor.test.js +81 -0
- package/dist/src/launcher.d.ts +41 -0
- package/dist/src/launcher.js +226 -0
- package/dist/src/launcher.test.d.ts +1 -0
- package/dist/src/launcher.test.js +153 -0
- package/dist/src/logger.d.ts +26 -0
- package/dist/src/logger.js +49 -0
- package/dist/src/main.d.ts +5 -0
- package/dist/src/main.js +177 -0
- package/dist/src/manifest-types.d.ts +43 -0
- package/dist/src/manifest-types.js +9 -0
- package/dist/src/node-network.d.ts +10 -0
- package/dist/src/node-network.js +174 -0
- package/dist/src/node-network.test.d.ts +1 -0
- package/dist/src/node-network.test.js +55 -0
- package/dist/src/observation/artifact.d.ts +16 -0
- package/dist/src/observation/artifact.js +260 -0
- package/dist/src/observation/artifact.test.d.ts +1 -0
- package/dist/src/observation/artifact.test.js +121 -0
- package/dist/src/observation/events.d.ts +89 -0
- package/dist/src/observation/events.js +1 -0
- package/dist/src/observation/index.d.ts +7 -0
- package/dist/src/observation/index.js +7 -0
- package/dist/src/observation/manager.d.ts +9 -0
- package/dist/src/observation/manager.js +27 -0
- package/dist/src/observation/manager.test.d.ts +1 -0
- package/dist/src/observation/manager.test.js +13 -0
- package/dist/src/observation/redaction.d.ts +11 -0
- package/dist/src/observation/redaction.js +81 -0
- package/dist/src/observation/redaction.test.d.ts +1 -0
- package/dist/src/observation/redaction.test.js +32 -0
- package/dist/src/observation/retention.d.ts +32 -0
- package/dist/src/observation/retention.js +160 -0
- package/dist/src/observation/retention.test.d.ts +1 -0
- package/dist/src/observation/retention.test.js +118 -0
- package/dist/src/observation/ring-buffer.d.ts +22 -0
- package/dist/src/observation/ring-buffer.js +45 -0
- package/dist/src/observation/ring-buffer.test.d.ts +1 -0
- package/dist/src/observation/ring-buffer.test.js +22 -0
- package/dist/src/observation/session.d.ts +25 -0
- package/dist/src/observation/session.js +50 -0
- package/dist/src/output.d.ts +14 -0
- package/dist/src/output.js +152 -0
- package/dist/src/output.test.d.ts +1 -0
- package/dist/src/output.test.js +53 -0
- package/dist/src/package-exports.test.d.ts +1 -0
- package/dist/src/package-exports.test.js +112 -0
- package/dist/src/package-paths.d.ts +8 -0
- package/dist/src/package-paths.js +41 -0
- package/dist/src/pipeline/executor.d.ts +11 -0
- package/dist/src/pipeline/executor.js +93 -0
- package/dist/src/pipeline/executor.test.d.ts +4 -0
- package/dist/src/pipeline/executor.test.js +182 -0
- package/dist/src/pipeline/index.d.ts +5 -0
- package/dist/src/pipeline/index.js +5 -0
- package/dist/src/pipeline/registry.d.ts +28 -0
- package/dist/src/pipeline/registry.js +55 -0
- package/dist/src/pipeline/steps/browser.d.ts +13 -0
- package/dist/src/pipeline/steps/browser.js +86 -0
- package/dist/src/pipeline/steps/download.d.ts +18 -0
- package/dist/src/pipeline/steps/download.js +252 -0
- package/dist/src/pipeline/steps/download.test.d.ts +1 -0
- package/dist/src/pipeline/steps/download.test.js +102 -0
- package/dist/src/pipeline/steps/fetch.d.ts +5 -0
- package/dist/src/pipeline/steps/fetch.js +122 -0
- package/dist/src/pipeline/steps/fetch.test.d.ts +1 -0
- package/dist/src/pipeline/steps/fetch.test.js +117 -0
- package/dist/src/pipeline/steps/intercept.d.ts +5 -0
- package/dist/src/pipeline/steps/intercept.js +50 -0
- package/dist/src/pipeline/steps/tap.d.ts +12 -0
- package/dist/src/pipeline/steps/tap.js +93 -0
- package/dist/src/pipeline/steps/transform.d.ts +9 -0
- package/dist/src/pipeline/steps/transform.js +70 -0
- package/dist/src/pipeline/template.d.ts +17 -0
- package/dist/src/pipeline/template.js +344 -0
- package/dist/src/pipeline/template.test.d.ts +4 -0
- package/dist/src/pipeline/template.test.js +197 -0
- package/dist/src/pipeline/transform.test.d.ts +4 -0
- package/dist/src/pipeline/transform.test.js +133 -0
- package/dist/src/plugin-manifest.d.ts +70 -0
- package/dist/src/plugin-manifest.js +160 -0
- package/dist/src/plugin-manifest.test.d.ts +4 -0
- package/dist/src/plugin-manifest.test.js +179 -0
- package/dist/src/plugin-scaffold.d.ts +28 -0
- package/dist/src/plugin-scaffold.js +143 -0
- package/dist/src/plugin-scaffold.test.d.ts +4 -0
- package/dist/src/plugin-scaffold.test.js +83 -0
- package/dist/src/plugin.d.ts +146 -0
- package/dist/src/plugin.js +1303 -0
- package/dist/src/plugin.test.d.ts +4 -0
- package/dist/src/plugin.test.js +1363 -0
- package/dist/src/registry-api.d.ts +13 -0
- package/dist/src/registry-api.js +10 -0
- package/dist/src/registry.d.ts +123 -0
- package/dist/src/registry.js +125 -0
- package/dist/src/registry.test.d.ts +4 -0
- package/dist/src/registry.test.js +209 -0
- package/dist/src/runtime-copy.test.d.ts +1 -0
- package/dist/src/runtime-copy.test.js +29 -0
- package/dist/src/runtime-detect.d.ts +31 -0
- package/dist/src/runtime-detect.js +47 -0
- package/dist/src/runtime-detect.test.d.ts +1 -0
- package/dist/src/runtime-detect.test.js +39 -0
- package/dist/src/runtime-identity.test.d.ts +1 -0
- package/dist/src/runtime-identity.test.js +18 -0
- package/dist/src/runtime.d.ts +47 -0
- package/dist/src/runtime.js +54 -0
- package/dist/src/scripts/framework.d.ts +7 -0
- package/dist/src/scripts/framework.js +25 -0
- package/dist/src/scripts/interact.d.ts +4 -0
- package/dist/src/scripts/interact.js +20 -0
- package/dist/src/scripts/store.d.ts +13 -0
- package/dist/src/scripts/store.js +48 -0
- package/dist/src/serialization.d.ts +42 -0
- package/dist/src/serialization.js +103 -0
- package/dist/src/serialization.test.d.ts +1 -0
- package/dist/src/serialization.test.js +78 -0
- package/dist/src/skills.d.ts +14 -0
- package/dist/src/skills.js +127 -0
- package/dist/src/skills.test.d.ts +1 -0
- package/dist/src/skills.test.js +71 -0
- package/dist/src/snapshotFormatter.d.ts +11 -0
- package/dist/src/snapshotFormatter.js +338 -0
- package/dist/src/snapshotFormatter.test.d.ts +7 -0
- package/dist/src/snapshotFormatter.test.js +521 -0
- package/dist/src/tui.d.ts +28 -0
- package/dist/src/tui.js +179 -0
- package/dist/src/tui.test.d.ts +1 -0
- package/dist/src/tui.test.js +19 -0
- package/dist/src/types.d.ts +236 -0
- package/dist/src/types.js +7 -0
- package/dist/src/update-check.d.ts +66 -0
- package/dist/src/update-check.js +206 -0
- package/dist/src/update-check.test.d.ts +1 -0
- package/dist/src/update-check.test.js +117 -0
- package/dist/src/utils.d.ts +57 -0
- package/dist/src/utils.js +152 -0
- package/dist/src/utils.test.d.ts +1 -0
- package/dist/src/utils.test.js +155 -0
- package/dist/src/validate.d.ts +21 -0
- package/dist/src/validate.js +130 -0
- package/dist/src/validate.test.d.ts +9 -0
- package/dist/src/validate.test.js +90 -0
- package/dist/src/verify.d.ts +26 -0
- package/dist/src/verify.js +67 -0
- package/dist/src/version.d.ts +4 -0
- package/dist/src/version.js +22 -0
- package/dist/src/weixin-download.test.d.ts +1 -0
- package/dist/src/weixin-download.test.js +45 -0
- package/package.json +4 -3
- package/scripts/check-package-bin.mjs +95 -0
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* argv preprocessing: rewrite `webcmd browser <session> <subcommand> ...`
|
|
3
|
+
* into `webcmd browser --session <session> <subcommand> ...` so commander
|
|
4
|
+
* (which can't combine a parent positional with subcommand dispatch) can parse it.
|
|
5
|
+
*
|
|
6
|
+
* The user-facing form is positional; the internal form uses --session. Help text
|
|
7
|
+
* for the `browser` command is overridden to advertise the positional form.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Browser subcommand names. If `<session>` would collide with one of these,
|
|
11
|
+
* we treat it as a missing-positional error and leave argv alone so commander
|
|
12
|
+
* reports a usable diagnostic.
|
|
13
|
+
*
|
|
14
|
+
* Keep in sync with the subcommands declared on the `browser` command in cli.ts.
|
|
15
|
+
*/
|
|
16
|
+
const BROWSER_SUBCOMMAND_NAMES = new Set([
|
|
17
|
+
'analyze',
|
|
18
|
+
'back',
|
|
19
|
+
'bind',
|
|
20
|
+
'check',
|
|
21
|
+
'click',
|
|
22
|
+
'close',
|
|
23
|
+
'console',
|
|
24
|
+
'dblclick',
|
|
25
|
+
'dialog',
|
|
26
|
+
'drag',
|
|
27
|
+
'eval',
|
|
28
|
+
'extract',
|
|
29
|
+
'fill',
|
|
30
|
+
'find',
|
|
31
|
+
'focus',
|
|
32
|
+
'frames',
|
|
33
|
+
'get',
|
|
34
|
+
'help',
|
|
35
|
+
'hover',
|
|
36
|
+
'init',
|
|
37
|
+
'keys',
|
|
38
|
+
'network',
|
|
39
|
+
'open',
|
|
40
|
+
'screenshot',
|
|
41
|
+
'scroll',
|
|
42
|
+
'select',
|
|
43
|
+
'state',
|
|
44
|
+
'tab',
|
|
45
|
+
'type',
|
|
46
|
+
'unbind',
|
|
47
|
+
'uncheck',
|
|
48
|
+
'upload',
|
|
49
|
+
'verify',
|
|
50
|
+
'wait',
|
|
51
|
+
]);
|
|
52
|
+
/**
|
|
53
|
+
* Root program options that consume the following token as their value. Used by
|
|
54
|
+
* the preprocessor to identify which token is the root command name (so e.g.
|
|
55
|
+
* `webcmd --profile work browser foo state` is recognised as the `browser`
|
|
56
|
+
* command with `<session>=foo`, not the value of --profile).
|
|
57
|
+
*
|
|
58
|
+
* Keep in sync with `program.option(...)` calls in cli.ts.
|
|
59
|
+
*/
|
|
60
|
+
const ROOT_VALUE_FLAGS = new Set(['--profile']);
|
|
61
|
+
/**
|
|
62
|
+
* Returns the set of reserved subcommand names (exposed for tests so they stay
|
|
63
|
+
* synced with the actual registrations in cli.ts).
|
|
64
|
+
*/
|
|
65
|
+
export function getBrowserSubcommandNames() {
|
|
66
|
+
return BROWSER_SUBCOMMAND_NAMES;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Rewrite `argv` to convert the positional `<session>` after `browser`
|
|
70
|
+
* into the internal `--session <name>` flag form.
|
|
71
|
+
*
|
|
72
|
+
* Only acts when `browser` is the root command (i.e. the first non-flag token
|
|
73
|
+
* after any leading root options), so it can't mis-interpret occurrences of
|
|
74
|
+
* the literal word `browser` deeper in the argv (e.g. `webcmd adapter init
|
|
75
|
+
* browser/x`, or a URL value containing `browser`).
|
|
76
|
+
*
|
|
77
|
+
* Leaves argv unchanged when:
|
|
78
|
+
* - root command is not `browser`
|
|
79
|
+
* - the token after `browser` is a flag (e.g. `--help`)
|
|
80
|
+
* - the token after `browser` is a known subcommand name (session was
|
|
81
|
+
* omitted; commander will surface its own required-flag error)
|
|
82
|
+
*/
|
|
83
|
+
export function rewriteBrowserArgv(argv) {
|
|
84
|
+
const result = [...argv];
|
|
85
|
+
// Walk past leading root flags + their values to find the root command token.
|
|
86
|
+
let i = 0;
|
|
87
|
+
while (i < result.length) {
|
|
88
|
+
const tok = result[i];
|
|
89
|
+
if (!tok.startsWith('-'))
|
|
90
|
+
break;
|
|
91
|
+
// `--flag=value` consumes one slot regardless of whether the flag expects a value.
|
|
92
|
+
if (tok.includes('=')) {
|
|
93
|
+
i += 1;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (ROOT_VALUE_FLAGS.has(tok) && i + 1 < result.length) {
|
|
97
|
+
i += 2;
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
i += 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (result[i] !== 'browser')
|
|
104
|
+
return result;
|
|
105
|
+
const sessionIdx = i + 1;
|
|
106
|
+
const next = result[sessionIdx];
|
|
107
|
+
if (next === undefined)
|
|
108
|
+
return result;
|
|
109
|
+
// The retired `--session` flag must not be a working public entrance.
|
|
110
|
+
if (next === '--session' || next === '--session=' || next.startsWith('--session=')) {
|
|
111
|
+
throw new BrowserSessionArgvError('The `--session` flag is no longer a public option. Use the positional form: webcmd browser <session> <command>');
|
|
112
|
+
}
|
|
113
|
+
if (next.startsWith('-'))
|
|
114
|
+
return result;
|
|
115
|
+
if (BROWSER_SUBCOMMAND_NAMES.has(next))
|
|
116
|
+
return result;
|
|
117
|
+
// Splice in --session <name> in place of the positional.
|
|
118
|
+
result.splice(sessionIdx, 1, '--session', next);
|
|
119
|
+
// `--window` is a browser namespace option, so commander accepts it before the
|
|
120
|
+
// leaf command. Users naturally put it at the end:
|
|
121
|
+
// `browser work open https://x.com --window background`. Hoist that public
|
|
122
|
+
// form into the namespace-option slot instead of mirroring the option onto
|
|
123
|
+
// every browser leaf command.
|
|
124
|
+
hoistBrowserWindowOption(result, sessionIdx + 2);
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Move one trailing `--window <mode>` / `--window=<mode>` from after the browser
|
|
129
|
+
* subcommand to just before it. Stops at `--` so literal browser arguments are
|
|
130
|
+
* untouched. Mutates `argv` in place.
|
|
131
|
+
*/
|
|
132
|
+
function hoistBrowserWindowOption(argv, fromIndex) {
|
|
133
|
+
const subcommandIdx = argv.findIndex((tok, idx) => idx >= fromIndex && BROWSER_SUBCOMMAND_NAMES.has(tok));
|
|
134
|
+
if (subcommandIdx === -1)
|
|
135
|
+
return;
|
|
136
|
+
for (let i = subcommandIdx + 1; i < argv.length; i += 1) {
|
|
137
|
+
const tok = argv[i];
|
|
138
|
+
if (tok === '--')
|
|
139
|
+
return;
|
|
140
|
+
if (tok.startsWith('--window=')) {
|
|
141
|
+
const removed = argv.splice(i, 1);
|
|
142
|
+
argv.splice(subcommandIdx, 0, ...removed);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
if (tok === '--window') {
|
|
146
|
+
const value = argv[i + 1];
|
|
147
|
+
if (value === undefined || value === '--')
|
|
148
|
+
return;
|
|
149
|
+
const removed = argv.splice(i, 2);
|
|
150
|
+
argv.splice(subcommandIdx, 0, ...removed);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Thrown by the preprocessor when user argv uses a retired/old form that we
|
|
157
|
+
* intentionally refuse to accept. main.ts catches this and exits with a
|
|
158
|
+
* usage error so it does not bubble up as an internal stacktrace.
|
|
159
|
+
*/
|
|
160
|
+
export class BrowserSessionArgvError extends Error {
|
|
161
|
+
constructor(message) {
|
|
162
|
+
super(message);
|
|
163
|
+
this.name = 'BrowserSessionArgvError';
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function knownCommandOptions(cmd) {
|
|
167
|
+
const options = new Map([
|
|
168
|
+
['-h', 'none'],
|
|
169
|
+
['--help', 'none'],
|
|
170
|
+
['-v', 'none'],
|
|
171
|
+
['--verbose', 'none'],
|
|
172
|
+
['-f', 'required'],
|
|
173
|
+
['--format', 'required'],
|
|
174
|
+
['--trace', 'required'],
|
|
175
|
+
]);
|
|
176
|
+
if (cmd.browser) {
|
|
177
|
+
options.set('--window', 'required');
|
|
178
|
+
options.set('--site-session', 'required');
|
|
179
|
+
options.set('--keep-tab', 'required');
|
|
180
|
+
}
|
|
181
|
+
for (const arg of cmd.args ?? []) {
|
|
182
|
+
if (arg.positional)
|
|
183
|
+
continue;
|
|
184
|
+
// Keep in sync with commanderAdapter.ts:
|
|
185
|
+
// required/valueRequired -> `<value>`; otherwise -> `[value]`.
|
|
186
|
+
options.set(`--${arg.name}`, arg.required || arg.valueRequired ? 'required' : 'optional');
|
|
187
|
+
}
|
|
188
|
+
return options;
|
|
189
|
+
}
|
|
190
|
+
function consumeKnownOption(argv, index, options) {
|
|
191
|
+
const token = argv[index];
|
|
192
|
+
if (!token || token === '--')
|
|
193
|
+
return null;
|
|
194
|
+
const eq = token.indexOf('=');
|
|
195
|
+
const key = eq === -1 ? token : token.slice(0, eq);
|
|
196
|
+
const mode = options.get(key);
|
|
197
|
+
if (!mode && eq === -1 && token.startsWith('-') && !token.startsWith('--') && token.length > 2) {
|
|
198
|
+
const shortKey = token.slice(0, 2);
|
|
199
|
+
const shortMode = options.get(shortKey);
|
|
200
|
+
if (shortMode === 'required') {
|
|
201
|
+
return { values: [token], nextIndex: index + 1 };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (!mode)
|
|
205
|
+
return null;
|
|
206
|
+
if (eq !== -1 || mode === 'none')
|
|
207
|
+
return { values: [token], nextIndex: index + 1 };
|
|
208
|
+
const next = argv[index + 1];
|
|
209
|
+
if (mode === 'required') {
|
|
210
|
+
return next === undefined
|
|
211
|
+
? { values: [token], nextIndex: index + 1 }
|
|
212
|
+
: { values: [token, next], nextIndex: index + 2 };
|
|
213
|
+
}
|
|
214
|
+
if (next !== undefined && !next.startsWith('-')) {
|
|
215
|
+
return { values: [token, next], nextIndex: index + 2 };
|
|
216
|
+
}
|
|
217
|
+
return { values: [token], nextIndex: index + 1 };
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* `webcmd boss detail -abc123def` fails because commander parses
|
|
221
|
+
* `-abc123def` as an unknown option rather than the required
|
|
222
|
+
* `<security-id>` positional. BOSS 直聘 securityId tokens are opaque
|
|
223
|
+
* strings that can legitimately start with `-` (issue #1160), and the
|
|
224
|
+
* same shape can show up in any adapter that takes an opaque-id
|
|
225
|
+
* positional. Insert a `--` separator so commander treats the next
|
|
226
|
+
* token as the positional value.
|
|
227
|
+
*/
|
|
228
|
+
export function escapeLeadingDashPositional(argv, manifest) {
|
|
229
|
+
const result = [...argv];
|
|
230
|
+
const requiredFirstPositional = new Map();
|
|
231
|
+
for (const cmd of manifest) {
|
|
232
|
+
const first = cmd.args?.find((a) => a.positional);
|
|
233
|
+
if (first?.required)
|
|
234
|
+
requiredFirstPositional.set(cmd.site + '/' + cmd.name, cmd);
|
|
235
|
+
}
|
|
236
|
+
let i = 0;
|
|
237
|
+
while (i < result.length) {
|
|
238
|
+
const tok = result[i];
|
|
239
|
+
if (!tok.startsWith('-'))
|
|
240
|
+
break;
|
|
241
|
+
if (tok.includes('=')) {
|
|
242
|
+
i += 1;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
if (ROOT_VALUE_FLAGS.has(tok) && i + 1 < result.length) {
|
|
246
|
+
i += 2;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
i += 1;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
const site = result[i];
|
|
253
|
+
const cmd = result[i + 1];
|
|
254
|
+
const positionalIdx = i + 2;
|
|
255
|
+
if (!site || !cmd || positionalIdx >= result.length)
|
|
256
|
+
return result;
|
|
257
|
+
const entry = requiredFirstPositional.get(site + '/' + cmd);
|
|
258
|
+
if (!entry)
|
|
259
|
+
return result;
|
|
260
|
+
const options = knownCommandOptions(entry);
|
|
261
|
+
const beforePositional = [];
|
|
262
|
+
let j = positionalIdx;
|
|
263
|
+
while (j < result.length) {
|
|
264
|
+
const token = result[j];
|
|
265
|
+
if (token === '--')
|
|
266
|
+
return result;
|
|
267
|
+
const consumed = consumeKnownOption(result, j, options);
|
|
268
|
+
if (consumed) {
|
|
269
|
+
beforePositional.push(...consumed.values);
|
|
270
|
+
j = consumed.nextIndex;
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
if (!token.startsWith('-'))
|
|
274
|
+
return result;
|
|
275
|
+
if (token.startsWith('--'))
|
|
276
|
+
return result;
|
|
277
|
+
break;
|
|
278
|
+
}
|
|
279
|
+
if (j >= result.length)
|
|
280
|
+
return result;
|
|
281
|
+
const positional = result[j];
|
|
282
|
+
const trailingOptions = [];
|
|
283
|
+
const trailingRest = [];
|
|
284
|
+
j += 1;
|
|
285
|
+
while (j < result.length) {
|
|
286
|
+
const consumed = consumeKnownOption(result, j, options);
|
|
287
|
+
if (consumed) {
|
|
288
|
+
trailingOptions.push(...consumed.values);
|
|
289
|
+
j = consumed.nextIndex;
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
trailingRest.push(result[j]);
|
|
293
|
+
j += 1;
|
|
294
|
+
}
|
|
295
|
+
return [
|
|
296
|
+
...result.slice(0, positionalIdx),
|
|
297
|
+
...beforePositional,
|
|
298
|
+
...trailingOptions,
|
|
299
|
+
'--',
|
|
300
|
+
positional,
|
|
301
|
+
...trailingRest,
|
|
302
|
+
];
|
|
303
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { getBrowserSubcommandNames, rewriteBrowserArgv } from './cli-argv-preprocess.js';
|
|
3
|
+
describe('rewriteBrowserArgv', () => {
|
|
4
|
+
it('rewrites `browser <session> <subcommand>` into `browser --session <name> <subcommand>`', () => {
|
|
5
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'state'])).toEqual([
|
|
6
|
+
'browser',
|
|
7
|
+
'--session',
|
|
8
|
+
'work',
|
|
9
|
+
'state',
|
|
10
|
+
]);
|
|
11
|
+
});
|
|
12
|
+
it('rewrites with subcommand arguments preserved', () => {
|
|
13
|
+
expect(rewriteBrowserArgv(['browser', 'mercury', 'open', 'https://x.com'])).toEqual([
|
|
14
|
+
'browser',
|
|
15
|
+
'--session',
|
|
16
|
+
'mercury',
|
|
17
|
+
'open',
|
|
18
|
+
'https://x.com',
|
|
19
|
+
]);
|
|
20
|
+
});
|
|
21
|
+
it('rewrites `browser <session> bind`', () => {
|
|
22
|
+
expect(rewriteBrowserArgv(['browser', 'mercury', 'bind'])).toEqual([
|
|
23
|
+
'browser',
|
|
24
|
+
'--session',
|
|
25
|
+
'mercury',
|
|
26
|
+
'bind',
|
|
27
|
+
]);
|
|
28
|
+
});
|
|
29
|
+
it('leaves argv alone when session omitted and a subcommand follows', () => {
|
|
30
|
+
// Commander surfaces the required-flag error itself.
|
|
31
|
+
expect(rewriteBrowserArgv(['browser', 'state'])).toEqual(['browser', 'state']);
|
|
32
|
+
expect(rewriteBrowserArgv(['browser', 'bind'])).toEqual(['browser', 'bind']);
|
|
33
|
+
});
|
|
34
|
+
it('leaves argv alone when the token after `browser` is a flag', () => {
|
|
35
|
+
expect(rewriteBrowserArgv(['browser', '--help'])).toEqual(['browser', '--help']);
|
|
36
|
+
expect(rewriteBrowserArgv(['browser', '-h'])).toEqual(['browser', '-h']);
|
|
37
|
+
});
|
|
38
|
+
it('refuses the retired `webcmd browser --session foo ...` user form', () => {
|
|
39
|
+
// The flag form is no longer a public entrance. Tests calling
|
|
40
|
+
// program.parseAsync directly bypass the preprocessor, so internal
|
|
41
|
+
// callers still work; but the user-facing pipeline throws.
|
|
42
|
+
expect(() => rewriteBrowserArgv(['browser', '--session', 'foo', 'state']))
|
|
43
|
+
.toThrowError(/no longer a public option/i);
|
|
44
|
+
expect(() => rewriteBrowserArgv(['browser', '--session=foo', 'state']))
|
|
45
|
+
.toThrowError(/no longer a public option/i);
|
|
46
|
+
});
|
|
47
|
+
it('leaves argv alone when `browser` is not present', () => {
|
|
48
|
+
expect(rewriteBrowserArgv(['twitter', 'tweets', '@elonmusk'])).toEqual([
|
|
49
|
+
'twitter',
|
|
50
|
+
'tweets',
|
|
51
|
+
'@elonmusk',
|
|
52
|
+
]);
|
|
53
|
+
expect(rewriteBrowserArgv(['doctor'])).toEqual(['doctor']);
|
|
54
|
+
});
|
|
55
|
+
it('returns argv unchanged when `browser` is the last token', () => {
|
|
56
|
+
expect(rewriteBrowserArgv(['browser'])).toEqual(['browser']);
|
|
57
|
+
});
|
|
58
|
+
it('only rewrites when `browser` is the root command, not deeper in argv', () => {
|
|
59
|
+
// `webcmd adapter init browser/x` — the literal `browser` is a path argument,
|
|
60
|
+
// not the root command. Must not be touched.
|
|
61
|
+
expect(rewriteBrowserArgv(['adapter', 'init', 'browser', 'x'])).toEqual([
|
|
62
|
+
'adapter',
|
|
63
|
+
'init',
|
|
64
|
+
'browser',
|
|
65
|
+
'x',
|
|
66
|
+
]);
|
|
67
|
+
// Same for URLs or arbitrary arg values that happen to contain `browser`.
|
|
68
|
+
expect(rewriteBrowserArgv(['twitter', 'tweets', 'https://browser.example.com'])).toEqual([
|
|
69
|
+
'twitter',
|
|
70
|
+
'tweets',
|
|
71
|
+
'https://browser.example.com',
|
|
72
|
+
]);
|
|
73
|
+
// First-match heuristic must NOT rewrite when an earlier non-flag token
|
|
74
|
+
// already established a different root command.
|
|
75
|
+
expect(rewriteBrowserArgv(['list', 'browser', 'state'])).toEqual([
|
|
76
|
+
'list',
|
|
77
|
+
'browser',
|
|
78
|
+
'state',
|
|
79
|
+
]);
|
|
80
|
+
});
|
|
81
|
+
it('skips leading root flags before identifying the root command', () => {
|
|
82
|
+
// `--profile` takes a value — the value is not the command.
|
|
83
|
+
expect(rewriteBrowserArgv(['--profile', 'work', 'browser', 'mercury', 'state'])).toEqual([
|
|
84
|
+
'--profile',
|
|
85
|
+
'work',
|
|
86
|
+
'browser',
|
|
87
|
+
'--session',
|
|
88
|
+
'mercury',
|
|
89
|
+
'state',
|
|
90
|
+
]);
|
|
91
|
+
// Long form with `=` separator consumes one slot only.
|
|
92
|
+
expect(rewriteBrowserArgv(['--profile=work', 'browser', 'mercury', 'state'])).toEqual([
|
|
93
|
+
'--profile=work',
|
|
94
|
+
'browser',
|
|
95
|
+
'--session',
|
|
96
|
+
'mercury',
|
|
97
|
+
'state',
|
|
98
|
+
]);
|
|
99
|
+
// Boolean flags don't consume values.
|
|
100
|
+
expect(rewriteBrowserArgv(['-v', 'browser', 'mercury', 'state'])).toEqual([
|
|
101
|
+
'-v',
|
|
102
|
+
'browser',
|
|
103
|
+
'--session',
|
|
104
|
+
'mercury',
|
|
105
|
+
'state',
|
|
106
|
+
]);
|
|
107
|
+
});
|
|
108
|
+
it('hoists a trailing browser --window option to the namespace slot', () => {
|
|
109
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'open', 'https://x.com', '--window', 'background'])).toEqual([
|
|
110
|
+
'browser',
|
|
111
|
+
'--session',
|
|
112
|
+
'work',
|
|
113
|
+
'--window',
|
|
114
|
+
'background',
|
|
115
|
+
'open',
|
|
116
|
+
'https://x.com',
|
|
117
|
+
]);
|
|
118
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'state', '--window', 'foreground'])).toEqual([
|
|
119
|
+
'browser',
|
|
120
|
+
'--session',
|
|
121
|
+
'work',
|
|
122
|
+
'--window',
|
|
123
|
+
'foreground',
|
|
124
|
+
'state',
|
|
125
|
+
]);
|
|
126
|
+
});
|
|
127
|
+
it('hoists trailing browser --window after leading root options', () => {
|
|
128
|
+
expect(rewriteBrowserArgv(['--profile', 'sandbox', 'browser', 'work', 'state', '--window', 'background'])).toEqual([
|
|
129
|
+
'--profile',
|
|
130
|
+
'sandbox',
|
|
131
|
+
'browser',
|
|
132
|
+
'--session',
|
|
133
|
+
'work',
|
|
134
|
+
'--window',
|
|
135
|
+
'background',
|
|
136
|
+
'state',
|
|
137
|
+
]);
|
|
138
|
+
});
|
|
139
|
+
it('hoists a trailing browser --window=<mode> option', () => {
|
|
140
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'open', 'https://x.com', '--window=background'])).toEqual([
|
|
141
|
+
'browser',
|
|
142
|
+
'--session',
|
|
143
|
+
'work',
|
|
144
|
+
'--window=background',
|
|
145
|
+
'open',
|
|
146
|
+
'https://x.com',
|
|
147
|
+
]);
|
|
148
|
+
});
|
|
149
|
+
it('hoists browser --window after nested browser leaf commands', () => {
|
|
150
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'get', 'url', '--window', 'background'])).toEqual([
|
|
151
|
+
'browser',
|
|
152
|
+
'--session',
|
|
153
|
+
'work',
|
|
154
|
+
'--window',
|
|
155
|
+
'background',
|
|
156
|
+
'get',
|
|
157
|
+
'url',
|
|
158
|
+
]);
|
|
159
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'tab', 'close', 'abc123', '--window', 'background'])).toEqual([
|
|
160
|
+
'browser',
|
|
161
|
+
'--session',
|
|
162
|
+
'work',
|
|
163
|
+
'--window',
|
|
164
|
+
'background',
|
|
165
|
+
'tab',
|
|
166
|
+
'close',
|
|
167
|
+
'abc123',
|
|
168
|
+
]);
|
|
169
|
+
});
|
|
170
|
+
it('leaves an already parent-slot browser --window option untouched', () => {
|
|
171
|
+
expect(rewriteBrowserArgv(['browser', 'work', '--window', 'background', 'open', 'https://x.com'])).toEqual([
|
|
172
|
+
'browser',
|
|
173
|
+
'--session',
|
|
174
|
+
'work',
|
|
175
|
+
'--window',
|
|
176
|
+
'background',
|
|
177
|
+
'open',
|
|
178
|
+
'https://x.com',
|
|
179
|
+
]);
|
|
180
|
+
});
|
|
181
|
+
it('does not hoist browser --window after a literal -- separator', () => {
|
|
182
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'eval', 'console.log(1)', '--', '--window', 'background'])).toEqual([
|
|
183
|
+
'browser',
|
|
184
|
+
'--session',
|
|
185
|
+
'work',
|
|
186
|
+
'eval',
|
|
187
|
+
'console.log(1)',
|
|
188
|
+
'--',
|
|
189
|
+
'--window',
|
|
190
|
+
'background',
|
|
191
|
+
]);
|
|
192
|
+
});
|
|
193
|
+
it('does not hoist a bare trailing browser --window without a value', () => {
|
|
194
|
+
expect(rewriteBrowserArgv(['browser', 'work', 'open', 'https://x.com', '--window'])).toEqual([
|
|
195
|
+
'browser',
|
|
196
|
+
'--session',
|
|
197
|
+
'work',
|
|
198
|
+
'open',
|
|
199
|
+
'https://x.com',
|
|
200
|
+
'--window',
|
|
201
|
+
]);
|
|
202
|
+
});
|
|
203
|
+
it('leaves argv alone when the root command is not `browser`, even if `browser` appears later', () => {
|
|
204
|
+
// The first browser keyword does NOT win — it must be at the root.
|
|
205
|
+
expect(rewriteBrowserArgv(['twitter', 'browser', 'work', 'state'])).toEqual([
|
|
206
|
+
'twitter',
|
|
207
|
+
'browser',
|
|
208
|
+
'work',
|
|
209
|
+
'state',
|
|
210
|
+
]);
|
|
211
|
+
});
|
|
212
|
+
it('reserved subcommand list covers every known browser subcommand registered in cli.ts', () => {
|
|
213
|
+
const names = getBrowserSubcommandNames();
|
|
214
|
+
const required = [
|
|
215
|
+
'analyze', 'back', 'bind', 'check', 'click', 'close', 'console', 'dblclick',
|
|
216
|
+
'dialog', 'drag', 'eval', 'extract', 'fill', 'find', 'focus', 'frames',
|
|
217
|
+
'get', 'hover', 'init', 'keys', 'network', 'open', 'screenshot', 'scroll',
|
|
218
|
+
'select', 'state', 'tab', 'type', 'unbind', 'uncheck', 'upload', 'verify',
|
|
219
|
+
'wait',
|
|
220
|
+
];
|
|
221
|
+
for (const name of required) {
|
|
222
|
+
expect(names.has(name)).toBe(true);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
});
|
|
226
|
+
import { escapeLeadingDashPositional } from './cli-argv-preprocess.js';
|
|
227
|
+
describe('escapeLeadingDashPositional', () => {
|
|
228
|
+
const manifest = [
|
|
229
|
+
{ site: 'boss', name: 'detail', browser: true, args: [{ name: 'security-id', positional: true, required: true }, { name: 'retry', positional: false, valueRequired: true }] },
|
|
230
|
+
{ site: 'boss', name: 'search', args: [{ name: 'query', positional: true, required: false }, { name: 'limit', positional: false }] },
|
|
231
|
+
{ site: 'twitter', name: 'follow', args: [{ name: 'username', positional: true, required: true }] },
|
|
232
|
+
{ site: 'twitter', name: 'lists', args: [{ name: 'limit', positional: false }] },
|
|
233
|
+
];
|
|
234
|
+
it('inserts -- before a required positional starting with `-`', () => {
|
|
235
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-abc123def'], manifest))
|
|
236
|
+
.toEqual(['boss', 'detail', '--', '-abc123def']);
|
|
237
|
+
});
|
|
238
|
+
it('preserves trailing flags after the dash-leading positional', () => {
|
|
239
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-xyz', '-f', 'json'], manifest))
|
|
240
|
+
.toEqual(['boss', 'detail', '-f', 'json', '--', '-xyz']);
|
|
241
|
+
});
|
|
242
|
+
it('preserves attached short option values like commander does', () => {
|
|
243
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-fjson', '-xyz'], manifest))
|
|
244
|
+
.toEqual(['boss', 'detail', '-fjson', '--', '-xyz']);
|
|
245
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-xyz', '-fjson'], manifest))
|
|
246
|
+
.toEqual(['boss', 'detail', '-fjson', '--', '-xyz']);
|
|
247
|
+
});
|
|
248
|
+
it('handles known options before a dash-leading positional', () => {
|
|
249
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '--format', 'json', '--trace=on', '-xyz'], manifest))
|
|
250
|
+
.toEqual(['boss', 'detail', '--format', 'json', '--trace=on', '--', '-xyz']);
|
|
251
|
+
});
|
|
252
|
+
it('keeps adapter and browser options parseable when they follow the positional', () => {
|
|
253
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-xyz', '--retry', '2', '--window', 'foreground'], manifest))
|
|
254
|
+
.toEqual(['boss', 'detail', '--retry', '2', '--window', 'foreground', '--', '-xyz']);
|
|
255
|
+
});
|
|
256
|
+
it('protects negative numeric positionals too', () => {
|
|
257
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-42'], manifest))
|
|
258
|
+
.toEqual(['boss', 'detail', '--', '-42']);
|
|
259
|
+
});
|
|
260
|
+
it('leaves unknown dash options untouched instead of hiding them behind --', () => {
|
|
261
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '--unknown', 'value'], manifest))
|
|
262
|
+
.toEqual(['boss', 'detail', '--unknown', 'value']);
|
|
263
|
+
});
|
|
264
|
+
it('does not touch positional values that do not start with -', () => {
|
|
265
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', 'normal-id'], manifest))
|
|
266
|
+
.toEqual(['boss', 'detail', 'normal-id']);
|
|
267
|
+
});
|
|
268
|
+
it('does not touch the recognised short flags -f / -v / -h', () => {
|
|
269
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-f', 'json'], manifest))
|
|
270
|
+
.toEqual(['boss', 'detail', '-f', 'json']);
|
|
271
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '-v'], manifest))
|
|
272
|
+
.toEqual(['boss', 'detail', '-v']);
|
|
273
|
+
});
|
|
274
|
+
it('does not touch long flags (--*)', () => {
|
|
275
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '--format', 'json'], manifest))
|
|
276
|
+
.toEqual(['boss', 'detail', '--format', 'json']);
|
|
277
|
+
});
|
|
278
|
+
it('does not touch already-escaped --', () => {
|
|
279
|
+
expect(escapeLeadingDashPositional(['boss', 'detail', '--', '-already-escaped'], manifest))
|
|
280
|
+
.toEqual(['boss', 'detail', '--', '-already-escaped']);
|
|
281
|
+
});
|
|
282
|
+
it('does not touch commands without a required positional', () => {
|
|
283
|
+
expect(escapeLeadingDashPositional(['boss', 'search', '-something'], manifest))
|
|
284
|
+
.toEqual(['boss', 'search', '-something']);
|
|
285
|
+
expect(escapeLeadingDashPositional(['twitter', 'lists', '-something'], manifest))
|
|
286
|
+
.toEqual(['twitter', 'lists', '-something']);
|
|
287
|
+
});
|
|
288
|
+
it('works when --profile or another root flag precedes the site', () => {
|
|
289
|
+
expect(escapeLeadingDashPositional(['--profile', 'work', 'boss', 'detail', '-abc'], manifest))
|
|
290
|
+
.toEqual(['--profile', 'work', 'boss', 'detail', '--', '-abc']);
|
|
291
|
+
});
|
|
292
|
+
it('works for any adapter, not just boss', () => {
|
|
293
|
+
expect(escapeLeadingDashPositional(['twitter', 'follow', '-someuser'], manifest))
|
|
294
|
+
.toEqual(['twitter', 'follow', '--', '-someuser']);
|
|
295
|
+
});
|
|
296
|
+
it('returns argv unchanged when the command is unknown', () => {
|
|
297
|
+
expect(escapeLeadingDashPositional(['unknown', 'cmd', '-arg'], manifest))
|
|
298
|
+
.toEqual(['unknown', 'cmd', '-arg']);
|
|
299
|
+
});
|
|
300
|
+
it('returns argv unchanged when argv is too short', () => {
|
|
301
|
+
expect(escapeLeadingDashPositional(['boss'], manifest)).toEqual(['boss']);
|
|
302
|
+
expect(escapeLeadingDashPositional(['boss', 'detail'], manifest)).toEqual(['boss', 'detail']);
|
|
303
|
+
});
|
|
304
|
+
});
|