#!/usr/bin/env bash ################################################################################ # Claude Code Customizations - Interactive Installer # Step-by-step installation with user choices for each component ################################################################################ set -e # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' MAGENTA='\033[0;35m' CYAN='\033[0;36m' BOLD='\033[1m' NC='\033[0m' # Configuration CLAUDE_DIR="$HOME/.claude" BACKUP_DIR="$HOME/.claude-backup-$(date +%Y%m%d_%H%M%S)" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" # User choices USE_ZAI_MODELS=false INSTALL_AGENTS=true INSTALL_ENGINEERING=true INSTALL_MARKETING=true INSTALL_PRODUCT=true INSTALL_STUDIO_OPS=true INSTALL_PROJECT_MGMT=true INSTALL_TESTING=true INSTALL_DESIGN=true INSTALL_BONUS=true INSTALL_MCP_TOOLS=true INSTALL_VISION_TOOLS=true INSTALL_WEB_TOOLS=true INSTALL_GITHUB_TOOLS=true INSTALL_TLDR=true INSTALL_PLUGINS=true INSTALL_HOOKS=true INSTALL_RALPH=false LAUNCH_CLAUDE=false # Counters SELECTED_AGENTS=0 SELECTED_MCP_TOOLS=0 ################################################################################ # Helper Functions ################################################################################ log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[✓]${NC} $1"; } log_warning() { echo -e "${YELLOW}[!]${NC} $1"; } log_error() { echo -e "${RED}[✗]${NC} $1"; } print_header() { clear echo -e "${CYAN}╔══════════════════════════════════════════════════════════════════╗${NC}" echo -e "${CYAN}║${NC} ${BOLD}Claude Code Customizations - Interactive Installer${NC} ${CYAN}║${NC}" echo -e "${CYAN}╚══════════════════════════════════════════════════════════════════╝${NC}" echo "" } confirm() { local prompt="$1" local default="$2" if [ "$default" = "Y" ]; then prompt="$prompt [Y/n]: " else prompt="$prompt [y/N]: " fi read -p "$prompt" response if [ -z "$response" ]; then if [ "$default" = "Y" ]; then return 0 else return 1 fi fi [[ "$response" =~ ^[Yy]$ ]] } select_multiple() { local title="$1" shift local options=("$@") echo "" echo -e "${BOLD}$title${NC}" echo "─────────────────────────────────────────────────────────────" echo "" local i=1 for opt in "${options[@]}"; do echo " $i) $opt" i=$((i+1)) done echo " a) All" echo " n) None" echo "" while true; do read -p "Select options (comma-separated, a=n): " selection if [[ "$selection" =~ ^[Aa]$ ]]; then return 0 # All elif [[ "$selection" =~ ^[Nn]$ ]]; then return 1 # None else return 0 # Has selections fi done } ################################################################################ # Welcome Screen ################################################################################ show_welcome() { print_header echo -e "${BOLD}Welcome to Claude Code Customizations Installer!${NC}" echo "" echo "This installer will guide you through setting up a customized" echo "Claude Code environment with:" echo "" echo " • 40+ specialized agents for development, marketing, and operations" echo " • MCP tools for vision analysis, web search, and GitHub integration" echo " • Custom skills and plugins" echo " • Optimized workflows for rapid 6-day development cycles" echo "" echo -e "${YELLOW}Note:${NC} You can choose what to install at each step." echo "" if ! confirm "Continue with installation?" "Y"; then echo "Installation cancelled." exit 0 fi } ################################################################################ # Model Selection ################################################################################ select_model() { print_header echo -e "${BOLD}Step 1: Model Selection${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "Choose which API models to use with Claude Code:" echo "" echo -e " ${GREEN}1${NC}) ${BOLD}Anthropic Claude Models${NC} (official)" echo " • claude-sonnet-4.5, claude-opus-4.5, etc." echo " • Direct Anthropic API" echo " • Base URL: https://api.anthropic.com" echo "" echo -e " ${CYAN}2${NC}) ${BOLD}Z.AI / GLM Coding Plan Models${NC}" echo " • Same Claude models via Z.AI platform" echo " • Additional features: usage tracking, feedback, promotions" echo " • Base URL: https://api.z.ai/api/anthropic" echo " • Includes: 旺仔牛奶 rewards program" echo "" read -p "Select model provider [1/2]: " model_choice case $model_choice in 2) USE_ZAI_MODELS=true log_success "Selected: Z.AI / GLM Coding Plan Models" ;; *) USE_ZAI_MODELS=false log_success "Selected: Anthropic Claude Models (official)" ;; esac echo "" } ################################################################################ # Agent Selection ################################################################################ select_agents() { print_header echo -e "${BOLD}Step 2: Agent Categories${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "Custom agents provide specialized assistance for different tasks." echo "Select which categories to install:" echo "" if confirm "Install Engineering agents? (AI engineer, frontend/backend dev, DevOps, mobile, rapid prototyper, test writer)" "Y"; then INSTALL_ENGINEERING=true SELECTED_AGENTS=$((SELECTED_AGENTS + 7)) else INSTALL_ENGINEERING=false fi if confirm "Install Marketing agents? (TikTok strategist, growth hacker, content creator, Instagram/Reddit/Twitter)" "Y"; then INSTALL_MARKETING=true SELECTED_AGENTS=$((SELECTED_AGENTS + 7)) else INSTALL_MARKETING=false fi if confirm "Install Product agents? (Sprint prioritizer, feedback synthesizer, trend researcher)" "Y"; then INSTALL_PRODUCT=true SELECTED_AGENTS=$((SELECTED_AGENTS + 3)) else INSTALL_PRODUCT=false fi if confirm "Install Studio Operations agents? (Studio producer, project shipper, analytics, finance, legal, support, coach)" "Y"; then INSTALL_STUDIO_OPS=true SELECTED_AGENTS=$((SELECTED_AGENTS + 8)) else INSTALL_STUDIO_OPS=false fi if confirm "Install Project Management agents? (Experiment tracker, studio producer, project shipper)" "Y"; then INSTALL_PROJECT_MGMT=true SELECTED_AGENTS=$((SELECTED_AGENTS + 3)) else INSTALL_PROJECT_MGMT=false fi if confirm "Install Testing agents? (Test writer/fixer, API tester, performance benchmarker, workflow optimizer)" "Y"; then INSTALL_TESTING=true SELECTED_AGENTS=$((SELECTED_AGENTS + 5)) else INSTALL_TESTING=false fi if confirm "Install Design agents? (UI/UX designer, brand guardian, visual storyteller, whimsy injector)" "Y"; then INSTALL_DESIGN=true SELECTED_AGENTS=$((SELECTED_AGENTS + 5)) else INSTALL_DESIGN=false fi if confirm "Install Bonus agents? (Joker, studio coach)" "Y"; then INSTALL_BONUS=true SELECTED_AGENTS=$((SELECTED_AGENTS + 2)) else INSTALL_BONUS=false fi if [ $SELECTED_AGENTS -eq 0 ]; then log_warning "No agents selected - you can add them later manually" else log_success "Selected $SELECTED_AGENTS agents across multiple categories" fi echo "" } ################################################################################ # MCP Tools Selection ################################################################################ select_mcp_tools() { print_header echo -e "${BOLD}Step 3: MCP Tools${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "MCP (Model Context Protocol) tools provide advanced capabilities." echo "Select which tools to install:" echo "" if confirm "Install Vision Analysis tools? (images, videos, UI screenshots, error diagnosis, data visualization, diagrams)" "Y"; then INSTALL_VISION_TOOLS=true SELECTED_MCP_TOOLS=$((SELECTED_MCP_TOOLS + 8)) else INSTALL_VISION_TOOLS=false fi if confirm "Install Web Search tool? (enhanced search with domain filtering, time-based results)" "Y"; then INSTALL_WEB_TOOLS=true SELECTED_MCP_TOOLS=$((SELECTED_MCP_TOOLS + 1)) else INSTALL_WEB_TOOLS=false fi if confirm "Install Web Reader tool? (fetch URLs, convert to markdown)" "Y"; then INSTALL_WEB_TOOLS=true SELECTED_MCP_TOOLS=$((SELECTED_MCP_TOOLS + 1)) fi if confirm "Install GitHub Reader tool? (read repos, search docs/issues/commits)" "Y"; then INSTALL_GITHUB_TOOLS=true SELECTED_MCP_TOOLS=$((SELECTED_MCP_TOOLS + 3)) else INSTALL_GITHUB_TOOLS=false fi if command -v python3 &> /dev/null && command -v pip3 &> /dev/null; then if confirm "Install TLDR Code Analysis? (95% token reduction, semantic search, program slicing - requires Python)" "Y"; then INSTALL_TLDR=true SELECTED_MCP_TOOLS=$((SELECTED_MCP_TOOLS + 18)) else INSTALL_TLDR=false fi else log_warning "Python/pip3 not found - skipping TLDR Code Analysis" INSTALL_TLDR=false fi if [ $SELECTED_MCP_TOOLS -eq 0 ]; then log_warning "No MCP tools selected" else log_success "Selected $SELECTED_MCP_TOOLS MCP tools" fi INSTALL_MCP_TOOLS=true echo "" } ################################################################################ # Plugins Selection ################################################################################ select_plugins() { print_header echo -e "${BOLD}Step 4: Plugins & Skills${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "Plugins extend Claude Code with additional features:" echo "" echo " • glm-plan-bug: Submit bug/issue feedback to Z.AI" echo " • glm-plan-usage: Query your GLM Coding Plan usage statistics" echo "" if confirm "Install Z.AI plugins?" "Y"; then INSTALL_PLUGINS=true log_success "Plugins selected" else INSTALL_PLUGINS=false log_warning "Plugins skipped" fi echo "" } ################################################################################ # Hooks Selection ################################################################################ select_hooks() { print_header echo -e "${BOLD}Step 5: Hooks${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "Hooks are scripts that run automatically on specific events." echo "Do you want to copy existing hooks from the package?" echo "" if confirm "Install hooks?" "N"; then INSTALL_HOOKS=true log_success "Hooks selected" else INSTALL_HOOKS=false log_warning "Hooks skipped" fi echo "" } ################################################################################ # Ralph Selection ################################################################################ select_ralph() { print_header echo -e "${BOLD}Step 6: Ralph CLI (Advanced - Optional)${NC}" echo "═══════════════════════════════════════════════════════════" echo "" echo "Ralph CLI provides autonomous agent looping (infinite iterations" echo "until task completion). This is an ADVANCED feature for complex" echo "multi-step workflows." echo "" echo " ${CYAN}• PROACTIVELY agents${NC}: Quick, single-pass coordination (built-in)" echo " ${CYAN}• Ralph CLI${NC}: Autonomous looping, stateful, requires installation" echo "" echo "See Step 6 in MASTER-PROMPT.md for full details." echo "" if confirm "Install Ralph CLI for autonomous looping? (Optional)" "N"; then INSTALL_RALPH=true log_success "Ralph CLI selected" else INSTALL_RALPH=false log_warning "Ralph CLI skipped (using built-in PROACTIVELY agents)" fi echo "" } ################################################################################ # Prerequisites Check ################################################################################ check_prerequisites() { print_header echo -e "${BOLD}Step 7: Prerequisites Check${NC}" echo "═══════════════════════════════════════════════════════════" echo "" local errors=0 # Check Node.js if command -v node &> /dev/null; then NODE_VERSION=$(node -v) log_success "Node.js installed: $NODE_VERSION" else log_error "Node.js not found" errors=$((errors+1)) fi # Check npm if command -v npm &> /dev/null; then NPM_VERSION=$(npm -v) log_success "npm installed: $NPM_VERSION" else log_error "npm not found" errors=$((errors+1)) fi # Check python3 if command -v python3 &> /dev/null; then PYTHON_VERSION=$(python3 --version) log_success "Python installed: $PYTHON_VERSION" else log_warning "Python3 not found (optional)" fi # Check npx if command -v npx &> /dev/null; then log_success "npx available" else log_warning "npx not found (will be installed with npm)" fi echo "" if [ $errors -gt 0 ]; then log_error "Some prerequisites are missing. Please install them and try again." echo "" echo "Install Node.js: https://nodejs.org/" echo "Or use nvm: curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash" echo "" exit 1 fi log_success "Prerequisites check passed" echo "" sleep 1 } ################################################################################ # Claude Code Installation ################################################################################ install_claude_code() { print_header echo -e "${BOLD}Step 8: Claude Code Installation${NC}" echo "═══════════════════════════════════════════════════════════" echo "" # Check if Claude Code is installed if command -v claude-code &> /dev/null; then log_success "Claude Code is already installed" claude-code --version 2>/dev/null || log_info "Version: unknown" echo "" return fi echo -e "${YELLOW}Claude Code is not installed on this system.${NC}" echo "" echo "Claude Code is Anthropic's official CLI for Claude." echo "You need it to use these customizations." echo "" echo "Installation options:" echo "" echo -e " ${GREEN}1${NC}) ${BOLD}Install via npm (recommended)${NC}" echo " • Requires Node.js 14+" echo " • Command: npm install -g @anthropic-ai/claude-code" echo " • Fastest method" echo "" echo -e " ${GREEN}2${NC}) ${BOLD}Install via curl (alternative)${NC}" echo " • Downloads standalone binary" echo " • No Node.js required" echo "" echo -e " ${GREEN}3${NC}) ${BOLD}Manual installation${NC}" echo " • Visit: https://claude.ai/download" echo " • Choose your platform" echo "" echo -e " ${YELLOW}0${NC}) Skip installation" echo "" read -p "Select installation method [1/2/3/0]: " install_choice case $install_choice in 1) echo "" log_info "Installing Claude Code via npm..." echo "" if command -v npm &> /dev/null; then npm install -g @anthropic-ai/claude-code if command -v claude-code &> /dev/null; then log_success "Claude Code installed successfully!" echo "" claude-code --version 2>/dev/null || true else log_error "Installation failed. Please try manual installation." fi else log_error "npm not found. Please install Node.js first." echo "Visit: https://nodejs.org/" fi ;; 2) echo "" log_info "Installing Claude Code via curl..." echo "" if command -v curl &> /dev/null; then # Detect OS and architecture OS="$(uname -s)" ARCH="$(uname -m)" case "$OS" in Linux) if [ "$ARCH" = "x86_64" ]; then curl -L https://claude.ai/download/claude-code-linux -o /tmp/claude-code sudo mv /tmp/claude-code /usr/local/bin/claude-code sudo chmod +x /usr/local/bin/claude-code log_success "Claude Code installed!" else log_error "Unsupported architecture: $ARCH" fi ;; Darwin) if [ "$ARCH" = "arm64" ]; then curl -L https://claude.ai/download/claude-code-mac-arm -o /tmp/claude-code else curl -L https://claude.ai/download/claude-code-mac -o /tmp/claude-code fi sudo mv /tmp/claude-code /usr/local/bin/claude-code sudo chmod +x /usr/local/bin/claude-code log_success "Claude Code installed!" ;; *) log_error "Unsupported OS: $OS" ;; esac else log_error "curl not found. Please install curl or use npm method." fi ;; 3) echo "" log_info "Please visit https://claude.ai/download to install Claude Code manually" echo "" echo "After installation, run this script again." echo "" exit 0 ;; 0) log_warning "Skipping Claude Code installation" log_warning "You will need to install it manually to use these customizations" ;; *) log_error "Invalid choice" ;; esac echo "" sleep 2 } ################################################################################ # Backup Existing Configuration ################################################################################ backup_config() { if [ -d "$CLAUDE_DIR" ]; then print_header echo -e "${BOLD}Step 8: Backup${NC}" echo "═══════════════════════════════════════════════════════════" echo "" log_info "Existing Claude Code configuration found" log_info "Creating backup at: $BACKUP_DIR" echo "" cp -r "$CLAUDE_DIR" "$BACKUP_DIR" log_success "Backup created successfully" echo "" sleep 1 fi } ################################################################################ # Installation ################################################################################ create_directories() { log_info "Creating directory structure..." mkdir -p "$CLAUDE_DIR"/{agents,plugins/cache,plugins/marketplaces,hooks,debug,file-history,paste-cache,projects,session-env,shell-snapshots,todos} if [ "$INSTALL_ENGINEERING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/engineering"; fi if [ "$INSTALL_MARKETING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/marketing"; fi if [ "$INSTALL_PRODUCT" = true ]; then mkdir -p "$CLAUDE_DIR/agents/product"; fi if [ "$INSTALL_STUDIO_OPS" = true ]; then mkdir -p "$CLAUDE_DIR/agents/studio-operations"; fi if [ "$INSTALL_PROJECT_MGMT" = true ]; then mkdir -p "$CLAUDE_DIR/agents/project-management"; fi if [ "$INSTALL_TESTING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/testing"; fi if [ "$INSTALL_DESIGN" = true ]; then mkdir -p "$CLAUDE_DIR/agents/design"; fi if [ "$INSTALL_BONUS" = true ]; then mkdir -p "$CLAUDE_DIR/agents/bonus"; fi log_success "Directories created" } fetch_latest_agents() { log_info "Checking for agent updates from GitHub..." local GITHUB_REPO="https://github.com/contains-studio/agents" local TEMP_AGENT_DIR="/tmp/claude-agents-latest-$RANDOM" local UPDATE_FOUND=false # Create temp directory mkdir -p "$TEMP_AGENT_DIR" # Try to clone using git if command -v git &> /dev/null; then if git clone --depth 1 --quiet "$GITHUB_REPO" "$TEMP_AGENT_DIR" 2>/dev/null; then UPDATE_FOUND=true log_success "Fetched latest agents from GitHub" # Copy updated agents to source directory for category in engineering marketing product studio-operations project-management testing design bonus; do if [ -d "$TEMP_AGENT_DIR/$category" ]; then mkdir -p "$SCRIPT_DIR/agents/$category" cp -f "$TEMP_AGENT_DIR/$category"/*.md "$SCRIPT_DIR/agents/$category/" 2>/dev/null || true fi done # Update README if present if [ -f "$TEMP_AGENT_DIR/README.md" ]; then cp -f "$TEMP_AGENT_DIR/README.md" "$SCRIPT_DIR/agents/README.md" 2>/dev/null || true fi log_info "Local agents updated from GitHub" else log_warning "Failed to fetch from GitHub (using local agents)" fi else log_warning "Git not found (using local agents)" fi # Cleanup rm -rf "$TEMP_AGENT_DIR" return 0 } install_agents() { if [ $SELECTED_AGENTS -eq 0 ]; then return fi log_info "Installing agents..." local source_agents="$SCRIPT_DIR/agents" if [ ! -d "$source_agents" ]; then log_warning "Agent source directory not found at $source_agents" log_warning "Please ensure you're running this from the correct location" return fi if [ "$INSTALL_ENGINEERING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/engineering" cp -r "$source_agents/engineering/"*.md "$CLAUDE_DIR/agents/engineering/" 2>/dev/null || true fi if [ "$INSTALL_MARKETING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/marketing" cp -r "$source_agents/marketing/"*.md "$CLAUDE_DIR/agents/marketing/" 2>/dev/null || true fi if [ "$INSTALL_PRODUCT" = true ]; then mkdir -p "$CLAUDE_DIR/agents/product" cp -r "$source_agents/product/"*.md "$CLAUDE_DIR/agents/product/" 2>/dev/null || true fi if [ "$INSTALL_STUDIO_OPS" = true ]; then mkdir -p "$CLAUDE_DIR/agents/studio-operations" cp -r "$source_agents/studio-operations/"*.md "$CLAUDE_DIR/agents/studio-operations/" 2>/dev/null || true fi if [ "$INSTALL_PROJECT_MGMT" = true ]; then mkdir -p "$CLAUDE_DIR/agents/project-management" cp -r "$source_agents/project-management/"*.md "$CLAUDE_DIR/agents/project-management/" 2>/dev/null || true fi if [ "$INSTALL_TESTING" = true ]; then mkdir -p "$CLAUDE_DIR/agents/testing" cp -r "$source_agents/testing/"*.md "$CLAUDE_DIR/agents/testing/" 2>/dev/null || true fi if [ "$INSTALL_DESIGN" = true ]; then mkdir -p "$CLAUDE_DIR/agents/design" cp -r "$source_agents/design/"*.md "$CLAUDE_DIR/agents/design/" 2>/dev/null || true fi if [ "$INSTALL_BONUS" = true ]; then mkdir -p "$CLAUDE_DIR/agents/bonus" cp -r "$source_agents/bonus/"*.md "$CLAUDE_DIR/agents/bonus/" 2>/dev/null || true log_info "Installing agent-updater for automatic sync..." fi # Install sync-agents.sh script if [ -f "$SCRIPT_DIR/sync-agents.sh" ]; then log_info "Installing sync-agents.sh script..." cp "$SCRIPT_DIR/sync-agents.sh" "$CLAUDE_DIR/sync-agents.sh" chmod +x "$CLAUDE_DIR/sync-agents.sh" log_success "sync-agents.sh installed (run: ~/.claude/sync-agents.sh)" fi log_success "Agents installed: $SELECTED_AGENTS" } install_settings() { log_info "Configuring settings..." local settings_file="$CLAUDE_DIR/settings.json" # Determine API base URL and help text if [ "$USE_ZAI_MODELS" = true ]; then API_BASE="https://api.z.ai/api/anthropic" API_NAME="Z.AI / GLM Coding Plan" API_HELP="Get your API key from: https://z.ai/ (Official docs: https://docs.z.ai/devpack/tool/claude)" API_TOKEN_NAME="Z.AI API Key" else API_BASE="https://api.anthropic.com" API_NAME="Anthropic Claude" API_HELP="Get your API key from: https://console.anthropic.com/" API_TOKEN_NAME="Anthropic API Key" fi echo "" echo -e "${CYAN}API Configuration${NC}" echo "─────────────────────────────────────────────────────────────" echo " Provider: $API_NAME" echo " Base URL: $API_BASE" echo "" echo -e "${YELLOW}$API_HELP${NC}" echo "" # Check if settings.json exists if [ -f "$settings_file" ]; then log_warning "settings.json already exists" if confirm "Keep existing API token?" "Y"; then log_info "Preserving existing configuration" else echo "" read -p "Enter your $API_TOKEN_NAME: " API_TOKEN while [ -z "$API_TOKEN" ]; do echo -e "${RED}API token cannot be empty${NC}" read -p "Enter your $API_TOKEN_NAME: " API_TOKEN done # Update existing file if [ "$USE_ZAI_MODELS" = true ]; then cat > "$settings_file" << EOF { "env": { "ANTHROPIC_AUTH_TOKEN": "$API_TOKEN", "ANTHROPIC_BASE_URL": "$API_BASE", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.5-air", "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.7", "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.7" }, "enabledPlugins": {} } EOF else cat > "$settings_file" << EOF { "env": { "ANTHROPIC_AUTH_TOKEN": "$API_TOKEN", "ANTHROPIC_BASE_URL": "$API_BASE", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" }, "enabledPlugins": {} } EOF fi log_success "API token updated" fi else read -p "Enter your $API_TOKEN_NAME: " API_TOKEN while [ -z "$API_TOKEN" ]; do echo -e "${RED}API token cannot be empty${NC}" read -p "Enter your $API_TOKEN_NAME: " API_TOKEN done if [ "$USE_ZAI_MODELS" = true ]; then cat > "$settings_file" << EOF { "env": { "ANTHROPIC_AUTH_TOKEN": "$API_TOKEN", "ANTHROPIC_BASE_URL": "$API_BASE", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.5-air", "ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.7", "ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.7" }, "enabledPlugins": {} } EOF else cat > "$settings_file" << EOF { "env": { "ANTHROPIC_AUTH_TOKEN": "$API_TOKEN", "ANTHROPIC_BASE_URL": "$API_BASE", "API_TIMEOUT_MS": "3000000", "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1" }, "enabledPlugins": {} } EOF fi log_success "API token configured" fi # Add plugins to enabledPlugins if selected if [ "$INSTALL_PLUGINS" = true ]; then if [ "$USE_ZAI_MODELS" = true ]; then # Add Z.AI plugins if command -v jq &> /dev/null; then temp=$(mktemp) jq '.enabledPlugins += {"glm-plan-bug@zai-coding-plugins": true, "glm-plan-usage@zai-coding-plugins": true}' "$settings_file" > "$temp" mv "$temp" "$settings_file" log_success "Z.AI plugins enabled" else log_warning "jq not found, plugins not added to settings" fi fi fi log_success "Settings configured for $API_NAME" # Version verification and Z.AI documentation reference if [ "$USE_ZAI_MODELS" = true ]; then echo "" echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" echo -e "${BOLD}Z.AI GLM Configuration${NC}" echo -e "${CYAN}═══════════════════════════════════════════════════════════════${NC}" echo "" echo -e "${GREEN}✓ GLM Models Configured:${NC}" echo " • glm-4.5-air (Haiku equivalent - fast, efficient)" echo " • glm-4.7 (Sonnet/Opus equivalent - high quality)" echo "" echo -e "${YELLOW}📖 Official Documentation:${NC}" echo " https://docs.z.ai/devpack/tool/claude" echo "" echo -e "${YELLOW}🔍 Verify Installation:${NC}" echo " 1. Check version: ${CYAN}claude --version${NC} (recommended: 2.0.14+)" echo " 2. Start Claude: ${CYAN}claude${NC}" echo " 3. Check status: ${CYAN}/status${NC} (when prompted)" echo "" echo -e "${YELLOW}🔧 Troubleshooting:${NC}" echo " • Close all Claude Code windows and reopen" echo " • Or delete ~/.claude/settings.json and reconfigure" echo " • Verify JSON format is correct (no missing/extra commas)" echo "" fi } install_local_settings() { log_info "Configuring permissions..." local local_settings="$CLAUDE_DIR/settings.local.json" cat > "$local_settings" << 'EOF' { "permissions": { "allow": [ "Bash(npm install:*)", "Bash(npm run content:*)", "Bash(npm run build:*)", "Bash(grep:*)", "Bash(find:*)", "Bash(for:*)", "Bash(do sed:*)", "Bash(done)", "Bash(python3:*)", "Bash(while read f)", "Bash(do echo \"$f%-* $f\")", "Bash(ls:*)", "Bash(node:*)", "Bash(pm2 delete:*)", "Bash(pm2 start npm:*)", "Bash(pm2 save:*)" ] } } EOF log_success "Permissions configured" } install_mcp_config() { if [ "$INSTALL_MCP_TOOLS" = false ] && [ "$INSTALL_TLDR" = false ]; then return fi log_info "Creating MCP server configuration..." local mcp_config="$CLAUDE_DIR/claude_desktop_config.json" local config_needed=false # Check if any MCP tools need configuration if [ "$INSTALL_VISION_TOOLS" = true ] || [ "$INSTALL_WEB_TOOLS" = true ] || [ "$INSTALL_GITHUB_TOOLS" = true ] || [ "$INSTALL_TLDR" = true ]; then config_needed=true fi if [ "$config_needed" = false ]; then return fi # Start building MCP config local mcp_servers="{" # Add vision tools if [ "$INSTALL_VISION_TOOLS" = true ]; then mcp_servers="${mcp_servers} \"zai-vision\": { \"command\": \"npx\", \"args\": [\"@z_ai/mcp-server\"] }," fi # Add web search tool if [ "$INSTALL_WEB_TOOLS" = true ]; then mcp_servers="${mcp_servers} \"web-search-prime\": { \"command\": \"npx\", \"args\": [\"@z_ai/coding-helper\"], \"env\": { \"TOOL\": \"web-search-prime\" } }, \"web-reader\": { \"command\": \"npx\", \"args\": [\"@z_ai/coding-helper\"], \"env\": { \"TOOL\": \"web-reader\" } }," fi # Add GitHub tool if [ "$INSTALL_GITHUB_TOOLS" = true ]; then mcp_servers="${mcp_servers} \"github-reader\": { \"command\": \"npx\", \"args\": [\"@z_ai/coding-helper\"], \"env\": { \"TOOL\": \"github-reader\" } }," fi # Add TLDR (remove trailing comma before closing) if [ "$INSTALL_TLDR" = true ]; then # Remove trailing comma from previous entry if exists mcp_servers="${mcp_servers%,}" mcp_servers="${mcp_servers} , \"tldr\": { \"command\": \"tldr-mcp\", \"args\": [\"--project\", \".\"] }" fi # Remove trailing comma if exists mcp_servers="${mcp_servers%,}" # Close JSON mcp_servers="${mcp_servers} }" # Write config file cat > "$mcp_config" << EOF { "mcpServers": $(echo "$mcp_servers") } EOF log_success "MCP server configuration created" } install_mcp_tools() { if [ "$INSTALL_MCP_TOOLS" = false ]; then return fi log_info "Installing MCP tools..." # Install @z_ai/mcp-server if vision tools selected if [ "$INSTALL_VISION_TOOLS" = true ]; then if command -v npm &> /dev/null; then npm install -g @z_ai/mcp-server 2>/dev/null || { log_warning "Global install failed, will use npx" } log_success "Vision MCP tools installed" fi fi # Install @z_ai/coding-helper for web/GitHub tools if [ "$INSTALL_WEB_TOOLS" = true ] || [ "$INSTALL_GITHUB_TOOLS" = true ]; then npm install -g @z_ai/coding-helper 2>/dev/null || { log_warning "Global install failed, will use npx" } log_success "Web/GitHub MCP tools installed" fi # Install llm-tldr for code analysis if [ "$INSTALL_TLDR" = true ]; then if command -v pip3 &> /dev/null; then pip3 install llm-tldr 2>/dev/null || { log_warning "pip3 install failed, trying pip" pip install llm-tldr 2>/dev/null || { log_error "Failed to install llm-tldr" log_info "Install manually: pip install llm-tldr" } } log_success "TLDR code analysis installed" # Initialize TLDR for current directory if it's a git repo if [ -d .git ] || git rev-parse --git-dir > /dev/null 2>&1; then log_info "Initializing TLDR for current directory..." tldr warm . 2>/dev/null || { log_warning "TLDR initialization failed - run 'tldr warm .' manually" } log_success "TLDR initialized for codebase" fi else log_warning "pip3 not found - skipping TLDR installation" fi fi log_success "MCP tools configured: $SELECTED_MCP_TOOLS" } install_plugins() { if [ "$INSTALL_PLUGINS" = false ]; then return fi log_info "Installing plugins..." # Create plugin registry mkdir -p "$CLAUDE_DIR/plugins/cache/zai-coding-plugins"/{glm-plan-bug,glm-plan-usage} local installed_plugins="$CLAUDE_DIR/plugins/installed_plugins.json" if [ "$USE_ZAI_MODELS" = true ]; then cat > "$installed_plugins" << EOF { "version": 2, "plugins": { "glm-plan-bug@zai-coding-plugins": [ { "scope": "user", "installPath": "$CLAUDE_DIR/plugins/cache/zai-coding-plugins/glm-plan-bug/0.0.1", "version": "0.0.1", "installedAt": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)", "lastUpdated": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" } ], "glm-plan-usage@zai-coding-plugins": [ { "scope": "user", "installPath": "$CLAUDE_DIR/plugins/cache/zai-coding-plugins/glm-plan-usage/0.0.1", "version": "0.0.1", "installedAt": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)", "lastUpdated": "$(date -u +%Y-%m-%dT%H:%M:%S.000Z)" } ] } } EOF fi log_success "Plugins installed" } install_hooks() { if [ "$INSTALL_HOOKS" = false ]; then return fi local source_hooks="$SCRIPT_DIR/claude-complete-package/hooks" if [ -d "$source_hooks" ] && [ "$(ls -A $source_hooks 2>/dev/null)" ]; then log_info "Installing hooks..." cp -r "$source_hooks/"* "$CLAUDE_DIR/hooks/" 2>/dev/null || true log_success "Hooks installed" fi } ################################################################################ # Ralph CLI Installation ################################################################################ install_ralph() { if [ "$INSTALL_RALPH" = false ]; then return fi log_info "Installing Ralph CLI..." # Check if npm is available if ! command -v npm &> /dev/null; then log_error "npm not found. Cannot install Ralph CLI." return fi # Install Ralph CLI globally if npm install -g @iannuttall/ralph 2>/dev/null; then log_success "Ralph CLI installed via npm" else log_warning "Ralph CLI installation failed. You can install manually later: npm install -g @iannuttall/ralph" return fi # Create hooks directory mkdir -p "$CLAUDE_DIR/hooks" # Create ralph-auto-trigger.sh script log_info "Creating Ralph auto-trigger hook..." cat > "$CLAUDE_DIR/hooks/ralph-auto-trigger.sh" << 'RALPH_HOOK_EOF' #!/bin/bash # Ralph Auto-Trigger Hook # Detects agent requests and manages Ralph state for autonomous looping STATE_FILE="$HOME/.claude/ralph-loop.local.md" RALPH_MODE="${RALPH_AUTO_MODE:-agents}" # Options: always, agents, off # Agent detection list (lowercase for matching) AGENTS=( "ai-engineer" "backend-architect" "devops-automator" "frontend-developer" "mobile-app-builder" "rapid-prototyper" "test-writer-fixer" "tiktok-strategist" "growth-hacker" "content-creator" "instagram-curator" "reddit-builder" "twitter-engager" "app-store-optimizer" "brand-guardian" "ui-designer" "ux-researcher" "visual-storyteller" "whimsy-injector" "ui-ux-pro-max" "feedback-synthesizer" "sprint-prioritizer" "trend-researcher" "experiment-tracker" "project-shipper" "studio-producer" "studio-coach" "analytics-reporter" "finance-tracker" "infrastructure-maintainer" "legal-compliance-checker" "support-responder" "api-tester" "performance-benchmarker" "test-results-analyzer" "tool-evaluator" "workflow-optimizer" "joker" "agent-updater" ) # Check if mode is off if [ "$RALPH_MODE" = "off" ]; then exit 0 fi # Read the user prompt USER_PROMPT="$1" # Detect agent request (case-insensitive) agent_detected=false detected_agent="" for agent in "${AGENTS[@]}"; do if echo "$USER_PROMPT" | grep -iq "$agent"; then agent_detected=true detected_agent="$agent" break fi done # Check if we should trigger should_trigger=false if [ "$RALPH_MODE" = "always" ]; then # Trigger on all prompts should_trigger=true elif [ "$RALPH_MODE" = "agents" ]; then # Only trigger on agent requests if [ "$agent_detected" = true ]; then should_trigger=true fi fi if [ "$should_trigger" = true ]; then # Create/update state file cat > "$STATE_FILE" << EOF # Ralph Loop State # Generated: $(date) **User Request:** $USER_PROMPT **Detected Agent:** $detected_agent **Mode:** $RALPH_MODE **Timestamp:** $(date -Iseconds) ## Context This state file was automatically generated by the Ralph auto-trigger hook. Ralph CLI can read this file to continue autonomous looping based on the user's request. ## Usage To run Ralph autonomously: \`\`\`bash ralph build 50 # Run 50 iterations \`\`\` Ralph will read this state file and continue working until the task is complete. EOF # Log the trigger (silent, no output) echo "[$(date '+%Y-%m-%d %H:%M:%S')] Ralph auto-triggered: mode=$RALPH_MODE, agent=$detected_agent" >> "$HOME/.claude/ralph-trigger.log" 2>/dev/null || true fi exit 0 RALPH_HOOK_EOF chmod +x "$CLAUDE_DIR/hooks/ralph-auto-trigger.sh" log_success "Ralph auto-trigger hook created" # Create or update hooks.json log_info "Configuring hooks.json..." HOOKS_FILE="$CLAUDE_DIR/hooks.json" if [ -f "$HOOKS_FILE" ]; then # Backup existing hooks.json cp "$HOOKS_FILE" "$HOOKS_FILE.backup.$(date +%Y%m%d-%H%M%S)" fi # Create new hooks.json with Ralph hook cat > "$HOOKS_FILE" << 'HOOKS_JSON_EOF' { "description": "User hooks for Ralph auto-trigger and custom behavior", "hooks": { "UserPromptSubmit": [ { "type": "command", "command": "bash", "args": ["/home/uroma/.claude/hooks/ralph-auto-trigger.sh", "{{userPrompt}}"] } ] } } HOOKS_JSON_EOF log_success "hooks.json configured for Ralph auto-trigger" # Create environment file for Ralph configuration cat > "$CLAUDE_DIR/ralph-config.env" << 'RALPH_ENV_EOF' # Ralph CLI Configuration # Source this file or add to your shell profile: export RALPH_AUTO_MODE=agents # Ralph auto-trigger mode: # - always: Trigger on all prompts # - agents: Only trigger on agent requests (default) # - off: Disable auto-trigger export RALPH_AUTO_MODE="${RALPH_AUTO_MODE:-agents}" # Ralph state file location (auto-created) export RALPH_STATE_FILE="$HOME/.claude/ralph-loop.local.md" RALPH_ENV_EOF log_success "Ralph configuration saved to $CLAUDE_DIR/ralph-config.env" echo "" log_info "To enable Ralph auto-trigger, add to your shell profile:" echo " source ~/.claude/ralph-config.env" echo "" log_info "Ralph CLI modes: always (all prompts) | agents (agent prompts only) | off (disabled)" } perform_installation() { print_header echo -e "${BOLD}Step 10: Installation${NC}" echo "═══════════════════════════════════════════════════════════" echo "" create_directories fetch_latest_agents install_agents install_settings install_local_settings install_mcp_config install_mcp_tools install_plugins install_hooks install_ralph echo "" log_success "Installation completed!" echo "" sleep 1 } ################################################################################ # Summary & Launch ################################################################################ show_summary() { print_header echo -e "${BOLD}Installation Summary${NC}" echo "╔══════════════════════════════════════════════════════════════════╗${NC}" echo "║ ║" echo "║ Configuration: ║" if [ "$USE_ZAI_MODELS" = true ]; then echo "║ • Model Provider: ${CYAN}Z.AI / GLM Coding Plan${NC} ║" else echo "║ • Model Provider: ${GREEN}Anthropic Claude (Official)${NC} ║" fi echo "║ ║" echo "║ Installed Components: ║" if [ $SELECTED_AGENTS -gt 0 ]; then echo "║ • Agents: ${GREEN}$SELECTED_AGENTS custom agents${NC} ║" fi if [ $SELECTED_MCP_TOOLS -gt 0 ]; then echo "║ • MCP Tools: ${CYAN}$SELECTED_MCP_TOOLS tools${NC} ║" fi if [ "$INSTALL_PLUGINS" = true ]; then echo "║ • Plugins: ${GREEN}Z.AI plugins enabled${NC} ║" fi if [ "$INSTALL_HOOKS" = true ]; then echo "║ • Hooks: ${GREEN}Installed${NC} ║" fi if [ "$INSTALL_RALPH" = true ]; then echo "║ • Ralph CLI: ${MAGENTA}Installed (Autonomous Looping)${NC} ║" fi echo "║ ║" echo "╚══════════════════════════════════════════════════════════════════╝" echo "" } launch_claude_code() { echo "" echo -e "${BOLD}Launch Claude Code?${NC}" echo "" echo "You can launch Claude Code now to start using your customizations." echo "" if confirm "Launch Claude Code now?" "N"; then echo "" log_info "Launching Claude Code..." echo "" # Try to launch claude-code if command -v claude-code &> /dev/null; then exec claude-code elif command -v code &> /dev/null; then log_info "Trying VS Code command..." code else log_warning "Claude Code command not found" echo "" echo "Please launch Claude Code manually:" echo " • From applications menu" echo " • Or run: claude-code" echo " • Or run: code" fi else echo "" log_info "You can launch Claude Code later with: claude-code" fi } ################################################################################ # Main Installation Flow ################################################################################ main() { show_welcome select_model select_agents select_mcp_tools select_plugins select_hooks select_ralph check_prerequisites install_claude_code backup_config perform_installation show_summary if [ -n "$BACKUP_DIR" ] && [ -d "$BACKUP_DIR" ]; then log_info "Backup saved to: $BACKUP_DIR" fi launch_claude_code } # Run main main "$@"