实现 Kanban 增强(P0-4)。后端 API + 前端五列看板页面。 核心定位: Kanban 是蜂群任务的电子沙盘——观察全貌、发现异常。不做批量 dispatch/创建任务/goal_mode 配置(这些走 Hermes CLI)。 ## 后端: Kanban API 创建 backend/app/api/kanban.py,全部 require_auth ### 1. GET /api/v1/kanban/tasks 跨 Profile 五列任务聚合: - 数据来源: hermes CLI `hermes kanban list` 解析 - 支持 ?worker=xxx&board=xxx&anomaly=blocked_timeout|unclaimed|retry_failure - 返回五列数据: {todo: [...], ready: [...], running: [...], blocked: [...], done: [...]} - 概览条: total_tasks, profile_count, running_count, blocked_count - 暂用 Mock 数据(TODO: CLI integration) ### 2. GET /api/v1/kanban/tasks/{id} 任务详情: - Meta: board, worker_profile, worker_type, priority, created_at, updated_at, goal_mode, retries/failures - Body: 任务描述(Markdown) - 关联: 依赖任务, 被依赖任务 - 活动: 最近操作时间线 ### 3. PATCH /api/v1/kanban/tasks/{id}/move 拖拽移动: - body: {column: "ready"|"running"|"blocked"|"done", block_reason?: "阻塞原因(≥10字)"} - 拖入 BLOCKED 需填写阻塞原因 - 拖入 DONE 二次确认(前端) ### 4. 异常检测(内置逻辑) 服务端计算任务异常标记: - blocked_timeout: BLOCKED 列超 24h → 标红 - unclaimed: TODO 列超 3 天 → 标黄 - retry_failure: 失败重试≥3 次 → 标红 ## 前端: Kanban 页面 修改 frontend/src/pages/KanbanPage.tsx: ### 顶部概览条 - "当前 N 个任务 · M 个 Profile · K 个 RUNNING · B 个阻塞" - RUNNING 蓝色, 阻塞橙色 - 右侧筛选下拉: Worker / 看板 / 异常状态 ### 五列看板 - TODO / READY / RUNNING / BLOCKED / DONE - 每列头: 列名(彩色) + 任务计数 - BLOCKED 列橙色边框 + 左边框 - 列宽 min 240px, 五列一屏可见 - 列内容纵向滚动, 列头 sticky ### 任务卡片 - 标题(粗体, 最多两行) + Worker Profile 名 + 蜂型图标 - 状态标记: 🎯 goal_mode, ⚡ 高优先级 - 创建时间(相对时间 "2h ago") - BLOCKED 列卡片显示阻塞原因(一行截断) - 卡片左侧色条: P0=红, goal_mode=金, blocked=橙 - 卡片 hover 边框变 honey - 异常卡片: 阻塞超时红色, 长期无主黄色, 失败重试红色 - 点击卡片 → 打开详情抽屉 - 卡片 Checkbox (hover 显示) ### 拖拽 - 桌面端支持拖拽卡片到任意列 - 拖入 BLOCKED 弹出阻塞原因输入框(必填 ≥10字) - 拖入 DONE 二次确认 - 移动端禁用拖拽 ### 任务详情抽屉 (Drawer 组件, 480px) - Header: 状态 Badge + 标题(可编辑) + ✕ - Meta: 看板, Worker, 类型, 优先级, 创建/更新时间, goal_mode, 重试次数 - Body: Markdown 描述, goal_mode 验收标准 checklist(可勾选), 阻塞原因 - 关联: 依赖/被依赖任务链接(点击跳转) - 活动: 时间线(操作人+时间) - Footer: [编辑] [标记阻塞] [标记完成] [删除] ### 批量操作栏(底部浮现) - 勾选≥1 张卡片后底部浮现操作栏 - [标记完成] [标记阻塞] [清除选择] - 不做 Dispatch(走 CLI) ### 四态覆盖 + 乐观更新(拖拽后即时更新 UI,失败回滚) 注册路由, 完成后提交。