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

会话删除 wuuuuu123-32/dsh-session-delete

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

删除会话前扫描产出,移入回收站可还原

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:待复验
是什么
dsh 原生插件 · other
装得上吗
曾在 dsh 0.2.0-rc.2 下真实安装成功,但当前 dsh 已更新至 0.2.1-rc.5,本站尚未在新版下复验
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 19 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令发起外部网络请求
查看扫描证据(共 4 处,展示前 4 条)
  • 发起网络请求
    lib/client.js:165
    const res = await fetch(url, {
  • 发起网络请求
    lib/client.js:180
    const res = await fetch(url, { headers: { accept: 'application/json' } });
  • 执行外部命令固定命令
    lib/recycle.mjs:24
    const res = spawnSync(
  • 执行外部命令固定命令
    lib/recycle.mjs:64
    const res = spawnSync(
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

功能亮点

  • 删除前扫描会话产出
  • 移入回收站可还原
  • 支持批量删除会话

DSH 会话删除插件:会话列表「⋯」菜单支持删除 / 批量删除会话,删除是移入 Windows 回收站而非永久删除,误删可还原;删除前扫描并列出该会话的产出。

README

由 DeepSeek 最新模型翻译生成
dsh-session-delete 给 DSH 会话列表的「⋯」菜单加两个动作:删除当前会话 和 批量删除会话。 删除不是永久删除 —— 记录进 Windows 回收站,误删可以还原。 删除前会扫描该会话的产出,列出来让你决定是否一并清理。 起因:DSH 官方到 0.2.0-rc.2 都没有删除会话的能力。 sessionPersistence 的契约只有 create / open / stat / list / flush,没有 delete;唯一会话级移除是 archiveSession(只隐藏)。所以这个能力必须由插件补。 和现有几种做法比 | 方案 | 会话记录 | 产出文件 | 可恢复 | | 官方「归档」 | 保留,只隐藏 | 不动 | — | | npm 上的 dsh-session-delete(作者 vtxf,与本项目无关) | 永久删除 | 不动 | ❌ 不可恢复 | | 本插件 | 移入回收站 | 扫描后由你勾选,默认不动 | ✅ 回收站还原 | ⚠️ npm 上已有一个同名包(别人写的,永久删除且不可恢复)。
展开完整文档(README 剩余 1 节)
dsh-session-delete

给 DSH 会话列表的「⋯」菜单加两个动作:删除当前会话 和 批量删除会话。

删除不是永久删除 —— 记录进 Windows 回收站,误删可以还原。
删除前会扫描该会话的产出,列出来让你决定是否一并清理。

起因:DSH 官方到 0.2.0-rc.2 都没有删除会话的能力。
sessionPersistence 的契约只有 create / open / stat / list / flush,没有 delete;唯一会话级移除是 archiveSession(只隐藏)。所以这个能力必须由插件补。

和现有几种做法比

| 方案 | 会话记录 | 产出文件 | 可恢复 |
| 官方「归档」 | 保留,只隐藏 | 不动 | — |
| npm 上的 dsh-session-delete(作者 vtxf,与本项目无关) | 永久删除 | 不动 | ❌ 不可恢复 |
| 本插件 | 移入回收站 | 扫描后由你勾选,默认不动 | ✅ 回收站还原 |

⚠️ npm 上已有一个同名包(别人写的,永久删除且不可恢复)。本项目只从 GitHub 发布,安装时请始终带 github: 前缀,否则会装到那个包:

dsh plugin --profile desktop add dsh-session-delete # ❌ 装到别人的包
dsh plugin --profile desktop add github:wuuuuu123-32/dsh-session-delete # ✅ 本插件

安装

桌面端(profile 名换成你自己的)
dsh plugin --profile desktop add github:wuuuuu123-32/dsh-session-delete

装完必须重启 DSH(客户端插件的 HMR 对新增插槽项不可靠)。

手动安装(不用 dsh plugin 时)

把本仓库放到任意目录,然后在 profile 目录里建链接并登记:

cd ~/.dsh/profiles/desktop
pnpm add /path/to/dsh-session-delete # 或用 junction / symlink 指过去

~/.dsh/profiles/desktop/package.json 里要有:

{
"dependencies": { "dsh-session-delete": "link:..." },
"dsh": { "profile": { "bundles": ["dsh-session-delete"] } }
}

❗ 改这个 JSON 时不要写 BOM(PowerShell 5.1 的 Set-Content -Encoding UTF8 会加 BOM, DSH 启动时 JSON.parse 直接抛 SyntaxError: Unexpected token '',表现为界面打不开)。
用 [System.IO.File]::WriteAllText($p, $json, (New-Object System.Text.UTF8Encoding($false)))。

用法

会话列表某一行的「⋯」菜单里:

| 菜单项 | 行为 |
| 删除会话 | 删这一条。先扫产出,弹确认框显示产出清单 + 各项占用 + 记录大小,勾选「我已了解后果」才能确认 |
| 批量删除会话… | 打开面板多选(支持全选/清空,运行中的不可勾),确认后先只扫选中项,再进确认框 |

产出默认原地保留;勾选「把上面的产出目录也一并移入回收站」才会动它。

❗ 什么算「产出」:只认专属子目录,绝不碰工作区根目录的公用文件

DSH 自己的 turn-deliverables 规则是"这个会话写过哪些文件"。写权限上这没问题(没写过就不该删),但它会把公用文件算进某个会话的产出 —— 因为总有一个会话写过 AGENTS.md / 升级日志这类跨对话公用的资产。实测中确认框里就把 升级日志.md 列成了某个会话的"产出",一旦勾选就会被移进回收站。

所以现在的规则是:

| 对象 | 处理 |
| cwd 下的专属子目录(lab-report-9\、my-plugin\ …) | 列入可删产出,勾选才移入回收站 |
| cwd 根目录下的散文件(AGENTS.md、升级日志.md、prompt-.md、临时脚本 …) | 分开列成「不会被移动」的提示区,永远不动 |

取舍说明:根目录散文件里既有公用文件也有会话自己的临时脚本,无法可靠自动区分,所以一律不动(安全优先)。要清临时文件请直接在工作区操作。

批量面板的排序与过滤

- 顺序照抄侧边栏:按 workspace.json 里 DSH 自己维护的 sessionIds 数组排(先按 global.workspaceIds 的工作区分组顺序,组内按 sessionIds)。
原先用投影缓存表的自然顺序,看着是乱的。
- 默认只列侧边栏看得见的主会话:子代理会话的投影缓存存在 session_projcache/sessions/<裸uuid>.json,标题多是"你要访问这个网页…", 不在 sessionIds 账目里,侧边栏看不到。默认收起它们并提示"另有 N 个未显示";取消勾选「只看侧边栏里的会话」即可看到全部(展开时排在最末,带灰色 子代理/未分组 标记)。
- 切回「只看侧边栏」会自动取消被隐藏项的勾选,避免"看不见却被删"。
- 批量确认框里若多个会话都有产出,按会话分别用小标题列,不再重复同一句提示。

删除链路(顺序不能换)

1. 运行中的会话 → 直接拒绝(409)
ctx.agents.get(id)?.status === 'running'
2. 扫描产出(在删之前,日志还在)
3. flush 活动会话(避免 dispose 阶段回写重建日志)
4. 会话日志目录 + 投影缓存文件 → 回收站 ★ 校验:删除后数一遍回收站 $I 条目,数量没增加就报错中止
5. 确认日志目录真的没了(被 dispose 回写的话这里会拦住)
6. 摘工作区记账(workspaceRegistry.detachSession / storageDomain)
7. ctx.emit('api-session/removed', id) ← 让列表行当场消失 ★ 注意:删完不能重拉列表,否则宿主基线会把行合并回来

第 4 步的校验是关键。见下面第一个坑。

实现要点

- 菜单项走官方插槽 sidebar.workspaces.session.menu.item(order 500 / 501,排在内置的 pin 100 / rename 200 / fork 300 / archive 400 之后),不是 DOM 注入 —— DSH 0.2.0-rc.2 已开放这个插槽。
- 必须发 api-session/removed,客户端 sessions.handleSessionRemoved 靠它收敛列表。
- 客户端是手写的模块表产物(与 dsh-better-sidebar/lib/client.js 同协议:
window.__ModuleLoader__.load({ id, factory: (require) => {...} }),最后 exports.apply / exports.inject),
所以不需要构建步骤,直接改 lib/client.js 即可。
- 客户端装的是 sidebar.workspaces.session.menu.item 插槽;host 半边注册同源 HTTP 路由,客户端经 fetch 调用,删除动作全部在 host 侧完成。

兼容性

- DSH 0.2.0-rc.2(桌面端配置档),依赖 webServer / sessionPersistence / workspaceRegistry / sessions 服务
- Windows(依赖 Windows 回收站;recycle.mjs 走 Shell COM + $Recycle.Bin 元数据解析)
- 旧版 web 端(0.1.5-rc.2)不支持:那一版前端产物里没有 sidebar.workspaces. 插槽体系(客户端 UI 是打包进 dsh-web-frontend 的单体产物,不是独立 @deepseek-ai/dsh-client-ui- 包),菜单项注入不成立。host 半边(HTTP 路由、扫描、回收站)本身不依赖客户端框架,可以跑。

目录

lib/index.js host 半边:HTTP 路由 (/list /scan /delete …) + 删除链路 lib/client.js 客户端半边(手写模块表产物):菜单项 + 批量面板 + 确认框 lib/recycle.mjs 移入回收站,并自证真的进了回收站 lib/list-recycle-bin.mjs 读回收站(解析每个盘 $I 元数据),验证可恢复 lib/scan-session-core.mjs 产出扫描(复刻 DSH turn-deliverables 规则) lib/zstd-session.mjs 会话日志多帧 zstd 逐帧解压 test/ 离线测试(不依赖 GUI)

测试脚本(全部只依赖 DSH_HOME 指向的环境,路径自动从文件位置推导):

node test/smoke-host.mjs # host 模块加载 + apply + 扫描(只读)
node test/mock-client.mjs # 客户端装载 + 插槽注册 + 组件渲染
node test/list-sessions.mjs # 列出会话与产出概况(只读)
node lib/list-recycle-bin.mjs # 看回收站里有什么
node lib/zstd-session.mjs <会话目录> # 解压单个会话日志,打事件统计

真实删除(⚠️ 会真的动数据,先备份):

node test/e2e-delete.mjs <sessionId> [...] [--with-produced]

❗ 踩过的坑

1. 受限令牌下 DeleteDirectory 会静默永久删除,不进回收站

实测:同一个调用,提权时文件进回收站,受限令牌下被永久删除,而且不抛任何异常 ——函数"成功"返回,文件没了,回收站里也没有。

如果直接信它,用户以为"可恢复",实际数据已经丢了。所以 recycle.mjs 的做法是:

1. 删除前数一遍回收站里的 $I 条目数;
2. 删除后数一遍;
3. 数量没增加就判定为永久删除,报错。

宁可删不掉,也不能把"可恢复"变成谎话。

2. node 用管道捕获子进程输出会 EPERM

DSH 沙箱的 piped grandchild spawn EPERM。所以调用 PowerShell 必须 stdio: 'ignore' + 看退出码;需要拿返回值时,让 PowerShell 写临时文件、node 再读回来。

3. endsWith('recycle.mjs') 当入口判断会被同后缀文件名误命中

diag-recycle.mjs 也满足 endsWith('recycle.mjs'),于是 import 它时 CLI 主逻辑跟着跑了,脚本在第 13 行就"停住",查了很久。正确做法是比较 import.meta.url 解析后的完整路径:

const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url);

4. Shell.Application Namespace(10) 在沙箱下看不到回收站

项目数为 0,但 $I 记录明明在。改成直接解析 <盘>:\$Recycle.Bin\<SID>\$I(8B header + 8B size + 8B FILETIME + 4B 路径长度 + UTF-16 路径)才可靠。

5. 会话日志是多帧 zstd,zstdDecompressSync 只吃第一帧

session.v<N>.jsonl.zstd 每个事件一个 frame(实测某会话 172 事件 = 93 帧)。
Node 自带的解压 API 和 createZstdDecompress 流都只返回第一帧。
必须自己扫 frame 边界(zstd 魔数 0x28 B5 2F FD)逐帧解压 —— 见 zstd-session.mjs。

6. 「有产出」的判据要跟着 DSH 的规则走

复刻 @deepseek-ai/dsh-client-ui-deliverables 的 turn-deliverables:只认成功的写文件类调用(write / edit / str_replace_editor)。
成功判据看 tool/result 里 message.content[].isError 和 data.error,失败的写调用不算产出(否则一次失败的 write 会凭空造出一个"产出目录")。

7. 会话日志的文件名带版本号,别写死

session.v3.jsonl.zstd → session.v4.jsonl.zstd(0.2.x 已升 v4)。
按固定文件名找日志会找不到;用 session.v.jsonl* 匹配,并保留兜底扫描。

8. 改 profile 的 package.json 必须无 BOM

见上面「手动安装」里的说明。

License

MIT
预览分享卡片长什么样 ↓wuuuuu123-32/dsh-session-delete
分享 · DeepSeek Harness Hub
wuuuuu123-32/dsh-session-delete

删除会话前扫描产出,移入回收站可还原

回到顶部