- Streamline Features section (65% shorter, bullet points only) - Remove redundant 'Why CCS' table column - Fix 'Sub-Account' → 'Multiple Accounts' terminology - Update tagline to highlight v3.0 multi-account capabilities - Merge duplicate sections (Concurrent Sessions) - Remove unrealistic usage examples - Fix weird formatting and stray content - Streamline Uninstall section with package managers grouped - Create root-level CONTRIBUTING.md (GitHub standard) - Remove duplicate docs/en/contributing.md and docs/vi/contributing.vi.md - Update all README links to point to root CONTRIBUTING.md - Refactor CLAUDE.md for v3.0 architecture - Update project overview to highlight multiple Claude accounts - Add v3.0 technical details (CLAUDE_CONFIG_DIR, profiles.json, instances/) - Remove redundant high-level flow (now in README) - Add Node.js code standards - Document two profile types (settings vs account-based) - Update testing requirements for v3.0 Total reduction: 46 lines across all READMEs Cross-language consistency: EN/VI/JA fully synchronized
12 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
CCS (Claude Code Switch) is a lightweight CLI wrapper enabling instant switching between multiple Claude subscription accounts (work, personal, team) and alternative models (GLM 4.6, Kimi for Coding). Built on v3.0 login-per-profile architecture where each profile is an isolated Claude instance.
Primary Installation Methods (highest priority):
- npm Package (recommended):
npm install -g @kaitranntt/ccs(cross-platform) - macOS/Linux:
curl -fsSL ccs.kaitran.ca/install | bash - Windows:
irm ccs.kaitran.ca/install | iex
Core Design Principles
YAGNI (You Aren't Gonna Need It): No features "just in case" KISS (Keep It Simple): Simple bash/PowerShell/Node.js, no complexity DRY (Don't Repeat Yourself): One source of truth (config.json)
The tool does ONE thing: enable instant switching between Claude accounts and alternative models. Never add features that violate these principles.
Key Constraints
- NO EMOJIS in terminal output - Use ASCII symbols ([OK], [!], [X], [i]) for compatibility
- TTY-aware color output - Colors only when output to terminal, respects NO_COLOR env var
- Unified install location (v2.2.0+):
- All Unix:
~/.local/bin(auto PATH config, no sudo) - Windows:
%USERPROFILE%\.ccs
- All Unix:
- Auto PATH configuration - Detects shell (bash/zsh/fish), adds to profile automatically
- Idempotent installations - Running install scripts multiple times must be safe
- Non-invasive - Never modify
~/.claude/settings.json - Cross-platform parity - Identical behavior on Unix/Linux/macOS/Windows
- Edge case handling - Handle all scenarios gracefully (see tests/edge-cases.sh)
Architecture
v3.0 Key Features
Login-Per-Profile Model: Each profile is an isolated Claude instance where users login directly via ccs auth create <profile>. No credential copying, no vault encryption.
Two Profile Types:
- Settings-based (models): GLM, Kimi, default - uses
--settingsflag - Account-based (Claude accounts): work, personal, team - uses
CLAUDE_CONFIG_DIR
Concurrent Sessions: Multiple profiles can run simultaneously in different terminals via isolated config directories.
Implementation Variants
npm package: Pure Node.js (bin/ccs.js) using child_process.spawn Traditional install: Platform-specific bash (lib/ccs) or PowerShell (lib/ccs.ps1)
File Structure
Key Files:
package.json: npm package manifest with bin field configuration and postinstall scriptbin/ccs.js: Cross-platform Node.js entry point (npm package)scripts/postinstall.js: Auto-creates config files during npm install (idempotent)lib/ccs(bash) /lib/ccs.ps1(PowerShell): Platform-specific executable wrappersinstallers/install.sh/installers/install.ps1: Traditional installation scriptsinstallers/uninstall.sh/installers/uninstall.ps1: Removal scriptsVERSION: Single source of truth for version (format: MAJOR.MINOR.PATCH).claude/: Commands and skills for Claude Code integration
Executable Locations:
- macOS / Linux:
~/.local/bin/ccs(symlink to~/.ccs/ccs) - Windows:
%USERPROFILE%\.ccs\ccs.ps1
Configuration Directory:
~/.ccs/
├── ccs # Main executable (or ccs.ps1 on Windows)
├── config.json # Settings-based profile mappings
├── profiles.json # Account-based profile registry (v3.0)
├── instances/ # Isolated Claude instances (v3.0)
│ ├── work/ # Each profile gets own directory
│ ├── personal/
│ └── team/
├── config.json.backup # Single backup (overwrites on each install)
├── glm.settings.json # GLM profile template
├── kimi.settings.json # Kimi profile template
├── VERSION # Version file copy
├── uninstall.sh # Uninstaller (or ccs-uninstall.ps1 on Windows)
└── .claude/ # Claude Code integration
├── commands/ccs.md
└── skills/ccs-delegation/
v3.0 Technical Implementation
Account-Based Profiles (v3.0):
# Create profile (opens Claude CLI for login)
ccs auth create work
# Creates ~/.ccs/instances/work/ with:
# - settings.json (Claude's config)
# - session files
# - todo lists
# - logs
# Usage: Set CLAUDE_CONFIG_DIR before spawning Claude CLI
CLAUDE_CONFIG_DIR=~/.ccs/instances/work claude [args]
Settings-Based Profiles (legacy, still supported):
# Usage: Pass --settings flag to Claude CLI
claude --settings ~/.ccs/glm.settings.json [args]
Profile Detection Logic:
- Check if profile exists in
profiles.json(account-based) - If yes → use
CLAUDE_CONFIG_DIRmethod - If no → check
config.json(settings-based) - If yes → use
--settingsmethod - If no → show error with available profiles
Development Commands
Version Management
# Bump version (updates VERSION, install.sh, install.ps1)
./scripts/bump-version.sh [major|minor|patch]
# Get current version
cat VERSION
# or
./scripts/get-version.sh
Testing
# Comprehensive edge case testing (Unix)
./tests/edge-cases.sh
# Comprehensive edge case testing (Windows)
./tests/edge-cases.ps1
Local Development
# Test local installation from git repo
./installers/install.sh
# Test with local executable
./ccs --version
./ccs glm --help
# Test npm package locally
npm pack # Creates @kaitranntt-ccs-X.Y.Z.tgz
npm install -g @kaitranntt-ccs-X.Y.Z.tgz # Test installation
ccs --version # Verify it works
npm uninstall -g @kaitranntt/ccs # Cleanup
rm @kaitranntt-ccs-X.Y.Z.tgz # Remove tarball
# Clean test environment
rm -rf ~/.ccs
npm Package Publishing
# First-time setup (one-time)
npm login # Login to npm account
npm token create --type=granular --scope=publish # Create token
# Add NPM_TOKEN to GitHub Secrets
# Publishing workflow
./scripts/bump-version.sh patch # Bump version
git add VERSION package.json lib/ccs lib/ccs.ps1 installers/install.sh installers/install.ps1
git commit -m "chore: bump version to X.Y.Z"
git tag vX.Y.Z
git push origin main
git push origin vX.Y.Z # Triggers GitHub Actions publish
# Manual publish (if needed)
npm publish --dry-run # Test before publishing
npm publish --access public # Publish to npm registry
Code Standards
Bash (Unix Systems)
- Compatibility: bash 3.2+ (macOS default)
- Always quote variables:
"$VAR"not$VAR - Use
[[ ]]for tests, not[ ] - Use
#!/usr/bin/env bashshebang - Set
set -euo pipefailfor safety - Dependencies: Only
jqfor JSON parsing
Terminal Output
- TTY Detection: Check
[[ -t 2 ]]before using colors (stderr) - NO_COLOR Support: Respect
${NO_COLOR:-}environment variable - ASCII Symbols Only: [OK], [!], [X], [i] - no emojis
- Error Formatting: Use box borders (╔═╗║╚╝) for critical messages
- Color Codes: RED, YELLOW, GREEN, CYAN, BOLD, RESET - disable when not TTY
PowerShell (Windows)
- Compatibility: PowerShell 5.1+
- Use
$ErrorActionPreference = "Stop" - Native JSON parsing via
ConvertFrom-Json/ConvertTo-Json - No external dependencies required
Node.js (npm package)
- Compatibility: Node.js 14+
- Use
child_process.spawnfor Claude CLI execution - Handle SIGINT/SIGTERM for graceful shutdown
- Cross-platform path handling with
pathmodule
Version Synchronization
When changing version, update ALL three locations:
VERSIONfileinstallers/install.sh(CCS_VERSION variable)installers/install.ps1($CcsVersion variable)
Use ./scripts/bump-version.sh to update all locations atomically.
Critical Implementation Details
Profile Detection Logic
The ccs wrapper uses smart detection:
- No args OR first arg starts with
-→ use default profile - First arg doesn't start with
-→ treat as profile name - Special flags handled BEFORE profile detection:
--version,-v,--help,-h ccs auth create <profile>→ create new account-based profile
Installation Modes
- Git mode: Running from cloned repository (symlinks executables)
- Standalone mode: Running via curl/irm (downloads from GitHub)
Detection: Check if ccs executable exists in script directory or parent.
Idempotency Requirements
Install scripts must be safe to run multiple times:
- Check existing files before creating
- Use single backup file (no timestamps):
config.json.backup - Skip existing
.claude/folder installation - Handle both clean and existing installations
Settings File Format
{
"env": {
"ANTHROPIC_BASE_URL": "https://api.z.ai/api/anthropic",
"ANTHROPIC_AUTH_TOKEN": "your_api_key",
"ANTHROPIC_MODEL": "glm-4.6",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "glm-4.6",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "glm-4.6",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "glm-4.6"
}
}
All values must be strings (not booleans/objects) to prevent PowerShell crashes.
v3.0 Profile Files
profiles.json (account-based profiles):
{
"profiles": {
"work": "~/.ccs/instances/work",
"personal": "~/.ccs/instances/personal",
"team": "~/.ccs/instances/team"
}
}
config.json (settings-based profiles):
{
"profiles": {
"glm": "~/.ccs/glm.settings.json",
"kimi": "~/.ccs/kimi.settings.json",
"default": "~/.claude/settings.json"
}
}
Common Tasks
Adding a New Feature
- Verify it aligns with YAGNI/KISS/DRY principles
- Implement for both bash/PowerShell and Node.js if applicable
- Test on all platforms (macOS, Linux, Windows)
- Update tests in
tests/edge-cases.shandtests/edge-cases.ps1 - Update CONTRIBUTING.md if it affects contributors
Fixing Bugs
- Add test case reproducing the bug
- Fix in both bash/PowerShell and Node.js versions
- Verify fix doesn't break existing tests
- Test on all supported platforms
Releasing New Version
- Run
./scripts/bump-version.sh [major|minor|patch] - Review changes to VERSION, install.sh, install.ps1
- Test installation from both git and standalone modes
- Run full edge case test suite
- Commit and tag:
git tag v<VERSION> - Push to trigger GitHub Actions:
git push origin main && git push origin v<VERSION>
Testing Requirements
Before any PR, verify:
- Works on macOS (bash)
- Works on Linux (bash)
- Works on Windows (PowerShell)
- Works on Windows (Git Bash)
- Handles all edge cases in test suite
- Installation is idempotent
- No emojis in terminal output (ASCII symbols only)
- Version displayed correctly with install location
- Colors work on TTY, disabled when piped
- NO_COLOR environment variable respected
- Auto PATH config works for bash, zsh, fish
- Shell reload instructions shown correctly
- PATH not duplicated on multiple installs
- Manual PATH setup instructions clear if auto fails
- v3.0 concurrent sessions work correctly
- Instance isolation works (no cross-profile contamination)
Integration with Claude Code
The .claude/ folder contains:
/ccscommand: Meta-command for delegating tasks to different modelsccs-delegationskill: Intelligent task delegation patterns
Error Handling Philosophy
- Validate early, fail fast with clear error messages
- Show available options when user makes mistake
- Suggest recovery steps (e.g., restore from backup)
- Never leave system in broken state
- For v3.0 profiles: Guide users through
ccs auth createif profile missing