Update documentation for xterm.js 6.0 migration
- README: Add scrollback feature, frontend dev instructions, update related projects - ARCHITECTURE: Document xterm.js bundling decision, update file structure
This commit is contained in:
@@ -6,7 +6,7 @@ Serve terminal sessions and Textual apps over the web with a simple CLI command.
|
||||
|
||||
This is heavily based on [textual-web](https://github.com/Textualize/textual-web), but specifically focused on serving a persistent terminal session in a way that you can host behind a reverse proxy (and some form of authentication).
|
||||
|
||||
Built on top of [textual-serve](https://github.com/Textualize/textual-serve), this package provides an easy way to expose terminal sessions and Textual applications via HTTP/WebSocket with automatic reconnection support.
|
||||
Built on [xterm.js](https://xtermjs.org/) 6.0, this package provides an easy way to expose terminal sessions and Textual applications via HTTP/WebSocket with automatic reconnection support.
|
||||
|
||||
Coupled with [`agentbox`](https://github.com/rcarmo/agentbox), you can use it to keep track of several containerized AI coding agents:
|
||||
|
||||
@@ -18,6 +18,7 @@ Coupled with [`agentbox`](https://github.com/rcarmo/agentbox), you can use it to
|
||||
- 🐍 **Textual app support** - Serve Textual apps directly from Python modules
|
||||
- 🔄 **Session reconnection** - Refresh the page and reconnect to the same session
|
||||
- 🎨 **Full terminal emulation** - Colors, cursor, and ANSI codes work correctly
|
||||
- 📜 **Scrollback history** - Scroll back through terminal output (configurable)
|
||||
- 📐 **Auto-sizing** - Terminal automatically resizes to fit the browser window
|
||||
- 📸 **Live screenshots** - Dashboard shows real-time SVG screenshots of terminals
|
||||
- 📊 **CPU sparklines** - Dashboard displays 30-minute CPU history for Docker containers
|
||||
@@ -162,14 +163,34 @@ make install-dev
|
||||
- Lint: `make lint`
|
||||
- Format: `make format`
|
||||
- Tests: `make test`
|
||||
- Coverage (fail_under=80): `make coverage`
|
||||
- Coverage (fail_under=79): `make coverage`
|
||||
- Full check (lint + coverage): `make check`
|
||||
|
||||
### Frontend Development
|
||||
|
||||
The terminal UI is built with [xterm.js](https://xtermjs.org/) 6.0. The pre-built bundle is committed to the repo, so users can `pip install` without needing Node.js.
|
||||
|
||||
To rebuild the frontend after modifying `terminal.ts`:
|
||||
|
||||
```bash
|
||||
# Requires Bun (https://bun.sh)
|
||||
bun install
|
||||
bun run build
|
||||
# Or simply:
|
||||
make bundle
|
||||
```
|
||||
|
||||
For development with auto-rebuild:
|
||||
|
||||
```bash
|
||||
make bundle-watch
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- WebSocket protocol (browser <-> server) is JSON: `["stdin", data]`, `["resize", {"width": w, "height": h}]`, `["ping", data]`.
|
||||
- Static assets are provided by `textual-serve`; this project does not add custom static files.
|
||||
- Screenshots use [pyte](https://github.com/selectel/pyte) for ANSI interpretation and [Rich](https://github.com/Textualize/rich) for SVG rendering.
|
||||
- WebSocket protocol (browser ↔ server) is JSON: `["stdin", data]`, `["resize", {"width": w, "height": h}]`, `["ping", data]`.
|
||||
- Frontend source is in `src/textual_webterm/static/js/terminal.ts`.
|
||||
- Screenshots use [pyte](https://github.com/selectel/pyte) for ANSI interpretation and custom SVG rendering.
|
||||
- CPU stats are read directly from Docker socket using asyncio (no additional dependencies).
|
||||
|
||||
## Requirements
|
||||
@@ -184,6 +205,5 @@ MIT License - see [LICENSE](LICENSE) for details.
|
||||
## Related Projects
|
||||
|
||||
- [Textual](https://github.com/Textualize/textual) - TUI framework for Python
|
||||
- [textual-serve](https://github.com/Textualize/textual-serve) - Serve Textual apps on the web
|
||||
- [Rich](https://github.com/Textualize/rich) - Rich text formatting for terminals
|
||||
- [xterm.js](https://xtermjs.org/) - Terminal emulator for the web
|
||||
- [pyte](https://github.com/selectel/pyte) - PYTE terminal emulator
|
||||
|
||||
+19
-2
@@ -186,6 +186,17 @@ JSON-encoded messages over WebSocket:
|
||||
|
||||
## Key Design Decisions
|
||||
|
||||
### Why bundle xterm.js directly?
|
||||
|
||||
We bundle xterm.js 6.0 directly rather than using textual-serve because:
|
||||
|
||||
- **Full configuration control** - fontFamily, scrollback, theme are configurable
|
||||
- **No workarounds needed** - xterm.js uses canvas rendering which ignores CSS fonts
|
||||
- **Smaller footprint** - No unused fonts or images from textual-serve
|
||||
- **Latest features** - xterm.js 6.0 includes ligature support, synchronized output, etc.
|
||||
|
||||
The pre-built `terminal.js` bundle is committed to the repo so users can `pip install` without needing Node.js/Bun.
|
||||
|
||||
### Why custom SVG exporter?
|
||||
|
||||
Rich's `export_svg()` had alignment issues with box-drawing characters and varied font rendering across browsers. The custom exporter:
|
||||
@@ -214,7 +225,7 @@ Unlike traditional web terminals, sessions survive page refreshes:
|
||||
|
||||
```
|
||||
src/textual_webterm/
|
||||
├── cli.py # Typer CLI entry point
|
||||
├── cli.py # Click CLI entry point
|
||||
├── config.py # Configuration parsing (YAML manifests)
|
||||
├── local_server.py # Main HTTP/WebSocket server
|
||||
├── session_manager.py # Session registry and routing
|
||||
@@ -228,5 +239,11 @@ src/textual_webterm/
|
||||
├── identity.py # Session ID generation
|
||||
├── slugify.py # URL-safe slug generation
|
||||
├── types.py # Type aliases
|
||||
└── constants.py # Platform constants
|
||||
├── constants.py # Platform constants
|
||||
└── static/
|
||||
├── monospace.css # Font stack CSS variables
|
||||
├── css/xterm.css # xterm.js styles
|
||||
└── js/
|
||||
├── terminal.ts # xterm.js client source (TypeScript)
|
||||
└── terminal.js # Pre-built bundle (committed)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user