diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index c0617c856b5..e537826e9f4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -99,5 +99,5 @@ docs/dev-rules/mobile-development.md 的「冷更边界」。 --> - [ ] 每个 commit 都带 DCO 签名(`git commit -s`,见 [DCO](../DCO)) - [ ] UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过) - [ ] 未提交凭证、令牌或授权文件 -- [ ] 已补充必要文档 +- [ ] 已核对受影响的文档,行为变化涉及的旧结论已同步修订(不涉及则无需修改文档) - [ ] 已确认测试结果或说明未执行原因 diff --git a/docs/dev-rules/development-workflow.md b/docs/dev-rules/development-workflow.md index 531e6b269ff..6de2ae2d7ec 100644 --- a/docs/dev-rules/development-workflow.md +++ b/docs/dev-rules/development-workflow.md @@ -105,6 +105,12 @@ worktree 会话契约、直推 `main` 的额外门禁与 review 严重度口径 对照 `docs/` 下各规则与 `.github/PULL_REQUEST_TEMPLATE.md`(以现行内容为准,不凭记忆): +- **核对受影响的文档**:改动改变已有行为时,结合实现和测试核对对应权威文档中的旧结论; + 发现冲突就在本次改动中修正,并在相关说明旁链接实现或测试,便于后续核对。不涉及文档 + 变化的 PR 无需修改文档,也无需另写经验总结。 +- **经验回写到已有依据**:纠正和排障发现说明错误或不完整时修原文;说明正确但入口遗漏时 + 补入口或触发条件;能自动验证的问题优先补回归测试。一次环境故障不默认升级为长期规则。 + - **P0**(不改不能合):红线/崩溃/数据丢失/跨平台失效/安全。 - **P1**(本次必须修但不阻断流程):明显 bug/规范违反/影响面没处理干净。 - **P2**(可选优化 / 风格偏好):不报。 diff --git a/docs/dev-rules/orca-team-architecture.md b/docs/dev-rules/orca-team-architecture.md index 88930c5c9c2..856e0b2567b 100644 --- a/docs/dev-rules/orca-team-architecture.md +++ b/docs/dev-rules/orca-team-architecture.md @@ -38,7 +38,7 @@ Orca 是 Cindy Desktop 内的多 agent 协同能力:一个 **Lead session** - 多 worker:同一个 active team 下可创建多个 worker,支持 role、label、focused worker 切换、soft/hard limit 与归档。 - Split view:Lead 与 focused Worker 共用 `OrcaSplitView` pane 外壳,宽屏为左右 split,doc rail 为 Lead/Worker toggle。见 `apps/desktop/src/renderer/features/cc-agent/OrcaSplitView.tsx` 的 `OrcaSplitView`、`OrcaPaneShell`。 -- 本地 Claude Code、Codex 与 Pi 的普通 Lead 无论是项目还是对话都可开启协同,本地 Worker 也支持这三类 agent;Pi 当前仅支持本地 Lead / Worker,不支持 SSH 远程协同。SSH 远端会话的 Claude Code 与 Codex 两端均可作 Lead(远端 agent 经 SSH remote-forward 直连本机 HTTP MCP bridge,`cindy_orca` 在两端都可用:codex 走 daemon config 注入,cc 走 per-query http 注入);device-link 被控端的项目与对话同样可作 Lead(Lead / Worker / team 的真身都在被控端,控制端只是镜像)。renderer 的入口判定收敛在 `apps/desktop/src/renderer/features/cc-agent/collabEntryPolicy.ts` 的 `resolveCollabEntryPolicy`,新建草稿(`NewMakerDraftRoute`)与会话视图(`CCAgentSessionView` 的 `allowCollabToggle`)共用同一份:普通 Lead 都显示入口,只排除不能嵌套协同的 Orca Worker 子会话。项目按项目级策略查询;Main 的 `resolveLocalCollabPolicyWorkingDir` 同时服务入口状态查询与最终授权,只有 workspace kind 为 dialogue 且 Main 确认目录位于 app 托管 dialogue root 时才只查用户级/全局级策略(即使 cwd 内出现 `.cindy/plugins.json`),显式绑定真实目录的对话仍按该目录的项目级策略查询,不能靠自报 `workspaceKind` 绕过项目禁用。 +- 本地 Claude Code、Codex 与 Pi 的普通 Lead 无论是项目还是对话都可开启协同,本地 Worker 也支持这三类 agent;SSH 远端会话的 Claude Code、Codex 与 Pi 均可作 Lead 或 Worker(远端 agent 经 SSH remote-forward 连接本机 MCP bridge:Codex 走 daemon config 注入,Claude Code 走 per-query HTTP 注入,Pi 走内部 MCP bridge URL 改写);device-link 被控端的项目与对话同样可作 Lead(Lead / Worker / team 的真身都在被控端,控制端只是镜像)。renderer 的入口判定收敛在 `apps/desktop/src/renderer/features/cc-agent/collabEntryPolicy.ts` 的 `resolveCollabEntryPolicy`,新建草稿(`NewMakerDraftRoute`)与会话视图(`CCAgentSessionView` 的 `allowCollabToggle`)共用同一份:普通 Lead 都显示入口,只排除不能嵌套协同的 Orca Worker 子会话。项目按项目级策略查询;Main 的 `resolveLocalCollabPolicyWorkingDir` 同时服务入口状态查询与最终授权,只有 workspace kind 为 dialogue 且 Main 确认目录位于 app 托管 dialogue root 时才只查用户级/全局级策略(即使 cwd 内出现 `.cindy/plugins.json`),显式绑定真实目录的对话仍按该目录的项目级策略查询,不能靠自报 `workspaceKind` 绕过项目禁用。 - Codex Lead 使用全局注册的 `cindy_orca`,调用时通过 context 恢复身份并在 handler 内拒绝越权。远端 Codex 同样走 `params._meta.threadId` 路由——remote thread 与本地 thread 一样注册进 `CodexMcpThreadContextStore`(`packages/maker-core/src/agents/codex/index.ts` 的 `registerCodexMcpContext` 不再跳过 remoteHostId)。远端 cc 没有 threadId,身份走持久 bearer token + URL `?session=` 路由(`codexHttpBridge.registerSessionCtx`),审批归属快照在 `remoteCcQueryFactory` 注入后按 `startParams.mcpServers` 最终清单定稿。 - SSH 远端 Codex 的 MCP 桥接:本机 `codexHttpBridge` 在原有 per-run 主 token 之外接受一个 persistent bearer token(safeStorage);`remote-ssh/codex-remote-mcp.ts` 在 session start/resume 前置完成 per-host 固定端口 remote-forward(`RemoteHost.openRemoteForward`,重连自动 rebind)、远端 `$CODEX_HOME/config.toml` 的 `mcp_servers` 管理段漂移检测(行级 marker + 剥离用户同名 table)与 daemon 幂等 bootstrap(token 只经 stdin 的 KEY=value 块注入,不进 argv);config 漂移需要重启 daemon 时若同 host 有 live turn 则本次降级(留待下次 ensure)。worker 创建经 `OrcaLeadSessionSnapshot.remoteHostId` 继承在同一台远端主机 spawn,创建前走 `ensureRemoteReadyForSessionStart`(SSH 重连 / agent 安装 / MCP 注入);lazy resume 与 Orca worker 唤醒路径同样先 ensure 再 bootstrap。 - PR #107 提供 side_chat 的底层 fork 数据动作:user/assistant 消息都能 fork,assistant 按 turn 粒度复制,Claude 用 uuid 锚点,Codex 用 ThreadFork + ThreadRollback。当前作为普通 session 跳转;未来要登记为 side activity 并挂入统一 pane。 @@ -51,7 +51,21 @@ Orca 是 Cindy Desktop 内的多 agent 协同能力:一个 **Lead session** - workflow_run / CC Workflow 编排还未纳入当前实现。 - side_chat 尚未登记为 side activity 对象,也未挂进 pane;PR #107 只是 fork 数据动作。 - device-link 协同的 Lead / Worker / team 全部在被控端进程内编排,控制端只按 session 来源经隧道路由(`makerTransport` 的 `makerApiFor` / `orcaWorkflowsFor` / `subscribeOrcaWorkerChanged`,channel 见 `packages/device-link/src/allowlist.ts` 的 Orca 段)。collab 开关同样查被控端(`maker:plugins:get-state` 经 `pluginEnableStateFor`):项目读取被控端项目级策略,对话读取被控端用户级/全局级策略。控制端本机状态不能代表被控端真相。老被控端没有该 channel 时回 `CHANNEL_NOT_ALLOWED`,控制端 fail-closed 置灰入口并提示设备版本过旧,而不是放行到 `enableOrca` 才撞错。 -- SSH 远端协同仅支持 codex 与 claude-code 两类 lead + 远端 worker(继承 remoteHostId),不支持 Pi Lead 或 Pi Worker。cc 远端经 `cc-remote-mcp.ts` 把 `cindy_orca` / `orca_worker_bridge` 以 http 形态追加进 `startParams.mcpServers`(persistent token + `?session=` 路由,白名单仅此两个 server)。远端 worker 手动 `send_to_lead` 依赖 daemon 侧 `orca_worker_bridge` 经同一 bridge 可达;auto-bridge 回报不依赖 worker 侧 MCP,天然可用。共享 userData 多实例连同一远端 host 时,只有先建立 SSH 转发的实例能持有该 host 的 MCP bridge 端口,其余实例按“远端无 MCP”降级(与历史行为一致)。远端会话的项目级 collab 开关不查本机 fs;`assertCollabProjectEnabled` 对 remote 只查用户级/全局级开关,远端项目级配置机制是 follow-up。 +- SSH 远端协同支持 Claude Code、Codex 与 Pi Lead / Worker;Worker 继承 Lead 的 `remoteHostId` 与远端工作目录,在同一台远端主机执行,启动前复用远端就绪检查。cc 远端经 `cc-remote-mcp.ts` 把 `cindy_orca` / `orca_worker_bridge` 以 http 形态追加进 `startParams.mcpServers`(persistent token + `?session=` 路由,白名单仅此两个 server)。远端 worker 手动 `send_to_lead` 依赖 daemon 侧 `orca_worker_bridge` 经同一 bridge 可达;auto-bridge 回报不依赖 worker 侧 MCP,天然可用。Claude Code / Codex 共享 userData 多实例连同一远端 host 时,只有先建立 SSH 转发的实例能持有该 host 的 MCP bridge 端口,其余实例按“远端无 MCP”降级(与历史行为一致)。远端会话的项目级 collab 开关不查本机 fs;`assertCollabProjectEnabled` 对 remote 只查用户级/全局级开关,远端项目级配置机制是 follow-up。 + +Pi 的远端 Lead 沿用统一的 Lead 身份与 prompt 装配;内部 MCP(含 `cindy_orca`、 +`orca_worker_bridge`)经独立 SSH remote-forward 连接本机 bridge,不复用 Codex 的 +per-host 转发槽位。实际可用性仍受协同开关与桥接状态约束。核对入口: + +- Lead 激活与 prompt:[orcaLifecycleService.ts](../../apps/desktop/src/main/maker-ipc/orcaLifecycleService.ts) + 的 `activateLeadTeam` / `startTeam`,以及 + [orcaSessionStartOptions.ts](../../apps/desktop/src/main/maker-ipc/orcaSessionStartOptions.ts)。 +- Pi bridge 注入:[pi-host.ts](../../apps/desktop/src/main/maker-host/pi-host.ts) 的 + `preparePiExtraSpawnConfig`,以及 [maker-host/index.ts](../../apps/desktop/src/main/maker-host/index.ts) + 的 `rewriteRemotePiMcpBridgeUrl`。 +- Worker 创建:[orcaWorkerCreationService.ts](../../apps/desktop/src/main/maker-ipc/orcaWorkerCreationService.ts); + [对应测试](../../apps/desktop/src/main/maker-ipc/__tests__/orcaWorkerCreationService.test.ts)中的 + `allows Pi workers for a remote lead` 验证 Pi Worker 继承远端主机、工作目录与 Worker 角色。 ### 核心概念与数据模型