@minniexcode/codex-switch 0.0.3 → 0.0.5
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 +8 -3
- package/README.md +160 -91
- package/dist/app/add-provider.js +32 -1
- package/dist/app/edit-provider.js +137 -0
- package/dist/app/get-status.js +9 -2
- package/dist/app/import-providers.js +47 -2
- package/dist/app/list-backups.js +17 -0
- package/dist/app/list-config-profiles.js +29 -0
- package/dist/app/remove-provider.js +34 -2
- package/dist/app/rollback-backup.js +30 -0
- package/dist/app/run-doctor.js +22 -21
- package/dist/app/setup-codex.js +155 -0
- package/dist/app/show-config.js +34 -0
- package/dist/app/show-provider.js +22 -0
- package/dist/app/switch-provider.js +5 -2
- package/dist/cli/add-interactive.js +25 -31
- package/dist/cli/args.js +19 -5
- package/dist/cli/help.js +109 -14
- package/dist/cli/interactive.js +123 -8
- package/dist/cli/output.js +56 -1
- package/dist/cli/prompt.js +19 -2
- package/dist/cli.js +250 -13
- package/dist/domain/backups.js +103 -0
- package/dist/domain/config.js +471 -39
- package/dist/domain/errors.js +3 -3
- package/dist/domain/providers.js +10 -0
- package/dist/domain/setup.js +30 -0
- package/dist/infra/backup-repo.js +65 -6
- package/dist/infra/codex-cli.js +79 -2
- package/dist/infra/codex-discovery.js +10 -0
- package/dist/infra/codex-paths.js +14 -1
- package/dist/infra/config-repo.js +102 -9
- package/dist/infra/providers-repo.js +29 -0
- package/docs/Design/codex-switch-v0.0.4-design.md +874 -0
- package/docs/Design/codex-switch-v0.0.5-design.md +922 -0
- package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +308 -0
- package/docs/PRD/codex-switch-prd-v0.1.0.md +343 -0
- package/docs/{codex-switch-prd.md → PRD/codex-switch-prd.md} +9 -5
- package/docs/cli-usage.md +580 -0
- package/docs/codex-switch-command-design.md +1 -1
- package/docs/codex-switch-product-overview.md +1 -1
- package/docs/codex-switch-product-research.md +2 -2
- package/docs/codex-switch-technical-architecture.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# codex-switch `0.0.5 -> 0.1.0` 演进 PRD
|
|
2
|
+
|
|
3
|
+
## 文档信息
|
|
4
|
+
|
|
5
|
+
- 状态:Target PRD
|
|
6
|
+
- 产品名:`codex-switch`
|
|
7
|
+
- CLI 命令名:`codexs`
|
|
8
|
+
- 当前阶段基线:`0.0.5`
|
|
9
|
+
- 目标版本:`0.1.0`
|
|
10
|
+
- 文档定位:定义 `0.0.5` 之后持续演进到 `0.1.0` 的目标规格与路线
|
|
11
|
+
- 当前活跃 PRD:[`codex-switch-prd-v0.1.0.md`](./codex-switch-prd-v0.1.0.md)
|
|
12
|
+
- 历史基线 PRD:[`codex-switch-prd.md`](./codex-switch-prd.md)
|
|
13
|
+
- 对应研究稿:[`../codex-switch-product-research.md`](../codex-switch-product-research.md)
|
|
14
|
+
- 对应技术架构:[`../codex-switch-technical-architecture.md`](../codex-switch-technical-architecture.md)
|
|
15
|
+
- 对应命令设计:[`../codex-switch-command-design.md`](../codex-switch-command-design.md)
|
|
16
|
+
|
|
17
|
+
## 一句话定义
|
|
18
|
+
|
|
19
|
+
`codex-switch` 的 `0.1.0` 目标,是从一个已经具备 provider 管理和基础 config consistency 能力的本地 CLI,演进为一套对人类和 AI 都稳定、可初始化、可诊断、可恢复、可结构化管理配置、可持续扩展的发布级命令体系。
|
|
20
|
+
|
|
21
|
+
## 版本语义
|
|
22
|
+
|
|
23
|
+
- `0.0.x`:测试 / 验证阶段版本,用于收敛模型、命令面和失败语义
|
|
24
|
+
- `0.1.0`:第一条稳定发布规格线,不要求立即全部完成,但要求边界清晰
|
|
25
|
+
- 本文档描述的是 `0.0.5` 之后继续走向 `0.1.0` 的长期目标
|
|
26
|
+
|
|
27
|
+
## `0.1.0` 总体目标
|
|
28
|
+
|
|
29
|
+
`0.1.0` 需要同时满足以下目标:
|
|
30
|
+
|
|
31
|
+
- 保持 CLI 与 JSON 契约稳定
|
|
32
|
+
- 保持 `setup`、provider registry、备份恢复主线能力不回退
|
|
33
|
+
- 将 `config.toml` 从“可结构化读取与最小受管写入”推进到“稳定受管 provider-linked sections”
|
|
34
|
+
- 让 provider registry 与 linked config sections 的一致性成为默认能力
|
|
35
|
+
- 让备份与回滚继续覆盖所有关键写操作
|
|
36
|
+
- 为未来 auth / extension 集成保留明确边界
|
|
37
|
+
|
|
38
|
+
## 长期演进守则
|
|
39
|
+
|
|
40
|
+
后续新增命令统一遵守:
|
|
41
|
+
|
|
42
|
+
- 不破坏当前 JSON envelope
|
|
43
|
+
- 不复用语义不匹配的错误码
|
|
44
|
+
- 所有写命令默认纳入备份与回滚模型
|
|
45
|
+
|
|
46
|
+
## 稳定公共契约
|
|
47
|
+
|
|
48
|
+
### JSON Envelope
|
|
49
|
+
|
|
50
|
+
`--json` 继续保持统一 envelope:
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"ok": true,
|
|
55
|
+
"command": "list",
|
|
56
|
+
"data": {},
|
|
57
|
+
"warnings": [],
|
|
58
|
+
"error": null
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
约束:
|
|
63
|
+
|
|
64
|
+
- 顶层 shape 保持不变
|
|
65
|
+
- 后续字段扩展只做加法
|
|
66
|
+
- 详细结果进入 `data`
|
|
67
|
+
- 非致命提示进入 `warnings`
|
|
68
|
+
- 结构化失败信息继续进入 `error`
|
|
69
|
+
|
|
70
|
+
### 数据模型
|
|
71
|
+
|
|
72
|
+
#### `providers.json`
|
|
73
|
+
|
|
74
|
+
`providers.json` 继续是 managed registry 的单一事实源:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{
|
|
78
|
+
"providers": {
|
|
79
|
+
"packycode": {
|
|
80
|
+
"profile": "packycode",
|
|
81
|
+
"apiKey": "sk-xxx",
|
|
82
|
+
"baseUrl": "https://example.com/v1",
|
|
83
|
+
"note": "primary free model route",
|
|
84
|
+
"tags": ["free", "daily"]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
到 `0.1.0` 为止默认不放宽:
|
|
91
|
+
|
|
92
|
+
- `profile` 仍然必填
|
|
93
|
+
- `apiKey` 仍按完整 managed provider 处理
|
|
94
|
+
- 不引入“半初始化 provider”作为正式稳定状态
|
|
95
|
+
|
|
96
|
+
#### `config.toml`
|
|
97
|
+
|
|
98
|
+
到 `0.1.0` 为止,`config.toml` 的定位是“部分受管的 runtime projection”:
|
|
99
|
+
|
|
100
|
+
- 顶层 active `profile = "..."` 继续受管
|
|
101
|
+
- 与 provider 关联的 `[profiles.<name>]` section 进入受管范围
|
|
102
|
+
- 非 provider 相关的顶层键、section 和注释仍允许存在,但不进入通用编辑器范围
|
|
103
|
+
|
|
104
|
+
#### `ManagedProfileFields`
|
|
105
|
+
|
|
106
|
+
`0.1.0` 之前第一批稳定受管 profile 持久化字段先锁定为最小集合:
|
|
107
|
+
|
|
108
|
+
```json
|
|
109
|
+
{
|
|
110
|
+
"model": "gpt-5"
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
约束:
|
|
115
|
+
|
|
116
|
+
- 第一批正式受管字段只锁 `model`
|
|
117
|
+
- `baseUrl` 等 endpoint 类字段继续只保留在 `providers.json`
|
|
118
|
+
- 后续扩展 profile 字段时,只能做加法
|
|
119
|
+
|
|
120
|
+
#### `ManagedProfileView`
|
|
121
|
+
|
|
122
|
+
面向 CLI、AI 和脚本输出的读取视图,与持久化字段分离:
|
|
123
|
+
|
|
124
|
+
```json
|
|
125
|
+
{
|
|
126
|
+
"name": "packycode",
|
|
127
|
+
"model": "gpt-5",
|
|
128
|
+
"linkedProviders": ["packycode"],
|
|
129
|
+
"isActive": true,
|
|
130
|
+
"managed": true
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### TOML 处理原则
|
|
135
|
+
|
|
136
|
+
为了支持结构化 config 管理,`0.1.0` 稳定主线要求:
|
|
137
|
+
|
|
138
|
+
- 不再以字符串匹配作为唯一 TOML 修改策略
|
|
139
|
+
- 对受管 section 的读取、创建、删除、重命名和字段更新,必须支持可验证的非破坏性结构化读取和修改
|
|
140
|
+
- 修改受管部分时,不应破坏非受管 TOML 内容、顺序、空行和注释
|
|
141
|
+
|
|
142
|
+
### 错误码演进原则
|
|
143
|
+
|
|
144
|
+
保留现有领域错误码,并把错误码体系从 MVP 复用模式收紧到语义匹配模式。
|
|
145
|
+
|
|
146
|
+
现有保留:
|
|
147
|
+
|
|
148
|
+
- `CONFIG_NOT_FOUND`
|
|
149
|
+
- `PROVIDERS_NOT_FOUND`
|
|
150
|
+
- `PROVIDERS_PARSE_ERROR`
|
|
151
|
+
- `PROVIDER_NOT_FOUND`
|
|
152
|
+
- `PROFILE_NOT_FOUND`
|
|
153
|
+
- `BACKUP_FAILED`
|
|
154
|
+
- `CODEX_LOGIN_FAILED`
|
|
155
|
+
- `ROLLBACK_FAILED`
|
|
156
|
+
- `LOCK_CONFLICT`
|
|
157
|
+
- `LIVE_STATE_DRIFT`
|
|
158
|
+
|
|
159
|
+
建议新增 / 预留:
|
|
160
|
+
|
|
161
|
+
- `INVALID_ARGUMENT`
|
|
162
|
+
- `UNKNOWN_COMMAND`
|
|
163
|
+
- `PROMPT_CANCELLED`
|
|
164
|
+
- `CODEX_NOT_INSTALLED`
|
|
165
|
+
- `CODEX_VERSION_UNSUPPORTED`
|
|
166
|
+
- `CODEX_DIR_NOT_FOUND`
|
|
167
|
+
- `CODEX_DIR_AMBIGUOUS`
|
|
168
|
+
- `PROVIDERS_ALREADY_EXISTS`
|
|
169
|
+
- `BACKUP_NOT_FOUND`
|
|
170
|
+
- `CONFIG_PARSE_ERROR`
|
|
171
|
+
- `PROFILE_IN_USE`
|
|
172
|
+
- `MANAGED_PROFILE_FIELDS_MISSING`
|
|
173
|
+
|
|
174
|
+
## 已落地能力的 `0.1.0` 稳定化要求
|
|
175
|
+
|
|
176
|
+
### `setup`
|
|
177
|
+
|
|
178
|
+
`setup` 在 `0.1.0` 主线中的要求是:
|
|
179
|
+
|
|
180
|
+
- 继续保持从环境检测到 registry 初始化的主流程
|
|
181
|
+
- 继续允许 `overwrite`、`merge` 和交互式补问缺失关键字段
|
|
182
|
+
- 与新的 config 管理能力保持兼容,不写出未来无法被结构化读取的受管状态
|
|
183
|
+
- 对历史遗留不一致状态给出 adopt / repair 建议,而不是静默忽略
|
|
184
|
+
|
|
185
|
+
### provider registry 命令
|
|
186
|
+
|
|
187
|
+
`show`、`edit`、`import --merge`、`backups list`、`rollback <backup-id>` 的 `0.1.0` 要求是:
|
|
188
|
+
|
|
189
|
+
- 保持命令名和基础 JSON 契约稳定
|
|
190
|
+
- 把错误语义继续收紧
|
|
191
|
+
- 让与 `config.toml` 关联的行为更完整
|
|
192
|
+
|
|
193
|
+
### `import --merge`
|
|
194
|
+
|
|
195
|
+
`import --merge` 在 `0.1.0` 主线中的要求是:
|
|
196
|
+
|
|
197
|
+
- 保持“导入侧覆盖本地同名 provider”的默认 merge 语义
|
|
198
|
+
- 不能只更新 `providers.json` 而放任 linked profile sections 漂移
|
|
199
|
+
- 当导入结果引用了缺失 profile 时,必须进入与 `add` / `edit` 一致的受管规则
|
|
200
|
+
- 非交互模式下,如果导入内容不能满足受管 profile 创建条件,应明确失败
|
|
201
|
+
- 交互模式下可以进入 adopt / repair 辅助流,但最终写入结果仍必须满足一致性约束
|
|
202
|
+
|
|
203
|
+
## `0.1.0` 远期能力域
|
|
204
|
+
|
|
205
|
+
下面这些方向明确有价值,但不进入 `0.0.5` 当前里程碑,只作为继续走向 `0.1.0` 的能力域。
|
|
206
|
+
|
|
207
|
+
### 第三方 auth / extension 集成
|
|
208
|
+
|
|
209
|
+
示例方向:
|
|
210
|
+
|
|
211
|
+
- 接入 Copilot auth
|
|
212
|
+
- 在本地启动代理服务,使特定上游可在 Codex 中使用
|
|
213
|
+
- 安装和管理第三方依赖
|
|
214
|
+
|
|
215
|
+
当前定位:
|
|
216
|
+
|
|
217
|
+
- 作为单独能力域保留
|
|
218
|
+
- 不在当前主 PRD 中锁定具体命令名和交互细节
|
|
219
|
+
- 不进入 `0.1.0` 稳定主线的验收标准
|
|
220
|
+
|
|
221
|
+
### 更大范围的 profile schema 管理
|
|
222
|
+
|
|
223
|
+
未来如果需要扩展:
|
|
224
|
+
|
|
225
|
+
- 可以逐步纳入 `model` 之外的 profile 字段
|
|
226
|
+
- 必须保持增量式 schema 扩展
|
|
227
|
+
- 不能在未定义字段契约前把 `config.toml` 直接提升为 full config manager
|
|
228
|
+
|
|
229
|
+
## 主题里程碑
|
|
230
|
+
|
|
231
|
+
从 `0.0.5` 走向 `0.1.0`,建议按能力主题推进:
|
|
232
|
+
|
|
233
|
+
### 里程碑 A:`0.0.5` / Config Management & Consistency
|
|
234
|
+
|
|
235
|
+
目标:
|
|
236
|
+
|
|
237
|
+
- 巩固结构化 TOML 读写
|
|
238
|
+
- 稳定 `config show`、`config list-profiles`
|
|
239
|
+
- 让 provider 管理命令可靠同步 linked profile sections
|
|
240
|
+
- 明确共享 profile、孤儿 section 和 active profile 安全规则
|
|
241
|
+
|
|
242
|
+
### 里程碑 B:Backup / Recovery Evolution
|
|
243
|
+
|
|
244
|
+
目标:
|
|
245
|
+
|
|
246
|
+
- 保持 `backups list` 与指定回滚能力稳定
|
|
247
|
+
- 确保跨 `providers.json` 与 `config.toml` 的双写场景仍可完整恢复
|
|
248
|
+
- 为更复杂的 config 变更继续复用同一事务模型
|
|
249
|
+
|
|
250
|
+
### 里程碑 C:Error Contract Hardening
|
|
251
|
+
|
|
252
|
+
目标:
|
|
253
|
+
|
|
254
|
+
- 收紧错误码语义
|
|
255
|
+
- 区分环境错误、参数错误、配置解析错误和恢复错误
|
|
256
|
+
- 保持 TTY / 非交互模式下的错误结果可预测
|
|
257
|
+
|
|
258
|
+
### 里程碑 D:Extensions / Auth Integration
|
|
259
|
+
|
|
260
|
+
目标:
|
|
261
|
+
|
|
262
|
+
- 评估第三方 auth 与本地代理集成
|
|
263
|
+
- 评估交互式依赖安装与 extension 管理
|
|
264
|
+
- 在不破坏主 CLI 契约的前提下扩展能力边界
|
|
265
|
+
|
|
266
|
+
## 对实现的要求
|
|
267
|
+
|
|
268
|
+
从 `0.0.5` 到 `0.1.0` 的所有新增能力,默认遵守:
|
|
269
|
+
|
|
270
|
+
- 命令帮助必须明确人类模式和 `--json` 模式行为
|
|
271
|
+
- 非交互环境不允许依赖 prompt 才能完成核心自动化流程
|
|
272
|
+
- 所有写命令默认走锁、备份、回滚
|
|
273
|
+
- 所有新增错误码都必须语义清晰
|
|
274
|
+
- 所有新增 JSON 返回都只能扩展 `data` 和 `warnings`
|
|
275
|
+
- 结构化 TOML 写回不能破坏非受管部分
|
|
276
|
+
- 多候选目录发现必须在交互和非交互模式下给出一致且可预测的行为
|
|
277
|
+
|
|
278
|
+
## `0.1.0` 目标完成标准
|
|
279
|
+
|
|
280
|
+
达到下面这些条件时,可以认为 `0.1.0` 主线目标基本收敛:
|
|
281
|
+
|
|
282
|
+
- 用户可以通过 `setup` 完成首次初始化
|
|
283
|
+
- `setup` 在多候选 Codex 目录场景下可交互选择或手动输入,在非交互场景下返回明确歧义错误
|
|
284
|
+
- provider registry 的查看、编辑、导入合并能力完整
|
|
285
|
+
- 用户和 AI 可以通过稳定命令结构化查看受管 `config.toml`
|
|
286
|
+
- `add` / `edit` / `remove` 执行后,`providers.json` 与 linked profile sections 不再出现预期内的一致性漂移
|
|
287
|
+
- 共享 profile 场景不会误删仍被引用的 section
|
|
288
|
+
- active profile 不会因为 provider 删除或 profile 迁移而变成悬空状态
|
|
289
|
+
- 历史 `0.0.4` / `0.0.5` 状态可以被识别,并通过 adopt / repair 路径逐步收敛
|
|
290
|
+
- 历史备份可被显式枚举和恢复
|
|
291
|
+
- CLI 错误码不再存在明显语义复用问题
|
|
292
|
+
- 主 CLI 契约对 AI 和脚本调用保持稳定
|
|
293
|
+
|
|
294
|
+
## 建议测试场景
|
|
295
|
+
|
|
296
|
+
至少需要覆盖:
|
|
297
|
+
|
|
298
|
+
- `config show` 与 `config list-profiles` 的稳定输出
|
|
299
|
+
- 共享 profile 场景下的 `add` / `edit` / `remove` 行为
|
|
300
|
+
- `setup` 在多目录候选下的交互和非交互分支
|
|
301
|
+
- `import --merge` 在缺失 profile / adopt / repair 下的一致性行为
|
|
302
|
+
- 结构化 TOML 修改后,非受管内容、顺序和注释保持稳定
|
|
303
|
+
- 双写失败时 `providers.json` 与 `config.toml` 能整体回滚
|
|
304
|
+
- 历史 workspace、共享 profile、孤儿 profile section、缺失 linked section 都能被 `doctor` / `status` 正确识别
|
|
305
|
+
|
|
306
|
+
## 结论
|
|
307
|
+
|
|
308
|
+
`0.1.0` 不是简单把 `0.0.x` 重命名为稳定版,而是在保持当前本地事务式切换模型不变的前提下,进一步收敛 config 管理、错误契约和恢复能力,并为未来更大范围的 auth / extension 集成留出清晰边界。
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
# codex-switch `0.0.5` PRD
|
|
2
|
+
|
|
3
|
+
## 文档信息
|
|
4
|
+
|
|
5
|
+
- 状态:Active PRD
|
|
6
|
+
- 产品名:`codex-switch`
|
|
7
|
+
- CLI 命令名:`codexs`
|
|
8
|
+
- 当前基线版本:`0.0.4`
|
|
9
|
+
- 目标版本:`0.0.5`
|
|
10
|
+
- 文档定位:定义 `0.0.4 -> 0.0.5` 的直接需求范围
|
|
11
|
+
- 历史基线 PRD:[`codex-switch-prd.md`](./codex-switch-prd.md)
|
|
12
|
+
- 后续演进 PRD:[`codex-switch-prd-v0.0.5-to-v0.1.0.md`](./codex-switch-prd-v0.0.5-to-v0.1.0.md)
|
|
13
|
+
- 对应研究稿:[`../codex-switch-product-research.md`](../codex-switch-product-research.md)
|
|
14
|
+
- 对应技术架构:[`../codex-switch-technical-architecture.md`](../codex-switch-technical-architecture.md)
|
|
15
|
+
- 对应命令设计:[`../codex-switch-command-design.md`](../codex-switch-command-design.md)
|
|
16
|
+
|
|
17
|
+
## 一句话定义
|
|
18
|
+
|
|
19
|
+
`0.0.5` 的目标不是继续堆命令,而是把 `config.toml` 从“只能浅层切换 active profile”升级为“可以结构化读取、受控维护 provider-linked profiles,并与 `providers.json` 保持一致”。
|
|
20
|
+
|
|
21
|
+
## 当前基线:`0.0.4`
|
|
22
|
+
|
|
23
|
+
当前已落地能力:
|
|
24
|
+
|
|
25
|
+
- `list` / `current` / `status`
|
|
26
|
+
- `switch <provider>`
|
|
27
|
+
- `import <file>` / `import <file> --merge` / `export <file>`
|
|
28
|
+
- `add <provider>` / `edit <provider>` / `show <provider>` / `remove <provider>`
|
|
29
|
+
- `setup`
|
|
30
|
+
- `doctor`
|
|
31
|
+
- `backups list`
|
|
32
|
+
- `rollback` / `rollback <backup-id>`
|
|
33
|
+
|
|
34
|
+
当前基线已具备的工程特征:
|
|
35
|
+
|
|
36
|
+
- 本地文件模型围绕 `~/.codex/`
|
|
37
|
+
- `providers.json` 作为 management SSOT
|
|
38
|
+
- `config.toml` 与 `auth.json` 作为 runtime state
|
|
39
|
+
- 写命令统一走备份、锁和失败回滚
|
|
40
|
+
- `--json` 输出固定 envelope
|
|
41
|
+
|
|
42
|
+
当前主要缺口:
|
|
43
|
+
|
|
44
|
+
- `config.toml` 仍以轻量字符串匹配方式处理
|
|
45
|
+
- provider 管理命令不能稳定同步 linked profile sections
|
|
46
|
+
- 缺少结构化展示 config 的稳定命令面
|
|
47
|
+
- 历史 profile、共享 profile、缺失 section 的一致性规则还不完整
|
|
48
|
+
|
|
49
|
+
## `0.0.5` 目标
|
|
50
|
+
|
|
51
|
+
`0.0.5` 需要完成四件事:
|
|
52
|
+
|
|
53
|
+
- 引入结构化 TOML 读取与非破坏性修改能力
|
|
54
|
+
- 增加稳定的 config 查看命令,供人类、AI 和脚本消费
|
|
55
|
+
- 让 provider 写命令同步维护 linked profile sections
|
|
56
|
+
- 补齐历史状态、一致性信号和安全删除规则
|
|
57
|
+
|
|
58
|
+
## 范围
|
|
59
|
+
|
|
60
|
+
### In Scope
|
|
61
|
+
|
|
62
|
+
- 顶层 active `profile`
|
|
63
|
+
- `[profiles.<name>]` 受管 section
|
|
64
|
+
- 第一批正式受管字段:`model`
|
|
65
|
+
- `config show`
|
|
66
|
+
- `config list-profiles`
|
|
67
|
+
- `add` / `edit` / `remove` / `setup` / `import --merge` 的 provider-config 一致性
|
|
68
|
+
- `doctor` / `status` 的一致性信号
|
|
69
|
+
|
|
70
|
+
### Out of Scope
|
|
71
|
+
|
|
72
|
+
- 整个 `config.toml` 的通用编辑器
|
|
73
|
+
- 任意顶层键的自由增删改
|
|
74
|
+
- 更大 profile schema 的首版正式规格
|
|
75
|
+
- 第三方 auth / extension 集成
|
|
76
|
+
|
|
77
|
+
## 数据与契约
|
|
78
|
+
|
|
79
|
+
### JSON Envelope
|
|
80
|
+
|
|
81
|
+
`--json` 继续保持统一 envelope:
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"ok": true,
|
|
86
|
+
"command": "list",
|
|
87
|
+
"data": {},
|
|
88
|
+
"warnings": [],
|
|
89
|
+
"error": null
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
要求:
|
|
94
|
+
|
|
95
|
+
- 顶层 shape 不变
|
|
96
|
+
- 新字段只追加到 `data` / `warnings`
|
|
97
|
+
- 错误信息继续进入 `error`
|
|
98
|
+
|
|
99
|
+
### `providers.json`
|
|
100
|
+
|
|
101
|
+
`providers.json` 继续是 provider registry 的单一事实源:
|
|
102
|
+
|
|
103
|
+
- `profile` 必填
|
|
104
|
+
- `apiKey` 仍按完整 managed provider 处理
|
|
105
|
+
- 不引入“半初始化 provider”作为稳定状态
|
|
106
|
+
|
|
107
|
+
### `config.toml`
|
|
108
|
+
|
|
109
|
+
到 `0.0.5` 为止,`config.toml` 的受管范围限定为:
|
|
110
|
+
|
|
111
|
+
- 顶层 active `profile`
|
|
112
|
+
- 与 provider 关联的 `[profiles.<name>]`
|
|
113
|
+
- section 内最小正式字段:`model`
|
|
114
|
+
|
|
115
|
+
约束:
|
|
116
|
+
|
|
117
|
+
- `providers.json` 仍是 provider 身份、凭据和管理元数据的 SSOT
|
|
118
|
+
- `config.toml` 只承载运行态投影,不升级为对等事实源
|
|
119
|
+
- 非受管 TOML 内容允许存在,但不进入通用编辑范围
|
|
120
|
+
|
|
121
|
+
### Managed Profile View
|
|
122
|
+
|
|
123
|
+
读取命令应围绕稳定视图返回,而不是直接暴露内部持久化细节。最小视图建议包含:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"name": "packycode",
|
|
128
|
+
"model": "gpt-5",
|
|
129
|
+
"linkedProviders": ["packycode"],
|
|
130
|
+
"isActive": true,
|
|
131
|
+
"managed": true
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Config Management 规则
|
|
136
|
+
|
|
137
|
+
### 受管与非受管
|
|
138
|
+
|
|
139
|
+
- managed profile:被至少一个 provider 引用,允许被写命令同步维护
|
|
140
|
+
- unmanaged profile:存在于 `config.toml`,但当前没有任何 provider 引用,默认只读展示
|
|
141
|
+
- orphaned managed reference:`providers.json` 引用了 profile,但 `config.toml` 缺失对应 section,属于不一致状态
|
|
142
|
+
|
|
143
|
+
### 共享 profile
|
|
144
|
+
|
|
145
|
+
多个 provider 指向同一个 profile 在 `0.0.5` 继续合法:
|
|
146
|
+
|
|
147
|
+
- profile section 不归单个 provider 独占
|
|
148
|
+
- 只有当没有任何 provider 引用时,才允许删除对应 section
|
|
149
|
+
- `remove` / `edit` 不能因单个 provider 操作误删共享 profile
|
|
150
|
+
|
|
151
|
+
### TOML 处理原则
|
|
152
|
+
|
|
153
|
+
- 不再以字符串匹配作为唯一修改策略
|
|
154
|
+
- 对受管 section 的读取、创建、删除、字段更新必须可验证
|
|
155
|
+
- 修改受管部分时,不应破坏非受管内容、顺序、空行和注释
|
|
156
|
+
|
|
157
|
+
## 新增命令
|
|
158
|
+
|
|
159
|
+
### `codexs config show`
|
|
160
|
+
|
|
161
|
+
用途:
|
|
162
|
+
|
|
163
|
+
- 展示结构化 config 视图
|
|
164
|
+
- 同时服务人类和 AI / 自动化读取
|
|
165
|
+
|
|
166
|
+
输入:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
codexs config show [profile] [--json] [--codex-dir <path>]
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
最小返回要求:
|
|
173
|
+
|
|
174
|
+
- `activeProfile`
|
|
175
|
+
- `profiles`
|
|
176
|
+
- `includedProfiles`
|
|
177
|
+
|
|
178
|
+
`profiles[]` 中每项至少包含:
|
|
179
|
+
|
|
180
|
+
- `name`
|
|
181
|
+
- `managed`
|
|
182
|
+
- `isActive`
|
|
183
|
+
- `linkedProviders`
|
|
184
|
+
- `managedFields`
|
|
185
|
+
- `source`
|
|
186
|
+
|
|
187
|
+
### `codexs config list-profiles`
|
|
188
|
+
|
|
189
|
+
用途:
|
|
190
|
+
|
|
191
|
+
- 列出当前 `config.toml` 中的 profile 视图
|
|
192
|
+
- 明确显示 profile 与 provider 的关联关系
|
|
193
|
+
|
|
194
|
+
输入:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
codexs config list-profiles [--json] [--codex-dir <path>]
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`data.profiles[]` 至少包含:
|
|
201
|
+
|
|
202
|
+
- `name`
|
|
203
|
+
- `managed`
|
|
204
|
+
- `isActive`
|
|
205
|
+
- `linkedProviders`
|
|
206
|
+
- `model`
|
|
207
|
+
|
|
208
|
+
## 现有写命令升级
|
|
209
|
+
|
|
210
|
+
### `codexs add <provider>`
|
|
211
|
+
|
|
212
|
+
新增或锁定:
|
|
213
|
+
|
|
214
|
+
- `--model <name>`
|
|
215
|
+
- `--create-profile`
|
|
216
|
+
|
|
217
|
+
规则:
|
|
218
|
+
|
|
219
|
+
- 当目标 profile 已存在时,允许直接建立映射
|
|
220
|
+
- 当目标 profile 不存在时,只有显式传入 `--create-profile --model <name>` 才允许创建 section
|
|
221
|
+
- 缺少最小受管字段时,返回 `MANAGED_PROFILE_FIELDS_MISSING`
|
|
222
|
+
|
|
223
|
+
### `codexs edit <provider>`
|
|
224
|
+
|
|
225
|
+
新增或锁定:
|
|
226
|
+
|
|
227
|
+
- `--profile <name>`
|
|
228
|
+
- `--model <name>`
|
|
229
|
+
- `--create-profile`
|
|
230
|
+
|
|
231
|
+
规则:
|
|
232
|
+
|
|
233
|
+
- `edit --profile <missing>` 且未传 `--create-profile` 时失败
|
|
234
|
+
- `edit --profile <missing> --create-profile` 但未传 `--model` 时失败
|
|
235
|
+
- 旧 profile 若仍被其他 provider 引用,则保留
|
|
236
|
+
- 旧 profile 若已无引用且不是 active profile,则可以删除
|
|
237
|
+
- 不隐式 rename 或 copy 旧 section 到新 profile
|
|
238
|
+
|
|
239
|
+
### `codexs remove <provider>`
|
|
240
|
+
|
|
241
|
+
新增或锁定:
|
|
242
|
+
|
|
243
|
+
- `--switch-to <profile>`
|
|
244
|
+
|
|
245
|
+
规则:
|
|
246
|
+
|
|
247
|
+
- 删除 provider 记录后,若 profile 仍被其他 provider 引用,则保留 section
|
|
248
|
+
- 若 profile 已无任何引用,则允许删除 section
|
|
249
|
+
- 若该 profile 仍是当前 active 且最后一个引用,必须先 `switch` 或显式传 `--switch-to`
|
|
250
|
+
- 不允许把 active profile 留成悬空状态
|
|
251
|
+
|
|
252
|
+
### `codexs switch <provider>`
|
|
253
|
+
|
|
254
|
+
- 继续只负责切换顶层 active profile
|
|
255
|
+
- 不负责修复 profile section 内容
|
|
256
|
+
- 执行前提仍是目标 profile section 必须存在且可识别
|
|
257
|
+
|
|
258
|
+
## `setup` 升级
|
|
259
|
+
|
|
260
|
+
`setup` 在 `0.0.5` 需要与新一致性模型兼容:
|
|
261
|
+
|
|
262
|
+
- 支持扫描多个候选 Codex 目录
|
|
263
|
+
- 多候选下,TTY 允许选择或手动输入目录
|
|
264
|
+
- 非交互模式下,多候选且未显式传 `--codex-dir` 时返回 `CODEX_DIR_AMBIGUOUS`
|
|
265
|
+
- 未发现任何候选目录时,TTY 可手动输入;非交互返回 `CODEX_DIR_NOT_FOUND`
|
|
266
|
+
- 对从现有 `config.toml` 发现的 profile,允许 adopt 为受管 profile
|
|
267
|
+
- 不制造新的 registry-config 不一致
|
|
268
|
+
|
|
269
|
+
## Write Result Contract
|
|
270
|
+
|
|
271
|
+
下列写命令成功时,建议在 JSON `data` 中稳定返回结果字段:
|
|
272
|
+
|
|
273
|
+
- `add`
|
|
274
|
+
- `edit`
|
|
275
|
+
- `remove`
|
|
276
|
+
- `setup`
|
|
277
|
+
- `import --merge`
|
|
278
|
+
|
|
279
|
+
建议字段:
|
|
280
|
+
|
|
281
|
+
- `provider`
|
|
282
|
+
- `profile`
|
|
283
|
+
- `createdProfileSections`
|
|
284
|
+
- `deletedProfileSections`
|
|
285
|
+
- `keptSharedProfiles`
|
|
286
|
+
- `switchedActiveProfile`
|
|
287
|
+
- `adoptedProfiles`
|
|
288
|
+
- `repairedProfiles`
|
|
289
|
+
|
|
290
|
+
## 事务与回滚
|
|
291
|
+
|
|
292
|
+
所有可能同时修改 `providers.json` 和 `config.toml` 的命令,默认遵守:
|
|
293
|
+
|
|
294
|
+
- 单次锁
|
|
295
|
+
- 单次备份
|
|
296
|
+
- 单次失败整体回滚
|
|
297
|
+
|
|
298
|
+
不能接受的结果:
|
|
299
|
+
|
|
300
|
+
- `providers.json` 已更新但 `config.toml` 未同步
|
|
301
|
+
- `config.toml` 已更新但 `providers.json` 未同步
|
|
302
|
+
- active profile 指向已不存在的 section
|
|
303
|
+
|
|
304
|
+
## 迁移与诊断
|
|
305
|
+
|
|
306
|
+
需要识别的历史状态:
|
|
307
|
+
|
|
308
|
+
- `providers.json` 可用,但 `config.toml` 中只有手工维护 profile
|
|
309
|
+
- `providers.json` 引用了 profile,但对应 section 不存在
|
|
310
|
+
- `config.toml` 存在历史 profile,但没有任何 provider 引用
|
|
311
|
+
- 当前 active profile 指向 unmanaged profile
|
|
312
|
+
|
|
313
|
+
迁移原则:
|
|
314
|
+
|
|
315
|
+
- 不要求用户先手工清空历史状态
|
|
316
|
+
- `setup`、`import --merge`、`doctor`、`status` 必须能识别这些状态
|
|
317
|
+
- 可安全 adopt 的 unmanaged profile,允许纳入受管
|
|
318
|
+
- 对悬空引用或缺失 section,默认不静默修复,必须告知用户下一步建议
|
|
319
|
+
|
|
320
|
+
`doctor` / `status` 至少需要覆盖:
|
|
321
|
+
|
|
322
|
+
- orphaned profile reference
|
|
323
|
+
- unmanaged active profile
|
|
324
|
+
- shared profile reference count
|
|
325
|
+
- orphaned profile section
|
|
326
|
+
- destructive remove blocked
|
|
327
|
+
|
|
328
|
+
## 验收标准
|
|
329
|
+
|
|
330
|
+
达到以下条件时,`0.0.5` 可以认为完成:
|
|
331
|
+
|
|
332
|
+
- `config show` 在文本和 `--json` 模式下返回稳定结构
|
|
333
|
+
- `config list-profiles` 能稳定展示 `managed`、`isActive`、`linkedProviders` 和 `model`
|
|
334
|
+
- `add` / `edit` / `remove` 会同步维护 linked profile sections
|
|
335
|
+
- 共享 profile 场景不会误删仍被引用的 section
|
|
336
|
+
- active profile 不会因删除 provider 或迁移 profile 而悬空
|
|
337
|
+
- 历史 `0.0.4` 状态可被识别,并通过 adopt / repair 路径收敛
|
|
338
|
+
- 结构化 TOML 修改后,非受管内容、顺序和注释保持稳定
|
|
339
|
+
- 双写失败时 `providers.json` 与 `config.toml` 能整体回滚
|
|
340
|
+
|
|
341
|
+
## 结论
|
|
342
|
+
|
|
343
|
+
`0.0.5` 是 `codex-switch` 从 provider registry 工具走向 config-aware CLI 的第一步。它的重点不是扩张命令面,而是建立稳定的 config 管理、一致性事务和可诊断能力,为后续 `0.0.5 -> 0.1.0` 演进打基础。
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
# codex-switch PRD
|
|
2
2
|
|
|
3
|
+
> 状态说明:
|
|
4
|
+
> 这份文档保留为 `0.0.x` / MVP 阶段的历史 PRD 基线。
|
|
5
|
+
> 从 `0.0.3` 继续走向 `0.1.0` 的目标规格,请参考 [`codex-switch-prd-v0.1.0.md`](./codex-switch-prd-v0.1.0.md)。
|
|
6
|
+
|
|
3
7
|
## 文档信息
|
|
4
8
|
|
|
5
|
-
- 状态:
|
|
9
|
+
- 状态:Historical Baseline
|
|
6
10
|
- 产品名:`codex-switch`
|
|
7
11
|
- CLI 命令名:`codexs`
|
|
8
12
|
- 版本范围:MVP / CLI First
|
|
9
|
-
-
|
|
10
|
-
- 对应研究稿:[
|
|
11
|
-
- 对应技术架构:[
|
|
12
|
-
- 对应命令设计:[
|
|
13
|
+
- 文档定位:`0.0.x` / MVP 阶段历史 PRD
|
|
14
|
+
- 对应研究稿:[`../codex-switch-product-research.md`](../codex-switch-product-research.md)
|
|
15
|
+
- 对应技术架构:[`../codex-switch-technical-architecture.md`](../codex-switch-technical-architecture.md)
|
|
16
|
+
- 对应命令设计:[`../codex-switch-command-design.md`](../codex-switch-command-design.md)
|
|
13
17
|
|
|
14
18
|
## 一句话定义
|
|
15
19
|
|