Skip to content

fix: ensure stdin state is correct for searchable multi-select prompt - #620

Closed
yongnianliu wants to merge 6 commits into
Fission-AI:mainfrom
yongnianliu:main
Closed

fix: ensure stdin state is correct for searchable multi-select prompt#620
yongnianliu wants to merge 6 commits into
Fission-AI:mainfrom
yongnianliu:main

Conversation

@yongnianliu

@yongnianliu yongnianliu commented Jan 30, 2026

Copy link
Copy Markdown

#619

Summary by CodeRabbit

  • Bug Fixes
    • Fixed arrow key navigation in searchable multi-select component that was unresponsive after the welcome screen. Keyboard input now responds correctly without requiring Enter to be pressed first.

✏️ Tip: You can customize this high-level summary in your review settings.

@yongnianliu
yongnianliu requested a review from TabishB as a code owner January 30, 2026 03:45
@coderabbitai

coderabbitai Bot commented Jan 30, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes fix a stdin state bug affecting arrow key input in searchableMultiSelect after the welcome screen. The welcome-screen no longer manages stdin state post-entry, while searchable-multi-select now explicitly prepares stdin (raw mode and resume) before initialization.

Changes

Cohort / File(s) Summary
Stdin State Management
src/ui/welcome-screen.ts, src/prompts/searchable-multi-select.ts
Redistributes stdin state responsibility: welcome-screen removes post-Enter stdin restoration/pause, delegating to next prompt; searchable-multi-select adds pre-initialization stdin setup (raw mode and resume) to fix arrow key failures.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 Arrows dance where once they froze,
Raw mode blooms in careful prose,
Welcome screen steps back with grace,
Let the prompt take its rightful place!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: fixing stdin state handling for the searchable multi-select prompt by adjusting how stdin is managed between the welcome screen and subsequent prompts.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

🧪 Unit Test Generation v2 is now available!

We have significantly improved our unit test generation capabilities.

To enable: Add this to your .coderabbit.yaml configuration:

reviews:
  finishing_touches:
    unit_tests:
      enabled: true

Try it out by using the @coderabbitai generate unit tests command on your code files or under ✨ Finishing Touches on the walkthrough!

Have feedback? Share your thoughts on our Discord thread!


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 and usage tips.

@vibe-kanban-cloud

Copy link
Copy Markdown

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

@greptile-apps

greptile-apps Bot commented Jan 30, 2026

Copy link
Copy Markdown

Greptile Overview

Greptile Summary

Fixed stdin state management issue where arrow keys didn't work in searchableMultiSelect prompt after the welcome screen.

Root cause: waitForEnter() in welcome-screen.ts was restoring raw mode and pausing stdin, leaving it in an incorrect state for the next prompt.

Changes:

  • welcome-screen.ts: Removed stdin cleanup (setRawMode restore and pause()) in waitForEnter() to leave stdin active
  • searchable-multi-select.ts: Added explicit stdin state initialization before creating the prompt to ensure raw mode is enabled and stdin is resumed

The fix follows a defensive programming approach where searchableMultiSelect now takes responsibility for ensuring stdin is in the correct state, rather than relying on previous functions to clean up properly.

Confidence Score: 4/5

  • This PR is safe to merge with minimal risk
  • The fix directly addresses the reported issue with a clear, well-documented solution. The defensive approach of ensuring stdin state in searchableMultiSelect is solid. Minor deduction for the unused wasRaw variable and lack of test coverage verification
  • No files require special attention - changes are straightforward stdin state management fixes

Important Files Changed

Filename Overview
src/prompts/searchable-multi-select.ts Added stdin state initialization to ensure raw mode and resume state before prompt creation
src/ui/welcome-screen.ts Removed stdin cleanup (setRawMode restore and pause) to allow next prompt to handle stdin state

Sequence Diagram

sequenceDiagram
    participant User
    participant InitCommand
    participant WelcomeScreen
    participant stdin as process.stdin
    participant SearchableMultiSelect

    Note over User,SearchableMultiSelect: Before Fix: stdin left in paused state

    User->>InitCommand: Run init command
    InitCommand->>WelcomeScreen: showWelcomeScreen()
    WelcomeScreen->>stdin: setRawMode(true)
    WelcomeScreen->>stdin: resume()
    User->>WelcomeScreen: Press Enter
    Note over WelcomeScreen,stdin: OLD: setRawMode(wasRaw) + pause()
    WelcomeScreen-->>InitCommand: Return
    InitCommand->>SearchableMultiSelect: searchableMultiSelect()
    Note over SearchableMultiSelect,stdin: Arrow keys don't work (stdin paused)
    User->>SearchableMultiSelect: Press Enter first
    Note over SearchableMultiSelect: Inquirer resumes stdin
    User->>SearchableMultiSelect: Arrow keys now work

    Note over User,SearchableMultiSelect: After Fix: stdin state properly managed

    User->>InitCommand: Run init command
    InitCommand->>WelcomeScreen: showWelcomeScreen()
    WelcomeScreen->>stdin: setRawMode(true)
    WelcomeScreen->>stdin: resume()
    User->>WelcomeScreen: Press Enter
    Note over WelcomeScreen: NEW: Don't restore/pause stdin
    WelcomeScreen-->>InitCommand: Return
    InitCommand->>SearchableMultiSelect: searchableMultiSelect()
    SearchableMultiSelect->>stdin: Check isTTY
    SearchableMultiSelect->>stdin: setRawMode(true) if not raw
    SearchableMultiSelect->>stdin: resume()
    Note over SearchableMultiSelect: stdin now in correct state
    User->>SearchableMultiSelect: Arrow keys work immediately
Loading

@greptile-apps greptile-apps Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

2 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@greptile-apps

greptile-apps Bot commented Jan 30, 2026

Copy link
Copy Markdown
Additional Comments (1)

src/ui/welcome-screen.ts
Variable wasRaw captured but never used after removing the cleanup code

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/ui/welcome-screen.ts
Line: 90:90

Comment:
Variable `wasRaw` captured but never used after removing the cleanup code

How can I resolve this? If you propose a fix, please make it concise.

@TabishB TabishB 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.

Nice find on the root cause. One suggestion below.

Comment thread src/ui/welcome-screen.ts
stdin.removeListener('data', onData);
stdin.setRawMode(wasRaw);
stdin.pause();
// Don't restore raw mode or pause stdin here - let the next prompt handle stdin state

@TabishB TabishB Jan 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.

The searchableMultiSelect() guard already fixes this. I'd revert this change so waitForEnter() keeps cleaning up after itself. No need for both.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

ok

@TabishB

TabishB commented Feb 2, 2026

Copy link
Copy Markdown
Contributor

@yongnianliu Let me know if you can take a look at the above comment

@clay-good

Copy link
Copy Markdown
Collaborator

Closing as already fixed on main — thank you for tracing this to the welcome screen's stdin handling, which was the correct root cause.

#619 is closed as completed, fixed by #1175 (596d6ba, fix(init): fix only Enter working after legacy cleanup on Windows, merged 2026-07-18).

src/ui/welcome-screen.ts on main no longer uses a raw data listener at all:

async function waitForEnter(): Promise<void> {
  if (!process.stdin.isTTY) return;

  // Keep all interactive input on Inquirer's keypress lifecycle. Mixing a raw
  // `data` listener between Inquirer prompts breaks arrow/space keys on Windows.
  const { createPrompt, isEnterKey, useKeypress } = await import('@inquirer/core');
  const prompt = createPrompt<void, Record<string, never>>((_config, done) => {
    useKeypress((key) => {
      if (key.ctrl && key.name === 'c') { process.stdout.write('\n'); process.exit(0); }
      if (isEnterKey(key)) done(undefined);
    });
    return '';
  });
  await prompt({});
}

That code comment names exactly the failure mode this PR was working around.

Why the shipped fix took a different shape, and why it matters here: this PR left the raw listener in place and compensated on both sides — waitForEnter stopped restoring wasRaw and stopped calling stdin.pause(), and searchableMultiSelect force-set raw mode before creating its prompt. That works, but it leaves two components sharing mutable global stdin state, so the next prompt added to the flow inherits the same hazard. #1175 removed the raw listener entirely and put the welcome screen on Inquirer's own keypress lifecycle, so there is no state to hand off.

Since then src/prompts/searchable-multi-select.ts has also picked up #1463 (checkbox markers [x]/[ ] for multi-select, closing #647) and the welcome screen picked up #1462 (reduced-motion / OPENSPEC_NO_ANIMATION / --no-animation, closing #722) — both of which assume the Inquirer-only input model.

Reopen if arrow keys still fail after the welcome screen on current main; that would be a fresh regression worth its own issue.

@clay-good clay-good closed this Jul 28, 2026
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.

3 participants