前言¶
在 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