dsh-branch-tree:把 DSH 會話當文件夾,派生獨立分支並在左側建樹

前言

在 DSH(DeepSeek Harness)裏做 agent 調試時,最常見的需求不是一直聊下去,而是「換一條路再試一次」。原生會話列表是一條平鋪的線:你想開條新分支的時候,通常只能新開一個會話,把上下文重新粘一遍,或者手動翻歷史。dsh-branch-tree 解決的就是這件事——把左側工作區的會話列表變成一棵樹,母會話是可展開的文件夾行,分支是掛在它下面的縮進子行。

它由 YB313(Yige Bao)維護,分類是工作流,GitHub 倉庫目前 1 個 star,許可證 MIT,當前版本 v1.3.1。只提供一個 client.js,在 web 客戶端側加載,沒有構建步驟。

這是什麼

一句話:dsh-branch-tree 是 DSH 的一個 web 端插件,把會話列表改造成樹,並提供「派生分支」能力,分支可選擇從母會話繼承多少記憶。

它不做合一:拖拽只改樹結構,不拼接對話;母會話之後的修改也不會同步進分支。

核心功能

三種繼承模式

創建分支時可以在三種模式裏選,決定分叉點和繼承到什麼:

模式 分叉點 分支繼承到什麼
全景繼承(full,默認) 母會話最後一次真實對話處 到該點爲止的全部對話,逐字複製進分支會話
壓縮繼承(inherit) 空會話 母會話到目前爲止的壓縮摘要,作爲分支自己的第一條消息寫入,原始歷史一條都不帶
開頭繼承(opening) 母會話第一輪結束處 只繼承最初的需求消息,不含之後的對話

默認給全景,理由是分支的意義是接着試:摘要有損,丟掉的恰好是讓分支有用的細節——已否決的方案、只說過一次的需求、約束的原話。

實現上的幾個坑,README 也寫明瞭:

  • 分叉點過濾注入塊:宿主注入的內容(運行上下文、技能目錄、時間上下文、記憶前置說明)不算對話,判輪次時過濾掉,切口落在助手真正說過的最後一句回覆上。
  • 空殼檢測:宿主有可能「成功」建出一個 0 事件的分支。插件讀子會話的繼承事件數,爲 0 就先不帶邊界重 fork 一次;仍然爲 0 就在行上標記 emptyFork,不裝作成功。
  • 壓縮繼承不污染母會話:摘要在一次性的臨時 scratch 會話裏生成,母會話自己不會插入提示語。摘要作爲種子消息寫進分支,帶 <!-- dsh-branch-tree:seed ... --> 標記。
  • 壓縮兜底:模型超時或答得不含摘要小節時,自動退回機械摘要(逐輪截斷的對話記錄,≤12k 字)。

明確的邊界

  • 不合並對話。拖動會話只重掛載樹結構(宿主支持 workspaces.create 時可能建子工作區目錄),兩個會話不會被拼接、共同摘要或合併。
  • 不與母會話聯動。母會話之後的編輯不同步進已存在的分支。
  • 不復制 md 文件。每個分支實時讀取同一批 md,母會話改了需求,分支下次讀取即生效。

本地狀態

樹結構、摺疊狀態、當前會話提示、分支任務狀態、分支計數顯隱、歸檔/隱藏標記,全部存 localStorage 前綴 dsh.branch-tree. 下。清掉只會重置視圖,不動任何會話數據。

安裝與啓用

DSH 以 profile package 形式加載插件,官方給了兩條路。挑一條:

# 本地 checkout(README 裏開發用的就是這條)
dsh plugin --profile web add /absolute/path/to/dsh-branch-tree

# GitHub tag 的 tarball(不需要本機 git)
dsh plugin --profile web add https://github.com/YB313/dsh-branch-tree/archive/refs/tags/v1.3.1.tar.gz

裝完重啓 web GUI(或刷新頁面),再看左側工作區。卸載:

dsh plugin --profile web remove dsh-branch-tree

注意:未發佈到 npm,目前只有 GitHub tarball 和本地路徑。插件是 web 客戶端插件,需要帶 web 能力的 profile,宿主側依賴 dsh.client.inject 聲明的五個包:@deepseek-ai/dsh-client-ui-sidebar、@deepseek-ai/dsh-client-ui-conversation、@deepseek-ai/dsh-client-ui-primitives、@deepseek-ai/dsh-api-session-controller、@deepseek-ai/dsh-api-workspace-files。

典型用法

1、在會話行的右鍵菜單點 + 派生分支…(分支行上是 + 子分支…),起名、選繼承模式、創建。

2、點文件夾行展開或摺疊它的分支。

3、拖拽調整歸屬:把會話拖到文件夾行上即重掛載,拖到工作區標題即移過去。拖拽不合並內容。

4、分支樹面板支持搜索、查看每個分支的任務狀態、重命名、歸檔/取消歸檔、「移出樹」和診斷。

5、分支產物默認落在 製圖/<母會話>/<分支>/。

樹接管了原生的側邊欄會話入口。如果宿主掛載點拋異常,插件會把 dsh.branch-tree.takeover 置爲 off,讓原生列表繼續工作;可以在 localStorage 裏把它改回 on 再試。

適用場景與注意

適合在 web 端調試 agent 的人:想在不改母會話的前提下開條新路,或者想把「正着聊一遍、歪着再試一遍」的多輪實驗的從屬關係留在側邊欄裏。README 寫的是在 dsh 開發者預覽版下驗證的,宿主仍在變動,建議跟上版本的 install 命令一起覈對。

需要提醒的是,插件以當前 dsh 進程的權限運行,能讀寫它能力範圍內的會話與工作區文件;安裝前通讀一遍 client.js 源碼和 MIT 許可證是必要的。GitHub 倉庫 1 個 star,基本是個人維護項目,升級和兼容性風險由你自行評估。

小結

dsh-branch-tree 做的事很窄也很具體:把側邊欄從列表變成樹,加一個可控記憶跨度的派生分支入口,同時明確劃清「不合並、不聯動、不復制文件」的邊界。如果你覺得分支這件事值得顯式看見,可以試試;如果只是想平鋪聊天,原生列表就夠了。

目錄頁:https://www.skillhub.cn/plugins/YB313/dsh-branch-tree
GitHub:https://github.com/YB313/dsh-branch-tree

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

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

小夜