<# .SYNOPSIS apicheap.store 1-Click Client Setup Script Tu dong / Automatic comprehensive setup for Claude Code CLI and OpenAI Codex App / CLI. #> param( [string]$ApiKey = "", [string]$Model = "", [string]$SubagentModel = "", [string]$BaseUrl = "https://apicheap.store", [string]$Lang = "" ) $ErrorActionPreference = "Stop" function Write-Utf8NoBom([string]$filePath, [string]$content) { $fileDir = [System.IO.Path]::GetDirectoryName($filePath) if (-not [string]::IsNullOrEmpty($fileDir) -and -not (Test-Path $fileDir)) { [System.IO.Directory]::CreateDirectory($fileDir) | Out-Null } $encoding = New-Object System.Text.UTF8Encoding($false) [System.IO.File]::WriteAllText($filePath, $content, $encoding) } function Read-Utf8Clean([string]$filePath) { if (-not (Test-Path $filePath)) { return $null } $text = [System.IO.File]::ReadAllText($filePath, [System.Text.Encoding]::UTF8) return ($text -replace "^", "") } if ([string]::IsNullOrWhiteSpace($Lang)) { if (-not [string]::IsNullOrWhiteSpace($env:QUOTAROUTER_LANG)) { $Lang = $env:QUOTAROUTER_LANG.Trim() } else { try { $uiCulture = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName.ToLower() if ($uiCulture -eq "vi") { $Lang = "vi" } else { $Lang = "en" } } catch { $Lang = "vi" } } } $isEn = ($Lang.ToLower() -eq "en") Write-Host "" Write-Host "========================================================" -ForegroundColor Cyan Write-Host " APICHEAP.STORE 1-CLICK CLIENT AUTO SETUP " -ForegroundColor Yellow Write-Host " Online Gateway: $BaseUrl " -ForegroundColor Cyan Write-Host "========================================================" -ForegroundColor Cyan Write-Host "" # 1. Kiem tra hoac hoi API Key if ([string]::IsNullOrWhiteSpace($ApiKey)) { if (-not [string]::IsNullOrWhiteSpace($env:QUOTAROUTER_API_KEY)) { $ApiKey = $env:QUOTAROUTER_API_KEY.Trim() } elseif (-not [string]::IsNullOrWhiteSpace($global:ApiKey)) { $ApiKey = $global:ApiKey.Trim() } } while ([string]::IsNullOrWhiteSpace($ApiKey)) { $apiPrompt = if ($isEn) { '[-] Enter your apicheap.store API Key (sk-...)' } else { '[-] Nhap API Key apicheap.store cua ban (sk-...)' } $ApiKey = (Read-Host $apiPrompt).Trim() } $fetchedCombos = @() try { $comboHeaders = @{ Authorization = "Bearer $ApiKey"; Accept = 'application/json' } $comboResponse = Invoke-RestMethod -Uri "$BaseUrl/api/combos" -Headers $comboHeaders -Method Get -TimeoutSec 10 if ($comboResponse.ok -and $comboResponse.combos) { $fetchedCombos = @($comboResponse.combos | Where-Object { $_.status -eq 'active' }) } } catch { if ($isEn) { Write-Host "[!] Could not load account combos: $($_.Exception.Message)" -ForegroundColor Yellow } else { Write-Host "[!] Khong the tai combo trong tai khoan: $($_.Exception.Message)" -ForegroundColor Yellow } } if ([string]::IsNullOrWhiteSpace($Model)) { Write-Host "" if ($fetchedCombos.Count -gt 0) { if ($isEn) { Write-Host "[OK] FOUND ACTIVE COMBOS IN YOUR ACCOUNT:" -ForegroundColor Green } else { Write-Host "[OK] TIM THAY DANH SACH COMBO TRONG TAI KHOAN CUA BAN:" -ForegroundColor Green } for ($i = 0; $i -lt $fetchedCombos.Count; $i++) { $c = $fetchedCombos[$i] $mList = @() if ($c.members) { foreach ($m in $c.members) { if ($m.model_id) { $mList += $m.model_id } else { $mList += $m } } } $chain = $mList -join " -> " $num = $i + 1 Write-Host " $num) " -NoNewline -ForegroundColor Yellow Write-Host "$($c.name)" -NoNewline -ForegroundColor White Write-Host " (Fallback: $chain)" -ForegroundColor Gray } Write-Host "" $defaultCombo = $fetchedCombos[0].name $totalCount = $fetchedCombos.Count if ($isEn) { Write-Host "[*] View all models & create new combos at: $BaseUrl/portal#/models" -ForegroundColor DarkGray $promptMsg = "[-] Select Combo [1-$totalCount] or enter Model / Combo name (Default: 1 - $defaultCombo): " } else { Write-Host "[*] Xem danh sach Model & tao them Combo tai: $BaseUrl/portal#/models" -ForegroundColor DarkGray $promptMsg = "[-] Chon Combo [1-$totalCount] hoac nhap ten Model / Combo khac (Mac dinh: 1 - $defaultCombo): " } $choice = Read-Host $promptMsg if ($null -ne $choice) { $choice = $choice.Trim() } if ([string]::IsNullOrWhiteSpace($choice) -or $choice -eq "1") { $Model = $defaultCombo } elseif ($choice -match '^\d+$' -and [int]$choice -le $totalCount -and [int]$choice -ge 1) { $idx = [int]$choice - 1 $Model = $fetchedCombos[$idx].name } else { $Model = $choice } } else { if ($isEn) { Write-Host "[i] No routing Combos found in your account." -ForegroundColor Yellow Write-Host "[*] -> View all available Models & create Combos at: $BaseUrl/portal#/models" -ForegroundColor Cyan Write-Host "" while ([string]::IsNullOrWhiteSpace($Model)) { $inputM = Read-Host "[-] Enter the Combo or Model name you want to use" if ($null -ne $inputM) { $Model = $inputM.Trim() } if ([string]::IsNullOrWhiteSpace($Model)) { Write-Host "[!] Please enter a valid Model or Combo name (see list at $BaseUrl/portal#/models)" -ForegroundColor Red } } } else { Write-Host "[i] Tai khoan cua ban hien chua tao Combo dinh tuyen nao." -ForegroundColor Yellow Write-Host "[*] -> Xem danh sach Model & tao Combo tai: $BaseUrl/portal#/models" -ForegroundColor Cyan Write-Host "" while ([string]::IsNullOrWhiteSpace($Model)) { $inputM = Read-Host "[-] Nhap ten Combo hoac Model ban muon dung" if ($null -ne $inputM) { $Model = $inputM.Trim() } if ([string]::IsNullOrWhiteSpace($Model)) { Write-Host "[!] Vui long nhap ten Model hoac Combo (xem danh sach tren $BaseUrl/portal#/models)" -ForegroundColor Red } } } } } if ([string]::IsNullOrWhiteSpace($SubagentModel)) { $SubagentModel = $Model } Write-Host "" if ($isEn) { Write-Host "=> Selected default Model / Combo: $Model" -ForegroundColor Yellow } else { Write-Host "=> Da chon Model / Combo mac dinh: $Model" -ForegroundColor Yellow } # 3. Thiet lap bien moi truong Windows User Write-Host "" if ($isEn) { Write-Host "[1/4] Updating user environment variables (User Environment)..." -ForegroundColor Green } else { Write-Host "[1/4] Dang cap nhat bien moi truong he thong (User Environment)..." -ForegroundColor Green } $envVars = @{ "ANTHROPIC_BASE_URL" = $BaseUrl "CLAUDE_CODE_API_BASE_URL" = $BaseUrl "ANTHROPIC_AUTH_TOKEN" = $ApiKey "ANTHROPIC_MODEL" = $Model "CLAUDE_DEFAULT_MODEL" = $Model "ANTHROPIC_DEFAULT_SONNET_MODEL"= $Model "ANTHROPIC_DEFAULT_OPUS_MODEL" = $Model "ANTHROPIC_DEFAULT_HAIKU_MODEL" = $SubagentModel "ANTHROPIC_SUBAGENT_MODEL" = $SubagentModel "CLAUDE_CODE_SUBAGENT_MODEL" = $SubagentModel "ANTHROPIC_FAST_MODEL" = $SubagentModel "ANTHROPIC_SMALL_FAST_MODEL" = $SubagentModel "QUOTAROUTER_API_KEY" = $ApiKey "OPENAI_BASE_URL" = "$BaseUrl/v1" "OPENAI_API_BASE" = "$BaseUrl/v1" "OPENAI_API_KEY" = $ApiKey } foreach ($k in $envVars.Keys) { [System.Environment]::SetEnvironmentVariable($k, $envVars[$k], "User") [System.Environment]::SetEnvironmentVariable($k, $envVars[$k], "Process") $shownValue = if ($k -match '(KEY|TOKEN)$') { $envVars[$k].Substring(0, [Math]::Min(8, $envVars[$k].Length)) + '...' } else { $envVars[$k] } Write-Host " + $k = $shownValue" -ForegroundColor Gray } foreach ($legacyVar in @('ANTHROPIC_API_KEY', 'NINEROUTER_API_KEY')) { [System.Environment]::SetEnvironmentVariable($legacyVar, $null, 'User') [System.Environment]::SetEnvironmentVariable($legacyVar, $null, 'Process') } # 4. Cap nhat cau hinh Claude Code CLI (~/.claude/settings.json) Write-Host "" if ($isEn) { Write-Host "[2/4] Checking and configuring Claude Code CLI (~/.claude/settings.json)..." -ForegroundColor Green } else { Write-Host "[2/4] Dang kiem tra va cau hinh Claude Code CLI (~/.claude/settings.json)..." -ForegroundColor Green } $claudeDir = Join-Path $env:USERPROFILE ".claude" $claudeSettings = Join-Path $claudeDir "settings.json" if (-not (Test-Path $claudeDir)) { New-Item -ItemType Directory -Path $claudeDir -Force | Out-Null } if (-not (Test-Path $claudeSettings)) { $defaultSettings = [PSCustomObject]@{ env = [PSCustomObject]@{} model = $Model } Write-Utf8NoBom $claudeSettings ($defaultSettings | ConvertTo-Json -Depth 5) if ($isEn) { Write-Host " + Initialized new $claudeSettings ready for Claude Code" -ForegroundColor Gray } else { Write-Host " + Da khoi tao moi $claudeSettings san sang cho Claude Code" -ForegroundColor Gray } } try { $rawSettings = Get-Content $claudeSettings -Raw -Encoding UTF8 $rawSettings = $rawSettings -replace '^\uFEFF', '' $settingsJson = $rawSettings | ConvertFrom-Json if (-not $settingsJson.env) { $settingsJson | Add-Member -MemberType NoteProperty -Name "env" -Value ([PSCustomObject]@{}) -Force } $claudeEnvProps = @{ "ANTHROPIC_BASE_URL" = $BaseUrl "CLAUDE_CODE_API_BASE_URL" = $BaseUrl "ANTHROPIC_AUTH_TOKEN" = $ApiKey "ANTHROPIC_MODEL" = $Model "CLAUDE_DEFAULT_MODEL" = $Model "ANTHROPIC_DEFAULT_SONNET_MODEL"= $Model "ANTHROPIC_DEFAULT_OPUS_MODEL" = $Model "ANTHROPIC_DEFAULT_HAIKU_MODEL" = $SubagentModel "ANTHROPIC_SUBAGENT_MODEL" = $SubagentModel "CLAUDE_CODE_SUBAGENT_MODEL" = $SubagentModel "ANTHROPIC_FAST_MODEL" = $SubagentModel "ANTHROPIC_SMALL_FAST_MODEL" = $SubagentModel } foreach ($legacyProp in @('ANTHROPIC_API_KEY', 'NINEROUTER_API_KEY')) { if ($null -ne $settingsJson.env.PSObject.Properties[$legacyProp]) { $settingsJson.env.PSObject.Properties.Remove($legacyProp) } } foreach ($prop in $claudeEnvProps.Keys) { if ($null -ne $settingsJson.env.PSObject.Properties[$prop]) { $settingsJson.env.$prop = $claudeEnvProps[$prop] } else { $settingsJson.env | Add-Member -MemberType NoteProperty -Name $prop -Value $claudeEnvProps[$prop] -Force } } if ($null -ne $settingsJson.PSObject.Properties["model"]) { $settingsJson.model = $Model } else { $settingsJson | Add-Member -MemberType NoteProperty -Name "model" -Value $Model -Force } Write-Utf8NoBom $claudeSettings ($settingsJson | ConvertTo-Json -Depth 30) if ($isEn) { Write-Host " + Updated settings.json for Claude Code (Model: $Model, URL: $BaseUrl)" -ForegroundColor Gray } else { Write-Host " + Da cap nhat settings.json cho Claude Code (Model: $Model, URL: $BaseUrl)" -ForegroundColor Gray } } catch { Write-Error "Claude settings.json: $($_.Exception.Message)" exit 1 } $providersCfg = Join-Path $claudeDir "profiles\providers_config.json" if (Test-Path $providersCfg) { try { $rawProv = Get-Content $providersCfg -Raw -Encoding UTF8 $rawProv = $rawProv -replace '^\uFEFF', '' $provJson = $rawProv | ConvertFrom-Json if ($provJson.providers) { $provJson.providers = @($provJson.providers | Where-Object { $_.id -ne '9router' }) $qrProv = $provJson.providers | Where-Object { $_.id -eq 'quotarouter' } if (-not $qrProv) { $newProv = [PSCustomObject]@{ id = "quotarouter" name = "apicheap.store" baseUrl = $BaseUrl defaultModel = $Model supportedModels = @($Model) accounts = @( [PSCustomObject]@{ id = "1" name = "apicheap.store" apiKey = $ApiKey model = $Model } ) } $provList = [System.Collections.ArrayList]@($provJson.providers) $provList.Insert(0, $newProv) $provJson.providers = $provList } else { $qrProv.baseUrl = $BaseUrl $qrProv.defaultModel = $Model $qrProv.supportedModels = @($Model) if ($qrProv.accounts -and $qrProv.accounts.Count -gt 0) { $qrProv.accounts[0].apiKey = $ApiKey $qrProv.accounts[0].model = $Model } } $provJson.ANTHROPIC_MODEL = $Model $provJson.ANTHROPIC_SUBAGENT_MODEL = $SubagentModel $provJson.CLAUDE_CODE_SUBAGENT_MODEL = $SubagentModel Write-Utf8NoBom $providersCfg ($provJson | ConvertTo-Json -Depth 20) if ($isEn) { Write-Host " + Synced apicheap.store into Claude switch menu ($providersCfg)" -ForegroundColor Gray } else { Write-Host " + Da dong bo apicheap.store vao menu chuyen doi Claude ($providersCfg)" -ForegroundColor Gray } } } catch {} } # 5. Cap nhat cau hinh Codex (~/.codex/config.toml) Write-Host "" if ($isEn) { Write-Host "[3/4] Checking and configuring Codex CLI / Codex App..." -ForegroundColor Green } else { Write-Host "[3/4] Dang kiem tra va cau hinh Codex CLI / Codex App..." -ForegroundColor Green } $codexDir = Join-Path $env:USERPROFILE ".codex" $codexConfig = Join-Path $codexDir "config.toml" if (-not (Test-Path $codexDir)) { [System.IO.Directory]::CreateDirectory($codexDir) | Out-Null } $codexLines = @( "model = `"$Model`"", "model_provider = `"quotarouter`"", "", "[model_providers.quotarouter]", "name = `"apicheap.store`"", "base_url = `"$BaseUrl/v1`"", "env_key = `"OPENAI_API_KEY`"", "wire_api = `"responses`"", "http_headers = { Authorization = `"Bearer $ApiKey`" }", "", "[model_providers.9router]", "name = `"apicheap.store`"", "base_url = `"$BaseUrl/v1`"", "env_key = `"OPENAI_API_KEY`"", "wire_api = `"responses`"", "http_headers = { Authorization = `"Bearer $ApiKey`" }", "", "[agents.subagent]", "model = `"$SubagentModel`"" ) $codexBlock = $codexLines -join "`r`n" if (Test-Path $codexConfig) { $contentConfig = Read-Utf8Clean $codexConfig # 1. Update model if ($contentConfig -match "(?m)^model\s*=") { $contentConfig = $contentConfig -replace '(?m)^model\s*=\s*"[^"]*"', "model = `"$Model`"" } else { $contentConfig = "model = `"$Model`"`r`n" + $contentConfig } # 2. Update model_provider to quotarouter if ($contentConfig -match "(?m)^model_provider\s*=") { $contentConfig = $contentConfig -replace '(?m)^model_provider\s*=\s*"[^"]*"', 'model_provider = "quotarouter"' } else { $contentConfig = "model_provider = `"quotarouter`"`r`n" + $contentConfig } # 3. Handle model_providers.quotarouter & model_providers.9router $qrBlock = @( "[model_providers.quotarouter]", "name = `"apicheap.store`"", "base_url = `"$BaseUrl/v1`"", "env_key = `"OPENAI_API_KEY`"", "wire_api = `"responses`"", "http_headers = { Authorization = `"Bearer $ApiKey`" }" ) -join "`r`n" if ($contentConfig -match "\[model_providers\.quotarouter\]") { $contentConfig = $contentConfig -replace '(?s)\[model_providers\.quotarouter\][\s\S]*?(?=\r?\n\[|\Z)', $qrBlock } else { $contentConfig += "`r`n`r`n$qrBlock" } $r9Block = @( "[model_providers.9router]", "name = `"apicheap.store`"", "base_url = `"$BaseUrl/v1`"", "env_key = `"OPENAI_API_KEY`"", "wire_api = `"responses`"", "http_headers = { Authorization = `"Bearer $ApiKey`" }" ) -join "`r`n" if ($contentConfig -match "\[model_providers\.9router\]") { $contentConfig = $contentConfig -replace '(?s)\[model_providers\.9router\][\s\S]*?(?=\r?\n\[|\Z)', $r9Block } else { $contentConfig += "`r`n`r`n$r9Block" } Write-Utf8NoBom $codexConfig $contentConfig if ($isEn) { Write-Host " + Updated apicheap.store provider (Model: $Model) in $codexConfig" -ForegroundColor Gray } else { Write-Host " + Da cap nhat provider apicheap.store (Model: $Model) trong $codexConfig" -ForegroundColor Gray } } else { Write-Utf8NoBom $codexConfig $codexBlock if ($isEn) { Write-Host " + Created new config file $codexConfig" -ForegroundColor Gray } else { Write-Host " + Da tao moi tep cau hinh $codexConfig" -ForegroundColor Gray } } # Cap nhat auth.json cho Codex (BAT BUOC khong co BOM de Rust serde_json doc duoc) $codexAuth = Join-Path $codexDir "auth.json" $authObj = [ordered]@{ "auth_mode" = "apikey" "OPENAI_API_KEY" = $ApiKey "QUOTAROUTER_API_KEY" = $ApiKey } if (Test-Path $codexAuth) { try { $existingRaw = Read-Utf8Clean $codexAuth $existingAuth = $existingRaw | ConvertFrom-Json if ($existingAuth.tokens) { $authObj["tokens"] = $existingAuth.tokens } } catch {} } $authJsonText = $authObj | ConvertTo-Json -Depth 5 Write-Utf8NoBom $codexAuth $authJsonText if ($isEn) { Write-Host " + Updated apicheap.store API key into $codexAuth (clean UTF-8)" -ForegroundColor Gray } else { Write-Host " + Da cap nhat API key apicheap.store vao $codexAuth (chuan UTF-8)" -ForegroundColor Gray } # Kich hoat codex login --with-api-key truc tiep neu co binary codex $codexExe = $null if (Get-Command codex -ErrorAction SilentlyContinue) { $codexExe = "codex" } else { $foundBin = Get-ChildItem "$env:LOCALAPPDATA\OpenAI\Codex\bin\*\codex.exe" -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName if ($foundBin -and (Test-Path $foundBin)) { $codexExe = $foundBin } } if ($codexExe) { try { $ApiKey | & $codexExe login --with-api-key 2>&1 | Out-Null $loginStatus = & $codexExe login status 2>&1 if ($isEn) { Write-Host " + Codex CLI authentication confirmed: $loginStatus" -ForegroundColor Green } else { Write-Host " + Xac thuc thanh cong Codex CLI: $loginStatus" -ForegroundColor Green } } catch {} } # Dong bo cac phien cu trong state_5.sqlite neu co $codexSqlite = Join-Path $codexDir "state_5.sqlite" if (Test-Path $codexSqlite) { try { if (Get-Command node -ErrorAction SilentlyContinue) { $syncScript = @" const { DatabaseSync } = require('node:sqlite'); const fs = require('fs'); const path = require('path'); const home = process.env.USERPROFILE || process.env.HOME; try { const db = new DatabaseSync(path.join(home, '.codex', 'state_5.sqlite')); db.prepare("UPDATE threads SET model_provider = 'quotarouter' WHERE model_provider = '9router'").run(); db.prepare("UPDATE threads SET model = '$Model' WHERE model = 'combocodex'").run(); } catch (e) {} try { const jsonl = path.join(home, '.codex', 'session_index.jsonl'); if (fs.existsSync(jsonl)) { let c = fs.readFileSync(jsonl, 'utf8'); c = c.replace(/"9router"/g, '"quotarouter"').replace(/"combocodex"/g, '"$Model"'); fs.writeFileSync(jsonl, c, 'utf8'); } } catch (e) {} "@ $tempSync = Join-Path $env:TEMP "codex_sync_qr.js" Write-Utf8NoBom $tempSync $syncScript & node $tempSync 2>$null Remove-Item $tempSync -ErrorAction SilentlyContinue } } catch {} } # 6. Kiem tra ket noi truc tuyen toi QuotaRouter Write-Host "" if ($isEn) { Write-Host "[4/4] Checking live connection to $BaseUrl/v1/models..." -ForegroundColor Green } else { Write-Host "[4/4] Kiem tra ket noi truc tiep toi $BaseUrl/v1/models..." -ForegroundColor Green } try { $headers = @{ "Authorization" = "Bearer $ApiKey" "Accept" = "application/json" } $response = Invoke-RestMethod -Uri "$BaseUrl/v1/models" -Headers $headers -Method Get -TimeoutSec 10 $modelCount = 0 if ($response.data) { $modelCount = $response.data.Count } if (-not @($response.data | Where-Object { $_.id -eq $Model }).Count) { throw "Model / combo '$Model' khong co trong tai khoan hoac chua san sang." } if ($isEn) { Write-Host " [OK] Connection successful! Found $modelCount available models." -ForegroundColor Green } else { Write-Host " [OK] Ket noi thanh cong! Tim thay $modelCount model kha dung." -ForegroundColor Green } } catch { if ($isEn) { Write-Host " [ERROR] Setup stopped: $($_.Exception.Message)" -ForegroundColor Red } else { Write-Host " [LOI] Dung cau hinh: $($_.Exception.Message)" -ForegroundColor Red } exit 1 } # 7. Kiem tra trang thai cai dat cong cu tren may $hasClaude = $false if (Get-Command claude -ErrorAction SilentlyContinue) { $hasClaude = $true } elseif (Test-Path "$env:APPDATA\npm\claude.cmd") { $hasClaude = $true } $hasCodex = $false if (Get-Command codex -ErrorAction SilentlyContinue) { $hasCodex = $true } elseif (Test-Path "$env:LOCALAPPDATA\Programs\Codex") { $hasCodex = $true } elseif (Test-Path "$env:APPDATA\npm\codex.cmd") { $hasCodex = $true } Write-Host "" Write-Host "========================================================" -ForegroundColor Cyan if ($isEn) { Write-Host " CONFIGURATION COMPLETED! " -ForegroundColor Green } else { Write-Host " CAU HINH HOAN TAT THANH CONG! " -ForegroundColor Green } Write-Host "========================================================" -ForegroundColor Cyan Write-Host "" if ($isEn) { Write-Host "[-] TOOL STATUS ON YOUR MACHINE:" -ForegroundColor Cyan if ($hasClaude) { Write-Host " * Claude Code CLI : [INSTALLED] - Ready to use!" -ForegroundColor Green } else { Write-Host " * Claude Code CLI : [NOT INSTALLED] - Pre-configured!" -ForegroundColor Yellow Write-Host " (When needed, simply run: npm i -g @anthropic-ai/claude-code)" -ForegroundColor Gray } if ($hasCodex) { Write-Host " * OpenAI Codex : [INSTALLED] - Ready to use!" -ForegroundColor Green } else { Write-Host " * OpenAI Codex : [NOT INSTALLED] - Pre-configured!" -ForegroundColor Yellow Write-Host " (When needed, simply run: npm i -g @openai/codex or download Codex Desktop App)" -ForegroundColor Gray } Write-Host " * IDEs & Editors : [100% READY] (Cursor, Windsurf, Cline, Roo, Python SDK)" -ForegroundColor Green Write-Host " (All environment variables have been permanently set in system)" -ForegroundColor Gray Write-Host "" Write-Host "[-] HOW TO LAUNCH & USE:" -ForegroundColor Cyan if ($hasClaude) { Write-Host " 1. CLAUDE CODE CLI:" -ForegroundColor Yellow Write-Host " Open a new Terminal / CMD and run:" Write-Host " claude" -ForegroundColor White } if ($hasCodex) { Write-Host " 2. OPENAI CODEX (CLI or Desktop App):" -ForegroundColor Yellow Write-Host " If Codex App is open, please FULLY QUIT and RESTART to reload apicheap.store." -ForegroundColor Magenta Write-Host " Or in a new Terminal, run: codex" -ForegroundColor White } if (-not $hasClaude -and -not $hasCodex) { Write-Host " -> The system is fully pre-configured! You can:" -ForegroundColor Yellow Write-Host " 1. Use directly in Cursor / Windsurf / VS Code (Cline, Continue) immediately." -ForegroundColor White Write-Host " 2. Or install Claude Code: npm i -g @anthropic-ai/claude-code" -ForegroundColor White Write-Host " 3. Or install Codex CLI: npm i -g @openai/codex" -ForegroundColor White } Write-Host "" Write-Host "========================================================" -ForegroundColor Cyan Write-Host " HOW TO SWITCH MODEL / COMBO AT ANY TIME " -ForegroundColor Yellow Write-Host "========================================================" -ForegroundColor Cyan Write-Host "" Write-Host "A. SWITCH MODEL IN CLAUDE CODE CLI:" -ForegroundColor Cyan Write-Host " - Method 1: Specify directly at startup:" Write-Host " claude --model $Model" -ForegroundColor White Write-Host " - Method 2: Inside active Claude chat session, run:" Write-Host " /model" -ForegroundColor White Write-Host " - Method 3: Re-run this script to pick a new default model." Write-Host "" Write-Host "B. SWITCH MODEL IN OPENAI CODEX APP / CLI:" -ForegroundColor Cyan Write-Host " - Method 1 (Codex CLI): Add -m flag:" Write-Host " codex -m $Model" -ForegroundColor White Write-Host " - Method 2 (Codex Desktop App):" Write-Host " Select desired model in list or edit ~/.codex/config.toml" -ForegroundColor White Write-Host "" Write-Host "C. SWITCH MODEL IN CURSOR / WINDSURF:" -ForegroundColor Cyan Write-Host " - Go to Settings -> Models, change model name to your combo or model ID." -ForegroundColor Gray Write-Host "" } else { Write-Host "[-] TINH TRANG CONG CU TREN MAY CUA BAN:" -ForegroundColor Cyan if ($hasClaude) { Write-Host " * Claude Code CLI : [DA CAI DAT] - San sang su dung!" -ForegroundColor Green } else { Write-Host " * Claude Code CLI : [CHUA CAI DAT] - Da cau hinh san!" -ForegroundColor Yellow Write-Host " (Khi can, chi can go: npm i -g @anthropic-ai/claude-code la dung ngay)" -ForegroundColor Gray } if ($hasCodex) { Write-Host " * OpenAI Codex : [DA CAI DAT] - San sang su dung!" -ForegroundColor Green } else { Write-Host " * OpenAI Codex : [CHUA CAI DAT] - Da cau hinh san!" -ForegroundColor Yellow Write-Host " (Khi can, chi can go: npm i -g @openai/codex hoac tai Codex Desktop App)" -ForegroundColor Gray } Write-Host " * IDEs & Editors : [SAN SANG 100%] (Cursor, Windsurf, Cline, Roo, Python SDK)" -ForegroundColor Green Write-Host " (Tat ca Bien moi truong da duoc ghi vinh vien vao he thong)" -ForegroundColor Gray Write-Host "" Write-Host "[-] CACH KHOI DONG & SU DUNG:" -ForegroundColor Cyan if ($hasClaude) { Write-Host " 1. CLAUDE CODE CLI:" -ForegroundColor Yellow Write-Host " Mo Terminal / CMD moi va go:" Write-Host " claude" -ForegroundColor White } if ($hasCodex) { Write-Host " 2. OPENAI CODEX (CLI hoac Desktop App):" -ForegroundColor Yellow Write-Host " Neu dang mo Codex App, vui long TAT HOAN TOAN va MO LAI de nhan apicheap.store." -ForegroundColor Magenta Write-Host " Hoac tren Terminal moi, go: codex" -ForegroundColor White } if (-not $hasClaude -and -not $hasCodex) { Write-Host " -> He thong da cau hinh san toan bo! Ban co the:" -ForegroundColor Yellow Write-Host " 1. Dung truc tiep tren Cursor / Windsurf / VS Code (Cline, Continue) ngay lap tuc." -ForegroundColor White Write-Host " 2. Hoac cai Claude Code: npm i -g @anthropic-ai/claude-code" -ForegroundColor White Write-Host " 3. Hoac cai Codex CLI: npm i -g @openai/codex" -ForegroundColor White } Write-Host "" Write-Host "========================================================" -ForegroundColor Cyan Write-Host " HUONG DAN DOI MODEL / COMBO BAT KY LUC NAO " -ForegroundColor Yellow Write-Host "========================================================" -ForegroundColor Cyan Write-Host "" Write-Host "A. DOI MODEL TRONG CLAUDE CODE CLI:" -ForegroundColor Cyan Write-Host " - Cach 1: Chi dinh truc tiep khi chay:" Write-Host " claude --model $Model" -ForegroundColor White Write-Host " - Cach 2: Trong phien chat Claude dang mo, go lenh:" Write-Host " /model" -ForegroundColor White Write-Host " - Cach 3: Chay lai script nay de chon lai model mac dinh." Write-Host "" Write-Host "B. DOI MODEL TRONG OPENAI CODEX APP / CLI:" -ForegroundColor Cyan Write-Host " - Cach 1 (Codex CLI): Them co -m khi chay:" Write-Host " codex -m $Model" -ForegroundColor White Write-Host " - Cach 2 (Codex Desktop App):" Write-Host " Chon model mong muon trong danh sach hoac sua ~/.codex/config.toml" -ForegroundColor White Write-Host "" Write-Host "C. DOI MODEL TRONG CURSOR / WINDSURF:" -ForegroundColor Cyan Write-Host " - Vao Settings -> Models, doi ten model thanh combo hoac model le." -ForegroundColor Gray Write-Host "" }