前言¶
DSH 的理念是「一切皆插件」,裝了幾個擴展之後你會發現一件事:左側欄頂部那塊「全局面板」入口區——插件、自動化任務、XD Pool、上下文洞察、MCP 連接器、WSL、資料館——每註冊一個面板就多一行 36px。幾個插件下來這塊自己佔七八行,下面的工作區 / 會話列表被擠成窄窄一條。
有一條思路是去改 ui-sidebar 本身的行爲,但那意味着跟版本走。這裏介紹的 meihuaanying/dsh-panel-fold(維護者 meihuaanying,MIT,版本 0.1.0,要求 dsh >=0.2.0-rc.1)走的是更小的一條路:不改 ui-sidebar 一行代碼,只用一條 CSS 把那一排圖標收進塊底本來就有的「更多」按鈕裏,並提供一行開關可以隨時還原。
需要先說明的是:這類直接寫 client 端行爲的插件以當前 DSH 進程權限運行,安裝前應自己讀一遍源碼並確認許可證(本插件爲 MIT)。另外它通過 GitHub 直接安裝,尚未發佈到 npm。
下面介紹它的實際行爲、安裝方式、實現思路和需要留意的地方。
一、它解決什麼問題¶
左側欄面板塊的可見部分,每行是一個面板入口。插件默認摺疊,裝完刷新即生效,塊變成一個 ⋯ 更多,下面的工作區列表多出約 7 × 36px。
摺疊不等於隱藏。所有面板仍然在「更多」菜單裏,點開行爲與原來一致(selectPanel,當前選中項保留)。plugins 這行按設計不動——ui-sidebar 自己就不允許取消固定它。
開關與持久化¶
- 「更多」菜單最後一行是「顯示全局面板圖標 / 收起全局面板圖標(只留『更多』)」,點一下立刻來回切換,不需要刷新或重啓。
- 狀態存在
localStorage的dsh-panel-fold:mode,取值爲collapsed或expanded,刷新、重啓、插件重載都會保持。 - 默認摺疊;裝這個插件本身就是你的選擇。
可逆性¶
- 臨時:側欄「更多」→「顯示全局面板圖標」。
- 徹底:停用或卸載。
<style>標籤和<html>上的類一起消失,側邊欄回到出廠樣子。 - 只停用不卸載:在自己的補丁層追加
- id: dsh-panel-fold
disabled: true
二、安裝與啓用¶
插件還沒上 npm,直接從 GitHub 安裝(命令來自 README):
dsh plugin --profile <你的 profile> add github:meihuaanying/dsh-panel-fold
本地 checkout 也可以:
dsh plugin --profile <你的 profile> add /path/to/dsh-panel-fold
然後刷新 web 客戶端,摺疊立即生效,開關出現在側欄「更多」菜單裏。
如果之前裝過改名前的老版本,先刪掉舊包,否則 profile 裏會留下指向已改名目錄的斷鏈:
dsh plugin --profile <profile> remove <舊包名>
三、典型用法:爲什麼默認摺疊時就能生效¶
這是整個插件最值得講清楚的一點。ui-sidebar 本身有「固定 / 取消固定面板」機制 setPinned,取消固定後面板行會從邊欄消失、但仍留在「更多」菜單裏——聽起來正是想要的效果。但它用不了:setPinned 只能通過 sidebar.panellist.actions 的 owner props 拿到,而那個槽只在「更多」菜單展開時掛載,啓動階段沒有任何鉤子能應用一個固定狀態。
插件的做法繞開這個限制:
- web 端用
MutationObserver觀察 DOM,找到面板列表<nav>並打標記。優先按aria-label精確匹配(全局面板/Global panels,即 ui-sidebar 的t("panels.label"));文案若變化則退回結構判據——<nav>裏含button[aria-haspopup="menu"]且至少有兩個直接子按鈕。 - 一條 CSS 規則掛在
<html>的類上:
html.dsh-panel-fold-collapsed nav[data-dsh-panel-fold-nav] > *:not(:last-child) {
display: none !important;
}
該 <nav> 的最後一個子元素就是「更多」按鈕,所以只剩它。
3. 開關行註冊進 sidebar.panellist.actions 槽,ui-sidebar 把它渲染在「更多」菜單裏。
不需要 patch ui-sidebar,也不依賴它的哈希 CSS 類名——那些類名在版本之間會變。README 註明在 DSH 0.2.1-rc.2(桌面 profile,Windows)上驗證過:摺疊狀態在 Ctrl+R 後仍然保持,摺疊 / 展開可以原地來回切換而不需要重新加載頁面。
四、代碼結構¶
| 文件 | 作用 |
|---|---|
lib/client.js |
整個功能的實現:樣式注入、<nav> 標記、「更多」菜單開關行 |
lib/index.js |
Host 端佔位,只爲承載 bundle patch 的那一行 |
cordis.patch.yml |
插入 dsh-panel-fold 行的 bundle patch |
test/manifest.test.mjs |
校驗 manifest、patch 與 client 入口三者一致 |
README 強調這個插件刻意取最小的一片:不新增任何一行入口,複用 ui-sidebar 已經在塊底渲染的「更多」按鈕;除面板塊之外不動側欄的其他部分;client 端保持在 7 KB 以下,Host 端沒有代碼。
package.json 裏還有這些約束值得看一眼:
engines.dsh:>=0.2.0-rc.1peerDependencies.react:^18.2.0(標記爲 optional)dsh.client.inject:@deepseek-ai/dsh-client-ui-sidebardsh.client.immediately:true,意味着裝完即注入
五、與同類插件的關係¶
同一位置還有兩個插件,都做側欄精簡,可以按需比較:
ACGsu/dsh-sidebar-panel-fold——最接近的一個。它在面板列表上方自己加一行「收起面板」;收起後整塊變成一行摘要(當前面板圖標 + 名字),點這一行彈浮層列出全部面板;狀態存在 DSH 的 Host 設置通道里而不是localStorage。想要「一行摘要 + 當前面板名稱」的選它。LoktLin/dsh-sidebar-tidy——範圍更大,把品牌行、新建會話按鈕、面板塊和底部設置都藏進一個「退出極簡模式」按鈕,還加了工作區色塊。想把整個側欄削乾淨的選它。
dsh-panel-fold 的定位是最小的那片:不收其他行,不新增 UI,不改 ui-sidebar,保留一鍵還原。
六、適用場景與注意¶
適合這幾種情況:
- 裝了多個會註冊面板的插件,工作區 / 會話列表被面板塊擠壓得難以使用。
- 想要已經存在的、已持久化的偏好,而不是每次手動收起。
- 側欄其他位置你不想動,只想收這一排圖標。
需要注意:
- 插件以當前 DSH 進程權限運行,會向頁面注入
<style>並修改<html>上的類名。安裝前自己讀一遍lib/client.js,確認 MIT 許可證與你的合規要求相符。 - 它依賴 ui-sidebar 的
aria-label(全局面板/Global panels)加一個結構性回退判據來定位<nav>。如果未來 ui-sidebar 的 DOM 結構變化超出其回退判據,標記可能失效;這也是爲什麼作者保留了一條不依賴類名、但依賴結構特徵的路徑。 plugins一行無論如何都收不掉,這是 ui-sidebar 的設計,插件不做繞過。- 目錄頁標註星標爲 0,屬於較早期項目;上述行爲描述全部來自 README,尚未經過獨立驗證。
結尾¶
dsh-panel-fold 的價值在精確:它不試圖改造側欄,只回答「全局面板這一排佔掉了會話列表的空間」這一個具體問題,用一條 CSS、一個 MutationObserver 和一個開關行解決,並保證可逆、可持久化。如果你的問題正好是這個,它是成本很低的選擇。
目錄頁:https://www.skillhub.cn/plugins/meihuaanying/dsh-panel-fold
倉庫:https://github.com/meihuaanying/dsh-panel-fold