feat(cli): enhance version and help display formatting (#11)

* feat: add -sc short flag for --shell-completion

Add -sc as a short flag alias for --shell-completion,
matching the pattern of -h for --help and -v for --version.

Changes:
- bin/ccs.js: Add -sc support in help text and flag detection
- lib/ccs: Add -sc support in help text and flag detection
- lib/ccs.ps1: Add -sc support in help text and flag detection

* chore: bump version to 4.1.4

* chore: bump version to 4.1.5

* feat: emphasize concurrent account usage in auth help text

Update all auth-related help messages to emphasize the ability
to run multiple Claude accounts concurrently.

Changes:
- bin/ccs.js: "Run multiple Claude accounts concurrently"
- bin/auth/auth-commands.js: "CCS Concurrent Account Management"
- lib/ccs: Updated both main help and auth_help function
- lib/ccs.ps1: Updated both main help and Show-AuthHelp function

* feat: implement ccs update command across all platforms

Add cross-platform ccs update command to sync delegation commands
and skills from ~/.ccs/.claude/ to ~/.claude/. Replaces vague
"CCS items" wording with specific "delegation commands and skills".

Changes:
- bin/ccs.js: Add update command handler and update help text
- bin/utils/claude-symlink-manager.js: Update user-facing messages
- lib/ccs: Implement update_run() function with symlink logic
- lib/ccs.ps1: Implement Update-Run function with Junction/SymbolicLink support

Features:
- Automatically backs up existing files before symlinking
- Skips items that are already correctly symlinked
- Reports installed vs up-to-date counts
- Handles Windows permissions gracefully (suggests Admin/Developer Mode)

Cross-platform parity: bash, PowerShell, and Node.js now all support ccs update

* refactor: rename ccs update to ccs sync for clarity

Rename the update command to sync across all platforms to avoid
confusion with updating the CCS tool itself. The sync command
clearly communicates syncing delegation features from the CCS
package to ~/.claude/.

Changes:
- bin/ccs.js: Rename handleUpdateCommand → handleSyncCommand
- bin/utils/claude-symlink-manager.js: Rename update() → sync()
- lib/ccs: Rename update_run() → sync_run()
- lib/ccs.ps1: Rename Update-Run → Sync-Run
- All: Update help text "update" → "sync"
- All: Update messages "Updating" → "Syncing"

Command usage: ccs sync or ccs --sync

* fix: update GitHub documentation links to stable permalink

Update broken #usage anchor links to stable /blob/main/README.md
permalink format. This matches the format already used in PowerShell
version and ensures links always work.

Changes:
- bin/ccs.js: Update link from #usage to /blob/main/README.md
- lib/ccs: Update link from #usage to /blob/main/README.md
- Now consistent with lib/ccs.ps1 which already used this format

Old: https://github.com/kaitranntt/ccs#usage
New: https://github.com/kaitranntt/ccs/blob/main/README.md

* feat: add sync command and -sc flag to shell completions

Update all shell completion scripts to include the newly added
sync command and -sc short flag for --shell-completion.

Changes across all completion scripts (bash, zsh, fish, PowerShell):
- Add 'sync' command to completion suggestions
- Add '-sc' as short flag for '--shell-completion'
- Update fish to handle both -sc and --shell-completion for subflags
- Update PowerShell to recognize -sc for shell completion flags
- Add sync command description: "Sync delegation commands and skills"

This ensures tab completion discovers the sync command and users
can use both -sc and --shell-completion interchangeably.

* fix: standardize help text across all implementations

Fix inconsistencies in help text that appeared after merge from main.
Ensures all three implementations (bash, PowerShell, Node.js) display
identical help messages.

Changes:
- lib/ccs: Update "Delegation (Token Optimization)" → "Delegation (inside Claude Code CLI)"
- lib/ccs: Remove redundant /ccs:create line, simplify description
- lib/ccs.ps1: Add missing Delegation section
- All: Now use consistent messaging about delegation features

This ensures users see the same information regardless of which
platform they're using (Linux/macOS bash, Windows PowerShell, or npm).

* fix: update description text to emphasize concurrent sessions

Update outdated description in lib/ccs and lib/ccs.ps1 to match
the improved wording already in bin/ccs.js. The new description
better emphasizes running concurrent Claude CLI sessions.

Changes:
- lib/ccs: Update description to emphasize "Run different Claude CLI sessions concurrently"
- lib/ccs.ps1: Update description to match bash and Node.js versions
- Remove "(work, personal, team)" examples to keep description cleaner
- Emphasize "Run different Claude CLI sessions concurrently" over vague "Concurrent sessions"

Old: "Switch between multiple Claude accounts (work, personal, team) and
      alternative models (GLM, Kimi) instantly. Concurrent sessions with
      auto-recovery. Zero downtime."

New: "Switch between multiple Claude accounts and alternative models
      (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently
      with auto-recovery. Zero downtime."

All three implementations now show identical, clearer description text.

* feat(cli): enhance version display formatting and delegation status

---------
This commit is contained in:
Kai (Tam Nhu) Tran
2025-11-18 01:19:28 -05:00
committed by kaitranntt
parent 2671b97039
commit fe4ff882b0
13 changed files with 516 additions and 149 deletions
+1 -1
View File
@@ -1 +1 @@
4.1.4
4.1.5
+1 -1
View File
@@ -29,7 +29,7 @@ class AuthCommands {
* Show help for auth commands
*/
showHelp() {
console.log(colored('CCS Account Management', 'bold'));
console.log(colored('CCS Concurrent Account Management', 'bold'));
console.log('');
console.log(colored('Usage:', 'cyan'));
console.log(` ${colored('ccs auth', 'yellow')} <command> [options]`);
+58 -34
View File
@@ -63,45 +63,69 @@ function handleVersionCommand() {
console.log(colored(`CCS (Claude Code Switch) v${CCS_VERSION}`, 'bold'));
console.log('');
// Installation section
// Installation section with table-like formatting
console.log(colored('Installation:', 'cyan'));
// Location
const installLocation = process.argv[1] || '(not found)';
console.log(` ${colored('Location:', 'cyan')} ${installLocation}`);
console.log(` ${colored('Location:'.padEnd(17), 'cyan')} ${installLocation}`);
// .ccs/ directory location
const ccsDir = path.join(os.homedir(), '.ccs');
console.log(` ${colored('CCS Directory:'.padEnd(17), 'cyan')} ${ccsDir}`);
// Config path
const configPath = getConfigPath();
console.log(` ${colored('Config:', 'cyan')} ${configPath}`);
console.log(` ${colored('Config:'.padEnd(17), 'cyan')} ${configPath}`);
// Delegation status
const delegationRulesPath = path.join(os.homedir(), '.ccs', 'delegation-rules.json');
const delegationEnabled = fs.existsSync(delegationRulesPath);
// Profiles.json location
const profilesJson = path.join(os.homedir(), '.ccs', 'profiles.json');
console.log(` ${colored('Profiles:'.padEnd(17), 'cyan')} ${profilesJson}`);
if (delegationEnabled) {
console.log(` ${colored('Delegation:', 'cyan')} Enabled`);
// Delegation status - check multiple indicators
const delegationSessionsPath = path.join(os.homedir(), '.ccs', 'delegation-sessions.json');
const delegationConfigured = fs.existsSync(delegationSessionsPath);
// Check which profiles are delegation-ready
const readyProfiles = [];
const { DelegationValidator } = require('./utils/delegation-validator');
let readyProfiles = [];
for (const profile of ['glm', 'kimi']) {
const validation = DelegationValidator.validate(profile);
if (validation.valid) {
readyProfiles.push(profile);
// Check for profiles with valid API keys
for (const profile of ['glm', 'kimi']) {
const settingsPath = path.join(os.homedir(), '.ccs', `${profile}.settings.json`);
if (fs.existsSync(settingsPath)) {
try {
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
const apiKey = settings.env?.ANTHROPIC_AUTH_TOKEN;
if (apiKey && !apiKey.match(/YOUR_.*_API_KEY_HERE/) && !apiKey.match(/sk-test.*/)) {
readyProfiles.push(profile);
}
} catch (error) {
// Invalid JSON, skip
}
}
if (readyProfiles.length > 0) {
console.log(` ${colored('Ready:', 'cyan')} ${readyProfiles.join(', ')}`);
} else {
console.log(` ${colored('Ready:', 'cyan')} None (configure profiles first)`);
}
} else {
console.log(` ${colored('Delegation:', 'cyan')} Not configured`);
}
const hasValidApiKeys = readyProfiles.length > 0;
const delegationEnabled = delegationConfigured || hasValidApiKeys;
if (delegationEnabled) {
console.log(` ${colored('Delegation:'.padEnd(17), 'cyan')} Enabled`);
} else {
console.log(` ${colored('Delegation:'.padEnd(17), 'cyan')} Not configured`);
}
console.log('');
// Ready Profiles section - make it more prominent
if (readyProfiles.length > 0) {
console.log(colored('Delegation Ready:', 'cyan'));
console.log(` ${colored('✓', 'yellow')} ${readyProfiles.join(', ')} profiles are ready for delegation`);
console.log('');
} else if (delegationEnabled) {
console.log(colored('Delegation Ready:', 'cyan'));
console.log(` ${colored('!', 'yellow')} Delegation configured but no valid API keys found`);
console.log('');
}
// Documentation
console.log(`${colored('Documentation:', 'cyan')} https://github.com/kaitranntt/ccs`);
console.log(`${colored('License:', 'cyan')} MIT`);
@@ -143,7 +167,7 @@ function handleHelpCommand() {
// Account Management
console.log(colored('Account Management:', 'cyan'));
console.log(` ${colored('ccs auth --help', 'yellow')} Manage multiple Claude accounts`);
console.log(` ${colored('ccs auth --help', 'yellow')} Run multiple Claude accounts concurrently`);
console.log('');
// Delegation (inside Claude Code CLI)
@@ -156,14 +180,14 @@ function handleHelpCommand() {
// Diagnostics
console.log(colored('Diagnostics:', 'cyan'));
console.log(` ${colored('ccs doctor', 'yellow')} Run health check and diagnostics`);
console.log(` ${colored('ccs update', 'yellow')} Re-install CCS items to ~/.claude/`);
console.log(` ${colored('ccs sync', 'yellow')} Sync delegation commands and skills`);
console.log('');
// Flags
console.log(colored('Flags:', 'cyan'));
console.log(` ${colored('-h, --help', 'yellow')} Show this help message`);
console.log(` ${colored('-v, --version', 'yellow')} Show version and installation info`);
console.log(` ${colored('--shell-completion', 'yellow')} Install shell auto-completion`);
console.log(` ${colored('-sc, --shell-completion', 'yellow')} Install shell auto-completion`);
console.log('');
// Configuration
@@ -188,7 +212,7 @@ function handleHelpCommand() {
console.log(` ${colored('$ ccs', 'yellow')} # Use default account`);
console.log(` ${colored('$ ccs glm "implement API"', 'yellow')} # Cost-optimized model`);
console.log('');
console.log(` For more: ${colored('https://github.com/kaitranntt/ccs#usage', 'cyan')}`);
console.log(` For more: ${colored('https://github.com/kaitranntt/ccs/blob/main/README.md', 'cyan')}`);
console.log('');
// Uninstall
@@ -245,7 +269,7 @@ async function handleDoctorCommand() {
process.exit(doctor.results.isHealthy() ? 0 : 1);
}
async function handleUpdateCommand() {
async function handleSyncCommand() {
// First, copy .claude/ directory from package to ~/.ccs/.claude/
const ClaudeDirInstaller = require('./utils/claude-dir-installer');
const installer = new ClaudeDirInstaller();
@@ -255,8 +279,8 @@ async function handleUpdateCommand() {
const ClaudeSymlinkManager = require('./utils/claude-symlink-manager');
const manager = new ClaudeSymlinkManager();
console.log('[i] Updating CCS items in ~/.claude/...');
manager.update();
console.log('[i] Syncing delegation commands and skills to ~/.claude/...');
manager.sync();
process.exit(0);
}
@@ -487,7 +511,7 @@ async function main() {
}
// Special case: shell completion installer
if (firstArg === '--shell-completion') {
if (firstArg === '--shell-completion' || firstArg === '-sc') {
await handleShellCompletionCommand(args.slice(1));
return;
}
@@ -498,9 +522,9 @@ async function main() {
return;
}
// Special case: update command (re-install CCS symlinks)
if (firstArg === 'update' || firstArg === '--update') {
await handleUpdateCommand();
// Special case: sync command (sync delegation commands and skills to ~/.claude/)
if (firstArg === 'sync' || firstArg === '--sync') {
await handleSyncCommand();
return;
}
+7 -7
View File
@@ -53,7 +53,7 @@ class ClaudeSymlinkManager {
this._installItem(item);
}
console.log('[OK] CCS items installed to ~/.claude/');
console.log('[OK] Delegation commands and skills installed to ~/.claude/');
}
/**
@@ -178,9 +178,9 @@ class ClaudeSymlinkManager {
}
if (removed > 0) {
console.log(`[OK] Removed ${removed} CCS items from ~/.claude/`);
console.log(`[OK] Removed ${removed} delegation commands and skills from ~/.claude/`);
} else {
console.log('[i] No CCS items to remove');
console.log('[i] No delegation commands or skills to remove');
}
}
@@ -226,11 +226,11 @@ class ClaudeSymlinkManager {
}
/**
* Re-install symlinks (used by 'ccs update' command)
* Same as install() but with explicit re-installation message
* Sync delegation commands and skills to ~/.claude/ (used by 'ccs sync' command)
* Same as install() but with explicit sync message
*/
update() {
console.log('[i] Updating CCS items in ~/.claude/...');
sync() {
console.log('[i] Syncing delegation commands and skills to ~/.claude/...');
this.install();
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ $InstallMethod = if ($ScriptDir -and ((Test-Path "$ScriptDir\lib\ccs.ps1") -or (
# IMPORTANT: Update this version when releasing new versions!
# This hardcoded version is used for standalone installations (irm | iex)
# For git installations, VERSION file is read if available
$CcsVersion = "4.1.4"
$CcsVersion = "4.1.5"
# Try to read VERSION file for git installations
if ($ScriptDir) {
+1 -1
View File
@@ -32,7 +32,7 @@ fi
# IMPORTANT: Update this version when releasing new versions!
# This hardcoded version is used for standalone installations (curl | bash)
# For git installations, VERSION file is read if available
CCS_VERSION="4.1.4"
CCS_VERSION="4.1.5"
# Try to read VERSION file for git installations
if [[ -f "$SCRIPT_DIR/VERSION" ]]; then
+196 -47
View File
@@ -2,7 +2,7 @@
set -euo pipefail
# Version (updated by scripts/bump-version.sh)
CCS_VERSION="4.1.4"
CCS_VERSION="4.1.5"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly CONFIG_FILE="${CCS_CONFIG:-$HOME/.ccs/config.json}"
readonly PROFILES_JSON="$HOME/.ccs/profiles.json"
@@ -165,65 +165,82 @@ find_similar_strings() {
show_help() {
echo -e "${BOLD}CCS (Claude Code Switch) - Instant profile switching for Claude CLI${RESET}"
echo ""
echo -e "${CYAN}Usage:${RESET}"
echo -e " ${YELLOW}ccs${RESET} [profile] [claude-args...]"
echo -e " ${YELLOW}ccs auth${RESET} <command> [options]"
echo -e " ${YELLOW}ccs${RESET} [flags]"
echo ""
echo -e "${CYAN}Description:${RESET}"
echo -e " Switch between multiple Claude accounts and alternative models"
echo -e " (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently"
echo -e " with auto-recovery. Zero downtime."
echo ""
echo -e "${CYAN}Model Switching:${RESET}"
echo -e " ${YELLOW}ccs${RESET} Use default Claude account"
echo -e " ${YELLOW}ccs glm${RESET} Switch to GLM 4.6 model"
echo -e " ${YELLOW}ccs glmt${RESET} Switch to GLM with thinking mode"
echo -e " ${YELLOW}ccs glmt --verbose${RESET} Enable debug logging"
echo -e " ${YELLOW}ccs kimi${RESET} Switch to Kimi for Coding"
echo -e " ${YELLOW}ccs glm${RESET} \"debug this code\" Use GLM and run command"
echo ""
echo -e "${CYAN}Account Management:${RESET}"
echo -e " ${YELLOW}ccs auth --help${RESET} Manage multiple Claude accounts"
echo -e " ${YELLOW}ccs auth --help${RESET} Run multiple Claude accounts concurrently"
echo ""
echo -e "${CYAN}Delegation (inside Claude Code CLI):${RESET}"
echo -e " ${YELLOW}/ccs:glm \"task\"${RESET} Delegate to GLM-4.6 for simple tasks"
echo -e " ${YELLOW}/ccs:kimi \"task\"${RESET} Delegate to Kimi for long context"
echo -e " Save tokens by delegating simple tasks to cost-optimized models"
echo ""
echo -e "${CYAN}Diagnostics:${RESET}"
echo -e " ${YELLOW}ccs doctor${RESET} Run health check and diagnostics"
echo -e " ${YELLOW}ccs sync${RESET} Sync delegation commands and skills"
echo ""
echo -e "${CYAN}Flags:${RESET}"
echo -e " ${YELLOW}-h, --help${RESET} Show this help message"
echo -e " ${YELLOW}-v, --version${RESET} Show version and installation info"
echo -e " ${YELLOW}--shell-completion${RESET} Install shell auto-completion"
echo -e " ${YELLOW}-sc, --shell-completion${RESET} Install shell auto-completion"
echo ""
echo -e "${CYAN}Configuration:${RESET}"
echo -e " Config: ~/.ccs/config.json"
echo -e " Profiles: ~/.ccs/profiles.json"
echo -e " Instances: ~/.ccs/instances/"
echo -e " Settings: ~/.ccs/*.settings.json"
echo -e " Config File: ~/.ccs/config.json"
echo -e " Profiles: ~/.ccs/profiles.json"
echo -e " Instances: ~/.ccs/instances/"
echo -e " Settings: ~/.ccs/*.settings.json"
echo -e " Environment: CCS_CONFIG (override config path)"
echo ""
echo -e "${CYAN}Shared Data:${RESET}"
echo -e " Commands: ~/.ccs/shared/commands/"
echo -e " Skills: ~/.ccs/shared/skills/"
echo -e " Commands: ~/.ccs/shared/commands/"
echo -e " Skills: ~/.ccs/shared/skills/"
echo -e " Agents: ~/.ccs/shared/agents/"
echo -e " Note: Commands, skills, and agents are symlinked across all profiles"
echo ""
echo -e "${CYAN}Examples:${RESET}"
echo -e " ${YELLOW}\$ ccs${RESET} # Use default account"
echo -e " ${YELLOW}\$ ccs glm \"implement API\"${RESET} # Cost-optimized model"
echo ""
echo -e " For more: ${CYAN}https://github.com/kaitranntt/ccs#usage${RESET}"
echo -e " For more: ${CYAN}https://github.com/kaitranntt/ccs/blob/main/README.md${RESET}"
echo ""
echo -e "${YELLOW}Uninstall:${RESET}"
echo " npm: npm uninstall -g @kaitranntt/ccs"
echo " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
echo " Windows: irm ccs.kaitran.ca/uninstall | iex"
echo -e " npm: npm uninstall -g @kaitranntt/ccs"
echo -e " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
echo -e " Windows: irm ccs.kaitran.ca/uninstall | iex"
echo ""
echo -e "${CYAN}Documentation:${RESET}"
echo -e " GitHub: ${CYAN}https://github.com/kaitranntt/ccs${RESET}"
echo -e " Docs: https://github.com/kaitranntt/ccs/blob/main/README.md"
echo -e " Issues: https://github.com/kaitranntt/ccs/issues"
echo ""
echo -e "${CYAN}License:${RESET} MIT"
}
@@ -480,6 +497,100 @@ doctor_run() {
$has_errors && exit 1 || exit 0
}
# --- Sync Command ---
sync_run() {
local ccs_claude_dir="$HOME/.ccs/.claude"
local user_claude_dir="$HOME/.claude"
echo -e "${CYAN}Syncing delegation commands and skills to ~/.claude/...${RESET}"
echo ""
# Check if source directory exists
if [[ ! -d "$ccs_claude_dir" ]]; then
msg_error "CCS .claude/ directory not found at $ccs_claude_dir"
echo "Reinstall CCS: npm install -g @kaitranntt/ccs --force"
exit 1
fi
# Create ~/.claude/ if missing
if [[ ! -d "$user_claude_dir" ]]; then
echo -e "${CYAN}[i]${RESET} Creating ~/.claude/ directory"
mkdir -p "$user_claude_dir"
chmod 700 "$user_claude_dir"
fi
# Items to symlink (source:target:type)
local items=(
"commands/ccs:commands/ccs:dir"
"skills/ccs-delegation:skills/ccs-delegation:dir"
"agents/ccs-delegator.md:agents/ccs-delegator.md:file"
)
local installed=0
local skipped=0
for item in "${items[@]}"; do
IFS=':' read -r source target type <<< "$item"
local source_path="$ccs_claude_dir/$source"
local target_path="$user_claude_dir/$target"
local target_dir="$(dirname "$target_path")"
# Check source exists
if [[ ! -e "$source_path" ]]; then
echo -e "${YELLOW}[!]${RESET} Source not found: $source, skipping"
continue
fi
# Create parent directory if needed
if [[ ! -d "$target_dir" ]]; then
mkdir -p "$target_dir"
chmod 700 "$target_dir"
fi
# Check if already correct symlink
if [[ -L "$target_path" ]]; then
local link_target="$(readlink "$target_path")"
local resolved_target="$(cd "$(dirname "$target_path")" && cd "$(dirname "$link_target")" && pwd)/$(basename "$link_target")"
if [[ "$resolved_target" == "$source_path" ]]; then
((skipped++))
continue
fi
fi
# Backup existing file/directory
if [[ -e "$target_path" ]]; then
local timestamp="$(date +%Y-%m-%d)"
local backup_path="${target_path}.backup-${timestamp}"
local counter=1
while [[ -e "$backup_path" ]]; do
backup_path="${target_path}.backup-${timestamp}-${counter}"
((counter++))
done
mv "$target_path" "$backup_path"
echo -e "${CYAN}[i]${RESET} Backed up existing to $(basename "$backup_path")"
fi
# Create symlink
ln -s "$source_path" "$target_path" 2>/dev/null
if [[ $? -eq 0 ]]; then
echo -e "${GREEN}[OK]${RESET} Installed $target"
((installed++))
else
echo -e "${RED}[X]${RESET} Failed to install $target"
fi
done
echo ""
echo -e "${GREEN}✓ Update complete${RESET}"
echo " Installed: $installed"
echo " Already up-to-date: $skipped"
echo ""
}
# --- Claude CLI Detection Logic ---
detect_claude_cli() {
@@ -509,49 +620,81 @@ Restart your terminal after installation."
}
show_version() {
# Title
echo -e "${BOLD}CCS (Claude Code Switch) v${CCS_VERSION}${RESET}"
echo ""
# Installation section with table-like formatting
echo -e "${CYAN}Installation:${RESET}"
# Simple location - just show what 'command -v' returns
local location=$(command -v ccs 2>/dev/null || echo "(not installed)")
echo -e " ${CYAN}Location:${RESET} ${location}"
# Location - prioritize script location over command location
local script_location="$(readlink -f "${BASH_SOURCE[0]}")"
local command_location=$(command -v ccs 2>/dev/null || echo "(not found)")
# Simple config display
local config="${CCS_CONFIG:-$HOME/.ccs/config.json}"
echo -e " ${CYAN}Config:${RESET} ${config}"
# Delegation status
local delegation_rules="$HOME/.ccs/delegation-rules.json"
if [[ -f "$delegation_rules" ]]; then
echo -e " ${CYAN}Delegation:${RESET} Enabled"
# Check which profiles are delegation-ready
local ready_profiles=()
for profile in glm kimi; do
local settings_file="$HOME/.ccs/profiles/$profile/settings.json"
if [[ -f "$settings_file" ]]; then
# Check if API key is configured (not a placeholder)
local api_key=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$settings_file" 2>/dev/null)
if [[ -n "$api_key" ]] && [[ ! "$api_key" =~ YOUR_.*_API_KEY_HERE ]]; then
ready_profiles+=("$profile")
fi
fi
done
if [[ ${#ready_profiles[@]} -gt 0 ]]; then
echo -e " ${CYAN}Ready:${RESET} ${ready_profiles[*]}"
else
echo -e " ${CYAN}Ready:${RESET} None (configure profiles first)"
fi
# Show script location if running from source
if [[ "$script_location" == *"ccs"* ]]; then
printf " ${CYAN}%-16s${RESET} %s\n" "Location:" "${script_location}"
else
echo -e " ${CYAN}Delegation:${RESET} Not configured"
printf " ${CYAN}%-16s${RESET} %s\n" "Location:" "${command_location}"
fi
# .ccs/ directory location
printf " ${CYAN}%-16s${RESET} %s\n" "CCS Directory:" "$HOME/.ccs/"
# Config path
printf " ${CYAN}%-16s${RESET} %s\n" "Config:" "${CONFIG_FILE}"
# Profiles.json location
printf " ${CYAN}%-16s${RESET} %s\n" "Profiles:" "${PROFILES_JSON}"
# Delegation status - check multiple indicators
local delegation_configured=false
local ready_profiles=()
# Check for delegation-sessions.json (primary indicator)
local delegation_sessions="$HOME/.ccs/delegation-sessions.json"
if [[ -f "$delegation_sessions" ]]; then
delegation_configured=true
fi
# Check for profiles with valid API keys (secondary indicator)
for profile in glm kimi; do
local settings_file="$HOME/.ccs/$profile.settings.json"
if [[ -f "$settings_file" ]]; then
# Check if API key is configured (not a placeholder)
local api_key=$(jq -r '.env.ANTHROPIC_AUTH_TOKEN // empty' "$settings_file" 2>/dev/null)
if [[ -n "$api_key" ]] && [[ ! "$api_key" =~ YOUR_.*_API_KEY_HERE ]] && [[ ! "$api_key" =~ sk-test.* ]]; then
ready_profiles+=("$profile")
delegation_configured=true
fi
fi
done
if $delegation_configured; then
printf " ${CYAN}%-16s${RESET} %s\n" "Delegation:" "Enabled"
else
printf " ${CYAN}%-16s${RESET} %s\n" "Delegation:" "Not configured"
fi
echo ""
# Ready Profiles section - make it more prominent
if [[ ${#ready_profiles[@]} -gt 0 ]]; then
echo -e "${CYAN}Delegation Ready:${RESET}"
echo " ${YELLOW}✓${RESET} ${ready_profiles[*]} profiles are ready for delegation"
echo ""
elif $delegation_configured; then
echo -e "${CYAN}Delegation Ready:${RESET}"
echo " ${YELLOW}!${RESET} Delegation configured but no valid API keys found"
echo ""
fi
# Documentation
echo -e "${CYAN}Documentation:${RESET} https://github.com/kaitranntt/ccs"
echo -e "${CYAN}License:${RESET} MIT"
echo ""
# Help hint
echo -e "${YELLOW}Run 'ccs --help' for usage information${RESET}"
}
@@ -957,7 +1100,7 @@ detect_profile_type() {
# --- Auth Commands (Phase 3) ---
auth_help() {
echo -e "${BOLD}CCS Account Management${RESET}"
echo -e "${BOLD}CCS Concurrent Account Management${RESET}"
echo ""
echo -e "${CYAN}Usage:${RESET}"
echo -e " ${YELLOW}ccs auth${RESET} <command> [options]"
@@ -1509,7 +1652,7 @@ if [[ $# -gt 0 ]] && [[ "${1}" == "auth" ]]; then
fi
# Special case: shell completion installer
if [[ $# -gt 0 ]] && [[ "${1}" == "--shell-completion" ]]; then
if [[ $# -gt 0 ]] && [[ "${1}" == "--shell-completion" || "${1}" == "-sc" ]]; then
install_shell_completion "$@"
exit $?
fi
@@ -1520,6 +1663,12 @@ if [[ $# -gt 0 ]] && [[ "${1}" == "doctor" || "${1}" == "--doctor" ]]; then
exit $?
fi
# Special case: sync command
if [[ $# -gt 0 ]] && [[ "${1}" == "sync" || "${1}" == "--sync" ]]; then
sync_run
exit $?
fi
# Run auto-recovery before main logic
auto_recover || {
msg_error "Auto-recovery failed. Check permissions."
+229 -37
View File
@@ -12,7 +12,7 @@ param(
$ErrorActionPreference = "Stop"
# Version (updated by scripts/bump-version.sh)
$CcsVersion = "4.1.4"
$CcsVersion = "4.1.5"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$ConfigFile = if ($env:CCS_CONFIG) { $env:CCS_CONFIG } else { "$env:USERPROFILE\.ccs\config.json" }
$ProfilesJson = "$env:USERPROFILE\.ccs\profiles.json"
@@ -212,66 +212,105 @@ function Show-Help {
Write-ColorLine "CCS (Claude Code Switch) - Instant profile switching for Claude CLI" "White"
Write-Host ""
Write-ColorLine "Usage:" "Cyan"
Write-ColorLine " ccs [profile] [claude-args...]" "Yellow"
Write-ColorLine " ccs auth <command> [options]" "Yellow"
Write-ColorLine " ccs [flags]" "Yellow"
Write-Host ""
Write-ColorLine "Description:" "Cyan"
Write-Host " Switch between multiple Claude accounts and alternative models"
Write-Host " (GLM, Kimi) instantly. Run different Claude CLI sessions concurrently"
Write-Host " with auto-recovery. Zero downtime."
Write-Host ""
Write-ColorLine "Model Switching:" "Cyan"
Write-ColorLine " ccs Use default Claude account" "Yellow"
Write-ColorLine " ccs glm Switch to GLM 4.6 model" "Yellow"
Write-ColorLine " ccs glmt Switch to GLM with thinking mode" "Yellow"
Write-ColorLine " ccs glmt --verbose Enable debug logging" "Yellow"
Write-ColorLine " ccs kimi Switch to Kimi for Coding" "Yellow"
Write-ColorLine " ccs glm 'debug this code' Use GLM and run command" "Yellow"
Write-Host ""
Write-ColorLine "Examples:" "Cyan"
Write-ColorLine " `$ ccs" "Yellow" -NoNewline
Write-Host " # Use default account"
Write-ColorLine " `$ ccs glm `"implement API`"" "Yellow" -NoNewline
Write-Host " # Cost-optimized model"
Write-Host ""
Write-ColorLine "Account Management:" "Cyan"
Write-ColorLine " ccs auth --help Manage multiple Claude accounts" "Yellow"
Write-ColorLine " ccs auth --help Run multiple Claude accounts concurrently" "Yellow"
Write-Host ""
Write-ColorLine "Delegation (inside Claude Code CLI):" "Cyan"
Write-ColorLine " /ccs:glm `"task`" Delegate to GLM-4.6 for simple tasks" "Yellow"
Write-ColorLine " /ccs:kimi `"task`" Delegate to Kimi for long context" "Yellow"
Write-Host " Save tokens by delegating simple tasks to cost-optimized models"
Write-Host ""
Write-ColorLine "Diagnostics:" "Cyan"
Write-ColorLine " ccs doctor Run health check and diagnostics" "Yellow"
Write-ColorLine " ccs sync Sync delegation commands and skills" "Yellow"
Write-Host ""
Write-ColorLine "Flags:" "Cyan"
Write-ColorLine " -h, --help Show this help message" "Yellow"
Write-ColorLine " -v, --version Show version and installation info" "Yellow"
Write-ColorLine " --shell-completion Install shell auto-completion" "Yellow"
Write-ColorLine " -sc, --shell-completion Install shell auto-completion" "Yellow"
Write-Host ""
Write-ColorLine "Configuration:" "Cyan"
Write-Host " Config: ~/.ccs/config.json"
Write-Host " Profiles: ~/.ccs/profiles.json"
Write-Host " Instances: ~/.ccs/instances/"
Write-Host " Settings: ~/.ccs/*.settings.json"
Write-Host " Config File: ~/.ccs/config.json"
Write-Host " Profiles: ~/.ccs/profiles.json"
Write-Host " Instances: ~/.ccs/instances/"
Write-Host " Settings: ~/.ccs/*.settings.json"
Write-Host " Environment: CCS_CONFIG (override config path)"
Write-Host ""
Write-ColorLine "Shared Data:" "Cyan"
Write-Host " Commands: ~/.ccs/shared/commands/"
Write-Host " Skills: ~/.ccs/shared/skills/"
Write-Host " Commands: ~/.ccs/shared/commands/"
Write-Host " Skills: ~/.ccs/shared/skills/"
Write-Host " Agents: ~/.ccs/shared/agents/"
Write-Host " Note: Commands, skills, and agents are symlinked across all profiles"
Write-Host ""
Write-ColorLine "Examples:" "Cyan"
Write-ColorLine " `$ ccs # Use default account" "Yellow"
Write-ColorLine " `$ ccs glm `"implement API`" # Cost-optimized model" "Yellow"
Write-Host ""
Write-ColorLine " For more: https://github.com/kaitranntt/ccs/blob/main/README.md" "Cyan"
Write-Host ""
Write-ColorLine "Uninstall:" "Yellow"
Write-Host " npm: npm uninstall -g @kaitranntt/ccs"
Write-Host " macOS/Linux: curl -fsSL ccs.kaitran.ca/uninstall | bash"
Write-Host " Windows: irm ccs.kaitran.ca/uninstall | iex"
Write-Host ""
Write-ColorLine "Documentation:" "Cyan"
Write-Host " GitHub: https://github.com/kaitranntt/ccs"
Write-Host " Docs: https://github.com/kaitranntt/ccs/blob/main/README.md"
Write-Host " Issues: https://github.com/kaitranntt/ccs/issues"
Write-Host ""
Write-ColorLine "License: MIT" "Cyan"
}
function Show-Version {
$UseColors = $env:FORCE_COLOR -or ([Console]::IsOutputRedirected -eq $false -and -not $env:NO_COLOR)
# Helper for aligned output
function Write-TableLine {
param(
[string]$Label,
[string]$Value,
[string]$Color = "Cyan"
)
if ($UseColors) {
$PaddedLabel = $Label.PadRight(17)
Write-Host " $PaddedLabel " -ForegroundColor $Color -NoNewline
Write-Host $Value
} else {
$PaddedLabel = $Label.PadRight(17)
Write-Host " $PaddedLabel $Value"
}
}
# Title
if ($UseColors) {
Write-Host "CCS (Claude Code Switch) v$CcsVersion" -ForegroundColor White
@@ -280,38 +319,91 @@ function Show-Version {
}
Write-Host ""
# Installation
# Installation section with table-like formatting
if ($UseColors) { Write-Host "Installation:" -ForegroundColor Cyan }
else { Write-Host "Installation:" }
# Location
# Location - prioritize script location over command location
$ScriptLocation = $MyInvocation.MyCommand.Path
$InstallLocation = (Get-Command ccs -ErrorAction SilentlyContinue).Source
if ($InstallLocation) {
if ($UseColors) {
Write-Host " Location: " -ForegroundColor Cyan -NoNewline
Write-Host $InstallLocation
} else {
Write-Host " Location: $InstallLocation"
}
# Show script location if running from source
if ($ScriptLocation -and (Test-Path $ScriptLocation)) {
Write-TableLine "Location:" $ScriptLocation
} elseif ($InstallLocation) {
Write-TableLine "Location:" $InstallLocation
} else {
if ($UseColors) {
Write-Host " Location: " -ForegroundColor Cyan -NoNewline
Write-Host "(not found - run from current directory)" -ForegroundColor Gray
} else {
Write-Host " Location: (not found - run from current directory)"
Write-TableLine "Location:" "(not found - run from current directory)"
}
# .ccs/ directory location
Write-TableLine "CCS Directory:" "$env:USERPROFILE\.ccs\"
# Config path
Write-TableLine "Config:" $ConfigFile
# Profiles.json location
Write-TableLine "Profiles:" $ProfilesJson
# Delegation status - check multiple indicators
$DelegationConfigured = $false
$ReadyProfiles = @()
# Check for delegation-sessions.json (primary indicator)
$DelegationSessions = "$env:USERPROFILE\.ccs\delegation-sessions.json"
if (Test-Path $DelegationSessions) {
$DelegationConfigured = $true
}
# Check for profiles with valid API keys (secondary indicator)
foreach ($profile in @("glm", "kimi")) {
$SettingsFile = "$env:USERPROFILE\.ccs\$profile.settings.json"
if (Test-Path $SettingsFile) {
try {
$Settings = Get-Content $SettingsFile -Raw | ConvertFrom-Json
$ApiKey = $Settings.env.ANTHROPIC_AUTH_TOKEN
if ($ApiKey -and $ApiKey -notmatch "YOUR_.*_API_KEY_HERE" -and $ApiKey -notmatch "sk-test.*") {
$ReadyProfiles += $profile
$DelegationConfigured = $true
}
} catch { }
}
}
# Config
if ($UseColors) {
Write-Host " Config: " -ForegroundColor Cyan -NoNewline
Write-Host $ConfigFile
if ($DelegationConfigured) {
Write-TableLine "Delegation:" "Enabled"
} else {
Write-Host " Config: $ConfigFile"
Write-TableLine "Delegation:" "Not configured"
}
Write-Host ""
# Ready Profiles section - make it more prominent
if ($ReadyProfiles.Count -gt 0) {
if ($UseColors) { Write-Host "Delegation Ready:" -ForegroundColor Cyan }
else { Write-Host "Delegation Ready:" }
$ReadyProfilesStr = $ReadyProfiles -join ", "
if ($UseColors) {
Write-Host "" -ForegroundColor Yellow -NoNewline
Write-Host "$ReadyProfilesStr profiles are ready for delegation"
} else {
Write-Host " ! $ReadyProfilesStr profiles are ready for delegation"
}
Write-Host ""
} elseif ($DelegationConfigured) {
if ($UseColors) { Write-Host "Delegation Ready:" -ForegroundColor Cyan }
else { Write-Host "Delegation Ready:" }
if ($UseColors) {
Write-Host " ! " -ForegroundColor Yellow -NoNewline
Write-Host "Delegation configured but no valid API keys found"
} else {
Write-Host " ! Delegation configured but no valid API keys found"
}
Write-Host ""
}
# Documentation
if ($UseColors) {
Write-Host "Documentation: https://github.com/kaitranntt/ccs" -ForegroundColor Cyan
@@ -845,11 +937,105 @@ function Get-ProfileType {
}
}
# --- Sync Command ---
function Sync-Run {
$CcsClaudeDir = "$env:USERPROFILE\.ccs\.claude"
$UserClaudeDir = "$env:USERPROFILE\.claude"
Write-Host "Syncing delegation commands and skills to ~/.claude/..." -ForegroundColor Cyan
Write-Host ""
# Check if source directory exists
if (-not (Test-Path $CcsClaudeDir)) {
Write-Host "[X] CCS .claude/ directory not found at $CcsClaudeDir" -ForegroundColor Red
Write-Host "Reinstall CCS: npm install -g @kaitranntt/ccs --force"
exit 1
}
# Create ~/.claude/ if missing
if (-not (Test-Path $UserClaudeDir)) {
Write-Host "[i] Creating ~/.claude/ directory" -ForegroundColor Cyan
New-Item -ItemType Directory -Path $UserClaudeDir -Force | Out-Null
}
# Items to symlink
$Items = @(
@{ Source = "commands\ccs"; Target = "commands\ccs"; Type = "Directory" }
@{ Source = "skills\ccs-delegation"; Target = "skills\ccs-delegation"; Type = "Directory" }
@{ Source = "agents\ccs-delegator.md"; Target = "agents\ccs-delegator.md"; Type = "File" }
)
$Installed = 0
$Skipped = 0
foreach ($Item in $Items) {
$SourcePath = Join-Path $CcsClaudeDir $Item.Source
$TargetPath = Join-Path $UserClaudeDir $Item.Target
$TargetDir = Split-Path -Parent $TargetPath
# Check source exists
if (-not (Test-Path $SourcePath)) {
Write-Host "[!] Source not found: $($Item.Source), skipping" -ForegroundColor Yellow
continue
}
# Create parent directory if needed
if (-not (Test-Path $TargetDir)) {
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
}
# Check if already correct symlink
if (Test-Path $TargetPath) {
$ItemInfo = Get-Item $TargetPath -Force
if ($ItemInfo.LinkType -eq "SymbolicLink") {
$LinkTarget = $ItemInfo.Target
if ($LinkTarget -eq $SourcePath) {
$Skipped++
continue
}
}
# Backup existing file/directory
$Timestamp = Get-Date -Format "yyyy-MM-dd"
$BackupPath = "$TargetPath.backup-$Timestamp"
$Counter = 1
while (Test-Path $BackupPath) {
$BackupPath = "$TargetPath.backup-$Timestamp-$Counter"
$Counter++
}
Move-Item -Path $TargetPath -Destination $BackupPath -Force
Write-Host "[i] Backed up existing to $(Split-Path -Leaf $BackupPath)" -ForegroundColor Cyan
}
# Create symlink
try {
$SymlinkType = if ($Item.Type -eq "Directory") { "Junction" } else { "SymbolicLink" }
New-Item -ItemType $SymlinkType -Path $TargetPath -Target $SourcePath -Force -ErrorAction Stop | Out-Null
Write-Host "[OK] Installed $($Item.Target)" -ForegroundColor Green
$Installed++
} catch {
Write-Host "[X] Failed to install $($Item.Target): $($_.Exception.Message)" -ForegroundColor Red
if ($_.Exception.Message -match "privilege") {
Write-Host "[i] Run PowerShell as Administrator or enable Developer Mode" -ForegroundColor Yellow
}
}
}
Write-Host ""
Write-Host "✓ Update complete" -ForegroundColor Green
Write-Host " Installed: $Installed"
Write-Host " Already up-to-date: $Skipped"
Write-Host ""
}
# --- Auth Commands (Phase 3) ---
function Show-AuthHelp {
Write-Host ""
Write-Host "CCS Account Management" -ForegroundColor White
Write-Host "CCS Concurrent Account Management" -ForegroundColor White
Write-Host ""
Write-Host "Usage:" -ForegroundColor Cyan
Write-Host " ccs auth <command> [options]" -ForegroundColor Yellow
@@ -1314,7 +1500,7 @@ if ($Help) {
}
# Special case: shell completion installer
if ($RemainingArgs.Count -gt 0 -and $RemainingArgs[0] -eq "--shell-completion") {
if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "--shell-completion" -or $RemainingArgs[0] -eq "-sc")) {
$CompletionArgs = if ($RemainingArgs.Count -gt 1) { $RemainingArgs[1..($RemainingArgs.Count-1)] } else { @() }
$Result = Install-ShellCompletion $CompletionArgs
exit $Result
@@ -1327,6 +1513,12 @@ if ($RemainingArgs.Count -gt 0 -and $RemainingArgs[0] -eq "auth") {
exit $LASTEXITCODE
}
# Special case: sync command
if ($RemainingArgs.Count -gt 0 -and ($RemainingArgs[0] -eq "sync" -or $RemainingArgs[0] -eq "--sync")) {
Sync-Run
exit 0
}
# Run auto-recovery before main logic
if (-not (Invoke-AutoRecovery)) {
Write-ErrorMsg "Auto-recovery failed. Check permissions."
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@kaitranntt/ccs",
"version": "4.1.4",
"version": "4.1.5",
"description": "Claude Code Switch - Instant profile switching between Claude Sonnet 4.5 and GLM 4.6",
"keywords": [
"cli",
+2 -2
View File
@@ -18,8 +18,8 @@ _ccs_completion() {
# Top-level completion (first argument)
if [[ ${COMP_CWORD} -eq 1 ]]; then
local commands="auth doctor"
local flags="--help --version --shell-completion -h -v"
local commands="auth doctor sync"
local flags="--help --version --shell-completion -h -v -sc"
local profiles=""
# Add profiles from config.json (settings-based profiles)
+14 -13
View File
@@ -70,29 +70,30 @@ complete -c ccs -f
# Top-level flags
complete -c ccs -s h -l help -d 'Show help message'
complete -c ccs -s v -l version -d 'Show version information'
complete -c ccs -l shell-completion -d 'Install shell completion'
complete -c ccs -s sc -l shell-completion -d 'Install shell completion'
# Top-level commands (blue color for commands)
complete -c ccs -n 'not __fish_seen_subcommand_from auth doctor' -a 'auth' -d (set_color blue)'Manage multiple Claude accounts'(set_color normal)
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)
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)
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)
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)
# Top-level known settings profiles (green color for model profiles)
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)
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)
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)
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)
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)
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)
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)
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)
# Top-level custom settings profiles (dynamic, with generic description in green)
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)
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)
# Top-level account profiles (dynamic, yellow color for account profiles)
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)
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)
# shell-completion subflags
complete -c ccs -n '__fish_seen_argument -l shell-completion' -l bash -d 'Install for bash'
complete -c ccs -n '__fish_seen_argument -l shell-completion' -l zsh -d 'Install for zsh'
complete -c ccs -n '__fish_seen_argument -l shell-completion' -l fish -d 'Install for fish'
complete -c ccs -n '__fish_seen_argument -l shell-completion' -l powershell -d 'Install for PowerShell'
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l bash -d 'Install for bash'
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l zsh -d 'Install for zsh'
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l fish -d 'Install for fish'
complete -c ccs -n '__fish_seen_argument -l shell-completion; or __fish_seen_argument -s sc' -l powershell -d 'Install for PowerShell'
# auth subcommands
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'
+2 -2
View File
@@ -12,7 +12,7 @@
Register-ArgumentCompleter -CommandName ccs -ScriptBlock {
param($commandName, $wordToComplete, $commandAst, $fakeBoundParameters)
$commands = @('auth', 'doctor', '--help', '--version', '--shell-completion', '-h', '-v')
$commands = @('auth', 'doctor', 'sync', '--help', '--version', '--shell-completion', '-h', '-v', '-sc')
$authCommands = @('create', 'list', 'show', 'remove', 'default', '--help', '-h')
$shellCompletionFlags = @('--bash', '--zsh', '--fish', '--powershell')
$listFlags = @('--verbose', '--json')
@@ -69,7 +69,7 @@ Register-ArgumentCompleter -CommandName ccs -ScriptBlock {
}
# shell-completion flag completion
if ($words[1] -eq '--shell-completion') {
if ($words[1] -eq '--shell-completion' -or $words[1] -eq '-sc') {
if ($position -eq 3) {
$shellCompletionFlags | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new(
+3 -2
View File
@@ -16,7 +16,7 @@
# Color codes: 0;34=blue, 0;32=green, 0;33=yellow, 2;37=dim white
# Pattern format: =(#b)(group1)(group2)==color_for_group1=color_for_group2
# The leading '=' means no color for whole match, then each '=' assigns to each group
zstyle ':completion:*:*:ccs:*:commands' list-colors '=(#b)(auth|doctor)([[:space:]]#--[[:space:]]#*)==0\;34=2\;37'
zstyle ':completion:*:*:ccs:*:commands' list-colors '=(#b)(auth|doctor|sync)([[:space:]]#--[[:space:]]#*)==0\;34=2\;37'
zstyle ':completion:*:*:ccs:*:model-profiles' list-colors '=(#b)(default|glm|glmt|kimi|[^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;32=2\;37'
zstyle ':completion:*:*:ccs:*:account-profiles' list-colors '=(#b)([^[:space:]]##)([[:space:]]#--[[:space:]]#*)==0\;33=2\;37'
zstyle ':completion:*:*:ccs:*' group-name ''
@@ -34,6 +34,7 @@ _ccs() {
commands=(
'auth:Manage multiple Claude accounts'
'doctor:Run health check and diagnostics'
'sync:Sync delegation commands and skills'
)
# Define known settings profiles with descriptions (consistent padding)
@@ -71,7 +72,7 @@ _ccs() {
_arguments -C \
'(- *)'{-h,--help}'[Show help message]' \
'(- *)'{-v,--version}'[Show version information]' \
'(- *)--shell-completion[Install shell completion]' \
'(- *)'{-sc,--shell-completion}'[Install shell completion]' \
'1: :->command' \
'*:: :->args'