@agile-team/wl-skills-ui 1.6.2
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/CHANGELOG.md +207 -0
- package/README.md +623 -0
- package/SKILL.md +632 -0
- package/bin/wl-ui.js +794 -0
- package/design/spec/color.md +41 -0
- package/design/spec/spacing.md +28 -0
- package/design/spec/typography.md +29 -0
- package/design/tokens/base.css +144 -0
- package/design/tokens/index.css +8 -0
- package/dist/ag-grid-override.scss +1 -0
- package/dist/element.scss +1 -0
- package/dist/index.scss +1 -0
- package/dist/portal.scss +1 -0
- package/dist/style-override.scss +1 -0
- package/dist/tokens.css +144 -0
- package/es/chunk-GBB7LDKQ.js +261 -0
- package/es/chunk-MDI2SCUP.js +281 -0
- package/es/chunk-QDTNMM7W.js +286 -0
- package/es/chunk-YLNAFAWE.js +233 -0
- package/es/common-preset.d.ts +38 -0
- package/es/common-preset.js +157 -0
- package/es/index.d.ts +32 -0
- package/es/index.js +1 -0
- package/es/presets/security.d.ts +16 -0
- package/es/presets/security.js +99 -0
- package/es/renderers-BFRSp2BH.d.ts +51 -0
- package/es/renderers-DMZbi_Gs.d.ts +51 -0
- package/es/renderers-DWhUlI2y.d.ts +47 -0
- package/es/types-04qLKHMt.d.ts +62 -0
- package/es/types-BrCPjAH6.d.ts +62 -0
- package/es/types-QZ1gy9KX.d.ts +63 -0
- package/examples/migration-operations-to-renderOps.md +107 -0
- package/examples/wk-exempt.example.json +30 -0
- package/mcp/server.js +394 -0
- package/package.json +130 -0
- package/reference/SelectPopupCom.vue +634 -0
- package/reference/ag-cell-renders.ts +644 -0
- package/reference/define-columns.ts +185 -0
- package/reference/jhlc.d.ts +1 -0
- package/scanner/coverage.mjs +287 -0
- package/scanner/exempt.mjs +127 -0
- package/scanner/fix.mjs +216 -0
- package/scanner/index.mjs +403 -0
- package/scanner/integration.mjs +155 -0
- package/scanner/report.mjs +459 -0
- package/scanner/rules/_shared.mjs +134 -0
- package/scanner/rules/button.mjs +97 -0
- package/scanner/rules/color.mjs +118 -0
- package/scanner/rules/componentFamily.mjs +184 -0
- package/scanner/rules/dialog.mjs +42 -0
- package/scanner/rules/form.mjs +86 -0
- package/scanner/rules/index.mjs +58 -0
- package/scanner/rules/table.mjs +170 -0
- package/scanner/rules/tag.mjs +245 -0
- package/scanner/snapshot.mjs +198 -0
- package/skills/_flows/full-audit.md +65 -0
- package/skills/_flows/legacy-skin-align.md +71 -0
- package/skills/_flows/new-project-init.md +80 -0
- package/skills/_flows/progressive-migrate.md +49 -0
- package/skills/_meta/_compat/README.md +47 -0
- package/skills/_meta/_compat/editors.json +76 -0
- package/skills/_meta/_compat/headers/agents.txt +7 -0
- package/skills/_meta/_compat/headers/claude-code.txt +7 -0
- package/skills/_meta/_compat/headers/cline.txt +7 -0
- package/skills/_meta/_compat/headers/cursor-mdc.txt +5 -0
- package/skills/_meta/_compat/headers/github-copilot.txt +5 -0
- package/skills/_meta/_compat/headers/kiro.txt +4 -0
- package/skills/_meta/_compat/headers/qoder.txt +4 -0
- package/skills/_meta/_compat/headers/trae.txt +3 -0
- package/skills/_meta/_compat/headers/windsurf.txt +5 -0
- package/skills/_meta/_detection.md +81 -0
- package/skills/_meta/_registry.md +96 -0
- package/skills/element/component-family/SKILL.md +71 -0
- package/skills/element/el-dialog/SKILL.md +124 -0
- package/skills/element/el-form/SKILL.md +84 -0
- package/skills/element/el-table/SKILL.md +86 -0
- package/skills/element/el-tag/SKILL.md +127 -0
- package/skills/layouts/detail-page/SKILL.md +99 -0
- package/skills/layouts/form-dialog/SKILL.md +128 -0
- package/skills/layouts/list-page/SKILL.md +111 -0
- package/skills/layouts/tree-list/SKILL.md +108 -0
- package/skills/ops/audit/SKILL.md +109 -0
- package/skills/ops/fix/SKILL.md +52 -0
- package/skills/ops/fix/USAGE.md +24 -0
- package/skills/ops/migrate/SKILL.md +157 -0
- package/skills/ops/scan/SKILL.md +71 -0
- package/skills/ops/scan/USAGE.md +16 -0
- package/skills/runtime/design-tokens/SKILL.md +88 -0
- package/skills/runtime/design-tokens/USAGE.md +19 -0
- package/skills/runtime/migration/SKILL.md +106 -0
- package/skills/runtime/migration/USAGE.md +34 -0
- package/skills/runtime/style-align/SKILL.md +124 -0
- package/skills/runtime/style-align/USAGE.md +52 -0
- package/skills/vendors/ag-grid/SKILL.md +94 -0
- package/skills/vendors/base-table/SKILL.md +57 -0
- package/skills/vendors/c-components/SKILL.md +36 -0
- package/skills/vendors/custom-wrappers/SKILL.md +45 -0
- package/skills/vendors/jh-components/SKILL.md +42 -0
- package/skills/vendors/unknown-wrapper/SKILL.md +44 -0
- package/standards/engineering/01-import-order.md +46 -0
- package/standards/engineering/02-naming.md +54 -0
- package/standards/engineering/03-scss-structure.md +59 -0
- package/standards/ui/01-table.md +111 -0
- package/standards/ui/02-button.md +83 -0
- package/standards/ui/03-form.md +118 -0
- package/standards/ui/04-tag-status.md +110 -0
- package/standards/ui/05-dialog-pagination.md +118 -0
- package/styles/element/_card.scss +26 -0
- package/styles/element/_descriptions.scss +22 -0
- package/styles/element/_dialog.scss +43 -0
- package/styles/element/_drawer.scss +22 -0
- package/styles/element/_feedback.scss +52 -0
- package/styles/element/_form.scss +22 -0
- package/styles/element/_navigation.scss +36 -0
- package/styles/element/_overlay.scss +32 -0
- package/styles/element/_pagination.scss +16 -0
- package/styles/element/_steps.scss +32 -0
- package/styles/element/_table.scss +13 -0
- package/styles/element/_tabs.scss +40 -0
- package/styles/element/_tree.scss +27 -0
- package/styles/element/_upload.scss +34 -0
- package/styles/element/index.scss +17 -0
- package/styles/index.scss +21 -0
- package/styles/layouts/_detail-page.scss +27 -0
- package/styles/layouts/_form-dialog.scss +19 -0
- package/styles/layouts/_list-page.scss +47 -0
- package/styles/layouts/_tree-list.scss +33 -0
- package/styles/layouts/index.scss +6 -0
- package/styles/presets/element-only.scss +6 -0
- package/styles/presets/full.scss +12 -0
- package/styles/presets/security.scss +37 -0
- package/styles/presets/skin.scss +14 -0
- package/styles/presets/tokens-only.scss +7 -0
- package/styles/tokens/index.scss +79 -0
- package/styles/vendors/_ag-grid.scss +273 -0
- package/styles/vendors/_base-components.scss +480 -0
- package/styles/vendors/_base-query-toolbar.scss +253 -0
- package/styles/vendors/_base-table.scss +41 -0
- package/styles/vendors/_c-components.scss +34 -0
- package/styles/vendors/_custom-wrappers.scss +30 -0
- package/styles/vendors/_jh-drag-col.scss +63 -0
- package/styles/vendors/_jh-pagination.scss +81 -0
- package/styles/vendors/_jh-tree.scss +196 -0
- package/styles/vendors/_portal.scss +114 -0
- package/styles/vendors/index.scss +17 -0
- package/templates/ag-grid-page/TPL-AG-GRID.md +76 -0
- package/templates/form-dialog/TPL-FORM-DIALOG.md +165 -0
- package/templates/list-page/TPL-LIST.md +139 -0
- package/templates/tree-list/TPL-TREE-LIST.md +176 -0
- package/templates/ui-optimization-report/TPL-UI-OPTIM-REPORT.md +343 -0
package/mcp/server.js
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { dirname, resolve, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = dirname(__filename);
|
|
9
|
+
const PKG_ROOT = resolve(__dirname, "..");
|
|
10
|
+
const require = createRequire(import.meta.url);
|
|
11
|
+
const PKG = require("../package.json");
|
|
12
|
+
|
|
13
|
+
const TOOLS = [
|
|
14
|
+
{
|
|
15
|
+
name: "wks_ui_check",
|
|
16
|
+
description:
|
|
17
|
+
"检查当前项目是否已正确接入 @agile-team/wk-skills-ui 的 tokens/styles/runtime。",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
type: "object",
|
|
20
|
+
properties: {
|
|
21
|
+
project: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "项目根目录,默认 WL_PROJECT_ROOT 或当前目录",
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: [],
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: "wks_ui_scan",
|
|
31
|
+
description:
|
|
32
|
+
"扫描 Vue 项目的 UI 风格偏差,支持 skin/native、layer、vendor、exempt 过滤。",
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: "object",
|
|
35
|
+
properties: {
|
|
36
|
+
target: { type: "string", description: "扫描目录,默认 src" },
|
|
37
|
+
project: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "项目根目录,默认 WL_PROJECT_ROOT 或当前目录",
|
|
40
|
+
},
|
|
41
|
+
mode: { type: "string", description: "skin 或 native" },
|
|
42
|
+
layer: { type: "string", description: "L0,L1,L2,L3,L4 逗号分隔" },
|
|
43
|
+
vendor: { type: "string", description: "vendor 过滤,逗号分隔" },
|
|
44
|
+
output: {
|
|
45
|
+
type: "string",
|
|
46
|
+
description: "markdown 或 json,默认 markdown",
|
|
47
|
+
},
|
|
48
|
+
exempt: { type: "string", description: "豁免配置文件路径" },
|
|
49
|
+
},
|
|
50
|
+
required: [],
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "wks_ui_fix_dry_run",
|
|
55
|
+
description: "预览 wk-skills-ui 自动修复会修改哪些文件,不实际写入。",
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: "object",
|
|
58
|
+
properties: {
|
|
59
|
+
target: { type: "string", description: "扫描目录,默认 src" },
|
|
60
|
+
project: {
|
|
61
|
+
type: "string",
|
|
62
|
+
description: "项目根目录,默认 WL_PROJECT_ROOT 或当前目录",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
required: [],
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "wks_ui_skill_prompt",
|
|
70
|
+
description:
|
|
71
|
+
"输出 wk-skills-ui 推荐触发语和下一步操作,引导 AI 加载正确 Skill/Flow。",
|
|
72
|
+
inputSchema: { type: "object", properties: {}, required: [] },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: "wks_ui_route_intent",
|
|
76
|
+
description:
|
|
77
|
+
"根据用户自然语言判断 UI 样式治理意图,并推荐 wk-skills-ui flow/tool/skill。",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {
|
|
81
|
+
text: { type: "string", description: "用户自然语言需求" },
|
|
82
|
+
},
|
|
83
|
+
required: ["text"],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: "wks_ui_recommend_flow",
|
|
88
|
+
description:
|
|
89
|
+
"根据 wks_ui_scan --output json 的扫描结果推荐后续 flow、tool 和 wl-skills-kit 桥接动作。",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
properties: {
|
|
93
|
+
scanJson: { type: "string", description: "扫描 JSON 字符串" },
|
|
94
|
+
},
|
|
95
|
+
required: ["scanJson"],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
function send(obj) {
|
|
101
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function sendResult(id, result) {
|
|
105
|
+
send({ jsonrpc: "2.0", id, result });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function sendError(id, code, message) {
|
|
109
|
+
send({ jsonrpc: "2.0", id, error: { code, message } });
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function projectRoot(args = {}) {
|
|
113
|
+
return resolve(args.project || process.env.WL_PROJECT_ROOT || process.cwd());
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function runScanner(command, args = {}) {
|
|
117
|
+
const root = projectRoot(args);
|
|
118
|
+
const scanner = join(PKG_ROOT, "scanner", "index.mjs");
|
|
119
|
+
const cliArgs = [scanner, command];
|
|
120
|
+
if (command === "check") {
|
|
121
|
+
cliArgs.push("--project", root);
|
|
122
|
+
} else {
|
|
123
|
+
cliArgs.push("--project", root);
|
|
124
|
+
cliArgs.push("--target", resolve(root, args.target || "src"));
|
|
125
|
+
if (args.mode) cliArgs.push("--mode", String(args.mode));
|
|
126
|
+
if (args.layer) cliArgs.push("--layer", String(args.layer));
|
|
127
|
+
if (args.vendor) cliArgs.push("--vendor", String(args.vendor));
|
|
128
|
+
if (args.output) cliArgs.push("--output", String(args.output));
|
|
129
|
+
if (args.exempt) cliArgs.push("--exempt", String(args.exempt));
|
|
130
|
+
if (command === "fix") cliArgs.push("--dry-run");
|
|
131
|
+
}
|
|
132
|
+
return new Promise((resolvePromise) => {
|
|
133
|
+
const child = spawn(process.execPath, cliArgs, { cwd: root, shell: false });
|
|
134
|
+
let stdout = "";
|
|
135
|
+
let stderr = "";
|
|
136
|
+
child.stdout.on("data", (chunk) => (stdout += chunk));
|
|
137
|
+
child.stderr.on("data", (chunk) => (stderr += chunk));
|
|
138
|
+
child.on("close", (code) => {
|
|
139
|
+
const text = [stdout.trim(), stderr.trim()].filter(Boolean).join("\n");
|
|
140
|
+
resolvePromise({ code, text: text || "(无输出)" });
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function skillPrompt() {
|
|
146
|
+
return "# wk-skills-ui Skill 触发提示\n\n核心原则:wk-skills-ui 优先保证样式绝对管控,覆盖纯 Element Plus、老项目封装、Base*/jh*/C_* 以及 wl-skills-kit 最佳写法。\n\n推荐触发语:\n\n- 新项目:用 wk-ui 的 new-project-init 流程接入统一 UI 风格\n- 老项目:用 wk-ui 的 legacy-skin-align 流程做老项目化妆对齐\n- 只审计:用 wk-ui 的 full-audit 流程扫描当前项目,不修改代码\n- 渐进迁移:用 wk-ui 的 progressive-migrate 流程从 skin 迁移到 runtime\n- 表格/弹窗/卡片/Tab/详情/树/抽屉/上传/步骤条/更多操作样式不统一:先调用 wks_ui_route_intent,再调用 wks_ui_scan\n- 单点修复:用 wk-ui 的 vendors/base-table、element/el-table 或 element 组件族 skill 检查当前文件\n\n执行约束:\n\n- 扫描只读,修复前必须先给用户摘要并等待确认\n- 老项目 skin 模式只处理 L0/L1/L2,不改业务布局和 runtime\n- 若扫描结果涉及页面结构、BaseTable render-type/cid 或 renderOps,视觉统一后再建议 wl-skills-kit validate-page / doctor-ui。";
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function routeIntent(args = {}) {
|
|
150
|
+
const text = String(args.text || "").toLowerCase();
|
|
151
|
+
const matchedComponents = [];
|
|
152
|
+
const recommendedSkills = [];
|
|
153
|
+
const recommendedTools = ["wks_ui_scan"];
|
|
154
|
+
let intent = "full-audit";
|
|
155
|
+
let recommendedFlow = "full-audit";
|
|
156
|
+
|
|
157
|
+
const componentRules = [
|
|
158
|
+
[/表格|table|basetable|aggrid|ag-grid/, "el-table", "element/el-table"],
|
|
159
|
+
[
|
|
160
|
+
/表单|输入|查询|筛选|form|input|select|date/,
|
|
161
|
+
"el-form",
|
|
162
|
+
"element/el-form",
|
|
163
|
+
],
|
|
164
|
+
[/弹窗|dialog|modal/, "el-dialog", "element/el-dialog"],
|
|
165
|
+
[/卡片|card/, "el-card", "element/el-card"],
|
|
166
|
+
[/tab|标签页|页签/, "el-tabs", "element/el-tabs"],
|
|
167
|
+
[/详情|描述|descriptions/, "el-descriptions", "element/el-descriptions"],
|
|
168
|
+
[/树|tree/, "el-tree", "element/el-tree"],
|
|
169
|
+
[/抽屉|drawer/, "el-drawer", "element/el-drawer"],
|
|
170
|
+
[/上传|附件|upload/, "el-upload", "element/el-upload"],
|
|
171
|
+
[/步骤|流程|审批|steps/, "el-steps", "element/el-steps"],
|
|
172
|
+
[
|
|
173
|
+
/下拉|更多|popover|tooltip|dropdown|提示/,
|
|
174
|
+
"el-overlay",
|
|
175
|
+
"element/el-overlay",
|
|
176
|
+
],
|
|
177
|
+
[
|
|
178
|
+
/菜单|面包屑|导航|menu|breadcrumb/,
|
|
179
|
+
"el-navigation",
|
|
180
|
+
"element/el-navigation",
|
|
181
|
+
],
|
|
182
|
+
[
|
|
183
|
+
/空状态|异常|警告|角标|empty|result|alert|badge/,
|
|
184
|
+
"el-feedback",
|
|
185
|
+
"element/el-feedback",
|
|
186
|
+
],
|
|
187
|
+
];
|
|
188
|
+
|
|
189
|
+
for (const [pattern, component, skill] of componentRules) {
|
|
190
|
+
if (pattern.test(text)) {
|
|
191
|
+
matchedComponents.push(component);
|
|
192
|
+
recommendedSkills.push(skill);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (/老项目|旧项目|样式乱|不统一|化妆|统一视觉|skin/.test(text)) {
|
|
197
|
+
intent = "legacy-skin-align";
|
|
198
|
+
recommendedFlow = "legacy-skin-align";
|
|
199
|
+
recommendedTools.push("wks_ui_fix_dry_run");
|
|
200
|
+
} else if (/迁移|runtime|token|硬编码|颜色/.test(text)) {
|
|
201
|
+
intent = "progressive-migrate";
|
|
202
|
+
recommendedFlow = "progressive-migrate";
|
|
203
|
+
} else if (/新项目|初始化|接入/.test(text)) {
|
|
204
|
+
intent = "new-project-init";
|
|
205
|
+
recommendedFlow = "new-project-init";
|
|
206
|
+
recommendedTools.unshift("wks_ui_check");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const shouldUseKit =
|
|
210
|
+
/生成|重构|规范化|菜单|权限|字典|validate|doctor|kit|basetable|renderops/.test(
|
|
211
|
+
text,
|
|
212
|
+
);
|
|
213
|
+
return {
|
|
214
|
+
intent,
|
|
215
|
+
matchedComponents: [...new Set(matchedComponents)],
|
|
216
|
+
recommendedFlow,
|
|
217
|
+
recommendedSkills: [...new Set(recommendedSkills)],
|
|
218
|
+
recommendedTools: [...new Set(recommendedTools)],
|
|
219
|
+
shouldUseKit,
|
|
220
|
+
nextActions: [
|
|
221
|
+
"先执行 wks_ui_scan 做只读扫描,确认 componentCoverage 与 issues",
|
|
222
|
+
"如需修复,先执行 wks_ui_fix_dry_run 预览,不直接写入",
|
|
223
|
+
shouldUseKit
|
|
224
|
+
? "若要规范化页面结构,再桥接 wl-skills-kit validate-page / doctor-ui"
|
|
225
|
+
: "优先由 wk-skills-ui skin/native 样式层完成视觉统一",
|
|
226
|
+
],
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function hasKitBridgeNeed(rules, coverage) {
|
|
231
|
+
return (
|
|
232
|
+
rules.has("R013") ||
|
|
233
|
+
rules.has("R021") ||
|
|
234
|
+
rules.has("R022") ||
|
|
235
|
+
(coverage.layouts || []).length > 0 ||
|
|
236
|
+
(coverage.businessScenarios || []).some((item) =>
|
|
237
|
+
["query-table", "tree-table", "dialog-form"].includes(item),
|
|
238
|
+
)
|
|
239
|
+
);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function buildKitBridge(needed) {
|
|
243
|
+
return {
|
|
244
|
+
needed,
|
|
245
|
+
reason: needed
|
|
246
|
+
? "扫描结果涉及页面结构、BaseTable 或操作列规范,建议视觉统一后桥接 wl-skills-kit。"
|
|
247
|
+
: "当前由 wk-skills-ui 负责样式绝对管控即可,不强制桥接 wl-skills-kit。",
|
|
248
|
+
commands: needed
|
|
249
|
+
? ["wl-skills validate-page <page>", "wl-skills doctor-ui <project>"]
|
|
250
|
+
: [],
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function recommendFromScan(args = {}) {
|
|
255
|
+
const parsed = JSON.parse(String(args.scanJson || "{}"));
|
|
256
|
+
const issues = parsed.issues || [];
|
|
257
|
+
const coverage = parsed.componentCoverage || {};
|
|
258
|
+
const rules = new Set(issues.map((issue) => issue.rule));
|
|
259
|
+
const categories = new Set(issues.map((issue) => issue.category));
|
|
260
|
+
const recommendedFlows = new Set(
|
|
261
|
+
parsed.recommendations?.recommendedFlows || [],
|
|
262
|
+
);
|
|
263
|
+
const nextActions = new Set(parsed.recommendations?.nextActions || []);
|
|
264
|
+
|
|
265
|
+
if (issues.length > 0) {
|
|
266
|
+
recommendedFlows.add("legacy-skin-align");
|
|
267
|
+
nextActions.add(
|
|
268
|
+
"先用 skin/native 样式层完成视觉统一,再判断是否需要代码级修复",
|
|
269
|
+
);
|
|
270
|
+
nextActions.add("修复前调用 wks_ui_fix_dry_run 并向用户展示摘要");
|
|
271
|
+
} else {
|
|
272
|
+
recommendedFlows.add("full-audit");
|
|
273
|
+
nextActions.add("当前扫描未发现规则问题,建议保留周期性 full-audit");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
if (categories.has("color") || categories.has("token")) {
|
|
277
|
+
recommendedFlows.add("progressive-migrate");
|
|
278
|
+
nextActions.add(
|
|
279
|
+
"硬编码色值应迁移为 wk-skills-ui tokens 或 Element Plus 变量",
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const shouldUseKit = hasKitBridgeNeed(rules, coverage);
|
|
284
|
+
return {
|
|
285
|
+
recommendedFlows: [...recommendedFlows].sort(),
|
|
286
|
+
recommendedSkills:
|
|
287
|
+
parsed.recommendedSkills || coverage.recommendedSkills || [],
|
|
288
|
+
componentCoverage: coverage,
|
|
289
|
+
recommendedTools:
|
|
290
|
+
issues.length > 0
|
|
291
|
+
? ["wks_ui_scan", "wks_ui_fix_dry_run"]
|
|
292
|
+
: ["wks_ui_scan"],
|
|
293
|
+
kitBridge: buildKitBridge(shouldUseKit),
|
|
294
|
+
nextActions: [...nextActions].sort(),
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
async function dispatchTool(id, name, args) {
|
|
299
|
+
try {
|
|
300
|
+
if (name === "wks_ui_check") {
|
|
301
|
+
const result = await runScanner("check", args);
|
|
302
|
+
sendResult(id, {
|
|
303
|
+
content: [{ type: "text", text: result.text }],
|
|
304
|
+
isError: result.code !== 0,
|
|
305
|
+
});
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
if (name === "wks_ui_scan") {
|
|
309
|
+
const result = await runScanner("scan", args);
|
|
310
|
+
sendResult(id, {
|
|
311
|
+
content: [{ type: "text", text: result.text }],
|
|
312
|
+
isError: result.code !== 0,
|
|
313
|
+
});
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
if (name === "wks_ui_fix_dry_run") {
|
|
317
|
+
const result = await runScanner("fix", args);
|
|
318
|
+
sendResult(id, {
|
|
319
|
+
content: [{ type: "text", text: result.text }],
|
|
320
|
+
isError: result.code !== 0,
|
|
321
|
+
});
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (name === "wks_ui_skill_prompt") {
|
|
325
|
+
sendResult(id, { content: [{ type: "text", text: skillPrompt() }] });
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (name === "wks_ui_route_intent") {
|
|
329
|
+
sendResult(id, {
|
|
330
|
+
content: [
|
|
331
|
+
{ type: "text", text: JSON.stringify(routeIntent(args), null, 2) },
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
if (name === "wks_ui_recommend_flow") {
|
|
337
|
+
sendResult(id, {
|
|
338
|
+
content: [
|
|
339
|
+
{
|
|
340
|
+
type: "text",
|
|
341
|
+
text: JSON.stringify(recommendFromScan(args), null, 2),
|
|
342
|
+
},
|
|
343
|
+
],
|
|
344
|
+
});
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
sendError(id, -32601, `未知工具: ${name}`);
|
|
348
|
+
} catch (e) {
|
|
349
|
+
sendResult(id, {
|
|
350
|
+
content: [{ type: "text", text: `❌ 工具执行异常: ${e.message}` }],
|
|
351
|
+
isError: true,
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
process.stdin.setEncoding("utf8");
|
|
357
|
+
let buffer = "";
|
|
358
|
+
process.stdin.on("data", (chunk) => {
|
|
359
|
+
buffer += chunk;
|
|
360
|
+
let index;
|
|
361
|
+
while ((index = buffer.indexOf("\n")) >= 0) {
|
|
362
|
+
const line = buffer.slice(0, index).trim();
|
|
363
|
+
buffer = buffer.slice(index + 1);
|
|
364
|
+
if (!line) continue;
|
|
365
|
+
let msg;
|
|
366
|
+
try {
|
|
367
|
+
msg = JSON.parse(line);
|
|
368
|
+
} catch {
|
|
369
|
+
send({
|
|
370
|
+
jsonrpc: "2.0",
|
|
371
|
+
id: null,
|
|
372
|
+
error: { code: -32700, message: "Parse error" },
|
|
373
|
+
});
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
const { id, method, params = {} } = msg;
|
|
377
|
+
if (id === undefined || id === null) continue;
|
|
378
|
+
if (method === "initialize") {
|
|
379
|
+
sendResult(id, {
|
|
380
|
+
protocolVersion: "2024-11-05",
|
|
381
|
+
capabilities: { tools: {} },
|
|
382
|
+
serverInfo: { name: "wk-skills-ui", version: PKG.version },
|
|
383
|
+
});
|
|
384
|
+
} else if (method === "tools/list") {
|
|
385
|
+
sendResult(id, { tools: TOOLS });
|
|
386
|
+
} else if (method === "tools/call") {
|
|
387
|
+
dispatchTool(id, params.name, params.arguments || {});
|
|
388
|
+
} else if (method === "ping") {
|
|
389
|
+
sendResult(id, {});
|
|
390
|
+
} else {
|
|
391
|
+
sendError(id, -32601, `Method not found: ${method}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agile-team/wl-skills-ui",
|
|
3
|
+
"version": "1.6.2",
|
|
4
|
+
"description": "企业级 UI 风格对齐框架 — Vue + Element Plus 项目通用化妆/原生双模式(tokens / element / vendors / layouts / runtime / scanner / fixer / skills)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./es/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./es/index.js",
|
|
10
|
+
"types": "./es/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./runtime": "./",
|
|
13
|
+
"./runtime/common-preset": {
|
|
14
|
+
"import": "./es/common-preset.js",
|
|
15
|
+
"types": "./es/common-preset.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./runtime/presets/security": {
|
|
18
|
+
"import": "./es/presets/security.js",
|
|
19
|
+
"types": "./es/presets/security.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./runtime/presets/*": "./runtime/presets/*",
|
|
22
|
+
"./styles": "./styles/index.scss",
|
|
23
|
+
"./styles/*": "./styles/*",
|
|
24
|
+
"./design/tokens": "./design/tokens/index.css",
|
|
25
|
+
"./design/tokens/*": "./design/tokens/*",
|
|
26
|
+
"./dist": "./dist/index.scss",
|
|
27
|
+
"./dist/tokens.css": "./dist/tokens.css",
|
|
28
|
+
"./dist/portal.scss": "./dist/portal.scss",
|
|
29
|
+
"./dist/*": "./dist/*",
|
|
30
|
+
"./standards/*": "./standards/*",
|
|
31
|
+
"./skills/*": "./skills/*",
|
|
32
|
+
"./templates/*": "./templates/*",
|
|
33
|
+
"./SKILL.md": "./SKILL.md"
|
|
34
|
+
},
|
|
35
|
+
"bin": {
|
|
36
|
+
"wl-ui": "bin/wl-ui.js",
|
|
37
|
+
"wl-scan": "scanner/index.mjs"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsup && npm run sync:tokens",
|
|
41
|
+
"prepare": "npm run build",
|
|
42
|
+
"sync:tokens": "node -e \"import('fs').then(fs=>fs.copyFileSync('design/tokens/base.css','dist/tokens.css'))\"",
|
|
43
|
+
"scan": "node scanner/index.mjs scan",
|
|
44
|
+
"check": "node scanner/index.mjs check",
|
|
45
|
+
"fix": "node scanner/index.mjs fix",
|
|
46
|
+
"all": "node scanner/index.mjs all",
|
|
47
|
+
"standards:init": "npx @robot-admin/git-standards init",
|
|
48
|
+
"cz": "git-cz",
|
|
49
|
+
"lint": "eslint ."
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"dist",
|
|
53
|
+
"es",
|
|
54
|
+
"scanner",
|
|
55
|
+
"standards",
|
|
56
|
+
"styles",
|
|
57
|
+
"design",
|
|
58
|
+
"skills",
|
|
59
|
+
"templates",
|
|
60
|
+
"bin",
|
|
61
|
+
"mcp",
|
|
62
|
+
"reference",
|
|
63
|
+
"examples",
|
|
64
|
+
"SKILL.md",
|
|
65
|
+
"README.md",
|
|
66
|
+
"CHANGELOG.md"
|
|
67
|
+
],
|
|
68
|
+
"sideEffects": [
|
|
69
|
+
"*.css",
|
|
70
|
+
"*.scss"
|
|
71
|
+
],
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"@commitlint/cli": "^20.5.3",
|
|
74
|
+
"@commitlint/config-conventional": "^20.5.3",
|
|
75
|
+
"@element-plus/icons-vue": "^2.3.0",
|
|
76
|
+
"@typescript-eslint/eslint-plugin": "^8.59.2",
|
|
77
|
+
"@typescript-eslint/parser": "^8.59.2",
|
|
78
|
+
"@vue/eslint-config-typescript": "^14.7.0",
|
|
79
|
+
"commitizen": "^4.3.1",
|
|
80
|
+
"cz-customizable": "^7.5.4",
|
|
81
|
+
"element-plus": "^2.7.0",
|
|
82
|
+
"eslint": "^10.3.0",
|
|
83
|
+
"eslint-plugin-vue": "^10.9.0",
|
|
84
|
+
"husky": "^9.1.7",
|
|
85
|
+
"lint-staged": "^16.4.0",
|
|
86
|
+
"tsup": "^8.3.0",
|
|
87
|
+
"typescript": "^5.4.0",
|
|
88
|
+
"vue": "^3.4.0"
|
|
89
|
+
},
|
|
90
|
+
"peerDependencies": {
|
|
91
|
+
"@element-plus/icons-vue": ">=2.0",
|
|
92
|
+
"element-plus": ">=2.2",
|
|
93
|
+
"vue": ">=3.2"
|
|
94
|
+
},
|
|
95
|
+
"peerDependenciesMeta": {
|
|
96
|
+
"@element-plus/icons-vue": {
|
|
97
|
+
"optional": true
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"engines": {
|
|
101
|
+
"node": ">=18"
|
|
102
|
+
},
|
|
103
|
+
"keywords": [
|
|
104
|
+
"vue",
|
|
105
|
+
"vue3",
|
|
106
|
+
"element-plus",
|
|
107
|
+
"ag-grid",
|
|
108
|
+
"design-tokens",
|
|
109
|
+
"ui-alignment",
|
|
110
|
+
"linter",
|
|
111
|
+
"copilot-skill"
|
|
112
|
+
],
|
|
113
|
+
"license": "UNLICENSED",
|
|
114
|
+
"publishConfig": {
|
|
115
|
+
"access": "public"
|
|
116
|
+
},
|
|
117
|
+
"config": {
|
|
118
|
+
"commitizen": {
|
|
119
|
+
"path": "node_modules/cz-customizable"
|
|
120
|
+
},
|
|
121
|
+
"cz-customizable": {
|
|
122
|
+
"config": ".cz-config.cjs"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
"lint-staged": {
|
|
126
|
+
"src/**/*.{js,jsx,ts,tsx,vue}": [
|
|
127
|
+
"eslint --fix --no-cache"
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
}
|