Eine Modifier-Geste, die niemand kennt, ist keine Funktion. Zwei Maßnahmen:
- Solange Alt gedrückt ist, trägt #out die Klasse `alt`: alle Knoten zeigen
`cursor:alias`, der Knoten unter dem Zeiger einen Petrol-Ring. Das wirkt
auch auf verlinkten Knoten, wo der einfache Klick dem Link gehört und es
sonst gar keine Rückmeldung gäbe. Der `blur`-Handler ist Pflicht — bei
Alt+Tab kommt kein keyup mehr an, der Modus bliebe hängen.
- Die aufklappbare Legende endet mit einer abgesetzten Bedienungs-Zeile
(`hint_jump` in 9 Sprachen, `.hint-op` mit gestricheltem Trenner), damit
sie ihre Rolle als Notations-Legende behält.
Verworfen (in D25 samt Begründung festgehalten): einfacher Klick springt auf
Knoten ohne URL (~97 % der Knoten der Beispieldateien) — beiläufig auffindbar,
aber dieselbe Geste täte je nach Knoten Verschiedenes; sowie ein einmaliger
Hinweis nach dem ersten Sprung.
Verifiziert im Browser: ohne Alt Cursor auto bzw. pointer (Link), mit Alt
überall `alias`, nach Loslassen zurück, nach blur ohne keyup (Alt+Tab)
zurückgesetzt; Legenden-Zeile sichtbar und abgesetzt. Vitest 37/37.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Knoten und Notationszeile sind nun verknüpft. Der Parser hängte die
Zeilennummer ohnehin schon an jeden Knoten — sie wandert jetzt als data-line
ins Markup.
- Diagramm -> Text: Alt+Klick markiert die ganze Zeile im Editor (Fokus,
in Sicht gescrollt); Tastatur Alt+Enter, Touch langer Druck (500 ms,
Wischen bricht ab). Ein zugeklapptes Editor-Panel wird zuerst geöffnet.
- Text -> Diagramm: der Knoten der Cursor-Zeile bekommt weißen Halo +
Tinte-Ring und wird beim Zeilenwechsel ins Bild gescrollt.
- Alt statt einfachem Klick, weil ein Knoten mit URL als <a> den ganzen
Kasten belegt (SPEC §6 bleibt unverändert). Der Handler ruft
preventDefault() — sonst lädt Alt+Klick auf einen Link das Ziel herunter.
Neuer Tooltip-Hinweis an jedem Knoten (i18n `jumpHint`, 9 Sprachen).
- Gescrollt wird über einen Spiegel-div, nicht über Zeilenhöhe x n: lange
Zeilen brechen weich um, die naive Rechnung lag im Test bei 60 Zeilen um
bis zu 525 px daneben.
Beim Verifizieren gefunden und behoben: `ul.or .node{box-shadow:none}` ist
spezifischer als `.node.current` und schluckte den Ring überall unterhalb
einer any-of-Gruppe — die Regel braucht den #out-Präfix.
Verifiziert im Browser (Alt+Klick auf <a>- und div-Knoten, Klick aufs
Größen-Badge, Klick/Enter ohne Alt unverändert, Alt+Enter, kurzer/langer
Druck und Wischen auf Mobil, Panel-Aufklappen aus dem minimierten Zustand,
Zeile nach Sprung immer im sichtbaren Band, Kommentar-/verworfene Zeilen
heben nichts hervor). Vitest 37/37 (3 neue data-line-Tests, Snapshots
aktualisiert). Dokumentiert als D25 + SPEC §9 + frontend/CLAUDE.md + README.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mit nur einem Beispiel ließ sich das Umschalten zwischen Dokumenten (D22)
nicht zeigen — jeder ?sourceUrl=-Link legt genau ein Dokument an (D23), erst
mehrere nacheinander geöffnete füllen den Wähler.
- Neue Endung `.werkbaum` (D24, SPEC §12): macht Notationstexte zuordenbar
(spätere Editor-Zuordnung, Syntax-Highlighting, Öffnen/Speichern). Konvention,
kein Vertrag — `?sourceUrl=` wertet weder Endung noch Content-Type aus, `.txt`
bleibt gültig. `.gitattributes` führt `*.werkbaum` als Text (LF).
- docs/example-plan.txt -> docs/examples/example-plan-0.werkbaum (Inhalt bis
auf die Kopfzeile unverändert); README-Links nachgezogen.
- Neu, je einen anderen Aspekt zeigend:
example-plan-1 (Küche: kein Software-Plan, alternativenlastig — günstigster
Pfad), example-plan-2 (Konferenz: breiter Fächer, viele Beteiligte),
example-plan-3 (drei Wurzeln = drei Bäume nebeneinander, dazu ein Knoten
ohne Größe für das implizite-M-Badge),
example-werkbaum (Werkbaum selbst: Bestand + mögliche Weiterentwicklung,
destilliert aus ROADMAP/TASKS/DECISIONS).
- README.md / README.de.md: Tabelle mit den fünf Live-Links samt Hinweis, dass
sie nacheinander geöffnet den Dokument-Wähler füllen.
Verifiziert: alle fünf parsen headless ohne Warnungen und ohne gemischte Gates
(19/26/43/28/79 Knoten, 3 Wurzeln in Beispiel 3); Vitest 34/34 grün.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Live-Beispiel-Link zeigte auf werkbaum.javagil.de — die stabile Instanz
wird manuell deployt (scripts/deploy-prod.sh) und kennt ?sourceUrl= noch nicht
(verifiziert: 0 Treffer im ausgelieferten HTML). Der Parameter waere dort
stillschweigend ignoriert worden. Der Link zeigt nun auf die automatisch aus
main deployte Pages-Instanz, die das Feature hat.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Für ?sourceUrl= (D23) fehlte bislang eine ladbare Beispieldatei — im Repo lagen
nur Markdown-Dokumente (rendern als Chaos) und VERSION.
- docs/example-plan.txt: englischer Beispielplan, der die Notation vorführt —
alle acht Status (inkl. [!] mit Warndreieck und einer verworfenen
Alternative), beide Gates, Größen, Tags, URLs, Kommentare sowie zwei
Geister-Knoten für die Untergliederungspflicht ab M.
- README.md / README.de.md: neuer Abschnitt „Loading a diagram from a URL" /
„Diagramm aus einer URL laden" mit klickbarem Live-Beispiel, dem Hinweis auf
URL-als-Dokumentname und der CORS-Einschränkung.
Verifiziert: Die Datei parst ohne Warnungen (18 Knoten, 7 sichtbare Status,
1 Warndreieck, 2 Geister-Knoten).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Editor kann den Text aus einer externen Textdatei beziehen:
…/index.html?sourceUrl=https://example.org/plan.txt
- Das Geladene wird als eigenes Dokument (D22) geführt, dessen Name die URL
ist; die id leitet sich aus der URL ab, derselbe Link aktualisiert also
dieses Dokument, statt bei jedem Aufruf ein neues anzulegen. Eigene
Dokumente bleiben unberührt. Die volle URL steht zusätzlich im Tooltip
(der Name wird in der Titelzeile elidiert).
- Ist der Parameter gesetzt, wird bei jedem Laden neu geholt — die URL ist
die Quelle der Wahrheit.
- Nur http(s) (relative Angaben werden aufgelöst), credentials:'omit';
file:/data:/javascript: werden abgewiesen. Fremder Text ist ungefährlich:
Labels werden escaped, der Parser erkennt als Link nur https?:// (SPEC §1).
- Fehler (CORS, 404, Netz) landen als zeilenlose Warnung `sourceLoad` im
Warnbereich und nennen CORS ausdrücklich als wahrscheinliche Ursache; der
bisherige Stand bleibt stehen. i18n in allen 9 Sprachen.
- Nebenbei: checkForUpdates() baut die Cache-Buster-URL nun über
URL/searchParams — mit vorhandenem Query-String hätte '?t=' ein zweites
'?' erzeugt.
Verifiziert headless (jsdom gegen den gebauten Bundle: Erfolg, CORS-Fehler,
404, ohne Parameter, verbotenes Schema) und im Browser gegen
raw.githubusercontent.com. Dokumentiert als D23 + SPEC §9 + frontend/CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Behebt drei Punkte am Mehrfach-Dokument-Feature (D22):
- Beispiel-Dokument heißt jetzt fest „Example" (englisch, nicht mehr
lokalisiert „Beispiel") und trägt die reservierte id `example`. Alt-Zustände
(zufällige id, „Beispiel") werden beim Laden adoptiert, sofern der Text noch
unverändert ist (=== INITIAL) — echte Inhalte nie.
- Umbenennen läuft inline im Menü (Textfeld: Enter bestätigt, Esc bricht ab,
Blur bestätigt) statt über window.prompt, das in manchen Browser-Kontexten
unterdrückt ist („Umbenennen funktioniert nicht").
- Reset (Debug-Knopf, non-prod) setzt nur noch das Beispiel-Dokument auf
INITIAL/„Example" zurück und verwirft Ansichts-/Sprach-/Update-Flags; alle
anderen Dokumente bleiben erhalten (vorher wurden pauschal alle werkbaum-*-
Schlüssel gelöscht).
i18n-Keys docDefaultName/docRenamePrompt entfallen (nicht mehr gebraucht).
D22 + frontend/CLAUDE.md nachgezogen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Editor kann jetzt mehrere Notationstexte halten und zwischen ihnen
umschalten. Der Name des aktiven Dokuments ersetzt die feste Beschriftung
„Struktur (Text)" und öffnet als Dropdown den Wähler mit Wechseln, Neu,
Umbenennen und Löschen.
- Datenmodell (noch kein Backend): Dokumente als [{id,name,text}] in
localStorage (werkbaum-docs), aktives per id in werkbaum-active; der
aktive Text bleibt zusätzlich in werkbaum-src gespiegelt.
- Migration verlustfrei: fehlt werkbaum-docs, wird der bestehende Einzeltext
(oder INITIAL) in ein Dokument gepackt. Reset und Löschen des letzten
Dokuments säen das Beispiel neu.
- Jedes Dokument ist nur Text + Name (kein Strukturformat, D14) —
vorwärtskompatibel zum geplanten Backend (D13). Ansichts-State (Modus,
Zoom, Aufteilung) bleibt global.
- i18n in allen 9 Sprachen; Doc-Namen bleiben Nutzerdaten (nicht übersetzt).
- Dokumentiert als ADR D22 (DECISIONS.md) + frontend/CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Letzter deutscher Rest im INITIAL-Beispiel entfernt, damit das
Standard-Diagramm ein breiteres Publikum anspricht.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Node 20 ist seit ~April 2026 End-of-Life. Node 24 "Krypton" ist der aktuelle
Active LTS und passt zur node24-Laufzeit der Actions.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GitHub erzwingt node24 für node20-Actions (Deprecation vom 2025-09-19). Die fünf
Pages-Actions auf ihren jeweils ersten node24-Major gehoben:
checkout v4->v5, setup-node v4->v5, configure-pages v5->v6,
upload-pages-artifact v3->v5, deploy-pages v4->v5.
Der Build-`node-version: 20` (für npm ci/test/build) ist davon unberührt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Die Erkennung hashte nur die ersten + letzten 300 Zeichen der Seite. Da der
Editor eine self-contained Datei ist (D19), liegen der gesamte App-Code UND die
Footer-Version als inline-Bundle in der Mitte — außerhalb des abgetasteten
Fensters. Anfang/Ende sind Build-übergreifend identisch, daher wurde eine neue
Version nie erkannt (nur die ETag änderte sich -> "Metadaten geändert, aber
Inhalt gleich").
- hashContent() (cyrb53) über den GESAMTEN Text als alleinige Wahrheit.
- ETag/Last-Modified-Vergleich entfernt: GitHub Pages liefert je Cache-Knoten
wechselnde ETags für identischen Inhalt und löste damit die irreführende
Metadaten-Meldung aus.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ohne gespeicherte werkbaum-lang wählt detectLang() die erste vom Browser
gemeldete Sprache (navigator.languages), für die eine Übersetzung existiert
(Primär-Subtag; de-AT->de, zh-Hans->zh), sonst Deutsch. Greift auch nach dem
Reset. Deutsch bleibt Quellsprache. Als D21 dokumentiert.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- [!]-Knoten trägt jetzt ein Warndreieck (⚠) an der oberen linken Ecke,
zusätzlich zur orangen Färbung — im Diagramm, im SVG/PNG-Export und
barrierefrei (aria-hidden, Status steckt im aria-label). Tooltip in allen
9 Sprachen.
- SPEC §4: [!]/highrisk-Status nachgetragen (war beim ersten Hinzufügen
übersprungen), inkl. Warndreieck-Kennzeichnung.
- Beispiel-PSP: Backend als High-Risk ([!]) markiert.
- Debug-Panel + Reset-Button nur außerhalb des Prod-Builds (isProdBuild via
VITE_BUILD_BADGE); im build:prod eliminiert esbuild den Zweig als toten
Code. Update-Check + Banner bleiben in allen Builds aktiv.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reset-Button gehört in den Header neben dem Fullscreen-Button,
nicht ins Debug-Panel.
Changes:
- Reset-Button (🔄) oben rechts neben Fullscreen-Toggle
- Benutzt gleiche Styling-Klasse (fsbtn) für Konsistenz
- Title: \"App auf Defaults zurücksetzen (für Testing)\"
- Debug-Panel vereinfacht (nur Log-Text, kein Button mehr)
Intuitivere Platzierung für Testing-Feature.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Reset-Button gehört ins Debug-Panel (Testing-Feature):
Changes:
- Debug-Panel erweitert mit flexiblem Layout (flex-column)
- 🔄 Reset-Button hinzugefügt (klickbar, hover-Effekt)
- ✕ Close-Button für Panel (zum Schließen)
- Bessere Styling: halbtransparente Buttons, klare Hover-States
Reset ist nur während Testing nötig — gehört ins Debug-Panel,
nicht in die Haupt-UI. Das 📦-Icon im Footer bleibt für
verfügbare Updates.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Statt Reset-Button im Footer:
- 📦-Symbol rechts neben Version (nur wenn Update verfügbar)
- Klick zeigt die Update-Benachrichtigung wieder an
- Hilft, wenn man den Banner auf \"Später\" verschoben hat
Features:
- Icon nur sichtbar wenn werkbaum-update-available Flag gesetzt
- Hover-Effekt: Icon wird größer (scale 1.2)
- Tooltip erklärt Funktion
- Auto-Update nach Benachrichtigung
Reset-Button entfernt (Nutzer wünscht sich das oben neben Fullscreen,
wenn überhaupt benötigt).
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Reset-Button war zu unauffällig (nur 🔄-Symbol).
Jetzt prominenter:
- Label: \"🔄 Reset\" statt nur 🔄
- Border: dünne Linie um den Button
- Hover-Effekt: Farbe ändert sich zu Petrol (#0F766E)
- Cursor zeigt es ist klickbar
Button sitzt im Footer zwischen Versionsnummer und Links.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Besseres Logging zum Verständnis von Cache-Verhalten:
- \"✓ Alles aktuell\" = Content + Headers gleich
- \"⚙ Metadaten geändert, aber Inhalt gleich\" = Headers unterschiedlich,
aber HTML-Inhalt identisch (nur Build-Metadaten/ETag geändert)
- \"✅ NEUE VERSION ERKANNT!\" = echter neuer Inhalt entdeckt
Hilft zu verstehen, ob GitHub Pages cacht oder ob wirklich
eine neue Version deployed wurde.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
HEAD-Request hat auf GitHub Pages zu Netzwerkfehlern geführt.
Vereinfachter Ansatz:
- Zurück zu einfachem GET-Request (statt HEAD)
- Cache-Busting via Timestamp: location.href + '?t=' + Date.now()
- ETag/Last-Modified Vergleich + Content-Hash Fallback
- Besseres Error-Logging: unterscheidet "Netzwerk/CORS" von anderen Fehlern
Robuster auf instabilen Netzwerk-Bedingungen (Smartphone).
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Neuer Button im Footer (🔄) zum Zurücksetzen aller Einstellungen:
Features:
- Löscht alle werkbaum-* localStorage-Einträge (Editor, Einstellungen, Update-Flags)
- Confirm-Dialog mit Warnung (Editor-Inhalt geht verloren)
- Reagiert auf alle Bildschirmgrößen
- Nach Confirm: kurze Verzögerung (Logging sichtbar), dann auto-reload
Hilfreich zum Testen:
- Update-Detection testen (Editor-Inhalt neu setzen)
- High-Risk-Status sehen (mit Reset auf Defaults und neuem Beispiel)
- Alle Einstellungen auf Default zurückbringen
Der Button sitzt unauffällig im Footer als 🔄-Symbol.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Problem: Nach Klick auf "Jetzt laden" wird die Seite neu geladen,
aber das werkbaum-update-available Flag bleibt in localStorage.
Beim Laden der neuen Version wird der alte Check noch vorhanden,
also wird der Banner wieder angezeigt (auch wenn die neue Version
schon da ist).
Lösung: Vor window.location.reload() das Flag löschen.
Damit nach dem Reload die neue Version sauber geladen wird.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Neue Debug-Features für Fehlersuche ohne Dev-Konsole:
- Update-Check alle 15 Sekunden (statt 60, für schnelleres Feedback beim Test)
- Logging in localStorage mit Zeitstempel
- Sichtbares Debug-Panel unten rechts (schwarz, Petrol-Rand)
* Zeigt die letzten 6 Update-Check-Einträge
* Klick zum Schließen
* Hilft ohne Browser Dev-Tools zu sehen, was passiert
Logging zeigt:
- ✅ Neue Version erkannt!
- ✓ Alles aktuell
- ⚠ Fehler: ... (falls Fetch fehlschlägt)
So kann Update-Detection auch auf Smartphone (ohne Dev-Konsole) debugged werden.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Service Worker mit Blob-URL funktionierte nicht zuverlässig (blob: Protocol
nicht registrierbar in einigen Browsern). Neue Lösung:
- Client-seitige Prüfung statt Service Worker
- Alle 60 Sekunden fetch() der index.html (mit Cache-Busting via Timestamp)
- Einfacher Hash-Check (erste + letzte 200 Zeichen des Content)
- localStorage speichert Hash zum Vergleichen
- Update-Flag wird gesetzt wenn sich Hash ändert
- Benachrichtigung nur wenn User aktiv ist (Page Visibility API)
- Erste Prüfung nach 3 Sekunden, dann alle 60 Sekunden
Viel zuverlässiger als der frühere SW-Ansatz. Funktioniert überall ohne Browser-Limit.
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Texte unter dem Titel angepasst, um Work Breakdown Structure (PSP/WBS) und
Lean Pathfinding gleich prominent zu zeigen. Feature-Tree nur erwähnt, wenn
Platz ist. Kurzversionen auf Mobile: „PSP · Lean Pathfinding Editor".
Alle 9 Sprachen angepasst (DE/EN/ES/FR/PL/RU/HI/ZH/JA).
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Service Worker prüft im Hintergrund auf neue Versionen (jede 5 Minuten)
- Update-Status wird in localStorage gespeichert
- Benachrichtigung erscheint nur wenn:
* User zur App zurückkommt (Page Visibility API)
* Oder beim initialen Laden wenn Update verfügbar
- "Später" Button zum Dismissieren, "Jetzt laden" für Reload
- Keine Browser-Permission nötig
- localStorage-Daten bleiben beim Reload erhalten
- Pragmatisch: User sieht Updates nur wenn er arbeitet
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Service Worker prüft periodisch auf neue Versionen (jede Minute)
- Bei verfügbarem Update: Benachrichtigung oben auf der Seite
- "Jetzt laden" Button triggert page reload
- Benachrichtigung verschwindet nach 30s oder bei Klick
- Service Worker als Blob registriert (Single-File-App kompatibel)
- localStorage-Daten bleiben erhalten beim Reload
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Rename variables to avoid conflicts with existing declarations
- Wrap ResizeObserver code in IIFE for local scope isolation
- Fixes build error: 'editorPanel' and 'legendBtn' already declared
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- ResizeObserver überwacht .editor-body Höhe
- Copy und Agenda Buttons werden versteckt wenn Body-Höhe < Head-Höhe
- Schwellwert: Buttons nur sichtbar wenn mindestens Titelzeilenhöhe Inhalt vorhanden ist
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Feste Höhe von 28px für .zoomctl (collapsed und expanded)
- Padding für .zoomToggle angepasst auf 4px 8px (gleich wie andere Buttons)
- SVG-Größe auf 16x16 optimiert
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Zoom-Controls collapse automatisch nach 3 Sekunden Inaktivität
- Toggle-Button mit Lupe+Plus-Symbol zum Expandieren der Controls
- Position weiter nach rechts-unten verschoben (6px)
- Event-Delegation für zuverlässige Click-Erfassung
- Lazy-Loading der DOM-Elemente für robuste Initialisierung
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Attached the `aria-labelledby` attribute to the editor textarea and added an ID to the editor title. Corrected the relative path for the script reference.
Removed redundant CSS fallbacks for mobile viewport height and replaced them with a streamlined `@supports` block to handle `dvh`-capable browsers. Clarified comments to reduce warnings and improve maintainability.
IBM Plex Sans and Mono are now embedded locally (`woff2`) under `src/fonts`, licensed under SIL OFL 1.1. Removed external `<link>` to Google Fonts for enhanced privacy and compliance. Updated `style.css` with `@font-face` and unicode ranges for `latin` and `latin-ext` subsets. Added license details to documentation.
"Claude Code" bleibt als Produktname unveraendert. Der Credit ist hartkodiert
(kein data-i18n) und damit wie zuvor sprachunabhaengig englisch — keine
Uebersetzungen betroffen.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DEPLOY_TARGET wird jetzt aus der .env im Repo-Wurzelordner gelesen (die von der
bestehenden .gitignore-Regel ohnehin ignoriert wird; Vite liest sie nicht, da
dessen Env unter frontend/ liegt). scripts/deploy.env(.example) entfaellt; neue
Vorlage .env.example im Wurzelordner. Argument hat weiterhin Vorrang, ~ bleibt
fuer die Remote-Seite erhalten (kein source).
.gitignore: eigene scripts/deploy.env-Zeile zurueckgenommen, Kommentar an der
.env-Regel ergaenzt. README (de/en) entsprechend aktualisiert.
Lokal verifiziert: Fallback liest aus Wurzel-.env, .env ignoriert, .env.example
getrackt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ohne Ziel-Argument liest das Skript DEPLOY_TARGET aus scripts/deploy.env
(git-ignoriert; Vorlage scripts/deploy.env.example ist eingecheckt). Argument
hat weiterhin Vorrang.
Der Wert wird bewusst NICHT via `source` gelesen, weil bash bei `host:~/pfad`
die Tilde nach dem ':' lokal expandieren wuerde; stattdessen roh ausgelesen,
Whitespace/CR + umgebende Quotes gestrippt, das ~ bleibt fuer die Remote-Seite
erhalten. Lokal verifiziert: Fallback greift, ~ bleibt in unquoted/single-/
double-quoted erhalten (kein lokales $HOME), Quotes entfernt.
.gitignore: scripts/deploy.env ergaenzt (die vorhandene .env-Regel greift wegen
des abweichenden Dateinamens nicht). README (de/en) aktualisiert; Beispielpfad
auf die htdocs-ssl-Direktaufschaltung umgestellt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rsync --filter='protect /.well-known/***' bewahrt am Ziel liegende
.well-known-Dateien (Let's-Encrypt-Challenge waehrend einer Erneuerung) vor dem
--delete, obwohl sie nicht in der Quelle liegen. Verhindert die Race Condition,
dass ein Deploy eine laufende Zertifikatserneuerung abraeumt. Bedient
Hostsharing die Challenge ausserhalb des Docroots, ist es ein No-op.
Lokal verifiziert: .well-known/acme-challenge/testtoken ueberlebt den Deploy,
eine sonstige Alt-Datei wird weiterhin per --delete entfernt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
mktemp -d legt das Staging-Verzeichnis mit 0700 an; rsync -a uebertrug diesen
Modus auf das Ziel-Verzeichnis, sodass der Webserver es nicht betreten konnte
(Apache 403 "Server unable to read htaccess file, denying access to be safe" —
die .htaccess-Suche selbst ist normal, der Zugriff scheiterte an den Rechten).
Fix: rsync mit --chmod=D755,F644, unabhaengig von lokalen mktemp-/umask-Rechten.
Lokal verifiziert: Ziel wird 755, Dateien 644 (auch wenn das Ziel vorher 700 war).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Im "Live ausprobieren"-Banner steht jetzt die stabile Prod-Instanz
https://werkbaum.javagil.de voran, der GitHub-Pages-Link bleibt als
"latest build 🚧" daneben. Der "gehosteter Editor"-Verweis im Fliesstext
zeigt ebenfalls auf die stabile Instanz. DE + EN.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Neues Skript scripts/deploy-prod.sh baut das badge-freie Prod-Bundle
(npm run build:prod), stellt es lokal wie der Pages-Workflow zusammen
(LICENSE danebenlegen + ../LICENSE-Link geradeziehen, Footer-Version +
Commit-Link) und spiegelt es per rsync --delete ueber SSH in ein als Argument
uebergebenes Zielverzeichnis — am Ziel bleibt nichts Altes stehen.
- Pflichtargument: rsync-Ziel (z. B. user@host:~/doms/.../subs-ssl/werkbaum/).
- Ohne -y erst --dry-run-Vorschau + Rueckfrage (--delete ist destruktiv).
- Warnt bei unsauberem Arbeitsbaum (Commit-Link zeigt auf HEAD).
- node_modules-Guard: npm ci nur wenn noetig.
End-to-End gegen ein lokales Ziel verifiziert: --delete raeumt Alt-Datei und
Alt-Unterordner weg, deployte index.html enthaelt 0x 🚧/🔧 (nur die ungenutzte
CSS-Regel), LICENSE danebengelegt + Link auf "LICENSE", Version 1.0.x + Commit.
Doku: README (de/en) Abschnitt Prod-Installation, DECISIONS D16 (warum die
sed-Zusammenstellung bewusst in Workflow UND Skript liegt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der sichtbare Abstand kam fast ganz vom internen Weißraum des Emoji-Glyphs
(~11px), nicht vom margin. margin-left auf -.5em gesetzt -> Abstand
Titelende->Badge von 12px auf 5px. Laufzeit-gemessen im Dev-Server.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Latest-Build-Hinweis wandert vom Workflow-sed in die App (app.js,
mountBuildBadge), damit ihn auch der Dev-Server zeigt — ein Post-Build-sed
erreicht den Dev-Server nicht. Logik umgekehrt: Hinweis ist der Normalfall,
nur die produktive Installation schaltet ihn ab.
Drei Zustaende ueber Vite-Env VITE_BUILD_BADGE (Auswertung in app.js):
- Dev-Server (import.meta.env.DEV) -> 🔧 "Vorschau/lokaler Entwicklungsstand"
- Default `npm run build` (Env ungesetzt) -> 🚧 "latest build"; der Pages-
Deploy nutzt den Default und traegt den Hinweis dadurch automatisch (die
sed-Injektion entfaellt).
- `npm run build:prod` (Vite-Modus prod, .env.prod: VITE_BUILD_BADGE=none)
-> KEIN Badge; esbuild eliminiert den Zweig als toten Code.
Verifiziert zur Laufzeit (Dev + `vite preview` auf beiden Builds): 🔧 im Dev,
🚧 im Default-Build, gar nichts im Prod-Build (Titel sauber "Werkbaum").
34 Vitest-Tests gruen, Workflow-YAML/Shell gueltig.
Doku: D16 fortgeschrieben (quellbasiert/env statt sed, Begruendung); README
(de/en) mit Prod-Build-Anleitung inkl. LICENSE-/Versions-Caveats; frontend/
CLAUDE.md; .claude/launch.json bekommt einen frontend-dist-Preview (vite
preview, Port 8138) zum Verifizieren gebauter Dateien.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Der Pages-Deploy ist der frischeste Entwicklungsstand und kann Fehler
enthalten; die stabile Instanz laeuft woanders. Damit nur diese
Veroeffentlichung markiert ist, injiziert der Workflow nach demselben Muster
wie Version/LICENSE — also NUR auf der Site-Kopie — hinter dem Titel (Anker
</h1>, im Bundle eindeutig) ein kleines Symbol mit zweisprachigem Tooltip
(<span class="build-badge">🚧</span>). Quelle bleibt unberuehrt: ein schlichter
`npm run build` erzeugt die Datei ohne Hinweis. Als Deploy-Metainfo bewusst
nicht im I18N-Objekt (D14). D16 fortgeschrieben.
Verifiziert gegen das echte dist-Bundle: Badge genau 1x, Version 1.0.x +
Commit-Link unveraendert, frontend/index.html traegt 0 Badges.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>