Skip to content

dsh-session-keeper

Verified

dsh-session-keeper · v1.2.1 · MIT · Web UI

DeepSeek Harness 的会话管理插件:工作区独立的分类树、拖拽排序、置顶、归档分区,以及可撤回的删除回收站。

Install

dsh plugin add dsh-session-keeper

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

会话管理 · dsh-session-keeper

English | 中文

把 dsh 侧边栏变成真正能管得住的地方:分类树、拖拽排序、置顶、归档分区、可撤回的删除回收站。 每个 Workspace 有自己独立的分类,每个会话最多属于一个分类;删掉的会话进回收站而不是蒸发。

包名 dsh-session-keeper
显示名 会话管理(设置 → 插件里的 tab 就是这个名字)
版本 1.2.1
许可 MIT
形态 一个包内含 Host 入口 + Web Client bundle + Cordis profile patch,不需要另装 Client / Bundle

这是谁的代码? 本项目是 ht719/dsh-session-categories(0.1.0,MIT)的维护分支。 上游那份装进当前版本的 dsh 会直接打不开窗口,本仓库在它之上做了移植与扩展。 每一项改动来自哪里(上游基线 / 竞品思路 / 使用者反馈)都记在 CHANGELOG.md;移植的技术细节在 FORK-NOTES.md。

不要与上游包同时安装。 dsh-session-keeper 与 @deepseek-ai/dsh-session-categories 抢的是同一个 sidebar.workspaces 槽位,打开的也是同一个存储域(session_categories,version 0)。两个一起装, 侧边栏会互相顶掉,分类文档也会被写进同一份。二选一:这个分支,或者上游。


为什么会有这个分支(源于什么)

上游 [email protected] 发布于 2026-08-19,对着更早的 dsh 预发布版写的。之后 dsh 移除了 @deepseek-ai/dsh-client-runtime 这个包,而上游的 client bundle 仍然 require 它:

upstream  lib/client.js 需要:
  "@deepseek-ai/dsh-client-runtime/client"   ← 现在解析不到

dsh 的模块加载器会拿插件的 inject 声明去解析 bundle 里的 require。解析不到就在 bundle 物化时抛异常,sidebar.workspaces 这个 slot 条目的挂载随之崩溃;官方侧边栏把 slot 收回去, 而崩溃发生在 shell 引导阶段,于是窗口永远开不完 —— 表现出来的样子是「dsh 打不开了」。

本分支从源码重建 bundle(不是打补丁改 lib/),所以重装插件也不会把修复冲掉。 上游还缺两样东西:仓库里没有 Rows.module.css(Rows.tsx 却 import 它), 以及重建出来的样式表里 @keyframes row-in 块被截断过(一个坏 at-rule 会让后面所有规则静默失效)。 这两处也在本分支补齐,细节见 FORK-NOTES.md 与 BUILD.md。


功能

1. 分类树

  • 分类按 Workspace 隔离:A 工作区的分类不会跑到 B 工作区去。
  • 支持多级嵌套:分类下可以再开子分类,缩进随层级增加。
  • 新建方式三个入口:Workspace 操作菜单建一级分类、分类 ⋯ 菜单建子分类、会话行的移动到分类。
  • 分类的 ⋯ 菜单:新建子分类 / 重命名 / 删除。重命名是就地输入(回车确认、Esc 取消),不弹框。

2. 拖拽

四种拖拽都支持,各有各的落点规则:

拖什么 拖到哪 结果
会话行 单列表 / 工作区分组里的另一行 调整顺序(写进本地存储)
会话行 分类里的行 在该分类内调整顺序
会话行 分类容器 改派到那个分类
分类行 同级分类行 在兄弟之间排序
分类行 其他分类行的中间带 变成它的子分类

分类行拖到另一行的上边缘 / 下边缘是排序,落在中间带是改父级 —— 两种手势靠落点高度区分。 跨父级排序会被 Host 拒绝(anchor-not-found),这是设计如此:排序只在同级内有意义。

需要「手动排序」生效,把视图菜单的排序方式切到 手动排序;停在 最近更新 时,新活动会把会话顶回前面。

3. 会话操作

每个会话行右缘有 ⋯,鼠标悬停时时间戳让位、按钮落到最右:

操作 作用
重命名 改标题
分叉会话 在最后一个完成的回合处分叉
置顶会话 / 取消置顶 标记该行醒目:置顶行会被抬进所有分类上方的全局置顶段,或者留在自己所属的分组里
归档会话 / 取消归档 归档该行,或把归档行放回原位
移动到分类… 改派到别的分类,或放回未分类尾部
删除会话 把会话记录移进回收站(见第 5 节)

4. 视图菜单

分组方式(三种,与官方浏览器一致):

模式 说明
按工作区 每个 Workspace 一个平铺分区
按工作区树 按目录路径嵌套:目录位于另一个 Workspace 目录之内的,作为那个分区里的子分区渲染。按严格路径边界匹配,E:\AI\DSHX 不是 E:\AI\DSH 的子级
单列表 一条按时间排的列表,不分组

路径比较前会归一化(Windows 分隔符、结尾分隔符、大小写都不计),所以 E:\AI\DSH 与 e:/ai/dsh/ 是同一个父级。

筛选会话(三态,与官方一致):

  • 隐藏已归档 —— 归档分区和归档行一起消失;
  • 全部对话(包括已归档) —— 分区出现并展开;
  • 仅显示已归档 —— 工作区分组全部隐藏,只剩归档分区。

第二项写「包括」而不是官方的「显示」,是有意为之;行为完全一致。

置顶位置(一个开关,管所有置顶行):

  • 置顶到分类上方 —— 置顶行从各自分类里抽出来,汇成所有分类之上的全局置顶段。置顶说的是 「在整个列表里醒目」,不是「在某个分组里靠前」;
  • 保留在所属分类 —— 置顶行留在自己所属的分组里,只在那个分组内靠前。

开关在同一个视图菜单里,默认是置顶到分类上方。

5. 删除与回收站

「删除会话」把会话记录移到 dsh 数据目录下的批次目录。文件不销毁,删除随时可逆。

移任何文件之前,确认框会先走 /session-recycle/scan 扫一遍并列出:

  • 会话记录本身占多大;
  • 选了更大范围时,会跟着一起移动的、该会话写过的文件;
  • 每一个被拒绝的文件,以及拒绝的理由。

三档范围:只移会话记录 / 连该会话在工作目录里写过的文件一起移 / 预留的「全部」档。 安全规则很严:只有真实路径严格位于会话工作目录内、且不在 dsh 数据目录下的文件才会被动到; 符号链接、不存在的文件、其余情况一律拒绝并给出理由。日志会在移动之前读出来,因为一旦离开 sessions 目录,持久化层就读不到它了。

删除同时把该会话从所有工作区名册里摘除、并从归档集合中释放,所以不会留下孤儿行。 撤回会把三面一起还原:恢复日志、重新挂回名册、原本已归档的重新归档。

回收站管理在 设置 → 插件 → 会话管理:

  • 按批次分组列出,显示删除时间、会话数、占用体积;
  • 看内容 展开该会话的存档对话,让「再删一次」是个知情决定;
  • 撤回最近一批 把最新一批放回原处;
  • 彻底删除(单批)与 清理过期(默认保留最近 20 批 / 30 天)—— 这两项不可逆;
  • 清空回收站 一次清掉全部批次。

6. 插件日志

设置页的插件日志是个环形记录,按时间倒序记插件自己的动作与失败(归档、取消归档、删除、扫描、撤回)。 被拒绝的动作会留下看得见的理由,而不是一闪而过的 toast。可以一键复制全部日志。


安装

shell 里要能用 dsh 命令,然后装到未修改的 dsh Web profile:

dsh plugin --profile web add dsh-session-keeper
dsh --profile web

在 dsh 源码仓库里跑的话,用它自己的 launcher:

pnpm dsh plugin --profile web add dsh-session-keeper
pnpm dsh --profile web

仓库里已含生成好的运行时文件,不需要额外构建插件。

从 tarball 装(离线或想锁定版本时):

dsh plugin --profile web add ./dsh-session-keeper-1.2.1.tgz

装完重启 dsh。插件注册三个 slot:sidebar.workspaces、settings.plugins.tab、sidebar.footer.action, 不碰任何 dsh 核心包,也不需要改 ui-workspace / ui-slots / api-remotes。


注意事项

1. 预发布版不承诺兼容。 插件对着当前的 dsh 预发布插件 API。dsh 升级时请一起更新本插件——只升一边很容易撞上 「包被移除 / 导出改名」这类断裂,症状往往就是侧边栏整块不见或窗口打不开。

2. 「彻底删除」是真的删。 「删除会话」是可逆的(进回收站);「彻底删除」「清理过期」「清空回收站」不可逆。 回收站不是备份,重要会话请另外导出。

3. 视图状态在你自己的浏览器里。 分组方式、排序方式、分类展开状态、归档筛选、各账户的手动顺序,都以 dsh.session-categories.view.v2 存在浏览器 localStorage。换机器、清缓存、换 profile 都会丢。 会话本身和分类数据不在这里,不会因为清缓存丢。

4. 分类删除会连带归档会话。 递归删除一个分类,会把里面的会话归档(不是删除)。日志不会被删掉,随时可以取消归档找回来。

5. 跨 Workspace 的操作会被拒绝。 把会话移到别的 Workspace 的分类、把分类移进自己的后代、对着过期 revision 动手 —— 都会被拒并给出理由。 这是保护,不是 bug。

6. 排序要开「手动排序」。 停在「最近更新」时,新活动会把会话顶回最前面,把用户手排的顺序不断覆盖。

7. 本插件不注入全局 CSS。 所有样式都走 CSS Modules(类名哈希化),作用域限定在自己渲染的 DOM 里。它不会改侧边栏的全局宽度、 不会改窗口背景、不会写 document.body。所以它既不会修好、也不会弄坏外壳层的布局问题。

8. 卸载。 dsh plugin --profile web remove dsh-session-keeper。分类与会话数据留在 dsh 存储里,不会跟着插件走。


数据与行为

  • 递归删除分类会归档其中的会话,不删持久化日志。
  • 归档操作带 operation id 重试,进程重启后可以恢复。
  • 变更会拒绝:过期 revision、跨 Workspace 的会话 id、移到自身后代、指向未知分类。
  • 删除的批次目录在 dsh 数据目录下,结构 <批次id>/<会话id>/;批次 id 形如 2026-10-17T14-31-25-939Z。

兼容性

面向当前 dsh 预发布版的插件 API,目标是在未修改的 dsh 安装里工作。 dsh 不承诺跨预发布版本兼容,升级时请同时更新 dsh 和本插件。

仓库结构

仓库根目录就是可安装的预构建包。源码保留在 packages/workspace/session-categories/、 packages/client/ui-session-categories/ 与 packages/bundle/session-categories/。 构建说明(含本分支不得不打的上游补丁)见 BUILD.md。

许可与致谢

MIT。上游版权归原作者 ht719;本分支保留同样的许可与署名,改动以同等条款发布。 上游仓库:ht719/dsh-session-categories。