Files
boss/docs/superpowers/specs/2026-04-06-device-gui-cli-capability-and-conflict-design.md

493 lines
12 KiB
Markdown
Raw Permalink 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.

# Mac/Windows 设备 GUI+CLI 双能力接入与并行冲突控制设计
日期:`2026-04-06`
## 1. 背景
Boss 当前的设备执行主链已经稳定在:
- 设备 heartbeat 上报
- `local-agent -> codex exec resume`
- Web / Android 会话与设备控制面
但现状仍有两个结构性缺口:
1. **设备模型还没有把 Codex GUI 与 Codex CLI 当成同一台设备下的两种能力。**
- 用户可能只开 GUI
- 也可能只开 CLI
- 也可能同一台 Mac / Windows 同时开着 GUI 和 CLI
- 当前 Boss 还没有显式表达这种“双能力设备”
2. **同一台设备的 GUI 与 CLI 同时推进同一项目时,缺少并行冲突控制。**
- 主 Agent 可能通过 CLI 正在推进某个项目
- 用户本人也可能在 GUI 中继续操作同一项目
- 如果两边都对同一 worktree 写入,很容易出现覆盖、上下文漂移、重复修改、误判进度
本轮设计要解决的是:
- 让 Boss 正式支持 `Mac / Windows``Codex CLI` 接入
- 让同一台设备同时支持 `GUI + CLI`
- 让 GUI / CLI 可以切换默认执行模式
- 在同项目并行写入风险出现时,默认阻断并弹出风险确认
## 2. 调研结论
### 2.1 官方产品结论
基于官方公开说明Codex app 与 CLI 的关系更像:
- 同一用户工作空间下的多个入口
- 共享 `session history`
- 共享 `configuration`
- 共享 `skills`
- 额度与使用量也统一计入同一个产品账户体系
因此Boss 不应把 GUI 与 CLI 理解成两个完全独立系统。
### 2.2 本地实测结论
在当前 macOS 开发机上Codex 的核心状态位于:
- `~/.codex/state_5.sqlite`
- `~/.codex/logs_1.sqlite`
- `~/.codex/session_index.jsonl`
- `~/.codex/.codex-global-state.json`
同时 GUI 还有自己的应用壳目录:
- `~/Library/Application Support/Codex`
这说明:
- `~/.codex` 更像主状态库
- `Application Support/Codex` 更像 GUI 壳层缓存/偏好/会话容器
### 2.3 Windows 实测结论
在局域网 Windows 设备 `192.168.31.18` 上实测:
- `C:\Users\kris\.codex` 存在
- 且真实包含:
- `state_5.sqlite`
- `logs_1.sqlite`
- `session_index.jsonl`
- `.codex-global-state.json`
- `auth.json`
- `config.toml`
这说明 Windows 上也存在同样的用户级 Codex 核心状态目录。
### 2.4 设计结论
因此在 Boss 中GUI 与 CLI 应建模为:
- **同一台物理设备下的两种能力**
- 不是两台设备
- 不是两套独立项目空间
## 3. 目标与非目标
### 3.1 目标
1. 支持 `Mac / Windows` 的 Codex CLI 接入。
2. 同一台设备可同时在线:
- `GUI`
- `CLI`
3. 设备级支持默认执行模式切换:
- `GUI`
- `CLI`
4. 主 Agent 和用户都可以在 GUI / CLI 间切换执行入口。
5. 检测同设备、同项目、同 folder/worktree 的并行写入风险。
6. 当发生并行写入风险时:
- 默认阻断继续执行
- 弹出风险警告
- 提供三个动作:
- `禁止`
- `允许本次`
- `永久放行`
7. 这三个动作都必须是**当前异常项目文件夹/线程级**,不是全局开关。
8. 整套冲突检测应尽量基于规则层完成,避免持续消耗 token。
### 3.2 非目标
1. 本轮不把 GUI 与 CLI 拆成两台虚拟设备。
2. 本轮不做 OS 级窗口焦点监测或键鼠监控。
3. 本轮不重写现有 `local-agent -> codex exec resume` 主链。
4. 本轮不要求 GUI 与 CLI 对同项目绝对互斥。
5. 本轮不做真正的多 worktree 自动编排,只做冲突识别与风险控制。
## 4. 用户体验结论
### 4.1 设备模型
一台物理设备在 Boss 中保持单条记录,例如:
- `Mac Studio`
- `Windows GPU`
但设备详情里要新增两类能力状态:
- `GUI`
- `CLI`
每种能力分别展示:
- 是否已连接
- 最近在线时间
- 最近活跃项目
### 4.2 默认执行模式
设备级新增 `默认执行模式`
- `GUI`
- `CLI`
说明:
- 这只是默认值
- 不会关闭另一种能力
- 同一台设备允许 `GUI + CLI` 同时在线
### 4.3 前台切换语义
用户层的真实语义是:
- 可以只用 GUI
- 可以只用 CLI
- 也可以同一台设备同时使用 GUI 和 CLI
Boss 必须支持三种状态共存,而不是互斥二选一。
## 5. 数据模型设计
### 5.1 Device 新增能力字段
为设备增加能力层字段:
- `capabilities.gui.connected`
- `capabilities.gui.lastSeenAt`
- `capabilities.gui.lastActiveProjectId`
- `capabilities.cli.connected`
- `capabilities.cli.lastSeenAt`
- `capabilities.cli.lastActiveProjectId`
- `preferredExecutionMode`
约束:
- `preferredExecutionMode` 仅允许:
- `gui`
- `cli`
### 5.2 Project / Folder 级并行风险状态
新增项目级或文件夹级并行状态:
- `deviceId`
- `folderKey`
- `projectId`
- `activeCliExecution`
- `recentExternalActivityAt`
- `conflictState`
- `allowPolicy`
其中:
- `conflictState`:
- `none`
- `warning`
- `blocked`
- `allowPolicy`:
- `forbid`
- `allow_once`
- `allow_always`
### 5.3 冲突动作生效粒度
这次风险警告上的所有动作都必须是**局部策略**,不是全局策略。
推荐主键:
- `deviceId + folderKey`
如果没有稳定 `folderKey`,退化为:
- `deviceId + projectId`
对于单线程项目,本质上仍然是该线程所在 folder/project 级别策略,而不是全账号或全设备策略。
也就是说:
- `禁止` 只表示当前这个异常项目/文件夹继续维持阻断
- `允许本次` 只放行当前这个异常项目/文件夹的一次执行
- `永久放行` 只放行当前这个异常项目/文件夹后续同类冲突
## 6. 并行冲突检测
## 6.1 冲突定义
满足以下条件时,视为并行冲突风险:
1. 同一台设备
2. 主 Agent 正通过 `CLI` 执行某项目的写入型任务
3. 同一项目 / folder / worktree 又出现新的外部活动
4. 该外部活动并非当前 Boss 发起的同一 CLI 任务的正常进展
这里的“外部活动”不强行区分一定来自 GUI 还是外部 CLI 手工操作。产品语义统一视为:
- **非当前 Boss 任务所控制的人工/外部活动**
如果设备同时具备 `GUI connected = true`,前台提示可优先表述为 GUI 并行操作;否则用更中性的“外部活动”提示。
### 6.2 检测方式
冲突检测应尽量走规则层,而不是 LLM 判断。
规则层输入:
- 当前 CLI 执行任务是否在跑
- 目标 deviceId / projectId / folderKey
- 线程 heartbeat / reply / activity 上报
- 最近外部活动时间
- 当前任务自己的 trace / taskId / targetThreadRef
输出:
- 是否冲突
- 冲突归属到哪个 folder/project
### 6.3 Token 策略
本设计要求:
- 冲突检测本身不调用 LLM
- 冲突提示文案模板化
- 只有用户主动要求“解释为什么冲突”或“请主 Agent 给建议”时,才允许主 Agent 读取线程状态文档与最近进展事件
因此,这套机制本身不应成为高 token 消耗来源。
## 7. 冲突拦截与用户确认
### 7.1 默认行为
发生并行冲突风险时:
- **默认不继续**
- 先弹风险警告
- 不直接自动放行
### 7.2 风险警告文案
默认模板:
- `检测到该项目正在同一设备上发生并行操作。`
- `主 Agent 当前正通过 CLI 推进,而你也在同一项目中产生了新的人工活动。`
- `继续执行可能导致文件覆盖、上下文偏移或重复修改。`
### 7.3 用户动作
警告卡必须提供三个动作:
1. `禁止`
- 当前这个异常项目/文件夹本次不继续
- 当前这个异常项目/文件夹保持默认阻断
- 不影响其他项目/文件夹
2. `允许本次`
- 只放行当前这个异常项目/文件夹的当前这一次执行
- 不改变当前项目/文件夹后续默认策略
- 不影响其他项目/文件夹
3. `永久放行`
- 仅对当前异常项目/文件夹生效
- 后续同一 `deviceId + folderKey` 再发生同类冲突时,允许继续
- 不影响其他项目/文件夹
### 7.4 永久放行撤销
`永久放行` 不是不可逆。
需要提供撤销入口,建议放在:
- 项目文件夹页 / 线程会话信息页
- 或设备详情中该项目的执行策略区
文案示例:
- `该项目已允许 GUI/CLI 并行继续`
- `关闭永久放行`
## 8. 执行路由设计
### 8.1 默认执行模式
主 Agent 与普通线程调度时:
- 先读设备的 `preferredExecutionMode`
- 优先走对应能力
### 8.2 执行能力选择
推荐行为:
- 写入型自动执行:优先 `CLI`
- 人工观察 / 人工接管 / 人工窗口操作:优先 `GUI`
### 8.3 同时在线
`GUI + CLI` 同时在线时:
- 不自动断开其中一边
- 也不自动把设备拆成两个逻辑设备
- 只在同项目并行写入风险时触发冲突控制
## 9. 前台设计
### 9.1 设备详情页
新增两个可见区:
1. `连接能力`
- `GUI`
- `CLI`
2. `默认执行模式`
- 单选:
- `GUI`
- `CLI`
### 9.2 项目文件夹 / 线程会话
当项目存在永久放行策略时,当前页可见:
- `GUI/CLI 并行已允许`
当项目发生实时冲突时,当前页显示风险卡:
- 风险说明
- `禁止`
- `允许本次`
- `永久放行`
### 9.3 主 Agent 交互
主 Agent 遇到此类冲突时:
- 默认停止继续下发
- 生成风险卡
- 等用户明确动作
注意:
- 这不代表主 Agent 抢占线程控制权
- 主 Agent 只是协同与调度者
- 用户仍可继续直接控制线程
## 10. API 与状态变更建议
### 10.1 设备能力状态
新增或扩展设备详情接口字段:
- `capabilities.gui`
- `capabilities.cli`
- `preferredExecutionMode`
### 10.2 项目并行策略
新增项目/文件夹级策略字段:
- `parallelConflictPolicy`
- `parallelConflictState`
并提供更新入口:
- `forbid`
- `allow_once`
- `allow_always`
`allow_once` 应在当前任务完成或取消后自动清空。
这些策略更新都只允许作用在当前冲突对象上:
- 同一 `deviceId + folderKey`
- 或退化到同一 `deviceId + projectId`
不得写成设备级或全局级默认行为。
### 10.3 冲突事件
建议在 SSE / APP 状态流里补一类事件:
- `project.parallel_conflict.detected`
- `project.parallel_conflict.cleared`
- `project.parallel_conflict.policy_updated`
## 11. 测试策略
### 11.1 服务端
覆盖这些场景:
1. 同设备 GUI + CLI 同时在线
2. CLI 正在执行,出现外部人工活动
3. 默认阻断
4. `允许本次` 只放行一次
5. `永久放行` 只对当前 folder/project 生效
6. 不同 folder 不受影响
7. `allow_once` 自动清空
### 11.2 Android / Web
覆盖这些场景:
1. 设备详情页能显示 GUI/CLI 双能力
2. 默认执行模式切换
3. 冲突卡三按钮行为
4. 永久放行状态展示
5. 撤销永久放行
## 12. 风险与边界
### 12.1 无法精确知道“是 GUI 还是手工 CLI”
本轮不做 OS 级窗口焦点和输入行为追踪,因此“人工活动”只能基于 Boss 可观察到的项目活动来判定。
这意味着:
- 有时只能判断为“外部人工/非 Boss 活动”
- 不能 100% 精确证明一定是 GUI
这在产品上是可以接受的,因为风险本质是:
- **同项目正在被外部人工推进**
### 12.2 worktree 级精度
如果未来要支持同项目多 worktree 并行,本模型还需再细化到:
- `deviceId + folderKey + worktreeRef`
本轮先按:
- `deviceId + folderKey`
收口。
## 13. 最终结论
本轮正式采用以下设计:
1. **GUI 和 CLI 是同一设备下的双能力,不拆成两个设备。**
2. **Mac / Windows 都按用户级 `.codex` 主状态库模型接入。**
3. **默认执行模式按设备级切换。**
4. **同项目 GUI/CLI 并行写入风险由规则层检测。**
5. **默认阻断,不自动继续。**
6. **用户必须在当前异常项目/文件夹级别做出选择:**
- `禁止`
- `允许本次`
- `永久放行`
7. **这三个动作都只对当前项目文件夹/线程生效,不做全局开关。**
这套方案既符合 Codex GUI/CLI 的真实关系,也能最大程度避免“主 Agent 与人工开发同时写同一项目”带来的实际风险。