#!/usr/bin/env bash set -euo pipefail # Claude Code Commander (ccc) # Repo-local launcher: switch model via ccm.sh and then exec `claude` # This affects only the spawned `claude` process, not your parent shell. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")" && pwd)" CCM_CMD_DEFAULT="$SCRIPT_DIR/ccm.sh" CCM="${CCM_CMD:-$CCM_CMD_DEFAULT}" usage() { cat < [region|variant] [claude-options] ./ccc open [claude-options] ./ccc [claude-options] # Switch account then launch (default model) ./ccc : [claude-options] Examples: ./ccc deepseek # Launch Claude Code with DeepSeek ./ccc open kimi # Launch with OpenRouter (kimi) ./ccc kimi --dangerously-skip-permissions # Pass options to Claude Code ./ccc woohelps # Switch to 'woohelps' account and launch ./ccc claude:work # Switch to 'work' account and use Claude Available models: Official: deepseek, glm, kimi, qwen, seed|doubao, claude, minimax OpenRouter: open Account: | claude: EOF } if [[ ! -f "$CCM" ]]; then echo "ccc error: cannot find ccm CLI at $CCM" >&2 echo "Hint: ensure ccm.sh exists next to this script, or set CCM_CMD=/path/to/ccm.sh" >&2 exit 1 fi if [[ $# -lt 1 ]]; then usage exit 1 fi model="" open_provider="" region_arg="" seed_variant="" if [[ $# -lt 1 ]]; then usage exit 1 fi if [[ "${1:-}" == "open" ]]; then shift || true if [[ $# -lt 1 ]]; then usage exit 1 fi model="open" open_provider="$1" shift || true else model="$1" shift || true fi # Helper: is known model keyword is_known_model() { case "$1" in deepseek|ds|glm|glm4|glm4.6|glm4.7|kimi|kimi2|qwen|minimax|mm|seed|doubao|claude|sonnet|s|open) return 0 ;; *) return 1 ;; esac } # Account-only mode: `ccc ` (not open, not known model, no colon) if [[ "$model" != "open" ]] && [[ "$model" != *:* ]] && ! is_known_model "$model" && [[ ! "$model" =~ ^- ]]; then account="$model" # 1) Switch account directly (no eval) if ! "$CCM" switch-account "$account"; then echo "❌ Failed to switch account: $account" >&2 exit 1 fi # Show current account summary (non-fatal if it fails) "$CCM" current-account || true # 2) Optionally set default model environment (Claude Sonnet) eval "$("$CCM" claude)" else # Configure environment for this process using repo-local ccm if [[ "$model" == "open" ]]; then eval "$("$CCM" open "$open_provider")" else case "$model" in kimi|kimi2|qwen|glm|glm4|glm4.6|glm4.7|minimax|mm) if [[ "${1:-}" =~ ^(global|china|cn)$ ]]; then region_arg="$1" shift || true fi ;; seed|doubao) if [[ "${1:-}" =~ ^(doubao|glm|glm4|glm4.7|deepseek|ds|kimi|kimi2)$ ]]; then seed_variant="$1" shift || true fi ;; esac if [[ -n "$seed_variant" ]]; then eval "$("$CCM" "$model" "$seed_variant")" elif [[ -n "$region_arg" ]]; then eval "$("$CCM" "$model" "$region_arg")" else eval "$("$CCM" "$model")" fi fi fi # Remaining args are passed through to `claude` claude_args=("$@") # Friendly status echo "" echo "🚀 Launching Claude Code..." echo " Model: ${ANTHROPIC_MODEL:-'(unset)'}" echo " Base URL: ${ANTHROPIC_BASE_URL:-'Default (Anthropic)'}" # Ensure `claude` is available if ! command -v claude >/dev/null 2>&1; then echo "❌ 'claude' CLI not found. Install it first: npm install -g @anthropic-ai/claude-code" >&2 exit 127 fi # Exec into Claude Code with the configured environment if [[ ${#claude_args[@]} -eq 0 ]]; then exec claude else exec claude "${claude_args[@]}" fi