Communitygithub.com

github-year-in-review

将某人的 GitHub 年度活动转化为一段可发布的年终回顾短视频(4:5 比例,约 45 秒,专为 LinkedIn 设计),使用 HyperFrames 渲染。

github-year-in-review 是什么?

github-year-in-review 是一个 AI 助手技能,它能自动从用户的 GitHub 活动数据中提取关键指标,并生成为一段适合在 LinkedIn 等社交平台分享的回顾视频。该技能通过 `gh` CLI 获取真实数据(无需截图或上传),使用 HyperFrames 进行渲染,输出 1080x1350 的竖版视频,并自动生成缩略图和分享文案。它支持自定义用户、年份、时区,并能处理私有仓库(默认不显示名称),还能识别自动化提交(如 CI 机器人)和 AI Agent 辅助的代码提交,并以积极的方式呈现这些信息。该技能要求 Python 3.9+、Node 18+、ffmpeg 以及 `gh` 认证,整个工作流程分为收集数据、构建故事脚本、渲染检查、交付四个步骤,全程有严格的校验门控确保数据准确和视觉效果。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/byronxlg/github-year-in-review/tree/HEAD/skills/github-year-in-review

在你喜欢的 AI 中提问

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

文档

/github-year-in-review

你在 GitHub 上的一年,浓缩成一段 45 秒可发布的影片。

与 /brag 是姊妹技能:brag 将项目转化为发布视频,而本技能将一个人的年度活动转化为视频。两者采用相同的渲染路径(HyperFrames)、相同的交付方式(海报帧嵌入为第 0 帧、共享文案)。区别在于:故事基于数据,因此数据和节奏逻辑以脚本形式提供,代理的工作是检查数字、润色文案、审阅帧并完成交付。

调用方式

/github-year-in-review
/github-year-in-review --user octocat --year 2025
/github-year-in-review --include-private --no-music
选项默认值
--user当前已认证的 gh 用户
--year当前年份(12 月 31 日前标记为“至今”)
--tz本机时区(用于小时维度的节奏数据)
--include-private关闭:私有仓库仅计数,不显示名称
--no-music有可用曲目时默认开启音乐
--formatportrait 1080x1350(唯一支持的格式)

输出位于当前目录下的 year-in-review-<user>-<year>/ 目录(如果已存在则添加时间戳)。<skill-dir> 是存放此文件的目录。

前置要求

gh 已认证(gh auth status)、Python 3.9+、Node 18+(需 npx hyperframes)、ffmpeg。需要 HyperFrames 领域技能(hyperframes-core、hyperframes-cli)用于检查和渲染。

步骤 1:数据收集

python3 <skill-dir>/scripts/collect.py --user <login> --year <year> --out <out>/year.json

对于活跃账户大约需要两分钟(提交历史会被采样用于时钟节奏)。它会写入:总计数据、每日日历、节奏(连续天数、时段、工作日)、热门仓库、编程语言、拉取请求、新建仓库、本年度获得的 Star 数,以及自动化:至少 60% 的采样提交共享同一消息模板的仓库(作为该用户身份提交的定时任务)。自动化数据不会纳入节奏和“工作”片段,而是成为独立的惊喜片段。

它还会收集可选的专题数据:代理(与编码 AI Agent 共同编写的提交,仅通过签名检测,加上通过脚注、应用作者和 claude/ 风格分支前缀标识的代理 PR)、本年度标记的版本发布,以及最大的已合并 PR。这些数据仅在数量达到阈值时才会形成独立片段(阈值定义见 references/story.md)。

门控: 在构建前读取 year.json 并进行合理性检查。标题总数应与该用户 GitHub 个人资料上显示的年度数量一致。如果发现异常(如检测器遗漏的机器人、不应显示名称的仓库),请修复收集器或使用 story.json 覆盖;切勿手动编辑数字到合成结果中。

步骤 2:故事脚本

python3 <skill-dir>/scripts/build.py <out>/year.json --out <out> \
  [--music <track.mp3> --cues <track.music-cues.json>]

这将生成 <out>/story.json(片段、文案、时间)、<out>/composition/(影片文件)和 <out>/thumbnail/(用于封面的结尾定格画面,持续 1 秒,见步骤 4)。片段、其数据及降级方案详见 references/story.md。数据不足的片段会被删除,因此安静的一年会生成更短的影片,而非空影片。

然后读取 story.json,并在默认文案基础上尽可能具体地进行改进(字幕、典型角色名称和原因、工作片段引用)。规则:

  • 每项声明必须与 year.json 中的数据一致。不得虚构数字,不得使用数据不支持的最高级表述。
  • 短句优先。文字字号较大是有意设计的;超过约 12 个单词的内容将无法在屏幕上停留足够长的时间。
  • 除非使用 --include-private,否则不得显示私有仓库名称。
  • 不使用表情符号、不出现长破折号、不采用“碾压一切”的语气。该内容将发布在 LinkedIn 上。
  • 将代理和自动化描绘为用户领导的团队(“与……共同交付”、“与……共同编写”)。切勿贬低,切勿暗示工作成果不属于用户;代理计数仅为下界。

从编辑后的故事脚本重新构建:使用 --story <out>/story.json(时间将重新推导)。

音乐:如果已安装 /brag,其内置曲目和提示预设可直接使用(<brag-dir>/assets/music/*.mp3、<brag-dir>/assets/music/cues/*.music-cues.json)。优先选择长度至少与影片相同的曲目。使用 --cues 时,场景起始点会自动对齐最近的节拍。没有曲目时影片为静音,这也可以接受:LinkedIn 会自动静音播放。

步骤 3:检查、渲染、审阅

cd <out>/composition
npx hyperframes check                       # 门控:零错误;同时修复 line_unread 和 type-floor 警告
npx hyperframes render --quality draft --output ../draft.mp4

在每个片段中提取一个稳定帧,在渲染最终版本之前亲自检查每一帧。同时检查每个章节卡片在其命令输入完成后的画面(约进入卡片 2.5 秒处):完整命令必须显示在屏幕上,保持一行,墨水色文字置于深色背景上。

for t in $(jq -r '.beats[]|.start+.duration-0.5' ../story.json); do
  ffmpeg -loglevel error -ss $t -i ../draft.mp4 -frames:v 1 ../frame-$t.png; done

检查以下问题:文字溢出或被裁剪、数字与 year.json 不符、空泛或无聊的片段、在手机尺寸下无法阅读的文字(将帧缩放到 540 像素宽进行测试)、第一帧视觉效果不佳。在 story.json 中修复原因(文案)或将其报告为技能 Bug;然后执行:

npx hyperframes render --quality high --output ../year-in-review.mp4

步骤 4:交付

海报帧:钩子的稳定帧(约 2.9 秒处)作为缩略图。将其嵌入为第 0 帧,以便所有平台都能显示(与 /brag 步骤 4 相同):

cd <out>
ffmpeg -ss 2.9 -i year-in-review.mp4 -frames:v 1 -q:v 2 poster.jpg
ffmpeg -y -i year-in-review.mp4 -i poster.jpg \
  -filter_complex "[0:v][1:v]overlay=0:0:enable='eq(n,0)'[v]" \
  -map "[v]" -map '0:a?' -c:v libx264 -crf 20 -preset slow -pix_fmt yuv420p \
  -c:a aac -b:a 160k -movflags +faststart tmp.mp4 && mv tmp.mp4 year-in-review.mp4

封面图:影片结尾(年度网格、用户名、“<年份>,回顾。”)的干净定格画面,不包含幻灯片计数器、哈希标签、底部轨道或页脚栏。在 LinkedIn 上将其上传为视频的自定义缩略图(它符合 LinkedIn 预期的 4:5 宽高比),并可用于任何需要封面图像的地方:

cd <out>
npx hyperframes check thumbnail
npx hyperframes snapshot thumbnail --at 0.5 --no-end -o thumbnail/shots
cp thumbnail/shots/frame-00-at-0.5s.png thumbnail.png

门控: year-in-review.mp4 必须为 H.264、1080x1350、小于 50 MB、时长 25-75 秒(构建上限为 70 秒加上章节卡片);poster.jpg 存在;thumbnail.png 为 1080x1350 且您已亲自检查过(无计数器、无底部轨道、无裁剪)。

编写 <out>/share-copy.txt:以用户口吻写两三句简洁文案,基于最有力的事实(典型角色、一个数字、一个项目)。不要用一堆话题标签;最多两个。示例:“到目前为止,我在 GitHub 上的 2026 年:30 个新仓库、连续 44 天活跃、还有一个提交数量超过我本人的机器人。由 github-year-in-review 制作。”

告知用户视频、封面图、海报帧和共享文案的位置,以及一句话说明影片内容。

创作法则

  • 第 0 帧就是帖子。 包含姓名、年份和头条数字,稳定呈现。
  • 每个片段只提一个问题和一个焦点。 一个大数字或一个形状;其余均为标签。
  • 身份重于清单。 影片以用户是谁(典型角色)结尾,而非数字总计。
  • 诚实。 自动化会被明确标注,私有名称会被隐藏,不满一年的数据会标注“至今”。
  • 静音可读。 每个片段在静音状态下也能理解。
  • Git,而非 GitHub。 使用输入提示、哈希标签、差异片段和提交尾注;不使用 Logo、GitHub 绿色或 UI 界面元素。
  • 独特外观。 严格遵守 references/story.md 中定义的总账风格;不要重新设计成 Wrapped 或 Unwrapped 风格。

相关技能