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