Repository navigation
fix(chat): feedback typed on Claude Code's plan card keeps Claude planning - #2518
Conversation
…nning The card typed the words into "Tell Claude what to change" and then sent Shift+Tab. Claude Code labels Shift+Tab on that row "approve with this feedback", so the plan was approved and ran. Send Enter instead, as every other responder does and as Claude's own terminal does: Claude takes the feedback and redraws the plan. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HabHntUPvy5yA9iU3G1m5y
|
No actionable comments were generated in the recent review.
|
| Layer / File(s) | Summary |
|---|---|
Submit custom plan feedback server/prompt.ts, server/prompt.test.ts, changelog.d/claude-plan-feedback-keeps-planning.md |
answerKeys now sends Enter after custom text for Claude plan prompts. The test expects Enter, and the changelog describes how this lets feedback go to Claude while planning continues. |
Estimated code review effort: 2 (Simple) | ~8 minutes
Change: Bug fix · Severity of issue fixed: Medium
Suggested reviewers: devswha
Merge Risk: 
Minimal · up to badd3
-
No actionable merge-blocking risk was identified in this change.
Pre-merge checks: 
4 · 
1
-
Failed checks: 1 warning Passed checks: 4 passed-
Full details: Linked Issues check
-
Explanation
Issue
#2517requires typed feedback on Claude Code's plan card to reach Claude and keep planning.server/prompt.tsnow sendsenterafter custom text forclaude-plan, instead ofshift+tab.server/prompt.test.tsverifies the new key sequence. The changelog records the behavior. The separate approval action remains excluded as required.
-
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 with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 1 functions across 2 files. (1 skipped: 1 unsupported.)
Resolution
Write docstrings for the functions missing them to satisfy the coverage threshold.
-
Finishing Touches
-
Generate unit tests (beta)
-
- 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.
|
Merging badd3d9 (fixes #2517, reported and fixed by @jpcarranza94): text typed into the "Tell Claude what to change" field of Claude Code's plan card is now followed by Enter, which sends it as feedback and keeps Claude planning; Shift+Tab approved the plan with the feedback and ran it. Strict review by the merge pass (Claude reviewer + Terra 6.1). The parser finds the feedback row by its label, refuses a missing row or empty text before any key, and types only once the cursor is on that row, so Enter cannot confirm a highlighted approve option. prompt 404/404 and dialogs/claude 52/52; the changed test fails on main. Confirmed live with Claude Code 2.1.312 in an isolated pseudo-terminal: "User rejected Claude's plan", Claude stayed in plan mode and redrew the plan with the feedback. LOW: nothing re-reads the screen between the typed text and Enter (already true with Shift+Tab; Enter is the safer key, and #2508 narrows this race for all keys); the end-to-end answer test has no typed-feedback case for the plan card; Enter on that row is measured on 2.1.312 and 2.1.316, with no recordings of older Claude Code versions. CodeRabbit reviewed it with no blocking comments. |
… and read it when the pane turns blocked (#2543) <!-- See CONTRIBUTING.md for checks, translations, contract tests and the changelog (a file in changelog.d/, never CHANGELOG.md). --> ## Change Fixes #2542. The question or approval card now stays in Chat while the agent waits for it, and shows as soon as herdr says the pane is blocked. Until now, the card went for 250–600 ms back from the Terminal view and across a reconnect. It also came up to 2 s after the turn said "Needs you". The composer said "Message Claude…" in each gap. All three are in the prompt poll of `src/components/ChatView.tsx` (+16/−4 lines): - **Back from the Terminal view.** A module map `lastPrompts` keeps the last prompt each pane's chat read, by `paneStorageId`, as the conversation cache does for turns. Each read sets or deletes it. The mount's layout effect draws it before paint, but only while herdr still says the pane is blocked. A card answered in the terminal (herdr now says working) is not drawn again. The first read checks the card. An answer to a stale card is refused with 409 `prompt_changed`, as before. - **Across a reconnect.** The poll effect clears the card only when the pane ends or loses its agent (`promptGone`). While the socket is down, it only stops the poll. A failed read already keeps the card (#1335), and a dropped socket tells no more about the screen. The first read after the reconnect checks the card. - **When the pane turns blocked.** `agentStatus === "blocked"` joins the poll effect's deps. The card is read at once when the pane turns blocked, and again when it stops being blocked. The second read takes away a card answered in the terminal at once, not at the next poll. - The server still decides which card a read gets. The read at the blocked edge brings back no fallback card that #2521 removed. A Claude pane whose screen still ends in Claude's input box gets no card, and a pane that is no longer blocked gets no fallback card. - `scripts/prompt-card-timing-demo-regression.ts` is new, and `scripts/ci-browser.sh` runs it after the prompt-dock regression. It runs the built app over the demo's fixture transport, with the "web" pane's approval open and a prompt read of 150 ms. It samples every painted frame and checks four things: - Back from the Terminal view, the composer is never drawn without the card. - Across a socket close and reconnect, the same. - The approval answered in the Terminal view (no prompt, herdr says working) is not drawn back in Chat. - The card shows, and goes, in less than half a poll after herdr's status changes. Each change is made right after a prompt read, so the next poll is about 2 s away. - `docs/development.md`: the prompt polling note now says a blocked edge reads the prompt at once. - The behaviour follows Claude Code's own terminal and the Claude app. A pending permission or question stays on screen until it is answered, through a view change or a reconnect. It shows together with the wait, not after it. - Limits: - A read at the blocked edge that comes before Claude draws its panel gets no card. The card then waits for the next poll, as on `main`. In my live run with the fix, every card came within 193 ms of blocked. - While the socket is down, the kept card shows no "Not updated" notice, because no read fails. - The cache holds only prompts of panes that were blocked. It has no size limit. It is drawn only for a blocked pane, and its first read replaces it. - This PR changes `src/components/ChatView.tsx` away from the lines of open #2538 (its comment near the follow effect and the removed `dropPendingListScroll` above `TRANSCRIPT_LINES`). They do not overlap. - Changelog fragment: `changelog.d/chat-prompt-card-timing.md`. ## Validation - `scripts/prompt-card-timing-demo-regression.ts`, red on `main` (a88b750), with the same script copied in: - Back from the Terminal view: the composer without the card for 317 ms. - Across a reconnect: 603 ms. - Answered in the terminal: 0 ms (no stale card on `main` either). - The card shown 2106 ms after herdr said blocked, and gone 2247 ms after it said working. - It fails on the first check: `back from the Terminal lens, 317 ms the composer was drawn without the open approval's card`. - The same script on this branch: 4 runs, 4 PASS (3 on a88b750, 1 after the rebase on c4cc67d). 0 ms, 0 ms and 0 ms. The card shown 234–398 ms after blocked and gone 208–404 ms after working. The poll is 2000 ms. - Guard check: with the cache drawn whatever herdr's status (My earlier first draft), the script fails on `answered in the terminal, the old card was drawn 75 ms back in Chat`. - `scripts/prompt-dock-demo-regression.ts`: 37 PASS on `main` and 37 PASS on this branch, the same lines. - `server/prompt.test.ts` and `server/dialogs/claude.test.ts`: 450 pass, 14 skip, 0 fail on `main` and on this branch (81.0 s and 81.5 s). - Through `bun run check run` (an isolated herdr session): `server/prompt.contract.test.ts`, `omo-prompt.contract`, `omp.contract`, `opencode-prompt.contract` and `opencode-answer.test.ts`: 73 pass, 1 skip, 0 fail on `main` and on this branch. - `src/components/PromptCard.test.ts`, `PromptCard.test.tsx`, `src/lib/promptAnswer.test.ts`, `promptText.test.ts`, the tests that import ChatView (`ChatFallback`, `ChatTurn`, `greeting`, `sentWaiting`, `i18n`, `userMessageFold`), the three `conventions.test.ts` files and `scripts/changelog-fold.test.ts`: 228 pass, 0 fail on `main` and on this branch. - `scripts/ci-browser.test.ts`, "browser lane assignment": 4 pass. - `bun run typecheck`: pass. - Live, from my test runs (Claude Code 2.1.316, an isolated herdr session, headless Chromium at 1280×800): - Before (feb3ae0): back from the Terminal view, the card came 256 ms after the chat, with the first prompt read (244 ms). Over four runs, 10 cards came 137–1884 ms after herdr said blocked. - After, with this fix and My earlier other Chat fixes applied together (the server parts are now #2518 and #2521): three Bash approvals showed their card 20, 26 and 114 ms after blocked, and a plan 87 ms after. - I did not repeat the live run with this branch alone. - Not run: `bun run check fast`. On this Mac it hangs on `server/usage-login-private`. These files also fail on `main` here: `scripts/check`, `scripts/self-hosted-runner`, `scripts/install-star`, `scripts/ci-browser`, `scripts/ci-browser-parallel`, `server/codex`, `server/codex-processes`, `server/session-history`, `server/letta`, `server/remote-entry`, `server/core/composer-framing`, `server/usage-login-private`, and sometimes `server/bridge`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01HabHntUPvy5yA9iU3G1m5y --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Change
Fixes #2517.
Words typed in the "Tell Claude what to change" field of Claude Code's plan card ("Ready to code?") now reach Claude as feedback, and Claude keeps planning. Until now the card typed the words and then sent Shift+Tab. Claude Code labels Shift+Tab on that row "approve with this feedback", so the plan was approved and ran, in auto mode, with no permission prompt.
server/prompt.ts:answerKeyssends Enter after the typed words forclaude-plan, as for every other responder. The special case for Shift+Tab is gone.server/prompt.test.ts: the plan test now expects{ keys: ["enter"] }after the words, notshift+tab.changelog.d/claude-plan-feedback-keeps-planning.md.Validation
bun test server/prompt.test.ts -t "Claude".main'sserver/prompt.ts: 125 pass, 1 fail. "parses Claude questions, approvals, and plans" expectsenterand getsshift+tab.bun test server/prompt.test.ts: 390 pass, 14 skip, 0 fail.bun test server/dialogs/claude.test.ts: 52 pass, 0 fail.CHECK_MAX_RUNS=6 CHECK_WAIT_SECONDS=2400 bun run check run bun test --timeout 15000 ./server/prompt.contract.test.ts, on an isolated herdr session: 13 pass, 0 fail. This file draws no plan dialog. It shows that the answer route still works.bun test server/conventions.test.ts: 12 pass.bun test scripts/changelog-fold.test.ts: 12 pass.bun run typecheckpasses.server/prompt.tsandserver/dialogs/are the same onmain(8d28829).bun run check fastandfull, andbun run build.server/usage-login-privatehangs on this Mac onmaintoo. These files also fail onmainon this Mac, so I did not run them:scripts/check,scripts/self-hosted-runner,scripts/install-star,scripts/ci-browser,scripts/ci-browser-parallel,server/codex,server/codex-processes,server/session-history,server/letta,server/remote-entry,server/core/composer-framing,server/usage-login-private, and sometimesserver/bridge.🤖 Generated with Claude Code
https://claude.ai/code/session_01HabHntUPvy5yA9iU3G1m5y