# Claude Live Dashboard Ein rahmenloses Always-on-Top-Widget für Windows, das die Auslastung des Claude-Plans live anzeigt: 5-Stunden-Fenster, Wochenverbrauch, Reset-Countdown, Tokenverbrauch je Modell und die Hochrechnung auf das Fensterende. Die Daten stammen aus den Transkripten, die Claude Code ohnehin unter `~/.claude/projects/**/*.jsonl` schreibt. Es wird nichts installiert, nichts mitgeschnitten und standardmäßig keine Netzwerkverbindung aufgebaut. ## Start Node.js wird benötigt. Ist es nicht im `PATH` (etwa bei nvm-windows ohne aktive Version), genügt der Versionspfad: ```powershell $env:PATH = "$env:APPDATA\nvm\v22.22.1;$env:PATH" npm install npm start ``` Das Tray-Symbol landet unter Windows zunächst im Überlaufbereich hinter dem `^` in der Taskleiste; per Drag lässt es sich dauerhaft sichtbar machen. ## Bedienung | Aktion | Wirkung | |---|---| | Kopfzeile ziehen | Fenster verschieben (Position wird gemerkt) | | ⚙ | Einstellungen öffnen | | „Details“ | Modell-Aufschlüsselung, Tempo und Datengrundlage aufklappen | | `–` | Ausblenden — Rückkehr über das Tray-Symbol | | Tray-Klick | Ein-/Ausblenden | | Tray-Menü | Deckkraft, Klick-Durchlässigkeit, Autostart, Einstellungen, Beenden | ### Einstellungen Das Zahnrad in der Kopfzeile öffnet einen Dialog für alle Felder der `config.json`: Deckkraft, Klick-Durchlässigkeit, Autostart, Serverabfrage, Bezugsgrößen, Gewichtung und Wochenfenster. Gespeicherte Änderungen greifen **sofort** — ohne Neustart. Der Dialog liest und schreibt dieselbe Datei, die sich auch von Hand bearbeiten lässt: Kommentarfelder (`_hinweis` und Verwandte) und unbekannte Einträge bleiben dabei unangetastet, weil die vorhandene Datei nur ergänzt und nicht ersetzt wird. `Strg`+`S` speichert, `Esc` schließt. Autostart ist kein Feld der Datei, sondern ein Systemzustand — er wird deshalb sofort beim Umschalten übernommen, unabhängig vom Speichern. „Klicks durchlassen“ macht das Widget für Mausereignisse transparent — es liegt dann über der Arbeit, ohne sie zu behindern. Zurückschalten geht über das Tray-Menü. ## Was angezeigt wird **Laufende Sitzung** — Auslastung des aktuellen 5-Stunden-Fensters, dazu verbrauchte Tokens und Tempo. **Wochenkontingent** — das übergeordnete Limit über alle Modelle, mit exaktem Reset-Zeitpunkt. **Nutzungsguthaben** — der Budget-Zustand jenseits des Plan-Kontingents (verbraucht von Monatslimit). Erscheint nur, wenn der Server ihn meldet. Darunter die eigentliche Kernaussage: *wie lange das Kontingent bei diesem Tempo noch reicht* — gerechnet in **aktiver Arbeitszeit**, nicht in Kalenderzeit. Eine Hochrechnung der Burn-Rate auf fünf Kalendertage wäre Unsinn, weil niemand durchgehend arbeitet. ## Woher die Werte kommen Standardmäßig fragt das Dashboard denselben Endpunkt ab, den auch `/usage` nutzt (`GET /api/oauth/usage` bei `api.anthropic.com`). Damit sind die Prozentwerte, Schweregrade und Reset-Zeitpunkte **exakt** — sekundengenau und ohne Schätzung. Das Zugriffstoken wird aus `~/.claude/.credentials.json` gelesen, nie gespeichert, nie protokolliert und nur an diesen Host gesendet. Es gibt bewusst keinen eigenen Refresh-Flow: Läuft das Token ab, pausiert die Abfrage, bis Claude Code es erneuert hat. Nach drei Fehlversuchen schaltet sie sich für die Sitzung ab. Abschalten über `config.json`: ```json { "oauth": { "enabled": false } } ``` **Wichtig:** Der Endpunkt ist nicht dokumentiert und kann durch ein Update brechen. Deshalb rechnet das Dashboard *immer* auch lokal weiter — fällt die Abfrage aus, läuft es ohne Unterbrechung auf den eigenen Zahlen weiter, nur eben mit Näherungswerten. Die Anzeige sagt jederzeit, welcher Fall vorliegt: | Anzeige | Bedeutung | |---|---| | **exakt (Server)** | Wert vom Server, entspricht `/usage` — nur mit Stufe 2 | | **eigener Wert** | `limits` aus `config.json` | | **kalibriert** | aus mindestens 5 eigenen abgeschlossenen Fenstern abgeleitet | | **geschätzt** | noch zu wenige Messungen, grober Anhaltspunkt | Solange die Serverabfrage läuft, kalibriert sich das Dashboard **selbst**: Der Server nennt den exakten Anteil, lokal ist der gewichtete Verbrauch im selben Fenster bekannt — daraus folgt die Bezugsgröße unmittelbar. Auch das Wochenfenster wird aus dem gemeldeten Reset-Zeitpunkt abgeleitet, nicht geraten. Die folgenden Abschnitte betreffen nur den Fall, dass die Abfrage **nicht** verfügbar ist. ### Kalibrieren (Rückfallebene) Ohne Serverabfrage nimmt das Dashboard das höchste je beobachtete Fenstervolumen als untere Schranke des Limits. Das ist grob. Besser: den Prozentwert in **Einstellungen ▸ Nutzung** ablesen und unmittelbar danach: ```powershell npm run calibrate -- --week 14 # nur rechnen npm run calibrate -- --week 14 --write # in config.json übernehmen npm run calibrate -- --block 37 --write # 5-Stunden-Fenster ``` Das Werkzeug teilt den aktuellen Verbrauch durch den angezeigten Anteil und erhält so die Bezugsgröße exakt. Danach das Dashboard neu starten. Steht in der Nutzungsanzeige ein fester Reset-Zeitpunkt („Zurücksetzung Mo., 21:59“), gehört er in `config.json` — sonst passt das Fenster nicht zum kalibrierten Wert: ```json { "weekResetWeekday": 1, "weekResetHour": 21, "weekResetMinute": 59 } ``` (0 = Sonntag, 1 = Montag …) Ohne diese Angabe rechnet das Dashboard mit einem rollierenden 7-Tage-Fenster und zeigt bewusst keinen Countdown, weil ein rollierendes Fenster keinen Reset-Zeitpunkt hat. ### Gewichtung Tokens zählen nicht gleich: Ausgabe wiegt stärker als ein Cache-Treffer, Opus stärker als Sonnet oder Haiku. Die Faktoren stehen in `config.json`. Weichen zwei Kalibrierungen mit **unterschiedlichem Modellmix** deutlich voneinander ab, stimmen diese Gewichte nicht — dann dort nachziehen, statt das Limit hin- und herzuschieben. Ein einzelner Kalibrierpunkt legt nur den Maßstab fest, nicht die Gewichte. ## Aufbau ``` src/main/index.js Fenster, Tray, IPC, Autostart src/main/collector.js Watch-Schleife, Zustandsaufbau src/main/jsonl.js inkrementeller Reader, Parser, Dedup src/main/blocks.js 5h-Blöcke, Wochenfenster, Burn-Rate src/main/limits.js Plan-Erkennung, Kalibrierung, Gewichtung src/main/oauth-usage.js Serverabfrage, gekapselt und ausfallsicher src/main/calibrate.js Kalibrierung gegen die echte Anzeige src/main/store.js state.json, config.json src/main/paths.js Speicherorte für Konfiguration und Zustand src/preload.js contextBridge fürs Widget src/settings-preload.js contextBridge für den Einstellungsdialog src/renderer/ Widget-Oberfläche src/settings/ Einstellungsdialog ``` Alle Dateizugriffe und Rechnungen passieren im Main-Prozess; der Renderer bekommt fertige Zahlen und lässt nur den Countdown lokal weiterlaufen. Zwei Details, die nicht offensichtlich sind: - **Datei-Offsets werden nicht persistiert.** Innerhalb einer Sitzung sorgen sie dafür, dass nur das Delta gelesen wird. Über einen Neustart hinweg wären sie schädlich, weil der Aggregator leer startet und die Historie sonst übersprungen würde. Ein Vollscan über 15 MB kostet rund 70 ms. - **Dedup ist nicht optional.** Claude Code schreibt dieselbe Nachricht bei Retries und beim Kompaktieren mehrfach ins Transkript; ohne Dedup über `message.id` wären alle Zahlen zu hoch. ## Release bauen ```powershell npm run dist # Installer + portable Fassung nach release/ npm run pack # nur entpackt nach release/win-unpacked (schneller Test) ``` Ergebnis in `release/`: | Datei | Zweck | |---|---| | `Claude Live Dashboard-1.0.0-x64.exe` | NSIS-Installer, ~97 MB | | `Claude Live Dashboard-1.0.0-portable.exe` | läuft ohne Installation | Der Installer läuft **ohne Administratorrechte** (`perMachine: false`), installiert also ins Benutzerprofil. Zielverzeichnis ist wählbar, Desktop- und Startmenü-Verknüpfung werden angelegt. Bei der Deinstallation bleiben Konfiguration und Kalibrierung erhalten (`deleteAppDataOnUninstall: false`). **Nicht signiert.** Ohne Code-Signing-Zertifikat zeigt Windows beim ersten Start einen SmartScreen-Hinweis („Der Computer wurde durch Windows geschützt“) — über *Weitere Informationen ▸ Trotzdem ausführen* zu bestätigen. Für eine Weitergabe an andere wäre ein Zertifikat nötig; für den Eigenbedarf ist es verzichtbar. ### Konfiguration und Zustand Beides liegt im Benutzerprofil, nicht im Programmverzeichnis — dort wäre es nach der Installation im asar-Archiv und schreibgeschützt: ``` %APPDATA%\Claude Live Dashboard\config.json %APPDATA%\Claude Live Dashboard\state.json ``` Beim ersten Start wird `config.json` aus der mitgelieferten Vorlage angelegt. Erreichbar über das Tray-Menü (*Konfiguration öffnen* / *Datenordner öffnen*). > Die mitgelieferte Vorlage enthält unter `limits` einen auf **diesem** System > kalibrierten Wert als Rückfallebene. Für eine Weitergabe an andere sollte er > entfernt werden — bei aktiver Serverabfrage wird er ohnehin nicht benutzt. ## Gegenprobe ```powershell npm run dump # Modell-Summen und alle 5h-Blöcke auf der Konsole npx ccusage blocks # unabhängige Referenz für Blockgrenzen und Summen ``` `npm run dump` gibt außerdem die Dauer des zweiten Polls aus — ohne neue Daten muss er 0 Bytes lesen und im einstelligen Millisekundenbereich liegen.