关于 token-audit
token-audit 是用于检查设计系统 Token 架构的技能,可生成带严重程度评级和优先级修复建议的报告,帮助团队发现不同层级中的结构问题。
主要功能
- 01发现常见代码格式中的 Token
- 02梳理基础、语义和组件层级
- 03检查引用关系与孤立候选项
- 04生成严重程度评级结果
- 05排列修复事项优先级
适用场景
- 01改版前审查 Token 架构
- 02查找分散在代码库中的 Token 来源
- 03识别仓库内未被引用的 Token
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ murphytrueman/ design-system-ops --skill token-audit安装后在 Claude Code 中输入/token-audit确认已加载。
详细介绍
令牌审计
一项用于审计设计令牌架构的技能,覆盖当前使用的各层级——通常包括基础令牌和语义令牌;如果系统使用组件令牌,也会一并审计。输出一份结构化报告,包含按严重程度评级的问题,以及按优先级排序的修复清单。
开始之前:验证引用
确认此技能前置元数据中的每个 references: 路径都相对于此 SKILL.md 存在。如果有任何路径缺失,请停止:安装不完整,通常是因为某个扁平化安装程序(例如 npx skills install)漏掉了仓库根目录下的 knowledge-notes/ 目录。告知用户使用 1-INSTALL.md 中的方法重新安装,并从安装根目录运行 verify-install.sh。只有在用户明确要求的情况下,才可在没有这些引用的情况下继续;此时请在输出中说明报告是在未使用该工具包参考资料的情况下生成的。
上下文
此技能基于分层令牌架构模型:基础令牌存储原始值,语义令牌表达用途;如果存在组件令牌,则将用途映射到特定 UI 上下文。并非所有系统都会使用组件令牌,没有组件层级不属于问题。大多数令牌债务都源于层级混淆——例如,组件上下文直接引用基础令牌、语义名称描述外观而非用途,或将基础层视为唯一层级。
本次审计并非要强制采用某种特定的命名规范,而是要找出令牌结构妨碍团队使用的地方。
配置
如果存在 .ds-ops-config.yml,请遵循配置与周期性知识说明(../../knowledge-notes/configuration-and-recurring.md),了解配置加载、集成回退和周期性运行方式。此技能会读取:
severity.*— 问题严重程度评级的覆盖设置(例如,将hardcoded_color: critical设为high默认值的覆盖项)system.theming— 如果为 true,则将硬编码颜色问题提升到配置指定的严重程度system.styling— 预先选择要应用的格式专属指导integrations.style_dictionary— 通过 Style Dictionary 4 或 5 解析令牌(见下文)integrations.figma— 将 Figma 变量作为额外的令牌来源recurring.*— 用于趋势对比的上一份报告(见下文的周期性工作流)
自动拉取集成
Style Dictionary 4 或 5,或 Terrazzo(integrations.style_dictionary.enabled: true,或仓库中的配置):
- 解析
integrations.style_dictionary.config_path中的配置 - 提取包含已解析引用和层级结构的完整令牌树
- 将其作为主要令牌来源——跳过手动询问“提供你的令牌文件”
- 运行
npx style-dictionary build --config [path]并输出到临时目录(或运行npx terrazzo build),让工具解析所有别名后再分析令牌树;解析错误应作为问题记录,并注明来源工具
Figma 变量(integrations.figma.enabled: true):
- 使用 Figma MCP 服务读取
integrations.figma.file_key指定文件中的变量 - 提取变量集合、模式和已解析值
- 将 Figma 变量与代码令牌文件交叉比对,检测不匹配(Figma 中的
--color-primary是#0066CC,而代码中是#0064CC——这属于问题)
GitHub(integrations.github.enabled: true):
- 如果未提供本地文件,则直接从默认分支拉取令牌文件
步骤 0:发现 Token
在向用户索要文件之前,先在代码库中搜索类似 Token 的模式。对于 Token 存在但尚未集中管理的团队,这一步可以降低启动门槛——用户无需知道所有 Token 存放在哪里。
搜索内容:
- CSS 自定义属性——扫描所有
.css文件,查找:root块或带--前缀的属性。包括作用域变体(.dark、[data-theme="..."]、.theme-*)。 - SCSS/Sass 变量——扫描所有
.scss和.sass文件,查找带$前缀的名称。沿着@import和@use链查找局部文件(_colors.scss、_variables.scss、_tokens.scss)。 - JSON/YAML Token 文件——扫描符合常见 Token 命名模式的文件:
tokens.json、tokens.yaml、*.tokens.json、design-tokens/**、src/tokens/**、tokens/**。还要查找包含$type或$value键的 DTCG 格式文件。 - Style Dictionary 配置——扫描
style-dictionary.config.json、style-dictionary/目录下的config.json,或.style-dictionary.json。 - TypeScript/JavaScript Token 对象——扫描
.ts和.js文件,查找符合常见模式的导出:export const tokens、export const theme、export default { color,以及使用as const类型标注、具有类似 Token 的键层级结构的对象。 - Tailwind 配置——查找
tailwind.config.js、tailwind.config.ts或tailwind.config.mjs,并提取theme和extend块。 - Figma Tokens / Tokens Studio——在
.tokens或tokens目录中查找tokens.json,或查找从 Tokens Studio 导出的文件。
搜索方式:
使用文件系统访问能力(glob 模式、读取文件)扫描项目。如果已配置 GitHub 集成且没有本地克隆,请仅使用 gh api search/code 定位候选文件,然后读取这些文件。如果已配置 Figma 集成,请将 Figma 变量作为额外的 Token 来源拉取。
按具体程度排序:专用的 tokens/ 目录比散落的 CSS 文件更可靠。Style Dictionary 配置比原始 JSON 更可靠。但要收集所有内容——分散的 Token 来源本身就是一项发现。
发现结果:
继续之前,先生成一份简要清单:
Token sources found:
- src/tokens/colors.json (94 tokens, JSON, likely primitives)
- src/tokens/semantic.json (67 tokens, JSON, likely semantic tier)
- src/styles/variables.scss (43 variables, SCSS)
- tailwind.config.ts (theme block with 28 custom values)
Total: ~232 token-like declarations across 4 sources
如果没有发现任何内容,请继续步骤 1,并向用户索取手动输入。如果在多种格式中发现了分散的来源,请将其标记为一项发现:“Token 存在于 [N] 种不同格式、分布在 [M] 个文件中。这种碎片化属于结构性技术债——建议集中到单一事实来源。”
向用户展示发现的来源,并询问:“我找到了这些 Token 来源。您希望我审计所有来源,还是只关注特定文件?”这样用户无需手动整理清单,也能掌控审计范围。
步骤 0b:孤立项检测检查点
运行完整审计前,先检查一遍 Token 的使用情况。这是唯一一次孤立项检查,步骤 3c 会复用其结果。
- 已声明的 Token — 统计步骤 0 中找到的所有 Token(或步骤 1 中手动提供的 Token)。
- 被引用的 Token — 搜索对每个已声明 Token 的引用,包括来自其他 Token 的引用,以及来自此仓库中组件的引用。对于 CSS 自定义属性,搜索
var(--token-name)。对于 SCSS 变量,在其声明文件之外搜索$variable-name。对于 JSON/DTCG Token,搜索别名引用({token.path})。对于 TypeScript 对象,搜索导入和访问模式(tokens.color.primary、theme.spacing.md)。 - 正向对照 — 在相信搜索结果前,选择一个已知正在使用的 Token,并确认每种搜索模式都能找到它。如果某种模式无法找到已知在使用的 Token,则说明该模式不适用于此代码库;请修正模式,或将该格式的孤立项报告为未经确认。
- 孤立项候选 — 未被其他 Token 或所扫描仓库中的任何组件引用的 Token。
在设计系统仓库中,大多数 Token 都由未扫描的产品仓库使用。此处的孤立项意味着“仓库内没有使用者”,而非“未使用”。除非用户已授权你访问使用该 Token 的仓库或使用数据,否则应将孤立项报告为尚未确认外部使用情况。
生成检查点摘要(数据仅供示例):
Orphan detection:
- 232 tokens declared
- 189 tokens referenced in-repo (at least once)
- 43 orphan candidates (no reference from another token or an in-repo component)
Top candidates: --color-legacy-teal, --spacing-xl-deprecated, $font-heading-alt (3 more)
Positive control: --color-action-primary found in 14 files by the same patterns
Not checked: consuming product repos
这能让用户在完整审计开始前了解问题的规模。已确认的孤立项会带来维护负担,却没有任何价值——它们会使自动补全列表变得杂乱、让新团队成员感到困惑,并增加 Token 数量。在完整审计中将孤立项候选列为发现项(类别:覆盖率;严重性:低;若数量超过总数的 20%,则为中),并说明检查了哪些使用方。
如果孤立项数量较多(超过总 Token 数的 30%),请显著标出:“超过三分之一的已声明 Token 未被引用。在审计 Token 质量之前,请考虑先进行清理,以简化架构。”
第 1 步:收集令牌来源
如果第 0 步发现了令牌来源,请将其作为主要输入——除非用户想要覆盖,否则跳过手动提问。如果第 0 步没有发现任何内容(或者因无法访问代码库而跳过),请询问令牌来源。可接受的输入:
- JSON、YAML 或 DTCG 格式的令牌文件
- Figma 文件或 Tokens Studio 导出文件
- 粘贴的令牌名称和值列表
- Style Dictionary 配置
- 包含自定义属性的 CSS 文件(例如
:root { --color-primary: #5e4890; },或作用域限定在.dark { }、[data-theme="dark"]或类似选择器下的主题变体) - 带有变量的 SCSS/Sass 文件(例如
$color-primary: #5e4890;) - TypeScript 或 JavaScript 令牌对象(例如
export const tokens = { color: { ... } }) - 包含定义自定义令牌的
theme或extend块的 Tailwind CSS 配置文件(tailwind.config.js或tailwind.config.ts)
特定格式指导:
对于 CSS 自定义属性:将每个带 -- 前缀的属性视为一个令牌。根据命名模式推断层级——类似 --color-blue-500 的属性很可能是原始令牌,--color-action-primary 是语义令牌,--button-background-default 则属于组件层级。如果属性限定在选择器(:root、.dark、[data-theme="dark"])内,请将每个作用域视为一个主题变体。CSS 自定义属性之间通过 var(--other-token) 进行的引用表示层级关系——按与 JSON 令牌引用相同的方式映射。
对于 SCSS 变量:将每个带 $ 前缀的变量视为一个令牌。引用其他变量的 SCSS 变量(例如 $color-primary: $blue-500)表示层级关系。如果变量分散在多个分部文件(_colors.scss、_spacing.scss)中,文件组织方式可能体现层级结构。
对于 TypeScript/JavaScript 对象:将导出对象的键层级视为令牌结构。嵌套对象的映射方式与 JSON 令牌相同。对于 Emotion 或 styled-components 主题,主题对象就是令牌来源。常见模式包括:扁平导出(export const backgroundColor = { scene: '#FFF', primary: '#206EF6' })、使用 as const 类型化的对象(const tokens = { ... } as const)、聚合式 barrel 导出(export const tokens = { breakpoint, fontSize, spacing }),以及将主题映射到 CSS 变量的函数(mapThemeToVars())。可解析为令牌值的辅助函数(如 theme.spacing(4) 或 theme.colors.primary)属于有效的令牌引用。
对于 Tailwind 配置:theme 块定义原始令牌,extend 添加语义覆盖项。引用自定义令牌的 Tailwind 工具类(例如 bg-primary、text-color-content-default)是令牌引用,而不是硬编码值。方括号中的任意值(例如 h-[12px]、bg-[#ff0000])才是实际的硬编码违规项。
如果用户粘贴的原始令牌名称不包含值,请仅进行命名和结构审查。在输出中注明无法进行值分析。
第 2 步:映射层级结构
识别存在哪些层级:
原始层级——原始值,没有语义含义。示例:color.blue.500、spacing.4、font-size.base
语义层级——按意图定义的引用。示例:color.action.primary、spacing.component.gap、text.body.size
组件层级——限定于特定组件上下文。示例:button.background.default、card.padding.inner
标记缺少原始层级或语义层级的情况。只有原始令牌的系统没有语义约定。只有语义令牌的系统缺少原始值的唯一事实来源。两者都是值得指出的结构性问题。缺少组件层级不属于问题——请参阅令牌架构说明。
第 3 步:运行审计检查
对于每项检查,给出 PASS、WARN 或 FAIL 评级,并附上具体示例。每项发现都必须附带证据:令牌路径,以及令牌定义所在的文件和行号(tokens/component.tokens.json:9、src/styles/tokens.css:17)。
严重性分级(severity.* 配置键会覆盖这些默认值):
- 🔴 严重 — 令牌文件并非其声称的真实来源(生成的输出与之发生偏差);在支持多个主题的系统中,层级泄漏或语义层、组件层出现原始值,因为主题切换会悄然漏掉这些值
- 🟠 高 — 单主题系统中的层级泄漏或语义层、组件层出现原始值;向上引用(语义层 → 组件层);命名表示外观的语义令牌(
color.semantic.blue) - 🟡 中 — 同一层级内的约定不一致;组件已使用的角色缺少交互状态;没有文档说明区别的重复原始值;超过 20% 阈值的孤立候选项
- ⚪ 低 — 含糊标记、平台后缀、低于阈值的孤立候选项、DTCG 迁移迹象
命名检查
描述性命名与规定性命名 语义令牌应描述用途,而非外观。
- FAIL 示例:
color.semantic.blue— 描述颜色,而非意图 - PASS 示例:
color.action.primary— 描述角色
层级泄漏 组件令牌应引用语义令牌,而非原始令牌。
- FAIL 示例:
button.background.default: {color.blue.500}— 跳过语义层 - PASS 示例:
button.background.default: {color.action.primary}— 引用链正确
含糊标记 可能有多种含义,或需要上下文才能理解的令牌名称(令牌架构说明中列出了完整规则及例外):
- 应标记的示例:
normal、alt、variant、misc、other,以及独立表示角色的default或base(color.default) - 不标记:作为角色旁边的状态或级别片段出现的
default/base(color.action.default、color.surface.base),以及 T 恤尺码或数字刻度步骤(spacing.sm、radius.lg) - 每个被标记的令牌都应附上建议的重命名
约定一致性(此技能负责令牌命名;naming-audit 涵盖组件和模式)
在每个层级内,找出主要的大小写形式、分隔符和片段顺序,并标记不符合的令牌:与 color.blue.500 并列的 color.blue-500、与 hover/pressed 并列的 hover/active、与 button.background.hover 并列的 button.background-hover。在发现结果中报告主要约定,以便团队确认其是否符合预期。
平台后缀滥用 令牌名称中包含平台特定信息,而非通过转换层处理:
- 示例:
color.primary.ios、spacing.mobile.gap— 这些信息应放在转换中,而非名称中
值检查(如果有值可用)
语义层或组件层的硬编码值 任何使用原始值而非引用的语义令牌或组件令牌,都是结构性技术债务。
- 对每处情况进行标记,并附上:令牌名称、找到的原始值,以及建议的引用目标
没有令牌别名的重复原始值 原始令牌层中,以不同名称出现但没有解释的相同原始值。
- 标记潜在重复项,并询问这种区别是否有意为之
跨层级引用 任何令牌引用了特异性更高层级的令牌。
- 示例:语义令牌引用组件令牌 — 这颠倒了依赖方向
覆盖情况检查
缺少交互状态 检查标准状态是否都有对应的语义令牌:默认、悬停、激活、禁用、焦点、错误、成功、警告。
缺少深色模式/主题别名 如果系统计划支持主题,请检查语义令牌是否作为能够感知主题的别名存在,还是直接使用原始值。
组件层级不一致(仅当系统使用组件令牌时) 如果系统已采用组件令牌,且某些组件有组件令牌,而同一类别中的其他组件没有,请标记这种不一致。如果系统完全不使用组件令牌,则这不算问题——采用两层架构(原语和语义)是有效且常见的选择。
第 3b 步:DTCG 2025.10 对齐评估(有条件——仅在相关时包含)
如果令牌源不是 DTCG 格式,且团队未提及 DTCG 迁移,请完全跳过本节。大多数团队不需要本节。令牌源使用 DTCG 格式、团队询问 DTCG 合规性,或审计目的是规划迁移时,才包含本节。
如果令牌源使用 DTCG 格式,或团队正在考虑迁移到 DTCG:
结构验证属于 schema-validator 的职责。 类型解析、超出 13 种类型的 $type 值、2025.10 值形状、复合子值完整性、损坏或循环别名,以及解析器文档有效性,都应由它负责。如果存在 schema-validator 报告,请在本节引用其中的问题 ID;如果没有,请运行它(过程快速且机械),不要手动重新检查。本节说明这些结果对架构的意义,并补充以下两项需要层级映射的检查。
复合令牌中的别名层级。 子值混合引用和原始值的复合令牌(例如 typography.body 中的 fontFamily: {font.family.body},但 fontSize: "16px"),在语义层级上属于原始值的复合形式:它无法应用主题。schema-validator 会报告其形状;本审计负责评定其严重程度。严重程度:🟡 中等;如果该复合令牌被使用主题的组件采用,则为 🟠 高。
解析器上下文与主题。 如果存在 .resolver.json 文件,请读取每个修饰符的 contexts 和 resolutionOrder(注释描述了其结构;规范使用的术语是 context,而不是 mode)。未重新定义某个令牌的上下文会继承较早的值,这是预期设计,并非缺陷。本审计需要报告的是:没有任何非默认上下文重新定义的依赖主题的语义令牌(颜色、阴影、边框颜色),因此主题会静默地保留默认值;以及不属于任何集合的令牌文件。严重程度:已发布主题中继承的颜色令牌为 🟠 高(有对比度风险);不属于任何集合的令牌文件为 ⚪ 低。如果团队拥有多个主题,theme-audit 会对此进行更深入的检查;引用它即可,无需重复检查。
迁移信号(仅供参考)。 对于尚未采用 DTCG 2025.10 的团队,用一段话说明:需要添加 $type 的令牌数量(完成类型解析后)、需要重构为对象值的复合令牌数量、需要转换为对象形状的字符串值数量,以及主题化是否需要解析器文件。指出风险最低的第一步(通常是为原语添加 $type,不会改变任何解析后的值)。然后提出:如果团队需要,可提供包含工作量范围的完整分阶段迁移计划——不要在未被要求时直接生成。
第 3c 步:令牌依赖关系图(有条件——在可访问代码库时纳入)
如果无法访问代码库,或审计仅关注令牌的命名/结构,跳过本节。如果用户已连接代码库,且希望在进行更改前了解影响范围,则纳入本节。
依赖关系图只有一个生成方:codebase-index,它会将令牌到组件的关联写入 .ai/index/。如果该目录存在,请读取其中的令牌关联,将第 0b 步中的孤立候选项标记在关联图上,并列出扇出较大的令牌(即在此代码库中被许多组件绑定的令牌;说明数量,并记住不计入代码库外部的使用方)。如果目录不存在,请说明尚未构建影响范围视图,并建议先运行 codebase-index;不要在此处再构建另一张图。令牌与 Figma 的一致性由 figma-variable-audit 第 6 步负责。
第 4 步:生成审计报告
以一句概述整体状态并指出重点的标题句开篇。示例:“你的令牌架构存在三个结构性问题——语义层有两个,另有一个跨层冲突。以下是完整分析。”
报告结构如下:
令牌审计报告
摘要 用一段话说明令牌架构的整体状态,以及最紧迫的问题。以同行评审的口吻撰写,而不是合规报告。
层级结构
- 原始层:🟢 强 / 🟡 可用 / 🟠 较弱 / 🔴 缺失
- 语义层:🟢 强 / 🟡 可用 / 🟠 较弱 / 🔴 缺失
- 组件层:🟢 强 / 🟡 可用 / 🟠 较弱,或“未使用”(不算问题)
- 层级泄漏实例:[数量]
发现
逐项列出每个发现,包含:
- 发现 ID(例如 TA-01)
- 严重程度:🔴 严重 / 🟠 高 / 🟡 中 / ⚪ 低
- 检查类别:命名 / 值 / 覆盖
- 描述:用一句话说明
- 证据:令牌路径,以及每个令牌的定义文件和行号
- 建议措施:具体且可执行,并写明替换方案
修复优先级 将发现分为三个层级:
- 优先修复 — 影响下游使用方的结构性问题
- 接下来修复 — 会随时间累积的命名问题
- 之后处理 — 覆盖缺口和可选改进
工作量估算 对每个修复层级提供经过校准的工作量估算,并明确说明假设和注意事项:
| 发现 | 预计工作量 | 假设 | 置信度 |
|---|---|---|---|
| [发现 ID] | [范围,例如 4–8 小时] | [此估算基于哪些假设] | [高/中/低] |
始终给出范围(“4–8 小时”,而不是“6 小时”),说明估算依据,并将置信度评为高/中/低;如果为低,说明还需要梳理哪些内容。对于“优先修复”项,请注明估算仅涵盖令牌侧的更改,迁移使用方不包含在内。令牌数量超过 200 个,或使用方应用多于 3 个时,建议先进行有时限的探索,再纳入冲刺规划。
目标是给出项目经理在冲刺规划中能够说明理由的估算,而不是那些一旦超时便会损害信任的乐观目标。
范围
- 已检查:[实际读取的令牌文件、配置和目录]
- 未检查:[无法访问的内容,例如使用方的产品代码库、Figma]
- “未发现”的检查方式:[例如孤立项搜索的正向对照——如果报告没有声称不存在任何问题,则省略]
- 假设:[任何作为既定条件而非经验证内容的事项]
最后附上以下结尾说明。
定期工作流
遵循配置与定期运行说明中的定期运行流程。本技能特有的要求:
- 比较违规总数:增加、稳定还是减少?
- 标记连续 2 个或更多周期未处理的持续性发现。
- 在报告标题部分添加“与上次审计相比的趋势”一节,注明违规数量变化(+/- n),并列出新出现的违规(这些是优先事项,属于近期新增的问题)。
步骤 5:Figma 变量
将代码令牌与 Figma 变量进行比较,并在 Figma 中创建或重命名变量,是 figma-variable-audit 的工作(其步骤 6 负责交叉引用,步骤 10 负责写入)。如果配置了 Figma 文件,或用户提到 Figma,请说明代码侧审计已完成,并提出使用同一令牌源运行 figma-variable-audit,这样两份报告就能按名称对应。请勿在此处比较或写入 Figma。
结尾说明(每份报告都要包含)
在报告末尾加上:
关于上下文的说明: 本次审计能看到你的令牌文件,却看不到这些令牌背后的决策。有些发现可能会标记出团队刻意采用的模式。如果某项发现描述的是有意为之的决策,请告诉我——我会在后续运行中将其排除,并了解你们系统的惯例。我们的目标是发现你尚未注意到的问题,而不是质疑你已经做出的选择。
质量检查
- 每项发现都有具体示例,包含文件和行号,而非笼统描述,并按评估标准标注严重程度
- 摘要段落如实说明严重程度,不要刻意委婉
- 修复建议具体明确:写“将
color.semantic.blue重命名为color.action.primary”,而不是“改进命名” - 层级结构评估涵盖原始层和语义层;如果系统使用组件层,也要涵盖该层
- 如果无法获取值,报告要注明跳过了哪些检查以及跳过的原因
- 结构性 DTCG 检查、依赖图和 Figma 比较应引用 schema-validator、codebase-index 和 figma-variable-audit 的结果,不要在此处重新执行
- 声称某项无引用时,要提供正向对照,并说明未检查哪些使用方
- 包含 Scope 区块和关于有意偏离的结尾说明