Impeccable Live 模式深度解析:浏览器选区 + 三变体生成 + HMR 热切换的实时设计工作流

发布时间:2026/9/5 15:15:22
Impeccable Live 模式深度解析:浏览器选区 + 三变体生成 + HMR 热切换的实时设计工作流 Impeccable Live 模式深度解析浏览器选区 三变体生成 HMR 热切换的实时设计工作流【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable本文围绕 Impeccable 技能包中的 live 模式参考文档 live.md 展开它在浏览器中选中一个元素、选择一个设计动作或自由提示词后由 AI 在现有设计身份内生成 3 个 HTMLCSS 变体通过 dev server 的 HMR 即时热切换用户挑选后接受/丢弃。读完后你将掌握完整的启动命令、轮询协议、变体投递结构、参数旋钮预算、accept/carbonize 清理流程以及各 AI harnessClaude Code / Cursor / Codex的运行策略差异并能结合仓库源码理解 helper 服务、根目录解析与持久化 journal 的底层机制。前置条件与整体契约Live 模式的工作前提是一个带 HMR 的 dev server 正在运行Vite、Next.js、Bun 等或者一个静态 HTML 文件在浏览器中打开。文档特别强调如果 dev server 的默认端口被占用应用很可能已经在运行——先探测默认 URL而不是再启一个 server。整个 live 会话的执行顺序是一份不可跳步、不可重排的契约且任何工具输出中的_instructions字段是该场景下带真实 id 和路径的权威下一步指令当它与文档描述冲突时以_instructions为准live.mjs启动boot。若请求指向 monorepo 内某个具体文件、路由或应用推断出具体路径并以--target path运行随后在返回的projectRoot下继续整个 live 会话。boot 会从 dev-server 配置文件解析应用根目录并持久化到.impeccable/live/roots.json之后每个 helper 启动时都重新锚定该 manifest错误的 cwd 不会分裂出第二份会话状态PRODUCT.md / DESIGN.md 向上搜索直到 git root--file等相对参数按应用根目录解析。打开能服务pageFile的应用 URL从package.json、文档、终端输出或已打开的标签页推断。绝不使用serverPort——那是 helper 服务的端口不是应用的。以默认长超时600000 ms运行轮询循环。每收到一个事件或每次--reply之后立即再跑一次live-poll.mjs不要传短--timeout。全局工具条上的 Impeccable 标记在没有进程轮询/poll时会变暗并显示闪烁的琥珀色圆点——重新运行live-poll.mjs即可重连。收到generate复用event.scaffold如存在、读取截图如有、加载对应动作的 reference、投递变体、--reply done、继续轮询。变体就在当前对话线程里生成——你已持有项目的 tokens 与布局上下文overlay 预览本身就是验证通道generate 与 accept 之间不要截图、重渲染或 QA。收到steer读取消息与pageUrl完成工作后--reply steer_done继续轮询。收到accept/discard轮询脚本已经运行了live-accept.mjs并确认投递打印_completionAck。普通 accept/discard 立即终结carbonize 类型的 accept 保持可恢复状态直到live-complete.mjs --id EVENT_ID完成清理——在再次轮询前必须完成它。若会话中断先运行live-status.mjs或live-resume.mjs再猜。.impeccable/live/sessions/下的 journal 是规范状态helper 重启后会重放未确认的工作页面重新打开时注入的live.js会重新附着。只有当live-resume.mjs报告不存在活跃会话时才回退到直接编辑流程。收到exit执行文末的清理。各 harness 的运行策略文档原文的政策差异值得逐条记住Claude Code将轮询作为后台任务运行不传短超时由 harness 在完成时通知不要阻塞 shell。Cursor在后台终端做一次性轮询并对type:(steer|generate|accept|discard|manual_edit_apply|variant_mount_failed|prefetch|exit)开启通知处理事件、--reply、再重启轮询。Cursor 上不要用--stream实测约 5 秒的拾取延迟而一次性轮询是亚秒级。Codex在让出的前台 exec 会话中运行默认一次性轮询不用、不用--stream绝不在没有活跃前台轮询的情况下离开 Live。启动轮询还不够——必须“服务”它持续读取 exec 会话直到它返回事件。一个没人读的输出让渡轮询就是死会话。其他 harness一次性前台轮询除非你确定 stdout 在 shell 退出时能可靠返回。投递策略所有场景采用原子化单次编辑投递。另外文档定下一条沟通纪律不写总结、不输出教程、不复读 PRODUCT/DESIGN 正文把 token 花在工具和编辑上失败时用一两句话说明即可。启动live.mjs 到底做了什么node .agent/skills/impeccable/scripts/live.mjs # monorepo 子应用 node .agent/skills/impeccable/scripts/live.mjs --target path成功时输出单个 JSON 对象{ ok, serverPort, serverToken, pageFiles, roots, hasProduct, product, productPath, hasDesign, design, designPath, hasSurfaceBrief, surfaceBrief }。其中roots是解析出的根目录 manifestprojectRoot与roots.appRoot相同surface brief 直接随 boot 输出附带不需要再单独调surface-brief.mjs。生成时的优先级是DESIGN.md 决定视觉问题PRODUCT.md 决定持久化的产品与语气问题surface brief 决定当前表面的策略。DESIGN.md 缺失并不意味着身份缺失——从 CSS 变量、计算样式和相邻组件中提取对应后文 Phase A保持身份是默认行为偏离必须来自用户明确的 redesign 意图。要特别分清两个端口serverPort/serverToken属于小型 helper HTTP 服务提供/live.js、SSE、/poll你的页面 URL 才是服务pageFiles条目的那个 origin。源码 live.mjs 展示了 boot 的完整顺序先做 monorepo 目标选择无法消歧时输出target_selection_required并附targetCandidates再通过 live/roots.mjs 解析四元根目录并写入 manifest接着按内容而非路径检查 PRODUCT.md / DESIGN.md 是否可读缺失时输出context_missing并给出下一步命令init或document然后依次跑live-inject.mjs --check校验配置、启动或复用 helper server、按当前端口注入浏览器脚本标签最后做配置漂移扫描。输出中还带有configDrift字段若非 null需一次性告知用户哪些 HTML 文件未被配置覆盖并建议添加文件或把files换成 glob——永远不自动改配置。当输出为{ ok: false, error: config_missing | config_invalid, path }时按 live-setup.md 完成一次性项目配置见文末一节。从 live/roots.mjs 的源码结构看一次 boot 实际解析的是四个随 manifest 一起旅行的根appRootdev server 服务的目录、live 会话状态与注入适配器所在地、repoRootgit 边界非 git 环境回退到 appRoot、contextRoot从 appRoot 向上携带 PRODUCT.md/DESIGN.md 的最近目录、sessionRootappRoot/.impeccable/live持久 live 状态。appRoot 的判定以 dev-server 配置文件的存在为准vite/next/astro/nuxt/svelte 等配置文件清单而不是 monorepo 品牌标记——嵌套的website/里有一个vite.config.js就胜过只有一个package.json的仓库根。manifest 持久化在appRoot/.impeccable/live/roots.json仓库根另存一个指针文件app-root.json因此从仓库内任何目录调用 helper 都会落到 boot 决定的同一组根上。事件 journal 与恢复命令.impeccable/live/sessions/下的 append-only journal 是规范的可恢复状态它不是项目源码的一部分。当聊天被中断、轮询被错过、helper 重启或浏览器重载时用以下三个恢复命令node .agent/skills/impeccable/scripts/live-status.mjs # helper 状态、活跃会话、排队事件helper 挂掉时也能工作 node .agent/skills/impeccable/scripts/live-resume.mjs --id SESSION_ID # 活跃快照、待处理事件、下一步安全动作 node .agent/skills/impeccable/scripts/live-complete.mjs --id SESSION_ID # 验证清理后的规范手工终态确认server 重启规则重新拉起live-server.mjs再轮询即可启动时会重新排队未确认的事件因此除非live-resume.mjs说没有活跃会话否则不要请用户再点一次 Go。源码层面live/session-store.mjs 实现了这套持久化每条事件以{ seq, id, type, ts, event }追加进 journal 文件派生状态快照按 journal 的(path, size, mtime)三元组做缓存键——任何来自其他进程的追加都会使缓存失效并触发完整重放保证序号与阶段围栏phase fence永不取自过期副本快照文件还记录写入时的 journal 字节数使“缓存是否仍然可信”可被证明。helper 服务本体 live-server.mjs 是零依赖的 Node HTTP 服务从 8400 端口起探测可用端口、用 SSE 做 server→browser 推送、HTTP POST 做 browser→server 事件、HTTP 长轮询做 agent 通道并维护pendingEvents等待 agent 确认的浏览器事件队列与pendingPolls等待浏览器事件的 agent 轮询回调。轮询循环与事件分派文档给出的循环骨架默认长超时、不传--timeoutLOOP: node .agent/skills/impeccable/scripts/live-poll.mjs 读取 JSON按 type 分派 generate → 处理生成reply doneLOOP steer → 处理 steerreply steer_doneLOOP accept → 处理接受如需 carbonize 清理则完成LOOP discard → 处理丢弃LOOP prefetch → 处理预取LOOP manual_edit_apply → 处理手动编辑应用reply done|partial|errorLOOP variant_mount_failed → 修复变体文件reply done --file pathLOOP timeout → LOOP exit → break → 清理其中variant_mount_failed表示浏览器无法渲染你发布的内容含variant、模块url、error用户看到的是常驻错误卡片而不是变体。修复变体文件后执行--reply EVENT_ID done --file manifest 或源码路径浏览器会自行重试。--stream是实验性模式一个长活进程、每事件一行 JSON、--reply从另一条命令发出仅适用于能可靠读取增量 stdout 的 harnessCursor 上永远不要用。从 live-poll.mjs 源码可见其实现细节Node 内置 fetch 有 300 秒的 headers 超时上限脚本将单次请求上限压到 270000 ms 并在内部循环合成“长轮询”默认事件租约为 600000 ms--reply id status [--file path] [--data json] [message]的 argv 解析带严格校验缺事件 id、把状态词误当 id、--data非法 JSON 都会抛出带用法说明的错误。处理generate替换模式与插入模式替换模式默认事件形状{id, action, freeformPrompt?, count, pageUrl, element, screenshotPath?, comments?, strokes?}。插入模式event.mode insert{id, mode: insert, count, pageUrl, insert: { position, anchor }, placeholder: { width, height }, freeformPrompt?, screenshotPath?, comments?, strokes?}——没有action要求freeformPrompt或标注非空placeholder只是软性尺寸提示。速度很重要用户在盯着被选中的元素。应复用 preflight 元数据、把发现性调用压到最少。插入模式分支若截图存在则读取仅看标注。若event.scaffold存在则直接用它不要再跑 helper 命令否则node .agent/skills/impeccable/scripts/live-insert.mjs --id EVENT_ID --count EVENT_COUNT --position after \ --element-id ANCHOR_ID --classes class1,class2 --tag section --text ANCHOR_TEXT--position取自event.insert.position锚点 flag 的映射与 wrap 完全一致。脚手架没有data-impeccable-variantoriginal变体是在insertLine处净新增的 HTMLCSS。对 source-preview 目标脚手架带sourceWritten: false与wrapperBlock且replaceEndLine replaceStartLine表示插入在wrapperBlock的标记处拼接变体并在replaceStartLine一次性编辑插入方式与 wrap 章节完全相同。先根据 surface 决定 visitor 模式并在写净新增标记前加载 craft-floor.md。Svelte 目标走与 wrap 相同的组件流程manifest 里mode: insert每个变体是componentDir下真正的单根组件不带data-impeccable-*属性生成期间绝不动路由accept 时机械地把选中标记拼接回sourceFile。非 Svelte 目标 accept/discard 时删除 wrapper锚点不受影响。替换模式读截图、wrap 元素、加载 reference、规划、投递第 1 步读截图如有。event.screenshotPath只在用户点 Go 前做了标注时才发送是元素标注合一的 PNG规划前先读。缺失时不要索要截图或自己截页面——没有标注的截图只会把你锚定在现有设计上与“三个不同方向”的约束相抵触应从element.outerHTML、计算样式和 prompt 出发。标注语义评论的{x, y}是元素本地坐标把文本绑定到该点下方的子元素靠近标题的评论就是关于标题的评论与笔迹默认独立除非明显配对。笔迹按形状解读闭合圈 “这个东西”强调不是裁剪区域箭头 方向或运动十字/斜线 删除涂鸦 视上下文强调或删除。若笔迹意图真实模糊且会改变 brief先问一个简短问题否则用一句话说明你的解读。第 2 步wrap 元素。若event.scaffold存在helper 已经找到源码并算好 wrapper视其为成功输出、跳过命令。event.scaffoldAttempted加上scaffoldError表示 preflight 没走完使用下面的命令node .agent/skills/impeccable/scripts/live-wrap.mjs --id EVENT_ID --count EVENT_COUNT --element-id ELEMENT_ID --classes class1,class2 --tag div --text TEXT_SNIPPETflag 映射保持分离绝不合并进--query--element-id←event.element.id--classes← 逗号连接的类名--tag← tagName--text← textContent 前 ~80 字符每次都要传——它用来消歧重复的兄弟组件缺了它 wrap 会落在第一个匹配上。若event.pageUrl暗示了文件传--file PATH。若--text仍匹配多个候选wrap 退出{ error: element_ambiguous, candidates, fallback: agent-driven }从页面上下文挑出正确区间按 fallback 流程手写 wrapper。成功输出{ file, insertLine, commentSyntax, styleMode, styleTag, cssSelectorPrefixExamples, cssAuthoring }source-preview 目标另带前述sourceWritten: false字段。不经 preflight scaffold 直接运行时它自己写 wrapper你在insertLine处拼接变体。styleMode控制预览 CSS 的写法应视为检测出的能力模式而非框架猜测scoped表示scope ([data-impeccable-variantN])规则astro-global-prefixed表示显式[data-impeccable-variantN]前缀配返回的精确styleTag。把cssAuthoring作为当前文件的唯一事实来源styleTag、选择器策略、要求、禁用模式除非它明确说明否则不套用任何框架特例。source-preview 目标上event.scaffold携带sourceWritten: falsehelper没有写 wrapper而是把scaffold.wrapperBlock和选中元素的源码区间replaceStartLine、replaceEndLine1 起始交给你。wrapper和所有变体必须写进同一次编辑把你的变体拼进wrapperBlock的 Variants: insert below this line 标记处再替换[replaceStartLine, replaceEndLine]行。分开先写 scaffold 会让框架在你的变体写入落地前就重载把浏览器搁浅在 0/N。replaceEndLine replaceStartLine即插入模式只插入、不删除。svelte-component路径从不设置sourceWritten。Svelte/SvelteKit 目标live-wrap.mjs返回previewMode: svelte-componentfile指向临时 manifestnode_modules/.impeccable-live/id/manifest.jsoncomponentDir保存变体组件sourceFile是真正的路由。脚手架基于 AST{#each}、{#if}等控制流块原样存活跨合约的自由 each 集合作为一个结构化 propkindcollection传递。payload 含componentStubMarkup已替换 prop 并写入每个 stub 的标记因此不必回读 manifest 或 stub。就地编辑v1.svelte、v2.svelte……绝不删除重建保留 stub 的控制流与propContract的 prop 名绝不把循环拍平成字面项。stub 的style预置了当前样式化选区的源规则可自由改写或删除——accept 时凡你的变体未重新声明的预置规则会从源中移除预览从未应用它等于用户批准了一个没有它的设计。使用语义化类选择器不用scope、不用data-impeccable-*。用--file指向 manifest 路径回复浏览器挂载编译后的组件Svelte HMR 不会重置页面状态。accept 把选中组件机械地合并回源标记还原到路由表达式、CSS 对账、参数固化、缩进保留此路径上没有 accept 后清理。当选区包含游离预览无法支持的构造组件标签、bind:/use:、await 块、内联脚本、展开属性时wrap 返回previewFallback: { from: svelte-component, reason }的普通 source-preview wrapper照返回形状执行即可。组件预览路径的参数放进 sidecar 而非属性Svelte 会把属性值里的{解析成表达式在componentDir/params.json中按变体号声明schema 与第 7 节相同{ 1: [ {id:density,kind:steps,default:snug,label:Density,options:[ {value:airy,label:Airy},{value:snug,label:Snug} ]} ] }组件style针对var(--p-id, default)range/toggle与[data-p-id…]steps编写并包在:global(...)里使挂载根上的运行时旋钮值能触达你的规则。fallback 错误。wrap 拒绝写入非源码文件生成文件、未跟踪文件——接受进那种文件是静默的数据丢失。三种形态都带fallback: agent-driven见后文 Handle fallbackfile_is_generated--file指向生成文件、element_not_in_source附generatedMatch元素只存在于生成文件、element_not_found很可能是运行时注入的。源码 live-wrap.mjs 印证了这条守卫链它自动搜索时排除生成文件未命中源码时再带includeGenerated搜一遍据此区分“落到 agent-driven 流程”与“元素根本不存在”。第 3 步加载动作 reference。event.action为impeccable自由形态时基于 SKILL.md 的设计规则加 craft-floor.md 干活从 surface 决定 visitor 模式不加载子命令 reference自由形态不是跳过参数的通行证遵守第 7 节的预算与自由形态偏向。其他动作bolder、quieter、distill、polish、typeset、colorize、layout、adapt、animate、delight、overdrive规划前先读reference/action.md其 MUST 参数叠加在第 7 节预算之上。第 4 步规划三个变体——先身份再模式再轴。Live 运行在既有 surface 上品牌已经选定。任务是身份内部的变奏而非在身份之间做选择。最糟的失败是三个用户无法接受的 off-brand 变体。四个阶段按顺序Phase A提取身份不可跳过。来源按优先级DESIGN.md 的视觉系统字段CSS 自定义属性事实上的 tokens选中元素及其父元素的计算样式相邻组件的视觉修辞。写一句话记录屏幕上实际存在的东西主导表面与强调色真实值不是“warm”、已加载的字体配对、布局拓扑堆叠/并排/网格/非对称/叠加、表面处理圆角、边框、阴影、装饰密度、从文案读出的语气。要具体宁可跳过某个轴也不要编造不要给美学家族命名那是结论不是数据。这句话就是身份锁每个变体并排放时必须读起来像同一品牌。DESIGN.md 缺失永远不是借口。Phase B选模式默认 vs 偏离。默认模式保持身份、在其内部改变表达适用于约 90% 的会话。偏离模式拒绝身份仅在当前请求或 prompt 里用户明确要求“redesign this”“rebuild from scratch”“something completely different”时触发过期的 critique 或旧笔记不是授权。不确定就选默认错的默认代价是“三个品牌一致但感觉相近的变体”可恢复错的偏离代价是三个 off-brand 变体不可恢复。Phase C规划三个变体。默认模式下每个变体押注一个不同的主轴保持身份句。六个轴1 层级哪个元素抓住眼球、2 布局拓扑堆叠/并排/网格/非对称/叠加、3 字体系统配对逻辑、比例、大小写/字重在可用字面内、4 色彩策略现有调色板中哪个角色承载表面Restrained/Committed/Full palette/Drenched只用现有 tokens、5 密度minimal/comfortable/dense、6 结构分解合并、拆分、渐进披露。三个变体、三个不同的轴同一品牌的三个角度。新字体、新色相、新美学家族信号只属于偏离模式。偏离模式下每个变体锚定一个源自品牌的不同美学方向不是固定目录读 PRODUCT.md 的 Brand Personality 词汇推导出体现它们的物理、空间或材料体验再从中推导出彼此真正不同、且与当前 surface 不同的三个方向拒绝那种理由放到邻居家产品也成立的惯性选择。每个方向必须是一句具体句子命名一个真实参照物“博物馆展签系统”而不是“clean and minimal”。两种模式下规划时就为每个变体命名 2~3 个参数旋钮第 7 节预算——参数是设计的一部分规划期决定“什么可调”胜过事后补。Phase D眯眼测试。默认模式把每个变体对照 Phase A 锁调色板、字体声音或修辞漂移说明它意外越过了偏离线返工然后确认三个不同的主轴——“三个更紧的密度”就是失败。偏离模式两轮先家族后句子家族轮不可协商给每个变体贴一个你自己选定的具体家族标签标签共享或可互换就返工句子轮把三条一句话描述并排放两条押韵就返工。主轴是色彩或主题时三件套不能共享主题主导色相三个色彩世界而不是三种深浅。各动作的轴要求bolder每个变体放大不同维度尺度/饱和度/结构变化quieter回拉不同维度色彩/装饰/间距distill移除不同类别的冗余视觉噪声/重复内容/嵌套结构polish不同的精修轴节奏/层级/微细节typeset不同的配对且不同的比例colorize每个不同色相家族变化度与对比策略layout不同的结构排布而非间距微调adapt每个变体不同目标上下文mobile-first/tablet/desktop/print 或低带宽animate不同动效词汇级联错峰/clip 擦除/缩放聚焦/形变/视差delight不同个性风味微交互/字体惊喜/插画点缀/声或触觉/彩蛋overdrive打破不同惯例尺度/结构/动效/输入模型/状态转换跳过其“提议并询问”步骤——live 是非交互的。第 5 步应用自由形态 prompt如有。event.freeformPrompt是方向上的上限所有变体遵守它同时在该 Phase B 模式内探索不同解读。默认模式prompt 收窄轴而不收窄身份“more confident” → 一个变体放大层级、一个提交强调色、一个收紧密度。偏离模式prompt 收窄赛道而不收窄家族“newspaper front page” → broadsheet vs tabloid vs trade journal再跑家族轮。prompt 与品牌硬约束或 DESIGN.md 不变量冲突时除非用户明确撤销否则保留不变量。第 6 步投递变体。每个变体是对原元素的完整 HTML 替换不是 CSS-only 补丁预览 CSS 以style标签就地放进 wrapper。原子化默认CSS 全部变体 参数 manifest 在insertLine处一次编辑完成!-- Variants: insert below this line -- style>style>div>node .agent/skills/impeccable/scripts/live-poll.mjs --reply EVENT_ID done --file RELATIVE_PATHRELATIVE_PATH相对项目根dev server 缺 HMR 时浏览器直接拉取源码。然后立即再次轮询。中止进行中的会话若 wrap 或生成在浏览器已切到 GENERATING 之后失败要让浏览器知道并重置工具条node .agent/skills/impeccable/scripts/live-poll.mjs --reply EVENT_ID error Short reason。绝不用live-accept --discard干这件事它是纯文件操作器浏览器看不到工具条会卡在圆点上--discard只用于清理浏览器自己发起的 discard 在源侧的痕迹。处理 fallback当元素真正住在别处当 wrap 返回fallback: agent-driven时源文件由你自选目标不变现在给出三个可预览的变体且被接受的那个要持久化到下一次构建擦不掉的地方从错误 payload 找元素真正所在element_not_in_sourcegeneratedMatch意味着服务的 HTML 是生成出来的去找生成器的模板或 partialelement_not_found意味着运行时注入去找渲染组件或数据源file_is_generated同理解析。纯视觉改动也许应该进共享样式表而不是模板。在“服务的文件”里做预览手工写出live-wrap.mjs会生成的同款 wrapper 脚手架!-- impeccable-variants-start ID --div>node .agent/skills/impeccable/scripts/live-poll.mjs --reply EVENT_ID done \ --data {status:done,appliedEntryIds:[8hexid],failed:[],files:[src/page.html],notes:[]}并非所有条目都应用时用status:partial或status:error加failed[]然后继续轮询。永远不要不带事件 id 回复--reply done --file ...对 manual Apply 无效。退出与清理用户通过聊天说明、关闭标签页SSE 断开poll 约 8 秒后返回exit或浏览器退出按钮来结束 live 模式。收到exit时杀掉所有仍在运行的后台轮询然后清理node .agent/skills/impeccable/scripts/live-server.mjs stop它停掉 helper 并运行live-inject.mjs --remove剥离注入的脚本stop --keep-inject可保留注入以便快速重启.impeccable/live/config.json作为项目配置保留。然后搜索并移除任何残留的impeccable-variants-startwrapper 与impeccable-carbonize-start块。一次性配置要点config_missing / configDrift 时仅当live.mjs报告config_missing/config_invalid、configDrift需要解释、或配置缺cspChecked时按 live-setup.md 操作。配置写在 boot 报告的path默认.impeccable/live/config.json{ files: [path-or-glob, path-or-glob, ...], exclude: [optional-glob, ...], insertBefore: /body, commentSyntax: html, cspChecked: true }files是注入目标——浏览器实际加载的 HTML 文件未必是源码tracked 与 generated 在此无关wrap 有自己的生成文件守卫exclude跳过filesglob 会扫进的文件cspChecked记录 CSP 步骤已跑过。**/node_modules/**与**/.git/**硬排除、不可覆盖。glob 语法**匹配任意段数含零段、*段内匹配、?单字符路径相对项目根、正斜杠。各框架的files/insertBefore/commentSyntax取值表框架filesinsertBeforecommentSyntaxSPA 单壳Vite / React / Plain HTML[index.html]/bodyhtmlNext.jsApp Router[app/layout.tsx]/bodyjsxNext.jsPages[pages/_document.tsx]/bodyjsxNuxt[app.vue]/bodyhtmlSvelte / SvelteKit[src/app.html]/bodyhtmlTanStack RouterSPA, Vite[index.html]/bodyhtmlTanStack StartSSR[src/routes/__root.tsx]ScriptsjsxAstro[root layout .astro]/bodyhtml多页每路由独立 HTML[public/**/*.html]glob/bodyhtml锚点要选每个文件都存在的/body几乎总能用insertAfter是行后匹配。多页站优先用 glob 让新页面自动被拾取。页面由生成器重建时注入只活到下次重生成之前每次构建后重跑live.mjsaccept 不受影响它经 fallback 流程写真源码。框架适配器在注入时自动检测SvelteKit、Nuxt、TanStack Start 服务端渲染文档壳入口模板里的裸script不可靠执行live-inject.mjs会把它们路由到专用适配器SvelteKit来自layout.svelte的 dev-only 根组件Nuxtdev-only.client.ts插件TanStack Start__root里生成的 dev-onlyImpeccableLiveRoot组件files值仍是有效的检测/CSP 提示但不再是字面插入点。每次注入在.impeccable/live/inject-journal.json记录所写内容下一次注入或移除会修复崩溃或错误目录 stop 留下的残迹。CSP 检测仅首次cspChecked true时整节跳过。运行node .agent/skills/impeccable/scripts/detect-csp.mjs输出{ shape, signals }shape 命名的是补丁机制null无 CSP写cspChecked: true结束、append-arrays结构化指令数组可自动打补丁、append-string字面量字符串可自动打补丁、middleware/meta-tag检测到但不自动打补丁请用户手工把http://localhost:8400加进script-src与connect-src后再标记cspChecked: true。自动补丁一律以NODE_ENV development守卫如const __impeccableLiveDev process.env.NODE_ENV development ? [http://localhost:8400] : []只出现在开发环境。参考输出见 nextjs-turborepo 补丁样例、sveltekit-csp 补丁样例、nextjs-inline-csp 补丁样例、nuxt-csp 补丁样例。排障用户曾拒绝 CSP 补丁后报告 live 不工作多半是 dev CSP 挡了 8400——删掉cspChecked重跑live.mjs重新询问。配置完成后重跑live.mjs。小结Impeccable 的 live 模式把“看设计、改设计”压缩成一条可恢复的协议链boot 锚定应用根与项目上下文helper server 用 SSE 长轮询连接浏览器与 agent事件 journal 保证中断可重放三个变体在身份锁内沿不同主轴展开、参数旋钮零成本调节accept 后 carbonize 五步把临时缝合固化成语义化源码live-complete.mjs作为残留闸门收尾。所有环节都围绕两条不变量轮询永不短超时、编辑原子化落地——这两点同时保证了用户在浏览器里看到的预览与最终提交进源码的内容是同一份。【免费下载链接】impeccableThe design language that makes your AI harness better at design.项目地址: https://gitcode.com/GitHub_Trending/im/impeccable创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考