@lesliechan721/aw 0.1.0-beta.4 → 0.1.0-beta.6
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/lib/plugin-version-check.d.mts +14 -0
- package/dist/authoring/scripts/lib/plugin-version-check.mjs +10 -224
- package/dist/authoring/scripts/lib/plugin-version-check.mjs.map +1 -1
- package/dist/authoring/scripts/remove-plugin.d.mts +2 -0
- package/dist/authoring/scripts/remove-plugin.mjs +366 -0
- package/dist/authoring/scripts/remove-plugin.mjs.map +1 -0
- package/dist/authoring/scripts/validate-plugin.mjs +9 -46
- package/dist/authoring/scripts/validate-plugin.mjs.map +1 -1
- package/dist/scripts/bundle-plugins.d.ts +0 -2
- package/dist/scripts/bundle-plugins.js +4 -2
- package/dist/scripts/bundle-plugins.js.map +1 -1
- package/dist/scripts/plugin-staging.d.ts +1 -16
- package/dist/scripts/plugin-staging.js +8 -115
- package/dist/scripts/plugin-staging.js.map +1 -1
- package/dist/src/authoring/workspace-commands.d.ts +9 -1
- package/dist/src/authoring/workspace-commands.js +24 -16
- package/dist/src/authoring/workspace-commands.js.map +1 -1
- package/dist/src/commands/catalog-publication-inspection.d.ts +106 -0
- package/dist/src/commands/catalog-publication-inspection.js +444 -0
- package/dist/src/commands/catalog-publication-inspection.js.map +1 -0
- package/dist/src/commands/catalog-publish.d.ts +18 -2
- package/dist/src/commands/catalog-publish.js +261 -316
- package/dist/src/commands/catalog-publish.js.map +1 -1
- package/dist/src/commands/catalog-status.d.ts +60 -0
- package/dist/src/commands/catalog-status.js +251 -0
- package/dist/src/commands/catalog-status.js.map +1 -0
- package/dist/src/commands/plugin-capabilities.d.ts +22 -0
- package/dist/src/commands/plugin-capabilities.js +143 -0
- package/dist/src/commands/plugin-capabilities.js.map +1 -0
- package/dist/src/commands/rebuild-command.d.ts +2 -0
- package/dist/src/commands/rebuild-command.js +37 -6
- package/dist/src/commands/rebuild-command.js.map +1 -1
- package/dist/src/commands/rebuild-integration.d.ts +1 -0
- package/dist/src/commands/rebuild-integration.js +55 -57
- package/dist/src/commands/rebuild-integration.js.map +1 -1
- package/dist/src/commands/status-v4.d.ts +21 -0
- package/dist/src/commands/status-v4.js +63 -2
- package/dist/src/commands/status-v4.js.map +1 -1
- package/dist/src/index.js +79 -18
- package/dist/src/index.js.map +1 -1
- package/dist/src/tui/components.d.ts +70 -0
- package/dist/src/tui/components.js +149 -6
- package/dist/src/tui/components.js.map +1 -1
- package/dist/src/tui/console-app-v4.js +1660 -628
- package/dist/src/tui/console-app-v4.js.map +1 -1
- package/dist/src/tui/controller-runtime.d.ts +5 -1
- package/dist/src/tui/controller-runtime.js +184 -33
- package/dist/src/tui/controller-runtime.js.map +1 -1
- package/dist/src/tui/controller.d.ts +35 -2
- package/dist/src/tui/controller.js +300 -39
- package/dist/src/tui/controller.js.map +1 -1
- package/dist/src/tui/diagnostics.d.ts +31 -0
- package/dist/src/tui/diagnostics.js +71 -0
- package/dist/src/tui/diagnostics.js.map +1 -0
- package/dist/src/tui/index.d.ts +5 -3
- package/dist/src/tui/index.js +3 -1
- package/dist/src/tui/index.js.map +1 -1
- package/dist/src/tui/model.d.ts +33 -4
- package/dist/src/tui/model.js +252 -17
- package/dist/src/tui/model.js.map +1 -1
- package/dist/src/tui/router.d.ts +15 -9
- package/dist/src/tui/router.js +35 -0
- package/dist/src/tui/router.js.map +1 -1
- package/dist/src/tui/theme.d.ts +18 -10
- package/dist/src/tui/theme.js +18 -10
- package/dist/src/tui/theme.js.map +1 -1
- package/dist/src/tui/viewport.d.ts +20 -0
- package/dist/src/tui/viewport.js +29 -0
- package/dist/src/tui/viewport.js.map +1 -0
- package/dist/src/utils/catalog-runtime-projection.d.ts +1 -7
- package/dist/src/utils/catalog-runtime-projection.js +2 -62
- package/dist/src/utils/catalog-runtime-projection.js.map +1 -1
- package/dist/src/utils/catalog-source-cache.d.ts +12 -11
- package/dist/src/utils/catalog-source-cache.js +20 -0
- package/dist/src/utils/catalog-source-cache.js.map +1 -1
- package/dist/src/utils/dynamic-skill-tree.js +1 -1
- package/dist/src/utils/dynamic-skill-tree.js.map +1 -1
- package/dist/src/utils/git-catalog-provider.js +1 -1
- package/dist/src/utils/git-catalog-provider.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +0 -1
- package/dist/src/utils/manifest.js +0 -1
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/plugin-config.js +28 -30
- package/dist/src/utils/plugin-config.js.map +1 -1
- package/dist/src/utils/skill-validation.d.ts +1 -1
- package/dist/src/utils/skill-validation.js +1 -1
- package/dist/src/utils/skill-validation.js.map +1 -1
- package/dist/src/utils/state-paths.d.ts +1 -0
- package/dist/src/utils/state-paths.js +5 -0
- package/dist/src/utils/state-paths.js.map +1 -1
- package/package.json +3 -4
- package/dist/src/utils/plugin-authoring-capabilities.d.ts +0 -23
- package/dist/src/utils/plugin-authoring-capabilities.js +0 -37
- package/dist/src/utils/plugin-authoring-capabilities.js.map +0 -1
- package/dist/src/utils/plugin-authoring-capabilities.json +0 -92
- package/dist/src/utils/skill-frontmatter-capabilities.d.ts +0 -201
- package/dist/src/utils/skill-frontmatter-capabilities.js +0 -5
- package/dist/src/utils/skill-frontmatter-capabilities.js.map +0 -1
- package/dist/src/utils/skill-frontmatter-capabilities.json +0 -200
package/dist/src/tui/model.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { PlatformName, PluginConfigFieldType, PluginConfigPresentationPreset, PluginConfigSchema, Scope } from '../types.js';
|
|
2
|
-
import type { StatusV4Payload, StatusV4PluginSummary, StatusV4Target, StatusV4Component } from '../commands/status-v4.js';
|
|
2
|
+
import type { StatusV4Payload, StatusV4PluginSummary, StatusV4Target, StatusV4Component, StatusTargetRevision, TargetRevisionState } from '../commands/status-v4.js';
|
|
3
3
|
import type { ResolvedConfigRead } from '../utils/plugin-config.js';
|
|
4
|
+
import { type DiagnosticSummaryViewModel } from './diagnostics.js';
|
|
4
5
|
export type SourceHealthState = 'ready' | 'cache' | 'path' | 'checking' | 'degraded' | 'unavailable';
|
|
5
6
|
export interface SourceHealthViewModel {
|
|
6
7
|
sourceId: string;
|
|
@@ -17,14 +18,31 @@ export type PlatformPlacementSummary = {
|
|
|
17
18
|
state: 'installed';
|
|
18
19
|
scope: Scope;
|
|
19
20
|
health: 'ready' | 'incomplete' | 'error';
|
|
21
|
+
revision: TargetRevisionState;
|
|
20
22
|
} | {
|
|
21
23
|
platform: PlatformName;
|
|
22
24
|
state: 'scopeConflict';
|
|
23
25
|
placements: Array<{
|
|
24
26
|
scope: Scope;
|
|
25
27
|
health: 'ready' | 'incomplete' | 'error';
|
|
28
|
+
revision: TargetRevisionState;
|
|
26
29
|
}>;
|
|
27
30
|
};
|
|
31
|
+
export type PluginMenuAction = {
|
|
32
|
+
id: 'add' | 'manage' | 'repair' | 'portableSkills' | 'dependencies' | 'settings' | 'source' | 'sourceProblem' | 'about' | 'refreshSource' | 'technical' | 'back';
|
|
33
|
+
} | {
|
|
34
|
+
id: 'platform' | 'scopeConflict';
|
|
35
|
+
platform: PlatformName;
|
|
36
|
+
} | {
|
|
37
|
+
id: 'upgrade';
|
|
38
|
+
platform: PlatformName;
|
|
39
|
+
scope: Scope;
|
|
40
|
+
availableVersion: string;
|
|
41
|
+
} | {
|
|
42
|
+
id: 'reinstall' | 'remove';
|
|
43
|
+
platform: PlatformName;
|
|
44
|
+
scope: Scope;
|
|
45
|
+
};
|
|
28
46
|
export interface PluginListItemViewModel {
|
|
29
47
|
pluginId: string;
|
|
30
48
|
sourceId: string;
|
|
@@ -114,6 +132,7 @@ export interface SourceDetailViewModel {
|
|
|
114
132
|
catalogVersion?: string;
|
|
115
133
|
channel?: string;
|
|
116
134
|
freshness?: 'remote' | 'cache' | 'path';
|
|
135
|
+
errorCode?: string;
|
|
117
136
|
configDigest: string;
|
|
118
137
|
}
|
|
119
138
|
export interface HomeSummaryViewModel {
|
|
@@ -136,7 +155,10 @@ export interface ConfigFieldViewModel {
|
|
|
136
155
|
inherited: boolean;
|
|
137
156
|
configured: boolean;
|
|
138
157
|
sourceLabel: string;
|
|
158
|
+
effectiveDisplayValue: string;
|
|
159
|
+
effectiveSourceLabel: string;
|
|
139
160
|
value?: string | number | boolean;
|
|
161
|
+
effectiveValue?: string | number | boolean;
|
|
140
162
|
defaultValue?: string | number | boolean;
|
|
141
163
|
enumValues?: string[];
|
|
142
164
|
valueLabels?: Record<string, string>;
|
|
@@ -169,7 +191,7 @@ export interface ConfigPageViewModel {
|
|
|
169
191
|
storedCount: number;
|
|
170
192
|
}
|
|
171
193
|
export type UserIssueCategory = 'incompleteInstallation' | 'sourceDegraded' | 'sourceUnavailable' | 'sourceMissing' | 'sourceIdentityChanged' | 'requiredConfigMissing' | 'scopeConflict' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'legacyState' | 'diagnostic';
|
|
172
|
-
export type UserIssueActionId = 'reinstall' | 'remove' | 'refreshSource' | 'continueWithCache' | 'editSource' | 'retryLater' | 'reAddSource' | 'viewSourceChange' | 'openConfig' | 'keepUserScope' | 'keepProjectScope' | 'viewTechnical' | 'manualMigration' | 'installDependency' | 'reinstallDependency' | 'viewDependencyIssue' | 'viewDependencies';
|
|
194
|
+
export type UserIssueActionId = 'reinstall' | 'cleanup' | 'remove' | 'refreshSource' | 'continueWithCache' | 'editSource' | 'retryLater' | 'reAddSource' | 'viewSourceChange' | 'openConfig' | 'keepUserScope' | 'keepProjectScope' | 'viewTechnical' | 'manualMigration' | 'installDependency' | 'reinstallDependency' | 'viewDependencyIssue' | 'viewDependencies';
|
|
173
195
|
export interface UserIssueActionViewModel {
|
|
174
196
|
id: UserIssueActionId;
|
|
175
197
|
label: string;
|
|
@@ -178,7 +200,7 @@ export interface UserIssueActionViewModel {
|
|
|
178
200
|
platform?: PlatformName;
|
|
179
201
|
scope?: Scope;
|
|
180
202
|
project?: 'current' | 'other' | null;
|
|
181
|
-
writeAction?: 'install' | 'upgrade' | 'reinstall';
|
|
203
|
+
writeAction?: 'install' | 'upgrade' | 'reinstall' | 'cleanup';
|
|
182
204
|
}
|
|
183
205
|
export type TargetIssueRootCode = 'partial' | 'sourceMissing' | 'sourceChanged' | 'catalogSourceUnavailable' | 'bundleUnavailable' | 'dependencyMissing' | 'dependencyNotReady' | 'dependencyTargetUnsupported' | 'dependencyStillRequired' | 'dependencyGraphInvalid' | 'targetDiagnostic';
|
|
184
206
|
export interface UserIssueViewModel {
|
|
@@ -218,6 +240,7 @@ export interface UserIssueViewModel {
|
|
|
218
240
|
code: string;
|
|
219
241
|
message: string;
|
|
220
242
|
}>;
|
|
243
|
+
diagnostic: DiagnosticSummaryViewModel;
|
|
221
244
|
}
|
|
222
245
|
export interface TuiViewModel {
|
|
223
246
|
plugins: PluginListItemViewModel[];
|
|
@@ -257,11 +280,15 @@ export interface PortableSkillSelectionViewModel {
|
|
|
257
280
|
};
|
|
258
281
|
canContinue: boolean;
|
|
259
282
|
}
|
|
260
|
-
export declare function projectPlatformPlacement(platform: PlatformName, targets: StatusV4Target[]): PlatformPlacementSummary;
|
|
283
|
+
export declare function projectPlatformPlacement(platform: PlatformName, targets: StatusV4Target[], revisions?: StatusTargetRevision[]): PlatformPlacementSummary;
|
|
284
|
+
export declare function buildPluginPreviewActions(plugin: PluginListItemViewModel): PluginMenuAction[];
|
|
285
|
+
export declare function buildPluginDetailActions(plugin: PluginListItemViewModel): PluginMenuAction[];
|
|
286
|
+
export declare function buildPlatformActions(plugin: PluginListItemViewModel, platform: PlatformName): PluginMenuAction[];
|
|
261
287
|
export declare function hasInstalledPlacement(plugin: PluginListItemViewModel): boolean;
|
|
262
288
|
export declare function buildTuiViewModel(options: {
|
|
263
289
|
status: StatusV4Payload;
|
|
264
290
|
pluginSummaries: StatusV4PluginSummary[];
|
|
291
|
+
targetRevisions?: StatusTargetRevision[];
|
|
265
292
|
sourceHealth?: ReadonlyMap<string, SourceHealthViewModel>;
|
|
266
293
|
sourceDetails?: SourceDetailViewModel[];
|
|
267
294
|
dependencyOverviews?: PluginDependencyOverviewViewModel[];
|
|
@@ -270,10 +297,12 @@ export declare function buildTuiViewModel(options: {
|
|
|
270
297
|
export declare function buildConfigGroups(options: {
|
|
271
298
|
schema: PluginConfigSchema;
|
|
272
299
|
read: ResolvedConfigRead;
|
|
300
|
+
effectiveRead?: ResolvedConfigRead;
|
|
273
301
|
dirtyKeys?: ReadonlySet<string>;
|
|
274
302
|
}): ConfigGroupViewModel[];
|
|
275
303
|
export declare function buildConfigPage(options: {
|
|
276
304
|
pluginId: string;
|
|
277
305
|
schema: PluginConfigSchema;
|
|
278
306
|
read: ResolvedConfigRead;
|
|
307
|
+
effectiveRead?: ResolvedConfigRead;
|
|
279
308
|
}): ConfigPageViewModel;
|
package/dist/src/tui/model.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { safeDiagnosticCode, } from './diagnostics.js';
|
|
1
2
|
function compareText(left, right) {
|
|
2
3
|
return left.localeCompare(right, 'en');
|
|
3
4
|
}
|
|
@@ -14,18 +15,34 @@ function isInstalledScopeEvidence(target) {
|
|
|
14
15
|
function dependencyPluginIdFromMessage(message) {
|
|
15
16
|
return message.match(/(?:[a-z0-9]+(?:-[a-z0-9]+)*)\/(?:[a-z0-9]+(?:-[a-z0-9]+)*)/u)?.[0];
|
|
16
17
|
}
|
|
17
|
-
export function projectPlatformPlacement(platform, targets) {
|
|
18
|
+
export function projectPlatformPlacement(platform, targets, revisions = []) {
|
|
19
|
+
const revisionFor = (target) => revisions.find((entry) => entry.pluginId === target.pluginId
|
|
20
|
+
&& entry.platform === target.platform
|
|
21
|
+
&& entry.scope === target.scope)?.revision
|
|
22
|
+
?? { state: 'unknown', ...(target.version ? { availableVersion: target.version } : {}) };
|
|
18
23
|
const supportedScopes = [...new Set(targets.map((target) => target.scope))];
|
|
19
24
|
const installed = targets.filter(isInstalledScopeEvidence);
|
|
20
25
|
if (installed.length === 0) {
|
|
21
26
|
const errorTarget = targets.find((target) => target.state === 'error');
|
|
22
27
|
if (!errorTarget)
|
|
23
28
|
return { platform, state: 'notInstalled', supportedScopes };
|
|
24
|
-
return {
|
|
29
|
+
return {
|
|
30
|
+
platform,
|
|
31
|
+
state: 'installed',
|
|
32
|
+
scope: errorTarget.scope,
|
|
33
|
+
health: 'error',
|
|
34
|
+
revision: revisionFor(errorTarget),
|
|
35
|
+
};
|
|
25
36
|
}
|
|
26
37
|
if (installed.length === 1) {
|
|
27
38
|
const target = installed[0];
|
|
28
|
-
return {
|
|
39
|
+
return {
|
|
40
|
+
platform,
|
|
41
|
+
state: 'installed',
|
|
42
|
+
scope: target.scope,
|
|
43
|
+
health: targetHealth(target),
|
|
44
|
+
revision: revisionFor(target),
|
|
45
|
+
};
|
|
29
46
|
}
|
|
30
47
|
return {
|
|
31
48
|
platform,
|
|
@@ -33,9 +50,89 @@ export function projectPlatformPlacement(platform, targets) {
|
|
|
33
50
|
placements: installed.map((target) => ({
|
|
34
51
|
scope: target.scope,
|
|
35
52
|
health: targetHealth(target),
|
|
53
|
+
revision: revisionFor(target),
|
|
36
54
|
})).sort((left, right) => compareText(left.scope, right.scope)),
|
|
37
55
|
};
|
|
38
56
|
}
|
|
57
|
+
function hasIncompletePlacement(plugin) {
|
|
58
|
+
return plugin.installedPlacements.some((placement) => placement.state === 'scopeConflict'
|
|
59
|
+
|| placement.state === 'installed' && placement.health !== 'ready');
|
|
60
|
+
}
|
|
61
|
+
function hasMissingPlatform(plugin) {
|
|
62
|
+
return plugin.supportedPlatforms.some((platform) => plugin.installedPlacements.find((placement) => placement.platform === platform)?.state === 'notInstalled');
|
|
63
|
+
}
|
|
64
|
+
function capabilityActions(plugin) {
|
|
65
|
+
return [
|
|
66
|
+
...(plugin.portableSkills ? [{ id: 'portableSkills' }] : []),
|
|
67
|
+
...((plugin.dependencySummary?.totalCount ?? 0) > 0 ? [{ id: 'dependencies' }] : []),
|
|
68
|
+
...(plugin.configFieldCount > 0 ? [{ id: 'settings' }] : []),
|
|
69
|
+
];
|
|
70
|
+
}
|
|
71
|
+
export function buildPluginPreviewActions(plugin) {
|
|
72
|
+
const installed = hasInstalledPlacement(plugin);
|
|
73
|
+
if (plugin.aggregateStatus === 'unavailable') {
|
|
74
|
+
return [{ id: 'sourceProblem' }, ...(installed ? [{ id: 'manage' }] : [])];
|
|
75
|
+
}
|
|
76
|
+
const primary = hasIncompletePlacement(plugin)
|
|
77
|
+
|| (plugin.dependencySummary?.issueCount ?? 0) > 0
|
|
78
|
+
? { id: 'repair' }
|
|
79
|
+
: installed && !hasMissingPlatform(plugin)
|
|
80
|
+
? { id: 'manage' }
|
|
81
|
+
: { id: 'add' };
|
|
82
|
+
return [primary, ...capabilityActions(plugin), { id: 'source' }];
|
|
83
|
+
}
|
|
84
|
+
export function buildPluginDetailActions(plugin) {
|
|
85
|
+
if (plugin.aggregateStatus === 'unavailable') {
|
|
86
|
+
return [
|
|
87
|
+
...plugin.installedPlacements.flatMap((placement) => placement.state === 'notInstalled'
|
|
88
|
+
? []
|
|
89
|
+
: [{ id: 'platform', platform: placement.platform }]),
|
|
90
|
+
{ id: 'sourceProblem' },
|
|
91
|
+
{ id: 'about' },
|
|
92
|
+
];
|
|
93
|
+
}
|
|
94
|
+
return [
|
|
95
|
+
...plugin.installedPlacements.map((placement) => placement.state === 'scopeConflict'
|
|
96
|
+
? { id: 'scopeConflict', platform: placement.platform }
|
|
97
|
+
: { id: 'platform', platform: placement.platform }),
|
|
98
|
+
...((plugin.dependencySummary?.totalCount ?? 0) > 0 ? [{ id: 'dependencies' }] : []),
|
|
99
|
+
...(plugin.portableSkills ? [{ id: 'portableSkills' }] : []),
|
|
100
|
+
...(plugin.configFieldCount > 0 ? [{ id: 'settings' }] : []),
|
|
101
|
+
{ id: 'about' },
|
|
102
|
+
];
|
|
103
|
+
}
|
|
104
|
+
export function buildPlatformActions(plugin, platform) {
|
|
105
|
+
if (plugin.aggregateStatus === 'unavailable') {
|
|
106
|
+
return [{ id: 'sourceProblem' }, { id: 'refreshSource' }];
|
|
107
|
+
}
|
|
108
|
+
const placement = plugin.installedPlacements.find((entry) => entry.platform === platform);
|
|
109
|
+
if (!placement || placement.state === 'notInstalled')
|
|
110
|
+
return [{ id: 'add' }, { id: 'about' }];
|
|
111
|
+
if (placement.state === 'scopeConflict')
|
|
112
|
+
return [{ id: 'scopeConflict', platform }];
|
|
113
|
+
if (placement.health === 'error')
|
|
114
|
+
return [{ id: 'technical' }, { id: 'back' }];
|
|
115
|
+
if (placement.health === 'incomplete') {
|
|
116
|
+
return [
|
|
117
|
+
{ id: 'reinstall', platform, scope: placement.scope },
|
|
118
|
+
{ id: 'technical' },
|
|
119
|
+
{ id: 'remove', platform, scope: placement.scope },
|
|
120
|
+
];
|
|
121
|
+
}
|
|
122
|
+
return [
|
|
123
|
+
...(placement.revision.state === 'upgradeAvailable'
|
|
124
|
+
? [{
|
|
125
|
+
id: 'upgrade',
|
|
126
|
+
platform,
|
|
127
|
+
scope: placement.scope,
|
|
128
|
+
availableVersion: placement.revision.availableVersion,
|
|
129
|
+
}]
|
|
130
|
+
: []),
|
|
131
|
+
{ id: 'reinstall', platform, scope: placement.scope },
|
|
132
|
+
{ id: 'remove', platform, scope: placement.scope },
|
|
133
|
+
{ id: 'technical' },
|
|
134
|
+
];
|
|
135
|
+
}
|
|
39
136
|
export function hasInstalledPlacement(plugin) {
|
|
40
137
|
return plugin.installedPlacements.some((placement) => placement.state !== 'notInstalled');
|
|
41
138
|
}
|
|
@@ -55,9 +152,9 @@ function sourceState(source, health) {
|
|
|
55
152
|
return source.freshness === 'cache' ? 'cache' : 'ready';
|
|
56
153
|
}
|
|
57
154
|
function sourceIssue(health, impactedTargets = 0) {
|
|
58
|
-
if (health.state !== '
|
|
155
|
+
if (health.state !== 'degraded' && health.state !== 'unavailable')
|
|
59
156
|
return undefined;
|
|
60
|
-
const cached = health.state === '
|
|
157
|
+
const cached = health.state === 'degraded';
|
|
61
158
|
const issueId = health.issueId ?? `source:${health.sourceId}:${cached ? 'cache' : 'unavailable'}`;
|
|
62
159
|
return {
|
|
63
160
|
issueId,
|
|
@@ -65,7 +162,7 @@ function sourceIssue(health, impactedTargets = 0) {
|
|
|
65
162
|
title: `${health.sourceId} · ${cached ? '来源使用缓存' : '来源不可用'}`,
|
|
66
163
|
explanation: cached
|
|
67
164
|
? '远端检查失败。当前仍使用已验证的缓存数据。'
|
|
68
|
-
: '
|
|
165
|
+
: '来源检查失败,并且没有可用缓存数据。',
|
|
69
166
|
impact: [cached ? '插件仍可浏览,但数据可能不是最新。' : '当前不能浏览或安装这个来源的插件。',
|
|
70
167
|
...(impactedTargets > 0 ? [`${impactedTargets} 个安装位置受此来源根问题影响。`] : [])],
|
|
71
168
|
entity: { kind: 'source', id: health.sourceId },
|
|
@@ -180,7 +277,13 @@ function targetIssues(payload) {
|
|
|
180
277
|
]
|
|
181
278
|
: root.category === 'sourceUnavailable'
|
|
182
279
|
? [
|
|
183
|
-
|
|
280
|
+
...(root.code === 'bundleUnavailable' ? [{
|
|
281
|
+
id: 'cleanup',
|
|
282
|
+
label: '清理已安装内容',
|
|
283
|
+
description: '只清理 AW 管理的现场内容;保留插件设置',
|
|
284
|
+
writeAction: 'cleanup',
|
|
285
|
+
}] : []),
|
|
286
|
+
{ id: 'editSource', label: '查看来源', description: root.code === 'bundleUnavailable' ? '检查当前 Catalog 或稍后重试' : '修复来源配置或稍后重试' },
|
|
184
287
|
{ id: 'viewTechnical', label: '技术详情' },
|
|
185
288
|
]
|
|
186
289
|
: [{ id: 'viewTechnical', label: '技术详情' }, { id: 'retryLater', label: '稍后重试' }];
|
|
@@ -197,7 +300,7 @@ function targetIssues(payload) {
|
|
|
197
300
|
dependencyTargetUnsupported: '依赖目标不兼容',
|
|
198
301
|
dependencyStillRequired: '依赖仍被使用',
|
|
199
302
|
dependencyGraphInvalid: '依赖关系无效',
|
|
200
|
-
}[root.category] : target.state === 'partial' ? '安装不完整' : bundleUnavailable ? '
|
|
303
|
+
}[root.category] : target.state === 'partial' ? '安装不完整' : bundleUnavailable ? '当前 Catalog 不再包含此插件' : '检查失败'}`,
|
|
201
304
|
explanation: dependencyCategory
|
|
202
305
|
? dependencyPluginId
|
|
203
306
|
? `${dependencyPluginId} 导致当前依赖检查不能通过。`
|
|
@@ -205,10 +308,10 @@ function targetIssues(payload) {
|
|
|
205
308
|
: target.state === 'partial'
|
|
206
309
|
? '必要内容缺失,插件可能不能稳定运行。'
|
|
207
310
|
: bundleUnavailable
|
|
208
|
-
? '
|
|
311
|
+
? '当前 Catalog 不再包含此插件,但仍发现 AW 管理的已安装内容。'
|
|
209
312
|
: '当前目标不能安全分类为正常安装。',
|
|
210
313
|
impact: [bundleUnavailable
|
|
211
|
-
? '
|
|
314
|
+
? '可以清理可信的 AW 现场;这不表示来源缓存整体不可用。'
|
|
212
315
|
: '写操作前需要重新检查这个目标。'],
|
|
213
316
|
entity: { kind: 'plugin', id: target.pluginId },
|
|
214
317
|
pluginId: target.pluginId,
|
|
@@ -313,7 +416,10 @@ function configIssues(pluginSummaries) {
|
|
|
313
416
|
{ id: 'retryLater', label: '稍后重新检查' },
|
|
314
417
|
{ id: 'viewTechnical', label: '查看技术详情' },
|
|
315
418
|
],
|
|
316
|
-
technicalDetails: [{
|
|
419
|
+
technicalDetails: [{
|
|
420
|
+
code: summary.configDiagnostic.code,
|
|
421
|
+
message: '设置读取报告了这个安全错误代码。',
|
|
422
|
+
}],
|
|
317
423
|
}];
|
|
318
424
|
}
|
|
319
425
|
if (!summary.configIssues?.length)
|
|
@@ -398,6 +504,104 @@ function enrichDependencyIssuePlacements(issues, overviews) {
|
|
|
398
504
|
};
|
|
399
505
|
});
|
|
400
506
|
}
|
|
507
|
+
function issueDiagnostic(issue, sourceDetails) {
|
|
508
|
+
const source = issue.sourceId ? sourceDetails.get(issue.sourceId) : undefined;
|
|
509
|
+
const sourceDegraded = issue.category === 'sourceDegraded';
|
|
510
|
+
const sourceUnavailable = issue.category === 'sourceUnavailable' && issue.entity.kind === 'source';
|
|
511
|
+
const configUnavailable = issue.category === 'diagnostic' && issue.issueId.startsWith('config:');
|
|
512
|
+
const configInvalid = issue.category === 'requiredConfigMissing';
|
|
513
|
+
const dependency = issue.category.startsWith('dependency');
|
|
514
|
+
const platformState = issue.issueId.startsWith('status:') || issue.rootCode === 'targetDiagnostic';
|
|
515
|
+
const preserved = sourceDegraded || sourceUnavailable
|
|
516
|
+
? '已安装插件和已保存设置不会被删除。'
|
|
517
|
+
: configUnavailable
|
|
518
|
+
? '已保存的设置保持不变。'
|
|
519
|
+
: '现有安装和已保存设置不会因本页自动改变。';
|
|
520
|
+
const impact = sourceDegraded
|
|
521
|
+
? [
|
|
522
|
+
{ state: 'degraded', message: '远端数据可能不是最新;匹配的已验证缓存仍可浏览和安装。' },
|
|
523
|
+
{ state: 'preserved', message: preserved },
|
|
524
|
+
]
|
|
525
|
+
: sourceUnavailable
|
|
526
|
+
? [
|
|
527
|
+
{ state: 'blocked', message: '没有可用缓存;当前不能浏览或安装这个来源中的插件。' },
|
|
528
|
+
{ state: 'preserved', message: preserved },
|
|
529
|
+
]
|
|
530
|
+
: [
|
|
531
|
+
...issue.impact.map((message) => ({
|
|
532
|
+
state: dependency || configUnavailable || configInvalid || platformState ? 'blocked' : 'degraded',
|
|
533
|
+
message,
|
|
534
|
+
})),
|
|
535
|
+
{ state: 'preserved', message: preserved },
|
|
536
|
+
];
|
|
537
|
+
const primaryAction = issue.actions.find((action) => action.id !== 'viewTechnical');
|
|
538
|
+
const nextStep = primaryAction
|
|
539
|
+
? `${primaryAction.label},然后重新检查当前状态。`
|
|
540
|
+
: '打开技术详情,记录安全错误代码后重新检查。';
|
|
541
|
+
const sourceDiagnostic = sourceDegraded || sourceUnavailable;
|
|
542
|
+
const rawCode = sourceDiagnostic
|
|
543
|
+
? source?.errorCode ?? issue.technicalDetails[0]?.code
|
|
544
|
+
: issue.technicalDetails[0]?.code;
|
|
545
|
+
const code = safeDiagnosticCode(rawCode, sourceDegraded
|
|
546
|
+
? 'catalogSourceDegraded'
|
|
547
|
+
: sourceUnavailable ? 'catalogSourceUnavailable' : 'diagnosticUnavailable');
|
|
548
|
+
const stage = sourceDegraded || sourceUnavailable ? 'resolve-source'
|
|
549
|
+
: configUnavailable ? 'read-config'
|
|
550
|
+
: configInvalid ? 'validate-config'
|
|
551
|
+
: dependency ? 'resolve-dependencies'
|
|
552
|
+
: platformState ? 'read-platform-state' : 'inspect-target';
|
|
553
|
+
const context = [
|
|
554
|
+
...(issue.pluginId ? [{ key: 'pluginId', value: issue.pluginId }] : []),
|
|
555
|
+
...(issue.dependencyPluginId
|
|
556
|
+
? [{ key: 'dependencyPluginId', value: issue.dependencyPluginId }]
|
|
557
|
+
: []),
|
|
558
|
+
...(issue.platform ? [{ key: 'platform', value: issue.platform }] : []),
|
|
559
|
+
...(issue.scope ? [{ key: 'scope', value: issue.scope }] : []),
|
|
560
|
+
...(sourceDiagnostic && source?.freshness
|
|
561
|
+
? [{ key: 'freshness', value: source.freshness }]
|
|
562
|
+
: []),
|
|
563
|
+
...(issue.requiredFields?.slice(0, 1).map((field) => ({
|
|
564
|
+
key: 'field',
|
|
565
|
+
value: field.title,
|
|
566
|
+
})) ?? []),
|
|
567
|
+
];
|
|
568
|
+
const checks = issue.category === 'legacyState'
|
|
569
|
+
? [
|
|
570
|
+
'不自动迁移旧版状态。',
|
|
571
|
+
'运行 aw status --json,记录公开错误 code。',
|
|
572
|
+
'备份相关 AW 配置。',
|
|
573
|
+
'按技术详情使用受支持命令或人工处理。',
|
|
574
|
+
'再次运行状态检查。',
|
|
575
|
+
]
|
|
576
|
+
: sourceDegraded || sourceUnavailable
|
|
577
|
+
? ['检查 Git URL、ref 或本地目录。', '确认当前终端具备来源授权。', '运行“重新检查来源”验证修复。']
|
|
578
|
+
: dependency
|
|
579
|
+
? ['检查依赖关系和依赖插件状态。', '完成恢复动作后重新检查根插件。']
|
|
580
|
+
: configUnavailable
|
|
581
|
+
? ['恢复插件来源和可信字段定义。', '重新检查来源后再次打开设置。']
|
|
582
|
+
: configInvalid
|
|
583
|
+
? ['完成或修正列出的设置字段。', '重新检查插件设置。']
|
|
584
|
+
: ['检查目标平台配置和访问权限。', '完成恢复动作后重新运行状态检查。'];
|
|
585
|
+
return {
|
|
586
|
+
severity: sourceDegraded ? 'warning' : 'error',
|
|
587
|
+
title: issue.title,
|
|
588
|
+
userMessage: issue.explanation,
|
|
589
|
+
impact,
|
|
590
|
+
nextStep,
|
|
591
|
+
technical: {
|
|
592
|
+
code,
|
|
593
|
+
stage,
|
|
594
|
+
...(sourceDiagnostic && issue.sourceId ? { sourceId: issue.sourceId } : {}),
|
|
595
|
+
...(sourceDiagnostic && source?.requestedRef ? { requestedRef: source.requestedRef } : {}),
|
|
596
|
+
...(sourceDiagnostic && source?.resolvedCommit ? { resolvedCommit: source.resolvedCommit } : {}),
|
|
597
|
+
...(sourceDegraded || sourceUnavailable
|
|
598
|
+
? { lastGood: sourceDegraded ? 'available' : 'unavailable' }
|
|
599
|
+
: {}),
|
|
600
|
+
...(context.length > 0 ? { context } : {}),
|
|
601
|
+
checks,
|
|
602
|
+
},
|
|
603
|
+
};
|
|
604
|
+
}
|
|
401
605
|
export function buildTuiViewModel(options) {
|
|
402
606
|
const dependencyById = new Map((options.dependencyOverviews ?? [])
|
|
403
607
|
.map((overview) => [overview.pluginId, overview]));
|
|
@@ -413,7 +617,9 @@ export function buildTuiViewModel(options) {
|
|
|
413
617
|
const sourceId = targets[0]?.sourceId ?? pluginId.slice(0, pluginId.indexOf('/'));
|
|
414
618
|
const placements = ['codex', 'claude'].flatMap((platform) => {
|
|
415
619
|
const platformTargets = targets.filter((target) => target.platform === platform);
|
|
416
|
-
return platformTargets.length > 0
|
|
620
|
+
return platformTargets.length > 0
|
|
621
|
+
? [projectPlatformPlacement(platform, platformTargets, options.targetRevisions)]
|
|
622
|
+
: [];
|
|
417
623
|
});
|
|
418
624
|
const attention = placements.some((placement) => placement.state === 'scopeConflict'
|
|
419
625
|
|| (placement.state === 'installed' && placement.health !== 'ready'));
|
|
@@ -466,7 +672,7 @@ export function buildTuiViewModel(options) {
|
|
|
466
672
|
state: sourceState(source, options.sourceHealth?.get(source.id)),
|
|
467
673
|
}));
|
|
468
674
|
const sourceRootIds = new Set([...(options.sourceHealth?.values() ?? [])]
|
|
469
|
-
.filter((health) => health.state === '
|
|
675
|
+
.filter((health) => health.state === 'degraded' || health.state === 'unavailable')
|
|
470
676
|
.map((health) => health.sourceId));
|
|
471
677
|
const allTargetIssues = targetIssues(options.status);
|
|
472
678
|
const targetImpactCounts = new Map();
|
|
@@ -475,13 +681,18 @@ export function buildTuiViewModel(options) {
|
|
|
475
681
|
continue;
|
|
476
682
|
targetImpactCounts.set(issue.sourceId, (targetImpactCounts.get(issue.sourceId) ?? 0) + 1);
|
|
477
683
|
}
|
|
478
|
-
const
|
|
684
|
+
const sourceDetails = new Map((options.sourceDetails ?? []).map((detail) => [detail.id, detail]));
|
|
685
|
+
const issueDrafts = enrichDependencyIssuePlacements([
|
|
479
686
|
...allTargetIssues.filter((issue) => !issue.mergeEligible
|
|
480
687
|
|| !issue.sourceId || !sourceRootIds.has(issue.sourceId)),
|
|
481
688
|
...statusIssues(options.status),
|
|
482
689
|
...configIssues(options.pluginSummaries),
|
|
483
690
|
...[...(options.sourceHealth?.values() ?? [])].flatMap((health) => sourceIssue(health, targetImpactCounts.get(health.sourceId) ?? 0) ?? []),
|
|
484
691
|
], options.dependencyOverviews ?? []);
|
|
692
|
+
const issues = issueDrafts.map((issue) => ({
|
|
693
|
+
...issue,
|
|
694
|
+
diagnostic: issueDiagnostic(issue, sourceDetails),
|
|
695
|
+
}));
|
|
485
696
|
return {
|
|
486
697
|
plugins,
|
|
487
698
|
sourceTabs,
|
|
@@ -524,25 +735,39 @@ function configSourceLabel(source) {
|
|
|
524
735
|
}
|
|
525
736
|
export function buildConfigGroups(options) {
|
|
526
737
|
const entryByKey = new Map(options.read.fields.map((field) => [field.key, field]));
|
|
738
|
+
const effectiveEntryByKey = new Map((options.effectiveRead ?? options.read).fields.map((field) => [field.key, field]));
|
|
527
739
|
const effectivePage = options.read.scope === 'effective';
|
|
528
740
|
const fieldModel = (key) => {
|
|
529
741
|
const schema = options.schema.schema[key];
|
|
530
742
|
const entry = entryByKey.get(key);
|
|
743
|
+
const effectiveEntry = effectiveEntryByKey.get(key);
|
|
531
744
|
const presentation = options.schema.presentation?.fields?.[key];
|
|
532
745
|
const inherited = effectivePage
|
|
533
|
-
?
|
|
746
|
+
? false
|
|
534
747
|
: entry?.storedSourceLayer === undefined;
|
|
535
748
|
const configured = effectivePage
|
|
536
|
-
? entry?.
|
|
749
|
+
? entry?.sourceLayer !== undefined
|
|
750
|
+
&& entry.sourceLayer !== null
|
|
751
|
+
&& entry.effectiveValue !== undefined
|
|
752
|
+
&& entry.effectiveValue !== null
|
|
753
|
+
&& (entry.valueState === 'configured' || entry.valueState === 'default')
|
|
537
754
|
: entry?.storedSourceLayer !== undefined;
|
|
538
755
|
const privateValue = schema.sensitive === true || schema.type === 'file' || schema.type === 'directory';
|
|
539
756
|
const selectedValue = effectivePage ? entry?.effectiveValue : entry?.storedValue;
|
|
757
|
+
const selectedStoredInvalid = !effectivePage
|
|
758
|
+
&& entry?.storedSourceLayer !== undefined
|
|
759
|
+
&& entry.storedValue === undefined;
|
|
760
|
+
const effectiveConfigured = effectiveEntry?.sourceLayer !== undefined
|
|
761
|
+
&& effectiveEntry.sourceLayer !== null
|
|
762
|
+
&& effectiveEntry.effectiveValue !== undefined
|
|
763
|
+
&& effectiveEntry.effectiveValue !== null
|
|
764
|
+
&& (effectiveEntry.valueState === 'configured' || effectiveEntry.valueState === 'default');
|
|
540
765
|
return {
|
|
541
766
|
key,
|
|
542
767
|
title: schema.title ?? key,
|
|
543
768
|
...(schema.description ? { description: schema.description } : {}),
|
|
544
769
|
type: schema.type,
|
|
545
|
-
displayValue: displayConfigValue({
|
|
770
|
+
displayValue: selectedStoredInvalid ? '值无效' : displayConfigValue({
|
|
546
771
|
privateValue,
|
|
547
772
|
inherited,
|
|
548
773
|
configured,
|
|
@@ -556,9 +781,19 @@ export function buildConfigGroups(options) {
|
|
|
556
781
|
sourceLabel: effectivePage
|
|
557
782
|
? configSourceLabel(entry?.sourceLayer ?? null)
|
|
558
783
|
: configured ? '本层已设置' : '继承',
|
|
784
|
+
effectiveDisplayValue: displayConfigValue({
|
|
785
|
+
privateValue,
|
|
786
|
+
inherited: false,
|
|
787
|
+
configured: effectiveConfigured,
|
|
788
|
+
value: effectiveEntry?.effectiveValue,
|
|
789
|
+
}),
|
|
790
|
+
effectiveSourceLabel: configSourceLabel(effectiveEntry?.sourceLayer ?? null),
|
|
559
791
|
...(!privateValue && selectedValue !== undefined
|
|
560
792
|
? { value: selectedValue }
|
|
561
793
|
: {}),
|
|
794
|
+
...(!privateValue && effectiveEntry?.effectiveValue !== undefined && effectiveEntry.effectiveValue !== null
|
|
795
|
+
? { effectiveValue: effectiveEntry.effectiveValue }
|
|
796
|
+
: {}),
|
|
562
797
|
...(!privateValue && schema.default !== undefined ? { defaultValue: schema.default } : {}),
|
|
563
798
|
...(schema.values ? { enumValues: [...schema.values] } : {}),
|
|
564
799
|
...(presentation?.valueLabels ? { valueLabels: { ...presentation.valueLabels } } : {}),
|