# 标题历史定位时间线:发现记录 ## 用户意图 - “定位”弹层当前只列可跳转的消息步骤。 - 左侧会话标题由 LLM 通过标题 MCP 修改;每次实际修改都要保留历史。 - 定位弹层需要插入标题变更节点,用于标识主题变化发生的位置。 - 标题节点只读、不能选中或触发滚动定位,但需要在视觉上明显区别于消息项。 - 定位弹层还要按消息时间显示日期分隔节点,参考横线中间承载日期的气泡样式。 - 日期仅显示到天(`YYYY-MM-DD`),不显示截图示例中的时分秒;日期节点同样不可点击、不编号。 - 计划审查确认日期时区必须明确:采用浏览器当前用户本地时区,与消息时间的前端展示语义保持一致。 - 日期视觉明确为两侧横线、中间承载 `YYYY-MM-DD` 的气泡;测试覆盖本地 23:59/00:01 边界。 ## 工作区与流程约束 - 当前 Trellis 指向另一个仍在进行的主题任务,不能擅自切换或覆盖。 - 根目录已有旧的 `task_plan.md`、`findings.md`、`progress.md`,因此本任务使用 `.planning/title-history-locator/` 隔离。 - 根目录已有他人未跟踪的 `修复会话切换表单不渲染 TO DO list.csv`,必须保留。 - 项目约定:代码理解先用 `codebase-memory-mcp`,`rg/sed` 仅做行号与文本校验;禁止使用 graphify。 - `codebase-memory-mcp` 的 `home-cc-web` 索引状态为 `ready`(4093 nodes / 8699 edges)。 - Trellis 前后端规范入口及相关组件/数据库规范仍是占位模板,没有额外的项目专属实现约束。 ## 待确认的技术事实 - `ccweb_set_title` 的后端实现、标题锁定与会话持久化结构。 - “定位”按钮和弹层的前端构建函数、消息序号、消息时间和点击逻辑。 - 会话详情接口是否已有适合承载时间线元数据的字段。 - 现有回归脚本中标题 MCP 与定位列表相关 target。 ## 已定位的实现链路 ### 标题 MCP - 入口是 `server.js` 的 `callInternalMcpTool()`,`ccweb_set_title` 路由到 `setCurrentConversationTitle()`。 - `setCurrentConversationTitle()` 会加载会话、拒绝空标题、尊重 `titleSource === 'manual'` 锁定,并在实际处理后保存 `session.title/titleSource`、发送 `session_renamed`、广播列表。 - 当前成功路径即使标题未变化也会保存并广播;历史事件必须只在 `changed === true` 时追加,避免重复标题伪事件。 - 手动 UI 改名走 `handleRenameSession()`,写入 `titleSource = 'manual'`;本需求只要求记录 LLM 调用实际生效的标题,因此不把手动改名写入该事件历史。 - 现有集成回归已经覆盖 MCP 成功、空标题、手动锁定和 `updated` 排序时间不变,适合直接扩展标题历史断言。 ### 定位弹层 - `public/app.js` 的 `buildUserOutlineItems()` 当前从已渲染的 `.msg.user[data-message-id]` DOM 构建纯用户消息数组,通过 `userMessageIndex` 取完整内容。 - `updateUserOutlinePanel()` 当前把所有项渲染成可点击 `