1use clap::{Parser, Subcommand};
2
3#[derive(Parser)]
5#[command(name = "cc-switch")]
6#[command(about = "A CLI tool for managing Claude API configurations")]
7#[command(version)]
8#[command(disable_help_subcommand = true)]
9#[command(
10 long_about = "cc-switch helps you manage multiple Claude API configurations and switch between them easily.
11
12EXAMPLES:
13 cc-switch add my-config sk-ant-xxx https://api.anthropic.com
14 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com
15 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com -m claude-3-5-sonnet-20241022
16 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com --small-fast-model claude-3-haiku-20240307
17 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com --max-thinking-tokens 8192
18 cc-switch add my-config -i # Interactive mode
19 cc-switch add my-config --force # Overwrite existing config
20 cc-switch list
21 cc-switch remove config1 config2 config3
22 cc-switch current # Interactive mode to view and switch configurations
23 cc-switch # Enter interactive mode (same as 'current' without arguments)
24
25SHELL COMPLETION AND ALIASES:
26 cc-switch completion fish # Generates shell completions
27 cc-switch alias fish # Generates aliases for eval
28
29 These aliases are available:
30 - cs='cc-switch' # Quick access to cc-switch
31 - ccd='claude --dangerously-skip-permissions' # Quick Claude launch
32
33 To use aliases immediately:
34 eval \"$(cc-switch alias fish)\" # Add aliases to current session
35
36 Or add them permanently:
37 cc-switch completion fish > ~/.config/fish/completions/cc-switch.fish
38 echo \"alias cs='cc-switch'\" >> ~/.config/fish/config.fish
39 echo \"alias ccd='claude --dangerously-skip-permissions'\" >> ~/.config/fish/config.fish
40
41 Then use:
42 cs current # Instead of cc-switch current
43 ccd # Quick Claude launch"
44)]
45pub struct Cli {
46 #[command(subcommand)]
47 pub command: Option<Commands>,
48
49 #[arg(long = "list-aliases", hide = true)]
51 pub list_aliases: bool,
52
53 #[arg(
55 long = "migrate",
56 help = "Migrate old config path to new path and exit"
57 )]
58 pub migrate: bool,
59
60 #[arg(
62 long = "store",
63 help = "Storage mode for writing configuration (env: write to env field, config: write to root with camelCase)",
64 global = true
65 )]
66 pub store: Option<String>,
67}
68
69#[derive(Subcommand)]
71#[allow(clippy::large_enum_variant)]
72pub enum Commands {
73 Add {
77 #[arg(
79 help = "Configuration alias name (cannot be 'cc')",
80 required_unless_present = "from_file"
81 )]
82 alias_name: Option<String>,
83
84 #[arg(
86 long = "token",
87 short = 't',
88 help = "API token (optional if not using interactive mode)"
89 )]
90 token: Option<String>,
91
92 #[arg(
94 long = "url",
95 short = 'u',
96 help = "API endpoint URL (optional if not using interactive mode)"
97 )]
98 url: Option<String>,
99
100 #[arg(long = "model", short = 'm', help = "Custom model name (optional)")]
102 model: Option<String>,
103
104 #[arg(
106 long = "small-fast-model",
107 help = "Haiku-class model for background tasks (optional)"
108 )]
109 small_fast_model: Option<String>,
110
111 #[arg(
113 long = "max-thinking-tokens",
114 help = "Maximum thinking tokens limit (optional)"
115 )]
116 max_thinking_tokens: Option<u32>,
117
118 #[arg(
120 long = "api-timeout-ms",
121 help = "API timeout in milliseconds (optional)"
122 )]
123 api_timeout_ms: Option<u32>,
124
125 #[arg(
127 long = "disable-nonessential-traffic",
128 help = "Disable non-essential traffic flag (optional)"
129 )]
130 claude_code_disable_nonessential_traffic: Option<u32>,
131
132 #[arg(
134 long = "default-sonnet-model",
135 help = "Default Sonnet model name (optional)"
136 )]
137 anthropic_default_sonnet_model: Option<String>,
138
139 #[arg(
141 long = "default-opus-model",
142 help = "Default Opus model name (optional)"
143 )]
144 anthropic_default_opus_model: Option<String>,
145
146 #[arg(
148 long = "default-haiku-model",
149 help = "Default Haiku model name (optional)"
150 )]
151 anthropic_default_haiku_model: Option<String>,
152
153 #[arg(
155 long = "force",
156 short = 'f',
157 help = "Overwrite existing configuration with same alias"
158 )]
159 force: bool,
160
161 #[arg(
163 long = "interactive",
164 short = 'i',
165 help = "Enter configuration values interactively"
166 )]
167 interactive: bool,
168
169 #[arg(help = "API token (if not using -t flag)")]
171 token_arg: Option<String>,
172
173 #[arg(help = "API endpoint URL (if not using -u flag)")]
175 url_arg: Option<String>,
176
177 #[arg(
179 long = "from-file",
180 short = 'j',
181 help = "Import configuration from a JSON file (filename becomes alias name)"
182 )]
183 from_file: Option<String>,
184 },
185 Remove {
189 #[arg(required = true)]
191 alias_names: Vec<String>,
192 },
193 List {
197 #[arg(long = "plain", short = 'p')]
199 plain: bool,
200 },
201 #[command(alias = "C")]
205 Completion {
206 #[arg(default_value = "fish")]
208 shell: String,
209 },
210}