From 8cece0b2d39061e558716d469b5e71c2cef8d294 Mon Sep 17 00:00:00 2001 From: Alec Fong Date: Sun, 4 Oct 2026 16:49:29 -0700 Subject: [PATCH] Install Codex noninteractively during bootstrap --- README.md | 4 ++++ install.sh | 3 ++- test.sh | 31 +++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4afdb2a..a6a3ea9 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,10 @@ then clones this repo to `~/.setup` and symlinks the Claude config into `~/.claude`. It works on macOS (Homebrew) and Linux (apt/dnf/apk), and is safe to re-run — anything already present is skipped. +Codex CLI installs without interactive prompts. On Linux, the bootstrap sets +`CODEX_NON_INTERACTIVE=1` for the Codex installer, which also skips launching +Codex after installation. Run `codex` when you are ready to sign in. + Each install is verified twice: the expected command must be on `PATH`, and the CLIs this bootstrap exists to install must actually execute (`assert_runs` invokes each one's version command, since a truncated download or a diff --git a/install.sh b/install.sh index d0d999b..913ebcc 100755 --- a/install.sh +++ b/install.sh @@ -283,7 +283,8 @@ install_codex() { if [ "$PM" = "brew" ]; then brew install --cask codex || { warn "failed to install Codex CLI"; record_failure codex; } else - curl -fsSL https://chatgpt.com/codex/install.sh | sh || { warn "failed to install Codex CLI"; record_failure codex; } + # Keep bootstrap unattended, including when the installer can read /dev/tty. + curl -fsSL https://chatgpt.com/codex/install.sh | CODEX_NON_INTERACTIVE=1 sh || { warn "failed to install Codex CLI"; record_failure codex; } add_path "$HOME/.local/bin" fi assert_installed "Codex CLI" codex diff --git a/test.sh b/test.sh index cc2b6ae..a8063f7 100755 --- a/test.sh +++ b/test.sh @@ -17,6 +17,37 @@ source ./install.sh scratch=$(mktemp -d) trap 'rm -rf "$scratch"' EXIT +# The downloaded Codex installer must receive noninteractive mode. Setting it +# on curl instead of sh would still leave a terminal-attached bootstrap blocked. +mkdir -p "$scratch/codex-install-bin" +( + unset CODEX_NON_INTERACTIVE + export CODEX_TEST_BIN="$scratch/codex-install-bin/codex" + export PATH="$scratch/codex-install-bin:$PATH" + PM=apt + FAILED="" + have() { [ "$1" = codex ] && [ -x "$CODEX_TEST_BIN" ]; } + add_path() { :; } + curl() { + cat <<'EOF' +set -eu +[ "${CODEX_NON_INTERACTIVE:-0}" = 1 ] || exit 1 +printf '#!/bin/sh\nexit 0\n' > "$CODEX_TEST_BIN" +chmod +x "$CODEX_TEST_BIN" +EOF + } + install_codex + [ -x "$CODEX_TEST_BIN" ] || exit 1 + [ -z "$FAILED" ] || exit 1 + [ "${CODEX_NON_INTERACTIVE-unset}" = unset ] || exit 1 + curl() { echo 'unexpected installer download on re-run' >&2; exit 1; } + install_codex + [ -z "$FAILED" ] || exit 1 +) || { + echo "FAIL: Codex installation was not noninteractive or safe to re-run" >&2 + exit 1 +} + # assert_installed must fail for a missing command, and summary must then # return nonzero rather than reporting a clean bootstrap. FAILED=""