关于 design-compliance
design-compliance 是面向 Hexagone Web 开发者的设计系统审计技能,可检查页面或组件并直接修复代码中的违规项。它结合项目规则、组件树分析和可用时的浅色与深色页面检查,最后生成报告。
主要功能
- 01解析 URL、页面名或组件名
- 02递归分析本地组件树
- 03检查设计令牌与框架规范
- 04检查可用页面的浅色和深色模式
- 05自动修改违规代码并生成报告
适用场景
- 01审查 Hexagone 页面是否符合设计系统
- 02将旧 PrimeVue 组件迁移到 PrimeVue 4 规范
- 03查找并修复硬编码颜色或令牌违规
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dedalus-erp-pas/ foundation-skills --skill design-compliance安装后在 Claude Code 中输入/design-compliance确认已加载。
详细介绍
设计规范合规性
对 Hexagone Web 应用中的页面或组件运行全自动设计系统合规性审计。该技能会查找源文件,递归分析完整的组件树,目视检查渲染后的页面(浅色 + 深色模式),检测所有违反 Hexagone 设计系统规则的情况,在原处自动修复所有违规项,并输出结构化报告——整个过程无需征求用户确认。
使用时机
当用户:
- 说出“design-compliance”并附上 URL、组件名称或页面名称
- 要求审计或检查页面或组件的设计系统合规性
- 希望在现有代码中强制执行 PrimeVue / Tailwind / Hexagone 令牌规范
- 在 Hexagone 代码中说“检查设计”“审计 UI”或“设计评审”
核心原则
1. 完全自主
- 整个流程运行期间无需提问
- 如果未提供参数,询问用户要审查什么,然后自主运行
- 直接在原处编辑文件,无需确认
- 不会提交更改——由开发者审查差异
2. 统一标准(不按 MF 设置例外)
- 始终使用 Composition API 和
<script setup lang="ts"> - 始终使用 Tailwind CSS 4
- 始终使用 Pinia 进行状态管理
- 始终使用 PrimeVue 4 原生组件(新建或修改的代码中不得使用 hexa-compat)
- 始终使用
dt覆盖作用域令牌(不得使用pt进行视觉样式设置)
3. Hexagone 专属
此技能针对 Hexagone Web monorepo 技术栈定制:
- PrimeVue 4.3 和
hexagone-preset.js(扩展 Aura) - Tailwind CSS 4
- 三层令牌系统:
--p-*(PrimeVue)、--hexa-*(仅 shell)、beta-scss(旧版,禁止使用) - Vue.js 3.5 和 TypeScript
4. 修复所有问题
此技能会自动修复所有违规项——包括机械性修复(导入重命名、类名替换)和结构性修复(组件替换、模板重写)。没有仅生成报告的模式。编辑前不会征求确认。
事实来源(优先级顺序)
此技能按以下顺序检查这些来源并据此构建规则集:
-
显式规则文件(如果存在,则优先于所有其他来源):
design-system.md或docs/design-system/design-rules.mdCLAUDE.md(根目录和每个 MF).github/copilot-instructions.md或.github/instructions/*.md
-
框架配置:
hexagone-preset.js— PrimeVue 预设(令牌、配色方案)shell-tokens.scss— Shell 外壳令牌(--hexa-*)tailwind.config.*— Tailwind 配置package.json— PrimeVue 版本、依赖项
-
代码库模式:
- 现有的“良好”组件作为隐式规范
- 路由器配置用于路由到组件的映射
输入模式
此技能接受三种类型的输入,最终都会进入相同的流程:
URL 模式
/design-compliance http://localhost:5173/hexagone-etab/vue/patients
- 直接使用 URL 进行视觉检查
- 将 URL 路径反向映射到路由器配置中的路由
- 查找该路由对应的组件文件
- 递归解析所有本地导入
组件名称模式
/design-compliance PatientDashboard
- 使用 glob 查找匹配文件:
**/PatientDashboard.vue、**/patient-dashboard.vue、**/PatientDashboard/** - 如果有多个匹配项,则全部审查
- 对每个匹配的组件,解析其所属路由(如果有),以进行视觉检查
- 递归解析所有本地导入
页面名称模式
/design-compliance Patients
- 在路由器配置文件中搜索名为“Patients”或路径为
/patients的路由 - 查找分配给该路由的组件
- 构建用于视觉检查的 URL
- 递归解析所有本地导入
无参数
/design-compliance
询问用户要审查什么。不要自行猜测。
工作流
步骤 1:查找权威依据
-
阅读明确的规则文件(如果项目中存在):
- 搜索
**/CLAUDE.md、**/design-system.md、**/design-rules.md - 搜索
.github/copilot-instructions.md、.github/instructions/*.md - 提取设计系统规则、反模式和令牌约定
- 搜索
-
阅读框架配置:
- 查找并阅读 PrimeVue 预设文件(通常为
**/hexagone-preset.js或**/theme/*.js) - 查找并阅读 shell 令牌(通常为
**/shell-tokens.scss) - 阅读
package.json,确认 PrimeVue 版本和依赖项 - 如果存在 Tailwind 配置,也一并阅读
- 查找并阅读 PrimeVue 预设文件(通常为
-
构建合并后的规则集——将所有来源整合为一份必须遵守的规则清单
步骤 2:确定目标文件
根据输入模式:
-
解析用户输入,确定模式(URL、组件名称或页面名称)
-
查找入口文件:
- URL → 解析路径,在路由文件(
**/router/**/*.{js,ts}、**/router.{js,ts})中搜索匹配路由,并获取组件 - 组件名称 → 搜索
**/<name>.vue、**/<name-kebab>.vue、**/<Name>/** - 页面名称 → 在路由配置中搜索匹配的路由名称或路径
- URL → 解析路径,在路由文件(
-
递归解析组件树:
- 阅读每个
.vue文件 - 提取所有本地导入(跳过
primevue/*、vue、vue-router、pinia、node_modules) - 跟进每个导入,找到对应文件并重复此过程,直到不再发现新的本地组件
- 构建需要审查的完整文件列表
- 阅读每个
-
向用户报告发现的组件树:
Found 12 files in component tree for PatientDashboard: - frontend/gap-mf/src/views/PatientDashboard.vue (entry) - frontend/gap-mf/src/components/PatientHeader.vue - frontend/gap-mf/src/components/PatientTimeline.vue - ...
步骤 3:静态代码分析
针对组件树中的每个文件,检查所有违规类别:
类别 1:组件错误
- 存在 PrimeVue 对应组件时,仍使用原生
<button>、<input>、<select>、<textarea>、<table> - 使用
<btn>、<alert>、<card>、<action>、<spinner>(hexa-compat)——应使用 PrimeVue 原生组件 - 使用任何 hexa 组件(
<datepicker>、<data-table>、<modal>等)——应使用 PrimeVue 原生组件 - **修复:**替换为正确的 PrimeVue 组件,更新导入并调整 props/插槽
类别 2:令牌层级错误
- 硬编码颜色:在
<style>或内联样式中使用#xxx、rgb(...)、hsl(...) - 在模板中使用 beta-scss 类:
text:teal、bg:grey-lightest、flex:6/12等 - 在 shell 组件(Header、Sidebar、Navigation)之外使用
--hexa-*令牌 - 使用任意 Tailwind 值:
text-[#ff0000]、bg-[rgb(...)]、p-[17px] - **修复:**替换为
var(--p-*)令牌、Tailwind 主题类或dt()覆盖
类别 3:pt 误用
- 使用
pt属性进行视觉样式设置:border、shadow、padding、margin、background、color、font-size、border-radius - **修复:**将视觉样式覆盖移至
dt属性,或使用令牌在<style scoped>中设置
类别 4:导入违规
- 使用大写的 PrimeVue 导入路径:
primevue/InputText→primevue/inputtext - 使用 v3 组件名称:
Dropdown→Select、Calendar→DatePicker、InputSwitch→ToggleSwitch、OverlayPanel→Popover、TabView/TabPanel→Tabs/TabList/Tab/TabPanels/TabPanel、Chips→InputChips - 从
primevue汇总模块进行具名导入:import { InputText } from "primevue"→ 默认导入 - **修复:**重写导入语句,更新组件注册和模板用法
类别 5:深色模式违规
- 在
<style scoped>内嵌套:global(.p-dark)——必须使用单独的非 scoped<style>块 - 硬编码仅适用于浅色模式的颜色,且没有深色模式变体
- **修复:**将深色模式样式移至单独的
<style>块,并使用可自动切换的令牌
类别 6:i18n 违规
- 在模板中硬编码文本字符串(标签、占位符、标题、消息、错误文本)
- 例外:单个字符(
/、|、:、-)、数字、CSS 类名称、非面向用户显示的 prop 值 - **修复:**提取到 locale 文件中,并替换为
t('key')(Composition API)或$t('key')(Options API)
类别 7:无障碍访问
- 仅包含图标且没有
aria-label的<button>或 PrimeVueButton - 表单字段没有关联的
<label>(没有for/id配对,也没有FloatLabel包装器) - 上下文菜单(右键处理程序)——应用必须能在平板电脑上正常使用
- 仅悬停交互(只有
@mouseenter/@mouseleave,没有点击替代方式) <img>标签缺少alt- **修复:**添加
aria-label,使用FloatLabel包装,将悬停交互替换为点击交互,并添加alt文本
类别 8:框架约定
- 使用 Options API(
export default { data(), methods, computed }),而非<script setup lang="ts"> <script setup>缺少lang="ts"- 使用 Vuex/pathify,而非 Pinia
- 使用
this.$store/mapState/mapGetters/mapActions,而非 Pinia 的useXxxStore() - 使用内联样式(
style="..."),而非 Tailwind 类或带设计令牌的作用域 CSS - 新代码中使用
!important(仅可用于解决 beta-scss 遗留冲突) - **修复:**改写为带
<script setup lang="ts">的组合式 API,将状态迁移到 Pinia,并替换内联样式
步骤 4:视觉检查
**前提条件:**探测常用端口(5173、5174、3000、8080),检查是否有开发服务器正在运行。
如果未检测到开发服务器,则完全跳过视觉检查,并继续步骤 5,仅提供代码检查结果。
如果开发服务器正在运行:
4a. 导航到页面
-
确定 URL:
- 如果用户提供了 URL,直接使用
- 如果提供了组件/页面名称,则根据路由配置构造 URL
- 如果无法确定路由,则跳过视觉检查
-
在无头浏览器(Playwright)中打开页面
-
处理身份验证:
- 如果检测到登录页面(查找登录表单或
/login重定向),则进行身份验证:- 用户名:
apvhn - 密码:
apvhn
- 用户名:
- 登录后,导航到目标页面
- 如果检测到登录页面(查找登录表单或
4b. 浅色模式检查
- 截取全页面截图
- 分析关键元素的计算样式:
- 检查是否有与
--p-*令牌值不匹配的硬编码颜色 - 检查是否有不符合 Tailwind 间距刻度的非标准间距值
- 检查同级元素的圆角是否一致
- 检查是否有与
- 视觉检查要点:
- 元素未对齐(同级元素的内边距/外边距不一致)
- 响应式行为异常或不一致
- 元素溢出容器
- 相同上下文中的字体大小不一致
4c. 深色模式检查
- 切换深色模式:在浏览器中执行
document.documentElement.classList.add('p-dark') - 再次截取全页面截图
- 检查以下问题:
- 硬编码的浅色在深色模式下未适配(白色背景、深色背景上的深色文本)
--hexa-*令牌未正确切换- 对比度问题(文本在背景上难以辨认)
- 非基于令牌的样式造成的视觉瑕疵
4d. 记录结果
汇总所有视觉问题,包括:
- 元素选择器或描述
- 问题描述
- 严重程度(P1:损坏/无法阅读;P2:不一致;P3:细节润色)
步骤 5:自动修复所有违规项
对于发现的每项违规(代码和视觉问题):
- **确定修复优先级:**P1(损坏)→ P2(不一致)→ P3(润色)
- 使用 Edit 工具直接编辑文件
- **遵循现有模式:**修复时匹配周边代码的风格
- **处理级联修复:**如果替换组件会改变其 API(props、插槽、事件),则更新模板中的所有用法
- **更新导入:**添加新的 PrimeVue 导入,移除未使用的导入
- 不要提交——保留未暂存的更改,供开发者审查
步骤 6:生成报告
在终端中打印结构化报告:
## Design Compliance Report
**Target:** [component/page name or URL]
**Files analyzed:** [count]
**Violations found:** [count]
**Violations fixed:** [count]
**Visual inspection:** [performed (light + dark) / skipped (no dev server)]
### Files in Component Tree
| # | File | Violations |
|---|------|------------|
| 1 | `frontend/gap-mf/src/views/PatientDashboard.vue` | 5 |
| 2 | `frontend/gap-mf/src/components/PatientHeader.vue` | 2 |
| ... | ... | ... |
### Violations Fixed
#### Category 1: Wrong Component ([count])
| File | Line | Before | After |
|------|------|--------|-------|
| `PatientDashboard.vue` | 42 | `<button @click="save">` | `<Button @click="save" label="..." />` |
#### Category 2: Wrong Token Layer ([count])
| File | Line | Before | After |
|------|------|--------|-------|
| `PatientHeader.vue` | 15 | `color: #006875` | `color: var(--p-primary-500)` |
#### Category 3: pt Misuse ([count])
...
#### Category 4: Import Violations ([count])
...
#### Category 5: Dark Mode Violations ([count])
...
#### Category 6: i18n Violations ([count])
...
#### Category 7: Accessibility ([count])
...
#### Category 8: Framework Conventions ([count])
...
### Visual Inspection Results
[If performed]
#### Light Mode
- [Issue 1: description — severity]
- [Issue 2: description — severity]
#### Dark Mode
- [Issue 1: description — severity]
- [Issue 2: description — severity]
### Summary
- **Total violations:** [count]
- **Auto-fixed:** [count]
- **Remaining (manual review needed):** [count, if any]
违规项参考
PrimeVue v3 → v4 重命名组件
| v3(禁止使用) | v4(正确) | 导入路径 |
|---|---|---|
Dropdown | Select | primevue/select |
Calendar | DatePicker | primevue/datepicker |
InputSwitch | ToggleSwitch | primevue/toggleswitch |
OverlayPanel | Popover | primevue/popover |
TabView / TabPanel | Tabs / TabList / Tab / TabPanels / TabPanel | primevue/tabs, etc. |
Chips | InputChips | primevue/inputchips |
HTML → PrimeVue 映射
| 原始 HTML | PrimeVue 替代组件 |
|---|---|
<button> | 来自 primevue/button 的 <Button> |
<input type="text"> | 来自 primevue/inputtext 的 <InputText> |
<input type="checkbox"> | 来自 primevue/checkbox 的 <Checkbox :binary="true"> |
<input type="radio"> | 来自 primevue/radiobutton 的 <RadioButton> |
<select> | 来自 primevue/select 的 <Select> |
<textarea> | 来自 primevue/textarea 的 <Textarea> |
<table> | 来自 primevue/datatable、primevue/column 的 <DataTable> + <Column> |
<dialog> | 来自 primevue/dialog 的 <Dialog> |
<progress> | 来自 primevue/progressbar 的 <ProgressBar> |
hexa-compat → PrimeVue 映射
| hexa-compat | PrimeVue 原生组件 |
|---|---|
<btn severity="..."> | 来自 primevue/button 的 <Button severity="..."> |
<alert color="red"> | 来自 primevue/message 的 <Message severity="error"> |
<card> | 来自 primevue/card 的 <Card> |
<action @click> | 来自 primevue/button 的 <Button link @click> |
<spinner> | 来自 primevue/progressspinner 的 <ProgressSpinner> |
<modal> | 来自 primevue/dialog 的 <Dialog> |
令牌层规则
| 场景 | 允许使用 | 禁止使用 |
|---|---|---|
| 业务页面(视图、组件) | var(--p-*)、Tailwind 类、dt() | var(--hexa-*)、beta-scss 类、硬编码颜色 |
| Shell 组件(Header、Sidebar、Nav) | var(--hexa-*)、var(--p-*) | beta-scss 类、硬编码颜色 |
| 新代码(任何代码) | Tailwind CSS 4 类、var(--p-*) 令牌 | beta-scss 类、内联样式、!important |
beta-scss → 现代替代项
| beta-scss 类 | Tailwind / 令牌替代项 |
|---|---|
text:teal | text-primary-500 或 var(--p-primary-500) |
bg:grey-lightest | bg-surface-50 或 var(--p-surface-50) |
bg:teal-dark | var(--hexa-chrome-bg-accent)(仅限 Shell) |
bg:orange | var(--hexa-nav-bg)(仅限 Shell) |
flex:X/12 | Tailwind 网格或 w-{fraction} |
p:1、m:1、pt:1 | Tailwind p-4、m-4、pt-4 |
text:bold | font-bold |
text:center | text-center |
border | border |
rounded:1/2 | rounded-md 或 var(--p-content-border-radius) |
w:full | w-full |
边缘情况
未找到文件
如果 glob/搜索没有找到匹配的文件:
- 告知用户:"未找到与 '[input]' 匹配的文件。请尝试使用 URL、.vue 组件名称或路由路径。"
- 停止
开发服务器未运行
- 完全跳过视觉检查
- 仅运行代码分析和自动修复
- 在报告中注明:"已跳过视觉检查 — 在端口 5173、5174、3000、8080 上未检测到开发服务器"
身份验证失败
- 如果使用
apvhn/apvhn登录失败,则跳过视觉检查 - 在报告中注明:"已跳过视觉检查 — 身份验证失败"
- 继续进行仅针对代码的分析
组件树较大(20+ 个文件)
- 处理所有文件 — 不要跳过或抽样
- 按文件组织报告,以便阅读
- 如果组件树超过 10 个文件,则使用并行子 Agent(每批 5 个文件分配一个子 Agent)
混合 MF 文件
如果组件树跨越多个微前端(例如,导入共享包):
- 对所有文件应用相同的单一标准
- 在报告中注明每个文件所属的 MF
文件已符合规范
如果文件没有违规项:
- 在文件列表中列出,并注明 "0 violations"
- 不要编辑该文件
重要说明
- 此技能会修改文件。 它会就地编辑
.vue文件以修复违规问题。不会提交更改。 - 开发者负责审核差异。 技能运行后,开发者应运行
git diff,检查所有更改。 - i18n 键: 提取硬编码文本时,请使用描述性点分隔键,并与组件名称和上下文对应(例如,
patientDashboard.title、patientHeader.saveButton) - PrimeVue 文档: 如需了解组件 API 详情,请获取
https://primevue.org/<component>.md - 递归解析会在以下位置停止:
primevue/*、vue、vue-router、pinia、@vueuse/*、node_modules、@hexagone/shared(将 shared 包视为库边界) - 外壳组件(Header、Sidebar、Navigation、Breadcrumbs)可以使用
--hexa-*令牌 — 不要将其标记为问题