@minniexcode/codex-switch 0.0.5 → 0.0.7

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.
Files changed (71) hide show
  1. package/README.AI.md +5 -2
  2. package/README.md +44 -100
  3. package/dist/app/add-provider.js +28 -4
  4. package/dist/app/edit-provider.js +47 -19
  5. package/dist/app/export-providers.js +2 -2
  6. package/dist/app/get-current-profile.js +1 -1
  7. package/dist/app/get-status.js +10 -3
  8. package/dist/app/import-providers.js +15 -7
  9. package/dist/app/init-codex.js +68 -0
  10. package/dist/app/list-backups.js +1 -1
  11. package/dist/app/list-config-profiles.js +3 -2
  12. package/dist/app/list-providers.js +2 -1
  13. package/dist/app/remove-provider.js +2 -2
  14. package/dist/app/rollback-backup.js +1 -1
  15. package/dist/app/rollback-latest.js +1 -1
  16. package/dist/app/run-doctor.js +83 -6
  17. package/dist/app/run-mutation.js +2 -2
  18. package/dist/app/setup-codex.js +21 -12
  19. package/dist/app/show-config.js +11 -3
  20. package/dist/app/show-provider.js +1 -1
  21. package/dist/app/switch-provider.js +16 -9
  22. package/dist/cli/add-interactive.js +7 -104
  23. package/dist/cli/args.js +6 -135
  24. package/dist/cli/help.js +8 -313
  25. package/dist/cli/interactive.js +17 -225
  26. package/dist/cli/output.js +21 -6
  27. package/dist/cli/prompt.js +4 -106
  28. package/dist/cli.js +10 -404
  29. package/dist/commands/args.js +132 -0
  30. package/dist/commands/dispatch.js +16 -0
  31. package/dist/commands/handlers.js +460 -0
  32. package/dist/commands/help.js +120 -0
  33. package/dist/commands/registry.js +351 -0
  34. package/dist/commands/types.js +2 -0
  35. package/dist/domain/config.js +235 -21
  36. package/dist/domain/providers.js +16 -2
  37. package/dist/domain/setup.js +1 -0
  38. package/dist/infra/backup-repo.js +9 -206
  39. package/dist/infra/codex-cli.js +9 -126
  40. package/dist/infra/codex-paths.js +6 -67
  41. package/dist/infra/config-repo.js +59 -0
  42. package/dist/infra/fs-utils.js +8 -93
  43. package/dist/infra/lock-repo.js +4 -95
  44. package/dist/infra/providers-repo.js +8 -94
  45. package/dist/interaction/add-interactive.js +99 -0
  46. package/dist/interaction/interactive.js +289 -0
  47. package/dist/interaction/prompt.js +110 -0
  48. package/dist/runtime/codex-cli.js +130 -0
  49. package/dist/runtime/codex-probe.js +57 -0
  50. package/dist/runtime/types.js +2 -0
  51. package/dist/storage/auth-repo.js +160 -0
  52. package/dist/storage/backup-repo.js +210 -0
  53. package/dist/storage/codex-paths.js +71 -0
  54. package/dist/storage/config-repo.js +266 -0
  55. package/dist/storage/fs-utils.js +97 -0
  56. package/dist/storage/lock-repo.js +99 -0
  57. package/dist/storage/providers-repo.js +98 -0
  58. package/docs/Design/codex-switch-v0.0.5-design.md +32 -22
  59. package/docs/Design/codex-switch-v0.0.6-design.md +708 -0
  60. package/docs/Design/codex-switch-v0.0.7-design.md +862 -0
  61. package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +227 -89
  62. package/docs/PRD/codex-switch-prd-v0.1.0.md +200 -226
  63. package/docs/PRD/codex-switch-prd.md +1 -1
  64. package/docs/Reference/codex-config-reference.md +604 -0
  65. package/docs/Reference/codex-config-reference.zh-CN.md +633 -0
  66. package/docs/cli-usage.md +78 -29
  67. package/docs/codex-switch-technical-architecture.md +73 -4
  68. package/docs/test-report-0.0.5.md +163 -0
  69. package/docs/test-report-0.0.7.md +118 -0
  70. package/docs/testing.md +151 -0
  71. package/package.json +1 -1
@@ -14,15 +14,21 @@
14
14
  - 对应技术架构:[`../codex-switch-technical-architecture.md`](../codex-switch-technical-architecture.md)
15
15
  - 对应命令设计:[`../codex-switch-command-design.md`](../codex-switch-command-design.md)
16
16
 
17
+ 说明:
18
+
19
+ - 当前 active PRD 文件名沿用历史命名,但正文语义已更新为 `0.0.7`
20
+ - 本文档以“版本演进路线”而不是“文件名字面值”作为解释基准
21
+
17
22
  ## 一句话定义
18
23
 
19
- `codex-switch` 的 `0.1.0` 目标,是从一个已经具备 provider 管理和基础 config consistency 能力的本地 CLI,演进为一套对人类和 AI 都稳定、可初始化、可诊断、可恢复、可结构化管理配置、可持续扩展的发布级命令体系。
24
+ `codex-switch` 的 `0.1.0` 目标,是从一个已经具备 provider 管理、config consistency 和本地事务能力的 CLI,演进为一套对人类、AI 和后续集成层都稳定的发布级命令体系;其中 `0.0.7` 必须先完成 provider 配置模型纠偏,统一 `providers.json`、`config.toml` 与 `auth.json` 的职责边界。
20
25
 
21
26
  ## 版本语义
22
27
 
23
- - `0.0.x`:测试 / 验证阶段版本,用于收敛模型、命令面和失败语义
24
- - `0.1.0`:第一条稳定发布规格线,不要求立即全部完成,但要求边界清晰
25
- - 本文档描述的是 `0.0.5` 之后继续走向 `0.1.0` 的长期目标
28
+ - `0.0.x`:测试 / 验证阶段版本,用于收敛命令面、错误契约、事务安全与模块边界
29
+ - `0.0.6`:稳定性修复 + 模块化重构里程碑,为后续 integration-ready 能力打基础
30
+ - `0.0.7`:Provider Configuration Correction,修复 provider secret 的配置落点,移除 `config.toml api_key` 假设,统一 `env_key` 驱动的运行态认证镜像
31
+ - `0.1.0`:第一条稳定发布规格线,要求公共契约、恢复能力和扩展边界清晰
26
32
 
27
33
  ## `0.1.0` 总体目标
28
34
 
@@ -30,18 +36,21 @@
30
36
 
31
37
  - 保持 CLI 与 JSON 契约稳定
32
38
  - 保持 `setup`、provider registry、备份恢复主线能力不回退
33
- - 将 `config.toml` 从“可结构化读取与最小受管写入”推进到“稳定受管 provider-linked sections”
34
39
  - 让 provider registry 与 linked config sections 的一致性成为默认能力
35
- - 让备份与回滚继续覆盖所有关键写操作
36
- - 为未来 auth / extension 集成保留明确边界
40
+ - 让 `providers.json`、`config.toml`、`auth.json` 的职责边界清晰且可诊断
41
+ - 让备份、回滚和诊断继续覆盖所有关键写操作
42
+ - 让模块边界足以承载未来第三方 auth / proxy / SDK 集成
43
+ - 在不破坏主 CLI 契约的前提下扩展运行时能力边界
37
44
 
38
45
  ## 长期演进守则
39
46
 
40
- 后续新增命令统一遵守:
47
+ 后续新增能力统一遵守:
41
48
 
42
49
  - 不破坏当前 JSON envelope
43
50
  - 不复用语义不匹配的错误码
44
51
  - 所有写命令默认纳入备份与回滚模型
52
+ - 所有交互都只是 TTY 增强层,不改变自动化显式契约
53
+ - 不再把 provider secret 写入 `config.toml`
45
54
 
46
55
  ## 稳定公共契约
47
56
 
@@ -79,9 +88,10 @@
79
88
  "packycode": {
80
89
  "profile": "packycode",
81
90
  "apiKey": "sk-xxx",
91
+ "envKey": "PACKYCODE_API_KEY",
82
92
  "baseUrl": "https://example.com/v1",
83
- "note": "primary free model route",
84
- "tags": ["free", "daily"]
93
+ "note": "primary route",
94
+ "tags": ["paid"]
85
95
  }
86
96
  }
87
97
  }
@@ -91,85 +101,101 @@
91
101
 
92
102
  - `profile` 仍然必填
93
103
  - `apiKey` 仍按完整 managed provider 处理
104
+ - `envKey` 仍然必填
94
105
  - 不引入“半初始化 provider”作为正式稳定状态
95
106
 
107
+ `envKey` 的产品语义是:
108
+
109
+ - 与 `config.toml` 中 `[model_providers.<name>].env_key` 对应
110
+ - 作为当前 provider 写入 `auth.json` 时的目标键名
111
+ - 例如 `envKey = "PACKYCODE_API_KEY"` 时,切换后 `auth.json` 中应写入同名字段
112
+
96
113
  #### `config.toml`
97
114
 
98
- 到 `0.1.0` 为止,`config.toml` 的定位是“部分受管的 runtime projection”:
115
+ 到 `0.1.0` 为止,`config.toml` 的定位继续是“部分受管的 runtime projection”:
99
116
 
100
117
  - 顶层 active `profile = "..."` 继续受管
101
118
  - 与 provider 关联的 `[profiles.<name>]` section 进入受管范围
119
+ - `[model_providers.<name>].base_url` 继续作为 runtime route 字段
120
+ - `[model_providers.<name>].env_key` 是当前唯一支持的 provider 认证配置字段
102
121
  - 非 provider 相关的顶层键、section 和注释仍允许存在,但不进入通用编辑器范围
103
122
 
123
+ 明确限制:
124
+
125
+ - `[model_providers.<name>].api_key` 不再是合法受管配置字段
126
+ - `codex-switch` 不再从 `config.toml` 读取或写入 provider secret
127
+ - 本版本不支持其他认证模式的受管配置界面
128
+
104
129
  #### `ManagedProfileFields`
105
130
 
106
- `0.1.0` 之前第一批稳定受管 profile 持久化字段先锁定为最小集合:
131
+ `0.1.0` 之前第一批稳定受管 profile 持久化字段继续锁定为最小集合:
107
132
 
108
133
  ```json
109
134
  {
110
- "model": "gpt-5"
135
+ "model": "gpt-5",
136
+ "modelProvider": "packycode"
111
137
  }
112
138
  ```
113
139
 
114
140
  约束:
115
141
 
116
- - 第一批正式受管字段只锁 `model`
117
- - `baseUrl` endpoint 类字段继续只保留在 `providers.json`
142
+ - 第一批正式受管字段锁 `model` 与 `model_provider`
143
+ - `baseUrl` 作为读取视图字段,可由 `model_provider -> model_providers.<name>.base_url` 解析
144
+ - `envKey` 不属于 `[profiles.*]` 的受管字段,而属于 runtime provider section 与 managed registry 的一致性边界
118
145
  - 后续扩展 profile 字段时,只能做加法
119
146
 
120
- #### `ManagedProfileView`
147
+ #### `auth.json`
148
+
149
+ `auth.json` 是受管运行态认证镜像文件:
121
150
 
122
- 面向 CLI、AI 和脚本输出的读取视图,与持久化字段分离:
151
+ - 不是 provider registry 的事实源
152
+ - 当前激活 provider 的 `apiKey` 与 `envKey` 决定其内容
153
+ - 运行态 secret 只投影到 `auth.json`,不再投影到 `config.toml`
154
+
155
+ 当前稳定写入形态:
123
156
 
124
157
  ```json
125
158
  {
126
- "name": "packycode",
127
- "model": "gpt-5",
128
- "linkedProviders": ["packycode"],
129
- "isActive": true,
130
- "managed": true
159
+ "auth_mode": "apikey",
160
+ "PACKYCODE_API_KEY": "sk-xxx"
131
161
  }
132
162
  ```
133
163
 
134
- ### TOML 处理原则
164
+ 约束:
165
+
166
+ - `auth_mode` 当前稳定为 `apikey`
167
+ - secret 键名不是固定 `OPENAI_API_KEY`
168
+ - secret 键名由当前 provider 的 `envKey` 决定
135
169
 
136
- 为了支持结构化 config 管理,`0.1.0` 稳定主线要求:
170
+ ## `0.1.0` 模块化目标
137
171
 
138
- - 不再以字符串匹配作为唯一 TOML 修改策略
139
- - 对受管 section 的读取、创建、删除、重命名和字段更新,必须支持可验证的非破坏性结构化读取和修改
140
- - 修改受管部分时,不应破坏非受管 TOML 内容、顺序、空行和注释
172
+ ### 核心结构方向
141
173
 
142
- ### 错误码演进原则
174
+ `0.1.0` 为止,`codex-switch` 不应只停留在“`cli / app / domain / infra` 四层可用”这个层次,而应进一步收敛出稳定的能力边界:
143
175
 
144
- 保留现有领域错误码,并把错误码体系从 MVP 复用模式收紧到语义匹配模式。
176
+ - `Command Surface`
177
+ - `Interaction Layer`
178
+ - `Application Use Cases`
179
+ - `Domain Policies`
180
+ - `Storage Repositories`
181
+ - `Runtime Integrations`
145
182
 
146
- 现有保留:
183
+ 这些边界的意义不是强制锁死具体类名,而是保证未来新增能力不会继续把复杂度堆回单一 CLI 入口。
147
184
 
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`
185
+ ### Runtime Integrations 的长期定位
158
186
 
159
- 建议新增 / 预留:
187
+ `Runtime Integrations` 是 `0.1.0` 目标线中必须预留清楚的能力域,负责:
160
188
 
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`
189
+ - `codex` CLI 调用与可用性检查
190
+ - 本地认证镜像写入与诊断
191
+ - 本地 proxy runtime
192
+ - 外部 SDK / 二进制依赖可用性探测
193
+ - integration 级错误语义收敛
194
+
195
+ 说明:
196
+
197
+ - 当前主线只支持 `env_key` 模型
198
+ - 第三方 auth adapter 仍属于未来扩展方向,不是 `0.0.7` 的受管能力
173
199
 
174
200
  ## 已落地能力的 `0.1.0` 稳定化要求
175
201
 
@@ -179,16 +205,51 @@
179
205
 
180
206
  - 继续保持从环境检测到 registry 初始化的主流程
181
207
  - 继续允许 `overwrite`、`merge` 和交互式补问缺失关键字段
182
- - 与新的 config 管理能力保持兼容,不写出未来无法被结构化读取的受管状态
208
+ - config 管理能力和未来 runtime integration 边界保持兼容
183
209
  - 对历史遗留不一致状态给出 adopt / repair 建议,而不是静默忽略
184
210
 
211
+ `0.0.7` 起,`setup` 的 adopt 规则明确收敛为:
212
+
213
+ - 只 adopt 已具备 `model`、`model_provider`、匹配 `model_providers.<name>.base_url`、匹配 `model_providers.<name>.env_key` 的 profile
214
+ - adopt 时从 runtime section 读取 `env_key`
215
+ - adopt 时不再从 `config.toml` 读取 `api_key`
216
+ - adopt 时只对 `apiKey` 进行交互补问或显式输入补全
217
+ - 非交互模式下,如果无法获得 `apiKey`,必须明确失败
218
+
219
+ 修复目标:
220
+
221
+ - `setup` 不得再因为缺失 `config.toml api_key` 而把合法 provider 判为 incomplete
222
+
185
223
  ### provider registry 命令
186
224
 
187
225
  `show`、`edit`、`import --merge`、`backups list`、`rollback <backup-id>` 的 `0.1.0` 要求是:
188
226
 
189
227
  - 保持命令名和基础 JSON 契约稳定
190
228
  - 把错误语义继续收紧
191
- - 让与 `config.toml` 关联的行为更完整
229
+ - 让与 `config.toml` 和 `auth.json` 关联的行为更完整
230
+ - 不因引入未来第三方集成而改变现有 provider/config 的领域边界
231
+
232
+ 当前 provider registry 的稳定字段口径是:
233
+
234
+ - `profile`
235
+ - `apiKey`
236
+ - `envKey`
237
+ - `baseUrl`
238
+ - `note`
239
+ - `tags`
240
+
241
+ ### `switch`
242
+
243
+ `switch` 在 `0.1.0` 主线中的要求是:
244
+
245
+ - 更新 `config.toml` 顶层 active profile
246
+ - 根据目标 provider 的 `envKey` 和 `apiKey` 重写 `auth.json`
247
+ - 将 `config.toml` 与 `auth.json` 置于同一事务边界
248
+
249
+ 明确限制:
250
+
251
+ - `switch` 不再依赖 `config.toml api_key`
252
+ - `switch` 的成功条件之一,是 `auth.json` 中的键名和值与当前 provider 的 `envKey` / `apiKey` 一致
192
253
 
193
254
  ### `import --merge`
194
255
 
@@ -198,33 +259,83 @@
198
259
  - 不能只更新 `providers.json` 而放任 linked profile sections 漂移
199
260
  - 当导入结果引用了缺失 profile 时,必须进入与 `add` / `edit` 一致的受管规则
200
261
  - 非交互模式下,如果导入内容不能满足受管 profile 创建条件,应明确失败
201
- - 交互模式下可以进入 adopt / repair 辅助流,但最终写入结果仍必须满足一致性约束
262
+ - 交互模式下可以进入 adopt 辅助流,但不会为缺失 `model_providers` runtime section 或缺失 `env_key` 做隐式 repair
263
+
264
+ ## `0.1.0` 主线能力域
265
+
266
+ 下面这些方向不要求在 `0.0.6` 全部交付,但它们不再只是模糊远期方向,而是 `0.1.0` 主线需要承接的能力域。
267
+
268
+ ### Config Management & Consistency
269
+
270
+ 目标:
271
+
272
+ - 巩固结构化 TOML 读写
273
+ - 稳定 `config-show`、`config-list-profiles`
274
+ - 让 provider 管理命令可靠同步 linked profile sections
275
+ - 明确共享 profile、孤儿 section 和 active profile 安全规则
276
+ - 诊断 `providers.json.envKey`、runtime `env_key` 与 `auth.json` 镜像键名之间的一致性
277
+
278
+ ### Backup / Recovery Evolution
279
+
280
+ 目标:
281
+
282
+ - 保持 `backups` 与指定回滚能力稳定
283
+ - 确保跨 `providers.json`、`config.toml`、`auth.json` 的多文件写入仍可完整恢复
284
+ - 明确三者的职责边界:
285
+ - `providers.json` = 管理态事实源
286
+ - `config.toml` = provider/profile 路由事实源
287
+ - `auth.json` = 运行态认证镜像
288
+
289
+ ### Error Contract Hardening
202
290
 
203
- ## `0.1.0` 远期能力域
291
+ 目标:
292
+
293
+ - 收紧错误码语义
294
+ - 区分环境错误、参数错误、配置解析错误、集成错误和恢复错误
295
+ - 保持 TTY / 非交互模式下的错误结果可预测
204
296
 
205
- 下面这些方向明确有价值,但不进入 `0.0.5` 当前里程碑,只作为继续走向 `0.1.0` 的能力域。
297
+ ### Third-Party Auth Adapters
206
298
 
207
- ### 第三方 auth / extension 集成
299
+ 目标:
300
+
301
+ - 保留未来把第三方认证来源封装为独立 integration 能力的空间
302
+ - 不把第三方 auth 状态直接混入 provider registry 事实源
303
+ - 但当前主线不承诺 `env_key` 之外的其他认证模型
208
304
 
209
- 示例方向:
305
+ ### Local Proxy Runtime
210
306
 
211
- - 接入 Copilot auth
212
- - 在本地启动代理服务,使特定上游可在 Codex 中使用
213
- - 安装和管理第三方依赖
307
+ 目标:
214
308
 
215
- 当前定位:
309
+ - 为需要本地代理的上游保留运行时承载能力
310
+ - 允许启动、检查、停止或探测代理状态的能力进入集成层
311
+ - 不破坏现有 provider/profile 切换和回滚模型
216
312
 
217
- - 作为单独能力域保留
218
- - 不在当前主 PRD 中锁定具体命令名和交互细节
219
- - 不进入 `0.1.0` 稳定主线的验收标准
313
+ ### External Dependency Lifecycle
220
314
 
221
- ### 更大范围的 profile schema 管理
315
+ 目标:
222
316
 
223
- 未来如果需要扩展:
317
+ - 识别和诊断外部 SDK、CLI、二进制依赖是否可用
318
+ - 把依赖缺失、版本不兼容、环境不可执行等问题映射到清晰错误语义
319
+ - 为未来的依赖安装或引导能力留出接口,但不强制 `0.0.x` 提前产品化
224
320
 
225
- - 可以逐步纳入 `model` 之外的 profile 字段
226
- - 必须保持增量式 schema 扩展
227
- - 不能在未定义字段契约前把 `config.toml` 直接提升为 full config manager
321
+ ## GitHub Copilot 代表性场景
322
+
323
+ GitHub Copilot 在演进 PRD 中的定位是代表性用例,而不是唯一目标:
324
+
325
+ - 可作为未来本地 proxy runtime 需求的首个真实驱动
326
+ - 可用来验证 `Runtime Integrations` 分层是否足够清楚
327
+
328
+ 当前不提前锁定:
329
+
330
+ - 具体命令名
331
+ - 具体交互流程
332
+ - `@github/copilot-sdk` 的封装形态
333
+ - 本地代理协议和生命周期细节
334
+
335
+ 说明:
336
+
337
+ - Copilot 不再作为当前 auth 模型设计的直接驱动
338
+ - 当前主线只支持 `env_key` 模式
228
339
 
229
340
  ## 主题里程碑
230
341
 
@@ -235,32 +346,51 @@
235
346
  目标:
236
347
 
237
348
  - 巩固结构化 TOML 读写
238
- - 稳定 `config show`、`config list-profiles`
349
+ - 稳定 `config-show`、`config-list-profiles`
239
350
  - 让 provider 管理命令可靠同步 linked profile sections
240
351
  - 明确共享 profile、孤儿 section 和 active profile 安全规则
241
352
 
242
- ### 里程碑 B:Backup / Recovery Evolution
353
+ ### 里程碑 B:`0.0.6` / Stability & Modularization
243
354
 
244
355
  目标:
245
356
 
246
- - 保持 `backups list` 与指定回滚能力稳定
247
- - 确保跨 `providers.json` 与 `config.toml` 的双写场景仍可完整恢复
248
- - 为更复杂的 config 变更继续复用同一事务模型
357
+ - 修复 `0.0.5` 已落地命令的稳定性问题
358
+ - 统一 help、交互、错误语义和恢复模型
359
+ - 解决 `cli.ts` 过重问题,明确 command / interaction / application / integration 边界
360
+ - 为后续 integration-ready 架构建立清晰基础
249
361
 
250
- ### 里程碑 C:Error Contract Hardening
362
+ ### 里程碑 C:`0.0.7` / Provider Configuration Correction
363
+
364
+ 目标:
365
+
366
+ - 去掉 `config.toml api_key` 假设
367
+ - 在 `providers.json` 中正式引入 `envKey`
368
+ - 将 runtime auth mirror 统一改为 `auth.json`
369
+ - 将 `setup`、`switch`、`doctor`、fixture、文档、测试统一到 `env_key` 模型
370
+ - 修正 provider secret 的采集、投影与恢复语义
371
+
372
+ ### 里程碑 D:Backup / Recovery Evolution
373
+
374
+ 目标:
375
+
376
+ - 保持历史备份、显式回滚和多文件恢复稳定
377
+ - 让更复杂的 runtime 变更继续复用同一事务模型
378
+
379
+ ### 里程碑 E:Error Contract Hardening
251
380
 
252
381
  目标:
253
382
 
254
383
  - 收紧错误码语义
255
384
  - 区分环境错误、参数错误、配置解析错误和恢复错误
256
- - 保持 TTY / 非交互模式下的错误结果可预测
385
+ - 对外部 integration 的失败提供清晰可预测的错误契约
257
386
 
258
- ### 里程碑 DExtensions / Auth Integration
387
+ ### 里程碑 FIntegrations & Runtime Expansion
259
388
 
260
389
  目标:
261
390
 
262
- - 评估第三方 auth 与本地代理集成
263
- - 评估交互式依赖安装与 extension 管理
391
+ - 逐步引入第三方 integration
392
+ - 逐步引入本地 proxy runtime
393
+ - 逐步引入外部依赖可用性管理
264
394
  - 在不破坏主 CLI 契约的前提下扩展能力边界
265
395
 
266
396
  ## 对实现的要求
@@ -273,7 +403,9 @@
273
403
  - 所有新增错误码都必须语义清晰
274
404
  - 所有新增 JSON 返回都只能扩展 `data` 和 `warnings`
275
405
  - 结构化 TOML 写回不能破坏非受管部分
276
- - 多候选目录发现必须在交互和非交互模式下给出一致且可预测的行为
406
+ - provider secret 不再写入 `config.toml`
407
+ - 第三方 integration 不得直接破坏 provider registry 作为 SSOT 的边界
408
+ - 多候选目录发现和依赖可用性检查必须在交互与非交互模式下给出一致且可预测的行为
277
409
 
278
410
  ## `0.1.0` 目标完成标准
279
411
 
@@ -283,26 +415,32 @@
283
415
  - `setup` 在多候选 Codex 目录场景下可交互选择或手动输入,在非交互场景下返回明确歧义错误
284
416
  - provider registry 的查看、编辑、导入合并能力完整
285
417
  - 用户和 AI 可以通过稳定命令结构化查看受管 `config.toml`
418
+ - 受管 provider 均具备 `profile`、`apiKey`、`envKey`
286
419
  - `add` / `edit` / `remove` 执行后,`providers.json` 与 linked profile sections 不再出现预期内的一致性漂移
420
+ - `switch` 能按当前 provider 的 `envKey` 将 `apiKey` 正确写入 `auth.json`
287
421
  - 共享 profile 场景不会误删仍被引用的 section
288
422
  - active profile 不会因为 provider 删除或 profile 迁移而变成悬空状态
289
- - 历史 `0.0.4` / `0.0.5` 状态可以被识别,并通过 adopt / repair 路径逐步收敛
423
+ - 历史 `0.0.4` / `0.0.5` / `0.0.6` / `0.0.7` 状态可以被识别,并通过 adopt / repair 路径逐步收敛
290
424
  - 历史备份可被显式枚举和恢复
291
425
  - CLI 错误码不再存在明显语义复用问题
292
- - CLI 契约对 AI 和脚本调用保持稳定
426
+ - 当前主线的 `env_key` provider 模型已稳定,后续 integration 可在此基础上扩展
293
427
 
294
428
  ## 建议测试场景
295
429
 
296
430
  至少需要覆盖:
297
431
 
298
- - `config show` 与 `config list-profiles` 的稳定输出
432
+ - `config-show` 与 `config-list-profiles` 的稳定输出
299
433
  - 共享 profile 场景下的 `add` / `edit` / `remove` 行为
300
434
  - `setup` 在多目录候选下的交互和非交互分支
435
+ - `setup` 对缺失 `env_key` 的 profile 明确失败
436
+ - `setup` 在无 `config.toml api_key` 时仍可正常 adopt 合法 provider
301
437
  - `import --merge` 在缺失 profile / adopt / repair 下的一致性行为
302
438
  - 结构化 TOML 修改后,非受管内容、顺序和注释保持稳定
303
- - 双写失败时 `providers.json` `config.toml` 能整体回滚
304
- - 历史 workspace、共享 profile、孤儿 profile section、缺失 linked section 都能被 `doctor` / `status` 正确识别
439
+ - `switch` 根据不同 provider 的 `envKey` 写入不同的 `auth.json` 键名
440
+ - 双写或三写失败时 `providers.json`、`config.toml` `auth.json` 能整体回滚
441
+ - 历史 workspace、共享 profile、孤儿 profile section、缺失 linked section、`envKey` 不一致都能被 `doctor` / `status` 正确识别
442
+ - 外部 CLI / SDK / integration 缺失或不可用时,错误语义清晰且不污染核心 provider/config 状态
305
443
 
306
444
  ## 结论
307
445
 
308
- `0.1.0` 不是简单把 `0.0.x` 重命名为稳定版,而是在保持当前本地事务式切换模型不变的前提下,进一步收敛 config 管理、错误契约和恢复能力,并为未来更大范围的 auth / extension 集成留出清晰边界。
446
+ `0.1.0` 不是简单把 `0.0.x` 重命名为稳定版,而是在先完成 `0.0.7` 的 provider 配置模型纠偏之后,进一步收敛 config 管理、错误契约、恢复能力和模块化扩展边界,并把后续 integration 能力建立在清晰的 `providers.json`、`config.toml`、`auth.json` 分层之上。