Communitygithub.com

echarrod/skillsed

Verwandle die Git-Historie einer Datei in eine Animation, ein Frame pro visuell unterschiedlicher Version – die Entwicklung eines Logos, die Neugestaltungen einer Seite. Verwende es, wenn du aufgefordert wirst, die Entwicklung eines Logos, Bildes, Icons oder einer Webseite über die Zeit zu animieren, wiederzugeben oder zu zeigen.

Was ist skillsed?

Diese Fähigkeit erstellt eine GIF- oder MP4-Animation aus der Git-Historie einer Datei. Sie extrahiert jede Version einer oder mehrerer Dateien aus der Versionsgeschichte, rendert sie (bei Bildern direkt, bei Webseiten als Screenshots), filtert optisch identische Versionen heraus und setzt die restlichen zu einer Animation zusammen. Das beigefügte Skript `animate-history.sh` übernimmt das Durchlaufen der Git-Historie, das Rendern, die visuelle Deduplizierung und die Kodierung. Der Benutzer muss lediglich die relevanten Dateien identifizieren und bei Webseiten die Screenshots erstellen. Die Fähigkeit erfordert `ffmpeg`, optional `rsvg-convert` für SVGs und Chrome/Chromium für Beschriftungen und HTML-Seiten. Sie unterstützt mehrere Repositories, benannte Versionen, benutzerdefinierte Bildraten, Haltezeiten und Ausgabeformate. Der Schwerpunkt liegt auf Effizienz: Standardmäßig wird ein Modell mit geringem Aufwand (Sonnet) empfohlen, da die Hauptarbeit vom Skript und Shell-Schleifen erledigt wird.

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

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Dateiverlauf animieren

Erstelle ein GIF (oder MP4) davon, wie etwas im Laufe des Lebens des Repositorys aussah. Die Anfrage erfolgt in natürlicher Sprache ($ARGUMENTS), also besteht die Aufgabe darin: herauszufinden, welche Dateien gemeint sind, jede Version von ihnen aus Git zu sammeln, jede zu rendern, Versionen zu verwerfen, die genauso aussehen wie die vorherige, und die restlichen zu einer Animation zusammenzufügen.

Das gebündelte Skript erledigt das Git-Durchlaufen, Rendern, visuelle Deduplizieren und Kodieren: scripts/animate-history.sh, relativ zum Basisverzeichnis dieser Fähigkeit – nicht zum Repository des Benutzers. Im Folgenden steht $SKILL für dieses Verzeichnis; rufe das Skript mit seinem absoluten Pfad auf. --help listet alle Optionen auf. Dein Teil ist es, die Dateien auszuwählen und bei Seiten die Screenshots zu erstellen.

1. Prüfe die Werkzeuge

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

ffmpeg wird benötigt. Für SVGs wird rsvg-convert benötigt (brew install librsvg / apt install librsvg2-bin) oder Chrome/Chromium. --label Beschriftungen und HTML-Seiten benötigen Chrome/Chromium (CHROME=/path überschreibt die Erkennung). Wenn etwas fehlt, sage was und wie man es installiert – lasse keine SVG-Versionen stillschweigend weg.

2. Löse die Anfrage in Dateien auf

Durchsuche die gesamte Historie des aktuellen Branches, nicht nur den heutigen Baum – Logos werden umbenannt, verschoben und neu exportiert, und gelöschte Dateien gehören trotzdem zur Geschichte:

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

Suche nach dem, wie das Ding heißt, nicht nur nach dem Wort des Benutzers. Ein Logo lebt auch in favicon*, apple-touch-icon*, *mark*, *lockup*, *wordmark*, *brand* und dem eigentlichen Produktnamen – frühe Versionen sind oft nur im Favicon. Erweitere die Glob-Liste entsprechend und schaue, was zurückkommt.

Filtere nach renderbaren Typen: png jpg jpeg gif webp bmp svg für Bilder; html für statische Seiten. Ignoriere Build-Ausgaben und eingekaufte Kopien (dist/, build/, node_modules/, .next/).

Gruppiere dann die Treffer in Abstammungslinien – eine Abstammungslinie pro Animation:

  • Dasselbe Kunstwerk über Umbenennungen, Verschiebungen oder einen Formatwechsel hinweg (logo.png → brand/logo.svg) ist eine Abstammungslinie. Übergib alle seine Pfade an einen Durchlauf; das Skript führt sie in einer einzigen Zeitleiste nach Commit-Datum zusammen.
  • Varianten, die nebeneinander existieren (logo-dark.svg, logo-mono.svg, favicon.png, exportierte Größen wie [email protected]) sind getrennte Abstammungslinien. Standardmäßig wird eine Animation pro Abstammungslinie erstellt, und es werden nur die Varianten animiert, die die Anfrage plausibel meint (normalerweise das primäre Logo, nicht jede Favicon-Größe).

Wenn die Gruppierung wirklich mehrdeutig ist (mehrere nicht zusammenhängende "Logo"-Dateien, oder nichts passt), zeige die Kandidatenliste mit Commit-Anzahlen (git log --follow --oneline -- <pfad> | wc -l) und frage vor dem Rendern.

3a. Bilder: Führe das Skript aus

"$SKILL/scripts/animate-history.sh" -o logo-history.gif --label <pfad> [<älterer-pfad> ...]

Nützliche Optionen: -s 512 oder -s 1200x800 Leinwand, -t 0.25 Sekunden pro Version (Standard für Bilder; Seitenscreenshots via --frames standardmäßig 0,8; verwende den Wert des Benutzers, wenn er einen angegeben hat, z.B. "0,5s pro Frame" → -t 0.5), --hold 1.5 Sekunden auf dem letzten Frame, --bg '#0b0b0b' für Logos, die für dunkle Hintergründe gezeichnet wurden, --keep VERZ um die Frames zu behalten, -o x.mp4 für Video, --skip <sha> (wiederholbar) um eine Version zu verwerfen, die der Benutzer nicht möchte. Es gibt keep/skip pro Commit und behielt N von M Versionen auf stderr aus.

Pfade sind relativ zum aktuellen Verzeichnis (oder -C VERZ), wie bei jedem Git-Pfadspezifikator; führe das Skript vom Repository-Stamm aus und übergib sie so, wie die Historie sie oben zeigt. Das Skript folgt selbst Umbenennungen (git log --follow), daher reicht der aktuelle Pfad normalerweise aus, es sei denn, die Datei wurde unter einem neuen Namen neu erstellt.

3b. Seiten: Screenshot jeder Version, dann führe das Skript im Ordner aus

Eine Seite muss bei jedem Commit gerendert werden. Finde die Quelle der Seite (index.html, app/page.tsx, src/pages/index.vue, ...) und liste die Commits auf, die sie oder das, was sie rendert, berührt haben – das Aussehen einer Startseite ändert sich auch durch ihre Komponenten und CSS:

git log --format='%H %cs' --reverse -- <seitendatei> <ihre komponenten-/styles-verzeichnisse>

Wenn das mehr als ~40 Commits sind, nimm eine Stichprobe (eine pro Woche oder Monat, plus den ersten und letzten) und sage dies. Screenshots kommen in einen Ordner mit dem Namen <JJJJ-MM-TT>_<kurzer-sha>.png, damit die Dateien nach Datum sortieren und der Name zur Beschriftung wird.

  • Statisches HTML: kein Build. Exportiere den Commit mit git archive <sha> | tar -x -C "$snap" und mache einen Screenshot der Datei mit "$CHROME" --headless=new --hide-scrollbars --window-size=1280,800 --screenshot=... "file://$snap/<seite>.html". Lösche $snap danach und behalte es außerhalb des Repositorys.

  • Framework-Seite (React, Next, Vue, Astro, ...): Sie muss laufen, um zu rendern. Verwende snapshot-commit.sh pro Commit:

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

    Es exportiert den Commit, installiert die Lockdatei dieses Commits (pro Lockdatei zwischengespeichert), startet den Dev-Server (-d 'Befehl mit {port}' wenn es nicht npm run dev -- --port {port} ist) und macht einen Screenshot über Playwright (scripts/screenshot-page.mjs, benötigt playwright-core und Chrome – das eigene des Repos wird gefunden über PLAYWRIGHT_DIR). Es wartet auf Netzwerkinaktivität und jedes <img>, schließt ein Cookie-Banner und gibt eine Zeile aus: ok, blank, error (eine Fehlerseite wie "konnte in diesem Browser nicht geladen werden") oder fail (Installation oder Dev-Server). Nur ok schreibt ein PNG. Frage vor der Ausführung, wenn dies mehr als eine Handvoll Installationen bedeutet.

Überprüfe die Ergebnisse vor dem Animieren, vertraue nicht blind auf ok:

  • Verwende niemals das aktuelle node_modules. Alte Commits importieren Pakete, die der aktuelle Baum fallen gelassen hat (z.B. react-router-dom), und die Seite wird leer gerendert. Deshalb installiert das Skript pro Commit.
  • blank / error / fail Commits: Sieh dir das Entwickler-Log an, versuche einmal, die Ursache zu beheben (eine fehlende Umgebungsvariable, ein falscher -d Befehl, --ignore-scripts, das einen benötigten Build-Schritt überspringt), überspringe andernfalls den Commit und sage wie viele.
  • Kaputte Bilder (broken-images=N in der ok-Zeile, mit den URLs): Assets, die der Dev-Server nicht ausliefern kann (plattform-gehostete Pfade wie /__l5e/..., git-ignorierte oder hochgeladene Dateien). -f <Produktionsseite> holt sie von der Produktion. Wenn Bilder immer noch kaputt sind, sage dies im Bericht – liefere nicht stillschweigend ein GIF voller leerer Boxen aus. Behebe es im laufenden Betrieb, anstatt danach zu berichten.
  • Sieh dir ein Kontaktblatt der Frames an (ffmpeg -pattern_type glob -i '*.png' -vf scale=320:-1,tile=6x6 -frames:v 1 sheet.png) vor dem endgültigen Durchlauf.

Dann:

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

Identische Screenshots werden auf die gleiche Weise wie identische Bilder verworfen, ebenso wie leere (einfarbige) (--keep-blank um sie zu behalten). Verwende eine feste Fenstergröße für jeden Shot und bevorzuge -o x.mp4 für lange oder detaillierte Seiten – GIFs von ganzen Seiten werden groß.

3c. Über mehrere Repos hinweg

Wenn das Logo in mehr als einem Repo lebt (eine App, ein Dashboard, eine Website), führe das Skript in jedem Repo mit --keep <verz> und ohne --label aus, kopiere dann jeden behaltenen Frame in einen Ordner mit dem Namen <JJJJ-MM-TT>_<repo>-<kurzer-sha>.png – die keep-Zeilen auf stderr geben das Datum und den Sha jedes behaltenen Frames in Reihenfolge an. Füge -2, -3 zu Namen hinzu, die kollidieren (mehrere Dateien wurden in einem Commit geändert). Führe dann --frames <ordner> --label -t 0.25 auf dem zusammengeführten Ordner aus, um eine einzige Zeitleiste über alle hinweg zu erhalten.

4. Bericht

Gib den Ausgabepfad an, wie viele Versionen gefunden wurden und wie viele es in die Animation geschafft haben, den Datumsbereich und alles, was übersprungen wurde (nicht renderbar, fehlgeschlagene Builds, ausgestichprobt). Öffne es, wenn darum gebeten wird (open x.gif). Schreibe die Ausgabe dorthin, wo der Benutzer sie haben möchte, standardmäßig in das aktuelle Verzeichnis – committe sie nie, es sei denn, darum gebeten.

Fallstricke

  • Die Deduplizierung erfolgt auf Basis gerenderter Pixel, nicht von Bytes. Ein neu exportiertes PNG oder neu formatiertes SVG wird übersprungen, wenn es identisch rendert; eine Verschiebung um ein Pixel zählt als Änderung. Das ist der Sinn – füge keinen Byte-Level-Filter hinzu.
  • SVGs, die auf externe Dateien verweisen (Schriftarten, <image href>) rendern ohne sie, da nur das SVG selbst aus der Historie geholt wird. Eingebettete Inhalte sind in Ordnung.
  • Animierte GIF-Quellen tragen nur ihren ersten Frame bei.
  • Merge-Commits werden nicht durchlaufen – git log zeigt die Änderungen der Datei auf dem Branch, der sie vorgenommen hat, was für eine Zeitleiste gewünscht ist.
  • Flache Klone (CI, --depth 1) haben keine Historie. Überprüfe git rev-parse --is-shallow-repository und schlage git fetch --unshallow vor, wenn es true ausgibt.
  • Beschriftungen benötigen Chrome/Chromium, weil die gebündelten ffmpeg-Builds oft drawtext fehlt.

Modell und Aufwand

Das Urteilsvermögen hier ist gering (Dateien auswählen, Abstammungslinien gruppieren, eine Stichprobe wählen); die Hauptarbeit liegt im Skript und Shell-Schleifen. Standardmäßig Sonnet mit geringem Aufwand. Opus oder höherer Aufwand bringt für diese Aufgabe nichts, und ein Fork oder Subagent ist unnötig. Erhöhe den Aufwand nur, wenn die Gruppierung der Abstammungslinien wirklich mehrdeutig ist.

Die meisten Tokens eines Durchlaufs sind der geerbte Kontext der Sitzung (CLAUDE.md, Fähigkeits- und Werkzeuglisten, ~100k+), der jedes Mal aus dem Cache gelesen wird, nicht die Arbeit selbst. Ein Durchlauf in einer schlanken Sitzung kostet weit weniger als einer in einer vollen.

Benchmarks

Messe mit dem Sitzungsprotokoll (summiere usage über die Assistenten-Durchgänge):

f=$(ls -t ~/.claude/projects/<projekt-verz>/*.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"
DatumModell / AufwandAufgabeDurchgängeAusgabe TokCache gelesenCache erstelltErgebnis
2026-10-23Sonnet 5.5 / niedrigstorra Startseite, nur Erkundung (vor dem Rendern)93.6k731k134kDateien + Routenhistorie in ~7 Aufrufen gefunden

Füge eine Zeile pro Durchlauf hinzu (vollständiger Durchlauf, nicht nur Erkundung); vergleiche Opus / höheren Aufwand nur, wenn ein Sonnet-niedrig-Durchlauf die Abstammungslinie oder Stichprobenziehung falsch macht.

Verwandte Skills