Files
cc-web/.planning/title-history-locator/task_plan.md

6.2 KiB
Raw Blame History

标题历史定位时间线

目标

当 LLM 通过 ccweb_set_title 修改会话标题时,持久化标题变更事件,并在“定位”列表中按对话顺序显示不可点击的标题分隔项;同时按消息时间插入精确到天的日期分隔项,让用户看出主题在哪一步变化以及对话发生在哪一天。

阶段

阶段 状态 验收标准
1. 建立计划并确认需求边界 complete 计划、发现、进度和 TODO CSV 已建立,且不覆盖现有任务文件
2. 定位标题 MCP、消息存储与定位弹层链路 complete 找到精确入口、数据流、现有测试和兼容边界
3. 补充标题历史及日期定位展示回归 complete 新断言覆盖持久化、接口返回、只读展示、历史兼容及浏览器本地 23:59/00:01 跨天边界
4. 实现标题变更事件持久化与读取 complete 成功改名时写入事件,忽略/失败不写,旧数据可读取
5. 实现定位列表标题与日期时间线展示 complete 标题项按步骤排序;日期按天去重并呈现横线中置日期气泡;两类节点均不可点击
6. 运行专项与全量验证 complete 语法、专项回归、全量回归和 diff 检查通过
7. 审查改动并清理临时跟踪文件 complete 代码审查通过,TODO CSV 删除,计划与进度收口

关键约束

  • 只记录由标题 MCP 实际生效的变更;用户手动锁定导致的 ignored 不产生伪历史。
  • 标题历史是时间线元数据,不伪装成普通对话消息,不参与消息定位选中。
  • 日期节点只显示 YYYY-MM-DD,按浏览器当前用户本地时区分组,与现有消息时间的前端展示语义一致,不显示时分秒。
  • 日期节点采用两侧横线、中间日期气泡的分隔样式;本地时间从 23:59 跨到 00:01 时必须产生新日期节点。
  • 兼容已有会话数据;历史中没有标题事件时维持当前行为。
  • 不覆盖工作区内与本任务无关的未提交文件和规划状态。
  • 测试命令最长 60 秒;未确认无其他 running 会话前不重启服务。

错误记录

错误 尝试 处理
标题历史专项回归因缺少 normalizeTitleHistory 失败 1 失败符合 TDD 预期,进入最小后端实现
后端实现后专项回归因缺少前端 normalizeOutlineTitleHistory 失败 1 后端纯函数契约已通过,进入前端实现
ccweb_list_conversations(status=running) 60 秒超时 1 降级检查 PM2、端口、近期会话文件;发现另一条 15:38 收到用户消息的 Codex App 会话,按约束暂缓重启
codebase-memory-mcp detect_changes 返回 transport closed 1 不重复同一失败,使用已完成的函数级检索、全量回归与本地 diff 审查收口
首轮标题前置计划审查要求细化锚点与传输契约 1 补充字段名、索引基准、合法范围、优先级、降级规则,以及实时/重载/缓存回归要求后重新审查
标题前置专项回归在后端锚点保留断言失败 1 符合 TDD 预期,确认现有 normalizeTitleHistory() 会丢弃新字段,进入最小后端实现
后端实现后专项回归在标题前置顺序断言失败 1 后端锚点契约已通过,失败符合预期,进入前端锚点排序实现
最终 codebase-memory-mcp detect_changes 返回 transport closed 1 不重复失败调用,改用函数级 diff、专项回归、全量回归与 git diff --check 完成影响面审查
首次全量回归调用未保留最终退出码 1 确认残留测试进程已结束后,改用可追踪 session id 重新运行并取得 exit 0 与通过标记

追加迭代:标题前置锚点(2026-07-29)

阶段 状态 验收标准
1. 梳理现有标题事件与消息索引契约 complete 明确现有标题为何排在触发消息之后,并确定不破坏历史数据的锚点字段
2. 补充标题前置及旧历史兼容回归 complete 新标题事件和无锚点旧事件均断言为“日期 → 标题 → 用户消息”
3. 持久化标题事件的触发消息锚点 complete LLM 实际改名事件记录 anchorMessageIndex;实时事件、会话重载、前端归一化与 snapshot 缓存均保留该字段,非法数据被清洗
4. 按锚点重排定位列表展示顺序 complete 标题显示在所属用户消息之前,不可点击且不占消息编号;锚点缺失或不可见时按既定回退规则处理
5. 运行语法检查与专项回归 complete server/app/regression 语法检查及标题时间线专项回归通过
6. 运行全量回归并审查最终差异 complete 全量回归、diff check 和影响面审查通过,临时 TODO CSV 已清理

追加约束

  • messageIndex 继续表示标题事件实际发生时的消息位置,不复用或改写其历史语义。
  • 新增可选字段 anchorMessageIndex:零基整数,指向改标题时 session.messages 中最近一条 role === 'user' 的消息;合法值必须 >= 0 且 < messageIndex,否则归一化时丢弃该字段但保留合法标题事件。
  • anchorMessageIndex 与 messageIndex 同时存在时,展示归属优先使用锚点;精确锚点消息未出现在当前定位消息集时,回退到 messageIndex 之前最近的可见用户消息;仍无候选时保留事件自身的时间位置。
  • 旧历史没有 anchorMessageIndex 时,从定位列表中选择 messageIndex 之前最近的用户消息作为兼容锚点,不改写磁盘历史。
  • 标题归属到触发消息后,日期也采用该用户消息的本地日期,保证固定顺序为“日期 → 标题 → 用户消息”。
  • 锚点字段必须贯穿 MCP 返回和持久化、实时 session_renamed.titleEvent、重新加载的 session_info.titleHistory、前端 normalizeOutlineTitleHistory() 与 session snapshot 缓存;实时打开定位列表和重新进入会话都应得到相同顺序。
  • 回归至少覆盖:新事件即时归属、重新加载后锚点仍存在、旧事件无锚点回退、跨午夜仍按锚点消息日期分组。
  • 不修改 .planning/.active_plan 指向的其他在途任务,不触碰其 TODO CSV。