# 子代理标题与简介展示计划 ## 目标 在协作子代理卡片中稳定展示可读标题和任务简介,并确保多子代理合并、运行中与完成态都不丢失各自的任务上下文。 ## 视觉与交互方向 - 视觉主张:延续现有深色紧凑工具卡,以清晰文字层级替代额外装饰。 - 内容计划:第一行标题与状态,第二层展示两行任务简介,角色作为低权重辅助信息,结果继续保留在悬浮详情中。 - 交互主张:保留卡片点击复制线程 ID、关闭按钮状态反馈和现有折叠行为,不新增装饰性动效。 ## 当前阶段 已完成 ## 阶段 ### Phase 1: 建立实施计划并完成独立审查 - **Status:** complete ### Phase 2: 补充标题与简介的数据归一化回归断言 - **Status:** complete ### Phase 3: 实现每个子代理独立的标题与简介合并 - **Status:** complete ### Phase 4: 实现紧凑双层卡片渲染与样式 - **Status:** complete ### Phase 5: 运行语法检查与自动化回归测试 - **Status:** complete ### Phase 6: 检查真实页面效果并完成交付清理 - **Status:** complete ### Phase 7: 修复关闭后子代理卡片消失 - [x] 覆盖关闭更新缺失结构化状态的回归场景 - [x] 缓存子代理最后一次结构化状态 - [x] 用已关闭 ID 和状态缓存重建关闭卡片 - [x] 保留已关闭子代理的标题、简介与线程 ID - [x] 验证关闭状态、数量和卡片持续可见 - [x] 验证普通工具调用不进入子代理合并路径 - [x] 找不到原 spawn 工具时,将 child 状态合并到最近的协作工具历史记录 - [x] 刷新/历史重渲染后仍保留标题、简介、线程 ID 和关闭状态 - [x] 实施前后核对工作树,只改子代理相关代码与测试 - **Status:** complete ### Phase 8: 统一 subAgentActivity 与原生协作工具卡片 - [x] 复现并定位两套子代理事件链路 - [x] 为活动归一空 wait 复用及去重写失败回归 - [x] 实现 agentThreadId agentPath 状态及 prompt 字段归一 - [x] 合并活动与协作工具并隐藏原始工具条及 call ID - [x] 运行语法检查和完整自动化回归 - [x] 重建 CentOS 7 发布包并完成二进制与 tar 核验 - [x] 为无 prompt 子代理生成可读标题与兜底简介 - [x] 重新回归并重建最终发布包 - **Status:** complete ## 完成标准 - 按 `label → title → nickname → name` 选择第一个非通用、非线程 ID 的协议标题。 - 仅有线程 ID 或 `子代理` / `子代理 N` 等通用名称时,从该子代理自己的任务提示词生成稳定标题。 - 每个子代理保留自己的简介,多子代理合并不会共用第一个提示词。 - 无 prompt 但有 agentPath/task name 时生成可读标题和明确的兜底简介;两者都没有时才回退短线程 ID。 - 简介最多显示两行,完整简介挂在简介 DOM 的悬浮提示;运行结果保留在卡片容器的独立悬浮详情,两者不互相覆盖。 - 现有状态、关闭、复制线程 ID 功能不回退。 - 窄屏下标题、状态和关闭按钮不横向溢出。 - 相关回归测试通过。 ## 回归场景 1. 可读协议标题按字段优先级展示。 2. 通用标题从各自 prompt 提炼。 3. 多代理不同 prompt 的标题和简介不串联。 4. 无 prompt 时回退短线程 ID。 5. 关闭更新即使不携带 `receiverThreadIds/agentsStates`,也保留原子代理卡片并显示“已关闭”。 6. 仅有 `subAgentActivity` 与空 `wait` 的历史会话也显示统一富卡片,不再显示原始活动工具条或 `ID call_...`。 7. `agentThreadId` 写入 `receiverThreadIds` 并作为 `agentsStates` 键;`agentPath` 的 basename 写入可读标题/角色。 8. `started/interacted` 映射为运行态,`completed/returned` 映射为完成态,失败/关闭类活动映射到对应终态。 9. 活动或同线程事件能提供 prompt 时写入 `taskDescription`;完全没有 prompt 时显示明确标注的兜底任务说明,不冒充真实 prompt。 10. 回归分别覆盖完整 `spawnAgent`、仅 `subAgentActivity + 空 wait`、刷新历史、原始工具条去重、无 `ID call_...` 与 prompt 保留。 11. 发布包保持 `bun-linux-x64-baseline` 目标,完成 MCP JSON-RPC 初始化 smoke test,并核对 tarball 内运行文件与静态资源。 12. 无 prompt 的 `subAgentActivity` 也必须使用与完整 spawnAgent 相同的标题+简介卡片结构,不再显示裸 snake_case 名称。 ## 范围约束 - 不新增依赖。 - 不改变后端协议。 - 不重启服务。 - 不覆盖当前工作树中 `CHANGELOG.md`、`README*.md`、图片附件数量相关 `public/app.js` / `server.js` / `scripts/regression.js` 改动。 - 允许定点修改 `server.js` 的子代理工具持久化函数,但不得触碰图片附件处理区。 ## 错误记录 | 错误 | 尝试 | 处理 | |---|---:|---| | 暂无 | 0 | - | | UUID v7 未被识别为线程式标题 | 1 | 扩展为通用 UUID 形状判断并补行为测试 | | 回归仅验证源码字符串契约 | 1 | 提取实际纯函数源码执行多 spawn / wait / close 用例 | | 新增集成契约按单行字符串匹配多行调用 | 1 | 改为允许空白与换行的正则匹配 | | 后续空标题字段覆盖首次可读协议标题 | 1 | 合并时无可读新标题则保留旧标题字段,并补行为回归 | | 多文件补丁缺少合法 hunk 边界 | 1 | 拆分为独立小补丁应用 | | prompt 派生 label 被误判为协议标题 | 1 | 归一化阶段携带标题来源标记并补行为回归 | | 规划文档阶段格式未被完成检查器识别 | 1 | 改为标准 Phase 三级标题与完成状态字段格式 | | 空 wait/close 工具缺少可渲染的子代理状态 | 1 | 缓存 `msg.child` 状态,并用已关闭 ID 重建关闭卡片 | | 测试先行缺少 `rememberCollabAgentState` | 1 | 实现按 threadId 缓存 helper 后回归通过 | | 实时缓存无法覆盖刷新后的历史重渲染 | 1 | 原 spawn 工具缺失时把 child 合并进最近协作工具并持久化 | | 收尾时临时 TODO CSV 已被外部流程移除 | 1 | 确认根目录无 TODO CSV 后不重建,直接闭合持久化计划 | | `task.py list-context` 误传 action 参数 | 1 | 查看 `--help`,确认该命令只接收任务目录,后续按正确形状调用 | | Phase 8 首次计划审查发现字段、去重和发布核验契约不够具体 | 1 | 补充字段级映射、逐项行为断言与 CentOS 7 二进制/tar 验证标准后复审 | | 首轮实现通过定向回归但独立检查发现空 wait 状态冲突与 completed 丢 prompt | 1 | 补充四类边界行为断言,改为子状态聚合整体状态并结构化合并 runtime 活动输入 | | `timeout` 后直接放环境变量导致命令被当成可执行文件 | 1 | 改用 npm `--registry` 单次参数,代理查询与临时 Bun 安装成功 | | 临时 TODO CSV 被外部流程移除 | 1 | 按现有计划状态重建 CSV,并追加新的展示兜底与最终重建步骤 | | 富卡片首轮复核发现 prompt 派生自动名被误翻译 | 1 | 在状态条目归一时保留显式标题来源标记,并补真实 merge→render 回归 | | 最终重启前发现另一个对话仍在运行 | 1 | 按项目规则不重启;确认静态 app.js 由磁盘直接提供且 HTTP 哈希一致、Cache-Control 为 no-store |