前言¶
DeepSeek Harness(简称 dsh)是 DeepSeek 开源的 Agent 运行时,核心理念是「一切皆插件」:模型、工具、会话、沙箱、调度和界面都可以用插件替换或组合。官方仓库目前仍处于 developer preview,接口还会变。社区里有人把各类插件整理到独立站点 DeepSeek Harness 插件库,它和 DeepSeek / 幻方没有官方从属关系,安装命令要以目录页原文为准。
日常用 dsh 写代码时,真正花时间的往往不是打开一次会话,而是把 Linear、GitHub Issues、Jira 里已经排好的票,一张一张交给智能体,再盯着它跑完、失败重试、换工作区。OpenAI 开源的 Symphony 做的就是这件事:轮询任务源、为每张票建隔离工作区、按 WORKFLOW.md 派发 Agent,失败则退避重试。dsh-dashboard 把这套编排契约接到了 DeepSeek Harness 上,并且看板直接嵌在原生侧栏里,不必另开一套控制台。
下面介绍这个插件是什么、能做什么、怎么装、WORKFLOW.md 怎么写,以及使用时必须注意的边界。
这是什么¶
dsh-dashboard 是一个工作流与自动化插件,由 Uddoo 维护,仓库地址是 Uddoo/dsh-dashboard,许可证为 MIT,主要语言是 TypeScript。目录页收录于 2026-08-15,截至 2026-08-18,GitHub 星标为 3。npm 包当前版本是 0.7.0,仓库声明针对 DeepSeek Harness Web profile 0.1.0-rc.6 编译和测试。
一句话定位:它把 Linear、GitHub Issues、Jira Cloud、Asana、GitLab 或 Host 本地任务,转成相互隔离的 Harness Agent 运行,同时保留原生 shell、侧栏、会话、工具、模型选择和权限系统。
它复刻的是 Symphony 的编排契约,而不是把 Elixir/OTP 实现嵌进 dsh。README 写得很清楚:TaskSource 负责 Provider 边界,HarnessAgentRunner 把执行和续跑映射到 Harness 原生 session,看板则把运行观测信号做成 Linear 风格的 Board。上游参考是 openai/symphony。
核心功能¶
插件能力可以分成任务源、调度、工作区和看板四块。
1、多任务源,但一份 WORKFLOW.md 只激活一个。支持 Linear 项目 Issue、GitHub 仓库 Issue(明确排除 Pull Request)、Jira Cloud 项目 Issue、Asana 项目 Task、GitLab 项目 Issue,以及不需要凭据的 Local 任务。切换 tracker.kind 之后,只有新工作流通过完整校验并热更新成功,看板上下文和调度来源才会跟着变。无效热更新会被拒绝,最后一个有效定义继续生效。
2、确定性调度。符合条件的任务按优先级、创建时间和标识符排序;可以要求必需标签;可以设全局并发,也可以按状态设并发。失败运行使用有上限的指数退避,每次派发前会重新核对任务源状态。Linear 的 blocks 关系和 Jira 的 “is blocked by” 在可用时会投影成 blocker。查询结果里暂时缺失的任务会停跑,但不会被当成终态,避免一次瞬时查询把工作区清掉。
3、每个任务一个持久工作区,并带生命周期 Hook。可配置 after_create、before_run、after_run、before_remove。Git 项目使用 detached worktree,非 Git 项目使用受控目录。自动任务领取始终关闭:注册或扫描到其他 Project,只是写入 Catalog,不会跨项目自己领票。
4、原生侧栏里的 Dashboard。通过 sidebar.footer.action 和 shell.overlay 挂上去,不替换现有侧栏。四个视图分别是 Board(列、筛选、任务详情)、Runtime(运行 / 重试 / 阻塞、turn、token、worker host)、Projects(持久化 Catalog、扫描确认)和 Configuration(最后有效 workflow、凭据健康、并发与 turn 上限)。标题旁的 Provider · Project 是动态上下文,例如 Linear · ENG、GitHub · openai/example、Local · Personal。
另外还有几条实现上的硬约束,写文章时不能略过:外部凭据始终留在受信任 Host,不会进入 Dashboard 的 RPC payload 或浏览器状态;浏览器只拿到受约束的状态投影,操作面是 Pause/Resume、Stop、Refresh、Catalog 以及 Local 任务维护;agentProfile.permissionPreset 必须显式填写,随包默认用已有的 workspace-write,无人值守编排不会静默抬权限。
安装与启用¶
运行环境按仓库 README:Node.js 22.19+ 或 24+;从源码构建时用 pnpm 11.19+;DeepSeek Harness Web profile 0.1.0-rc.6;还需要一个已经存在的 Harness permission preset。远程 Provider 需要对应凭据,Local 任务不需要。
目录页给出的安装命令如下,在 DeepSeek Harness 终端里运行即可:
dsh plugin add github:Uddoo/dsh-dashboard
目录页同时提醒:插件以当前 dsh 进程的权限运行,安装时可能执行代码。安装前请检查源代码仓库和许可证。如果需要可复现安装,按页面写法固定 commit 哈希:
dsh plugin add github:Uddoo/dsh-dashboard#commit
把上面的 commit 换成仓库里实际的提交哈希,不要用字面量 commit。
GitHub README 还提供了 npm 包安装方式,并明确指定 Web profile 和版本 0.7.0。npm 包含预构建的 Host 与浏览器入口,不需要授予安装时构建权限:
dsh plugin --profile web add dsh-dashboard@0.7.0
dsh web --dump-config
dsh web
没有全局 CLI 时,可以用官方包拉起同一套命令:
npx --yes @deepseek-ai/dsh@0.1.0-rc.6 plugin --profile web add dsh-dashboard@0.7.0
npx --yes @deepseek-ai/dsh@0.1.0-rc.6 web --dump-config
npx --yes @deepseek-ai/dsh@0.1.0-rc.6 web
打开 dsh web 打印出来的地址,在原生侧栏选择 Dashboard。卸载:
dsh plugin --profile web remove dsh-dashboard
插件默认配置在包内的 cordis.patch.yml。Web profile 里至少要配当前项目根目录、WORKFLOW.md 路径,以及显式的 permission preset。下面是 README 中的覆盖示例(路径按仓库原文,开发验证主机是 Windows):
- id: dsh-dashboard
config:
currentProject:
root: C:\work\my-project
policyPath: WORKFLOW.md
registerInCatalog: true
agentProfile:
id: default
permissionPreset: workspace-write
workerHost: workstation-01
policyDefaults:
pollingIntervalMs: 5000
workspaceRoot: .dsh-dashboard/workspaces
hookTimeoutMs: 60000
maxConcurrentAgents: 10
maxTurns: 20
maxRetryBackoffMs: 300000
currentProject.root 是 Harness 选中的项目根;相对路径从 Harness 进程工作目录解析。agentProfile.id 必须和 WORKFLOW.md 里的 project.agent_profile 完全一致。discovery.roots 可以给 Catalog 指定受限扫描根目录,每项需要绝对路径,maxDepth 范围是 1 到 8;扫描到的候选未经确认不会写入 Catalog。
典型用法¶
先决定任务源。仓库给了完整示例:默认的 WORKFLOW.example.md 面向 Linear,另外还有 GitHub、Jira、Asana、GitLab 和 Local 各一份。version 当前必须为 1。
不想接外部 Tracker 时,用 Local 最直接。下面摘自官方 examples/WORKFLOW.local.md:
---
version: 1
project:
name: personal
agent_profile: default
tracker:
kind: local
provider:
project_id: personal
context_label: Personal
required_labels: []
active_states: [Todo, In Progress, Human Review]
terminal_states: [Done, Canceled]
policy:
polling:
interval_ms: 5000
workspace:
root: .dsh-dashboard/workspaces
hooks:
timeout_ms: 60000
agent:
max_concurrent_agents: 3
max_turns: 20
max_retry_backoff_ms: 300000
dashboard:
visible_states: [Backlog, Todo, In Progress, Human Review]
---
Work on {{ issue.identifier }}: {{ issue.title }}.
{{ issue.description }}
Local 模式下,每个可见列标题会出现 Linear 风格的 +,可以直接建任务、改标题和描述、切状态、设优先级、删除。任务由 Host 侧 JSON 文件保存,默认路径是 ~/.dsh-dashboard/tasks.json,不走浏览器 localStorage。写入串行执行,用同目录临时文件再原子 rename。编辑会带上打开时的版本,Agent 或其他编辑器已经改过就会被拒绝。Dashboard 删除只去掉任务记录,已经存在的 Agent workspace 会留下来。
如果任务已经在 GitHub Issues 里,把 tracker.kind 换成 github,并填 owner、repo。下面摘自官方 examples/WORKFLOW.github.md:
tracker:
kind: github
provider:
owner: your-org
repo: your-repository
context_label: ENG
state_labels:
Backlog: status:backlog
Todo: status:todo
In Progress: status:in-progress
Human Review: status:review
Done: status:done
required_labels: []
active_states: [Todo, In Progress, Human Review]
terminal_states: [Done, Canceled]
GitHub 和 GitLab 用 state_labels 把工作流状态名映射到仓库标签。名称和某个已声明状态完全相同的标签也会被识别。没有匹配标签的打开 Issue 回退到第一个 active state,没有匹配终态标签的关闭 Issue 回退到第一个 terminal state。Jira 直接用原生 status 名;Asana 用任务所在 Section,已完成任务走第一个终态。
远程 Provider 的凭据只设当前用到的那一组。README 给出的环境变量名是:
- Linear:
LINEAR_API_KEY - GitHub:
GITHUB_TOKEN - Jira Cloud:
JIRA_EMAIL、JIRA_API_TOKEN - Asana:
ASANA_ACCESS_TOKEN - GitLab:
GITLAB_TOKEN
也可以把同名引用写进 $DSH_HOME/.credentials.yaml。不要提交这个文件,也不要把真实 token 写进日志。Configuration 视图只显示引用名称、是否已配置、凭据来源,不会把密钥送到浏览器。
Prompt 部分用 Liquid 模板。可以引用 issue.identifier、issue.title、issue.description、issue.state、issue.labels、issue.url 以及重试次数 attempt。Agent 在配置的 max_turns 内续跑同一个 Harness session;attempt 有值时,官方示例会要求从当前工作区和会话接着做,而不是把已经完成的调查重来一遍。
生命周期 Hook 在任务工作区里作为受信任的本地命令运行,审核标准应当和构建、部署脚本一样。当前项目是 Git 仓库时,after_create 执行前工作区已经是 detached worktree,不要在 Hook 里再 clone 一次。非 Git 项目拿到的是受控空目录,需要初始化就写在 after_create 里。after_create 失败会删掉不完整工作区,方便下次重新初始化;before_remove 结束后还会再解析一次删除目标,Hook 期间 root 或目标变了就不会清。
适用场景与注意事项¶
适合已经在用 DeepSeek Harness Web UI,并且希望按任务源状态自动派发 Agent 的人。典型用法有三类:
1、团队票在 Linear / Jira / Asana / GitLab,希望按状态列把「该跑的票」交给隔离工作区里的 Agent,并在同一个 Harness 界面里看 turn、token 和阻塞原因。
2、仓库用 GitHub Issues 做任务板(注意:Pull Request 不在任务范围内),用标签映射 Todo / In Progress / Review。
3、先不接外部系统,用 Local 看板自己建票,验证 WORKFLOW.md、Hook 和并发限制。
使用前有几条边界必须看清楚。
插件以当前 dsh 进程权限运行。目录页和 README 都要求安装前检查源码与许可证。Hook 能在工作区里执行本地命令,权限模型上应当按「这段脚本会出现在构建流水线里」来审查。
兼容性声明比安装命令更严。package.json 对多数 Harness peer 的范围是 >=0.1.0-rc.5 <0.2.0,但 Project Catalog 依赖的 dsh-storage / dsh-storage-domain 要求 >=0.1.0-rc.6 <0.2.0,完整运行基线是 Web profile 0.1.0-rc.6。仓库明确说:不能只凭 semver 假定兼容 rc.7 或后续 0.1.x,需要重新 typecheck、测试、打包,并在隔离的 DSH_HOME 里做一次安装和 smoke test。未声称兼容 <rc.6 或 >=0.2.0。
开发与验证主机是 Windows。兼容性文档写明:未声称已在 Linux / macOS 上完成 Hook、符号链接和路径清理的实机测试;实现里保留了跨平台路径逻辑,但实机证据目前停在 Windows。Workspace root 和任务目录必须是真实目录,不能是符号链接。
远程 Provider 的自动化测试用的是 mock API。仓库未声称已用真实 GitHub、Jira、Asana、GitLab 凭据做过写入或长期无人值守 burn-in,真实凭据要由部署者自己验证。GitHub 任务范围是 Issue,不含 Pull Request。
执行面始终绑在 Harness 选中的 currentProject 上。Catalog 可以登记多个 Project,但自动领取保持关闭,不会自己跨项目抢票。这和「打开看板就能同时喂一堆仓库」不是一回事。
小结¶
dsh-dashboard 解决的是 dsh 里一张一张手工喂票的问题:用 WORKFLOW.md 描述任务源、状态、并发和 Prompt,由 Host 侧编排器按规则派发隔离的 Harness Agent,看板仍留在原生侧栏。它受 Symphony 启发,但跑的是 Harness 自己的 session、权限和 UI slot,而不是另一套 Elixir 运行时。
社区插件目录页:https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-dashboard/
源码与完整配置说明:https://github.com/Uddoo/dsh-dashboard
安装前先看许可证和源码,需要可复现环境时固定 commit 或 npm 版本 0.7.0,并把 Harness 版本对到仓库声明的 0.1.0-rc.6。