关于 token-compliance
token-compliance 是用于设计系统的审查技能,可检查代码库中的硬编码值、错误层级引用和不一致的 Token 用法,并生成带文件位置、严重性及修复建议的报告。
主要功能
- 01检测硬编码值和 Token 违规
- 02检查 Token 层级与使用一致性
- 03提供文件及行号定位
- 04给出修复建议
- 05按样式方案和配置调整检查
适用场景
- 01在 Token 迁移前审查代码库
- 02查找样式文件中的原始值
- 03确定反复出现的合规问题热点
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ murphytrueman/ design-system-ops --skill token-compliance安装后在 Claude Code 中输入/token-compliance确认已加载。
详细介绍
令牌合规性
用于识别代码库或实现中的令牌合规违规:应使用令牌却硬编码原始值、引用了错误层级的令牌,以及令牌应用不一致。生成包含文件引用和修正建议的违规报告。
开始之前:验证引用
确认此技能的 frontmatter 中 references: 下的每个路径都相对于此 SKILL.md 存在。如果有任何路径缺失,请停止:安装不完整,通常是因为扁平化安装器(例如 npx skills install)漏掉了仓库根目录中的 knowledge-notes/ 目录。请告知用户通过 1-INSTALL.md 中的方法重新安装,并从安装根目录运行 verify-install.sh。只有用户明确要求不使用这些引用时,才可在缺少引用的情况下继续;届时须在输出中说明内容是在未使用该工具包参考资料的情况下生成的。
上下文
令牌合规问题会悄然累积。单个硬编码的十六进制值不会造成任何问题。两年间,数十位贡献者在整个代码库中分散添加了两百个这样的值,这会导致品牌焕新或暗色模式的实现变成需要在数千个文件中手动查找并替换的工作,而不是更新令牌。
合规性检查旨在及时发现违规,避免其不断累积;也能在违规已经存在时了解其模式。模式很重要:如果硬编码值集中在某个产品领域或某个团队的贡献中,应对方式就与这些值均匀分布时有所不同。
配置
如果 .ds-ops-config.yml 存在,请遵循配置与重复运行知识说明(../../knowledge-notes/configuration-and-recurring.md)中的说明,了解如何加载、处理集成回退及重复运行。此技能会读取:
severity.*— 违规严重程度的覆盖设置。尤其是:hardcoded_color、wrong_tier_reference、tier_leakagesystem.theming— 如果为 true,则将硬编码颜色违规提升至配置的严重程度(通常为critical)system.styling— 预先选择检测方法integrations.github— 要检出和搜索的仓库(见下文)integrations.style_dictionary— 解析后的令牌树,作为现有令牌及其正确层级的参考gates.*— 作为component-to-release的一部分运行时,会阻止发布的违规项
自动拉取集成
GitHub(integrations.github.enabled: true):
- 搜索
integrations.github.repo的本地检出副本,而不是 GitHub 的代码搜索 API(参见说明中的 GitHub 注意事项):代码搜索会漏掉#,因此在那里搜索颜色会返回空结果,看起来像是符合规范。 - 在手动检查之前进行广泛的颜色搜索:
如果没有 ripgrep:rg -n --glob '*.{css,scss,less,ts,tsx,js,jsx,vue}' --glob '!**/tokens/**' --glob '!**/{dist,node_modules}/**' \ '#[0-9a-fA-F]{3,8}\b|rgba?\(|hsla?\(|oklch\('grep -rnE --include='*.css' --include='*.scss' --include='*.tsx' [etc.] --exclude-dir=tokens --exclude-dir=node_modules --exclude-dir=dist '<same pattern>' .根据令牌实际所在位置调整 glob。可能会出现一些误报(例如#add或#faded这样的 CSS ID 选择器),需要手动筛除。 - **正向对照:**对令牌源文件运行相同的模式。只有在这些文件中确实搜索到匹配项后,才能将其他位置的零结果报告为零。如果在令牌源文件中也没有找到任何内容,说明该模式不适用于此代码库——请说明结果尚未确认。
- 搜索样式文件中的
px值,作为间距规范的合规性信号 - 使用结果在详细审计前量化范围——“在 47 个文件中发现约 340 个硬编码十六进制值”(示例数字)是报告摘要中有用的表述方式
Style Dictionary(4 或 5)(integrations.style_dictionary.enabled: true):
- 解析令牌树,构建各层级可用令牌的完整映射
- 将此映射作为权威依据,用于查询“此处应引用哪个令牌?”并标记违规项
- 如果某个硬编码值与已知令牌的解析值完全匹配,请在修正建议中自动注明令牌名称
Figma MCP(integrations.figma.enabled: true):
- 拉取 Figma 变量定义作为交叉参照——如果某个颜色定义为 Figma 变量,却在代码中硬编码,则属于违规,且有已知的正确令牌可供使用
步骤 0:混乱代码库协议
在混乱的代码库中,令牌合规最有价值——这些代码库积累了多年的硬编码值、不一致的样式方案,以及多次令牌迁移尝试。对于这类代码库,请应用扩展检测协议:
混乱代码库的特征:
- 同一项目中存在多种样式方案(CSS 自定义属性、SCSS 变量和内联样式并存)
- 虽然有令牌文件,但代码库中仍有很大一部分早于这些文件
- 样式文件中可见多种命名规范(camelCase、kebab-case、BEM 混用)
- 旧版调色板与当前令牌并存
- 组件模板中存在内联
style=属性
针对混乱代码库的扩展检测:
-
旧值映射。 标记违规项之前,先建立旧值到当前令牌的映射。旧版代码中的许多硬编码值在编写时是正确的——它们早于令牌系统。将
#0066CC映射到var(--color-action-primary),这样整改建议就能具体明确,而不只是“使用令牌”。 -
估算违规项的年代。 使用
git log -S'<value>' -- <file>(引入该值的提交)或git blame -w -C来估算违规项的引入时间。普通的git blame和文件修改日期指向的是最近一次重新格式化或文件移动,而非最初的作者——在相信日期之前,请检查是否存在批量格式化提交。按时期对违规项分组:- 令牌系统建立之前(令牌系统尚不存在)——这些是预期的技术债务,而非合规失败
- 迁移期间(采用令牌的过程中)——部分迁移的文件,其中一些值使用令牌,而另一些没有
- 令牌系统建立之后(令牌确立之后)——这些是真正的合规失败,应提高严重级别
-
检测热点。 找出违规项最多的 5–10 个文件。这些是最值得优先整改的目标——修复它们可以不成比例地减少违规项数量。按以下格式呈现:
Compliance hotspots (illustrative): 1. src/legacy/checkout/styles.scss — 47 hardcoded values (pre-token era) 2. src/components/Card/Card.styles.ts — 23 hardcoded values (migration era) 3. src/pages/Dashboard/index.tsx — 19 inline styles (post-token era — PRIORITY) -
检测有意覆盖。 并非所有硬编码值都是违规项:
- 带有
/* override */或/* intentional */等注释的值:将其单独列为“代码中标记为有意设置”,并附上注释,以便团队确认。 - 与任何令牌都不匹配的值仍属于违规项,应像其他违规项一样,按严重级别记录一次。在“正确令牌”列中填写“none — nearest:
<token>”,并在备注中将该行标记为系统外:该值可能是一次性设计需求,也可能表明标度存在缺口;应由团队而非工具来决定。
- 带有
步骤 1:明确范围和访问权限
询问或确认以下事项(自动提取已回答的问题可跳过):
- 要评估什么?(整个代码库、特定产品领域、特定组件集)
- 是否能访问实现内容:代码库、Figma 文件、Storybook 或已描述的属性
- 正在使用的令牌系统:有哪些令牌、定义了哪些层级,以及代码如何使用令牌
- 样式方案:CSS 自定义属性(
var(--token))、SCSS 变量($token)、Tailwind 工具类、CSS-in-JS 主题对象,或混合方案 - 检查应优先关注哪些已知的合规风险点
- 这是基线审计,还是针对之前检查的后续审计
- 代码库的历史和迁移记录: 令牌是什么时候引入的?之前是否进行过迁移?是否存在已知的旧版区域?(这决定是否适用杂乱代码库协议。)
- 代码无法体现的上下文(仅用于下方的严重程度调整):哪些组件位于关键用户路径上?哪些计划弃用?只询问一次;如果没有答复,则不做调整,并在“范围”下说明。切勿根据目录名称推断关键路径。
如果无法访问代码(没有路径、没有本地检出,也没有粘贴的文件),请停止并索要代码;对描述的代码进行合规检查只会得出猜测。如果目标是设计系统仓库,设计系统自身的组件代码也算作使用令牌的代码:请在“范围”下说明这一点,因为令牌源文件不在检查范围内,接受检查的是组件。
样式方案会影响违规检测方式:
- CSS 自定义属性: 令牌引用形式如
var(--color-action-primary)。硬编码值是var()之外的原始十六进制、rgb 或 px 值。 - SCSS 变量: 令牌引用形式如
$color-action-primary或map-get($tokens, 'action-primary')。硬编码值是不使用$变量的原始字面值。 - Tailwind 工具类: 令牌引用是映射到设计系统 Tailwind 配置的工具类(例如
bg-primary、text-color-content-default、gap-4)。这些不是硬编码值,而是以工具类形式表达的令牌引用。Tailwind 中的硬编码值采用任意值方括号形式:h-[12px]、bg-[#ff0000]、p-[7px]。将任意值标记为违规;不要将解析为已配置令牌的标准工具类标记为违规。 - CSS-in-JS(Emotion、styled-components): 令牌引用形式如
theme.colors.action.primary或tokens.spacing[4]。硬编码值是样式对象中的原始字面值。
针对框架的检测说明:
- 如果使用 Vue SFC: 令牌违规会出现在
<style lang="scss" scoped>块中。查找应使用$token变量或var(--token)的原始px值。Vue 的作用域样式也可能通过v-bind()引用令牌来实现动态 CSS——如果绑定到由令牌支持的属性,则属于有效的令牌用法。 - 如果使用 Twig/Fractal: 令牌违规会出现在模板中的内联
style=""属性(例如style="background-color: {{ item.color }}")、SVGfill/stroke属性中的硬编码十六进制值,以及 HTML 尺寸属性中的原始像素值。Twig 组件通常通过 BEM 工具类引用令牌——应审计这些类对应的 SCSS,而不只是模板。 - 如果使用 Emotion/styled-components:
theme.spacing(4)等辅助函数调用属于有效的令牌用法——先找到代码库中的辅助函数,避免误报。模板字符串 CSS(css\padding: 16px``)中的原始值可能无法通过对象语法搜索找到;也要搜索反引号内部的内容。 - 如果使用 React Native: 样式值是
StyleSheet.create或内联style中的无单位数字(padding: 16、fontSize: 14)。其中的数字字面值就是硬编码形式;令牌引用形式如tokens.spacing.md或主题 Hook。
步骤 2:运行合规检查
所有检查均排除以下内容: 令牌源文件、生成的 CSS(构建输出)、SVG 资源,以及故事/测试固件。请在 Scope 区块中注明排除的路径。
基础严重性(应用步骤 3 中的上下文调整之前;severity.* 配置键优先):
- 🔴 严重 — 在支持多个主题的系统中,存在硬编码颜色或错误层级的颜色引用:颜色无法随主题切换
- 🟠 高 — 在单主题系统中,存在硬编码颜色或错误层级的引用;在有对应令牌的文本角色上硬编码排版值
- 🟡 中 — 存在与比例令牌值匹配的硬编码间距;同级组件中的相同角色使用不同令牌实现
- ⚪ 低 — 意图不明确的固定尺寸(边框宽度、触控目标);等待设计决策的非系统内数值
每项违规的 Location 都必须包含文件和行号。没有此信息的发现不予记录。
所有场景下均豁免的值: transparent、currentColor、inherit、none 以及 CSS 全局关键字(initial、unset、revert)。这些永远不属于违规。
检查 1:硬编码颜色值
查找并标记所有非令牌引用的颜色值:
- 十六进制值(例如
#0066CC、#FFF) - RGB 和 RGBA 值(例如
rgb(0, 102, 204)、rgba(0,0,0,0.5)) - HSL 值
- 命名颜色值(例如
red、white),上述豁免关键字除外
对于每项发现:提供文件引用或上下文、找到的原始值,以及应引用的令牌。
如果评估基于设计文件而非代码:检查是否有颜色样式使用原始值,而非库样式。
检查 2:硬编码间距值
查找并标记所有非令牌引用的间距值:
padding、margin、gap、width或height属性中的原始像素值(例如padding: 16px、gap: 8px)- 与间距比例值对应的 rem 值(例如,当存在对应
16px/1rem的间距令牌时使用1rem)
注意:并非所有像素值都属于合规违规。边框宽度、最小触控目标和其他固定尺寸可能是有意硬编码的。如果意图不明确,将其记为 ⚪ 低,并说明原因。
检查 3:硬编码排版值
查找并标记所有非令牌引用的排版值:
- 原始
font-size值(例如font-size: 14px) - 原始
font-weight值(例如font-weight: 700) - 原始
line-height值(例如line-height: 1.5) - 原始
font-family值(例如font-family: 'Inter', sans-serif) - 原始
letter-spacing值
检查 4:错误层级的令牌引用
查找并标记直接引用基础令牌、而未通过语义令牌进行转换的组件级代码:
违规示例:按钮实现中的 background-color: var(--color-blue-500)
应为:background-color: var(--color-action-primary) → var(--color-blue-500)
这是最隐蔽、也最具架构破坏性的合规违规。表面上看似正确——使用了正确的颜色——但它破坏了语义约定,导致语义发生变化时(例如,“主要操作”的含义改变),变化不会传递到组件。
对于每项发现:说明所引用的令牌、应替换使用的语义令牌,以及上下文。
如果某个组件令牌在令牌文件中定义时直接指向基础令牌(card.border: {color.gray.200}),这是定义问题,应由 token-audit 的层级泄漏检查负责。只有当问题出现在使用代码中(例如组件样式表里的 var(--color-gray-200))时,才在此处记录错误层级的引用。如果检查过程中发现了定义问题,请在 Scope 中注明并交由 token-audit 处理;不要为其分配 TC- ID。
检查 5:令牌应用不一致
查找并标记以下情况:同一视觉属性在不同组件或上下文中采用了不同实现方式:
- 同一语义角色在不同组件中使用了不同令牌(例如,某些地方使用
color.action.primary,其他地方则对同一角色使用color.brand.500) - 类似组件中的同一间距场景使用了不同的间距令牌
- 本应共用同一令牌的组件,其交互状态(悬停、聚焦、激活)却采用了不同实现
这类违规在逐个组件审查时往往不易发现,但对比组件时就会清晰显现。
第 3 步:生成违规报告
令牌合规报告
以一句标题句开篇,说明整体状态以及需要重点关注的方面。
日期: [date] 范围: [what was assessed] 评估方法: [codebase / design file / Storybook / described properties]
摘要
整体合规情况。最重要的发现是什么?违规模式是集中出现还是分散出现?
违规数量
| 检查项 | 发现的违规数 | 🔴 严重 | 🟠 高 | 🟡 中 | ⚪ 低 |
|---|---|---|---|---|---|
| 硬编码颜色值 | |||||
| 硬编码间距值 | |||||
| 硬编码字体排印值 | |||||
| 错误层级的令牌引用 | |||||
| 令牌应用不一致 | |||||
| 总计 |
违规日志
按检查类型分组。每项违规填写:
| ID | 检查项 | 严重程度 | 位置 | 原始值 / 错误引用 | 正确令牌 | 备注 |
|---|---|---|---|---|---|---|
| TC-01 | 颜色 | 🔴 严重 / 🟠 高 / 🟡 中 / ⚪ 低 | [file path or context] | #0066CC | var(--color-action-primary) |
每个值只出现一次。不符合系统规范的值(没有匹配的令牌)仍需列在此表中并注明严重程度;在“正确令牌”列填写“无 — 最接近:<token>”,并在“备注”列填写“不符合系统规范”。不要在单独的列表中重复列出这些值。
因结构原因排除: 用一行列出排除的值及原因,例如 max-width: 960px(布局容器)、border: 1px solid(分隔线)、测试包装器内边距。不要将这些记录为违规。
考虑上下文的违规严重程度
并非所有违规的影响都相同。应根据组件的重要性调整严重程度。这正是合规检查区别于简单 grep 的关键特性——如果不考虑上下文,所有违规看起来都一样。
提高严重程度(上调一级):
- 出现在关键用户路径(结账、身份验证、主导航)中的组件
- 出现在扇入度较高的组件中(如果
codebase-index已运行,则参考.ai/index/;否则跳过此项调整并说明原因) - 出现在对主题敏感的组件中(面向品牌的界面、深色模式目标)
- 出现在令牌系统建立后编写的代码中(这些是当前的合规问题,而非继承而来的技术债)
标准严重程度:
- 出现在使用频率适中的通用组件中
- 出现在迁移期间的代码中(部分已迁移,合规性正在改善)
降低严重程度(下调一级):
- 出现在不直接面向用户的内部组件或实用组件中
- 出现在已计划弃用的组件中
- 出现在有明确迁移时间表的旧版代码区域中
- 出现在令牌系统建立前编写的代码中(这些是预期的技术债)
- 使用原始像素值处理与设计令牌无关的结构问题的布局工具(例如,容器使用
max-width: 1200px,分隔线使用height: 1px)——这不属于违规;请将其列在“因结构原因排除”一行中
在初步判定严重程度后再进行调整。在违规日志中注明调整结果及原因——“严重程度由中提高到高:该组件位于结账关键路径中。”
模式分析
跳出单个违规项,描述其模式:
- 违规是否集中在特定文件、组件或产品领域?
- 是否存在反复出现的原始值,且能明确对应到特定 token?
- 是否有某种检查类型在违规数量中占主导?
模式分析能将违规日志转化为可采取行动的信息。“硬编码的间距违规集中在旧版产品领域,可能早于 token 系统”与“硬编码的间距违规分布均匀且数量不断增加,说明 token 系统尚未得到采用”会引出不同的应对方式。
修复优先级
立即处理: 错误层级的 token 引用,以及任何在主题或品牌变更时会造成问题的硬编码值。这些会产生架构层面的影响。
计划处理: 与现有 token 明确对应的、一致的硬编码值。可通过系统性处理来解决。
审查: 含义不明确的值(原始百分比、取决于上下文的 px 值、有意为之的覆盖值)。修复前需要人工判断。
修复方案
根据发现的违规数量和模式,推荐最高效的处理方式:
- 如果违规数量庞大且重复性高:使用迁移脚本或 codemod,比手动修改更高效
- 如果违规集中在特定领域:针对该领域开展专项重构冲刺
- 如果违规稀少且分布分散:将其纳入团队持续执行的代码审查标准,并在每个领域有相关工作时逐步处理
- 如果错误层级的引用数量显著:在修复前,可能需要审查 token 架构,确保语义层级足够完善,能够正确引用
- 对于 token 推出后产生的违规,常规修复方式是添加 lint 规则,这样在清理期间违规数量就不会继续增长:对于 CSS、SCSS 和 CSS-in-JS 字符串,在由 token 支持的属性上使用 Stylelint 的
stylelint-declaration-strict-value,并将 token 模式设为ignoreValues;对于 Tailwind,使用eslint-plugin-tailwindcss的no-arbitrary-value;对于 React Native,对数值样式字面量使用自定义 ESLint 规则。governance-encoder会写入配置
范围
- 已检查: [搜索过的目录和文件类型]
- 未检查: [排除的路径 — token 源文件、生成的 CSS、SVG 资源、故事/夹具 — 以及所有无法访问的内容]
- 如何确认“未发现”: [对于任何报告数量为零的检查,提供正向对照:在 token 源文件中通过相同模式找到了匹配项]
- 假设: [例如,作为参考的 token 树是最新的]
如果其中任何值是有意为之(设计要求的一次性处理,或你已接受的旧版领域),请告知我,我会在今后的运行中将其排除。
此技能不负责 token 定义:DTCG 格式和别名完整性请使用 schema-validator;层级结构和跨系统一致性请使用 token-audit。
质量检查
- 已涵盖全部五项检查
- 错误层级引用与硬编码值分开检查——它们属于不同类别的违规
- 存在模式分析部分,描述违规的分布情况,而不只是总数
- 修复优先级区分架构层面的违规与表面层面的违规
- 报告足够具体,能够据此采取行动:每项违规都包含文件引用或上下文,而不只是“发现硬编码值”
- 任何为零的计数都通过对 token 源文件进行正向对照来验证
- 严重性调整需引用其依据(明确说明的关键路径、索引扇入计数、git 时间段);不得根据名称推断
- 免检关键词和排除路径绝不会被记录为违规
- 报告以“范围”区块和邀请标记有意设置的值结束