Öffentliches Register
Software-GesundheitsberichtSchema 0.27.0 · Metriken 1.13.0 · 2026-07-26 08:47 UTC

ZawadzkiB / very-nice-mermaid

Framework-agnostic Mermaid flowchart renderer: parse the DSL, dagre auto-layout, and beautiful interactive HTML / SVG / PNG / ASCII — no mermaid.js runtime, no headless browser. Library + web component + vnm CLI.

TypeScriptMIT★ 0 Sterne⑂ 0 Forksseit Juli 2026Auf GitHub ansehen ↗

ZawadzkiB/very-nice-mermaid erreicht einen Gesundheitsindex von 55 von 100 und liegt damit im Bereich Mittel. Am stärksten schneidet es bei Vitality (74/100) ab, am schwächsten bei Community & Adoption (32/100). Zuletzt vor 6 Tagen aktualisiert. Ein einzelner Mitwirkender trägt den Großteil der jüngsten Arbeit.

55
gesamt / 100
Mittel

Software-Gesundheitsindex

Metriken werden auf einer Skala von 1–100 in gewichtete Kategorien gruppiert. Der Gesamtwert beginnt als ihr Mittel; sobald öffentliche Evidenz die Richtlinie für Hochrisikojurisdiktionen auslöst, wird die Bewertung angepasst und erhält die Obergrenze 49 (Gefährdet). AI Readiness liegt außerhalb.

55
Exzellent85-100Vorbildlich; erfüllt im Wesentlichen alle geprüften Kriterien
Gut70-84Gesund; geringfügige Lücken
Mittel50-69Akzeptabel mit deutlichen Lücken; Überprüfung empfohlen
Gefährdet30-49Erhebliche Schwächen; eine Übernahme erfordert Vorsicht
Kritisch1-29Schwerwiegende Probleme (aufgegeben, nur ein Maintainer, keine Hygiene)
VitalitätCommunity &VerbreitungNachhaltigkeit &GovernanceEngineering-QualitätSicherheitAI Readiness

Bewertungsprofil

Jede Achse ist eine Kategorie. Die Form zählt mehr als der Durchschnitt — ein gesundes Projekt füllt die gesamte Fläche, während ein Profil aus Spitzen und Kratern bedeutet, dass Stärke in einer Dimension Risiken in einer anderen verdeckt.

Eigentümerschaft

BartekPersönliches Konto
2 Follower32 öffentliche Reposseit Apr. 2014

Dieses Repository gehört einem persönlichen Konto. Ein Projekt mit nur einem Eigentümer trägt ein höheres Kontinuitätsrisiko als ein organisationsgetragenes.

Paket-Ökosysteme

RegistryPaketVersionDownloads / MonatVersionenZuletzt veröffentlichtTags
npmvery-nice-mermaid0.7.22.33515vor 6 Tagenmermaidflowchartdiagramsvgrendererdagreinteractiveweb-component

Metriken nach Kategorie

Vitalität

Lebt das Projekt — wird Code geschrieben und werden Releases ausgeliefert?

74Gut · 22 % des Gesamtindex
Wie die Bewertung erfolgt
36/36Push-Aktualität — letzter Push vor 6 Tagen
2.8/36Commit-Rhythmus — 4/52 Wochen mit Commits
18/18Commit-Volumen — 112 Commits im letzten Jahr
0/10OpenSSF Scorecard: Maintained — project was created within the last 90 days. Please review its contents carefully
Verwendete Eingangsdaten
commits_last_year112
human_commit_share1
days_since_last_push6
active_weeks_last_year4

Release-Disziplin

100Exzellent
Wie die Bewertung erfolgt
27/27Liefert Releases aus — 10 Releases veröffentlicht
36/36Release-Aktualität — letztes Release vor 6 Tagen
27/27Release-Rhythmus — ein Release etwa alle 0,8 Tage
0/10OpenSSF Scorecard: Signed-Releases — keine Daten
Verwendete Eingangsdaten
releases_count10
latest_release_tagv0.7.2
releases_from_tagsnein
days_since_latest_release6
mean_days_between_releases0,8
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): OpenSSF Scorecard: Signed-Releases. Die verbleibenden Gewichte wurden renormalisiert.

Community & Verbreitung

Hat das Projekt Nutzer, Downloads, Aufmerksamkeit und ein einladendes Umfeld für Beitragende?

32Gefährdet · 18 % des Gesamtindex
Wie die Bewertung erfolgt
0/60Stars — 0 Stars
0/25Forks — 0 Forks
0/15Watcher — 0 Watcher
Verwendete Eingangsdaten
forks0
stars0
watchers0
growth_stateunverified
growth_factor_pct100
growth_unverified_reasonno_history
Wie die Bewertung erfolgt
22.5/22.5README
22.5/22.5Lizenz — anerkannte Lizenz (MIT)
0/18CONTRIBUTING-Leitfaden
0/13.5Verhaltenskodex
0/7.2Issue-Vorlage
0/6.3PR-Vorlage
Verwendete Eingangsdaten
has_readmeja
has_licenseja
has_contributingnein
has_issue_templatenein
has_code_of_conductnein
has_pull_request_templatenein
Wie die Bewertung erfolgt
44.9/80Downloads pro Monat — 2.335 Downloads/Monat über npm
0/20Abhängige in der Registry — von diesem Ökosystem nicht ausgewiesen
Verwendete Eingangsdaten
packagesvery-nice-mermaid
dependents
ecosystemsnpm
total_downloads
monthly_downloads2.335
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Abhängige in der Registry. Die verbleibenden Gewichte wurden renormalisiert.

Nachhaltigkeit & Governance

Überdauert das Projekt die Menschen, die es tragen — Bus-Faktor, Reaktionsfähigkeit, Trägerschaft und Paketpflege?

52Mittel · 24 % des Gesamtindex
Wie die Bewertung erfolgt
9/54Bus-Faktor — 1 Beitragende decken die Hälfte aller Commits ab
0/22.5Commit-Verteilung — wichtigste beitragende Person verfasste 100 % der Commits
1.4/13.5Breite der Beitragenden — 1 Beitragende
0/10OpenSSF Scorecard: Contributors — project has 0 contributing companies or organizations -- score normalized to 0
Verwendete Eingangsdaten
bus_factor1
contributors_sampled1
top_contributor_share1
Wie die Bewertung erfolgt
0/46.8Issue-Lösungsquote — keine Issues oder keine Daten
38.2/38.3PR-Annahme — 18/18 entschiedene PRs gemergt
0/15OpenSSF Scorecard: Code-Review — Found 0/14 approved changesets -- score normalized to 0
Verwendete Eingangsdaten
merged_prs18
open_issues0
closed_issues0
issue_closed_ratio
closed_unmerged_prs0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Issue-Lösungsquote. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
10/30Organisatorische Trägerschaft — persönliches (Nutzer-)Konto
0/20Verifizierte Domain — für Nutzerkonten nicht anwendbar
3.4/25Reichweite des Inhabers — 2 Follower von ZawadzkiB
23.1/25Kontohistorie — 32 öffentliche Repos, Kontoalter ca. 12 Jahre
Verwendete Eingangsdaten
followers2
owner_typeUser
is_verified
owner_loginZawadzkiB
public_repos32
account_age_days4.470
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Verifizierte Domain. Die verbleibenden Gewichte wurden renormalisiert.

Paketpflege

100Exzellent
Wie die Bewertung erfolgt
25/25Veröffentlicht & auflösbar — 1 Paket(e) auf npm
35/35Veröffentlichungsaktualität — letzte Veröffentlichung vor 6 Tagen
20/20Versionshistorie — 15 veröffentlichte Versionen
20/20Nicht veraltet — aktiv, nicht veraltet oder zurückgezogen
Verwendete Eingangsdaten
packagesvery-nice-mermaid
ecosystemsnpm
any_deprecatednein
min_days_since_publish6

Engineering-Qualität

Sind grundlegende Engineering- und Dokumentationspraktiken vorhanden?

71Gut · 20 % des Gesamtindex
Wie die Bewertung erfolgt
24/24CI-Workflows — 2 Workflow(s)
24/24Tests vorhanden
0/16Linter-Konfiguration
0/9.6Pre-Commit-Hooks
0/6.4.editorconfig
20/20OpenSSF Scorecard: CI-Tests — 14 out of 14 merged PRs checked by a CI test -- score normalized to 10
Verwendete Eingangsdaten
has_cija
has_testsja
has_editorconfignein
has_linter_confignein
has_precommit_confignein
Wie die Bewertung erfolgt
30/30README
25/25Dokumentationsverzeichnis
0/15Dokumentations-/Homepage-Site
10/10Repository-Beschreibung
0/10Topics
10/10Wiki
Verwendete Eingangsdaten
topics
has_wikija
homepage
has_readmeja
has_docs_dirja
has_descriptionja

Sicherheit

Sind die sichtbaren Sicherheits- und Lieferkettenpraktiken belastbar, ohne ungeklärte Exposition gegenüber Hochrisikojurisdiktionen?

41Gefährdet · 16 % des Gesamtindex

Sicherheitslage

26Kritisch
Wie die Bewertung erfolgt
7.5/7.5Binary-Artifacts — no binaries found in the repo
0/7.5Branch-Protection — branch protection not enabled on development/release branches
2.5/2.5CI-Tests — 14 out of 14 merged PRs checked by a CI test -- score normalized to 10
0/2.5CII-Best-Practices — no effort to earn an OpenSSF best practices badge detected
0/7.5Code-Review — Found 0/14 approved changesets -- score normalized to 0
0/2.5Contributors — project has 0 contributing companies or organizations -- score normalized to 0
10/10Dangerous-Workflow — no dangerous workflow patterns detected
0/7.5Dependency-Update-Tool — no update tool detected
0/5Fuzzing — project is not fuzzed
2.5/2.5Lizenz — license file detected
0/7.5Maintained — project was created within the last 90 days. Please review its contents carefully
0/5Packaging — keine Daten
1/5Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
0/5SAST — SAST tool is not run on all commits -- score normalized to 0
0/5Security-Policy — security policy file not detected
0/7.5Signed-Releases — keine Daten
0/7.5Token-Permissions — detected GitHub workflow tokens with excessive permissions
0.8/7.5Vulnerabilities — 9 existing vulnerabilities detected
Verwendete Eingangsdaten
sourceopenssf_scorecard
checks_evaluated16
scorecard_versionv5.5.0
checks_inconclusive2
scorecard_aggregate2,6
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): packaging, signed_releases. Die verbleibenden Gewichte wurden renormalisiert.
Wie die Bewertung erfolgt
35/35Direkte Abhängigkeiten ohne bekannte Advisories — keine direkte Abhängigkeit trägt ein bekanntes Advisory
25/25Indirekte Abhängigkeiten ohne bekannte Advisories — keine indirekte Abhängigkeit trägt ein bekanntes Advisory
0/40Keine offenen Advisories — kein Advisory trägt ein Veröffentlichungsdatum
Verwendete Eingangsdaten
sourceosv
advisories0
affected_packages0
assessed_packages188
unassessed_packages0
affected_by_severitynone
direct_affected_packages0
Von der Bewertung ausgeschlossen (keine Daten oder nicht anwendbar): Keine offenen Advisories. Die verbleibenden Gewichte wurden renormalisiert. Abgeglichen wurde die Laufzeit-Abhängigkeitshülle von npm:very-nice-mermaid@0.7.2 — das, was die Installation des veröffentlichten Pakets nach sich zieht — mit 188 Paketen. Erreichbarkeit wird nicht analysiert.

AI Readiness

Wie gut ist das Repository dafür ausgestattet, mit KI-Coding-Agenten entwickelt und gepflegt zu werden? Ein unabhängiges, experimentelles Badge — Gewicht 0,0, es wird eigenständig ausgewiesen und verändert den Gesamt-Gesundheitswert nicht.

55Mittel · 0 % des Gesamtindex
Wie die Bewertung erfolgt
0/45Agentenanweisungen — keine CLAUDE.md / AGENTS.md / Editor-Regeln
0/15Maschinenlesbare Doku (llms.txt)
40/40Lesbare Commit-Historie — 100 von 100 menschlichen Commits benennen ihre Absicht (strukturierter Betreff oder erläuternder Text)
Verwendete Eingangsdaten
has_llms_txtnein
legible_history_share1
agent_instruction_files
agent_instruction_max_bytes
Wie die Bewertung erfolgt
0/18Bootstrap mit einem Befehl
22/22Automatisierte Tests
0/11Lint-/Format-Konfiguration
11/11Statische Typprüfung — tsconfig.json
10/10Reproduzierbare Umgebung — lockfile
10/10Belegte Agentenpraxis — 61 der letzten 100 Commits von Agenten verfasst oder ihnen zugeschrieben
0/8Automatisierte Wartung — keine automatisierten Abhängigkeits-Updates beobachtet
2/10OpenSSF Scorecard: Pinned-Dependencies — dependency not pinned by hash detected -- score normalized to 2
Verwendete Eingangsdaten
has_nixnein
has_testsja
lockfilespackage-lock.json
has_dockerfilenein
typed_languageja
bootstrap_files
has_devcontainernein
has_linter_confignein
typecheck_configstsconfig.json
agent_commit_share0,61
toolchain_manifests
dependency_bot_commit_share0
Wie die Bewertung erfolgt
45/45Typprüfbarer Code — TypeScript (statisch typisiert)
52.3/55Handhabbare Dateigrößen — 5/101 Quelldateien über 60 KB
Verwendete Eingangsdaten
primary_languageTypeScript
largest_source_bytes400.762
source_files_sampled101
oversized_source_files5
Wie die Bewertung erfolgt
0/40API-Schema (OpenAPI/GraphQL/proto)
0/20MCP-Server
40/40Lauffähige Beispiele — examples
Verwendete Eingangsdaten
example_dirsexamples
has_mcp_signalnein
api_schema_files

Eckdaten

0GitHub-Sterne
1Mitwirkende
112Commits, letzte 12 Monate
6Tage seit letztem Push
10Releases
1Bus-Faktor
0offene Issues
npmPaket-Ökosysteme

Warnungen zur Datenerhebung

  • GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Weitere Details

OpenSSF Scorecard 2.6 / 10
2.6Gesamtwert

Unabhängige, werkzeugneutrale Sicherheitsbewertung durch das quelloffene OpenSSF Scorecard. Jede Prüfung honoriert eine Sicherheits-Praxis, nicht das Werkzeug eines bestimmten Anbieters. Prüfungen, die Scorecard nicht ermitteln konnte, sind mit k. A. markiert und vom Sicherheitswert ausgeschlossen (nie als null gezählt).Scorecard v5.5.0 · 2026-07-26 08:47 UTC

10Binary-Artifactsno binaries found in the repo
0Branch-Protectionbranch protection not enabled on development/release branches
10CI-Tests14 out of 14 merged PRs checked by a CI test -- score normalized to 10
0CII-Best-Practicesno effort to earn an OpenSSF best practices badge detected
0Code-ReviewFound 0/14 approved changesets -- score normalized to 0
0Contributorsproject has 0 contributing companies or organizations -- score normalized to 0
10Dangerous-Workflowno dangerous workflow patterns detected
0Dependency-Update-Toolno update tool detected
0Fuzzingproject is not fuzzed
10Licenselicense file detected
0Maintainedproject was created within the last 90 days. Please review its contents carefully
k. A.Packagingpackaging workflow not detected
2Pinned-Dependenciesdependency not pinned by hash detected -- score normalized to 2
0SASTSAST tool is not run on all commits -- score normalized to 0
0Security-Policysecurity policy file not detected
k. A.Signed-Releasesno releases found
0Token-Permissionsdetected GitHub workflow tokens with excessive permissions
1Vulnerabilities9 existing vulnerabilities detected
Direkte Abhängigkeiten 4
RegistryPaketVersionsvorgabeManifest
npm@dagrejs/dagre1.1.8package.json
npmcommander12.1.0package.json
npmjsdom25.0.1package.json
npmmermaid11.16.0package.json
Alle Abhängigkeiten nicht erhoben

Der aufgelöste Abhängigkeitssatz konnte für diesen Bericht nicht erhoben werden: GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository

Abhängigkeits-Advisories 0

Die Installation von npm:very-nice-mermaid@0.7.2 zieht 188 Pakete nach sich, direkt und transitiv: 0 tragen bekannte Advisories, davon 0 direkte Abhängigkeiten.

Keine bekannten Advisories betreffen die bewerteten Abhängigkeiten.

Ein Advisory bedeutet, dass die im Abhängigkeitsgraphen erfasste Version in den betroffenen Bereich eines Advisories fällt. Erreichbarkeit wird nicht analysiert, und der Graph enthält Entwicklungs- und Test-Pins — ein Fund kann das Werkzeug betreffen und nicht die ausgelieferte Software.

JSON-Rohbericht maschinenlesbar
{
  "data": {
    "repo": {
      "topics": [],
      "is_fork": false,
      "size_kb": 11871,
      "has_wiki": true,
      "homepage": null,
      "languages": {
        "HTML": 103276,
        "Mermaid": 112315,
        "JavaScript": 10137,
        "TypeScript": 1045943
      },
      "pushed_at": "2026-07-20T07:32:31Z",
      "created_at": "2026-07-03T21:11:43Z",
      "owner_type": "User",
      "updated_at": "2026-07-20T07:31:43Z",
      "description": "Framework-agnostic Mermaid flowchart renderer: parse the DSL, dagre auto-layout, and beautiful interactive HTML / SVG / PNG / ASCII — no mermaid.js runtime, no headless browser. Library + web component + vnm CLI.",
      "is_archived": false,
      "is_disabled": false,
      "license_spdx": "MIT",
      "default_branch": "master",
      "license_spdx_raw": "MIT",
      "primary_language": "TypeScript",
      "significant_languages": [
        "TypeScript"
      ]
    },
    "owner": {
      "blog": null,
      "name": "Bartek",
      "type": "User",
      "login": "ZawadzkiB",
      "company": null,
      "location": "Poland, Gdansk",
      "followers": 2,
      "avatar_url": "https://avatars.githubusercontent.com/u/7442319?v=4",
      "created_at": "2014-04-29T17:45:02Z",
      "is_verified": null,
      "public_repos": 32,
      "account_age_days": 4470
    },
    "license": {
      "state": "standard",
      "spdx_id": "MIT",
      "raw_spdx": "MIT",
      "file_present": true,
      "scorecard_found": true,
      "profile_has_license": true
    },
    "activity": {
      "releases": [
        {
          "tag": "v0.7.2",
          "kind": "patch",
          "published_at": "2026-07-20T07:32:32Z"
        },
        {
          "tag": "v0.7.1",
          "kind": "patch",
          "published_at": "2026-07-19T21:44:13Z"
        },
        {
          "tag": "v0.7.0",
          "kind": "minor",
          "published_at": "2026-07-19T20:18:19Z"
        },
        {
          "tag": "v0.6.6",
          "kind": "patch",
          "published_at": "2026-07-15T12:20:39Z"
        },
        {
          "tag": "v0.6.5",
          "kind": "patch",
          "published_at": "2026-07-15T12:17:58Z"
        },
        {
          "tag": "v0.6.4",
          "kind": "patch",
          "published_at": "2026-07-15T00:44:41Z"
        },
        {
          "tag": "v0.6.3",
          "kind": "patch",
          "published_at": "2026-07-14T22:26:57Z"
        },
        {
          "tag": "v0.6.2",
          "kind": "patch",
          "published_at": "2026-07-14T20:59:36Z"
        },
        {
          "tag": "v0.6.1",
          "kind": "patch",
          "published_at": "2026-07-13T22:34:34Z"
        },
        {
          "tag": "v0.6.0",
          "kind": "minor",
          "published_at": "2026-07-13T10:03:37Z"
        }
      ],
      "recent_commits": [
        {
          "oid": "6cf2745e0a4a8adb9b74919fe8df1c7fa610a5cc",
          "body": "feat(theme): make arch-light the default theme; v0.7.2",
          "is_bot": false,
          "headline": "Merge pull request #18 from ZawadzkiB/release/v0.7.2",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-20T07:30:47Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "af087308d26ec4a31ffda5b3ef0561528a315717",
          "body": "A diagram rendered with no theme now uses arch-light (the archify light look:\nclean canvas, monospace type, semantic role colours, coloured/legended edges)\ninstead of light. Centralised as a single DEFAULT_THEME_NAME constant so the CLI\ndefault, the library (resolveTheme(undefined) + unknown-name fa\n[…]\nts only crossing glyph is\n  a genuine two-edge crossing, not the jammed-border artifact TEST-005 guards against.\n\nVersion bumped to 0.7.2. No committed assets change (heroes/docs use explicit themes).",
          "is_bot": false,
          "headline": "feat(theme): make arch-light the default theme; v0.7.2",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-20T06:52:58Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "0325e57c136f4c5546c8ed56c6177e58b5926484",
          "body": "docs(readme): link the login sequence to its live interactive demo",
          "is_bot": false,
          "headline": "Merge pull request #17 from ZawadzkiB/docs/readme-interactive-demo-link",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T22:05:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "74e5ed575e40f7c6333178e7ec3794d1a437d710",
          "body": "Instead of a second static sequence image, the first (login) sequence now links\nto its hosted interactive page (drag / zoom / pan / export) on GitHub Pages, with\nan explicit \"Open this diagram interactively\" call-to-action. Rendered in\narch-light so the thumbnail matches the linked page's theme; the order-checkout\nsequence stays a static arch image below it.",
          "is_bot": false,
          "headline": "docs(readme): link the login sequence to its live interactive demo",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T21:47:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7d489cd0103b417bebae40c49cc87e1ea7807c2e",
          "body": "feat(render): semantic edge colours + legend for arch flowcharts; second archify sequence; v0.7.1",
          "is_bot": false,
          "headline": "Merge pull request #16 from ZawadzkiB/release/v0.7.1",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T21:42:30Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "50a2930ca16c1bd519599086cf1f916ba5d24ca5",
          "body": "…ond archify sequence; v0.7.1\n\nFlowchart edges now carry the archify look, gated behind a new `effects.semanticEdges`\ntheme flag (on for `arch` / `arch-light` only, so `light` / `dark` / `fancy` render\nbyte-for-byte unchanged):\n\n- A labelled edge picks a semantic from its keywords (request / cache /\n[…]\nalso added to the gallery).\n- All README images switched to absolute raw.githubusercontent URLs so they\n  render on the npm package page.\n- Heroes + docs gallery regenerated.\n\nVersion bumped to 0.7.1.",
          "is_bot": false,
          "headline": "feat(render): semantic edge colours + legend for arch flowcharts; sec…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T21:22:40Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "f831884a5f614cd86dd86abade9d81a72f2a212f",
          "body": "Release v0.7.0 — archify sequence diagrams, node-obstacle routing, arch themes",
          "is_bot": false,
          "headline": "Merge pull request #15 from ZawadzkiB/release/v0.7.0",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T20:16:46Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "ee753b26b3d2cc45542a6e9a3431c99662a2e7f1",
          "body": "Regenerate the README hero as the arch theme + hand-drawn sketch, coloured by\nsemantic role (frontend/backend/security/database/messagebus). New committed\nfixture arch-microservices.mmd + a generate-heroes entry so it's reproducible.",
          "is_bot": false,
          "headline": "docs(readme): archify + sketch hero (arch-microservices, role-coloured)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T20:13:25Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "8824846d7f8ad78731af053e1697f39827464d8c",
          "body": "…dpoint\n\nA layout.json / dragged anchor pin is explicit user intent. When a pinned exit\nface makes the elbow dip a crossbar into its own box, the R2 re-entry clamp read\nthat as a wrong-face thread-through and re-anchored the port, breaking the pin\n(REV-007 parallel-edge e2e: a top-pinned source landed on the right border).\nSkip re-anchoring any pinned end — static path via the layout.json anchor\noverrides, runtime twin via its live drag-pin overrides (anchorsOv).",
          "is_bot": false,
          "headline": "fix(routing): trimEndpointReentry must not re-anchor a user-pinned en…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T20:10:20Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "7847fe75b352541245f6ef6c6399006cc7949d46",
          "body": "…v0.7.0\n\nAdds architecture + auth-sequence example renders across all 5 themes × 2 styles\n(interactive HTML + PNG thumbnails), and refreshes every existing diagram with the\nv0.7.0 renderer (arrowhead caps, node-obstacle routing, arch-role colours).",
          "is_bot": false,
          "headline": "docs(gallery): regenerate assets for arch themes + archify sequence; …",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T16:08:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0147f0355d714564bd0e63d8313866a568d115a6",
          "body": "…v0.7.0\n\n- themes: add `arch` / `arch-light` + a universal 7-role semantic palette\n  (frontend/backend/database/cloud/security/messagebus/external) resolvable\n  under every built-in theme\n- render: layer-6 arrowhead caps so a head ending on/inside a node is never\n  hidden by the node fill (SVG + PNG\n[…]\n + sketch\n- cli: `--no-persist` (HTML always opens at the default, ignores saved drags)\n- examples: architecture.mmd + auth-sequence.mmd\n- docs: themes + gallery updated for the new style and examples",
          "is_bot": false,
          "headline": "feat: archify sequence diagrams, node-obstacle routing, arch themes; …",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-19T16:08:05Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "cbef52c19fb2600fce808e8b660b23fcc0739a07",
          "body": "fix(render): route edges around unrelated subgraph containers; v0.6.6",
          "is_bot": false,
          "headline": "Merge pull request #14 from ZawadzkiB/release/v0.6.6",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T12:19:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a6c90dcabccccc2f424cd5a70e993ae7d69dd47e",
          "body": "Release v0.6.5: de-tangle edge convergence + node skewer",
          "is_bot": false,
          "headline": "Merge pull request #13 from ZawadzkiB/release/v0.6.5",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T12:16:26Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5a63de593a178465cb2e71fababc7a24285144ca",
          "body": "docs: make the Library web-component demo live",
          "is_bot": false,
          "headline": "Merge pull request #12 from ZawadzkiB/docs/library-live-demo",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T12:16:13Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "a3628920b6e87d29c1277360751fe3f39f6e561b",
          "body": "A long edge could route as a straight vertical through a subgraph container it\ndoes not belong to (on architecture.mmd, BE<->RULES ran ~400px straight down\nINSIDE the Validation Engine box, impaling past MCP surface / Veris console).\nRoot cause: container boxes are computed post-layout (computeSubgr\n[…]\nr confirmed clean on real\nrenders (light + dark).\n\nNote: a pre-existing parser bug (microservices.mmd subgraph box never renders;\nbyte-identical to master) is out of scope and left for its own ticket.",
          "is_bot": false,
          "headline": "fix(render): route edges around unrelated subgraph containers; v0.6.6",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T12:07:51Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "b8650239aaf7867a85db2cd2fa4c07e043cc0dcd",
          "body": "Two routing defects on dense diagrams, fixed with small gated elbow-only passes:\n\n- Convergence tangle: when 3-4 edges enter the same node side they all jogged at\n  the same y-level and crossed into one knot (Rules-Sets-Runs). New\n  separateConvergentJogs pass in finishEdges (after separateAntiParal\n[…]\ncl. dom-runtime-parity) green, typecheck clean,\nbyte-deterministic; hands-on real-PNG check confirms the RULES knot is a clean\nstaircase and MCP is un-skewered, with fail/retry + label offsets intact.",
          "is_bot": false,
          "headline": "fix(render): de-tangle edge convergence + node skewer; v0.6.5",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T07:23:43Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "a00f7080774f66b736e8deeacf7177c8d8ecea34",
          "body": "The Library page documented the <very-nice-mermaid> element only as a fenced\nHTML code example - it never actually rendered on the site, and the referenced\n./pipeline.mmd did not exist. Make it a real, working live demo:\n\n- Vendor the self-contained element bundle to docs/assets/vnm-element.js via\n \n[…]\nthe bundle\nself-registers, fetches pipeline.mmd, and renders it interactively (fancy theme,\ntoolbar, minimap; the v0.6.4 label-offset shows on the yes/no labels). Docs-only;\nno package/version change.",
          "is_bot": false,
          "headline": "docs(site): make the Library web-component demo live",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T00:50:22Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "5772c94ba70b2b9d00693450d310978a71051b16",
          "body": "Release v0.6.4: lift edge labels off the line (fix label halo)",
          "is_bot": false,
          "headline": "Merge pull request #11 from ZawadzkiB/release/v0.6.4",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T00:43:08Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "afa9d886794d2b987d31c61ee0c7b1f514fc30ed",
          "body": "Every labelled edge on a flowchart / class / state diagram looked broken: the\nlabel was anchored dead-center ON the line, then an opaque, text-width background\nplate was painted over the line in a later draw layer, blanking a text-width\nstretch of the otherwise-continuous line. The shared label rend\n[…]\ners; hands-on visual check on architecture.mmd + gallery\nconfirms continuous lines under every label, no label/node or label/label\noverlap, fail/retry anti-parallel stagger intact, sequence tightened.",
          "is_bot": false,
          "headline": "fix(render): lift edge labels off the line; v0.6.4",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-15T00:40:46Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "ac0839e26c4cec0b9bfe12d4614d0de1c676a034",
          "body": "Release v0.6.3: cache-bust gallery embeds (fix stale live gallery)",
          "is_bot": false,
          "headline": "Merge pull request #10 from ZawadzkiB/release/v0.6.3",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-14T22:25:15Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "e2d5d23406b8f6125df0bec21a86750d41ef6bc6",
          "body": "The gallery embeds each diagram in an <iframe> and lists thumbnails, but the\nasset URLs had no version tag - so after a release browsers kept serving the\ncached iframe/PNG (iframes cache separately from the page, so even a parent\nhard-refresh often didn't re-fetch them). That made every release look\n[…]\n+ uat) for the shipped v0.6.2 de-cramp feature.\n\nVerification: 401 unit tests + typecheck green; --version prints 0.6.3;\nLiquid tags balanced; only the 6 template/version files change (no asset diff).",
          "is_bot": false,
          "headline": "docs(site): cache-bust gallery embeds/thumbnails; v0.6.3",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-14T21:49:00Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "950ef708eccb5c1e7345b0c68633409efea6a759",
          "body": "Release v0.6.2: de-cramp state anti-parallel edges",
          "is_bot": false,
          "headline": "Merge pull request #9 from ZawadzkiB/release/v0.6.2",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-14T20:58:01Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1f09d1dedd4b269b0eeaa5d5873ea49f71353b06",
          "body": "The state diagram's fail/retry pair (Loading<->Error) both routed their\nhorizontal jog at the same mid-y, so the two elbows merged into one crossbar\nwith the up/down arrowheads colliding on a single axis. The v0.6.1 light-edge\ncontrast fix made this pre-existing tangle plainly visible.\n\nAdd a tightl\n[…]\n: 401 unit + 85 e2e green, typecheck clean, dom-runtime-parity holds;\nall four elbow variants visually confirmed (fail/retry cleanly separated); assets\ndeterministic (second re-render byte-identical).",
          "is_bot": false,
          "headline": "fix(render): de-cramp anti-parallel elbow pairs; v0.6.2",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-14T01:13:19Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "6c4ca5428123cde52bba74ccbaedaf7057124d0e",
          "body": "docs: port Claude Code plugin page to master (Pages deploy)",
          "is_bot": false,
          "headline": "Merge pull request #8 from ZawadzkiB/docs/port-plugin-page",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T22:56:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "adf55f734e968d7a3ae7e4254c75c7df0f8360dc",
          "body": "Brings docs/plugin.md and its index.md feature link onto master so the\nGitHub Pages site can be served from master:/docs without losing the plugin\npage. These files previously lived only on the docs/pages-site branch.",
          "is_bot": false,
          "headline": "docs: port Claude Code plugin page to master for Pages deploy",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T22:51:05Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "5acad93211d32d713a3874d3c6f81f31611506ef",
          "body": "Release v0.6.1: diagram render fixes",
          "is_bot": false,
          "headline": "Merge pull request #7 from ZawadzkiB/release/v0.6.1",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T22:33:07Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c0030e2f22216c895ae08710fb9c543c7acf822",
          "body": "Fix the 3 remaining v0.6.0 gallery/README render issues, with no regression\nto the now-good diagrams:\n\n- Issue 1a: the idle->Loading edge now enters perpendicular to the node side\n  via a shared perpendicularizeEntry() on routeElbow (naive elbow and\n  elbowThrough, all sides), so the arrowhead point\n[…]\nrce for the sketch hero). Bump version 0.6.0 -> 0.6.1.\n\nVerification: 397 unit tests + typecheck green; e2e green (new\nrender-fixes-v0.6.1.spec.ts); assets deterministic (re-render is byte-identical).",
          "is_bot": false,
          "headline": "feat(render): v0.6.1 diagram render fixes",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T22:25:13Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "3c8ffa8ba400c96e1522926337cda78c31629cb6",
          "body": "docs: regenerate all diagrams at v0.6.0",
          "is_bot": false,
          "headline": "Merge pull request #6 from ZawadzkiB/docs/regenerate-0.6.0",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T10:19:41Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "04dfa00f19ded34fac46dd40631e216fd8bd451d",
          "body": "Re-render every committed diagram with the 0.6.0 renderer (layered draw\norder, opaque subgraph-title plates, wider fan-in spread, label\nde-collision, edge-crossing bridges):\n\n- docs/ gallery — interactive HTML + PNG thumbnails for flowchart / class /\n  state across style x theme. The 6 sequence arti\n[…]\nrrectly).\n- README hero + gallery — assets/example-{fancy,light,dark,sketch}.png.\n\nexamples/ is already at 0.6.0 (regenerated with the render-fix PR), so it is\nbyte-identical here — nothing to change.",
          "is_bot": false,
          "headline": "docs: regenerate diagram galleries + README heroes at v0.6.0",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T10:16:20Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "90ec773ae57acea130a4094e4797c3f4639a77b8",
          "body": "ci: drop registry-url so npm publish uses OIDC, not a placeholder token",
          "is_bot": false,
          "headline": "Merge pull request #5 from ZawadzkiB/ci/fix-oidc-publish",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:58:18Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "f46d4c67c0ff401420c4a922d519d8bbc6c86a03",
          "body": "setup-node's registry-url writes an .npmrc with a placeholder NODE_AUTH_TOKEN;\nnpm used that bogus token and publishing failed with a misleading E404 instead\nof doing the OIDC exchange (actions/setup-node#1440). Removing registry-url lets\nOIDC trusted publishing work (npm defaults to registry.npmjs.org).",
          "is_bot": false,
          "headline": "ci: drop registry-url so npm publish uses OIDC, not a placeholder token",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:56:16Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "1ae4f368ac27445ae7a918814e1b7af6724601e1",
          "body": "ci: tokenless npm publish via OIDC trusted publishing",
          "is_bot": false,
          "headline": "Merge pull request #4 from ZawadzkiB/ci/npm-trusted-publish",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:48:52Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "0daf2c326b752f16227db47dcef09b63ab7d8c92",
          "body": "feat(render): legible flowchart/state/class rendering (v0.6.0)",
          "is_bot": false,
          "headline": "Merge pull request #3 from ZawadzkiB/fix/flowchart-render-legibility",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:48:19Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "44ab88c22b3c1bb2f7e4b2624fb641d158acfa22",
          "body": "Replace the NPM_TOKEN-based publish.yml with push-npm.yml, which publishes\nvia npm OIDC Trusted Publishing — no secret token. The trusted publisher is\nconfigured on npmjs.com for this repo + this exact workflow filename.\n\nFires when a version bump lands on master (push + paths: package.json), plus a\n[…]\neady on npm, and generates provenance automatically. Uses Node 22 + npm@latest\n(OIDC needs Node >= 22.14 / npm >= 11.5.1) with id-token: write. Tags v<version>\nand creates a GitHub release on success.",
          "is_bot": false,
          "headline": "ci: tokenless npm publish via OIDC trusted publishing (push-npm.yml)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:46:26Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "4e5fad3b9232f90335e9cb74d2223ca1299f34ea",
          "body": "Fix the reported legibility defects in the shared geometry, mirrored\nbyte-for-byte in the inlined interactive runtime (parity-guarded) so the\nHTML export stays pixel-identical to the static SVG:\n\n- 5-layer draw order (subgraph boxes -> edges -> edge-labels -> subgraph\n  titles -> nodes) + an opaque \n[…]\nline-jumps) so crossing lines stay traceable\n  (flowchart + state + class; sequence excluded).\n\nDeterministic; snapshots + examples/ regenerated. 388 unit + 79 e2e green.\nBumps package + CLI to 0.6.0.",
          "is_bot": false,
          "headline": "feat(render): legible flowchart/state/class rendering; v0.6.0",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-13T09:15:10Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "c3348bbca71b85188f69aa310c6ab852bd3b33de",
          "body": "docs: GitHub Pages site with a live interactive gallery",
          "is_bot": false,
          "headline": "Merge pull request #2 from ZawadzkiB/docs/pages-site",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-10T20:23:17Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "9c687f4a8bc8ca688fca152765f0441a126873b5",
          "body": "A VNM monogram drawn as diagram-edge strokes (round-joined, echoing the\nconnectors the tool renders) in a gradient app-icon tile, in the indigo→cyan\nfancy palette:\n\n- assets/logo.svg        — square mark, added to the README header\n- docs/assets/logo.svg   — mark + wordmark lockup, shown in the site sidebar (logo:)\n- docs/assets/favicon.svg — heavier-stroke mark, legible to 16px (site favicon)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add VNM logo (mark, favicon, header lockup)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-10T20:16:16Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e32da28f02fdfde3ff5ba661f2b90c93738fb43e",
          "body": "Set up a Jekyll (just-the-docs) docs site served from /docs, mirroring the\ngogo setup, at https://zawadzkib.github.io/very-nice-mermaid/. Pages:\n\n- index (home + quickstart), gallery, cli, library, themes.\n- The Gallery embeds the REAL self-contained interactive HTML exports in\n  iframes — drag / re\n[…]\nto docs/.\nCI regenerates it each run (non-failing drift note) so the site never drifts\nfrom the renderer. README links the live docs + gallery.\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: add GitHub Pages site with a live interactive gallery",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-10T19:57:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ebfba0818d2e7752b0265bba428df95657b292d3",
          "body": "docs: re-render README images with fixed arrows (0.5.1)",
          "is_bot": false,
          "headline": "Merge pull request #1 from ZawadzkiB/docs/rerender-readme-images",
          "author_name": "Bartek",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T22:33:35Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "d5c035f42da015d2ade0dd163fece0fbc8cb7a18",
          "body": "The homepage hero + light/dark gallery shots were rendered before the\nresvg marker-orient fix, so they showed the old sideways-arrow bug.\nRegenerated with the current renderer — arrowheads now point into their\ntargets. (example-sketch.png uses open hand-drawn arrowheads, not SVG\nmarkers, so it was never affected.)\n\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: re-render README images with the fixed arrow markers (0.5.1)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T14:08:33Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5a9a01187d7c547475eb2703537ae27143c8bbc3",
          "body": "…0.5.1\n\nresvg ignores orient=auto-start-reverse (renders markers un-rotated → arrows\nalways point right). Switch end markers to orient=auto + add reversed-geometry\nstart markers, across all native renderers + the inlined runtime (parity).\nEvery arrowhead now points along its edge in PNG. Examples gallery regenerated.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Merge: fix arrowhead orientation in PNG (resvg auto-start-reverse), v…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T10:22:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "58dbd8094103ca90e94a39434603461f4e867f0b",
          "body": "…heads\n\n`npm run examples` after the marker fix — the committed flowchart/class/\nsequence/state PNGs (+ SVGs) now show arrowheads pointing the right way; no\n\"auto-start-reverse\" remains in any generated SVG.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(examples): regenerate gallery with correctly-oriented PNG arrow…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T10:21:30Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "d8cf404c5a087d185e7dfae31b0a37bcb75a1bcb",
          "body": "- render-svg: assert resvg-safe orient=\"auto\", the mirrored vnm-arrow-start\n  marker, and that a bidirectional edge references BOTH markers correctly.\n- class-svg: assert the four END + four mirrored START markers are defined,\n  no \"auto-start-reverse\" remains, and head=from relations use the -start\n[…]\nh class relation.\n- refresh SVG snapshots for the new marker defs; bump --version test to 0.5.1.\n- version → 0.5.1 (package.json + CLI VERSION).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test+chore: guard marker orient scheme; bump to v0.5.1",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T10:21:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8eddf3e042d8f45fd10bbd1f9049034b3e16f6ce",
          "body": "…start)\n\nThe four class relation markers (triangle / solid+hollow diamond / open arrow)\nalso used orient=\"auto-start-reverse\", so resvg rendered every relation head\nun-rotated in PNG. Switch each to orient=\"auto\" (its tip is at the high-x\nvertex → points into the `to` node) and add a horizontally-mi\n[…]\ncomposition *--, aggregation o--, association -->,\ndependency ..>. PNG-verified: each decoration sits on the correct end pointing\nthe right way.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(class): resvg-safe UML relation markers (orient=auto + mirrored -…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T10:21:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "923abc4e288b53bdc6a9ef8e843ee28784d38d0a",
          "body": "…t marker\n\nEdge arrowheads pointed the wrong way (always +x / right) in PNG output.\nEvery marker used orient=\"auto-start-reverse\", an SVG2 value @resvg/resvg-js\nignores — it renders the marker un-rotated, so a straight-down TD edge got a\nright-pointing head floating at the node. Browsers honor it, s\n[…]\nth marker-start references now match the static SVG exactly, so\nbrowser / PNG / Save-SVG all orient identically (guarded by dom-runtime-parity).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(render): resvg-safe arrow markers via orient=auto + mirrored star…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T10:21:00Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "1325de0d15ea3544e51fce721b8e950521d194e3",
          "body": "Push a `v*` tag to release: the workflow verifies the tag matches\npackage.json, builds/typechecks/tests, and `npm publish --access public\n--provenance` using a repo secret NPM_TOKEN (an npm Automation token) — so a\npublish credential never touches a shell or chat again.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(release): tag-triggered npm publish workflow (token-free)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T09:06:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "8af1a569e30d20973683d43e14dcf244f1f492a1",
          "body": "Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(gogo): stop tracking transient events.jsonl; refresh sketch state",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T09:05:57Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "bdaeb3072603d9309567631048f7adabc6f110a5",
          "body": "The previous drift step used a multi-line `git diff --exit-status ... \\\\ || (...)`\nthat mangled on the runner. Replace with a non-failing drift *warning* + always\nupload the freshly regenerated gallery, so `npm run examples` still runs each\nCI run (failing only on a real render error).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci(examples): regenerate gallery each run without a brittle drift gate",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T06:20:15Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "131ffb418b0cb8e89300f2501da7db53beaff364",
          "body": "…ve tiers (v0.5.0)\n\nThe sketch feature was implemented + tested green but left uncommitted in the\nworking tree (only the 0.5.0 version bump had landed on master, breaking the\nbuild with `unknown option '--style'`). This commits the actual feature:\n\n- src/rough/: deterministic (seeded, no RNG) rough-\n[…]\nanged. assets/fonts/Kalam (OFL).\n- Tests: rough determinism, sketch SVG, native-tier sketch, parity, e2e;\n  339 unit+cli green, typecheck clean.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sketch): hand-drawn (Excalidraw-like) --style sketch across nati…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T06:12:09Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "39428d32d1fd4afefb755d5bbcf515b5d00442f4",
          "body": "…d each run\n\n`npm run examples` renders every source in examples/src through the full\nclean/sketch × light/dark matrix to examples/{png,svg} and rewrites\nexamples/README.md (a gallery grouped by diagram type). A CI job regenerates\nit every run and fails on a stale committed SVG gallery (deterministic output),\nuploading the regenerated set as an artifact.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(examples): auto-generated style × diagram-type gallery, refreshe…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-09T06:06:48Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "b2bb4ac6e2d15f5a4906e04ef2964bdf54cc31c6",
          "body": "….4.1)\n\nThe gallery PNGs were rendered at 0.2.0 and showed the floating-arrow bug;\nregenerated with 0.4.1 so arrowheads land on the shape outlines.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(assets): regenerate README gallery with fixed edge anchoring (v0…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-08T22:08:52Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f563b36e68d1afaedccc0cc7e7f2d8f3af7423d7",
          "body": "Arrowheads now ride the true shape outline (diamond/circle/stadium/hexagon/\ncylinder/parallelogram) instead of floating off the bounding box when spread\nonto channels. Geometry + inlined runtime twin kept in parity.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "Merge: shape-aware edge anchoring (fix floating arrows), v0.4.1",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-08T22:08:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "cb7e7439145828f7549816389d0306f505309717",
          "body": "Patch release: shape-aware edge anchoring (detached arrowhead fix).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump to v0.4.1",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-08T22:04:43Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "0ab20d801dd302fa77da60fbe0d148ba025c7937",
          "body": "…tlines\n\nAdd geometry unit tests asserting a non-zero-offset anchor lies ON the\nshape outline (residual == 1) for diamond, circle/ellipse, and the\nclamped stadium — including the exact repro: anti-parallel A<->B with B a\ndiamond, both B endpoints on B's outline (not floating at the bbox top).\nExtend\n[…]\ntime ==\ncomputePerimeterPorts, projection genuinely active). Refresh the render\nSVG snapshot: the B{Choice} diamond edges now start on its edge.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(geometry): regress spread anchors onto diamond/circle/stadium ou…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-08T22:04:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "af4d338437268b26f9b76afd2ddb19617561d26a",
          "body": "… bbox\n\nNon-rectangular nodes (diamond, circle/ellipse, stadium, rounded,\nsubroutine, hexagon, cylinder, parallelogram/-alt) taper away from their\nbounding box, so a channel-spread anchor (offset != 0 from computePorts)\nlanded OFF the drawn outline — the edge endpoint + its arrowhead floated\nin empt\n[…]\nape is populated wherever routing\nboxes are built: src/layout (layout + applyPositions) and the native\nstate layout's shrunk pseudo-state boxes.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(geometry): anchor spread edges on the real shape outline, not the…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-08T22:04:34Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "933237286e5c0445793c1fcdffc867d662f5b3b3",
          "body": "- .gogo/changelog/2026-07-05-interactive-editing/: synthesized release entry + as-built diagram set\n- full pipeline audit trail in .gogo/work/feature-interactive-editing/ (plan, 6 review + 4 test rounds, UAT log, decisions D1-D7)\n- knowledge drift: code-review-standards + test-strategy gotchas from this feature",
          "is_bot": false,
          "headline": "chore(gogo): ship interactive-editing v0.4.0 to the changelog",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-06T06:12:24Z",
          "body_truncated": false,
          "is_coding_agent": false
        },
        {
          "oid": "00ad4ee2e04581b170878725f10109f4bdb104b5",
          "body": "…-drag, in-browser SVG/PNG export + reset layout (v0.4.0)\n\n- resize handles (min-clamp) with live edge re-anchor; sizes persist (localStorage + layout.json)\n- perimeter-distributed edge anchors (shared geometry, raySide + computePerimeterPorts), byte-parity between static SVG and the inlined runtime\n[…]\ns/sizes/positions\n- 301 unit + 62 Playwright e2e; parity guard covers all shapes, subgraphs, pins, resize\n- BREAKING (model API): RoutedEdge.ports is now {side,offset} anchors (layout.json unaffected)",
          "is_bot": false,
          "headline": "feat(interactive): resize, pinnable perimeter anchors, subgraph group…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-06T06:12:14Z",
          "body_truncated": true,
          "is_coding_agent": false
        },
        {
          "oid": "e3f15dd338e535ad1810524a356e1dc2c59b55b8",
          "body": "Supply-chain hardening: remove ^ ranges so direct deps are pinned to the exact\nversions currently locked (behavior unchanged), and add a project .npmrc with\nsave-exact=true + package-lock=true so future installs stay pinned. The committed\npackage-lock.json (integrity-hashed) + `npm ci` remain the transitive-tree guard.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(security): pin exact dependency versions + save-exact .npmrc",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T21:22:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ecba8249aca41d539203fdb709f27e1660876391",
          "body": "A .claude-plugin manifest + marketplace descriptor + skills/very-nice-mermaid\nSKILL.md that teaches Claude to render and view Mermaid diagrams via the\npublished `vnm` CLI (npx) — picking md/png/html/svg by intent, themes, and how\nto handle the native-vs-fallback tiers + diagnostics. Not shipped in the npm\ntarball (files: dist + README only).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(plugin): add Claude Code plugin with a very-nice-mermaid skill",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T15:30:47Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "70e739aa498b2c82e81a2c69c9029991194454a1",
          "body": "… the changelog\n\n/gogo:done — synthesized changelog entry\n.gogo/changelog/2026-07-04-hybrid-diagram-engine/ (report.md + slug-prefixed\nflow/class/sequence .mmd + before/ set + manifest with members[]); feature\nstate.md → shipped.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(gogo): ship very-nice-mermaid v0.2.0 (hybrid diagram engine) to…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T08:34:38Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e5305574b5770b7ed9a5ef6104819f485b463777",
          "body": "The hybrid diagram engine (all Mermaid types via native re-skin + mermaid.js\nfallback) ships as 0.2.0. Bump package.json, the CLI VERSION constant, and the\n--version test in lockstep.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(release): bump version to 0.2.0",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T08:30:41Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "6c1bc04cc049961ba80a20597042357ca6bcd62f",
          "body": "Close the plan→implement(6)→review(2)→test(2)→report pipeline for\nfeature-hybrid-diagram-engine: as-built report + flow/class/sequence\ndiagrams + before/after (flowchart-only → all-types), review/test round\nsnapshots + screenshots, and the gogo-owned knowledge docs refreshed\n(tech-stack deps + sync/\n[…]\nnc API, tiered architecture, and the verified\ngotchas: theme-injection sink + inlined-runtime/geometry parity). All\nphases green, 0 open issues.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(gogo): phase ⑤ report — hybrid diagram engine (v2) as-built",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T05:10:56Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "c6bec9ade6cd713fa1a55fafcb0288f232c14bf4",
          "body": "…active DOM (TEST-003)\n\nThe .toString()-serialized vnmRuntime — which mount(), mountAsync(), the\n<very-nice-mermaid> element AND the CLI's `-f html` export all use — recomputed\none un-offset anchor per (node, side) and never read the port system, so the\nround-5 anti-parallel/fan fix reached only the\n[…]\nasserts anti-parallel state\nedges get distinct paths + a class fan starts at 3 distinct points — closing the\nexact gap that hid this regression.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(runtime): apply port channel offsets + label stagger in the inter…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T04:59:19Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "77fbde24c9244b06255f45da200af0c57bcf48dc",
          "body": "…t clip (TEST-006)\n\nThe round-5 channel-offset fix separated anti-parallel edge LINES (20u apart)\nbut not their wider label plates (27-70+u), so adjacent plates overlapped and\nthe later-drawn one clipped the earlier label's text (`start`->`st`,\n`pause`->`p`, a flowchart `go` reduced to a sliver).\n\nc\n[…]\ns: a TD + LR bidirectional labelled pair (layout) and the state\nstart/stop pair (state-svg) assert the two computed plate rects don't intersect.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(geometry): stagger anti-parallel edge labels so their plates don'…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T04:59:06Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8b57651d87ba595bbbea59554b53253a7b1ac75f",
          "body": "…ement (TEST-001)\n\nmount(), renderSvg/Html/Ascii/Markdown and the <very-nice-mermaid>\nelement fed any raw string straight to the v1 flowchart parser, so a\nsequence/class/state/pie DSL passed to the LIBRARY (not the CLI) rendered\nas garbage — the exact silent-misparse FR1 promised to kill, present on\n[…]\nraw\nsequence/class/state/pie (native shapes, no flowchart-card garbage;\nfallback gets mermaid SVG). README documents the sync-vs-async contract.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(library): route raw DSL through detectType in the public API + el…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:51:11Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "ad946fc28397de0211ea1ae6175fdddb27c4b3fc",
          "body": "…scii exit code (TEST-004, TEST-005)\n\nTEST-004 (D9-A): a headless jsdom fallback render of a layout-heavy type\n(gantt/ER/gitgraph/kanban/timeline) collapses to a blank/invalid SVG\n(zero/negative viewBox, negative-dim rects, or empty content). Instead of\nreturning the broken SVG (and baking it into H\n[…]\nallback\ntiers, non-zero only under --strict — the fallback tier previously exited\n1 unconditionally, contradicting FR5 and the native precedent.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(fallback): honest hard-fail for degenerate renders + consistent a…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:50:58Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "67b435c96870267078ab3ade170c0baa16d9c5d0",
          "body": "…els (TEST-002, TEST-003)\n\nOne shared mechanism fixes both edge-routing defects, in the geometry\nlayer shared with flowchart:\n- TEST-003: anti-parallel transitions (Running-->Paused / Paused-->Running)\n  routed on the identical path, fully occluding one arrow + label.\n- TEST-002: a fan of relations \n[…]\nge borders are untouched, so ordinary flowchart routing is unchanged\nexcept where a genuine fan/anti-parallel pair benefits (snapshots updated).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(geometry): spread edges sharing a node border onto distinct chann…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:50:47Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "50f87741485267920abb52aed66fdefa4d9f6a13",
          "body": "…try (REV-006)\n\nsplitEnds() took the leftmost valid underscore split of mermaid's\nundelimited id_From_To_n, so with classes A/A_B/B_C/C the relation\nA_B --> C was silently recovered as A --> B_C. Now candidateEnds()\nreturns every valid split and resolveEnds() disambiguates the ambiguous\ncase via the edge-path endpoint geometry (nearest class-node center),\nthe same technique the state reader already uses.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(class): disambiguate underscore-ambiguous relation ends via geome…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:50:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "52e8e5b5ac42d96cf90b7038e7d2c3c413d1c82a",
          "body": "classifyState() keyed on the state NAME (/(^|_)start$/, /(^|_)end$/), so\na real state named end / process_start / session_end was rendered as a\n[*] start-disc / end-ring with its label dropped. Classify on structural\nsignals only: start = a circle.state-start descendant; end = an\nempty-label node carrying the `default` class; everything else normal.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(state): classify pseudo-states structurally, not by name (REV-005)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:50:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "a263c3c2aea12ef7c25d06ed1e826b2ce778ddfe",
          "body": "…REV-007)\n\nmermaid emits a lone U+200B as an unlabeled message's text, and\nString.trim() does not remove it, so the label became \"​\" (truthy)\nand drew a stray empty label plate. Normalize with a cleanLabel() that\nstrips U+200B/C/D + U+FEFF so unlabeled messages carry \"\".\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(sequence): strip zero-width chars from unlabeled message labels (…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T03:50:24Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "ac4b02def233436a57ffc677fed04a056faead08",
          "body": "Class and state are node-graphs, so their interactive DOM + HTML export reuse\nthe flowchart vnmRuntime directly (full draggable nodes with live edge\nre-routing) via the ClassLayout/StateLayout's embedded PositionedModel —\nnothing forks the runtime, so the dom-runtime-parity guard stays green. Router\n[…]\ns the degraded-fallback --strict CLI test to an ER\ndiagram (class no longer falls back).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(class,state): interactive DOM + router/CLI/API wiring + tests",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T02:21:32Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b91023b1c0998782a9e1fb4883ba37989fd52212",
          "body": "Lay out the StateModel with our own dagre (flowchart DiagramModel: normal\nstates rounded, [*] start/end as circle nodes; transitions directed edges),\nthen shrink the start/end pseudo-states to small circles and re-route their\nedges (keeping dagre detour waypoints) so transitions meet the small marke\n[…]\ner idiom. Adds a\nstate fixture + SVG snapshot / XML / determinism / pseudo-shrink tests.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(state): layout + SVG render",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T02:21:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "b2d70950edea7f865b50feb51cf50cfbdc18c695",
          "body": "Read a logical StateModel from mermaid's SVG (same pattern as class, simpler:\nno compartments), discarding mermaid's degenerate headless geometry. Recovers\nstates (normal + [*] start/end pseudo-states, classified by shape/id) and\ndirected transitions: endpoints by matching each transition path's fir\n[…]\nid link. Reuses native/read-util;\nStateModel is a sibling of the flowchart/class models.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(state): reader + model",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T02:21:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "517199ed01656f4a6703d739500cf61e652363c6",
          "body": "Lay out the ClassModel with OUR own dagre (spike-01.md): build a flowchart\nDiagramModel — each class a rect node whose label carries its full compartment\ntext so measureNode sizes the card, each relation a directed edge in relations\norder — and reuse the shared layout(). The resulting ClassLayout wr\n[…]\ns consistent.\nAdds a class fixture + SVG snapshot / XML / determinism / arrowhead tests.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(class): layout + SVG render",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T02:21:02Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "89a498435506880a98d00c618705216fd71c38b4",
          "body": "Read a logical ClassModel from mermaid's SVG (shared lazy loadMermaid path,\nhtmlLabels:false, DOMParser) and discard mermaid's degenerate headless\ngeometry (spike-01.md). Recovers classes (name, stereotype, visibility-tagged\nmembers/methods from the compartment groups) and typed relations: (from,to)\n[…]\nte reader will reuse. Model is a sibling of the flowchart/sequence\nmodels (no mutation).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(class): reader + model",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T02:20:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "073f44bbec5781be6c951979240c25691ea68c0f",
          "body": "Self-contained pan/zoom/fit/minimap shell (seqRuntime, .toString()-inlined\ninto a standalone HTML export via renderSequenceHtml/mountSequence) over the\nthemed static SVG — the plan's sequence interactivity floor (no participant\ndrag; the flowchart vnmRuntime + its parity guard are untouched). Router\n[…]\ntegration and\ne2e coverage; updates the router test to the new native-sequence contract.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sequence): interactive + CLI wiring",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:43:01Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a996b30a2422f8ef4b27a74afc683d4d4fd765f3",
          "body": "Sequence box-art renderer (FR4): participant header boxes, vertical lifelines,\nordered horizontal message arrows (solid ─ / dashed ╌ with ▶/◀ heads) and a\nself-message marker, deterministic, wrapped in the markdown fence. Top-level\nrenderAscii/renderMarkdown delegate a positioned SequenceLayout.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sequence): ascii",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:42:49Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "f5350fd0d3ae7fda5ba58378391c1d87678678ea",
          "body": "Our own deterministic, theme-driven sequence layout (participant boxes,\nlifelines, ordered horizontal message arrows, self-message loops) and a\nstatic themed SVG renderer (light/dark/fancy, valid XML), reusing the shared\narrow marker + edge-label plate idiom and shared escapeXml/escapeXmlAttr sink\ne\n[…]\ng (added to render/style.ts). Top-level renderSvg delegates a\npositioned SequenceLayout.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sequence): layout + SVG render",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:42:42Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5ada74580e0970f84c869abe56c7a9a2727c3792",
          "body": "Read a structured SequenceModel (participants + ordered messages, with\nsolid/dashed line style, arrow direction and self-messages) straight from\nmermaid's rendered SVG via the shared lazy loadMermaid + DOMParser path\n(htmlLabels:false; data-et/data-from/data-to/data-id hooks). Browser-safe:\nno stati\n[…]\nmermaid/jsdom import. Sibling SequenceModel type, not a mutation\nof the flowchart model.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>\nCo-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(sequence): SVG→model reader",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:42:28Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "054545348763e926dd218effa482a05f676151eb",
          "body": "… (REV-004)\n\nclassify() awaited loadMermaid() OUTSIDE the try/catch that guarded only\ndetectType, so a loader rejection would escape classify() (and doRender) and\nabort routing even for inputs that belong on the native flowchart tier with no\nmermaid at all — header-less `A-->B` and genuine garbage b\n[…]\n mermaid to throw on import and asserts a non-flowchart input still\nroutes native, while the explicit-header fast-path never touches the loader.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(router): decouple the native route from a successful mermaid load…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:13:35Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "8a4597e17fcbfbb8f45a864609e3cc1d8ffff064",
          "body": "…003)\n\ninNodeRuntime() keyed only on process.versions.node, so in a hybrid runtime\nthat has BOTH Node and a real DOM (an Electron renderer, or a jsdom/happy-dom\ntest env) a single fallback render stood up a headless jsdom and overwrote\nwindow/document/navigator + shimmed SVGElement.prototype process\n[…]\neometry only degrades under our jsdom stubs, not a real DOM).\n\nUnit test drives the gate directly across no-DOM / real-DOM / partial-stub cases.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(router): gate jsdom on absence of a usable DOM, not on Node (REV-…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:12:36Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "9f507e98004dd619e09bccc9f17efd98a6e0bb76",
          "body": "… (REV-002)\n\nOn a hard-fail fallback type (mindmap/architecture — cytoscape needs a real\ncanvas), jsdom forwarded its \"Not implemented: …getContext\" jsdomError to\nstderr as a raw multi-line Node stack trace, printed before our clean\nrender-failed diagnostic and polluting the structured FR5 channel.\n\n[…]\n exit 1.\n\nCLI test asserts a mindmap emits `render-failed error fallback` but no raw\njsdom trace (no \"Not implemented\"/getContext/stack frames).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(jsdom-env): swallow jsdomError so raw traces don't pollute stderr…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:11:18Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "a094657fa00f68406b6cf8779016d97b76819bba",
          "body": "Theme tokens (font.family, font.size, colors.*) were interpolated raw into\nmermaid's themeVariables, which land in the fallback SVG <style> and get\ninlined into the exported HTML page. A hostile font.family such as\n'sans; } body { display:none } .z { x:url(http://evil/y)' closed mermaid's\nscoped rul\n[…]\nrt the rendered fallback SVG carries neither the injected rule nor `evil`.\nv1 flowchart sanitization + zero-network HTML guarantees re-verified.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(theme-map): sanitize theme values before themeVariables (REV-001)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T01:09:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "241bb7b48da7392b64b3db2cf617e7da83751f55",
          "body": "The CLI now classifies input first: a KNOWN non-flowchart type (pie, sequence,\ngantt, ...) renders via the mermaid.js fallback tier instead of being force-fed\nto the flowchart parser and turned into garbage. Header-less/garbage still falls\nthrough to the native parser (D6 zero-node error preserved).\n[…]\n mutes info, --strict\nescalates a degradation/lost capability to a non-zero exit, and ASCII/md is\nreported unavailable for fallback types (FR4).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(router,cli): stop misparsing non-flowchart types; loud fallback tier",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T00:46:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "82414f9b9e81e920012d7e7a0c4994d16fa0cfd8",
          "body": "src/mermaid/: classify(dsl) routes native (flowchart) vs fallback tier using\nmermaid.detectType (cheap flowchart short-circuit skips loading mermaid);\nrenderFallbackSvg runs mermaid -> SVG in the browser DOM or a persistent jsdom\nin Node (D1, no Chromium), mapping our theme tokens onto mermaid theme\n[…]\nly (D4). jsdom is stood up before the first mermaid import so its\nbundled DOMPurify binds a real window. Adds renderPngFromSvg for fallback PNG.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(mermaid): detectType router + lazy loader + fallback SVG renderer",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T00:46:24Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d849362920e8ad974843e37e315f454739fdb425",
          "body": "A typed { code, severity: info|warn|error, tier, reason, capability?, message }\nrecord + a Diagnostics collector with fallbackTier/capabilityUnavailable/\ndegraded/failed helpers and a greppable formatter. Never fall back silently.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "feat(diagnostics): structured render/fallback diagnostics channel (FR5)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T00:46:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "165e8abf5036cc9b9615c984d2e3502aea158a93",
          "body": "mermaid@^11.16.0 and jsdom@^25 power the fallback tier. Both are marked\nexternal in tsup and imported only via dynamic import() on the render path,\nso the browser-safe core bundle (dist/index.js) is unchanged. Adds a minimal\nambient jsdom type decl (no @types/jsdom dependency).\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "build(deps): add mermaid + jsdom as lazy, external fallback-tier deps",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-04T00:46:09Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "3137f2f0464a27d641fe57a687ce3c3b96ecb87a",
          "body": "/gogo:done — synthesized changelog entry\n.gogo/changelog/2026-07-03-mermaid-render-toolkit/ (report.md + slug-prefixed\nflow/class/sequence .mmd + manifest with members[]); feature state.md → shipped.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(gogo): ship very-nice-mermaid v0.1.0 to the changelog",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T22:14:29Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "e01884cb1c5b908427cbaa34b8db1af9a07cda71",
          "body": "…metadata\n\nAdd a Quick Start (CLI/library/web-component), rendered example images\n(light/dark/fancy) and badges to the README; ship an annotated\ntheme.example.json copy-paste starting point; add the MIT LICENSE file and\nrepository/homepage/bugs/author metadata so npm and GitHub cross-link.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs: quick start, example gallery, theme.example.json, LICENSE, npm …",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T21:55:19Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "24563f286cef563a7d754f15ff61ecd27e883c9f",
          "body": "Two jobs on push/PR: `test` builds, typechecks, and runs vitest (unit + CLI\nintegration, incl. PNG via the optional resvg) across Node 20 & 22; `e2e`\ninstalls Chromium and runs the Playwright suite on Node 20. Make the Playwright\nconfig CI-aware — HTML report + 2 retries with trace on retry under CI — and\nupload the report as an artifact on failure.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "ci: add GitHub Actions workflow (build, typecheck, unit+cli, e2e)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T21:02:14Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "5b4b4c96ec1d7e7f876879fc3bee7def308cf397",
          "body": "CLI integration (test/cli.test.ts, 13 → 36): format inference for svg/png/md,\nevery fixture → valid-XML SVG + zero-network HTML, PNG dimension scaling,\nbuilt-in + custom-JSON themes, --layout/--strict/--title/--background, and\nerror paths. Playwright (e2e, 10 → 19): new interactions.spec.ts covers t\n[…]\nustom-element drag, and a console-error-free\nsession. Adds test:unit / test:cli / test:all scripts and documents the three\nlayers in the README.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test: expand CLI integration + Playwright e2e coverage",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T20:54:17Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d36122c5c25585f3c62937b88a7f2d038460c9bc",
          "body": "…wledge\n\nClose the plan→implement→review→test→report pipeline for\nfeature-mermaid-render-toolkit: as-built report + flow/class/sequence\ndiagrams, review/test round snapshots, and the gogo-owned knowledge docs\nrefreshed from the shipped code. All phases green, 0 open issues.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "docs(gogo): phase ⑤ report — as-built report, diagrams, refreshed kno…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:57:25Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "48aff5b4606e52e4aac29bb70ef11dd5f1a515e0",
          "body": "…007)\n\nExtend test/dom-runtime-parity.test.ts with a curved/fancy-theme parity\ncase over the skip-level shape (flowchart TD / A-->B-->C / A-->C). The\nTEST-001 fix added a curved-edge detour path — geometry.roundedPath() and\nits .toString()-serialized twin runtime.pathRounded() — reached only when\nan\n[…]\nbriefly perturbing the runtime's curved branch to pathPoly (reverted) — no\nproduct code changed. 110 unit (+1), 10 e2e, build + typecheck green.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "test(parity): guard curved/fancy waypoint routing against drift (REV-…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:50:07Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d9ce498d90f6d23b984336bb11c095f1a7687523",
          "body": "TEST-001/002/004/005 -> status: fixed (fixed_in_round 4, fix_summary + fixing\ncommit each); TEST-003 -> wontfix per decisions.md D5. state.md resume notes\nupdated for implement round 4.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(gogo): mark test round 1 findings fixed (implement round 4)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:08:53Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "c51ce398c519567454b26f322ca2ad453503895a",
          "body": "… D6)\n\nRendering nothing is a silent failure. The CLI now exits non-zero with\n`error: no diagram found (input produced 0 nodes)` when parse+layout yields no\nrenderable nodes, in both lenient and strict modes. Unknown constructs *within*\notherwise-valid mermaid still produce >=1 node and stay lenient\n[…]\nlly non-mermaid symbol-soup and empty string exit 1 with the\nmessage; a valid file with an unsupported `click` statement exits 0 with a\nwarning.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(cli): error on input that renders zero nodes (TEST-004 / decision…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:06:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "d69c14a6ea642034734a6f0c9c306432608cd799",
          "body": "An edge's own elbow turn was drawn with the line-merge that turns any h+v\noverlap into `┼`, so every routed turn read as an ambiguous crossing — most\nvisibly a `┼` jammed against the 'Lint passes?' box border in ci-pipeline, with\ninconsistent arrowheads near converging edges.\n\nPlace proper corner gl\n[…]\nupies the cell). ci-pipeline now renders\nfree of `┼` with clean corners and unambiguous arrowheads; a genuine two-edge\ncrossing still shows `┼`.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(ascii): draw edge elbows as corner glyphs, not crossings (TEST-005)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:06:10Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "5d466e71d1ba0b2251658c6d61b8a3668de9cc66",
          "body": "The viewport's onPointerDown captured the pointer for a background pan on ANY\npointerdown inside it, including the fit / zoom-in / zoom-out toolbar buttons\n(children of the viewport). Capturing the pointer redirected the implicit\npointerup and stopped the browser from synthesizing the button's click\n[…]\ne2e (\"fit-to-view actually resets the\ntransform after a real mouse click\") green; the minimap-recenter test locks in\nthat path stays unaffected.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(dom): don't let the viewport swallow toolbar clicks (TEST-002)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:05:57Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "2aa0eb9110f85b3c8c98f97241f8918ff85e78a5",
          "body": "…odes (TEST-001)\n\nBack-edges and skip-level edges were routed as a naive straight elbow between\nthe two node borders, ignoring any node in between — so they cut straight\nthrough intervening boxes (reproducible in the shipped state-machine.mmd, whose\n\"retry\" back-edge sliced the \"Response OK?\" diamon\n[…]\ns assert skip-level, cycle back-edge, the state-machine retry\nedge, and every shipped fixture leave no edge cutting through a non-endpoint\nnode.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(geometry,layout,dom): route multi-rank edges around intervening n…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T16:05:43Z",
          "body_truncated": true,
          "is_coding_agent": true
        },
        {
          "oid": "e4a25e9cbdb90a2f0c2dc690619872a15894180e",
          "body": "Record the REV-006 paren-aware style-split fix (commit 429e832) in the living\nreview contract and state.md resume notes: REV-006 → status fixed,\nfixed_in_round 3, with fix_summary. No open/new review findings remain.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "chore(gogo): mark REV-006 fixed (implement round 3)",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T15:05:35Z",
          "body_truncated": false,
          "is_coding_agent": true
        },
        {
          "oid": "429e832854feeadaae28ee28b2bbedb4782874b3",
          "body": "…e (REV-006)\n\nparseStyleProps() split the style/classDef property list on every comma\nbefore validation, fragmenting a legitimate comma-form CSS color like\nfill:rgb(10,20,30) or hsl(200,50%,40%) into rgb(10 / 20 / 30) — pieces that\nfail the isSafeStyleValue() allowlist, so the color was dropped AND \n[…]\nted, so the REV-001/REV-002 security fixes hold:\na payload like `rgb(10,20,30)\" onmouseover=\"x` is kept as one value and still\ndropped + warned.\n\nCo-Authored-By: Claude Fable 5 <noreply@anthropic.com>",
          "is_bot": false,
          "headline": "fix(parser): paren-aware style split so comma-form rgb()/hsl() surviv…",
          "author_name": "Bartlomiej Zawadzki",
          "author_login": "ZawadzkiB",
          "committed_at": "2026-07-03T15:04:50Z",
          "body_truncated": true,
          "is_coding_agent": true
        }
      ],
      "releases_count": 10,
      "commits_last_year": 112,
      "latest_release_at": "2026-07-20T07:32:32Z",
      "latest_release_tag": "v0.7.2",
      "releases_from_tags": false,
      "days_since_last_push": 6,
      "active_weeks_last_year": 4,
      "days_since_latest_release": 6,
      "mean_days_between_releases": 0.8
    },
    "community": {
      "has_readme": true,
      "has_license": true,
      "has_description": true,
      "has_contributing": false,
      "health_percentage": 42,
      "has_issue_template": false,
      "has_code_of_conduct": false,
      "has_pull_request_template": false
    },
    "ecosystem": {
      "packages": [
        {
          "name": "very-nice-mermaid",
          "exists": true,
          "license": "MIT",
          "keywords": [
            "mermaid",
            "flowchart",
            "diagram",
            "svg",
            "renderer",
            "dagre",
            "interactive",
            "web-component"
          ],
          "ecosystem": "npm",
          "matches_repo": true,
          "registry_url": "https://www.npmjs.com/package/very-nice-mermaid",
          "is_deprecated": false,
          "latest_version": "0.7.2",
          "repository_url": "https://github.com/ZawadzkiB/very-nice-mermaid",
          "versions_count": 15,
          "total_downloads": null,
          "dependents_count": null,
          "deprecation_note": null,
          "maintainers_count": 1,
          "monthly_downloads": 2335,
          "first_published_at": "2026-07-03T22:02:32.100000Z",
          "latest_published_at": "2026-07-20T07:32:29.758000Z",
          "latest_version_yanked": null,
          "days_since_latest_publish": 6
        }
      ]
    },
    "popularity": {
      "forks": 0,
      "stars": 0,
      "watchers": 0,
      "fork_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_forks": 0
      },
      "star_history": {
        "days": [],
        "complete": true,
        "collected": 0,
        "total_stars": 0,
        "collected_at": null
      },
      "open_issues_and_prs": 0
    },
    "ai_readiness": {
      "has_nix": false,
      "example_dirs": [
        "examples"
      ],
      "has_llms_txt": false,
      "has_dockerfile": false,
      "has_mcp_signal": false,
      "bootstrap_files": [],
      "api_schema_files": [],
      "has_devcontainer": false,
      "typecheck_configs": [
        "tsconfig.json"
      ],
      "toolchain_manifests": [],
      "largest_source_bytes": 400762,
      "source_files_sampled": 101,
      "oversized_source_files": 5,
      "agent_instruction_files": [],
      "agent_instruction_max_bytes": null
    },
    "dependencies": {
      "manifests": [
        "package.json"
      ],
      "advisories": {
        "error": null,
        "scope": "published_package",
        "source": "osv",
        "findings": [],
        "collected": true,
        "malicious": [],
        "truncated": false,
        "by_severity": {},
        "advisory_count": 0,
        "affected_count": 0,
        "assessed_count": 188,
        "malicious_count": 0,
        "assessed_package": "npm:very-nice-mermaid@0.7.2",
        "unassessed_count": 0,
        "direct_affected_count": 0
      },
      "ecosystems": [
        "npm"
      ],
      "dependencies": [
        {
          "name": "@dagrejs/dagre",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "1.1.8"
        },
        {
          "name": "commander",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "12.1.0"
        },
        {
          "name": "jsdom",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "25.0.1"
        },
        {
          "name": "mermaid",
          "manifest": "package.json",
          "ecosystem": "npm",
          "version_constraint": "11.16.0"
        }
      ],
      "all_dependencies": {
        "error": "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository",
        "source": null,
        "packages": [],
        "collected": false,
        "truncated": false,
        "total_count": null,
        "direct_count": null,
        "indirect_count": null
      }
    },
    "maintainership": {
      "issues": {
        "open_prs": 0,
        "merged_prs": 18,
        "open_issues": 0,
        "closed_ratio": null,
        "closed_issues": 0,
        "closed_unmerged_prs": 0
      },
      "bus_factor": 1,
      "bot_contributors": 0,
      "top_contributors": [
        {
          "type": "User",
          "login": "ZawadzkiB",
          "commits": 112,
          "avatar_url": "https://avatars.githubusercontent.com/u/7442319?v=4"
        }
      ],
      "contributors_sampled": 1,
      "top_contributor_share": 1
    },
    "quality_signals": {
      "has_ci": true,
      "has_tests": true,
      "ci_workflows": [
        "ci.yml",
        "push-npm.yml"
      ],
      "has_docs_dir": true,
      "linter_configs": [],
      "has_editorconfig": false,
      "has_linter_config": false,
      "has_precommit_config": false
    },
    "security_signals": {
      "lockfiles": [
        "package-lock.json"
      ],
      "scorecard": {
        "checks": [
          {
            "name": "Binary-Artifacts",
            "score": 10,
            "reason": "no binaries found in the repo",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#binary-artifacts"
          },
          {
            "name": "Branch-Protection",
            "score": 0,
            "reason": "branch protection not enabled on development/release branches",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#branch-protection"
          },
          {
            "name": "CI-Tests",
            "score": 10,
            "reason": "14 out of 14 merged PRs checked by a CI test -- score normalized to 10",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#ci-tests"
          },
          {
            "name": "CII-Best-Practices",
            "score": 0,
            "reason": "no effort to earn an OpenSSF best practices badge detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#cii-best-practices"
          },
          {
            "name": "Code-Review",
            "score": 0,
            "reason": "Found 0/14 approved changesets -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#code-review"
          },
          {
            "name": "Contributors",
            "score": 0,
            "reason": "project has 0 contributing companies or organizations -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#contributors"
          },
          {
            "name": "Dangerous-Workflow",
            "score": 10,
            "reason": "no dangerous workflow patterns detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dangerous-workflow"
          },
          {
            "name": "Dependency-Update-Tool",
            "score": 0,
            "reason": "no update tool detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#dependency-update-tool"
          },
          {
            "name": "Fuzzing",
            "score": 0,
            "reason": "project is not fuzzed",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#fuzzing"
          },
          {
            "name": "License",
            "score": 10,
            "reason": "license file detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#license"
          },
          {
            "name": "Maintained",
            "score": 0,
            "reason": "project was created within the last 90 days. Please review its contents carefully",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#maintained"
          },
          {
            "name": "Packaging",
            "score": null,
            "reason": "packaging workflow not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#packaging"
          },
          {
            "name": "Pinned-Dependencies",
            "score": 2,
            "reason": "dependency not pinned by hash detected -- score normalized to 2",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#pinned-dependencies"
          },
          {
            "name": "SAST",
            "score": 0,
            "reason": "SAST tool is not run on all commits -- score normalized to 0",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#sast"
          },
          {
            "name": "Security-Policy",
            "score": 0,
            "reason": "security policy file not detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#security-policy"
          },
          {
            "name": "Signed-Releases",
            "score": null,
            "reason": "no releases found",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#signed-releases"
          },
          {
            "name": "Token-Permissions",
            "score": 0,
            "reason": "detected GitHub workflow tokens with excessive permissions",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#token-permissions"
          },
          {
            "name": "Vulnerabilities",
            "score": 1,
            "reason": "9 existing vulnerabilities detected",
            "documentation_url": "https://github.com/ossf/scorecard/blob/c395761df6afe1a69e476bc60a013a94bcbc153f/docs/checks.md#vulnerabilities"
          }
        ],
        "commit": "6cf2745e0a4a8adb9b74919fe8df1c7fa610a5cc",
        "ran_at": "2026-07-26T08:47:35Z",
        "aggregate_score": 2.6,
        "scorecard_version": "v5.5.0"
      },
      "has_codeql_workflow": false,
      "has_security_policy": false,
      "has_dependabot_config": false
    },
    "contribution_flow": {
      "collected": true,
      "ci_last_run_at": "2026-07-20T07:34:04Z",
      "oldest_open_prs": [],
      "last_merged_pr_at": "2026-07-20T07:30:47Z",
      "ci_last_conclusion": "SUCCESS",
      "oldest_open_issues": []
    }
  },
  "config": {
    "disabled_metrics": [],
    "disabled_categories": [],
    "disabled_components": {}
  },
  "source": {
    "url": "https://github.com/ZawadzkiB/very-nice-mermaid",
    "host": "github.com",
    "name": "very-nice-mermaid",
    "owner": "ZawadzkiB"
  },
  "metrics": {
    "overall": {
      "key": "overall",
      "band": "moderate",
      "name": "Overall health",
      "note": null,
      "notes": [],
      "value": 55,
      "inputs": {
        "security": 41,
        "vitality": 74,
        "community": 32,
        "governance": 52,
        "engineering": 71
      },
      "components": []
    },
    "categories": [
      {
        "key": "vitality",
        "band": "good",
        "name": "Vitality",
        "value": 74,
        "weight": 0.22,
        "metrics": [
          {
            "key": "development_activity",
            "band": "moderate",
            "name": "Development activity",
            "note": null,
            "notes": [],
            "value": 57,
            "inputs": {
              "commits_last_year": 112,
              "human_commit_share": 1,
              "days_since_last_push": 6,
              "active_weeks_last_year": 4
            },
            "components": [
              {
                "key": "push_recency",
                "name": "Push recency",
                "detail": "last push 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "push_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_cadence",
                "name": "Commit cadence",
                "detail": "4/52 weeks with commits",
                "points": 2.8,
                "status": "partial",
                "details": [
                  {
                    "code": "commit_cadence_weeks",
                    "params": {
                      "weeks": 4
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "commit_volume",
                "name": "Commit volume",
                "detail": "112 commits in the last year",
                "points": 18,
                "status": "met",
                "details": [
                  {
                    "code": "commits_last_year",
                    "params": {
                      "count": 112
                    }
                  }
                ],
                "max_points": 18
              },
              {
                "key": "openssf_scorecard_maintained",
                "name": "OpenSSF Scorecard: Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "release_discipline",
            "band": "excellent",
            "name": "Release discipline",
            "note": "Excluded from scoring (no data or not applicable): OpenSSF Scorecard: Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "openssf_scorecard_signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "releases_count": 10,
              "latest_release_tag": "v0.7.2",
              "releases_from_tags": false,
              "days_since_latest_release": 6,
              "mean_days_between_releases": 0.8
            },
            "components": [
              {
                "key": "ships_releases",
                "name": "Ships releases",
                "detail": "10 releases published",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "releases_published",
                    "params": {
                      "count": 10
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "release_recency",
                "name": "Release recency",
                "detail": "latest release 6 days ago",
                "points": 36,
                "status": "met",
                "details": [
                  {
                    "code": "release_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 36
              },
              {
                "key": "release_cadence",
                "name": "Release cadence",
                "detail": "a release every ~0.8 days",
                "points": 27,
                "status": "met",
                "details": [
                  {
                    "code": "release_cadence",
                    "params": {
                      "gap": 0.8
                    }
                  }
                ],
                "max_points": 27
              },
              {
                "key": "openssf_scorecard_signed_releases",
                "name": "OpenSSF Scorecard: Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 10
              }
            ]
          },
          {
            "key": "abandonment",
            "band": "excellent",
            "name": "Abandonment",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "cap": null,
              "state": "unverified",
              "guards": [],
              "signals": [],
              "red_flag": false,
              "multiplier_pct": 100,
              "declared_reason": null,
              "unverified_reason": "repository_too_young",
              "unanswered_open_prs": null,
              "unanswered_open_issues": null,
              "days_since_last_merged_pr": null,
              "days_since_last_human_commit": null,
              "days_since_last_human_commit_is_floor": false
            },
            "components": [
              {
                "key": "project_is_still_maintained",
                "name": "Project is still maintained",
                "detail": "maintenance record not established from the collected data",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "abandonment_unverified",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Is the project alive — is code being written and are releases shipping?"
      },
      {
        "key": "community",
        "band": "at_risk",
        "name": "Community & Adoption",
        "value": 32,
        "weight": 0.18,
        "metrics": [
          {
            "key": "popularity",
            "band": "critical",
            "name": "Popularity & adoption",
            "note": null,
            "notes": [],
            "value": 1,
            "inputs": {
              "forks": 0,
              "stars": 0,
              "watchers": 0,
              "growth_state": "unverified",
              "growth_factor_pct": 100,
              "growth_unverified_reason": "no_history"
            },
            "components": [
              {
                "key": "stars",
                "name": "Stars",
                "detail": "0 stars",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "stars",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 60
              },
              {
                "key": "forks",
                "name": "Forks",
                "detail": "0 forks",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "forks",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "watchers",
                "name": "Watchers",
                "detail": "0 watchers",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "watchers",
                    "params": {
                      "count": 0
                    }
                  }
                ],
                "max_points": 15
              }
            ]
          },
          {
            "key": "community_health",
            "band": "moderate",
            "name": "Community health",
            "note": null,
            "notes": [],
            "value": 50,
            "inputs": {
              "has_readme": true,
              "has_license": true,
              "has_contributing": false,
              "has_issue_template": false,
              "has_code_of_conduct": false,
              "has_pull_request_template": false
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 22.5,
                "status": "met",
                "details": [],
                "max_points": 22.5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "recognized license (MIT)",
                "points": 22.5,
                "status": "met",
                "details": [
                  {
                    "code": "license_standard",
                    "params": {}
                  },
                  {
                    "code": "license_spdx",
                    "params": {
                      "spdx": "MIT"
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributing_guide",
                "name": "CONTRIBUTING guide",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "code_of_conduct",
                "name": "Code of conduct",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 13.5
              },
              {
                "key": "issue_template",
                "name": "Issue template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.2
              },
              {
                "key": "pr_template",
                "name": "PR template",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.3
              }
            ]
          },
          {
            "key": "ecosystem_adoption",
            "band": "moderate",
            "name": "Ecosystem adoption (downloads)",
            "note": "Excluded from scoring (no data or not applicable): Registry dependents. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "registry_dependents"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 56,
            "inputs": {
              "packages": [
                "very-nice-mermaid"
              ],
              "dependents": null,
              "ecosystems": "npm",
              "total_downloads": null,
              "monthly_downloads": 2335
            },
            "components": [
              {
                "key": "monthly_downloads",
                "name": "Monthly downloads",
                "detail": "2,335 downloads/month across npm",
                "points": 44.9,
                "status": "partial",
                "details": [
                  {
                    "code": "downloads_monthly",
                    "params": {
                      "count": 2335,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 80
              },
              {
                "key": "registry_dependents",
                "name": "Registry dependents",
                "detail": "not reported by this ecosystem",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_reported_by_this_ecosystem",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Does the project have users, downloads, attention, and a welcoming setup for contributors?"
      },
      {
        "key": "governance",
        "band": "moderate",
        "name": "Sustainability & Governance",
        "value": 52,
        "weight": 0.24,
        "metrics": [
          {
            "key": "maintainer_resilience",
            "band": "critical",
            "name": "Maintainer resilience (bus factor)",
            "note": null,
            "notes": [],
            "value": 10,
            "inputs": {
              "bus_factor": 1,
              "contributors_sampled": 1,
              "top_contributor_share": 1
            },
            "components": [
              {
                "key": "bus_factor",
                "name": "Bus factor",
                "detail": "1 contributor(s) cover half of all commits",
                "points": 9,
                "status": "partial",
                "details": [
                  {
                    "code": "bus_factor",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 54
              },
              {
                "key": "commit_distribution",
                "name": "Commit distribution",
                "detail": "top contributor authored 100% of commits",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "top_contributor_share",
                    "params": {
                      "share": 100
                    }
                  }
                ],
                "max_points": 22.5
              },
              {
                "key": "contributor_breadth",
                "name": "Contributor breadth",
                "detail": "1 contributors",
                "points": 1.4,
                "status": "partial",
                "details": [
                  {
                    "code": "contributors_sampled",
                    "params": {
                      "count": 1
                    }
                  }
                ],
                "max_points": 13.5
              },
              {
                "key": "openssf_scorecard_contributors",
                "name": "OpenSSF Scorecard: Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "responsiveness",
            "band": "good",
            "name": "Issue & PR responsiveness",
            "note": "Excluded from scoring (no data or not applicable): Issue resolution. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "issue_resolution"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 72,
            "inputs": {
              "merged_prs": 18,
              "open_issues": 0,
              "closed_issues": 0,
              "issue_closed_ratio": null,
              "closed_unmerged_prs": 0
            },
            "components": [
              {
                "key": "issue_resolution",
                "name": "Issue resolution",
                "detail": "no issues or no data",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_issues_or_data",
                    "params": {}
                  }
                ],
                "max_points": 46.75
              },
              {
                "key": "pr_acceptance",
                "name": "PR acceptance",
                "detail": "18/18 decided PRs merged",
                "points": 38.2,
                "status": "met",
                "details": [
                  {
                    "code": "decided_prs_merged",
                    "params": {
                      "merged": 18,
                      "decided": 18
                    }
                  }
                ],
                "max_points": 38.25
              },
              {
                "key": "openssf_scorecard_code_review",
                "name": "OpenSSF Scorecard: Code-Review",
                "detail": "Found 0/14 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              }
            ]
          },
          {
            "key": "stewardship",
            "band": "at_risk",
            "name": "Ownership & stewardship",
            "note": "Excluded from scoring (no data or not applicable): Verified domain. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "verified_domain"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 46,
            "inputs": {
              "followers": 2,
              "owner_type": "User",
              "is_verified": null,
              "owner_login": "ZawadzkiB",
              "public_repos": 32,
              "account_age_days": 4470
            },
            "components": [
              {
                "key": "ownership_backing",
                "name": "Ownership backing",
                "detail": "personal (user) account",
                "points": 10,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_personal",
                    "params": {}
                  }
                ],
                "max_points": 30
              },
              {
                "key": "verified_domain",
                "name": "Verified domain",
                "detail": "not applicable to user accounts",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "not_applicable_to_user_accounts",
                    "params": {}
                  }
                ],
                "max_points": 20
              },
              {
                "key": "owner_reach",
                "name": "Owner reach",
                "detail": "2 followers of ZawadzkiB",
                "points": 3.4,
                "status": "partial",
                "details": [
                  {
                    "code": "owner_followers",
                    "params": {
                      "count": 2,
                      "login": "ZawadzkiB"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "track_record",
                "name": "Track record",
                "detail": "32 public repos, account ~12 yr old",
                "points": 23.1,
                "status": "partial",
                "details": [
                  {
                    "code": "public_repos",
                    "params": {
                      "count": 32
                    }
                  },
                  {
                    "code": "account_age_years",
                    "params": {
                      "years": 12
                    }
                  }
                ],
                "max_points": 25
              }
            ]
          },
          {
            "key": "package_maintenance",
            "band": "excellent",
            "name": "Package maintenance",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "packages": [
                "very-nice-mermaid"
              ],
              "ecosystems": "npm",
              "any_deprecated": false,
              "min_days_since_publish": 6
            },
            "components": [
              {
                "key": "published_resolvable",
                "name": "Published & resolvable",
                "detail": "1 package(s) on npm",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "packages_published",
                    "params": {
                      "count": 1,
                      "ecosystems": "npm"
                    }
                  }
                ],
                "max_points": 25
              },
              {
                "key": "publish_recency",
                "name": "Publish recency",
                "detail": "latest publish 6 days ago",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "publish_recency",
                    "params": {
                      "days": 6
                    }
                  }
                ],
                "max_points": 35
              },
              {
                "key": "version_history",
                "name": "Version history",
                "detail": "15 published versions",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "published_versions",
                    "params": {
                      "count": 15
                    }
                  }
                ],
                "max_points": 20
              },
              {
                "key": "not_deprecated",
                "name": "Not deprecated",
                "detail": "active, not deprecated or yanked",
                "points": 20,
                "status": "met",
                "details": [
                  {
                    "code": "package_not_deprecated",
                    "params": {}
                  }
                ],
                "max_points": 20
              }
            ]
          }
        ],
        "description": "Will the project survive its people — bus factor, responsiveness, who backs it, and package upkeep?"
      },
      {
        "key": "engineering",
        "band": "good",
        "name": "Engineering Quality",
        "value": 71,
        "weight": 0.2,
        "metrics": [
          {
            "key": "engineering_practices",
            "band": "moderate",
            "name": "Engineering practices",
            "note": null,
            "notes": [],
            "value": 68,
            "inputs": {
              "has_ci": true,
              "has_tests": true,
              "has_editorconfig": false,
              "has_linter_config": false,
              "has_precommit_config": false
            },
            "components": [
              {
                "key": "ci_workflows",
                "name": "CI workflows",
                "detail": "2 workflow(s)",
                "points": 24,
                "status": "met",
                "details": [
                  {
                    "code": "ci_workflows",
                    "params": {
                      "count": 2
                    }
                  }
                ],
                "max_points": 24
              },
              {
                "key": "tests_present",
                "name": "Tests present",
                "detail": null,
                "points": 24,
                "status": "met",
                "details": [],
                "max_points": 24
              },
              {
                "key": "linter_config",
                "name": "Linter config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 16
              },
              {
                "key": "pre_commit_hooks",
                "name": "Pre-commit hooks",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 9.6
              },
              {
                "key": "editorconfig",
                "name": ".editorconfig",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 6.4
              },
              {
                "key": "openssf_scorecard_ci_tests",
                "name": "OpenSSF Scorecard: CI-Tests",
                "detail": "14 out of 14 merged PRs checked by a CI test -- score normalized to 10",
                "points": 20,
                "status": "met",
                "details": [],
                "max_points": 20
              }
            ]
          },
          {
            "key": "documentation",
            "band": "good",
            "name": "Documentation",
            "note": null,
            "notes": [],
            "value": 75,
            "inputs": {
              "topics": [],
              "has_wiki": true,
              "homepage": null,
              "has_readme": true,
              "has_docs_dir": true,
              "has_description": true
            },
            "components": [
              {
                "key": "readme",
                "name": "README",
                "detail": null,
                "points": 30,
                "status": "met",
                "details": [],
                "max_points": 30
              },
              {
                "key": "documentation_directory",
                "name": "Documentation directory",
                "detail": null,
                "points": 25,
                "status": "met",
                "details": [],
                "max_points": 25
              },
              {
                "key": "documentation_homepage_site",
                "name": "Documentation / homepage site",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "repository_description",
                "name": "Repository description",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "topics",
                "name": "Topics",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 10
              },
              {
                "key": "wiki",
                "name": "Wiki",
                "detail": null,
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              }
            ]
          }
        ],
        "description": "Are baseline engineering and documentation practices in place?"
      },
      {
        "key": "security",
        "band": "at_risk",
        "name": "Security",
        "value": 41,
        "weight": 0.16,
        "metrics": [
          {
            "key": "security_posture",
            "band": "critical",
            "name": "Security posture",
            "note": "Excluded from scoring (no data or not applicable): Packaging, Signed-Releases. Remaining weights renormalized.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "packaging",
                    "signed_releases"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              }
            ],
            "value": 26,
            "inputs": {
              "source": "openssf_scorecard",
              "checks_evaluated": 16,
              "scorecard_version": "v5.5.0",
              "checks_inconclusive": 2,
              "scorecard_aggregate": 2.6
            },
            "components": [
              {
                "key": "binary_artifacts",
                "name": "Binary-Artifacts",
                "detail": "no binaries found in the repo",
                "points": 7.5,
                "status": "met",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "branch_protection",
                "name": "Branch-Protection",
                "detail": "branch protection not enabled on development/release branches",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "ci_tests",
                "name": "CI-Tests",
                "detail": "14 out of 14 merged PRs checked by a CI test -- score normalized to 10",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "cii_best_practices",
                "name": "CII-Best-Practices",
                "detail": "no effort to earn an OpenSSF best practices badge detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "code_review",
                "name": "Code-Review",
                "detail": "Found 0/14 approved changesets -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "contributors",
                "name": "Contributors",
                "detail": "project has 0 contributing companies or organizations -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "dangerous_workflow",
                "name": "Dangerous-Workflow",
                "detail": "no dangerous workflow patterns detected",
                "points": 10,
                "status": "met",
                "details": [],
                "max_points": 10
              },
              {
                "key": "dependency_update_tool",
                "name": "Dependency-Update-Tool",
                "detail": "no update tool detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "fuzzing",
                "name": "Fuzzing",
                "detail": "project is not fuzzed",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "license",
                "name": "License",
                "detail": "license file detected",
                "points": 2.5,
                "status": "met",
                "details": [],
                "max_points": 2.5
              },
              {
                "key": "maintained",
                "name": "Maintained",
                "detail": "project was created within the last 90 days. Please review its contents carefully",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "packaging",
                "name": "Packaging",
                "detail": "packaging workflow not detected",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 5
              },
              {
                "key": "pinned_dependencies",
                "name": "Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 1,
                "status": "partial",
                "details": [],
                "max_points": 5
              },
              {
                "key": "sast",
                "name": "SAST",
                "detail": "SAST tool is not run on all commits -- score normalized to 0",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "security_policy",
                "name": "Security-Policy",
                "detail": "security policy file not detected",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 5
              },
              {
                "key": "signed_releases",
                "name": "Signed-Releases",
                "detail": "no releases found",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "no_data",
                    "params": {}
                  }
                ],
                "max_points": 7.5
              },
              {
                "key": "token_permissions",
                "name": "Token-Permissions",
                "detail": "detected GitHub workflow tokens with excessive permissions",
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 7.5
              },
              {
                "key": "vulnerabilities",
                "name": "Vulnerabilities",
                "detail": "9 existing vulnerabilities detected",
                "points": 0.8,
                "status": "partial",
                "details": [],
                "max_points": 7.5
              }
            ]
          },
          {
            "key": "dependency_advisories",
            "band": "excellent",
            "name": "Dependency advisories",
            "note": "Excluded from scoring (no data or not applicable): No advisories left outstanding. Remaining weights renormalized. Matched the npm:very-nice-mermaid@0.7.2 runtime dependency closure — what installing the published package pulls in — 188 packages. Reachability is not analyzed.",
            "notes": [
              {
                "code": "excluded_no_data",
                "params": {
                  "components": [
                    "no_advisories_left_outstanding"
                  ]
                }
              },
              {
                "code": "weights_renormalized",
                "params": {}
              },
              {
                "code": "advisories_scope_published",
                "params": {
                  "package": "npm:very-nice-mermaid@0.7.2",
                  "assessed": 188
                }
              },
              {
                "code": "advisories_reachability",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "source": "osv",
              "advisories": 0,
              "affected_packages": 0,
              "assessed_packages": 188,
              "unassessed_packages": 0,
              "affected_by_severity": "none",
              "direct_affected_packages": 0
            },
            "components": [
              {
                "key": "direct_dependencies_free_of_known_advisories",
                "name": "Direct dependencies free of known advisories",
                "detail": "no direct dependency carries a known advisory",
                "points": 35,
                "status": "met",
                "details": [
                  {
                    "code": "no_direct_advisories",
                    "params": {}
                  }
                ],
                "max_points": 35
              },
              {
                "key": "indirect_dependencies_free_of_known_advisories",
                "name": "Indirect dependencies free of known advisories",
                "detail": "no indirect dependency carries a known advisory",
                "points": 25,
                "status": "met",
                "details": [
                  {
                    "code": "no_indirect_advisories",
                    "params": {}
                  }
                ],
                "max_points": 25
              },
              {
                "key": "no_advisories_left_outstanding",
                "name": "No advisories left outstanding",
                "detail": "no advisory carries a publication date",
                "points": 0,
                "status": "excluded",
                "details": [
                  {
                    "code": "advisories_no_publication_date",
                    "params": {}
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "malicious_dependencies",
            "band": "excellent",
            "name": "Malicious dependencies",
            "note": null,
            "notes": [],
            "value": 100,
            "inputs": {
              "source": "osv",
              "meaning": "reported as a malicious package by the OpenSSF corpus; the remedy is removal or moving off the compromised name, never an upgrade of the same artifact. Versions the registry has since pulled are listed but not scored",
              "packages": [],
              "red_flag": false,
              "assessed_packages": 188,
              "malicious_packages": 0,
              "direct_malicious_packages": 0,
              "withdrawn_malicious_packages": 0,
              "installable_malicious_packages": 0
            },
            "components": [
              {
                "key": "no_dependency_reported_as_a_malicious_package",
                "name": "No dependency reported as a malicious package",
                "detail": "no dependency is reported as a malicious package",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "no_malicious_dependencies",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          },
          {
            "key": "high_risk_jurisdiction_exposure",
            "band": "excellent",
            "name": "High-Risk Jurisdiction Exposure",
            "note": "Only high-confidence self-published location evidence affects this multiplier. Ambiguous matches are review-only; country evidence is not proof of nationality, citizenship, legal registration, malicious intent, or sanctions status.",
            "notes": [
              {
                "code": "jurisdiction_evidence_limits",
                "params": {}
              }
            ],
            "value": 100,
            "inputs": {
              "meaning": "self-published location evidence; not nationality or citizenship",
              "red_flag": false,
              "exposures": [],
              "policy_countries": [
                "Russia",
                "Iran",
                "North Korea"
              ],
              "review_only_matches": 0,
              "assessed_self_published_locations": 2
            },
            "components": [
              {
                "key": "policy_exposure_multiplier",
                "name": "Policy exposure multiplier",
                "detail": "no confirmed policy-scope location match",
                "points": 100,
                "status": "met",
                "details": [
                  {
                    "code": "jurisdiction_no_match",
                    "params": {}
                  }
                ],
                "max_points": 100
              }
            ]
          }
        ],
        "description": "Are visible security and supply-chain practices strong, with no malicious dependency and no unresolved high-risk jurisdiction exposure?"
      },
      {
        "key": "ai_readiness",
        "band": "moderate",
        "name": "AI Readiness",
        "value": 55,
        "weight": 0,
        "metrics": [
          {
            "key": "ai_agent_context",
            "band": "at_risk",
            "name": "Agent context & guidance",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "has_llms_txt": false,
              "legible_history_share": 1,
              "agent_instruction_files": [],
              "agent_instruction_max_bytes": null
            },
            "components": [
              {
                "key": "agent_instructions",
                "name": "Agent instructions",
                "detail": "no CLAUDE.md / AGENTS.md / editor rules",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_agent_instructions",
                    "params": {}
                  }
                ],
                "max_points": 45
              },
              {
                "key": "machine_readable_docs_llms_txt",
                "name": "Machine-readable docs (llms.txt)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 15
              },
              {
                "key": "legible_commit_history",
                "name": "Legible commit history",
                "detail": "100 of 100 human commits state their intent (structured subject or explanatory body)",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "legible_history",
                    "params": {
                      "legible": 100,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          },
          {
            "key": "ai_verify_loop",
            "band": "moderate",
            "name": "Verify loop (build / test / typecheck)",
            "note": null,
            "notes": [],
            "value": 55,
            "inputs": {
              "has_nix": false,
              "has_tests": true,
              "lockfiles": [
                "package-lock.json"
              ],
              "has_dockerfile": false,
              "typed_language": true,
              "bootstrap_files": [],
              "has_devcontainer": false,
              "has_linter_config": false,
              "typecheck_configs": [
                "tsconfig.json"
              ],
              "agent_commit_share": 0.61,
              "toolchain_manifests": [],
              "dependency_bot_commit_share": 0
            },
            "components": [
              {
                "key": "one_command_bootstrap",
                "name": "One-command bootstrap",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 18
              },
              {
                "key": "automated_tests",
                "name": "Automated tests",
                "detail": null,
                "points": 22,
                "status": "met",
                "details": [],
                "max_points": 22
              },
              {
                "key": "lint_format_config",
                "name": "Lint / format config",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 11
              },
              {
                "key": "static_type_checking",
                "name": "Static type checking",
                "detail": "tsconfig.json",
                "points": 11,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "tsconfig.json"
                    }
                  }
                ],
                "max_points": 11
              },
              {
                "key": "reproducible_environment",
                "name": "Reproducible environment",
                "detail": "lockfile",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "lockfile"
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "demonstrated_agent_practice",
                "name": "Demonstrated agent practice",
                "detail": "61 of the last 100 commits agent-authored or agent-credited",
                "points": 10,
                "status": "met",
                "details": [
                  {
                    "code": "agent_authored_commits",
                    "params": {
                      "count": 61,
                      "sampled": 100
                    }
                  }
                ],
                "max_points": 10
              },
              {
                "key": "automated_maintenance",
                "name": "Automated maintenance",
                "detail": "no automated dependency updates observed",
                "points": 0,
                "status": "missed",
                "details": [
                  {
                    "code": "no_dependency_automation",
                    "params": {}
                  }
                ],
                "max_points": 8
              },
              {
                "key": "openssf_scorecard_pinned_dependencies",
                "name": "OpenSSF Scorecard: Pinned-Dependencies",
                "detail": "dependency not pinned by hash detected -- score normalized to 2",
                "points": 2,
                "status": "partial",
                "details": [],
                "max_points": 10
              }
            ]
          },
          {
            "key": "ai_code_legibility",
            "band": "excellent",
            "name": "Code legibility for models",
            "note": null,
            "notes": [],
            "value": 97,
            "inputs": {
              "primary_language": "TypeScript",
              "largest_source_bytes": 400762,
              "source_files_sampled": 101,
              "oversized_source_files": 5
            },
            "components": [
              {
                "key": "type_checkable_code",
                "name": "Type-checkable code",
                "detail": "TypeScript (statically typed)",
                "points": 45,
                "status": "met",
                "details": [
                  {
                    "code": "statically_typed_language",
                    "params": {
                      "language": "TypeScript"
                    }
                  }
                ],
                "max_points": 45
              },
              {
                "key": "manageable_file_sizes",
                "name": "Manageable file sizes",
                "detail": "5/101 source files over 60KB",
                "points": 52.3,
                "status": "partial",
                "details": [
                  {
                    "code": "oversized_source_files",
                    "params": {
                      "kb": 60,
                      "sampled": 101,
                      "oversized": 5
                    }
                  }
                ],
                "max_points": 55
              }
            ]
          },
          {
            "key": "ai_interfaces",
            "band": "at_risk",
            "name": "Machine-readable interfaces",
            "note": null,
            "notes": [],
            "value": 40,
            "inputs": {
              "example_dirs": [
                "examples"
              ],
              "has_mcp_signal": false,
              "api_schema_files": []
            },
            "components": [
              {
                "key": "api_schema_openapi_graphql_proto",
                "name": "API schema (OpenAPI/GraphQL/proto)",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 40
              },
              {
                "key": "mcp_server",
                "name": "MCP server",
                "detail": null,
                "points": 0,
                "status": "missed",
                "details": [],
                "max_points": 20
              },
              {
                "key": "runnable_examples",
                "name": "Runnable examples",
                "detail": "examples",
                "points": 40,
                "status": "met",
                "details": [
                  {
                    "code": "file_list",
                    "params": {
                      "files": "examples"
                    }
                  }
                ],
                "max_points": 40
              }
            ]
          }
        ],
        "description": "How well is the repo equipped to be developed and maintained with AI coding agents? An independent, experimental badge — weight 0.0, so it is surfaced on its own and does not affect the overall health score."
      }
    ],
    "metrics_version": "1.13.0"
  },
  "warnings": [
    "GitHub dependency-graph SBOM unavailable (404); the dependency graph may be disabled for this repository"
  ],
  "report_type": "repository",
  "generated_at": "2026-07-26T08:47:49.598828Z",
  "schema_version": "0.27.0",
  "badge_url": "https://raw.githubusercontent.com/inspect-software/badges/main/v1/z/ZawadzkiB/very-nice-mermaid.svg",
  "full_name": "ZawadzkiB/very-nice-mermaid",
  "license_state": "standard",
  "license_spdx": "MIT"
}

Bewertungen sind Signale, keine Garantien. Sie spiegeln öffentlich sichtbare Praxis auf GitHub wider — kein Code-Audit und keine Sicherheitsgarantie.

Fehlende Daten werden ausgeschlossen und die Gewichte neu normiert, nie als null bewertet. Die Methodik ist versioniert und offen: Metriken v1.13.0, Schema v0.27.0 — vollständige Methodik · Metriken-Wiki.

Wie ein einzelnes Ergebnis im Gesamtregister steht: aggregierte Statistikennpm.