[BUG] Over mosh, copy-on-select only works the first time a given string is copied: identical OSC 52 is deduped by mosh state sync while the TUI reports "sent N chars via OSC 52"
Summary
Over mosh, copy-on-select (and /copy) only reaches the client clipboard the first time a given string is copied. Copying the same text again emits an identical ESC ] 52 ; c ; <base64> BEL, mosh treats the clipboard as synced state rather than an event, sees no change, and never re-emits it to the local terminal. The clipboard keeps whatever overwrote it in the meantime (for me, the OAuth login URL), while the TUI still reports sent 31 chars via OSC 52 - if paste fails, hold Shift .... From the user's side it looks like "copy is broken".
This is the common case in practice: you copy a command, something else lands on the clipboard, you go back and select the same command again, and nothing happens.
Environment
- Claude Code 2.1.241 (native arm64 binary), sessions viewed through
claude agents(daemon +bg-pty-host), but the same applies to a plainclaudeover mosh since the bytes are identical - Remote: macOS (Apple Silicon), mosh-server 1.4.0
- Local: macOS, mosh-client 1.4.0, WezTerm 20240203-110809-5046fc22
- No tmux/screen/zellij in the chain
Reproduction (isolates mosh as the layer)
Written straight to the mosh pty on the remote host, so Claude Code is not involved at all:
B64=$(printf 'PROBE-X' | base64)
printf '\033]52;c;%s\a' "$B64" > /dev/ttysNNN # pty under mosh-server
# local: pbpaste -> PROBE-X (lands)
# local: printf 'CLOBBERED' | pbcopy
printf '\033]52;c;%s\a' "$B64" > /dev/ttysNNN # identical payload again
# local: pbpaste -> CLOBBERED (never re-emitted)
B64=$(printf 'PROBE-Y' | base64); printf '\033]52;c;%s\a' "$B64" > /dev/ttysNNN
# local: pbpaste -> PROBE-Y (a different payload lands)
Writing the same payload twice directly to the local terminal's tty (no mosh) sets the clipboard both times, so the terminal is not deduping; mosh is. Writing into the hidden bg-pty-host pty behaves exactly like writing to the mosh pty, so the daemon/viewer path forwards OSC 52 correctly. The only failing case is a repeated payload through mosh.
Expected
Every copy action updates the clipboard, or the feedback line tells the truth when it cannot.
Suggested fix
In the OSC 52 emitter (setClipboard, the emit=raw path), defeat state-sync dedupe by forcing a state change before each set, e.g. emit a clear first:
ESC ] 52 ; c ; ! BEL (clear)
ESC ] 52 ; c ; <base64> BEL (set)
mosh then sees two state changes and replays both; terminals that treat OSC 52 as an event just process two writes. Alternatively, only do this when the attached client looks like mosh (MOSH_* env or mosh-server in the process ancestry), the way the tmux DCS wrapping is gated today.
Related but different: #74214 is the opposite (an explicit copy emitting twice); #86290 is the daemon stripping TMUX. This one is a single correct emission that a stateful transport drops.