@minniexcode/codex-switch 0.1.0 → 0.1.2

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 (68) hide show
  1. package/README.AI.md +141 -110
  2. package/README.CN.md +215 -179
  3. package/README.md +224 -183
  4. package/dist/app/add-provider.js +16 -23
  5. package/dist/app/bridge.js +2 -1
  6. package/dist/app/edit-provider.js +30 -65
  7. package/dist/app/get-current-profile.js +15 -3
  8. package/dist/app/get-status.js +11 -8
  9. package/dist/app/list-config-profiles.js +3 -1
  10. package/dist/app/list-providers.js +10 -4
  11. package/dist/app/remove-provider.js +52 -19
  12. package/dist/app/run-doctor.js +26 -29
  13. package/dist/app/setup-codex.js +3 -3
  14. package/dist/app/show-config.js +3 -1
  15. package/dist/app/switch-provider.js +38 -6
  16. package/dist/cli/output.js +29 -19
  17. package/dist/commands/handlers.js +3 -2
  18. package/dist/commands/help.js +3 -3
  19. package/dist/commands/registry.js +29 -29
  20. package/dist/domain/config.js +293 -209
  21. package/dist/domain/providers.js +8 -0
  22. package/dist/domain/runtime-state.js +15 -15
  23. package/dist/domain/setup.js +3 -1
  24. package/dist/interaction/interactive.js +2 -2
  25. package/dist/runtime/codex-version.js +7 -0
  26. package/dist/runtime/copilot-adapter.js +326 -70
  27. package/dist/runtime/copilot-bridge-worker.js +27 -2
  28. package/dist/runtime/copilot-bridge.js +192 -10
  29. package/dist/runtime/copilot-cli.js +7 -0
  30. package/dist/runtime/copilot-installer.js +59 -1
  31. package/dist/runtime/copilot-sdk-loader.js +4 -1
  32. package/dist/storage/config-repo.js +6 -14
  33. package/docs/Design/codex-switch-v0.1.0-design.md +32 -152
  34. package/docs/Design/codex-switch-v0.1.1-design.md +22 -0
  35. package/docs/Design/codex-switch-v0.1.2-design.md +65 -0
  36. package/docs/PRD/codex-switch-prd-v0.1.0.md +65 -217
  37. package/docs/PRD/codex-switch-prd-v0.1.1.md +26 -0
  38. package/docs/PRD/codex-switch-prd-v0.1.2.md +41 -0
  39. package/docs/Reference/codex-config-reference.md +41 -0
  40. package/docs/Reference/codex-config-reference.zh-CN.md +41 -0
  41. package/docs/Tests/testing.md +1 -1
  42. package/docs/cli-usage.md +290 -223
  43. package/docs/codex-switch-command-design.md +2 -2
  44. package/docs/codex-switch-product-overview.md +18 -13
  45. package/docs/codex-switch-product-research.md +2 -2
  46. package/docs/codex-switch-technical-architecture.md +84 -1115
  47. package/package.json +2 -2
  48. package/docs/Design/codex-switch-copilot-integration-design.md +0 -517
  49. package/docs/Design/codex-switch-v0.0.10-design.md +0 -669
  50. package/docs/Design/codex-switch-v0.0.11-design.md +0 -824
  51. package/docs/Design/codex-switch-v0.0.12-design.md +0 -343
  52. package/docs/Design/codex-switch-v0.0.4-design.md +0 -874
  53. package/docs/Design/codex-switch-v0.0.5-design.md +0 -932
  54. package/docs/Design/codex-switch-v0.0.6-design.md +0 -708
  55. package/docs/Design/codex-switch-v0.0.7-design.md +0 -862
  56. package/docs/Design/codex-switch-v0.0.8-design.md +0 -132
  57. package/docs/Design/codex-switch-v0.0.9-design.md +0 -182
  58. package/docs/Design/codex-switch-v0.0.9-to-v0.0.12-roadmap.md +0 -413
  59. package/docs/PRD/codex-switch-prd-v0.0.10.md +0 -406
  60. package/docs/PRD/codex-switch-prd-v0.0.11.md +0 -577
  61. package/docs/PRD/codex-switch-prd-v0.0.12.md +0 -279
  62. package/docs/PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md +0 -446
  63. package/docs/PRD/codex-switch-prd-v0.0.8.md +0 -62
  64. package/docs/PRD/codex-switch-prd-v0.0.9.md +0 -166
  65. package/docs/PRD/codex-switch-prd.md +0 -650
  66. package/docs/Tests/test-report-0.0.5.md +0 -163
  67. package/docs/Tests/test-report-0.0.7.md +0 -118
  68. package/docs/Tests/testing-bridge-v0.0.9.md +0 -367
@@ -1,446 +0,0 @@
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
- - 当前 active PRD 文件名沿用历史命名,但正文语义已更新为 `0.0.7`
20
- - 本文档以“版本演进路线”而不是“文件名字面值”作为解释基准
21
-
22
- ## 一句话定义
23
-
24
- `codex-switch` 的 `0.1.0` 目标,是从一个已经具备 provider 管理、config consistency 和本地事务能力的 CLI,演进为一套对人类、AI 和后续集成层都稳定的发布级命令体系;其中 `0.0.7` 必须先完成 provider 配置模型纠偏,统一 `providers.json`、`config.toml` 与 `auth.json` 的职责边界。
25
-
26
- ## 版本语义
27
-
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`:第一条稳定发布规格线,要求公共契约、恢复能力和扩展边界清晰
32
-
33
- ## `0.1.0` 总体目标
34
-
35
- `0.1.0` 需要同时满足以下目标:
36
-
37
- - 保持 CLI 与 JSON 契约稳定
38
- - 保持 `setup`、provider registry、备份恢复主线能力不回退
39
- - 让 provider registry 与 linked config sections 的一致性成为默认能力
40
- - 让 `providers.json`、`config.toml`、`auth.json` 的职责边界清晰且可诊断
41
- - 让备份、回滚和诊断继续覆盖所有关键写操作
42
- - 让模块边界足以承载未来第三方 auth / proxy / SDK 集成
43
- - 在不破坏主 CLI 契约的前提下扩展运行时能力边界
44
-
45
- ## 长期演进守则
46
-
47
- 后续新增能力统一遵守:
48
-
49
- - 不破坏当前 JSON envelope
50
- - 不复用语义不匹配的错误码
51
- - 所有写命令默认纳入备份与回滚模型
52
- - 所有交互都只是 TTY 增强层,不改变自动化显式契约
53
- - 不再把 provider secret 写入 `config.toml`
54
-
55
- ## 稳定公共契约
56
-
57
- ### JSON Envelope
58
-
59
- `--json` 继续保持统一 envelope:
60
-
61
- ```json
62
- {
63
- "ok": true,
64
- "command": "list",
65
- "data": {},
66
- "warnings": [],
67
- "error": null
68
- }
69
- ```
70
-
71
- 约束:
72
-
73
- - 顶层 shape 保持不变
74
- - 后续字段扩展只做加法
75
- - 详细结果进入 `data`
76
- - 非致命提示进入 `warnings`
77
- - 结构化失败信息继续进入 `error`
78
-
79
- ### 数据模型
80
-
81
- #### `providers.json`
82
-
83
- `providers.json` 继续是 managed registry 的单一事实源:
84
-
85
- ```json
86
- {
87
- "providers": {
88
- "packycode": {
89
- "profile": "packycode",
90
- "apiKey": "sk-xxx",
91
- "envKey": "PACKYCODE_API_KEY",
92
- "baseUrl": "https://example.com/v1",
93
- "note": "primary route",
94
- "tags": ["paid"]
95
- }
96
- }
97
- }
98
- ```
99
-
100
- 到 `0.1.0` 为止默认不放宽:
101
-
102
- - `profile` 仍然必填
103
- - `apiKey` 仍按完整 managed provider 处理
104
- - `envKey` 仍然必填
105
- - 不引入“半初始化 provider”作为正式稳定状态
106
-
107
- `envKey` 的产品语义是:
108
-
109
- - 与 `config.toml` 中 `[model_providers.<name>].env_key` 对应
110
- - 作为当前 provider 写入 `auth.json` 时的目标键名
111
- - 例如 `envKey = "PACKYCODE_API_KEY"` 时,切换后 `auth.json` 中应写入同名字段
112
-
113
- #### `config.toml`
114
-
115
- 到 `0.1.0` 为止,`config.toml` 的定位继续是“部分受管的 runtime projection”:
116
-
117
- - 顶层 active `profile = "..."` 继续受管
118
- - 与 provider 关联的 `[profiles.<name>]` section 进入受管范围
119
- - `[model_providers.<name>].base_url` 继续作为 runtime route 字段
120
- - `[model_providers.<name>].env_key` 是当前唯一支持的 provider 认证配置字段
121
- - 非 provider 相关的顶层键、section 和注释仍允许存在,但不进入通用编辑器范围
122
-
123
- 明确限制:
124
-
125
- - `[model_providers.<name>].api_key` 不再是合法受管配置字段
126
- - `codex-switch` 不再从 `config.toml` 读取或写入 provider secret
127
- - 本版本不支持其他认证模式的受管配置界面
128
-
129
- #### `ManagedProfileFields`
130
-
131
- `0.1.0` 之前第一批稳定受管 profile 持久化字段继续锁定为最小集合:
132
-
133
- ```json
134
- {
135
- "model": "gpt-5",
136
- "modelProvider": "packycode"
137
- }
138
- ```
139
-
140
- 约束:
141
-
142
- - 第一批正式受管字段锁 `model` 与 `model_provider`
143
- - `baseUrl` 作为读取视图字段,可由 `model_provider -> model_providers.<name>.base_url` 解析
144
- - `envKey` 不属于 `[profiles.*]` 的受管字段,而属于 runtime provider section 与 managed registry 的一致性边界
145
- - 后续扩展 profile 字段时,只能做加法
146
-
147
- #### `auth.json`
148
-
149
- `auth.json` 是受管运行态认证镜像文件:
150
-
151
- - 不是 provider registry 的事实源
152
- - 当前激活 provider 的 `apiKey` 与 `envKey` 决定其内容
153
- - 运行态 secret 只投影到 `auth.json`,不再投影到 `config.toml`
154
-
155
- 当前稳定写入形态:
156
-
157
- ```json
158
- {
159
- "auth_mode": "apikey",
160
- "PACKYCODE_API_KEY": "sk-xxx"
161
- }
162
- ```
163
-
164
- 约束:
165
-
166
- - `auth_mode` 当前稳定为 `apikey`
167
- - secret 键名不是固定 `OPENAI_API_KEY`
168
- - secret 键名由当前 provider 的 `envKey` 决定
169
-
170
- ## `0.1.0` 模块化目标
171
-
172
- ### 核心结构方向
173
-
174
- 到 `0.1.0` 为止,`codex-switch` 不应只停留在“`cli / app / domain / infra` 四层可用”这个层次,而应进一步收敛出稳定的能力边界:
175
-
176
- - `Command Surface`
177
- - `Interaction Layer`
178
- - `Application Use Cases`
179
- - `Domain Policies`
180
- - `Storage Repositories`
181
- - `Runtime Integrations`
182
-
183
- 这些边界的意义不是强制锁死具体类名,而是保证未来新增能力不会继续把复杂度堆回单一 CLI 入口。
184
-
185
- ### Runtime Integrations 的长期定位
186
-
187
- `Runtime Integrations` 是 `0.1.0` 目标线中必须预留清楚的能力域,负责:
188
-
189
- - `codex` CLI 调用与可用性检查
190
- - 本地认证镜像写入与诊断
191
- - 本地 proxy runtime
192
- - 外部 SDK / 二进制依赖可用性探测
193
- - integration 级错误语义收敛
194
-
195
- 说明:
196
-
197
- - 当前主线只支持 `env_key` 模型
198
- - 第三方 auth adapter 仍属于未来扩展方向,不是 `0.0.7` 的受管能力
199
-
200
- ## 已落地能力的 `0.1.0` 稳定化要求
201
-
202
- ### `setup`
203
-
204
- `setup` 在 `0.1.0` 主线中的要求是:
205
-
206
- - 继续保持从环境检测到 registry 初始化的主流程
207
- - 继续允许 `overwrite`、`merge` 和交互式补问缺失关键字段
208
- - 与 config 管理能力和未来 runtime integration 边界保持兼容
209
- - 对历史遗留不一致状态给出 adopt / repair 建议,而不是静默忽略
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
-
223
- ### provider registry 命令
224
-
225
- `show`、`edit`、`import --merge`、`backups list`、`rollback <backup-id>` 的 `0.1.0` 要求是:
226
-
227
- - 保持命令名和基础 JSON 契约稳定
228
- - 把错误语义继续收紧
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` 一致
253
-
254
- ### `import --merge`
255
-
256
- `import --merge` 在 `0.1.0` 主线中的要求是:
257
-
258
- - 保持“导入侧覆盖本地同名 provider”的默认 merge 语义
259
- - 不能只更新 `providers.json` 而放任 linked profile sections 漂移
260
- - 当导入结果引用了缺失 profile 时,必须进入与 `add` / `edit` 一致的受管规则
261
- - 非交互模式下,如果导入内容不能满足受管 profile 创建条件,应明确失败
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
290
-
291
- 目标:
292
-
293
- - 收紧错误码语义
294
- - 区分环境错误、参数错误、配置解析错误、集成错误和恢复错误
295
- - 保持 TTY / 非交互模式下的错误结果可预测
296
-
297
- ### Third-Party Auth Adapters
298
-
299
- 目标:
300
-
301
- - 保留未来把第三方认证来源封装为独立 integration 能力的空间
302
- - 不把第三方 auth 状态直接混入 provider registry 事实源
303
- - 但当前主线不承诺 `env_key` 之外的其他认证模型
304
-
305
- ### Local Proxy Runtime
306
-
307
- 目标:
308
-
309
- - 为需要本地代理的上游保留运行时承载能力
310
- - 允许启动、检查、停止或探测代理状态的能力进入集成层
311
- - 不破坏现有 provider/profile 切换和回滚模型
312
-
313
- ### External Dependency Lifecycle
314
-
315
- 目标:
316
-
317
- - 识别和诊断外部 SDK、CLI、二进制依赖是否可用
318
- - 把依赖缺失、版本不兼容、环境不可执行等问题映射到清晰错误语义
319
- - 为未来的依赖安装或引导能力留出接口,但不强制 `0.0.x` 提前产品化
320
-
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` 模式
339
-
340
- ## 主题里程碑
341
-
342
- 从 `0.0.5` 走向 `0.1.0`,建议按能力主题推进:
343
-
344
- ### 里程碑 A:`0.0.5` / Config Management & Consistency
345
-
346
- 目标:
347
-
348
- - 巩固结构化 TOML 读写
349
- - 稳定 `config-show`、`config-list-profiles`
350
- - 让 provider 管理命令可靠同步 linked profile sections
351
- - 明确共享 profile、孤儿 section 和 active profile 安全规则
352
-
353
- ### 里程碑 B:`0.0.6` / Stability & Modularization
354
-
355
- 目标:
356
-
357
- - 修复 `0.0.5` 已落地命令的稳定性问题
358
- - 统一 help、交互、错误语义和恢复模型
359
- - 解决 `cli.ts` 过重问题,明确 command / interaction / application / integration 边界
360
- - 为后续 integration-ready 架构建立清晰基础
361
-
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
380
-
381
- 目标:
382
-
383
- - 收紧错误码语义
384
- - 区分环境错误、参数错误、配置解析错误和恢复错误
385
- - 对外部 integration 的失败提供清晰可预测的错误契约
386
-
387
- ### 里程碑 F:Integrations & Runtime Expansion
388
-
389
- 目标:
390
-
391
- - 逐步引入第三方 integration
392
- - 逐步引入本地 proxy runtime
393
- - 逐步引入外部依赖可用性管理
394
- - 在不破坏主 CLI 契约的前提下扩展能力边界
395
-
396
- ## 对实现的要求
397
-
398
- 从 `0.0.5` 到 `0.1.0` 的所有新增能力,默认遵守:
399
-
400
- - 命令帮助必须明确人类模式和 `--json` 模式行为
401
- - 非交互环境不允许依赖 prompt 才能完成核心自动化流程
402
- - 所有写命令默认走锁、备份、回滚
403
- - 所有新增错误码都必须语义清晰
404
- - 所有新增 JSON 返回都只能扩展 `data` 和 `warnings`
405
- - 结构化 TOML 写回不能破坏非受管部分
406
- - provider secret 不再写入 `config.toml`
407
- - 第三方 integration 不得直接破坏 provider registry 作为 SSOT 的边界
408
- - 多候选目录发现和依赖可用性检查必须在交互与非交互模式下给出一致且可预测的行为
409
-
410
- ## `0.1.0` 目标完成标准
411
-
412
- 达到下面这些条件时,可以认为 `0.1.0` 主线目标基本收敛:
413
-
414
- - 用户可以通过 `setup` 完成首次初始化
415
- - `setup` 在多候选 Codex 目录场景下可交互选择或手动输入,在非交互场景下返回明确歧义错误
416
- - provider registry 的查看、编辑、导入合并能力完整
417
- - 用户和 AI 可以通过稳定命令结构化查看受管 `config.toml`
418
- - 受管 provider 均具备 `profile`、`apiKey`、`envKey`
419
- - `add` / `edit` / `remove` 执行后,`providers.json` 与 linked profile sections 不再出现预期内的一致性漂移
420
- - `switch` 能按当前 provider 的 `envKey` 将 `apiKey` 正确写入 `auth.json`
421
- - 共享 profile 场景不会误删仍被引用的 section
422
- - active profile 不会因为 provider 删除或 profile 迁移而变成悬空状态
423
- - 历史 `0.0.4` / `0.0.5` / `0.0.6` / `0.0.7` 状态可以被识别,并通过 adopt / repair 路径逐步收敛
424
- - 历史备份可被显式枚举和恢复
425
- - CLI 错误码不再存在明显语义复用问题
426
- - 当前主线的 `env_key` provider 模型已稳定,后续 integration 可在此基础上扩展
427
-
428
- ## 建议测试场景
429
-
430
- 至少需要覆盖:
431
-
432
- - `config-show` 与 `config-list-profiles` 的稳定输出
433
- - 共享 profile 场景下的 `add` / `edit` / `remove` 行为
434
- - `setup` 在多目录候选下的交互和非交互分支
435
- - `setup` 对缺失 `env_key` 的 profile 明确失败
436
- - `setup` 在无 `config.toml api_key` 时仍可正常 adopt 合法 provider
437
- - `import --merge` 在缺失 profile / adopt / repair 下的一致性行为
438
- - 结构化 TOML 修改后,非受管内容、顺序和注释保持稳定
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 状态
443
-
444
- ## 结论
445
-
446
- `0.1.0` 不是简单把 `0.0.x` 重命名为稳定版,而是在先完成 `0.0.7` 的 provider 配置模型纠偏之后,进一步收敛 config 管理、错误契约、恢复能力和模块化扩展边界,并把后续 integration 能力建立在清晰的 `providers.json`、`config.toml`、`auth.json` 分层之上。
@@ -1,62 +0,0 @@
1
- # codex-switch `0.0.8` PRD
2
-
3
- ## 文档信息
4
-
5
- - 状态:Active PRD
6
- - 产品名:`codex-switch`
7
- - CLI 命令名:`codexs`
8
- - 当前基线版本:`0.0.7`
9
- - 目标版本:`0.0.8`
10
- - 文档定位:定义 `0.0.7 -> 0.0.8` 的直接需求范围
11
- - 关联设计文档:[`../Design/codex-switch-v0.0.8-design.md`](../Design/codex-switch-v0.0.8-design.md)
12
-
13
- ## 一句话定义
14
-
15
- `0.0.8` 的目标,是让用户可以把 GitHub Copilot 作为受管 provider 接入 Codex:通过官方 `@github/copilot-sdk` 完成上游鉴权与请求执行,并通过本地 OpenAI 兼容 bridge 供 Codex 使用。
16
-
17
- ## In Scope
18
-
19
- - 官方 `@github/copilot-sdk`
20
- - 本地 Node/TypeScript bridge
21
- - `POST /v1/chat/completions`
22
- - JSON 和 stream 返回
23
- - premium request 默认开启
24
- - `add --copilot`
25
- - `switch` 的 runtime gate
26
- - `status` / `doctor` 的 Copilot runtime 诊断
27
- - lazy-load SDK
28
- - TTY 确认后自动安装 SDK
29
- - 非交互 `--install-copilot-sdk`
30
-
31
- ## Out of Scope
32
-
33
- - 非官方 SDK
34
- - 独立 `copilot` / `proxy` 命令族
35
- - Responses API、Embeddings、图像/音频接口
36
- - 持久化 GitHub token 到 `providers.json` / `auth.json`
37
- - 多实例 bridge 编排
38
- - GUI、后台控制台
39
-
40
- ## 依赖策略
41
-
42
- - `@github/copilot-sdk` 不进入 core CLI 默认依赖
43
- - 命中 Copilot 路径时才 probe SDK
44
- - SDK 运行前提是用户本机已具备可用的 GitHub Copilot CLI / login 状态,`codex-switch` 不托管这部分登录数据
45
- - TTY 下缺失 SDK 时提示确认,确认后允许自动安装
46
- - 安装目录固定为用户级 runtime 目录
47
- - 非交互或 `--json` 默认失败
48
- - 非交互只有在显式 `--install-copilot-sdk` 时才允许安装
49
-
50
- ## 数据边界
51
-
52
- - `providers.json` 保存本地 bridge 配置与 bridge shared secret
53
- - `config.toml` 保存 bridge `base_url` 和 `env_key`
54
- - `auth.json` 只保存 Codex 到 bridge 的 shared secret
55
- - GitHub/Copilot 上游认证状态只由官方 SDK 管理,不进入受管 registry
56
-
57
- ## 验收标准
58
-
59
- - `add --copilot` 可以创建 Copilot provider
60
- - `switch` 到 Copilot provider 时完成 `probe -> install if allowed -> auth check -> bridge health -> config/auth write`
61
- - `status` / `doctor` 能诊断 SDK 缺失、安装失败、认证缺失、bridge 不健康、runtime base_url 漂移
62
- - 现有 direct provider 行为不回退
@@ -1,166 +0,0 @@
1
- # codex-switch `0.0.9` PRD
2
-
3
- ## 文档信息
4
-
5
- - 状态:Active PRD
6
- - 产品名:`codex-switch`
7
- - CLI 命令名:`codexs`
8
- - 当前基线版本:`0.0.8`
9
- - 目标版本:`0.0.9`
10
- - 文档定位:定义 `0.0.8 -> 0.0.9` 的直接需求范围
11
- - 关联设计文档:`../Design/codex-switch-v0.0.9-design.md`(待产出)
12
- - 关联上一版设计:[`../Design/codex-switch-v0.0.8-design.md`](../Design/codex-switch-v0.0.8-design.md)
13
-
14
- ## 一句话定义
15
-
16
- `0.0.9` 的目标,是把 GitHub Copilot 的本地 bridge 从“切换时临时可用”收敛成“可按需自动拉起、可手动管理、可诊断恢复”的稳定运行态能力。
17
-
18
- ## In Scope
19
-
20
- - 官方 `@github/copilot-sdk`
21
- - 本地 Node/TypeScript bridge
22
- - detached 用户态 bridge 守护进程
23
- - `switch` 的 bridge 自动启动 / 复用
24
- - `bridge start`
25
- - `bridge stop`
26
- - `bridge status`
27
- - 单实例 bridge 生命周期管理
28
- - 5 位数 bridge 端口默认策略
29
- - 端口冲突自动探测与自动换端口
30
- - runtime state manifest 的持久化与诊断
31
- - `status` / `doctor` 的 bridge 生命周期诊断
32
- - direct provider 回归稳定性
33
-
34
- ## Out of Scope
35
-
36
- - 开机自启动
37
- - 登录自启动
38
- - Windows Service / 系统服务注册
39
- - 多实例 bridge 编排
40
- - 非官方 SDK
41
- - 独立 GUI / TUI
42
- - Responses API、Embeddings、图像/音频接口
43
- - 持久化 GitHub token 到 `providers.json` / `auth.json`
44
-
45
- ## 运行形态
46
-
47
- - bridge 是由 `codex-switch` 启动和管理的本地后台进程
48
- - bridge 不是系统服务,也不注册开机或登录自动启动项
49
- - `switch` 到 Copilot provider 时,bridge 应自动启动或复用
50
- - 用户也可以通过 `bridge` 命令族手动启动、停止和查看状态
51
- - `0.0.9` 的“守护进程”语义仅指 detached 用户态后台进程,不等同于 OS service
52
-
53
- ## 命令面
54
-
55
- 新增命令:
56
-
57
- - `codexs bridge start [provider]`
58
- - `codexs bridge stop [provider]`
59
- - `codexs bridge status [provider]`
60
-
61
- 命令规则:
62
-
63
- - `bridge` 命令族只服务于 Copilot runtime-backed provider
64
- - `provider` 可显式传入;未传入时优先使用当前 active provider
65
- - 如果未传入且当前 active provider 不是 Copilot provider:
66
- - TTY 下允许交互选择目标 Copilot provider
67
- - 非交互或 `--json` 下必须明确失败
68
- - `bridge start` 必须先完成:
69
- - provider 解析
70
- - runtime 配置校验
71
- - SDK probe
72
- - Copilot auth state 校验
73
- - bridge 启动或复用
74
- - healthcheck
75
- - `bridge stop` 只停止当前受管 bridge 进程并清理 runtime state manifest,不修改 provider registry
76
- - `bridge status` 返回 runtime state、provider 绑定关系、healthcheck 结果与异常原因
77
-
78
- ## 生命周期规则
79
-
80
- - `add --copilot` 只负责创建 provider 和可选安装 SDK,不负责启动 bridge
81
- - `switch <copilot-provider>` 仍然是最常见的自动启动入口
82
- - `bridge start` 与 `switch` 共享同一套 bridge 启动与复用逻辑
83
- - 同一时刻只允许一个 bridge 实例处于受管运行状态
84
- - 如果 bridge 已为同一 provider 运行且健康,则 `bridge start` 和 `switch` 都直接复用
85
- - 如果已有 bridge 为另一 Copilot provider 运行:
86
- - `bridge start <new-provider>` 先停止旧实例,再启动新实例
87
- - `switch <new-provider>` 也遵守同样的单实例替换规则
88
- - `bridge stop` 应该是幂等的:bridge 已停止时不报致命错误
89
-
90
- ## 端口策略
91
-
92
- - `--bridge-host` 默认 `127.0.0.1`
93
- - `--bridge-port` 默认值必须是 5 位数端口
94
- - Copilot provider 的默认端口不再使用 `4141`
95
- - 如果 provider 指定端口已被占用:
96
- - bridge 启动阶段必须自动检测冲突
97
- - 自动选择新的可用 5 位数端口
98
- - 自动更新 provider 的 runtime 配置和对应 `baseUrl`
99
- - 自动保持 `config.toml` runtime projection 与 provider 配置一致
100
- - 自动换端口后的新端口必须持久化,避免下一次启动再次撞到旧端口
101
- - 端口自动切换只允许在 Copilot bridge provider 路径发生,不能影响 direct provider
102
-
103
- ## 依赖策略
104
-
105
- - `@github/copilot-sdk` 继续不进入 core CLI 默认依赖
106
- - 命中 Copilot 路径时才 probe SDK
107
- - SDK 自动安装仍然只允许发生在 `add --copilot`
108
- - `bridge start`、`switch`、`status`、`doctor` 都不能隐式安装 SDK
109
- - `bridge start` 在 SDK 缺失时必须明确失败,并提示回到 `add --copilot --install-copilot-sdk`
110
- - SDK 运行前提仍然是用户本机已具备可用的 GitHub Copilot CLI / login 状态,`codex-switch` 不托管这部分登录数据
111
-
112
- ## 数据边界
113
-
114
- - `providers.json` 保存 Copilot provider、bridge host/port、`baseUrl` 与 shared secret
115
- - `config.toml` 保存 Copilot provider 对应的 runtime `base_url` 与 `env_key`
116
- - `auth.json` 只保存 Codex 到本地 bridge 的 shared secret
117
- - runtime state manifest 保存当前 bridge 进程状态、provider 绑定、最后健康检查时间
118
- - runtime state manifest 不进入 managed backup 事务
119
- - GitHub/Copilot 上游认证状态仍然只由官方 SDK 管理,不进入受管 registry
120
-
121
- ## 错误语义
122
-
123
- `0.0.9` 继续稳定并收敛以下错误码:
124
-
125
- - `COPILOT_SDK_MISSING`
126
- - `COPILOT_SDK_INSTALL_FAILED`
127
- - `COPILOT_SDK_INSTALL_REQUIRES_TTY`
128
- - `COPILOT_SDK_UNSUPPORTED`
129
- - `COPILOT_AUTH_REQUIRED`
130
- - `COPILOT_PREMIUM_UNAVAILABLE`
131
- - `BRIDGE_PORT_CONFLICT`
132
- - `BRIDGE_START_FAILED`
133
- - `BRIDGE_HEALTHCHECK_FAILED`
134
- - `RUNTIME_PROVIDER_INVALID`
135
- - `PROVIDER_BASE_URL_MISMATCH`
136
-
137
- 新增要求:
138
-
139
- - `bridge start`、`switch`、`bridge status` 对同一类 bridge 失败应尽量映射到同一类错误码
140
- - 端口冲突在自动恢复成功时不应向上冒泡为致命失败
141
- - 只有在无法找到可用端口或无法持久化新端口时,才允许保留 `BRIDGE_PORT_CONFLICT` 失败
142
-
143
- ## 验收标准
144
-
145
- - `add --copilot` 可以创建 Copilot provider,并写入 5 位数默认端口
146
- - `switch` 到 Copilot provider 时完成 `probe -> auth check -> start or reuse bridge -> healthcheck -> config/auth write`
147
- - `codexs bridge start [provider]` 可以手动启动或复用 bridge
148
- - `codexs bridge stop [provider]` 可以手动停止当前 bridge,并清理 runtime state
149
- - `codexs bridge status [provider]` 可以给出 bridge 是否运行、绑定哪个 provider、端口是多少、是否健康
150
- - 当 bridge 目标端口被占用时,系统会自动切换到新的可用 5 位数端口,并持久化该变更
151
- - direct provider 不经过 Copilot 特有的 runtime gate
152
- - `status` / `doctor` 能诊断 SDK 缺失、认证缺失、bridge 不健康、stale runtime state、runtime base_url 漂移
153
-
154
- ## 测试重点
155
-
156
- - `bridge start/stop/status` 参数解析与帮助文案
157
- - 省略 provider 时的 active provider 解析路径
158
- - TTY 下的 Copilot provider 交互选择路径
159
- - 非交互下目标 provider 不明确时的失败路径
160
- - 单实例 bridge 的复用路径
161
- - 单实例 bridge 的替换路径
162
- - `switch` 与 `bridge start` 共享生命周期逻辑的回归
163
- - 端口占用时的自动换端口与持久化
164
- - stale runtime state 的诊断与清理
165
- - `bridge stop` 幂等性
166
- - direct provider 回归