Repository navigation
fix(chat): hold a send over a screen the agent opened outside a peek - #1787
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Summary
Merge Risk: ⚪ Minimal · up to
|
| Check name | Status | Explanation |
|---|---|---|
| Title check | The title clearly and concisely describes the primary change: preventing Chat from sending messages while an agent-owned screen remains open outside a peek. | |
| Description check | The description includes the required Change and Validation sections. It explains the problem, resulting behavior, linked issue, implementation scope, regression coverage, test results, and known vali… | |
| Linked Issues check | Issue #1552 asks that Chat not type a send into an agent overlay it cannot read (Codex transcript search, Claude /config). It asks for an honest held state that keeps the draft.Implementation at hea… |
|
| Out of Scope Changes check | Changed files between merge base 28c7c8b and head 362c4bb: - src/lib/usePeekReturn.ts: the core inferred-guard logic for #1552.- src/lib/usePeekReturn.hook.test.ts: unit tests for that logic. - scr… |
Full details: Description check
-
Explanation
The description includes the required Change and Validation sections. It explains the problem, resulting behavior, linked issue, implementation scope, regression coverage, test results, and known validation limits.
Full details: Linked Issues check
-
Explanation
Issue
#1552asks that Chat not type a send into an agent overlay it cannot read (Codex transcript search, Claude /config). It asks for an honest held state that keeps the draft.Implementation at head (src/lib/usePeekReturn.ts):
- New noteRow path infers a still-open screen from whole frames. It arms only when the agent is in SCREEN_OVER_ROW (claude, codex), the recognizer read this pane's empty row before ('ready'), the chat is mounted, no peek or guard is up, and the agent is not working or blocked.
- It raises the existing StillOpen guard with named:false. The composer then refuses the send and keeps the draft, using the existing unnamed still-open note.
- The guard clears on the first frame that shows the row again. A turn of the agent drops an inferred guard.
- Show terminal opens the Terminal lens when command is empty.
The recognizer that reads missing or covered rows is existing code (src/lib/inputRow.ts, from merged
#1637). The PR relies on it for the Codex and Claude overlay readings.Tests:
- src/lib/usePeekReturn.hook.test.ts drives the real hook with per-frame recognizer answers. It covers Claude 'gone' and Codex 'covered' arming, pi 'gone' not arming, no arming without a prior 'ready' or while 'blocked', dismissal and re-arming, and turn reset.
- scripts/terminal-autoswitch-demo-regression.ts adds a browser case at 1280 and 390 px that asserts the draft is kept and nothing is submitted.
Deviations, which do not change the requirement:
- The issue suggests the 'Not sent: ... answer it first' wording. The PR reuses the existing unnamed still-open notice text ('A screen is still open in the terminal' and 'Not sent: a screen is still open in the terminal.').
- Coverage is limited to Claude and Codex. The issue's 'or, generally' option is not implemented. The PR states the limit is deliberate, because other recognizers answer 'gone' for unknown layouts.
Residual uncertainty: the hook tests supply recognizer answers directly. Live Codex 0.163.0 transcript search and Claude Code /config were not driven. This review did not inspect inputRow.ts, so the real overlay readings are taken from the PR's stated evidence.
Full details: Out of Scope Changes check
-
Explanation
Changed files between merge base 28c7c8b and head 362c4bb:
- src/lib/usePeekReturn.ts: the core inferred-guard logic for
#1552. - src/lib/usePeekReturn.hook.test.ts: unit tests for that logic.
- scripts/terminal-autoswitch-demo-regression.ts: browser case for the same behavior.
- DESIGN.md and docs/agent-commands.md: one sentence each documenting the behavior.
- changelog.d/chat-holds-send-over-open-screen.md: changelog entry for the fix.
Each change supports the
#1552objective. The PR states it does not touch PaneTerminal.tsx, App.tsx, i18n, server/, or shared/. The reviewed summary is consistent with that. No change was found that is unrelated to the guard. The PR description's test count (6268) differs from the objectives text (6265). This does not affect scope. - src/lib/usePeekReturn.ts: the core inferred-guard logic for
Full details: Docstring Coverage
-
Explanation
Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 3 files. (3 skipped: 3 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
✨ Finishing Touches: 💡 1
-
📝 Generate docstrings: 💡
-
- Commit to this branch
- Create a new PR
🧪 Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
-
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
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.
Comment @coderabbitai help to get the list of available commands.
|
Merge pass: this changes when a typed Chat message is held or sent, so this comment records the review, as for queued input. Gate review (reviewer on a different model than the author's):
The reviewer's one blocker, overruled by the merge pass with reasons. Back in the chat by its lens, the new effect (
Follow-up nit: add the Not verified: live Codex search, Claude All required checks are green and no review thread is open. |
Change
Fixes #1552. While Codex's transcript search or Claude Code's
/configcovered the agent's input row in the terminal, a Chat message was typed into that screen's search box and shown as accepted, so it was silently lost.#1637 (merged after the report) added the input-row recognizers and a "still open" guard that holds Chat's Send. That guard only arms when a terminal peek is ended by hand. A screen opened any other way never armed it: from the terminal itself, or a peek's screen kept with Keep Terminal and then the header's Chat. So #1637 does not cover this.
src/lib/usePeekReturn.tsnow also infers the guard from whole frames and when the chat comes back by its lens. It reuses the existing unnamed notice, A screen is still open in the terminal, and the note Not sent: a screen is still open in the terminal. with Send anyway, so no new strings. It arms only when all of these hold:SCREEN_OVER_ROW). Their recognizers read a missing or covered row at rest as a screen over it. Other recognizers answergonefor layouts they simply don't know (pi's extra footer rows), which is no proof a message would be lost.ready), so an unknown variant never gets the notice.workingorblocked).screenHeldRef, set bysetStillOpenand so also by the existing peek path): once per screen. A dismissal holds until a frame shows the row again, and frames are still read under the Terminal lens while it holds, so a screen that closed there ends the episode. A turn of the agent drops the inferred guard and ends the episode unless a peek's guard still stands.The notice clears on the first whole frame that shows the row again, as before. For this unnamed screen, Show terminal opens the Terminal lens rather than a peek, because no command of the chat's opened the screen. Frames are read outside a peek only while the agent is not working, and once the row is known, only while the chat is mounted. Nothing is typed to close anything.
No changes to
PaneTerminal.tsx,App.tsx, i18n,server/orshared/. DESIGN.md anddocs/agent-commands.mdeach get one sentence.Design precedent: the same as the still-open guard's DESIGN.md paragraph, where this sentence lives. It follows the composer's refusal of a Claude box that may not be empty and t3code's composer banner stack. Warp and Zed give an interactive program the input until it exits, which this bridge can only see on the screen.
Validation
scripts/terminal-autoswitch-demo-regression.tsat 1280 and 390 px, using the demo's Claude pane./btw's screen through a peek, Keep Terminal, then the header's Chat.src/lib/usePeekReturn.hook.test.ts(react-test-renderer, real hook, recognizer answer set per frame).goneand Codexcoveredarm the guard.gonedoes not; nothing arms without a priorreadyor whileblocked.scripts/command-outcome-demo-regression.tspasses (23 PASS).bun run check fastpasses: workflow syntax, generated types and themes, typecheck, build, and 6268 unit tests with 0 failures./configwere not driven in this run. Their recognizers'gone/coveredreadings come from feat(chat): return the terminal peek to Chat from each agent's input row, and hold sends while a screen is open #1637's recorded screens.