Communitygithub.com

animate-file-history

Transforme o histórico do Git de um arquivo em uma animação, um quadro por versão visualmente diferente — a evolução de um logotipo, os redesigns de uma página. Use quando solicitado a animar, reproduzir ou mostrar a evolução de um logotipo, imagem, ícone ou página web ao longo do tempo.

O que é animate-file-history?

Esta skill permite gerar animações (GIF ou MP4) a partir do histórico de versões de arquivos em um repositório Git, com foco em elementos visuais como logotipos, ícones, imagens e páginas web. Ela resolve automaticamente quais arquivos correspondem ao pedido do usuário buscando no histórico completo do branch atual, agrupa arquivos relacionados (por exemplo, logo.png → brand/logo.svg) em linhagens separadas, renderiza cada versão, remove quadros visualmente idênticos e codifica a animação final. Suporta animação de imagens (SVG, PNG, JPG, etc.) e páginas HTML estáticas ou baseadas em frameworks como React/Next/Vue/Astro. Para páginas, realiza screenshots em cada commit relevante, usando navegador headless (Chrome/Chromium) e gerenciando dependências específicas de cada commit. A skill também lida com casos complexos como arquivos espalhados por vários repositórios, amostragem de commits quando há muitos, e tratamento de erros como imagens quebradas ou builds com falha. O resultado é uma animação limpa e informativa da evolução visual do ativo.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/echarrod/skillsed/tree/HEAD/skills/animate-file-history

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

O que animate-file-history faz?

Construa um GIF (ou MP4) de como algo se parecia ao longo da vida do repositório. A solicitação está em linguagem natural ($ARGUMENTS), portanto seu trabalho é: descobrir quais arquivos ela significa, coletar cada versão deles do git, renderizar cada uma, descartar versões que pareçam iguais à anterior e unir o resto em uma animação.

O script incluído faz a navegação pelo git, renderização, deduplicação visual e codificação: scripts/animate-history.sh, relativo ao diretório base desta skill — não ao repositório do usuário. Abaixo, $SKILL representa esse diretório; chame o script pelo caminho absoluto. --help lista todas as opções. Sua parte é escolher os arquivos e, para páginas, produzir as capturas de tela.

1. Verifique as ferramentas

command -v git ffmpeg rsvg-convert; ls "/Applications/Google Chrome.app" 2>/dev/null; command -v chromium google-chrome

ffmpeg é obrigatório. SVG precisa de rsvg-convert (brew install librsvg / apt install librsvg2-bin) ou Chrome/Chromium. Legendas (--label) e páginas HTML precisam de Chrome/Chromium (CHROME=/path substitui a detecção automática). Se algo estiver faltando, informe o que e como instalar — não descarte versões SVG silenciosamente.

2. Resolva a solicitação para os arquivos

Pesquise no histórico completo do branch atual, não apenas na árvore de hoje — logotipos são renomeados, movidos e reexportados, e arquivos deletados ainda fazem parte da história:

git log --format= --name-only -- ':(glob,icase)**/*logo*' | sort -u

Pesquise pelo nome do que a coisa é chamada, não apenas pela palavra do usuário. Um logotipo também vive em favicon*, apple-touch-icon*, *mark*, *lockup*, *wordmark*, *brand* e no nome do próprio produto — versões antigas frequentemente estão apenas no favicon. Amplie a lista de globs de acordo e veja o que retorna.

Filtre para tipos renderizáveis: png jpg jpeg gif webp bmp svg para imagens; html para páginas estáticas. Ignore saída de build e cópias de terceiros (dist/, build/, node_modules/, .next/).

Em seguida, agrupe as correspondências em linhagens — uma linhagem por animação:

  • A mesma arte através de renomes, movimentos ou mudança de formato (logo.png → brand/logo.svg) é uma linhagem. Passe todos os seus caminhos para uma execução; o script os mescla em uma única linha do tempo por data de commit.
  • Variantes que coexistem (logo-dark.svg, logo-mono.svg, favicon.png, exportações com tamanhos como [email protected]) são linhagens separadas. Por padrão, uma animação por linhagem, e anime apenas as variantes que a solicitação plausivelmente significa (geralmente o logotipo principal, não todos os tamanhos de favicon).

Se o agrupamento for genuinamente ambíguo (vários arquivos "logo" não relacionados, ou nada corresponde), mostre a lista de candidatos com contagens de commits (git log --follow --oneline -- <caminho> | wc -l) e pergunte antes de renderizar.

3a. Imagens: execute o script

"$SKILL/scripts/animate-history.sh" -o logo-history.gif --label <caminho> [<caminho-mais-antigo> ...]

Opções úteis: -s 512 ou -s 1200x800 para canvas, -t 0.25 segundos por versão (padrão para imagens; capturas de página via --frames padrão é 0.8; use o valor do usuário se fornecido, ex.: "0.5s por quadro" → -t 0.5), --hold 1.5 segundos no quadro final, --bg '#0b0b0b' para logotipos desenhados para fundos escuros, --keep DIR para manter os quadros, -o x.mp4 para vídeo, --skip <sha> (repetível) para descartar uma versão que o usuário não quer. Ele imprime keep/skip por commit e manteve N de M versões no stderr.

Os caminhos são relativos ao diretório atual (ou -C DIR), como qualquer pathspec do git; execute da raiz do repositório e passe-os como a lista de histórico os mostra. O script segue renomes automaticamente (git log --follow), então o caminho atual geralmente é suficiente, a menos que o arquivo tenha sido recriado com um novo nome.

3b. Páginas: capture cada versão e depois execute o script na pasta

Uma página precisa ser renderizada em cada commit. Encontre a fonte da página (index.html, app/page.tsx, src/pages/index.vue, ...) e liste os commits que a alteraram ou o que ela renderiza — a aparência de uma página inicial também muda através de seus componentes e CSS:

git log --format='%H %cs' --reverse -- <arquivo da página> <diretórios de componentes/estilos>

Se isso for mais de ~40 commits, faça uma amostragem (um por semana ou mês, mais o primeiro e o último) e informe. As capturas vão em uma pasta nomeada <AAAA-MM-DD>_<sha-curto>.png, para que os arquivos sejam ordenados por data e o nome vire a legenda.

  • HTML estático: sem build. Exporte o commit com git archive <sha> | tar -x -C "$snap" e capture o arquivo com "$CHROME" --headless=new --hide-scrollbars --window-size=1280,800 --screenshot=... "file://$snap/<página>.html". Delete $snap depois e mantenha-o fora do repositório.

  • Página de framework (React, Next, Vue, Astro, ...): precisa ser executada para renderizar. Use snapshot-commit.sh por commit:

    "$SKILL/scripts/snapshot-commit.sh" -C <repositório> -r /<rota> -f https://<site de produção> <sha> "$shots"
    

    Ele exporta o commit, instala o próprio lockfile do commit (em cache por lockfile), inicia o servidor dev (-d 'comando com {porta}' se não for npm run dev -- --port {porta}), e captura a tela via Playwright (scripts/screenshot-page.mjs, precisa de playwright-core e Chrome — o do repositório é encontrado via PLAYWRIGHT_DIR). Ele espera pela rede inativa e cada <img>, descarta um banner de cookies e imprime uma linha: ok, blank, error (uma página de erro como "não foi possível carregar neste navegador") ou fail (instalação ou servidor dev). Apenas ok escreve um PNG. Pergunte antes de executar isso se significar mais do que algumas instalações.

Verifique os resultados antes de animar, não confie apenas em ok:

  • Nunca pegue emprestado o node_modules atual. Commits antigos importam pacotes que a árvore atual descartou (ex.: react-router-dom), e a página renderiza em branco. Por isso o script instala por commit.
  • Commits blank / error / fail: veja o log do dev, tente uma vez corrigir a causa (variável de ambiente faltando, comando -d errado, --ignore-scripts pulando uma etapa de build necessária), caso contrário pule o commit e informe quantos.
  • Imagens quebradas (broken-images=N na linha de ok, com as URLs): ativos que o servidor dev não consegue servir (caminhos hospedados em plataforma como /__l5e/..., arquivos gitignorados ou enviados). -f <site de produção> os busca da produção. Se as imagens ainda estiverem quebradas, informe no relatório — não envie um GIF cheio de caixas vazias silenciosamente. Corrija na hora em vez de relatar depois.
  • Veja uma folha de contato dos quadros (ffmpeg -pattern_type glob -i '*.png' -vf scale=320:-1,tile=6x6 -frames:v 1 sheet.png) antes da execução final.

Então:

"$SKILL/scripts/animate-history.sh" --frames "$shots" -s 1280x800 --label -o home-page-history.gif

Capturas idênticas são descartadas da mesma forma que imagens idênticas, assim como as em branco (uma cor sólida) (--keep-blank para mantê-las). Use um tamanho de janela fixo para cada captura e prefira -o x.mp4 para páginas longas ou detalhadas — GIFs de páginas completas ficam grandes.

3c. Em vários repositórios

Quando o logotipo vive em mais de um repositório (um app, um dashboard, um site), execute o script em cada repositório com --keep <dir> e sem --label, depois copie cada quadro mantido em uma pasta nomeada <AAAA-MM-DD>_<repositório>-<sha-curto>.png — as linhas keep no stderr fornecem a data e o sha de cada quadro mantido em ordem. Adicione -2, -3 a nomes que colidem (vários arquivos alterados em um commit). Em seguida, execute --frames <pasta> --label -t 0.25 na pasta mesclada para obter uma única linha do tempo em todos eles.

4. Relatório

Informe o caminho de saída, quantas versões foram encontradas e quantas entraram na animação, o intervalo de datas e qualquer coisa pulada (não renderizável, builds com falha, amostrada). Abra se solicitado (open x.gif). Escreva a saída onde o usuário quiser, padronizando para o diretório atual — nunca faça commit a menos que seja solicitado.

Pegadinhas

  • A deduplicação é nos pixels renderizados, não nos bytes. Um PNG reexportado ou SVG reformatado é pulado se renderizar de forma idêntica; um deslocamento de um pixel conta como mudança. Esse é o ponto — não adicione um filtro de nível de byte por cima.
  • SVGs que referenciam arquivos externos (fontes, <image href>) renderizam sem eles, já que apenas o próprio SVG é extraído do histórico. Conteúdo incorporado é tranquilo.
  • Fontes de GIF animado contribuem apenas com seu primeiro quadro.
  • Commits de merge não são percorridos — git log mostra as alterações do arquivo no branch que as fez, que é o que você quer para uma linha do tempo.
  • Clones rasos (CI, --depth 1) não têm histórico. Verifique git rev-parse --is-shallow-repository e sugira git fetch --unshallow se imprimir true.
  • Legendas precisam de Chrome/Chromium porque as builds de ffmpeg incluídas frequentemente não têm drawtext.

Modelo e esforço

O julgamento aqui é pequeno (escolher arquivos, agrupar linhagens, escolher uma amostra); o trabalho pesado é o script e os loops de shell. Padrão para Sonnet com baixo esforço. Opus ou esforço maior não acrescenta nada para esta tarefa, e um fork ou subagente é desnecessário. Aumente o esforço apenas quando o agrupamento de linhagens for genuinamente ambíguo.

A maior parte dos tokens de uma execução é o contexto herdado da sessão (CLAUDE.md, listas de skills e ferramentas, ~100k+), relido do cache a cada turno, não o trabalho em si. Uma execução em uma sessão enxuta custa muito menos do que uma em uma sessão carregada.

Benchmarks

Meça com a transcrição da sessão (soma usage nos turnos do assistente):

f=$(ls -t ~/.claude/projects/<diretório-do-projeto>/*.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"
DataModelo / esforçoTarefaTurnosTokens de saídaCache lidoCache criadoResultado
2026-10-23Sonnet 5.5 / baixoPágina inicial da storra, apenas descoberta (antes da renderização)93.6k731k134karquivos + histórico de rota encontrados em ~7 chamadas

Adicione uma linha por execução (execução completa, não apenas descoberta); compare Opus / esforço maior apenas se uma execução Sonnet-baixo errar a linhagem ou a amostragem.

Habilidades Relacionadas