mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 10:15:40 +00:00
fix(windows): use environment variables instead of settings files
Windows Claude CLI doesn't support --settings flag or settings.json files.
It uses environment variables instead (ANTHROPIC_AUTH_TOKEN, ANTHROPIC_BASE_URL, etc.)
Changes:
- ccs.ps1: Completely rewritten to set environment variables per profile
- Supports both env var objects (Windows) and file paths (Unix cross-compat)
- Sets env vars before executing claude, restores after
- Shows helpful error if user tries to use file paths on Windows
- install.ps1: Updated to create env var-based config
- config.json now contains env var objects, not file paths
- GLM profile: Full env var config with API key placeholder
- Sonnet/default profiles: Empty {} = use Claude subscription
- README.md: Updated Windows configuration section
- Documents env var approach clearly
- Shows correct Windows config format
- Explains difference from Unix approach
Example Windows config:
{
"profiles": {
"glm": {
"ANTHROPIC_AUTH_TOKEN": "your_key",
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic"
},
"son": {}
}
}
Fixes: Windows users can now switch profiles with env vars instead of files
This commit is contained in:
1 parent
2b03406f00
commit
999f598735
3 files changed
+108
-62
No files matched your search
@@ -206,7 +206,9 @@ The installer auto-creates config and profile templates during installation:
|
||||
**macOS / Linux**: `~/.ccs/config.json`
|
||||
**Windows**: `%USERPROFILE%\.ccs\config.json`
|
||||
|
||||
If you need to customize:
|
||||
### macOS / Linux Configuration
|
||||
|
||||
Uses settings file paths:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -218,33 +220,43 @@ If you need to customize:
|
||||
}
|
||||
```
|
||||
|
||||
**Note**: Config uses Unix-style paths (`~/`) for cross-platform compatibility. Windows version automatically converts paths.
|
||||
|
||||
Each profile points to a Claude settings JSON file. Create settings files per [Claude CLI docs](https://docs.claude.com/en/docs/claude-code/installation).
|
||||
|
||||
### GLM Profile Configuration
|
||||
### Windows Configuration
|
||||
|
||||
The installer automatically configures GLM profiles with enhanced environment variables:
|
||||
**Important**: Windows Claude CLI uses **environment variables** instead of settings files.
|
||||
|
||||
Config format:
|
||||
|
||||
```json
|
||||
{
|
||||
"env": {
|
||||
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
|
||||
"ANTHROPIC_AUTH_TOKEN": "YOUR_GLM_API_KEY_HERE",
|
||||
"ANTHROPIC_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.6"
|
||||
"profiles": {
|
||||
"glm": {
|
||||
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
|
||||
"ANTHROPIC_AUTH_TOKEN": "your_glm_api_key",
|
||||
"ANTHROPIC_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.6",
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.6"
|
||||
},
|
||||
"son": {},
|
||||
"default": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Environment Variables**:
|
||||
- `ANTHROPIC_DEFAULT_OPUS_MODEL`: Default model for Opus-class requests
|
||||
- `ANTHROPIC_DEFAULT_SONNET_MODEL`: Default model for Sonnet-class requests
|
||||
- `ANTHROPIC_DEFAULT_HAIKU_MODEL`: Default model for Haiku-class requests
|
||||
**Profile types**:
|
||||
- **With env vars** (GLM): Sets environment variables for API providers
|
||||
- **Empty object** `{}` (Claude): Uses Claude subscription (no API key needed)
|
||||
- **Empty object** `{}` (default): Uses current environment variables
|
||||
|
||||
These variables ensure GLM is used as the default provider when switching profiles.
|
||||
**Environment Variables**:
|
||||
- `ANTHROPIC_BASE_URL`: API endpoint URL
|
||||
- `ANTHROPIC_AUTH_TOKEN`: Your API key
|
||||
- `ANTHROPIC_MODEL`: Default model
|
||||
- `ANTHROPIC_DEFAULT_OPUS_MODEL`: Model for Opus-class requests
|
||||
- `ANTHROPIC_DEFAULT_SONNET_MODEL`: Model for Sonnet-class requests
|
||||
- `ANTHROPIC_DEFAULT_HAIKU_MODEL`: Model for Haiku-class requests
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# CCS - Claude Code Switch (Windows PowerShell)
|
||||
# Cross-platform Claude CLI profile switcher
|
||||
# Cross-platform Claude CLI profile switcher using environment variables
|
||||
# https://github.com/kaitranntt/ccs
|
||||
|
||||
param(
|
||||
@@ -50,10 +50,10 @@ if (-not $Config.profiles) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Get settings path for profile
|
||||
$SettingsPath = $Config.profiles.$Profile
|
||||
# Get profile config
|
||||
$ProfileConfig = $Config.profiles.$Profile
|
||||
|
||||
if (-not $SettingsPath) {
|
||||
if (-not $ProfileConfig) {
|
||||
Write-Host "Error: Profile '$Profile' not found in $ConfigFile" -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Available profiles:"
|
||||
@@ -63,31 +63,64 @@ if (-not $SettingsPath) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Path expansion and normalization
|
||||
# 1. Handle Unix-style tilde expansion (~/path -> %USERPROFILE%\path)
|
||||
if ($SettingsPath -match '^~[/\\]') {
|
||||
$SettingsPath = $SettingsPath -replace '^~', $env:USERPROFILE
|
||||
}
|
||||
# Profile config can be either a string (settings file path) or object (env vars)
|
||||
# For backward compatibility with Unix, support both formats
|
||||
|
||||
# 2. Expand Windows environment variables (%USERPROFILE%, etc.)
|
||||
$SettingsPath = [System.Environment]::ExpandEnvironmentVariables($SettingsPath)
|
||||
|
||||
# 3. Convert forward slashes to backslashes (Unix path compatibility)
|
||||
$SettingsPath = $SettingsPath -replace '/', '\'
|
||||
|
||||
# Validate settings file exists
|
||||
if (-not (Test-Path $SettingsPath)) {
|
||||
Write-Host "Error: Settings file not found: $SettingsPath" -ForegroundColor Red
|
||||
if ($ProfileConfig -is [string]) {
|
||||
# Legacy format: path to settings file (for cross-platform configs)
|
||||
# This won't work on Windows Claude CLI, show helpful error
|
||||
Write-Host "Error: Windows Claude CLI doesn't support settings files." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Create the settings file or update the path in $ConfigFile"
|
||||
Write-Host "Windows uses environment variables instead."
|
||||
Write-Host "Update your profile in $ConfigFile to use this format:"
|
||||
Write-Host ""
|
||||
Write-Host ' "' + $Profile + '": {'
|
||||
Write-Host ' "ANTHROPIC_AUTH_TOKEN": "your_api_key",'
|
||||
Write-Host ' "ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",'
|
||||
Write-Host ' "ANTHROPIC_MODEL": "glm-4.6"'
|
||||
Write-Host ' }'
|
||||
Write-Host ""
|
||||
Write-Host "Or leave empty {} for Claude subscription (no API key needed)."
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Execute claude with settings
|
||||
# Pass arguments directly to Claude CLI with proper splatting
|
||||
if ($RemainingArgs) {
|
||||
& claude --settings $SettingsPath @RemainingArgs
|
||||
} else {
|
||||
& claude --settings $SettingsPath
|
||||
# Apply environment variables from profile
|
||||
# Save original values to restore after command execution
|
||||
$OriginalEnvVars = @{}
|
||||
|
||||
if ($ProfileConfig.PSObject.Properties.Count -gt 0) {
|
||||
foreach ($Property in $ProfileConfig.PSObject.Properties) {
|
||||
$VarName = $Property.Name
|
||||
$VarValue = $Property.Value
|
||||
|
||||
# Save original value
|
||||
$OriginalEnvVars[$VarName] = [System.Environment]::GetEnvironmentVariable($VarName, 'Process')
|
||||
|
||||
# Set new value for this process
|
||||
[System.Environment]::SetEnvironmentVariable($VarName, $VarValue, 'Process')
|
||||
}
|
||||
}
|
||||
exit $LASTEXITCODE
|
||||
|
||||
# Execute claude with environment variables set
|
||||
try {
|
||||
if ($RemainingArgs) {
|
||||
& claude @RemainingArgs
|
||||
} else {
|
||||
& claude
|
||||
}
|
||||
$ExitCode = $LASTEXITCODE
|
||||
} finally {
|
||||
# Restore original environment variables
|
||||
foreach ($VarName in $OriginalEnvVars.Keys) {
|
||||
$OriginalValue = $OriginalEnvVars[$VarName]
|
||||
if ($null -eq $OriginalValue) {
|
||||
# Variable didn't exist before, remove it
|
||||
[System.Environment]::SetEnvironmentVariable($VarName, $null, 'Process')
|
||||
} else {
|
||||
# Restore original value
|
||||
[System.Environment]::SetEnvironmentVariable($VarName, $OriginalValue, 'Process')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit $ExitCode
|
||||
+20
-19
@@ -186,8 +186,6 @@ Write-Host ""
|
||||
# Profile Setup
|
||||
|
||||
$CurrentProvider = Detect-CurrentProvider
|
||||
$GlmSettings = "$CcsDir\glm.settings.json"
|
||||
$SonnetSettings = "$CcsDir\sonnet.settings.json"
|
||||
|
||||
$ProviderLabel = switch ($CurrentProvider) {
|
||||
"glm" { " (detected: GLM)" }
|
||||
@@ -200,30 +198,33 @@ Write-Host "┌─ Configuring Profiles$ProviderLabel"
|
||||
|
||||
$NeedsGlmKey = $false
|
||||
|
||||
if (-not (Test-Path $GlmSettings)) {
|
||||
New-GlmProfile -Provider $CurrentProvider | Out-Null
|
||||
Write-Host "| [OK] GLM profile -> $env:USERPROFILE\.ccs\glm.settings.json"
|
||||
if ($CurrentProvider -ne "glm") { $NeedsGlmKey = $true }
|
||||
}
|
||||
|
||||
if (-not (Test-Path $SonnetSettings)) {
|
||||
New-SonnetProfile -Provider $CurrentProvider | Out-Null
|
||||
Write-Host "| [OK] Sonnet profile -> $env:USERPROFILE\.ccs\sonnet.settings.json"
|
||||
}
|
||||
|
||||
# Create ccs config (using Unix-style paths for cross-platform compatibility)
|
||||
# Create ccs config (Windows uses environment variables, not settings files)
|
||||
$ConfigFile = "$CcsDir\config.json"
|
||||
if (-not (Test-Path $ConfigFile)) {
|
||||
# Detect if user has GLM API key set in environment
|
||||
$HasGlmKey = $env:ANTHROPIC_AUTH_TOKEN -and $env:ANTHROPIC_BASE_URL -match "z\.ai"
|
||||
|
||||
$ConfigContent = @{
|
||||
profiles = @{
|
||||
glm = "~/.ccs/glm.settings.json"
|
||||
son = "~/.ccs/sonnet.settings.json"
|
||||
default = "~/.claude/settings.json"
|
||||
glm = @{
|
||||
ANTHROPIC_BASE_URL = "https://api.z.ai/api/anthropic"
|
||||
ANTHROPIC_AUTH_TOKEN = if ($HasGlmKey) { $env:ANTHROPIC_AUTH_TOKEN } else { "YOUR_GLM_API_KEY_HERE" }
|
||||
ANTHROPIC_MODEL = $GlmModel
|
||||
ANTHROPIC_DEFAULT_OPUS_MODEL = $GlmModel
|
||||
ANTHROPIC_DEFAULT_SONNET_MODEL = $GlmModel
|
||||
ANTHROPIC_DEFAULT_HAIKU_MODEL = $GlmModel
|
||||
}
|
||||
son = @{} # Empty = use Claude subscription (no env vars needed)
|
||||
default = @{} # Empty = use current environment settings
|
||||
}
|
||||
}
|
||||
|
||||
$ConfigContent | ConvertTo-Json -Depth 10 | Set-Content $ConfigFile
|
||||
Write-Host "| [OK] Config -> $env:USERPROFILE\.ccs\config.json"
|
||||
|
||||
if (-not $HasGlmKey) {
|
||||
$NeedsGlmKey = $true
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "└─"
|
||||
@@ -253,8 +254,8 @@ if ($UserPath -notlike "*$CcsDir*") {
|
||||
if ($NeedsGlmKey) {
|
||||
Write-Host "[!] ACTION REQUIRED"
|
||||
Write-Host ""
|
||||
Write-Host " Edit $env:USERPROFILE\.ccs\glm.settings.json and add your GLM API key"
|
||||
Write-Host " Replace: YOUR_GLM_API_KEY_HERE"
|
||||
Write-Host " Edit $env:USERPROFILE\.ccs\config.json and add your GLM API key"
|
||||
Write-Host " Replace YOUR_GLM_API_KEY_HERE in the 'glm' profile with your actual API key"
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user