composer: unwrap quote blocks with Backspace

Merged
TE
11d ago
+183-1

Backspace now unwraps a quote at its start into a plain paragraph, including an empty quote. It preserves the text and keeps any preceding paragraph separate. This repairs the shared rich editor used by chat and Cmd-I. New Tab paths that use plain inputs cannot create quote blocks.

Leo, 2026-10-26: "and i cant delete quote block text thingy with backspace? only shift enter? strange..."

Milkdown replaces ProseMirror's lifting Backspace with joinTextblockBackward: the first quote stays stuck, while one after other text can merge into that paragraph. A quote-specific command lifts its first paragraph before that fallback. Other Backspace behavior passes through.

Verification

  • cd webviews && bun test test/composer-quote-backspace.test.tsx: 0 pass / 3 fail at regression commit 7419f7e7377b; 3 pass / 0 fail after the fix. Reproduced all three failures against current base 4e28d9cf44d9ec587ad96d223ced6e5bc2c7f5b0 too.
  • Quote and caret suites: 5 pass / 0 fail at head 75284f15318dbf58ca5654f91b8bb27ec50d9a5e.
  • Changed-file lint, full webviews typecheck and prepush gate pass.
  • Full web lint reports an unchanged base violation in webviews/src/pages/keybindings/styles.css (missing reduced-transparency fallback). No changes to that file.

Observed / Not run

Observed the real Chromium gallery editor before and after Backspace in three fixture states: quoted text, empty quote, and a quote after another paragraph. The recording below compares base (left) and head (right), in order: nonempty quote, empty quote, quote after another paragraph. Reference reviewed: cmux-design-references/apps/claude/live/composer-demo-ready.png; this keyboard repair preserves existing composer chrome.

No native build or manual nightly verification performed yet. The regression exercises the shared editor's actual keymap; the recordings drive a real browser keyboard.

Before left, after right: Backspace quote behavior

Agent session: agent session