animate-file-history은(는) 무엇을 하나요?
저장소 수명 동안의 모습을 GIF(또는 MP4)로 만들어 보세요. 요청은 일반 언어($ARGUMENTS)로 전달되며, 작업은 다음과 같습니다: 어떤 파일을 의미하는지 파악하고, Git에서 각 버전을 수집한 후, 각각을 렌더링하고, 이전 버전과 동일하게 보이는 버전은 제거한 뒤 나머지를 애니메이션으로 연결합니다.
번들 스크립트가 Git 워킹, 렌더링, 시각적 중복 제거 및 인코딩을 처리합니다:
scripts/animate-history.sh (이 스킬의 기본 디렉토리 기준 - 사용자 저장소 기준이 아님). 아래에서 $SKILL은 해당 디렉토리를 나타냅니다; 스크립트는 절대 경로로 호출하세요. --help로 모든 옵션을 볼 수 있습니다. 당신의 역할은 파일을 선택하고, 페이지의 경우 스크린샷을 생성하는 것입니다.
1. 도구 확인
command -v git ffmpeg rsvg-convert; ls "/Applications/Google Chrome.app" 2>/dev/null; command -v chromium google-chrome
ffmpeg는 필수입니다. SVG는 rsvg-convert(brew install librsvg / apt install librsvg2-bin) 또는 Chrome/Chromium이 필요합니다. --label 캡션과 HTML 페이지는 Chrome/Chromium이 필요합니다(CHROME=/path로 감지 재정의). 누락된 것이 있으면 무엇인지와 설치 방법을 알려주세요. SVG 버전을 조용히 건너뛰지 마세요.
2. 요청을 파일로 해석
현재 브랜치의 전체 히스토리를 검색하세요. 오늘의 트리뿐만 아니라 - 로고는 이름이 바뀌고, 이동되고, 다시 내보내지며, 삭제된 파일도 여전히 이야기에 속합니다:
git log --format= --name-only -- ':(glob,icase)**/*logo*' | sort -u
사용자의 단어뿐만 아니라 해당 대상의 명칭으로 검색하세요. 로고는 favicon*, apple-touch-icon*, *mark*, *lockup*, *wordmark*, *brand* 및 제품 자체 이름에도 존재합니다 - 초기 버전은 종종 파비콘에만 있습니다. 그에 따라 glob 목록을 넓히고 반환된 결과를 확인하세요.
렌더링 가능한 형식으로 필터링: 이미지는 png jpg jpeg gif webp bmp svg; 정적 페이지는 html. 빌드 출력물과 벤더 복사본(dist/, build/, node_modules/, .next/)은 무시하세요.
그런 다음 일치 항목을 **계통(lineages)**으로 그룹화합니다 - 각 애니메이션당 하나의 계통:
- 이름 변경, 이동 또는 형식 변경(
logo.png→brand/logo.svg)을 거친 동일한 아트워크는 하나의 계통입니다. 모든 경로를 한 번의 실행에 전달하면 스크립트가 커밋 날짜별로 단일 타임라인으로 병합합니다. - 공존하는 변형(
logo-dark.svg,logo-mono.svg,favicon.png, 크기별 내보내기[email protected])은 별도의 계통입니다. 기본적으로 계통당 하나의 애니메이션을 만들고, 요청이 그럴듯하게 의미하는 변형만 애니메이션화합니다(보통 기본 로고, 모든 파비콘 크기는 아님).
그룹화가 진정으로 모호한 경우(여러 관련 없는 "logo" 파일이 있거나 일치하는 항목이 없는 경우), 커밋 수(git log --follow --oneline -- <path> | wc -l)와 함께 후보 목록을 표시하고 렌더링 전에 질문하세요.
3a. 이미지: 스크립트 실행
"$SKILL/scripts/animate-history.sh" -o logo-history.gif --label <path> [<older-path> ...]
유용한 옵션: -s 512 또는 -s 1200x800 캔버스 크기, -t 0.25 버전당 초(이미지 기본값; 페이지 스크린샷은 --frames를 통해 기본값 0.8; 사용자가 값을 제공한 경우 사용, 예: "0.5s per frame" → -t 0.5), 최종 프레임에 --hold 1.5초, 어두운 배경용 로그에 --bg '#0b0b0b', 프레임 유지에 --keep DIR, 비디오용 -o x.mp4, 사용자가 원하지 않는 버전 제거에 --skip <sha>(반복 가능). stderr에 커밋당 keep/skip 및 M개 버전 중 N개 유지됨을 출력합니다.
경로는 다른 git pathspec과 마찬가지로 현재 디렉토리(또는 -C DIR) 기준입니다; 저장소 루트에서 실행하고 히스토리 목록에 표시된 대로 전달하세요. 스크립트 자체가 이름 변경을 추적하므로(git log --follow), 파일이 새 이름으로 다시 생성되지 않는 한 일반적으로 현재 경로만으로 충분합니다.
3b. 페이지: 각 버전 스크린샷을 찍고 폴더에서 스크립트 실행
페이지는 각 커밋에서 렌더링이 필요합니다. 페이지 소스(index.html, app/page.tsx, src/pages/index.vue, ...)를 찾고 해당 페이지 또는 렌더링하는 항목을 건드린 커밋을 나열하세요 - 홈페이지의 모양은 컴포넌트와 CSS를 통해서도 변경됩니다:
git log --format='%H %cs' --reverse -- <page file> <its components/styles dirs>
약 40개 이상의 커밋이면 샘플링(주당 또는 월당 하나씩, 처음과 마지막 포함)하고 그렇게 말하세요. 스크린샷은 <YYYY-MM-DD>_<short-sha>.png 이름으로 한 폴더에 저장되므로 파일이 날짜별로 정렬되고 이름이 캡션이 됩니다.
-
정적 HTML: 빌드 불필요.
git archive <sha> | tar -x -C "$snap"로 커밋을 내보내고"$CHROME" --headless=new --hide-scrollbars --window-size=1280,800 --screenshot=... "file://$snap/<page>.html"로 스크린샷을 찍습니다. 이후$snap을 삭제하고 저장소 외부에 보관하세요. -
프레임워크 페이지(React, Next, Vue, Astro, ...): 렌더링하려면 실행해야 합니다. 커밋당
snapshot-commit.sh를 사용하세요:"$SKILL/scripts/snapshot-commit.sh" -C <repo> -r /<route> -f https://<production site> <sha> "$shots"커밋을 내보내고, 해당 커밋의 자체 lockfile(lockfile별로 캐시됨)을 설치하고, 개발 서버(
npm run dev -- --port {port}가 아닌 경우-d 'cmd with {port}')를 시작하고, Playwright(scripts/screenshot-page.mjs,playwright-core와 Chrome 필요 - 저장소 자체의 것은PLAYWRIGHT_DIR을 통해 찾음)를 통해 스크린샷을 찍습니다. 네트워크 유휴 상태와 모든<img>를 기다리고, 쿠키 배너를 닫으며, 한 줄(ok,blank,error(브라우저에서 로드할 수 없음과 같은 오류 페이지) 또는fail(설치 또는 개발 서버))을 출력합니다.ok만 PNG를 씁니다. 설치가 몇 개 이상인 경우 실행하기 전에 질문하세요.
애니메이션 전에 결과를 확인하고 ok만 신뢰하지 마세요:
- 현재
node_modules를 절대 빌리지 마세요. 이전 커밋은 현재 트리에 없는 패키지(예:react-router-dom)를 가져오며 페이지가 빈 상태로 렌더링됩니다. 이것이 스크립트가 커밋별로 설치하는 이유입니다. blank/error/fail커밋: 개발 로그를 보고, 원인을 한 번 해결해 보세요(누락된 환경 변수, 잘못된-d명령, 필요한 빌드 단계를 건너뛰는--ignore-scripts). 그렇지 않으면 커밋을 건너뛰고 개수를 알리세요.- 깨진 이미지(
ok라인에broken-images=N및 URL 포함): 개발 서버가 제공할 수 없는 자산(플랫폼 호스팅 경로/__l5e/..., gitignore된 파일 또는 업로드된 파일).-f <production site>가 프로덕션에서 가져옵니다. 이미지가 여전히 깨져 있으면 보고서에 알리세요 - 빈 상자가 가득한 GIF를 조용히 보내지 마세요. 사후 보고보다는 즉석에서 수정하세요. - 최종 실행 전에 프레임 접촉 시트(
ffmpeg -pattern_type glob -i '*.png' -vf scale=320:-1,tile=6x6 -frames:v 1 sheet.png)를 확인하세요.
그런 다음:
"$SKILL/scripts/animate-history.sh" --frames "$shots" -s 1280x800 --label -o home-page-history.gif
동일한 스크린샷은 동일한 이미지와 동일한 방식으로 제거되며, 빈(단일 색상) 스크린샷도 제거됩니다(--keep-blank로 유지). 모든 샷에 고정 창 크기를 사용하고, 길거나 상세한 페이지의 경우 -o x.mp4를 선호하세요 - 전체 페이지의 GIF는 커집니다.
3c. 여러 저장소에 걸쳐
로고가 둘 이상의 저장소(앱, 대시보드, 웹사이트)에 존재하는 경우, 각 저장소에서 --keep <dir> 및 --label 없이 스크립트를 실행한 다음, 각 유지된 프레임을 <YYYY-MM-DD>_<repo>-<short-sha>.png 이름으로 한 폴더에 복사하세요 - stderr의 keep 라인이 각 유지된 프레임의 날짜와 sha를 순서대로 제공합니다. 충돌하는 이름(한 커밋에서 여러 파일이 변경된 경우)에는 -2, -3을 추가하세요. 그런 다음 병합된 폴더에서 --frames <folder> --label -t 0.25를 실행하여 모든 저장소에 걸친 하나의 타임라인을 만드세요.
4. 보고
출력 경로, 발견된 버전 수와 애니메이션에 포함된 버전 수, 날짜 범위, 건너뛴 항목(렌더링 불가, 빌드 실패, 샘플링 제외)을 제공하세요. 요청 시 열기(open x.gif). 출력은 사용자가 원하는 위치에 쓰고, 기본값은 현재 디렉토리입니다 - 요청하지 않는 한 절대 커밋하지 마세요.
주의사항
- 중복 제거는 바이트가 아닌 렌더링된 픽셀을 기준으로 합니다. 동일하게 렌더링되는 경우 다시 내보낸 PNG 또는 재포맷된 SVG는 건너뜁니다; 1픽셀 이동은 변경으로 간주됩니다. 그것이 요점입니다 - 바이트 수준 필터를 추가하지 마세요.
- 외부 파일을 참조하는 SVG(글꼴,
<image href>)는 SVG 자체만 히스토리에서 가져오므로 해당 파일 없이 렌더링됩니다. 포함된 콘텐츠는 괜찮습니다. - 애니메이션 GIF 소스의 첫 번째 프레임만 사용됩니다.
- 병합 커밋은 탐색되지 않습니다 -
git log는 파일을 변경한 브랜치의 변경 사항을 표시하며, 타임라인에 원하는 것입니다. - 얕은 클론(CI,
--depth 1)에는 히스토리가 없습니다.git rev-parse --is-shallow-repository를 확인하고true를 출력하면git fetch --unshallow를 제안하세요. - 캡션은 번들 ffmpeg 빌드에
drawtext가 없는 경우가 많으므로 Chrome/Chromium이 필요합니다.
모델 및 노력
판단은 적습니다(파일 선택, 계통 그룹화, 샘플 선택); 무거운 작업은 스크립트와 쉘 루프가 담당합니다. 기본적으로 낮은 노력의 Sonnet을 사용하세요. Opus 또는 더 높은 노력은 이 작업에 아무 이점도 없으며, 포크나 서브에이전트는 불필요합니다. 계통 그룹화가 진정으로 모호할 때만 노력을 높이세요.
대부분의 실행 토큰은 세션의 상속된 컨텍스트(CLAUDE.md, 스킬 및 도구 목록, 약 100k+)로서, 작업 자체가 아니라 매 턴 캐시에서 다시 읽습니다. 가벼운 세션의 실행 비용은 로드된 세션보다 훨씬 저렴합니다.
벤치마크
세션 대화록으로 측정(어시스턴트 턴의 usage 합계):
f=$(ls -t ~/.claude/projects/<project-dir>/*.jsonl | head -1)
jq -s '[.[]|select(.message.usage)|.message.usage]|{turns:length,out:(map(.output_tokens)|add),cache_read:(map(.cache_read_input_tokens)|add),cache_create:(map(.cache_creation_input_tokens)|add)}' "$f"
| 날짜 | 모델 / 노력 | 작업 | 턴 수 | 출력 토큰 | 캐시 읽기 | 캐시 생성 | 결과 |
|---|---|---|---|---|---|---|---|
| 2026-10-23 | Sonnet 5.5 / 낮음 | storra 홈페이지, 발견만(렌더링 전) | 9 | 3.6k | 731k | 134k | 파일 + 라우트 히스토리 발견 (~7회 호출) |
실행당 한 행씩 추가합니다(전체 실행, 발견만 아님); Sonnet-낮음 실행이 계통이나 샘플링을 잘못한 경우에만 Opus/더 높은 노력과 비교하세요.