十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

为 AI 编码助手接入 Impeccable 设计检测 Hook:多 Harness 配置、两层检测与异常分级处理完全指南

为 AI 编码助手接入 Impeccable 设计检测 Hook:多 Harness 配置、两层检测与异常分级处理完全指南 为 AI 编码助手接入 Impeccable 设计检测 Hook多 Harness 配置、两层检测与异常分级处理完全指南【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable导读本文围绕 Impeccable 的/impeccable hooks命令完整讲解设计检测钩子design detector hook的机制与配置它如何把设计质量检查嵌入 Claude Code、Codex、Cursor、Grok Build 与 GitHub Copilot 的编辑流程per-edit 即时层与 Stop 深度层如何分工.impeccable/config.json中hook与detector两大配置键如何生效以及status / on / off / ignore-rule / ignore-file / ignore-value / reset各动作的语义。读完本文你将掌握在自己的 AI 编码工作流中安装、验证、调优与按证据最小化豁免设计告警的完整实战方案。钩子是什么一次编辑、一次机械化的设计审查Impeccable 的设计检测钩子会在 Agent直接编辑设计相关文件时运行设计检测器。覆盖的文件类型包括.tsx、.jsx、.html、.vue、.svelte、.astro、.css、.scss、.sass、.less、.ts、.js——这组内置扩展名在源码中被定义为ALLOWED_EXTS见 crates/hook/src/hook_lib.rs。注意hooks.md明确区分了两类文件纯.ts/.js文件虽然仍会被扫描但除非检测器真的发现问题否则保持安静不会输出干净确认。不同 AI 编码工具对钩子事件的支持差异很大因此 Impeccable 为每种 harness 选择了不同的接入形态Claude Code、Codex、GitHub Copilot使用 post-tool-use 钩子Claude Code 为PostToolUse在编辑完成后向 Agent 上下文推送一段简短的系统提醒发现问题时给出修正提示存在待处理问题时再次轻推re-nudge干净且属于 UI 风格的文件则给出简短确认——除非开启了安静模式配置中的hook.quiet。Cursor使用preToolUse在写入落盘之前拦截。检测器对提议写入的内容而不是已落盘的文件运行真实检测只有发现真实问题时才拒绝该写入。拒绝信息会以工具错误的形式对 Agent 可见因此 Agent 有机会在坏写入落地前重新考虑放行干净写入时则保持静默。Grok Build触发同样的 PostToolUse 扫描以标记被触碰的文件然后在 Stop 事件时通过additionalContext把发现的问题呈现出来。不要指望 Grok 提供每次编辑的提醒——Grok 会丢弃 PostToolUse 的 stdout这正是 Stop 深度扫描对 Grok 尤为关键的原因源码注释也在 crates/hook/src/hook.rs 中印证了这一取舍。两层检测机制即时层与深度层检测器规则分两个层级运行这是理解钩子行为的关键per-edit 即时层immediate tier每次编辑后只呈现机械性、无歧义、值得打断一次编辑的问题例如坏图broken images、溢出或裁切内容、对比度与可读性失败、渐变文字、发光阴影、设计系统漂移。这一层级的规则清单在 crates/foundation/src/registry.rs 中被定义为IMMEDIATE_TIER_RULES包括broken-image、text-overflow、clipped-overflow-container、body-text-viewport-edge、low-contrast、gray-on-color、tiny-text、gradient-text、dark-glow、design-system-font、design-system-color、design-system-radius、design-system-font-size。Stop 深度层deep pass其余问题文案节奏、调色板与字体品味、布局节奏等被延迟到 Stop 钩子事件上执行。Stop 深度扫描会针对会话中触碰过的每一个UI 文件运行完整规则集并与 per-edit 层已报告过的问题做去重最后一次性呈现剩余发现如果会话结束时已无任何可报告内容则静默结束。分层逻辑在源码中有两处明确体现split_findings_by_tier按IMMEDIATE_TIER_RULES把发现拆成(immediate, deferred)两组per_edit_tiering_active则按 harness 决定是否启用分层见 crates/hook/src/hook_lib.rs。各 harness 的深度扫描接入情况如下Stop 深度扫描已接线Claude Code、Codex、Grok Build——三者都会派发原生的 Stop 钩子事件。Cursor 不接线其 stop 钩子派发不稳定由 pre-write 网关preToolUse覆盖。GitHub Copilot 不接线其 stop 风格的事件不会把上下文回喂给模型因此 Copilot 的 per-edit 钩子保持完整规则集。此外 Grok 会在end_turn之后额外派发一次reason: shutdown的只观察 Stop 事件。源码中对此有专门处理只有当 Grok 事件的 reason 为end_turn时才执行扫描shutdown等其它 reason 直接跳过避免二次深度扫描重复输出相同问题见 crates/hook/src/hook.rs。恢复完整规则集在.impeccable/config.json中设置hook.perEditRules为all即可在每次编辑时恢复完整规则集。该配置的合法值只有all与immediate默认值解析逻辑见 crates/hook/src/hook_lib.rs。会话去重与重复编辑抑制深度层之所以能去重靠的是会话级缓存。run_hook以event.session_id缺省为unknown为缓存键为每个文件维护editCount与已记住的 findings见 crates/hook/src/hook.rs。当一个文件在同一会话内的编辑次数超过阈值EDIT_COUNT_THRESHOLD源码值为 6见 crates/hook/src/hook_lib.rs时钩子会输出一条抑制通知[impeccable1] Suppressing further design hints on file...避免反复打断同一文件的后续小修改。Stop 深度扫描则只针对touched_files会话缓存中记录的文件并且最多扫描STOP_MAX_FILES20 个文件STOP_MAX_FILES常量定义于 crates/hook/src/hook_lib.rs。无钩子时的兜底每个钩子本质上都是一次机械化的扫描但任何扫描器都抓不到reflexes设计直觉类约束。这些约束记录在 craft-floor.md 中skill 在编辑 UI 之前会加载它因此无论钩子是否接线都会生效。如果某个会话完全没有自动钩子则impeccable context会给出一个MANUAL_DETECTOR_REQUIRED指令要求会话结束时手动运行一次检测器。配置模型共享配置、本地覆盖与遗留环境变量/impeccable hooks命令按项目切换钩子通过编辑.impeccable/config.json实现。这是 Impeccable 的统一配置文件钩子运行时设置位于其hook键下共享的检测器忽略规则位于detector键下。每个开发者级别的覆盖包括 CLI 记录的安装同意决策hook.consent存放在被 gitignore 的.impeccable/config.local.json。源码层面的配置读取顺序是先config.json、后config.local.json依次应用后者覆盖前者见 crates/hook/src/hook_lib.rs。HookConfig的默认值见 crates/hook/src/hook_lib.rsenabled: true、quiet: false、per_edit_rules: immediate、advisory_rules: exclude、limits.maxFindings: 5、limits.maxChars: 8000、limits.maxFileBytes: 131072。hook 键的常用设置配置项作用默认值hook.enabled设为false关闭钩子truehook.quiet设为true静默干净/待处理确认不输出 clean/pending ackfalsehook.auditLog设为文件路径输出 NDJSON 审计日志无hook.perEditRulesimmediate默认或allimmediatehook.consent安装同意决策由 CLI 记录到config.local.json无hook.limits.maxFindings单次输出最大 findings 数5hook.limits.maxChars单次输出最大字符数UTF-168000hook.limits.maxFileBytes超过该字节数的文件跳过扫描131072limits的解析在 crates/hook/src/hook_lib.rs 中实现任何非正数值都会回退到默认值。maxFileBytes生效时超出大小的文件会在审计日志中记录skipped: too-large及实际字节数见 crates/hook/src/hook.rs。遗留环境变量仍然生效且优先级更高以下环境变量被保留兼容且当被设置时会覆盖上述配置值IMPECCABLE_HOOK_DISABLED等价于hook.enabled: false的一次性开关跟随 shell 环境。源码在run_hook/run_stop_hook/hook-before-edit三处入口都会最先检查它并直接返回skipped: env-disabled见 crates/hook/src/hook.rs。IMPECCABLE_HOOK_QUIET等价于hook.quiet: true。IMPECCABLE_HOOK_LOG等价于hook.auditLog。另有IMPECCABLE_HOOK_DEPTH/CLAUDE_HOOK_DEPTH用于防止钩子进程再触发钩子reentrant 保护以及IMPECCABLE_CACHE_ROOT可把可变的钩子状态缓存 待处理队列迁移到项目外的每项目子目录其实现细节见 crates/hook/src/hook_lib.rs。命令路由status / on / off / 三种 ignore / reset/impeccable hooks的第一个参数是动作缺省为status。底层由管理脚本实现仓库内对应 Rust 实现为 crates/hook/src/admin.rs其合法动作表ACTIONS定义于同文件第 19-27 行。动作作用status打印当前状态、共享/本地配置路径、被忽略的规则 / 文件 / 值、环境变量覆盖情况。on在.impeccable/config.json中设置enabled: true在本地配置中记录钩子同意为 accepted并在 skill 已安装时安装/修复各 provider 的钩子 manifest。off在.impeccable/config.json中设置enabled: false。ignore-rule id把id追加到detector.ignoreRules对overused-font规则要求带--all-values。在整个项目范围抑制该规则。ignore-file glob把glob追加到detector.ignoreFiles。对匹配文件抑制所有规则。ignore-value id value [--shared] [--reason ...]向共享的.impeccable/config.json追加一条规则/值级别的抑制。ignore-value id value --local [--reason ...]向私有的.impeccable/config.local.json追加一条私有规则/值抑制。ignore-value id * --file glob [--file glob...]只在匹配文件中关闭某一条规则其余位置保持生效。--file可重复也支持--fileglob/--filesglob。裸*不带--file会被拒绝——如果你确实要项目级抑制请用ignore-rule id。reset删除项目配置、去重缓存与 Cursor 待处理队列并从on会写入的每个 provider manifest 中移除钩子条目——包括已提交的 Copilot 文件但团队共享的settings.jsonon从不写它绝不会被触碰。关于ignore-value有几个值得注意的校验细节见 crates/hook/src/admin.rs--shared与--local不能同时传。通配值*必须配--file限定范围否则报错并提示改用ignore-rule。当value ! *且该规则不存在可提取的忽略值时命令会拒绝写入避免静默添加一条永远匹配不到任何 findings 的惰性条目并提示改用ignore-value rule * --file glob。各动作的行为差异off脚本执行后Agent 应追加一行说明Done. New edits will not trigger the design hook in this project until you run /impeccable hooks on.on脚本执行后Agent 应追加Done. The design hook will fire after the next Edit/Write on a UI file.ignore-value/ignore-file/ignore-rule直接输出脚本结果即可。默认范围是共享的.impeccable/config.json只有当用户明确要求私有例外时才加--local。status直接输出脚本结果除非用户追问否则不要添加评论。status输出的内容在 crates/hook/src/admin.rs 中构造包括 state、shared/local 文件路径若文件格式损坏会标注(malformed; ignored)、ignoreRules/ignoreFiles/ignoreValues列表、maxFindings/maxChars、env override与缓存文件路径。调用流程Agent 侧的执行协议hooks.md规定了/impeccable hooks的标准调用流程从用户的参数中解析动作未给动作时默认为status。调用管理脚本并把用户输出原样透传.hermes/skills/impeccable/scripts/impeccable hooks action [args...]在仓库内该无扩展名文件是启动器 .hermes/skills/impeccable/scripts/impeccableWindows 下对应impeccable.cmd源码注释也说明管理命令的 launcher 形态为self hooks见 crates/hook/src/hook_lib.rs。动作是off时追加一行说明见上节。动作是on时追加一行说明见上节。动作是ignore-value/ignore-file/ignore-rule时只输出脚本结果。动作是status时只输出脚本结果。Findings 分级处理Triage三种处置与最小化例外原则钩子自身从不写任何 ignore 配置——所有例外都必须通过impeccable hooks写入。每一条 finding 都应被分级为三种结果之一真实设计问题修复它。永远不要为了跳过修复或强推一个被拦截的写入而添加 ignore。有把握的误报或经批准的例外自己持久化最窄的例外并在回复中披露。判定的证据必须能具体命名有意的 demo 或 fixture、对坏设计的文档化说明、字面义或领域合适的动效例如一个弹跳的球或用户已确认的选择。把这些证据放进--reason格式为who decided: evidence只有用户确实确认过时才写user confirmed。不确定保留该 finding 并向用户用一行提问。只问一次——一行问题的成本远低于钩子在后续每次编辑时反复触发。自助self-serve止步于ignore-value。ignore-file和ignore-rule静默的范围太大不能仅凭 Agent 自己的判断添加——先问用户。最小化例外从窄到宽的决策阶梯如果 finding 行给出了ignore-value rule value组合就把它传给impeccable hooks ignore-value并附上--reason。默认写入共享的.impeccable/config.json。对值级别的 finding如overused-font、bounce-easing用ignore-value抑制特定值。不要为某个特定字体使用ignore-rule overused-font。如果该 finding 没有值级别的命令如side-tab把这一条规则限定到文件ignore-value id * --file path。先运行npx impeccable detect path看看该文件里实际会触发什么。只有整个文件都不在设计审查范围内时才考虑ignore-file path例如 fixture、生成产物、故意展示的 slop demo。它会让该文件的所有规则永久静默——包括尚未写出来的未来规则。一个真实 UI 表面只有一条吵闹规则时应该用上面的文件级值抑制。只有用户要求项目级抑制整条规则时才用ignore-rule id。对宽泛的 overused-font 抑制只有当用户要求普遍忽略过度使用的字体时才用ignore-rule overused-font --all-values。默认优先使用配置类 ignore上面的命令把抑制放在一个可审查的地方。只有当豁免必须随单个文件一起离开仓库时才考虑行内注释inline comment——例如生成/导出的独立文档、通过邮件发送的 HTML 文件。支持的行内标记是impeccable-disable rule整个文件或impeccable-disable-line/impeccable-disable-next-line单行可用于任意注释语法可在:或--后跟可选原因。检测器默认尊重它--no-inline-ignores或--no-config可绕过。命令示例值级别的字体例外.hermes/skills/impeccable/scripts/impeccable hooks ignore-value overused-font Inter --shared --reason User confirmed Inter is intentional自带证据的自助例外Agent 主动豁免一条字面义动效.hermes/skills/impeccable/scripts/impeccable hooks ignore-value bounce-easing bounce-ball --shared --reason Agent: literal ball-bounce animation, bounce easing is the subject整条规则的字体例外.hermes/skills/impeccable/scripts/impeccable hooks ignore-rule overused-font --all-values --reason User asked to ignore overused fonts generally单规则单文件例外文件仍值得为其它问题审查.hermes/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整文件例外该文件完全不在审查范围内.hermes/skills/impeccable/scripts/impeccable hooks ignore-file src/legacy/Card.tsx从源码看ignore-value的条目会带createdAt与可选的reason/files字段写入detector.ignoreValues见 crates/hook/src/admin.rs而ignore-file只存 glob、明确不支持--reason见 crates/hook/src/admin.rs。服务端模板扩展detector.extensions当项目使用 Blade、Twig、ERB 或 Handlebars 这类服务端模板时需要在detector.extensions下声明扩展名否则钩子会跳过它们它们不在内置扩展名列表中。每条一项{ ext: .blade.php, engine: html }engine选择分析器html用于标记类模板text用于 JS/TS/CSS 类文件默认html。匹配是针对文件名末尾进行的因此.blade.php、.html.erb这类双重扩展名也能工作实现见 crates/hook/src/hook_lib.rs 的match_configured_extension取最长匹配。配置只能新增扩展名内置列表永远生效。配置项也接受字符串简写形式不带engine即视为html归一化逻辑见 crates/hook/src/hook_lib.rs。注意detector.extensions没有对应的 admin 动作因此当用户要求覆盖某个模板栈时应直接编辑.impeccable/config.json中的该字段且保持文件其余部分不动。手动扫描与钩子的关系手动npx impeccable detect扫描默认使用同一套项目过滤配置detector.ignoreRules、detector.ignoreFiles、detector.ignoreValues、detector.designSystem.enabled。hook.enabled只控制自动钩子的执行不影响手动 CLI 扫描。使用npx impeccable detect --no-config ...可获得忽略项目配置/上下文的裸检测器运行。使用npx impeccable ignores ...可对同一套检测器忽略规则做直接的 CLI 增删改查CRUD。hook与detector两个配置节的管理在源码中是分离的write_hook_config与write_detector_config分别维护hook键与detector键后者还会把历史遗留放在hook下的ignoreRules等键迁移合并到detector见 crates/hook/src/admin.rs。各 Harness 的清单安装位置钩子随 Impeccable skill 一起打包并通过项目级 manifest 安装。每个 harness 的 manifest 目标在 crates/hook/src/admin.rs 中定义HarnessManifest 位置要点Claude Code.claude/settings.local.json被 gitignore钩子保持机器本地但如果你把钩子移入共享的.claude/settings.json也会在原位被启用on绝不写团队共享文件reset也绝不触碰。Codex.codex/hooks.json首次使用需用户通过/hooks批准。manifest 中带commandWindows兄弟字段指向 launcher 的.cmdshim同一份.codex/hooks.json可在所有操作系统上运行见 crates/hook/src/admin.rs。Cursor.cursor/hooks.json使用preToolUse需在 Settings - Hooks 确认钩子已启用。Grok Build.grok/hooks/impeccable.json需要/hooks-trust或--trust。GitHub Copilot.github/hooks/impeccable.json团队共享、可提交的文件Copilot CLI 与云端 Agent 都会读取。各 manifest 中实际写入的钩子命令launcher 形态也定义在 crates/hook/src/admin.rsClaude Code${CLAUDE_PROJECT_DIR}/.claude/skills/impeccable/scripts/impeccable hook事件为PostToolUsematcherEdit|Write与Stop。Codex.agents/skills/impeccable/scripts/impeccableWindows 用.cmd事件为PostToolUsematcherEdit|Write|apply_patch与Stop。Cursor.cursor/skills/impeccable/scripts/impeccable hook-before-edit事件为preToolUse超时 5 秒。GitHub Copilot$(git rev-parse --show-toplevel)/.github/skills/impeccable/scripts/impeccable hook事件为postToolUsematcheredit|create|apply_patchtimeoutSec为 5。关于 Copilot 的生效时机文档明确指出repo 级钩子一旦把.github/hooks/impeccable.json提交到仓库的默认分支Copilot CLI 就会加载它云端 Agent 则直接从 repo 读取。on动作还会做一次安装或修复repair_hook_manifests会检查每个 provider 的 skill 目录是否存在缺失时跳过、存在时写入/合并 manifest遇到格式损坏的 manifest 会先备份为.bak再重写见 crates/hook/src/admin.rs。Cursor preToolUse 网关的细节在 Cursor 上hook-before-edit源码为 crates/hook/src/before_edit.rs会检查提议的 Write/Edit/Shell 写入内容只有真实检测器发现问题时才拒绝。它不会直接读取磁盘文件而是从事件中提取提议内容从content/streamContent/text字段读取完整内容对 fragment 型编辑old_string/new_string或edits数组会读取现有文件并投影出编辑后的完整内容再检测对 shell 写入重定向、tee、cp、python的Path.write_text/open、heredoc也能解析出目标文件与内容见 crates/hook/src/before_edit.rs。拒绝时返回的 JSON 形如{permission:deny,user_message:...,agent_message:...}拒绝消息对 Agent 可见crates/hook/src/before_edit.rs。当同一文件同一 finding 签名被重复拒绝超过EDIT_COUNT_THRESHOLD次时网关会降级为放行并附带警告避免死循环见 crates/hook/src/before_edit.rs。扫描内容上限为 1 MiB超过则 fail-open 放行MAX_SCANNED_BYTES见 crates/hook/src/before_edit.rs。约束什么不能做绝不要从本命令手工修改.impeccable/config.json或.impeccable/config.local.json。始终通过impeccable hooks写入让写入保持校验、文件结构保持一致。唯一例外是上文提到的detector.extensions。不要从本流程修改 launcher 或impeccable hook/impeccable hook-before-edit背后的二进制——那是 skill 的 plumbing。阻断语义因 harness 而异Cursor 能在真实问题时拦截提议写入Claude Code、Codex、GitHub Copilot 不阻断编辑而是发出 post-edit 提醒。禁用钩子会同时关掉阻断与提醒。失败模式与恢复如果.impeccable/config.json或.impeccable/config.local.json不可读或格式损坏钩子会忽略该文件使用剩余的合法配置/默认值继续运行impeccable hooks status会把损坏文件显示为(malformed; ignored)实现见 crates/hook/src/admin.rs。如果用户要求全局禁用钩子先引导执行/impeccable hooks off对本项目持久生效向配置写入hook.enabled: false。遗留的IMPECCABLE_HOOK_DISABLED1环境变量同样可以作为跟随 shell 的一次性覆盖。钩子进程本身永远返回退出码 0stdout 要么是一段 JSON 文档要么为空见 crates/hook/src/hook.rs因此钩子崩溃不会把 Agent 的编辑流程拖垮——这符合机械性扫描的定位发现问题时提醒出问题时静默。结语/impeccable hooks把设计审查从事后人工检查前移到了 Agent 的每一次编辑动作中并且对不同 AI 编码工具的钩子能力做了差异化适配有 Stop 深度的 harness 走即时层 深度层两级去重没有的则保持完整规则集能阻断写入的 Cursor 走 pre-write 网关其余 harness 走 post-edit 提醒。其配置哲学也很一致——所有豁免都通过命令写入统一配置文件、默认共享、支持本地私有覆盖、要求最小化与证据化。要验证当前项目的钩子状态直接运行impeccable hooks status它会一次性告诉你启停状态、共享/本地配置路径、全部 ignore 列表与环境变量覆盖情况。【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表