From 2314140bce9455d08e7fd1ec17c27fdaa857d6ad Mon Sep 17 00:00:00 2001 From: sususu98 Date: Thu, 11 Dec 2025 18:15:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=A2=9E=E5=BC=BA=E4=B8=89=E4=B8=AA=20?= =?UTF-8?q?CLI=20=E5=B7=A5=E5=85=B7=E9=85=8D=E7=BD=AE=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Gemini CLI: 添加 GEMINI_MODEL 环境变量、settings.json 输出及备份逻辑 - Codex: 修复模型名称一致性 (gpt-5-codex)、添加 auth.json 备份逻辑 - Claude Code: 添加 VSCode 插件 config.json 配置支持 - CLAUDE.md: 重构文档,添加三个工具配置差异表 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 250 +++++++++---------------------- ClaudeCode/setup-claude-code.ps1 | 62 ++------ ClaudeCode/setup-claude-code.sh | 15 ++ GeminiCLI/setup-gemini.ps1 | 25 +++- GeminiCLI/setup-gemini.sh | 23 +++ codex/setup-codex.ps1 | 70 ++++----- codex/setup-codex.sh | 190 ++++++----------------- setup-claude-code.ps1 | 60 ++------ setup-claude-code.sh | 94 +++++++----- 9 files changed, 292 insertions(+), 497 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 61413f3..c0ff9a6 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,202 +4,94 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## 项目概述 -XCodeCLI-Shells 是一个智能配置工具集,用于设置 Claude Code 与 XCodeCLI API 路由器的集成。项目包含跨平台的安装脚本,支持 Windows (PowerShell) 和 Unix/Linux/macOS (Bash),具备自动端点发现和选择功能。 +XCodeCLI-Shells 是一个跨平台配置工具集,用于配置 **Claude Code**、**Gemini CLI** 和 **Codex** 三个 AI CLI 工具连接到 XCodeCLI API 路由器。每个工具都有 PowerShell (.ps1) 和 Bash (.sh) 两个版本。 -## 核心架构 +## 项目结构 -### 脚本功能 -- **setup-claude-code.ps1**: Windows PowerShell 配置脚本 -- **setup-claude-code.sh**: Unix/Linux/macOS Bash 配置脚本 - -两个脚本提供相同的功能: -- 验证 API 密钥格式 -- **智能端点发现**: 自动测试多个 API 端点并选择可用的 -- **自动 API 连接测试**: 使用 `/v1/models` 端点验证连接 -- 创建 Claude Code 配置文件 (~/.claude/settings.json) -- 设置环境变量 (ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN) -- 支持环境变量传递 API 密钥 (bash 脚本) - -### 配置结构 -脚本生成的 settings.json 包含: -```json -{ - "env": { - "ANTHROPIC_BASE_URL": "<自动选择的URL>", - "ANTHROPIC_AUTH_TOKEN": "<用户API密钥>", - "CLAUDE_CODE_MAX_OUTPUT_TOKENS": 20000, - "DISABLE_TELEMETRY": 1, - "DISABLE_ERROR_REPORTING": 1, - "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1, - "CLAUDE_BASH_MAINTAIN_PROJECT_WORKING_DIR": 1, - "MAX_THINKING_TOKENS": 12000 - }, - "model": "sonnet" -} +``` +xcodecli-shells/ +├── setup.ps1 # Windows 统一启动器 (安装+配置三个工具) +├── setup-claude-code.ps1/.sh # Claude Code 配置脚本 (根目录副本) +├── ClaudeCode/ +│ └── setup-claude-code.ps1/.sh +├── GeminiCLI/ +│ └── setup-gemini.ps1/.sh +└── codex/ + └── setup-codex.ps1/.sh ``` -### 支持的 API 端点 -脚本会按顺序测试以下端点,选择第一个可用的: +## 三个工具的配置差异 + +| 工具 | 配置位置 | 配置格式 | API 认证头 | +| ----------- | ------------------------------------ | ----------- | ----------------------- | +| Claude Code | `~/.claude/settings.json` | JSON | `Authorization: Bearer` | +| Gemini CLI | `~/.gemini/.env` | ENV 文件 | `x-goog-api-key` | +| Codex | `~/.codex/config.toml` + `auth.json` | TOML + JSON | `Authorization: Bearer` | + +## 统一启动器 (setup.ps1) + +Windows 专用的一站式安装配置工具: + +- 检测 Node.js/Bun 包管理器,缺失时引导安装 Bun +- 显示三个工具的安装状态 +- 自动安装缺失的工具 (`npm install -g` 或 `bun add -g`) +- 下载并执行对应工具的配置脚本 + +```powershell +# 使用方式 +$key='YOUR_API_KEY'; iwr -useb https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup.ps1 | iex +``` + +## 通用脚本模式 + +所有配置脚本共享相同的设计模式: + +### 参数接口 + +- PowerShell: `-ApiKey`, `-Test`, `-Show`, `-Help` +- Bash: `--key`, `--test`, `--show`, `--help` +- 支持 `$key` 变量 (PowerShell) 或 `$API_KEY` 环境变量 (Bash) + +### 智能端点发现 + +按顺序测试端点,选择第一个可用的: + 1. `https://api2.xcodecli.com` 2. `https://api.xcodecli.com` -## 常用命令 +### 核心流程 -### 🚀 一行命令快速配置 +1. API 密钥格式验证 (字母数字、连字符、下划线) +2. 调用 `/v1/models` 测试连接 +3. 备份现有配置 (时间戳命名) +4. 写入新配置文件 -#### Windows (PowerShell) -```powershell -$key='YOUR_API_KEY' -iwr -useb https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup-claude-code.ps1 | iex -``` +## 常用开发命令 -#### Unix/Linux/macOS (Bash) ```bash -export API_KEY='YOUR_API_KEY' -curl -fsSL https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup-claude-code.sh | bash +# 本地测试脚本 +./setup-claude-code.sh --key test-key --test +./GeminiCLI/setup-gemini.sh --key test-key --test +./codex/setup-codex.sh --key test-key --test + +# PowerShell 执行 (绕过执行策略) +powershell -ExecutionPolicy Bypass -File setup-claude-code.ps1 -ApiKey test-key -Test ``` -### Windows (PowerShell) -```powershell -# 基本使用(自动选择可用端点) -.\setup-claude-code.ps1 -ApiKey your-api-key - -# 测试连接(测试所有端点) -.\setup-claude-code.ps1 -Test -ApiKey your-api-key - -# 显示当前设置 -.\setup-claude-code.ps1 -Show - -# 交互模式 -.\setup-claude-code.ps1 - -# 帮助 -.\setup-claude-code.ps1 -Help -``` - -### Unix/Linux/macOS (Bash) -```bash -# 基本使用(自动选择可用端点) -./setup-claude-code.sh --key your-api-key - -# 使用环境变量 -export API_KEY='your-api-key' -./setup-claude-code.sh - -# 测试连接(测试所有端点) -./setup-claude-code.sh --test --key your-api-key - -# 显示当前设置 -./setup-claude-code.sh --show - -# 交互模式 -./setup-claude-code.sh - -# 帮助 -./setup-claude-code.sh --help -``` - -## 智能特性 - -### 自动端点发现 -脚本使用智能算法自动发现和选择最佳可用的 API 端点: - -1. **端点测试**: 依次测试所有配置的端点 -2. **连通性验证**: 使用 `/v1/models` 端点检查服务可用性 -3. **模型验证**: 确保端点返回有效的模型列表 -4. **自动选择**: 选择第一个通过所有测试的端点 -5. **智能降级**: 如果所有端点都失败,提供手动选择选项 - -### 错误处理和恢复 -- **连接失败**: 自动尝试下一个端点 -- **认证失败**: 提供清晰的错误信息和解决建议 -- **服务不可用**: 智能降级到默认配置 -- **用户选择**: 在失败时允许用户决定是否继续 - - - ## 开发注意事项 -### PowerShell 脚本特性 -- 支持执行策略绕过: `powershell -ExecutionPolicy Bypass` -- 彩色输出功能 (Blue/Green/Yellow/Red) -- 环境变量持久化 (用户级别) -- JSON 配置验证 -- **智能端点测试**: 自动测试多个 API 端点 -- **Bearer 认证**: 使用标准 `Authorization: Bearer` 头 -- **模型列表验证**: 通过 `/v1/models` 端点验证服务可用性 +### 脚本一致性 -### Bash 脚本特性 -- 依赖 jq 进行 JSON 处理 -- ANSI 颜色输出 -- 临时文件清理 -- 错误处理和回滚机制 -- **环境变量支持**: 支持 `API_KEY` 环境变量 -- **智能端点测试**: 自动测试多个 API 端点 -- **Bearer 认证**: 使用标准 `Authorization: Bearer` 头 -- **模型列表验证**: 通过 `/v1/models` 端点验证服务可用性 +- PowerShell 和 Bash 版本必须功能对等 +- 新增端点需同时更新所有 6 个配置脚本 +- 输出格式保持一致: `[INFO]`, `[SUCCESS]`, `[WARNING]`, `[ERROR]` -### 安全考虑 -- API 密钥格式验证 (仅允许字母数字、连字符、下划线) -- 配置文件自动备份 (时间戳) -- 敏感信息掩码显示 -- HTTP 状态码验证 -- **端点安全**: 仅测试预定义的可信端点 -- **连接超时**: 自动处理网络超时情况 +### Bash 脚本依赖 -### 配置文件位置 -- Windows: `%USERPROFILE%\.claude\settings.json` -- Unix/Linux/macOS: `~/.claude/settings.json` +- Claude Code 脚本依赖 `jq` 处理 JSON +- Gemini/Codex 脚本使用 `grep` 解析响应,无需 jq -## 故障排除 +### API 响应格式差异 -### 端点连接问题 -如果所有端点都无法连接: -1. 检查网络连接 -2. 验证 API 密钥是否有效 -3. 确认防火墙设置允许访问 -4. 检查代理配置 - -### API 密钥认证失败 -如果遇到 401 认证错误: -1. 验证 API 密钥格式是否正确 -2. 确认密钥是否过期 -3. 检查密钥权限设置 -4. 尝试重新生成密钥 - -### 脚本执行问题 -#### PowerShell 执行策略错误 -```powershell -powershell -ExecutionPolicy Bypass -File setup-claude-code.ps1 -``` - -#### Bash 权限问题 -```bash -chmod +x setup-claude-code.sh -``` - -### 环境变量问题 -#### Windows -检查用户环境变量是否正确设置: -```powershell -[Environment]::GetEnvironmentVariable("ANTHROPIC_BASE_URL", [EnvironmentVariableTarget]::User) -[Environment]::GetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", [EnvironmentVariableTarget]::User) -``` - -#### Unix/Linux/macOS -检查环境变量: -```bash -echo $ANTHROPIC_BASE_URL -echo $ANTHROPIC_AUTH_TOKEN -``` - -## 总结 - -XCodeCLI-Shells 现在提供智能化的配置体验: -- **零配置URL**: 无需手动指定API端点,自动发现可用服务 -- **一键安装**: 支持从远程直接下载执行 -- **智能降级**: 在连接失败时提供多种选择 -- **跨平台一致性**: Windows 和 Unix/Linux/macOS 脚本功能完全一致 -- **用户友好**: 清晰的错误提示和帮助信息 - -通过这些改进,用户只需要关心 API 密钥,其他配置都由脚本智能处理。 \ No newline at end of file +- Claude/Codex: 检查 `response.data` 或 `response.models` 数组 +- Gemini: 检查 `response.models` 数组 (Google API 格式) diff --git a/ClaudeCode/setup-claude-code.ps1 b/ClaudeCode/setup-claude-code.ps1 index e839536..9961713 100644 --- a/ClaudeCode/setup-claude-code.ps1 +++ b/ClaudeCode/setup-claude-code.ps1 @@ -83,6 +83,13 @@ function Backup-Settings { Copy-Item -Path $ClaudeSettingsFile -Destination $backupFile Write-Info "Backed up existing settings to: $backupFile" } + $configJsonPath = "$ClaudeConfigDir\config.json" + if (Test-Path $configJsonPath) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $backupFile = "$configJsonPath.backup.$timestamp" + Copy-Item -Path $configJsonPath -Destination $backupFile + Write-Info "Backed up existing config to: $backupFile" + } } # Function to create settings directory @@ -173,6 +180,12 @@ function New-Settings { $json = $settings | ConvertTo-Json -Depth 10 Set-Content -Path $ClaudeSettingsFile -Value $json -Encoding UTF8 Write-Success "Claude Code settings written to: $ClaudeSettingsFile" + + # Write config.json for VSCode Claude extension + $configJsonPath = "$ClaudeConfigDir\config.json" + $configJson = @{ primaryApiKey = "xcodecli" } + $configJson | ConvertTo-Json | Set-Content -Path $configJsonPath -Encoding UTF8 + Write-Success "VSCode Claude config written to: $configJsonPath" return $true } catch { @@ -192,30 +205,6 @@ function Show-Settings { } else { Write-Info "No existing Claude Code settings found." } - - Write-Host "" - Write-Info "Current environment variables:" - Write-Host "----------------------------------------" - $baseUrl = [Environment]::GetEnvironmentVariable("ANTHROPIC_BASE_URL", [EnvironmentVariableTarget]::User) - $authToken = [Environment]::GetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", [EnvironmentVariableTarget]::User) - - if ($baseUrl) { - Write-Info "ANTHROPIC_BASE_URL: $baseUrl" - } else { - Write-Info "ANTHROPIC_BASE_URL: (not set)" - } - - if ($authToken) { - $maskedToken = if ($authToken.Length -gt 12) { - "$($authToken.Substring(0, 8))...$($authToken.Substring($authToken.Length - 4))" - } else { - "$($authToken.Substring(0, [Math]::Min(4, $authToken.Length)))..." - } - Write-Info "ANTHROPIC_AUTH_TOKEN: $maskedToken" - } else { - Write-Info "ANTHROPIC_AUTH_TOKEN: (not set)" - } - Write-Host "----------------------------------------" } # Main function @@ -305,28 +294,6 @@ function Main { # Create new settings if (New-Settings -BaseUrl $BaseUrl -ApiKey $ApiKey) { - Write-Host "" - - # Also set environment variables for Windows - Write-Info "Setting environment variables..." - try { - # Set user environment variables (persistent across sessions) - [Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", $BaseUrl, [EnvironmentVariableTarget]::User) - [Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", $ApiKey, [EnvironmentVariableTarget]::User) - - # Also set for current session - $env:ANTHROPIC_BASE_URL = $BaseUrl - $env:ANTHROPIC_AUTH_TOKEN = $ApiKey - - Write-Success "Environment variables set successfully" - } - catch { - Write-Warning "Failed to set environment variables: $($_.Exception.Message)" - Write-Info "You may need to set them manually:" - Write-Info " ANTHROPIC_BASE_URL=$BaseUrl" - Write-Info " ANTHROPIC_AUTH_TOKEN=$ApiKey" - } - Write-Host "" Write-Success "Claude Code has been configured successfully!" Write-Info "You can now use Claude Code with your API router." @@ -335,8 +302,7 @@ function Main { Write-Info " claude --version" Write-Info "" Write-Info "Configuration file location: $ClaudeSettingsFile" - Write-Info "Environment variables have been set for ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN" - + if (Test-Path $ClaudeSettingsFile) { Write-Host "" Write-Info "Current settings:" diff --git a/ClaudeCode/setup-claude-code.sh b/ClaudeCode/setup-claude-code.sh index 9a6dfa7..4b1587c 100644 --- a/ClaudeCode/setup-claude-code.sh +++ b/ClaudeCode/setup-claude-code.sh @@ -54,6 +54,12 @@ backup_settings() { cp "$CLAUDE_SETTINGS_FILE" "$backup_file" print_info "Backed up existing settings to: $backup_file" fi + local config_json_path="$CLAUDE_CONFIG_DIR/config.json" + if [ -f "$config_json_path" ]; then + local backup_file="${config_json_path}.backup.$(date +%Y%m%d_%H%M%S)" + cp "$config_json_path" "$backup_file" + print_info "Backed up existing config to: $backup_file" + fi } # Function to create settings directory @@ -153,6 +159,15 @@ create_settings() { # Write settings file echo "$settings_json" > "$CLAUDE_SETTINGS_FILE" print_success "Claude Code settings written to: $CLAUDE_SETTINGS_FILE" + + # Write config.json for VSCode Claude extension + local config_json_path="$CLAUDE_CONFIG_DIR/config.json" + cat < "$config_json_path" +{ + "primaryApiKey": "xcodecli" +} +EOF + print_success "VSCode Claude config written to: $config_json_path" } # Function to display current settings diff --git a/GeminiCLI/setup-gemini.ps1 b/GeminiCLI/setup-gemini.ps1 index c924a7f..8772a54 100644 --- a/GeminiCLI/setup-gemini.ps1 +++ b/GeminiCLI/setup-gemini.ps1 @@ -86,6 +86,13 @@ function Backup-Settings { Copy-Item -Path $GeminiEnvFile -Destination $backupFile Write-Info "Backed up existing settings to: $backupFile" } + $settingsJsonPath = "$GeminiConfigDir\settings.json" + if (Test-Path $settingsJsonPath) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $backupFile = "$settingsJsonPath.backup.$timestamp" + Copy-Item -Path $settingsJsonPath -Destination $backupFile + Write-Info "Backed up existing settings to: $backupFile" + } } # Function to create settings directory @@ -165,11 +172,27 @@ function New-Settings { $envContent = @" GOOGLE_GEMINI_BASE_URL="$BaseUrl" GEMINI_API_KEY="$ApiKey" +GEMINI_MODEL="gemini-3-pro-preview" "@ - + + $settingsJson = @{ + general = @{ + previewFeatures = $true + } + security = @{ + auth = @{ + selectedType = "gemini-api-key" + } + } + } + try { Set-Content -Path $GeminiEnvFile -Value $envContent -Encoding UTF8 Write-Success "Gemini CLI settings written to: $GeminiEnvFile" + + $settingsJsonPath = "$GeminiConfigDir\settings.json" + $settingsJson | ConvertTo-Json -Depth 10 | Set-Content -Path $settingsJsonPath -Encoding UTF8 + Write-Success "Gemini CLI settings written to: $settingsJsonPath" return $true } catch { diff --git a/GeminiCLI/setup-gemini.sh b/GeminiCLI/setup-gemini.sh index 77f3503..a4adb05 100644 --- a/GeminiCLI/setup-gemini.sh +++ b/GeminiCLI/setup-gemini.sh @@ -42,6 +42,12 @@ backup_settings() { cp "$GEMINI_ENV_FILE" "$backup_file" print_info "Backed up existing settings to: $backup_file" fi + local settings_json_path="$GEMINI_CONFIG_DIR/settings.json" + if [ -f "$settings_json_path" ]; then + local backup_file="${settings_json_path}.backup.$(date +%Y%m%d_%H%M%S)" + cp "$settings_json_path" "$backup_file" + print_info "Backed up existing settings to: $backup_file" + fi } # Function to create settings directory @@ -122,8 +128,25 @@ create_settings_file() { cat < "$GEMINI_ENV_FILE" GOOGLE_GEMINI_BASE_URL="$base_url" GEMINI_API_KEY="$api_key" +GEMINI_MODEL="gemini-3-pro-preview" EOF print_success "Gemini CLI settings written to: $GEMINI_ENV_FILE" + + # Write to settings.json + local settings_json_path="$GEMINI_CONFIG_DIR/settings.json" + cat < "$settings_json_path" +{ + "general": { + "previewFeatures": true + }, + "security": { + "auth": { + "selectedType": "gemini-api-key" + } + } +} +EOF + print_success "Gemini CLI settings written to: $settings_json_path" } # Function to display current settings diff --git a/codex/setup-codex.ps1 b/codex/setup-codex.ps1 index c864933..f7d70e8 100644 --- a/codex/setup-codex.ps1 +++ b/codex/setup-codex.ps1 @@ -86,6 +86,13 @@ function Backup-Settings { Copy-Item -Path $CodexConfigFile -Destination $backupFile Write-Info "Backed up existing settings to: $backupFile" } + $authJsonPath = "$CodexConfigDir\auth.json" + if (Test-Path $authJsonPath) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $backupFile = "$authJsonPath.backup.$timestamp" + Copy-Item -Path $authJsonPath -Destination $backupFile + Write-Info "Backed up existing settings to: $backupFile" + } } # Function to create settings directory @@ -171,12 +178,20 @@ model_reasoning_effort = "high" name = "xcodecli" base_url = "$BaseUrl/v1" wire_api = "responses" -env_key = "XCODECLI_API_KEY" +env_key = "OPENAI_API_KEY" "@ + $authJson = @{ + OPENAI_API_KEY = $ApiKey + } + try { Set-Content -Path $CodexConfigFile -Value $config -Encoding UTF8 Write-Success "Codex configuration written to: $CodexConfigFile" + + $authJsonPath = "$CodexConfigDir\auth.json" + $authJson | ConvertTo-Json | Set-Content -Path $authJsonPath -Encoding UTF8 + Write-Success "Codex auth file written to: $authJsonPath" return $true } catch { @@ -195,23 +210,23 @@ function Show-Settings { } else { Write-Info "No existing Codex configuration found." } - - Write-Host "" - Write-Info "Current environment variables:" - Write-Host "----------------------------------------" - $apirouterKey = [Environment]::GetEnvironmentVariable("XCODECLI_API_KEY", [EnvironmentVariableTarget]::User) - - if ($apirouterKey) { - $maskedKey = if ($apirouterKey.Length -gt 12) { - "$($apirouterKey.Substring(0, 8))...$($apirouterKey.Substring($apirouterKey.Length - 4))" - } else { - "$($apirouterKey.Substring(0, [Math]::Min(4, $apirouterKey.Length)))..." + + $authJsonPath = "$CodexConfigDir\auth.json" + if (Test-Path $authJsonPath) { + Write-Host "" + Write-Info "Auth file: $authJsonPath" + Write-Host "----------------------------------------" + $authContent = Get-Content $authJsonPath -Raw | ConvertFrom-Json + if ($authContent.OPENAI_API_KEY) { + $maskedKey = if ($authContent.OPENAI_API_KEY.Length -gt 12) { + "$($authContent.OPENAI_API_KEY.Substring(0, 8))...$($authContent.OPENAI_API_KEY.Substring($authContent.OPENAI_API_KEY.Length - 4))" + } else { + "$($authContent.OPENAI_API_KEY.Substring(0, [Math]::Min(4, $authContent.OPENAI_API_KEY.Length)))..." + } + Write-Info "OPENAI_API_KEY: $maskedKey" } - Write-Info "XCODECLI_API_KEY: $maskedKey" - } else { - Write-Info "XCODECLI_API_KEY: (not set)" + Write-Host "----------------------------------------" } - Write-Host "----------------------------------------" } # Main function @@ -301,31 +316,12 @@ function Main { # Create new settings if (New-Settings -BaseUrl $BaseUrl -ApiKey $ApiKey) { - Write-Host "" - - # Also set environment variables for Windows - Write-Info "Setting environment variables..." - try { - # Set user environment variables (persistent across sessions) - [Environment]::SetEnvironmentVariable("XCODECLI_API_KEY", $ApiKey, [EnvironmentVariableTarget]::User) - - # Also set for current session - $env:XCODECLI_API_KEY = $ApiKey - - Write-Success "Environment variables set successfully" - } - catch { - Write-Warning "Failed to set environment variables: $($_.Exception.Message)" - Write-Info "You may need to set them manually:" - Write-Info " XCODECLI_API_KEY=$ApiKey" - } - Write-Host "" Write-Success "Codex has been configured successfully!" Write-Info "You can now use Codex with your XCodeCLI API router." Write-Info "" - Write-Info "Configuration file location: $CodexConfigFile" - Write-Info "Environment variable XCODECLI_API_KEY has been set" + Write-Info "Configuration file: $CodexConfigFile" + Write-Info "Auth file: $CodexConfigDir\auth.json" if (Test-Path $CodexConfigFile) { Write-Host "" diff --git a/codex/setup-codex.sh b/codex/setup-codex.sh index 03f61ad..4c7a832 100644 --- a/codex/setup-codex.sh +++ b/codex/setup-codex.sh @@ -38,7 +38,7 @@ API_KEY="" # Function to show help show_help() { - cat << EOF + cat < "$HOME/.codex/config.toml" << EOF + cat >"$HOME/.codex/config.toml" < "$HOME/.codex/auth.json" << EOF + cat >"$HOME/.codex/auth.json" </dev/null || echo 'unknown')}" - print_info "Using config file: $shell_config" - - # Handle Fish shell differently (uses 'set -x' instead of 'export') - if [ "$shell_name" = "fish" ] || [[ "$shell_config" == *"fish"* ]]; then - # Fish shell syntax - if [ -f "$shell_config" ] && grep -q "set -x XCODECLI_API_KEY" "$shell_config"; then - # Update existing - if [[ "$OSTYPE" == "darwin"* ]]; then - sed -i '' "s/set -x XCODECLI_API_KEY.*/set -x XCODECLI_API_KEY \"$api_key\"/" "$shell_config" - else - sed -i "s/set -x XCODECLI_API_KEY.*/set -x XCODECLI_API_KEY \"$api_key\"/" "$shell_config" - fi - print_info "Updated XCODECLI_API_KEY in $shell_config" - else - # Add new - mkdir -p "$(dirname "$shell_config")" - echo "" >> "$shell_config" - echo "# API Router API key for Codex" >> "$shell_config" - echo "set -x XCODECLI_API_KEY \"$api_key\"" >> "$shell_config" - print_info "Added XCODECLI_API_KEY to $shell_config" - fi - else - # Bash/Zsh/sh syntax - if [ -f "$shell_config" ] && grep -q "export XCODECLI_API_KEY=" "$shell_config"; then - # Update existing - if [[ "$OSTYPE" == "darwin"* ]]; then - # macOS - sed -i '' "s/export XCODECLI_API_KEY=.*/export XCODECLI_API_KEY=\"$api_key\"/" "$shell_config" - else - # Linux - sed -i "s/export XCODECLI_API_KEY=.*/export XCODECLI_API_KEY=\"$api_key\"/" "$shell_config" - fi - print_info "Updated XCODECLI_API_KEY in $shell_config" - else - # Add new - echo "" >> "$shell_config" - echo "# API Router API key for Codex" >> "$shell_config" - echo "export XCODECLI_API_KEY=\"$api_key\"" >> "$shell_config" - print_info "Added XCODECLI_API_KEY to $shell_config" - fi - fi - - return 0 -} - # Function to show current settings show_current_settings() { print_info "Current Codex settings:" echo "----------------------------------------" - + if [ -f "$HOME/.codex/config.toml" ]; then print_info "Configuration file: $HOME/.codex/config.toml" echo "" @@ -297,18 +209,20 @@ show_current_settings() { else print_info "No configuration file found at $HOME/.codex/config.toml" fi - + echo "----------------------------------------" - print_info "Environment variable:" - - if [ ! -z "$XCODECLI_API_KEY" ]; then - local masked_key="${XCODECLI_API_KEY:0:8}...${XCODECLI_API_KEY: -4}" - print_info "XCODECLI_API_KEY: $masked_key" - else - print_info "XCODECLI_API_KEY: (not set)" + + if [ -f "$HOME/.codex/auth.json" ]; then + print_info "Auth file: $HOME/.codex/auth.json" + echo "----------------------------------------" + local api_key + api_key=$(grep -o '"OPENAI_API_KEY"[[:space:]]*:[[:space:]]*"[^"]*"' "$HOME/.codex/auth.json" | sed 's/.*: *"//' | sed 's/"$//') + if [ -n "$api_key" ]; then + local masked_key="${api_key:0:8}...${api_key: -4}" + print_info "OPENAI_API_KEY: $masked_key" + fi + echo "----------------------------------------" fi - - echo "----------------------------------------" } # Main function @@ -390,28 +304,12 @@ main() { exit 1 fi - # Set environment variable - if ! set_environment_variable "$API_KEY"; then - print_warning "Failed to set environment variable automatically" - print_info "Please set manually: export XCODECLI_API_KEY=\"$API_KEY\"" - fi - echo "" print_success "Codex has been configured successfully!" print_info "You can now use Codex with your XCodeCLI API router." print_info "" - print_info "To apply the environment variable in your current session, run:" - - # Provide correct command based on detected shell - local current_shell=$(basename "$SHELL" 2>/dev/null || echo "bash") - if [ "$current_shell" = "fish" ]; then - print_info " set -x XCODECLI_API_KEY \"$API_KEY\"" - else - print_info " export XCODECLI_API_KEY=\"$API_KEY\"" - fi - print_info "Or restart your terminal." - print_info "" print_info "Configuration file: $HOME/.codex/config.toml" + print_info "Auth file: $HOME/.codex/auth.json" # Show current settings echo "" diff --git a/setup-claude-code.ps1 b/setup-claude-code.ps1 index e839536..e17fc8b 100644 --- a/setup-claude-code.ps1 +++ b/setup-claude-code.ps1 @@ -83,6 +83,13 @@ function Backup-Settings { Copy-Item -Path $ClaudeSettingsFile -Destination $backupFile Write-Info "Backed up existing settings to: $backupFile" } + $configJsonPath = "$ClaudeConfigDir\config.json" + if (Test-Path $configJsonPath) { + $timestamp = Get-Date -Format "yyyyMMdd_HHmmss" + $backupFile = "$configJsonPath.backup.$timestamp" + Copy-Item -Path $configJsonPath -Destination $backupFile + Write-Info "Backed up existing config to: $backupFile" + } } # Function to create settings directory @@ -173,6 +180,12 @@ function New-Settings { $json = $settings | ConvertTo-Json -Depth 10 Set-Content -Path $ClaudeSettingsFile -Value $json -Encoding UTF8 Write-Success "Claude Code settings written to: $ClaudeSettingsFile" + + # Write config.json for VSCode Claude extension + $configJsonPath = "$ClaudeConfigDir\config.json" + $configJson = @{ primaryApiKey = "xcodecli" } + $configJson | ConvertTo-Json | Set-Content -Path $configJsonPath -Encoding UTF8 + Write-Success "VSCode Claude config written to: $configJsonPath" return $true } catch { @@ -192,30 +205,6 @@ function Show-Settings { } else { Write-Info "No existing Claude Code settings found." } - - Write-Host "" - Write-Info "Current environment variables:" - Write-Host "----------------------------------------" - $baseUrl = [Environment]::GetEnvironmentVariable("ANTHROPIC_BASE_URL", [EnvironmentVariableTarget]::User) - $authToken = [Environment]::GetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", [EnvironmentVariableTarget]::User) - - if ($baseUrl) { - Write-Info "ANTHROPIC_BASE_URL: $baseUrl" - } else { - Write-Info "ANTHROPIC_BASE_URL: (not set)" - } - - if ($authToken) { - $maskedToken = if ($authToken.Length -gt 12) { - "$($authToken.Substring(0, 8))...$($authToken.Substring($authToken.Length - 4))" - } else { - "$($authToken.Substring(0, [Math]::Min(4, $authToken.Length)))..." - } - Write-Info "ANTHROPIC_AUTH_TOKEN: $maskedToken" - } else { - Write-Info "ANTHROPIC_AUTH_TOKEN: (not set)" - } - Write-Host "----------------------------------------" } # Main function @@ -305,28 +294,6 @@ function Main { # Create new settings if (New-Settings -BaseUrl $BaseUrl -ApiKey $ApiKey) { - Write-Host "" - - # Also set environment variables for Windows - Write-Info "Setting environment variables..." - try { - # Set user environment variables (persistent across sessions) - [Environment]::SetEnvironmentVariable("ANTHROPIC_BASE_URL", $BaseUrl, [EnvironmentVariableTarget]::User) - [Environment]::SetEnvironmentVariable("ANTHROPIC_AUTH_TOKEN", $ApiKey, [EnvironmentVariableTarget]::User) - - # Also set for current session - $env:ANTHROPIC_BASE_URL = $BaseUrl - $env:ANTHROPIC_AUTH_TOKEN = $ApiKey - - Write-Success "Environment variables set successfully" - } - catch { - Write-Warning "Failed to set environment variables: $($_.Exception.Message)" - Write-Info "You may need to set them manually:" - Write-Info " ANTHROPIC_BASE_URL=$BaseUrl" - Write-Info " ANTHROPIC_AUTH_TOKEN=$ApiKey" - } - Write-Host "" Write-Success "Claude Code has been configured successfully!" Write-Info "You can now use Claude Code with your API router." @@ -335,7 +302,6 @@ function Main { Write-Info " claude --version" Write-Info "" Write-Info "Configuration file location: $ClaudeSettingsFile" - Write-Info "Environment variables have been set for ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN" if (Test-Path $ClaudeSettingsFile) { Write-Host "" diff --git a/setup-claude-code.sh b/setup-claude-code.sh index 9a6dfa7..628b86b 100644 --- a/setup-claude-code.sh +++ b/setup-claude-code.sh @@ -37,7 +37,7 @@ print_error() { # Function to check if jq is installed check_jq() { - if ! command -v jq &> /dev/null; then + if ! command -v jq &>/dev/null; then print_error "jq is required but not installed." print_info "Please install jq:" print_info " macOS: brew install jq" @@ -54,6 +54,12 @@ backup_settings() { cp "$CLAUDE_SETTINGS_FILE" "$backup_file" print_info "Backed up existing settings to: $backup_file" fi + local config_json_path="$CLAUDE_CONFIG_DIR/config.json" + if [ -f "$config_json_path" ]; then + local backup_file="${config_json_path}.backup.$(date +%Y%m%d_%H%M%S)" + cp "$config_json_path" "$backup_file" + print_info "Backed up existing config to: $backup_file" + fi } # Function to create settings directory @@ -128,7 +134,7 @@ test_api_connection() { create_settings() { local base_url="$1" local api_key="$2" - + # Create JSON using jq to ensure proper escaping local settings_json settings_json=$(jq -n \ @@ -140,19 +146,29 @@ create_settings() { "ANTHROPIC_AUTH_TOKEN": $api_key, "DISABLE_TELEMETRY": 1, "DISABLE_ERROR_REPORTING": 1, + "API_TIMEOUT_MS": 600000, "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1 } }') - + # Validate JSON - if ! echo "$settings_json" | jq . > /dev/null 2>&1; then + if ! echo "$settings_json" | jq . >/dev/null 2>&1; then print_error "Generated settings JSON is invalid" return 1 fi - + # Write settings file - echo "$settings_json" > "$CLAUDE_SETTINGS_FILE" + echo "$settings_json" >"$CLAUDE_SETTINGS_FILE" print_success "Claude Code settings written to: $CLAUDE_SETTINGS_FILE" + + # Write config.json for VSCode Claude extension + local config_json_path="$CLAUDE_CONFIG_DIR/config.json" + cat < "$config_json_path" +{ + "primaryApiKey": "xcodecli" +} +EOF + print_success "VSCode Claude config written to: $config_json_path" } # Function to display current settings @@ -172,10 +188,10 @@ main() { print_info "Claude Code Configuration Script for XCodeCLI" echo "=======================================================" echo - + # Check dependencies check_jq - + # Parse command line arguments local api_key="" local test_only=false @@ -188,20 +204,20 @@ main() { while [[ $# -gt 0 ]]; do case $1 in - -k|--key) - api_key="$2" - shift 2 - ;; - -t|--test) - test_only=true - shift - ;; - -s|--show) - show_settings=true - shift - ;; - -h|--help) - cat <