@lesliechan721/aw 0.1.0-beta.4 → 0.1.0-beta.40
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/assets/aw-runtime-config.d.mts +13 -0
- package/dist/authoring/assets/aw-runtime-config.mjs +199 -0
- package/dist/authoring/assets/aw-runtime-config.mjs.map +1 -0
- 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 +353 -1175
- 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 +30 -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 +263 -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 +146 -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 +163 -0
- package/dist/src/commands/plugin-capabilities.js.map +1 -0
- package/dist/src/commands/rebuild-command.d.ts +78 -30
- package/dist/src/commands/rebuild-command.js +4877 -713
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +132 -21
- package/dist/src/commands/rebuild-integration.js +2853 -1327
- 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 +260 -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 +39 -0
- package/dist/src/commands/skill-eval.js +400 -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 +2787 -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 +8 -5
- package/dist/src/commands/wizard.js +6 -4
- 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 +127 -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 +228 -104
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +10 -4
- package/dist/src/index.js +1835 -469
- 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 +179 -41
- 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 +234 -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 +183 -0
- package/dist/src/review/source-binding.js +708 -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 +32 -0
- package/dist/src/tui/catalog-sources/session.js +300 -0
- package/dist/src/tui/catalog-sources/session.js.map +1 -0
- package/dist/src/tui/catalog-sources/types.d.ts +54 -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/clipboard.d.ts +13 -0
- package/dist/src/tui/clipboard.js +95 -0
- package/dist/src/tui/clipboard.js.map +1 -0
- package/dist/src/tui/components.d.ts +177 -0
- package/dist/src/tui/components.js +297 -7
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/config-array-draft.d.ts +29 -0
- package/dist/src/tui/config-array-draft.js +48 -0
- package/dist/src/tui/config-array-draft.js.map +1 -0
- package/dist/src/tui/config-leaf-editor.d.ts +16 -0
- package/dist/src/tui/config-leaf-editor.js +206 -0
- package/dist/src/tui/config-leaf-editor.js.map +1 -0
- package/dist/src/tui/config-value-presentation.d.ts +20 -0
- package/dist/src/tui/config-value-presentation.js +104 -0
- package/dist/src/tui/config-value-presentation.js.map +1 -0
- package/dist/src/tui/console-app-v4.d.ts +14 -4
- package/dist/src/tui/console-app-v4.js +9659 -1558
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/content-item-card.d.ts +13 -0
- package/dist/src/tui/content-item-card.js +51 -0
- package/dist/src/tui/content-item-card.js.map +1 -0
- package/dist/src/tui/controller-runtime.d.ts +13 -1
- package/dist/src/tui/controller-runtime.js +3323 -349
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +643 -40
- package/dist/src/tui/controller.js +3756 -705
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/dependency-graph-view.d.ts +39 -0
- package/dist/src/tui/dependency-graph-view.js +121 -0
- package/dist/src/tui/dependency-graph-view.js.map +1 -0
- package/dist/src/tui/dependency-graph.d.ts +81 -0
- package/dist/src/tui/dependency-graph.js +452 -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 +31 -0
- package/dist/src/tui/diagnostics.js +83 -0
- package/dist/src/tui/diagnostics.js.map +1 -0
- package/dist/src/tui/entity-cards.d.ts +55 -0
- package/dist/src/tui/entity-cards.js +220 -0
- package/dist/src/tui/entity-cards.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 +9 -0
- package/dist/src/tui/input-display.js +58 -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 +248 -27
- package/dist/src/tui/model.js +1662 -314
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +8 -0
- package/dist/src/tui/operation-diagnostic-screens.js +71 -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 +136 -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 +1295 -0
- package/dist/src/tui/operation-review-planner.js.map +1 -0
- package/dist/src/tui/plugin-content.d.ts +31 -0
- package/dist/src/tui/plugin-content.js +680 -0
- package/dist/src/tui/plugin-content.js.map +1 -0
- package/dist/src/tui/plugin-detail.d.ts +52 -0
- package/dist/src/tui/plugin-detail.js +165 -0
- package/dist/src/tui/plugin-detail.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/project-inventory.d.ts +68 -0
- package/dist/src/tui/project-inventory.js +203 -0
- package/dist/src/tui/project-inventory.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/query-header.d.ts +30 -0
- package/dist/src/tui/query-header.js +40 -0
- package/dist/src/tui/query-header.js.map +1 -0
- package/dist/src/tui/reader.d.ts +37 -0
- package/dist/src/tui/reader.js +47 -0
- package/dist/src/tui/reader.js.map +1 -0
- package/dist/src/tui/router.d.ts +207 -14
- 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 +701 -0
- package/dist/src/tui/screen-registry.js +230 -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-detail-card.d.ts +29 -0
- package/dist/src/tui/source-detail-card.js +45 -0
- package/dist/src/tui/source-detail-card.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 +30 -10
- package/dist/src/tui/theme.js +30 -10
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/viewport.d.ts +21 -0
- package/dist/src/tui/viewport.js +52 -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 +37 -13
- package/dist/src/tui/wizard.js.map +1 -1
- package/dist/src/types.d.ts +244 -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 +17 -7
- package/dist/src/utils/artifact-renderer.js +214 -216
- 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 +78 -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 +22 -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 +16 -0
- package/dist/src/utils/git-catalog-provider.js +169 -144
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +17 -1
- package/dist/src/utils/local-marketplace.js +301 -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 +1000 -296
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +153 -93
- package/dist/src/utils/plugin-config.js +1163 -1017
- 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 +65 -125
- package/dist/src/utils/plugin-scripts.js +482 -524
- 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/runtime-config.d.ts +20 -0
- package/dist/src/utils/runtime-config.js +75 -0
- package/dist/src/utils/runtime-config.js.map +1 -0
- 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,55 @@ 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 === 'cleanup' ? ['--yes'] : []),
|
|
470
|
+
...(command === 'install'
|
|
471
|
+
? (rawOptions.dependencyScope ?? []).flatMap((value) => ['--dependency-scope', value])
|
|
472
|
+
: []),
|
|
473
|
+
...((command === 'install' || command === 'reinstall')
|
|
474
|
+
? optionTokens('--script-timeout', rawOptions.scriptTimeout)
|
|
475
|
+
: []),
|
|
476
|
+
...(selection.plugins.length > 0 ? ['--', ...selection.plugins] : []),
|
|
144
477
|
];
|
|
145
478
|
}
|
|
146
479
|
function equivalentConfigCommand(options) {
|
|
@@ -152,39 +485,14 @@ function equivalentConfigCommandProjection(resolve) {
|
|
|
152
485
|
equivalentCommandTokens: (selection) => buildEquivalentConfigCommandTokens(resolve(selection)),
|
|
153
486
|
};
|
|
154
487
|
}
|
|
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
488
|
export function buildEquivalentConfigCommandTokens(options) {
|
|
181
489
|
return [
|
|
182
490
|
'aw',
|
|
183
491
|
'config',
|
|
184
492
|
options.command,
|
|
185
493
|
...optionTokens('--scope', options.scope),
|
|
186
|
-
...(
|
|
187
|
-
...(
|
|
494
|
+
...optionTokens('--value-json', options.valueJson),
|
|
495
|
+
...optionTokens('--preset', options.preset),
|
|
188
496
|
...(options.confirmed ? ['--yes'] : []),
|
|
189
497
|
'--',
|
|
190
498
|
options.plugin,
|
|
@@ -207,7 +515,6 @@ async function loadWizardCandidates(context, rawOptions) {
|
|
|
207
515
|
cwd: context.cwd,
|
|
208
516
|
scope: rawOptions.scope,
|
|
209
517
|
platform: rawOptions.platform,
|
|
210
|
-
includeCatalogOnly: true,
|
|
211
518
|
}, context);
|
|
212
519
|
return toWizardCandidates(loaded.items);
|
|
213
520
|
}
|
|
@@ -235,7 +542,6 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
235
542
|
cwd: context.cwd,
|
|
236
543
|
env: context.env,
|
|
237
544
|
scope: location.scope,
|
|
238
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
239
545
|
});
|
|
240
546
|
for (const store of stores) {
|
|
241
547
|
const keys = Object.keys(store.values);
|
|
@@ -243,12 +549,11 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
243
549
|
continue;
|
|
244
550
|
const existing = storesByPlugin.get(store.pluginId) ?? {
|
|
245
551
|
sourceId: store.sourceId,
|
|
246
|
-
|
|
552
|
+
...(store.binding.kind === 'source'
|
|
553
|
+
? { sourceIdentity: store.binding.sourceIdentity }
|
|
554
|
+
: {}),
|
|
247
555
|
keys: new Set(),
|
|
248
556
|
};
|
|
249
|
-
if (existing.sourceIdentity !== store.sourceIdentity) {
|
|
250
|
-
throw new Error(`sourceChanged: ${store.pluginId} config stores have different source identities.`);
|
|
251
|
-
}
|
|
252
557
|
for (const key of keys)
|
|
253
558
|
existing.keys.add(key);
|
|
254
559
|
storesByPlugin.set(store.pluginId, existing);
|
|
@@ -260,26 +565,53 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
260
565
|
pluginName: pluginId,
|
|
261
566
|
pluginId,
|
|
262
567
|
sourceId: store.sourceId,
|
|
263
|
-
sourceIdentity: store.sourceIdentity,
|
|
568
|
+
...(store.sourceIdentity ? { sourceIdentity: store.sourceIdentity } : {}),
|
|
264
569
|
targets: [],
|
|
265
570
|
configKeys: [...store.keys].sort((left, right) => left.localeCompare(right)),
|
|
266
571
|
}));
|
|
267
572
|
}
|
|
268
573
|
function configReadStoreLocations(rawOptions) {
|
|
269
|
-
if (rawOptions.local)
|
|
270
|
-
return [{ scope: 'project', projectLayer: 'local' }];
|
|
271
574
|
if (rawOptions.scope === 'user')
|
|
272
|
-
return [{ scope: 'user'
|
|
575
|
+
return [{ scope: 'user' }];
|
|
273
576
|
if (rawOptions.scope === 'project')
|
|
274
|
-
return [{ scope: 'project'
|
|
577
|
+
return [{ scope: 'project' }];
|
|
275
578
|
return [
|
|
276
|
-
{ scope: 'user'
|
|
277
|
-
{ scope: 'project'
|
|
278
|
-
{ scope: 'project', projectLayer: 'local' },
|
|
579
|
+
{ scope: 'user' },
|
|
580
|
+
{ scope: 'project' },
|
|
279
581
|
];
|
|
280
582
|
}
|
|
281
583
|
function overallResultState(value) {
|
|
282
|
-
return value.overallState;
|
|
584
|
+
return value.overallState === 'succeeded' ? 'succeeded' : 'failed';
|
|
585
|
+
}
|
|
586
|
+
async function resolveStoredConfigResetIdentity(options) {
|
|
587
|
+
const parsed = parsePluginId(options.selector);
|
|
588
|
+
if (parsed.sourceId) {
|
|
589
|
+
return {
|
|
590
|
+
pluginName: parsed.pluginName,
|
|
591
|
+
pluginId: options.selector,
|
|
592
|
+
sourceId: parsed.sourceId,
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
const matches = (await listNamespacedPluginConfigStores({
|
|
596
|
+
cwd: options.context.cwd,
|
|
597
|
+
env: options.context.env,
|
|
598
|
+
scope: options.scope,
|
|
599
|
+
})).filter((store) => store.pluginName === parsed.pluginName);
|
|
600
|
+
if (matches.length === 0) {
|
|
601
|
+
throw new Error(`configStoreMissing: ${options.selector} has no config in the selected store.`);
|
|
602
|
+
}
|
|
603
|
+
if (matches.length > 1) {
|
|
604
|
+
throw new Error(`configTargetAmbiguous: ${options.selector} exists in multiple source namespaces: ${matches.map((store) => store.pluginId).join(', ')}. Use a full pluginId.`);
|
|
605
|
+
}
|
|
606
|
+
const [match] = matches;
|
|
607
|
+
return {
|
|
608
|
+
pluginName: match.pluginName,
|
|
609
|
+
pluginId: match.pluginId,
|
|
610
|
+
sourceId: match.sourceId,
|
|
611
|
+
...(match.binding.kind === 'source'
|
|
612
|
+
? { sourceIdentity: match.binding.sourceIdentity }
|
|
613
|
+
: { logicalIdentity: match.binding.logicalIdentity }),
|
|
614
|
+
};
|
|
283
615
|
}
|
|
284
616
|
async function resolveStoredOnlyConfigIdentity(options) {
|
|
285
617
|
const parsed = parsePluginId(options.selector);
|
|
@@ -289,33 +621,43 @@ async function resolveStoredOnlyConfigIdentity(options) {
|
|
|
289
621
|
cwd: options.context.cwd,
|
|
290
622
|
env: options.context.env,
|
|
291
623
|
scope: location.scope,
|
|
292
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
293
624
|
})))).flat().filter((store) => store.pluginId === options.selector);
|
|
294
625
|
if (stores.length === 0)
|
|
295
626
|
throw new Error(`Plugin "${options.selector}" does not have a namespaced config store.`);
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
627
|
+
const sourceBindings = stores.flatMap((store) => store.binding.kind === 'source'
|
|
628
|
+
? [store.binding.sourceIdentity] : []);
|
|
629
|
+
const catalogBindings = stores.flatMap((store) => store.binding.kind === 'catalog'
|
|
630
|
+
? [store.binding.logicalIdentity] : []);
|
|
631
|
+
if (new Set(sourceBindings).size > 1 || new Set(catalogBindings).size > 1) {
|
|
632
|
+
throw new Error(`identityMismatch: ${options.selector} config stores have different bindings.`);
|
|
633
|
+
}
|
|
634
|
+
const currentSource = await withResolvedMultiSourceCatalog({
|
|
301
635
|
cliVersion: resolveCliVersion(),
|
|
302
|
-
freshnessPolicy: 'cacheFirst',
|
|
303
636
|
sourceIds: [parsed.sourceId],
|
|
304
637
|
env: options.context.env,
|
|
305
638
|
consume: async (catalog) => {
|
|
306
639
|
const source = catalog.sources.find((entry) => entry.sourceId === parsed.sourceId);
|
|
307
|
-
if (!source?.resolution)
|
|
640
|
+
if (!source?.resolution) {
|
|
308
641
|
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
642
|
}
|
|
643
|
+
return {
|
|
644
|
+
sourceIdentity: source.resolution.sourceIdentity,
|
|
645
|
+
logicalIdentity: source.resolution.logicalIdentity,
|
|
646
|
+
};
|
|
312
647
|
},
|
|
313
648
|
});
|
|
649
|
+
if (sourceBindings[0] && sourceBindings[0] !== currentSource.sourceIdentity) {
|
|
650
|
+
throw new Error(`identityMismatch: ${options.selector} user config does not match the current source identity.`);
|
|
651
|
+
}
|
|
652
|
+
if (catalogBindings[0] && catalogBindings[0] !== currentSource.logicalIdentity) {
|
|
653
|
+
throw new Error(`identityMismatch: ${options.selector} project config does not match the current Catalog logical identity.`);
|
|
654
|
+
}
|
|
314
655
|
return {
|
|
315
656
|
pluginName: parsed.pluginName,
|
|
316
657
|
pluginId: options.selector,
|
|
317
658
|
sourceId: parsed.sourceId,
|
|
318
|
-
sourceIdentity,
|
|
659
|
+
sourceIdentity: currentSource.sourceIdentity,
|
|
660
|
+
logicalIdentity: currentSource.logicalIdentity,
|
|
319
661
|
};
|
|
320
662
|
}
|
|
321
663
|
async function resolveMultiSourceConfigRead(options) {
|
|
@@ -324,26 +666,21 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
324
666
|
env: options.context.env,
|
|
325
667
|
});
|
|
326
668
|
assertCatalogSourceReferencesSupported(inventory);
|
|
327
|
-
const projectLayer = resolveConfigProjectLayer(options.rawOptions);
|
|
328
669
|
return withResolvedCatalogPlugin({
|
|
329
670
|
selector: options.selector,
|
|
330
671
|
cliVersion: resolveCliVersion(),
|
|
331
|
-
freshnessPolicy: 'cacheFirst',
|
|
332
672
|
env: options.context.env,
|
|
333
673
|
consume: async ({ pluginId, source, plugin }) => {
|
|
334
674
|
const result = await resolveConfigRead({
|
|
335
675
|
pluginName: plugin.manifest.name,
|
|
336
676
|
plugin,
|
|
337
|
-
scope: options.rawOptions.
|
|
338
|
-
? 'project'
|
|
339
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
340
|
-
projectLayer,
|
|
677
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
341
678
|
cwd: options.context.cwd,
|
|
342
679
|
env: options.context.env,
|
|
343
680
|
});
|
|
344
681
|
if (options.key !== undefined) {
|
|
345
682
|
const field = findConfigFieldEntry(result.fields, options.key);
|
|
346
|
-
if (!field && plugin.manifest.config?.
|
|
683
|
+
if (!field && plugin.manifest.config?.fields?.[options.key] === undefined) {
|
|
347
684
|
throw new Error(`Unknown config key "${options.key}".`);
|
|
348
685
|
}
|
|
349
686
|
if (field)
|
|
@@ -369,12 +706,10 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
369
706
|
const result = await resolveConfigRead({
|
|
370
707
|
sourceId: stored.sourceId,
|
|
371
708
|
sourceIdentity: stored.sourceIdentity,
|
|
709
|
+
logicalIdentity: stored.logicalIdentity,
|
|
372
710
|
pluginName: stored.pluginName,
|
|
373
711
|
plugin: null,
|
|
374
|
-
scope: options.rawOptions.
|
|
375
|
-
? 'project'
|
|
376
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
377
|
-
projectLayer,
|
|
712
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
378
713
|
cwd: options.context.cwd,
|
|
379
714
|
env: options.context.env,
|
|
380
715
|
});
|
|
@@ -387,36 +722,53 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
387
722
|
return { ...stored, result };
|
|
388
723
|
});
|
|
389
724
|
}
|
|
390
|
-
|
|
725
|
+
export function createManagedCodexAuthorizer(rawOptions, context) {
|
|
726
|
+
if (rawOptions.allowManagedCodexInstall === true)
|
|
727
|
+
return async () => true;
|
|
728
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
729
|
+
|| !context.prompt.confirm)
|
|
730
|
+
return undefined;
|
|
731
|
+
return async () => {
|
|
732
|
+
const response = await context.prompt.confirm({
|
|
733
|
+
message: '系统中没有可用的 Codex CLI。是否获取本次操作所需的 AW-managed Codex runtime?',
|
|
734
|
+
defaultValue: false,
|
|
735
|
+
});
|
|
736
|
+
return !response.cancelled && response.value === true;
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
async function executeWriteCommand(command, pluginNames, rawOptions, context, directCli = false, expectedPlanFingerprint) {
|
|
391
740
|
const raw = { cwd: context.cwd, ...rawOptions };
|
|
392
|
-
const commandOptions = command === 'install'
|
|
741
|
+
const commandOptions = normalizeWriteRequest(() => command === 'install'
|
|
393
742
|
? normalizeInstallCommandOptions(raw)
|
|
394
|
-
: command === '
|
|
395
|
-
?
|
|
396
|
-
: command === '
|
|
397
|
-
?
|
|
398
|
-
:
|
|
399
|
-
? normalizeCleanupCommandOptions(raw)
|
|
400
|
-
: normalizeReinstallCommandOptions(raw);
|
|
743
|
+
: command === 'uninstall'
|
|
744
|
+
? normalizeUninstallCommandOptions(raw)
|
|
745
|
+
: command === 'cleanup'
|
|
746
|
+
? normalizeCleanupCommandOptions(raw)
|
|
747
|
+
: normalizeReinstallCommandOptions(raw));
|
|
401
748
|
await emitCommandEvent(context, {
|
|
402
749
|
type: 'options:normalized',
|
|
403
750
|
data: { plugins: pluginNames, options: commandOptions },
|
|
404
751
|
});
|
|
752
|
+
const managedCodexAuthorizer = createManagedCodexAuthorizer(rawOptions, context);
|
|
753
|
+
const runtime = {
|
|
754
|
+
...context,
|
|
755
|
+
directCli,
|
|
756
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
757
|
+
...(expectedPlanFingerprint ? { expectedPlanFingerprint } : {}),
|
|
758
|
+
...(managedCodexAuthorizer ? { managedCodexAuthorizer } : {}),
|
|
759
|
+
};
|
|
405
760
|
switch (command) {
|
|
406
|
-
case 'install': return installCommand(pluginNames, commandOptions,
|
|
407
|
-
case '
|
|
408
|
-
case '
|
|
409
|
-
case '
|
|
410
|
-
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, context);
|
|
761
|
+
case 'install': return installCommand(pluginNames, commandOptions, runtime);
|
|
762
|
+
case 'uninstall': return uninstallCommand(pluginNames, commandOptions, runtime);
|
|
763
|
+
case 'cleanup': return cleanupCommand(pluginNames, commandOptions, runtime);
|
|
764
|
+
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, runtime);
|
|
411
765
|
}
|
|
412
766
|
}
|
|
413
767
|
async function runWriteCommandAction(command, pluginNames, rawOptions, context) {
|
|
414
768
|
if ((command === 'cleanup' || command === 'reinstall') && pluginNames.length > 1) {
|
|
415
|
-
throw new
|
|
769
|
+
throw new WriteCommandRequestError(`${command} 命令当前只支持单个插件目标。`);
|
|
416
770
|
}
|
|
417
|
-
|
|
418
|
-
assertUpgradeAllConflict(pluginNames, rawOptions.all === true);
|
|
419
|
-
const missingPlugin = pluginNames.length === 0 && !(command === 'upgrade' && rawOptions.all === true);
|
|
771
|
+
const missingPlugin = pluginNames.length === 0;
|
|
420
772
|
const missingPlatform = rawOptions.platform === undefined;
|
|
421
773
|
const missingScope = command === 'cleanup' && rawOptions.scope === undefined;
|
|
422
774
|
const missing = missingPlugin || missingPlatform || missingScope;
|
|
@@ -429,19 +781,42 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
|
|
|
429
781
|
};
|
|
430
782
|
void validationOptions;
|
|
431
783
|
if (!missing) {
|
|
784
|
+
if (command === 'cleanup' && rawOptions.force !== true && rawOptions.yes !== true
|
|
785
|
+
&& isWizardAvailable(context, rawOptions) && context.prompt.confirm) {
|
|
786
|
+
const preview = await cleanupCommand(pluginNames, normalizeCleanupCommandOptions({
|
|
787
|
+
cwd: context.cwd,
|
|
788
|
+
...rawOptions,
|
|
789
|
+
}), { ...context, previewOperationPlan: true });
|
|
790
|
+
if ((preview.removedPluginCleanupIds?.length ?? 0) > 0) {
|
|
791
|
+
if (!preview.operationPlan) {
|
|
792
|
+
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
793
|
+
}
|
|
794
|
+
const response = await context.prompt.confirm({
|
|
795
|
+
message: `清理已删除插件 ${preview.removedPluginCleanupIds.join('、')}:将处理 Codex、Claude Code 的用户与当前项目位置,删除保存设置、安装意图、专属输出和共享原生安装。其他项目可能因此无法继续使用该插件;其本地记录不会修改。即使指定了 --platform 或 --scope,本次仍覆盖上述全部位置。继续?`,
|
|
796
|
+
defaultValue: false,
|
|
797
|
+
});
|
|
798
|
+
if (response.cancelled || response.value !== true)
|
|
799
|
+
return { cancelled: true };
|
|
800
|
+
return {
|
|
801
|
+
cancelled: false,
|
|
802
|
+
result: await executeWriteCommand(command, pluginNames, {
|
|
803
|
+
...rawOptions, yes: true,
|
|
804
|
+
}, context, true, preview.operationPlan.planFingerprint),
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
}
|
|
432
808
|
return {
|
|
433
809
|
cancelled: false,
|
|
434
|
-
result: await executeWriteCommand(command, pluginNames, rawOptions, context),
|
|
810
|
+
result: await executeWriteCommand(command, pluginNames, rawOptions, context, true),
|
|
435
811
|
};
|
|
436
812
|
}
|
|
437
813
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
438
|
-
throw new
|
|
814
|
+
throw new WriteCommandRequestError(writeCommandUsage(command));
|
|
439
815
|
}
|
|
440
816
|
const loaded = await loadConsoleItemsResult({
|
|
441
817
|
cwd: context.cwd,
|
|
442
818
|
scope: rawOptions.scope,
|
|
443
819
|
platform: rawOptions.platform,
|
|
444
|
-
includeCatalogOnly: true,
|
|
445
820
|
}, context);
|
|
446
821
|
if (loaded.catalogUnavailable) {
|
|
447
822
|
throw new Error('插件目录不可用。请运行 `aw init` 或 `aw init --force`,或使用完整参数重试。');
|
|
@@ -472,11 +847,37 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
|
|
|
472
847
|
equivalentCommandTokens: (selection) => buildEquivalentWriteCommandTokens(command, selection, rawOptions),
|
|
473
848
|
isPluginSelectable: (candidate, selection) => writeCandidateEligibility(command, candidate, selection),
|
|
474
849
|
resultState: overallResultState,
|
|
475
|
-
|
|
850
|
+
...(command === 'cleanup' ? {
|
|
851
|
+
reviewDetails: async (selection) => {
|
|
852
|
+
const preview = await cleanupCommand(selection.plugins, normalizeCleanupCommandOptions({
|
|
853
|
+
cwd: context.cwd,
|
|
854
|
+
...rawOptions,
|
|
855
|
+
platform: selection.platform,
|
|
856
|
+
scope: selection.scope,
|
|
857
|
+
}), { ...context, previewOperationPlan: true });
|
|
858
|
+
if ((preview.removedPluginCleanupIds?.length ?? 0) === 0)
|
|
859
|
+
return { lines: [] };
|
|
860
|
+
if (!preview.operationPlan) {
|
|
861
|
+
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
862
|
+
}
|
|
863
|
+
return {
|
|
864
|
+
lines: [
|
|
865
|
+
`已删除插件:${preview.removedPluginCleanupIds.join('、')}`,
|
|
866
|
+
'实际清理范围:Codex、Claude Code;用户与当前项目。',
|
|
867
|
+
'将删除保存设置、安装意图、专属输出和共享原生安装。',
|
|
868
|
+
'其他项目可能失去此插件;其本地记录不会修改。',
|
|
869
|
+
'当前 --platform / --scope 选择不会限制整体清理范围。',
|
|
870
|
+
],
|
|
871
|
+
expectedPlanFingerprint: preview.operationPlan.planFingerprint,
|
|
872
|
+
};
|
|
873
|
+
},
|
|
874
|
+
} : {}),
|
|
875
|
+
execute: (selection, expectedPlanFingerprint) => executeWriteCommand(command, selection.plugins, {
|
|
476
876
|
...rawOptions,
|
|
477
877
|
platform: selection.platform,
|
|
478
878
|
scope: selection.scope,
|
|
479
|
-
|
|
879
|
+
...(command === 'cleanup' ? { yes: true } : {}),
|
|
880
|
+
}, context, false, expectedPlanFingerprint),
|
|
480
881
|
});
|
|
481
882
|
if (result.cancelled)
|
|
482
883
|
return { cancelled: true };
|
|
@@ -587,34 +988,77 @@ async function runActionWithContext(context, action) {
|
|
|
587
988
|
function writeJsonReceipt(write, payload) {
|
|
588
989
|
writeLine(write, JSON.stringify(payload, null, 2));
|
|
589
990
|
}
|
|
590
|
-
function configLayerLabel(scope
|
|
991
|
+
function configLayerLabel(scope) {
|
|
591
992
|
if (scope === 'user') {
|
|
592
993
|
return '个人';
|
|
593
994
|
}
|
|
594
|
-
return
|
|
995
|
+
return '当前项目';
|
|
595
996
|
}
|
|
596
997
|
function writeConfigApplyNotice(write, receipt) {
|
|
597
|
-
|
|
598
|
-
|
|
998
|
+
const sanitizeMessage = (message) => redactString(message)
|
|
999
|
+
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
1000
|
+
.replace(/(?:file:\/\/)?(?:\/[\w.@+-]+){2,}/gu, '[REDACTED PATH]')
|
|
1001
|
+
.replace(/[A-Za-z]:\\(?:[^\s\\]+\\)+[^\s\\]*/gu, '[REDACTED PATH]');
|
|
1002
|
+
const writeTargetFailures = () => {
|
|
1003
|
+
for (const entry of receipt.apply.targetResults.filter((target) => target.state === 'failed' || target.state === 'skipped')) {
|
|
1004
|
+
const reason = entry.message
|
|
1005
|
+
? `${entry.errorCode ? `[${entry.errorCode}] ` : ''}${sanitizeMessage(entry.message)}`
|
|
1006
|
+
: entry.errorCode
|
|
1007
|
+
? `失败原因:${entry.errorCode}。`
|
|
1008
|
+
: '未提供安全失败原因。';
|
|
1009
|
+
const command = `aw reinstall ${receipt.plugin} -p ${entry.target.platform} -s ${entry.target.scope}`;
|
|
1010
|
+
const recovery = entry.errorCode === 'invalidConfig'
|
|
1011
|
+
? ' 请修复无效配置后运行 aw sync。'
|
|
1012
|
+
: entry.errorCode === 'preApplyAuthorizationRequired'
|
|
1013
|
+
|| entry.errorCode === 'sharedNativeConfigApplyConfirmationRequired'
|
|
1014
|
+
|| entry.errorCode === 'sharedNativeImpactAuthorizationRequired'
|
|
1015
|
+
? ` 请运行 ${command} --yes 重试。`
|
|
1016
|
+
: entry.state === 'failed'
|
|
1017
|
+
? ` 请在解决失败原因后运行 ${command}。`
|
|
1018
|
+
: '';
|
|
1019
|
+
writeLine(write, `${entry.target.platform}/${entry.target.scope}:${reason}${recovery}`);
|
|
1020
|
+
}
|
|
1021
|
+
};
|
|
1022
|
+
const targetResults = receipt.apply.targetResults;
|
|
1023
|
+
if (receipt.apply.state === 'skipped') {
|
|
1024
|
+
const message = receipt.apply.reason === 'noConfigChange'
|
|
599
1025
|
? '配置内容没有变化,因此没有运行 reinstall。'
|
|
600
|
-
:
|
|
1026
|
+
: receipt.apply.reason === 'noEffectiveConfigChange'
|
|
1027
|
+
? '配置存储已更新,但有效配置没有变化,因此没有运行 reinstall。'
|
|
1028
|
+
: receipt.apply.reason === 'notRequested'
|
|
1029
|
+
? '配置已保存,但未请求应用配置。'
|
|
1030
|
+
: '配置已保存。当前没有可见的 AW 安装目标,因此没有应用配置。';
|
|
601
1031
|
writeLine(write, message);
|
|
602
1032
|
}
|
|
603
|
-
else {
|
|
604
|
-
const
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
}
|
|
1033
|
+
else if (receipt.apply.state === 'unavailable') {
|
|
1034
|
+
const fallbackMessages = {
|
|
1035
|
+
invalidConfig: '可见目标的有效配置无效。',
|
|
1036
|
+
schemaUnavailable: '配置 schema 不可用。',
|
|
1037
|
+
sourceUnavailable: '插件来源不可用。',
|
|
1038
|
+
effectiveConfigUnavailable: '无法读取有效配置。',
|
|
1039
|
+
targetDiscoveryFailed: '无法发现可应用配置的目标。',
|
|
1040
|
+
};
|
|
1041
|
+
const detail = receipt.apply.error
|
|
1042
|
+
? `${receipt.apply.error.code}:${sanitizeMessage(receipt.apply.error.message)}`
|
|
1043
|
+
: `${receipt.apply.reason}:${fallbackMessages[receipt.apply.reason]}`;
|
|
1044
|
+
const recovery = receipt.apply.reason === 'invalidConfig'
|
|
1045
|
+
? '请修复无效配置后运行 aw sync。'
|
|
1046
|
+
: receipt.apply.reason === 'effectiveConfigUnavailable'
|
|
1047
|
+
? '请修复配置后运行 aw sync。'
|
|
1048
|
+
: receipt.apply.reason === 'schemaUnavailable' || receipt.apply.reason === 'sourceUnavailable'
|
|
1049
|
+
? '请修复插件来源或配置后运行 aw sync。'
|
|
1050
|
+
: '请修复来源或配置后运行 aw sync。';
|
|
1051
|
+
writeLine(write, `配置已保存,但当前无法应用配置。${detail} ${recovery}`);
|
|
1052
|
+
writeTargetFailures();
|
|
611
1053
|
}
|
|
612
|
-
|
|
613
|
-
|
|
1054
|
+
else {
|
|
1055
|
+
const completed = targetResults.filter((entry) => entry.state === 'completed').length;
|
|
1056
|
+
const failed = targetResults.filter((entry) => entry.state === 'failed').length;
|
|
1057
|
+
const skipped = targetResults.filter((entry) => entry.state === 'skipped').length;
|
|
1058
|
+
writeLine(write, `配置已保存。已重装 ${completed} 个当前可见目标;失败 ${failed} 个;跳过 ${skipped} 个。`);
|
|
1059
|
+
writeTargetFailures();
|
|
614
1060
|
}
|
|
615
|
-
|
|
616
|
-
function writeProjectLocalConfigNotice(write) {
|
|
617
|
-
writeLine(write, '当前显示的是当前项目的本机私有覆盖层,不作为 repo-visible artifact 渲染输入。');
|
|
1061
|
+
writeWarnings(write, receipt.warnings);
|
|
618
1062
|
}
|
|
619
1063
|
function renderConfigFieldState(field) {
|
|
620
1064
|
if (field.valueState === 'invalid') {
|
|
@@ -634,13 +1078,15 @@ function writeConfigReadHuman(write, resolved, pluginName) {
|
|
|
634
1078
|
}
|
|
635
1079
|
if (field.kind === 'manifest' && field.valueState === 'invalid') {
|
|
636
1080
|
const sourceScope = field.sourceLayer === 'project'
|
|
637
|
-
? '
|
|
638
|
-
:
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
1081
|
+
? 'project'
|
|
1082
|
+
: 'user';
|
|
1083
|
+
const definition = resolved.fieldDefinitions?.[field.key];
|
|
1084
|
+
if (definition) {
|
|
1085
|
+
writeLine(write, ` ${formatPluginConfigSetRecoveryCommand(pluginName, field.key, definition, sourceScope)}`);
|
|
1086
|
+
}
|
|
1087
|
+
const scopeOption = ` -s ${sourceScope}`;
|
|
1088
|
+
writeLine(write, ` aw config unset ${pluginName} ${field.key}${scopeOption}`);
|
|
1089
|
+
writeLine(write, ` aw config reset ${pluginName}${scopeOption}`);
|
|
644
1090
|
}
|
|
645
1091
|
}
|
|
646
1092
|
}
|
|
@@ -674,9 +1120,178 @@ export function buildProgram(options = {}) {
|
|
|
674
1120
|
const plugin = program
|
|
675
1121
|
.command('plugin')
|
|
676
1122
|
.description('Create and validate AW plugin source');
|
|
1123
|
+
const self = program
|
|
1124
|
+
.command('self')
|
|
1125
|
+
.description('Describe and check this AW executable');
|
|
1126
|
+
self
|
|
1127
|
+
.command('describe')
|
|
1128
|
+
.description('Describe implemented AW capabilities')
|
|
1129
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1130
|
+
.action(() => {
|
|
1131
|
+
writeJsonReceipt(io.stdout, describeCurrentAw(resolveCliVersion()));
|
|
1132
|
+
});
|
|
1133
|
+
self
|
|
1134
|
+
.command('check')
|
|
1135
|
+
.description('Check nearby plugin requirements against this AW executable')
|
|
1136
|
+
.option('--from <path>', 'start discovery from this file or directory')
|
|
1137
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1138
|
+
.action(async (rawOptions) => {
|
|
1139
|
+
const result = await checkCurrentAw({
|
|
1140
|
+
awVersion: resolveCliVersion(),
|
|
1141
|
+
from: path.resolve(cwd, rawOptions.from ?? '.'),
|
|
1142
|
+
});
|
|
1143
|
+
writeJsonReceipt(io.stdout, result);
|
|
1144
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1145
|
+
});
|
|
1146
|
+
plugin
|
|
1147
|
+
.command('capabilities')
|
|
1148
|
+
.description('Show the current plugin manifest authoring surface')
|
|
1149
|
+
.option('--surface <surface>', 'manifest | build-config | extensions | slash-commands | mcp-apps | config | pre-apply | artifacts')
|
|
1150
|
+
.option('--json', 'emit one machine-readable JSON object', false)
|
|
1151
|
+
.action((rawOptions) => {
|
|
1152
|
+
try {
|
|
1153
|
+
const surface = rawOptions.surface === undefined
|
|
1154
|
+
? undefined
|
|
1155
|
+
: parsePluginCapabilitySurface(rawOptions.surface);
|
|
1156
|
+
const result = getPluginCapabilitiesResult({
|
|
1157
|
+
awVersion: resolveCliVersion(),
|
|
1158
|
+
...(surface ? { surface } : {}),
|
|
1159
|
+
});
|
|
1160
|
+
if (rawOptions.json)
|
|
1161
|
+
writeJsonReceipt(io.stdout, result);
|
|
1162
|
+
else
|
|
1163
|
+
for (const line of renderPluginCapabilities(result))
|
|
1164
|
+
writeLine(io.stdout, line);
|
|
1165
|
+
}
|
|
1166
|
+
catch (error) {
|
|
1167
|
+
writeLine(io.stderr, error instanceof Error ? error.message : String(error));
|
|
1168
|
+
commandExitState.exitCode = 1;
|
|
1169
|
+
}
|
|
1170
|
+
});
|
|
1171
|
+
plugin
|
|
1172
|
+
.command('requirements')
|
|
1173
|
+
.description('Inspect or update effective AW capabilities required by a plugin')
|
|
1174
|
+
.argument('<plugin-directory>', 'plugin source directory')
|
|
1175
|
+
.option('--workspace-root <root>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1176
|
+
.option('--add <capability>', 'add one declared AW capability')
|
|
1177
|
+
.option('--remove <capability>', 'remove one declared AW capability')
|
|
1178
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1179
|
+
.action(async (pluginDirectory, rawOptions) => {
|
|
1180
|
+
try {
|
|
1181
|
+
const result = await inspectPluginRequirements({
|
|
1182
|
+
pluginDirectory,
|
|
1183
|
+
...(rawOptions.workspaceRoot ? { workspaceRoot: rawOptions.workspaceRoot } : {}),
|
|
1184
|
+
...(rawOptions.add ? { add: rawOptions.add } : {}),
|
|
1185
|
+
...(rawOptions.remove ? { remove: rawOptions.remove } : {}),
|
|
1186
|
+
cwd,
|
|
1187
|
+
});
|
|
1188
|
+
writeJsonReceipt(io.stdout, result);
|
|
1189
|
+
if (result.observations.some((observation) => observation.blocking)) {
|
|
1190
|
+
commandExitState.exitCode = 1;
|
|
1191
|
+
}
|
|
1192
|
+
}
|
|
1193
|
+
catch (error) {
|
|
1194
|
+
writeJsonReceipt(io.stdout, {
|
|
1195
|
+
schemaVersion: 1,
|
|
1196
|
+
command: 'plugin:requirements',
|
|
1197
|
+
ok: false,
|
|
1198
|
+
error: error instanceof Error ? error.message : String(error),
|
|
1199
|
+
});
|
|
1200
|
+
commandExitState.exitCode = 1;
|
|
1201
|
+
}
|
|
1202
|
+
});
|
|
677
1203
|
const skill = program
|
|
678
1204
|
.command('skill')
|
|
679
1205
|
.description('Install, materialize, or validate Agent Skills');
|
|
1206
|
+
const skillEval = skill
|
|
1207
|
+
.command('eval')
|
|
1208
|
+
.description('Prepare or diagnose deterministic Agent Skill Eval inputs');
|
|
1209
|
+
skillEval
|
|
1210
|
+
.command('doctor')
|
|
1211
|
+
.description('Inspect Agent Skill Eval provider readiness without model execution')
|
|
1212
|
+
.requiredOption('--json', 'emit one provider doctor JSON object')
|
|
1213
|
+
.action(async () => {
|
|
1214
|
+
try {
|
|
1215
|
+
writeJsonReceipt(io.stdout, await doctorEvalProviders({ sourceEnv: env }));
|
|
1216
|
+
}
|
|
1217
|
+
catch (error) {
|
|
1218
|
+
writeJsonReceipt(io.stdout, {
|
|
1219
|
+
ok: false,
|
|
1220
|
+
error: redactString(error instanceof Error ? error.message : String(error)),
|
|
1221
|
+
});
|
|
1222
|
+
commandExitState.exitCode = 1;
|
|
1223
|
+
}
|
|
1224
|
+
});
|
|
1225
|
+
skillEval
|
|
1226
|
+
.command('prepare')
|
|
1227
|
+
.description('Prepare one complete Agent Skill Eval input directory')
|
|
1228
|
+
.argument('<plugin>', 'canonical Workspace plugin name')
|
|
1229
|
+
.argument('<skill>', 'owner Skill name')
|
|
1230
|
+
.option('--suite <suite>', 'Eval suite ID')
|
|
1231
|
+
.option('--profile <profile>', 'Eval profile ID')
|
|
1232
|
+
.option('--config-file <path>', 'non-sensitive plugin config overrides for the Eval profile')
|
|
1233
|
+
.option('--workspace-root <root>', 'Catalog Workspace root')
|
|
1234
|
+
.option('--split <split>', 'case split filter')
|
|
1235
|
+
.option('--case <id>', 'case ID filter')
|
|
1236
|
+
.option('--runs <count>', 'runs per selected case')
|
|
1237
|
+
.option('--timeout-ms <milliseconds>', 'timeout for each provider attempt')
|
|
1238
|
+
.option('--baseline <mode>', 'append without-skill comparison')
|
|
1239
|
+
.option('--previous-version <runtime-skill-root>', 'append a previous-version comparison')
|
|
1240
|
+
.option('--keep-workspace', 'retain the preparation materialization workspace', false)
|
|
1241
|
+
.requiredOption('--output <spec-directory>', 'new EvalSpec directory')
|
|
1242
|
+
.requiredOption('--json', 'emit one preparation receipt JSON object')
|
|
1243
|
+
.action(async (pluginName, skillName, rawOptions) => {
|
|
1244
|
+
try {
|
|
1245
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1246
|
+
cwd,
|
|
1247
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1248
|
+
mode: 'existing',
|
|
1249
|
+
env,
|
|
1250
|
+
});
|
|
1251
|
+
const runs = rawOptions.runs === undefined
|
|
1252
|
+
? undefined
|
|
1253
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.runs) ? Number(rawOptions.runs) : Number.NaN);
|
|
1254
|
+
const timeoutMs = rawOptions.timeoutMs === undefined
|
|
1255
|
+
? undefined
|
|
1256
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.timeoutMs) ? Number(rawOptions.timeoutMs) : Number.NaN);
|
|
1257
|
+
const receipt = await prepareSkillEval({
|
|
1258
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
1259
|
+
workspaceRootResolvedFrom: workspace.workspaceRootResolvedFrom,
|
|
1260
|
+
pluginName,
|
|
1261
|
+
skillName,
|
|
1262
|
+
...(rawOptions.suite === undefined ? {} : { suiteId: rawOptions.suite }),
|
|
1263
|
+
...(rawOptions.profile === undefined ? {} : { profileId: rawOptions.profile }),
|
|
1264
|
+
...(rawOptions.configFile === undefined ? {} : { configFile: path.resolve(cwd, rawOptions.configFile) }),
|
|
1265
|
+
output: rawOptions.output,
|
|
1266
|
+
cwd,
|
|
1267
|
+
env,
|
|
1268
|
+
...(rawOptions.split === undefined ? {} : { split: rawOptions.split }),
|
|
1269
|
+
...(rawOptions.case === undefined ? {} : { caseId: rawOptions.case }),
|
|
1270
|
+
...(runs === undefined ? {} : { runs }),
|
|
1271
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
1272
|
+
...(rawOptions.baseline === undefined ? {} : {
|
|
1273
|
+
baseline: rawOptions.baseline,
|
|
1274
|
+
}),
|
|
1275
|
+
...(rawOptions.previousVersion === undefined ? {} : {
|
|
1276
|
+
previousVersion: rawOptions.previousVersion,
|
|
1277
|
+
}),
|
|
1278
|
+
...(rawOptions.keepWorkspace === true ? { keepWorkspace: true } : {}),
|
|
1279
|
+
});
|
|
1280
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1281
|
+
}
|
|
1282
|
+
catch (error) {
|
|
1283
|
+
writeJsonReceipt(io.stdout, {
|
|
1284
|
+
schemaVersion: 1,
|
|
1285
|
+
command: 'skill:eval:prepare',
|
|
1286
|
+
ok: false,
|
|
1287
|
+
errors: [{
|
|
1288
|
+
code: 'evalPreparationFailed',
|
|
1289
|
+
message: redactString(error instanceof Error ? error.message : String(error)),
|
|
1290
|
+
}],
|
|
1291
|
+
});
|
|
1292
|
+
commandExitState.exitCode = 1;
|
|
1293
|
+
}
|
|
1294
|
+
});
|
|
680
1295
|
const review = program
|
|
681
1296
|
.command('review')
|
|
682
1297
|
.description('Publish and inspect immutable review records');
|
|
@@ -685,6 +1300,81 @@ export function buildProgram(options = {}) {
|
|
|
685
1300
|
recordDir: reviewRecordDir(repoRoot, record),
|
|
686
1301
|
manifest: record.manifest,
|
|
687
1302
|
});
|
|
1303
|
+
review
|
|
1304
|
+
.command('inspect')
|
|
1305
|
+
.description('Inspect current AW Review source and materialization facts')
|
|
1306
|
+
.argument('<target>', 'Catalog Workspace, Plugin, or source Skill path')
|
|
1307
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1308
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1309
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']))
|
|
1310
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']))
|
|
1311
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1312
|
+
.option('--materialization <receipt>', 'validate one aw-source-binding receipt', collectUniqueOption, [])
|
|
1313
|
+
.addOption(strictValueOption('--view <view>', 'select review or release view', ['review', 'release']).default('review'))
|
|
1314
|
+
.option('--json', 'emit one Review inspection JSON object', false)
|
|
1315
|
+
.action(async (target, rawOptions) => {
|
|
1316
|
+
try {
|
|
1317
|
+
const receipt = await inspectReviewTarget({
|
|
1318
|
+
cwd,
|
|
1319
|
+
target,
|
|
1320
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1321
|
+
? {}
|
|
1322
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1323
|
+
skills: rawOptions.skill,
|
|
1324
|
+
...(rawOptions.platform === undefined ? {} : { platform: rawOptions.platform }),
|
|
1325
|
+
...(rawOptions.scope === undefined ? {} : { scope: rawOptions.scope }),
|
|
1326
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1327
|
+
materializations: [...new Set(rawOptions.materialization
|
|
1328
|
+
.map((entry) => path.resolve(cwd, entry)))],
|
|
1329
|
+
view: rawOptions.view,
|
|
1330
|
+
env,
|
|
1331
|
+
});
|
|
1332
|
+
if (rawOptions.json)
|
|
1333
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1334
|
+
else
|
|
1335
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1336
|
+
commandExitState.exitCode = 0;
|
|
1337
|
+
}
|
|
1338
|
+
catch (error) {
|
|
1339
|
+
const receipt = createReviewInspectionFailure(error, rawOptions.view);
|
|
1340
|
+
if (rawOptions.json)
|
|
1341
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1342
|
+
else
|
|
1343
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1344
|
+
commandExitState.exitCode = getReviewInspectionExitCode(error);
|
|
1345
|
+
}
|
|
1346
|
+
});
|
|
1347
|
+
review
|
|
1348
|
+
.command('prepare')
|
|
1349
|
+
.description('Prepare deterministic Skill finals for AW Review')
|
|
1350
|
+
.argument('<target>', 'Plugin or source Skill path')
|
|
1351
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1352
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1353
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']).makeOptionMandatory())
|
|
1354
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']).makeOptionMandatory())
|
|
1355
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1356
|
+
.addOption(strictValueOption('--out <new-dir>', 'new output directory').makeOptionMandatory())
|
|
1357
|
+
.option('--json', 'emit one Review preparation JSON object', false)
|
|
1358
|
+
.action(async (target, rawOptions) => {
|
|
1359
|
+
const result = await prepareReviewTarget({
|
|
1360
|
+
cwd,
|
|
1361
|
+
target,
|
|
1362
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1363
|
+
? {}
|
|
1364
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1365
|
+
skills: rawOptions.skill,
|
|
1366
|
+
platform: rawOptions.platform,
|
|
1367
|
+
scope: rawOptions.scope,
|
|
1368
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1369
|
+
out: rawOptions.out,
|
|
1370
|
+
env,
|
|
1371
|
+
});
|
|
1372
|
+
if (rawOptions.json)
|
|
1373
|
+
writeJsonReceipt(io.stdout, result.receipt);
|
|
1374
|
+
else
|
|
1375
|
+
renderReviewPreparation(io.stdout, result.receipt);
|
|
1376
|
+
commandExitState.exitCode = result.exitCode;
|
|
1377
|
+
});
|
|
688
1378
|
review
|
|
689
1379
|
.command('digest')
|
|
690
1380
|
.description('Compute one canonical workflow component digest')
|
|
@@ -837,15 +1527,17 @@ export function buildProgram(options = {}) {
|
|
|
837
1527
|
.option('--skill <name...>', 'install only selected Skill names')
|
|
838
1528
|
.option('--agent <id...>', 'install to explicit Agent IDs')
|
|
839
1529
|
.option('-y, --yes', 'confirm the reviewed install', false)
|
|
840
|
-
.option('-j, --json', 'emit one receipt
|
|
1530
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
841
1531
|
.action(async (selector, rawOptions) => {
|
|
842
1532
|
const context = createActionContext('skill:install', {});
|
|
843
1533
|
const writeFailure = (error) => {
|
|
844
|
-
const
|
|
845
|
-
|
|
846
|
-
|
|
1534
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1535
|
+
const code = capabilityError?.code
|
|
1536
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1537
|
+
? error.code
|
|
1538
|
+
: 'portableInstallFailed');
|
|
847
1539
|
writeJsonReceipt(io.stdout, {
|
|
848
|
-
receiptSchemaVersion:
|
|
1540
|
+
receiptSchemaVersion: 5,
|
|
849
1541
|
command: 'skill:install',
|
|
850
1542
|
ok: false,
|
|
851
1543
|
status: 'failed',
|
|
@@ -861,7 +1553,15 @@ export function buildProgram(options = {}) {
|
|
|
861
1553
|
materializationDigest: null,
|
|
862
1554
|
verification: { records: [], missing: [] },
|
|
863
1555
|
warnings: [],
|
|
864
|
-
failures: [{
|
|
1556
|
+
failures: [{
|
|
1557
|
+
code,
|
|
1558
|
+
message: capabilityError?.message ?? `${code}: portable Skill 安装未执行。`,
|
|
1559
|
+
...(capabilityError ? {
|
|
1560
|
+
plugin: capabilityError.plugin,
|
|
1561
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1562
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1563
|
+
} : {}),
|
|
1564
|
+
}],
|
|
865
1565
|
});
|
|
866
1566
|
};
|
|
867
1567
|
if (rawOptions.json && !rawOptions.yes) {
|
|
@@ -931,7 +1631,7 @@ export function buildProgram(options = {}) {
|
|
|
931
1631
|
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
932
1632
|
.requiredOption('--out <dir>', 'output directory')
|
|
933
1633
|
.option('--skill <name...>', 'write only selected Skill names')
|
|
934
|
-
.option('-j, --json', 'emit one receipt
|
|
1634
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
935
1635
|
.action(async (selector, rawOptions) => {
|
|
936
1636
|
const context = createActionContext('skill:materialize', {});
|
|
937
1637
|
try {
|
|
@@ -952,11 +1652,13 @@ export function buildProgram(options = {}) {
|
|
|
952
1652
|
catch (error) {
|
|
953
1653
|
if (!rawOptions.json)
|
|
954
1654
|
throw error;
|
|
955
|
-
const
|
|
956
|
-
|
|
957
|
-
|
|
1655
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1656
|
+
const code = capabilityError?.code
|
|
1657
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1658
|
+
? error.code
|
|
1659
|
+
: 'portableMaterializeFailed');
|
|
958
1660
|
writeJsonReceipt(io.stdout, {
|
|
959
|
-
receiptSchemaVersion:
|
|
1661
|
+
receiptSchemaVersion: 5,
|
|
960
1662
|
command: 'skill:materialize',
|
|
961
1663
|
ok: false,
|
|
962
1664
|
plugin: { id: selector },
|
|
@@ -968,7 +1670,15 @@ export function buildProgram(options = {}) {
|
|
|
968
1670
|
configDigest: null,
|
|
969
1671
|
materializationDigest: null,
|
|
970
1672
|
outputDigest: null,
|
|
971
|
-
errors: [{
|
|
1673
|
+
errors: [{
|
|
1674
|
+
code,
|
|
1675
|
+
message: capabilityError?.message ?? `${code}: portable Skill 导出未执行。`,
|
|
1676
|
+
...(capabilityError ? {
|
|
1677
|
+
plugin: capabilityError.plugin,
|
|
1678
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1679
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1680
|
+
} : {}),
|
|
1681
|
+
}],
|
|
972
1682
|
});
|
|
973
1683
|
commandExitState.exitCode = 1;
|
|
974
1684
|
}
|
|
@@ -980,7 +1690,7 @@ export function buildProgram(options = {}) {
|
|
|
980
1690
|
'',
|
|
981
1691
|
'During development, keep the current stable target when production content changes.',
|
|
982
1692
|
'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.',
|
|
1693
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
984
1694
|
'',
|
|
985
1695
|
].join('\n'))
|
|
986
1696
|
.argument('<plugin-name>', 'lowercase hyphen-case plugin name')
|
|
@@ -992,14 +1702,12 @@ export function buildProgram(options = {}) {
|
|
|
992
1702
|
.option('--skill-short-description <text>', 'initial Skill UI summary (25-64 characters)')
|
|
993
1703
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
994
1704
|
.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)')
|
|
1705
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
998
1706
|
.option('--no-skills', 'create the plugin without a skills directory')
|
|
999
1707
|
.option('--with-mcp', 'add a minimal .mcp.json', false)
|
|
1000
1708
|
.option('--with-apps', 'add a minimal .app.json', false)
|
|
1001
1709
|
.option('--with-config-api', 'add AW config schema and helper', false)
|
|
1002
|
-
.option('--with-
|
|
1710
|
+
.option('--with-pre-apply', 'add an idempotent Node preApply environment check', false);
|
|
1003
1711
|
plugin
|
|
1004
1712
|
.command('add-skill')
|
|
1005
1713
|
.description('Add one static Skill scaffold to an existing plugin')
|
|
@@ -1007,7 +1715,7 @@ export function buildProgram(options = {}) {
|
|
|
1007
1715
|
'',
|
|
1008
1716
|
'During development, keep the current stable target when production content changes.',
|
|
1009
1717
|
'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.',
|
|
1718
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
1011
1719
|
'',
|
|
1012
1720
|
].join('\n'))
|
|
1013
1721
|
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
@@ -1015,28 +1723,39 @@ export function buildProgram(options = {}) {
|
|
|
1015
1723
|
.option('--skill-description <text>', 'Skill goal and discovery description (required)')
|
|
1016
1724
|
.option('--skill-short-description <text>', 'Skill UI summary (25-64 characters)')
|
|
1017
1725
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
1018
|
-
.option('--workspace-root <path>', '
|
|
1726
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1727
|
+
plugin
|
|
1728
|
+
.command('remove')
|
|
1729
|
+
.description('Remove one committed and unchanged canonical plugin source tree')
|
|
1730
|
+
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
1731
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1732
|
+
.option('--yes', 'confirm plugin source deletion', false)
|
|
1733
|
+
.option('--json', 'emit one schema 1 JSON object', false);
|
|
1019
1734
|
plugin
|
|
1020
1735
|
.command('validate')
|
|
1021
1736
|
.description('Validate one source plugin directory')
|
|
1022
1737
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1023
|
-
.option('--catalog-min-version <semver>', 'validate compatibility against a target catalog')
|
|
1024
1738
|
.option('--strict-agent-skills', 'allow only Agent Skills portable core frontmatter', false)
|
|
1025
1739
|
.option('--claude-skill-profile <profile>', 'minimum | current (default: minimum)')
|
|
1026
1740
|
.option('--version-base <git-ref>', 'production bundle comparison base (default: HEAD)')
|
|
1027
|
-
.option('--workspace-root <path>', '
|
|
1741
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1028
1742
|
.option('--json', 'emit one machine-readable JSON result', false);
|
|
1029
1743
|
plugin
|
|
1030
1744
|
.command('test')
|
|
1031
1745
|
.description('Run deterministic Node tests declared by one source plugin')
|
|
1032
1746
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1033
|
-
.option('--workspace-root <path>', '
|
|
1747
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1034
1748
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1035
1749
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1036
1750
|
try {
|
|
1751
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1752
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1753
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1754
|
+
mode: 'existing',
|
|
1755
|
+
});
|
|
1037
1756
|
commandExitState.exitCode = await runPluginTestCommand({
|
|
1038
|
-
|
|
1039
|
-
pluginDirectory,
|
|
1757
|
+
...workspace,
|
|
1758
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1040
1759
|
json: rawOptions.json,
|
|
1041
1760
|
io,
|
|
1042
1761
|
});
|
|
@@ -1053,15 +1772,20 @@ export function buildProgram(options = {}) {
|
|
|
1053
1772
|
.command('build')
|
|
1054
1773
|
.description('Build and inspect one source plugin bundle')
|
|
1055
1774
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1056
|
-
.option('--workspace-root <path>', '
|
|
1057
|
-
.option('--out <path>', 'output path inside the
|
|
1775
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1776
|
+
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1058
1777
|
.option('--force', 'replace an existing generated output', false)
|
|
1059
1778
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1060
1779
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1061
1780
|
try {
|
|
1781
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1782
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1783
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1784
|
+
mode: 'existing',
|
|
1785
|
+
});
|
|
1062
1786
|
await runPluginBuildCommand({
|
|
1063
|
-
|
|
1064
|
-
pluginDirectory,
|
|
1787
|
+
...workspace,
|
|
1788
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1065
1789
|
out: rawOptions.out,
|
|
1066
1790
|
force: rawOptions.force,
|
|
1067
1791
|
json: rawOptions.json,
|
|
@@ -1080,18 +1804,10 @@ export function buildProgram(options = {}) {
|
|
|
1080
1804
|
.command('status')
|
|
1081
1805
|
.description('Show current plugin status or compare against an explicit Git base')
|
|
1082
1806
|
.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)
|
|
1807
|
+
.option('--all', 'check every current Catalog Workspace plugin', false)
|
|
1092
1808
|
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1093
1809
|
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1094
|
-
.option('--workspace-root <path>', '
|
|
1810
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1095
1811
|
skill
|
|
1096
1812
|
.command('validate')
|
|
1097
1813
|
.description('Validate one Agent Skill directory')
|
|
@@ -1104,19 +1820,25 @@ export function buildProgram(options = {}) {
|
|
|
1104
1820
|
.description('Build and manage catalogs');
|
|
1105
1821
|
catalog
|
|
1106
1822
|
.command('init')
|
|
1107
|
-
.description('Initialize a local AW
|
|
1108
|
-
.option('--workspace-root <path>', '
|
|
1823
|
+
.description('Initialize a local AW Catalog Workspace')
|
|
1824
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor, then Git worktree root, then current directory)')
|
|
1109
1825
|
.option('--owner-name <name>', 'catalog owner name')
|
|
1110
1826
|
.option('--owner-url <url>', 'catalog owner URL')
|
|
1111
1827
|
.option('--display-name <name>', 'catalog display name')
|
|
1112
1828
|
.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
|
|
1829
|
+
.option('--force', 'repair a matching managed Catalog Workspace scaffold', false)
|
|
1114
1830
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1115
1831
|
.action(async (rawOptions) => {
|
|
1116
1832
|
try {
|
|
1833
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1834
|
+
cwd,
|
|
1835
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1836
|
+
mode: 'initialize',
|
|
1837
|
+
env,
|
|
1838
|
+
});
|
|
1117
1839
|
await runCatalogInitCommand({
|
|
1118
1840
|
...rawOptions,
|
|
1119
|
-
|
|
1841
|
+
...workspace,
|
|
1120
1842
|
io,
|
|
1121
1843
|
});
|
|
1122
1844
|
}
|
|
@@ -1130,15 +1852,22 @@ export function buildProgram(options = {}) {
|
|
|
1130
1852
|
});
|
|
1131
1853
|
catalog
|
|
1132
1854
|
.command('version')
|
|
1133
|
-
.description('Read or set the
|
|
1855
|
+
.description('Read or set the Catalog version')
|
|
1134
1856
|
.argument('[version]', 'stable or x.y.z-beta.N catalog version')
|
|
1135
|
-
.option('--
|
|
1857
|
+
.option('--bump <level>', 'bump the stable SemVer base: patch, minor, or major')
|
|
1858
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1136
1859
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1137
1860
|
.action(async (version, rawOptions) => {
|
|
1138
1861
|
try {
|
|
1862
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1863
|
+
cwd,
|
|
1864
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1865
|
+
mode: 'existing',
|
|
1866
|
+
});
|
|
1139
1867
|
await runCatalogVersionCommand({
|
|
1140
|
-
|
|
1868
|
+
...workspace,
|
|
1141
1869
|
version,
|
|
1870
|
+
bump: rawOptions.bump,
|
|
1142
1871
|
json: rawOptions.json,
|
|
1143
1872
|
io,
|
|
1144
1873
|
});
|
|
@@ -1154,14 +1883,19 @@ export function buildProgram(options = {}) {
|
|
|
1154
1883
|
catalog
|
|
1155
1884
|
.command('build')
|
|
1156
1885
|
.description('Build a deterministic development Catalog snapshot')
|
|
1157
|
-
.option('--workspace-root <path>', '
|
|
1158
|
-
.option('--out <path>', 'output path inside the
|
|
1886
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1887
|
+
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1159
1888
|
.option('--force', 'replace an existing generated output', false)
|
|
1160
1889
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1161
1890
|
.action(async (rawOptions) => {
|
|
1162
1891
|
try {
|
|
1892
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1893
|
+
cwd,
|
|
1894
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1895
|
+
mode: 'existing',
|
|
1896
|
+
});
|
|
1163
1897
|
await runCatalogBuildCommand({
|
|
1164
|
-
|
|
1898
|
+
...workspace,
|
|
1165
1899
|
out: rawOptions.out,
|
|
1166
1900
|
force: rawOptions.force,
|
|
1167
1901
|
json: rawOptions.json,
|
|
@@ -1178,7 +1912,7 @@ export function buildProgram(options = {}) {
|
|
|
1178
1912
|
});
|
|
1179
1913
|
catalog
|
|
1180
1914
|
.command('validate')
|
|
1181
|
-
.description('Validate a schema
|
|
1915
|
+
.description('Validate a schema 7 Catalog snapshot')
|
|
1182
1916
|
.argument('<snapshot-directory>', 'Catalog snapshot directory')
|
|
1183
1917
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1184
1918
|
.action(async (snapshotDirectory, rawOptions) => {
|
|
@@ -1198,27 +1932,97 @@ export function buildProgram(options = {}) {
|
|
|
1198
1932
|
}
|
|
1199
1933
|
});
|
|
1200
1934
|
catalog
|
|
1935
|
+
.command('status')
|
|
1936
|
+
.description('Inspect static Catalog Workspace, snapshot, and Git facts')
|
|
1937
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1938
|
+
.option('--json', 'emit one machine-readable JSON status object', false)
|
|
1939
|
+
.action(async (rawOptions) => {
|
|
1940
|
+
const receipt = await getCatalogStatus({
|
|
1941
|
+
cwd,
|
|
1942
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1943
|
+
env,
|
|
1944
|
+
});
|
|
1945
|
+
if (rawOptions.json)
|
|
1946
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1947
|
+
else
|
|
1948
|
+
io.stdout(renderCatalogStatus(receipt));
|
|
1949
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1950
|
+
});
|
|
1951
|
+
const catalogPublish = catalog
|
|
1201
1952
|
.command('publish')
|
|
1202
|
-
.description('
|
|
1203
|
-
|
|
1204
|
-
.
|
|
1953
|
+
.description('Plan or apply a versioned Catalog publication');
|
|
1954
|
+
catalogPublish
|
|
1955
|
+
.command('plan')
|
|
1956
|
+
.description('Prepare and inspect the exact Catalog publication plan')
|
|
1957
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1958
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
1205
1959
|
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
1206
|
-
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
1207
1960
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1208
1961
|
.action(async (rawOptions) => {
|
|
1209
1962
|
try {
|
|
1210
|
-
const
|
|
1211
|
-
|
|
1212
|
-
workspaceRoot:
|
|
1963
|
+
const result = await runCatalogPublishPlanCommand({
|
|
1964
|
+
cwd,
|
|
1965
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1213
1966
|
remote: rawOptions.remote,
|
|
1214
1967
|
branch: rawOptions.branch,
|
|
1215
|
-
yes: rawOptions.yes,
|
|
1216
|
-
json: rawOptions.json,
|
|
1217
1968
|
env,
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1969
|
+
io,
|
|
1970
|
+
});
|
|
1971
|
+
if (rawOptions.json)
|
|
1972
|
+
writeJsonReceipt(io.stdout, result);
|
|
1973
|
+
else {
|
|
1974
|
+
writeLine(io.stdout, `Workspace identity: ${result.workspaceIdentity}`);
|
|
1975
|
+
writeLine(io.stdout, `Source HEAD: ${result.sourceHead}`);
|
|
1976
|
+
writeLine(io.stdout, `Remote identity: ${result.descriptor.remote.identityDigest}`);
|
|
1977
|
+
writeLine(io.stdout, `Remote: ${result.remote} (${result.remoteUrl})`);
|
|
1978
|
+
writeLine(io.stdout, `Branch: refs/heads/${result.branch}`);
|
|
1979
|
+
writeLine(io.stdout, `Parent: ${result.parent ?? '<root>'}`);
|
|
1980
|
+
writeLine(io.stdout, `Tag: refs/tags/${result.tag}`);
|
|
1981
|
+
writeLine(io.stdout, `Snapshot digest: ${result.snapshotDigest}`);
|
|
1982
|
+
writeLine(io.stdout, `Expected commit: ${result.expectedCommit}`);
|
|
1983
|
+
writeLine(io.stdout, `Plan digest: ${result.planDigest}`);
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
catch (error) {
|
|
1987
|
+
const failure = catalogPublicationFailure({
|
|
1988
|
+
error,
|
|
1989
|
+
env,
|
|
1990
|
+
sensitiveRoots: [
|
|
1991
|
+
cwd,
|
|
1992
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
1993
|
+
],
|
|
1994
|
+
});
|
|
1995
|
+
if (rawOptions.json)
|
|
1996
|
+
writeJsonReceipt(io.stdout, failure);
|
|
1997
|
+
writeLine(io.stderr, failure.message);
|
|
1998
|
+
commandExitState.exitCode = 1;
|
|
1999
|
+
}
|
|
2000
|
+
});
|
|
2001
|
+
catalogPublish
|
|
2002
|
+
.command('apply')
|
|
2003
|
+
.description('Apply an authorized Catalog publication plan')
|
|
2004
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
2005
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
2006
|
+
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
2007
|
+
.requiredOption('--expected-plan-digest <sha256>', 'exact plan digest returned by catalog publish plan')
|
|
2008
|
+
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
2009
|
+
.option('--json', 'emit one machine-readable JSON result', false)
|
|
2010
|
+
.action(async (rawOptions) => {
|
|
2011
|
+
try {
|
|
2012
|
+
const context = createActionContext('catalog:publish:apply', {});
|
|
2013
|
+
const result = await runCatalogPublishApplyCommand({
|
|
2014
|
+
cwd,
|
|
2015
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2016
|
+
remote: rawOptions.remote,
|
|
2017
|
+
branch: rawOptions.branch,
|
|
2018
|
+
expectedPlanDigest: rawOptions.expectedPlanDigest,
|
|
2019
|
+
yes: rawOptions.yes,
|
|
2020
|
+
json: rawOptions.json,
|
|
2021
|
+
env,
|
|
2022
|
+
interactive: context.interactive,
|
|
2023
|
+
...(context.prompt.confirm ? {
|
|
2024
|
+
confirm: async (message) => {
|
|
2025
|
+
const response = await context.prompt.confirm({ message, defaultValue: false });
|
|
1222
2026
|
return !response.cancelled && response.value === true;
|
|
1223
2027
|
},
|
|
1224
2028
|
} : {}),
|
|
@@ -1237,14 +2041,95 @@ export function buildProgram(options = {}) {
|
|
|
1237
2041
|
}
|
|
1238
2042
|
}
|
|
1239
2043
|
catch (error) {
|
|
1240
|
-
const
|
|
2044
|
+
const failure = catalogPublicationFailure({
|
|
2045
|
+
error,
|
|
2046
|
+
env,
|
|
2047
|
+
sensitiveRoots: [
|
|
2048
|
+
cwd,
|
|
2049
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
2050
|
+
],
|
|
2051
|
+
});
|
|
1241
2052
|
if (rawOptions.json)
|
|
1242
|
-
writeJsonReceipt(io.stdout,
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
2053
|
+
writeJsonReceipt(io.stdout, failure);
|
|
2054
|
+
writeLine(io.stderr, failure.message);
|
|
2055
|
+
commandExitState.exitCode = 1;
|
|
2056
|
+
}
|
|
2057
|
+
});
|
|
2058
|
+
const catalogDev = catalog
|
|
2059
|
+
.command('dev')
|
|
2060
|
+
.description('Manage the current Catalog Workspace development source');
|
|
2061
|
+
catalogDev
|
|
2062
|
+
.command('activate')
|
|
2063
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2064
|
+
.option('--source-id <id>', 'explicit managed source ID')
|
|
2065
|
+
.option('--primary', 'make the development source primary', false)
|
|
2066
|
+
.option('--force-build', 'rebuild a current snapshot', false)
|
|
2067
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
2068
|
+
.requiredOption('--json', 'emit one schema 2 JSON receipt')
|
|
2069
|
+
.action(async (rawOptions) => {
|
|
2070
|
+
try {
|
|
2071
|
+
const receipt = await activateCatalogDevSource({
|
|
2072
|
+
cwd,
|
|
2073
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2074
|
+
sourceId: rawOptions.sourceId,
|
|
2075
|
+
primary: rawOptions.primary,
|
|
2076
|
+
forceBuild: rawOptions.forceBuild,
|
|
2077
|
+
yes: rawOptions.yes,
|
|
2078
|
+
cliVersion: resolveCliVersion(),
|
|
2079
|
+
env,
|
|
2080
|
+
});
|
|
2081
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2082
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2083
|
+
}
|
|
2084
|
+
catch (error) {
|
|
2085
|
+
const failure = catalogDevSourceError(error);
|
|
2086
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
2087
|
+
command: 'activate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
2088
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
2089
|
+
}));
|
|
2090
|
+
commandExitState.exitCode = 1;
|
|
2091
|
+
}
|
|
2092
|
+
});
|
|
2093
|
+
catalogDev
|
|
2094
|
+
.command('status')
|
|
2095
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2096
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
2097
|
+
.action(async (rawOptions) => {
|
|
2098
|
+
const receipt = await getCatalogDevSourceStatus({
|
|
2099
|
+
cwd,
|
|
2100
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2101
|
+
cliVersion: resolveCliVersion(),
|
|
2102
|
+
env,
|
|
2103
|
+
});
|
|
2104
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2105
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2106
|
+
});
|
|
2107
|
+
catalogDev
|
|
2108
|
+
.command('deactivate')
|
|
2109
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
2110
|
+
.option('--source-id <id>', 'recover one managed source by exact ID')
|
|
2111
|
+
.option('--replacement-primary <id>', 'replacement when the target source is primary')
|
|
2112
|
+
.option('-y, --yes', 'confirm source impact or recovery by source ID', false)
|
|
2113
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
2114
|
+
.action(async (rawOptions) => {
|
|
2115
|
+
try {
|
|
2116
|
+
const receipt = await deactivateCatalogDevSource({
|
|
2117
|
+
cwd,
|
|
2118
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
2119
|
+
sourceId: rawOptions.sourceId,
|
|
2120
|
+
replacementPrimary: rawOptions.replacementPrimary,
|
|
2121
|
+
yes: rawOptions.yes,
|
|
2122
|
+
env,
|
|
2123
|
+
});
|
|
2124
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2125
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
2126
|
+
}
|
|
2127
|
+
catch (error) {
|
|
2128
|
+
const failure = catalogDevSourceError(error);
|
|
2129
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
2130
|
+
command: 'deactivate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
2131
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
2132
|
+
}));
|
|
1248
2133
|
commandExitState.exitCode = 1;
|
|
1249
2134
|
}
|
|
1250
2135
|
});
|
|
@@ -1256,52 +2141,70 @@ export function buildProgram(options = {}) {
|
|
|
1256
2141
|
const message = failure instanceof Error ? failure.message : String(error);
|
|
1257
2142
|
if (json) {
|
|
1258
2143
|
writeJsonReceipt(io.stdout, {
|
|
1259
|
-
receiptSchemaVersion:
|
|
2144
|
+
receiptSchemaVersion: 6,
|
|
1260
2145
|
command,
|
|
1261
2146
|
ok: false,
|
|
1262
2147
|
changed: false,
|
|
1263
2148
|
sourceId,
|
|
1264
|
-
|
|
2149
|
+
primaryChange: failure.impact?.primaryChange ?? null,
|
|
2150
|
+
references: failure.impact?.references ?? failure.inventory?.references ?? [],
|
|
1265
2151
|
errors: [{ code: failure.code ?? failure.name ?? 'catalogSourceMutationFailed', message }],
|
|
1266
2152
|
});
|
|
1267
2153
|
}
|
|
1268
2154
|
writeLine(io.stderr, message);
|
|
1269
2155
|
commandExitState.exitCode = 1;
|
|
1270
2156
|
};
|
|
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:')) {
|
|
2157
|
+
const writeCatalogGenerationFailure = (command, sourceId, json, error) => {
|
|
2158
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2159
|
+
const message = redactString(failure.message);
|
|
2160
|
+
if (json) {
|
|
1283
2161
|
writeJsonReceipt(io.stdout, {
|
|
1284
|
-
|
|
2162
|
+
...(command === 'catalog:source:sync'
|
|
2163
|
+
? { catalogGenerationSchemaVersion: 1 }
|
|
2164
|
+
: { catalogGenerationStatusSchemaVersion: 2 }),
|
|
1285
2165
|
command,
|
|
1286
2166
|
ok: false,
|
|
1287
|
-
|
|
1288
|
-
...(
|
|
1289
|
-
errors: [{ code, message }],
|
|
2167
|
+
...(sourceId ? { sourceId } : {}),
|
|
2168
|
+
...(failure.impact ? { impact: failure.impact } : {}),
|
|
2169
|
+
errors: [{ code: catalogGenerationErrorCode(error), message }],
|
|
1290
2170
|
});
|
|
1291
2171
|
}
|
|
1292
2172
|
writeLine(io.stderr, message);
|
|
1293
2173
|
commandExitState.exitCode = 1;
|
|
1294
2174
|
};
|
|
1295
|
-
const
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
2175
|
+
const writeConfigMutationFailure = (command, plugin, json, error) => {
|
|
2176
|
+
const failure = configMutationFailure(error, env, cwd);
|
|
2177
|
+
if (json) {
|
|
2178
|
+
writeConfigMutationFailureReceipt(io.stdout, {
|
|
2179
|
+
command,
|
|
2180
|
+
...(plugin ? { plugin } : {}),
|
|
2181
|
+
}, failure);
|
|
2182
|
+
}
|
|
2183
|
+
const message = json
|
|
2184
|
+
? failure.message
|
|
2185
|
+
: redactString(sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), env, [cwd]));
|
|
2186
|
+
writeLine(io.stderr, message);
|
|
2187
|
+
commandExitState.exitCode = 1;
|
|
2188
|
+
};
|
|
2189
|
+
const withResolvedConfigMutationPlugin = (context, selector, consume) => (async () => {
|
|
2190
|
+
const parsed = parsePluginId(selector);
|
|
2191
|
+
return withAwHomeMutationLock({
|
|
1301
2192
|
env: context.env,
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
2193
|
+
action: async (awHomeMutationToken) => {
|
|
2194
|
+
const catalogOperationContext = await resolveCatalogOperationContext({
|
|
2195
|
+
...(parsed.sourceId ? { sourceIds: [parsed.sourceId] } : {}),
|
|
2196
|
+
env: context.env,
|
|
2197
|
+
});
|
|
2198
|
+
return withResolvedCatalogPlugin({
|
|
2199
|
+
selector,
|
|
2200
|
+
cliVersion: resolveCliVersion(),
|
|
2201
|
+
operationContext: catalogOperationContext,
|
|
2202
|
+
env: context.env,
|
|
2203
|
+
consume: (resolution) => consume(resolution, awHomeMutationToken, catalogOperationContext),
|
|
2204
|
+
});
|
|
2205
|
+
},
|
|
2206
|
+
});
|
|
2207
|
+
})();
|
|
1305
2208
|
catalogSource
|
|
1306
2209
|
.command('list')
|
|
1307
2210
|
.option('-j, --json', 'print catalog sources as JSON', false)
|
|
@@ -1316,6 +2219,70 @@ export function buildProgram(options = {}) {
|
|
|
1316
2219
|
writeLine(io.stdout, `${source.primary ? '*' : '-'} ${source.id} ${source.type} ${source.sourceIdentity}`);
|
|
1317
2220
|
}
|
|
1318
2221
|
});
|
|
2222
|
+
catalogSource
|
|
2223
|
+
.command('sync')
|
|
2224
|
+
.argument('<id>')
|
|
2225
|
+
.option('--check', 'fetch and validate without changing the Catalog store or Active state', false)
|
|
2226
|
+
.option('--replace-damaged', 'replace a damaged Active entry with the current candidate', false)
|
|
2227
|
+
.option('-y, --yes', 'confirm affected, unknown, or damaged Active replacement impact', false)
|
|
2228
|
+
.option('-j, --json', 'print the source sync result as JSON', false)
|
|
2229
|
+
.action(async (id, rawOptions) => {
|
|
2230
|
+
try {
|
|
2231
|
+
if (rawOptions.check && rawOptions.replaceDamaged) {
|
|
2232
|
+
throw new Error('catalog source sync --check cannot use --replace-damaged.');
|
|
2233
|
+
}
|
|
2234
|
+
const result = await syncCatalogSourceCommand({
|
|
2235
|
+
sourceId: id,
|
|
2236
|
+
cliVersion: resolveCliVersion(),
|
|
2237
|
+
cwd,
|
|
2238
|
+
check: rawOptions.check === true,
|
|
2239
|
+
impactConfirmed: rawOptions.yes === true,
|
|
2240
|
+
replaceDamaged: rawOptions.replaceDamaged === true,
|
|
2241
|
+
env,
|
|
2242
|
+
});
|
|
2243
|
+
if (rawOptions.json) {
|
|
2244
|
+
writeJsonReceipt(io.stdout, {
|
|
2245
|
+
...result,
|
|
2246
|
+
command: 'catalog:source:sync',
|
|
2247
|
+
ok: true,
|
|
2248
|
+
});
|
|
2249
|
+
}
|
|
2250
|
+
else {
|
|
2251
|
+
writeLine(io.stdout, rawOptions.check
|
|
2252
|
+
? `Catalog source ${id} is valid.`
|
|
2253
|
+
: `Catalog source ${id}: ${result.outcome}.`);
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
catch (error) {
|
|
2257
|
+
writeCatalogGenerationFailure('catalog:source:sync', id, rawOptions.json === true, error);
|
|
2258
|
+
}
|
|
2259
|
+
});
|
|
2260
|
+
catalogSource
|
|
2261
|
+
.command('status')
|
|
2262
|
+
.argument('[id]')
|
|
2263
|
+
.option('-j, --json', 'print offline Catalog source status schema 2 as JSON', false)
|
|
2264
|
+
.action(async (id, rawOptions) => {
|
|
2265
|
+
try {
|
|
2266
|
+
const result = await catalogSourceStatusCommand({ sourceId: id, env });
|
|
2267
|
+
if (rawOptions.json) {
|
|
2268
|
+
writeJsonReceipt(io.stdout, result);
|
|
2269
|
+
}
|
|
2270
|
+
else {
|
|
2271
|
+
for (const source of result.sources) {
|
|
2272
|
+
const active = source.active
|
|
2273
|
+
? `Active ${source.active.snapshotDigest}`
|
|
2274
|
+
: 'no Active';
|
|
2275
|
+
const readiness = source.compatibility?.state === 'unsupported'
|
|
2276
|
+
? `incompatible (required: ${source.compatibility.requiredCapabilities.join(', ')}; missing: ${source.compatibility.missingCapabilities.join(', ')})`
|
|
2277
|
+
: source.activeReady ? 'ready' : 'not ready';
|
|
2278
|
+
writeLine(io.stdout, `${source.sourceId}: ${active}, ${readiness}`);
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
catch (error) {
|
|
2283
|
+
writeCatalogGenerationFailure('catalog:source:status', id, rawOptions.json === true, error);
|
|
2284
|
+
}
|
|
2285
|
+
});
|
|
1319
2286
|
catalogSource
|
|
1320
2287
|
.command('add')
|
|
1321
2288
|
.argument('<id>')
|
|
@@ -1324,7 +2291,9 @@ export function buildProgram(options = {}) {
|
|
|
1324
2291
|
.addOption(new Option('--ref <ref>', 'use an explicit Git ref'))
|
|
1325
2292
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1326
2293
|
.option('--subdir <path>', 'use a catalog snapshot below the Git repository root')
|
|
2294
|
+
.option('--no-auto-check', 'disable automatic update checks for this source')
|
|
1327
2295
|
.option('--primary', 'make this source primary', false)
|
|
2296
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1328
2297
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1329
2298
|
.action(async (id, rawOptions) => {
|
|
1330
2299
|
try {
|
|
@@ -1335,7 +2304,7 @@ export function buildProgram(options = {}) {
|
|
|
1335
2304
|
throw new Error('Git catalog source add requires exactly one of `--ref` or `--default-ref`.');
|
|
1336
2305
|
}
|
|
1337
2306
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined)) {
|
|
1338
|
-
throw new Error('Path catalog source add only accepts `--path
|
|
2307
|
+
throw new Error('Path catalog source add only accepts `--path`, `--primary`, `--no-auto-check`, and `--yes`.');
|
|
1339
2308
|
}
|
|
1340
2309
|
const source = rawOptions.git !== undefined
|
|
1341
2310
|
? {
|
|
@@ -1345,18 +2314,32 @@ export function buildProgram(options = {}) {
|
|
|
1345
2314
|
url: rawOptions.git,
|
|
1346
2315
|
refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true),
|
|
1347
2316
|
...(rawOptions.subdir ? { subdir: rawOptions.subdir } : {}),
|
|
2317
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1348
2318
|
}
|
|
1349
2319
|
: {
|
|
1350
2320
|
id,
|
|
1351
2321
|
type: 'path',
|
|
1352
2322
|
primary: rawOptions.primary === true,
|
|
1353
2323
|
path: rawOptions.path,
|
|
2324
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1354
2325
|
};
|
|
2326
|
+
const preview = source.primary
|
|
2327
|
+
? await preflightCatalogSourceMutation({
|
|
2328
|
+
request: { action: 'add', source }, cwd, env,
|
|
2329
|
+
})
|
|
2330
|
+
: undefined;
|
|
1355
2331
|
const receipt = await addCatalogSourceCommand({
|
|
1356
2332
|
source,
|
|
1357
2333
|
cliVersion: resolveCliVersion(),
|
|
1358
2334
|
cwd,
|
|
1359
2335
|
env,
|
|
2336
|
+
...(preview ? {
|
|
2337
|
+
expectedConfigDigest: preview.configDigest,
|
|
2338
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2339
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2340
|
+
} : {}),
|
|
2341
|
+
requireImpactConfirmation: true,
|
|
2342
|
+
confirmImpact: rawOptions.yes === true,
|
|
1360
2343
|
});
|
|
1361
2344
|
if (rawOptions.json)
|
|
1362
2345
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1378,6 +2361,9 @@ export function buildProgram(options = {}) {
|
|
|
1378
2361
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1379
2362
|
.addOption(new Option('--subdir <path>', 'update the Git catalog subdirectory'))
|
|
1380
2363
|
.addOption(new Option('--no-subdir', 'remove the Git catalog subdirectory'))
|
|
2364
|
+
.addOption(new Option('--auto-check', 'enable automatic update checks for this source'))
|
|
2365
|
+
.addOption(new Option('--no-auto-check', 'disable automatic update checks for this source'))
|
|
2366
|
+
.option('-y, --yes', 'confirm a source identity change', false)
|
|
1381
2367
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1382
2368
|
.action(async (id, rawOptions) => {
|
|
1383
2369
|
try {
|
|
@@ -1391,15 +2377,25 @@ export function buildProgram(options = {}) {
|
|
|
1391
2377
|
|| rawOptions.path !== undefined
|
|
1392
2378
|
|| rawOptions.ref !== undefined
|
|
1393
2379
|
|| rawOptions.defaultRef === true
|
|
1394
|
-
|| rawOptions.subdir !== undefined
|
|
2380
|
+
|| rawOptions.subdir !== undefined
|
|
2381
|
+
|| rawOptions.autoCheck !== undefined;
|
|
1395
2382
|
if (!hasUpdate)
|
|
1396
2383
|
throw new Error('catalog source update requires at least one update option.');
|
|
1397
2384
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined))
|
|
1398
|
-
throw new Error('Path catalog source update only accepts `--path
|
|
2385
|
+
throw new Error('Path catalog source update only accepts `--path` and auto-check options.');
|
|
2386
|
+
const hasGitUpdate = rawOptions.git !== undefined
|
|
2387
|
+
|| rawOptions.ref !== undefined
|
|
2388
|
+
|| rawOptions.defaultRef === true
|
|
2389
|
+
|| rawOptions.subdir !== undefined;
|
|
1399
2390
|
const update = rawOptions.path !== undefined
|
|
1400
|
-
? {
|
|
1401
|
-
|
|
2391
|
+
? {
|
|
2392
|
+
type: 'path',
|
|
2393
|
+
path: rawOptions.path,
|
|
2394
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
2395
|
+
}
|
|
2396
|
+
: hasGitUpdate ? {
|
|
1402
2397
|
type: 'git',
|
|
2398
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
1403
2399
|
...(rawOptions.git !== undefined ? { url: rawOptions.git } : {}),
|
|
1404
2400
|
...(rawOptions.ref !== undefined || rawOptions.defaultRef === true
|
|
1405
2401
|
? { refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true) }
|
|
@@ -1407,13 +2403,22 @@ export function buildProgram(options = {}) {
|
|
|
1407
2403
|
...(rawOptions.subdir !== undefined
|
|
1408
2404
|
? { subdir: rawOptions.subdir === false ? null : rawOptions.subdir }
|
|
1409
2405
|
: {}),
|
|
1410
|
-
}
|
|
2406
|
+
}
|
|
2407
|
+
: { autoCheck: rawOptions.autoCheck };
|
|
2408
|
+
const preview = await preflightCatalogSourceMutation({
|
|
2409
|
+
request: { action: 'update', sourceId: id, update }, cwd, env,
|
|
2410
|
+
});
|
|
1411
2411
|
const receipt = await updateCatalogSourceCommand({
|
|
1412
2412
|
sourceId: id,
|
|
1413
2413
|
update,
|
|
1414
2414
|
cliVersion: resolveCliVersion(),
|
|
1415
2415
|
cwd,
|
|
1416
2416
|
env,
|
|
2417
|
+
expectedConfigDigest: preview.configDigest,
|
|
2418
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2419
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2420
|
+
requireIdentityChangeConfirmation: true,
|
|
2421
|
+
confirmIdentityChange: rawOptions.yes === true,
|
|
1417
2422
|
});
|
|
1418
2423
|
if (rawOptions.json)
|
|
1419
2424
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1429,10 +2434,17 @@ export function buildProgram(options = {}) {
|
|
|
1429
2434
|
catalogSource
|
|
1430
2435
|
.command('set-primary')
|
|
1431
2436
|
.argument('<id>')
|
|
2437
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1432
2438
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1433
2439
|
.action(async (id, rawOptions) => {
|
|
1434
2440
|
try {
|
|
1435
|
-
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2441
|
+
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2442
|
+
sourceId: id,
|
|
2443
|
+
cwd,
|
|
2444
|
+
env,
|
|
2445
|
+
requireImpactConfirmation: true,
|
|
2446
|
+
confirmImpact: rawOptions.yes === true,
|
|
2447
|
+
});
|
|
1436
2448
|
if (rawOptions.json)
|
|
1437
2449
|
writeJsonReceipt(io.stdout, receipt);
|
|
1438
2450
|
else
|
|
@@ -1445,10 +2457,17 @@ export function buildProgram(options = {}) {
|
|
|
1445
2457
|
catalogSource
|
|
1446
2458
|
.command('remove')
|
|
1447
2459
|
.argument('<id>')
|
|
2460
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
1448
2461
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1449
2462
|
.action(async (id, rawOptions) => {
|
|
1450
2463
|
try {
|
|
1451
|
-
const receipt = await removeCatalogSourceCommand({
|
|
2464
|
+
const receipt = await removeCatalogSourceCommand({
|
|
2465
|
+
sourceId: id,
|
|
2466
|
+
cwd,
|
|
2467
|
+
env,
|
|
2468
|
+
requireImpactConfirmation: true,
|
|
2469
|
+
confirmImpact: rawOptions.yes === true,
|
|
2470
|
+
});
|
|
1452
2471
|
if (rawOptions.json)
|
|
1453
2472
|
writeJsonReceipt(io.stdout, receipt);
|
|
1454
2473
|
else
|
|
@@ -1458,9 +2477,102 @@ export function buildProgram(options = {}) {
|
|
|
1458
2477
|
await writeCatalogSourceFailure('catalog:source:remove', id, rawOptions.json === true, error);
|
|
1459
2478
|
}
|
|
1460
2479
|
});
|
|
2480
|
+
const catalogStore = catalog
|
|
2481
|
+
.command('store')
|
|
2482
|
+
.description('Inspect or prune the immutable Catalog store');
|
|
2483
|
+
catalogStore
|
|
2484
|
+
.command('status')
|
|
2485
|
+
.option('-j, --json', 'print Catalog store status as JSON', false)
|
|
2486
|
+
.action(async (rawOptions) => {
|
|
2487
|
+
try {
|
|
2488
|
+
const result = await catalogStoreStatus({ env });
|
|
2489
|
+
if (rawOptions.json) {
|
|
2490
|
+
writeJsonReceipt(io.stdout, result);
|
|
2491
|
+
}
|
|
2492
|
+
else if (result.entries.length === 0) {
|
|
2493
|
+
writeLine(io.stdout, 'Catalog store is empty.');
|
|
2494
|
+
}
|
|
2495
|
+
else {
|
|
2496
|
+
for (const entry of result.entries) {
|
|
2497
|
+
const bytes = entry.reclaimableBytes === null ? 'unknown bytes' : `${entry.reclaimableBytes} bytes`;
|
|
2498
|
+
writeLine(io.stdout, `${entry.storeKey}: ${entry.category}, ${entry.status}, ${entry.reason}, ${bytes}`);
|
|
2499
|
+
}
|
|
2500
|
+
writeLine(io.stdout, `Reclaimable: ${result.totals.reclaimableEntries} item(s).`);
|
|
2501
|
+
if (result.errors.length > 0) {
|
|
2502
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2503
|
+
}
|
|
2504
|
+
}
|
|
2505
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2506
|
+
}
|
|
2507
|
+
catch (error) {
|
|
2508
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2509
|
+
const message = redactString(failure.message);
|
|
2510
|
+
if (rawOptions.json)
|
|
2511
|
+
writeJsonReceipt(io.stdout, {
|
|
2512
|
+
catalogStoreSchemaVersion: 2,
|
|
2513
|
+
command: 'catalog:store:status',
|
|
2514
|
+
ok: false,
|
|
2515
|
+
entries: [],
|
|
2516
|
+
errors: [{ code: catalogStoreErrorCode(error), message }],
|
|
2517
|
+
});
|
|
2518
|
+
writeLine(io.stderr, message);
|
|
2519
|
+
commandExitState.exitCode = 1;
|
|
2520
|
+
}
|
|
2521
|
+
});
|
|
2522
|
+
catalogStore
|
|
2523
|
+
.command('prune')
|
|
2524
|
+
.option('--dry-run', 'inspect reclaimable items without deleting them', false)
|
|
2525
|
+
.option('-y, --yes', 'delete items classified as safely reclaimable', false)
|
|
2526
|
+
.option('-j, --json', 'print the prune receipt as JSON', false)
|
|
2527
|
+
.action(async (rawOptions) => {
|
|
2528
|
+
const dryRun = rawOptions.yes !== true;
|
|
2529
|
+
try {
|
|
2530
|
+
if (rawOptions.dryRun === true && rawOptions.yes === true) {
|
|
2531
|
+
throw Object.assign(new Error('catalog store prune cannot combine `--dry-run` and `--yes`.'), {
|
|
2532
|
+
code: 'invalidArguments',
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
const result = await catalogStorePrune({ dryRun, env });
|
|
2536
|
+
if (rawOptions.json) {
|
|
2537
|
+
writeJsonReceipt(io.stdout, result);
|
|
2538
|
+
}
|
|
2539
|
+
else if (dryRun) {
|
|
2540
|
+
writeLine(io.stdout, `Dry run: ${result.entries.filter((entry) => entry.status === 'reclaimable').length} item(s) are reclaimable.`);
|
|
2541
|
+
writeLine(io.stdout, 'Run `aw catalog store prune --yes` to delete them.');
|
|
2542
|
+
if (result.errors.length > 0)
|
|
2543
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2544
|
+
}
|
|
2545
|
+
else {
|
|
2546
|
+
writeLine(io.stdout, `Deleted ${result.deleted.length} Catalog store item(s) (${result.deletedBytes} bytes).`);
|
|
2547
|
+
if (result.errors.length > 0)
|
|
2548
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected or deleted and were retained.`);
|
|
2549
|
+
}
|
|
2550
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2551
|
+
}
|
|
2552
|
+
catch (error) {
|
|
2553
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2554
|
+
const message = redactString(failure.message);
|
|
2555
|
+
const code = catalogStoreErrorCode(error);
|
|
2556
|
+
if (rawOptions.json)
|
|
2557
|
+
writeJsonReceipt(io.stdout, {
|
|
2558
|
+
catalogStoreSchemaVersion: 2,
|
|
2559
|
+
command: 'catalog:store:prune',
|
|
2560
|
+
ok: false,
|
|
2561
|
+
overallState: 'failed',
|
|
2562
|
+
dryRun,
|
|
2563
|
+
entries: [],
|
|
2564
|
+
deleted: [],
|
|
2565
|
+
retained: [],
|
|
2566
|
+
errors: [{ code, message }],
|
|
2567
|
+
reclaimableBytes: null,
|
|
2568
|
+
deletedBytes: 0,
|
|
2569
|
+
});
|
|
2570
|
+
writeLine(io.stderr, message);
|
|
2571
|
+
commandExitState.exitCode = 1;
|
|
2572
|
+
}
|
|
2573
|
+
});
|
|
1461
2574
|
program
|
|
1462
2575
|
.command('init')
|
|
1463
|
-
.option('-f, --force', 're-fetch and rebuild the current catalog cache entry', false)
|
|
1464
2576
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1465
2577
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1466
2578
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1468,8 +2580,6 @@ export function buildProgram(options = {}) {
|
|
|
1468
2580
|
.action(async (rawOptions) => {
|
|
1469
2581
|
const context = createActionContext('init', rawOptions);
|
|
1470
2582
|
const result = await runActionWithContext(context, () => initCommand({
|
|
1471
|
-
force: rawOptions.force,
|
|
1472
|
-
cliVersion: resolveCliVersion(),
|
|
1473
2583
|
env: context.env,
|
|
1474
2584
|
}));
|
|
1475
2585
|
if (rawOptions.json) {
|
|
@@ -1480,7 +2590,6 @@ export function buildProgram(options = {}) {
|
|
|
1480
2590
|
writeLine(io.stdout, line);
|
|
1481
2591
|
}
|
|
1482
2592
|
}
|
|
1483
|
-
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1484
2593
|
for (const source of result.sources) {
|
|
1485
2594
|
if (!source.ok && source.error)
|
|
1486
2595
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
@@ -1488,53 +2597,79 @@ export function buildProgram(options = {}) {
|
|
|
1488
2597
|
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1489
2598
|
});
|
|
1490
2599
|
program
|
|
1491
|
-
.command('
|
|
2600
|
+
.command('sync')
|
|
2601
|
+
.description('Reconcile actual state from existing desired intent')
|
|
1492
2602
|
.argument('[plugins...]')
|
|
1493
|
-
.
|
|
1494
|
-
.
|
|
1495
|
-
.option('
|
|
1496
|
-
.option('
|
|
2603
|
+
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
2604
|
+
.requiredOption('-p, --platform <platform>', 'codex, claude, or both')
|
|
2605
|
+
.option('-a, --all', 'reconcile every desired plugin in the selected scope', false)
|
|
2606
|
+
.option('--refresh', 'refresh only Catalog sources required by selected intent roots', false)
|
|
2607
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2608
|
+
.option('-y, --yes', 'authorize preApply and shared native replacement or forced repair', false)
|
|
2609
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2610
|
+
.option('-j, --json', 'print sync receipt as JSON', false)
|
|
1497
2611
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1498
2612
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1499
2613
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1500
2614
|
.action(async (plugins, rawOptions) => {
|
|
1501
|
-
const context = createActionContext('
|
|
1502
|
-
const
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
2615
|
+
const context = createActionContext('sync', rawOptions);
|
|
2616
|
+
const normalized = normalizeWriteRequest(() => normalizeInstallCommandOptions({
|
|
2617
|
+
cwd: context.cwd,
|
|
2618
|
+
scope: rawOptions.scope,
|
|
2619
|
+
platform: rawOptions.platform,
|
|
2620
|
+
scriptTimeout: rawOptions.scriptTimeout,
|
|
2621
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2622
|
+
}));
|
|
2623
|
+
const syncPlatform = normalized.platform;
|
|
2624
|
+
const result = await runActionWithContext(context, () => syncCommand(plugins ?? [], {
|
|
2625
|
+
cwd: context.cwd,
|
|
2626
|
+
env: context.env,
|
|
2627
|
+
platform: syncPlatform,
|
|
2628
|
+
scope: normalized.scope,
|
|
2629
|
+
all: rawOptions.all,
|
|
2630
|
+
refresh: rawOptions.refresh,
|
|
2631
|
+
cliVersion: resolveCliVersion(),
|
|
2632
|
+
yes: rawOptions.yes,
|
|
2633
|
+
json: rawOptions.json,
|
|
2634
|
+
interactive: context.interactive && context.isTty && !context.isCi,
|
|
2635
|
+
prompt: context.prompt,
|
|
2636
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2637
|
+
scriptTimeoutMs: normalized.scriptTimeoutMs,
|
|
2638
|
+
}, context));
|
|
1506
2639
|
if (rawOptions.json) {
|
|
1507
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2640
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('sync', result));
|
|
1508
2641
|
}
|
|
1509
2642
|
else {
|
|
1510
|
-
for (const line of renderRebuildReceipt('
|
|
2643
|
+
for (const line of renderRebuildReceipt('sync', result))
|
|
1511
2644
|
writeLine(io.stdout, line);
|
|
1512
|
-
}
|
|
1513
2645
|
}
|
|
1514
|
-
writeWarnings(io.stderr,
|
|
1515
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(
|
|
2646
|
+
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
2647
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1516
2648
|
});
|
|
1517
2649
|
program
|
|
1518
|
-
.command('
|
|
2650
|
+
.command('install')
|
|
1519
2651
|
.argument('[plugins...]')
|
|
1520
2652
|
.option('-s, --scope <scope>', 'project or user')
|
|
1521
2653
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1522
|
-
.option('--
|
|
2654
|
+
.option('--dependency-scope <pluginId[#platform]=scope>', 'place one dependency at project or user scope; repeat for more dependencies', (value, previous) => [...previous, value], [])
|
|
2655
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2656
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2657
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement', false)
|
|
1523
2658
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1524
2659
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1525
2660
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1526
2661
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1527
2662
|
.action(async (plugins, rawOptions) => {
|
|
1528
|
-
const context = createActionContext('
|
|
1529
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2663
|
+
const context = createActionContext('install', rawOptions);
|
|
2664
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('install', plugins ?? [], rawOptions, context));
|
|
1530
2665
|
if (outcome.cancelled)
|
|
1531
2666
|
return;
|
|
1532
2667
|
const receipt = outcome.result;
|
|
1533
2668
|
if (rawOptions.json) {
|
|
1534
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2669
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('install', receipt));
|
|
1535
2670
|
}
|
|
1536
2671
|
else {
|
|
1537
|
-
for (const line of renderRebuildReceipt('
|
|
2672
|
+
for (const line of renderRebuildReceipt('install', receipt)) {
|
|
1538
2673
|
writeLine(io.stdout, line);
|
|
1539
2674
|
}
|
|
1540
2675
|
}
|
|
@@ -1542,27 +2677,26 @@ export function buildProgram(options = {}) {
|
|
|
1542
2677
|
commandExitState.exitCode = resolveCommandReceiptExitCode(receipt);
|
|
1543
2678
|
});
|
|
1544
2679
|
program
|
|
1545
|
-
.command('
|
|
2680
|
+
.command('uninstall')
|
|
1546
2681
|
.argument('[plugins...]')
|
|
1547
|
-
.option('-a, --all', 'upgrade all plugins', false)
|
|
1548
2682
|
.option('-s, --scope <scope>', 'project or user')
|
|
1549
2683
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1550
|
-
.option('--
|
|
2684
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1551
2685
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1552
2686
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1553
2687
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1554
2688
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1555
2689
|
.action(async (plugins, rawOptions) => {
|
|
1556
|
-
const context = createActionContext('
|
|
1557
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2690
|
+
const context = createActionContext('uninstall', rawOptions);
|
|
2691
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('uninstall', plugins ?? [], rawOptions, context));
|
|
1558
2692
|
if (outcome.cancelled)
|
|
1559
2693
|
return;
|
|
1560
2694
|
const receipt = outcome.result;
|
|
1561
2695
|
if (rawOptions.json) {
|
|
1562
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2696
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('uninstall', receipt));
|
|
1563
2697
|
}
|
|
1564
2698
|
else {
|
|
1565
|
-
for (const line of renderRebuildReceipt('
|
|
2699
|
+
for (const line of renderRebuildReceipt('uninstall', receipt)) {
|
|
1566
2700
|
writeLine(io.stdout, line);
|
|
1567
2701
|
}
|
|
1568
2702
|
}
|
|
@@ -1575,7 +2709,9 @@ export function buildProgram(options = {}) {
|
|
|
1575
2709
|
.option('-s, --scope <scope>', 'project or user')
|
|
1576
2710
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1577
2711
|
.option('-j, --json', 'print cleanup result as JSON', false)
|
|
1578
|
-
.option('--force', '
|
|
2712
|
+
.option('--force', 'use exact shallow evidence for exclusively owned damaged output; preserve foreign/shared content; no deleted-plugin-wide cleanup', false)
|
|
2713
|
+
.option('-y, --yes', 'authorize cleanup of a deleted plugin across Codex, Claude Code, user and current project, including saved settings and shared native install', false)
|
|
2714
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1579
2715
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1580
2716
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1581
2717
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
@@ -1594,14 +2730,16 @@ export function buildProgram(options = {}) {
|
|
|
1594
2730
|
}
|
|
1595
2731
|
}
|
|
1596
2732
|
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1597
|
-
commandExitState.exitCode = result
|
|
2733
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1598
2734
|
});
|
|
1599
2735
|
program
|
|
1600
2736
|
.command('reinstall')
|
|
1601
2737
|
.argument('[plugins...]')
|
|
1602
2738
|
.option('-s, --scope <scope>', 'project or user')
|
|
1603
2739
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1604
|
-
.option('--script-timeout <ms>', 'override plugin
|
|
2740
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2741
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2742
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement or forced reinstall', false)
|
|
1605
2743
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1606
2744
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1607
2745
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1631,7 +2769,6 @@ export function buildProgram(options = {}) {
|
|
|
1631
2769
|
.command('list')
|
|
1632
2770
|
.argument('[plugin]')
|
|
1633
2771
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1634
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1635
2772
|
.option('-j, --json', 'print config as JSON', false)
|
|
1636
2773
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1637
2774
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1639,9 +2776,7 @@ export function buildProgram(options = {}) {
|
|
|
1639
2776
|
.action(async (pluginName, rawOptions) => {
|
|
1640
2777
|
const context = createActionContext('config:list', rawOptions);
|
|
1641
2778
|
const outcome = await runActionWithContext(context, async () => {
|
|
1642
|
-
|
|
1643
|
-
if (!rawOptions.local)
|
|
1644
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2779
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1645
2780
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1646
2781
|
selector: selectedPlugin,
|
|
1647
2782
|
rawOptions,
|
|
@@ -1666,7 +2801,6 @@ export function buildProgram(options = {}) {
|
|
|
1666
2801
|
command: 'list',
|
|
1667
2802
|
plugin: selection.plugins[0],
|
|
1668
2803
|
scope: rawOptions.scope,
|
|
1669
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1670
2804
|
})),
|
|
1671
2805
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1672
2806
|
});
|
|
@@ -1688,8 +2822,7 @@ export function buildProgram(options = {}) {
|
|
|
1688
2822
|
pluginId: resolved.pluginId,
|
|
1689
2823
|
sourceId: resolved.sourceId,
|
|
1690
2824
|
sourceIdentity: resolved.sourceIdentity,
|
|
1691
|
-
scope: rawOptions.
|
|
1692
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2825
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1693
2826
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1694
2827
|
fields: resolved.result.fields,
|
|
1695
2828
|
});
|
|
@@ -1703,7 +2836,6 @@ export function buildProgram(options = {}) {
|
|
|
1703
2836
|
.argument('[plugin]')
|
|
1704
2837
|
.argument('[key]')
|
|
1705
2838
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1706
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1707
2839
|
.option('-j, --json', 'print config as JSON', false)
|
|
1708
2840
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1709
2841
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1711,9 +2843,7 @@ export function buildProgram(options = {}) {
|
|
|
1711
2843
|
.action(async (pluginName, key, rawOptions) => {
|
|
1712
2844
|
const context = createActionContext('config:get', rawOptions);
|
|
1713
2845
|
const outcome = await runActionWithContext(context, async () => {
|
|
1714
|
-
|
|
1715
|
-
if (!rawOptions.local)
|
|
1716
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2846
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1717
2847
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1718
2848
|
selector: selectedPlugin,
|
|
1719
2849
|
...(key === undefined ? {} : { key }),
|
|
@@ -1740,7 +2870,6 @@ export function buildProgram(options = {}) {
|
|
|
1740
2870
|
plugin: selection.plugins[0],
|
|
1741
2871
|
key,
|
|
1742
2872
|
scope: rawOptions.scope,
|
|
1743
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1744
2873
|
})),
|
|
1745
2874
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1746
2875
|
});
|
|
@@ -1763,8 +2892,7 @@ export function buildProgram(options = {}) {
|
|
|
1763
2892
|
sourceId: resolved.sourceId,
|
|
1764
2893
|
sourceIdentity: resolved.sourceIdentity,
|
|
1765
2894
|
key,
|
|
1766
|
-
scope: rawOptions.
|
|
1767
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2895
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1768
2896
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1769
2897
|
fields: resolved.result.fields,
|
|
1770
2898
|
});
|
|
@@ -1776,47 +2904,119 @@ export function buildProgram(options = {}) {
|
|
|
1776
2904
|
config
|
|
1777
2905
|
.command('set')
|
|
1778
2906
|
.argument('[plugin]')
|
|
1779
|
-
.argument('[
|
|
1780
|
-
.argument('[value]')
|
|
2907
|
+
.argument('[field]')
|
|
1781
2908
|
.option('-s, --scope <scope>', 'project or user')
|
|
1782
|
-
.option('--
|
|
1783
|
-
.option('--value-
|
|
2909
|
+
.option('--value-json <json>', 'set the field to an exact JSON value')
|
|
2910
|
+
.option('--value-stdin', 'read the exact string value from stdin until EOF', false)
|
|
2911
|
+
.option('--preset <id>', 'set the field to the current manifest preset value')
|
|
2912
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2913
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2914
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1784
2915
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1785
2916
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1786
2917
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1787
2918
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1788
|
-
.action(async (pluginName, key,
|
|
2919
|
+
.action(async (pluginName, key, rawOptions) => {
|
|
2920
|
+
if (!pluginName || !key)
|
|
2921
|
+
throw new Error(configCommandUsage('set'));
|
|
1789
2922
|
const context = createActionContext('config:set', rawOptions);
|
|
1790
2923
|
let outcome;
|
|
1791
2924
|
try {
|
|
1792
2925
|
outcome = await runActionWithContext(context, async () => {
|
|
1793
2926
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
1794
|
-
const
|
|
1795
|
-
const
|
|
1796
|
-
|
|
1797
|
-
|
|
2927
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2928
|
+
const explicitValueCount = [
|
|
2929
|
+
rawOptions.valueJson !== undefined,
|
|
2930
|
+
rawOptions.valueStdin === true,
|
|
2931
|
+
rawOptions.preset !== undefined,
|
|
2932
|
+
].filter(Boolean).length;
|
|
2933
|
+
if (explicitValueCount > 1
|
|
2934
|
+
|| (explicitValueCount === 0
|
|
2935
|
+
&& !(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true))) {
|
|
2936
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2937
|
+
}
|
|
2938
|
+
return withResolvedConfigMutationPlugin(context, pluginName, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2939
|
+
if (!plugin.manifest.config?.fields) {
|
|
2940
|
+
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1798
2941
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
2942
|
+
const field = plugin.manifest.config.fields[key];
|
|
2943
|
+
if (!field) {
|
|
2944
|
+
throw new Error(`Unknown config key "${key}".`);
|
|
2945
|
+
}
|
|
2946
|
+
const sensitive = field.sensitive === true;
|
|
2947
|
+
if (sensitive && scope !== 'user') {
|
|
2948
|
+
const error = new Error('sensitiveProjectConfigUnsupported: Sensitive config can only be set in user scope.');
|
|
2949
|
+
error.code = 'sensitiveProjectConfigUnsupported';
|
|
2950
|
+
throw error;
|
|
2951
|
+
}
|
|
2952
|
+
if (sensitive && (rawOptions.valueJson !== undefined || rawOptions.preset !== undefined)) {
|
|
2953
|
+
const error = new Error('sensitiveConfigInputUnsupported: Sensitive config cannot use --value-json or --preset.');
|
|
2954
|
+
error.code = 'sensitiveConfigInputUnsupported';
|
|
2955
|
+
throw error;
|
|
2956
|
+
}
|
|
2957
|
+
if (!sensitive && explicitValueCount !== 1) {
|
|
2958
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2959
|
+
}
|
|
2960
|
+
let inputValue;
|
|
2961
|
+
if (rawOptions.valueStdin === true) {
|
|
2962
|
+
inputValue = await readUtf8Stdin(context.stdin);
|
|
2963
|
+
}
|
|
2964
|
+
else if (sensitive) {
|
|
2965
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
2966
|
+
|| !context.prompt.password) {
|
|
2967
|
+
const error = new Error('sensitiveConfigStdinRequired: Use --value-stdin for sensitive config outside an interactive terminal.');
|
|
2968
|
+
error.code = 'sensitiveConfigStdinRequired';
|
|
2969
|
+
throw error;
|
|
2970
|
+
}
|
|
2971
|
+
const response = await context.prompt.password({
|
|
2972
|
+
message: `输入 ${field.title ?? key}`,
|
|
2973
|
+
mask: true,
|
|
2974
|
+
});
|
|
2975
|
+
if (response.cancelled || response.action !== 'select' || response.value === undefined) {
|
|
2976
|
+
const error = new Error('sensitiveConfigInputCancelled: Sensitive config input was cancelled.');
|
|
2977
|
+
error.code = 'sensitiveConfigInputCancelled';
|
|
2978
|
+
throw error;
|
|
2979
|
+
}
|
|
2980
|
+
inputValue = response.value;
|
|
2981
|
+
}
|
|
2982
|
+
else if (rawOptions.valueJson !== undefined) {
|
|
2983
|
+
try {
|
|
2984
|
+
inputValue = JSON.parse(rawOptions.valueJson);
|
|
2985
|
+
}
|
|
2986
|
+
catch {
|
|
2987
|
+
throw new Error('--value-json must contain valid JSON.');
|
|
2988
|
+
}
|
|
2989
|
+
}
|
|
2990
|
+
else {
|
|
2991
|
+
const preset = field.choices?.presets.find((entry) => entry.id === rawOptions.preset);
|
|
2992
|
+
if (!preset)
|
|
2993
|
+
throw new Error(`Unknown preset "${rawOptions.preset}" for config key "${key}".`);
|
|
2994
|
+
inputValue = structuredClone(preset.value);
|
|
1801
2995
|
}
|
|
1802
2996
|
const writeReceipt = await applyPluginConfigWrite({
|
|
1803
2997
|
plugin,
|
|
1804
2998
|
pluginName: plugin.manifest.name,
|
|
1805
2999
|
scope,
|
|
1806
|
-
projectLayer,
|
|
1807
3000
|
cwd: context.cwd,
|
|
1808
3001
|
env: context.env,
|
|
1809
3002
|
nativeCliRunner: context.nativeCliRunner,
|
|
1810
|
-
rebuildRuntime: {
|
|
3003
|
+
rebuildRuntime: {
|
|
3004
|
+
...context,
|
|
3005
|
+
awHomeMutationToken,
|
|
3006
|
+
catalogOperationContext,
|
|
3007
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
3008
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
3009
|
+
},
|
|
1811
3010
|
awHomeMutationToken,
|
|
1812
3011
|
request: {
|
|
1813
|
-
updates: { [
|
|
3012
|
+
updates: { [key]: inputValue },
|
|
1814
3013
|
},
|
|
3014
|
+
apply: rawOptions.apply === true,
|
|
3015
|
+
sharedNativeApplyConfirmed: rawOptions.yes === true,
|
|
3016
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
1815
3017
|
});
|
|
1816
|
-
return {
|
|
3018
|
+
return buildConfigMutationReceipt('config:set', {
|
|
1817
3019
|
ok: writeReceipt.overallState === 'succeeded',
|
|
1818
|
-
receiptSchemaVersion: 4,
|
|
1819
|
-
command: 'config:set',
|
|
1820
3020
|
...writeReceipt,
|
|
1821
3021
|
plugin: plugin.manifest.name,
|
|
1822
3022
|
pluginName: plugin.manifest.name,
|
|
@@ -1824,104 +3024,39 @@ export function buildProgram(options = {}) {
|
|
|
1824
3024
|
sourceId: source.sourceId,
|
|
1825
3025
|
sourceIdentity: source.sourceIdentity,
|
|
1826
3026
|
affectedFields: [{
|
|
1827
|
-
key
|
|
1828
|
-
title:
|
|
3027
|
+
key,
|
|
3028
|
+
title: field.title ?? key,
|
|
1829
3029
|
kind: 'manifest',
|
|
1830
3030
|
reserved: false,
|
|
1831
3031
|
action: 'set',
|
|
1832
3032
|
scope,
|
|
1833
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
1834
3033
|
}],
|
|
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
|
-
},
|
|
3034
|
+
});
|
|
1893
3035
|
});
|
|
1894
|
-
return result.cancelled
|
|
1895
|
-
? { cancelled: true }
|
|
1896
|
-
: { cancelled: false, key: result.selection.key, value: result.value };
|
|
1897
3036
|
});
|
|
1898
3037
|
}
|
|
1899
3038
|
catch (error) {
|
|
1900
3039
|
writeConfigMutationFailure('config:set', pluginName, rawOptions.json === true, error);
|
|
1901
3040
|
return;
|
|
1902
3041
|
}
|
|
1903
|
-
|
|
1904
|
-
return;
|
|
1905
|
-
const receipt = outcome.value;
|
|
1906
|
-
const selectedKey = outcome.key;
|
|
3042
|
+
const receipt = outcome;
|
|
1907
3043
|
if (rawOptions.json) {
|
|
1908
3044
|
writeJsonReceipt(io.stdout, receipt);
|
|
1909
3045
|
}
|
|
1910
3046
|
else {
|
|
1911
|
-
writeLine(io.stdout, `已写入 ${receipt.plugin}.${
|
|
1912
|
-
if (receipt.projectLayer === 'local') {
|
|
1913
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
1914
|
-
}
|
|
3047
|
+
writeLine(io.stdout, `已写入 ${receipt.plugin}.${key}(${configLayerLabel(receipt.scope)}配置)。`);
|
|
1915
3048
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
1916
3049
|
}
|
|
1917
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3050
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
1918
3051
|
});
|
|
1919
3052
|
config
|
|
1920
3053
|
.command('unset')
|
|
1921
3054
|
.argument('[plugin]')
|
|
1922
3055
|
.argument('[key]')
|
|
1923
3056
|
.option('-s, --scope <scope>', 'project or user')
|
|
1924
|
-
.option('--
|
|
3057
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3058
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3059
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1925
3060
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1926
3061
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1927
3062
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1932,19 +3067,17 @@ export function buildProgram(options = {}) {
|
|
|
1932
3067
|
try {
|
|
1933
3068
|
outcome = await runActionWithContext(context, async () => {
|
|
1934
3069
|
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
|
-
}
|
|
3070
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
3071
|
+
const execute = async (selectedPlugin, selectedKey, confirmed) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
1940
3072
|
const store = await readPluginConfigStore({
|
|
1941
3073
|
sourceId: source.sourceId,
|
|
1942
3074
|
sourceIdentity: source.sourceIdentity,
|
|
3075
|
+
logicalIdentity: source.logicalIdentity,
|
|
1943
3076
|
pluginName: plugin.manifest.name,
|
|
1944
3077
|
scope,
|
|
1945
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
1946
3078
|
cwd: context.cwd,
|
|
1947
3079
|
env: context.env,
|
|
3080
|
+
schema: plugin.manifest.config?.fields,
|
|
1948
3081
|
});
|
|
1949
3082
|
const existed = Object.hasOwn(store.values, selectedKey);
|
|
1950
3083
|
if (!existed)
|
|
@@ -1953,20 +3086,26 @@ export function buildProgram(options = {}) {
|
|
|
1953
3086
|
plugin,
|
|
1954
3087
|
pluginName: plugin.manifest.name,
|
|
1955
3088
|
scope,
|
|
1956
|
-
projectLayer,
|
|
1957
3089
|
cwd: context.cwd,
|
|
1958
3090
|
env: context.env,
|
|
1959
3091
|
nativeCliRunner: context.nativeCliRunner,
|
|
1960
|
-
rebuildRuntime: {
|
|
3092
|
+
rebuildRuntime: {
|
|
3093
|
+
...context,
|
|
3094
|
+
awHomeMutationToken,
|
|
3095
|
+
catalogOperationContext,
|
|
3096
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
3097
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
3098
|
+
},
|
|
1961
3099
|
awHomeMutationToken,
|
|
1962
3100
|
request: {
|
|
1963
3101
|
removeKeys: [selectedKey],
|
|
1964
3102
|
},
|
|
3103
|
+
apply: rawOptions.apply === true,
|
|
3104
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
3105
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
1965
3106
|
});
|
|
1966
|
-
return {
|
|
3107
|
+
return buildConfigMutationReceipt('config:unset', {
|
|
1967
3108
|
ok: writeReceipt.overallState === 'succeeded',
|
|
1968
|
-
receiptSchemaVersion: 4,
|
|
1969
|
-
command: 'config:unset',
|
|
1970
3109
|
...writeReceipt,
|
|
1971
3110
|
plugin: plugin.manifest.name,
|
|
1972
3111
|
pluginName: plugin.manifest.name,
|
|
@@ -1977,17 +3116,20 @@ export function buildProgram(options = {}) {
|
|
|
1977
3116
|
existed,
|
|
1978
3117
|
affectedFields: [{
|
|
1979
3118
|
key: selectedKey,
|
|
1980
|
-
title: plugin?.manifest.config?.
|
|
3119
|
+
title: plugin?.manifest.config?.fields?.[selectedKey]?.title ?? selectedKey,
|
|
1981
3120
|
kind: 'manifest',
|
|
1982
3121
|
reserved: false,
|
|
1983
3122
|
action: 'unset',
|
|
1984
3123
|
scope,
|
|
1985
|
-
...(
|
|
3124
|
+
...(!plugin.manifest.config?.fields?.[selectedKey] ? { stale: true } : {}),
|
|
1986
3125
|
}],
|
|
1987
|
-
};
|
|
3126
|
+
});
|
|
1988
3127
|
});
|
|
1989
3128
|
if (pluginName && key) {
|
|
1990
|
-
return {
|
|
3129
|
+
return {
|
|
3130
|
+
cancelled: false,
|
|
3131
|
+
value: await execute(pluginName, key, rawOptions.yes === true),
|
|
3132
|
+
};
|
|
1991
3133
|
}
|
|
1992
3134
|
if (!isWizardAvailable(context, rawOptions))
|
|
1993
3135
|
throw new Error(configCommandUsage('unset'));
|
|
@@ -2003,7 +3145,7 @@ export function buildProgram(options = {}) {
|
|
|
2003
3145
|
const result = await runCommandWizard(context, {
|
|
2004
3146
|
command: 'config:unset',
|
|
2005
3147
|
candidates,
|
|
2006
|
-
initial: { plugins: pluginName ? [pluginName] : [], key, scope
|
|
3148
|
+
initial: { plugins: pluginName ? [pluginName] : [], key, scope },
|
|
2007
3149
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2008
3150
|
promptForKey: key === undefined,
|
|
2009
3151
|
destructive: true,
|
|
@@ -2012,10 +3154,9 @@ export function buildProgram(options = {}) {
|
|
|
2012
3154
|
plugin: selection.plugins[0],
|
|
2013
3155
|
key: selection.key,
|
|
2014
3156
|
scope: selection.scope ?? 'user',
|
|
2015
|
-
projectLayer: selection.projectLayer,
|
|
2016
3157
|
})),
|
|
2017
3158
|
resultState: overallResultState,
|
|
2018
|
-
execute: (selection) => execute(selection.plugins[0], selection.key),
|
|
3159
|
+
execute: (selection) => execute(selection.plugins[0], selection.key, true),
|
|
2019
3160
|
});
|
|
2020
3161
|
return result.cancelled
|
|
2021
3162
|
? { cancelled: true }
|
|
@@ -2034,21 +3175,19 @@ export function buildProgram(options = {}) {
|
|
|
2034
3175
|
}
|
|
2035
3176
|
else {
|
|
2036
3177
|
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
|
-
}
|
|
3178
|
+
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)。`
|
|
3179
|
+
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)原本不存在。`);
|
|
2042
3180
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2043
3181
|
}
|
|
2044
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3182
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2045
3183
|
});
|
|
2046
3184
|
config
|
|
2047
3185
|
.command('reset')
|
|
2048
3186
|
.argument('[plugin]')
|
|
2049
3187
|
.option('-s, --scope <scope>', 'project or user')
|
|
2050
|
-
.option('--
|
|
2051
|
-
.option('-
|
|
3188
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3189
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3190
|
+
.option('-y, --yes', 'confirm destructive reset and preApply/shared Codex native config apply', false)
|
|
2052
3191
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
2053
3192
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2054
3193
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -2058,61 +3197,79 @@ export function buildProgram(options = {}) {
|
|
|
2058
3197
|
let outcome;
|
|
2059
3198
|
try {
|
|
2060
3199
|
outcome = await runActionWithContext(context, async () => {
|
|
2061
|
-
const execute = async (selectedPlugin, selectedScope,
|
|
3200
|
+
const execute = async (selectedPlugin, selectedScope, confirmed) => {
|
|
3201
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2062
3202
|
if (!confirmed) {
|
|
2063
|
-
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope}
|
|
3203
|
+
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope} --yes\` to delete this store.`);
|
|
2064
3204
|
}
|
|
2065
|
-
|
|
3205
|
+
const located = await resolveStoredConfigResetIdentity({
|
|
3206
|
+
selector: selectedPlugin,
|
|
3207
|
+
context,
|
|
3208
|
+
scope: selectedScope,
|
|
3209
|
+
});
|
|
3210
|
+
const resetLocatedStore = async (plugin, pluginError) => {
|
|
2066
3211
|
const affectedFields = await describeResetAffectedFields({
|
|
2067
|
-
|
|
3212
|
+
sourceId: located.sourceId,
|
|
3213
|
+
sourceIdentity: located.sourceIdentity,
|
|
3214
|
+
logicalIdentity: located.logicalIdentity,
|
|
3215
|
+
pluginName: located.pluginName,
|
|
2068
3216
|
plugin,
|
|
3217
|
+
pluginError,
|
|
2069
3218
|
scope: selectedScope,
|
|
2070
|
-
projectLayer,
|
|
2071
3219
|
cwd: context.cwd,
|
|
2072
3220
|
env: context.env,
|
|
2073
|
-
});
|
|
3221
|
+
}).catch(() => []);
|
|
2074
3222
|
const resetReceipt = await resetPluginConfigWithHelper({
|
|
2075
|
-
|
|
3223
|
+
sourceId: located.sourceId,
|
|
3224
|
+
sourceIdentity: located.sourceIdentity,
|
|
3225
|
+
logicalIdentity: located.logicalIdentity,
|
|
3226
|
+
pluginName: located.pluginName,
|
|
2076
3227
|
scope: selectedScope,
|
|
2077
|
-
projectLayer,
|
|
2078
3228
|
cwd: context.cwd,
|
|
2079
3229
|
env: context.env,
|
|
2080
3230
|
nativeCliRunner: context.nativeCliRunner,
|
|
2081
|
-
rebuildRuntime: { ...context, awHomeMutationToken },
|
|
2082
|
-
awHomeMutationToken,
|
|
2083
3231
|
plugin,
|
|
3232
|
+
pluginError,
|
|
3233
|
+
apply: rawOptions.apply === true,
|
|
3234
|
+
rebuildRuntime: scriptTimeoutMs === undefined ? undefined : { scriptTimeoutMs },
|
|
3235
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
3236
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
2084
3237
|
});
|
|
2085
|
-
return {
|
|
3238
|
+
return buildConfigMutationReceipt('config:reset', {
|
|
2086
3239
|
ok: resetReceipt.overallState === 'succeeded',
|
|
2087
|
-
receiptSchemaVersion: 4,
|
|
2088
|
-
command: 'config:reset',
|
|
2089
3240
|
...resetReceipt,
|
|
2090
|
-
plugin:
|
|
2091
|
-
pluginName:
|
|
2092
|
-
pluginId,
|
|
2093
|
-
sourceId:
|
|
2094
|
-
sourceIdentity:
|
|
3241
|
+
plugin: located.pluginName,
|
|
3242
|
+
pluginName: located.pluginName,
|
|
3243
|
+
pluginId: located.pluginId,
|
|
3244
|
+
sourceId: located.sourceId,
|
|
3245
|
+
...(located.sourceIdentity ? { sourceIdentity: located.sourceIdentity } : {}),
|
|
2095
3246
|
affectedFields,
|
|
2096
|
-
};
|
|
2097
|
-
}
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
3247
|
+
});
|
|
3248
|
+
};
|
|
3249
|
+
let resetStarted = false;
|
|
3250
|
+
try {
|
|
3251
|
+
return await withResolvedCatalogPlugin({
|
|
3252
|
+
selector: located.pluginId,
|
|
3253
|
+
cliVersion: resolveCliVersion(),
|
|
3254
|
+
env: context.env,
|
|
3255
|
+
consume: async ({ plugin }) => {
|
|
3256
|
+
resetStarted = true;
|
|
3257
|
+
return resetLocatedStore(plugin, null);
|
|
3258
|
+
},
|
|
3259
|
+
});
|
|
3260
|
+
}
|
|
3261
|
+
catch (error) {
|
|
3262
|
+
if (resetStarted)
|
|
3263
|
+
throw error;
|
|
3264
|
+
return resetLocatedStore(null, error instanceof Error ? error : new Error(String(error)));
|
|
3265
|
+
}
|
|
2108
3266
|
};
|
|
2109
3267
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
2110
|
-
const projectLayer = resolveConfigProjectLayer(rawOptions);
|
|
2111
3268
|
const needsWizard = pluginName === undefined || rawOptions.yes !== true;
|
|
2112
3269
|
if (!needsWizard) {
|
|
2113
3270
|
return {
|
|
2114
3271
|
cancelled: false,
|
|
2115
|
-
value: await execute(pluginName, scope,
|
|
3272
|
+
value: await execute(pluginName, scope, true),
|
|
2116
3273
|
};
|
|
2117
3274
|
}
|
|
2118
3275
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
@@ -2120,16 +3277,16 @@ export function buildProgram(options = {}) {
|
|
|
2120
3277
|
throw new Error(configCommandUsage('reset'));
|
|
2121
3278
|
return {
|
|
2122
3279
|
cancelled: false,
|
|
2123
|
-
value: await execute(pluginName, scope,
|
|
3280
|
+
value: await execute(pluginName, scope, false),
|
|
2124
3281
|
};
|
|
2125
3282
|
}
|
|
2126
3283
|
const currentCandidates = pluginName ? [] : await loadWizardCandidates(context, {});
|
|
2127
3284
|
const candidatesByScope = new Map();
|
|
2128
3285
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'user')) {
|
|
2129
|
-
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user'
|
|
3286
|
+
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user' }], { includeEmptyStores: true })));
|
|
2130
3287
|
}
|
|
2131
3288
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'project')) {
|
|
2132
|
-
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project'
|
|
3289
|
+
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project' }], { includeEmptyStores: true })));
|
|
2133
3290
|
}
|
|
2134
3291
|
const candidates = mergeWizardCandidates(candidatesByScope.get('user') ?? [], candidatesByScope.get('project') ?? []);
|
|
2135
3292
|
if (!pluginName && candidates.length === 0) {
|
|
@@ -2138,7 +3295,7 @@ export function buildProgram(options = {}) {
|
|
|
2138
3295
|
const result = await runCommandWizard(context, {
|
|
2139
3296
|
command: 'config:reset',
|
|
2140
3297
|
candidates,
|
|
2141
|
-
initial: { plugins: pluginName ? [pluginName] : [], scope
|
|
3298
|
+
initial: { plugins: pluginName ? [pluginName] : [], scope },
|
|
2142
3299
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2143
3300
|
promptForScope: rawOptions.scope === undefined,
|
|
2144
3301
|
destructive: true,
|
|
@@ -2149,11 +3306,10 @@ export function buildProgram(options = {}) {
|
|
|
2149
3306
|
command: 'reset',
|
|
2150
3307
|
plugin: selection.plugins[0],
|
|
2151
3308
|
scope: selection.scope ?? 'user',
|
|
2152
|
-
projectLayer: selection.projectLayer,
|
|
2153
3309
|
confirmed: true,
|
|
2154
3310
|
})),
|
|
2155
3311
|
resultState: overallResultState,
|
|
2156
|
-
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user',
|
|
3312
|
+
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user', true),
|
|
2157
3313
|
});
|
|
2158
3314
|
return result.cancelled
|
|
2159
3315
|
? { cancelled: true }
|
|
@@ -2172,14 +3328,11 @@ export function buildProgram(options = {}) {
|
|
|
2172
3328
|
}
|
|
2173
3329
|
else {
|
|
2174
3330
|
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
|
-
}
|
|
3331
|
+
? `已重置 ${receipt.plugin} 的${configLayerLabel(receipt.scope)}配置。`
|
|
3332
|
+
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope)}配置。`);
|
|
2180
3333
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2181
3334
|
}
|
|
2182
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3335
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2183
3336
|
});
|
|
2184
3337
|
program
|
|
2185
3338
|
.command('status')
|
|
@@ -2192,7 +3345,7 @@ export function buildProgram(options = {}) {
|
|
|
2192
3345
|
.option('-j, --json', 'print status as JSON', false)
|
|
2193
3346
|
.action(async (plugins, rawOptions) => {
|
|
2194
3347
|
const context = createActionContext('status', rawOptions);
|
|
2195
|
-
const result = await runActionWithContext(context, () =>
|
|
3348
|
+
const result = await runActionWithContext(context, () => statusCommandV8({
|
|
2196
3349
|
plugins: plugins ?? [],
|
|
2197
3350
|
cwd,
|
|
2198
3351
|
env: context.env,
|
|
@@ -2205,11 +3358,11 @@ export function buildProgram(options = {}) {
|
|
|
2205
3358
|
commandExitState.exitCode = result.hasErrors ? 1 : 0;
|
|
2206
3359
|
writeLine(io.stdout, result.output);
|
|
2207
3360
|
for (const source of result.payload.catalog.sources) {
|
|
2208
|
-
if (source.error)
|
|
3361
|
+
if (rawOptions.json && source.error)
|
|
2209
3362
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
2210
3363
|
}
|
|
2211
3364
|
for (const error of result.payload.errors) {
|
|
2212
|
-
if (error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
3365
|
+
if (rawOptions.json && error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
2213
3366
|
writeLine(io.stderr, error.message);
|
|
2214
3367
|
}
|
|
2215
3368
|
}
|
|
@@ -2234,18 +3387,31 @@ export async function runCli(argv, options = {}) {
|
|
|
2234
3387
|
...createDefaultIo(),
|
|
2235
3388
|
...options.io,
|
|
2236
3389
|
};
|
|
3390
|
+
const reviewCommand = argv[0] === 'review' && ['inspect', 'prepare'].includes(argv[1] ?? '')
|
|
3391
|
+
? argv[1]
|
|
3392
|
+
: null;
|
|
3393
|
+
const jsonReviewCommand = reviewCommand !== null && argv.includes('--json');
|
|
2237
3394
|
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] ?? ''))
|
|
3395
|
+
&& ((argv[0] === 'catalog' && ['init', 'context', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
|
|
3396
|
+
|| (argv[0] === 'plugin' && ['build', 'test', 'validate', 'status', 'remove'].includes(argv[1] ?? ''))
|
|
3397
|
+
|| reviewCommand !== null)
|
|
2240
3398
|
? `${argv[0]}:${argv[1]}`
|
|
2241
3399
|
: null;
|
|
3400
|
+
const jsonCatalogDevCommand = argv.includes('--json')
|
|
3401
|
+
&& argv[0] === 'catalog'
|
|
3402
|
+
&& argv[1] === 'dev'
|
|
3403
|
+
&& ['activate', 'status', 'deactivate'].includes(argv[2] ?? '')
|
|
3404
|
+
? argv[2]
|
|
3405
|
+
: null;
|
|
3406
|
+
const jsonWriteRequest = jsonWriteCommandRequest(argv);
|
|
3407
|
+
const jsonConfigMutation = jsonConfigMutationRequest(argv);
|
|
2242
3408
|
try {
|
|
2243
3409
|
const authoringScriptByCommand = {
|
|
2244
3410
|
init: 'init-plugin.mjs',
|
|
2245
3411
|
'add-skill': 'add-skill.mjs',
|
|
3412
|
+
remove: 'remove-plugin.mjs',
|
|
2246
3413
|
validate: 'validate-plugin.mjs',
|
|
2247
3414
|
status: 'plugin-status.mjs',
|
|
2248
|
-
'check-versions': 'check-plugin-versions.mjs',
|
|
2249
3415
|
};
|
|
2250
3416
|
const authoringScript = argv[0] === 'plugin'
|
|
2251
3417
|
? authoringScriptByCommand[argv[1] ?? '']
|
|
@@ -2254,29 +3420,85 @@ export async function runCli(argv, options = {}) {
|
|
|
2254
3420
|
: undefined;
|
|
2255
3421
|
if (authoringScript && !argv.includes('--help') && !argv.includes('-h')) {
|
|
2256
3422
|
const authoringArgs = argv.slice(2);
|
|
3423
|
+
let authoringEnv = options.env ?? process.env;
|
|
2257
3424
|
if (argv[0] === 'plugin'
|
|
2258
|
-
&&
|
|
2259
|
-
|
|
2260
|
-
|
|
3425
|
+
&& !authoringArgs.some((token) => token === '--plugin-root' || token.startsWith('--plugin-root='))) {
|
|
3426
|
+
let explicitRoot;
|
|
3427
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3428
|
+
const token = authoringArgs[index];
|
|
3429
|
+
if (token.startsWith('--workspace-root='))
|
|
3430
|
+
explicitRoot = token.slice('--workspace-root='.length);
|
|
3431
|
+
if (token === '--workspace-root')
|
|
3432
|
+
explicitRoot = authoringArgs[index + 1];
|
|
3433
|
+
}
|
|
3434
|
+
const originalCwd = options.cwd ?? process.cwd();
|
|
3435
|
+
let discoveryCwd = originalCwd;
|
|
3436
|
+
if (argv[1] === 'validate') {
|
|
3437
|
+
const valueOptions = new Set(['--workspace-root', '--claude-skill-profile', '--version-base']);
|
|
3438
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3439
|
+
const token = authoringArgs[index];
|
|
3440
|
+
if (valueOptions.has(token)) {
|
|
3441
|
+
index += 1;
|
|
3442
|
+
continue;
|
|
3443
|
+
}
|
|
3444
|
+
if (!token.startsWith('-')) {
|
|
3445
|
+
discoveryCwd = path.resolve(originalCwd, token);
|
|
3446
|
+
authoringArgs[index] = discoveryCwd;
|
|
3447
|
+
break;
|
|
3448
|
+
}
|
|
3449
|
+
}
|
|
3450
|
+
}
|
|
3451
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
3452
|
+
cwd: discoveryCwd,
|
|
3453
|
+
...(explicitRoot === undefined ? {} : { explicitRoot: path.resolve(options.cwd ?? process.cwd(), explicitRoot) }),
|
|
3454
|
+
mode: 'existing',
|
|
3455
|
+
});
|
|
3456
|
+
authoringEnv = {
|
|
3457
|
+
...authoringEnv,
|
|
3458
|
+
AW_AUTHORING_WORKSPACE_ROOT: workspace.workspaceRoot,
|
|
3459
|
+
AW_AUTHORING_WORKSPACE_ROOT_RESOLVED_FROM: workspace.workspaceRootResolvedFrom,
|
|
3460
|
+
};
|
|
3461
|
+
if (explicitRoot === undefined)
|
|
3462
|
+
authoringArgs.push('--workspace-root', workspace.workspaceRoot);
|
|
2261
3463
|
}
|
|
2262
3464
|
return runAuthoringScript({
|
|
2263
3465
|
scriptName: authoringScript,
|
|
2264
3466
|
args: authoringArgs,
|
|
2265
3467
|
cwd: options.cwd ?? process.cwd(),
|
|
2266
|
-
env:
|
|
3468
|
+
env: authoringEnv,
|
|
2267
3469
|
io,
|
|
2268
3470
|
});
|
|
2269
3471
|
}
|
|
2270
|
-
if (
|
|
3472
|
+
if (!jsonConfigMutation
|
|
3473
|
+
&& argv.some((token) => token === '--subdir' || token.startsWith('--subdir='))
|
|
2271
3474
|
&& argv.includes('--no-subdir')) {
|
|
2272
3475
|
const message = 'option --subdir cannot be used with option --no-subdir';
|
|
2273
3476
|
if (argv.includes('--json') && argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update') {
|
|
2274
3477
|
writeJsonReceipt(io.stdout, {
|
|
2275
|
-
receiptSchemaVersion:
|
|
3478
|
+
receiptSchemaVersion: 6,
|
|
2276
3479
|
command: 'catalog:source:update',
|
|
2277
3480
|
ok: false,
|
|
2278
3481
|
changed: false,
|
|
2279
3482
|
sourceId: argv[3] ?? '',
|
|
3483
|
+
primaryChange: null,
|
|
3484
|
+
references: [],
|
|
3485
|
+
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
writeLine(io.stderr, `error: ${message}`);
|
|
3489
|
+
return 1;
|
|
3490
|
+
}
|
|
3491
|
+
if (argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update'
|
|
3492
|
+
&& argv.includes('--auto-check') && argv.includes('--no-auto-check')) {
|
|
3493
|
+
const message = 'option --auto-check cannot be used with option --no-auto-check';
|
|
3494
|
+
if (argv.includes('--json') || argv.includes('-j')) {
|
|
3495
|
+
writeJsonReceipt(io.stdout, {
|
|
3496
|
+
receiptSchemaVersion: 6,
|
|
3497
|
+
command: 'catalog:source:update',
|
|
3498
|
+
ok: false,
|
|
3499
|
+
changed: false,
|
|
3500
|
+
sourceId: argv[3] ?? '',
|
|
3501
|
+
primaryChange: null,
|
|
2280
3502
|
references: [],
|
|
2281
3503
|
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
2282
3504
|
});
|
|
@@ -2304,9 +3526,30 @@ export async function runCli(argv, options = {}) {
|
|
|
2304
3526
|
}
|
|
2305
3527
|
return await runActionWithContext(context, () => runConsoleController(context));
|
|
2306
3528
|
}
|
|
3529
|
+
let catalogPublicationActionStarted = false;
|
|
3530
|
+
let configMutationActionStarted = false;
|
|
3531
|
+
const programIo = jsonCatalogDevCommand || jsonWriteRequest || jsonReviewCommand
|
|
3532
|
+
? { ...io, stderr: () => undefined }
|
|
3533
|
+
: jsonConfigMutation
|
|
3534
|
+
? {
|
|
3535
|
+
...io,
|
|
3536
|
+
stderr: (text) => {
|
|
3537
|
+
if (configMutationActionStarted)
|
|
3538
|
+
io.stderr(text);
|
|
3539
|
+
},
|
|
3540
|
+
}
|
|
3541
|
+
: jsonAuthoringCommand === 'catalog:publish'
|
|
3542
|
+
? {
|
|
3543
|
+
...io,
|
|
3544
|
+
stderr: (text) => {
|
|
3545
|
+
if (catalogPublicationActionStarted)
|
|
3546
|
+
io.stderr(text);
|
|
3547
|
+
},
|
|
3548
|
+
}
|
|
3549
|
+
: io;
|
|
2307
3550
|
const program = buildProgram({
|
|
2308
3551
|
...options,
|
|
2309
|
-
io,
|
|
3552
|
+
io: programIo,
|
|
2310
3553
|
diagnostics: {
|
|
2311
3554
|
...options.diagnostics,
|
|
2312
3555
|
metadata: {
|
|
@@ -2315,16 +3558,139 @@ export async function runCli(argv, options = {}) {
|
|
|
2315
3558
|
},
|
|
2316
3559
|
},
|
|
2317
3560
|
});
|
|
3561
|
+
if (jsonAuthoringCommand === 'catalog:publish') {
|
|
3562
|
+
program.hook('preAction', () => {
|
|
3563
|
+
catalogPublicationActionStarted = true;
|
|
3564
|
+
});
|
|
3565
|
+
}
|
|
3566
|
+
if (jsonConfigMutation) {
|
|
3567
|
+
program.hook('preAction', () => {
|
|
3568
|
+
configMutationActionStarted = true;
|
|
3569
|
+
});
|
|
3570
|
+
}
|
|
2318
3571
|
await program.parseAsync(['node', 'aw', ...argv]);
|
|
2319
3572
|
return program.__awCommandExitState?.exitCode ?? 0;
|
|
2320
3573
|
}
|
|
2321
3574
|
catch (error) {
|
|
2322
|
-
if (
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
3575
|
+
if (reviewCommand && error instanceof CommanderError) {
|
|
3576
|
+
if (error.exitCode === 0)
|
|
3577
|
+
return 0;
|
|
3578
|
+
if (jsonReviewCommand) {
|
|
3579
|
+
const receipt = reviewCommand === 'inspect'
|
|
3580
|
+
? createReviewInspectionFailure(new Error(error.message), requestedReviewView(argv), 'invalidArguments')
|
|
3581
|
+
: createReviewPreparationFailure(error.message);
|
|
3582
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
3583
|
+
}
|
|
3584
|
+
return 2;
|
|
3585
|
+
}
|
|
3586
|
+
if (jsonCatalogDevCommand) {
|
|
3587
|
+
const workspaceRootIndex = argv.findIndex((token) => token === '--workspace-root');
|
|
3588
|
+
const workspaceRootOption = argv.find((token) => token.startsWith('--workspace-root='));
|
|
3589
|
+
const workspaceRoot = workspaceRootOption?.slice('--workspace-root='.length)
|
|
3590
|
+
?? (workspaceRootIndex >= 0 ? argv[workspaceRootIndex + 1] : undefined);
|
|
3591
|
+
const sourceIdIndex = argv.findIndex((token) => token === '--source-id');
|
|
3592
|
+
const sourceIdOption = argv.find((token) => token.startsWith('--source-id='));
|
|
3593
|
+
const sourceId = sourceIdOption?.slice('--source-id='.length)
|
|
3594
|
+
?? (sourceIdIndex >= 0 ? argv[sourceIdIndex + 1] : undefined);
|
|
3595
|
+
const failure = error instanceof CommanderError
|
|
3596
|
+
? { code: 'invalidArguments', message: error.message }
|
|
3597
|
+
: catalogDevSourceError(error);
|
|
3598
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
3599
|
+
command: jsonCatalogDevCommand,
|
|
3600
|
+
cwd: options.cwd ?? process.cwd(),
|
|
3601
|
+
workspaceRoot,
|
|
3602
|
+
sourceId,
|
|
3603
|
+
...failure,
|
|
3604
|
+
}));
|
|
3605
|
+
return 1;
|
|
3606
|
+
}
|
|
3607
|
+
if (jsonWriteRequest) {
|
|
3608
|
+
writeCommandFailureReceipt(io.stdout, jsonWriteRequest, error);
|
|
3609
|
+
return 1;
|
|
3610
|
+
}
|
|
3611
|
+
if (jsonConfigMutation) {
|
|
3612
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
3613
|
+
return 0;
|
|
3614
|
+
const failure = configMutationFailure(error, options.env ?? process.env, options.cwd ?? process.cwd());
|
|
3615
|
+
writeConfigMutationFailureReceipt(io.stdout, error instanceof CommanderError
|
|
3616
|
+
? { command: jsonConfigMutation.command }
|
|
3617
|
+
: jsonConfigMutation, failure);
|
|
3618
|
+
writeLine(io.stderr, failure.message);
|
|
3619
|
+
return 1;
|
|
3620
|
+
}
|
|
3621
|
+
if (jsonAuthoringCommand === 'catalog:publish' && error instanceof CommanderError) {
|
|
3622
|
+
const failure = catalogPublicationFailure({
|
|
3623
|
+
error: new CatalogPublicationInspectionError('invalidArguments', error.message),
|
|
3624
|
+
env: options.env,
|
|
3625
|
+
sensitiveRoots: [options.cwd ?? process.cwd()],
|
|
2327
3626
|
});
|
|
3627
|
+
writeJsonReceipt(io.stdout, failure);
|
|
3628
|
+
writeLine(io.stderr, failure.message);
|
|
3629
|
+
return 1;
|
|
3630
|
+
}
|
|
3631
|
+
if (jsonAuthoringCommand && !(error instanceof CommanderError)) {
|
|
3632
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3633
|
+
if (jsonAuthoringCommand === 'plugin:validate') {
|
|
3634
|
+
writeJsonReceipt(io.stdout, {
|
|
3635
|
+
ok: false,
|
|
3636
|
+
profile: 'unknown',
|
|
3637
|
+
warnings: [],
|
|
3638
|
+
errors: [message],
|
|
3639
|
+
});
|
|
3640
|
+
}
|
|
3641
|
+
else if (jsonAuthoringCommand === 'plugin:status') {
|
|
3642
|
+
writeJsonReceipt(io.stdout, {
|
|
3643
|
+
schemaVersion: 3,
|
|
3644
|
+
policy: 'development',
|
|
3645
|
+
ok: false,
|
|
3646
|
+
base: null,
|
|
3647
|
+
requestedBase: null,
|
|
3648
|
+
baseCommit: null,
|
|
3649
|
+
checkedPlugins: 0,
|
|
3650
|
+
checks: [],
|
|
3651
|
+
workspaceRoot: null,
|
|
3652
|
+
workspaceRootResolvedFrom: null,
|
|
3653
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3654
|
+
});
|
|
3655
|
+
}
|
|
3656
|
+
else if (jsonAuthoringCommand === 'plugin:remove') {
|
|
3657
|
+
writeJsonReceipt(io.stdout, {
|
|
3658
|
+
schemaVersion: 1,
|
|
3659
|
+
command: 'plugin:remove',
|
|
3660
|
+
ok: false,
|
|
3661
|
+
workspaceRoot: null,
|
|
3662
|
+
workspaceRootResolvedFrom: null,
|
|
3663
|
+
baseCommit: null,
|
|
3664
|
+
plugin: null,
|
|
3665
|
+
removed: false,
|
|
3666
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3667
|
+
});
|
|
3668
|
+
}
|
|
3669
|
+
else if (jsonAuthoringCommand === 'review:inspect') {
|
|
3670
|
+
writeJsonReceipt(io.stdout, createReviewInspectionFailure(error, requestedReviewView(argv)));
|
|
3671
|
+
}
|
|
3672
|
+
else if (jsonAuthoringCommand === 'review:prepare') {
|
|
3673
|
+
writeJsonReceipt(io.stdout, createReviewPreparationFailure(message, 'reviewPreparationFailed'));
|
|
3674
|
+
}
|
|
3675
|
+
else {
|
|
3676
|
+
writeJsonReceipt(io.stdout, {
|
|
3677
|
+
command: jsonAuthoringCommand,
|
|
3678
|
+
ok: false,
|
|
3679
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3680
|
+
});
|
|
3681
|
+
}
|
|
3682
|
+
return 1;
|
|
3683
|
+
}
|
|
3684
|
+
if (jsonAuthoringCommand && error instanceof CommanderError) {
|
|
3685
|
+
writeJsonReceipt(io.stdout, jsonAuthoringCommand === 'review:inspect'
|
|
3686
|
+
? createReviewInspectionFailure(new Error(error.message), requestedReviewView(argv), 'invalidArguments')
|
|
3687
|
+
: jsonAuthoringCommand === 'review:prepare'
|
|
3688
|
+
? createReviewPreparationFailure(error.message)
|
|
3689
|
+
: {
|
|
3690
|
+
command: jsonAuthoringCommand,
|
|
3691
|
+
ok: false,
|
|
3692
|
+
errors: [{ code: 'invalidArguments', message: error.message }],
|
|
3693
|
+
});
|
|
2328
3694
|
}
|
|
2329
3695
|
return handleCliError(error, io.stderr);
|
|
2330
3696
|
}
|