refactor(worker): remove MessageParser (replaced by StreamAnalyzer)

This commit is contained in:
Mika Kuns
2026-04-14 14:12:21 +02:00
parent 03728c8e4a
commit c1c4c75979
26 changed files with 3978 additions and 88 deletions

92
docs/improvement-plan.md Normal file
View File

@@ -0,0 +1,92 @@
# ClaudeDo — Improvement Plan (Session 2026-04-13)
Erfasst während manuellem Walkthrough der App. Priorisiert nach Schmerz/Aufwand.
---
## P1 — UX-Blocker (sollten zuerst)
### IP-1: UI ↔ Worker Auto-Reconnect
**Symptom:** Wenn UI vor Worker startet, bleibt die Verbindung tot. Manueller UI-Restart nötig.
**Soll:** SignalR-Client mit `WithAutomaticReconnect()` + Reconnect-Versuche im Hintergrund (exponential backoff). Status-Bar zeigt "verbinde…" während Retry.
**Dateien:** `src/ClaudeDo.Ui/Services/WorkerClient.cs` (oder wo `HubConnection` gebaut wird)
**Aufwand:** klein (~30 Zeilen, primär `HubConnectionBuilder`-Konfig + Reconnect-Handler)
**Risiko:** klein
### IP-2: Listen-Modus „Notes" (non-autonomous)
**Symptom:** Jede Liste ist Agent-gesteuert. Keine reine Notiz-Liste möglich.
**Soll:** Neues Feld `lists.kind` (`agent` | `notes`).
- `agent`: aktuelles Verhalten (Worker pickt Tasks)
- `notes`: Worker ignoriert die Liste komplett, UI versteckt Run-/Schedule-/Worktree-Felder, Tasks haben nur Title + Description + done-Checkbox.
**Dateien:**
- Schema: neue Spalte + Migration (siehe IP-9)
- `Data/Entities/TaskList.cs`, `Repositories/ListRepository.cs`
- `Worker/Queue/QueueService.cs` (Filter `WHERE list.kind = 'agent'`)
- UI: `ListEditorView` (Radio/ComboBox), `TaskListView` (conditional Columns), `TaskDetailView` (verstecken)
**Aufwand:** mittel (~Schema + Repo + UI an mehreren Stellen)
**Risiko:** mittel — bestehende Listen müssen Default `agent` bekommen
### IP-3: Doppelklick öffnet Edit-Dialog
**Symptom:** Edit nur über separaten Button/Menüpunkt.
**Soll:** `DoubleTapped`-Handler auf ListBox-Items (Listen-Pane) und auf TaskRows (Task-Pane) → öffnet jeweiligen Editor.
**Dateien:** `Views/MainWindow.axaml(.cs)`, `Views/TaskListView.axaml(.cs)`
**Aufwand:** klein (~1015 Zeilen pro Stelle)
**Risiko:** klein
### IP-4: Tag-Multi-Select statt Freitext
**Symptom:** Tags müssen getippt werden, keine Auto-Vervollständigung, Typos möglich.
**Soll:** Multi-Select-Control:
- Zeigt alle in DB existierenden Tags (DISTINCT aus `lists.tags` `tasks.tags`)
- Erlaubt Anlegen neuer Tags (Free-Text-Add)
- Chip/Token-Darstellung der ausgewählten Tags
**Dateien:**
- *neu* `Views/Controls/TagPicker.axaml` (wiederverwendbar)
- `ListEditorView`, `TaskEditorView` einbinden
- Repo-Methode `GetAllKnownTagsAsync()`
**Aufwand:** mittel (Custom-Control lohnt sich, da 2× verwendet)
**Risiko:** klein
### IP-5: Rechtsklick-Kontextmenü
**Symptom:** Quick-Actions nur über Buttons im Detail-Pane oder Toolbar.
**Soll:**
- **Liste:** Edit, Delete, New Task, ggf. „Mark all done" (für Notes-Listen aus IP-2)
- **Task:** Edit, Delete, Run Now, Show Diff, Merge, Cancel (je nach Status)
- Items kontext-sensitiv enabled/disabled je nach Task-Status & List-Kind
**Dateien:** `Views/MainWindow.axaml` (List-Pane), `Views/TaskListView.axaml` (Task-Pane)
**Aufwand:** kleinmittel — Avalonia `ContextMenu` + Command-Bindings
**Risiko:** klein
---
## P2 — Folge-Arbeiten (durch P1 ausgelöst)
### IP-6: Schema-Migration-Mechanismus
**Trigger:** IP-2 fügt eine Spalte zu `lists` hinzu. Aktuell `schema.sql` ist Drop-and-Create-Style.
**Soll:** Mini-Migrations-System: `migrations/0001_initial.sql`, `0002_lists_kind.sql`, … + `_schema_version` Tabelle.
**Aufwand:** kleinmittel
**Querverweis:** `open.md` Sektion 7 (Schulden-Tabelle: „Embedded schema.sql ohne Versionierung")
### IP-7: Status-Bar zeigt Reconnect-State
**Trigger:** IP-1 — User soll sehen, dass Verbindung gerade aufgebaut wird (statt nur „offline").
**Soll:** States: `connected` | `connecting` | `reconnecting` | `offline`. Farb-codiert.
**Datei:** `ViewModels/StatusBarViewModel.cs`
**Aufwand:** klein
### IP-8: Tag-Repository für `GetAllKnownTagsAsync`
**Trigger:** IP-4 braucht eine Quelle aller bekannten Tags.
**Soll:** Methode in `ListRepository`/`TaskRepository` ODER neuer `TagRepository`. SQL: `SELECT DISTINCT trim(value) FROM lists, json_each(lists.tags) UNION ...`.
**Aufwand:** klein
---
## Empfohlene Reihenfolge
1. **IP-1** (Auto-Reconnect) — sofortiger UX-Win, isoliert, klein
2. **IP-3** (Doppelklick) — trivial, sofort spürbar
3. **IP-5** (Kontextmenü) — kompakt, hebt Bedienkomfort deutlich
4. **IP-6** (Migrations) — Voraussetzung für IP-2
5. **IP-2** (Notes-Mode) — größerer Brocken, braucht Schema-Migration
6. **IP-8 → IP-4** (Tag-Repo, dann Multi-Select-Control)
7. **IP-7** (Reconnect-Status in StatusBar) — Polish nach IP-1
Block 1 (IP-1, IP-3, IP-5) ist ein realistischer Session-Block.