Last active
January 26, 2026 15:25
-
-
Save jeffscottward/ae7d7ea9cf02708be95072a0cd8686c4 to your computer and use it in GitHub Desktop.
One-command Mac setup for Claude Code - installs Homebrew, Oh My Zsh, NVM, Node.js LTS, Git, and Claude Code CLI with plugins
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # ============================================================================= | |
| # Mac Development Setup for Claude Code | |
| # ============================================================================= | |
| # This script installs everything you need to start using Claude Code on a Mac. | |
| # Just copy and paste this entire script into Terminal and press Enter! | |
| # | |
| # What gets installed: | |
| # - Homebrew (Mac package manager) | |
| # - Git (version control) | |
| # - Oh My Zsh (better terminal experience) | |
| # - Oh My Posh (beautiful terminal prompt with agnoster theme) | |
| # - NVM (Node version manager) | |
| # - Node.js LTS (JavaScript runtime) | |
| # - Python 3 (latest version) | |
| # - uv/uvx (fast Python package manager) | |
| # - Claude Code CLI (AI coding assistant) | |
| # - agent-browser (browser automation for AI agents) | |
| # - Useful plugins and skills for Claude Code | |
| # ============================================================================= | |
| set -e # Exit on any error | |
| # Colors for pretty output | |
| RED='\033[0;31m' | |
| GREEN='\033[0;32m' | |
| YELLOW='\033[1;33m' | |
| BLUE='\033[0;34m' | |
| PURPLE='\033[0;35m' | |
| CYAN='\033[0;36m' | |
| NC='\033[0m' # No Color | |
| # Helper functions | |
| print_header() { | |
| echo "" | |
| echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" | |
| echo -e "${PURPLE} $1${NC}" | |
| echo -e "${PURPLE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" | |
| echo "" | |
| } | |
| print_step() { | |
| echo -e "${CYAN}==>${NC} ${GREEN}$1${NC}" | |
| } | |
| print_info() { | |
| echo -e "${BLUE} $1${NC}" | |
| } | |
| print_success() { | |
| echo -e "${GREEN}[OK]${NC} $1" | |
| } | |
| print_warning() { | |
| echo -e "${YELLOW}[!]${NC} $1" | |
| } | |
| print_error() { | |
| echo -e "${RED}[ERROR]${NC} $1" | |
| } | |
| # ============================================================================= | |
| # Welcome Message | |
| # ============================================================================= | |
| clear | |
| print_header "Welcome to Mac Dev Setup for Claude Code!" | |
| echo "This script will set up your Mac for development with Claude Code." | |
| echo "It will install several tools - this may take 10-20 minutes." | |
| echo "" | |
| echo "You may be asked for your password once at the beginning." | |
| echo "This is normal - it's needed to install some software." | |
| echo "" | |
| # Pre-authenticate sudo to avoid prompts later | |
| print_step "Requesting admin access (you may need to enter your password)..." | |
| sudo -v | |
| # Keep sudo alive in background | |
| while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null & | |
| # ============================================================================= | |
| # Step 1: Install Xcode Command Line Tools | |
| # ============================================================================= | |
| print_header "Step 1/13: Xcode Command Line Tools" | |
| if xcode-select -p &>/dev/null; then | |
| print_success "Xcode Command Line Tools already installed" | |
| else | |
| print_step "Installing Xcode Command Line Tools..." | |
| # Try the silent software update method first (works on macOS 10.9+) | |
| touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress | |
| PROD=$(softwareupdate -l 2>/dev/null | grep -B 1 "Command Line Tools" | grep -o 'Command Line Tools[^"]*' | head -n 1) | |
| if [[ -n "$PROD" ]]; then | |
| print_info "Installing via Software Update (this may take a few minutes)..." | |
| softwareupdate -i "$PROD" --verbose 2>&1 | while read line; do | |
| echo -ne "\r $line " | |
| done | |
| echo "" | |
| rm -f /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress | |
| else | |
| # Fallback to xcode-select (requires GUI interaction) | |
| print_info "A popup may appear - click 'Install' and wait for it to complete" | |
| xcode-select --install 2>/dev/null || true | |
| # Wait for installation | |
| until xcode-select -p &>/dev/null; do | |
| sleep 5 | |
| done | |
| fi | |
| print_success "Xcode Command Line Tools installed" | |
| fi | |
| # ============================================================================= | |
| # Step 2: Install Homebrew | |
| # ============================================================================= | |
| print_header "Step 2/13: Homebrew (Package Manager)" | |
| if command -v brew &>/dev/null; then | |
| print_success "Homebrew already installed" | |
| print_step "Updating Homebrew..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew update | |
| else | |
| print_step "Installing Homebrew..." | |
| print_info "This is the Mac package manager - it helps install other software" | |
| NONINTERACTIVE=1 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| # Add Homebrew to PATH for Apple Silicon Macs | |
| if [[ $(uname -m) == "arm64" ]]; then | |
| echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofile | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| else | |
| echo 'eval "$(/usr/local/bin/brew shellenv)"' >> ~/.zprofile | |
| eval "$(/usr/local/bin/brew shellenv)" 2>/dev/null || true | |
| fi | |
| print_success "Homebrew installed" | |
| fi | |
| # Ensure brew is in PATH for this session | |
| if [[ $(uname -m) == "arm64" ]]; then | |
| eval "$(/opt/homebrew/bin/brew shellenv)" | |
| else | |
| eval "$(/usr/local/bin/brew shellenv)" 2>/dev/null || true | |
| fi | |
| # ============================================================================= | |
| # Step 3: Install Git | |
| # ============================================================================= | |
| print_header "Step 3/13: Git (Version Control)" | |
| if command -v git &>/dev/null; then | |
| print_success "Git already installed: $(git --version)" | |
| else | |
| print_step "Installing Git..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install git | |
| print_success "Git installed" | |
| fi | |
| # ============================================================================= | |
| # Step 4: Install Oh My Zsh | |
| # ============================================================================= | |
| print_header "Step 4/13: Oh My Zsh (Better Terminal)" | |
| if [[ -d "$HOME/.oh-my-zsh" ]]; then | |
| print_success "Oh My Zsh already installed" | |
| else | |
| print_step "Installing Oh My Zsh..." | |
| print_info "This makes your terminal prettier and easier to use" | |
| sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended | |
| print_success "Oh My Zsh installed" | |
| fi | |
| # ============================================================================= | |
| # Step 5/13: Oh My Posh (Beautiful Terminal Prompt) | |
| # ============================================================================= | |
| print_header "Step 5/13: Oh My Posh (Beautiful Prompt)" | |
| if command -v oh-my-posh &>/dev/null; then | |
| print_success "Oh My Posh already installed" | |
| else | |
| print_step "Installing Oh My Posh..." | |
| print_info "This gives you a beautiful, informative terminal prompt" | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install jandedobbeleer/oh-my-posh/oh-my-posh | |
| print_success "Oh My Posh installed" | |
| fi | |
| # Install Nerd Fonts (required for icons in the prompt) | |
| print_step "Installing Nerd Fonts (for prompt icons)..." | |
| print_info "These fonts include special icons used by Oh My Posh themes" | |
| # Install fonts via Homebrew cask (most reliable method) | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew tap homebrew/cask-fonts 2>/dev/null || true | |
| # Install Meslo (recommended by Oh My Posh), FiraCode, and Hack Nerd Fonts | |
| for font in font-meslo-lg-nerd-font font-fira-code-nerd-font font-hack-nerd-font; do | |
| if brew list --cask $font &>/dev/null; then | |
| print_success "$font already installed" | |
| else | |
| print_info "Installing $font..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install --cask $font 2>/dev/null || print_warning "Could not install $font" | |
| fi | |
| done | |
| print_success "Nerd Fonts installed" | |
| print_info "" | |
| print_info "IMPORTANT: After setup, configure your terminal to use a Nerd Font:" | |
| print_info " - Terminal.app: Preferences > Profiles > Font > 'MesloLGS Nerd Font'" | |
| print_info " - iTerm2: Preferences > Profiles > Text > Font > 'MesloLGS Nerd Font'" | |
| print_info " - VS Code: Settings > Terminal Font Family > 'MesloLGS Nerd Font'" | |
| print_info "" | |
| # Download agnoster theme | |
| print_step "Setting up agnoster theme..." | |
| mkdir -p ~/.config/omp | |
| if [[ ! -f ~/.config/omp/agnoster.omp.json ]]; then | |
| curl -fsSL "https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/agnoster.omp.json" > ~/.config/omp/agnoster.omp.json | |
| print_success "agnoster theme downloaded" | |
| else | |
| print_success "agnoster theme already exists" | |
| fi | |
| # Add Oh My Posh to shell config | |
| if ! grep -q "oh-my-posh init" ~/.zshrc 2>/dev/null; then | |
| cat >> ~/.zshrc << 'EOF' | |
| # Oh My Posh prompt theme | |
| eval "$(oh-my-posh init zsh --config ~/.config/omp/agnoster.omp.json)" | |
| EOF | |
| print_success "Oh My Posh configured in shell" | |
| else | |
| print_success "Oh My Posh already configured in shell" | |
| fi | |
| # ============================================================================= | |
| # Step 6/13: NVM and Node.js | |
| # ============================================================================= | |
| print_header "Step 6/13: NVM and Node.js" | |
| # Install NVM | |
| if [[ -d "$HOME/.nvm" ]]; then | |
| print_success "NVM already installed" | |
| else | |
| print_step "Installing NVM (Node Version Manager)..." | |
| curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash | |
| print_success "NVM installed" | |
| fi | |
| # Load NVM for this session | |
| export NVM_DIR="$HOME/.nvm" | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| # Ensure NVM is in shell config | |
| if ! grep -q 'NVM_DIR' ~/.zshrc 2>/dev/null; then | |
| cat >> ~/.zshrc << 'EOF' | |
| # NVM (Node Version Manager) | |
| export NVM_DIR="$HOME/.nvm" | |
| [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" | |
| [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" | |
| EOF | |
| fi | |
| # Install Node.js LTS | |
| print_step "Installing Node.js LTS..." | |
| nvm install --lts | |
| nvm use --lts | |
| nvm alias default 'lts/*' | |
| print_success "Node.js $(node --version) installed and set as default" | |
| # ============================================================================= | |
| # Step 7/13: Python 3 | |
| # ============================================================================= | |
| print_header "Step 7/13: Python 3" | |
| if command -v python3 &>/dev/null; then | |
| print_success "Python already installed: $(python3 --version)" | |
| else | |
| print_step "Installing Python 3..." | |
| HOMEBREW_NO_AUTO_UPDATE=1 brew install python | |
| print_success "Python installed" | |
| fi | |
| # Add python/pip aliases if not present | |
| if ! grep -q "alias python=" ~/.zshrc 2>/dev/null; then | |
| cat >> ~/.zshrc << 'EOF' | |
| # Python aliases | |
| alias python='python3' | |
| alias pip='pip3' | |
| EOF | |
| print_success "Python aliases configured" | |
| fi | |
| # ============================================================================= | |
| # Step 8/13: uv (Fast Python Package Manager) | |
| # ============================================================================= | |
| print_header "Step 8/13: uv (Fast Python Package Manager)" | |
| if command -v uv &>/dev/null; then | |
| print_success "uv already installed: $(uv --version)" | |
| else | |
| print_step "Installing uv..." | |
| print_info "uv is a blazingly fast Python package manager (includes uvx)" | |
| curl -LsSf https://astral.sh/uv/install.sh | sh | |
| print_success "uv installed" | |
| fi | |
| # Add uv to PATH if not present | |
| if ! grep -q '/.local/bin' ~/.zshrc 2>/dev/null; then | |
| cat >> ~/.zshrc << 'EOF' | |
| # uv/uvx path | |
| export PATH="$HOME/.local/bin:$PATH" | |
| EOF | |
| fi | |
| # Source for current session | |
| export PATH="$HOME/.local/bin:$PATH" | |
| # ============================================================================= | |
| # Step 9/13: Claude Code CLI | |
| # ============================================================================= | |
| print_header "Step 9/13: Claude Code CLI" | |
| if command -v claude &>/dev/null; then | |
| print_success "Claude Code already installed" | |
| print_step "Updating Claude Code..." | |
| npm update -g @anthropic-ai/claude-code | |
| else | |
| print_step "Installing Claude Code..." | |
| print_info "This is your AI coding assistant!" | |
| npm install -g @anthropic-ai/claude-code | |
| print_success "Claude Code installed" | |
| fi | |
| # ============================================================================= | |
| # Step 7: Set up aliases and Claude Code configuration | |
| # ============================================================================= | |
| print_header "Step 10/13: agent-browser (Browser Automation)" | |
| if command -v agent-browser &>/dev/null; then | |
| print_success "agent-browser already installed" | |
| else | |
| print_step "Installing agent-browser..." | |
| print_info "Headless browser automation for AI agents (by Vercel)" | |
| npm install -g agent-browser | |
| print_success "agent-browser installed" | |
| # Install Playwright browsers | |
| print_step "Installing browser engines for agent-browser..." | |
| npx playwright install chromium 2>/dev/null || print_warning "Browser install may need manual run: npx playwright install" | |
| fi | |
| # ============================================================================= | |
| # Step 11/13: Setting Up Aliases & Configuration | |
| # ============================================================================= | |
| print_header "Step 11/13: Setting Up Aliases & Configuration" | |
| # Create Claude directories | |
| mkdir -p ~/.claude/skills | |
| mkdir -p ~/.claude/agents | |
| mkdir -p ~/.claude/commands | |
| mkdir -p ~/.claude/rules | |
| # Add cc alias for Claude Code (with --dangerously-skip-permissions for smoother experience) | |
| if ! grep -q "alias cc=" ~/.zshrc 2>/dev/null; then | |
| print_step "Adding 'cc' alias for Claude Code..." | |
| cat >> ~/.zshrc << 'EOF' | |
| # Claude Code alias - just type 'cc' to start! | |
| # --dangerously-skip-permissions allows Claude to work without constant permission prompts | |
| alias cc='claude --dangerously-skip-permissions' | |
| EOF | |
| print_success "Added 'cc' alias - you can now type 'cc' to start Claude Code" | |
| else | |
| print_success "'cc' alias already configured" | |
| fi | |
| # ============================================================================= | |
| # Step 8: Install Claude Code Plugins and Skills | |
| # ============================================================================= | |
| print_header "Step 12/13: Destructive Command Guard (Security)" | |
| print_step "Installing Destructive Command Guard (dcg)..." | |
| print_info "This blocks dangerous commands like 'rm -rf /' before they execute" | |
| if command -v dcg &>/dev/null; then | |
| print_success "dcg already installed: $(dcg --version 2>/dev/null | head -1)" | |
| else | |
| curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/destructive_command_guard/master/install.sh" | bash -s -- --easy-mode | |
| print_success "dcg installed and configured as Claude Code hook" | |
| fi | |
| # ============================================================================= | |
| # Step 13/13: Installing Plugins & Skills | |
| # ============================================================================= | |
| print_header "Step 13/13: Installing Plugins & Skills" | |
| # Install orchestrating-swarms skill | |
| print_step "Installing orchestrating-swarms skill..." | |
| mkdir -p ~/.claude/skills/orchestrating-swarms | |
| curl -fsSL "https://gist.githubusercontent.com/kieranklaassen/4f2aba89594a4aea4ad64d753984b2ea/raw" > ~/.claude/skills/orchestrating-swarms/SKILL.md | |
| if [[ -f ~/.claude/skills/orchestrating-swarms/SKILL.md ]]; then | |
| print_success "orchestrating-swarms skill installed" | |
| else | |
| print_warning "Could not install orchestrating-swarms skill (you can add it later)" | |
| fi | |
| # Install voice-notify skill | |
| print_step "Installing voice-notify skill..." | |
| mkdir -p ~/.claude/skills/voice-notify | |
| curl -fsSL "https://gist.githubusercontent.com/jeffscottward/8ed4694bc15f85e6df7242bfde60e2dc/raw" > ~/.claude/skills/voice-notify/SKILL.md | |
| if [[ -f ~/.claude/skills/voice-notify/SKILL.md ]]; then | |
| print_success "voice-notify skill installed" | |
| print_info "Claude will speak summaries aloud after responses" | |
| print_info "Say 'quiet voice' to mute, 'voice on' to unmute" | |
| else | |
| print_warning "Could not install voice-notify skill (you can add it later)" | |
| fi | |
| # Set up everything-claude-code plugin | |
| print_step "Configuring everything-claude-code plugin..." | |
| # Create or update settings.json for the plugin | |
| SETTINGS_FILE="$HOME/.claude/settings.json" | |
| if [[ -f "$SETTINGS_FILE" ]]; then | |
| # Check if plugin already configured | |
| if grep -q "everything-claude-code" "$SETTINGS_FILE" 2>/dev/null; then | |
| print_success "everything-claude-code plugin already configured" | |
| else | |
| print_info "Backing up existing settings..." | |
| cp "$SETTINGS_FILE" "${SETTINGS_FILE}.backup" | |
| print_warning "Plugin needs manual setup - run these commands in Claude Code:" | |
| echo "" | |
| echo " /plugin marketplace add affaan-m/everything-claude-code" | |
| echo " /plugin install everything-claude-code@everything-claude-code" | |
| echo "" | |
| fi | |
| else | |
| # Create new settings file with plugin configuration | |
| cat > "$SETTINGS_FILE" << 'EOF' | |
| { | |
| "extraKnownMarketplaces": { | |
| "everything-claude-code": { | |
| "source": { | |
| "source": "github", | |
| "repo": "affaan-m/everything-claude-code" | |
| } | |
| } | |
| }, | |
| "enabledPlugins": { | |
| "everything-claude-code@everything-claude-code": true | |
| } | |
| } | |
| EOF | |
| print_success "everything-claude-code plugin configured" | |
| fi | |
| # ============================================================================= | |
| # Complete! | |
| # ============================================================================= | |
| print_header "Setup Complete!" | |
| echo -e "${GREEN}" | |
| cat << 'EOF' | |
| _____ _ _ _____ _ | |
| / ____| | | | / ____| | | | |
| | | | | __ _ _ _ __| | ___ | | ___ __| | ___ | |
| | | | |/ _` | | | |/ _` |/ _ \| | / _ \ / _` |/ _ \ | |
| | |____| | (_| | |_| | (_| | __/| |___| (_) | (_| | __/ | |
| \_____|_|\__,_|\__,_|\__,_|\___| \_____\___/ \__,_|\___| | |
| EOF | |
| echo -e "${NC}" | |
| echo "Everything is installed! Here's what to do next:" | |
| echo "" | |
| echo -e "${CYAN}1. Set your terminal font to a Nerd Font:${NC}" | |
| echo " - Terminal.app: Preferences > Profiles > Font > 'MesloLGS Nerd Font'" | |
| echo " - iTerm2: Preferences > Profiles > Text > Font > 'MesloLGS Nerd Font'" | |
| echo " - VS Code: Settings > Terminal Font Family > 'MesloLGS Nerd Font'" | |
| echo " (This enables the icons in your prompt)" | |
| echo "" | |
| echo -e "${CYAN}2. Close this Terminal window and open a new one${NC}" | |
| echo " (This loads all the new settings)" | |
| echo "" | |
| echo -e "${CYAN}3. Type 'cc' and press Enter to start Claude Code${NC}" | |
| echo " (The 'cc' alias runs Claude with permissions pre-approved)" | |
| echo "" | |
| echo -e "${CYAN}4. Follow the prompts to log in with your Anthropic account${NC}" | |
| echo "" | |
| echo -e "${CYAN}5. Once logged in, install the full plugin by typing:${NC}" | |
| echo " /plugin marketplace add affaan-m/everything-claude-code" | |
| echo " /plugin install everything-claude-code@everything-claude-code" | |
| echo "" | |
| echo -e "${YELLOW}Installed tools:${NC}" | |
| echo " - Homebrew (brew) - Package manager" | |
| echo " - Git (git) - Version control" | |
| echo " - Oh My Zsh - Better terminal" | |
| echo " - Oh My Posh - Beautiful prompt (agnoster theme)" | |
| echo " - Nerd Fonts - MesloLGS, FiraCode, Hack (for icons)" | |
| echo " - NVM (nvm) - Node version manager" | |
| echo " - Node.js $(node --version 2>/dev/null || echo 'LTS') - JavaScript runtime" | |
| echo " - Python $(python3 --version 2>/dev/null | cut -d' ' -f2 || echo '3.x') - Python runtime" | |
| echo " - uv/uvx - Fast Python package manager" | |
| echo " - Claude Code (cc) - AI coding assistant" | |
| echo " - agent-browser - Browser automation for AI" | |
| echo "" | |
| echo -e "${GREEN}You're all set! Enjoy coding with Claude!${NC}" | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment