{"id":51048337,"url":"https://github.com/pepperonas/repo2viz","last_synced_at":"2026-06-22T15:02:01.232Z","repository":{"id":361926588,"uuid":"1256467001","full_name":"pepperonas/repo2viz","owner":"pepperonas","description":"Repository Activity Visualizer – GitHub/Azure DevOps URL to a standalone interactive HTML dashboard (Material 3 dark, Chart.js). Timelines, heatmaps, peak-time clock, hotspots, contributor analytics.","archived":false,"fork":false,"pushed_at":"2026-06-01T21:35:25.000Z","size":2507,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T22:15:23.275Z","etag":null,"topics":["analytics","azure-devops","charts","dashboard","git","github","heatmap","material-design","python","visualization"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pepperonas.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-01T20:03:39.000Z","updated_at":"2026-06-01T21:35:29.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pepperonas/repo2viz","commit_stats":null,"previous_names":["pepperonas/repo2viz"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/pepperonas/repo2viz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepperonas%2Frepo2viz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepperonas%2Frepo2viz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepperonas%2Frepo2viz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepperonas%2Frepo2viz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pepperonas","download_url":"https://codeload.github.com/pepperonas/repo2viz/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pepperonas%2Frepo2viz/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34653715,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-22T02:00:06.391Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analytics","azure-devops","charts","dashboard","git","github","heatmap","material-design","python","visualization"],"created_at":"2026-06-22T15:02:00.289Z","updated_at":"2026-06-22T15:02:01.222Z","avatar_url":"https://github.com/pepperonas.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"screenshots/banner.png\" alt=\"repo2viz\" width=\"100%\"\u003e\u003c/p\u003e\n\n# repo2viz\n\n\u003e Repository-Aktivität auf einen Blick — als eigenständige, interaktive HTML-Datei.\n\n\u003cp\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz/releases\"\u003e\u003cimg alt=\"Version\" src=\"https://img.shields.io/badge/version-2.5.0-d0bcff\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg alt=\"License: MIT\" src=\"https://img.shields.io/badge/license-MIT-yellow\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz/releases/latest\"\u003e\u003cimg alt=\"Downloads\" src=\"https://img.shields.io/github/downloads/pepperonas/repo2viz/total?label=downloads\u0026color=blueviolet\"\u003e\u003c/a\u003e\n  \u003cimg alt=\"Python\" src=\"https://img.shields.io/badge/python-3.11%2B-3776AB?logo=python\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Dependencies\" src=\"https://img.shields.io/badge/dependencies-stdlib%20%2B%20git-2ea44f\"\u003e\n  \u003cimg alt=\"No build\" src=\"https://img.shields.io/badge/build-none-success\"\u003e\n  \u003cimg alt=\"Single file\" src=\"https://img.shields.io/badge/output-single%20HTML-orange\"\u003e\n  \u003cbr\u003e\n  \u003cimg alt=\"GitHub\" src=\"https://img.shields.io/badge/source-GitHub-181717?logo=github\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Azure DevOps\" src=\"https://img.shields.io/badge/source-Azure%20DevOps-0078D7?logo=azuredevops\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Chart.js\" src=\"https://img.shields.io/badge/charts-Chart.js-FF6384?logo=chartdotjs\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"PySide6\" src=\"https://img.shields.io/badge/GUI-PySide6%20%2F%20Qt%206-41CD52?logo=qt\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Azure DevOps\" src=\"https://img.shields.io/badge/PO%20Dashboard-Azure%20Work%20Items-0078D7?logo=azuredevops\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"DORA metrics\" src=\"https://img.shields.io/badge/metrics-DORA-7ddfa0\"\u003e\n  \u003cimg alt=\"Material Design 3\" src=\"https://img.shields.io/badge/design-Material%203-6750A4?logo=materialdesign\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Mobile ready\" src=\"https://img.shields.io/badge/mobile-ready-34d399\"\u003e\n  \u003cbr\u003e\n  \u003cimg alt=\"SemVer\" src=\"https://img.shields.io/badge/semver-2.0.0-blue\"\u003e\n  \u003cimg alt=\"PRs welcome\" src=\"https://img.shields.io/badge/PRs-welcome-brightgreen\"\u003e\n  \u003cimg alt=\"Platform\" src=\"https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-lightgrey\"\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz/commits\"\u003e\u003cimg alt=\"Last commit\" src=\"https://img.shields.io/github/last-commit/pepperonas/repo2viz?color=informational\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz\"\u003e\u003cimg alt=\"Repo size\" src=\"https://img.shields.io/github/repo-size/pepperonas/repo2viz\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz\"\u003e\u003cimg alt=\"Top language\" src=\"https://img.shields.io/github/languages/top/pepperonas/repo2viz\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/pepperonas/repo2viz/stargazers\"\u003e\u003cimg alt=\"Stars\" src=\"https://img.shields.io/github/stars/pepperonas/repo2viz?style=social\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n`repo2viz` nimmt eine **GitHub-** oder **Azure-DevOps**-Repository-URL entgegen, klont das\nRepo lesend, analysiert die git-Historie und erzeugt **eine einzelne, eigenständige\nHTML-Datei** mit interaktiven Charts und automatischen Analysen — im\n**Material-3-Expressive-Design (Dark)**, mit umschaltbaren Zeiträumen und Heatmaps.\n\nKein Build, keine Dependencies, kein Server: Skript ausführen → HTML im Browser öffnen.\n\n---\n\n## Nutzung\n\n### Schnellstart\n\n```bash\n# 1 · Repo klonen\ngit clone https://github.com/pepperonas/repo2viz.git\ncd repo2viz\n\n# 2 · Report für ein beliebiges öffentliches Repo erzeugen\npython3 repo2viz.py https://github.com/pallets/click\n\n# 3 · Die erzeugte  \u003crepo-name\u003e-activity.html  im Browser öffnen\n```\n\n\u003e **Voraussetzung:** Python 3.11+ und `git` im `PATH` — sonst nichts zu installieren.\n\u003e Details unter [Voraussetzungen](#voraussetzungen).\n\n### Aufruf\n\n```bash\npython3 repo2viz.py \u003crepo-url\u003e [-o ausgabe.html] [--token TOKEN] [--keep-clone]\n```\n\n| Option | Beschreibung |\n|--------|--------------|\n| `url` | Repository-URL (GitHub oder Azure DevOps) — **erforderlich** |\n| `-o`, `--output` | Ziel-HTML-Datei (Standard: `\u003crepo-name\u003e-activity.html`) |\n| `--token` | Auth-Token / PAT für private Repos (\u0026 Azure-DevOps-Work-Item-API) |\n| `--keep-clone` | Temporären Bare-Clone nicht löschen (Debugging) |\n| `--anonymize` | Contributor-Namen im HTML pseudonymisieren (DSGVO) |\n| `--no-po` | PO-/Delivery-Dashboard nicht erzeugen |\n| `--ado-api-version` | Azure-DevOps-REST-api-version (Default `7.1`) |\n| `--version` | Version ausgeben |\n\n### Beispiele\n\n```bash\n# Öffentliches GitHub-Repo (Ausgabedatei wird automatisch benannt)\npython3 repo2viz.py https://github.com/pallets/click\n\n# Azure DevOps\npython3 repo2viz.py https://dev.azure.com/org/projekt/_git/repo\n\n# Eigene Ausgabedatei\npython3 repo2viz.py https://github.com/me/repo -o report.html\n\n# Privates Repo mit Token\npython3 repo2viz.py https://github.com/me/private --token ghp_xxx\n```\n\n### Authentifizierung privater Repos\n\nToken per `--token` **oder** Umgebungsvariable (in dieser Reihenfolge geprüft):\n\n| Provider | Umgebungsvariablen |\n|----------|--------------------|\n| GitHub | `GITHUB_TOKEN`, `GH_TOKEN` |\n| Azure DevOps | `AZURE_DEVOPS_PAT`, `AZURE_DEVOPS_TOKEN`, `SYSTEM_ACCESSTOKEN` |\n| beliebig | `GIT_TOKEN` (Fallback) |\n\n```bash\nexport GITHUB_TOKEN=ghp_xxx\npython3 repo2viz.py https://github.com/me/private\n```\n\nDas Token wird nur für den Clone verwendet, nicht in der HTML gespeichert, und aus\netwaigen Fehlermeldungen maskiert.\n\n---\n\n![Übersicht des repo2viz-Dashboards](screenshots/overview.png)\n\n\u003csub\u003eBeispiel-Dashboard für \u003ccode\u003evuejs/core\u003c/code\u003e (7022 Commits · 632 Contributors · 280 Tags).\u003c/sub\u003e\n\n---\n\n## Features\n\n| | |\n|---|---|\n| 📊 **10 KPI-Karten** | Commits, Contributors, Zeilen +/−, aktive Tage, Ø Commits/Tag, Median-Commit-Größe, Conventional-Commits-Anteil, Peak-Stunde, Top-Wochentag |\n| 🧠 **Auto-Analyse** | Bus-Faktor, Wochenend-/Kernzeit-Anteil, Churn-Verhältnis, Aktivitätstrend, längste Commit-Serie \u0026 Pause — automatisch abgeleitet |\n| 📈 **Commit-Timeline** | Commits über Zeit mit gleitendem Durchschnitt + **Release-Tag-Markern**; Granularität (Tag/Woche/Monat) passt sich dem Zeitraum an |\n| 🔥 **Heatmap** | Wochentag × Tageszeit — wann wird committet? (Autor-lokale Stunde) |\n| 🟩 **Contribution-Kalender** | Tägliche Commits der letzten 12 Monate im GitHub-Style |\n| 🩹 **Code-Churn + Wachstum** | Hinzugefügte / gelöschte Zeilen pro Zeiteinheit + kumulative Netto-Zeilen-Kurve |\n| 🏷️ **Commit-Qualität** | Conventional-Commit-Typen (feat/fix/docs…) + Commit-Größen-Histogramm |\n| 👥 **Contributor-Analyse** | Top-Contributors-Tabelle, Anteils-Doughnut + **Lebensdauer-Gantt** (erste→letzte Aktivität) |\n| 📁 **Datei-Insights** | Meist geänderte Dateien + Dateityp-Verteilung nach Churn |\n| 🔥 **Hotspots \u0026 Risiko** | Häufig geänderte Dateien mit wenigen Autoren (Wissensrisiko/Refactoring-Kandidaten) |\n| 🗂️ **Verzeichnis-Bus-Faktor** | Commits \u0026 Contributor-Zahl je Top-Verzeichnis — wo hängt Wissen an wenigen? |\n| 🔗 **Co-Change-Kopplung** | Dateien, die häufig zusammen geändert werden — impliziter Architektur-Zusammenhang |\n| 🙋 **Contributor-Filter** | Statistiken pro Person — Dropdown im Header oder Klick auf eine Tabellenzeile filtert das ganze Dashboard |\n| 📅 **Tagesdetail** | Klick auf einen Kalendertag → Stundenverteilung, Churn \u0026 Beteiligte dieses Tages |\n| 🕘 **Stoßzeiten** | Radiales 24h-Zifferblatt der Commit-Verteilung über die Tageszeit |\n| ⏱️ **Zeitraum-Umschaltung** | 30 T / 90 T / 180 T / 1 Jahr / Gesamt — clientseitig, sofort |\n| 📱 **Mobile-Ready** | Responsives Layout für Smartphone \u0026 Tablet |\n| 📋 **PO-/Delivery-Dashboard** | Eigener View, der Engineering-Daten in PO-Sprache übersetzt — mit Azure-DevOps-Work-Item-Anreicherung ([Details](#po--delivery-dashboard)) |\n| 📐 **DORA \u0026 Qualität** | Rework-Rate (Change-Failure), Defekt-Module, Test-Begleitung, verwaistes Wissen, Release-Kadenz/Time-to-release + Monte-Carlo-Forecast ([Details](#dora--qualität)) |\n| 🧑‍🤝‍🧑 **Team \u0026 Architektur** | Team-Trend (aktive Devs, Bus-Faktor, After-Hours), Cross-Modul-Kopplung, Codebase-IST (Sprachen, größte Dateien) ([Details](#team--architektur)) |\n| 🔐 **GitHub \u0026 Azure DevOps** | Provider-Auto-Erkennung, Token-Auth für private Repos |\n\n---\n\n## Screenshots\n\n### KPI-Karten \u0026 Contributor-Filter\nZehn Kennzahlen auf einen Blick; das Dropdown oben rechts (bzw. ein Klick in der\nContributor-Tabelle) löst alle Statistiken nach Person auf.\n\n![KPI-Karten](screenshots/kpis.png)\n\n### Commit-Timeline mit Release-Tags\nCommits über Zeit mit gleitendem Durchschnitt; gestrichelte Marker = `git tag`-Releases.\n\n![Commit-Timeline](screenshots/timeline.png)\n\n### Aktivitäts-Heatmap \u0026 Stoßzeiten\nWochentag × Tageszeit (links) und das radiale 24-Stunden-Zifferblatt der Stoßzeiten (rechts).\n\n| Heatmap (Wochentag × Stunde) | Stoßzeiten (24h-Uhr) |\n|---|---|\n| ![Heatmap](screenshots/heatmap.png) | ![Stoßzeiten](screenshots/clock.png) |\n\n### Tagesdetail \u0026 Contribution-Kalender\nKlick auf eine Kalenderzelle (rechts) öffnet das Tagesdetail (links): Stundenverteilung,\nChurn und Beteiligte eines einzelnen Tages.\n\n| Tagesdetail | Contribution-Kalender |\n|---|---|\n| ![Tagesdetail](screenshots/daydetail.png) | ![Contribution-Kalender](screenshots/calendar.png) |\n\n### Commit-Typen \u0026 Hotspots\nConventional-Commit-Verteilung und Dateien mit hohem Wissensrisiko (oft geändert, wenige Autoren).\n\n| Commit-Typen | Hotspots \u0026 Wissensrisiko |\n|---|---|\n| ![Commit-Typen](screenshots/commit-types.png) | ![Hotspots](screenshots/hotspots.png) |\n\n### Mobile\nVollständig responsiv — inklusive View-Umschalter, Filter und 2-spaltigen KPIs (iPhone-Viewport):\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"screenshots/mobile.png\" alt=\"Mobile-Ansicht\" width=\"300\"\u003e\u003c/p\u003e\n\n---\n\n## GUI (Desktop-App)\n\nWer keine Kommandozeile nutzen möchte: Es gibt eine **Desktop-App** (PySide6 / Qt 6)\nim selben Material-3-Dark-Design — URL eingeben, „Report generieren\" klicken, fertig.\n\n![repo2viz GUI](screenshots/gui.png)\n\n### Fertige Pakete herunterladen\n\nVorgefertigte Builds für alle Betriebssysteme gibt es in den\n**[Releases](https://github.com/pepperonas/repo2viz/releases/latest)**:\n\n| OS | Paket | Nutzung |\n|----|-------|---------|\n| 🍎 **macOS** | `repo2viz-gui-macos.zip` | entpacken → `repo2viz-gui.app` starten |\n| 🪟 **Windows** | `repo2viz-gui-windows-x86_64.zip` | entpacken → `repo2viz-gui.exe` starten |\n| 🐧 **Linux** | `repo2viz-gui-linux-x86_64.tar.gz` | entpacken → `./repo2viz-gui` ausführen |\n\n\u003e **Laufzeit-Voraussetzung:** `git` muss installiert und im `PATH` sein. Die Pakete\n\u003e sind unsigniert — unter macOS ggf. über *Rechtsklick → Öffnen* bzw.\n\u003e *Systemeinstellungen → Datenschutz \u0026 Sicherheit* freigeben.\n\n### Aus dem Quellcode starten\n\n```bash\npip install -r requirements-gui.txt   # PySide6\npython3 repo2viz_gui.py\n```\n\n---\n\n## PO-/Delivery-Dashboard\n\nNeben der Engineering-Sicht gibt es einen zweiten View **„Product / Delivery\"** (Umschalter\noben im Header). Leitprinzip: **übersetzen statt nur darstellen.** Ein Product Owner liest\nkeinen Code-Churn — er fragt *„Liefern wir Wert, vorhersagbar, ohne Risiko für die Roadmap?\"*\nJede Kennzahl wird in dieser Sprache beantwortet (mit Ein-Satz-Erklärung im UI).\n\n![PO-/Delivery-Dashboard](screenshots/po-dashboard.png)\n\n\u003csub\u003ePO-Ansicht im eingeschränkten Modus (GitHub, ohne Work-Item-Metadaten).\u003c/sub\u003e\n\n### Module\n\n| Modul | Beantwortet für den PO |\n|-------|------------------------|\n| **Investment-Mix** | Wo ging die Kapazität hin? Anteil nach Feature/Story · Bug · Tech-Debt (Donut + Trend über Zeit). |\n| **Delivery-Throughput** | Wie viele Work Items hatten pro Woche/Monat Code-Aktivität? (Velocity-Trend-Proxy) |\n| **Cycle-Time-Proxy** | Wie lange brauchen Items typischerweise von erster bis letzter Code-Berührung? (Median + Verteilung) |\n| **Roadmap-Risiko** | Welche Area Paths/Epics hängen an einer Person oder sind instabil (viel Nacharbeit)? |\n| **Rework-Indikator** | Wie viel ist Nacharbeit statt Neubau? (Churn-Ratio, Bug-Anteil) |\n| **Prozess-Hygiene** | Anteil Commits **ohne** Work-Item-Bezug — Traceability/Datenqualität fürs Reporting. |\n\n### Azure-DevOps-Integration\n\nDer größte Hebel ist die Verknüpfung von Commits mit **Azure DevOps Work Items**:\n\n1. **Immer (ohne API):** Commit-Messages werden auf Work-Item-Referenzen geparst\n   (`#1234` und `AB#1234`) → Mapping Commit → Work-Item-ID rein aus git.\n2. **Mit PAT (Azure DevOps):** Über die REST-API (`workitemsbatch`, api-version 7.1) werden\n   Typ, State, Parent (für **Epic-Rollup**), Area Path, Iteration und Tags nachgeladen\n   (Batch ≤ 200 IDs, robustes Error-Handling, Parent-Ketten-Auflösung).\n\n```bash\nexport AZURE_DEVOPS_PAT=xxxxxxxx        # Scope: Work Items (Read)\npython3 repo2viz.py https://dev.azure.com/org/projekt/_git/repo\n```\n\nDas PAT wird **nur** für die API-Authentifizierung verwendet, landet **nie** in der HTML und\nwird aus Fehlermeldungen maskiert. Self-hosted **Azure DevOps Server** wird über den\n`/_git/`-Pfad erkannt; die API-Basis wird aus der Repo-URL abgeleitet (ggf. `--ado-api-version`\nauf `6.0`/`5.0` setzen).\n\n### Graceful Degradation\n\n| Situation | PO-Dashboard |\n|-----------|--------------|\n| **Azure DevOps + PAT** | Voll: angereicherte Work Items (Typ, State, Epic, Area Path). |\n| **Azure DevOps ohne PAT** | Nur aus Commit-Messages geparste IDs — mit Hinweis „PAT für volle Auswertung setzen\". |\n| **GitHub** | Provider-unabhängige Teile (Conventional-Commit-basierter Investment-Mix, Rework, Hygiene), klar als eingeschränkt gekennzeichnet. |\n\nFehlt etwas, stürzt nichts ab — alle Felder werden defensiv behandelt.\n\n### Relevante Optionen\n\n| Option / Env | Beschreibung |\n|--------------|--------------|\n| `AZURE_DEVOPS_PAT` (Env) | PAT für die Work-Item-Anreicherung (auch `AZURE_DEVOPS_TOKEN`, `SYSTEM_ACCESSTOKEN`, `--token`). |\n| `--ado-api-version` | Azure-DevOps-REST-api-version (Default `7.1`; on-prem ggf. `6.0`/`5.0`). |\n| `--anonymize` | Contributor-Namen im HTML pseudonymisieren — sinnvoll, da PO-Dashboards breiter geteilt werden (DSGVO). |\n| `--no-po` | PO-Dashboard nicht erzeugen. |\n\n---\n\n## DORA \u0026 Qualität\n\nZusätzliche Metriken, die Liefer- und Codequalität messbar machen — **alle clone-only**\n(keine API, kein Token nötig). Im Engineering-View ergänzen sie die bestehenden Charts,\nein Forecast liegt im PO-View.\n\n![Rework-Rate](screenshots/dora-rework.png)\n\n| Metrik | Was sie misst | Wie sie ermittelt wird |\n|--------|---------------|------------------------|\n| **Rework-Rate** (Change-Failure-Proxy) | Wie oft frisch Geliefertes sofort nachgebessert wird | Anteil der **Nicht-Fix-Commits**, denen binnen **14 Tagen** ein `fix:`-Commit auf **derselben Datei** folgt (monatlicher Trend + Gesamtquote). |\n| **Defekt-anfällige Module** | Wo sich Bugs sammeln | Dateien mit den meisten `fix:`-Commits (≥ 2). |\n| **Test-Begleitung** | Ob Testabdeckung mitwächst | Monatliche Quote des Churns in Test-/Spec-Dateien (`tests/`, `*.test.*`, `*_spec.*` …) am Gesamt-Churn. |\n| **Verwaistes Wissen** | Code ohne aktiven Betreuer | Dateien, deren **letzter** Autor seit **\u003e 180 Tagen** keinen Commit mehr gemacht hat. |\n| **Release-Kadenz \u0026 Time-to-release** | Wie oft \u0026 wie schnell wir ausliefern | Releases je Quartal, Median-Abstand zwischen Tags, Median-Zeit Commit → nächster Tag (Deployment-Frequency-Proxy). |\n| **Throughput-Forecast** (Monte-Carlo) | „Schaffen wir den Plan?\" | 2000 Simulationen über die Verteilung des Wochentempos der letzten 26 Wochen → erwarteter Durchsatz der nächsten 8 Wochen (50 % / 85 % Konfidenz). |\n\n| Release-Kadenz \u0026 Time-to-release | Throughput-Forecast (PO-View) |\n|---|---|\n| ![Release-Kadenz](screenshots/dora-cadence.png) | ![Forecast](screenshots/dora-forecast.png) |\n\n\u003e Damit deckt repo2viz die vier **DORA-Metriken** praktisch ab: Lead Time, Deployment\n\u003e Frequency, Change Failure Rate und Rework als MTTR-Näherung. Die Schwellen\n\u003e (14-Tage-Rework-Fenster, 180-Tage-Orphan-Grenze) stehen als Konstanten im Code.\n\n---\n\n## Team \u0026 Architektur\n\nDrei Dimensionen, die über reine Aktivität hinausgehen — **alle clone-only**.\n\n![Team-Entwicklung](screenshots/team-trend.png)\n\n- **Team-Trend** — aktive Entwickler pro Monat und After-Hours-/Wochenend-Anteil (Dual-Achse)\n  plus **Bus-Faktor je Quartal**. Antwort: *„Wächst das Team, steigt der Druck, werden wir\n  resilienter oder fragiler?\"*\n- **Cross-Modul-Kopplung** — Anteil der Multi-File-Commits, die **Modulgrenzen überspannen**\n  (Trend), plus die am stärksten verschränkten Modul-Paare. Antwort: *„Erodiert unsere\n  Modularität?\"* Module werden über bis zu zwei Pfad-Ebenen bestimmt (z. B. `packages/ui`),\n  Wurzeldateien (README, Configs …) zählen nicht als Modul.\n- **Codebase-IST** — aktuelle **Sprach-/Dateityp-Verteilung** nach Größe und **größte Dateien**\n  in HEAD (via `git ls-tree --long`, ohne Checkout). Antwort: *„Wie sieht die Codebase jetzt\n  aus — nicht nur, wie sie sich verändert?\"*\n\n| Cross-Modul-Kopplung | Sprachen heute |\n|---|---|\n| ![Cross-Modul-Kopplung](screenshots/cross-module.png) | ![Sprachen heute](screenshots/languages.png) |\n\n---\n\n## Voraussetzungen\n\n* **Python 3.11+** — die CLI nutzt nur die Standardbibliothek, keine Pakete zu installieren\n* **git** im `PATH`\n* **Internet beim Öffnen der HTML** — Chart.js + Matrix- und Annotation-Plugin werden per\n  CDN geladen (mit verifizierten SRI-Integritäts-Hashes als Schutz gegen CDN-Manipulation)\n* **nur für die GUI:** [PySide6](https://pypi.org/project/PySide6/) (`pip install -r requirements-gui.txt`)\n  — die fertigen Release-Pakete bringen alles mit, dann ist nichts zu installieren\n\n---\n\n## Funktionsweise\n\n```\nURL ──▶ Provider erkennen ──▶ git clone --bare (temp) ──▶ git log --no-merges --numstat\n                                                                      │\n                                                                      ▼\n        HTML mit eingebetteten Daten ◀── Aggregation in Python ◀── Parsing\n                     │\n                     ▼\n   Browser: clientseitige Aggregation je Zeitraum (Chart.js)\n```\n\n1. **Provider-Erkennung** über den Host der URL (github.com / dev.azure.com / visualstudio.com).\n2. **Bare-Clone** in ein temporäres Verzeichnis (kein Working-Tree → schnell), das danach\n   automatisch entfernt wird.\n3. **Analyse** via `git log --no-merges --numstat` — Commits, Autoren, Zeitstempel (Autor-lokal)\n   und Zeilen-Churn pro Datei.\n4. **Einbettung**: Die komplette Historie wird kompakt (wenige Integer pro Commit) als JSON in\n   die HTML eingebettet. **Alle Zeitraum-Aggregationen passieren clientseitig in JavaScript** —\n   deshalb ist das Umschalten der Zeiträume sofort und ohne erneute Datenbeschaffung.\n\n---\n\n## Hinweise \u0026 Designentscheidungen\n\n* Analysiert wird die git-Historie **ohne Merge-Commits** (`--no-merges`), damit Churn nicht\n  doppelt gezählt wird.\n* **Zeitraumunabhängig (gesamtbezogen)** sind: Dateien, Dateitypen, Hotspots, Verzeichnis-Bus-Faktor,\n  Co-Change-Kopplung, Contributor-Lebensdauer und der Contribution-Kalender — sie sind entsprechend\n  beschriftet. Alle übrigen Charts reagieren auf den Zeitraum-Umschalter.\n* **Commit-Typen** werden per [Conventional-Commits](https://www.conventionalcommits.org/)-Muster\n  aus der Message-Zeile klassifiziert (`feat:`, `fix:`, `docs:` …); nicht typisierte Messages\n  fallen unter „sonstige\".\n* **Hotspots** = häufig geänderte Dateien geteilt durch Autorenzahl → hoher Wert = oft geändert\n  *und* von wenigen betreut (Wissensrisiko). Nur Dateien mit ≥ 3 Änderungen.\n* **Co-Change-Kopplung** betrachtet nur Commits mit 2–40 berührten Dateien (vermeidet quadratische\n  Explosion bei Massen-Commits) und listet Paare ab 3 gemeinsamen Commits.\n* **Release-Marker** in der Timeline stammen aus `git tag` (Erstell-/Commit-Datum des Tags).\n* Contributors werden **per E-Mail-Adresse** zusammengeführt; unterschiedliche E-Mails derselben\n  Person erscheinen als getrennte Einträge.\n* Stunden in der Heatmap sind **Autor-lokal** (aus dem Zeitzonen-Offset des Commits), nicht UTC.\n* Der **Contribution-Kalender** zeigt fix die letzten 12 Monate, unabhängig vom Zeitraum-Umschalter.\n* Der **Contributor-Filter** wirkt auf alle zeitbasierten Charts, KPIs, Insights, Heatmaps und den\n  Kalender. Strukturelle Analysen (Hotspots, Verzeichnis-Bus-Faktor, Co-Change-Kopplung,\n  Lebensdauer) bleiben gesamtbezogen, und die Top-Contributors-Tabelle zeigt immer alle Personen\n  (damit man weiterhin umschalten kann).\n\n---\n\n## Versionierung\n\nDas Projekt folgt [Semantic Versioning](https://semver.org/lang/de/) (`MAJOR.MINOR.PATCH`).\nDie aktuelle Version steht in `repo2viz.py` (`__version__`) und ist über `--version` abrufbar:\n\n```bash\npython3 repo2viz.py --version     # -\u003e repo2viz 2.1.0\n```\n\nSie erscheint außerdem im Footer jeder generierten HTML. Alle Änderungen sind im\n[CHANGELOG.md](CHANGELOG.md) dokumentiert.\n\n---\n\n## Troubleshooting\n\n| Problem | Ursache / Lösung |\n|---------|------------------|\n| `git clone fehlgeschlagen` | URL prüfen; bei privaten Repos Token setzen (`--token` / Env-Variable). |\n| Charts bleiben leer | Internetzugang beim Öffnen der HTML nötig (Chart.js per CDN). |\n| `Keine Commit-Daten gefunden` | Repo ist leer oder enthält nur Merge-Commits. |\n| Falsche/fehlende Contributors | Mehrere E-Mail-Adressen pro Person — ggf. `.mailmap` im Repo pflegen. |\n\n---\n\n## Lizenz\n\n[MIT](LICENSE) © 2026 Martin Pfeffer ([pepperonas](https://github.com/pepperonas))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpepperonas%2Frepo2viz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpepperonas%2Frepo2viz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpepperonas%2Frepo2viz/lists"}