dsh-panel-fold:把側邊欄全局面板圖標收進「更多」

前言

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 拿到,而那個槽只在「更多」菜單展開時掛載,啓動階段沒有任何鉤子能應用一個固定狀態。

插件的做法繞開這個限制:

  1. web 端用 MutationObserver 觀察 DOM,找到面板列表 <nav> 並打標記。優先按 aria-label 精確匹配(全局面板 / Global panels,即 ui-sidebar 的 t("panels.label"));文案若變化則退回結構判據——<nav> 裏含 button[aria-haspopup="menu"] 且至少有兩個直接子按鈕。
  2. 一條 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.1
  • peerDependencies.react: ^18.2.0(標記爲 optional)
  • dsh.client.inject: @deepseek-ai/dsh-client-ui-sidebar
  • dsh.client.immediately: true,意味着裝完即注入

五、與同類插件的關係

同一位置還有兩個插件,都做側欄精簡,可以按需比較:

  • ACGsu/dsh-sidebar-panel-fold——最接近的一個。它在面板列表上方自己加一行「收起面板」;收起後整塊變成一行摘要(當前面板圖標 + 名字),點這一行彈浮層列出全部面板;狀態存在 DSH 的 Host 設置通道里而不是 localStorage。想要「一行摘要 + 當前面板名稱」的選它。
  • LoktLin/dsh-sidebar-tidy——範圍更大,把品牌行、新建會話按鈕、面板塊和底部設置都藏進一個「退出極簡模式」按鈕,還加了工作區色塊。想把整個側欄削乾淨的選它。

dsh-panel-fold 的定位是最小的那片:不收其他行,不新增 UI,不改 ui-sidebar,保留一鍵還原。

六、適用場景與注意

適合這幾種情況:

  1. 裝了多個會註冊面板的插件,工作區 / 會話列表被面板塊擠壓得難以使用。
  2. 想要已經存在的、已持久化的偏好,而不是每次手動收起。
  3. 側欄其他位置你不想動,只想收這一排圖標。

需要注意:

  • 插件以當前 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

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜