Skip to content

fix(runtime): read Antigravity, Cline and Prime Agent readiness from the live screen - #24222

Merged
Jinwoo-H merged 10 commits into
mainfrom
jinwoo/sta-8741-screen-readiness
Oct 1, 2026
Merged

Jinwoo-H merged 10 commits into
mainfrom
jinwoo/sta-8741-screen-readiness

Conversation

@Jinwoo-H

@Jinwoo-H Jinwoo-H commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 73 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1670 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​1669
Prod 20 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​743 $\color{#cf222e}{\Huge{\mathbf{−}}}$​123 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​620

ELI5

Before Orca hands a task to a freshly started agent, it waits until the agent is sitting at its input box. For Antigravity, Cline and Prime Agent that wait often never ended: the agent was visibly ready, but Orca couldn't tell, so worker-start gave up. Orca now looks at the agent's actual screen, the same way #23475 fixed Codex.

What Changed

Before: orca orchestration worker-start --agent antigravity|cline|prime-agent (and terminal wait --for tui-idle) often failed with agent_readiness / timeout while the agent showed its empty prompt.

After: the wait settles once the agent's empty input box is on screen and its output has been quiet for 3 s. Then the task is delivered.

Mechanism:

  • Orca's readiness check read a line-by-line text copy of the terminal output. That copy drops cursor movement, and these three agents draw their input box with cursor movement, so the prompt never appeared in it.
  • Main already keeps a live screen for every terminal (readLiveTerminalScreenLines, from fix(runtime): read Codex readiness from the live screen #23475). Each agent now has a small rule that reads its input box off that screen, written against real recordings: antigravity-terminal-readiness.ts, cline-terminal-readiness.ts, prime-agent-terminal-readiness.ts. They are registered in one table (screen-ruled-agent-readiness.ts), with no per-agent branches elsewhere.
  • Quiet period. These agents paint something that looks like their input box for a moment mid-turn, so a screen match only counts after 3 s without output.
  • Other checks, when the screen is trusted. While Orca can read a trustworthy screen, the "process went quiet" and "terminal title says the agent's name" checks can no longer override it. The recordings show both would settle over a model picker or a permission prompt.
  • When the screen isn't trusted, nothing changes. The screen counts as untrusted when there's no emulator, the grid size differs from the terminal's, or it was resized after reconnecting without a repaint. Then the pre-existing checks decide exactly as before, so a reconnected pane can't lose readiness it has today.
  • Antigravity probe. The Antigravity-only branch of the visible-read probe is removed. The probe now uses the same shared rule for any of these agents.
  • Only the three agents use the new screen reader. Their rules read through a new readScreenRuledLines, which returns the screen's raw rows (the read projection blanks Cline's placeholder, so a typed draft would look like an empty box) and applies the size-match and reflow checks. readLiveTerminalScreenLines is unchanged, so Codex, Qoder and every other agent read the screen exactly as on main. Proof: the 31 suites for those agents pass identically on main and this branch, and replaying all 93 of their recording/grid-size combinations frame by frame gives identical ready and blocked results.

Why

  • Why the screen, not a patch to the text copy: the text copy has no screen positions, so following cursor movement would mean writing a second terminal emulator. One already exists in main.
  • Why rules written against recordings: the Antigravity rule had been rewritten five times against screens typed from memory. Each rule here is checked against real recordings of its ready, busy, dialog and draft screens. Breaking any part of a rule makes a replay test fail.
  • Why the quiet period, not a stricter screen match: mid-stream, a Cline reply can look identical to an idle Cline, so no screen rule alone can tell them apart.
  • Alternatives considered:

Linked Issue

Fixes #15838
Fixes #23268
Fixes #22153

Related: #23475, #14561. Linear STA-8741. ZCode is left for later; its reported bug is fixed by #23374.

Visual Proof

N/A: no UI change. The observable difference is that worker-start reaches ready instead of an agent_readiness timeout (see Testing).

Testing

  • New recordings, captured with config/scripts/capture-agent-pty-transcript.mjs on macOS and scrubbed:
    • Antigravity 1.2.14: 12 recordings.
    • Cline 3.0.66: 9 recordings, plus the reporter's 3.0.65 Windows capture.
    • Prime Agent 0.9.8: 9 recordings, plus the reporter's two 0.9.5 captures.
    • Each covers ready, busy, dialog/picker and typed-draft screens. Details are in docs/reference/antigravity-readiness-evidence.md and docs/reference/cline-and-prime-agent-readiness-evidence.md.
  • Replay tests feed each recording through onPtyData and cover:
    • ready screens settle;
    • busy, dialog and draft screens never settle;
    • ready screens on a mismatched or reconnected grid still settle through the old checks;
    • a restored pane settles through the probe, using the real screen projection.
  • Mutation checks: reverting each rule piece or fix makes at least one test fail.
  • Gates: pnpm tc:node, oxlint on changed files and pnpm run check:code-quality:changed pass. The changed and related suites pass: 489 tests across 11 files. The runtime, daemon, shared and IPC suites pass except 3 tests that depend on the local shell setup and don't touch this code.
  • Gaps:
    • No Linux recordings; Windows only for Cline startup.
    • No recordings of Antigravity or Prime permission prompts; neither account asked for one.
    • A Cline reply that goes silent for 3 s after its spinner scrolls off would read ready (documented).
  • I manually tested these changes locally (real agent recordings, macOS)
  • Automated tests added/updated

Review

A separate reviewer checked the branch and replayed every agent's recordings: 2,499 tests, no regression for other agents. Its three findings are fixed in the last commit: the mismatched grid, the probe's projection, and the text check overriding the screen.

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

  • SSH: the screen is read in main on the execution host, the same place as the Codex check.
  • Cross-platform: the rules read rendered screen content, not the order bytes arrived in, so Cline's Windows cursor reordering doesn't matter.
  • Backwards compatible: a screen that isn't trustworthy falls back to the previous behaviour.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

agy paints its composer with cursor addressing, so the line-folded wait
text misses the 1.2.14 accept-edits and plan composers and an ended turn,
while the grid keeps the bare `>` caret painted mid-turn and behind the
/model picker. Read the screen's bottom rows instead: rule, caret, rule,
`? for shortcuts`. A clocked pane is held to quiescence (tier 1b) because
the submit repaint reads ready for a moment; a clockless restored pane
settles from the screen alone. When a trustworthy screen exists it
decides, so the name-only title lane no longer settles an open picker.

Retires the visible-read probe's Antigravity branch: the probe now runs
the shared screen rule for any screen-ruled agent without an output
clock, and keeps its generic empty-pane read for everyone else.

Adds twelve agy 1.2.14 recordings and a replay suite shared by
screen-ruled agents. STA-8741.
Cline paints its composer box with cursor addressing on the alternate
screen, so no text rule saw it and worker-start timed out at
agent_readiness (#23268). Read the box off the grid: rule, an empty
composer with one of the captured placeholders, rule, the Plan/Act row
and the auto-approve row, with no braille spinner above it.

A streaming reply repaints the same box once its spinner has scrolled
away, so Cline is tier 1b only: a clocked pane waits for quiet and a
clockless one never settles from the screen. The screen now decides for
a Cline pane, which shuts the quiet-process lane that would have settled
its unworded tool-approval prompt and the Cline Desktop promo.

readLiveTerminalScreenLines now returns raw rows: the read projection
blanks a composer it takes for a draft, and it takes Cline's
placeholder for one, so a typed draft and an empty composer looked the
same.

Adds nine cline 3.0.66 recordings (macOS) and the 3.0.65 Windows capture
from #23269. STA-8741.
Prime redraws its composer on the alternate screen, so the text tail
never showed a settled prompt and tui-idle timed out (#22153). Read the
grid instead: a bare `>` directly over the `<- manage` footer, with no
braille status row (`Writing - 6s`) above it. The footer and caret alone
stay painted for a whole turn.

Replayed chunk by chunk, Prime erases that status row before redrawing
it, and on first launch paints the idle composer just before the
trace-sharing question covers it. Both keep repainting, so a clocked
pane is held to quiescence (tier 1b); a clockless restored pane settles
from the screen alone.

Adds nine prime-agent 0.9.8 recordings (isolated HOME, OpenRouter) and
the two 0.9.5 captures from #22154. STA-8741.
Cline now follows the same pattern as Antigravity and Prime: a screen
rule plus table entries.

- Drop MID_TURN_COMPOSER_AGENTS. onPtyData stamps lastOutputAt on every
  chunk, so a re-attached streaming pane has an output clock from its
  first byte; the exception only guarded a pane that printed nothing
  since attach. A clockless Cline pane now settles from its screen like
  the other two.
- Drop the 'ready-body' rest-signal entries for all three agents. The
  rest signal is read only by quietForegroundLane, and a readable screen
  already shuts that lane and the title lane (isReadinessDecidedByScreen),
  so the entries only removed the quiet-process fallback for a pane with
  no trustworthy grid. The census now checks that screen-shut instead.
- Drop the Cline rule's auto-approve row check; no recorded verdict
  depends on it.

Kept: raw rows from readLiveTerminalScreenLines. Every frame of every
codex-* and qoder-* capture at 120x40, 80x24 and 100x32 gives the same
isKnownReadyPromptBody (with and without a clock) and
isQuietReadyScreenBody verdict through both readers.

Serializer known-failures for the new captures are pre-existing
serializer behaviour, not this branch: row-0 cells restore with a
true-colour background where the source has the default (the DSH
class), and Prime's cursor restores at column 119 instead of the pending
wrap at 120 (the qoder class). STA-8741.
Review findings on the screen-ruled readiness (STA-8741):

- A grid out of step with the PTY garbles cursor-addressed chrome, and a
  model resize does not make the TUI repaint. readLiveTerminalScreenLines
  now returns null unless the emulator's grid matches the PTY's reported
  size and was never reflowed without a repaint (a re-attach that learned
  the real size late), so the pre-existing lanes decide there instead of
  timing out.
- The visible-read probe reads the draft-blanking projection, which
  turns Cline's `❯ Ask anything...` into a bare `❯`. It now restores the
  blanked composer row before the rule reads it; `terminal read --screen`
  output is unchanged.
- The quiet lane no longer ORs the text rules over a trustworthy screen
  that refused; without one, tier 1 already ran them. No recorded
  verdict changes.

Tests: ready recordings on a mismatched and on a reflowed grid settle
through the old lanes; the restored-pane probe runs every ready
recording through the real projection; the rest-signal census checks
the lane verdict with and without a screen.
@greptile-apps

greptile-apps Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Adds test fixtures and readiness detection for three agent types.

The PR appears safe to merge; no outstanding finding or new actionable failure was established.

Summary

The PR reads Antigravity, Cline, and Prime Agent readiness from their live terminal screens, with a quiet period for panes that have an output clock.

  • Keeps the prior readiness checks when a screen-ruled agent’s grid is untrusted.
  • Adds recorded-screen replay tests for ready, busy, dialog, draft, resize, and restored-pane cases.
Diagram
%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Terminal wait] --> B{Trustworthy screen for this agent?}
  B -->|Yes| C{Empty composer visible?}
  C -->|No| D[Keep waiting]
  C -->|Yes, output clock| E{Quiet for 3 seconds?}
  E -->|No| D
  E -->|Yes| F[Ready]
  C -->|Yes, no output clock| F
  B -->|No| G[Use prior readiness checks]
Loading

Reviews (4) · Last reviewed commit: "refactor(runtime): keep screen-rule trus..."

Comment thread src/main/runtime/screen-ruled-agent-readiness.ts Outdated
Comment thread src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts Outdated

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one robustness note, one minor comment inline.

Reviewed changes

  • Screen readiness rules — new per-agent composer rules for Antigravity, Cline and Prime Agent, registered in one table (screen-ruled-agent-readiness.ts).
  • Screen tiering — tui-idle now consults the screen in tier 1/1b and shuts the name-only-title and quiet-process lanes whenever a trustworthy screen exists.
  • Trustworthy-grid gate — readLiveTerminalScreenLines returns raw rows and refuses a screen whose grid does not match the PTY's or was reflowed without a repaint.
  • Probe unification — the Antigravity-only probe branch is replaced by the shared rule; the probe's screen read restores the composer draft the projection blanked.
  • Recordings + replay suite — 30+ new PTY captures replayed by a shared suite, plus a harness switch to raw rows.

ℹ️ A trustworthy grid with an unrecognized layout now times out instead of settling

isReadinessDecidedByScreen shuts the name-only-title and quiet-process lanes for any screen-ruled pane with a trustworthy grid — including when the rule merely fails to match rather than positively identifying a dialog. The three rules encode specific versions (agy 1.2.14's ? for shortcuts hint, Cline 3.0.66's placeholders, Prime 0.9.5+'s ← manage footer). A future release, a localized build, or an unusual layout whose idle composer the rule does not recognize will now hold worker-start to its timeout, where the name-only title previously settled it. This is the deliberate safe-failure direction, but a timeout here is indistinguishable from a genuine hang; consider making it observable (a distinct outcome/reason or a log line) so version drift can be detected.

Technical details
# Screen authority over an unrecognized idle layout

## Affected sites
- `src/main/runtime/screen-ruled-agent-readiness.ts:28-33` — `isReadinessDecidedByScreen` returns true for any screen-ruled pane with a non-null grid.
- `src/main/runtime/tui-idle-evidence.ts:311-314` — the gate returns `pending`/`closed`, skipping `hasSustainedTitleIdle`.
- `src/main/runtime/{antigravity,cline,prime-agent}-terminal-readiness.ts` — the rules key on exact chrome from the captured versions.
- `docs/reference/antigravity-readiness-evidence.md`, `docs/reference/cline-and-prime-agent-readiness-evidence.md` — version-specific evidence; Prime 0.9.4 is already noted unsupported.

## Required outcome
- Decide whether a trustworthy grid that refuses should ever fall back to the weak lanes (e.g. after a longer bounded window), or whether a timeout with a trustworthy screen should surface a distinct reason so drift is visible.

## Open questions for the human
- Is the intended contract "screen authority, safe failure = timeout", accepting that an unrecognized layout on a supported version regresses to a timeout?

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Comment thread src/main/runtime/orca-runtime-start-tui-idle-visible-read-probe.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes (delta since the prior review at 26ed275)

  • Truncated STA-8741 recordings — cline-3-0-66-busy-streaming, prime-agent-0-9-8-busy-streaming, prime-agent-0-9-8-trace-question are cut at the first frame that shows the screen their tests need; the .meta.json notes record the original and truncated byte counts.
  • Serializer failure baselines — three KNOWN_PREEXISTING_I2_FAILURES counts updated to match the shorter fixtures.
  • Evidence doc — a new paragraph in cline-and-prime-agent-readiness-evidence.md explains why the Prime captures are large (no cell diffing; each synchronized frame rewrites touched rows) and why ready-after-question cannot be truncated.

No production code changed. I re-ran cline-screen-readiness-transcripts and prime-agent-screen-readiness-transcripts against 58cbe20: 91 tests pass, so the truncated fixtures still pin the same ready/busy verdicts and the spinner-presence preconditions still hold.

Pullfrog  | Fix it ➔ | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

readScreenRuledReady, readScreenRuledQuietReady and isReadinessDecidedByScreen
each re-derived the same thing: the agent's rule applied to a trustworthy live
screen. They collapse into readScreenRuledVerdict (true / false / null), which
tier 1, tier 1b and the lane gate read.

This also makes a refusal final in tier 1: a clockless pane whose trustworthy
screen refused fell through to the text rules, so retained ready text could
settle over an open picker (Greptile review). The quiet tier already refused
there; now both do.

The tier-1b agent set derives the screen-ruled agents from the rule table
instead of listing them again, and the lane test that repeated the census
case is dropped.
The probe's clock was captured at start and threaded through the wait
dependencies as a one-off parameter. The probe now reads it from the live
record when its screen read returns, which is also the fresher answer.
The reattach-reflow flag was never cleared, so a pane stayed on the old lanes
for the rest of its life even after a real resize made the TUI repaint
(Greptile review). The record now keeps the reflowed grid, and a PTY resize
off that grid clears it; an echo of the same size sends no SIGWINCH and keeps
it.

Tests: the reflow case in every screen-ruled suite now includes a same-size
echo, and an Antigravity recording only the screen reads ready settles after a
resize and repaint.
@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

📝 Walkthrough

Walkthrough

Added screen-based readiness rules for Antigravity, Cline, and Prime Agent and connected them to terminal-idle evaluation. Live-screen reads now reject mismatched or unrepainted terminal grids. Added transcript replay utilities, captured terminal fixtures, and tests for readiness states and idle waits. Updated readiness evidence documentation.

Fixed issue severity: Medium

Priority: ➖ Normal

Merge Risk: 🔵 Low · up to 70919

The readiness changes have no established blocking defect. Add the longer Cline streaming wait assertion to protect post-quiescence behavior; this is a bounded test-coverage improvement.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 70919

Existing blocking checks, quiet-period requirements, and screen-size safeguards limit exposure. No introduced permission bypass was established, but freshness during delayed screen updates and the complete downstream delivery path remain incompletely verified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated control effect is completion of an idle wait for the selected PTY or pane. The stated intent connects that result to task delivery, but the complete downstream delivery and authorization chain was not established. Broader tenant, datastore, environment, or privilege expansion is not supported by the inspected evidence.

Trust Boundaries and Controls

  • observed — Process-produced terminal content becomes readiness evidence through agent-selected, read-only predicates. The rules inspect bounded composer/footer patterns and busy indicators rather than granting execution permission. Antigravity's predicate distinguishes a bare or mode-labelled composer from arbitrary selected menu text.

Resilience and Maintainability Implications

  • inferred — The new predicates inherit an eventually updated synchronous screen view without a write-chain barrier or applied-sequence check. Output-clock gating mitigates ordinary update lag, and hydration gates exclude incomplete restored models. Whether a queued update can outlast quiescence and expose stale ready rows remains a proof gap; increased exploitability over the previous readiness paths was not established.

Hardening Proposals

  • proposed — Consider tying positive ruled-screen acceptance to an applied-output sequence or an equivalent settled-write condition. This would make freshness explicit rather than relying on the quiet interval to exceed emulator update lag.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR implements live-screen rules and replay coverage for Cline and Prime Agent, including ready, busy, draft, menu, permission, and working-state guards required by [#23268] and [#22153]. The Antig… Add a reviewable Windows Antigravity 1.1.17 fixture with the signed-in header, Gemini model line, and > Accept-edits mode: composer. Add an automated regression assertion that worker-start passes readiness and reaches dispatch_input.
Docstring Coverage ⚠️ Warning Docstring coverage is 45.16% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 31 functions across 23 files. (1 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Out of Scope Changes check ✅ Passed The runtime changes, screen-specific readiness rules, grid-trust handling, replay harness, fixtures, tests, and readiness documentation support the linked objectives [#15838], [#23268], and [#22153]. …
Title check ✅ Passed The title clearly and concisely describes the main runtime change: using live-screen readiness checks for Antigravity, Cline, and Prime Agent.
Description check ✅ Passed The description is complete and closely follows the required template. It explains the user impact, mechanism, rationale, linked issues, testing, limitations, compatibility considerations, and checkli…
Full details: Linked Issues check

Explanation

The PR implements live-screen rules and replay coverage for Cline and Prime Agent, including ready, busy, draft, menu, permission, and working-state guards required by [#23268] and [#22153]. The Antigravity matcher accepts a mode composer and the screen rule rejects busy and dialog fixtures. However, the reviewable Antigravity fixtures are for macOS agy 1.2.14, not the linked Windows CLI 1.1.17 &gt; Accept-edits mode: screen in [#15838]. The tests verify tui-idle, but they do not verify that worker-start reaches dispatch_input. The screen rule also checks only the bottom four rows, so the required header and Gemini-line evidence is not established by the Antigravity screen test.

Full details: Docstring Coverage

Explanation

Docstring coverage is 45.16% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 31 functions across 23 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: e8f96bac-0887-43fd-9840-0fad1452f4b8

📥 Commits

Reviewing files that changed from the base of the PR and between 7cae036 and 58cbe20.

📒 Files selected for processing (92)
  • .gitignore
  • docs/reference/agent-pty-transcript-capture.md
  • docs/reference/antigravity-readiness-evidence.md
  • docs/reference/cline-and-prime-agent-readiness-evidence.md
  • src/main/daemon/serialize-grid-transcript-replay.test.ts
  • src/main/runtime/__fixtures__/antigravity-1-2-14-busy-streaming.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-busy-streaming.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-busy-thinking.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-busy-thinking.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-command-palette.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-command-palette.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-draft.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-draft.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-model-picker.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-model-picker.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-picker-dismissed.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-picker-dismissed.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-80x24.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-80x24.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-accept-edits.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-accept-edits.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-plan.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready-plan.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-ready.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-trust-dialog.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-trust-dialog.txt
  • src/main/runtime/__fixtures__/antigravity-1-2-14-turn-ended.meta.json
  • src/main/runtime/__fixtures__/antigravity-1-2-14-turn-ended.txt
  • src/main/runtime/__fixtures__/cline-3-0-65-win32-startup.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-65-win32-startup.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-busy-streaming.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-busy-streaming.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-draft.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-draft.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-permission.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-permission.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-promo.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-promo.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-ready-80x24.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-ready-80x24.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-ready-plan.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-ready-plan.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-ready.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-ready.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-slash-menu.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-slash-menu.txt
  • src/main/runtime/__fixtures__/cline-3-0-66-turn-ended.meta.json
  • src/main/runtime/__fixtures__/cline-3-0-66-turn-ended.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-5-ready.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-5-ready.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-5-turn.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-5-turn.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-busy-streaming.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-busy-streaming.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-draft.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-draft.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready-80x24.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready-80x24.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready-after-question.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready-after-question.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-ready.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-slash-menu.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-slash-menu.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-tool-turn.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-tool-turn.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-trace-question.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-trace-question.txt
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-turn-ended.meta.json
  • src/main/runtime/__fixtures__/prime-agent-0-9-8-turn-ended.txt
  • src/main/runtime/agent-transcript-replay-test-harness.ts
  • src/main/runtime/antigravity-screen-readiness-transcripts.test.ts
  • src/main/runtime/antigravity-terminal-readiness.ts
  • src/main/runtime/cline-screen-readiness-transcripts.test.ts
  • src/main/runtime/cline-terminal-readiness.ts
  • src/main/runtime/codex-quiet-ready-screen.test.ts
  • src/main/runtime/cursor-approval-prompt-detection.ts
  • src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts
  • src/main/runtime/orca-runtime-runtime-id.ts
  • src/main/runtime/orca-runtime-start-tui-idle-visible-read-probe.ts
  • src/main/runtime/orca-runtime-terminal-projection.ts
  • src/main/runtime/orca-runtime-visible-snapshot-preview.ts
  • src/main/runtime/prime-agent-screen-readiness-transcripts.test.ts
  • src/main/runtime/prime-agent-terminal-readiness.ts
  • src/main/runtime/runtime-terminal-state-records.ts
  • src/main/runtime/runtime-terminal-wait.ts
  • src/main/runtime/screen-ruled-agent-readiness.ts
  • src/main/runtime/screen-ruled-agent-transcript-suite.ts
  • src/main/runtime/terminal-wait-detection.ts
  • src/main/runtime/tui-idle-evidence.test.ts
  • src/main/runtime/tui-idle-evidence.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.

Comment thread docs/reference/agent-pty-transcript-capture.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: e6347351-dd9a-4e42-827b-409763fd7271

📥 Commits

Reviewing files that changed from the base of the PR and between 58cbe20 and 3b507fa.

📒 Files selected for processing (12)
  • docs/reference/antigravity-readiness-evidence.md
  • src/main/runtime/antigravity-screen-readiness-transcripts.test.ts
  • src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts
  • src/main/runtime/orca-runtime-start-tui-idle-visible-read-probe.ts
  • src/main/runtime/orca-runtime-visible-snapshot-preview.ts
  • src/main/runtime/runtime-terminal-state-records.ts
  • src/main/runtime/runtime-terminal-wait.ts
  • src/main/runtime/screen-ruled-agent-readiness.ts
  • src/main/runtime/screen-ruled-agent-transcript-suite.ts
  • src/main/runtime/terminal-wait-detection.ts
  • src/main/runtime/tui-idle-evidence.test.ts
  • src/main/runtime/tui-idle-evidence.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/reference/antigravity-readiness-evidence.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

Comment on lines +164 to +165
if (unpainted && (unpainted.cols !== cols || unpainted.rows !== rows)) {
state.unrepaintedReflowGrid = undefined

@coderabbitai coderabbitai Bot Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🔎 Supported by static analysis

🏁 Script executed:

# Inspect resize, output processing, and emulator ordering without running repository code.
ast-grep outline src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts \
  --items all --match 'resizeHeadlessTerminal|reflowHeadlessTerminalToPtyGrid'
ast-grep outline src/main/daemon/headless-emulator.ts \
  --items all --match 'resize|getAppliedSize|getVisibleLines'
rg -n -C8 --glob '*.ts' \
  'onExternalPtyResize\s*\(|onPtyData\s*\(|unrepaintedReflowGrid' src/main

Repository: stablyai/orca

Length of output: 45658


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- focused diff ---'
git diff --unified=35 ed462b2caa5e280d6a56b2f9c6fed1b2bc2f86db 3b507fa49a3e1d68c9c9ff3cac12a7058cc7d1ac -- src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts

printf '%s\n' '--- changed file range ---'
cat -n src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts | sed -n '1,260p'

printf '%s\n' '--- relevant symbol locations ---'
rg -n -C12 --glob '*.ts' 'unrepaintedReflowGrid|onExternalPtyResize|reflowHeadlessTerminalToPtyGrid|resizeHeadlessTerminal|onPtyData|writeChain|tui-idle|tuiIdle|waitForTerminal' src/main/runtime src/main/daemon src/main/ipc/pty

printf '%s\n' '--- emulator files ---'
fd -i 'headless-emulator' src/main
fd -i 'headless-terminal' src/main

Repository: stablyai/orca

Length of output: 45650


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- marker consumers ---'
rg -n -C10 --glob '*.ts' 'unrepaintedReflowGrid' src/main

printf '%s\n' '--- resize entrypoints ---'
rg -n -C14 --glob '*.ts' 'onExternalPtyResize\s*\(' src/main

printf '%s\n' '--- emulator size and resize ---'
rg -n -C12 --glob '*.ts' 'getAppliedSize\s*\(|resize\s*\(' src/main/daemon/headless-emulator.ts

printf '%s\n' '--- readiness symbols ---'
rg -n -C16 --glob '*.ts' 'tui-idle|tuiIdle|waitForTerminal|waitForHeadless|readHeadless|serializeHeadless' src/main/runtime src/main/daemon

printf '%s\n' '--- terminal state type ---'
rg -n -C16 --glob '*.ts' 'type RuntimeHeadlessTerminal|interface RuntimeHeadlessTerminal|unrepaintedReflowGrid' src/main/runtime/runtime-terminal-state-records.ts

Repository: stablyai/orca

Length of output: 45662


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- visible snapshot preview ---'
cat -n src/main/runtime/orca-runtime-visible-snapshot-preview.ts | sed -n '130,230p'

printf '%s\n' '--- wait/readiness references ---'
rg -n 'readLiveTerminalScreenLines|condition.*tui-idle|tui-idle.*condition|case.*tui-idle|screen.*idle|isTuiIdle' src/main/runtime --glob '*.ts'

printf '%s\n' '--- headless emulator method locations ---'
rg -n 'getAppliedSize|^[[:space:]]*(public |private |protected )?resize[[:space:]]*\(' src/main/daemon/headless-emulator.ts

printf '%s\n' '--- headless emulator methods ---'
line=$(rg -n 'getAppliedSize|^[[:space:]]*(public |private |protected )?resize[[:space:]]*\(' src/main/daemon/headless-emulator.ts | head -n1 | cut -d: -f1)
if [ -n "$line" ]; then
  start=$((line-25))
  [ "$start" -lt 1 ] && start=1
  end=$((line+90))
  sed -n "${start},${end}p" src/main/daemon/headless-emulator.ts
fi

Repository: stablyai/orca

Length of output: 32956


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- terminal wait evaluator ---'
cat -n src/main/runtime/runtime-terminal-wait.ts | sed -n '1,245p'

printf '%s\n' '--- tui-idle evidence evaluator ---'
cat -n src/main/runtime/tui-idle-evidence.ts | sed -n '250,345p'

printf '%s\n' '--- runtime resize definitions ---'
rg -n -C12 'onExternalPtyResize' src/main/runtime --glob '*.ts'

Repository: stablyai/orca

Length of output: 42673


🏁 Script executed:

#!/bin/bash
set -e
printf '%s\n' '--- quiet-screen evidence and PTY evidence ---'
rg -n 'function hasQuietReadyScreen|const hasQuietReadyScreen|hasQuietReadyScreen|readQuietReadyBodyEvidence|readScreenDecidesReadiness|function ptyTuiIdleEvidence|export function ptyTuiIdleEvidence' src/main/runtime/tui-idle-evidence.ts
cat -n src/main/runtime/tui-idle-evidence.ts | sed -n '1,255p'
cat -n src/main/runtime/tui-idle-evidence.ts | sed -n '338,470p'

Repository: stablyai/orca

Length of output: 16904


Preserve repaint gating across resize round trips.

resizeHeadlessTerminal clears the marker before queuing emulator.resize. After a resize away and back, the dimensions can match again before repaint output arrives. readLiveTerminalScreenLines can then expose stale cells, and tui-idle can accept the stale composer after the output clock exceeds the quiescence interval. Keep the marker, or an equivalent barrier, until the resize-triggered repaint is applied.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The window exists but cannot produce a wrong "ready":

  • A working agent is printing output, which restarts the 3 s quiet requirement before stale cells can be accepted, and the SIGWINCH repaint replaces them within milliseconds.
  • A clockless pane (no output since attach) was already at rest, so its stale cells show the same prompt.

Closing the window would take another barrier state for a transient that every resize already has, including for the existing Codex screen rule. Leaving as is.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Jinwoo-H, understood. Thanks for the guidance. You accept the resize transient with the existing three-second quiescence check and SIGWINCH repaint behavior. I won’t press for an additional repaint barrier.


✏️ Learnings added
Learnt from: Jinwoo-H
Repo: stablyai/orca PR: 24222
File: src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts:164-165
Timestamp: 2026-09-30T23:59:32.385Z
Learning: In the TypeScript terminal-readiness runtime, maintainers accept the transient stale-screen window when `resizeHeadlessTerminal` in `src/main/runtime/orca-runtime-create-pty-headless-terminal-state.ts` clears `unrepaintedReflowGrid` after a PTY resize. The stated rationale is the existing three-second output-quiescence check and SIGWINCH repaint behavior. The existing Codex screen rule also has a resize transient. Do not recommend an additional repaint barrier solely because this window exists; establish a concrete incorrect-readiness case.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes (delta since the prior review at 58cbe20)

  • One screen verdict. readScreenRuledReady, readScreenRuledQuietReady and isReadinessDecidedByScreen collapse into readScreenRuledVerdict (true/false/null), so tier 1, tier 1b and the weak-lane gate read the same answer.
  • A refusal is now final in tier 1. isKnownReadyPromptBody returns screenVerdict && !hasOutputClock, so a clockless pane on a trustworthy screen that refused no longer falls through to the folded text rule — retained ready text can no longer settle over an open picker.
  • Probe reads its own clock. startVisibleReadProbe drops the hasOutputClock parameter and reads lastOutputAt from the live record when its screen read returns.
  • Reflow flag can be cleared. reflowedWithoutRepaint: boolean becomes unrepaintedReflowGrid?: { cols, rows }, set by reflowHeadlessTerminalToPtyGrid and cleared in resizeHeadlessTerminal when a genuine PTY resize arrives off that grid; an echo of the same size keeps it.
  • Tests. The shared reflow case now sends a same-size resize echo, and a new Antigravity recording that only the screen reads ready proves a resize-plus-repaint restores screen authority.

I re-ran antigravity-screen-readiness-transcripts (59 pass, including the new reflow-repaint test) and tui-idle-evidence (69 pass) at 3b507fa.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

…d agents

Two shared changes reached agents this PR does not target: the live
screen reader returned raw rows, and it refused a grid that did not
match the PTY. Both now live in readScreenRuledLines, which only the
screen-ruled agents read (screenReader picks it from the rule table);
readLiveTerminalScreenLines is main's again. The probe keeps main's
Antigravity-banner trigger, so a Codex or unknown pane is probed exactly
as before.

Proof: the non-screen-ruled suites give identical pass sets on this
branch and its base (1,781 tests), and replaying every other recording
frame by frame through the readiness and blocked verdicts, for its
agent and for an unknown pane, gives identical results (93 pairs). A new
test keeps a Codex pane reading its screen when the PTY reports another
grid; it fails if the trust check moves back into the shared reader.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/main/runtime/cline-screen-readiness-transcripts.test.ts (1)

77-90: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert that the streaming screen becomes ready after quiescence.

The current wait ends at 2.5 seconds, but Cline screen readiness requires three seconds of quiescence. The test therefore passes both when the screen correctly becomes ready after quiescence and when it never becomes ready. No other runtime test includes the STREAMING fixture.

Keep the early-timeout assertion and add a second wait with a longer timeout:

Suggested fix
     await expect(
       runtime.waitForTerminal(handle, { condition: 'tui-idle', timeoutMs: 2_500 })
     ).rejects.toThrow(/timeout/)
+    await expect(
+      runtime.waitForTerminal(handle, { condition: 'tui-idle', timeoutMs: 8_000 })
+    ).resolves.toMatchObject({ condition: 'tui-idle', satisfied: true })

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 59638e1d-21a6-455f-a421-177db1d68ff7

📥 Commits

Reviewing files that changed from the base of the PR and between 3b507fa and 709195b.

📒 Files selected for processing (12)
  • docs/reference/cline-and-prime-agent-readiness-evidence.md
  • src/main/runtime/agent-transcript-replay-test-harness.ts
  • src/main/runtime/antigravity-screen-readiness-transcripts.test.ts
  • src/main/runtime/antigravity-terminal-readiness.ts
  • src/main/runtime/cline-screen-readiness-transcripts.test.ts
  • src/main/runtime/orca-runtime-runtime-id.ts
  • src/main/runtime/orca-runtime-visible-snapshot-preview.ts
  • src/main/runtime/prime-agent-screen-readiness-transcripts.test.ts
  • src/main/runtime/runtime-terminal-wait.ts
  • src/main/runtime/screen-ruled-agent-transcript-suite.ts
  • src/main/runtime/screen-ruled-readiness-scope.test.ts
  • src/main/runtime/tui-idle-evidence.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/reference/cline-and-prime-agent-readiness-evidence.md

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes (delta since the prior review at 3b507fa)

  • Screen-rule trust and raw rows scoped to screen-ruled agents. readLiveTerminalScreenLines goes back to the read projection with only the whole-screen-model check (exactly main, so Codex/Qoder are unaffected), and a new readScreenRuledLines owns the raw rows plus the PTY-grid and unrepainted-reflow gates. This fixes the regression where the grid gate and raw rows applied to every agent.
  • Per-agent reader selection. tui-idle-evidence.ts adds readScreenRuledLines? to TuiIdleEvidenceSource and a screenReader helper; tier 1, tier 1b and the weak-lane gate now read the grid-gated raw rows for a screen-ruled agent and the projection for everyone else. orca-runtime-runtime-id.ts wires the new provider.
  • Antigravity probe trigger restored. hasAntigravityTerminalHeader returns and shouldProbeVisibleScreen probes a pane whose tail shows the antigravity cli banner, alongside the existing empty-text and clockless screen-ruled cases.
  • Regression test. screen-ruled-readiness-scope.test.ts asserts a Codex pane still settles from its screen when the PTY reports a grid the pane did not paint; it fails under the previous commit's readLiveTerminalScreenLines grid gate.
  • Harness/tests. The replay harness now yields both screenLines (projection) and ruledScreenLines (raw rows); the screen-ruled suites read ruledScreenLines, the Codex suites keep screenLines, matching each agent's production reader.

I re-ran screen-ruled-readiness-scope (1), tui-idle-evidence (69), the three screen-readiness transcript suites (150), and codex-quiet-ready-screen (53) at 709195b: all pass.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant