#!/usr/bin/env bash set -euo pipefail # ============================================================================== # AI Development Tools Configuration Script # Configures: Claude Code (env vars) + Codex CLI (config files) # Version: 2.2.0 (English, No Encoding Issues) # ============================================================================== # Color Definitions RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' WHITE='\033[1;37m' MAGENTA='\033[0;35m' NC='\033[0m' # Configuration Constants CLAUDE_BASE_URL="https://coder.api.visioncoder.cn" CODEX_BASE_URL="https://coder.api.visioncoder.cn/v1" CODEX_MODEL="gpt-5.4" # Configuration Choices (set by user) CONFIGURE_CLAUDE=false CONFIGURE_CODEX=false SHARED_API_KEY="" # Log Functions log_info() { echo -e "${BLUE}[INFO]${NC} $1"; } log_success() { echo -e "${GREEN}[OK]${NC} $1"; } log_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; } log_error() { echo -e "${RED}[ERROR]${NC} $1"; } log_step() { echo -e "${CYAN}[STEP]${NC} $1"; } print_banner() { clear echo -e "${CYAN}" echo "========================================" echo "" echo " AI Development Tools Config Script" echo " Version: 2.2.0" echo "" echo " Configures: Claude Code, Codex CLI" echo "" echo "========================================" echo -e "${NC}" } # Get Shell Config File get_shell_config() { if [[ "$SHELL" == *"zsh"* ]]; then echo "$HOME/.zshrc" elif [[ "$SHELL" == *"bash"* ]]; then if [[ "$OSTYPE" == "darwin"* ]]; then echo "$HOME/.bash_profile" else echo "$HOME/.bashrc" fi else echo "$HOME/.profile" fi } # ============================================ # User Selection Menu # ============================================ show_config_menu() { clear echo -e "${CYAN}" echo "========================================" echo "" echo " AI Development Tools Config Script" echo " Version: 2.2.0" echo "" echo "========================================" echo -e "${NC}" echo "" echo -e "${WHITE}Select tools to configure:${NC}" echo "" echo -e " ${GREEN}1${NC}) Claude Code only" echo -e " ${GREEN}2${NC}) Codex CLI only" echo -e " ${GREEN}3${NC}) Configure both (Recommended)" echo -e " ${GREEN}q${NC}) Quit" echo "" # Use /dev/tty to read input, supports curl | bash if [ -t 0 ]; then read -p "Choose [1-3]: " -r choice else read -p "Choose [1-3]: " -r choice < /dev/tty fi case "$choice" in 1) CONFIGURE_CLAUDE=true CONFIGURE_CODEX=false log_success "Will configure: Claude Code" ;; 2) CONFIGURE_CLAUDE=false CONFIGURE_CODEX=true log_success "Will configure: Codex CLI" ;; 3) CONFIGURE_CLAUDE=true CONFIGURE_CODEX=true log_success "Will configure: Claude Code + Codex CLI" ;; q|Q) log_info "Configuration cancelled" exit 0 ;; *) log_error "Invalid selection" echo "" read -p "Press Enter to try again..." -r show_config_menu return ;; esac } # ============================================ # Claude Code Configuration (Environment Variables) # ============================================ configure_claude() { echo "" echo -e "${MAGENTA}========================================${NC}" echo -e "${MAGENTA} Configuring Claude Code${NC}" echo -e "${MAGENTA}========================================${NC}" echo "" # Check claude command if ! command -v claude &> /dev/null; then log_error "Claude Code not installed" log_info "Please run install script first: ./install.sh" return 1 fi log_success "Claude Code is installed" # Get API Key echo "" echo -e "${CYAN}========================================${NC}" echo -e "${CYAN} Get Claude API Key${NC}" echo -e "${CYAN}========================================${NC}" echo "" log_info "How to get Claude API Key:" echo "" echo " 1. Visit: ${CYAN}https://coder.visioncoder.cn/key${NC}" echo " 2. Login to your account" echo " 3. Copy the displayed API Key" echo "" log_warning "Make sure your API Key is valid and not expired" echo "" # Try to auto-open browser log_info "Opening browser for you..." if command -v open > /dev/null 2>&1; then # macOS open "https://coder.visioncoder.cn/key" 2>/dev/null || true elif command -v xdg-open > /dev/null 2>&1; then # Linux xdg-open "https://coder.visioncoder.cn/key" 2>/dev/null || true elif command -v wslview > /dev/null 2>&1; then # WSL wslview "https://coder.visioncoder.cn/key" 2>/dev/null || true else log_warning "Cannot auto-open browser, please visit the URL manually" fi echo "" log_info "Please login and copy API Key, then continue..." echo "" # Use /dev/tty to read input, supports curl | bash if [ -t 0 ]; then read -p "Paste Claude API Key: " -r claude_api_key else read -p "Paste Claude API Key: " -r claude_api_key < /dev/tty fi if [ -z "$claude_api_key" ]; then log_error "API Key cannot be empty" return 1 fi # Save to global variable for Codex config SHARED_API_KEY="$claude_api_key" # Configure environment variables log_step "Configuring environment variables..." echo "" local shell_config=$(get_shell_config) log_info "Shell config file: $shell_config" # Check if already configured if grep -q "# >>> CLAUDE ENV BEGIN >>>" "$shell_config" 2>/dev/null; then log_warning "Detected existing Claude env vars, will update config" # Backup config file cp "$shell_config" "$shell_config.backup.$(date +%Y%m%d_%H%M%S)" log_success "Config file backed up" # Remove old config (lines between BEGIN and END) if [[ "$OSTYPE" == "darwin"* ]]; then # macOS uses sed -i '' sed -i '' '/# >>> CLAUDE ENV BEGIN >>>/,/# <<< CLAUDE ENV END <<>> CLAUDE ENV BEGIN >>>/,/# <<< CLAUDE ENV END <<> "$shell_config" fi fi # Add new config (with marker comments) cat >> "$shell_config" << EOF # >>> CLAUDE ENV BEGIN >>> # Claude Code environment configuration # Auto-generated by config script, do not manually edit this section export ANTHROPIC_AUTH_TOKEN="$claude_api_key" export ANTHROPIC_API_KEY="$claude_api_key" export ANTHROPIC_BASE_URL="$CLAUDE_BASE_URL" # <<< CLAUDE ENV END <<< EOF log_success "Claude Code environment variables configured" # Load into current session immediately export ANTHROPIC_AUTH_TOKEN="$claude_api_key" export ANTHROPIC_API_KEY="$claude_api_key" export ANTHROPIC_BASE_URL="$CLAUDE_BASE_URL" log_success "Environment variables active in current session" echo "" log_info "Configuration details:" echo " * ANTHROPIC_AUTH_TOKEN: ${claude_api_key:0:12}..." echo " * ANTHROPIC_API_KEY: ${claude_api_key:0:12}..." echo " * ANTHROPIC_BASE_URL: $CLAUDE_BASE_URL" echo "" return 0 } # ============================================ # Codex CLI Configuration (Config Files) # ============================================ configure_codex() { echo "" echo -e "${MAGENTA}========================================${NC}" echo -e "${MAGENTA} Configuring Codex CLI${NC}" echo -e "${MAGENTA}========================================${NC}" echo "" # Check codex command if ! command -v codex &> /dev/null; then log_warning "Codex CLI not installed" log_info "Please run install script first: ./install.sh" return 0 fi log_success "Codex CLI is installed" # Use previously obtained API Key (passed as parameter) local api_key="$1" if [ -z "$api_key" ]; then log_error "API Key not provided" return 1 fi # Create config directory local codex_dir="$HOME/.codex" log_step "Creating config directory: $codex_dir" mkdir -p "$codex_dir" log_success "Config directory created" # Create config.toml log_step "Creating config file: config.toml" cat > "$codex_dir/config.toml" << EOF model_provider = "codex" model = "$CODEX_MODEL" model_reasoning_effort = "high" disable_response_storage = true preferred_auth_method = "apikey" [model_providers.codex] name = "codex" base_url = "$CODEX_BASE_URL" wire_api = "responses" requires_openai_auth = true EOF log_success "config.toml created" # Create auth.json (using same API Key) log_step "Creating auth file: auth.json" cat > "$codex_dir/auth.json" << EOF { "OPENAI_API_KEY": "$api_key" } EOF # Set file permissions chmod 600 "$codex_dir/auth.json" log_success "auth.json created (permissions: 600)" echo "" log_info "Codex configuration details:" echo " * config.toml: $codex_dir/config.toml" echo " * auth.json: $codex_dir/auth.json" echo " * Base URL: $CODEX_BASE_URL" echo " * Model: $CODEX_MODEL" echo " * API Key: Using same Claude API Key" echo "" return 0 } # ============================================ # Verify Configuration # ============================================ verify_configuration() { print_banner echo -e "${GREEN}========================================${NC}" echo -e "${GREEN} Configuration Complete${NC}" echo -e "${GREEN}========================================${NC}" echo "" echo -e "${WHITE}Configuration status:${NC}" echo "" # Claude Code if [ -n "${ANTHROPIC_AUTH_TOKEN:-}" ]; then log_success "Claude Code: Configured" log_info " API Token: ${ANTHROPIC_AUTH_TOKEN:0:12}..." log_info " Base URL: ${ANTHROPIC_BASE_URL}" else log_warning "Claude Code: Not configured" fi echo "" # Codex CLI if [ -f "$HOME/.codex/auth.json" ]; then log_success "Codex CLI: Configured" log_info " Config directory: $HOME/.codex" log_info " Base URL: $CODEX_BASE_URL" else log_warning "Codex CLI: Not configured (optional)" fi echo "" echo -e "${CYAN}========================================${NC}" echo -e "${CYAN} Usage Instructions${NC}" echo -e "${CYAN}========================================${NC}" echo "" if [ -n "${ANTHROPIC_AUTH_TOKEN:-}" ]; then log_info "Claude Code usage:" echo " $ claude --help" echo " $ claude \"your question\"" echo "" fi if [ -f "$HOME/.codex/auth.json" ]; then log_info "Codex CLI usage:" echo " $ codex --version" echo " $ codex" echo " Then send a message to verify connection" echo "" fi local shell_config=$(get_shell_config) echo -e "${YELLOW}IMPORTANT:${NC}" echo " 1. Do not share your API Key with others" echo " 2. Config file permissions set to secure mode" echo " 3. Run this script again to reconfigure (auto-overwrites old config)" echo " 4. Config added to $shell_config (with marker comments)" echo "" echo -e "${YELLOW}To make environment variables effective:${NC}" echo -e " Method 1: ${GREEN}source $shell_config${NC}" echo " Method 2: Reopen terminal" echo "" echo -e "${CYAN}Test immediately (in new terminal window):${NC}" echo " $ claude --help" echo " $ echo \$ANTHROPIC_AUTH_TOKEN" echo "" echo -e "${CYAN}View config (in $shell_config):${NC}" echo " Config is between # >>> CLAUDE ENV BEGIN >>> and # <<< CLAUDE ENV END <<<" echo "" } # ============================================ # Main Function # ============================================ main() { # Show selection menu show_config_menu echo "" sleep 1 print_banner log_info "This script will configure:" if [ "$CONFIGURE_CLAUDE" = true ]; then echo " 1. Claude Code (environment variables)" fi if [ "$CONFIGURE_CODEX" = true ]; then echo " 2. Codex CLI (config files)" fi echo "" log_step "Starting configuration..." echo "" # 1. Configure Claude Code if [ "$CONFIGURE_CLAUDE" = true ]; then if configure_claude; then log_success "Claude Code configuration complete" else log_error "Claude Code configuration failed" exit 1 fi fi # 2. Configure Codex CLI (using same API Key) if [ "$CONFIGURE_CODEX" = true ]; then if [ -n "$SHARED_API_KEY" ]; then configure_codex "$SHARED_API_KEY" elif [ "$CONFIGURE_CLAUDE" = false ]; then # If Claude not configured, get API Key separately echo "" log_info "Please enter API Key for Codex CLI configuration" echo "" # Use /dev/tty to read input if [ -t 0 ]; then read -p "Paste API Key: " -r codex_api_key else read -p "Paste API Key: " -r codex_api_key < /dev/tty fi if [ -z "$codex_api_key" ]; then log_error "API Key cannot be empty" exit 1 fi configure_codex "$codex_api_key" fi fi # 3. Verify configuration echo "" sleep 1 verify_configuration } # Run main function main "$@"