/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일까지는 "sofar"로 표시) |
--tz | 이 머신의 시간대 (시간대 비트에 사용) |
--include-private | 꺼짐: 비공개 저장소는 개수에 포함되지만 이름은 공개되지 않음 |
--no-music | 트랙이 있으면 음악 켜짐 |
--format | portrait 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
활발한 계정의 경우 약 2분 소요 (커밋 히스토리는 클록 비트를 위해 샘플링됨). 총계, 일일 달력, 리듬(스트릭, 시간, 요일), 상위 저장소, 언어, 풀 리퀘스트, 신규 저장소, 올해 얻은 별, 그리고 자동화(샘플링된 커밋의 60% 이상이 동일한 메시지 템플릿을 공유하는 저장소)를 기록합니다. 자동화는 리듬 및 "work" 비트에서 제외되고 별도의 서프라이즈 비트가 됩니다.
또한 선택적, 주제별 데이터를 수집합니다: 에이전트(서명만으로 감지된 코딩 에이전트와 공동 작성된 커밋, 푸터, 앱 작성자, 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이 없으면 비공개 저장소 이름 금지.- 이모지, 대시, "crushing it" 식 표현 금지. LinkedIn에 게시될 것입니다.
- 에이전트와 자동화는 사용자가 이끄는 팀으로 프레이밍하세요 ("shipped with", "co-written with"). 절대 부끄럽게 하거나 작업이 덜한 것처럼 암시하지 마세요. 에이전트 수는 하한선입니다.
편집된 스토리로 --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 # 게이트: 오류 0개; 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과 일치하지 않는 숫자, 비어 있거나 지루한 비트, 휴대폰 크기에서 읽히지 않을 텍스트 (프레임을 540px 너비로 조정), 약한 첫 프레임. 원인을 story.json (카피)에서 수정하거나 스킬 버그로 보고하세요. 그런 다음:
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
썸네일: 클로즈 (연도 그리드, 핸들, ", in review.")를 슬라이드 카운터, 해시 레이블, 푸터 레일 또는 CTA 없이 깔끔한 스틸로 만듭니다. LinkedIn에서 동영상의 맞춤 썸네일로 업로드하고 (비디오의 4:5 종횡비와 일치하며 LinkedIn이 예상하는 형식) 표지 이미지가 필요한 곳에 사용하세요:
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, 50MB 미만, 25-75초 (빌드는 70초에 챕터 카드 포함하여 상한); poster.jpg 존재; thumbnail.png는 1080x1350이며 직접 확인함 (카운터, 레일, 잘린 부분 없음).
<out>/share-copy.txt를 작성하세요: 사용자의 목소리로 2~3개의 평문 문장, 가장 강력한 사실들 (아키타입, 숫자 하나, 프로젝트 하나)로 구성. 해시태그 벽은 안 됨; 최대 2개. 예: "My 2026 on GitHub, so far: 30 new repos, a 44-day streak, and a bot that out-committed me. Made with github-year-in-review."
사용자에게 비디오, 썸네일, 포스터 및 공유 카피의 위치와 영화가 무엇을 말하는지 한 줄로 알려주세요.
창작 규칙
- 프레임 0은 게시물. 이름, 연도 및 헤드라인 숫자, 안정적으로.
- 비트당 하나의 질문, 하나의 초점. 큰 숫자 또는 하나의 형태; 나머지는 레이블.
- 인벤토리보다 정체성. 영화는 총계가 아닌 그들이 누구였는지(아키타입)로 끝납니다.
- 정직함. 자동화는 명명되고, 비공개 이름은 숨겨지며, 부분 연도는 "sofar"라고 표시됩니다.
- 음소거 상태에서도 읽기 쉬움. 모든 비트는 소리 없이도 의미가 통합니다.
- Git, GitHub 아님. 입력된 프롬프트, 해시 레이블, diff 헝크 및 트레일러; 로고, GitHub 초록색 또는 UI 크롬 없음.
- 독창적인 외관. references/story.md의 원장 아이덴티티; Wrapped나 Unwrapped 스타일로 변경하지 마세요.