Cookie-basierte Client-Erkennung: Query-Parameter auf der ersten Navigation -> Middleware setzt Cookie auf jeder Antwort -> Hook liest es hydration-sicher
Beim Handbuchsatz zu Trotzdem ausführen wurde Der Grund dafür zu Der Grund für die Windows-Meldung umformuliert, weil der neu eingefuegte Satz sonst den Bezug des Pronomens verschoben haette (redaktionelle Praezisierung, kein inhaltlicher Unterschied zum Plan).
Phase quick-260917-h2s Plan 01: Desktop-Client-Erkennung, Beta-Label, deutscher Installer Summary
Der Desktop-Client meldet sich jetzt beim Web per Cookie an, wodurch Download-Links und das Browser-Kontextmenü in der App verschwinden; der Beta-Update-Hinweis nennt bei gleicher Version den Commit-Stand statt der verwirrenden gleichen Versionsnummer, und der Windows-Installer läuft auf Deutsch mit Tessera-Grafik und -Symbol.
with_desktop_marker(url) hängt desktop=1 als Query-Paar an einen Klon der Adresse an; beide window.navigate-Aufrufe (save_server_url, Startnavigation im setup) nutzen sie. Der im Store gespeicherte server_url-Wert bleibt unverändert (Parameter geht nur in die Navigation).
update_labels(version_changed, version, commit) liefert Menü-/Benachrichtigungstext: bei Versionswechsel wie bisher „Version {v} herunterladen"; bei gleicher Version (Beta-Kanal, neuer Commit) „Neuen Beta-Stand herunterladen" / „Neuer Beta-Stand {commit} verfügbar …".
mod tests deckt beide Helfer ab (5 Tests); cargo fmt --check, cargo check, cargo clippy, cargo test --lib grün.
Task 2 — Web, Tracer (Commit d9b94bd):
withDesktopCookie in middleware.ts setzt tessera_desktop=1 (Path /, ein Jahr, SameSite=lax, ohne HttpOnly, Secure nur bei https) auf jede Antwort der middleware-Funktion, sobald ?desktop=1 anliegt — auch auf dem Frühausstieg für öffentliche Routen und auf Redirects. Die von Plan 260917-gyd zwischenzeitlich ergänzten Rückgaben (u. a. der next-Redirect) sind mit eingeschlossen.
apps/web/src/lib/desktop-client.ts: isDesktopClient() liest das Cookie synchron (SSR-sicher: false ohne document); useIsDesktopClient() kapselt es per useEffect, damit Server- und erster Client-Render übereinstimmen.
DesktopDownloadLinks bricht den Ladeeffekt im Desktop-Client vor dem Request ab und rendert nichts.
DesktopContextMenuGuard (neu, in layout.tsx eingebunden) unterdrückt das WebView2-Kontextmenü außerhalb von Eingabefeldern/contenteditable-Bereichen.
Tracer-Gate: Die komplette Kette (Anfrage mit ?desktop=1 → Cookie auf der Antwort → Hook → Komponente rendert nichts) wurde Ende-zu-Ende durch die volle Testsuite (pnpm --filter @tessera/web exec vitest run, 417/417 grün) und type-check bestätigt, bevor Task 3 begann.
Beide BMPs aus dem Scratchpad nach icons/ kopiert (nsis-header.bmp 150×57, nsis-sidebar.bmp 164×314, beide BMP3).
CHANGELOG: vier neue Desktop-App:-Stichpunkte (zwei unter „Geändert", zwei unter „Behoben").
docs/anleitung-anwender.md: Satz zum deutschen Installationsassistenten (kein Admin nötig); Tray-Eintrag „Update herunterladen" erklärt (Beta-Text).
docs/anleitung-entwicklung.md: Ort der nsis-Konfiguration und Hinweis, dass nur der CI-Bau auf Windows den echten Nachweis liefert.
Deviations from Plan
Auto-fixed Issues
None — plan executed exactly as written. Eine redaktionelle Umformulierung (siehe decisions oben) war nötig, damit ein Pronomenbezug im Handbuchsatz nicht verrutscht; inhaltlich deckt sich der Text mit der Plan-Vorgabe.
Offene Nachweise (nicht lokal prüfbar)
Wie im Plan vorgesehen, bleibt der Beweis über die WebView2-Grenze durch den Orchestrator nach dem CI-Bau auf der Windows-VM offen:
Cookie tessera_desktop=1 im echten Client gesetzt (Bedienprobe)
Keine Download-Links auf der Anmeldeseite im Client
Kein Browser-Kontextmenü im Client, aber in Eingabefeldern erhalten
Beta-Label „Neuen Beta-Stand herunterladen" / Benachrichtigung mit Commit-Kürzel
Deutscher Installer mit Tessera-Kopf-/Seitenbild und -Symbol