Skip to content
Back to skills

Mermaid Lint

ASecurity

Findet und behebt Mermaid-Diagramme, die GitHub nicht rendert ("Unable to render rich display"). Prueft jeden ```mermaid-Block mit dem echten Mermaid-Parser ohne Browser und belegt das Ergebnis danach an der lebenden GitHub-Seite.

  • 6 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 21, 2026
ai-agentspythongoshellbashnodegit

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 6 files and shows the line behind each finding

Scanned September 26, 2026

npx -y skills add ellmos-ai/skills --skill mermaid-lint --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mermaid Lint?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mermaid Lint
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ellmos-ai-mermaid-lint/badge)](https://www.skillsdirectory.com/skills/ellmos-ai-mermaid-lint)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mermaid-lint
version: 1.0.0
type: tool
author: Lukas Geiger + Claude
created: 2026-09-20
updated: 2026-09-20
aliases: [mermaid, mermaid-fehler, diagramm-render-fehler, unable-to-render-rich-display, schaltplan-fehler]
description: Findet und behebt Mermaid-Diagramme, die GitHub nicht rendert ("Unable to render rich display"). Prueft jeden ```mermaid-Block mit dem echten Mermaid-Parser ohne Browser und belegt das Ergebnis danach an der lebenden GitHub-Seite.

standalone: true
anthropic_compatible: true
bach_compatible: true
bach_origin: false
category: dev
tags: [mermaid, markdown, github, readme, diagramm, lint, dokumentation]
language: de
status: active
visibility: public
dependencies: {'tools': ['node', 'git'], 'services': ['GitHub'], 'protocols': [], 'python': [], 'npm': ['mermaid', 'jsdom', 'playwright-core']}
---

<img src="banner.png" width="100%" alt="mermaid-lint banner">

# mermaid-lint

Ein Mermaid-Diagramm mit Syntaxfehler zeigt auf GitHub statt der Grafik den Kasten
**"Unable to render rich display"**. Lokal faellt das nicht auf, weil kein Werkzeug den
Block prueft. Dieser Skill schliesst die Luecke.

## Wann anwenden

- Ein README oder Dokument zeigt auf GitHub einen Renderfehler statt eines Diagramms.
- Vor einer Veroeffentlichung oder einem Release mit Diagrammen in der Dokumentation.
- Nach jedem Umbau von Markdown, der Mermaid-Bloecke beruehrt.
- Flaechendeckend ueber mehrere Repos, wenn unklar ist, wo ueberall etwas kaputt ist.

## Die zwei Werkzeuge

### 1. `mermaid_lint.mjs` — Syntaxpruefung ohne Browser

```
node mermaid_lint.mjs <repo-pfad> [...] [--json]
node mermaid_lint.mjs --from <liste.txt> [--json]
```

Sucht rekursiv alle `.md`-Dateien, extrahiert jeden ```mermaid-Block und laesst ihn
durch `mermaid.parse()` laufen — **denselben Parser, den GitHub im Browser benutzt**.
Exit 0 = alles parst, Exit 1 = mindestens ein Block defekt. Ausgabe nennt Datei,
Blocknummer, Zeile und den woertlichen Parserfehler.

`--from <datei>` liest eine Pfadliste, eine pro Zeile. Nutze das statt vieler Argumente:
Windows-Pfade mit Backslashes werden in der Bash-Shell stumm zerfressen
(aus `D:\code\my-repo` wird `D:codemy-repo`). Schreibe Pfade mit Forward-Slashes.

Ein einziger Prozess schafft hunderte Repos, weil Mermaid nur einmal geladen wird.
Kein Puppeteer, kein Chromium-Download.

### 2. `readback.mjs` — Beweis an der lebenden Seite

```
node readback.mjs <github-url> [...]
```

Oeffnet die Seiten im vorhandenen Edge (kein Browser-Download) und zaehlt echte
Renderfehler. Urteil je Seite: `OK`, `DEFEKT`, `UNKLAR` oder `KEIN-MERMAID`.

## Drei Fallen, die diesen Skill noetig machen

**GitHub rendert Mermaid in sandboxed iframes** von `viewscreen.githubusercontent.com`.
Die Hauptseite sieht deren Inhalt nicht. Wer nur `document.body.innerText` oder
`msedge --dump-dom` auswertet, bekommt auf **jeder** Seite null Fehler gemeldet — auch
auf einer nachweislich kaputten. `readback.mjs` wertet deshalb alle Frames aus.

**Ein einzelner DEFEKT-Befund ist nicht belastbar.** Waehrend des Ladens zeigt GitHub
kurz einen Platzhalter, der wie ein Renderfehler aussieht. Gemessen am 2026-09-20:
dieselbe Seite meldete erst `ERR=1`, dann zweimal `ERR=0`. `readback.mjs` wiederholt
negative Befunde deshalb automatisch; ein `OK` wird nie wiederholt.

**`mermaid.parse()` braucht ein DOM**, sonst scheitert es an `DOMPurify.addHook` und
meldet gueltige Flowcharts faelschlich als kaputt. `mermaid_lint.mjs` stellt vorab
ein jsdom-Fenster bereit. Bleibt trotzdem ein Umgebungsfehler uebrig, landet er
getrennt unter `envIssues` und wird **nicht** als Syntaxfehler gezaehlt.

## Immer gegen eine Negativkontrolle pruefen

Bevor du einem gruenen Ergebnis glaubst, lass das Werkzeug einmal auf einen Stand los,
von dem du weisst, dass er kaputt ist — etwa den Commit vor deinem Fix:

```
node readback.mjs "https://github.com/<org>/<repo>/blob/<alter-sha>/README.md"
```

Meldet der auch `OK`, misst dein Readback nichts. Genau so wurde die iframe-Falle oben
entdeckt.

## Haeufige Fehlerursachen und ihre minimal-invasive Behebung

| Symptom im Parserfehler | Ursache | Behebung |
|---|---|---|
| `Expecting '+', '-', '()', 'ACTOR', got 'loop'` | Teilnehmer heisst wie ein reserviertes Wort: `loop`, `alt`, `opt`, `par`, `end`, `critical`, `break`, `rect`, `note` | Alias deklarieren: `participant L as Loop`, Nachrichten nutzen `L`. Der **angezeigte Name bleibt** — nicht umbenennen. |
| `got 'PS'` in einem Flowchart | Runde Klammern im Knotenlabel | Label quoten: `A["Start (hier)"]` |
| `Lexical error ... Unrecognized text` | Backticks oder Doppelpunkt im Label | Label quoten, Backticks entfernen |
| `Expecting 'SEMI', 'NEWLINE', 'EOF'` in `graph`/`flowchart` | `Note:` gibt es nur in Sequenz- und Klassendiagrammen | Hinweistext aus dem Block nehmen und als Markdown-Zeile darunter setzen, damit die Information sichtbar bleibt |
| `Expecting 'SOLID_OPEN_ARROW' ... got 'NEWLINE'` in einem Sequenzdiagramm | **HTML-Entity** im Nachrichtentext (`&lambda;`, `&Delta;`, `&ge;`). Nicht die Klammern und nicht das `=` brechen hier — das abschliessende `;` der Entity liest der Lexer als Statement-Terminator, alles dahinter wird neue Anweisung. | Entity durch das literale Zeichen ersetzen (λ, Δ, ≥), Text sonst unveraendert. Klammern duerfen bleiben. Zahlenwerte und ihre Schreibweise niemals veraendern. |
| Semikolon in einer Sequenznachricht | wird als Statement-Ende gelesen | durch ` - ` ersetzen |

In **quotierten Flowchart-Labels** sind Entities unproblematisch — die Regel gilt nur fuer
Sequenznachrichten. `mermaid_lint.mjs` meldet solche Entities als eigene `[WARN]`-Zeile
(Feld `warnings` im JSON), zusaetzlich zum Parserfehler: der Parser sagt nur
`got 'NEWLINE'` und nennt die Ursache nicht.

**Grundsatz:** minimal-invasiv. Layout, Knoten-IDs, Reihenfolge und sichtbarer Text
bleiben, soweit irgend moeglich, unveraendert. In wissenschaftlichen Repos gilt das
besonders fuer Zahlenwerte und deren Schreibweise. Bei EN/DE-Paritaet beide Fassungen
strukturgleich halten.

## Ablauf ueber mehrere Repos

1. Inventar per `gh repo list <org> --limit 200 --json name,isArchived,isPrivate,defaultBranchRef`.
2. Klone **auf Remote-Stand ziehen** und Divergenzen ernst nehmen. Ein Lint auf einem
   veralteten Klon misst den falschen Stand. Schlaegt `git pull --ff-only` fehl, pruefe
   gegen `origin` statt gegen den Arbeitsbaum:
   `git archive origin/<branch> | tar -x -C <tempdir>` und linte den Tempordner.
3. **Gleichnamige Repos verschiedener Orgs** (typisch `.github`) duerfen nicht auf
   denselben Klon gemappt werden — sonst prueft man neunmal dasselbe Repo. Bei
   Namensdopplung flach nach `<org>__<repo>` klonen und den frischen Stand linten.
4. Vor jeder Aenderung Locks pruefen (`lock_scan.py`, `LOCK*.txt` im Klon **und** am
   OneDrive-Projektpfad), eigenen Lock setzen, nach dem Push wieder entfernen.
   **Scope lesen, nicht nur die Existenz:** `LOCK.team.*` mit abgelaufener
   `expires_after` ist ignorierbar; `LOCK.user.zenodo-upload.txt` sperrt ausschliesslich
   die externe Zenodo-Schreiboperation und erlaubt Doku-Aenderungen ausdruecklich.
   Ein `LOCK.user.until-winners-announcement.txt` (Judging) sperrt dagegen jeden Push —
   dort nur lesend pruefen und den Befund als Ticket ablegen.
5. Reparieren, linten bis gruen, committen, `git pull --rebase`, pushen.
6. Readback mit Negativkontrolle. Erst dann gilt es als erledigt.

## Einrichtung

```
npm install mermaid jsdom playwright-core
```

Im Ordner der Skripte oder global; `playwright-core` nutzt den installierten Edge
(`channel: 'msedge'`) und laedt keinen eigenen Browser herunter. Nur fuer den Readback
noetig — die Syntaxpruefung laeuft ohne ihn.

## Verwandt

- `_tools/lint_mermaid.py` im GithubBot: aelterer regexbasierter Linter mit `--fix`.
  Er repariert bekannte Muster automatisch, **kennt aber keine reservierten Woerter**
  und ersetzt diesen Skill nicht. Sinnvolle Reihenfolge: erst `mermaid_lint.mjs` zur
  Diagnose, dann ggf. `lint_mermaid.py --fix` fuer die Massenmuster, dann erneut linten.
- `github-repo-care`: Gesamtprotokoll fuer Repo-Pflege und Veroeffentlichung.

Files in this skill

  • SKILL.en.md7.5 KB
  • SKILL.md7.9 KB
  • mermaid_lint.mjs6.9 KB
  • package.json464 B
  • readback.mjs3.1 KB
  • selftest.mjs3.2 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.