dsh-config-sync
August 17, 2026 · View on GitHub
把 DSH 配置目录(默认 ~/.dsh 与 ~/.agents/skills)镜像同步到 iCloud(或任意本地目录),
设置页「配置同步」按钮一键触发。MinIO / OSS 作为预留存储后端,已在配置 schema 与后端注册表中留位。
快速开始
# 1. link 安装进 web profile(已做则跳过)
# 在 ~/.dsh/profiles/web/package.json 的 dependencies 加:
# "dsh-config-sync": "link:/Users/apple/dev/dsh-config-sync"
# 然后 cd ~/.dsh/profiles/web && pnpm install
# 2. cordis.patch.yml 注册(见 cordis.patch.yml.example)
# 3. 重启 DSH(服务端插件需重启加载)
# 4. 打开 设置 → 配置同步 → 点「立即同步」
功能
- 一键同步:设置页「配置同步」Tab 的按钮 →
POST /dsh-sync/run,后台按源目录逐个镜像。 - 双向同步:支持
export(本机→备份,默认)与import(备份→本机,恢复)。- 导入是破坏性操作:UI 强制「预演导入(dry-run,不改动)→ 执行导入(二次确认)」两步;
- 引擎护栏:源==目标、导入目标落在备份根目录内 → 拒绝执行。
- 镜像语义(rsync 式):
- 大小或 mtime 不同的文件才复制(2ms 容差);
- 目标里源已不存在的文件删除、空目录修剪(
rsync --delete); - 排除项按路径段精确名匹配(
node_modules、.git)或根锚前缀(pnpm-lock.yaml); - 符号链接默认跟随(
followSymlinks: true):指向文件的链接复制为普通文件,指向目录的链接递归拷贝其内容——镜像跨机器可移植(如dws/find-skills指向~/.tokentracker/...的场景)。
- 符号链接自动还原:导出时把链接目标记录进备份根的
.dsh-sync-manifest.json;导入时——- 同机(原链接目标仍存在)→ 重建符号链接,保住 tokentracker 等活链接;
- 新机 / 目标已迁移 → 自动降级为文件副本,技能照常可用(结果里提示)。
- 配置热生效:settings namespace
dsh-sync(settings.yaml用户层)覆盖 patch base,UI 或改文件均免重启。
存储后端扩展(MinIO / OSS 预留)
后端注册表在 lib/index.js 顶部(registerBackend / getBackend / listBackends):
registerBackend({
id: 'minio', // 配置 `backend: minio` 即可路由到这里
label: 'MinIO 对象存储',
describe(cfg) { return { kind: 'object-store', ... } },
async mirror({ source, dest, excludes, followSymlinks }, emit) {
// dest 在此语义为对象键前缀;用 minio SDK 逐个 put / delete
},
})
核心引擎不做任何存储假设——只调 backend.mirror(opts, emit)。本地 backend 已实现;
minio/oss 配置块已 schema 化(Config.minio / Config.oss),UI 会显示为
「预留」并允许选中(选中后运行会给出明确的「后端未实现」错误)。
HTTP 路由(同源)
| 路由 | 方法 | 说明 |
|---|---|---|
/dsh-sync/status | GET | 生效配置 + 可用/预留后端 + 上次同步结果 |
/dsh-sync/run | POST | 立即同步;body { direction: 'export'|'import', dryRun: bool }(重入保护,忙时 409) |
/dsh-sync/config | POST | 写入用户层配置(白名单键:backend/localRoot/excludes/followSymlinks) |
# 预演导入(不改动任何文件,列出将发生的变化)
curl -X POST http://127.0.0.1:3080/dsh-sync/run \
-H 'content-type: application/json' -d '{"direction":"import","dryRun":true}'
目录结构
lib/index.js 宿主半区:schema / 后端注册表 / 同步引擎 / webServer 路由 / settings ns
src/client/index.tsx 客户端源码(TSX → esbuild 打包)
scripts/build.mjs 客户端打包脚本(esbuild,产物提交到 lib/client.js)
assets/logo.svg 插件 logo(双向同步双箭头 + 中心配置点)
cordis.patch.yml.example 注册示例
开发
pnpm install
node scripts/build.mjs # 重新打包 lib/client.js(改客户端后执行)
已知行为
- 活跃会话的
sessions/*/session.jsonl.zstd与storages/*持续写入,每次同步都会重拷——属预期。 - 首次改宿主代码后需重启 DSH 才生效;客户端 bundle 改动刷新页面即可(带 rev 参数)。
- 导入仅在「已用新版本导出过一次」(备份根里存在
.dsh-sync-manifest.json)后才会还原链接;旧备份可直接导入,只是没有链接元数据、按纯文件恢复。
License
MIT