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

12 KiB
Raw Blame History

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-betaclaude-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 级 apibaseUrl、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-keydeferred credential 在物化后分类 由 request-capture 实证;不再停留在前置 C 的 DirectOnly
Skills Pi 进入统一 Skills UI;期望状态、原生发现、受管 ownership 分离;显式 native import 只在内容完全相同时接管;部署、删除、导入及 portable sync 有锁、CAS、事务补偿 Pi 的原生目录是部署目标,不能复用其他 app 的“复制后即视为拥有”假设
Prompts Prompt 库投影 AGENTS.md;同时原生管理 SYSTEM.mdAPPEND_SYSTEM.mdprompts/*.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.mdSYSTEM.mdAPPEND_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.rsmigration.rsbackup.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 不同的原生语义。 因此不为满足计数机械缩并,也不扩展到契约外功能。