Der Hintergrund-Takt aus dem letzten Commit funktionierte in der Praxis nicht:
im Netzwerk-Mitschnitt stapelten sich Anfragen und wurden abgebrochen
("cancelled"). Die Ursache ist nicht Langsamkeit, sondern ein Rate Limit —
Etherpads `importExportRateLimiting` ist serienmäßig an und lässt 10 Abrufe je
90 s und IP zu; der Takt wollte 36. Jenseits davon antwortet die Gegenseite
nicht mit 429, sondern hält die Verbindung ohne Antwort offen. Nachgemessen:
12:48:12 Abbruch nach 25 s (0 Bytes)
Abbruch nach 25 s (0 Bytes)
12:50:23 HTTP 200 nach 0,436 s <- nach ~40 s Pause
Zwei Minuten totgestellt, dann sofort in 0,4 s da. Gegen eine Drosselung kann
ein Takt nicht gewinnen, er erzeugt sie. Also ein Knopf. Damit entfallen
Stabilitätstakt, Sichtbarkeits-Wächter, Anti-Stapel-Riegel und Wiederanlauf.
Der Knopf greift zudem gut mit "Was ist neu?" (D28) zusammen: drücken, und was
seither in Produktion ging, leuchtet auf.
Verhindern UND melden, beides:
- Mindestabstand 10 s zwischen zwei Abrufen. Das ergibt höchstens 9 je 90 s und
bleibt damit beweisbar unter Etherpads Budget — die Drosselung wird gar nicht
erst ausgelöst. Nach einem Abbruch sind wir schon drüber: dann das ganze
Fenster (90 s) abwarten statt weiter dagegen zu rennen.
- Der Knopf bleibt in der Sperre **klickbar** (nur `aria-disabled`, nicht
`disabled`): Ein Klick meldet den Grund und nennt die Grenze samt Restzeit.
Die Meldung landet in `#warn`, das eine Live-Region ist, wird also angesagt.
Ein `disabled` erklärt nichts.
- Eigener Warnungstyp `sourceTimeout` für den Abbruch: `sourceLoad` zeigt auf
CORS und schickte hier auf die falsche Fährte.
- `setPadBusy()` dreht das Symbol während des Abrufs — das können bis zu 20 s
sein, und ohne Zeichen wirkt der Knopf kaputt.
Zwei Fehler des Vorgänger-Commits fielen dabei auf:
- `padSource` und der Takt standen HINTER dem `await` des ersten Abrufs. Ein
einziger Fehlschlag — bei dieser Gegenseite der Normalfall — ließ das Dokument
tot liegen, ohne Knopf und ohne Wiederversuch, bis zum Neuladen der Seite.
Genau das war die vom Nutzer gemeldete Fehlermeldung.
- Kein Erfolg räumte die Warnung des ersten Versuchs weg; sie hätte gestanden,
während der Text längst da war.
Dazu: `deleteDoc()` beendet die Pad-Quelle, sonst legte ein späterer Abruf das
gelöschte Dokument wieder an und aktivierte es auch gleich.
Nebenbefunde, beide nachgemessen und in D31 festgehalten:
- Das *Tippen* im Etherpad-Editor war der letzte offene Punkt. Der Nutzer hat
` - [ ] Layout` eingerückt eingetippt; der Export gibt es zeichengenau
zurück (vier echte Leerzeichen, kein Tab, kein Listen-Markup).
- Einbetten verweigert der Server nicht: kein `X-Frame-Options`, keine CSP mit
`frame-ancestors`, und im Versuch baute das Pad in einem fremdstämmigen Rahmen
seine Editorframes auf. Preis ist `SameSite=Lax` am Autoren-Cookie (jedes
Laden ein neuer Autor; nur serverseitig zu beheben) und der Verlust beider
Richtungen von D25, falls das Textpanel ersetzt wird.
86 Tests (85 -> 86); Schreibschutz zeigt den Text jetzt in Tinte statt grau —
hier wird gelesen, der Plantext ist der Hauptinhalt.
Werkbaum hat kein Backend, und das eigentlich Schwere an gemeinsamem
Bearbeiten ist das Zusammenführen gleichzeitiger Änderungen — im Plan als
`[!] Merging simultaneous edits` markiert. Etherpad hat das gelöst. Also
geliehen statt nachgebaut: das Pad ist die Schreibfläche, Werkbaum die
Ansicht.
Nachgemessen an pad.hostsharing.net, bevor irgendwas gebaut wurde:
- der Klartext-Export sendet `Access-Control-Allow-Origin: *`,
- das kanonische Beispiel (SPEC §10) kommt byte-identisch zurück,
- der HTML-Export zeigt kein Listen-Markup — Etherpad deutet `-` nicht zur
Aufzählung um und behält die führenden Leerzeichen.
Das war das Risiko, das die Idee hätte erledigen können. Nicht geprüft ist
das Tippen im Etherpad-Editor selbst (Tab-Einrückung, mögliches
Auto-Bullet); dafür braucht es einen echten Browser.
Eigener Parameter statt `?sourceUrl=`: Die URL, die ein Mensch in der Hand
hat, ist die Pad-URL — `/export/txt` hängt Werkbaum selbst an. Vor allem
aber lizenziert der eigene Parameter das andere Verhalten, sodass D23
unangetastet bleibt: `sourceUrl` heißt weiter „statische Datei, einmal pro
Laden geholt", bestehende Links bekommen kein Polling. Name und id sind die
vollständige Pad-URL (Pad-Namen sind nur pro Instanz eindeutig).
Textfeld schreibgeschützt, Knopf öffnet das Pad: ohne das verschwände
getippter Text beim nächsten Abruf. Schrift bleibt Tinte statt grau — hier
wird gelesen, der Plantext ist der Hauptinhalt.
Drei Riegel im Takt, jeder aus einem echten Fehler:
- `padBusy` — im Netzwerk-Mitschnitt stapelten sich die Abrufe, weil die
Gegenseite langsamer war als der Takt; eine spät eintreffende alte
Antwort hätte neueren Text überschrieben,
- Abbruch nach 10 s — sonst bliebe der Riegel bei hängender Gegenseite für
immer zu,
- `visibilityState` + `visibilitychange` — nicht im Hintergrund abrufen,
aber bei Rückkehr sofort.
Der Stabilitätstakt übernimmt erst beim zweiten gleichen Abruf, sonst sieht
man die anderen mitten im Tippen.
Die Normalisierung der Pad-Adresse liegt headless in `remote.js`, damit sie
testbar ist (23 neue Tests, 60 -> 83). Im Vorschau-Browser meldet
`visibilityState` „hidden" und HMR lädt bei jeder Quelländerung neu — ein
Reload sieht wie eine geglückte Übernahme aus; nachgewiesen wurde die
Übernahme deshalb mit einem Marker auf `window`, der einen Reload nicht
überlebt.
SPEC §9 zuerst, dann D31, dann Code. Der Plan bekommt den Knoten nach D30
mit `[x]`, nicht `[^]`.
Der mitgelieferte Werkbaum-Plan behauptete [^] für Funktionen, die nur auf der
automatisch deployten Pages-Instanz lagen, nicht auf werkbaum.javagil.de
(manueller Deploy, D16). Ausgerechnet das Dokument, das den Stand beschreiben
soll, war ungenau — und „Was ist neu?" (D28) meldete Dinge als live, die es
dort nicht waren.
Die Unterscheidung gibt es längst: SPEC §4 trennt [x] fertig von [^] in
Produktion. Der Plan hat sie für sich selbst nie benutzt. Konvention ab jetzt:
beim Mergen [x], der Deploy befördert — nur er weiß, wann die Aussage wahr wird.
- scripts/promote-shipped.sh schreibt Statusboxen am Zeilenanfang von [x] auf
[^] und hält das als eigenen Commit fest (-n zeigt nur, -y ohne Rückfrage).
Bricht ab, wenn die Plandatei uncommittete Änderungen hat; committet nur
diesen einen Pfad; pusht nicht.
- deploy-prod.sh ruft es als Schritt 0 auf (--no-promote schaltet es ab) und
warnt, wenn HEAD noch nicht auf origin liegt — der Footer-Versionslink zeigt
sonst auf einen Commit, den GitHub nicht kennt.
Warum ein Commit und kein Rewrite beim Bauen: Ein Rewrite macht GENAU EINE
Installation ehrlich; Pages untertriebe dauerhaft und die Neu-Anzeige wäre dort
für immer stumm. Der Commit wird von beiden Pipelines gesehen (Pages beim Push,
prod beim rsync), das Artefakt bleibt inhaltsgleich mit dem Repo — die
vorhandenen sed-Regeln (D16) fassen nur Pfade und Version an, Infrastruktur,
kein Rewrite dessen, was das Dokument aussagt. Außerdem Präzedenzfall D16:
VERSION per bewusstem Bump-Commit, „vollständig aus dem Repo reproduzierbar".
Einmalige Nachholung, exakt statt geschätzt: Der Footer der stabilen Instanz
verlinkt den deployten Commit (4061362); alles danach ist dort nicht drin. Es
sind GENAU ZWEI Knoten — „Optional nodes" (D29) und „Show what is new since
your last visit" (D28) —, nicht das Dutzend, das ich vorher grob geschätzt
hatte. Beide stehen jetzt auf [x] und leuchten beim nächsten Prod-Deploy als
neu auf. Eine Demotion [^]→[x] löst kein Falschleuchten aus: freshProdSet
meldet nur Knoten, die JETZT [^] sind (test-abgedeckt).
Umfang: nur example-werkbaum.werkbaum. Die übrigen Beispieldateien sind
erfunden und sagen nichts über ein Deployment aus.
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>
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.
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>
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 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>
Erster Schritt der Modularisierung (ROADMAP „tragfähige Codebasis",
TASKS Phase 1). Der bisher einzelne index.html-Prototyp wird zur Vite-App:
- CSS -> src/style.css, gesamtes JS -> src/app.js (noch als ein Modul;
Parser/Renderer werden in den folgenden Checkboxen herausgelöst).
- index.html ist der Vite-Entry (<script type="module" src="/src/app.js">).
- npm run build (vite + vite-plugin-singlefile) inlint JS+CSS+Favicon (als
data:-URI) in EINE self-contained dist/index.html -> bleibt file://-tauglich.
- Vitest als Testrunner eingerichtet (tests/, passWithNoTests bis Schritt 2/3).
- Pages-Workflow: Node + npm ci + npm test + npm run build, deployt dist/;
Favicon-sed entfällt (inline), nur ../LICENSE + Footer-Version bleiben.
- .claude/launch.json auf Vite-Dev-Server (Port 8137) umgestellt.
Entscheidung als D19 dokumentiert (weicht D11 „kein Build-Zwang" bewusst auf,
hält aber D16 file://-Versprechen über die gebündelte Datei). README (de/en)
und frontend/CLAUDE.md um Dev-/Build-/Test-Workflow ergänzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Im Footer sind "Werkbaum" und die Versionsnummer jetzt zwei Links:
- "Werkbaum" -> Repo-Startseite (wie bisher).
- Versionsnummer (<a class="ver">) -> exakt der deployte Commit.
CI setzt beim Build sowohl den Versionstext als auch den href der
ver-Anchor: COMMIT_URL=.../commit/$(git rev-parse HEAD); zwei gezielte
seds (href + Text). Lokal zeigt die Version "1.0" und verlinkt die
Commits-Uebersicht als Fallback.
Verifiziert: YAML gueltig; Trockenlauf ersetzt href -> commit/<sha> und
Text -> 1.0.7, "Werkbaum"-Link unveraendert. Preview lokal: Name -> Repo,
Version -> /commits/main.
Doku: README (EN+DE) Deployment + DECISIONS D16 ergaenzt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Micro-Version jetzt commit-basiert statt aus github.run_number:
- Major.Minor in neuer Datei VERSION (per Bump-Commit gepflegt).
- Micro = Commits seit dem letzten VERSION-Bump
(git rev-list --count <VERSION-Commit>..HEAD) -> beginnt nach einem
Bump wieder bei 0 (SemVer-artig, z. B. 1.0.0, 1.0.1, dann 1.1.0).
- checkout mit fetch-depth: 0 (flacher Klon zaehlte sonst nur 1 Commit).
- sed ersetzt jetzt ">Werkbaum <ziffern></a>" (regex), damit auch nach
einem Major/Minor-Bump im Quelltext getroffen wird; viewport-/xml-1.0
bleiben unberuehrt.
Vorteil ggue. Run-Nummer: vollstaendig aus dem Repo reproduzierbar,
zaehlt keine fehlgeschlagenen/manuellen Laeufe, kein Rueckschreiben.
Doku: README (EN+DE) Deployment-Abschnitt und DECISIONS D16 aktualisiert.
Keine SPEC-Aenderung (Notation unberuehrt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Beim Site-Build ersetzt der Workflow ">Werkbaum 1.0</a>" durch
">Werkbaum 1.0.${{ github.run_number }}</a>" (per sed, nur auf der
Site-Kopie). Die Micro-Version steigt so bei jedem Deployment monoton
um 1 — ohne Commit/Tag zurueck ins Repo und ohne selbstausloesenden
Deploy-Zyklus. run_number via env BUILD_VERSION injiziert. "1.0" bleibt
die manuell gepflegte Basis und die Version beim lokalen Oeffnen; die
viewport-/xml-"1.0" bleiben unberuehrt (Anker >...</a> als Ziel).
Doku: README (EN+DE) Deployment-Abschnitt und DECISIONS D16 ergaenzt.
Keine SPEC-Aenderung (Notation unberuehrt).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auf Wunsch ist die englische Fassung jetzt die Haupt-README.md; die
deutsche Fassung liegt als README.de.md. Sprachlinks oben in beiden
Dateien angepasst. Der Hinweis in README.md stellt klar, dass die
ausfuehrliche Doku unter docs/ weiterhin auf Deutsch gepflegt wird.
Screenshot der laufenden App (docs/screenshot.png, headless Chrome gegen
den lokalen Dev-Server) im Abschnitt Usage/Nutzung eingebunden.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Deutsch bleibt Quellsprache (CLAUDE: "Doku auf Deutsch"), daher die
Uebersetzung als separate README.en.md statt README.md zu ersetzen.
Wechselseitige Sprachlinks oben in beiden Dateien; Hinweis in der
englischen Fassung, dass sie eine Convenience-Uebersetzung ist und der
deutschen Vorlage hinterherhaengen kann.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Offizieller Actions-Weg (upload-pages-artifact + deploy-pages) mit
permissions pages/id-token und concurrency-Gruppe "pages"; Trigger:
Push auf main + workflow_dispatch. Vitest-Step als Platzhalter
auskommentiert (Tests folgen, TASKS.md Phase 1).
Site-Aufbau: frontend/index.html an die Wurzel-URL, dazu docs/brand/
(Favicon) und LICENSE (MIT-Link im Footer). Die ../-Pfade der Quelle
zeigten von der Wurzel aus über die Site hinaus; statt den Editor zu
aendern, zieht der Workflow sie nur auf der Site-Kopie per sed gerade
(Editor-Quelle bleibt unveraendert, lokal weiter nutzbar). backend/
und uebrige docs/ werden nicht veroeffentlicht.
Doku: README-Abschnitt "Deployment" (inkl. einmaliger Settings-
Umstellung auf Source "GitHub Actions", Repo muss oeffentlich sein),
TASKS.md-Rubrik "Deployment" abgehakt, DECISIONS D16. Hinweis: der
Auftrag nannte "D15", das war aber schon fuer den kompakten Modus
vergeben -> als D16 angelegt.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>