Skip to content

docs(adr): 0011 live cursors in description editor (proposed)#70

Merged
Musiker15 merged 1 commit into
mainfrom
docs/adr-live-cursors
May 28, 2026
Merged

docs(adr): 0011 live cursors in description editor (proposed)#70
Musiker15 merged 1 commit into
mainfrom
docs/adr-live-cursors

Conversation

@Musiker15
Copy link
Copy Markdown
Member

Summary

ADR-first for the last v0.2.0-beta-deferred feature — live cursors in the card description editor (CLAUDE.md §5.2 USP). Per the project's ADR-first convention, this lands the decision record before any implementation; the editor swap is a follow-up PR gated on this ADR merging.

This PR is docs-only (ADR 0011 + the CLAUDE.md §14 index row). No code.

The decision

Adopt CodeMirror 6 + y-codemirror.next, behind a FEATURE_LIVE_CURSORS flag (default off).

Why not the alternatives:

  • Keep textarea + hand-rolled cursor mapping — mapping plain offsets through Y.Text under concurrent edits is exactly the bug-prone problem the established bindings already solved; rendering selections over a <textarea> needs a shadow-mirror hack.
  • TipTap / ProseMirror — rich-text model; would push us off the Markdown-source model and force a serialise/parse layer on every read/write/export/encryption path. Big migration, big bundle.
  • CodeMirror 6 — edits plain text (Markdown source stays a string → zero change to storage/encryption/export/render), has the official Yjs binding that renders remote carets from Awareness, tree-shakeable, good a11y.

Why it's safe (zero-knowledge)

  • Content + cursor metadata both travel through the existing E2EE WS relay encrypted under the BoardKey — the server keeps seeing only v1.<nonce>.<ct> (ADR 0003 preserved).
  • The Awareness payload stays PII-free, mirroring PR feat(presence): board-level awareness via Yjs (#43) #50's board-presence shape: { userId, color } + opaque positions. No email, no name, no text. Same deterministic HSL colour as the avatar stack.
  • Lazy-imported (next/dynamic, no SSR) so the perf budget (Lighthouse ≥ 95) is untouched until a self-host operator opts in.

What the follow-up implementation PR will do

(captured in the ADR's "Implementation outline" — not in this PR)

  1. FEATURE_LIVE_CURSORS env flag.
  2. Dynamically-imported description-editor.tsx wrapping CodeMirror 6 + yCollab over the card's existing Y.Text + Awareness.
  3. Drawer renders CodeMirror when on, else the current textarea.
  4. Tests: Awareness-payload PII guard; relative-position survives a concurrent insert.
  5. Graduation gate: a11y review, Lighthouse ≥ 95 with editor loaded, two-user soak test.

Review ask

This is a design decision — if you'd prefer TipTap (richer, but a rich-text migration) or want to defer live cursors entirely, this is the place to say so before any code is written. If CodeMirror 6 looks right, merging this unblocks the implementation PR.

Test plan

  • CI green (docs-only; markdown link check if any)
  • Decision review: CodeMirror 6 vs TipTap vs defer

🤖 Generated with Claude Code

ADR-first for the last v0.2.0-beta-deferred feature. Live cursors need
a character-level CRDT-aware editor (the current textarea full-string-
replaces into Y.Text, which isn't a real binding and has nowhere to
carry a remote caret).

Recommends CodeMirror 6 + y-codemirror.next behind a
FEATURE_LIVE_CURSORS flag:
- keeps the Markdown-source storage model (no change to encryption /
  export / render paths — unlike a ProseMirror/TipTap rich-text model),
- official Yjs binding renders remote carets/selections from Awareness,
- reuses PR #50's per-user colour + PII-free Awareness payload,
- content + cursor metadata stay E2EE through the existing relay
  (ADR 0003 preserved),
- lazy-imported so the perf budget is untouched until opted in.

Status: proposed. Implementation is a follow-up PR gated on this
merging. Adds the ADR index row in CLAUDE.md §14.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Signed-off-by: Moritz Kohm <moritz.kohm@gmail.com>
Signed-off-by: Musiker15 <info@musiker15.de>
@Musiker15 Musiker15 merged commit 04dcdd4 into main May 28, 2026
8 checks passed
@Musiker15 Musiker15 deleted the docs/adr-live-cursors branch May 28, 2026 15:58
@Musiker15 Musiker15 mentioned this pull request May 28, 2026
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant