liangmianya/dsh-synapse
liangmianya/dsh-synapseDeepSeek Harness 的可视化非线性对话工作区:把会话、追问与分支变成可浏览、可拖拽的对话地图。
在 DSH 侧栏会话菜单中加入一键「删除会话」:把会话日志与该对话的 .dsh-sessions 产出目录移入 Windows 回收站,没有确认弹窗。
给 DSH(DeepSeek Harness)侧栏补上删除单个会话:会话行「⋯」菜单的最后一项是红色 「删除会话」,点击后直接删除,不弹确认框,并立刻从侧栏消失。
同时给每个对话建立独立的产出目录(.dsh-sessions/<session-id>/),删除对话时连同
它产生的文件一起删除。
适用于 DSH 0.2.1-rc.2(Web / Desktop profile,主要面向 Windows 桌面端)。
| 入口 | 菜单项 | 行为 |
|---|---|---|
会话行 ⋯ 菜单(末位,分隔线 + 红色危险样式) | 删除会话 | 一键删除该会话,无确认弹窗;日志与产出目录进 Windows 回收站,可还原 |
一次点击处理以下内容:
| 内容 | 去向 |
|---|---|
| 会话日志(含子代理子会话) | Windows 回收站(~/.dsh/sessions/<项目>/<session-id>/ 可还原) |
| 该对话的产出目录 | Windows 回收站(<会话工作目录>/.dsh-sessions/<session-id>/ 可还原) |
| 投影缓存 | 永久删除(可再生缓存,~/.dsh/storages/session_projcache/sessions/<session-id>.json) |
| 工作区账目 / 置顶 / 归档集合 | detachSession、unpinSession、unarchiveSession |
回收站还原:删完后打开 Windows 回收站,找到名为该会话 id 的目录 → 还原。 日志回到原路径后,去 DSH 的「已归档」/「未分组」里点「取消归档」或重新打开即可。 投影缓存不会进回收站(它只是缓存,会重新生成);非 Windows 平台回退为永久删除并记录警告。
运行中的会话会先被安全停止:写归档集合(agent/pre-step 门禁)→ sessions.flush
持久化屏障 → 短暂等待 live 会话关闭视图 → 然后无条件继续删除。
不会因为「会话仍处于打开状态」而拒绝删除(0.4.1 起;旧版会误报 409 active)。
删除是幂等的:只有投影缓存残留的幽灵会话、甚至完全不存在的 id,都返回成功而不是
missing;物理删除失败时会回滚归档,让会话恢复可见而不是灰着不放。
删除完成后,如果该会话仍 live 在宿主内存里(只存在于内存、没落到磁盘的会话, 或视图还没释放的会话),插件会保持归档隐藏而不是取消归档 —— 否则宿主的 session 列表会让它重新出现在侧栏(典型表现:删掉后「未分组」又冒出一行)。等该会话被释放 或 DSH 重启后,启动对账会自动清掉归档条目。
会话 id 就是编号,shell 里可通过 DSH_SESSION_ID 读取(PowerShell
$env:DSH_SESSION_ID,bash $DSH_SESSION_ID)。插件为每个对话建立:
<工作目录>/.dsh-sessions/<session-id>/
outputs/ 交付给用户的文件
memory.md 该对话的持久记忆/结论
tmp/ 临时文件
AGENTS.md 可作为同样的兜底约定。parentSession 归属顶层对话,产出写进同一个编号目录。handleSessionRemoved 摘掉,并在启动后 0.8s / 3s 再兜底清理;CSS 隐藏继续保留。.dsh-sessions/<id> 产出目录改成经
SHFileOperationW(FOF_ALLOWUNDO)移入 Windows 回收站,可以从回收站还原;
投影缓存仍永久删除(可再生)。仍然是一键直删、无确认弹窗。非 Windows 平台回退为永久删除。workspaces.archiveSession 同步客户端归档集合;/diag 自动清理旧版本残留的「已归档 + live + 无落盘」幽灵行。unarchive,于是它又以「未分组」行出现。现在仍 live 的会话删除后保持归档隐藏,
不再复活;/diag 提供 live/workspace/queryList 只读诊断。GET /ping 改为只读、不设栅栏,便于排障。connection.requestRejection 认证/Host-Origin 栅栏、
64 KiB 请求体上限、live 会话的 sessions.flush 持久化屏障)。
按用户要求去掉 0.3.0 的确认弹窗和回收站流程,改为直接删除
(0.5.0 又按用户要求把回收站加回来,但仍然没有确认弹窗)。persistence.list() 快照
的错误层级读 id);菜单从 MutationObserver 克隆 DOM 改为官方 slot 注册。git clone https://github.com/zenghang25/dsh-session-delete.git C:\Users\<you>\Documents\dsh-plugins\dsh-session-delete
dsh plugin --profile desktop add "C:\Users\<you>\Documents\dsh-plugins\dsh-session-delete"
add 的参数必须是绝对路径。包 manifest 里的 dsh.bundle.patch 会让它自动成为
profile 的一个 bundle 层,无需手改 cordis.patch.yml。
装完完全退出桌面端再启动(Host 半与 Client 半都会重新加载)。
卸载:
dsh plugin --profile desktop remove dsh-session-delete
不依赖 DOM / React 内部结构,只用 DSH 0.2.x 的官方扩展点:
sidebar.workspaces.session.menu.item:会话「⋯」菜单行列表 slot,本插件 order = 500
(官方 pin/rename/fork/archive/session-id 之后),渲染一个 danger 样式的
MenuItemButton,useMenuOpenState 负责关菜单。agent/created(Host 事件):建立产出目录并注册 per-agent 系统提示词段。ctx.webServer 同源路由。| 路由 | 作用 |
|---|---|
POST /dsh-session-delete/delete | { sessionId } → 删除;最多 64 KiB JSON;有认证/Host-Origin 栅栏 |
GET /dsh-session-delete/ping | 只读健康检查:{ ok: true, version }(不设栅栏,便于排障) |
GET /dsh-session-delete/diag | 只读诊断:live 会话 / 工作区账目 / sessionQuery 列表(不设栅栏) |
删除顺序(有意设计):
sessionPersistence.list() 快照,id 在 header.id),
并沿 parentSession 收集子代理子会话;archiveSession(id, { stopActivity: true }):durable 归档集合是 agent/pre-step
门禁,先写它再停工作;已归档的会话先 unarchive 再归档,确保停止逻辑真的执行;sessions.flush(session);失败只记警告,不再中止删除;active;detachSession(workspace.sessionIds getter 会按会话是否仍存在过滤,
必须赶在删文件之前);persistence.locate() 精确路径 + 扫描会话根兜底)和 .dsh-sessions/<id>/
产出目录移入 Windows 回收站;投影缓存永久删除;unpinSession 清理置顶;仅对已不再 live 的会话 unarchiveSession
清理归档集合(仍 live 的保持归档隐藏,避免侧栏复活);
有失败:把临时归档的会话 unarchive 回滚成可见,返回失败详情供重试。启动时做一次轻量对账:清掉已不存在会话的归档 id 与孤立投影缓存。
rmrf 拒绝根目录式路径。~/.dsh/attachments/v1/objects/…)是内容寻址共享资源,不随会话删除。node test\host.test.mjs # 假 ctx + 真实临时目录,驱动真实路由
node test\client.test.mjs # 迷你 React/slot runtime,驱动真实注册组件
覆盖:认证栅栏、方法/参数校验、正常删除、子会话、幽灵会话、已归档会话、live 会话 (含一直不退出/flush 失败也照删)、删除失败回滚归档、产出目录、启动对账、ping。
MIT