前言¶
用 DSH Web GUI 做智能體開發時,一個常見的彆扭之處是工作區只有一個:代碼在一個目錄,數據集在另一個目錄,參考資料又在第三處。想讓 agent 跨這些目錄工作,要麼手動把文件搬進同一個工作區,要麼乾脆不讓 agent 碰它們。
dsh-multi-root 針對的就是這個問題。下面介紹這個插件:它在側邊欄加一個 Roots(多根)面板,允許把任意數量的獨立文件夾掛載爲工作區根目錄,再通過一組受控的 host 端工具,讓 agent 在這些根之間 list / read / write / glob——思路接近 VS Code 的 multi-root workspace。
這是什麼¶
dsh-multi-root 是 DeepSeek Harness(DSH)Web GUI 的多根工作區插件,由 luoyu-xingu 維護,當前版本 0.1.1,MIT 許可證。
它以 cordis profile bundle 的形式激活在 web profile 中,熱插拔,不需要修改 DSH 源碼——這也符合 DSH「一切皆插件」的設計。幾條基本約定先交代清楚:
1、所有根平等,沒有主工作區之分;根集合由所有會話與 agent 共享。
2、GUI 與 agent 共享同一份根目錄存儲。
3、UI 文案雙語(zh / en),跟隨文檔語言。
核心功能¶
根目錄管理¶
- 側邊欄
Roots(多根)入口,點擊後中央欄切換爲管理面板。 - 掛載任意數量的文件夾:可以直接輸入路徑,也可以用 host 目錄瀏覽器選擇(Windows 從盤符級開始,Linux/macOS 從 home 目錄開始),每個根可配一個可選的顯示別名。
- 支持重命名、移除、排序根目錄;每一行顯示即時目錄狀態(
available/directory missing)。 - 根目錄持久化在
~/.dsh/dsh-multi-root.json:所在目錄權限 0700,文件權限 0600,原子寫入。
註冊給 agent 的工具¶
插件向 DSH 工具管線註冊五個工具,全部限定在已註冊的根內操作:
| 工具 | 作用 |
|---|---|
workspace_roots |
列出所有已掛載的根(id、name、path、status) |
workspace_root_list |
列出某個根內的一個目錄 |
workspace_root_read |
讀取根內的文本文件,256 KB 上限並報告截斷 |
workspace_root_write |
寫入或覆蓋根內的文本文件,自動創建父目錄 |
workspace_root_glob |
在根內做 glob 匹配,結果封頂 |
面向 agent 的通告與配置¶
插件會在系統提示詞中加一段內容,向每個 agent 通告自身及上述工具;不想通告可以關掉。host 端配置經 schemastery 校驗,共三項:
multi-root:
enabled: true # 路由、工具、提示詞段落的總開關
announceToAgent: true # 系統提示詞通告開關
hotReload: true # host 半部監聽自身 lib/,重建後重掛載
安裝與啓用¶
推薦從 npm 安裝,任意平臺可用:
# 1. 把插件裝入 web profile
dsh plugin --profile web add @luoyu_xingu/dsh-multi-root
# 2. 啓動 Web GUI(Ctrl+C 停止,--port 可改默認端口)
dsh web
打開 dsh web 打印的地址,默認是 http://127.0.0.1:3080。側邊欄出現 Roots(多根)入口即說明生效,也可以用下面的命令確認安裝:
dsh plugin --profile web ls @luoyu_xingu/dsh-multi-root
升級和移除:
dsh plugin --profile web update @luoyu_xingu/dsh-multi-root
dsh web # 升級後重啓
dsh plugin --profile web remove @luoyu_xingu/dsh-multi-root
如果想從源碼安裝:
git clone https://github.com/luoyu-xingu/dsh-multi-root.git
cd dsh-multi-root
pnpm install
pnpm build
# file: 方式裝入 checkout 的絕對路徑,profile 內保存自包含副本
dsh plugin --profile web add file:<checkout 絕對路徑>
# Windows 示例:
dsh plugin --profile web add file:E:/dsh_plugins/dsh-multi-root
改了代碼重新構建後,先把新的 lib/ 同步進 profile 裏的自包含副本,再重啓:
pnpm build
# PowerShell:
Copy-Item lib\* $env:USERPROFILE\.dsh\profiles\web\node_modules\@luoyu_xingu\dsh-multi-root\lib\ -Recurse -Force
# bash:
cp -r lib/* ~/.dsh/profiles/web/node_modules/@luoyu_xingu/dsh-multi-root/lib/
dsh web # 重啓
有一點務必注意:安裝或每次重建後都要重啓 dsh web。web profile 禁用了 cordis HMR,文件變更不會熱加載;host 還會校驗 bundle revision 與啓動文件哈希,舊進程對舊 revision 一律返回 404(bundle script ... failed to load)。
典型用法¶
經過上面的步驟,日常使用只有三步:
1、點擊側邊欄 Roots 入口。
2、用路徑輸入或 Browse 對話框掛載文件夾(Windows 先選盤符),按需給每個根起別名。
3、直接讓 agent 跨文件夾幹活——agent 會先用 workspace_roots 發現根,再用其他 workspace_root_* 工具在其中操作。
如果你要參與開發,倉庫提供了三條命令:
pnpm typecheck # tsc -b + 測試 tsconfig 的類型檢查
pnpm test # vitest run
pnpm build # 聲明文件 + lib/(node 半部與 client bundle)
安全模型¶
這個插件刻意繞過了 DSH 的文件沙箱:所有操作以 host 進程權限運行,信任邊界就是根集合本身。具體約束如下:
- 根只能由用戶在 GUI 中掛載,agent 永遠不能掛載或移除根。
- 路徑防逃逸:所有路徑相對根拼接、經
fs.realpath規範化,且必須落在註冊根之內;..、絕對路徑、盤符以及 symlink 逃逸在讀寫時均被拒絕,寫入時還會額外校驗解析後的父目錄;glob 不跟隨符號鏈接。 - 輸出限額:讀取 256 KB、寫入 5 MB、列目錄 500 條、glob 結果 1000 條,保證模型拿到的內容有界。
- 所有
/api/dsh-multi-root/*路由僅限 loopback 並帶瀏覽器同源標記,LAN 暴露的部署訪問不到這些路由。 - 存儲文件不含機密,但仍以 0600 權限原子寫入。
- 已知限制:工具以 host 用戶權限運行並佔用真實磁盤;覆蓋已存在的文件前,agent 需先與用戶確認;目錄瀏覽器會列出 host 目錄(按設計僅限 loopback,它是選擇器的數據來源)。
適用場景與注意事項¶
適合的場景很直接:文件本來就分散在多個目錄,不想爲了 agent 把它們搬進單一工作區,又希望 agent 能在明確劃定的範圍裏讀寫。
使用前有兩件事要清楚:
1、插件以當前 dsh 進程的權限運行,相當於給 agent 打開了這些根目錄下真實的磁盤讀寫通道。掛載哪些根、掛載多大範圍,是你要做的信任決策。
2、安裝前建議檢查源碼與許可證。倉庫以 MIT 發佈,代碼在 GitHub 上公開;運行環境要求 Node ^22.19.0 || >=24.0.0,peer 依賴爲 @deepseek-ai/dsh-* ^0.1.0-rc.6 與 react/react-dom ^18.2.0,另依賴 fast-glob ^3.3.3。
小結¶
dsh-multi-root 用一個插件補上了 DSH Web GUI 在多工作區上的缺口:掛載與管理在側邊欄完成,agent 側通過五個 workspace_root_* 工具受控訪問,路徑校驗、輸出限額、路由限制都在插件內部閉環,全程不需要改 DSH 源碼。
- GitHub:https://github.com/luoyu-xingu/dsh-multi-root
- 社區目錄頁:https://www.skillhub.cn/plugins/luoyu-xingu/dsh-multi-root
需要說明的是,社區目錄爲獨立站點,與 DeepSeek、幻方無官方從屬關係。