前言¶
DSH 本地部署没有云端存储:会话落在本机 $DSH_HOME/sessions/ 下,换个电脑就接不上。把会话文件拷给同事,附件、工作区路径都不对,还得手动改格式。dsh-github-sync 解决的是这个问题:把 DSH 会话连同引用的附件推到你自己的私有 GitHub 仓库,另一台机器拉下来就能继续聊。它的前提是你有 GitHub 账号和一个私有仓库,它不提供服务器、不提供账号体系。
下面介绍这个插件的定位、安装方式和日常用法。
这是什么¶
一句话定位:一个 DSH 插件,把本地会话与(可选)工作区文件夹同步到私有 GitHub 仓库,用于跨设备接力。
- 名称:
dsh-github-sync,版本 0.5.1,MIT 协议 - 分类:记忆
- 目录页归属:lifeng4127;package.json 中作者字段写作 mount9527,repository 字段指向 mount9527/dsh-github-sync。两者指向同一包名与同一份 README,安装时以仓库搜索结果为准。
- 同步是纯手动的:不点不动,没有后台定时任务
核心功能¶
| 能力 | 说明 |
|---|---|
| 上传会话 | 勾选本地会话推上去,连带它引用的图片等附件;一批文件合成一个原子提交 |
| 下载会话 | 从远端拉回,改写头帧里的 cwd 到本机工作区,并注册进项目列表,不用重启就能继续聊 |
| 上传文件夹 | 默认关闭,设置里开启后可推 <项目>/files/ |
| 下载文件 | 默认关闭,开启后写回工作区,同名冲突另存副本,路径做了防穿越 |
| agent 工具 | 提供 3 个工具,通过自然语言触发,先预览清单再执行 |
几个值得留意的机制,来自 README 的「关键实现」一节:
- 会话在磁盘上就是一个文件
session.v4.jsonl.zstd,所以不需要任何服务端。 - 改写
cwd时只重压第一帧,后面的帧字节原样保留,否则会破坏 append-only 字节链,前缀合并失效。 - 冲突判定只比对头帧之后的 body:一方是另一方的前缀则落后方补上,互不为前缀则分叉,远端另存
*.remote-fork-*。 - 前缀判定不下载远端文件,靠
manifest.json里记录的 body 长度与哈希做本地切片比对(README 给的例子是一条 2MB 会话的预览从 134 秒降到 5 秒)。
仓库结构:
README.md 自动生成的项目/会话索引(每次上传重写)
manifest.json 权威索引:会话 id → 路径、原始 cwd、sha、附件列表
<项目>/sessions/<id>.jsonl.zstd 会话文件本体
<项目>/attachments/<sha>.<ext> 会话引用到的附件
<项目>/files/<相对路径> 文件夹上传的内容
manifest.json 里的原始 cwd 是跨机还原的关键:下载时它会被改写成目标机器的工作区路径。
安装与启用¶
从插件市场安装:在 DSH 的「插件」里搜索 dsh-github-sync,安装后启用即可。
从本地目录安装(开发或自用):打开 DSH →「插件」→ 添加插件 → 本地目录,选这个文件夹;或者由 agent 调用 plugin_manager install_bundle,target 填绝对路径;或者在 profile 的 package.json 里加 "dsh-github-sync": "link:<路径>",并把它加进 dsh.profile.bundles。
装完左侧边栏出现「GitHub 同步」图标,点开是面板。
大陆网络下如果 npm 官方源很慢,用镜像装,注意镜像同步有几分钟到几小时的延迟:
npm install dsh-github-sync --registry=https://registry.npmmirror.com
客户端改动按 F5 刷新页面即可生效;宿主代码改动需要重载插件(重启 DSH,或在插件管理器里关掉再启用)。插件没有原生模块,Windows 和 macOS 跑同一份代码。
典型用法¶
首次配置¶
- 建一个空的私有仓。GitHub 新建仓库,不要勾 README、不要勾 .gitignore,选 Private。README 强调空仓库很重要:首次提交若仓库已有文件会多一次合并。
- 建一个 fine-grained PAT。打开 https://github.com/settings/tokens?type=beta → Generate new token,Repository access 选 Only select repositories 并只勾这一个仓,Contents 给 Read and write(勾选后会自动带上 Metadata Read-only),其它权限全部 No access。令牌只显示一次。
- 面板里填。右上角 ⚙ → 仓库地址(
owner/repo或完整 URL 都行)+ 访问令牌 → 测试连接。成功显示连接正常 · owner/repo;报「仓库是公开的」要去 Settings 改成 Private;401 多半是令牌没粘全,404 是仓库名错或令牌没授权到这个仓。
没连上仓库时,面板顶部会出引导条,点「开始配置」进三步向导,每步带官方页面链接。需要更细的图文步骤(截图位置、常见错误对照、令牌轮换)看仓库里的 TUTORIAL.md。
上传与下载¶
面板分两栏:左边远端仓库,右边本地会话。所有写操作都必须先预览,预览会逐个文件标注 upload / skip / blocked / copy 与原因,确认后才真正执行。被 blocked 远端更新 挡住的行,行尾直接有「先下载」按钮。
每条会话右侧有同步徽标,由本地 body 哈希与远端索引对比得出:
| 徽标 | 含义 |
|---|---|
| 已同步 | 两边内容一致 |
| 本地更新 | 本地多聊了几轮,可以推 |
| 远端更新 | 远端更新过,应先下载 |
| 未上传 | 还没传过 |
| 活跃 | 最近 5 分钟内还在写,推上去的是快照 |
也可以直接用自然语言,插件会调 github_sync_transfer:
"把这条会话推到 GitHub"
"远端都有哪些会话"
"从远端把某某会话拉到这个工作区"
前者先 phase=preview 出清单,确认后再 phase=execute 带同一个 token 执行。
传输过程中有文件级进度条(形如 12/30 · 上传文件 · f12.bin),点左边的 ▸ 能展开看过每个文件 等待 / 传输中 / 完成 / 已跳过。每个还没开始传的文件都有「跳过」按钮,跳过附件会自动从 manifest.json 里摘掉对应引用。取消在文件之间生效,ref 不更新,仓库里不会留下半个提交。传输状态存在宿主进程里,面板切走再回来会自动重新接上进度条,没确认的预览也会恢复。
删除与冲突¶
删除两边互不影响:本机行尾的 🗑 只删本机会话并回收不再被引用的本地附件;远端行尾的 🗑 只删仓库里的会话并回收远端附件。两边都要点两次确认(4 秒内有效)。
两端都动过同一条会话时,预览会标 blocked 并给出三个选择:「先下载」「用本地覆盖远端」「用远端覆盖本地」。选覆盖会直接执行并重新预览。
适用场景与注意¶
适合:两台及以上设备之间接力同一个任务,或把某台机器上的会话交给同事接着干;前提是 GitHub 可达、有私有仓库。不适合:想要自动云端备份、多端实时同步、或者会话需要跨组织权限管理的情况——它完全手动,且每台机器上传前先合并远端索引,所以不会互相覆盖记录,但也意味着它不做实时冲突自动合并。
几点必须留意:
- 插件以当前 DSH 进程权限运行,能写
$DSH_HOME、能访问当前工作区、能访问 GitHub API。安装前应读一遍源码,确认许可证(MIT)与依赖符合你的要求。 - 默认只写四个位置:
$DSH_HOME/github-sync/、$DSH_HOME/sessions/、$DSH_HOME/attachments/v1/objects/、当前工作区(文件夹/文件同步默认关闭,未开启时相关接口直接返回 403)。 - 只允许私有仓,公开仓直接拒绝;
.env*、*.key、*.pem、id_rsa、.npmrc、.netrc等密钥类文件二次确认也传不上。 - token 只存在宿主进程的
$DSH_HOME/.credentials.yaml,面板不回显;README 声明插件不启动子进程、不执行外部命令、不访问 GitHub 以外的域名,这些不变量由tools/audit-safety.mjs静态检查,发布前必跑。 - 仓库会变大且 GitHub 不会自动清理旧 blob。会话在仓库里是固定路径,历史版本只占空间不影响使用;要真回收需要
git clone --mirror后用git filter-repo重写历史,或重建空仓。按 README 的建议,主要用途是接力的话,一个项目一个仓比混在一起好清理。 - 附件按会话引用上传,未被引用的附件不会上传;单个附件超过 25MB 会跳过并在预览里告警。插件只处理
version: 4的会话格式。
结尾¶
dsh-github-sync 的价值很明确:把 DSH 本地会话变成可以跨设备搬运的普通文件,靠一个私有仓库和一串 fine-grained token 完成接力,没有额外的服务端。功能不算多,但上传前先预览、文件级跳过、取消不影响 ref、token 只在宿主进程这几件事,说明作者对「手动操作可能出错」这件事考虑得比较细。如果你本来就用 GitHub 管理私有仓库、也接受手动同步的节奏,可以试试。
目录页:https://www.skillhub.cn/plugins/lifeng4127/dsh-github-sync
GitHub:https://github.com/lifeng4127/dsh-github-sync