From c960e3f427b32b240e5c1599516db97d1b54b1da Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Wed, 27 May 2026 08:00:03 -0600 Subject: [PATCH] fix: stop analyze.sh from hanging at interactive prompts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The installer ran the compiled binary with `< /dev/tty` to give piped `curl ... | bash` invocations a terminal. But a `bun build --compile`'d binary can't read raw-mode keypresses from a freshly-opened /dev/tty fd, so every interactive prompt hung with no way to type, arrow, or Ctrl-C out — even for the recommended `bash -c "$(curl ...)"` form, whose stdin was already a working terminal before the redirect replaced it. Run with inherited stdin instead. The command-substitution form keeps a real terminal on stdin and works; the piped form now fails the CLI's TTY gate with a clear 'requires a terminal' message (exit 2) instead of hanging. --- scripts/analyze.sh | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/scripts/analyze.sh b/scripts/analyze.sh index 31379ed..fe55c42 100644 --- a/scripts/analyze.sh +++ b/scripts/analyze.sh @@ -11,9 +11,10 @@ # temporary directory, printing the path when it finishes. Nothing is installed. # # Use the `bash -c "$(curl ...)"` form rather than `curl ... | bash`: the -# command-substitution form leaves your terminal on stdin so the prompts work. -# As a fallback the script also reconnects the controlling terminal (/dev/tty) -# when running the binary, so a piped invocation still gets a TTY. +# command-substitution form leaves your real terminal on stdin so the +# interactive prompts work. A piped (`curl ... | bash`) invocation puts the pipe +# on stdin instead of a terminal, so the CLI's TTY gate refuses to run and asks +# you to re-run it interactively (it does not hang). # # Auth is the CLI's job: it reads GITHUB_TOKEN, then GH_TOKEN, then `gh auth # token`. Export a token first, or be logged in via the gh CLI. @@ -53,19 +54,14 @@ main() { [ -f "$_tmp/$BINARY_NAME" ] || fail "expected '$BINARY_NAME' in tarball, not found" chmod +x "$_tmp/$BINARY_NAME" - # The CLI is an interactive session, so it needs a terminal on stdin. - # Reconnect the controlling terminal (/dev/tty) so prompts work even when this - # script was piped into a shell (stdin = the pipe, not your terminal). Where - # there is no terminal (e.g. CI), run with inherited stdin and let the CLI - # report that it needs one. Run, don't exec, so the EXIT trap still deletes the - # temp binary; preserve the CLI's exit code for the caller. + # Run with inherited stdin and let the CLI's TTY gate handle non-terminals. Do + # NOT redirect `< /dev/tty`: the compiled Bun binary can't read raw-mode + # keypresses from a reopened /dev/tty fd, so prompts would hang with no way to + # Ctrl-C out. Run (not exec) so the EXIT trap deletes the temp binary, and + # forward the CLI's exit code. info "starting ${BINARY_NAME}..." set +e - if (: < /dev/tty) 2>/dev/null; then - "$_tmp/$BINARY_NAME" "$@" < /dev/tty - else - "$_tmp/$BINARY_NAME" "$@" - fi + "$_tmp/$BINARY_NAME" "$@" _status=$? set -e exit "$_status"