Skip to content

Commit b21c6a3

Browse files
authored
Task 8: Complete demos and documentation (#11)
- Created PTY shell server with real shell sessions - Created file browser terminal demo (demo/index.html) - Created ANSI colors showcase (demo/colors-demo.html) - Created comprehensive API documentation (docs/API.md) - Updated README with new structure and instructions - Organized demo/ directory with server subdirectory - Fixed hostname auto-detection for remote access (mux.coder) - Filtered OSC sequences for clean output - Added debug logging for troubleshooting Files created: - demo/server/pty-server.ts (217 lines) - Real PTY shell via WebSocket - demo/server/file-browser-server.ts (313 lines) - Command-by-command mode - demo/server/package.json - Server configuration - demo/server/start.sh - Startup helper script - demo/index.html (506 lines) - Interactive file browser terminal - demo/colors-demo.html (526 lines) - ANSI color showcase - docs/API.md (1046 lines) - Complete API reference Total new code: ~2,500 lines Features: - Full PTY shell session support - Real command execution with persistent state - WebSocket communication with hostname auto-detection - ANSI color filtering and cleanup - Comprehensive documentation - Clean project structure
1 parent 1619b9b commit b21c6a3

14 files changed

Lines changed: 2976 additions & 3292 deletions

README.md

Lines changed: 172 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,56 +7,121 @@ A terminal emulator that integrates [Ghostty's](https://github.com/ghostty-org/g
77
This repository provides a **foundation for building web-based terminals** using Ghostty's production-tested VT100 parser compiled to WebAssembly.
88

99
**What's implemented:**
10+
- ✅ Full terminal emulator with screen buffer, VT parser, canvas renderer
1011
- ✅ TypeScript wrapper for libghostty-vt WASM API
11-
- ✅ SGR parser (ANSI colors and text styles)
12+
- ✅ SGR parser (ANSI colors, 256-color, RGB true color)
1213
- ✅ Key encoder (keyboard events → escape sequences)
13-
- ✅ Demo showing parser in action
14+
- ✅ FitAddon for responsive terminal sizing
15+
- ✅ Interactive demos (file browser, color showcase)
16+
- ✅ xterm.js-compatible API
1417

15-
**What's missing (TODO):**
16-
- ❌ Terminal screen buffer
17-
- ❌ Canvas rendering
18-
- ❌ VT100 state machine
19-
- ❌ PTY connection
20-
- ❌ Scrollback, selection, clipboard
18+
**MVP Complete!** See demos below.
2119

2220
## Quick Start
2321

22+
### Run the Terminal
23+
24+
**Shell Terminal** (requires server)
25+
26+
```bash
27+
# Terminal 1: Start PTY shell server
28+
cd demo/server
29+
bun install
30+
bun run start
31+
32+
# Terminal 2: Start web server (from project root)
33+
bun run dev
34+
35+
# Open: http://localhost:8000/demo/
36+
```
37+
38+
This provides a **real persistent shell session**! You can:
39+
- Use `cd` and it persists between commands
40+
- Run interactive programs like `vim`, `nano`, `top`, `htop`
41+
- Use tab completion and command history (↑/↓)
42+
- Use pipes, redirects, and background jobs
43+
- Access all your shell aliases and environment
44+
45+
**Alternative: Command-by-Command Mode**
46+
47+
For the original file browser (executes each command separately):
2448
```bash
25-
./run-demo.sh
26-
# Opens: http://localhost:8000/examples/sgr-demo.html
49+
cd demo/server
50+
bun run file-browser
2751
```
2852

29-
The script will automatically:
30-
1. Check if `ghostty-vt.wasm` exists
31-
2. Build it from Ghostty source if needed
32-
3. Start an HTTP server
33-
4. Show you the URL to open
53+
**Remote Access:** If you're accessing via a forwarded hostname (e.g., `mux.coder`), make sure to forward both ports:
54+
- Port 8000 (web server - Vite)
55+
- Port 3001 (WebSocket server)
56+
57+
The terminal will automatically connect to the WebSocket using the same hostname you're accessing the page from.
58+
59+
**Colors Demo** (no server needed)
60+
61+
```bash
62+
bun run dev
63+
# Open: http://localhost:8000/demo/colors-demo.html
64+
```
65+
66+
See all ANSI colors (16, 256, RGB) and text styles in action.
3467

3568
## Usage
3669

70+
### Basic Terminal
71+
3772
```typescript
38-
import { Ghostty, SgrAttributeTag, KeyAction, Key, Mods } from './lib/ghostty.ts';
39-
40-
// Load WASM
41-
const ghostty = await Ghostty.load('./ghostty-vt.wasm');
42-
43-
// Parse colors (ESC[1;31m → Bold + Red)
44-
const parser = ghostty.createSgrParser();
45-
for (const attr of parser.parse([1, 31])) {
46-
if (attr.tag === SgrAttributeTag.BOLD) console.log('Bold!');
47-
if (attr.tag === SgrAttributeTag.FG_8) console.log('Red:', attr.color);
48-
}
49-
50-
// Encode keyboard (Ctrl+A → 0x01)
51-
const encoder = ghostty.createKeyEncoder();
52-
const bytes = encoder.encode({
53-
action: KeyAction.PRESS,
54-
key: Key.A,
55-
mods: Mods.CTRL,
73+
import { Terminal } from './lib/index.ts';
74+
import { FitAddon } from './lib/addons/fit.ts';
75+
76+
// Create terminal
77+
const term = new Terminal({
78+
cols: 80,
79+
rows: 24,
80+
cursorBlink: true,
81+
theme: {
82+
background: '#1e1e1e',
83+
foreground: '#d4d4d4',
84+
}
5685
});
57-
// Send bytes to PTY
86+
87+
// Add FitAddon for responsive sizing
88+
const fitAddon = new FitAddon();
89+
term.loadAddon(fitAddon);
90+
91+
// Open in container
92+
await term.open(document.getElementById('terminal'));
93+
fitAddon.fit();
94+
95+
// Write output (supports ANSI colors)
96+
term.write('Hello, World!\r\n');
97+
term.write('\x1b[1;32mGreen bold text\x1b[0m\r\n');
98+
99+
// Handle user input
100+
term.onData(data => {
101+
console.log('User typed:', data);
102+
// Send to backend, echo, etc.
103+
});
104+
```
105+
106+
### WebSocket Integration
107+
108+
```typescript
109+
const ws = new WebSocket('ws://localhost:3001/ws');
110+
111+
// Send user input to backend
112+
term.onData(data => {
113+
ws.send(JSON.stringify({ type: 'input', data }));
114+
});
115+
116+
// Display backend output
117+
ws.onmessage = (event) => {
118+
const msg = JSON.parse(event.data);
119+
term.write(msg.data);
120+
};
58121
```
59122

123+
**Full API Documentation:** [docs/API.md](docs/API.md)
124+
60125
## Why This Approach?
61126

62127
**DON'T** re-implement VT100 parsing from scratch (years of work, thousands of edge cases).
@@ -73,28 +138,59 @@ const bytes = encoder.encode({
73138
## Architecture
74139

75140
```
76-
Your Terminal (TypeScript)
77-
├─ Screen buffer (2D array)
78-
├─ Canvas rendering
79-
├─ Keyboard/mouse events
80-
└─ PTY connection
81-
82-
83-
Ghostty WASM (this repo)
84-
├─ Parse colors: ESC[1;31m → Bold + Red
85-
└─ Encode keys: Ctrl+A → 0x01
86-
87-
88-
libghostty-vt.wasm (122 KB)
89-
└─ Production VT100 parser
141+
┌─────────────────────────────────────────┐
142+
│ Terminal (lib/terminal.ts) │
143+
│ - Public xterm.js-compatible API │
144+
│ - Event handling (onData, onResize) │
145+
└───────────┬─────────────────────────────┘
146+
147+
├─► ScreenBuffer (lib/buffer.ts)
148+
│ - 2D grid, cursor, scrollback
149+
150+
├─► VTParser (lib/vt-parser.ts)
151+
│ - ANSI escape sequence parsing
152+
│ └─► Ghostty WASM (SGR parser)
153+
154+
├─► CanvasRenderer (lib/renderer.ts)
155+
│ - Canvas-based rendering
156+
│ - 60 FPS, supports all colors
157+
158+
└─► InputHandler (lib/input-handler.ts)
159+
- Keyboard events → escape codes
160+
└─► Ghostty WASM (Key encoder)
161+
162+
WebSocket Server (server/file-browser-server.ts)
163+
└─► Executes shell commands (ls, cd, cat, etc.)
90164
```
91165

92-
## Files
166+
## Project Structure
93167

94-
- `lib/ghostty.ts` - TypeScript wrapper for WASM
95-
- `lib/types.ts` - Type definitions
96-
- `examples/sgr-demo.html` - Interactive demo
97-
- `AGENTS.md` - Implementation guide for building the terminal
168+
```
169+
├── lib/
170+
│ ├── terminal.ts - Main Terminal class (xterm.js-compatible)
171+
│ ├── buffer.ts - Screen buffer with scrollback
172+
│ ├── vt-parser.ts - VT100/ANSI escape sequence parser
173+
│ ├── renderer.ts - Canvas-based renderer
174+
│ ├── input-handler.ts - Keyboard input handling
175+
│ ├── ghostty.ts - Ghostty WASM wrapper
176+
│ ├── types.ts - TypeScript type definitions
177+
│ ├── interfaces.ts - xterm.js-compatible interfaces
178+
│ └── addons/
179+
│ └── fit.ts - FitAddon for responsive sizing
180+
181+
├── demo/
182+
│ ├── index.html - File browser terminal
183+
│ ├── colors-demo.html - ANSI colors showcase
184+
│ └── server/
185+
│ ├── file-browser-server.ts - WebSocket server
186+
│ ├── package.json
187+
│ └── start.sh - Startup script (auto-kills port conflicts)
188+
189+
├── docs/
190+
│ └── API.md - Complete API documentation
191+
192+
└── ghostty-vt.wasm - Ghostty VT100 parser (122 KB)
193+
```
98194

99195
## Building
100196

@@ -119,13 +215,30 @@ zig build lib-vt -Dtarget=wasm32-freestanding -Doptimize=ReleaseSmall
119215
# Output: zig-out/bin/ghostty-vt.wasm (122 KB)
120216
```
121217

122-
## Next Steps
218+
## Testing
219+
220+
Run the test suite:
221+
222+
```bash
223+
bun test # Run all tests
224+
bun test --watch # Watch mode
225+
bun run typecheck # Type checking
226+
bun run build # Build distribution
227+
```
228+
229+
**Test Coverage:**
230+
- ✅ ScreenBuffer (63 tests, 163 assertions)
231+
- ✅ VTParser (45 tests)
232+
- ✅ CanvasRenderer (11 tests)
233+
- ✅ InputHandler (35 tests)
234+
- ✅ Terminal integration (25 tests)
235+
- ✅ FitAddon (12 tests)
236+
237+
## Documentation
123238

124-
See **[AGENTS.md](./AGENTS.md)** for:
125-
- How to implement the terminal
126-
- Code examples for screen buffer, rendering
127-
- VT100 state machine guide
128-
- Testing instructions
239+
- **[API Documentation](docs/API.md)** - Complete API reference
240+
- **[AGENTS.md](AGENTS.md)** - Implementation guide for developers
241+
- **[roadmap.md](roadmap.md)** - Project roadmap and task breakdown
129242

130243
## Links
131244

0 commit comments

Comments
 (0)