- bundle.windows.nsis in tauri.conf.json: Deutsch ohne Sprachauswahl,
Tessera-Icon, Kopf-/Seitenbild, currentUser (kein Admin noetig)
- icons/nsis-header.bmp (150x57), icons/nsis-sidebar.bmp (164x314) ergaenzt
- CHANGELOG: vier neue Desktop-App-Stichpunkte (Beta-Hinweis, Installer,
Download-Links, Kontextmenue)
- anleitung-anwender.md: Installationsassistent-Satz, Tray-Eintrag erklaert
- anleitung-entwicklung.md: Ort der nsis-Konfiguration, Pruefweg per CI
- Schema-Pruefung (node) und cargo check gruen
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- withDesktopCookie in middleware.ts setzt tessera_desktop=1 auf JEDER
Antwort (Fruehausstieg, Redirects, next()), wenn ?desktop=1 anliegt
- desktop-client.ts: isDesktopClient() liest das Cookie, useIsDesktopClient()
kapselt es hydration-sicher per useEffect
- DesktopDownloadLinks fragt /desktop/latest im Desktop-Client gar nicht
erst an und rendert nichts
- DesktopContextMenuGuard unterdrueckt das WebView2-Kontextmenue ausserhalb
von Eingabefeldern/contenteditable, in layout.tsx eingebunden
- middleware.test.ts (neu), desktop-client.test.ts (neu),
desktop-context-menu-guard.test.tsx (neu), Test 4 in
desktop-download-links.test.tsx — alle 417 Web-Tests und type-check gruen
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- with_desktop_marker haengt desktop=1 an beide Navigationen (save_server_url,
Startnavigation im setup); der Store-Wert server_url bleibt ohne Parameter
- update_labels liefert Menue-/Benachrichtigungstext: bei Versionswechsel wie
bisher, bei gleicher Version (Beta-Kanal) nennt der Text den Commit-Stempel
- mod tests deckt beide Helfer ab (fmt/check/clippy/test --lib gruen)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- auth-actions.ts: fetchSessionState() unterscheidet tote Sitzung (401/403/leere 200-Antwort, Cookie wird geloescht) von API-Ausfall (5xx/Netzwerkfehler/Nicht-JSON, unavailable ohne Redirect); fetchCurrentUser bleibt unveraendert
- header.tsx: Waechter im useEffect leitet bei toter Sitzung per Vollnavigation auf /login?next=… um, bleibt bei API-Ausfall still
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- safe-next.ts: buildNextParam()/sanitizeNextPath() als reine, getestete Funktionen (Open-Redirect-Schutz)
- middleware.ts: haengt next-Parameter an beide Login-Umleitungen (fehlendes Cookie, ungueltige Signatur)
- login/page.tsx: springt nach erfolgreicher Anmeldung auf den bereinigten next-Wert
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- LogoMark: gedrehte Signalkachel per Inline-Style fill: var(--primary, BRAND_YELLOW) statt festem fill-Attribut
- folgt damit der persoenlichen Akzentfarbe (applyAccentColor in auth-store.ts) in Kopfzeile, Seitenleiste und leerem Dashboard; ohne Nutzer (Anmeldeseite) gilt der CSS-Standard Markengelb
- brand.ts: Kommentar zu BRAND_YELLOW als Rueckfallwert ergaenzt
- tessera-logo.test.tsx: Kacheltest auf Inline-Style-Fuellung umgeschrieben (jsdom haelt var() in style.fill)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- STATE.md: Quick-Task-Zeile 260917-e15, Session Continuity, Last activity
- HANDOFF.json entfernt (einmaliges Uebergabe-Artefakt, in dieser Sitzung abgearbeitet)
- config.json: git.allow_default_branch_commits = true — Projekt committet
per branching_strategy "none" direkt auf main; ohne den Schalter blockiert
der Pre-Commit-Guard des Executors jeden Quick-Task
- SUMMARY des Quick-Tasks
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Die fuenf Icon-Dateien in apps/desktop/src-tauri/icons/ durch einen mit
der Tauri-CLI (tauri icon, Renderer resvg) erzeugten Satz ersetzt
- ImageMagick/MSVG hatte die gedrehte gelbe Kachel (transform rotate(12 51 21))
aus apps/web/src/app/icon.svg nicht gerendert, dadurch zeigte das Symbol
eine "1" statt des Tessera-T
- tauri.conf.json, Web-Code und Rust-Code unveraendert
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bedienprobe des Users: Installer und Start liefen, dann schwarzes Fenster
"asset not found: index.html". Das Fenster "main" hatte keine Startseite,
Tauri nimmt dann index.html; die Erststart-Seite heisst setup.html (Altlast
aus Phase 6, in keinem echten Paket sichtbar geworden). CARGO_BUILD_JOBS=4,
weil 8 parallele rustc-Prozesse den gemeinsam genutzten Runner-Host (15 GB)
an die Speichergrenze brachten; Betriebshandbuch Kap. 10 ergaenzt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Mit dem Cargo-Zwischenspeicher wuerde ein einmal einkompilierter Stempel
sonst veralten und der Beta-Update-Hinweis dauerhaft erscheinen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Alle vier Critical/Warning-Befunde aus 18-REVIEW.md sind behoben (CR-01
0d5c80f, WR-01 1b2f803, WR-02 579e24b, WR-03 a8964f1); die beiden Info-Befunde
bleiben laut Auftrag unbearbeitet (dokumentiert als uebersprungen). Status auf
clean gesetzt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
desktop-collect.sh vergibt fuer den Beta-Kanal (main) jedem Commit dieselbe
X.Y.Z-Version aus dem letzten Freigabe-Tag (D-07) -- der bisherige Vergleich
nur ueber `version` liess Nutzer zwischen zwei Tags nie eine neuere
Beta-Version sehen, obwohl manifest.json ein neues `commit`-Feld traegt.
build.rs bettet jetzt per `git rev-parse --short=7 HEAD` denselben
Commit-Stempel, den desktop-collect.sh fuer manifest.json schreibt, als
APP_COMMIT zur Kompilierzeit ein; lib.rs vergleicht bei channel == "beta"
zusaetzlich den Commit. Fuer den Live-Kanal bleibt es beim reinen
Versionsvergleich, D-07 (X.Y.Z in tauri.conf.json/Cargo.toml) bleibt
unveraendert. cargo check + cargo clippy -- -D warnings sind sauber.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die CSP erlaubte 'unsafe-eval' und Wildcard-Quellen (connect-src/img-src/
font-src/style-src *), obwohl setup.html -- die einzige lokale Seite der App --
kein eval() nutzt, keine externen Schriften/Bilder laedt und ausschliesslich
ueber die Tauri-IPC-Bruecke (window.__TAURI__.core.invoke) mit dem Rust-Teil
spricht. Diese CSP gilt nur fuer vom App-eigenen Protokoll ausgelieferte
Seiten; nach save_server_url() navigiert das Hauptfenster auf die
Server-Adresse, und diese Navigation wird von der CSP der Zielseite selbst
bestimmt, nicht mehr von dieser Konfiguration. Verengt auf
default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self'
'unsafe-inline'; img-src 'self' data:; connect-src 'self'.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Die Zeichen-Whitelist /^[A-Za-z0-9._-]+$/ liess Namen wie ".." durch, weil
Punkt und Bindestrich erlaubte Zeichen sind -- path.join(desktopDistDir, '..')
loest aber in den Elternordner auf und unterlaeuft genau die Verteidigung in
der Tiefe (T-18-02), die diese Zeile laut Kommentar herstellen soll. Jetzt
werden "." und ".." explizit abgelehnt UND der aufgeloeste Pfad zusaetzlich
gegen desktopDistDir geprueft (haelt auch kuenftige Varianten ab, falls die
Whitelist anderswo wiederverwendet wird). Neue Testfaelle fuer manifest-Eintraege
namens "..", "." und "../manifest.json".
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ein kaputter Plattform-Eintrag (z. B. fehlendes name-Feld oder ungueltiger
sha256) fiel bisher erst spaeter unbemerkt durch -- entry.name === undefined
wurde zu "undefined" gecoerct und als Dateiname gesucht. getManifest()
prueft jetzt jeden vorhandenen Plattform-Eintrag (name: string, size: number,
sha256: 64-stelliger Hex-String) und behandelt ein kaputtes Manifest wie ein
fehlendes (404 + Warn-Log), statt die kaputte Form durchzureichen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Coverage-Block, Manuelle-Abnahme-Abschnitt mit Bedienprobe-Schrittfolge und
den zwei auf den naechsten Freigabe-Tag vertagten Punkten, Self-Check PASSED.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Neuer Abschnitt "Phase 18 — Desktop-Client fertigstellen" mit DESK-01..05
(DESK-01/02 aus Phase 6 fortgefuehrt, DESK-03..05 neu aus 18-CONTEXT.md)
- Traceability-Tabelle um fuenf DESK-Zeilen ergaenzt, Coverage-Satz aktualisiert
- Alle Gesamtlaeufe gruen: API 1086/1086, Web 365/365, beide Typpruefungen
fehlerfrei, cargo check Finished
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Betriebshandbuch: neues Kapitel 10 (Pipeline-Herkunft, Ablageort im Abbild,
Release-Anhaenge, DESKTOP_DIST_DIR, Fehlerbilder-Tabelle); Kapitel 9 um
Satz zu Desktop-Paketen im Freigabe-Tag ergaenzt
- CI/CD-Runbook: aus drei werden vier Jobs, Job desktop ausfuehrlich
beschrieben (Cross-Bau, Cache-Reihenfolge, Cache-vs-upload-artifact-
Begruendung), Fehlerbehebung um drei Unterabschnitte ergaenzt
(Job desktop, cache miss, Release-Upload 413)
- Entwicklungshandbuch: apps/desktop ist kein Grundgeruest mehr, neuer
Abschnitt "Desktop-App lokal bauen", Testabschnitt um vitest src/desktop
und cargo check/clippy ergaenzt
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- Neues Kapitel "Desktop-App" (9 Unterabschnitte: Was es ist, Herunterladen,
Installation Windows/Linux, Erster Start, Infobereich/Beenden, Automatischer
Start, Neue Version, Fehlerbilder), Inhaltsverzeichnis um Punkt 8 ergaenzt
- CHANGELOG-Stichpunkt unter Unveroeffentlicht/Neu im Wortlaut von D-17
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Job desktop, Schritt "Rust pruefen": `cargo clippy` scheiterte mit
"'cargo-clippy' is not installed for the toolchain 'stable-x86_64-unknown-linux-gnu'"
(minimal-Profil enthaelt clippy nicht). `rustup component add clippy` direkt
nach der Toolchain-Installation ergaenzt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Baut nach dem AppImage zusaetzlich den Windows-Installer per Cross-Bau auf
dem Linux-Runner (cargo-xwin, NSIS aus dem Ubuntu-Paket), cached SDK und
NSIS-Plugins, und sammelt beide Dateien mit --require linux,windows ein.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>