mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
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:
@@ -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
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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 ""
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user