@kaitranntt/ccs 4.1.4 → 4.1.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/VERSION CHANGED
@@ -1 +1 @@
1
- 4.1.4
1
+ 4.1.5
@@ -29,7 +29,7 @@ class AuthCommands {
29
29
  * Show help for auth commands
30
30
  */
31
31
  showHelp() {
32
- console.log(colored('CCS Account Management', 'bold'));
32
+ console.log(colored('CCS Concurrent Account Management', 'bold'));
33
33
  console.log('');
34
34
  console.log(colored('Usage:', 'cyan'));
35
35
  console.log(` ${colored('ccs auth', 'yellow')} <command> [options]`);
package/bin/ccs.js CHANGED
@@ -63,45 +63,69 @@ function handleVersionCommand() {
63
63
  console.log(colored(`CCS (Claude Code Switch) v${CCS_VERSION}`, 'bold'));
64
64
  console.log('');
65
65
 
66
- // Installation section
66
+ // Installation section with table-like formatting
67
67
  console.log(colored('Installation:', 'cyan'));
68
68
 
69
69
  // Location
70
70
  const installLocation = process.argv[1] || '(not found)';
71
- console.log(` ${colored('Location:', 'cyan')} ${installLocation}`);
71
+ console.log(` ${colored('Location:'.padEnd(17), 'cyan')} ${installLocation}`);
72
+
73
+ // .ccs/ directory location
74
+ const ccsDir = path.join(os.homedir(), '.ccs');
75
+ console.log(` ${colored('CCS Directory:'.padEnd(17), 'cyan')} ${ccsDir}`);
72
76
 
73
77
  // Config path
74
78
  const configPath = getConfigPath();
75
- console.log(` ${colored('Config:', 'cyan')} ${configPath}`);
76
-
77
- // Delegation status
78
- const delegationRulesPath = path.join(os.homedir(), '.ccs', 'delegation-rules.json');
79
- const delegationEnabled = fs.existsSync(delegationRulesPath);
80
-
81
- if (delegationEnabled) {
82
- console.log(` ${colored('Delegation:', 'cyan')} Enabled`);
83
-
84
- // Check which profiles are delegation-ready
85
- const readyProfiles = [];
86
- const { DelegationValidator } = require('./utils/delegation-validator');
87
-
88
- for (const profile of ['glm', 'kimi']) {
89
- const validation = DelegationValidator.validate(profile);
90
- if (validation.valid) {
91
- readyProfiles.push(profile);
79
+ console.log(` ${colored('Config:'.padEnd(17), 'cyan')} ${configPath}`);
80
+
81
+ // Profiles.json location
82
+ const profilesJson = path.join(os.homedir(), '.ccs', 'profiles.json');
83
+ console.log(` ${colored('Profiles:'.padEnd(17), 'cyan')} ${profilesJson}`);
84
+
85
+ // Delegation status - check multiple indicators
86
+ const delegationSessionsPath = path.join(os.homedir(), '.ccs', 'delegation-sessions.json');
87
+ const delegationConfigured = fs.existsSync(delegationSessionsPath);
88
+
89
+ let readyProfiles = [];
90
+
91
+ // Check for profiles with valid API keys
92
+ for (const profile of ['glm', 'kimi']) {
93
+ const settingsPath = path.join(os.homedir(), '.ccs', `${profile}.settings.json`);
94
+ if (fs.existsSync(settingsPath)) {
95
+ try {
96
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
97
+ const apiKey = settings.env?.ANTHROPIC_AUTH_TOKEN;
98
+ if (apiKey && !apiKey.match(/YOUR_.*_API_KEY_HERE/) && !apiKey.match(/sk-test.*/)) {
99
+ readyProfiles.push(profile);
100
+ }
101
+ } catch (error) {
102
+ // Invalid JSON, skip
92
103
  }
93
104
  }
105
+ }
94
106
 
95
- if (readyProfiles.length > 0) {
96
- console.log(` ${colored('Ready:', 'cyan')} ${readyProfiles.join(', ')}`);
97
- } else {
98
- console.log(` ${colored('Ready:', 'cyan')} None (configure profiles first)`);
99
- }
107
+ const hasValidApiKeys = readyProfiles.length > 0;
108
+ const delegationEnabled = delegationConfigured || hasValidApiKeys;
109
+
110
+ if (delegationEnabled) {
111
+ console.log(` ${colored('Delegation:'.padEnd(17), 'cyan')} Enabled`);
100
112
  } else {
101
- console.log(` ${colored('Delegation:', 'cyan')} Not configured`);
113
+ console.log(` ${colored('Delegation:'.padEnd(17), 'cyan')} Not configured`);
102
114
  }
115
+
103
116
  console.log('');
104
117
 
118
+ // Ready Profiles section - make it more prominent
119
+ if (readyProfiles.length > 0) {
120
+ console.log(colored('Delegation Ready:', 'cyan'));
121
+ console.log(` ${colored('✓', 'yellow')} ${readyProfiles.join(', ')} profiles are ready for delegation`);
122
+ console.log('');
123
+ } else if (delegationEnabled) {
124
+ console.log(colored('Delegation Ready:', 'cyan'));
125
+ console.log(` ${colored('!', 'yellow')} Delegation configured but no valid API keys found`);
126
+ console.log('');
127
+ }
128
+
105
129
  // Documentation
106
130
  console.log(`${colored('Documentation:', 'cyan')} https://github.com/kaitranntt/ccs`);
107
131
  console.log(`${colored('License:', 'cyan')} MIT`);
@@ -143,7 +167,7 @@ function handleHelpCommand() {
143
167
 
144
168
  // Account Management
145
169
  console.log(colored('Account Management:', 'cyan'));
146
- console.log(` ${colored('ccs auth --help', 'yellow')} Manage multiple Claude accounts`);
170
+ console.log(` ${colored('ccs auth --help', 'yellow')} Run multiple Claude accounts concurrently`);
147
171
  console.log('');
148
172
 
149
173
  // Delegation (inside Claude Code CLI)
@@ -156,14 +180,14 @@ function handleHelpCommand() {
156
180
  // Diagnostics
157
181
  console.log(colored('Diagnostics:', 'cyan'));
158
182
  console.log(` ${colored('ccs doctor', 'yellow')} Run health check and diagnostics`);
159
- console.log(` ${colored('ccs update', 'yellow')} Re-install CCS items to ~/.claude/`);
183
+ console.log(` ${colored('ccs sync', 'yellow')} Sync delegation commands and skills`);
160
184
  console.log('');
161
185
 
162
186
  // Flags
163
187
  console.log(colored('Flags:', 'cyan'));
164
188
  console.log(` ${colored('-h, --help', 'yellow')} Show this help message`);
165
189
  console.log(` ${colored('-v, --version', 'yellow')} Show version and installation info`);
166
- console.log(` ${colored('--shell-completion', 'yellow')} Install shell auto-completion`);
190
+ console.log(` ${colored('-sc, --shell-completion', 'yellow')} Install shell auto-completion`);
167
191
  console.log('');
168
192
 
169
193
  // Configuration
@@ -188,7 +212,7 @@ function handleHelpCommand() {
188
212
  console.log(` ${colored('$ ccs', 'yellow')} # Use default account`);
189
213
  console.log(` ${colored('$ ccs glm "implement API"', 'yellow')} # Cost-optimized model`);
190
214
  console.log('');
191
- console.log(` For more: ${colored('https://github.com/kaitranntt/ccs#usage', 'cyan')}`);
215
+ console.log(` For more: ${colored('https://github.com/kaitranntt/ccs/blob/main/README.md', 'cyan')}`);
192
216
  console.log('');
193
217
 
194
218
  // Uninstall
@@ -245,7 +269,7 @@ async function handleDoctorCommand() {
245
269
  process.exit(doctor.results.isHealthy() ? 0 : 1);
246
270
  }
247
271
 
248
- async function handleUpdateCommand() {
272
+ async function handleSyncCommand() {
249
273
  // First, copy .claude/ directory from package to ~/.ccs/.claude/
250
274
  const ClaudeDirInstaller = require('./utils/claude-dir-installer');
251
275
  const installer = new ClaudeDirInstaller();
@@ -255,8 +279,8 @@ async function handleUpdateCommand() {
255
279
  const ClaudeSymlinkManager = require('./utils/claude-symlink-manager');
256
280
  const manager = new ClaudeSymlinkManager();
257
281
 
258
- console.log('[i] Updating CCS items in ~/.claude/...');
259
- manager.update();
282
+ console.log('[i] Syncing delegation commands and skills to ~/.claude/...');
283
+ manager.sync();
260
284
 
261
285
  process.exit(0);
262
286
  }
@@ -487,7 +511,7 @@ async function main() {
487
511
  }
488
512
 
489
513
  // Special case: shell completion installer
490
- if (firstArg === '--shell-completion') {
514
+ if (firstArg === '--shell-completion' || firstArg === '-sc') {
491
515
  await handleShellCompletionCommand(args.slice(1));
492
516
  return;
493
517
  }
@@ -498,9 +522,9 @@ async function main() {
498
522
  return;
499
523
  }
500
524
 
501
- // Special case: update command (re-install CCS symlinks)
502
- if (firstArg === 'update' || firstArg === '--update') {
503
- await handleUpdateCommand();
525
+ // Special case: sync command (sync delegation commands and skills to ~/.claude/)
526
+ if (firstArg === 'sync' || firstArg === '--sync') {
527
+ await handleSyncCommand();
504
528
  return;
505
529
  }
506
530
 
@@ -53,7 +53,7 @@ class ClaudeSymlinkManager {
53
53
  this._installItem(item);
54
54
  }
55
55
 
56
- console.log('[OK] CCS items installed to ~/.claude/');
56
+ console.log('[OK] Delegation commands and skills installed to ~/.claude/');
57
57
  }
58
58
 
59
59
  /**
@@ -178,9 +178,9 @@ class ClaudeSymlinkManager {
178
178
  }
179
179
 
180
180
  if (removed > 0) {
181
- console.log(`[OK] Removed ${removed} CCS items from ~/.claude/`);
181
+ console.log(`[OK] Removed ${removed} delegation commands and skills from ~/.claude/`);
182
182
  } else {
183
- console.log('[i] No CCS items to remove');
183
+ console.log('[i] No delegation commands or skills to remove');
184
184
  }
185
185
  }
186
186
 
@@ -226,11 +226,11 @@ class ClaudeSymlinkManager {
226
226
  }
227
227
 
228
228
  /**
229
- * Re-install symlinks (used by 'ccs update' command)
230
- * Same as install() but with explicit re-installation message
229
+ * Sync delegation commands and skills to ~/.claude/ (used by 'ccs sync' command)
230
+ * Same as install() but with explicit sync message
231
231
  */
232
- update() {
233
- console.log('[i] Updating CCS items in ~/.claude/...');
232
+ sync() {
233
+ console.log('[i] Syncing delegation commands and skills to ~/.claude/...');
234
234
  this.install();
235
235
  }
236
236
  }
package/lib/ccs CHANGED
@@ -2,7 +2,7 @@
2
2
  set -euo pipefail
3
3
 
4
4
  # Version (updated by scripts/bump-version.sh)
5
- CCS_VERSION="4.1.4"
5
+ CCS_VERSION="4.1.5"
6
6
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
7
  readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}"
8
8
  readonly PROFILES_JSON="$HOME/.ccs/profiles.json"
@@ -165,65 +165,82 @@ find_similar_strings() {
165
165
  show_help() {
166
166
  echo -e "${BOLD}CCS (Claude Code Switch) - Instant profile switching for Claude CLI${RESET}"
167
167
  echo ""
168
+
168
169
  echo -e "${CYAN}Usage:${RESET}"
169
170
  echo -e " ${YELLOW}ccs${RESET} [profile] [claude-args...]"
170
- echo -e " ${YELLOW}ccs auth${RESET} <command> [options]"
171
171
  echo -e " ${YELLOW}ccs${RESET} [flags]"
172
172
  echo ""
173
+
173
174
  echo -e "${CYAN}Description:${RESET}"
174
175
  echo -e " Switch between multiple Claude accounts and alternative models"
175
176
  echo -e " (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently"
176
177
  echo -e " with auto-recovery. Zero downtime."
177
178
  echo ""
179
+
178
180
  echo -e "${CYAN}Model Switching:${RESET}"
179
181
  echo -e " ${YELLOW}ccs${RESET} Use default Claude account"
180
182
  echo -e " ${YELLOW}ccs glm${RESET} Switch to GLM 4.6 model"
181
183
  echo -e " ${YELLOW}ccs glmt${RESET} Switch to GLM with thinking mode"
184
+ echo -e " ${YELLOW}ccs glmt --verbose${RESET} Enable debug logging"
182
185
  echo -e " ${YELLOW}ccs kimi${RESET} Switch to Kimi for Coding"
183
186
  echo -e " ${YELLOW}ccs glm${RESET} \"debug this code\" Use GLM and run command"
184
187
  echo ""
188
+
185
189
  echo -e "${CYAN}Account Management:${RESET}"
186
- echo -e " ${YELLOW}ccs auth --help${RESET} Manage multiple Claude accounts"
190
+ echo -e " ${YELLOW}ccs auth --help${RESET} Run multiple Claude accounts concurrently"
187
191
  echo ""
192
+
188
193
  echo -e "${CYAN}Delegation (inside Claude Code CLI):${RESET}"
189
194
  echo -e " ${YELLOW}/ccs:glm \"task\"${RESET} Delegate to GLM-4.6 for simple tasks"
190
195
  echo -e " ${YELLOW}/ccs:kimi \"task\"${RESET} Delegate to Kimi for long context"
191
196
  echo -e " Save tokens by delegating simple tasks to cost-optimized models"
192
197
  echo ""
198
+
193
199
  echo -e "${CYAN}Diagnostics:${RESET}"
194
200
  echo -e " ${YELLOW}ccs doctor${RESET} Run health check and diagnostics"
201
+ echo -e " ${YELLOW}ccs sync${RESET} Sync delegation commands and skills"
195
202
  echo ""
203
+
196
204
  echo -e "${CYAN}Flags:${RESET}"
197
205
  echo -e " ${YELLOW}-h, --help${RESET} Show this help message"
198
206
  echo -e " ${YELLOW}-v, --version${RESET} Show version and installation info"
199
- echo -e " ${YELLOW}--shell-completion${RESET} Install shell auto-completion"
207
+ echo -e " ${YELLOW}-sc, --shell-completion${RESET} Install shell auto-completion"
200
208
  echo ""
209
+
201
210
  echo -e "${CYAN}Configuration:${RESET}"
202
- echo -e " Config: ~/.ccs/config.json"
203
- echo -e " Profiles: ~/.ccs/profiles.json"
204
- echo -e " Instances: ~/.ccs/instances/"
205
- echo -e " Settings: ~/.ccs/*.settings.json"
211
+ echo -e " Config File: ~/.ccs/config.json"
212
+ echo -e " Profiles: ~/.ccs/profiles.json"
213
+ echo -e " Instances: ~/.ccs/instances/"
214
+ echo -e " Settings: ~/.ccs/*.settings.json"
215
+ echo -e " Environment: CCS_CONFIG (override config path)"
206
216
  echo ""
217
+
207
218
  echo -e "${CYAN}Shared Data:${RESET}"
208
- echo -e " Commands: ~/.ccs/shared/commands/"
209
- echo -e " Skills: ~/.ccs/shared/skills/"
219
+ echo -e " Commands: ~/.ccs/shared/commands/"
220
+ echo -e " Skills: ~/.ccs/shared/skills/"
221
+ echo -e " Agents: ~/.ccs/shared/agents/"
210
222
  echo -e " Note: Commands, skills, and agents are symlinked across all profiles"
211
223
  echo ""
224
+
212
225
  echo -e "${CYAN}Examples:${RESET}"
213
226
  echo -e " ${YELLOW}\$ ccs${RESET} # Use default account"
214
227
  echo -e " ${YELLOW}\$ ccs glm \"implement API\"${RESET} # Cost-optimized model"
215
228
  echo ""
216
- echo -e " For more: ${CYAN}https://github.com/kaitranntt/ccs#usage${RESET}"
229
+ echo -e " For more: ${CYAN}https://github.com/kaitranntt/ccs/blob/main/README.md${RESET}"
217
230
  echo ""
231
+
218
232
  echo -e "${YELLOW}Uninstall:${RESET}"
219
- echo " npm: npm uninstall -g @kaitranntt/ccs"
220
- echo " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
221
- echo " Windows: irm ccs.kaitran.ca/uninstall | iex"
233
+ echo -e " npm: npm uninstall -g @kaitranntt/ccs"
234
+ echo -e " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
235
+ echo -e " Windows: irm ccs.kaitran.ca/uninstall | iex"
222
236
  echo ""
237
+
223
238
  echo -e "${CYAN}Documentation:${RESET}"
224
239
  echo -e " GitHub: ${CYAN}https://github.com/kaitranntt/ccs${RESET}"
225
240
  echo -e " Docs: https://github.com/kaitranntt/ccs/blob/main/README.md"
241
+ echo -e " Issues: https://github.com/kaitranntt/ccs/issues"
226
242
  echo ""
243
+
227
244
  echo -e "${CYAN}License:${RESET} MIT"
228
245
  }
229
246
 
@@ -480,6 +497,100 @@ doctor_run() {
480
497
  $has_errors && exit 1 || exit 0
481
498
  }
482
499
 
500
+ # --- Sync Command ---
501
+
502
+ sync_run() {
503
+ local ccs_claude_dir="$HOME/.ccs/.claude"
504
+ local user_claude_dir="$HOME/.claude"
505
+
506
+ echo -e "${CYAN}Syncing delegation commands and skills to ~/.claude/...${RESET}"
507
+ echo ""
508
+
509
+ # Check if source directory exists
510
+ if [[ ! -d "$ccs_claude_dir" ]]; then
511
+ msg_error "CCS .claude/ directory not found at $ccs_claude_dir"
512
+ echo "Reinstall CCS: npm install -g @kaitranntt/ccs --force"
513
+ exit 1
514
+ fi
515
+
516
+ # Create ~/.claude/ if missing
517
+ if [[ ! -d "$user_claude_dir" ]]; then
518
+ echo -e "${CYAN}[i]${RESET} Creating ~/.claude/ directory"
519
+ mkdir -p "$user_claude_dir"
520
+ chmod 700 "$user_claude_dir"
521
+ fi
522
+
523
+ # Items to symlink (source:target:type)
524
+ local items=(
525
+ "commands/ccs:commands/ccs:dir"
526
+ "skills/ccs-delegation:skills/ccs-delegation:dir"
527
+ "agents/ccs-delegator.md:agents/ccs-delegator.md:file"
528
+ )
529
+
530
+ local installed=0
531
+ local skipped=0
532
+
533
+ for item in "${items[@]}"; do
534
+ IFS=':' read -r source target type <<< "$item"
535
+ local source_path="$ccs_claude_dir/$source"
536
+ local target_path="$user_claude_dir/$target"
537
+ local target_dir="$(dirname "$target_path")"
538
+
539
+ # Check source exists
540
+ if [[ ! -e "$source_path" ]]; then
541
+ echo -e "${YELLOW}[!]${RESET} Source not found: $source, skipping"
542
+ continue
543
+ fi
544
+
545
+ # Create parent directory if needed
546
+ if [[ ! -d "$target_dir" ]]; then
547
+ mkdir -p "$target_dir"
548
+ chmod 700 "$target_dir"
549
+ fi
550
+
551
+ # Check if already correct symlink
552
+ if [[ -L "$target_path" ]]; then
553
+ local link_target="$(readlink "$target_path")"
554
+ local resolved_target="$(cd "$(dirname "$target_path")" && cd "$(dirname "$link_target")" && pwd)/$(basename "$link_target")"
555
+
556
+ if [[ "$resolved_target" == "$source_path" ]]; then
557
+ ((skipped++))
558
+ continue
559
+ fi
560
+ fi
561
+
562
+ # Backup existing file/directory
563
+ if [[ -e "$target_path" ]]; then
564
+ local timestamp="$(date +%Y-%m-%d)"
565
+ local backup_path="${target_path}.backup-${timestamp}"
566
+ local counter=1
567
+
568
+ while [[ -e "$backup_path" ]]; do
569
+ backup_path="${target_path}.backup-${timestamp}-${counter}"
570
+ ((counter++))
571
+ done
572
+
573
+ mv "$target_path" "$backup_path"
574
+ echo -e "${CYAN}[i]${RESET} Backed up existing to $(basename "$backup_path")"
575
+ fi
576
+
577
+ # Create symlink
578
+ ln -s "$source_path" "$target_path" 2>/dev/null
579
+ if [[ $? -eq 0 ]]; then
580
+ echo -e "${GREEN}[OK]${RESET} Installed $target"
581
+ ((installed++))
582
+ else
583
+ echo -e "${RED}[X]${RESET} Failed to install $target"
584
+ fi
585
+ done
586
+
587
+ echo ""
588
+ echo -e "${GREEN}✓ Update complete${RESET}"
589
+ echo " Installed: $installed"
590
+ echo " Already up-to-date: $skipped"
591
+ echo ""
592
+ }
593
+
483
594
  # --- Claude CLI Detection Logic ---
484
595
 
485
596
  detect_claude_cli() {
@@ -509,49 +620,81 @@ Restart your terminal after installation."
509
620
  }
510
621
 
511
622
  show_version() {
623
+ # Title
512
624
  echo -e "${BOLD}CCS (Claude Code Switch) v${CCS_VERSION}${RESET}"
513
625
  echo ""
626
+
627
+ # Installation section with table-like formatting
514
628
  echo -e "${CYAN}Installation:${RESET}"
515
629
 
516
- # Simple location - just show what 'command -v' returns
517
- local location=$(command -v ccs 2>/dev/null || echo "(not installed)")
518
- echo -e " ${CYAN}Location:${RESET} ${location}"
519
-
520
- # Simple config display
521
- local config="${CCS_CONFIG:-$HOME/.ccs/config.json}"
522
- echo -e " ${CYAN}Config:${RESET} ${config}"
523
-
524
- # Delegation status
525
- local delegation_rules="$HOME/.ccs/delegation-rules.json"
526
- if [[ -f "$delegation_rules" ]]; then
527
- echo -e " ${CYAN}Delegation:${RESET} Enabled"
528
-
529
- # Check which profiles are delegation-ready
530
- local ready_profiles=()
531
- for profile in glm kimi; do
532
- local settings_file="$HOME/.ccs/profiles/$profile/settings.json"
533
- if [[ -f "$settings_file" ]]; then
534
- # Check if API key is configured (not a placeholder)
535
- local api_key=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$settings_file" 2>/dev/null)
536
- if [[ -n "$api_key" ]] && [[ ! "$api_key" =~ YOUR_.*_API_KEY_HERE ]]; then
537
- ready_profiles+=("$profile")
538
- fi
539
- fi
540
- done
630
+ # Location - prioritize script location over command location
631
+ local script_location="$(readlink -f "${BASH_SOURCE[0]}")"
632
+ local command_location=$(command -v ccs 2>/dev/null || echo "(not found)")
541
633
 
542
- if [[ ${#ready_profiles[@]} -gt 0 ]]; then
543
- echo -e " ${CYAN}Ready:${RESET} ${ready_profiles[*]}"
544
- else
545
- echo -e " ${CYAN}Ready:${RESET} None (configure profiles first)"
634
+ # Show script location if running from source
635
+ if [[ "$script_location" == *"ccs"* ]]; then
636
+ printf " ${CYAN}%-16s${RESET} %s\n" "Location:" "${script_location}"
637
+ else
638
+ printf " ${CYAN}%-16s${RESET} %s\n" "Location:" "${command_location}"
639
+ fi
640
+
641
+ # .ccs/ directory location
642
+ printf " ${CYAN}%-16s${RESET} %s\n" "CCS Directory:" "$HOME/.ccs/"
643
+
644
+ # Config path
645
+ printf " ${CYAN}%-16s${RESET} %s\n" "Config:" "${CONFIG_FILE}"
646
+
647
+ # Profiles.json location
648
+ printf " ${CYAN}%-16s${RESET} %s\n" "Profiles:" "${PROFILES_JSON}"
649
+
650
+ # Delegation status - check multiple indicators
651
+ local delegation_configured=false
652
+ local ready_profiles=()
653
+
654
+ # Check for delegation-sessions.json (primary indicator)
655
+ local delegation_sessions="$HOME/.ccs/delegation-sessions.json"
656
+ if [[ -f "$delegation_sessions" ]]; then
657
+ delegation_configured=true
658
+ fi
659
+
660
+ # Check for profiles with valid API keys (secondary indicator)
661
+ for profile in glm kimi; do
662
+ local settings_file="$HOME/.ccs/$profile.settings.json"
663
+ if [[ -f "$settings_file" ]]; then
664
+ # Check if API key is configured (not a placeholder)
665
+ local api_key=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$settings_file" 2>/dev/null)
666
+ if [[ -n "$api_key" ]] && [[ ! "$api_key" =~ YOUR_.*_API_KEY_HERE ]] && [[ ! "$api_key" =~ sk-test.* ]]; then
667
+ ready_profiles+=("$profile")
668
+ delegation_configured=true
669
+ fi
546
670
  fi
671
+ done
672
+
673
+ if $delegation_configured; then
674
+ printf " ${CYAN}%-16s${RESET} %s\n" "Delegation:" "Enabled"
547
675
  else
548
- echo -e " ${CYAN}Delegation:${RESET} Not configured"
676
+ printf " ${CYAN}%-16s${RESET} %s\n" "Delegation:" "Not configured"
549
677
  fi
678
+
550
679
  echo ""
551
680
 
681
+ # Ready Profiles section - make it more prominent
682
+ if [[ ${#ready_profiles[@]} -gt 0 ]]; then
683
+ echo -e "${CYAN}Delegation Ready:${RESET}"
684
+ echo " ${YELLOW}✓${RESET} ${ready_profiles[*]} profiles are ready for delegation"
685
+ echo ""
686
+ elif $delegation_configured; then
687
+ echo -e "${CYAN}Delegation Ready:${RESET}"
688
+ echo " ${YELLOW}!${RESET} Delegation configured but no valid API keys found"
689
+ echo ""
690
+ fi
691
+
692
+ # Documentation
552
693
  echo -e "${CYAN}Documentation:${RESET} https://github.com/kaitranntt/ccs"
553
694
  echo -e "${CYAN}License:${RESET} MIT"
554
695
  echo ""
696
+
697
+ # Help hint
555
698
  echo -e "${YELLOW}Run 'ccs --help' for usage information${RESET}"
556
699
  }
557
700
 
@@ -957,7 +1100,7 @@ detect_profile_type() {
957
1100
  # --- Auth Commands (Phase 3) ---
958
1101
 
959
1102
  auth_help() {
960
- echo -e "${BOLD}CCS Account Management${RESET}"
1103
+ echo -e "${BOLD}CCS Concurrent Account Management${RESET}"
961
1104
  echo ""
962
1105
  echo -e "${CYAN}Usage:${RESET}"
963
1106
  echo -e " ${YELLOW}ccs auth${RESET} <command> [options]"
@@ -1509,7 +1652,7 @@ if [[ $# -gt 0 ]] && [[ "${1}" == "auth" ]]; then
1509
1652
  fi
1510
1653
 
1511
1654
  # Special case: shell completion installer
1512
- if [[ $# -gt 0 ]] && [[ "${1}" == "--shell-completion" ]]; then
1655
+ if [[ $# -gt 0 ]] && [[ "${1}" == "--shell-completion" || "${1}" == "-sc" ]]; then
1513
1656
  install_shell_completion "$@"
1514
1657
  exit $?
1515
1658
  fi
@@ -1520,6 +1663,12 @@ if [[ $# -gt 0 ]] && [[ "${1}" == "doctor" || "${1}" == "--doctor" ]]; then
1520
1663
  exit $?
1521
1664
  fi
1522
1665
 
1666
+ # Special case: sync command
1667
+ if [[ $# -gt 0 ]] && [[ "${1}" == "sync" || "${1}" == "--sync" ]]; then
1668
+ sync_run
1669
+ exit $?
1670
+ fi
1671
+
1523
1672
  # Run auto-recovery before main logic
1524
1673
  auto_recover || {
1525
1674
  msg_error "Auto-recovery failed. Check permissions."
package/lib/ccs.ps1 CHANGED
@@ -12,7 +12,7 @@ param(
12
12
  $ErrorActionPreference = "Stop"
13
13
 
14
14
  # Version (updated by scripts/bump-version.sh)
15
- $CcsVersion = "4.1.4"
15
+ $CcsVersion = "4.1.5"
16
16
  $ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
17
17
  $ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" }
18
18
  $ProfilesJson = "$env:USERPROFILE\.ccs\profiles.json"
@@ -212,66 +212,105 @@ function Show-Help {
212
212
 
213
213
  Write-ColorLine "CCS (Claude Code Switch) - Instant profile switching for Claude CLI" "White"
214
214
  Write-Host ""
215
+
215
216
  Write-ColorLine "Usage:" "Cyan"
216
217
  Write-ColorLine " ccs [profile] [claude-args...]" "Yellow"
217
- Write-ColorLine " ccs auth <command> [options]" "Yellow"
218
218
  Write-ColorLine " ccs [flags]" "Yellow"
219
219
  Write-Host ""
220
+
220
221
  Write-ColorLine "Description:" "Cyan"
221
222
  Write-Host " Switch between multiple Claude accounts and alternative models"
222
223
  Write-Host " (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently"
223
224
  Write-Host " with auto-recovery. Zero downtime."
224
225
  Write-Host ""
226
+
225
227
  Write-ColorLine "Model Switching:" "Cyan"
226
228
  Write-ColorLine " ccs Use default Claude account" "Yellow"
227
229
  Write-ColorLine " ccs glm Switch to GLM 4.6 model" "Yellow"
228
230
  Write-ColorLine " ccs glmt Switch to GLM with thinking mode" "Yellow"
231
+ Write-ColorLine " ccs glmt --verbose Enable debug logging" "Yellow"
229
232
  Write-ColorLine " ccs kimi Switch to Kimi for Coding" "Yellow"
230
233
  Write-ColorLine " ccs glm 'debug this code' Use GLM and run command" "Yellow"
231
234
  Write-Host ""
232
- Write-ColorLine "Examples:" "Cyan"
233
- Write-ColorLine " `$ ccs" "Yellow" -NoNewline
234
- Write-Host " # Use default account"
235
- Write-ColorLine " `$ ccs glm `"implement API`"" "Yellow" -NoNewline
236
- Write-Host " # Cost-optimized model"
237
- Write-Host ""
235
+
238
236
  Write-ColorLine "Account Management:" "Cyan"
239
- Write-ColorLine " ccs auth --help Manage multiple Claude accounts" "Yellow"
237
+ Write-ColorLine " ccs auth --help Run multiple Claude accounts concurrently" "Yellow"
240
238
  Write-Host ""
239
+
241
240
  Write-ColorLine "Delegation (inside Claude Code CLI):" "Cyan"
242
241
  Write-ColorLine " /ccs:glm `"task`" Delegate to GLM-4.6 for simple tasks" "Yellow"
243
242
  Write-ColorLine " /ccs:kimi `"task`" Delegate to Kimi for long context" "Yellow"
244
243
  Write-Host " Save tokens by delegating simple tasks to cost-optimized models"
245
244
  Write-Host ""
245
+
246
246
  Write-ColorLine "Diagnostics:" "Cyan"
247
247
  Write-ColorLine " ccs doctor Run health check and diagnostics" "Yellow"
248
+ Write-ColorLine " ccs sync Sync delegation commands and skills" "Yellow"
248
249
  Write-Host ""
250
+
249
251
  Write-ColorLine "Flags:" "Cyan"
250
252
  Write-ColorLine " -h, --help Show this help message" "Yellow"
251
253
  Write-ColorLine " -v, --version Show version and installation info" "Yellow"
252
- Write-ColorLine " --shell-completion Install shell auto-completion" "Yellow"
254
+ Write-ColorLine " -sc, --shell-completion Install shell auto-completion" "Yellow"
253
255
  Write-Host ""
256
+
254
257
  Write-ColorLine "Configuration:" "Cyan"
255
- Write-Host " Config: ~/.ccs/config.json"
256
- Write-Host " Profiles: ~/.ccs/profiles.json"
257
- Write-Host " Instances: ~/.ccs/instances/"
258
- Write-Host " Settings: ~/.ccs/*.settings.json"
258
+ Write-Host " Config File: ~/.ccs/config.json"
259
+ Write-Host " Profiles: ~/.ccs/profiles.json"
260
+ Write-Host " Instances: ~/.ccs/instances/"
261
+ Write-Host " Settings: ~/.ccs/*.settings.json"
262
+ Write-Host " Environment: CCS_CONFIG (override config path)"
259
263
  Write-Host ""
264
+
260
265
  Write-ColorLine "Shared Data:" "Cyan"
261
- Write-Host " Commands: ~/.ccs/shared/commands/"
262
- Write-Host " Skills: ~/.ccs/shared/skills/"
266
+ Write-Host " Commands: ~/.ccs/shared/commands/"
267
+ Write-Host " Skills: ~/.ccs/shared/skills/"
268
+ Write-Host " Agents: ~/.ccs/shared/agents/"
263
269
  Write-Host " Note: Commands, skills, and agents are symlinked across all profiles"
264
270
  Write-Host ""
271
+
272
+ Write-ColorLine "Examples:" "Cyan"
273
+ Write-ColorLine " `$ ccs # Use default account" "Yellow"
274
+ Write-ColorLine " `$ ccs glm `"implement API`" # Cost-optimized model" "Yellow"
275
+ Write-Host ""
276
+ Write-ColorLine " For more: https://github.com/kaitranntt/ccs/blob/main/README.md" "Cyan"
277
+ Write-Host ""
278
+
279
+ Write-ColorLine "Uninstall:" "Yellow"
280
+ Write-Host " npm: npm uninstall -g @kaitranntt/ccs"
281
+ Write-Host " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
282
+ Write-Host " Windows: irm ccs.kaitran.ca/uninstall | iex"
283
+ Write-Host ""
284
+
265
285
  Write-ColorLine "Documentation:" "Cyan"
266
286
  Write-Host " GitHub: https://github.com/kaitranntt/ccs"
267
287
  Write-Host " Docs: https://github.com/kaitranntt/ccs/blob/main/README.md"
288
+ Write-Host " Issues: https://github.com/kaitranntt/ccs/issues"
268
289
  Write-Host ""
290
+
269
291
  Write-ColorLine "License: MIT" "Cyan"
270
292
  }
271
293
 
272
294
  function Show-Version {
273
295
  $UseColors = $env:FORCE_COLOR -or ([Console]::IsOutputRedirected -eq $false -and -not $env:NO_COLOR)
274
296
 
297
+ # Helper for aligned output
298
+ function Write-TableLine {
299
+ param(
300
+ [string]$Label,
301
+ [string]$Value,
302
+ [string]$Color = "Cyan"
303
+ )
304
+ if ($UseColors) {
305
+ $PaddedLabel = $Label.PadRight(17)
306
+ Write-Host " $PaddedLabel " -ForegroundColor $Color -NoNewline
307
+ Write-Host $Value
308
+ } else {
309
+ $PaddedLabel = $Label.PadRight(17)
310
+ Write-Host " $PaddedLabel $Value"
311
+ }
312
+ }
313
+
275
314
  # Title
276
315
  if ($UseColors) {
277
316
  Write-Host "CCS (Claude Code Switch) v$CcsVersion" -ForegroundColor White
@@ -280,38 +319,91 @@ function Show-Version {
280
319
  }
281
320
  Write-Host ""
282
321
 
283
- # Installation
322
+ # Installation section with table-like formatting
284
323
  if ($UseColors) { Write-Host "Installation:" -ForegroundColor Cyan }
285
324
  else { Write-Host "Installation:" }
286
325
 
287
- # Location
326
+ # Location - prioritize script location over command location
327
+ $ScriptLocation = $MyInvocation.MyCommand.Path
288
328
  $InstallLocation = (Get-Command ccs -ErrorAction SilentlyContinue).Source
289
- if ($InstallLocation) {
290
- if ($UseColors) {
291
- Write-Host " Location: " -ForegroundColor Cyan -NoNewline
292
- Write-Host $InstallLocation
293
- } else {
294
- Write-Host " Location: $InstallLocation"
295
- }
329
+
330
+ # Show script location if running from source
331
+ if ($ScriptLocation -and (Test-Path $ScriptLocation)) {
332
+ Write-TableLine "Location:" $ScriptLocation
333
+ } elseif ($InstallLocation) {
334
+ Write-TableLine "Location:" $InstallLocation
296
335
  } else {
297
- if ($UseColors) {
298
- Write-Host " Location: " -ForegroundColor Cyan -NoNewline
299
- Write-Host "(not found - run from current directory)" -ForegroundColor Gray
300
- } else {
301
- Write-Host " Location: (not found - run from current directory)"
336
+ Write-TableLine "Location:" "(not found - run from current directory)"
337
+ }
338
+
339
+ # .ccs/ directory location
340
+ Write-TableLine "CCS Directory:" "$env:USERPROFILE\.ccs\"
341
+
342
+ # Config path
343
+ Write-TableLine "Config:" $ConfigFile
344
+
345
+ # Profiles.json location
346
+ Write-TableLine "Profiles:" $ProfilesJson
347
+
348
+ # Delegation status - check multiple indicators
349
+ $DelegationConfigured = $false
350
+ $ReadyProfiles = @()
351
+
352
+ # Check for delegation-sessions.json (primary indicator)
353
+ $DelegationSessions = "$env:USERPROFILE\.ccs\delegation-sessions.json"
354
+ if (Test-Path $DelegationSessions) {
355
+ $DelegationConfigured = $true
356
+ }
357
+
358
+ # Check for profiles with valid API keys (secondary indicator)
359
+ foreach ($profile in @("glm", "kimi")) {
360
+ $SettingsFile = "$env:USERPROFILE\.ccs\$profile.settings.json"
361
+ if (Test-Path $SettingsFile) {
362
+ try {
363
+ $Settings = Get-Content $SettingsFile -Raw | ConvertFrom-Json
364
+ $ApiKey = $Settings.env.ANTHROPIC_AUTH_TOKEN
365
+ if ($ApiKey -and $ApiKey -notmatch "YOUR_.*_API_KEY_HERE" -and $ApiKey -notmatch "sk-test.*") {
366
+ $ReadyProfiles += $profile
367
+ $DelegationConfigured = $true
368
+ }
369
+ } catch { }
302
370
  }
303
371
  }
304
372
 
305
- # Config
306
- if ($UseColors) {
307
- Write-Host " Config: " -ForegroundColor Cyan -NoNewline
308
- Write-Host $ConfigFile
373
+ if ($DelegationConfigured) {
374
+ Write-TableLine "Delegation:" "Enabled"
309
375
  } else {
310
- Write-Host " Config: $ConfigFile"
376
+ Write-TableLine "Delegation:" "Not configured"
311
377
  }
312
378
 
313
379
  Write-Host ""
314
380
 
381
+ # Ready Profiles section - make it more prominent
382
+ if ($ReadyProfiles.Count -gt 0) {
383
+ if ($UseColors) { Write-Host "Delegation Ready:" -ForegroundColor Cyan }
384
+ else { Write-Host "Delegation Ready:" }
385
+
386
+ $ReadyProfilesStr = $ReadyProfiles -join ", "
387
+ if ($UseColors) {
388
+ Write-Host " ✓ " -ForegroundColor Yellow -NoNewline
389
+ Write-Host "$ReadyProfilesStr profiles are ready for delegation"
390
+ } else {
391
+ Write-Host " ! $ReadyProfilesStr profiles are ready for delegation"
392
+ }
393
+ Write-Host ""
394
+ } elseif ($DelegationConfigured) {
395
+ if ($UseColors) { Write-Host "Delegation Ready:" -ForegroundColor Cyan }
396
+ else { Write-Host "Delegation Ready:" }
397
+
398
+ if ($UseColors) {
399
+ Write-Host " ! " -ForegroundColor Yellow -NoNewline
400
+ Write-Host "Delegation configured but no valid API keys found"
401
+ } else {
402
+ Write-Host " ! Delegation configured but no valid API keys found"
403
+ }
404
+ Write-Host ""
405
+ }
406
+
315
407
  # Documentation
316
408
  if ($UseColors) {
317
409
  Write-Host "Documentation: https://github.com/kaitranntt/ccs" -ForegroundColor Cyan
@@ -845,11 +937,105 @@ function Get-ProfileType {
845
937
  }
846
938
  }
847
939
 
940
+ # --- Sync Command ---
941
+
942
+ function Sync-Run {
943
+ $CcsClaudeDir = "$env:USERPROFILE\.ccs\.claude"
944
+ $UserClaudeDir = "$env:USERPROFILE\.claude"
945
+
946
+ Write-Host "Syncing delegation commands and skills to ~/.claude/..." -ForegroundColor Cyan
947
+ Write-Host ""
948
+
949
+ # Check if source directory exists
950
+ if (-not (Test-Path $CcsClaudeDir)) {
951
+ Write-Host "[X] CCS .claude/ directory not found at $CcsClaudeDir" -ForegroundColor Red
952
+ Write-Host "Reinstall CCS: npm install -g @kaitranntt/ccs --force"
953
+ exit 1
954
+ }
955
+
956
+ # Create ~/.claude/ if missing
957
+ if (-not (Test-Path $UserClaudeDir)) {
958
+ Write-Host "[i] Creating ~/.claude/ directory" -ForegroundColor Cyan
959
+ New-Item -ItemType Directory -Path $UserClaudeDir -Force | Out-Null
960
+ }
961
+
962
+ # Items to symlink
963
+ $Items = @(
964
+ @{ Source = "commands\ccs"; Target = "commands\ccs"; Type = "Directory" }
965
+ @{ Source = "skills\ccs-delegation"; Target = "skills\ccs-delegation"; Type = "Directory" }
966
+ @{ Source = "agents\ccs-delegator.md"; Target = "agents\ccs-delegator.md"; Type = "File" }
967
+ )
968
+
969
+ $Installed = 0
970
+ $Skipped = 0
971
+
972
+ foreach ($Item in $Items) {
973
+ $SourcePath = Join-Path $CcsClaudeDir $Item.Source
974
+ $TargetPath = Join-Path $UserClaudeDir $Item.Target
975
+ $TargetDir = Split-Path -Parent $TargetPath
976
+
977
+ # Check source exists
978
+ if (-not (Test-Path $SourcePath)) {
979
+ Write-Host "[!] Source not found: $($Item.Source), skipping" -ForegroundColor Yellow
980
+ continue
981
+ }
982
+
983
+ # Create parent directory if needed
984
+ if (-not (Test-Path $TargetDir)) {
985
+ New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
986
+ }
987
+
988
+ # Check if already correct symlink
989
+ if (Test-Path $TargetPath) {
990
+ $ItemInfo = Get-Item $TargetPath -Force
991
+ if ($ItemInfo.LinkType -eq "SymbolicLink") {
992
+ $LinkTarget = $ItemInfo.Target
993
+ if ($LinkTarget -eq $SourcePath) {
994
+ $Skipped++
995
+ continue
996
+ }
997
+ }
998
+
999
+ # Backup existing file/directory
1000
+ $Timestamp = Get-Date -Format "yyyy-MM-dd"
1001
+ $BackupPath = "$TargetPath.backup-$Timestamp"
1002
+ $Counter = 1
1003
+
1004
+ while (Test-Path $BackupPath) {
1005
+ $BackupPath = "$TargetPath.backup-$Timestamp-$Counter"
1006
+ $Counter++
1007
+ }
1008
+
1009
+ Move-Item -Path $TargetPath -Destination $BackupPath -Force
1010
+ Write-Host "[i] Backed up existing to $(Split-Path -Leaf $BackupPath)" -ForegroundColor Cyan
1011
+ }
1012
+
1013
+ # Create symlink
1014
+ try {
1015
+ $SymlinkType = if ($Item.Type -eq "Directory") { "Junction" } else { "SymbolicLink" }
1016
+ New-Item -ItemType $SymlinkType -Path $TargetPath -Target $SourcePath -Force -ErrorAction Stop | Out-Null
1017
+ Write-Host "[OK] Installed $($Item.Target)" -ForegroundColor Green
1018
+ $Installed++
1019
+ } catch {
1020
+ Write-Host "[X] Failed to install $($Item.Target): $($_.Exception.Message)" -ForegroundColor Red
1021
+ if ($_.Exception.Message -match "privilege") {
1022
+ Write-Host "[i] Run PowerShell as Administrator or enable Developer Mode" -ForegroundColor Yellow
1023
+ }
1024
+ }
1025
+ }
1026
+
1027
+ Write-Host ""
1028
+ Write-Host "✓ Update complete" -ForegroundColor Green
1029
+ Write-Host " Installed: $Installed"
1030
+ Write-Host " Already up-to-date: $Skipped"
1031
+ Write-Host ""
1032
+ }
1033
+
848
1034
  # --- Auth Commands (Phase 3) ---
849
1035
 
850
1036
  function Show-AuthHelp {
851
1037
  Write-Host ""
852
- Write-Host "CCS Account Management" -ForegroundColor White
1038
+ Write-Host "CCS Concurrent Account Management" -ForegroundColor White
853
1039
  Write-Host ""
854
1040
  Write-Host "Usage:" -ForegroundColor Cyan
855
1041
  Write-Host " ccs auth <command> [options]" -ForegroundColor Yellow
@@ -1314,7 +1500,7 @@ if ($Help) {
1314
1500
  }
1315
1501
 
1316
1502
  # Special case: shell completion installer
1317
- if ($RemainingArgs.Count -gt 0 -and $RemainingArgs[0] -eq "--shell-completion") {
1503
+ if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "--shell-completion" -or $RemainingArgs[0] -eq "-sc")) {
1318
1504
  $CompletionArgs = if ($RemainingArgs.Count -gt 1) { $RemainingArgs[1..($RemainingArgs.Count-1)] } else { @() }
1319
1505
  $Result = Install-ShellCompletion $CompletionArgs
1320
1506
  exit $Result
@@ -1327,6 +1513,12 @@ if ($RemainingArgs.Count -gt 0 -and $RemainingArgs[0] -eq "auth") {
1327
1513
  exit $LASTEXITCODE
1328
1514
  }
1329
1515
 
1516
+ # Special case: sync command
1517
+ if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "sync" -or $RemainingArgs[0] -eq "--sync")) {
1518
+ Sync-Run
1519
+ exit 0
1520
+ }
1521
+
1330
1522
  # Run auto-recovery before main logic
1331
1523
  if (-not (Invoke-AutoRecovery)) {
1332
1524
  Write-ErrorMsg "Auto-recovery failed. Check permissions."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaitranntt/ccs",
3
- "version": "4.1.4",
3
+ "version": "4.1.5",
4
4
  "description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6",
5
5
  "keywords": [
6
6
  "cli",
@@ -18,8 +18,8 @@ _ccs_completion() {
18
18
 
19
19
  # Top-level completion (first argument)
20
20
  if [[ ${COMP_CWORD} -eq 1 ]]; then
21
- local commands="auth doctor"
22
- local flags="--help --version --shell-completion -h -v"
21
+ local commands="auth doctor sync"
22
+ local flags="--help --version --shell-completion -h -v -sc"
23
23
  local profiles=""
24
24
 
25
25
  # Add profiles from config.json (settings-based profiles)
@@ -70,29 +70,30 @@ complete -c ccs -f
70
70
  # Top-level flags
71
71
  complete -c ccs -s h -l help -d 'Show help message'
72
72
  complete -c ccs -s v -l version -d 'Show version information'
73
- complete -c ccs -l shell-completion -d 'Install shell completion'
73
+ complete -c ccs -s sc -l shell-completion -d 'Install shell completion'
74
74
 
75
75
  # Top-level commands (blue color for commands)
76
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'auth' -d (set_color blue)'Manage multiple Claude accounts'(set_color normal)
77
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'doctor' -d (set_color blue)'Run health check and diagnostics'(set_color normal)
76
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'auth' -d (set_color blue)'Manage multiple Claude accounts'(set_color normal)
77
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'doctor' -d (set_color blue)'Run health check and diagnostics'(set_color normal)
78
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'sync' -d (set_color blue)'Sync delegation commands and skills'(set_color normal)
78
79
 
79
80
  # Top-level known settings profiles (green color for model profiles)
80
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'default' -d (set_color green)'Default Claude Sonnet 4.5'(set_color normal)
81
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'glm' -d (set_color green)'GLM-4.6 (cost-optimized)'(set_color normal)
82
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'glmt' -d (set_color green)'GLM-4.6 with thinking mode'(set_color normal)
83
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'kimi' -d (set_color green)'Kimi for Coding (long-context)'(set_color normal)
81
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'default' -d (set_color green)'Default Claude Sonnet 4.5'(set_color normal)
82
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'glm' -d (set_color green)'GLM-4.6 (cost-optimized)'(set_color normal)
83
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'glmt' -d (set_color green)'GLM-4.6 with thinking mode'(set_color normal)
84
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a 'kimi' -d (set_color green)'Kimi for Coding (long-context)'(set_color normal)
84
85
 
85
86
  # Top-level custom settings profiles (dynamic, with generic description in green)
86
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a '(__fish_ccs_get_custom_settings_profiles)' -d (set_color green)'Settings-based profile'(set_color normal)
87
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a '(__fish_ccs_get_custom_settings_profiles)' -d (set_color green)'Settings-based profile'(set_color normal)
87
88
 
88
89
  # Top-level account profiles (dynamic, yellow color for account profiles)
89
- complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a '(__fish_ccs_get_account_profiles)' -d (set_color yellow)'Account profile'(set_color normal)
90
+ complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor sync' -a '(__fish_ccs_get_account_profiles)' -d (set_color yellow)'Account profile'(set_color normal)
90
91
 
91
92
  # shell-completion subflags
92
- complete -c ccs -n '__fish_seen_argument -l shell-completion' -l bash -d 'Install for bash'
93
- complete -c ccs -n '__fish_seen_argument -l shell-completion' -l zsh -d 'Install for zsh'
94
- complete -c ccs -n '__fish_seen_argument -l shell-completion' -l fish -d 'Install for fish'
95
- complete -c ccs -n '__fish_seen_argument -l shell-completion' -l powershell -d 'Install for PowerShell'
93
+ complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l bash -d 'Install for bash'
94
+ complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l zsh -d 'Install for zsh'
95
+ complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l fish -d 'Install for fish'
96
+ complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l powershell -d 'Install for PowerShell'
96
97
 
97
98
  # auth subcommands
98
99
  complete -c ccs -n '__fish_ccs_using_auth; and not __fish_seen_subcommand_from create list show remove default' -a 'create' -d 'Create new profile and login'
@@ -12,7 +12,7 @@
12
12
  Register-ArgumentCompleter -CommandName ccs -ScriptBlock {
13
13
  param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
14
14
 
15
- $commands = @('auth', 'doctor', '--help', '--version', '--shell-completion', '-h', '-v')
15
+ $commands = @('auth', 'doctor', 'sync', '--help', '--version', '--shell-completion', '-h', '-v', '-sc')
16
16
  $authCommands = @('create', 'list', 'show', 'remove', 'default', '--help', '-h')
17
17
  $shellCompletionFlags = @('--bash', '--zsh', '--fish', '--powershell')
18
18
  $listFlags = @('--verbose', '--json')
@@ -69,7 +69,7 @@ Register-ArgumentCompleter -CommandName ccs -ScriptBlock {
69
69
  }
70
70
 
71
71
  # shell-completion flag completion
72
- if ($words[1] -eq '--shell-completion') {
72
+ if ($words[1] -eq '--shell-completion' -or $words[1] -eq '-sc') {
73
73
  if ($position -eq 3) {
74
74
  $shellCompletionFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
75
75
  [System.Management.Automation.CompletionResult]::new(
@@ -16,7 +16,7 @@
16
16
  # Color codes: 0;34=blue, 0;32=green, 0;33=yellow, 2;37=dim white
17
17
  # Pattern format: =(#b)(group1)(group2)==color_for_group1=color_for_group2
18
18
  # The leading '=' means no color for whole match, then each '=' assigns to each group
19
- zstyle ':completion:*:*:ccs:*:commands' list-colors '=(#b)(auth|doctor)([[:space:]]#--[[:space:]]#*)==0\;34=2\;37'
19
+ zstyle ':completion:*:*:ccs:*:commands' list-colors '=(#b)(auth|doctor|sync)([[:space:]]#--[[:space:]]#*)==0\;34=2\;37'
20
20
  zstyle ':completion:*:*:ccs:*:model-profiles' list-colors '=(#b)(default|glm|glmt|kimi|[^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;32=2\;37'
21
21
  zstyle ':completion:*:*:ccs:*:account-profiles' list-colors '=(#b)([^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;33=2\;37'
22
22
  zstyle ':completion:*:*:ccs:*' group-name ''
@@ -34,6 +34,7 @@ _ccs() {
34
34
  commands=(
35
35
  'auth:Manage multiple Claude accounts'
36
36
  'doctor:Run health check and diagnostics'
37
+ 'sync:Sync delegation commands and skills'
37
38
  )
38
39
 
39
40
  # Define known settings profiles with descriptions (consistent padding)
@@ -71,7 +72,7 @@ _ccs() {
71
72
  _arguments -C \
72
73
  '(- *)'{-h,--help}'[Show help message]' \
73
74
  '(- *)'{-v,--version}'[Show version information]' \
74
- '(- *)--shell-completion[Install shell completion]' \
75
+ '(- *)'{-sc,--shell-completion}'[Install shell completion]' \
75
76
  '1: :->command' \
76
77
  '*:: :->args'
77
78