Commit Graph

401 Commits

Author SHA1 Message Date
GitHub Copilot 2d50731fa0 Harden websocket and stdin backpressure handling
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>
2026-02-16 23:04:55 +00:00
GitHub Copilot b09d8d58ee Fix websocket lifecycle races that can stall terminal output
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>
2026-02-16 23:00:30 +00:00
GitHub Copilot c981c89435 Bump version to 1.3.16 2026-02-16 14:50:17 +00:00
GitHub Copilot 5d9d0b0ee1 Merge branch 'main' of github.com:rcarmo/textual-webterm 2026-02-16 14:50:14 +00:00
GitHub Copilot b2889b97e8 Bump version to 1.3.15 2026-02-16 14:50:06 +00:00
GitHub Copilot c905a66d9b Add Firefox WebSocket stall recovery watchdog
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>
2026-02-16 14:48:53 +00:00
Rui Carmo 8078ba6d4b Update README.md 2026-02-16 13:25:19 +00:00
Rui Carmo ebd16b86c2 Update video link in README.md
Updated video link in README to point to a new asset location.
2026-02-15 17:14:29 +00:00
GitHub Copilot 5e375edf01 Fix README demo video rendering on GitHub
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>
2026-02-15 17:07:50 +00:00
GitHub Copilot 4c7641e380 Embed demo video in README
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>
2026-02-15 17:05:14 +00:00
GitHub Copilot a5e08c784a Bump version to 1.3.14 2026-02-15 16:20:32 +00:00
GitHub Copilot 98e000e3be Fix module path mismatch for go install
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>
2026-02-15 16:19:46 +00:00
GitHub Copilot 6a841837af Bump version to 1.3.13 2026-02-15 15:11:31 +00:00
GitHub Copilot 5017e3a53f Add right-click sanitized SVG export for dashboard tiles
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>
2026-02-15 15:11:12 +00:00
GitHub Copilot 5ade64b367 Wire vendored Nerd font into dashboard SVG thumbnails
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>
2026-02-15 15:05:36 +00:00
GitHub Copilot 252ecb3714 Bump version to 1.3.12 2026-02-15 14:55:20 +00:00
GitHub Copilot fbf4c968ed Vendor Fira Nerd Font for full glyph coverage
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>
2026-02-15 14:54:53 +00:00
GitHub Copilot cfc4b1d0f2 Bump version to 1.3.11 2026-02-15 14:28:45 +00:00
GitHub Copilot a4fb601c72 Merge branch 'main' of github.com:rcarmo/textual-webterm 2026-02-15 14:28:40 +00:00
GitHub Copilot cf2c5d14cb Bump version to 1.3.10 2026-02-15 14:28:34 +00:00
GitHub Copilot d43270d5dc Harden long-lived SSE and WebSocket connections
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>
2026-02-15 14:28:09 +00:00
Rui Carmo 1820c10b54 Enhance README features section with repository links
Updated feature descriptions with links to relevant repositories.
2026-02-15 13:51:30 +00:00
GitHub Copilot 5fd2f92ef1 Bump version to 1.3.9 2026-02-14 22:40:47 +00:00
GitHub Copilot 516f1b1946 Reorganize project into standard root layout
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 22:40:29 +00:00
GitHub Copilot 374b69bd7e Bump version to 1.3.8 2026-02-14 22:14:54 +00:00
GitHub Copilot 73f162075e Embed web assets into the Go binary
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>
2026-02-14 22:14:39 +00:00
GitHub Copilot ff60bc94ed Bump version to 1.3.7 2026-02-14 20:00:35 +00:00
GitHub Copilot 218aabc8ca Allow visible dashboard screenshots while unfocused
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>
2026-02-14 19:59:55 +00:00
GitHub Copilot d526fa1860 Bump version to 1.3.6 2026-02-14 19:52:53 +00:00
GitHub Copilot 8762e2cc7d Reduce idle screenshot churn with change-driven SSE
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>
2026-02-14 19:52:41 +00:00
GitHub Copilot d4be34dbc9 Bump version to 1.3.5 2026-02-14 19:42:21 +00:00
GitHub Copilot 2de22d37da Fix dashboard live refresh and UTF-8 hint rendering
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>
2026-02-14 19:42:09 +00:00
GitHub Copilot be45e91f9b Bump version to 1.3.4 2026-02-14 19:35:15 +00:00
GitHub Copilot 157da5deb9 Increase SSE activity debounce to 500ms
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>
2026-02-14 19:34:44 +00:00
GitHub Copilot eb0465403e Reduce dashboard screenshot churn with single-flight focus gating
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>
2026-02-14 19:33:22 +00:00
GitHub Copilot 5da9c28528 Bump version to 1.3.3 2026-02-14 19:20:12 +00:00
GitHub Copilot 0ca413f10c webterm: restore Python-style dashboard search and add gzip
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>
2026-02-14 19:19:49 +00:00
GitHub Copilot 0361ba41a8 Bump version to 1.3.2 2026-02-14 19:19:03 +00:00
GitHub Copilot 88fa460074 Bump version to 1.3.1 2026-02-14 19:00:56 +00:00
GitHub Copilot cb36beaf2e build: add VERSION-based release workflow
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>
2026-02-14 18:58:59 +00:00
GitHub Copilot a49c4d8718 webterm: add docker watcher event logging
Add structured server-side logs for Docker watcher lifecycle, event stream connectivity/decoding failures, start/die event handling, and container add/remove actions.

This complements HTTP/WebSocket request logs with Docker-specific observability for debugging dynamic tile/session behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 18:48:30 +00:00
GitHub Copilot 1cfced1052 webterm: fix screenshot tile bootstrap and add request logging
Fix screenshot generation for requested dashboard route keys by preserving non-empty route_key lookups when no session exists yet, allowing lazy session creation instead of returning 404.

Add server-side observability with HTTP request logs (method, URI, status, bytes, duration, remote address) and websocket connection lifecycle logs for connect/disconnect and unexpected read errors.

Update README title/positioning and expand feature bullets to document Ghostty WASM rendering and mobile/touch keyboard support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 18:46:36 +00:00
GitHub Copilot 4110963c9f Bump minor version to v1.3.0
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 18:32:34 +00:00
GitHub Copilot c8040e5938 go: harden session cleanup path
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>
2026-02-14 18:26:43 +00:00
GitHub Copilot 4e90b65c6b ci: tighten release workflow cleanup policy
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>
2026-02-14 18:21:25 +00:00
GitHub Copilot 3d4dab2359 Finalize Go-only migration, runtime hardening, and CI/container optimization
This commit consolidates the full repository transition to a Go-first codebase and captures the follow-up performance/reliability work completed in the same stream.

Highlights:
- Remove Python implementation and test suites (, , , ) and retire Python-specific docs/instructions.
- Move and standardize static web assets under , updating Bun/TypeScript build paths and server static resolution logic.
- Rewrite developer workflow to Makefile-first Go targets (vet/test/race/coverage/fuzz/build) and align repository guidance/docs accordingly.
- Update Docker and CI/CD for leaner artifacts:
  - switch to Alpine-based multi-stage build with stripped Go binary
  - install only minimal runtime deps (, )
  - tighten Docker build context via
  - ensure workflows build/publish the  target.
- Improve runtime correctness/latency and reduce duplication:
  - explicit WebSocket outbound frame typing (text vs binary) instead of payload-byte heuristics
  - SSE activity fan-out outside global lock and safer subscriber lifecycle
  - shared session output/snapshot helpers to reduce duplicated logic
  - restart-safe channel lifecycle for Docker watcher/stats start-stop-start flows
  - faster screenshot cold-start path (poll-until-ready within timeout vs fixed sleep).
- Add/expand regression coverage for the above lifecycle and helper paths.

Validation run:
- bun run build
Bundled 3 modules in 10ms

  terminal.js  0.68 MB  (entry point) (Bun typecheck + bundle)
- cd go && go vet ./...
cd go && go test ./...
ok  	github.com/rcarmo/webterm-go-port/cmd/webterm	(cached)
ok  	github.com/rcarmo/webterm-go-port/internal/terminalstate	(cached)
ok  	github.com/rcarmo/webterm-go-port/webterm	(cached)
cd go && go test ./webterm -coverprofile=coverage.out && go tool cover -func=coverage.out
ok  	github.com/rcarmo/webterm-go-port/webterm	(cached)	coverage: 81.0% of statements
github.com/rcarmo/webterm-go-port/webterm/cli.go:14:			RunCLI				51.6%
github.com/rcarmo/webterm-go-port/webterm/config.go:25:			DefaultConfig			100.0%
github.com/rcarmo/webterm-go-port/webterm/config.go:29:			LoadLandingYAML			82.6%
github.com/rcarmo/webterm-go-port/webterm/config.go:70:			LoadComposeManifest		76.9%
github.com/rcarmo/webterm-go-port/webterm/config.go:114:		extractLabel			92.3%
github.com/rcarmo/webterm-go-port/webterm/config.go:138:		asString			80.0%
github.com/rcarmo/webterm-go-port/webterm/constants.go:27:		EnvBool				50.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:30:	Read				100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:56:	NewDockerExecSession		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:72:	Open				90.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:99:	Start				85.7%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:119:	readLoop			83.3%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:143:	handleOutput			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:153:	createExec			75.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:183:	startExecSocket			60.7%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:219:	resizeExec			83.3%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:237:	Close				90.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:250:	Wait				100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:257:	SetTerminalSize			81.8%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:274:	ForceRedraw			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:281:	SendBytes			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:294:	SendMeta			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:298:	IsRunning			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:304:	GetReplayBuffer			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:308:	GetScreenSnapshot		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_exec_session.go:316:	UpdateConnector			80.0%
github.com/rcarmo/webterm-go-port/webterm/docker_http.go:23:		DockerSocketPath		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_http.go:37:		newUnixHTTPClient		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_http.go:47:		sharedUnixClient		91.7%
github.com/rcarmo/webterm-go-port/webterm/docker_http.go:64:		unixJSONRequest			84.2%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:33:		NewDockerStatsCollector		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:47:		Available			72.7%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:64:		Start				80.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:78:		Stop				75.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:90:		AddService			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:101:		RemoveService			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:115:		GetCPUHistory			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:124:		pollLoop			95.2%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:160:		discoverContainers		65.4%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:198:		pollContainer			77.8%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:223:		calculateCPUPercent		69.2%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:260:		RenderSparklineSVG		89.3%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:299:		max				100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:306:		toAnyMap			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:323:		toStringMap			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:331:		toAnySlice			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:340:		toStringSlice			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:351:		toUint				91.7%
github.com/rcarmo/webterm-go-port/webterm/docker_stats.go:376:		toInt				85.7%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:34:		NewDockerWatcher		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:54:		hasWebtermLabel			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:60:		isAutoLabel			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:67:		getContainerCommand		80.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:76:		getContainerTheme		100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:81:		getContainerName		42.9%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:93:		containerToSlug			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:98:		addContainer			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:119:	removeContainer			100.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:143:	listLabeledContainers		94.1%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:168:	handleEvent			80.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:202:	watchEvents			85.7%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:239:	ScanExisting			60.0%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:249:	Start				83.3%
github.com/rcarmo/webterm-go-port/webterm/docker_watcher.go:265:	Stop				81.8%
github.com/rcarmo/webterm-go-port/webterm/identity.go:12:		GenerateID			94.1%
github.com/rcarmo/webterm-go-port/webterm/normalize.go:13:		FilterDASequences		83.3%
github.com/rcarmo/webterm-go-port/webterm/replay.go:14:			NewReplayBuffer			66.7%
github.com/rcarmo/webterm-go-port/webterm/replay.go:21:			Add				100.0%
github.com/rcarmo/webterm-go-port/webterm/replay.go:43:			Bytes				100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:95:			OnData				100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go💯		OnBinary			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:105:		OnMeta				0.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:107:		OnClose				100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:112:		NewLocalServer			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:163:		findStaticPath			62.5%
github.com/rcarmo/webterm-go-port/webterm/server.go:184:		markRouteActivity		100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:207:		enqueueWSFrame			77.8%
github.com/rcarmo/webterm-go-port/webterm/server.go:233:		stopWSClient			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:246:		wsSender			80.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:256:		createTerminalSession		66.7%
github.com/rcarmo/webterm-go-port/webterm/server.go:278:		clampInt			60.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:288:		parseResizePayload		88.9%
github.com/rcarmo/webterm-go-port/webterm/server.go:303:		handleWebSocket			81.1%
github.com/rcarmo/webterm-go-port/webterm/server.go:425:		chooseRouteForScreenshot	50.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:440:		screenshotTTL			66.7%
github.com/rcarmo/webterm-go-port/webterm/server.go:457:		handleScreenshot		55.7%
github.com/rcarmo/webterm-go-port/webterm/server.go:541:		handleCPUSparkline		94.4%
github.com/rcarmo/webterm-go-port/webterm/server.go:566:		handleEvents			76.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:602:		toIntFromQuery			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:609:		dashboardTiles			81.8%
github.com/rcarmo/webterm-go-port/webterm/server.go:631:		handleTiles			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:636:		getWSURL			65.2%
github.com/rcarmo/webterm-go-port/webterm/server.go:671:		handleRoot			56.8%
github.com/rcarmo/webterm-go-port/webterm/server.go:732:		htmlEscape			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:736:		htmlAttrEscape			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:740:		handleHealth			100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:744:		setupDockerFeatures		40.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:791:		shutdown			62.5%
github.com/rcarmo/webterm-go-port/webterm/server.go:814:		Handler				100.0%
github.com/rcarmo/webterm-go-port/webterm/server.go:829:		Run				77.8%
github.com/rcarmo/webterm-go-port/webterm/session.go:31:		OnData				0.0%
github.com/rcarmo/webterm-go-port/webterm/session.go:32:		OnBinary			0.0%
github.com/rcarmo/webterm-go-port/webterm/session.go:33:		OnMeta				0.0%
github.com/rcarmo/webterm-go-port/webterm/session.go:34:		OnClose				0.0%
github.com/rcarmo/webterm-go-port/webterm/session.go:36:		dispatchSessionOutput		100.0%
github.com/rcarmo/webterm-go-port/webterm/session.go:47:		snapshotFromTracker		100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:20:	NewSessionManager		100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:34:	SetSessionFactory		100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:40:	defaultSessionFactory		87.5%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:57:	splitCommand			75.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:65:	shlexSplit			100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:69:	AddApp				87.5%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:88:	RemoveApp			87.5%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:101:	Apps				100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:107:	AppBySlug			100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:114:	GetDefaultApp			80.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:123:	NewSession			50.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:167:	OnSessionEnd			100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:176:	CloseAll			100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:189:	CloseSession			87.5%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:201:	GetSession			100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:207:	GetSessionByRouteKey		100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:217:	GetSessionIDByRouteKey		100.0%
github.com/rcarmo/webterm-go-port/webterm/session_manager.go:223:	GetFirstRunningSession		85.7%
github.com/rcarmo/webterm-go-port/webterm/shellsplit.go:5:		shlexSplitImpl			100.0%
github.com/rcarmo/webterm-go-port/webterm/slugify.go:13:		Slugify				100.0%
github.com/rcarmo/webterm-go-port/webterm/svg_exporter.go:35:		RenderTerminalSVG		92.6%
github.com/rcarmo/webterm-go-port/webterm/svg_exporter.go:113:		colorToHex			87.5%
github.com/rcarmo/webterm-go-port/webterm/svg_exporter.go:139:		isHex				100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:37:	NewTerminalSession		100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:49:	Open				86.7%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:90:	Start				85.7%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:110:	readLoop			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:132:	handleOutput			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:142:	Close				100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:160:	Wait				100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:167:	SetTerminalSize			80.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:190:	ForceRedraw			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:198:	SendBytes			88.9%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:211:	SendMeta			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:215:	IsRunning			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:221:	GetReplayBuffer			100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:225:	GetScreenSnapshot		100.0%
github.com/rcarmo/webterm-go-port/webterm/terminal_session.go:233:	UpdateConnector			80.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:14:			NewTwoWayMap			100.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:21:			Set				88.9%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:36:			DeleteKey			100.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:45:			Get				100.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:52:			GetKey				100.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:59:			Keys				100.0%
github.com/rcarmo/webterm-go-port/webterm/twoway.go:70:			UnsafeForward			100.0%
total:									(statements)			81.0%
- cd go && go test -race ./...
ok  	github.com/rcarmo/webterm-go-port/cmd/webterm	(cached)
ok  	github.com/rcarmo/webterm-go-port/internal/terminalstate	(cached)
ok  	github.com/rcarmo/webterm-go-port/webterm	(cached)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 18:03:28 +00:00
GitHub Copilot 065de286fb refactor: standardize Go layout with internal terminalstate
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>
2026-02-14 17:13:49 +00:00
GitHub Copilot f597f8f99d test: expand Go fuzzing and raise coverage above 80%
- Add comprehensive runtime tests for session, docker watcher/stats/http, and server helpers
- Add new fuzz targets: FuzzToIntFromQuery and FuzzHTMLHelpers
- Add cmd/webterm main entrypoint test
- Expand helper conversion and color-mode coverage tests

Validation:
- go test ./...
- go test -race ./...
- All 15 fuzz targets pass with short fuzz runs
- go test ./... -coverpkg=./... => 80.9% total statement coverage

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 17:06:52 +00:00
GitHub Copilot 5aa9eb9426 chore: incorporate relevant agentbox skel files
Add relevant skeleton files from rcarmo/agentbox/skel for this repo:
- .github/workflows/ci.yml (Makefile checks + conditional Go tests)
- .github/instructions/{00-project-detection,docker-image,frontend-bun,go,python}.instructions.md

Instruction files were adapted where needed to match current workflow names
and repository layout (Go module under go/, Docker workflow filename).

Validated with make check and go test ./... .

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 16:44:44 +00:00
GitHub Copilot 674e62d983 refactor: upgrade go-te to v0.1.0, remove C1 normalization
go-te v0.1.0 fixes the ByteStream C1 bug (Latin-1 fallback for
invalid UTF-8 bytes), so NormalizeC1Controls is no longer needed.

Removed:
- NormalizeC1Controls function and its tests/fuzz target
- utf8Buffer field from TerminalSession and DockerExecSession
- C1BUG.md (fix shipped upstream)

The handleOutput pipeline now does: FilterDA → replay → tracker → connector
(was: FilterDA → NormalizeC1 → replay → tracker → connector)

All tests pass with -race. 13 fuzz targets remain.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-14 16:40:28 +00:00