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

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

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

小夜