@lesliechan721/aw 0.1.0-beta.6 → 0.1.0-beta.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/authoring/scripts/init-plugin.mjs +4 -33
- package/dist/authoring/scripts/init-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +1 -1
- package/dist/authoring/scripts/plugin-status.mjs +8 -11
- package/dist/authoring/scripts/plugin-status.mjs.map +1 -1
- package/dist/authoring/scripts/remove-plugin.mjs +1 -0
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -1
- package/dist/authoring/scripts/validate-plugin.mjs +104 -54
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/codex-eval-app-server.d.ts +2 -0
- package/dist/scripts/codex-eval-app-server.js +107 -1
- package/dist/scripts/codex-eval-app-server.js.map +1 -1
- package/dist/scripts/eval-plugin-skills.js +5 -2
- package/dist/scripts/eval-plugin-skills.js.map +1 -1
- package/dist/scripts/plugin-eval-contract.d.ts +5 -1
- package/dist/scripts/plugin-eval-contract.js +54 -4
- package/dist/scripts/plugin-eval-contract.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +6 -7
- package/dist/scripts/plugin-staging.js +11 -23
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/scripts/test-plugin-scripts.js +2 -33
- package/dist/scripts/test-plugin-scripts.js.map +1 -1
- package/dist/src/adapters/helpers.js +2 -2
- package/dist/src/adapters/helpers.js.map +1 -1
- package/dist/src/authoring/workspace-commands.d.ts +17 -2
- package/dist/src/authoring/workspace-commands.js +21 -4
- package/dist/src/authoring/workspace-commands.js.map +1 -1
- package/dist/src/commands/aw-capabilities.d.ts +78 -0
- package/dist/src/commands/aw-capabilities.js +259 -0
- package/dist/src/commands/aw-capabilities.js.map +1 -0
- package/dist/src/commands/catalog-context.d.ts +52 -0
- package/dist/src/commands/catalog-context.js +156 -0
- package/dist/src/commands/catalog-context.js.map +1 -0
- package/dist/src/commands/catalog-dev-source.d.ts +112 -0
- package/dist/src/commands/catalog-dev-source.js +481 -0
- package/dist/src/commands/catalog-dev-source.js.map +1 -0
- package/dist/src/commands/catalog-generation.d.ts +26 -0
- package/dist/src/commands/catalog-generation.js +14 -0
- package/dist/src/commands/catalog-generation.js.map +1 -0
- package/dist/src/commands/catalog-publication-inspection.d.ts +1 -1
- package/dist/src/commands/catalog-publication-inspection.js +4 -5
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -1
- package/dist/src/commands/catalog-publication-target.d.ts +17 -0
- package/dist/src/commands/catalog-publication-target.js +60 -0
- package/dist/src/commands/catalog-publication-target.js.map +1 -0
- package/dist/src/commands/catalog-publish.d.ts +8 -1
- package/dist/src/commands/catalog-publish.js +25 -2
- package/dist/src/commands/catalog-publish.js.map +1 -1
- package/dist/src/commands/catalog-source.d.ts +23 -1
- package/dist/src/commands/catalog-source.js +126 -40
- package/dist/src/commands/catalog-source.js.map +1 -1
- package/dist/src/commands/catalog-status.d.ts +18 -2
- package/dist/src/commands/catalog-status.js +122 -18
- package/dist/src/commands/catalog-status.js.map +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/offline-cleanup-evidence.d.ts +23 -0
- package/dist/src/commands/offline-cleanup-evidence.js +38 -0
- package/dist/src/commands/offline-cleanup-evidence.js.map +1 -0
- package/dist/src/commands/options.d.ts +1 -0
- package/dist/src/commands/options.js +1 -0
- package/dist/src/commands/options.js.map +1 -1
- package/dist/src/commands/plugin-capabilities.js +1 -1
- package/dist/src/commands/plugin-capabilities.js.map +1 -1
- package/dist/src/commands/rebuild-command.d.ts +19 -7
- package/dist/src/commands/rebuild-command.js +415 -205
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +10 -3
- package/dist/src/commands/rebuild-integration.js +73 -76
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/rebuild-operations.d.ts +0 -8
- package/dist/src/commands/rebuild-operations.js +17 -115
- package/dist/src/commands/rebuild-operations.js.map +1 -1
- package/dist/src/commands/runtime.js +21 -34
- package/dist/src/commands/runtime.js.map +1 -1
- package/dist/src/commands/{status-v4.d.ts → status-v5.d.ts} +67 -21
- package/dist/src/commands/{status-v4.js → status-v5.js} +260 -30
- package/dist/src/commands/status-v5.js.map +1 -0
- package/dist/src/commands/wizard.d.ts +2 -2
- package/dist/src/commands/wizard.js +2 -2
- package/dist/src/commands/wizard.js.map +1 -1
- package/dist/src/commands/write-commands.js +73 -17
- package/dist/src/commands/write-commands.js.map +1 -1
- package/dist/src/constants.d.ts +6 -1
- package/dist/src/constants.js +6 -1
- package/dist/src/constants.js.map +1 -1
- package/dist/src/generators/local-plugin.js +57 -3
- package/dist/src/generators/local-plugin.js.map +1 -1
- package/dist/src/index.d.ts +4 -1
- package/dist/src/index.js +562 -85
- package/dist/src/index.js.map +1 -1
- package/dist/src/output/model.d.ts +1 -34
- package/dist/src/output/model.js +1 -144
- package/dist/src/output/model.js.map +1 -1
- package/dist/src/output/rebuild-progress.js +0 -3
- package/dist/src/output/rebuild-progress.js.map +1 -1
- package/dist/src/portable/commands.d.ts +4 -0
- package/dist/src/portable/commands.js +61 -4
- package/dist/src/portable/commands.js.map +1 -1
- package/dist/src/portable/materializer.d.ts +3 -0
- package/dist/src/portable/materializer.js +61 -10
- package/dist/src/portable/materializer.js.map +1 -1
- package/dist/src/tui/catalog-generation.d.ts +56 -0
- package/dist/src/tui/catalog-generation.js +244 -0
- package/dist/src/tui/catalog-generation.js.map +1 -0
- package/dist/src/tui/console-app-v4.d.ts +1 -1
- package/dist/src/tui/console-app-v4.js +446 -126
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +8 -2
- package/dist/src/tui/controller-runtime.js +606 -92
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +71 -6
- package/dist/src/tui/controller.js +377 -83
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/index.d.ts +1 -0
- package/dist/src/tui/index.js +1 -0
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/input-display.d.ts +8 -0
- package/dist/src/tui/input-display.js +36 -0
- package/dist/src/tui/input-display.js.map +1 -0
- package/dist/src/tui/model.d.ts +27 -7
- package/dist/src/tui/model.js +273 -65
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/router.d.ts +26 -0
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/source-ref-presets.d.ts +3 -0
- package/dist/src/tui/source-ref-presets.js +11 -0
- package/dist/src/tui/source-ref-presets.js.map +1 -0
- package/dist/src/tui/views.js +31 -3
- package/dist/src/tui/views.js.map +1 -1
- package/dist/src/types.d.ts +90 -6
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/agent-version.d.ts +3 -0
- package/dist/src/utils/agent-version.js +13 -5
- package/dist/src/utils/agent-version.js.map +1 -1
- package/dist/src/utils/aw-home-mutation-lock.d.ts +1 -0
- package/dist/src/utils/aw-home-mutation-lock.js +32 -4
- package/dist/src/utils/aw-home-mutation-lock.js.map +1 -1
- package/dist/src/utils/bundle-integrity.d.ts +0 -1
- package/dist/src/utils/bundle-integrity.js +0 -25
- package/dist/src/utils/bundle-integrity.js.map +1 -1
- package/dist/src/utils/bundle-layout.js +8 -6
- package/dist/src/utils/bundle-layout.js.map +1 -1
- package/dist/src/utils/catalog-digests.js +13 -2
- package/dist/src/utils/catalog-digests.js.map +1 -1
- package/dist/src/utils/catalog-generation-error.d.ts +12 -0
- package/dist/src/utils/catalog-generation-error.js +16 -0
- package/dist/src/utils/catalog-generation-error.js.map +1 -0
- package/dist/src/utils/catalog-generation-resolver.d.ts +13 -0
- package/dist/src/utils/catalog-generation-resolver.js +129 -0
- package/dist/src/utils/catalog-generation-resolver.js.map +1 -0
- package/dist/src/utils/catalog-generation-service.d.ts +52 -0
- package/dist/src/utils/catalog-generation-service.js +620 -0
- package/dist/src/utils/catalog-generation-service.js.map +1 -0
- package/dist/src/utils/catalog-generation-state.d.ts +13 -0
- package/dist/src/utils/catalog-generation-state.js +201 -0
- package/dist/src/utils/catalog-generation-state.js.map +1 -0
- package/dist/src/utils/catalog-generation-store.d.ts +44 -0
- package/dist/src/utils/catalog-generation-store.js +387 -0
- package/dist/src/utils/catalog-generation-store.js.map +1 -0
- package/dist/src/utils/catalog-manifest-v5.d.ts +5 -0
- package/dist/src/utils/{catalog-manifest-v4.js → catalog-manifest-v5.js} +39 -35
- package/dist/src/utils/{catalog-manifest-v4.js.map → catalog-manifest-v5.js.map} +1 -1
- package/dist/src/utils/catalog-operation-context.d.ts +28 -0
- package/dist/src/utils/catalog-operation-context.js +242 -0
- package/dist/src/utils/catalog-operation-context.js.map +1 -0
- package/dist/src/utils/catalog-public-error.d.ts +7 -3
- package/dist/src/utils/catalog-public-error.js +20 -4
- package/dist/src/utils/catalog-public-error.js.map +1 -1
- package/dist/src/utils/catalog-snapshot.d.ts +5 -3
- package/dist/src/utils/catalog-snapshot.js +11 -3
- package/dist/src/utils/catalog-snapshot.js.map +1 -1
- package/dist/src/utils/catalog-source-cache.d.ts +1 -1
- package/dist/src/utils/catalog-source-cache.js +37 -12
- package/dist/src/utils/catalog-source-cache.js.map +1 -1
- package/dist/src/utils/catalog-source-identity.d.ts +1 -0
- package/dist/src/utils/catalog-source-identity.js +21 -2
- package/dist/src/utils/catalog-source-identity.js.map +1 -1
- package/dist/src/utils/catalog-sources.d.ts +1 -0
- package/dist/src/utils/catalog-sources.js +30 -11
- package/dist/src/utils/catalog-sources.js.map +1 -1
- package/dist/src/utils/codex-config.js +4 -4
- package/dist/src/utils/codex-config.js.map +1 -1
- package/dist/src/utils/codex-manager.d.ts +33 -0
- package/dist/src/utils/codex-manager.js +656 -0
- package/dist/src/utils/codex-manager.js.map +1 -0
- package/dist/src/utils/codex-skill-staging.d.ts +2 -0
- package/dist/src/utils/codex-skill-staging.js.map +1 -1
- package/dist/src/utils/dynamic-skill-tree.d.ts +4 -0
- package/dist/src/utils/dynamic-skill-tree.js +35 -5
- package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.js +10 -25
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/lifecycle-active-store.d.ts +0 -28
- package/dist/src/utils/lifecycle-active-store.js +35 -247
- package/dist/src/utils/lifecycle-active-store.js.map +1 -1
- package/dist/src/utils/multi-source-catalog.d.ts +3 -0
- package/dist/src/utils/multi-source-catalog.js +120 -10
- package/dist/src/utils/multi-source-catalog.js.map +1 -1
- package/dist/src/utils/native-cli.d.ts +15 -6
- package/dist/src/utils/native-cli.js +31 -39
- package/dist/src/utils/native-cli.js.map +1 -1
- package/dist/src/utils/orphan-marketplace-cleanup.js +0 -3
- package/dist/src/utils/orphan-marketplace-cleanup.js.map +1 -1
- package/dist/src/utils/ownership.d.ts +10 -1
- package/dist/src/utils/ownership.js +52 -24
- package/dist/src/utils/ownership.js.map +1 -1
- package/dist/src/utils/path-catalog-provider.js +12 -8
- package/dist/src/utils/path-catalog-provider.js.map +1 -1
- package/dist/src/utils/plugin-config-write.js +18 -35
- package/dist/src/utils/plugin-config-write.js.map +1 -1
- package/dist/src/utils/plugin-config.d.ts +1 -12
- package/dist/src/utils/plugin-config.js +107 -226
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/plugin-scripts.d.ts +1 -1
- package/dist/src/utils/plugin-scripts.js +1 -1
- package/dist/src/utils/plugin-scripts.js.map +1 -1
- package/dist/src/utils/state-paths.js +7 -2
- package/dist/src/utils/state-paths.js.map +1 -1
- package/dist/src/utils/target-eligibility.d.ts +7 -2
- package/dist/src/utils/target-eligibility.js +6 -3
- package/dist/src/utils/target-eligibility.js.map +1 -1
- package/package.json +4 -3
- package/dist/authoring/scripts/check-plugin-versions.d.mts +0 -2
- package/dist/authoring/scripts/check-plugin-versions.mjs +0 -5
- package/dist/authoring/scripts/check-plugin-versions.mjs.map +0 -1
- package/dist/src/commands/status-v4.js.map +0 -1
- package/dist/src/commands/status.d.ts +0 -93
- package/dist/src/commands/status.js +0 -442
- package/dist/src/commands/status.js.map +0 -1
- package/dist/src/utils/active-marketplace-runtime-lock.d.ts +0 -12
- package/dist/src/utils/active-marketplace-runtime-lock.js +0 -133
- package/dist/src/utils/active-marketplace-runtime-lock.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v3.d.ts +0 -2
- package/dist/src/utils/catalog-manifest-v3.js +0 -3
- package/dist/src/utils/catalog-manifest-v3.js.map +0 -1
- package/dist/src/utils/catalog-manifest-v4.d.ts +0 -5
package/dist/src/tui/model.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { PlatformName, PluginConfigFieldType, PluginConfigPresentationPreset, PluginConfigSchema, Scope } from '../types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { StatusV5Payload, StatusV5PluginSummary, StatusV5Target, StatusV5Component, StatusTargetRevision, TargetRevisionState } from '../commands/status-v5.js';
|
|
3
3
|
import type { ResolvedConfigRead } from '../utils/plugin-config.js';
|
|
4
4
|
import { type DiagnosticSummaryViewModel } from './diagnostics.js';
|
|
5
5
|
export type SourceHealthState = 'ready' | 'cache' | 'path' | 'checking' | 'degraded' | 'unavailable';
|
|
@@ -54,13 +54,19 @@ export interface PluginListItemViewModel {
|
|
|
54
54
|
supportedPlatforms: PlatformName[];
|
|
55
55
|
installedPlacements: PlatformPlacementSummary[];
|
|
56
56
|
aggregateStatus: 'available' | 'installed' | 'needsAttention' | 'unavailable';
|
|
57
|
+
primaryAttention?: {
|
|
58
|
+
severity: 'warning' | 'error';
|
|
59
|
+
code: string;
|
|
60
|
+
message: string;
|
|
61
|
+
};
|
|
57
62
|
portableSkills: boolean;
|
|
63
|
+
missingCapabilities?: string[];
|
|
58
64
|
dependencySummary?: PluginDependencySummaryViewModel;
|
|
59
65
|
technicalComponents: Array<{
|
|
60
66
|
platform: PlatformName;
|
|
61
67
|
scope: Scope;
|
|
62
68
|
key: string;
|
|
63
|
-
state:
|
|
69
|
+
state: StatusV5Component['state'];
|
|
64
70
|
errorCode?: string;
|
|
65
71
|
}>;
|
|
66
72
|
}
|
|
@@ -157,6 +163,8 @@ export interface ConfigFieldViewModel {
|
|
|
157
163
|
sourceLabel: string;
|
|
158
164
|
effectiveDisplayValue: string;
|
|
159
165
|
effectiveSourceLabel: string;
|
|
166
|
+
fallbackDisplayValue?: string;
|
|
167
|
+
fallbackSourceLabel?: string;
|
|
160
168
|
value?: string | number | boolean;
|
|
161
169
|
effectiveValue?: string | number | boolean;
|
|
162
170
|
defaultValue?: string | number | boolean;
|
|
@@ -190,7 +198,8 @@ export interface ConfigPageViewModel {
|
|
|
190
198
|
presets: ConfigPresetViewModel[];
|
|
191
199
|
storedCount: number;
|
|
192
200
|
}
|
|
193
|
-
export type UserIssueCategory = 'incompleteInstallation' | 'sourceDegraded' | 'sourceUnavailable' | 'sourceMissing' | 'sourceIdentityChanged' | 'requiredConfigMissing' | 'scopeConflict' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'legacyState' | 'diagnostic';
|
|
201
|
+
export type UserIssueCategory = 'incompleteInstallation' | 'artifactCollision' | 'sourceDegraded' | 'sourceUnavailable' | 'sourceMissing' | 'sourceIdentityChanged' | 'requiredConfigMissing' | 'scopeConflict' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'legacyState' | 'diagnostic';
|
|
202
|
+
export type UserIssueGroup = 'sourceRemoved' | 'artifactCollision' | 'sourceUnavailable' | 'dependency' | 'scope' | 'config' | 'installation' | 'diagnostic';
|
|
194
203
|
export type UserIssueActionId = 'reinstall' | 'cleanup' | 'remove' | 'refreshSource' | 'continueWithCache' | 'editSource' | 'retryLater' | 'reAddSource' | 'viewSourceChange' | 'openConfig' | 'keepUserScope' | 'keepProjectScope' | 'viewTechnical' | 'manualMigration' | 'installDependency' | 'reinstallDependency' | 'viewDependencyIssue' | 'viewDependencies';
|
|
195
204
|
export interface UserIssueActionViewModel {
|
|
196
205
|
id: UserIssueActionId;
|
|
@@ -202,10 +211,11 @@ export interface UserIssueActionViewModel {
|
|
|
202
211
|
project?: 'current' | 'other' | null;
|
|
203
212
|
writeAction?: 'install' | 'upgrade' | 'reinstall' | 'cleanup';
|
|
204
213
|
}
|
|
205
|
-
export type TargetIssueRootCode = 'partial' | 'sourceMissing' | 'sourceChanged' | 'catalogSourceUnavailable' | 'bundleUnavailable' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'targetDiagnostic';
|
|
214
|
+
export type TargetIssueRootCode = 'partial' | 'artifactCollision' | 'sourceMissing' | 'sourceChanged' | 'catalogSourceUnavailable' | 'bundleUnavailable' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'targetDiagnostic';
|
|
206
215
|
export interface UserIssueViewModel {
|
|
207
216
|
issueId: string;
|
|
208
217
|
category: UserIssueCategory;
|
|
218
|
+
group: UserIssueGroup;
|
|
209
219
|
title: string;
|
|
210
220
|
explanation: string;
|
|
211
221
|
impact: string[];
|
|
@@ -280,14 +290,14 @@ export interface PortableSkillSelectionViewModel {
|
|
|
280
290
|
};
|
|
281
291
|
canContinue: boolean;
|
|
282
292
|
}
|
|
283
|
-
export declare function projectPlatformPlacement(platform: PlatformName, targets:
|
|
293
|
+
export declare function projectPlatformPlacement(platform: PlatformName, targets: StatusV5Target[], revisions?: StatusTargetRevision[]): PlatformPlacementSummary;
|
|
284
294
|
export declare function buildPluginPreviewActions(plugin: PluginListItemViewModel): PluginMenuAction[];
|
|
285
295
|
export declare function buildPluginDetailActions(plugin: PluginListItemViewModel): PluginMenuAction[];
|
|
286
296
|
export declare function buildPlatformActions(plugin: PluginListItemViewModel, platform: PlatformName): PluginMenuAction[];
|
|
287
297
|
export declare function hasInstalledPlacement(plugin: PluginListItemViewModel): boolean;
|
|
288
298
|
export declare function buildTuiViewModel(options: {
|
|
289
|
-
status:
|
|
290
|
-
pluginSummaries:
|
|
299
|
+
status: StatusV5Payload;
|
|
300
|
+
pluginSummaries: StatusV5PluginSummary[];
|
|
291
301
|
targetRevisions?: StatusTargetRevision[];
|
|
292
302
|
sourceHealth?: ReadonlyMap<string, SourceHealthViewModel>;
|
|
293
303
|
sourceDetails?: SourceDetailViewModel[];
|
|
@@ -298,6 +308,11 @@ export declare function buildConfigGroups(options: {
|
|
|
298
308
|
schema: PluginConfigSchema;
|
|
299
309
|
read: ResolvedConfigRead;
|
|
300
310
|
effectiveRead?: ResolvedConfigRead;
|
|
311
|
+
layerReads?: {
|
|
312
|
+
user: ResolvedConfigRead;
|
|
313
|
+
project: ResolvedConfigRead;
|
|
314
|
+
local: ResolvedConfigRead;
|
|
315
|
+
};
|
|
301
316
|
dirtyKeys?: ReadonlySet<string>;
|
|
302
317
|
}): ConfigGroupViewModel[];
|
|
303
318
|
export declare function buildConfigPage(options: {
|
|
@@ -305,4 +320,9 @@ export declare function buildConfigPage(options: {
|
|
|
305
320
|
schema: PluginConfigSchema;
|
|
306
321
|
read: ResolvedConfigRead;
|
|
307
322
|
effectiveRead?: ResolvedConfigRead;
|
|
323
|
+
layerReads?: {
|
|
324
|
+
user: ResolvedConfigRead;
|
|
325
|
+
project: ResolvedConfigRead;
|
|
326
|
+
local: ResolvedConfigRead;
|
|
327
|
+
};
|
|
308
328
|
}): ConfigPageViewModel;
|
package/dist/src/tui/model.js
CHANGED
|
@@ -190,7 +190,8 @@ function targetIssues(payload) {
|
|
|
190
190
|
for (const target of payload.targets) {
|
|
191
191
|
const key = `${target.pluginId}\0${target.platform}`;
|
|
192
192
|
byPlacement.set(key, [...(byPlacement.get(key) ?? []), target]);
|
|
193
|
-
if (target.state !== 'partial' && target.state !== 'error'
|
|
193
|
+
if (target.state !== 'partial' && target.state !== 'error'
|
|
194
|
+
&& !target.errors.some((error) => error.code === 'artifactCollision'))
|
|
194
195
|
continue;
|
|
195
196
|
const codes = new Set(target.errors.map((error) => error.code));
|
|
196
197
|
const dependencyCodes = [
|
|
@@ -200,41 +201,66 @@ function targetIssues(payload) {
|
|
|
200
201
|
'dependencyStillRequired',
|
|
201
202
|
'dependencyGraphInvalid',
|
|
202
203
|
];
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
204
|
+
const dependencyRootMap = new Map();
|
|
205
|
+
for (const error of target.errors) {
|
|
206
|
+
if (!dependencyCodes.includes(error.code))
|
|
207
|
+
continue;
|
|
208
|
+
if (error.rootIssueCode === 'artifactCollision') {
|
|
209
|
+
dependencyRootMap.set(error.rootIssueId ?? `artifactCollision\0${error.dependencyPluginId ?? ''}`, {
|
|
210
|
+
code: 'artifactCollision',
|
|
211
|
+
category: 'artifactCollision',
|
|
212
|
+
mergeEligible: false,
|
|
213
|
+
error,
|
|
214
|
+
dependencyPluginId: error.dependencyPluginId,
|
|
215
|
+
});
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
const code = error.code;
|
|
219
|
+
const dependencyPluginId = error.dependencyPluginId ?? dependencyPluginIdFromMessage(error.message);
|
|
220
|
+
dependencyRootMap.set(`${code}\0${dependencyPluginId ?? ''}`, {
|
|
221
|
+
code,
|
|
222
|
+
category: code,
|
|
223
|
+
mergeEligible: false,
|
|
224
|
+
error,
|
|
225
|
+
dependencyPluginId,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
const dependencyRoots = [...dependencyRootMap.values()];
|
|
229
|
+
const directCollision = target.errors.find((error) => error.code === 'artifactCollision');
|
|
230
|
+
const projectedCollisionRoots = dependencyRoots.filter((root) => root.code === 'artifactCollision');
|
|
231
|
+
const ordinaryDependencyRoots = dependencyRoots.filter((root) => root.code !== 'artifactCollision');
|
|
232
|
+
const roots = codes.has('sourceMissing')
|
|
233
|
+
? [{ code: 'sourceMissing', category: 'sourceMissing', mergeEligible: false }]
|
|
234
|
+
: directCollision || projectedCollisionRoots.length > 0
|
|
235
|
+
? [{
|
|
236
|
+
code: 'artifactCollision',
|
|
237
|
+
category: 'artifactCollision',
|
|
238
|
+
mergeEligible: false,
|
|
239
|
+
error: directCollision ?? projectedCollisionRoots[0].error,
|
|
240
|
+
dependencyPluginId: projectedCollisionRoots[0]?.dependencyPluginId,
|
|
241
|
+
}]
|
|
242
|
+
: codes.has('sourceChanged')
|
|
243
|
+
? [{ code: 'sourceChanged', category: 'sourceIdentityChanged', mergeEligible: false }]
|
|
244
|
+
: codes.has('catalogSourceUnavailable') || codes.has('bundleUnavailable')
|
|
245
|
+
? [
|
|
225
246
|
...(codes.has('catalogSourceUnavailable')
|
|
226
247
|
? [{ code: 'catalogSourceUnavailable', category: 'sourceUnavailable', mergeEligible: true }]
|
|
227
248
|
: []),
|
|
228
249
|
...(codes.has('bundleUnavailable')
|
|
229
250
|
? [{ code: 'bundleUnavailable', category: 'sourceUnavailable', mergeEligible: false }]
|
|
230
251
|
: []),
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
252
|
+
]
|
|
253
|
+
: ordinaryDependencyRoots.length > 0
|
|
254
|
+
? ordinaryDependencyRoots
|
|
255
|
+
: target.state === 'partial'
|
|
256
|
+
? [{ code: 'partial', category: 'incompleteInstallation', mergeEligible: false }]
|
|
257
|
+
: [
|
|
258
|
+
{ code: 'targetDiagnostic', category: 'diagnostic', mergeEligible: false },
|
|
259
|
+
];
|
|
235
260
|
for (const root of roots) {
|
|
236
261
|
const rootError = root.error ?? target.errors.find((error) => error.code === root.code);
|
|
237
262
|
const dependencyPluginId = root.dependencyPluginId
|
|
263
|
+
?? rootError?.dependencyPluginId
|
|
238
264
|
?? (rootError ? dependencyPluginIdFromMessage(rootError.message) : undefined);
|
|
239
265
|
const dependencyCategory = root.category.startsWith('dependency');
|
|
240
266
|
const actions = root.category === 'dependencyMissing'
|
|
@@ -259,60 +285,71 @@ function targetIssues(payload) {
|
|
|
259
285
|
{ id: 'viewDependencies', label: '查看依赖关系' },
|
|
260
286
|
{ id: 'viewTechnical', label: '技术详情' },
|
|
261
287
|
]
|
|
262
|
-
: root.category === '
|
|
288
|
+
: root.category === 'artifactCollision'
|
|
263
289
|
? [
|
|
264
|
-
{ id: '
|
|
265
|
-
{ id: '
|
|
266
|
-
{ id: 'viewTechnical', label: '技术详情' },
|
|
290
|
+
{ id: 'viewTechnical', label: '查看冲突原因' },
|
|
291
|
+
{ id: 'retryLater', label: '处理冲突后重试' },
|
|
267
292
|
]
|
|
268
|
-
: root.category === '
|
|
293
|
+
: root.category === 'incompleteInstallation'
|
|
269
294
|
? [
|
|
270
|
-
{ id: '
|
|
295
|
+
{ id: 'reinstall', label: '重新安装', description: '保留插件设置,重新生成缺失内容' },
|
|
296
|
+
{ id: 'remove', label: '移除安装', description: '保留插件设置' },
|
|
271
297
|
{ id: 'viewTechnical', label: '技术详情' },
|
|
272
298
|
]
|
|
273
|
-
: root.category === '
|
|
299
|
+
: root.category === 'sourceMissing'
|
|
274
300
|
? [
|
|
275
|
-
{ id: '
|
|
301
|
+
{ id: 'cleanup', label: '清理已安装内容', description: '只清理 matching owner 的现场内容;保留插件设置', writeAction: 'cleanup' },
|
|
302
|
+
{ id: 'reAddSource', label: '重新添加同一来源', description: '保留来源 ID;来源类型和位置由你选择' },
|
|
276
303
|
{ id: 'viewTechnical', label: '技术详情' },
|
|
277
304
|
]
|
|
278
|
-
: root.category === '
|
|
305
|
+
: root.category === 'sourceIdentityChanged'
|
|
279
306
|
? [
|
|
280
|
-
|
|
281
|
-
id: 'cleanup',
|
|
282
|
-
label: '清理已安装内容',
|
|
283
|
-
description: '只清理 AW 管理的现场内容;保留插件设置',
|
|
284
|
-
writeAction: 'cleanup',
|
|
285
|
-
}] : []),
|
|
286
|
-
{ id: 'editSource', label: '查看来源', description: root.code === 'bundleUnavailable' ? '检查当前 Catalog 或稍后重试' : '修复来源配置或稍后重试' },
|
|
307
|
+
{ id: 'viewSourceChange', label: '查看来源变更', description: '不会自动覆盖现场状态' },
|
|
287
308
|
{ id: 'viewTechnical', label: '技术详情' },
|
|
288
309
|
]
|
|
289
|
-
:
|
|
290
|
-
|
|
310
|
+
: root.category === 'sourceUnavailable'
|
|
311
|
+
? [
|
|
312
|
+
...(root.code === 'bundleUnavailable' ? [{
|
|
313
|
+
id: 'cleanup',
|
|
314
|
+
label: '清理已安装内容',
|
|
315
|
+
description: '只清理 AW 管理的现场内容;保留插件设置',
|
|
316
|
+
writeAction: 'cleanup',
|
|
317
|
+
}] : []),
|
|
318
|
+
{ id: 'editSource', label: '查看来源', description: root.code === 'bundleUnavailable' ? '检查当前 Catalog 或稍后重试' : '修复来源配置或稍后重试' },
|
|
319
|
+
{ id: 'viewTechnical', label: '技术详情' },
|
|
320
|
+
]
|
|
321
|
+
: [{ id: 'viewTechnical', label: '技术详情' }, { id: 'retryLater', label: '稍后重试' }];
|
|
322
|
+
const issueId = rootError?.rootIssueId
|
|
323
|
+
?? `target:${target.pluginId}:${target.platform}:${target.scope}:${target.state}${roots.length > 1 ? `:${root.code}` : ''}${dependencyPluginId ? `:${dependencyPluginId}` : ''}`;
|
|
291
324
|
const bundleUnavailable = root.code === 'bundleUnavailable';
|
|
292
325
|
issues.push({
|
|
293
326
|
issueId,
|
|
294
327
|
category: root.category,
|
|
295
328
|
rootCode: root.code,
|
|
296
329
|
mergeEligible: root.mergeEligible,
|
|
297
|
-
title: `${target.pluginId} · ${target.platform === 'codex' ? 'Codex' : 'Claude Code'} · ${dependencyCategory ? {
|
|
330
|
+
title: `${target.pluginId} · ${target.platform === 'codex' ? 'Codex' : 'Claude Code'} · ${root.category === 'artifactCollision' ? '输出冲突' : dependencyCategory ? {
|
|
298
331
|
dependencyMissing: '缺少依赖',
|
|
299
332
|
dependencyNotReady: '依赖安装不完整',
|
|
300
333
|
dependencyTargetUnsupported: '依赖目标不兼容',
|
|
301
334
|
dependencyStillRequired: '依赖仍被使用',
|
|
302
335
|
dependencyGraphInvalid: '依赖关系无效',
|
|
303
336
|
}[root.category] : target.state === 'partial' ? '安装不完整' : bundleUnavailable ? '当前 Catalog 不再包含此插件' : '检查失败'}`,
|
|
304
|
-
explanation:
|
|
305
|
-
?
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
337
|
+
explanation: root.category === 'artifactCollision'
|
|
338
|
+
? '目标位置已有不属于当前插件的内容。AW 不会覆盖或删除这些内容。'
|
|
339
|
+
: dependencyCategory
|
|
340
|
+
? dependencyPluginId
|
|
341
|
+
? `${dependencyPluginId} 导致当前依赖检查不能通过。`
|
|
342
|
+
: '当前依赖检查不能安全通过。'
|
|
343
|
+
: target.state === 'partial'
|
|
344
|
+
? '必要内容缺失,插件可能不能稳定运行。'
|
|
345
|
+
: bundleUnavailable
|
|
346
|
+
? '当前 Catalog 不再包含此插件,但仍发现 AW 管理的已安装内容。'
|
|
347
|
+
: '当前目标不能安全分类为正常安装。',
|
|
348
|
+
impact: [root.category === 'artifactCollision'
|
|
349
|
+
? '请先移除或迁移冲突内容,然后重试安装或重新安装。'
|
|
310
350
|
: bundleUnavailable
|
|
311
|
-
? '
|
|
312
|
-
: '
|
|
313
|
-
impact: [bundleUnavailable
|
|
314
|
-
? '可以清理可信的 AW 现场;这不表示来源缓存整体不可用。'
|
|
315
|
-
: '写操作前需要重新检查这个目标。'],
|
|
351
|
+
? '可以清理可信的 AW 现场;这不表示来源缓存整体不可用。'
|
|
352
|
+
: '写操作前需要重新检查这个目标。'],
|
|
316
353
|
entity: { kind: 'plugin', id: target.pluginId },
|
|
317
354
|
pluginId: target.pluginId,
|
|
318
355
|
...(dependencyPluginId ? { dependencyPluginId } : {}),
|
|
@@ -324,8 +361,18 @@ function targetIssues(payload) {
|
|
|
324
361
|
technicalDetails: target.errors.length > 0
|
|
325
362
|
? target.errors.filter((error) => root.code === 'targetDiagnostic'
|
|
326
363
|
|| root.code === 'partial'
|
|
327
|
-
|| error.code === root.code
|
|
328
|
-
|
|
364
|
+
|| error.code === root.code
|
|
365
|
+
|| error.rootIssueId === issueId)
|
|
366
|
+
.map((error) => ({
|
|
367
|
+
code: error.code,
|
|
368
|
+
message: error.collision
|
|
369
|
+
? ({
|
|
370
|
+
ownerMismatch: '目标由其他 owner 占用。',
|
|
371
|
+
unownedContent: '目标包含没有 AW owner 标记的内容。',
|
|
372
|
+
typeMismatch: '目标节点类型不符合预期。',
|
|
373
|
+
})[error.collision.reason]
|
|
374
|
+
: '状态检查报告了这个安全错误代码。',
|
|
375
|
+
}))
|
|
329
376
|
: [{ code: 'targetStateError', message: '目标状态异常。' }],
|
|
330
377
|
});
|
|
331
378
|
}
|
|
@@ -459,6 +506,39 @@ function configIssues(pluginSummaries) {
|
|
|
459
506
|
}];
|
|
460
507
|
});
|
|
461
508
|
}
|
|
509
|
+
function dependencyOverviewIssues(overviews, pluginSummaries, status) {
|
|
510
|
+
const summaryById = new Map(pluginSummaries.map((summary) => [summary.pluginId, summary]));
|
|
511
|
+
return overviews.flatMap((overview) => overview.blockers.flatMap((blocker) => {
|
|
512
|
+
if (blocker.code !== 'dependencyGraphInvalid'
|
|
513
|
+
&& blocker.code !== 'dependencyTargetUnsupported')
|
|
514
|
+
return [];
|
|
515
|
+
if (status.targets.some((target) => target.pluginId === overview.pluginId
|
|
516
|
+
&& target.errors.some((error) => error.code === blocker.code)))
|
|
517
|
+
return [];
|
|
518
|
+
const summary = summaryById.get(overview.pluginId);
|
|
519
|
+
const sourceId = overview.pluginId.slice(0, overview.pluginId.indexOf('/'));
|
|
520
|
+
const category = blocker.code;
|
|
521
|
+
return [{
|
|
522
|
+
issueId: `dependency:${overview.pluginId}:${blocker.code}`,
|
|
523
|
+
category,
|
|
524
|
+
rootCode: category,
|
|
525
|
+
mergeEligible: false,
|
|
526
|
+
title: `${summary?.displayName ?? summary?.pluginName ?? overview.pluginId} · ${blocker.title}`,
|
|
527
|
+
explanation: blocker.explanation,
|
|
528
|
+
impact: [category === 'dependencyGraphInvalid'
|
|
529
|
+
? '修复依赖关系后才能安全计算安装顺序。'
|
|
530
|
+
: '当前不能在所有声明的平台上安全安装这个插件。'],
|
|
531
|
+
entity: { kind: 'plugin', id: overview.pluginId },
|
|
532
|
+
pluginId: overview.pluginId,
|
|
533
|
+
sourceId,
|
|
534
|
+
actions: [
|
|
535
|
+
{ id: 'viewDependencies', label: '查看依赖关系' },
|
|
536
|
+
{ id: 'viewTechnical', label: '技术详情' },
|
|
537
|
+
],
|
|
538
|
+
technicalDetails: [{ code: blocker.code, message: blocker.explanation }],
|
|
539
|
+
}];
|
|
540
|
+
}));
|
|
541
|
+
}
|
|
462
542
|
function enrichDependencyIssuePlacements(issues, overviews) {
|
|
463
543
|
const overviewById = new Map(overviews.map((overview) => [overview.pluginId, overview]));
|
|
464
544
|
return issues.map((issue) => {
|
|
@@ -602,6 +682,86 @@ function issueDiagnostic(issue, sourceDetails) {
|
|
|
602
682
|
},
|
|
603
683
|
};
|
|
604
684
|
}
|
|
685
|
+
const issueGroupOrder = {
|
|
686
|
+
sourceRemoved: 0,
|
|
687
|
+
artifactCollision: 1,
|
|
688
|
+
sourceUnavailable: 2,
|
|
689
|
+
dependency: 3,
|
|
690
|
+
scope: 4,
|
|
691
|
+
config: 5,
|
|
692
|
+
installation: 6,
|
|
693
|
+
diagnostic: 7,
|
|
694
|
+
};
|
|
695
|
+
function issueGroup(issue) {
|
|
696
|
+
if (issue.category === 'sourceMissing')
|
|
697
|
+
return 'sourceRemoved';
|
|
698
|
+
if (issue.category === 'artifactCollision')
|
|
699
|
+
return 'artifactCollision';
|
|
700
|
+
if (issue.category === 'sourceUnavailable'
|
|
701
|
+
|| issue.category === 'sourceDegraded'
|
|
702
|
+
|| issue.category === 'sourceIdentityChanged')
|
|
703
|
+
return 'sourceUnavailable';
|
|
704
|
+
if (issue.category.startsWith('dependency'))
|
|
705
|
+
return 'dependency';
|
|
706
|
+
if (issue.category === 'scopeConflict')
|
|
707
|
+
return 'scope';
|
|
708
|
+
if (issue.category === 'requiredConfigMissing')
|
|
709
|
+
return 'config';
|
|
710
|
+
if (issue.category === 'incompleteInstallation')
|
|
711
|
+
return 'installation';
|
|
712
|
+
return 'diagnostic';
|
|
713
|
+
}
|
|
714
|
+
function primaryAttentionCode(issue) {
|
|
715
|
+
if (issue.category === 'requiredConfigMissing') {
|
|
716
|
+
return issue.requiredFields?.some((field) => field.type === 'invalid-config')
|
|
717
|
+
? 'invalidConfig'
|
|
718
|
+
: 'requiredConfigMissing';
|
|
719
|
+
}
|
|
720
|
+
if (issue.category === 'incompleteInstallation')
|
|
721
|
+
return 'incompleteInstallation';
|
|
722
|
+
if (issue.category === 'sourceDegraded')
|
|
723
|
+
return 'sourceUnavailable';
|
|
724
|
+
if (issue.category === 'sourceIdentityChanged')
|
|
725
|
+
return 'sourceUnavailable';
|
|
726
|
+
return issue.rootCode ?? issue.category;
|
|
727
|
+
}
|
|
728
|
+
function issueReasonPriority(issue) {
|
|
729
|
+
const code = primaryAttentionCode(issue);
|
|
730
|
+
return {
|
|
731
|
+
sourceMissing: 0,
|
|
732
|
+
artifactCollision: 1,
|
|
733
|
+
sourceUnavailable: 2,
|
|
734
|
+
catalogSourceUnavailable: 2,
|
|
735
|
+
bundleUnavailable: 2,
|
|
736
|
+
dependencyGraphInvalid: 3,
|
|
737
|
+
dependencyTargetUnsupported: 4,
|
|
738
|
+
dependencyNotReady: 5,
|
|
739
|
+
dependencyMissing: 5,
|
|
740
|
+
scopeConflict: 6,
|
|
741
|
+
requiredConfigMissing: 7,
|
|
742
|
+
invalidConfig: 7,
|
|
743
|
+
incompleteInstallation: 8,
|
|
744
|
+
diagnostic: 9,
|
|
745
|
+
}[code] ?? 9;
|
|
746
|
+
}
|
|
747
|
+
function collapseRootIssues(issues) {
|
|
748
|
+
const byId = new Map();
|
|
749
|
+
for (const issue of issues) {
|
|
750
|
+
const existing = byId.get(issue.issueId);
|
|
751
|
+
if (!existing) {
|
|
752
|
+
byId.set(issue.issueId, issue);
|
|
753
|
+
continue;
|
|
754
|
+
}
|
|
755
|
+
const primary = issue.dependencyPluginId ? issue : existing;
|
|
756
|
+
byId.set(issue.issueId, {
|
|
757
|
+
...primary,
|
|
758
|
+
impact: [...new Set([...existing.impact, ...issue.impact])],
|
|
759
|
+
technicalDetails: [...new Map([...existing.technicalDetails, ...issue.technicalDetails]
|
|
760
|
+
.map((detail) => [`${detail.code}\0${detail.message}`, detail])).values()],
|
|
761
|
+
});
|
|
762
|
+
}
|
|
763
|
+
return [...byId.values()];
|
|
764
|
+
}
|
|
605
765
|
export function buildTuiViewModel(options) {
|
|
606
766
|
const dependencyById = new Map((options.dependencyOverviews ?? [])
|
|
607
767
|
.map((overview) => [overview.pluginId, overview]));
|
|
@@ -624,7 +784,8 @@ export function buildTuiViewModel(options) {
|
|
|
624
784
|
const attention = placements.some((placement) => placement.state === 'scopeConflict'
|
|
625
785
|
|| (placement.state === 'installed' && placement.health !== 'ready'));
|
|
626
786
|
const installed = placements.some((placement) => placement.state !== 'notInstalled');
|
|
627
|
-
const unavailable = options.sourceHealth?.get(sourceId)?.state === 'unavailable'
|
|
787
|
+
const unavailable = options.sourceHealth?.get(sourceId)?.state === 'unavailable'
|
|
788
|
+
|| (summary?.missingCapabilities?.length ?? 0) > 0;
|
|
628
789
|
return {
|
|
629
790
|
pluginId,
|
|
630
791
|
sourceId,
|
|
@@ -642,6 +803,9 @@ export function buildTuiViewModel(options) {
|
|
|
642
803
|
installedPlacements: placements,
|
|
643
804
|
aggregateStatus: unavailable ? 'unavailable' : attention ? 'needsAttention' : installed ? 'installed' : 'available',
|
|
644
805
|
portableSkills: options.portablePluginIds?.includes(pluginId) ?? false,
|
|
806
|
+
...(summary?.missingCapabilities
|
|
807
|
+
? { missingCapabilities: summary.missingCapabilities }
|
|
808
|
+
: {}),
|
|
645
809
|
...(dependencyById.get(pluginId)
|
|
646
810
|
? { dependencySummary: dependencyById.get(pluginId).summary }
|
|
647
811
|
: summary && (summary.dependencyTotalCount ?? 0) > 0
|
|
@@ -687,24 +851,48 @@ export function buildTuiViewModel(options) {
|
|
|
687
851
|
|| !issue.sourceId || !sourceRootIds.has(issue.sourceId)),
|
|
688
852
|
...statusIssues(options.status),
|
|
689
853
|
...configIssues(options.pluginSummaries),
|
|
854
|
+
...dependencyOverviewIssues(options.dependencyOverviews ?? [], options.pluginSummaries, options.status),
|
|
690
855
|
...[...(options.sourceHealth?.values() ?? [])].flatMap((health) => sourceIssue(health, targetImpactCounts.get(health.sourceId) ?? 0) ?? []),
|
|
691
856
|
], options.dependencyOverviews ?? []);
|
|
692
|
-
const
|
|
857
|
+
const stableIssueDrafts = collapseRootIssues(issueDrafts).sort((left, right) => issueGroupOrder[issueGroup(left)] - issueGroupOrder[issueGroup(right)]
|
|
858
|
+
|| issueReasonPriority(left) - issueReasonPriority(right)
|
|
859
|
+
|| compareText(primaryAttentionCode(left), primaryAttentionCode(right))
|
|
860
|
+
|| compareText(left.issueId, right.issueId));
|
|
861
|
+
const issues = stableIssueDrafts.map((issue) => ({
|
|
693
862
|
...issue,
|
|
863
|
+
group: issueGroup(issue),
|
|
694
864
|
diagnostic: issueDiagnostic(issue, sourceDetails),
|
|
695
865
|
}));
|
|
866
|
+
const pluginsWithAttention = plugins.map((plugin) => {
|
|
867
|
+
const primary = stableIssueDrafts.filter((issue) => issue.pluginId === plugin.pluginId
|
|
868
|
+
|| issue.dependencyPluginId === plugin.pluginId
|
|
869
|
+
|| issue.entity.kind === 'source' && issue.sourceId === plugin.sourceId)
|
|
870
|
+
.sort((left, right) => issueReasonPriority(left) - issueReasonPriority(right)
|
|
871
|
+
|| compareText(primaryAttentionCode(left), primaryAttentionCode(right))
|
|
872
|
+
|| compareText(left.issueId, right.issueId))[0];
|
|
873
|
+
if (!primary)
|
|
874
|
+
return plugin;
|
|
875
|
+
return {
|
|
876
|
+
...plugin,
|
|
877
|
+
primaryAttention: {
|
|
878
|
+
severity: primary.category === 'sourceDegraded' ? 'warning' : 'error',
|
|
879
|
+
code: primaryAttentionCode(primary),
|
|
880
|
+
message: primary.explanation,
|
|
881
|
+
},
|
|
882
|
+
};
|
|
883
|
+
});
|
|
696
884
|
return {
|
|
697
|
-
plugins,
|
|
885
|
+
plugins: pluginsWithAttention,
|
|
698
886
|
sourceTabs,
|
|
699
887
|
sourceDetails: (options.sourceDetails ?? []).map((detail) => ({
|
|
700
888
|
...detail,
|
|
701
|
-
pluginCount:
|
|
889
|
+
pluginCount: pluginsWithAttention.filter((plugin) => plugin.sourceId === detail.id).length,
|
|
702
890
|
})),
|
|
703
891
|
issues,
|
|
704
892
|
dependencyOverviews: options.dependencyOverviews ?? [],
|
|
705
893
|
home: {
|
|
706
|
-
availablePlugins:
|
|
707
|
-
installedPlugins:
|
|
894
|
+
availablePlugins: pluginsWithAttention.filter((plugin) => plugin.aggregateStatus === 'available').length,
|
|
895
|
+
installedPlugins: pluginsWithAttention.filter(hasInstalledPlacement).length,
|
|
708
896
|
issueCount: issues.length,
|
|
709
897
|
sourceCount: sourceTabs.length,
|
|
710
898
|
cachedSourceCount: sourceTabs.filter((source) => source.state === 'cache').length,
|
|
@@ -737,6 +925,7 @@ export function buildConfigGroups(options) {
|
|
|
737
925
|
const entryByKey = new Map(options.read.fields.map((field) => [field.key, field]));
|
|
738
926
|
const effectiveEntryByKey = new Map((options.effectiveRead ?? options.read).fields.map((field) => [field.key, field]));
|
|
739
927
|
const effectivePage = options.read.scope === 'effective';
|
|
928
|
+
const layerEntry = (layer, key) => options.layerReads?.[layer].fields.find((field) => field.key === key);
|
|
740
929
|
const fieldModel = (key) => {
|
|
741
930
|
const schema = options.schema.schema[key];
|
|
742
931
|
const entry = entryByKey.get(key);
|
|
@@ -762,6 +951,16 @@ export function buildConfigGroups(options) {
|
|
|
762
951
|
&& effectiveEntry.effectiveValue !== undefined
|
|
763
952
|
&& effectiveEntry.effectiveValue !== null
|
|
764
953
|
&& (effectiveEntry.valueState === 'configured' || effectiveEntry.valueState === 'default');
|
|
954
|
+
const omittedLayer = options.read.scope === 'user'
|
|
955
|
+
? 'user'
|
|
956
|
+
: options.read.projectLayer === 'local' ? 'local' : 'project';
|
|
957
|
+
const fallback = ['local', 'project', 'user']
|
|
958
|
+
.filter((layer) => layer !== omittedLayer)
|
|
959
|
+
.map((layer) => ({ layer, entry: layerEntry(layer, key) }))
|
|
960
|
+
.find((candidate) => candidate.entry?.storedSourceLayer !== undefined);
|
|
961
|
+
const fallbackValue = fallback?.entry?.storedValue ?? schema.default;
|
|
962
|
+
const fallbackConfigured = fallback !== undefined || schema.default !== undefined;
|
|
963
|
+
const fallbackSource = fallback?.layer ?? (schema.default !== undefined ? 'default' : undefined);
|
|
765
964
|
return {
|
|
766
965
|
key,
|
|
767
966
|
title: schema.title ?? key,
|
|
@@ -788,6 +987,15 @@ export function buildConfigGroups(options) {
|
|
|
788
987
|
value: effectiveEntry?.effectiveValue,
|
|
789
988
|
}),
|
|
790
989
|
effectiveSourceLabel: configSourceLabel(effectiveEntry?.sourceLayer ?? null),
|
|
990
|
+
...(!effectivePage && configured ? {
|
|
991
|
+
fallbackDisplayValue: displayConfigValue({
|
|
992
|
+
privateValue,
|
|
993
|
+
inherited: false,
|
|
994
|
+
configured: fallbackConfigured,
|
|
995
|
+
value: fallbackValue,
|
|
996
|
+
}),
|
|
997
|
+
fallbackSourceLabel: fallbackSource ? configSourceLabel(fallbackSource) : '未设置',
|
|
998
|
+
} : {}),
|
|
791
999
|
...(!privateValue && selectedValue !== undefined
|
|
792
1000
|
? { value: selectedValue }
|
|
793
1001
|
: {}),
|