Replace xterm.js with ghostty-web

Migrate from xterm.js to ghostty-web (Ghostty WASM terminal emulator).

Benefits:
- WASM-compiled parser from Ghostty (same code as native app)
- Better Unicode/complex script handling
- Simpler initialization (no viewport.scrollBarWidth issues)
- ~400KB WASM bundle

Changes:
- Update package.json: remove @xterm/* deps, add ghostty-web
- Rewrite terminal.ts using ghostty-web API
- Use built-in FitAddon with observeResize()
- Remove WebGL/Canvas/Unicode11/WebLinks/Clipboard addons
- Remove xterm.css (ghostty uses canvas renderer)
- Add ghostty-vt.wasm to static assets
- Update HTML template and tests

BREAKING: Major version bump to 0.4.0
This commit is contained in:
GitHub Copilot
2026-01-28 00:54:50 +00:00
parent 712cc72911
commit 3f6cfd4e96
12 changed files with 98 additions and 1273 deletions
+1 -1
View File
@@ -18,7 +18,7 @@ class TestLocalServer:
"""Test that static path contains required assets."""
assert WEBTERM_STATIC_PATH is not None
assert (WEBTERM_STATIC_PATH / "js" / "terminal.js").exists()
assert (WEBTERM_STATIC_PATH / "css" / "xterm.css").exists()
assert (WEBTERM_STATIC_PATH / "js" / "ghostty-vt.wasm").exists()
def test_create_server(self, tmp_path) -> None:
"""Test creating a LocalServer instance."""
+3 -4
View File
@@ -27,12 +27,12 @@ class TestGetStaticPath:
assert WEBTERM_STATIC_PATH is not None
assert (WEBTERM_STATIC_PATH / "js").exists()
def test_static_path_has_css(self):
"""Test that static path has CSS directory."""
def test_static_path_has_wasm(self):
"""Test that static path has WASM file."""
from textual_webterm.local_server import WEBTERM_STATIC_PATH
assert WEBTERM_STATIC_PATH is not None
assert (WEBTERM_STATIC_PATH / "css").exists()
assert (WEBTERM_STATIC_PATH / "js" / "ghostty-vt.wasm").exists()
class TestLocalServer:
@@ -441,7 +441,6 @@ class TestLocalServerMoreCoverage:
request.secure = False
resp = await server_with_no_apps._handle_root(request)
assert "/static/css/xterm.css" in resp.text
assert "/static/monospace.css" in resp.text
assert "/static/js/terminal.js" in resp.text
assert "data-session-websocket-url" in resp.text