Skip to content

fix: capture an empty screen on a session that has printed nothing - #235

Merged
ThomasK33 merged 6 commits into
mainfrom
fix/213-empty-session-capture
Nov 2, 2026
Merged

ThomasK33 merged 6 commits into
mainfrom
fix/213-empty-session-capture

Conversation

@ThomasK33

Copy link
Copy Markdown
Member

Why

The operator wants his open agent-tty issues landed. This PR fixes #213. On a session whose program has not printed yet, snapshot and screenshot failed with exit 9 RPC_ERROR and retryable: true, and a retry failed the same way. An empty Event Log is a valid state: a blank screen at the session's size. Both renderer backends refused to render it, and the host and the offline replay path skipped the replay for it.

What changed

  • Both backends accept a replay to targetSeq -1. They take the session size and replay nothing. The host and the offline replay path now always replay, also for an empty log.
  • A capture before the first event reports capturedAtSeq: -1. record diff already uses -1 for this state. A new ReplaySeqSchema (an integer of at least -1) types capturedAtSeq in the snapshot, screenshot, render-wait and batch results, the artifact manifest and the renderer types.
  • wait --after-seq accepts -1, so the capturedAtSeq of an empty snapshot can be passed to it.

Behavior changes for CLI and JSON users

  • snapshot --json and screenshot --json on a silent session exit 0. They return an empty screen or a blank PNG of the session's size, with capturedAtSeq: -1. The screenshot file is screenshot--1-<profile>.png.
  • After a host death with an empty log, the offline snapshot, screenshot and render wait paths now return a JSON envelope. Before, they printed a raw Node stack and exited 1.
  • Live render waits no longer stop after about 3 s on a session that has not printed yet. Before, wait --text ready --timeout-ms 20000 returned timedOut: true after 3.0 s for output that came at 6 s. --screen-stable-ms now matches the blank screen.
  • capturedAtSeq and --after-seq can now be -1. A client that requires capturedAtSeq >= 0 must also accept -1. A live render wait that times out on an empty log reports capturedAtSeq: -1 (it was 0).

Scope

  • This PR covers snapshot, screenshot and render waits, live and offline, on both backends.
  • record export --format webm on an empty log still fails with exit 7 EXPORT_ERROR. Record export has its own "requires at least one event" checks. A blank video needs a decision on the empty-log seq for record export, because asciicast export reports 0 there today. I left it for a follow-up.

Tradeoffs

  • I did not report capturedAtSeq: 0 for the empty screen. That value says event 0 was rendered, and a wait --after-seq 0 chained from it skips the first output.

Verification

  • test/integration/empty-session-capture.test.ts (9 tests) fails 9 of 9 on main 997f701 and passes on this branch. Both backends have a new unit test for the empty replay.
  • Gates on this branch: unit 1593 passed. Integration (4 shards) 265 passed and e2e (3 shards) 34 passed, with 2 tests passing on retry under load average 82. typecheck, lint, format:check and the verify-session-lifecycle check.sh exit 0.
  • Live CLI run, before and after: 1 of 10 checks pass on main, 10 of 10 on this branch. The blank screenshot is byte-identical to a screenshot of a session that printed only a clear-screen sequence.

Closes #213


Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: xhigh

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-02T14:54:32.062349Z f29dde0 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: 8ecce4f16a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: f29dde0c6b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ThomasK33
ThomasK33 added this pull request to the merge queue Nov 2, 2026
Merged via the queue into main with commit 9d4ab3c Nov 2, 2026
12 checks passed
@ThomasK33
ThomasK33 deleted the fix/213-empty-session-capture branch November 2, 2026 16:44
@github-actions github-actions Bot mentioned this pull request Nov 2, 2026
ThomasK33 added a commit that referenced this pull request Nov 2, 2026
…itial size

#235 made screenshot() require replayTo() through initialReplayCols. Refs #226
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

snapshot and screenshot fail with RPC_ERROR on a session that has printed nothing

1 participant