# 任务计划:cc-web 使用统计看板 ## 目标 在不改变现有聊天、会话列表、会话检索和消息发送行为的前提下,为 cc-web 增加一个可独立启停、只读、可回滚的使用统计看板。 ## 当前阶段 已完成:功能、主题、回归、性能、浏览器与在线验收 ## 实施阶段 ### Phase 1:边界与统计口径确认 - [x] 明确当前可可靠统计的数据 - [x] 明确当前不可可靠统计的数据 - [x] 定义“不影响现有功能”的不可变边界 - **状态:** complete ### Phase 2:安全基线、只读统计核心与历史回填 - [x] 记录现有回归结果及消息发送、会话切换、检索的行为基线 - [x] 建立独立功能开关,`CC_WEB_USAGE_STATISTICS=0` 时不显示入口、不创建索引 - [x] 新增独立统计模块,读取保留期内的 `sessions/*.json` - [x] 第一次打开看板时懒加载回填,不把 83.3 MB 扫描放进服务启动或消息处理链路 - [x] 将聚合结果写入独立索引文件,不回写任何会话 JSON - [x] 索引就绪后通过防抖 save/delete 旁路钩子更新,钩子失败不进入主错误链路 - [x] 索引只保存统计事件、源文件指纹和会话元数据,可删除重建 - [x] 索引异常时返回看板错误,不阻塞聊天和会话持久化 - **状态:** complete ### Phase 3:独立查询协议 - [x] 新增只读 `usage_stats_query/result/error` 协议 - [x] 响应携带稳定的 `schemaVersion=1` - [x] 请求参数仅包含时间范围、时区和内部固定上限 - [x] 响应包含概览、趋势、MCP 明细、Skill 显式使用排行和会话明细 - [x] 不修改 `session_list`、`search_sessions`、`load_session` 等现有协议和负载结构 - [x] 增加排行/明细上限、频率限制和异常隔离 - **状态:** complete ### Phase 4:独立看板工作区 - [x] 在侧栏固定 footer 增加独立“统计”入口 - [x] 看板使用自己的前端状态、DOM 根节点和样式命名空间 - [x] 顶部提供本周、本月、自定义时间和刷新 - [x] 展示可靠指标,不展示无法准确解释的“活跃会话” - [x] MCP 支持明细窗口,会话行可返回对应会话 - [x] 关闭看板后恢复原聊天滚动、焦点和输入选区 - **状态:** complete ### Phase 5:全部现有主题适配 - [x] 枚举 `THEME_OPTIONS` 中全部 11 个现有主题 - [x] 适配侧栏底部入口、概览、趋势、表格、空态、错误态和加载态 - [x] 主题差异只通过语义变量和主题限定选择器实现,没有复制业务 DOM 或 JS - [x] 11 主题 × 5 视口完成真实浏览器几何验收 - [x] 检查 `prefers-reduced-motion`、文字对比度、日期图标和焦点可见性 - **状态:** complete ### Phase 6:兼容性、性能与故障回归 - [x] 执行现有全量回归并记录结果 - [x] 增加统计协议、时间边界、失败状态、空数据、限额和隐私测试 - [x] 增加入口隔离、刷新、错误态和 reduced-motion 前端合同 - [x] 验证统计查询后会话加载、会话搜索及 `session_list` 均不受影响 - [x] 验证索引缓存复用、增量、删除、空文件和损坏文件隔离 - [x] 对当前 83.3 MB 会话数据完成性能验收 - **状态:** complete ### Phase 7:灰度启用与回滚 - [x] 使用功能开关控制统计入口和统计查询服务 - [x] 当前环境已重启启用,用户已确认在线效果 - [x] 记录 CPU、内存、回填、查询耗时和索引比例 - [x] 回滚时可设 `CC_WEB_USAGE_STATISTICS=0`,不涉及会话数据迁移 - **状态:** complete ## 统计口径 | 指标 | 定义 | 时间归属 | 可靠性 | |---|---|---|---| | 新建会话 | `created` 落在时间范围内的会话数量,兼容 `createdAt` 历史兜底 | 会话创建时间 | 保留会话范围内高 | | 发送消息 | 时间范围内当前仍被保留的用户消息数量 | 用户消息时间 | 保留数据范围内高 | | 自动协作消息 | 非人工触发、由协作链路产生的消息数量 | 对应消息时间 | 先验证字段;无法稳定分类则首版不展示 | | MCP 调用 | assistant message 中 `toolCalls` 的 MCP 调用条目数量 | 暂按所属 assistant 消息时间 | 中 | | MCP 失败 | MCP 调用中 `status=failed` 的条目数量 | 暂按所属 assistant 消息时间 | 中 | | Skill 显式使用 | 用户消息 `composerMentions` 中显式 `$skill` mention 数量 | 用户消息时间 | 保留数据范围内高 | ## 当前版本明确不做 - 不统计 Skill 文件被模型实际读取或执行的次数。 - 不将“活跃会话”作为指标。 - 不修改历史或未来的会话 JSON schema。 - 不把统计字段塞入 `session_list` 或会话列表负载。 - 不为统计而改造现有消息发送、会话检索或 MCP 执行链路。 - 不承诺历史 MCP 的精确调用时刻和耗时。 - 不在页面每次刷新时全量扫描所有会话 JSON。 ## 核心架构决策 | 决策 | 理由 | |---|---| | 采用“历史回填 + 异步增量索引 + 独立查询” | 当前全量扫描可用但长期不适合每次看板请求执行 | | 首版使用可重建的旁路索引,不引入数据库依赖 | 降低发布和 CentOS 单文件打包风险;当前数据规模足够使用 | | 索引与会话源数据完全分离 | 索引可以删除重建,不给现有会话数据带来迁移风险 | | 新增独立 WebSocket 消息类型 | 避免改变现有会话列表、搜索和加载协议 | | 看板作为独立工作区 | 页面结构可复用现有外壳,同时隔离聊天状态和交互 | | 提供可立即关闭的功能开关 | 用户确认落地后默认展示入口;出现问题时可只关闭看板,不回滚会话功能 | | MCP 历史数据暂按 assistant 消息时间聚合 | 当前工具调用记录本身没有时间戳,必须在界面说明口径 | ## 看板界面基线 - **视觉主张:** 延续 cc-web 现有应用外壳,形成安静、紧凑、可快速扫描的运营工作区;不单独设计营销主题。 - **内容结构:** 时间与刷新控制 → 核心数字 → 趋势和 MCP 明细 → 状态与 Skill 排行 → 最近会话。 - **交互主张:** 切换看板时保留聊天现场;筛选刷新只更新看板区域;明细查看在看板内部完成,返回后保留筛选条件。 - **组件原则:** 只有可交互或需要独立语义的区域使用卡片,其余优先使用分栏、分隔线、图表和紧凑表格,避免卡片拼贴。 - **入口位置:** 固定在侧栏底部操作区,处于会话列表下方,与截图中的 `CC-Web` 设置入口同一区域;不插入会话列表滚动内容。 ## 不影响现有功能的硬性验收门槛 1. 关闭功能开关时,前端 DOM、交互和服务端行为与改动前一致。 2. 统计模块异常、索引缺失或查询超时,消息发送和会话操作仍正常。 3. `session_list`、`search_sessions`、`load_session` 的请求和响应合同不变。 4. 不修改现有会话文件内容;统计索引可随时删除并从源数据重建。 5. 全量现有回归通过,新增统计回归通过后才允许灰度开启。 6. 不在正常消息处理的同步关键路径中执行全量扫描或重聚合。 7. 看板必须显示“基于当前保留数据”和最后更新时间,不能把保留期数据表述为永久审计数据。 8. `THEME_OPTIONS` 中全部现有主题都必须完成桌面和窄屏验收;侧栏入口位置一致,看板内容可读,且聊天恢复、会话切换、搜索、消息发送和 MCP 功能不受影响。 ## 发布门禁建议 - 基线:先记录当前回归结果和典型聊天操作耗时。 - 开发态:仅显式开启功能开关后显示入口。 - 灰度态:限制单用户或指定环境开启,观察至少一个完整统计周期。 - 正式态:只有错误率、CPU、内存和 P95 查询耗时满足阈值才默认开启。 - 回滚:关闭功能开关;保留独立索引无害,必要时可后续清理。 ## 首版性能阈值 - 当前约 82 MB 会话数据的专项回填目标不超过 3 秒。 - 索引就绪后的本周/本月查询 P95 目标不超过 100 ms。 - 专项回填进程峰值 RSS 目标不超过 160 MB。 - 旁路索引文件目标不超过源会话 JSON 总量的 35%。 ## 错误记录 | 错误 | 尝试 | 处理 | |---|---:|---| | 无 | 1 | — | | `task.py list-context ... implement` 参数不被当前脚本接受 | 1 | `task.py validate` 已确认 context JSONL 合法;后续直接读取任务上下文文件,不重复该命令 |