@cc-x/cc-x 0.3.0 → 0.4.3
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.en.md +64 -32
- package/README.md +59 -25
- package/dist/config/store.js +1 -1
- package/dist/config/types.js +0 -1
- package/dist/i18n/messages.js +4 -4
- package/dist/ui/edit.js +2 -1
- package/dist/ui/menus.js +2 -1
- package/dist/ui/pickers.js +5 -3
- package/dist/ui/select.js +4 -3
- package/package.json +9 -2
package/README.en.md
CHANGED
|
@@ -11,9 +11,10 @@ purely through environment variables, so it is **physically incapable of clobber
|
|
|
11
11
|
plugins, or hooks** — and it lets **multiple terminals each run a different API at the
|
|
12
12
|
same time, without interfering with one another**.
|
|
13
13
|
|
|
14
|
-
>
|
|
15
|
-
>
|
|
16
|
-
>
|
|
14
|
+
> **Native Go build:** GitHub Releases provide a lightweight `xx` / `xx.exe` with no
|
|
15
|
+
> Node.js requirement for Windows x64, macOS Intel / Apple Silicon, and Linux x64 / arm64.
|
|
16
|
+
> If you prefer npm, `npm install -g @cc-x/cc-x` is still available (the terminal command
|
|
17
|
+
> is still `xx`).
|
|
17
18
|
|
|
18
19
|
---
|
|
19
20
|
|
|
@@ -67,18 +68,43 @@ place, or prefer an all-in-one tool.
|
|
|
67
68
|
|
|
68
69
|
## Requirements
|
|
69
70
|
|
|
70
|
-
- **
|
|
71
|
-
|
|
71
|
+
- **Native Go build:** Windows 10/11 x64, macOS Intel / Apple Silicon, Linux x64 / arm64;
|
|
72
|
+
no Node.js required.
|
|
73
|
+
- **Cross-platform npm build:** Node.js ≥ 18 (package `@cc-x/cc-x`).
|
|
72
74
|
- **Claude Code installed (`claude` on PATH)** — "Use this session" launches `claude`.
|
|
73
|
-
- *(optional, legacy)* PowerShell 7+ — the PowerShell edition is still offered on Windows.
|
|
74
|
-
|
|
75
|
-
> Fully verified on **Windows**; "Set as default" on **macOS / Linux** (writing the shell
|
|
76
|
-
> startup file) is the new cross-platform capability, while "Use this session" is identical
|
|
77
|
-
> everywhere. Feedback on other platforms is welcome.
|
|
78
75
|
|
|
79
76
|
## Install
|
|
80
77
|
|
|
81
|
-
**
|
|
78
|
+
**Native Windows build (recommended)**
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
irm https://github.com/becomeless/cc-x/releases/latest/download/install.ps1 | iex
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The installer downloads the latest GitHub Release asset named `ccx_*_windows_amd64.zip`,
|
|
85
|
+
installs it to `%LOCALAPPDATA%\Programs\ccx`, and adds that directory to the user PATH.
|
|
86
|
+
Open a new terminal afterwards and run:
|
|
87
|
+
|
|
88
|
+
```powershell
|
|
89
|
+
xx --version
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Native macOS / Linux build (recommended)**
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
curl -fsSL https://github.com/becomeless/cc-x/releases/latest/download/install.sh | sh
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The installer downloads the matching `ccx_*_darwin_*.tar.gz` or `ccx_*_linux_*.tar.gz`
|
|
99
|
+
asset, installs `xx` to `~/.local/bin` (override with `CCX_INSTALL_DIR` or
|
|
100
|
+
`--install-dir`), and verifies `checksums.txt` when available. If that directory is not
|
|
101
|
+
on PATH, add it as prompted, open a new terminal, and run:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
xx --version
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Cross-platform npm build**
|
|
82
108
|
|
|
83
109
|
```bash
|
|
84
110
|
npm install -g @cc-x/cc-x
|
|
@@ -87,24 +113,26 @@ npm install -g @cc-x/cc-x
|
|
|
87
113
|
Then type `xx` in any terminal. Update with `npm update -g @cc-x/cc-x`; remove with
|
|
88
114
|
`npm uninstall -g @cc-x/cc-x`. (The npm package is `@cc-x/cc-x`; the terminal command is `xx`.)
|
|
89
115
|
|
|
90
|
-
**
|
|
116
|
+
**From source (dev / custom)**
|
|
91
117
|
|
|
92
|
-
```
|
|
93
|
-
|
|
118
|
+
```bash
|
|
119
|
+
git clone https://github.com/becomeless/cc-x
|
|
120
|
+
cd cc-x
|
|
94
121
|
```
|
|
95
122
|
|
|
96
|
-
|
|
97
|
-
remove with `Uninstall-Module ccx`.
|
|
123
|
+
Native Go release build with version injection and multi-platform assets:
|
|
98
124
|
|
|
99
|
-
|
|
125
|
+
```powershell
|
|
126
|
+
.\scripts\build-release.ps1 -Version 0.4.2
|
|
127
|
+
.\dist\release\ccx_0.4.2_windows_amd64\xx.exe --version
|
|
128
|
+
```
|
|
100
129
|
|
|
101
|
-
|
|
102
|
-
# npm edition
|
|
103
|
-
git clone https://github.com/becomeless/cc-x
|
|
104
|
-
cd ccx && npm install && npm run build && npm link # then `xx` is available
|
|
130
|
+
npm build:
|
|
105
131
|
|
|
106
|
-
|
|
107
|
-
|
|
132
|
+
```bash
|
|
133
|
+
npm install
|
|
134
|
+
npm run build
|
|
135
|
+
npm link # then `xx` is available
|
|
108
136
|
```
|
|
109
137
|
|
|
110
138
|
**Open a new terminal afterwards.**
|
|
@@ -130,8 +158,8 @@ scopes:
|
|
|
130
158
|
| Effect on other / running sessions | **None** | **None** (env is fixed at process start) |
|
|
131
159
|
| Typical use | Parallel terminals, each on a different API | Your usual "main" API |
|
|
132
160
|
|
|
133
|
-
**Parallel example:** open 4 terminals and run `xx 官方 -
|
|
134
|
-
`xx 智谱GLM -
|
|
161
|
+
**Parallel example:** open 4 terminals and run `xx 官方 -s`, `xx DeepSeek -s`,
|
|
162
|
+
`xx 智谱GLM -s`, `xx 小米MiMo -s` — four Claude sessions running at once, each
|
|
135
163
|
on its own API, independent.
|
|
136
164
|
|
|
137
165
|
**Why not switch via a global config file?** Because `settings.json` is global and editing
|
|
@@ -153,7 +181,7 @@ up/down and reorder** — saved instantly:
|
|
|
153
181
|
- **Delete** — removes the profile (with confirmation; keep "官方").
|
|
154
182
|
- **Back**.
|
|
155
183
|
- **+ New profile**.
|
|
156
|
-
-
|
|
184
|
+
- **语言 / Language** — toggle the UI between English and Chinese instantly (remembered;
|
|
157
185
|
written back to `lang` in `~/.cc-mini/providers.json`).
|
|
158
186
|
- **Quit**.
|
|
159
187
|
|
|
@@ -179,9 +207,6 @@ xx --lang en # UI in English for this run (zh / en)
|
|
|
179
207
|
xx --help # show all options
|
|
180
208
|
```
|
|
181
209
|
|
|
182
|
-
- The **npm edition** uses `-s/--session`, `-l/--list`, `--lang`, `--help`; the **PowerShell
|
|
183
|
-
edition** uses `-Session`, `-List` (no `--lang`).
|
|
184
|
-
|
|
185
210
|
## Profile fields
|
|
186
211
|
|
|
187
212
|
| Field | Env var | Notes |
|
|
@@ -312,9 +337,16 @@ not support it. DeepSeek recommends `max`; leave others empty.
|
|
|
312
337
|
|
|
313
338
|
- **Clear env vars first**: run `xx` → Set as default → 官方 to clear all managed variables.
|
|
314
339
|
- Remove the tool itself:
|
|
315
|
-
-
|
|
316
|
-
|
|
317
|
-
|
|
340
|
+
- native Windows build: delete `%LOCALAPPDATA%\Programs\ccx` and remove that directory
|
|
341
|
+
from the user PATH, or run:
|
|
342
|
+
```powershell
|
|
343
|
+
powershell -NoProfile -ExecutionPolicy Bypass -Command "$s = irm https://github.com/becomeless/cc-x/releases/latest/download/install.ps1; & ([scriptblock]::Create($s)) -Uninstall"
|
|
344
|
+
```
|
|
345
|
+
- native macOS / Linux build:
|
|
346
|
+
```bash
|
|
347
|
+
curl -fsSL https://github.com/becomeless/cc-x/releases/latest/download/install.sh | sh -s -- --uninstall
|
|
348
|
+
```
|
|
349
|
+
- npm build: `npm uninstall -g @cc-x/cc-x`;
|
|
318
350
|
- on macOS / Linux, also remove the `# >>> xx >>>` marker block from your shell startup file
|
|
319
351
|
if you ever used "Set as default".
|
|
320
352
|
- Delete the data dir `~/.cc-mini/`.
|
package/README.md
CHANGED
|
@@ -8,8 +8,9 @@ Anthropic 兼容 API(DeepSeek、智谱 GLM、小米 MiMo 等)之间快速切
|
|
|
8
8
|
它最大的不同:**不写任何 Claude Code 配置文件**,切换只靠环境变量——所以从设计上**不可能弄丢你的
|
|
9
9
|
MCP / 插件 / hooks**;并且支持**多个终端同时各用各的 API、互不干扰**。
|
|
10
10
|
|
|
11
|
-
>
|
|
12
|
-
>
|
|
11
|
+
> **Go 原生版**:GitHub Release 提供轻量 `xx` / `xx.exe`,不需要 Node.js,覆盖
|
|
12
|
+
> Windows x64、macOS Intel / Apple Silicon、Linux x64 / arm64。偏好 npm 的用户仍可使用
|
|
13
|
+
> `npm install -g @cc-x/cc-x`(命令仍是 `xx`)。
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
@@ -85,16 +86,40 @@ Codex / Gemini 等多个 CLI,它更合适。ccx 走相反的**极简路线**
|
|
|
85
86
|
|
|
86
87
|
## 环境要求
|
|
87
88
|
|
|
88
|
-
- **
|
|
89
|
+
- **Go 原生版**:Windows 10/11 x64、macOS Intel / Apple Silicon、Linux x64 / arm64;不需要 Node.js。
|
|
90
|
+
- **npm 全平台版**:Node.js ≥ 18(包名 `@cc-x/cc-x`)。
|
|
89
91
|
- **已安装 Claude Code(`claude` 命令在 PATH 中)**:「本次启用」会直接调用 `claude`。
|
|
90
|
-
- *(可选,旧版)* PowerShell 7+:Windows 上仍保留 PowerShell 版。
|
|
91
|
-
|
|
92
|
-
> 当前在 **Windows** 上完整验证;**macOS / Linux** 的「设为默认」(写 shell 启动文件)是跨平台新增能力,
|
|
93
|
-
> 「本次启用」全平台一致。欢迎在其它平台试用并反馈。
|
|
94
92
|
|
|
95
93
|
## 安装
|
|
96
94
|
|
|
97
|
-
|
|
95
|
+
**Windows 原生版(推荐)**
|
|
96
|
+
|
|
97
|
+
```powershell
|
|
98
|
+
irm https://github.com/becomeless/cc-x/releases/latest/download/install.ps1 | iex
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
安装器会下载最新 GitHub Release 里的 `ccx_*_windows_amd64.zip`,安装到
|
|
102
|
+
`%LOCALAPPDATA%\Programs\ccx`,并把该目录加入用户 PATH。安装后新开终端,运行:
|
|
103
|
+
|
|
104
|
+
```powershell
|
|
105
|
+
xx --version
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**macOS / Linux 原生版(推荐)**
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
curl -fsSL https://github.com/becomeless/cc-x/releases/latest/download/install.sh | sh
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
安装器会按当前系统下载 `ccx_*_darwin_*.tar.gz` 或 `ccx_*_linux_*.tar.gz`,安装到
|
|
115
|
+
`~/.local/bin`(可用 `CCX_INSTALL_DIR` 或 `--install-dir` 改目录),并校验 `checksums.txt`。
|
|
116
|
+
如果该目录不在 PATH,按提示加入后新开终端,运行:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
xx --version
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**npm 全平台版**
|
|
98
123
|
|
|
99
124
|
```bash
|
|
100
125
|
npm install -g @cc-x/cc-x
|
|
@@ -103,23 +128,26 @@ npm install -g @cc-x/cc-x
|
|
|
103
128
|
装好后在任意终端敲 `xx` 即可。升级:`npm update -g @cc-x/cc-x`;卸载:`npm uninstall -g @cc-x/cc-x`。
|
|
104
129
|
(npm 包名是 `@cc-x/cc-x`,终端命令是 `xx`。)
|
|
105
130
|
|
|
106
|
-
|
|
131
|
+
**从源码(开发 / 自定义)**
|
|
107
132
|
|
|
108
|
-
```
|
|
109
|
-
|
|
133
|
+
```bash
|
|
134
|
+
git clone https://github.com/becomeless/cc-x
|
|
135
|
+
cd cc-x
|
|
110
136
|
```
|
|
111
137
|
|
|
112
|
-
|
|
138
|
+
Go 原生 Release 构建(注入版本号并生成多平台资产):
|
|
139
|
+
|
|
140
|
+
```powershell
|
|
141
|
+
.\scripts\build-release.ps1 -Version 0.4.2
|
|
142
|
+
.\dist\release\ccx_0.4.2_windows_amd64\xx.exe --version
|
|
143
|
+
```
|
|
113
144
|
|
|
114
|
-
|
|
145
|
+
npm 版开发:
|
|
115
146
|
|
|
116
147
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
# 或 PowerShell 旧版
|
|
122
|
-
pwsh -ExecutionPolicy Bypass -File .\ccx\install.ps1 # 在 $PROFILE 注册 xx 函数(幂等)
|
|
148
|
+
npm install
|
|
149
|
+
npm run build
|
|
150
|
+
npm link # 之后 xx 可用
|
|
123
151
|
```
|
|
124
152
|
|
|
125
153
|
**安装后请新开一个终端。**
|
|
@@ -144,8 +172,8 @@ pwsh -ExecutionPolicy Bypass -File .\ccx\install.ps1 # 在 $PROFILE 注册 xx
|
|
|
144
172
|
| 对其它 / 运行中会话 | **零影响** | **零影响**(环境变量在进程启动时定型,运行中不会变) |
|
|
145
173
|
| 典型场景 | 多终端并行,各用各 API 互不干扰 | 设定你最常用的“主力 API” |
|
|
146
174
|
|
|
147
|
-
**并行多终端示例**:你可以同时开 4 个终端,分别 `xx 官方 -
|
|
148
|
-
`xx 智谱GLM -
|
|
175
|
+
**并行多终端示例**:你可以同时开 4 个终端,分别 `xx 官方 -s`、`xx DeepSeek -s`、
|
|
176
|
+
`xx 智谱GLM -s`、`xx 小米MiMo -s`,得到 4 个同时运行、各用各 API、互不干扰的 Claude。
|
|
149
177
|
|
|
150
178
|
**为什么不用全局配置文件来切?** 因为 `settings.json` 是全局共享的,改它会波及**正在运行**
|
|
151
179
|
的其它会话(典型表现:另一个终端突然报 `... cannot be parsed as a URL` 之类)。ccx 用环境
|
|
@@ -163,7 +191,7 @@ pwsh -ExecutionPolicy Bypass -File .\ccx\install.ps1 # 在 $PROFILE 注册 xx
|
|
|
163
191
|
- **删除** — 删除该配置(会二次确认;建议保留「官方」)。
|
|
164
192
|
- **返回**。
|
|
165
193
|
- **+ 新增配置** — 新建一个空配置并进入编辑表单。
|
|
166
|
-
-
|
|
194
|
+
- **语言 / Language** — 中英文界面即时切换(选择会记住,写回 `~/.cc-mini/providers.json` 的 `lang`)。
|
|
167
195
|
- **退出**。
|
|
168
196
|
|
|
169
197
|
**编辑表单**:`↑↓` 选要改的字段,`Enter` 进入修改;继续往下可选「保存并返回」/「放弃修改」。
|
|
@@ -187,7 +215,6 @@ xx --help # 查看全部参数
|
|
|
187
215
|
|
|
188
216
|
- `xx <名称>`:默认是「设为默认」(写用户环境变量)。
|
|
189
217
|
- 加 `-s` / `--session`:改为「本次启用」(进程级 + 启动 Claude)。
|
|
190
|
-
- **npm 版**用 `-s/--session`、`-l/--list`、`--lang`、`--help`;**PowerShell 旧版**用 `-Session`、`-List`(无 `--lang`)。
|
|
191
218
|
|
|
192
219
|
## 配置字段说明
|
|
193
220
|
|
|
@@ -325,8 +352,15 @@ effort 是 Claude 模型特性,第三方端点未必支持。DeepSeek 官方
|
|
|
325
352
|
|
|
326
353
|
- **先清环境变量**:在 `xx` 里执行「设为默认 → 官方」一次清除全部受管变量(比手删干净)。
|
|
327
354
|
- 卸载命令本体:
|
|
328
|
-
-
|
|
329
|
-
|
|
355
|
+
- Windows 原生版:删除 `%LOCALAPPDATA%\Programs\ccx`,并从用户 PATH 移除这个目录;或运行:
|
|
356
|
+
```powershell
|
|
357
|
+
powershell -NoProfile -ExecutionPolicy Bypass -Command "$s = irm https://github.com/becomeless/cc-x/releases/latest/download/install.ps1; & ([scriptblock]::Create($s)) -Uninstall"
|
|
358
|
+
```
|
|
359
|
+
- macOS / Linux 原生版:
|
|
360
|
+
```bash
|
|
361
|
+
curl -fsSL https://github.com/becomeless/cc-x/releases/latest/download/install.sh | sh -s -- --uninstall
|
|
362
|
+
```
|
|
363
|
+
- npm 版:`npm uninstall -g @cc-x/cc-x`;
|
|
330
364
|
- macOS / Linux 若用过「设为默认」→ 顺手删掉 shell 启动文件里的 `# >>> xx >>>` 标记块。
|
|
331
365
|
- 删除数据目录 `~/.cc-mini/`。
|
|
332
366
|
|
package/dist/config/store.js
CHANGED
|
@@ -62,7 +62,7 @@ export function defaultStore() {
|
|
|
62
62
|
/**
|
|
63
63
|
* 把任意解析结果规整为合法 Store。
|
|
64
64
|
*
|
|
65
|
-
* 字段级**宽松容错**(缺 lang / 缺 note / 缺 builtin / 缺 env
|
|
65
|
+
* 字段级**宽松容错**(缺 lang / 缺 note / 缺 builtin / 缺 env 都不报错),保持既有数据格式兼容;
|
|
66
66
|
* 但结构级**严格校验**:顶层必须是对象、`providers` 必须是数组、每个配置的 name/env 结构必须合法
|
|
67
67
|
* —— 否则抛 StoreError('format')。
|
|
68
68
|
* 这是为了堵住「语法合法但结构损坏的 JSON 被静默规整成空 providers、用户一保存就覆盖丢数据」的坑([P1])。
|
package/dist/config/types.js
CHANGED
package/dist/i18n/messages.js
CHANGED
|
@@ -36,7 +36,7 @@ export const messages = {
|
|
|
36
36
|
zh: '↑↓ 选择 · Enter 进入 · Shift+↑↓(或 PgUp/PgDn)排序 · q 退出',
|
|
37
37
|
en: '↑↓ move · Enter open · Shift+↑↓ (or PgUp/PgDn) reorder · q quit',
|
|
38
38
|
},
|
|
39
|
-
'menu.newProfile': { zh: '
|
|
39
|
+
'menu.newProfile': { zh: '新增配置', en: 'New profile' },
|
|
40
40
|
'menu.exit': { zh: '退出', en: 'Exit' },
|
|
41
41
|
'menu.default': { zh: '(默认)', en: '(default)' },
|
|
42
42
|
'menu.comingSoon': { zh: '(该功能下一步实现)', en: '(coming in the next step)' },
|
|
@@ -56,7 +56,7 @@ export const messages = {
|
|
|
56
56
|
'action.hint': { zh: '↑↓ 选择 · Enter 确认 · q 返回', en: '↑↓ move · Enter select · q back' },
|
|
57
57
|
'action.deleteConfirm': { zh: '确认删除 [{0}]? (y/N): ', en: 'Delete [{0}]? (y/N): ' },
|
|
58
58
|
'action.deleteOfficialWarn': { zh: '建议保留『官方』。', en: 'Keeping "Official" is recommended.' },
|
|
59
|
-
'menu.language': { zh: '
|
|
59
|
+
'menu.language': { zh: '切换到 English', en: '切换到中文' },
|
|
60
60
|
// —— 通用占位 ——
|
|
61
61
|
'empty.paren': { zh: '(空)', en: '(empty)' },
|
|
62
62
|
// —— 编辑表单 ——
|
|
@@ -76,8 +76,8 @@ export const messages = {
|
|
|
76
76
|
'edit.field.sonnet': { zh: 'sonnet→ 模型 ', en: 'sonnet→ model ' },
|
|
77
77
|
'edit.field.haiku': { zh: 'haiku → 模型 ', en: 'haiku → model ' },
|
|
78
78
|
'edit.field.effort': { zh: 'effort 思考档 ', en: 'effort level ' },
|
|
79
|
-
'edit.toggleSecretShow': { zh: '
|
|
80
|
-
'edit.toggleSecretHide': { zh: '
|
|
79
|
+
'edit.toggleSecretShow': { zh: '显示密钥明文(当前隐藏)', en: 'Show key in plaintext (now hidden)' },
|
|
80
|
+
'edit.toggleSecretHide': { zh: '隐藏密钥(当前明文)', en: 'Hide key (now shown)' },
|
|
81
81
|
'edit.save': { zh: '保存并返回', en: 'Save & back' },
|
|
82
82
|
'edit.discard': { zh: '放弃修改', en: 'Discard' },
|
|
83
83
|
'edit.nameEmpty': { zh: '还没选供应商(或自定义名称),未保存。', en: 'No provider/name chosen yet; not saved.' },
|
package/dist/ui/edit.js
CHANGED
|
@@ -42,12 +42,13 @@ export async function editForm(prov, store, catalog) {
|
|
|
42
42
|
{ action: 'sonnet', label: `${T('edit.field.sonnet')}: ${v(W.sonnet)}` },
|
|
43
43
|
{ action: 'haiku', label: `${T('edit.field.haiku')}: ${v(W.haiku)}` },
|
|
44
44
|
{ action: 'effort', label: `${T('edit.field.effort')}: ${v(W.effort)}` },
|
|
45
|
+
{ action: 'sep', label: '' },
|
|
45
46
|
{ action: 'toggle', label: showSecret ? T('edit.toggleSecretHide') : T('edit.toggleSecretShow') },
|
|
46
47
|
{ action: 'sep', label: '' },
|
|
47
48
|
{ action: 'save', label: T('edit.save') },
|
|
48
49
|
{ action: 'discard', label: T('edit.discard') },
|
|
49
50
|
];
|
|
50
|
-
const sel = await selectMenu({ title: T('edit.title'), items: rows.map((r) => r.label), start, hint: T('edit.hint') });
|
|
51
|
+
const sel = await selectMenu({ title: T('edit.title'), items: rows.map((r) => r.label), start, hint: T('edit.hint'), noNumber: true });
|
|
51
52
|
if (sel < 0)
|
|
52
53
|
return false; // Esc / q = 放弃
|
|
53
54
|
start = sel;
|
package/dist/ui/menus.js
CHANGED
|
@@ -51,6 +51,7 @@ export async function openMenu(paths, store, scope, version, catalog) {
|
|
|
51
51
|
movableCount: n,
|
|
52
52
|
onMove,
|
|
53
53
|
hint: T('menu.mainHint'),
|
|
54
|
+
noNumber: true,
|
|
54
55
|
});
|
|
55
56
|
if (sel < 0 || sel === n + 4)
|
|
56
57
|
return; // 退出 / Esc / q
|
|
@@ -87,7 +88,7 @@ async function actionMenu(paths, store, p, scope, catalog) {
|
|
|
87
88
|
const dft = p.name === store.current ? T('menu.default') : '';
|
|
88
89
|
const title = `${T('action.titlePrefix')}${providerDisplayName(p)}${dft}${noteSuffix(p)} [${stateLabel(p)}]`;
|
|
89
90
|
const items = [T('action.session'), T('action.setDefault'), T('action.edit'), T('action.delete'), T('action.back')];
|
|
90
|
-
sel = await selectMenu({ title, items, start: sel, ...(flash ? { status: flash } : {}), hint: T('action.hint') });
|
|
91
|
+
sel = await selectMenu({ title, items, start: sel, ...(flash ? { status: flash } : {}), hint: T('action.hint'), noNumber: true });
|
|
91
92
|
flash = undefined;
|
|
92
93
|
if (sel === 0) {
|
|
93
94
|
launchSession(p);
|
package/dist/ui/pickers.js
CHANGED
|
@@ -14,6 +14,7 @@ export async function pickProvider(catalog, current) {
|
|
|
14
14
|
title: T('pick.provider.title', current || T('pick.provider.none')),
|
|
15
15
|
items,
|
|
16
16
|
hint: T('pick.hint'),
|
|
17
|
+
noNumber: true,
|
|
17
18
|
});
|
|
18
19
|
if (sel < 0 || sel === items.length - 1)
|
|
19
20
|
return null;
|
|
@@ -30,7 +31,7 @@ export async function pickProviderUrl(preset, current) {
|
|
|
30
31
|
return urls[0]?.url ?? current;
|
|
31
32
|
const labels = urls.map((u) => `${padDisplay(u.label, 12)} ${u.url || T('empty.paren')}`);
|
|
32
33
|
const items = [...labels, T('pick.noChange')];
|
|
33
|
-
const sel = await selectMenu({ title: T('pick.providerUrl.title', preset.name), items, hint: T('pick.hint') });
|
|
34
|
+
const sel = await selectMenu({ title: T('pick.providerUrl.title', preset.name), items, hint: T('pick.hint'), noNumber: true });
|
|
34
35
|
if (sel < 0 || sel === items.length - 1)
|
|
35
36
|
return current;
|
|
36
37
|
return urls[sel]?.url ?? current;
|
|
@@ -54,7 +55,7 @@ export async function pickBaseUrl(current, store, catalog) {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
const items = [...entries.map((e) => e.label), T('pick.manual'), T('pick.noChange')];
|
|
57
|
-
const sel = await selectMenu({ title: T('pick.base.title', current || T('empty.paren')), items, hint: T('pick.hint') });
|
|
58
|
+
const sel = await selectMenu({ title: T('pick.base.title', current || T('empty.paren')), items, hint: T('pick.hint'), noNumber: true });
|
|
58
59
|
if (sel < 0 || sel === items.length - 1)
|
|
59
60
|
return current;
|
|
60
61
|
if (sel < entries.length)
|
|
@@ -69,7 +70,7 @@ export async function pickBaseUrl(current, store, catalog) {
|
|
|
69
70
|
/** 选认证字段:AUTH_TOKEN / API_KEY / 不改。 */
|
|
70
71
|
export async function pickAuth(current) {
|
|
71
72
|
const items = [T('pick.auth.token'), T('pick.auth.apikey'), T('pick.noChange')];
|
|
72
|
-
const sel = await selectMenu({ title: T('pick.auth.title', current), items, hint: T('pick.hint') });
|
|
73
|
+
const sel = await selectMenu({ title: T('pick.auth.title', current), items, hint: T('pick.hint'), noNumber: true });
|
|
73
74
|
if (sel === 0)
|
|
74
75
|
return 'AUTH_TOKEN';
|
|
75
76
|
if (sel === 1)
|
|
@@ -84,6 +85,7 @@ export async function pickEffort(current) {
|
|
|
84
85
|
title: T('pick.effort.title', current || T('empty.paren')),
|
|
85
86
|
items,
|
|
86
87
|
hint: T('pick.effort.hint'),
|
|
88
|
+
noNumber: true,
|
|
87
89
|
});
|
|
88
90
|
if (sel < 0 || sel === items.length - 1)
|
|
89
91
|
return current;
|
package/dist/ui/select.js
CHANGED
|
@@ -50,10 +50,11 @@ export async function selectMenu(opts) {
|
|
|
50
50
|
lines.push('');
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
|
+
const num = opts.noNumber ? '' : `${i + 1}. `; // 行首序号,与数字键直选对应
|
|
53
54
|
if (i === idx)
|
|
54
|
-
lines.push(paint(` ▶ ${it}`, 'green'));
|
|
55
|
+
lines.push(paint(` ▶ ${num}${it}`, 'green'));
|
|
55
56
|
else
|
|
56
|
-
lines.push(paint(` ${it}`, opts.colors?.[i] ?? 'none'));
|
|
57
|
+
lines.push(paint(` ${num}${it}`, opts.colors?.[i] ?? 'none'));
|
|
57
58
|
}
|
|
58
59
|
lines.push('');
|
|
59
60
|
if (opts.hint)
|
|
@@ -114,7 +115,7 @@ export async function selectMenu(opts) {
|
|
|
114
115
|
break;
|
|
115
116
|
}
|
|
116
117
|
const ch = str ?? '';
|
|
117
|
-
if (/^[0-9]$/.test(ch)) {
|
|
118
|
+
if (!opts.noNumber && /^[0-9]$/.test(ch)) {
|
|
118
119
|
const n = Number.parseInt(ch, 10);
|
|
119
120
|
if (n >= 1 && n <= items.length && items[n - 1] !== '')
|
|
120
121
|
cleanup(n - 1);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cc-x/cc-x",
|
|
3
|
-
"version": "0.3
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Claude Code API 切换器(命令 xx):在官方账号与第三方 Anthropic 兼容 API 间切换,纯环境变量、不碰 Claude Code 配置文件。",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"claude",
|
|
@@ -27,7 +27,14 @@
|
|
|
27
27
|
"xx": "dist/index.js"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
|
-
"dist",
|
|
30
|
+
"dist/**/*.js",
|
|
31
|
+
"!dist/release/**",
|
|
32
|
+
"!dist/**/*.exe",
|
|
33
|
+
"!dist/**/*.zip",
|
|
34
|
+
"!dist/**/*.md",
|
|
35
|
+
"!dist/**/*.txt",
|
|
36
|
+
"!dist/**/LICENSE",
|
|
37
|
+
"!dist/**/presets.json",
|
|
31
38
|
"presets.json",
|
|
32
39
|
"README.md",
|
|
33
40
|
"README.en.md"
|