1实现原理 · 为什么它能做到
核心交付物是两份『种子模板』:assets/template.html(杂志风)与 assets/template-swiss.html(瑞士风)。CSS、WebGL shader、翻页 JS、演讲者模式、观众屏同步全部预置,agent 只需拷贝模板 + 填 `<!-- SLIDES_HERE -->` 与 SPEAKER_NOTES。
两个 `template*.html` 都是**完整可运行**的文件——CSS、WebGL shader、翻页 JS、演讲者模式、观众屏同步、字体/图标 CDN 全已预设好,只有 `<!-- SLIDES_HERE -->` 占位符和 `SPEAKER_NOTES` 等待你填充。
实现原理本质是『把设计决策前置成规格文件』:5 套/4 套主题色、10 种/22 种版式、字体分工、字号字重阶梯都写死在 references 里,agent 只能选不能造。
本 skill **只允许从 5 套精心调配的预设里选一套**,不接受用户自定义 hex 值——颜色搭配错了画面瞬间变丑,保护美学比给自由更重要。
把『类名必须在模板 <style> 里有定义』做成写码前的强制预检(Step 3.0),并指出这是所有生成问题的源头。
**这是所有生成问题的源头**。layouts 骨架使用了很多类名,如果模板的 `<style>` 里没有对应定义,浏览器会 fallback 到默认样式——大标题字体错、卡片挤成一团、pipeline 糊成一行、图片堆到页面底部。
用 Node 脚本做确定性校验,替模型补上『看不见版式好坏』的短板:静态检查 + 可选 Playwright 真实渲染测量。
校验器会先做静态结构检查;如果环境中能解析到 Playwright,还会做真实渲染后的可见边界、底部空白、nav 安全线和标题间距测量。
『先量后改』的修正阶梯把审美问题变成可执行阈值,避免模型凭感觉大删内容。
`1-40px` over:只微调,上移内容组或收紧一个 gap/padding,不要删内容。
启动前检查上游更新,且明确『不自动更新』——需要 git fetch 取差异、用户确认后才 pull。
不要自动更新。用户拒绝时继续使用当前版本;如果网络不可用、没有 upstream 或不是 git 仓库,说明无法检查更新并继续流程。
演讲者模式不是装饰:脚本强制页面 ID 稳定、备注与页面按 ID 对齐(而非数组下标),并校验时长预算与运行时控件完备性。
备注按页面 ID 存储,不要用数组下标或页码作为持久化键,否则页面重排后用户在演讲者视图里改过的备注会串页。
资源加载双保险 + 降级:Motion 先试本地 assets/motion.min.js,失败再走 CDN,双双失败则把 `[data-anim]` 强制可见,保证内容可读;瑞士风另有 B 键低功耗模式停 RAF 与动效。
console.warn('[motion] local + CDN both failed, disabling animations', e1, e2);
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| cli | git(Step 0 检查上游更新;pull 需用户确认) |
| cli | node(跑三个校验脚本;校验器可选解析 Playwright) |
| package | Playwright(可选;能解析到时启动 chromium 做渲染测量) |
| network | Google Fonts(模板 <head> 预连接并加载 Playfair Display / Source Serif 4 / IBM Plex Mono / Noto Serif SC / Noto Sans SC) |
| network | Lucide 图标(unpkg,注意是 @latest 浮动版本) |
| network | Motion One(jsDelivr ESM,仅在本地 assets/motion.min.js 加载失败时作为兜底) |
| network | MapLibre GL JS + OpenStreetMap 栅格瓦片(仅瑞士风 S08 地图组件页,用户需要地图时才引入) |
| api | GPT-M 2.0 配图生成(Codex 场景下由宿主 agent 调用,skill 只给提示词与比例规则,无端点硬编码) |
4风险提醒 风险提醒:黄色 · 留意使用
- 运行期依赖公开 CDN,其中 Lucide 用 @latest 浮动版本 — unpkg.com/lucide@latest/dist/umd/lucide.min.js 未 pin 版本;字体走 fonts.googleapis.com。断网或 CDN 变更会让演示页外观退化(内容仍可读);若投毒则进入页面执行环境,skill 侧无 SRI/完整性校验。
- Step 0 会拉取并改写 skill 自身 — git fetch +(用户确认后)git pull --ff-only。虽明示『不要自动更新』,但更新后的 SKILL.md/模板即为新代码,使用者实际是在信任上游最新提交。
- 瑞士风的约束极强,超出 22 个登记版式的需求会被迫将就 — 默认正文页只能用 S01–S22,且校验脚本会把未登记 data-layout 当问题报出(除非加 --allow-experimental)。特殊叙事结构需要用户显式同意走实验版式。
- 质量仍依赖人眼终检 — SKILL.md 自陈 '代码只能证明类名和结构存在,不能证明版式舒服',要求逐页打开对照,并提示截图前等 1-2 秒动效稳定;纯自动化跑完不保证观感。
- 许可为 AGPL-3.0,且仓库含赞助/品牌内容 — AGPL-3.0 对二次分发/网络服务化有传染性要求;SKILL.md 顶部与 provenance 注释含赞助方信息,并要求不得写入生成产物——使用者需自行确认合规口径。
- 校验脚本对环境的可选依赖会造成『静默降级』 — 解析不到 Playwright 时只推一条 warning('Rendered measurement skipped...')就继续,静态检查通过不等于版式没问题,容易被误读为已验收。
5第二遍独立确认
- [ok] skill.path 定位(任务表标『待定位』) — 仓库根即有 SKILL.md(git ls-tree 根层含 SKILL.md),assets/references/scripts 均位于根下同级,故 path=".";全仓 SKILL.md 计数为 1,不存在第二份。
- [ok] 三个校验脚本『只读』结论的反例搜索 — 全仓 grep 未发现 writeFileSync/createWriteStream/fs.write;validate-swiss-deck.mjs 顶部为 readFileSync + createRequire + pathToFileURL,Playwright 段为 launch/newContext/close;check-presenter-runtime-sync.mjs 为 readFileSync + 字符串比对。脚本输出走 console 与 process.exit(2)。
- [ok] 『无凭证读取』是否漏网 — api_key/API_KEY/token/secret/.env/os.environ/process.env/keychain 全仓扫描零命中。配图走 GPT-M 2.0(宿主能力)、更新走 git(用户既有凭证),skill 文本未要求读取任何密钥;MapLibre OSM 瓦片为公开无 key 服务。
- [ok] Step 0 自更新:是否会自动 pull — SKILL.md 原文 '有更新时先问用户是否要更新,用户确认后再执行更新' + '不要自动更新。用户拒绝时继续使用当前版本',且网络不可用/无 upstream/非 git 仓库时明确跳过继续流程。属用户确认型动作,非静默自更新。
- [discrepancy] CDN 依赖是否被低估(@latest 浮动版本) — 第一遍只记『字体/图标 CDN』;第二遍逐个 grep 模板发现 Lucide 走的是 `unpkg.com/lucide@latest`(浮动主版本,未 pin),而 Motion 是 pin 到 11.11.17 且有本地副本。已在 external_deps 与 security.reason 中显式点名该浮动风险(供应链面),并保留其余 CDN 条目。
- [ok] 『离线可用』宣称是否成立 — Motion 有本地 assets/motion.min.js 且失败时强制 reveal `[data-anim]`(template.html 内可见 console.warn 兜底分支);瑞士风有 body.low-power 静态模式(CSS 里 display:none 掉 canvas.bg/ascii-bg、animation/transition: none)。但字体与 Lucide 图标仍走外网——离线时字体退回系统栈/图标缺失,属『内容可读但外观退化』,SKILL.md 未把完全离线列为承诺,故不算夸大。
- [ok] 『S01–S22 版式锁定』是否真有约束力 — SKILL.md 要求每个 <section> 写 data-layout="Sxx" 并明示无 data-layout 视为未登记版式;validate-swiss-deck.mjs 以 --allow-experimental 开关区分实验版式;22 个 S 编号在 SKILL.md 表格中完整列出(S01 Index Cover … S22 Image Hero),与 layouts-swiss.md 骨架对应。
- [ok] license 档位核对 — 第一遍未写许可;第二遍读 LICENSE 首行确认为 GNU AGPL-3.0 文本,与 gh api 的 spdx_id=AGPL-3.0 一致,已在 meta.license 与 traits 中提示(对闭源二次分发有影响)。
6结论
81dbd0381b0986e8…c91369c449