ghostty-web 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/INSTALL.md ADDED
@@ -0,0 +1,181 @@
1
+ # Installation & Usage
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ npm install @coder/ghostty-web
7
+ # or
8
+ bun add @coder/ghostty-web
9
+ # or
10
+ yarn add @coder/ghostty-web
11
+ ```
12
+
13
+ ### Installing from Git
14
+
15
+ You can install directly from GitHub:
16
+
17
+ ```bash
18
+ npm install github:coder/ghostty-web
19
+ # or
20
+ bun add github:coder/ghostty-web
21
+ ```
22
+
23
+ **Note:** Git installs require manually building the package first. See [Local Development](#local-development) for build instructions.
24
+
25
+ ## Basic Usage
26
+
27
+ ```typescript
28
+ import { Terminal } from '@coder/ghostty-web';
29
+
30
+ const term = new Terminal({
31
+ cols: 80,
32
+ rows: 24,
33
+ cursorBlink: true,
34
+ theme: {
35
+ background: '#1e1e1e',
36
+ foreground: '#d4d4d4',
37
+ },
38
+ });
39
+
40
+ // Mount to DOM
41
+ await term.open(document.getElementById('terminal'));
42
+
43
+ // Write output
44
+ term.write('Hello, World!\r\n');
45
+ term.write('\x1b[1;32mGreen text\x1b[0m\r\n');
46
+
47
+ // Handle user input
48
+ term.onData((data) => {
49
+ console.log('User typed:', data);
50
+ // Send to backend, echo, etc.
51
+ });
52
+ ```
53
+
54
+ ## With FitAddon (Responsive Sizing)
55
+
56
+ ```typescript
57
+ import { Terminal, FitAddon } from '@coder/ghostty-web';
58
+
59
+ const term = new Terminal();
60
+ const fitAddon = new FitAddon();
61
+ term.loadAddon(fitAddon);
62
+
63
+ await term.open(document.getElementById('terminal'));
64
+ fitAddon.fit(); // Resize to container
65
+
66
+ // Resize on window resize
67
+ window.addEventListener('resize', () => fitAddon.fit());
68
+ ```
69
+
70
+ ## WebSocket Integration
71
+
72
+ ```typescript
73
+ import { Terminal } from '@coder/ghostty-web';
74
+
75
+ const term = new Terminal();
76
+ await term.open(document.getElementById('terminal'));
77
+
78
+ const ws = new WebSocket('ws://localhost:3001/ws');
79
+
80
+ // Send user input to backend
81
+ term.onData((data) => {
82
+ ws.send(JSON.stringify({ type: 'input', data }));
83
+ });
84
+
85
+ // Display backend output
86
+ ws.onmessage = (event) => {
87
+ const msg = JSON.parse(event.data);
88
+ term.write(msg.data);
89
+ };
90
+ ```
91
+
92
+ ## WASM File Handling
93
+
94
+ The library requires the `ghostty-vt.wasm` file at runtime. When installing from npm, the WASM is pre-built and included in the package.
95
+
96
+ ### Local Development
97
+
98
+ After cloning:
99
+
100
+ ```bash
101
+ ./scripts/build-wasm.sh
102
+ ```
103
+
104
+ The script will automatically initialize the submodule if needed. The WASM file is generated locally and gitignored.
105
+
106
+ ### Vite (Recommended)
107
+
108
+ Vite handles WASM automatically. No extra config needed:
109
+
110
+ ```javascript
111
+ // vite.config.js
112
+ export default {
113
+ // WASM works out of the box
114
+ };
115
+ ```
116
+
117
+ ### Webpack
118
+
119
+ Configure WASM as an asset:
120
+
121
+ ```javascript
122
+ // webpack.config.js
123
+ module.exports = {
124
+ module: {
125
+ rules: [
126
+ {
127
+ test: /\.wasm$/,
128
+ type: 'asset/resource',
129
+ },
130
+ ],
131
+ },
132
+ };
133
+ ```
134
+
135
+ ### Manual Import (Advanced)
136
+
137
+ ```typescript
138
+ import wasmUrl from '@coder/ghostty-web/ghostty-vt.wasm?url';
139
+ import { Ghostty } from '@coder/ghostty-web';
140
+
141
+ const ghostty = await Ghostty.load(wasmUrl);
142
+ ```
143
+
144
+ ## TypeScript Support
145
+
146
+ Full TypeScript definitions are included:
147
+
148
+ ```typescript
149
+ import { Terminal, ITerminalOptions, ITheme } from '@coder/ghostty-web';
150
+
151
+ const options: ITerminalOptions = {
152
+ cols: 80,
153
+ rows: 24,
154
+ cursorBlink: true,
155
+ };
156
+
157
+ const theme: ITheme = {
158
+ background: '#1e1e1e',
159
+ foreground: '#d4d4d4',
160
+ cursor: '#ffffff',
161
+ };
162
+ ```
163
+
164
+ ## API Documentation
165
+
166
+ See [API.md](https://github.com/coder/ghostty-web/blob/main/packaging/docs/API.md) for complete API reference.
167
+
168
+ ## Migration from xterm.js
169
+
170
+ This library follows xterm.js conventions:
171
+
172
+ ```typescript
173
+ // Before (xterm.js)
174
+ import { Terminal } from 'xterm';
175
+ import { FitAddon } from 'xterm-addon-fit';
176
+
177
+ // After (@coder/ghostty-web)
178
+ import { Terminal, FitAddon } from '@coder/ghostty-web';
179
+ ```
180
+
181
+ Most xterm.js code works with minimal changes. See [API.md](https://github.com/coder/ghostty-web/blob/main/packaging/docs/API.md) for differences.
package/README.md ADDED
@@ -0,0 +1,293 @@
1
+ # Ghostty Web
2
+
3
+ A web-based terminal emulator that integrates [Ghostty's](https://github.com/ghostty-org/ghostty) VT100 parser via WebAssembly.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @coder/ghostty-web
9
+ ```
10
+
11
+ Or install from GitHub:
12
+
13
+ ```bash
14
+ npm install github:coder/ghostty-web
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { Terminal } from '@coder/ghostty-web';
21
+
22
+ const term = new Terminal({ cols: 80, rows: 24 });
23
+ await term.open(document.getElementById('terminal'));
24
+ term.write('Hello, World!\r\n');
25
+ ```
26
+
27
+ See [INSTALL.md](./INSTALL.md) for complete usage guide.
28
+
29
+ ## Features
30
+
31
+ - ✅ Full xterm.js-compatible API
32
+ - ✅ Production-tested VT100 parser (via Ghostty)
33
+ - ✅ ANSI colors (16, 256, RGB true color)
34
+ - ✅ Canvas rendering at 60 FPS
35
+ - ✅ Scrollback buffer
36
+ - ✅ Text selection & clipboard
37
+ - ✅ FitAddon for responsive sizing
38
+ - ✅ TypeScript declarations included
39
+
40
+ ## Development & Demos
41
+
42
+ ### Shell Terminal Demo
43
+
44
+ **Requires server**
45
+
46
+ ```bash
47
+ # Terminal 1: Start PTY shell server
48
+ cd demo/server
49
+ bun install
50
+ bun run start
51
+
52
+ # Terminal 2: Start web server (from project root)
53
+ bun run dev
54
+
55
+ # Open: http://localhost:8000/demo/
56
+ ```
57
+
58
+ This provides a **real persistent shell session**! You can:
59
+
60
+ - Use `cd` and it persists between commands
61
+ - Run interactive programs like `vim`, `nano`, `top`, `htop`
62
+ - Use tab completion and command history (↑/↓)
63
+ - Use pipes, redirects, and background jobs
64
+ - Access all your shell aliases and environment
65
+
66
+ **Alternative: Command-by-Command Mode**
67
+
68
+ For the original file browser (executes each command separately):
69
+
70
+ ```bash
71
+ cd demo/server
72
+ bun run file-browser
73
+ ```
74
+
75
+ **Remote Access:** If you're accessing via a forwarded hostname (e.g., `mux.coder`), make sure to forward both ports:
76
+
77
+ - Port 8000 (web server - Vite)
78
+ - Port 3001 (WebSocket server)
79
+
80
+ The terminal will automatically connect to the WebSocket using the same hostname you're accessing the page from.
81
+
82
+ **Colors Demo** (no server needed)
83
+
84
+ ```bash
85
+ bun run dev
86
+ # Open: http://localhost:8000/demo/colors-demo.html
87
+ ```
88
+
89
+ See all ANSI colors (16, 256, RGB) and text styles in action.
90
+
91
+ ## Usage
92
+
93
+ ### Basic Terminal
94
+
95
+ ```typescript
96
+ import { Terminal } from './lib/index.ts';
97
+ import { FitAddon } from './lib/addons/fit.ts';
98
+
99
+ // Create terminal
100
+ const term = new Terminal({
101
+ cols: 80,
102
+ rows: 24,
103
+ cursorBlink: true,
104
+ theme: {
105
+ background: '#1e1e1e',
106
+ foreground: '#d4d4d4',
107
+ },
108
+ });
109
+
110
+ // Add FitAddon for responsive sizing
111
+ const fitAddon = new FitAddon();
112
+ term.loadAddon(fitAddon);
113
+
114
+ // Open in container
115
+ await term.open(document.getElementById('terminal'));
116
+ fitAddon.fit();
117
+
118
+ // Write output (supports ANSI colors)
119
+ term.write('Hello, World!\r\n');
120
+ term.write('\x1b[1;32mGreen bold text\x1b[0m\r\n');
121
+
122
+ // Handle user input
123
+ term.onData((data) => {
124
+ console.log('User typed:', data);
125
+ // Send to backend, echo, etc.
126
+ });
127
+ ```
128
+
129
+ ### WebSocket Integration
130
+
131
+ ```typescript
132
+ const ws = new WebSocket('ws://localhost:3001/ws');
133
+
134
+ // Send user input to backend
135
+ term.onData((data) => {
136
+ ws.send(JSON.stringify({ type: 'input', data }));
137
+ });
138
+
139
+ // Display backend output
140
+ ws.onmessage = (event) => {
141
+ const msg = JSON.parse(event.data);
142
+ term.write(msg.data);
143
+ };
144
+ ```
145
+
146
+ See [AGENTS.md](AGENTS.md) for development guide and code patterns.
147
+
148
+ ## Why This Approach?
149
+
150
+ **DON'T** re-implement VT100 parsing from scratch (years of work, thousands of edge cases).
151
+
152
+ **DO** use Ghostty's proven parser:
153
+
154
+ - ✅ Battle-tested by thousands of users
155
+ - ✅ Handles all VT100/ANSI quirks correctly
156
+ - ✅ Modern features (RGB colors, Kitty keyboard protocol)
157
+ - ✅ Get bug fixes and updates for free
158
+
159
+ **You build**: Screen buffer, rendering, UI (the "easy" parts in TypeScript)
160
+ **Ghostty handles**: VT100 parsing (the hard part via WASM)
161
+
162
+ ## Architecture
163
+
164
+ ```
165
+ ┌─────────────────────────────────────────┐
166
+ │ Terminal (lib/terminal.ts) │
167
+ │ - Public xterm.js-compatible API │
168
+ │ - Event handling (onData, onResize) │
169
+ └───────────┬─────────────────────────────┘
170
+
171
+ ├─► ScreenBuffer (lib/buffer.ts)
172
+ │ - 2D grid, cursor, scrollback
173
+
174
+ ├─► VTParser (lib/vt-parser.ts)
175
+ │ - ANSI escape sequence parsing
176
+ │ └─► Ghostty WASM (SGR parser)
177
+
178
+ ├─► CanvasRenderer (lib/renderer.ts)
179
+ │ - Canvas-based rendering
180
+ │ - 60 FPS, supports all colors
181
+
182
+ └─► InputHandler (lib/input-handler.ts)
183
+ - Keyboard events → escape codes
184
+ └─► Ghostty WASM (Key encoder)
185
+
186
+ WebSocket Server (server/file-browser-server.ts)
187
+ └─► Executes shell commands (ls, cd, cat, etc.)
188
+ ```
189
+
190
+ ## Project Structure
191
+
192
+ ```
193
+ ├── lib/
194
+ │ ├── terminal.ts - Main Terminal class (xterm.js-compatible)
195
+ │ ├── buffer.ts - Screen buffer with scrollback
196
+ │ ├── vt-parser.ts - VT100/ANSI escape sequence parser
197
+ │ ├── renderer.ts - Canvas-based renderer
198
+ │ ├── input-handler.ts - Keyboard input handling
199
+ │ ├── ghostty.ts - Ghostty WASM wrapper
200
+ │ ├── types.ts - TypeScript type definitions
201
+ │ ├── interfaces.ts - xterm.js-compatible interfaces
202
+ │ └── addons/
203
+ │ └── fit.ts - FitAddon for responsive sizing
204
+
205
+ ├── demo/
206
+ │ ├── index.html - File browser terminal
207
+ │ ├── colors-demo.html - ANSI colors showcase
208
+ │ └── server/
209
+ │ ├── file-browser-server.ts - WebSocket server
210
+ │ ├── package.json
211
+ │ └── start.sh - Startup script (auto-kills port conflicts)
212
+
213
+ ├── docs/
214
+ │ └── API.md - Complete API documentation
215
+
216
+ └── ghostty-vt.wasm - Ghostty VT100 parser (122 KB)
217
+ ```
218
+
219
+ ## Building WASM
220
+
221
+ The WASM binary is built from source, not committed to the repo.
222
+
223
+ **Requirements:**
224
+
225
+ - Zig 0.15.2+
226
+ - Git submodules initialized
227
+
228
+ **Build:**
229
+
230
+ ```bash
231
+ # Initialize submodule (first time only)
232
+ git submodule update --init --recursive
233
+
234
+ # Build WASM
235
+ ./scripts/build-wasm.sh
236
+ # or
237
+ bun run build:wasm
238
+ ```
239
+
240
+ **What it does:**
241
+
242
+ 1. Initializes `ghostty/` submodule (ghostty-org/ghostty)
243
+ 2. Applies patches from `patches/ghostty-wasm-api.patch`
244
+ 3. Builds WASM with Zig (takes ~20 seconds)
245
+ 4. Outputs `ghostty-vt.wasm` (404 KB)
246
+ 5. Reverts patch to keep submodule clean
247
+
248
+ **Updating Ghostty:**
249
+
250
+ ```bash
251
+ cd ghostty
252
+ git fetch origin
253
+ git checkout <commit-or-tag>
254
+ cd ..
255
+ ./scripts/build-wasm.sh
256
+ # Test, then commit the updated submodule pointer
257
+ ```
258
+
259
+ **CI:** The WASM is built as part of the `test` and `build` jobs.
260
+
261
+ ## Testing
262
+
263
+ Run the test suite:
264
+
265
+ ```bash
266
+ bun test # Run all tests
267
+ bun test --watch # Watch mode
268
+ bun run typecheck # Type checking
269
+ bun run build # Build distribution
270
+ ```
271
+
272
+ **Test Coverage:**
273
+
274
+ - ✅ ScreenBuffer (63 tests, 163 assertions)
275
+ - ✅ VTParser (45 tests)
276
+ - ✅ CanvasRenderer (11 tests)
277
+ - ✅ InputHandler (35 tests)
278
+ - ✅ Terminal integration (25 tests)
279
+ - ✅ FitAddon (12 tests)
280
+
281
+ ## Documentation
282
+
283
+ - **[AGENTS.md](AGENTS.md)** - Development guide for AI agents and developers
284
+
285
+ ## Links
286
+
287
+ - [Ghostty Terminal](https://github.com/ghostty-org/ghostty)
288
+ - [libghostty-vt API](https://github.com/ghostty-org/ghostty/tree/main/include/ghostty/vt)
289
+ - [VT100 Reference](https://vt100.net/docs/vt100-ug/)
290
+
291
+ ## License
292
+
293
+ See cmux LICENSE (AGPL-3.0)
@@ -0,0 +1,4 @@
1
+ const e = {};
2
+ export {
3
+ e as default
4
+ };
Binary file