dsh-session-manager
DSH 侧栏批量管理会话插件:工作区可批量多选删除,会话可直接删除(进系统回收站),无需归档
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 17, 2026
- Updated
- Sep 12, 2026
Introduction
dsh-session-manager
给 DeepSeek Harness(DSH)的 Web GUI 加一个 「归档」 面板:在会话顶部的 对话 / 轨迹 标签右边再多一个 归档 标签,用来查看被归档隐藏的会话,并把它们恢复回侧栏。
这一版只做恢复,不做删除。 删除功能已经移除,原因写在下面「为什么不做删除」。
界面
标签栏变成 对话 | 轨迹 | 归档。「归档」面板里只列出真正被归档、且日志还在磁盘上的会话:
- 每行:标题、工作目录、最后活动时间
- 每行一个 恢复 按钮(取消归档,回到侧栏)
- 勾选后可批量恢复,支持全选
- 运行中的会话带「运行中」标记
不替换任何官方界面:侧栏、官方三点菜单(含官方「归档会话」)、对话、轨迹全部原样保留,插件只是往官方 conversation.view 插槽追加一个条目。卸载后官方界面恢复原状。
怎么用
- 在侧栏用会话的「归档会话」(官方三点菜单)把不想看见的会话移进归档区
- 打开 归档 标签,它就出现在列表里
- 想让它回来就点 恢复
为什么不做删除
曾经有过一个删除按钮,做法是把会话的日志文件夹送进系统回收站,然后把它从归档名单里摘掉。这个组合本身就是危险的:
摘掉归档名单里的记录 = 取消隐藏 = 该会话重新出现在侧栏。所以只要有任何一条路径「名单摘掉了、但文件夹其实没被删」,用户看到的就是删除变成了恢复——点删除,会话回到工作区。实测确实会复现(磁盘上没有文件夹的会话就会走这条路径)。
会话的生命周期归官方产品管,归档视图不是跟它抢这件事的地方。所以删除整个去掉了:面板现在只有恢复。
要用官方能力删会话,请走官方界面;本插件不再提供第二条路径。
恢复是怎么做的
DSH 0.1.5 的归档是单向的:WorkspaceRegistry 只公开 archiveSession(),官方 README 明确写着「no unarchive action exists yet」。取消归档在官方接口层面不存在。
本插件通过 DSH 的 storage 域直接改写那份归档名单(~/.dsh/storages/workspace.json 的 archivedSessionIds)来实现恢复。归档从不碰 workspace 的成员记账,所以把 id 从名单里摘掉,会话就回到了它原来的位置。写入后会回读校验,条目还在就报错,不会假装成功。
代价有两点,都已做进产品行为里:
- 官方侧栏要刷新一次页面才会看到:运行中的
WorkspaceRegistry持有一份内存副本,直接改盘不会通知它。恢复后面板会提示「若侧栏没立刻出现,刷新一下页面」。 - 用的是标注为诊断用途的内部面:
storage.domain在官方文档里是诊断接口。DSH 升级后它有可能变化,届时恢复会明确报错(不会静默)。
怎么安装(手动安装)
第 1 步:到本仓库 Release 下载 dsh-session-manager-0.4.0.tgz,然后执行:
dsh plugin --profile web add ./dsh-session-manager-0.4.0.tgz
第 2 步:把插件加进 profile 的 bundles 列表。这一步不能省——dsh plugin add 只把包装进 node_modules,不会自动启用它:
打开 %DSH_HOME%\profiles\web\package.json(默认即 C:\Users\<你>\.dsh\profiles\web\package.json),在 dsh.profile.bundles 数组末尾加上:
"dsh-session-manager"
第 3 步:重启 DSH Web 服务(先停当前的 dsh web,再重新启动)。
验收:任意打开一个有内容的历史会话(空白新会话的顶部会被官方隐藏),顶部标签栏出现 对话 | 轨迹 | 归档 三个标签。
注意:空白新会话看不到标签栏,这是 DSH 官方行为(
hideChrome),不是插件问题。
从 GitHub 直接安装
dsh plugin --profile web add github:SuperPaiGu/dsh-session-manager
装完同样需要第 2、3 步。
卸载
dsh plugin --profile web remove dsh-session-manager
再把 bundles 里那行删掉并重启即可。
与官方分栏的适配(另一个坑)
中心列左右两条边缘各有一条官方的「拖动改列宽」手柄。它的抓取热区覆盖所在的那整条 40px 竖带,而且层级在视图之上——任何控件落在带子里,鼠标都会变成拖动光标而不是点击。
关键坑:手柄距面板边缘的距离会随列宽变化(它们锚在列的两条边上,而列宽随窗口变),所以固定的内边距必然会在某个窗口尺寸下失效:
| 窗口 | 左手柄 | 右手柄 | 热区 |
|---|---|---|---|
| 1280 | x=396(距左边缘 116px) | x=1124(距右边缘 146px) | 各 40px |
| 1440 | x=476 | x=1204 | 各 40px |
所以列表和底栏用的是比例内边距 calc(120px + 12%):跟着列宽一起缩放,把复选框和按钮都让进安全区;窄列时自动收缩,不会把标题挤没。顶栏和提示行只到文字为止,保持与官方对话视图一致的 32px 缩进,保证视觉中线对齐。
这几个数字不是随手写的,是逐像素 elementFromPoint 量出来的。如果以后官方改了手柄的宽度、位置或层级,要重新量:正确判据是——面板里每个可点控件(含复选框)的每一个像素,最顶层元素都必须是它自己。
⚠️ 两个实例共用一个 home 目录时
主服务和辅助端共用 ~/.dsh 时,归档名单有两份内存副本(每个进程各一份):
- 官方源码里每个写点都是
archivedSessionIds: state.archivedSessionIds—— 写的时候把内存里那整份名单一起写下去,不是只写它改动的那一条 - 会触发写入的操作:归档会话、新建/重命名/删除工作区、调整工作区顺序。普通聊天、刷新列表不会写
- 所以:在 A 实例归档/恢复后,B 实例的界面不会更新;B 之后做一次上述任一操作,就会把它内存里的旧名单整份写回,覆盖掉 A 的改动
- 插件的恢复是直接改磁盘那份(唯一可行的路径),所以跨实例操作后要重启另一个实例才能一致
- 面板里的「归档区 N 个」会每 4 秒自动重读一次,磁盘变了它最多 4 秒后自己纠正
建议:归档管理固定在一个实例里做。
已知限制
- 只做恢复,不做删除(见上)
- 只显示"日志还在磁盘上"的归档会话:归档名单里那些文件早已被删掉的历史记录不会出现在面板里(它们本来也无从恢复)
- 恢复后侧栏需刷新一次页面:运行中的注册表持有内存副本,不会收到直接改盘的通知
- 用的是官方标注为诊断用途的内部面(
storage.domain),DSH 升级后可能变化,届时恢复会明确报错
怎么安装(Agent 安装)
由 AI Agent 在用户机器上执行的确定性指令,按顺序执行,每步有验收条件。
0. 环境检测
dsh --version # 命令不存在则提示用户先安装 DSH
1. 安装插件
dsh plugin --profile web add github:SuperPaiGu/dsh-session-manager
验收:退出码 0,输出含 + dsh-session-manager。
(如需固定版本:从 Release 下载 dsh-session-manager-0.4.0.tgz,用 dsh plugin --profile web add ./dsh-session-manager-0.4.0.tgz。)
2. 启用 bundle(关键步骤)
编辑 $DSH_HOME/profiles/web/package.json,把 "dsh-session-manager" 加进 dsh.profile.bundles 数组,并在 dependencies 里确认有 "dsh-session-manager" 条目。
验收:dsh --profile web --dump-config 输出含 dsh-session-manager 层。
3. 重启 DSH Web 服务
停止当前 dsh web,再以用户原有方式重新启动。
验收:启动日志无报错;打开一个有内容的历史会话,顶部出现 对话 | 轨迹 | 归档。
4. 验收清单
- 第 1 步退出码 0
-
--dump-config含dsh-session-manager层 - 重启后设置 → 插件 → 插件列表 中
session-manager行 active - 历史会话顶部出现「归档」标签;无归档会话时显示引导文案
- 归档一个会话 → 出现在面板;点「恢复」→ 面板移除、刷新页面后侧栏出现
- 面板里没有删除按钮
目录结构
dsh-session-manager/ 组合包根
├── package.json dsh.bundle + dsh.client 声明
├── cordis.patch.yml 插件层(id session-manager → dsh-session-manager)
├── index.js Host:/session-manager/{archived,restore}
├── client.js Web 客户端:向 conversation.view 注册「归档」面板
├── tests/ 路径编码只读实证(encoding-check.mjs)
└── README.md
License
MIT