Instead of trying to replay a truncated byte buffer through pyte, this
change maintains a pyte Screen object within TerminalSession that gets
updated as terminal data flows through. This provides accurate terminal
state for screenshots without issues from buffer truncation.
Key changes:
- Add pyte Screen and Stream to TerminalSession
- Update screen state as data arrives via _update_screen()
- Add get_screen_lines() to return current screen state
- Resize pyte screen when terminal size changes
- Update local_server to use get_screen_lines() directly
- Remove _apply_carriage_returns() workaround
This properly fixes the tmux status bar 'creeping up' issue by ensuring
the screenshot always reflects the actual terminal state.
Convert f-string logging to lazy %-style interpolation throughout:
- session_manager.py
- cli.py
- terminal_session.py
This follows Python logging best practices for performance (lazy
evaluation) and consistency across the codebase.
Addresses REFACTORING.md item about normalizing logging style.
Consolidate nested helper functions and reduce complexity:
- Inline header extraction with first_header helper
- Use rpartition for cleaner host:port splitting
- Simplify control flow with loop over header candidates
Addresses REFACTORING.md item about simplifying _get_ws_url_from_request.
Replace try/finally with contextlib.AsyncExitStack for cleaner
structured cleanup of the aiohttp runner. This ensures proper
resource cleanup even in complex shutdown scenarios.
Addresses REFACTORING.md item about TaskGroup/cleanup context.
Replace bare Exception catch with specific exception types:
- json.JSONDecodeError for invalid JSON
- TypeError, KeyError, ValueError for malformed messages
- OSError for I/O errors
Addresses REFACTORING.md item about narrowing WebSocket error handling.
Replaces simple carriage return handling with pyte terminal emulator
to properly interpret all ANSI escape sequences including cursor
positioning. This fixes the tmux status bar 'creeping up' issue in
screenshots.
Adds pyte dependency to pyproject.toml.
Resolves TODO item #2.