@minniexcode/codex-switch 0.0.1 → 0.0.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.AI.md +105 -0
- package/README.CN.md +160 -0
- package/README.md +102 -111
- package/dist/app/add-provider.js +45 -0
- package/dist/app/export-providers.js +62 -0
- package/dist/app/get-current-profile.js +14 -0
- package/dist/app/get-status.js +75 -0
- package/dist/app/import-providers.js +74 -0
- package/dist/app/list-providers.js +23 -0
- package/dist/app/remove-provider.js +31 -0
- package/dist/app/rollback-latest.js +26 -0
- package/dist/app/run-doctor.js +130 -0
- package/dist/app/run-mutation.js +63 -0
- package/dist/app/switch-provider.js +43 -0
- package/dist/app/types.js +2 -0
- package/dist/cli/add-interactive.js +114 -0
- package/dist/cli/args.js +125 -0
- package/dist/cli/help.js +220 -0
- package/dist/cli/interactive.js +114 -0
- package/dist/cli/output.js +156 -0
- package/dist/cli/prompt.js +93 -0
- package/dist/cli.js +215 -26
- package/dist/domain/backup.js +2 -0
- package/dist/domain/config.js +106 -0
- package/dist/domain/errors.js +36 -0
- package/dist/domain/providers.js +92 -0
- package/dist/domain/runtime-state.js +56 -0
- package/dist/infra/backup-repo.js +151 -0
- package/dist/infra/codex-cli.js +53 -0
- package/dist/infra/codex-paths.js +58 -0
- package/dist/infra/config-repo.js +56 -0
- package/dist/infra/fs-utils.js +97 -0
- package/dist/infra/lock-repo.js +99 -0
- package/dist/infra/providers-repo.js +69 -0
- package/docs/codex-switch-command-design.md +646 -0
- package/docs/codex-switch-prd.md +24 -3
- package/docs/codex-switch-product-overview.md +2 -0
- package/docs/codex-switch-technical-architecture.md +1042 -0
- package/package.json +7 -4
|
@@ -0,0 +1,646 @@
|
|
|
1
|
+
# codex-switch 命令设计说明
|
|
2
|
+
|
|
3
|
+
## 文档信息
|
|
4
|
+
|
|
5
|
+
- 文档类型:命令设计文档
|
|
6
|
+
- 适用范围:`codex-switch` MVP
|
|
7
|
+
- 关联文档:
|
|
8
|
+
- [`codex-switch-prd.md`](./codex-switch-prd.md)
|
|
9
|
+
- [`codex-switch-technical-architecture.md`](./codex-switch-technical-architecture.md)
|
|
10
|
+
|
|
11
|
+
## 1. 文档目标
|
|
12
|
+
|
|
13
|
+
这份文档把 `codex-switch` 的每个 CLI 命令拆开描述,重点沉淀下面这些内容:
|
|
14
|
+
|
|
15
|
+
- 命令用途
|
|
16
|
+
- 输入参数
|
|
17
|
+
- 成功输出
|
|
18
|
+
- 失败错误码
|
|
19
|
+
- 关键行为语义
|
|
20
|
+
- 对 AI / 自动化调用的注意事项
|
|
21
|
+
|
|
22
|
+
这份文档是 PRD 的命令规格落地版,也是技术架构文档的命令视角补充。
|
|
23
|
+
|
|
24
|
+
## 1.1 与 `cc-switch` / `codex-auth` 的命令形态差异
|
|
25
|
+
|
|
26
|
+
为了帮助后续继续演进,这里先明确三者的命令/交互边界:
|
|
27
|
+
|
|
28
|
+
- `codex-switch`
|
|
29
|
+
- 目标是稳定 CLI 命令
|
|
30
|
+
- 聚焦 provider/profile 切换、导入导出、诊断、回滚
|
|
31
|
+
- `codex-auth`
|
|
32
|
+
- 更偏账号 / auth 管理 CLI
|
|
33
|
+
- 对本项目的参考点是命令组织方式
|
|
34
|
+
- `cc-switch`
|
|
35
|
+
- 更偏 GUI / 桌面管理器
|
|
36
|
+
- 即使内部也有切换逻辑,用户主入口不是命令行,而是桌面界面
|
|
37
|
+
|
|
38
|
+
这意味着 `codex-switch` 的命令设计原则应继续保持:
|
|
39
|
+
|
|
40
|
+
- 参数显式
|
|
41
|
+
- 输出稳定
|
|
42
|
+
- 能被 AI 和脚本直接消费
|
|
43
|
+
- 交互只作为 TTY 中的人类增强层,而不是自动化契约
|
|
44
|
+
|
|
45
|
+
## 2. 公共命令约定
|
|
46
|
+
|
|
47
|
+
### 2.1 命令入口
|
|
48
|
+
|
|
49
|
+
统一命令名:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
codexs
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 2.2 公共参数
|
|
56
|
+
|
|
57
|
+
所有支持的命令共享以下全局参数:
|
|
58
|
+
|
|
59
|
+
- `--json`
|
|
60
|
+
- 返回统一 JSON envelope
|
|
61
|
+
- `--codex-dir <path>`
|
|
62
|
+
- 指定目标工作目录
|
|
63
|
+
|
|
64
|
+
### 2.3 JSON 输出结构
|
|
65
|
+
|
|
66
|
+
统一 envelope:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"ok": true,
|
|
71
|
+
"command": "list",
|
|
72
|
+
"data": {},
|
|
73
|
+
"warnings": [],
|
|
74
|
+
"error": null
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
失败时:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"ok": false,
|
|
83
|
+
"command": "list",
|
|
84
|
+
"data": null,
|
|
85
|
+
"warnings": [],
|
|
86
|
+
"error": {
|
|
87
|
+
"code": "PROVIDERS_NOT_FOUND",
|
|
88
|
+
"message": "providers.json does not exist.",
|
|
89
|
+
"details": {
|
|
90
|
+
"file": "C:\\Users\\name\\.codex\\providers.json"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 2.4 固定错误码
|
|
97
|
+
|
|
98
|
+
当前命令层统一使用:
|
|
99
|
+
|
|
100
|
+
- `CONFIG_NOT_FOUND`
|
|
101
|
+
- `PROVIDERS_NOT_FOUND`
|
|
102
|
+
- `PROVIDERS_PARSE_ERROR`
|
|
103
|
+
- `PROVIDER_NOT_FOUND`
|
|
104
|
+
- `PROFILE_NOT_FOUND`
|
|
105
|
+
- `BACKUP_FAILED`
|
|
106
|
+
- `CODEX_LOGIN_FAILED`
|
|
107
|
+
- `ROLLBACK_FAILED`
|
|
108
|
+
- `INVALID_IMPORT_FILE`
|
|
109
|
+
|
|
110
|
+
### 2.5 渐进式交互约定
|
|
111
|
+
|
|
112
|
+
- `--json` 一律禁用交互
|
|
113
|
+
- 非 TTY 一律不进入交互
|
|
114
|
+
- 交互主要服务于人类高频写命令,不改变自动化显式参数契约
|
|
115
|
+
- 用户取消 prompt、`Ctrl+C`、或确认选择否时,不应产生任何文件写入
|
|
116
|
+
|
|
117
|
+
## 3. 命令清单概览
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
codexs list
|
|
121
|
+
codexs current
|
|
122
|
+
codexs switch <provider>
|
|
123
|
+
codexs status
|
|
124
|
+
codexs import <file>
|
|
125
|
+
codexs export <file>
|
|
126
|
+
codexs add <provider>
|
|
127
|
+
codexs remove <provider>
|
|
128
|
+
codexs doctor
|
|
129
|
+
codexs rollback
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 4. 命令逐项设计
|
|
133
|
+
|
|
134
|
+
### 4.1 `codexs list`
|
|
135
|
+
|
|
136
|
+
#### 目标
|
|
137
|
+
|
|
138
|
+
列出当前 `providers.json` 中的 provider 清单。
|
|
139
|
+
|
|
140
|
+
#### 输入
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
codexs list [--json] [--codex-dir <path>]
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
#### 成功输出
|
|
147
|
+
|
|
148
|
+
默认输出示意:
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
freemodel -> freemodel
|
|
152
|
+
packycode -> packycode tags=daily note=primary
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
JSON 输出示意:
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"ok": true,
|
|
160
|
+
"command": "list",
|
|
161
|
+
"data": {
|
|
162
|
+
"providers": [
|
|
163
|
+
{
|
|
164
|
+
"name": "freemodel",
|
|
165
|
+
"profile": "freemodel",
|
|
166
|
+
"note": null,
|
|
167
|
+
"tags": []
|
|
168
|
+
}
|
|
169
|
+
],
|
|
170
|
+
"count": 1
|
|
171
|
+
},
|
|
172
|
+
"warnings": [],
|
|
173
|
+
"error": null
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### 失败错误码
|
|
178
|
+
|
|
179
|
+
- `PROVIDERS_NOT_FOUND`
|
|
180
|
+
- `PROVIDERS_PARSE_ERROR`
|
|
181
|
+
|
|
182
|
+
#### AI 调用建议
|
|
183
|
+
|
|
184
|
+
- 优先使用 `--json`
|
|
185
|
+
- 不要依赖默认输出格式做机器解析
|
|
186
|
+
|
|
187
|
+
### 4.2 `codexs current`
|
|
188
|
+
|
|
189
|
+
#### 目标
|
|
190
|
+
|
|
191
|
+
返回当前 `config.toml` 顶层 `profile`。
|
|
192
|
+
|
|
193
|
+
#### 输入
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
codexs current [--json] [--codex-dir <path>]
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
#### 成功输出
|
|
200
|
+
|
|
201
|
+
默认:
|
|
202
|
+
|
|
203
|
+
```text
|
|
204
|
+
Current profile: packycode
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
JSON:
|
|
208
|
+
|
|
209
|
+
```json
|
|
210
|
+
{
|
|
211
|
+
"ok": true,
|
|
212
|
+
"command": "current",
|
|
213
|
+
"data": {
|
|
214
|
+
"profile": "packycode"
|
|
215
|
+
},
|
|
216
|
+
"warnings": [],
|
|
217
|
+
"error": null
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
#### 失败错误码
|
|
222
|
+
|
|
223
|
+
- `CONFIG_NOT_FOUND`
|
|
224
|
+
- `PROFILE_NOT_FOUND`
|
|
225
|
+
|
|
226
|
+
### 4.3 `codexs status`
|
|
227
|
+
|
|
228
|
+
#### 目标
|
|
229
|
+
|
|
230
|
+
给出本地配置的浅状态概览。
|
|
231
|
+
|
|
232
|
+
#### 输入
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
codexs status [--json] [--codex-dir <path>]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### 当前返回字段
|
|
239
|
+
|
|
240
|
+
- `codexDir`
|
|
241
|
+
- `configExists`
|
|
242
|
+
- `providersExists`
|
|
243
|
+
- `currentProfile`
|
|
244
|
+
- `currentProfileMapped`
|
|
245
|
+
- `provider`
|
|
246
|
+
|
|
247
|
+
#### 成功输出
|
|
248
|
+
|
|
249
|
+
JSON 示例:
|
|
250
|
+
|
|
251
|
+
```json
|
|
252
|
+
{
|
|
253
|
+
"ok": true,
|
|
254
|
+
"command": "status",
|
|
255
|
+
"data": {
|
|
256
|
+
"codexDir": "C:\\Users\\name\\.codex",
|
|
257
|
+
"configExists": true,
|
|
258
|
+
"providersExists": true,
|
|
259
|
+
"currentProfile": "packycode",
|
|
260
|
+
"currentProfileMapped": true,
|
|
261
|
+
"provider": "packycode"
|
|
262
|
+
},
|
|
263
|
+
"warnings": [],
|
|
264
|
+
"error": null
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
#### 设计说明
|
|
269
|
+
|
|
270
|
+
- `status` 是概览,不做深度建议
|
|
271
|
+
- 深度问题检测交给 `doctor`
|
|
272
|
+
|
|
273
|
+
### 4.4 `codexs switch <provider>`
|
|
274
|
+
|
|
275
|
+
#### 目标
|
|
276
|
+
|
|
277
|
+
切换到指定 provider,并默认同步更新登录状态。
|
|
278
|
+
|
|
279
|
+
#### 输入
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
codexs switch <provider> [--no-login] [--json] [--codex-dir <path>]
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### 交互行为
|
|
286
|
+
|
|
287
|
+
- 当 `<provider>` 缺失且当前是 TTY 时,先从 `providers.json` 读取 provider 列表,再用选择器选择 provider
|
|
288
|
+
- 当 `<provider>` 已显式传入时,不额外确认
|
|
289
|
+
- `--no-login` 仍保持显式 flag,不进入提问
|
|
290
|
+
|
|
291
|
+
#### 前置校验
|
|
292
|
+
|
|
293
|
+
- `providers.json` 必须存在
|
|
294
|
+
- provider 必须存在
|
|
295
|
+
- provider 对应的 `profile` 必须存在于 `config.toml`
|
|
296
|
+
|
|
297
|
+
#### 执行步骤
|
|
298
|
+
|
|
299
|
+
1. 读取 provider 数据
|
|
300
|
+
2. 校验 profile
|
|
301
|
+
3. 备份 `config.toml`
|
|
302
|
+
4. 如果存在,备份 `auth.json`
|
|
303
|
+
5. 更新顶层 `profile`
|
|
304
|
+
6. 默认执行 `codex login --with-api-key`
|
|
305
|
+
7. 成功则保存为最近一次备份
|
|
306
|
+
8. 失败则按 manifest 回滚
|
|
307
|
+
|
|
308
|
+
#### 成功输出
|
|
309
|
+
|
|
310
|
+
JSON 示例:
|
|
311
|
+
|
|
312
|
+
```json
|
|
313
|
+
{
|
|
314
|
+
"ok": true,
|
|
315
|
+
"command": "switch",
|
|
316
|
+
"data": {
|
|
317
|
+
"provider": "freemodel",
|
|
318
|
+
"profile": "freemodel",
|
|
319
|
+
"loginPerformed": true,
|
|
320
|
+
"backupPath": "C:\\Users\\name\\.codex\\backups\\20260511-221550-switch"
|
|
321
|
+
},
|
|
322
|
+
"warnings": [],
|
|
323
|
+
"error": null
|
|
324
|
+
}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
#### 失败错误码
|
|
328
|
+
|
|
329
|
+
- `PROVIDER_NOT_FOUND`
|
|
330
|
+
- `PROFILE_NOT_FOUND`
|
|
331
|
+
- `BACKUP_FAILED`
|
|
332
|
+
- `CODEX_LOGIN_FAILED`
|
|
333
|
+
- `ROLLBACK_FAILED`
|
|
334
|
+
|
|
335
|
+
#### 注意事项
|
|
336
|
+
|
|
337
|
+
- `--no-login` 仅跳过登录,不跳过备份和 profile 修改
|
|
338
|
+
- 登录失败时当前实现会附带 `rollbackApplied: true`
|
|
339
|
+
|
|
340
|
+
### 4.5 `codexs import <file>`
|
|
341
|
+
|
|
342
|
+
#### 目标
|
|
343
|
+
|
|
344
|
+
整体替换当前 `providers.json`。
|
|
345
|
+
|
|
346
|
+
#### 输入
|
|
347
|
+
|
|
348
|
+
```bash
|
|
349
|
+
codexs import <file> [--json] [--codex-dir <path>]
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
#### 行为语义
|
|
353
|
+
|
|
354
|
+
- 只支持整体替换
|
|
355
|
+
- 不支持 merge
|
|
356
|
+
- 写入前备份当前 `providers.json`
|
|
357
|
+
- 路径参数必须显式传入
|
|
358
|
+
- TTY 中实际替换前增加一次确认
|
|
359
|
+
|
|
360
|
+
#### 成功输出
|
|
361
|
+
|
|
362
|
+
```json
|
|
363
|
+
{
|
|
364
|
+
"ok": true,
|
|
365
|
+
"command": "import",
|
|
366
|
+
"data": {
|
|
367
|
+
"importedProviders": ["imported"],
|
|
368
|
+
"backupPath": "C:\\Users\\name\\.codex\\backups\\20260511-221457-import"
|
|
369
|
+
},
|
|
370
|
+
"warnings": [],
|
|
371
|
+
"error": null
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
#### 失败错误码
|
|
376
|
+
|
|
377
|
+
- `INVALID_IMPORT_FILE`
|
|
378
|
+
- `BACKUP_FAILED`
|
|
379
|
+
- `ROLLBACK_FAILED`
|
|
380
|
+
|
|
381
|
+
### 4.6 `codexs export <file>`
|
|
382
|
+
|
|
383
|
+
#### 目标
|
|
384
|
+
|
|
385
|
+
导出当前 `providers.json` 到指定位置。
|
|
386
|
+
|
|
387
|
+
#### 输入
|
|
388
|
+
|
|
389
|
+
```bash
|
|
390
|
+
codexs export <file> [--force] [--json] [--codex-dir <path>]
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
#### 行为语义
|
|
394
|
+
|
|
395
|
+
- 默认不覆盖已有文件
|
|
396
|
+
- 传 `--force` 后允许覆盖
|
|
397
|
+
- 路径参数必须显式传入
|
|
398
|
+
- 当目标文件已存在、当前是 TTY 且未传 `--force` 时,可通过确认后继续覆盖
|
|
399
|
+
|
|
400
|
+
#### 成功输出
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
{
|
|
404
|
+
"ok": true,
|
|
405
|
+
"command": "export",
|
|
406
|
+
"data": {
|
|
407
|
+
"exportedTo": "C:\\path\\providers-export.json",
|
|
408
|
+
"count": 3
|
|
409
|
+
},
|
|
410
|
+
"warnings": [],
|
|
411
|
+
"error": null
|
|
412
|
+
}
|
|
413
|
+
```
|
|
414
|
+
|
|
415
|
+
#### 失败错误码
|
|
416
|
+
|
|
417
|
+
- `INVALID_IMPORT_FILE`
|
|
418
|
+
- `PROVIDERS_NOT_FOUND`
|
|
419
|
+
- `PROVIDERS_PARSE_ERROR`
|
|
420
|
+
|
|
421
|
+
### 4.7 `codexs add <provider>`
|
|
422
|
+
|
|
423
|
+
#### 目标
|
|
424
|
+
|
|
425
|
+
新增一条 provider 记录。
|
|
426
|
+
|
|
427
|
+
#### 输入
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
codexs add <provider> \
|
|
431
|
+
--profile <name> \
|
|
432
|
+
--api-key <key> \
|
|
433
|
+
[--base-url <url>] \
|
|
434
|
+
[--note <text>] \
|
|
435
|
+
[--tag <tag>] \
|
|
436
|
+
[--json] \
|
|
437
|
+
[--codex-dir <path>]
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
#### 行为语义
|
|
441
|
+
|
|
442
|
+
- provider 名必须唯一
|
|
443
|
+
- 写入前备份旧 `providers.json`
|
|
444
|
+
- 显式参数模式保持可用
|
|
445
|
+
- 当缺少必填字段且 stdin/stdout 都是 TTY 时,允许渐进式提问
|
|
446
|
+
- `--json` 或非 TTY 场景下仍要求显式传入必填参数
|
|
447
|
+
- `profile` 优先从 `config.toml` 已有 profile 列表里选择,获取失败时退回文本输入
|
|
448
|
+
- `apiKey` 使用隐藏输入并要求二次确认
|
|
449
|
+
|
|
450
|
+
#### 成功输出
|
|
451
|
+
|
|
452
|
+
```json
|
|
453
|
+
{
|
|
454
|
+
"ok": true,
|
|
455
|
+
"command": "add",
|
|
456
|
+
"data": {
|
|
457
|
+
"provider": "temp",
|
|
458
|
+
"profile": "freemodel",
|
|
459
|
+
"backupPath": "C:\\Users\\name\\.codex\\backups\\20260511-221457-add"
|
|
460
|
+
},
|
|
461
|
+
"warnings": [],
|
|
462
|
+
"error": null
|
|
463
|
+
}
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
#### 失败错误码
|
|
467
|
+
|
|
468
|
+
- `INVALID_IMPORT_FILE`
|
|
469
|
+
- `BACKUP_FAILED`
|
|
470
|
+
- `ROLLBACK_FAILED`
|
|
471
|
+
|
|
472
|
+
### 4.8 `codexs remove <provider>`
|
|
473
|
+
|
|
474
|
+
#### 目标
|
|
475
|
+
|
|
476
|
+
删除一条 provider 记录。
|
|
477
|
+
|
|
478
|
+
#### 输入
|
|
479
|
+
|
|
480
|
+
```bash
|
|
481
|
+
codexs remove <provider> [--force] [--json] [--codex-dir <path>]
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
#### 行为语义
|
|
485
|
+
|
|
486
|
+
- TTY 中若缺少 `<provider>`,允许先选择 provider
|
|
487
|
+
- TTY 中始终需要确认,确认文案必须带 provider 名
|
|
488
|
+
- TTY 中即使未传 `--force`,也可通过确认完成删除
|
|
489
|
+
- 非 TTY 或 `--json` 场景下仍要求显式 `<provider> --force`
|
|
490
|
+
- 先备份再删除
|
|
491
|
+
|
|
492
|
+
#### 失败错误码
|
|
493
|
+
|
|
494
|
+
- `PROVIDER_NOT_FOUND`
|
|
495
|
+
- `INVALID_IMPORT_FILE`
|
|
496
|
+
- `BACKUP_FAILED`
|
|
497
|
+
- `ROLLBACK_FAILED`
|
|
498
|
+
|
|
499
|
+
### 4.9 `codexs doctor`
|
|
500
|
+
|
|
501
|
+
#### 目标
|
|
502
|
+
|
|
503
|
+
返回结构化问题列表,而不是只给一个总体状态。
|
|
504
|
+
|
|
505
|
+
#### 输入
|
|
506
|
+
|
|
507
|
+
```bash
|
|
508
|
+
codexs doctor [--json] [--codex-dir <path>]
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
#### 当前诊断项
|
|
512
|
+
|
|
513
|
+
- `config.toml` 是否存在
|
|
514
|
+
- `providers.json` 是否存在
|
|
515
|
+
- `providers.json` 是否可解析
|
|
516
|
+
- provider 的 profile 是否存在
|
|
517
|
+
- `codex` CLI 是否可执行
|
|
518
|
+
|
|
519
|
+
#### 当前返回结构
|
|
520
|
+
|
|
521
|
+
```json
|
|
522
|
+
{
|
|
523
|
+
"ok": true,
|
|
524
|
+
"command": "doctor",
|
|
525
|
+
"data": {
|
|
526
|
+
"healthy": false,
|
|
527
|
+
"issues": [
|
|
528
|
+
{
|
|
529
|
+
"code": "CODEX_LOGIN_FAILED",
|
|
530
|
+
"message": "codex CLI is not available.",
|
|
531
|
+
"cause": "spawnSync codex EPERM"
|
|
532
|
+
}
|
|
533
|
+
],
|
|
534
|
+
"codexDir": "C:\\Users\\name\\.codex"
|
|
535
|
+
},
|
|
536
|
+
"warnings": ["doctor found 1 issue(s)"],
|
|
537
|
+
"error": null
|
|
538
|
+
}
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
#### 说明
|
|
542
|
+
|
|
543
|
+
- 当前实现把 codex CLI 缺失归到 `CODEX_LOGIN_FAILED`
|
|
544
|
+
- 后续可按需要拆分更细错误码
|
|
545
|
+
|
|
546
|
+
### 4.10 `codexs rollback`
|
|
547
|
+
|
|
548
|
+
#### 目标
|
|
549
|
+
|
|
550
|
+
恢复最近一次备份对应的文件状态。
|
|
551
|
+
|
|
552
|
+
#### 输入
|
|
553
|
+
|
|
554
|
+
```bash
|
|
555
|
+
codexs rollback [--json] [--codex-dir <path>]
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
#### 行为语义
|
|
559
|
+
|
|
560
|
+
- 读取 `backups/latest.json`
|
|
561
|
+
- 恢复 manifest 中记录的文件
|
|
562
|
+
- 如果最近一次备份包含 `auth.json`,一并恢复
|
|
563
|
+
- TTY 中执行前会展示备份目录和受影响文件摘要,并请求确认
|
|
564
|
+
|
|
565
|
+
#### 成功输出
|
|
566
|
+
|
|
567
|
+
```json
|
|
568
|
+
{
|
|
569
|
+
"ok": true,
|
|
570
|
+
"command": "rollback",
|
|
571
|
+
"data": {
|
|
572
|
+
"restoredFiles": ["config.toml", "auth.json"],
|
|
573
|
+
"backupPath": "C:\\Users\\name\\.codex\\backups\\20260511-221550-switch"
|
|
574
|
+
},
|
|
575
|
+
"warnings": [],
|
|
576
|
+
"error": null
|
|
577
|
+
}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
#### 失败错误码
|
|
581
|
+
|
|
582
|
+
- `ROLLBACK_FAILED`
|
|
583
|
+
|
|
584
|
+
## 5. 默认输出与敏感信息策略
|
|
585
|
+
|
|
586
|
+
默认输出遵循:
|
|
587
|
+
|
|
588
|
+
- 不打印完整 `apiKey`
|
|
589
|
+
- 不打印无关调试信息
|
|
590
|
+
- 成功时尽量只返回命令核心结果
|
|
591
|
+
|
|
592
|
+
JSON 输出也遵循相同策略:
|
|
593
|
+
|
|
594
|
+
- `error.details` 不应包含完整 `apiKey`
|
|
595
|
+
- 主要返回路径、命令对象、回滚状态等可操作信息
|
|
596
|
+
|
|
597
|
+
## 6. AI / 自动化调用建议
|
|
598
|
+
|
|
599
|
+
对 AI 代理或自动化脚本,推荐以下调用约定:
|
|
600
|
+
|
|
601
|
+
- 一律使用 `--json`
|
|
602
|
+
- 严格按 `error.code` 判断失败类型
|
|
603
|
+
- 对 `switch` 命令关注:
|
|
604
|
+
- `provider`
|
|
605
|
+
- `profile`
|
|
606
|
+
- `loginPerformed`
|
|
607
|
+
- `backupPath`
|
|
608
|
+
- `rollbackApplied`
|
|
609
|
+
- 对 `doctor` 命令关注:
|
|
610
|
+
- `healthy`
|
|
611
|
+
- `issues[]`
|
|
612
|
+
|
|
613
|
+
推荐模式:
|
|
614
|
+
|
|
615
|
+
1. 先调用 `status --json`
|
|
616
|
+
2. 再调用 `doctor --json`
|
|
617
|
+
3. 满足前置条件后调用 `switch --json`
|
|
618
|
+
4. 失败时根据错误码决定是否提示用户手动执行 `rollback`
|
|
619
|
+
|
|
620
|
+
## 7. 后续命令演进建议
|
|
621
|
+
|
|
622
|
+
如果继续扩展命令面,建议新增命令时遵守下面三条:
|
|
623
|
+
|
|
624
|
+
- 不破坏当前 JSON envelope
|
|
625
|
+
- 不复用语义不匹配的错误码
|
|
626
|
+
- 所有写命令默认纳入备份与回滚模型
|
|
627
|
+
|
|
628
|
+
未来候选命令:
|
|
629
|
+
|
|
630
|
+
- `codexs show <provider>`
|
|
631
|
+
- `codexs edit <provider>`
|
|
632
|
+
- `codexs backups list`
|
|
633
|
+
- `codexs rollback <backup-id>`
|
|
634
|
+
- `codexs import --merge`
|
|
635
|
+
|
|
636
|
+
## 8. 结论
|
|
637
|
+
|
|
638
|
+
`codex-switch` 当前命令设计已经具备下面几个工程特征:
|
|
639
|
+
|
|
640
|
+
- 命令面稳定
|
|
641
|
+
- 参数风格统一
|
|
642
|
+
- JSON 输出可机器解析
|
|
643
|
+
- 写操作具备安全语义
|
|
644
|
+
- 错误码已可作为 AI 调用契约
|
|
645
|
+
|
|
646
|
+
这意味着它已经不再只是“能切换配置的脚本集合”,而是一套具备持续演进空间的 CLI 命令体系。
|
package/docs/codex-switch-prd.md
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
- 版本范围:MVP / CLI First
|
|
9
9
|
- 文档定位:正式 PRD
|
|
10
10
|
- 对应研究稿:[`codex-switch-product-research.md`](./codex-switch-product-research.md)
|
|
11
|
+
- 对应技术架构:[`codex-switch-technical-architecture.md`](./codex-switch-technical-architecture.md)
|
|
12
|
+
- 对应命令设计:[`codex-switch-command-design.md`](./codex-switch-command-design.md)
|
|
11
13
|
|
|
12
14
|
## 一句话定义
|
|
13
15
|
|
|
@@ -97,6 +99,10 @@ AI 需要通过 `status` 或 `doctor --json` 判断本地配置是否完整、
|
|
|
97
99
|
|
|
98
100
|
关键命令必须提供稳定、可解析的 `--json` 输出。
|
|
99
101
|
|
|
102
|
+
### Progressive For Humans
|
|
103
|
+
|
|
104
|
+
高频人类写命令可以在 TTY 中提供渐进式交互,但这层体验不能改变自动化的显式参数契约。
|
|
105
|
+
|
|
100
106
|
### Local First
|
|
101
107
|
|
|
102
108
|
MVP 的核心对象是本地文件与本机配置,不依赖云端控制面。
|
|
@@ -276,6 +282,12 @@ MVP 固定包含以下命令:
|
|
|
276
282
|
- 位置参数:`<provider>`
|
|
277
283
|
- 可选参数:`--no-login`
|
|
278
284
|
|
|
285
|
+
交互边界:
|
|
286
|
+
|
|
287
|
+
- 当 `<provider>` 缺失且运行在 TTY 中时,允许用户从 provider 列表中选择
|
|
288
|
+
- `--json` 或非 TTY 场景下仍要求显式 provider
|
|
289
|
+
- 当 provider 已显式传入时,不做额外确认
|
|
290
|
+
|
|
279
291
|
前置校验:
|
|
280
292
|
|
|
281
293
|
- `providers.json` 存在且可解析
|
|
@@ -344,6 +356,8 @@ MVP 固定包含以下命令:
|
|
|
344
356
|
说明:
|
|
345
357
|
|
|
346
358
|
- MVP 不做 merge 导入,固定为整体替换
|
|
359
|
+
- 路径参数保持显式,不做路径向导
|
|
360
|
+
- TTY 中在真正覆盖前增加确认
|
|
347
361
|
|
|
348
362
|
### `codexs export <file>`
|
|
349
363
|
|
|
@@ -359,6 +373,8 @@ MVP 固定包含以下命令:
|
|
|
359
373
|
|
|
360
374
|
- 默认不覆盖已有文件
|
|
361
375
|
- 只有传入 `--force` 时才允许覆盖
|
|
376
|
+
- TTY 中若目标已存在且未传 `--force`,允许通过确认覆盖
|
|
377
|
+
- 非 TTY 与 `--json` 保持显式 `--force` 契约
|
|
362
378
|
|
|
363
379
|
### `codexs add <provider>`
|
|
364
380
|
|
|
@@ -381,8 +397,11 @@ MVP 固定包含以下命令:
|
|
|
381
397
|
|
|
382
398
|
范围限制:
|
|
383
399
|
|
|
384
|
-
-
|
|
385
|
-
-
|
|
400
|
+
- 显式参数模式仍是自动化主路径
|
|
401
|
+
- 当 `add` 缺少必填参数且运行在 TTY 中时,允许进入渐进式交互录入
|
|
402
|
+
- `--json` 或非 TTY 场景下仍要求显式传参
|
|
403
|
+
- `profile` 优先展示 `config.toml` 中现有 profile 供选择
|
|
404
|
+
- `apiKey` 以隐藏输入采集并要求二次确认
|
|
386
405
|
|
|
387
406
|
### `codexs remove <provider>`
|
|
388
407
|
|
|
@@ -404,7 +423,8 @@ MVP 固定包含以下命令:
|
|
|
404
423
|
|
|
405
424
|
范围限制:
|
|
406
425
|
|
|
407
|
-
-
|
|
426
|
+
- TTY 中可选择 provider,并通过确认代替 `--force`
|
|
427
|
+
- 自动化调用场景下,仍要求显式传 `--force`
|
|
408
428
|
|
|
409
429
|
### `codexs doctor`
|
|
410
430
|
|
|
@@ -440,6 +460,7 @@ MVP 固定包含以下命令:
|
|
|
440
460
|
说明:
|
|
441
461
|
|
|
442
462
|
- `rollback` 进入 MVP,因为它直接支撑“默认安全”的产品承诺
|
|
463
|
+
- TTY 中在恢复前展示将被恢复的文件摘要,并请求确认
|
|
443
464
|
|
|
444
465
|
## 输出契约
|
|
445
466
|
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
- 研究输入稿:[`codex-switch-product-research.md`](./codex-switch-product-research.md)
|
|
12
12
|
- 正式 PRD:[`codex-switch-prd.md`](./codex-switch-prd.md)
|
|
13
|
+
- 技术架构设计:[`codex-switch-technical-architecture.md`](./codex-switch-technical-architecture.md)
|
|
14
|
+
- 命令设计说明:[`codex-switch-command-design.md`](./codex-switch-command-design.md)
|
|
13
15
|
|
|
14
16
|
## 产品概述
|
|
15
17
|
|