@kaitranntt/ccs 2.4.3 → 2.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -15
- package/README.vi.md +50 -7
- package/VERSION +1 -1
- package/bin/ccs.js +16 -109
- package/bin/claude-detector.js +5 -34
- package/bin/config-manager.js +8 -63
- package/bin/helpers.js +7 -23
- package/lib/ccs +107 -71
- package/lib/ccs.ps1 +210 -364
- package/package.json +13 -3
- package/scripts/bump-version.sh +136 -0
- package/scripts/check-executables.js +18 -0
- package/scripts/get-version.sh +16 -0
- package/scripts/postinstall.js +99 -0
- package/scripts/sync-version.js +15 -0
- package/scripts/worker.js +46 -0
- package/scripts/wrangler.toml +15 -0
package/lib/ccs.ps1
CHANGED
|
@@ -3,9 +3,8 @@
|
|
|
3
3
|
# https://github.com/kaitranntt/ccs
|
|
4
4
|
|
|
5
5
|
param(
|
|
6
|
-
[
|
|
7
|
-
[
|
|
8
|
-
|
|
6
|
+
[switch]$Help,
|
|
7
|
+
[switch]$Version,
|
|
9
8
|
[Parameter(ValueFromRemainingArguments=$true)]
|
|
10
9
|
[string[]]$RemainingArgs
|
|
11
10
|
)
|
|
@@ -16,419 +15,286 @@ $ErrorActionPreference = "Stop"
|
|
|
16
15
|
function Write-ErrorMsg {
|
|
17
16
|
param([string]$Message)
|
|
18
17
|
Write-Host ""
|
|
19
|
-
Write-Host "
|
|
20
|
-
Write-Host "
|
|
21
|
-
Write-Host "
|
|
18
|
+
Write-Host "=============================================" -ForegroundColor Red
|
|
19
|
+
Write-Host " ERROR" -ForegroundColor Red
|
|
20
|
+
Write-Host "=============================================" -ForegroundColor Red
|
|
22
21
|
Write-Host ""
|
|
23
22
|
Write-Host $Message -ForegroundColor Red
|
|
24
23
|
Write-Host ""
|
|
25
24
|
}
|
|
26
25
|
|
|
27
|
-
|
|
26
|
+
function Write-ColoredText {
|
|
27
|
+
param(
|
|
28
|
+
[string]$Text,
|
|
29
|
+
[string]$Color = "White",
|
|
30
|
+
[switch]$NoNewline
|
|
31
|
+
)
|
|
28
32
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
$UseColors = $env:FORCE_COLOR -or ([Console]::IsOutputRedirected -eq $false -and -not $env:NO_COLOR)
|
|
34
|
+
|
|
35
|
+
if ($UseColors -and $Color) {
|
|
36
|
+
if ($NoNewline) {
|
|
37
|
+
Write-Host $Text -ForegroundColor $Color -NoNewline
|
|
38
|
+
} else {
|
|
39
|
+
Write-Host $Text -ForegroundColor $Color
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
if ($NoNewline) {
|
|
43
|
+
Write-Host $Text -NoNewline
|
|
44
|
+
} else {
|
|
45
|
+
Write-Host $Text
|
|
39
46
|
}
|
|
40
|
-
# Invalid CCS_CLAUDE_PATH - show warning and fall back to PATH
|
|
41
|
-
Write-Host "[!] Warning: CCS_CLAUDE_PATH is set but file not found: $CcsClaudePath" -ForegroundColor Yellow
|
|
42
|
-
Write-Host " Falling back to system PATH lookup..." -ForegroundColor Yellow
|
|
43
47
|
}
|
|
44
|
-
|
|
45
|
-
# Priority 2: Use 'claude' from PATH (trust the system)
|
|
46
|
-
# This is the standard case - if user installed Claude CLI, it's in their PATH
|
|
47
|
-
return "claude"
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
Write-ErrorMsg @"
|
|
52
|
-
Claude CLI not found in PATH
|
|
53
|
-
|
|
54
|
-
CCS requires Claude CLI to be installed and available in your PATH.
|
|
50
|
+
# --- Claude CLI Detection Logic ---
|
|
55
51
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
52
|
+
function Find-ClaudeCli {
|
|
53
|
+
if ($env:CCS_CLAUDE_PATH) {
|
|
54
|
+
return $env:CCS_CLAUDE_PATH
|
|
55
|
+
} else {
|
|
56
|
+
return "claude"
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
function Show-ClaudeNotFoundError {
|
|
61
|
+
$Message = "Claude CLI not found in PATH" + "`n`n" +
|
|
62
|
+
"CCS requires Claude CLI to be installed and available in your PATH." + "`n`n" +
|
|
63
|
+
"Solutions:" + "`n" +
|
|
64
|
+
" 1. Install Claude CLI:" + "`n" +
|
|
65
|
+
" https://docs.claude.com/en/docs/claude-code/installation" + "`n`n" +
|
|
66
|
+
" 2. Verify installation:" + "`n" +
|
|
67
|
+
" Get-Command claude" + "`n`n" +
|
|
68
|
+
" 3. If installed but not in PATH, add it:" + "`n" +
|
|
69
|
+
" # Find Claude installation" + "`n" +
|
|
70
|
+
" where.exe claude" + "`n`n" +
|
|
71
|
+
" # Or set custom path" + "`n" +
|
|
72
|
+
" `$env:CCS_CLAUDE_PATH = 'C:\path\to\claude.exe'" + "`n`n" +
|
|
73
|
+
"Restart your terminal after installation."
|
|
74
|
+
|
|
75
|
+
Write-ErrorMsg $Message
|
|
76
|
+
}
|
|
62
77
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
where.exe claude
|
|
78
|
+
function Show-Help {
|
|
79
|
+
$UseColors = $env:FORCE_COLOR -or ([Console]::IsOutputRedirected -eq $false -and -not $env:NO_COLOR)
|
|
66
80
|
|
|
67
|
-
|
|
68
|
-
|
|
81
|
+
# Helper for colored output
|
|
82
|
+
function Write-ColorLine {
|
|
83
|
+
param([string]$Text, [string]$Color = "White")
|
|
84
|
+
if ($UseColors) { Write-Host $Text -ForegroundColor $Color }
|
|
85
|
+
else { Write-Host $Text }
|
|
86
|
+
}
|
|
69
87
|
|
|
70
|
-
|
|
71
|
-
"
|
|
88
|
+
Write-ColorLine "CCS (Claude Code Switch) - Instant profile switching for Claude CLI" "White"
|
|
89
|
+
Write-Host ""
|
|
90
|
+
Write-ColorLine "Usage:" "Cyan"
|
|
91
|
+
Write-ColorLine " ccs [profile] [claude-args...]" "Yellow"
|
|
92
|
+
Write-ColorLine " ccs [flags]" "Yellow"
|
|
93
|
+
Write-Host ""
|
|
94
|
+
Write-ColorLine "Description:" "Cyan"
|
|
95
|
+
Write-Host " Switch between Claude models instantly. Stop hitting rate limits."
|
|
96
|
+
Write-Host " Maps profile names to Claude settings files via ~/.ccs/config.json"
|
|
97
|
+
Write-Host ""
|
|
98
|
+
Write-ColorLine "Profile Switching:" "Cyan"
|
|
99
|
+
Write-ColorLine " ccs Use default profile" "Yellow"
|
|
100
|
+
Write-ColorLine " ccs glm Switch to GLM profile" "Yellow"
|
|
101
|
+
Write-ColorLine " ccs glm 'debug this code' Switch to GLM and run command" "Yellow"
|
|
102
|
+
Write-ColorLine " ccs glm --verbose Switch to GLM with Claude flags" "Yellow"
|
|
103
|
+
Write-Host ""
|
|
104
|
+
Write-ColorLine "Flags:" "Cyan"
|
|
105
|
+
Write-ColorLine " -h, --help Show this help message" "Yellow"
|
|
106
|
+
Write-ColorLine " -v, --version Show version and installation info" "Yellow"
|
|
107
|
+
Write-ColorLine " --install Install CCS commands to Claude CLI" "Yellow"
|
|
108
|
+
Write-ColorLine " --uninstall Remove CCS commands from Claude CLI" "Yellow"
|
|
109
|
+
Write-Host ""
|
|
110
|
+
Write-ColorLine "Configuration:" "Cyan"
|
|
111
|
+
Write-Host " Config File: ~/.ccs/config.json"
|
|
112
|
+
Write-Host " Settings: ~/.ccs/*.settings.json"
|
|
113
|
+
Write-Host " Environment: CCS_CONFIG (override config path)"
|
|
114
|
+
Write-Host ""
|
|
115
|
+
Write-ColorLine "Examples:" "Cyan"
|
|
116
|
+
Write-Host " # Use default Claude subscription"
|
|
117
|
+
Write-ColorLine " ccs 'Review this architecture'" "Yellow"
|
|
118
|
+
Write-Host ""
|
|
119
|
+
Write-Host " # Switch to GLM for cost-effective tasks"
|
|
120
|
+
Write-ColorLine " ccs glm 'Write unit tests'" "Yellow"
|
|
121
|
+
Write-Host ""
|
|
122
|
+
Write-Host " # Use GLM with verbose output"
|
|
123
|
+
Write-ColorLine " ccs glm --verbose 'Debug error'" "Yellow"
|
|
124
|
+
Write-Host ""
|
|
125
|
+
Write-Host " # Install CCS task delegation"
|
|
126
|
+
Write-ColorLine " ccs --install" "Yellow"
|
|
127
|
+
Write-Host ""
|
|
128
|
+
Write-ColorLine "Uninstall:" "Cyan"
|
|
129
|
+
Write-Host " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
|
|
130
|
+
Write-Host " Windows: irm ccs.kaitran.ca/uninstall | iex"
|
|
131
|
+
Write-Host " npm: npm uninstall -g @kaitranntt/ccs"
|
|
132
|
+
Write-Host ""
|
|
133
|
+
Write-ColorLine "Documentation:" "Cyan"
|
|
134
|
+
Write-Host " GitHub: https://github.com/kaitranntt/ccs"
|
|
135
|
+
Write-Host " Docs: https://github.com/kaitranntt/ccs/blob/main/README.md"
|
|
136
|
+
Write-Host " Issues: https://github.com/kaitranntt/ccs/issues"
|
|
137
|
+
Write-Host ""
|
|
138
|
+
Write-ColorLine "License: MIT" "Cyan"
|
|
72
139
|
}
|
|
73
140
|
|
|
74
141
|
# Version (updated by scripts/bump-version.sh)
|
|
75
|
-
$CcsVersion = "2.4.
|
|
142
|
+
$CcsVersion = "2.4.5"
|
|
76
143
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
|
144
|
+
$ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" }
|
|
77
145
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Try both possible locations for .claude directory
|
|
81
|
-
$SourceDir = $null
|
|
82
|
-
$PossibleDirs = @(
|
|
83
|
-
(Join-Path $ScriptDir ".claude"), # Development: tools/ccs/.claude
|
|
84
|
-
(Join-Path $env:USERPROFILE ".ccs\.claude") # Installed: ~/.ccs/.claude
|
|
85
|
-
)
|
|
146
|
+
function Show-Version {
|
|
147
|
+
$UseColors = $env:FORCE_COLOR -or ([Console]::IsOutputRedirected -eq $false -and -not $env:NO_COLOR)
|
|
86
148
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
$HomeDir = if ($env:HOME) { $env:HOME } else { $env:USERPROFILE }
|
|
95
|
-
$TargetDir = Join-Path $HomeDir ".claude"
|
|
96
|
-
|
|
97
|
-
Write-Host "[Installing CCS Commands and Skills]" -ForegroundColor Cyan
|
|
98
|
-
Write-Host "│ Source: $SourceDir"
|
|
99
|
-
Write-Host "│ Target: $TargetDir"
|
|
100
|
-
Write-Host "│"
|
|
101
|
-
|
|
102
|
-
# Check if source directory exists
|
|
103
|
-
if (-not $SourceDir) {
|
|
104
|
-
Write-Host "│"
|
|
105
|
-
$DevelopmentPath = Join-Path $ScriptDir ".claude"
|
|
106
|
-
$InstalledPath = Join-Path $env:USERPROFILE ".ccs\.claude"
|
|
107
|
-
Write-ErrorMsg @"
|
|
108
|
-
Source directory not found.
|
|
109
|
-
|
|
110
|
-
Checked locations:
|
|
111
|
-
- $DevelopmentPath (development)
|
|
112
|
-
- $InstalledPath (installed)
|
|
113
|
-
|
|
114
|
-
Solution:
|
|
115
|
-
1. If developing: Ensure you're in the CCS repository
|
|
116
|
-
2. If installed: Reinstall CCS with: irm ccs.kaitran.ca/install | iex
|
|
117
|
-
"@
|
|
118
|
-
exit 1
|
|
149
|
+
# Title
|
|
150
|
+
if ($UseColors) {
|
|
151
|
+
Write-Host "CCS (Claude Code Switch) v$CcsVersion" -ForegroundColor White
|
|
152
|
+
} else {
|
|
153
|
+
Write-Host "CCS (Claude Code Switch) v$CcsVersion"
|
|
119
154
|
}
|
|
155
|
+
Write-Host ""
|
|
120
156
|
|
|
121
|
-
#
|
|
122
|
-
$
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
if (-not (Test-Path $CommandsDir)) {
|
|
126
|
-
New-Item -ItemType Directory -Path $CommandsDir -Force | Out-Null
|
|
127
|
-
}
|
|
128
|
-
if (-not (Test-Path $SkillsDir)) {
|
|
129
|
-
New-Item -ItemType Directory -Path $SkillsDir -Force | Out-Null
|
|
130
|
-
}
|
|
157
|
+
# Installation
|
|
158
|
+
if ($UseColors) { Write-Host "Installation:" -ForegroundColor Cyan }
|
|
159
|
+
else { Write-Host "Installation:" }
|
|
131
160
|
|
|
132
|
-
|
|
133
|
-
$
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
$CmdName = $_.BaseName
|
|
141
|
-
$TargetFile = Join-Path $CommandsDir "$CmdName.md"
|
|
142
|
-
|
|
143
|
-
if (Test-Path $TargetFile) {
|
|
144
|
-
Write-Host "│ | [i] Skipping existing command: $CmdName.md" -ForegroundColor Yellow
|
|
145
|
-
$SkippedCount++
|
|
146
|
-
} else {
|
|
147
|
-
try {
|
|
148
|
-
Copy-Item $_.FullName $TargetFile -ErrorAction Stop
|
|
149
|
-
Write-Host "│ | [OK] Installed command: $CmdName.md" -ForegroundColor Green
|
|
150
|
-
$InstalledCount++
|
|
151
|
-
} catch {
|
|
152
|
-
Write-Host "│ | [!] Failed to install command: $CmdName.md" -ForegroundColor Red
|
|
153
|
-
Write-Host "│ Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
154
|
-
}
|
|
155
|
-
}
|
|
161
|
+
# Location
|
|
162
|
+
$InstallLocation = (Get-Command ccs -ErrorAction SilentlyContinue).Source
|
|
163
|
+
if ($InstallLocation) {
|
|
164
|
+
if ($UseColors) {
|
|
165
|
+
Write-Host " Location: " -ForegroundColor Cyan -NoNewline
|
|
166
|
+
Write-Host $InstallLocation
|
|
167
|
+
} else {
|
|
168
|
+
Write-Host " Location: $InstallLocation"
|
|
156
169
|
}
|
|
157
170
|
} else {
|
|
158
|
-
|
|
171
|
+
if ($UseColors) {
|
|
172
|
+
Write-Host " Location: " -ForegroundColor Cyan -NoNewline
|
|
173
|
+
Write-Host "(not found - run from current directory)" -ForegroundColor Gray
|
|
174
|
+
} else {
|
|
175
|
+
Write-Host " Location: (not found - run from current directory)"
|
|
176
|
+
}
|
|
159
177
|
}
|
|
160
178
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (Test-Path $SourceSkillsDir) {
|
|
166
|
-
Write-Host "│ Installing skills..." -ForegroundColor Yellow
|
|
167
|
-
Get-ChildItem $SourceSkillsDir -Directory | ForEach-Object {
|
|
168
|
-
$SkillName = $_.Name
|
|
169
|
-
$TargetSkillDir = Join-Path $SkillsDir $SkillName
|
|
170
|
-
|
|
171
|
-
if (Test-Path $TargetSkillDir) {
|
|
172
|
-
Write-Host "│ | [i] Skipping existing skill: $SkillName" -ForegroundColor Yellow
|
|
173
|
-
$SkippedCount++
|
|
174
|
-
} else {
|
|
175
|
-
try {
|
|
176
|
-
Copy-Item $_.FullName $TargetSkillDir -Recurse -ErrorAction Stop
|
|
177
|
-
Write-Host "│ | [OK] Installed skill: $SkillName" -ForegroundColor Green
|
|
178
|
-
$InstalledCount++
|
|
179
|
-
} catch {
|
|
180
|
-
Write-Host "│ | [!] Failed to install skill: $SkillName" -ForegroundColor Red
|
|
181
|
-
Write-Host "│ Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
179
|
+
# Config
|
|
180
|
+
if ($UseColors) {
|
|
181
|
+
Write-Host " Config: " -ForegroundColor Cyan -NoNewline
|
|
182
|
+
Write-Host $ConfigFile
|
|
185
183
|
} else {
|
|
186
|
-
Write-Host "
|
|
184
|
+
Write-Host " Config: $ConfigFile"
|
|
187
185
|
}
|
|
188
186
|
|
|
189
|
-
Write-Host "[DONE]"
|
|
190
|
-
Write-Host ""
|
|
191
|
-
Write-Host "[OK] Installation complete!" -ForegroundColor Green
|
|
192
|
-
Write-Host " Installed: $InstalledCount items"
|
|
193
|
-
Write-Host " Skipped: $SkippedCount items (already exist)"
|
|
194
187
|
Write-Host ""
|
|
195
|
-
Write-Host "You can now use the /ccs command in Claude CLI for task delegation." -ForegroundColor Cyan
|
|
196
|
-
Write-Host "Example: /ccs glm /plan 'add user authentication'" -ForegroundColor Cyan
|
|
197
|
-
}
|
|
198
188
|
|
|
199
|
-
#
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
$RemovedCount = 0
|
|
204
|
-
$NotFoundCount = 0
|
|
205
|
-
|
|
206
|
-
Write-Host "[Uninstalling CCS Commands and Skills]" -ForegroundColor Cyan
|
|
207
|
-
Write-Host "│ Target: $TargetDir"
|
|
208
|
-
Write-Host "│"
|
|
209
|
-
|
|
210
|
-
# Check if target directory exists
|
|
211
|
-
if (-not (Test-Path $TargetDir)) {
|
|
212
|
-
Write-Host "│"
|
|
213
|
-
Write-Host "│ [i] Claude directory not found: $TargetDir" -ForegroundColor Gray
|
|
214
|
-
Write-Host "│ Nothing to uninstall."
|
|
215
|
-
Write-Host "[DONE]"
|
|
216
|
-
Write-Host ""
|
|
217
|
-
Write-Host "[OK] Uninstall complete!" -ForegroundColor Green
|
|
218
|
-
Write-Host " Removed: 0 items (nothing was installed)"
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
# Remove commands
|
|
223
|
-
$CommandsDir = Join-Path $TargetDir "commands"
|
|
224
|
-
if (Test-Path $CommandsDir) {
|
|
225
|
-
Write-Host "│ Removing commands..." -ForegroundColor Yellow
|
|
226
|
-
$CmdFile = Join-Path $CommandsDir "ccs.md"
|
|
227
|
-
if (Test-Path $CmdFile) {
|
|
228
|
-
try {
|
|
229
|
-
Remove-Item $CmdFile -Force -ErrorAction Stop
|
|
230
|
-
Write-Host "│ | [OK] Removed command: ccs.md" -ForegroundColor Green
|
|
231
|
-
$RemovedCount++
|
|
232
|
-
} catch {
|
|
233
|
-
Write-Host "│ | [!] Failed to remove command: ccs.md" -ForegroundColor Red
|
|
234
|
-
Write-Host "│ Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
235
|
-
}
|
|
236
|
-
} else {
|
|
237
|
-
Write-Host "│ | [i] CCS command not found" -ForegroundColor Gray
|
|
238
|
-
$NotFoundCount++
|
|
239
|
-
}
|
|
189
|
+
# Documentation
|
|
190
|
+
if ($UseColors) {
|
|
191
|
+
Write-Host "Documentation: https://github.com/kaitranntt/ccs" -ForegroundColor Cyan
|
|
192
|
+
Write-Host "License: MIT" -ForegroundColor Cyan
|
|
240
193
|
} else {
|
|
241
|
-
Write-Host "
|
|
242
|
-
|
|
194
|
+
Write-Host "Documentation: https://github.com/kaitranntt/ccs"
|
|
195
|
+
Write-Host "License: MIT"
|
|
243
196
|
}
|
|
197
|
+
Write-Host ""
|
|
244
198
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
# Remove skills
|
|
248
|
-
$SkillsDir = Join-Path $TargetDir "skills"
|
|
249
|
-
if (Test-Path $SkillsDir) {
|
|
250
|
-
Write-Host "│ Removing skills..." -ForegroundColor Yellow
|
|
251
|
-
$SkillDir = Join-Path $SkillsDir "ccs-delegation"
|
|
252
|
-
if (Test-Path $SkillDir) {
|
|
253
|
-
try {
|
|
254
|
-
Remove-Item $SkillDir -Recurse -Force -ErrorAction Stop
|
|
255
|
-
Write-Host "│ | [OK] Removed skill: ccs-delegation" -ForegroundColor Green
|
|
256
|
-
$RemovedCount++
|
|
257
|
-
} catch {
|
|
258
|
-
Write-Host "│ | [!] Failed to remove skill: ccs-delegation" -ForegroundColor Red
|
|
259
|
-
Write-Host "│ Error: $($_.Exception.Message)" -ForegroundColor Red
|
|
260
|
-
}
|
|
261
|
-
} else {
|
|
262
|
-
Write-Host "│ | [i] CCS skill not found" -ForegroundColor Gray
|
|
263
|
-
$NotFoundCount++
|
|
264
|
-
}
|
|
199
|
+
if ($UseColors) {
|
|
200
|
+
Write-Host "Run 'ccs --help' for usage information" -ForegroundColor Yellow
|
|
265
201
|
} else {
|
|
266
|
-
Write-Host "
|
|
267
|
-
$NotFoundCount++
|
|
202
|
+
Write-Host "Run 'ccs --help' for usage information"
|
|
268
203
|
}
|
|
269
|
-
|
|
270
|
-
Write-Host "[DONE]"
|
|
271
|
-
Write-Host ""
|
|
272
|
-
Write-Host "[OK] Uninstall complete!" -ForegroundColor Green
|
|
273
|
-
Write-Host " Removed: $RemovedCount items"
|
|
274
|
-
Write-Host " Not found: $NotFoundCount items (already removed)"
|
|
275
|
-
Write-Host ""
|
|
276
|
-
Write-Host "The /ccs command is no longer available in Claude CLI." -ForegroundColor Cyan
|
|
277
|
-
Write-Host "To reinstall: ccs --install" -ForegroundColor Cyan
|
|
278
204
|
}
|
|
279
205
|
|
|
280
206
|
# Special case: version command (check BEFORE profile detection)
|
|
281
|
-
#
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
Write-Host "CCS (Claude Code Switch) version $CcsVersion"
|
|
285
|
-
|
|
286
|
-
# Show install location
|
|
287
|
-
$InstallLocation = (Get-Command ccs -ErrorAction SilentlyContinue).Source
|
|
288
|
-
if ($InstallLocation) {
|
|
289
|
-
Write-Host "Installed at: $InstallLocation"
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
Write-Host "https://github.com/kaitranntt/ccs"
|
|
207
|
+
# Handle switch parameters and remaining arguments
|
|
208
|
+
if ($Version) {
|
|
209
|
+
Show-Version
|
|
293
210
|
exit 0
|
|
211
|
+
} elseif ($RemainingArgs.Count -gt 0) {
|
|
212
|
+
$FirstArg = $RemainingArgs[0]
|
|
213
|
+
if ($FirstArg -eq "version" -or $FirstArg -eq "--version" -or $FirstArg -eq "-v") {
|
|
214
|
+
Show-Version
|
|
215
|
+
exit 0
|
|
216
|
+
}
|
|
294
217
|
}
|
|
295
218
|
|
|
296
219
|
# Special case: help command (check BEFORE profile detection)
|
|
297
|
-
if ($
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}
|
|
306
|
-
exit $LASTEXITCODE
|
|
307
|
-
} catch {
|
|
308
|
-
Show-ClaudeNotFoundError
|
|
309
|
-
exit 1
|
|
220
|
+
if ($Help) {
|
|
221
|
+
Show-Help
|
|
222
|
+
exit 0
|
|
223
|
+
} elseif ($RemainingArgs.Count -gt 0) {
|
|
224
|
+
$FirstArg = $RemainingArgs[0]
|
|
225
|
+
if ($FirstArg -eq "--help" -or $FirstArg -eq "-h" -or $FirstArg -eq "help") {
|
|
226
|
+
Show-Help
|
|
227
|
+
exit 0
|
|
310
228
|
}
|
|
311
229
|
}
|
|
312
230
|
|
|
313
231
|
# Special case: install command (check BEFORE profile detection)
|
|
314
232
|
if ($FirstArg -eq "--install") {
|
|
315
|
-
|
|
316
|
-
exit
|
|
233
|
+
Write-Host "Installation not implemented in this test version" -ForegroundColor Yellow
|
|
234
|
+
exit 0
|
|
317
235
|
}
|
|
318
236
|
|
|
319
237
|
# Special case: uninstall command (check BEFORE profile detection)
|
|
320
238
|
if ($FirstArg -eq "--uninstall") {
|
|
321
|
-
|
|
322
|
-
exit
|
|
239
|
+
Write-Host "Uninstallation not implemented in this test version" -ForegroundColor Yellow
|
|
240
|
+
exit 0
|
|
323
241
|
}
|
|
324
242
|
|
|
325
243
|
# Smart profile detection: if first arg starts with '-', it's a flag not a profile
|
|
326
|
-
if ($
|
|
327
|
-
#
|
|
244
|
+
if ($RemainingArgs.Count -eq 0 -or $RemainingArgs[0] -match '^-') {
|
|
245
|
+
# No args or first arg is a flag → use default profile
|
|
328
246
|
$Profile = "default"
|
|
329
|
-
#
|
|
330
|
-
if ($RemainingArgs) {
|
|
331
|
-
$RemainingArgs = @($ProfileOrFlag) + $RemainingArgs
|
|
332
|
-
} else {
|
|
333
|
-
$RemainingArgs = @($ProfileOrFlag)
|
|
334
|
-
}
|
|
247
|
+
# $RemainingArgs already contains the remaining args correctly
|
|
335
248
|
} else {
|
|
336
249
|
# First arg is a profile name
|
|
337
|
-
$Profile = $
|
|
338
|
-
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
# Special case: "default" profile just runs claude directly (no profile switching)
|
|
342
|
-
if ($Profile -eq "default") {
|
|
343
|
-
try {
|
|
344
|
-
if ($RemainingArgs) {
|
|
345
|
-
& claude @RemainingArgs
|
|
346
|
-
} else {
|
|
347
|
-
& claude
|
|
348
|
-
}
|
|
349
|
-
exit $LASTEXITCODE
|
|
350
|
-
} catch {
|
|
351
|
-
Write-Host "Error: Failed to execute claude" -ForegroundColor Red
|
|
352
|
-
Write-Host $_.Exception.Message
|
|
353
|
-
exit 1
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
# Config file location (supports environment variable override)
|
|
358
|
-
$ConfigFile = if ($env:CCS_CONFIG) {
|
|
359
|
-
$env:CCS_CONFIG
|
|
360
|
-
} else {
|
|
361
|
-
"$env:USERPROFILE\.ccs\config.json"
|
|
250
|
+
$Profile = $RemainingArgs[0]
|
|
251
|
+
$RemainingArgs = if ($RemainingArgs.Count -gt 1) { $RemainingArgs | Select-Object -Skip 1 } else { @() }
|
|
362
252
|
}
|
|
363
253
|
|
|
364
254
|
# Check config exists
|
|
365
255
|
if (-not (Test-Path $ConfigFile)) {
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
Set-Content -Path '$env:USERPROFILE\.ccs\config.json' -Value '{
|
|
376
|
-
"profiles": {
|
|
377
|
-
"glm": "~/.ccs/glm.settings.json",
|
|
378
|
-
"default": "~/.claude/settings.json"
|
|
379
|
-
}
|
|
380
|
-
}'
|
|
381
|
-
"@
|
|
256
|
+
$ErrorMessage = "Config file not found: $ConfigFile" + "`n`n" +
|
|
257
|
+
"Solutions:" + "`n" +
|
|
258
|
+
" 1. Reinstall CCS:" + "`n" +
|
|
259
|
+
" irm ccs.kaitran.ca/install | iex" + "`n`n" +
|
|
260
|
+
" 2. Or create config manually:" + "`n" +
|
|
261
|
+
" New-Item -ItemType Directory -Force -Path '$env:USERPROFILE\.ccs'" + "`n" +
|
|
262
|
+
" Set-Content -Path '$env:USERPROFILE\.ccs\config.json' -Value '{`"profiles`":{`"glm`":`"~/.ccs/glm.settings.json`",`"default`":`"~/.claude/settings.json`"}}'"
|
|
263
|
+
|
|
264
|
+
Write-ErrorMsg $ErrorMessage
|
|
382
265
|
exit 1
|
|
383
266
|
}
|
|
384
267
|
|
|
385
268
|
# Validate profile name (alphanumeric, dash, underscore only)
|
|
386
269
|
if ($Profile -notmatch '^[a-zA-Z0-9_-]+$') {
|
|
387
|
-
|
|
388
|
-
|
|
270
|
+
$ErrorMessage = "Invalid profile name: $Profile" + "`n`n" +
|
|
271
|
+
"Use only alphanumeric characters, dash, or underscore."
|
|
389
272
|
|
|
390
|
-
|
|
391
|
-
"@
|
|
273
|
+
Write-ErrorMsg $ErrorMessage
|
|
392
274
|
exit 1
|
|
393
275
|
}
|
|
394
276
|
|
|
395
|
-
# Read and parse JSON config
|
|
277
|
+
# Read and parse JSON config, get profile path in one step
|
|
396
278
|
try {
|
|
397
279
|
$ConfigContent = Get-Content $ConfigFile -Raw -ErrorAction Stop
|
|
398
280
|
$Config = $ConfigContent | ConvertFrom-Json -ErrorAction Stop
|
|
399
|
-
|
|
400
|
-
Write-ErrorMsg @"
|
|
401
|
-
Invalid JSON in $ConfigFile
|
|
402
|
-
|
|
403
|
-
Fix the JSON syntax or reinstall:
|
|
404
|
-
irm ccs.kaitran.ca/install | iex
|
|
405
|
-
"@
|
|
406
|
-
exit 1
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
# Validate config has profiles object
|
|
410
|
-
if (-not $Config.profiles) {
|
|
411
|
-
Write-ErrorMsg @"
|
|
412
|
-
Config must have 'profiles' object
|
|
281
|
+
$SettingsPath = $Config.profiles.$Profile
|
|
413
282
|
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
"
|
|
418
|
-
|
|
419
|
-
}
|
|
283
|
+
if (-not $SettingsPath) {
|
|
284
|
+
$AvailableProfiles = ($Config.profiles.PSObject.Properties.Name | ForEach-Object { " - $_" }) -join "`n"
|
|
285
|
+
$ErrorMessage = "Profile '$Profile' not found in $ConfigFile" + "`n`n" +
|
|
286
|
+
"Available profiles:" + "`n" +
|
|
287
|
+
$AvailableProfiles
|
|
420
288
|
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
$
|
|
426
|
-
|
|
427
|
-
|
|
289
|
+
Write-ErrorMsg $ErrorMessage
|
|
290
|
+
exit 1
|
|
291
|
+
}
|
|
292
|
+
} catch {
|
|
293
|
+
$ErrorMessage = "Invalid JSON in $ConfigFile" + "`n`n" +
|
|
294
|
+
"Fix the JSON syntax or reinstall:" + "`n" +
|
|
295
|
+
" irm ccs.kaitran.ca/install | iex"
|
|
428
296
|
|
|
429
|
-
|
|
430
|
-
$AvailableProfiles
|
|
431
|
-
"@
|
|
297
|
+
Write-ErrorMsg $ErrorMessage
|
|
432
298
|
exit 1
|
|
433
299
|
}
|
|
434
300
|
|
|
@@ -446,33 +312,13 @@ $SettingsPath = $SettingsPath -replace '/', '\'
|
|
|
446
312
|
|
|
447
313
|
# Validate settings file exists
|
|
448
314
|
if (-not (Test-Path $SettingsPath)) {
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
2. Update the path in $ConfigFile
|
|
455
|
-
3. Or reinstall: irm ccs.kaitran.ca/install | iex
|
|
456
|
-
"@
|
|
457
|
-
exit 1
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
# Validate settings file is valid JSON (basic check)
|
|
461
|
-
try {
|
|
462
|
-
$SettingsContent = Get-Content $SettingsPath -Raw -ErrorAction Stop
|
|
463
|
-
$Settings = $SettingsContent | ConvertFrom-Json -ErrorAction Stop
|
|
464
|
-
} catch {
|
|
465
|
-
Write-ErrorMsg @"
|
|
466
|
-
Invalid JSON in $SettingsPath
|
|
467
|
-
|
|
468
|
-
Details: $_
|
|
315
|
+
$ErrorMessage = "Settings file not found: $SettingsPath" + "`n`n" +
|
|
316
|
+
"Solutions:" + "`n" +
|
|
317
|
+
" 1. Create the settings file for profile '$Profile'" + "`n" +
|
|
318
|
+
" 2. Update the path in $ConfigFile" + "`n" +
|
|
319
|
+
" 3. Or reinstall: irm ccs.kaitran.ca/install | iex"
|
|
469
320
|
|
|
470
|
-
|
|
471
|
-
1. Validate JSON at https://jsonlint.com
|
|
472
|
-
2. Or reset to template:
|
|
473
|
-
Set-Content -Path '$SettingsPath' -Value '{`"env`":{}}`'
|
|
474
|
-
3. Or reinstall: irm ccs.kaitran.ca/install | iex
|
|
475
|
-
"@
|
|
321
|
+
Write-ErrorMsg $ErrorMessage
|
|
476
322
|
exit 1
|
|
477
323
|
}
|
|
478
324
|
|
|
@@ -490,4 +336,4 @@ try {
|
|
|
490
336
|
} catch {
|
|
491
337
|
Show-ClaudeNotFoundError
|
|
492
338
|
exit 1
|
|
493
|
-
}
|
|
339
|
+
}
|