fix: resolve keyboard input freeze on Windows and Mac at startup (#285)

Three compounding issues caused keyboard input to appear frozen or drop
characters on startup, particularly on Windows CMD/PowerShell and Mac
terminal environments.

Issue 1 — earlyInput disabled (cli.tsx):
The rebrand commit gated startCapturingEarlyInput() behind an opt-in
env flag (OPENCLAUDE_ENABLE_EARLY_INPUT=1), which meant any characters
typed before React finished mounting were silently dropped. Users who
type immediately after launch saw an empty input box with no indication
their keystrokes were lost. Flipped to an opt-out flag
(OPENCLAUDE_DISABLE_EARLY_INPUT=1) so early input capture is on by
default, matching the original upstream behaviour.

Issue 2 — stdin.resume() called before listener attached (App.tsx):
stdin.resume() put the stream into flowing mode before the data/readable
listener was registered. Any input arriving in that gap was queued and
delivered in a burst when the listener connected, which could flood
React's scheduler and stall input processing. Moved resume() to after
the listener is attached so the stream only flows once the handler is
ready.

Issue 3 — AnimatedAsterisk fires ~60 React re-renders in 3s (AnimatedAsterisk.tsx):
The startup screen colour sweep animation runs at 50ms intervals for
3000ms total. Each tick triggers a full re-render of the startup screen
subtree, which competes with stdin event processing in React's microtask
queue. On Windows, where the event loop scheduler is slower, this
reliably caused typing to lag or freeze for the first few seconds after
launch. The animation is now skipped on Windows (process.platform ===
'win32'), showing the icon in its settled state immediately. Mac and
Linux are unaffected.

Closes #228, #220, #205
This commit is contained in:
KRATOS
2026-04-03 23:04:41 +05:30
committed by GitHub
parent c735233f92
commit afed73fa5a
3 changed files with 5 additions and 3 deletions

View File

@@ -416,7 +416,7 @@ async function main(): Promise<void> {
}
// No special flags detected, load and run the full CLI
if (process.env.OPENCLAUDE_ENABLE_EARLY_INPUT === '1') {
if (process.env.OPENCLAUDE_DISABLE_EARLY_INPUT !== '1') {
const {
startCapturingEarlyInput
} = await import('../utils/earlyInput.js');