@agile-team/wl-skills-ui 1.6.6 → 1.6.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/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ All notable changes to **@agile-team/wl-skills-ui** will be documented in this f
4
4
 
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
+ ## [1.6.8] - 2026-05-11
8
+
9
+ ### Changed
10
+
11
+ - 修正架构边界文档中 L1/L2 的表述:L1 负责 Element Plus 原生组件族,L2 Project Vendors 是当前项目集群的必需覆盖层。
12
+ - README 和架构文档明确 `Base*`、`jh-*`、`C_*`、AG Grid、自研封装和 custom wrappers 都必须按统一 tokens 与 Element Plus 基础视觉对齐,不应被理解为可选补丁。
13
+
14
+ ## [1.6.7] - 2026-05-11
15
+
16
+ ### Added
17
+
18
+ - 新增 `standards/architecture/01-layer-boundaries.md`,明确 tokens、Element Plus、vendors、layouts、runtime、scanner、skills 的职责边界和扩展规则。
19
+ - 新增 `npm run docs:check`,校验旧命名、旧命令、README 版本文案、CHANGELOG 版本记录和编辑器配置完整性。
20
+
21
+ ### Changed
22
+
23
+ - CLI 编辑器安装配置改为读取 `skills/_meta/_compat/editors.json`,消除代码内第二份 `EDITOR_TARGETS` 路径映射。
24
+ - `editors.json` 补齐 `ext`、`singleFile`、`headerFile` 等安装行为字段,使 AI 编辑器配置成为单一事实源。
25
+
7
26
  ## [1.6.6] - 2026-05-11
8
27
 
9
28
  ### Changed
package/README.md CHANGED
@@ -193,10 +193,13 @@ yarn add @agile-team/wl-skills-ui
193
193
 
194
194
  ## 版本亮点
195
195
 
196
- 当前 v1.6.5 版本重点强化“统一规则源 + 多编辑器分发 + UI 细节精准修复”的闭环:
196
+ 当前 v1.6.8 版本重点强化“统一规则源 + 多编辑器分发 + 项目集群封装必覆盖 + UI 细节精准修复”的闭环:
197
197
 
198
198
  - `skills/**/*.md` 作为唯一规则源,`wl-ui init/update` 会按编辑器格式转换并覆盖写入目标 rules
199
+ - `skills/_meta/_compat/editors.json` 作为 AI 编辑器安装配置唯一来源,CLI 不再维护第二份编辑器路径映射
199
200
  - `wl-ui update --editor all --force` 可一次性刷新全部支持编辑器;未指定编辑器时会刷新 manifest 与项目中已存在的编辑器规则目录
201
+ - `standards/architecture/01-layer-boundaries.md` 固化 tokens、Element Plus、Project Vendors、layouts、runtime、scanner、skills 的扩展边界,明确 `Base*` / `jh-*` / `C_*` / AG Grid 是当前项目集群必覆盖层
202
+ - `npm run docs:check` 校验旧命名、旧命令、版本文案和编辑器配置,防止规则文档回退
200
203
  - 表格空状态改为对应表格区域内自适应居中,避免嵌套表格靠固定高度猜效果
201
204
  - 查询区/工具栏按钮补齐 token fallback,禁用按钮独立保留清晰禁用态
202
205
  - 表单控件圆角统一使用 `--wk-form-control-radius`,覆盖 input/select/date/textarea/upload 等控件家族
@@ -393,11 +396,11 @@ AI 按 _flows/legacy-skin-align.md 严格 6 phase 执行:
393
396
  ### Skin 模式优先级(团队约定)
394
397
 
395
398
  ```
396
- Base* > jh-* > C_*/c_* > custom wrappers
399
+ Base* > jh-* > C_*/c_* > AG Grid > custom wrappers
397
400
  (高) (低)
398
401
  ```
399
402
 
400
- 样式文件加载顺序在 `styles/vendors/index.scss` 中固化,确保高优先级覆盖低优先级。
403
+ 样式文件加载顺序在 `styles/vendors/index.scss` 中固化,确保高优先级覆盖低优先级。vendor 层不是可选补丁层,而是当前项目集群统一风格的必需适配层。
401
404
 
402
405
  ---
403
406
 
@@ -454,7 +457,7 @@ export const myRules = [
454
457
 
455
458
  ## Element Plus 组件族样式管控
456
459
 
457
- `wl-skills-ui` 的核心是样式绝对管控。加载 `styles`、`styles/presets/skin` 或 `styles/presets/element-only` 后,会统一覆盖首批 B 端高频 Element Plus 组件族:
460
+ `wl-skills-ui` 的核心是样式绝对管控。加载 `styles`、`styles/presets/skin` 或 `styles/presets/element-only` 后,会先统一覆盖首批 B 端高频 Element Plus 组件族;基于 Element Plus 的 `Base*`、`jh-*`、`C_*`、AG Grid 等封装/组合组件由 `styles/vendors` 继续承接,确保当前项目集群不管怎么封装组装,都收敛到同一套视觉体系:
458
461
 
459
462
  | 组件族 | 覆盖标签 | 典型场景 |
460
463
  | ------------ | ---------------------------------------------------------- | -------------------------------- |
package/bin/wl-ui.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * wl-ui — wl-skills-ui 统一 CLI
4
4
  *
5
5
  * 子命令:
6
- * wl-ui init [--project <path>] [--editor copilot|cursor|windsurf|kiro|trae] [--dry-run]
6
+ * wl-ui init [--project <path>] [--editor <editor|all>] [--dry-run]
7
7
  * 把 skills/ 写入目标项目的 AI 编辑器规则目录
8
8
  * wl-ui scan → 委托给 scanner/index.mjs
9
9
  * wl-ui check → 委托给 scanner/index.mjs
@@ -40,21 +40,7 @@ const MANIFEST_NAME = ".wl-skills-ui-manifest.json";
40
40
  // 常量
41
41
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
42
 
43
- /** 编辑器 安装目录映射 */
44
- const EDITOR_TARGETS = {
45
- "github-copilot": {
46
- dir: ".github/instructions/wk-skills",
47
- ext: ".instructions.md",
48
- },
49
- cursor: { dir: ".cursor/rules", ext: ".mdc" },
50
- windsurf: { dir: ".windsurf/rules", ext: ".md" },
51
- kiro: { dir: ".kiro/steering", ext: ".md" },
52
- trae: { dir: ".trae/rules", ext: ".md" },
53
- "claude-code": { dir: ".", ext: ".md", singleFile: "CLAUDE.md" },
54
- cline: { dir: ".", ext: ".md", singleFile: ".clinerules" },
55
- "agents-generic": { dir: ".", ext: ".md", singleFile: "AGENTS.md" },
56
- qoder: { dir: ".qoder/rules", ext: ".md" },
57
- };
43
+ const EDITOR_TARGETS = loadEditorTargets();
58
44
  const EDITOR_IDS = Object.keys(EDITOR_TARGETS);
59
45
 
60
46
  // ── 参数解析 ─────────────────────────────────────────────────────────────────
@@ -265,6 +251,33 @@ function detectEditor(projectRoot) {
265
251
  return "github-copilot";
266
252
  }
267
253
 
254
+ function loadEditorTargets() {
255
+ const configPath = join(
256
+ PKG_ROOT,
257
+ "skills",
258
+ "_meta",
259
+ "_compat",
260
+ "editors.json",
261
+ );
262
+ const config = JSON.parse(readFileSync(configPath, "utf8"));
263
+ return Object.fromEntries(
264
+ config.editors.map((editor) => [
265
+ editor.id,
266
+ {
267
+ dir: normalizeInstallDir(editor.installPath),
268
+ ext: editor.ext || ".md",
269
+ singleFile: editor.singleFile,
270
+ headerFile: editor.headerFile,
271
+ },
272
+ ]),
273
+ );
274
+ }
275
+
276
+ function normalizeInstallDir(installPath) {
277
+ const normalized = installPath.replace(/\\/g, "/").replace(/\/+$/, "");
278
+ return normalized === "." || normalized === "" ? "." : normalized;
279
+ }
280
+
268
281
  function detectInstalledEditors(projectRoot) {
269
282
  return EDITOR_IDS.filter((editor) => {
270
283
  const target = EDITOR_TARGETS[editor];
@@ -338,13 +351,14 @@ function collectSkills(skillsDir) {
338
351
 
339
352
  /** 读取编辑器 frontmatter 模板 */
340
353
  function getHeaderTemplate(editor) {
354
+ const target = EDITOR_TARGETS[editor];
355
+ const headerFile = target?.headerFile;
341
356
  const headerPath = join(
342
357
  PKG_ROOT,
343
358
  "skills",
344
359
  "_meta",
345
360
  "_compat",
346
- "headers",
347
- `${editorHeaderName(editor)}.txt`,
361
+ headerFile || join("headers", `${editor}.txt`),
348
362
  );
349
363
  if (existsSync(headerPath)) return readFileSync(headerPath, "utf8");
350
364
  return "";
@@ -543,22 +557,6 @@ function capitalize(s) {
543
557
  return s.charAt(0).toUpperCase() + s.slice(1);
544
558
  }
545
559
 
546
- function editorHeaderName(editor) {
547
- return (
548
- {
549
- cursor: "cursor-mdc",
550
- "github-copilot": "github-copilot",
551
- windsurf: "windsurf",
552
- kiro: "kiro",
553
- trae: "trae",
554
- "claude-code": "claude-code",
555
- cline: "cline",
556
- "agents-generic": "agents",
557
- qoder: "qoder",
558
- }[editor] || editor
559
- );
560
- }
561
-
562
560
  function installSupportFiles({ projectRoot, dryRun }) {
563
561
  const files = [
564
562
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/wl-skills-ui",
3
- "version": "1.6.6",
3
+ "version": "1.6.8",
4
4
  "description": "企业级 UI 风格对齐框架 — Vue + Element Plus 项目通用化妆/原生双模式(tokens / element / vendors / layouts / runtime / scanner / fixer / skills)",
5
5
  "type": "module",
6
6
  "main": "./es/index.js",
@@ -40,6 +40,7 @@
40
40
  "build": "tsup && npm run sync:tokens",
41
41
  "prepare": "npm run build",
42
42
  "sync:tokens": "node -e \"import('fs').then(fs=>fs.copyFileSync('design/tokens/base.css','dist/tokens.css'))\"",
43
+ "docs:check": "node scripts/check-docs.mjs",
43
44
  "scan": "node scanner/index.mjs scan",
44
45
  "check": "node scanner/index.mjs check",
45
46
  "fix": "node scanner/index.mjs fix",
@@ -58,6 +59,7 @@
58
59
  "skills",
59
60
  "templates",
60
61
  "bin",
62
+ "scripts",
61
63
  "mcp",
62
64
  "reference",
63
65
  "examples",
@@ -0,0 +1,83 @@
1
+ import { existsSync, readdirSync, readFileSync } from "node:fs";
2
+ import { dirname, join, relative } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+
5
+ const __filename = fileURLToPath(import.meta.url);
6
+ const __dirname = dirname(__filename);
7
+ const root = join(__dirname, "..");
8
+ const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
9
+ const readme = readFileSync(join(root, "README.md"), "utf8");
10
+ const changelog = readFileSync(join(root, "CHANGELOG.md"), "utf8");
11
+ const editorConfig = JSON.parse(
12
+ readFileSync(
13
+ join(root, "skills", "_meta", "_compat", "editors.json"),
14
+ "utf8",
15
+ ),
16
+ );
17
+
18
+ const errors = [];
19
+ const forbiddenPatterns = [
20
+ { pattern: /\bwk-ui\b/, message: "旧 CLI 名称 wk-ui" },
21
+ { pattern: /\bwk-skills-ui\b/, message: "旧包名 wk-skills-ui" },
22
+ {
23
+ pattern: /@agile-team\/wk-skills-ui/,
24
+ message: "旧 npm 包名 @agile-team/wk-skills-ui",
25
+ },
26
+ { pattern: /--editor auto/, message: "无效编辑器参数 --editor auto" },
27
+ { pattern: /当前 v1\.6\.2/, message: "过期 README 当前版本文案" },
28
+ ];
29
+
30
+ function walk(dir) {
31
+ const files = [];
32
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
33
+ if (["node_modules", ".git", "dist", "es"].includes(entry.name)) continue;
34
+ const full = join(dir, entry.name);
35
+ if (entry.isDirectory()) files.push(...walk(full));
36
+ if (entry.isFile() && entry.name.endsWith(".md")) files.push(full);
37
+ }
38
+ return files;
39
+ }
40
+
41
+ for (const file of walk(root)) {
42
+ const rel = relative(root, file).replace(/\\/g, "/");
43
+ const content = readFileSync(file, "utf8");
44
+ for (const { pattern, message } of forbiddenPatterns) {
45
+ if (rel === "CHANGELOG.md") continue;
46
+ if (pattern.test(content)) errors.push(`${rel}: ${message}`);
47
+ }
48
+ }
49
+
50
+ if (!readme.includes(`当前 v${pkg.version}`)) {
51
+ errors.push(
52
+ `README.md: 当前版本文案未同步 package.json version ${pkg.version}`,
53
+ );
54
+ }
55
+
56
+ if (!changelog.includes(`## [${pkg.version}]`)) {
57
+ errors.push(`CHANGELOG.md: 缺少 ${pkg.version} 版本记录`);
58
+ }
59
+
60
+ for (const editor of editorConfig.editors) {
61
+ if (!editor.id) errors.push("editors.json: editor 缺少 id");
62
+ if (!editor.installPath)
63
+ errors.push(`editors.json: ${editor.id} 缺少 installPath`);
64
+ if (!editor.ext) errors.push(`editors.json: ${editor.id} 缺少 ext`);
65
+ if (!editor.headerFile)
66
+ errors.push(`editors.json: ${editor.id} 缺少 headerFile`);
67
+ if (
68
+ !existsSync(join(root, "skills", "_meta", "_compat", editor.headerFile))
69
+ ) {
70
+ errors.push(
71
+ `editors.json: ${editor.id} headerFile 不存在:${editor.headerFile}`,
72
+ );
73
+ }
74
+ }
75
+
76
+ if (errors.length > 0) {
77
+ console.error(
78
+ "docs:check failed:\n" + errors.map((error) => `- ${error}`).join("\n"),
79
+ );
80
+ process.exit(1);
81
+ }
82
+
83
+ console.log("docs:check passed");
@@ -6,6 +6,7 @@
6
6
  "description": "VS Code GitHub Copilot Chat Agent 模式",
7
7
  "skillFormat": "SKILL.md with YAML frontmatter (applyTo: glob)",
8
8
  "installPath": ".github/instructions/wk-skills/",
9
+ "ext": ".instructions.md",
9
10
  "headerFile": "headers/github-copilot.txt"
10
11
  },
11
12
  {
@@ -14,6 +15,7 @@
14
15
  "description": "Cursor AI 编辑器 .mdc 规则文件",
15
16
  "skillFormat": ".mdc files with YAML frontmatter (globs:)",
16
17
  "installPath": ".cursor/rules/",
18
+ "ext": ".mdc",
17
19
  "headerFile": "headers/cursor-mdc.txt"
18
20
  },
19
21
  {
@@ -22,6 +24,7 @@
22
24
  "description": "Windsurf AI 编辑器规则文件",
23
25
  "skillFormat": "Plain markdown, no frontmatter",
24
26
  "installPath": ".windsurf/rules/",
27
+ "ext": ".md",
25
28
  "headerFile": "headers/windsurf.txt"
26
29
  },
27
30
  {
@@ -30,6 +33,7 @@
30
33
  "description": "Kiro AI 编辑器 steering 文档",
31
34
  "skillFormat": "Markdown with YAML frontmatter (inclusion: manual)",
32
35
  "installPath": ".kiro/steering/",
36
+ "ext": ".md",
33
37
  "headerFile": "headers/kiro.txt"
34
38
  },
35
39
  {
@@ -38,6 +42,7 @@
38
42
  "description": "Trae AI 编辑器规则文件",
39
43
  "skillFormat": "Markdown with description frontmatter",
40
44
  "installPath": ".trae/rules/",
45
+ "ext": ".md",
41
46
  "headerFile": "headers/trae.txt"
42
47
  },
43
48
  {
@@ -46,6 +51,8 @@
46
51
  "description": "Claude Code 项目规则文件",
47
52
  "skillFormat": "Plain markdown",
48
53
  "installPath": "./",
54
+ "ext": ".md",
55
+ "singleFile": "CLAUDE.md",
49
56
  "headerFile": "headers/claude-code.txt"
50
57
  },
51
58
  {
@@ -54,6 +61,8 @@
54
61
  "description": "Cline 规则文件",
55
62
  "skillFormat": "Plain markdown",
56
63
  "installPath": "./",
64
+ "ext": ".md",
65
+ "singleFile": ".clinerules",
57
66
  "headerFile": "headers/cline.txt"
58
67
  },
59
68
  {
@@ -62,6 +71,8 @@
62
71
  "description": "AGENTS.md 通用代理协议",
63
72
  "skillFormat": "Plain markdown",
64
73
  "installPath": "./",
74
+ "ext": ".md",
75
+ "singleFile": "AGENTS.md",
65
76
  "headerFile": "headers/agents.txt"
66
77
  },
67
78
  {
@@ -70,6 +81,7 @@
70
81
  "description": "Qoder IDE 规则文件",
71
82
  "skillFormat": "Markdown with description frontmatter",
72
83
  "installPath": ".qoder/rules/",
84
+ "ext": ".md",
73
85
  "headerFile": "headers/qoder.txt"
74
86
  }
75
87
  ]
@@ -0,0 +1,126 @@
1
+ # wl-skills-ui 架构分层与扩展边界
2
+
3
+ ## 核心原则
4
+
5
+ `wl-skills-ui` 当前服务于既定项目集群,因此默认 tokens、配色、圆角、密度、组件视觉和工程接入方式是固化体系;但这些固化内容必须保持为可替换的独立变量层,不能散落到组件覆盖、vendor 化妆或 AI rules 中形成补丁污染。
6
+
7
+ 任何新增能力都必须遵守:
8
+
9
+ - 单一事实源:同一类配置只能有一个权威来源。
10
+ - 分层隔离:tokens、Element Plus 原子覆盖、项目集群封装覆盖、layouts、runtime、scanner、skills 各自负责自己的边界。
11
+ - 向下依赖:上层可以使用下层 token 和规范,下层不能反向依赖上层实现。
12
+ - 覆盖有序:后写入和高优先级覆盖必须有明确目录和加载顺序,不能靠零散 `!important` 补丁堆叠。
13
+ - 项目集群优先:当前风格先服务当前项目集群;未来多项目集群主题替换应通过 theme/tokens/preset 入口扩展,而不是修改组件规则本身。
14
+
15
+ ## 分层边界
16
+
17
+ | 层级 | 目录 | 职责 | 不允许做的事 |
18
+ | --- | --- | --- | --- |
19
+ | L0 Design Tokens | `design/tokens`、`styles/tokens` | 定义颜色、圆角、间距、字号、阴影等基础变量 | 不写具体组件选择器,不绑定业务组件名 |
20
+ | L1 Element Plus | `styles/element`、`skills/element` | 统一 Element Plus 原生组件视觉,作为全部封装层的基础视觉规则 | 不把 `Base*`、`jh-*`、`C_*`、AG Grid 的私有选择器混入原子层 |
21
+ | L2 Project Vendors | `styles/vendors`、`skills/vendors` | 必须覆盖当前项目集群里的 `Base*`、`jh-*`、`C_*`、自研封装、AG Grid 等封装/组合组件,使其继承同一套风格 | 不重新定义品牌色体系,不脱离 L0/L1 另起一套视觉规则,不覆盖 layout 骨架语义 |
22
+ | L3 Layouts | `styles/layouts`、`skills/layouts`、`templates` | 约束列表页、树表页、表单弹窗等页面骨架 | 不改 token,不写 vendor 私有修复 |
23
+ | L4 Runtime | `runtime`、`reference` | 提供 `defineColumns`、`renderOps`、preset 等业务渲染能力 | 不直接承担老项目 skin 化妆职责 |
24
+ | Automation | `scanner`、`mcp` | 扫描、检查、dry-run 修复和 AI 工具入口 | 不绕过 skills/standards 私自定义新规则语义 |
25
+ | AI Rules | `skills`、`standards` | AI 可读规范、流程和修复策略 | 不和代码实现产生第二套事实源 |
26
+
27
+ ## Tokens 与主题替换边界
28
+
29
+ 当前默认主题位于:
30
+
31
+ ```text
32
+ design/tokens/base.css
33
+ styles/tokens/index.scss
34
+ ```
35
+
36
+ 这些文件是当前项目集群的默认主题源。组件样式只能引用 token,不应硬编码品牌色、表单圆角、按钮颜色、空状态颜色等可主题化变量。
37
+
38
+ 推荐写法:
39
+
40
+ ```scss
41
+ color: var(--el-text-color-secondary, #909399);
42
+ border-radius: var(--wk-form-control-radius, 6px);
43
+ ```
44
+
45
+ 不推荐写法:
46
+
47
+ ```scss
48
+ color: #909399;
49
+ border-radius: 6px;
50
+ ```
51
+
52
+ 未来如果不同项目集群需要切换主题,应优先增加新的 token/preset 入口,例如:
53
+
54
+ ```text
55
+ design/tokens/<cluster>.css
56
+ styles/presets/<cluster>.scss
57
+ ```
58
+
59
+ 而不是在 `styles/element` 或 `styles/vendors` 中追加按项目名区分的补丁选择器。
60
+
61
+ ## Element Plus 覆盖边界
62
+
63
+ Element Plus 原生组件覆盖必须保持组件族独立:
64
+
65
+ ```text
66
+ styles/element/_button.scss
67
+ styles/element/_form.scss
68
+ styles/element/_table.scss
69
+ styles/element/_feedback.scss
70
+ styles/element/_upload.scss
71
+ ```
72
+
73
+ 每个文件只处理对应组件族或强相关子组件。跨组件一致性通过 token 解决,例如表单圆角统一使用 `--wk-form-control-radius`,不能在 input、select、upload 中分别写不同硬编码。
74
+
75
+ L1 的“不处理封装私有结构”不是“不覆盖封装组件”,而是要求封装组件进入 L2,由 L2 按当前项目集群真实封装形态做统一风格适配。
76
+
77
+ ## Project Vendors 覆盖边界
78
+
79
+ Project Vendors 层是当前项目集群的必需覆盖层,不是可选补丁层。它用于承接所有基于 Element Plus 或与 Element Plus 共同组成页面的封装/组合组件,包括:
80
+
81
+ ```text
82
+ Base* > jh-* > C_*/c_* > AG Grid > custom wrappers
83
+ ```
84
+
85
+ 这些组件虽然不是 Element Plus 原生选择器,但在当前项目集群中同样属于统一 UI 风格体系的一部分,必须使用 L0 tokens 和 L1 组件视觉原则进行对齐。
86
+
87
+ 新增 vendor 覆盖时应同时补齐:
88
+
89
+ 1. `styles/vendors/_xxx.scss`
90
+ 2. `styles/vendors/index.scss` 加载顺序
91
+ 3. `skills/vendors/xxx/SKILL.md`
92
+ 4. `skills/_meta/_detection.md`
93
+ 5. 如需自动检查,补 `scanner/rules/*`
94
+
95
+ 不能只在某个页面局部追加样式补丁。
96
+
97
+ ## AI Rules 单一源原则
98
+
99
+ AI 编辑器规则由 `skills/**/*.md` 统一生成。不同编辑器只允许通过 `skills/_meta/_compat/editors.json` 和 `headers/*.txt` 做格式转换。
100
+
101
+ 禁止在以下目录手写与 `skills` 不一致的规则语义:
102
+
103
+ ```text
104
+ .github/instructions/wk-skills
105
+ .cursor/rules
106
+ .windsurf/rules
107
+ .kiro/steering
108
+ .trae/rules
109
+ .qoder/rules
110
+ CLAUDE.md
111
+ .clinerules
112
+ AGENTS.md
113
+ ```
114
+
115
+ 这些目录是安装产物,应由 `wl-ui init/update` 覆盖生成。
116
+
117
+ ## 新增能力检查清单
118
+
119
+ 新增任何 UI 规则或样式覆盖前,先确认:
120
+
121
+ - 是否能通过 token 解决,而不是新增组件补丁。
122
+ - 是否属于 Element Plus 原子层,还是 vendor 封装层。
123
+ - 是否需要同步 Skill、Standard、Scanner 和 Template。
124
+ - 是否会影响 skin 模式老项目布局。
125
+ - 是否会污染未来主题替换能力。
126
+ - 是否可以通过 `wl-ui update --editor all --force` 分发给全部 AI 编辑器。