Files
CC-Switch/docs/pi-main-project-zh.md
T

147 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Pi 主工程契约(纲领)
> 适用规则:`docs/pi-support-restructure-zh.md` §4.7(契约纲领化、协议放宽、增量审查)。
> 前置 A/B/C 已认证;本文是本工程**唯一**契约,不再有逐条裁决。
> 技术不变量以 `docs/pi-support-contracts-zh.md` 的五份契约为准(未变)。
## 目标
把 Pi 做成 cc-switch 的**一等公民 app**,与 Claude/Codex/OpenCode/Hermes 同级:
用户能在 Pi 这个 app 下管理供应商、模型、Skills、Prompts、Sessions、MCP,
能用网关代理它,能看到原生 `models.json` 的真实状态而不被我们的抽象骗。
## 验收标准
1. **同级**:`AppType::Pi` 在既有 app 的每一条通路上都存在且行为一致——
供应商与端点、切换与故障转移、Skills/Prompts/Sessions、MCP、深链、设置、
目录配置、可见性、使用统计、导入导出。以 **Hermes 为最近先例**逐条对照;
凡先例有而 Pi 没有的通路,要么实现,要么在本文件写明为何不适用。
2. **原生真实**:Pi 的原生资产(`models.json`、AGENTS.md / SYSTEM.md /
APPEND_SYSTEM.md、prompts、sessions)以 pinned Pi 的语义读写;
`exists = active`,不造影子状态;只读检查面已由前置 C 认证,主工程复用它,
不得另起一套判定。
3. **网关数据面**:Pi 供应商可经网关代理;候选物化、失败转移、协议身份沿用
前置 C 认证的判定结果。**OAuth 凭证(`sk-ant-oat` 子串)在本工程实现**——
Anthropic 族按实测发 `Authorization: Bearer` + oauth beta 头、不发 x-api-key;
完成前维持前置 C 的诚实降级(DirectOnly),不得半实现。
4. **可用**:UI/i18n 中英文齐全;新用户能从零添加一个 Pi 供应商并切换成功。
5. **不回退**:测试总数只增不减;既有 app 的行为不受影响。
## 边界
- 不碰:pinned 夹具、已重冻的 infra 三文件(`schema.rs`/`migration.rs`/`backup.rs`)、
restore 面(见 `docs/restore-hardening-debt-zh.md`)、三份认证套件、
`stash@{0}`、PR #5598;
- extensions 只做设计附录,themes 不做(用户已裁定);
- 不 push、不建 PR(终态交付仍是**一个** PR,由用户决定何时发)。
## 证据规则
凡断言"pinned Pi 如此行为",须有 oracle 或 `scripts/pi-transport-capture.mjs`
的实证,不接受读源码推断——这是四轮返工换来的唯一保留仪式。
## 自由度
范围划分、commit 粒度、DTO 与模块组织、测试组织、验证与审查节奏,全部自定。
不必对齐红绿账本,不必按固定轮次做盲审,偏离不必硬停上报。
遇到本文与既有契约冲突、或需要用户拍板的产品取舍(功能取舍、范围增删),
才上报;其余自行裁量,完成后报终态 SHA。
## 实现 authority 与可复现实证
- 唯一 Pi implementation pin:
`ab366ebe94cacd419d986be454f12b1b9913aaca`。主工程没有沿用历史文档中的
旧 pin,也没有从远端观察值推导行为。
- `scripts/generate-pi-native-oracle.mjs` 负责 schema/composer 的冻结 oracle
`scripts/pi-transport-capture.mjs` 负责需要真实执行 Pi 才能确认的 transport、
compat、原生资源与 CLI 行为。两者都先校验上述 commit,pin 不符即拒绝运行。
- 主工程捕获命令:
`PI_CHECKOUT=<pinned-Pi-checkout> node scripts/pi-transport-capture.mjs`
捕获直接执行 Pi,而非阅读上游源码推断。
- 捕获的发行元数据来自 `packages/coding-agent/package.json`,该文件在 pin 上的
SHA-256 为
`e02deae1cec07035807436c1864c88342e2f7d49050d03b858a3719f0c7aedbf`
包名 `@earendil-works/pi-coding-agent`、可执行文件 `pi`、配置目录 `.pi`
`parseArgs(["--version"])` 与带空格绝对路径的
`parseArgs(["--session", path])` 均由捕获实际执行。
- 同一捕获实际发出了四族请求并记录最终 URL/headers。Anthropic OAuth 凭证
(`sk-ant-oat` 子串)最终为 `Authorization: Bearer <credential>`
`anthropic-beta``claude-code-20250219,oauth-2025-04-20`,且主工程策略
强制不并发 `x-api-key`。OpenAI Responses/Completions、Google 与普通
Anthropic key 的头部矩阵也在同一输出中。
## Hermes 先例逐项对照账本
| 通路 | Pi 终态 | Hermes 差异或不适用理由 |
|---|---|---|
| App 注册、切换器、图标、可见性 | `AppType::Pi` 贯穿 Rust/IPC/TS,旧设置缺字段时默认可见,可独立隐藏 | 无差异 |
| 供应商与模型 | 独立 Pi 表单无损保留 provider/model 的未知 JSON;支持 provider/model 级 `api``baseUrl`、headers、`authHeader`、credential、cost/compat 等 pinned 字段;原生 catalog 使用已认证 inspection 导入 | Hermes 的 Web UI overlay/只读 provider 是 Hermes 自身所有权模型,Pi 使用共享 `models.json`,不套用 overlay |
| 新用户首用 | 创建第一位 Pi provider 时,在数据库、完整初始 endpoints 与原生 catalog 同一协调边界内发布,并把其第一模型设为 native default;随后可直接切换/代理 | 无需先手工导入或另开 native 文件 |
| 原生 catalog 与当前状态 | 复用前置 C 的三层 inspection;展示 raw/managed/composer/gateway 状态;可用 fingerprint CAS 导入;当前 provider/model 直接读 native defaults | 不以数据库 current 字段制造第二份“当前”状态 |
| 端点 | provider 主端点与多个 typed custom endpoints 均可增删、测速;membership 与 provider hydration 一致;网关按主端点及有序候选展开 | Hermes 的 additive provider 不具备该网关数据面 |
| 切换、代理与故障转移 | Pi 有独立 loopback route/token、catalog epoch、健康状态、重试/熔断和 failover 队列;候选必须保持 wire family 与协议身份兼容;不可预测协议表达式只允许单次 direct attempt,不重放 | Hermes 当前没有 cc-switch gateway handlerPi 对照的是已有完整代理 app 的安全边界 |
| OAuth 数据面 | 完整实现 Anthropic OAuth 的 Bearer + oauth beta,强制删除 `x-api-key`deferred credential 在物化后分类 | 由 request-capture 实证;不再停留在前置 C 的 DirectOnly |
| Skills | Pi 进入统一 Skills UI;期望状态、原生发现、受管 ownership 分离;显式 native import 只在内容完全相同时接管;部署、删除、导入及 portable sync 有锁、CAS、事务补偿 | Pi 的原生目录是部署目标,不能复用其他 app 的“复制后即视为拥有”假设 |
| Prompts | Prompt 库投影 `AGENTS.md`;同时原生管理 `SYSTEM.md``APPEND_SYSTEM.md``prompts/*.md`;文件存在即 active,直接编辑空白值会拒绝并要求显式删除 | Hermes 的 prompt 通路仍可复用;Pi 额外公开 pinned 原生资源,不制造 enabled 影子字段 |
| Sessions | 扫描 pinned v1v3 JSONL tree、只显示 active branch,支持详情、删除、终端恢复;遵守环境/设置/default sessionDir;相对 sessionDir 明示需要项目 cwd,不伪装为空列表 | Pi 的 tree/branch 与 Hermes session 格式不同,使用独立 parser 但复用统一 Session UI/安全入口 |
| MCP | **不适用**pinned Pi core 没有原生 MCP registryUI 不展示虚假 MCP 状态,服务入口结构化拒绝;capture 的 core tool inventory 为 `bash/edit/find/grep/ls/read/write` | Hermes 有原生 MCP registryPi extensions 可贡献 tools,但不等同 MCP。未来方案见 `docs/pi-extensions-design-appendix-zh.md` |
| 深链 | provider 深链支持 Pi provider key、模型、api、端点及 credential,走真实 `ProviderService::add`;prompt 深链走统一库与 Pi 文件所有权链 | 未识别 Pi API 保持 opaque,不用名称猜协议 |
| 设置与目录 | 设置页可发现/选择 Pi 配置目录,支持 `PI_CODING_AGENT_DIR`、WSL 路径展示、安装检测、网关/故障转移参数与凭证轮换;本地 gateway token 不下发前端 | 配置目录和 token 是 device-local,不写进 portable DB |
| 使用统计 | 四族 response/SSE 使用量进入统一日志、价格、筛选与 dashboard;每请求携带 input-token semantics,不能用 `app_type` 猜;Pi 混合协议的 cache-write 总数标为“部分可得” | Hermes 无 gateway usagePi 的单一 app 桶可能混合四族,不能显示误导性的确定 0 |
| 导入导出与远端同步 | DB provider/prompt/skill 期望状态可 portable;恢复后通过 catalog/prompt/skill reconciliation 与本机原生状态对齐;设备目录、native defaults、token、session 不跨机复制 | 原生资产属于设备/外部事实,不能塞进 SQL/binary 备份制造影子副本 |
| Profile 切换器 | **不适用**:现有项目 Profile 仅定义 Claude 组与 Codex 组,Hermes 本身也不属于任何 Profile scope;Pi 页面同样不展示 | 若未来产品定义新的跨 app Profile scope,应单独设计原生文件事务,不能暗自归入 Claude/Codex |
| Hermes Memory/Web UI | **不适用**:这是 Hermes 独有 daemon/APIPi 的长期上下文入口是 `AGENTS.md` 与原生 instruction files,已在 Prompts 面公开 | 不伪造不存在的 Pi daemon 或 Web UI |
| 原生“一键导入”按钮 | Pi 不调用 generic `import_default`;改为 certified native catalog 中逐 entry inspection + fingerprint CAS 导入 | 这是更严格的等价通路,不是功能缺失 |
| Extensions / Themes | extensions 本工程只交设计附录;themes 明确排除 | 用户已裁定范围 |
## 原生状态与 portable 状态边界
1. `models.json` 的读取、composition 与 gateway capability 只走前置 C 已认证链。
写入统一经 Pi catalog coordinator,协调 DB aggregate、typed endpoints、
native document、default provider/model、epoch 与失败补偿;legacy live-sync
不得旁路写它。
2. `AGENTS.md``SYSTEM.md``APPEND_SYSTEM.md`、prompt templates、Skills
与 Sessions 直接观察真实文件;所有 UI active 判断均来自 `exists` 或实际发现。
revision/fingerprint 只用于并发保护,不是第二套 enabled 状态。
3. portable import 恢复的是 cc-switch 拥有的 provider、prompt 与 Skill 期望状态,
随后与本机 native 事实 reconcile;不会跨设备覆盖目录、凭证 token、native
defaults 或会话。
4. Pi provider card 的“切换”选择该 provider 的第一模型;多模型的明确选择在
native catalog panel 完成,并写回同一 native default,不维护每 provider 的
隐藏 last-model 状态。
## 完成审查约束
- 主工程盲审最多七轮;每轮冻结精确 SHA/range,两位 fresh、互相独立、只读
reviewer。已审 clean SHA 作为下一轮增量基线;契约新增条款的作用域另做定向
全域调用点扫描。
- P0/P1 finding 必须修复;P2 由主审按可达性、影响面、数据/安全后果与发生概率
独立裁决,只有低影响且极少触发的边界才可保留,并在最终报告列出理由。
- 完成前做一次完整组件通读;零 validated P0/P1、相关验证全绿后才可交付。
## Scope audit(主工程预审检查点)
以主工程基线 `26a95aeb059235612c665d6b6bcd92fde9c3572e` 计,终态候选为
141 个文件、约 +16.9k 净行,触发历史 90 文件/12k 净行审计线。审计结论为
**范围大但未越界**
- Rust 70 文件:Pi catalog/typed endpoints、共享文件与 ownership、gateway/runtime/
usage、prompts/skills/sessions,以及把 `AppType::Pi` 接进现有 command/service/
startup/sync 通路;其中新增的大文件按 catalog、transport、runtime、session、
deployment 分开,避免一个全知模块。
- 前端与构建配置 55 文件:3 个 Pi 专用 panel/form、typed IPC/query、既有导航/
设置/代理/使用统计接线、四语 i18n 与 Windows 进程树能力;没有复制第二套 app
shell。
- 前端测试 13 文件:专用表单/prompt/usage 测试及既有跨 app matrix 增量。
- 证据与文档 3 文件:transport capture、本文账本、extensions 设计附录。
- `schema.rs``migration.rs``backup.rs`、三份认证套件及七个 pinned fixtures
均零改动;restore、themes 与 extensions 实现零文件。
压缩方案也做过评估:把 Pi 强塞进 legacy live-sync、通用 additive provider、
固定 app-type usage 语义或无 ledger Skill 复制可以减少文件,却会重新引入已经
认证过的 ownership/原生真实/协议分类错误;把 UI 与领域代码揉成少数巨型文件只
会减少文件数而增加审查风险。当前拆分复用了 provider write、proxy server、
统一 OS 条件替换原语、Prompt/Skill/Session UI、同步锁和统计基础设施,新增代码
只承载 Pi 不同的原生语义。
因此不为满足计数机械缩并,也不扩展到契约外功能。