dsh-goal-gantt:把长任务的阶段进度画进 DSH 会话

前言

跑长任务时很容易丢进度:对话窗口滚了几十轮,只知道还在做,不知道做到第几章、还剩多少、每章产出了什么。dsh-goal-gantt 就是解决这个的客户端插件,它把一个 goal 切成若干阶段,在会话顶部直接给你一面阶段级进度看板:当前阶段、四个关键数字、甘特时间轴和可折叠阶段清单。维护者是 123David-yang,仓库打了 dsh-plugin topic,可以走插件市场或 CLI 安装。

下面介绍它是什么、怎么装、怎么用,以及几个需要留意的地方。

一、这是什么

一句话定位:它是 DeepSeek Harness 的 goal 阶段级进度看板,不做单次工具调用的轨迹记录。

它回答三个问题:

  1. 这个 goal 现在走到第几章?
  2. 每一章做了什么、产出什么、还剩什么没做?
  3. 距离目标还有多远(阶段数 / 轮次 / 预估时间)?

看板有中英两套界面,按系统语言自动切换,也能用 ?lang=zh / ?lang=en 强制指定。

二、核心功能

一屏三件事。 顶部是「目标 + 会话 + 总进度」,然后当前阶段以大标题加一句话总结的形式占主导,并给出四个关键数字:进度、已用、检查项、剩余阶段。其余指标下放到阶段清单里按需展开。

甘特时间轴。 计划条用虚线、实际条用实线,二者叠加显示;刻度按跨度自动切换 15 分钟 / 1 小时 / 6 小时 / 1 天。缩放档位有四挡:聚焦现在 / 6h / 24h / 全部。「聚焦现在」以进行中阶段的时长为尺度取窗口,逼近边缘时自动重新取窗,不会跑出视野。

阶段可复用。 同一个 id 写多条配置会合并成一条泳道,每段单独画一根条,适合「间断优化」这类反复出现的工作。

** Hero 当前阶段。** 自动定位进行中的阶段,显示阶段名、一句话总结和四个关键数字。

阶段清单与分组。 每阶段一行,展开才看到摘要、检查项和产出物,默认只展开进行中的那条。可以按全部 / 进行中 / 未完成筛选,搜索框按 id、标题、摘要匹配,按 / 直接聚焦搜索。分组按进行中 / 未开始 / 已完成三组,已完成默认折叠。

筛选可分享。 筛选条件和搜索词写进 URL(?q=P3&f=active),「复制链接」会一并带上;Hero 右上角的复制链接还能给出 #P3 这种直达地址,打开就定位到该阶段并展开。

复制摘要与导出 CSV。 一键把当前进度复制成 Markdown(状态图标 + 阶段列表 + 剩余时间),可直接贴到 issue 或 IM;阶段表可一键导出 CSV(id / 标题 / 状态 / 进度 / 计划与实际时间 / 耗时 / 检查项 / 摘要),带 BOM,可直接用 Excel 打开。

交互细节。 点甘特条或阶段行会滚到对应阶段并高亮,键盘 Enter/Space 同样可用;甘特条和阶段行都能 Tab 聚焦,带 aria-label / aria-controls。滚动时吸顶头部的进度环与会话选择器保持可见。相对时间显示「5 小时前」/「已 2h36m」,展开状态和分组状态记在 localStorage。

主题与降级。 浅色主题跟随系统 prefers-color-scheme,并支持 prefers-reduced-motion;正文与辅助文字对比度均在 4.5:1 以上。

稳定性。 内容指纹(signature)不变时只移动时间游标,不重建 DOM;没有 goal 的会话显示空态提示,不会按对话轮次编造阶段;标签页不可见时暂停轮询。坏配置(非法时间、缺 id、phases 不是数组、进度越界)都有收敛处理,不会出现 NaN 或负宽度条形。

三、安装与启用

方式一是插件市场:仓库带了 dsh-plugin topic,会自动进入市场索引,在 DSH Web GUI 的插件页搜索 goal-board 一键安装。

方式二是 CLI:

dsh plugin add github:123David-yang/dsh-goal-gantt

方式三是手动脚本,适合装不进市场的环境:

# Windows
pwsh -File scripts/install.ps1

脚本会定位 $env:DSH_HOME/profiles/web(或 ~/.dsh/profiles/web),把插件复制进 node_modules 并注册 cordis.patch.yml。

装完重启一次 DSH,会话顶部会出现「看板」标签页。

四、典型用法

安装后有两个入口。一是会话顶部的「看板」标签页,就在「对话 / 轨迹」旁边,点开在当前会话内展示,不跳转、不新开页面,切换会话时自动跟随;渲染走 Shadow DOM,样式与宿主隔离。二是独立页面:

http://127.0.0.1:3080/goal-gantt

页面每 10 秒自动拉一次 /api/goal-gantt,阶段状态变化会实时反映。

阶段数据优先从工作区里的 goal-board/board.config.json 读取:

{
  "title": "GOAL 甘特看板",
  "phases": [
    {
      "id": "P1",
      "title": "数据采集层",
      "desc": "一句话说明这一章干什么",
      "status": "done",                        // done | active | pending | blocked
      "plannedStart": "2026-11-05T00:05:00+08:00",
      "plannedEnd":   "2026-11-05T00:14:00+08:00",
      "startedAt":    "2026-11-05T00:05:40+08:00",
      "endedAt":      "2026-11-05T00:13:30+08:00",
      "summary": "这一章实际做了什么(显示在总结卡上)",
      "checks": [{ "label": "子任务", "done": true }],
      "deliverables": [{ "label": "文件", "path": "relative/or/absolute/path" }]
    }
  ]
}

配置默认只对「同一工作区、且当前有 goal」的会话生效;也可以用 sessionId 或 goalId 精确绑定。没有配置文件时自动降级:先按 goal_round 轮次切分阶段,再没有就按对话轮次切分。阶段进度等于 checks 完成比例,没有 checks 时按状态估算(done=100 / active=40 / pending=0)。

复用阶段就是同一个 id 写多条:

{ "id": "P8", "title": "时间轴优化", "status": "done",   "startedAt": "...", "endedAt": "..." },
{ "id": "P9", "title": "文档",       "status": "done",   "startedAt": "...", "endedAt": "..." },
{ "id": "P8", "title": "时间轴优化", "status": "active", "startedAt": "..." }

甘特图上 P8 会是一行、两根条。

五、没有 goal 的会话:对话即项目

没有 goal 时不只有空态。插件会把对话本身抽象成项目:按空闲间隔切段(默认 20 分钟没动静算新的一段),四个数字换成本段用时、阶段数、总跨度、活跃时长;每段标题取该段第一条用户消息;每段从最后一条助手回复里抽取一句「做成了什么」(纯抽取,不调模型)。顶部标记「自动生成」,不伪造进度百分比。全程零 token,只用事件类型和工具名做规则判定,不调用模型。空态只在「连事件都没有」时出现。

六、性能、数据来源与隐私

性能上,解析只用得上的事件(turn/start、tool/call、消息、goal 变更),体积最大的 tool/result 先行文本过滤、不进 JSON.parse;投影缓存与日志都按 mtime + size 缓存。作者给的基准(node test/perf.test.mjs):9.5 MB / 20k 事件的会话,冷启动约 25 ms,热调用 < 1 ms,已接入 CI。超过 40 条的分组只渲染前 40 条,其余折叠为「显示更多」。

数据来源:

数据 位置
goal 状态、轮次、token、轮次大纲 $DSH_HOME/storages/session_projcache/sessions/*.json
精确事件时间线(turn / tool / goal 变更) $DSH_HOME/sessions/<cwd>/<session>/session.v4.jsonl.zstd

会话日志是多帧拼接的 zstd(每次写入一帧),Node 原生的 zstdDecompressSync 只解第一帧。插件按帧魔数 28 B5 2F FD 逐帧解压再合并——README 把这一段标为最关键的兼容逻辑。

隐私方面:默认只读,不写会话、不改已有配置;唯一的写操作是空态里点「写入示例配置」,只新建 <工作区>/goal-board/board.config.json,文件已存在时直接拒绝。离线运行,不发任何网络请求、无遥测,解析结果只在内存里按 mtime 缓存 1 秒。路由受 DSH 的 connection.requestRejection 信任围栏保护(Host/Origin + 登录 cookie)。

七、适用场景与注意

适合跑多阶段长任务、需要对外同步进度、以及想在 DSH 里直接看甘特而不想切到外部工具的开发者。

几点注意:

  • 插件以当前 DSH 进程的权限运行,能读到它能看到的工作区与会话数据。安装前应打开仓库核对源码与许可证(MIT),确认符合自己的安全约定。
  • 兼容范围是 DSH Web profile、@deepseek-ai/dsh 0.2.x,Node.js >= 22(依赖 zlib.zstdDecompressSync;更低版本会退化为只读投影缓存,日志事件不可用)。Windows / macOS / Linux 均支持,Windows 是主线开发环境。
  • 会话日志的逐帧 zstd 解压是版本敏感逻辑,若 DSH 日志格式变更导致阶段事件缺失,可据此定位。
  • 它只读不写、完全离线,这点对不想把会话内容外发的团队是加分项。

短结尾:如果你已经在用 DSH 跑长任务,这个插件的价值在于把「阶段进度」这个信号做进会话界面,而不是另开一套跟踪系统。它不会替你定义目标,只把已有的 goal 或对话结构摊成一张可读的进度板。

目录页:https://www.skillhub.cn/plugins/123David-yang/dsh-goal-gantt

GitHub:https://github.com/123David-yang/dsh-goal-gantt

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜