Skip to content

fix(cli): do not repaint the prompt after a keypress quits the session - #43

Merged
TaewoooPark merged 2 commits into
TaewoooPark:mainfrom
nimbly1:fix/issue-32-no-repaint-after-quit
Oct 17, 2026
Merged

TaewoooPark merged 2 commits into
TaewoooPark:mainfrom
nimbly1:fix/issue-32-no-repaint-after-quit

Conversation

@nimbly1

@nimbly1 nimbly1 commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Fixes #32

Ctrl-D at an empty prompt (and the second Ctrl-C of a double Ctrl-C) exits with code 0, but the live input box and the shortcut hint were painted again after the terminal had been cleaned up, so they stayed on screen as if the prompt were still interactive.

Chat.onKey() ends with an unconditional this.refresh(). For a quit keypress, onControl() has already run quit() -> finish() -> Screen.finish(), which clears the composer and footer and restores the cursor. The refresh then calls setHint/setComposer and paints the box again. This follows the starting point in the issue.

The change is one line: if (!this.quitting) this.refresh();, the same guard the other refresh call sites in chat.ts already use. Ctrl-D in a non-empty draft (delete forward) and Ctrl-C while a task runs do not quit, so they still refresh as before.

Tests

Two tests in packages/cli/test/chat.test.ts, using the existing in-process session() harness: Ctrl-D at an empty prompt, and a second Ctrl-C after the first one armed the quit. Each checks the prompt is on screen before the key, that the session exits 0, and that nothing written after the quit began draws the prompt text, the box or the auto-approve hint. Both fail without the change and pass with it.

  • npx vitest run on every test file that imports chat.ts (chat.test.ts, dashboard.test.ts, mcp-ui.test.ts, mcp/audit-regressions.test.ts): 7 tests fail identically on an unmodified main and with this change on my Windows machine (the Ctrl-O output test, the signing-in file mode test, and several signal and path tests); 2 more tests pass with the change.
  • pnpm typecheck passes.
  • I did not add the PTY-backed terminal test from the acceptance criteria, which needs a real terminal, and I did not check the result in a real terminal or on macOS.

Generated with Claude Code

nimbly1 and others added 2 commits October 4, 2026 02:11
onKey() ended with an unconditional refresh(). When the key was a quit
(Ctrl-D at an empty prompt, or the second Ctrl-C), onControl() had
already run quit() -> finish() -> Screen.finish(), which clears the live
composer and footer and restores the cursor. The refresh then painted the
input box and the shortcut hint again, leaving them on screen after the
process exited with code 0.

Skip the refresh once the session is quitting, as the other refresh call
sites in chat.ts already do. Add tests for Ctrl-D and for the second
Ctrl-C that check nothing drawing the prompt is written after the quit
begins. Ctrl-D in a non-empty draft (delete forward) and Ctrl-C while a
task runs are unchanged.

Fixes TaewoooPark#32

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@TaewoooPark

Copy link
Copy Markdown
Owner

Thanks @nimbly1 for the focused lifecycle fix and regressions! Reviewed 623682905aac028ea7219f654157395d044dc883, including the small maintainer follow-up 6236829 that adds coverage for Ctrl-D delete-forward in a nonempty draft. The production fix remains your one-line guard.

I reproduced both new shutdown tests failing on base, then verified them on the PR. On this Apple Silicon Mac, the actual built CLI in a visible xterm.js 6.0.0 + macOS PTY reproduced the stale composer at the next shell prompt on base. The patched build exits 0 after Ctrl-D and double Ctrl-C without repainting, preserves the settled transcript, restores terminal modes/cursor, drains final output, and hands off to a working zsh prompt (echo SHELL_HANDOFF_OK). Ctrl-D edits abxc to abc without quitting; Ctrl-C during sustained local SSE interrupts and leaves a reusable /help prompt. This is a PTY-backed browser terminal check, not a native Terminal.app check.

The 77 chat tests pass. Initial parallel full-suite runs hit existing timing-sensitive process tests; those passed in isolated reruns. The combined current-main + #43 + #47 + 0.4.3 tree now passes the complete 1,676 tests across 97 files with two workers, plus frozen install, typecheck, build and tool-schema lint. No real model credentials were used; the process and terminal checks used isolated local fixtures.

All five CI jobs pass on this exact head: https://github.com/TaewoooPark/Motifcode/actions/runs/39024058166

All acceptance criteria in #32 are covered, with no blocking regression or unrelated scope expansion found. Merging as a squash commit; npm 0.4.3 will be published after release-commit CI and registry verification.

@TaewoooPark
TaewoooPark merged commit 3fcb52b into TaewoooPark:main Oct 17, 2026
5 checks passed
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.

Do not repaint the interactive footer after Ctrl-D shutdown

2 participants