dsh-session-lock:为 DSH 会话加锁,拦截一切归档路径

前言

在 DeepSeek Harness(DSH)里,侧栏「归档」会把会话从列表里隐藏,数据仍留在 $DSH_HOME/sessions/。这是可恢复的 UI 操作,但手滑点错、批量脚本或其它插件调用 workspaces.archiveSession 时,正在用的会话也会从列表消失,找回要靠翻目录。下面介绍社区插件 dsh-session-lock(维护者 Setsuna-Kitahara,分类 admin-security):在侧栏给每个会话加锁,锁定后所有归档路径都会被拒绝并说明原因。

这是什么

dsh-session-lock 是面向 DSH 的第三方插件,与 DeepSeek 官方无从属关系。一句话:锁住的会话,侧栏 ⋮ 菜单、其它插件、维护脚本走 workspaces.archiveSession 都无法归档;宿主还提供批量归档不活跃会话的路由,且永远跳过已上锁会话。

核心功能

侧栏锁按钮

每个会话行左侧有 20×20 锁图标:空心为未锁,琥珀色实心为已锁,该行左侧有一条琥珀色细边。点击按钮即可锁定或解锁,整个按钮区域可点。

全路径拦截归档

包装并周期性重新断言 workspaces.archiveSession(约每 3 秒),侧栏菜单、其它插件、脚本调用都会被拦截,并提示「该会话已锁定,未被归档」。锁状态保存在宿主侧 $DSH_HOME/plugin-data/dsh-session-lock/locks.json,换浏览器、清缓存、重启 dsh 仍有效。

批量归档不活跃会话(可选)

宿主路由 POST /plugins/dsh-session-lock/archive-inactive 供每日维护任务使用;已上锁会话始终跳过。归档走 ctx.workspaceRegistry.archiveSession(),不直接改 storages/workspace.json。

HTTP 接口概要

路由均在 /plugins/dsh-session-lock/ 下,需请求头 x-dsh-session-lock: 1,并拒绝显式 sec-fetch-site: cross-site。

路由 方法 说明
/locks GET 当前锁清单
/set POST 上锁/解锁单个会话
/unlock-all POST 清空全部锁
/health GET 锁清单路径与条数
/archive-inactive POST 归档不活跃且未上锁的会话

archive-inactive 读锁清单失败时整次拒绝(503),宁可不归档也不误归档已锁会话。

安装与启用

DSH 生态里插件通过 profile 的 dsh.profile.bundles 挂载;只装依赖不写 bundles,插件不会加载。宿主半边不参与热加载,改完后需重启 dsh 进程(例如 systemctl restart dsh-web)。

方式一:插件市场

若已安装插件市场 dshmarket,在市场搜索 dsh-session-lock 安装即可(会写入 dsh.profile.bundles)。

方式二:命令行

# 1. 装依赖(dsh plugin 会把参数原样转发给 profile 目录里的 pnpm)
dsh plugin --profile web add dsh-session-lock

# 2. 把 "dsh-session-lock" 追加到 ~/.dsh/profiles/web/package.json 的 dsh.profile.bundles 列表里
#    (bundles 决定哪些包会被挂载;只装依赖不写这一段,插件不会加载)

# 3. 重启 dsh(宿主半边不参与热加载):托管在 systemd 上就是
#    systemctl restart dsh-web,其它部署方式重启你启动 dsh 的那个进程
systemctl restart dsh-web

<profile> 多为 web,按你的 profile 名替换 --profile 参数。

卸载

dsh plugin --profile web remove dsh-session-lock
# 从 dsh.profile.bundles 里删掉那一行,重启 dsh-web

锁清单可保留;不需要时手动删除 $DSH_HOME/plugin-data/dsh-session-lock/locks.json。

典型用法

经过上面的安装与重启,按下面步骤在界面和命令行验证。

  1. 刷新浏览器页面(客户端随 dsh-client-modules 加载)。
  2. 在侧栏会话行最左侧点锁按钮,切换锁定状态。
  3. 对已锁会话从 ⋮ 菜单尝试归档,应被拦下并提示未归档。
  4. 批量归档不活跃会话时,先用 dryRun 查看候选:
curl -sS -X POST http://127.0.0.1:3080/plugins/dsh-session-lock/archive-inactive \
  -H 'x-dsh-session-lock: 1' -H 'content-type: application/json' \
  -d '{"days":3,"dryRun":true}'

确认列表无误后去掉 dryRun 再执行真归档。默认按会话目录里 session.*.jsonl(.zstd) 最新 mtime 早于 now - days*24h 判定不活跃,默认 days 为 3。

适用场景与注意

适合谁: 长期开着多条 DSH 会话、担心误归档或跑维护脚本的用户;需要在反代域名下批量清理陈旧会话、又要保留若干「钉住」会话的环境。

边界(README 已写明):

  • 只拦「归档」,不拦「彻底删除」(删除走其它链路,如 dsh-archived-chats)。
  • 浏览器半边读不到锁清单时 fail-open(归档可能继续);宿主 archive-inactive 为 fail-closed。
  • 多标签页锁状态不实时同步,需切换锁或刷新后对齐;宿主账本为唯一事实来源。
  • 能访问 DSH HTTP 且带上 x-dsh-session-lock: 1 即可调用接口;反代部署请自行做访问控制。

安全提醒: 插件以当前 dsh 进程权限运行。安装前请阅读 仓库源码 与 MIT 许可证,确认符合你的部署策略。社区目录 SkillHub 为独立站点,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-session-lock 把「别误归档这条会话」做成侧栏一键锁与宿主持久账本,并覆盖菜单、插件与 archive-inactive 等路径。需要时从 SkillHub 目录页 进入,或直接在 GitHub 查看 README、测试与 issue。

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

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

Xiaoye