feat: add user input history MCP and rebuild release

This commit is contained in:
shiyue
2026-08-18 09:10:25 +08:00
parent 6ed8c7d30b
commit 389690af64
11 changed files with 957 additions and 0 deletions

View File

@@ -0,0 +1,79 @@
# Task Plan: 新增用户输入历史 MCP
## Goal
为 cc-web 增加一个只读 MCP,可读取指定对话(默认当前来源对话)最近的用户输入,纳入引导表单提交内容,并把所有返回正文控制在合计 1000 个 Unicode 字符以内,供 LLM 作为验收参考。
## Current Phase
Phase 3
## Phases
### Phase 1: 代码发现与契约确认
- [x] 梳理会话消息存储与 ccweb MCP 注册链路
- [x] 明确用户输入筛选、默认会话与截断规则
- 必须确认普通用户输入与引导表单提交的持久化形态。
- 必须确认来源会话缺失、指定会话不存在时的错误语义。
- **Status:** complete
### Phase 2: 测试与实现
- [x] 编写新 MCP 的失败回归测试
- 覆盖默认当前对话、显式指定对话、默认最近 15 条、仅返回 user 内容。
- 覆盖引导表单提交消息、合计 1000 字预算、截断标记及缺失来源会话。
- [x] 实现指定/当前会话的用户输入读取与限制逻辑
- [x] 注册 MCP schema、描述与运行时上下文
- **Status:** complete
### Phase 3: 验证与交付
- [x] 运行针对性测试并修复发现的问题
- [x] 执行相关回归、核验接口并整理交付
- **Status:** complete
## Key Questions
1. 普通用户输入和引导表单提交在持久层中如何标记、是否都使用 `role=user`?(已确认:提交后经普通 `handleMessage` 持久化为 `role=user`;待提交卡是 `role=assistant`)
2. 当前来源对话 ID 从哪个线程级运行时上下文解析?(已确认:JSON-RPC/内部 HTTP 上下文把 `sourceSessionId` 传给 `callInternalMcpTool`)
3. MCP 工具注册、参数校验和权限边界由哪些模块负责?(已确认:`lib/ccweb-mcp-server.js` 的 `TOOLS`/`isCallableToolName` 与 `server.js` 的内部 MCP 分派)
## Decisions Made
| Decision | Rationale |
|----------|-----------|
| 默认返回最近 15 条,最终按时间从旧到新排列 | 兼顾最近性与作为验收标准时的可读性 |
| 所有返回正文合计默认且硬性最多 1000 个 Unicode 字符 | 避免 15 条输入最坏膨胀到约 15000 字,保证验收上下文可控 |
| 从最新输入向前消耗字数预算,最终按旧到新输出 | 优先保留最新验收要求,同时维持自然阅读顺序 |
| 预算导致内容或更早消息未完整返回时给出截断/更多标记 | 避免 LLM 将不完整历史误认为完整要求 |
| 仅返回用户输入,不混入 assistant/tool/system 内容 | 保持用户原始验收意图纯净 |
## MCP Contract
- 工具名为 `ccweb_list_user_inputs`。
- 入参:
- `conversationId?: string`:缺省时使用 MCP 来源会话 ID。
- `limit?: integer`:默认 15,允许 1–50。
- `maxChars?: integer`:默认 1000,允许 1–1000;约束所有 `items[].content` 的字符总和。
- 返回:
- `conversationId`、`requestedLimit`、`maxChars`、`totalChars`、`returnedCount`、`hasMore`。
- `items[]` 至少含 `content`、`createdAt`、`truncated`;若持久层有稳定消息 ID,则同时返回 `messageId`。
- 排序与预算:先选最近 `limit` 条用户输入,再从最新向前填充 `maxChars` 预算,最终将已选内容按旧到新返回。
- 默认当前会话但运行时没有来源会话 ID 时返回明确参数错误;显式指定不存在的会话时返回 not-found 错误。
## Errors Encountered
| Error | Attempt | Resolution |
|-------|---------|------------|
| 计划审查指出 1000 字是逐条还是合计存在歧义 | 1 | 收紧为所有返回正文合计硬上限 1000 字,并固化预算顺序 |
| codebase-memory 单次查询误报项目未索引 | 1 | 立即用 list_projects/index_status 复核,项目实际为 ready;后续收敛查询重试,不触发无谓重建 |
| codebase-memory 重试返回 Transport closed | 2 | 停止重复 MCP 调用,降级到本地 rg/sed 精确核验小函数 |
| 初版失败测试覆盖 HOME 且误排除提交表单标题 | 1 | 已退回测试代理修正环境隔离与角色/ID 断言后再验红灯 |
| 主线程生产补丁因代理并发落盘而校验失败 | 1 | apply_patch 安全拒绝覆盖;检查 git diff 后确认代理已完成目标改动,直接进入验证 |
## Notes
- 计划与根目录 CSV、`update_plan` 保持一一同步。
- 研究发现写入 `findings.md`,测试结果写入 `progress.md`。
- 当前运行进程尚未重载:发现另一个非当前对话仍为 running,按项目约定暂缓 `pm2 restart ccweb --update-env`。