#!/bin/bash # Codex Configuration Script for XCodeCLI # This script configures Codex to use your XCodeCLI instance # Automatically tests multiple API endpoints and selects the working one set -e # Color functions for output print_info() { echo -e "\033[34m[INFO]\033[0m $1" } print_success() { echo -e "\033[32m[SUCCESS]\033[0m $1" } print_warning() { echo -e "\033[33m[WARNING]\033[0m $1" } print_error() { echo -e "\033[31m[ERROR]\033[0m $1" } # Default values DEFAULT_BASE_URL="https://api2.xcodecli.com" BASE_URL="" TEST_ONLY=false SHOW_SETTINGS=false # ========== Shell 环境变量配置 ========== # 检测当前 shell 配置文件 get_shell_rc() { if [ -n "${ZSH_VERSION:-}" ] || [ "${SHELL##*/}" = "zsh" ]; then echo "$HOME/.zshrc" elif [ -n "${BASH_VERSION:-}" ] || [ "${SHELL##*/}" = "bash" ]; then if [ -f "$HOME/.bashrc" ]; then echo "$HOME/.bashrc" else echo "$HOME/.bash_profile" fi elif [ "${SHELL##*/}" = "fish" ]; then echo "$HOME/.config/fish/config.fish" else echo "$HOME/.profile" fi } # 写入环境变量到 shell 配置文件 write_env_to_shell() { local var_name="$1" local var_value="$2" local rc_file rc_file=$(get_shell_rc) # 确保配置文件存在 mkdir -p "$(dirname "$rc_file")" touch "$rc_file" # 确保文件末尾有换行 if [ -s "$rc_file" ] && [ "$(tail -c1 "$rc_file" | wc -l)" -eq 0 ]; then echo "" >> "$rc_file" fi # 转义特殊字符(使用单引号包裹更安全) local export_line if [ "${SHELL##*/}" = "fish" ]; then export_line="set -Ux $var_name '$var_value'" else export_line="export $var_name='$var_value'" fi # 删除旧的同名变量行,添加新行 local tmp_file tmp_file=$(mktemp) if [ -s "$rc_file" ]; then grep -v "^export $var_name=" "$rc_file" | grep -v "^set -Ux $var_name " > "$tmp_file" 2>/dev/null || true fi echo "$export_line" >> "$tmp_file" # 保留原文件权限 cat "$tmp_file" > "$rc_file" rm -f "$tmp_file" # 立即生效 export "$var_name=$var_value" } # Function to validate API key format validate_api_key() { local api_key="$1" if [[ ! "$api_key" =~ ^[A-Za-z0-9_-]+$ ]]; then print_error "Invalid API key format. API key should contain only alphanumeric characters, hyphens, and underscores." return 1 fi return 0 } # Check for environment variable API_KEY if [ -n "$API_KEY" ]; then API_KEY_FROM_ENV="$API_KEY" else API_KEY_FROM_ENV="" fi API_KEY="" # Function to show help show_help() { cat <&2 for base_url in "${test_urls[@]}"; do print_info "Testing $base_url..." >&2 local test_endpoint="$base_url/v1/models" # Test with Authorization Bearer header (OpenAI API style) local response response=$(curl -s -w "%{http_code}" -o /tmp/codex_test_response \ -X GET "$test_endpoint" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $api_key" \ 2>/dev/null || echo "000") if [ "$response" = "200" ]; then # Check if response contains models data if grep -qE '"data".*\[|"object"' /tmp/codex_test_response 2>/dev/null; then local model_count model_count=$(grep -oE '"id"[[:space:]]*:' /tmp/codex_test_response | wc -l | tr -d ' ') print_success "API connection successful! Found $model_count models at $base_url" >&2 rm -f /tmp/codex_test_response echo "$base_url" return 0 else print_warning "API responded but no models found at $base_url" >&2 fi elif [ "$response" = "401" ]; then print_warning "API key authentication failed for $base_url" >&2 elif [ "$response" = "000" ]; then print_warning "Cannot connect to $base_url" >&2 else print_warning "API test failed for $base_url with HTTP status: $response" >&2 fi rm -f /tmp/codex_test_response done print_error "All API connections failed. Please check your API key and internet connection." >&2 return 1 } # Function to create Codex configuration create_codex_config() { local base_url="$1" local api_key="$2" # Create config directory if it doesn't exist mkdir -p "$HOME/.codex" # Create config.toml cat >"$HOME/.codex/config.toml" <"$HOME/.codex/auth.json" <