🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

按轮回退 YIYuNCU/dsh-rewind

DeepSeek Harness
YIYuNCU21 天前有提交已提供中文文档扫描:含敏感能力

把文件恢复到某轮开始时的内容并另开会话

29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/15 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add YIYuNCU/dsh-rewind
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/11/04·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 21 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件发起外部网络请求
查看扫描证据(共 137 处,展示前 101 条)
  • 读取本地文件
    lib/index.js:51
    const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
  • 发起网络请求
    lib/client.js:395
    const response = await fetch(url, init);
  • 读取本地文件
    lib/engine.js:656
    const info = await lstat(target);
  • 读取本地文件
    lib/host.js:260
    return await realpath(path);
  • 读取本地文件
    lib/capture.js:65
    info = await lstat(absolute);
  • 读取本地文件
    lib/capture.js:126
    entries = await readdir(directory, { withFileTypes: true });
  • 读取本地文件
    lib/capture.js:156
    return { ...item, info: await lstat(item.absolute) };
  • 读取本地文件
    lib/capture.js:253
    return await realpath(path);
  • 写入本地文件
    lib/ledger.js:40
    await mkdir(this.sessionsDir(), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/ledger.js:41
    await mkdir(this.blobRoot(), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/ledger.js:52
    await mkdir(join(this.blobRoot(), shard), { recursive: true, mode: 0o700 });
  • 读取本地文件
    lib/ledger.js:68
    const existing = await readFile(path);
  • 读取本地文件
    lib/ledger.js:78
    const bytes = await readFile(this.blobPath(hash));
  • 写入本地文件
    lib/ledger.js:87
    await mkdir(directory, { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/ledger.js:89
    await writeFile(join(directory, 'session-id'), record.sessionId, { encoding: 'utf8', mode: 0o600 });
  • 删除本地文件递归
    lib/ledger.js:139
    await rm(this.sessionDir(session.sessionId), { recursive: true, force: true });
  • 写入本地文件
    lib/ledger.js:150
    await mkdir(directory, { recursive: true, mode: 0o700 });
  • 读取本地文件
    lib/ledger.js:178
    names = await readdir(this.sessionsDir());
  • 读取本地文件
    lib/ledger.js:187
    sessionId = (await readFile(join(this.sessionsDir(), name, 'session-id'), 'utf8')).trim();
  • 读取本地文件
    lib/ledger.js:206
    names = await readdir(this.sessionsDir());
  • 读取本地文件
    lib/ledger.js:217
    sessionId = (await readFile(join(directory, 'session-id'), 'utf8')).trim();
  • 删除本地文件递归
    lib/ledger.js:247
    await rm(this.sessionDir(entry.sessionId), { recursive: true, force: true });
  • 删除本地文件递归
    lib/ledger.js:254
    await rm(this.sessionDir(sessionId), { recursive: true, force: true });
  • 删除本地文件
    lib/ledger.js:307
    await rm(join(directory, 'journal.json'), { force: true });
  • 删除本地文件
    lib/ledger.js:308
    await rm(join(directory, 'journal.jsonl'), { force: true });
  • 删除本地文件
    lib/ledger.js:372
    await rm(path, { force: true });
  • 读取本地文件
    lib/paths.js:40
    info = await lstat(current);
  • 读取本地文件
    lib/paths.js:71
    info = await lstat(current);
  • 写入本地文件
    lib/paths.js:94
    await mkdir(dirname(path), { recursive: true });
  • 删除本地文件
    lib/paths.js:108
    await rm(temporary, { force: true }).catch(() => undefined);
  • 读取本地文件
    lib/paths.js:116
    info = await lstat(path);
  • 删除本地文件
    lib/paths.js:126
    await unlink(path);
  • 删除本地文件
    lib/paths.js:133
    await rmdir(current);
  • 写入本地文件
    lib/paths.js:146
    await rename(from, to);
  • 删除本地文件
    lib/paths.js:151
    await rm(to, { force: true });
  • 写入本地文件
    lib/paths.js:152
    await rename(from, to);
  • 读取本地文件
    lib/relocate.js:45
    text = await readFile(file, 'utf8');
  • 写入本地文件
    lib/relocate.js:67
    await mkdir(dirname(file), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/relocate.js:69
    await writeFile(temporary, `${JSON.stringify({ version: 1, storageDir: resolve(storageDir) })}\n`, { mode: 0o600 });
  • 写入本地文件
    lib/relocate.js:70
    await rename(temporary, file);
  • 读取本地文件
    lib/relocate.js:75
    const names = await readdir(dir);
  • 写入本地文件
    lib/relocate.js:97
    await mkdir(to, { recursive: true, mode: 0o700 });
  • 读取本地文件
    lib/relocate.js:110
    const names = await readdir(to);
  • 删除本地文件递归
    lib/relocate.js:114
    await rm(from, { recursive: true, force: true });
  • 写入本地文件
    lib/relocate.js:117
    await mkdir(dirname(to), { recursive: true, mode: 0o700 });
  • 写入本地文件
    lib/relocate.js:119
    await rename(from, to);
  • 删除本地文件递归
    lib/relocate.js:132
    await rm(temporary, { recursive: true, force: true }).catch(() => undefined);
  • 删除本地文件递归
    lib/relocate.js:135
    await rm(from, { recursive: true, force: true }).catch(() => undefined);
  • 读取本地文件
    lib/relocate.js:144
    return await lstat(path);
  • 读取本地文件
    lib/relocate.js:153
    const names = await readdir(from);
  • 删除本地文件递归
    lib/relocate.js:177
    await rm(from, { recursive: true, force: true });
  • 读取本地文件
    src/capture.ts:82
    info = await lstat(absolute)
  • 读取本地文件
    src/capture.ts:150
    entries = await readdir(directory, { withFileTypes: true })
  • 读取本地文件
    src/capture.ts:173
    return { ...item, info: await lstat(item.absolute) }
  • 读取本地文件
    src/capture.ts:269
    return await realpath(path)
  • 读取本地文件
    src/engine.ts:765
    const info = await lstat(target)
  • 读取本地文件
    src/host.ts:349
    return await realpath(path)
  • 读取本地文件
    src/index.ts:73
    const manifest = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')) as { version?: unknown }
  • 写入本地文件
    src/ledger.ts:67
    await mkdir(this.sessionsDir(), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/ledger.ts:68
    await mkdir(this.blobRoot(), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/ledger.ts:80
    await mkdir(join(this.blobRoot(), shard), { recursive: true, mode: 0o700 })
  • 读取本地文件
    src/ledger.ts:93
    const existing = await readFile(path)
  • 读取本地文件
    src/ledger.ts:103
    const bytes = await readFile(this.blobPath(hash))
  • 写入本地文件
    src/ledger.ts:112
    await mkdir(directory, { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/ledger.ts:114
    await writeFile(join(directory, 'session-id'), record.sessionId, { encoding: 'utf8', mode: 0o600 })
  • 删除本地文件递归
    src/ledger.ts:162
    if (session.turns.length === 0) await rm(this.sessionDir(session.sessionId), { recursive: true, force: true })
  • 写入本地文件
    src/ledger.ts:172
    await mkdir(directory, { recursive: true, mode: 0o700 })
  • 读取本地文件
    src/ledger.ts:201
    names = await readdir(this.sessionsDir())
  • 读取本地文件
    src/ledger.ts:208
    sessionId = (await readFile(join(this.sessionsDir(), name, 'session-id'), 'utf8')).trim()
  • 读取本地文件
    src/ledger.ts:225
    names = await readdir(this.sessionsDir())
  • 读取本地文件
    src/ledger.ts:234
    sessionId = (await readFile(join(directory, 'session-id'), 'utf8')).trim()
  • 删除本地文件递归
    src/ledger.ts:260
    for (const entry of usage) await rm(this.sessionDir(entry.sessionId), { recursive: true, force: true })
  • 删除本地文件递归
    src/ledger.ts:267
    await rm(this.sessionDir(sessionId), { recursive: true, force: true })
  • 删除本地文件
    src/ledger.ts:316
    await rm(join(directory, 'journal.json'), { force: true })
  • 删除本地文件
    src/ledger.ts:317
    await rm(join(directory, 'journal.jsonl'), { force: true })
  • 删除本地文件
    src/ledger.ts:374
    await rm(path, { force: true })
  • 读取本地文件
    src/paths.ts:41
    info = await lstat(current)
  • 读取本地文件
    src/paths.ts:67
    info = await lstat(current)
  • 写入本地文件
    src/paths.ts:87
    await mkdir(dirname(path), { recursive: true })
  • 删除本地文件
    src/paths.ts:99
    await rm(temporary, { force: true }).catch(() => undefined)
  • 读取本地文件
    src/paths.ts:108
    info = await lstat(path)
  • 删除本地文件
    src/paths.ts:116
    await unlink(path)
  • 删除本地文件
    src/paths.ts:124
    await rmdir(current)
  • 写入本地文件
    src/paths.ts:138
    await rename(from, to)
  • 删除本地文件
    src/paths.ts:141
    await rm(to, { force: true })
  • 写入本地文件
    src/paths.ts:142
    await rename(from, to)
  • 读取本地文件
    src/relocate.ts:45
    text = await readFile(file, 'utf8')
  • 写入本地文件
    src/relocate.ts:63
    await mkdir(dirname(file), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/relocate.ts:65
    await writeFile(temporary, `${JSON.stringify({ version: 1, storageDir: resolve(storageDir) })}\n`, { mode: 0o600 })
  • 写入本地文件
    src/relocate.ts:66
    await rename(temporary, file)
  • 读取本地文件
    src/relocate.ts:72
    const names = await readdir(dir)
  • 写入本地文件
    src/relocate.ts:92
    await mkdir(to, { recursive: true, mode: 0o700 })
  • 读取本地文件
    src/relocate.ts:104
    const names = await readdir(to)
  • 删除本地文件递归
    src/relocate.ts:107
    await rm(from, { recursive: true, force: true })
  • 写入本地文件
    src/relocate.ts:110
    await mkdir(dirname(to), { recursive: true, mode: 0o700 })
  • 写入本地文件
    src/relocate.ts:112
    await rename(from, to)
  • 删除本地文件递归
    src/relocate.ts:122
    await rm(temporary, { recursive: true, force: true }).catch(() => undefined)
  • 删除本地文件递归
    src/relocate.ts:125
    await rm(from, { recursive: true, force: true }).catch(() => undefined)
  • 读取本地文件
    src/relocate.ts:136
    return await lstat(path)
  • 读取本地文件
    src/relocate.ts:144
    const names = await readdir(from)
  • 删除本地文件递归
    src/relocate.ts:165
    await rm(from, { recursive: true, force: true })
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/schemastery@deepseek-ai/dsh-settings
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

README

由 DeepSeek 最新模型翻译生成
dsh-rewind dsh-rewind DeepSeek Harness 的按轮回退插件。 把文件改回某一轮开始时的内容,并另开会话。原来的会话记录保持不变。 - 每一轮开始时,记下工作区里符合条件的文件。快照放在工作区外面,不写进仓库的 Git 对象。 - 回退会撤掉这一轮之后的文件工具改动,以及两轮之间的手改和脚本改动。 - 回退对话时另开一个会话,不截断原来的记录。 界面语言为简体中文和 English。 安装 这是一个 DSH Profile Bundle。安装使用仓库里已经构建好的 lib/,不需要在本机再构建。 网页或桌面端 在 添加插件 的输入框填: github:YIYuNCU/dsh-rewind desktop 这个 profile 由桌面端独占,不要运行 dsh plugin --profile desktop,也不要手改 profile 的 package.json。第一次启用如果提示无法导入,完全退出并重新打开客户端,再启用一次。
展开完整文档(README 剩余 1 节)
dsh-rewind dsh-rewind

DeepSeek Harness 的按轮回退插件。 把文件改回某一轮开始时的内容,并另开会话。原来的会话记录保持不变。

- 每一轮开始时,记下工作区里符合条件的文件。快照放在工作区外面,不写进仓库的 Git 对象。
- 回退会撤掉这一轮之后的文件工具改动,以及两轮之间的手改和脚本改动。
- 回退对话时另开一个会话,不截断原来的记录。

界面语言为简体中文和 English。

安装

这是一个 DSH Profile Bundle。安装使用仓库里已经构建好的 lib/,不需要在本机再构建。

网页或桌面端

在 添加插件 的输入框填:

github:YIYuNCU/dsh-rewind

desktop 这个 profile 由桌面端独占,不要运行 dsh plugin --profile desktop,也不要手改 profile 的 package.json。第一次启用如果提示无法导入,完全退出并重新打开客户端,再启用一次。

命令行

网页 profile:

dsh plugin --profile web add github:YIYuNCU/dsh-rewind

本地检出可以用相对路径或绝对路径:

dsh plugin --profile web add ./dsh-rewind

使用

每个用户回合末尾有 回退这一轮。打开后可以选择:

| 操作 | 结果 |
| 回退代码和对话 | 恢复文件,并另开一个会话 |
| 只回退代码 | 只恢复文件,当前会话不动 |
| 只回退对话 | 只另开会话,文件保持现状 |

没有可回退的文件时,仍然可以只回退对话。文件恢复失败时不会另开会话。同一工作区还有代理在跑时,默认不允许改文件。

设置在插件详情页,不在客户端的设置面板里。改完立即生效。

设置

| 设置 | 默认 | 说明 |
| 跳过生成目录 | 开 | 不记录「生成目录」里列出的目录,回退时也不删除它们 |
| 生成目录 | 常见语言的生成目录和临时目录 | 目录名用逗号分开,按路径中的一整段匹配。*.egg-info 匹配以 .egg-info 结尾的目录。这里填的是完整名单。build、bin、obj、out、vendor、Library 这类较宽的名字可以删掉 |
| 记录回合之间的改动 | 开 | 每轮开始时记下工作区。之后的手改和脚本改动,回退到这一轮时撤掉 |
| 记录子代理 | 开 | 子代理改的文件算到父会话当前这一轮 |
| 命令工具 | 标明跑过命令 | 只标明这一轮跑过命令,不给命令做快照。合格文件仍回到这一轮开始时的内容。另一项是「不标明」 |
| 文件冲突 | 询问 | 文件已经和记录不一致时:询问、跳过,或覆盖 |
| 删除本轮新建的文件 | 开 | 关闭后,这一轮新建的文件留在原地 |
| 把原话放回输入框 | 开 | 回退对话后,把当时的用户消息放进新会话的输入框 |
| 运行中禁止改文件 | 开 | 同一工作区还有代理在跑时,不允许回退代码 |
| 保留天数 | 30 | 0 表示不按天数删除 |
| 最大存储空间 | 2048 MiB | 全部会话加在一起的上限。超出后丢掉最旧的一轮,至少保留一轮 |
| 最大存储轮数 | 1000 | 全部会话加在一起最多保留这么多轮 |

生成目录、符号链接、硬链接,以及超过大小或数量上限的文件,不会自动撤掉。单个文件默认不超过 8 MiB,一轮默认最多记录 2000 个文件。

存储默认在 $DSH_HOME/rewind/v1。没有该变量时用 ~/.dsh/rewind/v1。存储目录只能在配置层修改,运行中不能改。

兼容

package.json 声明的 DeepSeek Harness 版本:

=0.1.0-rc.8 <0.2.0 || ^0.1.7-rc.1 || 0.2.0-rc.2

Node.js:^22.19.0 || >=24。

开发

pnpm install
pnpm test

pnpm test 会先构建 lib/,再运行测试。测试覆盖修改前记录、失败工具、命令缺口、冲突、新建文件、排除路径、符号链接、保留上限、回合之间的手改,以及中断回退后的启动补偿。

许可证

BSD-3-Clause
预览分享卡片长什么样 ↓YIYuNCU/dsh-rewind
分享 · DeepSeek Harness Hub
YIYuNCU/dsh-rewind

把文件恢复到某轮开始时的内容并另开会话

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部