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>
Audit findings: cmd/webterm and webterm package were acceptable, but terminalstate
was an internal implementation detail exposed as a public package.
Changes:
- Move go/terminalstate -> go/internal/terminalstate
- Update imports to github.com/rcarmo/webterm-go-port/internal/terminalstate
- Keep package name terminalstate unchanged
Resulting package layout:
- github.com/rcarmo/webterm-go-port/cmd/webterm
- github.com/rcarmo/webterm-go-port/internal/terminalstate
- github.com/rcarmo/webterm-go-port/webterm
Validation:
- go test ./...
- go test -race ./...
- go coverage check remains 80.9%
- make check
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>