Replace Windows-service/scheduled-task deployment docs with the Startup-folder shortcut mechanism and the App's connection-failure prompt. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
20 KiB
ClaudeDo — Offene Punkte
Stand: 2026-04-30. Neu erstellt nach Code-Audit gegen plan.md, improvement-plan.md und mailbox-proposal.md.
Die alte Version dieses Dokuments war auf 2026-04-13 ("nach Slice F") datiert und ignorierte die seither gelandeten Slices (Planning Sessions, Prime Claude, Self-Update, Externe MCP-Tools, editierbare Status/Tags, BlockedBy-Chains). Diese Version trennt sauber zwischen erledigt, teilweise, offen — und listet das, was inzwischen gebaut wurde, explizit als „shipped" auf, damit es nicht verloren geht.
Legende: ✅ DONE — 🟡 PARTIAL — ⬜ OPEN — ⛔ DROPPED
0. Was seit dem 2026-04-13 dazugekommen ist
Diese Slices gab es im alten Dokument noch nicht (oder nur als Platzhalter). Sie sind fertig im Code, brauchen aber jeweils noch ein paar Polish-Punkte (siehe Sektion 2/3).
| Slice | Worker-Anker | UI-Anker | Status |
|---|---|---|---|
| Planning Sessions (Plan B+C) | Planning/PlanningSessionManager, PlanningChainCoordinator, PlanningMcpService |
Views/Planning/PlanningDiffView, ConflictResolutionView, UnfinishedPlanningModalView |
✅ Code, manuelle Verifikation siehe §1.1 |
| Prime Claude (geplante Recurrence) | Prime/PrimeScheduler, NextDueCalculator, PrimeRunner |
ViewModels/Modals/PrimeClaudeTabViewModel, Views/Controls/ThemedDatePicker |
✅ Code, manuelle Verifikation siehe §1.2 |
| Self-Update System (Gitea Releases) | — | ClaudeDo.Releases (ReleaseClient, SelfUpdater, ChecksumVerifier, VersionComparer), ClaudeDo.Installer (Pages/Steps/Core) |
✅ Code, manuelle Verifikation siehe §1.3 |
| Externes MCP-Endpoint (11 Tools für Drittsessions) | External/ExternalMcpService (ListTaskLists, ListTasks, GetTask, AddTask, UpdateTask, UpdateTaskStatus, SetTaskTags, ListTags, DeleteTask, RunTaskNow, CancelTask), ExternalMcpAuthMiddleware (X-ClaudeDo-Key) |
— | ✅ Code, ohne Tests am Endpoint selbst |
Editierbare Status & Tags (entkoppelt vom agent-Tag) |
WorkerHub.SetTaskStatus, SetTaskTags, UpdateTaskAgentSettings; Queue-Picker filtert nicht mehr nach agent-Tag |
DetailsIslandViewModel, Status-/Tag-Kontextmenü in TasksIslandView |
✅ Code |
| BlockedBy-Chains (sequenzielle Subtask-Ausführung) | TaskStateService.BlockOn/UnblockAsync, QueuePicker filter BlockedByTaskId IS NULL, PlanningChainCoordinator.OnChildFinishedAsync |
Drittes Feld neben Status und PlanningPhase |
✅ Code, Migration 20260423154708_AddPlanningSupport |
| Worker-State-Konsolidierung | TaskStateService ist alleiniger Owner von Status/PlanningPhase/BlockedByTaskId-Writes; OverrideSlotService ausgelagert; QueueWaker + QueuePicker getrennt |
— | ✅ Code |
| MarkdownView / Tabbed Settings / About-Modal / Prime-Status-Footer / Doppelklick-Edit | — | Views/MarkdownView, SettingsModalView als TabControl, AboutModalView, transient Prime-Status in Footer, DoubleTapped an List/Task-Rows |
✅ Code |
1. Verification (vor allem anderen)
Der Großteil der Verification-Steps aus plan.md ist im Code abgedeckt — was fehlt ist die manuelle Bestätigung mit explizit notiertem Pass-Kriterium. Ohne falsifizierbare Observable produziert ein Manual-Run nur "sah ok aus".
1.0 Plan-Verification 1–13
| # | Item | Status | Pass-Kriterium (was muss konkret zu sehen sein) |
|---|---|---|---|
| 1 | Schema-Init | ✅ | ~/.todo-app/todo.db + *-wal + *-shm existieren; EF-Migrationsverlauf in __EFMigrationsHistory enthält alle 8 Migrationen; Worker-Log: „listening on …" |
| 1a | SignalR-Endpoint | ✅ | curl http://127.0.0.1:47821/hub → HTTP 400 (kein Handshake) |
| 1b | Hub-Roundtrip Ping |
🟡 | UI-Statusbar zeigt „Connected"; WorkerClient.PingAsync() liefert "pong" (UI-Test fehlt) |
| 2 | claude --version Preflight |
✅ | Worker/Lifecycle/ClaudeCliPreflight.cs + Wiring in Program.cs. Kaputter claude_bin → LogCritical(...) + Environment.Exit(1). Skip via CLAUDEDO_SKIP_CLI_PREFLIGHT=1. Tests: tests/.../Lifecycle/ClaudeCliPreflightTests.cs |
| 3 | Smoke-Spawn (claude -p Prompt „ping") |
⬜ | task_runs-Row mit session_id NOT NULL, result non-empty, output_tokens > 0 |
| 4 | E2E Happy Path (Non-Worktree) | ⬜ | Liste „Test" anlegen → Task „Schreibe ein Haiku über Intralogistik" → tasks.status='Done', tasks.result IS NOT NULL, Logfile unter ~/.todo-app/logs/<taskId>.ndjson, UI-Row mit Done-Badge |
| 5 | Worktree Happy Path | ⬜ | Liste mit working_dir auf temp-Repo, Task mit Codeänderung → worktrees.state='active', head_commit IS NOT NULL, diff_stat non-empty, Branch claudedo/<id> auf Disk |
| 6 | No-Changes-Run | ⬜ | Prompt der nichts ändert → tasks.status='Done' aber worktrees.head_commit IS NULL, diff_stat IS NULL |
| 7 | Kein Git-Repo | ⬜ | working_dir=C:\Temp (kein Repo) → tasks.status='Failed', keine worktrees-Row, Worker-Log enthält Git-Fehler |
| 8 | Merge-UI | 🟡 | MergeTask-Hub-Methode + MergeModalView vorhanden, manueller Run nicht durchgespielt → worktrees.state='merged', im Ziel-Repo git log zeigt Commit, git worktree list ohne Branch |
| 9 | Override-Parallelität | 🟡 | OverrideSlotService-Tests grün; UI-E2E nicht durchgespielt → WorkerHub.GetActive ≥ 2 Einträge bei Run+RunNow |
| 10 | Schedule | 🟡 | QueuePicker-Tests grün; UI-E2E nicht → scheduled_for=now+2min bleibt Queued, dann automatisch Running, started_at >= scheduled_for |
| 11 | Worker-Offline-Erkennung | 🟡 | WorkerClient.OnServerConnectionClosed + Auto-Reconnect implementiert (WithAutomaticReconnect); visuell prüfen: nach taskkill der Worker-Exe wechselt Statusbar in ≤ 5s auf „Offline", RunNow-Buttons disabled |
| 12 | Live-Stream | 🟡 | ClaudeProcess streamt NDJSON via TaskMessage-Event, UI hat LiveTail; visuell prüfen: während Run laufen ndjson-Zeilen ein |
| 13 | Wake-up (WakeQueue nach Anlage) |
🟡 | QueueWaker.Wake() wird bei Enqueue aufgerufen; visuell prüfen: Task wechselt in ≤ 1s auf Running (statt nach queue_backstop_interval_ms=30s) |
Empfohlener Sprint: Steps 3–7 in einem Rutsch durchspielen (alles non-UI), parallel daneben 8–13 visuell beim normalen App-Lauf abhaken.
1.1 Planning Sessions — Manual Verification (unverändert relevant)
Bedingt durch Slice "Planning B/C". Ablauf identisch zur alten open.md:
- Manual-Task mit Title + TODO-Description anlegen.
- Rechtsklick → Open planning Session → Windows Terminal mit Claude CLI öffnet.
- In CLI: zwei Children via
mcp__claudedo__create_child_taskanlegen. - UI: Drafts erscheinen eingerückt, italic, mit
DRAFT-Badge; Parent zeigtPLANNING-Badge. - Chevron klappt ein/aus.
- CLI
finalize→ Children werden Queued (erste) bzw. Queued+BlockedBy (Rest); Parent flippt vonActiveaufFinalized(PLANNED-Badge); erste Child startet automatisch. - Neuer Planning-Task, Terminal ohne Finalize schließen → Rechtsklick öffnet Resume/Finalize-now/Discard-Modal.
- Delete-Versuch auf Parent mit Children → freundlicher Fehlerdialog, kein Delete.
Bekannte Follow-ups (non-blocking):
- ✅
Border.badge.planned(blau) wird jetzt beiFinalizedangewendet —TaskRowViewnutztClasses.planning/Classes.plannedgebunden anIsPlanActive/IsPlanFinalized; der Child-„PLANNED"-Badge nutzt direktplanned. - ✅ Tote
Instance-Statics aufBoolToItalicConverterundBoolToDraftOpacityConverterentfernt (Registrierung läuft über das Resource-Dictionary inApp.axaml). - ✅
Ui.TestsIWorkerClient-Fakes auf gemeinsame BasisStubWorkerClientrebased — kein Constructor-Drift mehr; die drei Fakes überschreiben nur ihre relevanten Member.
1.2 Prime Claude — Manual Verification
Slice "Prime" (Recurrence-Scheduler).
- Settings → Prime-Claude-Tab → Schedule mit
at: 09:00,every: workday,task_template: "Daily Standup"anlegen. - Test mit verschobenem
IPrimeClock(oder Schedule mitat: now+1min) → bei Trigger erscheint Toast/Footer-Notification „Prime fired", neuer Task entsteht in der Ziel-Liste. - Worker-Restart innerhalb des Schedule-Fensters → Catch-up läuft genau einmal (kein Doppelfeuer).
- Schedule editieren →
next_due_atwird neu berechnet; UI-Anzeige aktualisiert. - Schedule löschen → keine weiteren Trigger, keine ghost-Tasks.
1.3 Self-Update — Manual Verification (aus alter open.md, weiterhin gültig)
Voraussetzung: funktionierendes Gitea-Release unter git.kuns.dev/releases/ClaudeDo mit drei Assets — ClaudeDo-<version>-win-x64.zip, ClaudeDo.Installer-<version>.exe, checksums.txt.
- Baseline-Version (z.B.
0.2.x) normal installieren. - Neues Release
v0.3.0mit frischem Installer + App-Zip + Checksums veröffentlichen. - App starten → Banner erscheint:
Update available: v0.2.x → v0.3.0. - Update now klicken → App schließt, Installer öffnet im Update-Mode, läuft, restartet Worker.
- App neu starten → Banner weg;
Help → Check for updateszeigt kurz „You're up to date (v0.3.0)". v0.2.x-Installer manuell starten → bietet Self-Update auf v0.3.0 an. Update → laufende Exe wird ersetzt, Wizard öffnet auf neuer Version.- Schritt 6 mit Continue anyway → Wizard öffnet ohne Self-Update.
- Schritt 6 mit Cancel → Installer beendet ohne Aktion.
- Network-Kill in App und Installer beim Start → silent fallback (kein Error, kein Banner).
2. UI-Polish
2.1 Folder-Picker für Working Directory ⬜
- Datei:
Views/ListSettingsModalView.axaml+ zugehöriges VM - Aktuell: plain
TextBox— Pfad muss getippt werden. - Soll: Button „…" daneben → öffnet
IStorageProvider.OpenFolderPickerAsync, schreibt Pfad ins Feld. - Aufwand: klein.
2.2 Delete-Confirmation ⬜
- Aktuell: Listen/Tasks-Delete läuft direkt ohne Rückfrage. Datenverlust-Risiko.
- Soll: generischer
ConfirmDialog(1× bauen, mehrfach nutzen), Mini-Dialog „Wirklich löschen?". - Aufwand: klein.
2.3 Markdown-Rendering Result + Description ✅
Views/MarkdownView.axaml+ Detail-Pane verwenden Markdown.Avalonia.
2.4 Live-Log Auto-Scroll ⬜
- Datei:
Views/DetailsIslandView.axaml(.cs)(Live-Tail-Section) - Aktuell: ndjson-Zeilen werden angehängt, Scrollposition bleibt stehen.
- Soll: Sticky-Bottom-Pattern — bei jeder neuen Zeile
ScrollToEnd(), solange User nicht manuell hochgescrollt hat. Attached-Behavior reicht.
2.5 Diff-Viewer 🟡
DiffModalView.axaml+PlanningDiffViewexistieren; integriert für Planning-Merges.- Offen: Task-Level-Diff (Worktree vs. main) noch nicht im Modal-Flow geprüft. Verwenden statt
Process.Start("cmd /k git diff …").
2.6 Status-Bar Active-Tasks Live-Update ⬜
- Datei:
ViewModels/StatusBarViewModel - Risiko:
RunNowCommand.NotifyCanExecuteChangedtriggert nicht pro Item bei Connection-Change. - Soll:
WeakReferenceMessenger-Connection-Change-Message; alleTaskRowViewModellauschen. - Aufwand: klein, muss sauber gemacht werden.
2.7 Settings-Dialog ✅
SettingsModalViewalsTabControl, Tabs: General, Prime Claude, etc. Persistiert in~/.todo-app/ui.config.jsonundworker.config.json.
2.8 (NEU) Planning-Phase Badge-Farbe für Finalized ✅
Finalized zeigt jetzt den blauen planned-Badge (Class-Binding in TaskRowView).
2.9 (NEU) Tote Converter-Statics entfernen ✅
BoolToItalicConverter.Instance, BoolToDraftOpacityConverter.Instance entfernt.
3. Worker-Robustheit
3.1 CLI-Preflight beim Worker-Start ✅
src/ClaudeDo.Worker/Lifecycle/ClaudeCliPreflight.cs+ Wiring inProgram.cs. Tests:tests/.../Lifecycle/ClaudeCliPreflightTests.cs. Skippable viaCLAUDEDO_SKIP_CLI_PREFLIGHT=1.
3.2 Worktree-Cleanup beim Anlege-Failed ⬜
- Datei:
src/ClaudeDo.Worker/Runner/WorktreeManager.cs - Soll: try/finally — bei Fehler zwischen
git worktree addund DB-Insertgit worktree remove --forceals Best-Effort-Cleanup. - Aufwand: klein.
3.3 Logging über file-Sink ⬜
- ILogger ist überall verdrahtet, aber kein File-Sink konfiguriert.
- Soll: Serilog oder
Karambolage.Extensions.Logging.File— für Service-Modus zwingend, console-only ist im SCM-Fenster verloren. - Aufwand: klein.
3.4 Tag-Negation / Exclusion ⬜
- Tags sind weiterhin rein additiv (
list_tags ∪ task_tags). Nach Slice „Editierbare Tags" weniger dringend, aber nicht gelöst. - Soll: entweder neue Tabelle
task_tag_exclusionsoder Prefix!tagim task_tags-Eintrag. - Aufwand: mittel — Schema + Repo + Tests + UI.
4. Service-Deployment
4.1 Worker-Autostart via Startup-Shortcut ✅ (ersetzt Scheduled Task + Windows-Service)
- Der Worker läuft als
WinExe(kein Konsolenfenster) + Serilog-File-Sink (~/.todo-app/logs/worker-*.log) + Single-Instance-Mutex. - Autostart über eine Startup-Ordner-Verknüpfung
ClaudeDo Worker.lnk(%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\), die der Installer viaAutostartShortcut/ShortcutFactoryCOM-Helper anlegt. Kein Scheduled Task, kein Windows-Service. StartWorkerStepstartet den Worker perProcess.Start;StopWorkerStepbeendet ihn per prozessbasiertem Kill.- Die App (
IslandsShellViewModel) startet den Worker nicht selbst. Bei offline-Worker ~12s nach App-Start: einmaligesWorkerConnectionModal(Start Worker / Rerun Installer / Dismiss); Connection-Status-Pill in der Fußzeile ist ein Button zum erneuten Öffnen des Modals. UninstallRunnerlöscht die Startup-.lnk; migriert ältere Installs durch best-effort-Löschen des Legacy-Scheduled-Tasks „ClaudeDoWorker" und des Legacy-Windows-Service.- Manuelle E2E-Verifikation am Gerät ausstehend (Logoff/Logon-Autostart, Update-Pfad, Uninstall).
4.2 Pfad-Auflösung absolut ✅
WorkerConfig.Loadexpandiert~/%USERPROFILE%für alle Pfad-Felder.
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 Installer-Projekt ✅
ClaudeDo.Installer(WPF) +ClaudeDo.Releasesmit Pages/Steps/Core/Theme — Self-Update funktioniert (siehe §1.3).
5. Tests / CI
5.1 CI-Pipeline (Gitea Actions) ⬜
- Datei (neu):
.gitea/workflows/ci.yml - Inhalt:
dotnet restore→dotnet build(csproj-weise wegen.slnx-Bug auf .NET 8) →dotnet test. Auf Push + PR. - Achtung: Pipeline darf NICHT die
.slnxals Build-Target nehmen — explizite csproj-Liste in einem checked-in Build-Skript. - Aufwand: klein.
5.2 SignalR-Hub-Tests ✅
tests/ClaudeDo.Worker.Tests/Hub/PlanningHubTests.cs,AgentSettingsHubTests.cstesten Hub-Methoden via Fakes (kein realer SignalR-Roundtrip, aber alle Code-Pfade abgedeckt).- Optional verbleibt: echter Roundtrip-Test mit
WebApplicationFactory<Program>+HubConnectionBuilderfür End-to-End-Validierung der SignalR-Pipeline. Niedriger Mehrwert solange Fakes alle Methoden treffen.
5.3 Smoke-Test gegen echten claude ⬜
- Datei (neu):
tests/ClaudeDo.Worker.Tests/Runner/ClaudeProcessSmokeTest.cs - Soll: Real-CLI-Test mit
[Fact(Skip="...")]ausgegraut, nur lokal aktiviert wennCLAUDE_AUTHENTICATED=1Env-Var gesetzt ist. - Aufwand: klein.
5.4 (NEU) ExternalMcpService-Tests ⬜
External/ExternalMcpServicehat 11 Tools, aber nur partielle Coverage intests/.../External/ExternalMcpServiceTests.cs. Für jedes Tool mindestens einen Happy-Path + einen Error-Pfad ergänzen.
6. Dokumentation
6.1 README.md ⬜
- Komplett fehlt. Mind. 1× kurz: was ist es, wie starten (Worker + UI), wo Config, wie Self-Update.
6.2 docs/architecture.md 🟡
- In
plan.mdenthalten — entweder konsolidieren oder explizit ausgliedern. CLAUDE.md-Dateien pro Projekt sind aktuell de-facto-Architecture-Doc.
6.3 ADRs ⬜
- Vorschläge: „SignalR vs. SQLite-Polling für IPC", „Worktree pro Task", „TaskStateService als alleiniger State-Owner", „BlockedByTaskId statt Status='Waiting'", „External MCP als zweite WebApplication".
- Aufwand: klein, hilfreich für später.
6.4 (NEU) Mailbox-Proposal ⬜
docs/mailbox-proposal.mdist als Vorschlag vorhanden, nicht implementiert. Entscheidung: bauen, droppen oder parken? Wenn droppen → Datei entfernen, sonst klare Roadmap.
7. Bekannte Code-Schulden / Smells
| Stelle | Issue | Status |
|---|---|---|
WorkerHub.GetActive returnt IReadOnlyList<object> mit anonymen Typen |
Sollte expliziter ActiveTaskDto sein, den Worker UND UI teilen |
✅ (gibt bereits IReadOnlyList<ActiveTaskDto> zurück) |
TaskRunner führt eine if (list.WorkingDir != null)-Verzweigung mitten in der Methode |
Strategy-Pattern wenn die Methode wächst, aktuell noch klein genug | ⬜ |
App.Services als public static ServiceProvider |
Service-Locator-Antipattern, toleriert weil nur in App.OnFrameworkInitializationCompleted |
⬜ |
Embedded schema.sql ohne Versionierung |
Durch EF-Core-Migrationen ersetzt | ✅ |
| CRLF-Warnings beim Commit | .gitattributes mit * text=auto eol=lf (oder explizit pro Sprache) wäre sauberer |
✅ (.gitattributes angelegt) |
Tote Converter-Instances (BoolToItalicConverter.Instance, BoolToDraftOpacityConverter.Instance) |
Per Resource-Dictionary registriert, Statics ungenutzt | ✅ (entfernt) |
1 unausgeführter // TODO in DetailsIslandViewModel (SendPromptAsync ohne Hub-Methode) |
Entweder Hub-Methode bauen oder TODO entfernen | ✅ (im Main-Code nicht mehr vorhanden) |
8. Improvement Plan (improvement-plan.md, Stand 2026-04-13)
| ID | Item | Status | Bemerkung |
|---|---|---|---|
| IP-1 | UI ↔ Worker Auto-Reconnect | ✅ | WorkerClient mit WithAutomaticReconnect() + Reconnect-Handler |
| IP-2 | Listen-Modus „Notes" (non-autonomous) | ⬜ | Nach Slice „editierbare Status/Tags" weniger dringend (man kann jetzt einen Task ohne agent-Tag idle lassen), aber lists.kind als sauberer Mode-Switch fehlt. |
| IP-3 | Doppelklick öffnet Edit-Dialog | ✅ | DoubleTapped-Handler in ListsIslandView, TasksIslandView |
| IP-4 | Tag Multi-Select Control | ⬜ | Tags sind via Picker im Detail-Pane editierbar, aber kein dediziertes Multi-Select-Control mit Auto-Vervollständigung in Editor-Dialogen. |
| IP-5 | Rechtsklick-Kontextmenü | ✅ | Listen + Tasks haben Context-Menüs (Edit, Delete, Run Now, Show Diff, Merge, Cancel, Status, Tags) |
| IP-6 | Schema-Migration-Mechanismus | ✅ | EF-Core-Migrations + __EFMigrationsHistory |
| IP-7 | Status-Bar Reconnect-States | ✅ | connected/connecting/reconnecting/offline farbcodiert |
| IP-8 | Tag-Repository GetAllKnownTagsAsync |
✅ | TagRepository.GetAllAsync + WorkerClient.GetAllTagsAsync |
9. Empfohlene Reihenfolge für die nächsten Sessions
Block 1 — Verification durchspielen (kein neuer Code, nur Beweis):
- §1.0 Steps 3–7 manuell (Smoke + E2E + Worktree + No-Changes + Kein-Repo) — ist die Pipeline wirklich lebendig?
- §1.1 Planning-Walkthrough — nach den uncommitted Coordinator-Änderungen einmal durchspielen.
- §1.2 Prime-Walkthrough — Schedule-Trigger einmal beobachten.
Block 2 — Niedrig hängende UI-Polish (eine Session): 4. §2.1 Folder-Picker 5. §2.2 Delete-Confirmation 6. §2.4 Live-Log Auto-Scroll 7. §2.6 Status-Bar Live-Update 8. §2.8 Planning-Badge-Farbe + §2.9 tote Converter weg
Block 3 — Robustheit & Service-Deployment: 9. §3.2 Worktree-Cleanup 10. §3.3 File-Sink-Logging 11. §4.3 Install-Skripte/Doku
Block 4 — Sicherheitsnetz: 12. §5.1 Gitea-Actions CI-Pipeline (csproj-weise) 13. §5.3 Smoke-Test gegen echten claude 14. §5.4 ExternalMcpService-Tests vervollständigen
Block 5 — Dokumentation & Aufräumen:
15. §6.1 README
16. §6.3 ADRs (mind. die fünf wichtigsten)
17. §6.4 Mailbox-Proposal: bauen/droppen entscheiden
18. §7 Smells: ActiveTaskDto, .gitattributes, TODO-Comment
Block 6 — Optional / wenn Bedarf konkret wird: 19. §3.4 Tag-Negation 20. §IP-2 Notes-Modus 21. §IP-4 Tag Multi-Select Control