dsh-history-purge
Manifest valid删除 / 回收 DSH 历史对话(会话)的插件:设置页批量管理、侧栏单条删除、回收站可还原,附离线 CLI。
dsh-history-purge
删掉 DSH 的历史对话(会话)——设置页批量管理 + 侧栏单条删除 + 回收站可还原 + 离线 CLI。
它做什么
| 入口 | 位置 | 能力 |
|---|---|---|
| 设置 → 历史对话 | 设置面板左侧导航(order 26) | 列出全部会话(标题 / 最近活动 / 大小 / 归属工作区 / 运行中 / 置顶 / 归档),勾选批量删除;回收站页可还原、永久删除、清空 |
| 侧栏会话「⋯」菜单 → 删除对话 | 每个会话行的菜单末尾(order 500) | 单条删除,进回收站 |
Agent 工具 history_purge | 模型可调用 | list / delete / restore / empty |
CLI dsh-history-purge | 终端 | 宿主没起床时也能删 |
默认删除 = 移入回收站($DSH_HOME/history-purge/trash/<时间戳>-<sessionId>/),默认保留 30 天后由宿主启动清理;permanent 才是直接抹盘。删除后会话会从侧栏、工作区账本、会话索引里一起消失;正在运行的会话默认拒删(勾「运行中的也删除」才放行)。
装
已在 web profile 里(本机路径安装,0.1.0):
dsh plugin --profile web add /home/qq/dsh-plugins/dsh-history-purge
# 然后把 dsh-history-purge 加进 profile 的 dsh.profile.bundles(plugin add 不会自己写)
重启 dsh web 生效:
~/.dsh/restart-dsh-web.sh
配置(profile 的 cordis.patch.yml)
- id: dsh-history-purge
name: dsh-history-purge
config:
trashRetentionDays: 30 # 回收站保留天数,0 = 永不自动清理
permanentByDefault: false # true = 删除直接抹盘,不进回收站
CLI
dsh-history-purge list --limit 20 # 看会话;--json 出机器可读
dsh-history-purge delete <id> [<id>...] # 进回收站
dsh-history-purge delete <id> --permanent # 直接抹盘
dsh-history-purge restore <trash-entry> # 从回收站还原
dsh-history-purge purge --all --yes # 永久清空回收站
dsh-history-purge sweep --days 7 # 按保留期清理
dsh-history-purge stats
在仓库目录里直接跑:node bin/dsh-history-purge.js list --home /tmp/fixture。
HTTP 桥
宿主半侧在 webServer 上注册五条同源路由(跨站 / sec-fetch-site: cross-site / Origin: null 一律 403):
GET /history-purge/state -> { sessions[], trash[], stats }
POST /history-purge/delete { ids: string[], permanent?: boolean, force?: boolean }
POST /history-purge/restore { entries: string[] }
POST /history-purge/purge { entries?: string[], empty?: boolean }
POST /history-purge/sweep {}
正在运行的会话默认拒删(force: true 才放行)——删盘但 Agent 还在跑,下一次 flush 会把日志写回来。
删除到底动了什么
$DSH_HOME/sessions/<project>/<sessionId>/—— 会话日志目录(移走或删除);$DSH_HOME/storages/session_projcache/sessions/<sessionId>.json—— 投影缓存(含标题);$DSH_HOME/storages/workspace.json—— 归账 / 归档 / 置顶三个 id 列表。宿主内走workspaceRegistry的detachSession,CLI 直接修剪 JSON。- 宿主内存里的 live 会话(
sessionsstore)—— 打开过的会话会被宿主一直持有,sessionQuery.listSessions()会把它们并进列表。删完磁盘后按 id 把它们摘出 store,并广播api-session/removed,已连上的页面立刻把这一行从侧栏摘掉。
归档位与置顶位随之解除,不会留下悬空引用。
删完回到「未分组」、再删报错是怎么回事
会话只要被打开过一次,宿主进程就会把它留在 sessions store 里;侧栏列表来自 sessionQuery.listSessions(),它会把 live 会话并进列表。于是只删磁盘时会出现经典的幽灵链:
- 删除成功,文件进了回收站;
- 工作区关联断了,但宿主仍然持有这个 live 会话 —— 侧栏于是把它落到**「未分组」**下继续显示;
- 再点删除:磁盘上已经没有它,旧实现回
session not found,界面报「失败」。
现在的处理(0.1.1 起):
- 摘 live 会话:按 id 从
sessionsstore 里detachEntered(entry),列表真的少一行,刷新也不会回来; - 广播
api-session/removed:已连上的页面不用等下一次拉取,立刻把该行摘掉; - 删除幂等:盘上没有、回收站里有 → 返回
ok:true, mode:"already-trashed";带permanent则顺手把回收站那份永久抹掉(mode:"purged", fromTrash:true)。重复点删除不再报错。
只有真正不存在的 id 才会回 session not found。
文件
| 文件 | 作用 |
|---|---|
| lib/core.js | 纯磁盘实现:列 / 删 / 还原 / 清空 / 过期清理,零 dsh 依赖 |
| lib/index.js | 宿主半侧:HTTP 路由、history_purge 工具、启动清扫、registry 摘账 |
| client.js | 浏览器半侧:设置分区 + 侧栏菜单项,纯 React + CSS,不引 ui-primitives |
| bin/dsh-history-purge.js | CLI |
| cordis.patch.yml | bundle 插入行 |
边界
- 只处理本机
$DSH_HOME;远端 / 多机历史不在范围内。 - 回收站是本插件自己的目录,DSH 原生没有「会话回收站」,所以被删会话不会再出现在任何原生界面里,只有本插件能还原。
- 摘 live 会话用的是
SessionStore的store(Map)与detachEntered()。这两处做了存在性检查与 try/catch:宿主换了内部结构只会退化成「没摘掉」,不会让删除失败。 - 会话日志是 app 的私有格式(zstd + JSONL,header 在第一行)。插件只读第一行取 id / cwd / createdAt,其余字节原样搬动,不做改写。
已验证(本机)
- 宿主半侧:5 条路由注册、同源 403、空 ids 400、缺失会话 200+失败条目、
history_purge工具 list/delete/restore 全通; - 浏览器半侧:在迷你 React harness 里渲染设置分区(标题/标签页/工具栏/列表/回收站/统计)与侧栏菜单项,均无错;
- 磁盘:真会话目录上跑通 回收站删除 → 还原 → 永久删除;
/dev/shm(tmpfs)与会话根跨设备时走cp + rm兜底,还原同样成功; - profile:
dsh plugin --profile web add已链入,dsh --profile web --dump-config里能看到id: dsh-history-purge,启动后GET /history-purge/state200; - 客户端 bundle:
/plugins/??dsh-history-purge/client.js&rev=...200,内容含__ModuleLoader__.load与settings.section。 - 真实浏览器端到端(Firefox 158 + geckodriver,真 UI):打开一个会话让它变成 live → 删除 → 返回里带
liveDetached,标题立刻从侧栏消失;整页刷新后它仍然不在(宿主侧确实摘掉了);同一个 id 再删一次返回already-trashed;带permanent再删返回purged(fromTrash: true);非 live 会话删除、回收站还原、永久抹盘同样通过。
仍然没覆盖到的一环:侧栏「⋯」菜单弹层本身的视觉与 setMenuOpen(false) 的收口 —— 上面的浏览器验证走的是同一条删除链路(同一份 call("/delete") + refreshSidebar()),但弹层是点击展开的,需要你实际看一眼。
回滚
dsh plugin --profile web remove dsh-history-purge
# 再从 profiles/web/package.json 的 dsh.profile.bundles 删掉该行
删插件不会动已删的会话;回收站里的东西留在 $DSH_HOME/history-purge/trash/,要恢复就装回来或手工搬回 sessions/<project>/<id>/。
发布到 GitHub
gh auth login --web # 或用 GH_TOKEN=ghp_xxx 代替
./scripts/publish.sh # 建仓 + 推送,仓库名默认 dsh-history-purge
./scripts/publish.sh my-name # 换仓库名
这台机器的 DNS 把 github.com 解析到 20.205.243.166(TCP 443 不通),而 140.82.113.3 /
20.27.177.113 / 140.82.121.3 可达。scripts/github-tunnel.mjs 是一个只做 CONNECT 的本地代理,
把这些域名粘到可达的边缘 IP;publish.sh 探测到直连不通时会自己拉起它,并把
http.proxy/https.proxy 指过去,推完自动清理。
不想用脚本时:
node scripts/github-tunnel.mjs &
export HTTPS_PROXY=http://127.0.0.1:8899
git remote add origin https://github.com/<you>/dsh-history-purge.git
git push -u origin main
Comments
Loading…
Similar plugins
by 3542967095
为 DeepSeek Harness 增加“删除对话 + 回收站”的插件:菜单删除、侧边栏预览、恢复与彻底删除。
★ 0
MIT
JavaScript
Oct 31, 2026
dsh plugin --profile web add dsh-plugin-session-deleteby jackxiao17
DSH 桌面版会话清理插件:侧栏 ··· 菜单一键删除会话入回收站,支持搜索、恢复、彻底删除与对话记录查看 | DSH desktop plugin: delete sessions from the sidebar ... menu into a recycle bin with search, restore, permanent delete and chat log viewer
★ 7
↓ 510/wk
MIT
JavaScript
Oct 30, 2026
dsh plugin --profile web add dsh-session-cleanerby new-256
DSH 会话清理宿主插件:侧边栏原生「移入回收站」+ 回收站管理页 + HTTP API(两级可恢复删除、同名防删错、活跃会话保护)
★ 0
↓ 296/wk
MIT
JavaScript
Sep 9, 2026
dsh plugin --profile web add @luchenglong/dsh-session-cleanerby Dcmwfg
DSH 插件:侧边栏会话三点菜单里加「删除会话」,确认后永久删除磁盘记录与投影缓存并立即从左侧列表移除。
★ 0
MIT
JavaScript
Oct 29, 2026
dsh plugin --profile web add dsh-session-menu-deleteby ShiraGawaAnri
DSH 会话/归档清理插件:在 **设置** 面板里新增两个页面,用来查看并清理 DSH 的残留会话与归档会话。
★ 0
MIT
JavaScript
Aug 16, 2026
dsh plugin --profile web add @dsh-external/dsh-session-cleanupby KuAgLan
dsh 插件: 在会话行「...」菜单增加 「删除会话」 选项
★ 0
JavaScript
Oct 29, 2026
dsh plugin --profile web add dsh-session-delete