refactor(windows): revert to Linux file structure with settings files

Changes:
- ccs.ps1: Read settings files and apply env vars (supports both direct and {"env": {...}} formats)
- install.ps1: Create separate settings files (glm.settings.json, sonnet.settings.json) instead of embedding in config.json
- README.md: Document Linux-style file structure for Windows
- README.vi.md: Add Vietnamese documentation for Windows configuration

Windows now uses same file structure as Linux:
- config.json contains file paths
- Settings files contain environment variables
- Maintains cross-platform consistency
This commit is contained in:
kaitranntt
2025-11-02 02:53:22 -05:00
parent 999f598735
commit ff357f188f
4 changed files with 147 additions and 83 deletions
+31 -23
View File
@@ -224,39 +224,47 @@ Each profile points to a Claude settings JSON file. Create settings files per [C
### Windows Configuration
**Important**: Windows Claude CLI uses **environment variables** instead of settings files.
**Important**: Windows Claude CLI uses **environment variables** instead of --settings flag.
Config format:
Windows uses the same file structure as Linux, but settings files contain environment variables:
**Config format** (`~/.ccs/config.json`):
```json
{
"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": {}
"glm": "~/.ccs/glm.settings.json",
"son": "~/.ccs/sonnet.settings.json",
"default": "~/.claude/settings.json"
}
}
```
**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
**GLM profile** (`~/.ccs/glm.settings.json`):
```json
{
"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"
}
```
**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
**Claude profile** (`~/.ccs/sonnet.settings.json`):
```json
{
"env": {}
}
```
**How it works**:
- CCS reads the settings file for the selected profile
- Temporarily sets environment variables from the settings file
- Executes Claude CLI with those variables
- Restores original environment variables after execution
**Compatibility**: Settings files support both direct format (Windows) and `{"env": {...}}` wrapper (Linux compatibility).
## Usage
+50 -18
View File
@@ -209,33 +209,65 @@ Nếu cần tùy chỉnh:
}
```
**Lưu ý**: Config dùng Unix-style paths (`~/`) để tương thích đa nền tảng. Phiên bản Windows tự động chuyển đổi paths.
### Cấu Hình macOS / Linux
Mỗi profile trỏ đến một file settings JSON của Claude. Tạo file settings theo [tài liệu Claude CLI](https://docs.claude.com/en/docs/claude-code/installation).
### Cấu Hình GLM Profile
Installer tự động cấu hình GLM profiles với các biến môi trường nâng cao:
Dùng file paths trỏ đến settings files:
```json
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
"ANTHROPIC_AUTH_TOKEN": "GLM_API_KEY_CUA_BAN",
"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": "~/.ccs/glm.settings.json",
"sonnet": "~/.ccs/sonnet.settings.json",
"default": "~/.claude/settings.json"
}
}
```
**Các biến môi trường**:
- `ANTHROPIC_DEFAULT_OPUS_MODEL`: Model mặc định cho requests Opus-class
- `ANTHROPIC_DEFAULT_SONNET_MODEL`: Model mặc định cho requests Sonnet-class
- `ANTHROPIC_DEFAULT_HAIKU_MODEL`: Model mặc định cho requests Haiku-class
Mỗi profile trỏ đến một file settings JSON của Claude. Tạo file settings theo [tài liệu Claude CLI](https://docs.claude.com/en/docs/claude-code/installation).
Các biến này đảm bảo GLM được dùng làm provider mặc định khi chuyển profiles.
### Cấu Hình Windows
**Quan trọng**: Claude CLI trên Windows dùng **biến môi trường** thay vì --settings flag.
Windows dùng cùng cấu trúc file như Linux, nhưng settings files chứa environment variables:
**Config format** (`~/.ccs/config.json`):
```json
{
"profiles": {
"glm": "~/.ccs/glm.settings.json",
"son": "~/.ccs/sonnet.settings.json",
"default": "~/.claude/settings.json"
}
}
```
**GLM profile** (`~/.ccs/glm.settings.json`):
```json
{
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
"ANTHROPIC_AUTH_TOKEN": "GLM_API_KEY_CUA_BAN",
"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"
}
```
**Claude profile** (`~/.ccs/sonnet.settings.json`):
```json
{
"env": {}
}
```
**Cách hoạt động**:
- CCS đọc settings file của profile được chọn
- Tạm thời set biến môi trường từ settings file
- Chạy Claude CLI với các biến đó
- Khôi phục biến môi trường gốc sau khi thực thi
**Tương thích**: Settings files hỗ trợ cả format trực tiếp (Windows) và wrapper `{"env": {...}}` (tương thích Linux).
## Sử Dụng
+44 -25
View File
@@ -1,5 +1,5 @@
# CCS - Claude Code Switch (Windows PowerShell)
# Cross-platform Claude CLI profile switcher using environment variables
# Cross-platform Claude CLI profile switcher
# https://github.com/kaitranntt/ccs
param(
@@ -50,10 +50,10 @@ if (-not $Config.profiles) {
exit 1
}
# Get profile config
$ProfileConfig = $Config.profiles.$Profile
# Get settings path for profile
$SettingsPath = $Config.profiles.$Profile
if (-not $ProfileConfig) {
if (-not $SettingsPath) {
Write-Host "Error: Profile '$Profile' not found in $ConfigFile" -ForegroundColor Red
Write-Host ""
Write-Host "Available profiles:"
@@ -63,40 +63,59 @@ if (-not $ProfileConfig) {
exit 1
}
# Profile config can be either a string (settings file path) or object (env vars)
# For backward compatibility with Unix, support both formats
# Path expansion and normalization
# 1. Handle Unix-style tilde expansion (~/path -> %USERPROFILE%\path)
if ($SettingsPath -match '^~[/\\]') {
$SettingsPath = $SettingsPath -replace '^~', $env:USERPROFILE
}
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
# 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
Write-Host ""
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)."
Write-Host "Create the settings file or update the path in $ConfigFile"
exit 1
}
# Apply environment variables from profile
# Save original values to restore after command execution
# Read settings file (contains environment variables for Windows)
try {
$SettingsContent = Get-Content $SettingsPath -Raw -ErrorAction Stop
$Settings = $SettingsContent | ConvertFrom-Json -ErrorAction Stop
} catch {
Write-Host "Error: Invalid JSON in $SettingsPath" -ForegroundColor Red
exit 1
}
# Windows Claude CLI uses environment variables instead of --settings flag
# Settings file contains env vars directly or nested in "env" object (Linux compat)
# Check if settings contain "env" wrapper (Linux format) or direct env vars (Windows format)
$EnvVars = if ($Settings.env) {
# Linux format: { "env": { "ANTHROPIC_AUTH_TOKEN": "..." } }
$Settings.env
} else {
# Windows format: { "ANTHROPIC_AUTH_TOKEN": "..." }
$Settings
}
# Save original environment variables to restore after execution
$OriginalEnvVars = @{}
if ($ProfileConfig.PSObject.Properties.Count -gt 0) {
foreach ($Property in $ProfileConfig.PSObject.Properties) {
if ($EnvVars.PSObject.Properties.Count -gt 0) {
foreach ($Property in $EnvVars.PSObject.Properties) {
$VarName = $Property.Name
$VarValue = $Property.Value
# Save original value
$OriginalEnvVars[$VarName] = [System.Environment]::GetEnvironmentVariable($VarName, 'Process')
# Set new value for this process
# Set new value for this process only
[System.Environment]::SetEnvironmentVariable($VarName, $VarValue, 'Process')
}
}
+22 -17
View File
@@ -198,33 +198,38 @@ Write-Host "┌─ Configuring Profiles$ProviderLabel"
$NeedsGlmKey = $false
# Create ccs config (Windows uses environment variables, not settings files)
# Create ccs config with file paths (same structure as Linux)
$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 = @{
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
glm = "~/.ccs/glm.settings.json"
son = "~/.ccs/sonnet.settings.json"
default = "~/.claude/settings.json"
}
}
$ConfigContent | ConvertTo-Json -Depth 10 | Set-Content $ConfigFile
Write-Host "| [OK] Config -> $env:USERPROFILE\.ccs\config.json"
}
if (-not $HasGlmKey) {
# Create profile settings files
$GlmSettings = "$CcsDir\glm.settings.json"
$SonnetSettings = "$CcsDir\sonnet.settings.json"
if (-not (Test-Path $GlmSettings)) {
New-GlmProfile -Provider $CurrentProvider
if ($CurrentProvider -ne "glm") {
$NeedsGlmKey = $true
}
} else {
Write-Host "| [OK] GLM profile exists: $GlmSettings"
}
if (-not (Test-Path $SonnetSettings)) {
New-SonnetProfile -Provider $CurrentProvider
} else {
Write-Host "| [OK] Sonnet profile exists: $SonnetSettings"
}
Write-Host "└─"
@@ -254,8 +259,8 @@ if ($UserPath -notlike "*$CcsDir*") {
if ($NeedsGlmKey) {
Write-Host "[!] ACTION REQUIRED"
Write-Host ""
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 " Edit $env:USERPROFILE\.ccs\glm.settings.json and add your GLM API key"
Write-Host " Replace YOUR_GLM_API_KEY_HERE with your actual API key"
Write-Host ""
}