fix: use session's actual screen state for screenshots

The screenshot was creating a new pyte screen with arbitrary dimensions
from query params, but the replay buffer contains ANSI sequences meant
for the session's actual terminal size. This mismatch caused wrapping.

Now we use get_screen_state() which returns the actual screen buffer
from the terminal session's pyte screen, with the correct dimensions.
This ensures the screenshot matches exactly what the terminal rendered.
This commit is contained in:
GitHub Copilot
2026-01-24 11:14:12 +00:00
parent 3e433f5af5
commit e85213315e
3 changed files with 81 additions and 61 deletions
+28
View File
@@ -138,6 +138,34 @@ class TerminalSession(Session):
async with self._screen_lock:
return [line.rstrip() for line in self._screen.display]
async def get_screen_state(self) -> tuple[int, int, list]:
"""Get the current screen state including dimensions and character buffer.
Returns:
Tuple of (width, height, buffer) where buffer is a list of rows,
each row containing character data with styling attributes.
"""
async with self._screen_lock:
width = self._screen.columns
height = self._screen.lines
# Copy the buffer data to avoid holding the lock
buffer = []
for row in range(height):
row_data = []
for col in range(width):
char = self._screen.buffer[row][col]
row_data.append({
"data": char.data if char.data else " ",
"fg": char.fg,
"bg": char.bg,
"bold": char.bold,
"italics": char.italics,
"underscore": char.underscore,
"reverse": char.reverse,
})
buffer.append(row_data)
return (width, height, buffer)
def update_connector(self, connector: SessionConnector) -> None:
"""Update the connector for reconnection without restarting the session."""
self._connector = connector