@lesliechan721/aw 0.1.0-beta.7 → 0.1.0-beta.9
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/scripts/add-skill.mjs +4 -4
- package/dist/authoring/scripts/add-skill.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +8 -37
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
- package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -90
- package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -120
- package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
- package/dist/authoring/scripts/plugin-status.mjs +8 -11
- package/dist/authoring/scripts/plugin-status.mjs.map +1 -1
- package/dist/authoring/scripts/remove-plugin.mjs +2 -1
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +64 -758
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/aw-skill-eval-materializer.d.ts +24 -0
- package/dist/scripts/{plugin-eval-materializer.js → aw-skill-eval-materializer.js} +34 -145
- 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 +2 -1
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +6 -8
- package/dist/scripts/plugin-staging.js +15 -28
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.js +2 -33
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/adapters/helpers.js +2 -2
- package/dist/src/adapters/helpers.js.map +1 -1
- package/dist/src/authoring/workspace-commands.d.ts +17 -1
- package/dist/src/authoring/workspace-commands.js +21 -4
- package/dist/src/authoring/workspace-commands.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +78 -0
- package/dist/src/commands/aw-capabilities.js +254 -0
- package/dist/src/commands/aw-capabilities.js.map +1 -0
- package/dist/src/commands/catalog-dev-source.d.ts +118 -0
- package/dist/src/commands/catalog-dev-source.js +417 -0
- package/dist/src/commands/catalog-dev-source.js.map +1 -0
- package/dist/src/commands/catalog-generation.d.ts +13 -0
- package/dist/src/commands/catalog-generation.js +13 -0
- package/dist/src/commands/catalog-generation.js.map +1 -0
- package/dist/src/commands/catalog-publication-inspection.d.ts +29 -28
- package/dist/src/commands/catalog-publication-inspection.js +138 -50
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-journal.d.ts +49 -0
- package/dist/src/commands/catalog-publication-journal.js +147 -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 +58 -15
- package/dist/src/commands/catalog-publish.js +590 -210
- package/dist/src/commands/catalog-publish.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +12 -15
- package/dist/src/commands/catalog-source.js +61 -86
- 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-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/dependency-operation-plan.d.ts +88 -9
- package/dist/src/commands/dependency-operation-plan.js +331 -6
- package/dist/src/commands/dependency-operation-plan.js.map +1 -1
- package/dist/src/commands/init.d.ts +5 -11
- package/dist/src/commands/init.js +30 -51
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/offline-cleanup-evidence.d.ts +43 -0
- package/dist/src/commands/offline-cleanup-evidence.js +116 -0
- package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
- package/dist/src/commands/options.d.ts +7 -1
- package/dist/src/commands/options.js +65 -6
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +5 -1
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +27 -13
- package/dist/src/commands/rebuild-command.js +1472 -471
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +63 -8
- package/dist/src/commands/rebuild-integration.js +761 -439
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +2 -8
- package/dist/src/commands/rebuild-operations.js +48 -132
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/runtime.js +21 -34
- package/dist/src/commands/runtime.js.map +1 -1
- package/dist/src/commands/skill-eval.d.ts +33 -0
- package/dist/src/commands/skill-eval.js +363 -0
- package/dist/src/commands/skill-eval.js.map +1 -0
- package/dist/src/commands/status-v6.d.ts +202 -0
- package/dist/src/commands/status-v6.js +1938 -0
- package/dist/src/commands/status-v6.js.map +1 -0
- package/dist/src/commands/sync-command.d.ts +21 -0
- package/dist/src/commands/sync-command.js +206 -0
- package/dist/src/commands/sync-command.js.map +1 -0
- package/dist/src/commands/wizard.d.ts +2 -2
- package/dist/src/commands/wizard.js +2 -2
- package/dist/src/commands/wizard.js.map +1 -1
- package/dist/src/commands/write-commands.js +33 -19
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/constants.d.ts +7 -1
- package/dist/src/constants.js +7 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/eval/manifest-v1.d.ts +66 -0
- package/dist/src/eval/manifest-v1.js +326 -0
- package/dist/src/eval/manifest-v1.js.map +1 -0
- package/dist/src/generators/local-plugin.d.ts +3 -0
- package/dist/src/generators/local-plugin.js +167 -45
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +6 -1
- package/dist/src/index.js +863 -126
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.d.ts +58 -8
- package/dist/src/output/command-receipt.js +141 -11
- 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 +0 -3
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/commands.d.ts +6 -2
- package/dist/src/portable/commands.js +57 -6
- package/dist/src/portable/commands.js.map +1 -1
- package/dist/src/portable/materializer.d.ts +4 -4
- package/dist/src/portable/materializer.js +61 -12
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.d.ts +35 -0
- package/dist/src/tui/catalog-generation.js +85 -0
- package/dist/src/tui/catalog-generation.js.map +1 -0
- package/dist/src/tui/components.js +1 -2
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +1 -1
- package/dist/src/tui/console-app-v4.js +647 -196
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +6 -2
- package/dist/src/tui/controller-runtime.js +646 -137
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +77 -15
- package/dist/src/tui/controller.js +647 -306
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostics.d.ts +1 -2
- package/dist/src/tui/diagnostics.js.map +1 -1
- package/dist/src/tui/index.d.ts +1 -0
- package/dist/src/tui/index.js +1 -0
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/input-display.d.ts +8 -0
- package/dist/src/tui/input-display.js +36 -0
- package/dist/src/tui/input-display.js.map +1 -0
- package/dist/src/tui/model.d.ts +102 -14
- package/dist/src/tui/model.js +630 -139
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/router.d.ts +35 -0
- package/dist/src/tui/router.js.map +1 -1
- 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/views.js +31 -3
- package/dist/src/tui/views.js.map +1 -1
- package/dist/src/types.d.ts +104 -13
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.d.ts +7 -1
- package/dist/src/utils/agent-version.js +41 -8
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/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 +8 -6
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-digests.d.ts +7 -0
- package/dist/src/utils/catalog-digests.js +40 -2
- package/dist/src/utils/catalog-digests.js.map +1 -1
- package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
- package/dist/src/utils/catalog-generation-error.d.ts +13 -0
- package/dist/src/utils/catalog-generation-error.js +28 -0
- package/dist/src/utils/catalog-generation-error.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +20 -0
- package/dist/src/utils/catalog-generation-resolver.js +143 -0
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
- package/dist/src/utils/catalog-generation-service.d.ts +43 -0
- package/dist/src/utils/catalog-generation-service.js +306 -0
- package/dist/src/utils/catalog-generation-service.js.map +1 -0
- package/dist/src/utils/catalog-generation-state.d.ts +17 -0
- package/dist/src/utils/catalog-generation-state.js +168 -0
- package/dist/src/utils/catalog-generation-state.js.map +1 -0
- package/dist/src/utils/catalog-generation-store.d.ts +34 -0
- package/dist/src/utils/catalog-generation-store.js +251 -0
- package/dist/src/utils/catalog-generation-store.js.map +1 -0
- package/dist/src/utils/catalog-manifest-v6.d.ts +5 -0
- package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v6.js} +35 -43
- package/dist/src/utils/catalog-manifest-v6.js.map +1 -0
- package/dist/src/utils/catalog-operation-context.d.ts +20 -0
- package/dist/src/utils/catalog-operation-context.js +141 -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 +21 -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-references.d.ts +7 -0
- package/dist/src/utils/catalog-source-references.js +44 -55
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +1 -0
- package/dist/src/utils/catalog-sources.js +55 -20
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-config.d.ts +2 -0
- package/dist/src/utils/codex-config.js +26 -5
- package/dist/src/utils/codex-config.js.map +1 -1
- package/dist/src/utils/codex-manager.d.ts +81 -0
- package/dist/src/utils/codex-manager.js +810 -0
- package/dist/src/utils/codex-manager.js.map +1 -0
- package/dist/src/utils/codex-reconciler.d.ts +131 -0
- package/dist/src/utils/codex-reconciler.js +327 -0
- package/dist/src/utils/codex-reconciler.js.map +1 -0
- package/dist/src/utils/codex-shared-native.d.ts +56 -0
- package/dist/src/utils/codex-shared-native.js +87 -0
- package/dist/src/utils/codex-shared-native.js.map +1 -0
- package/dist/src/utils/codex-skill-staging.d.ts +2 -0
- package/dist/src/utils/codex-skill-staging.js.map +1 -1
- package/dist/src/utils/codex-surface-analysis.d.ts +44 -0
- package/dist/src/utils/codex-surface-analysis.js +247 -0
- package/dist/src/utils/codex-surface-analysis.js.map +1 -0
- package/dist/src/utils/dynamic-skill-tree.d.ts +4 -0
- package/dist/src/utils/dynamic-skill-tree.js +35 -5
- package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.js +66 -140
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/lifecycle-active-store.d.ts +0 -28
- package/dist/src/utils/lifecycle-active-store.js +35 -247
- package/dist/src/utils/lifecycle-active-store.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +1 -3
- package/dist/src/utils/manifest.js +1 -3
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.d.ts +3 -9
- package/dist/src/utils/multi-source-catalog.js +53 -110
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +49 -6
- package/dist/src/utils/native-cli.js +116 -33
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/orphan-marketplace-cleanup.js +1 -3
- package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
- package/dist/src/utils/ownership.d.ts +10 -11
- package/dist/src/utils/ownership.js +55 -112
- 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 +52 -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-write.js +18 -40
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +1 -12
- package/dist/src/utils/plugin-config.js +107 -226
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-intent-state.d.ts +39 -0
- package/dist/src/utils/plugin-intent-state.js +325 -0
- package/dist/src/utils/plugin-intent-state.js.map +1 -0
- package/dist/src/utils/plugin-scripts.d.ts +1 -1
- package/dist/src/utils/plugin-scripts.js +1 -1
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- 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 +9 -5
- package/dist/src/utils/target-eligibility.js.map +1 -1
- package/package.json +6 -4
- 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.map +0 -1
- package/dist/scripts/skill-reporting.d.ts +0 -212
- package/dist/scripts/skill-reporting.js +0 -922
- package/dist/scripts/skill-reporting.js.map +0 -1
- package/dist/src/commands/status-v4.d.ts +0 -123
- package/dist/src/commands/status-v4.js +0 -905
- package/dist/src/commands/status-v4.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -93
- package/dist/src/commands/status.js +0 -442
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
- package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
- package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
- package/dist/src/utils/catalog-manifest-v3.js +0 -3
- package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
- package/dist/src/utils/catalog-manifest-v4.js.map +0 -1
- package/dist/src/utils/catalog-source-cache.d.ts +0 -62
- package/dist/src/utils/catalog-source-cache.js +0 -296
- package/dist/src/utils/catalog-source-cache.js.map +0 -1
- package/dist/src/utils/codex-project-surface.d.ts +0 -3
- package/dist/src/utils/codex-project-surface.js +0 -49
- package/dist/src/utils/codex-project-surface.js.map +0 -1
- package/dist/src/utils/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
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
|
-
import
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { statusCommandV6, } from '../commands/status-v6.js';
|
|
3
4
|
import { addCatalogSourceCommand, listCatalogSources, preflightCatalogSourceMutation, removeCatalogSourceCommand, setPrimaryCatalogSourceCommand, updateCatalogSourceCommand, } from '../commands/catalog-source.js';
|
|
4
5
|
import { cleanupWriteCommand, installWriteCommand, reinstallWriteCommand, uninstallWriteCommand, upgradeWriteCommand, } from '../commands/write-commands.js';
|
|
5
6
|
import { readCliPackageInfo } from '../utils/local-marketplace.js';
|
|
@@ -7,28 +8,42 @@ import { readCatalogSourcesConfigSnapshot, } from '../utils/catalog-sources.js';
|
|
|
7
8
|
import { withResolvedCatalogPlugin, withResolvedMultiSourceCatalog, formatPluginId, parsePluginId, } from '../utils/multi-source-catalog.js';
|
|
8
9
|
import { coercePluginConfigUpdates, readNamespacedPluginConfigStoreIdentity, readPluginConfigStore, resolveConfigRead, } from '../utils/plugin-config.js';
|
|
9
10
|
import { applyPluginConfigWrite, resetPluginConfigWithHelper, } from '../utils/plugin-config-write.js';
|
|
11
|
+
import { offlineCleanupEvidenceFromInventory, } from '../commands/offline-cleanup-evidence.js';
|
|
12
|
+
import { inventoryCatalogSourceReferences } from '../utils/catalog-source-references.js';
|
|
10
13
|
import { operationEvidenceFingerprint, TuiController, TuiOperationBlockedError, } from './controller.js';
|
|
11
|
-
import { buildConfigGroups, buildConfigPage, projectPlatformPlacement, } from './model.js';
|
|
14
|
+
import { buildConfigGroups, buildConfigPage, isPureNativeCodexTarget, projectPlatformPlacement, } from './model.js';
|
|
12
15
|
import { projectCatalogSourceLocation } from '../utils/catalog-source-presentation.js';
|
|
13
|
-
import { targetCanBeUninstalled } from '../utils/target-eligibility.js';
|
|
16
|
+
import { targetCanBeUninstalled, targetHasArtifactCollision, } from '../utils/target-eligibility.js';
|
|
14
17
|
import { calculateCatalogSourceIdentity } from '../utils/catalog-source-identity.js';
|
|
15
|
-
import {
|
|
18
|
+
import { checkAwCapabilitySupport, readPluginManifest } from '../utils/manifest.js';
|
|
16
19
|
import { withAwHomeMutationLock } from '../utils/aw-home-mutation-lock.js';
|
|
20
|
+
import { IMPLEMENTED_AW_CAPABILITIES } from '../commands/aw-capabilities.js';
|
|
21
|
+
import { resolveCatalogOperationContext, resolvePartialCatalogOperationContext, selectCatalogOperationContext, } from '../utils/catalog-operation-context.js';
|
|
22
|
+
import { loadCatalogGenerationViewModels } from './catalog-generation.js';
|
|
17
23
|
import { installPortableSkills, preparePortableInstall, PortableCommandError, } from '../portable/commands.js';
|
|
24
|
+
import { MANAGED_CODEX_PACKAGE_NAME, MANAGED_CODEX_VERSION, } from '../utils/codex-manager.js';
|
|
25
|
+
import { calculatePluginIntentDigest, canonicalizePluginIntentState, readPluginIntentState, writePluginIntentState, } from '../utils/plugin-intent-state.js';
|
|
18
26
|
async function loadPortablePluginIds(options) {
|
|
19
27
|
return withResolvedMultiSourceCatalog({
|
|
20
28
|
cliVersion: options.cliVersion,
|
|
21
|
-
freshnessPolicy: 'cacheFirst',
|
|
22
29
|
env: options.context.env,
|
|
23
30
|
signal: options.signal,
|
|
31
|
+
...(options.catalogOperationContext
|
|
32
|
+
? { operationContext: options.catalogOperationContext }
|
|
33
|
+
: {}),
|
|
24
34
|
consume: async (catalog) => (await Promise.all(catalog.sources.flatMap((item) => item.resolution
|
|
25
|
-
?
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
? item.resolution.manifest.entries.flatMap((entry) => {
|
|
36
|
+
const support = checkAwCapabilitySupport(entry.requires.aw.capabilities ?? [], IMPLEMENTED_AW_CAPABILITIES);
|
|
37
|
+
return support.supported
|
|
38
|
+
? [readPluginManifest(path.join(item.resolution.rootDir, 'plugins', entry.name), { mode: 'bundle' }).then((plugin) => plugin.manifest.distributions?.agentSkills
|
|
39
|
+
? formatPluginId({
|
|
40
|
+
sourceId: item.resolution.sourceId,
|
|
41
|
+
pluginName: entry.name,
|
|
42
|
+
})
|
|
43
|
+
: null)]
|
|
44
|
+
: [];
|
|
45
|
+
})
|
|
46
|
+
: []))).filter((pluginId) => pluginId !== null),
|
|
32
47
|
});
|
|
33
48
|
}
|
|
34
49
|
let tuiControllerRuntimeTestHooks;
|
|
@@ -60,6 +75,13 @@ export function statusTargetFingerprint(targets, revisions = []) {
|
|
|
60
75
|
.localeCompare([right.pluginId, right.platform, right.scope].join('\0'), 'en')),
|
|
61
76
|
});
|
|
62
77
|
}
|
|
78
|
+
export function configAffectedStatusTargets(targets, pluginId, configScope) {
|
|
79
|
+
return targets.filter((target) => target.pluginId === pluginId
|
|
80
|
+
&& (configScope === 'user' || target.scope === 'project')
|
|
81
|
+
&& (target.state === 'present' || target.state === 'partial'))
|
|
82
|
+
.sort((left, right) => `${left.platform}\0${left.scope}`
|
|
83
|
+
.localeCompare(`${right.platform}\0${right.scope}`, 'en'));
|
|
84
|
+
}
|
|
63
85
|
function operationReviewStale(message) {
|
|
64
86
|
return new TuiOperationBlockedError('operationReviewStale', `operationReviewStale: ${message}`);
|
|
65
87
|
}
|
|
@@ -73,6 +95,8 @@ function sourceEvidenceForPlugin(source, pluginName) {
|
|
|
73
95
|
manifestDigest: source.manifestDigest,
|
|
74
96
|
snapshotDigest: source.snapshotDigest,
|
|
75
97
|
contentDigest: entry.contentDigest,
|
|
98
|
+
catalogVersion: source.manifest.catalogVersion,
|
|
99
|
+
channel: source.manifest.channel,
|
|
76
100
|
};
|
|
77
101
|
}
|
|
78
102
|
function assertSourceEvidenceMatches(expected, actual) {
|
|
@@ -92,8 +116,6 @@ function throwIfWriteReviewStale(result) {
|
|
|
92
116
|
}
|
|
93
117
|
}
|
|
94
118
|
const SOURCE_PROGRESS_PHASES = {
|
|
95
|
-
refreshingCatalog: '刷新 Catalog 缓存',
|
|
96
|
-
catalogReady: 'Catalog 已读取,索引已刷新',
|
|
97
119
|
savingConfig: '保存来源配置',
|
|
98
120
|
};
|
|
99
121
|
function pluginIntent(intent) {
|
|
@@ -104,20 +126,48 @@ function assertIntentIsLegal(intent, targets, revisions = []) {
|
|
|
104
126
|
? ['codex', 'claude']
|
|
105
127
|
: [intent.platform];
|
|
106
128
|
for (const platform of platforms) {
|
|
107
|
-
const
|
|
108
|
-
&& target.platform === platform
|
|
129
|
+
const platformTargets = targets.filter((target) => target.pluginId === intent.pluginId
|
|
130
|
+
&& target.platform === platform);
|
|
131
|
+
const selected = platformTargets.find((target) => target.scope === intent.scope)
|
|
132
|
+
?? (platform === 'codex' ? platformTargets[0] : undefined);
|
|
109
133
|
if (!selected || selected.errors.some((error) => error.code === 'unsupportedTarget')) {
|
|
110
134
|
throw new TuiOperationBlockedError('unsupportedTarget', '所选插件不支持这个平台和使用位置。');
|
|
111
135
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
if (intent.
|
|
136
|
+
if (intent.action === 'sync' && platform !== 'codex') {
|
|
137
|
+
throw new TuiOperationBlockedError('syncPlatformUnsupported', 'sync 只支持 Codex。');
|
|
138
|
+
}
|
|
139
|
+
if (intent.dependencyPlacementOnly === 'desired')
|
|
140
|
+
continue;
|
|
141
|
+
const otherScope = intent.scope === 'user' ? 'project' : 'user';
|
|
142
|
+
const otherScopeInstalled = platform === 'codex'
|
|
143
|
+
? platformTargets.some((target) => target.desired.scopes.includes(otherScope)
|
|
144
|
+
|| target.activation?.[otherScope] === true)
|
|
145
|
+
: targets.some((target) => target.platform === platform
|
|
146
|
+
&& target.scope !== intent.scope
|
|
147
|
+
&& (target.state === 'present' || target.state === 'partial'));
|
|
148
|
+
const pureNativeCodex = isPureNativeCodexTarget(selected);
|
|
149
|
+
if (intent.action === 'install' && otherScopeInstalled && !pureNativeCodex
|
|
150
|
+
&& !intent.dependencyPlacementAdjustment) {
|
|
116
151
|
throw new TuiOperationBlockedError('scopeConflict', '这个平台已安装在另一个使用位置。请先移除原位置。');
|
|
117
152
|
}
|
|
118
|
-
if (intent.action === 'install'
|
|
153
|
+
if ((intent.action === 'install' || intent.action === 'upgrade' || intent.action === 'reinstall')
|
|
154
|
+
&& targetHasArtifactCollision(selected)) {
|
|
155
|
+
throw new TuiOperationBlockedError('artifactCollision', '所选位置存在输出冲突。请先移除或迁移冲突内容。');
|
|
156
|
+
}
|
|
157
|
+
const selectedScopeInstalled = platform === 'codex'
|
|
158
|
+
? selected.desired.scopes.includes(intent.scope)
|
|
159
|
+
|| selected.activation?.[intent.scope] === true
|
|
160
|
+
: selected.state !== 'absent';
|
|
161
|
+
if (intent.action === 'install' && selectedScopeInstalled
|
|
162
|
+
&& !intent.dependencyPlacementAdjustment) {
|
|
119
163
|
throw new TuiOperationBlockedError('targetAlreadyInstalled', '所选位置已经安装。');
|
|
120
164
|
}
|
|
165
|
+
if (intent.action === 'sync'
|
|
166
|
+
&& selected.actual.state !== 'needsSync'
|
|
167
|
+
&& selected.actual.state !== 'drifted'
|
|
168
|
+
&& selected.actual.state !== 'conflict') {
|
|
169
|
+
throw new TuiOperationBlockedError('targetStateChanged', '当前安装状态不需要同步。');
|
|
170
|
+
}
|
|
121
171
|
const revision = revisions.find((entry) => entry.pluginId === intent.pluginId
|
|
122
172
|
&& entry.platform === platform && entry.scope === intent.scope)?.revision;
|
|
123
173
|
if (intent.action === 'upgrade'
|
|
@@ -140,7 +190,9 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
140
190
|
};
|
|
141
191
|
const selected = targets.find((target) => target.pluginId === intent.pluginId
|
|
142
192
|
&& target.platform === intent.platform
|
|
143
|
-
&& target.scope === intent.scope)
|
|
193
|
+
&& target.scope === intent.scope)
|
|
194
|
+
?? targets.find((target) => target.pluginId === intent.pluginId
|
|
195
|
+
&& target.platform === 'codex');
|
|
144
196
|
if (intent.originIssue.category === 'dependencyMissing') {
|
|
145
197
|
if (intent.originIssue.actionId !== 'installDependency'
|
|
146
198
|
|| intent.action !== 'install' || !selected || selected.state !== 'absent') {
|
|
@@ -169,10 +221,25 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
169
221
|
}
|
|
170
222
|
return;
|
|
171
223
|
}
|
|
224
|
+
else if (intent.originIssue.category === 'sourceMissing') {
|
|
225
|
+
if (intent.originIssue.actionId !== 'cleanup' || intent.action !== 'cleanup'
|
|
226
|
+
|| !selected || !selected.errors.some((error) => error.code === 'sourceMissing')) {
|
|
227
|
+
stale('原来源缺失问题已变化。');
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
172
231
|
else if (intent.originIssue.category === 'scopeConflict') {
|
|
173
|
-
const installedScopes = new Set(
|
|
174
|
-
|
|
175
|
-
|
|
232
|
+
const installedScopes = new Set();
|
|
233
|
+
for (const target of targets.filter((candidate) => candidate.pluginId === intent.pluginId && candidate.platform === intent.platform)) {
|
|
234
|
+
if (target.state === 'present' || target.state === 'partial')
|
|
235
|
+
installedScopes.add(target.scope);
|
|
236
|
+
for (const scope of target.desired.scopes)
|
|
237
|
+
installedScopes.add(scope);
|
|
238
|
+
if (target.activation?.user === true)
|
|
239
|
+
installedScopes.add('user');
|
|
240
|
+
if (target.activation?.project === true)
|
|
241
|
+
installedScopes.add('project');
|
|
242
|
+
}
|
|
176
243
|
const correctBranch = intent.action === 'uninstall'
|
|
177
244
|
&& ((intent.originIssue.actionId === 'keepUserScope' && intent.scope === 'project')
|
|
178
245
|
|| (intent.originIssue.actionId === 'keepProjectScope' && intent.scope === 'user'));
|
|
@@ -202,25 +269,29 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
202
269
|
async function loadDependencyOverviews(options) {
|
|
203
270
|
const graph = await withResolvedMultiSourceCatalog({
|
|
204
271
|
cliVersion: options.cliVersion,
|
|
205
|
-
freshnessPolicy: 'cacheFirst',
|
|
206
272
|
env: options.context.env,
|
|
207
273
|
signal: options.signal,
|
|
274
|
+
...(options.catalogOperationContext
|
|
275
|
+
? { operationContext: options.catalogOperationContext }
|
|
276
|
+
: {}),
|
|
208
277
|
consume: async (catalog) => ({
|
|
209
|
-
nodes:
|
|
210
|
-
?
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
278
|
+
nodes: catalog.sources.flatMap((item) => item.resolution
|
|
279
|
+
? item.resolution.manifest.entries.map((entry) => ({
|
|
280
|
+
pluginId: formatPluginId({
|
|
281
|
+
sourceId: item.resolution.sourceId,
|
|
282
|
+
pluginName: entry.name,
|
|
283
|
+
}),
|
|
284
|
+
displayName: entry.interface?.displayName ?? entry.name,
|
|
285
|
+
dependencies: entry.dependencies.map((pluginName) => formatPluginId({ sourceId: item.resolution.sourceId, pluginName })),
|
|
286
|
+
}))
|
|
287
|
+
: []),
|
|
218
288
|
sourceErrors: catalog.sources.flatMap((item) => item.error
|
|
219
289
|
? [{ sourceId: item.sourceId, code: 'dependencyGraphInvalid' }]
|
|
220
290
|
: []),
|
|
221
291
|
}),
|
|
222
292
|
});
|
|
223
293
|
const nodes = new Map(graph.nodes.map((node) => [node.pluginId, node]));
|
|
294
|
+
const summaryById = new Map(options.status.pluginSummaries.map((summary) => [summary.pluginId, summary]));
|
|
224
295
|
const displayName = (pluginId) => nodes.get(pluginId)?.displayName
|
|
225
296
|
?? parsePluginId(pluginId).pluginName;
|
|
226
297
|
const reverse = new Map();
|
|
@@ -233,6 +304,9 @@ async function loadDependencyOverviews(options) {
|
|
|
233
304
|
for (const target of options.status.payload.targets) {
|
|
234
305
|
targetsByPlugin.set(target.pluginId, [...(targetsByPlugin.get(target.pluginId) ?? []), target]);
|
|
235
306
|
}
|
|
307
|
+
const unsupportedPluginIds = new Set(options.status.pluginSummaries
|
|
308
|
+
.filter((summary) => (summary.missingCapabilities?.length ?? 0) > 0)
|
|
309
|
+
.map((summary) => summary.pluginId));
|
|
236
310
|
const placementReferences = new Map();
|
|
237
311
|
for (const consumer of options.status.payload.targets.filter((target) => target.state !== 'absent')) {
|
|
238
312
|
const consumerNode = nodes.get(consumer.pluginId);
|
|
@@ -279,13 +353,15 @@ async function loadDependencyOverviews(options) {
|
|
|
279
353
|
};
|
|
280
354
|
const aggregateFor = (pluginId, placements) => {
|
|
281
355
|
const sourceId = parsePluginId(pluginId).sourceId;
|
|
282
|
-
if (graph.sourceErrors.some((error) => error.sourceId === sourceId)
|
|
356
|
+
if (graph.sourceErrors.some((error) => error.sourceId === sourceId)
|
|
357
|
+
|| unsupportedPluginIds.has(pluginId))
|
|
283
358
|
return 'unavailable';
|
|
284
359
|
if (placements.length === 0 || placements.every((placement) => placement.state === 'notInstalled')) {
|
|
285
360
|
return 'notInstalled';
|
|
286
361
|
}
|
|
287
362
|
return placements.some((placement) => placement.state === 'scopeConflict'
|
|
288
|
-
|| (placement.state === 'installed'
|
|
363
|
+
|| (placement.state === 'installed'
|
|
364
|
+
&& (placement.health !== 'ready' || placement.blockingReason !== undefined)))
|
|
289
365
|
? 'needsAttention'
|
|
290
366
|
: 'ready';
|
|
291
367
|
};
|
|
@@ -359,6 +435,13 @@ async function loadDependencyOverviews(options) {
|
|
|
359
435
|
title: '依赖关系需要处理',
|
|
360
436
|
explanation: '当前目标的依赖证据不能安全通过检查。',
|
|
361
437
|
})));
|
|
438
|
+
const consumerTargets = summaryById.get(pluginId)?.supportedTargets;
|
|
439
|
+
const unsupportedDependency = dependencyItems.find((dependency) => {
|
|
440
|
+
const dependencyTargets = summaryById.get(dependency.pluginId)?.supportedTargets;
|
|
441
|
+
if (!consumerTargets || !dependencyTargets)
|
|
442
|
+
return true;
|
|
443
|
+
return ['codex', 'claude'].some((platform) => consumerTargets[platform].length > 0 && dependencyTargets[platform].length === 0);
|
|
444
|
+
});
|
|
362
445
|
const sourceId = parsePluginId(pluginId).sourceId;
|
|
363
446
|
const blockers = [
|
|
364
447
|
...graph.sourceErrors.filter((error) => error.sourceId === sourceId).map((error) => ({
|
|
@@ -371,6 +454,11 @@ async function loadDependencyOverviews(options) {
|
|
|
371
454
|
title: '依赖关系无效',
|
|
372
455
|
explanation: '依赖关系形成环。',
|
|
373
456
|
}] : []),
|
|
457
|
+
...(unsupportedDependency ? [{
|
|
458
|
+
code: 'dependencyTargetUnsupported',
|
|
459
|
+
title: '依赖目标不兼容',
|
|
460
|
+
explanation: `${unsupportedDependency.displayName} 不支持根插件所需的平台。`,
|
|
461
|
+
}] : []),
|
|
374
462
|
...targetBlockers,
|
|
375
463
|
];
|
|
376
464
|
const directCount = dependencyItems.filter((item) => item.relation === 'direct').length;
|
|
@@ -418,40 +506,105 @@ function createReviewStageReporter(options) {
|
|
|
418
506
|
};
|
|
419
507
|
}
|
|
420
508
|
export function createTuiControllerDependencies(context, progressFeed, options = {}) {
|
|
509
|
+
const readInventory = options.inventoryCatalogSourceReferences
|
|
510
|
+
?? inventoryCatalogSourceReferences;
|
|
511
|
+
const validatedStoreEntries = new Map();
|
|
512
|
+
const validatingStoreEntries = new Map();
|
|
513
|
+
const loadCatalogGenerations = async () => {
|
|
514
|
+
const generations = await loadCatalogGenerationViewModels({
|
|
515
|
+
env: context.env,
|
|
516
|
+
validatedStoreEntries,
|
|
517
|
+
validatingStoreEntries,
|
|
518
|
+
onStage: (event) => context.debugLogger.log({
|
|
519
|
+
type: 'performance:stage',
|
|
520
|
+
level: 'debug',
|
|
521
|
+
target: 'debugLog',
|
|
522
|
+
message: 'Catalog generation load stage completed.',
|
|
523
|
+
data: event,
|
|
524
|
+
}),
|
|
525
|
+
});
|
|
526
|
+
const retained = new Set(generations.flatMap((source) => [
|
|
527
|
+
source.active?.storeKey,
|
|
528
|
+
].filter((value) => value !== undefined)));
|
|
529
|
+
for (const storeKey of validatedStoreEntries.keys()) {
|
|
530
|
+
if (!retained.has(storeKey))
|
|
531
|
+
validatedStoreEntries.delete(storeKey);
|
|
532
|
+
}
|
|
533
|
+
return generations;
|
|
534
|
+
};
|
|
535
|
+
const createOperationInventoryReader = () => {
|
|
536
|
+
let ordinaryInventory;
|
|
537
|
+
return (inventoryOptions) => {
|
|
538
|
+
if (inventoryOptions.includeHistoricalProjects === true) {
|
|
539
|
+
return readInventory(inventoryOptions);
|
|
540
|
+
}
|
|
541
|
+
ordinaryInventory ??= readInventory(inventoryOptions);
|
|
542
|
+
return ordinaryInventory;
|
|
543
|
+
};
|
|
544
|
+
};
|
|
545
|
+
const catalogOperationByEvidence = new WeakMap();
|
|
546
|
+
let sessionCatalogOperationContext;
|
|
547
|
+
let sessionStatusResult;
|
|
548
|
+
const sessionContextForPlugin = (pluginId) => {
|
|
549
|
+
const sourceId = parsePluginId(pluginId).sourceId;
|
|
550
|
+
if (!sourceId || !sessionCatalogOperationContext)
|
|
551
|
+
return undefined;
|
|
552
|
+
return selectCatalogOperationContext(sessionCatalogOperationContext, [sourceId]);
|
|
553
|
+
};
|
|
421
554
|
const loadStatus = async (signal) => {
|
|
422
555
|
signal.throwIfAborted();
|
|
423
556
|
const packageInfo = await readCliPackageInfo();
|
|
557
|
+
const catalogOperationContext = sessionCatalogOperationContext
|
|
558
|
+
?? await resolvePartialCatalogOperationContext({
|
|
559
|
+
env: context.env,
|
|
560
|
+
signal,
|
|
561
|
+
validatedStoreEntries,
|
|
562
|
+
validatingStoreEntries,
|
|
563
|
+
}).catch(() => undefined);
|
|
564
|
+
if (catalogOperationContext)
|
|
565
|
+
sessionCatalogOperationContext = catalogOperationContext;
|
|
424
566
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
425
|
-
const result = await
|
|
567
|
+
const result = await statusCommandV6({
|
|
426
568
|
cwd: context.cwd,
|
|
427
569
|
env: context.env,
|
|
428
570
|
cliVersion: packageInfo.version,
|
|
429
571
|
verbose: context.diagnostics.verbose,
|
|
572
|
+
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
573
|
+
inventoryCatalogSourceReferences: readInventory,
|
|
430
574
|
});
|
|
431
575
|
signal.throwIfAborted();
|
|
432
576
|
const configured = await listCatalogSources({ env: context.env });
|
|
433
577
|
signal.throwIfAborted();
|
|
434
578
|
if (result.payload.catalog.configDigest !== configured.configDigest)
|
|
435
579
|
continue;
|
|
580
|
+
sessionStatusResult = result;
|
|
436
581
|
const dependencyOverviews = await loadDependencyOverviews({
|
|
437
582
|
context,
|
|
438
583
|
cliVersion: packageInfo.version,
|
|
439
584
|
status: result,
|
|
440
585
|
signal,
|
|
586
|
+
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
441
587
|
});
|
|
442
588
|
const portablePluginIds = await loadPortablePluginIds({
|
|
443
589
|
context,
|
|
444
590
|
cliVersion: packageInfo.version,
|
|
445
591
|
signal,
|
|
592
|
+
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
446
593
|
});
|
|
447
594
|
signal.throwIfAborted();
|
|
595
|
+
const catalogGenerations = await loadCatalogGenerations();
|
|
596
|
+
signal.throwIfAborted();
|
|
448
597
|
const statusById = new Map(result.payload.catalog.sources.map((source) => [source.id, source]));
|
|
449
598
|
return {
|
|
599
|
+
cliChannel: packageInfo.version.includes('-') ? 'beta' : 'latest',
|
|
450
600
|
payload: result.payload,
|
|
451
601
|
pluginSummaries: result.pluginSummaries,
|
|
452
602
|
targetRevisions: result.targetRevisions,
|
|
453
603
|
dependencyOverviews,
|
|
454
604
|
portablePluginIds,
|
|
605
|
+
catalogGenerations,
|
|
606
|
+
sessionGenerationKeys: Object.fromEntries((catalogOperationContext?.generationSet.sources ?? [])
|
|
607
|
+
.map((source) => [source.sourceId, source.storeKey])),
|
|
455
608
|
sourceDetails: configured.sources.map((source) => {
|
|
456
609
|
const status = statusById.get(source.id);
|
|
457
610
|
return {
|
|
@@ -479,7 +632,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
479
632
|
}
|
|
480
633
|
throw new TuiOperationBlockedError('operationReviewStale', '状态读取期间来源配置持续变化。请重试。');
|
|
481
634
|
};
|
|
482
|
-
const captureEvidence = async (intent, signal,
|
|
635
|
+
const captureEvidence = async (intent, signal, preparation, operationInventory = createOperationInventoryReader(), freshCatalog = false) => {
|
|
483
636
|
if (intent.kind === 'sourceMutation') {
|
|
484
637
|
signal?.throwIfAborted();
|
|
485
638
|
if (intent.action === 'add' && !intent.source
|
|
@@ -501,10 +654,10 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
501
654
|
await preparation?.reporter.emit('evidence');
|
|
502
655
|
signal?.throwIfAborted();
|
|
503
656
|
const evidence = {
|
|
504
|
-
catalog: { configDigest: preview.configDigest, compositeDigest: preview.
|
|
657
|
+
catalog: { configDigest: preview.configDigest, compositeDigest: preview.proposedConfigDigest },
|
|
505
658
|
sourceWrite: {
|
|
506
659
|
configDigest: preview.configDigest,
|
|
507
|
-
|
|
660
|
+
proposedConfigDigest: preview.proposedConfigDigest,
|
|
508
661
|
...(preview.sourceIdentity ? { sourceIdentity: preview.sourceIdentity } : {}),
|
|
509
662
|
inventoryDigest: digest({ references: preview.references.references, errors: preview.references.errors }),
|
|
510
663
|
referenceCount: preview.references.references.length,
|
|
@@ -512,7 +665,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
512
665
|
},
|
|
513
666
|
};
|
|
514
667
|
if (preparation?.validateIntent
|
|
515
|
-
&& evidence.sourceWrite?.configDigest === evidence.sourceWrite?.
|
|
668
|
+
&& evidence.sourceWrite?.configDigest === evidence.sourceWrite?.proposedConfigDigest) {
|
|
516
669
|
throw new TuiOperationBlockedError('sourceNoChanges', '来源没有变化。');
|
|
517
670
|
}
|
|
518
671
|
return evidence;
|
|
@@ -522,8 +675,37 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
522
675
|
}
|
|
523
676
|
signal?.throwIfAborted();
|
|
524
677
|
const packageInfo = await readCliPackageInfo();
|
|
678
|
+
const offlineCleanupReason = intent.kind === 'pluginWrite'
|
|
679
|
+
&& intent.action === 'cleanup'
|
|
680
|
+
&& intent.originIssue?.actionId === 'cleanup'
|
|
681
|
+
&& (intent.originIssue?.category === 'sourceMissing'
|
|
682
|
+
|| intent.originIssue?.category === 'sourceUnavailable')
|
|
683
|
+
? intent.originIssue.category === 'sourceMissing' ? 'sourceMissing' : 'bundleUnavailable'
|
|
684
|
+
: undefined;
|
|
685
|
+
let catalogOperation;
|
|
686
|
+
let catalogOperationError;
|
|
687
|
+
if (!offlineCleanupReason && intent.kind !== 'portableInstall') {
|
|
688
|
+
try {
|
|
689
|
+
const sourceIds = [parsePluginId(intent.pluginId).sourceId];
|
|
690
|
+
catalogOperation = !freshCatalog && sessionCatalogOperationContext
|
|
691
|
+
? selectCatalogOperationContext(sessionCatalogOperationContext, sourceIds)
|
|
692
|
+
: await resolveCatalogOperationContext({
|
|
693
|
+
sourceIds,
|
|
694
|
+
env: context.env,
|
|
695
|
+
...(!freshCatalog ? { validatedStoreEntries, validatingStoreEntries } : {}),
|
|
696
|
+
...(signal ? { signal } : {}),
|
|
697
|
+
});
|
|
698
|
+
}
|
|
699
|
+
catch (error) {
|
|
700
|
+
catalogOperationError = error;
|
|
701
|
+
}
|
|
702
|
+
}
|
|
525
703
|
if (intent.kind === 'portableInstall') {
|
|
526
704
|
await preparation?.reporter.emit('portable');
|
|
705
|
+
const portableSourceId = parsePluginId(intent.pluginId).sourceId;
|
|
706
|
+
const portableCatalogOperation = sessionCatalogOperationContext
|
|
707
|
+
? selectCatalogOperationContext(sessionCatalogOperationContext, [portableSourceId])
|
|
708
|
+
: undefined;
|
|
527
709
|
const portable = await preparePortableInstall({
|
|
528
710
|
selector: intent.pluginId,
|
|
529
711
|
scope: intent.scope,
|
|
@@ -533,20 +715,105 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
533
715
|
env: context.env,
|
|
534
716
|
cliVersion: packageInfo.version,
|
|
535
717
|
signal,
|
|
718
|
+
...(portableCatalogOperation
|
|
719
|
+
? { catalogOperationContext: portableCatalogOperation }
|
|
720
|
+
: {}),
|
|
536
721
|
});
|
|
537
722
|
signal?.throwIfAborted();
|
|
538
723
|
await preparation?.reporter.emit('evidence');
|
|
539
724
|
signal?.throwIfAborted();
|
|
540
|
-
|
|
725
|
+
const evidence = {
|
|
541
726
|
catalog: {
|
|
542
727
|
configDigest: portable.configDigest,
|
|
543
728
|
compositeDigest: portable.evidenceDigest,
|
|
729
|
+
...(portable.generationSetDigest
|
|
730
|
+
? { generationSetDigest: portable.generationSetDigest }
|
|
731
|
+
: {}),
|
|
544
732
|
},
|
|
545
733
|
portable,
|
|
546
734
|
};
|
|
735
|
+
if (catalogOperation)
|
|
736
|
+
catalogOperationByEvidence.set(evidence, catalogOperation);
|
|
737
|
+
return evidence;
|
|
738
|
+
}
|
|
739
|
+
if (preparation && (intent.kind === 'configSave' || intent.kind === 'configReset')) {
|
|
740
|
+
if (!sessionStatusResult || !catalogOperation) {
|
|
741
|
+
throw operationReviewStale('当前 TUI session 没有可复用的设置证据。');
|
|
742
|
+
}
|
|
743
|
+
await preparation.reporter.emit('config');
|
|
744
|
+
const configSnapshot = await readCatalogSourcesConfigSnapshot(context.env);
|
|
745
|
+
signal?.throwIfAborted();
|
|
746
|
+
if (configSnapshot.digest !== sessionStatusResult.payload.catalog.configDigest) {
|
|
747
|
+
throw operationReviewStale('准备设置确认期间来源配置发生变化。');
|
|
748
|
+
}
|
|
749
|
+
const selected = await withResolvedCatalogPlugin({
|
|
750
|
+
selector: intent.pluginId,
|
|
751
|
+
cliVersion: packageInfo.version,
|
|
752
|
+
configSnapshot,
|
|
753
|
+
env: context.env,
|
|
754
|
+
operationContext: catalogOperation,
|
|
755
|
+
...(signal ? { signal } : {}),
|
|
756
|
+
consume: async ({ plugin, source }) => {
|
|
757
|
+
if (!plugin.manifest.config) {
|
|
758
|
+
throw new TuiOperationBlockedError('configSchemaUnavailable', '这个插件没有设置 schema。');
|
|
759
|
+
}
|
|
760
|
+
if (intent.kind === 'configSave') {
|
|
761
|
+
await coercePluginConfigUpdates({
|
|
762
|
+
schema: plugin.manifest.config.schema,
|
|
763
|
+
updates: intent.updates ?? {},
|
|
764
|
+
cwd: context.cwd,
|
|
765
|
+
});
|
|
766
|
+
for (const key of intent.removeKeys ?? []) {
|
|
767
|
+
if (!plugin.manifest.config.schema[key]) {
|
|
768
|
+
throw new TuiOperationBlockedError('unknownConfigKey', '设置字段已变化,请重新检查。');
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
return {
|
|
773
|
+
pluginName: plugin.manifest.name,
|
|
774
|
+
source: sourceEvidenceForPlugin(source, plugin.manifest.name),
|
|
775
|
+
};
|
|
776
|
+
},
|
|
777
|
+
});
|
|
778
|
+
const store = await readPluginConfigStore({
|
|
779
|
+
sourceId: selected.source.sourceId,
|
|
780
|
+
sourceIdentity: selected.source.sourceIdentity,
|
|
781
|
+
pluginName: selected.pluginName,
|
|
782
|
+
scope: intent.scope,
|
|
783
|
+
projectLayer: intent.projectLayer,
|
|
784
|
+
cwd: context.cwd,
|
|
785
|
+
env: context.env,
|
|
786
|
+
});
|
|
787
|
+
signal?.throwIfAborted();
|
|
788
|
+
const relevantTargets = configAffectedStatusTargets(sessionStatusResult.payload.targets, intent.pluginId, intent.scope);
|
|
789
|
+
const relevantRevisions = (sessionStatusResult.targetRevisions ?? []).filter((revision) => relevantTargets.some((target) => target.platform === revision.platform
|
|
790
|
+
&& target.scope === revision.scope
|
|
791
|
+
&& target.pluginId === revision.pluginId));
|
|
792
|
+
await preparation.reporter.emit('evidence');
|
|
793
|
+
const evidence = {
|
|
794
|
+
catalog: {
|
|
795
|
+
configDigest: sessionStatusResult.payload.catalog.configDigest,
|
|
796
|
+
compositeDigest: sessionStatusResult.payload.catalog.compositeDigest,
|
|
797
|
+
generationSetDigest: catalogOperation.generationSetDigest,
|
|
798
|
+
},
|
|
799
|
+
source: selected.source,
|
|
800
|
+
targetFingerprint: statusTargetFingerprint(relevantTargets, relevantRevisions),
|
|
801
|
+
config: {
|
|
802
|
+
scope: intent.scope,
|
|
803
|
+
projectLayer: intent.projectLayer,
|
|
804
|
+
schemaIdentity: selected.source.manifestDigest,
|
|
805
|
+
storeDigest: digest({ exists: store.exists, values: store.values }),
|
|
806
|
+
affectedTargets: relevantTargets.map(({ platform, scope }) => ({ platform, scope })),
|
|
807
|
+
},
|
|
808
|
+
};
|
|
809
|
+
catalogOperationByEvidence.set(evidence, catalogOperation);
|
|
810
|
+
return evidence;
|
|
547
811
|
}
|
|
548
812
|
await preparation?.reporter.emit('status');
|
|
549
|
-
const
|
|
813
|
+
const statusCatalogOperation = offlineCleanupReason
|
|
814
|
+
? undefined
|
|
815
|
+
: catalogOperation ?? (!freshCatalog ? sessionCatalogOperationContext : undefined);
|
|
816
|
+
const status = await statusCommandV6({
|
|
550
817
|
plugins: [...new Set([intent.pluginId,
|
|
551
818
|
...(intent.kind === 'pluginWrite' && intent.originIssue?.consumerPluginId
|
|
552
819
|
? [intent.originIssue.consumerPluginId] : [])])],
|
|
@@ -557,39 +824,72 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
557
824
|
cwd: context.cwd,
|
|
558
825
|
env: context.env,
|
|
559
826
|
cliVersion: packageInfo.version,
|
|
827
|
+
...(statusCatalogOperation ? { catalogOperationContext: statusCatalogOperation } : {}),
|
|
828
|
+
inventoryCatalogSourceReferences: operationInventory,
|
|
560
829
|
});
|
|
561
830
|
signal?.throwIfAborted();
|
|
831
|
+
const configSnapshot = await readCatalogSourcesConfigSnapshot(context.env);
|
|
832
|
+
signal?.throwIfAborted();
|
|
833
|
+
if (configSnapshot.digest !== status.payload.catalog.configDigest) {
|
|
834
|
+
throw operationReviewStale('准备确认信息期间来源配置发生变化。');
|
|
835
|
+
}
|
|
836
|
+
if (catalogOperationError)
|
|
837
|
+
throw catalogOperationError;
|
|
562
838
|
if (intent.kind === 'pluginWrite') {
|
|
563
839
|
await assertTypedIssueOrigin(intent, status.payload.targets);
|
|
564
840
|
if (preparation?.validateIntent) {
|
|
565
841
|
assertIntentIsLegal(intent, status.payload.targets, status.targetRevisions);
|
|
566
842
|
}
|
|
567
843
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
844
|
+
if (!offlineCleanupReason && !catalogOperation) {
|
|
845
|
+
catalogOperation = await resolveCatalogOperationContext({
|
|
846
|
+
sourceIds: [parsePluginId(intent.pluginId).sourceId],
|
|
847
|
+
configSnapshot,
|
|
848
|
+
env: context.env,
|
|
849
|
+
...(!freshCatalog ? { validatedStoreEntries, validatingStoreEntries } : {}),
|
|
850
|
+
...(signal ? { signal } : {}),
|
|
851
|
+
});
|
|
572
852
|
}
|
|
573
853
|
let dependencyPlan;
|
|
854
|
+
let codexReconcilePlans;
|
|
574
855
|
await preparation?.reporter.emit('catalog');
|
|
575
|
-
const
|
|
576
|
-
&& intent.action === 'cleanup'
|
|
577
|
-
&& intent.originIssue?.category === 'sourceUnavailable'
|
|
578
|
-
&& intent.originIssue.actionId === 'cleanup'
|
|
856
|
+
const offlineCleanupTarget = offlineCleanupReason && intent.kind === 'pluginWrite'
|
|
579
857
|
? status.payload.targets.find((target) => target.pluginId === intent.pluginId
|
|
580
858
|
&& target.platform === intent.platform
|
|
581
859
|
&& target.scope === intent.scope
|
|
582
|
-
&& target.errors.some((error) => error.code ===
|
|
860
|
+
&& target.errors.some((error) => error.code === offlineCleanupReason))
|
|
583
861
|
: undefined;
|
|
584
|
-
const catalogSource =
|
|
585
|
-
? status.payload.catalog.sources.find((source) => source.id ===
|
|
862
|
+
const catalogSource = offlineCleanupTarget
|
|
863
|
+
? status.payload.catalog.sources.find((source) => source.id === offlineCleanupTarget.sourceId)
|
|
586
864
|
: undefined;
|
|
587
|
-
|
|
865
|
+
let offlineCleanup;
|
|
866
|
+
if (offlineCleanupReason && offlineCleanupTarget) {
|
|
867
|
+
await preparation?.reporter.emit('inventory');
|
|
868
|
+
const inventory = await operationInventory({
|
|
869
|
+
cwd: context.cwd,
|
|
870
|
+
env: context.env,
|
|
871
|
+
});
|
|
872
|
+
signal?.throwIfAborted();
|
|
873
|
+
offlineCleanup = offlineCleanupEvidenceFromInventory({
|
|
874
|
+
reason: offlineCleanupReason,
|
|
875
|
+
pluginId: offlineCleanupTarget.pluginId,
|
|
876
|
+
pluginName: offlineCleanupTarget.pluginName,
|
|
877
|
+
sourceId: offlineCleanupTarget.sourceId,
|
|
878
|
+
sourceIdentity: offlineCleanupTarget.sourceIdentity,
|
|
879
|
+
platform: offlineCleanupTarget.platform,
|
|
880
|
+
scope: offlineCleanupTarget.scope,
|
|
881
|
+
inventory,
|
|
882
|
+
}) ?? undefined;
|
|
883
|
+
if (!offlineCleanup) {
|
|
884
|
+
throw operationReviewStale('离线清理现场证据已消失或无法验证。');
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const selected = offlineCleanupTarget
|
|
588
888
|
? {
|
|
589
|
-
pluginName:
|
|
889
|
+
pluginName: offlineCleanupTarget.pluginName,
|
|
590
890
|
source: {
|
|
591
|
-
sourceId:
|
|
592
|
-
sourceIdentity:
|
|
891
|
+
sourceId: offlineCleanupTarget.sourceId,
|
|
892
|
+
sourceIdentity: offlineCleanupTarget.sourceIdentity,
|
|
593
893
|
...(catalogSource?.requestedRef ? { requestedRef: catalogSource.requestedRef } : {}),
|
|
594
894
|
...(catalogSource?.resolvedCommit ? { resolvedCommit: catalogSource.resolvedCommit } : {}),
|
|
595
895
|
},
|
|
@@ -597,9 +897,9 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
597
897
|
: await withResolvedCatalogPlugin({
|
|
598
898
|
selector: intent.pluginId,
|
|
599
899
|
cliVersion: packageInfo.version,
|
|
600
|
-
freshnessPolicy,
|
|
601
900
|
configSnapshot,
|
|
602
901
|
env: context.env,
|
|
902
|
+
...(catalogOperation ? { operationContext: catalogOperation } : {}),
|
|
603
903
|
...(signal ? { signal } : {}),
|
|
604
904
|
consume: async ({ plugin, source }) => {
|
|
605
905
|
if (preparation?.validateIntent && intent.kind === 'configSave') {
|
|
@@ -624,48 +924,112 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
624
924
|
};
|
|
625
925
|
},
|
|
626
926
|
});
|
|
927
|
+
let codexManager;
|
|
627
928
|
const hasDeclaredDependencies = (status.pluginSummaries.find((summary) => summary.pluginId === intent.pluginId)?.dependencyTotalCount ?? 0) > 0;
|
|
628
|
-
if (intent.kind === 'pluginWrite'
|
|
629
|
-
&& hasDeclaredDependencies
|
|
630
|
-
&& (intent.action === 'install' || intent.action === 'upgrade' || intent.action === 'reinstall')) {
|
|
929
|
+
if (intent.kind === 'pluginWrite') {
|
|
631
930
|
const command = {
|
|
632
931
|
install: installWriteCommand,
|
|
633
932
|
upgrade: upgradeWriteCommand,
|
|
634
933
|
reinstall: reinstallWriteCommand,
|
|
934
|
+
uninstall: uninstallWriteCommand,
|
|
935
|
+
cleanup: cleanupWriteCommand,
|
|
936
|
+
sync: installWriteCommand,
|
|
635
937
|
}[intent.action];
|
|
636
938
|
const preview = await command([intent.pluginId], {
|
|
637
939
|
cwd: context.cwd,
|
|
638
940
|
platform: intent.platform,
|
|
639
941
|
scope: intent.scope,
|
|
942
|
+
...(intent.action === 'install' && intent.dependencyScopeOverrides
|
|
943
|
+
? { dependencyScopeOverrides: intent.dependencyScopeOverrides }
|
|
944
|
+
: {}),
|
|
945
|
+
...(intent.action === 'cleanup' ? { force: intent.force === true } : {}),
|
|
640
946
|
}, {
|
|
641
947
|
...context,
|
|
948
|
+
inventoryCatalogSourceReferences: operationInventory,
|
|
642
949
|
expectedCatalogConfigDigest: status.payload.catalog.configDigest,
|
|
950
|
+
...(catalogOperation ? {
|
|
951
|
+
catalogOperationContext: catalogOperation,
|
|
952
|
+
expectedGenerationSetDigest: catalogOperation.generationSetDigest,
|
|
953
|
+
} : {}),
|
|
643
954
|
previewDependencyPlanOnly: true,
|
|
955
|
+
...(intent.action === 'sync' ? { reconcileIntentOnly: true } : {}),
|
|
644
956
|
...(preparation ? {
|
|
645
|
-
previewCatalogFreshnessPolicy: 'cacheFirst',
|
|
646
957
|
onPreviewStage: (stage) => stage === 'catalog' ? undefined : preparation.reporter.emit(stage),
|
|
647
958
|
} : {}),
|
|
648
959
|
});
|
|
649
960
|
signal?.throwIfAborted();
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
961
|
+
codexReconcilePlans = intent.dependencyPlacementOnly === 'desired'
|
|
962
|
+
? undefined
|
|
963
|
+
: preview?.codexReconcilePlans;
|
|
964
|
+
if (hasDeclaredDependencies
|
|
965
|
+
&& (intent.action === 'install'
|
|
966
|
+
|| intent.action === 'upgrade'
|
|
967
|
+
|| intent.action === 'reinstall'
|
|
968
|
+
|| intent.action === 'sync')) {
|
|
969
|
+
dependencyPlan = preview.dependencyPlan;
|
|
970
|
+
if (!dependencyPlan) {
|
|
971
|
+
throw new TuiOperationBlockedError('dependencyGraphInvalid', '无法建立可信的依赖安装计划。');
|
|
972
|
+
}
|
|
973
|
+
const blocker = dependencyPlan.targets.find((target) => target.action === 'block');
|
|
974
|
+
if (blocker) {
|
|
975
|
+
throw new TuiOperationBlockedError(blocker.errorCode ?? 'dependencyNotReady', `${blocker.errorCode ?? 'dependencyNotReady'}: 依赖安装计划被阻止。`);
|
|
976
|
+
}
|
|
653
977
|
}
|
|
654
|
-
const
|
|
655
|
-
if (
|
|
656
|
-
|
|
978
|
+
const managerPreview = preview?.codexManagerPreview;
|
|
979
|
+
if (managerPreview?.state === 'blocked' && intent.dependencyPlacementOnly !== 'desired') {
|
|
980
|
+
const message = managerPreview.code === 'codexSystemCliUnsupported'
|
|
981
|
+
? '系统 Codex CLI 版本不受支持。请升级官方 Codex CLI 后重试。'
|
|
982
|
+
: 'AW-managed Codex runtime 当前不可用。请重试、升级 AW,或安装官方 Codex CLI。';
|
|
983
|
+
throw new TuiOperationBlockedError(managerPreview.code, `${managerPreview.code}: ${message}`);
|
|
984
|
+
}
|
|
985
|
+
if (managerPreview && managerPreview.state !== 'blocked'
|
|
986
|
+
&& intent.dependencyPlacementOnly !== 'desired') {
|
|
987
|
+
codexManager = {
|
|
988
|
+
state: managerPreview.state,
|
|
989
|
+
packageName: MANAGED_CODEX_PACKAGE_NAME,
|
|
990
|
+
version: managerPreview.state === 'requires-install'
|
|
991
|
+
? MANAGED_CODEX_VERSION
|
|
992
|
+
: managerPreview.manager.version,
|
|
993
|
+
};
|
|
657
994
|
}
|
|
658
995
|
}
|
|
659
996
|
await preparation?.reporter.emit('evidence');
|
|
660
997
|
signal?.throwIfAborted();
|
|
998
|
+
let projectIntentDigest;
|
|
999
|
+
if (intent.kind === 'pluginWrite' && intent.dependencyPlacementOnly === 'desired') {
|
|
1000
|
+
if (intent.scope !== 'project') {
|
|
1001
|
+
throw new TuiOperationBlockedError('dependencyPlacementScopeInvalid', '缩小依赖位置只能更新当前项目 desired intent。');
|
|
1002
|
+
}
|
|
1003
|
+
projectIntentDigest = calculatePluginIntentDigest(await readPluginIntentState({
|
|
1004
|
+
scope: 'project',
|
|
1005
|
+
cwd: context.cwd,
|
|
1006
|
+
env: context.env,
|
|
1007
|
+
}));
|
|
1008
|
+
signal?.throwIfAborted();
|
|
1009
|
+
}
|
|
1010
|
+
const evidenceTargets = intent.kind === 'configSave' || intent.kind === 'configReset'
|
|
1011
|
+
? configAffectedStatusTargets(status.payload.targets, intent.pluginId, intent.scope)
|
|
1012
|
+
: status.payload.targets;
|
|
1013
|
+
const evidenceRevisions = intent.kind === 'configSave' || intent.kind === 'configReset'
|
|
1014
|
+
? (status.targetRevisions ?? []).filter((revision) => evidenceTargets.some((target) => target.platform === revision.platform
|
|
1015
|
+
&& target.scope === revision.scope
|
|
1016
|
+
&& target.pluginId === revision.pluginId))
|
|
1017
|
+
: (status.targetRevisions ?? []);
|
|
661
1018
|
const evidence = {
|
|
662
1019
|
catalog: {
|
|
663
1020
|
configDigest: status.payload.catalog.configDigest,
|
|
664
1021
|
compositeDigest: status.payload.catalog.compositeDigest,
|
|
1022
|
+
...(catalogOperation
|
|
1023
|
+
? { generationSetDigest: catalogOperation.generationSetDigest }
|
|
1024
|
+
: {}),
|
|
665
1025
|
},
|
|
666
1026
|
source: selected.source,
|
|
1027
|
+
...(offlineCleanup ? { offlineCleanup } : {}),
|
|
667
1028
|
...(dependencyPlan ? { dependencyPlan } : {}),
|
|
668
|
-
|
|
1029
|
+
...(projectIntentDigest ? { projectIntentDigest } : {}),
|
|
1030
|
+
...(codexReconcilePlans ? { codexReconcilePlans } : {}),
|
|
1031
|
+
...(codexManager ? { codexManager } : {}),
|
|
1032
|
+
targetFingerprint: statusTargetFingerprint(evidenceTargets, evidenceRevisions),
|
|
669
1033
|
};
|
|
670
1034
|
if (intent.kind === 'configSave' || intent.kind === 'configReset') {
|
|
671
1035
|
const store = await readPluginConfigStore({
|
|
@@ -683,11 +1047,21 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
683
1047
|
projectLayer: intent.projectLayer,
|
|
684
1048
|
schemaIdentity: selected.source.manifestDigest,
|
|
685
1049
|
storeDigest: digest({ exists: store.exists, values: store.values }),
|
|
1050
|
+
affectedTargets: evidenceTargets.map(({ platform, scope }) => ({ platform, scope })),
|
|
686
1051
|
};
|
|
687
1052
|
}
|
|
1053
|
+
if (catalogOperation)
|
|
1054
|
+
catalogOperationByEvidence.set(evidence, catalogOperation);
|
|
688
1055
|
return evidence;
|
|
689
1056
|
};
|
|
690
1057
|
const dependencies = {
|
|
1058
|
+
beginCatalogSession(sessionOptions) {
|
|
1059
|
+
sessionCatalogOperationContext = undefined;
|
|
1060
|
+
if (sessionOptions?.reuseValidatedGenerations !== true) {
|
|
1061
|
+
validatedStoreEntries.clear();
|
|
1062
|
+
validatingStoreEntries.clear();
|
|
1063
|
+
}
|
|
1064
|
+
},
|
|
691
1065
|
loadStatus,
|
|
692
1066
|
async inspectSourceRemoval(_sourceId, signal) {
|
|
693
1067
|
signal.throwIfAborted();
|
|
@@ -708,7 +1082,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
708
1082
|
now: options.now ?? Date.now,
|
|
709
1083
|
});
|
|
710
1084
|
try {
|
|
711
|
-
return await captureEvidence(intent, signal,
|
|
1085
|
+
return await captureEvidence(intent, signal, {
|
|
712
1086
|
reporter,
|
|
713
1087
|
validateIntent: true,
|
|
714
1088
|
});
|
|
@@ -717,10 +1091,14 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
717
1091
|
await reporter.finish();
|
|
718
1092
|
}
|
|
719
1093
|
},
|
|
1094
|
+
async previewDependencyPlacement(intent, signal) {
|
|
1095
|
+
const evidence = await captureEvidence(intent, signal);
|
|
1096
|
+
return evidence.dependencyPlan;
|
|
1097
|
+
},
|
|
720
1098
|
async validateIntent(intent, signal) {
|
|
721
1099
|
if (intent.kind === 'sourceMutation') {
|
|
722
1100
|
const evidence = await captureEvidence(intent, signal);
|
|
723
|
-
if (evidence.sourceWrite?.configDigest === evidence.sourceWrite?.
|
|
1101
|
+
if (evidence.sourceWrite?.configDigest === evidence.sourceWrite?.proposedConfigDigest) {
|
|
724
1102
|
throw new TuiOperationBlockedError('sourceNoChanges', '来源没有变化。');
|
|
725
1103
|
}
|
|
726
1104
|
return;
|
|
@@ -730,9 +1108,11 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
730
1108
|
await withResolvedCatalogPlugin({
|
|
731
1109
|
selector: intent.pluginId,
|
|
732
1110
|
cliVersion: packageInfo.version,
|
|
733
|
-
freshnessPolicy: 'cacheFirst',
|
|
734
1111
|
env: context.env,
|
|
735
1112
|
signal,
|
|
1113
|
+
...(sessionContextForPlugin(intent.pluginId)
|
|
1114
|
+
? { operationContext: sessionContextForPlugin(intent.pluginId) }
|
|
1115
|
+
: {}),
|
|
736
1116
|
consume: async ({ plugin }) => {
|
|
737
1117
|
if (!plugin.manifest.config) {
|
|
738
1118
|
throw new TuiOperationBlockedError('configSchemaUnavailable', '这个插件没有设置 schema。');
|
|
@@ -755,39 +1135,53 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
755
1135
|
return;
|
|
756
1136
|
signal.throwIfAborted();
|
|
757
1137
|
const packageInfo = await readCliPackageInfo();
|
|
758
|
-
const
|
|
759
|
-
|
|
760
|
-
|
|
1138
|
+
const pluginIds = [...new Set([intent.pluginId,
|
|
1139
|
+
...(intent.originIssue?.consumerPluginId ? [intent.originIssue.consumerPluginId] : [])])];
|
|
1140
|
+
const offlineCleanup = intent.action === 'cleanup'
|
|
1141
|
+
&& intent.originIssue?.actionId === 'cleanup'
|
|
1142
|
+
&& (intent.originIssue.category === 'sourceMissing'
|
|
1143
|
+
|| intent.originIssue.category === 'sourceUnavailable');
|
|
1144
|
+
const sourceIds = pluginIds.map((pluginId) => parsePluginId(pluginId).sourceId);
|
|
1145
|
+
let catalogOperation = offlineCleanup
|
|
1146
|
+
? undefined
|
|
1147
|
+
: sessionCatalogOperationContext
|
|
1148
|
+
? selectCatalogOperationContext(sessionCatalogOperationContext, sourceIds)
|
|
1149
|
+
: undefined;
|
|
1150
|
+
const statusOptions = {
|
|
1151
|
+
plugins: pluginIds,
|
|
761
1152
|
platform: intent.platform,
|
|
762
1153
|
cwd: context.cwd,
|
|
763
1154
|
env: context.env,
|
|
764
1155
|
cliVersion: packageInfo.version,
|
|
1156
|
+
inventoryCatalogSourceReferences: readInventory,
|
|
1157
|
+
};
|
|
1158
|
+
let status = await statusCommandV6({
|
|
1159
|
+
...statusOptions,
|
|
1160
|
+
...(catalogOperation ? { catalogOperationContext: catalogOperation } : {}),
|
|
765
1161
|
});
|
|
1162
|
+
const platforms = intent.platform === 'both'
|
|
1163
|
+
? ['codex', 'claude']
|
|
1164
|
+
: [intent.platform];
|
|
1165
|
+
const missingSelectedTarget = platforms.some((platform) => !status.payload.targets.some((target) => target.pluginId === intent.pluginId
|
|
1166
|
+
&& target.platform === platform
|
|
1167
|
+
&& (platform === 'codex' || target.scope === intent.scope)));
|
|
1168
|
+
if (!offlineCleanup && !catalogOperation && missingSelectedTarget) {
|
|
1169
|
+
catalogOperation = await resolveCatalogOperationContext({
|
|
1170
|
+
sourceIds,
|
|
1171
|
+
env: context.env,
|
|
1172
|
+
validatedStoreEntries,
|
|
1173
|
+
validatingStoreEntries,
|
|
1174
|
+
signal,
|
|
1175
|
+
});
|
|
1176
|
+
status = await statusCommandV6({
|
|
1177
|
+
...statusOptions,
|
|
1178
|
+
catalogOperationContext: catalogOperation,
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
766
1181
|
signal.throwIfAborted();
|
|
767
1182
|
await assertTypedIssueOrigin(intent, status.payload.targets);
|
|
768
1183
|
assertIntentIsLegal(intent, status.payload.targets, status.targetRevisions);
|
|
769
1184
|
},
|
|
770
|
-
async checkSource(sourceId, signal) {
|
|
771
|
-
const packageInfo = await readCliPackageInfo();
|
|
772
|
-
const configSnapshot = await readCatalogSourcesConfigSnapshot(context.env);
|
|
773
|
-
return withResolvedMultiSourceCatalog({
|
|
774
|
-
cliVersion: packageInfo.version,
|
|
775
|
-
freshnessPolicy: 'forceRemote',
|
|
776
|
-
sourceIds: [sourceId],
|
|
777
|
-
configSnapshot,
|
|
778
|
-
env: context.env,
|
|
779
|
-
signal,
|
|
780
|
-
consume: (catalog) => {
|
|
781
|
-
const item = catalog.sources[0];
|
|
782
|
-
if (item.error)
|
|
783
|
-
throw item.error;
|
|
784
|
-
return {
|
|
785
|
-
sourceIdentity: item.resolution.sourceIdentity,
|
|
786
|
-
requestedRef: item.resolution.requestedRef,
|
|
787
|
-
};
|
|
788
|
-
},
|
|
789
|
-
});
|
|
790
|
-
},
|
|
791
1185
|
captureEvidence,
|
|
792
1186
|
logError(_error, code, logContext) {
|
|
793
1187
|
return context.debugLogger.log({
|
|
@@ -805,9 +1199,11 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
805
1199
|
return withResolvedCatalogPlugin({
|
|
806
1200
|
selector: pluginId,
|
|
807
1201
|
cliVersion: packageInfo.version,
|
|
808
|
-
freshnessPolicy: 'cacheFirst',
|
|
809
1202
|
env: context.env,
|
|
810
1203
|
signal,
|
|
1204
|
+
...(sessionContextForPlugin(pluginId)
|
|
1205
|
+
? { operationContext: sessionContextForPlugin(pluginId) }
|
|
1206
|
+
: {}),
|
|
811
1207
|
consume: async ({ plugin }) => {
|
|
812
1208
|
if (!plugin.manifest.config) {
|
|
813
1209
|
throw new TuiOperationBlockedError('configSchemaUnavailable', '这个插件没有设置 schema。');
|
|
@@ -837,9 +1233,11 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
837
1233
|
return withResolvedCatalogPlugin({
|
|
838
1234
|
selector: pluginId,
|
|
839
1235
|
cliVersion: packageInfo.version,
|
|
840
|
-
freshnessPolicy: 'cacheFirst',
|
|
841
1236
|
env: context.env,
|
|
842
1237
|
signal,
|
|
1238
|
+
...(sessionContextForPlugin(pluginId)
|
|
1239
|
+
? { operationContext: sessionContextForPlugin(pluginId) }
|
|
1240
|
+
: {}),
|
|
843
1241
|
consume: async ({ plugin }) => {
|
|
844
1242
|
if (!plugin.manifest.config) {
|
|
845
1243
|
throw new TuiOperationBlockedError('configSchemaUnavailable', '这个插件没有设置 schema。');
|
|
@@ -860,7 +1258,39 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
860
1258
|
cwd: context.cwd,
|
|
861
1259
|
env: context.env,
|
|
862
1260
|
});
|
|
863
|
-
|
|
1261
|
+
const layerReads = layer.scope === 'effective' ? undefined : {
|
|
1262
|
+
user: await resolveConfigRead({
|
|
1263
|
+
pluginName: plugin.manifest.name,
|
|
1264
|
+
plugin,
|
|
1265
|
+
scope: 'user',
|
|
1266
|
+
projectLayer: 'shared',
|
|
1267
|
+
cwd: context.cwd,
|
|
1268
|
+
env: context.env,
|
|
1269
|
+
}),
|
|
1270
|
+
project: await resolveConfigRead({
|
|
1271
|
+
pluginName: plugin.manifest.name,
|
|
1272
|
+
plugin,
|
|
1273
|
+
scope: 'project',
|
|
1274
|
+
projectLayer: 'shared',
|
|
1275
|
+
cwd: context.cwd,
|
|
1276
|
+
env: context.env,
|
|
1277
|
+
}),
|
|
1278
|
+
local: await resolveConfigRead({
|
|
1279
|
+
pluginName: plugin.manifest.name,
|
|
1280
|
+
plugin,
|
|
1281
|
+
scope: 'project',
|
|
1282
|
+
projectLayer: 'local',
|
|
1283
|
+
cwd: context.cwd,
|
|
1284
|
+
env: context.env,
|
|
1285
|
+
}),
|
|
1286
|
+
};
|
|
1287
|
+
return buildConfigPage({
|
|
1288
|
+
pluginId,
|
|
1289
|
+
schema: plugin.manifest.config,
|
|
1290
|
+
read,
|
|
1291
|
+
effectiveRead,
|
|
1292
|
+
...(layerReads ? { layerReads } : {}),
|
|
1293
|
+
});
|
|
864
1294
|
},
|
|
865
1295
|
});
|
|
866
1296
|
},
|
|
@@ -920,6 +1350,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
920
1350
|
env: context.env,
|
|
921
1351
|
cliVersion: packageInfo.version,
|
|
922
1352
|
expectedEvidenceDigest: expectedEvidence.portable.evidenceDigest,
|
|
1353
|
+
expectedGenerationSetDigest: expectedEvidence.catalog.generationSetDigest,
|
|
923
1354
|
onProgress(stage) {
|
|
924
1355
|
const phase = stage === 'prepare' ? '检查插件依赖并生成候选'
|
|
925
1356
|
: stage === 'add' ? '安装已选择的 Skills' : '验证安装结果';
|
|
@@ -934,49 +1365,87 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
934
1365
|
throw error;
|
|
935
1366
|
}
|
|
936
1367
|
}
|
|
1368
|
+
if (intent.kind === 'sourceMutation') {
|
|
1369
|
+
const currentEvidence = await captureEvidence(intent);
|
|
1370
|
+
if (operationEvidenceFingerprint(currentEvidence) !== operationEvidenceFingerprint(expectedEvidence)) {
|
|
1371
|
+
throw new TuiOperationBlockedError('operationReviewStale', '确认后状态发生变化。');
|
|
1372
|
+
}
|
|
1373
|
+
await tuiControllerRuntimeTestHooks?.afterMutationEvidenceCapture?.();
|
|
1374
|
+
const packageInfo = await readCliPackageInfo();
|
|
1375
|
+
const runtime = {
|
|
1376
|
+
onProgress: async (event) => {
|
|
1377
|
+
const phase = SOURCE_PROGRESS_PHASES[event.stage];
|
|
1378
|
+
progressFeed?.setCurrent({ target: 'Catalog 来源配置', phase }, `来源操作:${phase}`);
|
|
1379
|
+
await tuiControllerRuntimeTestHooks?.onCatalogSourceProgress?.(event);
|
|
1380
|
+
},
|
|
1381
|
+
};
|
|
1382
|
+
const common = {
|
|
1383
|
+
cwd: context.cwd,
|
|
1384
|
+
env: context.env,
|
|
1385
|
+
expectedConfigDigest: expectedEvidence.sourceWrite?.configDigest,
|
|
1386
|
+
runtime,
|
|
1387
|
+
};
|
|
1388
|
+
if (intent.action === 'add' && intent.source) {
|
|
1389
|
+
return addCatalogSourceCommand({ ...common, source: intent.source, cliVersion: packageInfo.version });
|
|
1390
|
+
}
|
|
1391
|
+
if (intent.action === 'update' && intent.update) {
|
|
1392
|
+
return updateCatalogSourceCommand({ ...common, sourceId: intent.sourceId, update: intent.update, cliVersion: packageInfo.version });
|
|
1393
|
+
}
|
|
1394
|
+
if (intent.action === 'setPrimary') {
|
|
1395
|
+
return setPrimaryCatalogSourceCommand({ ...common, sourceId: intent.sourceId });
|
|
1396
|
+
}
|
|
1397
|
+
if (intent.action === 'remove') {
|
|
1398
|
+
return removeCatalogSourceCommand({ ...common, sourceId: intent.sourceId });
|
|
1399
|
+
}
|
|
1400
|
+
throw new TuiOperationBlockedError('invalidSourceMutation', '来源操作缺少候选输入。');
|
|
1401
|
+
}
|
|
937
1402
|
return withAwHomeMutationLock({
|
|
938
1403
|
env: context.env,
|
|
939
1404
|
action: async (awHomeMutationToken) => {
|
|
940
|
-
|
|
1405
|
+
await tuiControllerRuntimeTestHooks?.beforeMutationEvidenceCapture?.();
|
|
1406
|
+
const operationInventory = createOperationInventoryReader();
|
|
1407
|
+
const currentEvidence = await captureEvidence(intent, undefined, undefined, operationInventory, true);
|
|
941
1408
|
if (operationEvidenceFingerprint(currentEvidence) !== operationEvidenceFingerprint(expectedEvidence)) {
|
|
942
1409
|
throw new TuiOperationBlockedError('operationReviewStale', '确认后状态发生变化。');
|
|
943
1410
|
}
|
|
944
|
-
|
|
945
|
-
if (
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
awHomeMutationToken,
|
|
949
|
-
onProgress: async (event) => {
|
|
950
|
-
const phase = SOURCE_PROGRESS_PHASES[event.stage];
|
|
951
|
-
progressFeed?.setCurrent({ target: 'Catalog 来源配置', phase }, `来源操作:${phase}`);
|
|
952
|
-
await tuiControllerRuntimeTestHooks?.onCatalogSourceProgress?.(event);
|
|
953
|
-
},
|
|
954
|
-
};
|
|
955
|
-
const common = {
|
|
956
|
-
cwd: context.cwd,
|
|
957
|
-
env: context.env,
|
|
958
|
-
expectedConfigDigest: expectedEvidence.sourceWrite?.configDigest,
|
|
959
|
-
runtime,
|
|
960
|
-
};
|
|
961
|
-
if (intent.action === 'add' && intent.source) {
|
|
962
|
-
return addCatalogSourceCommand({ ...common, source: intent.source, cliVersion: packageInfo.version });
|
|
963
|
-
}
|
|
964
|
-
if (intent.action === 'update' && intent.update) {
|
|
965
|
-
return updateCatalogSourceCommand({ ...common, sourceId: intent.sourceId, update: intent.update, cliVersion: packageInfo.version });
|
|
966
|
-
}
|
|
967
|
-
if (intent.action === 'setPrimary') {
|
|
968
|
-
return setPrimaryCatalogSourceCommand({ ...common, sourceId: intent.sourceId });
|
|
969
|
-
}
|
|
970
|
-
if (intent.action === 'remove') {
|
|
971
|
-
return removeCatalogSourceCommand({ ...common, sourceId: intent.sourceId });
|
|
972
|
-
}
|
|
973
|
-
throw new TuiOperationBlockedError('invalidSourceMutation', '来源操作缺少候选输入。');
|
|
1411
|
+
const catalogOperation = catalogOperationByEvidence.get(currentEvidence);
|
|
1412
|
+
if (expectedEvidence.catalog.generationSetDigest
|
|
1413
|
+
&& catalogOperation?.generationSetDigest !== expectedEvidence.catalog.generationSetDigest) {
|
|
1414
|
+
throw operationReviewStale('确认后 Active Catalog generation 发生变化。');
|
|
974
1415
|
}
|
|
1416
|
+
await tuiControllerRuntimeTestHooks?.afterMutationEvidenceCapture?.();
|
|
975
1417
|
if (intent.kind === 'pluginWrite') {
|
|
1418
|
+
if (intent.dependencyPlacementOnly === 'desired') {
|
|
1419
|
+
const plan = currentEvidence.dependencyPlan;
|
|
1420
|
+
if (!plan || !expectedEvidence.projectIntentDigest) {
|
|
1421
|
+
throw operationReviewStale('确认信息缺少依赖位置或 project intent 证据。');
|
|
1422
|
+
}
|
|
1423
|
+
const location = { scope: 'project', cwd: context.cwd, env: context.env };
|
|
1424
|
+
const currentIntent = await readPluginIntentState(location);
|
|
1425
|
+
if (calculatePluginIntentDigest(currentIntent) !== expectedEvidence.projectIntentDigest) {
|
|
1426
|
+
throw operationReviewStale('确认后 project desired intent 发生变化。');
|
|
1427
|
+
}
|
|
1428
|
+
const plannedKeys = new Set(plan.targets.map((target) => `${target.pluginId}\0${target.platform}`));
|
|
1429
|
+
const nextIntent = canonicalizePluginIntentState({
|
|
1430
|
+
...currentIntent,
|
|
1431
|
+
dependencyScopeOverrides: [
|
|
1432
|
+
...currentIntent.dependencyScopeOverrides.filter((override) => !plannedKeys.has(`${override.pluginId}\0${override.platform}`)),
|
|
1433
|
+
...plan.scopeOverrides,
|
|
1434
|
+
],
|
|
1435
|
+
});
|
|
1436
|
+
await writePluginIntentState(location, nextIntent);
|
|
1437
|
+
return { dependencyPlan: plan, desiredPlacementUpdated: true };
|
|
1438
|
+
}
|
|
976
1439
|
const options = {
|
|
977
1440
|
cwd: context.cwd,
|
|
978
1441
|
platform: intent.platform,
|
|
979
1442
|
scope: intent.scope,
|
|
1443
|
+
...(intent.action === 'install' && intent.dependencyScopeOverrides
|
|
1444
|
+
? { dependencyScopeOverrides: intent.dependencyScopeOverrides }
|
|
1445
|
+
: {}),
|
|
1446
|
+
...(expectedEvidence.codexManager?.state === 'requires-install'
|
|
1447
|
+
? { allowManagedCodexInstall: true }
|
|
1448
|
+
: {}),
|
|
980
1449
|
...(intent.action === 'cleanup' ? { force: intent.force === true } : {}),
|
|
981
1450
|
};
|
|
982
1451
|
const command = {
|
|
@@ -985,16 +1454,35 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
985
1454
|
reinstall: reinstallWriteCommand,
|
|
986
1455
|
uninstall: uninstallWriteCommand,
|
|
987
1456
|
cleanup: cleanupWriteCommand,
|
|
1457
|
+
sync: installWriteCommand,
|
|
988
1458
|
}[intent.action];
|
|
989
1459
|
const currentSource = currentEvidence.source;
|
|
990
|
-
|
|
1460
|
+
const offlineCleanup = currentEvidence.offlineCleanup;
|
|
1461
|
+
if (!offlineCleanup && (!expectedEvidence.source || !currentSource)) {
|
|
991
1462
|
throw new TuiOperationBlockedError('operationReviewStale', '确认信息缺少来源身份。');
|
|
992
1463
|
}
|
|
993
1464
|
const result = await command([intent.pluginId], options, {
|
|
994
1465
|
...context,
|
|
995
1466
|
awHomeMutationToken,
|
|
1467
|
+
inventoryCatalogSourceReferences: operationInventory,
|
|
1468
|
+
...(currentEvidence.dependencyPlan
|
|
1469
|
+
? { expectedOperationDependencyPlan: currentEvidence.dependencyPlan }
|
|
1470
|
+
: {}),
|
|
1471
|
+
...(currentEvidence.codexReconcilePlans
|
|
1472
|
+
? { expectedCodexReconcilePlans: currentEvidence.codexReconcilePlans }
|
|
1473
|
+
: {}),
|
|
1474
|
+
...(intent.action === 'sync' ? { reconcileIntentOnly: true } : {}),
|
|
996
1475
|
expectedCatalogConfigDigest: expectedEvidence.catalog.configDigest,
|
|
997
|
-
|
|
1476
|
+
...(catalogOperation ? {
|
|
1477
|
+
catalogOperationContext: catalogOperation,
|
|
1478
|
+
expectedGenerationSetDigest: expectedEvidence.catalog.generationSetDigest,
|
|
1479
|
+
} : {}),
|
|
1480
|
+
...(expectedEvidence.codexManager?.state === 'requires-install'
|
|
1481
|
+
? { managedCodexAuthorizer: async () => true }
|
|
1482
|
+
: {}),
|
|
1483
|
+
...(offlineCleanup
|
|
1484
|
+
? { expectedOfflineCleanupEvidence: offlineCleanup }
|
|
1485
|
+
: { reviewPreflight: (actual) => assertSourceEvidenceMatches(currentSource, actual) }),
|
|
998
1486
|
});
|
|
999
1487
|
throwIfWriteReviewStale(result);
|
|
1000
1488
|
return result;
|
|
@@ -1008,10 +1496,15 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1008
1496
|
return withResolvedCatalogPlugin({
|
|
1009
1497
|
selector: intent.pluginId,
|
|
1010
1498
|
cliVersion: packageInfo.version,
|
|
1011
|
-
freshnessPolicy: 'requireRemote',
|
|
1012
1499
|
env: context.env,
|
|
1500
|
+
...(catalogOperation ? { operationContext: catalogOperation } : {}),
|
|
1013
1501
|
consume: async ({ plugin, source }) => {
|
|
1014
1502
|
assertSourceEvidenceMatches(currentSource, sourceEvidenceForPlugin(source, plugin.manifest.name));
|
|
1503
|
+
const applyTargets = currentEvidence.config?.affectedTargets.map((target) => ({
|
|
1504
|
+
pluginName: plugin.manifest.name,
|
|
1505
|
+
platform: target.platform,
|
|
1506
|
+
scope: target.scope,
|
|
1507
|
+
})) ?? [];
|
|
1015
1508
|
const result = intent.kind === 'configSave'
|
|
1016
1509
|
? await applyPluginConfigWrite({
|
|
1017
1510
|
plugin,
|
|
@@ -1021,8 +1514,16 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1021
1514
|
cwd: context.cwd,
|
|
1022
1515
|
env: context.env,
|
|
1023
1516
|
nativeCliRunner: context.nativeCliRunner,
|
|
1024
|
-
rebuildRuntime: {
|
|
1517
|
+
rebuildRuntime: {
|
|
1518
|
+
...context,
|
|
1519
|
+
awHomeMutationToken,
|
|
1520
|
+
...(catalogOperation ? {
|
|
1521
|
+
catalogOperationContext: catalogOperation,
|
|
1522
|
+
expectedGenerationSetDigest: expectedEvidence.catalog.generationSetDigest,
|
|
1523
|
+
} : {}),
|
|
1524
|
+
},
|
|
1025
1525
|
awHomeMutationToken,
|
|
1526
|
+
applyTargets,
|
|
1026
1527
|
request: { updates: intent.updates, removeKeys: intent.removeKeys },
|
|
1027
1528
|
})
|
|
1028
1529
|
: await resetPluginConfigWithHelper({
|
|
@@ -1033,8 +1534,16 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1033
1534
|
cwd: context.cwd,
|
|
1034
1535
|
env: context.env,
|
|
1035
1536
|
nativeCliRunner: context.nativeCliRunner,
|
|
1036
|
-
rebuildRuntime: {
|
|
1537
|
+
rebuildRuntime: {
|
|
1538
|
+
...context,
|
|
1539
|
+
awHomeMutationToken,
|
|
1540
|
+
...(catalogOperation ? {
|
|
1541
|
+
catalogOperationContext: catalogOperation,
|
|
1542
|
+
expectedGenerationSetDigest: expectedEvidence.catalog.generationSetDigest,
|
|
1543
|
+
} : {}),
|
|
1544
|
+
},
|
|
1037
1545
|
awHomeMutationToken,
|
|
1546
|
+
applyTargets,
|
|
1038
1547
|
});
|
|
1039
1548
|
return result;
|
|
1040
1549
|
},
|