Was macht pr-demo?
Ein Reviewer sollte eine Änderung in deutlich unter einer Minute verstehen, ohne das Diff öffnen zu müssen: was sich geändert hat, wie es jetzt funktioniert, der Nachweis, dass es funktioniert, und wo man nachsehen muss. Repository-Fakten – Bildunterschriftensprache, wie der geänderte Fluss aufgezeichnet wird, wohin gepostet wird – stehen in .claude/profiles/delivery.md (Demo, Notify).
Kurz und knapp schlägt vollständig. Fünf Szenen in 30 Sekunden, in dieser Reihenfolge, und lasse weg, was die Änderung nicht hat, anstatt es aufzufüllen:
- Was sich geändert hat – der Titel und höchstens drei Aufzählungspunkte.
- Wie es jetzt funktioniert – der Ablauf, mit dem geänderten Knoten markiert.
- Vorher und nachher – nur für etwas Sichtbares; bei einer Backend-Änderung überspringen.
- Die Korrektur in Aktion – die Aufnahme, auf den relevanten Teil beschnitten, unter 12 s.
- Nachweis – Die Prüfungen des Prüfschlüssels und die Tests in einer
key-Szene. Sie beantworten dieselbe Frage, daher bekommen sie keine eigene Szene.
1. Material sammeln
In out/demo/<pr oder issue>/ (git-ignoriert):
- Die Belege des Prüfschlüssels:
out/review-key/<n>/result.jsonund daskey-reviewer-Urteil (review-key). - Screenshots für eine sichtbare Änderung: dieselbe Ansicht vorher (der Basis-Branch) und nachher, gleiche Größe und Daten. Auf den geänderten Teil zuschneiden; eine ganze Seite bei 1280 px macht die Änderung zu klein.
- Eine Aufnahme des geänderten Flusses (der Demo-Befehl des Profils oder Playwright mit
browser.newContext({ recordVideo: { dir, size: { width: 1280, height: 800 } }, viewport: { width: 1280, height: 800 } })um die Schritte des E2E-Checks, der sie abdeckt; die Datei erscheint, wenn der Kontext geschlossen wird). Unter 20 s halten: auf dem relevanten Bildschirm beginnen, keine Logins vor der Kamera. - Der Ablauf der Änderung als Mermaid
flowchart LR(oderTD): fünf bis neun Knoten, der Pfad des Benutzers oder der Anfrage, mit:::changedauf dem, was sich geändert hat,:::addedauf dem, was neu ist, und:::removedauf dem, was entfernt wurde. Verhalten erklären, nicht Dateien. - Tests, die gelaufen sind, mit je einer Zahl (
476 tests,12 flows).
2. demo.json schreiben
Neben dem Material (Pfade relativ dazu). Text in der Bildunterschriftensprache des Profils; kurz – eine Szene wird in ihren Sekunden gelesen. Backticks und **fett** funktionieren.
{
"lang": "de",
"brand": "**shop** · PR #352",
"ref": "Schließt #331",
"kicker": "Bugfix",
"title": "Der Checkout passt bei 1280 px",
"subtitle": "Der Bezahl-Button bedeckte den Warenkorb, und das Coupon-Feld war 49 px breit.",
"chips": [{ "text": "Prüfschlüssel: BESTANDEN", "ok": true }, "3 Dateien"],
"scenes": [
{ "type": "title", "seconds": 3 },
{ "type": "bullets", "items": ["…", "…", "…"], "seconds": 5 },
{ "type": "flow", "mermaid": "flowchart LR\n A[Breite] --> B{\"< 1440 px?\"}\n B -- ja --> C[Icons]:::changed", "seconds": 6 },
{ "type": "compare", "before": "before.png", "after": "after.png", "seconds": 5 },
{ "type": "clip", "heading": "Aufgenommen bei 1280 px", "src": "run.webm", "caption": "e2e: checkout-fit", "speed": 1.5, "maxSeconds": 12 },
{ "type": "key", "result": "../../review-key/331/result.json", "baseFails": true, "seconds": 7,
"rows": [{ "ok": true, "text": "`verify.sh` · 476 Tests" }] },
{ "type": "end", "title": „Bereit zur Überprüfung", "lines": ["PR: **github.com/…/pull/352**", "3 am: …"], "seconds": 3 }
]
}
Szenen: title, bullets (items, höchstens vier), flow (mermaid, legend: false zum Ausblenden der Legende), compare
(before, after, Labels; layout: "stack" legt sie übereinander, für breite Streifen wie eine Toolbar), clip (src .webm/.mp4, from/to Sekunden, speed, maxSeconds Standard 20, crop
{x, y, w, h} in Pixeln der Aufnahme, um auf den relevanten Teil zu zoomen; die Länge kommt aus der Datei), key
(result = keycheck's result.json oder ein Objekt; verdict, baseFails, claim, rows und count
{value, total, label} überschreiben – z. B. ein Check, der acht Fälle ausführt, liest sich besser als 8/8), checks (items mit name, detail, ok), end (title, lines). Jede Szene akzeptiert heading,
kicker und seconds. Lasse weg, was die Änderung nicht hat – eine Backend-Änderung hat kein compare oder clip; eine reine Refaktorisierung hat eine key-Szene mit Gleichheit und wenig mehr.
Die linke Spalte der key-Szene enthält bis zu acht Zeilen und nimmt rows deiner eigenen vor den Prüfungen des Schlüssels auf, sodass die Tests dort als eine Zeile pro Test eingehen ("verify.sh · 476 Tests") anstatt in einer checks-Szene danach. Verwende eine separate checks-Szene nur, wenn kein Prüfschlüssel angezeigt wird.
Formulierung
Die Bildunterschriften werden in den Sekunden gelesen, in denen sie auf dem Bildschirm sind, daher muss jedes Wort tragen. Drei Regeln, gelernt aus Demos, die ihre Leser genervt haben:
- Nenne das Ergebnis, lobe es nicht. Der Stempel des Urteils und „unabhängig vom key-reviewer geprüft“ sagen bereits, dass der Schlüssel bestanden wurde und wer geprüft hat. Ein zusätzliches „BESTANDEN, kein Betrug“ oder „vollständig verifiziert“ liest sich so, als würde der Autor seine eigenen Hausaufgaben bewerten. Verzichte auf Kommentare zum Urteil.
- Zähllabels sind einfache Substantive:
checks pass,cases identical,tests. Ein Verb wiefail/fehlschlagenals Label macht aus „5/5“ einen Satz, der rückwärts gelesen wird – „5 von 5 fehlgeschlagen“ klingt nach einer kaputten Änderung, obwohl der Basis-Branch gemeint ist. Wenn du sagen musst, dass der Basis fehlschlägt, gibt es dafür diebaseFails-Zeile, die sich selbst erklärt. - Kein Füllstoff. Streiche „erfolgreich“, „wie erwartet“, „dies stellt sicher, dass“ und jeden Aufzählungspunkt, der den Titel wiederholt. Wenn ein Aufzählungspunkt einen Reviewer dazu bringen würde, „ja, offensichtlich“ zu sagen, ist es kein Punkt.
3. Rendern
node <Verzeichnis dieses Skills>/scripts/render-demo.mjs out/demo/<n>/demo.json [--webm]
Es zeichnet jede Szene Bild für Bild in Chromium (scharfer Text, keine ausgelassenen Frames) und kodiert demo.mp4 (H.264, spielt inline in Slack, GitHub und Browsern ab), demo.png (ein Poster: die Ablauf- oder Schlüsselszene) und, mit --webm, ein VP9 demo.webm. Es benötigt ffmpeg und verwendet Playwright aus dem Projekt, andernfalls wird es einmalig in ~/.cache/carnufex-showcase installiert. Etwa eine Sekunde Rendering pro Sekunde Video.
Vor dem Versenden ansehen: nimm Frames aus jeder Szene (ffmpeg -ss <t> -i demo.mp4 -frames:v 1 f.png) und betrachte sie. Abgeschnittener Text, ein leeres Diagramm, ein Clip eines Anmeldebildschirms: korrigieren und erneut rendern.
4. Posten
In den vom Profil Notify genannten Kanal, als Bot, damit die Person eine echte Benachrichtigung erhält (eine über einen Slack-Connector gepostete Nachricht stammt von der Person selbst, und Slack benachrichtigt niemanden über die eigenen Nachrichten). Ein Thread pro PR: Das Demo startet den Thread des PRs; alles danach – CI, Review-Runden, Merge, Deploy, der Live-Check, ein Rollback – ist eine Antwort in diesem Thread (ship postet diese). Der Kanal bleibt eine Zeile pro PR, über alle Repositories hinweg. Schreibe die Nachricht in eine Datei; sie muss für sich allein stehen können (Slack mrkdwn) und mit dem Repository beginnen:
*<repo>* · PR #<n> · <Titel> — bereit zur Überprüfung
<PR-URL>
• <was sich geändert hat, Zeile 1>
• <Zeile 2>
Prüfschlüssel (<Art>): *BESTANDEN*, unabhängig geprüft: <eine Zeile aus dem Urteil>
3 am: <Signal>
node <Verzeichnis dieses Skills>/scripts/post-slack.mjs --channel <id> --pr <PR-URL> --file out/demo/<n>/demo.mp4 --title "<repo> PR #<n>: <Titel> (<Sekunden> s)" --comment-file out/demo/<n>/message.md
node <Verzeichnis dieses Skills>/scripts/post-slack.mjs --channel <id> --pr <PR-URL> --text-file update.md [--broadcast]
--pr findet den Thread des PRs anhand seiner URL im Kanal (kein Zustand gespeichert): gefunden, der Beitrag geht in den Thread; nicht gefunden, er startet ihn. --text-file postet eine Nachricht ohne Datei; --broadcast zeigt auch eine Thread-Antwort im Kanal an (verwende es für das Ergebnis: live oder zurückgerollt). Es gibt den Thread und den Permalink aus. Das Bot-Token stammt aus SLACK_BOT_TOKEN oder dem slack-channel-Plugins ~/.claude/channels/slack/.env; der Bot muss im Kanal sein (not_in_channel: /invite @<bot>). Ohne Bot falle auf den Slack-Connector zurück (slack_get_file_upload_url → POST the bytes → slack_complete_file_upload) und sage, dass keine Benachrichtigung rausgeht.
Füge dieselben drei Zeilen, das Mermaid-Flussdiagramm und den Slack-Link in die PR-Beschreibung ein (GitHub zeichnet Mermaid; es spielt kein über die API hochgeladenes Video ab).