Commit Graph

143 Commits

Author SHA1 Message Date
GitHub Copilot 231bf69b3d Bump version to 0.2.1 2026-01-24 11:59:40 +00:00
GitHub Copilot 5536c4ac51 Invalidate screenshot cache on terminal resize
When terminal resizes, old screenshot content is stale until
the app (tmux etc) re-renders at new dimensions. Clear cache
to force re-capture after resize.
2026-01-24 11:59:23 +00:00
GitHub Copilot 02d941af6a Fix sparkline service name mapping
- Pass service names (not slugs) to DockerStatsCollector
- Create slug->name mapping for sparkline lookups
- Stats are stored by service name, looked up by slug
- Add debug logging when no containers found
2026-01-24 11:57:16 +00:00
GitHub Copilot 901a2e4cfa Release v0.2.0
New features:
- CPU sparklines on dashboard showing 30-minute container history
- Real-time screenshot updates via Server-Sent Events
- Auto-focus terminals on page load
- Tab reuse when clicking dashboard tiles
- pyte-based screenshot rendering with proper ANSI interpretation
- Dirty tracking for efficient screenshot caching

Documentation:
- Updated README with new features and API endpoints
- Added Dashboard Features section
- Documented compose mode CPU sparklines
- Added API endpoints table

Technical improvements:
- Docker stats collection via Unix socket (no new deps)
- SSE endpoint for activity notifications
- Proper pyte-to-Rich color mapping
- Terminal lifecycle race condition fixes
2026-01-24 11:53:44 +00:00
GitHub Copilot be2f18c8ba Auto-focus terminal on page load
- Try to focus xterm textarea after initialization
- Retry with delays (100ms, 500ms, 1s) as terminal loads async
- Re-focus when window regains focus (tab switching)
2026-01-24 11:45:07 +00:00
GitHub Copilot bd477c1b3c Use SSE for real-time screenshot updates
- New /events SSE endpoint pushes activity notifications to browsers
- Dashboard subscribes to SSE stream instead of polling
- Screenshots refresh instantly when terminal activity occurs
- Sparklines still poll every 30s (appropriate for 30min history)
- SSE includes keepalive every 30s and auto-reconnect on error
- Removes inefficient 5s polling; updates only on actual changes
2026-01-24 11:44:29 +00:00
GitHub Copilot 1ba4ce2a34 Adjust sparkline and screenshot timing
Sparklines:
- Poll interval: 2s -> 10s
- History size: 30 -> 180 readings
- Now shows 30 minutes of CPU history

Screenshots:
- Dashboard refresh interval: 15s -> 5s
- Combined with dirty tracking, updates on activity with 5s cap
2026-01-24 11:41:01 +00:00
GitHub Copilot 34aee378d9 Bump version to 0.1.18 2026-01-24 11:34:27 +00:00
GitHub Copilot 3e29f925e2 Rename dashboard title to 'Session Dashboard' 2026-01-24 11:34:02 +00:00
GitHub Copilot 1f51d878c8 Add CPU sparkline to dashboard in compose mode
- New docker_stats.py module reads container stats from Docker socket
  using only asyncio + stdlib (no new dependencies)
- Calculates CPU % from delta of cpu_usage and system_cpu_usage
- Maintains ring buffer of last 30 CPU readings per container
- render_sparkline_svg() generates mini SVG chart from history
- DockerStatsCollector polls containers every 2 seconds
- New /cpu-sparkline.svg endpoint serves sparkline for a container
- Dashboard shows sparkline in tile header next to container name
- Only active in compose mode (--compose-manifest flag)
- Graceful degradation if Docker socket unavailable

Bump version to 0.1.17
2026-01-24 11:33:27 +00:00
GitHub Copilot ff8f5efabd Optimize screenshot updates using pyte dirty tracking
- get_screen_state() now returns has_changes flag indicating if screen changed
- pyte's dirty set tracks which rows have been modified since last read
- Screenshot handler returns cached SVG immediately when no changes detected
- Removed _screenshot_last_rendered_activity tracking (replaced by dirty flag)
- Added test for dirty flag behavior

Bump version to 0.1.16
2026-01-24 11:27:33 +00:00
GitHub Copilot 8ae3f77f23 fix: reuse same browser tab when clicking dashboard tiles
Use tile slug as window name in window.open() so clicking the same
tile twice focuses the existing tab instead of opening a new one.

Changed: window.open(url, '_blank') -> window.open(url, 'webterm-{slug}')
2026-01-24 11:23:43 +00:00
GitHub Copilot 0cae07cba6 fix: complete pyte-to-Rich color mapping
Audited all color names from both libraries and added complete mappings:

pyte standard ANSI:
- brown -> yellow (pyte uses 'brown' for ANSI color 33)

pyte bright/AIXTERM colors:
- brightblack -> bright_black
- brightred -> bright_red
- brightgreen -> bright_green
- brightbrown -> bright_yellow
- brightblue -> bright_blue
- brightmagenta -> bright_magenta
- bfightmagenta -> bright_magenta (typo in pyte's BG_AIXTERM)
- brightcyan -> bright_cyan
- brightwhite -> bright_white

Also handles hex colors from 256-color and truecolor modes
by adding '#' prefix (e.g., 'ff8700' -> '#ff8700').

Bumps version to 0.1.15.
2026-01-24 11:23:01 +00:00
GitHub Copilot 0d53952ff7 fix: handle all pyte color formats for Rich compatibility
- Add 'brown' -> 'yellow' mapping (pyte uses 'brown' for ANSI yellow)
- Add helper function to convert hex colors (pyte outputs 'ff8700',
  Rich needs '#ff8700')
- Handles 256-color and truecolor (24-bit) ANSI codes properly

Bumps version to 0.1.14.
2026-01-24 11:21:09 +00:00
GitHub Copilot 4566d03aa5 chore: bump version to 0.1.13
Changes since 0.1.12:
- Fix pyte color name mapping for Rich compatibility
- Use session's actual screen state for screenshots
- Use requested dimensions when creating screenshot sessions
- Fix terminal lifecycle race conditions
2026-01-24 11:17:55 +00:00
GitHub Copilot 4d3a13f6ef fix: resolve terminal lifecycle race conditions
1. Lock pyte screen initialization in open() to prevent races with
   concurrent _update_screen() calls

2. Reorder session registration: call open() BEFORE adding to
   sessions/routes dicts, so sessions are fully initialized before
   other code can access them

3. Add clarifying comment that PTY resize completes before pyte resize

These fixes prevent dimension mismatches between PTY and pyte screen
that could cause content wrapping in screenshots.
2026-01-24 11:17:18 +00:00
GitHub Copilot db22fd9357 fix: use requested dimensions when creating screenshot sessions
When creating a new session for screenshot:
1. Use width/height query params instead of hardcoded DISCONNECT_RESIZE
2. Add a small delay (0.5s) after creating session to allow initial output

This ensures new sessions are created with the correct dimensions
matching what the screenshot expects.
2026-01-24 11:15:01 +00:00
GitHub Copilot e85213315e 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.
2026-01-24 11:14:12 +00:00
GitHub Copilot 3e433f5af5 fix: map pyte color names to Rich-compatible names
Pyte uses 'brightblack', 'brightred', etc. but Rich expects
'bright_black', 'bright_red' with underscores. Added PYTE_TO_RICH_COLOR
mapping to translate color names in screenshot rendering.
2026-01-24 11:11:35 +00:00
GitHub Copilot 4f8c7d88d5 fix: repair broken tests and remove unused dependencies
Test fixes:
- Fix app_session.py to use 'textual-webterm' package name (not 'textual-web')
- Fix CLI version test to not hardcode version number
- Fix static path test to not use removed Path._flavour attribute

Removed unused dependencies:
- xdg
- msgpack
- httpx

All 209 tests pass with 86% coverage.
2026-01-24 10:40:26 +00:00
GitHub Copilot f9196da9f8 fix: use pyte+Rich hybrid for colored SVG screenshots
Screenshots now properly preserve terminal colors:
1. Replay buffer provides raw ANSI data with color codes
2. pyte interprets escape sequences for accurate screen state
3. Rich renders the pyte buffer with colors to SVG

This gives us both accurate terminal state (no creeping/wrapping)
and proper color preservation in screenshots.

Bumps version to 0.1.12.
2026-01-24 10:37:54 +00:00
GitHub Copilot 8ef48bdb86 chore: remove completed TODO.md and REFACTORING.md 2026-01-24 10:34:34 +00:00
GitHub Copilot fb88a4f6b9 docs: update TODO.md with screenshot fix details 2026-01-24 10:33:41 +00:00
GitHub Copilot 894fb2eaaf fix: maintain pyte screen state in TerminalSession for accurate screenshots
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.
2026-01-24 10:33:31 +00:00
GitHub Copilot a58c434eaf docs: mark completed items in TODO.md and REFACTORING.md 2026-01-24 10:27:25 +00:00
GitHub Copilot ea78ba7ff2 refactor: normalize logging to use %-style formatting
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.
2026-01-24 10:26:53 +00:00
GitHub Copilot 0086cf76b0 refactor: simplify _get_ws_url_from_request
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.
2026-01-24 10:25:24 +00:00
GitHub Copilot 8ab263f1a7 refactor: consolidate WS dispatch into separate handler methods
Extract stdin, resize, and ping handling into dedicated methods
(_handle_stdin, _handle_resize, _handle_ping) for better code
organization and testability.

Addresses REFACTORING.md item about consolidating WS dispatch table.
2026-01-24 10:24:51 +00:00
GitHub Copilot 48247d35c7 refactor: use AsyncExitStack for aiohttp runner cleanup
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.
2026-01-24 10:24:23 +00:00
GitHub Copilot f2996c2d9e refactor: narrow WebSocket exception handling
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.
2026-01-24 10:24:00 +00:00
GitHub Copilot 33da0e335c fix: use pyte terminal emulator for screenshot rendering
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.
2026-01-24 10:23:31 +00:00
GitHub Copilot c873ed2b2e fix: set tab title to container/app name
Updates the HTML page title to display the app name instead of a
generic 'Textual Web Terminal' title. Resolves TODO item #1.
2026-01-24 10:20:44 +00:00
GitHub Copilot d03f32bf69 Improve local_server and terminal_session coverage 2026-01-22 14:09:34 +00:00
GitHub Copilot 0cfb3b0a2f Include app/terminal/exit modules in coverage 2026-01-22 13:49:50 +00:00
GitHub Copilot 8f252adc27 Increase local_server test coverage 2026-01-22 13:40:59 +00:00
GitHub Copilot 557eafc163 Enforce monospace in screenshots 2026-01-22 13:02:28 +00:00
GitHub Copilot f6d986fb8f Only re-render screenshots on activity 2026-01-22 12:51:20 +00:00
GitHub Copilot 36b974287d Add screenshot backoff 2026-01-22 08:04:49 +00:00
GitHub Copilot 06a44f530a Stabilize screenshot rendering 2026-01-22 07:59:56 +00:00
GitHub Copilot f4f944b391 Bump version to 0.1.10 2026-01-22 00:38:23 +00:00
GitHub Copilot c72722191b Match textual-serve background 2026-01-22 00:37:59 +00:00
GitHub Copilot 20d33a97f8 Fix terminal font fallback 2026-01-22 00:34:11 +00:00
Rui Carmo a0e31d43fd merge 2026-01-21 23:53:57 +00:00