Skip to content

fix(web): preserve Mermaid source when copying selected text - #16249

Open
NikitaMGrimm wants to merge 3 commits into
pingdotgg:mainfrom
NikitaMGrimm:feat/mermaid-selection-copy
Open

NikitaMGrimm wants to merge 3 commits into
pingdotgg:mainfrom
NikitaMGrimm:feat/mermaid-selection-copy

Conversation

@NikitaMGrimm

@NikitaMGrimm NikitaMGrimm commented Oct 5, 2026 •

Copy link
Copy Markdown

Problem

Selecting prose across a rendered Mermaid diagram drops the diagram from copied Markdown in assistant and sent-user messages. Drag from the text above a diagram to the text below it, copy, and paste: only the prose remains.

Change

Give rendered diagrams the existing Markdown copy override containing fenced Mermaid source. Crossing selections preserve the selected surrounding prose; selections wholly inside a diagram copy its complete source. Partial “Show code” selections remain partial. Because the restored diagram source can contain context-looking links, those links do not authorize exporting context records whose chips were not selected.

Scope and approval

Submitted under the very small, focused obvious-bug exception: the established selection-to-Markdown workflow loses rendered message content. The fix stays in the shared web/desktop renderer and adds no dependency or setting. No prior maintainer approval is claimed.

Verification

Previously recorded on this PR head; not rerun in this audit:

  • vp test run apps/web/src/components/chat/MessagesTimeline.test.tsx apps/web/src/markdown-clipboard.mermaid.test.ts apps/web/src/markdown-clipboard.test.ts: passed. Regressions cover crossing, inside, start/end-inside selections, source backticks, partial source-view copying, and exporting an image record only when its chip is selected, even when its link appears in a Mermaid comment.
  • Web typecheck, targeted lint, formatting, and diff checks passed; lint reported existing timeline warnings.
  • Isolated T3 Browser checks used mouse selection and native copy/paste shortcuts in both message roles. Selection-range checks also covered collapsed/expanded user messages and partial source copying.

Dragging from a diagram label still does not start a text selection. Native mobile was not exercised.

Desktop: The author uses this change daily in the packaged Windows desktop app, in a personal build of the official nightly with their open PRs merged in, and confirms it works there. That use was manual and is not recorded.

Before is left; after is right. The recording copies the first three blocks of an expanded user message, leaving its final instruction unselected.

Copying part of a sent user message, before and after

mermaid-selection-copy-before-after.mp4

Head 85382ed960 merges main at ab3a3cd162 (no conflicts; this PR's diff is unchanged). The previous CI run was created on 2026-10-11 while main briefly failed Typecheck in packages/ssh (between #14598 and #18078), so it would have failed for reasons unrelated to this PR. On the merged head, MessagesTimeline.test.tsx and markdown-clipboard.mermaid.test.ts pass (96 tests) and apps/web typechecks.

Note

🤖 Agent assistance: gpt-6.1-sol via Codex

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Oct 5, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Oct 5, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7c7a2d1

Macroscope's review found this PR approvable — This is a small, well-contained clipboard bug fix that preserves Mermaid source while keeping structured context exports limited to actually selected chips. The production changes are localized to existing chat rendering and copy handling, with targeted regression coverage and no product-default or static-analysis configuration changes.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2c908c77-28b8-402d-90f7-02a12d0b7b7b
📥 Commits

Reviewing files that changed from the base of the PR and between 7c7a2d1 and 85382ed.

📒 Files selected for processing: 3
  • apps/web/src/components/chat/MermaidDiagram.tsx
  • apps/web/src/components/chat/MessagesTimeline.test.tsx
  • apps/web/src/components/chat/MessagesTimeline.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

The change adds an exported Markdown code-block serializer and uses it to preserve Mermaid source in clipboard payloads for selections within rendered diagrams. The copied-Markdown scan excludes Mermaid elements when identifying structured context records.

Changes: Mermaid Clipboard

Layer / File(s) Summary
Markdown code-block serialization
apps/web/src/markdown-clipboard.ts, apps/web/src/markdown-clipboard.mermaid.test.ts
The exported serializeCodeBlockToMarkdown helper trims one trailing newline, selects a fence, adds an optional language label, and formats the closing fence and spacing. The existing serializer delegates to this helper. A test checks that the fence is longer than a backtick run in the source.
Diagram clipboard payload
apps/web/src/components/chat/MermaidDiagram.tsx, apps/web/src/markdown-clipboard.ts, apps/web/src/markdown-clipboard.mermaid.test.ts
The diagram wrapper stores its source as fenced Mermaid Markdown. Clipboard handling uses that source and sanitized selected HTML when the selection is within the wrapper. Tests cover selections across and inside a diagram, and partial selections in Mermaid source view.
Context-record copy handling
apps/web/src/components/chat/MessagesTimeline.tsx, apps/web/src/components/chat/MessagesTimeline.test.tsx
The copied-Markdown scan excludes Mermaid elements when identifying structured context records. Tests check clipboard behavior when a selected context chip is present or absent.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: t3dotgg, maria-rcks

Merge Risk: ⚪ Minimal · up to 85382

The reviewed clipboard change has no established issue requiring a fix before merge.

Security architecture risk: 🔵 Low · up to 85382

The change preserves diagram source during copying while keeping that source separate from permission to copy attached context records. No new exposure was established, but browser selection and clipboard failure behavior have not been exhaustively verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • observed — For the reviewed copy handler, structured export is bounded by the current message’s resolved context records. Exported fragments carry environment, optional thread, and message identity. Mermaid text alone does not supply additional records to that collection.

Security Findings and Attack Paths

  • inferred — The inspected path does not establish that an attacker-controlled context-looking link in Mermaid source can export an unselected record. The new diagram override is excluded from the authority scan, and the selected/unselected-chip regression explicitly exercises this distinction. The supplied candidate remains deferred rather than a verified finding; this pass provides counterevidence without claiming exhaustive browser verification.

Trust Boundaries and Controls

  • observed — The inspected paste consumer requires a decoded structured fragment before importing context records and then filters its records against references in pasted text. A context-looking link in ordinary copied text cannot manufacture a record absent from that fragment.

Resilience and Maintainability Implications

  • observed — Record IDs are deduplicated before export, and the copy handler performs synchronous clipboard writes without changing their order in this PR. A runtime failure after preventDefault could produce a partial multi-format clipboard write, but that sequence predates this change and is not a newly introduced architecture concern.
Pre-merge checks: Passed 4
Passed Passed checks: 4 passed
Check name Status Explanation
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Title check Passed The title clearly and concisely describes the primary change: preserving Mermaid source when copying selected text.
Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, scope exception, test results, limitations, and agent details…
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@NikitaMGrimm

NikitaMGrimm commented Oct 6, 2026 •

Copy link
Copy Markdown
Author

Note

🤖 gpt-6.1-sol responding on behalf of NikitaMGrimm

Verified the structured-context concern and fixed it in 7c7a2d1. The user-message copy handler now excludes Mermaid source overrides when choosing context records; the source still copies as fenced Markdown. The regression failed before the fix and now confirms that an image link hidden in a Mermaid comment exports no image record unless its chip is selected. All 115 tests across the timeline and clipboard suites, web typecheck, and targeted lint/format checks passed (existing lint warnings only).

@github-actions github-actions Bot added size:M 30-99 changed lines (additions + deletions). and removed size:S 10-29 changed lines (additions + deletions). labels Oct 6, 2026
@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Hi! We are cleaning up open PRs, and this one does not say which model or harness was used to create it. If this change is really important, we recommend rebuilding the PR with a newer model and noting the model and harness in the PR description.

@maria-rcks maria-rcks closed this Oct 11, 2026
@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Reopening, this was closed by mistake. Sorry for the noise!

@maria-rcks maria-rcks reopened this Oct 11, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 11, 2026 — with ChatGPT Codex Connector
@macroscopeapp
macroscopeapp Bot dismissed their stale review October 11, 2026 06:34

Dismissing prior approval to re-evaluate 7c7a2d1

NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 12, 2026
NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 12, 2026
NikitaMGrimm pushed a commit to NikitaMGrimm/t3code that referenced this pull request Oct 14, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants