- 新增包管理器检测(Node.js/npm 和 Bun) - 新增 Bun 安装引导功能 - 新增工具安装功能(通过 npm/bun 安装 CLI 工具) - 支持从远程下载并执行配置脚本 - 移除 Claude Code 配置中的默认 model 设置
306 lines
8.8 KiB
PowerShell
306 lines
8.8 KiB
PowerShell
# XCodeCLI Setup Launcher (Windows)
|
||
# 一站式安装和配置 Claude Code, Gemini CLI, Codex
|
||
|
||
param(
|
||
[string]$ApiKey,
|
||
[switch]$Help
|
||
)
|
||
|
||
# 支持一行命令传入 API Key: $key='xxx'; iwr ... | iex
|
||
if (-not $ApiKey -and (Test-Path Variable:key)) { $ApiKey = $key }
|
||
|
||
# ========== 颜色输出函数 ==========
|
||
function Write-Info { param([string]$Message); Write-Host "[INFO]" -ForegroundColor Blue -NoNewline; Write-Host " $Message" }
|
||
function Write-Success { param([string]$Message); Write-Host "[SUCCESS]" -ForegroundColor Green -NoNewline; Write-Host " $Message" }
|
||
function Write-Warning { param([string]$Message); Write-Host "[WARNING]" -ForegroundColor Yellow -NoNewline; Write-Host " $Message" }
|
||
function Write-Error { param([string]$Message); Write-Host "[ERROR]" -ForegroundColor Red -NoNewline; Write-Host " $Message" }
|
||
|
||
# ========== 工具配置表 ==========
|
||
$ToolsConfig = @{
|
||
1 = @{
|
||
Name = "Claude Code"
|
||
Command = "claude"
|
||
Package = "@anthropic-ai/claude-code"
|
||
SetupUrl = "https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/ClaudeCode/setup-claude-code.ps1"
|
||
}
|
||
2 = @{
|
||
Name = "Gemini CLI"
|
||
Command = "gemini"
|
||
Package = "@google/gemini-cli@latest"
|
||
SetupUrl = "https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/GeminiCLI/setup-gemini.ps1"
|
||
}
|
||
3 = @{
|
||
Name = "Codex"
|
||
Command = "codex"
|
||
Package = "@openai/codex"
|
||
SetupUrl = "https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/codex/setup-codex.ps1"
|
||
}
|
||
}
|
||
|
||
# ========== 帮助信息 ==========
|
||
function Show-Help {
|
||
Write-Host @"
|
||
XCodeCLI Setup Launcher (Windows)
|
||
一站式安装和配置 Claude Code, Gemini CLI, Codex
|
||
|
||
Usage: powershell -ExecutionPolicy Bypass -File setup.ps1 [OPTIONS]
|
||
|
||
Options:
|
||
-ApiKey <KEY> 预设 API 密钥(可选)
|
||
-Help 显示此帮助信息
|
||
|
||
一行命令快速使用:
|
||
`$key='YOUR_API_KEY'; iwr -useb https://gitea.sususu.cf/sususu/xcodecli-shells/raw/branch/main/setup.ps1 | iex
|
||
"@
|
||
exit 0
|
||
}
|
||
|
||
# ========== 工具函数 ==========
|
||
function Test-Command {
|
||
param([string]$Name)
|
||
return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
|
||
}
|
||
|
||
function Refresh-Path {
|
||
$env:Path = [Environment]::GetEnvironmentVariable("Path", "User") + ";" + [Environment]::GetEnvironmentVariable("Path", "Machine")
|
||
}
|
||
|
||
# ========== 包管理器检测 ==========
|
||
function Get-PackageManager {
|
||
# 优先检测 Node.js/npm
|
||
if (Test-Command "node") {
|
||
try {
|
||
$nodeVersion = (& node --version 2>$null) -replace 'v', ''
|
||
Write-Info "检测到 Node.js v$nodeVersion"
|
||
return @{ Type = "npm"; Cmd = "npm install -g" }
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
# 其次检测 Bun
|
||
if (Test-Command "bun") {
|
||
try {
|
||
$bunVersion = & bun --version 2>$null
|
||
Write-Info "检测到 Bun v$bunVersion"
|
||
return @{ Type = "bun"; Cmd = "bun add -g" }
|
||
}
|
||
catch { }
|
||
}
|
||
|
||
return $null
|
||
}
|
||
|
||
# ========== Bun 安装引导 ==========
|
||
function Install-Bun {
|
||
Write-Host ""
|
||
Write-Warning "未检测到 Node.js 或 Bun"
|
||
Write-Info "推荐安装 Bun(轻量级 JavaScript 运行时)"
|
||
Write-Host ""
|
||
Write-Host " 安装命令: " -NoNewline
|
||
Write-Host 'powershell -c "irm bun.sh/install.ps1|iex"' -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host " 要求: Windows 10 version 1809 或更高" -ForegroundColor Gray
|
||
Write-Host ""
|
||
|
||
$install = Read-Host "是否立即安装 Bun? (Y/n)"
|
||
if ($install -eq "n" -or $install -eq "N") {
|
||
return $false
|
||
}
|
||
|
||
Write-Info "正在安装 Bun..."
|
||
try {
|
||
Invoke-Expression 'irm bun.sh/install.ps1 | iex'
|
||
Refresh-Path
|
||
|
||
if (Test-Command "bun") {
|
||
Write-Success "Bun 安装成功!"
|
||
return $true
|
||
}
|
||
else {
|
||
Write-Warning "Bun 可能已安装,但需要重新打开终端才能生效"
|
||
Write-Info "请重新打开 PowerShell 后再运行此脚本"
|
||
return $false
|
||
}
|
||
}
|
||
catch {
|
||
Write-Error "Bun 安装失败: $($_.Exception.Message)"
|
||
return $false
|
||
}
|
||
}
|
||
|
||
# ========== 工具安装 ==========
|
||
function Install-Tool {
|
||
param(
|
||
[hashtable]$Tool
|
||
)
|
||
|
||
# 获取包管理器
|
||
$pm = Get-PackageManager
|
||
if (-not $pm) {
|
||
if (-not (Install-Bun)) {
|
||
return $false
|
||
}
|
||
Refresh-Path
|
||
$pm = Get-PackageManager
|
||
if (-not $pm) {
|
||
Write-Error "仍未检测到可用的包管理器"
|
||
return $false
|
||
}
|
||
}
|
||
|
||
Write-Info "使用 $($pm.Type) 安装 $($Tool.Name)..."
|
||
$installCmd = "$($pm.Cmd) $($Tool.Package)"
|
||
Write-Host " 执行: $installCmd" -ForegroundColor Gray
|
||
|
||
try {
|
||
Invoke-Expression $installCmd
|
||
$exitCode = $LASTEXITCODE
|
||
Refresh-Path
|
||
|
||
# 检查安装命令退出码
|
||
if ($exitCode -ne 0) {
|
||
Write-Error "安装命令返回错误码: $exitCode"
|
||
return $false
|
||
}
|
||
|
||
if (Test-Command $Tool.Command) {
|
||
Write-Success "$($Tool.Name) 安装成功!"
|
||
return $true
|
||
}
|
||
else {
|
||
Write-Warning "$($Tool.Name) 可能已安装,但需要重新打开终端才能生效"
|
||
$continue = Read-Host "是否继续进行配置? (Y/n)"
|
||
return ($continue -ne "n" -and $continue -ne "N")
|
||
}
|
||
}
|
||
catch {
|
||
Write-Error "安装失败: $($_.Exception.Message)"
|
||
return $false
|
||
}
|
||
}
|
||
|
||
# ========== 远程配置脚本调用 ==========
|
||
function Invoke-RemoteSetup {
|
||
param(
|
||
[hashtable]$Tool,
|
||
[string]$ApiKey
|
||
)
|
||
|
||
Write-Host ""
|
||
Write-Info "下载并执行 $($Tool.Name) 配置脚本..."
|
||
Write-Host " URL: $($Tool.SetupUrl)" -ForegroundColor Gray
|
||
Write-Host ""
|
||
|
||
$tempFile = $null
|
||
try {
|
||
# 下载脚本到临时文件
|
||
$tempFile = [System.IO.Path]::ChangeExtension([System.IO.Path]::GetTempFileName(), ".ps1")
|
||
Invoke-WebRequest -Uri $Tool.SetupUrl -UseBasicParsing -OutFile $tempFile
|
||
|
||
# 执行脚本,正确传递参数
|
||
$LASTEXITCODE = 0
|
||
if ($ApiKey) {
|
||
& $tempFile -ApiKey $ApiKey
|
||
}
|
||
else {
|
||
& $tempFile
|
||
}
|
||
|
||
$scriptSucceeded = $?
|
||
$exitCode = $LASTEXITCODE
|
||
|
||
# 清理临时文件
|
||
Remove-Item $tempFile -ErrorAction SilentlyContinue
|
||
|
||
# 检查执行结果
|
||
if (-not $scriptSucceeded -or $exitCode -ne 0) {
|
||
Write-Error "配置脚本执行失败,退出码: $exitCode"
|
||
return $false
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Success "$($Tool.Name) 配置完成!"
|
||
return $true
|
||
}
|
||
catch {
|
||
if ($tempFile) { Remove-Item $tempFile -ErrorAction SilentlyContinue }
|
||
Write-Error "配置脚本执行失败: $($_.Exception.Message)"
|
||
return $false
|
||
}
|
||
}
|
||
|
||
# ========== 菜单显示 ==========
|
||
function Show-Menu {
|
||
Write-Host ""
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host " XCodeCLI Setup Launcher" -ForegroundColor Cyan
|
||
Write-Host "========================================" -ForegroundColor Cyan
|
||
Write-Host ""
|
||
Write-Host "选择要安装和配置的工具:" -ForegroundColor Yellow
|
||
Write-Host ""
|
||
|
||
foreach ($key in ($ToolsConfig.Keys | Sort-Object)) {
|
||
$tool = $ToolsConfig[$key]
|
||
$installed = Test-Command $tool.Command
|
||
$status = if ($installed) { "[已安装]" } else { "[未安装]" }
|
||
$color = if ($installed) { "Green" } else { "Red" }
|
||
$label = " [$key] $($tool.Name.PadRight(12))"
|
||
Write-Host "$label " -NoNewline
|
||
Write-Host $status -ForegroundColor $color
|
||
}
|
||
|
||
Write-Host ""
|
||
Write-Host " [0] 退出" -ForegroundColor Gray
|
||
Write-Host ""
|
||
}
|
||
|
||
# ========== 主函数 ==========
|
||
function Main {
|
||
if ($Help) { Show-Help }
|
||
|
||
Show-Menu
|
||
$choice = Read-Host "请选择 (0-3)"
|
||
|
||
# 退出选项
|
||
if ($choice -eq "0") {
|
||
Write-Info "再见!"
|
||
exit 0
|
||
}
|
||
|
||
# 验证选择
|
||
$choiceNum = 0
|
||
if (-not [int]::TryParse($choice, [ref]$choiceNum) -or $choiceNum -lt 1 -or $choiceNum -gt 3) {
|
||
Write-Error "无效的选择"
|
||
exit 1
|
||
}
|
||
|
||
$tool = $ToolsConfig[$choiceNum]
|
||
|
||
# 检测是否已安装
|
||
if (-not (Test-Command $tool.Command)) {
|
||
Write-Host ""
|
||
Write-Warning "$($tool.Name) 未安装"
|
||
$install = Read-Host "是否立即安装? (Y/n)"
|
||
|
||
if ($install -eq "n" -or $install -eq "N") {
|
||
Write-Info "已取消"
|
||
exit 0
|
||
}
|
||
|
||
if (-not (Install-Tool -Tool $tool)) {
|
||
exit 1
|
||
}
|
||
}
|
||
else {
|
||
Write-Host ""
|
||
Write-Success "$($tool.Name) 已安装"
|
||
}
|
||
|
||
# 调用远程配置脚本
|
||
if (-not (Invoke-RemoteSetup -Tool $tool -ApiKey $ApiKey)) {
|
||
exit 1
|
||
}
|
||
}
|
||
|
||
Main
|