🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

会话删除器 Gty2408/dsh-session-eraser

DeepSeek Harness
Gty240834 天前有提交已提供中文文档扫描:含敏感能力

从侧边栏永久删除会话及其日志与工作区记录

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Gty2408/dsh-session-eraser
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · browser
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/2) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 7 处,展示前 7 条)
  • 读取本地文件
    lib/index.js:86
    projects = await readdir(root, { withFileTypes: true });
  • 读取本地文件
    lib/index.js:95
    if ((await stat(dir)).isDirectory()) found.push(dir);
  • 读取本地文件
    lib/index.js:102
    if ((await stat(flat)).isFile()) found.push(flat);
  • 读取本地文件
    lib/index.js:227
    if (existsSync(artifact)) {
  • 删除本地文件递归
    lib/index.js:228
    await rm(artifact, { recursive: true, force: true });
  • 读取本地文件
    lib/index.js:235
    survivors = artifacts.filter((artifact) => existsSync(artifact));
  • 发起网络请求
    lib/client.js:68
    const response = await fetch(SESSION_DELETE_ROUTE, {
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 删除侧边栏会话
  • 清除会话日志
  • 清除工作区记录

从 DSH 侧边栏删除会话。DeepSeek Harness(DSH)插件。

README

由 DeepSeek 最新模型翻译生成
dsh-session-eraser 从 DSH 侧边栏删除会话,永久移除它存储的日志和工作区记账。 安装 dsh plugin --profile desktop add dsh-session-eraser 然后重启 DSH。这条命令会安装包,通过 dsh.bundle.patch 机制应用本包的 cordis.patch.yml,并把包加入配置档的 bundle 列表——不用手动改配置。 没有 dsh 命令行时,把包放进配置档的 node_modules,再在配置档的 cordis.patch.yml 里加上: - insert: - id: dsh-session-eraser name: dsh-session-eraser 它做什么 在侧边栏每个会话行上加一个 Delete session 入口,共两处: - 行内的 ... 菜单,位于自带的 Archive 行下方; - 悬停时显示在行内其他操作旁边的垃圾桶按钮。 两个入口都会打开确认对话框。确认后从磁盘移除会话存储的产物,从工作区解绑,并通知所有已连接的客户端该会话已消失,于是这一行立刻消失。 打开会话的保护 删除当前在主面板中打开的会话会被拒绝。 这是有意为之。
展开完整文档(README 剩余 1 节)
dsh-session-eraser

从 DSH 侧边栏删除会话,永久移除它存储的日志和工作区记账。

安装

dsh plugin --profile desktop add dsh-session-eraser

然后重启 DSH。这条命令会安装包,通过 dsh.bundle.patch 机制应用本包的 cordis.patch.yml,并把包加入配置档的 bundle 列表——不用手动改配置。

没有 dsh 命令行时,把包放进配置档的 node_modules,再在配置档的 cordis.patch.yml 里加上:

- insert:
- id: dsh-session-eraser
name: dsh-session-eraser

它做什么

在侧边栏每个会话行上加一个 Delete session 入口,共两处:

- 行内的 ... 菜单,位于自带的 Archive 行下方;
- 悬停时显示在行内其他操作旁边的垃圾桶按钮。

两个入口都会打开确认对话框。确认后从磁盘移除会话存储的产物,从工作区解绑,并通知所有已连接的客户端该会话已消失,于是这一行立刻消失。

打开会话的保护

删除当前在主面板中打开的会话会被拒绝。

这是有意为之。工作区 UI 能协调已归档的当前选中项,却没有应对当前会话被移除的路径:它不暴露公开的关闭/离开 API,而 openSession 只能替换。因此删除打开的会话会让主面板指向一个已不存在的会话,输入框静默禁用,且无法返回。

所以保护在四处拒绝:

| 入口 | 会话打开时的行为 |
| ... 菜单行 | 渲染为禁用,标签为 Delete session (currently open) |
| 悬停垃圾桶按钮 | 完全不渲染 |
| 对话框确认按钮 | 禁用,并附内联说明 |
| 对话框确认操作 | 重新检查保留状态并拒绝 |

悬停按钮选择不渲染而非禁用,是因为原生禁用的按钮不触发指针事件,它的 tooltip 永远无法解释拒绝原因——而且行操作槽位自己的目录规定:操作不适用于该行时就不渲染。

宿主路由

POST /api/session.delete

// request
{ "sessionId": "session-04e8f277-…" }

// 200
{ "ok": true, "status": "deleted", "live": true, "detached": true, "removed": 1 }

| 状态 | 响应体 | 含义 |
| 200 | { ok: true, … } | 已删除,并验证已从磁盘消失 |
| 400 | { error: "…" } | 请求体格式错误,或 sessionId 缺失/无效 |
| 404 | { error: "session not found" } | 没有存储的产物,也没有活动会话 |
| 500 | { error: "…" } | 意外失败,或产物在移除后仍然存在 |

路由绝不报告它无法验证的成功。rm 在 Windows 上会因真实原因失败——文件被锁定或 deny-ACL 会抛 EPERM/EBUSY——所以移除产物后,插件会重新检查路径,若还有任何存活下来,工作区记账保持原样,这样侧边栏仍会显示那个实际仍然存在的会话。

这条路由通过连接的 Fetch 处理器提供,因此它和其他 /api 一样位于同一道认证门之后,只有来自受信任来源才能访问。

删除顺序

Host 没有会话擦除 API,所以删除由公开组件按特定顺序组合而成:

1. workspaces.stopSessionActivity(sessionId) —— 请求停止该会话。
2. sessions.liveEntryFor(live) + sessions.detachEntered(entry) —— 分离活动会话,这也会派发 session/disposed。
3. 让写入器落定。持久化拆除的 writer.close() 不会 await,而 appendLines 每批都用 open(path, "a") 打开日志 —— 这会重新创建已删除的目录 —— 所以输掉竞态的排空会复活日志。有两种机制覆盖这一点:
- settleWriter(...) 直接汇合进行中的关闭。它读取一个未文档化的内部字段(persistence.tracker.openHandles),一旦该字段被改名就会失败开放,所以它只是优化,不是保证。
- persistence.flush() —— 公开的持久性屏障 —— 排空每个活跃写句柄,并发关闭中的句柄也算作已刷新。
- 当两者都无法 await 时,删除会被扣留一个有界的落定窗口,重新删除任何被迟到排空恢复的东西。
4. 删除每个定位到的产物,然后验证它已消失。任何幸存下来的都报告为失败,而不是成功。
5. 重新索引工作区,清除会话的归档与固定条目,并将其从所属实体上分离。
6. ctx.emit("api-session/removed", sessionId) —— 这样冷会话会立即从其他客户端消失,而不只是在下一次列表刷新时。

第 5 步的归档/固定清理很重要,因为这些是注册表全局的 id 列表:删除会话会移除它们所指向的行,所以 UI 里再也不会提供取消归档或取消固定的选项 —— 那个 id 会永久悬空。两个删除 API 都按设计跳过会话存在性检查(「会话已消失的条目仍能解析」),而这正是本例的情况。

所有者在重新索引之前捕获,因为 entity.sessionIds 由规范 cwd 头索引实时过滤,重新索引会剪掉该 id。

存储布局

产物位于 ~/.dsh/sessions/<encoded-project-dir>/<encoded-id>/ 下,日志在 session.v4.jsonl.zstd。插件精确镜像后端的 encodeSegment,所以恶意的 sessionId(穿越序列、绝对路径、分隔符)只能解析到根目录内它自己转义后的目录。test/host-traversal.test.mjs 埋下金丝雀并证明了这一点。

测试

node test/run.mjs

host- 套件是封闭的 —— 它们使用一次性持久化根,并对路由触及的服务打桩。live- 套件与运行中的应用通信(DSH_TEST_ORIGIN,默认 http://127.0.0.1:19387),连不上就自动跳过。

| 套件 | 覆盖内容 |
| host-route.test.mjs | 冷会话删除、状态码、产物清理 |
| host-live.test.mjs | 活跃会话分支:停止、分离、结算、属主分离 |
| host-writer-race.test.mjs | 迟到的写入方排空后,不得让日志复活 |
| host-race-control.test.mjs | 同样的竞态在没有修复时必须失败——证明修复是承重的 |
| host-internals-change.test.mjs | tracker.openHandles 缺失时,删除依然正确 |
| host-bookkeeping.test.mjs | 会话删除后,不留悬空的归档/固定条目 |
| host-partial-failure.test.mjs | 拒绝 ACL 抛出的真实 EPERM 会被上报,而不是被吞掉 |
| host-traversal.test.mjs | 恶意 id 只能解析到转义后的根内目录 |
| client-guard.test.mjs | 两个入口和对话框,包括打开会话守卫 |
| live-end-to-end.test.mjs | 对运行中的应用发起带认证的 HTTP 请求,包括一次真实删除 |
| live-bundle.test.mjs | 运行中的应用在声明的修订版本上提供带守卫的客户端 bundle |

live-* 用 ~/.dsh/.credentials.yaml 里的浏览器会话签名密钥自行签发认证 cookie;不涉及浏览器,也不用 cookie jar。

已知限制

- 附件不会被删除。 删除只移除会话日志和它的工作区记账;会话在磁盘上引用过的文件会留在原地(它们的引用随日志一起消失)。要删掉这些文件,就得知道会话实际创建了哪些文件,而不只是读过哪些。
- 打开会话守卫只在客户端。 Host 没有视图状态的概念——mainView 的保留逻辑在浏览器里——所以手工构造一个针对当前打开会话的 POST /api/session.delete 不会被拒绝。该路由在常规认证门之后,因此只有用户自己已认证的客户端才能触达,而随附的 UI 从不发送它。
- settleWriter 读取了内部字段。 persistence.tracker.openHandles 不属于文档化的接缝。插件把它当作优化:就算它消失,公开的 flush() 屏障和有界结算窗口仍能产生正确的删除,host-internals-change.test.mjs 锁定了这一点。
- 删除不是事务性的。 如果进程在移除和重建索引之间挂掉,产物已经没了,但工作区记账可能仍列出该会话,直到下一次索引重建才会对账。

目录结构

lib/index.js Host 半边:删除路由和删除序列 lib/client.js 浏览器半边:菜单行、悬停按钮、确认对话框 cordis.patch.yml 注册 bundle test/ 测试套件(见上)
预览分享卡片长什么样 ↓Gty2408/dsh-session-eraser
分享 · DeepSeek Harness Hub
Gty2408/dsh-session-eraser

从侧边栏永久删除会话及其日志与工作区记录

这是你的仓库?认领条目

回到顶部