Communitygithub.com

echarrod/skillsed

Transformez l'historique Git d'un fichier en animation, une image par version visuellement différente — l'évolution d'un logo, les redesigns d'une page. Utilisez-le lorsqu'on vous demande d'animer, rejouer ou montrer l'évolution d'un logo, d'une image, d'une icône ou d'une page web au fil du temps.

Qu'est-ce que skillsed ?

Cette compétence permet de créer une animation (GIF ou MP4) retraçant l'évolution visuelle d'un fichier au fil de l'historique Git d'un dépôt. Elle est particulièrement utile pour visualiser les transformations d'un logo, d'une icône, d'une image ou d'une page web au cours du temps, en ne conservant que les versions qui diffèrent visuellement. La compétence prend en charge tous les types de fichiers image (PNG, JPG, SVG, etc.) ainsi que les pages HTML statiques ou issues de frameworks (React, Next, Vue, Astro). Elle fonctionne avec n'importe quel dépôt Git local et est compatible avec les agents comme Claude Code, Cursor ou Codex. Le processus en quatre étapes consiste à : 1) vérifier les outils nécessaires (git, ffmpeg, rsvg-convert ou Chrome), 2) identifier les fichiers pertinents dans tout l'historique Git (y compris les renommages et déplacements), 3) soit exécuter directement le script d'animation pour les images, soit générer des captures d'écran pour les pages avant de les animer, et 4) produire un rapport des résultats. La compétence gère intelligemment les déduplications visuelles, les lignées multiples, et peut même combiner des animations provenant de plusieurs dépôts différents.

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

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

animate-file-history

Construisez un GIF (ou MP4) montrant l'évolution d'un fichier au cours de la vie du dépôt. La demande est formulée en langage naturel ($ARGUMENTS), donc le travail consiste à : déterminer les fichiers concernés, collecter chaque version provenant de git, les rendre, supprimer les versions identiques à la précédente, et assembler le tout en une animation.

Le script fourni effectue le parcours git, le rendu, la déduplication visuelle et l'encodage : scripts/animate-history.sh, relativement au répertoire de base de cette compétence - pas au dépôt de l'utilisateur. Ci-dessous, $SKILL désigne ce répertoire ; appelez le script via son chemin absolu. --help liste toutes les options. Votre rôle consiste à choisir les fichiers et, pour les pages, à produire les captures d'écran.

1. Vérifier les outils

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

ffmpeg est requis. Les SVG nécessitent rsvg-convert (brew install librsvg / apt install librsvg2-bin) ou Chrome/Chromium. Les légendes --label et les pages HTML nécessitent Chrome/Chromium (CHROME=/path remplace la détection automatique). Si quelque chose manque, indiquez quoi et comment l'installer - ne supprimez pas silencieusement des versions SVG.

2. Interpréter la demande pour trouver les fichiers

Recherchez dans tout l'historique de la branche courante, pas seulement l'arborescence actuelle - les logos sont renommés, déplacés et réexportés, et les fichiers supprimés font toujours partie de l'histoire :

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

Recherchez ce que la chose est appelée, pas seulement le mot de l'utilisateur. Un logo se trouve aussi dans favicon*, apple-touch-icon*, *mark*, *lockup*, *wordmark*, *brand* et le nom du produit lui-même - les premières versions sont souvent uniquement dans le favicon. Élargissez la liste des globs en conséquence et examinez les résultats.

Filtrez pour les types rendables : png jpg jpeg gif webp bmp svg pour les images ; html pour les pages statiques. Ignorez les fichiers de construction et les copies importées (dist/, build/, node_modules/, .next/).

Regroupez ensuite les correspondances en lignées - une lignée par animation :

  • La même œuvre à travers les renommages, déplacements ou changements de format (logo.png → brand/logo.svg) constitue une lignée. Passez tous ses chemins à une seule exécution ; le script les fusionne en une seule chronologie par date de commit.
  • Les variantes coexistantes (logo-dark.svg, logo-mono.svg, favicon.png, les exportations dimensionnées comme [email protected]) sont des lignées séparées. Par défaut, une animation par lignée, et animez uniquement les variantes que la demande signifie plausiblement (généralement le logo principal, pas chaque taille de favicon).

Si le regroupement est véritablement ambigu (plusieurs fichiers "logo" sans lien, ou aucune correspondance), montrez la liste des candidats avec le nombre de commits (git log --follow --oneline -- <chemin> | wc -l) et demandez avant de rendre.

3a. Images : exécuter le script

"$SKILL/scripts/animate-history.sh" -o logo-history.gif --label <chemin> [<chemin-plus-ancien> ...]

Options utiles : -s 512 ou -s 1200x800 pour le canevas, -t 0.25 secondes par version (valeur par défaut pour les images ; les captures d'écran de pages via --frames sont par défaut à 0.8 ; utilisez la valeur de l'utilisateur s'il en a donné une, par exemple "0.5s par image" → -t 0.5), --hold 1.5 secondes sur la dernière image, --bg '#0b0b0b' pour les logos conçus pour des fonds sombres, --keep DOSSIER pour conserver les images, -o x.mp4 pour une vidéo, --skip <sha> (répétable) pour supprimer une version que l'utilisateur ne souhaite pas. Il affiche keep/skip par commit et kept N of M versions sur stderr.

Les chemins sont relatifs au répertoire courant (ou -C DOSSIER), comme tout chemin git ; exécutez depuis la racine du dépôt et passez-les tels qu'ils apparaissent dans la liste d'historique ci-dessus. Le script suit lui-même les renommages (git log --follow), donc le chemin actuel seul suffit généralement, sauf si le fichier a été recréé sous un nouveau nom.

3b. Pages : capture d'écran de chaque version, puis exécution du script sur le dossier

Une page nécessite un rendu pour chaque commit. Trouvez la source de la page (index.html, app/page.tsx, src/pages/index.vue, ...) et listez les commits qui l'ont touchée ou ce qu'elle rend - l'apparence d'une page d'accueil change également via ses composants et son CSS :

git log --format='%H %cs' --reverse -- <fichier page> <ses dossiers composants/styles>

Si cela dépasse environ 40 commits, échantillonnez (un par semaine ou par mois, plus le premier et le dernier) et mentionnez-le. Les captures d'écran vont dans un dossier nommé <YYYY-MM-DD>_<sha-court>.png, afin que les fichiers soient triés par date et que le nom devienne la légende.

  • HTML statique : pas de construction. Exportez le commit avec git archive <sha> | tar -x -C "$snap" et capturez d'écran le fichier avec "$CHROME" --headless=new --hide-scrollbars --window-size=1280,800 --screenshot=... "file://$snap/<page>.html". Supprimez $snap ensuite et conservez-le en dehors du dépôt.

  • Page avec framework (React, Next, Vue, Astro, ...) : elle doit être exécutée pour s'afficher. Utilisez snapshot-commit.sh par commit :

    "$SKILL/scripts/snapshot-commit.sh" -C <depot> -r /<route> -f https://<site production> <sha> "$shots"
    

    Il exporte le commit, installe le fichier de verrouillage de ce commit (mis en cache par fichier de verrouillage), démarre le serveur de développement (-d 'commande avec {port}' si ce n'est pas npm run dev -- --port {port}), et prend une capture via Playwright (scripts/screenshot-page.mjs, nécessite playwright-core et Chrome - celui du dépôt est trouvé via PLAYWRIGHT_DIR). Il attend que le réseau soit inactif et chaque <img>, ferme une bannière de cookies, et affiche une ligne : ok, blank, error (une page d'erreur comme "impossible de charger dans ce navigateur") ou fail (échec d'installation ou du serveur de développement). Seul ok écrit un PNG. Demandez avant d'exécuter cela si cela implique plus de quelques installations.

Vérifiez les résultats avant d'animer, ne faites pas confiance à ok seul :

  • N'empruntez jamais le node_modules actuel. Les anciens commits importent des paquets que l'arbre actuel a abandonnés (par exemple react-router-dom), et la page s'affiche vide. C'est pourquoi le script installe par commit.
  • Commits blank / error / fail : examinez le journal de développement, essayez une fois de corriger la cause (une variable d'environnement manquante, une commande -d incorrecte, --ignore-scripts sautant une étape de construction nécessaire), sinon ignorez le commit et indiquez combien.
  • Images cassées (broken-images=N sur la ligne ok, avec les URL) : ressources que le serveur de développement ne peut pas servir (chemins hébergés sur la plateforme comme /__l5e/..., fichiers gitignorés ou téléchargés). -f <site production> les récupère depuis la production. Si les images sont toujours cassées, mentionnez-le dans le rapport - ne livrez pas un GIF plein de boîtes vides en silence. Corrigez à la volée plutôt que de signaler après.
  • Examinez une planche contact des images (ffmpeg -pattern_type glob -i '*.png' -vf scale=320:-1,tile=6x6 -frames:v 1 sheet.png) avant l'exécution finale.

Ensuite :

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

Les captures d'écran identiques sont supprimées de la même manière que les images identiques, de même que les captures vides (une seule couleur unie) (--keep-blank pour les conserver). Utilisez une taille de fenêtre fixe pour chaque capture, et préférez -o x.mp4 pour les pages longues ou détaillées - les GIF de pages entières deviennent volumineux.

3c. Sur plusieurs dépôts

Lorsque le logo vit dans plusieurs dépôts (une application, un tableau de bord, un site web), exécutez le script dans chaque dépôt avec --keep <dossier> et sans --label, puis copiez chaque image conservée dans un dossier nommé <YYYY-MM-DD>_<depot>-<sha-court>.png - les lignes keep sur stderr donnent la date et le sha de chaque image conservée dans l'ordre. Ajoutez -2, -3 aux noms qui entrent en collision (plusieurs fichiers modifiés dans un même commit). Exécutez ensuite --frames <dossier> --label -t 0.25 sur le dossier fusionné pour une seule chronologie sur tous.

4. Rapport

Donnez le chemin de sortie, combien de versions ont été trouvées et combien ont été incluses dans l'animation, la plage de dates, et tout ce qui a été ignoré (non rendable, constructions échouées, échantillonnage exclu). Ouvrez-le si demandé (open x.gif). Écrivez la sortie là où l'utilisateur le souhaite, par défaut dans le répertoire courant - ne la validez jamais sauf si demandé.

Pièges

  • La déduplication se fait sur les pixels rendus, pas sur les octets. Un PNG réexporté ou un SVG reformaté est ignoré s'il s'affiche à l'identique ; un décalage d'un pixel compte comme un changement. C'est le principe - n'ajoutez pas de filtre au niveau des octets par-dessus.
  • Les SVG qui référencent des fichiers externes (polices, <image href>) s'affichent sans eux, puisque seul le SVG lui-même est extrait de l'historique. Le contenu intégré est correct.
  • Les sources GIF animées ne contribuent que leur première image.
  • Les commits de fusion ne sont pas parcourus - git log montre les modifications du fichier sur la branche qui les a effectuées, ce qui est ce que vous voulez pour une chronologie.
  • Les clones superficiels (CI, --depth 1) n'ont pas d'historique. Vérifiez git rev-parse --is-shallow-repository et suggérez git fetch --unshallow s'il affiche true.
  • Les légendes nécessitent Chrome/Chromium car les versions ffmpeg fournies manquent souvent de drawtext.

Modèle et effort

Le jugement ici est limité (choisir les fichiers, regrouper les lignées, choisir un échantillon) ; le travail lourd est le script et les boucles shell. Par défaut, utilisez Sonnet à faible effort. Opus ou un effort plus élevé n'apporte rien pour cette tâche, et un fork ou un sous-agent est inutile. Augmentez l'effort uniquement lorsque le regroupement des lignées est véritablement ambigu.

La plupart des jetons d'une exécution sont le contexte hérité de la session (CLAUDE.md, listes de compétences et d'outils, ~100k+), relu depuis le cache à chaque tour, pas le travail lui-même. Une exécution dans une session légère coûte bien moins qu'une dans une session chargée.

Repères

Mesurez avec la transcription de la session (somme des usage sur les tours de l'assistant) :

f=$(ls -t ~/.claude/projects/<projet>/*.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"
DateModèle / effortTâcheToursJetons sortieCache luCache crééRésultat
23/10/2026Sonnet 5.5 / faiblePage d'accueil storra, découverte uniquement (avant rendu)93.6k731k134kfichiers + historique de route trouvés en ~7 appels

Ajoutez une ligne par exécution (exécution complète, pas seulement la découverte) ; comparez Opus / effort plus élevé uniquement si une exécution Sonnet-faible obtient un mauvais regroupement de lignées ou d'échantillonnage.

Skills associés