Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.5.0"
".": "0.6.0"
}
67 changes: 67 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,73 @@

## [Unreleased]

## [0.6.0] - 2026-11-09

### Added

- `record diff <session-a> <session-b>` replays two sessions offline and reports an LCS line diff between their canonical visible screens, with `--at-seq-a`/`--at-seq-b` for self-diffs against earlier state ([#170](https://github.com/coder/agent-tty/pull/170)).
- `record export --format svg [--animate]` writes a deterministic, byte-stable SVG (SMIL-animated or still) with no browser or ffmpeg; bundles JetBrains Mono and symbol-font subsets ([#171](https://github.com/coder/agent-tty/pull/171), [#349](https://github.com/coder/agent-tty/pull/349)).
- `screenshot --out <path>` writes the PNG to an explicit path (relative or absolute), with a shared `--out` resolver that also refuses paths inside session storage ([#241](https://github.com/coder/agent-tty/pull/241)).
- `screenshot --out` and `record export --out` now create missing parent folders like `mkdir -p`, except inside `sessions/` ([#290](https://github.com/coder/agent-tty/pull/290)).
- `mouse` CLI/RPC command and batch step: mode-aware native mouse input (clicks, drags, wheel) through the libghostty-vt backend, logged as `input_mouse` events; introduces the `CAPABILITY_UNAVAILABLE` error (exit 12) ([#179](https://github.com/coder/agent-tty/pull/179)).
- `wait --scope cursor-line` matches `--text`/`--regex` against the cursor row only, avoiding echo-of-command false positives; also available on batch `wait` steps ([#169](https://github.com/coder/agent-tty/pull/169)).
- `screenshot --json` reports glyphs drawn as `.notdef` boxes in `missingGlyphs` with their cells, plus `missingGlyphsTruncated`; `record export --format webm` reports the same per-code-point list ([#240](https://github.com/coder/agent-tty/pull/240), [#278](https://github.com/coder/agent-tty/pull/278)).
- Noto Sans Symbols 2 and Noto Sans Math subsets are now bundled and fall back after host monospace, so many previously-boxed symbols render without changing text-default emoji ([#278](https://github.com/coder/agent-tty/pull/278)).
- Session programs now get `AGENT_TTY_ACTIVE=true` and `AGENT_TTY_SESSION_ID=<uuid>` in their environment ([#166](https://github.com/coder/agent-tty/pull/166)).
- Sessions now default `COLORTERM=truecolor`, and the PTY query responder answers XTGETTCAP `Tc`/`RGB`/`setrgbf`/`setrgbb` and declines DECRQSS SGR, so programs like Neovim enable 24-bit color under `env -i` or `--env COLORTERM=` ([#231](https://github.com/coder/agent-tty/pull/231), [#271](https://github.com/coder/agent-tty/pull/271)).
- `inspect --json` reports `eventLogStop` (`reason`, `seq`) when the host has stopped appending at a limit; `WAIT_TIMEOUT` and offline `REPLAY_ERROR` messages/details name the stop ([#340](https://github.com/coder/agent-tty/pull/340), [#357](https://github.com/coder/agent-tty/pull/357)).

### Changed

- **Build:** migrated from aube to pnpm (10.34.5); contributors run `pnpm install` / `mise run bootstrap` and Dependabot can now update `pnpm-lock.yaml` ([#176](https://github.com/coder/agent-tty/pull/176)).
- **`wait` default timeout is now 30 s** (was 600 s); `wait --help` shows the default. Windows that cannot finish inside the timeout (`--idle-ms`, `--screen-stable-ms`) are rejected up front with `INVALID_DURATION`. Batch `wait` steps share the same default and the same window rule ([#236](https://github.com/coder/agent-tty/pull/236), [#250](https://github.com/coder/agent-tty/pull/250), [#277](https://github.com/coder/agent-tty/pull/277)).
- **Timed-out `wait` now returns an error envelope** with `ok: false`, `error.code: "WAIT_TIMEOUT"` (exit 11 unchanged), while preserving `result.timedOut`/`matched`. Fail-fast `batch` failures emit the matching error envelope with step details ([#232](https://github.com/coder/agent-tty/pull/232), [#273](https://github.com/coder/agent-tty/pull/273), [#301](https://github.com/coder/agent-tty/pull/301)).
- A render `wait` that fails every poll now stops with the renderer's error (for example `REPLAY_ERROR`) instead of reporting `WAIT_TIMEOUT` ([#301](https://github.com/coder/agent-tty/pull/301)).
- Unexpected errors print one `INTERNAL_ERROR` JSON envelope on stdout under `--json`, and the CLI exits promptly after it instead of hanging on open handles. Empty/invalid session IDs return `INVALID_SESSION_ID` (exit 2) on every command. Commander usage errors emit an `INVALID_INPUT` envelope under `--json` ([#237](https://github.com/coder/agent-tty/pull/237), [#287](https://github.com/coder/agent-tty/pull/287)).
- Live-command errors from the session host now carry `details` across RPC (e.g. `details.path`, `details.errno`), matching offline errors ([#313](https://github.com/coder/agent-tty/pull/313)).
- Node version is checked against `engines.node` (`>=24.0.0 <27`) at startup with a one-line stderr warning; `doctor` fails on versions outside that range ([#245](https://github.com/coder/agent-tty/pull/245)).
- `snapshot --include-cells` now accepts RPC responses up to 64 MiB (previously capped at 1 MiB); larger successes return `PROTOCOL_ERROR` with the size ([#320](https://github.com/coder/agent-tty/pull/320)).
- `config.json` errors are typed: unreadable → `STORAGE_READ_ERROR`, invalid JSON/schema → `INVALID_INPUT`. `list` on an unreadable sessions dir returns `STORAGE_READ_ERROR`. `help` exits 0 ([#287](https://github.com/coder/agent-tty/pull/287)).
- `screenshot`/`record export` with a non-folder or dangling symlink at `artifacts/` now give `STORAGE_WRITE_ERROR` (exit 8) with a clear message ([#287](https://github.com/coder/agent-tty/pull/287), [#301](https://github.com/coder/agent-tty/pull/301)).
- WebM exports no longer impose a total 5-minute replay deadline. The replay fails only when the renderer makes no progress for 5 minutes, and the error names the window and the last event ([#356](https://github.com/coder/agent-tty/pull/356)).
- `record export --format webm` on a session that printed nothing exits 0 with a blank video at `capturedAtSeq: -1`; asciicast reports `-1` instead of `0` ([#270](https://github.com/coder/agent-tty/pull/270)).
- `destroy` typed into the session's own shell now forwards SIGINT/SIGTERM to its detached re-run copy and exits 130/143 to match ([#281](https://github.com/coder/agent-tty/pull/281)).
- `destroy --force` records a session as `destroyed` when the program-group read fails twice with EACCES/EPERM/EIO/EISDIR/ENOTDIR/ELOOP/ENAMETOOLONG, or when it cannot read the program group at all ([#327](https://github.com/coder/agent-tty/pull/327), [#331](https://github.com/coder/agent-tty/pull/331), [#334](https://github.com/coder/agent-tty/pull/334)).

### Fixed

- **`snapshot`/`screenshot` on a session that has printed nothing** now return an empty screen or blank PNG at `capturedAtSeq: -1` instead of failing with `RPC_ERROR` ([#235](https://github.com/coder/agent-tty/pull/235)).
- **`screenshot --hide-cursor`** actually hides the block cursor in the PNG (was previously byte-identical to `--show-cursor`) ([#289](https://github.com/coder/agent-tty/pull/289)).
- **WebM output now shows printed lines at their recorded time** instead of batching to the next non-output event ([#285](https://github.com/coder/agent-tty/pull/285)).
- **ghostty-web replay is roughly 50x faster**: 20,000-event screenshots dropped from ~386 s to ~7 s. Each replay flush now writes in one animation frame; `max-speed` WebM respects recorded time and holds one video frame before resizes ([#358](https://github.com/coder/agent-tty/pull/358), [#364](https://github.com/coder/agent-tty/pull/364)).
- Live `screenshot`/`snapshot --renderer ghostty-web` on long logs no longer time out at 5 s: the host streams keep-alives and replays the backlog in bounded slices, so clients wait as long as replay progresses ([#359](https://github.com/coder/agent-tty/pull/359)).
- A `ghostty-web` page crash during replay is now reported as `REPLAY_ERROR` (exit 10, `retryable: false`) on live and offline paths with a message that names the known cause, instead of `RPC_ERROR`/`INTERNAL_ERROR` with retries that can never succeed ([#363](https://github.com/coder/agent-tty/pull/363)).
- `create` under heavy host load now waits for the detached host as long as it is alive (up to 30 s on a monotonic clock) and treats first-probe `EPIPE` as "not ready yet", instead of failing with `HOST_UNREACHABLE` after a fixed 50-poll budget ([#362](https://github.com/coder/agent-tty/pull/362)).
- `create` that gives up on its host now instructs that host to stop the session, so no orphan `running` session is left behind ([#247](https://github.com/coder/agent-tty/pull/247)).
- Concurrent captures no longer drop entries from `artifacts/manifest.json`: appends run under a cross-process lock with stale-owner recovery ([#282](https://github.com/coder/agent-tty/pull/282)).
- Multiple session-lifecycle race fixes across `create`/`reconcile`/`gc`/`destroy`: hosts record pids up front, `writeManifest` no longer resurrects removed session folders, `gc` keeps exited sessions whose program group still runs (so `destroy` can end them), and `destroy --force` provably covers unshared/hidden-proc cases ([#181](https://github.com/coder/agent-tty/pull/181), [#194](https://github.com/coder/agent-tty/pull/194), [#200](https://github.com/coder/agent-tty/pull/200), [#201](https://github.com/coder/agent-tty/pull/201), [#216](https://github.com/coder/agent-tty/pull/216), [#221](https://github.com/coder/agent-tty/pull/221), [#302](https://github.com/coder/agent-tty/pull/302), [#312](https://github.com/coder/agent-tty/pull/312)).
- Event log stops gracefully at the 50 MiB / 250,000-event limit with a labeled stop marker instead of crashing the host or failing every subsequent export/snapshot ([#340](https://github.com/coder/agent-tty/pull/340)).
- `pty` no longer leaks an outer session id into session-less PTYs ([#178](https://github.com/coder/agent-tty/pull/178)).
- Waited `run` input is now logged in PTY order, and mouse motion dedup state is preserved across renderer swaps ([#234](https://github.com/coder/agent-tty/pull/234)).
- Repeated captures keep earlier artifact files instead of clobbering each other; exports are taken from their temp file to avoid races ([#191](https://github.com/coder/agent-tty/pull/191), [#316](https://github.com/coder/agent-tty/pull/316), [#321](https://github.com/coder/agent-tty/pull/321)).
- Per-session sockets are now rooted under a per-uid path and dead-host sockets are removed; `host.json` refuses to grow a hostname-mismatched stub ([#239](https://github.com/coder/agent-tty/pull/239), [#288](https://github.com/coder/agent-tty/pull/288), [#305](https://github.com/coder/agent-tty/pull/305)).
- RPC: request `id` capped at 128 chars; response cap raised to 64 MiB with `PROTOCOL_ERROR` above; truncated error messages no longer split surrogate pairs; older-host oversize responses are reported as `PROTOCOL_ERROR` ([#315](https://github.com/coder/agent-tty/pull/315), [#319](https://github.com/coder/agent-tty/pull/319), [#320](https://github.com/coder/agent-tty/pull/320), [#322](https://github.com/coder/agent-tty/pull/322)).
- `create` validates `cwd` and shell before creating the session directory ([#188](https://github.com/coder/agent-tty/pull/188)).
- `--out` writes retry against a swapped output folder and refuse unsearchable parents, and a failed `screenshot --out` undoes its in-session capture ([#279](https://github.com/coder/agent-tty/pull/279), [#300](https://github.com/coder/agent-tty/pull/300)).
- SVG export now succeeds as a still when the session clock stepped backward; `--animate` surfaces a clear `EXPORT_ERROR` naming the first bad event ([#349](https://github.com/coder/agent-tty/pull/349)).
- Numerous additional host, storage, destroy, verify-skill and lifecycle-model fixes — see the full changelog for the complete list.

### Breaking Changes

- **`wait` default timeout dropped from 600 s to 30 s** ([#236](https://github.com/coder/agent-tty/pull/236)). Scripts that relied on waiting longer than 30 s must pass `--timeout` explicitly (or `--timeout 0` to wait without a limit). Batch `wait` steps share the new default ([#250](https://github.com/coder/agent-tty/pull/250)).
- **Timed-out `wait` returns `ok: false`** with `error.code: "WAIT_TIMEOUT"`; consumers checking `.ok === true` on a timeout will now see `false`. `.result.timedOut`/`matched` still carry the old fields. Fail-fast `batch` failures also now emit `ok: false` ([#232](https://github.com/coder/agent-tty/pull/232)).
- **Render `wait` on persistent renderer failure now exits 9 `RPC_ERROR`** (or the renderer's own `CliError` code such as `REPLAY_ERROR`), not exit 11 `WAIT_TIMEOUT` ([#301](https://github.com/coder/agent-tty/pull/301)).
- **Inherited `COLORTERM` from the shell that runs `agent-tty create` no longer reaches the session**; sessions see `COLORTERM=truecolor` unless overridden with `--env COLORTERM=<value>` ([#231](https://github.com/coder/agent-tty/pull/231)).
- Invalid session IDs on most commands now return exit 2 `INVALID_SESSION_ID` instead of exit 1 with a stack trace ([#237](https://github.com/coder/agent-tty/pull/237)).
- Downgrade compatibility note: an older CLI against a new host may see `RPC_ERROR` "RPC result failed validation" for new optional fields such as `eventLogStop`, `mouse-input` capability, or `details` on live errors; newer CLI against older hosts works fine ([#179](https://github.com/coder/agent-tty/pull/179), [#313](https://github.com/coder/agent-tty/pull/313), [#357](https://github.com/coder/agent-tty/pull/357)).
- `record export --format asciicast` on an empty log names its file `recording--1-asciicast.cast` (was `recording-0-asciicast.cast`); `capturedAtSeq` can now be `-1` in result schemas ([#235](https://github.com/coder/agent-tty/pull/235), [#270](https://github.com/coder/agent-tty/pull/270)).
- `screenshot`/`record export --out` paths that resolve inside `sessions/` are rejected with exit 7 `EXPORT_ERROR` (previously accepted for `record export`) ([#241](https://github.com/coder/agent-tty/pull/241)).

## [0.5.0] - 2026-06-23

### Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ See [`docs/AGENT-SKILLS.md`](./docs/AGENT-SKILLS.md).

## Status & platform support

`agent-tty` is `0.5.0` and focused on reliable, isolated, reviewable terminal and TUI automation through a stable CLI. <!-- x-release-please-version -->
`agent-tty` is `0.6.0` and focused on reliable, isolated, reviewable terminal and TUI automation through a stable CLI. <!-- x-release-please-version -->

- Linux and macOS are tier-1; Windows is tier-2 and not CI-tested.
- Semantic snapshots and render-backed waits prefer the optional `libghostty-vt` backend when it is available, then fall back to `ghostty-web`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agent-tty",
"version": "0.5.0",
"version": "0.6.0",
"description": "Terminal automation CLI for AI agents and humans",
"license": "Apache-2.0",
"keywords": [
Expand Down
Loading