docs: Eigene Endung .werkbaum + fünf Beispieldateien unter docs/examples/

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>
This commit is contained in:
mhoennig
2026-07-27 12:43:43 +02:00
co-authored by Claude Opus 4.8
parent 4d0fb9edd7
commit cdf843e2e3
11 changed files with 283 additions and 12 deletions
+2
View File
@@ -0,0 +1,2 @@
# Notationstexte sind Text (LF im Repo), damit Diffs lesbar bleiben — D24.
*.werkbaum text eol=lf diff
+19 -6
View File
@@ -44,15 +44,24 @@ Der Editor kann seinen Notationstext über den Query-Parameter `sourceUrl` aus
einer externen Textdatei beziehen — praktisch zum Teilen eines Plans oder wenn
die Quelle in Git oder einem Wiki gepflegt wird:
**▶ [Live-Beispiel](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/example-plan.txt)**
— lädt [`docs/example-plan.txt`](docs/example-plan.txt):
```
https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/example-plan.txt
https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-0.werkbaum
```
(Das Beispiel zeigt auf den latest build 🚧; die stabile Instanz kann
`sourceUrl` ab ihrem nächsten Produktions-Deploy.)
Fertige Beispiele in [`docs/examples/`](docs/examples/) — **nacheinander
öffnen**: Jedes wird ein eigenes Dokument, danach lässt sich in der
Editor-Titelzeile zwischen allen umschalten:
| Beispiel | Zeigt |
|---|---|
| **▶ [0 · Online-Shop-Relaunch](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-0.werkbaum)** | ein Softwareprojekt mit allen acht Status |
| **▶ [1 · Neue Küche](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-1.werkbaum)** | ein Plan ohne Software, viele Alternativen — gut für den Günstigster-Pfad-Schalter |
| **▶ [2 · Community-Konferenz](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-2.werkbaum)** | ein breiter Plan mit vielen Beteiligten; horizontal vs. kompakt vergleichen |
| **▶ [3 · Drei Arbeitsstränge](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-3.werkbaum)** | mehrere Wurzeln = mehrere Bäume nebeneinander |
| **▶ [Werkbaum selbst](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-werkbaum.werkbaum)** | Bestand und mögliche Weiterentwicklung |
(Die Links zeigen auf den latest build 🚧; die stabile Instanz kann `sourceUrl`
ab ihrem nächsten Produktions-Deploy.)
Der geladene Text wird als **eigenes Dokument** geführt, dessen **Name die URL**
ist — eigene Dokumente bleiben unberührt, und derselbe Link aktualisiert dieses
@@ -60,6 +69,10 @@ eine Dokument, statt Kopien anzuhäufen. Die URL ist die Quelle der Wahrheit: Si
wird bei jedem Laden neu geholt, lokale Änderungen daran überleben ein Neuladen
also nicht.
Notationsdateien tragen die Endung **`.werkbaum`** (UTF-8; siehe `docs/SPEC.md`
§12 und D24) — Konvention, kein Vertrag: `sourceUrl` liest jede per http(s)
erreichbare Textdatei, unabhängig von Endung und Content-Type.
**Einschränkung — CORS:** Der Browser lädt fremde Hosts nur, wenn sie
`Access-Control-Allow-Origin` senden. `raw.githubusercontent.com` und
GitLab-Raw-Links tun das; ein beliebiger Webserver oft nicht. Scheitert das
+18 -5
View File
@@ -43,14 +43,23 @@ The editor can pull its notation text from an external text file via the
`sourceUrl` query parameter — handy for sharing a plan or keeping the source in
Git or a wiki:
**▶ [Live example](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/example-plan.txt)**
— loads [`docs/example-plan.txt`](docs/example-plan.txt):
```
https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/example-plan.txt
https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-0.werkbaum
```
(The example points at the latest build 🚧; the stable instance supports
Ready-made examples in [`docs/examples/`](docs/examples/) — **open them one
after another**, each becomes its own document, so afterwards you can switch
between all of them in the editor title bar:
| Example | Shows |
|---|---|
| **▶ [0 · Online shop relaunch](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-0.werkbaum)** | a software project with all eight states |
| **▶ [1 · New kitchen](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-1.werkbaum)** | a non-software plan, lots of alternatives — good for the cheapest-path toggle |
| **▶ [2 · Community conference](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-2.werkbaum)** | a wide plan with many people; compare horizontal vs. compact |
| **▶ [3 · Three workstreams](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-plan-3.werkbaum)** | several roots = several trees side by side |
| **▶ [Werkbaum itself](https://mhoennig.github.io/werkbaum/?sourceUrl=https://raw.githubusercontent.com/mhoennig/werkbaum/main/docs/examples/example-werkbaum.werkbaum)** | what exists today and where it could go |
(The links point at the latest build 🚧; the stable instance supports
`sourceUrl` from its next production deploy on.)
The loaded text becomes its own document whose **name is the URL**, so your own
@@ -58,6 +67,10 @@ documents stay untouched; the same link updates that one document instead of
piling up copies. The URL is the source of truth — it is re-fetched on every
load, so local edits to it do not survive a reload.
Notation files use the extension **`.werkbaum`** (UTF-8; see `docs/SPEC.md` §12
and D24) — a convention, not a contract: `sourceUrl` reads any text file over
http(s) regardless of extension or content type.
**Caveat — CORS:** the browser only fetches a foreign host if it sends
`Access-Control-Allow-Origin`. `raw.githubusercontent.com` and GitLab raw links
do; an arbitrary web server often does not. If loading fails the previous
+37
View File
@@ -428,3 +428,40 @@ Knoten-Link ohnehin nur `https?://…` (SPEC §1/§6) — kein `javascript:`-Vek
Nebenbefund: `checkForUpdates()` hängte den Cache-Buster als `location.href +
'?t=…'` an, was mit vorhandenem Query-String ein zweites `?` erzeugt hätte; es
baut die URL nun über `URL`/`searchParams`.
## D24 — Eigene Dateiendung `.werkbaum`
Notationstexte tragen die Endung **`.werkbaum`** (UTF-8, LF). Bislang lag das
einzige Beispiel als `.txt` — eine Endung, die nichts über den Inhalt sagt und
in einem Verzeichnis mit Notizen, Logs und Exporten untergeht.
**Begründung:** Die Endung macht Dateien maschinell und für Menschen
zuordenbar — Voraussetzung für spätere Editor-Zuordnung (Öffnen mit Werkbaum),
Syntax-Highlighting (VS Code/Vim-Modus, `*.werkbaum`) und ein künftiges
Öffnen/Speichern im Editor (dann als `accept`-Filter und Download-Endung).
Ausgeschrieben statt kurz, weil kurze Endungen belegt/mehrdeutig sind: `.wbs`
wird von diversen Projektplanungswerkzeugen und generisch für „Work Breakdown
Structure" benutzt, `.wb` ist ebenfalls mehrfach vergeben, `.tree` sagt nichts
über die Notation. Die Länge stört nicht: die Dateien werden selten getippt und
meist als URL geteilt.
**Kein registrierter MIME-Typ nötig.** Server liefern unbekannte Endungen als
`application/octet-stream` oder `text/plain` aus; für das Laden per
`?sourceUrl=` (D23) ist das gleichgültig, weil der Loader den `Content-Type`
**nicht** auswertet, sondern `response.text()` liest. Empfehlung für eigene
Server dennoch `text/plain; charset=utf-8`, damit die Datei im Browser lesbar
statt als Download erscheint. `raw.githubusercontent.com` liefert `.werkbaum`
als `text/plain; charset=utf-8` mit `Access-Control-Allow-Origin: *`.
**`.txt` bleibt zulässig** — die Endung ist Konvention, kein Vertrag. Der
Parser sieht ohnehin nur Text (SPEC §1), und `?sourceUrl=` lädt jede per
http(s) erreichbare Textdatei unabhängig von Endung und Content-Type. Es gibt
also keinen Bruch für bestehende Links.
**Beispieldateien liegen unter `docs/examples/`** (`example-plan-0…3.werkbaum`,
`example-werkbaum.werkbaum`) statt einzeln in `docs/`. Mehrere Beispiele, weil
sich das Umschalten zwischen Dokumenten (D22) erst mit mehreren *geladenen*
Dokumenten zeigen lässt: jeder `?sourceUrl=`-Link legt ein eigenes Dokument an
(id aus der URL, D23), nacheinander geöffnet stehen sie danach alle im Wähler.
`example-werkbaum.werkbaum` beschreibt Werkbaum selbst (Bestand + mögliche
Weiterentwicklung, destilliert aus ROADMAP/TASKS/DECISIONS) — zugleich
Beispiel und lebende Projektübersicht; bei größeren Änderungen mitpflegen.
+11
View File
@@ -293,3 +293,14 @@ Druckdialog „an Seite anpassen“ bzw. Querformat wählen.
- `#123` — Referenz auf externe Tickets (geplant für Taiga-Integration).
- `#tag` — freie Schlagworte (deshalb `#` nicht anderweitig verwenden).
## 12. Dateiendung
- Notationstexte tragen die Endung **`.werkbaum`**, Kodierung UTF-8,
Zeilenende LF. Beispiele: `docs/examples/*.werkbaum`.
- Die Endung ist **Konvention, kein Vertrag**: Der Parser sieht nur Text, und
das Laden per `?sourceUrl=` (§9) wertet weder Endung noch `Content-Type` aus.
`.txt` und endungslose Dateien bleiben damit gültig.
- Es gibt keinen registrierten MIME-Typ; wer selbst ausliefert, nimmt
`text/plain; charset=utf-8` (dann zeigt der Browser die Datei an, statt sie
herunterzuladen). Siehe D24.
@@ -1,4 +1,4 @@
%% Werkbaum example plan — meant to be loaded via ?sourceUrl=
%% Werkbaum example 0 — a software project, all eight states in one tree.
%% Full notation reference: docs/SPEC.md
[~] Online shop relaunch (XL) https://example.com/shop
+29
View File
@@ -0,0 +1,29 @@
%% Werkbaum example 1 — a plan that is not software at all.
%% Lots of alternatives: switch the cheapest-path button on and off.
[~] New kitchen (XL)
- [x] Budget and measurements (S) @sam
- [~] Layout (M)
- [x] Floor plan sketch (XS)
- [~] Where the appliances go (S) @kim
- [ ] Worktop (M)
| [ ] Laminate (S)
| [?] Solid oak (L)
| [?] Quartz composite (L)
| [-] Marble (XL) %% too soft for a kitchen, and way over budget
- [ ] Floor (M)
| [ ] Vinyl planks (S)
| [?] Tiles (M)
- [ ] Take out the old screed (S)
- [ ] Check the underfloor heating (XS)
- [!] Move the water connection (M) @kim %% no idea what that wall hides
- [ ] Electrics (L)
- [ ] Own circuit for the oven (M)
- [ ] Cable route (S)
- [ ] Free slot in the fuse box (XS)
- [ ] Sockets on the island (S)
- [?] Splashback (S)
- [ ] Assembly weekend (M) @sam @kim @dad
- [ ] Carcasses (S)
- [ ] Doors and drawers (S)
- [ ] Silicone joints (XS)
+46
View File
@@ -0,0 +1,46 @@
%% Werkbaum example 2 — an event: wide plan, many people, few alternatives.
%% Good for the horizontal mode; try the compact one for comparison.
[~] Community conference 2027 (XXL) https://example.org/conf
- [^] Save the date announced (XS) @lena
- [x] Venue (L)
- [x] Shortlist three halls (S) @lena
- [x] Site visit (S) @lena @tom
- [x] Contract signed (M)
- [x] Cancellation clause (S)
- [x] Deposit paid (XS)
- [~] Programme (XL) @maria
- [x] Call for papers (S) https://example.org/conf/cfp
- [~] Review (M) @maria @tom
- [x] Reviewer team (S)
- [~] Second round (S)
- [ ] Schedule (M)
- [ ] Tracks and rooms (S)
- [ ] Breaks that actually work (XS)
- [ ] Keynote (M)
| [ ] Ask the local research group (S)
| [?] Invite an international speaker (L) %% travel budget?
- [~] Sponsors (L) @ben
- [x] Package prices (S)
- [~] Approach last year's sponsors (M)
- [x] Mailing (XS)
- [~] Follow-up calls (S) @ben
- [ ] Logos on the website (XS)
- [ ] Catering (M)
| [ ] Buffet from the hall's caterer %% nobody has priced these two yet
| [?] Food trucks in the yard
| [-] Everyone brings something (S) %% not with 300 guests
- [ ] Website (M) @sam
- [x] Landing page (S)
- [ ] Ticket shop (M)
- [ ] Payment provider (S)
- [ ] Refunds and name changes (S)
- [ ] Schedule page (S)
- [!] Recording and streaming (L) @tom %% hall has no fixed technology
- [ ] On the day (L)
- [ ] Helper shifts (M)
- [ ] Registration desk (S)
- [ ] Room angels (S)
- [ ] Signage (S)
- [ ] Badges printed (XS) @lena
- [?] Social event in the evening (S)
+34
View File
@@ -0,0 +1,34 @@
%% Werkbaum example 3 — three trees side by side.
%% A line without a leading "-" or "|" starts a new root (SPEC §2), so one
%% document can hold several independent plans.
[~] Now: ship the mobile app (L)
- [x] Beta with 50 testers (S) @kim
- [~] Fix what the beta found (M)
- [x] Crash on rotate (S)
- [~] Slow start-up (S)
- [ ] Store listing (M)
- [ ] Screenshots (S)
- [ ] Privacy declaration (S)
- [!] App review, first submission (S) %% nobody knows how long this takes
[ ] Next: a second office (L)
- [ ] Pick the city (M)
| [ ] Leipzig (M)
| [?] Porto (L)
| [-] Zurich (XL) %% rents eat the whole budget
- [ ] Find rooms (M)
- [ ] Broker briefing (XS)
- [ ] Three viewings (S)
- [ ] Hire the first two people (L)
- [ ] Job ads (S)
- [ ] Interviews on site (M)
- [ ] Travel budget (XS)
- [ ] Interview guide (S)
[?] Someday: our own hardware (XXL)
| [?] Buy a white-label device and brand it (L)
| [?] Build it ourselves (XXL)
- [?] Board design %% no size yet — the cheapest path assumes M
- [?] Certification (L)
| [-] Licence the design to someone else (M) %% then it is not our product
+82
View File
@@ -0,0 +1,82 @@
%% Werkbaum, planned with Werkbaum — what exists today and where it could go.
%% Distilled from docs/ROADMAP.md, docs/TASKS.md and docs/DECISIONS.md.
[~] Werkbaum (XXL) https://github.com/mhoennig/werkbaum
- [^] Notation (L)
- [^] Line format (M)
- [^] Status box, eight states (S)
- [^] T-shirt size and the "decompose from M" rule (S)
- [^] People tags, bare URLs, %% comments (XS)
- [^] And/or decomposition (S)
- [-] A separate storage format for the structure (L) %% the text is the format
- [ ] Ticket references #123 (S)
- [?] Benefit per node, not only cost (M)
| [?] Another sigil next to the size (S)
| [?] Story points behind the T-shirt sizes (M)
- [~] Editor (XL) https://werkbaum.javagil.de
- [^] Live diagram from text (M)
- [^] Parser (S)
- [^] Renderer, three layout modes (M)
- [^] Horizontal fan (S)
- [^] Vertical, transposed (S)
- [^] Compact (S)
- [^] Cheapest path (M)
- [^] Cost model, missing size counts as M (S)
- [^] Metro-map line through the leaves (S)
- [^] Export (M)
- [^] SVG and PNG download (S)
- [^] PNG to the clipboard (S)
- [^] Print stylesheet (XS)
- [^] Nine interface languages (M)
- [^] Translations (S)
- [^] Default taken from the browser (XS)
- [^] Accessibility: aria labels, focus order (S)
- [^] Works on a phone (S)
- [x] Several documents in one editor (M)
- [x] Switcher in the editor title bar (S)
- [x] Load a document from ?sourceUrl= (S)
- [ ] Open and save .werkbaum files (S)
- [?] A pastel colour per person (S)
- [?] Dates and milestones (M)
| [?] An attribute in the line (S)
| [?] A separate timeline view (L)
- [^] Build and delivery (M)
- [^] One self-contained file, bundled by Vite (S)
- [^] Unit tests (S)
- [^] Published on every push (S)
- [-] Deploy through a gh-pages branch (S) %% GitHub Actions instead
- [-] Fonts from Google (XS) %% self-hosted, no third-party request
- [ ] Backend (XL)
- [ ] Kotlin and Spring Boot scaffold (M)
- [ ] Gradle Kotlin DSL, JDK 21 (S)
- [ ] Health endpoint and CI (S)
- [ ] Documents on the server (L)
- [ ] Text plus metadata, no structure format (M)
- [ ] REST endpoints (S)
- [ ] Persistence (S)
- [ ] Share by link (S)
- [?] Accounts and permissions (L)
| [?] Single user, one token (S)
| [?] Log in with OIDC (L)
- [?] Mermaid plugin (XL)
- [!] A layout engine of its own (XL) %% measure, place, route — the real work
- [ ] Measure node sizes (M)
- [ ] Text metrics without a browser (S)
- [ ] Badges and tags inside the box (S)
- [ ] Place nodes and route connectors (L)
- [ ] All-of fan (M)
- [ ] Horizontal (S)
- [ ] Transposed (S)
- [ ] Any-of rail (S)
- [?] Registration with Mermaid (M)
| [?] External diagram, self-hosted pages only (M)
| [?] Pull request into Mermaid itself (L)
- [?] Tracker integration (XL)
| [?] Taiga (L) https://taiga.io
- [ ] Resolve #123 over the REST API (M)
- [ ] Read title, link and status (S)
- [ ] Map the workflow onto the states (S)
- [?] Write the status back (M)
- [-] A plugin inside Taiga itself (L) %% legacy frontend, self-hosted only
| [?] Tenzu, the successor (XXL) https://tenzu.net
| [ ] No tracker, plain text is enough (XS)
+4
View File
@@ -121,6 +121,10 @@ verworfene Elemente. Quelle sind ES-Module unter `src/`; `index.html` ist der
ja, beliebiger Webserver oft nicht) — der Warntext nennt das ausdrücklich.
`updateDocName()` setzt für solche Dokumente den vollen URL-Tooltip und muss
deshalb **nach** dem `data-i18n-title`-Durchlauf in `applyLang()` laufen.
Weder Endung noch `Content-Type` werden geprüft (`response.text()`); die
Endung `.werkbaum` ist reine Konvention (D24, SPEC §12). Beispieldateien zum
Ausprobieren: `docs/examples/*.werkbaum` (nacheinander geöffnet ergeben sie
mehrere Dokumente im Wähler).
- Kleiner Bildschirm: `body.mobile` (per `matchMedia`, ≤ 640 px) stapelt
Diagramm/Editor mit **stufenlosem** Splitter (kein Snap/Collapse wie auf
Desktop): der Gutter-Drag ruft `setMobileDrow()` (klemmt `--drow` zwischen den