Commit 0d34053
authored
tui: fix clipboard over SSH using OSC52 escape sequences (#656)
## Problem
When `roborev tui` is used over an SSH connection, pressing `y` to copy a review shows "Copied to clipboard ✓" but the clipboard is empty on the local machine.
**Root cause:** `realClipboard.WriteText()` calls `xclip`/`xsel`/`wl-clipboard` on the *remote* machine. This only reaches the user's local clipboard if X11 forwarding is active. Terminals that don't forward X11 (e.g. Tabby's built-in SSH plugin) silently lose the data.
## Fix
Add an `osc52Clipboard` implementation that writes the [OSC52 terminal escape sequence](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands) (`\x1b]52;c;<base64>\x07`) to stderr. The sequence travels through the SSH pipe and is intercepted by the **local** terminal emulator, which sets the system clipboard directly — no X11 forwarding required.
`newClipboard()` auto-selects the implementation:
- **SSH session** (`SSH_TTY` / `SSH_CLIENT` / `SSH_CONNECTION` env var is set) → `osc52Clipboard`
- **Local session** → `realClipboard` (unchanged behaviour)
## Compatibility
OSC52 is supported by all modern terminals: Alacritty, Tabby (xterm.js), Kitty, WezTerm, iTerm2, Windows Terminal, and more.
## Changes
- `cmd/roborev/tui/types.go` — add `osc52Clipboard` struct; promote `go-osc52/v2` from indirect to direct dependency
- `cmd/roborev/tui/tui.go` — add `newClipboard()` factory with SSH detection; wire into `newModel`
- `cmd/roborev/tui/review_clipboard_test.go` — 5 new tests: OSC52 output format, empty string, SSH env var detection (SSH_TTY / SSH_CLIENT / SSH_CONNECTION / no-SSH)
Co-authored-by: Luis Gonzalez <lgonzalezsa@users.noreply.github.com>1 parent 74fac25 commit 0d34053
3 files changed
Lines changed: 98 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
468 | 469 | | |
469 | 470 | | |
470 | 471 | | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
| 540 | + | |
| 541 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
447 | 447 | | |
448 | 448 | | |
449 | 449 | | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
450 | 462 | | |
451 | 463 | | |
452 | 464 | | |
| |||
584 | 596 | | |
585 | 597 | | |
586 | 598 | | |
587 | | - | |
| 599 | + | |
588 | 600 | | |
589 | 601 | | |
590 | 602 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| 9 | + | |
8 | 10 | | |
9 | 11 | | |
10 | 12 | | |
| |||
275 | 277 | | |
276 | 278 | | |
277 | 279 | | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
278 | 292 | | |
279 | 293 | | |
280 | 294 | | |
| |||
0 commit comments