只运行一个 Claude Code 或 Codex 会话时,状态显示并不难。多个会话同时工作后,问题变成了:一个线程正在等用户回答,另一个已经停滞,第三个还在正常运行,状态栏到底应该显示什么?
如果永远选择最后修改的 transcript,普通进度写入就可能盖住更早但真正需要处理的交接。正确做法分两步:先独立判断每个会话,再按用户行动的紧急程度排序。修改时间只负责打破同优先级并列。
为什么不能只选最新会话
时间只能说明谁最后写入,不能说明谁更重要。后台 worker 可能在另一个线程停在权限问题之后继续输出普通进度;一个已经确认过的 needs-you 状态也可能在有效期内停留,挡住刚刚恢复工作的兄弟会话。
因此,纯时间排序会制造三类错误:运行中会话盖住未回答问题;已确认交接让图标保持静止;普通 idle 写入盖住需要排查的 stalled 状态。
把优先级写成明确规则
Agent Island v1.7.1 的 macOS 与 Windows 活动监控使用相同顺序:
未确认的 needs-you = 4
stalled = 3
working = 2
已确认的 needs-you = 1
idle / auth / rate = 0未回答的交接排第一,因为下一步行动属于用户。停滞排在运行中之前,避免异常被正常活动淹没。已经确认的交接降到 working 之后,因为它仍是线程历史,却不该继续固定 provider 图标。
这里的 0 是这个聚合选择器的基础优先级,不是通用故障严重度。身份验证和限流的详细错误展示由别的状态表面处理。
时间只处理同级并列
分配优先级后,再按优先级降序和修改时间降序排序。两个状态语义相同时才选择更新的会话。这样既有确定结果,也不会让时间戳重新定义状态含义。
会话集合
-> 按 provider 过滤
-> 计算状态优先级
-> 优先级降序
-> 修改时间降序
-> 选择第一项
显示聚合和提醒队列要分开
一个图标只需要一个代表状态,提醒队列却必须保留所有未完成交接。Agent Island 会选择一个 best session 用于显示,同时单独收集每个 needs-you 线程。
因此,确认一个线程不会取消另一个线程的提醒。提醒身份包含 provider、session 和 turn。状态栏虽然聚合成一个结果,底层义务仍然按线程独立存在。
测试矩阵
- 旧的未回答 needs-you 与新的 working 同时存在时,显示 needs-you。
- 旧的 stalled 与新的 working 同时存在时,显示 stalled。
- 已确认 needs-you 与 working 同时存在时,显示 working。
- 两个 working 会话并列时,选择修改时间更新的一项。
- 两个未回答交接并列时,显示更新的一项,但保留两条提醒。
- 确认其中一个交接后,另一个仍可提醒。
- provider 没有任何会话时,返回 idle 且不选择线程。
边界
聚合状态只是显示决策,不代表其它会话消失。每个线程的原始状态必须继续用于深链、提醒和诊断,不能被聚合结果覆盖。
本文描述的优先级可以在 v1.7.1 的 macOS 与 Windows 源码中核验。更一般的原则是:按可行动性聚合,保留每个 worker 的身份,只用时间解决同级并列。
