DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-recall-plugin

Recall Plugin

Recall your own messages in DSH: workspace files and conversation history return to the state before the message was sent, while the message text and attachments are automatically restored to the input box for editing and resending. Files use independent shadow git snapshots without touching the pro

The plugin will be installed here. Keep web if you are unsure.

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

Description

Recall your own messages in DSH: workspace files and conversation history return to the state before the message was sent, while the message text and attachments are automatically restored to the input box for editing and resending. Files use independent shadow git snapshots without touching the project’s own git; conversations use the official sessions.fork, and the original session is archived for recovery.

Compatibility and provenance

Recall Plugin is published as dsh-recall-plugin and currently resolves to version 2.6.3. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/4/2026

Versions

2.6.3stable
11/3/2026
2.6.2stable
11/2/2026
2.6.1stable
10/30/2026
Show 66 more versionsCollapse versions
2.6.0stable
10/30/2026
2.5.3stable
10/30/2026
2.5.2stable
10/28/2026
2.5.1stable
10/27/2026
2.5.0stable
10/23/2026
2.4.16stable
10/18/2026
2.4.15stable
10/18/2026
2.4.14stable
10/17/2026
2.4.13stable
10/17/2026
2.4.12stable
10/15/2026
2.4.11stable
10/14/2026
2.4.10stable
10/7/2026
2.4.9stable
10/3/2026
2.4.8stable
10/3/2026
2.4.7stable

Related plugins

Loading related plugins…

Latest
2.6.3
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
700.3 kB
Files
26
Surface
web
License
MIT
Source
npm
GitHub
★ 52
Weekly downloads
2,852
Security scan
✓ v2.6.3 scan passed
Last push
11/3/2026
View source ↗Project homepage ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

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

Related plugins

More verified plugins in productivity-workflow.

Acp App@deepseek-ai/dsh-acp-appThe dsh ACP profile bundle: automation-only JSON-RPC stdio and process lifecycle over dsh-baseExperimental Schedule Bundle@deepseek-ai/dsh-experimental-schedule-bundleOptional bundle that adds Schedule, its task page, and time context to the Web compositionClient Ui Task Board@linxin666/dsh-client-ui-task-boardHost-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.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 显式锁定。见下方「界面语言」