The "Single clipboard write per R-* operation" refactor (commit 9a3cb242 on issues/547) introduces a regression where the paste pipeline reports success in logs but content never lands in the AI assistant's webview input. Discovered while writing the new claude-code-002 integration test on issues/483 (forked from issues/547).
Symptom
When R-L (or executeCommand(CMD_COPY_LINK_RELATIVE)) fires against a Claude Code Chat binding:
ComposablePasteDestination.pasteLink "Pasted link" log fires
VscodeAdapter.pasteTextFromClipboard "Clipboard paste succeeded" log fires
- Claude Code's chat input panel receives nothing
The human's eye is the only thing that catches the mismatch — all code-side signals say everything worked.
Evidence
Run on issues/483 (branched from issues/547):
claude-code-001 (automated, picker-only) — PASSES (picker contents log fires; no paste delivery is part of its assertion).
claude-code-002 (newly written, uses waitForHumanVerdict) — FAILS with verdict 'fail' because the human can see nothing arrived in Claude Code, even though both paste-success logs fired.
claude-code-004 (existing test, uses waitForHuman — see related silent-pass-trap issue) — passes because waitForHuman doesn't capture a human verdict. The human can stare at an empty chat input, click Cancel, and the test reports green. The log-based assertions only prove the code-side path fired.
Suspect
Commit 9a3cb242 [issues/547] Single clipboard write per R-* operation. The commit message itself flags the suspect area:
Two-delay model replaces the old single delay: FOCUS_TO_PASTE_DELAY_MS (pre-paste, 200ms) for focus readiness, CLIPBOARD_POST_PASTE_DELAY_MS (post-paste, 200ms) for webview async clipboard read across Electron IPC boundary
Possible failure modes:
- Order of operations — the
editor.action.clipboardPasteAction is dispatched before the clipboard write has actually committed across the Electron IPC boundary. Webview reads stale (or empty) clipboard data.
- Insufficient post-paste delay —
CLIPBOARD_POST_PASTE_DELAY_MS = 200ms is too short for the webview's async clipboard fetch on the test host's machine. The paste action sees nothing in the clipboard at read time.
- Wrong target for paste —
editor.action.clipboardPasteAction dispatches to the focused surface; if the webview hasn't fully taken focus when the paste fires, the keystroke goes nowhere.
- Padding pre-application drift — the commit moved padding pre-application to 4 call sites (
LinkGenerator, TextSelectionPaster, FilePathPaster, TerminalSelectionService). If one of those didn't get the padding applied correctly, the webview might be receiving an empty or malformed payload it discards.
The fact that focus IS landing in Claude Code's input field (user-confirmed) but content does not appear narrows the failure to the clipboard-content-arriving-at-webview step. Focus path is intact; clipboard delivery is not.
Why this slipped through
The commit's Test Plan says pnpm test:release passes. That is technically true — but:
pnpm test:release does NOT include --with-extensions tests. The Claude Code integration tests live in the with-extensions config and were not part of the baseline regression run.
- Even when the
with-extensions tests ran, claude-code-004/005 use waitForHuman (not waitForHumanVerdict), so they silent-pass against this exact regression. A "clean" green CI run is not actually proof the webview received anything.
This is two bugs interacting:
- The paste-pipeline regression (this issue)
- The silent-pass test trap (separate issue —
waitForHuman for visual verification doesn't capture an assertion)
The first is a real bug. The second is a test-rigor weakness that prevented the first from being caught.
Reproduction
git checkout issues/547 # or any branch forked from it
pnpm install
pnpm test:release:with-extensions --grep "claude-code-002"
# When the verdict prompt appears, look at Claude Code's chat input.
# It will be empty. Click FAIL.
# Test fails with verdict assertion error.
Alternative diagnostic: same on claude-code-004. Test will report green (silent-pass) but Claude Code input will be empty.
Suggested investigation path
- Compare
main vs issues/547 HEAD for ComposablePasteDestination, VscodeAdapter.pasteTextFromClipboard, the pasteTimingConstants.ts introduction, and the focusAndPasteCommands → focusCommands rename. Look for one of:
- A missing
await somewhere in the paste pipeline that lets the paste command race the clipboard write.
- The clipboard write happening AFTER the paste command instead of before.
- A delay value short enough to bite on machines slower than the developer's box.
- Manual reproduction in a real Cursor / VS Code (not the test host): bind Claude Code, send a link via R-L. If it's reproducible in normal use, the bug is real and not a test-host artifact.
- If reproducible in normal use, bisect across the
issues/547 commits to find which sub-change introduced it. Likely candidates per the commit message:
- The "two-delay model" change
- The "multi-command paste array replaced with single
editor.action.clipboardPasteAction" change
- The padding-pre-application moves to the 4 call sites
Blast radius
Affects all "send to AI assistant" paths under the new architecture:
- Claude Code Chat
- Likely Cursor AI (same
ComposablePasteDestination path)
- Likely GitHub Copilot Chat (same path)
- Custom AI assistants — unknown; depends on whether
customAiAssistantInsertFactory shares the same paste pipeline as the built-in factory
Terminal sends are probably unaffected (terminals don't have a webview clipboard race). Worth confirming with a quick R-L into a bound terminal.
What this blocks
claude-code-002 cannot pass on issues/483 (or any branch forked from issues/547). The test is correct; the underlying pipeline is broken.
claude-code-004 and claude-code-005 continue to silent-pass — they appear green but don't actually verify delivery. False sense of safety until the related silent-pass-trap issue is also addressed.
- Any human running R-L into an AI assistant binding will observe no content appearing. This is potentially user-visible if the refactor ships unfixed.
Priority
High. The commit message says "no user-visible behavior changes" but the refactor ACTUALLY breaks the headline RangeLink → AI workflow. Should block issues/547 from merging until fixed.
The "Single clipboard write per R-* operation" refactor (commit
9a3cb242onissues/547) introduces a regression where the paste pipeline reports success in logs but content never lands in the AI assistant's webview input. Discovered while writing the newclaude-code-002integration test onissues/483(forked fromissues/547).Symptom
When R-L (or
executeCommand(CMD_COPY_LINK_RELATIVE)) fires against a Claude Code Chat binding:ComposablePasteDestination.pasteLink "Pasted link"log firesVscodeAdapter.pasteTextFromClipboard "Clipboard paste succeeded"log firesThe human's eye is the only thing that catches the mismatch — all code-side signals say everything worked.
Evidence
Run on
issues/483(branched fromissues/547):claude-code-001(automated, picker-only) — PASSES (picker contents log fires; no paste delivery is part of its assertion).claude-code-002(newly written, useswaitForHumanVerdict) — FAILS with verdict 'fail' because the human can see nothing arrived in Claude Code, even though both paste-success logs fired.claude-code-004(existing test, useswaitForHuman— see related silent-pass-trap issue) — passes becausewaitForHumandoesn't capture a human verdict. The human can stare at an empty chat input, click Cancel, and the test reports green. The log-based assertions only prove the code-side path fired.Suspect
Commit
9a3cb242 [issues/547] Single clipboard write per R-* operation. The commit message itself flags the suspect area:Possible failure modes:
editor.action.clipboardPasteActionis dispatched before the clipboard write has actually committed across the Electron IPC boundary. Webview reads stale (or empty) clipboard data.CLIPBOARD_POST_PASTE_DELAY_MS = 200msis too short for the webview's async clipboard fetch on the test host's machine. The paste action sees nothing in the clipboard at read time.editor.action.clipboardPasteActiondispatches to the focused surface; if the webview hasn't fully taken focus when the paste fires, the keystroke goes nowhere.LinkGenerator,TextSelectionPaster,FilePathPaster,TerminalSelectionService). If one of those didn't get the padding applied correctly, the webview might be receiving an empty or malformed payload it discards.The fact that focus IS landing in Claude Code's input field (user-confirmed) but content does not appear narrows the failure to the clipboard-content-arriving-at-webview step. Focus path is intact; clipboard delivery is not.
Why this slipped through
The commit's Test Plan says
pnpm test:release passes. That is technically true — but:pnpm test:releasedoes NOT include--with-extensionstests. The Claude Code integration tests live in thewith-extensionsconfig and were not part of the baseline regression run.with-extensionstests ran,claude-code-004/005usewaitForHuman(notwaitForHumanVerdict), so they silent-pass against this exact regression. A "clean" green CI run is not actually proof the webview received anything.This is two bugs interacting:
waitForHumanfor visual verification doesn't capture an assertion)The first is a real bug. The second is a test-rigor weakness that prevented the first from being caught.
Reproduction
Alternative diagnostic: same on
claude-code-004. Test will report green (silent-pass) but Claude Code input will be empty.Suggested investigation path
mainvsissues/547HEAD forComposablePasteDestination,VscodeAdapter.pasteTextFromClipboard, thepasteTimingConstants.tsintroduction, and thefocusAndPasteCommands → focusCommandsrename. Look for one of:awaitsomewhere in the paste pipeline that lets the paste command race the clipboard write.issues/547commits to find which sub-change introduced it. Likely candidates per the commit message:editor.action.clipboardPasteAction" changeBlast radius
Affects all "send to AI assistant" paths under the new architecture:
ComposablePasteDestinationpath)customAiAssistantInsertFactoryshares the same paste pipeline as the built-in factoryTerminal sends are probably unaffected (terminals don't have a webview clipboard race). Worth confirming with a quick R-L into a bound terminal.
What this blocks
claude-code-002cannot pass onissues/483(or any branch forked fromissues/547). The test is correct; the underlying pipeline is broken.claude-code-004andclaude-code-005continue to silent-pass — they appear green but don't actually verify delivery. False sense of safety until the related silent-pass-trap issue is also addressed.Priority
High. The commit message says "no user-visible behavior changes" but the refactor ACTUALLY breaks the headline RangeLink → AI workflow. Should block
issues/547from merging until fixed.