给 DeepSeek Harness 侧栏的会话菜单补上「停止」与「删除」,并在有新版本时提示更新。
31.2/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/11/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add BG0EXM/dsh-session-remove该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · browser
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 3 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件发起外部网络请求
查看扫描证据(共 16 处,展示前 15 条)
- 删除本地文件递归index.js:642
await rm(directory, { recursive: true, force: true }); - 读取本地文件index.js:726
root = await realpath(cwd); - 读取本地文件index.js:734
excluded.push(await realpath(entry)); - 读取本地文件index.js:749
entries = await readdir(directory, { withFileTypes: true }); - 读取本地文件index.js:764
info = await lstat(path); - 读取本地文件index.js:807
const info = await lstat(file.path); - 删除本地文件index.js:811
await rm(file.path, { force: true }); - 读取本地文件index.js:821
const info = await lstat(dir.path); - 删除本地文件index.js:823
await rmdir(dir.path); - 删除本地文件index.js:901
await rm(path, { force: true }); - 删除本地文件递归index.js:915
await rm(aliasDir, { recursive: true, force: true }); - 删除本地文件index.js:917
await rm(object, { force: true }); - 发起网络请求index.js:1087
const response = await fetch(url, { - 写入本地文件index.js:1272
void appendFile(state.logPath, `${entry.time} ${line}\n`, "utf8").catch(() => {}); - 发起网络请求client.js:307
const response = await fetch(path, {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 一键停止会话
- 永久删除会话数据
- 清理日志与缓存
在侧边栏菜单里停止并删除 DeepSeek Harness 会话:先取消正在运行的回合、子代理、后台任务和提醒,再删掉日志、投影缓存和工作区记录。
README
由 DeepSeek 最新模型翻译生成dsh-session-remove
给 DeepSeek Harness 侧栏的会话菜单补上「停止」与「删除」,并在有新版本时提示更新。
中文 · English
版本:1.0.6 | 更新:2026-10-31
1.0.6 变更:适配并实测 DSH 0.2.1-rc.5;更新提示改为「只提示 + 打开插件页」,并在标题/正文标明插件名与包名(装了很多插件也能认出是谁)——官方把插件升级定义为 profile 级操作,第三方插件需卸载后重装(HMR 下管理器还会直接抛 already-installed);附件回收补齐文件类附件的本体与别名;peer 上界收紧为 <0.3.0-0,并补充内部 API 依赖与多实例说明。
DSH 的会话行菜单只有 重命名 / 分叉 / 归档 —— 归档只是把会话藏起来,日志一个字节都没少;而想停掉一个会话的工作,你得先打开它、再按停止。这个插件把这两件事都放回你最常点的位置(会话行的 ⋯ 菜单)。
⋯ 菜单 → 停止会话… 取消运行中的回合、子代理、后台任务与定时提醒 → 删除会话… 永久删除该会话的本地数据(不可恢复)
安装后不需要重启 DSH,也不需要刷新页面。
为什么不是又一个 DOM 补丁
同类插件普遍靠注入 DOM 或沿 React fiber 取行数据来塞菜单项,核心 UI 一改就可能失效。
展开完整文档(README 剩余 1 节)
dsh-session-remove 给 DeepSeek Harness 侧栏的会话菜单补上「停止」与「删除」,并在有新版本时提示更新。 中文 · English 版本:1.0.6 | 更新:2026-10-31 1.0.6 变更:适配并实测 DSH 0.2.1-rc.5;更新提示改为「只提示 + 打开插件页」,并在标题/正文标明插件名与包名(装了很多插件也能认出是谁)——官方把插件升级定义为 profile 级操作,第三方插件需卸载后重装(HMR 下管理器还会直接抛 already-installed);附件回收补齐文件类附件的本体与别名;peer 上界收紧为 <0.3.0-0,并补充内部 API 依赖与多实例说明。 DSH 的会话行菜单只有 重命名 / 分叉 / 归档 —— 归档只是把会话藏起来,日志一个字节都没少;而想停掉一个会话的工作,你得先打开它、再按停止。这个插件把这两件事都放回你最常点的位置(会话行的 ⋯ 菜单)。 ⋯ 菜单 → 停止会话… 取消运行中的回合、子代理、后台任务与定时提醒 → 删除会话… 永久删除该会话的本地数据(不可恢复) 安装后不需要重启 DSH,也不需要刷新页面。 为什么不是又一个 DOM 补丁 同类插件普遍靠注入 DOM 或沿 React fiber 取行数据来塞菜单项,核心 UI 一改就可能失效。 本插件走的是官方开放的扩展点: - 菜单项注册进官方 slot sidebar.workspaces.session.menu.item —— Pin / Rename / Fork / Archive 本身就是这个 slot 里的注册项,插件行按 order 排序; - 停止走官方的 workspace/session-stop 准入(ctx.workspaceRegistry.stopSessionActivity()),由 dsh-agent / dsh-subagent / dsh-jobs / dsh-schedule 四个 provider 分别停掉回合、子代理、后台任务与提醒; - 删除通过 ctx.workspaceRegistry 与 storageDomain 的公开 API 完成,不 shell 出 rm; - 删完 emit 官方事件 api-session/removed(会话被销毁时会话控制器自己发的那条),侧栏该行当帧消失; - 只删能自证身份的目录:日志路径由持久化后端的 locate() 给出,并要求 basename(dir) === sessionId,否则直接拒绝而不是猜。 安装 桌面版:侧栏 → 插件 → 添加插件 → 填包名 dsh-session-remove 其它 profile(web / tui / 自建) dsh plugin --profile web add dsh-session-remove 中国用户注意:如果你的 npm 默认源是 registry.npmmirror.com,新发布的包在镜像上可能有同步延迟。若安装时报「declares no dsh.bundle」,请在安装对话框里把安装源改成 npm 官方源,或改用 tarball 地址: https://registry.npmjs.org/dsh-session-remove/-/dsh-session-remove-<版本号>.tgz 升级:本插件带更新提示(见下),也可以在插件页卸载后重新安装。 用法 鼠标移到侧栏任意会话行 → 点 ⋯: | 菜单项 | 做什么 | | 停止会话… | 取消运行中的回合,并停掉该会话的子代理、后台任务与定时提醒 | | 删除会话… | 永久删除该会话的本地数据 | 停止的一个要点:这条停止路径与归档用的是同一条(workspace/session-stop),它丢弃排队中的输入(界面上的停止按钮会保留)。确认框里写明了这一点。 0.2.1-rc.5 的官方归档对话框也提供「停止并归档」(停止后还会把会话从列表藏起来);本插件的「停止会话…」只停止、不归档、不改变会话可见性,这是它与官方归档的差别。 删除遇到仍在跑的工作时,弹窗会说明原因并多给一个 停止并删除 按钮,一步完成。 删除的是什么 | 位置 | 内容 | | $DSH_HOME/sessions/<项目>/<会话id>/ | 会话日志(session.v4.jsonl.zstd)与写租约,整个目录移除 | | $DSH_HOME/sessions/<项目>/<子代理会话id>/ | 该会话名下每一层子代理 / 团队会话的日志与写租约,同样整目录移除 | | session_projcache 存储域 | 该会话及每个子代理会话的投影检查点记录 | | $DSH_HOME/storages/workspace.json | 工作区成员位置、置顶、归档记录 | | 可选:会话工作区里的新建文件 | 勾选「同时删除本会话产生的文件」后,删除会话创建之后新建的文件,并移除因此变空的目录 | | 可选:$DSH_HOME/attachments/v1/… | 同一勾选会回收只被该会话引用的内容寻址附件:图片删除 objects/… 本体;文件删除 files/… 别名目录与 file-objects/… 本体;仍被其它会话引用的附件保留 | | 页面 | api-session/removed 事件让该行立即消失,无需刷新 | 子代理会话是独立的存储会话:它们的目录和父会话并排放在同一个项目目录下,一旦父会话被删,侧栏、搜索和子代理寻址就都够不到它们了,所以删除必须连带清理。可以按需关闭: - id: session-remove name: 'dsh-session-remove' config: deleteSubagentSessions: false # 默认 true;关闭后只删选中的会话 分叉会话不连带删除:fork 产生的会话虽然也带 parentSession,但它是独立对话,不会随源会话消失。 工作区文件与附件默认不动,可显式勾选清理。工作区是项目目录,可能被多个会话共用;附件按哈希跨会话去重。因此这两类数据默认不会删除。删除对话框会先询问宿主,存在候选时给出带数量的选项: - 「同时删除本会话产生的文件(N 个工作区文件、M 个附件)」——默认不勾选; - 勾选后只删除会话创建之后新建的工作区文件(已存在的文件即使被覆盖也不会删),然后移除因此变空的目录; - 附件只回收不再被任何其它持久化会话引用的对象;枚举失败或其它会话超过 64 个时跳过并告警; - 想让它每次都自动执行(不再询问),配置 deleteSessionFiles: always;完全不清理用 off: - id: session-remove name: 'dsh-session-remove' config: deleteSessionFiles: confirm # confirm(默认)| always | off 搜索索引不需要额外处理:它按持久化列表对账,会话从列表消失即被清理。 安全边界 | 情况 | 行为 | | 仍有回合 / 子代理 / 后台任务 / 定时提醒 | 拒绝,并提供「停止并删除」 | | 停止后仍在收尾(有界等待内未清零) | 拒绝,提示稍候再试 | | 某个子代理会话仍在运行 | 先停止并等待;收尾不过来则拒绝,父会话的文件此时一个都还没动 | | 会话仍被进程持有 | 先释放它再删(见下) | | 释放后的持久化屏障失败 | 拒绝,避免活句柄把刚删的日志写回来 | | 子代理会话定位失败 | 父会话照常删除,对话框报告哪些子代理数据没清掉 | | 无法枚举子代理会话(存储列表读取失败) | 拒绝,避免只删掉一半数据 | | 工作区文件候选 | 仅在显式勾选(或 always)时删除;扫描按创建时间归属,已存在的文件绝不删除 | | 附件仍被其它会话引用 | 保留,不回收 | 为什么删除前要先释放:一个还活着的写句柄会在下一次 flush 时把刚删掉的日志重新创建出来。 注册表的归档流程把释放交给会话的登记方,而 seam 没给第三方留受支持的入口,所以插件调用存储服务的公开方法 detachEntered(entry),并在删除文件前跑一次持久化屏障: 释放会话 → 停止工作 → 等待清零 → flush 屏障 → 删除文件 两处顺序都不能颠倒:先释放再停止,否则被停止的会话会唤醒 agent 去处理被杀任务的结果、甚至重新启动新的工作,那份新工作会活过删除变成孤儿;先释放再删文件,否则写句柄会把日志写回来。 取不到释放凭据(不同版本)时会退化为拒绝并提示先切换会话——功能降级,但绝不会留下半删状态。 每个子代理会话也走同一条链路:先停掉并等它清零、释放它,再随父会话的文件一起删除;任何一个子代理会话还在跑或还持有写句柄,都会在父会话的文件被碰之前拒绝掉。 删除父会话后若有子代理数据没能清掉,对话框会明确列出会话 id,不会假装全部成功。 删除当前正在查看的会话后,主区域会自动回到空状态(与官方归档当前会话的行为一致),不会停在已经不存在的旧页面。 更新提示 插件会定期问一次注册表(默认 npm 官方源,失败回退 npmmirror)自己是不是最新版, 只提示、不自动安装:右下角出现一条可关闭的提示,按钮是「打开插件页」与「稍后」。 提示标题写明插件名(「会话停止与删除 有新版本」),正文重复 npm 包名与新旧版本号——同时装了很多插件时,用户也能一眼认出这条提示属于哪个插件。 这是对齐 DSH 的插件管理模型:插件包属于 profile 级状态,「插件」页负责安装与卸载;官方文案明确 “按需安装的官方插件才提供『更新』,其他插件请先卸载再安装新版”,并且挂了 HMR 时 pluginManager.installBundle() 会对已安装的包直接抛 already-installed。因此本插件不尝试 覆盖自己(那还会在请求中途卸载正在响应它的宿主半),只把用户送到插件页完成升级。 session-delete.install-update 路由保留给旧版页面半,返回同一段指引而不是安装。 包名取自自身的 package.json,默认即可工作;只有把包部署成别名时才需要覆盖 updatePackageName。 配置 所有字段都是可选的,写在插件行的 config 下: | 字段 | 默认值 | 说明 | | deleteSubagentSessions | true | 删除会话时连带删除其名下所有子代理 / 团队会话;false 只删选中的会话 | | deleteSessionFiles | confirm | 工作区文件与附件清理策略:confirm(弹窗勾选)、always(每次自动)、off(从不);也接受 true(等于 always)与 false(等于 off) | | updateMode | notify | notify 只提示新版本;off 关闭更新检查 | | updateRegistry | https://registry.npmjs.org/ | 更新检查使用的注册表 | | updateFallbackRegistry | https://registry.npmmirror.com/ | 主注册表失败时的回退 | | updateIntervalMs | 21600000(6 小时) | 检查间隔,最小 60000(1 分钟) | | updatePackageName | 自身包名 | 仅在以别名发布时需要覆盖 | | stopWaitMs | 10000 | 停止后等待工作清零的上限(毫秒),最小 500 | | logPath | $DSH_HOME/plugin-session-remove.log | 调试日志路径 | | debugLog | true | 设为 false 关闭调试日志 | 工作原理 | 半边 | 文件 | 职责 | | Host | index.js | 在 /api 鉴权围栏内注册 7 条精确 Fetch 路由:session-delete.delete / .inspect / .stop / .update-state / .install-update(仅返回升级指引)/ .client-ready / .status | | Client | client.js | 注册两个菜单项与一个 shell.overlay 条目(确认框 + 更新提示),中英双语跟随界面语言 | 浏览器半与宿主半同源通信,凭据由浏览器会话自动携带。 兼容性 - 实测 DSH 0.2.1-rc.5(DeepSeek Harness Desktop,2026-10-31;宿主半与页面半均真实加载、 client-ready 路由连通),以及 0.2.0-rc.2 / 0.2.1-rc.1 - 0.2.1-rc.1 → rc.5:本插件依赖的 24 个 DSH 包运行时 JS 逐字节相同(仅版本戳);宿主 API、持久化 locate/stat/list/open/flush、workspace 注册表、session_projcache 域、 api-session/removed、两个客户端 slot 与 connection.fetch.register 均未变化 - 会话日志格式仍为 v4(session.v4.jsonl.zstd,目录内另有 session.lock);删除时先从持久化后端 locate() 拿到目录,再整目录移除,不依赖文件名 - 兼容性门禁按 includePrerelease 评估 peer 范围:>=0.2.0-rc.2 <0.3.0-0 覆盖 rc.5;上界写成 -0 是为了不把下一个 minor 的预发布(如 0.3.0-rc.1)误放进来 - 依赖 0.2.1-rc.5 的一些内部面:sessions.store + detachEntered、 workspaceRegistry.headers/sessionPaths、storageDomain.get()(诊断面)。取不到时会明确拒绝删除 而不是误删;宿主升级后建议回归一次 - 需要组合里存在 connection / sessionPersistence / workspaceRegistry(Web profile 默认满足) - 仅面向单实例桌面:多实例或共享 persistence root 时删除会移除 session.lock,写租约互斥会失效 - 零依赖、零构建 排查 插件会写一行/次操作到 $DSH_HOME/plugin-session-remove.log: host half active (build r5-unified@1.0.6, 7 routes, update mode notify) client half mounted (features=stop,delete,update+menu=sidebar.workspaces.session.menu.item,overlay=shell.overlay) update check: current 1.0.6, latest 1.0.7 (update available) stop session-…: asked job (settled: true) released session-… from the live store found 2 subagent session(s) under session-… session files for session-…: 1 workspace file(s), 1 dir(s), 1 attachment(s) deleted session-… (+2 subagent sessions +3 session files) (session-dir:…, projection-cache) refused session-…: session-held - 没有 client half mounted → 页面半没装载(检查插件是否启用、页面是否刷新过) - refused <id>: → 宿主拒绝了这次操作,代码含义见「安全边界」 - refused <id>: session-release-unsupported → 当前 DSH 版本没有暴露安全释放入口;先切换到别的会话再删,或把 DSH / 本插件升级到相互匹配的版本 - 安装时报 declares no dsh.bundle → 见「安装」里的镜像同步说明 已知限制 - 删除不可恢复:没有回收站,也没有撤销。 - 子代理会话默认随父会话一并删除;用 deleteSubagentSessions: false 可关闭这一连带行为。 - 分叉会话是独立对话,删除源会话不会删掉它(即使它带 parentSession)。 - 子代理会话清理失败时父会话仍然会被删除(用户的主要意图已完成),残余目录只能在磁盘上手工处理;对话框会列出会话 id。 - 工作区清理是按创建时间的启发式归属:会话期间被覆盖的已有文件不会被删除(只会留下新内容),扫描有 2 万条目上限,超出部分会跳过并告警。 - 附件是内容寻址去重的;只有确认不再被其它会话引用的对象才会回收,被共享的附件保留。 文件类附件会连同 files/… 别名目录与 file-objects/… 本体一起删除;无法识别的宿主布局只删别名并保留本体。 - 删除正被界面打开的会话时会被先释放(主区域回到空状态)。 - 「停止」会丢弃排队中的输入,这是它所复用的官方停止路径的语义。 - 更新必须到「插件」页卸载后重新安装新版:插件不自行覆盖已安装的包(HMR 下管理器会以 already-installed 拒绝,且卸载正在响应请求的宿主半会中断请求);重装后旧宿主模块留到重启/重载,这是 DSH 的模块世代语义。 - 多实例 / 共享 persistence root 场景不要使用删除功能(会移除 session.lock,跨进程写租约失效)。 测试 测试不随 npm 包分发(files 白名单中没有 test/),安装后的插件目录不含测试文件。 仓库内运行:node --test test/.test.mjs(Node 22 下不要写成 node --test test/)。 Version: 1.0.6 | Updated: 2026-10-31 1.0.6 changes: verified against DSH 0.2.1-rc.5; the update notice is now report-only and hands the user to the Plugins page, naming the plugin and its package in the title/body so a user with many plugins can tell whose notice it is — DSH treats plugin upgrades as profile-level state and 第三方插件通过卸载再安装来更新(开启 HMR 时,管理器也会拒绝,提示 already-installed);文件附件连同其 digest body 一起回收;peer 上限收紧到 <0.3.0-0;内部 API 依赖与单实例边界已写入文档。 DeepSeek Harness 的会话行菜单只提供 Rename / Fork / Archive —— 归档只是隐藏会话,磁盘上的每个字节都还在;要停止会话的工作,得先打开会话再按 Stop。这个插件把这两项放回你本来就在点的位置:会话行的 ⋯ 菜单。 ⋯ menu → Stop Session… cancels the running turn, subagents, background jobs and reminders → Delete Session… permanently removes that session's local data (no undo) 安装后无需重启 DSH,也无需刷新页面。 为什么不用另一种 DOM 补丁 同类插件靠注入 DOM 节点或遍历 React fiber 来添加菜单项,核心 UI 一改就可能失效。这个插件只用开放的扩展点: - 菜单项注册进官方插槽 sidebar.workspaces.session.menu.item —— Pin / Rename / Fork / Archive 也是注册在同一插槽里的条目,所以插件菜单项按自己的 order 排序; - 停止走官方 workspace/session-stop 准入(ctx.workspaceRegistry.stopSessionActivity()),由 dsh-agent / dsh-subagent / dsh-jobs / dsh-schedule 分别应答轮次、子代理、后台任务和提醒; - 删除使用公开的 ctx.workspaceRegistry 和 storageDomain API —— 从不调用 rm; - 删除会发出官方 api-session/removed 事件(Session 控制器在销毁活动 Session 时自己发出的就是它),菜单项当场消失; - 只删除能证明自身身份的目录:日志路径取自持久化后端的 locate(),且必须满足 basename(dir) === sessionId,否则插件直接拒绝,不做猜测。 安装 Desktop: sidebar → Plugins → Add plugin → enter the package name dsh-session-remove Other profiles (web / tui / custom) dsh plugin --profile web add dsh-session-remove 用的是 npmmirror 镜像源? 刚发布的包在镜像上可能滞后。如果安装被拒并提示 declares no dsh.bundle,在对话框里把 Install source 切到官方 npm 源,或用 tarball URL 安装 https://registry.npmjs.org/dsh-session-remove/-/dsh-session-remove-<version>.tgz。 升级:这个插件会给出更新提示(见下文),也可以在 Plugins 页面卸载后重装。 用法 把鼠标悬停在侧边栏任意会话行上 → 点击 ⋯: | 菜单项 | 作用 | | Stop Session… | 取消正在运行的轮次,并停止该会话的子代理、后台任务和提醒 | | Delete Session… | 永久删除该会话的本地数据 | 关于停止,有一点需要知道:它和 archive 走同一条路径(workspace/session-stop),并且会丢弃排队中的输入(会话内的停止按钮会保留这些输入)。确认对话框里写明了这一点。 在 0.2.1-rc.5 中,内置的 archive 对话框还提供「停止并归档」(先停止工作,再隐藏会话);本插件的 Stop Session… 只停止——不归档,行仍然可见。这就是它与内置 archive 的区别。 当删除遇到正在运行的工作时,对话框会说明原因,并提供一个 Stop and delete 按钮,一步完成两件事。 删除的内容 | 位置 | 内容 | | $DSH_HOME/sessions/<project>/<session-id>/ | 会话日志(session.v4.jsonl.zstd)及其写入租约——整个目录 | | $DSH_HOME/sessions/<project>/<subagent-session-id>/ | 其下每个子代理 / 队友会话的日志和写入租约,任意深度——同样是整个目录 | | session_projcache 存储域 | 该会话及每个子代理会话的投影检查点记录 | | $DSH_HOME/storages/workspace.json | 工作区成员关系、固定和归档条目 | | 可选:会话在其工作区中创建的文件 | 勾选对话框中的「同时删除本会话产生的文件」后,会话启动后创建的文件会被删除,随后删除因此变空的目录 | | 可选:$DSH_HOME/attachments/v1/… | 同一选项会回收仅被该会话引用的内容寻址附件:图片的 objects/… 正文、文件的 files/… 别名目录及其 file-objects/… 正文;其他会话仍在引用的对象会保留 | | 页面 | api-session/removed 事件移除该行,无需刷新 | 子代理会话是单独存储的 Session:它的目录与父会话目录同级,位于同一项目目录下;父会话一旦删除,侧边栏、搜索和子代理寻址都无法再找到它——所以删除必须一并带走它。可按配置档关闭: - id: session-remove name: 'dsh-session-remove' config: deleteSubagentSessions: false # default true; then only the selected session is deleted 分叉不会级联删除:分叉的对话也会记录 parentSession,但它是独立对话,源会话删除后它仍然存在。 工作区文件和附件默认不动,清理它们是明确的选择。 工作区是项目目录,其他会话可能共用;附件按内容哈希跨会话去重,所以两者都不会被隐式删除。删除对话框向 Host 询问候选,并提供一个带计数的选项: - 「同时删除本会话产生的文件(N 个工作区文件,M 个附件)」——默认不勾选; - 勾选后,只删除会话启动后创建的文件(预先存在的文件即使会话覆盖了它的内容,也从不删除),然后删除它们留下的空目录; - 只有当没有其他已存储会话引用附件对象时,才回收它们;如果无法枚举其他会话,或这类会话超过 64 个,就跳过清扫并给出警告; - 用 deleteSessionFiles: always 让它自动执行,或用 off 完全关闭: - id: session-remove name: 'dsh-session-remove' config: deleteSessionFiles: confirm # confirm (default) | always | off 搜索索引不需要额外处理:它会与持久化列表对账,所以会话离开该列表时,也会离开索引。 安全边界 | 情况 | 行为 | | 轮次 / 子代理 / 后台任务 / 提醒仍在运行 | 拒绝,并提供 Stop and delete 操作 | | 停止在限时等待内没有落定 | 拒绝,请你稍后重试 | | 子代理会话仍在运行 | 先停止并等待;如果仍未落定,就在触碰任何父文件之前拒绝 | | 会话仍被当前进程持有 | 先释放,再删除(见下文) | | 释放后的持久化屏障失败 | 拒绝,这样打开的句柄无法重写已删除的日志 | | 找不到子代理会话 | 仍删除父会话;对话框会列出被留下的子代理数据 | | 无法枚举子代理会话(持久化列表失败) | 拒绝,这样在未知子会话仍存在时,父会话绝不会被删除 | | 工作区文件候选 | 仅在显式检查后(或 always)删除;归属按创建时间判断,已存在的文件绝不删除 | | 另一个会话仍引用的附件 | 保留,绝不回收 | 为什么先释放被持有的会话:活跃的写句柄会在我们删除日志后立刻把它刷回存在状态。注册表的归档流程依赖 Session 自己的所有者来释放它,而接缝没有给第三方插件提供受支持的释放方式,所以插件调用存储服务的公开方法 detachEntered(entry),并在触碰任何文件之前运行持久化屏障: release the session → stop its work → wait for it to settle → flush barrier → remove files 两个顺序都不能交换:先释放再停止,否则被停止的会话会唤醒它的智能体去消费被终止任务的结果,甚至可能启动新工作——这会作为孤儿活过删除;先释放再删除文件,否则写句柄会重建日志。当释放凭据不可用(DSH 版本不同)时,插件降级为拒绝,并请你切换会话——绝不会出现删了一半的状态。 每个子代理会话都走同一条流水线:停止它、等待它落定、释放它,然后连同父会话的文件一起删除。仍在运行或仍持有写 handle 会在改动任何父文件之前,拒绝整个删除操作。如果父文件已经删除,部分子代理数据却清理不掉,对话框会列出会话 id,而不是假装全部成功。 删除主区域正在显示的会话会清空该视图(内置归档对当前会话也是这个效果),所以你永远不会停留在一个已经不存在的对话上。 更新提示 插件会定期向 registry 查询是否有新版本(优先官方 npm,失败时回退到 npmmirror),并且只做提示:右下角出现一条可关闭的提示,带 Open Plugins 和 Later 按钮。标题里写明插件名(「Stop & Delete Sessions has an update」),正文重复 npm 包名和两个版本号,这样装了很多插件的用户也能看出这条提示属于谁。 这遵循 DSH 的插件模型:插件包属于配置档级状态,安装和卸载由 Plugins 面板负责。面板自己的文案说,按需加载的 Official 插件有 Update 按钮,其他插件则通过卸载再重装来更新;挂载 HMR 后,pluginManager.installBundle() 还会以 already-installed 拒绝已安装的包。所以本插件从不覆盖自身(那也会卸载正在应答请求的 Host 那一半),只把用户引导到面板。session-delete.install-update 路由为旧版页面保留,返回同样的指引,而不是执行安装。 包名取自插件自己的 package.json,所以无需配置即可工作;只有以别名部署时,updatePackageName 才有意义。 配置 每个字段都是可选的,写在插件行的 config 下: | 字段 | 默认值 | 含义 | | deleteSubagentSessions | true | 同时删除该会话下所有子代理 / 队友会话;false 只删除选中的会话 | | deleteSessionFiles | confirm | 工作区文件和附件策略:confirm(在对话框中询问)、always(每次删除都删)、off(从不删);true 视为 always,false 视为 off | | updateMode | notify | notify 只提示新版本;off 关闭更新检查 | | updateRegistry | https://registry.npmjs.org/ | 更新检查使用的 registry | | updateFallbackRegistry | https://registry.npmmirror.com/ | 主 registry 失败时尝试 | | updateIntervalMs | 21600000(6 小时) | 检查间隔;最小 60000(1 分钟) | | updatePackageName | 包自身的名称 | 仅在以别名部署时需要 | | stopWaitMs | 10000 | 等待已停止的工作清理完毕的上限,单位毫秒;最小 500 | | logPath | $DSH_HOME/plugin-session-remove.log | 诊断日志路径 | | debugLog | true | 设为 false 关闭诊断日志 | 工作原理 | 部分 | 文件 | 职责 | | Host | index.js | /api 鉴权围栏内的七条精确 Fetch 路由:session-delete.delete / .inspect / .stop / .update-state / .install-update(仅提示)/ .client-ready / .status | | Client | client.js | 两行菜单和一条 shell.overlay 条目(确认框 + 更新提示),双语,跟随 UI 语言 | 浏览器端与 Host 端同源通信;浏览器会话携带凭据。 兼容性 - 已在 DSH 0.2.1-rc.5 上验证(DeepSeek Harness Desktop,2026-10-31:两端均加载成功, client-ready 路由完成),另外也验证了 0.2.0-rc.2 / 0.2.1-rc.1 - rc.1 → rc.5:本插件依赖的 24 个 DSH 包在运行时字节一致(仅版本号不同);Host API、持久化 locate/stat/list/open/flush、工作区注册表、session_projcache 域、 api-session/removed、两个客户端插槽以及 connection.fetch.register 均未变化 - 存储的会话格式仍是 v4(session.v4.jsonl.zstd,旁边有 session.lock);删除时从持久化后端的 locate() 取得目录,整个删除,因此不依赖文件名 - 兼容性门禁用 includePrerelease 评估 peer 范围,>=0.2.0-rc.2 <0.3.0-0 覆盖 rc.5;上界 -0 把下一个小版本的预发布版(如 0.3.0-rc.1)排除在外 - 用到了一些内部接缝:sessions.store + detachEntered、 workspaceRegistry.headers/sessionPaths、storageDomain.get()(诊断接口)。缺少其中任何一个时, 插件会以具名错误码拒绝,而不是在活动句柄下执行删除;Host 升级后请重新测试 - 组合中需要 connection / sessionPersistence / workspaceRegistry(Web 配置档提供全部三项) - 仅支持单实例桌面:多实例或共享持久化根目录时,删除会移除 session.lock,跨进程写租约不再保护日志 - 零依赖,无需构建步骤 故障排查 插件每发生一个事件就向 $DSH_HOME/plugin-session-remove.log 追加一行: host half active (build r5-unified@1.0.6, 7 routes, update mode notify) client half mounted (features=stop,delete,update+menu=sidebar.workspaces.session.menu.item,overlay=shell.overlay) update check: current 1.0.6, latest 1.0.7 (update available) stop session-…: asked job (settled: true) released session-… from the live store found 2 subagent session(s) under session-… session files for session-…: 1 workspace file(s), 1 dir(s), 1 attachment(s) deleted session-… (+2 subagent sessions +3 session files) (session-dir:…, projection-cache) refused session-…: session-held - 没有 client half mounted → 页面端未加载(检查插件是否启用,并刷新页面) - refused <id>: → Host 拒绝;错误码见「安全边界」一节 - refused <id>: session-release-unsupported → 当前 DSH 版本没有暴露安全的释放接口;删除前先切换到其他会话,或者把 DSH / 本插件升级到匹配的版本 - 安装时报 declares no dsh.bundle 并拒绝 → 见 Install 下的 registry 说明 已知限制 - 删除是永久的:没有回收站,没有撤销。 - 默认情况下,子代理会话随父会话一起删除;deleteSubagentSessions: false 可关闭这层级联。 - 分叉出的对话是独立的:删除它的来源不会删除分叉,即使分叉记录了 parentSession。 - 如果子代理会话清理不掉,父会话仍然会被删除(用户的主要意图已经达成),残留项需要手动处理;对话框会列出这些会话 id。 - 工作区清理是创建时启发式:会话覆盖过的既有文件不会被删除(新内容保留),遍历上限为 20,000 个条目,跳过的其余部分会报告出来。 - 附件按内容寻址并去重;只回收没有其他会话引用的对象,共享的保留。文件附件会同时失去 files/… 别名目录和 file-objects/… 正文;遇到无法识别的 Host 布局时只删除别名。 - 删除 UI 中打开的会话会先释放它(主区域回到空状态)。 - 停止会丢弃排队的输入——这是它复用的官方停止路径的语义。 - 更新必须从 Plugins 页面执行(先卸载,再安装新版本):插件从不覆盖已安装的包(HMR 下管理器会以 already-installed 拒绝,而卸载处理该请求的 Host 半边会中止它)。重装后旧 Host 模块留在内存里,直到下次重启/重载——这是 DSH 的模块代际语义。 - 不要在多个实例或共享持久化根的情况下使用删除:它会移除 session.lock,跨进程写租约就不再保护日志。 测试 测试不属于 npm 包(test/ 不在 files 白名单里),所以安装后的插件副本不含测试文件。在检出目录里运行 node --test test/.test.mjs(Node 22 上不要写 node --test test/)。 License MIT
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
BG0EXM/dsh-session-remove
给 DeepSeek Harness 侧栏的会话菜单补上「停止」与「删除」,并在有新版本时提示更新。
相关插件 · 浏览器
智能体插件框架deepseek-ai/deepseek-harness
DeepSeek Harnessdsh是由 DeepSeek AI 开发的开源 agent harness智能体框架。
★ 270,422已汉化DSH
71.9
多设备 Agent 看板YaoApp/yao
✨ 所有 Agent 和工作区集中管理,覆盖你的每一台设备。任务看板追踪进度,桌面端、移动端、浏览器、API…
★ 8,147已汉化DSH
71.2
可扩展侧边栏工作台omdsh-dev/DSH-better-sidebar
DSH 的双工作台:原生右侧栏 + 自绘底部面板,并把 ctx.betterSidebar 服务开放给所有插件
★ 4,761已汉化DSH
71.1
浏览器自动化桥Tencent/BrowserSkill
你的 Agent。你的浏览器。连接,就能协作。
★ 9,967已汉化DSH
71
AI 小说创作工作台EthanYoQ/AI-Novel-Writer
AI 小说作家 / AI Novel Writer
★ 1,591已汉化DSH
70.7
智能体浏览器引擎platonai/Browser4
DeepSeek Harness 集成
★ 1,175已汉化DSH
70.4
这是你的仓库?认领条目