fix(remote): reset SGR at the remote scrollback splice seam (#602 merge-time fix)

joinScrollbackAndFrame joins two separate `capture-pane -e` outputs. The
remote history's last row can end with attributes still active (a diff row's
background, dim tool output), while the local frame is encoded relative to
the default state, so its first plain rows inherited them in the browser. A
`\x1b[0m` now ends the scrollback before the frame.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-10-13 18:01:45 +02:00
1 parent f9f00bdb5e
commit d571c41fb1
2 files changed
+12 -3

No files matched your search

+9 -2
View File
@@ -146,8 +146,15 @@ describe('the remote script under a real shell', () => {
describe('joinScrollbackAndFrame', () => {
it('puts the scrollback rows above the frame in tmux’s own row shape', () => {
expect(joinScrollbackAndFrame('old 1\nold 2\n', 'frame 1\nframe 2\n')).toBe('old 1\nold 2\nframe 1\nframe 2\n');
expect(joinScrollbackAndFrame('old 1', 'frame 1')).toBe('old 1\nframe 1');
expect(joinScrollbackAndFrame('old 1\nold 2\n', 'frame 1\nframe 2\n')).toBe(
'old 1\nold 2\x1b[0m\nframe 1\nframe 2\n'
);
expect(joinScrollbackAndFrame('old 1', 'frame 1')).toBe('old 1\x1b[0m\nframe 1');
});
it('resets SGR at the seam, so the last history row cannot bleed into the frame', () => {
// A remote history row that ends with a background still set (a diff row).
expect(joinScrollbackAndFrame('\x1b[41mRED ROW\n', 'plain\n')).toBe('\x1b[41mRED ROW\x1b[0m\nplain\n');
});
it('no scrollback leaves the frame alone', () => {