DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-graph

Graph

A DeepSeek Harness plugin for graph-based goal management and kanban visualization.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-graph@0.23.0
READMECompatibilityVersions

Compatibility and provenance

Graph is published as dsh-graph and currently resolves to version 0.23.0. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/4/2026

Versions

0.23.0stable
11/3/2026
0.22.0stable
10/20/2026
0.21.0stable
10/15/2026
Show 28 more versionsCollapse versions
0.20.2stable
10/10/2026
0.20.1stable
10/10/2026
0.20.0stable
10/9/2026
0.19.8stable
10/8/2026
0.19.7stable
10/6/2026
0.18.0stable
10/1/2026
0.17.0stable
9/30/2026
0.16.1stable
9/25/2026
0.16.0stable
9/25/2026
0.15.0stable
9/21/2026
0.12.0stable
9/20/2026
0.11.2stable
9/17/2026
0.11.1stable
9/17/2026
0.11.0stable
9/14/2026
0.10.0stable
9/12/2026
0.9.2stable
9/9/2026
0.9.1stable
9/7/2026
0.8.3stable
9/3/2026

Related plugins

Loading related plugins…

Latest
0.23.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
4.8 MB
Files
84
Surface
web
License
MIT
Source
npm
GitHub
★ 26
Weekly downloads
421
Security scan
✓ v0.23.0 scan passed
Last push
11/3/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue
0.8.1stable
9/1/2026
0.7.3stable
8/31/2026
0.7.2stable
8/27/2026
0.7.1stable
8/25/2026
0.6.1stable
8/23/2026
0.5.2stable
8/23/2026
0.5.1stable
8/22/2026
0.4.3stable
8/22/2026
0.4.2stable
8/22/2026
0.4.0stable
8/22/2026

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseExperimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundleOptional bundle that adds Schedule, its task page, and time context to the Web compositionWeb All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。Ab Ocrdsh-ab-ocr--- description: "The out-of-tree ocr tool: recognizes a scanned PDF or image page by page, merges the pages in order only after the last one, and saves one Markdown document with the heading levels the model decided." kind: "package-reference" ---

README

dsh-graph

中文 | English

dsh-graph —— Agent 工作的目标化管理


中文

概述

dsh-graph 是面向 DeepSeek Harness (DSH) 的目标看板插件。它将大模型智能体(Agent)的工作流组织为基于图的目标管理(Graph-based Goal Management)。

本插件采用一体化单包分发(npm 包名 dsh-graph),同时集成两大核心能力:

  • Host 端:向 DSH Agent 提供覆盖目标全生命周期的 53 个 graph_* 工具,并暴露 /api/dsh-graph* REST API(支持看板投影、目标详情查询与写操作);
  • Client 端:无缝内嵌于 DSH Web 控制台(conversation.view 槽位)的浏览器二维泳道看板,提供直观的可视化交互与实时追踪。

数据以本地纯文本与事件流形式存储于工作区的 .dsh-graph/ 目录,Git 友好、天然支持协同对账与审计追踪。


安装方式

在 DSH 环境中运行以下命令即可安装:

dsh plugin --profile <profile-name> add dsh-graph

当前版本:v0.23.0。环境要求:Node.js ≥ 22(包内预编译 core 运行时)。宿主提供的核心包(@deepseek-ai/cordis、@deepseek-ai/schemastery、@deepseek-ai/dsh-settings)以 peerDependencies + peerDependenciesMeta.optional(DSH 生态惯例)声明,由 DSH 宿主环境提供,安装不产生 peer 告警;yaml 为插件自带运行依赖(声明在 dependencies 中),避免产生重复的核心包实例。

宿主兼容范围:engines.dsh 与 peerDependencies["@deepseek-ai/dsh-settings"] 同步声明 >=0.1.5-rc.2 <0.2.2-0(上界 -0 排除 0.2.2 的一切预发布与正式版;整条 0.2.1 线已在范围内),engines.dsh 供 dsh-market 等宿主感知型市场在卡片展示与安装/更新预检中读取。⚠️ 宿主的安装/启动门禁只读 peerDependencies、不读 engines.dsh,故两处必须同步放宽(只改 engines.dsh 无效)。实测通过的宿主:0.1.6-alpha.2 ~ 0.1.7-rc.2、0.2.0-rc.1、0.2.0-rc.2(负责人 2026-09-30 真机复验)、0.2.1-alpha.2(2026-10-09 隔离实例无豁免复验)。⚠️ 上列是历史轮次的安装/启停/REST 结论,覆盖的是各自版本的产品代码;g-507 引入的 HTTP 鉴权入口只在 0.2.1-rc.2 实测(见下文「HTTP 鉴权」一节),不得据本段推断其它版本上的鉴权结论。该区间顺带覆盖的 0.1.8 系在 npm 上从未发布(0.1.7-rc.2 之后直接跳版到 0.2.0-rc.1),故为空集,不构成未实测声明。

平台状态:

平台本版状态
Linux / WSL2✅ 已实测通过(本版全量测试 fail 0;H 系列共享探针在本版全绿)
原生 Windows✅ 本版已实测通过(2026-11-02,win32/x64 + Node v24.21.0,宿主 0.2.1-rc.5,通过 22 / 失败 0 / 告警 0):详见 platform-gate §7.13 回填表 —— T1 静态/台账(67 项 268 处命中未登记 0)/ 派发可用(零硬编码 shell 名)/ H 组合探针(H1–H6 除 H3 外全绿)全部通过;T3 看板文件系统生命周期 32 步盘面断言全通过;T4/T5 实例启动就绪与 REST 鉴权换票冒烟通过。
macOS⏳ 本版未验证:v0.23.0 未在原生 macOS 上执行真机门禁 ⇒ 不得读出「已通过」;结论同样以 platform-gate §7 回填表(不随包发布)为准。历史记录见 platform-gate §7.4 / §7.7,只覆盖各自版本的产品代码。

三平台使用同一安装包。已知限制:① macOS 默认文件系统 APFS 大小写不敏感 —— 仅大小写不同的目标编号 / 版本泳道会落到同一实体,请勿只用大小写区分;② macOS 上若工作区路径经显式传入且含符号链接(如位于 /tmp、/var 之下),会被拒绝并报 graph root symlink is not allowed;由 process.cwd() 推导的路径不受影响。

最新亮点(v0.23.0)

  • 长任务智能关照与僵局干预:主管空闲期间对进行中的子代理长任务按生效间隔自动发起巡检与状态把关;支持连续未回复/进展停滞自动升级等待人工,到期只触发巡检而不武断中断执行,支持整组关照的暂停、继续与重置。
  • 子代理时间预算调度与动态基准重算:支持在目标中显式配置预计任务时间预算(未配置继承项目/全局默认阈值);首次派发、运行中调整预算或主管向运行中子代理发送新消息时,立即依据最新时间基准重新计算关照截止,并保持至少 5 分钟无答有效冷却防频发唤醒。
  • 运行轮次精确隔离与历史保真追溯:子代理运行按起止时点划定独立轮次,停止即停表,重新运行自起新轮;精确记录每轮起始预算与变更时间线,禁止以停止时刻预算冒充整轮预算,正常宿主重建遇到同一运行中任务不拆分轮次并如实标注观察空窗。
  • 主管会话智能保活机制:名下有子代理在运行且主管处于空闲时,自动在适当时机进行有界续期与单次防离线保活,避免长时间未交互导致上下文失效。
  • 插件 HTTP 接口安全加固与派发去重:全面封闭无凭证访问风险,对齐宿主统一鉴权与身份白名单校验;强化派发准入门禁,严格防止同一目标并发派发重复执行尝试,杜绝状态冲突与资源争用。

完整变更史见 CHANGELOG。已发布版本支持通过 npm 与 dsh-market 生态分发。


升级残留自检与清理

现象(外部报告):升级宿主后 Web GUI 冷启动报 web boot: N entry did not activate / <插件名>: failed —— 插件的 host 半边(graph_* 工具)正常、热加载也正常,只有浏览器半边不激活。

成因:dsh.client.inject 不是「名录」,而是加载顺序边。浏览器端 loader (@deepseek-ai/dsh-client-modules/lib/client.js)只对 inject 中已存在于客户端清单的包名做前置加载, 名字不在清单里就静默跳过。而 @deepseek-ai/dsh-client-runtime 自 dsh 0.2.x 起不再随宿主分发 (在 dsh 0.1.5-rc.2 / 0.1.7-rc.2 / 0.2.0-rc.2 / 0.2.1-alpha.2 的安装树里均无此包),但它的包清单仍声明 dsh.client: 升级过程中若这个旧条目/旧副本残留在 profile 里,它会重新变成一条客户端清单行;该行的加载失败会被级联成 client-modules: "<插件>" not loaded because dependency "…" failed,把任何仍声明它的插件一起拖死。 干净安装没有这一行,所以不复现。dsh-graph 已删除该声明(即使残留仍在,本插件也不再是它的消费者)。

首选动作:把 dsh-graph 升级到含本修复的版本即可,残留无需处理。 含本修复的版本已不再声明该死引用 ⇒ 无论 profile 里是否还残留旧副本,本插件都不再是它的消费者,也不会被它拖死。下面的自检只是「想确认现状」时的只读排查;清理残留是可选的进阶动作。

自检(全部只读;下述命令已在隔离实例 dsh 0.2.0-rc.2 / 0.1.7-rc.2 上实测):

把 <DSH_HOME> 换成你的 DSH home:web 版默认是 ~/.dsh(也可由 DSH_HOME 环境变量指定);桌面版是另一套路径,请以该壳的配置/日志里显示的 profile 目录为准。

# ① 本插件的声明 —— 期望 3 项,且不含 dsh-client-runtime
node -e 'console.log(JSON.stringify(require(process.argv[1]).dsh.client.inject))' \
  "<DSH_HOME>/profiles/web/node_modules/dsh-graph/package.json"

# ② profile 清单里是否还列着它 —— 期望输出 0
#    (注意:grep -c 在计数为 0 时退出码是 1,看打印出的数字即可,不要看退出码)
grep -c dsh-client-runtime "<DSH_HOME>/profiles/web/package.json"

# ③ 整个 DSH home 内是否还有名为 dsh-client-runtime 的目录 —— 期望无输出
find "<DSH_HOME>" -type d -name dsh-client-runtime 2>/dev/null

# ④(可选,仅在 Web 版且实例正在运行时)客户端清单里是否还有该行 —— 期望无输出
#    「dsh web」启动行会打印带 token 的 URL,把它原样填进 <URL>
curl -sL -b "" "<URL>" | grep -o '"@deepseek-ai/dsh-client-runtime"' | head -1

隔离实例实测结果(dsh 0.2.0-rc.2):

  • ① → ["@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-primitives","@deepseek-ai/dsh-client-ui-sidebar-right"]
  • ② → 0
  • ③ → 无输出
  • ④ → 无输出;curl 返回 200、35125 字节(同一命令对清单里确实存在的行名如 @deepseek-ai/dsh-client-ui-settings 能打印出来)
  • 命令有效性反证(都不是恒真空跑):在一份确实含该名字的清单文件上 ② 打印 1;在 profile 里放入名为 dsh-client-runtime 的目录后 ③ 确实打印出该路径(随即移除)

清理(可选,先备份):仅当你确实想清干净、且 ②非 0 或 ③有输出时:先备份 profile,再删除 ③ 打印出的残留目录(并在 ② 命中的清单里去掉对应条目),然后重启宿主 —— 客户端包元数据在激活期缓存,增删客户端插件必须重启才生效。风险提示:在 live profile 上直接删目录/改清单有改坏环境的风险;更稳妥的替代是重装同版本 dsh-graph 或新建一个干净 profile。自行清理前务必留备份,异常时用备份复原。

未验证:无桌面壳环境可用(@deepseek-ai/dsh-desktop 在 npm 为 E404)。上述现象与成因链引用外部报告与宿主源码, 不声称已复现桌面壳症状。


核心特性

  • 四阶段生命周期状态机: 引擎严格约束状态迁移:draft → planning → collecting → ready → in_progress → review → delivered(任何阶段均可标记进入 blocked 阻塞状态)。
  • 判据先于执行(Criteria Before Execution): 在目标派发执行前必须登记明确的质量验收判据,最终评审严格依照逐条判据核验交付物,杜绝模糊交付。
  • 结构化上下文卡片: 支持文本(Text)、文件(File)、图片(Image)、数据(Data)等多种上下文类型。经历 empty → collecting → filled → reviewed 闭环生命周期,为执行子代理提供精确的上下文种子。
  • 二维泳道看板: 横向按生命周期阶段划分列,纵向按排期划分版本(Version)、暂存池(Backlog)与独立目标(Standalone)泳道;支持拖拽排期。
  • 目标间关系标记: 目标之间可标记「取代 / 调整 / 补充 / 相关」四类关系(也可解除),关系只记在目标文件(frontmatter)这一处真源;看板卡片显示关系徽标,目标弹窗在「目标描述」下方直接列出关系清单(含跨版本与已归档标注)。
  • 流畅跨会话交接(Handoff & Supervisor Claim): 支持生成包含看板投影、长期记忆与关键环境事实的 HANDOFF.md,换会话后新 Supervisor 可幂等认领上下文并快速接管。
  • 现代交互与双主题适配: 完整适配深色与浅色双套主题(自动跟随 DSH 全局主题变量);外部数据更新时支持微光动画提醒(支持系统的 prefers-reduced-motion 无障碍降级);弹窗拖拽防误关。

设计哲学(面向首次接触本插件的用户)

想先弄懂「dsh-graph 为什么这样组织开发」——目标生命周期与状态机、判据门禁与人工 gate、派发与隔离三件套、 attempt 与结果面、独立复核与留痕真源、版本泳道与发布红线、记忆分级、事件先行——请读 设计哲学(中文): 它逐条给出代码真源引用,并附 archify 交互式图(内联静态预览 + 可交互 HTML);图只画今天已实现的 状态流转与角色分工,图内不含文件、函数或内部产物名,1.0 路线见文档 §13。


Agent 工具速查表

dsh-graph 为 Agent 提供了完善的工具链(共 53 个 graph_* 工具),按功能划分为以下分类:

分类工具名称核心说明
目标生命周期graph_create_goal创建目标(默认放入 Backlog,可指定版本)
graph_rename_goal重命名目标标题
graph_set_description设置/更新目标描述正文(Markdown)
graph_set_directive为下一次 Attempt 注入补充指令与边界要求
graph_set_goal_type设置目标类型(feature / bug / task / improvement / patch / chore)
graph_set_goal_tags设置目标标签列表(最多 20 个,乐观并发)
graph_set_goal_budget设置/清空目标预计任务预算(整数秒 30–86400;空=继承项目/全局关照阈值)
graph_amend_goal记录对目标的修订补充,可自动同步至描述
graph_transition推进目标状态机迁移(进入 blocked 需附原因)
graph_postpone_goal暂缓目标,移回 Backlog 并置为 draft
graph_archive_goal归档已完成或已废弃的目标
graph_unarchive_goal从归档中恢复目标
graph_delete_goal安全删除已归档的目标
graph_clean_worktree清理已验证的 worktree(用户确认后执行)
graph_list_worktrees查询 Git worktree 清理候选(只读,不自动删除)
目标关系graph_set_relation标记/解除目标间关系(取代/调整/补充/相关,可增可删;幂等,拒绝替代环)
质量判据graph_set_criteria登记目标验收判据(严格在执行前设定)
上下文卡片graph_add_card创建上下文卡片占位(text / file / image / data)
graph_bind_collect_card绑定收集子代理,卡片状态转为 collecting
graph_fill_card填充卡片内容并生成看板简要摘要
graph_review_card复核卡片内容(filled → reviewed)
graph_delete_card

浏览器看板说明

内嵌于 DSH Web 界面:

  • 二维泳道布局:清晰展现多个版本的推进节奏,支持灵活查看不同泳道和阶段;
  • 分级评审策略支持:通过 graph_get_settings / graph_update_settings 配置项目实际的 review.regions / review.contract_paths / review.non_product_prefixes,未登记区域安全升级 strict,空契约默认 M1 不触发;
  • 实时流式更新:卡片与顶部状态栏直观反映 Agent 汇报的最新执行状态;外部文件变更触发动画闪烁;
  • 丰富弹窗与抽屉交互:点击卡片可展开目标详情弹窗,查看质量判据、上下文卡片与 Attempt 历史。

侧边栏用法

右侧栏的「看板」与会话页的「看板」页签是同一份实现——同一个看板组件、同一套头部与窄档逻辑,两侧完全一致(零 host 门控),任选其一即可。

  • 入口:在会话里打开右侧栏 → 点「看板」磁贴;打开的看板面板会成为右侧栏顶部的一个页签常驻,随时切回。
  • ⋯ 工具:刷新 / 标签筛选 / 记忆 / 项目知识库(共享条目)/ 看板设置 / 已归档。工具条按头部实测宽度装不下自动折叠为这一项(不是写死的窗口断点)。
  • [🏷️] 版本管理:角落的方形图标按钮(可访问名称为「🏷️ 版本管理」),点开版本管理抽屉;紧邻其右是同一行等高的 创建版本。
  • 版本选择器:位于泳道行 [+](新建目标)左侧,切换当前显示的泳道(具体版本 / Backlog / 独立目标)。
  • 窄档行为(分档依据是看板根容器实测宽度——即看板组件自身元素的 clientWidth,不是窗口宽度、也不是浏览器视口宽度):
    • ≥ 480px(宽档):多泳道横向并排,各版本 / Backlog / 独立目标可同时查看;
    • < 480px(单泳道档):阶段列由横向并排改为纵向堆叠,泳道内容由版本选择器决定(具体版本 / Backlog / 独立目标三选一;工作区一个版本都没有时,默认落点就是「独立目标」,选择器当前项显示「独立目标」);该档没有版本折叠开关(收起来等于空板),并同时把工具条强制折叠为「⋯ 工具」、隐藏 DEBUG 行。
    • 怎么把看板放进 < 480px:宿主页签的宽度由页签布局模式决定,不是拖出来的——实测(1600px 视口)单页签 719px、页签上的 分栏 之后每页签 359px(该档随窗口宽度变化)、全屏 799px。所以默认单页签宽度(719px)落在宽档,此时不会出现单泳道;需要单泳道档时用页签上的 分栏,或把窗口收窄到看板面板实测宽度 <480px。进入后一眼可验:六个阶段块纵向堆叠,且泳道标题右侧出现版本选择器(当前项为具体版本 / Backlog / 独立目标)。
    • 宽档残留(实测):宽档网格的最小宽度实测约 956px,所以看板面板实测宽度在这之下时(例如默认单页签 719px),宽档网格仍会横向滚动、把「确认 / 批量接受」列推到可视区外;真正消除横向滚动的是单泳道档(<480px)。
    • 版本选择器只在单泳道档渲染:宽档下整个看板没有版本选择器(该元素不渲染)。因此宽档里能看到的「全部版本」只可能来自打开的下拉选项列表,而不是当前选中项;单泳道档未显式选择任何视图时,当前项是「独立目标」而不是「全部版本」。

效果截图见仓库 screenshot/sidebar-kanban.png(虚构演示数据 nebula-notes,右侧栏宽度落在 < 480px 单泳道档);本 npm 包不包含仓库的 screenshot/ 目录,故此处只给出仓库路径。


HTTP 鉴权(Web 看板的 REST 入口)

本插件在 Web 宿主里提供一组 /api/dsh-graph/** REST 入口(浏览器看板与脚本都用它)。从 g-507 起,这些入口的安全模型是单一受保护入口:

  • 一个入口,不是 63 个:插件只向宿主 webServer 注册一条 kind:"prefix"、path:"/api/dsh-graph" 的路由;原有的 63 条业务路由不再是宿主的独立路由,只在插件内部按 exact / 两条资产 prefix(/diagram、/help/asset)分发。
  • 先鉴权,后业务:入口每请求先调用宿主的公开 connection.admit(req)(保留 this 绑定),再判定调用方是否为 owner。认证之前不读请求体、不解析目标路径、不初始化工作区、不触碰任何文件与派发。
  • 拒绝面(固定口径):
    情形状态码
    匿名 / 凭证无效(宿主 401)401
    信任边界拒绝(宿主 403:Host / Origin / cross-site)403
    凭证有效但不是 owner403(not-owner)
    宿主未提供 connection 服务、未提供 admit、admit 抛错、或返回不可判定的结构503(fail-closed,不带任何内部细节)
    认证通过但路径不存在 / 方法不符404 / 405(认证之后才返回)
  • 能力依赖:判定完全依赖宿主公开能力 connection.admit。宿主没提供它时,HTTP 入口一律 503 fail-closed(不会退化成匿名放行);该情形不影响 Agent 工具面(graph_* 工具不经过 HTTP 入口)。
  • 尾斜杠与 query:/api/dsh-graph 与 /api/dsh-graph/ 不是同一路径(后者认证后 404);两条资产 prefix 的 prefix/ 会进入业务并由业务给 400(非法文件名);query 不参与匹配。
  • 实测范围(如实):本节的鉴权行为只在 DSH 0.2.1-rc.2 上实测(真实宿主 BrowserAuth + 真实 Token 交换 + 真实 HTTP)。engines.dsh 声明的其余宿主版本(含 0.1.x、0.2.0 各版本)本次未逐版验证;若某宿主缺少公开 admit,按上表 HTTP 入口会 503,这一点未经逐版核实,因此不能把声明范围读成「当前 Web 鉴权结论」。兼容范围的取舍由维护者决定,本版不做收窄或扩张。

Profile 全局设置(子代理默认值)

子代理默认 provider / model、推理档位、执行模式、提示词语言与补充提示词是 profile 级全局默认 —— 写入当前 DSH profile、跨 workspace 生效,且 workspace 的 project.yaml 明确配置与单次派发参数都更优先。

同一个设置页在两个入口都能打开,两处是同一份实现、读写同一份 profile 配置:

  • 设置 → 看板设置:左侧设置导航里的独立设置页;
  • 右侧栏 → 插件 → dsh-graph:组合包详情页里的配置区(按包名 dsh-graph 绑定)。

宿主未提供某个位面时(精简 profile / 旧宿主),对应席位自动不出现,看板与工具不受影响;两处都取不到设置服务时,页面如实提示当前 profile 未暴露设置服务,而不是假装已启用。配置文件落在 profile 的设置文档里(0.2.0 系宿主为 profile 的 cordis.patch.yml 中 dsh-graph-host 条目,0.1.6 系宿主为 $DSH_HOME/settings.yaml 的 dsh-graph 命名空间)。


数据存储说明

插件数据保存在当前工作区下的 .dsh-graph/ 目录:

  • 自动初始化:首次在工作区运行工具时自动生成数据骨架,不包含多余 Demo 数据;
  • Git 友好:所有数据由纯文本 YAML/Markdown 与只追加(append-only)的 events.jsonl 组成;
  • 事件流对账:events.jsonl 记录每一次状态流转与操作,是唯一事实来源,可通过 graph_rebuild 随时对账;
  • 多 Worktree 适配:Git Linked Worktrees 自动解析归一到主工作树的同一 .dsh-graph/ 根目录。

English

Overview

dsh-graph is a goal-oriented kanban plugin for DeepSeek Harness (DSH), bringing Graph-based Goal Management into Agent workflows.

Distributed as a single unified package (npm package name: dsh-graph), it provides both halves out-of-the-box:

  • Host Side: Exposes 53 graph_* tools to DSH Agents covering the entire goal lifecycle, along with /api/dsh-graph* REST endpoints for board projections, goal details, and mutations;
  • Client Side: A browser 2D swimlane kanban board integrated into DSH Web (the conversation.view slot) for intuitive visualization and real-time tracking.

All data is stored locally as human-readable files and an append-only event log under .dsh-graph/, making it Git-friendly, easily auditable, and collaborative.


Installation

Install the plugin using the DSH CLI:

dsh plugin --profile <profile-name> add dsh-graph

Current version: v0.23.0. Requirements: Node.js ≥ 22 (includes the precompiled core runtime). Core packages provided by the DSH host (@deepseek-ai/cordis, @deepseek-ai/schemastery, @deepseek-ai/dsh-settings) are declared under peerDependencies with peerDependenciesMeta.optional (standard DSH ecosystem convention) and provided by the host runtime without peer warnings; yaml is retained in dependencies as a plugin-specific runtime dependency, preventing duplicate core package instances.

Host compatibility range: engines.dsh and peerDependencies["@deepseek-ai/dsh-settings"] declare >=0.1.5-rc.2 <0.2.2-0 in lockstep (the -0 upper bound excludes every 0.2.2 prerelease and final release; the entire 0.2.1 line is now inside the range); engines.dsh is what host-aware markets such as dsh-market read for card display and install/update pre-flight. ⚠️ The host's install/boot gate reads peerDependencies only, never engines.dsh, so both fields must be widened together (widening engines.dsh alone has no effect). Hosts verified: 0.1.6-alpha.2 through 0.1.7-rc.2, 0.2.0-rc.1, 0.2.0-rc.2 (verified by the maintainer on 2026-09-30), and 0.2.1-alpha.2 (verified on 2026-10-09 in an isolated instance with no version exemption). ⚠️ Those are historical rounds covering install/boot/REST on their own version's product code; the HTTP authentication entry introduced by g-507 was measured on 0.2.1-rc.2 only (see "HTTP authentication" below) and must not be inferred for other versions from this paragraph. The 0.1.8 line incidentally covered by that range was never published on npm (versions jump straight from 0.1.7-rc.2 to 0.2.0-rc.1), so it is an empty set and adds no unverified claim.

Platform status:

PlatformStatus for this release
Linux / WSL2✅ Verified on-device (this release's full test suite: 0 failures; the shared H-series probes are all green on this release)
Native Windows✅ Verified on-device for this release (2026-11-02, win32/x64 + Node v24.21.0, host 0.2.1-rc.5, 22 passed / 0 failed / 0 warnings): see platform-gate §7.13 backfill table — T1 static / ledger (67 sites, 268 hits, 0 unrecorded) / dispatch capability (0 hardcoded shell names) / H combo probes (H1–H6 all green except H3) all passed; T3 kanban filesystem lifecycle 32-step assertions all passed; T4/T5 instance startup and REST auth exchange smoke passed.
macOS⏳ Not verified for this release: v0.23.0 has not run the on-device gate on native macOS ⇒ must not be read as "passed"; the verdict likewise comes from the platform-gate §7 backfill table (not shipped in the package). Earlier records are in platform-gate §7.4 / §7.7 and cover each of those versions' product code only.

All three platforms share the same package. Known limitations: (1) APFS, the macOS default, is case-insensitive — entries that differ only by case resolve to the same entity, so do not rely on case alone to distinguish goal ids or version lanes; (2) on macOS a workspace path that is explicitly supplied and contains a symlink (e.g. under /tmp or /var) is rejected with graph root symlink is not allowed; paths derived from process.cwd() are unaffected.

What's new (v0.23.0)

  • Smart Subagent Long-Task Care & Deadlock Intervention: Proactively conducts status checks on running subagent long tasks during supervisor idle intervals; automatically escalates to human intervention on consecutive unresponsiveness or stagnation without arbitrary aborts, supporting whole-group pause, resume, and reset.
  • Estimated Task Time Budgets & Dynamic Base Recalculation: Supports explicit goal-level expected time budget configuration (inheriting project/global defaults when unset); immediately recomputes care deadlines upon initial dispatch, mid-run budget edits, or new supervisor messages to running child agents, with an enforced 5-minute unanswered cooldown.
  • Run Boundary Isolation & Audit-True Budget Provenance: Groups subagent execution into distinct runs delimited by actual start/stop events; accurately records initial budgets and timeline changes without overwriting past history with terminal values, while preserving unified run identities and marking unobserved gaps across host recreations.
  • Intelligent Supervisor Context Keepalive: Automatically performs bounded renewals and single-shot AFK keepalives when child agents are running and the supervisor is idle, preventing context expiration during extended periods of inactivity.
  • Plugin HTTP API Hardening & Duplicate Dispatch Guards: Eliminates unauthenticated access risks by aligning with unified host authentication and identity allowlists; tightens dispatch admission gates to strictly prevent concurrent duplicate execution attempts for the same goal.

See the CHANGELOG for the full history. Official releases are distributed via npm and the dsh-market ecosystem.


Upgrade-residue self-check and cleanup

Symptom (externally reported): after upgrading the host, a Web GUI cold start reports web boot: N entry did not activate / <plugin>: failed — the plugin's host half (graph_* tools) works and hot reload works, but its browser half never activates.

Cause: dsh.client.inject is not a directory listing, it is a load-order edge. The browser-side loader (@deepseek-ai/dsh-client-modules/lib/client.js) preloads only those inject names that already exist in the client manifest, and silently skips the rest. @deepseek-ai/dsh-client-runtime is no longer shipped with the host since dsh 0.2.x (absent from the install trees of dsh 0.1.5-rc.2 / 0.1.7-rc.2 / 0.2.0-rc.2 / 0.2.1-alpha.2), yet its package manifest still declares dsh.client. If an old entry/copy of it survives an upgrade in your profile, it becomes a client manifest row again; that row's load failure cascades into client-modules: "<plugin>" not loaded because dependency "…" failed, dragging down every plugin that still declares it. A clean install has no such row, which is why it does not reproduce. dsh-graph has dropped that declaration — even if the residue is still present, this plugin is no longer one of its consumers.

Preferred action: just upgrade dsh-graph to a build that contains this fix — the residue needs no handling. A fixed build no longer declares the dead name, so whether or not an old copy survives in your profile, this plugin is no longer one of its consumers and can no longer be dragged down by it. The self-check below is only a read-only way to inspect the current state; cleaning up the residue is an optional advanced step.

Self-check (read-only; every command below was measured on isolated instances of dsh 0.2.0-rc.2 / 0.1.7-rc.2):

Replace <DSH_HOME> with your DSH home: for the Web build it defaults to ~/.dsh (or wherever DSH_HOME points); the desktop build uses a different path — take the profile directory shown in that shell's configuration or logs.

# (1) This plugin's declaration — expect three names, without dsh-client-runtime
node -e 'console.log(JSON.stringify(require(process.argv[1]).dsh.client.inject))' \
  "<DSH_HOME>/profiles/web/node_modules/dsh-graph/package.json"

# (2) Does the profile manifest still list it? — expect the number 0
#     (note: `grep -c` exits 1 when the count is 0 — read the printed number, not the exit code)
grep -c dsh-client-runtime "<DSH_HOME>/profiles/web/package.json"

# (3) Is there still a directory named dsh-client-runtime anywhere under the DSH home? — expect no output
find "<DSH_HOME>" -type d -name dsh-client-runtime 2>/dev/null

# (4) Optional, Web build with a running instance only: is it still a row in the client manifest? — expect no output
#     `dsh web` prints a tokenized URL on startup; paste it verbatim as <URL>
curl -sL -b "" "<URL>" | grep -o '"@deepseek-ai/dsh-client-runtime"' | head -1

Measured on an isolated instance (dsh 0.2.0-rc.2):

  • (1) → ["@deepseek-ai/dsh-client-ui-settings","@deepseek-ai/dsh-client-ui-primitives","@deepseek-ai/dsh-client-ui-sidebar-right"]
  • (2) → 0
  • (3) → no output
  • (4) → no output, while curl returned 200 with 35125 bytes (the same command does print a row name that is present in the manifest, e.g. @deepseek-ai/dsh-client-ui-settings)
  • Command-sanity counter-checks (neither command is vacuously silent): (2) prints 1 on a manifest file that really contains the name, and (3) did print the path after a directory named dsh-client-runtime was deliberately placed into the profile (removed again immediately).

Cleanup (optional, back up first): only if you really want a clean slate and (2) is non-zero or (3) has output: back up the profile first, then remove the residue directory printed by (3) (and drop the matching entry from the manifest that (2) flagged), then restart the host — client package metadata is cached at activation time, so adding/removing client plugins only takes effect after a restart. Risk note: deleting directories or editing the manifest of a live profile can break your environment; the safer alternatives are reinstalling the same dsh-graph version or creating a fresh, clean profile. Always keep a backup before doing this yourself, and restore from it if anything misbehaves.

Not verified: no desktop-shell environment is available (@deepseek-ai/dsh-desktop is E404 on npm). The symptom and cause chain above cite the external report and host source code; this README does not claim the desktop-shell symptom was reproduced.


Key Features

  • Four-Phase Lifecycle State Machine: Enforced by the core engine: draft → planning → collecting → ready → in_progress → review → delivered (with a blocked escape hatch available at any stage).
  • Criteria Before Execution: Acceptance criteria must be explicitly defined prior to execution. Deliverables in the review phase are verified strictly against individual criteria, preventing ambiguous delivery.
  • Context Cards: Supports Text, File, Image, and Data cards. Follows a structured lifecycle (empty → collecting → filled → reviewed) to seed precise task context for execution subagents.
  • 2D Swimlane Board: Columns represent lifecycle stages, while horizontal swimlanes organize goals by Version, Backlog, and Standalone categories, complete with drag-and-drop scheduling.
  • Graded Review & Policy Calibration: Configure project review parameters (review.regions, review.contract_paths, review.non_product_prefixes) via graph_get_settings and graph_update_settings. Product changes in unregistered regions safely escalate to strict; empty contract paths default to not triggering M1.
  • Relations Between Goals: Goals can be linked with four relation kinds — supersedes / amends / extends / related — and unlinked again; relations live in exactly one source of truth (the goal's frontmatter). Cards show relation badges, and the goal dialog lists the full inventory under "Goal description" (cross-version and archived peers flagged).
  • Seamless Session Handoff: Generate HANDOFF.md summarizing board projections, long-term memory, and environment facts. A new session can claim the Supervisor role idempotently via graph_claim_supervisor.
  • Modern UI & Dual-Theme Support: Full Dark and Light theme adaptation following DSH variables. Subtle pulse animations highlight external updates (with prefers-reduced-motion accessibility support); drag-safe modal text selection.

Design Philosophy (for readers new to this plugin)

To understand why dsh-graph organises development the way it does — goal lifecycle and state machine, criteria gate and human gate, dispatch and the isolation triad, attempts and the results surface, independent review and its source of truth, version lanes and release red lines, memory grading, event-first writes — read Design Philosophy (English): every behavioural claim carries a code citation, and the document ships archify interactive diagrams — an inline static preview plus an explorable HTML page — that draw only what is implemented today (state flow and role split, with no file, function or internal artifact names inside the figures; the 1.0 roadmap lives in §13).


Agent Tools Reference

dsh-graph equips Agents with a comprehensive set of graph_* tools (53 in total):

CategoryToolDescription
Goal Lifecyclegraph_create_goalCreate a goal (defaults to Backlog, optional Version)
graph_rename_goalRename goal title
graph_set_descriptionSet/update goal description body (Markdown)
graph_set_directiveInject instructions and boundaries for the upcoming attempt
graph_set_goal_typeSet goal type (feature / bug / task / improvement / patch / chore)
graph_set_goal_tagsSet goal tags (max 20, optimistic concurrency)
graph_set_goal_budgetSet/clear the goal budget (integer seconds 30–86400; empty inherits the project/global care threshold)
graph_amend_goalRecord amendments, optionally appending to description
graph_transitionAdvance goal through lifecycle states (reason required for blocked)
graph_postpone_goalPostpone goal back to Backlog as draft
graph_archive_goalArchive completed or obsolete goals
graph_unarchive_goalRestore goals from archive
graph_delete_goalSafely delete an archived goal
graph_clean_worktreeClean up a verified worktree (requires user confirmation)
graph_list_worktreesQuery Git worktree cleanup candidates (read-only, no auto-delete)
Goal Relationsgraph_set_relationMark or unmark a relation between goals (supersedes / amends / extends / related; idempotent, rejects supersede cycles)
Quality Criteriagraph_set_criteriaDefine quality criteria (required prior to execution)
Context Cards

Browser Kanban UI

Embedded directly within the DSH Web console:

  • 2D Swimlane Layout: View the progress of multiple versions and categories simultaneously;
  • Live Streaming Updates: Cards and the top status bar stream real-time execution updates; external file edits trigger visual highlights;
  • Interactive Modals & Drawers: Click cards to inspect quality criteria, context cards, attempt histories, and detailed instructions.

Sidebar Usage

The sidebar's "Kanban" tile and the conversation page's "Kanban" tab are the same implementation — the same board component and the same header / narrow-width logic, fully identical on both sides (zero host gating). Either entry point works.

  • Entry: open the right sidebar in a session → click the "Kanban" tile; the opened board then stays as a persistent tab at the top of the sidebar, one click away.
  • ⋯ Tools: Refresh / Tag filter / Memory / Project Knowledge Base (shared entries) / Board settings / Archived. The toolbar collapses into this single item automatically when it does not fit the measured header width (not a hard-coded viewport breakpoint).
  • [🏷️] Version Management: the square icon button in the corner (accessible name "🏷️ Version Management") opens the version-management drawer; immediately to its right sits Create Version, same row and equal height.
  • Version selector: sits to the left of the lane-row [+] (new goal) and switches the lane currently shown (a specific version / Backlog / Standalone).
  • Narrow-width behaviour (tiered by the measured width of the board's root container — the board element's own clientWidth, not the window width and not the browser viewport width):
    • ≥ 480px (wide tier): multiple swimlanes side by side, so versions / Backlog / Standalone are all visible at once;
    • < 480px (single-lane tier): stage columns switch from side-by-side to vertically stacked, and the lane shown is chosen by the version selector (exactly one of a specific version / Backlog / Standalone; when the workspace has no versions at all, the default landing lane is "Standalone", and the selector's current item reads "Standalone"); this tier has no per-lane collapse toggle (collapsing would leave an empty board), and it also forces the toolbar into ⋯ Tools and hides the DEBUG line.
    • How to get the board into < 480px: the host tab's width comes from the tab layout mode, not from dragging — measured at a 1600px viewport: single tab 719px, 359px per tab after the tab's Split mode (this mode scales with the window width), 799px in Fullscreen. So the default single-tab width (719px) lands in the wide tier and no single lane appears; use the tab's Split mode, or narrow the window until the board panel measures <480px. Once there, it is obvious: the six stage blocks are and the version selector appears next to the lane title (current item: a specific version / Backlog / Standalone).

See screenshot/sidebar-kanban.png in the repository for a screenshot (fictional demo data nebula-notes, sidebar width in the < 480px single-lane tier); this npm package does not ship the repository's screenshot/ directory, so only the repository path is given here.



HTTP authentication (REST entry points behind the Web kanban)

The plugin serves a set of /api/dsh-graph/** REST endpoints in the Web host (used by both the kanban UI and scripts). Since g-507 the security model is a single protected entry point:

  • One entry, not 63: the plugin registers exactly one kind:"prefix" route with path:"/api/dsh-graph". The 63 business routes are no longer host routes; they are dispatched inside the plugin as exact routes plus two asset prefixes (/diagram, /help/asset).
  • Authenticate first, business second: every request first calls the host's public connection.admit(req) (with this preserved), then checks whether the caller is the owner. Before admission it never reads the body, resolves the target path, initializes a workspace, touches files, or dispatches anything.
  • Rejection matrix (fixed):
    SituationStatus
    Anonymous / invalid credential (host 401)401
    Trust-boundary rejection (host 403: Host / Origin / cross-site)403
    Valid credential but not the owner403 (not-owner)
    Host has no connection service, no admit, admit throws, or returns an undecidable shape503 (fail-closed, no internal detail)
    Admitted but unknown path / wrong method404 / 405 (only after admission)
  • Capability dependency: everything hinges on the host's public connection.admit. When the host does not provide it, the HTTP entry points answer 503 fail-closed (never a silent anonymous pass-through); the tool surface is unaffected (graph_* tools do not go through the HTTP entry).
  • Trailing slash and query: /api/dsh-graph and /api/dsh-graph/ are different paths (the latter is 404 after admission); prefix/ on the two asset prefixes enters business handling and yields a 400 (illegal file name); query does not participate in matching.
  • Verified scope, stated plainly: the behaviour in this section was measured only on DSH 0.2.1-rc.2 (real host BrowserAuth, real token exchange, real HTTP). The other host versions declared in (including and the line) were in this round. If a host lacks the public , the table above implies 503 for HTTP entry points — that implication is , so the declared range must not be read as a current Web-authentication verdict. Widening or narrowing the range is the maintainer's call; this release does neither.

Profile-wide settings (subagent defaults)

The subagent default provider / model, reasoning effort, execution mode, prompt language and supplementary prompt are profile-wide defaults: they are written to the current DSH profile, apply across workspaces, and an explicit project.yaml value or a per-dispatch argument still takes precedence.

The same settings page opens from two places, both backed by one implementation reading and writing the same profile configuration:

  • Settings → Kanban Settings: the standalone page in the settings navigation;
  • Right sidebar → Plugins → dsh-graph: the configuration block on the bundle page (bound by the package name dsh-graph).

When the host does not expose a given seat (slim profile / older host) that seat simply does not appear and the board and tools are unaffected; when no settings service is reachable from either of them the page says so instead of pretending the settings are live. Values live in the profile's settings document (on 0.2.0-line hosts the dsh-graph-host entry in the profile's cordis.patch.yml; on 0.1.6-line hosts the dsh-graph namespace in $DSH_HOME/settings.yaml).


Data Storage

All data resides in .dsh-graph/ within your workspace:

  • Zero-Config Auto-Init: Generates directory structure automatically upon first tool call without dummy demo data;
  • Git Friendly: Managed as plain YAML/Markdown files and an append-only events.jsonl event log;
  • Auditability: events.jsonl serves as the authoritative single source of truth, reconcilable at any time via graph_rebuild;
  • Multi-Worktree Support: Git Linked Worktrees automatically resolve to the canonical graph root in the primary worktree.

License

MIT

删除未在收集中的卡片
graph_convert_card_to_shared将自有卡转换为共享卡(放入共享池)
graph_convert_card_to_owned将共享卡收回为自有卡(独占)
graph_attach_shared_card把共享池既有共享卡挂载到目标(复用已收集上下文,仅 owner/主管)
graph_detach_shared_card解除目标对共享卡的引用(卡仍留池;collecting 拒绝)
graph_list_shared_cards只读列出共享池共享卡(id/title/status/refs)
附件管理graph_store_attachment存储文件附件到目标
graph_delete_attachment删除目标附件
排期管理graph_move_goal在 Backlog、独立目标与版本之间移动排期
执行与返工graph_start_attempt派发执行 Attempt,启动并绑定可续轮子代理
graph_record_attempt_handoff记录前序 Attempt 的返工约束与排查基线
graph_unbind_goal_child安全解绑目标执行子代理
graph_abandon_attempt放弃陈旧或失联的 Attempt
graph_start_review为既有执行 Attempt 派发独立评审子代理(只读;不新建 attempt、不覆盖作者结果;结论独立落盘)
配置管理graph_get_settings查询当前 workspace 项目配置及合法枚举元信息
graph_update_settings结构化更新当前 workspace 项目配置(支持 patch)
记忆管理graph_memory_add写入按需/常驻记忆条目
graph_memory_recall按关键词检索记忆
graph_memory_remove删除指定记忆条目
graph_memory_replace替换已有记忆条目内容
状态汇报graph_report_status汇报当前 Attempt 进度(看板卡片实时显示)
graph_report_supervisor_statusSupervisor 汇报全局工作状态(顶部状态栏动画)
graph_care_outcome子代理关照巡检回传(仅绑定主管;一次性、事件先行、有证据才计数)
评审裁决graph_resolve_accept裁决交付验收(verdict: accept / object)
协作与交接graph_add_comment向目标追加可追溯的讨论与反馈历史
graph_write_results人工写入 attempt 完成摘要(source=manual + 写入者标注;无子代理的轻量改动兜底)
graph_refresh_results重写 results.md:零 LLM 兜底拼装,或采用专用摘要子代理/人工产出的 content(旧版自动归档;支持批量 goals[])
graph_handoff生成跨会话交接文档 HANDOFF.md
graph_claim_supervisor新会话接管 Supervisor 并更新会话元数据
graph_help输出插件功能说明与 53 个工具速查清单
数据与校验graph_validate执行全量不变式检查(状态、依赖环、卡片引用)
graph_rebuild从事件流完全重建目标状态并与元数据对账
graph_add_card
Create a context card placeholder (text / file / image / data)
graph_bind_collect_cardBind collection subagent; marks card status as collecting
graph_fill_cardPopulate card content with a concise board summary
graph_review_cardReview card content (filled → reviewed)
graph_delete_cardDelete cards not currently collecting
graph_convert_card_to_sharedConvert owned card to shared card
graph_convert_card_to_ownedConvert shared card back to owned card
graph_attach_shared_cardAttach an existing shared card to a goal (reuse collected context; owner/supervisor only)
graph_detach_shared_cardRemove a goal's reference to a shared card (card stays in the pool; rejected while collecting)
graph_list_shared_cardsList shared pool cards read-only (id/title/status/refs)
Attachmentsgraph_store_attachmentStore file attachments to a goal
graph_delete_attachmentDelete a goal attachment
Schedulinggraph_move_goalMove goals between Backlog, Standalone, and Versions
Execution & Reworkgraph_start_attemptDispatch an execution attempt and spawn a continuable subagent
graph_record_attempt_handoffRecord rework constraints, failure notes, and baseline
graph_unbind_goal_childSafely detach an execution subagent from a goal
graph_abandon_attemptAbandon a stale or lost attempt
graph_start_reviewDispatch an independent read-only review subagent for an existing attempt (no new attempt, never overwrites author results; conclusion stored separately)
Configurationgraph_get_settingsQuery workspace project configuration and enum metadata
graph_update_settingsUpdate workspace project configuration (supports partial patch)
Memorygraph_memory_addWrite on-demand / standing memory entries
graph_memory_recallRecall memory entries by keyword search
graph_memory_removeRemove a specific memory entry
graph_memory_replaceReplace an existing memory entry's content
Status Reportinggraph_report_statusReport progress of current attempt (live card display)
graph_report_supervisor_statusReport supervisor status (top status bar animation)
graph_care_outcomeReport a subagent-care inspection outcome (bound supervisor only; one-shot, event-first, evidence required for counting)
Review & Verdictgraph_resolve_acceptAccept or object to delivered attempts
Collaborationgraph_add_commentAppend historical discussion or human feedback
graph_write_resultsManually write an attempt completion summary (source=manual + writer annotation; fallback for subagent-less changes)
graph_refresh_resultsRegenerate results.md: zero-LLM fallback assembly, or a caller-supplied content body from the dedicated summarizer subagent / a human (previous version archived; supports a goals[] batch)
graph_handoffExport cross-session handover document (HANDOFF.md)
graph_claim_supervisorClaim supervisor role in new session & update metadata
graph_helpDisplay usage instructions and the 53-tool checklist
Validationgraph_validateValidate full invariants (states, cycles, card refs)
graph_rebuildRebuild goal state from events.jsonl and reconcile
stacked vertically
  • Residual in the wide tier (measured): the wide-tier grid's minimum width is about 956px, so whenever the board panel measures less than that (e.g. the default single tab at 719px) the wide grid still scrolls horizontally and pushes the confirm / bulk-accept column out of view; the tier that actually removes horizontal scrolling is the single-lane one (<480px).
  • The version selector is rendered only in the single-lane tier: in the wide tier the board has no version selector at all. So an "All versions" string seen in the wide tier can only come from an opened dropdown option list, never from the current selection; and in the single-lane tier, before any explicit view choice, the current item is "Standalone" — not "All versions".
  • engines.dsh
    0.1.x
    0.2.0
    not verified version by version
    admit
    not verified per version