# 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:** *neu* — `Views/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:**
  ```csharp
  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:** *neu* — `docs/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 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` + `HubConnectionBuilder` testen, dass `Ping`, `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, 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 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.

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` — children move to `Queued` (first) and `Queued + BlockedBy` (rest); parent's `PlanningPhase` flips from `Active` to `Finalized` (`PLANNED` badge). The first child must reach `Running` automatically — no manual `WakeQueue` needed (regression-tested in `PlanningEndToEndTests`).
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 `PlanningPhase=Active` and `Finalized`, so a finalized parent gets the amber badge. Either make the view swap `Classes.planned` when `PlanningPhase` is `Finalized`, 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.
- `Ui.Tests` `IWorkerClient` fakes (`DetailsIslandPlanningTests`, `PlanningDiffViewModelTests`, `ConflictResolutionViewModelTests`) miss `OpenInteractiveTerminalAsync` and `QueuePlanningSubtasksAsync` — pre-existing constructor-drift; rebase fakes onto a shared abstract base.
