dsh-sidebar-organizer
Adds custom ordering and tucking away to seven strips of buttons and cards in DSH (the left sidebar, sidebar footer, conversation tabs, composer dock, session header icon strip, right sidebar and settings navigation), plus per-area drag switches and JSON layout import/export. Tucked rows land in the
Install
dsh plugin --profile web add dsh-sidebar-organizer
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-sidebar-organizer
简体中文 · [English](README.en.md)
给 DSH(DeepSeek Harness)里七处会重复出现的按钮/卡片加上自定义排序与收纳能力:左侧边栏、侧栏底部、对话标签、输入框工具条、会话头部工具条、右侧栏、设置导航。
最新版要点:桌面端窗口与浏览器里的 Web 界面共用同一份布局(配置页可关闭),七区域整理、收纳与配置导入/导出齐全;0.8.1 起还能整理会话栏 / 工作区栏的右键菜单并增删其中的分隔线(DSH 0.2.2+),0.8.2 修好了它在菜单保持打开时增删分隔线、刷新后不记忆的问题,0.8.3 修好了“重置后删一条分隔线、刷新即乱序”的顺序落库问题,0.8.4 让菜单底部与插件直挂按钮也能增删分隔线,0.9.0 起还能把条目收进菜单底部的「··· 更多 ›」二级菜单,0.9.1 把这一行压到整张菜单的最末端、并让菜单最下面那几项(含插件直挂按钮)也能拖动排序与收纳,0.9.4 修好了长按二级菜单误拖一级行、收纳项没有图标、从「更多」拖回后隐形,以及分隔线按 DOM 顺序落位导致的错行;0.9.5 起还能拖动 dsh-sidebar-row-menu 的正文右键一级菜单与「打开方式」「更多操作」二级菜单,并修好了「更多」面板内部无法排序、拖影被 row-menu 菜单盖住的问题;0.9.6 是一次稳定性与性能版本,修好了布局更新可能被永久丢弃、触摸取消仍会提交拖动、禁用或重载后残留定时器与监听、设置页与右键菜单的多处错乱,并清理了一批死代码。完整版本历史与各版本下载见 Releases。
现在能做什么
整理范围覆盖七处位置:
位置 · 内容 · 拖动方向
左侧边栏 · 插件、市场、技能管理、定时任务…… · 上下
侧栏底部 · 反馈、设置等底部入口 · 左右
对话标签 · 对话、轨迹等标签 · 左右
输入框工具条 · 统计、上下文、活动、用量等 · 左右
会话头部工具条 · 提醒、底部面板、上下文诊断、查找等图标 · 左右
右侧栏「开始」页 · 文件、浏览器、终端、「更多工具」 · 上下
设置导航 · 账户、通用、模型、插件…… · 上下
- 长按拖动排序:按住目标约 0.26 秒,行/卡片浮起(跟随指针的 ghost + 落点指示线),拖到目标位置松手。横向区域显示竖线,纵向区域显示横线。顺序即时生效并保存。
- 收进对应「更多」:把行拖到本区域的「更多」按钮上松手,即从原位消失,收进该区域「更多」菜单的「已收纳」分组。侧栏底部与左侧边栏共用左侧「更多」;对话标签与输入框工具条共用对话区「更多」;右侧栏使用自己的「更多工具」;会话头部工具条收进官方那个「更多操作」菜单(下载 Session 日志 / 反馈所在的那个),被收纳的图标直接排在该菜单原生两项上方;那个「...」按钮本身是宿主控件,不参与排序也不可收纳,同一条带里的分屏组合控件(文件资源管理器 / 更多打开方式)同样保持整体。设置导航的「更多」由本插件在出现收纳项时补上:第一项需在配置页收起,之后导航底部会出现「更多」,可继续把其他设置行拖进去,也可以点击其中条目直接打开对应设置。
- 从「更多」拖回来:打开对应菜单,长按被收纳项并拖回该区域的目标位置松手;拖动时源行会隐藏,只留下浮动预览,避免预览框与原行重叠。
- 菜单内排序:在「已收纳」分组里长按拖动,调整被收纳项之间的顺序。
- 把官方菜单项拖成按钮:会话头部工具条里,把「更多操作」菜单自带的「下载 Session 日志」「反馈」拖到条带上,会生成同名图标按钮,点击等同于点该菜单项;把按钮拖回「更多操作」即撤下。
- 键盘排序:聚焦某行后
Alt+↑/Alt+↓(横向区域同样按顺序移动)。 - 拖动热键:默认不绑定。配置页的「拖动热键」可录制一组键盘组合(支持 Ctrl/Alt/Shift/Win);随后可单独或同时开启「长按」「开关」两种放行方式。「长按」只在按住热键时允许拖动,松开立即中止;「开关」按一下开启拖动、再按一下关闭。热键只在输入框/文本域之外生效,打字不会误触发;未绑定或两种模式都关闭时,拖动行为与旧版一致。
- 右键菜单排序与分隔线(DSH 0.2.2+):会话行、工作区行弹出的右键菜单里,长按条目即可拖动排序;菜单打开时右键某个非底部条目,会在它下方增删一条分隔线(再右键一次取消)。分隔线按位置保存,条目移动时它不跟着走;落到菜单最下方会自动删除。把条目拖到列表最底部,会出现一行
··· 更多 ›,松手在这里就把它收进该行的二级菜单(悬停展开,点击等同点原菜单项);长按二级菜单里的条目可以拖回菜单任意位置。这一行永远在整张菜单的最末端——归档会话与插件追加的按钮之下;菜单底部动作和插件直挂按钮本身也都能长按拖动、一起排序。菜单里只剩一个可见条目时不再允许收纳。设置页有独立的「右键菜单」开关,0.2.1 上该功能自动关闭、卡片也不显示。 - 联动 dsh-sidebar-row-menu(可选,安装了该插件时):会话正文右键菜单的一级行,以及「打开方式」「更多操作」两个二级菜单里的行,都能长按拖动排序;会话 / 工作区右键菜单里 row-menu 追加的「打开方式」子菜单与正文菜单共用一套应用顺序。一级菜单默认仍跟随本插件的会话头部顺序,只有你拖过一次后才按你的安排保存;「更多操作」的顺序写回本插件的头部菜单顺序(会话头部原生的「更多操作」弹窗会同步),「打开方式」单独保存。重置后恢复默认联动。本插件不会写 row-menu 自己的任何存储键,拖动仍需「右键菜单」开关为开。
- 配置页:DSH 设置 →「布局整理」,或本插件的详情页。七张位置卡片,可拖动整行、上移/下移、收起/恢复、恢复本组;每张卡片有独立的「拖动」开关,关闭后该区域不再响应长按拖动(布局和收纳保持不变)。本插件自己的设置入口可以拖动排序但不能收起;better-sidebar 的设置入口完全固定,既不能拖动也不能收起。
- 导入 / 导出配置:配置页标题栏的「导出配置」把七区域的排序、收纳状态和拖动开关写成 JSON 文件;「导入配置」读取同格式文件并整体替换当前配置。版本不兼容或文件损坏时整份拒绝,不会只应用一半。
- 跨窗口共用布局:桌面端窗口与浏览器打开的 Web 界面(
http://127.0.0.1:<端口>)共用同一份顺序,重启 DSH、换端口都不受影响;配置页顶部的「跨窗口共用布局」开关可关闭,关掉后各窗口只用自己的本地布局。 - 按区域恢复:每处「更多」菜单的「恢复默认排序」只恢复该区域,恢复时已收纳的行会立即展开;「恢复默认排序」不会改动各区域的拖动开关。
- 刷新页面、重启 DSH 后布局保持。
- 拖动过程中,指针下方的行不会触发
:hover或 tooltip(拖动期间临时pointer-events: none,命中判定全部走几何矩形)。 - 没有自己的右键菜单、悬浮启动器、搜索或分组——本版本只是在宿主已有的会话 / 工作区右键菜单里做排序与分隔线,不新增菜单入口;「拖动热键」只负责放行拖动,不是命令快捷键。
安装
从 GitHub Release 安装(推荐)
打开 Releases,在最新发布里复制
dsh-sidebar-organizer-<版本>.tgz 的链接,粘贴到 DSH 的「插件」页 →「添加插件」;
也可以下载后选择本地文件。发布页同时提供 SHA256SUMS 便于校验。
每个 v* 标签由 GitHub Actions 自动构建并附加到 Release。
也可以直接粘贴 Git 地址(使用仓库里已构建好的 lib/,无需在本机构建):
git+https://github.com/TLEWA/dsh-sidebar-organizer.git#v0.9.6
从 npm 安装
dsh plugin install dsh-sidebar-organizer
或在 DSH 的插件管理器里搜索 dsh-sidebar-organizer。
从源码安装
本仓库本身就是一个 DSH 插件包(bundle)。克隆后,用插件管理器指向仓库目录安装:
plugin_manager action: install_bundle target: <仓库的绝对路径>
安装后刷新 Web 界面(Ctrl+R)。以 link: 方式装进 profile 时,改 src/ 并执行 npm run build 后刷新页面即可生效,不必重装。
0.3.6 及更早版本名为 dsh-modmenu。改名后旧的布局存储键
dsh.modmenu.layout.v1会自动迁移到dsh.sidebar-organizer.layout.v1,
控制台句柄window.__dshModmenu也保留为window.__dshSidebarOrganizer的别名。
安全设计
0.1.0 曾在每次插槽变更通知里重新注册整列面板,形成
注册 → 通知 → 再注册 的反馈环,把页面拖死。0.2.0 起彻底换掉机制:
1. 被整理的插槽只读:不注册、不 shadow 任何 sidebar.panellist、sidebar.footer.action、
conversation.view、conversation.composer.dock、settings.section 条目;只用
entriesOfSlot 获取 id 与标签。设置导航是例外:本插件会注册自己的「布局整理」设置页,
该行可以拖动排序,但不能收起。
2. 排序 / 隐藏只写 DOM 内联样式:按区域给行写 style.order,横向容器与纵向容器都适用;
收纳用 style.display:none + data-dso-hidden。
3. 固定、幂等的插槽注册:三处「更多」菜单各注册一个静态行 panel-organizer;
settings.section 与 plugins.detail.section 各注册一次设置页。全部只注册一次,
不订阅、不重注册。
4. 幂等 + 限流:每次布局 pass 都是「值不同才写」,并用 requestAnimationFrame
合并到每帧最多一次。
5. 看门狗:3 秒内超过 90 次 pass 即判定异常并停止观察与监听。
6. 只观察 childList:自身写入的 style / data-* 不会反过来触发观察器。
7. 逃生开关(浏览器控制台):
window.__dshSidebarOrganizer.reset(); // 忘掉全部布局
window.__dshSidebarOrganizer.resetScope("footer"); // 只恢复某一区域
window.__dshSidebarOrganizer.hide("footer", "feedback"); // 手动收起
window.__dshSidebarOrganizer.reveal("footer", "feedback");// 手动恢复
window.__dshSidebarOrganizer.setDragEnabled("footer", false); // 关闭某区域拖动
window.__dshSidebarOrganizer.disable(); // 置开关并停用,刷新后也不启动
window.__dshSidebarOrganizer.status(); // 查看七区域状态
hide(id) / reveal(id) 只传一个参数时仍按旧版语义作用于 sidebar。
disable() 之后要恢复,执行
localStorage.removeItem("dsh.sidebar-organizer.disabled") 再刷新。
8. 宿主侧同步只走本机:宿主半用 connection.fetch.register 注册一条
GET/POST /api/dsh-sidebar-organizer/layout 路由,只接受本机 owner 身份的请求
(webServer 侧按会话 cookie 判定,非 owner 直接 403),不发出任何外部网络请求;
数据只写 $DSH_HOME/storages/dsh-sidebar-organizer/layout.json 一个文件,写入用
临时文件 + rename 原子替换,失败时客户端退回本地 localStorage。
9. 就算本插件完全不工作,七处位置也只是保持 DSH 默认顺序,不会有其他副作用。
实现说明
- 七个区域的定义、行/卡片发现与 id
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::21,最后更新 2026-11-06