首页
/ Impeccable Live 模式接入配置:写配置、适配框架注入、自动放行 CSP 的一站式设置指南

Impeccable Live 模式接入配置:写配置、适配框架注入、自动放行 CSP 的一站式设置指南

2026-09-07 15:41:19作者:凤尚柏Louis

导读:Impeccable 的 live-setup.md 描述了 live 变体模式(在浏览器里选中元素、生成 HTML+CSS 变体并通过 HMR 热替换)的一次性项目配置流程——即 live.mjs 首次启动回报 config_missing / config_invalid / configDrift、或配置缺少 cspChecked 字段时的处理手册。本文从这份文档出发,结合仓库内的测试 fixture 与脚本实现,讲透 .impeccable/live/config.json 的完整 schema、各框架注入点对照表、注入日志自愈机制、配置漂移处理,以及"检测 CSP → 询问用户 → 按 shape 打补丁"的完整链路。读完你可以独立为任何 Vite / Next.js / Nuxt / SvelteKit / Astro / TanStack 项目完成 live 模式的首次接入。

这份文档在 live 模式里的角色

Impeccable 的 live 模式采用 "boot → 轮询事件 → 处理事件" 的运行模型,其运行契约与事件分派定义在 live.md。而 live-setup 属于一次性启动设置,与每次会话的热路径无关,只在以下三种情况下被 live.md 加载:

  • live.mjs 启动时返回 config_missing(配置不存在)或 config_invalid(配置不合法);
  • 返回的 configDrift 非空,需要向用户解释未覆盖的 HTML 文件;
  • 配置中缺少 cspChecked 字段(首次设置必须执行 CSP 检测)。

也就是说:live-setup 拥有配置 schema、跨框架 files 表、注入适配器、漂移自愈以及 CSP 检测与征询流程的全部权责。日常轮询热路径中的 generate / steer / accept / discard 处理一律不回读本文件。

仓库中存在该 skill 的多份分发副本,例如 .opencode/skills/impeccable/reference/live-setup.md.claude/skills/impeccable/reference/live-setup.mdskill/reference/live-setup.mdplugin/skills/impeccable/reference/live-setup.md 等,内容一致、面向不同 Agent 宿主分发。

一、写入 .impeccable/live/config.json

1.1 配置文件位置与完整 schema

创建 live.mjs 启动时回报的 path(默认 .impeccable/live/config.json),内容如下:

{
  "files": ["<path-or-glob>", "<path-or-glob>", ...],
  "exclude": ["<optional-glob>", ...],
  "insertBefore": "</body>",
  "commentSyntax": "html",
  "cspChecked": true
}

各字段语义:

字段 必填 含义
files 注入目标:浏览器实际加载的 HTML 文件路径或 glob。注意它不一定是源码——是"页面被加载的入口";trackedgenerated 在此并不重要(wrap 阶段另有针对生成文件的守卫)
exclude 排除 glob:把 files 中 glob 命中的文件再剔除掉(如邮件模板、demo fixture)
insertBefore 注入锚点,默认 </body>
commentSyntax 注入文件使用的注释语法,htmljsxhtml 对应注释 <!-- -->jsx 对应 {/* */}
cspChecked 首次缺失 记录下方的 CSP 检测步骤是否已执行;首次设置时缺省

硬性排除路径(不可覆盖): **/node_modules/****/.git/**。向这两个目录注入等价于插桩第三方代码,任何配置都不允许写入。

Glob 语法: ** 匹配任意数量段(含零段),* 匹配段内任意字符,? 匹配单字符。路径一律相对项目根、使用正斜杠。

从源码结构看,config 会被扩展分发到前端 overlay:live 服务器把 .impeccable/config.json + config.local.json 的检测器忽略规则、连同注入配置 files glob 的 served-root 前缀一起序列化进 window.__IMPECCABLE_PROJECT_IGNORES__(见 live-browser-ignores.js),保证 overlay 端与 CLI、edit hook 端对检测结果的抑制口径一致。

1.2 跨框架注入点对照表

live-setup 内置一张按框架区分的注入点表,选锚点的原则是该锚点必须存在于每个目标文件中</body> 几乎总是成立):

框架 files insertBefore commentSyntax
SPA 单壳(Vite / React / Plain HTML) ["index.html"] </body> html
Next.js(App Router) ["app/layout.tsx"] </body> jsx
Next.js(Pages) ["pages/_document.tsx"] </body> jsx
Nuxt ["app.vue"] </body> html
Svelte / SvelteKit ["src/app.html"] </body> html
TanStack Router(SPA, Vite) ["index.html"] </body> html
TanStack Start(SSR) ["src/routes/__root.tsx"] <Scripts jsx
Astro ["<root layout .astro>"] </body> html
多页站点(每路由独立 HTML) ["public/**/*.html"] 服务目录 glob </body> html

实践要点:

  • 多页站点优先用 glob,这样新页面自动被覆盖,无需每次新增页面都改配置;
  • 生成器重建页面的站点,注入只存活到下次再生成:每次 build 后需重跑 live.mjs。不过 accept 不受影响——它走 fallback 流程把结果写入真正的源码;
  • insertAfterinsertBefore 对应两种定位方式:前者匹配在某行之后插入。

测试仓库里正是用一套 fixture 来固化这套配置解析行为。例如 tests/framework-fixtures/README.md 特别强调:nextjs-app/app/layout.tsx 作为 JSX 注入目标(commentSyntax: "jsx");而测试会把 live 配置写在与 fixture 同级的 tmp 根,因此 config.files 必须既能从仓库根解析又能从 app 根解析——此时写 glob "**/index.html" 两边都满足,写字面量 "index.html" 则只从 app 根有效,静态扫描会回报 file_not_found。这是配置与测试基建耦合的一个鲜活示例。

1.3 框架适配器:注入时自动探测

每次注入都会把写入结果记录在 .impeccable/live/inject-journal.json;下一次注入或移除时,会先自愈崩溃或错误目录停止遗留下的半成品。

SvelteKit、Nuxt、TanStack Start 会服务端渲染 document shell,在入口模板里塞裸 <script> 无法可靠执行,所以 live-inject.mjs 会探测到它们并路由到专用适配器

  • SvelteKit:从 +layout.svelte 派生一个 dev-only 根组件;
  • Nuxt:写一个 dev-only .client.ts 插件;
  • TanStack Start:在 __root 中生成 dev-only 的 ImpeccableLiveRoot 组件。

此时 files 的值仍作为合法的检测/CSP 提示被保留,但不再是字面的插入点。普通 TanStack Router SPA 则走基线 Vite 路径。

1.4 配置漂移:configDrift

每次 boot 时,live 会在常见页面根(public/src/app/pages/)下扫描 HTML 文件,凡不属于已解析 files 列表覆盖范围的,都会作为 configDrift.orphans 呈现,并附带提示。处理规则:

  • 每个会话只向用户汇报一次:哪些文件尚未被覆盖;
  • 建议用户追加这些文件或将 files 换成 glob
  • 绝不自动更新配置——决定权在用户;
  • 无漂移时 configDriftnull

二、CSP 检测(仅首次设置)

如果 config.cspChecked === true,跳过整节——用户已经被问过一次。否则执行检测脚本:

node .opencode/skills/impeccable/scripts/detect-csp.mjs

输出 { shape, signals }shape 命名的是补丁机制(patch mechanism),因此一套模板可以覆盖多个框架:

shape 含义 可否自动打补丁 典型场景
null 无 CSP —— 直接写配置 cspChecked: true 结束
append-arrays CSP 是结构化指令数组 monorepo helper 的 additionalScriptSrc / additionalConnectSrc、SvelteKit kit.csp.directives、Nuxt nuxt-security
append-string CSP 是字面字符串值 内联 next.config.*headers()、Nuxt routeRules
middleware / meta-tag 已检测但无法自动补丁 展示检测到的文件,请用户手动把 http://localhost:8400 加进 script-srcconnect-src,再标记 cspChecked: true

2.1 征询话术(Consent Prompt)

向用户展示将要执行的改动,并请求确认,标准话术如下:

CSP patch needed. I detected a Content Security Policy in your project that blocks http://localhost:8400: the live picker won't load without an allowance. Here's the change I'd make:

[file: <patchTarget>]
[exact diff, 2-5 lines]

It's guarded by NODE_ENV === "development" so the extra entry only appears in dev and never reaches production. You can remove it any time by reverting this file. Apply? [y/n]

分支处理:

  • 用户答 no:跳过补丁,提示"直到手动添加放行否则 live 无法工作",但仍写入 cspChecked: true(问题已经问过,不再重复打扰);
  • 用户答 yes:按 shape 应用补丁,再写 cspChecked: true

2.2 append-arrays:向指令数组追加

在持有 CSP 数组的文件顶部声明 dev-only 常量:

// Dev-only allowance so impeccable live mode can load. Guarded by NODE_ENV.
const __impeccableLiveDev =
  process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];

然后把它展开进 script-srcconnect-src 两个数组。分框架落点:

  • Next.js + monorepo helper:编辑 app 自身next.config.*(不是共享 helper),追加 additionalScriptSrc / additionalConnectSrc
  • SvelteKitsvelte.config.jskit.csp.directives['script-src']['connect-src']
  • Nuxt + nuxt-securitynuxt.config.*security.headers.contentSecurityPolicy['script-src']['connect-src']

仓库用 fixture 固化了两份人类/Agent 评审用的补丁参考输出:

幂等性:如果文件里已存在 __impeccableLiveDev,说明补丁已应用过——只需标记 cspChecked: true,不要重复声明。

2.3 append-string:向字面字符串插值

两步补丁:声明 dev-only 字符串,再把它插值进 CSP 值的两个指令处(前导空格保证拼接干净;编辑时把字面量转成模板字符串):

// Dev-only allowance so impeccable live mode can load.
const __impeccableLiveDev =
  process.env.NODE_ENV === "development" ? " http://localhost:8400" : "";

转换示意:

  • script-src 'self' 'unsafe-inline' 变为 `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}`
  • connect-src 'self' 变为 `connect-src 'self'${__impeccableLiveDev}`

分框架落点:Next.js 内联 headers()next.config.*);Nuxt 的 routeRules['/**'].headers['Content-Security-Policy']nuxt.config.*)。参考输出见 tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.jstests/framework-fixtures/nuxt-csp/expected-after-patch.ts

三、故障排查与收尾

3.1 用户拒绝 CSP 补丁导致 live 不可用

如果用户当时答了 "no",事后回报 live 无法工作:原因是 dev CSP 挡住了 http://localhost:8400。处理办法是把 cspChecked.impeccable/live/config.json 中删掉,再重跑 live.mjs——设置流程会再次询问。

3.2 设置完成后的标准动作

设置完成后重跑 live.mjs。此时 boot 应返回 { ok: true, ... } 进入正常 live 会话;若仍带 configDrift,按 1.4 节 只汇报一次并交由用户决策。

四、仓库中的佐证与延伸阅读

五、速查清单

接入一个新项目的 live 模式,一次跑通的最小路径:

  1. 首次运行 live.mjs,接受返回的 config_missing / config_invalid
  2. 1.1 节 的 schema 在 boot 报告的 path 写入 .impeccable/live/config.json,从 1.2 节 查表的 files / insertBefore / commentSyntax 取值,cspChecked 先留空;
  3. detect-csp.mjs,按输出 shape 决定:null 直接收尾,append-arrays / append-string 走征询-自动补丁(NODE_ENV === "development" 守卫,可随时 revert),middleware / meta-tag 手动放行 http://localhost:8400
  4. 标记 cspChecked: true 并重跑 live.mjs,按需解释 configDrift
  5. 若之后 CSP 相关的 live 失效,删除 cspChecked 重新触发询问即可。
登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391