@teamix-evo/skills 0.2.0 → 0.4.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.
Files changed (56) hide show
  1. package/README.md +18 -8
  2. package/_template/SKILL.md.hbs +14 -1
  3. package/manifest.json +79 -6
  4. package/package.json +7 -3
  5. package/src/teamix-evo-code-opentrek/SKILL.md +92 -0
  6. package/src/teamix-evo-code-opentrek/api-layering.md +225 -0
  7. package/src/teamix-evo-code-opentrek/checklist.md +173 -0
  8. package/src/teamix-evo-code-opentrek/error-and-loading.md +269 -0
  9. package/src/teamix-evo-code-opentrek/file-structure.md +273 -0
  10. package/src/teamix-evo-code-opentrek/forms-and-validation.md +220 -0
  11. package/src/teamix-evo-code-opentrek/reuse-first.md +130 -0
  12. package/src/teamix-evo-code-opentrek/routing-and-codesplit.md +298 -0
  13. package/src/teamix-evo-code-opentrek/testing.md +313 -0
  14. package/src/teamix-evo-code-uni-manager/SKILL.md +95 -0
  15. package/src/teamix-evo-code-uni-manager/api-layering.md +370 -0
  16. package/src/teamix-evo-code-uni-manager/checklist.md +193 -0
  17. package/src/teamix-evo-code-uni-manager/error-and-loading.md +389 -0
  18. package/src/teamix-evo-code-uni-manager/file-structure.md +339 -0
  19. package/src/teamix-evo-code-uni-manager/forms-and-validation.md +459 -0
  20. package/src/teamix-evo-code-uni-manager/reuse-first.md +188 -0
  21. package/src/teamix-evo-code-uni-manager/routing-and-codesplit.md +450 -0
  22. package/src/teamix-evo-code-uni-manager/testing.md +396 -0
  23. package/src/teamix-evo-design-opentrek/SKILL.md +71 -0
  24. package/src/teamix-evo-design-opentrek/boundaries.md +513 -0
  25. package/src/teamix-evo-design-opentrek/brand.md +154 -0
  26. package/src/teamix-evo-design-opentrek/checklist.md +83 -0
  27. package/src/teamix-evo-design-opentrek/components.md +245 -0
  28. package/src/teamix-evo-design-opentrek/flows.md +51 -0
  29. package/src/teamix-evo-design-opentrek/foundations.md +271 -0
  30. package/src/teamix-evo-design-opentrek/generation-flow.md +185 -0
  31. package/src/teamix-evo-design-opentrek/patterns/dashboard.md +31 -0
  32. package/src/teamix-evo-design-opentrek/patterns/detail-page.md +202 -0
  33. package/src/teamix-evo-design-opentrek/patterns/form-page.md +289 -0
  34. package/src/teamix-evo-design-opentrek/patterns/list-page.md +334 -0
  35. package/src/teamix-evo-design-opentrek/patterns/page-types.md +154 -0
  36. package/src/teamix-evo-design-opentrek/philosophy.md +96 -0
  37. package/src/teamix-evo-design-opentrek/rules/README.md +39 -0
  38. package/src/teamix-evo-design-opentrek/rules/boundaries.rules.json +391 -0
  39. package/src/teamix-evo-design-uni-manager/SKILL.md +73 -0
  40. package/src/teamix-evo-design-uni-manager/boundaries.md +564 -0
  41. package/src/teamix-evo-design-uni-manager/brand.md +202 -0
  42. package/src/teamix-evo-design-uni-manager/checklist.md +115 -0
  43. package/src/teamix-evo-design-uni-manager/components.md +254 -0
  44. package/src/teamix-evo-design-uni-manager/flows.md +63 -0
  45. package/src/teamix-evo-design-uni-manager/foundations.md +258 -0
  46. package/src/teamix-evo-design-uni-manager/generation-flow.md +194 -0
  47. package/src/teamix-evo-design-uni-manager/patterns/dashboard.md +95 -0
  48. package/src/teamix-evo-design-uni-manager/patterns/detail-page.md +224 -0
  49. package/src/teamix-evo-design-uni-manager/patterns/form-page.md +329 -0
  50. package/src/teamix-evo-design-uni-manager/patterns/list-page.md +356 -0
  51. package/src/teamix-evo-design-uni-manager/patterns/page-types.md +165 -0
  52. package/src/teamix-evo-design-uni-manager/philosophy.md +106 -0
  53. package/src/teamix-evo-design-uni-manager/rules/README.md +49 -0
  54. package/src/teamix-evo-design-uni-manager/rules/boundaries.rules.json +418 -0
  55. package/src/teamix-evo-manage/SKILL.md +281 -0
  56. package/skills/teamix-evo-manage/SKILL.md +0 -138
@@ -0,0 +1,154 @@
1
+ # Page Types — 5 种标准页面类型
2
+
3
+ > AI 生成页面前**必须先识别页面类型**,再选择对应模式。本文档是 generation-flow.md Step 2 的核心输入。
4
+
5
+ ---
6
+
7
+ ## 1. 类型概览
8
+
9
+ | 类型 | 用途 | 核心组件 | 子文件 |
10
+ | ---------------- | ------------------------------ | ----------------------------------------------- | ------------------------- |
11
+ | **ListPage** | 资源集合的查询、筛选、批量操作 | DataTable / CardGrid + SearchCombo + Pagination | `list-page.md` |
12
+ | **DetailPage** | 单个资源的完整信息展示 | Tabs + DescriptionList + ActionToolbar | `detail-page.md` |
13
+ | **FormPage** | 资源的创建 / 编辑 | Form(FieldGroup + Field) + SubmitBar | `form-page.md` |
14
+ | **Dashboard** | 数据概览与监控 | StatCard + Chart + Timeline | `dashboard.md` |
15
+ | **Dialog/Sheet** | 二次确认、快速操作 | AlertDialog / Dialog / Sheet | (见 components.md §3.1) |
16
+
17
+ ---
18
+
19
+ ## 2. 识别决策树
20
+
21
+ ```text
22
+ 用户描述包含什么?
23
+ ├─ "列表"/"表格"/"查询"/"检索"/"卡片管理" → ListPage
24
+ ├─ "详情"/"查看"/"信息"/"概览" → DetailPage
25
+ ├─ "新建"/"创建"/"编辑"/"修改"/"复制" → FormPage
26
+ ├─ "仪表盘"/"概览大屏"/"监控"/"统计" → Dashboard
27
+ ├─ "确认"/"删除二次确认"/"快速重命名" → Dialog
28
+ └─ 不确定 → 优先 ListPage(最通用入口)
29
+ ```
30
+
31
+ **优先级裁决**:
32
+
33
+ - 出现"批量操作" → ListPage(即使页面看起来像 Dashboard)
34
+ - 出现"步骤"/"分步" → FormPage(Wizard 变体)
35
+ - 出现"对比" → DetailPage(对比型)
36
+
37
+ ---
38
+
39
+ ## 3. 页面级别 (L1 / L2 / L0)
40
+
41
+ | 级别 | 适用类型 | PageHeader 模式 | Sidebar |
42
+ | ------ | -------------------- | ------------------------- | -------- |
43
+ | **L0** | Dialog / Sheet 内部 | 无 PageHeader | 无 |
44
+ | **L1** | ListPage、Dashboard | title 模式(仅标题) | 自动继承 |
45
+ | **L2** | DetailPage、FormPage | breadcrumb 模式(含路径) | 自动继承 |
46
+
47
+ **框架自动继承**:L1 / L2 页面**不需要在 skill 中显式声明** Sidebar 与 PageHeader — 由 page-frame 统一管理。
48
+
49
+ ---
50
+
51
+ ## 4. Zone Map(区域命名约定)
52
+
53
+ | Zone | 位置 | 用途 |
54
+ | --------------- | ------------- | ------------------------------------------------ |
55
+ | **header** | 顶部 | PageHeader(标题或面包屑 + 主操作) |
56
+ | **toolbar** | header 下 | ActionToolbar(搜索 + 筛选 + 视图切换) |
57
+ | **main** | 中部主体 | 主要内容区(DataTable / Form / DescriptionList) |
58
+ | **bulk-action** | main 浮于底部 | BulkActionBar(仅 ListPage 选中行时) |
59
+ | **footer** | 底部固定 | Pagination 或 SubmitBar |
60
+ | **sidebar** | 左侧 | 全局导航(框架级,自动继承) |
61
+ | **aside** | 右侧 | 侧边详情 / AI 面板(按 variant 启用) |
62
+
63
+ **默认壳层结构**:`Sidebar(左) + Header(顶) + Main(中)` — 三栏布局是基线。
64
+
65
+ ---
66
+
67
+ ## 5. Dashboard
68
+
69
+ > **完整规范见 [`dashboard.md`](./dashboard.md)** — 标准结构 + 设计要点(关键指标字号、StatCard 数量、chart-* 色彩消费顺序)。
70
+
71
+ ---
72
+
73
+ ## 6. 页间流转
74
+
75
+ > 单页内部规则在 §1-§5,本节是**跨页流转**视角。完整的"四条核心用户旅程"(A 资源查找 / B 创建 / C 异常 / D 批量)见 [`flows.md`](../flows.md)。
76
+
77
+ ### 6.1 后台主流转图
78
+
79
+ ```text
80
+ ┌─────────────────┐
81
+ │ 全局导航 / 首页 │
82
+ └────────┬────────┘
83
+ │ 选择模块
84
+
85
+ ┌──────────┐ 创建 ┌──────────┐ 查看 ┌────────────┐
86
+ │ FormPage │◄────│ ListPage │──────►│ DetailPage │
87
+ └────┬─────┘ └─────┬────┘ └─────┬──────┘
88
+ │ 成功 │ │
89
+ └────────────────►│◄──────────────────┘
90
+ │ 编辑 返回
91
+
92
+ ┌──────────────┐
93
+ │ FormPage │
94
+ └──────────────┘
95
+
96
+ Dashboard ──下钻──► ListPage(预筛选)
97
+ ```
98
+
99
+ > AI 副驾驶(命令面板 / 对话主面板 / 告警诊断 / 操作编排 / 知识问答 / 拓扑感知)属于**变体专属**流转,不在中性基线内。
100
+
101
+ ### 6.2 流转设计规则
102
+
103
+ 1. **导航深度 ≤ 4 层** — 超过即是信息架构问题
104
+ 2. **每层都有返回路径** — 面包屑 / 返回按钮 / Esc 快捷键
105
+ 3. **主导航始终可见** — 仅"全屏编辑 / 大屏展示"模式可隐藏
106
+ 4. **状态保持** — 列表筛选条件、表单未提交内容必须保留
107
+ 5. **快捷路径** — 高频操作建议提供 `Cmd+K` 入口
108
+ 6. **不创建死胡同** — 任何成功 / 失败页面都必须有"下一步"按钮
109
+
110
+ ### 6.3 资源生命周期
111
+
112
+ | 阶段 | 发现 | 创建 | 配置 | 监控 | 变更 | 删除 |
113
+ | ---- | -------- | -------- | ---------- | --------- | -------- | -------- |
114
+ | 页面 | ListPage | FormPage | DetailPage | Dashboard | FormPage | Dialog |
115
+ | 动作 | 搜索定位 | 填写表单 | 查看明细 | 处置异常 | 编辑提交 | 二次确认 |
116
+
117
+ > "资源" 泛指业务对象(订单 / 用户 / 商品 / 任务 / 工单 / 文档…)。
118
+
119
+ ### 6.4 CRUD 流转速查
120
+
121
+ | 意图 | 关键词 | 目标页 | 完成后 |
122
+ | -------- | -------------- | ------------------------- | -------------- |
123
+ | 查看列表 | 列表/查询/检索 | ListPage | — |
124
+ | 查看详情 | 详情/查看/信息 | DetailPage | 可返回列表 |
125
+ | 新建 | 新建/创建/新增 | FormPage(新建) | 保存后返回列表 |
126
+ | 编辑 | 编辑/修改 | FormPage(编辑)或 Drawer | 保存后返回原页 |
127
+ | 删除 | 删除/移除 | Dialog(输入确认) | 确认后刷新列表 |
128
+ | 复制 | 复制/克隆 | FormPage(复制新建) | 保存后返回列表 |
129
+
130
+ ---
131
+
132
+ ## 7. 通用结构铁律(所有页面类型共享)
133
+
134
+ 1. **PageContainer → ContentWrapper → Card(白卡容器) → 业务组件**
135
+ - 业务组件**必须**经白卡容器包裹,禁止直接放在 ContentWrapper 内
136
+ 2. **Card(白卡容器) 不可嵌套** — 白卡是单例
137
+ 3. **页头不可重复** — 子页面禁止自建 header,PageHeader 由框架管控
138
+ 4. **不在内容区直接放 Form 整体** — 必须用 FieldGroup + Field(详见 boundaries.md C7)
139
+ 5. **不在 ListPage / DetailPage 内嵌 Chart 整体** — 图表归属 Dashboard
140
+ 6. **不在 FormPage / DetailPage 内嵌 DataTable 整体** — 关联数据通过 Tabs / Drawer 组织
141
+
142
+ ---
143
+
144
+ ## 8. 类型选择自检
145
+
146
+ 完成识别后必须能回答:
147
+
148
+ - [ ] 这是 L0 / L1 / L2 哪一级?
149
+ - [ ] PageHeader 用 title 还是 breadcrumb 模式?
150
+ - [ ] Main 区核心组件是什么?(DataTable / DescriptionList / FieldGroup)
151
+ - [ ] 是否需要 toolbar / bulk-action / footer Zone?
152
+ - [ ] 错位风险:是否在不该出现的页面类型里出现了 Form / DataTable / Chart?
153
+
154
+ 类型识别错误 = 后续所有约束都错位。**错则回到 Step 1 重判。**
@@ -0,0 +1,96 @@
1
+ # 设计哲学 · OpenTrek
2
+
3
+ > 回答**"为什么这么做"**。具体规则见 [boundaries.md](./boundaries.md) / [foundations.md](./foundations.md)。
4
+
5
+ ---
6
+
7
+ ## 1. 我们是谁
8
+
9
+ OpenTrek 是面向**云资源管理 / 企业级控制台**的设计语言。用户是工程师、运维、IT 管理员 —— 每天数百次重复操作、对失误代价敏感、对花哨视觉无感。
10
+
11
+ **核心主张**:让复杂系统变得可管理,而非让简单事物变得复杂。
12
+
13
+ **三条不可让步的底层信念**:
14
+
15
+ 1. 设计是降低认知负荷的手段,不是展示创意的舞台
16
+ 2. 每一个视觉元素必须承载功能价值或信息语义
17
+ 3. 一致性优先于创新性 — "惊喜"在严肃工具中是反模式
18
+
19
+ ---
20
+
21
+ ## 2. 四大设计原则(按优先级降序)
22
+
23
+ 冲突时裁决顺序:**Safety > Predictability > Clarity > Efficiency**。
24
+
25
+ ### P1 · Safety — 安全防护(最高优先级)
26
+
27
+ > 关键资源操作必须有防护栏。
28
+
29
+ - 危险操作(删除 / 停止)二次确认 → `AlertDialog variant="destructive"`
30
+ - 表单未保存离开提示 → `beforeunload`
31
+ - 无权限操作隐藏或禁用 → `usePermission`
32
+ - 尽可能提供撤销 / 回收站
33
+
34
+ **评判**:一次误操作的最大损失是否被框定在可恢复的范围内?
35
+
36
+ ### P2 · Predictability — 可预期性
37
+
38
+ > 用户不应该猜测"点击这个会发生什么"。
39
+
40
+ - 同类操作使用同样的交互模式(页面类型规则统一)
41
+ - 同类型操作出现在固定位置(Zone Map)
42
+ - 操作后 ≤ 200ms 给出反馈
43
+ - 页面间跳转关系可预知(面包屑 + 返回按钮 + URL 语义)
44
+
45
+ **评判**:用户在 A 页面学会的操作,能否无障碍迁移到 B 页面?
46
+
47
+ ### P3 · Clarity — 清晰优先
48
+
49
+ > 界面的首要职责是传递信息,不是展示装饰。
50
+
51
+ - 文字对比度 ≥ 4.5:1(WCAG AA) — 走 `text-foreground` on `bg-background`
52
+ - 状态语义 = **颜色 + 图标 + 文字**三重传达 — `Badge variant` + Icon + Label
53
+ - 主操作入口在视觉焦点区域(左上 / 右上) — `ActionToolbar` 布局规则
54
+ - 3 级信息层级:标题 / 正文 / 辅助
55
+
56
+ **评判**:新用户是否能在 3 秒内理解当前页面的核心目的?
57
+
58
+ ### P4 · Efficiency — 效率至上
59
+
60
+ > 运维人员每天面对数百次重复操作,减少一次点击就是减少一次出错机会。
61
+
62
+ - 高频操作 ≤ 2 次点击可达
63
+ - 支持多选 + 批量操作 → `BulkActionBar` + Checkbox 列
64
+ - 列表页必须提供搜索入口 → `SearchCombo` / `QueryFilter`
65
+ - 筛选条件持久化(URL Params + localStorage)
66
+
67
+ **评判**:完成核心任务的步骤数是否为同类产品最少?
68
+
69
+ ---
70
+
71
+ ## 3. 原则冲突示例
72
+
73
+ | 场景 | 候选 | 选 | 理由 |
74
+ | ------------------------ | ----------------------------------------------------- | -- | --------------------------------- |
75
+ | 删除按钮要不要二次确认? | A. 直接删除(效率)<br>B. AlertDialog 确认(安全) | B | Safety > Efficiency |
76
+ | 创建按钮浮动还是固定? | A. 跟随滚动浮动(醒目)<br>B. 固定右下角(一致) | B | Predictability > Clarity |
77
+ | 状态用什么表达? | A. 仅颜色(简洁)<br>B. 颜色 + 图标 + 文字 | B | Clarity > Efficiency(视觉简洁) |
78
+
79
+ ---
80
+
81
+ ## 4. 决策框架(套用顺序)
82
+
83
+ 1. Safety > Predictability > Clarity > Efficiency
84
+ 2. 业务正确性 > 视觉美观
85
+ 3. 一致性 > 创新性
86
+ 4. 可访问性 > 视觉丰富度
87
+ 5. 性能 > 动效丰富度
88
+
89
+ ---
90
+
91
+ 文件分工:
92
+
93
+ - **philosophy.md** — 为什么
94
+ - **boundaries.md** — 不能做什么
95
+ - **foundations.md** — 用什么 token
96
+ - **patterns/** — 具体页面怎么搭
@@ -0,0 +1,39 @@
1
+ # rules/ — boundaries.md ↔ eslint-config 元数据桥
2
+
3
+ 本目录是 **结构化元数据**,不是规则实现。它把:
4
+
5
+ 1. `boundaries.md` 中的 38 条人类可读硬约束(F/FF/S/C/I 五组)
6
+ 2. `packages/eslint-config/src/rules/` 中的 9 条已实现 lint 规则
7
+ 3. AI 在生成代码时可读的 JSON 索引
8
+
9
+ 用一张表对齐起来,防止三者飘移。
10
+
11
+ ## boundaries.rules.json
12
+
13
+ 每条规则包含:
14
+
15
+ | 字段 | 说明 |
16
+ | ---------------- | -------------------------------------------------------------- |
17
+ | `id` | 在 boundaries.md 中的编号(F1-F10 / FF1-FF4 / S1-S8 / C1-C12 / I1-I4) |
18
+ | `group` | `forbidden` / `form` / `style` / `component` / `icon` |
19
+ | `rule` | 一句话规则陈述(与 boundaries.md 章节标题保持一致) |
20
+ | `severity` | `ERROR` 必须修复 / `WARN` 建议修复 |
21
+ | `scope` | `global` 或具体组件名(如 `Dialog`、`Button`) |
22
+ | `lintRule` | 对应的 eslint 规则名(`teamix-evo/<name>`);`null` 表示无 lint 覆盖,靠人工评审 |
23
+ | `boundaryAnchor` | 指向 boundaries.md 章节锚点;validate-skills 会校验存在性 |
24
+ | `status` | `active` / `deprecated` |
25
+
26
+ ## 双向校验(由 `pnpm validate` 触发)
27
+
28
+ `scripts/validate-skills.ts` 在校验 manifest 之后会额外检查:
29
+
30
+ 1. **JSON schema 合法** — 每条 rule 满足上表必填字段
31
+ 2. **boundaryAnchor 存在性** — 每条 rule 的 `boundaryAnchor` 必须能在 `boundaries.md` 中 grep 到对应的章节
32
+ 3. **eslint 双向对齐** — `packages/eslint-config/src/rules/` 中每条已实现的 rule 必须在本 JSON 中有 `lintRule: "teamix-evo/<name>"` 的条目;反过来,JSON 中每条 `lintRule != null` 的条目必须能在 eslint-config 中找到对应文件
33
+
34
+ ## 新增 boundary 规则的工序
35
+
36
+ 1. 在 `boundaries.md` 中加章节(`[ERROR]` / `[WARN]` 前缀 + 编号)
37
+ 2. 在 `boundaries.rules.json` 加对应条目
38
+ 3. 如需 lint 自动化:在 `packages/eslint-config/src/rules/` 加 ts 实现;`lintRule` 填规则名
39
+ 4. 跑 `pnpm --filter @teamix-evo/skills validate` 通过
@@ -0,0 +1,391 @@
1
+ {
2
+ "$schema": "./rules.schema.json",
3
+ "version": "1.0.0",
4
+ "source": "boundaries.md",
5
+ "rules": [
6
+ {
7
+ "id": "F1",
8
+ "group": "forbidden",
9
+ "rule": "禁止硬编码色值",
10
+ "severity": "ERROR",
11
+ "scope": "global",
12
+ "lintRule": "teamix-evo/no-color-literal",
13
+ "boundaryAnchor": "boundaries.md#error-f1--禁止硬编码色值",
14
+ "status": "active"
15
+ },
16
+ {
17
+ "id": "F2",
18
+ "group": "forbidden",
19
+ "rule": "禁止硬编码尺寸",
20
+ "severity": "ERROR",
21
+ "scope": "global",
22
+ "lintRule": "teamix-evo/no-arbitrary-tw-value",
23
+ "boundaryAnchor": "boundaries.md#error-f2--禁止硬编码尺寸",
24
+ "status": "active"
25
+ },
26
+ {
27
+ "id": "F3",
28
+ "group": "forbidden",
29
+ "rule": "禁止按组件新增重复语义变量",
30
+ "severity": "ERROR",
31
+ "scope": "global",
32
+ "lintRule": null,
33
+ "boundaryAnchor": "boundaries.md#error-f3--禁止按组件新增重复语义变量",
34
+ "status": "active"
35
+ },
36
+ {
37
+ "id": "F4",
38
+ "group": "forbidden",
39
+ "rule": "禁止页头添加底色或下边框",
40
+ "severity": "ERROR",
41
+ "scope": "PageHeader",
42
+ "lintRule": null,
43
+ "boundaryAnchor": "boundaries.md#error-f4--禁止页头添加底色或下边框--scope-pageheader",
44
+ "status": "active"
45
+ },
46
+ {
47
+ "id": "F5",
48
+ "group": "forbidden",
49
+ "rule": "outline 按钮禁止使用 border-input",
50
+ "severity": "ERROR",
51
+ "scope": "Button",
52
+ "lintRule": null,
53
+ "boundaryAnchor": "boundaries.md#error-f5--outline-按钮禁止使用-border-input--scope-button",
54
+ "status": "active"
55
+ },
56
+ {
57
+ "id": "F6",
58
+ "group": "forbidden",
59
+ "rule": "禁止直接写 font-size: 12px",
60
+ "severity": "ERROR",
61
+ "scope": "global",
62
+ "lintRule": "teamix-evo/no-arbitrary-tw-value",
63
+ "boundaryAnchor": "boundaries.md#error-f6--禁止直接写-font-size-12px",
64
+ "status": "active"
65
+ },
66
+ {
67
+ "id": "F7",
68
+ "group": "forbidden",
69
+ "rule": "语义间距必须走 CSS 变量",
70
+ "severity": "ERROR",
71
+ "scope": "global",
72
+ "lintRule": "teamix-evo/no-arbitrary-tw-value",
73
+ "boundaryAnchor": "boundaries.md#error-f7--语义间距必须走-css-变量",
74
+ "status": "active"
75
+ },
76
+ {
77
+ "id": "F8",
78
+ "group": "forbidden",
79
+ "rule": "禁止在 DialogTitle 中加图标",
80
+ "severity": "ERROR",
81
+ "scope": "Dialog",
82
+ "lintRule": null,
83
+ "boundaryAnchor": "boundaries.md#error-f8--禁止在-dialogtitle-中加图标--scope-dialog",
84
+ "status": "active"
85
+ },
86
+ {
87
+ "id": "F9",
88
+ "group": "forbidden",
89
+ "rule": "弹窗确定按钮禁止加 disabled 禁用态",
90
+ "severity": "ERROR",
91
+ "scope": "Dialog",
92
+ "lintRule": null,
93
+ "boundaryAnchor": "boundaries.md#error-f9--弹窗确定按钮禁止加-disabled-禁用态--scope-dialog",
94
+ "status": "active"
95
+ },
96
+ {
97
+ "id": "F10",
98
+ "group": "forbidden",
99
+ "rule": "hover 时禁止将 boxShadow 设为 undefined",
100
+ "severity": "WARN",
101
+ "scope": "HoverCard",
102
+ "lintRule": null,
103
+ "boundaryAnchor": "boundaries.md#warn-f10--hover-时禁止将-boxshadow-设为-undefined--scope-hovercard",
104
+ "status": "active"
105
+ },
106
+
107
+ {
108
+ "id": "FF1",
109
+ "group": "form",
110
+ "rule": "禁止用色块表达表单状态",
111
+ "severity": "ERROR",
112
+ "scope": "Form",
113
+ "lintRule": "teamix-evo/no-raw-color-scale",
114
+ "boundaryAnchor": "boundaries.md#error-ff1--禁止用色块表达表单状态--scope-form",
115
+ "status": "active"
116
+ },
117
+ {
118
+ "id": "FF2",
119
+ "group": "form",
120
+ "rule": "Card 不嵌套 Card",
121
+ "severity": "WARN",
122
+ "scope": "Form",
123
+ "lintRule": null,
124
+ "boundaryAnchor": "boundaries.md#warn-ff2--card-不嵌套-card--scope-form",
125
+ "status": "active"
126
+ },
127
+ {
128
+ "id": "FF3",
129
+ "group": "form",
130
+ "rule": "错误信息禁止暴露技术栈痕迹",
131
+ "severity": "ERROR",
132
+ "scope": "Form",
133
+ "lintRule": null,
134
+ "boundaryAnchor": "boundaries.md#error-ff3--错误信息禁止暴露技术栈痕迹--scope-form",
135
+ "status": "active"
136
+ },
137
+ {
138
+ "id": "FF4",
139
+ "group": "form",
140
+ "rule": "必填用红色 * 星号,放标签后空格",
141
+ "severity": "WARN",
142
+ "scope": "Form",
143
+ "lintRule": null,
144
+ "boundaryAnchor": "boundaries.md#warn-ff4--必填用红色--星号放标签后空格--scope-form",
145
+ "status": "active"
146
+ },
147
+
148
+ {
149
+ "id": "S1",
150
+ "group": "style",
151
+ "rule": "className 仅用于布局,不用于覆盖组件颜色/字体",
152
+ "severity": "ERROR",
153
+ "scope": "global",
154
+ "lintRule": "teamix-evo/no-color-literal",
155
+ "boundaryAnchor": "boundaries.md#error-s1--classname-仅用于布局不用于覆盖组件颜色--字体",
156
+ "status": "active"
157
+ },
158
+ {
159
+ "id": "S2",
160
+ "group": "style",
161
+ "rule": "不用 space-x-* / space-y-*,改用 flex + gap-*",
162
+ "severity": "ERROR",
163
+ "scope": "global",
164
+ "lintRule": "teamix-evo/prefer-gap-over-space",
165
+ "boundaryAnchor": "boundaries.md#error-s2--不用-space-x---space-y--改用-flex--gap-",
166
+ "status": "active"
167
+ },
168
+ {
169
+ "id": "S3",
170
+ "group": "style",
171
+ "rule": "等宽高用 size-*,不用 w-* h-*",
172
+ "severity": "WARN",
173
+ "scope": "global",
174
+ "lintRule": null,
175
+ "boundaryAnchor": "boundaries.md#warn-s3--等宽高用-size-不用-w--h-",
176
+ "status": "active"
177
+ },
178
+ {
179
+ "id": "S4",
180
+ "group": "style",
181
+ "rule": "用 truncate 简写文本截断",
182
+ "severity": "WARN",
183
+ "scope": "global",
184
+ "lintRule": null,
185
+ "boundaryAnchor": "boundaries.md#warn-s4--用-truncate-简写文本截断",
186
+ "status": "active"
187
+ },
188
+ {
189
+ "id": "S5",
190
+ "group": "style",
191
+ "rule": "不用手动 dark: 颜色覆盖,用语义 token",
192
+ "severity": "ERROR",
193
+ "scope": "global",
194
+ "lintRule": "teamix-evo/no-manual-dark-classnames",
195
+ "boundaryAnchor": "boundaries.md#error-s5--不用手动-dark-颜色覆盖用语义-token",
196
+ "status": "active"
197
+ },
198
+ {
199
+ "id": "S6",
200
+ "group": "style",
201
+ "rule": "用 cn() 处理条件类名,不用模板字符串三元",
202
+ "severity": "ERROR",
203
+ "scope": "global",
204
+ "lintRule": null,
205
+ "boundaryAnchor": "boundaries.md#error-s6--用-cn-处理条件类名不用模板字符串三元",
206
+ "status": "active"
207
+ },
208
+ {
209
+ "id": "S7",
210
+ "group": "style",
211
+ "rule": "overlay 组件不手动设置 z-index",
212
+ "severity": "ERROR",
213
+ "scope": "global",
214
+ "lintRule": null,
215
+ "boundaryAnchor": "boundaries.md#error-s7--overlay-组件不手动设置-z-index",
216
+ "status": "active"
217
+ },
218
+ {
219
+ "id": "S8",
220
+ "group": "style",
221
+ "rule": "不用原始色值表示状态",
222
+ "severity": "ERROR",
223
+ "scope": "global",
224
+ "lintRule": "teamix-evo/no-raw-color-scale",
225
+ "boundaryAnchor": "boundaries.md#error-s8--不用原始色值表示状态",
226
+ "status": "active"
227
+ },
228
+
229
+ {
230
+ "id": "C1",
231
+ "group": "component",
232
+ "rule": "Item 必须在 Group 内",
233
+ "severity": "ERROR",
234
+ "scope": "Select|DropdownMenu|Command|Menubar|ContextMenu",
235
+ "lintRule": null,
236
+ "boundaryAnchor": "boundaries.md#error-c1--item-必须在-group-内",
237
+ "status": "active"
238
+ },
239
+ {
240
+ "id": "C2",
241
+ "group": "component",
242
+ "rule": "Dialog / Sheet / Drawer 必须有 Title",
243
+ "severity": "ERROR",
244
+ "scope": "Dialog|Sheet|Drawer",
245
+ "lintRule": "teamix-evo/dialog-must-have-title",
246
+ "boundaryAnchor": "boundaries.md#error-c2--dialog--sheet--drawer-必须有-title",
247
+ "status": "active"
248
+ },
249
+ {
250
+ "id": "C3",
251
+ "group": "component",
252
+ "rule": "Card 用完整结构",
253
+ "severity": "WARN",
254
+ "scope": "Card",
255
+ "lintRule": null,
256
+ "boundaryAnchor": "boundaries.md#warn-c3--card-用完整结构",
257
+ "status": "active"
258
+ },
259
+ {
260
+ "id": "C4",
261
+ "group": "component",
262
+ "rule": "Button 用 Spinner + disabled 组合表达 loading",
263
+ "severity": "ERROR",
264
+ "scope": "Button",
265
+ "lintRule": null,
266
+ "boundaryAnchor": "boundaries.md#error-c4--button-用-spinner--disabled-组合表达-loading",
267
+ "status": "active"
268
+ },
269
+ {
270
+ "id": "C5",
271
+ "group": "component",
272
+ "rule": "TabsTrigger 必须在 TabsList 内",
273
+ "severity": "ERROR",
274
+ "scope": "Tabs",
275
+ "lintRule": null,
276
+ "boundaryAnchor": "boundaries.md#error-c5--tabstrigger-必须在-tabslist-内",
277
+ "status": "active"
278
+ },
279
+ {
280
+ "id": "C6",
281
+ "group": "component",
282
+ "rule": "Avatar 必须有 AvatarFallback",
283
+ "severity": "WARN",
284
+ "scope": "Avatar",
285
+ "lintRule": null,
286
+ "boundaryAnchor": "boundaries.md#warn-c6--avatar-必须有-avatarfallback",
287
+ "status": "active"
288
+ },
289
+ {
290
+ "id": "C7",
291
+ "group": "component",
292
+ "rule": "提示用 Alert,不用自定义 div",
293
+ "severity": "WARN",
294
+ "scope": "global",
295
+ "lintRule": "teamix-evo/no-raw-color-scale",
296
+ "boundaryAnchor": "boundaries.md#warn-c7--提示用-alert不用自定义-div",
297
+ "status": "active"
298
+ },
299
+ {
300
+ "id": "C8",
301
+ "group": "component",
302
+ "rule": "空状态用 Empty 组件",
303
+ "severity": "WARN",
304
+ "scope": "global",
305
+ "lintRule": null,
306
+ "boundaryAnchor": "boundaries.md#warn-c8--空状态用-empty-组件",
307
+ "status": "active"
308
+ },
309
+ {
310
+ "id": "C9",
311
+ "group": "component",
312
+ "rule": "Toast 用 sonner",
313
+ "severity": "WARN",
314
+ "scope": "global",
315
+ "lintRule": null,
316
+ "boundaryAnchor": "boundaries.md#warn-c9--toast-用-sonner",
317
+ "status": "active"
318
+ },
319
+ {
320
+ "id": "C10",
321
+ "group": "component",
322
+ "rule": "分隔线用 Separator",
323
+ "severity": "WARN",
324
+ "scope": "global",
325
+ "lintRule": null,
326
+ "boundaryAnchor": "boundaries.md#warn-c10--分隔线用-separator",
327
+ "status": "active"
328
+ },
329
+ {
330
+ "id": "C11",
331
+ "group": "component",
332
+ "rule": "加载占位用 Skeleton",
333
+ "severity": "WARN",
334
+ "scope": "global",
335
+ "lintRule": "teamix-evo/no-raw-color-scale",
336
+ "boundaryAnchor": "boundaries.md#warn-c11--加载占位用-skeleton",
337
+ "status": "active"
338
+ },
339
+ {
340
+ "id": "C12",
341
+ "group": "component",
342
+ "rule": "标签/状态用 Badge",
343
+ "severity": "WARN",
344
+ "scope": "global",
345
+ "lintRule": "teamix-evo/no-raw-color-scale",
346
+ "boundaryAnchor": "boundaries.md#warn-c12--标签--状态用-badge",
347
+ "status": "active"
348
+ },
349
+
350
+ {
351
+ "id": "I1",
352
+ "group": "icon",
353
+ "rule": "按钮内图标用 data-icon 属性定位",
354
+ "severity": "ERROR",
355
+ "scope": "Button",
356
+ "lintRule": null,
357
+ "boundaryAnchor": "boundaries.md#error-i1--按钮内图标用-data-icon-属性定位",
358
+ "status": "active"
359
+ },
360
+ {
361
+ "id": "I2",
362
+ "group": "icon",
363
+ "rule": "组件内图标不设尺寸类",
364
+ "severity": "ERROR",
365
+ "scope": "Button|DropdownMenuItem|Alert|Sidebar",
366
+ "lintRule": null,
367
+ "boundaryAnchor": "boundaries.md#error-i2--组件内图标不设尺寸类",
368
+ "status": "active"
369
+ },
370
+ {
371
+ "id": "I3",
372
+ "group": "icon",
373
+ "rule": "图标作为组件对象传递",
374
+ "severity": "ERROR",
375
+ "scope": "global",
376
+ "lintRule": null,
377
+ "boundaryAnchor": "boundaries.md#error-i3--图标作为组件对象传递",
378
+ "status": "active"
379
+ },
380
+ {
381
+ "id": "I4",
382
+ "group": "icon",
383
+ "rule": "按项目配置的 iconLibrary 导入",
384
+ "severity": "ERROR",
385
+ "scope": "global",
386
+ "lintRule": "teamix-evo/icon-from-lucide",
387
+ "boundaryAnchor": "boundaries.md#error-i4--按项目配置的-iconlibrary-导入",
388
+ "status": "active"
389
+ }
390
+ ]
391
+ }