[PR #9008] fix(clipboard): improve OSC 52 escape sequence for SSH compatibility #12951

Open
opened 2026-02-16 18:17:50 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/9008

State: open
Merged: No


Summary

  • Fix OSC 52 clipboard not working over SSH
  • Fix GNU Screen passthrough using wrong format
  • Add nested tmux session support
  • Use ST terminator instead of BEL for better compatibility

Problem

Clipboard copy operations fail when running OpenCode over SSH. The existing OSC 52 implementation had several issues:

  1. Used BEL (\x07) terminator which some terminals don't handle correctly inside DCS sequences
  2. Applied tmux-style passthrough (tmux; prefix) to GNU Screen, which uses a different format
  3. No support for nested tmux sessions

Fixes https://github.com/sst/opencode/issues/6111
Fixes https://github.com/anomalyco/opencode/issues/2773

Solution

1. BEL → ST Terminator

- const osc52 = `\x1b]52;c;${base64}\x07`
+ const osc52 = `\x1b]52;c;${base64}\x1b\\`

ST (String Terminator) is more reliably handled inside DCS passthrough sequences.

2. Correct GNU Screen Format

// GNU Screen: DCS without tmux; prefix
const wrapped = osc52.replace(/\x1b/g, "\x1b\x1b")
sequence = `\x1bP${wrapped}\x1b\\`

3. Nested tmux Support

Detect nesting level from TMUX environment variable (comma-separated) and double escapes for each level:

const tmuxLevel = (process.env["TMUX"]?.match(/,/g) || []).length + 1
for (let i = 0; i < tmuxLevel; i++) {
  wrapped = wrapped.replace(/\x1b/g, "\x1b\x1b")
  wrapped = `\x1bPtmux;${wrapped}\x1b\\`
}

Supported Environments

Environment Status
iTerm2
Kitty
Alacritty
Windows Terminal
tmux
Nested tmux
GNU Screen

Test plan

  • Tested copy operation over SSH session
  • Verified paste works on local machine
  • Test inside tmux
  • Test inside GNU Screen
  • Test nested tmux (tmux inside tmux)

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com

**Original Pull Request:** https://github.com/anomalyco/opencode/pull/9008 **State:** open **Merged:** No --- ## Summary - Fix OSC 52 clipboard not working over SSH - Fix GNU Screen passthrough using wrong format - Add nested tmux session support - Use ST terminator instead of BEL for better compatibility ## Problem Clipboard copy operations fail when running OpenCode over SSH. The existing OSC 52 implementation had several issues: 1. Used BEL (`\x07`) terminator which some terminals don't handle correctly inside DCS sequences 2. Applied tmux-style passthrough (`tmux;` prefix) to GNU Screen, which uses a different format 3. No support for nested tmux sessions Fixes https://github.com/sst/opencode/issues/6111 Fixes https://github.com/anomalyco/opencode/issues/2773 ## Solution ### 1. BEL → ST Terminator ```diff - const osc52 = `\x1b]52;c;${base64}\x07` + const osc52 = `\x1b]52;c;${base64}\x1b\\` ``` ST (String Terminator) is more reliably handled inside DCS passthrough sequences. ### 2. Correct GNU Screen Format ```typescript // GNU Screen: DCS without tmux; prefix const wrapped = osc52.replace(/\x1b/g, "\x1b\x1b") sequence = `\x1bP${wrapped}\x1b\\` ``` ### 3. Nested tmux Support Detect nesting level from TMUX environment variable (comma-separated) and double escapes for each level: ```typescript const tmuxLevel = (process.env["TMUX"]?.match(/,/g) || []).length + 1 for (let i = 0; i < tmuxLevel; i++) { wrapped = wrapped.replace(/\x1b/g, "\x1b\x1b") wrapped = `\x1bPtmux;${wrapped}\x1b\\` } ``` ## Supported Environments | Environment | Status | |-------------|--------| | iTerm2 | ✅ | | Kitty | ✅ | | Alacritty | ✅ | | Windows Terminal | ✅ | | tmux | ✅ | | Nested tmux | ✅ | | GNU Screen | ✅ | ## Test plan - [x] Tested copy operation over SSH session - [x] Verified paste works on local machine - [ ] Test inside tmux - [ ] Test inside GNU Screen - [ ] Test nested tmux (tmux inside tmux) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
yindo added the pull-request label 2026-02-16 18:17:50 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#12951