DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-recall-plugin

Recall Plugin

在 DSH 中撤回自己发过的消息:工作区文件与对话历史一起回到那条消息发出之前,消息的文本与附件自动放回输入框,改完即可重发。文件走独立影子 git 快照(不碰项目自身的 git),对话走官方 sessions.fork,原会话归档可找回。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-recall-plugin@2.6.3
README兼容性版本
悬停出现撤回按钮确认面板 · 变更文件清单设置页

兼容性与来源证明

Recall Plugin 以 dsh-recall-plugin 发布,当前版本为 2.6.3。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/11/4

版本

2.6.3stable
2026/11/3
2.6.2stable
2026/11/2
2.6.1stable
2026/10/30
查看其余 66 个版本收起版本
2.6.0stable
2026/10/30
2.5.3stable
2026/10/30
2.5.2stable
2026/10/28
2.5.1stable
2026/10/27
2.5.0stable
2026/10/23
2.4.16stable
2026/10/18
2.4.15stable
2026/10/18
2.4.14stable
2026/10/17
2.4.13stable
2026/10/17
2.4.12stable
2026/10/15
2.4.11stable
2026/10/14
2.4.10stable
2026/10/7
2.4.9stable
2026/10/3
2.4.8stable
2026/10/3
2.4.7stable
2026/9/29

相关插件

正在加载相关插件…

最新版
2.6.3
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
700.3 kB
文件数
26
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 52
周下载
2,852
安全扫描
✓ v2.6.3 扫描通过
最近提交
2026/11/3
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
2.4.6stable
2026/9/28
2.4.5stable
2026/9/24
2.4.4stable
2026/9/23
2.4.3stable
2026/9/23
2.4.2stable
2026/9/23
2.4.1stable
2026/9/22
2.3.24stable
2026/9/18
2.3.23stable
2026/9/17
2.3.22stable
2026/9/16
2.3.21stable
2026/9/15
2.3.20stable
2026/9/14
2.3.19stable
2026/9/11
2.3.16stable
2026/9/11
2.3.15stable
2026/9/11
2.3.14stable
2026/9/11
2.3.13stable
2026/9/11
2.3.12stable
2026/9/11
2.3.11stable
2026/9/11
2.3.10stable
2026/9/10
2.3.9stable
2026/9/10
2.3.8stable
2026/9/9
2.3.7stable
2026/9/8
2.3.6stable
2026/9/6
2.3.5stable
2026/9/6
2.3.4stable
2026/9/6
2.3.3stable
2026/9/5
2.3.2stable
2026/9/4
2.3.1stable
2026/9/1
2.3.0stable
2026/8/30
2.2.1stable
2026/8/29
2.2.0stable
2026/8/29
2.1.1stable
2026/8/29
2.1.0stable
2026/8/29
2.0.0stable
2026/8/26
1.7.1stable
2026/8/25
1.7.0stable
2026/8/24
1.6.2stable
2026/8/24
1.6.1stable
2026/8/23
1.6.0stable
2026/8/22
1.5.1stable
2026/8/20
1.5.0stable
2026/8/20
1.4.0stable
2026/8/17
1.3.0stable
2026/8/16
1.2.2stable
2026/8/15
1.2.1stable
2026/8/15
1.2.0stable
2026/8/15
1.0.4stable
2026/8/14
1.0.3stable
2026/8/14
1.0.2stable
2026/8/14
1.0.1stable
2026/8/14
1.0.0stable
2026/8/14

相关插件

继续浏览 productivity-workflow 分类下经过校验的插件。

Acp App@deepseek-ai/dsh-acp-appdsh ACP 配置文件包:基于 dsh-base 的仅限自动化的 JSON-RPC stdio 和进程生命周期管理Experimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundle为 Web 组合添加 Schedule、其任务页面和时间上下文的可选捆绑包Client Ui Task Board@linxin666/dsh-client-ui-task-board面向 DSH Web GUI 的主机权威任务面板,支持实际会话执行、主机 cron 调度以及可选的跨平台空闲睡眠保护;以挂载方式提供,无需修改 DSH 源代码。Web All@linxin666/dsh-web-allDSH Web UI 全家桶聚合插件:一键安装全部功能插件(task-board / git-graph / pet / web-ui-settings / skin-center / community-plugins / compat shim)。compat 桥接层已并入本包(src/client),无需独立 compat npm 包。

README

dsh-recall-plugin

简体中文 | English

在任意一条你发过的消息下方点「↶ 撤回」——工作区文件和对话历史一起回到那条消息发出之前的状态。

每条消息发送时,工作区先被快照进一个独立的影子 git 仓库(不碰项目自身的 git);撤回时按快照恢复文件,并经 DSH 官方 sessions.fork 把对话切回该消息之前的 turn 边界,原会话归档保留、随时可找回。被撤回消息的文本与附件自动放回输入框,改完即可重发;也可以点消息旁的「✎ 编辑」就地改完直接重发(不动文件),同一段对话的多个版本经 ‹ X/N › 翻页器来回切换。快照存储默认落在 $DSH_HOME 下。最主要的边界:快照只在消息发送时创建,插件启用前的历史消息没有快照、不显示撤回按钮。

更新日志

目录

  • 界面预览
  • 功能亮点
  • 技术栈与依赖
  • 已知限制
  • 安装
  • 使用
  • 配置项
  • 快照维护与清理
  • 常见问题
  • 工作原理
  • 事件契约(供同宿主插件监听)
  • 参与贡献
  • License

界面预览

撤回按钮确认面板 · 变更文件清单
悬停出现撤回按钮确认面板 · 变更文件清单
  • 设置页 · 插件配置卡片(配置表单 / 排除表 / 快照管理,保存即热生效)

设置页

功能亮点

带括号版本号的能力需要该版本或更高;其余无特殊版本要求。

  • 文件 + 对话,整段回退:撤回的不只是聊天记录,agent 改过的文件也一并回到原样;不受项目 .gitattributes 转换影响,换行与二进制内容字节级保真(2.1.1+)。
  • 只想重来对话?文件可以不动(2.3.24+):确认面板可二选一撤回范围——默认「回退文件与对话」为完整回退;「仅撤回对话」则项目文件一个字节都不动(也不打安全快照),适合对回复不满意、但文件改动正是想要内容的场景。
  • 不碰项目自身的 git,目录保持干净:快照存在独立的影子 git 仓库,分支、暂存区、未提交改动统统不受影响;存储默认落在 $DSH_HOME 下、与会话沙箱权限无关(workspace-write / read-only 照常工作),仅当 home 不可写才降级到项目内 .dsh-recall-snapshots。
  • 先看清单再动手,可反复后悔:撤回前展示将变更的文件清单(修改 / 恢复 / 删除),确认后才执行;撤回后还能再撤到更早,被覆盖的文件一直找得回来。
  • 撤回完就能重发(2.3.15+):消息的文本与附件(图片、文件)一起放回输入框,改完直接发送,不必重新挑一遍附件。
  • 只改一个字也不用三连(2.5.0+):消息旁的「✎ 编辑」在该消息位置长出一张与官方输入框同款的编辑卡(预填原文、随内容增高),底部输入框保持原样;卡内可改字、粘贴/拖入附件,按 Enter 或点发送即新建会话、把改后的文本自动发出(原会话照常归档可找回),但只回退对话、不动项目文件。原消息附件以可移除的标签显示,权限以只读标签展示,模型与推理等级可在卡内按官方同款菜单切换(同步到底部输入框);Esc 取消。不想立刻发可在设置里关掉「编辑后自动发送」,改为只回填输入框。
  • 同一句话的多个版本可以来回翻(2.5.0+):每次撤回或编辑重发都会 fork 出新会话,最后一轮回答的操作区出现 ‹ X/N ›——点一下切到别的版本,侧栏始终只留当前那个(其余自动归档),切回时视口停回原位置。
  • 撤回全程有防护(2.0+,救援 2.1+):预览后出现新快照会强制重新预览;执行前自动打「回退前」安全快照,回退失败自动救援,救援失败给出可直接复制执行的手动恢复命令。
  • 磁盘友好、自动维护:快照走 git delta 增量压缩,大文件自动跳过(阈值可配);定期无损 git gc、会话删除联动清理、按条数与保留天数自动清理;设置页提供工作区 → 会话 → 快照三级树形管理,支持搜索与分级删除。
  • 失败不静默、能自愈(自愈 2.1+):失败按根因分类(git 缺失 / 磁盘满 / 无权限 / 锁冲突 / 目录冲突)给出可行动提示,同类故障 10 分钟只打扰一次,原因进设置卡片「最近错误」;自动清理残骸、连续 3 次失败指数退避、多实例按心跳互让;无法索引的路径跳过并告知,不中断整条快照(撤回时也不触碰它们)。

技术栈与依赖

本插件是 DSH bundle 形态:host 半跑在 DSH 进程内(Node ESM),client 半跑在浏览器会话页内,两侧同出一个 npm 包,包本体零运行时 dependencies。

  • 运行时:Node.js ≥ 20、git CLI;Windows 走 PowerShell 5.1/7,Linux/macOS 走 bash(按平台自动分叉)。
  • 语言与构建:TypeScript + ESM;npm run build 经 esbuild 产出 lib/(host 逐文件转译、client 打包为单文件),产物随源码提交。
  • 测试与门禁:vitest(纯逻辑单测、jsdom client 组件测试、官方 API 字段探针)+ tsc --noEmit 类型门禁 + 装配门禁脚本,详见「参与贡献 → 测试」。
  • 宿主依赖(peerDependencies,随 DSH 安装提供,无需单独安装):@deepseek-ai/cordis 4、@deepseek-ai/dsh-*(host-webserver / sandbox-policy / session / session-query / settings / shell)、@deepseek-ai/schemastery 3.18;react 18 为可选 peer(client 由宿主注入)。

已知限制

设计上接受的边界与尚未覆盖的极端情形,使用前值得先确认。

  • 快照在消息发送时创建:插件启用前的历史消息没有快照,不显示撤回按钮。
  • 快照是尽力捕获:从收到消息到 git add 之间有约 0.5–1.5 秒窗口(Windows 上仅一次 PowerShell 启动就占约 0.4 秒)。秒级任务若在这个窗口内改完文件,该快照会连带捕获本轮改动——撤回时文件回退成为空操作(预览面板显示「共 0 个文件将变更」),对话回退不受影响。
  • 会话第一条用户消息无法回退对话(仅文件回退),因为 fork 需要更早的 turn 边界;「编辑并重发」同样受此限制——没有更早的切点时会明确拒绝,而不是静默降级成只回填。
  • 版本翻页器只识别本插件产生的版本(撤回 / 编辑重发);会话列表里手动 fork 出来的会话不计入家族。版本登记存在浏览器 localStorage,换浏览器或清缓存后翻页器不再显示历史版本(会话本身与归档不受影响)。
  • 目标工作区的 agent 正在运行时无法发起撤回(防护设计,先停止 agent 再撤回)。
  • 支持 Windows(PowerShell 5.1/7 + git CLI)与 Linux/macOS(bash + git CLI)。Windows 真机验证充分;Linux 已在 WSL2(Ubuntu 26.04,bash 5.3 + git 2.53)实测全流程(含中文路径、home 降级、会话清理、gc);macOS 侧脚本按 bash 3.2 兼容编写,尚未真机实测。
  • 工作区内嵌套的其他 git 仓库(子目录自带 .git)无法索引:其余部分快照照常(fail-open,页面会提示跳过了哪些路径),但其内容不参与回退。
  • Windows 保留设备名(如 nul、aux、con、com1,含扩展名形式)无法由 Git 索引,默认不参与快照与回退;这些路径保持原样,也不会反复产生跳过提示。此排除仅适用于 Windows。
  • 工作区根路径自身超过 260 字符时不支持撤回:这是 Windows MAX_PATH 的硬限制——git 拒绝索引这类目录(\\?\ 扩展路径只能救工作区内部的深文件,救不了根前缀本身;实测根长 259 字符起就失败)。这种工作区的快照会失败,「最近错误」里提示把项目移到更短的路径。工作区内的深文件(根短、文件路径超 260)不受影响,照常快照与回退。
  • 工作区内的目录重解析点(junction / 目录符号链接)默认不参与快照:它们指向的子树不会被索引,因此那部分内容不参与回退。win32 上这是必需的——git for Windows 把 junction 当普通目录递归,自引用 junction 会让索引膨胀到 Windows 的 31 层重解析点上限(实测 2 个文件的工作区产出 64 条索引);POSIX 侧符号链接照常进快照(git 记成 120000 条目,不递归进目标)。确需把某个良性 junction(指向工作区外、非自引用)纳入快照时,可在排除配置里追加 !路径/(如 !ext-link/)反选恢复——用户排除行在机器生成行之后生效;切勿对自引用 junction 使用(爆炸根因)。
  • 文件名含换行/TAB 的极端情形超出 diff 清单的解析能力(概率可忽略)。
  • 与 dsh-routing-suite(渐进式工具披露路由)的交互:同时启用其 router-standard 预设时,撤回经 sessions.fork 出新会话会把路由阶段重置为默认(工具面临时收窄)。现象、成因与解决方案见 docs/routing-interplay.md。

安装

前置:

  • git CLI:未安装时撤回按钮不出现(页面顶部会提示安装 git),不影响 DSH 运行。
  • shell:Windows 上 PowerShell 5.1 / 7 均可;Linux/macOS 需 bash。
  • DSH 版本:0.1.2-alpha.1 至 0.2.2-alpha.2;已核验 minor 线内的后续版本自动放行,未核验的新 minor 线会被启动期兼容门禁拦截(开窗机制见下方折叠块)。
  • 0.1.7-alpha.1 是破坏性版本(shell 执行与 settings 面接口更换),插件内置双分支共存适配:同一发布同时兼容 0.1.2–0.1.6 各线与 0.1.7+,老版本 DSH 上行为不变。
  • 0.1.1-rc.2 及更早不支持:那条线的客户端运行时没有 sessions/workspaces/uiWorkspace 服务,插件 UI 会静默不渲染。
peer 版本开窗机制(升级 dsh 前可看)

peerDependencies 按 minor 版本线开窗,与 dsh.compatibility.dshReleases 声明一致:

>=0.1.2-alpha.1 <0.1.3 || >=0.1.3-alpha.1 <0.1.4 || >=0.1.5-alpha.1 <0.1.6 || >=0.1.6-alpha.1 <0.1.7 || >=0.1.7-alpha.1 <0.1.8 || >=0.2.0-rc.1 <0.2.1 || >=0.2.1-alpha.1 <0.3.0 || >=0.2.2-alpha.1 <0.3.0

每条线以首个核验版本为下限、上界开到下一 minor(0.2.1 与 0.2.2 段上限均放宽到 <0.3.0,0.2 全线正式版自动放行),同线内后续 prerelease/正式版自动放行、无需改 peer 声明。0.2.0 / 0.2.1 / 0.2.2 每条线都必须显式开窗:npm 的 prerelease 门槛要求同 tuple 且带 prerelease 的比较器,既有 <0.1.8 段放行不了 0.2.0-rc.1、<0.2.1 段放行不了 0.2.1-alpha.1,>=0.2.1-alpha.1 <0.3.0 同样放行不了 0.2.2-alpha.2(首个 0.2.2 核验版本,2026-10-28)。

安装与验证:

  • 官方命令安装(按所用前端选 profile),安装后自动挂载进该 profile:

    dsh plugin --profile web add dsh-recall-plugin      # Web UI
    dsh plugin --profile desktop add dsh-recall-plugin  # Desktop
    
  • 也可从 git 直接安装:

    dsh plugin --profile web add github:limbo947/dsh-recall-plugin
    
  • 重启 DSH 进程(按你的启动方式选择):

    dsh web                      # 前台运行
    pm2 restart <你的-dsh-名称>  # pm2 托管时
    
  • 验证:重启后硬刷新页面(Ctrl+Shift+R),悬停任意一条插件启用后发送的用户消息——复制按钮旁出现「↶」即生效。没有按钮?九成是没重启 DSH 进程,或 git CLI 不在 PATH 里。

  • 卸载(同时移除依赖与挂载):

    dsh plugin --profile web remove dsh-recall-plugin
    

    快照数据保留在 home 下 dsh-recall-snapshots/,想彻底清除手动删掉该目录即可。

使用

对一条插件启用后发送的用户消息做完整撤回,流程如下:

  1. 鼠标悬停该消息(含 agent 运行中插入的转向指令消息),复制按钮左侧出现「↶ 撤回」。
  2. 点击 → 确认面板展示将变更的文件清单(修改 / 恢复 / 删除),并可选撤回范围:「回退文件与对话」(默认)或「仅撤回对话」(文件保持当前状态)。
  3. 点「确认回退」(或「确认撤回对话」)→ 文件恢复到该消息发送前的状态(仅撤回对话时文件不动);视图切到新会话(该消息及之后的对话移除),原会话归档、随时可找回。

只想改文字重发,点同一行的「✎ 编辑」:该消息位置出现同款编辑卡并预填原文,改完按 Enter(或点发送)——新建会话并把改后的消息发出(项目文件不动,附件一并带过去);Esc 取消。第一条用户消息没有可回退的对话切点,编辑会被明确拒绝。

撤回或编辑重发之后,最后一轮回答的操作区出现 ‹ X/N ›:左右切换即在该段对话的各版本间跳转(当前版本自动归档、目标版本自动恢复,侧栏只留一个)。

配置项

全部配置可在「设置 → 插件配置 → 撤回插件」卡片可视化修改(保存即热生效,无需重启),也可在 profile 的 cordis.patch.yml 按 id: recall 重述 insert 行改写;env 变量仅覆盖 gc 两项且优先级最高(设了 env 的字段在卡片里锁定)。

配置项默认值说明
gcSnaps50每积累多少条快照触发一次 git gc(env DSH_RECALL_GC_SNAPS 可强制覆盖)
gcHours24距上次 gc 超过多少小时触发(与条数先到先触发;env DSH_RECALL_GC_HOURS)
maxFileBytes8388608(8MB)超过该大小的文件不进快照、不被回退触碰;在 git add 之前就按清单剔除,不写对象(旧 git 退回「先加后剔」)
maxWorkspaceBytes268435456(256MB)单工作区可纳入快照的文件总量上限,口径与 git add 一致(.gitignore、.git/info/exclude、全局 excludesFile 都算数)。超过时停用该工作区快照(不截断——截断快照回退时会误删未纳入的文件),并在最近消息上提示;调大该值或补充排除表后自动恢复;0 = 不限制
scanBudgetMs10000(10 秒)快照前统计纳入总量的时间预算。超过时停用本次快照并提示(防病态大目录拖死启动);0 = 不限制
snapshotBudgetMs180000(3 分钟)单次快照从扫描到写入的总时限,超时即中止本次快照并记入「最近错误」;0 = 不限制
maxSnapshotsPerWorkspace500每个工作区保留的最大快照数,超限自动删除最旧的;0 = 不限制
retentionDays0按天数保留快照,超期自动删除;0 = 不启用(与条数上限各自独立生效)
baseExcludes.git、node_modules/、.dsh-recall-snapshots/、dsh-recall-snapshots/、target/、dist/、build/、out/、coverage/、.next/、.nuxt/、.output/、.cache/、.gradle/、*.exe、*.dll、*.pdb、*.so、*.dylib、*.msi、*.zip、*.7z、*.rar、*.tar、*.tar.gz、*.iso基础排除表(gitignore 语法,优先级低于 exclude.txt);被排除的大目录整棵子树不进快照扫描。其中「目录形态」项(如 target/)另有一层含义:工作区根自身的路径段命中时,该工作区不启用快照——在构建产物目录里开会话时排除表本来就管不到它自己(模式是相对该 root 的),这类目录也没有回退价值;删掉对应项即恢复
refillDrafttrue撤回后把被撤回的消息(文本与附件)回填到输入框
snapshotEnabled

设置卡片另提供「恢复默认」(一键重置全部字段)与「最近错误」查看/清空。

界面语言

插件自绘的界面(撤回按钮与确认面板、toast 提示、设置卡片三张卡、快照管理树、最近错误)全部双语,由 locale 控制:在配置卡片的「界面」分组下拉切换、保存即生效(设置页立刻切换;聊天页的会话文案在下次刷新页面后跟进)。

两项明示限制:① 宿主官方设置表单自己渲染的字段说明(即 Schema.description() 文本)仍是中文,插件无法本地化——插件自绘的配置卡片不受影响;② 带动态细节的宿主侧错误(回退失败的救援结果、具体校验失败原因、原始异常文本)在错误面板与「最近错误」里原样展示宿主返回的中文/英文原文,不套本地化短句——宁可中英混排,也不吞掉排障需要的细节。

快照维护与清理

插件自动控制磁盘占用,无需手动管理:

  • 定期 gc:每 50 条快照或距上次 gc 24 小时(先到先触发,阈值可配),后台执行 git gc 把 loose 对象压成 pack——无损操作,所有快照照常可回退。节流凭据写在影子仓库内的 gc.stamp,重启 DSH 不会重置周期。

  • 条数上限与保留天数:每工作区默认上限 500 条(超限清最旧),retentionDays 按保留天数清理;两者独立触发,都可在配置卡片调整或关闭。

  • 会话删除联动清理:会话被彻底删除(会话日志从磁盘消失)后,下一次维护会自动删除该会话的全部快照并释放空间。归档不算删除——撤回功能归档的原会话日志仍在,快照保留、随时可从归档找回。判断很保守:会话只是冷着(不在内存)不会误清;无法核实日志状态时宁可不清。

  • 用户自定义排除:打开「设置 → 插件配置 → 撤回插件」卡片(默认收起,点卡片头展开)即可可视化编辑快照排除项——输入路径或模式回车即加、常用模式(dist/、*.log、.env 等)一键追加、保存后下一次快照/回退立即生效,无需重启。也可以直接编辑 $DSH_HOME/dsh-recall-snapshots/exclude.txt(未设置时为 ~/.dsh/dsh-recall-snapshots/exclude.txt;UTF-8):一行一条 gitignore 风格 pattern(# 开头为注释),两种方式编辑的是同一份配置。例如:

    # 构建产物不进快照
    dist/
    build/
    *.log
    

    对所有项目生效(home 不可写而降级到项目内存储时,该工作区有独立的排除配置,设置页会分卡片列出)。新增排除只影响之后的快照;回退到更早的快照时,当时尚未排除的文件仍会被恢复(回到当时的状态,这正是回退语义)。想彻底清掉已进快照的目录,可手动删除 home 下 dsh-recall-snapshots/ 里对应项目的哈希目录。

  • 树形快照管理:打开「设置 → 插件配置 → 撤回插件 → 快照管理」可看到三级树——工作区(文件夹名)→ 会话(会话标题,撤回链聚成版本家族)→ 快照(时间 + 消息内容摘要,悬停看完整内容)。支持搜索与「加载更多」,工作区与会话节点可展开/折叠;每一级右侧都有删除按钮,删除前二次确认——删工作区 = 清掉该工作区全部快照,删会话 = 清掉该会话全部快照,删叶子 = 只删那一条;顶部另有带确认的「全部删除」。

常见问题

使用中最常遇到的几类问题与排查路径;更完整的设计边界见上文「已知限制」,环境类失败(git 缺失 / 磁盘满 / 无权限等)的原因在设置卡片「最近错误」里可查。

消息旁没有「↶ 撤回」按钮? 按概率排查:① 装完没重启 DSH 进程——重启后硬刷新页面(Ctrl+Shift+R);② git CLI 不在 PATH——页面顶部会有安装提示;③ 该消息发送于插件启用之前——快照只在消息发送时创建,历史消息无快照;④ 该工作区被停用快照——工作区开在 dist/、target/ 这类命中基础排除表目录形态的位置,或超出 maxWorkspaceBytes / scanBudgetMs 护栏,或快照前的范围统计本身失败(git ls-files 报错,原因见「最近错误」,10 分钟后自动重试);最近消息上会给出恢复提示(调大上限或补充排除表后自动恢复)。

撤回后个别文件没有恢复? 该文件不在快照里:超过 maxFileBytes(默认 8MB)、命中排除表(含 Windows 保留设备名),或位于嵌套 git 仓库 / win32 目录重解析点内(见「已知限制」)。撤回前确认面板的清单就是实际回退范围,以它为准。

快照占用磁盘太多? 打开「设置 → 插件配置 → 撤回插件 → 快照管理」查看各工作区占用,可「立即 gc」或按工作区 / 会话 / 单条分级删除;长期可压低 maxSnapshotsPerWorkspace、设置 retentionDays,或把大目录补进排除表。

如何彻底删除全部快照数据? 卸载插件后手动删除 home 下 dsh-recall-snapshots/(即 $DSH_HOME/dsh-recall-snapshots/,未设置时为 ~/.dsh/dsh-recall-snapshots/);曾降级存储的工作区另删项目内 .dsh-recall-snapshots/。

会话第一条消息能撤回或编辑吗? 文件可以回退,对话不能——fork 需要该消息之前的 turn 边界;「编辑并重发」对首条消息会被明确拒绝(原消息还在,补发即成重复消息)。

撤回后会话列表多出一个会话,能不能不新建? 不能,这是平台能力边界而非配置项:DSH 提供的「回到某条消息之前」唯一通道是 sessions.fork,fork 必然产生新会话——客户端会话面只有 fork / open / list / binding,没有删除或就地截断会话的动词。插件能控制的是原会话的去留(archiveOriginal,默认归档到「已归档」、可恢复),不是「是否新建」。若你说的「分支」指的是 git 分支:插件从不创建分支,快照只打 snap-<消息ID> tag,不碰项目自身的 git 状态。

工作原理

每条用户消息发送时(agent 动文件之前),工作区被快照进一个独立的影子 git 仓库;撤回时先打「回退前」安全快照、再用 git archive 恢复文件、通过 DSH 官方 sessions.fork 机制把会话切到该消息之前。二进制与换行符安全,全程不触碰项目自身的 git 状态。

  • 快照存储:home 下 dsh-recall-snapshots/<SHA256(项目绝对路径)>/,内含影子 git 仓库(git/,tag 名为 snap-<消息ID>)、索引文件 index.json(消息 ID → 快照时间 / 会话)与撤回链 lineage.json。Windows 上脚本走 PowerShell,Linux/macOS 走 bash(按平台自动分叉)。

  • Windows 上宿主把 shell 配成 bash 也照常工作(2.3.22+):官方 shell 由 profile 注册,win32 上可以只启用 bash-sandbox——此时 pwsh 脚本会被 bash 执行而全盘失败。插件首次执行命令前会先探测执行器能否跑 pwsh(哨兵命令),确认是 bash 后改用系统 PowerShell 5.1 直连执行,快照与撤回不受影响;ctx.shell 即 pwsh 的常规部署行为不变(探测一次、判为 pwsh 后一切照旧)。

  • 想直接翻历史快照:

    git --git-dir="<store>\git\.git" tag -l
    git --git-dir="<store>\git\.git" ls-tree -r --name-only snap-<消息ID>
    
  • 存储目录里每个文件(索引、撤回链、格式标记、意图记录等)的格式与版本兼容约定见 docs/format.md。

事件契约(供同宿主插件监听)

撤回到达终态时,插件经 cordis 事件广播两个公开事件(2.4.8+),同宿主任意插件可直接监听——例如长时记忆插件据此清理「被撤回回合」写入的记忆:

// 同宿主插件内
ctx.on('dsh-recall/complete', (e) => {
  if (e.chatReverted) memory.purgeTurn(e.root, e.sessionId, e.cutSeq)
})
ctx.on('dsh-recall/failed', (e) => {
  if (e.stage === 'fork') log.warn('文件已回退但对话未回退', e)
})

dsh-recall/complete——撤回成功终态:

字段类型说明
version1契约版本(演进规则见下)
sessionIdstring被撤回的原会话
childSessionIdstring | nullfork 出的新会话;纯文件回退时为 null
scope'both' | 'session-only'撤回范围
cutSeqnumber | null对话回退切点;该消息是会话首条时为 null
messageIdstring被撤回消息 ID(快照主键)
rootstring | null工作区根路径;host 解析失败为 null
countnumber回退文件数(session-only 恒 0)
chatRevertedboolean对话是否真的回退(下游清理判据,见下)
archiveRequestedboolean原会话归档是否已发起(fire-and-forget,不代表已落定)
timenumberhost 收到上报的时间(ms)

dsh-recall/failed——撤回失败终态:

字段类型说明
version1契约版本
stage'execute' | 'fork'失败阶段:文件回退被拒/异常,或文件已回退但对话回退失败
sessionIdstring | null被撤回的原会话
messageIdstring被撤回消息 ID
scope'both' | 'session-only'撤回范围
cutSeqnumber | nullclient 已知的对话切点(可能尚未使用)
rootstring | null工作区根路径;解析失败为 null
codestring?仅 stage='execute':透传 host 错误码(AGENT_BUSY / NO_SNAPSHOT 等)
errorstring错误描述
timenumberhost 收到上报的时间(ms)

语义要点(下游必读):

  • 只有终态才发事件。撤回确认后「预览已过期、自动重新拉清单」(STALE)是中间态,不发任何事件;用户取消、面板关闭同样不发。
  • fork 失败只发 failed(stage:'fork'),绝不发 complete——此刻文件已回退但对话未回退,若发 complete 会导致下游误清该回合记忆。判断「对话确实回退了」请以 complete 事件的 chatReverted 为准(纯文件回退的 complete 是 chatReverted:false)。
  • failed(stage:'execute') 若来自执行异常(而非护栏拒绝),文件是否已回退不确定,下游宜保守处理。
  • 重复撤回/重试可能对同一 (sessionId, messageId, cutSeq) 三元组多次发事件,下游按三元组做幂等。
  • payload 不含消息正文,只有 ID / seq / 路径;事件只对同宿主插件可见。

版本演进:首发即稳定公共契约(非 experimental)。新增字段(additive)走 minor;破坏性变更走 major 且 version 升 2,下游可按 version 分流。

版本错位:旧版插件前端(<2.4.8)不上报、事件永不触发;新版前端 + 旧版 host(<2.4.8)时上报端点不存在,前端静默忽略,撤回功能不受任何影响。

参与贡献

环境要求

  • Node.js ≥ 20(Windows / Linux / macOS 均可开发),git CLI;
  • 本机安装 DSH(≥ 0.1.2-alpha.1):npm run test:probe 与 npm run verify:host 依赖真实 dsh 安装;没有 dsh 时探针自动跳过,不阻塞其余开发与测试。

本地联调(无需发布)

先克隆并构建一次(peer 依赖是私有 @deepseek-ai/* 包,--legacy-peer-deps 跳过、只装 devDependencies——构建与测试工具链齐备):

git clone https://github.com/limbo947/dsh-recall-plugin.git
cd dsh-recall-plugin
npm install --legacy-peer-deps   # 安装构建/测试工具链(esbuild、vitest、typescript 等)
npm run build                    # 生成 lib/ 产物(link 模式加载的就是它)
npm test                         # 可选:跑一遍单测验证基线

再把 profile 对本包的依赖改成 link: 指向克隆目录;DSH 加载的是工作区 lib/ 构建产物(源码在 src/),改 src/ 后先 npm run build 再重启 DSH 生效,无需复制或发布:

# 1. 编辑 $env:USERPROFILE\.dsh\profiles\web\package.json:
#    "dependencies" 里 "dsh-recall-plugin": "link:<你的克隆路径>\dsh-recall-plugin"
#    "dsh.profile.bundles" 已含 "dsh-recall-plugin"(官方命令装过一次即可)
# 2. 在 profile 目录安装并重启
cd $env:USERPROFILE\.dsh\profiles\web
pnpm install
# 3. 重启 DSH + 硬刷新页面(Ctrl+Shift+R)

源码结构与构建

全部源码在 src/:Host(Node ESM TypeScript)在 src/host/、浏览器端在 src/client/、跨域共享类型在 src/types/;lib/ 是纯构建产物目录——npm run build 经 esbuild 生成(逐文件转译 host 产物 + 打包 lib/client.js),产物随源码提交。改任何 src/ 后必须跑 npm run build,否则运行的是旧产物(CI 有产物新鲜度统一校验)。

测试

  • npm test:纯逻辑单测(vitest,41 个文件 524 例,无 DSH 依赖,CI 与本地同跑)——配置解析、快照解析器、救援编排、错误分类、磁盘格式守卫、操作意图 journal、撤回终态事件上报组装、i18n 词典与 key 漏配扫描、脚本模板同名导出契约、执行通道双分支与失败分级、settings 双代桥接、产物 root 与快照总量护栏、撤回 scope 分流、客户端纯函数、发布包内容布局、快照索引持久化、存储上限与保留天数等;
  • npm run test:client:client 组件测试(vitest + jsdom,9 个文件 121 例,CI 同跑)——撤回节点主链(preview→execute→fork→回填)与终态事件上报、编辑卡提交链与官方内容投影、版本家族登记与翻页、快照管理树与删除流、配置/排除卡片错误路径、logger 开关矩阵、zh/en 双语渲染链;断言只锁行为与结构(className / aria / 请求载荷),不锁文案字面量;
  • npm run test:probe:官方 API 字段探针(2 个文件 58 例,依赖本机 dsh 安装;dsh 升级后本地必跑)——钉住 renderMessageImages/node/cwd、sessions.fork 的 atSeq/increaseTitle 与切点锚点、listSessions 记录结构、AgentRegistry、shell 执行接缝(execute/ShellExecution.result)、settings 面(SettingsForms/profile 条目 id/volatile 门槛)、输入区写入链(setDraft/addAttachments/submit/snapshot/createDrafts)与 loader/volatile-update/Fiber.entry 形状等字段,违反即红;
  • npm run verify:host:装配门禁(依赖本机 dsh 安装)——用真实 cordis 起插件跑两个 pass(旧面桩 + 只给新面的桩),断言 inject 声明、端点注册、Config schema、卸载清理与 settings 面分派,装配回归发版前即可拦截;
  • npm run typecheck:tsc --noEmit 全量类型检查(含 tests/types 编译期契约断言,CI 中置于单测之前);
  • npm run build:host+client 全量打包(改任何 src/ 后必跑);npm run check:dsh:dsh 版本巡检(发布前);npm run check:upgrade:dsh 升级一键核验门禁(串联 check:dsh + test:probe + verify:host,dsh 升级后必跑)。
  • CI(GitHub Actions)跑 npm ci --legacy-peer-deps + npm run typecheck + npm test + npm run test:client + 产物新鲜度统一校验(npm run build && git diff --exit-code lib/;探针与装配门禁只在有 dsh 的机器跑)。

提交规范(摘要)

  • 提交信息遵循 Conventional Commits(feat: / fix: / docs: / test: / ci: / chore: 前缀 + 中文摘要);修复 bump patch、新功能 bump minor;
  • 行为变更同步更新 CHANGELOG.md(Keep a Changelog 格式)与 README 双语(中文 / English);
  • 对 dsh 官方 API 的字段假设发生变化时,同步 docs/compat-audit.md 台账;
  • 完整的架构地图、开发流程、官方文档合规清单与已知坑见 AGENTS.md——面向 AI 编码代理与深度维护者的项目操作手册。

License

MIT

true
快照总开关(关闭只冻结新建,已有快照仍可撤回)
messageOnlyfalse只回退消息:每条用户消息仍登记撤回记录(按钮与对话回退照常),但不写文件快照——适合 gitignore 过滤后仍上 GB 的超大工作区。按消息生效:开启前的旧快照仍可完整回退文件;这类条目在快照管理里标「仅消息」,删除后不可从 tag 恢复
archiveOriginaltrue撤回后归档原会话(关闭后原会话保留在会话列表中)
editSubmitsImmediatelytrue「编辑并重发」提交后自动发出改后的消息;关闭则只回填输入框,由你按回车发送
localeauto界面语言:auto 跟随系统(navigator.language 以 zh 开头用中文,否则英文)、zh / en 显式锁定。见下方「界面语言」