@lesliechan721/aw 0.1.0-beta.3 → 0.1.0-beta.30
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/dist/authoring/assets/aw-config.mjs +100 -501
- package/dist/authoring/assets/aw-config.mjs.map +1 -1
- package/dist/authoring/scripts/add-skill.mjs +4 -4
- package/dist/authoring/scripts/add-skill.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +67 -97
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.d.mts +15 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +239 -232
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -90
- package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -120
- package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
- package/dist/authoring/scripts/plugin-status.mjs +8 -11
- package/dist/authoring/scripts/plugin-status.mjs.map +1 -1
- package/dist/authoring/scripts/remove-plugin.mjs +367 -0
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -0
- package/dist/authoring/scripts/validate-plugin.mjs +307 -1173
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/aw-skill-eval-materializer.d.ts +26 -0
- package/dist/scripts/aw-skill-eval-materializer.js +306 -0
- package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
- package/dist/scripts/bundle-plugins.d.ts +1 -2
- package/dist/scripts/bundle-plugins.js +24 -7
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +7 -24
- package/dist/scripts/plugin-staging.js +22 -142
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.d.ts +2 -0
- package/dist/scripts/test-plugin-scripts.js +27 -75
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/adapters/helpers.js +2 -2
- package/dist/src/adapters/helpers.js.map +1 -1
- package/dist/src/authoring/workspace-commands.d.ts +26 -2
- package/dist/src/authoring/workspace-commands.js +44 -19
- package/dist/src/authoring/workspace-commands.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +78 -0
- package/dist/src/commands/aw-capabilities.js +256 -0
- package/dist/src/commands/aw-capabilities.js.map +1 -0
- package/dist/src/commands/catalog-dev-source.d.ts +154 -0
- package/dist/src/commands/catalog-dev-source.js +655 -0
- package/dist/src/commands/catalog-dev-source.js.map +1 -0
- package/dist/src/commands/catalog-generation.d.ts +21 -0
- package/dist/src/commands/catalog-generation.js +9 -0
- package/dist/src/commands/catalog-generation.js.map +1 -0
- package/dist/src/commands/catalog-publication-inspection.d.ts +138 -0
- package/dist/src/commands/catalog-publication-inspection.js +757 -0
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -0
- package/dist/src/commands/catalog-publication-journal.d.ts +68 -0
- package/dist/src/commands/catalog-publication-journal.js +292 -0
- package/dist/src/commands/catalog-publication-journal.js.map +1 -0
- package/dist/src/commands/catalog-publication-target.d.ts +18 -0
- package/dist/src/commands/catalog-publication-target.js +95 -0
- package/dist/src/commands/catalog-publication-target.js.map +1 -0
- package/dist/src/commands/catalog-publish.d.ts +77 -7
- package/dist/src/commands/catalog-publish.js +746 -316
- package/dist/src/commands/catalog-publish.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +60 -22
- package/dist/src/commands/catalog-source.js +311 -91
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-status.d.ts +56 -0
- package/dist/src/commands/catalog-status.js +217 -0
- package/dist/src/commands/catalog-status.js.map +1 -0
- package/dist/src/commands/catalog-store.d.ts +104 -0
- package/dist/src/commands/catalog-store.js +685 -0
- package/dist/src/commands/catalog-store.js.map +1 -0
- package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
- package/dist/src/commands/catalog-workspace-resolution.js +42 -0
- package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
- package/dist/src/commands/console.js +28 -17
- package/dist/src/commands/console.js.map +1 -1
- package/dist/src/commands/dependency-operation-plan.d.ts +52 -15
- package/dist/src/commands/dependency-operation-plan.js +289 -7
- package/dist/src/commands/dependency-operation-plan.js.map +1 -1
- package/dist/src/commands/init.d.ts +5 -11
- package/dist/src/commands/init.js +30 -51
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/offline-cleanup-evidence.d.ts +67 -0
- package/dist/src/commands/offline-cleanup-evidence.js +181 -0
- package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
- package/dist/src/commands/operation-plan.d.ts +127 -0
- package/dist/src/commands/operation-plan.js +71 -0
- package/dist/src/commands/operation-plan.js.map +1 -0
- package/dist/src/commands/operation-planner.d.ts +46 -0
- package/dist/src/commands/operation-planner.js +141 -0
- package/dist/src/commands/operation-planner.js.map +1 -0
- package/dist/src/commands/options.d.ts +9 -7
- package/dist/src/commands/options.js +83 -21
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.d.ts +22 -0
- package/dist/src/commands/plugin-capabilities.js +159 -0
- package/dist/src/commands/plugin-capabilities.js.map +1 -0
- package/dist/src/commands/rebuild-command.d.ts +77 -30
- package/dist/src/commands/rebuild-command.js +3993 -711
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +120 -21
- package/dist/src/commands/rebuild-integration.js +2765 -1326
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +58 -30
- package/dist/src/commands/rebuild-operations.js +259 -319
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/reconcile-operation-plan.d.ts +28 -0
- package/dist/src/commands/reconcile-operation-plan.js +47 -0
- package/dist/src/commands/reconcile-operation-plan.js.map +1 -0
- package/dist/src/commands/review-inspection.d.ts +228 -0
- package/dist/src/commands/review-inspection.js +1341 -0
- package/dist/src/commands/review-inspection.js.map +1 -0
- package/dist/src/commands/review-preparation.d.ts +49 -0
- package/dist/src/commands/review-preparation.js +427 -0
- package/dist/src/commands/review-preparation.js.map +1 -0
- package/dist/src/commands/runtime.d.ts +1 -5
- package/dist/src/commands/runtime.js +24 -50
- package/dist/src/commands/runtime.js.map +1 -1
- package/dist/src/commands/skill-eval.d.ts +38 -0
- package/dist/src/commands/skill-eval.js +388 -0
- package/dist/src/commands/skill-eval.js.map +1 -0
- package/dist/src/commands/status-v6.d.ts +279 -0
- package/dist/src/commands/status-v6.js +2697 -0
- package/dist/src/commands/status-v6.js.map +1 -0
- package/dist/src/commands/sync-command.d.ts +40 -0
- package/dist/src/commands/sync-command.js +250 -0
- package/dist/src/commands/sync-command.js.map +1 -0
- package/dist/src/commands/wizard.d.ts +3 -4
- package/dist/src/commands/wizard.js +2 -2
- package/dist/src/commands/wizard.js.map +1 -1
- package/dist/src/commands/write-commands.d.ts +9 -3
- package/dist/src/commands/write-commands.js +124 -31
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/constants.d.ts +7 -1
- package/dist/src/constants.js +7 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/eval/manifest-v1.d.ts +71 -0
- package/dist/src/eval/manifest-v1.js +370 -0
- package/dist/src/eval/manifest-v1.js.map +1 -0
- package/dist/src/generators/local-plugin.d.ts +5 -1
- package/dist/src/generators/local-plugin.js +225 -104
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +10 -4
- package/dist/src/index.js +1787 -476
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.d.ts +43 -46
- package/dist/src/output/command-receipt.js +256 -80
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/model.d.ts +3 -44
- package/dist/src/output/model.js +1 -144
- package/dist/src/output/model.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +1 -13
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/commands.d.ts +46 -7
- package/dist/src/portable/commands.js +349 -37
- package/dist/src/portable/commands.js.map +1 -1
- package/dist/src/portable/materializer.d.ts +17 -4
- package/dist/src/portable/materializer.js +160 -38
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/portable/skills-cli.d.ts +15 -7
- package/dist/src/portable/skills-cli.js +66 -19
- package/dist/src/portable/skills-cli.js.map +1 -1
- package/dist/src/review/eval-source-input.d.ts +43 -0
- package/dist/src/review/eval-source-input.js +207 -0
- package/dist/src/review/eval-source-input.js.map +1 -0
- package/dist/src/review/review-profile.d.ts +17 -0
- package/dist/src/review/review-profile.js +177 -0
- package/dist/src/review/review-profile.js.map +1 -0
- package/dist/src/review/review-selection.d.ts +30 -0
- package/dist/src/review/review-selection.js +527 -0
- package/dist/src/review/review-selection.js.map +1 -0
- package/dist/src/review/review-types.d.ts +68 -0
- package/dist/src/review/review-types.js +16 -0
- package/dist/src/review/review-types.js.map +1 -0
- package/dist/src/review/skill-materialization.d.ts +13 -0
- package/dist/src/review/skill-materialization.js +75 -0
- package/dist/src/review/skill-materialization.js.map +1 -0
- package/dist/src/review/source-binding.d.ts +182 -0
- package/dist/src/review/source-binding.js +682 -0
- package/dist/src/review/source-binding.js.map +1 -0
- package/dist/src/tui/catalog-freshness.d.ts +1 -0
- package/dist/src/tui/catalog-freshness.js +2 -0
- package/dist/src/tui/catalog-freshness.js.map +1 -0
- package/dist/src/tui/catalog-generation.d.ts +21 -0
- package/dist/src/tui/catalog-generation.js +156 -0
- package/dist/src/tui/catalog-generation.js.map +1 -0
- package/dist/src/tui/catalog-sources/projection.d.ts +4 -0
- package/dist/src/tui/catalog-sources/projection.js +17 -0
- package/dist/src/tui/catalog-sources/projection.js.map +1 -0
- package/dist/src/tui/catalog-sources/review.d.ts +3 -0
- package/dist/src/tui/catalog-sources/review.js +13 -0
- package/dist/src/tui/catalog-sources/review.js.map +1 -0
- package/dist/src/tui/catalog-sources/screens.d.ts +12 -0
- package/dist/src/tui/catalog-sources/screens.js +40 -0
- package/dist/src/tui/catalog-sources/screens.js.map +1 -0
- package/dist/src/tui/catalog-sources/session.d.ts +28 -0
- package/dist/src/tui/catalog-sources/session.js +295 -0
- package/dist/src/tui/catalog-sources/session.js.map +1 -0
- package/dist/src/tui/catalog-sources/types.d.ts +53 -0
- package/dist/src/tui/catalog-sources/types.js +2 -0
- package/dist/src/tui/catalog-sources/types.js.map +1 -0
- package/dist/src/tui/catalog-store-task.d.ts +16 -0
- package/dist/src/tui/catalog-store-task.js +19 -0
- package/dist/src/tui/catalog-store-task.js.map +1 -0
- package/dist/src/tui/components.d.ts +128 -0
- package/dist/src/tui/components.js +251 -7
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +14 -4
- package/dist/src/tui/console-app-v4.js +9248 -1461
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +13 -1
- package/dist/src/tui/controller-runtime.js +3338 -410
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +614 -40
- package/dist/src/tui/controller.js +3478 -708
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/dependency-graph.d.ts +81 -0
- package/dist/src/tui/dependency-graph.js +455 -0
- package/dist/src/tui/dependency-graph.js.map +1 -0
- package/dist/src/tui/diagnostic-projection.d.ts +23 -0
- package/dist/src/tui/diagnostic-projection.js +567 -0
- package/dist/src/tui/diagnostic-projection.js.map +1 -0
- package/dist/src/tui/diagnostics.d.ts +30 -0
- package/dist/src/tui/diagnostics.js +76 -0
- package/dist/src/tui/diagnostics.js.map +1 -0
- package/dist/src/tui/glossary.d.ts +23 -0
- package/dist/src/tui/glossary.js +42 -0
- package/dist/src/tui/glossary.js.map +1 -0
- package/dist/src/tui/index.d.ts +11 -4
- package/dist/src/tui/index.js +8 -2
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/input-display.d.ts +8 -0
- package/dist/src/tui/input-display.js +36 -0
- package/dist/src/tui/input-display.js.map +1 -0
- package/dist/src/tui/keys.d.ts +44 -0
- package/dist/src/tui/keys.js +43 -15
- package/dist/src/tui/keys.js.map +1 -1
- package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
- package/dist/src/tui/lifecycle-action-view.js +36 -0
- package/dist/src/tui/lifecycle-action-view.js.map +1 -0
- package/dist/src/tui/model.d.ts +235 -27
- package/dist/src/tui/model.js +1652 -304
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +21 -0
- package/dist/src/tui/operation-diagnostic-screens.js +102 -0
- package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
- package/dist/src/tui/operation-history.d.ts +81 -0
- package/dist/src/tui/operation-history.js +135 -0
- package/dist/src/tui/operation-history.js.map +1 -0
- package/dist/src/tui/operation-review-planner.d.ts +21 -0
- package/dist/src/tui/operation-review-planner.js +1254 -0
- package/dist/src/tui/operation-review-planner.js.map +1 -0
- package/dist/src/tui/plugin-content.d.ts +23 -0
- package/dist/src/tui/plugin-content.js +336 -0
- package/dist/src/tui/plugin-content.js.map +1 -0
- package/dist/src/tui/plugin-write-task.d.ts +69 -0
- package/dist/src/tui/plugin-write-task.js +286 -0
- package/dist/src/tui/plugin-write-task.js.map +1 -0
- package/dist/src/tui/prompt.js +4 -15
- package/dist/src/tui/prompt.js.map +1 -1
- package/dist/src/tui/router.d.ts +183 -11
- package/dist/src/tui/router.js +352 -29
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/screen-registry.d.ts +702 -0
- package/dist/src/tui/screen-registry.js +231 -0
- package/dist/src/tui/screen-registry.js.map +1 -0
- package/dist/src/tui/session-console-app.d.ts +6 -0
- package/dist/src/tui/session-console-app.js +13 -0
- package/dist/src/tui/session-console-app.js.map +1 -0
- package/dist/src/tui/session-host.d.ts +45 -0
- package/dist/src/tui/session-host.js +209 -0
- package/dist/src/tui/session-host.js.map +1 -0
- package/dist/src/tui/source-ref-presets.d.ts +3 -0
- package/dist/src/tui/source-ref-presets.js +11 -0
- package/dist/src/tui/source-ref-presets.js.map +1 -0
- package/dist/src/tui/theme.d.ts +18 -10
- package/dist/src/tui/theme.js +18 -10
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/viewport.d.ts +20 -0
- package/dist/src/tui/viewport.js +29 -0
- package/dist/src/tui/viewport.js.map +1 -0
- package/dist/src/tui/views.js +31 -3
- package/dist/src/tui/views.js.map +1 -1
- package/dist/src/tui/wizard.js +11 -9
- package/dist/src/tui/wizard.js.map +1 -1
- package/dist/src/types.d.ts +242 -20
- package/dist/src/types.js +1 -0
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.d.ts +7 -1
- package/dist/src/utils/agent-version.js +41 -8
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/artifact-plan.d.ts +5 -4
- package/dist/src/utils/artifact-plan.js +18 -7
- package/dist/src/utils/artifact-plan.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +13 -7
- package/dist/src/utils/artifact-renderer.js +196 -219
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/artifact-request.d.ts +21 -0
- package/dist/src/utils/artifact-request.js +82 -0
- package/dist/src/utils/artifact-request.js.map +1 -0
- package/dist/src/utils/aw-home-mutation-lock.d.ts +1 -0
- package/dist/src/utils/aw-home-mutation-lock.js +32 -4
- package/dist/src/utils/aw-home-mutation-lock.js.map +1 -1
- package/dist/src/utils/bundle-integrity.d.ts +0 -1
- package/dist/src/utils/bundle-integrity.js +0 -25
- package/dist/src/utils/bundle-integrity.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +14 -29
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
- package/dist/src/utils/catalog-capability-projection.js +14 -0
- package/dist/src/utils/catalog-capability-projection.js.map +1 -0
- package/dist/src/utils/catalog-digests.d.ts +10 -0
- package/dist/src/utils/catalog-digests.js +50 -2
- package/dist/src/utils/catalog-digests.js.map +1 -1
- package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
- package/dist/src/utils/catalog-generation-error.d.ts +16 -0
- package/dist/src/utils/catalog-generation-error.js +30 -0
- package/dist/src/utils/catalog-generation-error.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +44 -0
- package/dist/src/utils/catalog-generation-resolver.js +273 -0
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
- package/dist/src/utils/catalog-generation-service.d.ts +172 -0
- package/dist/src/utils/catalog-generation-service.js +1271 -0
- package/dist/src/utils/catalog-generation-service.js.map +1 -0
- package/dist/src/utils/catalog-generation-state.d.ts +22 -0
- package/dist/src/utils/catalog-generation-state.js +192 -0
- package/dist/src/utils/catalog-generation-state.js.map +1 -0
- package/dist/src/utils/catalog-generation-store.d.ts +58 -0
- package/dist/src/utils/catalog-generation-store.js +452 -0
- package/dist/src/utils/catalog-generation-store.js.map +1 -0
- package/dist/src/utils/catalog-manifest-v7.d.ts +5 -0
- package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v7.js} +35 -43
- package/dist/src/utils/catalog-manifest-v7.js.map +1 -0
- package/dist/src/utils/catalog-operation-context.d.ts +20 -0
- package/dist/src/utils/catalog-operation-context.js +142 -0
- package/dist/src/utils/catalog-operation-context.js.map +1 -0
- package/dist/src/utils/catalog-public-error.d.ts +7 -3
- package/dist/src/utils/catalog-public-error.js +28 -8
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-runtime-projection.d.ts +4 -7
- package/dist/src/utils/catalog-runtime-projection.js +7 -102
- package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
- package/dist/src/utils/catalog-snapshot.d.ts +5 -3
- package/dist/src/utils/catalog-snapshot.js +11 -3
- package/dist/src/utils/catalog-snapshot.js.map +1 -1
- package/dist/src/utils/catalog-source-identity.d.ts +1 -0
- package/dist/src/utils/catalog-source-identity.js +21 -2
- package/dist/src/utils/catalog-source-identity.js.map +1 -1
- package/dist/src/utils/catalog-source-impact.d.ts +21 -0
- package/dist/src/utils/catalog-source-impact.js +344 -0
- package/dist/src/utils/catalog-source-impact.js.map +1 -0
- package/dist/src/utils/catalog-source-references.d.ts +3 -2
- package/dist/src/utils/catalog-source-references.js +195 -347
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +15 -1
- package/dist/src/utils/catalog-sources.js +206 -27
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-config.d.ts +2 -0
- package/dist/src/utils/codex-config.js +26 -5
- package/dist/src/utils/codex-config.js.map +1 -1
- package/dist/src/utils/codex-manager.d.ts +79 -0
- package/dist/src/utils/codex-manager.js +745 -0
- package/dist/src/utils/codex-manager.js.map +1 -0
- package/dist/src/utils/codex-marketplace-path.d.ts +5 -0
- package/dist/src/utils/codex-marketplace-path.js +45 -0
- package/dist/src/utils/codex-marketplace-path.js.map +1 -0
- package/dist/src/utils/codex-native-observation.d.ts +49 -0
- package/dist/src/utils/codex-native-observation.js +154 -0
- package/dist/src/utils/codex-native-observation.js.map +1 -0
- package/dist/src/utils/codex-native-render-receipt.d.ts +40 -0
- package/dist/src/utils/codex-native-render-receipt.js +205 -0
- package/dist/src/utils/codex-native-render-receipt.js.map +1 -0
- package/dist/src/utils/codex-reconciler.d.ts +126 -0
- package/dist/src/utils/codex-reconciler.js +298 -0
- package/dist/src/utils/codex-reconciler.js.map +1 -0
- package/dist/src/utils/codex-shared-native.d.ts +43 -0
- package/dist/src/utils/codex-shared-native.js +81 -0
- package/dist/src/utils/codex-shared-native.js.map +1 -0
- package/dist/src/utils/codex-skill-staging.d.ts +2 -0
- package/dist/src/utils/codex-skill-staging.js.map +1 -1
- package/dist/src/utils/codex-surface-analysis.d.ts +46 -0
- package/dist/src/utils/codex-surface-analysis.js +247 -0
- package/dist/src/utils/codex-surface-analysis.js.map +1 -0
- package/dist/src/utils/dynamic-skill-tree.d.ts +4 -0
- package/dist/src/utils/dynamic-skill-tree.js +36 -6
- package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.d.ts +18 -0
- package/dist/src/utils/git-catalog-provider.js +170 -144
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +15 -1
- package/dist/src/utils/local-marketplace.js +307 -84
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +1 -4
- package/dist/src/utils/manifest.js +1 -4
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.d.ts +3 -9
- package/dist/src/utils/multi-source-catalog.js +54 -110
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +55 -7
- package/dist/src/utils/native-cli.js +386 -57
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/orphan-marketplace-cleanup.js +0 -4
- package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
- package/dist/src/utils/ownership.d.ts +84 -20
- package/dist/src/utils/ownership.js +179 -222
- package/dist/src/utils/ownership.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.d.ts +1 -1
- package/dist/src/utils/path-catalog-provider.js +54 -65
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/paths.d.ts +0 -1
- package/dist/src/utils/paths.js +0 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/plugin-config-impact.d.ts +33 -0
- package/dist/src/utils/plugin-config-impact.js +298 -0
- package/dist/src/utils/plugin-config-impact.js.map +1 -0
- package/dist/src/utils/plugin-config-write.d.ts +52 -27
- package/dist/src/utils/plugin-config-write.js +990 -298
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +140 -93
- package/dist/src/utils/plugin-config.js +992 -980
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-intent-state.d.ts +49 -0
- package/dist/src/utils/plugin-intent-state.js +320 -0
- package/dist/src/utils/plugin-intent-state.js.map +1 -0
- package/dist/src/utils/plugin-scripts.d.ts +62 -125
- package/dist/src/utils/plugin-scripts.js +468 -525
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/process-tree.d.ts +2 -2
- package/dist/src/utils/process-tree.js +1 -1
- package/dist/src/utils/process-tree.js.map +1 -1
- package/dist/src/utils/project-boundary.d.ts +11 -13
- package/dist/src/utils/project-boundary.js +28 -34
- package/dist/src/utils/project-boundary.js.map +1 -1
- package/dist/src/utils/safe-fs.d.ts +21 -0
- package/dist/src/utils/safe-fs.js +111 -0
- package/dist/src/utils/safe-fs.js.map +1 -0
- package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
- package/dist/src/utils/safe-operation-diagnostic.js +33 -0
- package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
- package/dist/src/utils/sensitive-content.d.ts +4 -0
- package/dist/src/utils/sensitive-content.js +36 -0
- package/dist/src/utils/sensitive-content.js.map +1 -0
- package/dist/src/utils/skill-validation.d.ts +1 -1
- package/dist/src/utils/skill-validation.js +1 -1
- package/dist/src/utils/skill-validation.js.map +1 -1
- package/dist/src/utils/state-paths.d.ts +1 -0
- package/dist/src/utils/state-paths.js +12 -2
- package/dist/src/utils/state-paths.js.map +1 -1
- package/dist/src/utils/target-eligibility.d.ts +8 -2
- package/dist/src/utils/target-eligibility.js +17 -8
- package/dist/src/utils/target-eligibility.js.map +1 -1
- package/dist/src/utils/windows-claude-shim.d.ts +9 -0
- package/dist/src/utils/windows-claude-shim.js +141 -0
- package/dist/src/utils/windows-claude-shim.js.map +1 -0
- package/dist/vitest.config.js +91 -10
- package/dist/vitest.config.js.map +1 -1
- package/package.json +22 -19
- package/dist/authoring/scripts/check-plugin-versions.mjs +0 -5
- package/dist/authoring/scripts/check-plugin-versions.mjs.map +0 -1
- package/dist/scripts/aw-skill-eval-engine.d.ts +0 -13
- package/dist/scripts/aw-skill-eval-engine.js +0 -31
- package/dist/scripts/aw-skill-eval-engine.js.map +0 -1
- package/dist/scripts/codex-eval-app-server.d.ts +0 -89
- package/dist/scripts/codex-eval-app-server.js +0 -1228
- package/dist/scripts/codex-eval-app-server.js.map +0 -1
- package/dist/scripts/codex-eval-isolation.d.ts +0 -61
- package/dist/scripts/codex-eval-isolation.js +0 -318
- package/dist/scripts/codex-eval-isolation.js.map +0 -1
- package/dist/scripts/codex-eval-process-management.d.ts +0 -8
- package/dist/scripts/codex-eval-process-management.js +0 -69
- package/dist/scripts/codex-eval-process-management.js.map +0 -1
- package/dist/scripts/codex-eval-process-tree.d.ts +0 -38
- package/dist/scripts/codex-eval-process-tree.js +0 -803
- package/dist/scripts/codex-eval-process-tree.js.map +0 -1
- package/dist/scripts/codex-eval-runtime-config.d.ts +0 -62
- package/dist/scripts/codex-eval-runtime-config.js +0 -843
- package/dist/scripts/codex-eval-runtime-config.js.map +0 -1
- package/dist/scripts/codex-trigger-eval.d.ts +0 -84
- package/dist/scripts/codex-trigger-eval.js +0 -968
- package/dist/scripts/codex-trigger-eval.js.map +0 -1
- package/dist/scripts/eval-plugin-skills-audited.d.ts +0 -6
- package/dist/scripts/eval-plugin-skills-audited.js +0 -261
- package/dist/scripts/eval-plugin-skills-audited.js.map +0 -1
- package/dist/scripts/eval-plugin-skills.d.ts +0 -45
- package/dist/scripts/eval-plugin-skills.js +0 -1586
- package/dist/scripts/eval-plugin-skills.js.map +0 -1
- package/dist/scripts/eval-run-layout.d.ts +0 -17
- package/dist/scripts/eval-run-layout.js +0 -26
- package/dist/scripts/eval-run-layout.js.map +0 -1
- package/dist/scripts/plugin-eval-contract.d.ts +0 -185
- package/dist/scripts/plugin-eval-contract.js +0 -695
- package/dist/scripts/plugin-eval-contract.js.map +0 -1
- package/dist/scripts/plugin-eval-materializer.d.ts +0 -13
- package/dist/scripts/plugin-eval-materializer.js +0 -421
- package/dist/scripts/plugin-eval-materializer.js.map +0 -1
- package/dist/scripts/skill-reporting.d.ts +0 -212
- package/dist/scripts/skill-reporting.js +0 -922
- package/dist/scripts/skill-reporting.js.map +0 -1
- package/dist/src/commands/status-v4.d.ts +0 -102
- package/dist/src/commands/status-v4.js +0 -844
- package/dist/src/commands/status-v4.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -93
- package/dist/src/commands/status.js +0 -442
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
- package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
- package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
- package/dist/src/utils/catalog-manifest-v3.js +0 -3
- package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
- package/dist/src/utils/catalog-manifest-v4.js.map +0 -1
- package/dist/src/utils/catalog-source-cache.d.ts +0 -61
- package/dist/src/utils/catalog-source-cache.js +0 -276
- package/dist/src/utils/catalog-source-cache.js.map +0 -1
- package/dist/src/utils/codex-project-surface.d.ts +0 -3
- package/dist/src/utils/codex-project-surface.js +0 -49
- package/dist/src/utils/codex-project-surface.js.map +0 -1
- package/dist/src/utils/lifecycle-active-store.d.ts +0 -175
- package/dist/src/utils/lifecycle-active-store.js +0 -1276
- package/dist/src/utils/lifecycle-active-store.js.map +0 -1
- package/dist/src/utils/plugin-authoring-capabilities.d.ts +0 -23
- package/dist/src/utils/plugin-authoring-capabilities.js +0 -37
- package/dist/src/utils/plugin-authoring-capabilities.js.map +0 -1
- package/dist/src/utils/plugin-authoring-capabilities.json +0 -92
- package/dist/src/utils/plugin-release.d.ts +0 -2
- package/dist/src/utils/plugin-release.js +0 -2
- package/dist/src/utils/plugin-release.js.map +0 -1
- package/dist/src/utils/skill-frontmatter-capabilities.d.ts +0 -201
- package/dist/src/utils/skill-frontmatter-capabilities.js +0 -5
- package/dist/src/utils/skill-frontmatter-capabilities.js.map +0 -1
- package/dist/src/utils/skill-frontmatter-capabilities.json +0 -200
- /package/dist/authoring/scripts/{check-plugin-versions.d.mts → remove-plugin.d.mts} +0 -0
package/dist/src/index.js
CHANGED
|
@@ -3,37 +3,50 @@ import fs from 'node:fs';
|
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { spawn } from 'node:child_process';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
import { Command, CommanderError, Option } from 'commander';
|
|
6
|
+
import { Command, CommanderError, InvalidArgumentError, Option } from 'commander';
|
|
7
|
+
import { doctorEvalProviders } from '@lesliechan721/agent-skill-eval';
|
|
7
8
|
import { initCommand } from './commands/init.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { resolveCatalogWorkspaceRoot } from './commands/catalog-workspace-resolution.js';
|
|
10
|
+
import { addCatalogSourceCommand, preflightCatalogSourceMutation, explicitRefPolicy, listCatalogSources, removeCatalogSourceCommand, setPrimaryCatalogSourceCommand, updateCatalogSourceCommand, } from './commands/catalog-source.js';
|
|
11
|
+
import { catalogSourceStatusCommand, syncCatalogSourceCommand, } from './commands/catalog-generation.js';
|
|
12
|
+
import { catalogStoreErrorCode, catalogStorePrune, catalogStoreStatus, } from './commands/catalog-store.js';
|
|
13
|
+
import { cleanupWriteCommand as cleanupCommand, installWriteCommand as installCommand, reinstallWriteCommand as reinstallCommand, uninstallWriteCommand as uninstallCommand, } from './commands/write-commands.js';
|
|
14
|
+
import { syncCommand } from './commands/sync-command.js';
|
|
10
15
|
import { formatInteractiveConsoleUnavailableMessage, runConsoleController, } from './commands/console.js';
|
|
11
16
|
import { runCommandWizard, toWizardCandidates, WizardExecutionError, } from './commands/wizard.js';
|
|
12
17
|
import { createCliExecutionContext, emitCommandEvent, } from './commands/runtime.js';
|
|
13
|
-
import { loadConsoleItemsResult } from './commands/status.js';
|
|
14
|
-
import {
|
|
15
|
-
import { normalizeUninstallCommandOptions, normalizeCleanupCommandOptions, resolveConfigReadResolution, resolveConfigProjectLayer, resolveConfigWriteScope, normalizeInstallCommandOptions, normalizeReinstallCommandOptions, normalizeUpgradeCommandOptions, } from './commands/options.js';
|
|
18
|
+
import { loadConsoleItemsResult, statusCommandV8 } from './commands/status-v6.js';
|
|
19
|
+
import { normalizeUninstallCommandOptions, normalizeCleanupCommandOptions, resolveConfigReadResolution, resolveConfigWriteScope, normalizeInstallCommandOptions, normalizeReinstallCommandOptions, resolveScriptTimeoutMs, } from './commands/options.js';
|
|
16
20
|
import { isCommandWarningError, } from './types.js';
|
|
17
21
|
import { formatWarnings } from './output/reporter.js';
|
|
18
22
|
import { redactString, redactValue } from './output/redact.js';
|
|
19
23
|
import { renderShellCommand, } from './output/equivalent-command.js';
|
|
20
24
|
import { buildRebuildReceiptJson, buildInitReceiptJson, renderRebuildReceipt, renderInitReceipt, } from './output/command-receipt.js';
|
|
21
25
|
import { resolveCliPackageRoot } from './utils/paths.js';
|
|
22
|
-
import {
|
|
23
|
-
import { applyPluginConfigWrite, describeResetAffectedFields, resetPluginConfigWithHelper, } from './utils/plugin-config-write.js';
|
|
26
|
+
import { findConfigFieldEntry, formatPluginConfigSetRecoveryCommand, listNamespacedPluginConfigStores, listPluginConfigStorePluginNames, readPluginConfigStore, renderPluginConfigValueForDisplay, resolveConfigRead, } from './utils/plugin-config.js';
|
|
27
|
+
import { applyPluginConfigWrite, buildConfigMutationReceipt, configWriteStateForError, describeResetAffectedFields, resetPluginConfigWithHelper, } from './utils/plugin-config-write.js';
|
|
24
28
|
import { assertStrictSemVer } from './utils/manifest.js';
|
|
25
29
|
import { writeCandidateEligibility } from './utils/target-eligibility.js';
|
|
26
30
|
import { assertCatalogSourceReferencesSupported, inventoryLegacyConfigReferences, } from './utils/catalog-source-references.js';
|
|
27
31
|
import { parsePluginId, withResolvedCatalogPlugin, withResolvedMultiSourceCatalog, } from './utils/multi-source-catalog.js';
|
|
28
|
-
import { sanitizeCatalogSourceError } from './utils/catalog-public-error.js';
|
|
29
|
-
import {
|
|
32
|
+
import { sanitizeCatalogSourceError, sanitizeCatalogSourceErrorMessage, } from './utils/catalog-public-error.js';
|
|
33
|
+
import { catalogGenerationErrorCode } from './utils/catalog-generation-error.js';
|
|
34
|
+
import { resolveCatalogOperationContext, } from './utils/catalog-operation-context.js';
|
|
30
35
|
import { withAwHomeMutationLock, } from './utils/aw-home-mutation-lock.js';
|
|
31
36
|
import { installPortableSkills, materializePortableSkillsToDirectory, PortableCommandError, renderPortableReview, } from './portable/commands.js';
|
|
32
37
|
import { SkillsCliError } from './portable/skills-cli.js';
|
|
33
38
|
import { computeReviewComponentDigest, listReviewRecords, parseReviewAttachment, publishReviewRecord, showReviewRecord, verifyReviewRecord, } from './commands/review-publication.js';
|
|
39
|
+
import { createReviewInspectionFailure, getReviewInspectionExitCode, inspectReviewTarget, } from './commands/review-inspection.js';
|
|
40
|
+
import { prepareReviewTarget, } from './commands/review-preparation.js';
|
|
34
41
|
import { resolveRepoRoot } from './utils/state-paths.js';
|
|
35
42
|
import { runCatalogBuildCommand, runCatalogInitCommand, runCatalogValidateCommand, runCatalogVersionCommand, runPluginBuildCommand, runPluginTestCommand, } from './authoring/workspace-commands.js';
|
|
36
|
-
import {
|
|
43
|
+
import { runCatalogPublishApplyCommand, runCatalogPublishPlanCommand, } from './commands/catalog-publish.js';
|
|
44
|
+
import { catalogPublicationFailure, CatalogPublicationInspectionError, } from './commands/catalog-publication-inspection.js';
|
|
45
|
+
import { getCatalogStatus, renderCatalogStatus } from './commands/catalog-status.js';
|
|
46
|
+
import { activateCatalogDevSource, catalogDevSourceError, createCatalogDevFailureReceipt, deactivateCatalogDevSource, getCatalogDevSourceStatus, } from './commands/catalog-dev-source.js';
|
|
47
|
+
import { getPluginCapabilitiesResult, parsePluginCapabilitySurface, renderPluginCapabilities, } from './commands/plugin-capabilities.js';
|
|
48
|
+
import { AwCapabilityUnsupportedError, checkCurrentAw, describeCurrentAw, inspectPluginRequirements, } from './commands/aw-capabilities.js';
|
|
49
|
+
import { prepareSkillEval } from './commands/skill-eval.js';
|
|
37
50
|
function createDefaultIo() {
|
|
38
51
|
return {
|
|
39
52
|
stdout: (text) => process.stdout.write(text),
|
|
@@ -43,6 +56,62 @@ function createDefaultIo() {
|
|
|
43
56
|
function writeLine(write, line) {
|
|
44
57
|
write(`${line}\n`);
|
|
45
58
|
}
|
|
59
|
+
function strictValueOption(flags, description, choices) {
|
|
60
|
+
let seen = false;
|
|
61
|
+
const option = new Option(flags, description);
|
|
62
|
+
return option.argParser((value) => {
|
|
63
|
+
if (seen)
|
|
64
|
+
throw new InvalidArgumentError(`${option.long} can be specified only once.`);
|
|
65
|
+
if (choices && !choices.includes(value)) {
|
|
66
|
+
throw new InvalidArgumentError(`${option.long} must be one of: ${choices.join(', ')}.`);
|
|
67
|
+
}
|
|
68
|
+
seen = true;
|
|
69
|
+
return value;
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
function collectUniqueOption(value, previous) {
|
|
73
|
+
return previous.includes(value) ? previous : [...previous, value];
|
|
74
|
+
}
|
|
75
|
+
function renderReviewSkills(write, skills, issues) {
|
|
76
|
+
for (const skill of skills) {
|
|
77
|
+
writeLine(write, `${skill.skill}\t${skill.profile.platform}/${skill.profile.scope}\t${skill.state}\t${skill.finalPath ?? '-'}`);
|
|
78
|
+
}
|
|
79
|
+
for (const issue of issues)
|
|
80
|
+
writeLine(write, `${issue.code}: ${issue.message}`);
|
|
81
|
+
}
|
|
82
|
+
function renderReviewInspection(write, receipt) {
|
|
83
|
+
writeLine(write, `Review inspection (${receipt.view}): ${receipt.ok ? 'ok' : 'failed'}`);
|
|
84
|
+
if (receipt.view === 'review') {
|
|
85
|
+
renderReviewSkills(write, receipt.skills, receipt.issues);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
for (const issue of receipt.issues)
|
|
89
|
+
writeLine(write, `${issue.code}: ${issue.message}`);
|
|
90
|
+
}
|
|
91
|
+
function renderReviewPreparation(write, receipt) {
|
|
92
|
+
writeLine(write, `Review preparation: ${receipt.ok ? 'complete' : 'failed'}`);
|
|
93
|
+
if (receipt.sourceBindingPath)
|
|
94
|
+
writeLine(write, `Source binding: ${receipt.sourceBindingPath}`);
|
|
95
|
+
renderReviewSkills(write, receipt.skills, receipt.issues);
|
|
96
|
+
}
|
|
97
|
+
function requestedReviewView(argv) {
|
|
98
|
+
const inline = argv.find((token) => token.startsWith('--view='));
|
|
99
|
+
if (inline === '--view=release')
|
|
100
|
+
return 'release';
|
|
101
|
+
const index = argv.indexOf('--view');
|
|
102
|
+
return index >= 0 && argv[index + 1] === 'release' ? 'release' : 'review';
|
|
103
|
+
}
|
|
104
|
+
function createReviewPreparationFailure(message, code = 'invalidArguments') {
|
|
105
|
+
return {
|
|
106
|
+
schemaVersion: 1,
|
|
107
|
+
command: 'review:prepare',
|
|
108
|
+
ok: false,
|
|
109
|
+
target: null,
|
|
110
|
+
sourceBindingPath: null,
|
|
111
|
+
skills: [],
|
|
112
|
+
issues: [{ code, path: null, message }],
|
|
113
|
+
};
|
|
114
|
+
}
|
|
46
115
|
function writeWarnings(write, warnings, options = {}) {
|
|
47
116
|
for (const warning of formatWarnings(warnings, options)) {
|
|
48
117
|
writeLine(write, warning);
|
|
@@ -54,10 +123,266 @@ function resolveCliVersion() {
|
|
|
54
123
|
return assertStrictSemVer(packageJson.version, 'packages/cli/package.json version');
|
|
55
124
|
}
|
|
56
125
|
function resolveCommandReceiptExitCode(result) {
|
|
57
|
-
|
|
58
|
-
|
|
126
|
+
return result.overallState === 'succeeded' ? 0 : 1;
|
|
127
|
+
}
|
|
128
|
+
class WriteCommandRequestError extends Error {
|
|
129
|
+
code = 'invalidArguments';
|
|
130
|
+
}
|
|
131
|
+
function normalizeWriteRequest(normalize) {
|
|
132
|
+
try {
|
|
133
|
+
return normalize();
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
throw new WriteCommandRequestError(error instanceof Error ? error.message : String(error));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
function writeCommandFailure(error) {
|
|
140
|
+
const message = redactString(error instanceof Error ? error.message : String(error));
|
|
141
|
+
if (error instanceof CommanderError || error instanceof WriteCommandRequestError) {
|
|
142
|
+
return { code: 'invalidArguments', message };
|
|
143
|
+
}
|
|
144
|
+
const explicitCode = error?.code;
|
|
145
|
+
if (typeof explicitCode === 'string' && /^[A-Za-z][A-Za-z0-9]*$/u.test(explicitCode)) {
|
|
146
|
+
return { code: explicitCode, message };
|
|
147
|
+
}
|
|
148
|
+
const separator = message.indexOf(':');
|
|
149
|
+
const prefix = separator > 0 ? message.slice(0, separator) : '';
|
|
150
|
+
return {
|
|
151
|
+
code: /^[A-Za-z][A-Za-z0-9]*$/u.test(prefix) ? prefix : 'writeCommandFailed',
|
|
152
|
+
message,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function preparseWriteReceiptRequest(argv) {
|
|
156
|
+
const request = { json: false, plugins: [] };
|
|
157
|
+
let positionalOnly = false;
|
|
158
|
+
for (let index = 1; index < argv.length; index += 1) {
|
|
159
|
+
const token = argv[index];
|
|
160
|
+
if (positionalOnly) {
|
|
161
|
+
request.plugins.push(token);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
if (token === '--') {
|
|
165
|
+
positionalOnly = true;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (token === '--json') {
|
|
169
|
+
request.json = true;
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
if (token === '--platform' || token === '--scope') {
|
|
173
|
+
const value = argv[index + 1];
|
|
174
|
+
if (token === '--platform')
|
|
175
|
+
request.platform = value;
|
|
176
|
+
else
|
|
177
|
+
request.scope = value;
|
|
178
|
+
index += 1;
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
if (token.startsWith('--platform=')) {
|
|
182
|
+
request.platform = token.slice('--platform='.length);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (token.startsWith('--scope=')) {
|
|
186
|
+
request.scope = token.slice('--scope='.length);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (token === '--dependency-scope' || token === '--script-timeout' || token === '--log-file') {
|
|
190
|
+
index += 1;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
if (token.startsWith('--'))
|
|
194
|
+
continue;
|
|
195
|
+
if (token.startsWith('-') && token !== '-') {
|
|
196
|
+
const shortOptions = token.slice(1);
|
|
197
|
+
for (let offset = 0; offset < shortOptions.length; offset += 1) {
|
|
198
|
+
const option = shortOptions[offset];
|
|
199
|
+
if (option === 'j') {
|
|
200
|
+
request.json = true;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (option === 'p' || option === 's') {
|
|
204
|
+
const value = shortOptions.slice(offset + 1) || argv[index + 1];
|
|
205
|
+
if (option === 'p')
|
|
206
|
+
request.platform = value;
|
|
207
|
+
else
|
|
208
|
+
request.scope = value;
|
|
209
|
+
if (shortOptions.length === offset + 1)
|
|
210
|
+
index += 1;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
continue;
|
|
215
|
+
}
|
|
216
|
+
request.plugins.push(token);
|
|
217
|
+
}
|
|
218
|
+
return request;
|
|
219
|
+
}
|
|
220
|
+
function jsonWriteCommandRequest(argv) {
|
|
221
|
+
const command = argv[0];
|
|
222
|
+
if (!['install', 'reinstall', 'uninstall', 'cleanup', 'sync'].includes(command ?? '')) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
const request = preparseWriteReceiptRequest(argv);
|
|
226
|
+
if (!request.json)
|
|
227
|
+
return null;
|
|
228
|
+
const rawPlatform = request.platform;
|
|
229
|
+
const platform = rawPlatform === 'codex' || rawPlatform === 'claude' || rawPlatform === 'both'
|
|
230
|
+
? rawPlatform
|
|
231
|
+
: 'codex';
|
|
232
|
+
return {
|
|
233
|
+
command: command,
|
|
234
|
+
plugins: request.plugins,
|
|
235
|
+
platform,
|
|
236
|
+
scope: request.scope === 'project' ? 'project' : 'user',
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function writeCommandFailureReceipt(write, request, error) {
|
|
240
|
+
const platforms = request.platform === 'both'
|
|
241
|
+
? ['codex', 'claude']
|
|
242
|
+
: [request.platform];
|
|
243
|
+
writeJsonReceipt(write, buildRebuildReceiptJson(request.command, {
|
|
244
|
+
platforms,
|
|
245
|
+
plugins: request.plugins,
|
|
246
|
+
warnings: [],
|
|
247
|
+
overallState: 'failed',
|
|
248
|
+
errors: [writeCommandFailure(error)],
|
|
249
|
+
receiptTargets: request.plugins.flatMap((selector) => platforms.map((platform) => {
|
|
250
|
+
let pluginName = selector;
|
|
251
|
+
let sourceId;
|
|
252
|
+
try {
|
|
253
|
+
const parsed = parsePluginId(selector);
|
|
254
|
+
pluginName = parsed.pluginName;
|
|
255
|
+
sourceId = parsed.sourceId;
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// Keep the raw selector in the failed receipt.
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
pluginName,
|
|
262
|
+
pluginId: selector,
|
|
263
|
+
...(sourceId ? { sourceId } : {}),
|
|
264
|
+
platform,
|
|
265
|
+
scope: request.scope,
|
|
266
|
+
};
|
|
267
|
+
})),
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
270
|
+
function scanConfigMutationShortOptions(token, command) {
|
|
271
|
+
if (!/^-[^-].*/u.test(token))
|
|
272
|
+
return { json: false, consumesNextValue: false };
|
|
273
|
+
let json = false;
|
|
274
|
+
for (let index = 1; index < token.length; index += 1) {
|
|
275
|
+
const option = token[index];
|
|
276
|
+
if (option === 's') {
|
|
277
|
+
return {
|
|
278
|
+
json,
|
|
279
|
+
consumesNextValue: index === token.length - 1,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
if (option === 'j') {
|
|
283
|
+
json = true;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (option === 'v' || option === 'D' || (option === 'y' && command === 'config:reset')) {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
break;
|
|
290
|
+
}
|
|
291
|
+
return { json, consumesNextValue: false };
|
|
292
|
+
}
|
|
293
|
+
function jsonConfigMutationRequest(argv) {
|
|
294
|
+
if (argv[0] !== 'config' || !['set', 'unset', 'reset'].includes(argv[1] ?? '')) {
|
|
295
|
+
return null;
|
|
296
|
+
}
|
|
297
|
+
const command = `config:${argv[1]}`;
|
|
298
|
+
let json = false;
|
|
299
|
+
let plugin;
|
|
300
|
+
const valueOptions = new Set(['--scope', '--value-json', '--preset', '--log-file']);
|
|
301
|
+
for (let index = 2; index < argv.length; index += 1) {
|
|
302
|
+
const token = argv[index];
|
|
303
|
+
if (token === '--')
|
|
304
|
+
break;
|
|
305
|
+
if (valueOptions.has(token)) {
|
|
306
|
+
index += 1;
|
|
307
|
+
continue;
|
|
308
|
+
}
|
|
309
|
+
if (token === '--json') {
|
|
310
|
+
json = true;
|
|
311
|
+
continue;
|
|
312
|
+
}
|
|
313
|
+
const shortOptions = scanConfigMutationShortOptions(token, command);
|
|
314
|
+
if (shortOptions.json)
|
|
315
|
+
json = true;
|
|
316
|
+
if (shortOptions.consumesNextValue)
|
|
317
|
+
index += 1;
|
|
318
|
+
if (token.startsWith('-'))
|
|
319
|
+
continue;
|
|
320
|
+
plugin ??= token;
|
|
321
|
+
}
|
|
322
|
+
if (!json)
|
|
323
|
+
return null;
|
|
324
|
+
return {
|
|
325
|
+
command,
|
|
326
|
+
...(plugin ? { plugin } : {}),
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function configMutationFailure(error, env, cwd) {
|
|
330
|
+
const configWrite = configWriteStateForError(error);
|
|
331
|
+
if (error instanceof CommanderError) {
|
|
332
|
+
return {
|
|
333
|
+
code: 'invalidArguments',
|
|
334
|
+
message: 'error: invalid config mutation arguments',
|
|
335
|
+
configWrite,
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
const message = catalogPublicationFailure({
|
|
339
|
+
error,
|
|
340
|
+
env,
|
|
341
|
+
sensitiveRoots: [cwd],
|
|
342
|
+
}).message;
|
|
343
|
+
if (message.includes('Usage:'))
|
|
344
|
+
return { code: 'invalidArguments', message, configWrite };
|
|
345
|
+
const generationCode = catalogGenerationErrorCode(error);
|
|
346
|
+
if (generationCode === 'catalogGenerationUnavailable'
|
|
347
|
+
|| generationCode === 'catalogGenerationSourceMissing') {
|
|
348
|
+
return { code: 'catalogSourceUnavailable', message, configWrite };
|
|
349
|
+
}
|
|
350
|
+
if (generationCode !== 'catalogGenerationFailed')
|
|
351
|
+
return { code: generationCode, message, configWrite };
|
|
352
|
+
const explicitCode = error?.code;
|
|
353
|
+
if (typeof explicitCode === 'string' && /^[A-Za-z][A-Za-z0-9]*$/u.test(explicitCode)) {
|
|
354
|
+
return { code: explicitCode, message, configWrite };
|
|
355
|
+
}
|
|
356
|
+
if (message.includes('legacyStateUnsupported'))
|
|
357
|
+
return { code: 'legacyStateUnsupported', message, configWrite };
|
|
358
|
+
if (message.includes('sourceChanged'))
|
|
359
|
+
return { code: 'sourceChanged', message, configWrite };
|
|
360
|
+
if (message.includes('sourceMissing'))
|
|
361
|
+
return { code: 'sourceMissing', message, configWrite };
|
|
362
|
+
if (message.startsWith('Cannot resolve required catalog sources:')) {
|
|
363
|
+
return { code: 'catalogSourceUnavailable', message, configWrite };
|
|
364
|
+
}
|
|
365
|
+
const prefix = message.match(/^([A-Za-z][A-Za-z0-9]*):/u)?.[1];
|
|
366
|
+
return { code: prefix ?? 'configMutationFailed', message, configWrite };
|
|
367
|
+
}
|
|
368
|
+
function writeConfigMutationFailureReceipt(write, request, failure) {
|
|
369
|
+
let plugin;
|
|
370
|
+
try {
|
|
371
|
+
if (request.plugin) {
|
|
372
|
+
parsePluginId(request.plugin);
|
|
373
|
+
plugin = request.plugin;
|
|
374
|
+
}
|
|
59
375
|
}
|
|
60
|
-
|
|
376
|
+
catch {
|
|
377
|
+
// Do not echo an invalid selector from raw argv in an early failure receipt.
|
|
378
|
+
}
|
|
379
|
+
writeJsonReceipt(write, buildConfigMutationReceipt(request.command, {
|
|
380
|
+
ok: false,
|
|
381
|
+
overallState: 'failed',
|
|
382
|
+
configWrite: failure.configWrite,
|
|
383
|
+
...(plugin ? { plugin } : {}),
|
|
384
|
+
errors: [failure],
|
|
385
|
+
}));
|
|
61
386
|
}
|
|
62
387
|
async function runAuthoringScript(options) {
|
|
63
388
|
const scriptPath = path.join(resolveCliPackageRoot(), 'dist', 'authoring', 'scripts', options.scriptName);
|
|
@@ -100,47 +425,54 @@ function optionTokens(flag, value) {
|
|
|
100
425
|
function writeCommandUsage(command) {
|
|
101
426
|
const cardinality = command === 'reinstall' || command === 'cleanup' ? '<plugin>' : '<plugin...>';
|
|
102
427
|
const scope = command === 'cleanup' ? ' --scope <project|user>' : ' [--scope <project|user>]';
|
|
103
|
-
const all = command === 'upgrade' ? ' 或 aw upgrade --all --platform both --scope user' : '';
|
|
104
428
|
return [
|
|
105
429
|
`${command} 命令缺少必要参数。`,
|
|
106
430
|
`Usage: aw ${command} ${cardinality} --platform <codex|claude|both>${scope}`,
|
|
107
|
-
`Example: aw ${command} example-plugin --platform codex --scope user
|
|
431
|
+
`Example: aw ${command} example-plugin --platform codex --scope user`,
|
|
108
432
|
].join('\n');
|
|
109
433
|
}
|
|
110
434
|
function configCommandUsage(command) {
|
|
111
435
|
const argumentsByCommand = {
|
|
112
436
|
list: '<plugin>',
|
|
113
437
|
get: '<plugin> [key]',
|
|
114
|
-
set: '<plugin> <
|
|
438
|
+
set: '<plugin> <field> --scope <project|user> (--value-json <json> | --value-stdin | --preset <id>)',
|
|
115
439
|
unset: '<plugin> <key>',
|
|
116
440
|
reset: '<plugin> --scope <project|user> --yes',
|
|
117
441
|
};
|
|
118
442
|
return [
|
|
119
443
|
`config ${command} 命令缺少必要参数。`,
|
|
120
444
|
`Usage: aw config ${command} ${argumentsByCommand[command]}`,
|
|
121
|
-
`Example: aw config ${command} example-plugin${command === 'set' ? '
|
|
445
|
+
`Example: aw config ${command} example-plugin${command === 'set' ? ' mode --scope user --value-json \'"safe"\'' : command === 'unset' ? ' key' : command === 'reset' ? ' --scope user --yes' : ''}`,
|
|
122
446
|
].join('\n');
|
|
123
447
|
}
|
|
124
|
-
function
|
|
125
|
-
|
|
126
|
-
|
|
448
|
+
async function readUtf8Stdin(stdin) {
|
|
449
|
+
const chunks = [];
|
|
450
|
+
for await (const chunk of stdin) {
|
|
451
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : Buffer.from(chunk));
|
|
127
452
|
}
|
|
453
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
128
454
|
}
|
|
129
455
|
function equivalentWriteCommand(command, selection, rawOptions) {
|
|
130
456
|
return shellCommand(buildEquivalentWriteCommandTokens(command, selection, rawOptions));
|
|
131
457
|
}
|
|
132
458
|
export function buildEquivalentWriteCommandTokens(command, selection, rawOptions) {
|
|
133
|
-
const all = command === 'upgrade' && rawOptions.all === true;
|
|
134
459
|
return [
|
|
135
460
|
'aw',
|
|
136
461
|
command,
|
|
137
|
-
...(all ? ['--all'] : []),
|
|
138
462
|
'--platform',
|
|
139
463
|
selection.platform ?? 'both',
|
|
140
464
|
'--scope',
|
|
141
465
|
selection.scope ?? 'user',
|
|
142
|
-
...(
|
|
143
|
-
|
|
466
|
+
...(rawOptions.allowManagedCodexInstall === true
|
|
467
|
+
? ['--allow-managed-codex-install']
|
|
468
|
+
: []),
|
|
469
|
+
...(command === 'install'
|
|
470
|
+
? (rawOptions.dependencyScope ?? []).flatMap((value) => ['--dependency-scope', value])
|
|
471
|
+
: []),
|
|
472
|
+
...((command === 'install' || command === 'reinstall')
|
|
473
|
+
? optionTokens('--script-timeout', rawOptions.scriptTimeout)
|
|
474
|
+
: []),
|
|
475
|
+
...(selection.plugins.length > 0 ? ['--', ...selection.plugins] : []),
|
|
144
476
|
];
|
|
145
477
|
}
|
|
146
478
|
function equivalentConfigCommand(options) {
|
|
@@ -152,39 +484,14 @@ function equivalentConfigCommandProjection(resolve) {
|
|
|
152
484
|
equivalentCommandTokens: (selection) => buildEquivalentConfigCommandTokens(resolve(selection)),
|
|
153
485
|
};
|
|
154
486
|
}
|
|
155
|
-
function configSetEquivalentOptions(selection, candidates, rawOptions) {
|
|
156
|
-
const field = candidates.find((entry) => entry.pluginName === selection.plugins[0])
|
|
157
|
-
?.configSchema?.[selection.key ?? ''];
|
|
158
|
-
const placeholder = configFieldPlaceholder(field);
|
|
159
|
-
return {
|
|
160
|
-
command: 'set',
|
|
161
|
-
plugin: selection.plugins[0],
|
|
162
|
-
key: selection.key,
|
|
163
|
-
value: placeholder
|
|
164
|
-
? rawOptions.valueJson ? JSON.stringify(placeholder) : placeholder
|
|
165
|
-
: formatConfigCommandValue(selection.value, rawOptions.valueJson === true),
|
|
166
|
-
scope: selection.scope ?? 'user',
|
|
167
|
-
projectLayer: selection.projectLayer,
|
|
168
|
-
valueJson: rawOptions.valueJson,
|
|
169
|
-
};
|
|
170
|
-
}
|
|
171
|
-
function configFieldPlaceholder(field) {
|
|
172
|
-
if (field?.sensitive)
|
|
173
|
-
return '<sensitive-value>';
|
|
174
|
-
if (field?.type === 'file')
|
|
175
|
-
return '<file-path>';
|
|
176
|
-
if (field?.type === 'directory')
|
|
177
|
-
return '<directory-path>';
|
|
178
|
-
return undefined;
|
|
179
|
-
}
|
|
180
487
|
export function buildEquivalentConfigCommandTokens(options) {
|
|
181
488
|
return [
|
|
182
489
|
'aw',
|
|
183
490
|
'config',
|
|
184
491
|
options.command,
|
|
185
492
|
...optionTokens('--scope', options.scope),
|
|
186
|
-
...(
|
|
187
|
-
...(
|
|
493
|
+
...optionTokens('--value-json', options.valueJson),
|
|
494
|
+
...optionTokens('--preset', options.preset),
|
|
188
495
|
...(options.confirmed ? ['--yes'] : []),
|
|
189
496
|
'--',
|
|
190
497
|
options.plugin,
|
|
@@ -207,7 +514,6 @@ async function loadWizardCandidates(context, rawOptions) {
|
|
|
207
514
|
cwd: context.cwd,
|
|
208
515
|
scope: rawOptions.scope,
|
|
209
516
|
platform: rawOptions.platform,
|
|
210
|
-
includeCatalogOnly: true,
|
|
211
517
|
}, context);
|
|
212
518
|
return toWizardCandidates(loaded.items);
|
|
213
519
|
}
|
|
@@ -235,7 +541,6 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
235
541
|
cwd: context.cwd,
|
|
236
542
|
env: context.env,
|
|
237
543
|
scope: location.scope,
|
|
238
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
239
544
|
});
|
|
240
545
|
for (const store of stores) {
|
|
241
546
|
const keys = Object.keys(store.values);
|
|
@@ -243,12 +548,11 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
243
548
|
continue;
|
|
244
549
|
const existing = storesByPlugin.get(store.pluginId) ?? {
|
|
245
550
|
sourceId: store.sourceId,
|
|
246
|
-
|
|
551
|
+
...(store.binding.kind === 'source'
|
|
552
|
+
? { sourceIdentity: store.binding.sourceIdentity }
|
|
553
|
+
: {}),
|
|
247
554
|
keys: new Set(),
|
|
248
555
|
};
|
|
249
|
-
if (existing.sourceIdentity !== store.sourceIdentity) {
|
|
250
|
-
throw new Error(`sourceChanged: ${store.pluginId} config stores have different source identities.`);
|
|
251
|
-
}
|
|
252
556
|
for (const key of keys)
|
|
253
557
|
existing.keys.add(key);
|
|
254
558
|
storesByPlugin.set(store.pluginId, existing);
|
|
@@ -260,26 +564,53 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
260
564
|
pluginName: pluginId,
|
|
261
565
|
pluginId,
|
|
262
566
|
sourceId: store.sourceId,
|
|
263
|
-
sourceIdentity: store.sourceIdentity,
|
|
567
|
+
...(store.sourceIdentity ? { sourceIdentity: store.sourceIdentity } : {}),
|
|
264
568
|
targets: [],
|
|
265
569
|
configKeys: [...store.keys].sort((left, right) => left.localeCompare(right)),
|
|
266
570
|
}));
|
|
267
571
|
}
|
|
268
572
|
function configReadStoreLocations(rawOptions) {
|
|
269
|
-
if (rawOptions.local)
|
|
270
|
-
return [{ scope: 'project', projectLayer: 'local' }];
|
|
271
573
|
if (rawOptions.scope === 'user')
|
|
272
|
-
return [{ scope: 'user'
|
|
574
|
+
return [{ scope: 'user' }];
|
|
273
575
|
if (rawOptions.scope === 'project')
|
|
274
|
-
return [{ scope: 'project'
|
|
576
|
+
return [{ scope: 'project' }];
|
|
275
577
|
return [
|
|
276
|
-
{ scope: 'user'
|
|
277
|
-
{ scope: 'project'
|
|
278
|
-
{ scope: 'project', projectLayer: 'local' },
|
|
578
|
+
{ scope: 'user' },
|
|
579
|
+
{ scope: 'project' },
|
|
279
580
|
];
|
|
280
581
|
}
|
|
281
582
|
function overallResultState(value) {
|
|
282
|
-
return value.overallState;
|
|
583
|
+
return value.overallState === 'succeeded' ? 'succeeded' : 'failed';
|
|
584
|
+
}
|
|
585
|
+
async function resolveStoredConfigResetIdentity(options) {
|
|
586
|
+
const parsed = parsePluginId(options.selector);
|
|
587
|
+
if (parsed.sourceId) {
|
|
588
|
+
return {
|
|
589
|
+
pluginName: parsed.pluginName,
|
|
590
|
+
pluginId: options.selector,
|
|
591
|
+
sourceId: parsed.sourceId,
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
const matches = (await listNamespacedPluginConfigStores({
|
|
595
|
+
cwd: options.context.cwd,
|
|
596
|
+
env: options.context.env,
|
|
597
|
+
scope: options.scope,
|
|
598
|
+
})).filter((store) => store.pluginName === parsed.pluginName);
|
|
599
|
+
if (matches.length === 0) {
|
|
600
|
+
throw new Error(`configStoreMissing: ${options.selector} has no config in the selected store.`);
|
|
601
|
+
}
|
|
602
|
+
if (matches.length > 1) {
|
|
603
|
+
throw new Error(`configTargetAmbiguous: ${options.selector} exists in multiple source namespaces: ${matches.map((store) => store.pluginId).join(', ')}. Use a full pluginId.`);
|
|
604
|
+
}
|
|
605
|
+
const [match] = matches;
|
|
606
|
+
return {
|
|
607
|
+
pluginName: match.pluginName,
|
|
608
|
+
pluginId: match.pluginId,
|
|
609
|
+
sourceId: match.sourceId,
|
|
610
|
+
...(match.binding.kind === 'source'
|
|
611
|
+
? { sourceIdentity: match.binding.sourceIdentity }
|
|
612
|
+
: { logicalIdentity: match.binding.logicalIdentity }),
|
|
613
|
+
};
|
|
283
614
|
}
|
|
284
615
|
async function resolveStoredOnlyConfigIdentity(options) {
|
|
285
616
|
const parsed = parsePluginId(options.selector);
|
|
@@ -289,33 +620,43 @@ async function resolveStoredOnlyConfigIdentity(options) {
|
|
|
289
620
|
cwd: options.context.cwd,
|
|
290
621
|
env: options.context.env,
|
|
291
622
|
scope: location.scope,
|
|
292
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
293
623
|
})))).flat().filter((store) => store.pluginId === options.selector);
|
|
294
624
|
if (stores.length === 0)
|
|
295
625
|
throw new Error(`Plugin "${options.selector}" does not have a namespaced config store.`);
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
626
|
+
const sourceBindings = stores.flatMap((store) => store.binding.kind === 'source'
|
|
627
|
+
? [store.binding.sourceIdentity] : []);
|
|
628
|
+
const catalogBindings = stores.flatMap((store) => store.binding.kind === 'catalog'
|
|
629
|
+
? [store.binding.logicalIdentity] : []);
|
|
630
|
+
if (new Set(sourceBindings).size > 1 || new Set(catalogBindings).size > 1) {
|
|
631
|
+
throw new Error(`identityMismatch: ${options.selector} config stores have different bindings.`);
|
|
632
|
+
}
|
|
633
|
+
const currentSource = await withResolvedMultiSourceCatalog({
|
|
301
634
|
cliVersion: resolveCliVersion(),
|
|
302
|
-
freshnessPolicy: 'cacheFirst',
|
|
303
635
|
sourceIds: [parsed.sourceId],
|
|
304
636
|
env: options.context.env,
|
|
305
637
|
consume: async (catalog) => {
|
|
306
638
|
const source = catalog.sources.find((entry) => entry.sourceId === parsed.sourceId);
|
|
307
|
-
if (!source?.resolution)
|
|
639
|
+
if (!source?.resolution) {
|
|
308
640
|
throw source?.error ?? new Error(`Catalog source "${parsed.sourceId}" is unavailable.`);
|
|
309
|
-
if (source.resolution.sourceIdentity !== sourceIdentity) {
|
|
310
|
-
throw new Error(`sourceChanged: ${options.selector} config source identity does not match the current source.`);
|
|
311
641
|
}
|
|
642
|
+
return {
|
|
643
|
+
sourceIdentity: source.resolution.sourceIdentity,
|
|
644
|
+
logicalIdentity: source.resolution.logicalIdentity,
|
|
645
|
+
};
|
|
312
646
|
},
|
|
313
647
|
});
|
|
648
|
+
if (sourceBindings[0] && sourceBindings[0] !== currentSource.sourceIdentity) {
|
|
649
|
+
throw new Error(`identityMismatch: ${options.selector} user config does not match the current source identity.`);
|
|
650
|
+
}
|
|
651
|
+
if (catalogBindings[0] && catalogBindings[0] !== currentSource.logicalIdentity) {
|
|
652
|
+
throw new Error(`identityMismatch: ${options.selector} project config does not match the current Catalog logical identity.`);
|
|
653
|
+
}
|
|
314
654
|
return {
|
|
315
655
|
pluginName: parsed.pluginName,
|
|
316
656
|
pluginId: options.selector,
|
|
317
657
|
sourceId: parsed.sourceId,
|
|
318
|
-
sourceIdentity,
|
|
658
|
+
sourceIdentity: currentSource.sourceIdentity,
|
|
659
|
+
logicalIdentity: currentSource.logicalIdentity,
|
|
319
660
|
};
|
|
320
661
|
}
|
|
321
662
|
async function resolveMultiSourceConfigRead(options) {
|
|
@@ -324,26 +665,21 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
324
665
|
env: options.context.env,
|
|
325
666
|
});
|
|
326
667
|
assertCatalogSourceReferencesSupported(inventory);
|
|
327
|
-
const projectLayer = resolveConfigProjectLayer(options.rawOptions);
|
|
328
668
|
return withResolvedCatalogPlugin({
|
|
329
669
|
selector: options.selector,
|
|
330
670
|
cliVersion: resolveCliVersion(),
|
|
331
|
-
freshnessPolicy: 'cacheFirst',
|
|
332
671
|
env: options.context.env,
|
|
333
672
|
consume: async ({ pluginId, source, plugin }) => {
|
|
334
673
|
const result = await resolveConfigRead({
|
|
335
674
|
pluginName: plugin.manifest.name,
|
|
336
675
|
plugin,
|
|
337
|
-
scope: options.rawOptions.
|
|
338
|
-
? 'project'
|
|
339
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
340
|
-
projectLayer,
|
|
676
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
341
677
|
cwd: options.context.cwd,
|
|
342
678
|
env: options.context.env,
|
|
343
679
|
});
|
|
344
680
|
if (options.key !== undefined) {
|
|
345
681
|
const field = findConfigFieldEntry(result.fields, options.key);
|
|
346
|
-
if (!field && plugin.manifest.config?.
|
|
682
|
+
if (!field && plugin.manifest.config?.fields?.[options.key] === undefined) {
|
|
347
683
|
throw new Error(`Unknown config key "${options.key}".`);
|
|
348
684
|
}
|
|
349
685
|
if (field)
|
|
@@ -369,12 +705,10 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
369
705
|
const result = await resolveConfigRead({
|
|
370
706
|
sourceId: stored.sourceId,
|
|
371
707
|
sourceIdentity: stored.sourceIdentity,
|
|
708
|
+
logicalIdentity: stored.logicalIdentity,
|
|
372
709
|
pluginName: stored.pluginName,
|
|
373
710
|
plugin: null,
|
|
374
|
-
scope: options.rawOptions.
|
|
375
|
-
? 'project'
|
|
376
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
377
|
-
projectLayer,
|
|
711
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
378
712
|
cwd: options.context.cwd,
|
|
379
713
|
env: options.context.env,
|
|
380
714
|
});
|
|
@@ -387,36 +721,52 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
387
721
|
return { ...stored, result };
|
|
388
722
|
});
|
|
389
723
|
}
|
|
390
|
-
|
|
724
|
+
export function createManagedCodexAuthorizer(rawOptions, context) {
|
|
725
|
+
if (rawOptions.allowManagedCodexInstall === true)
|
|
726
|
+
return async () => true;
|
|
727
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
728
|
+
|| !context.prompt.confirm)
|
|
729
|
+
return undefined;
|
|
730
|
+
return async () => {
|
|
731
|
+
const response = await context.prompt.confirm({
|
|
732
|
+
message: '系统中没有可用的 Codex CLI。是否获取本次操作所需的 AW-managed Codex runtime?',
|
|
733
|
+
defaultValue: false,
|
|
734
|
+
});
|
|
735
|
+
return !response.cancelled && response.value === true;
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
async function executeWriteCommand(command, pluginNames, rawOptions, context, directCli = false) {
|
|
391
739
|
const raw = { cwd: context.cwd, ...rawOptions };
|
|
392
|
-
const commandOptions = command === 'install'
|
|
740
|
+
const commandOptions = normalizeWriteRequest(() => command === 'install'
|
|
393
741
|
? normalizeInstallCommandOptions(raw)
|
|
394
|
-
: command === '
|
|
395
|
-
?
|
|
396
|
-
: command === '
|
|
397
|
-
?
|
|
398
|
-
:
|
|
399
|
-
? normalizeCleanupCommandOptions(raw)
|
|
400
|
-
: normalizeReinstallCommandOptions(raw);
|
|
742
|
+
: command === 'uninstall'
|
|
743
|
+
? normalizeUninstallCommandOptions(raw)
|
|
744
|
+
: command === 'cleanup'
|
|
745
|
+
? normalizeCleanupCommandOptions(raw)
|
|
746
|
+
: normalizeReinstallCommandOptions(raw));
|
|
401
747
|
await emitCommandEvent(context, {
|
|
402
748
|
type: 'options:normalized',
|
|
403
749
|
data: { plugins: pluginNames, options: commandOptions },
|
|
404
750
|
});
|
|
751
|
+
const managedCodexAuthorizer = createManagedCodexAuthorizer(rawOptions, context);
|
|
752
|
+
const runtime = {
|
|
753
|
+
...context,
|
|
754
|
+
directCli,
|
|
755
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
756
|
+
...(managedCodexAuthorizer ? { managedCodexAuthorizer } : {}),
|
|
757
|
+
};
|
|
405
758
|
switch (command) {
|
|
406
|
-
case 'install': return installCommand(pluginNames, commandOptions,
|
|
407
|
-
case '
|
|
408
|
-
case '
|
|
409
|
-
case '
|
|
410
|
-
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, context);
|
|
759
|
+
case 'install': return installCommand(pluginNames, commandOptions, runtime);
|
|
760
|
+
case 'uninstall': return uninstallCommand(pluginNames, commandOptions, runtime);
|
|
761
|
+
case 'cleanup': return cleanupCommand(pluginNames, commandOptions, runtime);
|
|
762
|
+
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, runtime);
|
|
411
763
|
}
|
|
412
764
|
}
|
|
413
765
|
async function runWriteCommandAction(command, pluginNames, rawOptions, context) {
|
|
414
766
|
if ((command === 'cleanup' || command === 'reinstall') && pluginNames.length > 1) {
|
|
415
|
-
throw new
|
|
767
|
+
throw new WriteCommandRequestError(`${command} 命令当前只支持单个插件目标。`);
|
|
416
768
|
}
|
|
417
|
-
|
|
418
|
-
assertUpgradeAllConflict(pluginNames, rawOptions.all === true);
|
|
419
|
-
const missingPlugin = pluginNames.length === 0 && !(command === 'upgrade' && rawOptions.all === true);
|
|
769
|
+
const missingPlugin = pluginNames.length === 0;
|
|
420
770
|
const missingPlatform = rawOptions.platform === undefined;
|
|
421
771
|
const missingScope = command === 'cleanup' && rawOptions.scope === undefined;
|
|
422
772
|
const missing = missingPlugin || missingPlatform || missingScope;
|
|
@@ -431,17 +781,16 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
|
|
|
431
781
|
if (!missing) {
|
|
432
782
|
return {
|
|
433
783
|
cancelled: false,
|
|
434
|
-
result: await executeWriteCommand(command, pluginNames, rawOptions, context),
|
|
784
|
+
result: await executeWriteCommand(command, pluginNames, rawOptions, context, true),
|
|
435
785
|
};
|
|
436
786
|
}
|
|
437
787
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
438
|
-
throw new
|
|
788
|
+
throw new WriteCommandRequestError(writeCommandUsage(command));
|
|
439
789
|
}
|
|
440
790
|
const loaded = await loadConsoleItemsResult({
|
|
441
791
|
cwd: context.cwd,
|
|
442
792
|
scope: rawOptions.scope,
|
|
443
793
|
platform: rawOptions.platform,
|
|
444
|
-
includeCatalogOnly: true,
|
|
445
794
|
}, context);
|
|
446
795
|
if (loaded.catalogUnavailable) {
|
|
447
796
|
throw new Error('插件目录不可用。请运行 `aw init` 或 `aw init --force`,或使用完整参数重试。');
|
|
@@ -587,34 +936,77 @@ async function runActionWithContext(context, action) {
|
|
|
587
936
|
function writeJsonReceipt(write, payload) {
|
|
588
937
|
writeLine(write, JSON.stringify(payload, null, 2));
|
|
589
938
|
}
|
|
590
|
-
function configLayerLabel(scope
|
|
939
|
+
function configLayerLabel(scope) {
|
|
591
940
|
if (scope === 'user') {
|
|
592
941
|
return '个人';
|
|
593
942
|
}
|
|
594
|
-
return
|
|
943
|
+
return '当前项目';
|
|
595
944
|
}
|
|
596
945
|
function writeConfigApplyNotice(write, receipt) {
|
|
597
|
-
|
|
598
|
-
|
|
946
|
+
const sanitizeMessage = (message) => redactString(message)
|
|
947
|
+
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
948
|
+
.replace(/(?:file:\/\/)?(?:\/[\w.@+-]+){2,}/gu, '[REDACTED PATH]')
|
|
949
|
+
.replace(/[A-Za-z]:\\(?:[^\s\\]+\\)+[^\s\\]*/gu, '[REDACTED PATH]');
|
|
950
|
+
const writeTargetFailures = () => {
|
|
951
|
+
for (const entry of receipt.apply.targetResults.filter((target) => target.state === 'failed' || target.state === 'skipped')) {
|
|
952
|
+
const reason = entry.message
|
|
953
|
+
? `${entry.errorCode ? `[${entry.errorCode}] ` : ''}${sanitizeMessage(entry.message)}`
|
|
954
|
+
: entry.errorCode
|
|
955
|
+
? `失败原因:${entry.errorCode}。`
|
|
956
|
+
: '未提供安全失败原因。';
|
|
957
|
+
const command = `aw reinstall ${receipt.plugin} -p ${entry.target.platform} -s ${entry.target.scope}`;
|
|
958
|
+
const recovery = entry.errorCode === 'invalidConfig'
|
|
959
|
+
? ' 请修复无效配置后运行 aw sync。'
|
|
960
|
+
: entry.errorCode === 'preApplyAuthorizationRequired'
|
|
961
|
+
|| entry.errorCode === 'sharedNativeConfigApplyConfirmationRequired'
|
|
962
|
+
|| entry.errorCode === 'sharedNativeImpactAuthorizationRequired'
|
|
963
|
+
? ` 请运行 ${command} --yes 重试。`
|
|
964
|
+
: entry.state === 'failed'
|
|
965
|
+
? ` 请在解决失败原因后运行 ${command}。`
|
|
966
|
+
: '';
|
|
967
|
+
writeLine(write, `${entry.target.platform}/${entry.target.scope}:${reason}${recovery}`);
|
|
968
|
+
}
|
|
969
|
+
};
|
|
970
|
+
const targetResults = receipt.apply.targetResults;
|
|
971
|
+
if (receipt.apply.state === 'skipped') {
|
|
972
|
+
const message = receipt.apply.reason === 'noConfigChange'
|
|
599
973
|
? '配置内容没有变化,因此没有运行 reinstall。'
|
|
600
|
-
:
|
|
974
|
+
: receipt.apply.reason === 'noEffectiveConfigChange'
|
|
975
|
+
? '配置存储已更新,但有效配置没有变化,因此没有运行 reinstall。'
|
|
976
|
+
: receipt.apply.reason === 'notRequested'
|
|
977
|
+
? '配置已保存,但未请求应用配置。'
|
|
978
|
+
: '配置已保存。当前没有可见的 AW 安装目标,因此没有应用配置。';
|
|
601
979
|
writeLine(write, message);
|
|
602
980
|
}
|
|
603
|
-
else {
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}
|
|
981
|
+
else if (receipt.apply.state === 'unavailable') {
|
|
982
|
+
const fallbackMessages = {
|
|
983
|
+
invalidConfig: '可见目标的有效配置无效。',
|
|
984
|
+
schemaUnavailable: '配置 schema 不可用。',
|
|
985
|
+
sourceUnavailable: '插件来源不可用。',
|
|
986
|
+
effectiveConfigUnavailable: '无法读取有效配置。',
|
|
987
|
+
targetDiscoveryFailed: '无法发现可应用配置的目标。',
|
|
988
|
+
};
|
|
989
|
+
const detail = receipt.apply.error
|
|
990
|
+
? `${receipt.apply.error.code}:${sanitizeMessage(receipt.apply.error.message)}`
|
|
991
|
+
: `${receipt.apply.reason}:${fallbackMessages[receipt.apply.reason]}`;
|
|
992
|
+
const recovery = receipt.apply.reason === 'invalidConfig'
|
|
993
|
+
? '请修复无效配置后运行 aw sync。'
|
|
994
|
+
: receipt.apply.reason === 'effectiveConfigUnavailable'
|
|
995
|
+
? '请修复配置后运行 aw sync。'
|
|
996
|
+
: receipt.apply.reason === 'schemaUnavailable' || receipt.apply.reason === 'sourceUnavailable'
|
|
997
|
+
? '请修复插件来源或配置后运行 aw sync。'
|
|
998
|
+
: '请修复来源或配置后运行 aw sync。';
|
|
999
|
+
writeLine(write, `配置已保存,但当前无法应用配置。${detail} ${recovery}`);
|
|
1000
|
+
writeTargetFailures();
|
|
611
1001
|
}
|
|
612
|
-
|
|
613
|
-
|
|
1002
|
+
else {
|
|
1003
|
+
const completed = targetResults.filter((entry) => entry.state === 'completed').length;
|
|
1004
|
+
const failed = targetResults.filter((entry) => entry.state === 'failed').length;
|
|
1005
|
+
const skipped = targetResults.filter((entry) => entry.state === 'skipped').length;
|
|
1006
|
+
writeLine(write, `配置已保存。已重装 ${completed} 个当前可见目标;失败 ${failed} 个;跳过 ${skipped} 个。`);
|
|
1007
|
+
writeTargetFailures();
|
|
614
1008
|
}
|
|
615
|
-
|
|
616
|
-
function writeProjectLocalConfigNotice(write) {
|
|
617
|
-
writeLine(write, '当前显示的是当前项目的本机私有覆盖层,不作为 repo-visible artifact 渲染输入。');
|
|
1009
|
+
writeWarnings(write, receipt.warnings);
|
|
618
1010
|
}
|
|
619
1011
|
function renderConfigFieldState(field) {
|
|
620
1012
|
if (field.valueState === 'invalid') {
|
|
@@ -634,13 +1026,15 @@ function writeConfigReadHuman(write, resolved, pluginName) {
|
|
|
634
1026
|
}
|
|
635
1027
|
if (field.kind === 'manifest' && field.valueState === 'invalid') {
|
|
636
1028
|
const sourceScope = field.sourceLayer === 'project'
|
|
637
|
-
? '
|
|
638
|
-
:
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1029
|
+
? 'project'
|
|
1030
|
+
: 'user';
|
|
1031
|
+
const definition = resolved.fieldDefinitions?.[field.key];
|
|
1032
|
+
if (definition) {
|
|
1033
|
+
writeLine(write, ` ${formatPluginConfigSetRecoveryCommand(pluginName, field.key, definition, sourceScope)}`);
|
|
1034
|
+
}
|
|
1035
|
+
const scopeOption = ` -s ${sourceScope}`;
|
|
1036
|
+
writeLine(write, ` aw config unset ${pluginName} ${field.key}${scopeOption}`);
|
|
1037
|
+
writeLine(write, ` aw config reset ${pluginName}${scopeOption}`);
|
|
644
1038
|
}
|
|
645
1039
|
}
|
|
646
1040
|
}
|
|
@@ -674,9 +1068,176 @@ export function buildProgram(options = {}) {
|
|
|
674
1068
|
const plugin = program
|
|
675
1069
|
.command('plugin')
|
|
676
1070
|
.description('Create and validate AW plugin source');
|
|
1071
|
+
const self = program
|
|
1072
|
+
.command('self')
|
|
1073
|
+
.description('Describe and check this AW executable');
|
|
1074
|
+
self
|
|
1075
|
+
.command('describe')
|
|
1076
|
+
.description('Describe implemented AW capabilities')
|
|
1077
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1078
|
+
.action(() => {
|
|
1079
|
+
writeJsonReceipt(io.stdout, describeCurrentAw(resolveCliVersion()));
|
|
1080
|
+
});
|
|
1081
|
+
self
|
|
1082
|
+
.command('check')
|
|
1083
|
+
.description('Check nearby plugin requirements against this AW executable')
|
|
1084
|
+
.option('--from <path>', 'start discovery from this file or directory')
|
|
1085
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1086
|
+
.action(async (rawOptions) => {
|
|
1087
|
+
const result = await checkCurrentAw({
|
|
1088
|
+
awVersion: resolveCliVersion(),
|
|
1089
|
+
from: path.resolve(cwd, rawOptions.from ?? '.'),
|
|
1090
|
+
});
|
|
1091
|
+
writeJsonReceipt(io.stdout, result);
|
|
1092
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1093
|
+
});
|
|
1094
|
+
plugin
|
|
1095
|
+
.command('capabilities')
|
|
1096
|
+
.description('Show the current plugin manifest authoring surface')
|
|
1097
|
+
.option('--surface <surface>', 'manifest | build-config | extensions | slash-commands | mcp-apps | config | pre-apply | artifacts')
|
|
1098
|
+
.option('--json', 'emit one machine-readable JSON object', false)
|
|
1099
|
+
.action((rawOptions) => {
|
|
1100
|
+
try {
|
|
1101
|
+
const surface = rawOptions.surface === undefined
|
|
1102
|
+
? undefined
|
|
1103
|
+
: parsePluginCapabilitySurface(rawOptions.surface);
|
|
1104
|
+
const result = getPluginCapabilitiesResult({
|
|
1105
|
+
awVersion: resolveCliVersion(),
|
|
1106
|
+
...(surface ? { surface } : {}),
|
|
1107
|
+
});
|
|
1108
|
+
if (rawOptions.json)
|
|
1109
|
+
writeJsonReceipt(io.stdout, result);
|
|
1110
|
+
else
|
|
1111
|
+
for (const line of renderPluginCapabilities(result))
|
|
1112
|
+
writeLine(io.stdout, line);
|
|
1113
|
+
}
|
|
1114
|
+
catch (error) {
|
|
1115
|
+
writeLine(io.stderr, error instanceof Error ? error.message : String(error));
|
|
1116
|
+
commandExitState.exitCode = 1;
|
|
1117
|
+
}
|
|
1118
|
+
});
|
|
1119
|
+
plugin
|
|
1120
|
+
.command('requirements')
|
|
1121
|
+
.description('Inspect or update effective AW capabilities required by a plugin')
|
|
1122
|
+
.argument('<plugin-directory>', 'plugin source directory')
|
|
1123
|
+
.option('--workspace-root <root>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1124
|
+
.option('--add <capability>', 'add one declared AW capability')
|
|
1125
|
+
.option('--remove <capability>', 'remove one declared AW capability')
|
|
1126
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1127
|
+
.action(async (pluginDirectory, rawOptions) => {
|
|
1128
|
+
try {
|
|
1129
|
+
const result = await inspectPluginRequirements({
|
|
1130
|
+
pluginDirectory,
|
|
1131
|
+
...(rawOptions.workspaceRoot ? { workspaceRoot: rawOptions.workspaceRoot } : {}),
|
|
1132
|
+
...(rawOptions.add ? { add: rawOptions.add } : {}),
|
|
1133
|
+
...(rawOptions.remove ? { remove: rawOptions.remove } : {}),
|
|
1134
|
+
cwd,
|
|
1135
|
+
});
|
|
1136
|
+
writeJsonReceipt(io.stdout, result);
|
|
1137
|
+
if (result.observations.some((observation) => observation.blocking)) {
|
|
1138
|
+
commandExitState.exitCode = 1;
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
catch (error) {
|
|
1142
|
+
writeJsonReceipt(io.stdout, {
|
|
1143
|
+
schemaVersion: 1,
|
|
1144
|
+
command: 'plugin:requirements',
|
|
1145
|
+
ok: false,
|
|
1146
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1147
|
+
});
|
|
1148
|
+
commandExitState.exitCode = 1;
|
|
1149
|
+
}
|
|
1150
|
+
});
|
|
677
1151
|
const skill = program
|
|
678
1152
|
.command('skill')
|
|
679
1153
|
.description('Install, materialize, or validate Agent Skills');
|
|
1154
|
+
const skillEval = skill
|
|
1155
|
+
.command('eval')
|
|
1156
|
+
.description('Prepare or diagnose deterministic Agent Skill Eval inputs');
|
|
1157
|
+
skillEval
|
|
1158
|
+
.command('doctor')
|
|
1159
|
+
.description('Inspect Agent Skill Eval provider readiness without model execution')
|
|
1160
|
+
.requiredOption('--json', 'emit one provider doctor JSON object')
|
|
1161
|
+
.action(async () => {
|
|
1162
|
+
try {
|
|
1163
|
+
writeJsonReceipt(io.stdout, await doctorEvalProviders({ sourceEnv: env }));
|
|
1164
|
+
}
|
|
1165
|
+
catch (error) {
|
|
1166
|
+
writeJsonReceipt(io.stdout, {
|
|
1167
|
+
ok: false,
|
|
1168
|
+
error: redactString(error instanceof Error ? error.message : String(error)),
|
|
1169
|
+
});
|
|
1170
|
+
commandExitState.exitCode = 1;
|
|
1171
|
+
}
|
|
1172
|
+
});
|
|
1173
|
+
skillEval
|
|
1174
|
+
.command('prepare')
|
|
1175
|
+
.description('Prepare one complete Agent Skill Eval input directory')
|
|
1176
|
+
.argument('<plugin>', 'canonical Workspace plugin name')
|
|
1177
|
+
.argument('<skill>', 'owner Skill name')
|
|
1178
|
+
.option('--suite <suite>', 'Eval suite ID')
|
|
1179
|
+
.option('--profile <profile>', 'Eval profile ID')
|
|
1180
|
+
.option('--workspace-root <root>', 'Catalog Workspace root')
|
|
1181
|
+
.option('--split <split>', 'case split filter')
|
|
1182
|
+
.option('--case <id>', 'case ID filter')
|
|
1183
|
+
.option('--runs <count>', 'runs per selected case')
|
|
1184
|
+
.option('--timeout-ms <milliseconds>', 'timeout for each provider attempt')
|
|
1185
|
+
.option('--baseline <mode>', 'append without-skill comparison')
|
|
1186
|
+
.option('--previous-version <runtime-skill-root>', 'append a previous-version comparison')
|
|
1187
|
+
.option('--keep-workspace', 'retain the preparation materialization workspace', false)
|
|
1188
|
+
.requiredOption('--output <spec-directory>', 'new EvalSpec directory')
|
|
1189
|
+
.requiredOption('--json', 'emit one preparation receipt JSON object')
|
|
1190
|
+
.action(async (pluginName, skillName, rawOptions) => {
|
|
1191
|
+
try {
|
|
1192
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1193
|
+
cwd,
|
|
1194
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1195
|
+
mode: 'existing',
|
|
1196
|
+
env,
|
|
1197
|
+
});
|
|
1198
|
+
const runs = rawOptions.runs === undefined
|
|
1199
|
+
? undefined
|
|
1200
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.runs) ? Number(rawOptions.runs) : Number.NaN);
|
|
1201
|
+
const timeoutMs = rawOptions.timeoutMs === undefined
|
|
1202
|
+
? undefined
|
|
1203
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.timeoutMs) ? Number(rawOptions.timeoutMs) : Number.NaN);
|
|
1204
|
+
const receipt = await prepareSkillEval({
|
|
1205
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
1206
|
+
workspaceRootResolvedFrom: workspace.workspaceRootResolvedFrom,
|
|
1207
|
+
pluginName,
|
|
1208
|
+
skillName,
|
|
1209
|
+
...(rawOptions.suite === undefined ? {} : { suiteId: rawOptions.suite }),
|
|
1210
|
+
...(rawOptions.profile === undefined ? {} : { profileId: rawOptions.profile }),
|
|
1211
|
+
output: rawOptions.output,
|
|
1212
|
+
cwd,
|
|
1213
|
+
env,
|
|
1214
|
+
...(rawOptions.split === undefined ? {} : { split: rawOptions.split }),
|
|
1215
|
+
...(rawOptions.case === undefined ? {} : { caseId: rawOptions.case }),
|
|
1216
|
+
...(runs === undefined ? {} : { runs }),
|
|
1217
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
1218
|
+
...(rawOptions.baseline === undefined ? {} : {
|
|
1219
|
+
baseline: rawOptions.baseline,
|
|
1220
|
+
}),
|
|
1221
|
+
...(rawOptions.previousVersion === undefined ? {} : {
|
|
1222
|
+
previousVersion: rawOptions.previousVersion,
|
|
1223
|
+
}),
|
|
1224
|
+
...(rawOptions.keepWorkspace === true ? { keepWorkspace: true } : {}),
|
|
1225
|
+
});
|
|
1226
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1227
|
+
}
|
|
1228
|
+
catch (error) {
|
|
1229
|
+
writeJsonReceipt(io.stdout, {
|
|
1230
|
+
schemaVersion: 1,
|
|
1231
|
+
command: 'skill:eval:prepare',
|
|
1232
|
+
ok: false,
|
|
1233
|
+
errors: [{
|
|
1234
|
+
code: 'evalPreparationFailed',
|
|
1235
|
+
message: redactString(error instanceof Error ? error.message : String(error)),
|
|
1236
|
+
}],
|
|
1237
|
+
});
|
|
1238
|
+
commandExitState.exitCode = 1;
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
680
1241
|
const review = program
|
|
681
1242
|
.command('review')
|
|
682
1243
|
.description('Publish and inspect immutable review records');
|
|
@@ -685,6 +1246,81 @@ export function buildProgram(options = {}) {
|
|
|
685
1246
|
recordDir: reviewRecordDir(repoRoot, record),
|
|
686
1247
|
manifest: record.manifest,
|
|
687
1248
|
});
|
|
1249
|
+
review
|
|
1250
|
+
.command('inspect')
|
|
1251
|
+
.description('Inspect current AW Review source and materialization facts')
|
|
1252
|
+
.argument('<target>', 'Catalog Workspace, Plugin, or source Skill path')
|
|
1253
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1254
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1255
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']))
|
|
1256
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']))
|
|
1257
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1258
|
+
.option('--materialization <receipt>', 'validate one aw-source-binding receipt', collectUniqueOption, [])
|
|
1259
|
+
.addOption(strictValueOption('--view <view>', 'select review or release view', ['review', 'release']).default('review'))
|
|
1260
|
+
.option('--json', 'emit one Review inspection JSON object', false)
|
|
1261
|
+
.action(async (target, rawOptions) => {
|
|
1262
|
+
try {
|
|
1263
|
+
const receipt = await inspectReviewTarget({
|
|
1264
|
+
cwd,
|
|
1265
|
+
target,
|
|
1266
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1267
|
+
? {}
|
|
1268
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1269
|
+
skills: rawOptions.skill,
|
|
1270
|
+
...(rawOptions.platform === undefined ? {} : { platform: rawOptions.platform }),
|
|
1271
|
+
...(rawOptions.scope === undefined ? {} : { scope: rawOptions.scope }),
|
|
1272
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1273
|
+
materializations: [...new Set(rawOptions.materialization
|
|
1274
|
+
.map((entry) => path.resolve(cwd, entry)))],
|
|
1275
|
+
view: rawOptions.view,
|
|
1276
|
+
env,
|
|
1277
|
+
});
|
|
1278
|
+
if (rawOptions.json)
|
|
1279
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1280
|
+
else
|
|
1281
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1282
|
+
commandExitState.exitCode = 0;
|
|
1283
|
+
}
|
|
1284
|
+
catch (error) {
|
|
1285
|
+
const receipt = createReviewInspectionFailure(error, rawOptions.view);
|
|
1286
|
+
if (rawOptions.json)
|
|
1287
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1288
|
+
else
|
|
1289
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1290
|
+
commandExitState.exitCode = getReviewInspectionExitCode(error);
|
|
1291
|
+
}
|
|
1292
|
+
});
|
|
1293
|
+
review
|
|
1294
|
+
.command('prepare')
|
|
1295
|
+
.description('Prepare deterministic Skill finals for AW Review')
|
|
1296
|
+
.argument('<target>', 'Plugin or source Skill path')
|
|
1297
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1298
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1299
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']).makeOptionMandatory())
|
|
1300
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']).makeOptionMandatory())
|
|
1301
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1302
|
+
.addOption(strictValueOption('--out <new-dir>', 'new output directory').makeOptionMandatory())
|
|
1303
|
+
.option('--json', 'emit one Review preparation JSON object', false)
|
|
1304
|
+
.action(async (target, rawOptions) => {
|
|
1305
|
+
const result = await prepareReviewTarget({
|
|
1306
|
+
cwd,
|
|
1307
|
+
target,
|
|
1308
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1309
|
+
? {}
|
|
1310
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1311
|
+
skills: rawOptions.skill,
|
|
1312
|
+
platform: rawOptions.platform,
|
|
1313
|
+
scope: rawOptions.scope,
|
|
1314
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1315
|
+
out: rawOptions.out,
|
|
1316
|
+
env,
|
|
1317
|
+
});
|
|
1318
|
+
if (rawOptions.json)
|
|
1319
|
+
writeJsonReceipt(io.stdout, result.receipt);
|
|
1320
|
+
else
|
|
1321
|
+
renderReviewPreparation(io.stdout, result.receipt);
|
|
1322
|
+
commandExitState.exitCode = result.exitCode;
|
|
1323
|
+
});
|
|
688
1324
|
review
|
|
689
1325
|
.command('digest')
|
|
690
1326
|
.description('Compute one canonical workflow component digest')
|
|
@@ -837,15 +1473,17 @@ export function buildProgram(options = {}) {
|
|
|
837
1473
|
.option('--skill <name...>', 'install only selected Skill names')
|
|
838
1474
|
.option('--agent <id...>', 'install to explicit Agent IDs')
|
|
839
1475
|
.option('-y, --yes', 'confirm the reviewed install', false)
|
|
840
|
-
.option('-j, --json', 'emit one receipt
|
|
1476
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
841
1477
|
.action(async (selector, rawOptions) => {
|
|
842
1478
|
const context = createActionContext('skill:install', {});
|
|
843
1479
|
const writeFailure = (error) => {
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
1480
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1481
|
+
const code = capabilityError?.code
|
|
1482
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1483
|
+
? error.code
|
|
1484
|
+
: 'portableInstallFailed');
|
|
847
1485
|
writeJsonReceipt(io.stdout, {
|
|
848
|
-
receiptSchemaVersion:
|
|
1486
|
+
receiptSchemaVersion: 5,
|
|
849
1487
|
command: 'skill:install',
|
|
850
1488
|
ok: false,
|
|
851
1489
|
status: 'failed',
|
|
@@ -861,7 +1499,15 @@ export function buildProgram(options = {}) {
|
|
|
861
1499
|
materializationDigest: null,
|
|
862
1500
|
verification: { records: [], missing: [] },
|
|
863
1501
|
warnings: [],
|
|
864
|
-
failures: [{
|
|
1502
|
+
failures: [{
|
|
1503
|
+
code,
|
|
1504
|
+
message: capabilityError?.message ?? `${code}: portable Skill 安装未执行。`,
|
|
1505
|
+
...(capabilityError ? {
|
|
1506
|
+
plugin: capabilityError.plugin,
|
|
1507
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1508
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1509
|
+
} : {}),
|
|
1510
|
+
}],
|
|
865
1511
|
});
|
|
866
1512
|
};
|
|
867
1513
|
if (rawOptions.json && !rawOptions.yes) {
|
|
@@ -931,7 +1577,7 @@ export function buildProgram(options = {}) {
|
|
|
931
1577
|
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
932
1578
|
.requiredOption('--out <dir>', 'output directory')
|
|
933
1579
|
.option('--skill <name...>', 'write only selected Skill names')
|
|
934
|
-
.option('-j, --json', 'emit one receipt
|
|
1580
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
935
1581
|
.action(async (selector, rawOptions) => {
|
|
936
1582
|
const context = createActionContext('skill:materialize', {});
|
|
937
1583
|
try {
|
|
@@ -952,11 +1598,13 @@ export function buildProgram(options = {}) {
|
|
|
952
1598
|
catch (error) {
|
|
953
1599
|
if (!rawOptions.json)
|
|
954
1600
|
throw error;
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
1601
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1602
|
+
const code = capabilityError?.code
|
|
1603
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1604
|
+
? error.code
|
|
1605
|
+
: 'portableMaterializeFailed');
|
|
958
1606
|
writeJsonReceipt(io.stdout, {
|
|
959
|
-
receiptSchemaVersion:
|
|
1607
|
+
receiptSchemaVersion: 5,
|
|
960
1608
|
command: 'skill:materialize',
|
|
961
1609
|
ok: false,
|
|
962
1610
|
plugin: { id: selector },
|
|
@@ -968,7 +1616,15 @@ export function buildProgram(options = {}) {
|
|
|
968
1616
|
configDigest: null,
|
|
969
1617
|
materializationDigest: null,
|
|
970
1618
|
outputDigest: null,
|
|
971
|
-
errors: [{
|
|
1619
|
+
errors: [{
|
|
1620
|
+
code,
|
|
1621
|
+
message: capabilityError?.message ?? `${code}: portable Skill 导出未执行。`,
|
|
1622
|
+
...(capabilityError ? {
|
|
1623
|
+
plugin: capabilityError.plugin,
|
|
1624
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1625
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1626
|
+
} : {}),
|
|
1627
|
+
}],
|
|
972
1628
|
});
|
|
973
1629
|
commandExitState.exitCode = 1;
|
|
974
1630
|
}
|
|
@@ -980,7 +1636,7 @@ export function buildProgram(options = {}) {
|
|
|
980
1636
|
'',
|
|
981
1637
|
'During development, keep the current stable target when production content changes.',
|
|
982
1638
|
'Next, run `aw plugin validate`, `aw plugin test`, `aw plugin build`, and `aw catalog build`.',
|
|
983
|
-
'Publish only as an explicit later step; inspect `aw catalog publish --help` first.',
|
|
1639
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
984
1640
|
'',
|
|
985
1641
|
].join('\n'))
|
|
986
1642
|
.argument('<plugin-name>', 'lowercase hyphen-case plugin name')
|
|
@@ -992,14 +1648,12 @@ export function buildProgram(options = {}) {
|
|
|
992
1648
|
.option('--skill-short-description <text>', 'initial Skill UI summary (25-64 characters)')
|
|
993
1649
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
994
1650
|
.option('--version <semver>', 'initial stable plugin version (default: 0.1.0)')
|
|
995
|
-
.option('--
|
|
996
|
-
.option('--catalog-min-version <semver>', 'target catalog compatibility minimum')
|
|
997
|
-
.option('--workspace-root <path>', 'workspace root (default: current directory)')
|
|
1651
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
998
1652
|
.option('--no-skills', 'create the plugin without a skills directory')
|
|
999
1653
|
.option('--with-mcp', 'add a minimal .mcp.json', false)
|
|
1000
1654
|
.option('--with-apps', 'add a minimal .app.json', false)
|
|
1001
1655
|
.option('--with-config-api', 'add AW config schema and helper', false)
|
|
1002
|
-
.option('--with-
|
|
1656
|
+
.option('--with-pre-apply', 'add an idempotent Node preApply environment check', false);
|
|
1003
1657
|
plugin
|
|
1004
1658
|
.command('add-skill')
|
|
1005
1659
|
.description('Add one static Skill scaffold to an existing plugin')
|
|
@@ -1007,7 +1661,7 @@ export function buildProgram(options = {}) {
|
|
|
1007
1661
|
'',
|
|
1008
1662
|
'During development, keep the current stable target when production content changes.',
|
|
1009
1663
|
'Next, run `aw plugin validate`, `aw plugin test`, `aw plugin build`, and `aw catalog build`.',
|
|
1010
|
-
'Publish only as an explicit later step; inspect `aw catalog publish --help` first.',
|
|
1664
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
1011
1665
|
'',
|
|
1012
1666
|
].join('\n'))
|
|
1013
1667
|
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
@@ -1015,28 +1669,39 @@ export function buildProgram(options = {}) {
|
|
|
1015
1669
|
.option('--skill-description <text>', 'Skill goal and discovery description (required)')
|
|
1016
1670
|
.option('--skill-short-description <text>', 'Skill UI summary (25-64 characters)')
|
|
1017
1671
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
1018
|
-
.option('--workspace-root <path>', '
|
|
1672
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1673
|
+
plugin
|
|
1674
|
+
.command('remove')
|
|
1675
|
+
.description('Remove one committed and unchanged canonical plugin source tree')
|
|
1676
|
+
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
1677
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1678
|
+
.option('--yes', 'confirm plugin source deletion', false)
|
|
1679
|
+
.option('--json', 'emit one schema 1 JSON object', false);
|
|
1019
1680
|
plugin
|
|
1020
1681
|
.command('validate')
|
|
1021
1682
|
.description('Validate one source plugin directory')
|
|
1022
1683
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1023
|
-
.option('--catalog-min-version <semver>', 'validate compatibility against a target catalog')
|
|
1024
1684
|
.option('--strict-agent-skills', 'allow only Agent Skills portable core frontmatter', false)
|
|
1025
1685
|
.option('--claude-skill-profile <profile>', 'minimum | current (default: minimum)')
|
|
1026
1686
|
.option('--version-base <git-ref>', 'production bundle comparison base (default: HEAD)')
|
|
1027
|
-
.option('--workspace-root <path>', '
|
|
1687
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1028
1688
|
.option('--json', 'emit one machine-readable JSON result', false);
|
|
1029
1689
|
plugin
|
|
1030
1690
|
.command('test')
|
|
1031
1691
|
.description('Run deterministic Node tests declared by one source plugin')
|
|
1032
1692
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1033
|
-
.option('--workspace-root <path>', '
|
|
1693
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1034
1694
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1035
1695
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1036
1696
|
try {
|
|
1697
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1698
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1699
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1700
|
+
mode: 'existing',
|
|
1701
|
+
});
|
|
1037
1702
|
commandExitState.exitCode = await runPluginTestCommand({
|
|
1038
|
-
|
|
1039
|
-
pluginDirectory,
|
|
1703
|
+
...workspace,
|
|
1704
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1040
1705
|
json: rawOptions.json,
|
|
1041
1706
|
io,
|
|
1042
1707
|
});
|
|
@@ -1053,15 +1718,20 @@ export function buildProgram(options = {}) {
|
|
|
1053
1718
|
.command('build')
|
|
1054
1719
|
.description('Build and inspect one source plugin bundle')
|
|
1055
1720
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1056
|
-
.option('--workspace-root <path>', '
|
|
1057
|
-
.option('--out <path>', 'output path inside the
|
|
1721
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1722
|
+
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1058
1723
|
.option('--force', 'replace an existing generated output', false)
|
|
1059
1724
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1060
1725
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1061
1726
|
try {
|
|
1727
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1728
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1729
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1730
|
+
mode: 'existing',
|
|
1731
|
+
});
|
|
1062
1732
|
await runPluginBuildCommand({
|
|
1063
|
-
|
|
1064
|
-
pluginDirectory,
|
|
1733
|
+
...workspace,
|
|
1734
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1065
1735
|
out: rawOptions.out,
|
|
1066
1736
|
force: rawOptions.force,
|
|
1067
1737
|
json: rawOptions.json,
|
|
@@ -1080,18 +1750,10 @@ export function buildProgram(options = {}) {
|
|
|
1080
1750
|
.command('status')
|
|
1081
1751
|
.description('Show current plugin status or compare against an explicit Git base')
|
|
1082
1752
|
.argument('[plugin-name]', 'one explicit plugin name')
|
|
1083
|
-
.option('--all', 'check every current
|
|
1084
|
-
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1085
|
-
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1086
|
-
.option('--workspace-root <path>', 'workspace root (default: current directory)');
|
|
1087
|
-
plugin
|
|
1088
|
-
.command('check-versions')
|
|
1089
|
-
.description('Deprecated alias for plugin status')
|
|
1090
|
-
.argument('[plugin-name]', 'one explicit plugin name')
|
|
1091
|
-
.option('--all', 'check every plugin changed relative to the Git base', false)
|
|
1753
|
+
.option('--all', 'check every current Catalog Workspace plugin', false)
|
|
1092
1754
|
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1093
1755
|
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1094
|
-
.option('--workspace-root <path>', '
|
|
1756
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1095
1757
|
skill
|
|
1096
1758
|
.command('validate')
|
|
1097
1759
|
.description('Validate one Agent Skill directory')
|
|
@@ -1104,19 +1766,25 @@ export function buildProgram(options = {}) {
|
|
|
1104
1766
|
.description('Build and manage catalogs');
|
|
1105
1767
|
catalog
|
|
1106
1768
|
.command('init')
|
|
1107
|
-
.description('Initialize a local AW
|
|
1108
|
-
.option('--workspace-root <path>', '
|
|
1769
|
+
.description('Initialize a local AW Catalog Workspace')
|
|
1770
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor, then Git worktree root, then current directory)')
|
|
1109
1771
|
.option('--owner-name <name>', 'catalog owner name')
|
|
1110
1772
|
.option('--owner-url <url>', 'catalog owner URL')
|
|
1111
1773
|
.option('--display-name <name>', 'catalog display name')
|
|
1112
1774
|
.option('--catalog-version <version>', 'initial stable or x.y.z-beta.N catalog version (default: 0.1.0)')
|
|
1113
|
-
.option('--force', 'repair a matching managed
|
|
1775
|
+
.option('--force', 'repair a matching managed Catalog Workspace scaffold', false)
|
|
1114
1776
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1115
1777
|
.action(async (rawOptions) => {
|
|
1116
1778
|
try {
|
|
1779
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1780
|
+
cwd,
|
|
1781
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1782
|
+
mode: 'initialize',
|
|
1783
|
+
env,
|
|
1784
|
+
});
|
|
1117
1785
|
await runCatalogInitCommand({
|
|
1118
1786
|
...rawOptions,
|
|
1119
|
-
|
|
1787
|
+
...workspace,
|
|
1120
1788
|
io,
|
|
1121
1789
|
});
|
|
1122
1790
|
}
|
|
@@ -1130,15 +1798,22 @@ export function buildProgram(options = {}) {
|
|
|
1130
1798
|
});
|
|
1131
1799
|
catalog
|
|
1132
1800
|
.command('version')
|
|
1133
|
-
.description('Read or set the
|
|
1801
|
+
.description('Read or set the Catalog version')
|
|
1134
1802
|
.argument('[version]', 'stable or x.y.z-beta.N catalog version')
|
|
1135
|
-
.option('--
|
|
1803
|
+
.option('--bump <level>', 'bump the stable SemVer base: patch, minor, or major')
|
|
1804
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1136
1805
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1137
1806
|
.action(async (version, rawOptions) => {
|
|
1138
1807
|
try {
|
|
1808
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1809
|
+
cwd,
|
|
1810
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1811
|
+
mode: 'existing',
|
|
1812
|
+
});
|
|
1139
1813
|
await runCatalogVersionCommand({
|
|
1140
|
-
|
|
1814
|
+
...workspace,
|
|
1141
1815
|
version,
|
|
1816
|
+
bump: rawOptions.bump,
|
|
1142
1817
|
json: rawOptions.json,
|
|
1143
1818
|
io,
|
|
1144
1819
|
});
|
|
@@ -1154,14 +1829,19 @@ export function buildProgram(options = {}) {
|
|
|
1154
1829
|
catalog
|
|
1155
1830
|
.command('build')
|
|
1156
1831
|
.description('Build a deterministic development Catalog snapshot')
|
|
1157
|
-
.option('--workspace-root <path>', '
|
|
1158
|
-
.option('--out <path>', 'output path inside the
|
|
1832
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1833
|
+
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1159
1834
|
.option('--force', 'replace an existing generated output', false)
|
|
1160
1835
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1161
1836
|
.action(async (rawOptions) => {
|
|
1162
1837
|
try {
|
|
1838
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1839
|
+
cwd,
|
|
1840
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1841
|
+
mode: 'existing',
|
|
1842
|
+
});
|
|
1163
1843
|
await runCatalogBuildCommand({
|
|
1164
|
-
|
|
1844
|
+
...workspace,
|
|
1165
1845
|
out: rawOptions.out,
|
|
1166
1846
|
force: rawOptions.force,
|
|
1167
1847
|
json: rawOptions.json,
|
|
@@ -1178,7 +1858,7 @@ export function buildProgram(options = {}) {
|
|
|
1178
1858
|
});
|
|
1179
1859
|
catalog
|
|
1180
1860
|
.command('validate')
|
|
1181
|
-
.description('Validate a schema
|
|
1861
|
+
.description('Validate a schema 7 Catalog snapshot')
|
|
1182
1862
|
.argument('<snapshot-directory>', 'Catalog snapshot directory')
|
|
1183
1863
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1184
1864
|
.action(async (snapshotDirectory, rawOptions) => {
|
|
@@ -1198,53 +1878,204 @@ export function buildProgram(options = {}) {
|
|
|
1198
1878
|
}
|
|
1199
1879
|
});
|
|
1200
1880
|
catalog
|
|
1881
|
+
.command('status')
|
|
1882
|
+
.description('Inspect static Catalog Workspace, snapshot, and Git facts')
|
|
1883
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1884
|
+
.option('--json', 'emit one machine-readable JSON status object', false)
|
|
1885
|
+
.action(async (rawOptions) => {
|
|
1886
|
+
const receipt = await getCatalogStatus({
|
|
1887
|
+
cwd,
|
|
1888
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1889
|
+
env,
|
|
1890
|
+
});
|
|
1891
|
+
if (rawOptions.json)
|
|
1892
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1893
|
+
else
|
|
1894
|
+
io.stdout(renderCatalogStatus(receipt));
|
|
1895
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1896
|
+
});
|
|
1897
|
+
const catalogPublish = catalog
|
|
1201
1898
|
.command('publish')
|
|
1202
|
-
.description('
|
|
1203
|
-
|
|
1204
|
-
.
|
|
1899
|
+
.description('Plan or apply a versioned Catalog publication');
|
|
1900
|
+
catalogPublish
|
|
1901
|
+
.command('plan')
|
|
1902
|
+
.description('Prepare and inspect the exact Catalog publication plan')
|
|
1903
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1904
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
1205
1905
|
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
1206
|
-
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
1207
1906
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1208
1907
|
.action(async (rawOptions) => {
|
|
1209
1908
|
try {
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
workspaceRoot:
|
|
1909
|
+
const result = await runCatalogPublishPlanCommand({
|
|
1910
|
+
cwd,
|
|
1911
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1213
1912
|
remote: rawOptions.remote,
|
|
1214
1913
|
branch: rawOptions.branch,
|
|
1215
|
-
yes: rawOptions.yes,
|
|
1216
|
-
json: rawOptions.json,
|
|
1217
1914
|
env,
|
|
1218
|
-
interactive: context.interactive,
|
|
1219
|
-
...(context.prompt.confirm ? {
|
|
1220
|
-
confirm: async (message) => {
|
|
1221
|
-
const response = await context.prompt.confirm({ message, defaultValue: false });
|
|
1222
|
-
return !response.cancelled && response.value === true;
|
|
1223
|
-
},
|
|
1224
|
-
} : {}),
|
|
1225
1915
|
io,
|
|
1226
1916
|
});
|
|
1227
|
-
if (!result)
|
|
1228
|
-
return;
|
|
1229
1917
|
if (rawOptions.json)
|
|
1230
1918
|
writeJsonReceipt(io.stdout, result);
|
|
1231
1919
|
else {
|
|
1232
|
-
writeLine(io.stdout, `
|
|
1920
|
+
writeLine(io.stdout, `Workspace identity: ${result.workspaceIdentity}`);
|
|
1921
|
+
writeLine(io.stdout, `Source HEAD: ${result.sourceHead}`);
|
|
1922
|
+
writeLine(io.stdout, `Remote identity: ${result.descriptor.remote.identityDigest}`);
|
|
1923
|
+
writeLine(io.stdout, `Remote: ${result.remote} (${result.remoteUrl})`);
|
|
1233
1924
|
writeLine(io.stdout, `Branch: refs/heads/${result.branch}`);
|
|
1925
|
+
writeLine(io.stdout, `Parent: ${result.parent ?? '<root>'}`);
|
|
1234
1926
|
writeLine(io.stdout, `Tag: refs/tags/${result.tag}`);
|
|
1235
|
-
writeLine(io.stdout, `
|
|
1236
|
-
writeLine(io.stdout, `
|
|
1927
|
+
writeLine(io.stdout, `Snapshot digest: ${result.snapshotDigest}`);
|
|
1928
|
+
writeLine(io.stdout, `Expected commit: ${result.expectedCommit}`);
|
|
1929
|
+
writeLine(io.stdout, `Plan digest: ${result.planDigest}`);
|
|
1237
1930
|
}
|
|
1238
1931
|
}
|
|
1239
1932
|
catch (error) {
|
|
1240
|
-
const
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1933
|
+
const failure = catalogPublicationFailure({
|
|
1934
|
+
error,
|
|
1935
|
+
env,
|
|
1936
|
+
sensitiveRoots: [
|
|
1937
|
+
cwd,
|
|
1938
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
1939
|
+
],
|
|
1940
|
+
});
|
|
1941
|
+
if (rawOptions.json)
|
|
1942
|
+
writeJsonReceipt(io.stdout, failure);
|
|
1943
|
+
writeLine(io.stderr, failure.message);
|
|
1944
|
+
commandExitState.exitCode = 1;
|
|
1945
|
+
}
|
|
1946
|
+
});
|
|
1947
|
+
catalogPublish
|
|
1948
|
+
.command('apply')
|
|
1949
|
+
.description('Apply an authorized Catalog publication plan')
|
|
1950
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1951
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
1952
|
+
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
1953
|
+
.requiredOption('--expected-plan-digest <sha256>', 'exact plan digest returned by catalog publish plan')
|
|
1954
|
+
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
1955
|
+
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1956
|
+
.action(async (rawOptions) => {
|
|
1957
|
+
try {
|
|
1958
|
+
const context = createActionContext('catalog:publish:apply', {});
|
|
1959
|
+
const result = await runCatalogPublishApplyCommand({
|
|
1960
|
+
cwd,
|
|
1961
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1962
|
+
remote: rawOptions.remote,
|
|
1963
|
+
branch: rawOptions.branch,
|
|
1964
|
+
expectedPlanDigest: rawOptions.expectedPlanDigest,
|
|
1965
|
+
yes: rawOptions.yes,
|
|
1966
|
+
json: rawOptions.json,
|
|
1967
|
+
env,
|
|
1968
|
+
interactive: context.interactive,
|
|
1969
|
+
...(context.prompt.confirm ? {
|
|
1970
|
+
confirm: async (message) => {
|
|
1971
|
+
const response = await context.prompt.confirm({ message, defaultValue: false });
|
|
1972
|
+
return !response.cancelled && response.value === true;
|
|
1973
|
+
},
|
|
1974
|
+
} : {}),
|
|
1975
|
+
io,
|
|
1976
|
+
});
|
|
1977
|
+
if (!result)
|
|
1978
|
+
return;
|
|
1979
|
+
if (rawOptions.json)
|
|
1980
|
+
writeJsonReceipt(io.stdout, result);
|
|
1981
|
+
else {
|
|
1982
|
+
writeLine(io.stdout, `Published Catalog ${result.catalogVersion} to ${result.remote} (${result.pushUrl}).`);
|
|
1983
|
+
writeLine(io.stdout, `Branch: refs/heads/${result.branch}`);
|
|
1984
|
+
writeLine(io.stdout, `Tag: refs/tags/${result.tag}`);
|
|
1985
|
+
writeLine(io.stdout, `Commit: ${result.commit}`);
|
|
1986
|
+
writeLine(io.stdout, `Add it as a source: aw catalog source add <id> --git ${result.fetchUrl} --ref refs/heads/${result.branch}`);
|
|
1987
|
+
}
|
|
1988
|
+
}
|
|
1989
|
+
catch (error) {
|
|
1990
|
+
const failure = catalogPublicationFailure({
|
|
1991
|
+
error,
|
|
1992
|
+
env,
|
|
1993
|
+
sensitiveRoots: [
|
|
1994
|
+
cwd,
|
|
1995
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
1996
|
+
],
|
|
1997
|
+
});
|
|
1998
|
+
if (rawOptions.json)
|
|
1999
|
+
writeJsonReceipt(io.stdout, failure);
|
|
2000
|
+
writeLine(io.stderr, failure.message);
|
|
2001
|
+
commandExitState.exitCode = 1;
|
|
2002
|
+
}
|
|
2003
|
+
});
|
|
2004
|
+
const catalogDev = catalog
|
|
2005
|
+
.command('dev')
|
|
2006
|
+
.description('Manage the current Catalog Workspace development source');
|
|
2007
|
+
catalogDev
|
|
2008
|
+
.command('activate')
|
|
2009
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2010
|
+
.option('--source-id <id>', 'explicit managed source ID')
|
|
2011
|
+
.option('--primary', 'make the development source primary', false)
|
|
2012
|
+
.option('--force-build', 'rebuild a current snapshot', false)
|
|
2013
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
2014
|
+
.requiredOption('--json', 'emit one schema 2 JSON receipt')
|
|
2015
|
+
.action(async (rawOptions) => {
|
|
2016
|
+
try {
|
|
2017
|
+
const receipt = await activateCatalogDevSource({
|
|
2018
|
+
cwd,
|
|
2019
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2020
|
+
sourceId: rawOptions.sourceId,
|
|
2021
|
+
primary: rawOptions.primary,
|
|
2022
|
+
forceBuild: rawOptions.forceBuild,
|
|
2023
|
+
yes: rawOptions.yes,
|
|
2024
|
+
cliVersion: resolveCliVersion(),
|
|
2025
|
+
env,
|
|
2026
|
+
});
|
|
2027
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2028
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2029
|
+
}
|
|
2030
|
+
catch (error) {
|
|
2031
|
+
const failure = catalogDevSourceError(error);
|
|
2032
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
2033
|
+
command: 'activate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
2034
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
2035
|
+
}));
|
|
2036
|
+
commandExitState.exitCode = 1;
|
|
2037
|
+
}
|
|
2038
|
+
});
|
|
2039
|
+
catalogDev
|
|
2040
|
+
.command('status')
|
|
2041
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2042
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
2043
|
+
.action(async (rawOptions) => {
|
|
2044
|
+
const receipt = await getCatalogDevSourceStatus({
|
|
2045
|
+
cwd,
|
|
2046
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2047
|
+
cliVersion: resolveCliVersion(),
|
|
2048
|
+
env,
|
|
2049
|
+
});
|
|
2050
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2051
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2052
|
+
});
|
|
2053
|
+
catalogDev
|
|
2054
|
+
.command('deactivate')
|
|
2055
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2056
|
+
.option('--source-id <id>', 'recover one managed source by exact ID')
|
|
2057
|
+
.option('--replacement-primary <id>', 'replacement when the target source is primary')
|
|
2058
|
+
.option('-y, --yes', 'confirm source impact or recovery by source ID', false)
|
|
2059
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
2060
|
+
.action(async (rawOptions) => {
|
|
2061
|
+
try {
|
|
2062
|
+
const receipt = await deactivateCatalogDevSource({
|
|
2063
|
+
cwd,
|
|
2064
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2065
|
+
sourceId: rawOptions.sourceId,
|
|
2066
|
+
replacementPrimary: rawOptions.replacementPrimary,
|
|
2067
|
+
yes: rawOptions.yes,
|
|
2068
|
+
env,
|
|
2069
|
+
});
|
|
2070
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2071
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2072
|
+
}
|
|
2073
|
+
catch (error) {
|
|
2074
|
+
const failure = catalogDevSourceError(error);
|
|
2075
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
2076
|
+
command: 'deactivate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
2077
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
2078
|
+
}));
|
|
1248
2079
|
commandExitState.exitCode = 1;
|
|
1249
2080
|
}
|
|
1250
2081
|
});
|
|
@@ -1256,52 +2087,70 @@ export function buildProgram(options = {}) {
|
|
|
1256
2087
|
const message = failure instanceof Error ? failure.message : String(error);
|
|
1257
2088
|
if (json) {
|
|
1258
2089
|
writeJsonReceipt(io.stdout, {
|
|
1259
|
-
receiptSchemaVersion:
|
|
2090
|
+
receiptSchemaVersion: 6,
|
|
1260
2091
|
command,
|
|
1261
2092
|
ok: false,
|
|
1262
2093
|
changed: false,
|
|
1263
2094
|
sourceId,
|
|
1264
|
-
|
|
2095
|
+
primaryChange: failure.impact?.primaryChange ?? null,
|
|
2096
|
+
references: failure.impact?.references ?? failure.inventory?.references ?? [],
|
|
1265
2097
|
errors: [{ code: failure.code ?? failure.name ?? 'catalogSourceMutationFailed', message }],
|
|
1266
2098
|
});
|
|
1267
2099
|
}
|
|
1268
2100
|
writeLine(io.stderr, message);
|
|
1269
2101
|
commandExitState.exitCode = 1;
|
|
1270
2102
|
};
|
|
1271
|
-
const
|
|
1272
|
-
const
|
|
1273
|
-
const
|
|
1274
|
-
|
|
1275
|
-
: message.includes('sourceChanged')
|
|
1276
|
-
? 'sourceChanged'
|
|
1277
|
-
: message.includes('sourceMissing')
|
|
1278
|
-
? 'sourceMissing'
|
|
1279
|
-
: message.startsWith('Cannot resolve required catalog sources:')
|
|
1280
|
-
? 'catalogSourceUnavailable'
|
|
1281
|
-
: message.split(':', 1)[0] || 'configMutationFailed';
|
|
1282
|
-
if (json && !message.includes('Usage:')) {
|
|
2103
|
+
const writeCatalogGenerationFailure = (command, sourceId, json, error) => {
|
|
2104
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2105
|
+
const message = redactString(failure.message);
|
|
2106
|
+
if (json) {
|
|
1283
2107
|
writeJsonReceipt(io.stdout, {
|
|
1284
|
-
|
|
2108
|
+
...(command === 'catalog:source:sync'
|
|
2109
|
+
? { catalogGenerationSchemaVersion: 1 }
|
|
2110
|
+
: { catalogGenerationStatusSchemaVersion: 2 }),
|
|
1285
2111
|
command,
|
|
1286
2112
|
ok: false,
|
|
1287
|
-
|
|
1288
|
-
...(
|
|
1289
|
-
errors: [{ code, message }],
|
|
2113
|
+
...(sourceId ? { sourceId } : {}),
|
|
2114
|
+
...(failure.impact ? { impact: failure.impact } : {}),
|
|
2115
|
+
errors: [{ code: catalogGenerationErrorCode(error), message }],
|
|
1290
2116
|
});
|
|
1291
2117
|
}
|
|
1292
2118
|
writeLine(io.stderr, message);
|
|
1293
2119
|
commandExitState.exitCode = 1;
|
|
1294
2120
|
};
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
2121
|
+
const writeConfigMutationFailure = (command, plugin, json, error) => {
|
|
2122
|
+
const failure = configMutationFailure(error, env, cwd);
|
|
2123
|
+
if (json) {
|
|
2124
|
+
writeConfigMutationFailureReceipt(io.stdout, {
|
|
2125
|
+
command,
|
|
2126
|
+
...(plugin ? { plugin } : {}),
|
|
2127
|
+
}, failure);
|
|
2128
|
+
}
|
|
2129
|
+
const message = json
|
|
2130
|
+
? failure.message
|
|
2131
|
+
: redactString(sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), env, [cwd]));
|
|
2132
|
+
writeLine(io.stderr, message);
|
|
2133
|
+
commandExitState.exitCode = 1;
|
|
2134
|
+
};
|
|
2135
|
+
const withResolvedConfigMutationPlugin = (context, selector, consume) => (async () => {
|
|
2136
|
+
const parsed = parsePluginId(selector);
|
|
2137
|
+
return withAwHomeMutationLock({
|
|
1301
2138
|
env: context.env,
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
2139
|
+
action: async (awHomeMutationToken) => {
|
|
2140
|
+
const catalogOperationContext = await resolveCatalogOperationContext({
|
|
2141
|
+
...(parsed.sourceId ? { sourceIds: [parsed.sourceId] } : {}),
|
|
2142
|
+
env: context.env,
|
|
2143
|
+
});
|
|
2144
|
+
return withResolvedCatalogPlugin({
|
|
2145
|
+
selector,
|
|
2146
|
+
cliVersion: resolveCliVersion(),
|
|
2147
|
+
operationContext: catalogOperationContext,
|
|
2148
|
+
env: context.env,
|
|
2149
|
+
consume: (resolution) => consume(resolution, awHomeMutationToken, catalogOperationContext),
|
|
2150
|
+
});
|
|
2151
|
+
},
|
|
2152
|
+
});
|
|
2153
|
+
})();
|
|
1305
2154
|
catalogSource
|
|
1306
2155
|
.command('list')
|
|
1307
2156
|
.option('-j, --json', 'print catalog sources as JSON', false)
|
|
@@ -1316,6 +2165,70 @@ export function buildProgram(options = {}) {
|
|
|
1316
2165
|
writeLine(io.stdout, `${source.primary ? '*' : '-'} ${source.id} ${source.type} ${source.sourceIdentity}`);
|
|
1317
2166
|
}
|
|
1318
2167
|
});
|
|
2168
|
+
catalogSource
|
|
2169
|
+
.command('sync')
|
|
2170
|
+
.argument('<id>')
|
|
2171
|
+
.option('--check', 'fetch and validate without changing the Catalog store or Active state', false)
|
|
2172
|
+
.option('--replace-damaged', 'replace a damaged Active entry with the current candidate', false)
|
|
2173
|
+
.option('-y, --yes', 'confirm affected, unknown, or damaged Active replacement impact', false)
|
|
2174
|
+
.option('-j, --json', 'print the source sync result as JSON', false)
|
|
2175
|
+
.action(async (id, rawOptions) => {
|
|
2176
|
+
try {
|
|
2177
|
+
if (rawOptions.check && rawOptions.replaceDamaged) {
|
|
2178
|
+
throw new Error('catalog source sync --check cannot use --replace-damaged.');
|
|
2179
|
+
}
|
|
2180
|
+
const result = await syncCatalogSourceCommand({
|
|
2181
|
+
sourceId: id,
|
|
2182
|
+
cliVersion: resolveCliVersion(),
|
|
2183
|
+
cwd,
|
|
2184
|
+
check: rawOptions.check === true,
|
|
2185
|
+
impactConfirmed: rawOptions.yes === true,
|
|
2186
|
+
replaceDamaged: rawOptions.replaceDamaged === true,
|
|
2187
|
+
env,
|
|
2188
|
+
});
|
|
2189
|
+
if (rawOptions.json) {
|
|
2190
|
+
writeJsonReceipt(io.stdout, {
|
|
2191
|
+
...result,
|
|
2192
|
+
command: 'catalog:source:sync',
|
|
2193
|
+
ok: true,
|
|
2194
|
+
});
|
|
2195
|
+
}
|
|
2196
|
+
else {
|
|
2197
|
+
writeLine(io.stdout, rawOptions.check
|
|
2198
|
+
? `Catalog source ${id} is valid.`
|
|
2199
|
+
: `Catalog source ${id}: ${result.outcome}.`);
|
|
2200
|
+
}
|
|
2201
|
+
}
|
|
2202
|
+
catch (error) {
|
|
2203
|
+
writeCatalogGenerationFailure('catalog:source:sync', id, rawOptions.json === true, error);
|
|
2204
|
+
}
|
|
2205
|
+
});
|
|
2206
|
+
catalogSource
|
|
2207
|
+
.command('status')
|
|
2208
|
+
.argument('[id]')
|
|
2209
|
+
.option('-j, --json', 'print offline Catalog source status schema 2 as JSON', false)
|
|
2210
|
+
.action(async (id, rawOptions) => {
|
|
2211
|
+
try {
|
|
2212
|
+
const result = await catalogSourceStatusCommand({ sourceId: id, env });
|
|
2213
|
+
if (rawOptions.json) {
|
|
2214
|
+
writeJsonReceipt(io.stdout, result);
|
|
2215
|
+
}
|
|
2216
|
+
else {
|
|
2217
|
+
for (const source of result.sources) {
|
|
2218
|
+
const active = source.active
|
|
2219
|
+
? `Active ${source.active.snapshotDigest}`
|
|
2220
|
+
: 'no Active';
|
|
2221
|
+
const readiness = source.compatibility?.state === 'unsupported'
|
|
2222
|
+
? `incompatible (required: ${source.compatibility.requiredCapabilities.join(', ')}; missing: ${source.compatibility.missingCapabilities.join(', ')})`
|
|
2223
|
+
: source.activeReady ? 'ready' : 'not ready';
|
|
2224
|
+
writeLine(io.stdout, `${source.sourceId}: ${active}, ${readiness}`);
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
}
|
|
2228
|
+
catch (error) {
|
|
2229
|
+
writeCatalogGenerationFailure('catalog:source:status', id, rawOptions.json === true, error);
|
|
2230
|
+
}
|
|
2231
|
+
});
|
|
1319
2232
|
catalogSource
|
|
1320
2233
|
.command('add')
|
|
1321
2234
|
.argument('<id>')
|
|
@@ -1324,7 +2237,9 @@ export function buildProgram(options = {}) {
|
|
|
1324
2237
|
.addOption(new Option('--ref <ref>', 'use an explicit Git ref'))
|
|
1325
2238
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1326
2239
|
.option('--subdir <path>', 'use a catalog snapshot below the Git repository root')
|
|
2240
|
+
.option('--no-auto-check', 'disable automatic update checks for this source')
|
|
1327
2241
|
.option('--primary', 'make this source primary', false)
|
|
2242
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1328
2243
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1329
2244
|
.action(async (id, rawOptions) => {
|
|
1330
2245
|
try {
|
|
@@ -1335,7 +2250,7 @@ export function buildProgram(options = {}) {
|
|
|
1335
2250
|
throw new Error('Git catalog source add requires exactly one of `--ref` or `--default-ref`.');
|
|
1336
2251
|
}
|
|
1337
2252
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined)) {
|
|
1338
|
-
throw new Error('Path catalog source add only accepts `--path
|
|
2253
|
+
throw new Error('Path catalog source add only accepts `--path`, `--primary`, `--no-auto-check`, and `--yes`.');
|
|
1339
2254
|
}
|
|
1340
2255
|
const source = rawOptions.git !== undefined
|
|
1341
2256
|
? {
|
|
@@ -1345,18 +2260,32 @@ export function buildProgram(options = {}) {
|
|
|
1345
2260
|
url: rawOptions.git,
|
|
1346
2261
|
refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true),
|
|
1347
2262
|
...(rawOptions.subdir ? { subdir: rawOptions.subdir } : {}),
|
|
2263
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1348
2264
|
}
|
|
1349
2265
|
: {
|
|
1350
2266
|
id,
|
|
1351
2267
|
type: 'path',
|
|
1352
2268
|
primary: rawOptions.primary === true,
|
|
1353
2269
|
path: rawOptions.path,
|
|
2270
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1354
2271
|
};
|
|
2272
|
+
const preview = source.primary
|
|
2273
|
+
? await preflightCatalogSourceMutation({
|
|
2274
|
+
request: { action: 'add', source }, cwd, env,
|
|
2275
|
+
})
|
|
2276
|
+
: undefined;
|
|
1355
2277
|
const receipt = await addCatalogSourceCommand({
|
|
1356
2278
|
source,
|
|
1357
2279
|
cliVersion: resolveCliVersion(),
|
|
1358
2280
|
cwd,
|
|
1359
2281
|
env,
|
|
2282
|
+
...(preview ? {
|
|
2283
|
+
expectedConfigDigest: preview.configDigest,
|
|
2284
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2285
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2286
|
+
} : {}),
|
|
2287
|
+
requireImpactConfirmation: true,
|
|
2288
|
+
confirmImpact: rawOptions.yes === true,
|
|
1360
2289
|
});
|
|
1361
2290
|
if (rawOptions.json)
|
|
1362
2291
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1378,6 +2307,9 @@ export function buildProgram(options = {}) {
|
|
|
1378
2307
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1379
2308
|
.addOption(new Option('--subdir <path>', 'update the Git catalog subdirectory'))
|
|
1380
2309
|
.addOption(new Option('--no-subdir', 'remove the Git catalog subdirectory'))
|
|
2310
|
+
.addOption(new Option('--auto-check', 'enable automatic update checks for this source'))
|
|
2311
|
+
.addOption(new Option('--no-auto-check', 'disable automatic update checks for this source'))
|
|
2312
|
+
.option('-y, --yes', 'confirm a source identity change', false)
|
|
1381
2313
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1382
2314
|
.action(async (id, rawOptions) => {
|
|
1383
2315
|
try {
|
|
@@ -1391,15 +2323,25 @@ export function buildProgram(options = {}) {
|
|
|
1391
2323
|
|| rawOptions.path !== undefined
|
|
1392
2324
|
|| rawOptions.ref !== undefined
|
|
1393
2325
|
|| rawOptions.defaultRef === true
|
|
1394
|
-
|| rawOptions.subdir !== undefined
|
|
2326
|
+
|| rawOptions.subdir !== undefined
|
|
2327
|
+
|| rawOptions.autoCheck !== undefined;
|
|
1395
2328
|
if (!hasUpdate)
|
|
1396
2329
|
throw new Error('catalog source update requires at least one update option.');
|
|
1397
2330
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined))
|
|
1398
|
-
throw new Error('Path catalog source update only accepts `--path
|
|
2331
|
+
throw new Error('Path catalog source update only accepts `--path` and auto-check options.');
|
|
2332
|
+
const hasGitUpdate = rawOptions.git !== undefined
|
|
2333
|
+
|| rawOptions.ref !== undefined
|
|
2334
|
+
|| rawOptions.defaultRef === true
|
|
2335
|
+
|| rawOptions.subdir !== undefined;
|
|
1399
2336
|
const update = rawOptions.path !== undefined
|
|
1400
|
-
? {
|
|
1401
|
-
|
|
2337
|
+
? {
|
|
2338
|
+
type: 'path',
|
|
2339
|
+
path: rawOptions.path,
|
|
2340
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
2341
|
+
}
|
|
2342
|
+
: hasGitUpdate ? {
|
|
1402
2343
|
type: 'git',
|
|
2344
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
1403
2345
|
...(rawOptions.git !== undefined ? { url: rawOptions.git } : {}),
|
|
1404
2346
|
...(rawOptions.ref !== undefined || rawOptions.defaultRef === true
|
|
1405
2347
|
? { refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true) }
|
|
@@ -1407,13 +2349,22 @@ export function buildProgram(options = {}) {
|
|
|
1407
2349
|
...(rawOptions.subdir !== undefined
|
|
1408
2350
|
? { subdir: rawOptions.subdir === false ? null : rawOptions.subdir }
|
|
1409
2351
|
: {}),
|
|
1410
|
-
}
|
|
2352
|
+
}
|
|
2353
|
+
: { autoCheck: rawOptions.autoCheck };
|
|
2354
|
+
const preview = await preflightCatalogSourceMutation({
|
|
2355
|
+
request: { action: 'update', sourceId: id, update }, cwd, env,
|
|
2356
|
+
});
|
|
1411
2357
|
const receipt = await updateCatalogSourceCommand({
|
|
1412
2358
|
sourceId: id,
|
|
1413
2359
|
update,
|
|
1414
2360
|
cliVersion: resolveCliVersion(),
|
|
1415
2361
|
cwd,
|
|
1416
2362
|
env,
|
|
2363
|
+
expectedConfigDigest: preview.configDigest,
|
|
2364
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2365
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2366
|
+
requireIdentityChangeConfirmation: true,
|
|
2367
|
+
confirmIdentityChange: rawOptions.yes === true,
|
|
1417
2368
|
});
|
|
1418
2369
|
if (rawOptions.json)
|
|
1419
2370
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1429,10 +2380,17 @@ export function buildProgram(options = {}) {
|
|
|
1429
2380
|
catalogSource
|
|
1430
2381
|
.command('set-primary')
|
|
1431
2382
|
.argument('<id>')
|
|
2383
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1432
2384
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1433
2385
|
.action(async (id, rawOptions) => {
|
|
1434
2386
|
try {
|
|
1435
|
-
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2387
|
+
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2388
|
+
sourceId: id,
|
|
2389
|
+
cwd,
|
|
2390
|
+
env,
|
|
2391
|
+
requireImpactConfirmation: true,
|
|
2392
|
+
confirmImpact: rawOptions.yes === true,
|
|
2393
|
+
});
|
|
1436
2394
|
if (rawOptions.json)
|
|
1437
2395
|
writeJsonReceipt(io.stdout, receipt);
|
|
1438
2396
|
else
|
|
@@ -1445,10 +2403,17 @@ export function buildProgram(options = {}) {
|
|
|
1445
2403
|
catalogSource
|
|
1446
2404
|
.command('remove')
|
|
1447
2405
|
.argument('<id>')
|
|
2406
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
1448
2407
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1449
2408
|
.action(async (id, rawOptions) => {
|
|
1450
2409
|
try {
|
|
1451
|
-
const receipt = await removeCatalogSourceCommand({
|
|
2410
|
+
const receipt = await removeCatalogSourceCommand({
|
|
2411
|
+
sourceId: id,
|
|
2412
|
+
cwd,
|
|
2413
|
+
env,
|
|
2414
|
+
requireImpactConfirmation: true,
|
|
2415
|
+
confirmImpact: rawOptions.yes === true,
|
|
2416
|
+
});
|
|
1452
2417
|
if (rawOptions.json)
|
|
1453
2418
|
writeJsonReceipt(io.stdout, receipt);
|
|
1454
2419
|
else
|
|
@@ -1458,9 +2423,102 @@ export function buildProgram(options = {}) {
|
|
|
1458
2423
|
await writeCatalogSourceFailure('catalog:source:remove', id, rawOptions.json === true, error);
|
|
1459
2424
|
}
|
|
1460
2425
|
});
|
|
2426
|
+
const catalogStore = catalog
|
|
2427
|
+
.command('store')
|
|
2428
|
+
.description('Inspect or prune the immutable Catalog store');
|
|
2429
|
+
catalogStore
|
|
2430
|
+
.command('status')
|
|
2431
|
+
.option('-j, --json', 'print Catalog store status as JSON', false)
|
|
2432
|
+
.action(async (rawOptions) => {
|
|
2433
|
+
try {
|
|
2434
|
+
const result = await catalogStoreStatus({ env });
|
|
2435
|
+
if (rawOptions.json) {
|
|
2436
|
+
writeJsonReceipt(io.stdout, result);
|
|
2437
|
+
}
|
|
2438
|
+
else if (result.entries.length === 0) {
|
|
2439
|
+
writeLine(io.stdout, 'Catalog store is empty.');
|
|
2440
|
+
}
|
|
2441
|
+
else {
|
|
2442
|
+
for (const entry of result.entries) {
|
|
2443
|
+
const bytes = entry.reclaimableBytes === null ? 'unknown bytes' : `${entry.reclaimableBytes} bytes`;
|
|
2444
|
+
writeLine(io.stdout, `${entry.storeKey}: ${entry.category}, ${entry.status}, ${entry.reason}, ${bytes}`);
|
|
2445
|
+
}
|
|
2446
|
+
writeLine(io.stdout, `Reclaimable: ${result.totals.reclaimableEntries} item(s).`);
|
|
2447
|
+
if (result.errors.length > 0) {
|
|
2448
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2452
|
+
}
|
|
2453
|
+
catch (error) {
|
|
2454
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2455
|
+
const message = redactString(failure.message);
|
|
2456
|
+
if (rawOptions.json)
|
|
2457
|
+
writeJsonReceipt(io.stdout, {
|
|
2458
|
+
catalogStoreSchemaVersion: 2,
|
|
2459
|
+
command: 'catalog:store:status',
|
|
2460
|
+
ok: false,
|
|
2461
|
+
entries: [],
|
|
2462
|
+
errors: [{ code: catalogStoreErrorCode(error), message }],
|
|
2463
|
+
});
|
|
2464
|
+
writeLine(io.stderr, message);
|
|
2465
|
+
commandExitState.exitCode = 1;
|
|
2466
|
+
}
|
|
2467
|
+
});
|
|
2468
|
+
catalogStore
|
|
2469
|
+
.command('prune')
|
|
2470
|
+
.option('--dry-run', 'inspect reclaimable items without deleting them', false)
|
|
2471
|
+
.option('-y, --yes', 'delete items classified as safely reclaimable', false)
|
|
2472
|
+
.option('-j, --json', 'print the prune receipt as JSON', false)
|
|
2473
|
+
.action(async (rawOptions) => {
|
|
2474
|
+
const dryRun = rawOptions.yes !== true;
|
|
2475
|
+
try {
|
|
2476
|
+
if (rawOptions.dryRun === true && rawOptions.yes === true) {
|
|
2477
|
+
throw Object.assign(new Error('catalog store prune cannot combine `--dry-run` and `--yes`.'), {
|
|
2478
|
+
code: 'invalidArguments',
|
|
2479
|
+
});
|
|
2480
|
+
}
|
|
2481
|
+
const result = await catalogStorePrune({ dryRun, env });
|
|
2482
|
+
if (rawOptions.json) {
|
|
2483
|
+
writeJsonReceipt(io.stdout, result);
|
|
2484
|
+
}
|
|
2485
|
+
else if (dryRun) {
|
|
2486
|
+
writeLine(io.stdout, `Dry run: ${result.entries.filter((entry) => entry.status === 'reclaimable').length} item(s) are reclaimable.`);
|
|
2487
|
+
writeLine(io.stdout, 'Run `aw catalog store prune --yes` to delete them.');
|
|
2488
|
+
if (result.errors.length > 0)
|
|
2489
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2490
|
+
}
|
|
2491
|
+
else {
|
|
2492
|
+
writeLine(io.stdout, `Deleted ${result.deleted.length} Catalog store item(s) (${result.deletedBytes} bytes).`);
|
|
2493
|
+
if (result.errors.length > 0)
|
|
2494
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected or deleted and were retained.`);
|
|
2495
|
+
}
|
|
2496
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2497
|
+
}
|
|
2498
|
+
catch (error) {
|
|
2499
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2500
|
+
const message = redactString(failure.message);
|
|
2501
|
+
const code = catalogStoreErrorCode(error);
|
|
2502
|
+
if (rawOptions.json)
|
|
2503
|
+
writeJsonReceipt(io.stdout, {
|
|
2504
|
+
catalogStoreSchemaVersion: 2,
|
|
2505
|
+
command: 'catalog:store:prune',
|
|
2506
|
+
ok: false,
|
|
2507
|
+
overallState: 'failed',
|
|
2508
|
+
dryRun,
|
|
2509
|
+
entries: [],
|
|
2510
|
+
deleted: [],
|
|
2511
|
+
retained: [],
|
|
2512
|
+
errors: [{ code, message }],
|
|
2513
|
+
reclaimableBytes: null,
|
|
2514
|
+
deletedBytes: 0,
|
|
2515
|
+
});
|
|
2516
|
+
writeLine(io.stderr, message);
|
|
2517
|
+
commandExitState.exitCode = 1;
|
|
2518
|
+
}
|
|
2519
|
+
});
|
|
1461
2520
|
program
|
|
1462
2521
|
.command('init')
|
|
1463
|
-
.option('-f, --force', 're-fetch and rebuild the current catalog cache entry', false)
|
|
1464
2522
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1465
2523
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1466
2524
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1468,8 +2526,6 @@ export function buildProgram(options = {}) {
|
|
|
1468
2526
|
.action(async (rawOptions) => {
|
|
1469
2527
|
const context = createActionContext('init', rawOptions);
|
|
1470
2528
|
const result = await runActionWithContext(context, () => initCommand({
|
|
1471
|
-
force: rawOptions.force,
|
|
1472
|
-
cliVersion: resolveCliVersion(),
|
|
1473
2529
|
env: context.env,
|
|
1474
2530
|
}));
|
|
1475
2531
|
if (rawOptions.json) {
|
|
@@ -1480,7 +2536,6 @@ export function buildProgram(options = {}) {
|
|
|
1480
2536
|
writeLine(io.stdout, line);
|
|
1481
2537
|
}
|
|
1482
2538
|
}
|
|
1483
|
-
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1484
2539
|
for (const source of result.sources) {
|
|
1485
2540
|
if (!source.ok && source.error)
|
|
1486
2541
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
@@ -1488,53 +2543,79 @@ export function buildProgram(options = {}) {
|
|
|
1488
2543
|
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1489
2544
|
});
|
|
1490
2545
|
program
|
|
1491
|
-
.command('
|
|
2546
|
+
.command('sync')
|
|
2547
|
+
.description('Reconcile actual state from existing desired intent')
|
|
1492
2548
|
.argument('[plugins...]')
|
|
1493
|
-
.
|
|
1494
|
-
.
|
|
1495
|
-
.option('
|
|
1496
|
-
.option('
|
|
2549
|
+
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
2550
|
+
.requiredOption('-p, --platform <platform>', 'codex, claude, or both')
|
|
2551
|
+
.option('-a, --all', 'reconcile every desired plugin in the selected scope', false)
|
|
2552
|
+
.option('--refresh', 'refresh only Catalog sources required by selected intent roots', false)
|
|
2553
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2554
|
+
.option('-y, --yes', 'authorize preApply and shared native replacement or forced repair', false)
|
|
2555
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2556
|
+
.option('-j, --json', 'print sync receipt as JSON', false)
|
|
1497
2557
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1498
2558
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1499
2559
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1500
2560
|
.action(async (plugins, rawOptions) => {
|
|
1501
|
-
const context = createActionContext('
|
|
1502
|
-
const
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
2561
|
+
const context = createActionContext('sync', rawOptions);
|
|
2562
|
+
const normalized = normalizeWriteRequest(() => normalizeInstallCommandOptions({
|
|
2563
|
+
cwd: context.cwd,
|
|
2564
|
+
scope: rawOptions.scope,
|
|
2565
|
+
platform: rawOptions.platform,
|
|
2566
|
+
scriptTimeout: rawOptions.scriptTimeout,
|
|
2567
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2568
|
+
}));
|
|
2569
|
+
const syncPlatform = normalized.platform;
|
|
2570
|
+
const result = await runActionWithContext(context, () => syncCommand(plugins ?? [], {
|
|
2571
|
+
cwd: context.cwd,
|
|
2572
|
+
env: context.env,
|
|
2573
|
+
platform: syncPlatform,
|
|
2574
|
+
scope: normalized.scope,
|
|
2575
|
+
all: rawOptions.all,
|
|
2576
|
+
refresh: rawOptions.refresh,
|
|
2577
|
+
cliVersion: resolveCliVersion(),
|
|
2578
|
+
yes: rawOptions.yes,
|
|
2579
|
+
json: rawOptions.json,
|
|
2580
|
+
interactive: context.interactive && context.isTty && !context.isCi,
|
|
2581
|
+
prompt: context.prompt,
|
|
2582
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2583
|
+
scriptTimeoutMs: normalized.scriptTimeoutMs,
|
|
2584
|
+
}, context));
|
|
1506
2585
|
if (rawOptions.json) {
|
|
1507
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2586
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('sync', result));
|
|
1508
2587
|
}
|
|
1509
2588
|
else {
|
|
1510
|
-
for (const line of renderRebuildReceipt('
|
|
2589
|
+
for (const line of renderRebuildReceipt('sync', result))
|
|
1511
2590
|
writeLine(io.stdout, line);
|
|
1512
|
-
}
|
|
1513
2591
|
}
|
|
1514
|
-
writeWarnings(io.stderr,
|
|
1515
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(
|
|
2592
|
+
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
2593
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1516
2594
|
});
|
|
1517
2595
|
program
|
|
1518
|
-
.command('
|
|
2596
|
+
.command('install')
|
|
1519
2597
|
.argument('[plugins...]')
|
|
1520
2598
|
.option('-s, --scope <scope>', 'project or user')
|
|
1521
2599
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1522
|
-
.option('--
|
|
2600
|
+
.option('--dependency-scope <pluginId[#platform]=scope>', 'place one dependency at project or user scope; repeat for more dependencies', (value, previous) => [...previous, value], [])
|
|
2601
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2602
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2603
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement', false)
|
|
1523
2604
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1524
2605
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1525
2606
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1526
2607
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1527
2608
|
.action(async (plugins, rawOptions) => {
|
|
1528
|
-
const context = createActionContext('
|
|
1529
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2609
|
+
const context = createActionContext('install', rawOptions);
|
|
2610
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('install', plugins ?? [], rawOptions, context));
|
|
1530
2611
|
if (outcome.cancelled)
|
|
1531
2612
|
return;
|
|
1532
2613
|
const receipt = outcome.result;
|
|
1533
2614
|
if (rawOptions.json) {
|
|
1534
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2615
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('install', receipt));
|
|
1535
2616
|
}
|
|
1536
2617
|
else {
|
|
1537
|
-
for (const line of renderRebuildReceipt('
|
|
2618
|
+
for (const line of renderRebuildReceipt('install', receipt)) {
|
|
1538
2619
|
writeLine(io.stdout, line);
|
|
1539
2620
|
}
|
|
1540
2621
|
}
|
|
@@ -1542,27 +2623,26 @@ export function buildProgram(options = {}) {
|
|
|
1542
2623
|
commandExitState.exitCode = resolveCommandReceiptExitCode(receipt);
|
|
1543
2624
|
});
|
|
1544
2625
|
program
|
|
1545
|
-
.command('
|
|
2626
|
+
.command('uninstall')
|
|
1546
2627
|
.argument('[plugins...]')
|
|
1547
|
-
.option('-a, --all', 'upgrade all plugins', false)
|
|
1548
2628
|
.option('-s, --scope <scope>', 'project or user')
|
|
1549
2629
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1550
|
-
.option('--
|
|
2630
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1551
2631
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1552
2632
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1553
2633
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1554
2634
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1555
2635
|
.action(async (plugins, rawOptions) => {
|
|
1556
|
-
const context = createActionContext('
|
|
1557
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2636
|
+
const context = createActionContext('uninstall', rawOptions);
|
|
2637
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('uninstall', plugins ?? [], rawOptions, context));
|
|
1558
2638
|
if (outcome.cancelled)
|
|
1559
2639
|
return;
|
|
1560
2640
|
const receipt = outcome.result;
|
|
1561
2641
|
if (rawOptions.json) {
|
|
1562
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2642
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('uninstall', receipt));
|
|
1563
2643
|
}
|
|
1564
2644
|
else {
|
|
1565
|
-
for (const line of renderRebuildReceipt('
|
|
2645
|
+
for (const line of renderRebuildReceipt('uninstall', receipt)) {
|
|
1566
2646
|
writeLine(io.stdout, line);
|
|
1567
2647
|
}
|
|
1568
2648
|
}
|
|
@@ -1575,7 +2655,8 @@ export function buildProgram(options = {}) {
|
|
|
1575
2655
|
.option('-s, --scope <scope>', 'project or user')
|
|
1576
2656
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1577
2657
|
.option('-j, --json', 'print cleanup result as JSON', false)
|
|
1578
|
-
.option('--force', '
|
|
2658
|
+
.option('--force', 'use exact shallow evidence for exclusively owned damaged output; preserve foreign and shared content', false)
|
|
2659
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1579
2660
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1580
2661
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1581
2662
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
@@ -1594,14 +2675,16 @@ export function buildProgram(options = {}) {
|
|
|
1594
2675
|
}
|
|
1595
2676
|
}
|
|
1596
2677
|
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1597
|
-
commandExitState.exitCode = result
|
|
2678
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1598
2679
|
});
|
|
1599
2680
|
program
|
|
1600
2681
|
.command('reinstall')
|
|
1601
2682
|
.argument('[plugins...]')
|
|
1602
2683
|
.option('-s, --scope <scope>', 'project or user')
|
|
1603
2684
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1604
|
-
.option('--script-timeout <ms>', 'override plugin
|
|
2685
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2686
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2687
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement or forced reinstall', false)
|
|
1605
2688
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1606
2689
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1607
2690
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1631,7 +2714,6 @@ export function buildProgram(options = {}) {
|
|
|
1631
2714
|
.command('list')
|
|
1632
2715
|
.argument('[plugin]')
|
|
1633
2716
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1634
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1635
2717
|
.option('-j, --json', 'print config as JSON', false)
|
|
1636
2718
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1637
2719
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1639,9 +2721,7 @@ export function buildProgram(options = {}) {
|
|
|
1639
2721
|
.action(async (pluginName, rawOptions) => {
|
|
1640
2722
|
const context = createActionContext('config:list', rawOptions);
|
|
1641
2723
|
const outcome = await runActionWithContext(context, async () => {
|
|
1642
|
-
|
|
1643
|
-
if (!rawOptions.local)
|
|
1644
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2724
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1645
2725
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1646
2726
|
selector: selectedPlugin,
|
|
1647
2727
|
rawOptions,
|
|
@@ -1666,7 +2746,6 @@ export function buildProgram(options = {}) {
|
|
|
1666
2746
|
command: 'list',
|
|
1667
2747
|
plugin: selection.plugins[0],
|
|
1668
2748
|
scope: rawOptions.scope,
|
|
1669
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1670
2749
|
})),
|
|
1671
2750
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1672
2751
|
});
|
|
@@ -1688,8 +2767,7 @@ export function buildProgram(options = {}) {
|
|
|
1688
2767
|
pluginId: resolved.pluginId,
|
|
1689
2768
|
sourceId: resolved.sourceId,
|
|
1690
2769
|
sourceIdentity: resolved.sourceIdentity,
|
|
1691
|
-
scope: rawOptions.
|
|
1692
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2770
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1693
2771
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1694
2772
|
fields: resolved.result.fields,
|
|
1695
2773
|
});
|
|
@@ -1703,7 +2781,6 @@ export function buildProgram(options = {}) {
|
|
|
1703
2781
|
.argument('[plugin]')
|
|
1704
2782
|
.argument('[key]')
|
|
1705
2783
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1706
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1707
2784
|
.option('-j, --json', 'print config as JSON', false)
|
|
1708
2785
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1709
2786
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1711,9 +2788,7 @@ export function buildProgram(options = {}) {
|
|
|
1711
2788
|
.action(async (pluginName, key, rawOptions) => {
|
|
1712
2789
|
const context = createActionContext('config:get', rawOptions);
|
|
1713
2790
|
const outcome = await runActionWithContext(context, async () => {
|
|
1714
|
-
|
|
1715
|
-
if (!rawOptions.local)
|
|
1716
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2791
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1717
2792
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1718
2793
|
selector: selectedPlugin,
|
|
1719
2794
|
...(key === undefined ? {} : { key }),
|
|
@@ -1740,7 +2815,6 @@ export function buildProgram(options = {}) {
|
|
|
1740
2815
|
plugin: selection.plugins[0],
|
|
1741
2816
|
key,
|
|
1742
2817
|
scope: rawOptions.scope,
|
|
1743
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1744
2818
|
})),
|
|
1745
2819
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1746
2820
|
});
|
|
@@ -1763,8 +2837,7 @@ export function buildProgram(options = {}) {
|
|
|
1763
2837
|
sourceId: resolved.sourceId,
|
|
1764
2838
|
sourceIdentity: resolved.sourceIdentity,
|
|
1765
2839
|
key,
|
|
1766
|
-
scope: rawOptions.
|
|
1767
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2840
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1768
2841
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1769
2842
|
fields: resolved.result.fields,
|
|
1770
2843
|
});
|
|
@@ -1776,47 +2849,119 @@ export function buildProgram(options = {}) {
|
|
|
1776
2849
|
config
|
|
1777
2850
|
.command('set')
|
|
1778
2851
|
.argument('[plugin]')
|
|
1779
|
-
.argument('[
|
|
1780
|
-
.argument('[value]')
|
|
2852
|
+
.argument('[field]')
|
|
1781
2853
|
.option('-s, --scope <scope>', 'project or user')
|
|
1782
|
-
.option('--
|
|
1783
|
-
.option('--value-
|
|
2854
|
+
.option('--value-json <json>', 'set the field to an exact JSON value')
|
|
2855
|
+
.option('--value-stdin', 'read the exact string value from stdin until EOF', false)
|
|
2856
|
+
.option('--preset <id>', 'set the field to the current manifest preset value')
|
|
2857
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2858
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2859
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1784
2860
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1785
2861
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1786
2862
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1787
2863
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1788
|
-
.action(async (pluginName, key,
|
|
2864
|
+
.action(async (pluginName, key, rawOptions) => {
|
|
2865
|
+
if (!pluginName || !key)
|
|
2866
|
+
throw new Error(configCommandUsage('set'));
|
|
1789
2867
|
const context = createActionContext('config:set', rawOptions);
|
|
1790
2868
|
let outcome;
|
|
1791
2869
|
try {
|
|
1792
2870
|
outcome = await runActionWithContext(context, async () => {
|
|
1793
2871
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
1794
|
-
const
|
|
1795
|
-
const
|
|
1796
|
-
|
|
1797
|
-
|
|
2872
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2873
|
+
const explicitValueCount = [
|
|
2874
|
+
rawOptions.valueJson !== undefined,
|
|
2875
|
+
rawOptions.valueStdin === true,
|
|
2876
|
+
rawOptions.preset !== undefined,
|
|
2877
|
+
].filter(Boolean).length;
|
|
2878
|
+
if (explicitValueCount > 1
|
|
2879
|
+
|| (explicitValueCount === 0
|
|
2880
|
+
&& !(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true))) {
|
|
2881
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2882
|
+
}
|
|
2883
|
+
return withResolvedConfigMutationPlugin(context, pluginName, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2884
|
+
if (!plugin.manifest.config?.fields) {
|
|
2885
|
+
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1798
2886
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
2887
|
+
const field = plugin.manifest.config.fields[key];
|
|
2888
|
+
if (!field) {
|
|
2889
|
+
throw new Error(`Unknown config key "${key}".`);
|
|
2890
|
+
}
|
|
2891
|
+
const sensitive = field.sensitive === true;
|
|
2892
|
+
if (sensitive && scope !== 'user') {
|
|
2893
|
+
const error = new Error('sensitiveProjectConfigUnsupported: Sensitive config can only be set in user scope.');
|
|
2894
|
+
error.code = 'sensitiveProjectConfigUnsupported';
|
|
2895
|
+
throw error;
|
|
2896
|
+
}
|
|
2897
|
+
if (sensitive && (rawOptions.valueJson !== undefined || rawOptions.preset !== undefined)) {
|
|
2898
|
+
const error = new Error('sensitiveConfigInputUnsupported: Sensitive config cannot use --value-json or --preset.');
|
|
2899
|
+
error.code = 'sensitiveConfigInputUnsupported';
|
|
2900
|
+
throw error;
|
|
2901
|
+
}
|
|
2902
|
+
if (!sensitive && explicitValueCount !== 1) {
|
|
2903
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2904
|
+
}
|
|
2905
|
+
let inputValue;
|
|
2906
|
+
if (rawOptions.valueStdin === true) {
|
|
2907
|
+
inputValue = await readUtf8Stdin(context.stdin);
|
|
2908
|
+
}
|
|
2909
|
+
else if (sensitive) {
|
|
2910
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
2911
|
+
|| !context.prompt.password) {
|
|
2912
|
+
const error = new Error('sensitiveConfigStdinRequired: Use --value-stdin for sensitive config outside an interactive terminal.');
|
|
2913
|
+
error.code = 'sensitiveConfigStdinRequired';
|
|
2914
|
+
throw error;
|
|
2915
|
+
}
|
|
2916
|
+
const response = await context.prompt.password({
|
|
2917
|
+
message: `输入 ${field.title ?? key}`,
|
|
2918
|
+
mask: true,
|
|
2919
|
+
});
|
|
2920
|
+
if (response.cancelled || response.action !== 'select' || response.value === undefined) {
|
|
2921
|
+
const error = new Error('sensitiveConfigInputCancelled: Sensitive config input was cancelled.');
|
|
2922
|
+
error.code = 'sensitiveConfigInputCancelled';
|
|
2923
|
+
throw error;
|
|
2924
|
+
}
|
|
2925
|
+
inputValue = response.value;
|
|
2926
|
+
}
|
|
2927
|
+
else if (rawOptions.valueJson !== undefined) {
|
|
2928
|
+
try {
|
|
2929
|
+
inputValue = JSON.parse(rawOptions.valueJson);
|
|
2930
|
+
}
|
|
2931
|
+
catch {
|
|
2932
|
+
throw new Error('--value-json must contain valid JSON.');
|
|
2933
|
+
}
|
|
2934
|
+
}
|
|
2935
|
+
else {
|
|
2936
|
+
const preset = field.choices?.presets.find((entry) => entry.id === rawOptions.preset);
|
|
2937
|
+
if (!preset)
|
|
2938
|
+
throw new Error(`Unknown preset "${rawOptions.preset}" for config key "${key}".`);
|
|
2939
|
+
inputValue = structuredClone(preset.value);
|
|
1801
2940
|
}
|
|
1802
2941
|
const writeReceipt = await applyPluginConfigWrite({
|
|
1803
2942
|
plugin,
|
|
1804
2943
|
pluginName: plugin.manifest.name,
|
|
1805
2944
|
scope,
|
|
1806
|
-
projectLayer,
|
|
1807
2945
|
cwd: context.cwd,
|
|
1808
2946
|
env: context.env,
|
|
1809
2947
|
nativeCliRunner: context.nativeCliRunner,
|
|
1810
|
-
rebuildRuntime: {
|
|
2948
|
+
rebuildRuntime: {
|
|
2949
|
+
...context,
|
|
2950
|
+
awHomeMutationToken,
|
|
2951
|
+
catalogOperationContext,
|
|
2952
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
2953
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
2954
|
+
},
|
|
1811
2955
|
awHomeMutationToken,
|
|
1812
2956
|
request: {
|
|
1813
|
-
updates: { [
|
|
2957
|
+
updates: { [key]: inputValue },
|
|
1814
2958
|
},
|
|
2959
|
+
apply: rawOptions.apply === true,
|
|
2960
|
+
sharedNativeApplyConfirmed: rawOptions.yes === true,
|
|
2961
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
1815
2962
|
});
|
|
1816
|
-
return {
|
|
2963
|
+
return buildConfigMutationReceipt('config:set', {
|
|
1817
2964
|
ok: writeReceipt.overallState === 'succeeded',
|
|
1818
|
-
receiptSchemaVersion: 4,
|
|
1819
|
-
command: 'config:set',
|
|
1820
2965
|
...writeReceipt,
|
|
1821
2966
|
plugin: plugin.manifest.name,
|
|
1822
2967
|
pluginName: plugin.manifest.name,
|
|
@@ -1824,104 +2969,39 @@ export function buildProgram(options = {}) {
|
|
|
1824
2969
|
sourceId: source.sourceId,
|
|
1825
2970
|
sourceIdentity: source.sourceIdentity,
|
|
1826
2971
|
affectedFields: [{
|
|
1827
|
-
key
|
|
1828
|
-
title:
|
|
2972
|
+
key,
|
|
2973
|
+
title: field.title ?? key,
|
|
1829
2974
|
kind: 'manifest',
|
|
1830
2975
|
reserved: false,
|
|
1831
2976
|
action: 'set',
|
|
1832
2977
|
scope,
|
|
1833
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
1834
2978
|
}],
|
|
1835
|
-
};
|
|
1836
|
-
});
|
|
1837
|
-
if (pluginName && key && rawValue !== undefined) {
|
|
1838
|
-
const inputValue = parseConfigValue(rawValue, rawOptions.valueJson === true);
|
|
1839
|
-
return {
|
|
1840
|
-
cancelled: false,
|
|
1841
|
-
key,
|
|
1842
|
-
value: await execute(pluginName, key, inputValue),
|
|
1843
|
-
};
|
|
1844
|
-
}
|
|
1845
|
-
if (!isWizardAvailable(context, rawOptions))
|
|
1846
|
-
throw new Error(configCommandUsage('set'));
|
|
1847
|
-
const candidates = await loadWizardCandidates(context, {});
|
|
1848
|
-
if (pluginName) {
|
|
1849
|
-
const candidate = candidates.find((entry) => entry.pluginName === pluginName);
|
|
1850
|
-
if (!candidate)
|
|
1851
|
-
throw new Error(`Unknown plugin "${pluginName}".`);
|
|
1852
|
-
if (!hasConfigSchemaKeys(candidate)) {
|
|
1853
|
-
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1854
|
-
}
|
|
1855
|
-
if (key && !candidate.configSchema?.[key])
|
|
1856
|
-
throw new Error(`Unknown config key "${key}".`);
|
|
1857
|
-
}
|
|
1858
|
-
const configurableCandidates = candidates.filter(hasConfigSchemaKeys);
|
|
1859
|
-
if (configurableCandidates.length === 0) {
|
|
1860
|
-
throw new Error('configSchemaUnavailable: No current plugin declares an AW config schema.');
|
|
1861
|
-
}
|
|
1862
|
-
const result = await runCommandWizard(context, {
|
|
1863
|
-
command: 'config:set',
|
|
1864
|
-
candidates: configurableCandidates,
|
|
1865
|
-
initial: {
|
|
1866
|
-
plugins: pluginName ? [pluginName] : [],
|
|
1867
|
-
key,
|
|
1868
|
-
...(rawValue !== undefined ? { value: rawValue } : {}),
|
|
1869
|
-
scope,
|
|
1870
|
-
projectLayer,
|
|
1871
|
-
},
|
|
1872
|
-
pluginMode: pluginName ? 'none' : 'single',
|
|
1873
|
-
valueJson: rawOptions.valueJson === true,
|
|
1874
|
-
promptForKey: key === undefined,
|
|
1875
|
-
promptForValue: rawValue === undefined,
|
|
1876
|
-
...equivalentConfigCommandProjection((selection) => configSetEquivalentOptions(selection, candidates, rawOptions)),
|
|
1877
|
-
commandIsTemplate: (selection) => candidates.find((entry) => entry.pluginName === selection.plugins[0])?.configSchema?.[selection.key ?? ''] !== undefined
|
|
1878
|
-
&& configFieldPlaceholder(candidates.find((entry) => entry.pluginName === selection.plugins[0])?.configSchema?.[selection.key ?? '']) !== undefined,
|
|
1879
|
-
resultState: overallResultState,
|
|
1880
|
-
execute: async (selection) => {
|
|
1881
|
-
const selectedPlugin = selection.plugins[0];
|
|
1882
|
-
const selectedKey = selection.key;
|
|
1883
|
-
const schema = candidates.find((entry) => entry.pluginName === selectedPlugin).configSchema;
|
|
1884
|
-
const updates = await coercePluginConfigUpdates({
|
|
1885
|
-
schema,
|
|
1886
|
-
updates: {
|
|
1887
|
-
[selectedKey]: parseConfigValue(selection.value, rawOptions.valueJson === true),
|
|
1888
|
-
},
|
|
1889
|
-
cwd: context.cwd,
|
|
1890
|
-
});
|
|
1891
|
-
return execute(selectedPlugin, selectedKey, updates[selectedKey]);
|
|
1892
|
-
},
|
|
2979
|
+
});
|
|
1893
2980
|
});
|
|
1894
|
-
return result.cancelled
|
|
1895
|
-
? { cancelled: true }
|
|
1896
|
-
: { cancelled: false, key: result.selection.key, value: result.value };
|
|
1897
2981
|
});
|
|
1898
2982
|
}
|
|
1899
2983
|
catch (error) {
|
|
1900
2984
|
writeConfigMutationFailure('config:set', pluginName, rawOptions.json === true, error);
|
|
1901
2985
|
return;
|
|
1902
2986
|
}
|
|
1903
|
-
|
|
1904
|
-
return;
|
|
1905
|
-
const receipt = outcome.value;
|
|
1906
|
-
const selectedKey = outcome.key;
|
|
2987
|
+
const receipt = outcome;
|
|
1907
2988
|
if (rawOptions.json) {
|
|
1908
2989
|
writeJsonReceipt(io.stdout, receipt);
|
|
1909
2990
|
}
|
|
1910
2991
|
else {
|
|
1911
|
-
writeLine(io.stdout, `已写入 ${receipt.plugin}.${
|
|
1912
|
-
if (receipt.projectLayer === 'local') {
|
|
1913
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
1914
|
-
}
|
|
2992
|
+
writeLine(io.stdout, `已写入 ${receipt.plugin}.${key}(${configLayerLabel(receipt.scope)}配置)。`);
|
|
1915
2993
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
1916
2994
|
}
|
|
1917
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
2995
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
1918
2996
|
});
|
|
1919
2997
|
config
|
|
1920
2998
|
.command('unset')
|
|
1921
2999
|
.argument('[plugin]')
|
|
1922
3000
|
.argument('[key]')
|
|
1923
3001
|
.option('-s, --scope <scope>', 'project or user')
|
|
1924
|
-
.option('--
|
|
3002
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3003
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3004
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1925
3005
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1926
3006
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1927
3007
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1932,19 +3012,17 @@ export function buildProgram(options = {}) {
|
|
|
1932
3012
|
try {
|
|
1933
3013
|
outcome = await runActionWithContext(context, async () => {
|
|
1934
3014
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
1935
|
-
const
|
|
1936
|
-
const execute = async (selectedPlugin, selectedKey) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken) => {
|
|
1937
|
-
if (plugin.manifest.config?.schema && !plugin.manifest.config.schema[selectedKey]) {
|
|
1938
|
-
throw new Error(`Unknown config key "${selectedKey}".`);
|
|
1939
|
-
}
|
|
3015
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
3016
|
+
const execute = async (selectedPlugin, selectedKey, confirmed) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
1940
3017
|
const store = await readPluginConfigStore({
|
|
1941
3018
|
sourceId: source.sourceId,
|
|
1942
3019
|
sourceIdentity: source.sourceIdentity,
|
|
3020
|
+
logicalIdentity: source.logicalIdentity,
|
|
1943
3021
|
pluginName: plugin.manifest.name,
|
|
1944
3022
|
scope,
|
|
1945
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
1946
3023
|
cwd: context.cwd,
|
|
1947
3024
|
env: context.env,
|
|
3025
|
+
schema: plugin.manifest.config?.fields,
|
|
1948
3026
|
});
|
|
1949
3027
|
const existed = Object.hasOwn(store.values, selectedKey);
|
|
1950
3028
|
if (!existed)
|
|
@@ -1953,20 +3031,26 @@ export function buildProgram(options = {}) {
|
|
|
1953
3031
|
plugin,
|
|
1954
3032
|
pluginName: plugin.manifest.name,
|
|
1955
3033
|
scope,
|
|
1956
|
-
projectLayer,
|
|
1957
3034
|
cwd: context.cwd,
|
|
1958
3035
|
env: context.env,
|
|
1959
3036
|
nativeCliRunner: context.nativeCliRunner,
|
|
1960
|
-
rebuildRuntime: {
|
|
3037
|
+
rebuildRuntime: {
|
|
3038
|
+
...context,
|
|
3039
|
+
awHomeMutationToken,
|
|
3040
|
+
catalogOperationContext,
|
|
3041
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
3042
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
3043
|
+
},
|
|
1961
3044
|
awHomeMutationToken,
|
|
1962
3045
|
request: {
|
|
1963
3046
|
removeKeys: [selectedKey],
|
|
1964
3047
|
},
|
|
3048
|
+
apply: rawOptions.apply === true,
|
|
3049
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
3050
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
1965
3051
|
});
|
|
1966
|
-
return {
|
|
3052
|
+
return buildConfigMutationReceipt('config:unset', {
|
|
1967
3053
|
ok: writeReceipt.overallState === 'succeeded',
|
|
1968
|
-
receiptSchemaVersion: 4,
|
|
1969
|
-
command: 'config:unset',
|
|
1970
3054
|
...writeReceipt,
|
|
1971
3055
|
plugin: plugin.manifest.name,
|
|
1972
3056
|
pluginName: plugin.manifest.name,
|
|
@@ -1977,17 +3061,20 @@ export function buildProgram(options = {}) {
|
|
|
1977
3061
|
existed,
|
|
1978
3062
|
affectedFields: [{
|
|
1979
3063
|
key: selectedKey,
|
|
1980
|
-
title: plugin?.manifest.config?.
|
|
3064
|
+
title: plugin?.manifest.config?.fields?.[selectedKey]?.title ?? selectedKey,
|
|
1981
3065
|
kind: 'manifest',
|
|
1982
3066
|
reserved: false,
|
|
1983
3067
|
action: 'unset',
|
|
1984
3068
|
scope,
|
|
1985
|
-
...(
|
|
3069
|
+
...(!plugin.manifest.config?.fields?.[selectedKey] ? { stale: true } : {}),
|
|
1986
3070
|
}],
|
|
1987
|
-
};
|
|
3071
|
+
});
|
|
1988
3072
|
});
|
|
1989
3073
|
if (pluginName && key) {
|
|
1990
|
-
return {
|
|
3074
|
+
return {
|
|
3075
|
+
cancelled: false,
|
|
3076
|
+
value: await execute(pluginName, key, rawOptions.yes === true),
|
|
3077
|
+
};
|
|
1991
3078
|
}
|
|
1992
3079
|
if (!isWizardAvailable(context, rawOptions))
|
|
1993
3080
|
throw new Error(configCommandUsage('unset'));
|
|
@@ -2003,7 +3090,7 @@ export function buildProgram(options = {}) {
|
|
|
2003
3090
|
const result = await runCommandWizard(context, {
|
|
2004
3091
|
command: 'config:unset',
|
|
2005
3092
|
candidates,
|
|
2006
|
-
initial: { plugins: pluginName ? [pluginName] : [], key, scope
|
|
3093
|
+
initial: { plugins: pluginName ? [pluginName] : [], key, scope },
|
|
2007
3094
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2008
3095
|
promptForKey: key === undefined,
|
|
2009
3096
|
destructive: true,
|
|
@@ -2012,10 +3099,9 @@ export function buildProgram(options = {}) {
|
|
|
2012
3099
|
plugin: selection.plugins[0],
|
|
2013
3100
|
key: selection.key,
|
|
2014
3101
|
scope: selection.scope ?? 'user',
|
|
2015
|
-
projectLayer: selection.projectLayer,
|
|
2016
3102
|
})),
|
|
2017
3103
|
resultState: overallResultState,
|
|
2018
|
-
execute: (selection) => execute(selection.plugins[0], selection.key),
|
|
3104
|
+
execute: (selection) => execute(selection.plugins[0], selection.key, true),
|
|
2019
3105
|
});
|
|
2020
3106
|
return result.cancelled
|
|
2021
3107
|
? { cancelled: true }
|
|
@@ -2034,21 +3120,19 @@ export function buildProgram(options = {}) {
|
|
|
2034
3120
|
}
|
|
2035
3121
|
else {
|
|
2036
3122
|
writeLine(io.stdout, receipt.existed
|
|
2037
|
-
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope
|
|
2038
|
-
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope
|
|
2039
|
-
if (receipt.projectLayer === 'local') {
|
|
2040
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
2041
|
-
}
|
|
3123
|
+
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)。`
|
|
3124
|
+
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)原本不存在。`);
|
|
2042
3125
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2043
3126
|
}
|
|
2044
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3127
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2045
3128
|
});
|
|
2046
3129
|
config
|
|
2047
3130
|
.command('reset')
|
|
2048
3131
|
.argument('[plugin]')
|
|
2049
3132
|
.option('-s, --scope <scope>', 'project or user')
|
|
2050
|
-
.option('--
|
|
2051
|
-
.option('-
|
|
3133
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3134
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3135
|
+
.option('-y, --yes', 'confirm destructive reset and preApply/shared Codex native config apply', false)
|
|
2052
3136
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
2053
3137
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2054
3138
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -2058,61 +3142,79 @@ export function buildProgram(options = {}) {
|
|
|
2058
3142
|
let outcome;
|
|
2059
3143
|
try {
|
|
2060
3144
|
outcome = await runActionWithContext(context, async () => {
|
|
2061
|
-
const execute = async (selectedPlugin, selectedScope,
|
|
3145
|
+
const execute = async (selectedPlugin, selectedScope, confirmed) => {
|
|
3146
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2062
3147
|
if (!confirmed) {
|
|
2063
|
-
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope}
|
|
3148
|
+
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope} --yes\` to delete this store.`);
|
|
2064
3149
|
}
|
|
2065
|
-
|
|
3150
|
+
const located = await resolveStoredConfigResetIdentity({
|
|
3151
|
+
selector: selectedPlugin,
|
|
3152
|
+
context,
|
|
3153
|
+
scope: selectedScope,
|
|
3154
|
+
});
|
|
3155
|
+
const resetLocatedStore = async (plugin, pluginError) => {
|
|
2066
3156
|
const affectedFields = await describeResetAffectedFields({
|
|
2067
|
-
|
|
3157
|
+
sourceId: located.sourceId,
|
|
3158
|
+
sourceIdentity: located.sourceIdentity,
|
|
3159
|
+
logicalIdentity: located.logicalIdentity,
|
|
3160
|
+
pluginName: located.pluginName,
|
|
2068
3161
|
plugin,
|
|
3162
|
+
pluginError,
|
|
2069
3163
|
scope: selectedScope,
|
|
2070
|
-
projectLayer,
|
|
2071
3164
|
cwd: context.cwd,
|
|
2072
3165
|
env: context.env,
|
|
2073
|
-
});
|
|
3166
|
+
}).catch(() => []);
|
|
2074
3167
|
const resetReceipt = await resetPluginConfigWithHelper({
|
|
2075
|
-
|
|
3168
|
+
sourceId: located.sourceId,
|
|
3169
|
+
sourceIdentity: located.sourceIdentity,
|
|
3170
|
+
logicalIdentity: located.logicalIdentity,
|
|
3171
|
+
pluginName: located.pluginName,
|
|
2076
3172
|
scope: selectedScope,
|
|
2077
|
-
projectLayer,
|
|
2078
3173
|
cwd: context.cwd,
|
|
2079
3174
|
env: context.env,
|
|
2080
3175
|
nativeCliRunner: context.nativeCliRunner,
|
|
2081
|
-
rebuildRuntime: { ...context, awHomeMutationToken },
|
|
2082
|
-
awHomeMutationToken,
|
|
2083
3176
|
plugin,
|
|
3177
|
+
pluginError,
|
|
3178
|
+
apply: rawOptions.apply === true,
|
|
3179
|
+
rebuildRuntime: scriptTimeoutMs === undefined ? undefined : { scriptTimeoutMs },
|
|
3180
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
3181
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
2084
3182
|
});
|
|
2085
|
-
return {
|
|
3183
|
+
return buildConfigMutationReceipt('config:reset', {
|
|
2086
3184
|
ok: resetReceipt.overallState === 'succeeded',
|
|
2087
|
-
receiptSchemaVersion: 4,
|
|
2088
|
-
command: 'config:reset',
|
|
2089
3185
|
...resetReceipt,
|
|
2090
|
-
plugin:
|
|
2091
|
-
pluginName:
|
|
2092
|
-
pluginId,
|
|
2093
|
-
sourceId:
|
|
2094
|
-
sourceIdentity:
|
|
3186
|
+
plugin: located.pluginName,
|
|
3187
|
+
pluginName: located.pluginName,
|
|
3188
|
+
pluginId: located.pluginId,
|
|
3189
|
+
sourceId: located.sourceId,
|
|
3190
|
+
...(located.sourceIdentity ? { sourceIdentity: located.sourceIdentity } : {}),
|
|
2095
3191
|
affectedFields,
|
|
2096
|
-
};
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
3192
|
+
});
|
|
3193
|
+
};
|
|
3194
|
+
let resetStarted = false;
|
|
3195
|
+
try {
|
|
3196
|
+
return await withResolvedCatalogPlugin({
|
|
3197
|
+
selector: located.pluginId,
|
|
3198
|
+
cliVersion: resolveCliVersion(),
|
|
3199
|
+
env: context.env,
|
|
3200
|
+
consume: async ({ plugin }) => {
|
|
3201
|
+
resetStarted = true;
|
|
3202
|
+
return resetLocatedStore(plugin, null);
|
|
3203
|
+
},
|
|
3204
|
+
});
|
|
3205
|
+
}
|
|
3206
|
+
catch (error) {
|
|
3207
|
+
if (resetStarted)
|
|
3208
|
+
throw error;
|
|
3209
|
+
return resetLocatedStore(null, error instanceof Error ? error : new Error(String(error)));
|
|
3210
|
+
}
|
|
2108
3211
|
};
|
|
2109
3212
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
2110
|
-
const projectLayer = resolveConfigProjectLayer(rawOptions);
|
|
2111
3213
|
const needsWizard = pluginName === undefined || rawOptions.yes !== true;
|
|
2112
3214
|
if (!needsWizard) {
|
|
2113
3215
|
return {
|
|
2114
3216
|
cancelled: false,
|
|
2115
|
-
value: await execute(pluginName, scope,
|
|
3217
|
+
value: await execute(pluginName, scope, true),
|
|
2116
3218
|
};
|
|
2117
3219
|
}
|
|
2118
3220
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
@@ -2120,16 +3222,16 @@ export function buildProgram(options = {}) {
|
|
|
2120
3222
|
throw new Error(configCommandUsage('reset'));
|
|
2121
3223
|
return {
|
|
2122
3224
|
cancelled: false,
|
|
2123
|
-
value: await execute(pluginName, scope,
|
|
3225
|
+
value: await execute(pluginName, scope, false),
|
|
2124
3226
|
};
|
|
2125
3227
|
}
|
|
2126
3228
|
const currentCandidates = pluginName ? [] : await loadWizardCandidates(context, {});
|
|
2127
3229
|
const candidatesByScope = new Map();
|
|
2128
3230
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'user')) {
|
|
2129
|
-
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user'
|
|
3231
|
+
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user' }], { includeEmptyStores: true })));
|
|
2130
3232
|
}
|
|
2131
3233
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'project')) {
|
|
2132
|
-
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project'
|
|
3234
|
+
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project' }], { includeEmptyStores: true })));
|
|
2133
3235
|
}
|
|
2134
3236
|
const candidates = mergeWizardCandidates(candidatesByScope.get('user') ?? [], candidatesByScope.get('project') ?? []);
|
|
2135
3237
|
if (!pluginName && candidates.length === 0) {
|
|
@@ -2138,7 +3240,7 @@ export function buildProgram(options = {}) {
|
|
|
2138
3240
|
const result = await runCommandWizard(context, {
|
|
2139
3241
|
command: 'config:reset',
|
|
2140
3242
|
candidates,
|
|
2141
|
-
initial: { plugins: pluginName ? [pluginName] : [], scope
|
|
3243
|
+
initial: { plugins: pluginName ? [pluginName] : [], scope },
|
|
2142
3244
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2143
3245
|
promptForScope: rawOptions.scope === undefined,
|
|
2144
3246
|
destructive: true,
|
|
@@ -2149,11 +3251,10 @@ export function buildProgram(options = {}) {
|
|
|
2149
3251
|
command: 'reset',
|
|
2150
3252
|
plugin: selection.plugins[0],
|
|
2151
3253
|
scope: selection.scope ?? 'user',
|
|
2152
|
-
projectLayer: selection.projectLayer,
|
|
2153
3254
|
confirmed: true,
|
|
2154
3255
|
})),
|
|
2155
3256
|
resultState: overallResultState,
|
|
2156
|
-
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user',
|
|
3257
|
+
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user', true),
|
|
2157
3258
|
});
|
|
2158
3259
|
return result.cancelled
|
|
2159
3260
|
? { cancelled: true }
|
|
@@ -2172,14 +3273,11 @@ export function buildProgram(options = {}) {
|
|
|
2172
3273
|
}
|
|
2173
3274
|
else {
|
|
2174
3275
|
writeLine(io.stdout, receipt.deleted
|
|
2175
|
-
? `已重置 ${receipt.plugin} 的${configLayerLabel(receipt.scope
|
|
2176
|
-
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope
|
|
2177
|
-
if (receipt.projectLayer === 'local') {
|
|
2178
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
2179
|
-
}
|
|
3276
|
+
? `已重置 ${receipt.plugin} 的${configLayerLabel(receipt.scope)}配置。`
|
|
3277
|
+
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope)}配置。`);
|
|
2180
3278
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2181
3279
|
}
|
|
2182
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3280
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2183
3281
|
});
|
|
2184
3282
|
program
|
|
2185
3283
|
.command('status')
|
|
@@ -2192,7 +3290,7 @@ export function buildProgram(options = {}) {
|
|
|
2192
3290
|
.option('-j, --json', 'print status as JSON', false)
|
|
2193
3291
|
.action(async (plugins, rawOptions) => {
|
|
2194
3292
|
const context = createActionContext('status', rawOptions);
|
|
2195
|
-
const result = await runActionWithContext(context, () =>
|
|
3293
|
+
const result = await runActionWithContext(context, () => statusCommandV8({
|
|
2196
3294
|
plugins: plugins ?? [],
|
|
2197
3295
|
cwd,
|
|
2198
3296
|
env: context.env,
|
|
@@ -2205,11 +3303,11 @@ export function buildProgram(options = {}) {
|
|
|
2205
3303
|
commandExitState.exitCode = result.hasErrors ? 1 : 0;
|
|
2206
3304
|
writeLine(io.stdout, result.output);
|
|
2207
3305
|
for (const source of result.payload.catalog.sources) {
|
|
2208
|
-
if (source.error)
|
|
3306
|
+
if (rawOptions.json && source.error)
|
|
2209
3307
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
2210
3308
|
}
|
|
2211
3309
|
for (const error of result.payload.errors) {
|
|
2212
|
-
if (error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
3310
|
+
if (rawOptions.json && error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
2213
3311
|
writeLine(io.stderr, error.message);
|
|
2214
3312
|
}
|
|
2215
3313
|
}
|
|
@@ -2234,18 +3332,31 @@ export async function runCli(argv, options = {}) {
|
|
|
2234
3332
|
...createDefaultIo(),
|
|
2235
3333
|
...options.io,
|
|
2236
3334
|
};
|
|
3335
|
+
const reviewCommand = argv[0] === 'review' && ['inspect', 'prepare'].includes(argv[1] ?? '')
|
|
3336
|
+
? argv[1]
|
|
3337
|
+
: null;
|
|
3338
|
+
const jsonReviewCommand = reviewCommand !== null && argv.includes('--json');
|
|
2237
3339
|
const jsonAuthoringCommand = argv.includes('--json')
|
|
2238
|
-
&& ((argv[0] === 'catalog' && ['init', 'version', 'build', 'validate', 'publish'].includes(argv[1] ?? ''))
|
|
2239
|
-
|| (argv[0] === 'plugin' && ['build', 'test'].includes(argv[1] ?? ''))
|
|
3340
|
+
&& ((argv[0] === 'catalog' && ['init', 'context', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
|
|
3341
|
+
|| (argv[0] === 'plugin' && ['build', 'test', 'validate', 'status', 'remove'].includes(argv[1] ?? ''))
|
|
3342
|
+
|| reviewCommand !== null)
|
|
2240
3343
|
? `${argv[0]}:${argv[1]}`
|
|
2241
3344
|
: null;
|
|
3345
|
+
const jsonCatalogDevCommand = argv.includes('--json')
|
|
3346
|
+
&& argv[0] === 'catalog'
|
|
3347
|
+
&& argv[1] === 'dev'
|
|
3348
|
+
&& ['activate', 'status', 'deactivate'].includes(argv[2] ?? '')
|
|
3349
|
+
? argv[2]
|
|
3350
|
+
: null;
|
|
3351
|
+
const jsonWriteRequest = jsonWriteCommandRequest(argv);
|
|
3352
|
+
const jsonConfigMutation = jsonConfigMutationRequest(argv);
|
|
2242
3353
|
try {
|
|
2243
3354
|
const authoringScriptByCommand = {
|
|
2244
3355
|
init: 'init-plugin.mjs',
|
|
2245
3356
|
'add-skill': 'add-skill.mjs',
|
|
3357
|
+
remove: 'remove-plugin.mjs',
|
|
2246
3358
|
validate: 'validate-plugin.mjs',
|
|
2247
3359
|
status: 'plugin-status.mjs',
|
|
2248
|
-
'check-versions': 'check-plugin-versions.mjs',
|
|
2249
3360
|
};
|
|
2250
3361
|
const authoringScript = argv[0] === 'plugin'
|
|
2251
3362
|
? authoringScriptByCommand[argv[1] ?? '']
|
|
@@ -2254,29 +3365,85 @@ export async function runCli(argv, options = {}) {
|
|
|
2254
3365
|
: undefined;
|
|
2255
3366
|
if (authoringScript && !argv.includes('--help') && !argv.includes('-h')) {
|
|
2256
3367
|
const authoringArgs = argv.slice(2);
|
|
3368
|
+
let authoringEnv = options.env ?? process.env;
|
|
2257
3369
|
if (argv[0] === 'plugin'
|
|
2258
|
-
&&
|
|
2259
|
-
|
|
2260
|
-
|
|
3370
|
+
&& !authoringArgs.some((token) => token === '--plugin-root' || token.startsWith('--plugin-root='))) {
|
|
3371
|
+
let explicitRoot;
|
|
3372
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3373
|
+
const token = authoringArgs[index];
|
|
3374
|
+
if (token.startsWith('--workspace-root='))
|
|
3375
|
+
explicitRoot = token.slice('--workspace-root='.length);
|
|
3376
|
+
if (token === '--workspace-root')
|
|
3377
|
+
explicitRoot = authoringArgs[index + 1];
|
|
3378
|
+
}
|
|
3379
|
+
const originalCwd = options.cwd ?? process.cwd();
|
|
3380
|
+
let discoveryCwd = originalCwd;
|
|
3381
|
+
if (argv[1] === 'validate') {
|
|
3382
|
+
const valueOptions = new Set(['--workspace-root', '--claude-skill-profile', '--version-base']);
|
|
3383
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3384
|
+
const token = authoringArgs[index];
|
|
3385
|
+
if (valueOptions.has(token)) {
|
|
3386
|
+
index += 1;
|
|
3387
|
+
continue;
|
|
3388
|
+
}
|
|
3389
|
+
if (!token.startsWith('-')) {
|
|
3390
|
+
discoveryCwd = path.resolve(originalCwd, token);
|
|
3391
|
+
authoringArgs[index] = discoveryCwd;
|
|
3392
|
+
break;
|
|
3393
|
+
}
|
|
3394
|
+
}
|
|
3395
|
+
}
|
|
3396
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
3397
|
+
cwd: discoveryCwd,
|
|
3398
|
+
...(explicitRoot === undefined ? {} : { explicitRoot: path.resolve(options.cwd ?? process.cwd(), explicitRoot) }),
|
|
3399
|
+
mode: 'existing',
|
|
3400
|
+
});
|
|
3401
|
+
authoringEnv = {
|
|
3402
|
+
...authoringEnv,
|
|
3403
|
+
AW_AUTHORING_WORKSPACE_ROOT: workspace.workspaceRoot,
|
|
3404
|
+
AW_AUTHORING_WORKSPACE_ROOT_RESOLVED_FROM: workspace.workspaceRootResolvedFrom,
|
|
3405
|
+
};
|
|
3406
|
+
if (explicitRoot === undefined)
|
|
3407
|
+
authoringArgs.push('--workspace-root', workspace.workspaceRoot);
|
|
2261
3408
|
}
|
|
2262
3409
|
return runAuthoringScript({
|
|
2263
3410
|
scriptName: authoringScript,
|
|
2264
3411
|
args: authoringArgs,
|
|
2265
3412
|
cwd: options.cwd ?? process.cwd(),
|
|
2266
|
-
env:
|
|
3413
|
+
env: authoringEnv,
|
|
2267
3414
|
io,
|
|
2268
3415
|
});
|
|
2269
3416
|
}
|
|
2270
|
-
if (
|
|
3417
|
+
if (!jsonConfigMutation
|
|
3418
|
+
&& argv.some((token) => token === '--subdir' || token.startsWith('--subdir='))
|
|
2271
3419
|
&& argv.includes('--no-subdir')) {
|
|
2272
3420
|
const message = 'option --subdir cannot be used with option --no-subdir';
|
|
2273
3421
|
if (argv.includes('--json') && argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update') {
|
|
2274
3422
|
writeJsonReceipt(io.stdout, {
|
|
2275
|
-
receiptSchemaVersion:
|
|
3423
|
+
receiptSchemaVersion: 6,
|
|
3424
|
+
command: 'catalog:source:update',
|
|
3425
|
+
ok: false,
|
|
3426
|
+
changed: false,
|
|
3427
|
+
sourceId: argv[3] ?? '',
|
|
3428
|
+
primaryChange: null,
|
|
3429
|
+
references: [],
|
|
3430
|
+
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
3431
|
+
});
|
|
3432
|
+
}
|
|
3433
|
+
writeLine(io.stderr, `error: ${message}`);
|
|
3434
|
+
return 1;
|
|
3435
|
+
}
|
|
3436
|
+
if (argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update'
|
|
3437
|
+
&& argv.includes('--auto-check') && argv.includes('--no-auto-check')) {
|
|
3438
|
+
const message = 'option --auto-check cannot be used with option --no-auto-check';
|
|
3439
|
+
if (argv.includes('--json') || argv.includes('-j')) {
|
|
3440
|
+
writeJsonReceipt(io.stdout, {
|
|
3441
|
+
receiptSchemaVersion: 6,
|
|
2276
3442
|
command: 'catalog:source:update',
|
|
2277
3443
|
ok: false,
|
|
2278
3444
|
changed: false,
|
|
2279
3445
|
sourceId: argv[3] ?? '',
|
|
3446
|
+
primaryChange: null,
|
|
2280
3447
|
references: [],
|
|
2281
3448
|
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
2282
3449
|
});
|
|
@@ -2304,9 +3471,30 @@ export async function runCli(argv, options = {}) {
|
|
|
2304
3471
|
}
|
|
2305
3472
|
return await runActionWithContext(context, () => runConsoleController(context));
|
|
2306
3473
|
}
|
|
3474
|
+
let catalogPublicationActionStarted = false;
|
|
3475
|
+
let configMutationActionStarted = false;
|
|
3476
|
+
const programIo = jsonCatalogDevCommand || jsonWriteRequest || jsonReviewCommand
|
|
3477
|
+
? { ...io, stderr: () => undefined }
|
|
3478
|
+
: jsonConfigMutation
|
|
3479
|
+
? {
|
|
3480
|
+
...io,
|
|
3481
|
+
stderr: (text) => {
|
|
3482
|
+
if (configMutationActionStarted)
|
|
3483
|
+
io.stderr(text);
|
|
3484
|
+
},
|
|
3485
|
+
}
|
|
3486
|
+
: jsonAuthoringCommand === 'catalog:publish'
|
|
3487
|
+
? {
|
|
3488
|
+
...io,
|
|
3489
|
+
stderr: (text) => {
|
|
3490
|
+
if (catalogPublicationActionStarted)
|
|
3491
|
+
io.stderr(text);
|
|
3492
|
+
},
|
|
3493
|
+
}
|
|
3494
|
+
: io;
|
|
2307
3495
|
const program = buildProgram({
|
|
2308
3496
|
...options,
|
|
2309
|
-
io,
|
|
3497
|
+
io: programIo,
|
|
2310
3498
|
diagnostics: {
|
|
2311
3499
|
...options.diagnostics,
|
|
2312
3500
|
metadata: {
|
|
@@ -2315,16 +3503,139 @@ export async function runCli(argv, options = {}) {
|
|
|
2315
3503
|
},
|
|
2316
3504
|
},
|
|
2317
3505
|
});
|
|
3506
|
+
if (jsonAuthoringCommand === 'catalog:publish') {
|
|
3507
|
+
program.hook('preAction', () => {
|
|
3508
|
+
catalogPublicationActionStarted = true;
|
|
3509
|
+
});
|
|
3510
|
+
}
|
|
3511
|
+
if (jsonConfigMutation) {
|
|
3512
|
+
program.hook('preAction', () => {
|
|
3513
|
+
configMutationActionStarted = true;
|
|
3514
|
+
});
|
|
3515
|
+
}
|
|
2318
3516
|
await program.parseAsync(['node', 'aw', ...argv]);
|
|
2319
3517
|
return program.__awCommandExitState?.exitCode ?? 0;
|
|
2320
3518
|
}
|
|
2321
3519
|
catch (error) {
|
|
2322
|
-
if (
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
3520
|
+
if (reviewCommand && error instanceof CommanderError) {
|
|
3521
|
+
if (error.exitCode === 0)
|
|
3522
|
+
return 0;
|
|
3523
|
+
if (jsonReviewCommand) {
|
|
3524
|
+
const receipt = reviewCommand === 'inspect'
|
|
3525
|
+
? createReviewInspectionFailure(new Error(error.message), requestedReviewView(argv), 'invalidArguments')
|
|
3526
|
+
: createReviewPreparationFailure(error.message);
|
|
3527
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
3528
|
+
}
|
|
3529
|
+
return 2;
|
|
3530
|
+
}
|
|
3531
|
+
if (jsonCatalogDevCommand) {
|
|
3532
|
+
const workspaceRootIndex = argv.findIndex((token) => token === '--workspace-root');
|
|
3533
|
+
const workspaceRootOption = argv.find((token) => token.startsWith('--workspace-root='));
|
|
3534
|
+
const workspaceRoot = workspaceRootOption?.slice('--workspace-root='.length)
|
|
3535
|
+
?? (workspaceRootIndex >= 0 ? argv[workspaceRootIndex + 1] : undefined);
|
|
3536
|
+
const sourceIdIndex = argv.findIndex((token) => token === '--source-id');
|
|
3537
|
+
const sourceIdOption = argv.find((token) => token.startsWith('--source-id='));
|
|
3538
|
+
const sourceId = sourceIdOption?.slice('--source-id='.length)
|
|
3539
|
+
?? (sourceIdIndex >= 0 ? argv[sourceIdIndex + 1] : undefined);
|
|
3540
|
+
const failure = error instanceof CommanderError
|
|
3541
|
+
? { code: 'invalidArguments', message: error.message }
|
|
3542
|
+
: catalogDevSourceError(error);
|
|
3543
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
3544
|
+
command: jsonCatalogDevCommand,
|
|
3545
|
+
cwd: options.cwd ?? process.cwd(),
|
|
3546
|
+
workspaceRoot,
|
|
3547
|
+
sourceId,
|
|
3548
|
+
...failure,
|
|
3549
|
+
}));
|
|
3550
|
+
return 1;
|
|
3551
|
+
}
|
|
3552
|
+
if (jsonWriteRequest) {
|
|
3553
|
+
writeCommandFailureReceipt(io.stdout, jsonWriteRequest, error);
|
|
3554
|
+
return 1;
|
|
3555
|
+
}
|
|
3556
|
+
if (jsonConfigMutation) {
|
|
3557
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
3558
|
+
return 0;
|
|
3559
|
+
const failure = configMutationFailure(error, options.env ?? process.env, options.cwd ?? process.cwd());
|
|
3560
|
+
writeConfigMutationFailureReceipt(io.stdout, error instanceof CommanderError
|
|
3561
|
+
? { command: jsonConfigMutation.command }
|
|
3562
|
+
: jsonConfigMutation, failure);
|
|
3563
|
+
writeLine(io.stderr, failure.message);
|
|
3564
|
+
return 1;
|
|
3565
|
+
}
|
|
3566
|
+
if (jsonAuthoringCommand === 'catalog:publish' && error instanceof CommanderError) {
|
|
3567
|
+
const failure = catalogPublicationFailure({
|
|
3568
|
+
error: new CatalogPublicationInspectionError('invalidArguments', error.message),
|
|
3569
|
+
env: options.env,
|
|
3570
|
+
sensitiveRoots: [options.cwd ?? process.cwd()],
|
|
2327
3571
|
});
|
|
3572
|
+
writeJsonReceipt(io.stdout, failure);
|
|
3573
|
+
writeLine(io.stderr, failure.message);
|
|
3574
|
+
return 1;
|
|
3575
|
+
}
|
|
3576
|
+
if (jsonAuthoringCommand && !(error instanceof CommanderError)) {
|
|
3577
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3578
|
+
if (jsonAuthoringCommand === 'plugin:validate') {
|
|
3579
|
+
writeJsonReceipt(io.stdout, {
|
|
3580
|
+
ok: false,
|
|
3581
|
+
profile: 'unknown',
|
|
3582
|
+
warnings: [],
|
|
3583
|
+
errors: [message],
|
|
3584
|
+
});
|
|
3585
|
+
}
|
|
3586
|
+
else if (jsonAuthoringCommand === 'plugin:status') {
|
|
3587
|
+
writeJsonReceipt(io.stdout, {
|
|
3588
|
+
schemaVersion: 3,
|
|
3589
|
+
policy: 'development',
|
|
3590
|
+
ok: false,
|
|
3591
|
+
base: null,
|
|
3592
|
+
requestedBase: null,
|
|
3593
|
+
baseCommit: null,
|
|
3594
|
+
checkedPlugins: 0,
|
|
3595
|
+
checks: [],
|
|
3596
|
+
workspaceRoot: null,
|
|
3597
|
+
workspaceRootResolvedFrom: null,
|
|
3598
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
else if (jsonAuthoringCommand === 'plugin:remove') {
|
|
3602
|
+
writeJsonReceipt(io.stdout, {
|
|
3603
|
+
schemaVersion: 1,
|
|
3604
|
+
command: 'plugin:remove',
|
|
3605
|
+
ok: false,
|
|
3606
|
+
workspaceRoot: null,
|
|
3607
|
+
workspaceRootResolvedFrom: null,
|
|
3608
|
+
baseCommit: null,
|
|
3609
|
+
plugin: null,
|
|
3610
|
+
removed: false,
|
|
3611
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3612
|
+
});
|
|
3613
|
+
}
|
|
3614
|
+
else if (jsonAuthoringCommand === 'review:inspect') {
|
|
3615
|
+
writeJsonReceipt(io.stdout, createReviewInspectionFailure(error, requestedReviewView(argv)));
|
|
3616
|
+
}
|
|
3617
|
+
else if (jsonAuthoringCommand === 'review:prepare') {
|
|
3618
|
+
writeJsonReceipt(io.stdout, createReviewPreparationFailure(message, 'reviewPreparationFailed'));
|
|
3619
|
+
}
|
|
3620
|
+
else {
|
|
3621
|
+
writeJsonReceipt(io.stdout, {
|
|
3622
|
+
command: jsonAuthoringCommand,
|
|
3623
|
+
ok: false,
|
|
3624
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
return 1;
|
|
3628
|
+
}
|
|
3629
|
+
if (jsonAuthoringCommand && error instanceof CommanderError) {
|
|
3630
|
+
writeJsonReceipt(io.stdout, jsonAuthoringCommand === 'review:inspect'
|
|
3631
|
+
? createReviewInspectionFailure(new Error(error.message), requestedReviewView(argv), 'invalidArguments')
|
|
3632
|
+
: jsonAuthoringCommand === 'review:prepare'
|
|
3633
|
+
? createReviewPreparationFailure(error.message)
|
|
3634
|
+
: {
|
|
3635
|
+
command: jsonAuthoringCommand,
|
|
3636
|
+
ok: false,
|
|
3637
|
+
errors: [{ code: 'invalidArguments', message: error.message }],
|
|
3638
|
+
});
|
|
2328
3639
|
}
|
|
2329
3640
|
return handleCliError(error, io.stderr);
|
|
2330
3641
|
}
|