dsh-settings-sync:用私有 Git 仓库备份和恢复 DSH 全部配置

前言

DSH 的配置分散在几个地方:插件清单和 profile 的 bundle 列表在 ~/.dsh/profiles/<profile>/package.json,每个插件各自定义的模型、MCP 服务器和面板配置在 ~/.dsh/profiles/<profile>/cordis.patch.yml,技能在 ~/.dsh/skills/ 与 ~/.agents/skills/,插件自己的状态在 ~/.dsh/<plugin>/。这些位置都容易丢:重装、换机器、误删,任何一次都够你重建一遍。

已有做法是 dsh export,它把配置拷成一份文件,之后怎么搬、搬到哪、搬之前改了什么,都要你自己管。下面介绍的 dsh-settings-sync 把这个动作变成持续的同步:一个你自己拥有的私有 Git 仓库,一个方向一个按钮,提交前还能看到完整 diff。

这是什么

dsh-settings-sync 是一个 DeepSeek Harness 插件,维护者是 elfgzp。它把 DSH 的 profile 配置、插件设置、技能、已安装插件清单和 MCP 服务器定义收集成一个快照,推到你指定的私有 Git 仓库,也可以从仓库拉回并恢复。不是增量备份工具,也不维护自己的存储格式——快照本体就是一个正常的 Git 仓库。

同步范围

快照包含这些文件:

manifest.json                 快照由什么产生、什么时候产生
profile/package.json          插件清单和 bundle 列表
profile/cordis.patch.yml      每个插件的配置
profile/cordis.yml            profile 的根入口列表
profile/pnpm-workspace.yaml   workspace 和 release 年龄
homes/dsh/<plugin>/*.json     插件级设置(星标项、默认项目、任务)
homes/dsh/skills/<name>/…     $DSH_HOME 下的用户级技能
homes/agents/skills/<name>/…  $DSH_AGENTS_HOME 下的共享技能

下面是刻意排除的:

  • 凭据。 ~/.dsh/.credentials.yaml、tencent-intranet-auth.json、.env、*.pem、*.token、pairing.json 同时按文件名和内容排除。此外,已被纳入同步的配置里如果出现明文值,比如 cordis.patch.yml 里的 apiKey: 行,在快照离开本机前会被替换成 <redacted by dsh-settings-sync>,配置结构保留,恢复时你知道那里需要一个 key,然后自己补上。
  • 依赖与缓存。 node_modules、pnpm-lock.yaml、__pycache__、.plugin-manager 日志、附件文件。
  • 会话与历史。 ~/.dsh/sessions、~/.dsh/storages。历史不是配置,而且是 DSH home 里最大的那一块。
  • 旧编辑的备份。 profile 里任何匹配 .bak 的文件。

README 给了一个真实机器的量级:21 个已装插件、66 个技能、6 个插件级状态目录,收集结果 263 个文件、1.4 MB。

安装与启用

README 的做法是先把仓库放到本地路径,比如 ~/Work/Github/dsh-settings-sync。然后在 DSH 里通过 Settings → Plugins → Install 安装,或者在终端运行:

dsh plugin install ~/Work/Github/dsh-settings-sync

前提是 git 在 PATH 上(没有的话在插件配置里填绝对路径);只有在用到“一键创建仓库”按钮时才需要已登录的 GitHub CLI,即先用 gh auth login 完成认证。

插件安装后会在 Settings 下新增一个 Settings Sync 页面,第一次启动时弹出一个问题:从远端拉配置下来,还是把这台机器的配置推上去。

典型用法

  1. 设置仓库。 粘贴一个空的私有仓库地址,git@github.com:you/dsh-settings.git 和 https://github.com/you/dsh-settings.git 都行;也可以点 Create private repo,让 gh 去建一个。
  2. Push,把这台机器的配置传上去。
  3. 在另一台机器上安装插件,粘贴同样的地址,点 Pull。

按下去之前,diff 面板会完整展示这次 push 会改什么:+added、~modified、-removed,先看完再确认。

自动同步

设置项 含义
Redact secrets 上传前把真实 key 替换成占位符,默认开启
Auto push 设置变化后按检查间隔自动 push
Remote policy never 忽略远端;ask 弹窗询问(默认);always 当远端领先且本地干净时自动 pull
Check interval Off、5 分钟、30 分钟、1 小时

安全模型

  • 没有恢复点就不覆盖。 Pull 会先把当前状态完整复制到 <stateDir>/backups/<timestamp>-snapshot/,pull 结束后会报出这个路径。恢复点列在设置页面上,可以一键还原。
  • 收集不到东西的 push 会被拒绝。 HOME 解析错误看起来像“用户删掉了所有东西”,把一份好备份静默替换成空快照是不可恢复的。同理,一次 push 如果会删掉大部分已跟踪文件,除非显式 force,否则也会被拒。
  • 快照是真实的 Git 仓库,位于 <stateDir>/mirror。历史就是备份:在那里跑 git log 能看到每次同步,git show <commit>:profile/cordis.patch.yml 能拿到任意一次的旧文件。插件因此不需要自己的撤销格式。
  • push 和 pull 串行执行。 一次只跑一个操作,靠一个 busy 标志控制,第二次点击会等待而不是互相插队;pull 进行中的自动定时触发会被跳过。
  • 认证用你自己的。 插件不保存 token,它执行的就是用户平时跑的 git,所以 osxkeychain、SSH agent 或 credential.helper 都照常生效。反过来说也诚实:如果你在终端里 git push 对该仓库本来就不工作,在这里也一样不工作,报错会直接说明。

所有状态默认放在 $DSH_HOME/settings-sync 下:

config.json   repository、branch、策略、commit 身份
mirror/       本地克隆,它的历史就是快照历史
backups/      恢复点
last-run.json 最近一次 push 或 pull 的结果

开发与验证

仓库自带的检查:

pnpm test    # 等价于 node --test test/*.test.js
pnpm check   # 对每个模块跑 node --check

测试直接用真实 git 二进制,在一个临时 home 目录里搭出假 profile、两个技能根、插件级状态目录、一个禁止同步的凭据和一个代表远端的裸仓库。没有 mock git,因为最容易出错的就是 git 这一层。engines 要求 node >=20。

适用场景与注意

适合想要把 DSH 环境带着走、又不想自己写脚本维护备份的人:一台机器 push,另一台机器 pull,配置差异在按下去之前就能读完。也适合把私有仓库当作订阅源,让团队里不同机器上跑同一份 profile 配置。

需要留意的:

  • 凭据永不同步,换机器后需要重新填 API key。这既是限制也是设计意图。
  • 插件以当前 DSH 进程的权限运行,能读到和写入它能访问的所有路径。安装前应打开源码看一眼,确认目录排除逻辑符合你的环境,并核对许可证(MIT)。
  • 快照保存的是配置,不保存会话历史和依赖缓存;恢复后仍需重新装依赖。

插件在社区目录 SkillHub 的分类是 admin-security。需要说明的是,SkillHub 是独立站点,与 DeepSeek / 幻方没有官方从属关系,不是官方应用商店。

结尾

DSH 的理念是“一切皆插件”,配置同理值得写进你自己的仓库。上面这些能力来自 README 和 package.json 里的描述,是否适合你取决于你的备份习惯和对 Git 的熟悉程度。

  • 目录页:https://www.skillhub.cn/plugins/elfgzp/dsh-settings-sync
  • GitHub:https://github.com/elfgzp/dsh-settings-sync
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜