Communitygithub.com

keepwatching

Eine Retentionsdatenbank für Kurzvideo-Formate im 9:16-Format, die rendert. Mit benannten Formaten, festgeschriebenen Vorschauen, gemessener Retention und sichtbaren Stichprobengrößen – als Agenten-Skill installierbar basierend auf Node + Playwright + ffmpeg.

Was ist keepwatching?

keepwatching ist ein Skill, der als strukturierte Datenbank für benannte Kurzvideo-Formate im 9:16-Format fungiert und diese tatsächlich rendert. Er ist als Agenten-Skill installierbar und basiert auf Node.js, Playwright und ffmpeg. Die zentrale Regel des Skills lautet: Keine Retentionszahlen erfinden. Jede Behauptung über die Leistung eines Formats stammt aus der Datei `formats/<slug>/data.yml`, die immer die Stichprobengröße `n` angibt. Ist `n: 0`, ist die ehrliche Antwort „nicht getestet“. Der Skill ermöglicht es, aus einer Bibliothek von 24 vordefinierten Formaten (z. B. für große Zahlen, Countdowns, Ranglisten oder Enthüllungen) das passende für ein Thema auszuwählen, ein Video zu rendern, A/B-Tests durchzuführen und die Messergebnisse wieder einzulesen. Die enthaltene Galerie mit Vorschaubildern ist direkt nutzbar, ohne dass ein Video gerendert werden muss. Für die Wiedergabetreue und die korrekte Zuordnung der Retentionskurven ist Determinismus entscheidend: Derselbe `format.json`-Code erzeugt immer die gleichen Frames. Die Plattform unterstützt Claude Code, Cursor und andere KI-Agenten, die Shell-Befehle ausführen können. Der Skill unterteilt Messungen in zwei unabhängige Kategorien: `format` (die Struktur der Szene) und `content_axis` (das Thema), die getrennt ausgewertet werden, um Vermischungen zu vermeiden. Zu den strengen Ehrlichkeitsregeln gehört, dass Zahlen nur durch `kw measure apply` in `data.yml` geschrieben werden dürfen und jede auf dem Bildschirm angezeigte Zahl eine Quelle benötigt.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add msertdev/keepwatching

In Ihrer bevorzugten KI fragen

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

Dokumentation

Was macht keepwatching?

Eine Datenbank benannter Kurzvideo-Formate, die rendert. Jedes Format besteht aus drei Dateien: einer Rendervorgabe, einer formulierten Hypothese und den Messergebnissen – einschließlich „bisher nichts“.

Die Regel, die diesen Skill nützlich macht: Erfinde niemals eine Retentionszahl. Jede Behauptung darüber, wie ein Format abschneidet, stammt aus formats/<slug>/data.yml, und jede davon führt eine n. Wenn n: 0 ist, lautet die ehrliche Antwort „nicht getestet“ – sag das auch.

Einrichtung – mach das zuerst, in jeder Sitzung

Dieser Skill steuert einen echten Renderer, der sich im keepwatching-Repository befindet. Die Anweisungen allein können nichts rendern, daher ist Schritt eins immer das Lokalisieren oder Installieren des Repos.

# 1. Finde es. Erster Treffer gewinnt; frage den Benutzer, wenn keines existiert.
KW="${KEEPWATCHING_HOME:-}"
[ -z "$KW" ] && [ -d ./keepwatching ] && KW="$PWD/keepwatching"
[ -z "$KW" ] && [ -d "$HOME/keepwatching" ] && KW="$HOME/keepwatching"
[ -z "$KW" ] && { git clone https://github.com/msertdev/keepwatching "$HOME/keepwatching" && KW="$HOME/keepwatching"; }
cd "$KW"

# 2. Einmalige Installation. Kann wiederholt ausgeführt werden; es tut nichts, wenn bereits erledigt.
npm install && npm run setup

# 3. Bestätige, dass die Bibliothek intakt ist, bevor du etwas anderes tust.
npx kw check

Die 24 Galerie-Vorschaubilder sind festgeschrieben, daher zeigt npx kw gallery die Seite in Sekunden ohne etwas zu rendern. npm run setup wird nur zum Rendern von Videos benötigt. Wenn du die scene eines Formats änderst, wird dessen festgeschriebene Vorschau veraltet – rendere sie neu und schreibe sie mit npx kw gallery --no-serve && git add site/previews fest, sonst wird CI's kw previews check fehlschlagen.

kw check, das „keine Probleme“ ausgibt, bedeutet, dass du bereit bist. Wenn es fehlende Schriftarten meldet, führe npm run setup erneut aus – die Komposition weigert sich, mit einer Ersatzschriftart zu rendern, da eine substituierte Schriftart stillschweigend jedes Bild ändern würde, das das Repository jemals gemessen hat.

Zwei praktische Hinweise.

  • Shell-Variablen bleiben in den meisten Agent-Umgebungen nicht zwischen Tool-Aufrufen erhalten. Berechne KW entweder in jedem Befehl neu oder beginne jeden mit einem expliziten cd /absoluter/pfad/zu/keepwatching &&. Geh nicht davon aus, dass $KW überlebt.
  • npm run setup kann auf einer kalten Maschine Minuten dauern. Es lädt Inter (≈30 MB) und einen headless Chromium (≈150 MB) herunter. Auf einer Maschine, die beide bereits zwischengespeichert hat, ist es in Sekunden erledigt. Sage dem Benutzer, was gerade passiert, anstatt den Anschein zu erwecken, dass es hängt.

Jeder Befehl in dieser Datei setzt voraus, dass das Repository-Root das Arbeitsverzeichnis ist. Wenn der Benutzer in einem anderen Projekt arbeitet, rendere innerhalb des Repos und kopiere die MP4 zurück; kw läuft nicht von außerhalb.

Es gibt auch npm run check, das kw check plus tsc --noEmit ist. Verwende dieses, wenn du etwas unter engine/ bearbeitet hast.

Die vier Dinge, die du tun wirst

1. Ein Format für ein Thema auswählen

npx kw list          # jedes Format, mit seiner Stichprobengröße und gemessener Retention

Lies formats/<slug>/meta.yml für die hypothesis, useWhen und avoidWhen. Stimme die Form des Inhalts auf die Formatfamilie ab, nicht auf das Thema.

Jedes Format in der folgenden Tabelle hat derzeit n = 0. Dies sind Ausgangspunkte, die aus einer formulierten Hypothese gewählt wurden, keine Gewinner, die aus Beweisen ausgewählt wurden. Sage das, wenn du eines empfiehlst. Die Tabelle sagt dir, welches Format behauptet, zu einer Inhaltsform zu passen; sie sagt dir nicht, welches abschneidet.

Der Inhalt ist…FamilieBeginne mit
eine große Zahlstat-counterstat-counter-rise
eine Belohnung, die sich zu warten lohntcountdowncountdown-clock
eine geordnete Menge von Elementenrankingranking-suspense (Vollständigkeit) oder ranking-reveal (Anteile)
zwei Optionen, die sich in einer Zahl unterscheidencomparisonsplit-compare
dasselbe Subjekt in zwei Zuständenrevealbefore-after
ein weit verbreiteter falscher Glaubemyth-factmyth-vs-fact
ein starker Satzcold-opencold-open-line
ein Prozess mit echten Phasenprogressprogress-bar
Werte, die wirklich eskalierenescalationescalation-ladder
etwas Zirkuläresreverseloop-seam

Wenn du eines empfiehlst, zitiere sein n. „ranking-suspense, obwohl es in diesem Repository nicht getestet ist (n=0)“ ist eine gute Empfehlung. „ranking-suspense erreicht 68 % Retention“ ist eine Erfindung, es sei denn, data.yml sagt das.

2. Ein Video rendern

Kopiere ein Format, fülle den data-Block aus, rendere:

npx kw new my-clip --from=stat-counter-rise
# bearbeite formats/my-clip/format.json -> "data": { ... }
npx kw render my-clip           # -> out/my-clip/master.mp4

# Optional: Vorschau im Browser ansehen, ohne etwas zu kodieren.
# Blockiert, bis du es stoppst, daher überspringe es bei unbeaufsichtigtem Betrieb.
npx kw preview my-clip

Bearbeite nur data, es sei denn, das Layout muss sich wirklich ändern. Das scene-Array ist das Format; wenn du es änderst, wird der Clip zu einem anderen Format und seine Messungen sind nicht mehr übertragbar. Wenn du die Szene änderst, erhöhe version in format.json – die Varianten-ID leitet sich daraus ab.

Die Länge ändern – lies das, es ist die häufigste Anfrage.

Bibliotheksformate laufen 8–30 Sekunden (21 von 24 zwischen 8 und 14). Die drei 30-Sekunden-Formate – cold-open-question, countdown-clock, stat-counter-rise – sind die Stufen eines laufenden Experiments, nicht die Standardlänge. Jede Länge, die ein Format nicht bereits hat, erfordert die Bearbeitung der Szene, daher gilt „nur data bearbeiten“ nicht. Verwende diese Regel:

Multipliziere canvas.durationSec und jede zeitliche Angabe in der Szene mit newDuration / oldDuration. Betrachte dann das Ende: Die Skalierung dehnt das letzte Standbild um denselben Faktor, daher wird das Ende umso schlechter, je größer der Faktor ist.

Beispiel – stat-counter-rise von 10 s auf 30 s, Faktor 3,0. Dies sind die tatsächlich ausgelieferten Zahlen, nicht nur eine Veranschaulichung:

Feld10 s×3ausgeliefert
canvas.durationSec103030
counter endSec6,419,221,0
bar endSec6,419,221,0
unit at6,419,221,0
context at / in.at6,519,521,6
source at——25,5 – ein Schlag, der nicht existierte
posterSec8,425,227,5

Die Skalierung allein ließ den letzten Schlag bei 19,5 s in einem 30-Sekunden-Clip: 10,5 Sekunden einer eingefrorenen Karte. Selbst die Verschiebung auf 21,6 s reichte nicht. Ab einem Faktor von etwa zwei hört die Arithmetik auf, die Antwort zu sein – der Clip braucht einen Schlag, den er nicht hatte. Hier ist das eine Zitierzeile bei 25,5 s, die das Format in seinen sources die ganze Zeit beansprucht und nie auf dem Bildschirm gezeigt hatte. Endstandbild: 4 Sekunden.

Eine Endkarte, die länger als etwa 3 Sekunden gehalten wird, ist tote Luft, und tote Luft am Ende tötet die Abschlussrate. kw frame0 schlägt bei 5 Sekunden eines bewegungslosen Bildschirms fehl: 3 ist die handwerkliche Empfehlung, 5 ist die harte Grenze. Es fand drei Formate, die bereits mit einem 6-Sekunden-Einfrieren am Ende ausgeliefert waren.

Einschränkungen und Prüfungen:

  • durationSec × fps muss eine ganze Anzahl von Frames ergeben.
  • Erhöhe version in format.json, wann immer du die Szene änderst – Neuzeitlichung zählt. Ein neues Gerüst bei 0.1.0, das du dann neu zeitlich abstimmst, wird zu 0.2.0. Die Varianten-ID leitet sich von version plus einem Hash der Vorgabe ab, sodass eine zukünftige Messung zuordenbar bleibt.
  • npx kw check erfasst Zeitangaben, die über das Ende des Clips hinausgehen, und npx kw frame0 erfasst einen ersten Frame, der nichts malt, plus jeden bewegungslosen Lauf über 5 Sekunden. Keines von beiden kann dir sagen, dass ein Clip langweilig ist – öffne dazu nach dem Rendern out/<slug>/contact.png. Es tastet sechs Frames gleichmäßig über den Clip ab, sodass nahezu identische Kacheln auf einen Blick sichtbar sind.

Quellenangaben. kw new --from=<slug> setzt das Gerüst absichtlich auf sampleContent: placeholder zurück und entfernt die sources des übergeordneten Formats – die Zitate des übergeordneten Formats untermauerten dessen Zahlen, nicht deine. Wenn du eine echte Zahl auf den Bildschirm bringst, setze sampleContent: sourced und füge einen sources:-Eintrag mit einer URL und der genauen Behauptung hinzu, die er untermauert.

Eine bequellte Zahl ist erst dann bequellt, wenn sie erscheint. Wenn du einen Zähler auf eine zitierte Zahl animierst, markiere sie mit claim: "final" und halte die Einheit und jedes Wort wie „genau“ bis endSec vom Bildschirm fern – zeige bis dahin „zählt…“. Jedes andere Element, das während des Zählvorgangs sichtbar ist, benötigt neutralWhileCounting: true. kw check lehnt das Format andernfalls ab. Zähler, deren Zwischenwerte wahrheitsgemäß sind („Frames bisher“), sind mit claim: "running" markiert und sind ausgenommen.

Was als Quelle zählt: etwas, das ein Leser öffnen und die Zahl überprüfen kann – eine Primärpublikation oder ihr permanenter Datensatz (DOI, PubMed), eine Normungsorganisation, eine statistische Behörde, ein offizieller Bericht. Kein Listicle, kein Blog, der eines zusammenfasst, und keine eigene Erinnerung. Gib jede Rundung, die du für den Bildschirm vorgenommen hast, im claim-Feld an. kw check überprüft, ob eine URL und eine Behauptung vorhanden sind; es kann nicht überprüfen, ob sie wahr sind, daher liegt dieser Teil bei dir. Wenn du keine Quelle finden kannst, verwende stattdessen Platzhaltertext – eine erfundene Statistik ist derselbe Fehler wie eine erfundene Retentionszahl.

Siehe references/spec.md für die vollständige Referenz zu format.json.

3. Einen A/B-Test durchführen

Zwei Formate, gleicher Inhalt, gleicher Tag:

npx kw new test-a --from=cold-open-line
npx kw new test-b --from=redacted-reveal
# füge identischen Text in beide data-Blöcke ein
npx kw render test-a && npx kw render test-b
npx kw variant test-a           # zeichne diesen String gegen den Upload auf

Die variantId in out/<slug>/variant.json macht das Ergebnis zuordenbar. Zeichne sie zum Zeitpunkt des Uploads gegen das veröffentlichte Video auf – sie wird auch in den Metadatenkommentar der MP4 geschrieben, falls du deine Notizen verlierst.

4. Messungen wieder einlesen

# Exportiere CSVs aus YouTube Studio / TikTok Analytics in measure/inbox/
npx kw measure                  # importieren + Bericht -> measure/report.md
npx kw measure apply            # schreibe Ergebnisse in formats/*/data.yml
npx kw gallery                  # neu rendern + Galerie neu aufbauen

Keine API, kein OAuth. Siehe references/measuring.md für die genauen Exportschritte und das Format von mapping.csv.

Determinismus ist die Vereinbarung

Die gleiche format.json erzeugt die gleichen Frames, auf jeder Maschine, für immer. Das ermöglicht es, eine Retentionskurve einem Format zuzuordnen und nicht einem Render. Bearbeite niemals Date.now(), Math.random(), requestAnimationFrame, CSS-Übergänge oder CSS-Animationen in der Komposition. npx kw render <slug> --check-determinism sucht Frames in falscher Reihenfolge und schlägt fehl, wenn sich ein Pixel bewegt hat.

Zwei Messungen, die niemals vermischt werden dürfen

data.yml hat zwei Blöcke, und sie beantworten unterschiedliche Fragen:

BlockFrageBewertet die Bibliothek?
formatWie schneidet diese Szenenstruktur ab?Ja
content_axisWie schneidet dieses Thema ab?Nein

Ein einzelnes veröffentlichtes Video trägt beide Labels – es ist ein Countdown und es ist über den Körper. Die Mittelung der beiden ergibt eine Zahl, die keine der beiden Fragen beantwortet, daher werden sie getrennt gespeichert, getrennt berichtet und in der Galerie in verschiedenen Farben angezeigt.

Wenn du ein Ergebnis meldest, sag, welches es ist:

  • „countdown-clock behielt 62 % (n=6)“ – eine Formatbehauptung.
  • „persönliche/Körper-Themen behielten 68 % (n=9)“ – eine Achsenbehauptung.
  • „persönliche/Körper-Countdowns behielten 68 %“ – keins von beiden, es sei denn, du sagst auch, wie viele Videos, in welchen Formaten, und dass die beiden vermischt sind.

measure/report.md druckt eine Spalte getragen von für jede Achse. Wenn eine Achse nur von einem Format getragen wurde, sind dieses Achsenergebnis und dieses Formergebnis dieselben Videos mit zwei Labels; sag das, anstatt sie als zwei unabhängige Ergebnisse zu präsentieren.

Inhaltsachsen werden in data/content-axes.yml deklariert und einem Video durch die optionale Spalte content_axis in measure/mapping.csv zugeordnet. Es sind die eigenen Achsen des Benutzers, nicht die der Bibliothek – füge jede Unterscheidung hinzu, die sie tatsächlich testen.

variant_id: not-in-library markiert ein veröffentlichtes Video, dessen Format nicht in diesem Repository ist. Es ist nur eine Inhaltsachsen-Stichprobe: Es erreicht weder die Formattafel noch irgendeine data.yml, und getragen von benennt es, damit die Lücke sichtbar ist. Ergebnisse auf Repository-Ebene für Achsen leben in data/content-axis-results.yml, weshalb eine Achse gemessen werden kann, während jedes Format noch n = 0 hat. Spekuliere nicht darüber, was ein solches Format ist – das Label sagt absichtlich nichts darüber aus.

Ehrlichkeitsregeln

Dies sind keine Stilpräferenzen. Das Repository ist wertlos, wenn sie verletzt werden.

  1. n: 0 bedeutet nicht getestet. Runde es niemals auf „vielversprechend“ oder „wahrscheinlich“ auf.
  2. Unter n=5 ist eine Richtung, kein Ergebnis. Sage, welche du angibst.
  3. Verlierende Formate bleiben mit ihren Zahlen aufgelistet. Entferne sie nicht stillschweigend.
  4. Schreibe niemals data.yml von Hand. Nur kw measure apply schreibt es. Zahlen, die aus dem Gedächtnis getippt wurden, sind nicht von Zahlen zu unterscheiden, die erfunden wurden.
  5. Vermische niemals eine Formatnummer mit einer Achsennummer. Siehe die Tabelle oben.
  6. Jede Zahl auf dem Bildschirm benötigt eine Quelle. Ein Clip, den du generierst, trägt entweder sampleContent: sourced mit einer URL oder placeholder mit offensichtlichem Füllmaterial. Das Erfinden einer plausiblen Statistik für eine Demo ist derselbe Fehler wie das Erfinden einer Retentionszahl.
  7. Ausgangsdaten sind der Kanal eines einzigen Erstellers. Es ist ein Ausgangspunkt, kein Gesetz der Plattform. Sage, wessen Stichprobe es ist, wenn die Unterscheidung wichtig ist.

Referenzdateien

  • references/spec.md – die Element- und Animationsreferenz für format.json
  • references/formats.md – die Formatbibliothek, nach Familie, mit Hypothesen
  • references/measuring.md – CSV-Export, Zuordnung und der Berichtszyklus
  • references/authoring.md – ein neues Format schreiben, das es wert ist, gemessen zu werden

Verwandte Skills