@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,103 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Build-time CLI manifest compiler.
|
|
4
|
+
*
|
|
5
|
+
* Scans all JS CLI definitions in clis/ and pre-compiles them into a single
|
|
6
|
+
* manifest.json for instant cold-start registration.
|
|
7
|
+
*
|
|
8
|
+
* Usage: npx tsx src/build-manifest.ts [--allow-removals[=N]]
|
|
9
|
+
*
|
|
10
|
+
* Output: cli-manifest.json next to clis/
|
|
11
|
+
*
|
|
12
|
+
* Safety invariants:
|
|
13
|
+
* - Adapters whose source file does not call `cli(...)` are silently
|
|
14
|
+
* skipped (they are helpers / type modules, not commands).
|
|
15
|
+
* - Adapters that look like commands but fail to import are reported as
|
|
16
|
+
* failures, the manifest is NOT written, and the process exits 1. This
|
|
17
|
+
* prevents a stale dist or a broken adapter from silently dropping
|
|
18
|
+
* other adapters' entries (root cause of the "manifest lost 478 lines"
|
|
19
|
+
* incident).
|
|
20
|
+
* - Net-deletions vs the existing committed manifest abort the build by
|
|
21
|
+
* default; pass `--allow-removals=N` (or just `--allow-removals` for any
|
|
22
|
+
* amount) to confirm an intentional removal.
|
|
23
|
+
*/
|
|
24
|
+
import type { ManifestEntry } from './manifest-types.js';
|
|
25
|
+
export type { ManifestEntry } from './manifest-types.js';
|
|
26
|
+
/**
|
|
27
|
+
* Thrown by `loadManifestEntries` when an adapter file looks like a CLI
|
|
28
|
+
* module (matches CLI_MODULE_PATTERN) but cannot be imported. Callers
|
|
29
|
+
* decide whether to abort or aggregate failures across the whole scan.
|
|
30
|
+
*/
|
|
31
|
+
export declare class ManifestImportError extends Error {
|
|
32
|
+
readonly filePath: string;
|
|
33
|
+
readonly cause: unknown;
|
|
34
|
+
constructor(filePath: string, cause: unknown);
|
|
35
|
+
}
|
|
36
|
+
export interface BuildManifestResult {
|
|
37
|
+
entries: ManifestEntry[];
|
|
38
|
+
/** Adapters that look like CLI modules but failed to import. */
|
|
39
|
+
failures: ManifestImportError[];
|
|
40
|
+
}
|
|
41
|
+
export interface BuildManifestArgs {
|
|
42
|
+
/** Maximum number of entries that may be removed vs the existing manifest.
|
|
43
|
+
* `Number.POSITIVE_INFINITY` disables the safety net entirely. */
|
|
44
|
+
allowRemovals: number;
|
|
45
|
+
}
|
|
46
|
+
export declare function normalizeManifestPath(relativePath: string): string;
|
|
47
|
+
/**
|
|
48
|
+
* Load all manifest entries from a single adapter file.
|
|
49
|
+
*
|
|
50
|
+
* Returns `[]` for files that do not register a CLI command (helpers, types).
|
|
51
|
+
* Throws `ManifestImportError` when a file looks like a CLI module but its
|
|
52
|
+
* import or post-import processing fails — callers must decide whether to
|
|
53
|
+
* surface or aggregate the failure.
|
|
54
|
+
*
|
|
55
|
+
* The third argument `clisDir` is used to compute the POSIX-style
|
|
56
|
+
* `sourceFile` relative path; it defaults to the package's `clis/` dir so
|
|
57
|
+
* existing test callers stay backward-compatible.
|
|
58
|
+
*/
|
|
59
|
+
export declare function loadManifestEntries(filePath: string, site: string, importer?: (moduleHref: string) => Promise<unknown>, clisDir?: string): Promise<ManifestEntry[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Scan a `clis/` directory and aggregate per-adapter results. Import
|
|
62
|
+
* failures are collected in `failures` instead of crashing the whole scan,
|
|
63
|
+
* but the caller (e.g. `main()`) is expected to fail loud if any failure
|
|
64
|
+
* is present.
|
|
65
|
+
*/
|
|
66
|
+
export declare function scanClisDir(clisDir: string, importer?: (moduleHref: string) => Promise<unknown>): Promise<BuildManifestResult>;
|
|
67
|
+
export declare function buildManifest(): Promise<BuildManifestResult>;
|
|
68
|
+
export declare function serializeManifest(manifest: ManifestEntry[]): string;
|
|
69
|
+
/**
|
|
70
|
+
* Metadata audit: every positional arg must carry a non-empty `help` string.
|
|
71
|
+
*
|
|
72
|
+
* Why this is a hard gate (not advisory):
|
|
73
|
+
* - `webcmd twitter followers --help` rendered `Arguments:\n user ` with
|
|
74
|
+
* an empty trailing column. Agents and humans both saw a blank field —
|
|
75
|
+
* impossible to recover the parameter's purpose without reading source.
|
|
76
|
+
* - This is metadata completeness, not stylistic taste; failing closed is
|
|
77
|
+
* the only way to keep the help surface trustworthy as adapters land.
|
|
78
|
+
*
|
|
79
|
+
* Note: semantic quality (e.g. "what does the optional positional mean when
|
|
80
|
+
* omitted?") is intentionally NOT enforced here. That belongs to a follow-up
|
|
81
|
+
* advisory audit — see PR plan `Arg metadata v2` for the structured
|
|
82
|
+
* `when_omitted / when_present / value_format` schema.
|
|
83
|
+
*/
|
|
84
|
+
export interface ManifestMetadataIssue {
|
|
85
|
+
site: string;
|
|
86
|
+
command: string;
|
|
87
|
+
arg: string;
|
|
88
|
+
sourceFile?: string;
|
|
89
|
+
reason: string;
|
|
90
|
+
}
|
|
91
|
+
export declare function findManifestMetadataIssues(entries: readonly ManifestEntry[]): ManifestMetadataIssue[];
|
|
92
|
+
/**
|
|
93
|
+
* Diff helper: returns site/name keys that exist in `prev` but not in
|
|
94
|
+
* `next`. Used as a safety net to detect accidental mass-deletions caused
|
|
95
|
+
* by silently failing adapter imports.
|
|
96
|
+
*/
|
|
97
|
+
export declare function diffRemovedEntries(prev: readonly ManifestEntry[], next: readonly ManifestEntry[]): string[];
|
|
98
|
+
/**
|
|
99
|
+
* Parse `--allow-removals` and `--allow-removals=N` from argv.
|
|
100
|
+
* Bare `--allow-removals` disables the safety net (`Infinity`); the
|
|
101
|
+
* numeric form sets an explicit upper bound.
|
|
102
|
+
*/
|
|
103
|
+
export declare function parseBuildManifestArgs(argv: readonly string[]): BuildManifestArgs;
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Build-time CLI manifest compiler.
|
|
4
|
+
*
|
|
5
|
+
* Scans all JS CLI definitions in clis/ and pre-compiles them into a single
|
|
6
|
+
* manifest.json for instant cold-start registration.
|
|
7
|
+
*
|
|
8
|
+
* Usage: npx tsx src/build-manifest.ts [--allow-removals[=N]]
|
|
9
|
+
*
|
|
10
|
+
* Output: cli-manifest.json next to clis/
|
|
11
|
+
*
|
|
12
|
+
* Safety invariants:
|
|
13
|
+
* - Adapters whose source file does not call `cli(...)` are silently
|
|
14
|
+
* skipped (they are helpers / type modules, not commands).
|
|
15
|
+
* - Adapters that look like commands but fail to import are reported as
|
|
16
|
+
* failures, the manifest is NOT written, and the process exits 1. This
|
|
17
|
+
* prevents a stale dist or a broken adapter from silently dropping
|
|
18
|
+
* other adapters' entries (root cause of the "manifest lost 478 lines"
|
|
19
|
+
* incident).
|
|
20
|
+
* - Net-deletions vs the existing committed manifest abort the build by
|
|
21
|
+
* default; pass `--allow-removals=N` (or just `--allow-removals` for any
|
|
22
|
+
* amount) to confirm an intentional removal.
|
|
23
|
+
*/
|
|
24
|
+
import * as fs from 'node:fs';
|
|
25
|
+
import * as path from 'node:path';
|
|
26
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
27
|
+
import { getErrorMessage } from './errors.js';
|
|
28
|
+
import { fullName, getRegistry } from './registry.js';
|
|
29
|
+
import { findPackageRoot, getCliManifestPath } from './package-paths.js';
|
|
30
|
+
import { isRecord } from './utils.js';
|
|
31
|
+
const PACKAGE_ROOT = findPackageRoot(fileURLToPath(import.meta.url));
|
|
32
|
+
const CLIS_DIR = path.join(PACKAGE_ROOT, 'clis');
|
|
33
|
+
// Write manifest next to clis/ so both dev and installed runtime can find it.
|
|
34
|
+
const OUTPUT = getCliManifestPath(CLIS_DIR);
|
|
35
|
+
// Module is treated as a CLI command source if it either:
|
|
36
|
+
// 1. Calls `cli(...)` directly (the common case), or
|
|
37
|
+
// 2. Calls a factory `make<Pascal>Command(...)` from clis/_shared/ that
|
|
38
|
+
// wraps `cli(...)`. Without (2), shared-factory adapters
|
|
39
|
+
// (codex/cursor/chatwise new/status/dump/screenshot) match no `cli(`
|
|
40
|
+
// token at the top level and silently drop out of the manifest.
|
|
41
|
+
const CLI_MODULE_PATTERN = /\bcli\s*\(|\bregisterSiteAuthCommands\s*\(|\bmake[A-Z]\w*Command\s*\(/;
|
|
42
|
+
/**
|
|
43
|
+
* Thrown by `loadManifestEntries` when an adapter file looks like a CLI
|
|
44
|
+
* module (matches CLI_MODULE_PATTERN) but cannot be imported. Callers
|
|
45
|
+
* decide whether to abort or aggregate failures across the whole scan.
|
|
46
|
+
*/
|
|
47
|
+
export class ManifestImportError extends Error {
|
|
48
|
+
filePath;
|
|
49
|
+
cause;
|
|
50
|
+
constructor(filePath, cause) {
|
|
51
|
+
super(`failed to scan ${filePath}: ${getErrorMessage(cause)}`);
|
|
52
|
+
this.filePath = filePath;
|
|
53
|
+
this.cause = cause;
|
|
54
|
+
this.name = 'ManifestImportError';
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function toManifestArgs(args) {
|
|
58
|
+
return args.map(arg => ({
|
|
59
|
+
name: arg.name,
|
|
60
|
+
type: arg.type ?? 'str',
|
|
61
|
+
default: arg.default,
|
|
62
|
+
required: !!arg.required,
|
|
63
|
+
valueRequired: !!arg.valueRequired || undefined,
|
|
64
|
+
positional: arg.positional || undefined,
|
|
65
|
+
help: arg.help ?? '',
|
|
66
|
+
choices: arg.choices,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
function toModulePath(filePath, site) {
|
|
70
|
+
const baseName = path.basename(filePath, path.extname(filePath));
|
|
71
|
+
return `${site}/${baseName}.js`;
|
|
72
|
+
}
|
|
73
|
+
export function normalizeManifestPath(relativePath) {
|
|
74
|
+
return relativePath.replace(/\\/g, '/');
|
|
75
|
+
}
|
|
76
|
+
function toManifestRelativePath(filePath, clisDir) {
|
|
77
|
+
return normalizeManifestPath(path.relative(clisDir, filePath));
|
|
78
|
+
}
|
|
79
|
+
function isCliCommandValue(value, site) {
|
|
80
|
+
return isRecord(value)
|
|
81
|
+
&& typeof value.site === 'string'
|
|
82
|
+
&& value.site === site
|
|
83
|
+
&& typeof value.name === 'string'
|
|
84
|
+
&& (value.access === 'read' || value.access === 'write')
|
|
85
|
+
&& Array.isArray(value.args);
|
|
86
|
+
}
|
|
87
|
+
function toManifestEntry(cmd, modulePath, sourceFile) {
|
|
88
|
+
return {
|
|
89
|
+
site: cmd.site,
|
|
90
|
+
name: cmd.name,
|
|
91
|
+
aliases: cmd.aliases,
|
|
92
|
+
description: cmd.description ?? '',
|
|
93
|
+
access: cmd.access,
|
|
94
|
+
example: cmd.example,
|
|
95
|
+
domain: cmd.domain,
|
|
96
|
+
strategy: (cmd.strategy ?? 'public').toString().toLowerCase(),
|
|
97
|
+
browser: cmd.browser ?? true,
|
|
98
|
+
args: toManifestArgs(cmd.args),
|
|
99
|
+
columns: cmd.columns,
|
|
100
|
+
defaultFormat: cmd.defaultFormat,
|
|
101
|
+
type: 'js',
|
|
102
|
+
modulePath,
|
|
103
|
+
sourceFile,
|
|
104
|
+
navigateBefore: cmd.navigateBefore,
|
|
105
|
+
siteSession: cmd.siteSession,
|
|
106
|
+
defaultWindowMode: cmd.defaultWindowMode,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Load all manifest entries from a single adapter file.
|
|
111
|
+
*
|
|
112
|
+
* Returns `[]` for files that do not register a CLI command (helpers, types).
|
|
113
|
+
* Throws `ManifestImportError` when a file looks like a CLI module but its
|
|
114
|
+
* import or post-import processing fails — callers must decide whether to
|
|
115
|
+
* surface or aggregate the failure.
|
|
116
|
+
*
|
|
117
|
+
* The third argument `clisDir` is used to compute the POSIX-style
|
|
118
|
+
* `sourceFile` relative path; it defaults to the package's `clis/` dir so
|
|
119
|
+
* existing test callers stay backward-compatible.
|
|
120
|
+
*/
|
|
121
|
+
export async function loadManifestEntries(filePath, site, importer = moduleHref => import(moduleHref), clisDir = CLIS_DIR) {
|
|
122
|
+
let src;
|
|
123
|
+
try {
|
|
124
|
+
src = fs.readFileSync(filePath, 'utf-8');
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
throw new ManifestImportError(filePath, err);
|
|
128
|
+
}
|
|
129
|
+
// Helper / test modules that do not call cli() are not commands.
|
|
130
|
+
if (!CLI_MODULE_PATTERN.test(src))
|
|
131
|
+
return [];
|
|
132
|
+
try {
|
|
133
|
+
const modulePath = toModulePath(filePath, site);
|
|
134
|
+
const registry = getRegistry();
|
|
135
|
+
const before = new Map(registry.entries());
|
|
136
|
+
const mod = await importer(pathToFileURL(filePath).href);
|
|
137
|
+
const exportedCommands = Object.values(isRecord(mod) ? mod : {})
|
|
138
|
+
.filter(value => isCliCommandValue(value, site));
|
|
139
|
+
const runtimeCommands = exportedCommands.length > 0
|
|
140
|
+
? exportedCommands
|
|
141
|
+
: [...registry.entries()]
|
|
142
|
+
.filter(([key, cmd]) => {
|
|
143
|
+
if (cmd.site !== site)
|
|
144
|
+
return false;
|
|
145
|
+
const previous = before.get(key);
|
|
146
|
+
return !previous || previous !== cmd;
|
|
147
|
+
})
|
|
148
|
+
.map(([, cmd]) => cmd);
|
|
149
|
+
// Manifest paths are cross-platform artifacts; keep them POSIX-style even
|
|
150
|
+
// when build-manifest runs on Windows.
|
|
151
|
+
const sourceRelative = toManifestRelativePath(filePath, clisDir);
|
|
152
|
+
const seen = new Set();
|
|
153
|
+
return runtimeCommands
|
|
154
|
+
.filter((cmd) => {
|
|
155
|
+
const key = fullName(cmd);
|
|
156
|
+
if (seen.has(key))
|
|
157
|
+
return false;
|
|
158
|
+
seen.add(key);
|
|
159
|
+
return true;
|
|
160
|
+
})
|
|
161
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
162
|
+
.map(cmd => toManifestEntry(cmd, modulePath, sourceRelative));
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
throw new ManifestImportError(filePath, err);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Scan a `clis/` directory and aggregate per-adapter results. Import
|
|
170
|
+
* failures are collected in `failures` instead of crashing the whole scan,
|
|
171
|
+
* but the caller (e.g. `main()`) is expected to fail loud if any failure
|
|
172
|
+
* is present.
|
|
173
|
+
*/
|
|
174
|
+
export async function scanClisDir(clisDir, importer = moduleHref => import(moduleHref)) {
|
|
175
|
+
const manifest = new Map();
|
|
176
|
+
const failures = [];
|
|
177
|
+
if (!fs.existsSync(clisDir)) {
|
|
178
|
+
return { entries: [], failures };
|
|
179
|
+
}
|
|
180
|
+
for (const site of fs.readdirSync(clisDir)) {
|
|
181
|
+
const siteDir = path.join(clisDir, site);
|
|
182
|
+
if (!fs.statSync(siteDir).isDirectory())
|
|
183
|
+
continue;
|
|
184
|
+
for (const file of fs.readdirSync(siteDir)) {
|
|
185
|
+
if (file.endsWith('.js') && !file.endsWith('.d.js') && !file.endsWith('.test.js') && file !== 'index.js') {
|
|
186
|
+
const filePath = path.join(siteDir, file);
|
|
187
|
+
try {
|
|
188
|
+
const entries = await loadManifestEntries(filePath, site, importer, clisDir);
|
|
189
|
+
for (const entry of entries) {
|
|
190
|
+
const key = `${entry.site}/${entry.name}`;
|
|
191
|
+
manifest.set(key, entry);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
if (err instanceof ManifestImportError) {
|
|
196
|
+
failures.push(err);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
throw err;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const entries = [...manifest.values()].sort((a, b) => a.site.localeCompare(b.site) || a.name.localeCompare(b.name));
|
|
205
|
+
return { entries, failures };
|
|
206
|
+
}
|
|
207
|
+
export async function buildManifest() {
|
|
208
|
+
return scanClisDir(CLIS_DIR);
|
|
209
|
+
}
|
|
210
|
+
export function serializeManifest(manifest) {
|
|
211
|
+
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
212
|
+
}
|
|
213
|
+
export function findManifestMetadataIssues(entries) {
|
|
214
|
+
const issues = [];
|
|
215
|
+
for (const entry of entries) {
|
|
216
|
+
if (!Array.isArray(entry.args))
|
|
217
|
+
continue;
|
|
218
|
+
for (const arg of entry.args) {
|
|
219
|
+
if (!arg.positional)
|
|
220
|
+
continue;
|
|
221
|
+
const help = typeof arg.help === 'string' ? arg.help.trim() : '';
|
|
222
|
+
if (help === '') {
|
|
223
|
+
issues.push({
|
|
224
|
+
site: entry.site,
|
|
225
|
+
command: entry.name,
|
|
226
|
+
arg: arg.name,
|
|
227
|
+
sourceFile: entry.sourceFile,
|
|
228
|
+
reason: 'positional arg missing non-empty `help` text',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return issues;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Diff helper: returns site/name keys that exist in `prev` but not in
|
|
237
|
+
* `next`. Used as a safety net to detect accidental mass-deletions caused
|
|
238
|
+
* by silently failing adapter imports.
|
|
239
|
+
*/
|
|
240
|
+
export function diffRemovedEntries(prev, next) {
|
|
241
|
+
const nextKeys = new Set(next.map(e => `${e.site}/${e.name}`));
|
|
242
|
+
return prev
|
|
243
|
+
.map(e => `${e.site}/${e.name}`)
|
|
244
|
+
.filter(key => !nextKeys.has(key))
|
|
245
|
+
.sort();
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Parse `--allow-removals` and `--allow-removals=N` from argv.
|
|
249
|
+
* Bare `--allow-removals` disables the safety net (`Infinity`); the
|
|
250
|
+
* numeric form sets an explicit upper bound.
|
|
251
|
+
*/
|
|
252
|
+
export function parseBuildManifestArgs(argv) {
|
|
253
|
+
let allowRemovals = 0;
|
|
254
|
+
for (const arg of argv) {
|
|
255
|
+
if (arg === '--allow-removals') {
|
|
256
|
+
allowRemovals = Number.POSITIVE_INFINITY;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
const m = arg.match(/^--allow-removals=(\d+)$/);
|
|
260
|
+
if (m) {
|
|
261
|
+
allowRemovals = Number.parseInt(m[1], 10);
|
|
262
|
+
continue;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return { allowRemovals };
|
|
266
|
+
}
|
|
267
|
+
function readExistingManifest(filePath) {
|
|
268
|
+
try {
|
|
269
|
+
if (!fs.existsSync(filePath))
|
|
270
|
+
return null;
|
|
271
|
+
const raw = fs.readFileSync(filePath, 'utf-8');
|
|
272
|
+
const parsed = JSON.parse(raw);
|
|
273
|
+
return Array.isArray(parsed) ? parsed : null;
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
return null;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
async function main() {
|
|
280
|
+
// Runtime guard: refuse to run from dist/. tsc transitively emits this
|
|
281
|
+
// file (the test file imports from it) so dist/src/build-manifest.js
|
|
282
|
+
// physically exists. If a developer or agent runs that compiled copy,
|
|
283
|
+
// any stale dist will silently break adapter imports — the exact failure
|
|
284
|
+
// mode this script is meant to prevent. Direct them at the tsx entry
|
|
285
|
+
// before they can shoot themselves in the foot.
|
|
286
|
+
if (fileURLToPath(import.meta.url).includes(`${path.sep}dist${path.sep}`)) {
|
|
287
|
+
process.stderr.write(`❌ Refusing to run build-manifest from dist/.\n`
|
|
288
|
+
+ ` Stale compiled output silently drops adapters that import renamed/removed exports.\n`
|
|
289
|
+
+ ` Run \`npm run build-manifest\` (or \`tsx src/build-manifest.ts\`) from the source tree instead.\n`);
|
|
290
|
+
process.exit(1);
|
|
291
|
+
}
|
|
292
|
+
const args = parseBuildManifestArgs(process.argv.slice(2));
|
|
293
|
+
const { entries, failures } = await buildManifest();
|
|
294
|
+
if (failures.length > 0) {
|
|
295
|
+
process.stderr.write(`❌ ${failures.length} adapter(s) failed to load:\n`);
|
|
296
|
+
for (const failure of failures) {
|
|
297
|
+
const rel = path.relative(PACKAGE_ROOT, failure.filePath) || failure.filePath;
|
|
298
|
+
process.stderr.write(` - ${rel}: ${getErrorMessage(failure.cause)}\n`);
|
|
299
|
+
}
|
|
300
|
+
process.stderr.write(`\nManifest NOT written. Likely cause: stale dist/ or a broken adapter import.\n`
|
|
301
|
+
+ `Always run via tsx (\`npm run build-manifest\`), not against compiled dist/.\n`);
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
const metadataIssues = findManifestMetadataIssues(entries);
|
|
305
|
+
if (metadataIssues.length > 0) {
|
|
306
|
+
process.stderr.write(`❌ ${metadataIssues.length} positional arg(s) missing \`help\` text:\n`);
|
|
307
|
+
for (const issue of metadataIssues) {
|
|
308
|
+
const where = issue.sourceFile ? ` (${issue.sourceFile})` : '';
|
|
309
|
+
process.stderr.write(` - ${issue.site}/${issue.command} positional "${issue.arg}"${where}\n`);
|
|
310
|
+
}
|
|
311
|
+
process.stderr.write(`\nEvery positional arg must declare a non-empty \`help\` string so\n`
|
|
312
|
+
+ `\`webcmd <site> <cmd> --help\` shows callers what the parameter is for.\n`
|
|
313
|
+
+ `Add \`help: '...'\` to each arg above and re-run the build.\n`);
|
|
314
|
+
process.exit(1);
|
|
315
|
+
}
|
|
316
|
+
const existing = readExistingManifest(OUTPUT);
|
|
317
|
+
if (existing) {
|
|
318
|
+
const removed = diffRemovedEntries(existing, entries);
|
|
319
|
+
if (removed.length > args.allowRemovals) {
|
|
320
|
+
process.stderr.write(`❌ ${removed.length} manifest entries would be removed; refusing to overwrite.\n`);
|
|
321
|
+
const preview = removed.slice(0, 20);
|
|
322
|
+
for (const key of preview)
|
|
323
|
+
process.stderr.write(` - ${key}\n`);
|
|
324
|
+
if (removed.length > preview.length) {
|
|
325
|
+
process.stderr.write(` ... ${removed.length - preview.length} more\n`);
|
|
326
|
+
}
|
|
327
|
+
process.stderr.write(`\nIf this removal is intentional, rerun with `
|
|
328
|
+
+ `\`--allow-removals=${removed.length}\` (or \`--allow-removals\` to disable the check).\n`);
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
fs.mkdirSync(path.dirname(OUTPUT), { recursive: true });
|
|
333
|
+
fs.writeFileSync(OUTPUT, serializeManifest(entries));
|
|
334
|
+
console.log(`✅ Manifest compiled: ${entries.length} entries → ${OUTPUT}`);
|
|
335
|
+
// Restore executable permissions on bin entries.
|
|
336
|
+
// tsc does not preserve the +x bit, so after a clean rebuild the CLI
|
|
337
|
+
// entry-point loses its executable permission, causing "Permission denied".
|
|
338
|
+
// See: https://github.com/agentrhq/webcmd/issues/446
|
|
339
|
+
if (process.platform !== 'win32') {
|
|
340
|
+
const projectRoot = PACKAGE_ROOT;
|
|
341
|
+
const pkgPath = path.resolve(projectRoot, 'package.json');
|
|
342
|
+
try {
|
|
343
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
344
|
+
const bins = typeof pkg.bin === 'string'
|
|
345
|
+
? { [pkg.name ?? 'cli']: pkg.bin }
|
|
346
|
+
: pkg.bin ?? {};
|
|
347
|
+
for (const binPath of Object.values(bins)) {
|
|
348
|
+
const abs = path.resolve(projectRoot, binPath);
|
|
349
|
+
if (fs.existsSync(abs)) {
|
|
350
|
+
fs.chmodSync(abs, 0o755);
|
|
351
|
+
console.log(`✅ Restored executable permission: ${binPath}`);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
// Best-effort; never break the build for a permission fix.
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
const entrypoint = process.argv[1] ? pathToFileURL(path.resolve(process.argv[1])).href : null;
|
|
361
|
+
if (entrypoint === import.meta.url) {
|
|
362
|
+
void main();
|
|
363
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|