From ca5f34be9916317afda21d0cc4a4c862f52cdb59 Mon Sep 17 00:00:00 2001 From: Ken Date: Thu, 28 May 2026 07:16:00 +0000 Subject: [PATCH] fix: update tests and terminal.js for ghostty-web terminal swap --- muxplex/frontend/terminal.js | 11 +++++++++-- muxplex/tests/test_frontend_html.py | 14 ++++++++------ muxplex/tests/test_main.py | 11 +++++------ muxplex/tests/test_no_ttyd_refs.py | 1 + 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/muxplex/frontend/terminal.js b/muxplex/frontend/terminal.js index 69c9c91..4796c14 100644 --- a/muxplex/frontend/terminal.js +++ b/muxplex/frontend/terminal.js @@ -17,6 +17,11 @@ let _altActive = false; let _muxtermPort = null; let _muxtermToken = null; +// WASM initialization for ghostty-web +let _ghosttyReady = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.init) + ? GhosttyWeb.init({ wasmUrl: '/vendor/ghostty-vt.wasm' }) + : Promise.resolve(); + // ——— Encoding helpers —————————————————————————————————————————————————— const _encoder = typeof TextEncoder !== 'undefined' ? new TextEncoder() : null; const _decoder = typeof TextDecoder !== 'undefined' ? new TextDecoder() : null; @@ -170,7 +175,7 @@ function createTerminal(fontSize) { var mobile = window.innerWidth < 600; var effectiveFontSize = mobile ? Math.min(storedFontSize, 12) : storedFontSize; - var TerminalClass = window.Terminal; + var TerminalClass = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.Terminal) || window.Terminal; _term = new TerminalClass({ cursorBlink: true, fontSize: effectiveFontSize, @@ -184,7 +189,7 @@ function createTerminal(fontSize) { }); // FitAddon - var FitAddonClass = (window.FitAddon && window.FitAddon.FitAddon); + var FitAddonClass = (typeof GhosttyWeb !== 'undefined' && GhosttyWeb.FitAddon) || (window.FitAddon && window.FitAddon.FitAddon); _fitAddon = new FitAddonClass(); _term.loadAddon(_fitAddon); @@ -273,6 +278,8 @@ function openTerminal(sessionName, remoteId, fontSize) { return; } + // Ensure ghostty-web WASM is ready before creating terminal + _ghosttyReady.then(function() { // Create terminal if not already present if (!_term) { createTerminal(fontSize); diff --git a/muxplex/tests/test_frontend_html.py b/muxplex/tests/test_frontend_html.py index 773db96..2d1ec2b 100644 --- a/muxplex/tests/test_frontend_html.py +++ b/muxplex/tests/test_frontend_html.py @@ -91,7 +91,7 @@ def test_html_toast() -> None: def test_html_scripts() -> None: - """src=/app.js, src=/terminal.js, xterm.""" + """src=/app.js, src=/terminal.js, ghostty-web.""" soup = _SOUP scripts = soup.find_all("script") srcs = [str(s.get("src", "")) for s in scripts] @@ -101,16 +101,18 @@ def test_html_scripts() -> None: assert any("/terminal.js" in s for s in srcs), ( f"Missing script src=/terminal.js; found: {srcs}" ) - assert any("xterm" in s for s in srcs), f"Missing xterm script; found: {srcs}" + assert any("ghostty-web" in s for s in srcs), ( + f"Missing ghostty-web script; found: {srcs}" + ) -def test_html_xterm_css() -> None: - """xterm.css CDN link present.""" +def test_html_no_xterm_css() -> None: + """ghostty-web uses canvas rendering — xterm.css must not be present.""" soup = _SOUP links = soup.find_all("link", rel="stylesheet") hrefs = [str(lnk.get("href", "")) for lnk in links] - assert any("xterm.css" in h for h in hrefs), ( - f"Missing xterm.css link; found: {hrefs}" + assert not any("xterm.css" in h for h in hrefs), ( + f"xterm.css must not be present (ghostty-web uses canvas); found: {hrefs}" ) diff --git a/muxplex/tests/test_main.py b/muxplex/tests/test_main.py index 72ace09..60d91f6 100644 --- a/muxplex/tests/test_main.py +++ b/muxplex/tests/test_main.py @@ -92,8 +92,8 @@ def test_index_all_asset_urls_have_version_suffix(client): # All