Files
ClaudeDo/docs/open.md

14 KiB
Raw Permalink Blame History

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 ConfirmDialog lohnt 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.Avalonia Package einbinden und auf MarkdownScrollViewer umstellen.
  • 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 diff Output in TextBox mit 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.NotifyCanExecuteChanged triggert nicht pro Item bei IsConnected-Wechsel (vom Slice-F-Agent dokumentiert).
  • Soll: Über WeakReferenceMessenger (CommunityToolkit.Mvvm) eine Connection-Change-Message verteilen, an die alle TaskItemViewModel lauschen.
  • Aufwand: klein, aber muss sauber gemacht werden.

2.7 Settings-Dialog

  • Datei: neuViews/SettingsDialog.axaml + VM
  • Aktuell: ~/.todo-app/ui.config.json muss 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 --version ausführen; bei Fehler app.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 WorktreeAddAsync zwischen CreateAsync-Schritten failt (z.B. Branch existiert schon), bleibt evtl. ein halbangelegter Worktree-Dir auf der Platte.
  • Soll: try/finally — bei Fehler git worktree remove --force als 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_exclusions ODER ein Prefix !tag im 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.Load per Paths.Expand gemacht — verifizieren, dass auch cfg.ClaudeBin ggf. in Service-PATH gefunden wird.

4.3 Install-Skripte / Doku

  • Datei: neudocs/install-service.md oder scripts/install-service.cmd
  • Inhalt: dotnet publish + sc.exe create + sc.exe failure + Hinweis auf obj= (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 restoredotnet build --no-restoredotnet test --no-build. Auf Push + PR.
  • Aufwand: klein.

5.2 Echter SignalR-Roundtrip-Test

  • Datei: neutests/ClaudeDo.Worker.Tests/Hub/WorkerHubTests.cs
  • Soll: mit WebApplicationFactory + HubConnectionBuilder testen, dass Ping, GetActive, RunNow-Throw-Verhalten korrekt sind. Plan-Verification 1b + 9.
  • Aufwand: mittel.

5.3 Smoke-Test gegen echten claude

  • Datei: neutests/ClaudeDo.Worker.Tests/Runner/ClaudeProcessSmokeTest.cs
  • Soll: Real-CLI-Test, der mit [Fact(Skip="..."] ausgegraut bleibt und nur lokal aktiviert wird, wenn CLAUDE_AUTHENTICATED=1 Env-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.md schon 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

  1. Verification Step 4 zusammen durchspielen → falls etwas grundlegend kaputt ist, jetzt finden, nicht später.
  2. CLI-Preflight (3.1) + Folder-Picker (2.1) + Delete-Confirm (2.2) — kleine, isolierte Wins.
  3. Auto-Scroll (2.4) + Active-Tasks Live-Update (2.6) — User-Experience im Detail-Pane.
  4. Markdown-Rendering (2.3) — größer, lohnt sich aber für Lesbarkeit.
  5. Worktree-Cleanup (3.2) — Robustheit, bevor wir Worktrees ernsthaft nutzen.
  6. CI-Pipeline (5.1) — automatisches Sicherheitsnetz für alles weitere.
  7. Service-Deployment (4) — wenn die App lokal stabil läuft.
  8. Settings-Dialog (2.7) + Diff-Viewer (2.5) — Polish.
  9. Tag-Negation (3.4) — wenn der Bedarf konkret wird.

Punkte 13 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.

  1. Install a baseline version (e.g. 0.2.x) normally.
  2. Publish a new release tagged v0.3.0 with fresh installer + app zip + checksums.
  3. Launch the app — confirm the banner appears: Update available: v0.2.x → v0.3.0.
  4. Click Update now — app closes, installer opens in Update mode, runs, restarts the worker.
  5. Re-launch the app — banner is gone; Help → Check for updates briefly shows "You're up to date (v0.3.0)".
  6. Run the v0.2.x installer 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.
  7. Repeat step 6 with Continue anyway → wizard opens without self-update.
  8. Repeat step 6 with Cancel → installer exits without any action.
  9. 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.

  1. Create a Manual task with a title and a TODO-ish description.
  2. Right-click the task → Open planning Session — Windows Terminal opens with Claude CLI running (Plan B).
  3. Ask Claude to create two child tasks via mcp__claudedo__create_child_task.
  4. Watch the UI: drafts appear indented under the parent, italic, reduced opacity, with a DRAFT badge.
  5. The parent shows a PLANNING badge. Click the chevron → children collapse; click again → children expand.
  6. Ask Claude to finalize — drafts flip to Manual/Queued children; parent flips to PLANNED badge.
  7. 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.
  8. 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.planned style (blue) is defined in IslandStyles.axaml but never applied — TaskRowView keeps the planning class for both Planning and Planned, so Planned gets the amber badge. Either make the view swap Classes.planned when status is Planned, or remove the unused style + brush.
  • Dead Instance statics on BoolToItalicConverter and BoolToDraftOpacityConverter — App.axaml registers instances via the resource dictionary; the static members can be removed.