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(
9 long_about = "cc-switch helps you manage multiple Claude API configurations and switch between them easily.
10
11EXAMPLES:
12 cc-switch add my-config sk-ant-xxx https://api.anthropic.com
13 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com
14 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com -m claude-3-5-sonnet-20241022
15 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com --small-fast-model claude-3-haiku-20240307
16 cc-switch add my-config -t sk-ant-xxx -u https://api.anthropic.com --max-thinking-tokens 8192
17 cc-switch add my-config -i # Interactive mode
18 cc-switch add my-config --force # Overwrite existing config
19 cc-switch use my-config
20 cc-switch use -a my-config
21 cc-switch use --alias my-config
22 cc-switch use # Interactive mode
23 cc-switch use cc
24 cc-switch list
25 cc-switch remove config1 config2 config3
26 cc-switch # Enter interactive mode (same as 'use' without arguments)
27
28SHELL COMPLETION AND ALIASES:
29 cc-switch completion fish # Generates shell completions
30 cc-switch alias fish # Generates aliases for eval
31
32 These aliases are available:
33 - cs='cc-switch' # Quick access to cc-switch
34 - ccd='claude --dangerously-skip-permissions' # Quick Claude launch
35
36 To use aliases immediately:
37 eval \"$(cc-switch alias fish)\" # Add aliases to current session
38
39 Or add them permanently:
40 cc-switch completion fish > ~/.config/fish/completions/cc-switch.fish
41 echo \"alias cs='cc-switch'\" >> ~/.config/fish/config.fish
42 echo \"alias ccd='claude --dangerously-skip-permissions'\" >> ~/.config/fish/config.fish
43
44 Then use:
45 cs use my-config # Instead of cc-switch use my-config
46 ccd # Quick Claude launch"
47)]
48pub struct Cli {
49 #[command(subcommand)]
50 pub command: Option<Commands>,
51
52 #[arg(long = "list-aliases", hide = true)]
54 pub list_aliases: bool,
55
56 #[arg(
58 long = "migrate",
59 help = "Migrate old config path to new path and exit"
60 )]
61 pub migrate: bool,
62}
63
64#[derive(Subcommand)]
66#[allow(clippy::large_enum_variant)]
67pub enum Commands {
68 #[command(alias = "a")]
72 Add {
73 #[arg(
75 help = "Configuration alias name (cannot be 'cc')",
76 required_unless_present = "from_file"
77 )]
78 alias_name: Option<String>,
79
80 #[arg(
82 long = "token",
83 short = 't',
84 help = "API token (optional if not using interactive mode)"
85 )]
86 token: Option<String>,
87
88 #[arg(
90 long = "url",
91 short = 'u',
92 help = "API endpoint URL (optional if not using interactive mode)"
93 )]
94 url: Option<String>,
95
96 #[arg(long = "model", short = 'm', help = "Custom model name (optional)")]
98 model: Option<String>,
99
100 #[arg(
102 long = "small-fast-model",
103 help = "Haiku-class model for background tasks (optional)"
104 )]
105 small_fast_model: Option<String>,
106
107 #[arg(
109 long = "max-thinking-tokens",
110 help = "Maximum thinking tokens limit (optional)"
111 )]
112 max_thinking_tokens: Option<u32>,
113
114 #[arg(
116 long = "api-timeout-ms",
117 help = "API timeout in milliseconds (optional)"
118 )]
119 api_timeout_ms: Option<u32>,
120
121 #[arg(
123 long = "disable-nonessential-traffic",
124 help = "Disable non-essential traffic flag (optional)"
125 )]
126 claude_code_disable_nonessential_traffic: Option<u32>,
127
128 #[arg(
130 long = "default-sonnet-model",
131 help = "Default Sonnet model name (optional)"
132 )]
133 anthropic_default_sonnet_model: Option<String>,
134
135 #[arg(
137 long = "default-opus-model",
138 help = "Default Opus model name (optional)"
139 )]
140 anthropic_default_opus_model: Option<String>,
141
142 #[arg(
144 long = "default-haiku-model",
145 help = "Default Haiku model name (optional)"
146 )]
147 anthropic_default_haiku_model: Option<String>,
148
149 #[arg(
151 long = "force",
152 short = 'f',
153 help = "Overwrite existing configuration with same alias"
154 )]
155 force: bool,
156
157 #[arg(
159 long = "interactive",
160 short = 'i',
161 help = "Enter configuration values interactively"
162 )]
163 interactive: bool,
164
165 #[arg(help = "API token (if not using -t flag)")]
167 token_arg: Option<String>,
168
169 #[arg(help = "API endpoint URL (if not using -u flag)")]
171 url_arg: Option<String>,
172
173 #[arg(
175 long = "from-file",
176 short = 'j',
177 help = "Import configuration from a JSON file (filename becomes alias name)"
178 )]
179 from_file: Option<String>,
180 },
181 #[command(alias = "r")]
185 Remove {
186 #[arg(required = true)]
188 alias_names: Vec<String>,
189 },
190 #[command(alias = "l")]
194 List {
195 #[arg(long = "plain", short = 'p')]
197 plain: bool,
198 },
199 #[command(alias = "C")]
205 Completion {
206 #[arg(default_value = "fish")]
208 shell: String,
209 },
210 #[command(alias = "A")]
215 Alias {
216 #[arg(default_value = "fish")]
218 shell: String,
219 },
220 #[command(alias = "sw", alias = "switch")]
225 Use {
226 #[arg(help = "Configuration alias name (use 'cc' to reset to default)")]
228 alias_name: String,
229 },
230 #[command(alias = "v")]
232 Version,
233}