ccconfig 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -2
- package/README_zh.md +406 -0
- package/ccconfig.js +457 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Claude Code Configuration Manager
|
|
2
2
|
|
|
3
|
+
[English](README.md) | [中文](README_zh.md)
|
|
4
|
+
|
|
3
5
|
Quickly switch between different claude-code providers
|
|
4
6
|
|
|
5
7
|
|
|
@@ -35,7 +37,8 @@ ccconfig add
|
|
|
35
37
|
# - ANTHROPIC_BASE_URL
|
|
36
38
|
# - ANTHROPIC_AUTH_TOKEN
|
|
37
39
|
# - ANTHROPIC_API_KEY
|
|
38
|
-
# -
|
|
40
|
+
# - ANTHROPIC_MODEL (optional)
|
|
41
|
+
# - ANTHROPIC_SMALL_FAST_MODEL (optional)
|
|
39
42
|
|
|
40
43
|
# 3. Switch configuration
|
|
41
44
|
ccconfig use work
|
|
@@ -72,7 +75,8 @@ ccconfig add
|
|
|
72
75
|
# - ANTHROPIC_BASE_URL
|
|
73
76
|
# - ANTHROPIC_AUTH_TOKEN
|
|
74
77
|
# - ANTHROPIC_API_KEY
|
|
75
|
-
# -
|
|
78
|
+
# - ANTHROPIC_MODEL (optional)
|
|
79
|
+
# - ANTHROPIC_SMALL_FAST_MODEL (optional)
|
|
76
80
|
|
|
77
81
|
# 3. Switch configuration
|
|
78
82
|
ccconfig use work
|
|
@@ -179,6 +183,91 @@ if (Test-Path $cconfigEnv) {
|
|
|
179
183
|
|
|
180
184
|
## Advanced Usage
|
|
181
185
|
|
|
186
|
+
### Update Existing Configuration
|
|
187
|
+
|
|
188
|
+
If you need to modify an existing configuration, use the `update` command:
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
# Update a configuration interactively
|
|
192
|
+
ccconfig update work
|
|
193
|
+
|
|
194
|
+
# The tool will:
|
|
195
|
+
# 1. Show current values as defaults
|
|
196
|
+
# 2. Prompt for each field
|
|
197
|
+
# 3. Press Enter to keep current value, or type new value to update
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Example:**
|
|
201
|
+
```bash
|
|
202
|
+
$ ccconfig update work
|
|
203
|
+
Updating configuration 'work'
|
|
204
|
+
Press Enter to keep the current value, or enter a new value to update
|
|
205
|
+
|
|
206
|
+
ANTHROPIC_BASE_URL [https://api.company.com]: https://new-api.company.com
|
|
207
|
+
ANTHROPIC_AUTH_TOKEN [sk-ant-api...]: <press Enter to keep>
|
|
208
|
+
ANTHROPIC_API_KEY []: sk-new-key-123
|
|
209
|
+
ANTHROPIC_MODEL [claude-sonnet-4-5-20250929]: <press Enter to keep>
|
|
210
|
+
Do you want to set ANTHROPIC_SMALL_FAST_MODEL? (y/N) [n]:
|
|
211
|
+
|
|
212
|
+
✓ Configuration 'work' updated
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
**Note:** After updating a configuration, remember to activate it with `ccconfig use work` if you want the changes to take effect immediately.
|
|
216
|
+
|
|
217
|
+
### Shell Completion
|
|
218
|
+
|
|
219
|
+
ccconfig supports shell completion for commands, profile names, and options. This makes it easier to discover and use commands.
|
|
220
|
+
|
|
221
|
+
**Features:**
|
|
222
|
+
- ✅ Command completion (list, add, update, use, remove, etc.)
|
|
223
|
+
- ✅ Profile name completion (dynamically reads from your configurations)
|
|
224
|
+
- ✅ Option completion (--permanent, --show-secret, etc.)
|
|
225
|
+
- ✅ Mode completion (settings, env)
|
|
226
|
+
- ✅ Format completion (bash, zsh, fish, etc.)
|
|
227
|
+
|
|
228
|
+
**Installation:**
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
# Bash
|
|
232
|
+
ccconfig completion bash >> ~/.bashrc
|
|
233
|
+
source ~/.bashrc
|
|
234
|
+
|
|
235
|
+
# Zsh
|
|
236
|
+
ccconfig completion zsh >> ~/.zshrc
|
|
237
|
+
source ~/.zshrc
|
|
238
|
+
|
|
239
|
+
# Fish
|
|
240
|
+
ccconfig completion fish > ~/.config/fish/completions/ccconfig.fish
|
|
241
|
+
# Fish will automatically load it on next startup
|
|
242
|
+
|
|
243
|
+
# PowerShell
|
|
244
|
+
ccconfig completion pwsh >> $PROFILE
|
|
245
|
+
# Reload profile: . $PROFILE
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Note for PowerShell:** If you get an error about `$PROFILE` not existing, create it first:
|
|
249
|
+
```powershell
|
|
250
|
+
New-Item -Path $PROFILE -ItemType File -Force
|
|
251
|
+
ccconfig completion pwsh >> $PROFILE
|
|
252
|
+
. $PROFILE
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Usage examples after installing completion:**
|
|
256
|
+
|
|
257
|
+
```bash
|
|
258
|
+
# Type 'ccconfig' and press TAB to see all commands
|
|
259
|
+
ccconfig <TAB>
|
|
260
|
+
# Shows: list, add, update, use, remove, current, mode, env, edit, completion
|
|
261
|
+
|
|
262
|
+
# Type 'ccconfig use' and press TAB to see all profiles
|
|
263
|
+
ccconfig use <TAB>
|
|
264
|
+
# Shows: work, personal, project1, etc.
|
|
265
|
+
|
|
266
|
+
# Type 'ccconfig mode' and press TAB
|
|
267
|
+
ccconfig mode <TAB>
|
|
268
|
+
# Shows: settings, env
|
|
269
|
+
```
|
|
270
|
+
|
|
182
271
|
### Quick Aliases
|
|
183
272
|
|
|
184
273
|
```bash
|
package/README_zh.md
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# Claude Code 配置管理器
|
|
2
|
+
|
|
3
|
+
[English](README.md) | [中文](README_zh.md)
|
|
4
|
+
|
|
5
|
+
快速切换不同的 claude-code 提供商配置
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 工作时间切换到公司配置
|
|
9
|
+
ccconfig use company
|
|
10
|
+
|
|
11
|
+
# 下班后切换回个人配置
|
|
12
|
+
ccconfig use personal
|
|
13
|
+
|
|
14
|
+
# 永久写入 shell 配置文件(无需每次 eval 或 source)
|
|
15
|
+
ccconfig use personal --permanent # 或使用 -p 简写
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
### 安装
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# 从 npm 安装(推荐)
|
|
24
|
+
npm install -g ccconfig
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### ENV 模式(推荐,默认)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# 1. 配置 Shell 自动加载(见下文)
|
|
31
|
+
|
|
32
|
+
# 2. 添加配置(交互模式)
|
|
33
|
+
ccconfig add
|
|
34
|
+
# 按提示输入:
|
|
35
|
+
# - 名称
|
|
36
|
+
# - ANTHROPIC_BASE_URL
|
|
37
|
+
# - ANTHROPIC_AUTH_TOKEN
|
|
38
|
+
# - ANTHROPIC_API_KEY
|
|
39
|
+
# - ANTHROPIC_MODEL(可选)
|
|
40
|
+
# - ANTHROPIC_SMALL_FAST_MODEL(可选)
|
|
41
|
+
|
|
42
|
+
# 3. 切换配置
|
|
43
|
+
ccconfig use work
|
|
44
|
+
|
|
45
|
+
# 4. 立即生效(选择一种方法):
|
|
46
|
+
# 方法 A: 临时生效(仅当前 shell)
|
|
47
|
+
eval $(ccconfig env bash) # 或使用输出中检测到的命令
|
|
48
|
+
|
|
49
|
+
# 方法 B: 永久生效(写入 shell 配置文件)
|
|
50
|
+
ccconfig use work --permanent # 或使用 -p 简写
|
|
51
|
+
# 自动检测并修改 ~/.bashrc、~/.zshrc 或 config.fish
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Settings 模式
|
|
55
|
+
|
|
56
|
+
Settings 模式直接修改 `~/.claude/settings.json` 文件,这是 Claude Code 的原生配置文件。此模式适合不想配置 shell 脚本的情况。
|
|
57
|
+
|
|
58
|
+
**工作原理:**
|
|
59
|
+
- 直接将环境变量写入 `~/.claude/settings.json` 的 `env` 字段
|
|
60
|
+
- Claude Code 启动时读取这些设置
|
|
61
|
+
- 无需 shell 配置
|
|
62
|
+
- 每次切换后需要重启 Claude Code
|
|
63
|
+
|
|
64
|
+
**设置步骤:**
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
# 1. 切换到 settings 模式
|
|
68
|
+
ccconfig mode settings
|
|
69
|
+
|
|
70
|
+
# 2. 添加配置(交互模式)
|
|
71
|
+
ccconfig add
|
|
72
|
+
# 按提示输入:
|
|
73
|
+
# - 名称
|
|
74
|
+
# - ANTHROPIC_BASE_URL
|
|
75
|
+
# - ANTHROPIC_AUTH_TOKEN
|
|
76
|
+
# - ANTHROPIC_API_KEY
|
|
77
|
+
# - ANTHROPIC_MODEL(可选)
|
|
78
|
+
# - ANTHROPIC_SMALL_FAST_MODEL(可选)
|
|
79
|
+
|
|
80
|
+
# 3. 切换配置
|
|
81
|
+
ccconfig use work
|
|
82
|
+
|
|
83
|
+
# 4. 重启 Claude Code
|
|
84
|
+
# 配置现已生效!
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**验证:**
|
|
88
|
+
```bash
|
|
89
|
+
# 查看当前配置
|
|
90
|
+
ccconfig current
|
|
91
|
+
|
|
92
|
+
# 直接查看 settings 文件
|
|
93
|
+
cat ~/.claude/settings.json
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### ENV 模式 Shell 配置
|
|
97
|
+
|
|
98
|
+
您有两种方式配置 shell 环境:
|
|
99
|
+
|
|
100
|
+
**方式 1: 自动配置(推荐)**
|
|
101
|
+
|
|
102
|
+
使用 `-p/--permanent` 标志自动写入您的 shell 配置:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 自动检测您的 shell 并写入相应的配置文件
|
|
106
|
+
ccconfig use <profile> --permanent
|
|
107
|
+
|
|
108
|
+
# 您将看到:
|
|
109
|
+
# - 修改 shell 配置的警告
|
|
110
|
+
# - 目标文件路径
|
|
111
|
+
# - 内容预览
|
|
112
|
+
# - 确认提示(yes/no)
|
|
113
|
+
|
|
114
|
+
# 这将修改:
|
|
115
|
+
# - Fish: ~/.config/fish/config.fish
|
|
116
|
+
# - Bash: ~/.bashrc
|
|
117
|
+
# - Zsh: ~/.zshrc
|
|
118
|
+
# - PowerShell: ~/.config/powershell/profile.ps1
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
工具会在 `# >>> ccconfig >>>` 和 `# <<< ccconfig <<<` 标记之间添加一个标记块,便于后续识别和更新。
|
|
122
|
+
|
|
123
|
+
**安全特性:**
|
|
124
|
+
- **需要用户确认**: 修改文件前会提示确认
|
|
125
|
+
- **内容预览**: 显示将要写入的确切内容
|
|
126
|
+
- **清晰说明**: 解释将要进行的更改
|
|
127
|
+
- **非破坏性**: 保留现有内容,仅更新 ccconfig 块
|
|
128
|
+
- **仅交互模式**: 需要交互式终端以防止意外修改
|
|
129
|
+
|
|
130
|
+
**方式 2: 手动配置**
|
|
131
|
+
|
|
132
|
+
如果您喜欢手动配置,请将以下内容添加到您的 shell 启动文件:
|
|
133
|
+
|
|
134
|
+
**Fish** (`~/.config/fish/config.fish`):
|
|
135
|
+
```fish
|
|
136
|
+
# 加载 Claude Code 环境变量
|
|
137
|
+
set -l ccconfig_env ~/.config/ccconfig/current.env
|
|
138
|
+
if test -f $ccconfig_env
|
|
139
|
+
for line in (cat $ccconfig_env)
|
|
140
|
+
set -l parts (string split -m1 '=' $line)
|
|
141
|
+
if test (count $parts) -eq 2
|
|
142
|
+
set -gx $parts[1] $parts[2]
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**Bash** (`~/.bashrc`):
|
|
149
|
+
```bash
|
|
150
|
+
# 加载 Claude Code 环境变量
|
|
151
|
+
if [ -f ~/.config/ccconfig/current.env ]; then
|
|
152
|
+
set -a
|
|
153
|
+
. ~/.config/ccconfig/current.env
|
|
154
|
+
set +a
|
|
155
|
+
fi
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Zsh** (`~/.zshrc`):
|
|
159
|
+
```zsh
|
|
160
|
+
# 加载 Claude Code 环境变量
|
|
161
|
+
if [ -f ~/.config/ccconfig/current.env ]; then
|
|
162
|
+
set -a
|
|
163
|
+
. ~/.config/ccconfig/current.env
|
|
164
|
+
set +a
|
|
165
|
+
fi
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**PowerShell** (`$PROFILE`):
|
|
169
|
+
```powershell
|
|
170
|
+
# 加载 Claude Code 环境变量
|
|
171
|
+
$cconfigEnv = "$env:USERPROFILE\.config\ccconfig\current.env"
|
|
172
|
+
if (Test-Path $cconfigEnv) {
|
|
173
|
+
Get-Content $cconfigEnv | ForEach-Object {
|
|
174
|
+
if ($_ -match '^([^=]+)=(.*)$') {
|
|
175
|
+
[Environment]::SetEnvironmentVariable($matches[1], $matches[2], 'Process')
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**注意**: 手动配置允许您通过更改 `current.env` 动态切换配置文件,而 `-p/--permanent` 直接将值写入 shell 配置文件。
|
|
182
|
+
|
|
183
|
+
## 高级用法
|
|
184
|
+
|
|
185
|
+
### 更新现有配置
|
|
186
|
+
|
|
187
|
+
如果您需要修改已有配置,使用 `update` 命令:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# 交互式更新配置
|
|
191
|
+
ccconfig update work
|
|
192
|
+
|
|
193
|
+
# 工具会:
|
|
194
|
+
# 1. 显示当前值作为默认值
|
|
195
|
+
# 2. 提示输入每个字段
|
|
196
|
+
# 3. 按 Enter 保持当前值,或输入新值来更新
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
**示例:**
|
|
200
|
+
```bash
|
|
201
|
+
$ ccconfig update work
|
|
202
|
+
Updating configuration 'work'
|
|
203
|
+
Press Enter to keep the current value, or enter a new value to update
|
|
204
|
+
|
|
205
|
+
ANTHROPIC_BASE_URL [https://api.company.com]: https://new-api.company.com
|
|
206
|
+
ANTHROPIC_AUTH_TOKEN [sk-ant-api...]: <按 Enter 保持不变>
|
|
207
|
+
ANTHROPIC_API_KEY []: sk-new-key-123
|
|
208
|
+
ANTHROPIC_MODEL [claude-sonnet-4-5-20250929]: <按 Enter 保持不变>
|
|
209
|
+
Do you want to set ANTHROPIC_SMALL_FAST_MODEL? (y/N) [n]:
|
|
210
|
+
|
|
211
|
+
✓ Configuration 'work' updated
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**注意:** 更新配置后,如果要立即生效,记得使用 `ccconfig use work` 激活配置。
|
|
215
|
+
|
|
216
|
+
### Shell 自动补全
|
|
217
|
+
|
|
218
|
+
ccconfig 支持命令、配置名称和选项的 shell 自动补全,让您更容易发现和使用命令。
|
|
219
|
+
|
|
220
|
+
**功能:**
|
|
221
|
+
- ✅ 命令补全 (list, add, update, use, remove 等)
|
|
222
|
+
- ✅ 配置名称补全(动态读取您的配置)
|
|
223
|
+
- ✅ 选项补全 (--permanent, --show-secret 等)
|
|
224
|
+
- ✅ 模式补全 (settings, env)
|
|
225
|
+
- ✅ 格式补全 (bash, zsh, fish 等)
|
|
226
|
+
|
|
227
|
+
**安装:**
|
|
228
|
+
|
|
229
|
+
```bash
|
|
230
|
+
# Bash
|
|
231
|
+
ccconfig completion bash >> ~/.bashrc
|
|
232
|
+
source ~/.bashrc
|
|
233
|
+
|
|
234
|
+
# Zsh
|
|
235
|
+
ccconfig completion zsh >> ~/.zshrc
|
|
236
|
+
source ~/.zshrc
|
|
237
|
+
|
|
238
|
+
# Fish
|
|
239
|
+
ccconfig completion fish > ~/.config/fish/completions/ccconfig.fish
|
|
240
|
+
# Fish 会在下次启动时自动加载
|
|
241
|
+
|
|
242
|
+
# PowerShell
|
|
243
|
+
ccconfig completion pwsh >> $PROFILE
|
|
244
|
+
# 重新加载配置: . $PROFILE
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**PowerShell 注意事项:** 如果遇到 `$PROFILE` 不存在的错误,请先创建它:
|
|
248
|
+
```powershell
|
|
249
|
+
New-Item -Path $PROFILE -ItemType File -Force
|
|
250
|
+
ccconfig completion pwsh >> $PROFILE
|
|
251
|
+
. $PROFILE
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
**安装补全后的使用示例:**
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
# 输入 'ccconfig' 然后按 TAB 查看所有命令
|
|
258
|
+
ccconfig <TAB>
|
|
259
|
+
# 显示: list, add, update, use, remove, current, mode, env, edit, completion
|
|
260
|
+
|
|
261
|
+
# 输入 'ccconfig use' 然后按 TAB 查看所有配置
|
|
262
|
+
ccconfig use <TAB>
|
|
263
|
+
# 显示: work, personal, project1 等
|
|
264
|
+
|
|
265
|
+
# 输入 'ccconfig mode' 然后按 TAB
|
|
266
|
+
ccconfig mode <TAB>
|
|
267
|
+
# 显示: settings, env
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### 快捷别名
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
# 添加到 ~/.bashrc 或 ~/.zshrc
|
|
274
|
+
alias ccs='ccconfig'
|
|
275
|
+
alias ccs-use='ccconfig use'
|
|
276
|
+
alias ccs-list='ccconfig list'
|
|
277
|
+
alias ccs-current='ccconfig current'
|
|
278
|
+
|
|
279
|
+
# Fish (~/.config/fish/config.fish)
|
|
280
|
+
abbr ccs 'ccconfig'
|
|
281
|
+
abbr ccs-use 'ccconfig use'
|
|
282
|
+
abbr ccs-list 'ccconfig list'
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 项目级配置
|
|
286
|
+
|
|
287
|
+
对于特定项目,您可以导出 .env 文件:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# 导出到项目目录
|
|
291
|
+
cd my-project
|
|
292
|
+
ccconfig use project-config
|
|
293
|
+
ccconfig env dotenv > .env
|
|
294
|
+
|
|
295
|
+
# 使用项目配置
|
|
296
|
+
source .env
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### 备份和同步
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
# 备份配置
|
|
303
|
+
cp ~/.config/ccconfig/profiles.json ~/backup/ccconfig-profiles.json
|
|
304
|
+
|
|
305
|
+
# 同步到新机器
|
|
306
|
+
scp ~/backup/ccconfig-profiles.json new-machine:~/.config/ccconfig/
|
|
307
|
+
|
|
308
|
+
# 或使用版本控制(注意安全!)
|
|
309
|
+
cd ~/.config/ccconfig
|
|
310
|
+
git init
|
|
311
|
+
echo "*.env" >> .gitignore
|
|
312
|
+
git add profiles.json
|
|
313
|
+
git commit -m "ccconfig profiles"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
## 故障排除
|
|
317
|
+
|
|
318
|
+
### 配置未生效
|
|
319
|
+
|
|
320
|
+
**Settings 模式**:
|
|
321
|
+
1. **检查配置是否正确写入**:
|
|
322
|
+
```bash
|
|
323
|
+
ccconfig current
|
|
324
|
+
# 查看【1】~/.claude/settings.json 部分
|
|
325
|
+
```
|
|
326
|
+
2. **直接验证 settings.json**:
|
|
327
|
+
```bash
|
|
328
|
+
cat ~/.claude/settings.json | grep -A 5 '"env"'
|
|
329
|
+
```
|
|
330
|
+
3. **确认已重启 Claude Code**:
|
|
331
|
+
- 完全退出 Claude Code(不只是关闭窗口)
|
|
332
|
+
- 重新启动应用程序
|
|
333
|
+
4. **检查 `~/.claude/settings.json` 中的 `env` 字段**:
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"env": {
|
|
337
|
+
"ANTHROPIC_BASE_URL": "https://api.anthropic.com",
|
|
338
|
+
"ANTHROPIC_AUTH_TOKEN": "sk-...",
|
|
339
|
+
"ANTHROPIC_API_KEY": "sk-..."
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
**ENV 模式**:
|
|
345
|
+
1. **检查环境变量文件**:
|
|
346
|
+
```bash
|
|
347
|
+
cat ~/.config/ccconfig/current.env
|
|
348
|
+
```
|
|
349
|
+
2. **如果使用 --permanent 标志**:
|
|
350
|
+
- 工具会显示警告并在修改文件前要求确认
|
|
351
|
+
- 检查您的 shell 配置文件是否有 ccconfig 块:
|
|
352
|
+
```bash
|
|
353
|
+
# For bash/zsh
|
|
354
|
+
cat ~/.bashrc | grep -A 5 "ccconfig"
|
|
355
|
+
# For fish
|
|
356
|
+
cat ~/.config/fish/config.fish | grep -A 5 "ccconfig"
|
|
357
|
+
```
|
|
358
|
+
- 重启 shell 或运行: `source ~/.bashrc`(或您的 shell 对应的命令)
|
|
359
|
+
- 注意: 您也可以使用 `-p` 作为 `--permanent` 的简写
|
|
360
|
+
- 要取消操作,在提示时输入 "no"
|
|
361
|
+
|
|
362
|
+
3. **如果使用手动配置或 eval 命令**:
|
|
363
|
+
- 确认 Shell 配置正确: `cat ~/.bashrc | grep ccconfig`
|
|
364
|
+
- 重启 Shell 或使用 `eval $(ccconfig env bash)`
|
|
365
|
+
|
|
366
|
+
4. **检查进程环境变量**:
|
|
367
|
+
```bash
|
|
368
|
+
ccconfig current
|
|
369
|
+
# 查看【3】当前进程环境变量部分
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### 切换模式后配置丢失
|
|
373
|
+
|
|
374
|
+
切换模式不会影响已保存的配置,只会改变配置的应用方式。切换后,您需要再次 `use`:
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
ccconfig mode env # 切换到 env 模式
|
|
378
|
+
ccconfig use work # 重新应用配置
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 文件权限问题
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
# 修复配置文件权限
|
|
385
|
+
chmod 600 ~/.config/ccconfig/profiles.json
|
|
386
|
+
chmod 600 ~/.claude/settings.json
|
|
387
|
+
chmod 600 ~/.config/ccconfig/current.env
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
## 安全考虑
|
|
391
|
+
|
|
392
|
+
1. **文件权限**: 工具会自动将配置文件设置为 600 权限(仅所有者可读写)
|
|
393
|
+
|
|
394
|
+
2. **敏感信息**:
|
|
395
|
+
- API 密钥默认隐藏,使用 `--show-secret` 查看完整值
|
|
396
|
+
- 不要将配置文件提交到公共仓库
|
|
397
|
+
- 使用 `.gitignore` 排除敏感文件
|
|
398
|
+
|
|
399
|
+
3. **环境变量**: ENV 模式的环境变量会被子进程继承,请注意安全
|
|
400
|
+
|
|
401
|
+
4. **版本控制**: 如果对配置进行版本控制,请使用加密或私有仓库
|
|
402
|
+
|
|
403
|
+
## 许可证
|
|
404
|
+
|
|
405
|
+
MIT
|
|
406
|
+
|
package/ccconfig.js
CHANGED
|
@@ -147,6 +147,8 @@ function updateClaudeSettings(envVars) {
|
|
|
147
147
|
delete settings.env.ANTHROPIC_BASE_URL;
|
|
148
148
|
delete settings.env.ANTHROPIC_AUTH_TOKEN;
|
|
149
149
|
delete settings.env.ANTHROPIC_API_KEY;
|
|
150
|
+
delete settings.env.ANTHROPIC_MODEL;
|
|
151
|
+
delete settings.env.ANTHROPIC_SMALL_FAST_MODEL;
|
|
150
152
|
|
|
151
153
|
// Set new environment variables
|
|
152
154
|
Object.assign(settings.env, envVars);
|
|
@@ -323,8 +325,11 @@ function list() {
|
|
|
323
325
|
if (profile.env && profile.env.ANTHROPIC_BASE_URL) {
|
|
324
326
|
console.log(` URL: ${profile.env.ANTHROPIC_BASE_URL}`);
|
|
325
327
|
}
|
|
326
|
-
if (profile.
|
|
327
|
-
console.log(`
|
|
328
|
+
if (profile.env && profile.env.ANTHROPIC_MODEL) {
|
|
329
|
+
console.log(` Model: ${profile.env.ANTHROPIC_MODEL}`);
|
|
330
|
+
}
|
|
331
|
+
if (profile.env && profile.env.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
332
|
+
console.log(` Small Fast Model: ${profile.env.ANTHROPIC_SMALL_FAST_MODEL}`);
|
|
328
333
|
}
|
|
329
334
|
console.log('');
|
|
330
335
|
}
|
|
@@ -374,7 +379,8 @@ async function add(name) {
|
|
|
374
379
|
});
|
|
375
380
|
};
|
|
376
381
|
|
|
377
|
-
let baseUrl, authToken, apiKey,
|
|
382
|
+
let baseUrl, authToken, apiKey, model, smallFastModel;
|
|
383
|
+
let profiles;
|
|
378
384
|
|
|
379
385
|
try {
|
|
380
386
|
if (!name) {
|
|
@@ -386,38 +392,48 @@ async function add(name) {
|
|
|
386
392
|
process.exit(1);
|
|
387
393
|
}
|
|
388
394
|
|
|
395
|
+
// Check if configuration already exists before asking for details
|
|
396
|
+
profiles = loadProfiles() || {profiles: {}};
|
|
397
|
+
|
|
398
|
+
if (profiles.profiles[name]) {
|
|
399
|
+
console.error(`Error: Configuration '${name}' already exists`);
|
|
400
|
+
console.error('To update, please edit the configuration file directly');
|
|
401
|
+
process.exit(1);
|
|
402
|
+
}
|
|
403
|
+
|
|
389
404
|
baseUrl = await askQuestion(
|
|
390
|
-
'Please enter ANTHROPIC_BASE_URL (
|
|
405
|
+
'Please enter ANTHROPIC_BASE_URL (press Enter for default)',
|
|
391
406
|
'https://api.anthropic.com');
|
|
392
407
|
|
|
393
408
|
authToken =
|
|
394
|
-
await askQuestion('Please enter ANTHROPIC_AUTH_TOKEN (
|
|
409
|
+
await askQuestion('Please enter ANTHROPIC_AUTH_TOKEN (press Enter to set as empty)');
|
|
410
|
+
|
|
411
|
+
apiKey = await askQuestion('Please enter ANTHROPIC_API_KEY (press Enter to set as empty)');
|
|
395
412
|
|
|
396
|
-
|
|
413
|
+
model = await askQuestion('Please enter ANTHROPIC_MODEL (press Enter to skip)');
|
|
397
414
|
|
|
398
|
-
|
|
399
|
-
'Please enter configuration description (can be empty)');
|
|
415
|
+
smallFastModel = await askQuestion('Please enter ANTHROPIC_SMALL_FAST_MODEL (press Enter to skip)');
|
|
400
416
|
} finally {
|
|
401
417
|
if (rl) {
|
|
402
418
|
rl.close();
|
|
403
419
|
}
|
|
404
420
|
}
|
|
405
421
|
|
|
406
|
-
const profiles = loadProfiles() || {profiles: {}};
|
|
407
|
-
|
|
408
|
-
if (profiles.profiles[name]) {
|
|
409
|
-
console.error(`Error: Configuration '${name}' already exists`);
|
|
410
|
-
console.error('To update, please edit the configuration file directly');
|
|
411
|
-
process.exit(1);
|
|
412
|
-
}
|
|
413
|
-
|
|
414
422
|
const envVars = {
|
|
415
423
|
ANTHROPIC_BASE_URL: baseUrl || '',
|
|
416
424
|
ANTHROPIC_AUTH_TOKEN: authToken || '',
|
|
417
425
|
ANTHROPIC_API_KEY: apiKey || ''
|
|
418
426
|
};
|
|
419
427
|
|
|
420
|
-
|
|
428
|
+
// Add optional model variables if provided
|
|
429
|
+
if (model) {
|
|
430
|
+
envVars.ANTHROPIC_MODEL = model;
|
|
431
|
+
}
|
|
432
|
+
if (smallFastModel) {
|
|
433
|
+
envVars.ANTHROPIC_SMALL_FAST_MODEL = smallFastModel;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
profiles.profiles[name] = {env: envVars};
|
|
421
437
|
|
|
422
438
|
saveProfiles(profiles);
|
|
423
439
|
console.log(`✓ Configuration '${name}' added`);
|
|
@@ -441,6 +457,12 @@ async function add(name) {
|
|
|
441
457
|
safePrint('ANTHROPIC_BASE_URL', envVars.ANTHROPIC_BASE_URL, false);
|
|
442
458
|
safePrint('ANTHROPIC_AUTH_TOKEN', envVars.ANTHROPIC_AUTH_TOKEN);
|
|
443
459
|
safePrint('ANTHROPIC_API_KEY', envVars.ANTHROPIC_API_KEY);
|
|
460
|
+
if (envVars.ANTHROPIC_MODEL) {
|
|
461
|
+
safePrint('ANTHROPIC_MODEL', envVars.ANTHROPIC_MODEL, false);
|
|
462
|
+
}
|
|
463
|
+
if (envVars.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
464
|
+
safePrint('ANTHROPIC_SMALL_FAST_MODEL', envVars.ANTHROPIC_SMALL_FAST_MODEL, false);
|
|
465
|
+
}
|
|
444
466
|
console.log('');
|
|
445
467
|
console.log('This information has been saved to:');
|
|
446
468
|
console.log(` ${PROFILES_FILE}`);
|
|
@@ -450,6 +472,131 @@ async function add(name) {
|
|
|
450
472
|
console.log('Or run ccconfig edit to open it with your preferred editor');
|
|
451
473
|
}
|
|
452
474
|
|
|
475
|
+
/**
|
|
476
|
+
* Update existing configuration
|
|
477
|
+
*/
|
|
478
|
+
async function update(name) {
|
|
479
|
+
// Auto-initialize if needed
|
|
480
|
+
initIfNeeded();
|
|
481
|
+
|
|
482
|
+
const isInteractive = process.stdin.isTTY && process.stdout.isTTY;
|
|
483
|
+
|
|
484
|
+
if (!isInteractive) {
|
|
485
|
+
console.error('Error: Interactive mode required for updating configurations');
|
|
486
|
+
console.error('This command must be run in an interactive terminal');
|
|
487
|
+
process.exit(1);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
let rl = null;
|
|
491
|
+
|
|
492
|
+
const askQuestion = (question, defaultValue = '') => {
|
|
493
|
+
if (!rl) {
|
|
494
|
+
rl = readline.createInterface(
|
|
495
|
+
{input: process.stdin, output: process.stdout});
|
|
496
|
+
}
|
|
497
|
+
return new Promise(resolve => {
|
|
498
|
+
const suffix = defaultValue ? ` [${defaultValue}]` : '';
|
|
499
|
+
rl.question(`${question}${suffix}: `, answer => {
|
|
500
|
+
const trimmed = answer.trim();
|
|
501
|
+
resolve(trimmed ? trimmed : defaultValue);
|
|
502
|
+
});
|
|
503
|
+
});
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
let baseUrl, authToken, apiKey, model, smallFastModel;
|
|
507
|
+
let profiles;
|
|
508
|
+
|
|
509
|
+
try {
|
|
510
|
+
if (!name) {
|
|
511
|
+
name = await askQuestion('Please enter configuration name to update');
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
if (!name) {
|
|
515
|
+
console.error('Error: Configuration name cannot be empty');
|
|
516
|
+
process.exit(1);
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
// Check if configuration exists
|
|
520
|
+
profiles = loadProfiles() || {profiles: {}};
|
|
521
|
+
|
|
522
|
+
if (!profiles.profiles[name]) {
|
|
523
|
+
console.error(`Error: Configuration '${name}' does not exist`);
|
|
524
|
+
console.error('Run ccconfig list to see available configurations');
|
|
525
|
+
console.error(`Or use 'ccconfig add ${name}' to create a new configuration`);
|
|
526
|
+
process.exit(1);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
const existingProfile = profiles.profiles[name];
|
|
530
|
+
const existingEnv = existingProfile.env || {};
|
|
531
|
+
|
|
532
|
+
console.log(`Updating configuration '${name}'`);
|
|
533
|
+
console.log('Press Enter to keep current value/default, or enter new value to update');
|
|
534
|
+
console.log('');
|
|
535
|
+
|
|
536
|
+
baseUrl = await askQuestion(
|
|
537
|
+
'ANTHROPIC_BASE_URL (press Enter to keep current/default)',
|
|
538
|
+
existingEnv.ANTHROPIC_BASE_URL || 'https://api.anthropic.com');
|
|
539
|
+
|
|
540
|
+
authToken =
|
|
541
|
+
await askQuestion('ANTHROPIC_AUTH_TOKEN (press Enter to keep current/set empty)', existingEnv.ANTHROPIC_AUTH_TOKEN || '');
|
|
542
|
+
|
|
543
|
+
apiKey = await askQuestion('ANTHROPIC_API_KEY (press Enter to keep current/set empty)', existingEnv.ANTHROPIC_API_KEY || '');
|
|
544
|
+
|
|
545
|
+
model = await askQuestion('ANTHROPIC_MODEL (press Enter to skip/keep current)', existingEnv.ANTHROPIC_MODEL || '');
|
|
546
|
+
|
|
547
|
+
smallFastModel = await askQuestion('ANTHROPIC_SMALL_FAST_MODEL (press Enter to skip/keep current)', existingEnv.ANTHROPIC_SMALL_FAST_MODEL || '');
|
|
548
|
+
} finally {
|
|
549
|
+
if (rl) {
|
|
550
|
+
rl.close();
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
const envVars = {
|
|
555
|
+
ANTHROPIC_BASE_URL: baseUrl || '',
|
|
556
|
+
ANTHROPIC_AUTH_TOKEN: authToken || '',
|
|
557
|
+
ANTHROPIC_API_KEY: apiKey || ''
|
|
558
|
+
};
|
|
559
|
+
|
|
560
|
+
// Add optional model variables if provided
|
|
561
|
+
if (model) {
|
|
562
|
+
envVars.ANTHROPIC_MODEL = model;
|
|
563
|
+
}
|
|
564
|
+
if (smallFastModel) {
|
|
565
|
+
envVars.ANTHROPIC_SMALL_FAST_MODEL = smallFastModel;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
profiles.profiles[name] = {env: envVars};
|
|
569
|
+
|
|
570
|
+
saveProfiles(profiles);
|
|
571
|
+
console.log(`✓ Configuration '${name}' updated`);
|
|
572
|
+
console.log('');
|
|
573
|
+
console.log('Updated environment variables:');
|
|
574
|
+
const safePrint = (key, value, mask = true) => {
|
|
575
|
+
if (!value) {
|
|
576
|
+
console.log(` ${key}: (not set)`);
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (!mask) {
|
|
580
|
+
console.log(` ${key}: ${value}`);
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
const masked = value.length > 20 ? value.substring(0, 20) + '...' : value;
|
|
584
|
+
console.log(` ${key}: ${masked}`);
|
|
585
|
+
};
|
|
586
|
+
safePrint('ANTHROPIC_BASE_URL', envVars.ANTHROPIC_BASE_URL, false);
|
|
587
|
+
safePrint('ANTHROPIC_AUTH_TOKEN', envVars.ANTHROPIC_AUTH_TOKEN);
|
|
588
|
+
safePrint('ANTHROPIC_API_KEY', envVars.ANTHROPIC_API_KEY);
|
|
589
|
+
if (envVars.ANTHROPIC_MODEL) {
|
|
590
|
+
safePrint('ANTHROPIC_MODEL', envVars.ANTHROPIC_MODEL, false);
|
|
591
|
+
}
|
|
592
|
+
if (envVars.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
593
|
+
safePrint('ANTHROPIC_SMALL_FAST_MODEL', envVars.ANTHROPIC_SMALL_FAST_MODEL, false);
|
|
594
|
+
}
|
|
595
|
+
console.log('');
|
|
596
|
+
console.log('Run the following command to activate:');
|
|
597
|
+
console.log(` ccconfig use ${name}`);
|
|
598
|
+
}
|
|
599
|
+
|
|
453
600
|
/**
|
|
454
601
|
* Remove configuration
|
|
455
602
|
*/
|
|
@@ -860,7 +1007,9 @@ function current(showSecret = false) {
|
|
|
860
1007
|
const processEnv = {
|
|
861
1008
|
ANTHROPIC_BASE_URL: process.env.ANTHROPIC_BASE_URL,
|
|
862
1009
|
ANTHROPIC_AUTH_TOKEN: process.env.ANTHROPIC_AUTH_TOKEN,
|
|
863
|
-
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY
|
|
1010
|
+
ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,
|
|
1011
|
+
ANTHROPIC_MODEL: process.env.ANTHROPIC_MODEL,
|
|
1012
|
+
ANTHROPIC_SMALL_FAST_MODEL: process.env.ANTHROPIC_SMALL_FAST_MODEL
|
|
864
1013
|
};
|
|
865
1014
|
const currentProfile = getCurrentProfile();
|
|
866
1015
|
|
|
@@ -890,6 +1039,12 @@ function current(showSecret = false) {
|
|
|
890
1039
|
|
|
891
1040
|
console.log(` ANTHROPIC_BASE_URL: ${baseUrl}`);
|
|
892
1041
|
console.log(` ANTHROPIC_AUTH_TOKEN: ${maskedToken}`);
|
|
1042
|
+
if (settings.env.ANTHROPIC_MODEL) {
|
|
1043
|
+
console.log(` ANTHROPIC_MODEL: ${settings.env.ANTHROPIC_MODEL}`);
|
|
1044
|
+
}
|
|
1045
|
+
if (settings.env.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
1046
|
+
console.log(` ANTHROPIC_SMALL_FAST_MODEL: ${settings.env.ANTHROPIC_SMALL_FAST_MODEL}`);
|
|
1047
|
+
}
|
|
893
1048
|
} else {
|
|
894
1049
|
console.log(' (not configured)');
|
|
895
1050
|
}
|
|
@@ -909,6 +1064,12 @@ function current(showSecret = false) {
|
|
|
909
1064
|
|
|
910
1065
|
console.log(` ANTHROPIC_BASE_URL: ${baseUrl}`);
|
|
911
1066
|
console.log(` ANTHROPIC_AUTH_TOKEN: ${maskedToken}`);
|
|
1067
|
+
if (envFile.ANTHROPIC_MODEL) {
|
|
1068
|
+
console.log(` ANTHROPIC_MODEL: ${envFile.ANTHROPIC_MODEL}`);
|
|
1069
|
+
}
|
|
1070
|
+
if (envFile.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
1071
|
+
console.log(` ANTHROPIC_SMALL_FAST_MODEL: ${envFile.ANTHROPIC_SMALL_FAST_MODEL}`);
|
|
1072
|
+
}
|
|
912
1073
|
} else {
|
|
913
1074
|
console.log(' (not configured)');
|
|
914
1075
|
}
|
|
@@ -927,6 +1088,12 @@ function current(showSecret = false) {
|
|
|
927
1088
|
|
|
928
1089
|
console.log(` ANTHROPIC_BASE_URL: ${baseUrl}`);
|
|
929
1090
|
console.log(` ANTHROPIC_AUTH_TOKEN: ${maskedToken}`);
|
|
1091
|
+
if (processEnv.ANTHROPIC_MODEL) {
|
|
1092
|
+
console.log(` ANTHROPIC_MODEL: ${processEnv.ANTHROPIC_MODEL}`);
|
|
1093
|
+
}
|
|
1094
|
+
if (processEnv.ANTHROPIC_SMALL_FAST_MODEL) {
|
|
1095
|
+
console.log(` ANTHROPIC_SMALL_FAST_MODEL: ${processEnv.ANTHROPIC_SMALL_FAST_MODEL}`);
|
|
1096
|
+
}
|
|
930
1097
|
} else {
|
|
931
1098
|
console.log(' (not set)');
|
|
932
1099
|
}
|
|
@@ -1074,6 +1241,268 @@ function env(format = 'bash') {
|
|
|
1074
1241
|
}
|
|
1075
1242
|
}
|
|
1076
1243
|
|
|
1244
|
+
/**
|
|
1245
|
+
* Generate shell completion script
|
|
1246
|
+
*/
|
|
1247
|
+
function completion(shell) {
|
|
1248
|
+
if (!shell) {
|
|
1249
|
+
console.error('Error: Missing shell type');
|
|
1250
|
+
console.error('Usage: ccconfig completion <bash|zsh|fish|powershell|pwsh>');
|
|
1251
|
+
console.error('');
|
|
1252
|
+
console.error('To install:');
|
|
1253
|
+
console.error(' Bash: ccconfig completion bash >> ~/.bashrc');
|
|
1254
|
+
console.error(' Zsh: ccconfig completion zsh >> ~/.zshrc');
|
|
1255
|
+
console.error(' Fish: ccconfig completion fish > ~/.config/fish/completions/ccconfig.fish');
|
|
1256
|
+
console.error(' PowerShell: ccconfig completion pwsh >> $PROFILE');
|
|
1257
|
+
process.exit(1);
|
|
1258
|
+
}
|
|
1259
|
+
|
|
1260
|
+
const commands = 'list ls add update use remove rm current mode env edit';
|
|
1261
|
+
|
|
1262
|
+
switch (shell) {
|
|
1263
|
+
case 'bash':
|
|
1264
|
+
console.log(`# ccconfig bash completion
|
|
1265
|
+
_ccconfig_completions() {
|
|
1266
|
+
local cur prev commands profiles
|
|
1267
|
+
COMPREPLY=()
|
|
1268
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
1269
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
1270
|
+
commands="${commands}"
|
|
1271
|
+
|
|
1272
|
+
# Get available profiles
|
|
1273
|
+
if [ -f ~/.config/ccconfig/profiles.json ]; then
|
|
1274
|
+
profiles=$(node -e "try { const data = require(process.env.HOME + '/.config/ccconfig/profiles.json'); console.log(Object.keys(data.profiles || {}).join(' ')); } catch(e) { }" 2>/dev/null)
|
|
1275
|
+
fi
|
|
1276
|
+
|
|
1277
|
+
case "\${COMP_CWORD}" in
|
|
1278
|
+
1)
|
|
1279
|
+
COMPREPLY=( $(compgen -W "\${commands}" -- \${cur}) )
|
|
1280
|
+
;;
|
|
1281
|
+
2)
|
|
1282
|
+
case "\${prev}" in
|
|
1283
|
+
use|update|remove|rm)
|
|
1284
|
+
COMPREPLY=( $(compgen -W "\${profiles}" -- \${cur}) )
|
|
1285
|
+
;;
|
|
1286
|
+
mode)
|
|
1287
|
+
COMPREPLY=( $(compgen -W "settings env" -- \${cur}) )
|
|
1288
|
+
;;
|
|
1289
|
+
env)
|
|
1290
|
+
COMPREPLY=( $(compgen -W "bash zsh fish sh powershell pwsh dotenv" -- \${cur}) )
|
|
1291
|
+
;;
|
|
1292
|
+
esac
|
|
1293
|
+
;;
|
|
1294
|
+
3)
|
|
1295
|
+
case "\${COMP_WORDS[1]}" in
|
|
1296
|
+
use)
|
|
1297
|
+
COMPREPLY=( $(compgen -W "--permanent -p" -- \${cur}) )
|
|
1298
|
+
;;
|
|
1299
|
+
current)
|
|
1300
|
+
COMPREPLY=( $(compgen -W "--show-secret -s" -- \${cur}) )
|
|
1301
|
+
;;
|
|
1302
|
+
esac
|
|
1303
|
+
;;
|
|
1304
|
+
esac
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
complete -F _ccconfig_completions ccconfig
|
|
1308
|
+
`);
|
|
1309
|
+
break;
|
|
1310
|
+
|
|
1311
|
+
case 'zsh':
|
|
1312
|
+
console.log(`# ccconfig zsh completion
|
|
1313
|
+
_ccconfig() {
|
|
1314
|
+
local -a commands profiles modes formats
|
|
1315
|
+
commands=(
|
|
1316
|
+
'list:List all configurations'
|
|
1317
|
+
'ls:List all configurations'
|
|
1318
|
+
'add:Add new configuration'
|
|
1319
|
+
'update:Update existing configuration'
|
|
1320
|
+
'use:Switch to specified configuration'
|
|
1321
|
+
'remove:Remove configuration'
|
|
1322
|
+
'rm:Remove configuration'
|
|
1323
|
+
'current:Display current configuration'
|
|
1324
|
+
'mode:View or switch mode'
|
|
1325
|
+
'env:Output environment variables'
|
|
1326
|
+
'edit:Show configuration file location'
|
|
1327
|
+
)
|
|
1328
|
+
|
|
1329
|
+
modes=('settings' 'env')
|
|
1330
|
+
formats=('bash' 'zsh' 'fish' 'sh' 'powershell' 'pwsh' 'dotenv')
|
|
1331
|
+
|
|
1332
|
+
# Get available profiles
|
|
1333
|
+
if [ -f ~/.config/ccconfig/profiles.json ]; then
|
|
1334
|
+
profiles=($(node -e "try { const data = require(process.env.HOME + '/.config/ccconfig/profiles.json'); console.log(Object.keys(data.profiles || {}).join(' ')); } catch(e) { }" 2>/dev/null))
|
|
1335
|
+
fi
|
|
1336
|
+
|
|
1337
|
+
case $CURRENT in
|
|
1338
|
+
2)
|
|
1339
|
+
_describe 'command' commands
|
|
1340
|
+
;;
|
|
1341
|
+
3)
|
|
1342
|
+
case $words[2] in
|
|
1343
|
+
use|update|remove|rm)
|
|
1344
|
+
_describe 'profile' profiles
|
|
1345
|
+
;;
|
|
1346
|
+
mode)
|
|
1347
|
+
_describe 'mode' modes
|
|
1348
|
+
;;
|
|
1349
|
+
env)
|
|
1350
|
+
_describe 'format' formats
|
|
1351
|
+
;;
|
|
1352
|
+
esac
|
|
1353
|
+
;;
|
|
1354
|
+
4)
|
|
1355
|
+
case $words[2] in
|
|
1356
|
+
use)
|
|
1357
|
+
_arguments '-p[Write permanently to shell config]' '--permanent[Write permanently to shell config]'
|
|
1358
|
+
;;
|
|
1359
|
+
current)
|
|
1360
|
+
_arguments '-s[Show full token]' '--show-secret[Show full token]'
|
|
1361
|
+
;;
|
|
1362
|
+
esac
|
|
1363
|
+
;;
|
|
1364
|
+
esac
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
compdef _ccconfig ccconfig
|
|
1368
|
+
`);
|
|
1369
|
+
break;
|
|
1370
|
+
|
|
1371
|
+
case 'fish':
|
|
1372
|
+
console.log(`# ccconfig fish completion
|
|
1373
|
+
|
|
1374
|
+
# Commands
|
|
1375
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "list" -d "List all configurations"
|
|
1376
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "ls" -d "List all configurations"
|
|
1377
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "add" -d "Add new configuration"
|
|
1378
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "update" -d "Update existing configuration"
|
|
1379
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "use" -d "Switch to specified configuration"
|
|
1380
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "remove" -d "Remove configuration"
|
|
1381
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "rm" -d "Remove configuration"
|
|
1382
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "current" -d "Display current configuration"
|
|
1383
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "mode" -d "View or switch mode"
|
|
1384
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "env" -d "Output environment variables"
|
|
1385
|
+
complete -c ccconfig -f -n "__fish_use_subcommand" -a "edit" -d "Show configuration file location"
|
|
1386
|
+
|
|
1387
|
+
# Get profile names dynamically
|
|
1388
|
+
function __ccconfig_profiles
|
|
1389
|
+
if test -f ~/.config/ccconfig/profiles.json
|
|
1390
|
+
node -e "try { const data = require(process.env.HOME + '/.config/ccconfig/profiles.json'); Object.keys(data.profiles || {}).forEach(k => console.log(k)); } catch(e) { }" 2>/dev/null
|
|
1391
|
+
end
|
|
1392
|
+
end
|
|
1393
|
+
|
|
1394
|
+
# Profile name completion for use, update, remove
|
|
1395
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from use update remove rm" -a "(__ccconfig_profiles)"
|
|
1396
|
+
|
|
1397
|
+
# Mode options
|
|
1398
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from mode" -a "settings env"
|
|
1399
|
+
|
|
1400
|
+
# Env format options
|
|
1401
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from env" -a "bash zsh fish sh powershell pwsh dotenv"
|
|
1402
|
+
|
|
1403
|
+
# Flags for use command
|
|
1404
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from use" -s p -l permanent -d "Write permanently to shell config"
|
|
1405
|
+
|
|
1406
|
+
# Flags for current command
|
|
1407
|
+
complete -c ccconfig -f -n "__fish_seen_subcommand_from current" -s s -l show-secret -d "Show full token"
|
|
1408
|
+
|
|
1409
|
+
# Global flags
|
|
1410
|
+
complete -c ccconfig -f -s h -l help -d "Display help information"
|
|
1411
|
+
complete -c ccconfig -f -s V -l version -d "Display version information"
|
|
1412
|
+
`);
|
|
1413
|
+
break;
|
|
1414
|
+
|
|
1415
|
+
case 'powershell':
|
|
1416
|
+
case 'pwsh':
|
|
1417
|
+
console.log(`# ccconfig PowerShell completion
|
|
1418
|
+
|
|
1419
|
+
# Get available profiles
|
|
1420
|
+
function Get-CconfigProfiles {
|
|
1421
|
+
$profilesPath = Join-Path $env:USERPROFILE ".config\\ccconfig\\profiles.json"
|
|
1422
|
+
if (Test-Path $profilesPath) {
|
|
1423
|
+
try {
|
|
1424
|
+
$profiles = Get-Content $profilesPath | ConvertFrom-Json
|
|
1425
|
+
return $profiles.profiles.PSObject.Properties.Name
|
|
1426
|
+
} catch {
|
|
1427
|
+
return @()
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
return @()
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
# Register argument completer for ccconfig
|
|
1434
|
+
Register-ArgumentCompleter -Native -CommandName ccconfig -ScriptBlock {
|
|
1435
|
+
param($wordToComplete, $commandAst, $cursorPosition)
|
|
1436
|
+
|
|
1437
|
+
$commands = @('list', 'ls', 'add', 'update', 'use', 'remove', 'rm', 'current', 'mode', 'env', 'edit', 'completion')
|
|
1438
|
+
$modes = @('settings', 'env')
|
|
1439
|
+
$formats = @('bash', 'zsh', 'fish', 'sh', 'powershell', 'pwsh', 'dotenv')
|
|
1440
|
+
|
|
1441
|
+
# Parse the command line
|
|
1442
|
+
$tokens = $commandAst.ToString() -split '\\s+'
|
|
1443
|
+
$position = $tokens.Count - 1
|
|
1444
|
+
|
|
1445
|
+
# If we're completing the first argument (command)
|
|
1446
|
+
if ($position -eq 1 -or ($position -eq 2 -and $wordToComplete)) {
|
|
1447
|
+
$commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1448
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1449
|
+
}
|
|
1450
|
+
return
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
# Get the command (first argument)
|
|
1454
|
+
$command = if ($tokens.Count -gt 1) { $tokens[1] } else { '' }
|
|
1455
|
+
|
|
1456
|
+
# Second argument completions based on command
|
|
1457
|
+
if ($position -eq 2 -or ($position -eq 3 -and $wordToComplete)) {
|
|
1458
|
+
switch ($command) {
|
|
1459
|
+
{ $_ -in 'use', 'update', 'remove', 'rm' } {
|
|
1460
|
+
Get-CconfigProfiles | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1461
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1462
|
+
}
|
|
1463
|
+
}
|
|
1464
|
+
'mode' {
|
|
1465
|
+
$modes | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1466
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
'env' {
|
|
1470
|
+
$formats | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1471
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
'completion' {
|
|
1475
|
+
@('bash', 'zsh', 'fish', 'powershell', 'pwsh') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1476
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
}
|
|
1480
|
+
return
|
|
1481
|
+
}
|
|
1482
|
+
|
|
1483
|
+
# Flag completions
|
|
1484
|
+
if ($position -ge 3 -and $command -eq 'use') {
|
|
1485
|
+
@('-p', '--permanent') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1486
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', 'Write permanently to shell config')
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
|
|
1490
|
+
if ($position -ge 2 -and $command -eq 'current') {
|
|
1491
|
+
@('-s', '--show-secret') | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
|
|
1492
|
+
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', 'Show full token')
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
`);
|
|
1497
|
+
break;
|
|
1498
|
+
|
|
1499
|
+
default:
|
|
1500
|
+
console.error(`Error: Unsupported shell: ${shell}`);
|
|
1501
|
+
console.error('Supported shells: bash, zsh, fish, powershell, pwsh');
|
|
1502
|
+
process.exit(1);
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
|
|
1077
1506
|
/**
|
|
1078
1507
|
* Display help information
|
|
1079
1508
|
*/
|
|
@@ -1102,6 +1531,8 @@ function help() {
|
|
|
1102
1531
|
' list|ls List all configurations (default)');
|
|
1103
1532
|
console.log(
|
|
1104
1533
|
' add [name] Add new configuration (interactive)');
|
|
1534
|
+
console.log(
|
|
1535
|
+
' update [name] Update existing configuration (interactive)');
|
|
1105
1536
|
console.log(
|
|
1106
1537
|
' use <name> [-p|--permanent] Switch to specified configuration');
|
|
1107
1538
|
console.log(
|
|
@@ -1114,6 +1545,8 @@ function help() {
|
|
|
1114
1545
|
' env [format] Output environment variables (env mode)');
|
|
1115
1546
|
console.log(
|
|
1116
1547
|
' edit Show configuration file location');
|
|
1548
|
+
console.log(
|
|
1549
|
+
' completion <bash|zsh|fish|pwsh> Generate shell completion script');
|
|
1117
1550
|
console.log('');
|
|
1118
1551
|
console.log('Flags:');
|
|
1119
1552
|
console.log(
|
|
@@ -1170,6 +1603,9 @@ async function main() {
|
|
|
1170
1603
|
case 'add':
|
|
1171
1604
|
await add(filteredArgs[1]);
|
|
1172
1605
|
break;
|
|
1606
|
+
case 'update':
|
|
1607
|
+
await update(filteredArgs[1]);
|
|
1608
|
+
break;
|
|
1173
1609
|
case 'remove':
|
|
1174
1610
|
case 'rm':
|
|
1175
1611
|
remove(filteredArgs[1]);
|
|
@@ -1186,6 +1622,9 @@ async function main() {
|
|
|
1186
1622
|
case 'edit':
|
|
1187
1623
|
edit();
|
|
1188
1624
|
break;
|
|
1625
|
+
case 'completion':
|
|
1626
|
+
completion(filteredArgs[1]);
|
|
1627
|
+
break;
|
|
1189
1628
|
default:
|
|
1190
1629
|
if (!command) {
|
|
1191
1630
|
list();
|