@lesliechan721/aw 0.1.0-beta.10 → 0.1.0-beta.12
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-config.d.mts +1 -50
- package/dist/authoring/assets/aw-config.mjs +58 -928
- package/dist/authoring/assets/aw-config.mjs.map +1 -1
- package/dist/authoring/scripts/init-plugin.mjs +28 -33
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.d.mts +1 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +229 -8
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +159 -48
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/bundle-plugins.js +18 -4
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.d.ts +2 -0
- package/dist/scripts/test-plugin-scripts.js +21 -5
- 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 +1 -1
- package/dist/src/commands/aw-capabilities.js.map +1 -1
- package/dist/src/commands/catalog-dev-source.d.ts +6 -3
- package/dist/src/commands/catalog-dev-source.js +96 -35
- package/dist/src/commands/catalog-dev-source.js.map +1 -1
- package/dist/src/commands/catalog-publication-inspection.d.ts +1 -1
- package/dist/src/commands/catalog-publication-inspection.js +54 -8
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-journal.js +1 -1
- package/dist/src/commands/catalog-publication-journal.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +19 -4
- package/dist/src/commands/catalog-source.js +121 -12
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-store.d.ts +26 -7
- package/dist/src/commands/catalog-store.js +361 -42
- package/dist/src/commands/catalog-store.js.map +1 -1
- package/dist/src/commands/console.js +28 -17
- package/dist/src/commands/console.js.map +1 -1
- package/dist/src/commands/operation-plan.d.ts +2 -1
- package/dist/src/commands/operation-plan.js +24 -0
- package/dist/src/commands/operation-plan.js.map +1 -1
- package/dist/src/commands/operation-planner.d.ts +2 -2
- package/dist/src/commands/operation-planner.js +22 -20
- package/dist/src/commands/operation-planner.js.map +1 -1
- package/dist/src/commands/options.d.ts +2 -2
- package/dist/src/commands/options.js +18 -4
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +2 -2
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +19 -0
- package/dist/src/commands/rebuild-command.js +828 -283
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +25 -47
- package/dist/src/commands/rebuild-integration.js +1176 -1016
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +50 -12
- package/dist/src/commands/rebuild-operations.js +207 -101
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/status-v6.d.ts +21 -2
- package/dist/src/commands/status-v6.js +163 -31
- package/dist/src/commands/status-v6.js.map +1 -1
- package/dist/src/commands/sync-command.d.ts +17 -0
- package/dist/src/commands/sync-command.js +45 -37
- package/dist/src/commands/sync-command.js.map +1 -1
- package/dist/src/commands/write-commands.d.ts +5 -0
- package/dist/src/commands/write-commands.js +50 -3
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/generators/local-plugin.js +14 -4
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.js +260 -91
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/command-receipt.js +1 -3
- package/dist/src/output/command-receipt.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +1 -3
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/materializer.js +10 -8
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.js +41 -1
- package/dist/src/tui/catalog-generation.js.map +1 -1
- package/dist/src/tui/catalog-sources/session.d.ts +1 -0
- package/dist/src/tui/catalog-sources/session.js +16 -3
- package/dist/src/tui/catalog-sources/session.js.map +1 -1
- package/dist/src/tui/catalog-sources/types.d.ts +3 -2
- package/dist/src/tui/components.d.ts +4 -0
- package/dist/src/tui/components.js +36 -24
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.d.ts +13 -4
- package/dist/src/tui/console-app-v4.js +2065 -857
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.js +731 -62
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +156 -10
- package/dist/src/tui/controller.js +1187 -163
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostic-projection.d.ts +22 -0
- package/dist/src/tui/diagnostic-projection.js +437 -0
- package/dist/src/tui/diagnostic-projection.js.map +1 -0
- package/dist/src/tui/diagnostics.d.ts +1 -1
- package/dist/src/tui/diagnostics.js +7 -2
- package/dist/src/tui/diagnostics.js.map +1 -1
- package/dist/src/tui/glossary.d.ts +23 -0
- package/dist/src/tui/glossary.js +42 -0
- package/dist/src/tui/glossary.js.map +1 -0
- package/dist/src/tui/index.d.ts +4 -1
- package/dist/src/tui/index.js +4 -1
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/keys.d.ts +44 -0
- package/dist/src/tui/keys.js +43 -15
- package/dist/src/tui/keys.js.map +1 -1
- package/dist/src/tui/lifecycle-action-view.d.ts +6 -0
- package/dist/src/tui/lifecycle-action-view.js +34 -0
- package/dist/src/tui/lifecycle-action-view.js.map +1 -0
- package/dist/src/tui/model.d.ts +12 -2
- package/dist/src/tui/model.js +128 -52
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/operation-diagnostic-screens.d.ts +21 -0
- package/dist/src/tui/operation-diagnostic-screens.js +101 -0
- package/dist/src/tui/operation-diagnostic-screens.js.map +1 -0
- package/dist/src/tui/operation-history.d.ts +80 -0
- package/dist/src/tui/operation-history.js +130 -0
- package/dist/src/tui/operation-history.js.map +1 -0
- package/dist/src/tui/operation-review-planner.js +366 -99
- package/dist/src/tui/operation-review-planner.js.map +1 -1
- package/dist/src/tui/router.d.ts +82 -17
- package/dist/src/tui/router.js +186 -38
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/screen-registry.d.ts +546 -0
- package/dist/src/tui/screen-registry.js +179 -0
- package/dist/src/tui/screen-registry.js.map +1 -0
- package/dist/src/tui/session-console-app.d.ts +6 -0
- package/dist/src/tui/session-console-app.js +13 -0
- package/dist/src/tui/session-console-app.js.map +1 -0
- package/dist/src/tui/session-host.d.ts +44 -0
- package/dist/src/tui/session-host.js +197 -0
- package/dist/src/tui/session-host.js.map +1 -0
- package/dist/src/types.d.ts +64 -3
- package/dist/src/types.js +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.js +1 -1
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/artifact-plan.d.ts +2 -2
- package/dist/src/utils/artifact-plan.js +8 -6
- package/dist/src/utils/artifact-plan.js.map +1 -1
- package/dist/src/utils/artifact-renderer.d.ts +2 -1
- package/dist/src/utils/artifact-renderer.js +139 -120
- package/dist/src/utils/artifact-renderer.js.map +1 -1
- package/dist/src/utils/artifact-request.d.ts +5 -0
- package/dist/src/utils/artifact-request.js +40 -0
- package/dist/src/utils/artifact-request.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +4 -4
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-capability-projection.d.ts +8 -0
- package/dist/src/utils/catalog-capability-projection.js +14 -0
- package/dist/src/utils/catalog-capability-projection.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +14 -2
- package/dist/src/utils/catalog-generation-resolver.js +49 -27
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -1
- package/dist/src/utils/catalog-generation-service.d.ts +8 -1
- package/dist/src/utils/catalog-generation-service.js +81 -47
- package/dist/src/utils/catalog-generation-service.js.map +1 -1
- package/dist/src/utils/catalog-generation-store.d.ts +1 -0
- package/dist/src/utils/catalog-generation-store.js +60 -5
- package/dist/src/utils/catalog-generation-store.js.map +1 -1
- package/dist/src/utils/catalog-operation-context.js +1 -0
- package/dist/src/utils/catalog-operation-context.js.map +1 -1
- package/dist/src/utils/catalog-public-error.js +4 -0
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-source-impact.d.ts +3 -2
- package/dist/src/utils/catalog-source-impact.js +142 -20
- package/dist/src/utils/catalog-source-impact.js.map +1 -1
- package/dist/src/utils/catalog-source-references.js +95 -9
- package/dist/src/utils/catalog-source-references.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +1 -1
- package/dist/src/utils/catalog-sources.js +19 -3
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-manager.js +8 -0
- package/dist/src/utils/codex-manager.js.map +1 -1
- package/dist/src/utils/codex-native-observation.d.ts +34 -1
- package/dist/src/utils/codex-native-observation.js +132 -0
- package/dist/src/utils/codex-native-observation.js.map +1 -1
- package/dist/src/utils/codex-reconciler.d.ts +0 -2
- package/dist/src/utils/codex-reconciler.js.map +1 -1
- package/dist/src/utils/codex-shared-native.d.ts +2 -26
- package/dist/src/utils/codex-shared-native.js +8 -82
- package/dist/src/utils/codex-shared-native.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.d.ts +3 -0
- package/dist/src/utils/git-catalog-provider.js +40 -1
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/local-marketplace.d.ts +1 -0
- package/dist/src/utils/local-marketplace.js +69 -73
- package/dist/src/utils/local-marketplace.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.js +1 -0
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +9 -4
- package/dist/src/utils/native-cli.js +280 -34
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.js +2 -0
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/plugin-config-impact.d.ts +33 -0
- package/dist/src/utils/plugin-config-impact.js +298 -0
- package/dist/src/utils/plugin-config-impact.js.map +1 -0
- package/dist/src/utils/plugin-config-write.d.ts +36 -14
- package/dist/src/utils/plugin-config-write.js +709 -225
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +58 -4
- package/dist/src/utils/plugin-config.js +328 -60
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-scripts.d.ts +20 -12
- package/dist/src/utils/plugin-scripts.js +389 -114
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/process-tree.d.ts +2 -2
- package/dist/src/utils/process-tree.js +1 -1
- package/dist/src/utils/process-tree.js.map +1 -1
- package/dist/src/utils/project-boundary.d.ts +11 -1
- package/dist/src/utils/project-boundary.js +33 -11
- package/dist/src/utils/project-boundary.js.map +1 -1
- package/dist/src/utils/safe-operation-diagnostic.d.ts +15 -0
- package/dist/src/utils/safe-operation-diagnostic.js +33 -0
- package/dist/src/utils/safe-operation-diagnostic.js.map +1 -0
- package/dist/src/utils/sensitive-content.d.ts +4 -0
- package/dist/src/utils/sensitive-content.js +36 -0
- package/dist/src/utils/sensitive-content.js.map +1 -0
- package/dist/src/utils/windows-claude-shim.d.ts +9 -0
- package/dist/src/utils/windows-claude-shim.js +141 -0
- package/dist/src/utils/windows-claude-shim.js.map +1 -0
- package/dist/vitest.config.js +91 -10
- package/dist/vitest.config.js.map +1 -1
- package/package.json +9 -9
- package/dist/authoring/templates/aw-config-runtime.d.mts +0 -2
- package/dist/authoring/templates/aw-config-runtime.mjs +0 -407
- package/dist/authoring/templates/aw-config-runtime.mjs.map +0 -1
|
@@ -5,6 +5,7 @@ import { previewCodexManager, resolveCodexOperationConsumer, } from '../utils/co
|
|
|
5
5
|
import { createNoopDebugLogger } from '../output/debug-log.js';
|
|
6
6
|
import { createNoopReporter } from '../output/reporter.js';
|
|
7
7
|
import { getDefaultNativeCliRunner, } from '../utils/native-cli.js';
|
|
8
|
+
import { createCodexNativeObservationSession } from '../utils/codex-native-observation.js';
|
|
8
9
|
import { readPluginManifest } from '../utils/manifest.js';
|
|
9
10
|
import { resolveAwHome, resolveCodexPaths } from '../utils/paths.js';
|
|
10
11
|
import { resolveCliPackageRoot } from '../utils/paths.js';
|
|
@@ -13,8 +14,8 @@ import { analyzeCodexSurface } from '../utils/codex-surface-analysis.js';
|
|
|
13
14
|
import { buildGeneratedName } from '../generators/shared.js';
|
|
14
15
|
import { createCodexReconcilePlan, } from '../utils/codex-reconciler.js';
|
|
15
16
|
import { readCodexConfigFile } from '../utils/codex-config.js';
|
|
16
|
-
import { executeRebuildOperation, } from './rebuild-operations.js';
|
|
17
|
-
import { assertNoClaudeUnboundNativeNameCollision, CodexActivationPostcheckError, createRebuildIntegration, executeCodexReconcileActivations, inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, inspectNativeMarketplaceRegistrations, } from './rebuild-integration.js';
|
|
17
|
+
import { executeRebuildComponentCleanup, executeRebuildOperation, prepareRebuildOperation, } from './rebuild-operations.js';
|
|
18
|
+
import { assertNoClaudeUnboundNativeNameCollision, CodexActivationPostcheckError, createRebuildIntegration, executeCodexReconcileActivations, inspectCodexPluginRegistrationLive, inspectCodexSharedNativeLive, inspectNativeMarketplaceRegistrations, postcheckCodexReconcileActivations, } from './rebuild-integration.js';
|
|
18
19
|
import { getNamespacedMarketplaceName } from '../utils/local-marketplace.js';
|
|
19
20
|
import { formatPluginId, parsePluginId, planPluginSelectorSourceIds, preflightDesiredArtifactCollisions, withResolvedMultiSourceCatalog, } from '../utils/multi-source-catalog.js';
|
|
20
21
|
import { calculateCodexNativeRenderPayloadDigest, calculateCodexSharedNativePayloadDigest, } from '../utils/catalog-digests.js';
|
|
@@ -32,8 +33,7 @@ import { readCatalogSourcesConfigSnapshot } from '../utils/catalog-sources.js';
|
|
|
32
33
|
import { catalogGenerationErrorCode, isOfflineCleanupCatalogGenerationError, } from '../utils/catalog-generation-error.js';
|
|
33
34
|
import { canonicalizePluginIntentState, calculatePluginIntentDigest, createEmptyPluginIntentState, mergePluginIntentRootPlatforms, readPluginIntentState, removePluginIntentRootPlatforms, writePluginIntentState, } from '../utils/plugin-intent-state.js';
|
|
34
35
|
import { assertOperationPlanFingerprint, createOperationPlanConfigDigest, createOperationPlan, } from './operation-plan.js';
|
|
35
|
-
import { validateCatalogSnapshotPluginEntriesComplete } from '../utils/catalog-snapshot.js';
|
|
36
|
-
import { runPostApplyScript } from '../utils/plugin-scripts.js';
|
|
36
|
+
import { validateCatalogSnapshotComplete, validateCatalogSnapshotPluginEntriesComplete, } from '../utils/catalog-snapshot.js';
|
|
37
37
|
import { AwCapabilityUnsupportedError, IMPLEMENTED_AW_CAPABILITIES, } from './aw-capabilities.js';
|
|
38
38
|
import { checkAwCapabilitySupport } from '../utils/manifest.js';
|
|
39
39
|
import { createDependencyPlacementPlan, } from './dependency-operation-plan.js';
|
|
@@ -86,6 +86,7 @@ function assertRebuildCatalogSourceInventoryComplete(inventory, targetScope) {
|
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
const MALFORMED_CONFIG_PRESERVED_WARNING = 'pluginConfigPreserved: 目标插件的无效配置文件已保留。可稍后运行 aw config reset 清理。';
|
|
89
|
+
const OBSOLETE_CONTRACTS_CLEANUP_WARNING = 'obsoleteContractsCleanupFailed: Obsolete installation contracts could not be removed.';
|
|
89
90
|
function omitSelectedPluginConfigErrors(inventory, targets) {
|
|
90
91
|
let omitted = false;
|
|
91
92
|
const errors = inventory.errors.filter((error) => {
|
|
@@ -326,9 +327,11 @@ function toTargetResult(result) {
|
|
|
326
327
|
state: result.status === 'succeeded' ? 'completed' : 'failed',
|
|
327
328
|
...(result.status === 'failed' ? {
|
|
328
329
|
message: result.error.message,
|
|
329
|
-
errorCode:
|
|
330
|
-
?
|
|
331
|
-
:
|
|
330
|
+
errorCode: result.error.phase === 'preApply'
|
|
331
|
+
? 'preApplyFailed'
|
|
332
|
+
: errorPrefix && /^[A-Za-z][A-Za-z0-9]*$/u.test(errorPrefix)
|
|
333
|
+
? errorPrefix
|
|
334
|
+
: 'writeFailed',
|
|
332
335
|
} : {}),
|
|
333
336
|
};
|
|
334
337
|
}
|
|
@@ -365,6 +368,8 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
365
368
|
...(options.runtime?.codexManager ? { codexManager: options.runtime.codexManager } : {}),
|
|
366
369
|
expectedCatalogConfigDigest: options.runtime?.expectedCatalogConfigDigest,
|
|
367
370
|
codexUserActivationDesired: options.runtime?.codexUserActivationDesired,
|
|
371
|
+
codexObservationSession: options.runtime?.codexObservationSession,
|
|
372
|
+
preApplyExecutionCache: options.runtime?.preApplyExecutionCache,
|
|
368
373
|
};
|
|
369
374
|
const env = runtime.env;
|
|
370
375
|
const selected = selectedPlatforms(options.commandOptions.platform);
|
|
@@ -392,6 +397,7 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
392
397
|
for (const plugin of catalogPlugins) {
|
|
393
398
|
plugin.sourceId = options.runtime.namespacedSource.sourceId;
|
|
394
399
|
plugin.sourceIdentity = options.runtime.namespacedSource.sourceIdentity;
|
|
400
|
+
plugin.catalogLogicalIdentity = options.runtime.namespacedSource.logicalIdentity;
|
|
395
401
|
plugin.pluginId = formatPluginId({
|
|
396
402
|
sourceId: options.runtime.namespacedSource.sourceId,
|
|
397
403
|
pluginName: plugin.manifest.name,
|
|
@@ -411,7 +417,7 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
411
417
|
}
|
|
412
418
|
}
|
|
413
419
|
const platforms = selected.filter((platform) => (requestedByPlatform.get(platform)?.length ?? 0) > 0);
|
|
414
|
-
const integration = createRebuildIntegration({
|
|
420
|
+
const integration = options.execution?.integration ?? createRebuildIntegration({
|
|
415
421
|
context: runtime,
|
|
416
422
|
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
417
423
|
...(options.execution?.prepared
|
|
@@ -421,11 +427,6 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
421
427
|
const targets = [];
|
|
422
428
|
const results = [];
|
|
423
429
|
const warnings = [];
|
|
424
|
-
const recordWarning = (error) => {
|
|
425
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
426
|
-
if (!warnings.includes(message))
|
|
427
|
-
warnings.push(message);
|
|
428
|
-
};
|
|
429
430
|
for (const platform of platforms) {
|
|
430
431
|
for (const pluginName of requestedByPlatform.get(platform) ?? []) {
|
|
431
432
|
const currentPlugin = catalogByName.get(pluginName);
|
|
@@ -497,72 +498,34 @@ async function runSingleSourceRebuildCommand(options) {
|
|
|
497
498
|
...options.runtime.resolvedReviewEvidenceByPlugin?.[pluginName],
|
|
498
499
|
});
|
|
499
500
|
}
|
|
500
|
-
const driver =
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
});
|
|
518
|
-
await emit({ name: 'postApply', phase: 'start' });
|
|
519
|
-
try {
|
|
520
|
-
await integration.driver.runPostApply(invocation);
|
|
521
|
-
}
|
|
522
|
-
catch (error) {
|
|
523
|
-
await emit({
|
|
524
|
-
name: 'postApply',
|
|
525
|
-
phase: 'failure',
|
|
526
|
-
durationMs: Math.max(0, Date.now() - startedAt),
|
|
527
|
-
message: '运行 postApply 失败。',
|
|
528
|
-
});
|
|
529
|
-
throw error;
|
|
530
|
-
}
|
|
531
|
-
await emit({
|
|
532
|
-
name: 'postApply',
|
|
533
|
-
phase: 'success',
|
|
534
|
-
durationMs: Math.max(0, Date.now() - startedAt),
|
|
535
|
-
});
|
|
536
|
-
},
|
|
537
|
-
onFailure: (error) => {
|
|
538
|
-
recordWarning(error);
|
|
539
|
-
const action = result.actions.find((entry) => entry.name === 'postApply');
|
|
540
|
-
if (action)
|
|
541
|
-
action.status = 'failed';
|
|
542
|
-
},
|
|
543
|
-
});
|
|
544
|
-
},
|
|
501
|
+
const driver = integration.driver;
|
|
502
|
+
let operationPreparation = options.execution?.operationPreparation;
|
|
503
|
+
if (options.execution?.skipPreApply
|
|
504
|
+
&& !operationPreparation
|
|
505
|
+
&& (options.command === 'install'
|
|
506
|
+
|| options.command === 'sync'
|
|
507
|
+
|| options.command === 'reinstall')) {
|
|
508
|
+
const prepared = await prepareRebuildOperation({
|
|
509
|
+
command: options.command,
|
|
510
|
+
target,
|
|
511
|
+
driver,
|
|
512
|
+
skipPreApply: true,
|
|
513
|
+
onActionEvent: (event) => emitRebuildActionEvent(runtime, event),
|
|
514
|
+
});
|
|
515
|
+
if (prepared.status === 'failed') {
|
|
516
|
+
results.push(prepared.result);
|
|
517
|
+
continue;
|
|
545
518
|
}
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
runPostApply: async (invocation) => {
|
|
549
|
-
try {
|
|
550
|
-
await integration.driver.runPostApply(invocation);
|
|
551
|
-
}
|
|
552
|
-
catch (error) {
|
|
553
|
-
recordWarning(error);
|
|
554
|
-
throw error;
|
|
555
|
-
}
|
|
556
|
-
},
|
|
557
|
-
};
|
|
519
|
+
operationPreparation = prepared.preparation;
|
|
520
|
+
}
|
|
558
521
|
result = await executeRebuildOperation({
|
|
559
522
|
command: options.command,
|
|
560
523
|
target,
|
|
561
524
|
driver,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
525
|
+
...(operationPreparation
|
|
526
|
+
? { preparation: operationPreparation }
|
|
527
|
+
: {}),
|
|
528
|
+
onActionEvent: (event) => emitRebuildActionEvent(runtime, event),
|
|
566
529
|
});
|
|
567
530
|
}
|
|
568
531
|
catch (error) {
|
|
@@ -631,7 +594,7 @@ function mergeRebuildCommandResults(results) {
|
|
|
631
594
|
: {}),
|
|
632
595
|
};
|
|
633
596
|
}
|
|
634
|
-
function reconcileOverallState(targetResults, plan) {
|
|
597
|
+
function reconcileOverallState(targetResults, plan, rebuildResults = []) {
|
|
635
598
|
const failed = targetResults.some((result) => result.state === 'failed' || result.action === 'skipped');
|
|
636
599
|
if (!failed)
|
|
637
600
|
return 'succeeded';
|
|
@@ -642,7 +605,15 @@ function reconcileOverallState(targetResults, plan) {
|
|
|
642
605
|
&& result.action !== 'skipped'
|
|
643
606
|
&& result.target.pluginId !== undefined
|
|
644
607
|
&& requested.has(`${result.target.pluginId}\0${result.target.platform}`));
|
|
645
|
-
|
|
608
|
+
const completedMutation = targetResults.some((result) => result.state === 'completed'
|
|
609
|
+
&& result.action !== 'keep'
|
|
610
|
+
&& result.action !== 'skipped');
|
|
611
|
+
const observedMutation = rebuildResults.some((result) => result.actions.some((action) => action.status === 'succeeded'
|
|
612
|
+
&& (action.name === 'stale.cleanup'
|
|
613
|
+
|| action.name === 'native.write'
|
|
614
|
+
|| action.name === 'artifacts.write'
|
|
615
|
+
|| action.name === 'cleanup.owned')));
|
|
616
|
+
return completedRequested || completedMutation || observedMutation ? 'partial' : 'failed';
|
|
646
617
|
}
|
|
647
618
|
function createRebuildOperationPlan(options) {
|
|
648
619
|
const selectedRoots = [...new Map(options.dependencyPlan.targets.flatMap((target) => target.relation === 'requested'
|
|
@@ -931,8 +902,8 @@ async function cleanupOfflineOwnedComponents(options) {
|
|
|
931
902
|
try {
|
|
932
903
|
await (options.removeObsoleteInstallationContracts ?? fs.remove)(obsoleteContracts);
|
|
933
904
|
}
|
|
934
|
-
catch
|
|
935
|
-
warnings.push(
|
|
905
|
+
catch {
|
|
906
|
+
warnings.push(OBSOLETE_CONTRACTS_CLEANUP_WARNING);
|
|
936
907
|
}
|
|
937
908
|
return leaseSafeRebuildResult({
|
|
938
909
|
platforms: [...new Set(results.map((result) => result.target.platform))],
|
|
@@ -1034,6 +1005,7 @@ async function buildForceExclusiveCleanupPlan(options) {
|
|
|
1034
1005
|
const pluginId = formatPluginId({ sourceId, pluginName: parsed.pluginName });
|
|
1035
1006
|
plugin.sourceId = sourceId;
|
|
1036
1007
|
plugin.sourceIdentity = active.sourceIdentity;
|
|
1008
|
+
plugin.catalogLogicalIdentity = active.logicalIdentity;
|
|
1037
1009
|
plugin.pluginId = pluginId;
|
|
1038
1010
|
plugin.marketplaceName = sourceId === options.primarySourceId ? 'aw' : `aw-${sourceId}`;
|
|
1039
1011
|
const context = {
|
|
@@ -1179,7 +1151,7 @@ async function buildLiveForceExclusiveCleanupPlan(options) {
|
|
|
1179
1151
|
writeNativeRequired: false,
|
|
1180
1152
|
artifacts: [],
|
|
1181
1153
|
operationActions: [],
|
|
1182
|
-
|
|
1154
|
+
preApplySource: plugin,
|
|
1183
1155
|
forceExclusiveCleanup: true,
|
|
1184
1156
|
});
|
|
1185
1157
|
evidence.push(await forceOfflineCleanupEvidence({
|
|
@@ -1228,7 +1200,7 @@ async function mergeForceCleanupPlans(...plans) {
|
|
|
1228
1200
|
}))),
|
|
1229
1201
|
};
|
|
1230
1202
|
}
|
|
1231
|
-
|
|
1203
|
+
async function runRebuildCommandInSession(options) {
|
|
1232
1204
|
const runtimeEnv = options.runtime?.env ?? process.env;
|
|
1233
1205
|
const readInventory = options.runtime?.inventoryCatalogSourceReferences
|
|
1234
1206
|
?? inventoryCatalogSourceReferences;
|
|
@@ -1338,7 +1310,7 @@ export async function runRebuildCommand(options) {
|
|
|
1338
1310
|
}
|
|
1339
1311
|
return mergeRebuildCommandResults([]);
|
|
1340
1312
|
}
|
|
1341
|
-
if (options.command === 'cleanup') {
|
|
1313
|
+
if (options.command === 'cleanup' && !options.all) {
|
|
1342
1314
|
if (cleanupForce) {
|
|
1343
1315
|
const requestedPlatforms = selectedPlatforms(options.commandOptions.platform);
|
|
1344
1316
|
const cleanupSourceSnapshot = await readCatalogSourcesConfigSnapshot(runtimeEnv).catch(() => undefined);
|
|
@@ -1512,8 +1484,8 @@ export async function runRebuildCommand(options) {
|
|
|
1512
1484
|
try {
|
|
1513
1485
|
await (options.runtime?.removeObsoleteInstallationContracts ?? fs.remove)(path.join(resolveAwHome(runtimeEnv), 'installation-contracts'));
|
|
1514
1486
|
}
|
|
1515
|
-
catch
|
|
1516
|
-
result.warnings.push(
|
|
1487
|
+
catch {
|
|
1488
|
+
result.warnings.push(OBSOLETE_CONTRACTS_CLEANUP_WARNING);
|
|
1517
1489
|
}
|
|
1518
1490
|
}
|
|
1519
1491
|
return result;
|
|
@@ -1597,13 +1569,6 @@ export async function runRebuildCommand(options) {
|
|
|
1597
1569
|
pluginId: formatPluginId({ sourceId: source.sourceId, pluginName: entry.name }),
|
|
1598
1570
|
}));
|
|
1599
1571
|
});
|
|
1600
|
-
const intentCatalogEntries = availableEntries.map((candidate) => ({
|
|
1601
|
-
pluginId: candidate.pluginId,
|
|
1602
|
-
dependencyPluginIds: candidate.entry.dependencies.map((dependency) => formatPluginId({
|
|
1603
|
-
sourceId: candidate.source.sourceId,
|
|
1604
|
-
pluginName: dependency,
|
|
1605
|
-
})),
|
|
1606
|
-
}));
|
|
1607
1572
|
const selectedEntries = selectors.map((selector, index) => {
|
|
1608
1573
|
const matches = availableEntries.filter((candidate) => candidate.entry.name === selector.pluginName
|
|
1609
1574
|
&& (selector.sourceId === undefined || candidate.source.sourceId === selector.sourceId));
|
|
@@ -1615,6 +1580,24 @@ export async function runRebuildCommand(options) {
|
|
|
1615
1580
|
}
|
|
1616
1581
|
return matches[0];
|
|
1617
1582
|
});
|
|
1583
|
+
if (options.command === 'uninstall' || (options.command === 'cleanup' && options.all)) {
|
|
1584
|
+
await measureCommandPerformanceStage(options.runtime, 'catalog.validation', async () => {
|
|
1585
|
+
const selectedSources = new Map(selectedEntries.map((candidate) => [
|
|
1586
|
+
candidate.source.sourceId,
|
|
1587
|
+
candidate.source,
|
|
1588
|
+
]));
|
|
1589
|
+
for (const source of selectedSources.values()) {
|
|
1590
|
+
await validateCatalogSnapshotComplete(source.rootDir);
|
|
1591
|
+
}
|
|
1592
|
+
});
|
|
1593
|
+
}
|
|
1594
|
+
const intentCatalogEntries = availableEntries.map((candidate) => ({
|
|
1595
|
+
pluginId: candidate.pluginId,
|
|
1596
|
+
dependencyPluginIds: candidate.entry.dependencies.map((dependency) => formatPluginId({
|
|
1597
|
+
sourceId: candidate.source.sourceId,
|
|
1598
|
+
pluginName: dependency,
|
|
1599
|
+
})),
|
|
1600
|
+
}));
|
|
1618
1601
|
const dependencyEnabled = options.command === 'install'
|
|
1619
1602
|
|| options.command === 'sync'
|
|
1620
1603
|
|| options.command === 'reinstall';
|
|
@@ -1682,6 +1665,7 @@ export async function runRebuildCommand(options) {
|
|
|
1682
1665
|
const plugin = await readPluginManifest(path.join(candidate.source.rootDir, 'plugins', candidate.entry.name), { mode: 'bundle' });
|
|
1683
1666
|
plugin.sourceId = candidate.source.sourceId;
|
|
1684
1667
|
plugin.sourceIdentity = candidate.source.sourceIdentity;
|
|
1668
|
+
plugin.catalogLogicalIdentity = candidate.source.logicalIdentity;
|
|
1685
1669
|
plugin.pluginId = candidate.pluginId;
|
|
1686
1670
|
return { source: candidate.source, plugin, pluginId: candidate.pluginId };
|
|
1687
1671
|
}));
|
|
@@ -1905,12 +1889,41 @@ export async function runRebuildCommand(options) {
|
|
|
1905
1889
|
}
|
|
1906
1890
|
return marketplaceName;
|
|
1907
1891
|
};
|
|
1892
|
+
const codexObservationScopeByMarketplace = new Map();
|
|
1893
|
+
const projectIntentPluginIds = new Set();
|
|
1894
|
+
for (const root of intentBeforeByScope.project.roots.filter((candidate) => candidate.platforms.includes('codex'))) {
|
|
1895
|
+
const rootEntry = availableEntries.find((candidate) => candidate.pluginId === root.pluginId);
|
|
1896
|
+
if (!rootEntry)
|
|
1897
|
+
continue;
|
|
1898
|
+
for (const candidate of entryClosure([rootEntry])) {
|
|
1899
|
+
projectIntentPluginIds.add(candidate.pluginId);
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
const projectCodexConfig = await readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath);
|
|
1903
|
+
for (const { entry, platform } of executionSelections) {
|
|
1904
|
+
if (platform !== 'codex')
|
|
1905
|
+
continue;
|
|
1906
|
+
const marketplaceName = marketplaceNameFor(entry, platform, options.commandOptions.scope);
|
|
1907
|
+
const codexPluginId = `${entry.plugin.manifest.name}@${marketplaceName}`;
|
|
1908
|
+
const requiredScope = options.commandOptions.scope === 'project'
|
|
1909
|
+
|| projectIntentPluginIds.has(entry.pluginId)
|
|
1910
|
+
|| Object.hasOwn(projectCodexConfig.snapshot.plugins, codexPluginId)
|
|
1911
|
+
? 'both'
|
|
1912
|
+
: 'user';
|
|
1913
|
+
if (requiredScope === 'both'
|
|
1914
|
+
|| !codexObservationScopeByMarketplace.has(marketplaceName)) {
|
|
1915
|
+
codexObservationScopeByMarketplace.set(marketplaceName, requiredScope);
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1908
1918
|
const executionContext = {
|
|
1909
1919
|
env: runtimeEnv,
|
|
1910
1920
|
nativeCliRunner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
1911
1921
|
reporter: options.runtime?.reporter ?? createNoopReporter(),
|
|
1912
1922
|
debugLogger: options.runtime?.debugLogger ?? createNoopDebugLogger(),
|
|
1913
1923
|
expectedCatalogConfigDigest: catalog.configDigest,
|
|
1924
|
+
codexObservationSession: options.runtime?.codexObservationSession,
|
|
1925
|
+
codexObservationScopeByMarketplace,
|
|
1926
|
+
preApplyExecutionCache: options.runtime?.preApplyExecutionCache,
|
|
1914
1927
|
};
|
|
1915
1928
|
const inspection = createRebuildIntegration({
|
|
1916
1929
|
context: executionContext,
|
|
@@ -1925,6 +1938,43 @@ export async function runRebuildCommand(options) {
|
|
|
1925
1938
|
: []),
|
|
1926
1939
|
}]]
|
|
1927
1940
|
: [])).values()];
|
|
1941
|
+
const intentPlanForPreparedRoots = (plan, preparedKeys) => {
|
|
1942
|
+
const retainedRootKeys = new Set(plan.targets.flatMap((target) => target.relation === 'requested'
|
|
1943
|
+
&& preparedKeys.has(`${target.pluginId}\0${target.platform}`)
|
|
1944
|
+
? [`${target.pluginId}\0${target.platform}`]
|
|
1945
|
+
: []));
|
|
1946
|
+
const closureKeys = new Set(retainedRootKeys);
|
|
1947
|
+
const pending = [...closureKeys];
|
|
1948
|
+
while (pending.length > 0) {
|
|
1949
|
+
const consumerKey = pending.pop();
|
|
1950
|
+
for (const edge of plan.dependencyEdges) {
|
|
1951
|
+
if (`${edge.from}\0${edge.platform}` !== consumerKey)
|
|
1952
|
+
continue;
|
|
1953
|
+
const dependencyKey = `${edge.to}\0${edge.platform}`;
|
|
1954
|
+
if (closureKeys.has(dependencyKey))
|
|
1955
|
+
continue;
|
|
1956
|
+
closureKeys.add(dependencyKey);
|
|
1957
|
+
pending.push(dependencyKey);
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
return {
|
|
1961
|
+
plan: {
|
|
1962
|
+
...plan,
|
|
1963
|
+
requestedPluginIds: plan.requestedPluginIds.filter((pluginId) => plan.targets.some((target) => target.pluginId === pluginId
|
|
1964
|
+
&& retainedRootKeys.has(`${target.pluginId}\0${target.platform}`))),
|
|
1965
|
+
resolvedPluginIds: plan.resolvedPluginIds.filter((pluginId) => plan.targets.some((target) => target.pluginId === pluginId
|
|
1966
|
+
&& closureKeys.has(`${target.pluginId}\0${target.platform}`))),
|
|
1967
|
+
dependencyEdges: plan.dependencyEdges.filter((edge) => closureKeys.has(`${edge.from}\0${edge.platform}`)
|
|
1968
|
+
&& closureKeys.has(`${edge.to}\0${edge.platform}`)),
|
|
1969
|
+
scopeOverrides: plan.scopeOverrides.filter((override) => closureKeys.has(`${override.pluginId}\0${override.platform}`)),
|
|
1970
|
+
targets: plan.targets.filter((target) => closureKeys.has(`${target.pluginId}\0${target.platform}`)),
|
|
1971
|
+
},
|
|
1972
|
+
selectedRoots: selectedRootsForPlan(plan).flatMap((root) => {
|
|
1973
|
+
const platforms = root.platforms.filter((platform) => retainedRootKeys.has(`${root.pluginId}\0${platform}`));
|
|
1974
|
+
return platforms.length > 0 ? [{ ...root, platforms }] : [];
|
|
1975
|
+
}),
|
|
1976
|
+
};
|
|
1977
|
+
};
|
|
1928
1978
|
let plannedCodexRegistrations = new Map();
|
|
1929
1979
|
let plannedOwnedTextTargets = new Map();
|
|
1930
1980
|
let plannedSkillMarkerTargets = new Map();
|
|
@@ -1956,7 +2006,7 @@ export async function runRebuildCommand(options) {
|
|
|
1956
2006
|
}
|
|
1957
2007
|
return output;
|
|
1958
2008
|
};
|
|
1959
|
-
const createPlan = async (inventory, codexManager) => {
|
|
2009
|
+
const createPlan = async (inventory, codexManager, planOptions) => {
|
|
1960
2010
|
plannedCodexRegistrations = new Map();
|
|
1961
2011
|
plannedOwnedTextTargets = new Map();
|
|
1962
2012
|
plannedSkillMarkerTargets = new Map();
|
|
@@ -1965,6 +2015,15 @@ export async function runRebuildCommand(options) {
|
|
|
1965
2015
|
const placementNodes = [];
|
|
1966
2016
|
const blockingTargets = new Map();
|
|
1967
2017
|
const actualStates = new Map();
|
|
2018
|
+
const loadPlacementCodexConfigs = async () => {
|
|
2019
|
+
const [user, project] = await Promise.all(['user', 'project'].map((scope) => readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, scope, runtimeEnv).configTomlPath)));
|
|
2020
|
+
return { user, project };
|
|
2021
|
+
};
|
|
2022
|
+
let placementCodexConfigs;
|
|
2023
|
+
const readPlacementCodexConfigs = () => {
|
|
2024
|
+
placementCodexConfigs ??= loadPlacementCodexConfigs();
|
|
2025
|
+
return placementCodexConfigs;
|
|
2026
|
+
};
|
|
1968
2027
|
for (const [order, { entry, platform }] of executionSelections.entries()) {
|
|
1969
2028
|
const relation = selectedIds.has(entry.pluginId) ? 'requested' : 'dependency';
|
|
1970
2029
|
let resolvedScope = options.commandOptions.scope;
|
|
@@ -2050,12 +2109,17 @@ export async function runRebuildCommand(options) {
|
|
|
2050
2109
|
cwd: options.commandOptions.cwd,
|
|
2051
2110
|
env: runtimeEnv,
|
|
2052
2111
|
nativeCliRunner: executionContext.nativeCliRunner,
|
|
2112
|
+
scope: codexObservationScopeByMarketplace.get(marketplaceNameFor(entry, platform, resolvedScope)) ?? 'both',
|
|
2113
|
+
observationSession: executionContext.codexObservationSession,
|
|
2053
2114
|
...(codexManager ? { manager: codexManager } : {}),
|
|
2054
2115
|
})
|
|
2055
2116
|
: undefined;
|
|
2056
2117
|
if (codexRegistration) {
|
|
2057
2118
|
plannedCodexRegistrations.set(codexPluginId, codexRegistration);
|
|
2058
2119
|
}
|
|
2120
|
+
const placementActivationConfigs = codexRegistration
|
|
2121
|
+
? await readPlacementCodexConfigs()
|
|
2122
|
+
: undefined;
|
|
2059
2123
|
const placementState = (inspected, scope) => {
|
|
2060
2124
|
if (platform !== 'codex'
|
|
2061
2125
|
|| surface?.classification !== 'native'
|
|
@@ -2070,8 +2134,12 @@ export async function runRebuildCommand(options) {
|
|
|
2070
2134
|
return 'partial';
|
|
2071
2135
|
if (codexRegistration.observation.value === 'absent')
|
|
2072
2136
|
return 'absent';
|
|
2073
|
-
|
|
2074
|
-
|
|
2137
|
+
const configEnabled = placementActivationConfigs.user
|
|
2138
|
+
.snapshot.plugins[codexPluginId]?.enabled === true
|
|
2139
|
+
|| (scope === 'project'
|
|
2140
|
+
&& placementActivationConfigs.project
|
|
2141
|
+
.snapshot.plugins[codexPluginId]?.enabled === true);
|
|
2142
|
+
return configEnabled
|
|
2075
2143
|
? inspected.state
|
|
2076
2144
|
: 'partial';
|
|
2077
2145
|
};
|
|
@@ -2205,12 +2273,14 @@ export async function runRebuildCommand(options) {
|
|
|
2205
2273
|
state = resolvedInspection.state;
|
|
2206
2274
|
errorCode ??= 'dependencyNotReady';
|
|
2207
2275
|
}
|
|
2208
|
-
if (
|
|
2276
|
+
if (!planOptions?.skipConfigValidation
|
|
2277
|
+
&& entry.plugin.manifest.config?.fields
|
|
2209
2278
|
&& (action === 'install' || action === 'reinstall')) {
|
|
2210
2279
|
const effective = resolvedScope === 'project'
|
|
2211
2280
|
? await resolveArtifactRenderConfig({
|
|
2212
2281
|
sourceId: entry.source.sourceId,
|
|
2213
2282
|
sourceIdentity: entry.source.sourceIdentity,
|
|
2283
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
2214
2284
|
pluginName: entry.plugin.manifest.name,
|
|
2215
2285
|
manifest: entry.plugin.manifest,
|
|
2216
2286
|
scope: 'project',
|
|
@@ -2220,6 +2290,7 @@ export async function runRebuildCommand(options) {
|
|
|
2220
2290
|
: await resolveEffectivePluginConfig({
|
|
2221
2291
|
sourceId: entry.source.sourceId,
|
|
2222
2292
|
sourceIdentity: entry.source.sourceIdentity,
|
|
2293
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
2223
2294
|
pluginName: entry.plugin.manifest.name,
|
|
2224
2295
|
manifest: entry.plugin.manifest,
|
|
2225
2296
|
targetScope: 'user',
|
|
@@ -2418,15 +2489,29 @@ export async function runRebuildCommand(options) {
|
|
|
2418
2489
|
return [...scopes].sort();
|
|
2419
2490
|
};
|
|
2420
2491
|
const inspectBothScopes = options.command !== 'cleanup' && options.command !== 'uninstall';
|
|
2421
|
-
const readActivationConfig = async (scope) => {
|
|
2422
|
-
return readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, scope, runtimeEnv).configTomlPath);
|
|
2423
|
-
};
|
|
2424
2492
|
const [userConfig, projectConfig] = await Promise.all([
|
|
2425
|
-
|
|
2426
|
-
|
|
2493
|
+
readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'user', runtimeEnv).configTomlPath),
|
|
2494
|
+
readCodexConfigFile(resolveCodexPaths(options.commandOptions.cwd, 'project', runtimeEnv).configTomlPath),
|
|
2427
2495
|
]);
|
|
2428
2496
|
const catalogClosure = [];
|
|
2429
2497
|
const liveEvidence = [];
|
|
2498
|
+
const desiredScopesByPluginId = new Map();
|
|
2499
|
+
const intentScopesByPluginId = new Map();
|
|
2500
|
+
for (const planned of reconciledCodexTargets) {
|
|
2501
|
+
const entry = available.find((candidate) => candidate.pluginId === planned.pluginId);
|
|
2502
|
+
const marketplaceName = marketplaceNameFor(entry, 'codex', planned.resolvedScope);
|
|
2503
|
+
const codexPluginId = `${entry.plugin.manifest.name}@${marketplaceName}`;
|
|
2504
|
+
const desiredScopes = desiredScopesForEntry(entry);
|
|
2505
|
+
const intentScopes = intentScopesForEntry(entry);
|
|
2506
|
+
desiredScopesByPluginId.set(entry.pluginId, desiredScopes);
|
|
2507
|
+
intentScopesByPluginId.set(entry.pluginId, intentScopes);
|
|
2508
|
+
if (planned.resolvedScope === 'project'
|
|
2509
|
+
|| desiredScopes.includes('project')
|
|
2510
|
+
|| intentScopes.includes('project')
|
|
2511
|
+
|| Object.hasOwn(projectConfig.snapshot.plugins, codexPluginId)) {
|
|
2512
|
+
codexObservationScopeByMarketplace.set(marketplaceName, 'both');
|
|
2513
|
+
}
|
|
2514
|
+
}
|
|
2430
2515
|
for (const planned of reconciledCodexTargets) {
|
|
2431
2516
|
const entry = available.find((candidate) => candidate.pluginId === planned.pluginId);
|
|
2432
2517
|
const surface = analyzeCodexSurface(entry.plugin.manifest);
|
|
@@ -2438,7 +2523,11 @@ export async function runRebuildCommand(options) {
|
|
|
2438
2523
|
const staticContentDigest = hasNativeRenderTargets
|
|
2439
2524
|
? undefined
|
|
2440
2525
|
: await calculateCodexSharedNativePayloadDigest(entry.plugin.rootDir);
|
|
2441
|
-
const desiredScopes =
|
|
2526
|
+
const desiredScopes = desiredScopesByPluginId.get(entry.pluginId);
|
|
2527
|
+
const intentScopes = intentScopesByPluginId.get(entry.pluginId);
|
|
2528
|
+
const observationScope = codexObservationScopeByMarketplace.get(marketplaceName)
|
|
2529
|
+
?? 'user';
|
|
2530
|
+
const plannedRegistration = plannedCodexRegistrations.get(codexPluginId);
|
|
2442
2531
|
const sharedInspection = surface.nativeKinds.length > 0
|
|
2443
2532
|
? await inspectCodexSharedNativeLive({
|
|
2444
2533
|
pluginName: entry.plugin.manifest.name,
|
|
@@ -2450,9 +2539,12 @@ export async function runRebuildCommand(options) {
|
|
|
2450
2539
|
marketplaceName,
|
|
2451
2540
|
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
|
|
2452
2541
|
nativeCliRunner: executionContext.nativeCliRunner,
|
|
2542
|
+
observationScope,
|
|
2543
|
+
observationSession: executionContext.codexObservationSession,
|
|
2453
2544
|
...(codexManager ? { manager: codexManager } : {}),
|
|
2454
|
-
...(
|
|
2455
|
-
|
|
2545
|
+
...(plannedRegistration
|
|
2546
|
+
&& (observationScope === 'user' || plannedRegistration.observations.project)
|
|
2547
|
+
? { pluginRegistration: plannedRegistration }
|
|
2456
2548
|
: {}),
|
|
2457
2549
|
...(hasNativeRenderTargets ? { nativeRenderPlugin: entry.plugin } : {}),
|
|
2458
2550
|
})
|
|
@@ -2469,7 +2561,7 @@ export async function runRebuildCommand(options) {
|
|
|
2469
2561
|
relation: planned.relation,
|
|
2470
2562
|
resolvedScope: planned.resolvedScope,
|
|
2471
2563
|
desiredScopes,
|
|
2472
|
-
intentScopes
|
|
2564
|
+
intentScopes,
|
|
2473
2565
|
surface,
|
|
2474
2566
|
});
|
|
2475
2567
|
const sharedNative = sharedInspection?.sharedNative
|
|
@@ -2544,15 +2636,8 @@ export async function runRebuildCommand(options) {
|
|
|
2544
2636
|
liveEvidence.push({
|
|
2545
2637
|
codexPluginId,
|
|
2546
2638
|
sharedNative,
|
|
2547
|
-
...(sharedInspection?.actualPayloadDigest
|
|
2548
|
-
? { sharedNativePayloadDigest: sharedInspection.actualPayloadDigest }
|
|
2549
|
-
: {}),
|
|
2550
|
-
...(sharedInspection?.payloadPath
|
|
2551
|
-
? { sharedNativePayloadPath: sharedInspection.payloadPath }
|
|
2552
|
-
: {}),
|
|
2553
2639
|
activations: {
|
|
2554
|
-
user:
|
|
2555
|
-
?? userConfig?.snapshot.plugins[codexPluginId]?.enabled,
|
|
2640
|
+
user: userConfig.snapshot.plugins[codexPluginId]?.enabled,
|
|
2556
2641
|
project: projectConfig?.snapshot.plugins[codexPluginId]?.enabled,
|
|
2557
2642
|
},
|
|
2558
2643
|
extensions,
|
|
@@ -2664,6 +2749,7 @@ export async function runRebuildCommand(options) {
|
|
|
2664
2749
|
const integration = createRebuildIntegration({
|
|
2665
2750
|
context: executionContext,
|
|
2666
2751
|
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
2752
|
+
operationScopedNativePhases: true,
|
|
2667
2753
|
});
|
|
2668
2754
|
const preparedTargets = new Map();
|
|
2669
2755
|
const preparedTargetErrors = new Map();
|
|
@@ -2689,8 +2775,10 @@ export async function runRebuildCommand(options) {
|
|
|
2689
2775
|
const plannedNative = platform === 'codex'
|
|
2690
2776
|
? codexPlans.flatMap((codexPlan) => codexPlan.sharedNativeActions).find((action) => action.pluginId === entry.pluginId)
|
|
2691
2777
|
: undefined;
|
|
2778
|
+
const codexNativeStillDesired = platform === 'codex'
|
|
2779
|
+
&& codexPlans.some((codexPlan) => codexPlan.desiredTargets.some((target) => target.pluginId === entry.pluginId && target.scopes.length > 0));
|
|
2692
2780
|
const preserveSharedNative = plannedNative?.action === 'reuse'
|
|
2693
|
-
|| plannedNative?.action === 'none';
|
|
2781
|
+
|| (plannedNative?.action === 'none' && codexNativeStillDesired);
|
|
2694
2782
|
const marketplaceName = marketplaceNameFor(entry, platform, planned.resolvedScope);
|
|
2695
2783
|
try {
|
|
2696
2784
|
const target = await measureCommandPerformanceStage(options.runtime, 'target.build', () => integration.buildTarget({
|
|
@@ -2731,10 +2819,20 @@ export async function runRebuildCommand(options) {
|
|
|
2731
2819
|
...codexPlan.extensionRemovals,
|
|
2732
2820
|
].some((action) => action.pluginId === entry.pluginId
|
|
2733
2821
|
&& action.scope === planned.resolvedScope));
|
|
2822
|
+
const hasActivationMutation = codexPlans.some((codexPlan) => [
|
|
2823
|
+
...codexPlan.activationActions.user,
|
|
2824
|
+
...codexPlan.activationActions.project,
|
|
2825
|
+
].some((action) => action.pluginId === entry.pluginId
|
|
2826
|
+
&& action.action !== 'none'));
|
|
2734
2827
|
target.codexNativeObservationExpectation = preserveSharedNative && hasExtensionMutation
|
|
2735
2828
|
? (plannedNative.action === 'reuse' ? 'installed' : 'observed')
|
|
2736
2829
|
: undefined;
|
|
2737
|
-
|
|
2830
|
+
const removesSharedNative = !writesSharedNative
|
|
2831
|
+
&& !preserveSharedNative
|
|
2832
|
+
&& (buildCommand === 'cleanup' || buildCommand === 'uninstall');
|
|
2833
|
+
target.codexNativeSensitivePreflightRequired = preserveSharedNative
|
|
2834
|
+
&& hasActivationMutation;
|
|
2835
|
+
if (!writesSharedNative && !removesSharedNative) {
|
|
2738
2836
|
const isSharedNativeComponent = (component) => component.kind === 'native-plugin'
|
|
2739
2837
|
|| (component.kind === 'shared-config'
|
|
2740
2838
|
&& component.identity.artifactKey.startsWith('marketplace-'));
|
|
@@ -2744,6 +2842,9 @@ export async function runRebuildCommand(options) {
|
|
|
2744
2842
|
target.optionalOwnedComponents = target.optionalOwnedComponents?.filter((component) => !isSharedNativeComponent(component));
|
|
2745
2843
|
target.operationActions = target.operationActions?.filter((action) => action.kind !== 'ensureNativeRegistration');
|
|
2746
2844
|
}
|
|
2845
|
+
if (target.codexNativeSensitivePreflightRequired && !hasExtensionMutation) {
|
|
2846
|
+
await integration.driver.preflightMutation?.(target);
|
|
2847
|
+
}
|
|
2747
2848
|
}
|
|
2748
2849
|
preparedTargets.set(`${entry.pluginId}\0${platform}`, {
|
|
2749
2850
|
target,
|
|
@@ -2793,6 +2894,7 @@ export async function runRebuildCommand(options) {
|
|
|
2793
2894
|
const effective = await resolveEffectivePluginConfig({
|
|
2794
2895
|
sourceId: entry.source.sourceId,
|
|
2795
2896
|
sourceIdentity: entry.source.sourceIdentity,
|
|
2897
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
2796
2898
|
pluginName: entry.plugin.manifest.name,
|
|
2797
2899
|
manifest: entry.plugin.manifest,
|
|
2798
2900
|
targetScope: scope,
|
|
@@ -2806,12 +2908,40 @@ export async function runRebuildCommand(options) {
|
|
|
2806
2908
|
});
|
|
2807
2909
|
}));
|
|
2808
2910
|
return {
|
|
2911
|
+
integration,
|
|
2809
2912
|
preparedTargets,
|
|
2810
2913
|
preparedTargetErrors,
|
|
2811
2914
|
targetActions: [...preparedTargets.values()].flatMap((prepared) => prepared.target.operationActions ?? []),
|
|
2812
2915
|
configDigests,
|
|
2813
2916
|
};
|
|
2814
2917
|
};
|
|
2918
|
+
if (options.runtime?.resolvePreApplyAuthorization) {
|
|
2919
|
+
const authorizationPlan = await measureCommandPerformanceStage(options.runtime, 'dependency.plan', () => createPlan(stateInventory, undefined, { skipConfigValidation: true }));
|
|
2920
|
+
assertWriteInventoryComplete(stateInventory, exactOwnedTextTargets(authorizationPlan), exactSkillMarkerTargets(authorizationPlan));
|
|
2921
|
+
const preview = mergeRebuildCommandResults([]);
|
|
2922
|
+
preview.dependencyPlan = authorizationPlan;
|
|
2923
|
+
preview.preApplyAuthorization = executionSelections.flatMap(({ entry, platform }) => {
|
|
2924
|
+
const planned = authorizationPlan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === platform);
|
|
2925
|
+
if (!planned || planned.action === 'block' || !entry.plugin.manifest.scripts?.preApply) {
|
|
2926
|
+
return [];
|
|
2927
|
+
}
|
|
2928
|
+
const relation = planned.relation === 'requested'
|
|
2929
|
+
? 'requested'
|
|
2930
|
+
: planned.requiredBy.some((pluginId) => selectedIds.has(pluginId))
|
|
2931
|
+
? 'direct'
|
|
2932
|
+
: 'transitive';
|
|
2933
|
+
return [{
|
|
2934
|
+
pluginId: entry.pluginId,
|
|
2935
|
+
pluginName: entry.plugin.manifest.name,
|
|
2936
|
+
sourceId: entry.source.sourceId,
|
|
2937
|
+
sourceIdentity: entry.source.sourceIdentity,
|
|
2938
|
+
platform,
|
|
2939
|
+
scope: planned.resolvedScope,
|
|
2940
|
+
relation,
|
|
2941
|
+
}];
|
|
2942
|
+
});
|
|
2943
|
+
return preview;
|
|
2944
|
+
}
|
|
2815
2945
|
if (options.runtime?.previewOperationPlan) {
|
|
2816
2946
|
await options.runtime.onPreviewStage?.('dependencyPlan');
|
|
2817
2947
|
const initialPlan = await measureCommandPerformanceStage(options.runtime, 'dependency.plan', () => createPlan(stateInventory));
|
|
@@ -2882,6 +3012,7 @@ export async function runRebuildCommand(options) {
|
|
|
2882
3012
|
: {}),
|
|
2883
3013
|
sourceId: entry.source.sourceId,
|
|
2884
3014
|
sourceIdentity: entry.source.sourceIdentity,
|
|
3015
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
2885
3016
|
resolvedCommit: entry.source.resolvedCommit,
|
|
2886
3017
|
manifestDigest: entry.source.manifestDigest,
|
|
2887
3018
|
snapshotDigest: entry.source.snapshotDigest,
|
|
@@ -2890,64 +3021,25 @@ export async function runRebuildCommand(options) {
|
|
|
2890
3021
|
}
|
|
2891
3022
|
let lockedPlan = await measureCommandPerformanceStage(options.runtime, 'dependency.plan', () => createPlan(stateInventory));
|
|
2892
3023
|
assertWriteInventoryComplete(stateInventory, exactOwnedTextTargets(lockedPlan), exactSkillMarkerTargets(lockedPlan));
|
|
3024
|
+
const lifecycleCommand = options.command === 'install'
|
|
3025
|
+
|| options.command === 'sync'
|
|
3026
|
+
|| options.command === 'reinstall';
|
|
3027
|
+
const preApplyRequired = lifecycleCommand && executionSelections.some(({ entry, platform }) => entry.plugin.manifest.scripts?.preApply !== undefined
|
|
3028
|
+
&& lockedPlan.targets.some((target) => target.pluginId === entry.pluginId
|
|
3029
|
+
&& target.platform === platform
|
|
3030
|
+
&& target.action !== 'block'));
|
|
3031
|
+
if (preApplyRequired
|
|
3032
|
+
&& options.commandOptions.yes !== true
|
|
3033
|
+
&& options.runtime?.preApplyConfirmed !== true) {
|
|
3034
|
+
throw namespacedPreflightError('preApplyAuthorizationRequired: Running plugin preApply requires --yes or an accepted Review.', preflightTargets);
|
|
3035
|
+
}
|
|
2893
3036
|
const provisionalLockedCodexPlans = await createCodexPlans(lockedPlan);
|
|
2894
3037
|
const codexManagerRequired = provisionalLockedCodexPlans.some((plan) => plan.sharedNativeActions.some((action) => action.action === 'install'
|
|
2895
3038
|
|| action.action === 'replace'
|
|
2896
3039
|
|| action.action === 'repair'));
|
|
2897
|
-
|
|
2898
|
-
|
|
2899
|
-
|
|
2900
|
-
const activationScope = provisionalLockedCodexPlans.some((plan) => plan.requirement.requiresProjectPluginContract) ? 'project' : 'user';
|
|
2901
|
-
const activationConsumer = activationOnlyOperation
|
|
2902
|
-
? await (options.runtime?.codexOperationConsumerResolver ?? resolveCodexOperationConsumer)({
|
|
2903
|
-
cwd: options.commandOptions.cwd,
|
|
2904
|
-
env: runtimeEnv,
|
|
2905
|
-
runner: executionContext.nativeCliRunner,
|
|
2906
|
-
operationRequirement: getCodexOperationRequirement(activationScope),
|
|
2907
|
-
requiresNativeMaterialization: false,
|
|
2908
|
-
})
|
|
2909
|
-
: undefined;
|
|
2910
|
-
if (activationConsumer?.support === 'observed') {
|
|
2911
|
-
executionContext.codexManager = activationConsumer.manager;
|
|
2912
|
-
}
|
|
2913
|
-
if (codexManagerRequired) {
|
|
2914
|
-
const codexRequirementScope = provisionalLockedCodexPlans.some((plan) => plan.requirement.requiresProjectPluginContract)
|
|
2915
|
-
? 'project'
|
|
2916
|
-
: 'user';
|
|
2917
|
-
if (options.runtime?.codexManagerResolver) {
|
|
2918
|
-
executionContext.codexManager = await options.runtime.codexManagerResolver({
|
|
2919
|
-
cwd: options.commandOptions.cwd,
|
|
2920
|
-
env: runtimeEnv,
|
|
2921
|
-
runner: executionContext.nativeCliRunner,
|
|
2922
|
-
authorizer: options.runtime?.managedCodexAuthorizer,
|
|
2923
|
-
operationRequirement: getCodexOperationRequirement(codexRequirementScope),
|
|
2924
|
-
});
|
|
2925
|
-
}
|
|
2926
|
-
else {
|
|
2927
|
-
const consumer = await (options.runtime?.codexOperationConsumerResolver ?? resolveCodexOperationConsumer)({
|
|
2928
|
-
cwd: options.commandOptions.cwd,
|
|
2929
|
-
env: runtimeEnv,
|
|
2930
|
-
runner: executionContext.nativeCliRunner,
|
|
2931
|
-
authorizer: options.runtime?.managedCodexAuthorizer,
|
|
2932
|
-
operationRequirement: getCodexOperationRequirement(codexRequirementScope),
|
|
2933
|
-
requiresNativeMaterialization: true,
|
|
2934
|
-
});
|
|
2935
|
-
if (consumer.support !== 'observed') {
|
|
2936
|
-
throw new Error('Codex native materialization requires an observed CLI consumer.');
|
|
2937
|
-
}
|
|
2938
|
-
executionContext.codexManager = consumer.manager;
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
let lockedCodexPlans = activationConsumer?.support === 'assumed'
|
|
2942
|
-
? await createCodexPlans(lockedPlan, 'assumed')
|
|
2943
|
-
: provisionalLockedCodexPlans;
|
|
2944
|
-
if (executionContext.codexManager) {
|
|
2945
|
-
lockedPlan = await createPlan(stateInventory, executionContext.codexManager);
|
|
2946
|
-
assertWriteInventoryComplete(stateInventory, exactOwnedTextTargets(lockedPlan), exactSkillMarkerTargets(lockedPlan));
|
|
2947
|
-
lockedCodexPlans = await createCodexPlans(lockedPlan, 'observed', executionContext.codexManager);
|
|
2948
|
-
}
|
|
2949
|
-
const lockedPreparation = await prepareRenderedTargets(lockedPlan, lockedCodexPlans, true);
|
|
2950
|
-
const lockedOperationPlan = createRebuildOperationPlan({
|
|
3040
|
+
let lockedCodexPlans = provisionalLockedCodexPlans;
|
|
3041
|
+
let lockedPreparation = await prepareRenderedTargets(lockedPlan, lockedCodexPlans, true);
|
|
3042
|
+
let lockedOperationPlan = createRebuildOperationPlan({
|
|
2951
3043
|
command: options.command,
|
|
2952
3044
|
scope: options.commandOptions.scope,
|
|
2953
3045
|
dependencyPlan: lockedPlan,
|
|
@@ -2968,27 +3060,299 @@ export async function runRebuildCommand(options) {
|
|
|
2968
3060
|
}
|
|
2969
3061
|
if (options.runtime?.directCli
|
|
2970
3062
|
&& options.commandOptions.yes !== true
|
|
2971
|
-
&&
|
|
2972
|
-
|| options.command === 'sync'
|
|
2973
|
-
|| options.command === 'reinstall')) {
|
|
3063
|
+
&& lifecycleCommand) {
|
|
2974
3064
|
const sharedNativeImpact = lockedCodexPlans.some((plan) => plan.review.requiresConfirmation);
|
|
2975
3065
|
if (sharedNativeImpact) {
|
|
2976
3066
|
throw namespacedPreflightError('sharedNativeImpactAuthorizationRequired: Replacing or force-reinstalling shared Codex native state requires --yes.', preflightTargets);
|
|
2977
3067
|
}
|
|
2978
3068
|
}
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
3069
|
+
const operationPreparations = new Map();
|
|
3070
|
+
const operationPreparationFailures = new Map();
|
|
3071
|
+
const executionCommandFor = (entry, platform) => {
|
|
3072
|
+
const planned = lockedPlan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === platform);
|
|
3073
|
+
const desiredInCurrentScope = platform === 'codex'
|
|
3074
|
+
&& lockedCodexPlans.some((codexPlan) => codexPlan.desiredTargets.some((target) => target.pluginId === entry.pluginId && target.scopes.includes(planned.resolvedScope)));
|
|
3075
|
+
if (platform === 'codex' && options.command === 'sync' && !desiredInCurrentScope) {
|
|
3076
|
+
return 'cleanup';
|
|
3077
|
+
}
|
|
3078
|
+
if (platform === 'codex' && options.command === 'cleanup' && desiredInCurrentScope) {
|
|
3079
|
+
return 'install';
|
|
3080
|
+
}
|
|
3081
|
+
if (planned.action === 'move') {
|
|
3082
|
+
return planned.state === 'partial' ? 'reinstall' : 'install';
|
|
3083
|
+
}
|
|
3084
|
+
if (planned.relation === 'dependency'
|
|
3085
|
+
&& (planned.action === 'install' || planned.action === 'reinstall')) {
|
|
3086
|
+
return planned.action;
|
|
3087
|
+
}
|
|
3088
|
+
return options.command;
|
|
3089
|
+
};
|
|
3090
|
+
const prepareLockedTargets = async (preparationOptions) => {
|
|
3091
|
+
const preparations = new Map();
|
|
3092
|
+
const failures = new Map();
|
|
3093
|
+
const states = new Map();
|
|
3094
|
+
const integration = createRebuildIntegration({
|
|
3095
|
+
context: executionContext,
|
|
3096
|
+
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
3097
|
+
preparedTargets: [...lockedPreparation.preparedTargets.values()].map((entry) => entry.target),
|
|
2991
3098
|
});
|
|
3099
|
+
for (const { entry, platform } of executionSelections) {
|
|
3100
|
+
const key = `${entry.pluginId}\0${platform}`;
|
|
3101
|
+
if (preparationOptions.eligibleKeys
|
|
3102
|
+
&& !preparationOptions.eligibleKeys.has(key)) {
|
|
3103
|
+
states.set(key, 'skipped');
|
|
3104
|
+
continue;
|
|
3105
|
+
}
|
|
3106
|
+
const directDependencyFailed = (entry.plugin.manifest.dependencies ?? []).some((pluginName) => {
|
|
3107
|
+
const dependencyPluginId = formatPluginId({
|
|
3108
|
+
sourceId: entry.source.sourceId,
|
|
3109
|
+
pluginName,
|
|
3110
|
+
});
|
|
3111
|
+
const state = states.get(`${dependencyPluginId}\0${platform}`);
|
|
3112
|
+
return state === 'failed' || state === 'skipped';
|
|
3113
|
+
});
|
|
3114
|
+
const planned = lockedPlan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === platform);
|
|
3115
|
+
if (directDependencyFailed || planned.action === 'block') {
|
|
3116
|
+
states.set(key, 'skipped');
|
|
3117
|
+
continue;
|
|
3118
|
+
}
|
|
3119
|
+
const preparationError = lockedPreparation.preparedTargetErrors.get(key);
|
|
3120
|
+
const prepared = lockedPreparation.preparedTargets.get(key);
|
|
3121
|
+
if (preparationError || !prepared) {
|
|
3122
|
+
const message = preparationError instanceof Error
|
|
3123
|
+
? preparationError.message
|
|
3124
|
+
: String(preparationError ?? 'Target preparation did not produce a target.');
|
|
3125
|
+
failures.set(key, failedResult(options.command, {
|
|
3126
|
+
sourceId: entry.source.sourceId,
|
|
3127
|
+
sourceIdentity: entry.source.sourceIdentity,
|
|
3128
|
+
pluginId: entry.pluginId,
|
|
3129
|
+
pluginName: entry.plugin.manifest.name,
|
|
3130
|
+
pluginVersion: entry.plugin.manifest.version,
|
|
3131
|
+
platform,
|
|
3132
|
+
scope: planned.resolvedScope,
|
|
3133
|
+
cwd: options.commandOptions.cwd,
|
|
3134
|
+
}, message));
|
|
3135
|
+
states.set(key, 'failed');
|
|
3136
|
+
continue;
|
|
3137
|
+
}
|
|
3138
|
+
const executionCommand = executionCommandFor(entry, platform);
|
|
3139
|
+
if (executionCommand === 'cleanup' || executionCommand === 'uninstall') {
|
|
3140
|
+
states.set(key, 'ready');
|
|
3141
|
+
continue;
|
|
3142
|
+
}
|
|
3143
|
+
const preparedOperation = await prepareRebuildOperation({
|
|
3144
|
+
command: executionCommand,
|
|
3145
|
+
target: prepared.target,
|
|
3146
|
+
driver: integration.driver,
|
|
3147
|
+
...(preparationOptions.skipPreApply ? { skipPreApply: true } : {}),
|
|
3148
|
+
...(preparationOptions.deferManagedNativeInspection
|
|
3149
|
+
&& platform === 'codex'
|
|
3150
|
+
&& executionContext.codexManager === undefined
|
|
3151
|
+
&& (prepared.target.writeNativeRequired ?? prepared.target.requiresNative)
|
|
3152
|
+
? { deferNativeInspection: true }
|
|
3153
|
+
: {}),
|
|
3154
|
+
onActionEvent: (event) => emitRebuildActionEvent(executionContext, event),
|
|
3155
|
+
});
|
|
3156
|
+
if (preparedOperation.status === 'failed') {
|
|
3157
|
+
failures.set(key, preparedOperation.result);
|
|
3158
|
+
states.set(key, 'failed');
|
|
3159
|
+
continue;
|
|
3160
|
+
}
|
|
3161
|
+
preparations.set(key, preparedOperation.preparation);
|
|
3162
|
+
states.set(key, 'ready');
|
|
3163
|
+
}
|
|
3164
|
+
return { preparations, failures };
|
|
3165
|
+
};
|
|
3166
|
+
if (lifecycleCommand) {
|
|
3167
|
+
const initialPreparation = await prepareLockedTargets({
|
|
3168
|
+
deferManagedNativeInspection: codexManagerRequired,
|
|
3169
|
+
});
|
|
3170
|
+
for (const [key, preparation] of initialPreparation.preparations) {
|
|
3171
|
+
operationPreparations.set(key, preparation);
|
|
3172
|
+
}
|
|
3173
|
+
for (const [key, failure] of initialPreparation.failures) {
|
|
3174
|
+
operationPreparationFailures.set(key, failure);
|
|
3175
|
+
}
|
|
3176
|
+
const nativePreparationKeys = new Set([...operationPreparations].flatMap(([key, preparation]) => preparation.target.identity.platform === 'codex'
|
|
3177
|
+
&& (preparation.target.writeNativeRequired ?? preparation.target.requiresNative)
|
|
3178
|
+
? [key]
|
|
3179
|
+
: []));
|
|
3180
|
+
const activationPluginIds = new Set(provisionalLockedCodexPlans.flatMap((plan) => plan.postcheck.plugins.map((plugin) => plugin.pluginId)));
|
|
3181
|
+
const activationPreparationKeys = new Set([...operationPreparations].flatMap(([key, preparation]) => preparation.target.identity.platform === 'codex'
|
|
3182
|
+
&& preparation.target.identity.pluginId
|
|
3183
|
+
&& activationPluginIds.has(preparation.target.identity.pluginId)
|
|
3184
|
+
? [key]
|
|
3185
|
+
: []));
|
|
3186
|
+
const codexRequirementScopeFor = (keys) => {
|
|
3187
|
+
const pluginIds = new Set([...keys].flatMap((key) => {
|
|
3188
|
+
const pluginId = operationPreparations.get(key)?.target.identity.pluginId;
|
|
3189
|
+
return pluginId ? [pluginId] : [];
|
|
3190
|
+
}));
|
|
3191
|
+
return provisionalLockedCodexPlans.some((plan) => plan.desiredTargets.some((target) => pluginIds.has(target.pluginId) && target.scopes.includes('project')))
|
|
3192
|
+
? 'project'
|
|
3193
|
+
: 'user';
|
|
3194
|
+
};
|
|
3195
|
+
let refreshManagedNativePlan = false;
|
|
3196
|
+
const failPreparedTargets = (keys, error) => {
|
|
3197
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3198
|
+
for (const key of keys) {
|
|
3199
|
+
const target = operationPreparations.get(key)?.target;
|
|
3200
|
+
if (!target)
|
|
3201
|
+
continue;
|
|
3202
|
+
operationPreparations.delete(key);
|
|
3203
|
+
operationPreparationFailures.set(key, failedResult(options.command, target.identity, message));
|
|
3204
|
+
}
|
|
3205
|
+
};
|
|
3206
|
+
if (executionContext.codexManager === undefined
|
|
3207
|
+
&& nativePreparationKeys.size > 0) {
|
|
3208
|
+
try {
|
|
3209
|
+
if (options.runtime?.codexManagerResolver) {
|
|
3210
|
+
executionContext.codexManager = await options.runtime.codexManagerResolver({
|
|
3211
|
+
cwd: options.commandOptions.cwd,
|
|
3212
|
+
env: runtimeEnv,
|
|
3213
|
+
runner: executionContext.nativeCliRunner,
|
|
3214
|
+
authorizer: options.runtime?.managedCodexAuthorizer,
|
|
3215
|
+
operationRequirement: getCodexOperationRequirement(codexRequirementScopeFor(nativePreparationKeys)),
|
|
3216
|
+
});
|
|
3217
|
+
}
|
|
3218
|
+
else {
|
|
3219
|
+
const consumer = await (options.runtime?.codexOperationConsumerResolver ?? resolveCodexOperationConsumer)({
|
|
3220
|
+
cwd: options.commandOptions.cwd,
|
|
3221
|
+
env: runtimeEnv,
|
|
3222
|
+
runner: executionContext.nativeCliRunner,
|
|
3223
|
+
authorizer: options.runtime?.managedCodexAuthorizer,
|
|
3224
|
+
operationRequirement: getCodexOperationRequirement(codexRequirementScopeFor(nativePreparationKeys)),
|
|
3225
|
+
requiresNativeMaterialization: true,
|
|
3226
|
+
});
|
|
3227
|
+
if (consumer.support !== 'observed') {
|
|
3228
|
+
throw new Error('Codex native materialization requires an observed CLI consumer.');
|
|
3229
|
+
}
|
|
3230
|
+
executionContext.codexManager = consumer.manager;
|
|
3231
|
+
}
|
|
3232
|
+
refreshManagedNativePlan = true;
|
|
3233
|
+
}
|
|
3234
|
+
catch (error) {
|
|
3235
|
+
failPreparedTargets(nativePreparationKeys, error);
|
|
3236
|
+
}
|
|
3237
|
+
}
|
|
3238
|
+
else if (executionContext.codexManager === undefined
|
|
3239
|
+
&& activationPreparationKeys.size > 0) {
|
|
3240
|
+
try {
|
|
3241
|
+
const consumer = await (options.runtime?.codexOperationConsumerResolver ?? resolveCodexOperationConsumer)({
|
|
3242
|
+
cwd: options.commandOptions.cwd,
|
|
3243
|
+
env: runtimeEnv,
|
|
3244
|
+
runner: executionContext.nativeCliRunner,
|
|
3245
|
+
operationRequirement: getCodexOperationRequirement(codexRequirementScopeFor(activationPreparationKeys)),
|
|
3246
|
+
requiresNativeMaterialization: false,
|
|
3247
|
+
});
|
|
3248
|
+
if (consumer.support === 'observed') {
|
|
3249
|
+
executionContext.codexManager = consumer.manager;
|
|
3250
|
+
}
|
|
3251
|
+
else {
|
|
3252
|
+
lockedCodexPlans = lockedCodexPlans.map((plan) => ({
|
|
3253
|
+
...plan,
|
|
3254
|
+
warnings: [...new Set([
|
|
3255
|
+
...plan.warnings,
|
|
3256
|
+
'codexProjectActivationAssumed',
|
|
3257
|
+
])],
|
|
3258
|
+
postcheck: { ...plan.postcheck, support: 'assumed' },
|
|
3259
|
+
}));
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
catch (error) {
|
|
3263
|
+
failPreparedTargets(activationPreparationKeys, error);
|
|
3264
|
+
}
|
|
3265
|
+
}
|
|
3266
|
+
if (executionContext.codexManager) {
|
|
3267
|
+
executionContext.codexObservationSession?.setManager(executionContext.codexManager);
|
|
3268
|
+
}
|
|
3269
|
+
if (refreshManagedNativePlan) {
|
|
3270
|
+
if (executionContext.codexManager) {
|
|
3271
|
+
lockedPlan = await createPlan(stateInventory, executionContext.codexManager);
|
|
3272
|
+
assertWriteInventoryComplete(stateInventory, exactOwnedTextTargets(lockedPlan), exactSkillMarkerTargets(lockedPlan));
|
|
3273
|
+
}
|
|
3274
|
+
lockedCodexPlans = await createCodexPlans(lockedPlan, 'observed', executionContext.codexManager);
|
|
3275
|
+
lockedPreparation = await prepareRenderedTargets(lockedPlan, lockedCodexPlans, false);
|
|
3276
|
+
const eligibleKeys = new Set(operationPreparations.keys());
|
|
3277
|
+
const initialOperationPreparations = new Map(operationPreparations);
|
|
3278
|
+
const finalPreparation = await prepareLockedTargets({
|
|
3279
|
+
eligibleKeys,
|
|
3280
|
+
skipPreApply: true,
|
|
3281
|
+
});
|
|
3282
|
+
operationPreparations.clear();
|
|
3283
|
+
for (const [key, preparation] of finalPreparation.preparations) {
|
|
3284
|
+
operationPreparations.set(key, {
|
|
3285
|
+
...preparation,
|
|
3286
|
+
actions: [
|
|
3287
|
+
...(initialOperationPreparations.get(key)?.actions ?? []),
|
|
3288
|
+
...preparation.actions,
|
|
3289
|
+
],
|
|
3290
|
+
});
|
|
3291
|
+
}
|
|
3292
|
+
for (const [key, failure] of finalPreparation.failures) {
|
|
3293
|
+
operationPreparationFailures.set(key, failure);
|
|
3294
|
+
}
|
|
3295
|
+
}
|
|
3296
|
+
const eligibleTargets = [...operationPreparations.keys()].flatMap((key) => {
|
|
3297
|
+
const prepared = lockedPreparation.preparedTargets.get(key);
|
|
3298
|
+
return prepared ? [prepared.target] : [];
|
|
3299
|
+
});
|
|
3300
|
+
lockedPreparation.integration.setNativeMarketplaceEligibleTargets(eligibleTargets);
|
|
3301
|
+
}
|
|
3302
|
+
lockedOperationPlan = createRebuildOperationPlan({
|
|
3303
|
+
command: options.command,
|
|
3304
|
+
scope: options.commandOptions.scope,
|
|
3305
|
+
dependencyPlan: lockedPlan,
|
|
3306
|
+
codexPlans: lockedCodexPlans,
|
|
3307
|
+
targetActions: lockedPreparation.targetActions,
|
|
3308
|
+
catalogSources: catalog.sources.flatMap((source) => source.resolution ? [source.resolution] : []),
|
|
3309
|
+
intentBeforeByScope,
|
|
3310
|
+
configDigests: lockedPreparation.configDigests,
|
|
3311
|
+
catalogEntries: intentCatalogEntries,
|
|
3312
|
+
});
|
|
3313
|
+
if (options.runtime?.expectedPlanFingerprint) {
|
|
3314
|
+
assertOperationPlanFingerprint(options.runtime.expectedPlanFingerprint, lockedOperationPlan);
|
|
3315
|
+
}
|
|
3316
|
+
if (options.runtime?.directCli
|
|
3317
|
+
&& options.commandOptions.yes !== true
|
|
3318
|
+
&& lifecycleCommand
|
|
3319
|
+
&& lockedCodexPlans.some((plan) => plan.review.requiresConfirmation)) {
|
|
3320
|
+
throw namespacedPreflightError('sharedNativeImpactAuthorizationRequired: Replacing or force-reinstalling shared Codex native state requires --yes.', preflightTargets);
|
|
3321
|
+
}
|
|
3322
|
+
if (options.runtime?.awHomeMutationToken) {
|
|
3323
|
+
if (lifecycleCommand) {
|
|
3324
|
+
const preparedKeys = new Set(operationPreparations.keys());
|
|
3325
|
+
const intentSelection = intentPlanForPreparedRoots(lockedPlan, preparedKeys);
|
|
3326
|
+
const intentPlan = intentSelection.plan;
|
|
3327
|
+
const selectedRoots = intentSelection.selectedRoots;
|
|
3328
|
+
if (selectedRoots.length > 0) {
|
|
3329
|
+
await writeDesiredIntentSuperset({
|
|
3330
|
+
command: options.command,
|
|
3331
|
+
cwd: options.commandOptions.cwd,
|
|
3332
|
+
scope: options.commandOptions.scope,
|
|
3333
|
+
selectedRoots,
|
|
3334
|
+
plan: intentPlan,
|
|
3335
|
+
codexPlan: lockedCodexPlans[0],
|
|
3336
|
+
preserveOtherCodexScopeRootIds,
|
|
3337
|
+
catalogEntries: intentCatalogEntries,
|
|
3338
|
+
env: runtimeEnv,
|
|
3339
|
+
});
|
|
3340
|
+
}
|
|
3341
|
+
}
|
|
3342
|
+
else {
|
|
3343
|
+
const selectedRoots = selectedRootsForPlan(lockedPlan);
|
|
3344
|
+
await writeDesiredIntentSuperset({
|
|
3345
|
+
command: options.command,
|
|
3346
|
+
cwd: options.commandOptions.cwd,
|
|
3347
|
+
scope: options.commandOptions.scope,
|
|
3348
|
+
selectedRoots,
|
|
3349
|
+
plan: lockedPlan,
|
|
3350
|
+
codexPlan: lockedCodexPlans[0],
|
|
3351
|
+
preserveOtherCodexScopeRootIds,
|
|
3352
|
+
catalogEntries: intentCatalogEntries,
|
|
3353
|
+
env: runtimeEnv,
|
|
3354
|
+
});
|
|
3355
|
+
}
|
|
2992
3356
|
}
|
|
2993
3357
|
for (const pluginName of new Set(lockedPlan.targets.flatMap((target) => target.platform === 'claude'
|
|
2994
3358
|
&& (target.action === 'install'
|
|
@@ -3142,7 +3506,6 @@ export async function runRebuildCommand(options) {
|
|
|
3142
3506
|
}
|
|
3143
3507
|
}
|
|
3144
3508
|
const results = [];
|
|
3145
|
-
const deferredPostApplyTasks = [];
|
|
3146
3509
|
const dependencyStates = new Map();
|
|
3147
3510
|
for (const { entry, platform } of executionSelections) {
|
|
3148
3511
|
const planned = lockedPlan.targets.find((target) => target.pluginId === entry.pluginId && target.platform === platform);
|
|
@@ -3230,6 +3593,27 @@ export async function runRebuildCommand(options) {
|
|
|
3230
3593
|
dependencyStates.set(`${entry.pluginId}\0${platform}`, failedDependency || failedConsumer ? 'skipped' : 'failed');
|
|
3231
3594
|
continue;
|
|
3232
3595
|
}
|
|
3596
|
+
const operationPreparationFailure = operationPreparationFailures.get(`${entry.pluginId}\0${platform}`);
|
|
3597
|
+
if (operationPreparationFailure) {
|
|
3598
|
+
const targetResult = toTargetResult(operationPreparationFailure);
|
|
3599
|
+
results.push({
|
|
3600
|
+
platforms: [platform],
|
|
3601
|
+
plugins: [],
|
|
3602
|
+
warnings: [],
|
|
3603
|
+
rebuildResults: [operationPreparationFailure],
|
|
3604
|
+
targetResults: [{ ...targetResult, action: planned.action }],
|
|
3605
|
+
overallState: 'failed',
|
|
3606
|
+
receiptTargets: [{
|
|
3607
|
+
pluginName: identity.pluginName,
|
|
3608
|
+
pluginId: identity.pluginId,
|
|
3609
|
+
sourceId: identity.sourceId,
|
|
3610
|
+
platform,
|
|
3611
|
+
scope: planned.resolvedScope,
|
|
3612
|
+
}],
|
|
3613
|
+
});
|
|
3614
|
+
dependencyStates.set(`${entry.pluginId}\0${platform}`, 'failed');
|
|
3615
|
+
continue;
|
|
3616
|
+
}
|
|
3233
3617
|
if (reconcileActivationOnly) {
|
|
3234
3618
|
const preparedError = preparedTargetErrors.get(`${entry.pluginId}\0${platform}`);
|
|
3235
3619
|
if (preparedError) {
|
|
@@ -3255,43 +3639,55 @@ export async function runRebuildCommand(options) {
|
|
|
3255
3639
|
dependencyStates.set(`${entry.pluginId}\0${platform}`, 'failed');
|
|
3256
3640
|
continue;
|
|
3257
3641
|
}
|
|
3258
|
-
const
|
|
3259
|
-
|
|
3642
|
+
const actions = operationPreparations.get(`${entry.pluginId}\0${platform}`)?.actions
|
|
3643
|
+
?? [];
|
|
3644
|
+
const preparedTarget = preparedTargets.get(`${entry.pluginId}\0${platform}`)?.target;
|
|
3645
|
+
let result;
|
|
3646
|
+
if (preparedTarget) {
|
|
3647
|
+
const nativeSkillKeys = new Set((entry.plugin.manifest.artifacts?.targets ?? [])
|
|
3648
|
+
.filter((target) => target.platform === 'codex'
|
|
3649
|
+
&& target.target === 'codex.skill'
|
|
3650
|
+
&& target.delivery?.mode === 'codex-native')
|
|
3651
|
+
.map((target) => target.skillKey));
|
|
3652
|
+
const marketplaceRoot = preparedTarget.identity.marketplaceRoot;
|
|
3653
|
+
const legacyNativeSkills = preparedTarget.ownedComponents.filter((component) => component.kind === 'skill-directory'
|
|
3654
|
+
&& nativeSkillKeys.has(component.identity.artifactKey)
|
|
3655
|
+
&& (!marketplaceRoot || path.relative(marketplaceRoot, component.path).startsWith('..')));
|
|
3656
|
+
if (legacyNativeSkills.length > 0) {
|
|
3657
|
+
result = await executeRebuildComponentCleanup({
|
|
3658
|
+
command: options.command,
|
|
3659
|
+
target: preparedTarget,
|
|
3660
|
+
driver: lockedPreparation.integration.driver,
|
|
3661
|
+
components: legacyNativeSkills,
|
|
3662
|
+
actions,
|
|
3663
|
+
onActionEvent: (event) => emitRebuildActionEvent(executionContext, event),
|
|
3664
|
+
...(rebuildCommandTestHooks?.beforeActivationLegacyCleanupMutation ? {
|
|
3665
|
+
beforeMutation: rebuildCommandTestHooks.beforeActivationLegacyCleanupMutation,
|
|
3666
|
+
} : {}),
|
|
3667
|
+
...(rebuildCommandTestHooks?.afterActivationLegacyCleanupQuarantine ? {
|
|
3668
|
+
afterQuarantine: rebuildCommandTestHooks.afterActivationLegacyCleanupQuarantine,
|
|
3669
|
+
} : {}),
|
|
3670
|
+
});
|
|
3671
|
+
}
|
|
3672
|
+
}
|
|
3673
|
+
result ??= {
|
|
3260
3674
|
status: 'succeeded', command: options.command, target: identity,
|
|
3261
|
-
actions
|
|
3675
|
+
actions,
|
|
3262
3676
|
cleanupAttempted: false, removed: [], absent: [], residual: [], quarantined: [], failures: [],
|
|
3263
3677
|
};
|
|
3264
|
-
deferredPostApplyTasks.push({
|
|
3265
|
-
pluginId: entry.pluginId,
|
|
3266
|
-
run: () => runPostApplyScript({
|
|
3267
|
-
plugin: entry.plugin,
|
|
3268
|
-
platform,
|
|
3269
|
-
scope: planned.resolvedScope,
|
|
3270
|
-
cwd: options.commandOptions.cwd,
|
|
3271
|
-
context: executionContext,
|
|
3272
|
-
artifacts: [],
|
|
3273
|
-
components: [{
|
|
3274
|
-
kind: 'target',
|
|
3275
|
-
key: `${platform}:${planned.resolvedScope}`,
|
|
3276
|
-
outcome: 'unchanged',
|
|
3277
|
-
}],
|
|
3278
|
-
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
3279
|
-
}),
|
|
3280
|
-
onFailure: (error) => {
|
|
3281
|
-
warnings.push(error instanceof Error ? error.message : String(error));
|
|
3282
|
-
result.actions[0].status = 'failed';
|
|
3283
|
-
},
|
|
3284
|
-
});
|
|
3285
3678
|
results.push({
|
|
3286
|
-
platforms: [platform],
|
|
3287
|
-
|
|
3288
|
-
|
|
3679
|
+
platforms: [platform],
|
|
3680
|
+
plugins: result.status === 'succeeded' ? [identity.pluginName] : [],
|
|
3681
|
+
warnings: result.failures.map((failure) => failure.message),
|
|
3682
|
+
rebuildResults: [result],
|
|
3683
|
+
targetResults: [{ ...toTargetResult(result), action: planned.action }],
|
|
3684
|
+
overallState: result.status === 'succeeded' ? 'succeeded' : 'failed',
|
|
3289
3685
|
receiptTargets: [{
|
|
3290
3686
|
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
3291
3687
|
sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
|
|
3292
3688
|
}],
|
|
3293
3689
|
});
|
|
3294
|
-
dependencyStates.set(`${entry.pluginId}\0${platform}`, 'completed');
|
|
3690
|
+
dependencyStates.set(`${entry.pluginId}\0${platform}`, result.status === 'succeeded' ? 'completed' : 'failed');
|
|
3295
3691
|
continue;
|
|
3296
3692
|
}
|
|
3297
3693
|
if (platform === 'codex'
|
|
@@ -3318,33 +3714,39 @@ export async function runRebuildCommand(options) {
|
|
|
3318
3714
|
&& !reconcileObsolete
|
|
3319
3715
|
&& options.command !== 'cleanup'
|
|
3320
3716
|
&& options.command !== 'uninstall') {
|
|
3321
|
-
const
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3717
|
+
const preparedError = preparedTargetErrors.get(`${entry.pluginId}\0${platform}`);
|
|
3718
|
+
if (preparedError) {
|
|
3719
|
+
const message = preparedError instanceof Error
|
|
3720
|
+
? preparedError.message
|
|
3721
|
+
: String(preparedError);
|
|
3722
|
+
const result = failedResult(options.command, identity, message);
|
|
3723
|
+
results.push({
|
|
3724
|
+
platforms: [platform], plugins: [], warnings: [], rebuildResults: [result],
|
|
3725
|
+
targetResults: [{
|
|
3726
|
+
target: identity,
|
|
3727
|
+
action: planned.action,
|
|
3728
|
+
state: 'failed',
|
|
3729
|
+
errorCode: message.split(':', 1)[0] ?? 'targetPreparationFailed',
|
|
3730
|
+
message,
|
|
3731
|
+
}],
|
|
3732
|
+
overallState: 'failed',
|
|
3733
|
+
receiptTargets: [{
|
|
3734
|
+
pluginName: identity.pluginName, pluginId: identity.pluginId,
|
|
3735
|
+
sourceId: identity.sourceId, platform, scope: planned.resolvedScope,
|
|
3334
3736
|
}],
|
|
3335
|
-
scriptTimeoutMs: options.commandOptions.scriptTimeoutMs,
|
|
3336
3737
|
});
|
|
3738
|
+
dependencyStates.set(`${entry.pluginId}\0${platform}`, 'failed');
|
|
3739
|
+
continue;
|
|
3337
3740
|
}
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
}
|
|
3741
|
+
const actions = operationPreparations.get(`${entry.pluginId}\0${platform}`)?.actions
|
|
3742
|
+
?? [];
|
|
3341
3743
|
const result = {
|
|
3342
3744
|
status: 'succeeded', command: options.command, target: identity,
|
|
3343
|
-
actions
|
|
3745
|
+
actions,
|
|
3344
3746
|
cleanupAttempted: false, removed: [], absent: [], residual: [], quarantined: [], failures: [],
|
|
3345
3747
|
};
|
|
3346
3748
|
results.push({
|
|
3347
|
-
platforms: [platform], plugins: [identity.pluginName], warnings, rebuildResults: [result],
|
|
3749
|
+
platforms: [platform], plugins: [identity.pluginName], warnings: [], rebuildResults: [result],
|
|
3348
3750
|
targetResults: [{ target: identity, action: 'keep', state: 'completed' }],
|
|
3349
3751
|
overallState: 'succeeded',
|
|
3350
3752
|
receiptTargets: [{
|
|
@@ -3359,6 +3761,7 @@ export async function runRebuildCommand(options) {
|
|
|
3359
3761
|
const namespacedSource = {
|
|
3360
3762
|
sourceId: entry.source.sourceId,
|
|
3361
3763
|
sourceIdentity: entry.source.sourceIdentity,
|
|
3764
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
3362
3765
|
marketplaceName,
|
|
3363
3766
|
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
|
|
3364
3767
|
};
|
|
@@ -3400,6 +3803,7 @@ export async function runRebuildCommand(options) {
|
|
|
3400
3803
|
: {}),
|
|
3401
3804
|
sourceId: entry.source.sourceId,
|
|
3402
3805
|
sourceIdentity: entry.source.sourceIdentity,
|
|
3806
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
3403
3807
|
resolvedCommit: entry.source.resolvedCommit,
|
|
3404
3808
|
manifestDigest: entry.source.manifestDigest,
|
|
3405
3809
|
snapshotDigest: entry.source.snapshotDigest,
|
|
@@ -3411,10 +3815,10 @@ export async function runRebuildCommand(options) {
|
|
|
3411
3815
|
reviewCompleted: true,
|
|
3412
3816
|
targetHookCompleted: true,
|
|
3413
3817
|
prepared: preparedTargets.get(`${entry.pluginId}\0${platform}`),
|
|
3818
|
+
operationPreparation: operationPreparations.get(`${entry.pluginId}\0${platform}`),
|
|
3819
|
+
integration: lockedPreparation.integration,
|
|
3414
3820
|
preparationError: preparedTargetErrors.get(`${entry.pluginId}\0${platform}`),
|
|
3415
|
-
|
|
3416
|
-
? { deferredPostApplyTasks }
|
|
3417
|
-
: {}),
|
|
3821
|
+
skipPreApply: reconcileDesiredCleanup,
|
|
3418
3822
|
},
|
|
3419
3823
|
});
|
|
3420
3824
|
if (reconcileDesiredCleanup) {
|
|
@@ -3426,14 +3830,84 @@ export async function runRebuildCommand(options) {
|
|
|
3426
3830
|
results.push(executionResult);
|
|
3427
3831
|
dependencyStates.set(`${entry.pluginId}\0${platform}`, executionResult.overallState === 'succeeded' ? 'completed' : 'failed');
|
|
3428
3832
|
}
|
|
3833
|
+
const failCompletedCodexTarget = (options_) => {
|
|
3834
|
+
const resultIndex = results.findIndex((candidate) => candidate.targetResults.some((target) => target.target.pluginId === options_.identity.pluginId
|
|
3835
|
+
&& target.target.platform === 'codex'
|
|
3836
|
+
&& target.target.scope === options_.identity.scope));
|
|
3837
|
+
if (resultIndex === -1)
|
|
3838
|
+
return false;
|
|
3839
|
+
const existing = results[resultIndex];
|
|
3840
|
+
const phase = options_.phase ?? 'postcheck.inspect';
|
|
3841
|
+
const rebuildResults = existing.rebuildResults.map((rebuild) => {
|
|
3842
|
+
if (rebuild.target.pluginId !== options_.identity.pluginId
|
|
3843
|
+
|| rebuild.target.platform !== 'codex'
|
|
3844
|
+
|| rebuild.target.scope !== options_.identity.scope)
|
|
3845
|
+
return rebuild;
|
|
3846
|
+
if (!rebuild.failures.some((failure) => failure.phase === phase && failure.message === options_.message)) {
|
|
3847
|
+
rebuild.failures.unshift({ phase, message: options_.message });
|
|
3848
|
+
}
|
|
3849
|
+
return {
|
|
3850
|
+
...rebuild,
|
|
3851
|
+
status: 'failed',
|
|
3852
|
+
actions: rebuild.actions,
|
|
3853
|
+
error: { phase, message: options_.message },
|
|
3854
|
+
};
|
|
3855
|
+
});
|
|
3856
|
+
results[resultIndex] = {
|
|
3857
|
+
...existing,
|
|
3858
|
+
plugins: existing.plugins.filter((pluginName) => pluginName !== options_.identity.pluginName),
|
|
3859
|
+
rebuildResults,
|
|
3860
|
+
targetResults: existing.targetResults.map((target) => target.target.pluginId === options_.identity.pluginId
|
|
3861
|
+
&& target.target.platform === 'codex'
|
|
3862
|
+
&& target.target.scope === options_.identity.scope
|
|
3863
|
+
? {
|
|
3864
|
+
...target,
|
|
3865
|
+
target: options_.identity,
|
|
3866
|
+
action: options_.action ?? target.action,
|
|
3867
|
+
state: 'failed',
|
|
3868
|
+
errorCode: options_.message.split(':', 1)[0] ?? 'codexActivationPostcheckFailed',
|
|
3869
|
+
message: options_.message,
|
|
3870
|
+
...(options_.recoveryActions
|
|
3871
|
+
? { recoveryActions: options_.recoveryActions }
|
|
3872
|
+
: {}),
|
|
3873
|
+
}
|
|
3874
|
+
: target),
|
|
3875
|
+
overallState: 'failed',
|
|
3876
|
+
};
|
|
3877
|
+
dependencyStates.set(`${options_.identity.pluginId}\0codex`, 'failed');
|
|
3878
|
+
return true;
|
|
3879
|
+
};
|
|
3880
|
+
const activationMutationPluginIds = new Set(lockedCodexPlans.flatMap((plan) => [
|
|
3881
|
+
...plan.activationActions.user,
|
|
3882
|
+
...plan.activationActions.project,
|
|
3883
|
+
].flatMap((action) => action.action === 'none' ? [] : [action.pluginId])));
|
|
3884
|
+
for (const { entry, platform } of executionSelections) {
|
|
3885
|
+
if (platform !== 'codex'
|
|
3886
|
+
|| !activationMutationPluginIds.has(entry.pluginId)
|
|
3887
|
+
|| (dependencyStates.get(`${entry.pluginId}\0${platform}`) !== 'completed'
|
|
3888
|
+
&& dependencyStates.get(`${entry.pluginId}\0${platform}`) !== 'kept'))
|
|
3889
|
+
continue;
|
|
3890
|
+
const prepared = preparedTargets.get(`${entry.pluginId}\0${platform}`)?.target;
|
|
3891
|
+
if (!prepared)
|
|
3892
|
+
continue;
|
|
3893
|
+
try {
|
|
3894
|
+
await lockedPreparation.integration.prepareNativeMarketplaceGroup(prepared);
|
|
3895
|
+
}
|
|
3896
|
+
catch (error) {
|
|
3897
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
3898
|
+
failCompletedCodexTarget({ identity: prepared.identity, message, phase: 'native.write' });
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3429
3901
|
const successfulCodexPluginIds = new Set(executionSelections.flatMap(({ entry, platform }) => platform === 'codex'
|
|
3430
3902
|
&& (dependencyStates.get(`${entry.pluginId}\0${platform}`) === 'completed'
|
|
3431
3903
|
|| dependencyStates.get(`${entry.pluginId}\0${platform}`) === 'kept')
|
|
3432
3904
|
? [entry.pluginId]
|
|
3433
3905
|
: []));
|
|
3434
3906
|
const activationPlans = selectCodexActivationPlans(lockedCodexPlans, successfulCodexPluginIds);
|
|
3435
|
-
if (activationPlans.length > 0
|
|
3436
|
-
|
|
3907
|
+
if (activationPlans.length > 0
|
|
3908
|
+
|| lockedPreparation.integration.driver.completePostchecks) {
|
|
3909
|
+
let activationError;
|
|
3910
|
+
const activationMutationMarketplaces = new Set();
|
|
3437
3911
|
try {
|
|
3438
3912
|
if (activationPlans.length > 0) {
|
|
3439
3913
|
await executeCodexReconcileActivations({
|
|
@@ -3442,23 +3916,67 @@ export async function runRebuildCommand(options) {
|
|
|
3442
3916
|
env: runtimeEnv,
|
|
3443
3917
|
manager: executionContext.codexManager,
|
|
3444
3918
|
runner: executionContext.nativeCliRunner,
|
|
3919
|
+
observationSession: executionContext.codexObservationSession,
|
|
3920
|
+
preflightCompleted: true,
|
|
3921
|
+
mutationMarketplaces: activationMutationMarketplaces,
|
|
3922
|
+
observationScopeByMarketplace: codexObservationScopeByMarketplace,
|
|
3445
3923
|
});
|
|
3446
3924
|
}
|
|
3447
3925
|
}
|
|
3448
3926
|
catch (error) {
|
|
3449
|
-
|
|
3450
|
-
|
|
3927
|
+
activationError = error;
|
|
3928
|
+
}
|
|
3929
|
+
try {
|
|
3930
|
+
await lockedPreparation.integration.captureCodexPostMutationSnapshots([...activationMutationMarketplaces]);
|
|
3931
|
+
}
|
|
3932
|
+
catch (error) {
|
|
3933
|
+
activationError ??= error;
|
|
3934
|
+
}
|
|
3935
|
+
const failedCodexPluginIds = new Set(executionSelections.flatMap(({ entry, platform }) => platform === 'codex'
|
|
3936
|
+
&& (dependencyStates.get(`${entry.pluginId}\0${platform}`) === 'failed'
|
|
3937
|
+
|| dependencyStates.get(`${entry.pluginId}\0${platform}`) === 'skipped')
|
|
3938
|
+
? [entry.pluginId]
|
|
3939
|
+
: []));
|
|
3940
|
+
for (const failure of await lockedPreparation.integration.driver.completePostchecks?.() ?? []) {
|
|
3941
|
+
const message = failure.error instanceof Error
|
|
3942
|
+
? failure.error.message
|
|
3943
|
+
: String(failure.error);
|
|
3944
|
+
if (failCompletedCodexTarget({ identity: failure.target.identity, message })) {
|
|
3945
|
+
failedCodexPluginIds.add(failure.target.identity.pluginId ?? failure.target.identity.pluginName);
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
if (!activationError && activationPlans.length > 0) {
|
|
3949
|
+
const postcheckPluginIds = new Set([...successfulCodexPluginIds]
|
|
3950
|
+
.filter((pluginId) => !failedCodexPluginIds.has(pluginId)));
|
|
3951
|
+
const postcheckPlans = selectCodexActivationPlans(activationPlans, postcheckPluginIds);
|
|
3952
|
+
try {
|
|
3953
|
+
await postcheckCodexReconcileActivations({
|
|
3954
|
+
plans: postcheckPlans,
|
|
3955
|
+
cwd: options.commandOptions.cwd,
|
|
3956
|
+
env: runtimeEnv,
|
|
3957
|
+
manager: executionContext.codexManager,
|
|
3958
|
+
runner: executionContext.nativeCliRunner,
|
|
3959
|
+
observationScopeByMarketplace: codexObservationScopeByMarketplace,
|
|
3960
|
+
observationSession: executionContext.codexObservationSession,
|
|
3961
|
+
});
|
|
3962
|
+
}
|
|
3963
|
+
catch (error) {
|
|
3964
|
+
activationError = error;
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
if (activationError) {
|
|
3968
|
+
const failedActivationPluginIds = failedCodexActivationPluginIds({
|
|
3969
|
+
error: activationError,
|
|
3451
3970
|
plans: activationPlans,
|
|
3452
3971
|
successfulPluginIds: successfulCodexPluginIds,
|
|
3453
3972
|
});
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
3973
|
+
const message = activationError instanceof Error
|
|
3974
|
+
? activationError.message
|
|
3975
|
+
: String(activationError);
|
|
3458
3976
|
const failedSelections = executionSelections.filter((candidate) => candidate.platform === 'codex'
|
|
3459
3977
|
&& failedActivationPluginIds.has(candidate.entry.pluginId));
|
|
3460
3978
|
if (failedSelections.length === 0)
|
|
3461
|
-
throw
|
|
3979
|
+
throw activationError;
|
|
3462
3980
|
for (const selection of failedSelections) {
|
|
3463
3981
|
const planned = lockedPlan.targets.find((target) => target.pluginId === selection.entry.pluginId && target.platform === 'codex');
|
|
3464
3982
|
const identity = {
|
|
@@ -3471,44 +3989,48 @@ export async function runRebuildCommand(options) {
|
|
|
3471
3989
|
scope: planned.resolvedScope,
|
|
3472
3990
|
cwd: options.commandOptions.cwd,
|
|
3473
3991
|
};
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
if (resultIndex === -1)
|
|
3478
|
-
throw error;
|
|
3479
|
-
const existing = results[resultIndex];
|
|
3480
|
-
const failed = failedResult(options.command, identity, message, 'postcheck.inspect');
|
|
3481
|
-
results[resultIndex] = {
|
|
3482
|
-
...existing,
|
|
3483
|
-
plugins: existing.plugins.filter((pluginName) => pluginName !== identity.pluginName),
|
|
3484
|
-
rebuildResults: existing.rebuildResults.map((rebuild) => rebuild.target.pluginId === identity.pluginId
|
|
3485
|
-
&& rebuild.target.platform === 'codex'
|
|
3486
|
-
&& rebuild.target.scope === identity.scope
|
|
3487
|
-
? failed
|
|
3488
|
-
: rebuild),
|
|
3489
|
-
targetResults: existing.targetResults.map((target) => target.target.pluginId === identity.pluginId
|
|
3490
|
-
&& target.target.platform === 'codex'
|
|
3491
|
-
&& target.target.scope === identity.scope
|
|
3492
|
-
? {
|
|
3493
|
-
target: identity,
|
|
3494
|
-
action: target.action,
|
|
3495
|
-
state: 'failed',
|
|
3496
|
-
errorCode: message.split(':', 1)[0] ?? 'codexActivationPostcheckFailed',
|
|
3497
|
-
message,
|
|
3498
|
-
}
|
|
3499
|
-
: target),
|
|
3500
|
-
overallState: 'failed',
|
|
3501
|
-
};
|
|
3992
|
+
if (!failCompletedCodexTarget({ identity, message }))
|
|
3993
|
+
throw activationError;
|
|
3994
|
+
failedCodexPluginIds.add(selection.entry.pluginId);
|
|
3502
3995
|
}
|
|
3503
3996
|
}
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3997
|
+
let propagated = true;
|
|
3998
|
+
while (propagated) {
|
|
3999
|
+
propagated = false;
|
|
4000
|
+
for (const selection of executionSelections.filter((candidate) => candidate.platform === 'codex')) {
|
|
4001
|
+
if (failedCodexPluginIds.has(selection.entry.pluginId))
|
|
4002
|
+
continue;
|
|
4003
|
+
const failedDependency = (selection.entry.plugin.manifest.dependencies ?? [])
|
|
4004
|
+
.map((pluginName) => formatPluginId({
|
|
4005
|
+
sourceId: selection.entry.source.sourceId,
|
|
4006
|
+
pluginName,
|
|
4007
|
+
}))
|
|
4008
|
+
.find((pluginId) => failedCodexPluginIds.has(pluginId));
|
|
4009
|
+
if (!failedDependency)
|
|
4010
|
+
continue;
|
|
4011
|
+
const planned = lockedPlan.targets.find((target) => target.pluginId === selection.entry.pluginId && target.platform === 'codex');
|
|
4012
|
+
const identity = {
|
|
4013
|
+
sourceId: selection.entry.source.sourceId,
|
|
4014
|
+
sourceIdentity: selection.entry.source.sourceIdentity,
|
|
4015
|
+
pluginId: selection.entry.pluginId,
|
|
4016
|
+
pluginName: selection.entry.plugin.manifest.name,
|
|
4017
|
+
pluginVersion: selection.entry.plugin.manifest.version,
|
|
4018
|
+
platform: 'codex',
|
|
4019
|
+
scope: planned.resolvedScope,
|
|
4020
|
+
cwd: options.commandOptions.cwd,
|
|
4021
|
+
};
|
|
4022
|
+
const message = `dependencyInstallFailed: ${selection.entry.pluginId} requires failed dependency ${failedDependency}.`;
|
|
4023
|
+
if (failCompletedCodexTarget({
|
|
4024
|
+
identity,
|
|
4025
|
+
message,
|
|
4026
|
+
recoveryActions: [
|
|
4027
|
+
`run aw sync --all --platform codex --scope ${planned.resolvedScope}`,
|
|
4028
|
+
],
|
|
4029
|
+
})) {
|
|
4030
|
+
failedCodexPluginIds.add(selection.entry.pluginId);
|
|
4031
|
+
dependencyStates.set(`${selection.entry.pluginId}\0codex`, 'failed');
|
|
4032
|
+
propagated = true;
|
|
4033
|
+
}
|
|
3512
4034
|
}
|
|
3513
4035
|
}
|
|
3514
4036
|
}
|
|
@@ -3524,8 +4046,9 @@ export async function runRebuildCommand(options) {
|
|
|
3524
4046
|
return {
|
|
3525
4047
|
...target,
|
|
3526
4048
|
recoveryActions: [
|
|
3527
|
-
`
|
|
3528
|
-
`then run aw
|
|
4049
|
+
`remove every direct and indirect dependent of ${planned.pluginId} in consumer-first order; if dependencyStillRequired is reported, handle the other reported dependents first`,
|
|
4050
|
+
`then run aw cleanup ${planned.pluginId} --platform ${planned.platform} --scope ${planned.preservedScope}`,
|
|
4051
|
+
`then reinstall every removed root at its original platform and scope, selecting --dependency-scope ${planned.pluginId}#${planned.platform}=${planned.resolvedScope} during each install`,
|
|
3529
4052
|
],
|
|
3530
4053
|
};
|
|
3531
4054
|
});
|
|
@@ -3561,6 +4084,7 @@ export async function runRebuildCommand(options) {
|
|
|
3561
4084
|
namespacedSource: {
|
|
3562
4085
|
sourceId: entry.source.sourceId,
|
|
3563
4086
|
sourceIdentity: entry.source.sourceIdentity,
|
|
4087
|
+
logicalIdentity: entry.source.logicalIdentity,
|
|
3564
4088
|
marketplaceName,
|
|
3565
4089
|
marketplaceRoot: path.join(resolveAwHome(runtimeEnv), 'marketplaces', entry.source.sourceId),
|
|
3566
4090
|
},
|
|
@@ -3585,7 +4109,7 @@ export async function runRebuildCommand(options) {
|
|
|
3585
4109
|
merged.warnings.push(MALFORMED_CONFIG_PRESERVED_WARNING);
|
|
3586
4110
|
}
|
|
3587
4111
|
merged.dependencyPlan = lockedPlan;
|
|
3588
|
-
merged.overallState = reconcileOverallState(merged.targetResults, lockedPlan);
|
|
4112
|
+
merged.overallState = reconcileOverallState(merged.targetResults, lockedPlan, merged.rebuildResults);
|
|
3589
4113
|
if (lockedCodexPlans.length > 0)
|
|
3590
4114
|
merged.codexReconcilePlans = lockedCodexPlans;
|
|
3591
4115
|
merged.operationPlan = lockedOperationPlan;
|
|
@@ -3596,8 +4120,8 @@ export async function runRebuildCommand(options) {
|
|
|
3596
4120
|
try {
|
|
3597
4121
|
await (options.runtime?.removeObsoleteInstallationContracts ?? fs.remove)(path.join(resolveAwHome(runtimeEnv), 'installation-contracts'));
|
|
3598
4122
|
}
|
|
3599
|
-
catch
|
|
3600
|
-
resolvedResult.warnings.push(
|
|
4123
|
+
catch {
|
|
4124
|
+
resolvedResult.warnings.push(OBSOLETE_CONTRACTS_CLEANUP_WARNING);
|
|
3601
4125
|
}
|
|
3602
4126
|
}
|
|
3603
4127
|
return resolvedResult;
|
|
@@ -3623,4 +4147,25 @@ export async function runRebuildCommand(options) {
|
|
|
3623
4147
|
throw error;
|
|
3624
4148
|
}
|
|
3625
4149
|
}
|
|
4150
|
+
export async function runRebuildCommand(options) {
|
|
4151
|
+
if (options.runtime?.codexObservationSession) {
|
|
4152
|
+
return runRebuildCommandInSession(options);
|
|
4153
|
+
}
|
|
4154
|
+
const env = options.runtime?.env ?? process.env;
|
|
4155
|
+
const session = await createCodexNativeObservationSession({
|
|
4156
|
+
exactCwd: options.commandOptions.cwd,
|
|
4157
|
+
env,
|
|
4158
|
+
runner: options.runtime?.nativeCliRunner ?? getDefaultNativeCliRunner(),
|
|
4159
|
+
manager: options.runtime?.codexManager,
|
|
4160
|
+
});
|
|
4161
|
+
try {
|
|
4162
|
+
return await runRebuildCommandInSession({
|
|
4163
|
+
...options,
|
|
4164
|
+
runtime: { ...options.runtime, codexObservationSession: session },
|
|
4165
|
+
});
|
|
4166
|
+
}
|
|
4167
|
+
finally {
|
|
4168
|
+
await session.dispose();
|
|
4169
|
+
}
|
|
4170
|
+
}
|
|
3626
4171
|
//# sourceMappingURL=rebuild-command.js.map
|