前言¶
DeepSeek Harness(DSH)的理念是「一切皆插件」,但按官方鏈路,寫進 dsh.profile.bundles 的 bundle 會隨進程啓動加載、長期駐留。想臨時停用一個第三方插件,就得改 profile manifest、再重啓。同時 DSH 有一條關鍵架構要求:可選第三方插件只能放在 dependencies,不得寫入 dsh.profile.bundles——也就是說,官方靜態層並沒有給這類插件提供運行時啓停的位置。
dsh-bundle-manager 補的就是這一環:它經 Loader API 在進程內掛載/卸載 bundle 行,即時生效、無需重啓、不改寫 profile manifest,並提供命名預設與自愈式失敗回退。下面逐項介紹。
這是什麼¶
dsh-bundle-manager 由 KaramachiA217 維護,MIT 許可證,定位是 DeepSeek Harness 可選第三方插件包的運行時掛載管理器。安裝後它自己作爲框架 bundle 進入官方靜態層,並在設置頁提供「插件掛載管理」區塊;被管理的第三方插件則只放在 dependencies 裏,由它在運行時掛載。
兩條架構約束先交代清楚:
- 可選第三方插件只能放在
dependencies,不得寫入dsh.profile.bundles; - 本插件是唯一在運行時掛載這些插件的框架 bundle。
核心功能¶
草稿開關與一次性應用¶
在設置頁的本地草稿中切換插件開關,點擊 Save & Refresh 一次性應用整張表:主機側 diff 出需要創建/移除的掛載並持久化,隨後硬刷新頁面,使客戶端半部對齊。apply 走串行隊列,單次上限 30 秒。
命名預設¶
可以把當前草稿組合保存爲命名預設:未提交的切換會合並進快照,保存新名稱的預設會自動激活。之後從下拉框切換預設即可;刪除支持多選,帶不可逆確認,並拒絕刪除 default 預設與當前活動預設。
自愈式失敗回退¶
壞插件不會拖垮其他插件:出錯的插件落入 Failed 分組(含 kind、嘗試次數、錯誤信息),其餘插件繼續工作。內置 20 秒掛載看門狗;啓動時按分組並行,組數由 DSH_PM_BOOT_GROUPS 控制,取值 1–8。
安全機制¶
framework 白名單保護核心 bundle(標記爲 framework-protected);註冊表原子寫入並保留 .bak 最近可用副本;支持自動舊路徑遷移。
與官方靜態層雙軌共存(v0.5)¶
v0.5 引入了官方靜態層(dsh.profile.bundles)與 bm 運行時層之間的可逆切換:
- import-to-bm:把靜態層裏的插件導入 bm,交給運行時管理;
- export-to-bundles / export-all-to-bundles:把 bm 管理的插件導出回官方靜態層,後者可作爲移除 bm 前的安全網批量導出全部。
被靜態層覆蓋的插件在 bm 中只讀顯示爲 superseded-by-static。導入/導出會編輯 profile manifest,是「永不改寫 manifest」規則的三個顯式例外,且全部走 A 級冗餘:原子寫入 + .bm.bak 備份 + JSON.parse 回滾、一鍵批量回滾、依賴組提示、框架硬保護。
注意:軌道切換(導入/導出)需要重啓;bm 運行時層自身的掛載/卸載是零重啓。
卸載半程(v0.5)¶
卸載分兩步:先由 bm 註銷註冊表行(只清 bm 自有文件,不動 manifest),再引導執行官方 dsh plugin remove pkg...(支持批量)。先清註冊表行是爲了保持可逆:若官方移除失敗,包降級爲休眠依賴(已安裝、空閒),可在設置頁重新開啓(重寫註冊表行)恢復管理。另有響應式 GC,清理繞過 bm 被外部移除的包的註冊表行,並記錄一條可見的 failed 條目。
圍欄 API¶
上述能力經圍欄 API /bundle-manager/api(browser-trust fence)暴露,共十個接口:list、apply、preset/save、preset/switch、preset/delete、import-to-bm、export-to-bundles、export-all-to-bundles、import/rollback、uninstall。
安裝與啓用¶
用官方 CLI 安裝,一步完成依賴添加,隨後 reconcile 會把包追加到 dsh.profile.bundles:
dsh plugin --profile <profile-name> add dsh-bundle-manager
安裝後 CLI 生成的 profile 佈局形如:
{
"dependencies": { "dsh-bundle-manager": "^0.5.3" },
"dsh": { "profile": { "bundles": ["dsh-base", "dsh-web-app", "dsh-settings-ui", "dsh-bundle-manager"] } }
}
升級時重新運行並加 @latest:
dsh plugin --profile <profile-name> add dsh-bundle-manager@latest
運行環境要求 Node >= 20;peerDependencies 包含 dsh-settings-ui >=0.3.0、@deepseek-ai/cordis >=4.0.0-rc.0、@deepseek-ai/dsh-host-webserver >=0.1.0-rc.0、@deepseek-ai/dsh-client-runtime >=0.1.0-rc.0、@deepseek-ai/dsh-client-ui-slots >=0.1.0-rc.0。
本地開發與測試¶
本地開發時,先用 npm pack 構建 tarball,再用官方 CLI 安裝本地包(或 file: 依賴),每次改動需重新打包:
npm pack
dsh plugin --profile <profile-name> add ./dsh-bundle-manager-<ver>.tgz
已知差異:在 rc.6 上 link: 掛載會因 ESM 解析失敗,請改用 file: tarball。
測試與 CI 各有一條命令:
npm test # 離線迴歸,210 斷言,mock ctx 驅動圍欄 API
npm run ci # 5 步門禁:語法 + 測試 + 密鑰掃描 + 淨化 + 打包白名單
兼容性¶
- dsh 0.1.0-rc.5:已在官方桌面 shell(僅框架 bundle)驗證。
- rc.6(2026-08-17 驗證):與 rc.5 同上遊提交
47f9438,運行時掛載/卸載、framework 白名單、失敗隔離、預設、註冊表持久化與客戶端半部均零代碼適配通過。 - rc.7(2026-08-19 驗證):bm 唯一使用的 kit 面
settings.section在 rc.7 上不變;kit 鎖定 npm 發佈版dsh-settings-ui@0.2.22,不依賴 kit 0.3.0 的pluginCard/settingsScope。
完整中文手冊見倉庫的 MANUAL.md。
適用場景與注意事項¶
適合的用戶:
- 需要頻繁啓停第三方插件、不想每次改 manifest 再重啓的 DSH 用戶;
- 想把不同插件組合保存爲預設、按任務一鍵切換的用戶;
- 想先在 bm 運行時層試用靜態層插件、再決定是否固化(或反向導出)的用戶。
使用前注意:
- 軌道切換(import-to-bm / export-to-bundles / export-all-to-bundles)需要重啓,且是「永不改寫 manifest」的僅有的三個例外;bm 運行時層的掛載/卸載零重啓。
- apply 爲串行隊列、30 秒上限;預設刪除是不可逆操作,
default與當前活動預設受保護。 - 家族單軌說明:其他第一方家族插件(mcp / search / proxy / skill / balance 等)保持 dependencies-only 單軌,由 bm 在運行時掛載,不參與導入/導出;雙軌是面向外部用戶的可選增強。
- 插件以當前 dsh 進程權限運行,安裝前應檢查源碼與許可證。
小結¶
dsh-bundle-manager 把第三方插件的啓停從「改 manifest + 重啓」變成設置頁裏的一次點擊,失敗隔離與雙軌共存讓試錯成本可控。如果你的 DSH profile 裏插件較多,值得一試。
- 社區目錄頁(獨立站點,與 DeepSeek / 幻方無官方從屬關係):https://www.skillhub.cn/plugins/KaramachiA217/dsh-bundle-manager
- GitHub 倉庫:https://github.com/KaramachiA217/dsh-bundle-manager