cx-ncc.103: agent pane recap card when a turn ends on a question (Debug toggle)
Recut of #20867 onto the current feat-cmux-next. That branch was 1,200 commits behind and carried 44 commits. This PR is two: the #20953 recut and one recap commit (2ebd864814c, 10 files, +1373/−9). The recap card, its strings and its tests are unchanged. The transcript-end fix (THREAD_TOP) has meanwhile landed on the base, and its Reduce Motion follow rule moved to #21955. The catalog adds only the recap.* keys; strings.json is regenerated (gen-strings.mjs --check passes). Locally, bun run typecheck and test/recap-card.test.ts (10 pass) are clean. The browser test agent-pane-recap-card.test.ts didn't finish on this machine (browser lane timeout), so CI is its run.
cx-ncc.103. When a finished turn ends on a question, a recap card appears above the composer. It shows the answer's last paragraph (muted, at most three lines), the question, a default action on ⌘↩ ("Yes, open PR" when the question names one, otherwise "Yes"), and "Not now". This is part (2) of the in-session status parity work with Claude Code desktop (part 1, the plan card, is #20833).
- Debug toggle: it shows only with the Debug Settings toggle "In-session status (plan card, recap card)" on (
agent.sessionStatus, off by default). With it off, the pane is unchanged. No Labs gating. - Depends on #20953 (cx-ncc.104), which adds the toggle, its
sessionStatuspage event anduseSessionStatus(). Until #20953 lands, this PR also carries its commit (5db0eba12b9). After #20953 squash-merges, only the recap commit is left. - Harness-agnostic: it reads the transcript rows, not any one harness's events.
- Yes: sends the reply as a normal prompt. ⌘↩ triggers it while the composer is empty.
- Not now and ×: dismiss the card for that question. The choice is remembered per session.
- Hidden: while the agent works, or while a permission, trust or folder ask is up.
- Strings: new
recap.*strings in all 21 locales.
Transcript fix (all users, not only with the toggle on): the card made a transcript bug visible. A followed transcript stopped 16 px short of its last row, because the layout's total height left out the thread's top padding. The layout now counts the padding. (The Reduce Motion spacer fix is in #21955.) Any chat that overflows had this cut; an assistant row's bottom padding usually hid it.
Captures
Gallery renders of the real pane (760×560, reduced motion). A real-app capture and clip from a DEV build follow in a comment.
| Toggle on, dark | Toggle on, light |
|---|---|
![]() | ![]() |
| Without the transcript fix: the card covers the footer | Toggle off: unchanged |
|---|---|
![]() | ![]() |
Testing
bun test test/recap-card.test.ts(10 pass) andtest/gallery-coverage.test.tspass on sbx;bunx vp checkis clean.- Browser test
CMUX_BROWSER_TESTS=1 bun test test/agent-pane-recap-card.test.ts:- red at 93225a4a7aea: the new footer test fails with
below: 16; - green at head: 5 pass (the card is turned on via
cmuxAcpmuxBridge.applySessionStatus(true)).
- red at 93225a4a7aea: the new footer test fails with
- The transcript jsdom tests (42) and the browser tests for follow-live, chat-column, bottom-stack, reading-place, soft-edges, history-paging and transcript-follow pass.
Changelog
- Added: Debug toggle: a recap card offers a finished turn's question with a ⌘↩ default reply.
- Fixed: the agent transcript now scrolls fully to its last row instead of stopping 16 px short.
🤖 Generated with Claude Code
🤖 Generated with Claude Code
Need help on this PR? Tag @codesmith-bot with what you need.
Summary by cubic
Shows a recap card above the composer when a finished turn ends on a question, behind the agent.sessionStatus Debug toggle (off by default). The card shows the answer's last paragraph (muted, at most three lines), the question, and a default yes on click or ⌘↩ on the empty composer ("Yes, open PR" when the question names a short action, otherwise "Yes"), plus "Not now". It reads the transcript rows rather than any harness's events, stays hidden while the agent works or a permission, trust, or folder ask is up, and only shows when the composer can send. Yes sends the reply as a normal prompt; Not now and × hide the card for that turn, remembered per session. New recap.* strings land in all 21 locales.
- With the toggle off, the pane is unchanged.
- ⌘Return answers the card only in the markdown composer; in shell mode it does nothing, and the card drops its ⌘Return keycap.
- If the yes fails to send, the card comes back with a "Your reply wasn't sent" note (role=alert), cleared on the next try.
- The transcript-end fix is already on the base; the Reduce Motion spacer fix moved to #21955.
bun run typecheckandtest/recap-card.test.ts(10 pass) are clean; the browser test did not finish on this machine.



