把会话日志与插件环境备份到 WebDAV 并恢复
29.9/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/9 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add alfredhuang211/dsh-webdav-sync该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:待复验
是什么
dsh 原生插件 · chat
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 24 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 35 处,展示前 34 条)
- 读取本地文件lib/index.js:51
if (existsSync(pkgPath)) { - 读取本地文件lib/index.js:52
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) - 执行外部命令来自配置/变量lib/index.js:149
const child = spawn(command, args, { - 发起网络请求client/bundle.js:31
var res = await fetch(API + path, init) - 读取本地文件lib/sync.js:85
const buf = await readFile(absPath) - 写入本地文件lib/sync.js:224
await mkdir(dirname(target), { recursive: true }) - 写入本地文件lib/sync.js:225
await writeFile(target, bytes) - 读取本地文件lib/sync.js:280
const buf = local.bytes ?? (await readFile(local.absPath)) - 读取本地文件lib/sync.js:387
const file = await readFile(local.absPath) - 读取本地文件lib/sync.js:438
const file = await readFile(local.absPath) - 读取本地文件lib/sync.js:450
const merged = mergeSelfPatchRow(buf.toString('utf8'), await readFile(target, 'utf8'), SELF_ENTRY_ID) - 写入本地文件lib/sync.js:456
await mkdir(dirname(target), { recursive: true }) - 读取本地文件lib/sync.js:459
await writeFile(`${target}.bak-${stamp}`, await readFile(target)) - 写入本地文件lib/sync.js:459
await writeFile(`${target}.bak-${stamp}`, await readFile(target)) - 写入本地文件lib/sync.js:463
await writeFile(tmp, payload) - 写入本地文件lib/sync.js:464
await rename(tmp, target) - 发起网络请求lib/webdav.js:89
await this.request('PUT', rel, { body: data, headers: { 'content-type': 'application/octet-stream' } }) - 发起网络请求lib/webdav.js:101
const res = await this.request('GET', rel, { expect: [404] }) - 发起网络请求lib/webdav.js:108
const res = await this.request('PROPFIND', rel, { headers: { depth: '1', 'content-type': 'application/xml' }, body: '<?xml version="1.0"?><propfind xm - 发起网络请求lib/webdav.js:130
await this.request('DELETE', rel, { expect: [404] }) - 发起网络请求lib/webdav.js:135
const res = await this.request('PROPFIND', '', { headers: { depth: '0' }, expect: [207, 404] }) - 读取本地文件lib/env.js:72
info = await stat(spec.absPath) - 读取本地文件lib/env.js:78
const bytes = await readFile(spec.absPath) - 读取本地文件lib/env.js:194
return await readFile(path, 'utf8') - 读取本地文件lib/env.js:221
return existsSync(join(profileDir, 'package.json')) && Boolean(home) - 读取本地文件lib/layout.js:62
const stream = createReadStream(absPath).pipe(createZstdDecompress()) - 读取本地文件lib/layout.js:90
projectDirs = await readdir(sessionsRoot, { withFileTypes: true }) - 读取本地文件lib/layout.js:99
sessionDirs = await readdir(projectPath, { withFileTypes: true }) - 读取本地文件lib/layout.js:108
files = await readdir(sessionPath, { withFileTypes: true }) - 读取本地文件lib/layout.js:119
st = await stat(absPath) - 读取本地文件lib/state.js:25
raw = JSON.parse(await readFile(stateFile(stateDir), 'utf8')) - 写入本地文件lib/state.js:55
await mkdir(stateDir, { recursive: true }) - 写入本地文件lib/state.js:58
await writeFile(tmp, `${JSON.stringify(state, null, 2)}\n`, 'utf8') - 写入本地文件lib/state.js:59
await rename(tmp, target)
扫描于 2026/10/31(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/schemastery@deepseek-ai/cordis@deepseek-ai/dsh@deepseek-ai/dsh-settings给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 备份会话日志与插件环境
- 从WebDAV恢复数据
- 版本比较与冲突策略
DeepSeek Harness 插件:把会话日志与插件环境备份到任意 WebDAV 服务,并可从 WebDAV 恢复(会话+环境双源同步、rev/generation 版本机制、三方比较与冲突策略)
README
由 DeepSeek 最新模型翻译生成dsh-webdav-sync
把 DSH 的会话日志和插件环境同步到任意 WebDAV 服务,带版本号 / 时间 / 设备溯源,可增量备份与恢复。零运行时依赖(Node 内置 zstd + fetch),host + 客户端两半齐全,Desktop 与 CLI 都能用。
仓库内的参考实现(v0.2.1),已在真实 dsh 0.2.0-rc.1 的 web profile 上跑通双源同步、版本溯源、冲突处理与强制恢复。
它同步什么
| 源 | 内容 | 说明 |
| 会话 | $DSH_HOME/sessions/*/.jsonl.zstd | 字节级;恢复时按日志头部的 cwd 重算落位目录 |
| 插件环境 | profile 的 package.json、cordis.patch.yml、pnpm-lock.yaml、pnpm-workspace.yaml、$DSH_HOME/cordis.patch.yml(可选)、插件市场状态(可选) | 这些才是"环境真身";node_modules 是可重装的产物,永不同步 |
| 插件清单 | 自动生成的 environment/inventory.json | 每个插件的名称 + 版本 + 启用状态——宿主自带的清单 API 不含版本号,所以版本是插件自己从 node_modules 里读的 |
展开完整文档(README 剩余 1 节)
dsh-webdav-sync
把 DSH 的会话日志和插件环境同步到任意 WebDAV 服务,带版本号 / 时间 / 设备溯源,可增量备份与恢复。零运行时依赖(Node 内置 zstd + fetch),host + 客户端两半齐全,Desktop 与 CLI 都能用。
仓库内的参考实现(v0.2.1),已在真实 dsh 0.2.0-rc.1 的 web profile 上跑通双源同步、版本溯源、冲突处理与强制恢复。
它同步什么
| 源 | 内容 | 说明 |
| 会话 | $DSH_HOME/sessions/*/.jsonl.zstd | 字节级;恢复时按日志头部的 cwd 重算落位目录 |
| 插件环境 | profile 的 package.json、cordis.patch.yml、pnpm-lock.yaml、pnpm-workspace.yaml、$DSH_HOME/cordis.patch.yml(可选)、插件市场状态(可选) | 这些才是"环境真身";node_modules 是可重装的产物,永不同步 |
| 插件清单 | 自动生成的 environment/inventory.json | 每个插件的名称 + 版本 + 启用状态——宿主自带的清单 API 不含版本号,所以版本是插件自己从 node_modules 里读的 |
版本机制:怎么知道哪一份是最新的
远端 manifest.json 是 v2 结构,每个文件都带三层信息:
{
"schema": 2,
"generation": 12, // 整份备份的代号,有变化才 +1 "updatedAt": "2026-09-30T10:12:54.873Z",
"device": { "id": "dev-98597ad2", "label": "sandbox-mac", "platform": "darwin" },
"devices": { "dev-98597ad2": { "label": "sandbox-mac", "lastSeen": "..." } },
"entries": {
"sessions/--Users-me-proj--/sess-x/session.v4.jsonl.zstd": {
"sha1": "…", "size": 12933, "rev": 3, // 逻辑版本号:内容变了才 +1 "updatedAt": "2026-09-30T09:02:08.000Z", // 源文件时间 "device": "dev-98597ad2" // 最后写入者 } } }
判定规则(lib/versioning.js):
1. sha1 相同 → 一致,什么都不做;
2. 本机存有 base(上次同步的共同祖先)时:只有一端变了 → 直接推进那一端,不是冲突;
3. 两端相对 base 都变了 → 冲突,按 conflictPolicy 取舍:
- prefer-newer(默认):先比 rev,再比 updatedAt,最后用 device 字典序收敛(保证两端算出同一结果,不会来回覆盖);
- keep-local / keep-remote / keep-both / manual;
4. 落败的一方默认另存为 .conflict-<设备>-r<版本> 副本,绝不静默丢弃。
安全红线
- push / pull 都不删除本机会话;
- 恢复覆盖的条件是"本机相对 base 没改过"(覆盖不丢东西);本机改过的文件必须显式开启 pullOverwrite 或走「以云端为准」(POST /pull?force=1);
- 环境文件被覆盖前先写 .bak-<时间戳>;
- 运行中的会话不参与覆盖;
- 同步两侧都剥离本插件自身的配置行:否则换机恢复后会把 WebDAV 同步目标改回旧机器;恢复时本机那一行会被保留(换机后你重新填的地址不会被云端旧值抹掉);
- 永不触碰 node_modules。
配置界面(已实测渲染)
设置 → WebDAV 同步,三组表单(连接 / 同步内容 / 版本与冲突)+ 状态面板:
连接 可达本机 sandbox-mac 云端 第 2 代,2026/9/30 18:13:39 由 sandbox-mac 写入,10 个文件差异 待上传 0,待恢复 0,冲突 0,一致 10 插件清单对照:一致
按钮:保存 / 状态/版本 / 测试连接 / 预演 / 立即备份 / 从云端恢复 / 以云端为准 / 安装依赖。
命令行也可用:/webdav-sync push|pull|plan|status|test|install(pull force = 以云端为准)。
环境恢复后的最后一步
恢复 package.json / pnpm-lock.yaml 之后需要重装依赖:
- 界面上点「安装依赖」,或命令 /webdav-sync install;
- 它调用 ctx.profileContext.packageManager(打包版用内置 pnpm、开发版用 PATH 里的 pnpm),在 profile 目录里执行 install;
- 等价手工命令:cd $DSH_HOME/profiles/<profile> && pnpm install。
测试
pnpm install # 只为 @deepseek-ai/schemastery
node --test test/.test.mjs
42 个用例:版本排序与三方比较矩阵、WebDAV 客户端路径与建目录(含 basePath 非空)、全新 state 面对已有云端的 base 落下、nextRev、v1 清单兼容、环境发现与清单版本、自指剥离、冲突各策略、双源端到端、force 恢复、恢复后收敛性(不抖动)、运行中会话跳过、鉴权失败。
目录结构
lib/index.js 入口:name/inject/Config/apply;接 profileContext、路由、命令、定时器、依赖安装 lib/config.js schemastery Config(.volatile() 子树决定哪些字段可被设置页写回)+ 到引擎配置的映射 lib/versioning.js 版本机制核心:compareVersion / decide(三方比较)/ nextRev / manifest v1→v2 归一化 lib/state.js 本机状态:设备 ID、base 三方基准、sha1 缓存 lib/env.js 环境采集:声明文件发现、插件清单(含版本)、patch 解析与自指剥离、清单 diff lib/layout.js 复刻宿主的 encodeSegment / projectKey / 日志识别 / 流式读 header lib/webdav.js 零依赖 WebDAV 客户端(Basic / MKCOL / PUT / GET / PROPFIND / DELETE) lib/sync.js 同步引擎:双源、manifest v2、冲突副本、原子写、force 恢复 lib/routes.js 同源 HTTP 路由(首行过 ctx.connection.requestRejection 信任栅栏) client/bundle.js 浏览器半边:window.__ModuleLoader__ 自注册 + settings.section 表单 test/ 42 个用例
安装
已发布到 npm 后(CLI 的 web / 自定义 profile)
dsh plugin --profile web add dsh-webdav-sync
直接从 GitHub 源码装(pnpm 的 git 协议,会按本地源码构建/链接)
dsh plugin --profile web add github:alfredhuang211/dsh-webdav-sync
Desktop:desktop profile 由 Electron 托管,CLI 拒绝操作,必须走 App 内的插件市场。package.json 已按市场契约声明 engines.dsh 与 @deepseek-ai/ peer。
仓库
源码:<https://github.com/alfredhuang211/dsh-webdav-sync>(MIT)
开发指引与踩坑记录另见上层文档《DSH插件开发指南-WebDAV会话同步.md》,本仓库只放插件本身。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
alfredhuang211/dsh-webdav-sync
把会话日志与插件环境备份到 WebDAV 并恢复
相关插件 · 对话 / 记忆
上下文中枢oceanbase/powercontext
上下文跟着工作走 —— 跨会话、跨智能体、跨人。
★ 1,462已汉化DSH
73
智能体记忆库plastic-labs/honcho
Honcho 是记忆基础设施,用来构建有状态的智能体。这些智能体能理解不断变化的人、智能体、群组、项目和想法。
★ 7,848已汉化DSH
71.7
长程智能体控制面loopx-project/loopx
给 Agent 一个目标,让工作持续向前。
★ 6,358已汉化DSH
71.3
智能体上下文数据库volcengine/OpenViking
给 AI 智能体用的上下文数据库
★ 41,246已汉化DSH
71.3
长效机器人团队Fei2411/DS-Bot
DS Bot 是一个基于 DeepSeek Harness简称 dsh的 bot 插件,插件将 dsh 改造为 bot…
★ 4,717已汉化DSH
71.1
可携带记忆层EverMind-AI/EverOS
为什么选择 EverOS
★ 13,711已汉化DSH
71.1