Skip to content

fix(tui): 跨 run 陈旧 todo 清单不再复活显示——「◇ 任务 (5/5) 不更新」的根因与修复 - #43

Open
yq04 wants to merge 1 commit into
huiliyi37:mainfrom
yq04:fix/todo-stale-panel
Open

fix(tui): 跨 run 陈旧 todo 清单不再复活显示——「◇ 任务 (5/5) 不更新」的根因与修复#43
yq04 wants to merge 1 commit into
huiliyi37:mainfrom
yq04:fix/todo-stale-panel

Conversation

@yq04

@yq04 yq04 commented Aug 16, 2026

Copy link
Copy Markdown

问题

「◇ 任务 (5/5) 有时候不会更新」。

根因分析(先排除同步问题)

同步链路本身健全,逐项核验:

环节 机制 状态
todo/plan_task 工具结果 handleToolResult 即时 refreshTodos + flushNow
长 run 兜底 120ms ticker 每 tick refreshTodos(agent 活跃期间)
回合结束 isFinal 前兜底 refreshTodos,收尾 commit 触发渲染
渲染数据源 任务面板(主区/侧栏)与 GlanceBar 徽章每帧直读 state.todos,无缓存

「输出太快导致丢同步」不成立(事件驱动 + 轮询双保险,渲染合并不丢终态)。

真正的机制是跨 run 陈旧显示shouldShowTaskPanel 的隐藏条件只看 phase === 'idle'——上一轮全部完成的清单在 run 结束后被隐藏,但新 run 一开始 phase 抬离 idle,旧清单(如 5/5)重新挂载,直到 AI 首次写入新 todo 才变化。用户看到新任务已开工、计数却停在上一轮终态,观感即「不更新」。

方案

todosWrittenThisRun 生命周期标志:

  • 重置:用户提交的四处 run 启动点(handleInputSubmit / notifyRunSettled 补发 / submitText / slash 透传)。守护中断(watchdog/convergence)的自动续跑不重置——续跑是同一任务的延续,旧清单继续显示是正确语义
  • 置位updateTodos 以清单签名(id:status:content 拼接)区分「AI 真写入」与 ticker 同值轮询拉取,签名变化才置位
  • Gate:全完成清单 + 本 run 未写 → 任务面板(主区 + 侧栏)与 GlanceBar 徽章均不显示。三个不受影响的情形:
    • 部分完成清单跨 run 仍显示(AI 大概率续写)
    • 本 run 内推进到全完成仍显示(完成态是本 run 的有效信息)
    • todoExpanded(ctrl+x t)强制回看不变

测试

新增 todo-stale.test.ts 5 条契约(含防空洞断言与对照帧设计,规避 LiveEngine「无变化短路」的空帧假绿):

  1. 新 run 未写 todo 前:陈旧面板 + 徽章隐藏(干净基线 RED,复现问题)
  2. 本 run 写入新 todo 后:新清单正常显示
  3. 本 run 内推进到全完成:仍显示
  4. idle + 全完成隐藏(原有行为防回归,含 streaming 对照帧)
  5. 部分完成清单跨 run 仍显示

验证:干净基线 1 RED / 修复后 5 GREEN;引擎域 521 测试 519 通过(1 失败为预存在的 approval-key.test.ts Windows 路径问题,上游基线同样失败);既有 todo-panel.test.ts 4 条契约无回归;改动域 typecheck 零错误。

问题定位(同步链路本身健全:todo/plan_task 工具结果即时刷新 + 120ms
ticker 兜底 + 每帧直读 state.todos,「输出太快丢同步」不成立):
上一轮全部完成的清单在新 run 期间(phase≠idle)原样复活——
shouldShowTaskPanel 的隐藏条件只看 phase==='idle',新 run 一开始
phase 抬离 idle,旧 5/5 重新挂载,直到 AI 首次 todo write 才变化。
用户看到新任务已开工、计数停在上一轮终态,观感即「不更新」。

修复(todosWrittenThisRun 生命周期标志):
- 用户提交的四处 run 启动点重置(handleInputSubmit / notifyRunSettled
  补发 / submitText / slash 透传);守护中断自动续跑不重置(同一任务
  的延续,旧清单继续显示是正确语义)
- updateTodos 以清单签名(id:status:content)区分「真写入」与 ticker
  同值轮询拉取,签名变化才置位
- 全完成清单 + 本 run 未写 → 任务面板(主区+侧栏)与 GlanceBar 徽章
  均不显示;部分完成清单不受影响(AI 大概率续写);todoExpanded 强制
  回看不变;本 run 内推进到全完成仍显示(完成态是本 run 有效信息)

新增 todo-stale.test.ts 5 条契约(含防空洞断言与对照帧),
干净基线 1 RED / 修复后 5 GREEN;todo-panel 既有 4 条契约无回归。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant