14 KiB
ClaudeDo — Offene Punkte
Stand: 2026-04-13 nach Slice F. Branch main @ 48e4aab. Alle Tests grün (38/38), Build 0 Warnings.
Dieses Dokument listet alles, was noch fehlt — gruppiert nach Aufwand/Risiko und mit konkreten Datei-Pointern, damit wir es in der IDE der Reihe nach durchgehen können.
1. Verification (vor allem anderen)
Die in plan.md definierten Verification-Steps sind teilweise nur durch Build/Tests abgedeckt. Diese sollten manuell einmal durchlaufen werden, BEVOR wir Polish bauen — damit wir wissen, was tatsächlich kaputt ist.
| # | Plan | Status | Was tun |
|---|---|---|---|
| 1 | Schema-Init | Auto verifiziert (Worker startet ohne Crash, WAL-Files entstehen) | OK |
| 1a | SignalR-Endpoint | Manuell verifiziert (HTTP 400 auf /hub ohne Handshake) |
OK |
| 1b | Hub-Roundtrip Ping |
Nicht getestet | Test-Client schreiben oder UI starten und im Log nach "pong" schauen |
| 2 | claude --version Preflight |
Nicht implementiert | Worker/Program.cs: vor app.Run() einmal claude --version shellen und bei Exit≠0 abbrechen |
| 3 | Smoke-Spawn (claude -p mit Prompt "ping") |
Nicht getestet | Integrationstest schreiben oder einmal manuell laufen lassen |
| 4 | E2E Happy Path (Non-Worktree) | Nicht getestet | UI starten → Liste "Test" anlegen → Task mit Tag agent + Status queued + Description "Schreibe ein Haiku über Intralogistik" → Run abwarten → Result prüfen |
| 5 | Worktree Happy Path | Nicht getestet | Manueller Test mit echtem Repo (z.B. einem temp-Repo) |
| 6 | No-Changes-Run | Nicht getestet | Prompt der nichts ändert → head_commit bleibt NULL |
| 7 | Kein Git-Repo | Nicht getestet | working_dir auf C:\Temp → Task failed, keine worktrees-Row |
| 8 | Merge-UI | Nicht getestet (UI ruft GitService.MergeFfOnlyAsync, aber nie ausgeführt) |
Manuell |
| 9 | Override-Parallelität | Tests vorhanden für Slot-Logik, End-to-End nicht | UI: zwei Tasks queuen, Run Now auf der zweiten → beide laufen parallel |
| 10 | Schedule | Logik per Test abgedeckt, End-to-End nicht | Task mit scheduled_for = now+2min |
| 11 | Worker-Offline-Erkennung | UI hat Status-Bar, aber nicht visuell verifiziert | Worker killen, schauen ob Status auf "offline" wechselt |
| 12 | Live-Stream | Nicht getestet | Während Run TaskDetail öffnen, beobachten ob ndjson-Zeilen erscheinen |
| 13 | Wake-up (UI ruft WakeQueue nach Anlage) |
Implementiert in TaskListViewModel, nicht visuell verifiziert |
Tasks nach Anlage in <1s gepickert |
Vorschlag: Wir machen einmal Step 4 (Haiku-Happy-Path) gemeinsam — wenn das läuft, ist die ganze Pipeline lebendig.
2. UI-Polish (kritisch für Benutzbarkeit)
Im aktuellen Stand kompiliert die UI, aber mehrere Stellen sind als // TODO markiert. Reihenfolge nach Schmerz:
2.1 Folder-Picker für Working Directory
- Datei:
src/ClaudeDo.Ui/Views/ListEditorView.axaml+src/ClaudeDo.Ui/ViewModels/ListEditorViewModel.cs - Aktuell: plain
TextBox— Pfad muss getippt werden. - Soll: Button "…" daneben → öffnet
IStorageProvider.OpenFolderPickerAsync, schreibt Pfad ins Feld. - Aufwand: klein, ~30 Zeilen.
2.2 Delete-Confirmation
- Dateien:
MainWindowViewModel.DeleteList,TaskListViewModel.DeleteTask - Aktuell: löscht direkt ohne Rückfrage. Datenverlust-Risiko.
- Soll: Mini-Dialog "Wirklich löschen?" mit Ja/Nein.
- Aufwand: klein, generisches
ConfirmDialoglohnt sich (1× bauen, mehrfach nutzen).
2.3 Markdown-Rendering für Result + Description
- Datei:
src/ClaudeDo.Ui/Views/TaskDetailView.axaml - Aktuell:
TextBox IsReadOnly="True"mit Plaintext. - Soll:
Markdown.AvaloniaPackage einbinden und aufMarkdownScrollViewerumstellen. - Aufwand: mittel — Package + ein paar XAML-Anpassungen. Theme-Integration kann nerven.
2.4 Live-Log Auto-Scroll
- Datei:
src/ClaudeDo.Ui/Views/TaskDetailView.axaml.cs(oder im VM) - Aktuell: ndjson-Zeilen werden angehängt, aber Scrollposition bleibt stehen.
- Soll: Bei jeder neuen Zeile
ScrollViewer.ScrollToEnd()solange User nicht manuell hochgescrollt hat (Sticky-Bottom-Pattern). - Aufwand: klein, ein attached behavior reicht.
2.5 Diff-Viewer
- Datei:
TaskDetailViewModel.ShowDiffAsync - Aktuell:
Process.Start("cmd", "/k git diff …")— separates Konsolenfenster, hässlich. - Soll: entweder unified-diff inline anzeigen (
git diffOutput inTextBoxmit Mono-Font + Color für +/-) oder einen externen Diff-Tool-Hook (git difftool). - Aufwand: mittel. MVP: einfach nur den Diff-Output in einem Modal.
2.6 Status-Bar Active-Tasks Live-Update
- Datei:
StatusBarViewModel - Risiko: das Slot-State-Update kommt vom WorkerClient, aber
RunNowCommand.NotifyCanExecuteChangedtriggert nicht pro Item beiIsConnected-Wechsel (vom Slice-F-Agent dokumentiert). - Soll: Über
WeakReferenceMessenger(CommunityToolkit.Mvvm) eine Connection-Change-Message verteilen, an die alleTaskItemViewModellauschen. - Aufwand: klein, aber muss sauber gemacht werden.
2.7 Settings-Dialog
- Datei: neu —
Views/SettingsDialog.axaml+ VM - Aktuell:
~/.todo-app/ui.config.jsonmuss von Hand editiert werden. - Soll: Dialog mit Feldern: DB-Pfad, SignalR-Port, Default-Tags. Persistiert zurück in JSON.
- Aufwand: mittel. Achtung: Port-Wechsel braucht Worker-Restart.
3. Worker-Robustheit
3.1 CLI-Preflight beim Worker-Start
- Datei:
src/ClaudeDo.Worker/Program.cs - Soll: vor
app.Run()claude --versionausführen; bei Fehlerapp.Logger.LogCritical+Environment.Exit(1). - Aufwand: klein, ~20 Zeilen. Liefert Verification Step 2.
3.2 Worktree-Cleanup beim Anlege-Failed
- Datei:
src/ClaudeDo.Worker/Runner/WorktreeManager.cs - Aktuell: Wenn
WorktreeAddAsynczwischenCreateAsync-Schritten failt (z.B. Branch existiert schon), bleibt evtl. ein halbangelegter Worktree-Dir auf der Platte. - Soll: try/finally — bei Fehler
git worktree remove --forceals Best-Effort-Cleanup. - Aufwand: klein.
3.3 Logging über Microsoft.Extensions.Logging strukturieren
- Datei: alle Worker-Komponenten
- Aktuell: ILogger wird benutzt, aber kein File-Sink konfiguriert.
- Soll: Optional Serilog oder einfach
AddFile(Karambolage.Extensions.Logging.File) — Service-Modus braucht persistente Logs außerhalb der Console. - Aufwand: klein.
3.4 Tag-Negation / Exclusion (Plan-TODO)
- Plan-Sektion: "Tag-Modell"
- Aktuell: Tags sind rein additiv (
list_tags ∪ task_tags). - Soll: Mechanismus, um auf Task-Ebene einen List-Tag auszuschließen. Z.B. neue Tabelle
task_tag_exclusionsODER ein Prefix!tagim task_tags-Eintrag. - Aufwand: mittel — Schema + Repo + Tests + UI.
4. Service-Deployment (Plan-Sektion „Worker als Windows-Service")
4.1 Windows-Service-Hosting in Code
- Datei:
src/ClaudeDo.Worker/Program.cs - Pakete:
Microsoft.Extensions.Hosting.WindowsServices - Soll:
builder.Host.UseWindowsService(o => o.ServiceName = "ClaudeDoWorker"); builder.Logging.AddEventLog(...); - Aufwand: klein.
4.2 Pfad-Auflösung absolut machen
- Bereits in
WorkerConfig.LoadperPaths.Expandgemacht — verifizieren, dass auchcfg.ClaudeBinggf. in Service-PATH gefunden wird.
4.3 Install-Skripte / Doku
- Datei: neu —
docs/install-service.mdoderscripts/install-service.cmd - Inhalt:
dotnet publish+sc.exe create+sc.exe failure+ Hinweis aufobj=(User-Account) wegen Claude-CLI-Session. - Aufwand: klein.
4.4 (später) Installer-Projekt
- WiX/MSIX, registriert Service + UI-Shortcut. Plan-Sektion „Offene Punkte".
5. Tests / CI
5.1 GitHub-Actions / Gitea-Actions Pipeline
- Datei: neu —
.gitea/workflows/ci.yml(oder.github/workflows/ci.yml) - Inhalt:
dotnet restore→dotnet build --no-restore→dotnet test --no-build. Auf Push + PR. - Aufwand: klein.
5.2 Echter SignalR-Roundtrip-Test
- Datei: neu —
tests/ClaudeDo.Worker.Tests/Hub/WorkerHubTests.cs - Soll: mit
WebApplicationFactory+HubConnectionBuildertesten, dassPing,GetActive,RunNow-Throw-Verhalten korrekt sind. Plan-Verification 1b + 9. - Aufwand: mittel.
5.3 Smoke-Test gegen echten claude
- Datei: neu —
tests/ClaudeDo.Worker.Tests/Runner/ClaudeProcessSmokeTest.cs - Soll: Real-CLI-Test, der mit
[Fact(Skip="..."]ausgegraut bleibt und nur lokal aktiviert wird, wennCLAUDE_AUTHENTICATED=1Env-Var gesetzt ist. - Aufwand: klein.
6. Dokumentation
6.1 README.md
- Komplett fehlt. Mind. 1× kurz: was ist es, wie starten (Worker + UI), wo Config.
- Aufwand: klein.
6.2 docs/architecture.md
- In
plan.mdschon teilweise enthalten — kann entweder konsolidiert oder explizit ausgegliedert werden.
6.3 ADRs für die getroffenen Entscheidungen
- Z.B. „SignalR vs. SQLite-Polling für IPC", „Worktree pro Task", „SignalR über Loopback ohne Auth".
- Aufwand: klein, hilfreich für später.
7. Bekannte Code-Schulden / Smells
| Stelle | Issue |
|---|---|
WorkerHub.GetActive returnt IReadOnlyList<object> mit anonymen Typen |
Sollte ein expliziter DTO sein (ActiveTaskDto), den Worker UND Ui teilen. Aktuell duplizieren beide das Schema. |
TaskRunner führt eine if (list.WorkingDir != null) Verzweigung mitten in der Methode |
Strategy-Pattern (IRunStrategy: SandboxStrategy, WorktreeStrategy) wenn die Methode wächst. Aktuell noch klein genug. |
App.Services als public static ServiceProvider |
Service-Locator-Antipattern. Toleriert, weil nur in App.OnFrameworkInitializationCompleted verwendet. Falls mehr Code drauf zugreift → echtes DI durchziehen. |
Embedded schema.sql ohne Versionierung |
Solange das Schema nicht in Production läuft, OK. Sobald User-Daten existieren → migrations/ Folder + Version-Tabelle. |
| CRLF-Warnings beim Commit | .gitattributes mit * text=auto eol=lf (oder explizit pro Sprache) wäre sauberer. |
Empfohlene Reihenfolge für die nächste Session
- Verification Step 4 zusammen durchspielen → falls etwas grundlegend kaputt ist, jetzt finden, nicht später.
- CLI-Preflight (3.1) + Folder-Picker (2.1) + Delete-Confirm (2.2) — kleine, isolierte Wins.
- Auto-Scroll (2.4) + Active-Tasks Live-Update (2.6) — User-Experience im Detail-Pane.
- Markdown-Rendering (2.3) — größer, lohnt sich aber für Lesbarkeit.
- Worktree-Cleanup (3.2) — Robustheit, bevor wir Worktrees ernsthaft nutzen.
- CI-Pipeline (5.1) — automatisches Sicherheitsnetz für alles weitere.
- Service-Deployment (4) — wenn die App lokal stabil läuft.
- Settings-Dialog (2.7) + Diff-Viewer (2.5) — Polish.
- Tag-Negation (3.4) — wenn der Bedarf konkret wird.
Punkte 1–3 sind ein realistischer Block für eine Session.
Self-Update — Manual Verification
Preconditions: a working Gitea release at git.kuns.dev/releases/ClaudeDo with three assets — ClaudeDo-<version>-win-x64.zip, ClaudeDo.Installer-<version>.exe, and checksums.txt listing both.
- Install a baseline version (e.g.
0.2.x) normally. - Publish a new release tagged
v0.3.0with fresh installer + app zip + checksums. - Launch the app — confirm the banner appears:
Update available: v0.2.x → v0.3.0. - Click Update now — app closes, installer opens in Update mode, runs, restarts the worker.
- Re-launch the app — banner is gone;
Help → Check for updatesbriefly shows "You're up to date (v0.3.0)". - Run the
v0.2.xinstaller manually — confirm it prompts to self-update to v0.3.0. Click Update → running exe is replaced and the wizard opens on the new version. - Repeat step 6 with Continue anyway → wizard opens without self-update.
- Repeat step 6 with Cancel → installer exits without any action.
- Kill network during startup in both app and installer → confirm silent fallback (no errors, no banner, wizard opens normally).
Planning Sessions — Manual Verification (Plan C UI)
Requires Plan B (worker hub endpoints) merged. Until then, only the UI structure/styling checks are meaningful.
- Create a Manual task with a title and a TODO-ish description.
- Right-click the task → Open planning Session — Windows Terminal opens with Claude CLI running (Plan B).
- Ask Claude to create two child tasks via
mcp__claudedo__create_child_task. - Watch the UI: drafts appear indented under the parent, italic, reduced opacity, with a
DRAFTbadge. - The parent shows a
PLANNINGbadge. Click the chevron → children collapse; click again → children expand. - Ask Claude to
finalize— drafts flip to Manual/Queued children; parent flips toPLANNEDbadge. - In a new planning task, close the terminal without finalize. Right-click the Planning task → the unfinished-session modal opens with Resume / Finalize now / Discard.
- Attempt to delete a parent with children via the details panel — confirm the friendly error dialog appears and the task is NOT deleted.
Known followups (non-blocking):
Border.badge.plannedstyle (blue) is defined inIslandStyles.axamlbut never applied —TaskRowViewkeeps theplanningclass for both Planning and Planned, so Planned gets the amber badge. Either make the view swapClasses.plannedwhen status is Planned, or remove the unused style + brush.- Dead
Instancestatics onBoolToItalicConverterandBoolToDraftOpacityConverter— App.axaml registers instances via the resource dictionary; the static members can be removed.