@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
|
@@ -0,0 +1,1271 @@
|
|
|
1
|
+
import { withAwHomeMutationLock, } from './aw-home-mutation-lock.js';
|
|
2
|
+
import { CatalogGenerationError, catalogGenerationErrorCode } from './catalog-generation-error.js';
|
|
3
|
+
import { createCatalogStoreKey, prepareCatalogStoreEntryRepair, publishCatalogStoreEntry, readCatalogSnapshotLogicalIdentity, readCatalogStoreEntry, } from './catalog-generation-store.js';
|
|
4
|
+
import { readCatalogGenerationState, replaceInvalidCatalogGenerationState, withCatalogGenerationStateTransaction, } from './catalog-generation-state.js';
|
|
5
|
+
export { removeCatalogSourceGenerationState } from './catalog-generation-state.js';
|
|
6
|
+
import { validateCatalogSnapshotTransport } from './catalog-snapshot.js';
|
|
7
|
+
import { calculateCatalogSourceConfigFingerprint, calculateCatalogSourceIdentity } from './catalog-source-identity.js';
|
|
8
|
+
import { readCatalogSourcesConfigSnapshot } from './catalog-sources.js';
|
|
9
|
+
import { catalogGitProviderInternal } from './git-catalog-provider.js';
|
|
10
|
+
import { catalogPathProviderInternal } from './path-catalog-provider.js';
|
|
11
|
+
import { readValidatedCatalogGenerationStoreEntry, resolveValidatedActiveCatalogGeneration, } from './catalog-generation-resolver.js';
|
|
12
|
+
import { compareStrictSemVer } from './manifest.js';
|
|
13
|
+
import { projectCatalogCapabilityCompatibility, } from './catalog-capability-projection.js';
|
|
14
|
+
import { calculateCatalogSourceImpactDigest, catalogSourceImpactRequiresConfirmation, inspectCatalogSourceImpact, } from './catalog-source-impact.js';
|
|
15
|
+
const CANDIDATE_FIELDS = [
|
|
16
|
+
'sourceConfigFingerprint', 'sourceIdentity', 'logicalIdentity', 'requestedRef',
|
|
17
|
+
'resolvedCommit', 'catalogVersion', 'channel', 'manifestDigest', 'snapshotDigest',
|
|
18
|
+
];
|
|
19
|
+
function now(runtime) {
|
|
20
|
+
return (runtime?.now?.() ?? new Date()).toISOString();
|
|
21
|
+
}
|
|
22
|
+
function warnCleanupFailure(sourceId) {
|
|
23
|
+
try {
|
|
24
|
+
process.emitWarning(`Catalog provider staging cleanup failed for source "${sourceId}".`, {
|
|
25
|
+
code: 'AW_CATALOG_PROVIDER_CLEANUP_FAILED',
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// Cleanup diagnostics cannot replace the operation result.
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function resolveProvider(options) {
|
|
33
|
+
const providers = options.runtime?.providers ?? {
|
|
34
|
+
git: catalogGitProviderInternal.resolve,
|
|
35
|
+
path: catalogPathProviderInternal.resolve,
|
|
36
|
+
};
|
|
37
|
+
return providers[options.source.type](options.source, {
|
|
38
|
+
cliVersion: options.cliVersion,
|
|
39
|
+
env: options.env,
|
|
40
|
+
signal: options.signal,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
async function resolveCandidate(options) {
|
|
44
|
+
const source = options.source ?? (await readCatalogSourcesConfigSnapshot(options.env)).config.sources
|
|
45
|
+
.find((entry) => entry.id === options.sourceId);
|
|
46
|
+
if (!source)
|
|
47
|
+
throw new CatalogGenerationError({
|
|
48
|
+
code: 'catalogGenerationSourceMissing', sourceId: options.sourceId,
|
|
49
|
+
message: `Catalog source "${options.sourceId}" is not configured.`,
|
|
50
|
+
});
|
|
51
|
+
const resolution = await resolveProvider({ source, ...options });
|
|
52
|
+
try {
|
|
53
|
+
const sourceIdentity = await calculateCatalogSourceIdentity(source);
|
|
54
|
+
if (resolution.sourceId !== source.id || resolution.sourceIdentity !== sourceIdentity) {
|
|
55
|
+
throw new CatalogGenerationError({
|
|
56
|
+
code: 'catalogGenerationIdentityMismatch', sourceId: source.id,
|
|
57
|
+
message: `Catalog provider returned mismatched identity for source "${source.id}".`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const validation = await validateCatalogSnapshotTransport(resolution.rootDir);
|
|
61
|
+
if (validation.manifestDigest !== resolution.manifestDigest
|
|
62
|
+
|| validation.snapshotDigest !== resolution.snapshotDigest)
|
|
63
|
+
throw new CatalogGenerationError({
|
|
64
|
+
code: 'catalogGenerationIdentityMismatch', sourceId: source.id,
|
|
65
|
+
message: `Catalog provider returned mismatched snapshot evidence for source "${source.id}".`,
|
|
66
|
+
});
|
|
67
|
+
return {
|
|
68
|
+
source,
|
|
69
|
+
resolution,
|
|
70
|
+
candidate: {
|
|
71
|
+
sourceConfigFingerprint: calculateCatalogSourceConfigFingerprint(source),
|
|
72
|
+
sourceIdentity: resolution.sourceIdentity,
|
|
73
|
+
logicalIdentity: await readCatalogSnapshotLogicalIdentity(resolution.rootDir),
|
|
74
|
+
catalogVersion: validation.manifest.catalogVersion,
|
|
75
|
+
channel: validation.manifest.channel,
|
|
76
|
+
requestedRef: resolution.requestedRef,
|
|
77
|
+
resolvedCommit: resolution.resolvedCommit,
|
|
78
|
+
manifestDigest: resolution.manifestDigest,
|
|
79
|
+
snapshotDigest: resolution.snapshotDigest,
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
await resolution.cleanup().catch(() => warnCleanupFailure(source.id));
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
export function compareCatalogGenerationCandidates(expected, actual) {
|
|
89
|
+
const changedFields = CANDIDATE_FIELDS.filter((field) => expected[field] !== actual[field]);
|
|
90
|
+
return { matches: changedFields.length === 0, changedFields };
|
|
91
|
+
}
|
|
92
|
+
export function compareCatalogGenerationFreshness(options) {
|
|
93
|
+
const active = options.active;
|
|
94
|
+
if (!active) {
|
|
95
|
+
return {
|
|
96
|
+
state: options.sourceType === 'path' ? 'localChangesAvailable' : 'updateAvailable',
|
|
97
|
+
candidate: options.candidate,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const base = {
|
|
101
|
+
activeVersion: active.catalogVersion,
|
|
102
|
+
activeResolvedCommit: active.resolvedCommit,
|
|
103
|
+
candidate: options.candidate,
|
|
104
|
+
};
|
|
105
|
+
if (active.logicalIdentity !== options.candidate.logicalIdentity) {
|
|
106
|
+
return { ...base, state: 'incompatible', errorCode: 'catalogLogicalIdentityChanged' };
|
|
107
|
+
}
|
|
108
|
+
if (active.snapshotDigest === options.candidate.snapshotDigest) {
|
|
109
|
+
return { ...base, state: 'current' };
|
|
110
|
+
}
|
|
111
|
+
if (options.sourceType === 'path') {
|
|
112
|
+
return { ...base, state: 'localChangesAvailable' };
|
|
113
|
+
}
|
|
114
|
+
const relation = compareStrictSemVer(options.candidate.catalogVersion, active.catalogVersion);
|
|
115
|
+
if (relation > 0)
|
|
116
|
+
return { ...base, state: 'updateAvailable' };
|
|
117
|
+
if (relation < 0)
|
|
118
|
+
return { ...base, state: 'rollbackDetected' };
|
|
119
|
+
return { ...base, state: 'versionConflict' };
|
|
120
|
+
}
|
|
121
|
+
function publicEvidence(candidate) {
|
|
122
|
+
const { sourceConfigFingerprint: _fingerprint, ...evidence } = candidate;
|
|
123
|
+
return evidence;
|
|
124
|
+
}
|
|
125
|
+
function sameActive(active, next) {
|
|
126
|
+
return Boolean(active)
|
|
127
|
+
&& active.sourceConfigFingerprint === next.sourceConfigFingerprint
|
|
128
|
+
&& active.sourceIdentity === next.sourceIdentity
|
|
129
|
+
&& active.requestedRef === next.requestedRef
|
|
130
|
+
&& active.resolvedCommit === next.resolvedCommit
|
|
131
|
+
&& active.logicalIdentity === next.logicalIdentity
|
|
132
|
+
&& active.manifestDigest === next.manifestDigest
|
|
133
|
+
&& active.snapshotDigest === next.snapshotDigest;
|
|
134
|
+
}
|
|
135
|
+
const ACTIVE_FIELDS = [
|
|
136
|
+
'sourceConfigFingerprint', 'sourceIdentity', 'requestedRef', 'resolvedCommit',
|
|
137
|
+
'logicalIdentity', 'manifestDigest', 'snapshotDigest', 'activatedAt',
|
|
138
|
+
];
|
|
139
|
+
function assertExpectedActive(sourceId, current, expected) {
|
|
140
|
+
if (expected === undefined)
|
|
141
|
+
return;
|
|
142
|
+
const matches = expected === null
|
|
143
|
+
? current === undefined
|
|
144
|
+
: current !== undefined && ACTIVE_FIELDS.every((field) => current[field] === expected[field]);
|
|
145
|
+
if (!matches)
|
|
146
|
+
throw new CatalogGenerationError({
|
|
147
|
+
code: 'catalogGenerationReviewStale',
|
|
148
|
+
sourceId,
|
|
149
|
+
message: `Active Catalog for source "${sourceId}" changed after review. Review it again.`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
async function assertCurrentSource(options) {
|
|
153
|
+
const config = await readCatalogSourcesConfigSnapshot(options.env);
|
|
154
|
+
if (options.expectedConfigDigest && config.digest !== options.expectedConfigDigest) {
|
|
155
|
+
throw new CatalogGenerationError({
|
|
156
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
157
|
+
message: `Catalog source "${options.sourceId}" configuration changed after review. Review it again.`,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
const source = config.config.sources.find((entry) => entry.id === options.sourceId);
|
|
161
|
+
if (!source)
|
|
162
|
+
throw new CatalogGenerationError({
|
|
163
|
+
code: 'catalogGenerationSourceMissing', sourceId: options.sourceId,
|
|
164
|
+
message: `Catalog source "${options.sourceId}" was removed during sync.`,
|
|
165
|
+
});
|
|
166
|
+
if (calculateCatalogSourceConfigFingerprint(source) !== options.candidate.sourceConfigFingerprint
|
|
167
|
+
|| await calculateCatalogSourceIdentity(source) !== options.candidate.sourceIdentity)
|
|
168
|
+
throw new CatalogGenerationError({
|
|
169
|
+
code: 'catalogGenerationIdentityMismatch', sourceId: options.sourceId,
|
|
170
|
+
message: `Catalog source "${options.sourceId}" changed during sync. Run sync again.`,
|
|
171
|
+
});
|
|
172
|
+
return source;
|
|
173
|
+
}
|
|
174
|
+
async function enforceCatalogActivationCandidatePolicy(options) {
|
|
175
|
+
const configuredChanged = Boolean(options.active)
|
|
176
|
+
&& (options.active.sourceConfigFingerprint !== options.candidate.sourceConfigFingerprint
|
|
177
|
+
|| options.active.sourceIdentity !== options.candidate.sourceIdentity);
|
|
178
|
+
if (options.mode === 'explicitSourceChange' && options.active && !configuredChanged) {
|
|
179
|
+
throw new CatalogGenerationError({
|
|
180
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
181
|
+
message: `Catalog source "${options.sourceId}" no longer has a verified source configuration change.`,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
if (options.mode === 'exactRepair') {
|
|
185
|
+
if (!options.active
|
|
186
|
+
|| options.active.logicalIdentity !== options.candidate.logicalIdentity
|
|
187
|
+
|| options.active.snapshotDigest !== options.candidate.snapshotDigest
|
|
188
|
+
|| options.active.manifestDigest !== options.candidate.manifestDigest
|
|
189
|
+
|| options.active.resolvedCommit !== options.candidate.resolvedCommit) {
|
|
190
|
+
throw new CatalogGenerationError({
|
|
191
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
192
|
+
message: `Catalog source "${options.sourceId}" no longer matches the exact repair target.`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
await readCatalogStoreEntry({
|
|
196
|
+
logicalIdentity: options.active.logicalIdentity,
|
|
197
|
+
snapshotDigest: options.active.snapshotDigest,
|
|
198
|
+
env: options.env,
|
|
199
|
+
}).then(() => {
|
|
200
|
+
throw new CatalogGenerationError({
|
|
201
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
202
|
+
message: `Catalog source "${options.sourceId}" Active entry is no longer damaged. Review it again.`,
|
|
203
|
+
});
|
|
204
|
+
}).catch((error) => {
|
|
205
|
+
if (error instanceof CatalogGenerationError
|
|
206
|
+
&& error.code === 'catalogGenerationReviewStale')
|
|
207
|
+
throw error;
|
|
208
|
+
});
|
|
209
|
+
return { preserveActive: true };
|
|
210
|
+
}
|
|
211
|
+
if (!options.active)
|
|
212
|
+
return { preserveActive: false };
|
|
213
|
+
if (options.mode === 'normal'
|
|
214
|
+
&& options.active.logicalIdentity !== options.candidate.logicalIdentity) {
|
|
215
|
+
throw new CatalogGenerationError({
|
|
216
|
+
code: 'catalogLogicalIdentityChanged', sourceId: options.sourceId,
|
|
217
|
+
message: `Catalog source "${options.sourceId}" changed logical identity without a verified source configuration change.`,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
if (options.mode === 'replaceDamaged') {
|
|
221
|
+
if (options.active.logicalIdentity !== options.candidate.logicalIdentity && !configuredChanged) {
|
|
222
|
+
throw new CatalogGenerationError({
|
|
223
|
+
code: 'catalogLogicalIdentityChanged', sourceId: options.sourceId,
|
|
224
|
+
message: `Catalog source "${options.sourceId}" changed logical identity without a verified source configuration change.`,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
await readCatalogStoreEntry({
|
|
228
|
+
logicalIdentity: options.active.logicalIdentity,
|
|
229
|
+
snapshotDigest: options.active.snapshotDigest,
|
|
230
|
+
env: options.env,
|
|
231
|
+
}).then(() => {
|
|
232
|
+
throw new CatalogGenerationError({
|
|
233
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
234
|
+
message: `Catalog source "${options.sourceId}" Active entry is no longer damaged. Review it again.`,
|
|
235
|
+
});
|
|
236
|
+
}).catch((error) => {
|
|
237
|
+
if (error instanceof CatalogGenerationError
|
|
238
|
+
&& error.code === 'catalogGenerationReviewStale')
|
|
239
|
+
throw error;
|
|
240
|
+
});
|
|
241
|
+
return { preserveActive: false };
|
|
242
|
+
}
|
|
243
|
+
let previous;
|
|
244
|
+
try {
|
|
245
|
+
previous = await readCatalogStoreEntry({
|
|
246
|
+
logicalIdentity: options.active.logicalIdentity,
|
|
247
|
+
snapshotDigest: options.active.snapshotDigest,
|
|
248
|
+
env: options.env,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
throw new CatalogGenerationError({
|
|
253
|
+
code: 'catalogReplaceDamagedRequired', sourceId: options.sourceId,
|
|
254
|
+
message: `Catalog source "${options.sourceId}" Active entry is damaged. Repair it or use --replace-damaged --yes.`,
|
|
255
|
+
cause: error,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
if (options.source.type === 'git'
|
|
259
|
+
&& options.active.logicalIdentity === options.candidate.logicalIdentity
|
|
260
|
+
&& options.active.snapshotDigest === options.candidate.snapshotDigest) {
|
|
261
|
+
return { preserveActive: true };
|
|
262
|
+
}
|
|
263
|
+
if (options.mode === 'explicitSourceChange')
|
|
264
|
+
return { preserveActive: false };
|
|
265
|
+
if (options.source.type === 'path') {
|
|
266
|
+
return { preserveActive: options.active.snapshotDigest === options.candidate.snapshotDigest };
|
|
267
|
+
}
|
|
268
|
+
if (options.active.snapshotDigest === options.candidate.snapshotDigest) {
|
|
269
|
+
return { preserveActive: true };
|
|
270
|
+
}
|
|
271
|
+
const relation = compareStrictSemVer(options.candidate.catalogVersion, previous.metadata.catalogVersion);
|
|
272
|
+
if (relation === 0)
|
|
273
|
+
throw new CatalogGenerationError({
|
|
274
|
+
code: 'catalogVersionConflict', sourceId: options.sourceId,
|
|
275
|
+
message: `Catalog source "${options.sourceId}" candidate has the same version with different content.`,
|
|
276
|
+
});
|
|
277
|
+
if (relation < 0)
|
|
278
|
+
throw new CatalogGenerationError({
|
|
279
|
+
code: 'catalogRollbackDetected', sourceId: options.sourceId,
|
|
280
|
+
message: `Catalog source "${options.sourceId}" candidate version is lower than the Active version.`,
|
|
281
|
+
});
|
|
282
|
+
return { preserveActive: false };
|
|
283
|
+
}
|
|
284
|
+
function enforceCatalogActivationImpactPolicy(options) {
|
|
285
|
+
if (catalogSourceImpactRequiresConfirmation(options.impact) && !options.impactConfirmed) {
|
|
286
|
+
throw new CatalogGenerationError({
|
|
287
|
+
code: 'catalogImpactConfirmationRequired', sourceId: options.sourceId,
|
|
288
|
+
message: `Catalog source "${options.sourceId}" has affected or unknown references. Use --yes after reviewing the impact.`,
|
|
289
|
+
impact: options.impact,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function assertExpectedImpact(options) {
|
|
294
|
+
if (options.expectedImpactDigest
|
|
295
|
+
&& calculateCatalogSourceImpactDigest(options.impact) !== options.expectedImpactDigest) {
|
|
296
|
+
throw new CatalogGenerationError({
|
|
297
|
+
code: 'catalogGenerationReviewStale',
|
|
298
|
+
sourceId: options.sourceId,
|
|
299
|
+
message: `Catalog source "${options.sourceId}" impact changed after review. Review it again.`,
|
|
300
|
+
impact: options.impact,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
async function inspectActivationImpact(options) {
|
|
305
|
+
return (options.runtime?.inspectSourceImpact ?? inspectCatalogSourceImpact)({
|
|
306
|
+
sourceId: options.sourceId,
|
|
307
|
+
cwd: options.cwd,
|
|
308
|
+
env: options.env,
|
|
309
|
+
sourcePrimary: options.source.primary,
|
|
310
|
+
mode: options.mode,
|
|
311
|
+
...(options.mode === 'generation' ? { candidateManifest: options.candidateManifest } : {}),
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
function assertStoreMatchesCandidate(sourceId, store, candidate) {
|
|
315
|
+
if (store.metadata.logicalIdentity !== candidate.logicalIdentity
|
|
316
|
+
|| store.metadata.manifestDigest !== candidate.manifestDigest
|
|
317
|
+
|| store.metadata.snapshotDigest !== candidate.snapshotDigest)
|
|
318
|
+
throw new CatalogGenerationError({
|
|
319
|
+
code: 'catalogGenerationPublishFailed', sourceId,
|
|
320
|
+
message: `Catalog store evidence does not match the validated candidate for source "${sourceId}".`,
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
async function writeLastSync(options) {
|
|
324
|
+
return withAwHomeMutationLock({
|
|
325
|
+
env: options.env,
|
|
326
|
+
signal: options.signal,
|
|
327
|
+
action: async () => {
|
|
328
|
+
await assertCurrentSource(options);
|
|
329
|
+
const lastSync = {
|
|
330
|
+
syncedAt: now(options.runtime), mode: options.mode, state: options.state,
|
|
331
|
+
...(options.state === 'succeeded'
|
|
332
|
+
? { resolvedCommit: options.candidate.resolvedCommit }
|
|
333
|
+
: { errorCode: options.errorCode }),
|
|
334
|
+
};
|
|
335
|
+
await withCatalogGenerationStateTransaction({
|
|
336
|
+
env: options.env,
|
|
337
|
+
beforeReplace: async () => { await assertCurrentSource(options); },
|
|
338
|
+
action: async (current) => ({
|
|
339
|
+
state: {
|
|
340
|
+
schemaVersion: 1,
|
|
341
|
+
sources: {
|
|
342
|
+
...current.sources,
|
|
343
|
+
[options.sourceId]: { ...current.sources[options.sourceId], lastSync },
|
|
344
|
+
},
|
|
345
|
+
},
|
|
346
|
+
result: undefined,
|
|
347
|
+
}),
|
|
348
|
+
});
|
|
349
|
+
return lastSync;
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
async function recordFailure(options) {
|
|
354
|
+
if (!options.candidate)
|
|
355
|
+
return;
|
|
356
|
+
await writeLastSync({ ...options, candidate: options.candidate, state: 'failed' })
|
|
357
|
+
.catch(() => undefined);
|
|
358
|
+
}
|
|
359
|
+
async function readCandidateContinuity(sourceId, env) {
|
|
360
|
+
const source = (await readCatalogSourcesConfigSnapshot(env)).config.sources
|
|
361
|
+
.find((entry) => entry.id === sourceId);
|
|
362
|
+
if (!source)
|
|
363
|
+
return undefined;
|
|
364
|
+
return {
|
|
365
|
+
sourceConfigFingerprint: calculateCatalogSourceConfigFingerprint(source),
|
|
366
|
+
sourceIdentity: await calculateCatalogSourceIdentity(source),
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
export async function probeCatalogSourceGeneration(options) {
|
|
370
|
+
const env = options.env ?? process.env;
|
|
371
|
+
let resolved;
|
|
372
|
+
try {
|
|
373
|
+
resolved = await resolveCandidate({ ...options, env });
|
|
374
|
+
return {
|
|
375
|
+
sourceId: options.sourceId,
|
|
376
|
+
candidate: resolved.candidate,
|
|
377
|
+
manifest: resolved.resolution.manifest,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
finally {
|
|
381
|
+
if (resolved)
|
|
382
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
export async function probeCatalogSourceRepairGeneration(options) {
|
|
386
|
+
const env = options.env ?? process.env;
|
|
387
|
+
const config = await readCatalogSourcesConfigSnapshot(env);
|
|
388
|
+
if (options.expectedConfigDigest && config.digest !== options.expectedConfigDigest) {
|
|
389
|
+
throw new CatalogGenerationError({
|
|
390
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
391
|
+
message: `Catalog source "${options.sourceId}" configuration changed after review.`,
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
const source = config.config.sources.find((entry) => entry.id === options.sourceId);
|
|
395
|
+
const active = options.expectedActive
|
|
396
|
+
?? (await readCatalogGenerationState(env)).sources[options.sourceId]?.active;
|
|
397
|
+
if (!source || !active)
|
|
398
|
+
throw new CatalogGenerationError({
|
|
399
|
+
code: 'catalogGenerationUnavailable', sourceId: options.sourceId,
|
|
400
|
+
message: `Catalog source "${options.sourceId}" has no Active snapshot to repair.`,
|
|
401
|
+
});
|
|
402
|
+
const exactSource = source.type === 'git'
|
|
403
|
+
? { ...source, refPolicy: { type: 'explicit', ref: active.resolvedCommit } }
|
|
404
|
+
: source;
|
|
405
|
+
let resolved;
|
|
406
|
+
try {
|
|
407
|
+
resolved = await resolveCandidate({ ...options, source: exactSource, env });
|
|
408
|
+
const candidate = {
|
|
409
|
+
...resolved.candidate,
|
|
410
|
+
sourceConfigFingerprint: calculateCatalogSourceConfigFingerprint(source),
|
|
411
|
+
sourceIdentity: await calculateCatalogSourceIdentity(source),
|
|
412
|
+
requestedRef: active.requestedRef,
|
|
413
|
+
};
|
|
414
|
+
if (candidate.logicalIdentity !== active.logicalIdentity
|
|
415
|
+
|| candidate.snapshotDigest !== active.snapshotDigest
|
|
416
|
+
|| candidate.manifestDigest !== active.manifestDigest
|
|
417
|
+
|| candidate.resolvedCommit !== active.resolvedCommit) {
|
|
418
|
+
throw new CatalogGenerationError({
|
|
419
|
+
code: 'catalogReplaceDamagedRequired', sourceId: options.sourceId,
|
|
420
|
+
message: `Catalog source "${options.sourceId}" cannot reproduce the damaged Active entry. Use the current candidate replacement Review.`,
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return { sourceId: options.sourceId, candidate, manifest: resolved.resolution.manifest };
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
if (error instanceof CatalogGenerationError)
|
|
427
|
+
throw error;
|
|
428
|
+
throw new CatalogGenerationError({
|
|
429
|
+
code: 'catalogReplaceDamagedRequired', sourceId: options.sourceId,
|
|
430
|
+
message: `Catalog source "${options.sourceId}" cannot reproduce the damaged Active entry. Use the current candidate replacement Review.`,
|
|
431
|
+
cause: error,
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
finally {
|
|
435
|
+
if (resolved)
|
|
436
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
export async function probeCatalogSourceFreshness(options) {
|
|
440
|
+
const env = options.env ?? process.env;
|
|
441
|
+
options.signal?.throwIfAborted();
|
|
442
|
+
const source = (await readCatalogSourcesConfigSnapshot(env)).config.sources
|
|
443
|
+
.find((entry) => entry.id === options.sourceId);
|
|
444
|
+
if (!source)
|
|
445
|
+
throw new CatalogGenerationError({
|
|
446
|
+
code: 'catalogGenerationSourceMissing',
|
|
447
|
+
sourceId: options.sourceId,
|
|
448
|
+
message: `Catalog source "${options.sourceId}" is not configured.`,
|
|
449
|
+
});
|
|
450
|
+
const active = await resolveValidatedActiveCatalogGeneration({
|
|
451
|
+
sourceId: source.id,
|
|
452
|
+
env,
|
|
453
|
+
validatedStoreEntries: options.runtime?.validatedStoreEntries,
|
|
454
|
+
validatingStoreEntries: options.runtime?.validatingStoreEntries,
|
|
455
|
+
}).catch(() => undefined);
|
|
456
|
+
const activeEvidence = active ? {
|
|
457
|
+
logicalIdentity: active.logicalIdentity,
|
|
458
|
+
catalogVersion: active.catalogVersion,
|
|
459
|
+
snapshotDigest: active.snapshotDigest,
|
|
460
|
+
resolvedCommit: active.resolvedCommit,
|
|
461
|
+
} : undefined;
|
|
462
|
+
if (source.type === 'git' && active && options.fullValidation !== true) {
|
|
463
|
+
const remote = await (options.runtime?.probeGitRef ?? catalogGitProviderInternal.probeRef)(source, {
|
|
464
|
+
cliVersion: options.cliVersion,
|
|
465
|
+
env,
|
|
466
|
+
signal: options.signal,
|
|
467
|
+
});
|
|
468
|
+
if (remote.sourceId !== source.id || remote.sourceIdentity !== active.sourceIdentity) {
|
|
469
|
+
throw new CatalogGenerationError({
|
|
470
|
+
code: 'catalogGenerationIdentityMismatch',
|
|
471
|
+
sourceId: source.id,
|
|
472
|
+
message: `Catalog provider returned mismatched identity for source "${source.id}".`,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
if (remote.fixed) {
|
|
476
|
+
return {
|
|
477
|
+
sourceId: source.id,
|
|
478
|
+
state: 'fixed',
|
|
479
|
+
activeVersion: active.catalogVersion,
|
|
480
|
+
activeResolvedCommit: active.resolvedCommit,
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
if (remote.resolvedCommit === active.resolvedCommit) {
|
|
484
|
+
return {
|
|
485
|
+
sourceId: source.id,
|
|
486
|
+
state: 'current',
|
|
487
|
+
activeVersion: active.catalogVersion,
|
|
488
|
+
activeResolvedCommit: remote.resolvedCommit,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
const probe = await probeCatalogSourceGeneration({
|
|
493
|
+
sourceId: source.id,
|
|
494
|
+
source,
|
|
495
|
+
cliVersion: options.cliVersion,
|
|
496
|
+
env,
|
|
497
|
+
signal: options.signal,
|
|
498
|
+
runtime: options.runtime,
|
|
499
|
+
});
|
|
500
|
+
return {
|
|
501
|
+
...compareCatalogGenerationFreshness({
|
|
502
|
+
sourceType: source.type,
|
|
503
|
+
...(activeEvidence ? { active: activeEvidence } : {}),
|
|
504
|
+
candidate: probe.candidate,
|
|
505
|
+
}),
|
|
506
|
+
sourceId: source.id,
|
|
507
|
+
reusableCandidate: {
|
|
508
|
+
probe,
|
|
509
|
+
sourceConfigFingerprint: calculateCatalogSourceConfigFingerprint(source),
|
|
510
|
+
activeStoreKey: active?.storeKey ?? null,
|
|
511
|
+
},
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
export async function recordCatalogGenerationCheck(options) {
|
|
515
|
+
const env = options.env ?? process.env;
|
|
516
|
+
const lastSync = await writeLastSync({
|
|
517
|
+
sourceId: options.probe.sourceId, candidate: options.probe.candidate,
|
|
518
|
+
mode: 'check', state: 'succeeded', env,
|
|
519
|
+
signal: options.signal, runtime: options.runtime,
|
|
520
|
+
});
|
|
521
|
+
const active = (await readCatalogGenerationState(env)).sources[options.probe.sourceId]?.active;
|
|
522
|
+
return {
|
|
523
|
+
catalogGenerationSchemaVersion: 1, sourceId: options.probe.sourceId,
|
|
524
|
+
mode: 'check', outcome: 'checked', activeChanged: false,
|
|
525
|
+
resolution: publicEvidence(options.probe.candidate),
|
|
526
|
+
...(active ? { active } : {}), lastSync,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
async function activateResolvedCandidate(options) {
|
|
530
|
+
const candidate = options.resolved.candidate;
|
|
531
|
+
const store = options.store ?? await publishCatalogStoreEntry({
|
|
532
|
+
resolution: options.resolved.resolution, env: options.env, signal: options.signal,
|
|
533
|
+
afterInactiveRepairPrepared: options.runtime?.afterInactiveStoreRepairPrepared,
|
|
534
|
+
});
|
|
535
|
+
assertStoreMatchesCandidate(options.sourceId, store, candidate);
|
|
536
|
+
return withAwHomeMutationLock({
|
|
537
|
+
env: options.env,
|
|
538
|
+
token: options.token,
|
|
539
|
+
signal: options.signal,
|
|
540
|
+
action: async () => {
|
|
541
|
+
const lockedStore = await readCatalogStoreEntry({
|
|
542
|
+
logicalIdentity: store.metadata.logicalIdentity,
|
|
543
|
+
snapshotDigest: store.metadata.snapshotDigest,
|
|
544
|
+
env: options.env,
|
|
545
|
+
});
|
|
546
|
+
assertStoreMatchesCandidate(options.sourceId, lockedStore, candidate);
|
|
547
|
+
const source = await assertCurrentSource({
|
|
548
|
+
sourceId: options.sourceId,
|
|
549
|
+
candidate,
|
|
550
|
+
env: options.env,
|
|
551
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
552
|
+
});
|
|
553
|
+
const syncedAt = now(options.runtime);
|
|
554
|
+
return withCatalogGenerationStateTransaction({
|
|
555
|
+
env: options.env,
|
|
556
|
+
beforeReplace: async () => {
|
|
557
|
+
await assertCurrentSource({
|
|
558
|
+
sourceId: options.sourceId,
|
|
559
|
+
candidate,
|
|
560
|
+
env: options.env,
|
|
561
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
562
|
+
});
|
|
563
|
+
},
|
|
564
|
+
action: async (current) => {
|
|
565
|
+
const previous = current.sources[options.sourceId]?.active;
|
|
566
|
+
assertExpectedActive(options.sourceId, previous, options.expectedActive);
|
|
567
|
+
const policy = await enforceCatalogActivationCandidatePolicy({
|
|
568
|
+
sourceId: options.sourceId,
|
|
569
|
+
source,
|
|
570
|
+
active: previous,
|
|
571
|
+
candidate,
|
|
572
|
+
mode: options.activationMode,
|
|
573
|
+
env: options.env,
|
|
574
|
+
});
|
|
575
|
+
const impact = await inspectActivationImpact({
|
|
576
|
+
sourceId: options.sourceId,
|
|
577
|
+
source,
|
|
578
|
+
cwd: options.cwd ?? process.cwd(),
|
|
579
|
+
env: options.env,
|
|
580
|
+
mode: options.impactMode ?? 'generation',
|
|
581
|
+
candidateManifest: options.resolved.resolution.manifest,
|
|
582
|
+
runtime: options.runtime,
|
|
583
|
+
});
|
|
584
|
+
assertExpectedImpact({
|
|
585
|
+
sourceId: options.sourceId,
|
|
586
|
+
impact,
|
|
587
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
588
|
+
});
|
|
589
|
+
enforceCatalogActivationImpactPolicy({
|
|
590
|
+
sourceId: options.sourceId,
|
|
591
|
+
impact,
|
|
592
|
+
impactConfirmed: options.impactConfirmed,
|
|
593
|
+
});
|
|
594
|
+
const activeInput = {
|
|
595
|
+
sourceConfigFingerprint: candidate.sourceConfigFingerprint,
|
|
596
|
+
sourceIdentity: candidate.sourceIdentity,
|
|
597
|
+
requestedRef: candidate.requestedRef,
|
|
598
|
+
resolvedCommit: candidate.resolvedCommit,
|
|
599
|
+
logicalIdentity: store.metadata.logicalIdentity,
|
|
600
|
+
manifestDigest: store.metadata.manifestDigest,
|
|
601
|
+
snapshotDigest: store.metadata.snapshotDigest,
|
|
602
|
+
};
|
|
603
|
+
const unchanged = policy.preserveActive || sameActive(previous, activeInput);
|
|
604
|
+
const active = unchanged
|
|
605
|
+
? policy.preserveActive && source.type === 'git'
|
|
606
|
+
? { ...activeInput, activatedAt: previous.activatedAt }
|
|
607
|
+
: previous
|
|
608
|
+
: { ...activeInput, activatedAt: syncedAt };
|
|
609
|
+
const lastSync = {
|
|
610
|
+
syncedAt, mode: 'sync', state: 'succeeded', resolvedCommit: candidate.resolvedCommit,
|
|
611
|
+
};
|
|
612
|
+
return {
|
|
613
|
+
state: {
|
|
614
|
+
schemaVersion: 1,
|
|
615
|
+
sources: { ...current.sources, [options.sourceId]: { active, lastSync } },
|
|
616
|
+
},
|
|
617
|
+
result: {
|
|
618
|
+
catalogGenerationSchemaVersion: 1, sourceId: options.sourceId,
|
|
619
|
+
mode: 'sync', outcome: unchanged ? 'unchanged' : 'activated',
|
|
620
|
+
activeChanged: !unchanged, resolution: publicEvidence(candidate), active, lastSync,
|
|
621
|
+
impact,
|
|
622
|
+
},
|
|
623
|
+
};
|
|
624
|
+
},
|
|
625
|
+
});
|
|
626
|
+
},
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
export async function activateCatalogSourceGeneration(options) {
|
|
630
|
+
const env = options.env ?? process.env;
|
|
631
|
+
const initialCandidate = await readCandidateContinuity(options.sourceId, env);
|
|
632
|
+
let resolved;
|
|
633
|
+
try {
|
|
634
|
+
resolved = await resolveCandidate({ ...options, env });
|
|
635
|
+
if (options.expectedCandidate
|
|
636
|
+
&& !compareCatalogGenerationCandidates(options.expectedCandidate, resolved.candidate).matches) {
|
|
637
|
+
throw new CatalogGenerationError({
|
|
638
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
639
|
+
message: `Catalog source "${options.sourceId}" changed after review. Review it again.`,
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
const activationMode = options.activationMode ?? 'normal';
|
|
643
|
+
const active = (await readCatalogGenerationState(env)).sources[options.sourceId]?.active;
|
|
644
|
+
assertExpectedActive(options.sourceId, active, options.expectedActive);
|
|
645
|
+
await enforceCatalogActivationCandidatePolicy({
|
|
646
|
+
sourceId: options.sourceId,
|
|
647
|
+
source: resolved.source,
|
|
648
|
+
active,
|
|
649
|
+
candidate: resolved.candidate,
|
|
650
|
+
mode: activationMode,
|
|
651
|
+
env,
|
|
652
|
+
});
|
|
653
|
+
const impact = await inspectActivationImpact({
|
|
654
|
+
sourceId: options.sourceId,
|
|
655
|
+
cwd: options.cwd ?? process.cwd(),
|
|
656
|
+
env,
|
|
657
|
+
source: resolved.source,
|
|
658
|
+
mode: options.impactMode ?? 'generation',
|
|
659
|
+
candidateManifest: resolved.resolution.manifest,
|
|
660
|
+
runtime: options.runtime,
|
|
661
|
+
});
|
|
662
|
+
assertExpectedImpact({
|
|
663
|
+
sourceId: options.sourceId,
|
|
664
|
+
impact,
|
|
665
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
666
|
+
});
|
|
667
|
+
await options.runtime?.afterCandidateResolved?.();
|
|
668
|
+
return await activateResolvedCandidate({
|
|
669
|
+
...options,
|
|
670
|
+
env,
|
|
671
|
+
resolved,
|
|
672
|
+
activationMode,
|
|
673
|
+
impactConfirmed: options.impactConfirmed === true,
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
catch (error) {
|
|
677
|
+
if (!(error instanceof CatalogGenerationError
|
|
678
|
+
&& error.code === 'catalogGenerationReviewStale')) {
|
|
679
|
+
await recordFailure({
|
|
680
|
+
sourceId: options.sourceId, candidate: resolved?.candidate ?? initialCandidate, mode: 'sync',
|
|
681
|
+
errorCode: error instanceof CatalogGenerationError
|
|
682
|
+
? error.code : 'catalogGenerationRefreshFailed',
|
|
683
|
+
env, signal: options.signal, runtime: options.runtime,
|
|
684
|
+
});
|
|
685
|
+
}
|
|
686
|
+
if (error instanceof CatalogGenerationError)
|
|
687
|
+
throw error;
|
|
688
|
+
throw new CatalogGenerationError({
|
|
689
|
+
code: 'catalogGenerationRefreshFailed', sourceId: options.sourceId,
|
|
690
|
+
message: `Cannot sync Catalog source "${options.sourceId}". The previous Active snapshot is unchanged.`,
|
|
691
|
+
cause: error,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
finally {
|
|
695
|
+
if (resolved)
|
|
696
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
export async function recoverCatalogGenerationStateAndActivate(options) {
|
|
700
|
+
const env = options.env ?? process.env;
|
|
701
|
+
let resolved;
|
|
702
|
+
try {
|
|
703
|
+
resolved = await resolveCandidate({ ...options, env });
|
|
704
|
+
if (!compareCatalogGenerationCandidates(options.expectedCandidate, resolved.candidate).matches) {
|
|
705
|
+
throw new CatalogGenerationError({
|
|
706
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
707
|
+
message: `Catalog source "${options.sourceId}" changed after review. Review it again.`,
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
const impact = await inspectCatalogSourceImpact({
|
|
711
|
+
sourceId: options.sourceId,
|
|
712
|
+
cwd: options.cwd ?? process.cwd(),
|
|
713
|
+
env,
|
|
714
|
+
sourcePrimary: resolved.source.primary,
|
|
715
|
+
mode: 'generation',
|
|
716
|
+
candidateManifest: resolved.resolution.manifest,
|
|
717
|
+
});
|
|
718
|
+
assertExpectedImpact({
|
|
719
|
+
sourceId: options.sourceId,
|
|
720
|
+
impact,
|
|
721
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
722
|
+
});
|
|
723
|
+
await options.runtime?.afterCandidateResolved?.();
|
|
724
|
+
const store = await publishCatalogStoreEntry({
|
|
725
|
+
resolution: resolved.resolution, env, signal: options.signal,
|
|
726
|
+
afterInactiveRepairPrepared: options.runtime?.afterInactiveStoreRepairPrepared,
|
|
727
|
+
});
|
|
728
|
+
assertStoreMatchesCandidate(options.sourceId, store, resolved.candidate);
|
|
729
|
+
await options.runtime?.afterRecoveryStorePublished?.();
|
|
730
|
+
return await withAwHomeMutationLock({
|
|
731
|
+
env,
|
|
732
|
+
signal: options.signal,
|
|
733
|
+
action: async () => {
|
|
734
|
+
const lockedStore = await readCatalogStoreEntry({
|
|
735
|
+
logicalIdentity: store.metadata.logicalIdentity,
|
|
736
|
+
snapshotDigest: store.metadata.snapshotDigest,
|
|
737
|
+
env,
|
|
738
|
+
});
|
|
739
|
+
assertStoreMatchesCandidate(options.sourceId, lockedStore, resolved.candidate);
|
|
740
|
+
const source = await assertCurrentSource({
|
|
741
|
+
sourceId: options.sourceId,
|
|
742
|
+
candidate: resolved.candidate,
|
|
743
|
+
env,
|
|
744
|
+
});
|
|
745
|
+
await enforceCatalogActivationCandidatePolicy({
|
|
746
|
+
sourceId: options.sourceId,
|
|
747
|
+
source,
|
|
748
|
+
active: undefined,
|
|
749
|
+
candidate: resolved.candidate,
|
|
750
|
+
mode: 'normal',
|
|
751
|
+
env,
|
|
752
|
+
});
|
|
753
|
+
const lockedImpact = await inspectActivationImpact({
|
|
754
|
+
sourceId: options.sourceId,
|
|
755
|
+
source,
|
|
756
|
+
cwd: options.cwd ?? process.cwd(),
|
|
757
|
+
env,
|
|
758
|
+
mode: 'generation',
|
|
759
|
+
candidateManifest: resolved.resolution.manifest,
|
|
760
|
+
runtime: options.runtime,
|
|
761
|
+
});
|
|
762
|
+
assertExpectedImpact({
|
|
763
|
+
sourceId: options.sourceId,
|
|
764
|
+
impact: lockedImpact,
|
|
765
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
766
|
+
});
|
|
767
|
+
enforceCatalogActivationImpactPolicy({
|
|
768
|
+
sourceId: options.sourceId,
|
|
769
|
+
impact: lockedImpact,
|
|
770
|
+
impactConfirmed: options.impactConfirmed === true,
|
|
771
|
+
});
|
|
772
|
+
const syncedAt = now(options.runtime);
|
|
773
|
+
const candidate = resolved.candidate;
|
|
774
|
+
const active = {
|
|
775
|
+
sourceConfigFingerprint: candidate.sourceConfigFingerprint,
|
|
776
|
+
sourceIdentity: candidate.sourceIdentity,
|
|
777
|
+
requestedRef: candidate.requestedRef,
|
|
778
|
+
resolvedCommit: candidate.resolvedCommit,
|
|
779
|
+
logicalIdentity: store.metadata.logicalIdentity,
|
|
780
|
+
manifestDigest: store.metadata.manifestDigest,
|
|
781
|
+
snapshotDigest: store.metadata.snapshotDigest,
|
|
782
|
+
activatedAt: syncedAt,
|
|
783
|
+
};
|
|
784
|
+
const lastSync = {
|
|
785
|
+
syncedAt, mode: 'sync', state: 'succeeded', resolvedCommit: candidate.resolvedCommit,
|
|
786
|
+
};
|
|
787
|
+
await replaceInvalidCatalogGenerationState({
|
|
788
|
+
env,
|
|
789
|
+
state: { schemaVersion: 1, sources: { [options.sourceId]: { active, lastSync } } },
|
|
790
|
+
beforeReplace: async () => {
|
|
791
|
+
await assertCurrentSource({
|
|
792
|
+
sourceId: options.sourceId, candidate, env,
|
|
793
|
+
});
|
|
794
|
+
},
|
|
795
|
+
});
|
|
796
|
+
return {
|
|
797
|
+
catalogGenerationSchemaVersion: 1,
|
|
798
|
+
sourceId: options.sourceId,
|
|
799
|
+
mode: 'sync',
|
|
800
|
+
outcome: 'activated',
|
|
801
|
+
activeChanged: true,
|
|
802
|
+
resolution: publicEvidence(candidate),
|
|
803
|
+
active,
|
|
804
|
+
lastSync,
|
|
805
|
+
impact: lockedImpact,
|
|
806
|
+
};
|
|
807
|
+
},
|
|
808
|
+
});
|
|
809
|
+
}
|
|
810
|
+
finally {
|
|
811
|
+
if (resolved)
|
|
812
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
export async function repairCatalogSourceGeneration(options) {
|
|
816
|
+
const env = options.env ?? process.env;
|
|
817
|
+
const target = options.expectedActive === undefined
|
|
818
|
+
? (await readCatalogGenerationState(env)).sources[options.sourceId]?.active
|
|
819
|
+
: options.expectedActive ?? undefined;
|
|
820
|
+
if (!target)
|
|
821
|
+
throw new CatalogGenerationError({
|
|
822
|
+
code: 'catalogGenerationUnavailable', sourceId: options.sourceId,
|
|
823
|
+
message: `Catalog source "${options.sourceId}" has no Active snapshot to repair.`,
|
|
824
|
+
});
|
|
825
|
+
let resolved;
|
|
826
|
+
let preparedRepair;
|
|
827
|
+
try {
|
|
828
|
+
const config = await readCatalogSourcesConfigSnapshot(env);
|
|
829
|
+
if (options.expectedConfigDigest && config.digest !== options.expectedConfigDigest) {
|
|
830
|
+
throw new CatalogGenerationError({
|
|
831
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
832
|
+
message: `Catalog source "${options.sourceId}" configuration changed after review.`,
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
const source = config.config.sources.find((entry) => entry.id === options.sourceId);
|
|
836
|
+
if (!source)
|
|
837
|
+
throw new CatalogGenerationError({
|
|
838
|
+
code: 'catalogGenerationSourceMissing', sourceId: options.sourceId,
|
|
839
|
+
message: `Catalog source "${options.sourceId}" is not configured.`,
|
|
840
|
+
});
|
|
841
|
+
const exactSource = source.type === 'git'
|
|
842
|
+
? { ...source, refPolicy: { type: 'explicit', ref: target.resolvedCommit } }
|
|
843
|
+
: source;
|
|
844
|
+
const exact = await resolveCandidate({ ...options, source: exactSource, env });
|
|
845
|
+
resolved = {
|
|
846
|
+
...exact,
|
|
847
|
+
source,
|
|
848
|
+
candidate: {
|
|
849
|
+
...exact.candidate,
|
|
850
|
+
sourceConfigFingerprint: calculateCatalogSourceConfigFingerprint(source),
|
|
851
|
+
sourceIdentity: await calculateCatalogSourceIdentity(source),
|
|
852
|
+
requestedRef: target.requestedRef,
|
|
853
|
+
},
|
|
854
|
+
};
|
|
855
|
+
if (options.expectedCandidate
|
|
856
|
+
&& !compareCatalogGenerationCandidates(options.expectedCandidate, resolved.candidate).matches) {
|
|
857
|
+
throw new CatalogGenerationError({
|
|
858
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
859
|
+
message: `Catalog source "${options.sourceId}" changed after review. Review it again.`,
|
|
860
|
+
});
|
|
861
|
+
}
|
|
862
|
+
await options.runtime?.afterCandidateResolved?.();
|
|
863
|
+
if (resolved.candidate.logicalIdentity !== target.logicalIdentity
|
|
864
|
+
|| resolved.candidate.snapshotDigest !== target.snapshotDigest
|
|
865
|
+
|| resolved.candidate.manifestDigest !== target.manifestDigest
|
|
866
|
+
|| resolved.candidate.resolvedCommit !== target.resolvedCommit) {
|
|
867
|
+
throw new CatalogGenerationError({
|
|
868
|
+
code: 'catalogReplaceDamagedRequired', sourceId: options.sourceId,
|
|
869
|
+
message: `Catalog source "${options.sourceId}" cannot reproduce the damaged Active entry. Use the current candidate replacement Review.`,
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
preparedRepair = await prepareCatalogStoreEntryRepair({
|
|
873
|
+
resolution: resolved.resolution,
|
|
874
|
+
logicalIdentity: target.logicalIdentity,
|
|
875
|
+
snapshotDigest: target.snapshotDigest,
|
|
876
|
+
env,
|
|
877
|
+
signal: options.signal,
|
|
878
|
+
});
|
|
879
|
+
return await withAwHomeMutationLock({
|
|
880
|
+
env,
|
|
881
|
+
signal: options.signal,
|
|
882
|
+
action: async () => {
|
|
883
|
+
const currentSource = await assertCurrentSource({
|
|
884
|
+
sourceId: options.sourceId,
|
|
885
|
+
candidate: resolved.candidate,
|
|
886
|
+
env,
|
|
887
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
888
|
+
});
|
|
889
|
+
const currentState = await readCatalogGenerationState(env);
|
|
890
|
+
const current = currentState.sources[options.sourceId]?.active;
|
|
891
|
+
assertExpectedActive(options.sourceId, current, options.expectedActive);
|
|
892
|
+
if (options.expectedActive === undefined)
|
|
893
|
+
assertExpectedActive(options.sourceId, current, target);
|
|
894
|
+
await enforceCatalogActivationCandidatePolicy({
|
|
895
|
+
sourceId: options.sourceId,
|
|
896
|
+
source: currentSource,
|
|
897
|
+
active: current,
|
|
898
|
+
candidate: resolved.candidate,
|
|
899
|
+
mode: 'exactRepair',
|
|
900
|
+
env,
|
|
901
|
+
});
|
|
902
|
+
const store = await preparedRepair.commit();
|
|
903
|
+
assertStoreMatchesCandidate(options.sourceId, store, resolved.candidate);
|
|
904
|
+
const syncedAt = now(options.runtime);
|
|
905
|
+
const lastSync = {
|
|
906
|
+
syncedAt,
|
|
907
|
+
mode: 'sync',
|
|
908
|
+
state: 'succeeded',
|
|
909
|
+
resolvedCommit: target.resolvedCommit,
|
|
910
|
+
};
|
|
911
|
+
await withCatalogGenerationStateTransaction({
|
|
912
|
+
env,
|
|
913
|
+
beforeReplace: async () => {
|
|
914
|
+
await assertCurrentSource({
|
|
915
|
+
sourceId: options.sourceId,
|
|
916
|
+
candidate: resolved.candidate,
|
|
917
|
+
env,
|
|
918
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
919
|
+
});
|
|
920
|
+
const active = (await readCatalogGenerationState(env)).sources[options.sourceId]?.active;
|
|
921
|
+
assertExpectedActive(options.sourceId, active, options.expectedActive ?? target);
|
|
922
|
+
},
|
|
923
|
+
action: async (latest) => ({
|
|
924
|
+
state: {
|
|
925
|
+
schemaVersion: 1,
|
|
926
|
+
sources: {
|
|
927
|
+
...latest.sources,
|
|
928
|
+
[options.sourceId]: { active: target, lastSync },
|
|
929
|
+
},
|
|
930
|
+
},
|
|
931
|
+
result: undefined,
|
|
932
|
+
}),
|
|
933
|
+
});
|
|
934
|
+
return {
|
|
935
|
+
catalogGenerationSchemaVersion: 1,
|
|
936
|
+
sourceId: options.sourceId,
|
|
937
|
+
mode: 'sync',
|
|
938
|
+
outcome: 'unchanged',
|
|
939
|
+
activeChanged: false,
|
|
940
|
+
resolution: publicEvidence(resolved.candidate),
|
|
941
|
+
active: target,
|
|
942
|
+
lastSync,
|
|
943
|
+
};
|
|
944
|
+
},
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
catch (error) {
|
|
948
|
+
if (error instanceof CatalogGenerationError)
|
|
949
|
+
throw error;
|
|
950
|
+
throw new CatalogGenerationError({
|
|
951
|
+
code: 'catalogReplaceDamagedRequired', sourceId: options.sourceId,
|
|
952
|
+
message: `Catalog source "${options.sourceId}" cannot reproduce the damaged Active entry. Use --replace-damaged --yes to use the current candidate.`,
|
|
953
|
+
cause: error,
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
finally {
|
|
957
|
+
if (preparedRepair)
|
|
958
|
+
await preparedRepair.cleanup();
|
|
959
|
+
if (resolved)
|
|
960
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
export async function replaceDamagedCatalogSourceGeneration(options) {
|
|
964
|
+
const env = options.env ?? process.env;
|
|
965
|
+
let resolved;
|
|
966
|
+
let preparedRepair;
|
|
967
|
+
try {
|
|
968
|
+
resolved = await resolveCandidate({ ...options, env });
|
|
969
|
+
if (options.expectedCandidate
|
|
970
|
+
&& !compareCatalogGenerationCandidates(options.expectedCandidate, resolved.candidate).matches) {
|
|
971
|
+
throw new CatalogGenerationError({
|
|
972
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
973
|
+
message: `Catalog source "${options.sourceId}" changed after review. Review it again.`,
|
|
974
|
+
});
|
|
975
|
+
}
|
|
976
|
+
const targetKey = createCatalogStoreKey(options.expectedActive.logicalIdentity, options.expectedActive.snapshotDigest);
|
|
977
|
+
const candidateKey = createCatalogStoreKey(resolved.candidate.logicalIdentity, resolved.candidate.snapshotDigest);
|
|
978
|
+
const impact = await inspectCatalogSourceImpact({
|
|
979
|
+
sourceId: options.sourceId,
|
|
980
|
+
cwd: options.cwd ?? process.cwd(),
|
|
981
|
+
env,
|
|
982
|
+
sourcePrimary: resolved.source.primary,
|
|
983
|
+
mode: 'generation',
|
|
984
|
+
candidateManifest: resolved.resolution.manifest,
|
|
985
|
+
});
|
|
986
|
+
assertExpectedImpact({
|
|
987
|
+
sourceId: options.sourceId,
|
|
988
|
+
impact,
|
|
989
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
990
|
+
});
|
|
991
|
+
await options.runtime?.afterCandidateResolved?.();
|
|
992
|
+
if (targetKey === candidateKey) {
|
|
993
|
+
preparedRepair = await prepareCatalogStoreEntryRepair({
|
|
994
|
+
resolution: resolved.resolution,
|
|
995
|
+
logicalIdentity: resolved.candidate.logicalIdentity,
|
|
996
|
+
snapshotDigest: resolved.candidate.snapshotDigest,
|
|
997
|
+
env,
|
|
998
|
+
signal: options.signal,
|
|
999
|
+
});
|
|
1000
|
+
return await withAwHomeMutationLock({
|
|
1001
|
+
env,
|
|
1002
|
+
signal: options.signal,
|
|
1003
|
+
action: async () => {
|
|
1004
|
+
const source = await assertCurrentSource({
|
|
1005
|
+
sourceId: options.sourceId,
|
|
1006
|
+
candidate: resolved.candidate,
|
|
1007
|
+
env,
|
|
1008
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
1009
|
+
});
|
|
1010
|
+
const syncedAt = now(options.runtime);
|
|
1011
|
+
return withCatalogGenerationStateTransaction({
|
|
1012
|
+
env,
|
|
1013
|
+
beforeReplace: async () => {
|
|
1014
|
+
await assertCurrentSource({
|
|
1015
|
+
sourceId: options.sourceId,
|
|
1016
|
+
candidate: resolved.candidate,
|
|
1017
|
+
env,
|
|
1018
|
+
expectedConfigDigest: options.expectedConfigDigest,
|
|
1019
|
+
});
|
|
1020
|
+
},
|
|
1021
|
+
action: async (current) => {
|
|
1022
|
+
const previous = current.sources[options.sourceId]?.active;
|
|
1023
|
+
assertExpectedActive(options.sourceId, previous, options.expectedActive);
|
|
1024
|
+
await enforceCatalogActivationCandidatePolicy({
|
|
1025
|
+
sourceId: options.sourceId,
|
|
1026
|
+
source,
|
|
1027
|
+
active: previous,
|
|
1028
|
+
candidate: resolved.candidate,
|
|
1029
|
+
mode: 'replaceDamaged',
|
|
1030
|
+
env,
|
|
1031
|
+
});
|
|
1032
|
+
const lockedImpact = await inspectActivationImpact({
|
|
1033
|
+
sourceId: options.sourceId,
|
|
1034
|
+
source,
|
|
1035
|
+
cwd: options.cwd ?? process.cwd(),
|
|
1036
|
+
env,
|
|
1037
|
+
mode: 'generation',
|
|
1038
|
+
candidateManifest: resolved.resolution.manifest,
|
|
1039
|
+
runtime: options.runtime,
|
|
1040
|
+
});
|
|
1041
|
+
assertExpectedImpact({
|
|
1042
|
+
sourceId: options.sourceId,
|
|
1043
|
+
impact: lockedImpact,
|
|
1044
|
+
expectedImpactDigest: options.expectedImpactDigest,
|
|
1045
|
+
});
|
|
1046
|
+
enforceCatalogActivationImpactPolicy({
|
|
1047
|
+
sourceId: options.sourceId,
|
|
1048
|
+
impact: lockedImpact,
|
|
1049
|
+
impactConfirmed: options.impactConfirmed === true,
|
|
1050
|
+
});
|
|
1051
|
+
const store = await preparedRepair.commit();
|
|
1052
|
+
assertStoreMatchesCandidate(options.sourceId, store, resolved.candidate);
|
|
1053
|
+
const activeInput = {
|
|
1054
|
+
sourceConfigFingerprint: resolved.candidate.sourceConfigFingerprint,
|
|
1055
|
+
sourceIdentity: resolved.candidate.sourceIdentity,
|
|
1056
|
+
requestedRef: resolved.candidate.requestedRef,
|
|
1057
|
+
resolvedCommit: resolved.candidate.resolvedCommit,
|
|
1058
|
+
logicalIdentity: store.metadata.logicalIdentity,
|
|
1059
|
+
manifestDigest: store.metadata.manifestDigest,
|
|
1060
|
+
snapshotDigest: store.metadata.snapshotDigest,
|
|
1061
|
+
};
|
|
1062
|
+
const unchanged = sameActive(previous, activeInput);
|
|
1063
|
+
const active = unchanged
|
|
1064
|
+
? previous
|
|
1065
|
+
: { ...activeInput, activatedAt: syncedAt };
|
|
1066
|
+
const lastSync = {
|
|
1067
|
+
syncedAt,
|
|
1068
|
+
mode: 'sync',
|
|
1069
|
+
state: 'succeeded',
|
|
1070
|
+
resolvedCommit: resolved.candidate.resolvedCommit,
|
|
1071
|
+
};
|
|
1072
|
+
return {
|
|
1073
|
+
state: {
|
|
1074
|
+
schemaVersion: 1,
|
|
1075
|
+
sources: { ...current.sources, [options.sourceId]: { active, lastSync } },
|
|
1076
|
+
},
|
|
1077
|
+
result: {
|
|
1078
|
+
catalogGenerationSchemaVersion: 1,
|
|
1079
|
+
sourceId: options.sourceId,
|
|
1080
|
+
mode: 'sync',
|
|
1081
|
+
outcome: unchanged ? 'unchanged' : 'activated',
|
|
1082
|
+
activeChanged: !unchanged,
|
|
1083
|
+
resolution: publicEvidence(resolved.candidate),
|
|
1084
|
+
active,
|
|
1085
|
+
lastSync,
|
|
1086
|
+
impact: lockedImpact,
|
|
1087
|
+
},
|
|
1088
|
+
};
|
|
1089
|
+
},
|
|
1090
|
+
});
|
|
1091
|
+
},
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1094
|
+
return await activateResolvedCandidate({
|
|
1095
|
+
...options,
|
|
1096
|
+
env,
|
|
1097
|
+
resolved,
|
|
1098
|
+
expectedActive: options.expectedActive,
|
|
1099
|
+
activationMode: 'replaceDamaged',
|
|
1100
|
+
impactConfirmed: options.impactConfirmed === true,
|
|
1101
|
+
});
|
|
1102
|
+
}
|
|
1103
|
+
finally {
|
|
1104
|
+
if (preparedRepair)
|
|
1105
|
+
await preparedRepair.cleanup();
|
|
1106
|
+
if (resolved)
|
|
1107
|
+
await resolved.resolution.cleanup().catch(() => warnCleanupFailure(options.sourceId));
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
async function inferredActivationMode(options) {
|
|
1111
|
+
if (!options.active)
|
|
1112
|
+
return 'normal';
|
|
1113
|
+
const source = (await readCatalogSourcesConfigSnapshot(options.env)).config.sources
|
|
1114
|
+
.find((entry) => entry.id === options.sourceId);
|
|
1115
|
+
if (!source)
|
|
1116
|
+
return 'normal';
|
|
1117
|
+
return options.active.sourceConfigFingerprint !== calculateCatalogSourceConfigFingerprint(source)
|
|
1118
|
+
|| options.active.sourceIdentity !== await calculateCatalogSourceIdentity(source)
|
|
1119
|
+
? 'explicitSourceChange'
|
|
1120
|
+
: 'normal';
|
|
1121
|
+
}
|
|
1122
|
+
export async function syncCatalogSourceGeneration(options) {
|
|
1123
|
+
const env = options.env ?? process.env;
|
|
1124
|
+
if (!options.check) {
|
|
1125
|
+
const config = await readCatalogSourcesConfigSnapshot(env);
|
|
1126
|
+
const active = (await readCatalogGenerationState(env)).sources[options.sourceId]?.active;
|
|
1127
|
+
if (options.replaceDamaged === true && options.impactConfirmed !== true) {
|
|
1128
|
+
throw new CatalogGenerationError({
|
|
1129
|
+
code: 'catalogImpactConfirmationRequired', sourceId: options.sourceId,
|
|
1130
|
+
message: '--replace-damaged requires --yes.',
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
if (active) {
|
|
1134
|
+
const damaged = await readCatalogStoreEntry({
|
|
1135
|
+
logicalIdentity: active.logicalIdentity,
|
|
1136
|
+
snapshotDigest: active.snapshotDigest,
|
|
1137
|
+
env,
|
|
1138
|
+
}).then(() => false).catch(() => true);
|
|
1139
|
+
if (damaged) {
|
|
1140
|
+
try {
|
|
1141
|
+
await repairCatalogSourceGeneration({
|
|
1142
|
+
...options,
|
|
1143
|
+
env,
|
|
1144
|
+
expectedActive: active,
|
|
1145
|
+
expectedConfigDigest: config.digest,
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
catch (error) {
|
|
1149
|
+
if (!(error instanceof CatalogGenerationError)
|
|
1150
|
+
|| error.code !== 'catalogReplaceDamagedRequired'
|
|
1151
|
+
|| options.replaceDamaged !== true)
|
|
1152
|
+
throw error;
|
|
1153
|
+
return replaceDamagedCatalogSourceGeneration({
|
|
1154
|
+
...options,
|
|
1155
|
+
env,
|
|
1156
|
+
expectedActive: active,
|
|
1157
|
+
expectedConfigDigest: config.digest,
|
|
1158
|
+
impactConfirmed: true,
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
else if (options.replaceDamaged === true) {
|
|
1163
|
+
throw new CatalogGenerationError({
|
|
1164
|
+
code: 'catalogGenerationReviewStale', sourceId: options.sourceId,
|
|
1165
|
+
message: `Catalog source "${options.sourceId}" Active entry is not damaged.`,
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
return activateCatalogSourceGeneration({
|
|
1170
|
+
...options,
|
|
1171
|
+
env,
|
|
1172
|
+
expectedActive: active ?? null,
|
|
1173
|
+
activationMode: await inferredActivationMode({ sourceId: options.sourceId, active, env }),
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
const initialCandidate = await readCandidateContinuity(options.sourceId, env);
|
|
1177
|
+
let probe;
|
|
1178
|
+
try {
|
|
1179
|
+
probe = await probeCatalogSourceGeneration({ ...options, env });
|
|
1180
|
+
const source = (await readCatalogSourcesConfigSnapshot(env)).config.sources
|
|
1181
|
+
.find((entry) => entry.id === options.sourceId);
|
|
1182
|
+
const impact = await inspectCatalogSourceImpact({
|
|
1183
|
+
sourceId: options.sourceId,
|
|
1184
|
+
cwd: options.cwd ?? process.cwd(),
|
|
1185
|
+
env,
|
|
1186
|
+
sourcePrimary: source?.primary === true,
|
|
1187
|
+
mode: 'generation',
|
|
1188
|
+
candidateManifest: probe.manifest,
|
|
1189
|
+
});
|
|
1190
|
+
const result = await recordCatalogGenerationCheck({
|
|
1191
|
+
probe,
|
|
1192
|
+
env,
|
|
1193
|
+
signal: options.signal,
|
|
1194
|
+
runtime: options.runtime,
|
|
1195
|
+
});
|
|
1196
|
+
return { ...result, impact };
|
|
1197
|
+
}
|
|
1198
|
+
catch (error) {
|
|
1199
|
+
await recordFailure({
|
|
1200
|
+
sourceId: options.sourceId, candidate: probe?.candidate ?? initialCandidate, mode: 'check',
|
|
1201
|
+
errorCode: error instanceof CatalogGenerationError
|
|
1202
|
+
? error.code : 'catalogGenerationRefreshFailed',
|
|
1203
|
+
env, signal: options.signal, runtime: options.runtime,
|
|
1204
|
+
});
|
|
1205
|
+
if (error instanceof CatalogGenerationError)
|
|
1206
|
+
throw error;
|
|
1207
|
+
throw new CatalogGenerationError({
|
|
1208
|
+
code: 'catalogGenerationRefreshFailed', sourceId: options.sourceId,
|
|
1209
|
+
message: `Cannot check Catalog source "${options.sourceId}".`, cause: error,
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
1213
|
+
export async function readCatalogGenerationStatus(options = {}) {
|
|
1214
|
+
const env = options.env ?? process.env;
|
|
1215
|
+
const config = await readCatalogSourcesConfigSnapshot(env);
|
|
1216
|
+
const state = await readCatalogGenerationState(env);
|
|
1217
|
+
const selected = options.sourceId
|
|
1218
|
+
? config.config.sources.filter((source) => source.id === options.sourceId)
|
|
1219
|
+
: config.config.sources;
|
|
1220
|
+
if (options.sourceId && selected.length === 0)
|
|
1221
|
+
throw new CatalogGenerationError({
|
|
1222
|
+
code: 'catalogGenerationSourceMissing', sourceId: options.sourceId,
|
|
1223
|
+
message: `Catalog source "${options.sourceId}" is not configured.`,
|
|
1224
|
+
});
|
|
1225
|
+
const sources = await Promise.all(selected.map(async (source) => {
|
|
1226
|
+
const configuredSourceIdentity = await calculateCatalogSourceIdentity(source);
|
|
1227
|
+
const sourceState = state.sources[source.id];
|
|
1228
|
+
const active = sourceState?.active;
|
|
1229
|
+
const configMatchesActive = Boolean(active)
|
|
1230
|
+
&& active.sourceIdentity === configuredSourceIdentity
|
|
1231
|
+
&& active.sourceConfigFingerprint === calculateCatalogSourceConfigFingerprint(source);
|
|
1232
|
+
if (!active)
|
|
1233
|
+
return {
|
|
1234
|
+
sourceId: source.id, configuredSourceIdentity, activeReady: false,
|
|
1235
|
+
configMatchesActive: false, lastSync: sourceState?.lastSync,
|
|
1236
|
+
compatibility: null,
|
|
1237
|
+
};
|
|
1238
|
+
try {
|
|
1239
|
+
const entry = await readValidatedCatalogGenerationStoreEntry({
|
|
1240
|
+
logicalIdentity: active.logicalIdentity,
|
|
1241
|
+
snapshotDigest: active.snapshotDigest,
|
|
1242
|
+
env,
|
|
1243
|
+
validatedStoreEntries: options.validatedStoreEntries,
|
|
1244
|
+
validatingStoreEntries: options.validatingStoreEntries,
|
|
1245
|
+
});
|
|
1246
|
+
if (entry.metadata.manifestDigest !== active.manifestDigest)
|
|
1247
|
+
throw new CatalogGenerationError({
|
|
1248
|
+
code: 'catalogGenerationIdentityMismatch', message: 'Active does not match store metadata.',
|
|
1249
|
+
});
|
|
1250
|
+
const compatibility = projectCatalogCapabilityCompatibility(entry.metadata.requiredAwCapabilities);
|
|
1251
|
+
return {
|
|
1252
|
+
sourceId: source.id, configuredSourceIdentity, active,
|
|
1253
|
+
activeReady: configMatchesActive && compatibility.state === 'supported',
|
|
1254
|
+
configMatchesActive,
|
|
1255
|
+
catalogVersion: entry.metadata.catalogVersion, channel: entry.metadata.channel,
|
|
1256
|
+
storeKey: createCatalogStoreKey(active.logicalIdentity, active.snapshotDigest),
|
|
1257
|
+
lastSync: sourceState?.lastSync, compatibility,
|
|
1258
|
+
};
|
|
1259
|
+
}
|
|
1260
|
+
catch (error) {
|
|
1261
|
+
return {
|
|
1262
|
+
sourceId: source.id, configuredSourceIdentity, active, activeReady: false,
|
|
1263
|
+
configMatchesActive, lastSync: sourceState?.lastSync,
|
|
1264
|
+
compatibility: null,
|
|
1265
|
+
errorCode: catalogGenerationErrorCode(error),
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
}));
|
|
1269
|
+
return { catalogGenerationStatusSchemaVersion: 2, sources };
|
|
1270
|
+
}
|
|
1271
|
+
//# sourceMappingURL=catalog-generation-service.js.map
|