From 891d7222fb8bf4631d3e1f3566ec650bf9b443af Mon Sep 17 00:00:00 2001 From: aaddrick Date: Wed, 1 Apr 2026 06:11:56 -0400 Subject: [PATCH] fix: prevent session-start hook from blocking on sudo password Add early exit when all tools are already installed, and use sudo -n (non-interactive) throughout both hook scripts to fail immediately instead of hanging on password prompts. Applies to session-start.sh and install-build-tools.sh. Fixes #359 Co-Authored-By: Claude --- .claude/hooks/install-build-tools.sh | 20 +++++++++++++------- .claude/hooks/session-start.sh | 28 +++++++++++++++++++++------- 2 files changed, 34 insertions(+), 14 deletions(-) diff --git a/.claude/hooks/install-build-tools.sh b/.claude/hooks/install-build-tools.sh index 96a0349..ec5793c 100755 --- a/.claude/hooks/install-build-tools.sh +++ b/.claude/hooks/install-build-tools.sh @@ -35,7 +35,7 @@ install_apt_package() { fi log "Installing $pkg via apt..." - if sudo apt-get install -y -qq "$pkg" >> "$log_file" 2>&1; then + if sudo -n apt-get install -y -qq "$pkg" >> "$log_file" 2>&1; then installed+=("$cmd") return 0 else @@ -60,7 +60,7 @@ install_imagemagick() { fi log 'Installing imagemagick via apt...' - if sudo apt-get install -y -qq imagemagick >> "$log_file" 2>&1; then + if sudo -n apt-get install -y -qq imagemagick >> "$log_file" 2>&1; then installed+=('imagemagick') return 0 else @@ -87,8 +87,8 @@ install_node() { log 'Installing Node.js v20 via NodeSource...' # Add NodeSource repository for Node.js 20 - if curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - >> "$log_file" 2>&1; then - if sudo apt-get install -y -qq nodejs >> "$log_file" 2>&1; then + if curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -n -E bash - >> "$log_file" 2>&1; then + if sudo -n apt-get install -y -qq nodejs >> "$log_file" 2>&1; then installed+=('node') return 0 fi @@ -100,8 +100,14 @@ install_node() { } main() { + # Use sudo -n (non-interactive) to avoid blocking on password + # prompts in contexts where the user can't respond (hooks, etc). log 'Updating apt cache...' - sudo apt-get update -qq >> "$log_file" 2>&1 + if ! sudo -n apt-get update -qq >> "$log_file" 2>&1; then + log 'sudo not available without password, skipping installs' + printf 'Skipped build tool installation (sudo requires password)\n' + return 0 + fi # Extraction tools install_apt_package '7z' 'p7zip-full' @@ -118,8 +124,8 @@ main() { if ! dpkg -l libfuse2 &>/dev/null && ! dpkg -l libfuse2t64 &>/dev/null; then log 'Installing libfuse2 for AppImage support...' # Try libfuse2t64 first (Ubuntu 24.04+), fall back to libfuse2 - if ! sudo apt-get install -y -qq libfuse2t64 >> "$log_file" 2>&1; then - sudo apt-get install -y -qq libfuse2 >> "$log_file" 2>&1 + if ! sudo -n apt-get install -y -qq libfuse2t64 >> "$log_file" 2>&1; then + sudo -n apt-get install -y -qq libfuse2 >> "$log_file" 2>&1 fi installed+=('libfuse2') else diff --git a/.claude/hooks/session-start.sh b/.claude/hooks/session-start.sh index 288a452..5639de6 100755 --- a/.claude/hooks/session-start.sh +++ b/.claude/hooks/session-start.sh @@ -35,7 +35,7 @@ install_apt_package() { fi log "Installing $pkg via apt..." - if sudo apt-get install -y -qq "$pkg" >> "$log_file" 2>&1; then + if sudo -n apt-get install -y -qq "$pkg" >> "$log_file" 2>&1; then installed+=("$cmd") return 0 else @@ -66,7 +66,7 @@ install_actionlint() { return 1 fi - if curl -sL "$url" | sudo tar xz -C /usr/local/bin actionlint; then + if curl -sL "$url" | sudo -n tar xz -C /usr/local/bin actionlint; then installed+=('actionlint') return 0 else @@ -88,13 +88,13 @@ install_gh() { local keyring='/usr/share/keyrings/githubcli-archive-keyring.gpg' if [[ ! -f "$keyring" ]]; then curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \ - | sudo tee "$keyring" > /dev/null + | sudo -n tee "$keyring" > /dev/null printf 'deb [arch=%s signed-by=%s] %s stable main\n' \ "$(dpkg --print-architecture)" \ "$keyring" \ 'https://cli.github.com/packages' \ - | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null - sudo apt-get update -qq >> "$log_file" 2>&1 + | sudo -n tee /etc/apt/sources.list.d/github-cli.list > /dev/null + sudo -n apt-get update -qq >> "$log_file" 2>&1 fi if sudo apt-get install -y -qq gh >> "$log_file" 2>&1; then @@ -108,9 +108,23 @@ install_gh() { } main() { - # Update apt cache once at the start + # Skip everything if all tools are already present + if command -v jq &>/dev/null && command -v shellcheck &>/dev/null \ + && command -v actionlint &>/dev/null && command -v gh &>/dev/null; then + log 'All tools present, skipping install' + printf 'Already present: jq shellcheck actionlint gh\n' + return 0 + fi + + # Update apt cache once before installing missing tools. + # Use sudo -n (non-interactive) to avoid blocking on password + # prompts in contexts where the user can't respond (hooks, etc). log 'Updating apt cache...' - sudo apt-get update -qq >> "$log_file" 2>&1 + if ! sudo -n apt-get update -qq >> "$log_file" 2>&1; then + log 'sudo not available without password, skipping installs' + printf 'Skipped tool installation (sudo requires password)\n' + return 0 + fi # Install critical tools install_apt_package 'jq'