@lesliechan721/aw 0.1.0-beta.64 → 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 +405 -1626
- 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 +9 -2
- package/dist/src/utils/plugin-config-references.js +75 -85
- 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
package/dist/src/index.js
CHANGED
|
@@ -1,41 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { describeNativeToolClosure } from './utils/native-tool-review.js';
|
|
2
3
|
import fs from 'node:fs';
|
|
3
4
|
import path from 'node:path';
|
|
4
5
|
import { spawn } from 'node:child_process';
|
|
5
6
|
import { fileURLToPath } from 'node:url';
|
|
6
7
|
import { Command, CommanderError, InvalidArgumentError, Option } from 'commander';
|
|
7
8
|
import { doctorEvalProviders } from '@lesliechan721/agent-skill-eval';
|
|
9
|
+
import { compilePluginConfigDefinition, PLATFORM_TARGETS, PORTABLE_PLATFORM_TARGETS } from '@lesliechan721/aw-plugin-core/manifest';
|
|
8
10
|
import { initCommand } from './commands/init.js';
|
|
9
11
|
import { resolveCatalogWorkspaceRoot } from './commands/catalog-workspace-resolution.js';
|
|
10
12
|
import { addCatalogSourceCommand, preflightCatalogSourceMutation, explicitRefPolicy, listCatalogSources, removeCatalogSourceCommand, setPrimaryCatalogSourceCommand, updateCatalogSourceCommand, } from './commands/catalog-source.js';
|
|
11
13
|
import { catalogSourceStatusCommand, syncCatalogSourceCommand, } from './commands/catalog-generation.js';
|
|
12
14
|
import { catalogStoreErrorCode, catalogStorePrune, catalogStoreStatus, } from './commands/catalog-store.js';
|
|
13
|
-
import { cleanupWriteCommand as cleanupCommand, installWriteCommand as installCommand, reinstallWriteCommand as reinstallCommand, uninstallWriteCommand as uninstallCommand, } from './commands/write-commands.js';
|
|
14
|
-
import { syncCommand } from './commands/sync-command.js';
|
|
15
15
|
import { formatInteractiveConsoleUnavailableMessage, runConsoleController, } from './commands/console.js';
|
|
16
|
-
import {
|
|
16
|
+
import { WizardExecutionError, } from './commands/wizard.js';
|
|
17
17
|
import { createCliExecutionContext, emitCommandEvent, } from './commands/runtime.js';
|
|
18
|
-
import {
|
|
19
|
-
import { normalizeUninstallCommandOptions, normalizeCleanupCommandOptions, resolveConfigReadResolution, resolveConfigWriteScope, normalizeInstallCommandOptions, normalizeReinstallCommandOptions, resolveScriptTimeoutMs, } from './commands/options.js';
|
|
18
|
+
import { parseContextValue, parsePlatformTargetValue, parseScopeValue, resolveScriptTimeoutMs, } from './commands/options.js';
|
|
20
19
|
import { isCommandWarningError, } from './types.js';
|
|
21
20
|
import { formatWarnings } from './output/reporter.js';
|
|
22
21
|
import { redactString, redactValue } from './output/redact.js';
|
|
23
|
-
import {
|
|
24
|
-
import { buildRebuildReceiptJson, buildInitReceiptJson, renderRebuildReceipt, renderInitReceipt, } from './output/command-receipt.js';
|
|
22
|
+
import { buildInitReceiptJson, renderInitReceipt, } from './output/command-receipt.js';
|
|
25
23
|
import { resolveCliPackageRoot } from './utils/paths.js';
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { applyPluginConfigWrite, buildConfigMutationReceipt, configWriteStateForError, describeResetAffectedFields, resetPluginConfigWithHelper, } from './utils/plugin-config-write.js';
|
|
24
|
+
import { findConfigFieldEntry, formatPluginConfigSetRecoveryCommand, listNamespacedPluginConfigStores, readPluginConfigStore, renderPluginConfigValueForDisplay, resolveConfigRead, } from './utils/plugin-config.js';
|
|
25
|
+
import { applyPluginConfigWrite, applyPluginConfig, buildConfigMutationReceipt, configWriteStateForError, resetPluginConfigWithHelper, } from './utils/plugin-config-write.js';
|
|
29
26
|
import { assertStrictSemVer } from './utils/manifest.js';
|
|
30
|
-
import { writeCandidateEligibility } from './utils/target-eligibility.js';
|
|
31
27
|
import { assertCatalogSourceReferencesSupported, inventoryLegacyConfigReferences, } from './utils/catalog-source-references.js';
|
|
32
28
|
import { parsePluginId, withResolvedCatalogPlugin, withResolvedMultiSourceCatalog, } from './utils/multi-source-catalog.js';
|
|
33
29
|
import { sanitizeCatalogSourceError, sanitizeCatalogSourceErrorMessage, } from './utils/catalog-public-error.js';
|
|
34
30
|
import { catalogGenerationErrorCode } from './utils/catalog-generation-error.js';
|
|
35
31
|
import { resolveCatalogOperationContext, } from './utils/catalog-operation-context.js';
|
|
36
32
|
import { withAwHomeMutationLock, } from './utils/aw-home-mutation-lock.js';
|
|
37
|
-
import {
|
|
38
|
-
import { SkillsCliError } from './portable/skills-cli.js';
|
|
33
|
+
import { materializePortableSkillsToDirectory, PortableCommandError } from './portable/commands.js';
|
|
39
34
|
import { createReviewInspectionFailure, getReviewInspectionExitCode, inspectReviewTarget, } from './commands/review-inspection.js';
|
|
40
35
|
import { prepareReviewTarget, } from './commands/review-preparation.js';
|
|
41
36
|
import { runCatalogBuildCommand, runCatalogInitCommand, runCatalogValidateCommand, runCatalogVersionCommand, runPluginBuildCommand, runPluginTestCommand, } from './authoring/workspace-commands.js';
|
|
@@ -46,6 +41,13 @@ import { activateCatalogDevSource, catalogDevSourceError, createCatalogDevFailur
|
|
|
46
41
|
import { getPluginCapabilitiesResult, parsePluginCapabilitySurface, renderPluginCapabilities, } from './commands/plugin-capabilities.js';
|
|
47
42
|
import { AwCapabilityUnsupportedError, checkCurrentAw, describeCurrentAw, inspectPluginRequirements, } from './commands/aw-capabilities.js';
|
|
48
43
|
import { prepareSkillEval } from './commands/skill-eval.js';
|
|
44
|
+
import { readRecoveryStatus, checkRecovery } from './recovery/status.js';
|
|
45
|
+
import { intentAdd, intentRemove, intentList } from './commands/intent-command.js';
|
|
46
|
+
import { targetsSet, targetsList, targetsChangeExclusion } from './commands/targets-command.js';
|
|
47
|
+
import { runRecovery } from './recovery/coordinator.js';
|
|
48
|
+
import { runRetire } from './recovery/retirement.js';
|
|
49
|
+
import { normalizeAgents } from './intent/deployment-preferences.js';
|
|
50
|
+
import { resolveWorkContext } from './intent/work-context.js';
|
|
49
51
|
import { registerManagedCommandCli, runManagedCommandCli } from './commands/managed-commands.js';
|
|
50
52
|
function createDefaultIo() {
|
|
51
53
|
return {
|
|
@@ -69,7 +71,7 @@ function strictValueOption(flags, description, choices) {
|
|
|
69
71
|
return value;
|
|
70
72
|
});
|
|
71
73
|
}
|
|
72
|
-
function collectUniqueOption(value, previous) {
|
|
74
|
+
function collectUniqueOption(value, previous = []) {
|
|
73
75
|
return previous.includes(value) ? previous : [...previous, value];
|
|
74
76
|
}
|
|
75
77
|
function renderReviewSkills(write, skills, issues) {
|
|
@@ -110,9 +112,6 @@ function resolveCliVersion() {
|
|
|
110
112
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
111
113
|
return assertStrictSemVer(packageJson.version, 'packages/cli/package.json version');
|
|
112
114
|
}
|
|
113
|
-
function resolveCommandReceiptExitCode(result) {
|
|
114
|
-
return result.overallState === 'succeeded' ? 0 : 1;
|
|
115
|
-
}
|
|
116
115
|
class WriteCommandRequestError extends Error {
|
|
117
116
|
code = 'invalidArguments';
|
|
118
117
|
}
|
|
@@ -140,122 +139,47 @@ function writeCommandFailure(error) {
|
|
|
140
139
|
message,
|
|
141
140
|
};
|
|
142
141
|
}
|
|
143
|
-
function
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
request.plugins.push(token);
|
|
150
|
-
continue;
|
|
151
|
-
}
|
|
152
|
-
if (token === '--') {
|
|
153
|
-
positionalOnly = true;
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
if (token === '--json') {
|
|
157
|
-
request.json = true;
|
|
158
|
-
continue;
|
|
159
|
-
}
|
|
160
|
-
if (token === '--platform' || token === '--scope') {
|
|
161
|
-
const value = argv[index + 1];
|
|
162
|
-
if (token === '--platform')
|
|
163
|
-
request.platform = value;
|
|
164
|
-
else
|
|
165
|
-
request.scope = value;
|
|
166
|
-
index += 1;
|
|
167
|
-
continue;
|
|
168
|
-
}
|
|
169
|
-
if (token.startsWith('--platform=')) {
|
|
170
|
-
request.platform = token.slice('--platform='.length);
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
if (token.startsWith('--scope=')) {
|
|
174
|
-
request.scope = token.slice('--scope='.length);
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
if (token === '--dependency-scope' || token === '--script-timeout' || token === '--log-file') {
|
|
178
|
-
index += 1;
|
|
179
|
-
continue;
|
|
180
|
-
}
|
|
181
|
-
if (token.startsWith('--'))
|
|
182
|
-
continue;
|
|
183
|
-
if (token.startsWith('-') && token !== '-') {
|
|
184
|
-
const shortOptions = token.slice(1);
|
|
185
|
-
for (let offset = 0; offset < shortOptions.length; offset += 1) {
|
|
186
|
-
const option = shortOptions[offset];
|
|
187
|
-
if (option === 'j') {
|
|
188
|
-
request.json = true;
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
if (option === 'p' || option === 's') {
|
|
192
|
-
const value = shortOptions.slice(offset + 1) || argv[index + 1];
|
|
193
|
-
if (option === 'p')
|
|
194
|
-
request.platform = value;
|
|
195
|
-
else
|
|
196
|
-
request.scope = value;
|
|
197
|
-
if (shortOptions.length === offset + 1)
|
|
198
|
-
index += 1;
|
|
199
|
-
break;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
continue;
|
|
203
|
-
}
|
|
204
|
-
request.plugins.push(token);
|
|
205
|
-
}
|
|
206
|
-
return request;
|
|
207
|
-
}
|
|
208
|
-
function jsonWriteCommandRequest(argv) {
|
|
209
|
-
const command = argv[0];
|
|
210
|
-
if (!['install', 'reinstall', 'uninstall', 'cleanup', 'sync'].includes(command ?? '')) {
|
|
142
|
+
function recoveryRequest(argv) {
|
|
143
|
+
const nested = argv[0] === 'plugin';
|
|
144
|
+
const args = nested ? argv.slice(1) : argv;
|
|
145
|
+
const family = args[0] ?? '';
|
|
146
|
+
if (nested && ['remove', 'status'].includes(family)
|
|
147
|
+
&& args.some((value) => value === '--workspace-root' || value.startsWith('--workspace-root=')))
|
|
211
148
|
return null;
|
|
212
|
-
|
|
213
|
-
const request = preparseWriteReceiptRequest(argv);
|
|
214
|
-
if (!request.json)
|
|
149
|
+
if (!['intent', 'targets', 'sync', 'install', 'remove', 'reinstall', 'uninstall', 'cleanup', 'status', 'project'].includes(family))
|
|
215
150
|
return null;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
151
|
+
let rawScope;
|
|
152
|
+
let json = false;
|
|
153
|
+
for (let index = 1; index < args.length; index++) {
|
|
154
|
+
const value = args[index];
|
|
155
|
+
if (value === '--')
|
|
156
|
+
break;
|
|
157
|
+
if (value === '--scope')
|
|
158
|
+
rawScope = args[++index];
|
|
159
|
+
else if (value.startsWith('--scope='))
|
|
160
|
+
rawScope = value.slice('--scope='.length);
|
|
161
|
+
else if (value === '--json' || (/^-[ajvyD]+$/u.test(value) && value.includes('j')))
|
|
162
|
+
json = true;
|
|
163
|
+
else if (['--target', '--context', '--script-timeout', '--log-file'].includes(value))
|
|
164
|
+
index++;
|
|
165
|
+
}
|
|
220
166
|
return {
|
|
221
|
-
command:
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
scope: request.scope === 'project' ? 'project' : 'user',
|
|
167
|
+
command: ['intent', 'targets', 'project'].includes(family) ? `${family}:${args[1] ?? ''}` : family,
|
|
168
|
+
scope: rawScope === 'user' || rawScope === 'project' ? rawScope : null,
|
|
169
|
+
json,
|
|
225
170
|
};
|
|
226
171
|
}
|
|
227
|
-
function
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
:
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
errors: [writeCommandFailure(error)],
|
|
237
|
-
receiptTargets: request.plugins.flatMap((selector) => platforms.map((platform) => {
|
|
238
|
-
let pluginName = selector;
|
|
239
|
-
let sourceId;
|
|
240
|
-
try {
|
|
241
|
-
const parsed = parsePluginId(selector);
|
|
242
|
-
pluginName = parsed.pluginName;
|
|
243
|
-
sourceId = parsed.sourceId;
|
|
244
|
-
}
|
|
245
|
-
catch {
|
|
246
|
-
// Keep the raw selector in the failed receipt.
|
|
247
|
-
}
|
|
248
|
-
return {
|
|
249
|
-
pluginName,
|
|
250
|
-
pluginId: selector,
|
|
251
|
-
...(sourceId ? { sourceId } : {}),
|
|
252
|
-
platform,
|
|
253
|
-
scope: request.scope,
|
|
254
|
-
};
|
|
255
|
-
})),
|
|
256
|
-
}));
|
|
172
|
+
function recoveryFailureReceipt(command, scope, error) {
|
|
173
|
+
const failure = writeCommandFailure(error);
|
|
174
|
+
return {
|
|
175
|
+
schemaVersion: 1, kind: 'aw-recovery', scope, command, ok: false,
|
|
176
|
+
intent: { state: 'unreadable', roots: null }, requestedRoots: [], requestedTargets: [],
|
|
177
|
+
selection: { agents: [], origin: 'none', preferences: 'unreadable' },
|
|
178
|
+
blockers: [failure], errors: [failure], targetResults: [], remainingTargets: [], recoveryActions: [],
|
|
179
|
+
declarationChanged: false, preferencesChanged: false, configChanged: false, outputsMayHaveChanged: false,
|
|
180
|
+
};
|
|
257
181
|
}
|
|
258
|
-
function scanConfigMutationShortOptions(token
|
|
182
|
+
function scanConfigMutationShortOptions(token) {
|
|
259
183
|
if (!/^-[^-].*/u.test(token))
|
|
260
184
|
return { json: false, consumesNextValue: false };
|
|
261
185
|
let json = false;
|
|
@@ -271,7 +195,7 @@ function scanConfigMutationShortOptions(token, command) {
|
|
|
271
195
|
json = true;
|
|
272
196
|
continue;
|
|
273
197
|
}
|
|
274
|
-
if (option === 'v' || option === 'D' ||
|
|
198
|
+
if (option === 'v' || option === 'D' || option === 'y') {
|
|
275
199
|
continue;
|
|
276
200
|
}
|
|
277
201
|
break;
|
|
@@ -279,15 +203,16 @@ function scanConfigMutationShortOptions(token, command) {
|
|
|
279
203
|
return { json, consumesNextValue: false };
|
|
280
204
|
}
|
|
281
205
|
function jsonConfigMutationRequest(argv) {
|
|
282
|
-
|
|
206
|
+
const args = argv[0] === 'plugin' ? argv.slice(1) : argv;
|
|
207
|
+
if (args[0] !== 'config' || !['set', 'edit', 'unset', 'reset', 'apply'].includes(args[1] ?? '')) {
|
|
283
208
|
return null;
|
|
284
209
|
}
|
|
285
|
-
const command = `config:${
|
|
210
|
+
const command = `config:${args[1]}`;
|
|
286
211
|
let json = false;
|
|
287
212
|
let plugin;
|
|
288
|
-
const valueOptions = new Set(['--
|
|
289
|
-
for (let index = 2; index <
|
|
290
|
-
const token =
|
|
213
|
+
const valueOptions = new Set(['--platform', '--context', '--target', '--value-json', '--preset', '--log-file', '--script-timeout']);
|
|
214
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
215
|
+
const token = args[index];
|
|
291
216
|
if (token === '--')
|
|
292
217
|
break;
|
|
293
218
|
if (valueOptions.has(token)) {
|
|
@@ -298,7 +223,7 @@ function jsonConfigMutationRequest(argv) {
|
|
|
298
223
|
json = true;
|
|
299
224
|
continue;
|
|
300
225
|
}
|
|
301
|
-
const shortOptions = scanConfigMutationShortOptions(token
|
|
226
|
+
const shortOptions = scanConfigMutationShortOptions(token);
|
|
302
227
|
if (shortOptions.json)
|
|
303
228
|
json = true;
|
|
304
229
|
if (shortOptions.consumesNextValue)
|
|
@@ -314,6 +239,24 @@ function jsonConfigMutationRequest(argv) {
|
|
|
314
239
|
...(plugin ? { plugin } : {}),
|
|
315
240
|
};
|
|
316
241
|
}
|
|
242
|
+
function jsonConfigReadRequested(argv) {
|
|
243
|
+
if (argv[0] !== 'plugin' || argv[1] !== 'config'
|
|
244
|
+
|| !['schema', 'list', 'get'].includes(argv[2] ?? ''))
|
|
245
|
+
return false;
|
|
246
|
+
const values = new Set(['--platform', '--context', '--target', '--script-timeout', '--log-file']);
|
|
247
|
+
for (let index = 3; index < argv.length; index++) {
|
|
248
|
+
const token = argv[index];
|
|
249
|
+
if (token === '--')
|
|
250
|
+
break;
|
|
251
|
+
if (values.has(token)) {
|
|
252
|
+
index++;
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (token === '--json' || /^-[jvD]+$/u.test(token) && token.includes('j'))
|
|
256
|
+
return true;
|
|
257
|
+
}
|
|
258
|
+
return false;
|
|
259
|
+
}
|
|
317
260
|
function configMutationFailure(error, env, cwd) {
|
|
318
261
|
const configWrite = configWriteStateForError(error);
|
|
319
262
|
if (error instanceof CommanderError) {
|
|
@@ -404,35 +347,6 @@ function toCliDiagnosticsOptions(commandName, rawOptions, runtimeDiagnostics) {
|
|
|
404
347
|
function isWizardAvailable(context, rawOptions) {
|
|
405
348
|
return context.interactive && context.isTty && !context.isCi && rawOptions.json !== true;
|
|
406
349
|
}
|
|
407
|
-
function shellCommand(tokens) {
|
|
408
|
-
return renderShellCommand(tokens, 'posix');
|
|
409
|
-
}
|
|
410
|
-
function optionTokens(flag, value) {
|
|
411
|
-
return value === undefined ? [] : [flag, value];
|
|
412
|
-
}
|
|
413
|
-
function writeCommandUsage(command) {
|
|
414
|
-
const cardinality = command === 'reinstall' || command === 'cleanup' ? '<plugin>' : '<plugin...>';
|
|
415
|
-
const scope = command === 'cleanup' ? ' --scope <project|user>' : ' [--scope <project|user>]';
|
|
416
|
-
return [
|
|
417
|
-
`${command} 命令缺少必要参数。`,
|
|
418
|
-
`Usage: aw ${command} ${cardinality} --platform <codex|claude|both>${scope}`,
|
|
419
|
-
`Example: aw ${command} example-plugin --platform codex --scope user`,
|
|
420
|
-
].join('\n');
|
|
421
|
-
}
|
|
422
|
-
function configCommandUsage(command) {
|
|
423
|
-
const argumentsByCommand = {
|
|
424
|
-
list: '<plugin>',
|
|
425
|
-
get: '<plugin> [key]',
|
|
426
|
-
set: '<plugin> <field> --scope <project|user> (--value-json <json> | --value-stdin | --preset <id>)',
|
|
427
|
-
unset: '<plugin> <key>',
|
|
428
|
-
reset: '<plugin> --scope <project|user> --yes',
|
|
429
|
-
};
|
|
430
|
-
return [
|
|
431
|
-
`config ${command} 命令缺少必要参数。`,
|
|
432
|
-
`Usage: aw config ${command} ${argumentsByCommand[command]}`,
|
|
433
|
-
`Example: aw config ${command} example-plugin${command === 'set' ? ' mode --scope user --value-json \'"safe"\'' : command === 'unset' ? ' key' : command === 'reset' ? ' --scope user --yes' : ''}`,
|
|
434
|
-
].join('\n');
|
|
435
|
-
}
|
|
436
350
|
async function readUtf8Stdin(stdin) {
|
|
437
351
|
const chunks = [];
|
|
438
352
|
for await (const chunk of stdin) {
|
|
@@ -440,137 +354,6 @@ async function readUtf8Stdin(stdin) {
|
|
|
440
354
|
}
|
|
441
355
|
return Buffer.concat(chunks).toString('utf8');
|
|
442
356
|
}
|
|
443
|
-
function equivalentWriteCommand(command, selection, rawOptions) {
|
|
444
|
-
return shellCommand(buildEquivalentWriteCommandTokens(command, selection, rawOptions));
|
|
445
|
-
}
|
|
446
|
-
export function buildEquivalentWriteCommandTokens(command, selection, rawOptions) {
|
|
447
|
-
return [
|
|
448
|
-
'aw',
|
|
449
|
-
command,
|
|
450
|
-
'--platform',
|
|
451
|
-
selection.platform ?? 'both',
|
|
452
|
-
'--scope',
|
|
453
|
-
selection.scope ?? 'user',
|
|
454
|
-
...(rawOptions.allowManagedCodexInstall === true
|
|
455
|
-
? ['--allow-managed-codex-install']
|
|
456
|
-
: []),
|
|
457
|
-
...(command === 'cleanup' ? ['--yes'] : []),
|
|
458
|
-
...(command === 'install'
|
|
459
|
-
? (rawOptions.dependencyScope ?? []).flatMap((value) => ['--dependency-scope', value])
|
|
460
|
-
: []),
|
|
461
|
-
...((command === 'install' || command === 'reinstall')
|
|
462
|
-
? optionTokens('--script-timeout', rawOptions.scriptTimeout)
|
|
463
|
-
: []),
|
|
464
|
-
...(selection.plugins.length > 0 ? ['--', ...selection.plugins] : []),
|
|
465
|
-
];
|
|
466
|
-
}
|
|
467
|
-
function equivalentConfigCommand(options) {
|
|
468
|
-
return shellCommand(buildEquivalentConfigCommandTokens(options));
|
|
469
|
-
}
|
|
470
|
-
function equivalentConfigCommandProjection(resolve) {
|
|
471
|
-
return {
|
|
472
|
-
equivalentCommand: (selection) => equivalentConfigCommand(resolve(selection)),
|
|
473
|
-
equivalentCommandTokens: (selection) => buildEquivalentConfigCommandTokens(resolve(selection)),
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
export function buildEquivalentConfigCommandTokens(options) {
|
|
477
|
-
return [
|
|
478
|
-
'aw',
|
|
479
|
-
'config',
|
|
480
|
-
options.command,
|
|
481
|
-
...optionTokens('--scope', options.scope),
|
|
482
|
-
...optionTokens('--value-json', options.valueJson),
|
|
483
|
-
...optionTokens('--preset', options.preset),
|
|
484
|
-
...(options.confirmed ? ['--yes'] : []),
|
|
485
|
-
'--',
|
|
486
|
-
options.plugin,
|
|
487
|
-
...(options.key === undefined ? [] : [options.key]),
|
|
488
|
-
...(options.value === undefined ? [] : [options.value]),
|
|
489
|
-
];
|
|
490
|
-
}
|
|
491
|
-
function hasSelectableWriteCandidate(command, candidates, selection, options) {
|
|
492
|
-
const platforms = options.missingPlatform
|
|
493
|
-
? ['codex', 'claude', 'both']
|
|
494
|
-
: [selection.platform ?? 'both'];
|
|
495
|
-
const scopes = options.missingScope ? ['user', 'project'] : [selection.scope ?? 'user'];
|
|
496
|
-
return candidates.some((candidate) => platforms.some((platform) => scopes.some((scope) => writeCandidateEligibility(command, candidate, { ...selection, platform, scope }).selectable)));
|
|
497
|
-
}
|
|
498
|
-
function hasConfigSchemaKeys(candidate) {
|
|
499
|
-
return candidate.configSchema !== undefined && Object.keys(candidate.configSchema).length > 0;
|
|
500
|
-
}
|
|
501
|
-
async function loadWizardCandidates(context, rawOptions) {
|
|
502
|
-
const loaded = await loadConsoleItemsResult({
|
|
503
|
-
cwd: context.cwd,
|
|
504
|
-
scope: rawOptions.scope,
|
|
505
|
-
platform: rawOptions.platform,
|
|
506
|
-
}, context);
|
|
507
|
-
return toWizardCandidates(loaded.items);
|
|
508
|
-
}
|
|
509
|
-
function mergeWizardCandidates(current, stored) {
|
|
510
|
-
const merged = new Map(current.map((candidate) => [candidate.pluginName, candidate]));
|
|
511
|
-
for (const candidate of stored) {
|
|
512
|
-
const existing = merged.get(candidate.pluginName);
|
|
513
|
-
if (!existing) {
|
|
514
|
-
merged.set(candidate.pluginName, candidate);
|
|
515
|
-
}
|
|
516
|
-
else if (!existing.configSchema) {
|
|
517
|
-
merged.set(candidate.pluginName, { ...candidate, ...existing });
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return [...merged.values()];
|
|
521
|
-
}
|
|
522
|
-
async function loadStoredConfigWizardCandidates(context, locations, options = {}) {
|
|
523
|
-
const legacy = await listPluginConfigStorePluginNames({ cwd: context.cwd, env: context.env });
|
|
524
|
-
if (legacy.length > 0) {
|
|
525
|
-
throw new Error('legacyStateUnsupported: legacy bare-name config stores are not supported.');
|
|
526
|
-
}
|
|
527
|
-
const storesByPlugin = new Map();
|
|
528
|
-
for (const location of locations) {
|
|
529
|
-
const stores = await listNamespacedPluginConfigStores({
|
|
530
|
-
cwd: context.cwd,
|
|
531
|
-
env: context.env,
|
|
532
|
-
scope: location.scope,
|
|
533
|
-
});
|
|
534
|
-
for (const store of stores) {
|
|
535
|
-
const keys = Object.keys(store.values);
|
|
536
|
-
if (keys.length === 0 && options.includeEmptyStores !== true)
|
|
537
|
-
continue;
|
|
538
|
-
const existing = storesByPlugin.get(store.pluginId) ?? {
|
|
539
|
-
sourceId: store.sourceId,
|
|
540
|
-
...(store.binding.kind === 'source'
|
|
541
|
-
? { sourceIdentity: store.binding.sourceIdentity }
|
|
542
|
-
: {}),
|
|
543
|
-
keys: new Set(),
|
|
544
|
-
};
|
|
545
|
-
for (const key of keys)
|
|
546
|
-
existing.keys.add(key);
|
|
547
|
-
storesByPlugin.set(store.pluginId, existing);
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
return [...storesByPlugin]
|
|
551
|
-
.sort(([left], [right]) => left.localeCompare(right))
|
|
552
|
-
.map(([pluginId, store]) => ({
|
|
553
|
-
pluginName: pluginId,
|
|
554
|
-
pluginId,
|
|
555
|
-
sourceId: store.sourceId,
|
|
556
|
-
...(store.sourceIdentity ? { sourceIdentity: store.sourceIdentity } : {}),
|
|
557
|
-
targets: [],
|
|
558
|
-
configKeys: [...store.keys].sort((left, right) => left.localeCompare(right)),
|
|
559
|
-
}));
|
|
560
|
-
}
|
|
561
|
-
function configReadStoreLocations(rawOptions) {
|
|
562
|
-
if (rawOptions.scope === 'user')
|
|
563
|
-
return [{ scope: 'user' }];
|
|
564
|
-
if (rawOptions.scope === 'project')
|
|
565
|
-
return [{ scope: 'project' }];
|
|
566
|
-
return [
|
|
567
|
-
{ scope: 'user' },
|
|
568
|
-
{ scope: 'project' },
|
|
569
|
-
];
|
|
570
|
-
}
|
|
571
|
-
function overallResultState(value) {
|
|
572
|
-
return value.overallState === 'succeeded' ? 'succeeded' : 'failed';
|
|
573
|
-
}
|
|
574
357
|
async function resolveStoredConfigResetIdentity(options) {
|
|
575
358
|
const parsed = parsePluginId(options.selector);
|
|
576
359
|
if (parsed.sourceId) {
|
|
@@ -596,27 +379,21 @@ async function resolveStoredConfigResetIdentity(options) {
|
|
|
596
379
|
pluginName: match.pluginName,
|
|
597
380
|
pluginId: match.pluginId,
|
|
598
381
|
sourceId: match.sourceId,
|
|
599
|
-
|
|
600
|
-
? { sourceIdentity: match.binding.sourceIdentity }
|
|
601
|
-
: { logicalIdentity: match.binding.logicalIdentity }),
|
|
382
|
+
sourceIdentity: match.binding.sourceIdentity,
|
|
602
383
|
};
|
|
603
384
|
}
|
|
604
385
|
async function resolveStoredOnlyConfigIdentity(options) {
|
|
605
386
|
const parsed = parsePluginId(options.selector);
|
|
606
387
|
if (!parsed.sourceId)
|
|
607
388
|
throw new Error(`Plugin "${options.selector}" is not a qualified stored config target.`);
|
|
608
|
-
const stores = (await
|
|
609
|
-
cwd: options.context.cwd,
|
|
610
|
-
|
|
611
|
-
scope: location.scope,
|
|
612
|
-
})))).flat().filter((store) => store.pluginId === options.selector);
|
|
389
|
+
const stores = (await listNamespacedPluginConfigStores({
|
|
390
|
+
cwd: options.context.cwd, env: options.context.env, scope: 'user',
|
|
391
|
+
})).filter((store) => store.pluginId === options.selector);
|
|
613
392
|
if (stores.length === 0)
|
|
614
393
|
throw new Error(`Plugin "${options.selector}" does not have a namespaced config store.`);
|
|
615
394
|
const sourceBindings = stores.flatMap((store) => store.binding.kind === 'source'
|
|
616
395
|
? [store.binding.sourceIdentity] : []);
|
|
617
|
-
|
|
618
|
-
? [store.binding.logicalIdentity] : []);
|
|
619
|
-
if (new Set(sourceBindings).size > 1 || new Set(catalogBindings).size > 1) {
|
|
396
|
+
if (new Set(sourceBindings).size > 1) {
|
|
620
397
|
throw new Error(`identityMismatch: ${options.selector} config stores have different bindings.`);
|
|
621
398
|
}
|
|
622
399
|
const currentSource = await withResolvedMultiSourceCatalog({
|
|
@@ -637,9 +414,6 @@ async function resolveStoredOnlyConfigIdentity(options) {
|
|
|
637
414
|
if (sourceBindings[0] && sourceBindings[0] !== currentSource.sourceIdentity) {
|
|
638
415
|
throw new Error(`identityMismatch: ${options.selector} user config does not match the current source identity.`);
|
|
639
416
|
}
|
|
640
|
-
if (catalogBindings[0] && catalogBindings[0] !== currentSource.logicalIdentity) {
|
|
641
|
-
throw new Error(`identityMismatch: ${options.selector} project config does not match the current Catalog logical identity.`);
|
|
642
|
-
}
|
|
643
417
|
return {
|
|
644
418
|
pluginName: parsed.pluginName,
|
|
645
419
|
pluginId: options.selector,
|
|
@@ -652,6 +426,7 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
652
426
|
const inventory = await inventoryLegacyConfigReferences({
|
|
653
427
|
cwd: options.context.cwd,
|
|
654
428
|
env: options.context.env,
|
|
429
|
+
scope: options.rawOptions.context === 'project' ? 'project' : 'user',
|
|
655
430
|
});
|
|
656
431
|
assertCatalogSourceReferencesSupported(inventory);
|
|
657
432
|
return withResolvedCatalogPlugin({
|
|
@@ -662,13 +437,14 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
662
437
|
const result = await resolveConfigRead({
|
|
663
438
|
pluginName: plugin.manifest.name,
|
|
664
439
|
plugin,
|
|
665
|
-
scope:
|
|
440
|
+
scope: options.rawOptions.context === 'project' ? 'project' : 'user',
|
|
441
|
+
platform: options.rawOptions.platform,
|
|
666
442
|
cwd: options.context.cwd,
|
|
667
443
|
env: options.context.env,
|
|
668
444
|
});
|
|
669
445
|
if (options.key !== undefined) {
|
|
670
446
|
const field = findConfigFieldEntry(result.fields, options.key);
|
|
671
|
-
if (!field && plugin.manifest.config
|
|
447
|
+
if (!field && compilePluginConfigDefinition(plugin.manifest.config, options.rawOptions.platform).fields[options.key] === undefined) {
|
|
672
448
|
throw new Error(`Unknown config key "${options.key}".`);
|
|
673
449
|
}
|
|
674
450
|
if (field)
|
|
@@ -689,7 +465,6 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
689
465
|
const stored = await resolveStoredOnlyConfigIdentity({
|
|
690
466
|
selector: options.selector,
|
|
691
467
|
context: options.context,
|
|
692
|
-
locations: configReadStoreLocations(options.rawOptions),
|
|
693
468
|
});
|
|
694
469
|
const result = await resolveConfigRead({
|
|
695
470
|
sourceId: stored.sourceId,
|
|
@@ -697,7 +472,8 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
697
472
|
logicalIdentity: stored.logicalIdentity,
|
|
698
473
|
pluginName: stored.pluginName,
|
|
699
474
|
plugin: null,
|
|
700
|
-
scope:
|
|
475
|
+
scope: options.rawOptions.context === 'project' ? 'project' : 'user',
|
|
476
|
+
platform: options.rawOptions.platform,
|
|
701
477
|
cwd: options.context.cwd,
|
|
702
478
|
env: options.context.env,
|
|
703
479
|
});
|
|
@@ -710,6 +486,46 @@ async function resolveMultiSourceConfigRead(options) {
|
|
|
710
486
|
return { ...stored, result };
|
|
711
487
|
});
|
|
712
488
|
}
|
|
489
|
+
function renderRecoveryReceipt(write, value) {
|
|
490
|
+
writeLine(write, `${value.command} [${value.scope}]: ${value.ok ? 'ok' : 'failed'}`);
|
|
491
|
+
writeLine(write, `需求:${value.intent.roots?.join('、') || (value.intent.roots === null ? '不可读' : '无')}`);
|
|
492
|
+
writeLine(write, `本机工具:${value.selection.agents.join('、') || '未配置'}`);
|
|
493
|
+
writeLine(write, `变化:声明 ${value.declarationChanged ? '已保存' : '无'};偏好 ${value.preferencesChanged ? '已保存' : '无'};配置 ${value.configChanged ? '已保存' : '无'};输出 ${value.outputsMayHaveChanged ? '可能已变更' : '无'}`);
|
|
494
|
+
for (const target of value.targetResults) {
|
|
495
|
+
writeLine(write, `${target.pluginId} / ${target.agent} [${target.scope}]: ${target.execution}; ${target.content ?? target.observation}`);
|
|
496
|
+
}
|
|
497
|
+
for (const result of value.commandResults ?? []) {
|
|
498
|
+
const producer = result.producer;
|
|
499
|
+
writeLine(write, `托管命令 ${producer.sourceId}/${producer.pluginName}/${producer.key} [${producer.scope}]: ${result.state}`);
|
|
500
|
+
}
|
|
501
|
+
for (const change of value.nativeToolChanges ?? []) {
|
|
502
|
+
for (const phase of ['before', 'after']) {
|
|
503
|
+
const closure = change[phase];
|
|
504
|
+
if (closure)
|
|
505
|
+
for (const description of describeNativeToolClosure(closure)) {
|
|
506
|
+
writeLine(write, `原生工具 ${change.producer.sourceId}/${change.producer.pluginName} ${phase}: ${description}`);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
const diagnostics = new Map([...value.blockers, ...value.errors,
|
|
511
|
+
...value.targetResults.flatMap((target) => target.blockers),
|
|
512
|
+
...(value.commandResults ?? []).flatMap((result) => result.errors),
|
|
513
|
+
].map((item) => [`${item.code}:${item.message}`, item]));
|
|
514
|
+
for (const item of diagnostics.values())
|
|
515
|
+
writeLine(write, `${item.code}: ${item.message}`);
|
|
516
|
+
for (const action of value.recoveryActions)
|
|
517
|
+
writeLine(write, action);
|
|
518
|
+
}
|
|
519
|
+
function renderRecoveryStatus(write, value) {
|
|
520
|
+
writeLine(write, `status [${value.scope}]: ${value.ok ? 'ok' : 'failed'}`);
|
|
521
|
+
writeLine(write, `本机工具:${value.selection.agents.join('、') || '未配置'}`);
|
|
522
|
+
writeLine(write, `全部满足:${value.allSatisfied === null ? '未知' : value.allSatisfied ? '是' : '否'}`);
|
|
523
|
+
for (const root of value.inventory ?? []) {
|
|
524
|
+
writeLine(write, `${root.pluginId}: ${root.targetResults.length ? root.targetResults.map((target) => `${target.agent}/${target.content ?? target.observation}`).join(', ') : 'localTargetsRequired'}`);
|
|
525
|
+
}
|
|
526
|
+
for (const error of value.errors)
|
|
527
|
+
writeLine(write, `${error.code}: ${error.message}`);
|
|
528
|
+
}
|
|
713
529
|
export function createManagedCodexAuthorizer(rawOptions, context) {
|
|
714
530
|
if (rawOptions.allowManagedCodexInstall === true)
|
|
715
531
|
return async () => true;
|
|
@@ -724,152 +540,14 @@ export function createManagedCodexAuthorizer(rawOptions, context) {
|
|
|
724
540
|
return !response.cancelled && response.value === true;
|
|
725
541
|
};
|
|
726
542
|
}
|
|
727
|
-
|
|
728
|
-
const raw = { cwd: context.cwd, ...rawOptions };
|
|
729
|
-
const commandOptions = normalizeWriteRequest(() => command === 'install'
|
|
730
|
-
? normalizeInstallCommandOptions(raw)
|
|
731
|
-
: command === 'uninstall'
|
|
732
|
-
? normalizeUninstallCommandOptions(raw)
|
|
733
|
-
: command === 'cleanup'
|
|
734
|
-
? normalizeCleanupCommandOptions(raw)
|
|
735
|
-
: normalizeReinstallCommandOptions(raw));
|
|
736
|
-
await emitCommandEvent(context, {
|
|
737
|
-
type: 'options:normalized',
|
|
738
|
-
data: { plugins: pluginNames, options: commandOptions },
|
|
739
|
-
});
|
|
543
|
+
function recoveryRuntime(context, rawOptions, directCli) {
|
|
740
544
|
const managedCodexAuthorizer = createManagedCodexAuthorizer(rawOptions, context);
|
|
741
|
-
|
|
545
|
+
return {
|
|
742
546
|
...context,
|
|
743
547
|
directCli,
|
|
744
548
|
preApplyConfirmed: rawOptions.yes === true,
|
|
745
|
-
...(expectedPlanFingerprint ? { expectedPlanFingerprint } : {}),
|
|
746
549
|
...(managedCodexAuthorizer ? { managedCodexAuthorizer } : {}),
|
|
747
550
|
};
|
|
748
|
-
switch (command) {
|
|
749
|
-
case 'install': return installCommand(pluginNames, commandOptions, runtime);
|
|
750
|
-
case 'uninstall': return uninstallCommand(pluginNames, commandOptions, runtime);
|
|
751
|
-
case 'cleanup': return cleanupCommand(pluginNames, commandOptions, runtime);
|
|
752
|
-
case 'reinstall': return reinstallCommand(pluginNames, commandOptions, runtime);
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
async function runWriteCommandAction(command, pluginNames, rawOptions, context) {
|
|
756
|
-
if ((command === 'cleanup' || command === 'reinstall') && pluginNames.length > 1) {
|
|
757
|
-
throw new WriteCommandRequestError(`${command} 命令当前只支持单个插件目标。`);
|
|
758
|
-
}
|
|
759
|
-
const missingPlugin = pluginNames.length === 0;
|
|
760
|
-
const missingPlatform = rawOptions.platform === undefined;
|
|
761
|
-
const missingScope = command === 'cleanup' && rawOptions.scope === undefined;
|
|
762
|
-
const missing = missingPlugin || missingPlatform || missingScope;
|
|
763
|
-
// Validate every value already supplied by the caller before opening the TUI.
|
|
764
|
-
const validationOptions = {
|
|
765
|
-
cwd: context.cwd,
|
|
766
|
-
...rawOptions,
|
|
767
|
-
platform: rawOptions.platform ?? 'both',
|
|
768
|
-
...(command === 'cleanup' ? { scope: rawOptions.scope ?? 'user' } : {}),
|
|
769
|
-
};
|
|
770
|
-
void validationOptions;
|
|
771
|
-
if (!missing) {
|
|
772
|
-
if (command === 'cleanup' && rawOptions.force !== true && rawOptions.yes !== true
|
|
773
|
-
&& isWizardAvailable(context, rawOptions) && context.prompt.confirm) {
|
|
774
|
-
const preview = await cleanupCommand(pluginNames, normalizeCleanupCommandOptions({
|
|
775
|
-
cwd: context.cwd,
|
|
776
|
-
...rawOptions,
|
|
777
|
-
}), { ...context, previewOperationPlan: true });
|
|
778
|
-
if ((preview.removedPluginCleanupIds?.length ?? 0) > 0) {
|
|
779
|
-
if (!preview.operationPlan) {
|
|
780
|
-
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
781
|
-
}
|
|
782
|
-
const response = await context.prompt.confirm({
|
|
783
|
-
message: `清理已删除插件 ${preview.removedPluginCleanupIds.join('、')}:将处理 Codex、Claude Code 的用户与当前项目位置,删除保存设置、安装意图、专属输出和共享原生安装。其他项目可能因此无法继续使用该插件;其本地记录不会修改。即使指定了 --platform 或 --scope,本次仍覆盖上述全部位置。继续?`,
|
|
784
|
-
defaultValue: false,
|
|
785
|
-
});
|
|
786
|
-
if (response.cancelled || response.value !== true)
|
|
787
|
-
return { cancelled: true };
|
|
788
|
-
return {
|
|
789
|
-
cancelled: false,
|
|
790
|
-
result: await executeWriteCommand(command, pluginNames, {
|
|
791
|
-
...rawOptions, yes: true,
|
|
792
|
-
}, context, true, preview.operationPlan.planFingerprint),
|
|
793
|
-
};
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
return {
|
|
797
|
-
cancelled: false,
|
|
798
|
-
result: await executeWriteCommand(command, pluginNames, rawOptions, context, true),
|
|
799
|
-
};
|
|
800
|
-
}
|
|
801
|
-
if (!isWizardAvailable(context, rawOptions)) {
|
|
802
|
-
throw new WriteCommandRequestError(writeCommandUsage(command));
|
|
803
|
-
}
|
|
804
|
-
const loaded = await loadConsoleItemsResult({
|
|
805
|
-
cwd: context.cwd,
|
|
806
|
-
scope: rawOptions.scope,
|
|
807
|
-
platform: rawOptions.platform,
|
|
808
|
-
}, context);
|
|
809
|
-
if (loaded.catalogUnavailable) {
|
|
810
|
-
throw new Error('插件目录不可用。请运行 `aw init` 或 `aw init --force`,或使用完整参数重试。');
|
|
811
|
-
}
|
|
812
|
-
const candidates = missingPlugin ? toWizardCandidates(loaded.items) : [];
|
|
813
|
-
const initialSelection = {
|
|
814
|
-
plugins: pluginNames,
|
|
815
|
-
platform: rawOptions.platform,
|
|
816
|
-
scope: (rawOptions.scope ?? 'user'),
|
|
817
|
-
};
|
|
818
|
-
if (missingPlugin && !hasSelectableWriteCandidate(command, candidates, initialSelection, {
|
|
819
|
-
missingPlatform,
|
|
820
|
-
missingScope,
|
|
821
|
-
})) {
|
|
822
|
-
throw new Error('没有可执行此操作的目标。请运行 `aw status` 检查当前状态。');
|
|
823
|
-
}
|
|
824
|
-
const result = await runCommandWizard(context, {
|
|
825
|
-
command,
|
|
826
|
-
candidates,
|
|
827
|
-
initial: initialSelection,
|
|
828
|
-
pluginMode: missingPlugin
|
|
829
|
-
? command === 'cleanup' || command === 'reinstall' ? 'single' : 'multiple'
|
|
830
|
-
: 'none',
|
|
831
|
-
promptForPlatform: missingPlatform,
|
|
832
|
-
promptForScope: missingScope,
|
|
833
|
-
destructive: command === 'uninstall' || command === 'cleanup',
|
|
834
|
-
equivalentCommand: (selection) => equivalentWriteCommand(command, selection, rawOptions),
|
|
835
|
-
equivalentCommandTokens: (selection) => buildEquivalentWriteCommandTokens(command, selection, rawOptions),
|
|
836
|
-
isPluginSelectable: (candidate, selection) => writeCandidateEligibility(command, candidate, selection),
|
|
837
|
-
resultState: overallResultState,
|
|
838
|
-
...(command === 'cleanup' ? {
|
|
839
|
-
reviewDetails: async (selection) => {
|
|
840
|
-
const preview = await cleanupCommand(selection.plugins, normalizeCleanupCommandOptions({
|
|
841
|
-
cwd: context.cwd,
|
|
842
|
-
...rawOptions,
|
|
843
|
-
platform: selection.platform,
|
|
844
|
-
scope: selection.scope,
|
|
845
|
-
}), { ...context, previewOperationPlan: true });
|
|
846
|
-
if ((preview.removedPluginCleanupIds?.length ?? 0) === 0)
|
|
847
|
-
return { lines: [] };
|
|
848
|
-
if (!preview.operationPlan) {
|
|
849
|
-
throw new WriteCommandRequestError('cleanupPlanUnavailable: 无法建立可信的整体清理预览。');
|
|
850
|
-
}
|
|
851
|
-
return {
|
|
852
|
-
lines: [
|
|
853
|
-
`已删除插件:${preview.removedPluginCleanupIds.join('、')}`,
|
|
854
|
-
'实际清理范围:Codex、Claude Code;用户与当前项目。',
|
|
855
|
-
'将删除保存设置、安装意图、专属输出和共享原生安装。',
|
|
856
|
-
'其他项目可能失去此插件;其本地记录不会修改。',
|
|
857
|
-
'当前 --platform / --scope 选择不会限制整体清理范围。',
|
|
858
|
-
],
|
|
859
|
-
expectedPlanFingerprint: preview.operationPlan.planFingerprint,
|
|
860
|
-
};
|
|
861
|
-
},
|
|
862
|
-
} : {}),
|
|
863
|
-
execute: (selection, expectedPlanFingerprint) => executeWriteCommand(command, selection.plugins, {
|
|
864
|
-
...rawOptions,
|
|
865
|
-
platform: selection.platform,
|
|
866
|
-
scope: selection.scope,
|
|
867
|
-
...(command === 'cleanup' ? { yes: true } : {}),
|
|
868
|
-
}, context, false, expectedPlanFingerprint),
|
|
869
|
-
});
|
|
870
|
-
if (result.cancelled)
|
|
871
|
-
return { cancelled: true };
|
|
872
|
-
return { cancelled: false, result: result.value };
|
|
873
551
|
}
|
|
874
552
|
function parseBareConsoleOptions(argv) {
|
|
875
553
|
if (argv.length === 0) {
|
|
@@ -976,12 +654,6 @@ async function runActionWithContext(context, action) {
|
|
|
976
654
|
function writeJsonReceipt(write, payload) {
|
|
977
655
|
writeLine(write, JSON.stringify(payload, null, 2));
|
|
978
656
|
}
|
|
979
|
-
function configLayerLabel(scope) {
|
|
980
|
-
if (scope === 'user') {
|
|
981
|
-
return '个人';
|
|
982
|
-
}
|
|
983
|
-
return '当前项目';
|
|
984
|
-
}
|
|
985
657
|
function writeConfigApplyNotice(write, receipt) {
|
|
986
658
|
const sanitizeMessage = (message) => redactString(message)
|
|
987
659
|
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
@@ -995,9 +667,9 @@ function writeConfigApplyNotice(write, receipt) {
|
|
|
995
667
|
: entry.errorCode
|
|
996
668
|
? `失败原因:${entry.errorCode}。`
|
|
997
669
|
: '未提供安全失败原因。';
|
|
998
|
-
const command = `aw
|
|
670
|
+
const command = `aw plugin sync ${receipt.plugin} --rebuild --target ${entry.target.platform} --context ${entry.target.scope}`;
|
|
999
671
|
const recovery = entry.errorCode === 'invalidConfig'
|
|
1000
|
-
?
|
|
672
|
+
? ` 请修复无效配置后运行 ${command}。`
|
|
1001
673
|
: entry.errorCode === 'preApplyAuthorizationRequired'
|
|
1002
674
|
|| entry.errorCode === 'sharedNativeConfigApplyConfirmationRequired'
|
|
1003
675
|
|| entry.errorCode === 'sharedNativeImpactAuthorizationRequired'
|
|
@@ -1011,9 +683,9 @@ function writeConfigApplyNotice(write, receipt) {
|
|
|
1011
683
|
const targetResults = receipt.apply.targetResults;
|
|
1012
684
|
if (receipt.apply.state === 'skipped') {
|
|
1013
685
|
const message = receipt.apply.reason === 'noConfigChange'
|
|
1014
|
-
? '
|
|
686
|
+
? '配置内容没有变化,因此没有刷新输出。'
|
|
1015
687
|
: receipt.apply.reason === 'noEffectiveConfigChange'
|
|
1016
|
-
? '
|
|
688
|
+
? '配置存储已更新,但有效配置没有变化,因此没有刷新输出。'
|
|
1017
689
|
: receipt.apply.reason === 'notRequested'
|
|
1018
690
|
? '配置已保存,但未请求应用配置。'
|
|
1019
691
|
: '配置已保存。当前没有可见的 AW 安装目标,因此没有应用配置。';
|
|
@@ -1031,12 +703,12 @@ function writeConfigApplyNotice(write, receipt) {
|
|
|
1031
703
|
? `${receipt.apply.error.code}:${sanitizeMessage(receipt.apply.error.message)}`
|
|
1032
704
|
: `${receipt.apply.reason}:${fallbackMessages[receipt.apply.reason]}`;
|
|
1033
705
|
const recovery = receipt.apply.reason === 'invalidConfig'
|
|
1034
|
-
? '
|
|
706
|
+
? '请修复无效配置,再运行 aw plugin sync <source/plugin>。'
|
|
1035
707
|
: receipt.apply.reason === 'effectiveConfigUnavailable'
|
|
1036
|
-
? '
|
|
708
|
+
? '请修复配置,再运行 aw plugin sync <source/plugin>。'
|
|
1037
709
|
: receipt.apply.reason === 'schemaUnavailable' || receipt.apply.reason === 'sourceUnavailable'
|
|
1038
|
-
? '
|
|
1039
|
-
: '
|
|
710
|
+
? '请修复插件来源或配置,再运行 aw plugin sync <source/plugin>。'
|
|
711
|
+
: '请修复来源或配置,再运行 aw plugin sync <source/plugin>。';
|
|
1040
712
|
writeLine(write, `配置已保存,但当前无法应用配置。${detail} ${recovery}`);
|
|
1041
713
|
writeTargetFailures();
|
|
1042
714
|
}
|
|
@@ -1044,7 +716,7 @@ function writeConfigApplyNotice(write, receipt) {
|
|
|
1044
716
|
const completed = targetResults.filter((entry) => entry.state === 'completed').length;
|
|
1045
717
|
const failed = targetResults.filter((entry) => entry.state === 'failed').length;
|
|
1046
718
|
const skipped = targetResults.filter((entry) => entry.state === 'skipped').length;
|
|
1047
|
-
writeLine(write,
|
|
719
|
+
writeLine(write, `配置已保存。已刷新 ${completed} 个当前可见目标;失败 ${failed} 个;跳过 ${skipped} 个。`);
|
|
1048
720
|
writeTargetFailures();
|
|
1049
721
|
}
|
|
1050
722
|
writeWarnings(write, receipt.warnings);
|
|
@@ -1066,16 +738,14 @@ function writeConfigReadHuman(write, resolved, pluginName) {
|
|
|
1066
738
|
writeLine(write, ` stored=${field.storedSourceLayer} ${renderPluginConfigValueForDisplay(field.storedValue)}`);
|
|
1067
739
|
}
|
|
1068
740
|
if (field.kind === 'manifest' && field.valueState === 'invalid') {
|
|
1069
|
-
const
|
|
1070
|
-
? 'project'
|
|
1071
|
-
: 'user';
|
|
741
|
+
const context = resolved.context ?? 'user';
|
|
1072
742
|
const definition = resolved.fieldDefinitions?.[field.key];
|
|
1073
743
|
if (definition) {
|
|
1074
|
-
writeLine(write, ` ${formatPluginConfigSetRecoveryCommand(pluginName, field.key, definition,
|
|
744
|
+
writeLine(write, ` ${formatPluginConfigSetRecoveryCommand(pluginName, field.key, definition, context, resolved.platform)}`);
|
|
1075
745
|
}
|
|
1076
|
-
const
|
|
1077
|
-
writeLine(write, ` aw config unset ${pluginName} ${field.key}${
|
|
1078
|
-
writeLine(write, ` aw config reset ${pluginName}${
|
|
746
|
+
const profileOptions = ` --context ${context}${resolved.platform ? ` --platform ${resolved.platform}` : ''}`;
|
|
747
|
+
writeLine(write, ` aw plugin config unset ${pluginName} ${field.key}${profileOptions}`);
|
|
748
|
+
writeLine(write, ` aw plugin config reset ${pluginName}${profileOptions} --yes`);
|
|
1079
749
|
}
|
|
1080
750
|
}
|
|
1081
751
|
}
|
|
@@ -1108,7 +778,7 @@ export function buildProgram(options = {}) {
|
|
|
1108
778
|
});
|
|
1109
779
|
const plugin = program
|
|
1110
780
|
.command('plugin')
|
|
1111
|
-
.description('
|
|
781
|
+
.description('Manage plugin demand, outputs, configuration, and author sources');
|
|
1112
782
|
registerManagedCommandCli(program, () => createActionContext('command', {}), {
|
|
1113
783
|
cliEntry: fileURLToPath(import.meta.url),
|
|
1114
784
|
cliVersion: resolveCliVersion(),
|
|
@@ -1296,7 +966,7 @@ export function buildProgram(options = {}) {
|
|
|
1296
966
|
.argument('<target>', 'Catalog Workspace, Plugin, or source Skill path')
|
|
1297
967
|
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1298
968
|
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1299
|
-
.addOption(strictValueOption('--platform <platform>', 'select
|
|
969
|
+
.addOption(strictValueOption('--platform <platform>', 'select a canonical platform target', PLATFORM_TARGETS))
|
|
1300
970
|
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']))
|
|
1301
971
|
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1302
972
|
.option('--materialization <receipt>', 'validate one aw-source-binding receipt', collectUniqueOption, [])
|
|
@@ -1340,7 +1010,7 @@ export function buildProgram(options = {}) {
|
|
|
1340
1010
|
.argument('<target>', 'Plugin or source Skill path')
|
|
1341
1011
|
.addOption(strictValueOption('--workspace-root <root>', 'explicit Catalog Workspace root'))
|
|
1342
1012
|
.option('--skill <name>', 'select one declared Skill', collectUniqueOption, [])
|
|
1343
|
-
.addOption(strictValueOption('--platform <platform>', 'select
|
|
1013
|
+
.addOption(strictValueOption('--platform <platform>', 'select a canonical platform target', PLATFORM_TARGETS).makeOptionMandatory())
|
|
1344
1014
|
.addOption(strictValueOption('--scope <scope>', 'select user or project scope', ['user', 'project']).makeOptionMandatory())
|
|
1345
1015
|
.addOption(strictValueOption('--config <file>', 'review config JSON file'))
|
|
1346
1016
|
.addOption(strictValueOption('--out <new-dir>', 'new output directory').makeOptionMandatory())
|
|
@@ -1365,117 +1035,12 @@ export function buildProgram(options = {}) {
|
|
|
1365
1035
|
renderReviewPreparation(io.stdout, result.receipt);
|
|
1366
1036
|
commandExitState.exitCode = result.exitCode;
|
|
1367
1037
|
});
|
|
1368
|
-
skill
|
|
1369
|
-
.command('install')
|
|
1370
|
-
.description('Install portable Skills through the skills CLI')
|
|
1371
|
-
.argument('<plugin>', 'plugin or source/plugin selector')
|
|
1372
|
-
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
1373
|
-
.option('--skill <name...>', 'install only selected Skill names')
|
|
1374
|
-
.option('--agent <id...>', 'install to explicit Agent IDs')
|
|
1375
|
-
.option('-y, --yes', 'confirm the reviewed install', false)
|
|
1376
|
-
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
1377
|
-
.action(async (selector, rawOptions) => {
|
|
1378
|
-
const context = createActionContext('skill:install', {});
|
|
1379
|
-
const writeFailure = (error) => {
|
|
1380
|
-
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1381
|
-
const code = capabilityError?.code
|
|
1382
|
-
?? (error instanceof PortableCommandError || error instanceof SkillsCliError
|
|
1383
|
-
? error.code
|
|
1384
|
-
: 'portableInstallFailed');
|
|
1385
|
-
writeJsonReceipt(io.stdout, {
|
|
1386
|
-
receiptSchemaVersion: 5,
|
|
1387
|
-
command: 'skill:install',
|
|
1388
|
-
ok: false,
|
|
1389
|
-
status: 'failed',
|
|
1390
|
-
plugin: { id: selector },
|
|
1391
|
-
scope: rawOptions.scope,
|
|
1392
|
-
selectedSkills: [],
|
|
1393
|
-
...(rawOptions.skill ? { requestedSkills: rawOptions.skill } : {}),
|
|
1394
|
-
agentMode: rawOptions.agent ? 'explicit' : 'automatic',
|
|
1395
|
-
requestedAgents: rawOptions.agent ?? [],
|
|
1396
|
-
skillsCliVersion: null,
|
|
1397
|
-
collisions: [],
|
|
1398
|
-
dependencies: [],
|
|
1399
|
-
materializationDigest: null,
|
|
1400
|
-
verification: { records: [], missing: [] },
|
|
1401
|
-
warnings: [],
|
|
1402
|
-
failures: [{
|
|
1403
|
-
code,
|
|
1404
|
-
message: capabilityError?.message ?? `${code}: portable Skill 安装未执行。`,
|
|
1405
|
-
...(capabilityError ? {
|
|
1406
|
-
plugin: capabilityError.plugin,
|
|
1407
|
-
missingCapabilities: capabilityError.missingCapabilities,
|
|
1408
|
-
availableCapabilities: capabilityError.availableCapabilities,
|
|
1409
|
-
} : {}),
|
|
1410
|
-
}],
|
|
1411
|
-
});
|
|
1412
|
-
};
|
|
1413
|
-
if (rawOptions.json && !rawOptions.yes) {
|
|
1414
|
-
writeFailure(new PortableCommandError('confirmationRequired', '写入型 --json 必须同时使用 --yes。'));
|
|
1415
|
-
commandExitState.exitCode = 1;
|
|
1416
|
-
return;
|
|
1417
|
-
}
|
|
1418
|
-
try {
|
|
1419
|
-
const receipt = await runActionWithContext(context, () => installPortableSkills({
|
|
1420
|
-
selector,
|
|
1421
|
-
scope: rawOptions.scope,
|
|
1422
|
-
...(rawOptions.skill ? { requestedSkills: rawOptions.skill } : {}),
|
|
1423
|
-
...(rawOptions.agent ? { requestedAgents: rawOptions.agent } : {}),
|
|
1424
|
-
yes: rawOptions.yes,
|
|
1425
|
-
cwd: context.cwd,
|
|
1426
|
-
cliVersion: resolveCliVersion(),
|
|
1427
|
-
env: context.env,
|
|
1428
|
-
...(context.interactive && context.prompt.confirm ? {
|
|
1429
|
-
confirm: async () => context.prompt.confirm({
|
|
1430
|
-
message: '确认按以上 Review 安装 portable Skills?',
|
|
1431
|
-
defaultValue: false,
|
|
1432
|
-
}),
|
|
1433
|
-
} : {}),
|
|
1434
|
-
...(!rawOptions.json ? {
|
|
1435
|
-
onReview: (review) => {
|
|
1436
|
-
for (const line of renderPortableReview(review))
|
|
1437
|
-
writeLine(io.stdout, line);
|
|
1438
|
-
},
|
|
1439
|
-
} : {}),
|
|
1440
|
-
}));
|
|
1441
|
-
if (rawOptions.json)
|
|
1442
|
-
writeJsonReceipt(io.stdout, receipt);
|
|
1443
|
-
else if (receipt.ok)
|
|
1444
|
-
writeLine(io.stdout, `portable Skill 安装完成:${receipt.selectedSkills.length} 项。`);
|
|
1445
|
-
else {
|
|
1446
|
-
const sanitize = (value) => redactString(value)
|
|
1447
|
-
.replace(/https?:\/\/\S+/giu, '[REDACTED URL]')
|
|
1448
|
-
.replace(/file:\/\/\S+/giu, '[REDACTED PATH]')
|
|
1449
|
-
.replace(/(?:file:\/\/)?(?:\/[\w.@+-]+){2,}/gu, '[REDACTED PATH]')
|
|
1450
|
-
.replace(/[A-Za-z]:\\(?:[^\s\\]+\\)+[^\s\\]*/gu, '[REDACTED PATH]');
|
|
1451
|
-
const lines = new Set();
|
|
1452
|
-
for (const failure of receipt.failures) {
|
|
1453
|
-
lines.add(`${failure.code}: ${sanitize(failure.message)}`);
|
|
1454
|
-
}
|
|
1455
|
-
for (const warning of receipt.warnings)
|
|
1456
|
-
lines.add(`警告:${sanitize(warning)}`);
|
|
1457
|
-
const recoveries = receipt.failures.map((failure) => failure.recovery).filter(Boolean);
|
|
1458
|
-
const recovery = recoveries.find((entry) => entry.includes('aw skill install')
|
|
1459
|
-
&& entry.includes('skills remove'))
|
|
1460
|
-
?? '重新运行 aw skill install;如需清理外部写入,请使用 skills remove。';
|
|
1461
|
-
lines.add(`恢复:${sanitize(recovery)}`);
|
|
1462
|
-
for (const line of lines)
|
|
1463
|
-
writeLine(io.stderr, line);
|
|
1464
|
-
}
|
|
1465
|
-
commandExitState.exitCode = receipt.ok ? 0 : 1;
|
|
1466
|
-
}
|
|
1467
|
-
catch (error) {
|
|
1468
|
-
if (!rawOptions.json)
|
|
1469
|
-
throw error;
|
|
1470
|
-
writeFailure(error);
|
|
1471
|
-
commandExitState.exitCode = 1;
|
|
1472
|
-
}
|
|
1473
|
-
});
|
|
1474
1038
|
skill
|
|
1475
1039
|
.command('materialize')
|
|
1476
1040
|
.description('Write portable Skills to a safe output directory')
|
|
1477
1041
|
.argument('<plugin>', 'plugin or source/plugin selector')
|
|
1478
|
-
.
|
|
1042
|
+
.addOption(strictValueOption('--platform <target>', 'Portable platform target', PORTABLE_PLATFORM_TARGETS).makeOptionMandatory())
|
|
1043
|
+
.addOption(strictValueOption('-s, --scope <scope>', 'artifact scope', ['user', 'project']).makeOptionMandatory())
|
|
1479
1044
|
.requiredOption('--out <dir>', 'output directory')
|
|
1480
1045
|
.option('--skill <name...>', 'write only selected Skill names')
|
|
1481
1046
|
.option('-j, --json', 'emit one receipt v5 JSON object', false)
|
|
@@ -1484,6 +1049,7 @@ export function buildProgram(options = {}) {
|
|
|
1484
1049
|
try {
|
|
1485
1050
|
const receipt = await runActionWithContext(context, () => materializePortableSkillsToDirectory({
|
|
1486
1051
|
selector,
|
|
1052
|
+
platform: rawOptions.platform,
|
|
1487
1053
|
scope: rawOptions.scope,
|
|
1488
1054
|
out: rawOptions.out,
|
|
1489
1055
|
...(rawOptions.skill ? { requestedSkills: rawOptions.skill } : {}),
|
|
@@ -1501,7 +1067,7 @@ export function buildProgram(options = {}) {
|
|
|
1501
1067
|
throw error;
|
|
1502
1068
|
const capabilityError = error instanceof AwCapabilityUnsupportedError ? error : undefined;
|
|
1503
1069
|
const code = capabilityError?.code
|
|
1504
|
-
?? (error instanceof PortableCommandError
|
|
1070
|
+
?? (error instanceof PortableCommandError
|
|
1505
1071
|
? error.code
|
|
1506
1072
|
: 'portableMaterializeFailed');
|
|
1507
1073
|
writeJsonReceipt(io.stdout, {
|
|
@@ -1510,6 +1076,7 @@ export function buildProgram(options = {}) {
|
|
|
1510
1076
|
ok: false,
|
|
1511
1077
|
plugin: { id: selector },
|
|
1512
1078
|
scope: rawOptions.scope,
|
|
1079
|
+
platform: rawOptions.platform,
|
|
1513
1080
|
out: path.resolve(context.cwd, rawOptions.out),
|
|
1514
1081
|
selectedSkills: [],
|
|
1515
1082
|
...(rawOptions.skill ? { requestedSkills: rawOptions.skill } : {}),
|
|
@@ -1571,13 +1138,6 @@ export function buildProgram(options = {}) {
|
|
|
1571
1138
|
.option('--skill-short-description <text>', 'Skill UI summary (25-64 characters)')
|
|
1572
1139
|
.option('--skill-invocation <mode>', 'model | manual | claude-model-only (default: model)')
|
|
1573
1140
|
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1574
|
-
plugin
|
|
1575
|
-
.command('remove')
|
|
1576
|
-
.description('Remove one committed and unchanged canonical plugin source tree')
|
|
1577
|
-
.argument('<plugin-name>', 'existing lowercase hyphen-case plugin name')
|
|
1578
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)')
|
|
1579
|
-
.option('--yes', 'confirm plugin source deletion', false)
|
|
1580
|
-
.option('--json', 'emit one schema 1 JSON object', false);
|
|
1581
1141
|
plugin
|
|
1582
1142
|
.command('validate')
|
|
1583
1143
|
.description('Validate one source plugin directory')
|
|
@@ -1651,14 +1211,6 @@ export function buildProgram(options = {}) {
|
|
|
1651
1211
|
commandExitState.exitCode = 1;
|
|
1652
1212
|
}
|
|
1653
1213
|
});
|
|
1654
|
-
plugin
|
|
1655
|
-
.command('status')
|
|
1656
|
-
.description('Show current plugin status or compare against an explicit Git base')
|
|
1657
|
-
.argument('[plugin-name]', 'one explicit plugin name')
|
|
1658
|
-
.option('--all', 'check every current Catalog Workspace plugin', false)
|
|
1659
|
-
.option('--base <git-ref>', 'explicit Git comparison base')
|
|
1660
|
-
.option('--json', 'emit one schema v3 JSON document', false)
|
|
1661
|
-
.option('--workspace-root <path>', 'Catalog Workspace root (default: nearest ancestor from current directory)');
|
|
1662
1214
|
skill
|
|
1663
1215
|
.command('validate')
|
|
1664
1216
|
.description('Validate one Agent Skill directory')
|
|
@@ -2035,12 +1587,10 @@ export function buildProgram(options = {}) {
|
|
|
2035
1587
|
? failure.message
|
|
2036
1588
|
: redactString(sanitizeCatalogSourceErrorMessage(error instanceof Error ? error.message : String(error), env, [cwd]));
|
|
2037
1589
|
writeLine(io.stderr, message);
|
|
2038
|
-
commandExitState.exitCode = 1;
|
|
1590
|
+
commandExitState.exitCode = failure.code === 'invalidArguments' ? 2 : 1;
|
|
2039
1591
|
};
|
|
2040
|
-
const withResolvedConfigMutationPlugin = (context, selector, consume,
|
|
1592
|
+
const withResolvedConfigMutationPlugin = (context, selector, consume, _apply = false) => (async () => {
|
|
2041
1593
|
const parsed = parsePluginId(selector);
|
|
2042
|
-
if (apply)
|
|
2043
|
-
await prepareNativeCliExecution({ env: context.env, runner: context.nativeCliRunner });
|
|
2044
1594
|
return withAwHomeMutationLock({
|
|
2045
1595
|
env: context.env,
|
|
2046
1596
|
action: async (awHomeMutationToken) => {
|
|
@@ -2449,777 +1999,409 @@ export function buildProgram(options = {}) {
|
|
|
2449
1999
|
}
|
|
2450
2000
|
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
2451
2001
|
});
|
|
2452
|
-
|
|
2453
|
-
.
|
|
2454
|
-
.description('Reconcile actual state from existing desired intent')
|
|
2455
|
-
.argument('[plugins...]')
|
|
2456
|
-
.requiredOption('-s, --scope <scope>', 'project or user')
|
|
2457
|
-
.requiredOption('-p, --platform <platform>', 'codex, claude, or both')
|
|
2458
|
-
.option('-a, --all', 'reconcile every desired plugin in the selected scope', false)
|
|
2459
|
-
.option('--refresh', 'refresh only Catalog sources required by selected intent roots', false)
|
|
2460
|
-
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2461
|
-
.option('-y, --yes', 'authorize preApply and shared native replacement or forced repair', false)
|
|
2462
|
-
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2463
|
-
.option('-j, --json', 'print sync receipt as JSON', false)
|
|
2464
|
-
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2465
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2466
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2467
|
-
.action(async (plugins, rawOptions) => {
|
|
2468
|
-
const context = createActionContext('sync', rawOptions);
|
|
2469
|
-
const normalized = normalizeWriteRequest(() => normalizeInstallCommandOptions({
|
|
2470
|
-
cwd: context.cwd,
|
|
2471
|
-
scope: rawOptions.scope,
|
|
2472
|
-
platform: rawOptions.platform,
|
|
2473
|
-
scriptTimeout: rawOptions.scriptTimeout,
|
|
2474
|
-
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2475
|
-
}));
|
|
2476
|
-
const syncPlatform = normalized.platform;
|
|
2477
|
-
const result = await runActionWithContext(context, () => syncCommand(plugins ?? [], {
|
|
2478
|
-
cwd: context.cwd,
|
|
2479
|
-
env: context.env,
|
|
2480
|
-
platform: syncPlatform,
|
|
2481
|
-
scope: normalized.scope,
|
|
2482
|
-
all: rawOptions.all,
|
|
2483
|
-
refresh: rawOptions.refresh,
|
|
2484
|
-
cliVersion: resolveCliVersion(),
|
|
2485
|
-
yes: rawOptions.yes,
|
|
2486
|
-
json: rawOptions.json,
|
|
2487
|
-
interactive: context.interactive && context.isTty && !context.isCi,
|
|
2488
|
-
prompt: context.prompt,
|
|
2489
|
-
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2490
|
-
scriptTimeoutMs: normalized.scriptTimeoutMs,
|
|
2491
|
-
}, context));
|
|
2492
|
-
if (rawOptions.json) {
|
|
2493
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('sync', result));
|
|
2494
|
-
}
|
|
2495
|
-
else {
|
|
2496
|
-
for (const line of renderRebuildReceipt('sync', result))
|
|
2497
|
-
writeLine(io.stdout, line);
|
|
2498
|
-
}
|
|
2499
|
-
writeWarnings(io.stderr, result.warnings, { actionableOnly: true });
|
|
2500
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(result);
|
|
2501
|
-
});
|
|
2502
|
-
program
|
|
2503
|
-
.command('install')
|
|
2504
|
-
.argument('[plugins...]')
|
|
2505
|
-
.option('-s, --scope <scope>', 'project or user')
|
|
2506
|
-
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
2507
|
-
.option('--dependency-scope <pluginId[#platform]=scope>', 'place one dependency at project or user scope; repeat for more dependencies', (value, previous) => [...previous, value], [])
|
|
2508
|
-
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2509
|
-
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2510
|
-
.option('-y, --yes', 'authorize preApply and shared Codex native replacement', false)
|
|
2511
|
-
.option('-j, --json', 'print receipt as JSON', false)
|
|
2512
|
-
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2513
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2514
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2515
|
-
.action(async (plugins, rawOptions) => {
|
|
2516
|
-
const context = createActionContext('install', rawOptions);
|
|
2517
|
-
const outcome = await runActionWithContext(context, () => runWriteCommandAction('install', plugins ?? [], rawOptions, context));
|
|
2518
|
-
if (outcome.cancelled)
|
|
2519
|
-
return;
|
|
2520
|
-
const receipt = outcome.result;
|
|
2521
|
-
if (rawOptions.json) {
|
|
2522
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('install', receipt));
|
|
2523
|
-
}
|
|
2524
|
-
else {
|
|
2525
|
-
for (const line of renderRebuildReceipt('install', receipt)) {
|
|
2526
|
-
writeLine(io.stdout, line);
|
|
2527
|
-
}
|
|
2528
|
-
}
|
|
2529
|
-
writeWarnings(io.stderr, receipt.warnings, { actionableOnly: true });
|
|
2530
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(receipt);
|
|
2531
|
-
});
|
|
2532
|
-
program
|
|
2533
|
-
.command('uninstall')
|
|
2534
|
-
.argument('[plugins...]')
|
|
2535
|
-
.option('-s, --scope <scope>', 'project or user')
|
|
2536
|
-
.option('-p, --platform <platform>', 'codex | claude | both')
|
|
2537
|
-
.option('--allow-managed-codex-install', 'allow this command to acquire or rebuild the pinned AW-managed Codex runtime', false)
|
|
2538
|
-
.option('-y, --yes', 'confirm changes to installed native tool declarations', false)
|
|
2539
|
-
.option('-j, --json', 'print receipt as JSON', false)
|
|
2002
|
+
const recoveryCommand = (command) => command
|
|
2003
|
+
.option('-j, --json', 'print one recovery receipt as JSON', false)
|
|
2540
2004
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2541
2005
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2542
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
.
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
.
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
.option('
|
|
2594
|
-
.option('--
|
|
2595
|
-
.option('--
|
|
2596
|
-
.
|
|
2597
|
-
.
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
const receipt = outcome.result;
|
|
2607
|
-
if (rawOptions.json) {
|
|
2608
|
-
writeJsonReceipt(io.stdout, buildRebuildReceiptJson('reinstall', receipt));
|
|
2609
|
-
}
|
|
2610
|
-
else {
|
|
2611
|
-
const lines = renderRebuildReceipt('reinstall', receipt);
|
|
2612
|
-
for (const line of lines) {
|
|
2613
|
-
writeLine(io.stdout, line);
|
|
2614
|
-
}
|
|
2615
|
-
}
|
|
2616
|
-
writeWarnings(io.stderr, receipt.warnings, { actionableOnly: true });
|
|
2617
|
-
commandExitState.exitCode = resolveCommandReceiptExitCode(receipt);
|
|
2618
|
-
});
|
|
2619
|
-
const config = program
|
|
2620
|
-
.command('config')
|
|
2621
|
-
.description('Manage AW plugin configuration');
|
|
2622
|
-
config
|
|
2623
|
-
.command('list')
|
|
2624
|
-
.argument('[plugin]')
|
|
2625
|
-
.option('-s, --scope <scope>', 'read only project or user config')
|
|
2626
|
-
.option('-j, --json', 'print config as JSON', false)
|
|
2627
|
-
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2628
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2629
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2630
|
-
.action(async (pluginName, rawOptions) => {
|
|
2631
|
-
const context = createActionContext('config:list', rawOptions);
|
|
2632
|
-
const outcome = await runActionWithContext(context, async () => {
|
|
2633
|
-
resolveConfigReadResolution(rawOptions.scope);
|
|
2634
|
-
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
2635
|
-
selector: selectedPlugin,
|
|
2636
|
-
rawOptions,
|
|
2637
|
-
context,
|
|
2638
|
-
});
|
|
2639
|
-
if (pluginName)
|
|
2640
|
-
return { cancelled: false, pluginName, value: await execute(pluginName) };
|
|
2641
|
-
if (!isWizardAvailable(context, rawOptions))
|
|
2642
|
-
throw new Error(configCommandUsage('list'));
|
|
2643
|
-
const currentCandidates = await loadWizardCandidates(context, {});
|
|
2644
|
-
const storedCandidates = await loadStoredConfigWizardCandidates(context, configReadStoreLocations(rawOptions));
|
|
2645
|
-
const candidates = mergeWizardCandidates(currentCandidates, storedCandidates);
|
|
2646
|
-
if (candidates.length === 0) {
|
|
2647
|
-
throw new Error('No plugin config candidates exist in the selected location.');
|
|
2648
|
-
}
|
|
2649
|
-
const result = await runCommandWizard(context, {
|
|
2650
|
-
command: 'config:list',
|
|
2651
|
-
candidates,
|
|
2652
|
-
initial: { plugins: [], scope: rawOptions.scope },
|
|
2653
|
-
pluginMode: 'single',
|
|
2654
|
-
...equivalentConfigCommandProjection((selection) => ({
|
|
2655
|
-
command: 'list',
|
|
2656
|
-
plugin: selection.plugins[0],
|
|
2657
|
-
scope: rawOptions.scope,
|
|
2658
|
-
})),
|
|
2659
|
-
execute: (selection) => execute(selection.plugins[0]),
|
|
2660
|
-
});
|
|
2661
|
-
return result.cancelled
|
|
2662
|
-
? { cancelled: true }
|
|
2663
|
-
: { cancelled: false, pluginName: result.selection.plugins[0], value: result.value };
|
|
2006
|
+
.option('--log-file <path>', 'write debug diagnostics to the specified file');
|
|
2007
|
+
const scopedCommand = (command) => recoveryCommand(command)
|
|
2008
|
+
.addOption(strictValueOption('--scope <scope>', 'requirement or physical scope', ['user', 'project']).makeOptionMandatory());
|
|
2009
|
+
const contextualCommand = (command) => recoveryCommand(command)
|
|
2010
|
+
.addOption(strictValueOption('--context <context>', 'user only, or user and current project', ['user', 'project']));
|
|
2011
|
+
const recoveryScope = (rawOptions) => normalizeWriteRequest(() => parseScopeValue(rawOptions.scope));
|
|
2012
|
+
const recoveryTargets = (rawOptions) => rawOptions.target === undefined
|
|
2013
|
+
? undefined : normalizeWriteRequest(() => normalizeAgents(typeof rawOptions.target === 'string' ? [rawOptions.target] : rawOptions.target));
|
|
2014
|
+
const recoveryContext = (rawOptions) => rawOptions.context === undefined
|
|
2015
|
+
? undefined : normalizeWriteRequest(() => parseContextValue(rawOptions.context));
|
|
2016
|
+
const runRecoveryAction = async (command, rawOptions, action) => {
|
|
2017
|
+
const context = createActionContext(command, rawOptions);
|
|
2018
|
+
const result = await runActionWithContext(context, () => action(context));
|
|
2019
|
+
if (rawOptions.json)
|
|
2020
|
+
writeJsonReceipt(io.stdout, result);
|
|
2021
|
+
else
|
|
2022
|
+
renderRecoveryReceipt(io.stdout, result);
|
|
2023
|
+
commandExitState.exitCode = result.ok ? 0
|
|
2024
|
+
: result.errors.some((error) => error.code === 'invalidArguments') ? 2 : 1;
|
|
2025
|
+
};
|
|
2026
|
+
const showWorkContext = async (context, rawOptions) => {
|
|
2027
|
+
if (rawOptions.scope === 'project' && rawOptions.context === 'user') {
|
|
2028
|
+
throw new WriteCommandRequestError('--scope project cannot be combined with --context user.');
|
|
2029
|
+
}
|
|
2030
|
+
const work = await resolveWorkContext({ cwd: context.cwd, context: recoveryContext(rawOptions),
|
|
2031
|
+
...(rawOptions.scope === undefined ? {} : { scope: recoveryScope(rawOptions) }) });
|
|
2032
|
+
if (!rawOptions.json)
|
|
2033
|
+
writeLine(io.stdout, work.projectRoot
|
|
2034
|
+
? `工作上下文:用户与当前项目 ${work.projectRoot}` : '工作上下文:仅用户');
|
|
2035
|
+
return work;
|
|
2036
|
+
};
|
|
2037
|
+
const intent = plugin.command('intent').description('Manage user or project plugin requirements');
|
|
2038
|
+
scopedCommand(intent.command('add').argument('<plugins...>'))
|
|
2039
|
+
.action(async (plugins, rawOptions) => runRecoveryAction('intent:add', rawOptions, (context) => intentAdd({ scope: recoveryScope(rawOptions), cwd: context.cwd, env: context.env, selectors: plugins })));
|
|
2040
|
+
scopedCommand(intent.command('remove').argument('<plugins...>'))
|
|
2041
|
+
.action(async (plugins, rawOptions) => runRecoveryAction('intent:remove', rawOptions, (context) => intentRemove({ scope: recoveryScope(rawOptions), cwd: context.cwd, env: context.env, selectors: plugins })));
|
|
2042
|
+
scopedCommand(intent.command('list'))
|
|
2043
|
+
.action(async (rawOptions) => runRecoveryAction('intent:list', rawOptions, (context) => intentList({ scope: recoveryScope(rawOptions), cwd: context.cwd, env: context.env })));
|
|
2044
|
+
scopedCommand(intent.command('retire').argument('<plugin>'))
|
|
2045
|
+
.description('Retire a plugin proven absent from its healthy Catalog')
|
|
2046
|
+
.option('--target <target>', 'limit output changes to a platform target', collectUniqueOption)
|
|
2047
|
+
.option('--delete-config', 'also delete saved user plugin configuration', false)
|
|
2048
|
+
.option('-y, --yes', 'confirm the reviewed retirement changes', false)
|
|
2049
|
+
.option('--allow-managed-codex-install', 'allow acquisition of the pinned AW-managed Codex runtime', false)
|
|
2050
|
+
.action(async (selector, rawOptions) => runRecoveryAction('intent:retire', rawOptions, (context) => runRetire({ scope: recoveryScope(rawOptions), cwd: context.cwd, env: context.env, selector,
|
|
2051
|
+
cliVersion: resolveCliVersion(), targets: recoveryTargets(rawOptions),
|
|
2052
|
+
deleteConfig: rawOptions.deleteConfig, yes: rawOptions.yes,
|
|
2053
|
+
interactive: isWizardAvailable(context, rawOptions), prompt: context.prompt,
|
|
2054
|
+
}, recoveryRuntime(context, rawOptions, true))));
|
|
2055
|
+
const targets = plugin.command('targets').description('Manage the local platform policy');
|
|
2056
|
+
contextualCommand(targets.command('set').argument('[targets...]'))
|
|
2057
|
+
.option('--none', 'save an empty target set', false)
|
|
2058
|
+
.option('--apply', 'apply the saved target policy in this work context', false)
|
|
2059
|
+
.option('-y, --yes', 'confirm reviewed output changes', false)
|
|
2060
|
+
.action(async (agents, rawOptions) => {
|
|
2061
|
+
if (rawOptions.none ? agents.length > 0 : agents.length === 0) {
|
|
2062
|
+
throw new WriteCommandRequestError('Use target IDs or --none, but not both.');
|
|
2063
|
+
}
|
|
2064
|
+
const normalized = normalizeWriteRequest(() => normalizeAgents(agents));
|
|
2065
|
+
await runRecoveryAction('targets:set', rawOptions, async (context) => {
|
|
2066
|
+
await showWorkContext(context, rawOptions);
|
|
2067
|
+
return targetsSet({ cwd: context.cwd, env: context.env, targets: normalized,
|
|
2068
|
+
context: recoveryContext(rawOptions), apply: rawOptions.apply, yes: rawOptions.yes,
|
|
2069
|
+
cliVersion: resolveCliVersion(), runtime: recoveryRuntime(context, rawOptions, true) });
|
|
2664
2070
|
});
|
|
2665
|
-
if (outcome.cancelled)
|
|
2666
|
-
return;
|
|
2667
|
-
const resolved = outcome.value;
|
|
2668
|
-
const selectedPluginName = resolved.pluginName;
|
|
2669
|
-
if (rawOptions.json) {
|
|
2670
|
-
writeJsonReceipt(io.stdout, {
|
|
2671
|
-
ok: true,
|
|
2672
|
-
configSchemaVersion: 4,
|
|
2673
|
-
command: 'config:list',
|
|
2674
|
-
plugin: selectedPluginName,
|
|
2675
|
-
pluginName: selectedPluginName,
|
|
2676
|
-
pluginId: resolved.pluginId,
|
|
2677
|
-
sourceId: resolved.sourceId,
|
|
2678
|
-
sourceIdentity: resolved.sourceIdentity,
|
|
2679
|
-
scope: rawOptions.scope ?? 'effective',
|
|
2680
|
-
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
2681
|
-
fields: resolved.result.fields,
|
|
2682
|
-
});
|
|
2683
|
-
}
|
|
2684
|
-
else {
|
|
2685
|
-
writeConfigReadHuman(io.stdout, resolved.result, resolved.pluginId);
|
|
2686
|
-
}
|
|
2687
2071
|
});
|
|
2688
|
-
|
|
2689
|
-
.
|
|
2690
|
-
|
|
2691
|
-
.argument('
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
const execute = async (selectedPlugin) => resolveMultiSourceConfigRead({
|
|
2702
|
-
selector: selectedPlugin,
|
|
2703
|
-
...(key === undefined ? {} : { key }),
|
|
2704
|
-
rawOptions,
|
|
2705
|
-
context,
|
|
2072
|
+
contextualCommand(targets.command('list'))
|
|
2073
|
+
.action(async (rawOptions) => runRecoveryAction('targets:list', rawOptions, (context) => targetsList({ cwd: context.cwd, env: context.env, context: recoveryContext(rawOptions) })));
|
|
2074
|
+
for (const action of ['exclude', 'include']) {
|
|
2075
|
+
contextualCommand(targets.command(action).argument('<plugin>'))
|
|
2076
|
+
.addOption(strictValueOption('--target <target>', 'one canonical platform target', PLATFORM_TARGETS).makeOptionMandatory())
|
|
2077
|
+
.option('--apply', 'apply the saved exclusion policy in this work context', false)
|
|
2078
|
+
.option('-y, --yes', 'confirm reviewed output changes', false)
|
|
2079
|
+
.action(async (selector, rawOptions) => {
|
|
2080
|
+
await runRecoveryAction(`targets:${action}`, rawOptions, async (context) => {
|
|
2081
|
+
await showWorkContext(context, rawOptions);
|
|
2082
|
+
return targetsChangeExclusion({ cwd: context.cwd, env: context.env, context: recoveryContext(rawOptions),
|
|
2083
|
+
selector, target: rawOptions.target, excluded: action === 'exclude', apply: rawOptions.apply,
|
|
2084
|
+
yes: rawOptions.yes, cliVersion: resolveCliVersion(), runtime: recoveryRuntime(context, rawOptions, true) });
|
|
2706
2085
|
});
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2086
|
+
});
|
|
2087
|
+
}
|
|
2088
|
+
for (const command of ['sync', 'install', 'remove', 'cleanup']) {
|
|
2089
|
+
const entry = command === 'cleanup'
|
|
2090
|
+
? scopedCommand(plugin.command(command).argument('[plugins...]'))
|
|
2091
|
+
: contextualCommand(plugin.command(command).argument(command === 'sync' ? '[plugins...]' : '<plugins...>'));
|
|
2092
|
+
entry.option('-y, --yes', 'authorize reviewed scripts or output changes', false)
|
|
2093
|
+
.option('--allow-managed-codex-install', 'allow acquisition of the pinned AW-managed Codex runtime', false);
|
|
2094
|
+
if (command === 'install' || command === 'remove')
|
|
2095
|
+
entry
|
|
2096
|
+
.addOption(strictValueOption('--scope <scope>', 'requirement document to edit', ['user', 'project']));
|
|
2097
|
+
if (command === 'remove')
|
|
2098
|
+
entry.option('--workspace-root <path>', 'delete plugin source from this explicit Catalog Workspace');
|
|
2099
|
+
if (command === 'sync')
|
|
2100
|
+
entry
|
|
2101
|
+
.option('--target <target>', 'limit execution to a canonical platform target', collectUniqueOption)
|
|
2102
|
+
.option('--rebuild', 'rebuild selected desired outputs', false)
|
|
2103
|
+
.option('--check', 'observe without preparing or writing', false)
|
|
2104
|
+
.option('--refresh', 'refresh required Catalog sources before review', false);
|
|
2105
|
+
if (command === 'cleanup')
|
|
2106
|
+
entry
|
|
2107
|
+
.addOption(strictValueOption('--target <target>', 'physical platform target to clean', PLATFORM_TARGETS).makeOptionMandatory())
|
|
2108
|
+
.option('--force', 'clean provably owned output despite damaged weak state', false);
|
|
2109
|
+
if (command === 'install' || command === 'sync')
|
|
2110
|
+
entry
|
|
2111
|
+
.option('--script-timeout <ms>', 'override plugin preApply timeout in milliseconds');
|
|
2112
|
+
entry.action(async (plugins, rawOptions) => {
|
|
2113
|
+
if (rawOptions.check && (rawOptions.refresh || rawOptions.rebuild)) {
|
|
2114
|
+
throw new WriteCommandRequestError('--check cannot be combined with --refresh or --rebuild.');
|
|
2716
2115
|
}
|
|
2717
|
-
|
|
2718
|
-
command
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2116
|
+
await runRecoveryAction(command, rawOptions, async (context) => {
|
|
2117
|
+
if (command !== 'cleanup')
|
|
2118
|
+
await showWorkContext(context, rawOptions);
|
|
2119
|
+
const targetValues = typeof rawOptions.target === 'string' ? [rawOptions.target] : rawOptions.target;
|
|
2120
|
+
const options = {
|
|
2121
|
+
...(rawOptions.scope === undefined ? {} : { scope: recoveryScope(rawOptions) }),
|
|
2122
|
+
context: recoveryContext(rawOptions), cwd: context.cwd, env: context.env, cliVersion: resolveCliVersion(),
|
|
2123
|
+
targets: targetValues === undefined ? undefined : normalizeWriteRequest(() => normalizeAgents(targetValues)),
|
|
2124
|
+
all: command === 'sync' && plugins.length === 0,
|
|
2125
|
+
yes: rawOptions.yes, force: rawOptions.force, refresh: rawOptions.refresh,
|
|
2126
|
+
allowManagedCodexInstall: rawOptions.allowManagedCodexInstall,
|
|
2127
|
+
scriptTimeoutMs: normalizeWriteRequest(() => resolveScriptTimeoutMs(rawOptions)),
|
|
2128
|
+
interactive: isWizardAvailable(context, rawOptions), prompt: context.prompt,
|
|
2129
|
+
};
|
|
2130
|
+
const backendCommand = command === 'remove' ? 'uninstall'
|
|
2131
|
+
: command === 'sync' && rawOptions.rebuild ? 'reinstall' : command;
|
|
2132
|
+
const result = rawOptions.check ? await checkRecovery(plugins, options)
|
|
2133
|
+
: await runRecovery(backendCommand, plugins, options, recoveryRuntime(context, rawOptions, true));
|
|
2134
|
+
return { ...result, command };
|
|
2729
2135
|
});
|
|
2730
|
-
return result.cancelled
|
|
2731
|
-
? { cancelled: true }
|
|
2732
|
-
: { cancelled: false, pluginName: result.selection.plugins[0], value: result.value };
|
|
2733
2136
|
});
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
ok: true,
|
|
2741
|
-
configSchemaVersion: 4,
|
|
2742
|
-
command: 'config:get',
|
|
2743
|
-
plugin: selectedPluginName,
|
|
2744
|
-
pluginName: selectedPluginName,
|
|
2745
|
-
pluginId: resolved.pluginId,
|
|
2746
|
-
sourceId: resolved.sourceId,
|
|
2747
|
-
sourceIdentity: resolved.sourceIdentity,
|
|
2748
|
-
key,
|
|
2749
|
-
scope: rawOptions.scope ?? 'effective',
|
|
2750
|
-
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
2751
|
-
fields: resolved.result.fields,
|
|
2752
|
-
});
|
|
2753
|
-
}
|
|
2754
|
-
else {
|
|
2755
|
-
writeConfigReadHuman(io.stdout, resolved.result, resolved.pluginId);
|
|
2756
|
-
}
|
|
2757
|
-
});
|
|
2758
|
-
config
|
|
2759
|
-
.command('set')
|
|
2760
|
-
.argument('[plugin]')
|
|
2761
|
-
.argument('[field]')
|
|
2762
|
-
.option('-s, --scope <scope>', 'project or user')
|
|
2763
|
-
.option('--value-json <json>', 'set the field to an exact JSON value')
|
|
2764
|
-
.option('--value-stdin', 'read the exact string value from stdin until EOF', false)
|
|
2765
|
-
.option('--preset <id>', 'set the field to the current manifest preset value')
|
|
2766
|
-
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2767
|
-
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2768
|
-
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
2769
|
-
.option('-j, --json', 'print receipt as JSON', false)
|
|
2137
|
+
}
|
|
2138
|
+
const config = plugin.command('config').description('Manage user common and platform configuration');
|
|
2139
|
+
const configCommand = (command) => command
|
|
2140
|
+
.addOption(strictValueOption('--platform <target>', 'configuration platform; omitted means common', PLATFORM_TARGETS))
|
|
2141
|
+
.addOption(strictValueOption('--context <context>', 'definition and reference context', ['user', 'project']))
|
|
2142
|
+
.option('-j, --json', 'print one JSON object', false)
|
|
2770
2143
|
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2771
2144
|
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2772
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2145
|
+
.option('--log-file <path>', 'write debug diagnostics to the specified file');
|
|
2146
|
+
const configMutation = (command) => configCommand(command)
|
|
2147
|
+
.option('--apply', 'refresh existing affected outputs after saving', false)
|
|
2148
|
+
.option('--script-timeout <ms>', 'override plugin preApply timeout in milliseconds')
|
|
2149
|
+
.option('-y, --yes', 'confirm reviewed output changes', false);
|
|
2150
|
+
const configContext = async (context, rawOptions, apply = rawOptions.apply === true) => {
|
|
2151
|
+
const requested = rawOptions.context === undefined ? apply ? undefined : 'user'
|
|
2152
|
+
: normalizeWriteRequest(() => parseContextValue(rawOptions.context));
|
|
2153
|
+
const work = await resolveWorkContext({ cwd: context.cwd, context: requested });
|
|
2154
|
+
if (apply && !rawOptions.json)
|
|
2155
|
+
writeLine(io.stdout, work.projectRoot
|
|
2156
|
+
? `工作上下文:用户与当前项目 ${work.projectRoot}` : '工作上下文:仅用户');
|
|
2157
|
+
return work;
|
|
2158
|
+
};
|
|
2159
|
+
const configPlatform = (rawOptions) => rawOptions.platform === undefined
|
|
2160
|
+
? undefined : normalizeWriteRequest(() => parsePlatformTargetValue(rawOptions.platform));
|
|
2161
|
+
for (const command of ['schema', 'list', 'get']) {
|
|
2162
|
+
const entry = configCommand(config.command(command).argument('<plugin>'));
|
|
2163
|
+
if (command === 'get')
|
|
2164
|
+
entry.argument('[key]');
|
|
2165
|
+
entry.action(async (...args) => {
|
|
2166
|
+
const selector = args[0];
|
|
2167
|
+
const key = command === 'get' ? args[1] : undefined;
|
|
2168
|
+
const rawOptions = args[command === 'get' ? 2 : 1];
|
|
2169
|
+
const context = createActionContext(`config:${command}`, rawOptions);
|
|
2170
|
+
const work = await configContext(context, rawOptions);
|
|
2171
|
+
const resolved = await runActionWithContext(context, () => resolveMultiSourceConfigRead({
|
|
2172
|
+
selector, key, rawOptions: { ...rawOptions, context: work.context }, context,
|
|
2173
|
+
}));
|
|
2174
|
+
if (rawOptions.json)
|
|
2175
|
+
writeJsonReceipt(io.stdout, {
|
|
2176
|
+
ok: true, configSchemaVersion: 5, command: `config:${command}`,
|
|
2177
|
+
plugin: resolved.pluginName, pluginName: resolved.pluginName, pluginId: resolved.pluginId,
|
|
2178
|
+
sourceId: resolved.sourceId, sourceIdentity: resolved.sourceIdentity,
|
|
2179
|
+
context: work, platform: configPlatform(rawOptions) ?? 'common',
|
|
2180
|
+
...(resolved.result.schema ? { schema: resolved.result.schema } : {}),
|
|
2181
|
+
fields: command === 'schema' ? resolved.result.fieldDefinitions ?? {} : resolved.result.fields,
|
|
2182
|
+
...(key === undefined ? {} : { key }),
|
|
2183
|
+
});
|
|
2184
|
+
else if (command === 'schema')
|
|
2185
|
+
writeJsonReceipt(io.stdout, resolved.result.fieldDefinitions ?? {});
|
|
2186
|
+
else
|
|
2187
|
+
writeConfigReadHuman(io.stdout, resolved.result, resolved.pluginId);
|
|
2188
|
+
});
|
|
2189
|
+
}
|
|
2190
|
+
for (const command of ['set', 'edit', 'unset']) {
|
|
2191
|
+
const entry = configMutation(config.command(command).argument('<plugin>'));
|
|
2192
|
+
if (command !== 'edit')
|
|
2193
|
+
entry.argument('<field>');
|
|
2194
|
+
if (command === 'set')
|
|
2195
|
+
entry
|
|
2196
|
+
.option('--value-json <json>', 'set an exact JSON value')
|
|
2197
|
+
.option('--value-stdin', 'read the exact string value until stdin EOF', false)
|
|
2198
|
+
.option('--preset <id>', 'use a declared preset');
|
|
2199
|
+
entry.action(async (...args) => {
|
|
2200
|
+
const selector = args[0];
|
|
2201
|
+
const rawOptions = args[command === 'edit' ? 1 : 2];
|
|
2202
|
+
let key = command === 'edit' ? undefined : args[1];
|
|
2203
|
+
const context = createActionContext(`config:${command}`, rawOptions);
|
|
2204
|
+
try {
|
|
2205
|
+
const work = await configContext(context, rawOptions);
|
|
2206
|
+
const platform = configPlatform(rawOptions);
|
|
2207
|
+
const scriptTimeoutMs = normalizeWriteRequest(() => resolveScriptTimeoutMs(rawOptions));
|
|
2208
|
+
if (command === 'edit' && (!isWizardAvailable(context, rawOptions) || !context.prompt.select || !context.prompt.input)) {
|
|
2209
|
+
throw new WriteCommandRequestError('config edit requires an interactive terminal. Use config set for scripts.');
|
|
2791
2210
|
}
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
error.code = 'sensitiveConfigInputUnsupported';
|
|
2809
|
-
throw error;
|
|
2211
|
+
const explicitValueCount = [rawOptions.valueJson !== undefined, rawOptions.valueStdin === true,
|
|
2212
|
+
rawOptions.preset !== undefined].filter(Boolean).length;
|
|
2213
|
+
if (command === 'set' && (explicitValueCount > 1 || explicitValueCount === 0
|
|
2214
|
+
&& !(context.interactive && context.isTty && !context.isCi && !rawOptions.json))) {
|
|
2215
|
+
throw new WriteCommandRequestError('Use exactly one of --value-json, --value-stdin, or --preset.');
|
|
2216
|
+
}
|
|
2217
|
+
const receipt = await runActionWithContext(context, () => withResolvedConfigMutationPlugin(context, selector, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2218
|
+
if (!plugin.manifest.config)
|
|
2219
|
+
throw Object.assign(new Error(`configSchemaUnavailable: Plugin "${plugin.manifest.name}" does not declare an AW config schema.`), { code: 'configSchemaUnavailable' });
|
|
2220
|
+
const fields = compilePluginConfigDefinition(plugin.manifest.config, platform).fields;
|
|
2221
|
+
if (command === 'edit') {
|
|
2222
|
+
const selected = await context.prompt.select({ message: `编辑用户${platform ?? 'common'}配置`,
|
|
2223
|
+
choices: Object.entries(fields).map(([value, field]) => ({ value, label: field.title ?? value })) });
|
|
2224
|
+
if (selected.cancelled || selected.action !== 'select' || selected.value === undefined)
|
|
2225
|
+
return undefined;
|
|
2226
|
+
key = selected.value;
|
|
2810
2227
|
}
|
|
2811
|
-
|
|
2812
|
-
|
|
2228
|
+
const field = fields[key];
|
|
2229
|
+
const store = await readPluginConfigStore({ sourceId: source.sourceId,
|
|
2230
|
+
sourceIdentity: source.sourceIdentity, logicalIdentity: source.logicalIdentity,
|
|
2231
|
+
pluginName: plugin.manifest.name, scope: 'user', platform, cwd: context.cwd, env: context.env,
|
|
2232
|
+
schema: fields });
|
|
2233
|
+
if (command === 'unset') {
|
|
2234
|
+
if (!Object.hasOwn(store.values, key))
|
|
2235
|
+
throw new WriteCommandRequestError(`Unknown config key "${key}" in the selected layer.`);
|
|
2813
2236
|
}
|
|
2237
|
+
else if (!field)
|
|
2238
|
+
throw new WriteCommandRequestError(`Unknown config key "${key}".`);
|
|
2814
2239
|
let inputValue;
|
|
2815
|
-
if (
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
if (!(context.interactive && context.isTty && !context.isCi && rawOptions.json !== true)
|
|
2820
|
-
|| !context.prompt.password) {
|
|
2821
|
-
const error = new Error('sensitiveConfigStdinRequired: Use --value-stdin for sensitive config outside an interactive terminal.');
|
|
2822
|
-
error.code = 'sensitiveConfigStdinRequired';
|
|
2823
|
-
throw error;
|
|
2240
|
+
if (command !== 'unset') {
|
|
2241
|
+
const sensitive = field.sensitive === true;
|
|
2242
|
+
if (sensitive && (rawOptions.valueJson !== undefined || rawOptions.preset !== undefined)) {
|
|
2243
|
+
throw new Error('sensitiveConfigInputUnsupported: Sensitive config requires --value-stdin.');
|
|
2824
2244
|
}
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2245
|
+
if (rawOptions.valueStdin)
|
|
2246
|
+
inputValue = await readUtf8Stdin(context.stdin);
|
|
2247
|
+
else if (sensitive) {
|
|
2248
|
+
if (!context.interactive || !context.isTty || context.isCi || rawOptions.json || !context.prompt.password) {
|
|
2249
|
+
throw new Error('sensitiveConfigStdinRequired: Use --value-stdin outside an interactive terminal.');
|
|
2250
|
+
}
|
|
2251
|
+
const response = await context.prompt.password({ message: `输入 ${field.title ?? key}`, mask: true });
|
|
2252
|
+
if (response.cancelled || response.action !== 'select' || response.value === undefined)
|
|
2253
|
+
return undefined;
|
|
2254
|
+
inputValue = response.value;
|
|
2833
2255
|
}
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2256
|
+
else if (command === 'edit' || explicitValueCount === 0) {
|
|
2257
|
+
if (!context.prompt.input)
|
|
2258
|
+
throw new WriteCommandRequestError('Use --value-json, --value-stdin, or --preset.');
|
|
2259
|
+
const response = await context.prompt.input({ message: `输入 ${field.title ?? key} 的 JSON 值`,
|
|
2260
|
+
defaultValue: JSON.stringify(store.values[key]) });
|
|
2261
|
+
if (response.cancelled || response.action !== 'select' || response.value === undefined)
|
|
2262
|
+
return undefined;
|
|
2263
|
+
try {
|
|
2264
|
+
inputValue = JSON.parse(response.value);
|
|
2265
|
+
}
|
|
2266
|
+
catch {
|
|
2267
|
+
throw new WriteCommandRequestError('Enter a valid JSON value.');
|
|
2268
|
+
}
|
|
2839
2269
|
}
|
|
2840
|
-
|
|
2841
|
-
|
|
2270
|
+
else if (rawOptions.valueJson !== undefined) {
|
|
2271
|
+
try {
|
|
2272
|
+
inputValue = JSON.parse(rawOptions.valueJson);
|
|
2273
|
+
}
|
|
2274
|
+
catch {
|
|
2275
|
+
throw new WriteCommandRequestError('--value-json must contain valid JSON.');
|
|
2276
|
+
}
|
|
2277
|
+
}
|
|
2278
|
+
else {
|
|
2279
|
+
const preset = field.choices?.presets.find((candidate) => candidate.id === rawOptions.preset);
|
|
2280
|
+
if (!preset)
|
|
2281
|
+
throw new WriteCommandRequestError(`Unknown preset "${rawOptions.preset}".`);
|
|
2282
|
+
inputValue = structuredClone(preset.value);
|
|
2842
2283
|
}
|
|
2843
2284
|
}
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
inputValue = structuredClone(preset.value);
|
|
2849
|
-
}
|
|
2850
|
-
const writeReceipt = await applyPluginConfigWrite({
|
|
2851
|
-
plugin,
|
|
2852
|
-
pluginName: plugin.manifest.name,
|
|
2853
|
-
scope,
|
|
2854
|
-
cwd: context.cwd,
|
|
2855
|
-
env: context.env,
|
|
2856
|
-
nativeCliRunner: context.nativeCliRunner,
|
|
2857
|
-
rebuildRuntime: {
|
|
2858
|
-
...context,
|
|
2859
|
-
awHomeMutationToken,
|
|
2860
|
-
catalogOperationContext,
|
|
2285
|
+
const writeReceipt = await applyPluginConfigWrite({ plugin, pluginName: plugin.manifest.name,
|
|
2286
|
+
scope: work.context, context: work.context, platform, cliVersion: resolveCliVersion(),
|
|
2287
|
+
cwd: context.cwd, env: context.env, nativeCliRunner: context.nativeCliRunner,
|
|
2288
|
+
rebuildRuntime: { ...context, awHomeMutationToken, catalogOperationContext,
|
|
2861
2289
|
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
2862
|
-
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
2863
|
-
},
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
...writeReceipt,
|
|
2875
|
-
plugin: plugin.manifest.name,
|
|
2876
|
-
pluginName: plugin.manifest.name,
|
|
2877
|
-
pluginId,
|
|
2878
|
-
sourceId: source.sourceId,
|
|
2879
|
-
sourceIdentity: source.sourceIdentity,
|
|
2880
|
-
affectedFields: [{
|
|
2881
|
-
key,
|
|
2882
|
-
title: field.title ?? key,
|
|
2883
|
-
kind: 'manifest',
|
|
2884
|
-
reserved: false,
|
|
2885
|
-
action: 'set',
|
|
2886
|
-
scope,
|
|
2887
|
-
}],
|
|
2290
|
+
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }) },
|
|
2291
|
+
awHomeMutationToken, request: command === 'unset' ? { removeKeys: [key] } : { updates: { [key]: inputValue } },
|
|
2292
|
+
apply: rawOptions.apply === true, sharedNativeApplyConfirmed: rawOptions.yes === true,
|
|
2293
|
+
preApplyConfirmed: rawOptions.yes === true });
|
|
2294
|
+
return buildConfigMutationReceipt(`config:${command}`, {
|
|
2295
|
+
...writeReceipt, ok: writeReceipt.overallState === 'succeeded', plugin: plugin.manifest.name,
|
|
2296
|
+
pluginName: plugin.manifest.name, pluginId, sourceId: source.sourceId, sourceIdentity: source.sourceIdentity,
|
|
2297
|
+
context: work, platform: platform ?? 'common',
|
|
2298
|
+
...(command === 'unset' ? { removedKey: key, existed: true } : {}),
|
|
2299
|
+
affectedFields: [{ key: key, title: field?.title ?? key, kind: 'manifest', reserved: false,
|
|
2300
|
+
action: command === 'unset' ? 'unset' : 'set', scope: 'user',
|
|
2301
|
+
...(writeReceipt.staleRemovedKeys?.includes(key) ? { stale: true } : {}) }],
|
|
2888
2302
|
});
|
|
2889
|
-
}, rawOptions.apply === true);
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
if (rawOptions.json) {
|
|
2898
|
-
writeJsonReceipt(io.stdout, receipt);
|
|
2899
|
-
}
|
|
2900
|
-
else {
|
|
2901
|
-
writeLine(io.stdout, `已写入 ${receipt.plugin}.${key}(${configLayerLabel(receipt.scope)}配置)。`);
|
|
2902
|
-
writeConfigApplyNotice(io.stderr, receipt);
|
|
2903
|
-
}
|
|
2904
|
-
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2905
|
-
});
|
|
2906
|
-
config
|
|
2907
|
-
.command('unset')
|
|
2908
|
-
.argument('[plugin]')
|
|
2909
|
-
.argument('[key]')
|
|
2910
|
-
.option('-s, --scope <scope>', 'project or user')
|
|
2911
|
-
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
2912
|
-
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
2913
|
-
.option('-y, --yes', 'confirm preApply and shared Codex native config apply', false)
|
|
2914
|
-
.option('-j, --json', 'print receipt as JSON', false)
|
|
2915
|
-
.option('-v, --verbose', 'show command diagnostics', false)
|
|
2916
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
2917
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
2918
|
-
.action(async (pluginName, key, rawOptions) => {
|
|
2919
|
-
const context = createActionContext('config:unset', rawOptions);
|
|
2920
|
-
let outcome;
|
|
2921
|
-
try {
|
|
2922
|
-
outcome = await runActionWithContext(context, async () => {
|
|
2923
|
-
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
2924
|
-
const scriptTimeoutMs = resolveScriptTimeoutMs(rawOptions);
|
|
2925
|
-
const execute = async (selectedPlugin, selectedKey, confirmed) => withResolvedConfigMutationPlugin(context, selectedPlugin, async ({ pluginId, source, plugin }, awHomeMutationToken, catalogOperationContext) => {
|
|
2926
|
-
const store = await readPluginConfigStore({
|
|
2927
|
-
sourceId: source.sourceId,
|
|
2928
|
-
sourceIdentity: source.sourceIdentity,
|
|
2929
|
-
logicalIdentity: source.logicalIdentity,
|
|
2930
|
-
pluginName: plugin.manifest.name,
|
|
2931
|
-
scope,
|
|
2932
|
-
cwd: context.cwd,
|
|
2933
|
-
env: context.env,
|
|
2934
|
-
schema: plugin.manifest.config?.fields,
|
|
2935
|
-
});
|
|
2936
|
-
const existed = Object.hasOwn(store.values, selectedKey);
|
|
2937
|
-
if (!existed)
|
|
2938
|
-
throw new Error(`Unknown config key "${selectedKey}".`);
|
|
2939
|
-
const writeReceipt = await applyPluginConfigWrite({
|
|
2940
|
-
plugin,
|
|
2941
|
-
pluginName: plugin.manifest.name,
|
|
2942
|
-
scope,
|
|
2943
|
-
cwd: context.cwd,
|
|
2944
|
-
env: context.env,
|
|
2945
|
-
nativeCliRunner: context.nativeCliRunner,
|
|
2946
|
-
rebuildRuntime: {
|
|
2947
|
-
...context,
|
|
2948
|
-
awHomeMutationToken,
|
|
2949
|
-
catalogOperationContext,
|
|
2950
|
-
expectedGenerationSetDigest: catalogOperationContext.generationSetDigest,
|
|
2951
|
-
...(scriptTimeoutMs === undefined ? {} : { scriptTimeoutMs }),
|
|
2952
|
-
},
|
|
2953
|
-
awHomeMutationToken,
|
|
2954
|
-
request: {
|
|
2955
|
-
removeKeys: [selectedKey],
|
|
2956
|
-
},
|
|
2957
|
-
apply: rawOptions.apply === true,
|
|
2958
|
-
sharedNativeApplyConfirmed: confirmed,
|
|
2959
|
-
preApplyConfirmed: rawOptions.yes === true,
|
|
2960
|
-
});
|
|
2961
|
-
return buildConfigMutationReceipt('config:unset', {
|
|
2962
|
-
ok: writeReceipt.overallState === 'succeeded',
|
|
2963
|
-
...writeReceipt,
|
|
2964
|
-
plugin: plugin.manifest.name,
|
|
2965
|
-
pluginName: plugin.manifest.name,
|
|
2966
|
-
pluginId,
|
|
2967
|
-
sourceId: source.sourceId,
|
|
2968
|
-
sourceIdentity: source.sourceIdentity,
|
|
2969
|
-
removedKey: selectedKey,
|
|
2970
|
-
existed,
|
|
2971
|
-
affectedFields: [{
|
|
2972
|
-
key: selectedKey,
|
|
2973
|
-
title: plugin?.manifest.config?.fields?.[selectedKey]?.title ?? selectedKey,
|
|
2974
|
-
kind: 'manifest',
|
|
2975
|
-
reserved: false,
|
|
2976
|
-
action: 'unset',
|
|
2977
|
-
scope,
|
|
2978
|
-
...(!plugin.manifest.config?.fields?.[selectedKey] ? { stale: true } : {}),
|
|
2979
|
-
}],
|
|
2980
|
-
});
|
|
2981
|
-
}, rawOptions.apply === true);
|
|
2982
|
-
if (pluginName && key) {
|
|
2983
|
-
return {
|
|
2984
|
-
cancelled: false,
|
|
2985
|
-
value: await execute(pluginName, key, rawOptions.yes === true),
|
|
2986
|
-
};
|
|
2987
|
-
}
|
|
2988
|
-
if (!isWizardAvailable(context, rawOptions))
|
|
2989
|
-
throw new Error(configCommandUsage('unset'));
|
|
2990
|
-
const loadedCurrentCandidates = await loadWizardCandidates(context, {});
|
|
2991
|
-
const currentCandidates = loadedCurrentCandidates.filter(hasConfigSchemaKeys);
|
|
2992
|
-
const candidates = currentCandidates;
|
|
2993
|
-
if (pluginName && !candidates.some((entry) => entry.pluginName === pluginName)) {
|
|
2994
|
-
throw new Error(`Unknown plugin "${pluginName}".`);
|
|
2303
|
+
}, rawOptions.apply === true));
|
|
2304
|
+
if (!receipt)
|
|
2305
|
+
return;
|
|
2306
|
+
if (rawOptions.json)
|
|
2307
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2308
|
+
else {
|
|
2309
|
+
writeLine(io.stdout, `已保存 ${receipt.plugin}.${key}(用户 ${platform ?? 'common'} 配置)。`);
|
|
2310
|
+
writeConfigApplyNotice(io.stderr, receipt);
|
|
2995
2311
|
}
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
destructive: true,
|
|
3006
|
-
...equivalentConfigCommandProjection((selection) => ({
|
|
3007
|
-
command: 'unset',
|
|
3008
|
-
plugin: selection.plugins[0],
|
|
3009
|
-
key: selection.key,
|
|
3010
|
-
scope: selection.scope ?? 'user',
|
|
3011
|
-
})),
|
|
3012
|
-
resultState: overallResultState,
|
|
3013
|
-
execute: (selection) => execute(selection.plugins[0], selection.key, true),
|
|
3014
|
-
});
|
|
3015
|
-
return result.cancelled
|
|
3016
|
-
? { cancelled: true }
|
|
3017
|
-
: { cancelled: false, value: result.value };
|
|
3018
|
-
});
|
|
3019
|
-
}
|
|
3020
|
-
catch (error) {
|
|
3021
|
-
writeConfigMutationFailure('config:unset', pluginName, rawOptions.json === true, error);
|
|
3022
|
-
return;
|
|
3023
|
-
}
|
|
3024
|
-
if (outcome.cancelled)
|
|
3025
|
-
return;
|
|
3026
|
-
const receipt = outcome.value;
|
|
3027
|
-
if (rawOptions.json) {
|
|
3028
|
-
writeJsonReceipt(io.stdout, receipt);
|
|
3029
|
-
}
|
|
3030
|
-
else {
|
|
3031
|
-
writeLine(io.stdout, receipt.existed
|
|
3032
|
-
? `已删除 ${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)。`
|
|
3033
|
-
: `${receipt.plugin}.${receipt.removedKey}(${configLayerLabel(receipt.scope)}配置)原本不存在。`);
|
|
3034
|
-
writeConfigApplyNotice(io.stderr, receipt);
|
|
3035
|
-
}
|
|
3036
|
-
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
3037
|
-
});
|
|
3038
|
-
config
|
|
3039
|
-
.command('reset')
|
|
3040
|
-
.argument('[plugin]')
|
|
3041
|
-
.option('-s, --scope <scope>', 'project or user')
|
|
3042
|
-
.option('--apply', 'apply the saved config to visible desired placements', false)
|
|
3043
|
-
.option('--script-timeout <ms>', 'override plugin preApply script timeout in milliseconds')
|
|
3044
|
-
.option('-y, --yes', 'confirm destructive reset and preApply/shared Codex native config apply', false)
|
|
3045
|
-
.option('-j, --json', 'print receipt as JSON', false)
|
|
3046
|
-
.option('-v, --verbose', 'show command diagnostics', false)
|
|
3047
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
3048
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
3049
|
-
.action(async (pluginName, rawOptions) => {
|
|
2312
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
2313
|
+
}
|
|
2314
|
+
catch (error) {
|
|
2315
|
+
writeConfigMutationFailure(`config:${command}`, selector, rawOptions.json === true, error);
|
|
2316
|
+
}
|
|
2317
|
+
});
|
|
2318
|
+
}
|
|
2319
|
+
configMutation(config.command('reset').argument('<plugin>'))
|
|
2320
|
+
.action(async (selector, rawOptions) => {
|
|
3050
2321
|
const context = createActionContext('config:reset', rawOptions);
|
|
3051
|
-
let outcome;
|
|
3052
2322
|
try {
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
cwd: context.cwd,
|
|
3074
|
-
env: context.env,
|
|
3075
|
-
}).catch(() => []);
|
|
3076
|
-
const resetReceipt = await resetPluginConfigWithHelper({
|
|
3077
|
-
sourceId: located.sourceId,
|
|
3078
|
-
sourceIdentity: located.sourceIdentity,
|
|
3079
|
-
logicalIdentity: located.logicalIdentity,
|
|
3080
|
-
pluginName: located.pluginName,
|
|
3081
|
-
scope: selectedScope,
|
|
3082
|
-
cwd: context.cwd,
|
|
3083
|
-
env: context.env,
|
|
3084
|
-
nativeCliRunner: context.nativeCliRunner,
|
|
3085
|
-
plugin,
|
|
3086
|
-
pluginError,
|
|
3087
|
-
apply: rawOptions.apply === true,
|
|
3088
|
-
rebuildRuntime: scriptTimeoutMs === undefined ? undefined : { scriptTimeoutMs },
|
|
3089
|
-
sharedNativeApplyConfirmed: confirmed,
|
|
3090
|
-
preApplyConfirmed: rawOptions.yes === true,
|
|
3091
|
-
});
|
|
3092
|
-
return buildConfigMutationReceipt('config:reset', {
|
|
3093
|
-
ok: resetReceipt.overallState === 'succeeded',
|
|
3094
|
-
...resetReceipt,
|
|
3095
|
-
plugin: located.pluginName,
|
|
3096
|
-
pluginName: located.pluginName,
|
|
3097
|
-
pluginId: located.pluginId,
|
|
3098
|
-
sourceId: located.sourceId,
|
|
3099
|
-
...(located.sourceIdentity ? { sourceIdentity: located.sourceIdentity } : {}),
|
|
3100
|
-
affectedFields,
|
|
3101
|
-
});
|
|
3102
|
-
};
|
|
3103
|
-
let resetStarted = false;
|
|
3104
|
-
try {
|
|
3105
|
-
return await withResolvedCatalogPlugin({
|
|
3106
|
-
selector: located.pluginId,
|
|
3107
|
-
cliVersion: resolveCliVersion(),
|
|
3108
|
-
env: context.env,
|
|
3109
|
-
consume: async ({ plugin }) => {
|
|
3110
|
-
resetStarted = true;
|
|
3111
|
-
return resetLocatedStore(plugin, null);
|
|
3112
|
-
},
|
|
3113
|
-
});
|
|
3114
|
-
}
|
|
3115
|
-
catch (error) {
|
|
3116
|
-
if (resetStarted)
|
|
3117
|
-
throw error;
|
|
3118
|
-
return resetLocatedStore(null, error instanceof Error ? error : new Error(String(error)));
|
|
3119
|
-
}
|
|
3120
|
-
};
|
|
3121
|
-
const scope = resolveConfigWriteScope(rawOptions.scope);
|
|
3122
|
-
const needsWizard = pluginName === undefined || rawOptions.yes !== true;
|
|
3123
|
-
if (!needsWizard) {
|
|
3124
|
-
return {
|
|
3125
|
-
cancelled: false,
|
|
3126
|
-
value: await execute(pluginName, scope, true),
|
|
3127
|
-
};
|
|
3128
|
-
}
|
|
3129
|
-
if (!isWizardAvailable(context, rawOptions)) {
|
|
3130
|
-
if (!pluginName)
|
|
3131
|
-
throw new Error(configCommandUsage('reset'));
|
|
3132
|
-
return {
|
|
3133
|
-
cancelled: false,
|
|
3134
|
-
value: await execute(pluginName, scope, false),
|
|
3135
|
-
};
|
|
3136
|
-
}
|
|
3137
|
-
const currentCandidates = pluginName ? [] : await loadWizardCandidates(context, {});
|
|
3138
|
-
const candidatesByScope = new Map();
|
|
3139
|
-
if (!pluginName && (rawOptions.scope === undefined || scope === 'user')) {
|
|
3140
|
-
candidatesByScope.set('user', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'user' }], { includeEmptyStores: true })));
|
|
3141
|
-
}
|
|
3142
|
-
if (!pluginName && (rawOptions.scope === undefined || scope === 'project')) {
|
|
3143
|
-
candidatesByScope.set('project', mergeWizardCandidates(currentCandidates, await loadStoredConfigWizardCandidates(context, [{ scope: 'project' }], { includeEmptyStores: true })));
|
|
2323
|
+
const work = await configContext(context, rawOptions);
|
|
2324
|
+
const platform = configPlatform(rawOptions);
|
|
2325
|
+
if (!rawOptions.yes) {
|
|
2326
|
+
if (!isWizardAvailable(context, rawOptions) || !context.prompt.confirm)
|
|
2327
|
+
throw new WriteCommandRequestError('config reset requires --yes.');
|
|
2328
|
+
const confirmed = await context.prompt.confirm({ message: `删除 ${selector} 的用户 ${platform ?? 'common'} 覆盖?`, defaultValue: false });
|
|
2329
|
+
if (confirmed.cancelled || confirmed.value !== true)
|
|
2330
|
+
return;
|
|
2331
|
+
}
|
|
2332
|
+
const located = await resolveStoredConfigResetIdentity({ selector, context, scope: 'user' });
|
|
2333
|
+
const resetStore = async (plugin, pluginError) => resetPluginConfigWithHelper({ ...located, plugin, pluginError, platform, scope: work.context,
|
|
2334
|
+
context: work.context, cliVersion: resolveCliVersion(), cwd: context.cwd, env: context.env,
|
|
2335
|
+
nativeCliRunner: context.nativeCliRunner, apply: rawOptions.apply === true,
|
|
2336
|
+
rebuildRuntime: { ...context, scriptTimeoutMs: resolveScriptTimeoutMs(rawOptions) },
|
|
2337
|
+
sharedNativeApplyConfirmed: true, preApplyConfirmed: rawOptions.yes === true });
|
|
2338
|
+
let started = false;
|
|
2339
|
+
const resetReceipt = await runActionWithContext(context, async () => {
|
|
2340
|
+
try {
|
|
2341
|
+
return await withResolvedCatalogPlugin({ selector: located.pluginId, cliVersion: resolveCliVersion(), env: context.env,
|
|
2342
|
+
consume: ({ plugin }) => { started = true; return resetStore(plugin, null); } });
|
|
3144
2343
|
}
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
2344
|
+
catch (error) {
|
|
2345
|
+
if (started)
|
|
2346
|
+
throw error;
|
|
2347
|
+
return resetStore(null, error instanceof Error ? error : new Error(String(error)));
|
|
3148
2348
|
}
|
|
3149
|
-
const result = await runCommandWizard(context, {
|
|
3150
|
-
command: 'config:reset',
|
|
3151
|
-
candidates,
|
|
3152
|
-
initial: { plugins: pluginName ? [pluginName] : [], scope },
|
|
3153
|
-
pluginMode: pluginName ? 'none' : 'single',
|
|
3154
|
-
promptForScope: rawOptions.scope === undefined,
|
|
3155
|
-
destructive: true,
|
|
3156
|
-
isPluginVisible: (candidate, selection) => candidatesByScope
|
|
3157
|
-
.get(selection.scope ?? 'user')
|
|
3158
|
-
?.some((entry) => entry.pluginName === candidate.pluginName) !== false,
|
|
3159
|
-
...equivalentConfigCommandProjection((selection) => ({
|
|
3160
|
-
command: 'reset',
|
|
3161
|
-
plugin: selection.plugins[0],
|
|
3162
|
-
scope: selection.scope ?? 'user',
|
|
3163
|
-
confirmed: true,
|
|
3164
|
-
})),
|
|
3165
|
-
resultState: overallResultState,
|
|
3166
|
-
execute: (selection) => execute(selection.plugins[0], selection.scope ?? 'user', true),
|
|
3167
|
-
});
|
|
3168
|
-
return result.cancelled
|
|
3169
|
-
? { cancelled: true }
|
|
3170
|
-
: { cancelled: false, value: result.value };
|
|
3171
2349
|
});
|
|
2350
|
+
const receipt = buildConfigMutationReceipt('config:reset', { ...resetReceipt,
|
|
2351
|
+
ok: resetReceipt.overallState === 'succeeded', ...located, plugin: located.pluginName,
|
|
2352
|
+
context: work, platform: platform ?? 'common' });
|
|
2353
|
+
if (rawOptions.json)
|
|
2354
|
+
writeJsonReceipt(io.stdout, receipt);
|
|
2355
|
+
else {
|
|
2356
|
+
writeLine(io.stdout, `已恢复 ${receipt.plugin} 的用户 ${platform ?? 'common'} 默认配置。`);
|
|
2357
|
+
writeConfigApplyNotice(io.stderr, receipt);
|
|
2358
|
+
}
|
|
2359
|
+
commandExitState.exitCode = receipt.overallState === 'succeeded' ? 0 : 1;
|
|
3172
2360
|
}
|
|
3173
2361
|
catch (error) {
|
|
3174
|
-
writeConfigMutationFailure('config:reset',
|
|
3175
|
-
return;
|
|
3176
|
-
}
|
|
3177
|
-
if (outcome.cancelled)
|
|
3178
|
-
return;
|
|
3179
|
-
const receipt = outcome.value;
|
|
3180
|
-
if (rawOptions.json) {
|
|
3181
|
-
writeJsonReceipt(io.stdout, receipt);
|
|
2362
|
+
writeConfigMutationFailure('config:reset', selector, rawOptions.json === true, error);
|
|
3182
2363
|
}
|
|
2364
|
+
});
|
|
2365
|
+
contextualCommand(config.command('apply').argument('<plugin>'))
|
|
2366
|
+
.option('--target <target>', 'limit existing-output refresh to this platform target', collectUniqueOption)
|
|
2367
|
+
.option('-y, --yes', 'confirm reviewed output changes', false)
|
|
2368
|
+
.option('--script-timeout <ms>', 'override plugin preApply timeout in milliseconds')
|
|
2369
|
+
.action(async (selector, rawOptions) => {
|
|
2370
|
+
const context = createActionContext('config:apply', rawOptions);
|
|
2371
|
+
const work = await configContext(context, rawOptions, true);
|
|
2372
|
+
const targets = rawOptions.target?.map((target) => normalizeWriteRequest(() => parsePlatformTargetValue(target)));
|
|
2373
|
+
const receipt = await runActionWithContext(context, () => withResolvedConfigMutationPlugin(context, selector, async ({ plugin, pluginId, source }, awHomeMutationToken) => ({
|
|
2374
|
+
...await applyPluginConfig({ plugin, scope: work.context, context: work.context, targets,
|
|
2375
|
+
cliVersion: resolveCliVersion(), cwd: context.cwd, env: context.env, awHomeMutationToken,
|
|
2376
|
+
nativeCliRunner: context.nativeCliRunner, sharedNativeApplyConfirmed: rawOptions.yes === true,
|
|
2377
|
+
preApplyConfirmed: rawOptions.yes === true, rebuildRuntime: { ...context, scriptTimeoutMs: resolveScriptTimeoutMs(rawOptions) } }),
|
|
2378
|
+
command: 'config:apply', plugin: plugin.manifest.name, pluginId, sourceId: source.sourceId,
|
|
2379
|
+
context: work,
|
|
2380
|
+
}), true));
|
|
2381
|
+
const result = buildConfigMutationReceipt('config:apply', { ...receipt,
|
|
2382
|
+
ok: receipt.overallState === 'succeeded' });
|
|
2383
|
+
if (rawOptions.json)
|
|
2384
|
+
writeJsonReceipt(io.stdout, result);
|
|
3183
2385
|
else {
|
|
3184
|
-
writeLine(io.stdout,
|
|
3185
|
-
|
|
3186
|
-
: `${receipt.plugin} 没有可重置的${configLayerLabel(receipt.scope)}配置。`);
|
|
3187
|
-
writeConfigApplyNotice(io.stderr, receipt);
|
|
2386
|
+
writeLine(io.stdout, `配置应用:${result.ok ? '完成' : '部分失败'}。`);
|
|
2387
|
+
writeConfigApplyNotice(io.stderr, { ...result, warnings: [] });
|
|
3188
2388
|
}
|
|
3189
|
-
commandExitState.exitCode =
|
|
2389
|
+
commandExitState.exitCode = result.ok ? 0 : 1;
|
|
3190
2390
|
});
|
|
3191
|
-
|
|
3192
|
-
.
|
|
3193
|
-
.
|
|
3194
|
-
.option('-s, --scope <scope>', 'filter by scope')
|
|
3195
|
-
.option('-p, --platform <platform>', 'filter by platform')
|
|
3196
|
-
.option('-v, --verbose', 'show status details and command diagnostics', false)
|
|
3197
|
-
.option('-D, --debug', 'write debug diagnostics to a log file', false)
|
|
3198
|
-
.option('--log-file <path>', 'write debug diagnostics to the specified file')
|
|
3199
|
-
.option('-j, --json', 'print status as JSON', false)
|
|
3200
|
-
.action(async (plugins, rawOptions) => {
|
|
2391
|
+
contextualCommand(plugin.command('status'))
|
|
2392
|
+
.description('Observe user and current project demand and output state')
|
|
2393
|
+
.action(async (rawOptions) => {
|
|
3201
2394
|
const context = createActionContext('status', rawOptions);
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
cwd,
|
|
3205
|
-
|
|
3206
|
-
cliVersion: resolveCliVersion(),
|
|
3207
|
-
platform: rawOptions.platform,
|
|
3208
|
-
scope: rawOptions.scope,
|
|
3209
|
-
json: rawOptions.json,
|
|
3210
|
-
verbose: rawOptions.verbose,
|
|
2395
|
+
await showWorkContext(context, rawOptions);
|
|
2396
|
+
const result = await runActionWithContext(context, () => readRecoveryStatus({
|
|
2397
|
+
context: recoveryContext(rawOptions), cwd: context.cwd, env: context.env, cliVersion: resolveCliVersion(),
|
|
2398
|
+
nativeCliRunner: context.nativeCliRunner,
|
|
3211
2399
|
}));
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
}
|
|
3218
|
-
for (const error of result.payload.errors) {
|
|
3219
|
-
if (rawOptions.json && error.code !== 'nativeStateUnreadable' && error.code !== 'stateInventoryFailed') {
|
|
3220
|
-
writeLine(io.stderr, error.message);
|
|
3221
|
-
}
|
|
3222
|
-
}
|
|
2400
|
+
if (rawOptions.json)
|
|
2401
|
+
writeJsonReceipt(io.stdout, result);
|
|
2402
|
+
else
|
|
2403
|
+
renderRecoveryStatus(io.stdout, result);
|
|
2404
|
+
commandExitState.exitCode = result.errors.length ? 1 : 0;
|
|
3223
2405
|
});
|
|
3224
2406
|
Object.assign(program, { __awCommandExitState: commandExitState });
|
|
3225
2407
|
return program;
|
|
@@ -3251,9 +2433,16 @@ export async function runCli(argv, options = {}) {
|
|
|
3251
2433
|
? argv[1]
|
|
3252
2434
|
: null;
|
|
3253
2435
|
const jsonReviewCommand = reviewCommand !== null && argv.includes('--json');
|
|
2436
|
+
const jsonMaterialize = argv[0] === 'skill' && argv[1] === 'materialize'
|
|
2437
|
+
&& (argv.includes('--json') || argv.includes('-j'));
|
|
2438
|
+
const jsonConfigCommand = jsonConfigReadRequested(argv);
|
|
2439
|
+
const explicitWorkspace = argv.some((token) => token === '--workspace-root' || token.startsWith('--workspace-root='));
|
|
2440
|
+
const authoringPluginCommand = argv[0] === 'plugin'
|
|
2441
|
+
&& (['build', 'test', 'validate', 'init', 'add-skill'].includes(argv[1] ?? '')
|
|
2442
|
+
|| ['remove', 'status'].includes(argv[1] ?? '') && explicitWorkspace);
|
|
3254
2443
|
const jsonAuthoringCommand = argv.includes('--json')
|
|
3255
2444
|
&& ((argv[0] === 'catalog' && ['init', 'context', 'version', 'build', 'validate', 'status', 'publish'].includes(argv[1] ?? ''))
|
|
3256
|
-
||
|
|
2445
|
+
|| authoringPluginCommand
|
|
3257
2446
|
|| reviewCommand !== null)
|
|
3258
2447
|
? `${argv[0]}:${argv[1]}`
|
|
3259
2448
|
: null;
|
|
@@ -3263,7 +2452,8 @@ export async function runCli(argv, options = {}) {
|
|
|
3263
2452
|
&& ['activate', 'status', 'deactivate'].includes(argv[2] ?? '')
|
|
3264
2453
|
? argv[2]
|
|
3265
2454
|
: null;
|
|
3266
|
-
const
|
|
2455
|
+
const recovery = recoveryRequest(argv);
|
|
2456
|
+
const jsonRecoveryRequest = recovery?.json ? recovery : null;
|
|
3267
2457
|
const jsonConfigMutation = jsonConfigMutationRequest(argv);
|
|
3268
2458
|
try {
|
|
3269
2459
|
const authoringScriptByCommand = {
|
|
@@ -3273,12 +2463,13 @@ export async function runCli(argv, options = {}) {
|
|
|
3273
2463
|
validate: 'validate-plugin.mjs',
|
|
3274
2464
|
status: 'plugin-status.mjs',
|
|
3275
2465
|
};
|
|
3276
|
-
const authoringScript =
|
|
2466
|
+
const authoringScript = authoringPluginCommand
|
|
3277
2467
|
? authoringScriptByCommand[argv[1] ?? '']
|
|
3278
2468
|
: argv[0] === 'skill' && argv[1] === 'validate'
|
|
3279
2469
|
? 'validate-skill.mjs'
|
|
3280
2470
|
: undefined;
|
|
3281
|
-
if (authoringScript && !argv.includes('--help') && !argv.includes('-h'))
|
|
2471
|
+
if (authoringScript && ((!argv.includes('--help') && !argv.includes('-h'))
|
|
2472
|
+
|| explicitWorkspace && ['remove', 'status'].includes(argv[1] ?? ''))) {
|
|
3282
2473
|
const authoringArgs = argv.slice(2);
|
|
3283
2474
|
let authoringEnv = options.env ?? process.env;
|
|
3284
2475
|
if (argv[0] === 'plugin'
|
|
@@ -3388,7 +2579,7 @@ export async function runCli(argv, options = {}) {
|
|
|
3388
2579
|
}
|
|
3389
2580
|
let catalogPublicationActionStarted = false;
|
|
3390
2581
|
let configMutationActionStarted = false;
|
|
3391
|
-
const programIo = jsonCatalogDevCommand ||
|
|
2582
|
+
const programIo = jsonCatalogDevCommand || jsonRecoveryRequest || jsonReviewCommand || jsonMaterialize || jsonConfigCommand
|
|
3392
2583
|
? { ...io, stderr: () => undefined }
|
|
3393
2584
|
: jsonConfigMutation
|
|
3394
2585
|
? {
|
|
@@ -3432,6 +2623,16 @@ export async function runCli(argv, options = {}) {
|
|
|
3432
2623
|
return program.__awCommandExitState?.exitCode ?? 0;
|
|
3433
2624
|
}
|
|
3434
2625
|
catch (error) {
|
|
2626
|
+
if (jsonMaterialize && error instanceof CommanderError) {
|
|
2627
|
+
if (error.exitCode === 0)
|
|
2628
|
+
return 0;
|
|
2629
|
+
writeJsonReceipt(io.stdout, {
|
|
2630
|
+
receiptSchemaVersion: 5, command: 'skill:materialize', ok: false,
|
|
2631
|
+
selectedSkills: [], dependencies: [], configDigest: null, materializationDigest: null,
|
|
2632
|
+
outputDigest: null, errors: [{ code: 'invalidArguments', message: error.message }],
|
|
2633
|
+
});
|
|
2634
|
+
return 2;
|
|
2635
|
+
}
|
|
3435
2636
|
if (reviewCommand && error instanceof CommanderError) {
|
|
3436
2637
|
if (error.exitCode === 0)
|
|
3437
2638
|
return 0;
|
|
@@ -3464,9 +2665,36 @@ export async function runCli(argv, options = {}) {
|
|
|
3464
2665
|
}));
|
|
3465
2666
|
return 1;
|
|
3466
2667
|
}
|
|
3467
|
-
if (
|
|
3468
|
-
|
|
3469
|
-
|
|
2668
|
+
if (jsonConfigCommand && !jsonConfigMutation) {
|
|
2669
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
2670
|
+
return 0;
|
|
2671
|
+
const failure = configMutationFailure(error, options.env ?? process.env, options.cwd ?? process.cwd());
|
|
2672
|
+
writeJsonReceipt(io.stdout, { ok: false, command: `config:${argv[2] ?? ''}`, errors: [failure] });
|
|
2673
|
+
return failure.code === 'invalidArguments' ? 2 : 1;
|
|
2674
|
+
}
|
|
2675
|
+
if (recovery) {
|
|
2676
|
+
if (error instanceof CommanderError && error.exitCode === 0)
|
|
2677
|
+
return 0;
|
|
2678
|
+
const failure = writeCommandFailure(error);
|
|
2679
|
+
if (argv[0] === 'project' || argv.some((value) => value === '-p' || value === '--platform' || value.startsWith('--platform='))) {
|
|
2680
|
+
failure.message += '\n使用 aw plugin intent、aw plugin targets 或 aw plugin install/remove/sync/cleanup/status。安装归属使用 --scope;工作上下文使用 --context。';
|
|
2681
|
+
}
|
|
2682
|
+
if (jsonRecoveryRequest) {
|
|
2683
|
+
if (recovery.command === 'status')
|
|
2684
|
+
writeJsonReceipt(io.stdout, {
|
|
2685
|
+
schemaVersion: 1, kind: 'aw-recovery-status', scope: recovery.scope, ok: false,
|
|
2686
|
+
intent: { state: 'unreadable', roots: null },
|
|
2687
|
+
selection: { agents: [], origin: 'none', preferences: 'unreadable' },
|
|
2688
|
+
inventory: null, extraObserved: [], coverage: null, counts: null, allSatisfied: null,
|
|
2689
|
+
errors: [failure],
|
|
2690
|
+
});
|
|
2691
|
+
else
|
|
2692
|
+
writeJsonReceipt(io.stdout, { ...recoveryFailureReceipt(recovery.command, recovery.scope, error),
|
|
2693
|
+
blockers: [failure], errors: [failure] });
|
|
2694
|
+
}
|
|
2695
|
+
else
|
|
2696
|
+
writeLine(io.stderr, failure.message);
|
|
2697
|
+
return failure.code === 'invalidArguments' ? 2 : 1;
|
|
3470
2698
|
}
|
|
3471
2699
|
if (jsonConfigMutation) {
|
|
3472
2700
|
if (error instanceof CommanderError && error.exitCode === 0)
|
|
@@ -3476,7 +2704,15 @@ export async function runCli(argv, options = {}) {
|
|
|
3476
2704
|
? { command: jsonConfigMutation.command }
|
|
3477
2705
|
: jsonConfigMutation, failure);
|
|
3478
2706
|
writeLine(io.stderr, failure.message);
|
|
3479
|
-
return 1;
|
|
2707
|
+
return failure.code === 'invalidArguments' ? 2 : 1;
|
|
2708
|
+
}
|
|
2709
|
+
if ((argv[0] === 'plugin' && argv[1] === 'config'
|
|
2710
|
+
|| argv[0] === 'skill' && argv[1] === 'materialize')
|
|
2711
|
+
&& (error instanceof CommanderError || error instanceof WriteCommandRequestError)) {
|
|
2712
|
+
if (error instanceof CommanderError)
|
|
2713
|
+
return error.exitCode === 0 ? 0 : 2;
|
|
2714
|
+
writeLine(io.stderr, error.message);
|
|
2715
|
+
return 2;
|
|
3480
2716
|
}
|
|
3481
2717
|
if (jsonAuthoringCommand === 'catalog:publish' && error instanceof CommanderError) {
|
|
3482
2718
|
const failure = catalogPublicationFailure({
|