
pr-to-video
热门将 GitHub 拉取请求(PR URL,如 github.com/<owner>/<repo>/pull/<N>,或 <owner>/<repo>#<N> 引用,或已检出仓库中的 'this PR')转换为代码变更解说视频,时长最长约 3 分钟(最佳时长 30-90 秒)—— 变更日志、功能展示、修复或重构讲解,基于 diff/提交/文件渲染。输入是通过 gh CLI 读取的代码变更,不涉及网站捕获。此技能用于 GitHub PR。请勿用于产品发布/推广(使用 /product-launch-video)、真实网站导览(使用 /website-to-video)、无 PR 的主题讲解(使用 /faceless-explainer)、现有素材的字幕(使用 /embedded-captions)或短篇无旁白动态图形(使用 /motion-graphics)。若意图不明确,请先通过 /hyperframes 路由。
将 GitHub 拉取请求(PR URL,如 github.com/<owner>/<repo>/pull/<N>,或 <owner>/<repo>#<N> 引用,或已检出仓库中的 'this PR')转换为代码变更解说视频,时长最长约 3 分钟(最佳时长 30-90 秒)—— 变更日志、功能展示、修复或重构讲解,基于 diff/提交/文件渲染。输入是通过 gh CLI 读取的代码变更,不涉及网站捕获。此技能用于 GitHub PR。请勿用于产品发布/推广(使用 /product-launch-video)、真实网站导览(使用 /website-to-video)、无 PR 的主题讲解(使用 /faceless-explainer)、现有素材的字幕(使用 /embedded-captions)或短篇无旁白动态图形(使用 /motion-graphics)。若意图不明确,请先通过 /hyperframes 路由。
media-use:在获取音频/图片前,先调用
/media-use从 HeyGen 目录中确定 BGM/SFX/图片。先运行--adopt注册已有资源。参见/media-use技能。
PR 到 HyperFrames
使用此技能来摄取 GitHub 拉取请求,理解变更,规划代码变更解说视频,并在 HyperFrames 中逐帧构建。输入是代码变更(通过 gh 读取),而非网站——没有捕获步骤,也没有真实资源,除了贡献者的头像。
在步骤 0 之前确认路由。 你是编排者。运行每个步骤,验证其关卡,然后继续。此技能适用于 GitHub 拉取请求(代码变更)。将其他意图路由到别处:产品发布/推广 →
/product-launch-video;通用网站导览 →/website-to-video;无 PR 的主题讲解 →/faceless-explainer;现有素材的字幕 →/embedded-captions;短篇无旁白动态图形 →/motion-graphics;整个仓库或多 PR 的发布讲解 →/general-video。超出范围: 实时/渲染时数据——PR 事实仅在创作时读取一次并固化。如果用户只说“制作视频”或路由不确定,请先阅读/hyperframes。
你是编排者。在 videos/<project>/ 中工作。按顺序运行步骤,并在继续前通过每个关卡。用户关卡为步骤 0、步骤 3 和步骤 6。除步骤 5(你为每帧分派一个子代理)外,自行执行每个步骤。不要在此处放置设计或运动规则;这些位于帧工作子代理、hyperframes-creative 和 hyperframes-animation 中。
工作流程:步骤 0 设置 → hyperframes.json;步骤 1 摄取 → capture/extracted/ + assets/<login>.png;步骤 2 设计系统 → frame.md;步骤 3 故事板/脚本 → STORYBOARD.md 和 SCRIPT.md;步骤 3.1 音频 → audio_meta.json;步骤 4 视觉设计 → 增强的 STORYBOARD.md;步骤 5 帧 → compositions/frames/NN-*.html 和 index.html;步骤 6 最终渲染 → renders/video.mp4。
步骤 0:设置与简报
目标:锁定 PR 引用和核心视频简报,并在需要时创建 HyperFrames 项目。
获取 PR 引用(完整 URL、<owner>/<repo>#<N> 引用,或已检出仓库中的“this PR”),并在一条消息中确认简报——为每项提供推荐默认值,并预填 /hyperframes 已设置的任何内容:角度(变更日志 / 功能展示 / 修复讲解 / 重构讲解——默认:从 PR 推断)、受众(默认:开发者)、时长(默认:根据 PR 变更规模缩放——见下文)、宽高比(默认 16:9)、语言。风格始终为 claude。仅在用户回复后继续;“go”表示接受默认值。
根据 PR 的变更规模推荐时长,而非固定猜测。在确认简报前,先只读查看一次 PR——该调用也用于确定角度(步骤 1 仍执行完整的确定性获取):
gh pr view <PR_REF> --json title,additions,deletions,changedFiles
根据 additions + deletions(由 changedFiles 微调)选择层级,并将其作为默认值推荐(用户可覆盖;硬上限约 3 分钟):
| PR 变更规模 | 推荐时长 |
|---|---|
| 微小(≲ 50 行变更) | 约 20-40 秒 |
| 集中(约 50-200 行) | 约 40-70 秒 |
| 较大(约 200-600 行) | 约 70-110 秒 |
| 大型(≳ 600 行,或 25+ 文件) | 约 110-180 秒 |
在提出时用一句话说明依据(例如“约 40 秒——小变更,+44/−13 跨 12 个文件”)。大型 PR 不意味着长视频——如果故事只有一个重点变更,保持紧凑并说明。
仅在 hyperframes.json 缺失时初始化。以 kebab-case 形式从 PR 命名 <project>,例如 acme-sdk-pr-1842;切勿使用工作区名称或时间戳。
npx hyperframes init "videos/<project>" --non-interactive --skip-skills --example=blank
在简报前显示登录状态——运行 npx hyperframes auth status 并逐字输出其结果(不要转述或重写)。 它报告语音/BGM 将使用 HeyGen 还是本地引擎,以及未登录时如何登录。如果未登录,停止并等待用户选择——登录,或说“go”/“offline”以使用本地引擎继续——然后再询问简报或其他任何内容。 将其视为真正的决策点,而非附带说明;不要将选择并入简报问题,也不要将密钥写入每个仓库的 .env。(在自主模式下,记录状态并离线继续。)参见 ../hyperframes-media → Preflight 获取规范指导。
关卡: hyperframes.json 存在;PR 引用已捕获;角度、时长、宽高比和语言已锁定;登录状态已显示(已登录,或继续离线)。
步骤 1:摄取 PR(无捕获)
目标:获取 PR 的事实并将其纳入项目作为信息来源。没有网站捕获。fetch-pr.mjs 确定性运行 gh——通过分页的 gh api 完成文件列表,因此大型 PR 不会在约 100 个文件处截断,并仅写入 capture/pr.json + capture/diff.patch(无临时目录)。然后 ingest.mjs 将其离线折叠到合成捕获包中。
PR="<url | owner/repo#N | N>"
# 确定性获取 PR:运行 gh,通过分页的 gh api 完成文件列表
# (因此大型 PR 不会在约 100 个文件处截断),仅写入 capture/pr.json +
# capture/diff.patch — 无临时目录。gh auth / not-found / private 错误在此退出 1。
(cd "videos/<project>" && node <SKILL_DIR>/scripts/fetch-pr.mjs --pr "$PR" --out-dir ./capture)
# 离线转换 → capture/extracted/{tokens.json (colors:[] → claude 调色板),
# visible-text.txt (简报), people.json (贡献者, 过滤机器人, avatarFile=assets/<login>.png)}。
(cd "videos/<project>" && node <SKILL_DIR>/scripts/ingest.mjs \
--pr-json ./capture/pr.json --diff ./capture/diff.patch --out-dir ./capture/extracted)
# 人员方面的唯一网络步骤——将每位贡献者的 GitHub 头像下载到
# assets/<login>.png,用于可选的致谢结尾。尽力而为;始终退出 0。
(cd "videos/<project>" && node <SKILL_DIR>/scripts/fetch-people-avatars.mjs \
--people ./capture/extracted/people.json)
如果 fetch-pr.mjs 退出 1(gh auth / not found / private),报告其 stderr 并停止——不要编造 PR 内容。如果 ingest.mjs 退出 1,读取其 stderr(通常是格式错误的 pr.json),修复并重新运行(确定性)。fetch-people-avatars.mjs 始终退出 0;缺失头像仅意味着没有致谢结尾给作者。
关卡: capture/pr.json、capture/diff.patch、capture/extracted/tokens.json、capture/extracted/visible-text.txt 和 capture/extracted/people.json 存在;你能用一句清晰的话说明 PR 的变更。assets/<login>.png 是尽力而为——缺失不算失败。
步骤 2:设计系统
目标:采用 claude 帧预设;脚本将其转换为该视频的 frame.md + 字幕皮肤。
风格固定——claude(温暖编辑风格;为 diff 构建的海军蓝代码表面)。运行:
node <SKILL_DIR>/scripts/build-frame.mjs --preset claude --hyperframes .
脚本复制 claude 预设的 FRAME.md → frame.md,将其与 capture/extracted/tokens.json 中的任何品牌令牌混合(PR 没有 → colors:[]/fonts:[] 保留 claude 自己的调色板,完整设计),将预设的字幕皮肤复制到 .hyperframes/caption-skin.html,并自我验证(映射损坏时退出 1)。一旦退出 0 即继续——无需手动编辑。
关卡: build-frame.mjs 退出 0——frame.md 从 claude 预设存在,且 .hyperframes/caption-skin.html 作为字幕皮肤源存在。
步骤 3:故事板与脚本
目标:将 PR 转换为经批准的逐帧解释计划。
阅读 references/story-design.md、../hyperframes-core/references/storyboard-format.md 和 ../hyperframes-core/references/script-format.md。使用它们编写 STORYBOARD.md,并在需要旁白时编写 SCRIPT.md。
使用 story-design.md 获取 PR 原型(变更日志 / 功能展示 / 修复讲解 / 重构讲解)、PR 原生帧类型、钩子、说服、节拍、每帧字数预算以及可选的致谢结尾。顺序来自叙事设计,而非 diff 的文件顺序——解释变更,而非逐字朗读 diff。展示 2-4 个真实 diff 片段(来自 capture/diff.patch),每个为简短可读的片段;命名每个帧的 scene 所需的 code-* 块。帧不携带 asset_candidates,除了可选的 credits 结尾(2-6 个 assets/<login>.png 头像)。使用故事板和脚本参考中的确切必填字段。
草拟后,显示逐帧摘要。在同一条消息中询问用户(a)批准或请求更改,以及(b)是否希望实时预览故事板框架(npx hyperframes preview)——仅在回答“是”时打开。迭代直至批准;将预览选择带到步骤 6。
关卡: STORYBOARD.md 存在,每帧具有必需的叙事字段,需要旁白时 SCRIPT.md 存在,且用户批准了计划。
步骤 3.1:音频
目标:根据批准的脚本生成旁白、单词时间、音乐和音频元数据。
在步骤 3 批准后开始音频。在后台运行,然后继续步骤 4。
node <SKILL_DIR>/scripts/audio.mjs --script ./SCRIPT.md --storyboard ./STORYBOARD.md --hyperframes . --out ./audio_meta.json &
音频脚本处理旁白、单词时间、从 HeyGen 音乐库查找 BGM 以及时间元数据。BGM 情绪来自故事板的 music: 字段。这使用 HeyGen 音频 API 进行检索而非生成,并使用与 TTS 相同的 ~/.heygen 凭据。有关提供商详细信息,请阅读 ../hyperframes-media/references/tts.md。
如果没有旁白且没有 SCRIPT.md,则跳过语音生成。如果故事板有音乐情绪,BGM 仍可能运行。
关卡: 音频作业已启动,或项目标记为静音。
步骤 4:帧视觉设计
目标:为每个故事板帧添加视觉方向、布局意图和运动选择。
原地编辑 STORYBOARD.md。不要创建另一个故事板。使用 frame.md 作为颜色、字体、布局感觉和风格的真相来源。
阅读 references/visual-design.md、references/composition.md、references/motion-language.md、references/code-vocabulary.md 和 ../hyperframes-animation/。使用 visual-design.md 获取必需的帧字段和必需的 ## Video direction 块,以及代码节拍如何将 code-* 块命名为其 focal。使用 code-vocabulary.md 为每个节拍选择正确的块(diff = code-diff,重构 = code-morph,新代码 = code-typing,……)。使用 composition.md 获取布局/层次/焦点,使用 motion-language.md + ../hyperframes-animation/ 获取有效的效果和蓝图 ID。不要发明效果名称或块/蓝图 ID。
对于每帧,添加必需的视觉和运动字段,包括 effects 和 focal 和/或 roles。对于代码节拍,将 code-* 块命名为 focal,并让 effects 编排周围的 claude 代码表面(而非代码动画,该动画由块拥有)。添加一个视频范围的 ## Video direction 块。
不要更改故事、脚本、transition_in、asset_candidates 或 PR 来源。不要在此步骤编写 HTML。没有资源暂存步骤——唯一的真实资源是致谢头像,已在 assets/ 中。
关卡: 每帧具有 effects 加上 focal 和/或 roles;代码帧命名 code-* 块;## Video direction 存在。
步骤 5:构建帧
目标:将每个故事板帧构建为 HTML 合成,并组装可播放的视频。
如果音频已启动,等待步骤 3.1 音频完成。然后同步时长并获取 SFX;如果静音则跳过两者。
node <SKILL_DIR>/scripts/audio.mjs sync-durations --audio-meta ./audio_meta.json --storyboard ./STORYBOARD.md
node <SKILL_DIR>/scripts/audio.mjs fetch-sfx --storyboard ./STORYBOARD.md --hyperframes .
时长同步是机械性的:真实语音时长优先;静音帧保留估计值;切勿手动编辑同步后的时长。
预安装注册表块,这些块在 STORYBOARD.md 中命名一次,在分派之前,以便并行工作线程不会在注册表上竞争:
for b in <each registry block named in the storyboard>; do npx hyperframes add "$b"; done
在分派前,阅读 sub-agents/frame-worker.md 和 ../hyperframes-core/references/subagent-dispatch.md。每帧分派一个子代理,尽可能并行;否则以波次运行工作线程。每个工作线程恰好获得一帧。每个工作线程的上下文必须包括 PROJECT_DIR、frame_id、画布大小、字幕状态和启用字幕时的保留带、ANIM_DIR(../hyperframes-animation/ 的绝对路径)以及 references/code-vocabulary.md 的绝对路径。每个工作线程读取 frame.md、其自己的 ## Frame N 块、每个引用的效果/蓝图 ID 的配方主体,以及——对于代码节拍——code-vocabulary.md 以获取命名块的输入。每个工作线程仅写入 compositions/frames/NN-*.html;工作线程从不编辑 STORYBOARD.md。
当每个工作线程返回时,在 STORYBOARD.md 中将该帧标记为 animated。
在音频时间存在后,在后台构建字幕并组装索引:
node <SKILL_DIR>/scripts/captions.mjs build --storyboard ./STORYBOARD.md --audio-meta ./audio_meta.json --hyperframes . --out ./caption_groups.json &
node <SKILL_DIR>/scripts/assemble-index.mjs --storyboard ./STORYBOARD.md --hyperframes .
captions.mjs 使用项目的 .hyperframes/caption-skin.html(claude 的,在步骤 2 中复制),从 frame.md 注入品牌令牌;captions: skipped (<reason>) 是有效的。assemble-index.mjs 将 assets/ 中的致谢头像作为幂等后备暂存。
关卡: 每帧标记为 animated,index.html 存在,且字幕已构建或明确跳过。
步骤 6:最终确定
目标:验证组装的视频,获取用户批准,并渲染最终的 MP4。
注入过渡,运行检查,暂停审查,然后渲染。
node <SKILL_DIR>/scripts/transitions.mjs inject --storyboard ./STORYBOARD.md --hyperframes .
node <SKILL_DIR>/scripts/transitions.mjs verify --storyboard ./STORYBOARD.md --index ./index.html
npx hyperframes lint
npx hyperframes validate
npx hyperframes inspect
npx hyperframes snapshot --at <frame-midpoints>
snapshot 将捕获的帧拼接成一个联系表(snapshots/contact-sheet.jpg)。快速浏览;如果没有明显损坏,继续——不要在此停留。
如果命令失败,显示 stderr 并停止——不要堆叠恢复命令。自行修复:对 compositions/frames/NN-*.html 进行最便宜的安全编辑,然后重新运行失败的检查。
已知误报——不要追究。 inspect 可能报告少量约 1-4px 的 text_box_overflow 错误,位于字幕高亮词(选择器 #caption-word-* / .caption-line)上。字幕药丸使用故意紧凑的 line-height(在 scripts/captions.mjs 中设置一次),并且没有 overflow:hidden,因此重显示字形的墨水会溢出几像素到药丸自己的内边距中——实际上没有内容被裁剪。将这些视为预期并继续。不要增大字幕 line-height(这会使药丸膨胀,更糟)。仅在 text_box_overflow 命名帧元素(#el-NN-*)而非字幕词时采取行动。
检查通过后,暂停等待用户审查。视频已组装、可查看,并可在 Studio 中编辑。仅在步骤 3 和步骤 6 之间管理一次预览:如果用户之前要求则打开,如果之前拒绝则提供,如果已在 Studio 中审查则不再询问。
预览:npx hyperframes preview
仅在用户批准后渲染:
npx hyperframes render --skill=pr-to-video --quality high --output renders/video.mp4
除非用户要求,否则不要在渲染后重新运行 lint、validate、inspect 或 snapshot。
关卡: lint、validate 和 inspect 在渲染前通过;用户在审查暂停时批准;renders/video.mp4 存在。最终回复说明 MP4 路径和最终时长。
快速参考
格式: 默认横向 1920x1080;纵向 1080x1920;方形 1080x1080。在故事板前言中设置一次格式。
PR 差异与捕获资源工作流: 无步骤 1 捕获(gh CLI 将 PR 摄取到合成 capture/extracted/ 包中——tokens.json + visible-text.txt + people.json);唯一的真实资源是贡献者的 assets/<login>.png 头像(可选的致谢结尾);无 asset-descriptions.md,无资源暂存步骤。代码节拍由 code-* 注册表块在 claude 的海军蓝代码表面上渲染;风格始终为 claude。
后台脚本: 工作流在 scripts/ 下提供这些脚本:fetch-pr(PR → capture/pr.json + diff.patch 通过 gh;大型 PR 安全,无临时文件),ingest(→ 合成捕获包;离线),以及 fetch-people-avatars(贡献者头像 → assets/);加上共享引擎——build-frame(采用预设并混合品牌到 frame.md + 字幕皮肤),audio(TTS、BGM、SFX、时长同步),captions,transitions(注入 + 验证),以及 assemble-index。其他一切都是 hyperframes CLI。代码块通过 npx hyperframes add <name> 安装。
| 阅读 | 时机 |
|---|---|
[references/story-design.md](references/story-design.md) |
步骤 3:规划 PR 解释。 |
[../hyperframes-core/references/storyboard-format.md](../hyperframes-core/references/storyboard-format.md) |
步骤 3:编写 STORYBOARD.md。 |
[../hyperframes-core/references/script-format.md](../hyperframes-core/references/script-format.md) |
步骤 3:编写 SCRIPT.md。 |
[../hyperframes-media/references/tts.md](../hyperframes-media/references/tts.md) |
步骤 3.1:选择或了解 TTS 提供商。 |
[references/visual-design.md](references/visual-design.md) |
步骤 4:视觉上丰富故事板。 |
[references/code-vocabulary.md](references/code-vocabulary.md) |
步骤 4 + 5:为代码节拍选择并填充 code-* 块。 |
[references/composition.md](references/composition.md) |
步骤 4:判断构图。 |
[references/motion-language.md](references/motion-language.md) |
步骤 4:判断运动语言。 |
[../hyperframes-animation/](../hyperframes-animation/) |
步骤 4:引用效果和蓝图 ID。 |
[sub-agents/frame-worker.md](sub-agents/frame-worker.md) |
步骤 5:分派每帧工作线程。 |
[../hyperframes-core/references/subagent-dispatch.md](../hyperframes-core/references/subagent-dispatch.md) |
步骤 5:安全分派子代理。 |
[../hyperframes-creative/frame-presets/claude/FRAME.md](../hyperframes-creative/frame-presets/claude/FRAME.md) |
步骤 2:claude 预设(固定风格)。 |





