[BUG] VSCode extension: whitespace stripped at inline element boundaries when copying from chat panel
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
What's Wrong?
When selecting and copying text from the VSCode extension's chat panel (Ctrl+C), whitespace adjacent to inline formatting elements (bold, links, code spans) is stripped from the clipboard HTML. Pasting into any rich-text target (Slack, Notion, Google Docs) produces words jammed together at formatting boundaries.
Example: a response containing "word next" pastes into Slack as "wordnext" — the bold renders correctly but the space between the bold text and the next word is missing.
This affects <strong>, <a>, <em>, <code>, and <span> elements. Every inline formatting boundary is a potential break point.
Expected Behavior
Copied text preserves whitespace at all inline element boundaries, matching what's visually rendered in the chat panel.
How to Reproduce
- Open Claude Code in VSCode extension
- Get a response containing bold text adjacent to normal text (e.g. "word next")
- Select the text, Ctrl+C
- Paste into Slack (or Notion, Google Docs, any rich-text editor)
- Observe: space between "word" and "next" is missing
Root Cause
The chat panel renders markdown via ReactMarkdown, which produces HTML like <strong>word</strong>next with no whitespace node between the closing tag and adjacent text. The browser's native copy serializes this to text/html faithfully, preserving the missing whitespace. There is no copy event listener on the chat container to normalize it.
Code block copy buttons use navigator.clipboard.writeText() (text/plain only), and there's no intervention on general DOM selection copy.
Confirmed Fix
A copy event listener appended to the webview that intercepts the copy event, clones the selection, and injects spaces at inline element boundaries before writing to clipboardData:
document.addEventListener('copy', function(e) {
var sel = window.getSelection();
if (!sel || !sel.rangeCount || sel.isCollapsed) return;
var c = document.createElement('div');
c.appendChild(sel.getRangeAt(0).cloneContents());
var html = c.innerHTML;
if (!html || !html.trim()) return;
html = html.replace(/<\/(strong|b|a|em|i|code|span)>([^\s<.,;:!?)}\]])/g, '</$1> $2');
html = html.replace(/([^\s>({\["])<(strong|b|a|em|i|code)([\s>])/g, '$1 <$2$3');
e.clipboardData.setData('text/html', html);
e.clipboardData.setData('text/plain', sel.toString());
e.preventDefault();
});
Tested locally by patching webview/index.js. Slack paste now preserves spacing correctly.
Environment
- Claude Code: 2.1.216
- VSCode: Windows 11
- Platform: VSCode extension (not terminal CLI)
Related Issues
- #54670 - Feature request for "copy as markdown source" (different issue, but same surface)
- #72565 - TUI strips rich clipboard flavors (same family, different code path)
- #61021 - Selection/copy difficulties in VSCode