1. 项目缘起为什么我们需要一个叫“impeccable”的东西第一次看到“impeccable”这个词是在一个前端群里有人甩了张截图说“这玩意儿把 AI 写出来的页面从‘能看’拉到了‘能交付’”。我当时的第一反应是又一个包装概念的工具。毕竟这两年打着“AI coding agents”旗号的 CLI 工具太多了从 codex cli 到各种 zcode cli、trae cli装了一圈下来真正留在工作流里的没几个。但“impeccable”这个名字起得很刁——它不叫“fast”也不叫“smart”而是直接指向了前端设计里最难量化的那个维度无可挑剔。说白了impeccable 是一个面向 AI coding agents 的前端设计约束层。它本身不是一个代码生成器也不是一个独立的编辑器而是一套通过 CLI 和 browser extension 双通道介入的工作方式用来解决一个非常具体的问题AI 生成的界面代码功能上跑得通但视觉上一眼假。间距忽大忽小、颜色对比度不够、圆角半径不统一、hover 状态缺失、响应式断点乱设——这些问题单个看都是小事堆在一起就是“这页面一看就是 AI 写的”。它适合谁如果你是用 codex cli 或者类似工具做前端原型的独立开发者如果你在团队里负责把 AI 产出的 UI 稿落地成可维护的组件如果你单纯受够了每次都要手动去调那些 AI 根本不管的细节那 impeccable 这套思路值得你花时间研究。它不解决“从零到一”的问题它解决的是“从一到一点五”的那段脏活。我花了大概两周时间把 impeccable 的核心逻辑拆了一遍结合自己平时用 codex cli、openspec cli 的习惯整理出一套可复现的实操方案。下面从设计思路开始讲然后拆细节、走流程、排坑最后给几个我踩过的坑和对应的解法。2. 整体设计思路为什么是“约束层”而不是“生成器”2.1 核心定位在 AI 和浏览器之间插一道质检市面上大多数 AI 前端工具的思路是“生成即完成”——你给 prompt它吐代码你复制粘贴跑起来能看就行。但 impeccable 的思路是反过来的它假设 AI 生成的代码一定会在细节上出问题所以它在 AI 输出和最终渲染之间插了一道约束层。这道约束层通过两个入口介入一个是 CLI用来在代码提交前做静态规则校验另一个是 browser extension用来在真实渲染环境里做动态视觉审计。这个设计选择背后的逻辑很直接静态检查抓不到视觉问题动态检查抓不到代码结构问题。比如“两个相邻卡片的间距不一致”这件事在代码里可能表现为一个用margin-bottom: 16px另一个用gap: 1rem静态规则很难判定这是 bug 还是有意为之。但在浏览器里一渲染肉眼可见的错位就暴露了。反过来“所有按钮都缺少 focus-visible 样式”这种问题在浏览器里不一定能立刻发现但静态扫描一遍 CSS 就能揪出来。impeccable 把这两条路都走了。2.2 为什么选 CLI Browser Extension 双通道CLI 通道的价值在于可集成。你可以把它挂到 git pre-commit hook 里也可以在用 codex cli 生成完代码后自动跑一遍。我试过在 codex cli 的 workflow 里加一步impeccable check --staged效果就是每次 AI 改完代码提交前会自动列出所有违反设计规范的条目。这个反馈环很短短到你在还没切到浏览器之前就知道哪里有问题。Browser extension 通道的价值在于所见即所得。它不依赖你手动跑命令而是在你打开页面的时候自动注入审计脚本把当前视口内所有元素的间距、颜色、字体、层级关系扫一遍然后在侧边栏给出一个“视觉一致性评分”。这个评分不是玄学它背后是一套基于设计 token 的比对逻辑——如果你的设计系统里定义了spacing-4 16px那所有本该用这个 token 的地方如果出现了15px或17px就会被标记出来。注意browser extension 的审计结果依赖页面已经加载完设计 token 的定义文件。如果你的项目是用 CSS-in-JS 动态生成样式需要在 extension 设置里开启“等待样式注入完成”选项否则会漏报。2.3 和 codex cli、openspec cli 的关系很多人容易把 impeccable 和 codex cli 搞混觉得是不是要替代它。不是的。codex cli 负责“写”impeccable 负责“审”。你可以把 codex cli 理解成一个手速极快但审美不稳定的初级开发impeccable 就是坐在他旁边的那个设计系统守护者。openspec cli 则是另一条线它管的是接口规范和契约和 impeccable 管的设计规范是互补的。我目前的组合方式是用 codex cli 生成组件骨架用 openspec cli 校验 API 契约用 impeccable 校验视觉一致性。三个工具各管一摊互不越界。这种分工的好处是每个工具的职责边界清晰出问题的时候容易定位是哪一层没守住。3. 核心细节解析impeccable 到底在检查什么3.1 间距系统的原子化校验间距是 AI 生成前端代码时最容易翻车的地方。原因很简单AI 在生成 CSS 的时候倾向于“就近取值”——它看到上下文里有个1rem就继续用1rem看到有个12px就继续用12px。它不会主动去对齐你的设计 token 体系。impeccable 的做法是强制所有间距值必须映射到预定义的 spacing scale 上。具体来说你需要在项目根目录放一个impeccable.config.json里面定义好你的 spacing scale{ spacing: { scale: [0, 4, 8, 12, 16, 24, 32, 48, 64], tolerance: 0, allowNegative: true } }tolerance: 0意味着任何不在 scale 里的值都会被标记。我一开始设了tolerance: 2想着给点弹性空间结果发现 AI 会利用这个弹性把所有值都往边界上靠最后整个页面的间距还是乱的。后来改成 0配合一个自动修复命令impeccable fix --spacing它会帮你把最近似的合法值替换上去。实测下来一个中等复杂度的页面大概有 30 到 50 处间距违规自动修复能处理掉八成以上。3.2 颜色对比度与语义化检查颜色这块 impeccable 做了两层检查。第一层是对比度它会按照 WCAG 2.1 的标准计算每个文本元素的前景色和背景色对比度低于 4.5:1 的正文和低于 3:1 的大号文字都会被标记。第二层是语义化它会检查你是否使用了设计系统里定义的颜色 token而不是硬编码的 hex 值。这里有个细节值得展开AI 生成颜色的时候特别喜欢用“看起来差不多”的近似值。比如你的主色是#2563EB它可能会生成#2564EB或者#2573EB。人眼几乎看不出区别但设计系统的一致性就被破坏了。impeccable 的语义化检查会把这些近似值全部揪出来并给出建议替换的 token 名称。我遇到过一个比较隐蔽的情况某个按钮的 hover 状态颜色对比度在默认状态下是合格的但 hover 之后背景变深文字颜色没变对比度掉到了 3.8:1。这种问题静态扫描很容易漏但 browser extension 在模拟 hover 状态时能抓到。所以我的习惯是每次改完按钮样式都手动在 extension 里触发一遍 hover 审计。3.3 响应式断点的逻辑一致性响应式是另一个重灾区。AI 生成媒体查询的时候断点值经常是随机的——这次用768px下次用767px再下次用770px。impeccable 要求你在配置里声明断点集合然后检查所有media查询是否严格使用了这些断点。{ breakpoints: { values: [640, 768, 1024, 1280, 1536], strategy: min-width, allowRange: false } }strategy: min-width意味着它只允许min-width写法不允许max-width和min-width混用。这个约束一开始我觉得太死板后来发现混用确实是 bug 温床——尤其是在嵌套媒体查询的时候max-width: 768px和min-width: 768px会在 768px 这个点上产生重叠或空隙。统一成min-width之后逻辑清晰了很多。3.4 交互状态的完整性覆盖impeccable 会检查每个可交互元素是否定义了完整的交互状态default、hover、focus-visible、active、disabled。缺任何一个都会被标记。这个检查在 AI 生成代码的场景下特别有价值因为 AI 往往只写 default 和 hoverfocus-visible 和 disabled 经常被忽略。实操心得focus-visible 的样式不要直接用outline: none去掉而是用outline: 2px solid token(colors.focus)加上outline-offset: 2px。这样既满足可访问性要求又不会破坏视觉设计。impeccable 的自动修复命令里内置了这个模式直接跑impeccable fix --focus就能批量补上。4. 实操流程从零接入 impeccable 的完整步骤4.1 环境准备与 CLI 安装impeccable 的 CLI 是通过 npm 分发的全局安装即可npm install -g impeccable-cli安装完之后先跑impeccable init它会在项目根目录生成一个默认的impeccable.config.json。这个默认配置里包含了一套比较通用的 spacing scale 和断点集合但我不建议直接用——你应该根据自己的设计系统去改。我一般会先把设计稿里的 spacing 值和断点值整理出来然后手动填进去。初始化完成之后跑一次impeccable check看看当前项目的基线情况。第一次跑大概率会报几百个问题别慌这是正常的。先看汇总报告impeccable check --summary输出会按类别分组比如 spacing 违规 120 处、color 违规 45 处、breakpoint 违规 12 处。根据这个分布决定先修哪一类。我的经验是先修 breakpoint因为断点问题会影响后续所有响应式检查的结果然后修 spacing因为 spacing 改动会影响布局可能连带解决一些 color 对比度问题最后修 color 和交互状态。4.2 Browser Extension 的配置与使用Browser extension 的安装方式取决于你用的浏览器这里不展开。装好之后需要在 extension 的设置页里填入项目的设计 token 文件路径。impeccable 支持从 CSS 自定义属性、SCSS 变量文件、或者 JSON token 文件里读取 token 定义。配置好之后打开你的开发环境页面点击 extension 图标它会自动开始审计。审计结果分三个等级error、warning、info。error 是必须修的warning 是建议修的info 是提示性的。我一般只关注 error 和 warninginfo 太多了看不过来。Extension 还有一个“实时模式”开启之后每次页面热更新都会自动重新审计。这个模式在开发阶段很好用但会稍微拖慢浏览器性能。我的做法是开发时开着准备提交前关掉跑一次完整的 CLI 检查作为最终把关。4.3 与 codex cli 的集成方式如果你平时用 codex cli 生成代码可以在生成命令后面直接串上 impeccable 的检查codex generate --prompt 创建一个用户卡片组件 impeccable check --file src/components/UserCard.tsx这样 AI 一生成完立刻就能看到设计规范层面的问题。更进一步的做法是写一个 shell 函数把生成、检查、自动修复串成一条流水线ai-frontend() { codex generate --prompt $1 \ impeccable fix --auto \ impeccable check --summary }这个函数我用了大概一个月最大的感受是自动修复能解决 70% 的机械性问题但剩下的 30% 需要人工判断。比如某个间距违规自动修复会把它改成最近的合法值但这个合法值可能不是设计意图上的那个值。所以自动修复之后一定要人工过一遍 diff。4.4 参数计算spacing scale 的推导过程很多人不知道自己的 spacing scale 该怎么定。我的方法是这样的先找出设计稿里所有出现过的间距值去重后排序然后看这些值之间的比例关系。如果比例接近 1.5 或 1.6那就是一个等比数列如果比例不固定那就取一个最小公约数作为基数然后按倍数扩展。举个例子假设设计稿里的间距值是4, 8, 12, 16, 24, 32, 48, 64。相邻比值大概是 2, 1.5, 1.33, 1.5, 1.33, 1.5, 1.33。这不是严格的等比但可以近似成一个以 4 为基数、按 1.5 倍递增的序列中间插入一些过渡值。最终我定的 scale 就是上面那组。关键是基数要小4px 是个好选择因为它是大多数屏幕像素密度的整数倍不会产生半像素渲染问题。断点的推导类似先看设计稿里有哪些画板宽度然后取这些宽度的最小公倍数附近的整百值。比如设计稿有 375、768、1440 三个宽度那断点就定 640、768、1024、1280、1536覆盖从手机到宽屏的完整范围。5. 常见问题与排查技巧实录5.1 自动修复后样式反而更乱了这是最常见的问题。原因通常是自动修复只考虑了“合法性”没有考虑“语义”。比如一个卡片的内边距原本是14px自动修复把它改成了16px但设计意图其实是12px——因为14px是手误正确值应该是12px。自动修复选了数值上更近的16px但语义上更近的是12px。解法在配置里加一个preferredValues列表把设计系统里最常用的几个值标出来自动修复会优先选这些值。{ spacing: { scale: [0, 4, 8, 12, 16, 24, 32, 48, 64], preferredValues: [8, 16, 24, 32], tolerance: 0 } }5.2 Browser extension 审计结果和 CLI 不一致这个问题的根源通常是渲染环境和源码环境的差异。CLI 检查的是源码里的静态值extension 检查的是浏览器计算后的样式。如果项目里用了 CSS 预处理器或者运行时样式注入两者看到的值可能不一样。排查步骤先在 extension 里找到报错的元素右键检查看 computed style 里的实际值然后在源码里搜索这个值看它是怎么被计算出来的。如果源码里写的是变量就顺着变量链往上找直到找到硬编码的那个值。这个过程比较繁琐但能帮你发现一些隐藏的样式覆盖问题。5.3 和现有 lint 工具的冲突impeccable 的检查规则和 stylelint、eslint 的某些规则会有重叠。比如 stylelint 也有 spacing 相关的规则但它的判定逻辑和 impeccable 不一样。两者同时跑的时候可能会出现一个报错一个不报的情况。我的处理方式是把 stylelint 的 spacing 和 color 规则关掉只保留语法层面的检查把设计规范层面的检查全部交给 impeccable。这样职责清晰不会互相打架。具体做法是在.stylelintrc里把declaration-block-no-redundant-longhand-properties之类的规则保留把unit-allowed-list之类的规则关掉。5.4 常见问题速查表问题现象可能原因排查动作解决方式CLI 报 spacing 违规但代码里找不到对应值值来自 CSS 变量或预处理器计算在浏览器里查 computed style在配置里声明变量映射关系Extension 不显示审计结果token 文件路径配置错误检查 extension 设置页的路径重新指向正确的 token 文件自动修复后组件布局错位修复值改变了盒模型尺寸对比修复前后的 diff回滚并手动指定正确值断点检查误报使用了非标准断点但有意为之确认是否在配置的断点集合内把该断点加入配置或改用标准断点focus-visible 检查不通过使用了 outline: none搜索所有 outline 相关样式替换为 outline outline-offset 方案避坑技巧在接入 impeccable 的初期不要一次性开启所有检查规则。先开 spacing 和 breakpoint跑一周稳定之后再开 color 和交互状态。一次性全开会导致报错太多反而不知道从哪下手。6. 进阶用法把 impeccable 嵌入团队工作流6.1 Git Hook 自动拦截在.git/hooks/pre-commit里加一行#!/bin/sh impeccable check --staged --fail-on error这样每次提交前都会自动检查暂存区的文件有 error 级别的违规就直接拦截提交。warning 级别的不拦截但会在终端里打印出来提醒。这个机制在团队协作里特别有用能防止 AI 生成的脏代码混进主分支。6.2 CI 流水线集成在 CI 配置里加一个 impeccable 检查步骤作为构建的前置条件- name: Impeccable Design Audit run: | npm install -g impeccable-cli impeccable check --all --fail-on error --report json impeccable-report.json artifacts: paths: - impeccable-report.json这样每次 PR 都会生成一份设计审计报告reviewer 可以直接看报告里的违规列表不用自己去翻代码。6.3 自定义规则扩展impeccable 支持通过插件机制扩展自定义规则。比如你们团队规定所有卡片的圆角必须用radius-lg这个 token就可以写一个自定义规则module.exports { name: card-radius-consistency, check: (node) { if (node.selector.includes(card) node.property border-radius) { return node.value var(--radius-lg); } return true; }, message: 卡片圆角必须使用 radius-lg token };把插件文件放到impeccable.plugins/目录下配置里引用一下就能生效。这个机制让 impeccable 从一个通用工具变成了贴合团队规范的工具。7. 我踩过的几个坑和对应的解法第一个坑是过度依赖自动修复。刚开始用的时候看到impeccable fix --auto能一键修几百个问题觉得很爽每次都是无脑跑。结果有一次修完之后整个页面的视觉节奏全乱了——因为自动修复把一些有意的非标准值也改成了标准值破坏了设计上的呼吸感。后来我学乖了自动修复只用来处理明确的机械性错误比如拼写错误导致的颜色值偏差、遗漏的 focus 样式间距和布局相关的修复一律人工确认。第二个坑是配置文件的版本管理。impeccable.config.json应该提交到 git 里但impeccable.local.json应该加到.gitignore。我一开始把两个都提交了结果同事拉下来之后本地配置覆盖了项目配置检查结果完全对不上。后来把本地覆盖文件单独命名并忽略问题就解决了。第三个坑是和 codex cli 的版本兼容性。codex cli 更新比较频繁有几次更新之后生成的代码风格变了导致 impeccable 的误报率突然升高。我的应对方式是锁定 codex cli 的版本在package.json里写死版本号等 impeccable 适配了新版本再升级。这个策略虽然保守但省去了很多排查兼容性问题的时间。最后分享一个小技巧impeccable 的--watch模式配合 browser extension 的实时审计可以在你写代码的时候持续给出反馈。我一般左边开编辑器右边开浏览器extension 侧边栏常驻改一行代码就能看到设计规范层面的变化。这种即时反馈的体验比等到提交前才跑一次检查要好得多——因为问题刚产生的时候修复成本最低等积累了几十个再修心态容易崩。