go-te is a Go terminal emulator library that models a VT100/VT220/VT520-style screen. It is a faithful port of the Python pyte test suite with additional coverage from the ESCTest2 conformance tests. The library focuses on deterministic, in-memory screen state suitable for screen scraping, TUI rendering, and playback, and is used in webterm to provide live terminal previews.
- Pyte fidelity: The Go implementation follows pyte semantics and test behavior 1:1.
- ESCTest2 coverage: Comprehensive CSI/OSC/DSR behavior is validated through upstream tests.
- Multiple screen variants: Base, diff (dirty tracking), history (scrollback), and debug screens.
- Alternate buffer support: Primary/alternate buffers with cursor save/restore.
- SVG rendering: Export screen buffers to SVG for screenshots or reports.
go get github.com/rcarmo/go-tepackage main
import (
"fmt"
"github.com/rcarmo/go-te/pkg/te"
)
func main() {
screen := te.NewScreen(80, 24)
stream := te.NewStream(screen, false)
_ = stream.Feed("Hello, world!\n")
_ = stream.Feed(te.ControlCSI + "31m" + "Red text" + te.ControlCSI + "0m")
for _, line := range screen.Display() {
fmt.Println(line)
}
}Screen is a 2D grid of Cell values that hold character data and attributes. It tracks cursor state, modes, margins, and metadata like window titles.
screen := te.NewScreen(80, 24)
lines := screen.Display()Stream consumes UTF-8 strings and dispatches parsed escape sequences to a screen. ByteStream accepts raw bytes and handles UTF-8 decoding.
stream := te.NewStream(screen, false)
_ = stream.Feed(te.ControlCSI + "2J") // clear screen
byteStream := te.NewByteStream(screen, false)
_ = byteStream.Feed([]byte("hello"))HistoryScreen adds a scrollback buffer and paging controls.
history := te.NewHistoryScreen(80, 24, 200)
stream := te.NewStream(history, false)DiffScreen tracks which rows have changed since the last update.
diff := te.NewDiffScreen(80, 24)
stream := te.NewStream(diff, false)DebugScreen writes JSON-encoded event data for diagnostics and testing.
debug := te.NewDebugScreen(os.Stdout)
stream := te.NewStream(debug, false)The SVG exporter renders a screen buffer into a self-contained SVG image.
opts := te.DefaultSVGOptions()
svg := te.RenderScreenSVG(screen, opts)You can customize colors and fonts by setting fields in SVGOptions.
The repository includes an SVG snapshot of Copilot running inside tmux (with a green status bar) generated by scripts/capture_copilot_tmux_svg.sh:
go test ./...The project maintains a complete audit of the pyte and ESCTest2 ports. See docs/TEST_AUDIT_CHECKLIST.md for the canonical mapping between upstream tests and Go counterparts.
A standalone script captures a tmux pane running Copilot and renders the result to SVG. It expects tmux, go, and a Copilot CLI (gh copilot or copilot).
./scripts/capture_copilot_tmux_svg.shUseful environment variables:
COPILOT_CMD: command to run inside tmux (default:copilot).TERMINAL_WIDTH/TERMINAL_HEIGHT: tmux client size (pane height is one row less when status is enabled).CAPTURE_DELAY: seconds to wait before capture (when not attaching).ATTACH_SESSION=1: attach to tmux interactively before capture.OUTPUT_SVG: output path for the generated SVG.INCLUDE_STATUS=1: include a rendered tmux status bar row.STATUS_BG/STATUS_FG: ANSI color names for the status bar background/foreground.STATUS_TEXT: status bar text (tmux format expansion supported).
The script uses scripts/render_svg.go to parse the captured pane output and export SVG via te.RenderScreenSVG.
go-te can be compiled to WebAssembly using either the Go toolchain (GOOS=js GOARCH=wasm) or TinyGo, making it suitable for browser-based terminal playback or screenshot tooling.
docs/TEST_AUDIT_CHECKLIST.md— test mapping statusdocs/PYTE_PORTING_CONVENTION.md— pyte porting rulesdocs/ESCTEST_PORTING_CONVENTION.md— esctest2 porting rulesdocs/pyte-test-coverage.md— behavior coverage summarydocs/SPEC.md— implementation notes and API scope
See LICENSE for details.