删除整个会话或单个轮次,并清理残留文件
29.8/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/14 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add giriimuls/dsh-chat-eraser该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
支持删除工作区下的对话,也能编辑已输入的提示词。
README
由 DeepSeek 最新模型翻译生成dsh-chat-eraser
从侧边栏的 ... 菜单删除整个聊天会话,也可以从转录的轮次尾部删除单个轮次。这是一个 DeepSeek Harness(dsh)插件:宿主端负责持久化删除,浏览器端负责两处入口。
sidebar ... menu transcript turn tail
├── Pin session ┌──────────────────────────────┐
├── Rename │ [answer of turn 17] │
├── Fork session │ 🗑 Delete turn │ ← this plugin
├── Archive session └──────────────────────────────┘
└── 🗑 Delete session ← this plugin
为什么需要插件
harness 在每一层都没有删除 API。dsh-session-persistence-jsonl 说得很直白——「Nothing deletes session files」——Workspace 浏览器也写明「sessions can be archived but never deleted」。任何地方都没有「删除轮次」这个操作:会话就是一份只追加的 JSONL 日志。
展开完整文档(README 剩余 1 节)
dsh-chat-eraser
从侧边栏的 ... 菜单删除整个聊天会话,也可以从转录的轮次尾部删除单个轮次。这是一个 DeepSeek Harness(dsh)插件:宿主端负责持久化删除,浏览器端负责两处入口。
sidebar ... menu transcript turn tail
├── Pin session ┌──────────────────────────────┐
├── Rename │ [answer of turn 17] │
├── Fork session │ 🗑 Delete turn │ ← this plugin
├── Archive session └──────────────────────────────┘
└── 🗑 Delete session ← this plugin
为什么需要插件
harness 在每一层都没有删除 API。dsh-session-persistence-jsonl 说得很直白——「Nothing deletes session files」——Workspace 浏览器也写明「sessions can be archived but never deleted」。任何地方都没有「删除轮次」这个操作:会话就是一份只追加的 JSONL 日志。
所以这个插件是接缝之外的运维工具:它像运维人员那样编辑每个会话的产物,而且做得足够小心。
功能
删除会话。 侧边栏行的 ... 菜单多出一行 Delete session(放在自带的 Archive session 之后,用分隔线隔开)。确认后,按以下顺序执行:
* 请求宿主停掉会话里正在运行的一切(注册表自己的停止扇出,和 Archive-with-stop 用的是同一个),
* 把会话从 harness 的活动会话存储里取出——这一步才是真正删除。已挂载的会话是从那个存储里列出来的,所以从它底下删掉会话,侧边栏行还在,日志也还开着,于是下一次提示词就会以 ENOENT … session.v4.jsonl.zstd 失败。存储自己的单次移除是幂等的,会丢掉存储条目和它的附件,并广播 session/disposed,列表和查询正是靠这个丢掉活动行,
* 请求宿主通过注册表 API 归档它,这样即使客户端列表过期,也渲染不出这一行,
* 删除会话目录里的每一代规范文件(session[.vN].jsonl[.zstd]),
* 删除它的投影缓存检查点($DSH_HOME/storages/session_projcache/sessions/<id>.json),
* 如果宿主拒绝归档,就退回到清理宿主持久化的 Workspace 注册表($DSH_HOME/storages/workspace.json:工作区成员关系,加上已归档和已固定集合),清理前先给该文件做一份带时间戳的副本。
在删除任何东西之前,会话日志的副本会写进这个插件自己的备份树。删除是彻底的:会话从列表数据本身消失,而不是被归档过滤器藏起来,harness 也无法再挂载它——所以没有行可以打开,也没有提示词会因为文件缺失而失败。
页面不会重新加载。存储释放和归档状态变更都通过宿主自己的事件传到已打开的页面,所以行会原地消失;早先有个构建在这里重新加载,闪了一下空的 New Session 视图,然后直接从 harness 的内存列表里把那一行又拉回来了。
删除一轮。 转录里的每一轮都带一个 Delete turn 控件。确认后,会把那一轮以及之后所有轮从会话日志里删掉。日志是只追加的,序号连续,所以只能做后缀截断:这一轮第一行之前的内容逐字节保留(原始 header frame 保留,序号保留),同时丢弃投影缓存,让 harness 重新折叠,而不是继续提供一个已经跑到日志前面的投影。
轮次从 1 开始编号,直接来自持久化的 turn/start 事件,所以转录里标为 17 的那一轮,就是 host 截掉的那一轮。还在运行的轮次永远不会提供,即使请求也会被拒绝。
已验证行为
| 检查 | 结果 |
| 菜单行和每轮控件在真实应用里渲染 | 在 Chromium 里对着实时 harness 验证通过 |
| 删除会话后,无论是否挂载,都会从列表数据里移除该行 | 验证通过:mounted false、queryListed false,行没了,重新加载后仍然没有 |
| harness 无法再挂载已删除的会话 | 验证通过(删除它打开过的会话后 mounted false) |
| 在 621 行、17 轮的会话上截断轮次 | 保留 612 行,丢弃 9 行,235,023 → 119,721 字节 |
| 每次重写前都备份 | 写入 $DSH_HOME/chat-eraser/backups/ |
| harness 重新读取重写后的日志 | host 重启后,转录渲染第 5..16 轮(第 17 轮没了) |
| 运行中的轮次 | 以 turn-running 代码拒绝 |
node test/run.mjs 跑这个包的检查:物理编解码器对着真实会话产物,两个删除操作对着 fixture harness home,HTTP 接口通过 stub web server,浏览器 bundle 通过 stub module loader。
运行中的 harness 能看到什么、看不到什么
harness 在内存里构建会话列表,来源是持久化的语料加上它挂载过的每个会话,而且它从不重新读取已经加载过的日志。这就把两个功能分开了:
* 已删除的会话会立刻从列表里消失:删除路径先通过 host 自己的 registry API 把它归档,页面不会重新加载。
* 截断的轮次不一定能立刻显示:你正在读的转录来自 harness 挂载的那个会话,所以在 harness 重新打开之前,它会一直显示被移除的那一轮。重写本身已经是持久化的,插件会如实说明,而不是假装——操作后检查会在页面里立刻运行并报告
Already deleted — The turn was removed from the log, but this harness keeps serving the copy it mounted when it opened the session, so the transcript still shows it. Closing and reopening DeepSeek Harness refreshes the transcript.
如果用了过期的控件,也会出现同样的提示——点击删除一个轮次视图仍然提供,但日志里已经没有对应的答案 unknown-turn,客户端会把它报告为过期的视图,而不是失败。
重新打开 harness 不会丢失任何东西:不需要重复执行删除。
插件自身代码改动的生效方式
两半的更新节奏不同,就地编辑这个包时这点很关键:
* 浏览器那一半会被监听:client/client.js 变化时,模块图会重新发布 bundle 修订版,刷新页面就能加载到新版本;
* 宿主那一半不会:这个配置档以 root: [] 运行 HMR,模块监听因此关闭,而 Node 会在进程存活期间缓存已导入的模块。所以编辑过的 lib/ 代码要到下次启动 harness 才生效,而配置改动(补丁层、配置档清单)仍然会实时重新组合。
想在不重启 harness 的情况下运行编辑过的宿主那一半,就把插入的行指向一个带缓存破坏参数的路径——模块按解析后的 URL 缓存,新 URL 会导入新代码——并禁用它所替代的那行 bundle:
profile cordis.patch.yml, applied after every bundle layer
- id: chat-eraser
disabled: true
- insert:
- id: chat-eraser-live
name: 'file:///C:/Users/<you>/.dsh/plugins/dsh-chat-eraser/lib/index.js?v=2'
每次编辑 lib/ 后把 ?v= 递增;这个补丁文件会被监听,运行中的 harness 会在一两秒内重新组合。浏览器那一半仍然来自包本身(client/client.js),因为插入的行解析到同一个包名。重启后组合会回到 bundle 行,所以那时直接删掉这两条即可——编辑前的文件副本就保存在旁边,名为 cordis.patch.yml.bak。
安装
这个包是配置档 bundle。scripts/install.mjs 完成整个安装(幂等),不需要包管理器——不下载任何东西,也不重写 lockfile:
node scripts/install.mjs # --profile desktop (default), --home <dsh home>
node scripts/install.mjs --dry-run # print the plan
node scripts/uninstall.mjs # reverse it
它会
1. 把包链接到 <profile>/node_modules/dsh-chat-eraser,
2. 在配置档清单里加上 "dsh-chat-eraser": "file:<relative path>",
3. 把 dsh-chat-eraser 追加到 dsh.profile.bundles,
4. 重写配置档清单前先备份。
然后包自带的 cordis.patch.yml 插入 loader 行。运行中的 harness 会在几秒内通过 HMR 重新组合(清单和补丁层都被监听);没有 HMR 的宿主会在下次启动时加载这个 bundle。重新加载浏览器页面即可加载浏览器那一半。
想手动安装,就往配置档的 cordis.patch.yml 里加上:
- insert:
- id: chat-eraser
name: dsh-chat-eraser
并让这个 specifier 可解析(用上面的链接,或者 npm/pnpm add)。
HTTP 接口
harness web 服务器上的精确路由,仅限同源,JSON 进 JSON 出。
错误一律返回 { ok: false, error: { code, message } },绝不向宿主的请求循环抛异常。
| 路由 | 请求体 | 作用 |
| GET /chat-eraser/status | — | 这个插件能看到什么:home、会话数量、组装出的客户端行、实际提供的 bundle 路径 |
| GET /chat-eraser/inspect?sessionId= | — | 某个会话的轮次、未结束的轮次、大小、标题 |
| GET /chat-eraser/why?sessionId= | — | 某个会话为什么(仍然)在列表里:是否已挂载、查询是否列出它、这台宿主上有哪些服务和方法 |
| POST /chat-eraser/delete-session | { sessionId } | 停止、从实时存储中释放、归档,然后永久删除某个会话 |
| POST /chat-eraser/delete-turn | { sessionId, turn } | 从某一轮开始,连同其后所有内容一起切掉 |
错误码:session-not-found、unknown-turn、turn-running、invalid-turn、invalid-session、method-not-allowed、internal。
目录结构
package.json dsh.bundle.patch + dsh.client (web)
cordis.patch.yml the loader row this bundle inserts
lib/index.js cordis plugin: routes, JSON envelope, error codes
lib/session-store.js locate / delete / cut; workspace-registry scrub; backups
lib/log-format.js Zstandard concatenated-frame codec (read, scan, encode)
client/client.js Module Loader bundle: three slot registrations + one notice
scripts/install.mjs idempotent bundle install
scripts/uninstall.mjs reverse of it
test/ four suites, no framework: node test/run.mjs
恢复
每个破坏性步骤都会先复制它即将改动的内容:
$DSH_HOME/chat-eraser/backups/<sessionId>/<timestamp>-
$DSH_HOME/chat-eraser/backups/_registry/<timestamp>-workspace.json
要恢复某个会话,把它的日志放回 $DSH_HOME/sessions/<project>/<sessionId>/session.v4.jsonl.zstd,再把 id 重新加回 Workspace 注册表(或者干脆启动 harness,让它自己列出该目录)。要恢复被切掉的轮次,把切割前的备份覆盖到日志路径上,然后重启 harness。因删除而处于归档状态的会话,可以在侧边栏的 All conversations (show archived) 视图里取消归档;如果背后没有日志,无论哪种方式它都不会出现在列表里。
给维护者的说明
* 会话日志格式是多个独立 Zstandard 帧的拼接,第一帧是头部行,后续帧追加批次。lib/log-format.js 逐帧解析结构(magic、descriptor、block header、checksum),而不是搜索 magic,因为压缩块里可能正好含有这些字节。头部帧按字节原样复用;新帧的校验和方式与后端自己的写入器一致。
* 切割点是 turn/start 行加上紧挨在它前面的 agent/inbox/spliced 行——这些行负责把该轮次的用户消息排入队列,如果保留它们却丢掉消息,inbox 投影就会指向已不存在的事件。
* 切割时必须删除投影缓存。它的记录按生命周期标识(formatVersion、createdAt、cwd、isSeeded),而不是日志的修订号,所以留在原地的缓存会提供一个截断之前的投影——比它本该汇总的日志还要超前。记录缺失就当作不存在,harness 会重新折叠,这才是正确答案;等 harness 写入下一个检查点,侧边栏标题就会恢复。
* 末尾帧损坏时,重写会被拒绝,而不是静默丢弃已提交的事件;打开一次会话,让后端修复尾部,然后重试。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
giriimuls/dsh-chat-eraser
删除整个会话或单个轮次,并清理残留文件
相关插件 · 市场 / 管理
插件精选列表awesome-dsh-plugin/awesome-dsh-plugin
DeepSeek Harness(dsh)插件精选列表
★ 22,399未汉化DSH
73.6
新词雷达zhuyansen/new-term-radar
new-term-radar新词雷达
★ 2,049已汉化MCP
72.8
插件生态导航0xsline/awesome-deepseek-harness
安装 贡献指南 DeepSeek Docs 公开插件目录 Issues
★ 1,188已汉化DSH
72.6
技能注册中心iflytek/skillhub
企业级开源智能体技能注册中心——发布、发现并管理组织内可复用的技能包。
★ 5,384已汉化DSH
71.9
插件市场目录imsai-sh/awesome-deepseek-harness-plugins
面向 DeepSeek Harnessdsh生态的社区插件目录,共收录 13950 个插件含 PR 收录与…
★ 360已汉化DSH
71.9
插件精选清单Anil-matcha/awesome-dsh-plugin
DeepSeek Harnessdsh精选指南——DeepSeek…
★ 1,013已汉化DSH
71.7
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。