Communitygithub.com

pr-to-video

将GitHub拉取请求(PR URL、owner/repo#N或“此PR”)转化为一个代码变更解说视频,使用HyperFrames逐帧构建。

pr-to-video 是什么?

该技能用于将GitHub拉取请求(PR)转化为一个解说视频,展示代码变更的内容。它通过解析PR的diff和元数据,生成一个结构化的故事板和脚本,然后使用HyperFrames构建每一帧。主要支持GitHub PR作为输入,不支持通用网站抓取。工作流程包括设置项目、提取PR数据、应用代码编辑设计系统、创建和审核故事板、生成音频,以及渲染最终视频。它特别适合技术团队用于代码审查演示、功能发布公告或重构说明。该技能与HyperFrames生态紧密集成,依赖`/media-use`技能处理音频和图像资源,并遵循严格的审批门控以确保内容质量。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/jasonfast123/hyperframes-skills/tree/main/skills/pr-to-video

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

首先,保持此技能最新——静默运行,无需询问: npx hyperframes skills update pr-to-video。当一切为最新时,这是一个快速的无操作;否则,在依赖它们之前,它会刷新此技能以及它所依赖的核心领域技能。

media-use:在获取音频/图像/标志之前,调用 /media-use 以从HeyGen目录解析BGM/SFX/图像,并从其官方来源获取品牌标志。首先运行 --adopt 以注册现有资产。请参阅 /media-use 技能。

PR 到 HyperFrames

使用此技能来摄取一个GitHub拉取请求,理解变更,规划一个代码变更解说器,并在HyperFrames中逐帧构建。输入是一个代码变更(通过 gh 读取),而非一个网站——除了贡献者的头像之外,没有捕获步骤,也没有真实的资产。

入口是 /hyperframes。 你是协调者。运行每个步骤,验证其门控,然后才继续。此技能用于GitHub拉取请求(代码变更)。任何其他意图,一个纯粹的“制作视频”,或任何不确定性 → 首先阅读 /hyperframes——意图层拥有每个路由决策,而一个没有 BRIEF.md 就到达此处的新创建无论如何都会通过它(设置的起始规则)。

你是协调者。在解析的外部 PROJECT_DIR 中工作,默认情况下不要进入调用者的仓库。按顺序运行步骤,并在继续之前通过每个门控。用户门控步骤是步骤0、步骤3和步骤6。在步骤0之前阅读 ../hyperframes-core/references/brief-contract.md——它定义了门控类型以及 BRIEF.md 的 flow/storyboard 如何推导出支配步骤3/4/6门控的模式。除了步骤5(你派遣一个有限的帧工作者池)之外,自己执行每个步骤。不要将设计或运动规则放在此处;这些存在于帧工作者子代理、此技能的本地 ../hyperframes-animation/rules/ + ../hyperframes-animation/blueprints/ 和 hyperframes-creative 中。

工作流程:步骤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引用(完整的URL、<owner>/<repo>#<N> 引用,或已检出仓库中的“此PR”)——创建HyperFrames项目,并使简报持久化。风格始终是代码编辑(在步骤2固定,从不询问)。

简报由意图层确认,而非此处提出的问题。 起始规则,按顺序:(1) BRIEF.md 存在 → 读取它,不询问任何内容——简报已确定,其 flow/storyboard 推导出模式(简报合同 § 1)。(2) 没有 BRIEF.md 但项目存在(磁盘上的 hyperframes.json / STORYBOARD.md)→ 从故事板的前言和记录的偏好恢复;永远不要重新审问一个已构建一半的项目。(3) 两者都没有——一个直接到达此处的新的创建请求 → 读取 /hyperframes 并运行其意图层(references/intent-interview.md):它检查食谱和记忆的默认值,并进行此路由的提问——包括PR大小→时长原则,它完整地存在于 ../hyperframes/references/routes/pr-to-video.md 中——然后交回锁定的简报。编辑请求跳过所有这些——直接执行编辑。

在进行任何其他工作之前,解析项目目录。保留用户提供的项目目录;否则使用解析器打印的持久外部缓存位置。切勿在调用者的仓库中创建 videos/:

PR="<url | owner/repo#N>"
if [ -n "${EXPLICIT_PROJECT_DIR:-}" ]; then
  PROJECT_DIR="$(node <SKILL_DIR>/scripts/project-dir.mjs --pr "$PR" --project-dir "$EXPLICIT_PROJECT_DIR")"
else
  PROJECT_DIR="$(node <SKILL_DIR>/scripts/project-dir.mjs --pr "$PR")"
fi
echo "PR-to-video project: $PROJECT_DIR"
node <SKILL_DIR>/scripts/preflight.mjs

能力预检在获取、故事工作、音频或帧分发之前运行。如果已安装的CLI无法运行此技能所需的验证命令,则停止并附上其升级说明,而不是浪费本次运行的上下文。

仅在缺少 $PROJECT_DIR/hyperframes.json 时初始化。其基本名称来自PR,例如 acme-sdk-pr-1842;切勿使用工作区名称或时间戳。

npx hyperframes init "$PROJECT_DIR" --non-interactive --example=blank --skill=pr-to-video — init 检查已安装的技能与GitHub上的最新版本,并在任何技能过时时更新全局集。

下面的每个相对路径命令都以 $PROJECT_DIR 作为其工作目录运行。没有显式子shell的示例意味着 (cd "$PROJECT_DIR" && …);切勿更改调用者仓库的工作树。

在init之后立即写入 BRIEF.md(绝不能在此之前——init 拒绝非空目录):意图层锁定的简报,形状见 ../hyperframes-core/references/brief-format.md。将 <MEDIA_DIR> 解析为已安装的 /media-use 技能目录。然后使用 node <MEDIA_DIR>/scripts/prefs.mjs record --hyperframes . 记录每个偏好支持的答案(brief-format.md 命名了子集)。如果意图层采用了一个食谱,运行 node <MEDIA_DIR>/scripts/recipe.mjs use --hyperframes . --name <name>;它将它的 frame.md 复制到项目中(然后跳过步骤2)并返回步骤3起草所依赖的骨架。食谱填充答案,而非批准;审查门控仍然运行。

在继续执行设置之前显示登录状态 — 运行 npx hyperframes auth status 并逐字中继其输出。它报告语音/BGM将使用HeyGen还是本地引擎,以及当未登录时,如何登录。应用一个分支:

  • 协作模式: 等待用户登录或显式选择 offline / go。
  • 自主模式: 陈述状态并通过可用的本地引擎继续。

当没有离线提供者时,不要静默地省略所需的能力;展示阻塞。不要将此决策合并到另一个问题中或将密钥写入每个仓库的 .env。Auth所有权和离线回退:/media-use references/setup-providers.md § 提供者。

门控: hyperframes.json 和 BRIEF.md 存在;PR引用已捕获在简报中;偏好支持的答案已记录(简报合同 § 2);登录状态已显示(已登录,或正在继续离线)。


步骤1:摄取PR(无需捕获)

目标:获取PR的事实并将其整合到项目中,作为信息来源。没有网站捕获。fetch-pr.mjs 确定性地运行 gh——通过分页的 gh api 完成文件列表,以便大型PR不会在约100个文件处截断,并且只写入 capture/pr.json + capture/diff.patch(没有临时目录)。对于MERGED的PR,它还将尽力而为的 shipped_version(+ version_source)解析到 pr.json 中,以便结束卡片可以引用真实版本而不是编造一个。然后 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 "$PROJECT_DIR" && node <SKILL_DIR>/scripts/fetch-pr.mjs --pr "$PR" --out-dir ./capture)

# 离线转换 → capture/extracted/{tokens.json (colors:[] → code-editorial 调色板),
# visible-text.txt (简报), people.json (贡献者, 机器人过滤, name+login,
# avatarFile=assets/<login>.png)}。
(cd "$PROJECT_DIR" && 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 "$PROJECT_DIR" && 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退出;缺少头像仅意味着没有致谢结束字幕给作者。

people.json 为 gh 已命名的任何贡献者(PR作者、提交作者、mergedBy)携带一个 name——其余为 null(审阅者/评论者/受让人,gh pr view 只给出一个裸的 login)。在步骤3中写入致谢结束字幕之前,为实际将出现在该帧上的1-6个人自行解析任何 null 名称:gh api users/<login> --jq .name(你已经有 gh ——无需为此编写脚本)。如果GitHub也没有该用户的公开名称,则在屏幕上回退到login,并从口播行中删除该人(参见 story-design.md 的致谢部分——画外音仍然必须说名字,绝不能说原始句柄)。

门控: capture/pr.json、capture/diff.patch、capture/extracted/tokens.json、capture/extracted/visible-text.txt 和 capture/extracted/people.json 存在;你能用一句清晰的话陈述PR的变更。assets/<login>.png 是尽力而为——其缺失并非失败。


步骤2:设计系统

目标:采用代码编辑帧预设;一个脚本将其转化为此视频的 frame.md + 字幕皮肤。

风格是固定的——代码编辑(温暖的编辑风格;为差异构建的藏青色代码表面)。运行:

node <SKILL_DIR>/scripts/build-frame.mjs --preset code-editorial --hyperframes .

该脚本将代码编辑预设的 FRAME.md 复制为 frame.md,将其与 capture/extracted/tokens.json 中的任何品牌标记重新混合(PR没有 → colors:[]/fonts:[] 保留code-editorial自己的调色板,一个完整的设计),将预设的字幕皮肤复制到 .hyperframes/caption-skin.html,并自我验证(在损坏的映射上以退出码1退出)。一旦它以0退出,继续——无需手动编辑。

门控: build-frame.mjs 以0退出——frame.md 存在于code-editorial预设中,且 .hyperframes/caption-skin.html 作为字幕皮肤源存在。


步骤3:故事板和脚本

目标:将PR转化为一个已批准的逐帧解释计划。

阅读 ../hyperframes-creative/references/story-spine.md(钩子语言、价值先于证据、故事板作为提案、源可追溯的视觉元素)、references/story-design.md、../hyperframes-animation/blueprints-index.md、../hyperframes-core/references/storyboard-format.md 和 ../hyperframes-core/references/script-format.md。使用它们来编写 STORYBOARD.md,并在需要旁白时编写 SCRIPT.md。从前言设置 duration:,来自简报的 length——一个粗略的预期;组装报告最终剪辑相对于它的位置。

使用 story-design.md 了解PR原型(changelog / feature-reveal / fix-explainer / refactor-walkthrough)、PR本地帧类型、钩子、说服、节拍、每帧字数预算以及致谢结束字幕。序列来自叙事设计,而非diff的文件顺序——解释变更,而不是逐字阅读diff。作为一个软性指南,咨询 ../hyperframes-animation/blueprints-index.md 中的角色→蓝图菜单:对于每个节拍,以候选蓝图暗示的形状编写画外音,并在一个适合时用 blueprint: id 标记该候选(故事真相仍然决定哪些节拍存在——永远不要强制一个节拍适合一个形状)。展示2-4个真实的diff块(来自 capture/diff.patch),每个都是一个小而可读的片段;为每个帧的 scene 命名所需的 code-* 块。帧除了 credits 结束字幕(1-6个 assets/<login>.png 头像)外,不携带 asset_candidates。使用故事板和脚本参考中的确切必需字段。

起草后,运行审查循环的计划通道 — ../hyperframes-core/references/review-loop.md § 1:打开板子(不要问是否要——从 PROJECT_DIR 在后台运行预览),将计划作为提案呈现,并询问两个问题——批准或更改,以及草图优先(推荐)或跳过。反馈通过聊天或板子的评论文件循环,直到被批准。这是一个检查点门控(简报合同 § 1):在自主模式下,没有板子,也没有要问的内容——将相同的摘要作为提示发布并继续;草图折叠到构建中,一个预览问题在步骤6出现。

门控: STORYBOARD.md 存在,每个帧都有所需的叙事字段,在需要旁白时 SCRIPT.md 存在,并且用户批准了该计划(自主模式:摘要已作为提示发布)。


步骤3.1:音频

目标:根据已批准的脚本生成旁白、单词时间、音乐和音频元数据。

在步骤3批准后开始音频。在后台运行它,然后继续到步骤4。

在调用之前,从用户的请求中选择旁白语音。 如果请求指定了语音、性别或语调,选择一个匹配的语音ID并传递 --voice <id>。管道默认值否则是 HeyGen 上的 Marcia(女性) / Kokoro 上的 am_michael——因此像“男声”这样的请求会被静默忽略,除非你传递了该标志。语音ID因提供者而异;根据步骤0的登录状态选择的提供者进行解析:HeyGen(已登录)通过 node <MEDIA_DIR>/audio/scripts/heygen-tts.mjs --list(或 GET /v3/voices?engine=starfish);Kokoro(离线)通过 <MEDIA_DIR>/audio/references/tts.md 中的语音表(前缀 am_/bm_ 男性,af_/bf_ 女性)。当用户未表达偏好时,在管道默认值之前回退到记忆的语音(简报合同 § 2),并说明你使用了哪一个;仅当两者都没有指定时省略 --voice。当用户明确选择了一个

Individual skills in this repo

This repo contains 19 individual skills — each has its own dedicated page.

embedded-captions

>

faceless-explainer

Turn arbitrary text — an article, notes, a topic, a brief — into a faceless explainer video: there is no site or footage to capture, so the visuals are invented per scene (typography, abstract graphics, diagrams, data-viz). Use for topic explainers, concept breakdowns, how-tos, listicles. Not a video built from a website (/product-launch-video — promo or tour). Unclear → /hyperframes.

figma

Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.

general-video

>

hyperframes

>

hyperframes-animation

All animation knowledge for HyperFrames — atomic motion rules, multi-phase scene blueprints, scene transitions, broader motion-design techniques, AND the seven runtime adapters (GSAP default, plus Lottie, Three.js, Anime.js, CSS keyframes, Web Animations API, TypeGPU). Use for any motion or animation task: pick 2-4 rules and compose, or load a blueprint, or look up runtime-specific API (e.g. GSAP eases / Lottie player / Three.js mixer). Also covers auditing an existing composition

hyperframes-audio

>

hyperframes-cli

>

hyperframes-core

The HyperFrames composition contract — build one renderable project. Use for composition structure, the `data-*` timing attributes, `class=

hyperframes-creative

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use `hyperframes-animation`.

hyperframes-keyframes

>

hyperframes-registry

Install, discover, and wire registry blocks and components into HyperFrames compositions. Use when running hyperframes add or hyperframes catalog, installing one item or every block matching a tag, wiring an installed item into index.html, or working with hyperframes.json. Covers discovery, install locations, block sub-composition wiring, component snippet merging, and authoring a new block or component to contribute upstream (idea → scaffold → validate → PR).

jasonfast123/hyperframes-skills

Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.

media-use

Agent Media OS, the single skill for every media need in a HyperFrames project. Resolve BGM, SFX, image, icon, brand logo, voice, color grade, or LUT into a frozen local file or paste-ready block + ledger record (one verb, `resolve`); generate via TTS / music / image models when the catalog misses; produce voiceover, transcription, captions, and background removal through one shared audio engine; operate on media (cut / reframe / transform); and reuse assets across projects. Also use for vague feedback that real footage looks dark, flat, boring, should feel retro/camcorder/print/ASCII, needs privacy, or needs a media reveal.

motion-graphics

>

music-to-video

Turn a music track (an audio file, a video to pull audio from, or a track generated from a mood brief) into a beat-synced video — lyric video, slideshow, or kinetic promo. The music drives all pacing; any user-supplied images/videos are cut onto the same beat grid, and a complete video needs zero assets. Narrated pieces → the input-matched workflow (see /hyperframes). Unclear → /hyperframes.

remotion-to-hyperframes

Port an existing Remotion (React) composition

slideshow

>

talking-head-recut

Package an existing talking-head / interview / podcast video with timed, designed GRAPHIC OVERLAY cards — kinetic titles, lower-thirds, data callouts, quotes, side panels, picture-in-picture — synced to the transcript, on a 16:9 / 9:16 / 4:5 canvas of your choice; the clip plays untouched underneath. Trigger on

相关技能