使用dsh-dashboard在DeepSeek Harness裏編排Linear與GitHub任務

前言

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_createbefore_runafter_runbefore_remove。Git 項目使用 detached worktree,非 Git 項目使用受控目錄。自動任務領取始終關閉:註冊或掃描到其他 Project,只是寫入 Catalog,不會跨項目自己領票。

4、原生側欄裏的 Dashboard。通過 sidebar.footer.actionshell.overlay 掛上去,不替換現有側欄。四個視圖分別是 Board(列、篩選、任務詳情)、Runtime(運行 / 重試 / 阻塞、turn、token、worker host)、Projects(持久化 Catalog、掃描確認)和 Configuration(最後有效 workflow、憑據健康、併發與 turn 上限)。標題旁的 Provider · Project 是動態上下文,例如 Linear · ENGGitHub · openai/exampleLocal · 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,並填 ownerrepo。下面摘自官方 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_EMAILJIRA_API_TOKEN
  • Asana:ASANA_ACCESS_TOKEN
  • GitLab:GITLAB_TOKEN

也可以把同名引用寫進 $DSH_HOME/.credentials.yaml。不要提交這個文件,也不要把真實 token 寫進日誌。Configuration 視圖只顯示引用名稱、是否已配置、憑據來源,不會把密鑰送到瀏覽器。

Prompt 部分用 Liquid 模板。可以引用 issue.identifierissue.titleissue.descriptionissue.stateissue.labelsissue.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

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

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

小夜