Impeccable 设计检测 Hook 实战指南/impeccable hooks命令、双层级规则与多 Harness 接入【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccableImpeccable 为 AI 编码助手Claude Code、Codex、Cursor、GitHub Copilot、Grok Build提供一套自动化的设计检测 Hook每当 Agent 直接编辑 UI 相关文件.tsx、.jsx、.html、.vue、.svelte、.astro、.css、.scss、.sass、.less、.ts、.js时Hook 会运行 impeccable 设计检测器把机械性、明确无歧义的视觉问题破图、溢出/裁剪、对比度与可读性失败、渐变文字、发光阴影、设计系统漂移即时推送给 Agent把其余更偏“品味”的检查文案节奏、调色板与字体品味、布局韵律延迟到会话结束的 Stop 深扫描。本文围绕.trae-cn/skills/impeccable/reference/hooks.md展开结合仓库源码系统讲解/impeccable hooks命令的用法、路由动作、配置项、异常ignore分流策略以及它在各 Harness 下的安装与运行机制。读完你可以独立完成 Hook 的启用/关闭、忽略规则管理、finding 分级处置并理解它背后的双层级设计与去重缓存原理。Hook 是什么一次编辑一次机械化的设计体检设计检测 Hook 的核心是机械化mechanical它只做规则引擎能百分之百确定的事把不可判定的“审美”判断留给人类与 Agent 本身。/impeccable hooks命令负责管理这个 Hook 的项目级开关与忽略配置而真正的扫描逻辑由 crates/hook 中的三个入口承载impeccable hook对应 PostToolUse 逐编辑扫描 Stop 深扫描hook.rsimpeccable hook-before-edit对应 Cursor 的 preToolUse 写入拦截before_edit.rsimpeccable hooks action即本文主角hook 管理/配置命令admin.rs。不同 Harness 的接入方式差异很大这是理解 Hook 行为的第一把钥匙Harness触发方式行为特点Claude CodePostToolUseEdit\|Write Stop编辑后把一段简短的 system reminder 推入 Agent 上下文有 finding 给修正提示遗留问题再提醒一次干净的 UI 文件给一句简短确认除非开启hook.quietCodexPostToolUseEdit\|Write\|apply_patch Stop与 Claude Code 类似首次需通过/hooks授权GitHub CopilotpostToolUseedit\|create\|apply_patch同样的 post-tool-use 模式没有可用的 Stop 深扫描因此每次编辑都跑全量规则CursorpreToolUse在坏写入落地前直接拒绝允许干净写入时保持沉默拒绝消息以工具错误形式可见Grok BuildPostToolUse StopadditionalContext逐编辑扫描只做“标记”finding 在 Stop 时统一上浮不要期待逐编辑提醒——Grok 会丢弃该 stdout其中.ts/.js文件虽然也在扫描范围见 hook_lib.rs 中的ALLOWED_EXTS但默认安静除非检测器真的发现问题否则不会对纯 TS/JS 文件发出确认类输出。双层级规则即时层 Stop 深扫描规则分两层运行这是避免“每次编辑都被海量建议轰炸”的关键设计。即时层immediate tier每次编辑触发只上浮机械性、无歧义、值得打断一次编辑的问题。完整的即时规则清单定义在 registry.rs 的IMMEDIATE_TIER_RULES从源码看共四组 13 条破坏性输出broken-image破图、text-overflow文字溢出、clipped-overflow-container容器裁剪溢出、body-text-viewport-edge正文贴视口边缘客观对比度/可读性失败low-contrast低对比、gray-on-color彩色背景上的灰色文字、tiny-text过小文字单属性机械 slopgradient-text渐变文字、dark-glow发光阴影设计系统漂移design-system-font、design-system-color、design-system-radius、design-system-font-size——这类问题在编辑当下不纠正会不断累积。深扫描层deep pass其余规则文案节奏、调色板与字体品味、布局韵律全部延迟到会话结束的StopHook 事件对本次会话触碰过的每个 UI 文件跑全量规则集并对逐编辑扫描已报告过的内容做去重只上浮一次新问题。会话没有任何遗留问题时Stop 静默退出。从 hook_lib.rs 的per_edit_tiering_active实现可以看到分层并非对所有 Harness 生效pub fn per_edit_tiering_active(config: HookConfig, harness: str) - bool { if harness cursor || harness github { return false; // 没有 Stop 深扫描延迟会导致规则永远不执行 } config.per_edit_rules ! all }即 Cursor 与 GitHub Copilot 没有可用的 Stop 深扫描强制关闭分层、每次编辑跑全量规则否则非即时规则会被静默丢弃Claude Code、Codex、Grok Build 原生分发Stop事件因此走分层。若你想在支持分层的 Harness 上也恢复“每次编辑跑全量规则”在.impeccable/config.json里设置hook.perEditRules: all即可。Grok Build 还有一个细节它在end_turn之后还会补发一次reason: shutdown的 observe-only Stop——必须跳过这次只扫描end_turn否则同样的 finding 会被重复上浮hook.rs 中的 Stop 入口对 Grok 的reason做了专门判断。最后要强调任何 Hook 都是机械化扫描。扫描器抓不到的“手感/直觉”类规则reflexes存在于 craft-floor.mdskill 在编辑 UI 前会加载它所以无论 Hook 是否接线都生效。完全没有自动 Hook 的会话impeccable context会下发一条MANUAL_DETECTOR_REQUIRED指令要求会话结束时手动跑一次检测。配置模型共享配置与本地覆盖Hook 是按项目管理的配置写入.impeccable/config.json统一 Impeccable 配置Hook 运行时设置位于其hook键下共享的检测器忽略规则位于detector键下。每位开发者的本地覆盖包括 CLI 记录的安装同意hook.consent写入被 gitignore 的.impeccable/config.local.json。对应源码 hook_lib.rs 中的默认值HookConfig { enabled: true, quiet: false, audit_log: None, design_system_enabled: true, per_edit_rules: immediate.to_string(), advisory_rules: exclude.to_string(), limits: Limits { max_findings: 5.0, max_chars: 8000.0, max_file_bytes: 131072.0, }, }常用配置项速查配置键默认值作用hook.enabledtrue设为false关闭自动 Hook不影响手动 CLI 扫描hook.quietfalse设为true静默干净/遗留确认消息hook.auditLog无设为文件路径写 NDJSON 审计日志hook.perEditRulesimmediate设为all恢复每次编辑全量规则hook.consent无CLI 在on时记录的本地安装同意config.local.jsondetector.ignoreRules[]项目级整规则忽略detector.ignoreFiles[]匹配文件的全部规则忽略detector.ignoreValues[]规则/取值级忽略可带files与reasondetector.designSystem.enabledtrue设计系统检测开关detector.extensions[]追加服务端模板扩展名见下三个遗留环境变量仍然生效且优先级高于配置文件IMPECCABLE_HOOK_DISABLED、IMPECCABLE_HOOK_QUIET、IMPECCABLE_HOOK_LOG。IMPECCABLE_HOOK_DISABLED1常被当作“跟随 shell 的一次性开关”使用。服务端模板扩展名detector.extensions项目使用 Blade、Twig、ERB 或 Handlebars 文件时必须把扩展名声明在detector.extensions下否则 Hook 会因为它们不在内置扩展名列表中而跳过。一条扩展名一个条目{ ext: .blade.php, engine: html }engine选择分析器html用于标记模板走静态 HTML 引擎text用于 JS/TS/CSS 类文件默认html。匹配方式是文件名末尾匹配因此.blade.php、.html.erb这类双扩展名都能命中。配置只能追加扩展名内置列表始终生效。手动扫描与配置的联动手动npx impeccable detect默认使用同样的项目过滤配置detector.ignoreRules、detector.ignoreFiles、detector.ignoreValues、detector.designSystem.enabled。注意hook.enabled只控制自动 Hook 执行不影响手动 CLI 扫描。需要绕过项目配置/上下文做一次“裸扫描”时用npx impeccable detect --no-config ...要对同样的 detector 忽略规则做直接的 CLI 增删改查则用npx impeccable ignores ...路由动作/impeccable hooks action命令的第一个参数是 action缺省为status。完整路由表与 admin.rs 中的ACTIONS常量一致Action作用status打印当前状态、共享/本地配置路径、被忽略的规则/文件/值、环境变量覆盖on在.impeccable/config.json写入enabled: true在本地记录 hook consent 为 accepted并在 skill 已安装时安装/修复各 provider 的 hook manifestoff在.impeccable/config.json写入enabled: falseignore-rule id把id追加进detector.ignoreRules对overused-font必须加--all-values。项目全局压制该规则ignore-file glob把glob追加进detector.ignoreFiles。匹配文件的所有规则全部压制ignore-value id value [--shared] [--reason ...]追加一条共享的规则/取值压制写.impeccable/config.jsonignore-value id value --local [--reason ...]追加一条私有的规则/取值压制写.impeccable/config.local.jsonignore-value id * --file glob [--file glob...]只在匹配文件中关掉某一条规则其余位置保持生效。--file可重复也支持--fileglob/--filesglob。裸*不带--file会被拒绝真想全局压制请用ignore-rule idreset删除项目配置、去重缓存与 Cursor pending 队列并从on安装过的每个 provider manifest包括已提交的 Copilot 文件中移除 Hook 条目on从不写入的团队共享settings.json不会被触碰status的输出内容对应源码 admin.rs 的status_reportstate、shared file、local file、ignoreRules、ignoreFiles、ignoreValues含文件作用域、maxFindings、maxChars、env override、cache file。配置或本地文件损坏时会以(malformed; ignored)标注。命令流程Flow在 skill 中执行/impeccable hooks时按以下流程走从用户参数解析 action无参数则默认status调用管理脚本并把用户输出原样透传.trae-cn/skills/impeccable/scripts/impeccable hooks action [args...]若 action 为off追加一行说明“Done. New edits will not trigger the design hook in this project until you run/impeccable hooks on.”若 action 为on追加“Done. The design hook will fire after the next Edit/Write on a UI file.”若 action 为ignore-value、ignore-file或ignore-rule直接打印脚本输出即可。默认作用域是共享的.impeccable/config.json只有用户明确要求私有例外时才加--local若 action 为status直接打印脚本输出除非用户追问否则不要添加评论。排查 finding三分法分流与“最窄异常”原则Hook 自身从不直接写 ignore 配置——所有例外都必须经过impeccable hooks这样写入才能被校验、文件结构才能保持一致。收到 finding 时把它分流到三种结果之一真设计问题直接修。永远不要为了跳过修复或放行被拦截的写入而加 ignore确信的误报或合规例外自行持久化最窄的 ignore并在回复中披露。判据必须是可以点名道姓的证据有意的 demo 或 fixture、对坏设计的文档说明、字面或领域恰当的动效比如弹跳的球、或用户已经确认过的选择。把证据写进--reason格式为谁决定的: 证据只有用户真的确认过才写 “user confirmed”不确定保留 finding用一句话问用户。只问一次——一行问题比 Hook 在之后的每次编辑上反复触发便宜得多。自助权限止步于ignore-valueignore-file和ignore-rule静默的范围太大不能凭自己的判断添加必须先问用户。按“最窄异常”递减的优先顺序如果 finding 行给出了ignore-value rule value对就带上--reason执行impeccable hooks ignore-value默认写共享.impeccable/config.json对overused-font、bounce-easing这类取值特定的 finding用ignore-value针对具体取值不要为了一个具体字体用ignore-rule overused-font若 finding 没有取值级命令如side-tab把该规则限定到文件ignore-value id * --file path。执行前先跑npx impeccable detect path看这个文件实际触发了什么只有当整个文件都不在设计审查范围内fixture、生成产物、故意制作的 slop demo时才用ignore-file path——它会永久静默该文件的所有规则包括还没写出来的未来规则一个只是某条规则噪音较多的真实 UI 界面应该用上面的文件级取值 ignoreignore-rule id只在用户要求项目全局压制某条规则时使用对 overused-font 的大范围压制只有用户要求“普遍忽略 overused 字体”时才用ignore-rule overused-font --all-values。默认优先使用上述配置类 ignore把压制集中在一个可审查的地方只有豁免必须随单个文件一起离开仓库时生成/导出的独立文档、通过邮件发送的 HTML 文件才用行内注释。支持标记为impeccable-disable rule整文件、impeccable-disable-line/impeccable-disable-next-line单行任意注释语法均可可在:或--后附加原因。检测器默认尊重行内标记--no-inline-ignores或--no-config可绕过见 detect/src/cli.rs。命令示例取值级例外用户确认 Inter 是有意为之.trae-cn/skills/impeccable/scripts/impeccable hooks ignore-value overused-font Inter --shared --reason User confirmed Inter is intentional自助例外的示例证据点名字面弹球动画bounce easing 正是主题.trae-cn/skills/impeccable/scripts/impeccable hooks ignore-value bounce-easing bounce-ball --shared --reason Agent: literal ball-bounce animation, bounce easing is the subject整规则字体例外.trae-cn/skills/impeccable/scripts/impeccable hooks ignore-rule overused-font --all-values --reason User asked to ignore overused fonts generally“某文件只关某条规则”的例外该文件其余检查仍值得做.trae-cn/skills/impeccable/scripts/impeccable hooks ignore-value design-system-font-size * --file src/overlay/widget.js --reason Injected widget builds its own type scale; DESIGN.mds ramp describes the site整文件例外文件完全不在审查范围.trae-cn/skills/impeccable/scripts/impeccable hooks ignore-file src/legacy/Card.tsx从源码看ignore-value的写入会做惰性条目拒绝admin.rs 的add_ignore_value如果某规则根本没有可提取的 ignore 值直接报错并提示改用ignore-value rule * --file glob——避免写入一条永远匹配不到任何东西的“死配置”。各 Harness 的安装与 manifestHook 随 Impeccable skill 捆绑通过项目级 manifest 安装Harnessmanifest 路径备注Claude Code.claude/settings.local.json项目内被 gitignoreHook 保持机器本地移到共享settings.json也会原位生效Codex.codex/hooks.json项目内首次需通过/hooks授权Cursor.cursor/hooks.json项目内确认 Settings - Hooks 已启用Grok Build.grok/hooks/impeccable.json项目内需要/hooks-trust或--trustGitHub Copilot.github/hooks/impeccable.json项目内团队共享、可提交CLI 与云端 agent 都读它CLI 在文件提交到仓库默认分支后生效各 manifest 的命令形如在 admin.rs 的常量中Claude 用${CLAUDE_PROJECT_DIR}/.claude/skills/impeccable/scripts/impeccable hook并挂PostToolUseStopCodex 走.agents/skills/impeccable/scripts/impeccable hook含 Windows 的.cmdshim 与commandWindowsCursor 走hook-before-editpreToolUseCopilot 走bash形式的$(git rev-parse --show-toplevel)/.github/skills/impeccable/scripts/impeccable hook。on安装时会做manifest 修复识别旧的node hook.mjs形态并改写到 launcher 形态损坏的 manifest 备份为.bak后再写已有的其他 Hook 条目会与 impeccable 条目合并保留。Cursor 的 preToolUse 拦截值得一提hook-before-editbefore_edit.rs会先解析工具输入中提议写入的内容——content/streamContent/text直接取用old_stringnew_string或edits数组则先在原文件上投影出编辑后的完整内容甚至能解析tee、cp、heredoc、PythonPath.write_text等 shell 写入方式——然后运行真实检测器只在确实发现问题时才返回{permission:deny}。拒绝消息会作为工具错误展示给 Agent让它在坏写入落地前重新考虑。该 gate 默认 fail-open超过 1MB 的内容、无法读取的原文件、检测器抛错等场景一律 allow。约束与失败模式约束Constraints绝不要手工改.impeccable/config.json或.impeccable/config.local.json一律走impeccable hooks保证写入被校验、文件结构一致。唯一例外是detector.extensions——它没有管理 action用户要求覆盖某模板栈时直接编辑该字段其余部分不动不要从本流程编辑impeccable hook/impeccable hook-before-edit背后的 launcher 或二进制——那是 skill 内部管道Cursor 能在检测到真实问题时拦截提议写入Claude Code、Codex、GitHub Copilot 不拦截而是发出 post-edit 提醒。关闭 Hook 会同时停掉拦截与提醒。失败模式Failure modes若.impeccable/config.json或.impeccable/config.local.json不可读或畸形Hook忽略该文件用剩余有效配置/默认值运行impeccable hooks status会把畸形文件显示为(malformed; ignored)对应 hook_lib.rs 的safe_read_json容错与 admin.rs 的read_raw_config_file用户说“全局禁用 hook”时先用/impeccable hooks off对项目持久生效写hook.enabled: false遗留的IMPECCABLE_HOOK_DISABLED1环境变量也能作为跟随 shell 的一次性覆盖。底层原理小结去重缓存与审计Hook 的“不重复打扰”建立在会话级缓存上.impeccable/hook.cache.json以session_id为键保存每个文件已报告过的 finding 签名、editCount、clean ack 状态每次编辑 bumpeditCount同一文件同一签名超过阈值EDIT_COUNT_THRESHOLD 6见 hook_lib.rs后Hook 会发出 suppression 提示并停止继续提醒同一问题避免 Agent 被循环打断。Stop 深扫描只对本次会话 touch 过的文件上限STOP_MAX_FILES 20重跑全量规则并对即时层已报告内容去重。所有运行都会在配置hook.auditLog指向的文件里追加 NDJSON 审计记录含harness、event、durationMs、emitted、freshFindings等字段方便事后排查“为什么这条提醒没出现”。这一整套行为都有 crates/hook/tests/hook_tests.rs 等测试用例覆盖例如per_edit_tiering_active断言了 Cursor/GitHub 强制关闭分层、Claude 默认开启分层等关键语义。对团队而言推荐的落地路径是/impeccable hooks status确认状态 →/impeccable hooks on开启并按提示在各 Harness 完成首次授权 → 在真实编辑中根据三分法分流 finding → 用ignore-value沉淀最窄异常共享配置 --reason留痕→ 需要整体退出时/impeccable hooks off或reset清理干净。【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考