@minniexcode/codex-switch 0.0.7 → 0.0.9

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.
@@ -0,0 +1,413 @@
1
+ # codex-switch `0.0.9 -> 0.0.12` Roadmap
2
+
3
+ ## Document Info
4
+
5
+ - Document type: roadmap / execution plan
6
+ - Current implementation baseline: `0.0.8`
7
+ - Planned versions: `0.0.9`, `0.0.10`, `0.0.11`, `0.0.12`
8
+ - Release gate after roadmap: `0.1.0`
9
+ - Scope: stabilize the current CLI through four focused pre-`0.1.0` versions
10
+ - Related PRD: [`../PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md`](../PRD/codex-switch-prd-v0.0.5-to-v0.1.0.md)
11
+ - Related design baseline: [`./codex-switch-v0.0.8-design.md`](./codex-switch-v0.0.8-design.md)
12
+
13
+ ## 1. Goal
14
+
15
+ This roadmap turns the current `0.0.8` baseline into a concrete version-by-version plan instead of a single abstract jump to `0.1.0`.
16
+
17
+ The intent is:
18
+
19
+ - `0.0.9` solves the remaining runtime-backed provider uncertainty
20
+ - `0.0.10` makes diagnosis and recovery dependable
21
+ - `0.0.11` freezes public contracts
22
+ - `0.0.12` prepares the codebase and docs for a stable release decision
23
+
24
+ `0.1.0` is not treated as the next automatic version. It is the release gate reached only after the `0.0.9 -> 0.0.12` line has proven stable.
25
+
26
+ ## 2. Planning Principles
27
+
28
+ Across `0.0.9` to `0.0.12`, the project should prefer:
29
+
30
+ - stabilizing existing behavior over adding new command families
31
+ - making side effects explicit over hiding them behind convenience
32
+ - improving diagnosis and recovery before broadening abstractions
33
+ - containing runtime-backed complexity rather than generalizing too early
34
+ - deferring plugin-system work until there is more than one real runtime-backed path to support
35
+
36
+ This means the roadmap does not aim to deliver:
37
+
38
+ - a true plugin system
39
+ - a broad auth adapter platform
40
+ - a background daemon product
41
+ - a GUI / TUI track
42
+ - multiple unrelated runtime-backed provider families
43
+
44
+ ## 3. Release Target Semantics
45
+
46
+ By the end of this roadmap, the project should be able to justify `0.1.0` with confidence that:
47
+
48
+ - the command surface is stable for humans and automation
49
+ - the top-level `--json` envelope is effectively frozen
50
+ - `providers.json`, `config.toml`, `auth.json`, backups, and runtime state have clear boundaries
51
+ - direct providers remain stable
52
+ - the Copilot runtime-backed path is understandable, diagnosable, and recoverable
53
+ - docs reflect actual shipped behavior
54
+
55
+ ## 4. Version Plan
56
+
57
+ ## 4.1 `0.0.9`: Runtime-Backed Provider Stabilization
58
+
59
+ ### Objective
60
+
61
+ Make the Copilot runtime-backed provider path operationally safe, explainable, and testable.
62
+
63
+ ### Why `0.0.9` comes first
64
+
65
+ `0.0.8` introduced the first optional runtime install and local bridge lifecycle. That is the largest behavior change in the current line. If this remains fuzzy, later contract and documentation work will sit on an unstable foundation.
66
+
67
+ ### Main tasks
68
+
69
+ - Confirm the exact user-visible Copilot lifecycle:
70
+ - detect runtime-backed provider
71
+ - probe optional SDK install state
72
+ - fail clearly when SDK is missing
73
+ - install only when explicitly allowed by the command path
74
+ - verify upstream Copilot auth state
75
+ - start or reuse bridge
76
+ - healthcheck bridge
77
+ - only then mutate managed Codex files
78
+ - Tighten runtime error semantics:
79
+ - `COPILOT_SDK_MISSING`
80
+ - `COPILOT_SDK_INSTALL_FAILED`
81
+ - `COPILOT_SDK_UNSUPPORTED`
82
+ - `COPILOT_AUTH_REQUIRED`
83
+ - `BRIDGE_PORT_CONFLICT`
84
+ - `BRIDGE_START_FAILED`
85
+ - `BRIDGE_HEALTHCHECK_FAILED`
86
+ - Improve first-use CLI messaging:
87
+ - explain that the runtime is optional
88
+ - explain that installation is lazy and local
89
+ - explain where the runtime is installed
90
+ - explain whether failure is repairable by reinstall or upstream login
91
+ - Make runtime state handling explicit:
92
+ - what is persisted
93
+ - what is best-effort only
94
+ - how stale bridge state is treated
95
+ - when old runtime state is ignored, reused, or cleared
96
+ - Ensure direct providers never pass through Copilot-specific runtime checks
97
+
98
+ ### Testing tasks
99
+
100
+ - Add runtime installation probe coverage
101
+ - Add non-interactive failure-path coverage for missing SDK
102
+ - Add bridge reuse vs fresh-start coverage
103
+ - Add stale runtime-state coverage
104
+ - Add rollback-path coverage when bridge start succeeds but file mutation fails
105
+ - Re-run direct-provider regression coverage
106
+
107
+ ### Documentation tasks
108
+
109
+ - Update README runtime-backed provider notes
110
+ - Update `docs/cli-usage.md` for Copilot-related command semantics
111
+ - Document runtime install location and runtime state file purpose
112
+
113
+ ### Exit criteria
114
+
115
+ `0.0.9` is complete when:
116
+
117
+ - Copilot runtime-backed usage has a predictable first-use flow
118
+ - runtime failures map to actionable error messages
119
+ - lazy install behavior is understandable from both CLI output and docs
120
+ - direct-provider behavior still passes regression coverage
121
+
122
+ ## 4.2 `0.0.10`: Recovery and Diagnostics Hardening
123
+
124
+ ### Objective
125
+
126
+ Make local-state diagnosis, rollback expectations, and runtime visibility strong enough that the CLI feels safe to operate.
127
+
128
+ ### Why `0.0.10` comes next
129
+
130
+ Once runtime-backed behavior is stable, the next risk is supportability. Users need to know what is broken, where it is broken, and what they can safely do next.
131
+
132
+ ### Main tasks
133
+
134
+ - Improve `doctor` so it explains cross-file inconsistencies clearly:
135
+ - provider missing from registry
136
+ - linked profile missing from `config.toml`
137
+ - `base_url` mismatch
138
+ - `env_key` mismatch
139
+ - `auth.json` key/value mismatch with active provider
140
+ - runtime-backed provider configured but runtime unavailable
141
+ - stale or invalid bridge state
142
+ - Review `status` so it can answer:
143
+ - which provider is active
144
+ - whether config projection is consistent
145
+ - whether auth mirror state is consistent
146
+ - whether runtime-backed dependencies are healthy
147
+ - Review write commands for transaction and rollback integrity:
148
+ - `setup`
149
+ - `add`
150
+ - `edit`
151
+ - `switch`
152
+ - `remove`
153
+ - `import`
154
+ - `rollback`
155
+ - Re-check lock, backup, and rollback boundaries now that runtime side effects exist
156
+ - Strengthen rollback UX:
157
+ - clearer backup listing
158
+ - clearer latest-backup recovery path
159
+ - clearer missing/corrupt-backup failure output
160
+ - Decide whether a narrow repair-oriented helper is needed before `0.1.0`
161
+ - if yes, keep it minimal
162
+ - if not, ensure `doctor` provides precise next actions
163
+
164
+ ### Testing tasks
165
+
166
+ - Add malformed runtime-state coverage
167
+ - Add backup corruption and partial-history edge cases
168
+ - Add `rollback latest` coverage if that path is intended to be stable
169
+ - Add cross-file inconsistency fixtures for `doctor`
170
+
171
+ ### Documentation tasks
172
+
173
+ - Expand troubleshooting guidance
174
+ - Document how backups relate to runtime state
175
+ - Explain what managed rollback does and does not cover
176
+
177
+ ### Exit criteria
178
+
179
+ `0.0.10` is complete when:
180
+
181
+ - common failure states can be diagnosed from CLI output
182
+ - rollback remains trustworthy for managed files
183
+ - runtime-specific side effects are clearly separated from file rollback guarantees
184
+
185
+ ## 4.3 `0.0.11`: Public Contract Freeze
186
+
187
+ ### Objective
188
+
189
+ Lock the external behavior expected by human users, scripts, and future AI callers.
190
+
191
+ ### Why `0.0.11` follows recovery work
192
+
193
+ Contract freeze should happen after the runtime path and repair path have already settled. Freezing too early just causes repeated exceptions and compatibility noise.
194
+
195
+ ### Main tasks
196
+
197
+ - Review command behavior for stability:
198
+ - `list`
199
+ - `show`
200
+ - `current`
201
+ - `status`
202
+ - `doctor`
203
+ - `setup`
204
+ - `add`
205
+ - `edit`
206
+ - `switch`
207
+ - `remove`
208
+ - `import`
209
+ - `export`
210
+ - `backups`
211
+ - `rollback`
212
+ - Freeze the top-level JSON envelope:
213
+ - `ok`
214
+ - `command`
215
+ - `data`
216
+ - `warnings`
217
+ - `error`
218
+ - Review command-specific `data` payloads and identify fields that should now be considered stable
219
+ - Audit non-interactive behavior:
220
+ - `--json` must not prompt
221
+ - non-TTY mode must not prompt
222
+ - commands requiring additional input must fail explicitly
223
+ - Audit TTY-only behavior:
224
+ - prompt cancel semantics
225
+ - destructive confirmation semantics
226
+ - wording alignment with current managed model
227
+ - Tighten help text and examples so docs and behavior match exactly
228
+
229
+ ### Specific contract areas to verify
230
+
231
+ - `setup` adoption rules must align with provider/config/auth separation
232
+ - `switch` success must mean both `config.toml` and `auth.json` are correct
233
+ - `import --merge` must not leave linked profile state drifting
234
+ - `edit` must enforce the stable managed provider field set
235
+ - `status` and `doctor` must expose enough detail without future top-level shape changes
236
+
237
+ ### Testing tasks
238
+
239
+ - Add JSON snapshot-style assertions where useful
240
+ - Add more non-interactive validation coverage
241
+ - Add `status` / `doctor` coverage for both direct and runtime-backed providers
242
+ - Verify help rendering after wording cleanup
243
+
244
+ ### Documentation tasks
245
+
246
+ - Refresh command reference docs against actual behavior
247
+ - Document which output fields are stable vs descriptive
248
+ - Clarify interactive convenience vs automation contract
249
+
250
+ ### Exit criteria
251
+
252
+ `0.0.11` is complete when:
253
+
254
+ - command behavior is stable enough to treat as a release contract
255
+ - JSON output no longer needs structural changes for known near-term needs
256
+ - prompt and non-prompt paths behave consistently across commands
257
+
258
+ ## 4.4 `0.0.12`: Architecture Cleanup and Release Readiness
259
+
260
+ ### Objective
261
+
262
+ Make the codebase, tests, and shipped materials clean enough that the project can either release `0.1.0` directly after `0.0.12` or justify one more pre-release step with clear reasons.
263
+
264
+ ### Why `0.0.12` is the last pre-`0.1.0` planned version
265
+
266
+ By this point, runtime behavior, recovery behavior, and public contracts should already be settled. The final pre-release version should focus on maintainability, packaging clarity, and release discipline.
267
+
268
+ ### Main tasks
269
+
270
+ - Review `src/cli.ts` and command wiring for continued responsibility leakage
271
+ - Refine the intended boundaries:
272
+ - command surface
273
+ - interaction layer
274
+ - application use cases
275
+ - domain policies
276
+ - storage repositories
277
+ - runtime integrations
278
+ - Reduce hidden coupling between:
279
+ - CLI parsing and business rules
280
+ - prompts and mutation orchestration
281
+ - runtime integration logic and provider storage rules
282
+ - Standardize runtime integration entry points and helper naming
283
+ - Check exported types and JSDoc coverage for modules that now define stable contracts
284
+ - Prune compatibility logic that no longer serves the current release line
285
+ - Perform a full documentation pass:
286
+ - README
287
+ - CLI usage
288
+ - testing guide
289
+ - design docs
290
+ - changelog / release notes
291
+ - Resolve version-document naming confusion where practical
292
+ - Audit package publishing surface:
293
+ - included files
294
+ - help/version output
295
+ - install instructions
296
+ - Node version assumptions
297
+ - Define the final `0.0.12 -> 0.1.0` release checklist
298
+
299
+ ### Testing and maintenance tasks
300
+
301
+ - Keep tests aligned with module boundaries, not only end-to-end scenarios
302
+ - Ensure fixture usage stays understandable and isolated
303
+ - Update `docs/testing.md` if test-layer responsibilities changed
304
+ - Run release verification against:
305
+ - fresh Codex directory
306
+ - existing valid managed directory
307
+ - partially broken directory
308
+ - runtime-backed provider directory
309
+ - non-interactive automation usage
310
+
311
+ ### Suggested checklist
312
+
313
+ - `npm run build`
314
+ - `npm test`
315
+ - built CLI `--help`
316
+ - built CLI `--version`
317
+ - read commands in JSON mode
318
+ - write commands in temp sandbox
319
+ - runtime-backed provider health scenarios
320
+ - docs updated for actual shipped behavior
321
+ - changelog updated
322
+
323
+ ### Exit criteria
324
+
325
+ `0.0.12` is complete when:
326
+
327
+ - code structure matches the intended architecture closely enough
328
+ - new fixes no longer require repeatedly editing oversized entrypoint logic
329
+ - runtime integration feels like an explicit capability domain
330
+ - the package presents itself consistently as a near-release build
331
+ - the shipped docs match actual behavior
332
+ - there is a repeatable release check ready for the `0.1.0` decision
333
+
334
+ ## 5. `0.1.0` Release Gate
335
+
336
+ Release `0.1.0` only if, after `0.0.12`, all of the following are true:
337
+
338
+ - direct providers are stable and regression-covered
339
+ - Copilot runtime-backed provider behavior is documented and operationally understandable
340
+ - managed file boundaries are explicit and reflected in docs and diagnostics
341
+ - write commands remain protected by lock, backup, and rollback semantics
342
+ - `--json` envelope and major command outputs are stable
343
+ - release docs, changelog, and test guide match the shipped package
344
+
345
+ If one or more of these remain weak, continue with `0.0.13+` instead of forcing the minor-version bump.
346
+
347
+ ## 6. Explicitly Deferred Until After `0.1.0`
348
+
349
+ The following items should stay out of this roadmap unless a hard dependency forces them in:
350
+
351
+ - general plugin system
352
+ - extension marketplace semantics
353
+ - broad auth adapter platform
354
+ - daemonized background bridge supervision
355
+ - GUI / TUI product tracks
356
+ - turning `config.toml` support into a general-purpose editor
357
+ - multiple new runtime-backed provider families with divergent behavior
358
+
359
+ These are valid future directions, but they should not dilute the current release goal.
360
+
361
+ ## 7. Main Risks
362
+
363
+ ### Risk 1: Runtime complexity leaks into the whole CLI
364
+
365
+ If Copilot runtime handling is not kept contained, command behavior and diagnostics will become harder to reason about across all providers.
366
+
367
+ Mitigation:
368
+
369
+ - keep runtime-backed logic behind explicit runtime checks
370
+ - preserve direct-provider fast paths
371
+ - maintain separate tests for direct and runtime-backed scenarios
372
+
373
+ ### Risk 2: Lazy install feels hidden or surprising
374
+
375
+ Users usually react more strongly to unexplained installation side effects than to the installation itself.
376
+
377
+ Mitigation:
378
+
379
+ - make first-use messaging explicit
380
+ - document install location and repair path
381
+ - expose runtime state in `status` and `doctor`
382
+
383
+ ### Risk 3: The `0.1.0` goal expands into platform work
384
+
385
+ The project can drift from “stabilize a CLI” into “design a plugin platform” if future-looking abstractions are introduced too early.
386
+
387
+ Mitigation:
388
+
389
+ - keep runtime semantics narrow
390
+ - defer true plugin work
391
+ - only add abstractions justified by current behavior
392
+
393
+ ### Risk 4: Docs and version files drift from implementation
394
+
395
+ The repository already has several versioned design and PRD documents. Without a cleanup pass, release messaging can remain confusing.
396
+
397
+ Mitigation:
398
+
399
+ - reserve explicit doc-alignment time in `0.0.12`
400
+ - tie roadmap progress to implementation reality, not just historical filenames
401
+
402
+ ## 8. Suggested Immediate Next Steps
403
+
404
+ From the current repository state, the practical next order is:
405
+
406
+ 1. Finish the remaining `0.0.9` runtime stabilization items.
407
+ 2. Expand `status` and `doctor` for runtime-backed visibility in `0.0.10`.
408
+ 3. Add missing runtime and recovery test cases before `0.0.11`.
409
+ 4. Freeze command/output semantics in `0.0.11`.
410
+ 5. Do one architecture and documentation cleanup pass in `0.0.12`.
411
+ 6. Decide `0.1.0` only after the `0.0.12` release checklist passes.
412
+
413
+ This keeps the release line focused and avoids premature abstraction.
@@ -0,0 +1,62 @@
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 行为不回退
@@ -0,0 +1,166 @@
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 回归