@lesliechan721/aw 0.1.0-beta.5 → 0.1.0-beta.51
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-root.mjs +4 -4
- package/dist/authoring/scripts/lib/plugin-root.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.d.mts +1 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +229 -8
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -92
- package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -124
- 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 +3 -2
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +346 -1131
- 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 -0
- package/dist/scripts/bundle-plugins.js +20 -5
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +7 -9
- package/dist/scripts/plugin-staging.js +18 -29
- 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 +47 -76
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/scripts/test-workers.d.mts +24 -0
- package/dist/scripts/test-workers.mjs +59 -0
- package/dist/scripts/test-workers.mjs.map +1 -0
- 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 +17 -1
- package/dist/src/authoring/workspace-commands.js +21 -4
- 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 +71 -30
- package/dist/src/commands/catalog-publication-inspection.js +475 -63
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- 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 +73 -15
- package/dist/src/commands/catalog-publish.js +701 -212
- 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 +18 -22
- package/dist/src/commands/catalog-status.js +81 -115
- package/dist/src/commands/catalog-status.js.map +1 -1
- 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.js +23 -3
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +77 -31
- package/dist/src/commands/rebuild-command.js +4862 -729
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +131 -21
- package/dist/src/commands/rebuild-integration.js +2866 -1339
- 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 +60 -0
- package/dist/src/commands/review-inspection.js +422 -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 +68 -0
- package/dist/src/eval/manifest-v1.js +353 -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 +236 -109
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +10 -4
- package/dist/src/index.js +1752 -608
- 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 +74 -20
- 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 +110 -3
- package/dist/src/tui/components.js +183 -36
- 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 +8941 -1872
- 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 +10 -2
- package/dist/src/tui/controller-runtime.js +3211 -388
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +615 -45
- package/dist/src/tui/controller.js +3558 -768
- 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 +3 -3
- package/dist/src/tui/diagnostics.js +14 -2
- package/dist/src/tui/diagnostics.js.map +1 -1
- 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 +6 -1
- package/dist/src/tui/index.js +5 -1
- 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 +223 -31
- package/dist/src/tui/model.js +1510 -397
- 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 +197 -10
- package/dist/src/tui/router.js +338 -50
- 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 +12 -0
- package/dist/src/tui/theme.js +12 -0
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/viewport.d.ts +1 -0
- package/dist/src/tui/viewport.js +23 -0
- package/dist/src/tui/viewport.js.map +1 -1
- 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 +57 -20
- 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 +3 -0
- package/dist/src/utils/catalog-runtime-projection.js +5 -40
- 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 +747 -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 +35 -5
- 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 +177 -145
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +18 -1
- package/dist/src/utils/local-marketplace.js +354 -84
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +1 -3
- package/dist/src/utils/manifest.js +1 -3
- 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 +400 -58
- 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 +1116 -968
- 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 +484 -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/state-paths.js +7 -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 +7 -0
- package/dist/src/utils/windows-claude-shim.js +10 -0
- package/dist/src/utils/windows-claude-shim.js.map +1 -0
- package/dist/src/utils/windows-npm-shim.d.ts +14 -0
- package/dist/src/utils/windows-npm-shim.js +140 -0
- package/dist/src/utils/windows-npm-shim.js.map +1 -0
- package/dist/vitest.config.js +92 -10
- package/dist/vitest.config.js.map +1 -1
- package/package.json +27 -18
- package/dist/authoring/scripts/check-plugin-versions.d.mts +0 -2
- 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/review-publication.d.ts +0 -99
- package/dist/src/commands/review-publication.js +0 -904
- package/dist/src/commands/review-publication.js.map +0 -1
- package/dist/src/commands/status-v4.d.ts +0 -123
- package/dist/src/commands/status-v4.js +0 -905
- 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 -62
- package/dist/src/utils/catalog-source-cache.js +0 -296
- 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-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/index.js
CHANGED
|
@@ -3,39 +3,48 @@ 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
|
-
import {
|
|
34
|
-
import {
|
|
38
|
+
import { createReviewInspectionFailure, getReviewInspectionExitCode, inspectReviewTarget, } from './commands/review-inspection.js';
|
|
39
|
+
import { prepareReviewTarget, } from './commands/review-preparation.js';
|
|
35
40
|
import { runCatalogBuildCommand, runCatalogInitCommand, runCatalogValidateCommand, runCatalogVersionCommand, runPluginBuildCommand, runPluginTestCommand, } from './authoring/workspace-commands.js';
|
|
36
|
-
import {
|
|
41
|
+
import { runCatalogPublishApplyCommand, runCatalogPublishPlanCommand, } from './commands/catalog-publish.js';
|
|
42
|
+
import { catalogPublicationFailure, CatalogPublicationInspectionError, } from './commands/catalog-publication-inspection.js';
|
|
37
43
|
import { getCatalogStatus, renderCatalogStatus } from './commands/catalog-status.js';
|
|
44
|
+
import { activateCatalogDevSource, catalogDevSourceError, createCatalogDevFailureReceipt, deactivateCatalogDevSource, getCatalogDevSourceStatus, } from './commands/catalog-dev-source.js';
|
|
38
45
|
import { getPluginCapabilitiesResult, parsePluginCapabilitySurface, renderPluginCapabilities, } from './commands/plugin-capabilities.js';
|
|
46
|
+
import { AwCapabilityUnsupportedError, checkCurrentAw, describeCurrentAw, inspectPluginRequirements, } from './commands/aw-capabilities.js';
|
|
47
|
+
import { prepareSkillEval } from './commands/skill-eval.js';
|
|
39
48
|
function createDefaultIo() {
|
|
40
49
|
return {
|
|
41
50
|
stdout: (text) => process.stdout.write(text),
|
|
@@ -45,6 +54,50 @@ function createDefaultIo() {
|
|
|
45
54
|
function writeLine(write, line) {
|
|
46
55
|
write(`${line}\n`);
|
|
47
56
|
}
|
|
57
|
+
function strictValueOption(flags, description, choices) {
|
|
58
|
+
let seen = false;
|
|
59
|
+
const option = new Option(flags, description);
|
|
60
|
+
return option.argParser((value) => {
|
|
61
|
+
if (seen)
|
|
62
|
+
throw new InvalidArgumentError(`${option.long} can be specified only once.`);
|
|
63
|
+
if (choices && !choices.includes(value)) {
|
|
64
|
+
throw new InvalidArgumentError(`${option.long} must be one of: ${choices.join(', ')}.`);
|
|
65
|
+
}
|
|
66
|
+
seen = true;
|
|
67
|
+
return value;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function collectUniqueOption(value, previous) {
|
|
71
|
+
return previous.includes(value) ? previous : [...previous, value];
|
|
72
|
+
}
|
|
73
|
+
function renderReviewSkills(write, skills, issues) {
|
|
74
|
+
for (const skill of skills) {
|
|
75
|
+
writeLine(write, `${skill.skill}\t${skill.profile.platform}/${skill.profile.scope}\t${skill.state}\t${skill.finalPath ?? '-'}`);
|
|
76
|
+
}
|
|
77
|
+
for (const issue of issues)
|
|
78
|
+
writeLine(write, `${issue.code}: ${issue.message}`);
|
|
79
|
+
}
|
|
80
|
+
function renderReviewInspection(write, receipt) {
|
|
81
|
+
writeLine(write, `Review inspection (${receipt.view}): ${receipt.ok ? 'ok' : 'failed'}`);
|
|
82
|
+
renderReviewSkills(write, receipt.skills, receipt.issues);
|
|
83
|
+
}
|
|
84
|
+
function renderReviewPreparation(write, receipt) {
|
|
85
|
+
writeLine(write, `Review preparation: ${receipt.ok ? 'complete' : 'failed'}`);
|
|
86
|
+
if (receipt.sourceBindingPath)
|
|
87
|
+
writeLine(write, `Source binding: ${receipt.sourceBindingPath}`);
|
|
88
|
+
renderReviewSkills(write, receipt.skills, receipt.issues);
|
|
89
|
+
}
|
|
90
|
+
function createReviewPreparationFailure(message, code = 'invalidArguments') {
|
|
91
|
+
return {
|
|
92
|
+
schemaVersion: 1,
|
|
93
|
+
command: 'review:prepare',
|
|
94
|
+
ok: false,
|
|
95
|
+
target: null,
|
|
96
|
+
sourceBindingPath: null,
|
|
97
|
+
skills: [],
|
|
98
|
+
issues: [{ code, path: null, message }],
|
|
99
|
+
};
|
|
100
|
+
}
|
|
48
101
|
function writeWarnings(write, warnings, options = {}) {
|
|
49
102
|
for (const warning of formatWarnings(warnings, options)) {
|
|
50
103
|
writeLine(write, warning);
|
|
@@ -56,10 +109,266 @@ function resolveCliVersion() {
|
|
|
56
109
|
return assertStrictSemVer(packageJson.version, 'packages/cli/package.json version');
|
|
57
110
|
}
|
|
58
111
|
function resolveCommandReceiptExitCode(result) {
|
|
59
|
-
|
|
60
|
-
|
|
112
|
+
return result.overallState === 'succeeded' ? 0 : 1;
|
|
113
|
+
}
|
|
114
|
+
class WriteCommandRequestError extends Error {
|
|
115
|
+
code = 'invalidArguments';
|
|
116
|
+
}
|
|
117
|
+
function normalizeWriteRequest(normalize) {
|
|
118
|
+
try {
|
|
119
|
+
return normalize();
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new WriteCommandRequestError(error instanceof Error ? error.message : String(error));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function writeCommandFailure(error) {
|
|
126
|
+
const message = redactString(error instanceof Error ? error.message : String(error));
|
|
127
|
+
if (error instanceof CommanderError || error instanceof WriteCommandRequestError) {
|
|
128
|
+
return { code: 'invalidArguments', message };
|
|
129
|
+
}
|
|
130
|
+
const explicitCode = error?.code;
|
|
131
|
+
if (typeof explicitCode === 'string' && /^[A-Za-z][A-Za-z0-9]*$/u.test(explicitCode)) {
|
|
132
|
+
return { code: explicitCode, message };
|
|
133
|
+
}
|
|
134
|
+
const separator = message.indexOf(':');
|
|
135
|
+
const prefix = separator > 0 ? message.slice(0, separator) : '';
|
|
136
|
+
return {
|
|
137
|
+
code: /^[A-Za-z][A-Za-z0-9]*$/u.test(prefix) ? prefix : 'writeCommandFailed',
|
|
138
|
+
message,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function preparseWriteReceiptRequest(argv) {
|
|
142
|
+
const request = { json: false, plugins: [] };
|
|
143
|
+
let positionalOnly = false;
|
|
144
|
+
for (let index = 1; index < argv.length; index += 1) {
|
|
145
|
+
const token = argv[index];
|
|
146
|
+
if (positionalOnly) {
|
|
147
|
+
request.plugins.push(token);
|
|
148
|
+
continue;
|
|
149
|
+
}
|
|
150
|
+
if (token === '--') {
|
|
151
|
+
positionalOnly = true;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (token === '--json') {
|
|
155
|
+
request.json = true;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (token === '--platform' || token === '--scope') {
|
|
159
|
+
const value = argv[index + 1];
|
|
160
|
+
if (token === '--platform')
|
|
161
|
+
request.platform = value;
|
|
162
|
+
else
|
|
163
|
+
request.scope = value;
|
|
164
|
+
index += 1;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (token.startsWith('--platform=')) {
|
|
168
|
+
request.platform = token.slice('--platform='.length);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (token.startsWith('--scope=')) {
|
|
172
|
+
request.scope = token.slice('--scope='.length);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
if (token === '--dependency-scope' || token === '--script-timeout' || token === '--log-file') {
|
|
176
|
+
index += 1;
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (token.startsWith('--'))
|
|
180
|
+
continue;
|
|
181
|
+
if (token.startsWith('-') && token !== '-') {
|
|
182
|
+
const shortOptions = token.slice(1);
|
|
183
|
+
for (let offset = 0; offset < shortOptions.length; offset += 1) {
|
|
184
|
+
const option = shortOptions[offset];
|
|
185
|
+
if (option === 'j') {
|
|
186
|
+
request.json = true;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
if (option === 'p' || option === 's') {
|
|
190
|
+
const value = shortOptions.slice(offset + 1) || argv[index + 1];
|
|
191
|
+
if (option === 'p')
|
|
192
|
+
request.platform = value;
|
|
193
|
+
else
|
|
194
|
+
request.scope = value;
|
|
195
|
+
if (shortOptions.length === offset + 1)
|
|
196
|
+
index += 1;
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
request.plugins.push(token);
|
|
203
|
+
}
|
|
204
|
+
return request;
|
|
205
|
+
}
|
|
206
|
+
function jsonWriteCommandRequest(argv) {
|
|
207
|
+
const command = argv[0];
|
|
208
|
+
if (!['install', 'reinstall', 'uninstall', 'cleanup', 'sync'].includes(command ?? '')) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
const request = preparseWriteReceiptRequest(argv);
|
|
212
|
+
if (!request.json)
|
|
213
|
+
return null;
|
|
214
|
+
const rawPlatform = request.platform;
|
|
215
|
+
const platform = rawPlatform === 'codex' || rawPlatform === 'claude' || rawPlatform === 'both'
|
|
216
|
+
? rawPlatform
|
|
217
|
+
: 'codex';
|
|
218
|
+
return {
|
|
219
|
+
command: command,
|
|
220
|
+
plugins: request.plugins,
|
|
221
|
+
platform,
|
|
222
|
+
scope: request.scope === 'project' ? 'project' : 'user',
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function writeCommandFailureReceipt(write, request, error) {
|
|
226
|
+
const platforms = request.platform === 'both'
|
|
227
|
+
? ['codex', 'claude']
|
|
228
|
+
: [request.platform];
|
|
229
|
+
writeJsonReceipt(write, buildRebuildReceiptJson(request.command, {
|
|
230
|
+
platforms,
|
|
231
|
+
plugins: request.plugins,
|
|
232
|
+
warnings: [],
|
|
233
|
+
overallState: 'failed',
|
|
234
|
+
errors: [writeCommandFailure(error)],
|
|
235
|
+
receiptTargets: request.plugins.flatMap((selector) => platforms.map((platform) => {
|
|
236
|
+
let pluginName = selector;
|
|
237
|
+
let sourceId;
|
|
238
|
+
try {
|
|
239
|
+
const parsed = parsePluginId(selector);
|
|
240
|
+
pluginName = parsed.pluginName;
|
|
241
|
+
sourceId = parsed.sourceId;
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
// Keep the raw selector in the failed receipt.
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
pluginName,
|
|
248
|
+
pluginId: selector,
|
|
249
|
+
...(sourceId ? { sourceId } : {}),
|
|
250
|
+
platform,
|
|
251
|
+
scope: request.scope,
|
|
252
|
+
};
|
|
253
|
+
})),
|
|
254
|
+
}));
|
|
255
|
+
}
|
|
256
|
+
function scanConfigMutationShortOptions(token, command) {
|
|
257
|
+
if (!/^-[^-].*/u.test(token))
|
|
258
|
+
return { json: false, consumesNextValue: false };
|
|
259
|
+
let json = false;
|
|
260
|
+
for (let index = 1; index < token.length; index += 1) {
|
|
261
|
+
const option = token[index];
|
|
262
|
+
if (option === 's') {
|
|
263
|
+
return {
|
|
264
|
+
json,
|
|
265
|
+
consumesNextValue: index === token.length - 1,
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
if (option === 'j') {
|
|
269
|
+
json = true;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
if (option === 'v' || option === 'D' || (option === 'y' && command === 'config:reset')) {
|
|
273
|
+
continue;
|
|
274
|
+
}
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
return { json, consumesNextValue: false };
|
|
278
|
+
}
|
|
279
|
+
function jsonConfigMutationRequest(argv) {
|
|
280
|
+
if (argv[0] !== 'config' || !['set', 'unset', 'reset'].includes(argv[1] ?? '')) {
|
|
281
|
+
return null;
|
|
282
|
+
}
|
|
283
|
+
const command = `config:${argv[1]}`;
|
|
284
|
+
let json = false;
|
|
285
|
+
let plugin;
|
|
286
|
+
const valueOptions = new Set(['--scope', '--value-json', '--preset', '--log-file']);
|
|
287
|
+
for (let index = 2; index < argv.length; index += 1) {
|
|
288
|
+
const token = argv[index];
|
|
289
|
+
if (token === '--')
|
|
290
|
+
break;
|
|
291
|
+
if (valueOptions.has(token)) {
|
|
292
|
+
index += 1;
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
if (token === '--json') {
|
|
296
|
+
json = true;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const shortOptions = scanConfigMutationShortOptions(token, command);
|
|
300
|
+
if (shortOptions.json)
|
|
301
|
+
json = true;
|
|
302
|
+
if (shortOptions.consumesNextValue)
|
|
303
|
+
index += 1;
|
|
304
|
+
if (token.startsWith('-'))
|
|
305
|
+
continue;
|
|
306
|
+
plugin ??= token;
|
|
307
|
+
}
|
|
308
|
+
if (!json)
|
|
309
|
+
return null;
|
|
310
|
+
return {
|
|
311
|
+
command,
|
|
312
|
+
...(plugin ? { plugin } : {}),
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function configMutationFailure(error, env, cwd) {
|
|
316
|
+
const configWrite = configWriteStateForError(error);
|
|
317
|
+
if (error instanceof CommanderError) {
|
|
318
|
+
return {
|
|
319
|
+
code: 'invalidArguments',
|
|
320
|
+
message: 'error: invalid config mutation arguments',
|
|
321
|
+
configWrite,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
const message = catalogPublicationFailure({
|
|
325
|
+
error,
|
|
326
|
+
env,
|
|
327
|
+
sensitiveRoots: [cwd],
|
|
328
|
+
}).message;
|
|
329
|
+
if (message.includes('Usage:'))
|
|
330
|
+
return { code: 'invalidArguments', message, configWrite };
|
|
331
|
+
const generationCode = catalogGenerationErrorCode(error);
|
|
332
|
+
if (generationCode === 'catalogGenerationUnavailable'
|
|
333
|
+
|| generationCode === 'catalogGenerationSourceMissing') {
|
|
334
|
+
return { code: 'catalogSourceUnavailable', message, configWrite };
|
|
335
|
+
}
|
|
336
|
+
if (generationCode !== 'catalogGenerationFailed')
|
|
337
|
+
return { code: generationCode, message, configWrite };
|
|
338
|
+
const explicitCode = error?.code;
|
|
339
|
+
if (typeof explicitCode === 'string' && /^[A-Za-z][A-Za-z0-9]*$/u.test(explicitCode)) {
|
|
340
|
+
return { code: explicitCode, message, configWrite };
|
|
341
|
+
}
|
|
342
|
+
if (message.includes('legacyStateUnsupported'))
|
|
343
|
+
return { code: 'legacyStateUnsupported', message, configWrite };
|
|
344
|
+
if (message.includes('sourceChanged'))
|
|
345
|
+
return { code: 'sourceChanged', message, configWrite };
|
|
346
|
+
if (message.includes('sourceMissing'))
|
|
347
|
+
return { code: 'sourceMissing', message, configWrite };
|
|
348
|
+
if (message.startsWith('Cannot resolve required catalog sources:')) {
|
|
349
|
+
return { code: 'catalogSourceUnavailable', message, configWrite };
|
|
350
|
+
}
|
|
351
|
+
const prefix = message.match(/^([A-Za-z][A-Za-z0-9]*):/u)?.[1];
|
|
352
|
+
return { code: prefix ?? 'configMutationFailed', message, configWrite };
|
|
353
|
+
}
|
|
354
|
+
function writeConfigMutationFailureReceipt(write, request, failure) {
|
|
355
|
+
let plugin;
|
|
356
|
+
try {
|
|
357
|
+
if (request.plugin) {
|
|
358
|
+
parsePluginId(request.plugin);
|
|
359
|
+
plugin = request.plugin;
|
|
360
|
+
}
|
|
61
361
|
}
|
|
62
|
-
|
|
362
|
+
catch {
|
|
363
|
+
// Do not echo an invalid selector from raw argv in an early failure receipt.
|
|
364
|
+
}
|
|
365
|
+
writeJsonReceipt(write, buildConfigMutationReceipt(request.command, {
|
|
366
|
+
ok: false,
|
|
367
|
+
overallState: 'failed',
|
|
368
|
+
configWrite: failure.configWrite,
|
|
369
|
+
...(plugin ? { plugin } : {}),
|
|
370
|
+
errors: [failure],
|
|
371
|
+
}));
|
|
63
372
|
}
|
|
64
373
|
async function runAuthoringScript(options) {
|
|
65
374
|
const scriptPath = path.join(resolveCliPackageRoot(), 'dist', 'authoring', 'scripts', options.scriptName);
|
|
@@ -102,47 +411,55 @@ function optionTokens(flag, value) {
|
|
|
102
411
|
function writeCommandUsage(command) {
|
|
103
412
|
const cardinality = command === 'reinstall' || command === 'cleanup' ? '<plugin>' : '<plugin...>';
|
|
104
413
|
const scope = command === 'cleanup' ? ' --scope <project|user>' : ' [--scope <project|user>]';
|
|
105
|
-
const all = command === 'upgrade' ? ' 或 aw upgrade --all --platform both --scope user' : '';
|
|
106
414
|
return [
|
|
107
415
|
`${command} 命令缺少必要参数。`,
|
|
108
416
|
`Usage: aw ${command} ${cardinality} --platform <codex|claude|both>${scope}`,
|
|
109
|
-
`Example: aw ${command} example-plugin --platform codex --scope user
|
|
417
|
+
`Example: aw ${command} example-plugin --platform codex --scope user`,
|
|
110
418
|
].join('\n');
|
|
111
419
|
}
|
|
112
420
|
function configCommandUsage(command) {
|
|
113
421
|
const argumentsByCommand = {
|
|
114
422
|
list: '<plugin>',
|
|
115
423
|
get: '<plugin> [key]',
|
|
116
|
-
set: '<plugin> <
|
|
424
|
+
set: '<plugin> <field> --scope <project|user> (--value-json <json> | --value-stdin | --preset <id>)',
|
|
117
425
|
unset: '<plugin> <key>',
|
|
118
426
|
reset: '<plugin> --scope <project|user> --yes',
|
|
119
427
|
};
|
|
120
428
|
return [
|
|
121
429
|
`config ${command} 命令缺少必要参数。`,
|
|
122
430
|
`Usage: aw config ${command} ${argumentsByCommand[command]}`,
|
|
123
|
-
`Example: aw config ${command} example-plugin${command === 'set' ? '
|
|
431
|
+
`Example: aw config ${command} example-plugin${command === 'set' ? ' mode --scope user --value-json \'"safe"\'' : command === 'unset' ? ' key' : command === 'reset' ? ' --scope user --yes' : ''}`,
|
|
124
432
|
].join('\n');
|
|
125
433
|
}
|
|
126
|
-
function
|
|
127
|
-
|
|
128
|
-
|
|
434
|
+
async function readUtf8Stdin(stdin) {
|
|
435
|
+
const chunks = [];
|
|
436
|
+
for await (const chunk of stdin) {
|
|
437
|
+
chunks.push(typeof chunk === 'string' ? Buffer.from(chunk, 'utf8') : Buffer.from(chunk));
|
|
129
438
|
}
|
|
439
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
130
440
|
}
|
|
131
441
|
function equivalentWriteCommand(command, selection, rawOptions) {
|
|
132
442
|
return shellCommand(buildEquivalentWriteCommandTokens(command, selection, rawOptions));
|
|
133
443
|
}
|
|
134
444
|
export function buildEquivalentWriteCommandTokens(command, selection, rawOptions) {
|
|
135
|
-
const all = command === 'upgrade' && rawOptions.all === true;
|
|
136
445
|
return [
|
|
137
446
|
'aw',
|
|
138
447
|
command,
|
|
139
|
-
...(all ? ['--all'] : []),
|
|
140
448
|
'--platform',
|
|
141
449
|
selection.platform ?? 'both',
|
|
142
450
|
'--scope',
|
|
143
451
|
selection.scope ?? 'user',
|
|
144
|
-
...(
|
|
145
|
-
|
|
452
|
+
...(rawOptions.allowManagedCodexInstall === true
|
|
453
|
+
? ['--allow-managed-codex-install']
|
|
454
|
+
: []),
|
|
455
|
+
...(command === 'cleanup' ? ['--yes'] : []),
|
|
456
|
+
...(command === 'install'
|
|
457
|
+
? (rawOptions.dependencyScope ?? []).flatMap((value) => ['--dependency-scope', value])
|
|
458
|
+
: []),
|
|
459
|
+
...((command === 'install' || command === 'reinstall')
|
|
460
|
+
? optionTokens('--script-timeout', rawOptions.scriptTimeout)
|
|
461
|
+
: []),
|
|
462
|
+
...(selection.plugins.length > 0 ? ['--', ...selection.plugins] : []),
|
|
146
463
|
];
|
|
147
464
|
}
|
|
148
465
|
function equivalentConfigCommand(options) {
|
|
@@ -154,39 +471,14 @@ function equivalentConfigCommandProjection(resolve) {
|
|
|
154
471
|
equivalentCommandTokens: (selection) => buildEquivalentConfigCommandTokens(resolve(selection)),
|
|
155
472
|
};
|
|
156
473
|
}
|
|
157
|
-
function configSetEquivalentOptions(selection, candidates, rawOptions) {
|
|
158
|
-
const field = candidates.find((entry) => entry.pluginName === selection.plugins[0])
|
|
159
|
-
?.configSchema?.[selection.key ?? ''];
|
|
160
|
-
const placeholder = configFieldPlaceholder(field);
|
|
161
|
-
return {
|
|
162
|
-
command: 'set',
|
|
163
|
-
plugin: selection.plugins[0],
|
|
164
|
-
key: selection.key,
|
|
165
|
-
value: placeholder
|
|
166
|
-
? rawOptions.valueJson ? JSON.stringify(placeholder) : placeholder
|
|
167
|
-
: formatConfigCommandValue(selection.value, rawOptions.valueJson === true),
|
|
168
|
-
scope: selection.scope ?? 'user',
|
|
169
|
-
projectLayer: selection.projectLayer,
|
|
170
|
-
valueJson: rawOptions.valueJson,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
function configFieldPlaceholder(field) {
|
|
174
|
-
if (field?.sensitive)
|
|
175
|
-
return '<sensitive-value>';
|
|
176
|
-
if (field?.type === 'file')
|
|
177
|
-
return '<file-path>';
|
|
178
|
-
if (field?.type === 'directory')
|
|
179
|
-
return '<directory-path>';
|
|
180
|
-
return undefined;
|
|
181
|
-
}
|
|
182
474
|
export function buildEquivalentConfigCommandTokens(options) {
|
|
183
475
|
return [
|
|
184
476
|
'aw',
|
|
185
477
|
'config',
|
|
186
478
|
options.command,
|
|
187
479
|
...optionTokens('--scope', options.scope),
|
|
188
|
-
...(
|
|
189
|
-
...(
|
|
480
|
+
...optionTokens('--value-json', options.valueJson),
|
|
481
|
+
...optionTokens('--preset', options.preset),
|
|
190
482
|
...(options.confirmed ? ['--yes'] : []),
|
|
191
483
|
'--',
|
|
192
484
|
options.plugin,
|
|
@@ -209,7 +501,6 @@ async function loadWizardCandidates(context, rawOptions) {
|
|
|
209
501
|
cwd: context.cwd,
|
|
210
502
|
scope: rawOptions.scope,
|
|
211
503
|
platform: rawOptions.platform,
|
|
212
|
-
includeCatalogOnly: true,
|
|
213
504
|
}, context);
|
|
214
505
|
return toWizardCandidates(loaded.items);
|
|
215
506
|
}
|
|
@@ -237,7 +528,6 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
237
528
|
cwd: context.cwd,
|
|
238
529
|
env: context.env,
|
|
239
530
|
scope: location.scope,
|
|
240
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
241
531
|
});
|
|
242
532
|
for (const store of stores) {
|
|
243
533
|
const keys = Object.keys(store.values);
|
|
@@ -245,12 +535,11 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
245
535
|
continue;
|
|
246
536
|
const existing = storesByPlugin.get(store.pluginId) ?? {
|
|
247
537
|
sourceId: store.sourceId,
|
|
248
|
-
|
|
538
|
+
...(store.binding.kind === 'source'
|
|
539
|
+
? { sourceIdentity: store.binding.sourceIdentity }
|
|
540
|
+
: {}),
|
|
249
541
|
keys: new Set(),
|
|
250
542
|
};
|
|
251
|
-
if (existing.sourceIdentity !== store.sourceIdentity) {
|
|
252
|
-
throw new Error(`sourceChanged: ${store.pluginId} config stores have different source identities.`);
|
|
253
|
-
}
|
|
254
543
|
for (const key of keys)
|
|
255
544
|
existing.keys.add(key);
|
|
256
545
|
storesByPlugin.set(store.pluginId, existing);
|
|
@@ -262,26 +551,53 @@ async function loadStoredConfigWizardCandidates(context, locations, options = {}
|
|
|
262
551
|
pluginName: pluginId,
|
|
263
552
|
pluginId,
|
|
264
553
|
sourceId: store.sourceId,
|
|
265
|
-
sourceIdentity: store.sourceIdentity,
|
|
554
|
+
...(store.sourceIdentity ? { sourceIdentity: store.sourceIdentity } : {}),
|
|
266
555
|
targets: [],
|
|
267
556
|
configKeys: [...store.keys].sort((left, right) => left.localeCompare(right)),
|
|
268
557
|
}));
|
|
269
558
|
}
|
|
270
559
|
function configReadStoreLocations(rawOptions) {
|
|
271
|
-
if (rawOptions.local)
|
|
272
|
-
return [{ scope: 'project', projectLayer: 'local' }];
|
|
273
560
|
if (rawOptions.scope === 'user')
|
|
274
|
-
return [{ scope: 'user'
|
|
561
|
+
return [{ scope: 'user' }];
|
|
275
562
|
if (rawOptions.scope === 'project')
|
|
276
|
-
return [{ scope: 'project'
|
|
563
|
+
return [{ scope: 'project' }];
|
|
277
564
|
return [
|
|
278
|
-
{ scope: 'user'
|
|
279
|
-
{ scope: 'project'
|
|
280
|
-
{ scope: 'project', projectLayer: 'local' },
|
|
565
|
+
{ scope: 'user' },
|
|
566
|
+
{ scope: 'project' },
|
|
281
567
|
];
|
|
282
568
|
}
|
|
283
569
|
function overallResultState(value) {
|
|
284
|
-
return value.overallState;
|
|
570
|
+
return value.overallState === 'succeeded' ? 'succeeded' : 'failed';
|
|
571
|
+
}
|
|
572
|
+
async function resolveStoredConfigResetIdentity(options) {
|
|
573
|
+
const parsed = parsePluginId(options.selector);
|
|
574
|
+
if (parsed.sourceId) {
|
|
575
|
+
return {
|
|
576
|
+
pluginName: parsed.pluginName,
|
|
577
|
+
pluginId: options.selector,
|
|
578
|
+
sourceId: parsed.sourceId,
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
const matches = (await listNamespacedPluginConfigStores({
|
|
582
|
+
cwd: options.context.cwd,
|
|
583
|
+
env: options.context.env,
|
|
584
|
+
scope: options.scope,
|
|
585
|
+
})).filter((store) => store.pluginName === parsed.pluginName);
|
|
586
|
+
if (matches.length === 0) {
|
|
587
|
+
throw new Error(`configStoreMissing: ${options.selector} has no config in the selected store.`);
|
|
588
|
+
}
|
|
589
|
+
if (matches.length > 1) {
|
|
590
|
+
throw new Error(`configTargetAmbiguous: ${options.selector} exists in multiple source namespaces: ${matches.map((store) => store.pluginId).join(', ')}. Use a full pluginId.`);
|
|
591
|
+
}
|
|
592
|
+
const [match] = matches;
|
|
593
|
+
return {
|
|
594
|
+
pluginName: match.pluginName,
|
|
595
|
+
pluginId: match.pluginId,
|
|
596
|
+
sourceId: match.sourceId,
|
|
597
|
+
...(match.binding.kind === 'source'
|
|
598
|
+
? { sourceIdentity: match.binding.sourceIdentity }
|
|
599
|
+
: { logicalIdentity: match.binding.logicalIdentity }),
|
|
600
|
+
};
|
|
285
601
|
}
|
|
286
602
|
async function resolveStoredOnlyConfigIdentity(options) {
|
|
287
603
|
const parsed = parsePluginId(options.selector);
|
|
@@ -291,33 +607,43 @@ async function resolveStoredOnlyConfigIdentity(options) {
|
|
|
291
607
|
cwd: options.context.cwd,
|
|
292
608
|
env: options.context.env,
|
|
293
609
|
scope: location.scope,
|
|
294
|
-
...(location.scope === 'project' ? { projectLayer: location.projectLayer } : {}),
|
|
295
610
|
})))).flat().filter((store) => store.pluginId === options.selector);
|
|
296
611
|
if (stores.length === 0)
|
|
297
612
|
throw new Error(`Plugin "${options.selector}" does not have a namespaced config store.`);
|
|
298
|
-
const
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
613
|
+
const sourceBindings = stores.flatMap((store) => store.binding.kind === 'source'
|
|
614
|
+
? [store.binding.sourceIdentity] : []);
|
|
615
|
+
const catalogBindings = stores.flatMap((store) => store.binding.kind === 'catalog'
|
|
616
|
+
? [store.binding.logicalIdentity] : []);
|
|
617
|
+
if (new Set(sourceBindings).size > 1 || new Set(catalogBindings).size > 1) {
|
|
618
|
+
throw new Error(`identityMismatch: ${options.selector} config stores have different bindings.`);
|
|
619
|
+
}
|
|
620
|
+
const currentSource = await withResolvedMultiSourceCatalog({
|
|
303
621
|
cliVersion: resolveCliVersion(),
|
|
304
|
-
freshnessPolicy: 'cacheFirst',
|
|
305
622
|
sourceIds: [parsed.sourceId],
|
|
306
623
|
env: options.context.env,
|
|
307
624
|
consume: async (catalog) => {
|
|
308
625
|
const source = catalog.sources.find((entry) => entry.sourceId === parsed.sourceId);
|
|
309
|
-
if (!source?.resolution)
|
|
626
|
+
if (!source?.resolution) {
|
|
310
627
|
throw source?.error ?? new Error(`Catalog source "${parsed.sourceId}" is unavailable.`);
|
|
311
|
-
if (source.resolution.sourceIdentity !== sourceIdentity) {
|
|
312
|
-
throw new Error(`sourceChanged: ${options.selector} config source identity does not match the current source.`);
|
|
313
628
|
}
|
|
629
|
+
return {
|
|
630
|
+
sourceIdentity: source.resolution.sourceIdentity,
|
|
631
|
+
logicalIdentity: source.resolution.logicalIdentity,
|
|
632
|
+
};
|
|
314
633
|
},
|
|
315
634
|
});
|
|
635
|
+
if (sourceBindings[0] && sourceBindings[0] !== currentSource.sourceIdentity) {
|
|
636
|
+
throw new Error(`identityMismatch: ${options.selector} user config does not match the current source identity.`);
|
|
637
|
+
}
|
|
638
|
+
if (catalogBindings[0] && catalogBindings[0] !== currentSource.logicalIdentity) {
|
|
639
|
+
throw new Error(`identityMismatch: ${options.selector} project config does not match the current Catalog logical identity.`);
|
|
640
|
+
}
|
|
316
641
|
return {
|
|
317
642
|
pluginName: parsed.pluginName,
|
|
318
643
|
pluginId: options.selector,
|
|
319
644
|
sourceId: parsed.sourceId,
|
|
320
|
-
sourceIdentity,
|
|
645
|
+
sourceIdentity: currentSource.sourceIdentity,
|
|
646
|
+
logicalIdentity: currentSource.logicalIdentity,
|
|
321
647
|
};
|
|
322
648
|
}
|
|
323
649
|
async function resolveMultiSourceConfigRead(options) {
|
|
@@ -326,26 +652,21 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
326
652
|
env: options.context.env,
|
|
327
653
|
});
|
|
328
654
|
assertCatalogSourceReferencesSupported(inventory);
|
|
329
|
-
const projectLayer = resolveConfigProjectLayer(options.rawOptions);
|
|
330
655
|
return withResolvedCatalogPlugin({
|
|
331
656
|
selector: options.selector,
|
|
332
657
|
cliVersion: resolveCliVersion(),
|
|
333
|
-
freshnessPolicy: 'cacheFirst',
|
|
334
658
|
env: options.context.env,
|
|
335
659
|
consume: async ({ pluginId, source, plugin }) => {
|
|
336
660
|
const result = await resolveConfigRead({
|
|
337
661
|
pluginName: plugin.manifest.name,
|
|
338
662
|
plugin,
|
|
339
|
-
scope: options.rawOptions.
|
|
340
|
-
? 'project'
|
|
341
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
342
|
-
projectLayer,
|
|
663
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
343
664
|
cwd: options.context.cwd,
|
|
344
665
|
env: options.context.env,
|
|
345
666
|
});
|
|
346
667
|
if (options.key !== undefined) {
|
|
347
668
|
const field = findConfigFieldEntry(result.fields, options.key);
|
|
348
|
-
if (!field && plugin.manifest.config?.
|
|
669
|
+
if (!field && plugin.manifest.config?.fields?.[options.key] === undefined) {
|
|
349
670
|
throw new Error(`Unknown config key "${options.key}".`);
|
|
350
671
|
}
|
|
351
672
|
if (field)
|
|
@@ -371,12 +692,10 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
371
692
|
const result = await resolveConfigRead({
|
|
372
693
|
sourceId: stored.sourceId,
|
|
373
694
|
sourceIdentity: stored.sourceIdentity,
|
|
695
|
+
logicalIdentity: stored.logicalIdentity,
|
|
374
696
|
pluginName: stored.pluginName,
|
|
375
697
|
plugin: null,
|
|
376
|
-
scope: options.rawOptions.
|
|
377
|
-
? 'project'
|
|
378
|
-
: resolveConfigReadResolution(options.rawOptions.scope),
|
|
379
|
-
projectLayer,
|
|
698
|
+
scope: resolveConfigReadResolution(options.rawOptions.scope),
|
|
380
699
|
cwd: options.context.cwd,
|
|
381
700
|
env: options.context.env,
|
|
382
701
|
});
|
|
@@ -389,36 +708,53 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
389
708
|
return { ...stored, result };
|
|
390
709
|
});
|
|
391
710
|
}
|
|
392
|
-
|
|
711
|
+
export function createManagedCodexAuthorizer(rawOptions, context) {
|
|
712
|
+
if (rawOptions.allowManagedCodexInstall === true)
|
|
713
|
+
return async () => true;
|
|
714
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
715
|
+
|| !context.prompt.confirm)
|
|
716
|
+
return undefined;
|
|
717
|
+
return async () => {
|
|
718
|
+
const response = await context.prompt.confirm({
|
|
719
|
+
message: '系统中没有可用的 Codex CLI。是否获取本次操作所需的 AW-managed Codex runtime?',
|
|
720
|
+
defaultValue: false,
|
|
721
|
+
});
|
|
722
|
+
return !response.cancelled && response.value === true;
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
async function executeWriteCommand(command, pluginNames, rawOptions, context, directCli = false, expectedPlanFingerprint) {
|
|
393
726
|
const raw = { cwd: context.cwd, ...rawOptions };
|
|
394
|
-
const commandOptions = command === 'install'
|
|
727
|
+
const commandOptions = normalizeWriteRequest(() => command === 'install'
|
|
395
728
|
? normalizeInstallCommandOptions(raw)
|
|
396
|
-
: command === '
|
|
397
|
-
?
|
|
398
|
-
: command === '
|
|
399
|
-
?
|
|
400
|
-
:
|
|
401
|
-
? normalizeCleanupCommandOptions(raw)
|
|
402
|
-
: normalizeReinstallCommandOptions(raw);
|
|
729
|
+
: command === 'uninstall'
|
|
730
|
+
? normalizeUninstallCommandOptions(raw)
|
|
731
|
+
: command === 'cleanup'
|
|
732
|
+
? normalizeCleanupCommandOptions(raw)
|
|
733
|
+
: normalizeReinstallCommandOptions(raw));
|
|
403
734
|
await emitCommandEvent(context, {
|
|
404
735
|
type: 'options:normalized',
|
|
405
736
|
data: { plugins: pluginNames, options: commandOptions },
|
|
406
737
|
});
|
|
738
|
+
const managedCodexAuthorizer = createManagedCodexAuthorizer(rawOptions, context);
|
|
739
|
+
const runtime = {
|
|
740
|
+
...context,
|
|
741
|
+
directCli,
|
|
742
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
743
|
+
...(expectedPlanFingerprint ? { expectedPlanFingerprint } : {}),
|
|
744
|
+
...(managedCodexAuthorizer ? { managedCodexAuthorizer } : {}),
|
|
745
|
+
};
|
|
407
746
|
switch (command) {
|
|
408
|
-
case 'install': return installCommand(pluginNames, commandOptions,
|
|
409
|
-
case '
|
|
410
|
-
case '
|
|
411
|
-
case '
|
|
412
|
-
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, context);
|
|
747
|
+
case 'install': return installCommand(pluginNames, commandOptions, runtime);
|
|
748
|
+
case 'uninstall': return uninstallCommand(pluginNames, commandOptions, runtime);
|
|
749
|
+
case 'cleanup': return cleanupCommand(pluginNames, commandOptions, runtime);
|
|
750
|
+
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, runtime);
|
|
413
751
|
}
|
|
414
752
|
}
|
|
415
753
|
async function runWriteCommandAction(command, pluginNames, rawOptions, context) {
|
|
416
754
|
if ((command === 'cleanup' || command === 'reinstall') && pluginNames.length > 1) {
|
|
417
|
-
throw new
|
|
755
|
+
throw new WriteCommandRequestError(`${command} 命令当前只支持单个插件目标。`);
|
|
418
756
|
}
|
|
419
|
-
|
|
420
|
-
assertUpgradeAllConflict(pluginNames, rawOptions.all === true);
|
|
421
|
-
const missingPlugin = pluginNames.length === 0 && !(command === 'upgrade' && rawOptions.all === true);
|
|
757
|
+
const missingPlugin = pluginNames.length === 0;
|
|
422
758
|
const missingPlatform = rawOptions.platform === undefined;
|
|
423
759
|
const missingScope = command === 'cleanup' && rawOptions.scope === undefined;
|
|
424
760
|
const missing = missingPlugin || missingPlatform || missingScope;
|
|
@@ -431,19 +767,42 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
|
|
|
431
767
|
};
|
|
432
768
|
void validationOptions;
|
|
433
769
|
if (!missing) {
|
|
770
|
+
if (command === 'cleanup' && rawOptions.force !== true && rawOptions.yes !== true
|
|
771
|
+
&& isWizardAvailable(context, rawOptions) && context.prompt.confirm) {
|
|
772
|
+
const preview = await cleanupCommand(pluginNames, normalizeCleanupCommandOptions({
|
|
773
|
+
cwd: context.cwd,
|
|
774
|
+
...rawOptions,
|
|
775
|
+
}), { ...context, previewOperationPlan: true });
|
|
776
|
+
if ((preview.removedPluginCleanupIds?.length ?? 0) > 0) {
|
|
777
|
+
if (!preview.operationPlan) {
|
|
778
|
+
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
779
|
+
}
|
|
780
|
+
const response = await context.prompt.confirm({
|
|
781
|
+
message: `清理已删除插件 ${preview.removedPluginCleanupIds.join('、')}:将处理 Codex、Claude Code 的用户与当前项目位置,删除保存设置、安装意图、专属输出和共享原生安装。其他项目可能因此无法继续使用该插件;其本地记录不会修改。即使指定了 --platform 或 --scope,本次仍覆盖上述全部位置。继续?`,
|
|
782
|
+
defaultValue: false,
|
|
783
|
+
});
|
|
784
|
+
if (response.cancelled || response.value !== true)
|
|
785
|
+
return { cancelled: true };
|
|
786
|
+
return {
|
|
787
|
+
cancelled: false,
|
|
788
|
+
result: await executeWriteCommand(command, pluginNames, {
|
|
789
|
+
...rawOptions, yes: true,
|
|
790
|
+
}, context, true, preview.operationPlan.planFingerprint),
|
|
791
|
+
};
|
|
792
|
+
}
|
|
793
|
+
}
|
|
434
794
|
return {
|
|
435
795
|
cancelled: false,
|
|
436
|
-
result: await executeWriteCommand(command, pluginNames, rawOptions, context),
|
|
796
|
+
result: await executeWriteCommand(command, pluginNames, rawOptions, context, true),
|
|
437
797
|
};
|
|
438
798
|
}
|
|
439
799
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
440
|
-
throw new
|
|
800
|
+
throw new WriteCommandRequestError(writeCommandUsage(command));
|
|
441
801
|
}
|
|
442
802
|
const loaded = await loadConsoleItemsResult({
|
|
443
803
|
cwd: context.cwd,
|
|
444
804
|
scope: rawOptions.scope,
|
|
445
805
|
platform: rawOptions.platform,
|
|
446
|
-
includeCatalogOnly: true,
|
|
447
806
|
}, context);
|
|
448
807
|
if (loaded.catalogUnavailable) {
|
|
449
808
|
throw new Error('插件目录不可用。请运行 `aw init` 或 `aw init --force`,或使用完整参数重试。');
|
|
@@ -474,11 +833,37 @@ async function runWriteCommandAction(command, pluginNames, rawOptions, context)
|
|
|
474
833
|
equivalentCommandTokens: (selection) => buildEquivalentWriteCommandTokens(command, selection, rawOptions),
|
|
475
834
|
isPluginSelectable: (candidate, selection) => writeCandidateEligibility(command, candidate, selection),
|
|
476
835
|
resultState: overallResultState,
|
|
477
|
-
|
|
836
|
+
...(command === 'cleanup' ? {
|
|
837
|
+
reviewDetails: async (selection) => {
|
|
838
|
+
const preview = await cleanupCommand(selection.plugins, normalizeCleanupCommandOptions({
|
|
839
|
+
cwd: context.cwd,
|
|
840
|
+
...rawOptions,
|
|
841
|
+
platform: selection.platform,
|
|
842
|
+
scope: selection.scope,
|
|
843
|
+
}), { ...context, previewOperationPlan: true });
|
|
844
|
+
if ((preview.removedPluginCleanupIds?.length ?? 0) === 0)
|
|
845
|
+
return { lines: [] };
|
|
846
|
+
if (!preview.operationPlan) {
|
|
847
|
+
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
848
|
+
}
|
|
849
|
+
return {
|
|
850
|
+
lines: [
|
|
851
|
+
`已删除插件:${preview.removedPluginCleanupIds.join('、')}`,
|
|
852
|
+
'实际清理范围:Codex、Claude Code;用户与当前项目。',
|
|
853
|
+
'将删除保存设置、安装意图、专属输出和共享原生安装。',
|
|
854
|
+
'其他项目可能失去此插件;其本地记录不会修改。',
|
|
855
|
+
'当前 --platform / --scope 选择不会限制整体清理范围。',
|
|
856
|
+
],
|
|
857
|
+
expectedPlanFingerprint: preview.operationPlan.planFingerprint,
|
|
858
|
+
};
|
|
859
|
+
},
|
|
860
|
+
} : {}),
|
|
861
|
+
execute: (selection, expectedPlanFingerprint) => executeWriteCommand(command, selection.plugins, {
|
|
478
862
|
...rawOptions,
|
|
479
863
|
platform: selection.platform,
|
|
480
864
|
scope: selection.scope,
|
|
481
|
-
|
|
865
|
+
...(command === 'cleanup' ? { yes: true } : {}),
|
|
866
|
+
}, context, false, expectedPlanFingerprint),
|
|
482
867
|
});
|
|
483
868
|
if (result.cancelled)
|
|
484
869
|
return { cancelled: true };
|
|
@@ -589,34 +974,78 @@ async function runActionWithContext(context, action) {
|
|
|
589
974
|
function writeJsonReceipt(write, payload) {
|
|
590
975
|
writeLine(write, JSON.stringify(payload, null, 2));
|
|
591
976
|
}
|
|
592
|
-
function configLayerLabel(scope
|
|
977
|
+
function configLayerLabel(scope) {
|
|
593
978
|
if (scope === 'user') {
|
|
594
979
|
return '个人';
|
|
595
980
|
}
|
|
596
|
-
return
|
|
981
|
+
return '当前项目';
|
|
597
982
|
}
|
|
598
983
|
function writeConfigApplyNotice(write, receipt) {
|
|
599
|
-
|
|
600
|
-
|
|
984
|
+
const sanitizeMessage = (message) => redactString(message)
|
|
985
|
+
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
986
|
+
.replace(/file:\/\/\S+/giu, '[REDACTED PATH]')
|
|
987
|
+
.replace(/(?:file:\/\/)?(?:\/[\w.@+-]+){2,}/gu, '[REDACTED PATH]')
|
|
988
|
+
.replace(/[A-Za-z]:\\(?:[^\s\\]+\\)+[^\s\\]*/gu, '[REDACTED PATH]');
|
|
989
|
+
const writeTargetFailures = () => {
|
|
990
|
+
for (const entry of receipt.apply.targetResults.filter((target) => target.state === 'failed' || target.state === 'skipped')) {
|
|
991
|
+
const reason = entry.message
|
|
992
|
+
? `${entry.errorCode ? `[${entry.errorCode}] ` : ''}${sanitizeMessage(entry.message)}`
|
|
993
|
+
: entry.errorCode
|
|
994
|
+
? `失败原因:${entry.errorCode}。`
|
|
995
|
+
: '未提供安全失败原因。';
|
|
996
|
+
const command = `aw reinstall ${receipt.plugin} -p ${entry.target.platform} -s ${entry.target.scope}`;
|
|
997
|
+
const recovery = entry.errorCode === 'invalidConfig'
|
|
998
|
+
? ' 请修复无效配置后运行 aw sync。'
|
|
999
|
+
: entry.errorCode === 'preApplyAuthorizationRequired'
|
|
1000
|
+
|| entry.errorCode === 'sharedNativeConfigApplyConfirmationRequired'
|
|
1001
|
+
|| entry.errorCode === 'sharedNativeImpactAuthorizationRequired'
|
|
1002
|
+
? ` 请运行 ${command} --yes 重试。`
|
|
1003
|
+
: entry.state === 'failed'
|
|
1004
|
+
? ` 请在解决失败原因后运行 ${command}。`
|
|
1005
|
+
: '';
|
|
1006
|
+
writeLine(write, `${entry.target.platform}/${entry.target.scope}:${reason}${recovery}`);
|
|
1007
|
+
}
|
|
1008
|
+
};
|
|
1009
|
+
const targetResults = receipt.apply.targetResults;
|
|
1010
|
+
if (receipt.apply.state === 'skipped') {
|
|
1011
|
+
const message = receipt.apply.reason === 'noConfigChange'
|
|
601
1012
|
? '配置内容没有变化,因此没有运行 reinstall。'
|
|
602
|
-
:
|
|
1013
|
+
: receipt.apply.reason === 'noEffectiveConfigChange'
|
|
1014
|
+
? '配置存储已更新,但有效配置没有变化,因此没有运行 reinstall。'
|
|
1015
|
+
: receipt.apply.reason === 'notRequested'
|
|
1016
|
+
? '配置已保存,但未请求应用配置。'
|
|
1017
|
+
: '配置已保存。当前没有可见的 AW 安装目标,因此没有应用配置。';
|
|
603
1018
|
writeLine(write, message);
|
|
604
1019
|
}
|
|
605
|
-
else {
|
|
606
|
-
const
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
}
|
|
1020
|
+
else if (receipt.apply.state === 'unavailable') {
|
|
1021
|
+
const fallbackMessages = {
|
|
1022
|
+
invalidConfig: '可见目标的有效配置无效。',
|
|
1023
|
+
schemaUnavailable: '配置 schema 不可用。',
|
|
1024
|
+
sourceUnavailable: '插件来源不可用。',
|
|
1025
|
+
effectiveConfigUnavailable: '无法读取有效配置。',
|
|
1026
|
+
targetDiscoveryFailed: '无法发现可应用配置的目标。',
|
|
1027
|
+
};
|
|
1028
|
+
const detail = receipt.apply.error
|
|
1029
|
+
? `${receipt.apply.error.code}:${sanitizeMessage(receipt.apply.error.message)}`
|
|
1030
|
+
: `${receipt.apply.reason}:${fallbackMessages[receipt.apply.reason]}`;
|
|
1031
|
+
const recovery = receipt.apply.reason === 'invalidConfig'
|
|
1032
|
+
? '请修复无效配置后运行 aw sync。'
|
|
1033
|
+
: receipt.apply.reason === 'effectiveConfigUnavailable'
|
|
1034
|
+
? '请修复配置后运行 aw sync。'
|
|
1035
|
+
: receipt.apply.reason === 'schemaUnavailable' || receipt.apply.reason === 'sourceUnavailable'
|
|
1036
|
+
? '请修复插件来源或配置后运行 aw sync。'
|
|
1037
|
+
: '请修复来源或配置后运行 aw sync。';
|
|
1038
|
+
writeLine(write, `配置已保存,但当前无法应用配置。${detail} ${recovery}`);
|
|
1039
|
+
writeTargetFailures();
|
|
613
1040
|
}
|
|
614
|
-
|
|
615
|
-
|
|
1041
|
+
else {
|
|
1042
|
+
const completed = targetResults.filter((entry) => entry.state === 'completed').length;
|
|
1043
|
+
const failed = targetResults.filter((entry) => entry.state === 'failed').length;
|
|
1044
|
+
const skipped = targetResults.filter((entry) => entry.state === 'skipped').length;
|
|
1045
|
+
writeLine(write, `配置已保存。已重装 ${completed} 个当前可见目标;失败 ${failed} 个;跳过 ${skipped} 个。`);
|
|
1046
|
+
writeTargetFailures();
|
|
616
1047
|
}
|
|
617
|
-
|
|
618
|
-
function writeProjectLocalConfigNotice(write) {
|
|
619
|
-
writeLine(write, '当前显示的是当前项目的本机私有覆盖层,不作为 repo-visible artifact 渲染输入。');
|
|
1048
|
+
writeWarnings(write, receipt.warnings);
|
|
620
1049
|
}
|
|
621
1050
|
function renderConfigFieldState(field) {
|
|
622
1051
|
if (field.valueState === 'invalid') {
|
|
@@ -636,13 +1065,15 @@ function writeConfigReadHuman(write, resolved, pluginName) {
|
|
|
636
1065
|
}
|
|
637
1066
|
if (field.kind === 'manifest' && field.valueState === 'invalid') {
|
|
638
1067
|
const sourceScope = field.sourceLayer === 'project'
|
|
639
|
-
? '
|
|
640
|
-
:
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
1068
|
+
? 'project'
|
|
1069
|
+
: 'user';
|
|
1070
|
+
const definition = resolved.fieldDefinitions?.[field.key];
|
|
1071
|
+
if (definition) {
|
|
1072
|
+
writeLine(write, ` ${formatPluginConfigSetRecoveryCommand(pluginName, field.key, definition, sourceScope)}`);
|
|
1073
|
+
}
|
|
1074
|
+
const scopeOption = ` -s ${sourceScope}`;
|
|
1075
|
+
writeLine(write, ` aw config unset ${pluginName} ${field.key}${scopeOption}`);
|
|
1076
|
+
writeLine(write, ` aw config reset ${pluginName}${scopeOption}`);
|
|
646
1077
|
}
|
|
647
1078
|
}
|
|
648
1079
|
}
|
|
@@ -676,10 +1107,33 @@ export function buildProgram(options = {}) {
|
|
|
676
1107
|
const plugin = program
|
|
677
1108
|
.command('plugin')
|
|
678
1109
|
.description('Create and validate AW plugin source');
|
|
1110
|
+
const self = program
|
|
1111
|
+
.command('self')
|
|
1112
|
+
.description('Describe and check this AW executable');
|
|
1113
|
+
self
|
|
1114
|
+
.command('describe')
|
|
1115
|
+
.description('Describe implemented AW capabilities')
|
|
1116
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1117
|
+
.action(() => {
|
|
1118
|
+
writeJsonReceipt(io.stdout, describeCurrentAw(resolveCliVersion()));
|
|
1119
|
+
});
|
|
1120
|
+
self
|
|
1121
|
+
.command('check')
|
|
1122
|
+
.description('Check nearby plugin requirements against this AW executable')
|
|
1123
|
+
.option('--from <path>', 'start discovery from this file or directory')
|
|
1124
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1125
|
+
.action(async (rawOptions) => {
|
|
1126
|
+
const result = await checkCurrentAw({
|
|
1127
|
+
awVersion: resolveCliVersion(),
|
|
1128
|
+
from: path.resolve(cwd, rawOptions.from ?? '.'),
|
|
1129
|
+
});
|
|
1130
|
+
writeJsonReceipt(io.stdout, result);
|
|
1131
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1132
|
+
});
|
|
679
1133
|
plugin
|
|
680
1134
|
.command('capabilities')
|
|
681
|
-
.description('Show the current plugin authoring
|
|
682
|
-
.option('--surface <surface>', 'manifest | build-config | extensions | slash-commands | mcp-apps | config |
|
|
1135
|
+
.description('Show the current plugin manifest authoring surface')
|
|
1136
|
+
.option('--surface <surface>', 'manifest | build-config | extensions | slash-commands | mcp-apps | config | pre-apply | artifacts')
|
|
683
1137
|
.option('--json', 'emit one machine-readable JSON object', false)
|
|
684
1138
|
.action((rawOptions) => {
|
|
685
1139
|
try {
|
|
@@ -701,160 +1155,207 @@ export function buildProgram(options = {}) {
|
|
|
701
1155
|
commandExitState.exitCode = 1;
|
|
702
1156
|
}
|
|
703
1157
|
});
|
|
704
|
-
|
|
705
|
-
.command('
|
|
706
|
-
.description('
|
|
707
|
-
|
|
708
|
-
.
|
|
709
|
-
.
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
1158
|
+
plugin
|
|
1159
|
+
.command('requirements')
|
|
1160
|
+
.description('Inspect or update effective AW capabilities required by a plugin')
|
|
1161
|
+
.argument('<plugin-directory>', 'plugin source directory')
|
|
1162
|
+
.option('--workspace-root <root>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1163
|
+
.option('--add <capability>', 'add one declared AW capability')
|
|
1164
|
+
.option('--remove <capability>', 'remove one declared AW capability')
|
|
1165
|
+
.requiredOption('--json', 'emit one machine-readable JSON object')
|
|
1166
|
+
.action(async (pluginDirectory, rawOptions) => {
|
|
1167
|
+
try {
|
|
1168
|
+
const result = await inspectPluginRequirements({
|
|
1169
|
+
pluginDirectory,
|
|
1170
|
+
...(rawOptions.workspaceRoot ? { workspaceRoot: rawOptions.workspaceRoot } : {}),
|
|
1171
|
+
...(rawOptions.add ? { add: rawOptions.add } : {}),
|
|
1172
|
+
...(rawOptions.remove ? { remove: rawOptions.remove } : {}),
|
|
1173
|
+
cwd,
|
|
1174
|
+
});
|
|
1175
|
+
writeJsonReceipt(io.stdout, result);
|
|
1176
|
+
if (result.observations.some((observation) => observation.blocking)) {
|
|
1177
|
+
commandExitState.exitCode = 1;
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
catch (error) {
|
|
724
1181
|
writeJsonReceipt(io.stdout, {
|
|
725
1182
|
schemaVersion: 1,
|
|
726
|
-
command: '
|
|
727
|
-
ok:
|
|
728
|
-
|
|
1183
|
+
command: 'plugin:requirements',
|
|
1184
|
+
ok: false,
|
|
1185
|
+
error: error instanceof Error ? error.message : String(error),
|
|
729
1186
|
});
|
|
730
|
-
|
|
1187
|
+
commandExitState.exitCode = 1;
|
|
731
1188
|
}
|
|
732
|
-
writeLine(io.stdout, `${result.path}: ${result.digest}`);
|
|
733
1189
|
});
|
|
734
|
-
|
|
735
|
-
.command('
|
|
736
|
-
.description('
|
|
737
|
-
|
|
738
|
-
.
|
|
739
|
-
.
|
|
740
|
-
|
|
741
|
-
.
|
|
742
|
-
.
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
], [])
|
|
750
|
-
.option('--release-check <release-check.json>', 'release check JSON file')
|
|
751
|
-
.option('--supersedes <review-id>', 'review ID that this record supersedes')
|
|
752
|
-
.option('--json', 'emit one review record JSON object', false)
|
|
753
|
-
.action(async (rawOptions) => {
|
|
754
|
-
const repoRoot = await resolveRepoRoot(cwd);
|
|
755
|
-
const record = await publishReviewRecord({
|
|
756
|
-
repoRoot,
|
|
757
|
-
kind: rawOptions.kind,
|
|
758
|
-
target: rawOptions.target,
|
|
759
|
-
report: rawOptions.report,
|
|
760
|
-
...(rawOptions.scope === undefined ? {} : { scope: rawOptions.scope }),
|
|
761
|
-
...(rawOptions.result === undefined ? {} : { result: rawOptions.result }),
|
|
762
|
-
...(rawOptions.check.length === 0 ? {} : { checks: rawOptions.check }),
|
|
763
|
-
...(rawOptions.evidence.length === 0 ? {} : { evidence: rawOptions.evidence }),
|
|
764
|
-
...(rawOptions.releaseCheck === undefined ? {} : { releaseCheck: rawOptions.releaseCheck }),
|
|
765
|
-
...(rawOptions.supersedes === undefined ? {} : { supersedes: rawOptions.supersedes }),
|
|
766
|
-
});
|
|
767
|
-
const recordDir = reviewRecordDir(repoRoot, record);
|
|
768
|
-
if (rawOptions.json) {
|
|
1190
|
+
const skill = program
|
|
1191
|
+
.command('skill')
|
|
1192
|
+
.description('Install, materialize, or validate Agent Skills');
|
|
1193
|
+
const skillEval = skill
|
|
1194
|
+
.command('eval')
|
|
1195
|
+
.description('Prepare or diagnose deterministic Agent Skill Eval inputs');
|
|
1196
|
+
skillEval
|
|
1197
|
+
.command('doctor')
|
|
1198
|
+
.description('Inspect Agent Skill Eval provider readiness without model execution')
|
|
1199
|
+
.requiredOption('--json', 'emit one provider doctor JSON object')
|
|
1200
|
+
.action(async () => {
|
|
1201
|
+
try {
|
|
1202
|
+
writeJsonReceipt(io.stdout, await doctorEvalProviders({ sourceEnv: env }));
|
|
1203
|
+
}
|
|
1204
|
+
catch (error) {
|
|
769
1205
|
writeJsonReceipt(io.stdout, {
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
ok: true,
|
|
773
|
-
...reviewJsonRecord(repoRoot, record),
|
|
774
|
-
existing: record.existing,
|
|
1206
|
+
ok: false,
|
|
1207
|
+
error: redactString(error instanceof Error ? error.message : String(error)),
|
|
775
1208
|
});
|
|
776
|
-
|
|
1209
|
+
commandExitState.exitCode = 1;
|
|
777
1210
|
}
|
|
778
|
-
writeLine(io.stdout, `${record.existing ? 'Existing' : 'Published'} review ${record.manifest.reviewId}: ${recordDir}`);
|
|
779
1211
|
});
|
|
780
|
-
|
|
781
|
-
.command('
|
|
782
|
-
.description('
|
|
783
|
-
.argument('<
|
|
784
|
-
.
|
|
785
|
-
.
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
1212
|
+
skillEval
|
|
1213
|
+
.command('prepare')
|
|
1214
|
+
.description('Prepare one complete Agent Skill Eval input directory')
|
|
1215
|
+
.argument('<plugin>', 'canonical Workspace plugin name')
|
|
1216
|
+
.argument('<skill>', 'owner Skill name')
|
|
1217
|
+
.option('--suite <suite>', 'Eval suite ID')
|
|
1218
|
+
.option('--profile <profile>', 'Eval profile ID')
|
|
1219
|
+
.option('--config-file <path>', 'non-sensitive plugin config overrides for the Eval profile')
|
|
1220
|
+
.option('--workspace-root <root>', 'Catalog Workspace root')
|
|
1221
|
+
.option('--split <split>', 'case split filter')
|
|
1222
|
+
.option('--case <id>', 'case ID filter')
|
|
1223
|
+
.option('--runs <count>', 'runs per selected case')
|
|
1224
|
+
.option('--timeout-ms <milliseconds>', 'timeout for each provider attempt')
|
|
1225
|
+
.option('--baseline <mode>', 'append without-skill comparison')
|
|
1226
|
+
.option('--previous-version <runtime-skill-root>', 'append a previous-version comparison')
|
|
1227
|
+
.option('--keep-workspace', 'retain the preparation materialization workspace', false)
|
|
1228
|
+
.requiredOption('--output <spec-directory>', 'new EvalSpec directory')
|
|
1229
|
+
.requiredOption('--json', 'emit one preparation receipt JSON object')
|
|
1230
|
+
.action(async (pluginName, skillName, rawOptions) => {
|
|
1231
|
+
try {
|
|
1232
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1233
|
+
cwd,
|
|
1234
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1235
|
+
mode: 'existing',
|
|
1236
|
+
env,
|
|
1237
|
+
});
|
|
1238
|
+
const runs = rawOptions.runs === undefined
|
|
1239
|
+
? undefined
|
|
1240
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.runs) ? Number(rawOptions.runs) : Number.NaN);
|
|
1241
|
+
const timeoutMs = rawOptions.timeoutMs === undefined
|
|
1242
|
+
? undefined
|
|
1243
|
+
: (/^[1-9][0-9]*$/u.test(rawOptions.timeoutMs) ? Number(rawOptions.timeoutMs) : Number.NaN);
|
|
1244
|
+
const receipt = await prepareSkillEval({
|
|
1245
|
+
workspaceRoot: workspace.workspaceRoot,
|
|
1246
|
+
workspaceRootResolvedFrom: workspace.workspaceRootResolvedFrom,
|
|
1247
|
+
pluginName,
|
|
1248
|
+
skillName,
|
|
1249
|
+
...(rawOptions.suite === undefined ? {} : { suiteId: rawOptions.suite }),
|
|
1250
|
+
...(rawOptions.profile === undefined ? {} : { profileId: rawOptions.profile }),
|
|
1251
|
+
...(rawOptions.configFile === undefined ? {} : { configFile: path.resolve(cwd, rawOptions.configFile) }),
|
|
1252
|
+
output: rawOptions.output,
|
|
1253
|
+
cwd,
|
|
1254
|
+
env,
|
|
1255
|
+
...(rawOptions.split === undefined ? {} : { split: rawOptions.split }),
|
|
1256
|
+
...(rawOptions.case === undefined ? {} : { caseId: rawOptions.case }),
|
|
1257
|
+
...(runs === undefined ? {} : { runs }),
|
|
1258
|
+
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
1259
|
+
...(rawOptions.baseline === undefined ? {} : {
|
|
1260
|
+
baseline: rawOptions.baseline,
|
|
1261
|
+
}),
|
|
1262
|
+
...(rawOptions.previousVersion === undefined ? {} : {
|
|
1263
|
+
previousVersion: rawOptions.previousVersion,
|
|
1264
|
+
}),
|
|
1265
|
+
...(rawOptions.keepWorkspace === true ? { keepWorkspace: true } : {}),
|
|
1266
|
+
});
|
|
1267
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1268
|
+
}
|
|
1269
|
+
catch (error) {
|
|
790
1270
|
writeJsonReceipt(io.stdout, {
|
|
791
1271
|
schemaVersion: 1,
|
|
792
|
-
command: '
|
|
793
|
-
ok:
|
|
794
|
-
|
|
1272
|
+
command: 'skill:eval:prepare',
|
|
1273
|
+
ok: false,
|
|
1274
|
+
errors: [{
|
|
1275
|
+
code: 'evalPreparationFailed',
|
|
1276
|
+
message: redactString(error instanceof Error ? error.message : String(error)),
|
|
1277
|
+
}],
|
|
795
1278
|
});
|
|
796
|
-
|
|
1279
|
+
commandExitState.exitCode = 1;
|
|
797
1280
|
}
|
|
798
|
-
writeLine(io.stdout, `Verified review ${record.manifest.reviewId}: ${relativeRecordDir}`);
|
|
799
1281
|
});
|
|
1282
|
+
const review = program
|
|
1283
|
+
.command('review')
|
|
1284
|
+
.description('Inspect and prepare Skill review materializations');
|
|
800
1285
|
review
|
|
801
|
-
.command('
|
|
802
|
-
.description('
|
|
803
|
-
.
|
|
804
|
-
.
|
|
805
|
-
.option('--
|
|
806
|
-
.
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
1286
|
+
.command('inspect')
|
|
1287
|
+
.description('Inspect current AW Review source and materialization facts')
|
|
1288
|
+
.argument('<target>', 'Catalog Workspace, Plugin, or source Skill path')
|
|
1289
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1290
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1291
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']))
|
|
1292
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']))
|
|
1293
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1294
|
+
.option('--materialization <receipt>', 'validate one aw-source-binding receipt', collectUniqueOption, [])
|
|
1295
|
+
.addOption(strictValueOption('--view <view>', 'select the review navigation view', ['review']).default('review'))
|
|
1296
|
+
.option('--json', 'emit one Review inspection JSON object', false)
|
|
1297
|
+
.action(async (target, rawOptions) => {
|
|
1298
|
+
try {
|
|
1299
|
+
const receipt = await inspectReviewTarget({
|
|
1300
|
+
cwd,
|
|
1301
|
+
target,
|
|
1302
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1303
|
+
? {}
|
|
1304
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1305
|
+
skills: rawOptions.skill,
|
|
1306
|
+
...(rawOptions.platform === undefined ? {} : { platform: rawOptions.platform }),
|
|
1307
|
+
...(rawOptions.scope === undefined ? {} : { scope: rawOptions.scope }),
|
|
1308
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1309
|
+
materializations: [...new Set(rawOptions.materialization
|
|
1310
|
+
.map((entry) => path.resolve(cwd, entry)))],
|
|
1311
|
+
view: rawOptions.view,
|
|
1312
|
+
env,
|
|
819
1313
|
});
|
|
820
|
-
|
|
1314
|
+
if (rawOptions.json)
|
|
1315
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1316
|
+
else
|
|
1317
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1318
|
+
commandExitState.exitCode = 0;
|
|
821
1319
|
}
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
1320
|
+
catch (error) {
|
|
1321
|
+
const receipt = createReviewInspectionFailure(error);
|
|
1322
|
+
if (rawOptions.json)
|
|
1323
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1324
|
+
else
|
|
1325
|
+
renderReviewInspection(io.stdout, receipt);
|
|
1326
|
+
commandExitState.exitCode = getReviewInspectionExitCode(error);
|
|
829
1327
|
}
|
|
830
1328
|
});
|
|
831
1329
|
review
|
|
832
|
-
.command('
|
|
833
|
-
.description('
|
|
834
|
-
.argument('<
|
|
835
|
-
.
|
|
836
|
-
.
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
1330
|
+
.command('prepare')
|
|
1331
|
+
.description('Prepare deterministic Skill finals for AW Review')
|
|
1332
|
+
.argument('<target>', 'Plugin or source Skill path')
|
|
1333
|
+
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1334
|
+
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1335
|
+
.addOption(strictValueOption('--platform <platform>', 'select codex, claude, or agent-skills', ['codex', 'claude', 'agent-skills']).makeOptionMandatory())
|
|
1336
|
+
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']).makeOptionMandatory())
|
|
1337
|
+
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1338
|
+
.addOption(strictValueOption('--out <new-dir>', 'new output directory').makeOptionMandatory())
|
|
1339
|
+
.option('--json', 'emit one Review preparation JSON object', false)
|
|
1340
|
+
.action(async (target, rawOptions) => {
|
|
1341
|
+
const result = await prepareReviewTarget({
|
|
1342
|
+
cwd,
|
|
1343
|
+
target,
|
|
1344
|
+
...(rawOptions.workspaceRoot === undefined
|
|
1345
|
+
? {}
|
|
1346
|
+
: { workspaceRoot: rawOptions.workspaceRoot }),
|
|
1347
|
+
skills: rawOptions.skill,
|
|
1348
|
+
platform: rawOptions.platform,
|
|
1349
|
+
scope: rawOptions.scope,
|
|
1350
|
+
...(rawOptions.config === undefined ? {} : { configFile: rawOptions.config }),
|
|
1351
|
+
out: rawOptions.out,
|
|
1352
|
+
env,
|
|
1353
|
+
});
|
|
1354
|
+
if (rawOptions.json)
|
|
1355
|
+
writeJsonReceipt(io.stdout, result.receipt);
|
|
1356
|
+
else
|
|
1357
|
+
renderReviewPreparation(io.stdout, result.receipt);
|
|
1358
|
+
commandExitState.exitCode = result.exitCode;
|
|
858
1359
|
});
|
|
859
1360
|
skill
|
|
860
1361
|
.command('install')
|
|
@@ -864,15 +1365,17 @@ export function buildProgram(options = {}) {
|
|
|
864
1365
|
.option('--skill <name...>', 'install only selected Skill names')
|
|
865
1366
|
.option('--agent <id...>', 'install to explicit Agent IDs')
|
|
866
1367
|
.option('-y, --yes', 'confirm the reviewed install', false)
|
|
867
|
-
.option('-j, --json', 'emit one receipt
|
|
1368
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
868
1369
|
.action(async (selector, rawOptions) => {
|
|
869
1370
|
const context = createActionContext('skill:install', {});
|
|
870
1371
|
const writeFailure = (error) => {
|
|
871
|
-
const
|
|
872
|
-
|
|
873
|
-
|
|
1372
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1373
|
+
const code = capabilityError?.code
|
|
1374
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1375
|
+
? error.code
|
|
1376
|
+
: 'portableInstallFailed');
|
|
874
1377
|
writeJsonReceipt(io.stdout, {
|
|
875
|
-
receiptSchemaVersion:
|
|
1378
|
+
receiptSchemaVersion: 5,
|
|
876
1379
|
command: 'skill:install',
|
|
877
1380
|
ok: false,
|
|
878
1381
|
status: 'failed',
|
|
@@ -888,7 +1391,15 @@ export function buildProgram(options = {}) {
|
|
|
888
1391
|
materializationDigest: null,
|
|
889
1392
|
verification: { records: [], missing: [] },
|
|
890
1393
|
warnings: [],
|
|
891
|
-
failures: [{
|
|
1394
|
+
failures: [{
|
|
1395
|
+
code,
|
|
1396
|
+
message: capabilityError?.message ?? `${code}: portable Skill 安装未执行。`,
|
|
1397
|
+
...(capabilityError ? {
|
|
1398
|
+
plugin: capabilityError.plugin,
|
|
1399
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1400
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1401
|
+
} : {}),
|
|
1402
|
+
}],
|
|
892
1403
|
});
|
|
893
1404
|
};
|
|
894
1405
|
if (rawOptions.json && !rawOptions.yes) {
|
|
@@ -926,6 +1437,7 @@ export function buildProgram(options = {}) {
|
|
|
926
1437
|
else {
|
|
927
1438
|
const sanitize = (value) => redactString(value)
|
|
928
1439
|
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
1440
|
+
.replace(/file:\/\/\S+/giu, '[REDACTED PATH]')
|
|
929
1441
|
.replace(/(?:file:\/\/)?(?:\/[\w.@+-]+){2,}/gu, '[REDACTED PATH]')
|
|
930
1442
|
.replace(/[A-Za-z]:\\(?:[^\s\\]+\\)+[^\s\\]*/gu, '[REDACTED PATH]');
|
|
931
1443
|
const lines = new Set();
|
|
@@ -958,7 +1470,7 @@ export function buildProgram(options = {}) {
|
|
|
958
1470
|
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
959
1471
|
.requiredOption('--out <dir>', 'output directory')
|
|
960
1472
|
.option('--skill <name...>', 'write only selected Skill names')
|
|
961
|
-
.option('-j, --json', 'emit one receipt
|
|
1473
|
+
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
962
1474
|
.action(async (selector, rawOptions) => {
|
|
963
1475
|
const context = createActionContext('skill:materialize', {});
|
|
964
1476
|
try {
|
|
@@ -979,11 +1491,13 @@ export function buildProgram(options = {}) {
|
|
|
979
1491
|
catch (error) {
|
|
980
1492
|
if (!rawOptions.json)
|
|
981
1493
|
throw error;
|
|
982
|
-
const
|
|
983
|
-
|
|
984
|
-
|
|
1494
|
+
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1495
|
+
const code = capabilityError?.code
|
|
1496
|
+
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1497
|
+
? error.code
|
|
1498
|
+
: 'portableMaterializeFailed');
|
|
985
1499
|
writeJsonReceipt(io.stdout, {
|
|
986
|
-
receiptSchemaVersion:
|
|
1500
|
+
receiptSchemaVersion: 5,
|
|
987
1501
|
command: 'skill:materialize',
|
|
988
1502
|
ok: false,
|
|
989
1503
|
plugin: { id: selector },
|
|
@@ -995,7 +1509,15 @@ export function buildProgram(options = {}) {
|
|
|
995
1509
|
configDigest: null,
|
|
996
1510
|
materializationDigest: null,
|
|
997
1511
|
outputDigest: null,
|
|
998
|
-
errors: [{
|
|
1512
|
+
errors: [{
|
|
1513
|
+
code,
|
|
1514
|
+
message: capabilityError?.message ?? `${code}: portable Skill 导出未执行。`,
|
|
1515
|
+
...(capabilityError ? {
|
|
1516
|
+
plugin: capabilityError.plugin,
|
|
1517
|
+
missingCapabilities: capabilityError.missingCapabilities,
|
|
1518
|
+
availableCapabilities: capabilityError.availableCapabilities,
|
|
1519
|
+
} : {}),
|
|
1520
|
+
}],
|
|
999
1521
|
});
|
|
1000
1522
|
commandExitState.exitCode = 1;
|
|
1001
1523
|
}
|
|
@@ -1007,7 +1529,7 @@ export function buildProgram(options = {}) {
|
|
|
1007
1529
|
'',
|
|
1008
1530
|
'During development, keep the current stable target when production content changes.',
|
|
1009
1531
|
'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.',
|
|
1532
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
1011
1533
|
'',
|
|
1012
1534
|
].join('\n'))
|
|
1013
1535
|
.argument('<plugin-name>', 'lowercase hyphen-case plugin name')
|
|
@@ -1019,14 +1541,12 @@ export function buildProgram(options = {}) {
|
|
|
1019
1541
|
.option('--skill-short-description <text>', 'initial Skill UI summary (25-64 characters)')
|
|
1020
1542
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
1021
1543
|
.option('--version <semver>', 'initial stable plugin version (default: 0.1.0)')
|
|
1022
|
-
.option('--
|
|
1023
|
-
.option('--catalog-min-version <semver>', 'target catalog compatibility minimum')
|
|
1024
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
|
|
1544
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1025
1545
|
.option('--no-skills', 'create the plugin without a skills directory')
|
|
1026
1546
|
.option('--with-mcp', 'add a minimal .mcp.json', false)
|
|
1027
1547
|
.option('--with-apps', 'add a minimal .app.json', false)
|
|
1028
1548
|
.option('--with-config-api', 'add AW config schema and helper', false)
|
|
1029
|
-
.option('--with-
|
|
1549
|
+
.option('--with-pre-apply', 'add an idempotent Node preApply environment check', false);
|
|
1030
1550
|
plugin
|
|
1031
1551
|
.command('add-skill')
|
|
1032
1552
|
.description('Add one static Skill scaffold to an existing plugin')
|
|
@@ -1034,7 +1554,7 @@ export function buildProgram(options = {}) {
|
|
|
1034
1554
|
'',
|
|
1035
1555
|
'During development, keep the current stable target when production content changes.',
|
|
1036
1556
|
'Next, run `aw plugin validate`, `aw plugin test`, `aw plugin build`, and `aw catalog build`.',
|
|
1037
|
-
'Publish only as an explicit later step; inspect `aw catalog publish --help` first.',
|
|
1557
|
+
'Publish only as an explicit later step; inspect `aw catalog publish plan --help` first.',
|
|
1038
1558
|
'',
|
|
1039
1559
|
].join('\n'))
|
|
1040
1560
|
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
@@ -1042,35 +1562,39 @@ export function buildProgram(options = {}) {
|
|
|
1042
1562
|
.option('--skill-description <text>', 'Skill goal and discovery description (required)')
|
|
1043
1563
|
.option('--skill-short-description <text>', 'Skill UI summary (25-64 characters)')
|
|
1044
1564
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
1045
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
|
|
1565
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1046
1566
|
plugin
|
|
1047
1567
|
.command('remove')
|
|
1048
1568
|
.description('Remove one committed and unchanged canonical plugin source tree')
|
|
1049
1569
|
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
1050
|
-
.
|
|
1570
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1051
1571
|
.option('--yes', 'confirm plugin source deletion', false)
|
|
1052
1572
|
.option('--json', 'emit one schema 1 JSON object', false);
|
|
1053
1573
|
plugin
|
|
1054
1574
|
.command('validate')
|
|
1055
1575
|
.description('Validate one source plugin directory')
|
|
1056
1576
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1057
|
-
.option('--catalog-min-version <semver>', 'validate compatibility against a target catalog')
|
|
1058
1577
|
.option('--strict-agent-skills', 'allow only Agent Skills portable core frontmatter', false)
|
|
1059
1578
|
.option('--claude-skill-profile <profile>', 'minimum | current (default: minimum)')
|
|
1060
1579
|
.option('--version-base <git-ref>', 'production bundle comparison base (default: HEAD)')
|
|
1061
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default:
|
|
1580
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1062
1581
|
.option('--json', 'emit one machine-readable JSON result', false);
|
|
1063
1582
|
plugin
|
|
1064
1583
|
.command('test')
|
|
1065
1584
|
.description('Run deterministic Node tests declared by one source plugin')
|
|
1066
1585
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1067
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default:
|
|
1586
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1068
1587
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1069
1588
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1070
1589
|
try {
|
|
1590
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1591
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1592
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1593
|
+
mode: 'existing',
|
|
1594
|
+
});
|
|
1071
1595
|
commandExitState.exitCode = await runPluginTestCommand({
|
|
1072
|
-
|
|
1073
|
-
pluginDirectory,
|
|
1596
|
+
...workspace,
|
|
1597
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1074
1598
|
json: rawOptions.json,
|
|
1075
1599
|
io,
|
|
1076
1600
|
});
|
|
@@ -1087,15 +1611,20 @@ export function buildProgram(options = {}) {
|
|
|
1087
1611
|
.command('build')
|
|
1088
1612
|
.description('Build and inspect one source plugin bundle')
|
|
1089
1613
|
.argument('<plugin-directory>', 'source plugin directory')
|
|
1090
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default:
|
|
1614
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from plugin directory)')
|
|
1091
1615
|
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1092
1616
|
.option('--force', 'replace an existing generated output', false)
|
|
1093
1617
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1094
1618
|
.action(async (pluginDirectory, rawOptions) => {
|
|
1095
1619
|
try {
|
|
1620
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1621
|
+
cwd: path.resolve(cwd, pluginDirectory),
|
|
1622
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: path.resolve(cwd, rawOptions.workspaceRoot) }),
|
|
1623
|
+
mode: 'existing',
|
|
1624
|
+
});
|
|
1096
1625
|
await runPluginBuildCommand({
|
|
1097
|
-
|
|
1098
|
-
pluginDirectory,
|
|
1626
|
+
...workspace,
|
|
1627
|
+
pluginDirectory: path.resolve(cwd, pluginDirectory),
|
|
1099
1628
|
out: rawOptions.out,
|
|
1100
1629
|
force: rawOptions.force,
|
|
1101
1630
|
json: rawOptions.json,
|
|
@@ -1117,15 +1646,7 @@ export function buildProgram(options = {}) {
|
|
|
1117
1646
|
.option('--all', 'check every current Catalog Workspace plugin', false)
|
|
1118
1647
|
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1119
1648
|
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1120
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
|
|
1121
|
-
plugin
|
|
1122
|
-
.command('check-versions')
|
|
1123
|
-
.description('Deprecated alias for plugin status')
|
|
1124
|
-
.argument('[plugin-name]', 'one explicit plugin name')
|
|
1125
|
-
.option('--all', 'check every plugin changed relative to the Git base', false)
|
|
1126
|
-
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1127
|
-
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1128
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)');
|
|
1649
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1129
1650
|
skill
|
|
1130
1651
|
.command('validate')
|
|
1131
1652
|
.description('Validate one Agent Skill directory')
|
|
@@ -1139,7 +1660,7 @@ export function buildProgram(options = {}) {
|
|
|
1139
1660
|
catalog
|
|
1140
1661
|
.command('init')
|
|
1141
1662
|
.description('Initialize a local AW Catalog Workspace')
|
|
1142
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
|
|
1663
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor, then Git worktree root, then current directory)')
|
|
1143
1664
|
.option('--owner-name <name>', 'catalog owner name')
|
|
1144
1665
|
.option('--owner-url <url>', 'catalog owner URL')
|
|
1145
1666
|
.option('--display-name <name>', 'catalog display name')
|
|
@@ -1148,9 +1669,15 @@ export function buildProgram(options = {}) {
|
|
|
1148
1669
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1149
1670
|
.action(async (rawOptions) => {
|
|
1150
1671
|
try {
|
|
1672
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1673
|
+
cwd,
|
|
1674
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1675
|
+
mode: 'initialize',
|
|
1676
|
+
env,
|
|
1677
|
+
});
|
|
1151
1678
|
await runCatalogInitCommand({
|
|
1152
1679
|
...rawOptions,
|
|
1153
|
-
|
|
1680
|
+
...workspace,
|
|
1154
1681
|
io,
|
|
1155
1682
|
});
|
|
1156
1683
|
}
|
|
@@ -1167,12 +1694,17 @@ export function buildProgram(options = {}) {
|
|
|
1167
1694
|
.description('Read or set the Catalog version')
|
|
1168
1695
|
.argument('[version]', 'stable or x.y.z-beta.N catalog version')
|
|
1169
1696
|
.option('--bump <level>', 'bump the stable SemVer base: patch, minor, or major')
|
|
1170
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
|
|
1697
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1171
1698
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1172
1699
|
.action(async (version, rawOptions) => {
|
|
1173
1700
|
try {
|
|
1701
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1702
|
+
cwd,
|
|
1703
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1704
|
+
mode: 'existing',
|
|
1705
|
+
});
|
|
1174
1706
|
await runCatalogVersionCommand({
|
|
1175
|
-
|
|
1707
|
+
...workspace,
|
|
1176
1708
|
version,
|
|
1177
1709
|
bump: rawOptions.bump,
|
|
1178
1710
|
json: rawOptions.json,
|
|
@@ -1190,14 +1722,19 @@ export function buildProgram(options = {}) {
|
|
|
1190
1722
|
catalog
|
|
1191
1723
|
.command('build')
|
|
1192
1724
|
.description('Build a deterministic development Catalog snapshot')
|
|
1193
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
|
|
1725
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1194
1726
|
.option('--out <path>', 'output path inside the Catalog Workspace')
|
|
1195
1727
|
.option('--force', 'replace an existing generated output', false)
|
|
1196
1728
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1197
1729
|
.action(async (rawOptions) => {
|
|
1198
1730
|
try {
|
|
1731
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
1732
|
+
cwd,
|
|
1733
|
+
...(rawOptions.workspaceRoot === undefined ? {} : { explicitRoot: rawOptions.workspaceRoot }),
|
|
1734
|
+
mode: 'existing',
|
|
1735
|
+
});
|
|
1199
1736
|
await runCatalogBuildCommand({
|
|
1200
|
-
|
|
1737
|
+
...workspace,
|
|
1201
1738
|
out: rawOptions.out,
|
|
1202
1739
|
force: rawOptions.force,
|
|
1203
1740
|
json: rawOptions.json,
|
|
@@ -1214,7 +1751,7 @@ export function buildProgram(options = {}) {
|
|
|
1214
1751
|
});
|
|
1215
1752
|
catalog
|
|
1216
1753
|
.command('validate')
|
|
1217
|
-
.description('Validate a schema
|
|
1754
|
+
.description('Validate a schema 7 Catalog snapshot')
|
|
1218
1755
|
.argument('<snapshot-directory>', 'Catalog snapshot directory')
|
|
1219
1756
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1220
1757
|
.action(async (snapshotDirectory, rawOptions) => {
|
|
@@ -1235,18 +1772,13 @@ export function buildProgram(options = {}) {
|
|
|
1235
1772
|
});
|
|
1236
1773
|
catalog
|
|
1237
1774
|
.command('status')
|
|
1238
|
-
.description('Inspect
|
|
1239
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: current directory)')
|
|
1240
|
-
.option('--remote <name>', 'configured Git remote name for preflight (default: origin)')
|
|
1241
|
-
.option('--branch <name>', 'dedicated Catalog branch for preflight (default: catalog)')
|
|
1242
|
-
.option('--preflight', 'run publication validation and temporary plugin builds (executes plugin code)', false)
|
|
1775
|
+
.description('Inspect static Catalog Workspace, snapshot, and Git facts')
|
|
1776
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1243
1777
|
.option('--json', 'emit one machine-readable JSON status object', false)
|
|
1244
1778
|
.action(async (rawOptions) => {
|
|
1245
1779
|
const receipt = await getCatalogStatus({
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
branch: rawOptions.branch,
|
|
1249
|
-
preflight: rawOptions.preflight,
|
|
1780
|
+
cwd,
|
|
1781
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1250
1782
|
env,
|
|
1251
1783
|
});
|
|
1252
1784
|
if (rawOptions.json)
|
|
@@ -1255,23 +1787,74 @@ export function buildProgram(options = {}) {
|
|
|
1255
1787
|
io.stdout(renderCatalogStatus(receipt));
|
|
1256
1788
|
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1257
1789
|
});
|
|
1258
|
-
catalog
|
|
1790
|
+
const catalogPublish = catalog
|
|
1259
1791
|
.command('publish')
|
|
1260
|
-
.description('
|
|
1261
|
-
|
|
1262
|
-
.
|
|
1792
|
+
.description('Plan or apply a versioned Catalog publication');
|
|
1793
|
+
catalogPublish
|
|
1794
|
+
.command('plan')
|
|
1795
|
+
.description('Prepare and inspect the exact Catalog publication plan')
|
|
1796
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1797
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
1263
1798
|
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
1264
|
-
.option('--expected-descriptor-digest <digest>', 'required exact descriptor returned by publication preflight')
|
|
1265
|
-
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
1266
1799
|
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1267
1800
|
.action(async (rawOptions) => {
|
|
1268
1801
|
try {
|
|
1269
|
-
const
|
|
1270
|
-
|
|
1271
|
-
workspaceRoot:
|
|
1802
|
+
const result = await runCatalogPublishPlanCommand({
|
|
1803
|
+
cwd,
|
|
1804
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1272
1805
|
remote: rawOptions.remote,
|
|
1273
1806
|
branch: rawOptions.branch,
|
|
1274
|
-
|
|
1807
|
+
env,
|
|
1808
|
+
io,
|
|
1809
|
+
});
|
|
1810
|
+
if (rawOptions.json)
|
|
1811
|
+
writeJsonReceipt(io.stdout, result);
|
|
1812
|
+
else {
|
|
1813
|
+
writeLine(io.stdout, `Workspace identity: ${result.workspaceIdentity}`);
|
|
1814
|
+
writeLine(io.stdout, `Source HEAD: ${result.sourceHead}`);
|
|
1815
|
+
writeLine(io.stdout, `Remote identity: ${result.descriptor.remote.identityDigest}`);
|
|
1816
|
+
writeLine(io.stdout, `Remote: ${result.remote} (${result.remoteUrl})`);
|
|
1817
|
+
writeLine(io.stdout, `Branch: refs/heads/${result.branch}`);
|
|
1818
|
+
writeLine(io.stdout, `Parent: ${result.parent ?? '<root>'}`);
|
|
1819
|
+
writeLine(io.stdout, `Tag: refs/tags/${result.tag}`);
|
|
1820
|
+
writeLine(io.stdout, `Snapshot digest: ${result.snapshotDigest}`);
|
|
1821
|
+
writeLine(io.stdout, `Expected commit: ${result.expectedCommit}`);
|
|
1822
|
+
writeLine(io.stdout, `Plan digest: ${result.planDigest}`);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1825
|
+
catch (error) {
|
|
1826
|
+
const failure = catalogPublicationFailure({
|
|
1827
|
+
error,
|
|
1828
|
+
env,
|
|
1829
|
+
sensitiveRoots: [
|
|
1830
|
+
cwd,
|
|
1831
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
1832
|
+
],
|
|
1833
|
+
});
|
|
1834
|
+
if (rawOptions.json)
|
|
1835
|
+
writeJsonReceipt(io.stdout, failure);
|
|
1836
|
+
writeLine(io.stderr, failure.message);
|
|
1837
|
+
commandExitState.exitCode = 1;
|
|
1838
|
+
}
|
|
1839
|
+
});
|
|
1840
|
+
catalogPublish
|
|
1841
|
+
.command('apply')
|
|
1842
|
+
.description('Apply an authorized Catalog publication plan')
|
|
1843
|
+
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1844
|
+
.option('--remote <name>', 'Git remote (default: origin, otherwise sole remote; explicit if ambiguous)')
|
|
1845
|
+
.option('--branch <name>', 'dedicated Catalog branch (default: catalog)')
|
|
1846
|
+
.requiredOption('--expected-plan-digest <sha256>', 'exact plan digest returned by catalog publish plan')
|
|
1847
|
+
.option('-y, --yes', 'confirm publication without a prompt', false)
|
|
1848
|
+
.option('--json', 'emit one machine-readable JSON result', false)
|
|
1849
|
+
.action(async (rawOptions) => {
|
|
1850
|
+
try {
|
|
1851
|
+
const context = createActionContext('catalog:publish:apply', {});
|
|
1852
|
+
const result = await runCatalogPublishApplyCommand({
|
|
1853
|
+
cwd,
|
|
1854
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1855
|
+
remote: rawOptions.remote,
|
|
1856
|
+
branch: rawOptions.branch,
|
|
1857
|
+
expectedPlanDigest: rawOptions.expectedPlanDigest,
|
|
1275
1858
|
yes: rawOptions.yes,
|
|
1276
1859
|
json: rawOptions.json,
|
|
1277
1860
|
env,
|
|
@@ -1297,14 +1880,95 @@ export function buildProgram(options = {}) {
|
|
|
1297
1880
|
}
|
|
1298
1881
|
}
|
|
1299
1882
|
catch (error) {
|
|
1300
|
-
const
|
|
1883
|
+
const failure = catalogPublicationFailure({
|
|
1884
|
+
error,
|
|
1885
|
+
env,
|
|
1886
|
+
sensitiveRoots: [
|
|
1887
|
+
cwd,
|
|
1888
|
+
...(rawOptions.workspaceRoot ? [path.resolve(cwd, rawOptions.workspaceRoot)] : []),
|
|
1889
|
+
],
|
|
1890
|
+
});
|
|
1301
1891
|
if (rawOptions.json)
|
|
1302
|
-
writeJsonReceipt(io.stdout,
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1892
|
+
writeJsonReceipt(io.stdout, failure);
|
|
1893
|
+
writeLine(io.stderr, failure.message);
|
|
1894
|
+
commandExitState.exitCode = 1;
|
|
1895
|
+
}
|
|
1896
|
+
});
|
|
1897
|
+
const catalogDev = catalog
|
|
1898
|
+
.command('dev')
|
|
1899
|
+
.description('Manage the current Catalog Workspace development source');
|
|
1900
|
+
catalogDev
|
|
1901
|
+
.command('activate')
|
|
1902
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
1903
|
+
.option('--source-id <id>', 'explicit managed source ID')
|
|
1904
|
+
.option('--primary', 'make the development source primary', false)
|
|
1905
|
+
.option('--force-build', 'rebuild a current snapshot', false)
|
|
1906
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
1907
|
+
.requiredOption('--json', 'emit one schema 2 JSON receipt')
|
|
1908
|
+
.action(async (rawOptions) => {
|
|
1909
|
+
try {
|
|
1910
|
+
const receipt = await activateCatalogDevSource({
|
|
1911
|
+
cwd,
|
|
1912
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1913
|
+
sourceId: rawOptions.sourceId,
|
|
1914
|
+
primary: rawOptions.primary,
|
|
1915
|
+
forceBuild: rawOptions.forceBuild,
|
|
1916
|
+
yes: rawOptions.yes,
|
|
1917
|
+
cliVersion: resolveCliVersion(),
|
|
1918
|
+
env,
|
|
1919
|
+
});
|
|
1920
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1921
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1922
|
+
}
|
|
1923
|
+
catch (error) {
|
|
1924
|
+
const failure = catalogDevSourceError(error);
|
|
1925
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
1926
|
+
command: 'activate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
1927
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
1928
|
+
}));
|
|
1929
|
+
commandExitState.exitCode = 1;
|
|
1930
|
+
}
|
|
1931
|
+
});
|
|
1932
|
+
catalogDev
|
|
1933
|
+
.command('status')
|
|
1934
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
1935
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
1936
|
+
.action(async (rawOptions) => {
|
|
1937
|
+
const receipt = await getCatalogDevSourceStatus({
|
|
1938
|
+
cwd,
|
|
1939
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1940
|
+
cliVersion: resolveCliVersion(),
|
|
1941
|
+
env,
|
|
1942
|
+
});
|
|
1943
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1944
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1945
|
+
});
|
|
1946
|
+
catalogDev
|
|
1947
|
+
.command('deactivate')
|
|
1948
|
+
.option('--workspace-root <path>', 'explicit Catalog Workspace root')
|
|
1949
|
+
.option('--source-id <id>', 'recover one managed source by exact ID')
|
|
1950
|
+
.option('--replacement-primary <id>', 'replacement when the target source is primary')
|
|
1951
|
+
.option('-y, --yes', 'confirm source impact or recovery by source ID', false)
|
|
1952
|
+
.requiredOption('--json', 'emit one schema 4 JSON receipt')
|
|
1953
|
+
.action(async (rawOptions) => {
|
|
1954
|
+
try {
|
|
1955
|
+
const receipt = await deactivateCatalogDevSource({
|
|
1956
|
+
cwd,
|
|
1957
|
+
workspaceRoot: rawOptions.workspaceRoot,
|
|
1958
|
+
sourceId: rawOptions.sourceId,
|
|
1959
|
+
replacementPrimary: rawOptions.replacementPrimary,
|
|
1960
|
+
yes: rawOptions.yes,
|
|
1961
|
+
env,
|
|
1962
|
+
});
|
|
1963
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
1964
|
+
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1965
|
+
}
|
|
1966
|
+
catch (error) {
|
|
1967
|
+
const failure = catalogDevSourceError(error);
|
|
1968
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
1969
|
+
command: 'deactivate', cwd, workspaceRoot: rawOptions.workspaceRoot,
|
|
1970
|
+
sourceId: rawOptions.sourceId, ...failure,
|
|
1971
|
+
}));
|
|
1308
1972
|
commandExitState.exitCode = 1;
|
|
1309
1973
|
}
|
|
1310
1974
|
});
|
|
@@ -1316,52 +1980,70 @@ export function buildProgram(options = {}) {
|
|
|
1316
1980
|
const message = failure instanceof Error ? failure.message : String(error);
|
|
1317
1981
|
if (json) {
|
|
1318
1982
|
writeJsonReceipt(io.stdout, {
|
|
1319
|
-
receiptSchemaVersion:
|
|
1983
|
+
receiptSchemaVersion: 6,
|
|
1320
1984
|
command,
|
|
1321
1985
|
ok: false,
|
|
1322
1986
|
changed: false,
|
|
1323
1987
|
sourceId,
|
|
1324
|
-
|
|
1988
|
+
primaryChange: failure.impact?.primaryChange ?? null,
|
|
1989
|
+
references: failure.impact?.references ?? failure.inventory?.references ?? [],
|
|
1325
1990
|
errors: [{ code: failure.code ?? failure.name ?? 'catalogSourceMutationFailed', message }],
|
|
1326
1991
|
});
|
|
1327
1992
|
}
|
|
1328
1993
|
writeLine(io.stderr, message);
|
|
1329
1994
|
commandExitState.exitCode = 1;
|
|
1330
1995
|
};
|
|
1331
|
-
const
|
|
1332
|
-
const
|
|
1333
|
-
const
|
|
1334
|
-
|
|
1335
|
-
: message.includes('sourceChanged')
|
|
1336
|
-
? 'sourceChanged'
|
|
1337
|
-
: message.includes('sourceMissing')
|
|
1338
|
-
? 'sourceMissing'
|
|
1339
|
-
: message.startsWith('Cannot resolve required catalog sources:')
|
|
1340
|
-
? 'catalogSourceUnavailable'
|
|
1341
|
-
: message.split(':', 1)[0] || 'configMutationFailed';
|
|
1342
|
-
if (json && !message.includes('Usage:')) {
|
|
1996
|
+
const writeCatalogGenerationFailure = (command, sourceId, json, error) => {
|
|
1997
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
1998
|
+
const message = redactString(failure.message);
|
|
1999
|
+
if (json) {
|
|
1343
2000
|
writeJsonReceipt(io.stdout, {
|
|
1344
|
-
|
|
2001
|
+
...(command === 'catalog:source:sync'
|
|
2002
|
+
? { catalogGenerationSchemaVersion: 1 }
|
|
2003
|
+
: { catalogGenerationStatusSchemaVersion: 2 }),
|
|
1345
2004
|
command,
|
|
1346
2005
|
ok: false,
|
|
1347
|
-
|
|
1348
|
-
...(
|
|
1349
|
-
errors: [{ code, message }],
|
|
2006
|
+
...(sourceId ? { sourceId } : {}),
|
|
2007
|
+
...(failure.impact ? { impact: failure.impact } : {}),
|
|
2008
|
+
errors: [{ code: catalogGenerationErrorCode(error), message }],
|
|
1350
2009
|
});
|
|
1351
2010
|
}
|
|
1352
2011
|
writeLine(io.stderr, message);
|
|
1353
2012
|
commandExitState.exitCode = 1;
|
|
1354
2013
|
};
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
2014
|
+
const writeConfigMutationFailure = (command, plugin, json, error) => {
|
|
2015
|
+
const failure = configMutationFailure(error, env, cwd);
|
|
2016
|
+
if (json) {
|
|
2017
|
+
writeConfigMutationFailureReceipt(io.stdout, {
|
|
2018
|
+
command,
|
|
2019
|
+
...(plugin ? { plugin } : {}),
|
|
2020
|
+
}, failure);
|
|
2021
|
+
}
|
|
2022
|
+
const message = json
|
|
2023
|
+
? failure.message
|
|
2024
|
+
: redactString(sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), env, [cwd]));
|
|
2025
|
+
writeLine(io.stderr, message);
|
|
2026
|
+
commandExitState.exitCode = 1;
|
|
2027
|
+
};
|
|
2028
|
+
const withResolvedConfigMutationPlugin = (context, selector, consume) => (async () => {
|
|
2029
|
+
const parsed = parsePluginId(selector);
|
|
2030
|
+
return withAwHomeMutationLock({
|
|
1361
2031
|
env: context.env,
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
2032
|
+
action: async (awHomeMutationToken) => {
|
|
2033
|
+
const catalogOperationContext = await resolveCatalogOperationContext({
|
|
2034
|
+
...(parsed.sourceId ? { sourceIds: [parsed.sourceId] } : {}),
|
|
2035
|
+
env: context.env,
|
|
2036
|
+
});
|
|
2037
|
+
return withResolvedCatalogPlugin({
|
|
2038
|
+
selector,
|
|
2039
|
+
cliVersion: resolveCliVersion(),
|
|
2040
|
+
operationContext: catalogOperationContext,
|
|
2041
|
+
env: context.env,
|
|
2042
|
+
consume: (resolution) => consume(resolution, awHomeMutationToken, catalogOperationContext),
|
|
2043
|
+
});
|
|
2044
|
+
},
|
|
2045
|
+
});
|
|
2046
|
+
})();
|
|
1365
2047
|
catalogSource
|
|
1366
2048
|
.command('list')
|
|
1367
2049
|
.option('-j, --json', 'print catalog sources as JSON', false)
|
|
@@ -1376,6 +2058,70 @@ export function buildProgram(options = {}) {
|
|
|
1376
2058
|
writeLine(io.stdout, `${source.primary ? '*' : '-'} ${source.id} ${source.type} ${source.sourceIdentity}`);
|
|
1377
2059
|
}
|
|
1378
2060
|
});
|
|
2061
|
+
catalogSource
|
|
2062
|
+
.command('sync')
|
|
2063
|
+
.argument('<id>')
|
|
2064
|
+
.option('--check', 'fetch and validate without changing the Catalog store or Active state', false)
|
|
2065
|
+
.option('--replace-damaged', 'replace a damaged Active entry with the current candidate', false)
|
|
2066
|
+
.option('-y, --yes', 'confirm affected, unknown, or damaged Active replacement impact', false)
|
|
2067
|
+
.option('-j, --json', 'print the source sync result as JSON', false)
|
|
2068
|
+
.action(async (id, rawOptions) => {
|
|
2069
|
+
try {
|
|
2070
|
+
if (rawOptions.check && rawOptions.replaceDamaged) {
|
|
2071
|
+
throw new Error('catalog source sync --check cannot use --replace-damaged.');
|
|
2072
|
+
}
|
|
2073
|
+
const result = await syncCatalogSourceCommand({
|
|
2074
|
+
sourceId: id,
|
|
2075
|
+
cliVersion: resolveCliVersion(),
|
|
2076
|
+
cwd,
|
|
2077
|
+
check: rawOptions.check === true,
|
|
2078
|
+
impactConfirmed: rawOptions.yes === true,
|
|
2079
|
+
replaceDamaged: rawOptions.replaceDamaged === true,
|
|
2080
|
+
env,
|
|
2081
|
+
});
|
|
2082
|
+
if (rawOptions.json) {
|
|
2083
|
+
writeJsonReceipt(io.stdout, {
|
|
2084
|
+
...result,
|
|
2085
|
+
command: 'catalog:source:sync',
|
|
2086
|
+
ok: true,
|
|
2087
|
+
});
|
|
2088
|
+
}
|
|
2089
|
+
else {
|
|
2090
|
+
writeLine(io.stdout, rawOptions.check
|
|
2091
|
+
? `Catalog source ${id} is valid.`
|
|
2092
|
+
: `Catalog source ${id}: ${result.outcome}.`);
|
|
2093
|
+
}
|
|
2094
|
+
}
|
|
2095
|
+
catch (error) {
|
|
2096
|
+
writeCatalogGenerationFailure('catalog:source:sync', id, rawOptions.json === true, error);
|
|
2097
|
+
}
|
|
2098
|
+
});
|
|
2099
|
+
catalogSource
|
|
2100
|
+
.command('status')
|
|
2101
|
+
.argument('[id]')
|
|
2102
|
+
.option('-j, --json', 'print offline Catalog source status schema 2 as JSON', false)
|
|
2103
|
+
.action(async (id, rawOptions) => {
|
|
2104
|
+
try {
|
|
2105
|
+
const result = await catalogSourceStatusCommand({ sourceId: id, env });
|
|
2106
|
+
if (rawOptions.json) {
|
|
2107
|
+
writeJsonReceipt(io.stdout, result);
|
|
2108
|
+
}
|
|
2109
|
+
else {
|
|
2110
|
+
for (const source of result.sources) {
|
|
2111
|
+
const active = source.active
|
|
2112
|
+
? `Active ${source.active.snapshotDigest}`
|
|
2113
|
+
: 'no Active';
|
|
2114
|
+
const readiness = source.compatibility?.state === 'unsupported'
|
|
2115
|
+
? `incompatible (required: ${source.compatibility.requiredCapabilities.join(', ')}; missing: ${source.compatibility.missingCapabilities.join(', ')})`
|
|
2116
|
+
: source.activeReady ? 'ready' : 'not ready';
|
|
2117
|
+
writeLine(io.stdout, `${source.sourceId}: ${active}, ${readiness}`);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
}
|
|
2121
|
+
catch (error) {
|
|
2122
|
+
writeCatalogGenerationFailure('catalog:source:status', id, rawOptions.json === true, error);
|
|
2123
|
+
}
|
|
2124
|
+
});
|
|
1379
2125
|
catalogSource
|
|
1380
2126
|
.command('add')
|
|
1381
2127
|
.argument('<id>')
|
|
@@ -1384,7 +2130,9 @@ export function buildProgram(options = {}) {
|
|
|
1384
2130
|
.addOption(new Option('--ref <ref>', 'use an explicit Git ref'))
|
|
1385
2131
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1386
2132
|
.option('--subdir <path>', 'use a catalog snapshot below the Git repository root')
|
|
2133
|
+
.option('--no-auto-check', 'disable automatic update checks for this source')
|
|
1387
2134
|
.option('--primary', 'make this source primary', false)
|
|
2135
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1388
2136
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1389
2137
|
.action(async (id, rawOptions) => {
|
|
1390
2138
|
try {
|
|
@@ -1395,7 +2143,7 @@ export function buildProgram(options = {}) {
|
|
|
1395
2143
|
throw new Error('Git catalog source add requires exactly one of `--ref` or `--default-ref`.');
|
|
1396
2144
|
}
|
|
1397
2145
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined)) {
|
|
1398
|
-
throw new Error('Path catalog source add only accepts `--path
|
|
2146
|
+
throw new Error('Path catalog source add only accepts `--path`, `--primary`, `--no-auto-check`, and `--yes`.');
|
|
1399
2147
|
}
|
|
1400
2148
|
const source = rawOptions.git !== undefined
|
|
1401
2149
|
? {
|
|
@@ -1405,18 +2153,32 @@ export function buildProgram(options = {}) {
|
|
|
1405
2153
|
url: rawOptions.git,
|
|
1406
2154
|
refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true),
|
|
1407
2155
|
...(rawOptions.subdir ? { subdir: rawOptions.subdir } : {}),
|
|
2156
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1408
2157
|
}
|
|
1409
2158
|
: {
|
|
1410
2159
|
id,
|
|
1411
2160
|
type: 'path',
|
|
1412
2161
|
primary: rawOptions.primary === true,
|
|
1413
2162
|
path: rawOptions.path,
|
|
2163
|
+
...(rawOptions.autoCheck === false ? { autoCheck: false } : {}),
|
|
1414
2164
|
};
|
|
2165
|
+
const preview = source.primary
|
|
2166
|
+
? await preflightCatalogSourceMutation({
|
|
2167
|
+
request: { action: 'add', source }, cwd, env,
|
|
2168
|
+
})
|
|
2169
|
+
: undefined;
|
|
1415
2170
|
const receipt = await addCatalogSourceCommand({
|
|
1416
2171
|
source,
|
|
1417
2172
|
cliVersion: resolveCliVersion(),
|
|
1418
2173
|
cwd,
|
|
1419
2174
|
env,
|
|
2175
|
+
...(preview ? {
|
|
2176
|
+
expectedConfigDigest: preview.configDigest,
|
|
2177
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2178
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2179
|
+
} : {}),
|
|
2180
|
+
requireImpactConfirmation: true,
|
|
2181
|
+
confirmImpact: rawOptions.yes === true,
|
|
1420
2182
|
});
|
|
1421
2183
|
if (rawOptions.json)
|
|
1422
2184
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1438,6 +2200,9 @@ export function buildProgram(options = {}) {
|
|
|
1438
2200
|
.addOption(new Option('--default-ref', 'select the Git ref from the CLI release channel'))
|
|
1439
2201
|
.addOption(new Option('--subdir <path>', 'update the Git catalog subdirectory'))
|
|
1440
2202
|
.addOption(new Option('--no-subdir', 'remove the Git catalog subdirectory'))
|
|
2203
|
+
.addOption(new Option('--auto-check', 'enable automatic update checks for this source'))
|
|
2204
|
+
.addOption(new Option('--no-auto-check', 'disable automatic update checks for this source'))
|
|
2205
|
+
.option('-y, --yes', 'confirm a source identity change', false)
|
|
1441
2206
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1442
2207
|
.action(async (id, rawOptions) => {
|
|
1443
2208
|
try {
|
|
@@ -1451,15 +2216,25 @@ export function buildProgram(options = {}) {
|
|
|
1451
2216
|
|| rawOptions.path !== undefined
|
|
1452
2217
|
|| rawOptions.ref !== undefined
|
|
1453
2218
|
|| rawOptions.defaultRef === true
|
|
1454
|
-
|| rawOptions.subdir !== undefined
|
|
2219
|
+
|| rawOptions.subdir !== undefined
|
|
2220
|
+
|| rawOptions.autoCheck !== undefined;
|
|
1455
2221
|
if (!hasUpdate)
|
|
1456
2222
|
throw new Error('catalog source update requires at least one update option.');
|
|
1457
2223
|
if (rawOptions.path !== undefined && (rawOptions.ref !== undefined || rawOptions.defaultRef === true || rawOptions.subdir !== undefined))
|
|
1458
|
-
throw new Error('Path catalog source update only accepts `--path
|
|
2224
|
+
throw new Error('Path catalog source update only accepts `--path` and auto-check options.');
|
|
2225
|
+
const hasGitUpdate = rawOptions.git !== undefined
|
|
2226
|
+
|| rawOptions.ref !== undefined
|
|
2227
|
+
|| rawOptions.defaultRef === true
|
|
2228
|
+
|| rawOptions.subdir !== undefined;
|
|
1459
2229
|
const update = rawOptions.path !== undefined
|
|
1460
|
-
? {
|
|
1461
|
-
|
|
2230
|
+
? {
|
|
2231
|
+
type: 'path',
|
|
2232
|
+
path: rawOptions.path,
|
|
2233
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
2234
|
+
}
|
|
2235
|
+
: hasGitUpdate ? {
|
|
1462
2236
|
type: 'git',
|
|
2237
|
+
...(rawOptions.autoCheck !== undefined ? { autoCheck: rawOptions.autoCheck } : {}),
|
|
1463
2238
|
...(rawOptions.git !== undefined ? { url: rawOptions.git } : {}),
|
|
1464
2239
|
...(rawOptions.ref !== undefined || rawOptions.defaultRef === true
|
|
1465
2240
|
? { refPolicy: explicitRefPolicy(rawOptions.ref, rawOptions.defaultRef === true) }
|
|
@@ -1467,13 +2242,22 @@ export function buildProgram(options = {}) {
|
|
|
1467
2242
|
...(rawOptions.subdir !== undefined
|
|
1468
2243
|
? { subdir: rawOptions.subdir === false ? null : rawOptions.subdir }
|
|
1469
2244
|
: {}),
|
|
1470
|
-
}
|
|
2245
|
+
}
|
|
2246
|
+
: { autoCheck: rawOptions.autoCheck };
|
|
2247
|
+
const preview = await preflightCatalogSourceMutation({
|
|
2248
|
+
request: { action: 'update', sourceId: id, update }, cwd, env,
|
|
2249
|
+
});
|
|
1471
2250
|
const receipt = await updateCatalogSourceCommand({
|
|
1472
2251
|
sourceId: id,
|
|
1473
2252
|
update,
|
|
1474
2253
|
cliVersion: resolveCliVersion(),
|
|
1475
2254
|
cwd,
|
|
1476
2255
|
env,
|
|
2256
|
+
expectedConfigDigest: preview.configDigest,
|
|
2257
|
+
expectedProposedConfigDigest: preview.proposedConfigDigest,
|
|
2258
|
+
expectedImpactDigest: preview.impactDigest,
|
|
2259
|
+
requireIdentityChangeConfirmation: true,
|
|
2260
|
+
confirmIdentityChange: rawOptions.yes === true,
|
|
1477
2261
|
});
|
|
1478
2262
|
if (rawOptions.json)
|
|
1479
2263
|
writeJsonReceipt(io.stdout, receipt);
|
|
@@ -1489,10 +2273,17 @@ export function buildProgram(options = {}) {
|
|
|
1489
2273
|
catalogSource
|
|
1490
2274
|
.command('set-primary')
|
|
1491
2275
|
.argument('<id>')
|
|
2276
|
+
.option('-y, --yes', 'confirm affected or unknown primary source references', false)
|
|
1492
2277
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1493
2278
|
.action(async (id, rawOptions) => {
|
|
1494
2279
|
try {
|
|
1495
|
-
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2280
|
+
const receipt = await setPrimaryCatalogSourceCommand({
|
|
2281
|
+
sourceId: id,
|
|
2282
|
+
cwd,
|
|
2283
|
+
env,
|
|
2284
|
+
requireImpactConfirmation: true,
|
|
2285
|
+
confirmImpact: rawOptions.yes === true,
|
|
2286
|
+
});
|
|
1496
2287
|
if (rawOptions.json)
|
|
1497
2288
|
writeJsonReceipt(io.stdout, receipt);
|
|
1498
2289
|
else
|
|
@@ -1505,10 +2296,17 @@ export function buildProgram(options = {}) {
|
|
|
1505
2296
|
catalogSource
|
|
1506
2297
|
.command('remove')
|
|
1507
2298
|
.argument('<id>')
|
|
2299
|
+
.option('-y, --yes', 'confirm affected or unknown source references', false)
|
|
1508
2300
|
.option('-j, --json', 'print mutation receipt as JSON', false)
|
|
1509
2301
|
.action(async (id, rawOptions) => {
|
|
1510
2302
|
try {
|
|
1511
|
-
const receipt = await removeCatalogSourceCommand({
|
|
2303
|
+
const receipt = await removeCatalogSourceCommand({
|
|
2304
|
+
sourceId: id,
|
|
2305
|
+
cwd,
|
|
2306
|
+
env,
|
|
2307
|
+
requireImpactConfirmation: true,
|
|
2308
|
+
confirmImpact: rawOptions.yes === true,
|
|
2309
|
+
});
|
|
1512
2310
|
if (rawOptions.json)
|
|
1513
2311
|
writeJsonReceipt(io.stdout, receipt);
|
|
1514
2312
|
else
|
|
@@ -1518,9 +2316,102 @@ export function buildProgram(options = {}) {
|
|
|
1518
2316
|
await writeCatalogSourceFailure('catalog:source:remove', id, rawOptions.json === true, error);
|
|
1519
2317
|
}
|
|
1520
2318
|
});
|
|
2319
|
+
const catalogStore = catalog
|
|
2320
|
+
.command('store')
|
|
2321
|
+
.description('Inspect or prune the immutable Catalog store');
|
|
2322
|
+
catalogStore
|
|
2323
|
+
.command('status')
|
|
2324
|
+
.option('-j, --json', 'print Catalog store status as JSON', false)
|
|
2325
|
+
.action(async (rawOptions) => {
|
|
2326
|
+
try {
|
|
2327
|
+
const result = await catalogStoreStatus({ env });
|
|
2328
|
+
if (rawOptions.json) {
|
|
2329
|
+
writeJsonReceipt(io.stdout, result);
|
|
2330
|
+
}
|
|
2331
|
+
else if (result.entries.length === 0) {
|
|
2332
|
+
writeLine(io.stdout, 'Catalog store is empty.');
|
|
2333
|
+
}
|
|
2334
|
+
else {
|
|
2335
|
+
for (const entry of result.entries) {
|
|
2336
|
+
const bytes = entry.reclaimableBytes === null ? 'unknown bytes' : `${entry.reclaimableBytes} bytes`;
|
|
2337
|
+
writeLine(io.stdout, `${entry.storeKey}: ${entry.category}, ${entry.status}, ${entry.reason}, ${bytes}`);
|
|
2338
|
+
}
|
|
2339
|
+
writeLine(io.stdout, `Reclaimable: ${result.totals.reclaimableEntries} item(s).`);
|
|
2340
|
+
if (result.errors.length > 0) {
|
|
2341
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2342
|
+
}
|
|
2343
|
+
}
|
|
2344
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2345
|
+
}
|
|
2346
|
+
catch (error) {
|
|
2347
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2348
|
+
const message = redactString(failure.message);
|
|
2349
|
+
if (rawOptions.json)
|
|
2350
|
+
writeJsonReceipt(io.stdout, {
|
|
2351
|
+
catalogStoreSchemaVersion: 2,
|
|
2352
|
+
command: 'catalog:store:status',
|
|
2353
|
+
ok: false,
|
|
2354
|
+
entries: [],
|
|
2355
|
+
errors: [{ code: catalogStoreErrorCode(error), message }],
|
|
2356
|
+
});
|
|
2357
|
+
writeLine(io.stderr, message);
|
|
2358
|
+
commandExitState.exitCode = 1;
|
|
2359
|
+
}
|
|
2360
|
+
});
|
|
2361
|
+
catalogStore
|
|
2362
|
+
.command('prune')
|
|
2363
|
+
.option('--dry-run', 'inspect reclaimable items without deleting them', false)
|
|
2364
|
+
.option('-y, --yes', 'delete items classified as safely reclaimable', false)
|
|
2365
|
+
.option('-j, --json', 'print the prune receipt as JSON', false)
|
|
2366
|
+
.action(async (rawOptions) => {
|
|
2367
|
+
const dryRun = rawOptions.yes !== true;
|
|
2368
|
+
try {
|
|
2369
|
+
if (rawOptions.dryRun === true && rawOptions.yes === true) {
|
|
2370
|
+
throw Object.assign(new Error('catalog store prune cannot combine `--dry-run` and `--yes`.'), {
|
|
2371
|
+
code: 'invalidArguments',
|
|
2372
|
+
});
|
|
2373
|
+
}
|
|
2374
|
+
const result = await catalogStorePrune({ dryRun, env });
|
|
2375
|
+
if (rawOptions.json) {
|
|
2376
|
+
writeJsonReceipt(io.stdout, result);
|
|
2377
|
+
}
|
|
2378
|
+
else if (dryRun) {
|
|
2379
|
+
writeLine(io.stdout, `Dry run: ${result.entries.filter((entry) => entry.status === 'reclaimable').length} item(s) are reclaimable.`);
|
|
2380
|
+
writeLine(io.stdout, 'Run `aw catalog store prune --yes` to delete them.');
|
|
2381
|
+
if (result.errors.length > 0)
|
|
2382
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected and were retained.`);
|
|
2383
|
+
}
|
|
2384
|
+
else {
|
|
2385
|
+
writeLine(io.stdout, `Deleted ${result.deleted.length} Catalog store item(s) (${result.deletedBytes} bytes).`);
|
|
2386
|
+
if (result.errors.length > 0)
|
|
2387
|
+
writeLine(io.stderr, `${result.errors.length} item(s) could not be fully inspected or deleted and were retained.`);
|
|
2388
|
+
}
|
|
2389
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2390
|
+
}
|
|
2391
|
+
catch (error) {
|
|
2392
|
+
const failure = sanitizeCatalogSourceError(error, env);
|
|
2393
|
+
const message = redactString(failure.message);
|
|
2394
|
+
const code = catalogStoreErrorCode(error);
|
|
2395
|
+
if (rawOptions.json)
|
|
2396
|
+
writeJsonReceipt(io.stdout, {
|
|
2397
|
+
catalogStoreSchemaVersion: 2,
|
|
2398
|
+
command: 'catalog:store:prune',
|
|
2399
|
+
ok: false,
|
|
2400
|
+
overallState: 'failed',
|
|
2401
|
+
dryRun,
|
|
2402
|
+
entries: [],
|
|
2403
|
+
deleted: [],
|
|
2404
|
+
retained: [],
|
|
2405
|
+
errors: [{ code, message }],
|
|
2406
|
+
reclaimableBytes: null,
|
|
2407
|
+
deletedBytes: 0,
|
|
2408
|
+
});
|
|
2409
|
+
writeLine(io.stderr, message);
|
|
2410
|
+
commandExitState.exitCode = 1;
|
|
2411
|
+
}
|
|
2412
|
+
});
|
|
1521
2413
|
program
|
|
1522
2414
|
.command('init')
|
|
1523
|
-
.option('-f, --force', 're-fetch and rebuild the current catalog cache entry', false)
|
|
1524
2415
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1525
2416
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1526
2417
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1528,8 +2419,6 @@ export function buildProgram(options = {}) {
|
|
|
1528
2419
|
.action(async (rawOptions) => {
|
|
1529
2420
|
const context = createActionContext('init', rawOptions);
|
|
1530
2421
|
const result = await runActionWithContext(context, () => initCommand({
|
|
1531
|
-
force: rawOptions.force,
|
|
1532
|
-
cliVersion: resolveCliVersion(),
|
|
1533
2422
|
env: context.env,
|
|
1534
2423
|
}));
|
|
1535
2424
|
if (rawOptions.json) {
|
|
@@ -1540,7 +2429,6 @@ export function buildProgram(options = {}) {
|
|
|
1540
2429
|
writeLine(io.stdout, line);
|
|
1541
2430
|
}
|
|
1542
2431
|
}
|
|
1543
|
-
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1544
2432
|
for (const source of result.sources) {
|
|
1545
2433
|
if (!source.ok && source.error)
|
|
1546
2434
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
@@ -1548,53 +2436,79 @@ export function buildProgram(options = {}) {
|
|
|
1548
2436
|
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
1549
2437
|
});
|
|
1550
2438
|
program
|
|
1551
|
-
.command('
|
|
2439
|
+
.command('sync')
|
|
2440
|
+
.description('Reconcile actual state from existing desired intent')
|
|
1552
2441
|
.argument('[plugins...]')
|
|
1553
|
-
.
|
|
1554
|
-
.
|
|
1555
|
-
.option('
|
|
1556
|
-
.option('
|
|
2442
|
+
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
2443
|
+
.requiredOption('-p, --platform <platform>', 'codex, claude, or both')
|
|
2444
|
+
.option('-a, --all', 'reconcile every desired plugin in the selected scope', false)
|
|
2445
|
+
.option('--refresh', 'refresh only Catalog sources required by selected intent roots', false)
|
|
2446
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2447
|
+
.option('-y, --yes', 'authorize preApply and shared native replacement or forced repair', false)
|
|
2448
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2449
|
+
.option('-j, --json', 'print sync receipt as JSON', false)
|
|
1557
2450
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1558
2451
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1559
2452
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1560
2453
|
.action(async (plugins, rawOptions) => {
|
|
1561
|
-
const context = createActionContext('
|
|
1562
|
-
const
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
2454
|
+
const context = createActionContext('sync', rawOptions);
|
|
2455
|
+
const normalized = normalizeWriteRequest(() => normalizeInstallCommandOptions({
|
|
2456
|
+
cwd: context.cwd,
|
|
2457
|
+
scope: rawOptions.scope,
|
|
2458
|
+
platform: rawOptions.platform,
|
|
2459
|
+
scriptTimeout: rawOptions.scriptTimeout,
|
|
2460
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2461
|
+
}));
|
|
2462
|
+
const syncPlatform = normalized.platform;
|
|
2463
|
+
const result = await runActionWithContext(context, () => syncCommand(plugins ?? [], {
|
|
2464
|
+
cwd: context.cwd,
|
|
2465
|
+
env: context.env,
|
|
2466
|
+
platform: syncPlatform,
|
|
2467
|
+
scope: normalized.scope,
|
|
2468
|
+
all: rawOptions.all,
|
|
2469
|
+
refresh: rawOptions.refresh,
|
|
2470
|
+
cliVersion: resolveCliVersion(),
|
|
2471
|
+
yes: rawOptions.yes,
|
|
2472
|
+
json: rawOptions.json,
|
|
2473
|
+
interactive: context.interactive && context.isTty && !context.isCi,
|
|
2474
|
+
prompt: context.prompt,
|
|
2475
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2476
|
+
scriptTimeoutMs: normalized.scriptTimeoutMs,
|
|
2477
|
+
}, context));
|
|
1566
2478
|
if (rawOptions.json) {
|
|
1567
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2479
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('sync', result));
|
|
1568
2480
|
}
|
|
1569
2481
|
else {
|
|
1570
|
-
for (const line of renderRebuildReceipt('
|
|
2482
|
+
for (const line of renderRebuildReceipt('sync', result))
|
|
1571
2483
|
writeLine(io.stdout, line);
|
|
1572
|
-
}
|
|
1573
2484
|
}
|
|
1574
|
-
writeWarnings(io.stderr,
|
|
1575
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(
|
|
2485
|
+
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
2486
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1576
2487
|
});
|
|
1577
2488
|
program
|
|
1578
|
-
.command('
|
|
2489
|
+
.command('install')
|
|
1579
2490
|
.argument('[plugins...]')
|
|
1580
2491
|
.option('-s, --scope <scope>', 'project or user')
|
|
1581
2492
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1582
|
-
.option('--
|
|
2493
|
+
.option('--dependency-scope <pluginId[#platform]=scope>', 'place one dependency at project or user scope; repeat for more dependencies', (value, previous) => [...previous, value], [])
|
|
2494
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2495
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2496
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement', false)
|
|
1583
2497
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1584
2498
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1585
2499
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1586
2500
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1587
2501
|
.action(async (plugins, rawOptions) => {
|
|
1588
|
-
const context = createActionContext('
|
|
1589
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2502
|
+
const context = createActionContext('install', rawOptions);
|
|
2503
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('install', plugins ?? [], rawOptions, context));
|
|
1590
2504
|
if (outcome.cancelled)
|
|
1591
2505
|
return;
|
|
1592
2506
|
const receipt = outcome.result;
|
|
1593
2507
|
if (rawOptions.json) {
|
|
1594
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2508
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('install', receipt));
|
|
1595
2509
|
}
|
|
1596
2510
|
else {
|
|
1597
|
-
for (const line of renderRebuildReceipt('
|
|
2511
|
+
for (const line of renderRebuildReceipt('install', receipt)) {
|
|
1598
2512
|
writeLine(io.stdout, line);
|
|
1599
2513
|
}
|
|
1600
2514
|
}
|
|
@@ -1602,27 +2516,26 @@ export function buildProgram(options = {}) {
|
|
|
1602
2516
|
commandExitState.exitCode = resolveCommandReceiptExitCode(receipt);
|
|
1603
2517
|
});
|
|
1604
2518
|
program
|
|
1605
|
-
.command('
|
|
2519
|
+
.command('uninstall')
|
|
1606
2520
|
.argument('[plugins...]')
|
|
1607
|
-
.option('-a, --all', 'upgrade all plugins', false)
|
|
1608
2521
|
.option('-s, --scope <scope>', 'project or user')
|
|
1609
2522
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1610
|
-
.option('--
|
|
2523
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1611
2524
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1612
2525
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1613
2526
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1614
2527
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1615
2528
|
.action(async (plugins, rawOptions) => {
|
|
1616
|
-
const context = createActionContext('
|
|
1617
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('
|
|
2529
|
+
const context = createActionContext('uninstall', rawOptions);
|
|
2530
|
+
const outcome = await runActionWithContext(context, () => runWriteCommandAction('uninstall', plugins ?? [], rawOptions, context));
|
|
1618
2531
|
if (outcome.cancelled)
|
|
1619
2532
|
return;
|
|
1620
2533
|
const receipt = outcome.result;
|
|
1621
2534
|
if (rawOptions.json) {
|
|
1622
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('
|
|
2535
|
+
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('uninstall', receipt));
|
|
1623
2536
|
}
|
|
1624
2537
|
else {
|
|
1625
|
-
for (const line of renderRebuildReceipt('
|
|
2538
|
+
for (const line of renderRebuildReceipt('uninstall', receipt)) {
|
|
1626
2539
|
writeLine(io.stdout, line);
|
|
1627
2540
|
}
|
|
1628
2541
|
}
|
|
@@ -1635,7 +2548,9 @@ export function buildProgram(options = {}) {
|
|
|
1635
2548
|
.option('-s, --scope <scope>', 'project or user')
|
|
1636
2549
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1637
2550
|
.option('-j, --json', 'print cleanup result as JSON', false)
|
|
1638
|
-
.option('--force', '
|
|
2551
|
+
.option('--force', 'use exact shallow evidence for exclusively owned damaged output; preserve foreign/shared content; no deleted-plugin-wide cleanup', false)
|
|
2552
|
+
.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)
|
|
2553
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
1639
2554
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1640
2555
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1641
2556
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
@@ -1654,14 +2569,16 @@ export function buildProgram(options = {}) {
|
|
|
1654
2569
|
}
|
|
1655
2570
|
}
|
|
1656
2571
|
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
1657
|
-
commandExitState.exitCode = result
|
|
2572
|
+
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
1658
2573
|
});
|
|
1659
2574
|
program
|
|
1660
2575
|
.command('reinstall')
|
|
1661
2576
|
.argument('[plugins...]')
|
|
1662
2577
|
.option('-s, --scope <scope>', 'project or user')
|
|
1663
2578
|
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
1664
|
-
.option('--script-timeout <ms>', 'override plugin
|
|
2579
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2580
|
+
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2581
|
+
.option('-y, --yes', 'authorize preApply and shared Codex native replacement or forced reinstall', false)
|
|
1665
2582
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1666
2583
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1667
2584
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1691,7 +2608,6 @@ export function buildProgram(options = {}) {
|
|
|
1691
2608
|
.command('list')
|
|
1692
2609
|
.argument('[plugin]')
|
|
1693
2610
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1694
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1695
2611
|
.option('-j, --json', 'print config as JSON', false)
|
|
1696
2612
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1697
2613
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1699,9 +2615,7 @@ export function buildProgram(options = {}) {
|
|
|
1699
2615
|
.action(async (pluginName, rawOptions) => {
|
|
1700
2616
|
const context = createActionContext('config:list', rawOptions);
|
|
1701
2617
|
const outcome = await runActionWithContext(context, async () => {
|
|
1702
|
-
|
|
1703
|
-
if (!rawOptions.local)
|
|
1704
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2618
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1705
2619
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1706
2620
|
selector: selectedPlugin,
|
|
1707
2621
|
rawOptions,
|
|
@@ -1726,7 +2640,6 @@ export function buildProgram(options = {}) {
|
|
|
1726
2640
|
command: 'list',
|
|
1727
2641
|
plugin: selection.plugins[0],
|
|
1728
2642
|
scope: rawOptions.scope,
|
|
1729
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1730
2643
|
})),
|
|
1731
2644
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1732
2645
|
});
|
|
@@ -1748,8 +2661,7 @@ export function buildProgram(options = {}) {
|
|
|
1748
2661
|
pluginId: resolved.pluginId,
|
|
1749
2662
|
sourceId: resolved.sourceId,
|
|
1750
2663
|
sourceIdentity: resolved.sourceIdentity,
|
|
1751
|
-
scope: rawOptions.
|
|
1752
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2664
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1753
2665
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1754
2666
|
fields: resolved.result.fields,
|
|
1755
2667
|
});
|
|
@@ -1763,7 +2675,6 @@ export function buildProgram(options = {}) {
|
|
|
1763
2675
|
.argument('[plugin]')
|
|
1764
2676
|
.argument('[key]')
|
|
1765
2677
|
.option('-s, --scope <scope>', 'read only project or user config')
|
|
1766
|
-
.option('--local', 'read only the current project local override layer', false)
|
|
1767
2678
|
.option('-j, --json', 'print config as JSON', false)
|
|
1768
2679
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1769
2680
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1771,9 +2682,7 @@ export function buildProgram(options = {}) {
|
|
|
1771
2682
|
.action(async (pluginName, key, rawOptions) => {
|
|
1772
2683
|
const context = createActionContext('config:get', rawOptions);
|
|
1773
2684
|
const outcome = await runActionWithContext(context, async () => {
|
|
1774
|
-
|
|
1775
|
-
if (!rawOptions.local)
|
|
1776
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2685
|
+
resolveConfigReadResolution(rawOptions.scope);
|
|
1777
2686
|
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
1778
2687
|
selector: selectedPlugin,
|
|
1779
2688
|
...(key === undefined ? {} : { key }),
|
|
@@ -1800,7 +2709,6 @@ export function buildProgram(options = {}) {
|
|
|
1800
2709
|
plugin: selection.plugins[0],
|
|
1801
2710
|
key,
|
|
1802
2711
|
scope: rawOptions.scope,
|
|
1803
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
1804
2712
|
})),
|
|
1805
2713
|
execute: (selection) => execute(selection.plugins[0]),
|
|
1806
2714
|
});
|
|
@@ -1823,8 +2731,7 @@ export function buildProgram(options = {}) {
|
|
|
1823
2731
|
sourceId: resolved.sourceId,
|
|
1824
2732
|
sourceIdentity: resolved.sourceIdentity,
|
|
1825
2733
|
key,
|
|
1826
|
-
scope: rawOptions.
|
|
1827
|
-
projectLayer: rawOptions.local ? 'local' : 'shared',
|
|
2734
|
+
scope: rawOptions.scope ?? 'effective',
|
|
1828
2735
|
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
1829
2736
|
fields: resolved.result.fields,
|
|
1830
2737
|
});
|
|
@@ -1836,47 +2743,119 @@ export function buildProgram(options = {}) {
|
|
|
1836
2743
|
config
|
|
1837
2744
|
.command('set')
|
|
1838
2745
|
.argument('[plugin]')
|
|
1839
|
-
.argument('[
|
|
1840
|
-
.argument('[value]')
|
|
2746
|
+
.argument('[field]')
|
|
1841
2747
|
.option('-s, --scope <scope>', 'project or user')
|
|
1842
|
-
.option('--
|
|
1843
|
-
.option('--value-
|
|
2748
|
+
.option('--value-json <json>', 'set the field to an exact JSON value')
|
|
2749
|
+
.option('--value-stdin', 'read the exact string value from stdin until EOF', false)
|
|
2750
|
+
.option('--preset <id>', 'set the field to the current manifest preset value')
|
|
2751
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2752
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2753
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1844
2754
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1845
2755
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1846
2756
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
1847
2757
|
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
1848
|
-
.action(async (pluginName, key,
|
|
2758
|
+
.action(async (pluginName, key, rawOptions) => {
|
|
2759
|
+
if (!pluginName || !key)
|
|
2760
|
+
throw new Error(configCommandUsage('set'));
|
|
1849
2761
|
const context = createActionContext('config:set', rawOptions);
|
|
1850
2762
|
let outcome;
|
|
1851
2763
|
try {
|
|
1852
2764
|
outcome = await runActionWithContext(context, async () => {
|
|
1853
2765
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
1854
|
-
const
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
2766
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2767
|
+
const explicitValueCount = [
|
|
2768
|
+
rawOptions.valueJson !== undefined,
|
|
2769
|
+
rawOptions.valueStdin === true,
|
|
2770
|
+
rawOptions.preset !== undefined,
|
|
2771
|
+
].filter(Boolean).length;
|
|
2772
|
+
if (explicitValueCount > 1
|
|
2773
|
+
|| (explicitValueCount === 0
|
|
2774
|
+
&& !(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true))) {
|
|
2775
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2776
|
+
}
|
|
2777
|
+
return withResolvedConfigMutationPlugin(context, pluginName, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2778
|
+
if (!plugin.manifest.config?.fields) {
|
|
2779
|
+
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1858
2780
|
}
|
|
1859
|
-
|
|
1860
|
-
|
|
2781
|
+
const field = plugin.manifest.config.fields[key];
|
|
2782
|
+
if (!field) {
|
|
2783
|
+
throw new Error(`Unknown config key "${key}".`);
|
|
2784
|
+
}
|
|
2785
|
+
const sensitive = field.sensitive === true;
|
|
2786
|
+
if (sensitive && scope !== 'user') {
|
|
2787
|
+
const error = new Error('sensitiveProjectConfigUnsupported: Sensitive config can only be set in user scope.');
|
|
2788
|
+
error.code = 'sensitiveProjectConfigUnsupported';
|
|
2789
|
+
throw error;
|
|
2790
|
+
}
|
|
2791
|
+
if (sensitive && (rawOptions.valueJson !== undefined || rawOptions.preset !== undefined)) {
|
|
2792
|
+
const error = new Error('sensitiveConfigInputUnsupported: Sensitive config cannot use --value-json or --preset.');
|
|
2793
|
+
error.code = 'sensitiveConfigInputUnsupported';
|
|
2794
|
+
throw error;
|
|
2795
|
+
}
|
|
2796
|
+
if (!sensitive && explicitValueCount !== 1) {
|
|
2797
|
+
throw new Error('Use exactly one of --value-json <json>, --value-stdin, or --preset <id>.');
|
|
2798
|
+
}
|
|
2799
|
+
let inputValue;
|
|
2800
|
+
if (rawOptions.valueStdin === true) {
|
|
2801
|
+
inputValue = await readUtf8Stdin(context.stdin);
|
|
2802
|
+
}
|
|
2803
|
+
else if (sensitive) {
|
|
2804
|
+
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
2805
|
+
|| !context.prompt.password) {
|
|
2806
|
+
const error = new Error('sensitiveConfigStdinRequired: Use --value-stdin for sensitive config outside an interactive terminal.');
|
|
2807
|
+
error.code = 'sensitiveConfigStdinRequired';
|
|
2808
|
+
throw error;
|
|
2809
|
+
}
|
|
2810
|
+
const response = await context.prompt.password({
|
|
2811
|
+
message: `输入 ${field.title ?? key}`,
|
|
2812
|
+
mask: true,
|
|
2813
|
+
});
|
|
2814
|
+
if (response.cancelled || response.action !== 'select' || response.value === undefined) {
|
|
2815
|
+
const error = new Error('sensitiveConfigInputCancelled: Sensitive config input was cancelled.');
|
|
2816
|
+
error.code = 'sensitiveConfigInputCancelled';
|
|
2817
|
+
throw error;
|
|
2818
|
+
}
|
|
2819
|
+
inputValue = response.value;
|
|
2820
|
+
}
|
|
2821
|
+
else if (rawOptions.valueJson !== undefined) {
|
|
2822
|
+
try {
|
|
2823
|
+
inputValue = JSON.parse(rawOptions.valueJson);
|
|
2824
|
+
}
|
|
2825
|
+
catch {
|
|
2826
|
+
throw new Error('--value-json must contain valid JSON.');
|
|
2827
|
+
}
|
|
2828
|
+
}
|
|
2829
|
+
else {
|
|
2830
|
+
const preset = field.choices?.presets.find((entry) => entry.id === rawOptions.preset);
|
|
2831
|
+
if (!preset)
|
|
2832
|
+
throw new Error(`Unknown preset "${rawOptions.preset}" for config key "${key}".`);
|
|
2833
|
+
inputValue = structuredClone(preset.value);
|
|
1861
2834
|
}
|
|
1862
2835
|
const writeReceipt = await applyPluginConfigWrite({
|
|
1863
2836
|
plugin,
|
|
1864
2837
|
pluginName: plugin.manifest.name,
|
|
1865
2838
|
scope,
|
|
1866
|
-
projectLayer,
|
|
1867
2839
|
cwd: context.cwd,
|
|
1868
2840
|
env: context.env,
|
|
1869
2841
|
nativeCliRunner: context.nativeCliRunner,
|
|
1870
|
-
rebuildRuntime: {
|
|
2842
|
+
rebuildRuntime: {
|
|
2843
|
+
...context,
|
|
2844
|
+
awHomeMutationToken,
|
|
2845
|
+
catalogOperationContext,
|
|
2846
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
2847
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
2848
|
+
},
|
|
1871
2849
|
awHomeMutationToken,
|
|
1872
2850
|
request: {
|
|
1873
|
-
updates: { [
|
|
2851
|
+
updates: { [key]: inputValue },
|
|
1874
2852
|
},
|
|
2853
|
+
apply: rawOptions.apply === true,
|
|
2854
|
+
sharedNativeApplyConfirmed: rawOptions.yes === true,
|
|
2855
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
1875
2856
|
});
|
|
1876
|
-
return {
|
|
2857
|
+
return buildConfigMutationReceipt('config:set', {
|
|
1877
2858
|
ok: writeReceipt.overallState === 'succeeded',
|
|
1878
|
-
receiptSchemaVersion: 4,
|
|
1879
|
-
command: 'config:set',
|
|
1880
2859
|
...writeReceipt,
|
|
1881
2860
|
plugin: plugin.manifest.name,
|
|
1882
2861
|
pluginName: plugin.manifest.name,
|
|
@@ -1884,104 +2863,39 @@ export function buildProgram(options = {}) {
|
|
|
1884
2863
|
sourceId: source.sourceId,
|
|
1885
2864
|
sourceIdentity: source.sourceIdentity,
|
|
1886
2865
|
affectedFields: [{
|
|
1887
|
-
key
|
|
1888
|
-
title:
|
|
2866
|
+
key,
|
|
2867
|
+
title: field.title ?? key,
|
|
1889
2868
|
kind: 'manifest',
|
|
1890
2869
|
reserved: false,
|
|
1891
2870
|
action: 'set',
|
|
1892
2871
|
scope,
|
|
1893
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
1894
2872
|
}],
|
|
1895
|
-
};
|
|
1896
|
-
});
|
|
1897
|
-
if (pluginName && key && rawValue !== undefined) {
|
|
1898
|
-
const inputValue = parseConfigValue(rawValue, rawOptions.valueJson === true);
|
|
1899
|
-
return {
|
|
1900
|
-
cancelled: false,
|
|
1901
|
-
key,
|
|
1902
|
-
value: await execute(pluginName, key, inputValue),
|
|
1903
|
-
};
|
|
1904
|
-
}
|
|
1905
|
-
if (!isWizardAvailable(context, rawOptions))
|
|
1906
|
-
throw new Error(configCommandUsage('set'));
|
|
1907
|
-
const candidates = await loadWizardCandidates(context, {});
|
|
1908
|
-
if (pluginName) {
|
|
1909
|
-
const candidate = candidates.find((entry) => entry.pluginName === pluginName);
|
|
1910
|
-
if (!candidate)
|
|
1911
|
-
throw new Error(`Unknown plugin "${pluginName}".`);
|
|
1912
|
-
if (!hasConfigSchemaKeys(candidate)) {
|
|
1913
|
-
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1914
|
-
}
|
|
1915
|
-
if (key && !candidate.configSchema?.[key])
|
|
1916
|
-
throw new Error(`Unknown config key "${key}".`);
|
|
1917
|
-
}
|
|
1918
|
-
const configurableCandidates = candidates.filter(hasConfigSchemaKeys);
|
|
1919
|
-
if (configurableCandidates.length === 0) {
|
|
1920
|
-
throw new Error('configSchemaUnavailable: No current plugin declares an AW config schema.');
|
|
1921
|
-
}
|
|
1922
|
-
const result = await runCommandWizard(context, {
|
|
1923
|
-
command: 'config:set',
|
|
1924
|
-
candidates: configurableCandidates,
|
|
1925
|
-
initial: {
|
|
1926
|
-
plugins: pluginName ? [pluginName] : [],
|
|
1927
|
-
key,
|
|
1928
|
-
...(rawValue !== undefined ? { value: rawValue } : {}),
|
|
1929
|
-
scope,
|
|
1930
|
-
projectLayer,
|
|
1931
|
-
},
|
|
1932
|
-
pluginMode: pluginName ? 'none' : 'single',
|
|
1933
|
-
valueJson: rawOptions.valueJson === true,
|
|
1934
|
-
promptForKey: key === undefined,
|
|
1935
|
-
promptForValue: rawValue === undefined,
|
|
1936
|
-
...equivalentConfigCommandProjection((selection) => configSetEquivalentOptions(selection, candidates, rawOptions)),
|
|
1937
|
-
commandIsTemplate: (selection) => candidates.find((entry) => entry.pluginName === selection.plugins[0])?.configSchema?.[selection.key ?? ''] !== undefined
|
|
1938
|
-
&& configFieldPlaceholder(candidates.find((entry) => entry.pluginName === selection.plugins[0])?.configSchema?.[selection.key ?? '']) !== undefined,
|
|
1939
|
-
resultState: overallResultState,
|
|
1940
|
-
execute: async (selection) => {
|
|
1941
|
-
const selectedPlugin = selection.plugins[0];
|
|
1942
|
-
const selectedKey = selection.key;
|
|
1943
|
-
const schema = candidates.find((entry) => entry.pluginName === selectedPlugin).configSchema;
|
|
1944
|
-
const updates = await coercePluginConfigUpdates({
|
|
1945
|
-
schema,
|
|
1946
|
-
updates: {
|
|
1947
|
-
[selectedKey]: parseConfigValue(selection.value, rawOptions.valueJson === true),
|
|
1948
|
-
},
|
|
1949
|
-
cwd: context.cwd,
|
|
1950
|
-
});
|
|
1951
|
-
return execute(selectedPlugin, selectedKey, updates[selectedKey]);
|
|
1952
|
-
},
|
|
2873
|
+
});
|
|
1953
2874
|
});
|
|
1954
|
-
return result.cancelled
|
|
1955
|
-
? { cancelled: true }
|
|
1956
|
-
: { cancelled: false, key: result.selection.key, value: result.value };
|
|
1957
2875
|
});
|
|
1958
2876
|
}
|
|
1959
2877
|
catch (error) {
|
|
1960
2878
|
writeConfigMutationFailure('config:set', pluginName, rawOptions.json === true, error);
|
|
1961
2879
|
return;
|
|
1962
2880
|
}
|
|
1963
|
-
|
|
1964
|
-
return;
|
|
1965
|
-
const receipt = outcome.value;
|
|
1966
|
-
const selectedKey = outcome.key;
|
|
2881
|
+
const receipt = outcome;
|
|
1967
2882
|
if (rawOptions.json) {
|
|
1968
2883
|
writeJsonReceipt(io.stdout, receipt);
|
|
1969
2884
|
}
|
|
1970
2885
|
else {
|
|
1971
|
-
writeLine(io.stdout, `已写入 ${receipt.plugin}.${
|
|
1972
|
-
if (receipt.projectLayer === 'local') {
|
|
1973
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
1974
|
-
}
|
|
2886
|
+
writeLine(io.stdout, `已写入 ${receipt.plugin}.${key}(${configLayerLabel(receipt.scope)}配置)。`);
|
|
1975
2887
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
1976
2888
|
}
|
|
1977
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
2889
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
1978
2890
|
});
|
|
1979
2891
|
config
|
|
1980
2892
|
.command('unset')
|
|
1981
2893
|
.argument('[plugin]')
|
|
1982
2894
|
.argument('[key]')
|
|
1983
2895
|
.option('-s, --scope <scope>', 'project or user')
|
|
1984
|
-
.option('--
|
|
2896
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2897
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2898
|
+
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
1985
2899
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
1986
2900
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
1987
2901
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -1992,19 +2906,17 @@ export function buildProgram(options = {}) {
|
|
|
1992
2906
|
try {
|
|
1993
2907
|
outcome = await runActionWithContext(context, async () => {
|
|
1994
2908
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
1995
|
-
const
|
|
1996
|
-
const execute = async (selectedPlugin, selectedKey) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken) => {
|
|
1997
|
-
if (plugin.manifest.config?.schema && !plugin.manifest.config.schema[selectedKey]) {
|
|
1998
|
-
throw new Error(`Unknown config key "${selectedKey}".`);
|
|
1999
|
-
}
|
|
2909
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2910
|
+
const execute = async (selectedPlugin, selectedKey, confirmed) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2000
2911
|
const store = await readPluginConfigStore({
|
|
2001
2912
|
sourceId: source.sourceId,
|
|
2002
2913
|
sourceIdentity: source.sourceIdentity,
|
|
2914
|
+
logicalIdentity: source.logicalIdentity,
|
|
2003
2915
|
pluginName: plugin.manifest.name,
|
|
2004
2916
|
scope,
|
|
2005
|
-
...(scope === 'project' ? { projectLayer } : {}),
|
|
2006
2917
|
cwd: context.cwd,
|
|
2007
2918
|
env: context.env,
|
|
2919
|
+
schema: plugin.manifest.config?.fields,
|
|
2008
2920
|
});
|
|
2009
2921
|
const existed = Object.hasOwn(store.values, selectedKey);
|
|
2010
2922
|
if (!existed)
|
|
@@ -2013,20 +2925,26 @@ export function buildProgram(options = {}) {
|
|
|
2013
2925
|
plugin,
|
|
2014
2926
|
pluginName: plugin.manifest.name,
|
|
2015
2927
|
scope,
|
|
2016
|
-
projectLayer,
|
|
2017
2928
|
cwd: context.cwd,
|
|
2018
2929
|
env: context.env,
|
|
2019
2930
|
nativeCliRunner: context.nativeCliRunner,
|
|
2020
|
-
rebuildRuntime: {
|
|
2931
|
+
rebuildRuntime: {
|
|
2932
|
+
...context,
|
|
2933
|
+
awHomeMutationToken,
|
|
2934
|
+
catalogOperationContext,
|
|
2935
|
+
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
2936
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
2937
|
+
},
|
|
2021
2938
|
awHomeMutationToken,
|
|
2022
2939
|
request: {
|
|
2023
2940
|
removeKeys: [selectedKey],
|
|
2024
2941
|
},
|
|
2942
|
+
apply: rawOptions.apply === true,
|
|
2943
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
2944
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
2025
2945
|
});
|
|
2026
|
-
return {
|
|
2946
|
+
return buildConfigMutationReceipt('config:unset', {
|
|
2027
2947
|
ok: writeReceipt.overallState === 'succeeded',
|
|
2028
|
-
receiptSchemaVersion: 4,
|
|
2029
|
-
command: 'config:unset',
|
|
2030
2948
|
...writeReceipt,
|
|
2031
2949
|
plugin: plugin.manifest.name,
|
|
2032
2950
|
pluginName: plugin.manifest.name,
|
|
@@ -2037,17 +2955,20 @@ export function buildProgram(options = {}) {
|
|
|
2037
2955
|
existed,
|
|
2038
2956
|
affectedFields: [{
|
|
2039
2957
|
key: selectedKey,
|
|
2040
|
-
title: plugin?.manifest.config?.
|
|
2958
|
+
title: plugin?.manifest.config?.fields?.[selectedKey]?.title ?? selectedKey,
|
|
2041
2959
|
kind: 'manifest',
|
|
2042
2960
|
reserved: false,
|
|
2043
2961
|
action: 'unset',
|
|
2044
2962
|
scope,
|
|
2045
|
-
...(
|
|
2963
|
+
...(!plugin.manifest.config?.fields?.[selectedKey] ? { stale: true } : {}),
|
|
2046
2964
|
}],
|
|
2047
|
-
};
|
|
2965
|
+
});
|
|
2048
2966
|
});
|
|
2049
2967
|
if (pluginName && key) {
|
|
2050
|
-
return {
|
|
2968
|
+
return {
|
|
2969
|
+
cancelled: false,
|
|
2970
|
+
value: await execute(pluginName, key, rawOptions.yes === true),
|
|
2971
|
+
};
|
|
2051
2972
|
}
|
|
2052
2973
|
if (!isWizardAvailable(context, rawOptions))
|
|
2053
2974
|
throw new Error(configCommandUsage('unset'));
|
|
@@ -2063,7 +2984,7 @@ export function buildProgram(options = {}) {
|
|
|
2063
2984
|
const result = await runCommandWizard(context, {
|
|
2064
2985
|
command: 'config:unset',
|
|
2065
2986
|
candidates,
|
|
2066
|
-
initial: { plugins: pluginName ? [pluginName] : [], key, scope
|
|
2987
|
+
initial: { plugins: pluginName ? [pluginName] : [], key, scope },
|
|
2067
2988
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2068
2989
|
promptForKey: key === undefined,
|
|
2069
2990
|
destructive: true,
|
|
@@ -2072,10 +2993,9 @@ export function buildProgram(options = {}) {
|
|
|
2072
2993
|
plugin: selection.plugins[0],
|
|
2073
2994
|
key: selection.key,
|
|
2074
2995
|
scope: selection.scope ?? 'user',
|
|
2075
|
-
projectLayer: selection.projectLayer,
|
|
2076
2996
|
})),
|
|
2077
2997
|
resultState: overallResultState,
|
|
2078
|
-
execute: (selection) => execute(selection.plugins[0], selection.key),
|
|
2998
|
+
execute: (selection) => execute(selection.plugins[0], selection.key, true),
|
|
2079
2999
|
});
|
|
2080
3000
|
return result.cancelled
|
|
2081
3001
|
? { cancelled: true }
|
|
@@ -2094,21 +3014,19 @@ export function buildProgram(options = {}) {
|
|
|
2094
3014
|
}
|
|
2095
3015
|
else {
|
|
2096
3016
|
writeLine(io.stdout, receipt.existed
|
|
2097
|
-
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope
|
|
2098
|
-
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope
|
|
2099
|
-
if (receipt.projectLayer === 'local') {
|
|
2100
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
2101
|
-
}
|
|
3017
|
+
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)。`
|
|
3018
|
+
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)原本不存在。`);
|
|
2102
3019
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2103
3020
|
}
|
|
2104
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3021
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2105
3022
|
});
|
|
2106
3023
|
config
|
|
2107
3024
|
.command('reset')
|
|
2108
3025
|
.argument('[plugin]')
|
|
2109
3026
|
.option('-s, --scope <scope>', 'project or user')
|
|
2110
|
-
.option('--
|
|
2111
|
-
.option('-
|
|
3027
|
+
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3028
|
+
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3029
|
+
.option('-y, --yes', 'confirm destructive reset and preApply/shared Codex native config apply', false)
|
|
2112
3030
|
.option('-j, --json', 'print receipt as JSON', false)
|
|
2113
3031
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2114
3032
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
@@ -2118,61 +3036,79 @@ export function buildProgram(options = {}) {
|
|
|
2118
3036
|
let outcome;
|
|
2119
3037
|
try {
|
|
2120
3038
|
outcome = await runActionWithContext(context, async () => {
|
|
2121
|
-
const execute = async (selectedPlugin, selectedScope,
|
|
3039
|
+
const execute = async (selectedPlugin, selectedScope, confirmed) => {
|
|
3040
|
+
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2122
3041
|
if (!confirmed) {
|
|
2123
|
-
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope}
|
|
3042
|
+
throw new Error(`Reset requires confirmation. Re-run \`aw config reset ${selectedPlugin} -s ${selectedScope} --yes\` to delete this store.`);
|
|
2124
3043
|
}
|
|
2125
|
-
|
|
3044
|
+
const located = await resolveStoredConfigResetIdentity({
|
|
3045
|
+
selector: selectedPlugin,
|
|
3046
|
+
context,
|
|
3047
|
+
scope: selectedScope,
|
|
3048
|
+
});
|
|
3049
|
+
const resetLocatedStore = async (plugin, pluginError) => {
|
|
2126
3050
|
const affectedFields = await describeResetAffectedFields({
|
|
2127
|
-
|
|
3051
|
+
sourceId: located.sourceId,
|
|
3052
|
+
sourceIdentity: located.sourceIdentity,
|
|
3053
|
+
logicalIdentity: located.logicalIdentity,
|
|
3054
|
+
pluginName: located.pluginName,
|
|
2128
3055
|
plugin,
|
|
3056
|
+
pluginError,
|
|
2129
3057
|
scope: selectedScope,
|
|
2130
|
-
projectLayer,
|
|
2131
3058
|
cwd: context.cwd,
|
|
2132
3059
|
env: context.env,
|
|
2133
|
-
});
|
|
3060
|
+
}).catch(() => []);
|
|
2134
3061
|
const resetReceipt = await resetPluginConfigWithHelper({
|
|
2135
|
-
|
|
3062
|
+
sourceId: located.sourceId,
|
|
3063
|
+
sourceIdentity: located.sourceIdentity,
|
|
3064
|
+
logicalIdentity: located.logicalIdentity,
|
|
3065
|
+
pluginName: located.pluginName,
|
|
2136
3066
|
scope: selectedScope,
|
|
2137
|
-
projectLayer,
|
|
2138
3067
|
cwd: context.cwd,
|
|
2139
3068
|
env: context.env,
|
|
2140
3069
|
nativeCliRunner: context.nativeCliRunner,
|
|
2141
|
-
rebuildRuntime: { ...context, awHomeMutationToken },
|
|
2142
|
-
awHomeMutationToken,
|
|
2143
3070
|
plugin,
|
|
3071
|
+
pluginError,
|
|
3072
|
+
apply: rawOptions.apply === true,
|
|
3073
|
+
rebuildRuntime: scriptTimeoutMs === undefined ? undefined : { scriptTimeoutMs },
|
|
3074
|
+
sharedNativeApplyConfirmed: confirmed,
|
|
3075
|
+
preApplyConfirmed: rawOptions.yes === true,
|
|
2144
3076
|
});
|
|
2145
|
-
return {
|
|
3077
|
+
return buildConfigMutationReceipt('config:reset', {
|
|
2146
3078
|
ok: resetReceipt.overallState === 'succeeded',
|
|
2147
|
-
receiptSchemaVersion: 4,
|
|
2148
|
-
command: 'config:reset',
|
|
2149
3079
|
...resetReceipt,
|
|
2150
|
-
plugin:
|
|
2151
|
-
pluginName:
|
|
2152
|
-
pluginId,
|
|
2153
|
-
sourceId:
|
|
2154
|
-
sourceIdentity:
|
|
3080
|
+
plugin: located.pluginName,
|
|
3081
|
+
pluginName: located.pluginName,
|
|
3082
|
+
pluginId: located.pluginId,
|
|
3083
|
+
sourceId: located.sourceId,
|
|
3084
|
+
...(located.sourceIdentity ? { sourceIdentity: located.sourceIdentity } : {}),
|
|
2155
3085
|
affectedFields,
|
|
2156
|
-
};
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
3086
|
+
});
|
|
3087
|
+
};
|
|
3088
|
+
let resetStarted = false;
|
|
3089
|
+
try {
|
|
3090
|
+
return await withResolvedCatalogPlugin({
|
|
3091
|
+
selector: located.pluginId,
|
|
3092
|
+
cliVersion: resolveCliVersion(),
|
|
3093
|
+
env: context.env,
|
|
3094
|
+
consume: async ({ plugin }) => {
|
|
3095
|
+
resetStarted = true;
|
|
3096
|
+
return resetLocatedStore(plugin, null);
|
|
3097
|
+
},
|
|
3098
|
+
});
|
|
3099
|
+
}
|
|
3100
|
+
catch (error) {
|
|
3101
|
+
if (resetStarted)
|
|
3102
|
+
throw error;
|
|
3103
|
+
return resetLocatedStore(null, error instanceof Error ? error : new Error(String(error)));
|
|
3104
|
+
}
|
|
2168
3105
|
};
|
|
2169
3106
|
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
2170
|
-
const projectLayer = resolveConfigProjectLayer(rawOptions);
|
|
2171
3107
|
const needsWizard = pluginName === undefined || rawOptions.yes !== true;
|
|
2172
3108
|
if (!needsWizard) {
|
|
2173
3109
|
return {
|
|
2174
3110
|
cancelled: false,
|
|
2175
|
-
value: await execute(pluginName, scope,
|
|
3111
|
+
value: await execute(pluginName, scope, true),
|
|
2176
3112
|
};
|
|
2177
3113
|
}
|
|
2178
3114
|
if (!isWizardAvailable(context, rawOptions)) {
|
|
@@ -2180,16 +3116,16 @@ export function buildProgram(options = {}) {
|
|
|
2180
3116
|
throw new Error(configCommandUsage('reset'));
|
|
2181
3117
|
return {
|
|
2182
3118
|
cancelled: false,
|
|
2183
|
-
value: await execute(pluginName, scope,
|
|
3119
|
+
value: await execute(pluginName, scope, false),
|
|
2184
3120
|
};
|
|
2185
3121
|
}
|
|
2186
3122
|
const currentCandidates = pluginName ? [] : await loadWizardCandidates(context, {});
|
|
2187
3123
|
const candidatesByScope = new Map();
|
|
2188
3124
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'user')) {
|
|
2189
|
-
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user'
|
|
3125
|
+
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user' }], { includeEmptyStores: true })));
|
|
2190
3126
|
}
|
|
2191
3127
|
if (!pluginName && (rawOptions.scope === undefined || scope === 'project')) {
|
|
2192
|
-
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project'
|
|
3128
|
+
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project' }], { includeEmptyStores: true })));
|
|
2193
3129
|
}
|
|
2194
3130
|
const candidates = mergeWizardCandidates(candidatesByScope.get('user') ?? [], candidatesByScope.get('project') ?? []);
|
|
2195
3131
|
if (!pluginName && candidates.length === 0) {
|
|
@@ -2198,7 +3134,7 @@ export function buildProgram(options = {}) {
|
|
|
2198
3134
|
const result = await runCommandWizard(context, {
|
|
2199
3135
|
command: 'config:reset',
|
|
2200
3136
|
candidates,
|
|
2201
|
-
initial: { plugins: pluginName ? [pluginName] : [], scope
|
|
3137
|
+
initial: { plugins: pluginName ? [pluginName] : [], scope },
|
|
2202
3138
|
pluginMode: pluginName ? 'none' : 'single',
|
|
2203
3139
|
promptForScope: rawOptions.scope === undefined,
|
|
2204
3140
|
destructive: true,
|
|
@@ -2209,11 +3145,10 @@ export function buildProgram(options = {}) {
|
|
|
2209
3145
|
command: 'reset',
|
|
2210
3146
|
plugin: selection.plugins[0],
|
|
2211
3147
|
scope: selection.scope ?? 'user',
|
|
2212
|
-
projectLayer: selection.projectLayer,
|
|
2213
3148
|
confirmed: true,
|
|
2214
3149
|
})),
|
|
2215
3150
|
resultState: overallResultState,
|
|
2216
|
-
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user',
|
|
3151
|
+
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user', true),
|
|
2217
3152
|
});
|
|
2218
3153
|
return result.cancelled
|
|
2219
3154
|
? { cancelled: true }
|
|
@@ -2232,14 +3167,11 @@ export function buildProgram(options = {}) {
|
|
|
2232
3167
|
}
|
|
2233
3168
|
else {
|
|
2234
3169
|
writeLine(io.stdout, receipt.deleted
|
|
2235
|
-
? `已重置 ${receipt.plugin} 的${configLayerLabel(receipt.scope
|
|
2236
|
-
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope
|
|
2237
|
-
if (receipt.projectLayer === 'local') {
|
|
2238
|
-
writeProjectLocalConfigNotice(io.stdout);
|
|
2239
|
-
}
|
|
3170
|
+
? `已重置 ${receipt.plugin} 的${configLayerLabel(receipt.scope)}配置。`
|
|
3171
|
+
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope)}配置。`);
|
|
2240
3172
|
writeConfigApplyNotice(io.stderr, receipt);
|
|
2241
3173
|
}
|
|
2242
|
-
commandExitState.exitCode = receipt.overallState === '
|
|
3174
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2243
3175
|
});
|
|
2244
3176
|
program
|
|
2245
3177
|
.command('status')
|
|
@@ -2252,7 +3184,7 @@ export function buildProgram(options = {}) {
|
|
|
2252
3184
|
.option('-j, --json', 'print status as JSON', false)
|
|
2253
3185
|
.action(async (plugins, rawOptions) => {
|
|
2254
3186
|
const context = createActionContext('status', rawOptions);
|
|
2255
|
-
const result = await runActionWithContext(context, () =>
|
|
3187
|
+
const result = await runActionWithContext(context, () => statusCommandV8({
|
|
2256
3188
|
plugins: plugins ?? [],
|
|
2257
3189
|
cwd,
|
|
2258
3190
|
env: context.env,
|
|
@@ -2265,11 +3197,11 @@ export function buildProgram(options = {}) {
|
|
|
2265
3197
|
commandExitState.exitCode = result.hasErrors ? 1 : 0;
|
|
2266
3198
|
writeLine(io.stdout, result.output);
|
|
2267
3199
|
for (const source of result.payload.catalog.sources) {
|
|
2268
|
-
if (source.error)
|
|
3200
|
+
if (rawOptions.json && source.error)
|
|
2269
3201
|
writeLine(io.stderr, `${source.id}: ${source.error}`);
|
|
2270
3202
|
}
|
|
2271
3203
|
for (const error of result.payload.errors) {
|
|
2272
|
-
if (error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
3204
|
+
if (rawOptions.json && error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
2273
3205
|
writeLine(io.stderr, error.message);
|
|
2274
3206
|
}
|
|
2275
3207
|
}
|
|
@@ -2294,11 +3226,24 @@ export async function runCli(argv, options = {}) {
|
|
|
2294
3226
|
...createDefaultIo(),
|
|
2295
3227
|
...options.io,
|
|
2296
3228
|
};
|
|
3229
|
+
const reviewCommand = argv[0] === 'review' && ['inspect', 'prepare'].includes(argv[1] ?? '')
|
|
3230
|
+
? argv[1]
|
|
3231
|
+
: null;
|
|
3232
|
+
const jsonReviewCommand = reviewCommand !== null && argv.includes('--json');
|
|
2297
3233
|
const jsonAuthoringCommand = argv.includes('--json')
|
|
2298
|
-
&& ((argv[0] === 'catalog' && ['init', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
|
|
2299
|
-
|| (argv[0] === 'plugin' && ['build', 'test'].includes(argv[1] ?? ''))
|
|
3234
|
+
&& ((argv[0] === 'catalog' && ['init', 'context', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
|
|
3235
|
+
|| (argv[0] === 'plugin' && ['build', 'test', 'validate', 'status', 'remove'].includes(argv[1] ?? ''))
|
|
3236
|
+
|| reviewCommand !== null)
|
|
2300
3237
|
? `${argv[0]}:${argv[1]}`
|
|
2301
3238
|
: null;
|
|
3239
|
+
const jsonCatalogDevCommand = argv.includes('--json')
|
|
3240
|
+
&& argv[0] === 'catalog'
|
|
3241
|
+
&& argv[1] === 'dev'
|
|
3242
|
+
&& ['activate', 'status', 'deactivate'].includes(argv[2] ?? '')
|
|
3243
|
+
? argv[2]
|
|
3244
|
+
: null;
|
|
3245
|
+
const jsonWriteRequest = jsonWriteCommandRequest(argv);
|
|
3246
|
+
const jsonConfigMutation = jsonConfigMutationRequest(argv);
|
|
2302
3247
|
try {
|
|
2303
3248
|
const authoringScriptByCommand = {
|
|
2304
3249
|
init: 'init-plugin.mjs',
|
|
@@ -2306,7 +3251,6 @@ export async function runCli(argv, options = {}) {
|
|
|
2306
3251
|
remove: 'remove-plugin.mjs',
|
|
2307
3252
|
validate: 'validate-plugin.mjs',
|
|
2308
3253
|
status: 'plugin-status.mjs',
|
|
2309
|
-
'check-versions': 'check-plugin-versions.mjs',
|
|
2310
3254
|
};
|
|
2311
3255
|
const authoringScript = argv[0] === 'plugin'
|
|
2312
3256
|
? authoringScriptByCommand[argv[1] ?? '']
|
|
@@ -2315,29 +3259,85 @@ export async function runCli(argv, options = {}) {
|
|
|
2315
3259
|
: undefined;
|
|
2316
3260
|
if (authoringScript && !argv.includes('--help') && !argv.includes('-h')) {
|
|
2317
3261
|
const authoringArgs = argv.slice(2);
|
|
3262
|
+
let authoringEnv = options.env ?? process.env;
|
|
2318
3263
|
if (argv[0] === 'plugin'
|
|
2319
|
-
&&
|
|
2320
|
-
|
|
2321
|
-
|
|
3264
|
+
&& !authoringArgs.some((token) => token === '--plugin-root' || token.startsWith('--plugin-root='))) {
|
|
3265
|
+
let explicitRoot;
|
|
3266
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3267
|
+
const token = authoringArgs[index];
|
|
3268
|
+
if (token.startsWith('--workspace-root='))
|
|
3269
|
+
explicitRoot = token.slice('--workspace-root='.length);
|
|
3270
|
+
if (token === '--workspace-root')
|
|
3271
|
+
explicitRoot = authoringArgs[index + 1];
|
|
3272
|
+
}
|
|
3273
|
+
const originalCwd = options.cwd ?? process.cwd();
|
|
3274
|
+
let discoveryCwd = originalCwd;
|
|
3275
|
+
if (argv[1] === 'validate') {
|
|
3276
|
+
const valueOptions = new Set(['--workspace-root', '--claude-skill-profile', '--version-base']);
|
|
3277
|
+
for (let index = 0; index < authoringArgs.length; index += 1) {
|
|
3278
|
+
const token = authoringArgs[index];
|
|
3279
|
+
if (valueOptions.has(token)) {
|
|
3280
|
+
index += 1;
|
|
3281
|
+
continue;
|
|
3282
|
+
}
|
|
3283
|
+
if (!token.startsWith('-')) {
|
|
3284
|
+
discoveryCwd = path.resolve(originalCwd, token);
|
|
3285
|
+
authoringArgs[index] = discoveryCwd;
|
|
3286
|
+
break;
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3289
|
+
}
|
|
3290
|
+
const workspace = await resolveCatalogWorkspaceRoot({
|
|
3291
|
+
cwd: discoveryCwd,
|
|
3292
|
+
...(explicitRoot === undefined ? {} : { explicitRoot: path.resolve(options.cwd ?? process.cwd(), explicitRoot) }),
|
|
3293
|
+
mode: 'existing',
|
|
3294
|
+
});
|
|
3295
|
+
authoringEnv = {
|
|
3296
|
+
...authoringEnv,
|
|
3297
|
+
AW_AUTHORING_WORKSPACE_ROOT: workspace.workspaceRoot,
|
|
3298
|
+
AW_AUTHORING_WORKSPACE_ROOT_RESOLVED_FROM: workspace.workspaceRootResolvedFrom,
|
|
3299
|
+
};
|
|
3300
|
+
if (explicitRoot === undefined)
|
|
3301
|
+
authoringArgs.push('--workspace-root', workspace.workspaceRoot);
|
|
2322
3302
|
}
|
|
2323
3303
|
return runAuthoringScript({
|
|
2324
3304
|
scriptName: authoringScript,
|
|
2325
3305
|
args: authoringArgs,
|
|
2326
3306
|
cwd: options.cwd ?? process.cwd(),
|
|
2327
|
-
env:
|
|
3307
|
+
env: authoringEnv,
|
|
2328
3308
|
io,
|
|
2329
3309
|
});
|
|
2330
3310
|
}
|
|
2331
|
-
if (
|
|
3311
|
+
if (!jsonConfigMutation
|
|
3312
|
+
&& argv.some((token) => token === '--subdir' || token.startsWith('--subdir='))
|
|
2332
3313
|
&& argv.includes('--no-subdir')) {
|
|
2333
3314
|
const message = 'option --subdir cannot be used with option --no-subdir';
|
|
2334
3315
|
if (argv.includes('--json') && argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update') {
|
|
2335
3316
|
writeJsonReceipt(io.stdout, {
|
|
2336
|
-
receiptSchemaVersion:
|
|
3317
|
+
receiptSchemaVersion: 6,
|
|
2337
3318
|
command: 'catalog:source:update',
|
|
2338
3319
|
ok: false,
|
|
2339
3320
|
changed: false,
|
|
2340
3321
|
sourceId: argv[3] ?? '',
|
|
3322
|
+
primaryChange: null,
|
|
3323
|
+
references: [],
|
|
3324
|
+
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
3325
|
+
});
|
|
3326
|
+
}
|
|
3327
|
+
writeLine(io.stderr, `error: ${message}`);
|
|
3328
|
+
return 1;
|
|
3329
|
+
}
|
|
3330
|
+
if (argv[0] === 'catalog' && argv[1] === 'source' && argv[2] === 'update'
|
|
3331
|
+
&& argv.includes('--auto-check') && argv.includes('--no-auto-check')) {
|
|
3332
|
+
const message = 'option --auto-check cannot be used with option --no-auto-check';
|
|
3333
|
+
if (argv.includes('--json') || argv.includes('-j')) {
|
|
3334
|
+
writeJsonReceipt(io.stdout, {
|
|
3335
|
+
receiptSchemaVersion: 6,
|
|
3336
|
+
command: 'catalog:source:update',
|
|
3337
|
+
ok: false,
|
|
3338
|
+
changed: false,
|
|
3339
|
+
sourceId: argv[3] ?? '',
|
|
3340
|
+
primaryChange: null,
|
|
2341
3341
|
references: [],
|
|
2342
3342
|
errors: [{ code: 'catalogSourceOptionConflict', message }],
|
|
2343
3343
|
});
|
|
@@ -2365,9 +3365,30 @@ export async function runCli(argv, options = {}) {
|
|
|
2365
3365
|
}
|
|
2366
3366
|
return await runActionWithContext(context, () => runConsoleController(context));
|
|
2367
3367
|
}
|
|
3368
|
+
let catalogPublicationActionStarted = false;
|
|
3369
|
+
let configMutationActionStarted = false;
|
|
3370
|
+
const programIo = jsonCatalogDevCommand || jsonWriteRequest || jsonReviewCommand
|
|
3371
|
+
? { ...io, stderr: () => undefined }
|
|
3372
|
+
: jsonConfigMutation
|
|
3373
|
+
? {
|
|
3374
|
+
...io,
|
|
3375
|
+
stderr: (text) => {
|
|
3376
|
+
if (configMutationActionStarted)
|
|
3377
|
+
io.stderr(text);
|
|
3378
|
+
},
|
|
3379
|
+
}
|
|
3380
|
+
: jsonAuthoringCommand === 'catalog:publish'
|
|
3381
|
+
? {
|
|
3382
|
+
...io,
|
|
3383
|
+
stderr: (text) => {
|
|
3384
|
+
if (catalogPublicationActionStarted)
|
|
3385
|
+
io.stderr(text);
|
|
3386
|
+
},
|
|
3387
|
+
}
|
|
3388
|
+
: io;
|
|
2368
3389
|
const program = buildProgram({
|
|
2369
3390
|
...options,
|
|
2370
|
-
io,
|
|
3391
|
+
io: programIo,
|
|
2371
3392
|
diagnostics: {
|
|
2372
3393
|
...options.diagnostics,
|
|
2373
3394
|
metadata: {
|
|
@@ -2376,16 +3397,139 @@ export async function runCli(argv, options = {}) {
|
|
|
2376
3397
|
},
|
|
2377
3398
|
},
|
|
2378
3399
|
});
|
|
3400
|
+
if (jsonAuthoringCommand === 'catalog:publish') {
|
|
3401
|
+
program.hook('preAction', () => {
|
|
3402
|
+
catalogPublicationActionStarted = true;
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
if (jsonConfigMutation) {
|
|
3406
|
+
program.hook('preAction', () => {
|
|
3407
|
+
configMutationActionStarted = true;
|
|
3408
|
+
});
|
|
3409
|
+
}
|
|
2379
3410
|
await program.parseAsync(['node', 'aw', ...argv]);
|
|
2380
3411
|
return program.__awCommandExitState?.exitCode ?? 0;
|
|
2381
3412
|
}
|
|
2382
3413
|
catch (error) {
|
|
2383
|
-
if (
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
3414
|
+
if (reviewCommand && error instanceof CommanderError) {
|
|
3415
|
+
if (error.exitCode === 0)
|
|
3416
|
+
return 0;
|
|
3417
|
+
if (jsonReviewCommand) {
|
|
3418
|
+
const receipt = reviewCommand === 'inspect'
|
|
3419
|
+
? createReviewInspectionFailure(new Error(error.message), 'invalidArguments')
|
|
3420
|
+
: createReviewPreparationFailure(error.message);
|
|
3421
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
3422
|
+
}
|
|
3423
|
+
return 2;
|
|
3424
|
+
}
|
|
3425
|
+
if (jsonCatalogDevCommand) {
|
|
3426
|
+
const workspaceRootIndex = argv.findIndex((token) => token === '--workspace-root');
|
|
3427
|
+
const workspaceRootOption = argv.find((token) => token.startsWith('--workspace-root='));
|
|
3428
|
+
const workspaceRoot = workspaceRootOption?.slice('--workspace-root='.length)
|
|
3429
|
+
?? (workspaceRootIndex >= 0 ? argv[workspaceRootIndex + 1] : undefined);
|
|
3430
|
+
const sourceIdIndex = argv.findIndex((token) => token === '--source-id');
|
|
3431
|
+
const sourceIdOption = argv.find((token) => token.startsWith('--source-id='));
|
|
3432
|
+
const sourceId = sourceIdOption?.slice('--source-id='.length)
|
|
3433
|
+
?? (sourceIdIndex >= 0 ? argv[sourceIdIndex + 1] : undefined);
|
|
3434
|
+
const failure = error instanceof CommanderError
|
|
3435
|
+
? { code: 'invalidArguments', message: error.message }
|
|
3436
|
+
: catalogDevSourceError(error);
|
|
3437
|
+
writeJsonReceipt(io.stdout, createCatalogDevFailureReceipt({
|
|
3438
|
+
command: jsonCatalogDevCommand,
|
|
3439
|
+
cwd: options.cwd ?? process.cwd(),
|
|
3440
|
+
workspaceRoot,
|
|
3441
|
+
sourceId,
|
|
3442
|
+
...failure,
|
|
3443
|
+
}));
|
|
3444
|
+
return 1;
|
|
3445
|
+
}
|
|
3446
|
+
if (jsonWriteRequest) {
|
|
3447
|
+
writeCommandFailureReceipt(io.stdout, jsonWriteRequest, error);
|
|
3448
|
+
return 1;
|
|
3449
|
+
}
|
|
3450
|
+
if (jsonConfigMutation) {
|
|
3451
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
3452
|
+
return 0;
|
|
3453
|
+
const failure = configMutationFailure(error, options.env ?? process.env, options.cwd ?? process.cwd());
|
|
3454
|
+
writeConfigMutationFailureReceipt(io.stdout, error instanceof CommanderError
|
|
3455
|
+
? { command: jsonConfigMutation.command }
|
|
3456
|
+
: jsonConfigMutation, failure);
|
|
3457
|
+
writeLine(io.stderr, failure.message);
|
|
3458
|
+
return 1;
|
|
3459
|
+
}
|
|
3460
|
+
if (jsonAuthoringCommand === 'catalog:publish' && error instanceof CommanderError) {
|
|
3461
|
+
const failure = catalogPublicationFailure({
|
|
3462
|
+
error: new CatalogPublicationInspectionError('invalidArguments', error.message),
|
|
3463
|
+
env: options.env,
|
|
3464
|
+
sensitiveRoots: [options.cwd ?? process.cwd()],
|
|
2388
3465
|
});
|
|
3466
|
+
writeJsonReceipt(io.stdout, failure);
|
|
3467
|
+
writeLine(io.stderr, failure.message);
|
|
3468
|
+
return 1;
|
|
3469
|
+
}
|
|
3470
|
+
if (jsonAuthoringCommand && !(error instanceof CommanderError)) {
|
|
3471
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3472
|
+
if (jsonAuthoringCommand === 'plugin:validate') {
|
|
3473
|
+
writeJsonReceipt(io.stdout, {
|
|
3474
|
+
ok: false,
|
|
3475
|
+
profile: 'unknown',
|
|
3476
|
+
warnings: [],
|
|
3477
|
+
errors: [message],
|
|
3478
|
+
});
|
|
3479
|
+
}
|
|
3480
|
+
else if (jsonAuthoringCommand === 'plugin:status') {
|
|
3481
|
+
writeJsonReceipt(io.stdout, {
|
|
3482
|
+
schemaVersion: 3,
|
|
3483
|
+
policy: 'development',
|
|
3484
|
+
ok: false,
|
|
3485
|
+
base: null,
|
|
3486
|
+
requestedBase: null,
|
|
3487
|
+
baseCommit: null,
|
|
3488
|
+
checkedPlugins: 0,
|
|
3489
|
+
checks: [],
|
|
3490
|
+
workspaceRoot: null,
|
|
3491
|
+
workspaceRootResolvedFrom: null,
|
|
3492
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3493
|
+
});
|
|
3494
|
+
}
|
|
3495
|
+
else if (jsonAuthoringCommand === 'plugin:remove') {
|
|
3496
|
+
writeJsonReceipt(io.stdout, {
|
|
3497
|
+
schemaVersion: 1,
|
|
3498
|
+
command: 'plugin:remove',
|
|
3499
|
+
ok: false,
|
|
3500
|
+
workspaceRoot: null,
|
|
3501
|
+
workspaceRootResolvedFrom: null,
|
|
3502
|
+
baseCommit: null,
|
|
3503
|
+
plugin: null,
|
|
3504
|
+
removed: false,
|
|
3505
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3506
|
+
});
|
|
3507
|
+
}
|
|
3508
|
+
else if (jsonAuthoringCommand === 'review:inspect') {
|
|
3509
|
+
writeJsonReceipt(io.stdout, createReviewInspectionFailure(error));
|
|
3510
|
+
}
|
|
3511
|
+
else if (jsonAuthoringCommand === 'review:prepare') {
|
|
3512
|
+
writeJsonReceipt(io.stdout, createReviewPreparationFailure(message, 'reviewPreparationFailed'));
|
|
3513
|
+
}
|
|
3514
|
+
else {
|
|
3515
|
+
writeJsonReceipt(io.stdout, {
|
|
3516
|
+
command: jsonAuthoringCommand,
|
|
3517
|
+
ok: false,
|
|
3518
|
+
errors: [{ code: 'workspaceResolutionFailed', message }],
|
|
3519
|
+
});
|
|
3520
|
+
}
|
|
3521
|
+
return 1;
|
|
3522
|
+
}
|
|
3523
|
+
if (jsonAuthoringCommand && error instanceof CommanderError) {
|
|
3524
|
+
writeJsonReceipt(io.stdout, jsonAuthoringCommand === 'review:inspect'
|
|
3525
|
+
? createReviewInspectionFailure(new Error(error.message), 'invalidArguments')
|
|
3526
|
+
: jsonAuthoringCommand === 'review:prepare'
|
|
3527
|
+
? createReviewPreparationFailure(error.message)
|
|
3528
|
+
: {
|
|
3529
|
+
command: jsonAuthoringCommand,
|
|
3530
|
+
ok: false,
|
|
3531
|
+
errors: [{ code: 'invalidArguments', message: error.message }],
|
|
3532
|
+
});
|
|
2389
3533
|
}
|
|
2390
3534
|
return handleCliError(error, io.stderr);
|
|
2391
3535
|
}
|