Commit Graph
372 Commits
Author SHA1 Message Date
mhoennigandClaude Opus 5 1a33ebdac8 feat(taiga): Ticket verknüpfen — URL/Ref-Feld mit Betreff-Bestätigung (D91-Nachtrag 11)
Ein Knopf im Knoten-Fenster bindet ein bestehendes Taiga-Ticket an den
Knoten: Die eingefügte Ticket-URL trägt Slug, Typ und Nummer selbst; eine
nackte Nummer wird per Probe Story-dann-Task aufgelöst. Verknüpft wird erst
nach Anzeige des Betreffs; geschrieben werden Ref-Token und ggf.
&taiga.<slug> in einem Undo-Schritt, der geholte Stand füllt den
Ticket-Cache. Eine URL einer fremden Instanz wird benannt statt verknüpft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 12:48:32 +02:00
mhoennig ce657e74c1 docs: Werkbaum-Plan — 3 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #trk.bulk: Diverging tickets show up in the diagram (M) :#trk.resolve.read
- #trk.bulk.proxy: One request fans out into by_ref queries server-side
- #trk.bulk.mark: A diverging ref turns amber on its node
2026-08-28 11:44:42 +02:00
mhoennigandClaude Opus 5 a1e4a3bbab feat(taiga): Bulk-Abfrage und Abweichungs-Marke — das Diagramm zeigt, wo Ticket und Plan auseinanderlaufen (D91-Nachtrag 10, SPEC §9)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 11:44:33 +02:00
mhoennig e77a4d1ce4 docs: Werkbaum-Plan — 1 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #trk.create.task: A dialog-free "create task" under a story ancestor (S) :#trk.create.tasks,#trk.resolve.read
2026-08-28 11:08:26 +02:00
mhoennigandClaude Opus 5 0ed30e9eae feat(taiga): Anlage-Knöpfe neu geschnitten — ein Story-Knopf mit Dialog, dialogfreie Task unter einem Story-Vorfahren (D91-Nachtrag 9)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 11:08:13 +02:00
mhoennig 4f6d45045a docs: Werkbaum-Plan — 1 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #trk.write: Write the status back (M) :#trk.resolve
2026-08-27 22:20:45 +02:00
mhoennigandClaude Fable 5 323e8fe0ba feat(taiga): Status zurückschreiben — zwei Knöpfe, niemand gewinnt von selbst (D91-Nachtrag 8, SPEC §9)
Weicht der Ticket-Status von der Statusbox ab, markiert das Knoten-Fenster
die Abweichung und bietet beide Richtungen ausdrücklich an.

- „nach Taiga schreiben": Spalte des Projekts suchen (Taiga schreibt nach Id,
  die Namen sind je Projekt frei) und mit der zuletzt GELESENEN `version`
  patchen — hat jemand dazwischen geändert, lehnt Taiga ab und der Text steht
  im Fenster, statt dass etwas überschrieben wird.
- „aus Taiga übernehmen": `setStatusBox()` schreibt die Box in die Textzeile,
  undo-fähig wie jede andere Änderung.
- Schreibbar sind nur die fünf abgebildeten Zustände; `[?]`, `[!]`, `[-]` und
  der neutrale Knoten lassen das Ticket unangetastet — mit Begründung im
  Fenster.
- Proxy: zwei Spaltenlisten (`/taiga/{userstory,task}-statuses?slug=`) und
  zwei Schreib-Endpunkte (`PATCH …/{ref}/status?slug=`); die Zielspalte wählt
  der Editor, das Backend parst die Notation nicht (D14).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 22:18:52 +02:00
mhoennigandClaude Fable 5 4e6f98bbee docs: Status-Rückschreiben festgelegt — zwei Knöpfe statt einer Richtung, nur die fünf abgebildeten Zustände (D91-Nachtrag 7, SPEC §11)
Die offene Frage von #trk.write ist entschieden, gebaut ist nichts: Weicht
der Ticket-Status von der Statusbox ab, wird die Abweichung markiert und mit
zwei ausdrücklichen Aktionen angeboten — nichts geschieht von selbst.
Verworfen sind „der Text gewinnt" (schreibt selbsttätig in ein fremdes,
geteiltes System) und „Taiga gewinnt" (schriebe fortlaufend im Notationstext,
gegen D14); „Zeitstempel entscheidet" ist ohne erfundene Metadaten gar nicht
baubar.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 22:00:20 +02:00
mhoennig 990632ddcf docs: Werkbaum-Plan — 1 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #trk.resolve.read: Read title, link and status
2026-08-27 20:43:09 +02:00
mhoennigandClaude Fable 5 842e89795a feat(taiga): Ticket-Stand im Knoten-Fenster — gelesen, nie geschrieben (D91-Nachtrag 6, SPEC §9)
Wo eine Ref steht und ein `&taiga.<slug>` gilt, zeigt das Knoten-Fenster
Betreff, Status und Zuständigen des Tickets; Taigas Statusname steht neben
der Statusbox der Notation (`In progress → [~]`).

- Proxy: zwei benannte Lese-Endpunkte (`GET /taiga/userstories/{ref}` und
  `…/tasks/{ref}`, je `?slug=`) — das Präfix der Ref trägt den Typ, Taiga
  hat getrennte `by_ref`-Endpunkte. Erst `/projects/by_slug`, dann `by_ref`
  (eine Ref ist nur je Projekt eindeutig); der Slug wird kodiert angehängt.
- Die Abbildung Status → Statusbox liegt im Editor (`mapTaigaStatus`,
  headless): Statuscodes sind Notation, das Backend parst sie nicht (D14).
  Unbekannte Namen bleiben unabgebildet — Raten hieße, dem Knoten eine
  Aussage zu geben, die niemand gemacht hat.
- Geholt wird erst nach 400 ms Verweilen und je Ticket einmal je Sitzung
  (↻ holt neu); ohne Anmeldung gar nicht — der Knopf meldet erst an.
- Nichts wird geschrieben: kein Text, keine Statusbox (das bleibt
  `#trk.write`).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 20:41:21 +02:00
mhoennig e58f71bf90 docs: Werkbaum-Plan — 2 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #trk.create: Create tickets from nodes
- #trk.open: Open a ticket ref in Taiga (S) :#trk.create.ref,#not.tag.project
2026-08-27 17:30:33 +02:00
mhoennigandClaude Fable 5 eae2ff1ef0 docs: D91-Nachtrag 5 — Ref-Umbruch und Strg+Klick-Öffnen festgehalten; #trk.create bestanden, #trk.open im Plan
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 17:28:36 +02:00
mhoennigandClaude Fable 5 a22c320909 feat(editor): Strg+Klick öffnet eine Ticket-Ref in Taiga (D91, SPEC §9)
Im Text (freistehendes #US-123/#T-1234, D67-Ausschlüsse) wie auf dem
Knoten; das Knoten-Fenster trägt an Refs einen Öffnen-Knopf — der Weg
auf Touch. Adresse aus taigaWeb (/info) + &taiga.slug-Vererbung; in
einem :#…-Token gewinnt weiter der Abhängigkeits-Sprung.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 17:24:20 +02:00
mhoennigandClaude Fable 5 55cade1a65 feat(backend): /info meldet die Taiga-Web-Basis für Ticket-Links (D91)
WERKBAUM_TAIGA_WEB_URL (das Taiga-Frontend, nicht aus der API-URL
ableitbar) kommt als taigaWeb in GET /api/v1/info — ohne Schrägstrich am
Ende, fehlt unkonfiguriert. deploy-backend.sh zieht die Zeile aus der
lokalen .env idempotent in die Server-Umgebung nach.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 17:19:02 +02:00
mhoennigandClaude Fable 5 83eb6ff77f fix(diagram): Ticket-Refs im Label brechen nicht mehr am Bindestrich um (SPEC §9)
Der Browser bricht eine zu breit geratene Zeile an jedem Bindestrich —
aus #US-123 wurde #US-/123 über zwei Zeilen. Eine tref-Spanne mit
white-space:nowrap hält das Token zusammen; labelLines() (Export) misst
ihre Textknoten unverändert mit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 17:14:27 +02:00
mhoennig 3f336db680 docs: Werkbaum-Plan — 7 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #not.tag.project: (&taiga.slug) assigns the Taiga project, inherited
- #trk.create.proxy: Backend proxy with named endpoints
- #trk.create.login: Log in to Taiga, token stays in the browser (S) :#trk.create.proxy
- #trk.create.project: The project comes from the inherited tag (S) :#not.tag.project
- #trk.create.story: A "create story" action in the node window (S) :#trk.create.login
- #trk.create.tasks: Sub-packages become tasks, picked in a dialog (M) :#trk.create.story
- #trk.create.ref: The ref lands in the line beside the id (S) :#trk.create.story
2026-08-27 16:54:26 +02:00
mhoennigandClaude Fable 5 3ab931d50e docs: D91-Nachtrag 4 — Bau-Entscheidungen der Taiga-Anlage festgehalten
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:51:55 +02:00
mhoennigandClaude Fable 5 d1de8758b1 feat(editor): Taiga-Story und -Tasks aus dem Knoten-Fenster anlegen (D91, #trk.create)
Zwei Aktionen im Knoten-Fenster, nur wo GET /info das Feature meldet
(Lebendprobe-Muster, je Basis einmal gecacht) und nur an Knoten ohne
Ticket-Referenz — die Ref an der Zeile ist der Idempotenz-Marker.
Login-Dialog (type=password, kein window.prompt; nur das Token landet
im Browser, 401 fragt neu), Projekt-Dialog vorbelegt aus dem geerbten
&taiga.<slug>, Häkchen-Dialog nach der D91-Vorbelegung; Refs und ggf.
das Projekt-Schlagwort gehen undo-fähig als Tokens an die Zeilen
(appendToken: vor %% und vor der Fortsetzungsmarke). Regeln headless in
taiga.js (15 neue Tests); Deploy zieht TAIGA_API_URL aus der .env als
WERKBAUM_TAIGA_API_URL in die Server-Umgebung nach (Nutzerwunsch).

E2E im Browser gegen Backend + Taiga-Stub gemessen: Buttons nur ohne
Ref, Vorbelegung Kundenprojekt aus geerbtem Tag, Refs #US-/#T- an den
richtigen Zeilen, Erledigtes uebersprungen, abweichende Projektwahl
schreibt &taiga.mi-intern zurueck, Undo/Redo je Schreibzug, falsches
Passwort bleibt als Taiga-Fehlertext im Dialog.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:51:10 +02:00
mhoennigandClaude Fable 5 fd0e730656 feat(backend): Taiga-Proxy — vier schmale Endpunkte, Ziel-URL aus der Server-Konfiguration (D91, #trk.create.proxy)
API First: /taiga/auth, /taiga/projects, /taiga/userstories, /taiga/tasks
in der OpenAPI-Spec; TaigaClient/TaigaProperties in
de.werkbaum.integration.taiga. Die API-URL kommt aus
WERKBAUM_TAIGA_API_URL (nie Request-Parameter — SSRF), das Token je
Aufruf im Header X-Taiga-Token (Authorization muessen OpenAPI-Werkzeuge
als Header-Parameter ignorieren) und geht als Bearer hinaus; der Server
speichert nichts und loggt keine Request-Bodies. Taiga-4xx werden samt
_error_message durchgereicht, 5xx/Netz sind 502, unkonfiguriert 503 —
und GET /info meldet das Feature (taiga). Tests gegen aufgezeichnete
Antwortformen auf einem JDK-HttpServer-Stub (statt WireMock: keine neue
Test-Abhaengigkeit, dieselbe Zusicherung); Gegenprobe: ohne den
type-Durchreich faellt genau der benannte Test. check gruen, 93 %
Coverage.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:33:35 +02:00
mhoennigandClaude Fable 5 5a18505571 feat(notation): Schlagworte &tag gebaut — taiga.<slug> benennt das Projekt je Teilbaum, vererbt (SPEC §1, D91)
SPEC zuerst: §1 Schritt 5b samt Block und Referenz-Regex, §11 auf
'umgesetzt' umgestellt; llms.md nachgezogen. Parser extrahiert
alleinstehende &-Token als node.marks (Zitier-Konvention gilt),
taigaSlugs() in model.js vererbt das taiga.*-Schlagwort wie die
@-Tags beim Engpass. Sichtbar im Tooltip und aria-label (a11yMarks,
9 Sprachen). Plan-Labels mit &-Erwähnungen eingeklammert; 12 neue
Tests, Gegenprobe: ohne Alleinstehend-Anker fallen genau die zwei
Zitier-Tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 16:20:03 +02:00
mhoennigandClaude Fable 5 c712e81970 docs: Mehrprojekt-Pläne — &taiga.slug erbt je Teilbaum, erster &tag-Konsument (D91-Nachtrag 3, SPEC §11)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 14:48:03 +02:00
mhoennigandClaude Fable 5 4c98ec6603 docs: Ticket-Ref zusätzlich zur Knoten-ID, Präfixe US-/T- festgelegt (D91-Nachtrag 2, SPEC §11)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 14:37:08 +02:00
mhoennigandClaude Fable 5 ac484f8104 docs: Taiga-Zielinstanz vermessen — API-Host, ldap-Auth, offenes CORS, OIDC-Vormerker (D91-Nachtrag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 14:31:49 +02:00
mhoennigandClaude Fable 5 6bbc91e849 docs: Ticket-Anlage aus Knoten festgelegt — Proxy, zwei Aktionen, Häkchen-Dialog (D91, #trk.create)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 14:16:41 +02:00
mhoennigandClaude Fable 5 e3742feffb feat(diagram): Unassigned-Pille zeigt das Sprach-Kürzel — de N.N., en TBD; Langform im Tooltip (D87-Nachtrag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 13:52:39 +02:00
mhoennigandClaude Fable 5 e684ac73d3 feat(tools): pull-doc --open öffnet die Datei danach in IntelliJ IDEA (D88-Nachtrag 2)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 13:36:25 +02:00
mhoennigandClaude Fable 5 78e2eeb616 feat(live): Sitzung heilt sich selbst; Verbindungszustand warnfarben am Namens-Chip (D89-Nachtrag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 13:23:34 +02:00
mhoennig 0d573a80c4 docs: Werkbaum-Plan — 2 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #col.git.pull: A script pulls the server document and commits it (S)  %% tools/pull-doc --git-commit, dated commits — see D88
- #col.live.safe: Unsent work is loud, rescued and never silently discarded (M)  %% modal for a second window, watchdog, local backups — see D89
2026-08-27 13:04:58 +02:00
mhoennigandClaude Fable 5 f45ca44d3c feat(kopf): Dokumentart grau hinter dem Namens-Chip — Mitgeliefert/Lokal/Geteilt samt Host (D90)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 13:03:53 +02:00
mhoennigandClaude Fable 5 408e23f25b feat(live): vier Netze gegen stillen Verlust — Zwei-Fenster-Modal, Wachhund, Rettungs-Sicherungen, lokale Stände für Server-Dokumente (D89)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 12:51:11 +02:00
mhoennigandClaude Fable 5 42d37daf63 feat(tools): pull-doc committet nur noch mit --git-commit (D88-Nachtrag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 12:00:53 +02:00
mhoennigandClaude Fable 5 887b5c75ee feat(tools): pull-doc holt ein Server-Dokument in ein git-Worktree und committet es datiert (D88)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 11:56:12 +02:00
mhoennigandClaude Fable 5 22769cf3b6 docs: Nutzen je Knoten festgelegt — (M/9) im Größen-Token, lohnendster Pfad (SPEC §11)
Geplant, nicht gebaut: Ziffer 0-9 im Größen-Token (0 = Vorbedingung),
reine Autoren-Aussage ohne Aggregation; der Pfad-Knopf wird ein
Durchschalter aus -> günstigster -> lohnendster. Plan-Knoten
#not.benefit (XOR-Gruppe aufgelöst) und #ed.path.worth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 11:03:36 +02:00
mhoennig d12bfd1c57 docs: Werkbaum-Plan — 3 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #ed.lens: A people bar with a person lens
- #ed.lens.fold: One person's nodes, everything else folds (S)  %% view-only, never written into the text
- #ed.lens.load: A load bar per person, shares of the open path work (S)  %% the D71 measure
2026-08-27 10:41:07 +02:00
mhoennigandClaude Fable 5 deec39e82a feat(diagram): Personen-Leiste mit Personen-Linse und Belastungsanzeige (D87)
Je @Person eine Pille mit Anteil an der offenen Pfad-Arbeit (D71-Maß),
dazu ein Eintrag für Unzugewiesenes — die Anteile summieren auf 100 %.
Ein Tipp filtert das Diagramm auf die Knoten der Person: alles andere
faltet, ihre Pakete stehen als ▸ n, die Pillen färben petrol. Die Linse
ist rein Ansicht und Sitzungssache — in den Text wird nichts geschrieben,
in geteilten Dokumenten ginge der persönliche Filter sonst an alle.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:38:53 +02:00
mhoennigandClaude Fable 5 1e1a00f794 docs: Changelog-Zeile zur Text-Falten-Idee
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:14:27 +02:00
mhoennigandClaude Fable 5 67d3585310 docs: Text-Falten im Editor als Idee in den Plan (#ed.textfold, unbewertet)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:14:12 +02:00
mhoennigandClaude Fable 5 a59bbaa16a fix(diagram): Wurzelknoten-Falt-Chip wie überall, helle Marken nur auf dunkler Wurzel (D64-Nachtrag 2)
Die helle Umkehrung des Chips war für die dunkle Tinte-Wurzel gebaut —
seit D39 ist die Wurzel mit Status aber pastellfarben, und Weiß darauf
unsichtbar. Der Chip ist jetzt überall derselbe; desc-mark und nid
bleiben nur auf der statuslosen (dunklen) Wurzel weiß.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 10:05:19 +02:00
mhoennigandClaude Fable 5 9d1d580166 fix(diagram): Cursor-Zeile lässt zurückgetretene Knoten blass (D25-Nachtrag 4)
Die Ausnahme von der Pfad-Inversion stellte den ganzen Knoten auf volle
Stärke, weil opacity/filter den Ring mitträfen. Jetzt bleibt der Knoten
deckend und die Blässe wird nachgebildet: Papier-Wasch über der Füllung,
gefadete Text-/Rahmenfarbe, Kinder einzeln gedimmt — der Ring steht voll.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 09:54:55 +02:00
mhoennig f6c7eff490 docs: Werkbaum-Plan — 3 Knoten in Produktion
Beim Deploy der stabilen Instanz gehen diese Knoten live; SPEC §4
unterscheidet [x] fertig von [^] in Produktion (D30):

- #col.live.rename: Renaming reaches everyone (S)  %% PATCH /title + RENAMED in the feed, see D85
- #col.live.history: Earlier states come from the server (M)  %% milestones in the clock menu, rollback for everyone, see D86
- #col.live.name: A self-chosen display name (XS)  %% fills "changed by", a claim, not a proof
2026-08-27 08:36:15 +02:00
mhoennigandClaude Fable 5 53b48bcd42 feat(paket c): Frühere Stände eines geteilten Dokuments kommen vom Server (D86)
Der Verlaufs-Knopf zeigt bei Geteilten die Meilenstein-Historie des
Servers (GET /history, jetzt samt clientId/displayName); Laden ist ein
Server-Rollback (POST /restore, ROLLED_BACK — neue Version für alle,
nichts geht verloren, mit Rückfrage). Die Kamera legt einen
Server-Meilenstein an (pushLive(true), leeres Diff erlaubt); lokale
Momentaufnahmen sammelt snapshotNow() für Server-Dokumente nicht mehr —
sie enthielten fremde Arbeit und überschrieben sie beim Laden als
eigenes Diff. Dazu der Anzeigename: einmal gefragt, im Browser gemerkt,
füllt das 'geändert von' der Historie (Behauptung, kein Nachweis).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 08:21:17 +02:00
mhoennigandClaude Fable 5 1fb11ceba4 chore: lokale H2-Datenbank aus dem Repo entfernt und ignoriert
backend/data/ entsteht beim lokalen bootRun (D77: werkbaum.data-dir) und
war im D85-Commit versehentlich mitgegangen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 08:13:39 +02:00
mhoennigandClaude Fable 5 fbe9b1fd22 feat(paket b): Umbenennen erreicht alle — PATCH /title und RENAMED im Feed (D85)
Backend: PATCH /documents/{id}/title mit expectedVersion (409 bei
veralteter Version, 400 bei leerem/zu langem Titel), neuer ChangeType
RENAMED (strukturell, immer Meilenstein), der Feed stellt den neuen Titel
im Klartext zu (ChangeEvent.title). Unter derselben Stripe-Sperre wie die
Inhalts-Patches; Owner-Vormerkung in der API-Beschreibung. Vier neue
Cucumber-Szenarien, zwei Unit-Tests.

Frontend: Der Zeilen-Stift eines Server-Dokuments benennt über den Server
um (optimistisch, 409-Retry, Rücknahme + Warnung bei Fehlschlag); fremde
Umbenennungen kommen als RENAMED über den Feed in Chip und Menü.
URL-Dokumente verlieren den Stift — ihr Name ist die URL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 08:13:25 +02:00
mhoennigandClaude Fable 5 c438a88344 fix(paket a): URL-Reload ohne Rückfrage, Letztes-Dokument-Hinweis, Fremd-Tab-Warnung (D84)
1. Neu laden fragt bei URL-Dokumenten nicht mehr (F5 verwirft ohnehin
   still, D23); bei Datei-Dokumenten bleibt die Rückfrage. Dabei gefunden
   und behoben: Der Knopf erschien auch bei Server-Dokumenten und hätte
   die JSON-Antwort der API als Text an alle gepusht.
2. Die Rückfrage beim letzten Dokument sagt, dass danach wieder das
   Beispiel dasteht (docDeleteLastConfirm, 9 Sprachen).
3. Ein zweiter Tab, der in dieselbe Ablage schreibt, wird per
   storage-Ereignis erkannt und gemeldet (tabConflict, isDocKey in
   docstore.js) — kein Sync, aber kein stiller Verlust mehr.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 08:02:15 +02:00
mhoennigandClaude Fable 5 83dc329b43 docs(plan): Owner-Passwort für geteilte Pläne als geplant eingetragen (#col.live.owner)
Beim Anlegen einmalig vom Server geliefert, Browser hält eine Kopie, keine
Recovery auf fremdem Browser; Verwaltung bindet künftig daran, ein Admin
mit Master-Passwort kann reclaimen. Nur Plan-Eintrag, noch keine Umsetzung.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 07:44:13 +02:00
mhoennigandClaude Fable 5 5c8fbcde01 feat(menü): Geteilte werden verlassen, nicht gelöscht (D81-Nachtrag 5)
Eigene Aktion für die Geteilt-Gruppe (Server- und URL-Dokumente): Wort
(Verlassen), Icon (Tür mit Pfeil statt Papierkorb), Rückfrage (nur der
eigene Listeneintrag geht, Server bleibt) und normales statt rotem Hover.
Der Link wandert beim Verlassen in die Zwischenablage — der Listeneintrag
ist zugleich das Lesezeichen. Verhalten wie lokales Löschen
(removeDocLocally, gemeinsamer Kern); i18n in neun Sprachen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 07:28:43 +02:00
mhoennigandClaude Fable 5 a78147e459 feat(menü): Gruppen heißen Mitgeliefert · Lokal · Geteilt (D81-Nachtrag 4)
Nutzer-Wortwahl statt „Eigene"/„Quellen": Lokale leben nur in diesem
Browser, Geteilte (Server- und URL-Dokumente) erreicht man über eine
weitergegebene Adresse. In allen neun Sprachen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 07:06:00 +02:00
mhoennigandClaude Fable 5 3072f3a9c0 feat(speicher): Dokument-Ablage aufgeteilt — Index + ein Schlüssel je Text (D83)
werkbaum-docs ist nur noch der Index [{id,name,source?}]; der Text jedes
Dokuments liegt unter werkbaum-doc:<id>. Damit trifft eine volle Quota nur
das eine zu große Dokument statt jeden Flush, und ein kaputter Schlüssel
kostet ein Dokument statt aller (vorher: JSON.parse-Fehler -> Rückfall auf
das Beispiel, alle Dokumente unsichtbar). Der Tastendruck schreibt direkt
den Text-Schlüssel; der Voll-Flush vergleicht vor jedem Schreiben und räumt
verwaiste Schlüssel ab. Altformat migriert beim ersten Laden; die
Spiegel-Regel aus D82 gilt nur noch dieser Migration. Schema headless in
docstore.js (+10 Tests).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 06:58:10 +02:00
mhoennigandClaude Fable 5 4f34454075 perf+fix(speicher): Tastendruck schreibt nur den Spiegel; Quota-Fehler werden gemeldet (D82)
saveSrc() serialisierte bei jedem Tastendruck ALLE Dokumente in
werkbaum-docs. Jetzt schreibt der Tastendruck nur noch den Spiegel
werkbaum-src (ein Text); das volle Array schreiben die Flush-Punkte
(Wechseln/Anlegen/Löschen/Umbenennen, pagehide, verborgener Tab). Beim
Laden gewinnt der Spiegel für das aktive Dokument — zwingend VOR dem
Nachziehen mitgelieferter Fassungen, sonst dreht er sie zurück.

Und: persistDocs schluckte Speicherfehler still — bei voller Quota lief
der Editor scheinbar normal weiter, der Verlust fiel erst beim Neuladen
auf. Jetzt meldet die persistente Warnung storeFailed (9 Sprachen),
zuoberst, bis ein Schreiben wieder gelingt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 06:43:10 +02:00
mhoennigandClaude Fable 5 ca4c6f98d8 fix(menü): mitgelieferte Dokumente sind nicht mehr umbenennbar (D81-Nachtrag 3)
Ihr Name ist Auslieferungsstand: Wiederherstellen stellt ihn mit her, der
Neu-laden-Vergleich prüft ihn, und ein umbenanntes, aber unverändertes
Beispiel bekäme weiter still neue Fassungen nachgezogen (das Nachziehen
hängt an id + Text-Fingerabdruck, nicht am Namen). Kein Stift an
mitgelieferten Zeilen; renameDoc() prüft es selbst. Löschen bleibt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 05:51:41 +02:00