#!/usr/bin/env bash # prereqs.sh — detect distro, install missing prerequisites detect_distro() { if command -v pacman &>/dev/null; then echo "arch"; elif command -v apt-get &>/dev/null; then echo "debian"; elif command -v dnf &>/dev/null; then echo "rhel"; elif command -v yum &>/dev/null; then echo "rhel-yum"; elif command -v zypper &>/dev/null; then echo "suse"; else echo "unknown"; fi } install_pkg() { local pkg="$1" local distro distro="$(detect_distro)" case "$distro" in arch) sudo pacman -Sy --noconfirm "$pkg" ;; debian) sudo apt-get update -qq && sudo apt-get install -y "$pkg" ;; rhel) sudo dnf install -y "$pkg" ;; rhel-yum) sudo yum install -y "$pkg" ;; suse) sudo zypper install -y "$pkg" ;; *) die "Unsupported distro — please install $pkg manually." ;; esac } ensure_git() { if command -v git &>/dev/null; then success "git $(git --version | awk '{print $3}')" return fi warn "git not found." ask_yn _install "Install git now?" "y" if [[ "$_install" != "y" ]]; then die "git is required."; fi gum spin --spinner dot --spinner.foreground "$C_MAUVE" \ --title " Installing git..." --title.foreground "$C_SKY" \ -- bash -c "$(declare -f install_pkg detect_distro); install_pkg git" command -v git &>/dev/null || die "git installation failed." success "git $(git --version | awk '{print $3}')" } ensure_container_runtime() { if command -v podman &>/dev/null; then CONTAINER_CMD="podman" success "podman $(podman --version | awk '{print $3}')" return fi if command -v docker &>/dev/null; then CONTAINER_CMD="docker" success "docker $(docker --version | awk '{print $3}' | tr -d ',')" return fi warn "No container runtime found." echo "" gum style --foreground "$C_SKY" --margin "0 4" \ "podman — recommended (rootless, no daemon)" \ "docker — alternative" echo "" ask_choice _runtime "Which would you like to install?" \ "podman (recommended)" \ "docker" local runtime_choice="$_runtime" case "$runtime_choice" in podman*) _install_podman; CONTAINER_CMD="podman" ;; docker*) _install_docker; CONTAINER_CMD="docker" ;; esac command -v "$CONTAINER_CMD" &>/dev/null \ || die "$CONTAINER_CMD installation failed. Please install manually." success "$CONTAINER_CMD installed" } _install_podman() { local distro distro="$(detect_distro)" gum spin --spinner dot --spinner.foreground "$C_MAUVE" \ --title " Installing podman..." --title.foreground "$C_SKY" \ -- bash -c "$(declare -f install_pkg detect_distro); install_pkg podman" } _install_docker() { local distro distro="$(detect_distro)" case "$distro" in arch) install_pkg docker ;; debian) install_pkg docker.io ;; rhel) install_pkg docker ;; rhel-yum) install_pkg docker ;; suse) install_pkg docker ;; *) die "Unsupported distro — install docker manually." ;; esac sudo systemctl enable --now docker 2>/dev/null || true sudo usermod -aG docker "$USER" 2>/dev/null || true warn "Added $USER to docker group — log out and back in for it to take effect." } ensure_api_key() { if [[ -n "${ANTHROPIC_API_KEY:-}" ]]; then success "ANTHROPIC_API_KEY is set" return fi # Resolve config dir — CLAUDE_CONFIG_DIR overrides default ~/.claude local claude_dir="${CLAUDE_CONFIG_DIR:-$HOME/.claude}" local creds_file="" if [[ -f "$claude_dir/.credentials.json" ]]; then creds_file="$claude_dir/.credentials.json" elif [[ -f "$HOME/.claude.json" ]]; then creds_file="$HOME/.claude.json" elif [[ -f "$claude_dir/.claude.json" ]]; then creds_file="$claude_dir/.claude.json" elif [[ -f "$HOME/.anthropic/.credentials.json" ]]; then creds_file="$HOME/.anthropic/.credentials.json" fi if [[ -n "$creds_file" ]]; then success "Anthropic credentials found ($creds_file)" return fi warn "ANTHROPIC_API_KEY is not set." echo "" gum style --foreground "$C_SKY" --margin "0 4" \ "Claude Code needs an Anthropic API key to run inside the container." \ "Get one at: https://console.anthropic.com/settings/api-keys" echo "" local key key=$(gum input \ --password \ --placeholder "sk-ant-..." \ --prompt " › " \ --prompt.foreground "$C_MAUVE" \ --cursor.foreground "$C_MAUVE" \ --header " Anthropic API key" \ --header.foreground "$C_SKY" \ --width 70) || true if [[ -z "$key" ]]; then warn "No API key entered — set ANTHROPIC_API_KEY before running ./start.sh" return fi export ANTHROPIC_API_KEY="$key" success "ANTHROPIC_API_KEY set for this session" ask_yn _save "Save to shell profile (~/.zshrc / ~/.bashrc)?" "y" if [[ "$_save" == "y" ]]; then local profile if [[ "$SHELL" == */zsh ]]; then profile="$HOME/.zshrc" else profile="$HOME/.bashrc" fi if grep -q "ANTHROPIC_API_KEY" "$profile" 2>/dev/null; then warn "ANTHROPIC_API_KEY already in $profile — not adding again." else printf '\nexport ANTHROPIC_API_KEY="%s"\n' "$key" >> "$profile" success "Saved to $profile" fi fi } check_prerequisites() { header "Prerequisites" ensure_git ensure_container_runtime ensure_api_key }