Update ghostty-web to b0aa99e which wraps the requestAnimationFrame
render loop in try/catch. Previously, any exception in renderer.render()
or wasmTerm.getCursor() would silently kill the loop, permanently
freezing the terminal canvas while input continued to flow normally.
The fix ensures requestAnimationFrame is always re-scheduled and logs
errors to console for diagnosis. This addresses intermittent terminal
stalls that were not correlated with resize, focus, or user interaction.
Close retired websocket connections in stopWSClient so clients reconnect promptly instead of remaining in a stdin-only state with no returning output. Add regression coverage to verify stopWSClient actively disconnects the websocket.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace silent output frame dropping with fail-fast slow-client disconnects when websocket send queues saturate, and replace unbounded stdin write goroutine spawning with a bounded queue + worker and timeout-driven disconnect under input backlog. Also add targeted regression tests for queue saturation and stdin backlog disconnect behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Guard route client cleanup against stale websocket/session close paths so newer connections keep receiving output after focus/reconnect transitions. Also refresh websocket read deadlines on every inbound message and add regression tests covering both reconnect and stale-session-close race scenarios.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address issue #3 by hardening the terminal WebSocket client against silent receive stalls seen in Firefox.
Changes:
- Added a client heartbeat watchdog that sends periodic ping messages.
- Detects stale inbound streams and forces reconnect when no inbound data/pong is seen within the timeout window.
- Added Blob WebSocket message handling for improved cross-browser receive compatibility.
- Ensures heartbeat timers are started/stopped with socket lifecycle and terminal disposal.
Validation:
- Rebuilt frontend bundle via make build-fast.
- Ran make check successfully.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update the README <video> source to use the GitHub raw media URL for docs/demo.mp4 so the demo renders inline instead of resolving to a blob page.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the static screenshot with an embedded demo.mp4 player in the README and add docs/demo.mp4 to the repository so the preview is available in-repo.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve GitHub issue #2 by aligning the Go module identity with the repository path so works.
Changes made:
- Updated go.mod module path from github.com/rcarmo/webterm-go-port to github.com/rcarmo/webterm.
- Updated all internal import references to the new module path.
- Updated version ldflags in Makefile and Dockerfile to use github.com/rcarmo/webterm/webterm.Version.
- Added README quick-install section documenting the command.
Validation:
- Ran make check successfully after the rename/import updates.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce a dashboard workflow to export screenshot SVGs without external font URL references.
Server changes:
- Added screenshot query flags: sanitize_font_urls=1 and download=1.
- Added SVG sanitization that strips @font-face src:url(...) for the vendored font path.
- Added safe filename normalization for download responses.
- Added Content-Disposition attachment support for downloadable screenshot exports.
- Preserved existing cache behavior while computing ETags from the actual response variant.
Dashboard changes:
- Added tile contextmenu handler (right-click) to trigger sanitized SVG download per tile.
- Download URL includes cache-busting timestamp to avoid stale browser downloads.
Tests:
- Added coverage for sanitized download response (attachment header + font URL removal).
- Added coverage asserting dashboard HTML includes right-click sanitized download wiring.
- Validated with make format && make check.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ensure dashboard screenshot SVGs consistently use the vendored Fira Nerd font stack used by the terminal.
Changes:
- Added dashboard inline CSS declarations for @font-face (FiraCode Nerd Font/FiraMono Nerd Font) and --webterm-mono in the dashboard HTML template.
- Updated RenderTerminalSVG styling to use font-family: var(--webterm-mono, ...) with the full Nerd-font-aware fallback stack.
- Embedded matching @font-face declarations inside generated SVG style blocks so externally loaded SVG images can resolve the vendored font without relying on parent page CSS inheritance.
Result:
- Dashboard screenshot tiles and search thumbnails retain full glyph/icon coverage with consistent typography across environments.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bundle FiraCode Nerd Font directly in static assets so terminal rendering no longer depends on host-installed Nerd Fonts.
Changes included:
- Added vendored font asset at webterm/static/fonts/FiraCodeNerdFont-Regular.ttf.
- Added bundled font license at webterm/static/fonts/FiraCode-LICENSE.txt.
- Wired local @font-face declarations in webterm/static/monospace.css for both "FiraCode Nerd Font" and "FiraMono Nerd Font" family names used by the existing font stack.
- Documented the capability in README Features as a first-class feature with full glyph/icon support and no external font fetch requirement.
Impact:
- Font glyph/icon rendering is now more consistent across environments.
- Font assets continue to be embedded in the Go binary by default through the existing static embed path.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Address intermittent stalls seen after many hours by improving liveness detection and failure handling for both streaming channels.
WebSocket changes:
- Added periodic server ping frames and a read deadline refreshed by pong replies.
- On sender write/ping failure, explicitly close the underlying connection so clients promptly observe disconnect and reconnect instead of remaining half-open.
SSE changes:
- Excluded /events from gzip middleware and added X-Accel-Buffering: no to reduce proxy buffering risk.
- Stop the SSE loop on write errors for activity/keepalive frames so dead subscribers are cleaned up immediately.
Tests:
- Added regression coverage for gzip bypass on /events.
- Added regression coverage ensuring SSE handler exits and unsubscribes on write failure.
- Verified with make format && make check.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Serve /static from embedded assets when no static path override is configured, add static route coverage, and update Docker/docs to reflect embedded-by-default behavior.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Relax screenshot request gating to depend on tab visibility only, so thumbnail updates continue when the dashboard tab is visible but the window is not focused.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Emit dashboard activity updates only when terminal screen content actually changes, and tighten screenshot 304 fast-path behavior to avoid stale not-modified responses after newer activity.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore reliable live thumbnail updates in the single-flight queue and set UTF-8 charset metadata/headers so typeahead hint symbols render correctly.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reduce per-route SSE activity event frequency by doubling the server-side debounce window from 250ms to 500ms.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ensure only one screenshot request is in flight at a time, queue per-tile refreshes, and pause screenshot fetches while the dashboard is hidden or unfocused.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Restore dashboard typeahead behavior to match the Python version with floating results, keyboard navigation, tile highlighting, and Enter-to-open handling.
Add HTTP gzip compression middleware (while excluding WebSocket upgrades) to reduce SVG transfer size, and add a safe make push target that pushes current branch plus tags on HEAD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce VERSION as the app version source of truth and add make bump-patch to increment VERSION, commit, and create a matching vX.Y.Z tag.
Wire VERSION into build outputs by injecting it into webterm.Version for make build-go and Docker image builds, and include VERSION in Docker build context.
Also remove the visible dashboard container count subtitle while keeping count updates in browser console logs.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ensure SessionManager.CloseAll fully removes session and route mappings by reusing CloseSession for each tracked session ID.
Tighten coverage test assertions to verify CloseAll removes both sessions and route-key mappings, guarding against stale state regressions.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rationalize the release workflow by adding top-level concurrency to avoid overlapping publish runs for the same ref and by restricting cleanup jobs to tag refs only.
Keep ci.yml as the PR/main validation gate while docker.yml remains focused on release publishing and post-release maintenance.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>