feat: add conversation search and usage dashboard

This commit is contained in:
shiyue
2026-08-03 18:20:33 +08:00
parent cc600bdf31
commit 58d5f816c2
30 changed files with 6316 additions and 22 deletions

View File

@@ -0,0 +1,94 @@
# 高级会话检索发现与决策
## 用户边界
- 现有检索必须保留,不改输入行为和本地标题/项目/路径/ID 过滤。
- 在现有检索框旁增加高级检索按钮。
- 高级检索参照用户提供的暗色结果页,结合前一轮正文索引分析落地。
## 视觉论点
在不打扰现有侧栏检索的前提下,打开一层沉静、近乎无边框的检索工作台,用青蓝标题、暖黄命中标记和克制分隔线建立快速扫读节奏。
## 内容计划
1. 顶部:返回按钮、长查询输入、清空按钮和回车提示。
2. 控制:相关优先/最新优先,整词/包含两组切换。
3. 状态:结果数、耗时、索引构建/错误状态。
4. 结果:会话标题、项目/角色来源、最多两段摘要、右对齐时间和细分隔线。
5. 空态:未输入、无结果、索引构建中和查询失败。
## 交互论点
- 入口点击后使用 140ms 淡入和轻微上移,形成从侧栏到检索工作台的空间切换。
- 查询采用约 200ms debounce;旧响应由 requestId 丢弃,结果更新只做轻微透明度过渡。
- 点击摘要打开原会话,必要时补载历史页,定位后做一次短暂暖色高亮。
## 参考图量化
- 源图:733 × 673 RGBA PNG。
- 顶栏约 58px;左右内容安全区约 46–48px。
- 控制行位于顶栏下约 22px,采用低对比胶囊,不使用独立卡片。
- 状态行与第一条结果间距约 18px;结果之间使用 1px 低对比分隔线。
- 标题使用高饱和青蓝,正文接近中性白,命中使用暖黄底深色字,时间靠右且弱化。
- 面板是单一连续表面,不叠加卡片阴影;参考图中的圆角仅属于外围窗口,不复制成结果卡片。
## 参考区域映射
| 参考区域 | 目标 DOM | CSS 责任 | 资产 |
|---|---|---|---|
| 顶部搜索栏 | `.advanced-search-header` | 高度、输入基线、返回/清空按钮 | 无 |
| 排序/匹配切换 | `.advanced-search-toolbar` | 分段控件、选中态 | 无 |
| 结果统计 | `#advanced-search-status` | 弱化状态文案 | 无 |
| 结果列表 | `#advanced-search-results` | 连续流、分隔线、滚动 | 无 |
| 命中标题/摘要 | `.result-title/.result-snippet` | 青蓝标题、暖黄 mark、截断 | 无 |
| 侧栏入口 | `#advanced-search-open` | 紧邻现有输入、独立 tooltip | 无 |
## 资产台账
- 原始附件:`sessions/_attachments/237582ef-4157-4175-84fa-38629613df7f.png`
- 归档:`.trellis/tasks/08-03-advanced-conversation-search/references/source-assets/advanced-search-reference.png`
- SHA-256:`39e5b93d26deca64ea88a46b09bed7f7c47d2af733e8f2f857a9d35fc7895692`
- 用途:仅作为视觉对照,不进入产品运行时。
## 已确认技术基线
- 当前 `session_list` 只携带元数据,完整消息按会话加载。
- 当前可检索 user/assistant 正文约 4.26 MB,内存全量子串扫描约 0.98ms。
- 项目运行于 Node 18,发布使用 Bun baseline 单文件;首期采用零依赖内存索引和派生缓存。
## 代码接入基线
- `codebase-memory-mcp` 的 `home-cc-web` 索引 ready(4417 节点、9212 边)。
- 服务端模块统一使用 CommonJS 工厂函数,可新增 `lib/session-search-index.js` 并在 `server.js` 顶部 require。
- WebSocket 消息 switch 在 `load_session/load_history_page/delete_session/rename_session` 附近,新增 `search_sessions` 可保持普通会话列表协议不变。
- 前端 `handleServerMessage` 已集中处理 `session_info/session_history_chunk`,高级检索结果可新增独立 case;`openSession(sessionId, options)` 已支持 options,适合作为命中定位入口。
- `markSessionMessageElement` 已给消息 DOM 写入 `data-message-index`;历史分页响应包含 `historyBaseIndex`,可以稳定定位旧消息。
- `saveSession` 有大量调用者,索引更新必须按 sessionId debounce 并在成功写盘后触发,避免频繁同步重建。
## 跨层数据流
```text
sessions/*.json
→ SessionSearchIndex 规范化 user/assistant 文本
→ 内存文档集合 + sessions/_search/index-v1.json 派生缓存
→ search_sessions 请求验证
→ session_search_results 受限摘要
→ 高级检索结果流
→ openSession + load_session(targetMessageIndex)
→ data-message-index 定位与高亮
```
- 服务端入口负责 query、limit、sort、matchMode 校验;前端只发送枚举值并丢弃过期 requestId。
- 原始会话文件是唯一事实来源;缓存损坏只能降级/重建,不能反向覆盖会话。
- Trellis backend/frontend 细则当前仍为占位模板,本次以现有 CommonJS、集中消息 switch、原生 DOM/CSS 和回归脚本的实际约定为准。
## 并行审计结论
- 高级检索面板放在 `.chat-main` 内并使用局部 absolute overlay;桌面保留侧栏,移动端点击入口后关闭抽屉。不要复用全局 modal overlay。
- 现有 `sessionSearchQuery`、`syncSessionSearchUi`、`getSessionSearchText`、`sessionMatchesSearch`、`renderSessionList` 和原 input/Escape/clear 事件均保持原样;高级检索使用完全独立状态。
- 搜索缓存的文件签名使用 dev/ino/size/mtimeMs;每次启动对账 root `*.json` 集合,原子保存导致 inode 变化时自然失效,删除项被 prune。
- 初次构建和变化扫描分批让出事件循环;查询只访问内存文档,不在请求路径解析全部 JSON。
- 高级面板 z-index 位于聊天内容之上、全局 modal 之下;结果区自身滚动,避免落进 `.messages-wrap` 的 overflow 裁切。
- 精确定位必须返回 `sessionId + messageIndex`;前端在 `renderMessages/prependHistoryMessages` 后查找 `data-message-index`,服务端按 `targetMessageIndex` 增加首次加载的历史预取块。
- 修改 `style.css/app.js` 后同步推进 `index.html` cache-bust,并覆盖 dark/gilded/wasteland 与 768px 移动端。

View File

@@ -0,0 +1,26 @@
# 高级会话检索进展
- 2026-08-03:读取并启用 create-cc-web-theme、frontend-skill、planning-with-files、todo-list-csv。
- 2026-08-03:创建并启动 Trellis 任务 `08-03-advanced-conversation-search`。
- 2026-08-03:归档参考图,确认源图与归档 hash 一致。
- 2026-08-03:建立 10 步 TODO CSV 与对话计划,当前处于规格与基线阶段。
- 2026-08-03:首次派发后端审计子代理因 full-history 与 agent_type 参数冲突失败,已记录并改用无历史完整提示。
- 2026-08-03:确认 codebase-memory 索引 ready,并定位服务端模块、WebSocket、前端消息分发和历史定位主链路。
- 2026-08-03:读取 Trellis backend/frontend 与跨层指南;细则为空,已按实际代码模式记录数据流和边界责任。
- 2026-08-03:wait_agent 首次使用低于最小等待窗口,已记录并改用 10 秒。
- 2026-08-03:独立计划审查通过,无阻塞问题;已将协议上限、缓存校验和 messageIndex 定位补入主计划。
- 2026-08-03:后端/前端并行只读审计完成;汇总独立协议、文件签名缓存、局部 overlay、主题和命中定位边界。
- 2026-08-03:完成 TODO 第 1 步,进入索引模块实现。
- 2026-08-03:新增 `lib/session-search-index.js`,完成版本化 0600 派生缓存、文件指纹校验、分批构建、增量 upsert/remove、相关/最新与包含/整词检索。
- 2026-08-03:服务端接入 `search_sessions → session_search_results/session_search_error`,限制 query≤200、limit≤50、120ms 单连接频率,并保持 `session_list` 原协议不变。
- 2026-08-03:`saveSession`、重命名和删除链路已同步索引;查询前 flush pending upsert,避免 250ms debounce 窗口内读取旧索引。
- 2026-08-03:侧栏原检索 DOM 属性和 input/Escape/clear 事件保持不变,仅增加相邻 `#advanced-search-open`;高级工作台使用独立状态和 `.chat-main` 局部 overlay。
- 2026-08-03:完成安全 DOM 高亮、requestId 旧响应隔离、200ms 防抖、结果流、排序/匹配切换及 `sessionId + messageIndex` 定位。
- 2026-08-03:目标命中通过 `load_session.targetMessageIndex` 计算额外预取块,180 条消息夹具可补载到 `historyBaseIndex=0`。
- 2026-08-03:新增 `advanced-session-search` 专项回归,覆盖敏感内容排除、整词检索、协议隔离和旧历史定位;语法、diff、gilded、wasteland、全量回归通过。
- 2026-08-03:真实 Chromium 验收 1672×941、1440×900、390×844;三个视口横向溢出均为 0,结果区 `overflow-y:auto`,控制台错误为 0。
- 2026-08-03:视觉实测为深色连续表面、青蓝标题 `rgb(0,164,223)`、暖黄命中 `rgb(242,211,107)`;桌面侧栏保留,移动侧栏抽屉关闭后面板占满主画布。
- 2026-08-03:专项浏览器点击结果确认面板关闭并生成 `data-message-index="0"` 的目标高亮;临时实例使用 18082 端口,验收后已停止,未重启生产 ccweb。
- 2026-08-03:完成后尝试按项目约定刷新 codebase-memory 全量索引;`index_repository` 与后续 `index_status` 均返回 `Transport closed`,已降级为本地语法、专项/全量回归与 diff 核验,不影响运行时代码交付。
- 2026-08-03:根据用户截图复核 wasteland 侧栏几何,将搜索框的 8px 外距提升到行容器,并把高级按钮统一为 36×36;真实 Chromium bbox 为搜索框与按钮 `y=66 / h=36 / centerY=84`,中心差 0。
- 2026-08-03:对齐调整后 cache-bust 更新为 `20260803-advanced-search-align`;advanced-session-search、wasteland-theme 与全量 regression 再次通过。

View File

@@ -0,0 +1,62 @@
# 高级会话检索落地计划
## Goal
保留现有侧栏检索全部行为,在旁边新增高级检索入口,落地可检索用户/助手消息正文、展示命中摘要并定位原消息的独立检索工作台。
## Current Phase
Complete
## Phases
### Phase 1: 规格与基线
- [x] 归档参考图并记录哈希
- [x] 审计相关实现、测试与主题边界
- [x] 完成计划审查
- **Status:** complete
### Phase 2: 服务端检索能力
- [x] 实现零依赖内存文档索引和缓存
- [x] 缓存按 version + 文件 dev/ino/size/mtime 校验,缺失或损坏时后台分批重建
- [x] 接入会话生命周期
- [x] 接入 WebSocket 协议、限流和状态(query≤200、limit≤50、snippet≤2×220)
- **Status:** complete
### Phase 3: 高级检索前端
- [x] 保持现有检索代码不变并新增旁路按钮
- [x] 实现独立面板、结果流、排序和匹配模式
- [x] 结果携带 messageIndex;打开会话时按目标索引预取历史块并定位命中消息
- **Status:** complete
### Phase 4: 视觉与回归
- [x] 按参考图完成无卡片结果流、响应式和主题适配
- [x] 增加回归、性能和安全断言
- [x] 更新静态资源缓存版本
- **Status:** complete
### Phase 5: 验证与交付
- [x] 运行语法、专项/主题/全量回归与 diff 检查
- [x] 在真实 Chromium 完成参考、桌面和移动视口验收
- [x] 清理 TODO CSV 并完成 Trellis 记录
- **Status:** complete
## 关键约束
- `normalizeSessionSearchQuery/getSessionSearchText/sessionMatchesSearch` 及现有输入事件语义保持不变。
- 高级检索作为独立入口和独立状态机,不把消息正文塞入 `session_list`。
- 首期不引入第三方运行依赖,不改变现有会话 JSON schema。
- 搜索词不写日志;结果只返回受限摘要,不返回完整历史。
- 使用中文注释和文档;不覆盖用户已有改动。
## Errors Encountered
| Error | Attempt | Resolution |
|-------|---------|------------|
| 子代理使用 full-history fork 时同时指定 agent_type 被拒绝 | 1 | 改用 `fork_turns: none` 并在任务消息中提供完整只读上下文。 |
| wait_agent 使用 1000ms 被拒绝 | 1 | 工具最小等待为 10000ms,后续改用 10000ms。 |