fix(init): fix InkUI on native Windows terminals (CLI-1NT)#978
Draft
betegon wants to merge 4 commits into
Draft
Conversation
On Windows, /dev/tty doesn't exist in CMD.exe, PowerShell, or Windows Terminal. openFreshTtyForInk() returned null, leaving Ink reading from process.stdin — the broken Bun fd 0 (oven-sh/bun#6862) — which caused mountApp() to throw. getUIAsync() swallowed the throw silently and fell back to LoggingUI, which then threw LoggingUIPromptError in preamble(), surfacing as "The interactive UI failed to load." Git Bash / MSYS2 / Cygwin users were unaffected because their POSIX emulation layer maps /dev/tty correctly. Three changes: - ink-ui.ts: try \\.\CON as the TTY device path on Windows. A freshly opened console handle is not fd 0 and should deliver readable events correctly, the same way /dev/tty does on Unix. A setRawMode(true/false) probe verifies the handle supports raw mode before handing it to Ink — if it fails the function returns null and falls back gracefully. - factory.ts: add a breadcrumb in the InkUI catch block (including the error stack) so the actual throw is visible in Sentry. Previously only the downstream LoggingUIPromptError appeared, with no indication of the real cause. - wizard-runner.ts: when LoggingUIPromptError fires but isTTY is true, point the user to --no-tui --yes rather than just --yes, which alone doesn't explain why the TUI failed. Fixes CLI-1NT
Contributor
|
…fd leak If openSync and new ReadStream both succeed but setRawMode(true) throws (e.g. a \.\CON handle that passes open but fails SetConsoleMode), the catch block was returning null without closing the stream, leaking the underlying file descriptor. Hoist stream outside the try block so the catch can call stream?.destroy() before returning null. The optional chain is a no-op when the error occurred in openSync or the ReadStream constructor. Reported by sentry-warden on PR #978.
The error message now branches on process.stdin.isTTY: interactive TTY gets '--no-tui --yes' guidance; non-TTY gets '--yes'. Update the test name and expected string to match the isTTY=true branch that forceStdinTty exercises. The non-TTY branch is unreachable via LoggingUIPromptError (preamble throws earlier with a different message).
Contributor
Codecov Results 📊✅ 6990 passed | Total: 6990 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
All tests are passing successfully. ❌ Patch coverage is 75.00%. Project has 14140 uncovered lines. Files with missing lines (2)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 77.08% 77.12% +0.04%
==========================================
Files 320 320 —
Lines 61811 61802 -9
Branches 0 0 —
==========================================
+ Hits 47646 47662 +16
- Misses 14165 14140 -25
- Partials 0 0 —Generated by Codecov Action |
…Error hint factory.mocked.test.ts: 4 tests covering the getUIAsync() catch path — fallback to LoggingUI when createInkUI throws an Error, rejects with a non-Error, or when the dynamic import itself fails. Also verifies the fallback is stateless across consecutive calls. mock.module() isolates the ink-ui sidecar so the Ink renderer is never spun up in tests. wizard-runner.test.ts: update test name and expected message to match the isTTY=true branch that forceStdinTty() exercises (--no-tui --yes guidance instead of the old --yes-only hint). Remove the trailing blank line left by the deleted non-TTY test case.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sentry initwas failing on Windows in CMD.exe, PowerShell, and Windows Terminal with "The interactive UI failed to load" since 0.33.0 (when InkUI replaced OpenTUI). Git Bash / MSYS2 users were fine because their POSIX layer maps/dev/tty— native Windows terminals don't have it.The failure chain:
openFreshTtyForInk()returnsnullon Windows → Ink falls back toprocess.stdin(Bun's broken fd 0, oven-sh/bun#6862) →mountApp()throws →getUIAsync()swallows it silently →LoggingUIis used →LoggingUIPromptErrorinpreamble()→WizardError.Changes
ink-ui.ts— try\\.\CONas the TTY device path on Windows. It's the console device equivalent of/dev/tty: a freshly-opened handle is not fd 0 and should deliverreadableevents correctly, bypassing the Bun bug. AsetRawMode(true/false)probe runs immediately after opening to verify the handle actually supports raw mode — if it throws, the function returnsnulland falls back gracefully rather than blowing up insidemountApp.factory.ts— add a breadcrumb (with stack) in thegetUIAsynccatch block. Previously the actual InkUI throw was swallowed with no trace; only the downstreamLoggingUIPromptErrorappeared in Sentry. The breadcrumb will confirm whether\\.\CONfixes the issue or if there's a secondary failure to address.wizard-runner.ts— whenLoggingUIPromptErrorfires butstdin.isTTYis true, suggest--no-tui --yesinstead of just--yes. The old message was misleading for any user who expected interactive mode.Test Plan
sentry initfrom CMD.exe or PowerShell on Windows 10/11 with Bun — should enter the wizard instead of immediately erroring\\.\CONdoesn't fully resolve it on some setupsFixes CLI-1NT