diff --git a/docs/open.md b/docs/open.md index 88c1c1c..bb9615d 100644 --- a/docs/open.md +++ b/docs/open.md @@ -161,11 +161,13 @@ Voraussetzung: funktionierendes Gitea-Release unter `git.kuns.dev/releases/Claud ## 4. Service-Deployment -### 4.1 Worker-Autostart als Per-User-Task ✅ (ersetzt Windows-Service) -- Der Worker läuft **nicht mehr als Windows-Service** (LocalSystem konnte die Claude-CLI-Auth des Users nicht sehen). Stattdessen: per-user **Logon-Scheduled-Task** „ClaudeDoWorker" (`schtasks /Create /XML`), läuft als angemeldeter User, versteckt, mit Restart-on-Failure. -- Worker ist `WinExe` (kein Konsolenfenster) + Serilog-File-Sink (`~/.todo-app/logs/worker-*.log`) + Single-Instance-Mutex. -- Installer migriert beim Update den alten Service automatisch weg (`sc stop`/`delete`) und registriert die Task; Uninstall entfernt Task + Worker-Prozess. App startet/neustartet den Worker als Prozess und sorgt beim Start dafür, dass er läuft. -- Implementiert 2026-05-29, getestet (Build + Unit-Tests grün), **manuelle E2E-Verifikation am Gerät ausstehend** (Update von 1.0.2-alpha → Task, Logoff/Logon-Autostart, Uninstall). +### 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 via `AutostartShortcut`/`ShortcutFactory` COM-Helper anlegt. Kein Scheduled Task, kein Windows-Service. +- `StartWorkerStep` startet den Worker per `Process.Start`; `StopWorkerStep` beendet ihn per prozessbasiertem Kill. +- Die App (`IslandsShellViewModel`) startet den Worker nicht selbst. Bei offline-Worker ~12s nach App-Start: einmaliges `WorkerConnectionModal` (Start Worker / Rerun Installer / Dismiss); Connection-Status-Pill in der Fußzeile ist ein Button zum erneuten Öffnen des Modals. +- `UninstallRunner` lö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.Load` expandiert `~`/`%USERPROFILE%` für alle Pfad-Felder. diff --git a/docs/plan.md b/docs/plan.md index 774ddf0..fb912ce 100644 --- a/docs/plan.md +++ b/docs/plan.md @@ -231,36 +231,21 @@ Beispiel: `feat(lager-app): add barcode scan retry logic` DB-Zugriff via Microsoft.Data.Sqlite + Repository-Layer (`TaskRepository`, `ListRepository`). Git-Operationen (UI + Worker) über gemeinsamen `GitService` in `ClaudeDo.Data`. MVVM via CommunityToolkit.Mvvm. -## Worker als Windows-Service (Ziel-Deployment) +## Worker-Deployment (Autostart via Startup-Shortcut) -Initial läuft der Worker als Console-Prozess (lokales Dev-Setup). Im Endzustand soll er als **Windows-Service** automatisch starten. +Der Worker läuft als **WinExe** (kein Konsolenfenster) — kein Windows-Service, kein Scheduled Task. -**Code-seitig:** -- Paket `Microsoft.Extensions.Hosting.WindowsServices` referenzieren. -- In `Program.cs`: `builder.Host.UseWindowsService(o => o.ServiceName = "ClaudeDoWorker")`. -- Logging zusätzlich über `EventLog` (`builder.Logging.AddEventLog(...)`), damit Service-Fehler im Windows Event Viewer landen. -- Alle Pfade in `worker.config.json` **absolut** auflösen (`%USERPROFILE%` / `~` expandieren) — der Service-Working-Directory ist standardmäßig `C:\Windows\System32`. -- `StaleTaskRecovery` (siehe oben) sorgt nach Service-Restart automatisch für das Aufräumen hängender `running`-Tasks. -- Restart-Verhalten via `sc.exe failure`-Konfig oder beim Install. +**Autostart:** Der Installer legt eine Verknüpfung `ClaudeDo Worker.lnk` im Startup-Ordner des Users an (`%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\`). Dafür nutzt `ClaudeDo.Installer` den Helper `AutostartShortcut` (mit extrahiertem `ShortcutFactory` COM-Helper). Beim Windows-Logon startet Windows die Verknüpfung automatisch — ohne Elevated-Rechte und mit vollem Zugriff auf die `~/.claude/`-Session des Users. -**Install:** -- Veröffentlichen mit `dotnet publish -c Release -r win-x64 --self-contained false`. -- Service registrieren: - ```cmd - sc.exe create ClaudeDoWorker binPath= "C:\Path\To\ClaudeDo.Worker.exe" start= auto - sc.exe failure ClaudeDoWorker reset= 60 actions= restart/5000/restart/10000/restart/30000 - ``` -- Später optional: kleines `ClaudeDo.Installer`-Projekt (WiX oder MSIX), das das auch macht. +**Manueller Start (App-seitig):** Der Installer-Step `StartWorkerStep` startet den Worker beim Install/Update via `Process.Start` direkt. Die App (`IslandsShellViewModel`) startet den Worker **nicht** selbst. Stattdessen: ist der Worker ~12 Sekunden nach App-Start noch offline, erscheint einmalig ein `WorkerConnectionModal` mit drei Optionen (Start Worker / Rerun Installer / Dismiss). Der Connection-Status-Pill in der Fußzeile ist ein klickbarer Button, der das Modal auf Anfrage erneut öffnet. -**Auth-Konflikt mit "User-CLI-Session" beachten:** -Der Worker-Service läuft per Default unter `LocalSystem` — der hat **keinen Zugriff** auf die `~/.claude/`-Session des interaktiven Users, in der der CLI-Login liegt. Optionen: +**Stop/Uninstall:** `StopWorkerStep` beendet den Worker via prozessbasiertem Kill (kein `schtasks /End` mehr). `UninstallRunner` löscht die Startup-`.lnk`. Als Migrations-Schritt für ältere Installationen löscht der Uninstaller auch den Legacy-Scheduled-Task „ClaudeDoWorker" und den Legacy-Windows-Service (best-effort). -1. **Empfohlen:** Service unter dem **User-Account** laufen lassen (`sc.exe config ClaudeDoWorker obj= ".\" password= "..."` oder via `services.msc` → "Log On As"). Dann greift die bestehende `claude login`-Session des Users. Voraussetzung: User-Account hat das Recht "Log on as a service". -2. **Fallback:** Wieder auf API-Key wechseln (`ANTHROPIC_API_KEY` als Umgebungsvariable des Service oder im `worker.config.json`). Dann ist der Service unabhängig vom User-Profil — verliert aber den Vorteil "kein Key-Handling". +**Logging:** Serilog-File-Sink nach `~/.todo-app/logs/worker-*.log`. Single-Instance-Mutex verhindert parallele Instanzen. -Entscheidung wird beim Service-Deployment getroffen, bleibt für die initiale Console-Variante irrelevant. Service-Modus erfordert keine Schema- oder API-Änderungen am Worker. +**Pfade:** `WorkerConfig.Load` expandiert `~`/`%USERPROFILE%` für alle Pfad-Felder. -**SignalR im Service-Modus:** Bindung bleibt `127.0.0.1:47821`. Da die UI auf demselben Rechner läuft, ist Loopback-Erreichbarkeit gegeben — Windows-Firewall greift bei Loopback nicht. +**SignalR:** Bindung bleibt `127.0.0.1:47821`. Da die UI auf demselben Rechner läuft, ist Loopback-Erreichbarkeit gegeben — Windows-Firewall greift bei Loopback nicht. ## Project-Layout (Monorepo) @@ -319,4 +304,4 @@ Vorteil Monorepo: gemeinsames `schema.sql`, atomische Änderungen über UI+Worke - Bulk-Discard alter Worktrees. - Anzeige der ndjson-Message-Chronik im UI. - Windows Job Objects für garantierten Child-Cleanup beim Worker-Crash. -- Installer-Projekt (`ClaudeDo.Installer`, WiX/MSIX), das den Service registriert + UI shortcut anlegt. +- Install-Skripte/Doku für manuelles Deployment ohne Installer.