7.2 KiB
7.2 KiB
发现与决策:ccweb_list_conversations children scope
需求
- 给
ccweb_list_conversations增加scope: "children"。 - 同步更新该 MCP 的提示词/描述。
- 完成实现、回归覆盖和验证。
已知代码事实
listConversationSummaries(args, sourceSessionId)当前遍历SESSIONS_DIR下全部 JSON,只按 agent/status 过滤,最后排序并应用 limit。- MCP 创建的子会话在自身 JSON 中持久化
createdFrom.kind = "mcp"和createdFrom.sourceSessionId。 loadSessionMetaFromFile当前只暴露createdFromKind,没有暴露来源会话 ID;实现 children 过滤需扩展元数据或读取完整会话。ccweb_list_conversations有两处 schema/描述:lib/ccweb-mcp-server.js与server.js的 Codex App 动态工具兼容定义。- README 的 MCP 表格需要同步新语义。
- 当前工作树已有其他任务修改
server.js、lib/ccweb-mcp-server.js、scripts/regression.js,补丁必须基于当前内容最小追加。 - 本地
git diff -G未发现既有未提交改动触碰ccweb_list_conversations、listConversationSummaries、loadSessionMetaFromFile或createdFromKind相关行;目标区域可做局部补丁。 - 当前回归先在
scripts/regression.js约 6021 行测试全量列表,MCP 创建及createdFrom断言位于约 6139 行后,适合在创建完成后追加 children scope 场景。 createdFrom已包含在大文件头尾 preview 的顶层字段集合中,因此只需从现有对象提取sourceSessionId,无需为 children scope 全量读取大 JSON。loadSessionMetaFromFile的完整解析和 preview 两条分支都应新增内部字段createdFromSourceSessionId;该字段只用于过滤,不必暴露到 MCP 返回摘要。- children 过滤应紧跟 meta 读取执行,早于运行态、等待状态计算,以减少无关会话开销。
- stdio MCP 与 Codex App 兼容工具的现有描述文字不同;两者都需明确“默认全部、children 为当前来源直接 MCP 子对话”,并添加同一 enum schema。
- 两处 schema 均设置
additionalProperties: false,新增scope后不会影响既有 agent/status/limit 参数。 - 回归中可在首个
mcpCreate完成并验证createdFrom后调用列表:此时当前来源只有一个直接 MCP 子会话,适合断言精确集合。 - 省略 scope 与显式 all 的兼容性可比较同参数调用返回的会话 ID 数组;children 应包含新建子会话且排除来源会话。
- README 当前仅有一行轻量元数据描述,可直接补充
scope=children的行为与默认 all。 - 现有回归没有 branch 会话夹具;为验证
kind === 'mcp'条件,需要在回归中创建一个来自同一来源的 branch,或构造等价持久会话夹具。 - 项目只有
npm run regression这一完整回归入口;失败测试与最终验证均需用timeout 60s包裹。 handleNewSession创建 branch 后会把测试 WebSocket 切换到新会话;为避免干扰后续事件断言,children scope 回归应直接在临时 sessions 目录写入最小 branch/孙级夹具。buildSessionInfoPayload虽会返回createdFromKind,但 children MCP 过滤不应依赖当前 WebSocket 查看状态。- 会话元数据完整解析阈值默认 512 KiB、preview 头尾各 128 KiB;已有
session-preview-metadata定向回归以更小阈值强制走 preview 分支。 - 该定向回归已覆盖 preview 中的
createdFrom.kind,可扩展来源 ID 或通过内部 MCP 验证 children 过滤,避免只测试小文件路径。 runSessionPreviewMetadataRegression已配置独立内部 MCP token,可将 tail 夹具改为kind: mcp + sourceSessionId,随后调用ccweb_list_conversations(scope=children)精确断言;这是最小且快速的失败回归入口。- preview 定向回归无需真实父会话文件:列表过滤只使用自动传入的来源 ID 与子会话持久元数据比对。
- 主回归已直接导入
lib/ccweb-mcp-server.js的TOOLS,可对 stdio/shared MCP 的 scope enum 与描述做结构化断言。 - Codex App 当前主路径走线程级 MCP;
codexAppCommunicationDynamicTools是兼容定义,仍需同步文字与 schema,可用已有 server 源码审计断言或行为回归覆盖。 - 回归已有
assertCcwebDisplayImageContract这类静态契约函数和 target 分派模式;可新增列表 scope 契约函数,并在session-preview-metadata定向目标及完整回归中复用。 - 完整回归后续没有对全局会话数量做精确断言,仅按 ID 查找;增加 branch 与孙级临时会话夹具不会破坏后续场景。
- 新增测试语法检查通过;实现前定向回归稳定失败在 stdio/shared MCP 缺少 scope enum,证明失败测试有效。
- 实现后
server.js、lib/ccweb-mcp-server.js、scripts/regression.js语法检查全部通过,preview 定向回归通过。 - 服务端将任何非
children值归一为all;children 在运行态/等待态计算、排序和 limit 前完成过滤。 - 最终语法检查、session-preview-metadata 定向回归、完整
npm run regression与git diff --check全部通过。 - 最终局部差异确认核心改动仅落在会话元数据、列表过滤、两处 MCP 契约、README 与回归断言;工作树中的任务看板等大段 diff 为既有改动,未被覆盖。
- 差异审查发现 preview 测试不应把原有
ccweb_prompt_user夹具改写为mcp;将改为新增独立大文件 MCP 子会话夹具,以保留旧覆盖。 - 已完成上述修正,定向回归、完整回归和 diff check 再次通过;没有剩余代码风险或阻塞。
- 无需重启服务即可完成代码交付;本轮未执行服务重启。
- 最终文件行号已核验,临时 CSV 已不存在,
git diff --check仍通过。 - 重启前运行态检查发现除当前对话外还有 2 个 running 对话;按项目运维规则暂缓
pm2 restart ccweb --update-env。
技术决策
| 决策 | 理由 |
|---|---|
| 支持 `scope: "all" | "children"` |
children 匹配 createdFrom.kind === "mcp" && createdFrom.sourceSessionId === sourceSessionId |
精确表达直接持久子对话,不混入分支对话 |
| 非法 scope 回退 all | 正常 MCP 由 enum 约束,服务内部调用仍保持兼容与可预测 |
| 不依赖 LLM 上下文或 pending reply 状态 | 子会话持久元数据才是可重启恢复的权威来源 |
| 暂不新增返回字段 | 用户只要求过滤能力,遵循 YAGNI;现有摘要字段足以继续投递消息 |
风险
- 大会话文件可能走 preview 解析路径,需要确保 preview 元数据能读取
createdFrom.sourceSessionId。 - limit 必须在 children 过滤后应用。
- 回归测试已有大量并行任务新增内容,插入断言时避免更改无关逻辑。
- 需分别断言省略 scope、scope=all、scope=children 和非法 scope。
- 本轮
codebase-memory-mcptransport 已关闭;按降级策略使用本地检索,不再重复失败调用。
资源
server.js:列表实现、会话元数据解析、Codex App 工具 schema。lib/ccweb-mcp-server.js:stdio MCP 工具 schema 与提示词。scripts/regression.js:MCP 创建及列表回归。README.md:MCP 能力说明。