Documentation
¶
Overview ¶
Package stdinarg carries the shared vocabulary for "-" (read from stdin) argument handling: the cobra annotation that marks where a command accepts "-", and pipe detection for deciding whether a stray "-" is ambiguous.
It is a leaf package because both internal/commands (which resolves "-" and installs the guard) and internal/cli (which surfaces the annotation in agent help) need the same annotation key, and cli already depends on commands.
Index ¶
Constants ¶
const AnnotationAllowDash = "allow_dash"
AnnotationAllowDash is the cmd.Annotations key marking where a command accepts "-" as "read from stdin". The value is a space-separated list of tokens: "arg:0" (exact positional index), "arg:1+" (that index and beyond), "flag:data" (the --data flag). Everything not listed is guarded: a literal "-" there combined with piped stdin is rejected as ambiguous.
Variables ¶
This section is empty.
Functions ¶
func InteractivePrompt ¶
func InteractivePrompt() bool
InteractivePrompt reports whether stdin and stderr are terminals — the floor for a huh form specifically, because huh draws the form to stderr rather than stdout (huh form.go:112 passes tea.WithOutput(os.Stderr)), while a bare bubbletea program such as the picker draws to stdout.
The distinction is not pedantry. Checking stdout for a form that renders to stderr means `cmd 2>somewhere` draws the prompt into the void while still reading /dev/tty: an invisible question blocking a terminal. Ask about the stream the launcher actually writes to.
func InteractiveStdio ¶
func InteractiveStdio() bool
InteractiveStdio reports whether both stdout and stdin are terminals — the floor for launching anything that draws to the terminal and reads keystrokes. A TUI (picker, wizard) reads key events from stdin, so a pipe or redirected file can never drive one — and when the command is consuming piped content (a "-" stdin input), a TUI would eat that content as key events.
This asks term.IsTerminal, not whether the file is a character device. The two differ on exactly the case that matters: /dev/null is a character device that delivers no keystrokes, and `cmd < /dev/null` from a terminal session is how an agent says "I have nothing to type". Bubble Tea agrees — it tests the same term.IsTerminal, and when stdin fails that test it does not error, it opens /dev/tty and waits on the real terminal instead. Calling /dev/null interactive is therefore a hang, not a cosmetic mismatch.
IsPiped above deliberately keeps the character-device test: it answers a different question (is there content on stdin to read?), and reading /dev/null correctly yields nothing.
func IsPiped ¶
IsPiped reports whether the reader carries piped (redirected) input rather than an interactive terminal. A non-*os.File reader — the cmd.SetIn test seam — always counts as piped. For a real file, a character device means a terminal; anything else (pipe, regular file redirect) is piped input.
Types ¶
type Allow ¶
type Allow struct {
// contains filtered or unexported fields
}
Allow is the parsed form of an AnnotationAllowDash value.
func ParseAllow ¶
ParseAllow parses a space-separated token list ("arg:0 arg:1+ flag:data") into an Allow. Unrecognized tokens are ignored rather than failing: the annotation is authored in-repo and covered by tests, so a typo shows up as a guarded (rejected) input, not a silent bypass.