@lmzhen/dsh-evolution-skill-health 0.34.0 → 0.36.0
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/lib/client.js +112 -20
- package/lib/types/client/health-presentation.d.ts +15 -0
- package/package.json +6 -6
package/lib/client.js
CHANGED
|
@@ -112,6 +112,55 @@ window.__ModuleLoader__.load({
|
|
|
112
112
|
reason: "transport"
|
|
113
113
|
});
|
|
114
114
|
//#endregion
|
|
115
|
+
//#region ../evolution-client-kit/src/notice.ts
|
|
116
|
+
/** One inline state notice: semantic tone plus text, no surface-specific styling. */
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region ../evolution-client-kit/src/presentation/decision-frame.ts
|
|
119
|
+
/** One decision card: title, facts, at most one primary, secondary actions and details. */
|
|
120
|
+
//#endregion
|
|
121
|
+
//#region ../evolution-client-kit/src/presentation/task-banner.ts
|
|
122
|
+
/** A read-only task hint; it deliberately has no primary action. */
|
|
123
|
+
//#endregion
|
|
124
|
+
//#region ../evolution-client-kit/src/presentation/chips.ts
|
|
125
|
+
/** Read-only status chips and toggleable filter chips. */
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region ../evolution-client-kit/src/presentation/empty-state.ts
|
|
128
|
+
/** A compact completed/empty state with at most one primary next step. */
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region ../evolution-client-kit/src/presentation/disclosure-group.ts
|
|
131
|
+
/** A native details group for normal/secondary facts. */
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region ../evolution-client-kit/src/presentation/time-text.ts
|
|
134
|
+
/** The one local-time presentation used by reading surfaces. */
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region ../evolution-client-kit/src/presentation/action-menu.ts
|
|
137
|
+
/**
|
|
138
|
+
* The one seam onto the platform's menu material, plus a small fallback for deployments
|
|
139
|
+
* without the primitive row. No page owns a second menu implementation.
|
|
140
|
+
*/
|
|
141
|
+
const PLATFORM_UI_MODULE$1 = "@deepseek-ai/dsh-client-ui-primitives";
|
|
142
|
+
/**
|
|
143
|
+
* Accept only the two component functions; a namespace row without them is not a menu.
|
|
144
|
+
* @param row - the module row's exports.
|
|
145
|
+
* @returns the two components, or undefined.
|
|
146
|
+
*/
|
|
147
|
+
function menuPrimitivesFrom(row) {
|
|
148
|
+
const surface = row.MenuSurface;
|
|
149
|
+
const item = row.MenuItemButton;
|
|
150
|
+
if (typeof surface !== "function" || typeof item !== "function") return void 0;
|
|
151
|
+
return {
|
|
152
|
+
MenuSurface: surface,
|
|
153
|
+
MenuItemButton: item
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
(() => {
|
|
157
|
+
try {
|
|
158
|
+
return menuPrimitivesFrom(require(PLATFORM_UI_MODULE$1));
|
|
159
|
+
} catch {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
})();
|
|
163
|
+
//#endregion
|
|
115
164
|
//#region ../evolution-client-kit/src/action.ts
|
|
116
165
|
/**
|
|
117
166
|
* Command-only actions. Approval decisions are a separate host API and must never
|
|
@@ -314,6 +363,8 @@ window.__ModuleLoader__.load({
|
|
|
314
363
|
"loading": "读取中…",
|
|
315
364
|
"group.byRule": "按规则",
|
|
316
365
|
"group.bySkill": "按技能",
|
|
366
|
+
"health.complete": "没有需要处理的问题",
|
|
367
|
+
"health.normal": "{n} 项正常,展开查看",
|
|
317
368
|
"verdict.healthy": "正常",
|
|
318
369
|
"verdict.warn": "警告",
|
|
319
370
|
"verdict.needs-restructure": "需重构",
|
|
@@ -396,6 +447,8 @@ window.__ModuleLoader__.load({
|
|
|
396
447
|
"loading": "Loading…",
|
|
397
448
|
"group.byRule": "By rule",
|
|
398
449
|
"group.bySkill": "By skill",
|
|
450
|
+
"health.complete": "Nothing needs attention",
|
|
451
|
+
"health.normal": "{n} normal items — expand to view",
|
|
399
452
|
"verdict.healthy": "OK",
|
|
400
453
|
"verdict.warn": "Warn",
|
|
401
454
|
"verdict.needs-restructure": "Needs restructure",
|
|
@@ -498,13 +551,19 @@ window.__ModuleLoader__.load({
|
|
|
498
551
|
":where(.dsh-evolution-skill-health) { --evo-type-lg:calc(1em + 2px);--evo-type-body:1em;--evo-type-sm:calc(1em - 1px);--evo-type-xs:calc(1em - 2px);--evo-space-2:2px;--evo-space-4:4px;--evo-space-6:6px;--evo-space-8:8px;--evo-space-10:10px;--evo-space-12:12px;--evo-space-14:14px;--evo-space-16:16px;--evo-space-20:20px;--evo-radius-chip:4px;--evo-radius-control:8px;--evo-radius-surface:12px;--evo-radius-pill:999px;--evo-hairline-width:.5px;--evo-hairline-marker:2px;--evo-measure-read:80ch;--evo-leading-base:1.5;--evo-tone-quiet:var(--dsw-alias-label-secondary);--evo-tone-primary:var(--dsw-alias-brand-primary);--evo-tone-danger:var(--dsw-alias-state-error-primary);--evo-tone-success:var(--dsw-alias-state-success-primary);--evo-focus-ring:2px solid var(--dsw-alias-label-primary);--evo-focus-offset:-2px;--evo-cap-aside:280px;--evo-cap-block:260px }",
|
|
499
552
|
":where(.dsh-evolution-skill-health) { display: flex; flex-direction: column; gap: var(--evo-space-12); padding: var(--evo-space-16); color: var(--dsw-alias-label-primary); font-size: var(--evo-type-sm); line-height: var(--evo-leading-base); }",
|
|
500
553
|
":where(.dsh-evolution-skill-health [data-role=\"hint\"]) { margin: 0; color: var(--dsw-alias-label-secondary); }",
|
|
501
|
-
":where(.dsh-evolution-skill-health [data-role=\"stats\"]) { display:
|
|
502
|
-
":where(.dsh-evolution-skill-health [data-role=\"stat\"]) { display: flex;
|
|
554
|
+
":where(.dsh-evolution-skill-health [data-role=\"stats\"]) { display: flex; flex-wrap: wrap; gap: var(--evo-space-6); }",
|
|
555
|
+
":where(.dsh-evolution-skill-health [data-role=\"stat\"]) { display: inline-flex; align-items: baseline; gap: var(--evo-space-4); padding: var(--evo-space-4) var(--evo-space-10); border: var(--evo-hairline-width) solid var(--dsw-alias-border-l1); border-radius: var(--evo-radius-pill); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }",
|
|
556
|
+
":where(.dsh-evolution-skill-health [data-role=\"stat-value\"]) { font-size: var(--evo-type-sm); }",
|
|
557
|
+
":where(.dsh-evolution-skill-health [data-role=\"health-complete\"]) { padding: var(--evo-space-12) var(--evo-space-14); border: var(--evo-hairline-width) solid var(--dsw-alias-state-success-primary); border-radius: var(--evo-radius-control); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-state-success-primary); }",
|
|
558
|
+
":where(.dsh-evolution-skill-health [data-role=\"health-normal\"]) { display: flex; flex-direction: column; gap: var(--evo-space-4); padding-top: var(--evo-space-4); }",
|
|
559
|
+
":where(.dsh-evolution-skill-health [data-role=\"health-normal\"] > summary) { cursor: pointer; color: var(--dsw-alias-label-tertiary); font-size: var(--evo-type-xs); }",
|
|
560
|
+
":where(.dsh-evolution-skill-health [data-role=\"stat\"][aria-pressed=\"true\"]) { border-color: var(--dsw-alias-brand-primary); background: var(--dsw-alias-interactive-bg-hover); }",
|
|
561
|
+
":where(.dsh-evolution-skill-health [data-role=\"stat\"]:disabled) { opacity: 0.55; cursor: default; }",
|
|
503
562
|
":where(.dsh-evolution-skill-health [data-role=\"stat\"][data-tone=\"ok\"]) { box-shadow: inset 2px 0 0 var(--dsw-alias-state-success-primary); }",
|
|
504
563
|
":where(.dsh-evolution-skill-health [data-role=\"stat\"][data-tone=\"warn\"]) { box-shadow: inset 2px 0 0 var(--dsw-alias-state-warn-primary); }",
|
|
505
564
|
":where(.dsh-evolution-skill-health [data-role=\"stat\"][data-tone=\"error\"]) { box-shadow: inset 2px 0 0 var(--dsw-alias-state-error-primary); }",
|
|
506
565
|
":where(.dsh-evolution-skill-health [data-role=\"stat\"][data-tone=\"unreadable\"]) { box-shadow: inset 2px 0 0 var(--evo-tone-quiet); }",
|
|
507
|
-
":where(.dsh-evolution-skill-health [data-role=\"stat-value\"]) { font-
|
|
566
|
+
":where(.dsh-evolution-skill-health [data-role=\"stat-value\"]) { font-variant-numeric: tabular-nums; }",
|
|
508
567
|
":where(.dsh-evolution-skill-health [data-role=\"stat-label\"]) { color: var(--dsw-alias-label-tertiary); }",
|
|
509
568
|
":where(.dsh-evolution-skill-health [data-role=\"group-title\"]) { margin: 0; font-weight: 500; }",
|
|
510
569
|
":where(.dsh-evolution-skill-health [data-role=\"rule-table\"]) { display: table; width: 100%; border-collapse: collapse; border: var(--evo-hairline-width) solid var(--dsw-alias-border-l1); border-radius: var(--evo-radius-control); overflow: hidden; }",
|
|
@@ -549,6 +608,29 @@ window.__ModuleLoader__.load({
|
|
|
549
608
|
return cached ?? void 0;
|
|
550
609
|
}
|
|
551
610
|
//#endregion
|
|
611
|
+
//#region src/client/health-presentation.ts
|
|
612
|
+
/**
|
|
613
|
+
* Split rows without dropping or inventing a verdict. Unreadable is an issue, never normal.
|
|
614
|
+
* @param rows - all rows in the current projection.
|
|
615
|
+
* @returns issues in severity order and the normal remainder.
|
|
616
|
+
*/
|
|
617
|
+
function healthViewModel(rows) {
|
|
618
|
+
const order = [
|
|
619
|
+
"error",
|
|
620
|
+
"needs-restructure",
|
|
621
|
+
"warn",
|
|
622
|
+
"unreadable",
|
|
623
|
+
"healthy"
|
|
624
|
+
];
|
|
625
|
+
const sorted = [...rows].sort((a, b) => order.indexOf(a.verdict) - order.indexOf(b.verdict) || a.name.localeCompare(b.name));
|
|
626
|
+
const issues = sorted.filter((row) => row.verdict !== "healthy");
|
|
627
|
+
return {
|
|
628
|
+
issues,
|
|
629
|
+
normal: sorted.filter((row) => row.verdict === "healthy"),
|
|
630
|
+
hasIssues: issues.length > 0
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
//#endregion
|
|
552
634
|
//#region src/client/Panel.ts
|
|
553
635
|
/**
|
|
554
636
|
* The panel body: a four-state summary plus the list aggregated BY RULE.
|
|
@@ -645,17 +727,8 @@ window.__ModuleLoader__.load({
|
|
|
645
727
|
}
|
|
646
728
|
}, text);
|
|
647
729
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
const order = [
|
|
651
|
-
"error",
|
|
652
|
-
"needs-restructure",
|
|
653
|
-
"warn",
|
|
654
|
-
"unreadable",
|
|
655
|
-
"healthy"
|
|
656
|
-
];
|
|
657
|
-
const rows = [...face.rows].sort((a, b) => order.indexOf(a.verdict) - order.indexOf(b.verdict) || a.name.localeCompare(b.name));
|
|
658
|
-
return (0, react.createElement)("div", { "data-role": "skill-queue" }, (0, react.createElement)("h3", { "data-role": "group-title" }, t("group.bySkill")), ...rows.map((row) => (0, react.createElement)("div", {
|
|
730
|
+
function skillRowNode(face, t, row) {
|
|
731
|
+
return (0, react.createElement)("div", {
|
|
659
732
|
key: row.name,
|
|
660
733
|
"data-role": "skill-row",
|
|
661
734
|
"data-tone": row.verdict
|
|
@@ -671,7 +744,14 @@ window.__ModuleLoader__.load({
|
|
|
671
744
|
t,
|
|
672
745
|
role: "action-copy",
|
|
673
746
|
label: t("action.copy")
|
|
674
|
-
})))
|
|
747
|
+
})));
|
|
748
|
+
}
|
|
749
|
+
/** H4: issues first, normal items folded behind one native details summary. */
|
|
750
|
+
function skillQueue(face, t, model) {
|
|
751
|
+
return (0, react.createElement)("div", { "data-role": "skill-queue" }, (0, react.createElement)("h3", { "data-role": "group-title" }, t("group.bySkill")), model.hasIssues ? null : (0, react.createElement)("div", { "data-role": "health-complete" }, t("health.complete")), ...model.issues.map((row) => skillRowNode(face, t, row)), model.normal.length === 0 ? null : (0, react.createElement)("details", {
|
|
752
|
+
"data-role": "health-normal",
|
|
753
|
+
className: "evo-health-normal"
|
|
754
|
+
}, (0, react.createElement)("summary", null, t("health.normal").replace("{n}", String(model.normal.length))), ...model.normal.map((row) => skillRowNode(face, t, row))));
|
|
675
755
|
}
|
|
676
756
|
/** The rule table: a grid so counts line up, with a tone bar per row and skill pills. */
|
|
677
757
|
function ruleTable(face, t) {
|
|
@@ -731,6 +811,7 @@ window.__ModuleLoader__.load({
|
|
|
731
811
|
const [lastReadAt, setLastReadAt] = (0, react.useState)(face.readAt);
|
|
732
812
|
const [scan, setScan] = (0, react.useState)(face.scan);
|
|
733
813
|
const [viewMode, setViewMode] = (0, react.useState)("skills");
|
|
814
|
+
const [verdictFilter, setVerdictFilter] = (0, react.useState)(void 0);
|
|
734
815
|
const firstLoad = (0, react.useRef)(false);
|
|
735
816
|
const readTicket = (0, react.useRef)(0);
|
|
736
817
|
/** One read trigger for first paint and the refresh button; the latest answer wins. */
|
|
@@ -771,11 +852,22 @@ window.__ModuleLoader__.load({
|
|
|
771
852
|
load();
|
|
772
853
|
}, [face]);
|
|
773
854
|
const counts = new Map(KINDS.map((kind) => [kind, view.rows.filter((row) => row.verdict === kind).length]));
|
|
774
|
-
const
|
|
855
|
+
const shown = verdictFilter === void 0 ? view : {
|
|
856
|
+
...view,
|
|
857
|
+
rows: view.rows.filter((row) => row.verdict === verdictFilter)
|
|
858
|
+
};
|
|
859
|
+
const stats = (0, react.createElement)("div", { "data-role": "stats" }, KINDS.map((kind) => (0, react.createElement)("button", {
|
|
775
860
|
key: kind,
|
|
861
|
+
type: "button",
|
|
776
862
|
"data-role": "stat",
|
|
777
|
-
"data-tone": TONE[kind]
|
|
778
|
-
|
|
863
|
+
"data-tone": TONE[kind],
|
|
864
|
+
"aria-pressed": verdictFilter === kind ? "true" : "false",
|
|
865
|
+
"aria-label": t("verdict." + kind),
|
|
866
|
+
disabled: (counts.get(kind) ?? 0) === 0,
|
|
867
|
+
onClick: () => {
|
|
868
|
+
setVerdictFilter((previous) => previous === kind ? void 0 : kind);
|
|
869
|
+
}
|
|
870
|
+
}, (0, react.createElement)("span", { "data-role": "stat-value" }, String(counts.get(kind) ?? 0)), (0, react.createElement)("span", { "data-role": "stat-label" }, t("verdict." + kind)))));
|
|
779
871
|
return (0, react.createElement)("section", { className: CSS_TAG_ID }, (0, react.createElement)("div", { "data-role": "header" }, (0, react.createElement)("span", { "data-role": "read-at" }, lastReadAt === void 0 ? t("readAt.unknown") : new Date(lastReadAt).toLocaleString()), (0, react.createElement)("span", { "data-role": "scan-status" }, t("scan." + (scan?.status ?? "unavailable"))), (0, react.createElement)("button", {
|
|
780
872
|
type: "button",
|
|
781
873
|
"data-role": "refresh",
|
|
@@ -834,10 +926,10 @@ window.__ModuleLoader__.load({
|
|
|
834
926
|
})(), viewMode === "skills" ? (0, react.createElement)("div", {
|
|
835
927
|
id: "evo-health-skills",
|
|
836
928
|
role: "tabpanel"
|
|
837
|
-
}, skillQueue(
|
|
929
|
+
}, skillQueue(shown, t, healthViewModel(shown.rows))) : (0, react.createElement)("div", {
|
|
838
930
|
id: "evo-health-rules",
|
|
839
931
|
role: "tabpanel"
|
|
840
|
-
}, (0, react.createElement)("h3", { "data-role": "group-title" }, t("group.byRule")), ruleTable(
|
|
932
|
+
}, (0, react.createElement)("h3", { "data-role": "group-title" }, t("group.byRule")), ruleTable(shown, t)));
|
|
841
933
|
}
|
|
842
934
|
//#endregion
|
|
843
935
|
//#region src/client/seats.ts
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Pure health reading shape: issues first, normal items folded behind a summary. */
|
|
2
|
+
import type { HealthRow } from './Panel.ts';
|
|
3
|
+
/** The split the health page renders from; counts remain the caller's whole-row facts. */
|
|
4
|
+
export interface HealthViewModel {
|
|
5
|
+
readonly issues: readonly HealthRow[];
|
|
6
|
+
readonly normal: readonly HealthRow[];
|
|
7
|
+
readonly hasIssues: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Split rows without dropping or inventing a verdict. Unreadable is an issue, never normal.
|
|
11
|
+
* @param rows - all rows in the current projection.
|
|
12
|
+
* @returns issues in severity order and the normal remainder.
|
|
13
|
+
*/
|
|
14
|
+
export declare function healthViewModel(rows: readonly HealthRow[]): HealthViewModel;
|
|
15
|
+
//# sourceMappingURL=health-presentation.d.ts.map
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
]
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
|
-
"version": "0.
|
|
14
|
+
"version": "0.36.0",
|
|
15
15
|
"publishConfig": {
|
|
16
16
|
"access": "public"
|
|
17
17
|
},
|
|
@@ -42,18 +42,18 @@
|
|
|
42
42
|
"peerDependencies": {
|
|
43
43
|
"@deepseek-ai/cordis": "^4.0.5",
|
|
44
44
|
"react": "^18.2.0",
|
|
45
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
46
|
-
"@lmzhen/dsh-evolution-curator": "^0.
|
|
45
|
+
"@lmzhen/dsh-evolution-core": "^0.36.0",
|
|
46
|
+
"@lmzhen/dsh-evolution-curator": "^0.36.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
49
|
"@deepseek-ai/cordis": "^4.0.5",
|
|
50
50
|
"@types/react": "~18.3.1",
|
|
51
51
|
"react": "^18.2.0",
|
|
52
|
-
"@lmzhen/dsh-evolution-core": "^0.
|
|
53
|
-
"@lmzhen/dsh-evolution-curator": "^0.
|
|
52
|
+
"@lmzhen/dsh-evolution-core": "^0.36.0",
|
|
53
|
+
"@lmzhen/dsh-evolution-curator": "^0.36.0"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"@lmzhen/dsh-evolution-client-kit": "^0.
|
|
56
|
+
"@lmzhen/dsh-evolution-client-kit": "^0.36.0"
|
|
57
57
|
},
|
|
58
58
|
"engines": {
|
|
59
59
|
"dsh": ">=0.2.1-rc.2 <0.2.2-0"
|