CURRENT_IMPLEMENTATION.md 6.9 KB

OpenClaw 任务看板:当前实现方法与技术要点(基线)

更新时间:2026-02-24

1. 当前实现目标与范围

当前版本已经实现一个可运行的“对话任务看板”基线,核心目标是:

  1. 把 OpenClaw 对话自动同步为任务节点。
  2. 以思维导图形式在画布展示父子层级关系。
  3. 支持节点详情卡编辑(开始时间、计划、Bug 原因、备注等)。
  4. 支持导出 JSON / SVG。
  5. 用低饱和粉色主题展示状态,执行中节点带旋转虚线动画。

2. 代码结构与职责

路径 职责
task-board/server.js Node 原生 HTTP 服务,提供静态资源与任务 CRUD API,持久化到 tasks.json
task-board/public/index.html 页面结构:顶部工具栏、侧边统计、SVG 画布、节点详情弹窗
task-board/public/app.js 前端状态管理、树布局计算、SVG 绘制、节点交互、导出逻辑
task-board/public/styles.css 低饱和粉色主题、状态色、连线样式、执行中虚线旋转动画、响应式布局
hooks/task-board-realtime/HOOK.md Hook 元数据,声明监听的 OpenClaw 事件
hooks/task-board-realtime/handler.js 对话到任务节点的实时同步逻辑(含去重、补偿扫描、会话收尾)
task-board/.sync-state.json Hook 同步状态(会话映射、计数器、已处理消息索引)
task-board/tasks.json 看板任务数据文件

3. 后端实现(任务服务)

服务:task-board/server.js

3.1 技术选型

  1. Node.js 原生 http + fs,无额外框架。
  2. 单文件 JSON 持久化,适合本地轻量部署与调试。

3.2 任务数据模型

字段(标准化后):

  1. idtimestamp-random 形式字符串。
  2. name:节点名称,最长 120。
  3. parentId:父节点 id,根节点为 null
  4. statuspending | in-progress | completed | bug
  5. createdAt / updatedAt:ISO 时间。
  6. startTime / endTime:可选 ISO 时间。
  7. plannedApproach:计划说明(最多 2000)。
  8. bugDetails:Bug 终止说明(最多 2000)。
  9. notes:补充信息(最多 3000)。

3.3 API

  1. GET /api/tasks:返回任务列表。
  2. POST /api/tasks:创建任务(校验父节点存在)。
  3. PUT /api/tasks/:id:更新任务(校验状态、时间、父子环)。
  4. DELETE /api/tasks/:id:级联删除该节点及全子树。

3.4 关键约束

  1. 父子关系禁止成环(detectCycle)。
  2. 状态自动补齐时间:
  3. in-progressstartTime 时自动填充。
  4. completed/bugendTime 时自动填充。

4. 前端实现(画布 + 卡片)

入口:task-board/public/app.js

4.1 画布与布局

  1. 使用 SVG 分层渲染:linksLayer(连线)+ nodesLayer(节点)。
  2. 通过 buildTreeLayout 把数据组织成树:
  3. 根节点按 createdAt 排序。
  4. 子节点按 createdAt 排序。
  5. x 由深度决定,y 通过 DFS 叶子递增并把父节点放在子树中线。
  6. 连线使用三次贝塞尔曲线。

4.2 交互能力

  1. 拖拽平移画布(pointer)。
  2. 滚轮缩放(scale clamp)。
  3. fitView 自动适配到当前节点包围盒。
  4. 点击节点打开详情弹窗。
  5. 弹窗可编辑状态、时间、计划、Bug、备注;可增删子节点。
  6. 导出 JSON 与 SVG。

4.3 状态与视觉表达

  1. 低饱和粉色主色系在 styles.css:root 变量定义。
  2. 状态色:
  3. pending 灰粉、in-progress 粉、completed 绿、bug 红粉。
  4. 执行中动画:
  5. 节点外环 progress-ring 使用 stroke-dasharray + stroke-dashoffset 动画旋转虚线。

5. 实时同步实现(OpenClaw Hook)

入口:hooks/task-board-realtime/handler.js

5.1 监听事件

HOOK.md 当前声明:

  1. message:received
  2. message:sent
  3. agent:bootstrap
  4. command:new
  5. command:reset
  6. command:stop

5.2 同步策略

  1. 对每个 sessionKey 维护一个根节点(Conversation)。
  2. 每条用户消息写为子节点(Turn)。
  3. /new/reset 时把当前会话根节点置为 completed,下次消息再开新根。
  4. 如果事件中无 sessionId,会从 ~/.openclaw/agents/<agent>/sessions/sessions.json 反查。
  5. transcript 读取策略:
  6. sessionId.jsonlsessionId-topic-*.jsonl 中选择最近修改的文件。
  7. 扫描尾部用户消息并批量补写未处理消息。

5.3 去重与状态文件

  1. 去重键:sessionKey::messageId,无 messageId 时使用内容+时间 hash。
  2. task-board/.sync-state.json 保存:
  3. sessions:会话到根节点映射。
  4. counters:会话根节点编号计数。
  5. messages:已处理消息索引(防重复写入)。
  6. 配置项:
  7. maxRememberedMessages 控制消息去重索引上限。

5.4 时序补偿(避免“慢一拍”)

  1. 事件触发时先进行一次即时 transcript 扫描。
  2. 额外安排异步延迟补扫(当前为 1600ms、4800ms),不阻塞主流程。
  3. 该机制用于处理 transcript 落盘晚于 hook 触发时刻的情况。

6. 当前实现与需求对照

6.1 已满足

  1. 对话自动入板(主节点 + 子节点)。
  2. 层级关系可视化。
  3. 状态色区分明确。
  4. 执行中旋转虚线动画。
  5. 节点详情卡字段完整。
  6. 导出 JSON / SVG。
  7. 低饱和粉色整体风格。

6.2 当前缺口(你刚提出的两点)

  1. 缺少“按对话筛选”的下拉标签或会话选择器。
  2. 当前布局是“树状层级布局”,不是“思考链/思维链”导图语义布局。

7. 已知技术限制与结构问题

  1. 数据层是平铺数组 + parentId,缺少对“对话维度”的一级索引接口。
  2. 前端默认一次渲染全部节点,缺少“按会话聚焦/隔离”。
  3. 节点语义目前只有根/子区分,缺少“推理步骤类型”(观察、假设、行动、验证、结论等)建模。
  4. 布局算法是静态树排布,不包含链路方向强化、时间轴、分支合并等“思考链视觉语法”。
  5. 同步依赖本地 JSON 文件,暂不支持多实例并发写入。

8. 后续重构建议(用于你准备的新结构)

  1. 数据层先引入“会话视图模型”:
  2. conversationId -> nodes[] 与全量任务存储分离。
  3. API 增加 GET /api/conversationsGET /api/tasks?conversationId=...
  4. 前端增加“会话下拉 + 标签筛选 + 仅看当前会话”模式。
  5. 把当前树布局抽象成 layout engines
  6. tree(兼容模式)+ thought-chain(新模式)可切换。
  7. 给节点补充“思考链语义字段”(例如 stepType, confidence, evidenceRef)。
  8. Hook 写入时可按语义模板自动填充(至少先区分 user-turn / agent-turn / tool-turn)。

如果后续要拆目录,建议以 backend/, frontend/, sync-hook/, docs/ 四层分离,先保证 API 与布局引擎可独立迭代。