@@ -6,23 +6,34 @@ This repository integrates **libghostty-vt** (Ghostty's VT100 parser) with WebAs
66
77### What's Implemented
88
9- ** TypeScript Wrapper (618 lines)**
9+ ** Task 1: TypeScript Wrapper (618 lines)** ✅
1010- ` lib/types.ts ` - Type definitions for libghostty-vt C API
1111- ` lib/ghostty.ts ` - ` Ghostty ` , ` SgrParser ` , ` KeyEncoder ` classes
1212- Automatic memory management for WASM pointers
13-
14- ** Demo**
15- - ` examples/sgr-demo.html ` - Interactive SGR parser demo
13+ - Demo: ` examples/sgr-demo.html ` - Interactive SGR parser demo
14+
15+ ** Task 2: Screen Buffer (1,704 lines)** ✅
16+ - ` lib/buffer.ts ` - ScreenBuffer class (840 lines)
17+ - 2D grid with cursor management
18+ - Wide character support (CJK, emoji, combining chars)
19+ - Scroll regions (DECSTBM) for vim-like apps
20+ - Terminal modes (origin, insert, autowrap)
21+ - Scrollback buffer with size limits
22+ - xterm.js-compatible API
23+ - ` lib/buffer.test.ts ` - 63 comprehensive tests (864 lines)
24+ - All passing, 163 assertions
25+ - Covers all features and edge cases
26+ - Demo: ` examples/buffer-demo.html ` - Interactive buffer testing
1627
1728### What's Missing (Your Job)
1829
19- ** Terminal Implementation** - The screen buffer, rendering, and state machine:
20- 1 . Screen buffer (2D array of cells)
30+ ** Terminal Implementation** - Rendering and state machine:
31+ 1 . ~~ Screen buffer (2D array of cells)~~ ✅ ** DONE (Task 2) **
21322 . Canvas renderer (draw cells with colors)
22333 . VT100 state machine (parse escape sequences, use Ghostty parsers)
23344 . Keyboard input handler (use KeyEncoder)
24355 . PTY connection (IPC to backend)
25- 6 . Scrollback buffer
36+ 6 . ~~ Scrollback buffer~~ ✅ ** DONE (Task 2) **
26377 . Selection/clipboard
2738
2839## Building the WASM
@@ -81,7 +92,79 @@ python3 -m http.server 8000
8192└──────────────────────────────────────────┘
8293```
8394
84- ## Using the Ghostty API
95+ ## Using the APIs
96+
97+ ### ScreenBuffer API (Task 2)
98+
99+ ``` typescript
100+ import { ScreenBuffer } from ' ./lib/buffer.ts' ;
101+
102+ // Create buffer
103+ const buffer = new ScreenBuffer (80 , 24 , 1000 );
104+
105+ // Write text
106+ buffer .writeString (' Hello, World!' );
107+ buffer .getCursor (); // {x: 13, y: 0, visible: true}
108+
109+ // Wide characters (CJK, emoji)
110+ buffer .writeChar (' 中' ); // Takes 2 cells
111+ buffer .getCursor (); // {x: 15, y: 0, ...} - advanced by 2!
112+
113+ // Cursor movement
114+ buffer .moveCursorTo (10 , 5 );
115+ buffer .moveCursorUp (2 );
116+ buffer .saveCursor ();
117+ buffer .restoreCursor ();
118+
119+ // Styling
120+ buffer .setStyle ({
121+ bold: true ,
122+ fg: { type: ' palette' , index: 1 } // Red
123+ });
124+ buffer .writeString (' Bold red text' );
125+ buffer .resetStyle ();
126+
127+ // Scroll regions (for vim-like apps)
128+ buffer .setScrollRegion (5 , 20 ); // Lines 5-20 scroll
129+ buffer .setOriginMode (true ); // Cursor relative to region
130+ buffer .moveCursorTo (0 , 0 ); // Goes to line 5 (region top)
131+
132+ // Scrolling
133+ buffer .scrollUp (1 ); // Scroll up 1 line
134+ buffer .index (); // Move down, scroll if at bottom
135+ buffer .reverseIndex (); // Move up, scroll if at top
136+
137+ // Erasing
138+ buffer .eraseInLine (2 ); // Clear entire line
139+ buffer .eraseInDisplay (2 ); // Clear entire screen
140+
141+ // Line operations
142+ buffer .insertLines (2 ); // Insert 2 blank lines
143+ buffer .deleteLines (1 ); // Delete current line
144+
145+ // Modes
146+ buffer .setAutoWrap (false ); // Disable wrapping
147+ buffer .setInsertMode (true ); // Insert vs replace
148+
149+ // Access data (returns copies)
150+ const line = buffer .getLine (0 );
151+ const allLines = buffer .getAllLines ();
152+ const scrollback = buffer .getScrollback ();
153+
154+ // Dirty tracking for efficient rendering
155+ if (buffer .isDirty (5 )) {
156+ renderLine (5 );
157+ }
158+ buffer .clearDirty ();
159+
160+ // xterm.js-compatible properties
161+ buffer .cursorX ; // Same as getCursor().x
162+ buffer .cursorY ; // Same as getCursor().y
163+ buffer .baseY ; // Scrollback length
164+ buffer .length ; // Total lines (scrollback + rows)
165+ ```
166+
167+ ### Ghostty SGR Parser API (Task 1)
85168
86169### Parse SGR (Colors/Styles)
87170
@@ -307,8 +390,84 @@ console.log(bytes); // Uint8Array([1])
307390
308391**Estimated time**: 2-4 weeks for MVP terminal
309392
393+ ## Testing & Development
394+
395+ ### Running Tests
396+
397+ **Run automated tests:**
398+ ```bash
399+ bun test # Run all tests
400+ bun test lib/buffer.test.ts # Run specific test file
401+ bun test --watch # Watch mode
402+ ```
403+
404+ **TypeScript type checking:**
405+ ```bash
406+ bun run typecheck # Check types without compiling
407+ ```
408+
409+ ### Running Demos
410+
411+ **⚠️ IMPORTANT: Use Vite, not basic HTTP server!**
412+
413+ ```bash
414+ # ✅ CORRECT - Use Vite for TypeScript imports
415+ bun run dev
416+
417+ # ❌ WRONG - Basic HTTP server can' t handle TypeScript
418+ python3 -m http.server 8000
419+ ` ` `
420+
421+ Then open:
422+ - Buffer Demo: ` http://localhost:8000/examples/buffer-demo.html`
423+ - SGR Demo: ` http://localhost:8000/examples/sgr-demo.html`
424+
425+ # ## Demo Testing Tips
426+
427+ ** Task 2: Screen Buffer Demo**
428+
429+ When testing ` buffer-demo.html` :
430+
431+ 1. ** Check status banner** at top:
432+ - ✅ Green " Ready!" = Success
433+ - ❌ Red " Error!" = Check console
434+
435+ 2. ** Open browser console (F12)** to see:
436+ ` ` `
437+ ✅ ScreenBuffer loaded successfully
438+ ✅ Buffer instance created
439+ ✅ Buffer demo loaded successfully!
440+ ` ` `
441+
442+ 3. ** Click test scenario buttons** and watch console:
443+ ` ` `
444+ 🧪 Running Test 1: Basic Writing
445+ ✅ Test 1 complete
446+ ` ` `
447+
448+ 4. ** Visual checks:**
449+ - Blinking green cursor should be visible
450+ - Stats update: cursor position, scrollback count
451+ - Terminal content appears when clicking buttons
452+
453+ 5. ** Manual testing in console:**
454+ ` ` ` javascript
455+ // Test buffer API directly
456+ buffer.writeString(' Hello!' )
457+ buffer.getCursor () // {x: 6, y: 0, ...}
458+ buffer.writeChar(' 中' ) // Wide char
459+ buffer.getCursor () // x increased by 2!
460+ renderBuffer () // Update display
461+ ` ` `
462+
463+ ** Critical tests:**
464+ - ** Test 3 (Wide Chars)** : Chinese 中文 should be visibly WIDER than ABC
465+ - ** Test 4 (Scroll Region)** : Headers/footers stay fixed while middle scrolls
466+
310467# # Troubleshooting
311468
469+ # ## Build/WASM Issues
470+
312471** WASM not loading?**
313472- Check file exists: ` ls -lh ghostty-vt.wasm`
314473- Check browser console for fetch errors
@@ -323,3 +482,74 @@ console.log(bytes); // Uint8Array([1])
323482- Check WASM exports: ` wasm-objdump -x ghostty-vt.wasm | grep export`
324483- Check browser console for errors
325484- Test with demo: ` http://localhost:8000/examples/sgr-demo.html`
485+
486+ # ## Demo Issues
487+
488+ ** " Nothing is rendering in the terminal" **
489+ - ❌ Using basic HTTP server → ** Use ` bun run dev` instead! **
490+ - Refresh browser (Ctrl+Shift+R)
491+ - Check console for import errors
492+ - Verify status banner is green
493+
494+ ** " Buttons don't work" **
495+ - Check console (F12) for JavaScript errors
496+ - Try manual test: `testBasicWriting ()` in console
497+ - Verify functions exist: ` window.testBasicWriting` should be ` function`
498+
499+ ** " Wide characters look wrong" **
500+ - This is expected with basic HTML rendering
501+ - Verify in console: cursor advances by 2 for wide chars
502+ - Proper rendering comes in Task 4 (Canvas Renderer)
503+
504+ ** Module import errors**
505+ - Must use Vite dev server: ` bun run dev`
506+ - Don' t use: `python3 -m http.server` or `./run-demo.sh` without Vite
507+ - Check `package.json` scripts are correct
508+
509+ ### Test Failures
510+
511+ **If tests fail:**
512+ ```bash
513+ # Run specific test file with verbose output
514+ bun test lib/buffer.test.ts
515+
516+ # Check TypeScript compilation
517+ bun run typecheck
518+
519+ # Run single test
520+ bun test -t "test name pattern"
521+ ```
522+
523+ **Common test issues:**
524+ - Import errors → Check file paths
525+ - Type errors → Run `bun run typecheck`
526+ - Assertion failures → Check implementation logic
527+
528+ ### Development Workflow
529+
530+ **Best practices for agents:**
531+
532+ 1. **Always run tests after changes:**
533+ ```bash
534+ bun test lib/buffer.test.ts
535+ ```
536+
537+ 2. **Type check before committing:**
538+ ```bash
539+ bun run typecheck
540+ ```
541+
542+ 3. **Test in browser:**
543+ ```bash
544+ bun run dev
545+ # Open http://localhost:8000/examples/buffer-demo.html
546+ ```
547+
548+ 4. **Debug in console:**
549+ - Use `console.log()` liberally
550+ - Check browser console (F12) for errors
551+ - Test APIs directly: `buffer.writeChar(' A' )`
552+
553+ 5. **Iterate quickly:**
554+ - Vite has hot reload - save file, browser auto-updates
555+ - Keep console open to catch errors immediately
0 commit comments