需要 DeepSeek Harness(
dsh web,本地 127.0.0.1:3080)
把 multica.ai 的核心理念搬进 DeepSeek Harness 网页界面 (默认 http://127.0.0.1:3080):一个看板,issue 分派给 agent / 人,状态流转带 评审门禁,运行与执行日志留痕,数据本地持久化。参考实现: multica-ai/multica。
本轮为「核心优先」版本:看板 + issue 管理 + agent 分派 + 运行日志 + 评审门禁 + 一键自动执行(真实拉起 DSH agent)+ 拖拽排序 + token/成本统计 + Inbox 收件箱 + @提及派活 + 失败自动重试 + Autopilot 定时任务 + Skill 沉淀 + 项目仓库上下文 + 多看板 + SSE 实时推送 + 键盘快捷键。 multica 的 squads / 外部 agent CLI 桥接 / IM 渠道 / 桌面端 等留作后续扩展。
deepmutica/
├── install.sh # 安装/卸载脚本(幂等,含健康检查)
├── README.md
└── board/
├── plugin.mjs # 服务端插件(board-server):/board/api/* 路由、
│ # JSON 持久化、评审门禁、agent 花名册
├── build.js # 客户端 bundle 构建脚本(零依赖,node build.js)
├── split.js # 一次性拆分脚本(client.js → lib/src/*.js,仅供追溯)
└── client/ # 客户端插件包(deepmutica-board)
├── package.json # dsh.client 声明(platform: web, inject: ["slots"])
└── lib/
├── index.js # node half:空实现(仅保证 loader 挂载)
├── client.js # 浏览器 bundle(由 lib/src 构建产物,勿手改)
└── src/ # 源码(按组件拆分:样式/状态/API/组件/快捷键等)
├── 00-head.txt / 99-tail.txt # bundle 壳模板
└── 01-style.js … 17-mount.js # 顺序即依赖顺序
集成方式(零构建,纯热加载):
- 服务端插件:
cordis.patch.yml插入 loader 条目{id: board-server, name: ./board/plugin.mjs}。dsh 的补丁热加载会自动挂载, 注册/board/api前缀路由(与/plugins同级),数据写入$DSH_HOME/storages/board.json(原子写)。 - 客户端插件:包
deepmutica-board软链进 profile 的node_modules;client-modules扫描到其dsh.client声明后,把lib/client.js作为浏览器束注入window.__DSH_BOOT__,由 GUI 壳加载。 插件向既有槽位注册:sidebar.footer.action→ 「看板」开关按钮(带评审待办角标)shell.overlay→ 全屏看板(列 / 卡片 / 详情抽屉 / 评论 / 运行日志 / 评审)
cd ~/Desktop/deepseek-harness/deepmutica
./install.sh # 安装(重复执行安全)
./install.sh uninstall # 卸载安装后刷新一次浏览器页面(刷新后 index.html 才会带上看板插件的 boot 条目)。
之后改服务端 board/plugin.mjs 无需重启——补丁热加载 + 页面刷新即可生效。
lib/client.js 是构建产物,不要手改。改 board/client/lib/src/*.js 后:
cd board/client
node build.js # 构建 lib/client.js(零依赖,顺序=依赖顺序)
node build.js --check # 语法校验(逐个 src 文件 + 产物)
node build.js --watch # 监听 src 自动重建改完刷新浏览器页面即生效(bundle 按内容 hash 下发,无需重启服务器)。 运行测试:
cd board/client/lib
node shortcuts.test.mjs # 单元测试(快捷键/剪贴板/菜单逻辑)
node e2e-shortcuts.mjs # 快捷键 E2E(真实浏览器;自动建测试卡片并清理)
node e2e-modals.mjs # 弹窗 E2E(ModalShell 全部 7 个弹窗渲染 + Esc 关闭 + console 零错误)
node e2e-ui-css.mjs # 样式 E2E(深色主题对比度 + 响应式断点 + 卡片键盘导航 + focus trap)-
刷新页面后,左侧边栏底部出现「▦ 看板」按钮;有 issue 处于「评审」时带角标。
-
打开看板:右侧并排面板,左侧聊天区保持可见可用(不再全屏跳页)。
- 点击看板外的任意区域即可收起看板(也可用
Cmd/Ctrl+B、Esc或右上角 ✕); 在聊天区拖拽选中文字等操作不会误收起。 四列 待办 → 进行中 → 评审 → 完成。 - 卡片显示优先级、所属项目、运行中标记、分派人、更新时间。
- 点卡片打开右侧详情抽屉:描述、元信息、执行提示词、运行日志、评论、操作。
- 点看板内、详情抽屉外的任意区域即可收起详情(点其它卡片则切换到该卡片;弹窗打开时不收详情)。
- 点击看板外的任意区域即可收起看板(也可用
-
新建 Issue:标题 / 描述 / 所属项目 / 分派人(花名册建议:主代理、agent 预设、子代理、自定义 agent、人工)/ 优先级 / 标签。
- 创建后立即自动执行:创建表单里的勾选项。分派给 agent 时自动勾选并 显式提示「已分派给 agent,创建后会自动拉起执行(可取消勾选)」——消灭"填了 agent 却没跑"的隐性陷阱;分派给人/未分配则取消勾选。不勾选则只建 issue。 勾选创建后自动打开详情看到运行进度(卡片高亮闪烁)。
- 表单内
Cmd/Ctrl+Enter直接提交。 - 任务模板:新建表单顶部 6 个内置模板(功能开发 / Bug 修复 / 代码评审 / 安全巡检 / 调研分析 / 文档),点一下预填标题、描述、优先级、标签。
- 截止日期:可选;卡片显示 ⏰ 徽标,到期未完成变红;支持「按截止日期」排序。 3b. 依赖关系(详情抽屉「依赖(阻塞)」):可添加其它 issue 作为依赖。依赖未完成 时,本任务不能进入「进行中/完成」(服务端门禁,卡片 ⛓ 红色提示);设置会 校验循环依赖。依赖任务可一键「打开」跳转。 3c. 全局搜索:看板头部 🔍 搜索框,跨标题 / 描述 / 评论 / 日志 / 标签(≥2 字符 实时搜索,结果点击直达)。 3d. 列内排序:头部「排序」下拉(手动顺序 / 按优先级 / 按更新时间 / 按截止日期); 拖拽排序仅在「手动顺序」下生效。 3e. 数据导出:⋯ 菜单「导出数据(JSON 备份)」→ 下载全量数据(含归档),备份 / 迁移用。
-
项目(Projects):看板顶栏「项目」按钮 → 创建 / 重命名 / 删除项目;顶栏 下拉可按项目过滤看板(含「未分配项目」)。项目删除后其下 issue 变为无项目。
-
自定义 Agent(Agents):顶栏「Agents」按钮 → 创建 / 编辑 / 删除自定义 agent(名称、描述、DSH 预设、默认工作目录),像 multica 一样给 agent 定身份; 创建后立即出现在分派花名册里。工作目录不用手打:点「📁 访达选择」会弹出 macOS 原生文件夹选择框(复用 DSH 的 directory-picker),选完自动填入; 选择器不可用时按钮会报错提示(如远程部署无桌面)。 从模板创建:内置 12 个常用 agent 模板,点一下自动预填表单(可改)再创建:
模板 预设 用途 产品经理 standard 需求澄清、PRD、验收标准、任务拆解 页面设计师 standard UI/UX、布局交互、设计→前端 前端工程师 code 组件/样式/交互/性能 后端工程师 code API、数据库、脚本、联调 代码审查员 standard 质量、bug、边界、diff 评审(只审不改) 测试工程师 code 用例、自动化测试、回归、验收 安全运维检测 standard 依赖漏洞、密钥泄露、权限日志、加固 数据分析师 standard 数据处理、统计、图表 量化策略研究 standard 因子、回测、RRG 象限、信号报告 文案与内容 minimal 产品介绍、健康/心理内容、发布文案 文档工程师 standard README、SOP、评审记录、架构说明 部署与打包 standard 编译、dmg 打包、部署脚本、发布检查 -
分派与执行:
- 一键自动执行:详情里「▶ 自动执行(拉起 agent)」→ 服务端用
agents.create拉起一个真实 DSH agent(带分派人指定的预设/工作目录), followup 任务文本;agent 干活过程的工具调用/结果/文本自动镜像成运行日志, 结束后自动统计 token、写摘要,并把 issue 移入「评审」。- 触发后自动高亮状态卡片、详情运行区自动滚到最新日志,进度即时可见。
- 自动执行在工作目录 / 预设不可用时回退 standard 预设;有 20 分钟看护 超时(卡在审批/死循环会自动中止并触发重试)。
- 看板生成的任务不进聊天界面:被拉起的 agent 会话以
origin: "subagent"标记,GUI 会话列表按既有规则过滤,因此不会出现 在侧边栏会话列表;进度实时镜像成运行日志,会话 id 记录在运行元信息里, 详情里「在会话中打开 ↗」可跳转到该会话围观/审批。
- 手动运行:只建一条 run 记录,适合人工执行后自己补日志; 「完成运行」时可手工填 token 用量(输入,输出)。
- agent 也可直接调 API 上报(见下)。
- 一键自动执行:详情里「▶ 自动执行(拉起 agent)」→ 服务端用
-
拖拽排序:卡片可直接拖到其它列(末尾),或拖到某张卡片上(插到它前面) ——跨列移动同样受评审门禁约束。
-
token/成本统计:每次运行记录 token(自动执行取 provider 真实用量,手动可填); 「统计」面板按分派人和项目汇总 issue 数 / 完成数 / 运行数 / token / 估算成本 (内置近似价格:输入 ¥2/百万、缓存读 ¥0.5/百万、输出 ¥8/百万)。
-
Inbox 收件箱:评审待办、被打回、运行失败、等待人工审批 汇总到「📥」面板 (侧边栏「看板」按钮带角标),点击直接跳转对应 issue。
-
@提及派活(带补全):评论或 issue 描述里输入
@→ 弹出自定义 agent 补全 菜单(方向键选择、回车/Tab 插入)→ 选中的 agent 自动接收该 issue 并拉起执行 (run 记录 + 系统评论确认)。 -
失败自动重试:自动执行失败/超时后同一条 run 自动重试(默认最多 2 次, 10 秒起退避递增),日志里能看到「自动重试」记录。
-
Autopilot 定时任务(「⏰」按钮):站会 / 安全巡检 / 周报,支持每天定点 / 每周某天 / 每 N 小时;动作会生成 issue(可选自动执行),30 秒 tick 校验。 执行 agent 可在表单里显式选择(「自动选择 agent」= 默认逻辑;指定后优先 派给该自定义 agent——安全巡检保留"名称含安全/运维"的兜底匹配)。
-
Skill 沉淀:issue 有完成运行后,详情里「📚 沉淀为 Skill」→ 把标题/描述/ 完成结论写入
~/.dsh/skills/<slug>/SKILL.md(DSH 标准 skill 格式,所有 agent 可见可用)。 -
项目仓库上下文 + 工作区同步:项目可配「仓库目录」(📁 访达选择);自动执行时 会把分支 / 最近 8 条提交 / 工作区变更带进任务提示词,让 agent 进对上下文。 DSH 侧边栏的 Workspaces 会自动同步成看板项目(同名合并,repoPath 自动指向 工作区目录)——新建 issue 的「所属项目」直接就能选你已有的工作区项目。
-
多看板:顶栏看板下拉切换,可新建/删除看板;issue 归属看板,各看板独立。
-
SSE 实时推送:看板变化即时推送,无需手动刷新(1 分钟兜底轮询)。
-
键盘快捷键(看板顶栏下方有提示条;macOS 显示
⌘、Windows/Linux 显示Ctrl+,两者都支持;输入框/文本域内一律不拦截):Cmd/Ctrl+B开/关看板Esc逐层关闭(弹窗 → 详情 → 看板)Cmd/Ctrl+C全局复制:任意位置(对话消息、代码块、看板文本等 非输入框区域)选中文字后按Cmd/Ctrl+C→ 立即接管并显式把选中内容写入 剪贴板(preventDefault 避免系统 beep,提示「已复制选中内容 ✓」); 无选区且看板打开时才是看板专用功能——复制卡片内容(标题+描述,可粘贴到 聊天,或再按Cmd/Ctrl+V直接复制出一张新卡片):点开详情复制该卡片, 未点开详情时悬停到卡片上直接按Cmd/Ctrl+C也能复制(详情优先于 悬停);Cmd/Ctrl+Shift+C复制执行提示词Cmd/Ctrl+V全局粘贴:编辑态(输入框/文本域)交浏览器默认粘贴 (WKWebView 原生编辑粘贴,绝不拦截);非编辑态一律接管(preventDefault 避免系统 beep)——看板打开(无弹窗)时从剪贴板预填新建表单(第一行为标题, 其余为描述;详情打开时同样生效,复制卡片→粘贴新建;新建表单已打开时直接 更新字段;剪贴板不可读/被拒时提示手动粘贴);看板关闭时若剪贴板有内容则 明确引导「请点进输入框后按Cmd/Ctrl+V粘贴」- 绝不静默无反应:没有任何可复制卡片时会提示「没有可复制的卡片…」;
点卡片/开看板会自动清掉聊天区残留的文本选区,避免它吞掉
Cmd/Ctrl+C - 双通道兜底:除了监听按键(keydown),还监听浏览器必然派发的
copy/paste事件(带clipboardData、无需权限)——某些内嵌 webview/IDE 壳(如 Electron/TRAE 内嵌浏览器)会用系统菜单先吞掉⌘C/⌘V的 keydown,页面收不到按键;此时复制/粘贴事件通道仍能接管, 功能照常可用 - 右键菜单兜底:卡片上右键 → 「复制卡片内容」「复制执行提示词」;看板 空白处右键 → 「从剪贴板粘贴新建」。右键(contextmenu)事件在内嵌壳里 通常可达,即使快捷键事件被宿主吞掉也有可用入口
- 服务端剪贴板桥:客户端剪贴板 API 与 execCommand 都不可用时,自动经
POST /board/api/clipboard(macOS osascript 直连系统剪贴板,UTF-8/GBK 自动识别)读写,与浏览器/桌面共享同一剪贴板 - 可见诊断:提示条下方有一行「诊断:按键 ⌘C×N ⌘V×N | 事件 复制×N 粘贴×N」, 按快捷键后看计数是否增加——不增加说明 keydown 被浏览器/宿主应用拦截 (页面收不到),此时走「事件」通道;两路都走不通的环境请反馈该行内容
- 表单内
Cmd/Ctrl+Enter提交 - 复制带降级方案:
navigator.clipboard在 webview/沙箱里被禁时自动改用execCommand复制,再失败走服务端剪贴板桥;全部失败时弹「手动复制」 对话框兜底(文本已备好,按Cmd/Ctrl+C即可);输入框/文本域内的Cmd/Ctrl+C一律交给浏览器默认行为,绝不拦截;编辑态Cmd/Ctrl+V交浏览器默认粘贴,若 120ms 内未收到默认 paste 事件(WKWebView 壳吞掉 paste),自动读取剪贴板并插入文本兜底(contenteditable 用 execCommand('insertText'),input/textarea 用 setRangeText + input 事件) - 改完代码后需刷新页面(
Cmd/Ctrl+R)才会加载新版插件;内嵌壳 (DeepSeek Harness.app 等 WKWebView 应用)需要重启应用才会重新加载页面
-
归档:详情里「🗂 归档」把任务移出看板(不删除,可恢复);顶栏「🗂 归档」 按钮(带归档数角标)直接打开归档区查看/恢复/永久删除归档任务(「⋯」菜单里 也有「🗂 归档区」入口);当前看板没有任务但归档区有历史任务时,看板顶部会 显示醒目的归档区引导条,点一下即可查看/恢复——归档任务不会凭空消失。
-
评审门禁(服务端强制):
- 进入「评审」后只能「评审通过 → 完成」或「打回 → 进行中」;
- 未评审通过直接移入「完成」会被拒绝(403 review-required);
- 「完成」列受保护,保证「没有人类点头不进完成」。
前缀 /board/api,全部 JSON:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /state |
全部列、issue、项目、自定义 agent |
| GET | /agents?sessionId= |
分派人花名册建议(含自定义 agent) |
| POST | /issues |
新建 {title, description?, projectId?, assignee?, priority?, labels?} |
| GET | /issues/:id |
单个 issue |
| PATCH | /issues/:id |
改 {title?, description?, projectId?, assignee?, priority?, labels?} |
| DELETE | /issues/:id |
删除 |
| POST | /issues/:id/archive |
归档(移出看板,可恢复) |
| POST | /issues/:id/unarchive |
恢复归档 |
| GET | /archived |
归档区列表 |
| POST | /issues/:id/move |
{to: todo|in_progress|review|done, index?}(带门禁;index 用于拖拽排序) |
| POST | /issues/:id/comment |
{text, author?} |
| POST | /issues/:id/runs |
{mode?: manual|auto} 开始运行;auto 会真实拉起 DSH agent 执行 |
| POST | /issues/:id/runs/:rid/log |
{text, kind?: info|command|result|error, source?} |
| POST | /issues/:id/runs/:rid/complete |
{summary?, tokens?: {input, output}, source?} |
| POST | /issues/:id/review |
{action: approve|reject, note?, by?} |
| GET/POST | /projects |
项目列表 / 新建 {name, description?} |
| PATCH/DELETE | /projects/:id |
重命名改描述 / 删除(级联清空 issue.projectId) |
| POST | /agents |
自定义 agent {name, description?, preset?, cwd?} |
| PATCH/DELETE | /agents/:id |
编辑 / 删除自定义 agent |
| GET | /agents/templates |
常用 agent 模板目录(12 个内置) |
| POST | /pick-directory |
打开系统文件夹选择框,返回 {path}(取消→409 cancelled);GET ?probe=1 探测可用性 |
| GET | /events |
SSE 实时推送(看板变化事件流) |
| GET | /chat-context?max=2200 |
主对话上下文(界面↔看板互通):最近活跃非看板会话的最后若干条消息 {sessionId, cwd, updatedAt, context} |
| GET | /work-digest?limit=6 |
看板 agent 工作摘要(看板→主对话):最近运行完整摘要+日志摘录+token+会话id |
| GET | /runs/:rid/transcript |
某次看板运行的完整执行记录(运行中读实时会话;结束后回退持久化日志) |
| GET/POST | /boards |
看板列表 / 新建 {name} |
| PATCH/DELETE | /boards/:id |
重命名 / 删除(issue 归入其它看板) |
| GET/POST | /autopilots |
定时任务列表 / 新建 {name, kind: standup|security|weekly-report, schedule, autoRun} |
| PATCH/DELETE | /autopilots/:id |
启停/改配置 / 删除 |
| POST | /skills |
{issueId} 沉淀为 DSH skill(写入 ~/.dsh/skills/) |
| POST | /clipboard |
{action: read|write, text?} macOS 系统剪贴板桥(osascript;UTF-8/GBK 自动识别;供内嵌壳兜底) |
示例(agent 上报执行进度):
B=http://127.0.0.1:3080/board/api
curl -X POST $B/issues/iss-xxx/runs/run-xxx/log \
-H 'content-type: application/json' \
-d '{"text":"修复了拖拽排序的边界情况","kind":"result","source":"agent-1"}'
curl -X POST $B/issues/iss-xxx/runs/run-xxx/complete \
-H 'content-type: application/json' \
-d '{"summary":"已实现并自测通过","source":"agent-1"}'
curl -X POST $B/issues/iss-xxx/move -H 'content-type: application/json' -d '{"to":"review"}'卸载脚本会移除软链与补丁条目;~/.dsh/storages/board.json(看板数据)保留,
重装后数据仍在。手动清除:rm ~/.dsh/storages/board.json。
- 界面 ↔ 看板互相理解上下文(看板任务不进聊天界面,但双方互通语境):
- 看板 → 主对话(重点:主界面 agent 理解看板 agent 干了什么):
看板状态实时注入主对话的系统提示词(每个模型步骤刷新),包括最近完成
运行的完整摘要(标题 + 结论,而非只有数量);需要深读时一条 curl:
curl http://127.0.0.1:3080/board/api/work-digest(最近运行:完整摘要 + 日志摘录 + token + 会话 id)、curl http://127.0.0.1:3080/board/api/runs/<runId>/transcript(某次执行的完整记录,运行中读实时会话、结束后回退持久化日志)、curl http://127.0.0.1:3080/board/api/issues/<id>(issue 全量日志)。 - 主对话 → 看板:看板自动执行拉起的 agent 在任务提示词里自带「主对话
上下文」段(最近活跃非看板会话的最后若干条消息,自动排除看板运行会话),
所以看板任务一开始就理解你在主界面里正在做什么;也可随时用
curl http://127.0.0.1:3080/board/api/chat-context实时查询。 - 隔离:看板运行会话以
origin: "subagent"标记,不会出现在本界面的 会话列表;围观/审批走运行详情里的「在会话中打开 ↗」。
- 看板 → 主对话(重点:主界面 agent 理解看板 agent 干了什么):
看板状态实时注入主对话的系统提示词(每个模型步骤刷新),包括最近完成
运行的完整摘要(标题 + 结论,而非只有数量);需要深读时一条 curl:
- 自动执行的沙箱与审批:被拉起的 agent 与普通会话同一套工具/沙箱/审批策略; 遇到需要人工审批的操作会停下等待(运行日志会提示,Inbox 会有「等待人工审批」项), 审批在「在会话中打开 ↗」跳转到的会话弹窗里处理;20 分钟无进展自动中止并进入重试。
- 工作目录:自动执行默认用 dsh 进程 cwd;给自定义 agent 配好「默认工作目录」
即可让它在指定目录干活(
~会自动展开)。 - 改服务端插件后的热重载:补丁热加载不会重新 import 同名插件文件。改了
board/plugin.mjs后,把 profile 补丁里board-server的 name 加个版本号 (如./board/plugin.mjs?v=11)即可强制重载;改client.js只需刷新页面。 - 列自定义 / squads(组队路由)/ 外部 agent CLI 桥接 / IM 渠道 / 桌面端 / WebSocket 双向:按 multica 功能面逐步补齐。
- 看板数据单文件存储,多用户并发写采用整文件原子替换;规模上来后可换 SQLite。
- 本地单用户工具:
/board/api/*与 Web GUI 无鉴权、无加密,仅应绑定127.0.0.1本地访问。切勿把 3080 端口暴露到公网/局域网(任何人可读写看板、 查看导出数据、拉起 agent 执行)。 - 看板数据(
~/.dsh/storages/board.json)含任务内容、运行日志与 token 统计, 属敏感数据,请勿提交到版本库。 - 自动执行拉起的 agent 与普通会话共用同一套工具/沙箱/审批策略(详见上文)。
MIT © deepmutica contributors
