@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,708 +0,0 @@
1
- # codex-switch `0.0.6` 设计文档
2
-
3
- ## 文档信息
4
-
5
- - 文档类型:详细设计文档
6
- - 适用版本:`0.0.6`
7
- - 目标范围:`0.0.5 -> 0.0.6`
8
- - 主对齐 PRD:[`../PRD/codex-switch-prd-v0.1.0.md`](../PRD/codex-switch-prd-v0.1.0.md)
9
- - 远期边界参考:[`../PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md`](../PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md)
10
- - 风格基线:[`codex-switch-v0.0.5-design.md`](./codex-switch-v0.0.5-design.md)
11
-
12
- ## 1. 文档目标
13
-
14
- 这份文档回答的是 `0.0.6` 应该怎样落地,而不是继续讨论长期愿景:
15
-
16
- - `0.0.5` 已经落下来的命令能力哪些必须稳住,哪些边缘行为必须收口
17
- - `0.0.6` 为什么不是“再加一批新命令”,而是“稳定性 + 模块化”版本
18
- - 当前 `src/cli.ts`、`src/app/types.ts`、`src/infra/` 的职责混合问题应该怎样拆开
19
- - 未来第三方 auth / proxy / SDK 相关需求,在本版里只应该沉淀成什么内部扩展契约
20
-
21
- 目标是让实现阶段不再重复拍板“要不要重构”“命令表面怎么统一”“未来集成往哪层放”这些关键问题。
22
-
23
- ## 2. 版本定位与设计原则
24
-
25
- ### 2.1 当前基线
26
-
27
- 当前 `0.0.5` 已具备:
28
-
29
- - provider registry 管理:`list`、`show`、`add`、`edit`、`remove`
30
- - 运行态切换:`current`、`switch`
31
- - 导入导出:`import`、`import --merge`、`export`
32
- - 初始化与诊断:`setup`、`status`、`doctor`
33
- - 备份恢复:`backups list`、`rollback`
34
- - `config show` / `config list-profiles`
35
- - 统一 JSON envelope
36
- - 写操作统一走锁、备份、失败回滚
37
-
38
- 当前主要短板已经不再是“缺命令”,而是:
39
-
40
- - help、参数、TTY 和 `--json` 的行为仍有继续统一的空间
41
- - `src/cli.ts` 已承担过多解析、分发、交互和异常渲染职责
42
- - CLI 解析类型与应用层类型混放,层次所有权不清
43
- - `infra` 同时装文件仓储和外部运行时调用,未来会继续膨胀
44
-
45
- ### 2.2 `0.0.6` 的一句话定义
46
-
47
- `0.0.6` 的核心不是继续扩张命令面,而是修复 `0.0.5` 的稳定性问题,冻结当前 CLI 公共契约,并把实现收敛为适合继续扩展的显式分层结构。
48
-
49
- ### 2.3 设计原则
50
-
51
- `0.0.6` 继续沿用现有工程原则:
52
-
53
- - `CLI First`
54
- - `Local First`
55
- - `Safe by Default`
56
- - `AI Friendly`
57
- - `Split State Model`
58
- - `Lightweight Transactions`
59
-
60
- 在此基础上新增三条版本原则:
61
-
62
- - 不破坏当前 help、命令名和 `--json` envelope
63
- - 架构重构必须先收口公共契约,再做内部迁移
64
- - 未来 integration 能力只能挂在独立 runtime / integration 边界,不得重新耦合回 CLI 入口
65
-
66
- ## 3. 范围与边界
67
-
68
- ### 3.1 `0.0.6` 范围内
69
-
70
- 本设计覆盖:
71
-
72
- - help 文案、参数、TTY 交互、错误语义的一致性修复
73
- - 命令分发、交互编排、应用用例、存储访问、运行时集成的重新分层
74
- - `setup` / `add` / `edit` / `remove` / `import` / `export` / `switch` / `rollback` 的稳定性收口
75
- - `status` / `doctor` / `config show` / `config list-profiles` 的读取稳定性收口
76
- - 面向未来 auth / proxy / SDK 的内部能力契约
77
-
78
- ### 3.2 明确不在 `0.0.6` 范围内
79
-
80
- 下面这些内容不进入本设计:
81
-
82
- - 新增大型命令族
83
- - 真实 Copilot 登录接入
84
- - 本地代理服务启动、停止、守护与生命周期管理命令
85
- - 第三方 SDK 安装器或依赖下载体验
86
- - GUI / TUI / daemon 化
87
- - 把 `config.toml` 升级为通用配置编辑器
88
-
89
- ### 3.3 数据与公共契约边界
90
-
91
- `0.0.6` 继续坚持现有公共边界:
92
-
93
- - `providers.json`:provider registry 的单一事实源
94
- - `config.toml`:运行态配置投影,继续保持局部受管
95
- - `auth.json`:认证态运行时文件
96
- - `backups/` + `latest.json`:恢复态
97
- - `--json`:顶层 envelope shape 不变
98
-
99
- 本版允许内部文件和模块重组,但不允许用户可见契约漂移。
100
-
101
- ## 4. 当前实现问题盘点
102
-
103
- ### 4.1 `src/cli.ts` 过重
104
-
105
- 当前 `src/cli.ts` 同时承担:
106
-
107
- - version 输出
108
- - help 分发
109
- - 参数分发
110
- - 交互能力判断
111
- - 命令调用
112
- - 异常归一化和最终渲染
113
-
114
- 这意味着任何一个新命令、新交互分支或未来 integration,都容易继续把复杂度堆回单文件入口。
115
-
116
- ### 4.2 CLI 类型落在 `src/app/types.ts`
117
-
118
- 当前 `ParsedArgs`、`CommandContext` 等 CLI 解析与调度类型放在 `src/app/types.ts`,带来两个问题:
119
-
120
- - 类型所有权不清,CLI 表面层概念混入用例层
121
- - 后续要拆 command surface 时,应用层会被迫携带 CLI 历史包袱
122
-
123
- ### 4.3 公开命令形态与内部 command key 未正式抽象
124
-
125
- 当前 help 和解析事实上已经存在两套概念:
126
-
127
- - 公开 CLI 形态:`config show`、`config list-profiles`、`backups list`
128
- - 内部执行 key:`config-show`、`config-list-profiles`、`backups-list`
129
-
130
- 这套事实目前只散落在 `help.ts` 和 `args.ts` 中,没有被提升成正式抽象,因此 help、参数解析和 dispatch 仍可能出现映射漂移。
131
-
132
- ### 4.4 `src/infra/` 职责过宽
133
-
134
- 当前 `src/infra/` 同时承载:
135
-
136
- - `providers.json` / `config.toml` / 备份 / 锁 / 路径解析
137
- - `codex` CLI 调用与可用性检查
138
-
139
- 如果未来 auth adapter、proxy runtime、SDK probe 继续往这里堆,`infra` 会再次变成“什么都放”的兜底目录,边界无法稳定。
140
-
141
- ## 5. `0.0.6` 功能总览
142
-
143
- `0.0.6` 需要完成四件事:
144
-
145
- - 巩固现有命令的 help、参数、TTY、错误和回滚行为
146
- - 把 command surface、interaction、application、storage、runtime 的职责边界显式化
147
- - 让 `src/cli.ts` 缩回薄入口,只保留 bootstrap 与最终渲染职责
148
- - 为未来第三方 auth / proxy / SDK 接入预留清晰但非侵入式的 runtime 边界
149
-
150
- ## 6. 目标架构
151
-
152
- ### 6.1 最终结构方向
153
-
154
- `0.0.6` 设计稿直接锁定目标源码结构为:
155
-
156
- ```text
157
- src/
158
- cli.ts
159
- commands/
160
- interaction/
161
- application/
162
- domain/
163
- storage/
164
- runtime/
165
- ```
166
-
167
- 说明:
168
-
169
- - `src/cli.ts` 保留为薄入口,不再承担持续膨胀的业务编排
170
- - 这不是要求一次性重命名所有文件完成“大爆炸迁移”
171
- - 这是最终结构方向,迁移允许分阶段完成
172
-
173
- ### 6.2 为什么选择 Hybrid 显式分层
174
-
175
- `0.0.6` 不采用“所有命令逻辑继续围绕 CLI 文件散开”的路线,也不要求引入过度设计的框架式架构。
176
-
177
- 这里锁定的是一套 Hybrid 分层:
178
-
179
- - 上层围绕命令表面与交互体验组织
180
- - 中层围绕应用用例与领域规则组织
181
- - 下层按持久化与运行时依赖做边界隔离
182
-
183
- 这样既能保留现有 CLI 工程的简单性,也能防止未来第三方集成倒灌回入口层。
184
-
185
- ## 7. 模块职责设计
186
-
187
- ### 7.1 `commands/`
188
-
189
- `commands/` 是命令表面层,负责:
190
-
191
- - `parseArgs`
192
- - help 定义与渲染
193
- - `CommandId` 与公开 token 映射
194
- - command registry
195
- - dispatch orchestration
196
- - `ParsedCommand` / `CommandExecutionContext` 这类类型归属
197
-
198
- 明确不负责:
199
-
200
- - 真实文件写入
201
- - 直接业务事务
202
- - 终端 prompt 细节实现
203
- - 第三方 CLI / SDK 调用
204
-
205
- ### 7.2 `interaction/`
206
-
207
- `interaction/` 是纯交互层,负责:
208
-
209
- - `PromptRuntime`
210
- - `canPrompt`
211
- - provider 选择
212
- - 危险确认
213
- - setup 目录选择
214
- - 渐进式补问
215
- - 交互取消语义
216
-
217
- 交互层的唯一产物是“已决输入”,而不是文件副作用:
218
-
219
- - 可以决定 providerName / profile / strategy / confirm 等输入
220
- - 不直接写 `providers.json`、`config.toml`、`auth.json`
221
-
222
- ### 7.3 `application/`
223
-
224
- `application/` 是用例编排层,继续保留现有命令 use case 思想,但要求:
225
-
226
- - 每个 use case 只接收显式参数
227
- - 不直接依赖终端 IO
228
- - 不再承载 CLI 解析类型
229
- - 继续负责双写事务、结果契约和回滚增强
230
-
231
- 它是 command surface 到 storage / runtime / domain 的稳定入口。
232
-
233
- ### 7.4 `domain/`
234
-
235
- `domain/` 继续保留,但职责要显式收紧为:
236
-
237
- - provider / config / runtime-state 规则
238
- - 错误码与纯规则判断
239
- - 共享 profile、悬空 active profile、一致性 issue 等策略
240
-
241
- 明确不承载:
242
-
243
- - 命令解析
244
- - prompt 流程
245
- - 文件系统访问
246
- - 外部 CLI / SDK 可用性探测
247
-
248
- ### 7.5 `storage/`
249
-
250
- `storage/` 从 `infra` 中拆出,职责锁定为:
251
-
252
- - `providers.json` / `config.toml` / backups / lock / path resolution
253
- - 原子写入
254
- - 备份 manifest
255
- - 文件读取校验
256
-
257
- 明确不承载:
258
-
259
- - `codex` CLI 调用
260
- - 第三方 auth / SDK / proxy 调用
261
-
262
- ### 7.6 `runtime/`
263
-
264
- `runtime/` 从 `infra` 中拆出,职责锁定为:
265
-
266
- - 当前 `codex` CLI 调用
267
- - 未来第三方 auth adapter
268
- - 未来本地 proxy runtime
269
- - 外部依赖探测与版本 / 可用性检查
270
-
271
- 这层唯一目标是吸收“依赖外部程序或外部集成”的复杂度,而不是承载 provider/config 核心规则。
272
-
273
- ## 8. 内部接口与类型
274
-
275
- `0.0.6` 不锁未来用户命令,但锁内部契约名称和边界。
276
-
277
- ### 8.1 `CommandId`
278
-
279
- `CommandId` 表示内部稳定命令标识,和公开 token 序列分离。
280
-
281
- 例如:
282
-
283
- ```ts
284
- type CommandId =
285
- | "config-show"
286
- | "config-list-profiles"
287
- | "list"
288
- | "show"
289
- | "current"
290
- | "status"
291
- | "setup"
292
- | "edit"
293
- | "add"
294
- | "switch"
295
- | "remove"
296
- | "import"
297
- | "export"
298
- | "backups-list"
299
- | "doctor"
300
- | "rollback";
301
- ```
302
-
303
- 设计要求:
304
-
305
- - 对外命令 token 可以多段
306
- - 对内 dispatch key 必须稳定单值
307
- - help、解析、dispatch 和 JSON `command` 字段都应共享同一套命令定义来源
308
-
309
- ### 8.2 `CommandDefinition`
310
-
311
- `CommandDefinition` 负责描述一条命令的帮助、公开 token、参数规范和处理器绑定。
312
-
313
- 建议内部结构:
314
-
315
- ```ts
316
- type CommandDefinition = {
317
- id: CommandId;
318
- tokens: string[];
319
- group: "read" | "write" | "recovery";
320
- summary: string;
321
- usage: string[];
322
- details: string[];
323
- examples: string[];
324
- handler: CommandHandler;
325
- };
326
- ```
327
-
328
- 这样 help 文案、topic 匹配、参数解析和 dispatch 都能共用一份 registry。
329
-
330
- ### 8.3 `CommandHandler`
331
-
332
- `CommandHandler` 是 command surface 到 application 的统一入口。
333
-
334
- 建议职责:
335
-
336
- - 接收 `ParsedCommand`
337
- - 在必要时请求 `InteractiveResolver`
338
- - 将“已决输入”映射为应用层显式参数
339
- - 返回稳定 `CommandResult`
340
-
341
- 它不直接做底层文件写入,也不直接操作终端输出。
342
-
343
- ### 8.4 `InteractiveResolver`
344
-
345
- `InteractiveResolver` 的目标,是把 TTY 条件下的补问与确认从 handler 里拿出去。
346
-
347
- 能力至少包括:
348
-
349
- - 选择 provider
350
- - 选择 setup 目录
351
- - 选择 setup strategy
352
- - 危险删除确认
353
- - rollback 确认
354
- - add / edit 的渐进式缺失字段补问
355
-
356
- 它只产出已决输入或取消结果,不直接调用应用用例。
357
-
358
- ### 8.5 `RuntimeDependencyProbe`
359
-
360
- `RuntimeDependencyProbe` 负责探测 `codex` CLI 或未来 SDK 是否可用。
361
-
362
- 职责包括:
363
-
364
- - 可执行文件是否存在
365
- - 版本是否满足最低要求
366
- - 环境是否具备调用条件
367
- - 将失败归一为 runtime/integration 侧错误
368
-
369
- 它不负责 provider/config 规则判断。
370
-
371
- ### 8.6 `AuthRuntimeAdapter` 与 `ProxyRuntimeAdapter`
372
-
373
- 这两个接口在 `0.0.6` 里只定义能力边界,不定义未来命令名。
374
-
375
- 建议能力方向:
376
-
377
- ```ts
378
- type AuthRuntimeAdapter = {
379
- probe(): Promise<RuntimeAvailability>;
380
- readState?(): Promise<unknown>;
381
- acquire?(): Promise<unknown>;
382
- };
383
-
384
- type ProxyRuntimeAdapter = {
385
- probe(): Promise<RuntimeAvailability>;
386
- getStatus?(): Promise<unknown>;
387
- };
388
- ```
389
-
390
- 约束:
391
-
392
- - 不在 `0.0.6` 里提前承诺 Copilot 用户命令
393
- - 不在本版里提前锁死 SDK 选型和协议细节
394
- - 只要求未来集成能以 runtime adapter 形式接入
395
-
396
- ## 9. 命令表面模型
397
-
398
- ### 9.1 公开 CLI 形态
399
-
400
- 公开 CLI 形态继续允许多 token 命令:
401
-
402
- - `config show`
403
- - `config list-profiles`
404
- - `backups list`
405
-
406
- 同时继续保留单 token 命令:
407
-
408
- - `list`
409
- - `show`
410
- - `current`
411
- - `status`
412
- - `setup`
413
- - `edit`
414
- - `add`
415
- - `switch`
416
- - `remove`
417
- - `import`
418
- - `export`
419
- - `doctor`
420
- - `rollback`
421
-
422
- ### 9.2 内部执行 ID
423
-
424
- 内部执行 ID 继续允许使用稳定 key:
425
-
426
- - `config-show`
427
- - `config-list-profiles`
428
- - `backups-list`
429
-
430
- 这与当前实现事实一致,但在 `0.0.6` 中必须正式化,不再只靠局部 if/else 映射。
431
-
432
- ### 9.3 单一 registry 原则
433
-
434
- help 文案、参数解析、dispatch 都必须共享同一份 registry,不允许再多处手写映射。
435
-
436
- 禁止继续扩散的形态包括:
437
-
438
- - `help.ts` 自己维护一套命令名
439
- - `args.ts` 自己维护一套多 token -> key 映射
440
- - `cli.ts` 再用 `switch` 补一套分发事实
441
-
442
- `0.0.6` 的目标是让这三者都从 `CommandDefinition[]` 派生。
443
-
444
- ## 10. 稳定性与错误语义要求
445
-
446
- ### 10.1 help / 参数 / TTY 一致性
447
-
448
- `0.0.6` 要求显式收口以下行为:
449
-
450
- - help 文案与真实命令行为一致
451
- - 默认文本输出与 `--json` 输出语义一致
452
- - `--json` 一律禁用交互
453
- - `setup` 在 `0.0.6` 中如果仍依赖 adopt 输入采集,则非交互路径必须显式失败,不允许伪装成“稳定支持但最终必然报错”的半可用状态
454
- - 非 TTY 一律不进入交互
455
- - 用户取消 prompt 时不得产生文件写入
456
-
457
- ### 10.2 写命令安全语义
458
-
459
- 所有修改 `providers.json`、`config.toml`、`auth.json` 的命令继续默认遵守:
460
-
461
- - 单次锁
462
- - 单次备份
463
- - 单次失败整体回滚
464
-
465
- 不能接受的状态包括:
466
-
467
- - `providers.json` 已更新但 `config.toml` 未同步
468
- - `config.toml` 已更新但 `providers.json` 未同步
469
- - `auth.json` 或 active profile 留在半切换状态
470
-
471
- ### 10.3 读取稳定性
472
-
473
- 读取命令在 `0.0.6` 至少需要满足:
474
-
475
- - 历史 workspace 或边缘状态下不轻易崩溃
476
- - `status` 与 `doctor` 的诊断语义继续对齐
477
- - `config show` 与 `config list-profiles` 的输出结构稳定
478
- - 对缺失文件、解析失败和不一致状态给出可预测错误或 warning
479
-
480
- ## 11. 迁移方案
481
-
482
- ### 11.1 Phase 1:抽出 command surface 契约
483
-
484
- 第一阶段目标:
485
-
486
- - 抽出 command surface 类型和 registry
487
- - 把 `ParsedArgs`、`CommandContext` 从 `src/app/types.ts` 迁走
488
- - 明确 `CommandId`、`ParsedCommand`、`CommandExecutionContext` 的所有权
489
-
490
- 这一阶段不追求目录一次性重命名完毕,先解决“谁拥有 CLI 契约”。
491
-
492
- ### 11.2 Phase 2:缩薄 `src/cli.ts`
493
-
494
- 第二阶段目标:
495
-
496
- - 让 `src/cli.ts` 只保留 bootstrap
497
- - 只保留 version / help / main / error exit
498
- - 命令分发和处理器绑定下沉到 `commands/`
499
-
500
- 这一步完成后,入口文件应能稳定维持在薄层。
501
-
502
- ### 11.3 Phase 3:抽离 `interaction/`
503
-
504
- 第三阶段目标:
505
-
506
- - 把现有 `cli/interactive.ts`、`add-interactive.ts`、`prompt.ts` 收口为独立 `interaction/` 层
507
- - 把危险确认、补问、目录选择、交互取消统一抽象
508
- - 避免每个 command handler 再自行散落 prompt 细节
509
-
510
- ### 11.4 Phase 4:拆分 `infra` 为 `storage` 与 `runtime`
511
-
512
- 第四阶段目标:
513
-
514
- - 先迁 `codex-cli.ts` 一类外部运行时调用到 `runtime/`
515
- - 把文件读写、锁、备份、路径、仓储收口到 `storage/`
516
- - 在 runtime 层补齐 capability contracts
517
-
518
- 迁移顺序上先拆运行时入口,再收口未来 probe / adapter 扩展点。
519
-
520
- ### 11.5 Phase 5:测试与文档同步
521
-
522
- 第五阶段目标:
523
-
524
- - 按新边界收口测试
525
- - 修正 README / help / 版本同步问题
526
- - 确认命令行为和公共契约未回归
527
-
528
- 这是收尾阶段,不应被当成可后置省略项。
529
-
530
- ## 12. 关键流程时序
531
-
532
- ### 12.1 顶层 CLI 启动到 command registry dispatch
533
-
534
- ```text
535
- argv
536
- -> cli.ts bootstrap
537
- -> commands.parseArgs
538
- -> commands.resolveCommandDefinition
539
- -> commands.dispatch
540
- -> handler
541
- -> application use case
542
- -> output render
543
- ```
544
-
545
- 要求:
546
-
547
- - 顶层入口不再自行维护命令知识
548
- - dispatch 以 registry 为单一事实源
549
-
550
- ### 12.2 带交互的写命令:解析到“已决输入”再进入 application
551
-
552
- ```text
553
- argv
554
- -> parse command surface
555
- -> handler checks TTY / --json
556
- -> interaction resolver collects missing inputs / confirmations
557
- -> resolved command input
558
- -> application use case
559
- -> storage + runtime mutation
560
- -> result
561
- ```
562
-
563
- 关键点:
564
-
565
- - 交互发生在 application 之前
566
- - application 看见的始终是显式参数,而不是 prompt 分支
567
-
568
- ### 12.3 `switch` 的 storage + runtime 事务链路
569
-
570
- ```text
571
- switch command
572
- -> resolve provider
573
- -> application/switch-provider
574
- -> storage acquire lock
575
- -> storage create backup
576
- -> storage update active profile in config.toml
577
- -> runtime refresh codex auth/login when enabled
578
- -> success result
579
- -> on failure rollback config/auth from backup
580
- ```
581
-
582
- 关键约束:
583
-
584
- - runtime 失败不能污染核心状态
585
- - rollback 仍由应用层事务编排触发
586
-
587
- ### 12.4 `setup` 的目录发现、策略选择、adopt 输入采集与写入边界
588
-
589
- ```text
590
- setup command
591
- -> runtime/storage path candidate discovery
592
- -> interaction choose directory when needed
593
- -> read config + providers state
594
- -> interaction choose strategy and adopt inputs
595
- -> application/setup-codex
596
- -> storage mutation under backup
597
- -> doctor/status style summary output
598
- ```
599
-
600
- 关键边界:
601
-
602
- - 候选目录选择属于 interaction
603
- - adopt 规则判断属于 application + domain
604
- - 真实写入仍由 storage 执行
605
-
606
- ### 12.5 integration-ready 场景:dependency probe / auth adapter 不可用
607
-
608
- ```text
609
- future integration command or switch extension
610
- -> handler / application requests runtime probe
611
- -> runtime dependency probe fails
612
- -> runtime-layer error normalization
613
- -> command fails before core mutation
614
- -> providers/config/auth state unchanged
615
- ```
616
-
617
- 要求:
618
-
619
- - 失败归因停留在 runtime 层
620
- - 不把“外部依赖不可用”污染成 provider/config 领域错误
621
-
622
- ## 13. 测试设计
623
-
624
- ### 13.1 总体原则
625
-
626
- 测试继续采用当前 plain Node specs 模式:
627
-
628
- - 不引入 Jest / Vitest
629
- - 保留现有 domain / app / cli / dev-sandbox / e2e 五层思路
630
- - 新测试覆盖围绕 command surface、interaction、runtime 三条新增设计关注点补强
631
-
632
- ### 13.2 Command Surface 覆盖
633
-
634
- 最少覆盖:
635
-
636
- - 多 token 命令解析:`config show`、`config list-profiles`、`backups list`
637
- - help topic 到内部 `CommandId` 的映射
638
- - command registry dispatch
639
- - `--json` 与 TTY gating
640
- - version / help / unknown command 的统一入口行为
641
-
642
- ### 13.3 Interaction 覆盖
643
-
644
- 最少覆盖:
645
-
646
- - 取消 prompt
647
- - 危险确认拒绝
648
- - `setup` 多候选目录
649
- - `add` / `edit` 的渐进式输入补问
650
- - provider 选择与 rollback 确认
651
-
652
- ### 13.4 Runtime 覆盖
653
-
654
- 最少覆盖:
655
-
656
- - `codex` CLI 不可用
657
- - 版本不兼容
658
- - 未来依赖探测失败的错误归类
659
- - runtime 失败时不污染 provider/config 核心状态
660
-
661
- ### 13.5 现有主路径回归
662
-
663
- 继续保持 e2e 针对以下路径的真实回归:
664
-
665
- - `switch`
666
- - `rollback`
667
- - `add` / `edit` / `remove`
668
- - `import` / `export`
669
- - `config show`
670
- - `doctor`
671
-
672
- 重点不是补更多命令名,而是证明重构后当前主路径没有回归。
673
-
674
- ## 14. Deferred 到 `0.1.0`
675
-
676
- 下面这些内容明确 deferred,不混入 `0.0.6`:
677
-
678
- - 真实 Copilot / 第三方 auth 登录流程
679
- - 本地 proxy 用户命令和生命周期管理
680
- - 具体 SDK 安装、下载、引导体验
681
- - 更大的 integration 命令面
682
-
683
- `0.0.6` 只接受“把边界设计清楚”,不接受“先把未来功能半做进去”。
684
-
685
- ## 15. 验收标准
686
-
687
- `0.0.6` 设计落地后,至少应满足:
688
-
689
- - 当前 help 文案与命令行为、参数和危险提示基本一致
690
- - 现有命令在 TTY / 非交互 / `--json` 模式下行为稳定
691
- - `src/cli.ts` 不再承担持续膨胀的主调度与交互编排复杂度
692
- - command surface、interaction、application、storage、runtime 的职责边界比 `0.0.5` 清晰
693
- - 公开 token 与内部 `CommandId` 的映射被正式收口为单一 registry
694
- - 写命令继续满足锁、备份、失败回滚语义
695
- - 读取命令对历史状态和异常状态的处理更稳
696
- - 为未来第三方 auth / proxy / SDK 接入预留了清楚但非侵入式的 integration-ready 边界
697
-
698
- 验收维度同时包含三类:
699
-
700
- - 稳定性:当前命令不回归
701
- - 分层完成度:核心职责边界明确且可迁移
702
- - integration-ready:未来外部能力有独立 runtime 契约,不反向污染 CLI 与领域层
703
-
704
- ## 16. 结论
705
-
706
- `0.0.6` 的本质,是把 `codex-switch` 从“命令已基本成形但入口和职责正在持续膨胀”的状态,推进到“公共契约冻结、现有能力稳定、内部边界清晰、可继续承接 integration-ready 演进”的下一阶段。
707
-
708
- 这一步不要求立刻交付 Copilot、proxy 或 SDK 功能;它要求的是,在不破坏当前 CLI 用户面和事务安全模型的前提下,把结构调整到足以支撑下一阶段演进的状态。