wisp-diagram: Wisp-konforme Diagramme erstellen
Ziel: Erstellung stilistisch konsistenter, thematisierbarer und portabler Diagramme. Quelldateien (.excalidraw / .drawio) + generiertes *.wisp.svg: Das gleiche SVG folgt auf Wisp-Seiten dem Seitenthema, während es in GitHub-READMEs / anderen Blogs als <img> die System-Hell/Dunkel-Einstellung nutzt.
Dieses Skill-Verzeichnis ist in sich geschlossen und kann als Ganzes in jedes Projekt kopiert werden (~/.claude/skills/ oder <Projekt>/.claude/skills/). Das Skript ist in Python und wird mit uv ausgeführt: Der Einstiegspunkt scripts/wisp_diagram.py deklariert die Abhängigkeiten (playwright, fonttools) mittels PEP 723; uv run erstellt automatisch eine isolierte Umgebung – kein npm / pip install erforderlich.
SKILL.md
palette.json Farbpalette (einzige Farbquelle)
reference/ style-guide.md excalidraw-skeleton.md drawio-cheatsheet.md ml-patterns.md
assets/ wisp.excalidrawlib wisp-drawio-library.xml drawio-config.json drawio-colors.txt
scripts/ wisp_diagram.py (einheitlicher Einstiegspunkt) wisp_diagram_lib/ (Implementierung) tests/ (pytest)
Einmalige Vorbereitung
Die folgenden Befehle werden im Projektstammverzeichnis ausgeführt; $W repräsentiert das Einstiegsskript (Pfad je nach tatsächlicher Position des Skills anpassen):
W="uv run skills/wisp-diagram/scripts/wisp_diagram.py" # z. B. .claude/skills/wisp-diagram/... oder ~/.claude/skills/wisp-diagram/...
uv run --with playwright==1.64.1 playwright install chromium # Headless-Browser für Exporte (überspringen, wenn bereits installiert)
$W probe # Prüft, ob Chromium, Excalidraw und draw.io Exportmethoden (cli / docker / browser) verfügbar sind
Erstmalige Ausführung lädt herunter und cached (danach offline verfügbar):
| Inhalt | Quelle | Größe |
|---|---|---|
| Python-Abhängigkeiten playwright 1.64.1, fonttools | PyPI (verwaltet von uv, im uv-eigenen Cache) | ≈ 55 MB |
| Chromium (nur wenn nicht vorhanden) | playwright install chromium, gespeichert in ~/.cache/ms-playwright/ | mehrere hundert MB |
| @excalidraw/excalidraw 0.18.1 und Abhängigkeiten (≈ 110 ES-Module) | jsDelivr, versioniert | ≈ 1.6 MB |
| svgo 4.1.0 Browser-Build (SVG-Optimierung, läuft in Chromium) | jsDelivr | 0.8 MB |
| Schriftarten: Excalifont, Inter 5.3.0, Noto Sans SC 5.3.1 (nach Unicode-Bereich fragmentiert, nur benötigte Teile) | jsDelivr | insgesamt ≈ 4.5 MB |
| draw.io viewer (nur bei Browser-Export-Methode) | viewer.diagrams.net | ≈ 4.7 MB |
Abgesehen von Python-Abhängigkeiten und Chromium liegen alle Caches in ~/.cache/wisp-diagram/ (kann mit WISP_DIAGRAM_CACHE geändert werden). $W cache status zeigt den Cache-Status an, $W cache clear leert ihn.
Offline-Nutzung: Führen Sie zunächst in einer Netzwerkumgebung $W cache warm aus (lädt alle oben genannten Frontend-Ressourcen herunter, ≈ 11 MB). Anschließend kann mit WISP_DIAGRAM_OFFLINE=1 komplett offline gearbeitet werden; bei fehlenden Cache-Dateien wird ein Fehler gemeldet und ein Hinweis zum Vorwärmen gegeben – es erfolgt keine stille Netzwerkabfrage. Alternativ können Sie mit WISP_EXCALIDRAW_BUNDLE=<lokales JS> ein eigenes Excalidraw-Build angeben (ein IIFE, das window.__wisp definiert, oder ein ES-Modul, das Funktionen wie exportToSvg exportiert) und mit WISP_DRAWIO_VIEWER=<lokale Datei> einen eigenen draw.io-Viewer.
Der draw.io-Export fällt automatisch in der Reihenfolge cli → docker → browser zurück. new, build und export benötigen Chromium (Excalidraw-Export und svgo-Optimierung laufen im Headless-Browser); lint, normalize und check nicht.
1. Werkzeugauswahl
| Szenario | Wahl | Quelldatei |
|---|---|---|
| Flussdiagramme, Sequenzdiagramme, Zustandsdiagramme, Klassendiagramme usw. strukturierte Diagramme, Knotenbeziehungen im Vordergrund | Mermaid (am einfachsten, direkte Integration in ```mermaid-Codeblöcke; Wisp-Seiten rendern zur Build-Zeit) | Keine separate Datei |
| Konzeptdiagramme, intuitive Skizzen, handgezeichneter Stil, ML-Operator-Datenflüsse | Excalidraw | name.excalidraw (JSON) |
| Präzise ausgerichtete Modellstrukturdiagramme, geschichtete Architekturdiagramme, rechtwinklige Linien und mehrere Seiten | draw.io | name.drawio (unkomprimiertes XML) |
| Schrittweise Demonstrationen, interaktiv | Nicht Teil dieses Skills (React-Komponente) | — |
Prinzip: Wenn es mit Mermaid klar erklärt werden kann, kein Diagramm zeichnen. Handgezeichneter Stil mit maximal etwa 12 Knoten. Stil innerhalb eines Artikels einheitlich halten.
2. Arbeitsablauf (5 Schritte)
Im Folgenden am Beispiel diagrams/attention, Pfad entsprechend der tatsächlichen Position ersetzen.
① Typ bestimmen (siehe obige Tabelle). Nach der Auswahl die entsprechende Referenz lesen: Excalidraw → reference/excalidraw-skeleton.md; draw.io → reference/drawio-cheatsheet.md; gängige Modelldiagramme direkt aus reference/ml-patterns.md kopieren und anpassen. Layout-Prinzipien in reference/style-guide.md.
② Quelldatei generieren
- Excalidraw: Skelett-JSON schreiben (Position, Größe, Label, semantischer Farbname, Anfangs-/End-IDs der Pfeile), dann konvertieren. Nicht das vollständige Excalidraw-Element von Hand schreiben (Felder wie seed, boundElements, version sind sehr fehleranfällig).
Die Skelettdatei kann nach der Konvertierung gelöscht oder als Generierungsskript behalten werden; danach gilt die$W new diagrams/attention.skeleton.json -o diagrams/attention.excalidraw.excalidraw-Datei. - draw.io: Direkt unkomprimiertes mxGraph-XML schreiben, Stil-Strings nur aus
reference/drawio-cheatsheet.mdverwenden. Bei einer komprimierten.drawio-Datei zuerst$W normalize diagrams/file.drawioausführen, um sie zu dekomprimieren. - Manuell im Editor zeichnen:
assets/wisp.excalidrawlibimportieren (Excalidraw: rechte Seite Library → Open) oderassets/wisp-drawio-library.xml(draw.io: File → Open Library from → Device) und die Palette gemäßassets/drawio-colors.txtkonfigurieren.
③ Lint (zuerst reparieren) dann build
$W lint diagrams/attention.excalidraw --fix # Nicht-Palettenfarben auf nächstgelegenes Token verschieben; nicht automatisch reparierbare werden aufgelistet
$W lint diagrams/attention.excalidraw --strict # Keinerlei error/warn = bestanden
$W build diagrams/attention.excalidraw # Erzeugt diagrams/attention.wisp.svg
Häufige build-Parameter: --embed-fonts (Schriftarten-Untermenge einbetten, für externe Plattformen), --fix, --title T --desc D (Barrierefreiheitstext überschreiben, nur bei Einzeldatei), --drawio cli|docker|browser, --out-dir DIR, --strict. Bei mehrseitigem draw.io wird die zweite und folgende Seite als name.page-2.wisp.svg ausgegeben.
④ Selbstkontrolle: Light- und Dark-Vorschau exportieren, mit Read-Tool ansehen
$W export diagrams/attention.wisp.svg --theme light -o /tmp/attention.light.png
$W export diagrams/attention.wisp.svg --theme dark -o /tmp/attention.dark.png
Prüfen: Textüberlappungen, Pfeile durch Knoten, Labels über Pfeilspitzen, im Dunklen schwer lesbar, chinesische Zeichen abgeschnitten. Bei Problemen die Quelldatei ändern und zu ③ zurückkehren, um neu zu bauen. Vorschau-PNGs in einem temporären Verzeichnis ablegen, nicht einchecken.
⑤ Referenzieren und Alt-Text schreiben: Siehe unten unter „Verwendung der Ergebnisse“. Es muss ein aussagekräftiger Alt-Text angegeben werden (beschreibt die Schlussfolgerung des Diagramms, nicht „Abbildung 1“).
3. Farbpalette
Farben dürfen nur aus palette.json stammen. Beim Zeichnen ausschließlich die hellen Werte verwenden (linke Werte in der Tabelle unten); build bildet sie auf var(--wd-*) ab (dunkle Werte werden automatisch vom SVG umgeschaltet). Keine dunklen Werte von Hand auswählen und keine Farben außerhalb der Palette verwenden (lint meldet Fehler, --fix verschiebt auf nächstgelegenes Token).
| Farbton (Hue) | Strich (Linien, Text) light / dark | Füllung light / dark | Semantischer Name |
|---|---|---|---|
blue | #1d4ed8 / #60a5fa | #dbeafe / #1b2740 | q, active |
amber | #b45309 / #fbbf24 | #fef3c7 / #38290c | k, highlight |
green | #15803d / #4ade80 | #dcfce7 / #122d1c | v, done |
rose | #be123c / #fb7185 | #ffe4e6 / #3a1620 | grad, error |
violet | #7c3aed / #a78bfa | #ede9fe / #272040 | weight |
teal | #0f766e / #2dd4bf | #ccfbf1 / #0f2c29 | activation |
orange | #c2410c / #fb923c | #ffedd5 / #3a2010 | bias |
slate | #475569 / #94a3b8 | #e2e8f0 / #222831 | mask, visited |
Basisfarben: Fließtext fg #1d1d1f (Excalidraw-Standard-Schwarz #000000/#1e1e1e wird ebenfalls als fg behandelt), sekundär muted #5c6067, Fläche surface #f4f4f2, Rahmen border #e2e2dd, Leinwand weiß #ffffff (wird von build entfernt).
Semantische Farben (einheitlich in allen Artikeln und Diagrammen)
| Semantischer Name | Bedeutung | Farbton (Hue) |
|---|---|---|
q | Query (Abfrage) | blue |
k | Key (Schlüssel) | amber |
v | Value (Wert) | green |
weight | Gewicht, Parameter | violet |
activation | Aktivierung, softmax | teal |
grad | Gradient | rose |
bias | Bias (Versatz) | orange |
mask | Maske, Eingabe | slate |
highlight | Hervorhebung | amber |
visited | Besucht | slate |
active | Aktuell/laufend | blue |
done | Abgeschlossen | green |
error | Fehler, Verlust | rose |
Im Skelett kann das color-Feld direkt den semantischen Namen (z. B. "color": "q") oder den Farbtonnamen verwenden; in draw.io die Tabelle nachschlagen und den entsprechenden fill/stroke des Farbtons verwenden.
4. Strenge Stilregeln
| Kategorie | Regel |
|---|---|
| Raster | Alle x-/y-/Breiten-/Höhenwerte müssen Vielfache von 8px sein |
| Schriftgröße | Nur 12 (Anmerkungen) / 14 (Labels) / 18 (Titel) verwenden; lint-Toleranz ±1 |
| Linienstärke | 1.5 (Standard), 2.5 (Hervorhebung, ein bis zwei pro Diagramm); dünne Linie 1 nur für Trennlinien |
| Abrundung | Rechteck/Container-Abrundung: Excalidraw round, draw.io rounded=1;arcSize=8 |
| Füllung | Einfarbige Füllung, den fill-Wert des Farbtons verwenden; Kein Farbverlauf |
| Schatten | Keine |
| Schriftart | Excalidraw: Excalifont (chinesische Schrift: Noto Sans SC, nicht Xiaolai); draw.io: Inter |
| Handzeichnung | roughness: 1; draw.io kein sketch=1 |
| Hintergrund | Kein Hintergrundrechteck zeichnen, transparent lassen |
| Quelldatei | .excalidraw als JSON; .drawio als unkomprimiertes XML; eingebettete Bilder blähen die Datei auf (>2MB Warnung) |
5. Selbstprüfungs-Checkliste
- lint
--strictbestanden: Keine Nicht-Palettenfarben, keine Schatten/Verläufe, Schriftgrößen konform, Elemente im 8px-Raster - Semantische Farben korrekt verwendet: Q blau, K amber, V grün, Gewicht violett, Aktivierung cyan, Gradient/Verlust rose, Bias orange, Maske/Eingabe grau
- Ein Diagramm erklärt nur eine Sache, Knoten ≤ 12 (handgezeichnet)
- Linien kreuzen keine Knoten oder einander; keine Labels auf kurzen Linien (Abstand < 96px)
- Chinesische Labels: maximal 8–10 Zeichen pro Zeile, keine Abschneidungen
- Titel (Text mit
size: "title"/ draw.io-Seitenname) und ein erklärender Kommentar vorhanden - Light- und Dark-Vorschau-PNGs mit Read betrachtet
-
.wisp.svggeneriert und nach Änderung der Quelldatei neu gebaut - Alt-Text aussagekräftig
6. Verwendung der Ergebnisse
Auf einer Wisp-Seite (optional)
Die Befehle pnpm diagram build|check|lint [--fix], pnpm diagram new <skeleton.json> --build, pnpm diagram export <Datei> --png --theme dark der Seite sind dünne Wrapper um dieses Skill (rufen uv run skills/wisp-diagram/scripts/wisp_diagram.py mit --root <Repo> --manifest scripts/diagram/manifest.json für inkrementelle Builds auf).
Quelldateien und Artikel gemeinsam ablegen (Verzeichnis diagrams/), .wisp.svg ebenfalls einchecken. In MDX/Markdown mit der Standard-Bildsyntax auf die Quelldatei verweisen (die Seite bettet die gleichnamige .wisp.svg ein und fügt einen Download-Link für die Quelldatei hinzu):


Der Alt-Text wird in das <title> des SVGs eingetragen, der Text in Anführungszeichen wird zur Bildunterschrift; #page=<Seitenname> wählt die Seite in draw.io aus. pnpm diagram check prüft nur den Inhalts-Hash und benötigt im CI keinen Browser (aber uv).
Andere Projekte können denselben „Projektmodus“ nutzen: $W build --root . --manifest diagrams.manifest.json baut nur geänderte Quelldateien neu (scannt <root>/src/content/**/diagrams/); $W check --root . --manifest diagrams.manifest.json prüft den Hash im CI.
An anderen Orten (GitHub README, andere Blogs, IDE-Vorschau)
Direkt auf die generierte *.wisp.svg verweisen: Sie enthält ein <style>-Element und folgt als <img> über prefers-color-scheme der System-Hell/Dunkel-Einstellung. Renderer ohne CSS-Variablen-Unterstützung verwenden den hellen Fallback aus den Attributen.

- Vor Veröffentlichung auf externen Plattformen mit
$W build <Datei> --embed-fontsdie Schriftarten-Untermenge einbetten (normalerweise einige Dutzend KB pro Diagramm), um Schriftarten-Fallback zu vermeiden. - Für Plattformen ohne SVG-Unterstützung (z. B. WeChat, Zhihu):
$W export <Datei> --theme light --scale 2 -o out.png(--transparentfür transparenten Hintergrund; standardmäßig mit eingebetteten Schriftarten). - Quelldateien zusammen im Repository ablegen, um spätere Änderungen zu ermöglichen;
.excalidrawkann in excalidraw.com geöffnet werden,.drawioin app.diagrams.net.
7. Häufige Fehler
| Fehler | Vermeidung |
|---|---|
| Vollständiges Excalidraw-Element von Hand geschrieben | Nur Skelett schreiben, mit $W new konvertieren |
| Im Editor Farben außerhalb der Palette verwendet (Pipette, Standardfarben) | Materialbibliothek verwenden; lint --fix verschiebt; bei weiterem Fehler Quelldatei ändern |
| Dunkle Werte von Hand zum Zeichnen verwendet | Nur helle Werte verwenden, dunkle Werte werden automatisch per SVG umgeschaltet |
| Skelett-Pfeil kreuzt dritten Knoten | Pfeile sind gerade Linien auf der Mittellinie; Layout anpassen oder auf draw.io-Knicklinien umsteigen |
| Label auf kurzer Linie, Label überdeckt Pfeilspitze | Knotenabstand ≥ 96px für Labels; sonst Label entfernen |
| Koordinaten nicht im 8px-Raster | Alle Werte als Vielfache von 8 nehmen |
.drawio im komprimierten Format eingereicht | $W normalize dekomprimiert; File → Properties → Compressed deaktivieren |
& in draw.io-Label nicht maskiert | Bei html=1 als &amp; schreiben, Zeilenumbruch als <br> |
| Zu langes chinesisches Label abgeschnitten | Maximal 8–10 Zeichen pro Zeile, mit \n / <br> umbrechen, Knotenbreite erhöhen |
| Quelldatei geändert, aber nicht neu gebaut | Nach Änderung $W build erneut ausführen (auf der Seite erkennt pnpm diagram check Hash-Inkonsistenz) |
| Dunkle Vorschau vor Auslieferung nicht geprüft | Schritt ④: Dark-Vorschau muss angesehen werden |
| Nichtssagender Alt-Text („Abbildung 1“, „Diagramm“) | Alt-Text beschreibt die Schlussfolgerung des Diagramms |
| Datencharts mit Diagrammwerkzeug erstellt | Liniendiagramme/Balkendiagramme gehören nicht zu diesem Skill |
8. Fehlerbehebung
uv: command not found: uv installieren (curl -LsSf https://astral.sh/uv/install.sh | sh). Python ≥ 3.11 erforderlich; uv lädt es bei Bedarf automatisch herunter.Chromium kann nicht gestartet werden:uv run --with playwright==1.64.1 playwright install chromium(Version muss mit der im Skript festgelegten playwright-Version übereinstimmen).Download fehlgeschlagen/Offline-Modus: Cache fehlt N Dateien: Einmal im Netzwerk$W cache warmausführen; Cache-Position mit$W cache statuseinsehen.- draw.io-Export fehlgeschlagen:
$W probezeigt, welche Methode verfügbar ist; mit--drawio browser|cli|dockererzwingen. - Fehler im Browser anzeigen:
WISP_DIAGRAM_DEBUG=1setzen. - lint meldet
unrecognised color: Farbe ist kein Hex-Wert (z. B. spezielle Werte wiergb()); manuell durch hellen Wert aus der Palette ersetzen.