Skip to content

Instantly share code, notes, and snippets.

@jeffscottward
Last active January 26, 2026 15:25
Show Gist options
  • Select an option

  • Save jeffscottward/ae7d7ea9cf02708be95072a0cd8686c4 to your computer and use it in GitHub Desktop.

Select an option

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
#!/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