@lesliechan721/aw 0.1.0-beta.63 → 0.1.0-beta.65
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-runtime-config.mjs +3 -3
- package/dist/authoring/assets/aw-runtime-config.mjs.map +1 -1
- package/dist/authoring/scripts/add-skill.mjs +3 -17
- package/dist/authoring/scripts/add-skill.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +1 -0
- 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 +2 -0
- package/dist/authoring/scripts/lib/skill-scaffold.mjs +2 -0
- package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +95 -698
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/aw-skill-eval-materializer.d.ts +2 -0
- package/dist/scripts/aw-skill-eval-materializer.js +74 -44
- package/dist/scripts/aw-skill-eval-materializer.js.map +1 -1
- package/dist/scripts/bundle-plugins.js +10 -2
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +1 -1
- package/dist/scripts/plugin-staging.js +1 -1
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.js +31 -31
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +1 -1
- package/dist/src/commands/aw-capabilities.js +2 -0
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/console.js +4 -3
- package/dist/src/commands/console.js.map +1 -1
- package/dist/src/commands/intent-command.d.ts +30 -0
- package/dist/src/commands/intent-command.js +164 -0
- package/dist/src/commands/intent-command.js.map +1 -0
- package/dist/src/commands/operation-plan.d.ts +2 -0
- package/dist/src/commands/operation-plan.js +2 -1
- package/dist/src/commands/operation-plan.js.map +1 -1
- package/dist/src/commands/options.d.ts +3 -11
- package/dist/src/commands/options.js +11 -17
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +27 -33
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +108 -6
- package/dist/src/commands/rebuild-command.js +617 -1549
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +19 -3
- package/dist/src/commands/rebuild-integration.js +500 -459
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.js +1 -2
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/review-inspection.d.ts +2 -2
- package/dist/src/commands/review-inspection.js +30 -86
- package/dist/src/commands/review-inspection.js.map +1 -1
- package/dist/src/commands/review-preparation.js +16 -7
- package/dist/src/commands/review-preparation.js.map +1 -1
- package/dist/src/commands/skill-eval.d.ts +2 -0
- package/dist/src/commands/skill-eval.js +15 -9
- package/dist/src/commands/skill-eval.js.map +1 -1
- package/dist/src/commands/status-v6.d.ts +38 -5
- package/dist/src/commands/status-v6.js +269 -102
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/commands/targets-command.d.ts +27 -0
- package/dist/src/commands/targets-command.js +77 -0
- package/dist/src/commands/targets-command.js.map +1 -0
- package/dist/src/commands/write-commands.js +5 -5
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/eval/manifest-v1.d.ts +2 -0
- package/dist/src/eval/manifest-v1.js +7 -2
- package/dist/src/eval/manifest-v1.js.map +1 -1
- package/dist/src/generators/local-plugin.d.ts +2 -1
- package/dist/src/generators/local-plugin.js +111 -108
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +10 -17
- package/dist/src/index.js +585 -1349
- package/dist/src/index.js.map +1 -1
- package/dist/src/intent/deployment-preferences.d.ts +63 -0
- package/dist/src/intent/deployment-preferences.js +170 -0
- package/dist/src/intent/deployment-preferences.js.map +1 -0
- package/dist/src/intent/diagnostics.d.ts +11 -0
- package/dist/src/intent/diagnostics.js +14 -0
- package/dist/src/intent/diagnostics.js.map +1 -0
- package/dist/src/intent/intent-codec.d.ts +19 -0
- package/dist/src/intent/intent-codec.js +117 -0
- package/dist/src/intent/intent-codec.js.map +1 -0
- package/dist/src/intent/intent-store.d.ts +43 -0
- package/dist/src/intent/intent-store.js +118 -0
- package/dist/src/intent/intent-store.js.map +1 -0
- package/dist/src/intent/scope-context.d.ts +33 -0
- package/dist/src/intent/scope-context.js +145 -0
- package/dist/src/intent/scope-context.js.map +1 -0
- package/dist/src/intent/work-context.d.ts +13 -0
- package/dist/src/intent/work-context.js +22 -0
- package/dist/src/intent/work-context.js.map +1 -0
- package/dist/src/output/command-receipt.js +16 -9
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/portable/commands.d.ts +18 -8
- package/dist/src/portable/commands.js +46 -562
- package/dist/src/portable/commands.js.map +1 -1
- package/dist/src/portable/historical-materialization.d.ts +22 -0
- package/dist/src/portable/historical-materialization.js +124 -0
- package/dist/src/portable/historical-materialization.js.map +1 -0
- package/dist/src/portable/materializer.d.ts +8 -0
- package/dist/src/portable/materializer.js +75 -44
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/portable/recovery-layout.d.ts +17 -0
- package/dist/src/portable/recovery-layout.js +55 -0
- package/dist/src/portable/recovery-layout.js.map +1 -0
- package/dist/src/portable/recovery.d.ts +143 -0
- package/dist/src/portable/recovery.js +339 -0
- package/dist/src/portable/recovery.js.map +1 -0
- package/dist/src/portable/writer.d.ts +64 -0
- package/dist/src/portable/writer.js +316 -0
- package/dist/src/portable/writer.js.map +1 -0
- package/dist/src/recovery/coordinator.d.ts +137 -0
- package/dist/src/recovery/coordinator.js +1198 -0
- package/dist/src/recovery/coordinator.js.map +1 -0
- package/dist/src/recovery/demand.d.ts +44 -0
- package/dist/src/recovery/demand.js +178 -0
- package/dist/src/recovery/demand.js.map +1 -0
- package/dist/src/recovery/joint-coordinator.d.ts +24 -0
- package/dist/src/recovery/joint-coordinator.js +770 -0
- package/dist/src/recovery/joint-coordinator.js.map +1 -0
- package/dist/src/recovery/joint-demand.d.ts +68 -0
- package/dist/src/recovery/joint-demand.js +166 -0
- package/dist/src/recovery/joint-demand.js.map +1 -0
- package/dist/src/recovery/receipt.d.ts +81 -0
- package/dist/src/recovery/receipt.js +2 -0
- package/dist/src/recovery/receipt.js.map +1 -0
- package/dist/src/recovery/retirement.d.ts +45 -0
- package/dist/src/recovery/retirement.js +366 -0
- package/dist/src/recovery/retirement.js.map +1 -0
- package/dist/src/recovery/status.d.ts +108 -0
- package/dist/src/recovery/status.js +417 -0
- package/dist/src/recovery/status.js.map +1 -0
- package/dist/src/recovery/types.d.ts +86 -0
- package/dist/src/recovery/types.js +2 -0
- package/dist/src/recovery/types.js.map +1 -0
- package/dist/src/review/review-profile.d.ts +2 -1
- package/dist/src/review/review-profile.js +15 -15
- package/dist/src/review/review-profile.js.map +1 -1
- package/dist/src/review/review-selection.d.ts +1 -2
- package/dist/src/review/review-selection.js +40 -114
- package/dist/src/review/review-selection.js.map +1 -1
- package/dist/src/review/review-types.d.ts +4 -4
- package/dist/src/review/review-types.js.map +1 -1
- package/dist/src/review/skill-materialization.js +15 -6
- package/dist/src/review/skill-materialization.js.map +1 -1
- package/dist/src/review/source-binding.d.ts +14 -4
- package/dist/src/review/source-binding.js +62 -117
- package/dist/src/review/source-binding.js.map +1 -1
- package/dist/src/tui/agent-management.d.ts +23 -0
- package/dist/src/tui/agent-management.js +217 -0
- package/dist/src/tui/agent-management.js.map +1 -0
- package/dist/src/tui/agent-settings.d.ts +44 -0
- package/dist/src/tui/agent-settings.js +98 -0
- package/dist/src/tui/agent-settings.js.map +1 -0
- package/dist/src/tui/components.d.ts +3 -0
- package/dist/src/tui/components.js +10 -1
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/config-references.d.ts +6 -3
- package/dist/src/tui/config-references.js +17 -12
- package/dist/src/tui/config-references.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +1 -2
- package/dist/src/tui/console-app-v4.js +1533 -1047
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +2 -1
- package/dist/src/tui/controller-runtime.js +457 -1634
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +131 -81
- package/dist/src/tui/controller.js +307 -227
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/entity-cards.d.ts +2 -2
- package/dist/src/tui/entity-cards.js +98 -20
- package/dist/src/tui/entity-cards.js.map +1 -1
- package/dist/src/tui/glossary.d.ts +2 -0
- package/dist/src/tui/glossary.js +20 -0
- package/dist/src/tui/glossary.js.map +1 -1
- package/dist/src/tui/model.d.ts +28 -10
- package/dist/src/tui/model.js +41 -41
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-review-planner.d.ts +2 -0
- package/dist/src/tui/operation-review-planner.js +58 -122
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/tui/plugin-content.js +7 -4
- package/dist/src/tui/plugin-content.js.map +1 -1
- package/dist/src/tui/plugin-detail.d.ts +22 -3
- package/dist/src/tui/plugin-detail.js +113 -26
- package/dist/src/tui/plugin-detail.js.map +1 -1
- package/dist/src/tui/reader.d.ts +1 -0
- package/dist/src/tui/reader.js +3 -1
- package/dist/src/tui/reader.js.map +1 -1
- package/dist/src/tui/router.d.ts +23 -33
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/scoped-flow.d.ts +45 -0
- package/dist/src/tui/scoped-flow.js +96 -0
- package/dist/src/tui/scoped-flow.js.map +1 -0
- package/dist/src/tui/scoped-inventory.d.ts +122 -0
- package/dist/src/tui/scoped-inventory.js +225 -0
- package/dist/src/tui/scoped-inventory.js.map +1 -0
- package/dist/src/tui/screen-registry.d.ts +25 -25
- package/dist/src/tui/screen-registry.js +3 -7
- package/dist/src/tui/screen-registry.js.map +1 -1
- package/dist/src/tui/session-console-app.js +1 -1
- package/dist/src/tui/session-console-app.js.map +1 -1
- package/dist/src/tui/session-host.js +12 -2
- package/dist/src/tui/session-host.js.map +1 -1
- package/dist/src/types.d.ts +15 -12
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.js +2 -0
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/artifact-plan.js +13 -6
- package/dist/src/utils/artifact-plan.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +6 -3
- package/dist/src/utils/artifact-renderer.js +27 -32
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/artifact-request.d.ts +1 -0
- package/dist/src/utils/artifact-request.js +22 -12
- package/dist/src/utils/artifact-request.js.map +1 -1
- package/dist/src/utils/artifact-sources.d.ts +2 -2
- package/dist/src/utils/bundle-layout.js +18 -16
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-digests.js +2 -0
- package/dist/src/utils/catalog-digests.js.map +1 -1
- package/dist/src/utils/catalog-runtime-projection.d.ts +4 -3
- package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
- package/dist/src/utils/catalog-source-references.d.ts +5 -0
- package/dist/src/utils/catalog-source-references.js +42 -57
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/claude-native-render-receipt.d.ts +14 -0
- package/dist/src/utils/claude-native-render-receipt.js +26 -0
- package/dist/src/utils/claude-native-render-receipt.js.map +1 -0
- package/dist/src/utils/claude-skills-root.js +14 -3
- package/dist/src/utils/claude-skills-root.js.map +1 -1
- package/dist/src/utils/codex-manager.js +6 -12
- package/dist/src/utils/codex-manager.js.map +1 -1
- package/dist/src/utils/codex-native-observation.js +29 -13
- package/dist/src/utils/codex-native-observation.js.map +1 -1
- package/dist/src/utils/codex-reconciler.d.ts +2 -5
- package/dist/src/utils/codex-reconciler.js +25 -1
- package/dist/src/utils/codex-reconciler.js.map +1 -1
- package/dist/src/utils/codex-surface-analysis.js +5 -3
- package/dist/src/utils/codex-surface-analysis.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +14 -2
- package/dist/src/utils/local-marketplace.js +209 -42
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/managed-command-evidence.js +1 -1
- package/dist/src/utils/managed-command-evidence.js.map +1 -1
- package/dist/src/utils/managed-command-materialization.d.ts +4 -0
- package/dist/src/utils/managed-command-materialization.js +15 -6
- package/dist/src/utils/managed-command-materialization.js.map +1 -1
- package/dist/src/utils/managed-command-store.d.ts +15 -0
- package/dist/src/utils/managed-command-store.js +73 -8
- package/dist/src/utils/managed-command-store.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +2 -0
- package/dist/src/utils/native-cli.js +22 -0
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/native-demand.d.ts +10 -0
- package/dist/src/utils/native-demand.js +4 -0
- package/dist/src/utils/native-demand.js.map +1 -0
- package/dist/src/utils/ownership.js +2 -0
- package/dist/src/utils/ownership.js.map +1 -1
- package/dist/src/utils/paths.js +1 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/platform-support.d.ts +1 -1
- package/dist/src/utils/platform-support.js +1 -1
- package/dist/src/utils/platform-support.js.map +1 -1
- package/dist/src/utils/plugin-config-impact.d.ts +3 -0
- package/dist/src/utils/plugin-config-impact.js +115 -273
- package/dist/src/utils/plugin-config-impact.js.map +1 -1
- package/dist/src/utils/plugin-config-references.d.ts +11 -2
- package/dist/src/utils/plugin-config-references.js +85 -90
- package/dist/src/utils/plugin-config-references.js.map +1 -1
- package/dist/src/utils/plugin-config-write.d.ts +58 -1
- package/dist/src/utils/plugin-config-write.js +756 -809
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +47 -46
- package/dist/src/utils/plugin-config.js +292 -833
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-scripts.d.ts +11 -6
- package/dist/src/utils/plugin-scripts.js +52 -35
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/runtime-config.js +5 -4
- package/dist/src/utils/runtime-config.js.map +1 -1
- package/dist/src/utils/runtime-skill-closure.d.ts +2 -2
- package/dist/src/utils/runtime-skill-closure.js.map +1 -1
- package/dist/src/utils/state-paths.d.ts +8 -3
- package/dist/src/utils/state-paths.js +53 -16
- package/dist/src/utils/state-paths.js.map +1 -1
- package/dist/src/utils/windows-npm-shim.d.ts +2 -0
- package/dist/src/utils/windows-npm-shim.js +5 -7
- package/dist/src/utils/windows-npm-shim.js.map +1 -1
- package/dist/vitest.config.js +1 -0
- package/dist/vitest.config.js.map +1 -1
- package/package.json +3 -3
- package/dist/src/commands/sync-command.d.ts +0 -40
- package/dist/src/commands/sync-command.js +0 -254
- package/dist/src/commands/sync-command.js.map +0 -1
- package/dist/src/portable/skills-cli.d.ts +0 -51
- package/dist/src/portable/skills-cli.js +0 -202
- package/dist/src/portable/skills-cli.js.map +0 -1
- package/dist/src/tui/project-inventory.d.ts +0 -68
- package/dist/src/tui/project-inventory.js +0 -203
- package/dist/src/tui/project-inventory.js.map +0 -1
- package/dist/src/utils/plugin-intent-state.d.ts +0 -49
- package/dist/src/utils/plugin-intent-state.js +0 -320
- package/dist/src/utils/plugin-intent-state.js.map +0 -1
|
@@ -16,10 +16,10 @@ import { supportsPlatform } from '../utils/platform-support.js';
|
|
|
16
16
|
import { analyzeCodexSurface } from '../utils/codex-surface-analysis.js';
|
|
17
17
|
import { buildGeneratedName } from '../generators/shared.js';
|
|
18
18
|
import { createCodexReconcilePlan, } from '../utils/codex-reconciler.js';
|
|
19
|
-
import { readCodexConfigFile } from '../utils/codex-config.js';
|
|
19
|
+
import { parseCodexConfig, readCodexConfigFile } from '../utils/codex-config.js';
|
|
20
20
|
import { isCanonicalCodexMarketplaceRegistration } from '../utils/codex-shared-native.js';
|
|
21
21
|
import { executeRebuildComponentCleanup, executeRebuildOperation, prepareRebuildOperation, } from './rebuild-operations.js';
|
|
22
|
-
import { assertNoClaudeUnboundNativeNameCollision, CodexActivationPostcheckError, createRebuildIntegration, executeCodexReconcileActivations, inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, hasPreparedStaticNativeCommandDrift, inspectNativeMarketplaceRegistrations,
|
|
22
|
+
import { assertNoClaudeUnboundNativeNameCollision, CodexActivationPostcheckError, createRebuildIntegration, executeCodexReconcileActivations, inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, hasPreparedStaticNativeCommandDrift, inspectNativeMarketplaceRegistrations, isNativeActivationOnlyTarget, postcheckCodexReconcileActivations, removeForceCleanupCodexRoleRegistration, } from './rebuild-integration.js';
|
|
23
23
|
import { assertSafeNamespacedMarketplacePluginRoot, getNamespacedMarketplaceName, readStrictNamespacedMarketplaceRoot, } from '../utils/local-marketplace.js';
|
|
24
24
|
import { formatPluginId, parsePluginId, planPluginSelectorSourceIds, preflightDesiredArtifactCollisions, withResolvedMultiSourceCatalog, } from '../utils/multi-source-catalog.js';
|
|
25
25
|
import { calculateCodexNativeRenderPayloadDigest, calculateCodexSharedNativePayloadDigest, } from '../utils/catalog-digests.js';
|
|
@@ -27,17 +27,17 @@ import { resolveCatalogOperationContext, } from '../utils/catalog-operation-cont
|
|
|
27
27
|
import { assertStrictSemVer } from '../utils/manifest.js';
|
|
28
28
|
import { assertCatalogSourceInventoryComplete, canonicalMarketplaceRegistrationNames, inventoryCatalogSourceReferences, } from '../utils/catalog-source-references.js';
|
|
29
29
|
import { sanitizeCatalogSourceErrorMessage } from '../utils/catalog-public-error.js';
|
|
30
|
-
import {
|
|
30
|
+
import { readSafeOperationError } from '../utils/safe-operation-diagnostic.js';
|
|
31
|
+
import { inspectPluginConfigResetTarget, readNamespacedPluginConfigStoreIdentity, resolvePluginConfigStorePath, resolveEffectivePluginConfig, } from '../utils/plugin-config.js';
|
|
31
32
|
import { resolveArtifactRenderConfig } from '../utils/artifact-renderer.js';
|
|
32
33
|
import { pluginConfigTargetRenderScopes } from '../utils/plugin-config-impact.js';
|
|
33
34
|
import { inspectOwnedComponents, parseOwnedTextHeader, readSkillOwnerMarker, SKILL_OWNER_MARKER, } from '../utils/ownership.js';
|
|
34
35
|
import { resolveActiveCatalogGeneration, resolveActiveCatalogPluginShallow } from '../utils/catalog-generation-resolver.js';
|
|
35
|
-
import { canonicalizePathThroughExistingAncestorSync, codexProjectConfigAliasesUserHome, getClaudeHome, getCodexHome,
|
|
36
|
+
import { canonicalizePathThroughExistingAncestorSync, codexProjectConfigAliasesUserHome, getClaudeHome, getCodexHome, resolveRepoRootSync, } from '../utils/state-paths.js';
|
|
36
37
|
import { resolvePluginMetaDependencyClosure } from '../utils/plugin-dependencies.js';
|
|
37
38
|
import { readCatalogSourcesConfigSnapshot } from '../utils/catalog-sources.js';
|
|
38
39
|
import { catalogGenerationErrorCode, isOfflineCleanupCatalogGenerationError, } from '../utils/catalog-generation-error.js';
|
|
39
|
-
import {
|
|
40
|
-
import { assertOperationPlanFingerprint, createBatchIntentCompatiblePlanFingerprint, createOperationPlanConfigDigest, createOperationPlan, } from './operation-plan.js';
|
|
40
|
+
import { assertOperationPlanFingerprint, createOperationPlanConfigDigest, createOperationPlan, } from './operation-plan.js';
|
|
41
41
|
import { validateCatalogSnapshotComplete, validateCatalogSnapshotPluginEntriesComplete, } from '../utils/catalog-snapshot.js';
|
|
42
42
|
import { AwCapabilityUnsupportedError, IMPLEMENTED_AW_CAPABILITIES, } from './aw-capabilities.js';
|
|
43
43
|
import { checkAwCapabilitySupport } from '../utils/manifest.js';
|
|
@@ -100,7 +100,7 @@ function assertRebuildCatalogSourceInventoryComplete(inventory, targetScope) {
|
|
|
100
100
|
|| !error.kind.startsWith('config')),
|
|
101
101
|
});
|
|
102
102
|
}
|
|
103
|
-
const MALFORMED_CONFIG_PRESERVED_WARNING = 'pluginConfigPreserved: 目标插件的无效配置文件已保留。可稍后运行 aw config reset 清理。';
|
|
103
|
+
const MALFORMED_CONFIG_PRESERVED_WARNING = 'pluginConfigPreserved: 目标插件的无效配置文件已保留。可稍后运行 aw plugin config reset <source/plugin> --context user 清理。';
|
|
104
104
|
const OBSOLETE_CONTRACTS_CLEANUP_WARNING = 'obsoleteContractsCleanupFailed: Obsolete installation contracts could not be removed.';
|
|
105
105
|
function omitSelectedPluginConfigErrors(inventory, targets) {
|
|
106
106
|
let omitted = false;
|
|
@@ -154,7 +154,7 @@ async function selectedProjectCodexSkillReferences(options) {
|
|
|
154
154
|
return references;
|
|
155
155
|
}
|
|
156
156
|
const cleanupProjectSkillsByInventory = new WeakMap();
|
|
157
|
-
function selectCodexActivationPlans(plans, targetScopes, preservedActivations) {
|
|
157
|
+
function selectCodexActivationPlans(plans, targetScopes, preservedActivations, originalUserActivations) {
|
|
158
158
|
return plans.flatMap((plan) => {
|
|
159
159
|
const includesScope = (pluginId, scope) => targetScopes.has(`${pluginId}\0${scope}`);
|
|
160
160
|
const pluginIds = new Set(plan.desiredTargets.flatMap((target) => ['user', 'project'].some((scope) => includesScope(target.pluginId, scope))
|
|
@@ -162,9 +162,21 @@ function selectCodexActivationPlans(plans, targetScopes, preservedActivations) {
|
|
|
162
162
|
: []));
|
|
163
163
|
if (pluginIds.size === 0)
|
|
164
164
|
return [];
|
|
165
|
-
const includesActivationAction = (action) => includesScope(action.pluginId, action.scope)
|
|
165
|
+
const includesActivationAction = (action) => includesScope(action.pluginId, action.scope);
|
|
166
166
|
const sharedNativeActions = plan.sharedNativeActions.filter((action) => pluginIds.has(action.pluginId));
|
|
167
167
|
const userActions = plan.activationActions.user.filter((action) => pluginIds.has(action.pluginId) && includesActivationAction(action));
|
|
168
|
+
for (const action of plan.activationActions.user) {
|
|
169
|
+
if (!originalUserActivations || includesScope(action.pluginId, 'user')
|
|
170
|
+
|| !includesScope(action.pluginId, 'project')
|
|
171
|
+
|| !sharedNativeActions.some((shared) => shared.pluginId === action.pluginId
|
|
172
|
+
&& (shared.action === 'install' || shared.action === 'replace' || shared.action === 'repair'))) {
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
const original = originalUserActivations.get(action.codexPluginId) === true;
|
|
176
|
+
if ((preservedActivations?.user.get(action.codexPluginId) === true) === original)
|
|
177
|
+
continue;
|
|
178
|
+
userActions.push({ ...action, action: original ? 'enable' : 'disable', desired: original });
|
|
179
|
+
}
|
|
168
180
|
const projectActions = plan.activationActions.project.filter((action) => pluginIds.has(action.pluginId) && includesActivationAction(action));
|
|
169
181
|
const desiredTargets = plan.desiredTargets.flatMap((target) => {
|
|
170
182
|
const scopes = target.scopes.filter((scope) => includesScope(target.pluginId, scope));
|
|
@@ -188,6 +200,7 @@ function selectCodexActivationPlans(plans, targetScopes, preservedActivations) {
|
|
|
188
200
|
return [{
|
|
189
201
|
...plan,
|
|
190
202
|
desiredTargets,
|
|
203
|
+
sharedNativeActions,
|
|
191
204
|
activationActions: { user: userActions, project: projectActions },
|
|
192
205
|
extensionWrites: plan.extensionWrites.filter((action) => includesScope(action.pluginId, action.scope)),
|
|
193
206
|
extensionRemovals: plan.extensionRemovals.filter((action) => includesScope(action.pluginId, action.scope)),
|
|
@@ -227,134 +240,20 @@ function failedCodexActivationTargetScopes(options) {
|
|
|
227
240
|
}
|
|
228
241
|
return failed.size > 0 ? failed : new Set(options.successfulTargetScopes);
|
|
229
242
|
}
|
|
230
|
-
function updateIntentOverrides(options) {
|
|
231
|
-
const plannedKeys = new Set(options.plan.targets.map((target) => `${target.pluginId}\0${target.platform}`));
|
|
232
|
-
return canonicalizePluginIntentState({
|
|
233
|
-
...options.state,
|
|
234
|
-
dependencyScopeOverrides: [
|
|
235
|
-
...options.state.dependencyScopeOverrides.filter((override) => !plannedKeys.has(`${override.pluginId}\0${override.platform}`)),
|
|
236
|
-
...options.plan.scopeOverrides,
|
|
237
|
-
],
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
243
|
function effectiveDependencyScopeOverrides(options) {
|
|
241
244
|
const nodeKeys = new Set(options.nodes.map((node) => `${node.pluginId}\0${node.platform}`));
|
|
242
245
|
const explicitMatches = (pluginId, platform) => options.explicit.some((override) => override.pluginId === pluginId
|
|
243
246
|
&& (override.platform === undefined || override.platform === platform));
|
|
244
247
|
return [
|
|
245
|
-
...options.state.dependencyScopeOverrides.filter((override) => nodeKeys.has(`${override.pluginId}\0${override.platform}`)
|
|
248
|
+
...(options.state.dependencyScopeOverrides ?? []).filter((override) => nodeKeys.has(`${override.pluginId}\0${override.platform}`)
|
|
246
249
|
&& !options.ignoredPersistedRootIds?.has(override.pluginId)
|
|
247
250
|
&& !explicitMatches(override.pluginId, override.platform)),
|
|
248
251
|
...options.explicit.filter((override) => options.nodes.some((node) => node.pluginId === override.pluginId
|
|
249
252
|
&& (override.platform === undefined || node.platform === override.platform))),
|
|
250
253
|
];
|
|
251
254
|
}
|
|
252
|
-
function
|
|
253
|
-
|
|
254
|
-
return state;
|
|
255
|
-
const byId = new Map(catalogEntries.map((entry) => [entry.pluginId, entry]));
|
|
256
|
-
const reachable = new Set();
|
|
257
|
-
const visiting = new Set();
|
|
258
|
-
const visited = new Set();
|
|
259
|
-
const visit = (pluginId, platform, root) => {
|
|
260
|
-
const entry = byId.get(pluginId);
|
|
261
|
-
if (!entry || visiting.has(pluginId))
|
|
262
|
-
return false;
|
|
263
|
-
const visitKey = `${pluginId}\0${platform}`;
|
|
264
|
-
if (visited.has(visitKey)) {
|
|
265
|
-
if (!root)
|
|
266
|
-
reachable.add(visitKey);
|
|
267
|
-
return true;
|
|
268
|
-
}
|
|
269
|
-
visiting.add(pluginId);
|
|
270
|
-
for (const dependencyPluginId of entry.dependencyPluginIds) {
|
|
271
|
-
if (!visit(dependencyPluginId, platform, false))
|
|
272
|
-
return false;
|
|
273
|
-
}
|
|
274
|
-
visiting.delete(pluginId);
|
|
275
|
-
visited.add(visitKey);
|
|
276
|
-
if (!root)
|
|
277
|
-
reachable.add(visitKey);
|
|
278
|
-
return true;
|
|
279
|
-
};
|
|
280
|
-
for (const root of state.roots) {
|
|
281
|
-
for (const platform of root.platforms) {
|
|
282
|
-
visiting.clear();
|
|
283
|
-
if (!visit(root.pluginId, platform, true))
|
|
284
|
-
return state;
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
return canonicalizePluginIntentState({
|
|
288
|
-
...state,
|
|
289
|
-
dependencyScopeOverrides: state.dependencyScopeOverrides.filter((override) => reachable.has(`${override.pluginId}\0${override.platform}`)),
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
function deriveDesiredIntentState(options) {
|
|
293
|
-
let next = options.state;
|
|
294
|
-
if (options.command === 'install') {
|
|
295
|
-
for (const root of options.selectedRoots)
|
|
296
|
-
next = mergePluginIntentRootPlatforms(next, root);
|
|
297
|
-
if (options.selectedRoots.length > 0) {
|
|
298
|
-
next = updateIntentOverrides({ state: next, plan: options.plan });
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
else if (options.command === 'uninstall' || options.command === 'cleanup') {
|
|
302
|
-
for (const root of options.selectedRoots)
|
|
303
|
-
next = removePluginIntentRootPlatforms(next, root);
|
|
304
|
-
if (options.command === 'uninstall') {
|
|
305
|
-
next = pruneUnreachableDependencyScopeOverrides(next, options.catalogEntries);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
return next;
|
|
309
|
-
}
|
|
310
|
-
function removeSelectedRootPlatformsFromOtherScope(options) {
|
|
311
|
-
let next = options.state;
|
|
312
|
-
for (const root of options.selectedRoots) {
|
|
313
|
-
const platforms = root.platforms.filter((platform) => platform !== 'codex' || !options.preserveCodexRootIds.has(root.pluginId));
|
|
314
|
-
if (platforms.length > 0) {
|
|
315
|
-
next = removePluginIntentRootPlatforms(next, { ...root, platforms });
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
return next;
|
|
319
|
-
}
|
|
320
|
-
async function writeDesiredIntentSuperset(options) {
|
|
321
|
-
const location = { scope: options.scope, cwd: options.cwd, env: options.env };
|
|
322
|
-
let next = deriveDesiredIntentState({
|
|
323
|
-
command: options.command,
|
|
324
|
-
state: await readPluginIntentState(location),
|
|
325
|
-
selectedRoots: options.selectedRoots,
|
|
326
|
-
plan: options.plan,
|
|
327
|
-
catalogEntries: options.catalogEntries,
|
|
328
|
-
});
|
|
329
|
-
const superset = next;
|
|
330
|
-
await writePluginIntentState(location, superset);
|
|
331
|
-
const writes = [{ location, superset }];
|
|
332
|
-
if (options.command === 'install' || options.codexPlan) {
|
|
333
|
-
const otherScope = options.scope === 'user' ? 'project' : 'user';
|
|
334
|
-
const otherLocation = { scope: otherScope, cwd: options.cwd, env: options.env };
|
|
335
|
-
let other = await readPluginIntentState(otherLocation);
|
|
336
|
-
if (options.command === 'install' && options.removeOtherScopeRoots !== false) {
|
|
337
|
-
const protectedOtherRootPlatforms = new Set(options.plan.targets.flatMap((target) => target.relation === 'requested'
|
|
338
|
-
&& (target.requestedScope ?? target.resolvedScope) === otherScope
|
|
339
|
-
? [`${target.pluginId}\0${target.platform}`]
|
|
340
|
-
: []));
|
|
341
|
-
other = removeSelectedRootPlatformsFromOtherScope({
|
|
342
|
-
state: other,
|
|
343
|
-
selectedRoots: options.selectedRoots.flatMap((root) => {
|
|
344
|
-
const platforms = root.platforms.filter((platform) => !protectedOtherRootPlatforms.has(`${root.pluginId}\0${platform}`));
|
|
345
|
-
return platforms.length > 0 ? [{ ...root, platforms }] : [];
|
|
346
|
-
}),
|
|
347
|
-
preserveCodexRootIds: options.preserveOtherCodexScopeRootIds,
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
const otherSuperset = other;
|
|
351
|
-
await writePluginIntentState(otherLocation, otherSuperset);
|
|
352
|
-
writes.push({
|
|
353
|
-
location: otherLocation,
|
|
354
|
-
superset: otherSuperset,
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
return writes;
|
|
255
|
+
function nativeDemandDigest(demand) {
|
|
256
|
+
return `sha256:${crypto.createHash('sha256').update(JSON.stringify(demand)).digest('hex')}`;
|
|
358
257
|
}
|
|
359
258
|
function createSyntheticPlugin(pluginName, env) {
|
|
360
259
|
const rootDir = path.join(resolveAwHome(env), 'plugins', pluginName);
|
|
@@ -416,18 +315,6 @@ function toTargetResult(result) {
|
|
|
416
315
|
} : {}),
|
|
417
316
|
};
|
|
418
317
|
}
|
|
419
|
-
function toRemovedCleanupTargetResult(result) {
|
|
420
|
-
const target = toTargetResult(result);
|
|
421
|
-
if (result.status === 'succeeded' || !result.target.pluginId)
|
|
422
|
-
return target;
|
|
423
|
-
return {
|
|
424
|
-
...target,
|
|
425
|
-
recoveryActions: [
|
|
426
|
-
`repair the reported ownership, native CLI, or config path evidence, then run aw cleanup ${result.target.pluginId} --platform both --scope user --yes`,
|
|
427
|
-
'use cleanup --force only for exclusively owned damaged output, then retry ordinary cleanup',
|
|
428
|
-
],
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
318
|
async function assertClaudeVersion(options) {
|
|
432
319
|
if (!options.platforms.includes('claude'))
|
|
433
320
|
return;
|
|
@@ -454,6 +341,9 @@ async function resolveRequestedNames(options) {
|
|
|
454
341
|
}
|
|
455
342
|
async function runSingleSourceRebuildCommand(options) {
|
|
456
343
|
const runtime = {
|
|
344
|
+
preparedArtifactRenderResults: options.runtime?.preparedArtifactRenderResults,
|
|
345
|
+
signal: options.runtime?.signal,
|
|
346
|
+
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
457
347
|
env: options.runtime?.env ?? process.env,
|
|
458
348
|
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
459
349
|
reporter: options.runtime?.reporter ?? createNoopReporter(),
|
|
@@ -464,6 +354,8 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
464
354
|
codexObservationSession: options.runtime?.codexObservationSession,
|
|
465
355
|
preApplyExecutionCache: options.runtime?.preApplyExecutionCache,
|
|
466
356
|
managedCommandProducerCache: options.runtime?.managedCommandProducerCache ?? new Map(),
|
|
357
|
+
preserveLegacyNativeSkills: options.runtime?.preserveLegacyNativeSkills,
|
|
358
|
+
nativeActivationOnlyTargets: options.runtime?.nativeActivationOnlyTargets,
|
|
467
359
|
commandResults: options.runtime?.commandResults ?? [],
|
|
468
360
|
};
|
|
469
361
|
const env = runtime.env;
|
|
@@ -663,6 +555,35 @@ function toCatalogResolution(source) {
|
|
|
663
555
|
channel: source.manifest.channel,
|
|
664
556
|
};
|
|
665
557
|
}
|
|
558
|
+
function preparedNativeFootprints(targets) {
|
|
559
|
+
return targets.flatMap((target) => (target.desiredOwnedComponents ?? target.ownedComponents).flatMap((component) => {
|
|
560
|
+
let outputPath;
|
|
561
|
+
if ('path' in component)
|
|
562
|
+
outputPath = component.path;
|
|
563
|
+
else if ('locator' in component) {
|
|
564
|
+
const locator = component.locator;
|
|
565
|
+
if ('configPath' in locator)
|
|
566
|
+
outputPath = locator.configPath;
|
|
567
|
+
else if ('settingsPath' in locator)
|
|
568
|
+
outputPath = locator.settingsPath;
|
|
569
|
+
else if ('hooksPath' in locator)
|
|
570
|
+
outputPath = locator.hooksPath;
|
|
571
|
+
else if ('marketplaceRoot' in locator)
|
|
572
|
+
outputPath = locator.marketplaceRoot;
|
|
573
|
+
}
|
|
574
|
+
return outputPath ? [{
|
|
575
|
+
path: path.resolve(outputPath),
|
|
576
|
+
pluginId: target.identity.pluginId ?? target.identity.pluginName,
|
|
577
|
+
platform: target.identity.platform,
|
|
578
|
+
scope: target.identity.scope,
|
|
579
|
+
shared: component.kind === 'shared-config' || component.kind === 'managed-block',
|
|
580
|
+
...(component.kind === 'shared-config'
|
|
581
|
+
&& (component.locator.kind === 'codex-marketplace'
|
|
582
|
+
|| component.locator.kind === 'claude-marketplace')
|
|
583
|
+
? { sharedMarketplace: true } : {}),
|
|
584
|
+
}] : [];
|
|
585
|
+
}));
|
|
586
|
+
}
|
|
666
587
|
function mergeRebuildCommandResults(results) {
|
|
667
588
|
const rebuildResults = results.flatMap((result) => result.rebuildResults);
|
|
668
589
|
const platforms = [...new Set(results.flatMap((result) => result.platforms))];
|
|
@@ -674,9 +595,12 @@ function mergeRebuildCommandResults(results) {
|
|
|
674
595
|
targetResults: results.flatMap((result) => result.targetResults),
|
|
675
596
|
...(results.some((result) => result.commandResults?.length) ? { commandResults: results.flatMap((result) => result.commandResults ?? []) } : {}),
|
|
676
597
|
overallState: rebuildResults.every((result) => result.status === 'succeeded')
|
|
677
|
-
? 'succeeded'
|
|
598
|
+
? results.some((result) => result.overallState === 'partial') ? 'partial' : 'succeeded'
|
|
678
599
|
: rebuildResults.some((result) => result.status === 'succeeded') ? 'partial' : 'failed',
|
|
679
600
|
receiptTargets: results.flatMap((result) => result.receiptTargets),
|
|
601
|
+
...(results.some((result) => result.nativeFootprints !== undefined)
|
|
602
|
+
? { nativeFootprints: results.flatMap((result) => result.nativeFootprints ?? []) }
|
|
603
|
+
: {}),
|
|
680
604
|
...(results.find((result) => result.dependencyPlan)?.dependencyPlan
|
|
681
605
|
? { dependencyPlan: results.find((result) => result.dependencyPlan).dependencyPlan }
|
|
682
606
|
: {}),
|
|
@@ -689,9 +613,6 @@ function mergeRebuildCommandResults(results) {
|
|
|
689
613
|
...(results.some((result) => result.offlineCleanupPlans !== undefined)
|
|
690
614
|
? { offlineCleanupPlans: results.flatMap((result) => result.offlineCleanupPlans ?? []) }
|
|
691
615
|
: {}),
|
|
692
|
-
...(results.some((result) => result.removedPluginCleanupIds !== undefined)
|
|
693
|
-
? { removedPluginCleanupIds: [...new Set(results.flatMap((result) => result.removedPluginCleanupIds ?? []))] }
|
|
694
|
-
: {}),
|
|
695
616
|
};
|
|
696
617
|
}
|
|
697
618
|
function reconcileOverallState(targetResults, plan, rebuildResults = []) {
|
|
@@ -716,30 +637,6 @@ function reconcileOverallState(targetResults, plan, rebuildResults = []) {
|
|
|
716
637
|
return completedRequested || completedMutation || observedMutation ? 'partial' : 'failed';
|
|
717
638
|
}
|
|
718
639
|
function createRebuildOperationPlan(options) {
|
|
719
|
-
const intentChanges = ['user', 'project'].flatMap((scope) => {
|
|
720
|
-
const selectedRoots = [...new Map(options.dependencyPlan.targets.flatMap((target) => target.relation === 'requested'
|
|
721
|
-
&& (target.requestedScope ?? target.resolvedScope) === scope
|
|
722
|
-
? [[target.pluginId, {
|
|
723
|
-
pluginId: target.pluginId,
|
|
724
|
-
platforms: options.dependencyPlan.targets.flatMap((candidate) => candidate.relation === 'requested'
|
|
725
|
-
&& candidate.pluginId === target.pluginId
|
|
726
|
-
&& (candidate.requestedScope ?? candidate.resolvedScope) === scope
|
|
727
|
-
? [candidate.platform]
|
|
728
|
-
: []),
|
|
729
|
-
}]]
|
|
730
|
-
: [])).values()];
|
|
731
|
-
const intentBefore = options.intentBeforeByScope[scope];
|
|
732
|
-
const intentAfter = deriveDesiredIntentState({
|
|
733
|
-
command: options.command,
|
|
734
|
-
state: intentBefore,
|
|
735
|
-
selectedRoots,
|
|
736
|
-
plan: options.dependencyPlan,
|
|
737
|
-
catalogEntries: options.catalogEntries,
|
|
738
|
-
});
|
|
739
|
-
const beforeDigest = calculatePluginIntentDigest(intentBefore);
|
|
740
|
-
const afterDigest = calculatePluginIntentDigest(intentAfter);
|
|
741
|
-
return beforeDigest === afterDigest ? [] : [{ scope, beforeDigest, afterDigest }];
|
|
742
|
-
});
|
|
743
640
|
const actions = [
|
|
744
641
|
...(options.targetActions ?? []),
|
|
745
642
|
...options.codexPlans.flatMap((plan) => [
|
|
@@ -771,7 +668,7 @@ function createRebuildOperationPlan(options) {
|
|
|
771
668
|
]),
|
|
772
669
|
];
|
|
773
670
|
return createOperationPlan({
|
|
774
|
-
intentChanges,
|
|
671
|
+
intentChanges: [],
|
|
775
672
|
actions,
|
|
776
673
|
changes: options.dependencyPlan.targets.map((target) => [
|
|
777
674
|
target.pluginId,
|
|
@@ -785,10 +682,7 @@ function createRebuildOperationPlan(options) {
|
|
|
785
682
|
sourceId: source.sourceId,
|
|
786
683
|
digest: source.manifestDigest,
|
|
787
684
|
})),
|
|
788
|
-
intentDigests: [
|
|
789
|
-
scope,
|
|
790
|
-
digest: calculatePluginIntentDigest(options.intentBeforeByScope[scope]),
|
|
791
|
-
})),
|
|
685
|
+
intentDigests: [{ scope: options.scope, digest: nativeDemandDigest(options.requirements) }],
|
|
792
686
|
configDigests: options.configDigests,
|
|
793
687
|
targetOwnerFingerprints: options.dependencyPlan.targets.map((target) => ({
|
|
794
688
|
pluginId: target.pluginId,
|
|
@@ -878,18 +772,6 @@ function cleanupIntentTargets(options) {
|
|
|
878
772
|
}];
|
|
879
773
|
}));
|
|
880
774
|
}
|
|
881
|
-
function cleanupSelectedRoots(targets) {
|
|
882
|
-
const platformsByPluginId = new Map();
|
|
883
|
-
for (const target of targets) {
|
|
884
|
-
const platforms = platformsByPluginId.get(target.pluginId) ?? new Set();
|
|
885
|
-
platforms.add(target.platform);
|
|
886
|
-
platformsByPluginId.set(target.pluginId, platforms);
|
|
887
|
-
}
|
|
888
|
-
return [...platformsByPluginId].map(([pluginId, platforms]) => ({
|
|
889
|
-
pluginId,
|
|
890
|
-
platforms: [...platforms],
|
|
891
|
-
}));
|
|
892
|
-
}
|
|
893
775
|
function cleanupIntentResult(target) {
|
|
894
776
|
return {
|
|
895
777
|
status: 'succeeded',
|
|
@@ -1113,6 +995,7 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
1113
995
|
...(codexManager ? { codexManager } : {}),
|
|
1114
996
|
reporter: createNoopReporter(),
|
|
1115
997
|
debugLogger: createNoopDebugLogger(),
|
|
998
|
+
preserveLegacyNativeSkills: options.preserveLegacyNativeSkills,
|
|
1116
999
|
};
|
|
1117
1000
|
const integration = createRebuildIntegration({ context });
|
|
1118
1001
|
for (const target of options.targets) {
|
|
@@ -1125,14 +1008,11 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
1125
1008
|
&& candidate.sourceIdentity === target.sourceIdentity
|
|
1126
1009
|
&& candidate.platform === target.platform
|
|
1127
1010
|
&& candidate.scope === target.scope);
|
|
1128
|
-
const activationAction = target.platform === 'codex'
|
|
1011
|
+
const activationAction = target.platform === 'codex'
|
|
1129
1012
|
? evidence?.plan.actions.find((action) => action.action === 'removeNativeRegistration'
|
|
1130
1013
|
&& action.activationScope === target.scope)
|
|
1131
1014
|
: undefined;
|
|
1132
|
-
|
|
1133
|
-
if (activationAction && target.scope === 'user') {
|
|
1134
|
-
activationDisposition = 'disable';
|
|
1135
|
-
}
|
|
1015
|
+
const activationDisposition = 'disable';
|
|
1136
1016
|
const plugin = createSyntheticPlugin(target.pluginName, options.env);
|
|
1137
1017
|
plugin.sourceId = target.sourceId;
|
|
1138
1018
|
plugin.sourceIdentity = target.sourceIdentity;
|
|
@@ -1156,8 +1036,7 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
1156
1036
|
catalogVersion: '0.0.0',
|
|
1157
1037
|
channel: 'beta',
|
|
1158
1038
|
},
|
|
1159
|
-
includeNativeCleanupCandidate:
|
|
1160
|
-
...(options.removedPluginWhole ? { removedPluginWhole: true } : {}),
|
|
1039
|
+
includeNativeCleanupCandidate: false,
|
|
1161
1040
|
...(activationAction
|
|
1162
1041
|
? {
|
|
1163
1042
|
codexActivationCleanup: [{
|
|
@@ -1168,6 +1047,15 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
1168
1047
|
}
|
|
1169
1048
|
: {}),
|
|
1170
1049
|
});
|
|
1050
|
+
const sharedNativeComponent = (component) => component.kind === 'native-plugin'
|
|
1051
|
+
|| (component.kind === 'shared-config'
|
|
1052
|
+
&& component.identity.artifactKey.startsWith('marketplace-'));
|
|
1053
|
+
desired.requiresNative = false;
|
|
1054
|
+
desired.writeNativeRequired = false;
|
|
1055
|
+
desired.ownedComponents = desired.ownedComponents.filter((component) => !sharedNativeComponent(component));
|
|
1056
|
+
desired.desiredOwnedComponents = desired.desiredOwnedComponents?.filter((component) => !sharedNativeComponent(component));
|
|
1057
|
+
desired.optionalOwnedComponents = desired.optionalOwnedComponents?.filter((component) => !sharedNativeComponent(component));
|
|
1058
|
+
desired.operationActions = desired.operationActions?.filter((action) => action.kind !== 'removeNativeRegistration');
|
|
1171
1059
|
const unplannedCandidates = evidence
|
|
1172
1060
|
? desired.ownedComponents.filter((component) => !cleanupComponentAuthorized(component, evidence))
|
|
1173
1061
|
: [];
|
|
@@ -1183,19 +1071,17 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
1183
1071
|
desired.desiredOwnedComponents = desired.desiredOwnedComponents?.filter(authorized);
|
|
1184
1072
|
desired.optionalOwnedComponents = desired.optionalOwnedComponents?.filter(authorized);
|
|
1185
1073
|
desired.artifacts = desired.artifacts.filter((artifact) => cleanupPathAuthorized(artifact.path, evidence));
|
|
1186
|
-
|
|
1187
|
-
desired.
|
|
1188
|
-
desired.writeNativeRequired &&= nativeAuthorized;
|
|
1074
|
+
desired.requiresNative = false;
|
|
1075
|
+
desired.writeNativeRequired = false;
|
|
1189
1076
|
desired.operationActions = desired.operationActions?.filter((action) => {
|
|
1190
1077
|
if (action.kind === 'removeOwnedArtifact') {
|
|
1191
1078
|
return cleanupPathAuthorized(action.path, evidence);
|
|
1192
1079
|
}
|
|
1193
|
-
if (action.kind === '
|
|
1194
|
-
return
|
|
1195
|
-
&&
|
|
1080
|
+
if (action.kind === 'setActivation') {
|
|
1081
|
+
return Boolean(activationAction
|
|
1082
|
+
&& action.scope === target.scope
|
|
1083
|
+
&& action.registration === activationAction.target);
|
|
1196
1084
|
}
|
|
1197
|
-
if (action.kind === 'setActivation')
|
|
1198
|
-
return nativeAuthorized;
|
|
1199
1085
|
if (action.kind === 'retainManagedCommandPackage')
|
|
1200
1086
|
return true;
|
|
1201
1087
|
return false;
|
|
@@ -1296,45 +1182,42 @@ async function previewOfflineOwnedComponents(options) {
|
|
|
1296
1182
|
await options.onPreviewStage?.('dependencyPlan');
|
|
1297
1183
|
return preview;
|
|
1298
1184
|
}
|
|
1299
|
-
function createOfflineCleanupOperationPlan(evidence,
|
|
1300
|
-
const beforeDigest = intent ? calculatePluginIntentDigest(intent.before) : undefined;
|
|
1301
|
-
const afterDigest = intent ? calculatePluginIntentDigest(intent.after) : undefined;
|
|
1302
|
-
const removesIntent = (target) => intent !== undefined
|
|
1303
|
-
&& intent.before.roots.some((root) => root.pluginId === target.pluginId && root.platforms.includes(target.platform))
|
|
1304
|
-
&& !intent.after.roots.some((root) => root.pluginId === target.pluginId && root.platforms.includes(target.platform));
|
|
1185
|
+
function createOfflineCleanupOperationPlan(evidence, requirements, warnings = [], retainedPackages = []) {
|
|
1305
1186
|
return createOperationPlan({
|
|
1306
|
-
intentChanges:
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
:
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1187
|
+
intentChanges: [],
|
|
1188
|
+
actions: [...retainedPackages, ...evidence.flatMap((target) => target.plan.actions.flatMap((action) => action.action === 'removeOwnedOutput'
|
|
1189
|
+
? [{
|
|
1190
|
+
kind: 'removeOwnedArtifact',
|
|
1191
|
+
pluginId: target.pluginId,
|
|
1192
|
+
platform: target.platform,
|
|
1193
|
+
scope: target.scope,
|
|
1194
|
+
path: action.kind === 'namespacedOwner' && path.basename(action.target) === SKILL_OWNER_MARKER
|
|
1195
|
+
? path.dirname(action.target) : action.target,
|
|
1196
|
+
ownerFingerprint: target.targetFingerprint,
|
|
1197
|
+
}]
|
|
1198
|
+
: action.activationScope === target.scope
|
|
1199
|
+
? [{
|
|
1200
|
+
kind: 'setActivation',
|
|
1201
|
+
pluginId: target.pluginId,
|
|
1202
|
+
platform: 'codex',
|
|
1203
|
+
scope: target.scope,
|
|
1204
|
+
enabled: false,
|
|
1205
|
+
}]
|
|
1206
|
+
: []))],
|
|
1207
|
+
changes: evidence.flatMap((target) => target.plan.actions.flatMap((action) => action.action === 'removeOwnedOutput'
|
|
1208
|
+
? [`${target.pluginId}:${target.platform}:${target.scope}:${action.action}:${action.target}`]
|
|
1209
|
+
: action.activationScope === target.scope
|
|
1210
|
+
? [`${target.pluginId}:${target.platform}:${target.scope}:setActivation:false:${action.target}`]
|
|
1211
|
+
: [])),
|
|
1331
1212
|
warnings: [...warnings],
|
|
1332
1213
|
evidence: {
|
|
1333
1214
|
catalogDigests: evidence.map((target) => ({
|
|
1334
1215
|
sourceId: target.sourceId,
|
|
1335
1216
|
digest: target.sourceIdentity,
|
|
1336
1217
|
})),
|
|
1337
|
-
intentDigests:
|
|
1218
|
+
intentDigests: requirements
|
|
1219
|
+
? [{ scope: requirements.scope, digest: nativeDemandDigest(requirements.view) }]
|
|
1220
|
+
: [],
|
|
1338
1221
|
configDigests: [],
|
|
1339
1222
|
targetOwnerFingerprints: evidence.map((target) => ({
|
|
1340
1223
|
pluginId: target.pluginId,
|
|
@@ -1596,24 +1479,14 @@ async function removedProjectionTreeFingerprint(root) {
|
|
|
1596
1479
|
};
|
|
1597
1480
|
return removedCleanupDigest(await visit(root));
|
|
1598
1481
|
}
|
|
1599
|
-
function
|
|
1600
|
-
return canonicalizePluginIntentState({
|
|
1601
|
-
...state,
|
|
1602
|
-
roots: state.roots.filter((root) => !pluginIds.has(root.pluginId)),
|
|
1603
|
-
dependencyScopeOverrides: state.dependencyScopeOverrides.filter((override) => !pluginIds.has(override.pluginId)),
|
|
1604
|
-
});
|
|
1605
|
-
}
|
|
1606
|
-
async function inspectRemovedPluginConfig(options) {
|
|
1482
|
+
export async function inspectRemovedPluginConfig(options) {
|
|
1607
1483
|
const inspection = await inspectPluginConfigResetTarget(options);
|
|
1608
1484
|
if (inspection.kind !== 'regularFile')
|
|
1609
1485
|
return inspection;
|
|
1610
1486
|
try {
|
|
1611
1487
|
const identity = await readNamespacedPluginConfigStoreIdentity(options);
|
|
1612
|
-
if (identity && (
|
|
1613
|
-
|
|
1614
|
-
|| identity.binding.sourceIdentity !== options.sourceIdentity
|
|
1615
|
-
: identity.binding.kind !== 'catalog'
|
|
1616
|
-
|| identity.binding.logicalIdentity !== options.logicalIdentity)) {
|
|
1488
|
+
if (identity && (identity.binding.kind !== 'source'
|
|
1489
|
+
|| identity.binding.sourceIdentity !== options.sourceIdentity)) {
|
|
1617
1490
|
return { ...inspection, conflict: 'removedPluginConfigIdentityConflict: saved config binding differs from the Active source.' };
|
|
1618
1491
|
}
|
|
1619
1492
|
}
|
|
@@ -1638,7 +1511,7 @@ async function inspectRemovedPluginConfig(options) {
|
|
|
1638
1511
|
}
|
|
1639
1512
|
return inspection;
|
|
1640
1513
|
}
|
|
1641
|
-
async function inspectRemovedPluginCleanup(options) {
|
|
1514
|
+
export async function inspectRemovedPluginCleanup(options) {
|
|
1642
1515
|
const parsed = parsePluginId(options.pluginId);
|
|
1643
1516
|
if (!parsed.sourceId)
|
|
1644
1517
|
return null;
|
|
@@ -1705,7 +1578,7 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1705
1578
|
const activationScopes = [];
|
|
1706
1579
|
if (marketplaceName) {
|
|
1707
1580
|
const inspectedPaths = new Set();
|
|
1708
|
-
for (const scope of [
|
|
1581
|
+
for (const scope of [options.scope]) {
|
|
1709
1582
|
const configPath = resolveCodexPaths(options.cwd, scope, options.env).configTomlPath;
|
|
1710
1583
|
if (inspectedPaths.has(path.resolve(configPath)))
|
|
1711
1584
|
continue;
|
|
@@ -1737,7 +1610,7 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1737
1610
|
env: options.env,
|
|
1738
1611
|
nativeCliRunner: options.nativeCliRunner,
|
|
1739
1612
|
manager: options.codexManager,
|
|
1740
|
-
scope:
|
|
1613
|
+
scope: options.scope,
|
|
1741
1614
|
});
|
|
1742
1615
|
nativeState = observed.observation.state === 'observed'
|
|
1743
1616
|
? observed.observation.value === 'installed' ? 'installed' : 'absent'
|
|
@@ -1758,7 +1631,7 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1758
1631
|
blockers.push('removedPluginNativeOwnershipUnavailable: native evidence remains without a valid AW marketplace root.');
|
|
1759
1632
|
}
|
|
1760
1633
|
const configTargets = [];
|
|
1761
|
-
for (const scope of [
|
|
1634
|
+
for (const scope of [options.scope]) {
|
|
1762
1635
|
try {
|
|
1763
1636
|
const inspected = await inspectRemovedPluginConfig({
|
|
1764
1637
|
sourceId: parsed.sourceId,
|
|
@@ -1817,7 +1690,7 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1817
1690
|
});
|
|
1818
1691
|
const evidence = [];
|
|
1819
1692
|
for (const platform of ['codex', 'claude']) {
|
|
1820
|
-
for (const scope of [
|
|
1693
|
+
for (const scope of [options.scope]) {
|
|
1821
1694
|
const base = offlineCleanupEvidenceFromInventory({
|
|
1822
1695
|
reason: 'bundleUnavailable',
|
|
1823
1696
|
pluginId,
|
|
@@ -1835,27 +1708,11 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1835
1708
|
platform,
|
|
1836
1709
|
scope,
|
|
1837
1710
|
});
|
|
1838
|
-
const actions = base.plan.actions.
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
&& registration?.claude === 'canonical'
|
|
1844
|
-
&& marketplaceName && action.kind === 'namespacedMarketplace'
|
|
1845
|
-
? [{ ...action, target: `${parsed.pluginName}@${marketplaceName}` }]
|
|
1846
|
-
: [];
|
|
1847
|
-
}
|
|
1848
|
-
return [action];
|
|
1849
|
-
});
|
|
1850
|
-
if (platform === 'codex' && scope === 'user' && nativeState === 'installed'
|
|
1851
|
-
&& marketplaceName && nativeOwnershipVerified && projectionPathSafe) {
|
|
1852
|
-
actions.push({
|
|
1853
|
-
action: 'removeNativeRegistration',
|
|
1854
|
-
kind: 'namespacedMarketplace',
|
|
1855
|
-
target: `${parsed.pluginName}@${marketplaceName}`,
|
|
1856
|
-
marketplaceName,
|
|
1857
|
-
});
|
|
1858
|
-
}
|
|
1711
|
+
const actions = base.plan.actions.filter((action) => action.action !== 'removeNativeRegistration'
|
|
1712
|
+
|| (platform === 'codex'
|
|
1713
|
+
&& nativeOwnershipVerified
|
|
1714
|
+
&& projectionPathSafe
|
|
1715
|
+
&& action.activationScope === scope));
|
|
1859
1716
|
const safeActions = ownershipConflict ? [] : actions;
|
|
1860
1717
|
const enrichedActions = await Promise.all(safeActions.map(async (action) => action.action === 'removeOwnedOutput'
|
|
1861
1718
|
? { ...action, pathEvidence: await removedProjectionTreeFingerprint(action.target.split('#', 1)[0]) }
|
|
@@ -1887,441 +1744,131 @@ async function inspectRemovedPluginCleanup(options) {
|
|
|
1887
1744
|
blockers,
|
|
1888
1745
|
};
|
|
1889
1746
|
}
|
|
1890
|
-
function
|
|
1891
|
-
const
|
|
1892
|
-
const
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
if (calculatePluginIntentDigest(before) !== calculatePluginIntentDigest(after)
|
|
1898
|
-
&& (before.roots.some((root) => root.pluginId === target.pluginId)
|
|
1899
|
-
|| before.dependencyScopeOverrides.some((override) => override.pluginId === target.pluginId))) {
|
|
1900
|
-
changes.push(`${target.pluginId}:${scope}:removeIntentAndOverrides`);
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
for (const evidence of target.evidence) {
|
|
1904
|
-
for (const action of evidence.plan.actions) {
|
|
1905
|
-
actions.push(action.action === 'removeNativeRegistration'
|
|
1906
|
-
? {
|
|
1907
|
-
kind: 'removeNativeRegistration',
|
|
1908
|
-
pluginId: target.pluginId,
|
|
1909
|
-
platform: evidence.platform,
|
|
1910
|
-
scope: evidence.scope,
|
|
1911
|
-
registration: action.target,
|
|
1912
|
-
}
|
|
1913
|
-
: {
|
|
1914
|
-
kind: 'removeOwnedArtifact',
|
|
1915
|
-
pluginId: target.pluginId,
|
|
1916
|
-
platform: evidence.platform,
|
|
1917
|
-
scope: evidence.scope,
|
|
1918
|
-
path: action.target,
|
|
1919
|
-
ownerFingerprint: evidence.targetFingerprint,
|
|
1920
|
-
});
|
|
1921
|
-
changes.push(`${target.pluginId}:${evidence.platform}:${evidence.scope}:${action.action}:${action.target}`);
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
|
-
for (const config of target.configTargets.filter((entry) => entry.kind !== 'absent')) {
|
|
1925
|
-
if (config.kind === 'directory' || config.kind === 'special'
|
|
1926
|
-
|| target.blockers.some((blocker) => blocker.startsWith(`${config.scope}: removedPluginConfigIdentityConflict`))) {
|
|
1927
|
-
continue;
|
|
1928
|
-
}
|
|
1929
|
-
actions.push({
|
|
1930
|
-
kind: 'removePluginConfig',
|
|
1931
|
-
pluginId: target.pluginId,
|
|
1932
|
-
platform: 'codex',
|
|
1933
|
-
scope: config.scope,
|
|
1934
|
-
path: resolvePluginConfigStorePath({
|
|
1935
|
-
sourceId: target.sourceId,
|
|
1936
|
-
pluginName: target.pluginName,
|
|
1937
|
-
scope: config.scope,
|
|
1938
|
-
cwd: options.cwd,
|
|
1939
|
-
env: options.env,
|
|
1940
|
-
}),
|
|
1941
|
-
fingerprint: config.fingerprint,
|
|
1942
|
-
});
|
|
1943
|
-
changes.push(`${target.pluginId}:${config.scope}:removeSavedConfig:${config.kind}:${config.fingerprint}`);
|
|
1944
|
-
}
|
|
1945
|
-
for (const activation of target.activationScopes) {
|
|
1946
|
-
changes.push(`${target.pluginId}:codex:${activation.scope}:activationEvidence:${activation.enabled}`);
|
|
1947
|
-
if (!target.nativeOwnershipVerified || target.nativeState === 'unknown')
|
|
1948
|
-
continue;
|
|
1949
|
-
actions.push({
|
|
1950
|
-
kind: 'removeActivation',
|
|
1951
|
-
pluginId: target.pluginId,
|
|
1952
|
-
platform: 'codex',
|
|
1953
|
-
scope: activation.scope,
|
|
1954
|
-
registration: `${target.pluginName}@${target.marketplaceName}`,
|
|
1955
|
-
});
|
|
1956
|
-
changes.push(`${target.pluginId}:codex:${activation.scope}:removeActivation`);
|
|
1957
|
-
}
|
|
1958
|
-
changes.push(`${target.pluginId}:projectionEvidence:${target.projectionFingerprint}`);
|
|
1959
|
-
if (target.projectionPresent && target.projectionOwnershipVerified
|
|
1960
|
-
&& target.nativeState !== 'unknown'
|
|
1961
|
-
&& (target.nativeOwnershipVerified || target.activationScopes.length === 0)) {
|
|
1962
|
-
actions.push({
|
|
1963
|
-
kind: 'removeMarketplaceProjection',
|
|
1964
|
-
pluginId: target.pluginId,
|
|
1965
|
-
platform: 'codex',
|
|
1966
|
-
scope: 'user',
|
|
1967
|
-
marketplaceRoot: target.marketplaceRoot,
|
|
1968
|
-
});
|
|
1969
|
-
changes.push(`${target.pluginId}:removeMarketplaceProjection`);
|
|
1970
|
-
}
|
|
1971
|
-
changes.push(`${target.pluginId}:nativeObservation:${target.nativeState}:${target.nativeObservationFingerprint}:${target.marketplaceEvidenceFingerprint}`);
|
|
1972
|
-
}
|
|
1973
|
-
const warnings = options.targets.flatMap((target) => [
|
|
1974
|
-
`removedPluginCleanupScope: ${target.pluginId} 清理范围为 Codex 和 Claude 的用户及当前项目,包含两处保存设置。`,
|
|
1975
|
-
`removedPluginCleanupSharedNativeImpact: ${target.pluginId} 的 Codex 共享原生包卸载后,其他项目可能无法继续使用;其他项目的本地记录不会修改。`,
|
|
1976
|
-
...target.blockers,
|
|
1977
|
-
]);
|
|
1978
|
-
return createOperationPlan({
|
|
1979
|
-
intentChanges: ['user', 'project'].flatMap((scope) => {
|
|
1980
|
-
const beforeDigest = calculatePluginIntentDigest(options.intents[scope].before);
|
|
1981
|
-
const afterDigest = calculatePluginIntentDigest(options.intents[scope].after);
|
|
1982
|
-
return beforeDigest === afterDigest ? [] : [{ scope, beforeDigest, afterDigest }];
|
|
1983
|
-
}),
|
|
1984
|
-
actions,
|
|
1985
|
-
changes,
|
|
1986
|
-
warnings,
|
|
1987
|
-
evidence: {
|
|
1988
|
-
catalogDigests: options.targets.map((target) => ({
|
|
1989
|
-
sourceId: target.sourceId,
|
|
1990
|
-
digest: removedCleanupDigest({
|
|
1991
|
-
sourceIdentity: target.sourceIdentity,
|
|
1992
|
-
logicalIdentity: target.logicalIdentity,
|
|
1993
|
-
snapshotDigest: target.snapshotDigest,
|
|
1994
|
-
}),
|
|
1995
|
-
})),
|
|
1996
|
-
intentDigests: ['user', 'project'].map((scope) => ({
|
|
1997
|
-
scope,
|
|
1998
|
-
digest: calculatePluginIntentDigest(options.intents[scope].before),
|
|
1999
|
-
})),
|
|
2000
|
-
configDigests: options.targets.flatMap((target) => target.configTargets.map((config) => ({
|
|
2001
|
-
pluginId: target.pluginId,
|
|
2002
|
-
scope: config.scope,
|
|
2003
|
-
digest: config.fingerprint,
|
|
2004
|
-
}))),
|
|
2005
|
-
targetOwnerFingerprints: options.targets.flatMap((target) => target.evidence.map((evidence) => ({
|
|
2006
|
-
pluginId: target.pluginId,
|
|
2007
|
-
platform: evidence.platform,
|
|
2008
|
-
scope: evidence.scope,
|
|
2009
|
-
fingerprint: evidence.targetFingerprint,
|
|
2010
|
-
}))),
|
|
2011
|
-
},
|
|
2012
|
-
});
|
|
2013
|
-
}
|
|
2014
|
-
function combineCleanupOperationPlans(plans) {
|
|
2015
|
-
return createOperationPlan({
|
|
2016
|
-
intentChanges: plans.flatMap((plan) => plan.intentChanges),
|
|
2017
|
-
actions: plans.flatMap((plan) => plan.actions),
|
|
2018
|
-
changes: plans.flatMap((plan) => plan.changes),
|
|
2019
|
-
warnings: plans.flatMap((plan) => plan.warnings),
|
|
2020
|
-
evidence: {
|
|
2021
|
-
catalogDigests: plans.flatMap((plan) => plan.evidence.catalogDigests),
|
|
2022
|
-
intentDigests: plans.flatMap((plan) => plan.evidence.intentDigests),
|
|
2023
|
-
configDigests: plans.flatMap((plan) => plan.evidence.configDigests),
|
|
2024
|
-
targetOwnerFingerprints: plans.flatMap((plan) => plan.evidence.targetOwnerFingerprints),
|
|
2025
|
-
},
|
|
1747
|
+
export async function executeRemovedPluginOutputCleanup(options) {
|
|
1748
|
+
const selected = options.selectedTargets.filter((target) => target.pluginId === options.target.pluginId && target.scope === options.context.scope);
|
|
1749
|
+
const retainedPackages = await discoverRetainedManagedCommandPackages({
|
|
1750
|
+
selectors: [{ sourceId: options.target.sourceId, pluginName: options.target.pluginName }],
|
|
1751
|
+
scope: options.context.scope,
|
|
1752
|
+
cwd: options.context.executionCwd,
|
|
1753
|
+
env: options.context.env,
|
|
2026
1754
|
});
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
}
|
|
2041
|
-
let hasConfig = false;
|
|
2042
|
-
for (const scope of ['user', 'project']) {
|
|
2043
|
-
try {
|
|
2044
|
-
hasConfig ||= (await inspectPluginConfigResetTarget({
|
|
2045
|
-
sourceId: parsed.sourceId,
|
|
2046
|
-
pluginName: parsed.pluginName,
|
|
2047
|
-
scope,
|
|
2048
|
-
cwd: options.cwd,
|
|
2049
|
-
env: options.env,
|
|
2050
|
-
})).exists;
|
|
2051
|
-
}
|
|
2052
|
-
catch {
|
|
2053
|
-
hasConfig = true;
|
|
1755
|
+
const retainedActions = retainedPackages.map((entry) => ({
|
|
1756
|
+
...entry, kind: 'retainManagedCommandPackage', pluginId: options.target.pluginId,
|
|
1757
|
+
scope: entry.producer.scope,
|
|
1758
|
+
}));
|
|
1759
|
+
const withRetainedPackages = (result, operationPlan = createOfflineCleanupOperationPlan([], undefined, [], retainedActions)) => {
|
|
1760
|
+
result.operationPlan = operationPlan;
|
|
1761
|
+
const commandResults = [...new Map([
|
|
1762
|
+
...retainedPackages.map(retainedManagedCommandPackageResult), ...(result.commandResults ?? []),
|
|
1763
|
+
].map((entry) => [JSON.stringify(entry.producer), entry])).values()];
|
|
1764
|
+
if (commandResults.length > 0) {
|
|
1765
|
+
result.commandResults = commandResults;
|
|
1766
|
+
if (result.overallState === 'succeeded' && commandResults.some((entry) => entry.state !== 'completed')) {
|
|
1767
|
+
result.overallState = 'partial';
|
|
2054
1768
|
}
|
|
2055
1769
|
}
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
pluginId: target.pluginId,
|
|
2068
|
-
pluginName: target.pluginName,
|
|
2069
|
-
sourceId: target.sourceId,
|
|
2070
|
-
sourceIdentity: target.sourceIdentity,
|
|
2071
|
-
pluginVersion: '0.0.0',
|
|
2072
|
-
platform: 'codex',
|
|
2073
|
-
scope,
|
|
2074
|
-
cwd: options.cwd,
|
|
1770
|
+
return result;
|
|
1771
|
+
};
|
|
1772
|
+
if (selected.length === 0)
|
|
1773
|
+
return withRetainedPackages(mergeRebuildCommandResults([]));
|
|
1774
|
+
const inventoryReader = options.runtime?.inventoryCatalogSourceReferences
|
|
1775
|
+
?? inventoryCatalogSourceReferences;
|
|
1776
|
+
const inventory = await inventoryReader({
|
|
1777
|
+
cwd: options.context.executionCwd,
|
|
1778
|
+
env: options.context.env,
|
|
1779
|
+
scope: options.context.scope,
|
|
1780
|
+
includeProjectAgentSkills: true,
|
|
2075
1781
|
});
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
pluginName: target.pluginName,
|
|
2093
|
-
sourceId: target.sourceId,
|
|
2094
|
-
sourceIdentity: target.sourceIdentity,
|
|
2095
|
-
platform: 'codex',
|
|
2096
|
-
scope,
|
|
2097
|
-
});
|
|
2098
|
-
result.removed.push(`pluginIntent:${scope}`);
|
|
2099
|
-
results.push(result);
|
|
2100
|
-
}
|
|
2101
|
-
}
|
|
2102
|
-
catch (error) {
|
|
2103
|
-
const message = `removedPluginIntentWriteFailed: ${scope}: ${error instanceof Error ? error.message : String(error)}. Retry cleanup.`;
|
|
2104
|
-
results.push(...options.targets.map((target) => failedResult('cleanup', targetIdentity(target, scope), message)));
|
|
2105
|
-
return {
|
|
2106
|
-
platforms: ['codex', 'claude'],
|
|
2107
|
-
plugins: [],
|
|
2108
|
-
warnings: [...warnings, message],
|
|
2109
|
-
rebuildResults: results,
|
|
2110
|
-
targetResults: results.map(toRemovedCleanupTargetResult),
|
|
2111
|
-
overallState: intentChanged ? 'partial' : 'failed',
|
|
2112
|
-
receiptTargets: results.map((result) => result.target),
|
|
2113
|
-
removedPluginCleanupIds: options.targets.map((target) => target.pluginId),
|
|
2114
|
-
operationPlan: options.operationPlan,
|
|
2115
|
-
};
|
|
2116
|
-
}
|
|
2117
|
-
}
|
|
2118
|
-
let codexManager = options.runtime?.codexManager;
|
|
2119
|
-
if (!codexManager && options.targets.some((target) => target.nativeState === 'installed')) {
|
|
2120
|
-
try {
|
|
2121
|
-
if (options.runtime?.codexManagerResolver) {
|
|
2122
|
-
codexManager = await options.runtime.codexManagerResolver({
|
|
2123
|
-
cwd: options.cwd,
|
|
2124
|
-
env: options.env,
|
|
2125
|
-
runner: options.runtime.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
2126
|
-
authorizer: options.runtime.managedCodexAuthorizer,
|
|
2127
|
-
operationRequirement: getCodexOperationRequirement('project'),
|
|
2128
|
-
});
|
|
2129
|
-
}
|
|
2130
|
-
else {
|
|
2131
|
-
const consumer = await (options.runtime?.codexOperationConsumerResolver
|
|
2132
|
-
?? resolveCodexOperationConsumer)({
|
|
2133
|
-
cwd: options.cwd,
|
|
2134
|
-
env: options.env,
|
|
2135
|
-
runner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
2136
|
-
authorizer: options.runtime?.managedCodexAuthorizer,
|
|
2137
|
-
operationRequirement: getCodexOperationRequirement('project'),
|
|
2138
|
-
requiresNativeMaterialization: true,
|
|
2139
|
-
});
|
|
2140
|
-
if (consumer.support !== 'observed') {
|
|
2141
|
-
throw new Error('Codex native removal requires an observed official CLI consumer.');
|
|
2142
|
-
}
|
|
2143
|
-
codexManager = consumer.manager;
|
|
2144
|
-
}
|
|
2145
|
-
}
|
|
2146
|
-
catch (error) {
|
|
2147
|
-
warnings.push(`removedPluginCodexManagerUnavailable: ${error instanceof Error ? error.message : String(error)}`);
|
|
2148
|
-
}
|
|
1782
|
+
const current = await inspectRemovedPluginCleanup({
|
|
1783
|
+
pluginId: options.target.pluginId,
|
|
1784
|
+
scope: options.context.scope,
|
|
1785
|
+
inventory,
|
|
1786
|
+
cwd: options.context.executionCwd,
|
|
1787
|
+
env: options.context.env,
|
|
1788
|
+
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
1789
|
+
codexManager: options.runtime?.codexManager,
|
|
1790
|
+
});
|
|
1791
|
+
if (!current || current.sourceIdentity !== options.target.sourceIdentity
|
|
1792
|
+
|| current.projectionFingerprint !== options.target.projectionFingerprint
|
|
1793
|
+
|| current.evidence.some((entry) => {
|
|
1794
|
+
const expected = options.target.evidence.find((candidate) => candidate.platform === entry.platform && candidate.scope === entry.scope);
|
|
1795
|
+
return !expected || !offlineCleanupEvidenceMatches(expected, entry);
|
|
1796
|
+
})) {
|
|
1797
|
+
throw new Error('operationReviewStale: removed plugin ownership or output changed before cleanup.');
|
|
2149
1798
|
}
|
|
2150
|
-
const
|
|
2151
|
-
|
|
2152
|
-
.
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
sourceIdentity: target.sourceIdentity,
|
|
1799
|
+
const evidence = current.evidence.filter((entry) => selected.some((target) => target.platform === entry.platform && target.scope === entry.scope));
|
|
1800
|
+
const targets = evidence.map((entry) => ({
|
|
1801
|
+
pluginId: current.pluginId,
|
|
1802
|
+
pluginName: current.pluginName,
|
|
1803
|
+
sourceId: current.sourceId,
|
|
1804
|
+
sourceIdentity: current.sourceIdentity,
|
|
2157
1805
|
platform: entry.platform,
|
|
2158
1806
|
scope: entry.scope,
|
|
2159
|
-
...(
|
|
2160
|
-
nativeRegistration: entry.
|
|
2161
|
-
}))
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
1807
|
+
...(current.marketplaceName ? { marketplaceName: current.marketplaceName } : {}),
|
|
1808
|
+
nativeRegistration: entry.platform === 'codex',
|
|
1809
|
+
}));
|
|
1810
|
+
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan(evidence, undefined, [], retainedActions), options.context.env);
|
|
1811
|
+
if (options.runtime?.expectedPlanFingerprint) {
|
|
1812
|
+
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
1813
|
+
}
|
|
1814
|
+
const result = options.runtime?.previewOperationPlan
|
|
1815
|
+
? await previewOfflineOwnedComponents({
|
|
1816
|
+
targets,
|
|
1817
|
+
evidence,
|
|
1818
|
+
cwd: options.context.executionCwd,
|
|
1819
|
+
env: options.context.env,
|
|
1820
|
+
nativeCliRunner: options.runtime?.nativeCliRunner,
|
|
1821
|
+
codexManagerPreviewer: options.runtime?.codexManagerPreviewer,
|
|
1822
|
+
onPreviewStage: options.runtime?.onPreviewStage,
|
|
1823
|
+
})
|
|
1824
|
+
: await cleanupOfflineOwnedComponents({
|
|
1825
|
+
targets,
|
|
1826
|
+
evidence,
|
|
1827
|
+
inventoryErrors: inventory.errors.filter((error) => !error.kind.startsWith('config')),
|
|
1828
|
+
cwd: options.context.executionCwd,
|
|
1829
|
+
env: options.context.env,
|
|
2169
1830
|
nativeCliRunner: options.runtime?.nativeCliRunner,
|
|
2170
|
-
|
|
1831
|
+
codexManager: options.runtime?.codexManager,
|
|
2171
1832
|
executeCleanupOperation: options.runtime?.executeCleanupOperation,
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
});
|
|
2175
|
-
results.push(...owned.rebuildResults);
|
|
2176
|
-
warnings.push(...owned.warnings);
|
|
2177
|
-
}
|
|
2178
|
-
for (const target of options.targets) {
|
|
2179
|
-
for (const config of target.configTargets.filter((entry) => entry.kind !== 'absent')) {
|
|
2180
|
-
if (config.kind === 'directory' || config.kind === 'special'
|
|
2181
|
-
|| target.blockers.some((blocker) => blocker.startsWith(`${config.scope}: removedPluginConfigIdentityConflict`))) {
|
|
2182
|
-
continue;
|
|
2183
|
-
}
|
|
2184
|
-
try {
|
|
2185
|
-
const receipt = await resetPluginConfigStore({
|
|
2186
|
-
sourceId: target.sourceId,
|
|
2187
|
-
sourceIdentity: target.sourceIdentity,
|
|
2188
|
-
pluginName: target.pluginName,
|
|
2189
|
-
scope: config.scope,
|
|
2190
|
-
cwd: options.cwd,
|
|
2191
|
-
env: options.env,
|
|
2192
|
-
});
|
|
2193
|
-
const result = cleanupIntentResult({
|
|
2194
|
-
pluginId: target.pluginId,
|
|
2195
|
-
pluginName: target.pluginName,
|
|
2196
|
-
sourceId: target.sourceId,
|
|
2197
|
-
sourceIdentity: target.sourceIdentity,
|
|
2198
|
-
platform: 'codex',
|
|
2199
|
-
scope: config.scope,
|
|
2200
|
-
});
|
|
2201
|
-
if (receipt.deleted)
|
|
2202
|
-
result.removed.push(`${config.scope}/plugin-config/${target.sourceId}/${target.pluginName}`);
|
|
2203
|
-
results.push(result);
|
|
2204
|
-
}
|
|
2205
|
-
catch (error) {
|
|
2206
|
-
results.push(failedResult('cleanup', targetIdentity(target, config.scope), `removedPluginConfigResetFailed: ${error instanceof Error ? error.message : String(error)}. Retry cleanup.`, 'cleanup.owned'));
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2209
|
-
let nativeAbsent = target.nativeState === 'absent';
|
|
2210
|
-
if (target.marketplaceName && target.nativeState !== 'unbound') {
|
|
2211
|
-
try {
|
|
2212
|
-
const observed = await inspectCodexPluginRegistrationLive({
|
|
2213
|
-
pluginId: `${target.pluginName}@${target.marketplaceName}`,
|
|
2214
|
-
cwd: options.cwd,
|
|
2215
|
-
env: options.env,
|
|
2216
|
-
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
2217
|
-
...(codexManager ? { manager: codexManager } : {}),
|
|
2218
|
-
scope: 'both',
|
|
2219
|
-
});
|
|
2220
|
-
nativeAbsent = observed.observation.state === 'observed'
|
|
2221
|
-
&& observed.observation.value === 'absent';
|
|
2222
|
-
}
|
|
2223
|
-
catch {
|
|
2224
|
-
nativeAbsent = false;
|
|
2225
|
-
}
|
|
2226
|
-
}
|
|
2227
|
-
if (!nativeAbsent && (target.nativeState === 'installed' || target.nativeState === 'unknown')) {
|
|
2228
|
-
results.push(failedResult('cleanup', targetIdentity(target), 'removedPluginNativeResidual: official Codex list did not confirm absent. Retry ordinary cleanup.', 'cleanup.owned'));
|
|
2229
|
-
}
|
|
2230
|
-
if (nativeAbsent && target.marketplaceName && target.nativeOwnershipVerified) {
|
|
2231
|
-
for (const activation of target.activationScopes) {
|
|
2232
|
-
try {
|
|
2233
|
-
await removeCodexPluginActivation({
|
|
2234
|
-
configPath: resolveCodexPaths(options.cwd, activation.scope, options.env).configTomlPath,
|
|
2235
|
-
codexPluginId: `${target.pluginName}@${target.marketplaceName}`,
|
|
2236
|
-
});
|
|
2237
|
-
const result = cleanupIntentResult({
|
|
2238
|
-
pluginId: target.pluginId,
|
|
2239
|
-
pluginName: target.pluginName,
|
|
2240
|
-
sourceId: target.sourceId,
|
|
2241
|
-
sourceIdentity: target.sourceIdentity,
|
|
2242
|
-
platform: 'codex',
|
|
2243
|
-
scope: activation.scope,
|
|
2244
|
-
});
|
|
2245
|
-
result.removed.push(`codexActivation:${activation.scope}`);
|
|
2246
|
-
results.push(result);
|
|
2247
|
-
}
|
|
2248
|
-
catch (error) {
|
|
2249
|
-
results.push(failedResult('cleanup', targetIdentity(target, activation.scope), `removedPluginActivationFailed: ${error instanceof Error ? error.message : String(error)}`, 'cleanup.owned'));
|
|
2250
|
-
}
|
|
2251
|
-
}
|
|
2252
|
-
}
|
|
2253
|
-
const claudeNativeFailed = results.some((result) => result.target.pluginId === target.pluginId
|
|
2254
|
-
&& result.target.platform === 'claude' && result.status === 'failed');
|
|
2255
|
-
if (target.projectionPresent && target.projectionOwnershipVerified
|
|
2256
|
-
&& nativeAbsent && !claudeNativeFailed && !target.claudeNativeCleanupBlocked
|
|
2257
|
-
&& (target.nativeOwnershipVerified || target.activationScopes.length === 0)) {
|
|
2258
|
-
try {
|
|
2259
|
-
await removeNamespacedMarketplacePluginProjection({
|
|
2260
|
-
rootDir: target.marketplaceRoot,
|
|
2261
|
-
sourceId: target.sourceId,
|
|
2262
|
-
sourceIdentity: target.sourceIdentity,
|
|
2263
|
-
pluginName: target.pluginName,
|
|
2264
|
-
env: options.env,
|
|
2265
|
-
});
|
|
2266
|
-
const result = cleanupIntentResult({
|
|
2267
|
-
pluginId: target.pluginId,
|
|
2268
|
-
pluginName: target.pluginName,
|
|
2269
|
-
sourceId: target.sourceId,
|
|
2270
|
-
sourceIdentity: target.sourceIdentity,
|
|
2271
|
-
platform: 'codex',
|
|
2272
|
-
scope: 'user',
|
|
2273
|
-
});
|
|
2274
|
-
result.removed.push('marketplaceProjection');
|
|
2275
|
-
results.push(result);
|
|
2276
|
-
}
|
|
2277
|
-
catch (error) {
|
|
2278
|
-
results.push(failedResult('cleanup', targetIdentity(target), `removedPluginMarketplaceProjectionFailed: ${error instanceof Error ? error.message : String(error)}`, 'cleanup.owned'));
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
for (const blocker of target.blockers) {
|
|
2282
|
-
results.push(failedResult('cleanup', targetIdentity(target), blocker));
|
|
2283
|
-
}
|
|
2284
|
-
}
|
|
2285
|
-
const afterInventory = await options.readInventory({ cwd: options.cwd, env: options.env });
|
|
2286
|
-
for (const target of options.targets) {
|
|
2287
|
-
const after = await inspectRemovedPluginCleanup({
|
|
2288
|
-
pluginId: target.pluginId,
|
|
2289
|
-
inventory: afterInventory,
|
|
2290
|
-
cwd: options.cwd,
|
|
2291
|
-
env: options.env,
|
|
2292
|
-
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
2293
|
-
...(codexManager ? { codexManager } : {}),
|
|
1833
|
+
preserveLegacyNativeSkills: options.runtime?.preserveLegacyNativeSkills,
|
|
1834
|
+
removeObsoleteInstallationContracts: options.runtime?.removeObsoleteInstallationContracts,
|
|
2294
1835
|
});
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
1836
|
+
withRetainedPackages(result, operationPlan);
|
|
1837
|
+
const residual = [
|
|
1838
|
+
...current.blockers.filter((blocker) => !blocker.includes('Config')),
|
|
1839
|
+
...(current.nativeState === 'installed' || current.nativeState === 'unknown'
|
|
1840
|
+
? ['sharedNativePreserved: Codex package remains available to other scopes.'] : []),
|
|
1841
|
+
...(current.projectionPresent ? ['sharedMarketplaceProjectionPreserved'] : []),
|
|
1842
|
+
];
|
|
1843
|
+
if (residual.length > 0) {
|
|
1844
|
+
result.warnings.push(...residual);
|
|
1845
|
+
if (result.overallState === 'succeeded')
|
|
1846
|
+
result.overallState = 'partial';
|
|
2304
1847
|
}
|
|
2305
|
-
|
|
2306
|
-
const hasSuccess = intentChanged || results.some((result) => result.status === 'succeeded'
|
|
2307
|
-
&& result.removed.length > 0);
|
|
2308
|
-
return {
|
|
2309
|
-
platforms: ['codex', 'claude'],
|
|
2310
|
-
plugins: hasFailure ? [] : options.targets.map((target) => target.pluginName),
|
|
2311
|
-
warnings: [...new Set(warnings)],
|
|
2312
|
-
rebuildResults: results,
|
|
2313
|
-
targetResults: results.map(toRemovedCleanupTargetResult),
|
|
2314
|
-
overallState: hasFailure ? hasSuccess ? 'partial' : 'failed' : 'succeeded',
|
|
2315
|
-
receiptTargets: results.map((result) => result.target),
|
|
2316
|
-
removedPluginCleanupIds: options.targets.map((target) => target.pluginId),
|
|
2317
|
-
operationPlan: options.operationPlan,
|
|
2318
|
-
};
|
|
1848
|
+
return result;
|
|
2319
1849
|
}
|
|
2320
1850
|
async function runRebuildCommandInSession(options) {
|
|
2321
|
-
const
|
|
1851
|
+
const executionInput = options.runtime?.executionInput;
|
|
1852
|
+
if (!executionInput || executionInput.context.scope !== options.commandOptions.scope
|
|
1853
|
+
|| executionInput.preserveOtherObservedTargets !== true) {
|
|
1854
|
+
throw new Error('nativeExecutionInputRequired: Native execution requires an explicit matching scope context and complete demand.');
|
|
1855
|
+
}
|
|
1856
|
+
if (executionInput.selectedTargets.length === 0)
|
|
1857
|
+
return mergeRebuildCommandResults([]);
|
|
1858
|
+
if (executionInput.selectedTargets.some((target) => target.scope !== executionInput.context.scope)) {
|
|
1859
|
+
throw new Error('nativeExecutionTargetScopeInvalid: Selected targets must use the execution context scope.');
|
|
1860
|
+
}
|
|
1861
|
+
const requestedPlatforms = selectedPlatforms(options.commandOptions.platform);
|
|
1862
|
+
if (executionInput.selectedTargets.some((target) => !requestedPlatforms.includes(target.platform))) {
|
|
1863
|
+
throw new Error('nativeExecutionTargetPlatformInvalid: Selected targets must use a requested platform.');
|
|
1864
|
+
}
|
|
1865
|
+
const selectedExecutionTarget = (target) => executionInput.selectedTargets.some((selected) => selected.pluginId === target.pluginId && selected.platform === target.platform && selected.scope === target.scope);
|
|
1866
|
+
const runtimeEnv = executionInput.context.env;
|
|
2322
1867
|
const retainSelectors = options.command === 'cleanup' ? options.pluginNames.map(parsePluginId) : [];
|
|
2323
1868
|
const primarySourceId = retainSelectors.some((selector) => !selector.sourceId)
|
|
2324
|
-
?
|
|
1869
|
+
? await readCatalogSourcesConfigSnapshot(runtimeEnv)
|
|
1870
|
+
.then((snapshot) => snapshot.config.sources.find((source) => source.primary)?.id)
|
|
1871
|
+
.catch(() => undefined)
|
|
2325
1872
|
: undefined;
|
|
2326
1873
|
const retainedPackages = options.command === 'cleanup'
|
|
2327
1874
|
? await discoverRetainedManagedCommandPackages({ selectors: retainSelectors.map((selector) => ({ ...selector, sourceId: selector.sourceId ?? primarySourceId })), all: options.all, scope: options.commandOptions.scope, cwd: options.commandOptions.cwd, env: runtimeEnv })
|
|
@@ -2335,6 +1882,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2335
1882
|
const inventory = await readInventory({
|
|
2336
1883
|
cwd: options.commandOptions.cwd,
|
|
2337
1884
|
env: runtimeEnv,
|
|
1885
|
+
scope: options.commandOptions.scope,
|
|
2338
1886
|
});
|
|
2339
1887
|
if (options.command !== 'cleanup'
|
|
2340
1888
|
|| options.commandOptions.scope !== 'project'
|
|
@@ -2369,13 +1917,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2369
1917
|
let requestedPluginNames = options.pluginNames;
|
|
2370
1918
|
const cleanupForce = options.command === 'cleanup'
|
|
2371
1919
|
&& options.commandOptions.force === true;
|
|
2372
|
-
const
|
|
2373
|
-
? await readPluginIntentState({
|
|
2374
|
-
scope: options.commandOptions.scope,
|
|
2375
|
-
cwd: options.commandOptions.cwd,
|
|
2376
|
-
env: runtimeEnv,
|
|
2377
|
-
})
|
|
2378
|
-
: undefined;
|
|
1920
|
+
const cleanupRequirements = options.command === 'cleanup' ? executionInput.requirements : undefined;
|
|
2379
1921
|
const expectedOfflineCleanup = options.runtime?.expectedOfflineCleanupEvidence;
|
|
2380
1922
|
let cleanupInventory;
|
|
2381
1923
|
let cleanupLiveTargets = [];
|
|
@@ -2391,7 +1933,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2391
1933
|
references: cleanupInventory.references,
|
|
2392
1934
|
});
|
|
2393
1935
|
requestedPluginNames = live.selectors;
|
|
2394
|
-
cleanupLiveTargets = live.targets;
|
|
1936
|
+
cleanupLiveTargets = live.targets.filter(selectedExecutionTarget);
|
|
2395
1937
|
if (expectedOfflineCleanup
|
|
2396
1938
|
&& expectedOfflineCleanup.forceExclusive !== true
|
|
2397
1939
|
&& expectedOfflineCleanup.plan.actions.length > 0) {
|
|
@@ -2456,7 +1998,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2456
1998
|
liveTargets = projectedTargets;
|
|
2457
1999
|
if (options.command === 'cleanup') {
|
|
2458
2000
|
cleanupInventory = inventory;
|
|
2459
|
-
cleanupLiveTargets = projectedTargets;
|
|
2001
|
+
cleanupLiveTargets = projectedTargets.filter(selectedExecutionTarget);
|
|
2460
2002
|
}
|
|
2461
2003
|
const identities = new Set();
|
|
2462
2004
|
for (const reference of live) {
|
|
@@ -2464,14 +2006,13 @@ async function runRebuildCommandInSession(options) {
|
|
|
2464
2006
|
identities.add(pluginId);
|
|
2465
2007
|
}
|
|
2466
2008
|
if (options.command === 'cleanup') {
|
|
2467
|
-
for (const root of
|
|
2009
|
+
for (const root of cleanupRequirements.roots)
|
|
2468
2010
|
identities.add(root.pluginId);
|
|
2469
2011
|
}
|
|
2470
2012
|
requestedPluginNames = [...identities];
|
|
2471
2013
|
}
|
|
2472
2014
|
let cleanupTargets = [];
|
|
2473
2015
|
let cleanupUnavailableWarnings = [];
|
|
2474
|
-
let cleanupIntentAfter;
|
|
2475
2016
|
let cleanupSelectionErrors = [];
|
|
2476
2017
|
if (options.command === 'cleanup') {
|
|
2477
2018
|
const primarySourceId = cleanupForce
|
|
@@ -2480,7 +2021,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2480
2021
|
.catch(() => undefined)
|
|
2481
2022
|
: undefined;
|
|
2482
2023
|
const intentTargets = cleanupIntentTargets({
|
|
2483
|
-
state:
|
|
2024
|
+
state: cleanupRequirements,
|
|
2484
2025
|
selectors: options.pluginNames,
|
|
2485
2026
|
platforms: selectedPlatforms(options.commandOptions.platform),
|
|
2486
2027
|
scope: options.commandOptions.scope,
|
|
@@ -2507,17 +2048,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
2507
2048
|
cleanupTargets = [...new Map([...damagedTargets, ...intentTargets, ...cleanupLiveTargets].map((target) => [
|
|
2508
2049
|
`${target.pluginId}\0${target.platform}\0${target.scope}`,
|
|
2509
2050
|
target,
|
|
2510
|
-
])).values()];
|
|
2051
|
+
])).values()].filter(selectedExecutionTarget);
|
|
2511
2052
|
requestedPluginNames = [...new Set([
|
|
2512
2053
|
...requestedPluginNames,
|
|
2513
2054
|
...cleanupTargets.map((target) => target.pluginId),
|
|
2514
2055
|
])];
|
|
2515
|
-
cleanupIntentAfter = deriveDesiredIntentState({
|
|
2516
|
-
command: 'cleanup',
|
|
2517
|
-
state: cleanupIntentBefore,
|
|
2518
|
-
selectedRoots: cleanupSelectedRoots(cleanupTargets),
|
|
2519
|
-
plan: { requestedPluginIds: [], resolvedPluginIds: [], dependencyEdges: [], targets: [], scopeOverrides: [] },
|
|
2520
|
-
});
|
|
2521
2056
|
const filtered = omitSelectedPluginConfigErrors(cleanupInventory, cleanupTargets);
|
|
2522
2057
|
cleanupInventory = filtered.inventory;
|
|
2523
2058
|
malformedSelectedConfigPreserved ||= filtered.omitted;
|
|
@@ -2532,171 +2067,18 @@ async function runRebuildCommandInSession(options) {
|
|
|
2532
2067
|
const selectors = requestedPluginNames.map(parsePluginId);
|
|
2533
2068
|
const sourceIds = planPluginSelectorSourceIds(selectors);
|
|
2534
2069
|
if (options.all && selectors.length === 0 && options.command !== 'cleanup') {
|
|
2535
|
-
if (legacyLiveTargets.length > 0) {
|
|
2536
|
-
throw namespacedPreflightError(`legacyStateUnsupported: legacy live runtime state exists for ${legacyLiveTargets.map((target) => `${target.pluginName}:${target.platform}/${target.scope}`).join(', ')}.`, [], legacyLiveTargets);
|
|
2537
|
-
}
|
|
2538
|
-
return mergeRebuildCommandResults([]);
|
|
2539
|
-
}
|
|
2540
|
-
if (options.command === 'cleanup') {
|
|
2541
|
-
if (!cleanupForce) {
|
|
2542
|
-
const exactIds = [...new Set(requestedPluginNames.flatMap((selector) => {
|
|
2543
|
-
const parsed = parsePluginId(selector);
|
|
2544
|
-
return parsed.sourceId ? [formatPluginId(parsed)] : [];
|
|
2545
|
-
}))];
|
|
2546
|
-
const projectSkills = await selectedProjectCodexSkillReferences({
|
|
2547
|
-
cwd: options.commandOptions.cwd,
|
|
2548
|
-
});
|
|
2549
|
-
const fullInventory = {
|
|
2550
|
-
...cleanupInventory,
|
|
2551
|
-
references: [...new Map([...cleanupInventory.references, ...projectSkills].map((reference) => [[
|
|
2552
|
-
reference.kind,
|
|
2553
|
-
reference.location,
|
|
2554
|
-
reference.sourceId ?? '',
|
|
2555
|
-
reference.pluginName ?? '',
|
|
2556
|
-
reference.platform ?? '',
|
|
2557
|
-
reference.scope ?? '',
|
|
2558
|
-
].join('\0'), reference])).values()],
|
|
2559
|
-
};
|
|
2560
|
-
const removed = (await Promise.all(exactIds.map((pluginId) => inspectRemovedPluginCleanup({
|
|
2561
|
-
pluginId,
|
|
2562
|
-
inventory: fullInventory,
|
|
2563
|
-
cwd: options.commandOptions.cwd,
|
|
2564
|
-
env: runtimeEnv,
|
|
2565
|
-
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
2566
|
-
codexManager: options.runtime?.codexManager,
|
|
2567
|
-
})))).filter((target) => target !== null);
|
|
2568
|
-
cleanupUnavailableWarnings = await unavailableRemovedCleanupWarnings({
|
|
2569
|
-
pluginIds: exactIds.filter((pluginId) => !removed.some((target) => target.pluginId === pluginId)),
|
|
2570
|
-
inventory: fullInventory,
|
|
2571
|
-
cwd: options.commandOptions.cwd,
|
|
2572
|
-
env: runtimeEnv,
|
|
2573
|
-
});
|
|
2574
|
-
if (removed.length > 0) {
|
|
2575
|
-
const removedIds = new Set(removed.map((target) => target.pluginId));
|
|
2576
|
-
const intents = {
|
|
2577
|
-
user: {
|
|
2578
|
-
before: await readPluginIntentState({
|
|
2579
|
-
scope: 'user', cwd: options.commandOptions.cwd, env: runtimeEnv,
|
|
2580
|
-
}),
|
|
2581
|
-
after: createEmptyPluginIntentState(),
|
|
2582
|
-
},
|
|
2583
|
-
project: {
|
|
2584
|
-
before: await readPluginIntentState({
|
|
2585
|
-
scope: 'project', cwd: options.commandOptions.cwd, env: runtimeEnv,
|
|
2586
|
-
}),
|
|
2587
|
-
after: createEmptyPluginIntentState(),
|
|
2588
|
-
},
|
|
2589
|
-
};
|
|
2590
|
-
intents.user.after = removeRemovedPluginIntent(intents.user.before, removedIds);
|
|
2591
|
-
intents.project.after = removeRemovedPluginIntent(intents.project.before, removedIds);
|
|
2592
|
-
const removedPlan = await withNativeToolRemovalImpact(createRemovedPluginCleanupOperationPlan({
|
|
2593
|
-
targets: removed,
|
|
2594
|
-
intents,
|
|
2595
|
-
cwd: options.commandOptions.cwd,
|
|
2596
|
-
env: runtimeEnv,
|
|
2597
|
-
}), runtimeEnv);
|
|
2598
|
-
const remaining = exactIds.filter((pluginId) => !removedIds.has(pluginId));
|
|
2599
|
-
const normalOptions = {
|
|
2600
|
-
...options,
|
|
2601
|
-
all: false,
|
|
2602
|
-
pluginNames: remaining,
|
|
2603
|
-
runtime: {
|
|
2604
|
-
...options.runtime,
|
|
2605
|
-
expectedPlanFingerprint: undefined,
|
|
2606
|
-
expectedOfflineCleanupEvidence: undefined,
|
|
2607
|
-
},
|
|
2608
|
-
};
|
|
2609
|
-
const normalPreview = remaining.length > 0
|
|
2610
|
-
? await runRebuildCommandInSession({
|
|
2611
|
-
...normalOptions,
|
|
2612
|
-
runtime: { ...normalOptions.runtime, previewOperationPlan: true },
|
|
2613
|
-
})
|
|
2614
|
-
: undefined;
|
|
2615
|
-
const operationPlan = normalPreview?.operationPlan
|
|
2616
|
-
? combineCleanupOperationPlans([removedPlan, normalPreview.operationPlan])
|
|
2617
|
-
: removedPlan;
|
|
2618
|
-
if (options.runtime?.expectedPlanFingerprint) {
|
|
2619
|
-
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
2620
|
-
}
|
|
2621
|
-
if (options.runtime?.previewOperationPlan) {
|
|
2622
|
-
const preview = normalPreview ?? mergeRebuildCommandResults([]);
|
|
2623
|
-
preview.removedPluginCleanupIds = [...removedIds];
|
|
2624
|
-
preview.operationPlan = operationPlan;
|
|
2625
|
-
preview.warnings = [...new Set([...preview.warnings, ...removedPlan.warnings])];
|
|
2626
|
-
return preview;
|
|
2627
|
-
}
|
|
2628
|
-
assertNativeToolChangeAuthorization(operationPlan, options);
|
|
2629
|
-
if (options.commandOptions.yes !== true
|
|
2630
|
-
&& !(options.runtime?.preApplyConfirmed === true
|
|
2631
|
-
&& options.runtime.expectedPlanFingerprint !== undefined)) {
|
|
2632
|
-
throw new Error('removedPluginCleanupAuthorizationRequired: deleted-plugin cleanup covers Codex and Claude in user and current-project scopes, removes saved settings and the shared Codex native package, and may affect other projects. Use --yes or accept the full Review.');
|
|
2633
|
-
}
|
|
2634
|
-
const removedResult = await executeRemovedPluginCleanup({
|
|
2635
|
-
targets: removed,
|
|
2636
|
-
intents,
|
|
2637
|
-
inventory: fullInventory,
|
|
2638
|
-
cwd: options.commandOptions.cwd,
|
|
2639
|
-
env: runtimeEnv,
|
|
2640
|
-
runtime: options.runtime,
|
|
2641
|
-
readInventory,
|
|
2642
|
-
operationPlan: removedPlan,
|
|
2643
|
-
});
|
|
2644
|
-
let normalResult;
|
|
2645
|
-
if (remaining.length > 0) {
|
|
2646
|
-
try {
|
|
2647
|
-
for (const scope of ['user', 'project']) {
|
|
2648
|
-
const actual = await readPluginIntentState({ scope, cwd: options.commandOptions.cwd, env: runtimeEnv });
|
|
2649
|
-
if (calculatePluginIntentDigest(actual) !== calculatePluginIntentDigest(intents[scope].after)) {
|
|
2650
|
-
throw new Error('operationPlanStale: installation intent changed beyond the reviewed deleted-plugin cleanup.');
|
|
2651
|
-
}
|
|
2652
|
-
}
|
|
2653
|
-
const currentNormalPreview = await runRebuildCommandInSession({
|
|
2654
|
-
...normalOptions,
|
|
2655
|
-
runtime: { ...normalOptions.runtime, previewOperationPlan: true },
|
|
2656
|
-
});
|
|
2657
|
-
if (!normalPreview?.operationPlan || !currentNormalPreview.operationPlan
|
|
2658
|
-
|| createBatchIntentCompatiblePlanFingerprint(normalPreview.operationPlan)
|
|
2659
|
-
!== createBatchIntentCompatiblePlanFingerprint(currentNormalPreview.operationPlan)) {
|
|
2660
|
-
throw new Error('operationPlanStale: the remaining cleanup actions changed after the reviewed deleted-plugin cleanup.');
|
|
2661
|
-
}
|
|
2662
|
-
normalResult = await runRebuildCommandInSession({
|
|
2663
|
-
...normalOptions,
|
|
2664
|
-
runtime: { ...normalOptions.runtime, expectedPlanFingerprint: currentNormalPreview.operationPlan.planFingerprint },
|
|
2665
|
-
});
|
|
2666
|
-
}
|
|
2667
|
-
catch (error) {
|
|
2668
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
2669
|
-
const failures = (normalPreview?.receiptTargets ?? []).map((target) => failedResult('cleanup', {
|
|
2670
|
-
...target, cwd: options.commandOptions.cwd, pluginVersion: 'unavailable',
|
|
2671
|
-
}, message));
|
|
2672
|
-
normalResult = { ...mergeRebuildCommandResults([]), overallState: 'failed', warnings: [message],
|
|
2673
|
-
platforms: normalPreview?.platforms ?? [], rebuildResults: failures,
|
|
2674
|
-
targetResults: failures.map(toTargetResult), receiptTargets: failures.map((failure) => failure.target) };
|
|
2675
|
-
}
|
|
2676
|
-
}
|
|
2677
|
-
const combined = normalResult
|
|
2678
|
-
? mergeRebuildCommandResults([removedResult, normalResult])
|
|
2679
|
-
: removedResult;
|
|
2680
|
-
combined.operationPlan = operationPlan;
|
|
2681
|
-
combined.removedPluginCleanupIds = [...removedIds];
|
|
2682
|
-
combined.warnings = [...new Set([...combined.warnings, ...operationPlan.warnings])];
|
|
2683
|
-
combined.overallState = [removedResult, normalResult].filter(Boolean).every((result) => result?.overallState === 'succeeded')
|
|
2684
|
-
? 'succeeded'
|
|
2685
|
-
: [removedResult, normalResult].filter(Boolean).some((result) => result?.overallState === 'succeeded' || result?.overallState === 'partial')
|
|
2686
|
-
? 'partial' : 'failed';
|
|
2687
|
-
return combined;
|
|
2688
|
-
}
|
|
2070
|
+
if (legacyLiveTargets.length > 0) {
|
|
2071
|
+
throw namespacedPreflightError(`legacyStateUnsupported: legacy live runtime state exists for ${legacyLiveTargets.map((target) => `${target.pluginName}:${target.platform}/${target.scope}`).join(', ')}.`, [], legacyLiveTargets);
|
|
2689
2072
|
}
|
|
2073
|
+
return mergeRebuildCommandResults([]);
|
|
2074
|
+
}
|
|
2075
|
+
if (options.command === 'cleanup') {
|
|
2690
2076
|
if (!cleanupForce
|
|
2691
2077
|
&& cleanupTargets.length === 0
|
|
2692
2078
|
&& cleanupSelectionErrors.length === 0
|
|
2693
2079
|
&& legacyLiveTargets.length === 0) {
|
|
2694
2080
|
const result = mergeRebuildCommandResults([]);
|
|
2695
|
-
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan([], {
|
|
2696
|
-
scope: options.commandOptions.scope,
|
|
2697
|
-
before: cleanupIntentBefore,
|
|
2698
|
-
after: cleanupIntentAfter,
|
|
2699
|
-
}, [...cleanupInventoryWarnings(cleanupInventory, []), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2081
|
+
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan([], { scope: options.commandOptions.scope, view: cleanupRequirements }, [...cleanupInventoryWarnings(cleanupInventory, []), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2700
2082
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
2701
2083
|
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
2702
2084
|
}
|
|
@@ -2744,6 +2126,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
2744
2126
|
damagedOnly: cleanupLiveTargets.length > 0,
|
|
2745
2127
|
})));
|
|
2746
2128
|
const forcePlan = await mergeForceCleanupPlans(livePlan, ...supplementAttempts.flatMap((attempt) => attempt.status === 'fulfilled' ? [attempt.value] : []));
|
|
2129
|
+
forcePlan.targets = forcePlan.targets.filter((target) => selectedExecutionTarget(target.identity));
|
|
2130
|
+
forcePlan.evidence = forcePlan.evidence.filter(selectedExecutionTarget);
|
|
2747
2131
|
const forceCleanupTargets = [...new Map([
|
|
2748
2132
|
...cleanupTargets,
|
|
2749
2133
|
...forcePlan.targets.map((target) => ({
|
|
@@ -2786,11 +2170,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2786
2170
|
&& candidate.platform === target.platform
|
|
2787
2171
|
&& candidate.scope === target.scope)
|
|
2788
2172
|
?? intentOnlyOfflineCleanupEvidence(target));
|
|
2789
|
-
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan(forceEvidence, {
|
|
2790
|
-
scope: options.commandOptions.scope,
|
|
2791
|
-
before: cleanupIntentBefore,
|
|
2792
|
-
after: cleanupIntentAfter,
|
|
2793
|
-
}, cleanupInventoryWarnings(cleanupInventory, forceCleanupTargets), retainedPackageActions), runtimeEnv);
|
|
2173
|
+
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan(forceEvidence, { scope: options.commandOptions.scope, view: cleanupRequirements }, cleanupInventoryWarnings(cleanupInventory, forceCleanupTargets), retainedPackageActions), runtimeEnv);
|
|
2794
2174
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
2795
2175
|
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
2796
2176
|
}
|
|
@@ -2807,14 +2187,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
2807
2187
|
};
|
|
2808
2188
|
}
|
|
2809
2189
|
assertNativeToolChangeAuthorization(operationPlan, options);
|
|
2810
|
-
if (calculatePluginIntentDigest(cleanupIntentBefore)
|
|
2811
|
-
!== calculatePluginIntentDigest(cleanupIntentAfter)) {
|
|
2812
|
-
await (options.runtime?.writePluginIntentState ?? writePluginIntentState)({
|
|
2813
|
-
scope: options.commandOptions.scope,
|
|
2814
|
-
cwd: options.commandOptions.cwd,
|
|
2815
|
-
env: runtimeEnv,
|
|
2816
|
-
}, cleanupIntentAfter);
|
|
2817
|
-
}
|
|
2818
2190
|
const forceResults = await Promise.all(forcePlan.targets.map(async (target) => {
|
|
2819
2191
|
const integration = createRebuildIntegration({
|
|
2820
2192
|
context: {
|
|
@@ -2824,7 +2196,16 @@ async function runRebuildCommandInSession(options) {
|
|
|
2824
2196
|
debugLogger: options.runtime?.debugLogger ?? createNoopDebugLogger(),
|
|
2825
2197
|
},
|
|
2826
2198
|
});
|
|
2827
|
-
const { finalizeCleanup: _finalizeCleanup, ...
|
|
2199
|
+
const { finalizeCleanup: _finalizeCleanup, ...driver } = integration.driver;
|
|
2200
|
+
const pathOnlyDriver = {
|
|
2201
|
+
...driver,
|
|
2202
|
+
beforeCleanupMutation: async (component) => {
|
|
2203
|
+
await driver.beforeCleanupMutation?.(component);
|
|
2204
|
+
await removeForceCleanupCodexRoleRegistration({
|
|
2205
|
+
component, cwd: options.commandOptions.cwd, env: runtimeEnv,
|
|
2206
|
+
});
|
|
2207
|
+
},
|
|
2208
|
+
};
|
|
2828
2209
|
const result = await (options.runtime?.executeCleanupOperation ?? executeRebuildOperation)({
|
|
2829
2210
|
command: 'cleanup', target, driver: pathOnlyDriver,
|
|
2830
2211
|
});
|
|
@@ -2880,9 +2261,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
2880
2261
|
targetResults: allResults.map(toTargetResult),
|
|
2881
2262
|
overallState: allResults.every((entry) => entry.status === 'succeeded')
|
|
2882
2263
|
? 'succeeded'
|
|
2883
|
-
:
|
|
2884
|
-
||
|
|
2885
|
-
|| entry.actions.some((action) => action.status === 'succeeded'))
|
|
2264
|
+
: allResults.some((entry) => entry.status === 'succeeded'
|
|
2265
|
+
|| entry.actions.some((action) => action.status === 'succeeded'))
|
|
2886
2266
|
? 'partial' : 'failed',
|
|
2887
2267
|
receiptTargets: allResults.map((entry) => entry.target),
|
|
2888
2268
|
offlineCleanupPlans: forceEvidence,
|
|
@@ -2891,11 +2271,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2891
2271
|
}
|
|
2892
2272
|
if (cleanupTargets.length === 0) {
|
|
2893
2273
|
const result = mergeRebuildCommandResults([]);
|
|
2894
|
-
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan([], {
|
|
2895
|
-
scope: options.commandOptions.scope,
|
|
2896
|
-
before: cleanupIntentBefore,
|
|
2897
|
-
after: cleanupIntentAfter,
|
|
2898
|
-
}, [...cleanupInventoryWarnings(cleanupInventory, []), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2274
|
+
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan([], { scope: options.commandOptions.scope, view: cleanupRequirements }, [...cleanupInventoryWarnings(cleanupInventory, []), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2899
2275
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
2900
2276
|
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
2901
2277
|
}
|
|
@@ -2924,7 +2300,9 @@ async function runRebuildCommandInSession(options) {
|
|
|
2924
2300
|
sourceIdentity: target.sourceIdentity,
|
|
2925
2301
|
platform: target.platform,
|
|
2926
2302
|
scope: target.scope,
|
|
2927
|
-
inventory:
|
|
2303
|
+
inventory: options.runtime?.preserveLegacyNativeSkills
|
|
2304
|
+
? { ...cleanupInventory, references: cleanupInventory.references.filter((reference) => path.basename(reference.location) !== SKILL_OWNER_MARKER) }
|
|
2305
|
+
: cleanupInventory,
|
|
2928
2306
|
});
|
|
2929
2307
|
return value ? [value] : [];
|
|
2930
2308
|
});
|
|
@@ -2932,11 +2310,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2932
2310
|
&& candidate.platform === target.platform
|
|
2933
2311
|
&& candidate.scope === target.scope)
|
|
2934
2312
|
?? intentOnlyOfflineCleanupEvidence(target));
|
|
2935
|
-
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan(evidence, {
|
|
2936
|
-
scope: options.commandOptions.scope,
|
|
2937
|
-
before: cleanupIntentBefore,
|
|
2938
|
-
after: cleanupIntentAfter,
|
|
2939
|
-
}, [...cleanupInventoryWarnings(cleanupInventory, cleanupTargets), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2313
|
+
const operationPlan = await withNativeToolRemovalImpact(createOfflineCleanupOperationPlan(evidence, { scope: options.commandOptions.scope, view: cleanupRequirements }, [...cleanupInventoryWarnings(cleanupInventory, cleanupTargets), ...cleanupUnavailableWarnings], retainedPackageActions), runtimeEnv);
|
|
2940
2314
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
2941
2315
|
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, operationPlan);
|
|
2942
2316
|
}
|
|
@@ -2952,14 +2326,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
2952
2326
|
return previewResult;
|
|
2953
2327
|
}
|
|
2954
2328
|
assertNativeToolChangeAuthorization(operationPlan, options);
|
|
2955
|
-
if (calculatePluginIntentDigest(cleanupIntentBefore)
|
|
2956
|
-
!== calculatePluginIntentDigest(cleanupIntentAfter)) {
|
|
2957
|
-
await (options.runtime?.writePluginIntentState ?? writePluginIntentState)({
|
|
2958
|
-
scope: options.commandOptions.scope,
|
|
2959
|
-
cwd: options.commandOptions.cwd,
|
|
2960
|
-
env: runtimeEnv,
|
|
2961
|
-
}, cleanupIntentAfter);
|
|
2962
|
-
}
|
|
2963
2329
|
const cleanupResult = await cleanupOfflineOwnedComponents({
|
|
2964
2330
|
targets: cleanupLiveTargets,
|
|
2965
2331
|
evidence,
|
|
@@ -2970,6 +2336,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
2970
2336
|
nativeCliRunner: options.runtime?.nativeCliRunner,
|
|
2971
2337
|
codexManager: options.runtime?.codexManager,
|
|
2972
2338
|
executeCleanupOperation: options.runtime?.executeCleanupOperation,
|
|
2339
|
+
preserveLegacyNativeSkills: options.runtime?.preserveLegacyNativeSkills,
|
|
2973
2340
|
});
|
|
2974
2341
|
const liveKeys = new Set(cleanupLiveTargets.map((target) => `${target.pluginId}\0${target.platform}\0${target.scope}`));
|
|
2975
2342
|
const intentOnlyResults = cleanupTargets
|
|
@@ -2989,11 +2356,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
2989
2356
|
cleanupResult.platforms = [...new Set([...cleanupResult.platforms, ...intentOnlyResults.map((result) => result.target.platform)])];
|
|
2990
2357
|
cleanupResult.plugins = [...new Set([...cleanupResult.plugins, ...intentOnlyResults.map((result) => result.target.pluginName)])];
|
|
2991
2358
|
cleanupResult.operationPlan = operationPlan;
|
|
2992
|
-
if (
|
|
2993
|
-
|
|
2994
|
-
cleanupResult.overallState = 'partial';
|
|
2995
|
-
else if (intentOnlyResults.some((result) => result.status === 'failed')) {
|
|
2996
|
-
cleanupResult.overallState = operationPlan.intentChanges.length > 0 ? 'partial' : 'failed';
|
|
2359
|
+
if (intentOnlyResults.some((result) => result.status === 'failed')) {
|
|
2360
|
+
cleanupResult.overallState = 'failed';
|
|
2997
2361
|
}
|
|
2998
2362
|
if (malformedSelectedConfigPreserved) {
|
|
2999
2363
|
cleanupResult.warnings.push(MALFORMED_CONFIG_PRESERVED_WARNING);
|
|
@@ -3046,6 +2410,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
3046
2410
|
}
|
|
3047
2411
|
return matches[0];
|
|
3048
2412
|
});
|
|
2413
|
+
const requestedIds = new Set(selectedEntries.map((entry) => entry.pluginId));
|
|
2414
|
+
if (executionInput.selectedTargets.some((target) => !requestedIds.has(target.pluginId))) {
|
|
2415
|
+
throw new Error('nativeExecutionTargetOutsideRequest: selected target must match a requested plugin.');
|
|
2416
|
+
}
|
|
3049
2417
|
if (options.command === 'uninstall' || (options.command === 'cleanup' && options.all)) {
|
|
3050
2418
|
await measureCommandPerformanceStage(options.runtime, 'catalog.validation', async () => {
|
|
3051
2419
|
const selectedSources = new Map(selectedEntries.map((candidate) => [
|
|
@@ -3057,17 +2425,9 @@ async function runRebuildCommandInSession(options) {
|
|
|
3057
2425
|
}
|
|
3058
2426
|
});
|
|
3059
2427
|
}
|
|
3060
|
-
const intentCatalogEntries = availableEntries.map((candidate) => ({
|
|
3061
|
-
pluginId: candidate.pluginId,
|
|
3062
|
-
dependencyPluginIds: candidate.entry.dependencies.map((dependency) => formatPluginId({
|
|
3063
|
-
sourceId: candidate.source.sourceId,
|
|
3064
|
-
pluginName: dependency,
|
|
3065
|
-
})),
|
|
3066
|
-
}));
|
|
3067
2428
|
const dependencyEnabled = options.command === 'install'
|
|
3068
2429
|
|| options.command === 'sync'
|
|
3069
2430
|
|| options.command === 'reinstall';
|
|
3070
|
-
const intentCommand = options.taskTargets ? 'install' : options.command;
|
|
3071
2431
|
const entryClosure = (roots) => {
|
|
3072
2432
|
const result = [];
|
|
3073
2433
|
const seen = new Set();
|
|
@@ -3138,9 +2498,20 @@ async function runRebuildCommandInSession(options) {
|
|
|
3138
2498
|
}));
|
|
3139
2499
|
const selected = selectedEntries.map((entry) => available.find((candidate) => candidate.pluginId === entry.pluginId));
|
|
3140
2500
|
const selectedIds = new Set(selected.map((entry) => entry.pluginId));
|
|
3141
|
-
const
|
|
3142
|
-
|
|
3143
|
-
|
|
2501
|
+
const codexDemandRootsFor = (entry) => requirements.roots.filter((root) => {
|
|
2502
|
+
if (!root.platforms.includes('codex'))
|
|
2503
|
+
return false;
|
|
2504
|
+
const rootEntry = availableEntries.find((candidate) => candidate.pluginId === root.pluginId);
|
|
2505
|
+
if (!rootEntry || rootEntry.source.sourceId !== entry.source.sourceId)
|
|
2506
|
+
return false;
|
|
2507
|
+
try {
|
|
2508
|
+
return entryClosure([rootEntry]).some((candidate) => candidate.pluginId === entry.pluginId);
|
|
2509
|
+
}
|
|
2510
|
+
catch {
|
|
2511
|
+
return rootEntry.pluginId === entry.pluginId;
|
|
2512
|
+
}
|
|
2513
|
+
});
|
|
2514
|
+
const selectedCodexRoot = (pluginId) => executionInput.selectedTargets.some((target) => target.pluginId === pluginId && target.platform === 'codex');
|
|
3144
2515
|
const resolveClosureEntries = (rootsBySource) => catalog.sources.flatMap((item) => {
|
|
3145
2516
|
const source = item.resolution;
|
|
3146
2517
|
const roots = rootsBySource
|
|
@@ -3157,12 +2528,13 @@ async function runRebuildCommandInSession(options) {
|
|
|
3157
2528
|
});
|
|
3158
2529
|
const closureEntriesByPlatform = new Map();
|
|
3159
2530
|
if (dependencyEnabled) {
|
|
3160
|
-
const
|
|
3161
|
-
|
|
2531
|
+
const selectionTargets = executionInput.selectedTargets;
|
|
2532
|
+
const selectedTaskPlatforms = selectionTargets
|
|
2533
|
+
? [...new Set(selectionTargets.map((target) => target.platform))]
|
|
3162
2534
|
: selectedPlatforms(options.commandOptions.platform);
|
|
3163
2535
|
for (const platform of selectedTaskPlatforms) {
|
|
3164
|
-
const platformRoots =
|
|
3165
|
-
? selected.filter((entry) =>
|
|
2536
|
+
const platformRoots = selectionTargets
|
|
2537
|
+
? selected.filter((entry) => selectionTargets.some((target) => target.pluginId === entry.pluginId && target.platform === platform))
|
|
3166
2538
|
: options.commandOptions.platform === 'both'
|
|
3167
2539
|
? selected.filter((entry) => supportsPlatform(entry.plugin.manifest, platform))
|
|
3168
2540
|
: selected;
|
|
@@ -3174,59 +2546,37 @@ async function runRebuildCommandInSession(options) {
|
|
|
3174
2546
|
: options.command === 'cleanup'
|
|
3175
2547
|
? resolveClosureEntries(selected)
|
|
3176
2548
|
: selected;
|
|
3177
|
-
const
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
2549
|
+
const rawExecutionSelections = executionInput.selectedTargets.flatMap((target) => {
|
|
2550
|
+
const root = selected.find((entry) => entry.pluginId === target.pluginId);
|
|
2551
|
+
if (!root)
|
|
2552
|
+
return [];
|
|
2553
|
+
return (dependencyEnabled ? resolveClosureEntries([root]) : [root]).map((entry) => ({
|
|
2554
|
+
entry, platform: target.platform,
|
|
2555
|
+
...(entry.pluginId === root.pluginId ? { requestedScope: target.scope } : {}),
|
|
2556
|
+
requestedMethod: options.taskTargets?.find((candidate) => candidate.pluginId === entry.pluginId
|
|
2557
|
+
&& candidate.platform === target.platform)?.method
|
|
2558
|
+
?? options.taskRepairTargets?.find((candidate) => candidate.pluginId === entry.pluginId
|
|
2559
|
+
&& candidate.platform === target.platform)?.method,
|
|
2560
|
+
}));
|
|
2561
|
+
});
|
|
2562
|
+
const normalizedExecutionSelections = [...new Map(rawExecutionSelections.map((selection) => [[
|
|
2563
|
+
selection.entry.pluginId,
|
|
2564
|
+
selection.entry.source.sourceIdentity,
|
|
2565
|
+
selection.platform,
|
|
2566
|
+
].join('\0'), selection])).values()];
|
|
2567
|
+
if (dependencyEnabled) {
|
|
2568
|
+
const ordered = new Map();
|
|
2569
|
+
for (const [platform, closure] of closureEntriesByPlatform) {
|
|
2570
|
+
for (const entry of closure) {
|
|
2571
|
+
const selection = normalizedExecutionSelections.find((candidate) => candidate.entry.pluginId === entry.pluginId && candidate.platform === platform);
|
|
2572
|
+
if (selection)
|
|
2573
|
+
ordered.set(`${entry.pluginId}\0${platform}`, selection);
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
normalizedExecutionSelections.splice(0, normalizedExecutionSelections.length, ...ordered.values());
|
|
3181
2577
|
}
|
|
3182
|
-
const rawExecutionSelections = options.taskTargets
|
|
3183
|
-
? options.taskTargets.flatMap((root) => {
|
|
3184
|
-
const rootEntry = selected.find((entry) => entry.pluginId === root.pluginId);
|
|
3185
|
-
return resolveClosureEntries([rootEntry]).flatMap((entry) => {
|
|
3186
|
-
const exactRoots = taskRootsByTarget.get(`${entry.pluginId}\0${root.platform}`) ?? [];
|
|
3187
|
-
if (exactRoots.length > 0) {
|
|
3188
|
-
return exactRoots.map((exactRoot) => ({
|
|
3189
|
-
entry,
|
|
3190
|
-
platform: root.platform,
|
|
3191
|
-
requestedScope: exactRoot.scope,
|
|
3192
|
-
requestedMethod: exactRoot.method,
|
|
3193
|
-
}));
|
|
3194
|
-
}
|
|
3195
|
-
return [{
|
|
3196
|
-
entry,
|
|
3197
|
-
platform: root.platform,
|
|
3198
|
-
requestedMethod: options.taskRepairTargets?.find((target) => target.pluginId === entry.pluginId
|
|
3199
|
-
&& target.platform === root.platform)?.method,
|
|
3200
|
-
}];
|
|
3201
|
-
});
|
|
3202
|
-
})
|
|
3203
|
-
: options.all
|
|
3204
|
-
? liveTargets.flatMap((target) => {
|
|
3205
|
-
const entry = selected.find((candidate) => candidate.pluginId === target.pluginId);
|
|
3206
|
-
if (target.sourceIdentity !== 'unavailable'
|
|
3207
|
-
&& entry.source.sourceIdentity !== target.sourceIdentity) {
|
|
3208
|
-
throw namespacedPreflightError(`sourceChanged: ${target.pluginId} live target has a different source identity.`, liveTargets, legacyLiveTargets);
|
|
3209
|
-
}
|
|
3210
|
-
const sourcePlugins = available
|
|
3211
|
-
.filter((candidate) => candidate.source.sourceId === entry.source.sourceId)
|
|
3212
|
-
.map((candidate) => candidate.plugin);
|
|
3213
|
-
return (options.command === 'uninstall'
|
|
3214
|
-
? [entry.plugin]
|
|
3215
|
-
: resolvePluginMetaDependencyClosure(sourcePlugins, [entry.plugin.manifest.name])).map((plugin) => ({
|
|
3216
|
-
entry: available.find((candidate) => candidate.source.sourceId === entry.source.sourceId
|
|
3217
|
-
&& candidate.plugin.manifest.name === plugin.manifest.name),
|
|
3218
|
-
platform: target.platform,
|
|
3219
|
-
}));
|
|
3220
|
-
})
|
|
3221
|
-
: selectedPlatforms(options.commandOptions.platform).flatMap((platform) => (dependencyEnabled ? closureEntriesByPlatform.get(platform) ?? [] : closureEntries)
|
|
3222
|
-
.flatMap((entry) => options.command !== 'cleanup'
|
|
3223
|
-
&& options.command !== 'uninstall'
|
|
3224
|
-
&& options.commandOptions.platform === 'both'
|
|
3225
|
-
&& !supportsPlatform(entry.plugin.manifest, platform)
|
|
3226
|
-
? []
|
|
3227
|
-
: [{ entry, platform }]));
|
|
3228
2578
|
const taskSelectionMethods = new Map();
|
|
3229
|
-
for (const selection of
|
|
2579
|
+
for (const selection of normalizedExecutionSelections) {
|
|
3230
2580
|
if (!selection.requestedMethod)
|
|
3231
2581
|
continue;
|
|
3232
2582
|
const key = [
|
|
@@ -3240,18 +2590,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
3240
2590
|
}
|
|
3241
2591
|
taskSelectionMethods.set(key, selection.requestedMethod);
|
|
3242
2592
|
}
|
|
3243
|
-
let executionSelections =
|
|
3244
|
-
selection.entry.pluginId,
|
|
3245
|
-
selection.entry.source.sourceIdentity,
|
|
3246
|
-
selection.platform,
|
|
3247
|
-
selection.requestedScope ?? '',
|
|
3248
|
-
].join('\0'), selection])).values()];
|
|
2593
|
+
let executionSelections = normalizedExecutionSelections;
|
|
3249
2594
|
const planTargetFor = (plan, selection) => plan.targets.find((target) => target.pluginId === selection.entry.pluginId
|
|
3250
2595
|
&& target.platform === selection.platform
|
|
3251
|
-
&& (
|
|
3252
|
-
||
|
|
3253
|
-
? target.relation === 'dependency'
|
|
3254
|
-
: target.requestedScope === selection.requestedScope)));
|
|
2596
|
+
&& (selection.requestedScope === undefined
|
|
2597
|
+
|| target.requestedScope === selection.requestedScope));
|
|
3255
2598
|
const executionKey = (selection, plan) => {
|
|
3256
2599
|
const target = planTargetFor(plan, selection);
|
|
3257
2600
|
return [
|
|
@@ -3340,22 +2683,9 @@ async function runRebuildCommandInSession(options) {
|
|
|
3340
2683
|
if (checked.omitted)
|
|
3341
2684
|
stateInventory.errors = checked.inventory.errors;
|
|
3342
2685
|
assertWriteInventoryComplete(checked.inventory);
|
|
3343
|
-
const
|
|
3344
|
-
const
|
|
3345
|
-
|
|
3346
|
-
user: await readPluginIntentState({
|
|
3347
|
-
scope: 'user', cwd: options.commandOptions.cwd, env: runtimeEnv,
|
|
3348
|
-
}),
|
|
3349
|
-
project: await readPluginIntentState({
|
|
3350
|
-
scope: 'project', cwd: options.commandOptions.cwd, env: runtimeEnv,
|
|
3351
|
-
}),
|
|
3352
|
-
}
|
|
3353
|
-
: {
|
|
3354
|
-
user: createEmptyPluginIntentState(),
|
|
3355
|
-
project: createEmptyPluginIntentState(),
|
|
3356
|
-
};
|
|
3357
|
-
const commandProjectKey = await resolveCanonicalRepoProjectKey(options.commandOptions.cwd);
|
|
3358
|
-
const codexScopePathsAlias = codexProjectConfigAliasesUserHome(options.commandOptions.cwd, runtimeEnv);
|
|
2686
|
+
const requirements = executionInput.requirements;
|
|
2687
|
+
const commandProjectKey = executionInput.context.projectRoot ?? executionInput.context.executionCwd;
|
|
2688
|
+
const codexScopePathsAlias = options.commandOptions.scope === 'project' && codexProjectConfigAliasesUserHome(options.commandOptions.cwd, runtimeEnv);
|
|
3359
2689
|
const selectedLegacy = selectedLegacyLiveReferences(stateInventory.references, new Set(executionSelections.map((selection) => selection.platform)), options.commandOptions.scope);
|
|
3360
2690
|
const legacy = options.all
|
|
3361
2691
|
? selectedLegacy
|
|
@@ -3431,24 +2761,17 @@ async function runRebuildCommandInSession(options) {
|
|
|
3431
2761
|
return marketplaceName;
|
|
3432
2762
|
};
|
|
3433
2763
|
const codexObservationScopeByMarketplace = new Map();
|
|
3434
|
-
const
|
|
3435
|
-
|
|
3436
|
-
|
|
3437
|
-
if (!rootEntry)
|
|
3438
|
-
continue;
|
|
3439
|
-
for (const candidate of entryClosure([rootEntry])) {
|
|
3440
|
-
projectIntentPluginIds.add(candidate.pluginId);
|
|
3441
|
-
}
|
|
3442
|
-
}
|
|
3443
|
-
const projectCodexConfig = await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath);
|
|
2764
|
+
const projectCodexConfig = options.commandOptions.scope === 'project'
|
|
2765
|
+
? await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath)
|
|
2766
|
+
: undefined;
|
|
3444
2767
|
for (const { entry, platform } of executionSelections) {
|
|
3445
2768
|
if (platform !== 'codex')
|
|
3446
2769
|
continue;
|
|
3447
2770
|
const marketplaceName = marketplaceNameFor(entry, platform, options.commandOptions.scope);
|
|
3448
2771
|
const codexPluginId = `${entry.plugin.manifest.name}@${marketplaceName}`;
|
|
3449
2772
|
const requiredScope = options.commandOptions.scope === 'project'
|
|
3450
|
-
||
|
|
3451
|
-
|
|
2773
|
+
|| (projectCodexConfig !== undefined
|
|
2774
|
+
&& Object.hasOwn(projectCodexConfig.snapshot.plugins, codexPluginId))
|
|
3452
2775
|
? 'both'
|
|
3453
2776
|
: 'user';
|
|
3454
2777
|
if (requiredScope === 'both'
|
|
@@ -3457,6 +2780,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
3457
2780
|
}
|
|
3458
2781
|
}
|
|
3459
2782
|
const executionContext = {
|
|
2783
|
+
preparedArtifactRenderResults: options.runtime?.preparedArtifactRenderResults,
|
|
2784
|
+
signal: options.runtime?.signal,
|
|
2785
|
+
referencePlugins: options.runtime?.referencePlugins,
|
|
2786
|
+
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
3460
2787
|
env: runtimeEnv,
|
|
3461
2788
|
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
3462
2789
|
codexManager: options.runtime?.codexManager,
|
|
@@ -3467,92 +2794,14 @@ async function runRebuildCommandInSession(options) {
|
|
|
3467
2794
|
codexObservationScopeByMarketplace,
|
|
3468
2795
|
preApplyExecutionCache: options.runtime?.preApplyExecutionCache,
|
|
3469
2796
|
managedCommandProducerCache: options.runtime?.managedCommandProducerCache,
|
|
2797
|
+
preserveLegacyNativeSkills: options.runtime?.preserveLegacyNativeSkills,
|
|
2798
|
+
nativeActivationOnlyTargets: options.runtime?.nativeActivationOnlyTargets,
|
|
3470
2799
|
commandResults: options.runtime?.commandResults,
|
|
3471
2800
|
};
|
|
3472
2801
|
const inspection = createRebuildIntegration({
|
|
3473
2802
|
context: executionContext,
|
|
3474
2803
|
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
3475
2804
|
});
|
|
3476
|
-
const selectedRootsForScope = (plan, scope) => [...new Map(plan.targets.flatMap((target) => target.relation === 'requested'
|
|
3477
|
-
&& (target.requestedScope ?? target.resolvedScope) === scope
|
|
3478
|
-
? [[target.pluginId, {
|
|
3479
|
-
pluginId: target.pluginId,
|
|
3480
|
-
platforms: plan.targets.flatMap((candidate) => candidate.relation === 'requested'
|
|
3481
|
-
&& candidate.pluginId === target.pluginId
|
|
3482
|
-
&& (candidate.requestedScope ?? candidate.resolvedScope) === scope
|
|
3483
|
-
? [candidate.platform]
|
|
3484
|
-
: []),
|
|
3485
|
-
}]]
|
|
3486
|
-
: [])).values()];
|
|
3487
|
-
const intentPlanForPreparedRoots = (plan, preparedKeys, scope) => {
|
|
3488
|
-
const retainedRootKeys = new Set(plan.targets.flatMap((target) => target.relation === 'requested'
|
|
3489
|
-
&& (target.requestedScope ?? target.resolvedScope) === scope
|
|
3490
|
-
&& preparedKeys.has([
|
|
3491
|
-
target.pluginId,
|
|
3492
|
-
target.platform,
|
|
3493
|
-
target.requestedScope ?? target.resolvedScope,
|
|
3494
|
-
].join('\0'))
|
|
3495
|
-
? [[
|
|
3496
|
-
target.pluginId,
|
|
3497
|
-
target.platform,
|
|
3498
|
-
target.requestedScope ?? target.resolvedScope,
|
|
3499
|
-
].join('\0')]
|
|
3500
|
-
: []));
|
|
3501
|
-
const closureKeys = new Set(retainedRootKeys);
|
|
3502
|
-
const pending = [...closureKeys];
|
|
3503
|
-
while (pending.length > 0) {
|
|
3504
|
-
const consumerKey = pending.pop();
|
|
3505
|
-
const consumer = plan.targets.find((target) => [
|
|
3506
|
-
target.pluginId,
|
|
3507
|
-
target.platform,
|
|
3508
|
-
target.requestedScope ?? target.resolvedScope,
|
|
3509
|
-
].join('\0') === consumerKey);
|
|
3510
|
-
if (!consumer)
|
|
3511
|
-
continue;
|
|
3512
|
-
for (const dependency of plan.targets.filter((target) => (target.requiredByTargets ?? []).some((requiredBy) => requiredBy.pluginId === consumer.pluginId
|
|
3513
|
-
&& requiredBy.platform === consumer.platform
|
|
3514
|
-
&& requiredBy.scope === (consumer.requestedScope ?? consumer.resolvedScope)))) {
|
|
3515
|
-
const dependencyKey = [
|
|
3516
|
-
dependency.pluginId,
|
|
3517
|
-
dependency.platform,
|
|
3518
|
-
dependency.requestedScope ?? dependency.resolvedScope,
|
|
3519
|
-
].join('\0');
|
|
3520
|
-
if (closureKeys.has(dependencyKey))
|
|
3521
|
-
continue;
|
|
3522
|
-
closureKeys.add(dependencyKey);
|
|
3523
|
-
pending.push(dependencyKey);
|
|
3524
|
-
}
|
|
3525
|
-
}
|
|
3526
|
-
return {
|
|
3527
|
-
plan: {
|
|
3528
|
-
...plan,
|
|
3529
|
-
requestedPluginIds: plan.requestedPluginIds.filter((pluginId) => plan.targets.some((target) => target.pluginId === pluginId
|
|
3530
|
-
&& retainedRootKeys.has([target.pluginId, target.platform,
|
|
3531
|
-
target.requestedScope ?? target.resolvedScope].join('\0')))),
|
|
3532
|
-
resolvedPluginIds: plan.resolvedPluginIds.filter((pluginId) => plan.targets.some((target) => target.pluginId === pluginId
|
|
3533
|
-
&& closureKeys.has([target.pluginId, target.platform,
|
|
3534
|
-
target.requestedScope ?? target.resolvedScope].join('\0')))),
|
|
3535
|
-
dependencyEdges: plan.dependencyEdges.filter((edge) => plan.targets.some((target) => target.pluginId === edge.from
|
|
3536
|
-
&& target.platform === edge.platform
|
|
3537
|
-
&& closureKeys.has([target.pluginId, target.platform,
|
|
3538
|
-
target.requestedScope ?? target.resolvedScope].join('\0')))
|
|
3539
|
-
&& plan.targets.some((target) => target.pluginId === edge.to
|
|
3540
|
-
&& target.platform === edge.platform
|
|
3541
|
-
&& closureKeys.has([target.pluginId, target.platform,
|
|
3542
|
-
target.requestedScope ?? target.resolvedScope].join('\0')))),
|
|
3543
|
-
scopeOverrides: plan.scopeOverrides.filter((override) => plan.targets.some((target) => target.pluginId === override.pluginId
|
|
3544
|
-
&& target.platform === override.platform
|
|
3545
|
-
&& closureKeys.has([target.pluginId, target.platform,
|
|
3546
|
-
target.requestedScope ?? target.resolvedScope].join('\0')))),
|
|
3547
|
-
targets: plan.targets.filter((target) => closureKeys.has([target.pluginId, target.platform,
|
|
3548
|
-
target.requestedScope ?? target.resolvedScope].join('\0'))),
|
|
3549
|
-
},
|
|
3550
|
-
selectedRoots: selectedRootsForScope(plan, scope).flatMap((root) => {
|
|
3551
|
-
const platforms = root.platforms.filter((platform) => retainedRootKeys.has([root.pluginId, platform, scope].join('\0')));
|
|
3552
|
-
return platforms.length > 0 ? [{ ...root, platforms }] : [];
|
|
3553
|
-
}),
|
|
3554
|
-
};
|
|
3555
|
-
};
|
|
3556
2805
|
let plannedCodexRegistrations = new Map();
|
|
3557
2806
|
let plannedOwnedTextTargets = new Map();
|
|
3558
2807
|
let plannedSkillMarkerTargets = new Map();
|
|
@@ -3594,7 +2843,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
3594
2843
|
const blockingTargets = new Map();
|
|
3595
2844
|
const actualStates = new Map();
|
|
3596
2845
|
const loadPlacementCodexConfigs = async () => {
|
|
3597
|
-
const
|
|
2846
|
+
const user = await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'user', runtimeEnv).configTomlPath);
|
|
2847
|
+
const project = options.commandOptions.scope === 'project'
|
|
2848
|
+
? await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath)
|
|
2849
|
+
: { content: '', snapshot: parseCodexConfig('') };
|
|
3598
2850
|
return { user, project };
|
|
3599
2851
|
};
|
|
3600
2852
|
let placementCodexConfigs;
|
|
@@ -3604,11 +2856,16 @@ async function runRebuildCommandInSession(options) {
|
|
|
3604
2856
|
};
|
|
3605
2857
|
for (const [order, selection] of executionSelections.entries()) {
|
|
3606
2858
|
const { entry, platform } = selection;
|
|
3607
|
-
const relation =
|
|
3608
|
-
?
|
|
3609
|
-
: selectedIds.has(entry.pluginId) ? 'requested' : 'dependency';
|
|
2859
|
+
const relation = executionInput.selectedTargets.some((target) => target.pluginId === entry.pluginId && target.platform === platform)
|
|
2860
|
+
? 'requested' : 'dependency';
|
|
3610
2861
|
const requestedScope = selection.requestedScope ?? options.commandOptions.scope;
|
|
3611
2862
|
const requestedMethod = selection.requestedMethod ?? options.command;
|
|
2863
|
+
const activationOnly = isNativeActivationOnlyTarget(executionContext, {
|
|
2864
|
+
pluginId: entry.pluginId, platform, scope: requestedScope,
|
|
2865
|
+
});
|
|
2866
|
+
const otherScopeRetires = options.runtime?.previewOperationPlan === true
|
|
2867
|
+
&& options.runtime.nativePlannedRetirements?.some((target) => target.pluginId === entry.pluginId && target.platform === platform
|
|
2868
|
+
&& target.scope !== requestedScope) === true;
|
|
3612
2869
|
let resolvedScope = requestedScope;
|
|
3613
2870
|
const inspectScope = async (scope) => {
|
|
3614
2871
|
const marketplaceName = marketplaceNameFor(entry, platform, scope);
|
|
@@ -3677,9 +2934,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
3677
2934
|
const otherScope = resolvedScope === 'user' ? 'project' : 'user';
|
|
3678
2935
|
const [requestedInspection, otherInspection] = await Promise.all([
|
|
3679
2936
|
inspectScope(resolvedScope),
|
|
3680
|
-
|
|
3681
|
-
? Promise.resolve({ state: '
|
|
3682
|
-
:
|
|
2937
|
+
options.commandOptions.scope === 'user'
|
|
2938
|
+
? Promise.resolve({ state: 'partial', components: [], errors: [] })
|
|
2939
|
+
: platform === 'codex' && codexScopePathsAlias && resolvedScope === 'user'
|
|
2940
|
+
? Promise.resolve({ state: 'absent', components: [], errors: [] })
|
|
2941
|
+
: inspectScope(otherScope),
|
|
3683
2942
|
]);
|
|
3684
2943
|
const surface = platform === 'codex'
|
|
3685
2944
|
? analyzeCodexSurface(entry.plugin.manifest)
|
|
@@ -3743,9 +3002,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
3743
3002
|
: ['project', 'user'];
|
|
3744
3003
|
if (allowedScopes.length === 0)
|
|
3745
3004
|
allowedScopes.push(requestedScope);
|
|
3746
|
-
const hasWiderDesiredRoot = relation === 'dependency'
|
|
3747
|
-
&& requestedScope === 'project'
|
|
3748
|
-
&& intentBeforeByScope.user.roots.some((root) => root.pluginId === entry.pluginId && root.platforms.includes(platform));
|
|
3749
3005
|
if (!placementNodes.some((node) => node.pluginId === entry.pluginId && node.platform === platform)) {
|
|
3750
3006
|
placementNodes.push({
|
|
3751
3007
|
pluginId: entry.pluginId,
|
|
@@ -3754,16 +3010,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
3754
3010
|
relation,
|
|
3755
3011
|
depth: order,
|
|
3756
3012
|
allowedScopes,
|
|
3757
|
-
...(relation === 'dependency'
|
|
3758
|
-
&& requestedScope === 'project'
|
|
3759
|
-
&& (otherPlacementState === 'present' || hasWiderDesiredRoot)
|
|
3760
|
-
? {
|
|
3761
|
-
preferredScope: 'user',
|
|
3762
|
-
...(otherPlacementState === 'present'
|
|
3763
|
-
? { preferredScopeReason: 'existingWiderTarget' }
|
|
3764
|
-
: {}),
|
|
3765
|
-
}
|
|
3766
|
-
: {}),
|
|
3767
3013
|
});
|
|
3768
3014
|
}
|
|
3769
3015
|
let state = requestedPlacementState;
|
|
@@ -3773,13 +3019,20 @@ async function runRebuildCommandInSession(options) {
|
|
|
3773
3019
|
: requestedMethod === 'reinstall' ? 'reinstall' : 'install'
|
|
3774
3020
|
: requestedMethod === 'reinstall' ? 'reinstall' : 'install';
|
|
3775
3021
|
let errorCode;
|
|
3776
|
-
if (dependencyEnabled
|
|
3022
|
+
if (!dependencyEnabled && platform === 'codex'
|
|
3023
|
+
&& relation === 'requested'
|
|
3024
|
+
&& codexDemandRootsFor(entry).some((root) => !selectedCodexRoot(root.pluginId))) {
|
|
3025
|
+
action = 'block';
|
|
3026
|
+
errorCode = 'dependencyStillRequired';
|
|
3027
|
+
}
|
|
3028
|
+
else if (dependencyEnabled
|
|
3777
3029
|
&& platform === 'codex'
|
|
3778
3030
|
&& relation === 'requested'
|
|
3031
|
+
&& !activationOnly
|
|
3032
|
+
&& !otherScopeRetires
|
|
3779
3033
|
&& surface?.scopeOverlap === 'aw-owned-conflict'
|
|
3780
|
-
&& options.command !== '
|
|
3781
|
-
&&
|
|
3782
|
-
&& intentBeforeByScope[otherScope].roots.some((root) => root.pluginId === entry.pluginId && root.platforms.includes(platform)))
|
|
3034
|
+
&& options.command !== 'cleanup'
|
|
3035
|
+
&& options.command !== 'uninstall'
|
|
3783
3036
|
&& otherInspection.components.some((component) => component.state !== 'absent'
|
|
3784
3037
|
&& component.component.kind !== 'native-plugin'
|
|
3785
3038
|
&& !component.component.identity.artifactKey.startsWith('activation-')
|
|
@@ -3790,6 +3043,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
3790
3043
|
else if (dependencyEnabled && relation === 'requested'
|
|
3791
3044
|
&& (requestedInspection.state === 'error'
|
|
3792
3045
|
|| (requestedInspection.state === 'partial'
|
|
3046
|
+
&& !activationOnly
|
|
3793
3047
|
&& platform !== 'codex'
|
|
3794
3048
|
&& requestedMethod !== 'reinstall'
|
|
3795
3049
|
&& options.command !== 'cleanup'))) {
|
|
@@ -3797,34 +3051,33 @@ async function runRebuildCommandInSession(options) {
|
|
|
3797
3051
|
errorCode = 'dependencyNotReady';
|
|
3798
3052
|
}
|
|
3799
3053
|
if (relation === 'dependency'
|
|
3800
|
-
&& requestedPlacementState === 'present'
|
|
3801
|
-
&& otherPlacementState === 'present') {
|
|
3802
|
-
action = 'block';
|
|
3803
|
-
state = 'partial';
|
|
3804
|
-
errorCode = 'dependencyScopeConflict';
|
|
3805
|
-
}
|
|
3806
|
-
else if (relation === 'dependency'
|
|
3807
|
-
&& requestedScope === 'project'
|
|
3808
|
-
&& otherInspection.state === 'present') {
|
|
3809
|
-
resolvedScope = 'user';
|
|
3810
|
-
state = 'present';
|
|
3811
|
-
}
|
|
3812
|
-
else if (relation === 'dependency'
|
|
3813
|
-
&& requestedScope === 'project'
|
|
3814
|
-
&& (otherPlacementState === 'partial' || otherPlacementState === 'error')) {
|
|
3815
|
-
resolvedScope = 'user';
|
|
3816
|
-
state = otherPlacementState;
|
|
3817
|
-
if (otherPlacementState === 'error') {
|
|
3818
|
-
action = 'block';
|
|
3819
|
-
errorCode = 'dependencyNotReady';
|
|
3820
|
-
}
|
|
3821
|
-
}
|
|
3822
|
-
else if (relation === 'dependency'
|
|
3823
3054
|
&& requestedScope === 'user'
|
|
3824
3055
|
&& otherPlacementState === 'error') {
|
|
3825
3056
|
action = 'block';
|
|
3826
3057
|
errorCode = 'dependencyNotReady';
|
|
3827
3058
|
}
|
|
3059
|
+
const dependencyScopeOverride = relation === 'dependency'
|
|
3060
|
+
? [
|
|
3061
|
+
...(options.commandOptions.dependencyScopeOverrides ?? []),
|
|
3062
|
+
...(requirements.dependencyScopeOverrides ?? []),
|
|
3063
|
+
].find((override) => override.pluginId === entry.pluginId
|
|
3064
|
+
&& (override.platform === undefined || override.platform === platform))
|
|
3065
|
+
: undefined;
|
|
3066
|
+
if (dependencyEnabled && relation === 'dependency' && platform === 'codex'
|
|
3067
|
+
&& !activationOnly
|
|
3068
|
+
&& !otherScopeRetires
|
|
3069
|
+
&& surface?.scopeOverlap === 'aw-owned-conflict'
|
|
3070
|
+
&& (dependencyScopeOverride?.scope ?? requestedScope) === requestedScope
|
|
3071
|
+
&& !(requestedScope === 'project'
|
|
3072
|
+
&& dependencyScopeOverride?.scope === 'project'
|
|
3073
|
+
&& otherPlacementState === 'present')
|
|
3074
|
+
&& otherInspection.components.some((component) => component.state !== 'absent'
|
|
3075
|
+
&& component.component.kind !== 'native-plugin'
|
|
3076
|
+
&& !component.component.identity.artifactKey.startsWith('activation-')
|
|
3077
|
+
&& !component.component.identity.artifactKey.startsWith('marketplace-'))) {
|
|
3078
|
+
action = 'block';
|
|
3079
|
+
errorCode = 'codexExtensionScopeConflict';
|
|
3080
|
+
}
|
|
3828
3081
|
const resolvedInspection = resolvedScope === requestedScope
|
|
3829
3082
|
? requestedInspection
|
|
3830
3083
|
: otherInspection;
|
|
@@ -3871,6 +3124,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
3871
3124
|
manifest: entry.plugin.manifest,
|
|
3872
3125
|
referencePlugins: options.runtime?.referencePlugins,
|
|
3873
3126
|
scope,
|
|
3127
|
+
platform,
|
|
3874
3128
|
cwd: options.commandOptions.cwd,
|
|
3875
3129
|
env: runtimeEnv,
|
|
3876
3130
|
})));
|
|
@@ -3913,21 +3167,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
3913
3167
|
const placement = createDependencyPlacementPlan({
|
|
3914
3168
|
requestedPluginIds: selected.map((entry) => entry.pluginId),
|
|
3915
3169
|
nodes: placementNodes,
|
|
3916
|
-
roots:
|
|
3917
|
-
|
|
3918
|
-
|
|
3919
|
-
|
|
3920
|
-
|
|
3921
|
-
scope: selection.requestedScope,
|
|
3922
|
-
}]
|
|
3923
|
-
: [])
|
|
3924
|
-
: placementNodes.flatMap((node) => selectedIds.has(node.pluginId)
|
|
3925
|
-
? [{
|
|
3926
|
-
pluginId: node.pluginId,
|
|
3927
|
-
platform: node.platform,
|
|
3928
|
-
scope: options.commandOptions.scope,
|
|
3929
|
-
}]
|
|
3930
|
-
: []),
|
|
3170
|
+
roots: executionInput.selectedTargets.map((target) => ({
|
|
3171
|
+
pluginId: target.pluginId,
|
|
3172
|
+
platform: target.platform,
|
|
3173
|
+
scope: target.scope,
|
|
3174
|
+
})),
|
|
3931
3175
|
dependencyEdges: closureEntries.flatMap((entry) => (entry.plugin.manifest.dependencies ?? []).flatMap((dependency) => {
|
|
3932
3176
|
const dependencyId = formatPluginId({
|
|
3933
3177
|
sourceId: entry.source.sourceId,
|
|
@@ -3939,13 +3183,17 @@ async function runRebuildCommandInSession(options) {
|
|
|
3939
3183
|
: []);
|
|
3940
3184
|
})),
|
|
3941
3185
|
scopeOverrides: effectiveDependencyScopeOverrides({
|
|
3942
|
-
state:
|
|
3186
|
+
state: requirements,
|
|
3943
3187
|
explicit: options.commandOptions
|
|
3944
3188
|
.dependencyScopeOverrides ?? [],
|
|
3945
3189
|
nodes: placementNodes,
|
|
3946
3190
|
ignoredPersistedRootIds: selectedIds,
|
|
3947
3191
|
}),
|
|
3948
3192
|
});
|
|
3193
|
+
if (options.commandOptions.scope === 'user'
|
|
3194
|
+
&& placement.targets.some((target) => target.resolvedScope === 'project')) {
|
|
3195
|
+
throw new Error('nativeUserProjectPlacementUnsupported: User execution cannot use project output.');
|
|
3196
|
+
}
|
|
3949
3197
|
for (const repairTarget of options.taskRepairTargets ?? []) {
|
|
3950
3198
|
if (!placement.targets.some((target) => target.pluginId === repairTarget.pluginId
|
|
3951
3199
|
&& target.platform === repairTarget.platform)) {
|
|
@@ -3970,34 +3218,21 @@ async function runRebuildCommandInSession(options) {
|
|
|
3970
3218
|
?? options.taskRepairTargets?.find((candidate) => candidate.pluginId === target.pluginId
|
|
3971
3219
|
&& candidate.platform === target.platform)?.method
|
|
3972
3220
|
?? options.command;
|
|
3973
|
-
const otherScope = target.resolvedScope === 'user' ? 'project' : 'user';
|
|
3974
|
-
const otherState = actualStates.get(`${target.pluginId}\0${target.platform}\0${otherScope}`);
|
|
3975
|
-
const movesExistingPlacement = target.relation === 'dependency'
|
|
3976
|
-
&& target.resolvedScope === 'user'
|
|
3977
|
-
&& (state === 'absent' || state === 'partial')
|
|
3978
|
-
&& (otherState === 'present' || otherState === 'partial');
|
|
3979
|
-
const preservesWiderPlacement = target.relation === 'dependency'
|
|
3980
|
-
&& target.resolvedScope === 'project'
|
|
3981
|
-
&& (state === 'absent' || state === 'partial')
|
|
3982
|
-
&& (otherState === 'present' || otherState === 'partial');
|
|
3983
3221
|
const action = errorCode
|
|
3984
3222
|
? 'block'
|
|
3985
3223
|
: options.command === 'cleanup' || options.command === 'uninstall'
|
|
3986
3224
|
? 'keep'
|
|
3987
|
-
:
|
|
3988
|
-
? '
|
|
3989
|
-
:
|
|
3990
|
-
? '
|
|
3991
|
-
:
|
|
3992
|
-
? 'reinstall'
|
|
3993
|
-
: 'install';
|
|
3225
|
+
: target.relation === 'dependency' && state === 'present'
|
|
3226
|
+
? 'keep'
|
|
3227
|
+
: state === 'partial' || requestedMethod === 'reinstall'
|
|
3228
|
+
? 'reinstall'
|
|
3229
|
+
: 'install';
|
|
3994
3230
|
return {
|
|
3995
3231
|
...prior,
|
|
3996
3232
|
scope: targetScope,
|
|
3997
3233
|
state,
|
|
3998
3234
|
action,
|
|
3999
3235
|
...(errorCode ? { errorCode } : {}),
|
|
4000
|
-
...(preservesWiderPlacement ? { preservedScope: 'user' } : {}),
|
|
4001
3236
|
};
|
|
4002
3237
|
}),
|
|
4003
3238
|
});
|
|
@@ -4014,10 +3249,12 @@ async function runRebuildCommandInSession(options) {
|
|
|
4014
3249
|
});
|
|
4015
3250
|
return createReconcileOperationPlan({ placement: directPlacement, actual: targets });
|
|
4016
3251
|
};
|
|
3252
|
+
const isHealthyWiderDependency = (target) => target.relation === 'dependency'
|
|
3253
|
+
&& target.resolvedScope !== options.commandOptions.scope
|
|
3254
|
+
&& target.action === 'keep';
|
|
4017
3255
|
const createCodexPlans = async (plan, activationSupport = 'observed', codexManager) => {
|
|
4018
3256
|
const codexTargets = plan.targets.filter((target) => target.platform === 'codex');
|
|
4019
3257
|
const currentScope = options.commandOptions.scope;
|
|
4020
|
-
const otherScope = currentScope === 'user' ? 'project' : 'user';
|
|
4021
3258
|
const reconciledCodexTargetsByPlugin = new Map();
|
|
4022
3259
|
for (const target of codexTargets) {
|
|
4023
3260
|
if (!reconciledCodexTargetsByPlugin.has(target.pluginId)
|
|
@@ -4028,99 +3265,22 @@ async function runRebuildCommandInSession(options) {
|
|
|
4028
3265
|
const reconciledCodexTargets = [...reconciledCodexTargetsByPlugin.values()];
|
|
4029
3266
|
if (reconciledCodexTargets.length === 0)
|
|
4030
3267
|
return [];
|
|
4031
|
-
const beforeByScope = intentBeforeByScope;
|
|
4032
|
-
const afterByScope = {
|
|
4033
|
-
user: beforeByScope.user,
|
|
4034
|
-
project: beforeByScope.project,
|
|
4035
|
-
};
|
|
4036
|
-
for (const scope of ['user', 'project']) {
|
|
4037
|
-
const selectedRoots = selectedRootsForScope(plan, scope);
|
|
4038
|
-
afterByScope[scope] = deriveDesiredIntentState({
|
|
4039
|
-
command: intentCommand,
|
|
4040
|
-
state: beforeByScope[scope],
|
|
4041
|
-
selectedRoots,
|
|
4042
|
-
plan,
|
|
4043
|
-
catalogEntries: intentCatalogEntries,
|
|
4044
|
-
});
|
|
4045
|
-
}
|
|
4046
|
-
if (options.command === 'install') {
|
|
4047
|
-
for (const scope of ['user', 'project']) {
|
|
4048
|
-
const relatedScope = scope === 'user' ? 'project' : 'user';
|
|
4049
|
-
const protectedRoots = new Set(selectedRootsForScope(plan, relatedScope)
|
|
4050
|
-
.flatMap((root) => root.platforms.map((platform) => `${root.pluginId}\0${platform}`)));
|
|
4051
|
-
const selectedRoots = selectedRootsForScope(plan, scope).flatMap((root) => {
|
|
4052
|
-
const platforms = root.platforms.filter((platform) => !protectedRoots.has(`${root.pluginId}\0${platform}`));
|
|
4053
|
-
return platforms.length > 0 ? [{ ...root, platforms }] : [];
|
|
4054
|
-
});
|
|
4055
|
-
afterByScope[relatedScope] = removeSelectedRootPlatformsFromOtherScope({
|
|
4056
|
-
state: afterByScope[relatedScope],
|
|
4057
|
-
selectedRoots,
|
|
4058
|
-
preserveCodexRootIds: preserveOtherCodexScopeRootIds,
|
|
4059
|
-
});
|
|
4060
|
-
}
|
|
4061
|
-
}
|
|
4062
3268
|
const desiredScopesForEntry = (entry) => {
|
|
4063
|
-
const
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
try {
|
|
4072
|
-
closure = entryClosure([rootEntry]);
|
|
4073
|
-
}
|
|
4074
|
-
catch {
|
|
4075
|
-
closure = [rootEntry];
|
|
4076
|
-
}
|
|
4077
|
-
if (!closure.some((candidate) => candidate.pluginId === entry.pluginId)) {
|
|
4078
|
-
continue;
|
|
4079
|
-
}
|
|
4080
|
-
const currentPlannedScope = selectedRootsForScope(plan, intentScope)
|
|
4081
|
-
.some((selectedRoot) => selectedRoot.pluginId === root.pluginId)
|
|
4082
|
-
? plan.targets.find((target) => target.pluginId === entry.pluginId
|
|
4083
|
-
&& target.platform === 'codex'
|
|
4084
|
-
&& (target.relation === 'dependency'
|
|
4085
|
-
|| target.requestedScope === intentScope))?.resolvedScope
|
|
4086
|
-
: undefined;
|
|
4087
|
-
const override = intent.dependencyScopeOverrides.find((candidate) => candidate.pluginId === entry.pluginId && candidate.platform === 'codex');
|
|
4088
|
-
const reusedUserDependency = intentScope === 'project'
|
|
4089
|
-
&& root.pluginId !== entry.pluginId
|
|
4090
|
-
&& scopes.has('user');
|
|
4091
|
-
scopes.add(currentPlannedScope
|
|
4092
|
-
?? override?.scope
|
|
4093
|
-
?? (reusedUserDependency ? 'user' : intentScope));
|
|
4094
|
-
}
|
|
4095
|
-
}
|
|
4096
|
-
return [...scopes].sort();
|
|
4097
|
-
};
|
|
4098
|
-
const intentScopesForEntry = (entry) => {
|
|
4099
|
-
const scopes = new Set();
|
|
4100
|
-
for (const intentScope of ['user', 'project']) {
|
|
4101
|
-
for (const root of afterByScope[intentScope].roots.filter((candidate) => candidate.platforms.includes('codex'))) {
|
|
4102
|
-
const rootEntry = availableEntries.find((candidate) => candidate.pluginId === root.pluginId);
|
|
4103
|
-
if (!rootEntry || rootEntry.source.sourceId !== entry.source.sourceId)
|
|
4104
|
-
continue;
|
|
4105
|
-
let closure;
|
|
4106
|
-
try {
|
|
4107
|
-
closure = entryClosure([rootEntry]);
|
|
4108
|
-
}
|
|
4109
|
-
catch {
|
|
4110
|
-
closure = [rootEntry];
|
|
4111
|
-
}
|
|
4112
|
-
if (closure.some((candidate) => candidate.pluginId === entry.pluginId)) {
|
|
4113
|
-
scopes.add(intentScope);
|
|
4114
|
-
}
|
|
4115
|
-
}
|
|
4116
|
-
}
|
|
4117
|
-
return [...scopes].sort();
|
|
3269
|
+
const roots = codexDemandRootsFor(entry);
|
|
3270
|
+
const protectedRoot = roots.some((root) => !selectedCodexRoot(root.pluginId));
|
|
3271
|
+
const selectedForRemoval = selectedCodexRoot(entry.pluginId);
|
|
3272
|
+
if ((options.command === 'cleanup' || options.command === 'uninstall')
|
|
3273
|
+
&& (roots.length === 0 || (selectedForRemoval && !protectedRoot)))
|
|
3274
|
+
return [];
|
|
3275
|
+
const planned = plan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === 'codex');
|
|
3276
|
+
return [planned?.resolvedScope ?? currentScope];
|
|
4118
3277
|
};
|
|
4119
|
-
const
|
|
4120
|
-
const
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
3278
|
+
const intentScopesForEntry = (entry) => codexDemandRootsFor(entry).length > 0 ? [currentScope] : [];
|
|
3279
|
+
const inspectBothScopes = currentScope === 'project';
|
|
3280
|
+
const userConfig = await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'user', runtimeEnv).configTomlPath);
|
|
3281
|
+
const projectConfig = currentScope === 'project'
|
|
3282
|
+
? await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath)
|
|
3283
|
+
: { content: '', snapshot: parseCodexConfig('') };
|
|
4124
3284
|
const catalogClosure = [];
|
|
4125
3285
|
const liveEvidence = [];
|
|
4126
3286
|
const desiredScopesByPluginId = new Map();
|
|
@@ -4142,12 +3302,22 @@ async function runRebuildCommandInSession(options) {
|
|
|
4142
3302
|
}
|
|
4143
3303
|
for (const planned of reconciledCodexTargets) {
|
|
4144
3304
|
const entry = available.find((candidate) => candidate.pluginId === planned.pluginId);
|
|
4145
|
-
const
|
|
3305
|
+
const activationOnly = isNativeActivationOnlyTarget(executionContext, {
|
|
3306
|
+
pluginId: entry.pluginId, platform: 'codex', scope: planned.resolvedScope,
|
|
3307
|
+
});
|
|
3308
|
+
const declaredSurface = analyzeCodexSurface(entry.plugin.manifest);
|
|
3309
|
+
const surface = activationOnly ? {
|
|
3310
|
+
...declaredSurface,
|
|
3311
|
+
components: declaredSurface.components.filter((component) => component.owner === 'codex-native'),
|
|
3312
|
+
extensionKinds: [],
|
|
3313
|
+
classification: 'native',
|
|
3314
|
+
deliveryOwner: 'codex-native',
|
|
3315
|
+
scopeOverlap: 'native-compatible',
|
|
3316
|
+
} : declaredSurface;
|
|
4146
3317
|
const marketplaceName = marketplaceNameFor(entry, 'codex', planned.resolvedScope);
|
|
4147
3318
|
const codexPluginId = `${entry.plugin.manifest.name}@${marketplaceName}`;
|
|
4148
3319
|
const hasNativeRenderTargets = (entry.plugin.manifest.artifacts?.targets ?? []).some((target) => target.platform === 'codex'
|
|
4149
|
-
&& target.target === 'codex.skill'
|
|
4150
|
-
&& target.delivery?.mode === 'codex-native');
|
|
3320
|
+
&& target.target === 'codex.skill');
|
|
4151
3321
|
const staticContentDigest = hasNativeRenderTargets
|
|
4152
3322
|
? undefined
|
|
4153
3323
|
: await calculateCodexSharedNativePayloadDigest(entry.plugin.rootDir);
|
|
@@ -4190,11 +3360,21 @@ async function runRebuildCommandInSession(options) {
|
|
|
4190
3360
|
resolvedScope: planned.resolvedScope,
|
|
4191
3361
|
desiredScopes,
|
|
4192
3362
|
intentScopes,
|
|
3363
|
+
executionScopes: [...new Set(codexTargets.filter((target) => target.pluginId === entry.pluginId).map((target) => target.resolvedScope))],
|
|
4193
3364
|
surface,
|
|
4194
3365
|
});
|
|
4195
3366
|
let sharedNative = sharedInspection?.sharedNative
|
|
4196
3367
|
?? { state: 'unobserved' };
|
|
4197
|
-
if (
|
|
3368
|
+
if (activationOnly && sharedNative.state !== 'usable') {
|
|
3369
|
+
if (options.runtime?.previewOperationPlan && sharedNative.state !== 'blocked') {
|
|
3370
|
+
// The joint request can establish its User provider before this target executes.
|
|
3371
|
+
sharedNative = { state: 'usable' };
|
|
3372
|
+
}
|
|
3373
|
+
else {
|
|
3374
|
+
throw new Error('nativeActivationOnlyRequiresHealthySharedPackage: the shared Native package must be current and owned before scope activation.');
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
if (!activationOnly && options.command === 'sync' && sharedNative.state === 'usable'
|
|
4198
3378
|
&& await hasPreparedStaticNativeCommandDrift({ plugin: entry.plugin,
|
|
4199
3379
|
cwd: options.commandOptions.cwd, env: runtimeEnv, context: executionContext,
|
|
4200
3380
|
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId) })) {
|
|
@@ -4282,50 +3462,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
4282
3462
|
scope: currentScope,
|
|
4283
3463
|
cwd: options.commandOptions.cwd,
|
|
4284
3464
|
operation: options.command,
|
|
4285
|
-
intentBefore: beforeByScope[currentScope],
|
|
4286
|
-
intentAfter: afterByScope[currentScope],
|
|
4287
|
-
relatedIntentBefore: beforeByScope[otherScope],
|
|
4288
|
-
relatedIntentAfter: afterByScope[otherScope],
|
|
4289
3465
|
catalogClosure,
|
|
4290
3466
|
liveEvidence,
|
|
4291
3467
|
activationSupport,
|
|
4292
3468
|
});
|
|
4293
|
-
|
|
4294
|
-
? [[target.pluginId, target.preservedScope]]
|
|
4295
|
-
: []));
|
|
4296
|
-
if (preservedScopes.size === 0)
|
|
4297
|
-
return [codexPlan];
|
|
4298
|
-
const preservedNativePluginIds = new Set(catalogClosure.flatMap((target) => (options.command === 'install' || options.command === 'reinstall')
|
|
4299
|
-
&& preservedScopes.get(target.pluginId) === 'user'
|
|
4300
|
-
&& liveEvidence.find((evidence) => evidence.codexPluginId === target.codexPluginId)?.activations.user === true
|
|
4301
|
-
? [target.pluginId]
|
|
4302
|
-
: []));
|
|
4303
|
-
const preservedCodexIds = new Set(codexPlan.sharedNativeActions.flatMap((action) => preservedNativePluginIds.has(action.pluginId) ? [action.codexPluginId] : []));
|
|
4304
|
-
return [{
|
|
4305
|
-
...codexPlan,
|
|
4306
|
-
desiredTargets: codexPlan.desiredTargets.map((target) => {
|
|
4307
|
-
const preservedScope = preservedNativePluginIds.has(target.pluginId)
|
|
4308
|
-
? preservedScopes.get(target.pluginId)
|
|
4309
|
-
: undefined;
|
|
4310
|
-
return preservedScope
|
|
4311
|
-
? { ...target, scopes: [...new Set([...target.scopes, preservedScope])].sort() }
|
|
4312
|
-
: target;
|
|
4313
|
-
}),
|
|
4314
|
-
activationActions: {
|
|
4315
|
-
user: codexPlan.activationActions.user.map((action) => preservedNativePluginIds.has(action.pluginId)
|
|
4316
|
-
? { ...action, action: 'none', desired: true }
|
|
4317
|
-
: action),
|
|
4318
|
-
project: codexPlan.activationActions.project,
|
|
4319
|
-
},
|
|
4320
|
-
extensionRemovals: codexPlan.extensionRemovals.filter((action) => preservedScopes.get(action.pluginId) !== action.scope),
|
|
4321
|
-
staleActivationRemovals: codexPlan.staleActivationRemovals.filter((action) => !(action.scope === 'user' && preservedCodexIds.has(action.codexPluginId))),
|
|
4322
|
-
postcheck: {
|
|
4323
|
-
...codexPlan.postcheck,
|
|
4324
|
-
plugins: codexPlan.postcheck.plugins.map((plugin) => preservedNativePluginIds.has(plugin.pluginId)
|
|
4325
|
-
? { ...plugin, expectedUserEnabled: true }
|
|
4326
|
-
: plugin),
|
|
4327
|
-
},
|
|
4328
|
-
}];
|
|
3469
|
+
return [codexPlan];
|
|
4329
3470
|
};
|
|
4330
3471
|
const operationNeedsNativeCli = async (platform, plan) => {
|
|
4331
3472
|
for (const { entry, platform: selectedPlatform } of executionSelections) {
|
|
@@ -4354,9 +3495,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
4354
3495
|
scope,
|
|
4355
3496
|
cwd: options.commandOptions.cwd,
|
|
4356
3497
|
command: dependencyEnabled
|
|
4357
|
-
? planned.action
|
|
4358
|
-
? planned.state === 'partial' ? 'reinstall' : 'install'
|
|
4359
|
-
: planned.action
|
|
3498
|
+
? planned.action
|
|
4360
3499
|
: options.command,
|
|
4361
3500
|
catalog: toCatalogResolution(entry.source),
|
|
4362
3501
|
readOnlyInspectionPlan: true,
|
|
@@ -4394,27 +3533,19 @@ async function runRebuildCommandInSession(options) {
|
|
|
4394
3533
|
const key = executionKey(selection, plan);
|
|
4395
3534
|
if (planned.action === 'block')
|
|
4396
3535
|
continue;
|
|
4397
|
-
const
|
|
4398
|
-
&&
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
&& options.command === 'sync'
|
|
4402
|
-
&& codexPlans.some((codexPlan) => codexPlan.desiredTargets.some((target) => target.pluginId === entry.pluginId && !target.scopes.includes(planned.resolvedScope)));
|
|
4403
|
-
const buildCommand = reconcileObsolete
|
|
4404
|
-
? 'cleanup'
|
|
4405
|
-
: desiredCleanup || planned.action === 'move'
|
|
4406
|
-
? planned.state === 'partial' ? 'reinstall' : 'install'
|
|
4407
|
-
: planned.relation === 'dependency'
|
|
4408
|
-
&& (planned.action === 'install' || planned.action === 'reinstall')
|
|
4409
|
-
? planned.action
|
|
4410
|
-
: selection.requestedMethod ?? options.command;
|
|
3536
|
+
const buildCommand = planned.relation === 'dependency'
|
|
3537
|
+
&& (planned.action === 'install' || planned.action === 'reinstall')
|
|
3538
|
+
? planned.action
|
|
3539
|
+
: selection.requestedMethod ?? options.command;
|
|
4411
3540
|
const plannedNative = platform === 'codex'
|
|
4412
3541
|
? codexPlans.flatMap((codexPlan) => codexPlan.sharedNativeActions).find((action) => action.pluginId === entry.pluginId)
|
|
4413
3542
|
: undefined;
|
|
4414
3543
|
const codexNativeStillDesired = platform === 'codex'
|
|
4415
3544
|
&& codexPlans.some((codexPlan) => codexPlan.desiredTargets.some((target) => target.pluginId === entry.pluginId && target.scopes.length > 0));
|
|
4416
3545
|
const preserveSharedNative = plannedNative?.action === 'reuse'
|
|
4417
|
-
|| (plannedNative?.action === 'none' && codexNativeStillDesired)
|
|
3546
|
+
|| (plannedNative?.action === 'none' && codexNativeStillDesired)
|
|
3547
|
+
|| options.command === 'cleanup'
|
|
3548
|
+
|| options.command === 'uninstall';
|
|
4418
3549
|
const marketplaceName = marketplaceNameFor(entry, platform, planned.resolvedScope);
|
|
4419
3550
|
try {
|
|
4420
3551
|
const target = await measureCommandPerformanceStage(options.runtime, 'target.build', () => integration.buildTarget({
|
|
@@ -4429,6 +3560,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
4429
3560
|
cwd: options.commandOptions.cwd,
|
|
4430
3561
|
command: buildCommand,
|
|
4431
3562
|
catalog: toCatalogResolution(entry.source),
|
|
3563
|
+
...(platform === 'codex'
|
|
3564
|
+
&& (buildCommand === 'cleanup' || buildCommand === 'uninstall')
|
|
3565
|
+
? { includeNativeCleanupCandidate: false }
|
|
3566
|
+
: {}),
|
|
4432
3567
|
}));
|
|
4433
3568
|
if (plannedNative) {
|
|
4434
3569
|
const writesSharedNative = plannedNative.action === 'install'
|
|
@@ -4459,12 +3594,9 @@ async function runRebuildCommandInSession(options) {
|
|
|
4459
3594
|
target.codexNativeObservationExpectation = preserveSharedNative && hasExtensionMutation
|
|
4460
3595
|
? (plannedNative.action === 'reuse' ? 'installed' : 'observed')
|
|
4461
3596
|
: undefined;
|
|
4462
|
-
const removesSharedNative = !writesSharedNative
|
|
4463
|
-
&& !preserveSharedNative
|
|
4464
|
-
&& (buildCommand === 'cleanup' || buildCommand === 'uninstall');
|
|
4465
3597
|
target.codexNativeSensitivePreflightRequired = preserveSharedNative
|
|
4466
3598
|
&& hasActivationMutation;
|
|
4467
|
-
if (!writesSharedNative
|
|
3599
|
+
if (!writesSharedNative) {
|
|
4468
3600
|
const isSharedNativeComponent = (component) => component.kind === 'native-plugin'
|
|
4469
3601
|
|| (component.kind === 'shared-config'
|
|
4470
3602
|
&& component.identity.artifactKey.startsWith('marketplace-'));
|
|
@@ -4501,6 +3633,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
4501
3633
|
});
|
|
4502
3634
|
}
|
|
4503
3635
|
catch (error) {
|
|
3636
|
+
options.runtime?.signal?.throwIfAborted();
|
|
3637
|
+
if (error instanceof Error && error.name === 'AbortError'
|
|
3638
|
+
|| readSafeOperationError(error))
|
|
3639
|
+
throw error;
|
|
4504
3640
|
preparedTargetErrors.set(key, error);
|
|
4505
3641
|
}
|
|
4506
3642
|
}
|
|
@@ -4520,15 +3656,15 @@ async function runRebuildCommandInSession(options) {
|
|
|
4520
3656
|
for (const scope of pluginConfigTargetRenderScopes(entry.plugin, {
|
|
4521
3657
|
pluginName: entry.plugin.manifest.name, platform: selection.platform, scope: planned.resolvedScope,
|
|
4522
3658
|
}))
|
|
4523
|
-
configTargets.set(`${entry.pluginId}\0${scope}`, { entry, scope });
|
|
3659
|
+
configTargets.set(`${entry.pluginId}\0${selection.platform}\0${scope}`, { entry, scope, platform: selection.platform });
|
|
4524
3660
|
for (const action of preparedTargets.get(executionKey(selection, plan)).target.operationActions ?? []) {
|
|
4525
3661
|
if (action.kind === 'runPreApply' && action.pluginId === entry.pluginId) {
|
|
4526
|
-
configTargets.set(`${entry.pluginId}\0${action.scope}`, { entry, scope: action.scope });
|
|
3662
|
+
configTargets.set(`${entry.pluginId}\0${selection.platform}\0${action.scope}`, { entry, scope: action.scope, platform: selection.platform });
|
|
4527
3663
|
}
|
|
4528
3664
|
}
|
|
4529
3665
|
}
|
|
4530
3666
|
}
|
|
4531
|
-
const configDigests = await Promise.all([...configTargets.values()].map(async ({ entry, scope, }) => {
|
|
3667
|
+
const configDigests = await Promise.all([...configTargets.values()].map(async ({ entry, scope, platform, }) => {
|
|
4532
3668
|
const effective = await resolveEffectivePluginConfig({
|
|
4533
3669
|
sourceId: entry.source.sourceId,
|
|
4534
3670
|
sourceIdentity: entry.source.sourceIdentity,
|
|
@@ -4537,12 +3673,14 @@ async function runRebuildCommandInSession(options) {
|
|
|
4537
3673
|
manifest: entry.plugin.manifest,
|
|
4538
3674
|
referencePlugins: options.runtime?.referencePlugins,
|
|
4539
3675
|
targetScope: scope,
|
|
3676
|
+
platform,
|
|
4540
3677
|
cwd: options.commandOptions.cwd,
|
|
4541
3678
|
env: runtimeEnv,
|
|
4542
3679
|
});
|
|
4543
3680
|
return createOperationPlanConfigDigest({
|
|
4544
3681
|
pluginId: entry.pluginId,
|
|
4545
3682
|
scope,
|
|
3683
|
+
platform,
|
|
4546
3684
|
effectiveValues: effective.values,
|
|
4547
3685
|
});
|
|
4548
3686
|
}));
|
|
@@ -4562,7 +3700,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
4562
3700
|
preview.preApplyAuthorization = executionSelections.flatMap((selection) => {
|
|
4563
3701
|
const { entry, platform } = selection;
|
|
4564
3702
|
const planned = planTargetFor(authorizationPlan, selection);
|
|
4565
|
-
if (!planned || planned.action === 'block' ||
|
|
3703
|
+
if (!planned || planned.action === 'block' || isHealthyWiderDependency(planned)
|
|
3704
|
+
|| !entry.plugin.manifest.scripts?.preApply) {
|
|
4566
3705
|
return [];
|
|
4567
3706
|
}
|
|
4568
3707
|
const relation = planned.relation === 'requested'
|
|
@@ -4609,15 +3748,15 @@ async function runRebuildCommandInSession(options) {
|
|
|
4609
3748
|
const previewPreparation = await prepareRenderedTargets(initialPlan, initialCodexPlans, false);
|
|
4610
3749
|
const preview = mergeRebuildCommandResults([]);
|
|
4611
3750
|
preview.dependencyPlan = initialPlan;
|
|
3751
|
+
preview.nativeFootprints = preparedNativeFootprints([...previewPreparation.preparedTargets.values()].map((entry) => entry.target));
|
|
4612
3752
|
preview.operationPlan = await withNativeToolRemovalImpact(createRebuildOperationPlan({
|
|
4613
|
-
command: intentCommand,
|
|
4614
3753
|
dependencyPlan: initialPlan,
|
|
4615
3754
|
codexPlans: initialCodexPlans,
|
|
4616
3755
|
targetActions: previewPreparation.targetActions,
|
|
4617
3756
|
catalogSources: catalog.sources.flatMap((source) => source.resolution ? [source.resolution] : []),
|
|
4618
|
-
|
|
3757
|
+
requirements,
|
|
3758
|
+
scope: options.commandOptions.scope,
|
|
4619
3759
|
configDigests: previewPreparation.configDigests,
|
|
4620
|
-
catalogEntries: intentCatalogEntries,
|
|
4621
3760
|
}), runtimeEnv);
|
|
4622
3761
|
if (initialCodexPlans.length > 0)
|
|
4623
3762
|
preview.codexReconcilePlans = initialCodexPlans;
|
|
@@ -4666,7 +3805,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
4666
3805
|
const preApplyRequired = lifecycleCommand && executionSelections.some(({ entry, platform }) => entry.plugin.manifest.scripts?.preApply !== undefined
|
|
4667
3806
|
&& lockedPlan.targets.some((target) => target.pluginId === entry.pluginId
|
|
4668
3807
|
&& target.platform === platform
|
|
4669
|
-
&& target.action !== 'block'
|
|
3808
|
+
&& target.action !== 'block'
|
|
3809
|
+
&& !isHealthyWiderDependency(target)));
|
|
4670
3810
|
if (preApplyRequired
|
|
4671
3811
|
&& options.commandOptions.yes !== true
|
|
4672
3812
|
&& options.runtime?.preApplyConfirmed !== true) {
|
|
@@ -4679,14 +3819,13 @@ async function runRebuildCommandInSession(options) {
|
|
|
4679
3819
|
let lockedCodexPlans = provisionalLockedCodexPlans;
|
|
4680
3820
|
let lockedPreparation = await prepareRenderedTargets(lockedPlan, lockedCodexPlans, true);
|
|
4681
3821
|
let lockedOperationPlan = await withNativeToolRemovalImpact(createRebuildOperationPlan({
|
|
4682
|
-
command: intentCommand,
|
|
4683
3822
|
dependencyPlan: lockedPlan,
|
|
4684
3823
|
codexPlans: lockedCodexPlans,
|
|
4685
3824
|
targetActions: lockedPreparation.targetActions,
|
|
4686
3825
|
catalogSources: catalog.sources.flatMap((source) => source.resolution ? [source.resolution] : []),
|
|
4687
|
-
|
|
3826
|
+
requirements,
|
|
3827
|
+
scope: options.commandOptions.scope,
|
|
4688
3828
|
configDigests: lockedPreparation.configDigests,
|
|
4689
|
-
catalogEntries: intentCatalogEntries,
|
|
4690
3829
|
}), runtimeEnv);
|
|
4691
3830
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
4692
3831
|
try {
|
|
@@ -4708,19 +3847,13 @@ async function runRebuildCommandInSession(options) {
|
|
|
4708
3847
|
const operationPreparations = new Map();
|
|
4709
3848
|
const operationPreparationFailures = new Map();
|
|
4710
3849
|
const executionCommandFor = (selection) => {
|
|
4711
|
-
const { entry, platform } = selection;
|
|
4712
3850
|
const planned = planTargetFor(lockedPlan, selection);
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
}
|
|
4718
|
-
if (platform === 'codex' && options.command === 'cleanup' && desiredInCurrentScope) {
|
|
3851
|
+
if (isNativeActivationOnlyTarget(executionContext, {
|
|
3852
|
+
pluginId: selection.entry.pluginId,
|
|
3853
|
+
platform: selection.platform,
|
|
3854
|
+
scope: planned.resolvedScope,
|
|
3855
|
+
}))
|
|
4719
3856
|
return 'install';
|
|
4720
|
-
}
|
|
4721
|
-
if (planned.action === 'move') {
|
|
4722
|
-
return planned.state === 'partial' ? 'reinstall' : 'install';
|
|
4723
|
-
}
|
|
4724
3857
|
if (planned.relation === 'dependency'
|
|
4725
3858
|
&& (planned.action === 'install' || planned.action === 'reinstall')) {
|
|
4726
3859
|
return planned.action;
|
|
@@ -4739,9 +3872,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
4739
3872
|
for (const selection of executionSelections) {
|
|
4740
3873
|
const { entry, platform } = selection;
|
|
4741
3874
|
const key = executionKey(selection, lockedPlan);
|
|
3875
|
+
const planned = planTargetFor(lockedPlan, selection);
|
|
4742
3876
|
if (preparationOptions.eligibleKeys
|
|
4743
3877
|
&& !preparationOptions.eligibleKeys.has(key)) {
|
|
4744
|
-
states.set(key, 'skipped');
|
|
3878
|
+
states.set(key, isHealthyWiderDependency(planned) ? 'ready' : 'skipped');
|
|
4745
3879
|
continue;
|
|
4746
3880
|
}
|
|
4747
3881
|
const directDependencyFailed = (entry.plugin.manifest.dependencies ?? []).some((pluginName) => {
|
|
@@ -4754,11 +3888,14 @@ async function runRebuildCommandInSession(options) {
|
|
|
4754
3888
|
const state = dependency ? states.get(planExecutionKey(dependency)) : undefined;
|
|
4755
3889
|
return state === 'failed' || state === 'skipped';
|
|
4756
3890
|
});
|
|
4757
|
-
const planned = planTargetFor(lockedPlan, selection);
|
|
4758
3891
|
if (directDependencyFailed || planned.action === 'block') {
|
|
4759
3892
|
states.set(key, 'skipped');
|
|
4760
3893
|
continue;
|
|
4761
3894
|
}
|
|
3895
|
+
if (isHealthyWiderDependency(planned)) {
|
|
3896
|
+
states.set(key, 'ready');
|
|
3897
|
+
continue;
|
|
3898
|
+
}
|
|
4762
3899
|
const preparationError = lockedPreparation.preparedTargetErrors.get(key);
|
|
4763
3900
|
const prepared = lockedPreparation.preparedTargets.get(key);
|
|
4764
3901
|
if (preparationError || !prepared) {
|
|
@@ -4943,14 +4080,13 @@ async function runRebuildCommandInSession(options) {
|
|
|
4943
4080
|
lockedPreparation.integration.setNativeMarketplaceEligibleTargets(eligibleTargets);
|
|
4944
4081
|
}
|
|
4945
4082
|
lockedOperationPlan = await withNativeToolRemovalImpact(createRebuildOperationPlan({
|
|
4946
|
-
command: intentCommand,
|
|
4947
4083
|
dependencyPlan: lockedPlan,
|
|
4948
4084
|
codexPlans: lockedCodexPlans,
|
|
4949
4085
|
targetActions: lockedPreparation.targetActions,
|
|
4950
4086
|
catalogSources: catalog.sources.flatMap((source) => source.resolution ? [source.resolution] : []),
|
|
4951
|
-
|
|
4087
|
+
requirements,
|
|
4088
|
+
scope: options.commandOptions.scope,
|
|
4952
4089
|
configDigests: lockedPreparation.configDigests,
|
|
4953
|
-
catalogEntries: intentCatalogEntries,
|
|
4954
4090
|
}), runtimeEnv);
|
|
4955
4091
|
if (options.runtime?.expectedPlanFingerprint) {
|
|
4956
4092
|
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, lockedOperationPlan);
|
|
@@ -4962,7 +4098,9 @@ async function runRebuildCommandInSession(options) {
|
|
|
4962
4098
|
&& lockedCodexPlans.some((plan) => plan.review.requiresConfirmation)) {
|
|
4963
4099
|
throw namespacedPreflightError('sharedNativeImpactAuthorizationRequired: Replacing or force-reinstalling shared Codex native state requires --yes.', preflightTargets);
|
|
4964
4100
|
}
|
|
4965
|
-
if (
|
|
4101
|
+
if (options.command !== 'cleanup'
|
|
4102
|
+
&& options.command !== 'uninstall'
|
|
4103
|
+
&& !executionContext.codexManager) {
|
|
4966
4104
|
const removalTargets = [];
|
|
4967
4105
|
for (const [key, prepared] of lockedPreparation.preparedTargets) {
|
|
4968
4106
|
const target = prepared.target;
|
|
@@ -5027,47 +4165,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
5027
4165
|
}
|
|
5028
4166
|
}
|
|
5029
4167
|
}
|
|
5030
|
-
if (options.runtime?.awHomeMutationToken) {
|
|
5031
|
-
if (lifecycleCommand) {
|
|
5032
|
-
const preparedKeys = new Set(operationPreparations.keys());
|
|
5033
|
-
for (const scope of ['user', 'project']) {
|
|
5034
|
-
const intentSelection = intentPlanForPreparedRoots(lockedPlan, preparedKeys, scope);
|
|
5035
|
-
if (intentSelection.selectedRoots.length > 0) {
|
|
5036
|
-
await writeDesiredIntentSuperset({
|
|
5037
|
-
command: intentCommand,
|
|
5038
|
-
removeOtherScopeRoots: !options.taskTargets,
|
|
5039
|
-
cwd: options.commandOptions.cwd,
|
|
5040
|
-
scope,
|
|
5041
|
-
selectedRoots: intentSelection.selectedRoots,
|
|
5042
|
-
plan: intentSelection.plan,
|
|
5043
|
-
codexPlan: lockedCodexPlans[0],
|
|
5044
|
-
preserveOtherCodexScopeRootIds,
|
|
5045
|
-
catalogEntries: intentCatalogEntries,
|
|
5046
|
-
env: runtimeEnv,
|
|
5047
|
-
});
|
|
5048
|
-
}
|
|
5049
|
-
}
|
|
5050
|
-
}
|
|
5051
|
-
else {
|
|
5052
|
-
for (const scope of ['user', 'project']) {
|
|
5053
|
-
const selectedRoots = selectedRootsForScope(lockedPlan, scope);
|
|
5054
|
-
if (selectedRoots.length === 0)
|
|
5055
|
-
continue;
|
|
5056
|
-
await writeDesiredIntentSuperset({
|
|
5057
|
-
command: intentCommand,
|
|
5058
|
-
removeOtherScopeRoots: !options.taskTargets,
|
|
5059
|
-
cwd: options.commandOptions.cwd,
|
|
5060
|
-
scope,
|
|
5061
|
-
selectedRoots,
|
|
5062
|
-
plan: lockedPlan,
|
|
5063
|
-
codexPlan: lockedCodexPlans[0],
|
|
5064
|
-
preserveOtherCodexScopeRootIds,
|
|
5065
|
-
catalogEntries: intentCatalogEntries,
|
|
5066
|
-
env: runtimeEnv,
|
|
5067
|
-
});
|
|
5068
|
-
}
|
|
5069
|
-
}
|
|
5070
|
-
}
|
|
5071
4168
|
for (const pluginName of new Set(lockedPlan.targets.flatMap((target) => target.platform === 'claude'
|
|
5072
4169
|
&& (target.action === 'install'
|
|
5073
4170
|
|| target.action === 'reinstall')
|
|
@@ -5082,6 +4179,11 @@ async function runRebuildCommandInSession(options) {
|
|
|
5082
4179
|
const claudeCliRequired = await operationNeedsNativeCli('claude', lockedPlan);
|
|
5083
4180
|
const codexUserActivationDesired = new Set(lockedCodexPlans.flatMap((plan) => plan.activationActions.user.flatMap((action) => action.desired ? [action.codexPluginId] : [])));
|
|
5084
4181
|
executionContext.codexUserActivationDesired = codexUserActivationDesired;
|
|
4182
|
+
const originalUserActivations = options.commandOptions.scope === 'project'
|
|
4183
|
+
&& lockedCodexPlans.length > 0
|
|
4184
|
+
? new Map(Object.entries((await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'user', runtimeEnv).configTomlPath)).snapshot.plugins)
|
|
4185
|
+
.map(([pluginId, activation]) => [pluginId, activation.enabled === true]))
|
|
4186
|
+
: undefined;
|
|
5085
4187
|
await assertClaudeVersion({
|
|
5086
4188
|
platforms: claudeCliRequired ? ['claude'] : [],
|
|
5087
4189
|
cwd: options.commandOptions.cwd,
|
|
@@ -5097,6 +4199,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
5097
4199
|
const removalStateInventory = await readInventory({
|
|
5098
4200
|
cwd: options.commandOptions.cwd,
|
|
5099
4201
|
env: runtimeEnv,
|
|
4202
|
+
scope: options.commandOptions.scope,
|
|
5100
4203
|
});
|
|
5101
4204
|
if (options.command !== 'cleanup') {
|
|
5102
4205
|
const checked = options.command === 'uninstall'
|
|
@@ -5225,6 +4328,14 @@ async function runRebuildCommandInSession(options) {
|
|
|
5225
4328
|
}
|
|
5226
4329
|
const results = [];
|
|
5227
4330
|
const dependencyStates = new Map();
|
|
4331
|
+
const nativeTargetExecution = lifecycleCommand ? options.runtime?.nativeTargetExecution : undefined;
|
|
4332
|
+
const recordTargetCommands = (commands) => {
|
|
4333
|
+
executionContext.commandResults ??= [];
|
|
4334
|
+
for (const result of commands) {
|
|
4335
|
+
if (!executionContext.commandResults.some((entry) => JSON.stringify(entry) === JSON.stringify(result)))
|
|
4336
|
+
executionContext.commandResults.push(result);
|
|
4337
|
+
}
|
|
4338
|
+
};
|
|
5228
4339
|
for (const selection of executionSelections) {
|
|
5229
4340
|
const { entry, platform } = selection;
|
|
5230
4341
|
const planned = planTargetFor(lockedPlan, selection);
|
|
@@ -5256,18 +4367,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
5256
4367
|
const codexReconcilePlan = platform === 'codex'
|
|
5257
4368
|
? lockedCodexPlans.find((plan) => plan.desiredTargets.some((target) => target.pluginId === entry.pluginId))
|
|
5258
4369
|
: undefined;
|
|
5259
|
-
const desiredInCurrentScope = codexReconcilePlan?.desiredTargets.some((target) => target.pluginId === entry.pluginId && target.scopes.includes(planned.resolvedScope)) === true;
|
|
5260
|
-
const reconcileObsolete = platform === 'codex'
|
|
5261
|
-
&& options.command === 'sync'
|
|
5262
|
-
&& !desiredInCurrentScope;
|
|
5263
|
-
const desiredCleanupMutation = codexReconcilePlan !== undefined && (codexReconcilePlan.sharedNativeActions.some((action) => action.pluginId === entry.pluginId
|
|
5264
|
-
&& (action.action === 'install'
|
|
5265
|
-
|| action.action === 'replace'
|
|
5266
|
-
|| action.action === 'repair'))
|
|
5267
|
-
|| [...codexReconcilePlan.activationActions.user,
|
|
5268
|
-
...codexReconcilePlan.activationActions.project].some((action) => action.pluginId === entry.pluginId && action.action !== 'none')
|
|
5269
|
-
|| [...codexReconcilePlan.extensionWrites,
|
|
5270
|
-
...codexReconcilePlan.extensionRemovals].some((action) => action.pluginId === entry.pluginId));
|
|
5271
4370
|
const plannedNativeAction = codexReconcilePlan?.sharedNativeActions.find((action) => action.pluginId === entry.pluginId);
|
|
5272
4371
|
const hasCodexExtensionMutation = codexReconcilePlan !== undefined
|
|
5273
4372
|
&& [...codexReconcilePlan.extensionWrites, ...codexReconcilePlan.extensionRemovals]
|
|
@@ -5282,17 +4381,20 @@ async function runRebuildCommandInSession(options) {
|
|
|
5282
4381
|
const code = failedConsumer
|
|
5283
4382
|
? 'dependencyStillRequired'
|
|
5284
4383
|
: failedDependency ? 'dependencyInstallFailed' : planned.errorCode ?? 'dependencyNotReady';
|
|
4384
|
+
recordTargetCommands(nativeTargetExecution?.blocked?.(identity, code) ?? []);
|
|
5285
4385
|
const message = `${code}: ${failedConsumer
|
|
5286
4386
|
? `${entry.pluginId} retained because consumer ${failedConsumer.split('\0', 1)[0]} was not removed.`
|
|
5287
4387
|
: failedDependency
|
|
5288
4388
|
? `${entry.pluginId} requires failed dependency ${failedDependency}.`
|
|
5289
4389
|
: code === 'exclusiveOwnerEvidenceInvalid'
|
|
5290
|
-
? `${entry.pluginId} has damaged or missing exclusive owner evidence. Run aw cleanup ${entry.pluginId} --
|
|
4390
|
+
? `${entry.pluginId} has damaged or missing exclusive owner evidence. Run aw plugin cleanup ${entry.pluginId} --target ${platform} --scope ${planned.resolvedScope} --force, then run aw plugin sync ${entry.pluginId} --target ${platform} --context ${planned.resolvedScope} --rebuild.`
|
|
5291
4391
|
: code === 'artifactCollision'
|
|
5292
4392
|
? `${entry.pluginId} has foreign-owned output. Remove or relocate it, then run cleanup and reinstall.`
|
|
5293
4393
|
: code === 'dependencyNotReady'
|
|
5294
4394
|
? `${entry.pluginId} live state is unreadable. Run cleanup, then reinstall.`
|
|
5295
|
-
:
|
|
4395
|
+
: code === 'dependencyStillRequired'
|
|
4396
|
+
? `${entry.pluginId} remains required by an unselected declared root.`
|
|
4397
|
+
: `${entry.pluginId} dependency preflight is blocked.`}`;
|
|
5296
4398
|
const result = failedResult(requestedMethod, identity, message);
|
|
5297
4399
|
results.push({
|
|
5298
4400
|
platforms: [platform], plugins: [], warnings: [], rebuildResults: [result],
|
|
@@ -5304,8 +4406,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
5304
4406
|
message,
|
|
5305
4407
|
...(code === 'exclusiveOwnerEvidenceInvalid' ? {
|
|
5306
4408
|
recoveryActions: [
|
|
5307
|
-
`run aw cleanup ${entry.pluginId} --
|
|
5308
|
-
`then run aw
|
|
4409
|
+
`run aw plugin cleanup ${entry.pluginId} --target ${platform} --scope ${planned.resolvedScope} --force`,
|
|
4410
|
+
`then run aw plugin sync ${entry.pluginId} --target ${platform} --context ${planned.resolvedScope} --rebuild`,
|
|
5309
4411
|
],
|
|
5310
4412
|
} : {}),
|
|
5311
4413
|
}],
|
|
@@ -5318,9 +4420,23 @@ async function runRebuildCommandInSession(options) {
|
|
|
5318
4420
|
dependencyStates.set(key, failedDependency || failedConsumer ? 'skipped' : 'failed');
|
|
5319
4421
|
continue;
|
|
5320
4422
|
}
|
|
4423
|
+
if (isHealthyWiderDependency(planned)) {
|
|
4424
|
+
results.push({
|
|
4425
|
+
platforms: [platform], plugins: [identity.pluginName], warnings: [], rebuildResults: [],
|
|
4426
|
+
targetResults: [{ target: identity, action: 'keep', state: 'completed' }],
|
|
4427
|
+
overallState: 'succeeded',
|
|
4428
|
+
receiptTargets: [{
|
|
4429
|
+
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
4430
|
+
sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
|
|
4431
|
+
}],
|
|
4432
|
+
});
|
|
4433
|
+
dependencyStates.set(key, 'kept');
|
|
4434
|
+
continue;
|
|
4435
|
+
}
|
|
5321
4436
|
const operationPreparationFailure = operationPreparationFailures.get(key);
|
|
5322
4437
|
if (operationPreparationFailure) {
|
|
5323
4438
|
const targetResult = toTargetResult(operationPreparationFailure);
|
|
4439
|
+
recordTargetCommands(nativeTargetExecution?.blocked?.(identity, targetResult.errorCode ?? 'targetPreparationFailed') ?? []);
|
|
5324
4440
|
results.push({
|
|
5325
4441
|
platforms: [platform],
|
|
5326
4442
|
plugins: [],
|
|
@@ -5339,6 +4455,37 @@ async function runRebuildCommandInSession(options) {
|
|
|
5339
4455
|
dependencyStates.set(key, 'failed');
|
|
5340
4456
|
continue;
|
|
5341
4457
|
}
|
|
4458
|
+
if (nativeTargetExecution) {
|
|
4459
|
+
let packageFailure;
|
|
4460
|
+
try {
|
|
4461
|
+
const commands = await nativeTargetExecution.beforeApply(identity);
|
|
4462
|
+
recordTargetCommands(commands);
|
|
4463
|
+
if (commands.some((result) => result.state !== 'completed')) {
|
|
4464
|
+
packageFailure = 'commandPackageProviderNotSatisfied';
|
|
4465
|
+
}
|
|
4466
|
+
}
|
|
4467
|
+
catch (error) {
|
|
4468
|
+
executionContext.signal?.throwIfAborted();
|
|
4469
|
+
if (error instanceof Error && error.name === 'AbortError')
|
|
4470
|
+
throw error;
|
|
4471
|
+
packageFailure = 'commandPackageApplyFailed';
|
|
4472
|
+
recordTargetCommands(nativeTargetExecution.blocked?.(identity, packageFailure) ?? []);
|
|
4473
|
+
}
|
|
4474
|
+
if (packageFailure) {
|
|
4475
|
+
const result = failedResult(requestedMethod, identity, `${packageFailure}: ${entry.pluginId} requires a completed command package provider.`);
|
|
4476
|
+
results.push({
|
|
4477
|
+
platforms: [platform], plugins: [], warnings: [], rebuildResults: [result],
|
|
4478
|
+
targetResults: [{ ...toTargetResult(result), action: planned.action }],
|
|
4479
|
+
overallState: 'failed',
|
|
4480
|
+
receiptTargets: [{
|
|
4481
|
+
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
4482
|
+
sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
|
|
4483
|
+
}],
|
|
4484
|
+
});
|
|
4485
|
+
dependencyStates.set(key, 'failed');
|
|
4486
|
+
continue;
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
5342
4489
|
if (reconcileActivationOnly) {
|
|
5343
4490
|
const preparedError = preparedTargetErrors.get(key);
|
|
5344
4491
|
if (preparedError) {
|
|
@@ -5368,11 +4515,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
5368
4515
|
?? [];
|
|
5369
4516
|
const preparedTarget = preparedTargets.get(key)?.target;
|
|
5370
4517
|
let result;
|
|
5371
|
-
if (preparedTarget) {
|
|
4518
|
+
if (preparedTarget && executionContext.preserveLegacyNativeSkills !== true) {
|
|
5372
4519
|
const nativeSkillKeys = new Set((entry.plugin.manifest.artifacts?.targets ?? [])
|
|
5373
4520
|
.filter((target) => target.platform === 'codex'
|
|
5374
|
-
&& target.target === 'codex.skill'
|
|
5375
|
-
&& target.delivery?.mode === 'codex-native')
|
|
4521
|
+
&& target.target === 'codex.skill')
|
|
5376
4522
|
.map((target) => target.skillKey));
|
|
5377
4523
|
const marketplaceRoot = preparedTarget.identity.marketplaceRoot;
|
|
5378
4524
|
const legacyNativeSkills = preparedTarget.ownedComponents.filter((component) => component.kind === 'skill-directory'
|
|
@@ -5405,7 +4551,14 @@ async function runRebuildCommandInSession(options) {
|
|
|
5405
4551
|
plugins: result.status === 'succeeded' ? [identity.pluginName] : [],
|
|
5406
4552
|
warnings: result.failures.map((failure) => failure.message),
|
|
5407
4553
|
rebuildResults: [result],
|
|
5408
|
-
targetResults: [{
|
|
4554
|
+
targetResults: [{
|
|
4555
|
+
...toTargetResult(result),
|
|
4556
|
+
action: result.status === 'succeeded' && result.removed.length === 0
|
|
4557
|
+
&& codexReconcilePlan
|
|
4558
|
+
&& [...codexReconcilePlan.activationActions.user,
|
|
4559
|
+
...codexReconcilePlan.activationActions.project].every((action) => action.pluginId !== entry.pluginId || action.action === 'none')
|
|
4560
|
+
? 'keep' : planned.action,
|
|
4561
|
+
}],
|
|
5409
4562
|
overallState: result.status === 'succeeded' ? 'succeeded' : 'failed',
|
|
5410
4563
|
receiptTargets: [{
|
|
5411
4564
|
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
@@ -5415,28 +4568,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
5415
4568
|
dependencyStates.set(key, result.status === 'succeeded' ? 'completed' : 'failed');
|
|
5416
4569
|
continue;
|
|
5417
4570
|
}
|
|
5418
|
-
if (platform === 'codex'
|
|
5419
|
-
&& desiredInCurrentScope
|
|
5420
|
-
&& (options.command === 'uninstall'
|
|
5421
|
-
|| (options.command === 'cleanup' && !desiredCleanupMutation))) {
|
|
5422
|
-
const result = {
|
|
5423
|
-
status: 'succeeded', command: options.command, target: identity, actions: [],
|
|
5424
|
-
cleanupAttempted: false, removed: [], absent: [], residual: [], quarantined: [], failures: [],
|
|
5425
|
-
};
|
|
5426
|
-
results.push({
|
|
5427
|
-
platforms: [platform], plugins: [identity.pluginName], warnings: [], rebuildResults: [result],
|
|
5428
|
-
targetResults: [{ target: identity, action: 'keep', state: 'completed' }],
|
|
5429
|
-
overallState: 'succeeded',
|
|
5430
|
-
receiptTargets: [{
|
|
5431
|
-
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
5432
|
-
sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
|
|
5433
|
-
}],
|
|
5434
|
-
});
|
|
5435
|
-
dependencyStates.set(key, 'kept');
|
|
5436
|
-
continue;
|
|
5437
|
-
}
|
|
5438
4571
|
if (planned.action === 'keep'
|
|
5439
|
-
&& !
|
|
4572
|
+
&& !(preparedTargets.get(key)?.target.writeNativeRequired ?? false)
|
|
5440
4573
|
&& options.command !== 'cleanup'
|
|
5441
4574
|
&& options.command !== 'uninstall') {
|
|
5442
4575
|
const preparedError = preparedTargetErrors.get(key);
|
|
@@ -5491,20 +4624,12 @@ async function runRebuildCommandInSession(options) {
|
|
|
5491
4624
|
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
|
|
5492
4625
|
};
|
|
5493
4626
|
entry.plugin.marketplaceName = marketplaceName;
|
|
5494
|
-
const reconcileDesiredCleanup = platform === 'codex'
|
|
5495
|
-
&& options.command === 'cleanup'
|
|
5496
|
-
&& desiredInCurrentScope;
|
|
5497
4627
|
const executionResult = await runSingleSourceRebuildCommand({
|
|
5498
4628
|
...options,
|
|
5499
|
-
command:
|
|
5500
|
-
|
|
5501
|
-
|
|
5502
|
-
|
|
5503
|
-
: planned.action === 'move'
|
|
5504
|
-
? planned.state === 'partial' ? 'reinstall' : 'install'
|
|
5505
|
-
: planned.relation === 'dependency'
|
|
5506
|
-
? planned.action
|
|
5507
|
-
: requestedMethod,
|
|
4629
|
+
command: isNativeActivationOnlyTarget(executionContext, identity) ? 'install'
|
|
4630
|
+
: planned.relation === 'dependency' && planned.action !== 'keep'
|
|
4631
|
+
? planned.action
|
|
4632
|
+
: requestedMethod,
|
|
5508
4633
|
pluginNames: [entry.plugin.manifest.name],
|
|
5509
4634
|
all: false,
|
|
5510
4635
|
commandOptions: { ...options.commandOptions, platform, scope: planned.resolvedScope },
|
|
@@ -5543,15 +4668,8 @@ async function runRebuildCommandInSession(options) {
|
|
|
5543
4668
|
operationPreparation: operationPreparations.get(key),
|
|
5544
4669
|
integration: lockedPreparation.integration,
|
|
5545
4670
|
preparationError: preparedTargetErrors.get(key),
|
|
5546
|
-
skipPreApply: reconcileDesiredCleanup,
|
|
5547
4671
|
},
|
|
5548
4672
|
});
|
|
5549
|
-
if (reconcileDesiredCleanup) {
|
|
5550
|
-
for (const result of executionResult.rebuildResults)
|
|
5551
|
-
result.command = 'cleanup';
|
|
5552
|
-
for (const result of executionResult.targetResults)
|
|
5553
|
-
result.action = 'cleanup';
|
|
5554
|
-
}
|
|
5555
4673
|
results.push(executionResult);
|
|
5556
4674
|
dependencyStates.set(key, executionResult.overallState === 'succeeded' ? 'completed' : 'failed');
|
|
5557
4675
|
}
|
|
@@ -5634,17 +4752,17 @@ async function runRebuildCommandInSession(options) {
|
|
|
5634
4752
|
|| dependencyStates.get(executionKey(selection, lockedPlan)) === 'kept')
|
|
5635
4753
|
? [`${selection.entry.pluginId}\0${planTargetFor(lockedPlan, selection).resolvedScope}`]
|
|
5636
4754
|
: []));
|
|
5637
|
-
const
|
|
5638
|
-
|
|
5639
|
-
readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath)
|
|
5640
|
-
|
|
4755
|
+
const activationUserBefore = await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'user', runtimeEnv).configTomlPath);
|
|
4756
|
+
const activationProjectBefore = options.commandOptions.scope === 'project'
|
|
4757
|
+
? await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath)
|
|
4758
|
+
: undefined;
|
|
5641
4759
|
const preservedActivations = {
|
|
5642
4760
|
user: new Map(Object.entries(activationUserBefore.snapshot.plugins)
|
|
5643
4761
|
.map(([pluginId, activation]) => [pluginId, activation.enabled === true])),
|
|
5644
|
-
project: new Map(Object.entries(activationProjectBefore
|
|
4762
|
+
project: new Map(Object.entries(activationProjectBefore?.snapshot.plugins ?? {})
|
|
5645
4763
|
.map(([pluginId, activation]) => [pluginId, activation.enabled === true])),
|
|
5646
4764
|
};
|
|
5647
|
-
const activationPlans = selectCodexActivationPlans(lockedCodexPlans, successfulCodexTargetScopes, preservedActivations);
|
|
4765
|
+
const activationPlans = selectCodexActivationPlans(lockedCodexPlans, successfulCodexTargetScopes, preservedActivations, originalUserActivations);
|
|
5648
4766
|
if (activationPlans.length > 0
|
|
5649
4767
|
|| lockedPreparation.integration.driver.completePostchecks) {
|
|
5650
4768
|
let activationError;
|
|
@@ -5691,7 +4809,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
5691
4809
|
if (!activationError && activationPlans.length > 0) {
|
|
5692
4810
|
const postcheckTargetScopes = new Set([...successfulCodexTargetScopes]
|
|
5693
4811
|
.filter((key) => !failedCodexTargetScopes.has(key)));
|
|
5694
|
-
const postcheckPlans = selectCodexActivationPlans(activationPlans, postcheckTargetScopes, preservedActivations);
|
|
4812
|
+
const postcheckPlans = selectCodexActivationPlans(activationPlans, postcheckTargetScopes, preservedActivations, originalUserActivations);
|
|
5695
4813
|
try {
|
|
5696
4814
|
await postcheckCodexReconcileActivations({
|
|
5697
4815
|
plans: postcheckPlans,
|
|
@@ -5773,7 +4891,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
5773
4891
|
identity,
|
|
5774
4892
|
message,
|
|
5775
4893
|
recoveryActions: [
|
|
5776
|
-
`run aw sync
|
|
4894
|
+
`run aw plugin sync ${selection.entry.pluginId} --target codex --context ${planned.resolvedScope}`,
|
|
5777
4895
|
],
|
|
5778
4896
|
})) {
|
|
5779
4897
|
failedCodexTargetScopes.add(targetScopeKey);
|
|
@@ -5783,78 +4901,6 @@ async function runRebuildCommandInSession(options) {
|
|
|
5783
4901
|
}
|
|
5784
4902
|
}
|
|
5785
4903
|
}
|
|
5786
|
-
for (const result of results) {
|
|
5787
|
-
result.targetResults = result.targetResults.map((target) => {
|
|
5788
|
-
if (target.state !== 'completed')
|
|
5789
|
-
return target;
|
|
5790
|
-
const planned = lockedPlan.targets.find((candidate) => candidate.pluginId === target.target.pluginId
|
|
5791
|
-
&& candidate.platform === target.target.platform
|
|
5792
|
-
&& candidate.resolvedScope === target.target.scope);
|
|
5793
|
-
if (!planned?.preservedScope)
|
|
5794
|
-
return target;
|
|
5795
|
-
return {
|
|
5796
|
-
...target,
|
|
5797
|
-
recoveryActions: [
|
|
5798
|
-
`remove every direct and indirect dependent of ${planned.pluginId} in consumer-first order; if dependencyStillRequired is reported, handle the other reported dependents first`,
|
|
5799
|
-
`then run aw cleanup ${planned.pluginId} --platform ${planned.platform} --scope ${planned.preservedScope}`,
|
|
5800
|
-
`then reinstall every removed root at its original platform and scope, selecting --dependency-scope ${planned.pluginId}#${planned.platform}=${planned.resolvedScope} during each install`,
|
|
5801
|
-
],
|
|
5802
|
-
};
|
|
5803
|
-
});
|
|
5804
|
-
}
|
|
5805
|
-
if (options.command === 'install' || options.command === 'sync') {
|
|
5806
|
-
for (const selection of executionSelections) {
|
|
5807
|
-
const { entry, platform } = selection;
|
|
5808
|
-
const planned = planTargetFor(lockedPlan, selection);
|
|
5809
|
-
const key = executionKey(selection, lockedPlan);
|
|
5810
|
-
if (dependencyStates.get(key) !== 'completed')
|
|
5811
|
-
continue;
|
|
5812
|
-
const previousScope = planned.resolvedScope === 'user' ? 'project' : 'user';
|
|
5813
|
-
const removesPreviousScope = planned.resolvedScope === 'user'
|
|
5814
|
-
&& (planned.action === 'move'
|
|
5815
|
-
|| platform === 'codex' && lockedCodexPlans.some((plan) => plan.extensionRemovals.some((action) => action.pluginId === entry.pluginId && action.scope === previousScope)));
|
|
5816
|
-
if (!removesPreviousScope) {
|
|
5817
|
-
continue;
|
|
5818
|
-
}
|
|
5819
|
-
const marketplaceName = marketplaceNameFor(entry, platform, previousScope);
|
|
5820
|
-
entry.plugin.marketplaceName = marketplaceName;
|
|
5821
|
-
const migration = await runSingleSourceRebuildCommand({
|
|
5822
|
-
command: 'cleanup',
|
|
5823
|
-
pluginNames: [entry.plugin.manifest.name],
|
|
5824
|
-
commandOptions: { ...options.commandOptions, platform, scope: previousScope },
|
|
5825
|
-
runtime: {
|
|
5826
|
-
...options.runtime,
|
|
5827
|
-
env: runtimeEnv,
|
|
5828
|
-
...(executionContext.codexManager
|
|
5829
|
-
? { codexManager: executionContext.codexManager }
|
|
5830
|
-
: {}),
|
|
5831
|
-
catalogResolution: toCatalogResolution(entry.source),
|
|
5832
|
-
resolvedCatalogPlugins: available
|
|
5833
|
-
.filter((candidate) => candidate.source.sourceId === entry.source.sourceId)
|
|
5834
|
-
.map((candidate) => candidate.plugin),
|
|
5835
|
-
namespacedSource: {
|
|
5836
|
-
sourceId: entry.source.sourceId,
|
|
5837
|
-
sourceIdentity: entry.source.sourceIdentity,
|
|
5838
|
-
logicalIdentity: entry.source.logicalIdentity,
|
|
5839
|
-
marketplaceName,
|
|
5840
|
-
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
|
|
5841
|
-
},
|
|
5842
|
-
},
|
|
5843
|
-
execution: { reviewCompleted: true },
|
|
5844
|
-
});
|
|
5845
|
-
results.push({
|
|
5846
|
-
...migration,
|
|
5847
|
-
targetResults: migration.targetResults.map((target) => ({
|
|
5848
|
-
...target,
|
|
5849
|
-
relation: planned.relation,
|
|
5850
|
-
requiredBy: planned.requiredBy,
|
|
5851
|
-
})),
|
|
5852
|
-
});
|
|
5853
|
-
if (migration.overallState !== 'succeeded') {
|
|
5854
|
-
dependencyStates.set(key, 'failed');
|
|
5855
|
-
}
|
|
5856
|
-
}
|
|
5857
|
-
}
|
|
5858
4904
|
const merged = mergeRebuildCommandResults(results);
|
|
5859
4905
|
if (malformedSelectedConfigPreserved) {
|
|
5860
4906
|
merged.warnings.push(MALFORMED_CONFIG_PRESERVED_WARNING);
|
|
@@ -5864,6 +4910,7 @@ async function runRebuildCommandInSession(options) {
|
|
|
5864
4910
|
if (lockedCodexPlans.length > 0)
|
|
5865
4911
|
merged.codexReconcilePlans = lockedCodexPlans;
|
|
5866
4912
|
merged.operationPlan = lockedOperationPlan;
|
|
4913
|
+
merged.nativeFootprints = preparedNativeFootprints([...lockedPreparation.preparedTargets.values()].map((entry) => entry.target));
|
|
5867
4914
|
return leaseSafeRebuildResult(merged);
|
|
5868
4915
|
},
|
|
5869
4916
|
});
|
|
@@ -5899,6 +4946,10 @@ async function runRebuildCommandInSession(options) {
|
|
|
5899
4946
|
}
|
|
5900
4947
|
}
|
|
5901
4948
|
export async function runRebuildCommand(options) {
|
|
4949
|
+
const executionInput = options.runtime?.executionInput;
|
|
4950
|
+
if (!executionInput) {
|
|
4951
|
+
throw new Error('nativeExecutionInputRequired: Native execution requires an explicit scope context and complete demand.');
|
|
4952
|
+
}
|
|
5902
4953
|
const commandResults = options.runtime?.commandResults ?? [];
|
|
5903
4954
|
options = { ...options, runtime: { ...options.runtime, commandResults, managedCommandProducerCache: options.runtime?.managedCommandProducerCache ?? new Map() } };
|
|
5904
4955
|
const withCommands = (result) => {
|
|
@@ -5915,20 +4966,25 @@ export async function runRebuildCommand(options) {
|
|
|
5915
4966
|
const failed = commands.some((entry) => entry.state !== 'completed');
|
|
5916
4967
|
return { ...result, commandResults: commands, overallState: failed ? result.targetResults.some((entry) => entry.state === 'completed') || commands.some((entry) => entry.state === 'completed') ? 'partial' : 'failed' : result.overallState };
|
|
5917
4968
|
};
|
|
5918
|
-
|
|
5919
|
-
|
|
4969
|
+
const scopedOptions = {
|
|
4970
|
+
...options,
|
|
4971
|
+
commandOptions: { ...options.commandOptions, cwd: executionInput.context.executionCwd },
|
|
4972
|
+
runtime: { ...options.runtime, env: executionInput.context.env },
|
|
4973
|
+
};
|
|
4974
|
+
if (scopedOptions.runtime?.codexObservationSession) {
|
|
4975
|
+
return withCommands(await runRebuildCommandInSession(scopedOptions));
|
|
5920
4976
|
}
|
|
5921
|
-
const env =
|
|
4977
|
+
const env = executionInput.context.env;
|
|
5922
4978
|
const session = await createCodexNativeObservationSession({
|
|
5923
|
-
exactCwd:
|
|
4979
|
+
exactCwd: executionInput.context.executionCwd,
|
|
5924
4980
|
env,
|
|
5925
|
-
runner:
|
|
5926
|
-
manager:
|
|
4981
|
+
runner: scopedOptions.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
4982
|
+
manager: scopedOptions.runtime?.codexManager,
|
|
5927
4983
|
});
|
|
5928
4984
|
try {
|
|
5929
4985
|
return withCommands(await runRebuildCommandInSession({
|
|
5930
|
-
...
|
|
5931
|
-
runtime: { ...
|
|
4986
|
+
...scopedOptions,
|
|
4987
|
+
runtime: { ...scopedOptions.runtime, codexObservationSession: session },
|
|
5932
4988
|
}));
|
|
5933
4989
|
}
|
|
5934
4990
|
finally {
|
|
@@ -5982,6 +5038,12 @@ export async function runRebuildTaskCommand(targets, options, runtime = {}) {
|
|
|
5982
5038
|
const repairTargets = deduplicate(normalizedRepairs);
|
|
5983
5039
|
const commandOptions = { ...options };
|
|
5984
5040
|
delete commandOptions.repairTargets;
|
|
5041
|
+
if (!runtime.executionInput) {
|
|
5042
|
+
throw new Error('nativeExecutionInputRequired: rebuild tasks require a scope context and complete demand.');
|
|
5043
|
+
}
|
|
5044
|
+
if (normalized.some((target) => target.scope !== runtime.executionInput.context.scope)) {
|
|
5045
|
+
throw new Error('nativeExecutionTargetScopeInvalid: rebuild tasks cannot mix scopes.');
|
|
5046
|
+
}
|
|
5985
5047
|
return runRebuildCommand({
|
|
5986
5048
|
command: 'sync',
|
|
5987
5049
|
pluginNames: [...new Set(normalized.map((target) => target.pluginId))],
|
|
@@ -5990,7 +5052,13 @@ export async function runRebuildTaskCommand(targets, options, runtime = {}) {
|
|
|
5990
5052
|
platform: 'both',
|
|
5991
5053
|
scope: normalized[0].scope,
|
|
5992
5054
|
},
|
|
5993
|
-
runtime
|
|
5055
|
+
runtime: {
|
|
5056
|
+
...runtime,
|
|
5057
|
+
executionInput: {
|
|
5058
|
+
...runtime.executionInput,
|
|
5059
|
+
selectedTargets: normalized.map(({ pluginId, platform, scope }) => ({ pluginId, platform, scope })),
|
|
5060
|
+
},
|
|
5061
|
+
},
|
|
5994
5062
|
taskTargets: normalized,
|
|
5995
5063
|
taskRepairTargets: repairTargets,
|
|
5996
5064
|
});
|