feat(cli): add early input capture to prevent keystroke loss during startup#3319
feat(cli): add early input capture to prevent keystroke loss during startup#3319
Conversation
…tartup (#3224) Start raw mode stdin listening immediately after setRawMode(true), buffer user input during REPL initialization (200-500ms), then replay it once KeypressProvider is mounted. Prevents keystrokes typed before the REPL is ready from being silently dropped. - Filter out terminal response sequences (DA, DA2, OSC, DCS, APC) while preserving real user input (arrow keys, function keys, etc.) - 64KB buffer limit for safety - Replay via setImmediate() to ensure subscribers are registered first - Disable via QWEN_CODE_DISABLE_EARLY_CAPTURE=1 - Add benchmark-startup.sh / benchmark-startup-simple.sh for baseline startup time measurement Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
📋 Review SummaryThis PR implements an early input capture mechanism to prevent keystroke loss during CLI startup by buffering user input between raw mode activation and REPL initialization. The implementation is well-designed with comprehensive test coverage, proper terminal response filtering, and appropriate safety controls. Overall, this is a solid solution to a real UX problem. 🔍 General Feedback
🎯 Specific Feedback🟢 Medium
🔵 Low
✅ Highlights
|
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
- Fix getAndClearCapturedInput resetting captured flag, preventing potential re-arm - Fix passthrough mode replay bypassing paste marker handling in KeypressContext - Optimize buffer storage from O(n^2) concat to chunked collection - Optimize filterTerminalResponses to use pre-allocated Buffer instead of number[] - Add atomic stopAndGetCapturedInput API to prevent two-step usage errors - Remove unrelated benchmark shell scripts - Add test for stopAndGetCapturedInput Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
…arly input capture - Register cleanup for stdin listener in gemini.tsx to prevent orphaned listener on any error path before UI mounts - Add try-catch and cancellation guard to setImmediate replay in KeypressContext to handle component unmount and replay errors gracefully - Stop capture immediately and warn when buffer limit is reached instead of silently dropping data with a debug-level log - Capture stdin reference at registration time so removeListener always operates on the correct stream instance - Add debug log when early capture is skipped due to non-TTY stdin Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Move stopAndGetCapturedInput() from inside KeypressProvider's useEffect to before render() in startInteractiveUI. When DEBUG=1, React StrictMode deliberately runs effect→cleanup→effect, causing the first mount to drain the buffer and schedule a replay that the cleanup immediately cancels. The second mount found an empty buffer, silently discarding startup keystrokes. By draining once before render() and passing the bytes as a stable prop, StrictMode remounts always read the same data and can schedule replay on the second (stable) mount. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
d464cd5 to
ed6fd28
Compare
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
When capture stops with an incomplete ESC sequence in pendingTerminalResponse (e.g. lone \x1b or \x1b[), classifyEscapeSequence returns 'incomplete'. Previously shouldReplayPendingAtStop used !== 'terminal' which treated incomplete sequences as user input. Changed to === 'user' so only definitively-user input is replayed; ambiguous sequences are safely dropped. Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Closes #3224
Summary
Start raw mode stdin listening immediately after
setRawMode(true), buffer user input during REPL initialization (200-500ms), then replay it onceKeypressProvideris mounted. Prevents keystrokes typed before the REPL is ready from being silently dropped.Terminal response filtering:
Controls:
QWEN_CODE_DISABLE_EARLY_CAPTURE=1setImmediate()to ensure subscribers are registered firstTest Plan
人工校验
DingTalk.Recording.Screen_2026-04-16.185523.mp4
DingTalk.Recording.Screen_2026-04-16.185613.mp4
3.输入正常文字+上下左右+ESC,只记录正常文字
DingTalk.Recording.Screen_2026-04-16.185700.mp4
🤖 Generated with Claude Code