Skip to content

fix(cmd): refuse to prompt when nothing can answer - #134

Open
Ilyes512 wants to merge 1 commit into
refactor/GH-114-setup-loggerfrom
fix/GH-119-non-interactive-prompts
Open

fix(cmd): refuse to prompt when nothing can answer#134
Ilyes512 wants to merge 1 commit into
refactor/GH-114-setup-loggerfrom
fix/GH-119-non-interactive-prompts

Conversation

@Ilyes512

@Ilyes512 Ilyes512 commented Sep 2, 2026

Copy link
Copy Markdown
Member

Neither interactive form asked whether stdin was a terminal, and neither was
given explicit streams, so huh read os.Stdin and drew on os.Stdout.

A CI job running specs template use with a variable that has no value from
flags or project.yaml reached the prompt pass and waited for a keystroke that
could never arrive. Nothing was drawn, nothing came back, and the job hung
until the runner's timeout killed it with no explanation in the log. --yes
covered the hook confirmation, but for a missing variable there was nothing
to pass.

Drawing on stdout was the second half of it: stdout carries the product, so a
form's redraws corrupt -o json and end up inside the file a caller redirected
to. A prompt is narration by any reading.

output.IsTTY answers the terminal question, and it takes any stream because
the one that matters is stdin — a job with a terminal on stderr and its stdin
closed must still refuse. App gains Stdin/Stdout/Stderr seams populated from
cmd.InOrStdin() and friends, so a form is drawn through streams a test can
supply, and --non-interactive forces the same refusal at a terminal for
checking what CI will do.

A prompt pass with nothing to answer it now fails naming every key it would
have asked for and how to supply it. The hook confirmation is treated
differently: declining is the safe reading of a question nobody can answer, so
the template still applies and only its hooks are skipped — failing there would
break every CI job using a remote template that happens to define one.

Closes #119


Stack created with GitHub Stacks CLIGive Feedback 💬

Neither interactive form asked whether stdin was a terminal, and neither was
given explicit streams, so huh read os.Stdin and drew on os.Stdout.

A CI job running `specs template use` with a variable that has no value from
flags or project.yaml reached the prompt pass and waited for a keystroke that
could never arrive. Nothing was drawn, nothing came back, and the job hung
until the runner's timeout killed it with no explanation in the log. --yes
covered the hook confirmation, but for a missing variable there was nothing
to pass.

Drawing on stdout was the second half of it: stdout carries the product, so a
form's redraws corrupt -o json and end up inside the file a caller redirected
to. A prompt is narration by any reading.

output.IsTTY answers the terminal question, and it takes any stream because
the one that matters is stdin — a job with a terminal on stderr and its stdin
closed must still refuse. App gains Stdin/Stdout/Stderr seams populated from
cmd.InOrStdin() and friends, so a form is drawn through streams a test can
supply, and --non-interactive forces the same refusal at a terminal for
checking what CI will do.

A prompt pass with nothing to answer it now fails naming every key it would
have asked for and how to supply it. The hook confirmation is treated
differently: declining is the safe reading of a question nobody can answer, so
the template still applies and only its hooks are skipped — failing there would
break every CI job using a remote template that happens to define one.

Closes #119
@Ilyes512
Ilyes512 marked this pull request as ready for review September 2, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant