前言¶
DSH 的運行方式是「一切皆插件」,插件裝得越多,環境越貼近自己的工作流,但維護成本也越高:在辦公室的桌面端裝了一批插件,回家打開另一臺設備卻只有基礎集合,要麼手工重新裝一遍,要麼靠記憶覈對哪些插件是開着的。手工複製插件目錄的做法有幾個問題:目錄結構、cordis.patch.yml、依賴和 profile 的差異很難對齊,而且容易遺漏「某臺設備上停用了某個插件」這種狀態差異。
下面介紹的 wystan68/dsh-plugin-sync 解決的正是這個問題:它同步的不是插件源碼,而是一份「插件清單」——包名、版本、啓用/停用狀態,在登錄了 DSH 的設備之間保持一致。
這是什麼¶
dsh-plugin-sync 由 Wystan68 維護(package.json 中 author 爲 Wystan),分類爲 admin-security,當前星標爲 0。它定位爲一個 DSH Host 插件 + Client 插件,通過同步碼或加密中轉在設備間搬運插件清單。
它明確不在同步範圍內的內容:cordis.patch.yml 裏的 config 配置項、插件源碼,以及任何密鑰或會話數據。也就是說,它解決的是「裝上哪些、哪些開着」的問題,不是「配置成什麼樣」的問題。
安裝與啓用¶
在 DSH 裏裝(推薦):打開 設置 → 插件 → 安裝插件,粘貼:
github:Wystan68/dsh-plugin-sync
或在終端裝(需要 dsh 命令可用):
dsh plugin --profile desktop add github:Wystan68/dsh-plugin-sync
desktop 換成當前正在使用的 profile 名,不填 profile 時默認是 web。桌面版可以用完整路徑調用:
"/Applications/DeepSeek Harness.app/Contents/Resources/runtime/cli/bin/dsh" plugin --profile desktop add github:Wystan68/dsh-plugin-sync
裝完重啓 DSH,左側欄會出現「插件同步」圖標(第 6 個)。卸載時在 設置 → 插件 裏停用或移除,或執行:
dsh plugin --profile desktop remove dsh-plugin-sync
使用:同步碼或加密中轉¶
使用時的固定順序是:先在每臺設備設好同步密鑰,再選一種傳輸方式,最後在差異預覽裏確認應用。
1、設同步密鑰。打開面板,輸入一把至少 8 位的密鑰(例如 correct horse battery staple),點「設置」。密鑰只在本機派生,明文不上傳、不寫入同步數據。
2、確認設備處在同一組。兩臺設備使用同一把密鑰後,面板上會顯示相同的同步組碼(如 qvi2a-jwfkq)。
3、選擇傳輸方式:
- 同步碼:A 設備點「生成同步碼」複製,B 設備點「導入同步碼」粘貼 → 預覽差異 → 應用。不依賴任何服務器。
- 加密中轉:在「加密中轉」裏部署或填寫地址 → A 點「推送」,B 點「拉取」→ 預覽差異 → 應用。也可勾選「自動拉取並應用」。
4、確認差異。差異預覽會列出:要安裝的插件、要切換的啓用狀態、跳過項(本地鏈接插件、無安裝來源)、版本差異提示。確認後再點「應用變更」。
同步語義¶
幾點需要知道的語義,避免誤操作:
- 誰推送,以誰爲準。同一同步組的遠端只有一份最新快照,後推送的會覆蓋先前的;應用後本機也變成這份清單的副本。
- 最小改動。只安裝缺失的插件、只切換與遠端不同的啓用狀態;未列出的插件不會被卸載。版本不同只提示,不自動升降級。
- 不會同步自己。插件同步自己的停用狀態會被忽略,避免應用後界面消失。
- 安裝來源。npm 包按
name@version安裝;link:/file:本地插件在其它設備上沒有源碼目錄,會列入「跳過」並提示手動安裝。 - 賬號通道。已登錄 DeepSeek 賬號時面板會顯示賬號信息;賬號雲同步接口尚未開放,當前同步仍由同步密鑰驅動。
加密中轉¶
一鍵部署:在「加密中轉」裏填一個 Cloudflare API Token,點「自動部署」。Token 需要 Account Settings: Read、Workers Scripts: Edit、Workers KV Storage: Edit 三項權限。插件會創建 dsh-plugin-sync KV 命名空間、上傳 Worker(綁定 SYNC)、嘗試開啓 *.workers.dev 子域,最後把地址填回面板,每一步的結果都會顯示。
手動部署:在面板裏打開「手動部署」複製 Worker 腳本,或在倉庫取 worker.mjs:
1、Cloudflare 控制台 → Workers & Pages → 創建 Worker,粘貼腳本。
2、綁定 KV 命名空間,變量名必須是 SYNC。
3、部署後把 https://<worker>.<子域>.workers.dev 填回面板。
中轉協議:
GET /health
GET /v1/snapshots/{group} → 密文信封 JSON,或 404
PUT /v1/snapshots/{group} → 寫入信封
DELETE /v1/snapshots/{group}
Authorization: Bearer <由密鑰派生的令牌>
載荷是端到端加密的 AES-256-GCM 密文,中轉無法解密。同一同步組第一次寫入時,中轉會把令牌的 SHA-256 釘在 KV 裏;換成另一把密鑰既讀不到也覆蓋不了這個組。單次請求體上限 200 KB。
安全模型¶
同步碼和中轉共用同一套加密載荷,派生鏈路如下:
- 密鑰 → PBKDF2-SHA256(210,000 次)→ 32 字節主密鑰;同步組碼、中轉令牌、加密密鑰都由主密鑰 HMAC 派生。
- 本機只保存派生後的主密鑰(DSH 憑據庫
plugin-sync/settings),明文口令不會落盤。 - 載荷在加密前先 gzip,使用隨機 12 字節 IV 與 AAD(綁定同步組),防止跨組重放。
- 中轉只存密文;刪除同步組會同時刪除令牌哈希。
適用場景與注意¶
適合需要在多臺 DSH 設備間保持插件集合一致、又不想手工覈對的場景,尤其是明文同步碼不方便傳遞時,可以用自建的 Cloudflare Worker 中轉。
需要注意幾點:插件以當前 DSH 進程的權限運行,安裝前應先閱讀源碼與許可證(MIT),並確認 github:Wystan68/dsh-plugin-sync 這個來源可信。它只同步插件清單,不同步 config 與源碼,配置差異仍需單獨管理。中轉自建的情況下,*.workers.dev 子域可用性依賴 Cloudflare;如果將來要正式使用賬號雲同步,需要等待接口開放。
結尾¶
dsh-plugin-sync 做的事情比較單薄但具體:把「設備之間插件集合是否一致」這個問題,收斂成一次同步碼導入或一次中轉拉取。項目當前版本 0.1.0,純 ESM、無運行時依賴、要求 Node.js ≥ 20,測試覆蓋密鑰派生、加解密、同步碼、差異計劃、Worker 與端到端流程。目錄頁見 https://www.skillhub.cn/plugins/Wystan68/dsh-plugin-sync ,源碼見 https://github.com/Wystan68/dsh-plugin-sync 。