1实现原理 · 为什么它能做到
该 skill 不是可执行程序,而是 html-anything 的「模板」:一个目录(SKILL.md + example.html[/example.md]),由 loader.ts 在运行时扫盘读取——新增模板=新增目录,不需要改 TypeScript。
Adding a template = adding a folder. No TS code change required; the API
frontmatter 是给选择器/API 的元数据(zh_name/en_name/emoji/description/category/scenario/aspect_hint/featured/recommended/tags),由 fmToMeta() 映射成 SkillMeta;frontmatter 之后的正文才是给模型的规格。
zhName: fm.zh_name ?? fm.name ?? id,
生成时该模板正文被当成 prompt body:/api/convert 用 assemblePrompt() 把「全局设计指令 + 本模板正文 + 用户内容」拼成一段 prompt,交给宿主的本地 agent CLI,HTML 由 stdout 流式捕获。
prompt = assemblePrompt({ body: skill.body, content, format });
模板正文之上还压着一段全局前置指令(SHARED_DESIGN_DIRECTIVES),把技术与内容纪律统一加在每个模板之前——示例 HTML 里普遍出现的 CDN/字体外链就源自这里(宿主壳注入,不是模板自身要求)。
通过 CDN 引入 Tailwind v3 Play (https://cdn.tailwindcss.com) 与所需的 Google Fonts。
产物以 stdout 文本返回:全局指令显式禁止 agent 动用文件系统,落盘由前端负责——所以模板目录既无脚本也无写盘能力。
**禁止使用 Write / Edit / MultiEdit / Bash / Create / 任何文件系统工具**。
example.html 是随包预渲染示例:/api/templates/<id>/preview 原样按 text/html 返回给 iframe(选择器内联预览),/api/templates/<id>/example 另把 example.md + example.html 一起返回。
return new Response(skill.exampleHtml, {
正文把「帧」定成机器可读的连续 <section class="frame">(1920×1080),帧数由内容密度决定而非固定值——短脚本 6-10 帧起步,每帧只承载一个镜头/概念。
- 输出 N 个连续 `<section class="frame">`, 每个 `w-[1920px] h-[1080px]`; N 由【用户内容】信息密度决定
每帧底部埋隐藏标记 `<!-- frame:N duration:3000 transition:fade -->`,文件末尾再附一段 `<!-- HYPERFRAMES_META: ... -->` JSON(duration/transition/sceneSummary),供后续 Remotion 渲染脚本读取。
- 每帧底部隐藏标记 `<!-- frame:N duration:3000 transition:fade -->` 供后续 Remotion / Hyperframes 渲染脚本读取。
自动播放是模板正文的硬要求:顶部一段 JavaScript 每 3 秒切帧,支持点击/方向键,角落显示进度条。
- 顶部加一段 JavaScript 自动播放: 每 3 秒切换到下一帧, 也支持点击 / 方向键控制; 角落显示进度条。
叙事结构被写进模板:第 1 帧是 hook(一个数据/反常识/问题),第 2-N 是论证,最后一帧是结论 + CTA,字号巨大、一句话即可。
- 第 1 帧是 hook (一个数据 / 一个反常识 / 一个问题), 第 2-N 是论证, 最后是结论 + CTA。
应用侧真的消费这套约定:export-menu.tsx 检测到 frame 结构后,额外提供 Remotion zip 导出(parseHyperframes → exportRemotionZip)。
await exportRemotionZip(hyperframes, hyperframes.title, {
CLI 侧另有一条关键词直配通道:skills-matcher.ts 把用户内容里的关键词直接映射到该模板 id,命中即给 confidence=命中数×2+3,达到阈值 3 就走本地规则、不再让模型挑模板。
[["视频", "video", "帧动画", "hyperframes", "remotion", "mp4", "片头"], "video-hyperframes"],
CLI 兜底匹配用到的阈值常量:内容长度需超过 60 字符才启用 AI 摘要匹配;强信号阈值是 3。
const MIN_CONTENT_LENGTH_FOR_AI = 60;
宿主壳用 sandbox="allow-scripts allow-same-origin" 的 iframe 渲染示例/产物(允许脚本、允许同源)——这是产品壳取舍,写进风险,不参与本 skill 判级。
sandbox="allow-scripts allow-same-origin"
2核心能力
3外部依赖
| 类型 | 依赖 |
|---|---|
| network | Tailwind CDN(示例 HTML 引用) |
| network | Google Fonts(Inter Tight / Noto Sans SC / JetBrains Mono) |
| network | 上游项目(frontmatter 元数据,非运行依赖) |
4风险提醒 风险提醒:绿色 · 放心使用
- 示例未演示行内 frame 标记 — SKILL.md 指定每帧底部埋 `<!-- frame:N duration:3000 transition:fade -->`,但示例 8 帧里该标记出现次数为 0(改用 data-duration 属性);宿主解析器两种都支持(注释提到 fall back to per-frame `data-duration` / inline-comment markers),但只看示例的用户会漏掉这一约定。
- 自动播放与无障碍 — 正文要求每 3 秒自动切帧(示例时长 3-5s 不等),未要求 prefers-reduced-motion 降级或暂停语义;对前庭敏感用户不友好,示例虽有播放/暂停按钮但默认自动播放。
- META JSON 容错靠宿主 — 宿主解析器注释自述 agents sometimes emit slightly invalid JSON 时只做兜底,不报错;元数据合法性最终取决于模型输出。
- 预览侧脚本与 CDN — 示例含 Tailwind CDN 与外链字体,且内联播放器脚本在宿主 iframe(allow-scripts + allow-same-origin)内运行,属产物/宿主行为。
5第二遍独立确认
- [ok] skill 目录文件清单 — find 得 SKILL.md + example.html + example.md,无 scripts/references。
- [ok] 外部端点只出现在示例/元数据 — SKILL.md 正文无 URL;URL 分别位于 frontmatter example_source_url 与示例的 Tailwind CDN / Google Fonts。
- [ok] HYPERFRAMES_META 是否真实存在 — example.html 含 <!-- HYPERFRAMES_META: {"frames":[ … ]} --> 共 8 条(i/duration/transition/scene),与示例 8 个 section.frame 一一对应。
- [discrepancy] 行内 frame 标记是否在示例中 — grep 'frame:' example.html = 0 命中;SKILL.md 要求的 `<!-- frame:N duration:3000 transition:fade -->` 在示例中未出现,时长改由 data-duration 承载。宿主解析器 parseInlineMarker + 兜底注释表明两条路径都被支持,故为约定演示缺口而非能力缺口。
- [ok] 宿主是否真消费该约定 — next/src/lib/hyperframes.ts 存在 FRAME_RE/META_RE/parseInlineMarker 实现(注释「Pull duration / transition out of the inline …marker the skill plants at the bottom of each section」);export-menu.tsx 提供 hyperframes-remotion-zip 动作;e2e/ui/export-menu.test.ts 以 templateId "video-hyperframes" 造样本。
- [ok] CLI 匹配器路由 — cli/src/skills-matcher.ts 存在 [["视频", "video", "帧动画", "hyperframes", "remotion", "mp4", "片头"], "video-hyperframes"] 行。
- [ok] 判级 green 自证 — 目录零脚本文件(示例内联 JS 属产物示例)、零凭证、零写盘;正文只规定 HTML 结构与注释标记,未点名运行时接口 → green。
- [ok] official_desc 逐字 — meta.official_desc 取自 frontmatter description 原文「Hyperframes / Remotion 兼容的连续帧动画, 可自动播放」。
6结论
f8c23c688123a19b…553ed98c28