Skip to content

fix(web): preserve quote boundaries in restored drafts - #1055

Merged
incognitojam merged 1 commit into
mainfrom
styal/preserve-message-markdown
Oct 25, 2026
Merged

incognitojam merged 1 commit into
mainfrom
styal/preserve-message-markdown

Conversation

@incognitojam

@incognitojam incognitojam commented Oct 25, 2026 •

Copy link
Copy Markdown
Owner

Problem

A restored or prefilled rich-text value can show a comment outside a quote in the composer, then send it inside the quote. The editor displays parsed blocks while the stored value still lacks the blank Markdown line that separates the comment from the quote; editing the text was required to serialize that separator.

Typing a quote and comment into a new-thread composer already uses the separator fix on main. This PR covers the additional loaded-value path, where text is sent without a further edit.

Change

After applying a controlled rich-text value, persist the editor's serialized document when it differs from the source and that source is still current. Sending a restored draft now preserves the quote boundary already shown in the composer. Plain-text input and literal question answers keep their source text.

Scope and approval

Focused correction to restored/prefilled composer state in the shared web and desktop editor. The existing draft-sync ledger records the restored-value invariant and regression coverage.

Verification

  • Restored a synthetic draft and sent it without editing: the following thread reference joined the quote before the fix and remained a separate paragraph after it.
  • Pasted a quote containing inline code and typed a new quote, leaving it with Shift+Enter twice: the sent comments stayed outside their quotes and inline code remained intact.
  • Browser regression coverage exercises restoration on mount and replacement of an existing draft, then sends the stored value through the chat Markdown pipeline. Both boundary cases fail with the fix removed and pass with it present. Plain-text composer input and literal question answers retain their source text.

Verified in the isolated web client. Desktop shares the editor; the Electron shell, native mobile clients, and remote/tunnel connections were not exercised. No new browser-console or server errors appeared during the verified sends.

Before: thread reference joins the quote After: latest message keeps the thread reference outside the quote
Before: thread reference is inside the quote After: the lower message keeps the thread reference outside the quote

Written by an agent (Codex, gpt-6.1-sol).

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Upstream divergence

Both sides are compared with upstream at the in-order tip 393a9f8950. Excludes .repos/ and pnpm-lock.yaml.

Measure Base This PR Change
Upstream files the fork changes 1,674 1,675 +1
Lines changed in them 89,301 89,307 +6
Upstream files the fork removes 49 49 0
Fork-only files 651 652 +1
Fork-only lines 117,462 117,552 +90

Upstream files that start to differ (1)

  • apps/web/src/components/ComposerPromptEditorTiptap.tsx: +6 −0 from upstream

@github-actions

github-actions Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 4.9 KiB −30 B (−0.6%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB −30 B (−2.5%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.8 KiB −41 B (−0.2%) 29.3 KiB ✅
Codex Live turn messages 2 1 −1 (−50.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB +7 B (+0.1%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB +7 B (+0.6%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB 0 B (0.0%) 29.3 KiB ✅
Claude Live turn messages 2 2 0 (0.0%) 8 ✅

Baseline: 4634870 · PR result: df758ac · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@incognitojam
incognitojam force-pushed the styal/preserve-message-markdown branch from d05cc08 to df758ac Compare October 25, 2026 18:05
@incognitojam
incognitojam enabled auto-merge (squash) October 25, 2026 19:12
@incognitojam
incognitojam merged commit c85ea7f into main Oct 25, 2026
39 checks passed
@incognitojam
incognitojam deleted the styal/preserve-message-markdown branch October 25, 2026 19:13
incognitojam pushed a commit that referenced this pull request Oct 29, 2026
…ingdotgg#19186)

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: Julius Marminge <[email protected]>

Fork adaptation: The lockfile is regenerated from the fork's dependency graph and uses the fork's existing Tiptap 3.31.4 graph for the new italic dependency. Retain restored-draft normalization and history normalization from the composer-draft-sync feature (including fork PR #1055), alongside upstream's literal underscore rules.

(cherry picked from commit bb76f12)
Upstream-PR: 19186
Fork-Feature: composer-draft-sync
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant