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

崩溃备份 2000HINA/dsh-crash-backup

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

手动快照当前环境,崩溃后双击脚本即可回档

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

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

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

状态速览

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

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

验证判据与等级说明 →

可信度证据

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

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

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 59 处,展示前 56 条)
  • 执行外部命令固定命令
    index.js:24
    const child = spawn('explorer.exe', [target], { detached: true, stdio: 'ignore' })
  • 发起网络请求
    client.js:699
    const response = await fetch(pathname, { cache: 'no-store', ...(init ?? {}) })
  • 执行外部命令来自配置/变量
    lib/config.js:40
    const result = spawnSync(
  • 读取本地文件
    lib/backup.js:122
    await access(target)
  • 读取本地文件
    lib/backup.js:132
    return (await stat(target)).isFile()
  • 读取本地文件
    lib/backup.js:142
    info = await stat(dir)
  • 读取本地文件
    lib/backup.js:218
    entries = await readdir(root, { withFileTypes: true })
  • 写入本地文件
    lib/backup.js:278
    await rename(source, target)
  • 写入本地文件
    lib/backup.js:365
    await mkdir(partial, { recursive: true })
  • 写入本地文件
    lib/backup.js:395
    await writeFile(
  • 写入本地文件
    lib/backup.js:419
    await writeFile(path.join(partial, names.ps1), `${BOM}${renderRestorePs1(restoreMeta)}`, 'utf8')
  • 写入本地文件
    lib/backup.js:420
    await writeFile(path.join(partial, names.cmd), renderRestoreCmd(), 'utf8')
  • 删除本地文件递归
    lib/backup.js:438
    await rm(partial, { recursive: true, force: true }).catch(() => {})
  • 读取本地文件
    lib/backup.js:503
    rootReal = await realpath(root)
  • 读取本地文件
    lib/backup.js:511
    info = await lstat(target)
  • 删除本地文件递归
    lib/backup.js:539
    await rm(targetReal, { recursive: true, force: true })
  • 删除本地文件递归
    lib/backup.js:564
    await rm(dir, { recursive: true, force: true })
  • 读取本地文件
    lib/location.js:58
    const data = JSON.parse(await readFile(path.join(root, BACKUP_ROOT_MARKER), 'utf8'))
  • 写入本地文件
    lib/location.js:68
    await writeFile(file, contents, { encoding: 'utf8', flag: 'wx' })
  • 写入本地文件
    lib/location.js:91
    await mkdir(root, { recursive: true })
  • 读取本地文件
    lib/location.js:92
    const entries = await readdir(root)
  • 写入本地文件
    lib/location.js:102
    await mkdir(path.join(root, '_pre-restore'), { recursive: true })
  • 写入本地文件
    lib/location.js:103
    await mkdir(path.join(root, '_restore-logs'), { recursive: true })
  • 读取本地文件
    lib/manifest.js:87
    return (await readFile(path.join(installDir, 'version'), 'utf8')).trim()
  • 读取本地文件
    lib/manifest.js:100
    const pkg = JSON.parse(await readFile(path.join(profileDir, 'package.json'), 'utf8'))
  • 读取本地文件
    lib/manifest.js:124
    entries = await readdir(dir, { withFileTypes: true })
  • 读取本地文件
    lib/manifest.js:132
    info = await lstat(full)
  • 执行外部命令固定命令
    lib/picker.js:66
    child = spawn(
  • 写入本地文件
    lib/picker.js:110
    await writeFile(scriptPath, `\uFEFF${buildScript(initial)}`, 'utf8')
  • 删除本地文件
    lib/picker.js:113
    await rm(scriptPath, { force: true }).catch(() => {})
  • 读取本地文件
    lib/restore.js:28
    return existsSync(restoreLeasePath(backupRoot))
  • 读取本地文件
    lib/restore.js:45
    return existsSync(full) ? full : 'powershell'
  • 执行外部命令来自配置/变量
    lib/restore.js:83
    const child = spawn(file, args, {
  • 读取本地文件
    lib/settings.js:30
    const parsed = JSON.parse(readFileSync(settingsFile(home), 'utf8'))
  • 写入本地文件
    lib/settings.js:42
    await mkdir(win32.dirname(file), { recursive: true })
  • 写入本地文件
    lib/settings.js:44
    await writeFile(temporary, `${JSON.stringify({ backupRoot }, null, 2)}\n`, 'utf8')
  • 写入本地文件
    lib/settings.js:45
    await rename(temporary, file)
  • 删除本地文件
    lib/settings.js:47
    await rm(temporary, { force: true }).catch(() => {})
  • 写入本地文件
    lib/settings.js:73
    writeFileSync(probe, '')
  • 删除本地文件
    lib/settings.js:74
    unlinkSync(probe)
  • 读取本地文件
    lib/settings.js:93
    const info = statSync(resolved, { throwIfNoEntry: false })
  • 读取本地文件
    lib/settings.js:104
    return statSync(target).isDirectory()
  • 写入本地文件
    lib/settings.js:144
    mkdirSync(resolved, { recursive: true })
  • 读取本地文件
    lib/archive.js:13
    const root = await lstat(dir).catch(() => null)
  • 读取本地文件
    lib/archive.js:17
    const entries = await readdir(dir, { withFileTypes: true }).catch(() => [])
  • 读取本地文件
    lib/archive.js:22
    const info = await lstat(full)
  • 执行外部命令来自配置/变量
    lib/copy.js:59
    const child = spawn(ROBOCOPY, args, { windowsHide: true })
  • 读取本地文件
    lib/index-file.js:20
    const data = JSON.parse(await readFile(indexFile(root), 'utf8'))
  • 写入本地文件
    lib/index-file.js:32
    await mkdir(root, { recursive: true })
  • 写入本地文件
    lib/index-file.js:34
    await writeFile(tmp, body, 'utf8')
  • 写入本地文件
    lib/index-file.js:35
    await rename(tmp, target)
  • 删除本地文件
    lib/index-file.js:37
    await rm(tmp, { force: true }).catch(() => {})
  • 读取本地文件
    lib/index-file.js:45
    if (!(await stat(path.join(dir, 'payload'))).isDirectory()) return false
  • 读取本地文件
    lib/index-file.js:46
    return (await stat(path.join(dir, 'manifest.json'))).isFile()
  • 读取本地文件
    lib/index-file.js:73
    entries = await readdir(root, { withFileTypes: true })
  • 读取本地文件
    lib/index-file.js:84
    const manifest = JSON.parse(await readFile(path.join(dir, 'manifest.json'), 'utf8'))
扫描于 2026/11/5(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

用崩溃安全的恢复脚本复制目录,备份 DSH 环境。

README

由 DeepSeek 最新模型翻译生成
dsh-crash-backup DSH Desktop 的崩溃备份插件:手动把当前环境保存成一个目录快照。DSH 崩溃或无法启动后,直接双击存档里的 RESTORE.cmd 就能回档。 - 一份存档 = 一个文件夹:dsh-save-<时间戳>\,里面是 payload/ 目录、manifest.json、RESTORE.cmd 和 RESTORE.ps1。 - 只手动备份:没有定时任务、启动/退出自动备份、agent 工具或后台监听;只有设置页的「备份当前环境」按钮会创建存档。 - 不依赖 DSH 回档:RESTORE.cmd / RESTORE.ps1 是独立脚本,DSH 进程不存在也能运行。
展开完整文档(README 剩余 1 节)
dsh-crash-backup

DSH Desktop 的崩溃备份插件:手动把当前环境保存成一个目录快照。DSH 崩溃或无法启动后,直接双击存档里的 RESTORE.cmd 就能回档。

- 一份存档 = 一个文件夹:dsh-save-<时间戳>\,里面是 payload/ 目录、manifest.json、RESTORE.cmd 和 RESTORE.ps1。
- 只手动备份:没有定时任务、启动/退出自动备份、agent 工具或后台监听;只有设置页的「备份当前环境」按钮会创建存档。
- 不依赖 DSH 回档:RESTORE.cmd / RESTORE.ps1 是独立脚本,DSH 进程不存在也能运行。

环境要求

| 项目 | 要求 |
| 操作系统 | Windows 10 1803+ / Windows 11(回档依赖系统自带的 tar.exe 和 robocopy) |
| PowerShell | Windows PowerShell 5.1(RESTORE.ps1 声明 #Requires -Version 5.1) |
| DSH | DSH Desktop,当前开发与验证版本为 44.7.0;其它版本未验证 |
| 备份空间 | 每份存档约 2.6 GB;备份目录所在磁盘至少 3 GB 可用空间 |
| 回档空间 | 回档直接从存档目录复制,不再需要额外的解压空间 |
| 权限 | 当前用户可读写 DSH 安装目录、插件 profile 和备份目录 |

只支持 Windows;插件默认管理 desktop profile。

安装

方式一:DSH 插件市场(若已上架)

在 DSH 侧栏打开「插件」页,搜索 dsh-crash-backup,安装并启用。市场尚未上架时(0.1.0 未发布),使用方式二或方式三。

方式二:link: 本地仓库(推荐给开发者)

1. 打开当前 profile 的 package.json(默认 profile 为 desktop):

%USERPROFILE%\.dsh\profiles\desktop\package.json

设置了 DSH_HOME 时改用:

%DSH_HOME%\profiles\desktop\package.json

2. 在 dependencies 中加入下面这一行(路径按实际仓库位置修改,JSON 中用正斜杠):

"dsh-crash-backup": "link:C:/tool/dsh-crash-backup"

3. 在 dsh.profile.bundles 数组末尾加入包名,启用该 bundle:

"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-crash-backup"
]
}
}

4. 重启 DSH。侧栏「插件」页应能看到 dsh-crash-backup 并处于启用状态;若没有,用下面的方式三兜底。

方式三:手动复制到 node_modules + bundle patch

先关闭 DSH,然后复制整个包:

$profileDir = Join-Path $env:USERPROFILE '.dsh\profiles\desktop'
$dest = Join-Path $profileDir 'node_modules\dsh-crash-backup'
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Copy-Item -Path 'C:\tool\dsh-crash-backup\' -Destination $dest -Recurse -Force

再把下面这段追加到 profile 的 cordis.patch.yml(默认 %USERPROFILE%\.dsh\profiles\desktop\cordis.patch.yml):

- insert:
- id: dsh-crash-backup
name: 'dsh-crash-backup'
config:
profile: desktop

重启 DSH。手动复制的包不会由包管理器维护,下次 pnpm install 或插件安装可能把它清掉;能用方式二就不要用方式三。

首次使用

1. 重启 DSH,打开 设置 → 存档(侧栏也有入口)。
2. 点击 备份当前环境。
3. 等待进度条依次经过:准备备份 → 检查环境 → 复制安装目录与插件 → 写入回退脚本 → 完成。备份期间可以继续使用 DSH,但不要关闭进程。
4. 完成后出现存档卡片,显示创建时间、DSH 版本、插件数量、大小和存档 id。

默认最多保留 3 份存档;达到上限后先删除一份旧存档,再备份。备份根目录可以在页面里用「更改目录」修改,不能选磁盘根目录、DSH 安装目录、profile 目录或 DSH home 内部(自动回退目录 %DSH_HOME%\dsh-backups 除外);所选文件夹必须是空文件夹,或已经是本插件的备份目录,否则会被拒绝以免覆盖其中的文件。

崩溃后回档

1. 打开备份根目录。默认是 DSH 安装目录同级的 dsh-backups:DSH 装在 C:\tool\dsh 时就是 C:\tool\dsh-backups;默认目录不可写时会回退到 %DSH_HOME%\dsh-backups。也可以在设置页「存档」查看实际路径并点「打开文件夹」。
2. 进入要回档的 dsh-save- 文件夹(按时间选最新的,或选崩溃前的那份)。
3. 双击 RESTORE.cmd。
4. 脚本先显示存档信息,然后让你选择回档方式:输入 1 是完整回档,输入 2 是仅回滚插件(两种模式的差别见下一节)。
5. 输入 Y 确认;如果脚本检测到 DSH 仍在运行,会再问一次是否结束进程,也输入 Y。
6. 等待脚本完成。成功、取消、失败三种结束都会停在窗口里,按任意键关闭。
7. 手动重新启动 DSH。

设置页「存档 → 回滚」的弹窗提供同样的两种模式,选定后点「确认回滚」,脚本会带着对应的模式启动。
脚本会先把当前配置快照到 _pre-restore,把过程写入 _restore-logs。也可以不双击,直接在存档目录运行:

完整回档 powershell -NoProfile -ExecutionPolicy Bypass -File .\RESTORE.ps1 -Mode full 仅回滚插件 powershell -NoProfile -ExecutionPolicy Bypass -File .\RESTORE.ps1 -Mode plugins

两种回档模式

| 模式 | 恢复范围 | 对存档后新增内容的处理 |
| 完整回档(-Mode full,默认) | DSH 安装目录、当前插件 profile、用户目录白名单、dsh-runtimes | 安装目录和 profile 用 robocopy /MIR 镜像,会删除存档之后新增的文件;用户目录和运行库只覆盖,不删除 |
| 仅回滚插件(-Mode plugins) | 只恢复当前插件 profile:package.json、pnpm-lock.yaml、cordis.patch.yml 和 node_modules | profile 用 /MIR 镜像,会删除存档之后新增的插件文件;其它内容一律不动 |

仅回滚插件的确切范围(适用场景:只是插件装坏或升级出问题,想回到某个插件组合,又不想动 DSH 本身):

- 只改插件 profile:package.json、锁文件 pnpm-lock.yaml、cordis.patch.yml 与 node_modules 恢复到存档状态;profile 里存档之后新增的插件会被删除。
- 不改 DSH 安装、用户数据和运行库:安装目录、home/(cordis.patch.yml、settings.yaml、.credentials.yaml、skills、storages 等)和 dsh-runtimes 都保持原样,DSH 版本也不会回退。
- 插件数据不回退:storages 等插件运行时数据不在恢复范围内,「仅回滚插件」不会把它们退回到存档时的状态。需要这些数据也回退时用完整回档。
- DSH 版本不一致会警告:存档版本与当前 DSH 版本不同时,脚本打印兼容性警告后继续;回档后的插件可能无法加载,遇到问题请改用完整回档。
- 同样需要重启:两种模式都会先关闭 DSH,完成(或取消、失败)后都要手动重新启动 DSH。

设置页的「回滚」弹窗原样提供这两种模式;存档没有插件内容(hasProfile: false)时,「仅回滚插件」置灰并说明原因。两种模式共用同一套确认、回档前快照、日志、本插件自排除和 junction 重建逻辑。

数据与目录

插件自己只保存一个设置:用户选定的备份根目录。

%USERPROFILE%\.dsh\dsh-crash-backup\settings.json # 只含 {"backupRoot": "..."}

DSH_HOME 非默认时,这个文件在 %DSH_HOME%\dsh-crash-backup\settings.json。存档本身放在选定的备份目录,默认是 C:\tool\dsh-backups;默认目录不可写时会自动回退到 %DSH_HOME%\dsh-backups,设置页会说明回退原因。

C:\tool\dsh-backups\
├─ dsh-save-20261024-214000\
│ ├─ payload\ # install/、profile/、home/、runtimes/ │ ├─ manifest.json # 版本、插件清单、链接与体积 │ ├─ RESTORE.cmd # 双击入口 │ └─ RESTORE.ps1 # 实际恢复脚本 ├─ _pre-restore\<时间戳>\ # 每次回档前的当前配置快照 ├─ _restore-logs\restore-.log # 回档日志(含 robocopy 失败明细) ├─ _restore-in-progress.json # 回档脚本运行期间的占用标记,结束自动删除 ├─ index.json # 存档索引(可重建的缓存) ├─ settings.json # 备份目录自身的元数据,不是插件设置 ├─ .dsh-crash-backup.json # 本插件的备份目录标记,请勿删除 └─ README.txt # 备份目录说明

如果回档脚本被强制结束(例如在任务管理器里结束进程),_restore-in-progress.json 可能残留在备份目录中,需要手动删除;在删除它之前,设置页会一直显示有任务正在进行。

存档的 payload/ 里包含:install/(DSH 安装目录)、profile/<profile>/(含 node_modules)、其它 profile 的配置文件、home/(用户配置白名单,存在时含 .credentials.yaml)、runtimes/;manifest.json 记录版本、插件清单、链接与体积。sessions、attachments、cache 不在存档里,回档也不会删除它们。

安全与风险

- 存档里有凭据:home/.credentials.yaml 会以明文进入存档,可能包含 API Key。不要上传、分享或同步备份目录,建议用 NTFS 权限限制访问,必要时放在 BitLocker 卷上。_pre-restore 里的配置也可能含敏感信息。
- /MIR 会删除文件:完整回档会把安装目录和插件 profile 恢复到存档时的状态,仅回滚插件同样会镜像整个插件 profile;存档之后新增或修改的内容都会丢失。确认要回到那一刻再执行。
- 本插件会保留自己:恢复 profile 时排除 node_modules\dsh-crash-backup,并用 manifest.json 记录的信息重建 link: 依赖的 junction;如果存档创建时插件还没安装,脚本会提示重新安装。
- 回档前会检查常驻进程:从 profile 的 node_modules 或用户目录启动的进程(dsh-ops 的 fastctx.exe/pwsh.exe、MCP server 等)会占用要恢复的文件;脚本会列出 PID 与路径并询问是否结束,拒绝或无法结束则中止,不修改任何目标。
- 时间戳按 2 秒精度比较:恢复使用 /FFT,存档在 exFAT/FAT32 或被复制工具重写时间时,未变化文件会被跳过;代价是「同尺寸且 2 秒内」的改动可能不被复制。
- 只恢复自己创建的存档:RESTORE.ps1 会执行恢复逻辑,不要运行来路不明的存档脚本。
- 备份不是瞬间快照:复制时 DSH 仍在运行,文件可能在写入过程中变化。重要操作前先备份;备份进行中不要安装或升级插件,也不要修改设置。

卸载

1. 在侧栏「插件」页禁用 dsh-crash-backup;需要彻底移除时用「移除」,或从 profile package.json 的 dependencies 和 dsh.profile.bundles 中删掉 dsh-crash-backup。
2. 手动复制安装的还要删两处:%USERPROFILE%\.dsh\profiles\desktop\node_modules\dsh-crash-backup,以及 profile cordis.patch.yml 中安装时追加的 - insert: 块(id: dsh-crash-backup)。只删除这一段,不要动其它插件配置;保留它会导致重启后 Loader 仍尝试加载已被删除的包并报错。

- insert:
- id: dsh-crash-backup
name: 'dsh-crash-backup'
config:
profile: desktop

3. 重启 DSH。

存档和设置不会被删除:存档在备份目录里,%USERPROFILE%\.dsh\dsh-crash-backup\settings.json 也会保留。不再需要时再手动删除备份目录;每份存档自带恢复脚本,即使插件已卸载也仍可回档。

故障排查

| 现象 | 处理 |
| 设置页看不到「存档」 | bundle 未启用或 DSH 未重启。打开侧栏「插件」页确认 dsh-crash-backup 已启用;手动安装的检查 cordis.patch.yml 和 node_modules 路径 |
| 选择目录 / 打开文件夹的窗口看不到 | 窗口可能被 DSH 挡在后面,查看任务栏或重试;仍不行时手动创建目录并写入 %USERPROFILE%\.dsh\dsh-crash-backup\settings.json:{"backupRoot": "D:\\dsh-backups"},重启 DSH |
| 双击 RESTORE.cmd 窗口一闪而过 | 在存档目录打开 PowerShell 手动运行 powershell -NoProfile -ExecutionPolicy Bypass -File .\RESTORE.ps1 -Mode full,查看完整报错和 _restore-logs 最新日志 |
| 存档缺少 payload/ 或 manifest.json | 脚本会在修改任何目标之前中止。换一个存档;检查磁盘错误和杀毒软件隔离记录;不要尝试强行恢复损坏的存档 |
| 磁盘空间不足 | 备份盘至少保留 3 GB;回档需要目标卷至少 256 MB 可用空间。清理磁盘,或在设置页把备份目录换到空间更大的卷 |
| 提示长路径未启用 | 备份/回档只提示不中止。把 HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled 设为 1 并重启 Windows,可避免深层目录因路径过长失败 |
| 杀毒软件拦截 RESTORE.ps1 / RESTORE.cmd | 把备份目录和 DSH 安装目录加入安全软件排除项,或在安全软件允许后手动运行;不要为此关闭实时防护 |
| 备份卡住或留下 .partial 目录 | 文件可能被杀毒软件/索引服务占用;稍后重试。超过 30 分钟的 .partial 会在下次备份前自动清理,也可关闭 DSH 后手动删除 |
| 回档后插件消失 | 存档创建于插件安装之前,profile 被存档覆盖。按上面的安装步骤重新安装 dsh-crash-backup |
| 回档后 DSH 无法启动 | 打开 _restore-logs 最新日志看最后一步;重新运行同一存档的 RESTORE.ps1(镜像是幂等的),或从 _pre-restore 手动取回配置 |

开发

npm test
node --check index.js
node --check client.js
Get-ChildItem lib -Filter .js | ForEach-Object { node --check $_.FullName }

打包检查:

npm pack --dry-run

发布前 TODO(维护者)

- [ ] 确认许可证:package.json 目前把 license 写成 MIT 占位,发布前需仓库所有者确认。
- [ ] 补 repository / homepage / author:目前没有真实 URL 和作者信息,package.json 未填写,避免编造。
- [ ] 补截图:设置页「存档」、存档卡片、RESTORE.cmd 窗口各一张,放进 docs/ 并链接到本 README。
- [ ] 确认 DSH 版本范围:当前只验证过 44.7.0;确认后写入 README 并考虑在 package.json 增加 engines.dsh。
- [ ] 市场发布:发布 npm 包并在 DSH 插件市场上架后,把「方式一」改为确定可用的步骤。
预览分享卡片长什么样 ↓2000HINA/dsh-crash-backup
分享 · DeepSeek Harness Hub
2000HINA/dsh-crash-backup

手动快照当前环境,崩溃后双击脚本即可回档

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