Terminal
A Terminal is a live terminal session. It wraps a Backend and adds everything you need to run a real program and inspect what it draws:
- an optional PTY — spawn a process and connect it to the emulator;
- the buffer — cells, colors, cursor, scrollback, modes;
- a readable surface — query the screen as structured data, not strings;
- input — press keys, type text, click and drag;
- region selectors + matchers — the testing surface.
A Terminal is the live counterpart of a Recording: a Terminal is a session happening now; a Recording is a session captured over time.
Creating a Terminal
import { createTerminal } from "@termless/core"
import { createXtermBackend } from "@termless/xtermjs"
const term = createTerminal({ backend: createXtermBackend(), cols: 80, rows: 24 })
await term.spawn(["bash", "-lc", "ls -la"])The readable surface
A Terminal exposes its buffer as queryable values, never as a flat string:
Buffer/Cell— the grid and a single cell (text, fg, bg, style flags).RegionView— a lazy view over part of the screen that recomputes on access.RowView— a single row with cell-level access.
These are value types within a Terminal — not separate domain objects. You read them; you don't construct a session out of them.
Region selectors + matchers
Termless's headline testing API is a query-and-assert pair over a Terminal: pick where with a region selector, assert what with a matcher.
expect(term.screen).toContainText("ready")
expect(term.cell(0, 8)).toHaveFg("#00ff00")
expect(term).toHaveCursorAt(14, 2)Region selectors — term.screen, term.scrollback, term.buffer, term.viewport, term.row(n), term.cell(r, c), term.range(...) — are an API over a Terminal, not a noun of their own.
See the Terminal API for the full method list, the Writing Tests guide for the testing workflow, and the Matcher Reference for every matcher.