EIGHTfs / dsh-git-rescue

Listed

DSH git 版本管理 + 崩溃自动救援插件(仅 GitHub token 方案)

mainOther View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:EIGHTfs/dsh-git-rescue

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 05b2da3Synced Aug 18, 2026

This README snapshot could not be refreshed during the latest directory sync.

🛟 dsh-git-rescue

DSH git 版本管理 + 崩溃自动救援插件

.dsh 用户目录(sessions 会话、settings、profiles 配置)与 workspace 纳入 git 版本管理, 用 commit 历史做精细回退;harness 崩溃时自动回退到上一个好版本。远端备份仅支持 GitHub token 方案

体系架构


✨ 为什么需要它?

DeepSeek Harness 改配置、装插件、跑长任务都是家常便饭,风险也随之而来:

  • 😱 改崩了 —— cordis.patch.yml 写错、插件冲突,DSH 启动失败白屏
  • 😱 会话丢了 —— sessions 目录误删/损坏,几天的对话留档没了
  • 😱 反复改反复崩 —— 不知道回退到哪一步才是好的,只能凭记忆重做
  • 😱 单机无备份 —— 机器坏了/重装,全部配置与工作留档烟消云散

dsh-git-rescue 的思路:一切历史都是 git 历史。 版本管理交给 git,救援恢复就是回退, 远端备份交给 GitHub(token)。与现有的 zip 快照方案(dsh-snapshot-guardian)互补:

方案手段特点适用
dsh-snapshot-guardianzip 全量快照 + 解压恢复零依赖、快照间无关联、恢复 = 解压启动失败/网页崩了的手动兜底
dsh-git-rescue(本插件)git 增量历史 + commit 回退可 diff、可溯源、自动触发、可远端备份日常版本管理 + 崩溃自动恢复

🧭 设计原理

原理一:版本管理 = git 仓库 + 自动 commit

管理对象路径说明
用户目录.dsh/settings.yamlprofiles/sessions/skills/DSH 全部可编辑状态
工作区workspace/(白名单)项目源码、留档、脚本;按 .gitignore 规则入库

触发时机(任一命中即 commit):

  • 🚀 启动时(恢复现场,记录"上次结束时长什么样")
  • 💥 崩溃检测到时(先记坏状态,再谈回退)
  • ⏱️ 定时(默认每 30 分钟,可配置)
  • 👆 手动(设置页一键备份)

commit 规范chore(guard): <触发原因> | <自检摘要>,例如 chore(guard): crash-detected | pre-rollback snapshot of broken state —— 每个 commit 都能回溯"当时发生了什么"。

入库边界(安全第一):

  • ❌ 凭据永不入库:.credentials.yaml.env、token 文件
  • ❌ 大文件不入库:.fpk.zip.tgznode_modules/
  • ❌ sessions 为 zstd 压缩的 jsonl.zstd(二进制、整体差异大)→ 采用 定期全量基线 + 短周期增量 策略,避免仓库无限膨胀
  • .gitignore 规则由插件首次初始化时自动生成并提交

原理二:救援恢复 = git 回退

崩溃检测 → ① 强制 commit 当前坏状态(可事后分析)
        → ② 从坏点向前找最后一个"好" commit
        → ③ 回退前做一次全量副本备份(双保险)
        → ④ git reset/checkout 回退
        → ⑤ 重启 DSH 自检(端口监听 + 健康检查)
        → ⑥ 失败则继续回退上一步,最多 N 步(默认 3,可配置)
  • 坏点标记:回退过的 commit 打 bad 标记,防止"回退后又回到同一个坏点"的死循环
  • 回退动作可逆:回退前有全量副本,误回退也能再恢复

原理三:远端备份 = GitHub + token(唯一方案)

  • 🔑 只接受 GitHub token:插件配置页填写 token,push 走 HTTPS
  • 🔒 token 只存本地,权限 600,绝不写入任何 commit;仅用于 push 认证
  • ⚠️ 环境自检:初始化时检测系统 git 是否可用。已知坑:本机 git 缺少 git-remote-https 助手,HTTPS git 操作直接失败 —— 插件检测到该情况时自动降级为 GitHub REST API 直连(curl/Node fetch + token),保证 token 方案在异常环境下依然可用
  • ☁️ 远端仓库结构:<账号>/dsh-git-rescue-backup-<设备ID前12位>每台设备一个备份仓
  • 🪪 设备身份 = 设备稳定指纹,不是主机名:主机名会撞车(不同设备同名)也不稳定(同设备改名)。 默认仓名基于 /etc/machine-id(Linux 系统级唯一 ID,兜底为持久化 UUID), 同一 GitHub 账号下多台设备互不冲突;hostname 仅进仓库描述供人识别,githubRepo 配置仍可手动覆盖

原理四:崩溃检测与自动回退

检测手段判定说明
进程探活dsh web 进程消失guardian 独立进程周期探活(每 10s)
心跳文件心跳超时(默认 60s)DSH 内插件定期写心跳,guardian 读
启动自检端口未监听 / 白屏重启后健康检查不通过 = 判定为坏状态

检测到崩溃 → 走原理二的自动回退流程 → 回退后自动拉起 DSH → 自检通过则通知恢复完成。


🔄 工作流程总览

┌─────────────┐   ┌──────────────────────────┐   ┌─────────────────┐
│  DSH 启动    │──▶│ ① 检测运行机器有无 git     │──▶│ ② 检查插件配置   │
└─────────────┘   │    (git --version)        │   │    (token 等)    │
                  └──────────────────────────┘   └────────┬────────┘
                                                          ▼
                  ┌─────────────────────────────────────────────┐
                  │ ③ 初始化 git 仓库 + .gitignore + 首次 commit   │
                  └─────────────────────────────────────────────┘
                                                          │
                  ┌───────────────┐   每 30min / 事件触发    ▼
                  │ ④ 自动 commit  ◀───────────────────── 版本快照
                  └───────┬───────┘
                          │
                  ┌───────▼───────┐   push (token)   ┌──────────────────┐
                  │ ⑤ 远端备份     │────────────────▶│ GitHub 备份仓库    │
                  └───────┬───────┘                  └──────────────────┘
                          │
                  ┌───────▼───────┐
                  │ ⑥ 崩溃监控     │──崩溃?──▶ ⑦ commit 坏状态 → ⑧ 自动回退 → ⑨ 重启自检
                  └───────────────┘

📦 组件规划

组件一:dsh-git-rescue 插件(DSH 进程内)

  • 设置页卡片:token 配置、触发策略、仓库状态、手动备份/回退按钮
  • 自动 commit 与心跳写入
  • Agent 工具:git_rescue_backup / git_rescue_status / git_rescue_rollback

组件二:guardian 独立进程

  • 为什么独立? 网页崩了恢复按钮就没了 —— 监控与回退必须活在 DSH 之外
  • 周期探活 + 崩溃自动回退 + DSH 拉起(与 dsh-snapshot-guardian 的守护进程同思路,机制换成 git 回退)
  • 独立日志 guardian.log,动作全程留痕

组件三:手动兜底(零依赖)

  • 什么都不装也能用:cd ~/.dsh && git log --onelinegit reset --hard <commit>
  • 崩溃到连 guardian 都起不来时,命令行 git 就是最后一张网

🔒 安全边界

条目约定
token 存储本地文件,权限 600,仅 push 用,绝不提交
远端仓库只含版本历史与快照,不含任何凭据明文
回退安全回退前全量副本 + 坏点标记 + 最大回退步数
大文件一律 gitignore,仓库只保留文本/配置/小体积留档

📚 设计理念

  1. 历史即资产:凡是 DSH 可编辑的状态都进 git,丢了的都能找回来
  2. 回退是最终手段,也是自动手段:手动可回、守护可回、崩溃自动回
  3. token 唯一、环境自检:只认 GitHub token,环境不对劲时自动降级,不把鸡蛋放一个篮子里
  4. 三层网互不依赖:插件(网页活时)、guardian(进程活时)、命令行 git(永远在)——每层都能独立救援

📖 设计溯源:从 zip 快照方案学到的原理

原独立仓库 dsh-snapshot-archive / dsh-guardian / dsh-snapshot-guardian 已合并入本仓库并从 GitHub 删除。 以下是从中提取、迁移到 git 方案的原理要点——原仓库已不在,这份记录就是永久提醒,后续开发照此执行。

核心思想(三仓库共通)

  1. 恢复 = 最朴素的操作:zip 版恢复 = 解压覆盖;git 版 = git reset --hard;网页全崩,命令行也能救
  2. 监控不能依赖被监控对象:guardian 独立进程 + 独立端口,DSH 崩了它照样活着
  3. 三层安全网互不依赖:插件(网页活) → guardian(进程活) → 手动(文件/命令在),故障域最小化
  4. 敏感隔离:凭据脱敏 / 独立文件 600 权限,绝不进备份
  5. 双入口:设置页按钮 + Agent 工具
  6. 回退前保留现场:先快照/commit 坏状态,再谈回退
  7. 连续失败阈值:连续 N 次失败才触发回退,防单次误判
  8. 回退后自证健康:重启 + 健康检查通过才算恢复成功
  9. 撤销即恢复:不搞撤销栈,从历史选一个点恢复
  10. 零依赖可移植:zip 自实现 / git 命令 spawn 封装

迁移对照(zip 方案 → git 方案)

原 zip 方案git 方案(本仓库)
zip 全量快照(.dsh 原始路径)git 增量历史(add -A 自动 commit)
恢复 = unzip 覆盖恢复 = git reset --hard
敏感文件脱敏 ***REDACTED***token 单独文件 600 + .gitignore 排除
guardian 探活 + failThreshold=3照搬(GUARDIAN_FAIL_THRESHOLD)
回退前 autoSnapshotpre-rollback commit 坏现场
重启 + 健康检查自证照搬(startWaitMs + probe)
手动 unzip 兜底命令行 git 兜底
快照自带三平台恢复脚本不需要(git 本身跨平台)

增强(git 方案新增,原方案没有)

  • bad 标记:回退过的提交打 bad-* tag,防"回退后又回到同一坏点"死循环
  • 心跳文件 + 启动自检:区分"进程挂了"与"启动即崩",崩溃检出更细
  • GitHub token 远端备份 + REST API 降级:绕开 git-remote-https 缺失的环境坑
  • sessions 入库策略:zstd 二进制直接入库,靠 .gitignore 排除大文件/凭据控体积

🧪 测试结果(2026-08-18,测试实例 3083 实测)

  • git 环境检测:git 2.43.0 可用,git-remote-https 缺失被正确检出(推送自动走 REST API)
  • 有 git 无 token:本地版本管理正常,push 返回明确提示
  • git-remote-https 缺失环境:REST API 推送成功(159 文件,敏感文件零泄漏)
  • 模拟崩溃(kill dsh web):崩溃检测 90s 阈值检出 crash-detected + 自动 commit 现场
  • guardian 自动救援 e2e:破坏 cordis.patch.yml 致无法启动 → 自动 git 回退 → 拉起 → 自检通过
  • 坏点标记:回退后再次崩溃不会回到同一 commit(bad-* tag 实测)
  • 破坏测试:篡改 settings.yaml / 删除被跟踪文件 → 回退恢复
  • sessions 基线+增量策略:仓库体积增长可控(后续优化项)

🧪 测试体系:不测"正常",专测"搞破坏"

救援工具的信任来自反面测试。我们不信"应该没问题",而是故意把它弄坏,再让它自己爬起来—— 这是本项目的核心测试哲学,也是它敢自称"救援"的底气。

破坏矩阵(5 类真实破坏,全部实测通过)

#破坏手段破坏对象验证的救援能力结果
1篡改配置settings.yaml 写入垃圾git 回退恢复原状
2删除文件删除被跟踪的 pnpm-workspace.yaml回退找回文件
3连环破坏恢复后再次破坏bad 标记防回退死循环
4进程秒杀kill -9 dsh web心跳过期检出 crash-detected + 自动 commit 现场
5灭门级破坏 cordis.patch.yml 致 DSH 无法启动guardian 自动 git 回退 → 拉起 → 健康自检

灭门级测试的完整时间线(真实日志节选)

10:21:44  健康检查失败(连续 1/3)
10:21:54  健康检查失败(连续 2/3)
10:22:04  健康检查失败(连续 3/3)→ 触发自动救援
10:22:04  坏点标记: bad-c6a588b            ← 坏提交被标记,防再次踩坑
10:22:04  已回退到 bd6824c(from c6a588b) ← git reset --hard 秒级完成
10:22:04  启动 DSH: <自动拉起命令>
10:22:09  ✅ 救援成功:回退后 DSH 恢复正常  ← 5 秒内满血复活

为什么值得"吹"

  • 留证:每次破坏都会留下一个可事后分析的坏提交(pre-rollback snapshot)——不只救回来,还保留完整现场供复盘
  • 防死循环:坏点标记(bad-* tag)保证"回退后再次崩溃不会回到同一个坏点"——这是 zip 方案没有的增量能力
  • 可复现:整套破坏流程跑在一次性测试实例上,任何人想验证都能安全重放,不碰生产数据

独立测试环境:测试随便崩,生产不动摇

为什么必须独立:改插件必须重启 DSH,而重启会中断正在进行的会话 → 插件测试一律在隔离实例进行。

┌─ 主实例(生产/会话)────────────────────────┐
│  dsh web  127.0.0.1:3081   DSH_HOME=~/.dsh  │
│  └ 反代 0.0.0.0:3080(局域网访问)           │
└──────────────────────────────────────────────┘
┌─ 测试实例(插件热开发,随便崩)───────────────┐
│  dsh web  127.0.0.1:3083-3182(自动分配)    │
│  DSH_HOME=workspace/dsh-test-home(完全隔离)│
│  └ 反代 0.0.0.0:3084(局域网访问)           │
└──────────────────────────────────────────────┘

要点

  • 完全隔离:测试实例有自己的 DSH_HOME(配置/会话/插件互不干扰),kill -9 测试实例不碰主实例一根汗毛
  • 不烧生产额度:测试实例复用 provider 配置但独立运行,长测试不占主实例资源
  • 注册三要素 + 软链机制:插件源码放 node_modules_local/ → package.json 声明 file: 依赖 → cordis.patch.yml insert → node_modules 补软链(踩坑后总结的解析机制)
  • 干净基线dsh-clean-env.sh 一键生成"初始、无插件"的纯环境,做插件前后对照 / 隔离排查
  • 分层兜底:网页崩了有 guardian(独立进程),guardian 崩了有命令行 git——每层都独立可救

数据:单元测试 23/23(含真实 GitHub 推送往返)、5 类破坏场景全过、guardian 救援 5 秒自愈。

✅ 三合一合并(已完成)

结果:三个原独立仓库(dsh-snapshot-archive / dsh-guardian / dsh-snapshot-guardian)已并入本仓库并从 GitHub 删除(2026-08-18,用户确认)。

合并来源归入位置状态
zip 快照归档components/snapshot-archive/(组件 A)✅ 已合并
守护进程components/guardian/(组件 B)✅ 已合并
git 版本管理+救援components/git-rescue/(组件 C)✅ v1.2.0 已开发完成
整合版(A+B)不纳入(用户指定),已删分支与仓库✅ 已删除

三组件协同关系

组件手段职责
A 快照归档zip 全量快照零依赖兜底,网页全崩也能手动 unzip 恢复
B guardian 守护独立进程探活网页/进程全崩时自动回退 + 拉起
C git 救援git 增量历史精细回退、可 diff、GitHub token 远端备份

License

MIT

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

TestsDetected
DocumentationDetected

Repository information

Language
JavaScript
License
MIT
Last updated
Aug 18, 2026, 4:03 AM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.