Skip to content

chore(release): 0.6.0 - #172

Open
github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main
Open

github-actions[bot] wants to merge 1 commit into
mainfrom
release-please--branches--main

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

The next agent-tty release. Merging this PR creates the release tag and GitHub Release and starts the publish pipeline.

[0.6.0] - 2026-11-05

Added

  • mouse command and batch step for mode-aware native mouse input (clicks, drags, wheel), encoded in the child program's negotiated tracking mode. Requires the libghostty-vt renderer with the optional @coder/libghostty-vt-node native package; a new mouse-input capability and CAPABILITY_UNAVAILABLE error (exit 12) is returned otherwise (#179 by @pmarreck, #234, #293).
  • wait --scope cursor-line matches --text/--regex against only the cursor's row, avoiding false positives from a terminal echoing the command that was just typed. Available as scope on batch wait steps and the waitForRender RPC (#169).
  • record diff <session-id-a> <session-id-b>: a new offline command that replays two sessions from their event logs and emits an LCS line diff (--at-seq-a/--at-seq-b supported, including -1 for an empty log), as JSON ({ identical, a, b, diff }) or a unified-style human diff (#170, #300).
  • screenshot --out <path> writes the PNG to a chosen location while still publishing the in-session capture. Shares a hardened resolver with record export --out that creates missing parent folders (like mkdir -p) and refuses paths under session storage (#241, #279, #290).
  • screenshot --json now reports missingGlyphs and missingGlyphsTruncated: glyphs drawn as .notdef boxes, with the cells where they appear. record export --format webm reports missingGlyphs (code-point only) for glyphs that any painted frame drew as a box. The bundled font stack now also ends with Noto Sans Symbols 2 and Noto Sans Math (OFL-1.1 subsets without Emoji code points) to cover more symbols out of the box (#240, #278).
  • PTY sessions now export AGENT_TTY_ACTIVE=true and AGENT_TTY_SESSION_ID=<id> so programs can detect the active session and reference their own session id (#166 by @prmartinow, #178).
  • Sessions default COLORTERM=truecolor, and the host now answers Neovim's XTGETTCAP (Tc, RGB, setrgbf/setrgbb) and declines DECRQSS SGR, so 24-bit color turns on even with env -i or --env COLORTERM=. Opt back out with another --env COLORTERM=<value> (#231, #271).

Changed

  • Standalone wait --timeout defaults to 30 s (was 600 s) and the default is shown in --help. Pass --timeout 0 to wait indefinitely. A batch wait step without timeout also defaults to 30 s. Windows (--idle-ms/--screen-stable-ms) that cannot finish within the timeout are now rejected up front with INVALID_DURATION (exit 2) (#236, #250, #277).
  • A timed-out wait now emits ok: false with error.code: "WAIT_TIMEOUT" (exit code remains 11) while still carrying result.timedOut/matched/capturedAtSeq. Fail-fast batch --json with a failing step now returns an error envelope with the step's code and the full result.steps (#232). Human-mode messages now name the timeout, e.g. Wait timed out after 30000 ms (the default; pass --timeout <ms>, or --timeout 0 to wait without a limit). (#273, #301).
  • A render wait that fails every renderer poll now stops with the renderer's own error (exit 9 RPC_ERROR), not WAIT_TIMEOUT. WAIT_TIMEOUT is now reserved for the deadline running out (#301).
  • WebM exports now play back at their recorded pace: output batches flush on a monotonic schedule instead of waiting for a non-output event, so continuous output no longer appears in one late frame (#285).
  • All RPC sockets moved to a private per-uid root /tmp/agent-tty-<uid>/ (mode 0o700). inspect --json reports the new host.rpcSocketPath; a one-release fallback still reads sockets at the old /tmp/agent-tty/ path for sessions started by older builds (#288).
  • Live snapshot --include-cells responses are now accepted up to 64 MiB (was 1 MiB), so styled captures on terminals up to ~1.2 M cells succeed. A response that still exceeds the cap is reported as PROTOCOL_ERROR with details.maxResponseChars (#320, #322).
  • CliError.details from the session host now carry through the RPC so live errors see the same details as offline ones (for example snapshot/screenshot now report details.path and details.errno) (#313).
  • Playwright bumped to 1.64.1 so Chromium installs on Ubuntu 26.04. Chromium moves from 148 to 156, and exported WebM now uses VP9 instead of VP8. Run npx playwright install chromium once after upgrading (#192).
  • Pinned @coder/libghostty-vt-node to 0.1.0-beta.7: fixes same-cell mouse motion dedup after program output and lowers the linux-x64 prebuild to the x86-64 baseline (still needs AVX2) (#179, #293).

Fixed

  • snapshot, screenshot, and render wait on a session that has not printed yet now return an empty screen / blank PNG at capturedAtSeq: -1 instead of failing with RPC_ERROR. record export on an empty log also exports at seq -1 (asciicast header-only, WebM a blank video) (#235, #270, #300).
  • screenshot --show-cursor and --hide-cursor now produce different PNGs: the canvas is force-redrawn when the cursor toggle changes, so the default (hidden) no longer shows a block cursor (#289).
  • Unexpected errors and invalid session IDs now always emit a single JSON envelope under --json (never a raw Node stack): INTERNAL_ERROR for unexpected failures, INVALID_SESSION_ID for empty/./../path-like IDs across every command, and INVALID_INPUT for Commander usage errors (#237). The CLI now exits deterministically after INTERNAL_ERROR instead of hanging on leaked handles, and snapshot/screenshot/record export now report STORAGE_WRITE_ERROR (with details.errno) when the artifacts path is a file, a symlink loop, or a dangling symlink (#287, #301).
  • On an unsupported Node version the CLI now logs one warning to stderr at startup, and doctor checks against the engines.node range in package.json (currently >=24.0.0 <27) instead of a hard-coded 24+ (#245).
  • Concurrent captures on one session no longer drop manifest entries: a manifest.json.lock now serializes publish+append across the host and CLI processes (#282, #299, #318). Repeat screenshot/snapshot captures at the same seq now publish via link so a failed append never deletes an earlier capture's file (#191). Two record export runs at the same seq no longer leave a manifest entry pointing at bytes that were replaced (#300, #316). A failed screenshot --out copy now removes the in-session capture and its manifest entry (#300).
  • Waited run input is now logged in PTY order relative to concurrent type/paste/send-keys (no more log/PTY reorder when input_run awaits its write), and native mouse state is preserved across renderer swaps by giving mouse its own HostRendererManager (#234).
  • destroy typed into the session's own interactive shell now reliably prints its result: the copy is re-run in a new session and forwards SIGINT/SIGTERM (exits 130/143); off-Linux it finds the session by its controlling terminal; /proc/self/stat that cannot be read (or reports session id 0) is counted as inside the program's session; and the Windows path has bounded retries plus a late-host marker watch so a failed create never leaves a serving host (#216, #246, #259, #281, #324, #327, #331, #333, #334).
  • create that gives up on its host now stops that host, so a late-starting host can no longer serve a failed session. Every create error after the first manifest write now carries error.details.sessionId, and text-mode prints Session <id> failed to start. on stderr first (#247, #294, #312).
  • Lifecycle correctness: create/reconcile/gc races closed so another agent's gc cannot remove a starting session (#181); writeManifest no longer recreates a folder that gc removed (#200, #210, #212); gc keeps an exited session whose program group still runs (even a fast fork chain under a non-reaping PID 1) so destroy can end the leftover (#302, #326); a host record from another machine or time namespace reads as unknown instead of killing a live session (#275); and destroy --force now ends sessions whose program.json cannot be read (EACCES, EIO) (#327).
  • The Home registry keeps valid entries when one entry is invalid, instead of returning an empty list and letting the next create overwrite the file (#186).
  • The per-session socket directory is now removed once it holds no socket, so throwaway Homes do not pile up under /tmp/agent-tty/ (#239).
  • RPC hardening: error responses cannot crash the host, oversized messages are truncated with [message truncated], surrogate pairs are kept whole, the request-id echo is capped at 128 characters, and responses from an older host over the 64 MiB cap now report PROTOCOL_ERROR (not retryable) (#315, #319, #322).
  • Many smaller fixes: macOS APFS EINVAL from a removed session folder is now mapped to SESSION_NOT_FOUND (#318, #321); WebM size and SHA-256 come from the temp file to survive a post-rename overwrite (#321); native mouse dedup is preserved after a renderer swap (#293); session-less PTYs (e.g. the doctor probe) no longer inherit the outer session's env (#178); and the validate-bundle --profile canonical tool now rejects symlinks that escape the bundle root (#187).

Breaking Changes

  • wait --timeout default dropped from 600 s to 30 s (also for batch wait steps). Scripts that relied on the old 10-minute default must pass an explicit --timeout or "timeout": <ms> on the step. Pass --timeout 0 / "timeout": 0 for no limit (#236, #250).
  • A timed-out wait --json now emits ok: false with error.code: "WAIT_TIMEOUT" and the existing result fields alongside error. Callers that branch on .ok for a timeout will see the opposite value; exit code is unchanged (11). Fail-fast batch --json with a failing step is affected the same way (#232).
  • RPC sockets moved to /tmp/agent-tty-<uid>/. A CLI running as a different uid (e.g. sudo agent-tty …) can no longer reach hosts your uid started. Scripts that hand-built the old socket path must read inspect --json's host.rpcSocketPath. The old-path fallback for sessions started by 0.5.0 or earlier is slated for removal in 0.7.0 (#288).
  • Playwright 1.64.1 / Chromium 156. Users must run npx playwright install chromium once after upgrading; until then screenshot and record export --format webm report the capability as degraded in doctor. Exported WebM is now VP9 (was VP8) (#192).
  • A render wait whose renderer repeatedly fails now exits 9 RPC_ERROR with the renderer's own message, not 11 WAIT_TIMEOUT. Callers that treated every exit-11 as a timeout must branch on error.code (#301).
  • capturedAtSeq: -1 is now a valid value in snapshot, screenshot, render-wait, and record export results on an empty event log. JSON consumers that asserted capturedAtSeq >= 0 must relax that check (#235, #270).
  • Native mouse (agent-tty mouse …) requires the libghostty-vt renderer with the optional @coder/libghostty-vt-node 0.1.0-beta.7 package; the Linux x64 prebuild still requires AVX2. CAPABILITY_UNAVAILABLE (exit 12) is a new error code (#179).

New Contributors


Maintained by the release-please workflow. Notes are regenerated by Communique on every push to main, so manual edits to this PR are overwritten.

@github-actions github-actions Bot changed the title chore(release): 0.5.1 chore(release): 0.6.0 Aug 21, 2026
@github-actions
github-actions Bot force-pushed the release-please--branches--main branch 2 times, most recently from b99a3f3 to 8803e75 Compare August 21, 2026 16:02
@github-actions
github-actions Bot force-pushed the release-please--branches--main branch 3 times, most recently from 4877580 to 37f9725 Compare September 24, 2026 12:15
@github-actions
github-actions Bot force-pushed the release-please--branches--main branch 22 times, most recently from 4dbc4df to 7eea1fa Compare November 2, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants