@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
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { resolveWorkContext } from '../intent/work-context.js';
|
|
2
|
+
import { statusTargetHasLiveConfigConsumer } from '../commands/status-v6.js';
|
|
3
|
+
import { readDemand, demandNativeProjection } from '../recovery/demand.js';
|
|
4
|
+
import { createScopeContext } from '../intent/scope-context.js';
|
|
5
|
+
import { compilePluginConfigDefinition, getCommandPackageId } from '@lesliechan721/aw-plugin-core/manifest';
|
|
6
|
+
import { flattenStatusTargets, statusCommandV8, } from '../commands/status-v6.js';
|
|
3
7
|
import { syncWriteCommand } from '../commands/write-commands.js';
|
|
4
8
|
import { CONFIG_MUTATION_RECEIPT_SCHEMA_VERSION, } from '../types.js';
|
|
5
9
|
import { getDefaultNativeCliRunner, prepareNativeCliExecution } from './native-cli.js';
|
|
6
|
-
import {
|
|
10
|
+
import { assertPluginConfigMutationCandidate, assertSafePluginConfigSegment, coercePluginConfigUpdates, patchPluginConfigStore, PluginConfigSchemaResolutionError, readPluginConfigStore, readNamespacedPluginConfigStoreIdentity, resetPluginConfigStore, resolveConfigRead, resolveEffectivePluginConfig, resolvePluginConfigStorePath, resolvePluginConfigSchemaAccess, summarizeEffectivePluginConfig, } from './plugin-config.js';
|
|
7
11
|
import { analyzePluginConfigMutationImpact, discoverPluginConfigManagedCommandPackages, pluginConfigTargetRenderScopes, pluginSharedNativeConfigTargets } from './plugin-config-impact.js';
|
|
8
|
-
import { resolvePluginConfigReferencePlugins, resolvePluginConfigReferenceConsumers } from './plugin-config-references.js';
|
|
12
|
+
import { collectPluginConfigReferenceEvidence, resolvePluginConfigReferencePlugins, resolvePluginConfigReferenceConsumers } from './plugin-config-references.js';
|
|
9
13
|
import { orderPluginMetasByDependencies, resolvePluginMetaDependencyClosure } from './plugin-dependencies.js';
|
|
10
|
-
import { assertManagedCommandPackageNativeToolsUnchanged, syncPluginManagedCommandPackage, } from './managed-command-materialization.js';
|
|
11
|
-
import { managedCommandDiagnostic } from './managed-command-store.js';
|
|
14
|
+
import { assertManagedCommandPackageNativeToolsUnchanged, discoverInstalledPluginManagedCommandPackages, syncPluginManagedCommandPackage, } from './managed-command-materialization.js';
|
|
15
|
+
import { listManagedCommandPackages, managedCommandDiagnostic, readInstalledCommandProducer } from './managed-command-store.js';
|
|
12
16
|
import { collectSensitivePluginConfigValues, redactPluginScriptOutput, } from './plugin-scripts.js';
|
|
13
|
-
import { resolveClaudeProjectKey, resolveCodexProjectKey } from './paths.js';
|
|
17
|
+
import { resolveClaudeProjectKey, resolveCodexProjectKey, resolveCliPackageRoot } from './paths.js';
|
|
18
|
+
import { readSafeOperationError } from './safe-operation-diagnostic.js';
|
|
14
19
|
import { withAwHomeMutationLock, } from './aw-home-mutation-lock.js';
|
|
15
|
-
import
|
|
20
|
+
import fs from 'fs-extra';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
import crypto from 'node:crypto';
|
|
16
23
|
export function buildConfigMutationReceipt(command, receipt) {
|
|
17
24
|
return {
|
|
18
25
|
...receipt,
|
|
@@ -128,21 +135,21 @@ async function discoverVisibleTargets(options) {
|
|
|
128
135
|
: {}),
|
|
129
136
|
});
|
|
130
137
|
for (const statusTarget of flattenStatusTargets(status.payload.targets)) {
|
|
131
|
-
|
|
132
|
-
|
|
138
|
+
if (!selectors.includes(statusTarget.pluginId ?? '')
|
|
139
|
+
&& !consumers.some((plugin) => plugin.manifest.name === statusTarget.pluginName)
|
|
133
140
|
&& statusTarget.pluginId !== selector && statusTarget.pluginName !== options.pluginName)
|
|
134
|
-
|| !intent.enabled)
|
|
135
141
|
continue;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
// A declaration alone is not a consumer. Config apply cannot install it.
|
|
143
|
+
if (!statusTargetHasLiveConfigConsumer(statusTarget))
|
|
144
|
+
continue;
|
|
145
|
+
if (options.scope === 'user' && statusTarget.scope !== 'user')
|
|
146
|
+
continue;
|
|
147
|
+
targets.push(await createCandidateTarget({
|
|
148
|
+
pluginName: statusTarget.pluginName,
|
|
149
|
+
platform: statusTarget.platform,
|
|
150
|
+
scope: statusTarget.scope,
|
|
151
|
+
cwd: options.cwd,
|
|
152
|
+
}));
|
|
146
153
|
}
|
|
147
154
|
return { targets: dedupeTargets(targets), failures };
|
|
148
155
|
}
|
|
@@ -181,7 +188,7 @@ async function reinstallVisibleTargets(options) {
|
|
|
181
188
|
failed.add(`${plugin.manifest.name}\0${target.platform}\0${target.scope}`);
|
|
182
189
|
results.push(...blocked.map((target) => ({ target, action: 'skipped',
|
|
183
190
|
state: 'skipped', errorCode: 'dependencyApplyFailed',
|
|
184
|
-
message: `A required provider failed. Run aw sync ${plugin.pluginId ?? plugin.manifest.name} --
|
|
191
|
+
message: `A required provider failed. Run aw plugin sync ${plugin.pluginId ?? plugin.manifest.name} --context ${target.scope} --target ${target.platform} --yes.` })));
|
|
185
192
|
}
|
|
186
193
|
const blockedPackages = packages.filter((target) => {
|
|
187
194
|
const platforms = plugin.manifest.managedCommands?.packages.find((entry) => entry.key === target.packageKey
|
|
@@ -203,7 +210,7 @@ async function reinstallVisibleTargets(options) {
|
|
|
203
210
|
const own = plugin.manifest.name === options.plugin.manifest.name;
|
|
204
211
|
const result = await reinstallVisibleTargets({ ...options, plugin,
|
|
205
212
|
changedConfigKeys: own ? options.changedConfigKeys : [],
|
|
206
|
-
rebuildRuntime: { ...options.rebuildRuntime, managedCommandProducerCache },
|
|
213
|
+
rebuildRuntime: { ...options.rebuildRuntime, referencePlugins: plugins, managedCommandProducerCache },
|
|
207
214
|
discovered: { targets: available, failures: [], commandPackages: availablePackages,
|
|
208
215
|
commandDiscoveryErrors: [] } });
|
|
209
216
|
if (result.state !== 'succeeded' && result.state !== 'skipped') {
|
|
@@ -229,277 +236,320 @@ async function reinstallVisibleTargets(options) {
|
|
|
229
236
|
return { state: partial ? 'partial' : 'succeeded', targetResults: results,
|
|
230
237
|
...(commandResults.length ? { commandResults } : {}), ...(errors.length ? { errors } : {}) };
|
|
231
238
|
}
|
|
232
|
-
const
|
|
233
|
-
const
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
errors:
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
if (nativeFailures.length > 0) {
|
|
263
|
-
return { state: 'partial', commandResults: nativeFailures,
|
|
264
|
-
targetResults: [...targetResults, ...discovered.targets.map((target) => ({
|
|
265
|
-
target, action: 'reinstall', state: 'failed', errorCode: 'nativeToolSyncRequired',
|
|
266
|
-
message: 'Run a reviewed producer sync or package sync before configuration apply.',
|
|
267
|
-
}))] };
|
|
268
|
-
}
|
|
269
|
-
const sanitizeFailure = async (message, target) => {
|
|
270
|
-
let sensitiveValues = [];
|
|
271
|
-
try {
|
|
272
|
-
const effective = await resolveEffectivePluginConfig({
|
|
273
|
-
...(options.plugin.sourceId ? {
|
|
274
|
-
sourceId: options.plugin.sourceId,
|
|
275
|
-
sourceIdentity: options.plugin.sourceIdentity,
|
|
276
|
-
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
277
|
-
} : {}),
|
|
278
|
-
pluginName: options.plugin.manifest.name,
|
|
279
|
-
manifest: options.plugin.manifest,
|
|
280
|
-
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
281
|
-
targetScope: target.scope,
|
|
282
|
-
cwd: options.cwd,
|
|
283
|
-
env: options.env,
|
|
284
|
-
});
|
|
285
|
-
sensitiveValues = collectSensitivePluginConfigValues(options.plugin.manifest, effective.values);
|
|
239
|
+
const contexts = new Map();
|
|
240
|
+
const demands = new Map();
|
|
241
|
+
const failedScopes = new Set();
|
|
242
|
+
try {
|
|
243
|
+
const targetResults = [...discovered.failures];
|
|
244
|
+
const commandResults = new Map();
|
|
245
|
+
let runtimeFailed = discovered.failures.length > 0
|
|
246
|
+
|| (discovered.commandDiscoveryErrors?.length ?? 0) > 0;
|
|
247
|
+
let invalidTargets = 0;
|
|
248
|
+
let unavailableTargets = 0;
|
|
249
|
+
const errors = [];
|
|
250
|
+
for (const scope of new Set(discovered.targets.map((target) => target.scope))) {
|
|
251
|
+
try {
|
|
252
|
+
const context = await createScopeContext({ scope, cwd: options.cwd, env: options.env });
|
|
253
|
+
contexts.set(scope, context);
|
|
254
|
+
const demand = await readDemand({ scope, cwd: context.executionCwd, env: context.env });
|
|
255
|
+
demandNativeProjection(demand);
|
|
256
|
+
demands.set(scope, demand);
|
|
257
|
+
}
|
|
258
|
+
catch {
|
|
259
|
+
failedScopes.add(scope);
|
|
260
|
+
runtimeFailed = true;
|
|
261
|
+
for (const target of discovered.targets.filter((entry) => entry.scope === scope)) {
|
|
262
|
+
targetResults.push({ target, action: 'reinstall', state: 'failed', errorCode: 'configApplyContextUnavailable',
|
|
263
|
+
message: 'The target scope or its demand cannot be read safely.' });
|
|
264
|
+
}
|
|
265
|
+
errors.push({ stage: 'targetValidation', code: 'configApplyContextUnavailable',
|
|
266
|
+
message: 'A visible target scope or its demand cannot be read safely.' });
|
|
267
|
+
}
|
|
286
268
|
}
|
|
287
|
-
|
|
288
|
-
|
|
269
|
+
if ((discovered.commandDiscoveryErrors?.length ?? 0) > 0) {
|
|
270
|
+
errors.push(...discovered.commandDiscoveryErrors.map((error) => ({
|
|
271
|
+
stage: 'targetDiscovery', code: error.code, message: error.message,
|
|
272
|
+
})));
|
|
289
273
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
sanitized = sanitized.split(privatePath).join('<project>');
|
|
274
|
+
const reinstall = options.reinstallCommandImpl ?? syncWriteCommand;
|
|
275
|
+
if (options.plugin.sourceId && !options.plugin.pluginId) {
|
|
276
|
+
throw new Error(`Plugin "${options.plugin.manifest.name}" is missing its namespaced plugin ID.`);
|
|
294
277
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
env: options.env
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
sanitized = sanitized.split(configPath).join(safeTarget);
|
|
278
|
+
const selector = options.plugin.sourceId
|
|
279
|
+
? options.plugin.pluginId
|
|
280
|
+
: options.plugin.manifest.name;
|
|
281
|
+
const nativeFailures = [];
|
|
282
|
+
for (const target of discovered.commandPackages ?? []) {
|
|
283
|
+
try {
|
|
284
|
+
await assertManagedCommandPackageNativeToolsUnchanged({ plugin: options.plugin, producer: target.producer, env: options.env });
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
nativeFailures.push({ producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
288
|
+
errors: [managedCommandDiagnostic(error)],
|
|
289
|
+
recoveryActions: [`aw command package sync ${selector} ${target.packageKey} --scope ${target.producer.scope} --yes`] });
|
|
290
|
+
}
|
|
309
291
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
return value;
|
|
317
|
-
if (Array.isArray(value)) {
|
|
318
|
-
return Promise.all(value.map((entry) => sanitizeProjection(entry, target, freeText)));
|
|
292
|
+
if (nativeFailures.length > 0) {
|
|
293
|
+
return { state: 'partial', commandResults: nativeFailures,
|
|
294
|
+
targetResults: [...targetResults, ...discovered.targets.map((target) => ({
|
|
295
|
+
target, action: 'reinstall', state: 'failed', errorCode: 'nativeToolSyncRequired',
|
|
296
|
+
message: 'Run a reviewed producer sync or package sync before configuration apply.',
|
|
297
|
+
}))] };
|
|
319
298
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
299
|
+
const sanitizeFailure = async (message, target) => {
|
|
300
|
+
let sensitiveValues = [];
|
|
301
|
+
try {
|
|
302
|
+
const effective = await resolveEffectivePluginConfig({
|
|
303
|
+
...(options.plugin.sourceId ? {
|
|
304
|
+
sourceId: options.plugin.sourceId,
|
|
305
|
+
sourceIdentity: options.plugin.sourceIdentity,
|
|
306
|
+
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
307
|
+
} : {}),
|
|
308
|
+
pluginName: options.plugin.manifest.name,
|
|
309
|
+
manifest: options.plugin.manifest,
|
|
310
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
311
|
+
targetScope: target.scope,
|
|
312
|
+
platform: target.platform ?? undefined,
|
|
313
|
+
cwd: options.cwd,
|
|
314
|
+
env: options.env,
|
|
315
|
+
});
|
|
316
|
+
sensitiveValues = collectSensitivePluginConfigValues(options.plugin.manifest, effective.values, target.platform ?? undefined);
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Generic credential redaction and known config paths still apply.
|
|
320
|
+
}
|
|
321
|
+
let sanitized = redactPluginScriptOutput(message, sensitiveValues);
|
|
322
|
+
for (const privatePath of [target.projectKey, options.cwd]) {
|
|
323
|
+
if (privatePath)
|
|
324
|
+
sanitized = sanitized.split(privatePath).join('<project>');
|
|
325
|
+
}
|
|
326
|
+
for (const scope of ['user', 'project']) {
|
|
327
|
+
const configPath = resolvePluginConfigStorePath({
|
|
332
328
|
sourceId: options.plugin.sourceId,
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
329
|
+
pluginName: options.plugin.manifest.name,
|
|
330
|
+
scope,
|
|
331
|
+
cwd: options.cwd,
|
|
332
|
+
env: options.env,
|
|
333
|
+
});
|
|
334
|
+
const safeTarget = `${scope}/plugin-config/${[
|
|
335
|
+
options.plugin.sourceId,
|
|
336
|
+
options.plugin.manifest.name,
|
|
337
|
+
'config.json',
|
|
338
|
+
].filter(Boolean).join('/')}`;
|
|
339
|
+
sanitized = sanitized.split(configPath).join(safeTarget);
|
|
340
|
+
}
|
|
341
|
+
return sanitized;
|
|
342
|
+
};
|
|
343
|
+
const sanitizeProjection = async (value, target, freeText = false) => {
|
|
344
|
+
if (typeof value === 'string')
|
|
345
|
+
return freeText ? sanitizeFailure(value, target) : value;
|
|
346
|
+
if (value === null || typeof value !== 'object')
|
|
347
|
+
return value;
|
|
348
|
+
if (Array.isArray(value)) {
|
|
349
|
+
return Promise.all(value.map((entry) => sanitizeProjection(entry, target, freeText)));
|
|
350
|
+
}
|
|
351
|
+
return Object.fromEntries(await Promise.all(Object.entries(value).map(async ([key, entry]) => [
|
|
352
|
+
key,
|
|
353
|
+
await sanitizeProjection(entry, target, typeof entry === 'string'
|
|
354
|
+
? /^(?:message|error|stack|stdout|stderr|output|warning)$/u.test(key)
|
|
355
|
+
: Array.isArray(entry) && /^(?:messages|warnings)$/u.test(key)),
|
|
356
|
+
])));
|
|
357
|
+
};
|
|
358
|
+
const preApplyExecutionCache = new Map();
|
|
359
|
+
for (const target of discovered.targets) {
|
|
360
|
+
if (failedScopes.has(target.scope))
|
|
361
|
+
continue;
|
|
362
|
+
try {
|
|
363
|
+
const configs = await Promise.all(pluginConfigTargetRenderScopes(options.plugin, target).map((scope) => resolveEffectivePluginConfig({
|
|
364
|
+
...(options.plugin.sourceId ? {
|
|
365
|
+
sourceId: options.plugin.sourceId,
|
|
366
|
+
sourceIdentity: options.plugin.sourceIdentity,
|
|
367
|
+
logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
368
|
+
} : {}),
|
|
369
|
+
pluginName: options.plugin.manifest.name,
|
|
370
|
+
manifest: options.plugin.manifest,
|
|
371
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
372
|
+
targetScope: scope,
|
|
373
|
+
platform: target.platform ?? undefined,
|
|
374
|
+
cwd: options.cwd,
|
|
375
|
+
env: options.env,
|
|
376
|
+
})));
|
|
377
|
+
if (configs.some((effective) => effective.issues.length > 0)) {
|
|
378
|
+
invalidTargets += 1;
|
|
379
|
+
targetResults.push({
|
|
380
|
+
target,
|
|
381
|
+
action: 'reinstall',
|
|
382
|
+
state: 'skipped',
|
|
383
|
+
errorCode: 'invalidConfig',
|
|
384
|
+
message: 'The effective config is invalid for this target.',
|
|
385
|
+
});
|
|
386
|
+
continue;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
catch {
|
|
390
|
+
runtimeFailed = true;
|
|
391
|
+
unavailableTargets += 1;
|
|
345
392
|
targetResults.push({
|
|
346
393
|
target,
|
|
347
394
|
action: 'reinstall',
|
|
348
|
-
state: '
|
|
349
|
-
errorCode: '
|
|
350
|
-
message: 'The effective config
|
|
395
|
+
state: 'failed',
|
|
396
|
+
errorCode: 'effectiveConfigUnavailable',
|
|
397
|
+
message: 'The effective config cannot be read for this target.',
|
|
398
|
+
});
|
|
399
|
+
errors.push({
|
|
400
|
+
stage: 'targetValidation',
|
|
401
|
+
code: 'effectiveConfigUnavailable',
|
|
402
|
+
message: 'The effective config cannot be read for a visible target.',
|
|
351
403
|
});
|
|
352
404
|
continue;
|
|
353
405
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
const debugLogger = options.rebuildRuntime?.debugLogger;
|
|
374
|
-
const reporter = options.rebuildRuntime?.reporter;
|
|
375
|
-
const result = await reinstall([selector], {
|
|
376
|
-
cwd: options.cwd,
|
|
377
|
-
platform: target.platform,
|
|
378
|
-
scope: target.scope,
|
|
379
|
-
...(options.rebuildRuntime?.scriptTimeoutMs === undefined
|
|
380
|
-
? {}
|
|
381
|
-
: { scriptTimeoutMs: options.rebuildRuntime.scriptTimeoutMs }),
|
|
382
|
-
}, {
|
|
383
|
-
...options.rebuildRuntime,
|
|
384
|
-
env: options.env,
|
|
385
|
-
nativeCliRunner,
|
|
386
|
-
preApplyConfirmed: options.preApplyConfirmed === true,
|
|
387
|
-
preApplyExecutionCache,
|
|
388
|
-
managedCommandProducerCache,
|
|
389
|
-
...(debugLogger ? {
|
|
390
|
-
debugLogger: {
|
|
391
|
-
...debugLogger,
|
|
392
|
-
log: async (value) => debugLogger.log(await sanitizeProjection(value, target)),
|
|
393
|
-
},
|
|
394
|
-
} : {}),
|
|
395
|
-
...(reporter ? {
|
|
396
|
-
reporter: {
|
|
397
|
-
event: async (value) => reporter.event(await sanitizeProjection(value, target)),
|
|
398
|
-
notice: async (value) => reporter.notice(await sanitizeProjection(value, target)),
|
|
406
|
+
try {
|
|
407
|
+
const debugLogger = options.rebuildRuntime?.debugLogger;
|
|
408
|
+
const reporter = options.rebuildRuntime?.reporter;
|
|
409
|
+
const result = await reinstall([selector], {
|
|
410
|
+
cwd: contexts.get(target.scope).executionCwd,
|
|
411
|
+
platform: target.platform,
|
|
412
|
+
scope: target.scope,
|
|
413
|
+
...(options.rebuildRuntime?.scriptTimeoutMs === undefined
|
|
414
|
+
? {}
|
|
415
|
+
: { scriptTimeoutMs: options.rebuildRuntime.scriptTimeoutMs }),
|
|
416
|
+
}, {
|
|
417
|
+
...options.rebuildRuntime,
|
|
418
|
+
env: contexts.get(target.scope).env,
|
|
419
|
+
nativeCliRunner,
|
|
420
|
+
executionInput: {
|
|
421
|
+
context: contexts.get(target.scope),
|
|
422
|
+
requirements: demandNativeProjection(demands.get(target.scope)),
|
|
423
|
+
selectedTargets: [{ pluginId: selector, platform: target.platform, scope: target.scope }],
|
|
424
|
+
preserveOtherObservedTargets: true,
|
|
399
425
|
},
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
426
|
+
preApplyConfirmed: options.preApplyConfirmed === true,
|
|
427
|
+
preApplyExecutionCache,
|
|
428
|
+
managedCommandProducerCache,
|
|
429
|
+
...(debugLogger ? {
|
|
430
|
+
debugLogger: {
|
|
431
|
+
...debugLogger,
|
|
432
|
+
log: async (value) => debugLogger.log(await sanitizeProjection(value, target)),
|
|
433
|
+
},
|
|
434
|
+
} : {}),
|
|
435
|
+
...(reporter ? {
|
|
436
|
+
reporter: {
|
|
437
|
+
event: async (value) => reporter.event(await sanitizeProjection(value, target)),
|
|
438
|
+
notice: async (value) => reporter.notice(await sanitizeProjection(value, target)),
|
|
439
|
+
},
|
|
440
|
+
} : {}),
|
|
441
|
+
});
|
|
442
|
+
options.rebuildRuntime?.operationDiagnosticSink?.(result.rebuildResults);
|
|
443
|
+
for (const producer of result.commandResults ?? []) {
|
|
444
|
+
commandResults.set(getCommandPackageId(producer.producer), producer);
|
|
445
|
+
if (producer.state !== 'completed')
|
|
446
|
+
runtimeFailed = true;
|
|
447
|
+
}
|
|
448
|
+
if (result.overallState !== 'succeeded')
|
|
406
449
|
runtimeFailed = true;
|
|
450
|
+
targetResults.push(...await Promise.all(result.targetResults.map(async (entry) => ({
|
|
451
|
+
...entry,
|
|
452
|
+
state: entry.action === 'skipped' ? 'skipped' : entry.state,
|
|
453
|
+
...(entry.message ? { message: await sanitizeFailure(entry.message, entry.target) } : {}),
|
|
454
|
+
}))));
|
|
407
455
|
}
|
|
408
|
-
|
|
456
|
+
catch (error) {
|
|
409
457
|
runtimeFailed = true;
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
action: 'reinstall',
|
|
422
|
-
state: 'failed',
|
|
423
|
-
message,
|
|
424
|
-
});
|
|
425
|
-
errors.push({
|
|
426
|
-
stage: 'apply',
|
|
427
|
-
code: 'targetApplyFailed',
|
|
428
|
-
message: 'A visible config apply target failed.',
|
|
429
|
-
});
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
for (const target of discovered.commandPackages ?? []) {
|
|
433
|
-
await options.rebuildRuntime?.reporter?.event({
|
|
434
|
-
type: 'managed-command:producer',
|
|
435
|
-
source: { plugin: options.plugin.manifest.name, scope: target.producer.scope },
|
|
436
|
-
data: { packageKey: target.packageKey, phase: 'start' },
|
|
437
|
-
});
|
|
438
|
-
let result;
|
|
439
|
-
if (!target.declared) {
|
|
440
|
-
result = {
|
|
441
|
-
producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
442
|
-
errors: [{ code: 'commandPackageDeclarationMissing',
|
|
443
|
-
message: 'The installed command package is no longer declared by this plugin.' }],
|
|
444
|
-
recoveryActions: [`aw command package remove ${target.packageId} --yes`],
|
|
445
|
-
};
|
|
446
|
-
}
|
|
447
|
-
else {
|
|
448
|
-
try {
|
|
449
|
-
result = await syncPluginManagedCommandPackage({
|
|
450
|
-
plugin: options.plugin, packageKey: target.packageKey, scope: target.producer.scope,
|
|
451
|
-
cwd: options.cwd, env: options.env, managedCommandProducerCache,
|
|
452
|
-
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
453
|
-
event: options.changedConfigKeys?.length ? 'refresh' : 'install',
|
|
454
|
-
changedConfigKeys: options.changedConfigKeys ?? [],
|
|
458
|
+
const message = await sanitizeFailure(error instanceof Error ? error.message : String(error), target);
|
|
459
|
+
targetResults.push({
|
|
460
|
+
target,
|
|
461
|
+
action: 'reinstall',
|
|
462
|
+
state: 'failed',
|
|
463
|
+
message,
|
|
464
|
+
});
|
|
465
|
+
errors.push({
|
|
466
|
+
stage: 'apply',
|
|
467
|
+
code: 'targetApplyFailed',
|
|
468
|
+
message: 'A visible config apply target failed.',
|
|
455
469
|
});
|
|
456
470
|
}
|
|
457
|
-
|
|
471
|
+
}
|
|
472
|
+
for (const target of discovered.commandPackages ?? []) {
|
|
473
|
+
await options.rebuildRuntime?.reporter?.event({
|
|
474
|
+
type: 'managed-command:producer',
|
|
475
|
+
source: { plugin: options.plugin.manifest.name, scope: target.producer.scope },
|
|
476
|
+
data: { packageKey: target.packageKey, phase: 'start' },
|
|
477
|
+
});
|
|
478
|
+
let result;
|
|
479
|
+
if (!target.declared) {
|
|
458
480
|
result = {
|
|
459
481
|
producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
460
|
-
errors: [{ code: '
|
|
461
|
-
|
|
462
|
-
|
|
482
|
+
errors: [{ code: 'commandPackageDeclarationMissing',
|
|
483
|
+
message: 'The installed command package is no longer declared by this plugin.' }],
|
|
484
|
+
recoveryActions: [`aw command package remove ${target.packageId} --yes`],
|
|
463
485
|
};
|
|
464
486
|
}
|
|
487
|
+
else {
|
|
488
|
+
try {
|
|
489
|
+
result = await syncPluginManagedCommandPackage({
|
|
490
|
+
plugin: options.plugin, packageKey: target.packageKey, scope: target.producer.scope,
|
|
491
|
+
cwd: options.cwd, env: options.env, managedCommandProducerCache,
|
|
492
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
493
|
+
event: options.changedConfigKeys?.length ? 'refresh' : 'install',
|
|
494
|
+
changedConfigKeys: options.changedConfigKeys ?? [],
|
|
495
|
+
signal: options.rebuildRuntime?.signal,
|
|
496
|
+
scriptTimeoutMs: options.rebuildRuntime?.scriptTimeoutMs,
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
if (options.rebuildRuntime?.signal?.aborted
|
|
501
|
+
|| error instanceof Error && error.name === 'AbortError'
|
|
502
|
+
|| readSafeOperationError(error))
|
|
503
|
+
throw error;
|
|
504
|
+
result = {
|
|
505
|
+
producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
506
|
+
errors: [{ code: 'commandPackageApplyFailed', message: 'The managed command package could not be refreshed.' }],
|
|
507
|
+
recoveryActions: [`aw command package sync ${selector} ${target.packageKey} --scope ${target.producer.scope} --yes`,
|
|
508
|
+
`aw command package remove ${target.packageId} --yes`],
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
result = { ...result, errors: await Promise.all(result.errors.map(async (error) => ({
|
|
513
|
+
...error, message: await sanitizeFailure(error.message, { scope: target.producer.scope,
|
|
514
|
+
...(target.producer.projectRoot ? { projectKey: target.producer.projectRoot } : {}) }),
|
|
515
|
+
}))) };
|
|
516
|
+
commandResults.set(getCommandPackageId(result.producer), result);
|
|
517
|
+
await options.rebuildRuntime?.reporter?.event({
|
|
518
|
+
type: 'managed-command:producer',
|
|
519
|
+
source: { plugin: options.plugin.manifest.name, scope: target.producer.scope },
|
|
520
|
+
data: { packageKey: target.packageKey, phase: result.state === 'completed' ? 'success' : 'failure' },
|
|
521
|
+
});
|
|
522
|
+
if (result.state !== 'completed')
|
|
523
|
+
runtimeFailed = true;
|
|
465
524
|
}
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
return {
|
|
525
|
+
const commands = commandResults.size > 0 ? { commandResults: [...commandResults.values()] } : {};
|
|
526
|
+
const commandTargetCount = (discovered.commandPackages?.length ?? 0);
|
|
527
|
+
if (discovered.targets.length === 0 && discovered.failures.length === 0
|
|
528
|
+
&& commandTargetCount === 0 && !runtimeFailed) {
|
|
529
|
+
return skippedApply('noVisibleTarget');
|
|
530
|
+
}
|
|
531
|
+
if (discovered.targets.length > 0 && invalidTargets === discovered.targets.length && commandTargetCount === 0) {
|
|
532
|
+
return { ...unavailableApply('invalidConfig', 'targetValidation', targetResults), ...commands };
|
|
533
|
+
}
|
|
534
|
+
if (discovered.targets.length > 0 && unavailableTargets === discovered.targets.length && commandTargetCount === 0) {
|
|
535
|
+
return { ...unavailableApply('effectiveConfigUnavailable', 'targetValidation', targetResults), ...commands };
|
|
536
|
+
}
|
|
537
|
+
if (runtimeFailed
|
|
538
|
+
|| invalidTargets > 0
|
|
539
|
+
|| unavailableTargets > 0
|
|
540
|
+
|| targetResults.some((entry) => entry.state === 'failed' || entry.state === 'skipped')) {
|
|
541
|
+
return {
|
|
542
|
+
state: 'partial',
|
|
543
|
+
targetResults,
|
|
544
|
+
...commands,
|
|
545
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
return { state: 'succeeded', targetResults, ...commands };
|
|
490
549
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|| unavailableTargets > 0
|
|
494
|
-
|| targetResults.some((entry) => entry.state === 'failed' || entry.state === 'skipped')) {
|
|
495
|
-
return {
|
|
496
|
-
state: 'partial',
|
|
497
|
-
targetResults,
|
|
498
|
-
...commands,
|
|
499
|
-
...(errors.length > 0 ? { errors } : {}),
|
|
500
|
-
};
|
|
550
|
+
finally {
|
|
551
|
+
await Promise.all([...contexts.values()].map((context) => context.dispose()));
|
|
501
552
|
}
|
|
502
|
-
return { state: 'succeeded', targetResults, ...commands };
|
|
503
553
|
}
|
|
504
554
|
async function resolveConfigApplyTargets(options) {
|
|
505
555
|
const platformTargets = options.applyTargets !== undefined
|
|
@@ -523,48 +573,19 @@ async function resolveConfigApplyTargets(options) {
|
|
|
523
573
|
async function configApplyHasValidSharedNativeTarget(options) {
|
|
524
574
|
const plugins = await resolvePluginConfigReferenceConsumers({ plugin: options.plugin, env: options.env, plugins: options.plugins });
|
|
525
575
|
for (const plugin of plugins) {
|
|
526
|
-
const
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
pluginName: plugin.manifest.name,
|
|
537
|
-
manifest: plugin.manifest,
|
|
538
|
-
referencePlugins: options.plugins,
|
|
539
|
-
targetScope: 'user',
|
|
540
|
-
cwd: options.cwd,
|
|
541
|
-
env: options.env,
|
|
542
|
-
});
|
|
543
|
-
if (effective.issues.length === 0)
|
|
544
|
-
return true;
|
|
545
|
-
}
|
|
546
|
-
return false;
|
|
547
|
-
}
|
|
548
|
-
async function applyConfigToVisibleTargets(options) {
|
|
549
|
-
let discovered;
|
|
550
|
-
if (options.discovered) {
|
|
551
|
-
discovered = options.discovered;
|
|
552
|
-
}
|
|
553
|
-
else {
|
|
554
|
-
try {
|
|
555
|
-
discovered = await resolveConfigApplyTargets(options);
|
|
556
|
-
}
|
|
557
|
-
catch {
|
|
558
|
-
return unavailableApply('targetDiscoveryFailed', 'targetDiscovery');
|
|
576
|
+
for (const target of options.targets.filter((target) => target.pluginName === plugin.manifest.name)) {
|
|
577
|
+
const shared = pluginSharedNativeConfigTargets(plugin);
|
|
578
|
+
if (!shared.some((entry) => (entry.platform ?? 'codex') === target.platform))
|
|
579
|
+
continue;
|
|
580
|
+
const effective = await resolveEffectivePluginConfig({ sourceId: plugin.sourceId,
|
|
581
|
+
sourceIdentity: plugin.sourceIdentity, logicalIdentity: plugin.catalogLogicalIdentity,
|
|
582
|
+
manifest: plugin.manifest, platform: target.platform, targetScope: 'user',
|
|
583
|
+
cwd: options.cwd, env: options.env, referencePlugins: options.plugins });
|
|
584
|
+
if (!effective.issues.length)
|
|
585
|
+
return true;
|
|
559
586
|
}
|
|
560
587
|
}
|
|
561
|
-
|
|
562
|
-
&& discovered.failures.length === 0
|
|
563
|
-
&& (discovered.commandPackages?.length ?? 0) === 0
|
|
564
|
-
&& options.noVisibleTargetHasInvalidConfig) {
|
|
565
|
-
return unavailableApply('invalidConfig', 'targetValidation');
|
|
566
|
-
}
|
|
567
|
-
return reinstallVisibleTargets({ ...options, discovered });
|
|
588
|
+
return false;
|
|
568
589
|
}
|
|
569
590
|
export async function resolveConfigPreApplyAuthorization(options) {
|
|
570
591
|
const applyTargets = dedupeTargets(options.applyTargets);
|
|
@@ -609,17 +630,27 @@ export async function resolveConfigPreApplyAuthorization(options) {
|
|
|
609
630
|
const resolveGroup = async (targets) => {
|
|
610
631
|
const platforms = new Set(targets.map((target) => target.platform));
|
|
611
632
|
const platform = platforms.size === 2 ? 'both' : [...platforms][0];
|
|
633
|
+
let context;
|
|
612
634
|
try {
|
|
635
|
+
context = await createScopeContext({ scope: targets[0].scope, cwd: options.cwd, env: options.env });
|
|
636
|
+
const demand = await readDemand({ scope: targets[0].scope,
|
|
637
|
+
cwd: context.executionCwd, env: context.env });
|
|
613
638
|
const preview = await (options.reinstallCommandImpl ?? syncWriteCommand)([selector], {
|
|
614
|
-
cwd:
|
|
639
|
+
cwd: context.executionCwd,
|
|
615
640
|
platform,
|
|
616
641
|
scope: targets[0].scope,
|
|
617
642
|
}, {
|
|
618
643
|
...options.rebuildRuntime,
|
|
619
|
-
env:
|
|
644
|
+
env: context.env,
|
|
620
645
|
nativeCliRunner: options.nativeCliRunner,
|
|
621
646
|
previewOperationPlan: true,
|
|
622
647
|
resolvePreApplyAuthorization: true,
|
|
648
|
+
executionInput: {
|
|
649
|
+
context, requirements: demandNativeProjection(demand),
|
|
650
|
+
selectedTargets: targets.map((target) => ({ pluginId: selector,
|
|
651
|
+
platform: target.platform, scope: target.scope })),
|
|
652
|
+
preserveOtherObservedTargets: true,
|
|
653
|
+
},
|
|
623
654
|
});
|
|
624
655
|
if (preview.overallState !== 'succeeded' || !preview.preApplyAuthorization)
|
|
625
656
|
return false;
|
|
@@ -630,6 +661,9 @@ export async function resolveConfigPreApplyAuthorization(options) {
|
|
|
630
661
|
catch {
|
|
631
662
|
return false;
|
|
632
663
|
}
|
|
664
|
+
finally {
|
|
665
|
+
await context?.dispose();
|
|
666
|
+
}
|
|
633
667
|
};
|
|
634
668
|
for (const targets of groups.values()) {
|
|
635
669
|
if (await resolveGroup(targets))
|
|
@@ -686,7 +720,7 @@ function preApplyAuthorizationIsConfirmed(options) {
|
|
|
686
720
|
}
|
|
687
721
|
function otherProjectsWarning(scope) {
|
|
688
722
|
return scope === 'user'
|
|
689
|
-
? ['其它项目不会由本次命令扫描或更新,可能需要在对应项目目录中运行 aw sync。']
|
|
723
|
+
? ['其它项目不会由本次命令扫描或更新,可能需要在对应项目目录中运行 aw plugin sync --context project。']
|
|
690
724
|
: [];
|
|
691
725
|
}
|
|
692
726
|
function buildReceiptFieldEntry(options) {
|
|
@@ -816,303 +850,397 @@ export async function replayConfigRuntimeWrites(options) {
|
|
|
816
850
|
},
|
|
817
851
|
});
|
|
818
852
|
}
|
|
819
|
-
function
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
throw error;
|
|
853
|
+
function configApplyRequestedTargets(plan) {
|
|
854
|
+
return plan.receipt.requestedTargets.filter((target) => !plan.receipt.targetResults.some((result) => result.pluginId === target.pluginId && result.agent === target.agent && result.scope === target.scope
|
|
855
|
+
&& (result.satisfaction === 'unsupported' || result.satisfaction === 'excluded')));
|
|
823
856
|
}
|
|
824
|
-
async function
|
|
825
|
-
const
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
const
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
const duplicateKeys = requestedRemoveKeys.filter((key) => Object.hasOwn(requestedUpdates, key));
|
|
837
|
-
if (duplicateKeys.length > 0) {
|
|
838
|
-
throw new Error(`Config write cannot update and remove the same key: ${duplicateKeys.join(', ')}.`);
|
|
839
|
-
}
|
|
840
|
-
const schemaAccess = await resolvePluginConfigSchemaAccess({
|
|
841
|
-
pluginName,
|
|
842
|
-
currentPlugin: options.plugin,
|
|
843
|
-
currentPluginError: options.pluginError,
|
|
844
|
-
scope: options.scope,
|
|
845
|
-
cwd: options.cwd,
|
|
846
|
-
env: options.env,
|
|
847
|
-
});
|
|
848
|
-
const schemaPlugin = schemaAccess.plugin;
|
|
849
|
-
const schema = schemaPlugin?.manifest.config?.fields;
|
|
850
|
-
if (!schema || !schemaPlugin) {
|
|
851
|
-
throw new Error(`configSchemaUnavailable: Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
852
|
-
}
|
|
853
|
-
if (options.scope === 'project') {
|
|
854
|
-
const userStore = await readPluginConfigStore({
|
|
855
|
-
...configIdentity,
|
|
856
|
-
pluginName,
|
|
857
|
-
scope: 'user',
|
|
858
|
-
cwd: options.cwd,
|
|
859
|
-
env: options.env,
|
|
860
|
-
schema,
|
|
861
|
-
});
|
|
862
|
-
assertReadyPluginConfigStore(userStore);
|
|
863
|
-
}
|
|
864
|
-
if (options.scope === 'project') {
|
|
865
|
-
const rejectedSensitiveKeys = Object.keys(requestedUpdates)
|
|
866
|
-
.filter((key) => schema[key]?.sensitive === true);
|
|
867
|
-
if (rejectedSensitiveKeys.length > 0) {
|
|
868
|
-
const error = new Error('sensitiveProjectConfigUnsupported: Sensitive config can only be set in user scope.');
|
|
869
|
-
error.code = 'sensitiveProjectConfigUnsupported';
|
|
870
|
-
throw error;
|
|
871
|
-
}
|
|
872
|
-
const userOnlyKeys = codexNativeRefreshKeys(schemaPlugin.manifest);
|
|
873
|
-
const rejectedKeys = Object.keys(requestedUpdates).filter((key) => userOnlyKeys.has(key));
|
|
874
|
-
if (rejectedKeys.length > 0) {
|
|
875
|
-
const error = new Error(`sharedNativeConfigUserScopeRequired: Codex native Skill refresh keys can only be set in user scope: ${rejectedKeys.join(', ')}.`);
|
|
876
|
-
error.code = 'sharedNativeConfigUserScopeRequired';
|
|
877
|
-
throw error;
|
|
857
|
+
async function prepareConfigApplyPackages(options, plugins, plan, referencePlugins) {
|
|
858
|
+
const env = options.env ?? process.env;
|
|
859
|
+
const context = options.context ?? options.scope;
|
|
860
|
+
const discoveries = [];
|
|
861
|
+
const scopes = context === 'project' ? ['user', 'project'] : ['user'];
|
|
862
|
+
const nativeTargets = configApplyRequestedTargets(plan).flatMap((target) => target.agent === 'codex' || target.agent === 'claude'
|
|
863
|
+
? [{ pluginName: target.pluginId.split('/').at(-1), pluginId: target.pluginId, platform: target.agent, scope: target.scope }] : []);
|
|
864
|
+
for (const plugin of plugins) {
|
|
865
|
+
for (const scope of scopes) {
|
|
866
|
+
discoveries.push(await discoverInstalledPluginManagedCommandPackages({ plugin, scope, cwd: options.cwd, env,
|
|
867
|
+
platformTargets: nativeTargets.filter((target) => target.pluginId === (plugin.pluginId ?? plugin.manifest.name)
|
|
868
|
+
&& (scope === 'user' || target.scope === 'project')) }));
|
|
878
869
|
}
|
|
879
870
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
871
|
+
const packages = [...new Map(discoveries.flatMap((discovery) => discovery.packages).filter((target) => {
|
|
872
|
+
if (options.applyCommandPackages && !options.applyCommandPackages.includes(target.packageId))
|
|
873
|
+
return false;
|
|
874
|
+
if (options.platform)
|
|
875
|
+
return false;
|
|
876
|
+
if (!options.targets)
|
|
877
|
+
return true;
|
|
878
|
+
const plugin = plugins.find((entry) => entry.manifest.name === target.producer.pluginName);
|
|
879
|
+
const declaration = plugin?.manifest.managedCommands?.packages.find((entry) => entry.key === target.packageKey && entry.scope === target.producer.scope);
|
|
880
|
+
return declaration?.platforms.some((platform) => options.targets.includes(platform)) ?? false;
|
|
881
|
+
}).map((target) => [target.packageId, target])).values()];
|
|
882
|
+
const inventory = await listManagedCommandPackages(env);
|
|
883
|
+
const entries = await Promise.all(packages.map(async (target) => {
|
|
884
|
+
const plugin = plugins.find((entry) => entry.manifest.name === target.producer.pluginName);
|
|
885
|
+
const installed = inventory.packages.find((entry) => entry.id === target.packageId);
|
|
886
|
+
let recordDigest;
|
|
887
|
+
let blocker;
|
|
888
|
+
if (!target.installed || !installed) {
|
|
889
|
+
blocker = { code: 'configApplyRequiresExistingOutput', message: 'Configuration apply requires an existing command package. Run package sync first.' };
|
|
893
890
|
}
|
|
894
|
-
|
|
895
|
-
|
|
891
|
+
else if (!target.declared) {
|
|
892
|
+
blocker = { code: 'commandPackageDeclarationMissing', message: 'The installed command package is no longer declared by this plugin.' };
|
|
896
893
|
}
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
894
|
+
else {
|
|
895
|
+
try {
|
|
896
|
+
const record = await readInstalledCommandProducer(installed.resourceRoot);
|
|
897
|
+
recordDigest = `sha256:${crypto.createHash('sha256').update(JSON.stringify(record)).digest('hex')}`;
|
|
898
|
+
await assertManagedCommandPackageNativeToolsUnchanged({ plugin, producer: target.producer, env });
|
|
899
|
+
}
|
|
900
|
+
catch (error) {
|
|
901
|
+
blocker = managedCommandDiagnostic(error);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
return { target, recordDigest, blocker };
|
|
905
|
+
}));
|
|
906
|
+
const errors = [...new Map(discoveries.flatMap((discovery) => discovery.errors).map((error) => [JSON.stringify(error), error])).values()];
|
|
907
|
+
const evidence = { packages: entries, errors };
|
|
908
|
+
const targets = [...new Map(entries.map(({ target }) => {
|
|
909
|
+
const plugin = plugins.find((entry) => entry.manifest.name === target.producer.pluginName);
|
|
910
|
+
const pluginId = plugin.pluginId ?? plugin.manifest.name;
|
|
911
|
+
const dependencies = resolvePluginMetaDependencyClosure(referencePlugins, [plugin.manifest.name])
|
|
912
|
+
.filter((entry) => entry.manifest.name !== plugin.manifest.name).map((entry) => entry.pluginId ?? entry.manifest.name);
|
|
913
|
+
return [`${pluginId}\0${target.producer.scope}`, { pluginId, scope: target.producer.scope, dependencies }];
|
|
914
|
+
})).values()];
|
|
915
|
+
const cache = plan.runtime.managedCommandProducerCache ??= new Map();
|
|
916
|
+
const hook = { targets, evidence,
|
|
917
|
+
blocked: (pluginId, scope, code) => {
|
|
918
|
+
const plugin = plugins.find((entry) => (entry.pluginId ?? entry.manifest.name) === pluginId);
|
|
919
|
+
return entries.filter(({ target }) => target.producer.pluginName === plugin.manifest.name && target.producer.scope === scope)
|
|
920
|
+
.map(({ target }) => ({
|
|
921
|
+
producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
922
|
+
errors: [{ code, message: 'A required provider failed; the command package was not refreshed.' }],
|
|
923
|
+
recoveryActions: [`aw command package sync ${pluginId} ${target.packageKey} --scope ${scope} --yes`],
|
|
924
|
+
}));
|
|
912
925
|
},
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
926
|
+
execute: async (pluginId, scope, token) => {
|
|
927
|
+
const plugin = plugins.find((entry) => (entry.pluginId ?? entry.manifest.name) === pluginId);
|
|
928
|
+
const selected = entries.filter(({ target }) => target.producer.pluginName === plugin.manifest.name && target.producer.scope === scope);
|
|
929
|
+
const results = [];
|
|
930
|
+
let executionContext;
|
|
931
|
+
try {
|
|
932
|
+
executionContext = await createScopeContext({ scope, cwd: options.cwd, env });
|
|
933
|
+
for (const { target, blocker } of selected) {
|
|
934
|
+
if (blocker) {
|
|
935
|
+
const result = { producer: target.producer, state: 'failed', commandIds: [], removedCommandIds: [],
|
|
936
|
+
errors: [blocker], recoveryActions: [target.declared
|
|
937
|
+
? `aw command package sync ${pluginId} ${target.packageKey} --scope ${scope} --yes`
|
|
938
|
+
: `aw command package remove ${target.packageId} --yes`] };
|
|
939
|
+
cache.set(target.packageId, Promise.resolve(result));
|
|
940
|
+
results.push(result);
|
|
941
|
+
continue;
|
|
942
|
+
}
|
|
943
|
+
const applied = await reinstallVisibleTargets({ plugin, scope, cwd: executionContext.executionCwd, env: executionContext.env,
|
|
944
|
+
changedConfigKeys: [...target.refreshKeys],
|
|
945
|
+
rebuildRuntime: { ...options.rebuildRuntime, awHomeMutationToken: token, referencePlugins, managedCommandProducerCache: cache },
|
|
946
|
+
discovered: { targets: [], failures: [], commandPackages: [target], commandDiscoveryErrors: [] } });
|
|
947
|
+
results.push(...('commandResults' in applied ? applied.commandResults ?? [] : []));
|
|
948
|
+
}
|
|
949
|
+
return results;
|
|
950
|
+
}
|
|
951
|
+
finally {
|
|
952
|
+
await executionContext?.dispose();
|
|
953
|
+
}
|
|
954
|
+
} };
|
|
955
|
+
return { packages, evidence, errors, hook };
|
|
956
|
+
}
|
|
957
|
+
/** Prepare the same existing-output plan used by apply, without saving config or output. */
|
|
958
|
+
export async function preparePluginConfigApply(options) {
|
|
959
|
+
const { prepareRecovery, describeRecoveryPlan } = await import('../recovery/coordinator.js');
|
|
960
|
+
const context = options.context ?? options.scope;
|
|
961
|
+
const referencePlugins = await resolvePluginConfigReferencePlugins({ sourceId: options.plugin.sourceId,
|
|
962
|
+
sourceIdentity: options.plugin.sourceIdentity, logicalIdentity: options.plugin.catalogLogicalIdentity,
|
|
963
|
+
env: options.env, plugins: options.rebuildRuntime?.referencePlugins });
|
|
964
|
+
const plugins = await resolvePluginConfigReferenceConsumers({ plugin: options.plugin, env: options.env,
|
|
965
|
+
plugins: referencePlugins });
|
|
966
|
+
const selectors = plugins.map((plugin) => plugin.pluginId ?? plugin.manifest.name);
|
|
967
|
+
const version = options.cliVersion
|
|
968
|
+
?? (await fs.readJson(path.join(resolveCliPackageRoot(), 'package.json'))).version;
|
|
969
|
+
let exactTargets = options.applyTargets?.map((target) => ({
|
|
970
|
+
pluginId: target.pluginId ?? plugins.find((plugin) => plugin.manifest.name === target.pluginName)?.pluginId ?? target.pluginName,
|
|
971
|
+
agent: target.platform,
|
|
972
|
+
scope: target.scope,
|
|
973
|
+
}));
|
|
974
|
+
const retainedLegacyTargets = [];
|
|
975
|
+
if (exactTargets?.some((target) => target.agent === 'codex' || target.agent === 'claude')) {
|
|
976
|
+
const { readRecoveryStatus } = await import('../recovery/status.js');
|
|
977
|
+
const observed = await readRecoveryStatus({ context, cwd: options.cwd, env: options.env, cliVersion: version,
|
|
978
|
+
nativeCliRunner: options.nativeCliRunner ?? options.rebuildRuntime?.nativeCliRunner,
|
|
979
|
+
codexObservationSession: options.rebuildRuntime?.codexObservationSession });
|
|
980
|
+
const key = (target) => `${target.pluginId}\0${target.agent}\0${target.scope}`;
|
|
981
|
+
const live = new Set(observed.existingTargets?.map(key));
|
|
982
|
+
const owned = new Set(observed.ownedTargets?.map(key));
|
|
983
|
+
exactTargets = exactTargets.filter((target, index) => {
|
|
984
|
+
if ((target.agent === 'codex' || target.agent === 'claude') && owned.has(key(target)) && !live.has(key(target))) {
|
|
985
|
+
retainedLegacyTargets.push(options.applyTargets[index]);
|
|
986
|
+
return false;
|
|
987
|
+
}
|
|
988
|
+
return true;
|
|
989
|
+
});
|
|
990
|
+
}
|
|
991
|
+
const plan = await prepareRecovery('sync', selectors, {
|
|
992
|
+
scope: context,
|
|
993
|
+
context,
|
|
920
994
|
cwd: options.cwd,
|
|
921
995
|
env: options.env,
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
996
|
+
cliVersion: version,
|
|
997
|
+
existingOnly: true,
|
|
998
|
+
...(exactTargets ? { exactTargets } : {}),
|
|
999
|
+
...(options.targets ? { targets: options.targets } : options.platform ? { targets: [options.platform] } : {}),
|
|
1000
|
+
}, {
|
|
1001
|
+
...options.rebuildRuntime,
|
|
1002
|
+
referencePlugins,
|
|
1003
|
+
nativeCliRunner: options.nativeCliRunner,
|
|
1004
|
+
awHomeMutationToken: options.awHomeMutationToken,
|
|
1005
|
+
preApplyConfirmed: options.preApplyConfirmed,
|
|
925
1006
|
});
|
|
926
|
-
|
|
927
|
-
|
|
1007
|
+
try {
|
|
1008
|
+
plan.warnings.push(...retainedLegacyTargets.map((target) => `${target.pluginId ?? target.pluginName}/${target.platform}/${target.scope}:保留已停用的历史输出;配置 apply 不创建激活。`));
|
|
1009
|
+
const commands = await prepareConfigApplyPackages(options, plugins, plan, referencePlugins);
|
|
1010
|
+
plan.runtime.configApplyPackages = commands.hook;
|
|
1011
|
+
const profiles = configApplyRequestedTargets(plan).map((target) => ({
|
|
1012
|
+
pluginName: target.pluginId.split('/').at(-1), scope: target.scope, platform: target.agent,
|
|
1013
|
+
}));
|
|
1014
|
+
// A package has platform=null and always consumes the public common profile.
|
|
1015
|
+
profiles.push(...commands.packages.map((target) => ({ pluginName: target.producer.pluginName,
|
|
1016
|
+
scope: target.producer.scope, platform: undefined })));
|
|
1017
|
+
const references = await collectPluginConfigReferenceEvidence({ plugin: options.plugin, plugins: referencePlugins,
|
|
1018
|
+
profiles, cwd: options.cwd, env: options.env });
|
|
1019
|
+
const authorization = await resolveConfigPreApplyAuthorization({
|
|
1020
|
+
plugin: options.plugin, scope: context, cwd: options.cwd, env: options.env,
|
|
1021
|
+
applyTargets: configApplyRequestedTargets(plan).flatMap((target) => target.agent === 'codex' || target.agent === 'claude'
|
|
1022
|
+
? [{ pluginName: target.pluginId.split('/').at(-1), pluginId: target.pluginId, platform: target.agent, scope: target.scope }] : []),
|
|
1023
|
+
nativeCliRunner: options.nativeCliRunner,
|
|
1024
|
+
rebuildRuntime: { ...plan.runtime, referencePlugins },
|
|
1025
|
+
});
|
|
1026
|
+
const portableAuthorization = (current) => [
|
|
1027
|
+
...current.preApplyAuthorization ?? [],
|
|
1028
|
+
...(current.joint?.children ?? []).flatMap(portableAuthorization),
|
|
1029
|
+
];
|
|
1030
|
+
const preApplyAuthorization = [...new Map([...authorization.targets, ...portableAuthorization(plan)]
|
|
1031
|
+
.map((target) => [[target.pluginId, target.platform, target.scope].join('\0'), target])).values()];
|
|
1032
|
+
return { plan, retainedLegacyTargets, commandPackages: commands.packages, commandDiscoveryErrors: commands.errors,
|
|
1033
|
+
preApplyAuthorization,
|
|
1034
|
+
evidence: { recovery: describeRecoveryPlan(plan), references, commands: commands.evidence,
|
|
1035
|
+
preApplyAuthorization, retainedLegacyTargets } };
|
|
928
1036
|
}
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
1037
|
+
catch (error) {
|
|
1038
|
+
await disposePluginConfigApply(plan);
|
|
1039
|
+
throw error;
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
export async function disposePluginConfigApply(plan) {
|
|
1043
|
+
for (const child of plan.joint?.children ?? [])
|
|
1044
|
+
await disposePluginConfigApply(child);
|
|
1045
|
+
await plan.context.dispose();
|
|
1046
|
+
}
|
|
1047
|
+
export async function applyPluginConfig(options) {
|
|
1048
|
+
return withAwHomeMutationLock({ env: options.env, token: options.awHomeMutationToken, action: async (token) => {
|
|
1049
|
+
await options.reviewPreflight?.();
|
|
1050
|
+
let prepared;
|
|
1051
|
+
try {
|
|
1052
|
+
const { executeRecovery } = await import('../recovery/coordinator.js');
|
|
1053
|
+
prepared = await preparePluginConfigApply({ ...options, awHomeMutationToken: token });
|
|
1054
|
+
if (options.expectedEvidence !== undefined
|
|
1055
|
+
&& JSON.stringify(options.expectedEvidence) !== JSON.stringify(prepared.evidence)) {
|
|
1056
|
+
throw Object.assign(new Error('operationPlanStale: Configuration apply inputs changed. Prepare a new Review.'), { code: 'operationPlanStale' });
|
|
1057
|
+
}
|
|
1058
|
+
const authorization = prepared.preApplyAuthorization;
|
|
1059
|
+
if (authorization.length && !preApplyAuthorizationIsConfirmed({ required: authorization,
|
|
1060
|
+
confirmed: options.preApplyConfirmed, authorizedTargets: options.preApplyAuthorizedTargets })) {
|
|
1061
|
+
throwPreApplyAuthorizationRequired(authorization);
|
|
1062
|
+
}
|
|
1063
|
+
if (options.sharedNativeApplyConfirmed !== true && await configApplyHasValidSharedNativeTarget({
|
|
1064
|
+
plugin: options.plugin, cwd: options.cwd, env: options.env, plugins: options.rebuildRuntime?.referencePlugins,
|
|
1065
|
+
targets: configApplyRequestedTargets(prepared.plan).flatMap((target) => target.agent === 'codex' || target.agent === 'claude'
|
|
1066
|
+
? [{ pluginName: target.pluginId.split('/').at(-1), pluginId: target.pluginId, platform: target.agent, scope: target.scope }] : []),
|
|
1067
|
+
}))
|
|
1068
|
+
throwSharedNativeApplyConfirmationRequired();
|
|
1069
|
+
const discoveryErrors = prepared.commandDiscoveryErrors.map((error) => ({
|
|
1070
|
+
stage: 'targetDiscovery', code: error.code, message: error.message,
|
|
1071
|
+
}));
|
|
1072
|
+
const receipt = await executeRecovery(prepared.plan, {
|
|
1073
|
+
yes: options.sharedNativeApplyConfirmed === true || options.preApplyConfirmed === true,
|
|
1074
|
+
runtime: { ...options.rebuildRuntime, awHomeMutationToken: token, preApplyConfirmed: options.preApplyConfirmed },
|
|
1075
|
+
});
|
|
1076
|
+
const retainedLegacyTargets = prepared.retainedLegacyTargets.filter((target) => !receipt.targetResults.some((result) => (target.pluginId ? result.pluginId === target.pluginId : result.pluginId.split('/').at(-1) === target.pluginName)
|
|
1077
|
+
&& result.agent === target.platform && result.scope === target.scope));
|
|
1078
|
+
prepared = undefined;
|
|
1079
|
+
const ok = receipt.ok && discoveryErrors.length === 0;
|
|
1080
|
+
const errors = [...discoveryErrors, ...receipt.blockers, ...receipt.errors].map((error) => ({
|
|
1081
|
+
stage: 'stage' in error ? error.stage : 'apply', code: error.code, message: error.message,
|
|
1082
|
+
}));
|
|
1083
|
+
const apply = {
|
|
1084
|
+
state: ok ? 'succeeded' : 'partial',
|
|
1085
|
+
targetResults: [...receipt.targetResults.filter((target) => target.satisfaction !== 'unsupported' && target.satisfaction !== 'excluded').map((target) => ({
|
|
1086
|
+
target: { pluginName: target.pluginId.split('/').at(-1), pluginId: target.pluginId,
|
|
1087
|
+
platform: target.agent, scope: target.scope },
|
|
1088
|
+
action: 'refresh',
|
|
1089
|
+
state: target.execution === 'applied' || target.execution === 'no-op' ? 'completed'
|
|
1090
|
+
: target.execution === 'not-run' ? 'skipped' : 'failed',
|
|
1091
|
+
...(target.blockers.length ? { errorCode: target.blockers[0].code,
|
|
1092
|
+
message: target.blockers.map((item) => item.message).join(' ') } : {}),
|
|
1093
|
+
})), ...retainedLegacyTargets.map((target) => ({
|
|
1094
|
+
target, action: 'refresh', state: 'skipped',
|
|
1095
|
+
message: 'The inactive legacy output was preserved. Configuration apply does not create an activation.',
|
|
1096
|
+
}))],
|
|
1097
|
+
commandResults: receipt.commandResults,
|
|
1098
|
+
...(errors.length ? { errors } : {}),
|
|
1099
|
+
};
|
|
1100
|
+
return { configWrite: 'notStarted', overallState: ok ? 'succeeded' : 'partial', apply,
|
|
1101
|
+
otherProjectsMayRequireSync: true };
|
|
957
1102
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1103
|
+
catch (error) {
|
|
1104
|
+
if (options.rebuildRuntime?.signal?.aborted || error instanceof Error && error.name === 'AbortError'
|
|
1105
|
+
|| readSafeOperationError(error))
|
|
1106
|
+
throw error;
|
|
1107
|
+
const apply = unavailableApply('targetDiscoveryFailed', 'targetDiscovery');
|
|
1108
|
+
const code = error?.code;
|
|
1109
|
+
if (typeof code === 'string')
|
|
1110
|
+
apply.error = { stage: 'apply', code,
|
|
1111
|
+
message: code === 'operationPlanStale' ? 'Configuration apply inputs changed. Prepare a new Review.'
|
|
1112
|
+
: 'The existing outputs cannot be refreshed with the current authorization.' };
|
|
1113
|
+
return { configWrite: 'notStarted', overallState: 'partial', apply, otherProjectsMayRequireSync: true };
|
|
967
1114
|
}
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
1115
|
+
finally {
|
|
1116
|
+
if (prepared)
|
|
1117
|
+
await disposePluginConfigApply(prepared.plan);
|
|
1118
|
+
}
|
|
1119
|
+
} });
|
|
1120
|
+
}
|
|
1121
|
+
function throwSharedNativeApplyConfirmationRequired() {
|
|
1122
|
+
const error = new Error('sharedNativeConfigApplyConfirmationRequired: Applying this user config changes a shared native artifact. Re-run with --yes.');
|
|
1123
|
+
error.code = 'sharedNativeConfigApplyConfirmationRequired';
|
|
1124
|
+
throw error;
|
|
1125
|
+
}
|
|
1126
|
+
async function applyPluginConfigWriteUnlocked(options) {
|
|
1127
|
+
const pluginName = assertSafePluginConfigSegment(options.pluginName ?? options.plugin?.manifest.name ?? '');
|
|
1128
|
+
const identity = options.plugin?.sourceId ? { sourceId: options.plugin.sourceId,
|
|
1129
|
+
sourceIdentity: options.plugin.sourceIdentity, logicalIdentity: options.plugin.catalogLogicalIdentity } : {};
|
|
1130
|
+
const requestedUpdates = options.request.updates ?? {};
|
|
1131
|
+
const removeKeys = uniqueInOrder(options.request.removeKeys ?? []);
|
|
1132
|
+
const duplicateKeys = removeKeys.filter((key) => Object.hasOwn(requestedUpdates, key));
|
|
1133
|
+
if (duplicateKeys.length)
|
|
1134
|
+
throw new Error(`Config write cannot update and remove the same key: ${duplicateKeys.join(', ')}.`);
|
|
1135
|
+
const schemaAccess = await resolvePluginConfigSchemaAccess({ pluginName, currentPlugin: options.plugin,
|
|
1136
|
+
currentPluginError: options.pluginError, scope: options.scope, platform: options.platform, cwd: options.cwd, env: options.env });
|
|
1137
|
+
const plugin = schemaAccess.plugin;
|
|
1138
|
+
const definition = plugin?.manifest.config ? compilePluginConfigDefinition(plugin.manifest.config, options.platform) : undefined;
|
|
1139
|
+
if (!plugin || !definition)
|
|
1140
|
+
throw new PluginConfigSchemaResolutionError('configSchemaUnavailable', `Plugin "${pluginName}" does not declare an AW config schema.`);
|
|
1141
|
+
const updates = await coercePluginConfigUpdates({ schema: definition.fields, updates: requestedUpdates, cwd: options.cwd });
|
|
1142
|
+
const impact = await analyzePluginConfigMutationImpact({ plugin, scope: options.scope, platform: options.platform,
|
|
1143
|
+
cwd: options.cwd, env: options.env, visibleTargets: [], commandDiscovery: { packages: [], errors: [] },
|
|
1144
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins, mutation: { kind: 'patch', updates, removeKeys } });
|
|
1145
|
+
await assertPluginConfigMutationCandidate({ ...identity, pluginName, manifest: plugin.manifest,
|
|
1146
|
+
scope: options.scope, platform: options.platform, cwd: options.cwd, env: options.env, updates, removeKeys,
|
|
1147
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins });
|
|
1148
|
+
if (impact.referenceBlockers?.length)
|
|
1149
|
+
throw Object.assign(new Error(`configReferenceInUse: ${impact.referenceBlockers.join(' ')}`), { code: 'configReferenceInUse' });
|
|
978
1150
|
if (impact.storeChanged) {
|
|
979
1151
|
try {
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
pluginName,
|
|
983
|
-
scope: options.scope,
|
|
984
|
-
cwd: options.cwd,
|
|
985
|
-
env: options.env,
|
|
986
|
-
updates: Object.fromEntries(updatedKeys.map((key) => [key, updates[key]])),
|
|
987
|
-
removeKeys: requestedRemoveKeys,
|
|
988
|
-
schema,
|
|
989
|
-
});
|
|
990
|
-
warnings.push(...write.warnings);
|
|
1152
|
+
await patchPluginConfigStore({ ...identity, pluginName, scope: 'user', platform: options.platform,
|
|
1153
|
+
cwd: options.cwd, env: options.env, updates: Object.fromEntries(impact.updatedKeys.map((key) => [key, updates[key]])), removeKeys });
|
|
991
1154
|
}
|
|
992
1155
|
catch (error) {
|
|
993
1156
|
throw markConfigWriteFailed(error);
|
|
994
1157
|
}
|
|
995
1158
|
}
|
|
1159
|
+
const warnings = [...impact.referenceWarnings ?? []];
|
|
996
1160
|
let effective;
|
|
997
1161
|
try {
|
|
998
|
-
effective = summarizeEffectivePluginConfig(await resolveEffectivePluginConfig({
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
manifest: schemaPlugin.manifest,
|
|
1002
|
-
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1003
|
-
targetScope: options.scope,
|
|
1004
|
-
cwd: options.cwd,
|
|
1005
|
-
env: options.env,
|
|
1006
|
-
}));
|
|
1162
|
+
effective = summarizeEffectivePluginConfig(await resolveEffectivePluginConfig({ ...identity, pluginName,
|
|
1163
|
+
manifest: plugin.manifest, platform: options.platform, targetScope: options.scope, cwd: options.cwd, env: options.env,
|
|
1164
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins }));
|
|
1007
1165
|
}
|
|
1008
1166
|
catch {
|
|
1009
|
-
|
|
1010
|
-
const otherProjectsMayRequireSync = options.scope === 'user' && impact.storeChanged;
|
|
1011
|
-
if (otherProjectsMayRequireSync)
|
|
1012
|
-
warnings.push(...otherProjectsWarning(options.scope));
|
|
1013
|
-
return {
|
|
1014
|
-
plugin: pluginName,
|
|
1015
|
-
scope: options.scope,
|
|
1016
|
-
...(schemaAccess.schema ? { schema: schemaAccess.schema } : {}),
|
|
1017
|
-
updatedKeys,
|
|
1018
|
-
removedKeys,
|
|
1019
|
-
staleRemovedKeys,
|
|
1020
|
-
configWrite: 'succeeded',
|
|
1021
|
-
overallState: 'partial',
|
|
1022
|
-
apply: publicConfigApplyResult(apply),
|
|
1023
|
-
otherProjectsMayRequireSync,
|
|
1024
|
-
warnings,
|
|
1025
|
-
};
|
|
1167
|
+
warnings.push('The saved configuration cannot be previewed. Check its schema and reference sources before applying it.');
|
|
1026
1168
|
}
|
|
1027
|
-
|
|
1169
|
+
if (impact.storeChanged)
|
|
1170
|
+
warnings.push(...otherProjectsWarning('user'));
|
|
1171
|
+
return { plugin: pluginName, scope: 'user', context: options.scope, platform: options.platform,
|
|
1172
|
+
...(schemaAccess.schema ? { schema: schemaAccess.schema } : {}), updatedKeys: impact.updatedKeys,
|
|
1173
|
+
removedKeys: impact.removedKeys, staleRemovedKeys: impact.staleRemovedKeys, effective,
|
|
1174
|
+
configWrite: 'succeeded', overallState: 'succeeded',
|
|
1175
|
+
apply: skippedApply(impact.storeChanged ? 'notRequested' : 'noConfigChange'),
|
|
1176
|
+
otherProjectsMayRequireSync: impact.storeChanged, warnings };
|
|
1177
|
+
}
|
|
1178
|
+
async function prepareConfigMutationApplySelection(options) {
|
|
1179
|
+
if (options.apply !== true || !options.plugin)
|
|
1180
|
+
return undefined;
|
|
1181
|
+
let prepared;
|
|
1028
1182
|
try {
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
noVisibleTargetHasInvalidConfig: (discovered?.targets.length ?? 0) > 0
|
|
1051
|
-
&& effective.issues.length > 0,
|
|
1052
|
-
preApplyConfirmed: options.preApplyConfirmed,
|
|
1053
|
-
discovered: applyDiscovery,
|
|
1054
|
-
changedConfigKeys: impact.changedKeys,
|
|
1055
|
-
});
|
|
1183
|
+
prepared = await preparePluginConfigApply({ ...options, plugin: options.plugin });
|
|
1184
|
+
const requestedTargets = configApplyRequestedTargets(prepared.plan);
|
|
1185
|
+
if (requestedTargets.some((target) => target.agent !== 'codex' && target.agent !== 'claude'))
|
|
1186
|
+
return undefined;
|
|
1187
|
+
const visibleTargets = requestedTargets.map((target) => ({
|
|
1188
|
+
pluginName: target.pluginId.split('/').at(-1), pluginId: target.pluginId,
|
|
1189
|
+
platform: target.agent, scope: target.scope,
|
|
1190
|
+
}));
|
|
1191
|
+
if (!visibleTargets.length && !prepared.commandPackages.length && !prepared.commandDiscoveryErrors.length) {
|
|
1192
|
+
if (prepared.plan.blockExecution || prepared.plan.receipt.blockers.length || prepared.plan.receipt.errors.length)
|
|
1193
|
+
return undefined;
|
|
1194
|
+
return { skipReason: 'noVisibleTarget' };
|
|
1195
|
+
}
|
|
1196
|
+
const impact = await analyzePluginConfigMutationImpact({ plugin: options.plugin, scope: options.context ?? options.scope,
|
|
1197
|
+
platform: options.platform, cwd: options.cwd, env: options.env, visibleTargets,
|
|
1198
|
+
commandDiscovery: { packages: prepared.commandPackages, errors: prepared.commandDiscoveryErrors },
|
|
1199
|
+
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1200
|
+
mutation: 'request' in options ? { kind: 'patch', ...options.request } : { kind: 'reset' } });
|
|
1201
|
+
return { applyTargets: impact.affectedTargets,
|
|
1202
|
+
applyCommandPackages: impact.affectedCommandPackages.map((target) => target.packageId),
|
|
1203
|
+
...(impact.noEffectiveChange ? { skipReason: 'noEffectiveConfigChange' } : {}) };
|
|
1056
1204
|
}
|
|
1057
|
-
catch
|
|
1058
|
-
|
|
1059
|
-
|
|
1205
|
+
catch {
|
|
1206
|
+
// A failed output discovery must not prevent a valid configuration save.
|
|
1207
|
+
return undefined;
|
|
1208
|
+
}
|
|
1209
|
+
finally {
|
|
1210
|
+
if (prepared)
|
|
1211
|
+
await disposePluginConfigApply(prepared.plan);
|
|
1060
1212
|
}
|
|
1061
|
-
const otherProjectsMayRequireSync = options.scope === 'user' && impact.storeChanged;
|
|
1062
|
-
if (otherProjectsMayRequireSync)
|
|
1063
|
-
warnings.push(...otherProjectsWarning(options.scope));
|
|
1064
|
-
return {
|
|
1065
|
-
plugin: pluginName,
|
|
1066
|
-
scope: options.scope,
|
|
1067
|
-
...(schemaAccess.schema ? { schema: schemaAccess.schema } : {}),
|
|
1068
|
-
updatedKeys,
|
|
1069
|
-
removedKeys,
|
|
1070
|
-
staleRemovedKeys,
|
|
1071
|
-
effective,
|
|
1072
|
-
configWrite: 'succeeded',
|
|
1073
|
-
overallState: overallStateForApply(apply),
|
|
1074
|
-
apply: publicConfigApplyResult(apply),
|
|
1075
|
-
otherProjectsMayRequireSync,
|
|
1076
|
-
warnings,
|
|
1077
|
-
};
|
|
1078
1213
|
}
|
|
1079
1214
|
export async function applyPluginConfigWrite(options) {
|
|
1215
|
+
if (options.context)
|
|
1216
|
+
await resolveWorkContext({ cwd: options.cwd, context: options.context });
|
|
1080
1217
|
const requestedPluginName = options.pluginName ?? options.plugin?.manifest.name;
|
|
1081
1218
|
if (!requestedPluginName)
|
|
1082
1219
|
throw new Error('Plugin name is required for config write.');
|
|
1083
1220
|
assertSafePluginConfigSegment(requestedPluginName);
|
|
1084
|
-
if (options.scope === 'project') {
|
|
1085
|
-
const targetPath = resolvePluginConfigStorePath({
|
|
1086
|
-
sourceId: options.plugin?.sourceId,
|
|
1087
|
-
pluginName: requestedPluginName,
|
|
1088
|
-
scope: 'project',
|
|
1089
|
-
cwd: options.cwd,
|
|
1090
|
-
env: options.env,
|
|
1091
|
-
});
|
|
1092
|
-
await assertProjectSharedConfigPathVisible({
|
|
1093
|
-
cwd: options.cwd,
|
|
1094
|
-
targetPath,
|
|
1095
|
-
env: options.env,
|
|
1096
|
-
});
|
|
1097
|
-
}
|
|
1098
|
-
if (options.apply !== false && !options.awHomeMutationToken) {
|
|
1099
|
-
await prepareNativeCliExecution({ env: options.env, runner: options.nativeCliRunner });
|
|
1100
|
-
}
|
|
1101
1221
|
return withAwHomeMutationLock({
|
|
1102
1222
|
env: options.env,
|
|
1103
1223
|
token: options.awHomeMutationToken,
|
|
1104
1224
|
action: async (awHomeMutationToken) => {
|
|
1105
1225
|
await options.reviewPreflight?.();
|
|
1226
|
+
let configCommitted = false;
|
|
1106
1227
|
try {
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
awHomeMutationToken,
|
|
1110
|
-
|
|
1111
|
-
|
|
1228
|
+
const selection = await prepareConfigMutationApplySelection({ ...options, awHomeMutationToken });
|
|
1229
|
+
const saved = await applyPluginConfigWriteUnlocked({ ...options, scope: options.context ?? options.scope,
|
|
1230
|
+
apply: false, awHomeMutationToken, rebuildRuntime: { ...options.rebuildRuntime, awHomeMutationToken } });
|
|
1231
|
+
configCommitted = true;
|
|
1232
|
+
if (options.apply !== true || !options.plugin)
|
|
1233
|
+
return saved;
|
|
1234
|
+
if (saved.apply.state === 'skipped' && saved.apply.reason === 'noConfigChange')
|
|
1235
|
+
return saved;
|
|
1236
|
+
if (selection?.skipReason)
|
|
1237
|
+
return { ...saved, apply: skippedApply(selection.skipReason) };
|
|
1238
|
+
const applied = await applyPluginConfig({ ...options, ...selection, plugin: options.plugin, awHomeMutationToken });
|
|
1239
|
+
return { ...saved, overallState: applied.overallState, apply: applied.apply };
|
|
1112
1240
|
}
|
|
1113
1241
|
catch (error) {
|
|
1114
1242
|
let sensitiveValues = options.plugin
|
|
1115
|
-
? collectSensitivePluginConfigValues(options.plugin.manifest, (options.request.updates ?? {}))
|
|
1243
|
+
? collectSensitivePluginConfigValues(options.plugin.manifest, (options.request.updates ?? {}), options.platform)
|
|
1116
1244
|
: [];
|
|
1117
1245
|
if (options.plugin) {
|
|
1118
1246
|
try {
|
|
@@ -1126,12 +1254,13 @@ export async function applyPluginConfigWrite(options) {
|
|
|
1126
1254
|
manifest: options.plugin.manifest,
|
|
1127
1255
|
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1128
1256
|
targetScope: options.scope,
|
|
1257
|
+
platform: options.platform,
|
|
1129
1258
|
cwd: options.cwd,
|
|
1130
1259
|
env: options.env,
|
|
1131
1260
|
});
|
|
1132
1261
|
sensitiveValues = [
|
|
1133
1262
|
...sensitiveValues,
|
|
1134
|
-
...collectSensitivePluginConfigValues(options.plugin.manifest, effective.values),
|
|
1263
|
+
...collectSensitivePluginConfigValues(options.plugin.manifest, effective.values, options.platform),
|
|
1135
1264
|
];
|
|
1136
1265
|
}
|
|
1137
1266
|
catch {
|
|
@@ -1160,8 +1289,8 @@ export async function applyPluginConfigWrite(options) {
|
|
|
1160
1289
|
: message.startsWith('schemaVersionUnsupported:') ? 'schemaVersionUnsupported'
|
|
1161
1290
|
: 'configApplyFailed';
|
|
1162
1291
|
const configWrite = error.configWrite;
|
|
1163
|
-
if (configWrite === 'succeeded' || configWriteStateForError(error) === 'failed') {
|
|
1164
|
-
safeError.configWrite = configWrite === 'succeeded' ? 'succeeded' : 'failed';
|
|
1292
|
+
if (configCommitted || configWrite === 'succeeded' || configWriteStateForError(error) === 'failed') {
|
|
1293
|
+
safeError.configWrite = configCommitted || configWrite === 'succeeded' ? 'succeeded' : 'failed';
|
|
1165
1294
|
}
|
|
1166
1295
|
if (error && typeof error === 'object' && 'operationDiagnostic' in error) {
|
|
1167
1296
|
safeError.operationDiagnostic = error.operationDiagnostic;
|
|
@@ -1173,277 +1302,90 @@ export async function applyPluginConfigWrite(options) {
|
|
|
1173
1302
|
}
|
|
1174
1303
|
async function resetPluginConfigWithHelperUnlocked(options) {
|
|
1175
1304
|
const pluginName = assertSafePluginConfigSegment(options.pluginName);
|
|
1176
|
-
let
|
|
1177
|
-
|
|
1178
|
-
sourceIdentity: options.
|
|
1179
|
-
|
|
1180
|
-
} : options.sourceId ? {
|
|
1181
|
-
sourceId: options.sourceId,
|
|
1182
|
-
sourceIdentity: options.sourceIdentity,
|
|
1183
|
-
logicalIdentity: options.logicalIdentity,
|
|
1184
|
-
} : {};
|
|
1185
|
-
if (options.sourceId && !options.sourceIdentity) {
|
|
1305
|
+
let identity = options.plugin?.sourceId ? { sourceId: options.plugin.sourceId,
|
|
1306
|
+
sourceIdentity: options.plugin.sourceIdentity, logicalIdentity: options.plugin.catalogLogicalIdentity }
|
|
1307
|
+
: { sourceId: options.sourceId, sourceIdentity: options.sourceIdentity, logicalIdentity: options.logicalIdentity };
|
|
1308
|
+
if (identity.sourceId && !identity.sourceIdentity) {
|
|
1186
1309
|
try {
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
cwd: options.cwd,
|
|
1192
|
-
env: options.env,
|
|
1193
|
-
});
|
|
1194
|
-
if (identity?.binding.kind === 'source')
|
|
1195
|
-
configIdentity = {
|
|
1196
|
-
sourceId: options.sourceId,
|
|
1197
|
-
sourceIdentity: identity.binding.sourceIdentity,
|
|
1198
|
-
};
|
|
1199
|
-
if (identity?.binding.kind === 'catalog')
|
|
1200
|
-
configIdentity = {
|
|
1201
|
-
sourceId: options.sourceId,
|
|
1202
|
-
logicalIdentity: identity.binding.logicalIdentity,
|
|
1203
|
-
};
|
|
1204
|
-
}
|
|
1205
|
-
catch {
|
|
1206
|
-
// Reset does not require a readable or valid envelope.
|
|
1310
|
+
const stored = await readNamespacedPluginConfigStoreIdentity({ sourceId: identity.sourceId, pluginName,
|
|
1311
|
+
scope: 'user', platform: options.platform, cwd: options.cwd, env: options.env });
|
|
1312
|
+
if (stored)
|
|
1313
|
+
identity = { ...identity, sourceIdentity: stored.binding.sourceIdentity };
|
|
1207
1314
|
}
|
|
1315
|
+
catch { /* Reset remains available for unreadable identity metadata. */ }
|
|
1208
1316
|
}
|
|
1209
1317
|
let removedKeys = [];
|
|
1210
1318
|
try {
|
|
1211
|
-
const store = await readPluginConfigStore({
|
|
1212
|
-
|
|
1213
|
-
pluginName,
|
|
1214
|
-
scope: options.scope,
|
|
1215
|
-
cwd: options.cwd,
|
|
1216
|
-
env: options.env,
|
|
1217
|
-
});
|
|
1319
|
+
const store = await readPluginConfigStore({ ...identity, pluginName, scope: 'user', platform: options.platform,
|
|
1320
|
+
cwd: options.cwd, env: options.env });
|
|
1218
1321
|
removedKeys = collectRemovedConfigKeys(store.values);
|
|
1219
1322
|
}
|
|
1220
|
-
catch {
|
|
1221
|
-
// Reset is the final recovery boundary and does not require a readable store.
|
|
1222
|
-
}
|
|
1323
|
+
catch { /* Broken stores still have the path-based reset boundary. */ }
|
|
1223
1324
|
const warnings = [];
|
|
1224
|
-
let impact;
|
|
1225
|
-
let targetDiscoveryFailed = false;
|
|
1226
|
-
let visibleTargets = [];
|
|
1227
|
-
let discovered;
|
|
1228
1325
|
if (options.plugin) {
|
|
1229
|
-
if (options.apply !== false) {
|
|
1230
|
-
try {
|
|
1231
|
-
discovered = await resolveConfigApplyTargets({
|
|
1232
|
-
plugin: options.plugin,
|
|
1233
|
-
scope: options.scope,
|
|
1234
|
-
cwd: options.cwd,
|
|
1235
|
-
env: options.env ?? process.env,
|
|
1236
|
-
applyTargets: options.applyTargets,
|
|
1237
|
-
nativeCliRunner: options.nativeCliRunner,
|
|
1238
|
-
rebuildRuntime: options.rebuildRuntime,
|
|
1239
|
-
});
|
|
1240
|
-
visibleTargets = discovered.targets;
|
|
1241
|
-
}
|
|
1242
|
-
catch {
|
|
1243
|
-
targetDiscoveryFailed = true;
|
|
1244
|
-
}
|
|
1245
|
-
}
|
|
1246
1326
|
try {
|
|
1247
|
-
impact = await analyzePluginConfigMutationImpact({
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
visibleTargets,
|
|
1253
|
-
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1254
|
-
...(discovered ? { commandDiscovery: {
|
|
1255
|
-
packages: discovered.commandPackages ?? [], errors: discovered.commandDiscoveryErrors ?? [],
|
|
1256
|
-
} } : {}),
|
|
1257
|
-
mutation: { kind: 'reset' },
|
|
1258
|
-
});
|
|
1259
|
-
removedKeys = impact.removedKeys;
|
|
1260
|
-
warnings.push(...impact.referenceBlockers ?? []);
|
|
1261
|
-
warnings.push(...impact.referenceWarnings ?? []);
|
|
1327
|
+
const impact = await analyzePluginConfigMutationImpact({ plugin: options.plugin, scope: options.scope,
|
|
1328
|
+
platform: options.platform, cwd: options.cwd, env: options.env, visibleTargets: [],
|
|
1329
|
+
commandDiscovery: { packages: [], errors: [] }, referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1330
|
+
mutation: { kind: 'reset' } });
|
|
1331
|
+
warnings.push(...impact.referenceWarnings ?? [], ...impact.referenceBlockers ?? []);
|
|
1262
1332
|
}
|
|
1263
1333
|
catch {
|
|
1264
|
-
|
|
1334
|
+
warnings.push('Configuration references could not be checked. Reset will still clear the selected layer.');
|
|
1265
1335
|
}
|
|
1266
1336
|
}
|
|
1267
|
-
let preApplyUnavailableReason;
|
|
1268
|
-
let preApplyUnavailableTargetResults = [];
|
|
1269
|
-
let applyDiscovery = options.plugin && !targetDiscoveryFailed
|
|
1270
|
-
? { targets: impact?.affectedTargets ?? visibleTargets, failures: [],
|
|
1271
|
-
commandPackages: impact?.affectedCommandPackages ?? discovered?.commandPackages,
|
|
1272
|
-
commandDiscoveryErrors: impact?.commandDiscoveryErrors ?? discovered?.commandDiscoveryErrors }
|
|
1273
|
-
: undefined;
|
|
1274
|
-
if (options.plugin
|
|
1275
|
-
&& options.apply !== false
|
|
1276
|
-
&& impact?.storeChanged
|
|
1277
|
-
&& !impact.noEffectiveChange
|
|
1278
|
-
&& applyDiscovery
|
|
1279
|
-
&& (pluginMayRunPreApply(options.plugin)
|
|
1280
|
-
|| applyDiscovery.targets.some((target) => target.pluginName !== options.plugin.manifest.name))) {
|
|
1281
|
-
const preApplyAuthorization = await resolveConfigPreApplyAuthorization({
|
|
1282
|
-
plugin: options.plugin,
|
|
1283
|
-
scope: options.scope,
|
|
1284
|
-
cwd: options.cwd,
|
|
1285
|
-
env: options.env,
|
|
1286
|
-
applyTargets: applyDiscovery.targets,
|
|
1287
|
-
nativeCliRunner: options.nativeCliRunner,
|
|
1288
|
-
rebuildRuntime: options.rebuildRuntime,
|
|
1289
|
-
reinstallCommandImpl: options.reinstallCommandImpl,
|
|
1290
|
-
});
|
|
1291
|
-
if (preApplyAuthorization.targets.length > 0 && !preApplyAuthorizationIsConfirmed({
|
|
1292
|
-
required: preApplyAuthorization.targets,
|
|
1293
|
-
confirmed: options.preApplyConfirmed,
|
|
1294
|
-
authorizedTargets: options.preApplyAuthorizedTargets,
|
|
1295
|
-
})) {
|
|
1296
|
-
throwPreApplyAuthorizationRequired(preApplyAuthorization.targets);
|
|
1297
|
-
}
|
|
1298
|
-
preApplyUnavailableTargetResults = preApplyAuthorization.unavailableTargetResults;
|
|
1299
|
-
applyDiscovery = {
|
|
1300
|
-
...applyDiscovery,
|
|
1301
|
-
targets: preApplyAuthorization.availableApplyTargets,
|
|
1302
|
-
failures: preApplyUnavailableTargetResults,
|
|
1303
|
-
};
|
|
1304
|
-
if (applyDiscovery.targets.length === 0 && preApplyUnavailableTargetResults.length > 0
|
|
1305
|
-
&& (applyDiscovery.commandPackages?.length ?? 0) === 0) {
|
|
1306
|
-
preApplyUnavailableReason = 'sourceUnavailable';
|
|
1307
|
-
}
|
|
1308
|
-
}
|
|
1309
|
-
if (options.plugin
|
|
1310
|
-
&& options.apply !== false
|
|
1311
|
-
&& options.scope === 'user'
|
|
1312
|
-
&& options.sharedNativeApplyConfirmed !== true
|
|
1313
|
-
&& (impact
|
|
1314
|
-
? impact.sharedNativeRenderTargets.some((shared) => impact.affectedTargets
|
|
1315
|
-
.some((target) => (!shared.pluginName || shared.pluginName === target.pluginName)
|
|
1316
|
-
&& target.platform === (shared.platform ?? 'codex')))
|
|
1317
|
-
: pluginSharedNativeConfigTargets(options.plugin).some((shared) => visibleTargets
|
|
1318
|
-
.some((target) => (!shared.pluginName || shared.pluginName === target.pluginName)
|
|
1319
|
-
&& target.platform === (shared.platform ?? 'codex'))))) {
|
|
1320
|
-
throwSharedNativeApplyConfirmationRequired();
|
|
1321
|
-
}
|
|
1322
1337
|
let reset;
|
|
1323
1338
|
try {
|
|
1324
|
-
reset = await resetPluginConfigStore({
|
|
1325
|
-
|
|
1326
|
-
pluginName,
|
|
1327
|
-
scope: options.scope,
|
|
1328
|
-
cwd: options.cwd,
|
|
1329
|
-
env: options.env,
|
|
1330
|
-
});
|
|
1339
|
+
reset = await resetPluginConfigStore({ ...identity, pluginName, scope: 'user', platform: options.platform,
|
|
1340
|
+
cwd: options.cwd, env: options.env });
|
|
1331
1341
|
}
|
|
1332
1342
|
catch (error) {
|
|
1333
1343
|
throw markConfigWriteFailed(error);
|
|
1334
1344
|
}
|
|
1335
|
-
let schemaAccess;
|
|
1336
|
-
let apply = reset.deleted ? skippedApply('notRequested') : skippedApply('noConfigChange');
|
|
1337
1345
|
let effective;
|
|
1346
|
+
let schema;
|
|
1338
1347
|
if (options.plugin) {
|
|
1339
1348
|
try {
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
env: options.env,
|
|
1346
|
-
});
|
|
1349
|
+
schema = (await resolvePluginConfigSchemaAccess({ pluginName, currentPlugin: options.plugin,
|
|
1350
|
+
scope: options.scope, platform: options.platform, cwd: options.cwd, env: options.env })).schema;
|
|
1351
|
+
effective = summarizeEffectivePluginConfig(await resolveEffectivePluginConfig({ ...identity, pluginName,
|
|
1352
|
+
manifest: options.plugin.manifest, platform: options.platform, targetScope: options.scope, cwd: options.cwd,
|
|
1353
|
+
env: options.env, referencePlugins: options.rebuildRuntime?.referencePlugins }));
|
|
1347
1354
|
}
|
|
1348
1355
|
catch {
|
|
1349
|
-
|
|
1350
|
-
apply = unavailableApply('sourceUnavailable', 'source');
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
1353
|
-
const schemaPlugin = schemaAccess?.plugin;
|
|
1354
|
-
if (schemaPlugin?.manifest.config?.fields) {
|
|
1355
|
-
try {
|
|
1356
|
-
effective = summarizeEffectivePluginConfig(await resolveEffectivePluginConfig({
|
|
1357
|
-
...configIdentity,
|
|
1358
|
-
pluginName,
|
|
1359
|
-
manifest: schemaPlugin.manifest,
|
|
1360
|
-
referencePlugins: options.rebuildRuntime?.referencePlugins,
|
|
1361
|
-
targetScope: options.scope,
|
|
1362
|
-
cwd: options.cwd,
|
|
1363
|
-
env: options.env,
|
|
1364
|
-
}));
|
|
1365
|
-
}
|
|
1366
|
-
catch {
|
|
1367
|
-
if (reset.deleted && options.apply !== false) {
|
|
1368
|
-
apply = unavailableApply('effectiveConfigUnavailable', 'effectiveConfig', [], impact?.affectedCommandPackages);
|
|
1369
|
-
}
|
|
1370
|
-
}
|
|
1371
|
-
if (reset.deleted
|
|
1372
|
-
&& options.apply !== false
|
|
1373
|
-
&& apply.state === 'skipped'
|
|
1374
|
-
&& impact?.noEffectiveChange
|
|
1375
|
-
&& visibleTargets.length + (impact?.commandPackages.length ?? 0) > 0) {
|
|
1376
|
-
apply = skippedApply('noEffectiveConfigChange');
|
|
1377
|
-
}
|
|
1378
|
-
else if (reset.deleted
|
|
1379
|
-
&& options.apply !== false
|
|
1380
|
-
&& apply.state === 'skipped'
|
|
1381
|
-
&& targetDiscoveryFailed) {
|
|
1382
|
-
apply = unavailableApply('targetDiscoveryFailed', 'targetDiscovery');
|
|
1383
|
-
}
|
|
1384
|
-
else if (reset.deleted && options.apply !== false && apply.state === 'skipped') {
|
|
1385
|
-
apply = preApplyUnavailableReason
|
|
1386
|
-
? unavailableApply(preApplyUnavailableReason, 'source', preApplyUnavailableTargetResults)
|
|
1387
|
-
: await applyConfigToVisibleTargets({
|
|
1388
|
-
plugin: schemaPlugin,
|
|
1389
|
-
scope: options.scope,
|
|
1390
|
-
cwd: options.cwd,
|
|
1391
|
-
env: options.env ?? process.env,
|
|
1392
|
-
applyTargets: applyDiscovery?.targets ?? impact?.affectedTargets ?? options.applyTargets,
|
|
1393
|
-
nativeCliRunner: options.nativeCliRunner,
|
|
1394
|
-
reinstallCommandImpl: options.reinstallCommandImpl,
|
|
1395
|
-
rebuildRuntime: options.rebuildRuntime,
|
|
1396
|
-
noVisibleTargetHasInvalidConfig: (effective?.issues.length ?? 0) > 0,
|
|
1397
|
-
preApplyConfirmed: options.preApplyConfirmed,
|
|
1398
|
-
discovered: applyDiscovery,
|
|
1399
|
-
changedConfigKeys: impact?.changedKeys ?? removedKeys,
|
|
1400
|
-
});
|
|
1401
|
-
}
|
|
1356
|
+
warnings.push('The cleared configuration cannot be previewed. Check its schema and references before applying it.');
|
|
1402
1357
|
}
|
|
1403
|
-
else if (reset.deleted && options.apply !== false && apply.state === 'skipped') {
|
|
1404
|
-
apply = unavailableApply('schemaUnavailable', 'schema');
|
|
1405
|
-
}
|
|
1406
|
-
}
|
|
1407
|
-
else if (reset.deleted && options.apply !== false) {
|
|
1408
|
-
apply = options.pluginError
|
|
1409
|
-
? unavailableApply('sourceUnavailable', 'source')
|
|
1410
|
-
: unavailableApply('schemaUnavailable', 'schema');
|
|
1411
1358
|
}
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
existed: reset.existed,
|
|
1420
|
-
deleted: reset.deleted,
|
|
1421
|
-
resetDisposition: reset.resetDisposition,
|
|
1422
|
-
...(reset.quarantineBasename ? { quarantineBasename: reset.quarantineBasename } : {}),
|
|
1423
|
-
removedKeys,
|
|
1424
|
-
...(effective ? { effective } : {}),
|
|
1425
|
-
configWrite: 'succeeded',
|
|
1426
|
-
overallState: overallStateForApply(apply),
|
|
1427
|
-
apply: publicConfigApplyResult(apply),
|
|
1428
|
-
otherProjectsMayRequireSync,
|
|
1429
|
-
warnings,
|
|
1430
|
-
};
|
|
1359
|
+
if (reset.existed)
|
|
1360
|
+
warnings.push(...otherProjectsWarning('user'));
|
|
1361
|
+
return { plugin: pluginName, scope: 'user', context: options.scope, platform: options.platform, schema,
|
|
1362
|
+
existed: reset.existed, deleted: reset.deleted, resetDisposition: reset.resetDisposition,
|
|
1363
|
+
...(reset.quarantineBasename ? { quarantineBasename: reset.quarantineBasename } : {}), removedKeys, effective,
|
|
1364
|
+
configWrite: 'succeeded', overallState: 'succeeded', apply: skippedApply(reset.existed ? 'notRequested' : 'noConfigChange'),
|
|
1365
|
+
otherProjectsMayRequireSync: reset.existed, warnings };
|
|
1431
1366
|
}
|
|
1432
1367
|
export async function resetPluginConfigWithHelper(options) {
|
|
1368
|
+
if (options.context)
|
|
1369
|
+
await resolveWorkContext({ cwd: options.cwd, context: options.context });
|
|
1433
1370
|
assertSafePluginConfigSegment(options.pluginName);
|
|
1434
|
-
if (options.apply !== false && !options.awHomeMutationToken) {
|
|
1435
|
-
await prepareNativeCliExecution({ env: options.env, runner: options.nativeCliRunner });
|
|
1436
|
-
}
|
|
1437
1371
|
return withAwHomeMutationLock({
|
|
1438
1372
|
env: options.env,
|
|
1439
1373
|
token: options.awHomeMutationToken,
|
|
1440
1374
|
action: async (awHomeMutationToken) => {
|
|
1441
1375
|
await options.reviewPreflight?.();
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
awHomeMutationToken,
|
|
1445
|
-
|
|
1446
|
-
|
|
1376
|
+
const selection = await prepareConfigMutationApplySelection({ ...options, awHomeMutationToken });
|
|
1377
|
+
const saved = await resetPluginConfigWithHelperUnlocked({ ...options, scope: options.context ?? options.scope,
|
|
1378
|
+
apply: false, awHomeMutationToken, rebuildRuntime: { ...options.rebuildRuntime, awHomeMutationToken } });
|
|
1379
|
+
if (options.apply !== true)
|
|
1380
|
+
return saved;
|
|
1381
|
+
if (!options.plugin)
|
|
1382
|
+
return { ...saved, overallState: 'partial', apply: unavailableApply('sourceUnavailable', 'source') };
|
|
1383
|
+
if (saved.apply.state === 'skipped' && saved.apply.reason === 'noConfigChange')
|
|
1384
|
+
return saved;
|
|
1385
|
+
if (selection?.skipReason)
|
|
1386
|
+
return { ...saved, apply: skippedApply(selection.skipReason) };
|
|
1387
|
+
const applied = await applyPluginConfig({ ...options, ...selection, plugin: options.plugin, awHomeMutationToken });
|
|
1388
|
+
return { ...saved, overallState: applied.overallState, apply: applied.apply };
|
|
1447
1389
|
},
|
|
1448
1390
|
});
|
|
1449
1391
|
}
|
|
@@ -1454,6 +1396,8 @@ export async function describeResetAffectedFields(options) {
|
|
|
1454
1396
|
plugin: options.plugin,
|
|
1455
1397
|
...(options.pluginError ? { pluginError: options.pluginError } : {}),
|
|
1456
1398
|
scope: options.scope,
|
|
1399
|
+
context: options.context,
|
|
1400
|
+
platform: options.platform,
|
|
1457
1401
|
cwd: options.cwd,
|
|
1458
1402
|
env: options.env,
|
|
1459
1403
|
});
|
|
@@ -1463,7 +1407,8 @@ export async function describeResetAffectedFields(options) {
|
|
|
1463
1407
|
kind: field.kind,
|
|
1464
1408
|
reserved: field.reserved,
|
|
1465
1409
|
action: 'reset',
|
|
1466
|
-
scope:
|
|
1410
|
+
scope: 'user',
|
|
1411
|
+
platform: options.platform,
|
|
1467
1412
|
valueState: field.valueState,
|
|
1468
1413
|
}));
|
|
1469
1414
|
}
|
|
@@ -1479,7 +1424,8 @@ export async function describeResetAffectedFields(options) {
|
|
|
1479
1424
|
logicalIdentity: options.logicalIdentity,
|
|
1480
1425
|
} : {}),
|
|
1481
1426
|
pluginName: options.pluginName,
|
|
1482
|
-
scope:
|
|
1427
|
+
scope: 'user',
|
|
1428
|
+
platform: options.platform,
|
|
1483
1429
|
cwd: options.cwd,
|
|
1484
1430
|
env: options.env,
|
|
1485
1431
|
});
|
|
@@ -1489,7 +1435,8 @@ export async function describeResetAffectedFields(options) {
|
|
|
1489
1435
|
kind: 'manifest',
|
|
1490
1436
|
reserved: false,
|
|
1491
1437
|
action: 'reset',
|
|
1492
|
-
scope:
|
|
1438
|
+
scope: 'user',
|
|
1439
|
+
platform: options.platform,
|
|
1493
1440
|
}));
|
|
1494
1441
|
}
|
|
1495
1442
|
}
|