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