@lesliechan721/aw 0.1.0-beta.8 → 0.1.0-beta.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring/scripts/add-skill.mjs +4 -4
- package/dist/authoring/scripts/add-skill.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +4 -4
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
- package/dist/authoring/scripts/lib/skill-scaffold.d.mts +77 -90
- package/dist/authoring/scripts/lib/skill-scaffold.mjs +99 -120
- package/dist/authoring/scripts/lib/skill-scaffold.mjs.map +1 -1
- package/dist/authoring/scripts/remove-plugin.mjs +1 -1
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +34 -778
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/aw-skill-eval-materializer.d.ts +24 -0
- package/dist/scripts/{plugin-eval-materializer.js → aw-skill-eval-materializer.js} +34 -145
- package/dist/scripts/aw-skill-eval-materializer.js.map +1 -0
- package/dist/scripts/bundle-plugins.d.ts +1 -0
- package/dist/scripts/bundle-plugins.js +2 -1
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +5 -6
- package/dist/scripts/plugin-staging.js +12 -13
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/src/authoring/workspace-commands.d.ts +2 -1
- package/dist/src/authoring/workspace-commands.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +2 -2
- package/dist/src/commands/aw-capabilities.js +6 -11
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/catalog-dev-source.d.ts +18 -12
- package/dist/src/commands/catalog-dev-source.js +241 -305
- package/dist/src/commands/catalog-dev-source.js.map +1 -1
- package/dist/src/commands/catalog-generation.d.ts +6 -19
- package/dist/src/commands/catalog-generation.js +10 -11
- package/dist/src/commands/catalog-generation.js.map +1 -1
- package/dist/src/commands/catalog-publication-inspection.d.ts +28 -27
- package/dist/src/commands/catalog-publication-inspection.js +139 -50
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-journal.d.ts +49 -0
- package/dist/src/commands/catalog-publication-journal.js +147 -0
- package/dist/src/commands/catalog-publication-journal.js.map +1 -0
- package/dist/src/commands/catalog-publication-target.d.ts +2 -1
- package/dist/src/commands/catalog-publication-target.js +37 -2
- package/dist/src/commands/catalog-publication-target.js.map +1 -1
- package/dist/src/commands/catalog-publish.d.ts +51 -15
- package/dist/src/commands/catalog-publish.js +576 -219
- package/dist/src/commands/catalog-publish.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +3 -28
- package/dist/src/commands/catalog-source.js +29 -140
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-status.d.ts +6 -26
- package/dist/src/commands/catalog-status.js +8 -146
- package/dist/src/commands/catalog-status.js.map +1 -1
- package/dist/src/commands/catalog-workspace-resolution.d.ts +13 -0
- package/dist/src/commands/catalog-workspace-resolution.js +42 -0
- package/dist/src/commands/catalog-workspace-resolution.js.map +1 -0
- package/dist/src/commands/dependency-operation-plan.d.ts +88 -9
- package/dist/src/commands/dependency-operation-plan.js +331 -6
- package/dist/src/commands/dependency-operation-plan.js.map +1 -1
- package/dist/src/commands/init.d.ts +5 -11
- package/dist/src/commands/init.js +30 -51
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/offline-cleanup-evidence.d.ts +20 -0
- package/dist/src/commands/offline-cleanup-evidence.js +87 -9
- package/dist/src/commands/offline-cleanup-evidence.js.map +1 -1
- package/dist/src/commands/options.d.ts +6 -1
- package/dist/src/commands/options.js +64 -6
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +4 -0
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +10 -8
- package/dist/src/commands/rebuild-command.js +1217 -426
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +54 -6
- package/dist/src/commands/rebuild-integration.js +691 -364
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +2 -0
- package/dist/src/commands/rebuild-operations.js +31 -17
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/skill-eval.d.ts +33 -0
- package/dist/src/commands/skill-eval.js +363 -0
- package/dist/src/commands/skill-eval.js.map +1 -0
- package/dist/src/commands/{status-v5.d.ts → status-v6.d.ts} +59 -26
- package/dist/src/commands/{status-v5.js → status-v6.js} +882 -79
- package/dist/src/commands/status-v6.js.map +1 -0
- package/dist/src/commands/sync-command.d.ts +21 -0
- package/dist/src/commands/sync-command.js +206 -0
- package/dist/src/commands/sync-command.js.map +1 -0
- package/dist/src/commands/wizard.d.ts +2 -2
- package/dist/src/commands/write-commands.js +1 -43
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/constants.d.ts +5 -4
- package/dist/src/constants.js +5 -4
- package/dist/src/constants.js.map +1 -1
- package/dist/src/eval/manifest-v1.d.ts +66 -0
- package/dist/src/eval/manifest-v1.js +326 -0
- package/dist/src/eval/manifest-v1.js.map +1 -0
- package/dist/src/generators/local-plugin.d.ts +3 -0
- package/dist/src/generators/local-plugin.js +123 -55
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +2 -0
- package/dist/src/index.js +412 -152
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.d.ts +58 -8
- package/dist/src/output/command-receipt.js +141 -11
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/model.d.ts +3 -11
- package/dist/src/portable/commands.d.ts +2 -2
- package/dist/src/portable/commands.js +2 -8
- package/dist/src/portable/commands.js.map +1 -1
- package/dist/src/portable/materializer.d.ts +1 -4
- package/dist/src/portable/materializer.js +0 -2
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.d.ts +20 -41
- package/dist/src/tui/catalog-generation.js +65 -224
- package/dist/src/tui/catalog-generation.js.map +1 -1
- package/dist/src/tui/components.js +1 -2
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.js +461 -330
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +3 -5
- package/dist/src/tui/controller-runtime.js +182 -187
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +42 -45
- package/dist/src/tui/controller.js +454 -407
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostics.d.ts +1 -2
- package/dist/src/tui/diagnostics.js.map +1 -1
- package/dist/src/tui/index.d.ts +1 -1
- package/dist/src/tui/index.js +1 -1
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/model.d.ts +81 -13
- package/dist/src/tui/model.js +378 -95
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/router.d.ts +9 -0
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/types.d.ts +54 -47
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.d.ts +4 -1
- package/dist/src/utils/agent-version.js +28 -3
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/catalog-digests.d.ts +7 -0
- package/dist/src/utils/catalog-digests.js +27 -0
- package/dist/src/utils/catalog-digests.js.map +1 -1
- package/dist/src/utils/catalog-generation-control-snapshot.d.ts +11 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js +45 -0
- package/dist/src/utils/catalog-generation-control-snapshot.js.map +1 -0
- package/dist/src/utils/catalog-generation-error.d.ts +2 -1
- package/dist/src/utils/catalog-generation-error.js +12 -0
- package/dist/src/utils/catalog-generation-error.js.map +1 -1
- package/dist/src/utils/catalog-generation-resolver.d.ts +10 -3
- package/dist/src/utils/catalog-generation-resolver.js +90 -76
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -1
- package/dist/src/utils/catalog-generation-service.d.ts +24 -33
- package/dist/src/utils/catalog-generation-service.js +253 -567
- package/dist/src/utils/catalog-generation-service.js.map +1 -1
- package/dist/src/utils/catalog-generation-state.d.ts +4 -0
- package/dist/src/utils/catalog-generation-state.js +73 -106
- package/dist/src/utils/catalog-generation-state.js.map +1 -1
- package/dist/src/utils/catalog-generation-store.d.ts +16 -26
- package/dist/src/utils/catalog-generation-store.js +154 -290
- package/dist/src/utils/catalog-generation-store.js.map +1 -1
- package/dist/src/utils/catalog-manifest-v6.d.ts +5 -0
- package/dist/src/utils/{catalog-manifest-v5.js → catalog-manifest-v6.js} +23 -35
- package/dist/src/utils/catalog-manifest-v6.js.map +1 -0
- package/dist/src/utils/catalog-operation-context.d.ts +6 -14
- package/dist/src/utils/catalog-operation-context.js +68 -169
- package/dist/src/utils/catalog-operation-context.js.map +1 -1
- package/dist/src/utils/catalog-public-error.js +1 -4
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-runtime-projection.d.ts +3 -0
- package/dist/src/utils/catalog-runtime-projection.js +5 -40
- package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
- package/dist/src/utils/catalog-snapshot.d.ts +2 -2
- package/dist/src/utils/catalog-source-references.d.ts +7 -0
- package/dist/src/utils/catalog-source-references.js +44 -55
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.js +25 -9
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-config.d.ts +2 -0
- package/dist/src/utils/codex-config.js +22 -1
- package/dist/src/utils/codex-config.js.map +1 -1
- package/dist/src/utils/codex-manager.d.ts +50 -2
- package/dist/src/utils/codex-manager.js +160 -6
- package/dist/src/utils/codex-manager.js.map +1 -1
- package/dist/src/utils/codex-reconciler.d.ts +131 -0
- package/dist/src/utils/codex-reconciler.js +327 -0
- package/dist/src/utils/codex-reconciler.js.map +1 -0
- package/dist/src/utils/codex-shared-native.d.ts +56 -0
- package/dist/src/utils/codex-shared-native.js +87 -0
- package/dist/src/utils/codex-shared-native.js.map +1 -0
- package/dist/src/utils/codex-surface-analysis.d.ts +44 -0
- package/dist/src/utils/codex-surface-analysis.js +247 -0
- package/dist/src/utils/codex-surface-analysis.js.map +1 -0
- package/dist/src/utils/git-catalog-provider.js +56 -115
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +1 -3
- package/dist/src/utils/manifest.js +1 -3
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.d.ts +1 -10
- package/dist/src/utils/multi-source-catalog.js +8 -175
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +34 -0
- package/dist/src/utils/native-cli.js +91 -0
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/orphan-marketplace-cleanup.js +1 -0
- package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
- package/dist/src/utils/ownership.d.ts +0 -10
- package/dist/src/utils/ownership.js +3 -88
- package/dist/src/utils/ownership.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.d.ts +1 -1
- package/dist/src/utils/path-catalog-provider.js +45 -62
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/paths.d.ts +0 -1
- package/dist/src/utils/paths.js +0 -1
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/plugin-config-write.js +0 -5
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-intent-state.d.ts +39 -0
- package/dist/src/utils/plugin-intent-state.js +325 -0
- package/dist/src/utils/plugin-intent-state.js.map +1 -0
- package/dist/src/utils/target-eligibility.d.ts +3 -2
- package/dist/src/utils/target-eligibility.js +4 -3
- package/dist/src/utils/target-eligibility.js.map +1 -1
- package/package.json +5 -4
- package/dist/scripts/aw-skill-eval-engine.d.ts +0 -13
- package/dist/scripts/aw-skill-eval-engine.js +0 -31
- package/dist/scripts/aw-skill-eval-engine.js.map +0 -1
- package/dist/scripts/codex-eval-app-server.d.ts +0 -91
- package/dist/scripts/codex-eval-app-server.js +0 -1334
- package/dist/scripts/codex-eval-app-server.js.map +0 -1
- package/dist/scripts/codex-eval-isolation.d.ts +0 -61
- package/dist/scripts/codex-eval-isolation.js +0 -318
- package/dist/scripts/codex-eval-isolation.js.map +0 -1
- package/dist/scripts/codex-eval-process-management.d.ts +0 -8
- package/dist/scripts/codex-eval-process-management.js +0 -69
- package/dist/scripts/codex-eval-process-management.js.map +0 -1
- package/dist/scripts/codex-eval-process-tree.d.ts +0 -38
- package/dist/scripts/codex-eval-process-tree.js +0 -803
- package/dist/scripts/codex-eval-process-tree.js.map +0 -1
- package/dist/scripts/codex-eval-runtime-config.d.ts +0 -62
- package/dist/scripts/codex-eval-runtime-config.js +0 -843
- package/dist/scripts/codex-eval-runtime-config.js.map +0 -1
- package/dist/scripts/codex-trigger-eval.d.ts +0 -84
- package/dist/scripts/codex-trigger-eval.js +0 -968
- package/dist/scripts/codex-trigger-eval.js.map +0 -1
- package/dist/scripts/eval-plugin-skills-audited.d.ts +0 -6
- package/dist/scripts/eval-plugin-skills-audited.js +0 -261
- package/dist/scripts/eval-plugin-skills-audited.js.map +0 -1
- package/dist/scripts/eval-plugin-skills.d.ts +0 -45
- package/dist/scripts/eval-plugin-skills.js +0 -1589
- package/dist/scripts/eval-plugin-skills.js.map +0 -1
- package/dist/scripts/eval-run-layout.d.ts +0 -17
- package/dist/scripts/eval-run-layout.js +0 -26
- package/dist/scripts/eval-run-layout.js.map +0 -1
- package/dist/scripts/plugin-eval-contract.d.ts +0 -189
- package/dist/scripts/plugin-eval-contract.js +0 -745
- package/dist/scripts/plugin-eval-contract.js.map +0 -1
- package/dist/scripts/plugin-eval-materializer.d.ts +0 -13
- package/dist/scripts/plugin-eval-materializer.js.map +0 -1
- package/dist/scripts/skill-reporting.d.ts +0 -212
- package/dist/scripts/skill-reporting.js +0 -922
- package/dist/scripts/skill-reporting.js.map +0 -1
- package/dist/src/commands/catalog-context.d.ts +0 -52
- package/dist/src/commands/catalog-context.js +0 -156
- package/dist/src/commands/catalog-context.js.map +0 -1
- package/dist/src/commands/status-v5.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v5.d.ts +0 -5
- package/dist/src/utils/catalog-manifest-v5.js.map +0 -1
- package/dist/src/utils/catalog-source-cache.d.ts +0 -62
- package/dist/src/utils/catalog-source-cache.js +0 -321
- package/dist/src/utils/catalog-source-cache.js.map +0 -1
- package/dist/src/utils/codex-project-surface.d.ts +0 -3
- package/dist/src/utils/codex-project-surface.js +0 -49
- package/dist/src/utils/codex-project-surface.js.map +0 -1
- package/dist/src/utils/plugin-release.d.ts +0 -2
- package/dist/src/utils/plugin-release.js +0 -2
- package/dist/src/utils/plugin-release.js.map +0 -1
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import crypto from 'node:crypto';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { statusCommandV6, } from '../commands/status-v6.js';
|
|
4
4
|
import { addCatalogSourceCommand, listCatalogSources, preflightCatalogSourceMutation, removeCatalogSourceCommand, setPrimaryCatalogSourceCommand, updateCatalogSourceCommand, } from '../commands/catalog-source.js';
|
|
5
5
|
import { cleanupWriteCommand, installWriteCommand, reinstallWriteCommand, uninstallWriteCommand, upgradeWriteCommand, } from '../commands/write-commands.js';
|
|
6
6
|
import { readCliPackageInfo } from '../utils/local-marketplace.js';
|
|
7
|
-
import { CatalogGenerationError } from '../utils/catalog-generation-error.js';
|
|
8
7
|
import { readCatalogSourcesConfigSnapshot, } from '../utils/catalog-sources.js';
|
|
9
8
|
import { withResolvedCatalogPlugin, withResolvedMultiSourceCatalog, formatPluginId, parsePluginId, } from '../utils/multi-source-catalog.js';
|
|
10
9
|
import { coercePluginConfigUpdates, readNamespacedPluginConfigStoreIdentity, readPluginConfigStore, resolveConfigRead, } from '../utils/plugin-config.js';
|
|
@@ -12,7 +11,7 @@ import { applyPluginConfigWrite, resetPluginConfigWithHelper, } from '../utils/p
|
|
|
12
11
|
import { offlineCleanupEvidenceFromInventory, } from '../commands/offline-cleanup-evidence.js';
|
|
13
12
|
import { inventoryCatalogSourceReferences } from '../utils/catalog-source-references.js';
|
|
14
13
|
import { operationEvidenceFingerprint, TuiController, TuiOperationBlockedError, } from './controller.js';
|
|
15
|
-
import { buildConfigGroups, buildConfigPage, projectPlatformPlacement, } from './model.js';
|
|
14
|
+
import { buildConfigGroups, buildConfigPage, isPureNativeCodexTarget, projectPlatformPlacement, } from './model.js';
|
|
16
15
|
import { projectCatalogSourceLocation } from '../utils/catalog-source-presentation.js';
|
|
17
16
|
import { targetCanBeUninstalled, targetHasArtifactCollision, } from '../utils/target-eligibility.js';
|
|
18
17
|
import { calculateCatalogSourceIdentity } from '../utils/catalog-source-identity.js';
|
|
@@ -20,20 +19,18 @@ import { checkAwCapabilitySupport, readPluginManifest } from '../utils/manifest.
|
|
|
20
19
|
import { withAwHomeMutationLock } from '../utils/aw-home-mutation-lock.js';
|
|
21
20
|
import { IMPLEMENTED_AW_CAPABILITIES } from '../commands/aw-capabilities.js';
|
|
22
21
|
import { resolveCatalogOperationContext, resolvePartialCatalogOperationContext, selectCatalogOperationContext, } from '../utils/catalog-operation-context.js';
|
|
23
|
-
import { activateCatalogSourceCandidate, refreshCatalogSourceGeneration, setCatalogSourceRefreshPolicy, } from '../utils/catalog-generation-service.js';
|
|
24
22
|
import { loadCatalogGenerationViewModels } from './catalog-generation.js';
|
|
25
23
|
import { installPortableSkills, preparePortableInstall, PortableCommandError, } from '../portable/commands.js';
|
|
26
24
|
import { MANAGED_CODEX_PACKAGE_NAME, MANAGED_CODEX_VERSION, } from '../utils/codex-manager.js';
|
|
25
|
+
import { calculatePluginIntentDigest, canonicalizePluginIntentState, readPluginIntentState, writePluginIntentState, } from '../utils/plugin-intent-state.js';
|
|
27
26
|
async function loadPortablePluginIds(options) {
|
|
28
27
|
return withResolvedMultiSourceCatalog({
|
|
29
28
|
cliVersion: options.cliVersion,
|
|
30
|
-
freshnessPolicy: 'cacheFirst',
|
|
31
29
|
env: options.context.env,
|
|
32
30
|
signal: options.signal,
|
|
33
31
|
...(options.catalogOperationContext
|
|
34
32
|
? { operationContext: options.catalogOperationContext }
|
|
35
33
|
: {}),
|
|
36
|
-
...(options.bootstrapMissingActive === false ? { bootstrapMissingActive: false } : {}),
|
|
37
34
|
consume: async (catalog) => (await Promise.all(catalog.sources.flatMap((item) => item.resolution
|
|
38
35
|
? item.resolution.manifest.entries.flatMap((entry) => {
|
|
39
36
|
const support = checkAwCapabilitySupport(entry.requires.aw.capabilities ?? [], IMPLEMENTED_AW_CAPABILITIES);
|
|
@@ -119,8 +116,6 @@ function throwIfWriteReviewStale(result) {
|
|
|
119
116
|
}
|
|
120
117
|
}
|
|
121
118
|
const SOURCE_PROGRESS_PHASES = {
|
|
122
|
-
refreshingCatalog: '刷新 Catalog 缓存',
|
|
123
|
-
catalogReady: 'Catalog 已读取,索引已刷新',
|
|
124
119
|
savingConfig: '保存来源配置',
|
|
125
120
|
};
|
|
126
121
|
function pluginIntent(intent) {
|
|
@@ -131,23 +126,48 @@ function assertIntentIsLegal(intent, targets, revisions = []) {
|
|
|
131
126
|
? ['codex', 'claude']
|
|
132
127
|
: [intent.platform];
|
|
133
128
|
for (const platform of platforms) {
|
|
134
|
-
const
|
|
135
|
-
&& target.platform === platform
|
|
129
|
+
const platformTargets = targets.filter((target) => target.pluginId === intent.pluginId
|
|
130
|
+
&& target.platform === platform);
|
|
131
|
+
const selected = platformTargets.find((target) => target.scope === intent.scope)
|
|
132
|
+
?? (platform === 'codex' ? platformTargets[0] : undefined);
|
|
136
133
|
if (!selected || selected.errors.some((error) => error.code === 'unsupportedTarget')) {
|
|
137
134
|
throw new TuiOperationBlockedError('unsupportedTarget', '所选插件不支持这个平台和使用位置。');
|
|
138
135
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (intent.
|
|
136
|
+
if (intent.action === 'sync' && platform !== 'codex') {
|
|
137
|
+
throw new TuiOperationBlockedError('syncPlatformUnsupported', 'sync 只支持 Codex。');
|
|
138
|
+
}
|
|
139
|
+
if (intent.dependencyPlacementOnly === 'desired')
|
|
140
|
+
continue;
|
|
141
|
+
const otherScope = intent.scope === 'user' ? 'project' : 'user';
|
|
142
|
+
const otherScopeInstalled = platform === 'codex'
|
|
143
|
+
? platformTargets.some((target) => target.desired.scopes.includes(otherScope)
|
|
144
|
+
|| target.activation?.[otherScope] === true)
|
|
145
|
+
: targets.some((target) => target.platform === platform
|
|
146
|
+
&& target.scope !== intent.scope
|
|
147
|
+
&& (target.state === 'present' || target.state === 'partial'));
|
|
148
|
+
const pureNativeCodex = isPureNativeCodexTarget(selected);
|
|
149
|
+
if (intent.action === 'install' && otherScopeInstalled && !pureNativeCodex
|
|
150
|
+
&& !intent.dependencyPlacementAdjustment) {
|
|
143
151
|
throw new TuiOperationBlockedError('scopeConflict', '这个平台已安装在另一个使用位置。请先移除原位置。');
|
|
144
152
|
}
|
|
145
|
-
if (intent.action === 'install'
|
|
153
|
+
if ((intent.action === 'install' || intent.action === 'upgrade' || intent.action === 'reinstall')
|
|
154
|
+
&& targetHasArtifactCollision(selected)) {
|
|
146
155
|
throw new TuiOperationBlockedError('artifactCollision', '所选位置存在输出冲突。请先移除或迁移冲突内容。');
|
|
147
156
|
}
|
|
148
|
-
|
|
157
|
+
const selectedScopeInstalled = platform === 'codex'
|
|
158
|
+
? selected.desired.scopes.includes(intent.scope)
|
|
159
|
+
|| selected.activation?.[intent.scope] === true
|
|
160
|
+
: selected.state !== 'absent';
|
|
161
|
+
if (intent.action === 'install' && selectedScopeInstalled
|
|
162
|
+
&& !intent.dependencyPlacementAdjustment) {
|
|
149
163
|
throw new TuiOperationBlockedError('targetAlreadyInstalled', '所选位置已经安装。');
|
|
150
164
|
}
|
|
165
|
+
if (intent.action === 'sync'
|
|
166
|
+
&& selected.actual.state !== 'needsSync'
|
|
167
|
+
&& selected.actual.state !== 'drifted'
|
|
168
|
+
&& selected.actual.state !== 'conflict') {
|
|
169
|
+
throw new TuiOperationBlockedError('targetStateChanged', '当前安装状态不需要同步。');
|
|
170
|
+
}
|
|
151
171
|
const revision = revisions.find((entry) => entry.pluginId === intent.pluginId
|
|
152
172
|
&& entry.platform === platform && entry.scope === intent.scope)?.revision;
|
|
153
173
|
if (intent.action === 'upgrade'
|
|
@@ -170,7 +190,9 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
170
190
|
};
|
|
171
191
|
const selected = targets.find((target) => target.pluginId === intent.pluginId
|
|
172
192
|
&& target.platform === intent.platform
|
|
173
|
-
&& target.scope === intent.scope)
|
|
193
|
+
&& target.scope === intent.scope)
|
|
194
|
+
?? targets.find((target) => target.pluginId === intent.pluginId
|
|
195
|
+
&& target.platform === 'codex');
|
|
174
196
|
if (intent.originIssue.category === 'dependencyMissing') {
|
|
175
197
|
if (intent.originIssue.actionId !== 'installDependency'
|
|
176
198
|
|| intent.action !== 'install' || !selected || selected.state !== 'absent') {
|
|
@@ -207,9 +229,17 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
207
229
|
return;
|
|
208
230
|
}
|
|
209
231
|
else if (intent.originIssue.category === 'scopeConflict') {
|
|
210
|
-
const installedScopes = new Set(
|
|
211
|
-
|
|
212
|
-
|
|
232
|
+
const installedScopes = new Set();
|
|
233
|
+
for (const target of targets.filter((candidate) => candidate.pluginId === intent.pluginId && candidate.platform === intent.platform)) {
|
|
234
|
+
if (target.state === 'present' || target.state === 'partial')
|
|
235
|
+
installedScopes.add(target.scope);
|
|
236
|
+
for (const scope of target.desired.scopes)
|
|
237
|
+
installedScopes.add(scope);
|
|
238
|
+
if (target.activation?.user === true)
|
|
239
|
+
installedScopes.add('user');
|
|
240
|
+
if (target.activation?.project === true)
|
|
241
|
+
installedScopes.add('project');
|
|
242
|
+
}
|
|
213
243
|
const correctBranch = intent.action === 'uninstall'
|
|
214
244
|
&& ((intent.originIssue.actionId === 'keepUserScope' && intent.scope === 'project')
|
|
215
245
|
|| (intent.originIssue.actionId === 'keepProjectScope' && intent.scope === 'user'));
|
|
@@ -239,13 +269,11 @@ async function assertTypedIssueOrigin(intent, targets) {
|
|
|
239
269
|
async function loadDependencyOverviews(options) {
|
|
240
270
|
const graph = await withResolvedMultiSourceCatalog({
|
|
241
271
|
cliVersion: options.cliVersion,
|
|
242
|
-
freshnessPolicy: 'cacheFirst',
|
|
243
272
|
env: options.context.env,
|
|
244
273
|
signal: options.signal,
|
|
245
274
|
...(options.catalogOperationContext
|
|
246
275
|
? { operationContext: options.catalogOperationContext }
|
|
247
276
|
: {}),
|
|
248
|
-
...(options.bootstrapMissingActive === false ? { bootstrapMissingActive: false } : {}),
|
|
249
277
|
consume: async (catalog) => ({
|
|
250
278
|
nodes: catalog.sources.flatMap((item) => item.resolution
|
|
251
279
|
? item.resolution.manifest.entries.map((entry) => ({
|
|
@@ -332,7 +360,8 @@ async function loadDependencyOverviews(options) {
|
|
|
332
360
|
return 'notInstalled';
|
|
333
361
|
}
|
|
334
362
|
return placements.some((placement) => placement.state === 'scopeConflict'
|
|
335
|
-
|| (placement.state === 'installed'
|
|
363
|
+
|| (placement.state === 'installed'
|
|
364
|
+
&& (placement.health !== 'ready' || placement.blockingReason !== undefined)))
|
|
336
365
|
? 'needsAttention'
|
|
337
366
|
: 'ready';
|
|
338
367
|
};
|
|
@@ -479,6 +508,30 @@ function createReviewStageReporter(options) {
|
|
|
479
508
|
export function createTuiControllerDependencies(context, progressFeed, options = {}) {
|
|
480
509
|
const readInventory = options.inventoryCatalogSourceReferences
|
|
481
510
|
?? inventoryCatalogSourceReferences;
|
|
511
|
+
const validatedStoreEntries = new Map();
|
|
512
|
+
const validatingStoreEntries = new Map();
|
|
513
|
+
const loadCatalogGenerations = async () => {
|
|
514
|
+
const generations = await loadCatalogGenerationViewModels({
|
|
515
|
+
env: context.env,
|
|
516
|
+
validatedStoreEntries,
|
|
517
|
+
validatingStoreEntries,
|
|
518
|
+
onStage: (event) => context.debugLogger.log({
|
|
519
|
+
type: 'performance:stage',
|
|
520
|
+
level: 'debug',
|
|
521
|
+
target: 'debugLog',
|
|
522
|
+
message: 'Catalog generation load stage completed.',
|
|
523
|
+
data: event,
|
|
524
|
+
}),
|
|
525
|
+
});
|
|
526
|
+
const retained = new Set(generations.flatMap((source) => [
|
|
527
|
+
source.active?.storeKey,
|
|
528
|
+
].filter((value) => value !== undefined)));
|
|
529
|
+
for (const storeKey of validatedStoreEntries.keys()) {
|
|
530
|
+
if (!retained.has(storeKey))
|
|
531
|
+
validatedStoreEntries.delete(storeKey);
|
|
532
|
+
}
|
|
533
|
+
return generations;
|
|
534
|
+
};
|
|
482
535
|
const createOperationInventoryReader = () => {
|
|
483
536
|
let ordinaryInventory;
|
|
484
537
|
return (inventoryOptions) => {
|
|
@@ -492,7 +545,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
492
545
|
const catalogOperationByEvidence = new WeakMap();
|
|
493
546
|
let sessionCatalogOperationContext;
|
|
494
547
|
let sessionStatusResult;
|
|
495
|
-
let bootstrapNextCatalogSession = true;
|
|
496
548
|
const sessionContextForPlugin = (pluginId) => {
|
|
497
549
|
const sourceId = parsePluginId(pluginId).sourceId;
|
|
498
550
|
if (!sourceId || !sessionCatalogOperationContext)
|
|
@@ -504,23 +556,20 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
504
556
|
const packageInfo = await readCliPackageInfo();
|
|
505
557
|
const catalogOperationContext = sessionCatalogOperationContext
|
|
506
558
|
?? await resolvePartialCatalogOperationContext({
|
|
507
|
-
cliVersion: packageInfo.version,
|
|
508
559
|
env: context.env,
|
|
509
560
|
signal,
|
|
510
|
-
|
|
511
|
-
|
|
561
|
+
validatedStoreEntries,
|
|
562
|
+
validatingStoreEntries,
|
|
512
563
|
}).catch(() => undefined);
|
|
513
564
|
if (catalogOperationContext)
|
|
514
565
|
sessionCatalogOperationContext = catalogOperationContext;
|
|
515
566
|
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
516
|
-
const result = await
|
|
567
|
+
const result = await statusCommandV6({
|
|
517
568
|
cwd: context.cwd,
|
|
518
569
|
env: context.env,
|
|
519
570
|
cliVersion: packageInfo.version,
|
|
520
571
|
verbose: context.diagnostics.verbose,
|
|
521
572
|
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
522
|
-
...(!catalogOperationContext ? { bootstrapMissingActive: false } : {}),
|
|
523
|
-
...(options.catalogGenerationRuntime ? { catalogGenerationRuntime: options.catalogGenerationRuntime } : {}),
|
|
524
573
|
inventoryCatalogSourceReferences: readInventory,
|
|
525
574
|
});
|
|
526
575
|
signal.throwIfAborted();
|
|
@@ -535,17 +584,15 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
535
584
|
status: result,
|
|
536
585
|
signal,
|
|
537
586
|
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
538
|
-
...(!catalogOperationContext ? { bootstrapMissingActive: false } : {}),
|
|
539
587
|
});
|
|
540
588
|
const portablePluginIds = await loadPortablePluginIds({
|
|
541
589
|
context,
|
|
542
590
|
cliVersion: packageInfo.version,
|
|
543
591
|
signal,
|
|
544
592
|
...(catalogOperationContext ? { catalogOperationContext } : {}),
|
|
545
|
-
...(!catalogOperationContext ? { bootstrapMissingActive: false } : {}),
|
|
546
593
|
});
|
|
547
594
|
signal.throwIfAborted();
|
|
548
|
-
const catalogGenerations = await
|
|
595
|
+
const catalogGenerations = await loadCatalogGenerations();
|
|
549
596
|
signal.throwIfAborted();
|
|
550
597
|
const statusById = new Map(result.payload.catalog.sources.map((source) => [source.id, source]));
|
|
551
598
|
return {
|
|
@@ -556,6 +603,8 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
556
603
|
dependencyOverviews,
|
|
557
604
|
portablePluginIds,
|
|
558
605
|
catalogGenerations,
|
|
606
|
+
sessionGenerationKeys: Object.fromEntries((catalogOperationContext?.generationSet.sources ?? [])
|
|
607
|
+
.map((source) => [source.sourceId, source.storeKey])),
|
|
559
608
|
sourceDetails: configured.sources.map((source) => {
|
|
560
609
|
const status = statusById.get(source.id);
|
|
561
610
|
return {
|
|
@@ -583,38 +632,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
583
632
|
}
|
|
584
633
|
throw new TuiOperationBlockedError('operationReviewStale', '状态读取期间来源配置持续变化。请重试。');
|
|
585
634
|
};
|
|
586
|
-
const captureEvidence = async (intent, signal, preparation,
|
|
587
|
-
if (intent.kind === 'catalogActivate') {
|
|
588
|
-
signal?.throwIfAborted();
|
|
589
|
-
const source = (await loadCatalogGenerationViewModels({ env: context.env }))
|
|
590
|
-
.find((entry) => entry.sourceId === intent.sourceId);
|
|
591
|
-
if (!source?.active || !source.candidate) {
|
|
592
|
-
throw operationReviewStale('Catalog Candidate 不再可用。');
|
|
593
|
-
}
|
|
594
|
-
if (source.candidate.generationKey !== intent.candidateGenerationKey) {
|
|
595
|
-
throw operationReviewStale('Catalog Candidate 已变化。');
|
|
596
|
-
}
|
|
597
|
-
const sessionCatalog = sessionCatalogOperationContext?.catalog;
|
|
598
|
-
return {
|
|
599
|
-
catalog: {
|
|
600
|
-
configDigest: sessionCatalog?.configDigest ?? 'unavailable',
|
|
601
|
-
compositeDigest: sessionCatalog?.compositeDigest ?? 'unavailable',
|
|
602
|
-
...(sessionCatalogOperationContext?.generationSetDigest
|
|
603
|
-
? { generationSetDigest: sessionCatalogOperationContext.generationSetDigest }
|
|
604
|
-
: {}),
|
|
605
|
-
},
|
|
606
|
-
catalogCandidate: {
|
|
607
|
-
sourceId: source.sourceId,
|
|
608
|
-
activeVersion: source.active.catalogVersion,
|
|
609
|
-
candidateVersion: source.candidate.catalogVersion,
|
|
610
|
-
channel: source.candidate.channel,
|
|
611
|
-
requestedRef: source.candidate.requestedRef,
|
|
612
|
-
candidateGenerationKey: source.candidate.generationKey,
|
|
613
|
-
digestShort: source.candidate.digestShort,
|
|
614
|
-
pluginChanges: source.candidate.pluginChanges,
|
|
615
|
-
},
|
|
616
|
-
};
|
|
617
|
-
}
|
|
635
|
+
const captureEvidence = async (intent, signal, preparation, operationInventory = createOperationInventoryReader(), freshCatalog = false) => {
|
|
618
636
|
if (intent.kind === 'sourceMutation') {
|
|
619
637
|
signal?.throwIfAborted();
|
|
620
638
|
if (intent.action === 'add' && !intent.source
|
|
@@ -636,10 +654,10 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
636
654
|
await preparation?.reporter.emit('evidence');
|
|
637
655
|
signal?.throwIfAborted();
|
|
638
656
|
const evidence = {
|
|
639
|
-
catalog: { configDigest: preview.configDigest, compositeDigest: preview.
|
|
657
|
+
catalog: { configDigest: preview.configDigest, compositeDigest: preview.proposedConfigDigest },
|
|
640
658
|
sourceWrite: {
|
|
641
659
|
configDigest: preview.configDigest,
|
|
642
|
-
|
|
660
|
+
proposedConfigDigest: preview.proposedConfigDigest,
|
|
643
661
|
...(preview.sourceIdentity ? { sourceIdentity: preview.sourceIdentity } : {}),
|
|
644
662
|
inventoryDigest: digest({ references: preview.references.references, errors: preview.references.errors }),
|
|
645
663
|
referenceCount: preview.references.references.length,
|
|
@@ -647,7 +665,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
647
665
|
},
|
|
648
666
|
};
|
|
649
667
|
if (preparation?.validateIntent
|
|
650
|
-
&& evidence.sourceWrite?.configDigest === evidence.sourceWrite?.
|
|
668
|
+
&& evidence.sourceWrite?.configDigest === evidence.sourceWrite?.proposedConfigDigest) {
|
|
651
669
|
throw new TuiOperationBlockedError('sourceNoChanges', '来源没有变化。');
|
|
652
670
|
}
|
|
653
671
|
return evidence;
|
|
@@ -666,19 +684,16 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
666
684
|
: undefined;
|
|
667
685
|
let catalogOperation;
|
|
668
686
|
let catalogOperationError;
|
|
669
|
-
if (!offlineCleanupReason && intent.kind !== 'portableInstall'
|
|
670
|
-
&& sessionCatalogOperationContext) {
|
|
687
|
+
if (!offlineCleanupReason && intent.kind !== 'portableInstall') {
|
|
671
688
|
try {
|
|
672
689
|
const sourceIds = [parsePluginId(intent.pluginId).sourceId];
|
|
673
|
-
catalogOperation =
|
|
690
|
+
catalogOperation = !freshCatalog && sessionCatalogOperationContext
|
|
674
691
|
? selectCatalogOperationContext(sessionCatalogOperationContext, sourceIds)
|
|
675
692
|
: await resolveCatalogOperationContext({
|
|
676
|
-
cliVersion: packageInfo.version,
|
|
677
693
|
sourceIds,
|
|
678
694
|
env: context.env,
|
|
679
|
-
...(
|
|
695
|
+
...(!freshCatalog ? { validatedStoreEntries, validatingStoreEntries } : {}),
|
|
680
696
|
...(signal ? { signal } : {}),
|
|
681
|
-
...(!bootstrapMissingActive ? { bootstrapMissingActive: false } : {}),
|
|
682
697
|
});
|
|
683
698
|
}
|
|
684
699
|
catch (error) {
|
|
@@ -734,7 +749,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
734
749
|
const selected = await withResolvedCatalogPlugin({
|
|
735
750
|
selector: intent.pluginId,
|
|
736
751
|
cliVersion: packageInfo.version,
|
|
737
|
-
freshnessPolicy: 'cacheFirst',
|
|
738
752
|
configSnapshot,
|
|
739
753
|
env: context.env,
|
|
740
754
|
operationContext: catalogOperation,
|
|
@@ -798,8 +812,8 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
798
812
|
await preparation?.reporter.emit('status');
|
|
799
813
|
const statusCatalogOperation = offlineCleanupReason
|
|
800
814
|
? undefined
|
|
801
|
-
: catalogOperation ?? (
|
|
802
|
-
const status = await
|
|
815
|
+
: catalogOperation ?? (!freshCatalog ? sessionCatalogOperationContext : undefined);
|
|
816
|
+
const status = await statusCommandV6({
|
|
803
817
|
plugins: [...new Set([intent.pluginId,
|
|
804
818
|
...(intent.kind === 'pluginWrite' && intent.originIssue?.consumerPluginId
|
|
805
819
|
? [intent.originIssue.consumerPluginId] : [])])],
|
|
@@ -811,10 +825,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
811
825
|
env: context.env,
|
|
812
826
|
cliVersion: packageInfo.version,
|
|
813
827
|
...(statusCatalogOperation ? { catalogOperationContext: statusCatalogOperation } : {}),
|
|
814
|
-
...(offlineCleanupReason || !bootstrapMissingActive
|
|
815
|
-
|| (!statusCatalogOperation && sessionCatalogOperationContext)
|
|
816
|
-
? { bootstrapMissingActive: false }
|
|
817
|
-
: {}),
|
|
818
828
|
inventoryCatalogSourceReferences: operationInventory,
|
|
819
829
|
});
|
|
820
830
|
signal?.throwIfAborted();
|
|
@@ -833,16 +843,15 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
833
843
|
}
|
|
834
844
|
if (!offlineCleanupReason && !catalogOperation) {
|
|
835
845
|
catalogOperation = await resolveCatalogOperationContext({
|
|
836
|
-
cliVersion: packageInfo.version,
|
|
837
846
|
sourceIds: [parsePluginId(intent.pluginId).sourceId],
|
|
838
847
|
configSnapshot,
|
|
839
848
|
env: context.env,
|
|
840
|
-
...(
|
|
849
|
+
...(!freshCatalog ? { validatedStoreEntries, validatingStoreEntries } : {}),
|
|
841
850
|
...(signal ? { signal } : {}),
|
|
842
|
-
...(!bootstrapMissingActive ? { bootstrapMissingActive: false } : {}),
|
|
843
851
|
});
|
|
844
852
|
}
|
|
845
853
|
let dependencyPlan;
|
|
854
|
+
let codexReconcilePlans;
|
|
846
855
|
await preparation?.reporter.emit('catalog');
|
|
847
856
|
const offlineCleanupTarget = offlineCleanupReason && intent.kind === 'pluginWrite'
|
|
848
857
|
? status.payload.targets.find((target) => target.pluginId === intent.pluginId
|
|
@@ -888,7 +897,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
888
897
|
: await withResolvedCatalogPlugin({
|
|
889
898
|
selector: intent.pluginId,
|
|
890
899
|
cliVersion: packageInfo.version,
|
|
891
|
-
freshnessPolicy: 'cacheFirst',
|
|
892
900
|
configSnapshot,
|
|
893
901
|
env: context.env,
|
|
894
902
|
...(catalogOperation ? { operationContext: catalogOperation } : {}),
|
|
@@ -925,11 +933,15 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
925
933
|
reinstall: reinstallWriteCommand,
|
|
926
934
|
uninstall: uninstallWriteCommand,
|
|
927
935
|
cleanup: cleanupWriteCommand,
|
|
936
|
+
sync: installWriteCommand,
|
|
928
937
|
}[intent.action];
|
|
929
938
|
const preview = await command([intent.pluginId], {
|
|
930
939
|
cwd: context.cwd,
|
|
931
940
|
platform: intent.platform,
|
|
932
941
|
scope: intent.scope,
|
|
942
|
+
...(intent.action === 'install' && intent.dependencyScopeOverrides
|
|
943
|
+
? { dependencyScopeOverrides: intent.dependencyScopeOverrides }
|
|
944
|
+
: {}),
|
|
933
945
|
...(intent.action === 'cleanup' ? { force: intent.force === true } : {}),
|
|
934
946
|
}, {
|
|
935
947
|
...context,
|
|
@@ -940,15 +952,20 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
940
952
|
expectedGenerationSetDigest: catalogOperation.generationSetDigest,
|
|
941
953
|
} : {}),
|
|
942
954
|
previewDependencyPlanOnly: true,
|
|
955
|
+
...(intent.action === 'sync' ? { reconcileIntentOnly: true } : {}),
|
|
943
956
|
...(preparation ? {
|
|
944
957
|
onPreviewStage: (stage) => stage === 'catalog' ? undefined : preparation.reporter.emit(stage),
|
|
945
958
|
} : {}),
|
|
946
959
|
});
|
|
947
960
|
signal?.throwIfAborted();
|
|
961
|
+
codexReconcilePlans = intent.dependencyPlacementOnly === 'desired'
|
|
962
|
+
? undefined
|
|
963
|
+
: preview?.codexReconcilePlans;
|
|
948
964
|
if (hasDeclaredDependencies
|
|
949
965
|
&& (intent.action === 'install'
|
|
950
966
|
|| intent.action === 'upgrade'
|
|
951
|
-
|| intent.action === 'reinstall'
|
|
967
|
+
|| intent.action === 'reinstall'
|
|
968
|
+
|| intent.action === 'sync')) {
|
|
952
969
|
dependencyPlan = preview.dependencyPlan;
|
|
953
970
|
if (!dependencyPlan) {
|
|
954
971
|
throw new TuiOperationBlockedError('dependencyGraphInvalid', '无法建立可信的依赖安装计划。');
|
|
@@ -959,13 +976,14 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
959
976
|
}
|
|
960
977
|
}
|
|
961
978
|
const managerPreview = preview?.codexManagerPreview;
|
|
962
|
-
if (managerPreview?.state === 'blocked') {
|
|
979
|
+
if (managerPreview?.state === 'blocked' && intent.dependencyPlacementOnly !== 'desired') {
|
|
963
980
|
const message = managerPreview.code === 'codexSystemCliUnsupported'
|
|
964
981
|
? '系统 Codex CLI 版本不受支持。请升级官方 Codex CLI 后重试。'
|
|
965
982
|
: 'AW-managed Codex runtime 当前不可用。请重试、升级 AW,或安装官方 Codex CLI。';
|
|
966
983
|
throw new TuiOperationBlockedError(managerPreview.code, `${managerPreview.code}: ${message}`);
|
|
967
984
|
}
|
|
968
|
-
if (managerPreview
|
|
985
|
+
if (managerPreview && managerPreview.state !== 'blocked'
|
|
986
|
+
&& intent.dependencyPlacementOnly !== 'desired') {
|
|
969
987
|
codexManager = {
|
|
970
988
|
state: managerPreview.state,
|
|
971
989
|
packageName: MANAGED_CODEX_PACKAGE_NAME,
|
|
@@ -977,6 +995,18 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
977
995
|
}
|
|
978
996
|
await preparation?.reporter.emit('evidence');
|
|
979
997
|
signal?.throwIfAborted();
|
|
998
|
+
let projectIntentDigest;
|
|
999
|
+
if (intent.kind === 'pluginWrite' && intent.dependencyPlacementOnly === 'desired') {
|
|
1000
|
+
if (intent.scope !== 'project') {
|
|
1001
|
+
throw new TuiOperationBlockedError('dependencyPlacementScopeInvalid', '缩小依赖位置只能更新当前项目 desired intent。');
|
|
1002
|
+
}
|
|
1003
|
+
projectIntentDigest = calculatePluginIntentDigest(await readPluginIntentState({
|
|
1004
|
+
scope: 'project',
|
|
1005
|
+
cwd: context.cwd,
|
|
1006
|
+
env: context.env,
|
|
1007
|
+
}));
|
|
1008
|
+
signal?.throwIfAborted();
|
|
1009
|
+
}
|
|
980
1010
|
const evidenceTargets = intent.kind === 'configSave' || intent.kind === 'configReset'
|
|
981
1011
|
? configAffectedStatusTargets(status.payload.targets, intent.pluginId, intent.scope)
|
|
982
1012
|
: status.payload.targets;
|
|
@@ -996,6 +1026,8 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
996
1026
|
source: selected.source,
|
|
997
1027
|
...(offlineCleanup ? { offlineCleanup } : {}),
|
|
998
1028
|
...(dependencyPlan ? { dependencyPlan } : {}),
|
|
1029
|
+
...(projectIntentDigest ? { projectIntentDigest } : {}),
|
|
1030
|
+
...(codexReconcilePlans ? { codexReconcilePlans } : {}),
|
|
999
1031
|
...(codexManager ? { codexManager } : {}),
|
|
1000
1032
|
targetFingerprint: statusTargetFingerprint(evidenceTargets, evidenceRevisions),
|
|
1001
1033
|
};
|
|
@@ -1025,7 +1057,10 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1025
1057
|
const dependencies = {
|
|
1026
1058
|
beginCatalogSession(sessionOptions) {
|
|
1027
1059
|
sessionCatalogOperationContext = undefined;
|
|
1028
|
-
|
|
1060
|
+
if (sessionOptions?.reuseValidatedGenerations !== true) {
|
|
1061
|
+
validatedStoreEntries.clear();
|
|
1062
|
+
validatingStoreEntries.clear();
|
|
1063
|
+
}
|
|
1029
1064
|
},
|
|
1030
1065
|
loadStatus,
|
|
1031
1066
|
async inspectSourceRemoval(_sourceId, signal) {
|
|
@@ -1056,14 +1091,14 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1056
1091
|
await reporter.finish();
|
|
1057
1092
|
}
|
|
1058
1093
|
},
|
|
1094
|
+
async previewDependencyPlacement(intent, signal) {
|
|
1095
|
+
const evidence = await captureEvidence(intent, signal);
|
|
1096
|
+
return evidence.dependencyPlan;
|
|
1097
|
+
},
|
|
1059
1098
|
async validateIntent(intent, signal) {
|
|
1060
|
-
if (intent.kind === 'catalogActivate') {
|
|
1061
|
-
await captureEvidence(intent, signal);
|
|
1062
|
-
return;
|
|
1063
|
-
}
|
|
1064
1099
|
if (intent.kind === 'sourceMutation') {
|
|
1065
1100
|
const evidence = await captureEvidence(intent, signal);
|
|
1066
|
-
if (evidence.sourceWrite?.configDigest === evidence.sourceWrite?.
|
|
1101
|
+
if (evidence.sourceWrite?.configDigest === evidence.sourceWrite?.proposedConfigDigest) {
|
|
1067
1102
|
throw new TuiOperationBlockedError('sourceNoChanges', '来源没有变化。');
|
|
1068
1103
|
}
|
|
1069
1104
|
return;
|
|
@@ -1073,7 +1108,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1073
1108
|
await withResolvedCatalogPlugin({
|
|
1074
1109
|
selector: intent.pluginId,
|
|
1075
1110
|
cliVersion: packageInfo.version,
|
|
1076
|
-
freshnessPolicy: 'cacheFirst',
|
|
1077
1111
|
env: context.env,
|
|
1078
1112
|
signal,
|
|
1079
1113
|
...(sessionContextForPlugin(intent.pluginId)
|
|
@@ -1108,89 +1142,45 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1108
1142
|
&& (intent.originIssue.category === 'sourceMissing'
|
|
1109
1143
|
|| intent.originIssue.category === 'sourceUnavailable');
|
|
1110
1144
|
const sourceIds = pluginIds.map((pluginId) => parsePluginId(pluginId).sourceId);
|
|
1111
|
-
|
|
1145
|
+
let catalogOperation = offlineCleanup
|
|
1112
1146
|
? undefined
|
|
1113
1147
|
: sessionCatalogOperationContext
|
|
1114
1148
|
? selectCatalogOperationContext(sessionCatalogOperationContext, sourceIds)
|
|
1115
1149
|
: undefined;
|
|
1116
|
-
const
|
|
1150
|
+
const statusOptions = {
|
|
1117
1151
|
plugins: pluginIds,
|
|
1118
1152
|
platform: intent.platform,
|
|
1119
1153
|
cwd: context.cwd,
|
|
1120
1154
|
env: context.env,
|
|
1121
1155
|
cliVersion: packageInfo.version,
|
|
1122
|
-
...(catalogOperation ? { catalogOperationContext: catalogOperation } : {}),
|
|
1123
|
-
...(offlineCleanup || sessionCatalogOperationContext
|
|
1124
|
-
? { bootstrapMissingActive: false }
|
|
1125
|
-
: {}),
|
|
1126
1156
|
inventoryCatalogSourceReferences: readInventory,
|
|
1157
|
+
};
|
|
1158
|
+
let status = await statusCommandV6({
|
|
1159
|
+
...statusOptions,
|
|
1160
|
+
...(catalogOperation ? { catalogOperationContext: catalogOperation } : {}),
|
|
1127
1161
|
});
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
freshnessPolicy: 'forceRemote',
|
|
1138
|
-
sourceIds: [sourceId],
|
|
1139
|
-
configSnapshot,
|
|
1140
|
-
env: context.env,
|
|
1141
|
-
signal,
|
|
1142
|
-
consume: (catalog) => {
|
|
1143
|
-
const item = catalog.sources[0];
|
|
1144
|
-
if (item.error)
|
|
1145
|
-
throw item.error;
|
|
1146
|
-
return {
|
|
1147
|
-
sourceIdentity: item.resolution.sourceIdentity,
|
|
1148
|
-
requestedRef: item.resolution.requestedRef,
|
|
1149
|
-
};
|
|
1150
|
-
},
|
|
1151
|
-
});
|
|
1152
|
-
},
|
|
1153
|
-
async refreshCatalogSource(sourceId, signal, onState) {
|
|
1154
|
-
let refreshError;
|
|
1155
|
-
let refreshCompleted = false;
|
|
1156
|
-
try {
|
|
1157
|
-
await refreshCatalogSourceGeneration({
|
|
1158
|
-
sourceId,
|
|
1159
|
-
cliVersion: (await readCliPackageInfo()).version,
|
|
1162
|
+
const platforms = intent.platform === 'both'
|
|
1163
|
+
? ['codex', 'claude']
|
|
1164
|
+
: [intent.platform];
|
|
1165
|
+
const missingSelectedTarget = platforms.some((platform) => !status.payload.targets.some((target) => target.pluginId === intent.pluginId
|
|
1166
|
+
&& target.platform === platform
|
|
1167
|
+
&& (platform === 'codex' || target.scope === intent.scope)));
|
|
1168
|
+
if (!offlineCleanup && !catalogOperation && missingSelectedTarget) {
|
|
1169
|
+
catalogOperation = await resolveCatalogOperationContext({
|
|
1170
|
+
sourceIds,
|
|
1160
1171
|
env: context.env,
|
|
1172
|
+
validatedStoreEntries,
|
|
1173
|
+
validatingStoreEntries,
|
|
1161
1174
|
signal,
|
|
1162
|
-
runtime: {
|
|
1163
|
-
...options.catalogGenerationRuntime,
|
|
1164
|
-
onProgress: (event) => onState(event.state),
|
|
1165
|
-
},
|
|
1166
1175
|
});
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1176
|
+
status = await statusCommandV6({
|
|
1177
|
+
...statusOptions,
|
|
1178
|
+
catalogOperationContext: catalogOperation,
|
|
1179
|
+
});
|
|
1171
1180
|
}
|
|
1172
1181
|
signal.throwIfAborted();
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
if (!source)
|
|
1176
|
-
throw refreshError ?? new TuiOperationBlockedError('catalogGenerationSourceMissing', 'Catalog 来源已不存在。');
|
|
1177
|
-
if (refreshError && source.refreshState !== 'failed'
|
|
1178
|
-
&& source.refreshState !== 'immutableViolation')
|
|
1179
|
-
throw refreshError;
|
|
1180
|
-
return {
|
|
1181
|
-
source: refreshCompleted && source.refreshState === 'idle'
|
|
1182
|
-
? { ...source, refreshState: 'upToDate' }
|
|
1183
|
-
: source,
|
|
1184
|
-
};
|
|
1185
|
-
},
|
|
1186
|
-
async setCatalogRefreshPolicy(sourceId, refreshPolicy) {
|
|
1187
|
-
await setCatalogSourceRefreshPolicy({
|
|
1188
|
-
sourceId,
|
|
1189
|
-
refreshPolicy,
|
|
1190
|
-
env: context.env,
|
|
1191
|
-
});
|
|
1192
|
-
return (await loadCatalogGenerationViewModels({ env: context.env }))
|
|
1193
|
-
.find((source) => source.sourceId === sourceId);
|
|
1182
|
+
await assertTypedIssueOrigin(intent, status.payload.targets);
|
|
1183
|
+
assertIntentIsLegal(intent, status.payload.targets, status.targetRevisions);
|
|
1194
1184
|
},
|
|
1195
1185
|
captureEvidence,
|
|
1196
1186
|
logError(_error, code, logContext) {
|
|
@@ -1209,7 +1199,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1209
1199
|
return withResolvedCatalogPlugin({
|
|
1210
1200
|
selector: pluginId,
|
|
1211
1201
|
cliVersion: packageInfo.version,
|
|
1212
|
-
freshnessPolicy: 'cacheFirst',
|
|
1213
1202
|
env: context.env,
|
|
1214
1203
|
signal,
|
|
1215
1204
|
...(sessionContextForPlugin(pluginId)
|
|
@@ -1244,7 +1233,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1244
1233
|
return withResolvedCatalogPlugin({
|
|
1245
1234
|
selector: pluginId,
|
|
1246
1235
|
cliVersion: packageInfo.version,
|
|
1247
|
-
freshnessPolicy: 'cacheFirst',
|
|
1248
1236
|
env: context.env,
|
|
1249
1237
|
signal,
|
|
1250
1238
|
...(sessionContextForPlugin(pluginId)
|
|
@@ -1377,27 +1365,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1377
1365
|
throw error;
|
|
1378
1366
|
}
|
|
1379
1367
|
}
|
|
1380
|
-
if (intent.kind === 'catalogActivate') {
|
|
1381
|
-
const currentEvidence = await captureEvidence(intent, undefined, undefined, false);
|
|
1382
|
-
if (operationEvidenceFingerprint(currentEvidence) !== operationEvidenceFingerprint(expectedEvidence)) {
|
|
1383
|
-
throw operationReviewStale('确认后 Catalog Candidate 发生变化。');
|
|
1384
|
-
}
|
|
1385
|
-
try {
|
|
1386
|
-
return await activateCatalogSourceCandidate({
|
|
1387
|
-
sourceId: intent.sourceId,
|
|
1388
|
-
expectedCandidateGenerationKey: intent.candidateGenerationKey,
|
|
1389
|
-
env: context.env,
|
|
1390
|
-
});
|
|
1391
|
-
}
|
|
1392
|
-
catch (error) {
|
|
1393
|
-
if (error instanceof CatalogGenerationError
|
|
1394
|
-
&& (error.code === 'catalogGenerationCandidateChanged'
|
|
1395
|
-
|| error.code === 'catalogGenerationCandidateUnavailable')) {
|
|
1396
|
-
throw operationReviewStale('确认后 Catalog Candidate 发生变化。');
|
|
1397
|
-
}
|
|
1398
|
-
throw error;
|
|
1399
|
-
}
|
|
1400
|
-
}
|
|
1401
1368
|
if (intent.kind === 'sourceMutation') {
|
|
1402
1369
|
const currentEvidence = await captureEvidence(intent);
|
|
1403
1370
|
if (operationEvidenceFingerprint(currentEvidence) !== operationEvidenceFingerprint(expectedEvidence)) {
|
|
@@ -1437,7 +1404,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1437
1404
|
action: async (awHomeMutationToken) => {
|
|
1438
1405
|
await tuiControllerRuntimeTestHooks?.beforeMutationEvidenceCapture?.();
|
|
1439
1406
|
const operationInventory = createOperationInventoryReader();
|
|
1440
|
-
const currentEvidence = await captureEvidence(intent, undefined, undefined,
|
|
1407
|
+
const currentEvidence = await captureEvidence(intent, undefined, undefined, operationInventory, true);
|
|
1441
1408
|
if (operationEvidenceFingerprint(currentEvidence) !== operationEvidenceFingerprint(expectedEvidence)) {
|
|
1442
1409
|
throw new TuiOperationBlockedError('operationReviewStale', '确认后状态发生变化。');
|
|
1443
1410
|
}
|
|
@@ -1448,10 +1415,34 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1448
1415
|
}
|
|
1449
1416
|
await tuiControllerRuntimeTestHooks?.afterMutationEvidenceCapture?.();
|
|
1450
1417
|
if (intent.kind === 'pluginWrite') {
|
|
1418
|
+
if (intent.dependencyPlacementOnly === 'desired') {
|
|
1419
|
+
const plan = currentEvidence.dependencyPlan;
|
|
1420
|
+
if (!plan || !expectedEvidence.projectIntentDigest) {
|
|
1421
|
+
throw operationReviewStale('确认信息缺少依赖位置或 project intent 证据。');
|
|
1422
|
+
}
|
|
1423
|
+
const location = { scope: 'project', cwd: context.cwd, env: context.env };
|
|
1424
|
+
const currentIntent = await readPluginIntentState(location);
|
|
1425
|
+
if (calculatePluginIntentDigest(currentIntent) !== expectedEvidence.projectIntentDigest) {
|
|
1426
|
+
throw operationReviewStale('确认后 project desired intent 发生变化。');
|
|
1427
|
+
}
|
|
1428
|
+
const plannedKeys = new Set(plan.targets.map((target) => `${target.pluginId}\0${target.platform}`));
|
|
1429
|
+
const nextIntent = canonicalizePluginIntentState({
|
|
1430
|
+
...currentIntent,
|
|
1431
|
+
dependencyScopeOverrides: [
|
|
1432
|
+
...currentIntent.dependencyScopeOverrides.filter((override) => !plannedKeys.has(`${override.pluginId}\0${override.platform}`)),
|
|
1433
|
+
...plan.scopeOverrides,
|
|
1434
|
+
],
|
|
1435
|
+
});
|
|
1436
|
+
await writePluginIntentState(location, nextIntent);
|
|
1437
|
+
return { dependencyPlan: plan, desiredPlacementUpdated: true };
|
|
1438
|
+
}
|
|
1451
1439
|
const options = {
|
|
1452
1440
|
cwd: context.cwd,
|
|
1453
1441
|
platform: intent.platform,
|
|
1454
1442
|
scope: intent.scope,
|
|
1443
|
+
...(intent.action === 'install' && intent.dependencyScopeOverrides
|
|
1444
|
+
? { dependencyScopeOverrides: intent.dependencyScopeOverrides }
|
|
1445
|
+
: {}),
|
|
1455
1446
|
...(expectedEvidence.codexManager?.state === 'requires-install'
|
|
1456
1447
|
? { allowManagedCodexInstall: true }
|
|
1457
1448
|
: {}),
|
|
@@ -1463,6 +1454,7 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1463
1454
|
reinstall: reinstallWriteCommand,
|
|
1464
1455
|
uninstall: uninstallWriteCommand,
|
|
1465
1456
|
cleanup: cleanupWriteCommand,
|
|
1457
|
+
sync: installWriteCommand,
|
|
1466
1458
|
}[intent.action];
|
|
1467
1459
|
const currentSource = currentEvidence.source;
|
|
1468
1460
|
const offlineCleanup = currentEvidence.offlineCleanup;
|
|
@@ -1476,6 +1468,10 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1476
1468
|
...(currentEvidence.dependencyPlan
|
|
1477
1469
|
? { expectedOperationDependencyPlan: currentEvidence.dependencyPlan }
|
|
1478
1470
|
: {}),
|
|
1471
|
+
...(currentEvidence.codexReconcilePlans
|
|
1472
|
+
? { expectedCodexReconcilePlans: currentEvidence.codexReconcilePlans }
|
|
1473
|
+
: {}),
|
|
1474
|
+
...(intent.action === 'sync' ? { reconcileIntentOnly: true } : {}),
|
|
1479
1475
|
expectedCatalogConfigDigest: expectedEvidence.catalog.configDigest,
|
|
1480
1476
|
...(catalogOperation ? {
|
|
1481
1477
|
catalogOperationContext: catalogOperation,
|
|
@@ -1500,7 +1496,6 @@ export function createTuiControllerDependencies(context, progressFeed, options =
|
|
|
1500
1496
|
return withResolvedCatalogPlugin({
|
|
1501
1497
|
selector: intent.pluginId,
|
|
1502
1498
|
cliVersion: packageInfo.version,
|
|
1503
|
-
freshnessPolicy: 'cacheFirst',
|
|
1504
1499
|
env: context.env,
|
|
1505
1500
|
...(catalogOperation ? { operationContext: catalogOperation } : {}),
|
|
1506
1501
|
consume: async ({ plugin, source }) => {
|