GitHub Copilot 2c5d3c72f9 Pause VT parser for idle sessions to eliminate CPU waste
When no WebSocket client is connected, the session's readLoop still
processes every byte of terminal output through the go-te VT parser
(tracker.Feed), Screen.Draw grapheme segmentation, and string
allocations — even though nobody is consuming the screen state.
For programs like btop inside tmux that produce continuous full-screen
redraws, this causes sustained CPU usage and GC pressure over hours.

Fix: after a 10-second idle threshold (no client connected), skip
tracker.Feed() and only maintain the replay buffer. When a client
reconnects (UpdateConnector) or a screenshot is requested
(GetScreenSnapshot), rebuild the tracker by replaying the buffer
through a fresh VT parser instance.

Changes:
- Add idleSince atomic timestamp + MarkIdle() to Session interface
- handleOutput() skips tracker.Feed when idle > threshold
- UpdateConnector() clears idle flag and rebuilds tracker from replay
- GetScreenSnapshot() rebuilds stale tracker on-demand for screenshots
- Wire MarkIdle() call into handleWebSocket cleanup (client disconnect)
- Add TestIdleTrackerPauseAndRebuild covering the full lifecycle
2026-02-18 09:21:18 +00:00
2026-02-15 16:19:46 +00:00
2026-01-21 23:53:57 +00:00
2026-02-18 00:05:04 +00:00

webterm

Icon

webterm serves terminal sessions over HTTP/WebSocket, with a dashboard mode for multiple sessions and live-updating terminal tiles that is perfect for running multiple AI coding agents in agentbox.

This repository is the Go port of the original Python implementation, which is preserved in the python branch.

https://github.com/user-attachments/assets/62c52183-83a3-4fb5-97b1-ed001de4f53a

Features

  • Typeahead find for quickly finding and launching sessions with minimal friction
  • Web terminal with reconnect support
  • Ghostty WebAssembly terminal engine for fast rendering from ghostty-web
  • Session dashboard with live SVG screenshots from go-te
  • Docker watch mode (webterm-command / webterm-theme labels)
  • Docker compose manifest ingestion
  • CPU sparkline tiles for compose services
  • SSE activity updates for fast dashboard refresh
  • Mobile/touch support with virtual keyboard + draggable keybar
  • Theme/font controls for terminal rendering
  • Vendored Nerd Font assets with full glyph/icon support (no external font fetch required)

Install

Quick install

go install github.com/rcarmo/webterm/cmd/webterm@latest

Build from source

git clone https://github.com/rcarmo/webterm.git
cd webterm
mkdir -p bin
go build -o ./bin/webterm ./cmd/webterm

The command above produces bin/webterm; you can also build it from repo root with make build-go.

Quick start

Run a default shell session:

go run ./cmd/webterm

Run a specific command:

go run ./cmd/webterm -- htop

Then open http://localhost:8080.

Dashboard modes

Landing manifest

- name: Logs
  slug: logs
  command: docker logs -f my-service
  theme: nord
go run ./cmd/webterm -- --landing-manifest ./landing.yaml

Docker watch

go run ./cmd/webterm -- --docker-watch

Containers with these labels become tiles:

  • webterm-command: command string, or auto for Docker exec
  • webterm-theme: theme name (fallback is xterm palette)

Available themes: tango, xterm, monokai, monokai-pro, ristretto, dark, light, dracula, catppuccin, nord, gruvbox, solarized, tokyo, miasma, github, gotham

Compose manifest

go run ./cmd/webterm -- --compose-manifest ./docker-compose.yaml

Environment variables

  • WEBTERM_STATIC_PATH: override static asset directory
  • WEBTERM_DOCKER_USERNAME: user for Docker exec sessions
  • WEBTERM_DOCKER_AUTO_COMMAND: override auto command (/bin/bash default)
  • WEBTERM_SCREENSHOT_FORCE_REDRAW: force redraw before screenshots (true/1/yes/on)
  • DOCKER_HOST: Docker daemon endpoint override

Development (Makefile-first)

make install-dev
make check
make race
make test
make bump-patch

Frontend bundle tasks:

make build
make build-fast
make bundle-watch

Docker

docker build -t webterm .
docker run -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 webterm --docker-watch

Web assets are embedded in the Go binary by default (you can still override with WEBTERM_STATIC_PATH). The Dockerfile uses a minimal Alpine runtime stage and only installs ca-certificates plus docker-cli.

S
Description
No description provided
Readme 122 MiB
Languages
Go 51.5%
TypeScript 31%
JavaScript 14.8%
Shell 1.2%
Makefile 0.8%
Other 0.7%