Read stdin through the command, with shared read helpers - #187
Open
nathanjcochran wants to merge 3 commits into
Open
Read stdin through the command, with shared read helpers#187nathanjcochran wants to merge 3 commits into
nathanjcochran wants to merge 3 commits into
Conversation
BubbleTea defaults to os.Stdin when WithInput is omitted, so the four interactive pickers read real stdin regardless of what the command was given. Pass both streams explicitly, and gate the two ungated pickers on a TTY so they fail with a useful message instead of inside BubbleTea. oauthLogin now holds the *cobra.Command rather than an io.Writer, since the project picker needs stdin as well as stderr.
nathanjcochran
force-pushed
the
nathan/improve-stdin
branch
from
August 6, 2026 21:53
d8e4652 to
0e5c134
Compare
Without the gate the prompt fails on an unhelpful EOF in CI, instead of pointing at --confirm.
Askir
approved these changes
Aug 10, 2026
| }) | ||
| } | ||
|
|
||
| func ReadAll(ctx context.Context, stdin io.Reader) (string, error) { |
Contributor
There was a problem hiding this comment.
This seems to have no callers, I guess it's still fine to add since you ported it over. Just calling that out.
|
|
||
| val, err := readFn() | ||
| if err != nil { | ||
| resultCh <- result{err: err} |
Contributor
There was a problem hiding this comment.
This breaks for piped input apparently if it doesn't end with a \n, idk if that's a real use case though so probably fine.
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.
Follow-up to #186, applying the same idea to input. Commands read through
cmd.InOrStdin()rather thanos.Stdin, and the ad-hoc terminal helpers ininternal/cmdare replaced byutil.ReadLine/util.ReadPassword/util.ReadAll, ported from Ghost.The benefit is one place that knows how to read a line, a password, or piped input, instead of each command hand-rolling
bufioandtermcalls. All three helpers run the blocking read on a goroutine and select on the context, so Ctrl-C unblocks a waiting prompt instead of hanging until the user hits enter. Tests drive the interactive paths by stubbingutil.IsTerminalandutil.ReadPasswordcentrally, rather than every command carrying its own override hooks.The interactive menus needed the same treatment. BubbleTea silently defaults to
os.StdinwhenWithInputis omitted — and there's no compile error to catch it — so all four pickers (project, read replica, password recovery, MCP client) were reading real stdin regardless of what the command was given. They now get both streams explicitly, which is whyoauthLogincarries the*cobra.Commandinstead of a writer.Finally, every prompt that blocks on a real-time answer is now gated on whether stdin is a terminal, and names the flag to use when it isn't. Three were missing that check and would fail on an opaque EOF, or hang, when run in CI.
Bug fixes and behavior changes:
db save-password,db connect's password recovery,service update-password, andauth login.tiger mcp installwith no argument now tells you to name a client, instead of failing somewhere inside BubbleTea.tiger service deletewithout--confirmnow points at that flag rather than dying onfailed to read confirmation: EOF. Note this also stops a piped confirmation (echo svc-x | tiger service delete svc-x) from working —--confirmis the automation path for a destructive command.tiger auth loginwith multiple projects and no TTY points at--public-key/--secret-keyinstead of erroring out of the picker.The conventions are written up in CLAUDE.md.