File size: 11,157 Bytes
bbc65cd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 | # ClaudeCodePanel β Wie dein Panel funktioniert
## Die Kurzversion
Dein Panel ist wie ein **Cockpit fuer Claude Code**. Statt 15 Terminal-Fenster
und Config-Dateien zu jonglieren, hast du ein GTK3-Fenster mit 7 Tabs
und ein Tray-Icon das immer da ist. Denk an ein Auto-Armaturenbrett:
Tacho (Monitor), Bordcomputer (Hub), Fehlerlampen (Logs), Navigationsliste (Sessions).
**Stack:** Python 3.12 + PyGObject (GTK3) + Catppuccin Theming + systemd Service
---
## Architektur β 14 Module
### panel.py (2373 Zeilen) β Der Dirigent
Das Hauptfenster. Baut alle Tabs zusammen, startet die Timer, verwaltet das Tray-Icon.
Wie ein Dirigent: spielt selbst kein Instrument, aber koordiniert alle anderen.
**Key:** `ControlPanel` Klasse mit `_build_*_tab()` Methoden, `_refresh_hub()`, `_refresh_monitor()`.
### monitor.py (729 Zeilen) β Der Daten-Butler
Holt alle Zahlen: Kosten, Top-Tools, aktive Sessions, Timeline.
Hat einen TTL-Cache (30 Sekunden) β fragt nicht staendig die Festplatte.
**Key:** `get_daily_cost()`, `get_top_tools()`, `get_active_sessions()`. Nutzt MyAIGame's `tui.data.*` Module.
### log_viewer.py (435 Zeilen) β Der Protokollant
Zeigt heutige Usage-Eintraege und Coaching-Log. Filterbar nach Tools/Errors/Hooks.
**Key:** `build_logs_tab()`, `refresh_logs()`. Liest `~/.claude/usage/YYYY-MM-DD.jsonl`.
### session_browser.py (1039 Zeilen) β Das Telefonbuch
Alle Claude-Sessions durchsuchbar. Zeigt Projekt, Vorschau, Groesse. Resume-Button oeffnet kitty.
**Key:** `build_sessions_tab()`, `_scan_all_sessions()`, `_on_resume_clicked()`.
### process_manager.py (588 Zeilen) β Der Hausmeister
Scannt `ps aux` nach Claude-relevanten Prozessen. Zeigt RAM, CPU, Uptime.
Kill-Button pro Prozess + "Kill All Ghosts" fuer Prozesse >24h.
**Key:** `build_processes_tab()`, `_scan_processes()`, Ghost-Detection via `/proc/<pid>/stat`.
### theme.py (620 Zeilen) β Der Maler
Erkennt ob COSMIC Desktop dunkel oder hell ist, generiert passendes CSS.
Catppuccin Mocha (dark) / Latte (light). Wechselt live wenn du das System-Theme aenderst.
**Key:** `is_dark_mode()` liest `~/.config/cosmic/com.system76.CosmicTheme.Mode/v1/is_dark`.
`setup_theme_watcher()` nutzt `Gio.FileMonitor` fuer Live-Updates.
### config_io.py (168 Zeilen) β Der Tresorwaerter
Liest und schreibt `~/.claude/settings.json` **atomar** β nie direkt.
Immer: Backup β Temp-Datei β `os.replace()`. So geht nie was kaputt.
**Key:** `read_settings()`, `write_settings()`, `update_setting("key.path", value)`.
### swarm_tab.py (974 Zeilen) β Der Lageplaner
Zeigt die laufende Agent Team Pipeline in Echtzeit. Liest `~/.claude/teams/` und
`~/.claude/tasks/` und stellt ScoutβWeaverβBuilderβValidatorβPruefer als Karten dar.
**Key:** `build_swarm_tab()`, `_scan_teams()`, `_refresh_swarm()`.
### swarm_visual.py (708 Zeilen) β Der Kartograf
Generiert HTML-Seiten mit interaktiven Agent-Kommunikationsgraphen: Hub-and-Spoke-Layout,
Bezier-Kurven, Partikel-Animationen. Wird von swarm_tab.py aufgerufen und in WebKit2 eingebettet.
**Key:** `generate_swarm_html()`, Bezier + Partikel-Rendering via Canvas.
### event_tab.py (426 Zeilen) β Der Horcher
Live-Viewer fuer Hook-Events aus `~/.claude/events/YYYY-MM-DD.jsonl`. Filterbar
nach Event-Typ, Auto-Scroll wenn neue Events reinkommen.
**Key:** `build_events_tab()`, `_tail_events()`, Filter-Logik nach Typ/Quelle.
### shortcut_counter_tab.py (450 Zeilen) β Der Strichlisten-Fuehrer
Zeigt Keyboard-Shortcut-Statistiken aus der ShortcutCounter-Datenbank. Wie oft hast
du Ctrl+C vs. Ctrl+Z genutzt? Welcher Shortcut spart am meisten Zeit?
**Key:** `build_shortcut_tab()`, liest ShortcutCounter SQLite DB.
### project_dashboard_tab.py (254 Zeilen) β Das Fenster
Bettet das Project Dashboard als WebKit2-Webview direkt ins Panel ein, statt
einen Browser oeffnen zu muessen. Ein Tab = ein komplettes Web-Dashboard.
**Key:** `build_project_dashboard_tab()`, `WebKit2.WebView` Setup + Reload-Button.
### utils.py (33 Zeilen) β Der Werkzeugkasten
Kleine Hilfsfunktionen die ueberall gebraucht werden (Format-Helpers, Pfad-Utilities).
Klein aber da wenn man ihn braucht.
**Key:** Shared Utilities fuer alle anderen Module.
### tools-gui/ (623 Zeilen) β Das Zweite Cockpit
Separates GTK3-Fenster mit 3 eigenen Tabs: Kosten-Analyse, Session-Uebersicht, Tool-Statistiken.
Laeuft als eigenstaendiges Fenster neben dem Hauptpanel (main.py + 3 Tab-Module).
**Key:** `tools-gui/main.py` als Einstiegspunkt, 3 Tab-Module fuer costs/sessions/tools.
---
## Wie die Tabs zusammenhaengen
```
panel.py (Dirigent)
βββ importiert monitor.py β liefert Daten fuer Hub + Monitor Tab
βββ importiert log_viewer.py β baut Logs Tab
βββ importiert session_browser.py β baut Sessions Tab
βββ importiert process_manager.py β baut Prozesse Tab
βββ importiert swarm_tab.py β baut Agent Swarm Tab
βββ importiert swarm_visual.py β generiert Swarm-Graphen (HTML)
βββ importiert event_tab.py β baut Events Tab
βββ importiert shortcut_counter_tab.py β baut Shortcut Counter Tab
βββ importiert project_dashboard_tab.py β baut Project Dashboard Tab (WebKit2)
βββ importiert theme.py β CSS + Theme Watcher
βββ importiert config_io.py β Settings + Hooks Tabs lesen/schreiben Config
```
Jedes Modul ist **eigenstaendig** β kann theoretisch allein funktionieren.
panel.py ist nur der Rahmen der sie zusammenbringt.
---
## Timer-System β Das Herzschlag-System
Dein Panel hat 6 Timer die wie Herzschlaege funktionieren. Jeder Timer
ruft periodisch eine Funktion auf die Daten aktualisiert:
| Timer | Intervall | Funktion | Was wird aktualisiert? |
|-------|-----------|----------|----------------------|
| Hub | 30s | `_refresh_hub()` | Kosten, Top-Tools, Sessions |
| Monitor-Start | 15s | `_start_monitor_timer()` | Startet Monitor-Timer |
| Logs | 10s | `refresh_logs()` | Usage + Coaching Eintraege |
| Sessions | 60s | `refresh_sessions()` | Session-Liste |
| Prozesse | 30s | `refresh_processes()` | Prozess-Scan |
| Monitor | 30s | `_refresh_monitor()` | Timeline, Skills |
**Warum gestaffelt?** Damit nicht alle gleichzeitig feuern und die UI einfriert.
Logs sind am schnellsten (10s) weil Usage-Daten sich oft aendern.
Sessions am langsamsten (60s) weil sich Sessions selten aendern.
**Was wenn ein Timer haengt?** Jeder Timer returned `True` um am Leben zu bleiben.
Wenn einer Exception wirft, faengt `try/except` es ab und der Timer laeuft weiter.
Worst case: ein Tab zeigt veraltete Daten, aber das Panel stuerzt nicht ab.
---
## Daten-Flow
```
~/.claude/usage/YYYY-MM-DD.jsonl βββ monitor.py (Cache 30s) βββ Hub Tab (Kosten, Tools)
ββββ log_viewer.py βββ Logs Tab (Eintraege)
~/.claude/projects/*/ βββββββββββββ monitor.py + session_browser βββ Sessions Tab
ps aux βββββββββββββββββββββββββββββ process_manager.py βββ Prozesse Tab
~/.claude/settings.json βββββββββββ config_io.py βββ Settings + Hooks Tab
```
---
## Theme-System
1. **Detection:** Liest `~/.config/cosmic/com.system76.CosmicTheme.Mode/v1/is_dark`
- `true` β Catppuccin Mocha (dunkle Palette)
- `false` β Catppuccin Latte (helle Palette)
- Datei fehlt β Fallback auf GTK `gtk-application-prefer-dark-theme`
2. **CSS:** `build_css(palette)` generiert ~150 Zeilen CSS aus der Palette
3. **Live-Switch:** `Gio.FileMonitor` beobachtet die COSMIC Config-Datei.
Aendert sich das System-Theme, wird `apply_theme()` via `GLib.idle_add` aufgerufen.
---
## Config-System β Atomare Writes
Warum nicht einfach `json.dump(data, open(file, "w"))`?
Weil: wenn der Prozess mittendrin stirbt, hast du eine kaputte halbe Datei.
**Stattdessen (config_io.py):**
1. **Backup:** `settings.json` β `settings.json.backup-20260302-143000`
2. **Temp:** Schreibe in `settings-XXXX.tmp` (gleicher Ordner)
3. **Rename:** `os.replace(tmp, settings.json)` β atomar auf Linux!
Entweder hast du die alte ODER die neue Datei. Nie eine kaputte.
---
## Sprint 2026-03-04 Learnings
### Das Wichtigste zuerst: Deine vorherige Arbeit war solide.
4 von 5 Warnings waren **bereits gefixt** bevor der Sprint anfing (Commit `67a4362`).
Du hast einen 5-Agenten-Sprint geplant fuer... einen einzigen verbleibenden Fix (subprocess.run β Popen).
Das Panel ist zu **95%+ fertig**. Was wirklich noch offen ist: 4 Suggestions (nice-to-have), kein Critical.
### Muster: Erst schauen, dann planen.
Tendency erkannt: Samuel plant gross (5 Agents, detaillierter PLAN-File) **bevor** er den aktuellen Stand prueft.
Regel fuer dich: **`/check-state` vor jedem Sprint-Start.** Eine Minute Status-Check spart eine Stunde Overhead.
Konkret: Bevor du Tasks erstellst, kurz pruefen:
- Welche Punkte der Checkliste sind schon erledigt? (PLAN-File lesen)
- Laeuft der Service gerade fehlerfrei? (`systemctl --user status claude-panel.service`)
- Wie gross ist der echte Rueckstand? (1 Fix β 5-Agenten-Aufwand)
### Was gut lief (verstaerken!)
- **Dokumentations-Disziplin:** PLAN-File erstellt, Review-Findings dokumentiert, Entscheidungen festgehalten. Das ist wertvoll.
- **Commit-Hygiene:** Criticals sofort gefixt und committed. Kein "ich mach das spaeter".
- **Code-Review Workflow:** Sonnet Review + MiniMax Zweitmeinung. Zwei Perspektiven fangen mehr.
- **Architektur-Entscheidungen klar begruendet:** `**/*.jsonl` fuer rekursive Suche, `"anthropic"` Key-Aggregation, Fingerprint-Mechanismus β alles dokumentiert.
### Was noch aussteht (die echte Restliste)
Nur Suggestions, kein muss:
1. `monitor.py:~662` β `sorted()` mit stat()-Lambda vereinfachen
2. `log_viewer.py:~456` β unbenutzten `sort_model` Parameter entfernen
3. `panel.py:~812` β `_DETECTOR_LAYOUT` Naming-Konvention
4. `log_viewer.py` β Status-Farben aus Theme-Palette statt hardcoded
Das Panel laeuft. Diese Fixes machen es sauberer, nicht funktionsfaehiger.
---
## Bekannte Gotchas
1. **CPU Spin-Loop (GEFIXT):** `GLib.idle_add(refresh_logs)` mit `return True` =
Endlosschleife. Fix: One-Shot Wrapper mit `return False`. Regel: `idle_add`
Callbacks muessen IMMER `False` returnen.
2. **Ghost-Prozesse:** MCP-Server (opencode-mcp, gemini-mcp) werden pro Session
gestartet aber nie beendet. Der Prozesse-Tab zeigt sie als "Ghosts" (>24h).
3. **MyAIGame Dependency:** `monitor.py` importiert `tui.data.usage_reader` aus
`~/Projekte/MyAIGame/`. Wenn das Projekt nicht existiert, fallen Kosten-
und Tool-Statistiken auf Null zurueck (graceful fallback, kein Crash).
4. **COSMIC-only Theme Detection:** Auf nicht-COSMIC-Desktops funktioniert nur
der GTK-Fallback. Die Catppuccin-Farben bleiben, aber Live-Switching nur per GTK.
5. **Singleton Lock (GEFIXT):** Frueher konnten mehrere Panel-Instanzen gleichzeitig
laufen (systemd restart + manueller Start). Fix: `fcntl.flock` auf `/tmp/claude-panel.lock`.
Zweite Instanz erkennt Lock und beendet sich mit `sys.exit(0)`.
|