fix(auth): show the interactive login prompt instead of erasing it#39
Open
narthur wants to merge 1 commit into
Open
fix(auth): show the interactive login prompt instead of erasing it#39narthur wants to merge 1 commit into
narthur wants to merge 1 commit into
Conversation
a3e88df to
d61c14f
Compare
auth login with non-TTY stdin`ynab auth login` on a TTY appeared to hang with no prompt. The cause was
in promptForToken(): it wrote "Enter YNAB Personal Access Token: " to the
output stream itself and then called readline's `question('')` with an
empty query. readline owns the current line and, when it renders, emits
`ESC[1G ESC[0J` (cursor-home + clear-to-end-of-screen) — which erases the
pre-written prompt the instant it appears. On terminals that apply those
sequences promptly (Warp is one), the user sees a blank line with a
blinking cursor and no hint that a token is expected, so the command
looks dead. (Input actually still worked — typing a token and pressing
Enter authenticated — but nothing told the user to type.)
Pass the prompt as readline's `question()` query instead. readline then
reprints the prompt after its own clear, so it stays visible and the
cursor parks right after it.
Verified under a real PTY: the byte stream is now
`ESC[1G ESC[0J Enter YNAB Personal Access Token: ESC[35G` — clear first,
prompt second, surviving on screen.
Also makes promptForToken/readTokenFromStdin accept injectable streams so
the prompt-rendering and stdin-parsing behaviour can be unit-tested, and
gives the empty-token error an actionable hint.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
d61c14f to
5f15641
Compare
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.
Problem
On an interactive TTY,
ynab auth loginlooks like it hangs: no prompt appears, just a blank line with a blinking cursor. Reported on Warp; reproducible on any terminal that applies cursor/erase escape sequences promptly.It isn't actually a non-TTY/stdin issue —
stdin,stdout, andstderrare all TTYs in the affected sessions. The bug is in the interactive prompt itself.Root cause
The prompt is written directly to the output stream, then
readline.question('')is called with an empty query. readline owns the current line and, when it renders, emitsESC[1G(cursor to column 1) +ESC[0J(erase to end of screen) — wiping the just-written prompt.Captured from the real binary under a PTY, before any input:
Result: the prompt flashes and vanishes; the user sees nothing and assumes it's stuck. (Input still works — piping/typing a token authenticates — but nothing signals that a token is expected.)
Fix
Pass the prompt as readline's
question()query so readline reprints it after its own clear instead of erasing a string it doesn't know about:Same binary under a PTY after the fix — clear first, prompt second, surviving on screen with the cursor parked after it:
promptForToken()andreadTokenFromStdin()now accept injectable streams (defaulting to the real stdio) so the prompt-rendering and stdin-parsing paths can be unit-tested, and the empty-token error gains an actionable hint.Tests
Adds
src/commands/auth.test.ts: the prompt text reaches the output stream and the typed token is returned/trimmed; stdin piping resolves/trims, empty-EOF resolves empty, and stream errors reject.bun run typecheckandbun run lint(oxlint) pass.🤖 Generated with Claude Code