用 WebDAV 跨设备同步配置与密钥,随时预览恢复历史备份
29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/23 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add jeweis/dsh-sync该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:仅索引
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 41 处,展示前 40 条)
- 读取本地文件src/files.mjs:18
const info = await lstat(current) - 删除本地文件src/files.mjs:53
if (content === null) { try { await unlink(target) } catch (error) { if (error.code !== 'ENOENT') throw error }; return } - 写入本地文件src/files.mjs:54
await mkdir(dirname(target), { recursive: true, mode: 0o700 }) - 写入本地文件src/files.mjs:61
await rename(temporary, target) - 删除本地文件src/files.mjs:64
await unlink(temporary).catch(error => { if (error.code !== 'ENOENT') throw error }) - 读取本地文件src/settings.mjs:54
try { entries = await readdir(await safePath(home, 'profiles'), { withFileTypes: true }) } - 发起网络请求src/webdav.mjs:28
const req = client.request(url, { method, signal: combined, headers: { Authorization: this.authorization, ...body ? { 'Content-Length': body.length } - 发起网络请求src/webdav.mjs:50
const result = await this.request('PROPFIND', url, { body, signal, stage, headers: { Depth: '0', 'Content-Type': 'application/xml; charset=utf-8' }, l - 发起网络请求src/webdav.mjs:85
const result = await this.request('MKCOL', directory, { signal, limit: 65536 }) - 发起网络请求src/webdav.mjs:97
const result = await this.request('PUT', this.object(id), { body: bytes, signal, headers: { 'Content-Type': 'application/octet-stream', 'If-None-Match - 发起网络请求src/webdav.mjs:106
const result = await this.request('GET', this.object(id), { signal }) - 发起网络请求src/webdav.mjs:113
const result = await this.request('DELETE', this.object(id), { signal, headers: { 'If-Match': etag }, limit: 65536 }) - 写入本地文件src/retention.mjs:24
await mkdir(await safePath(home, 'config-vault'), { recursive: true, mode: 0o700 }) - 删除本地文件src/retention.mjs:54
if (await readManaged(home, path) === raw) await unlink(await safePath(home, path)).catch(error => { if (error.code !== 'ENOENT') throw error }) - 删除本地文件src/retention.mjs:61
if (raw && JSON.parse(raw).token === token) await unlink(await safePath(home, path)) - 读取本地文件src/retention.mjs:92
const entries = await readdir(await safePath(home, dir), { withFileTypes: true }) - 写入本地文件src/restore.mjs:36
await mkdir(await safePath(home, 'config-vault'), { recursive: true, mode: 0o700 }) - 读取本地文件src/restore.mjs:41
const saved = JSON.parse(await readFile(await safePath(home, LOCK), 'utf8')) - 删除本地文件src/restore.mjs:45
await unlink(await safePath(home, LOCK)) - 删除本地文件src/restore.mjs:49
return () => unlink(resolve(home, LOCK)) - 读取本地文件src/provider-transition.mjs:15
const PACKAGE = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8')).name - 读取本地文件src/provider-transition.mjs:36
const bytes = await readFile(path) - 读取本地文件src/provider-transition.mjs:86
const directories = await readdir(await safePath(home, 'profiles'), { withFileTypes: true }), profiles = [] - 读取本地文件src/provider-transition.mjs:120
const ownInfo=JSON.parse(await readFile(new URL('../package.json',import.meta.url),'utf8')) - 读取本地文件src/provider-transition.mjs:123
inputs.push(['provider-module', module, hash(await readFile(module))]) - 写入本地文件src/auto-backup.mjs:19
await mkdir(await safePath(home, 'config-vault'), { recursive: true, mode: 0o700 }) - 删除本地文件src/auto-backup.mjs:33
if (await readManaged(home, LOCK) === raw) await unlink(path).catch(error => { if (error.code !== 'ENOENT') throw error }) - 删除本地文件src/auto-backup.mjs:40
if (raw && JSON.parse(raw).token === token) await unlink(path) - 写入本地文件src/sync-lock.mjs:6
await mkdir(await safePath(home, 'config-vault'), { recursive: true, mode: 0o700 }) - 删除本地文件src/sync-lock.mjs:18
if (await readManaged(home, relative) === raw) await unlink(path).catch(error => { if (error.code !== 'ENOENT') throw error }) - 删除本地文件src/sync-lock.mjs:22
return async () => { const raw = await readManaged(home, relative); if (raw && JSON.parse(raw).token === token) await unlink(path) } - 发起网络请求src/sync-remote.mjs:12
const result = await this.dav.request('GET', url, { signal, limit: 1048576 }) - 发起网络请求src/sync-remote.mjs:20
const result = await this.dav.request('PUT', url, { body: bytes, signal, limit: 65536, headers: { 'Content-Type': 'application/octet-stream', ...etag - 发起网络请求src/sync-remote.mjs:34
const result = await this.dav.request('PUT', url, { body: Buffer.from('must not replace'), headers, signal, limit: 65536 }) - 发起网络请求src/sync-remote.mjs:42
if (latest) await this.dav.request('DELETE', url, { headers: { 'If-Match': latest.etag }, signal, limit: 65536 }).catch(() => {}) - 发起网络请求src/client/controller.cjs:26
constructor(fetcher = (...args) => fetch(...args)) { - 发起网络请求src/client/controller.cjs:41
async read() { const host = await this.request('GET'); if (!validState(host)) throw new Error('operation-failed'); return host } - 发起网络请求src/client/controller.cjs:59
const value = await this.request('POST', { ...payload, action, revision: before.host.revision }) - 发起网络请求src/client/controller.cjs:72
try { const answer = await this.request('POST', { action: 'list', revision: value.state.revision }); if (!Array.isArray(answer.snapshots) || !answer.s - 写入剪贴板src/client/recovery-view.cjs:58
button(t('recoveryCopy'),false,async()=>{try{await navigator.clipboard.writeText(command);setCopyResult('recoveryCopied')}catch{setCopyResult('recover
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-include@deepseek-ai/dsh-client-connection@deepseek-ai/dsh-client-store@deepseek-ai/dsh-credentials-local@deepseek-ai/dsh-launch-environment@deepseek-ai/dsh-system-prompt@deepseek-ai/dsh-tools给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
DeepSeek Harness 同步与备份插件:通过 WebDAV 同步常用配置和 API Key,自动备份,并可预览、恢复历史配置。
README
由 DeepSeek 最新模型翻译生成DSH Sync · 同步与备份
DeepSeek Harness 的跨设备配置同步与备份插件。用你自己的 WebDAV 存储同步常用配置、保留历史快照,需要时预览并恢复。
适用于 DeepSeek Harness 0.2.1-rc.2。目前支持 WebDAV,暂不支持 S3、GitHub 存储。
快速开始
1. 在 DeepSeek Harness 中打开 插件管理,点击 添加插件。
2. 在「输入插件的包名、GitHub 仓库地址或本地目录路径」输入框中,填写下面任意一种:
npm 包名(推荐):
@jeweis/dsh-sync
GitHub 仓库地址:
https://github.com/jeweis/dsh-sync
3. 点击 安装。安装完成后,在 已安装插件 中打开 同步与备份 右侧的启用开关。npm 包名使用所选安装源;刚发布的包若在镜像源找不到,可切换为 npm 官方源。GitHub 安装需要能访问 GitHub,并按 Harness 提示授权源码构建。
在哪里使用
安装并启用后,点击 DeepSeek Harness 左下角 更多 → 设置 → 同步与备份。
页面分为 连接存储、同步到其他设备、备份与恢复 三个页签,每次只显示一项任务。可以连接 WebDAV、选择同步内容、开启自动备份、查看备份记录和恢复预览。
展开完整文档(README 剩余 1 节)
DSH Sync · 同步与备份 DeepSeek Harness 的跨设备配置同步与备份插件。用你自己的 WebDAV 存储同步常用配置、保留历史快照,需要时预览并恢复。 适用于 DeepSeek Harness 0.2.1-rc.2。目前支持 WebDAV,暂不支持 S3、GitHub 存储。 快速开始 1. 在 DeepSeek Harness 中打开 插件管理,点击 添加插件。 2. 在「输入插件的包名、GitHub 仓库地址或本地目录路径」输入框中,填写下面任意一种: npm 包名(推荐): @jeweis/dsh-sync GitHub 仓库地址: https://github.com/jeweis/dsh-sync 3. 点击 安装。安装完成后,在 已安装插件 中打开 同步与备份 右侧的启用开关。npm 包名使用所选安装源;刚发布的包若在镜像源找不到,可切换为 npm 官方源。GitHub 安装需要能访问 GitHub,并按 Harness 提示授权源码构建。 在哪里使用 安装并启用后,点击 DeepSeek Harness 左下角 更多 → 设置 → 同步与备份。 页面分为 连接存储、同步到其他设备、备份与恢复 三个页签,每次只显示一项任务。可以连接 WebDAV、选择同步内容、开启自动备份、查看备份记录和恢复预览。超时、检查间隔等参数放在各部分的「更多设置」中,通常不用调整。无需编辑 YAML,也无需先运行终端命令;只有凭据扩展接入/回退与完整恢复需要按页面指引离线确认。 插件安装完成后,跨设备同步、API Key 同步和自动备份均需自行开启。 连接两台设备 在两台设备上分别安装插件,然后: 1. 在 连接存储 填写相同的 WebDAV 文件夹地址,然后开启 同步到其他设备 → 开启自动同步。 2. 在 选择同步内容 中选择需要的项目,点击 保存设置。「更多同步设置」中的 同步分组 通常保留 default,两台设备一致即可。 3. 在「同步状态」输入相同的 两台设备共用的同步口令,点击 解锁并检查更新。口令须为 12–1024 个字符,且与 WebDAV 密码不同。 4. 首次连接时核对差异:第一台设备点击 使用本机设置开始同步;新设备点击 接收云端设置。也可展开逐项比较;本机独有内容会保留。 之后默认每 3 分钟核对一次,也可手动点击「立即同步」。两台设备同时修改同一项时会提示选择,不会直接以最后上传者覆盖另一端。 | 内容 | 当前支持方式 | | 主题、字体、字号和界面语言 | 支持的字段可自动同步并在线生效 | | 默认模型及部分 DeepSeek 参数 | 支持的字段可自动同步并在线生效 | | 供应商 API Key | 单独开启,仅加密同步,接收方式见下文 | | 插件清单 | 显示差异,需要在 Harness 中手动安装或移除 | 同步作用于当前运行的配置(如 web 或 desktop),与「要备份的配置」独立选择。不同用途的配置请使用不同同步分组。会话、附件、OAuth 登录状态、MCP/技能文件和任意第三方插件配置不在当前同步范围内。 API Key 不想重复填写? 在两台设备分别开启 同时同步 API Key。支持 DeepSeek 与 pi-ai 中已绑定的 API Key;两端需先有对应的供应商配置,插件不会自动创建供应商。 - 受支持的 Key 记录:可自动双向同步。 - 引用型 Key(如供应商使用 DEEPSEEK_API_KEY):默认只加密上传,接收端提示在 Harness 手动配置。要让新设备自动接收、避免重复填写,请在 更多同步设置 → API Key 自动接收设置 中预览接入。 高级接入先预览变更,再按页面指引停止共享凭据存储的全部 Harness 进程,在终端确认切换并重启。退出仅发生在接入、回退或完整恢复时,日常同步和备份无需退出。 接入可安全回退,并保留接入后更新的 Key。步骤见 API Key 自动接收指南。 API Key 同步默认关闭,始终加密,不受备份加密开关影响。页面不显示 Key;缺失的 Key 不会清空另一台设备的 Key。 历史备份 在 备份与恢复 点击 立即备份,输入加密口令后点击 开始备份。要调整配置范围、保留份数或加密方式,展开 更多备份设置。备份包含插件依赖清单、profile 配置补丁及存在的锁文件,不包含凭据文件、会话、附件或已安装的 node_modules。 - 自动备份:可开启配置变更后自动备份;默认等配置稳定 30 秒,两次尝试至少间隔 5 分钟。 - 保留数量:默认保留本设备最近 30 份。仅在新备份校验成功后清理本设备有归属记录的旧快照,不清理其他设备快照。 - 加密:默认开启。可明确选择明文备份,但配置里直接填写的秘密值也会随文件明文保存。 加密口令需自行妥善保管,丢失后无法恢复加密数据。手动操作不保存口令;自动备份和同步的解锁仅对当前 Harness 进程有效,重启后需要重新解锁。 在新设备上恢复 1. 在新设备安装并启用插件,连接与旧设备相同的 WebDAV 文件夹,点击 保存设置。页面会查找已有备份。 2. 在 备份与恢复 点击 恢复备份,选择备份,输入这份备份的加密口令,再点击 检查并预览恢复。 3. 核对恢复内容;备份含多份配置时,选择其中一份。它将恢复到当前运行的配置,例如将旧设备的 desktop 配置带到新设备的 desktop。默认保留新设备已安装的插件版本和额外插件;所选配置的插件设置会被替换。 4. 若缺少插件,可点击 检查 npm 版本。核对名称和版本后,点击 确认安装此版本,由 Harness 安装,再重新检查。旧设备的本地插件需要先在新设备安装可信副本;不能把旧路径直接带过来。构建授权仍遵循 Harness 提示。 5. 检查通过后点击 生成离线恢复步骤,然后 复制恢复命令。此时只在本机加密暂存恢复任务,尚未替换配置文件。 6. 退出使用该配置位置的全部 Harness 窗口和后台进程,在系统终端运行复制的命令。输入口令(不会回显),核对变化并输入 确认恢复,再重新打开 Harness 检查。 只需运行一条命令,无需设置环境变量、复制确认码或再次连接 WebDAV。终端会重新检查文件;若准备后配置又有修改,会停止并要求重新预览。恢复前会保留加密回退副本。 新设备向导不会导入旧设备的锁文件、安装脚本、包管理策略或全局配置补丁,会保留本机启动方式。它恢复配置与插件清单,不包含聊天记录或凭据文件。API Key 仍通过独立、默认关闭的加密同步功能接收,不会因恢复备份而自动开启。 如需逐文件原样还原,在 恢复备份 向导中展开 高级:原样还原配置文件。这里仍使用原来的预览、确认码和离线 CLI 流程。这里的「离线」指停止相关 Harness 进程,不是断开网络。回退和中断处理见 恢复说明。 常见问题 测试连接成功,为什么备份失败? 测试只确认目录读取情况,写入和创建子目录还需要额外权限。填写 WebDAV 对外的共享目录路径,勿直接使用 NAS 内部磁盘路径;缺失目录会在备份时尝试逐级创建。 关闭设置页后还会同步吗? Harness 进程仍运行时会继续;退出 Harness 后停止,不会创建系统登录启动项。 能使用 HTTP 吗? 支持 HTTP 和 HTTPS。HTTP 会暴露连接上的 WebDAV 用户名和密码,优先使用 HTTPS。数据加密不等于连接加密。 同步为什么暂停? 先查看是否需要解锁、首次比较或处理冲突。设备同步要求 WebDAV 支持强 ETag 和条件写;不支持时仍可使用普通备份。 更多说明 - 双设备同步与支持范围 - 自动备份 · 快照保留策略 - 版本兼容与改名说明 · 品牌与数据兼容 - 开发、CLI 与验收说明 · 维护者发布流程 问题反馈:GitHub Issues。
预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
jeweis/dsh-sync
用 WebDAV 跨设备同步配置与密钥,随时预览恢复历史备份
相关插件 · 工具 / 效率
破甲管控台kingcharleslzy-ai/dsh-purge
dsh-purge Community · DeepSeek Harness 社区维护版:宿主兼容、状态诊断、提示词管理、更新与本机备份回滚。基于小杨 / YuJunZhiXue 的 dsh-purge。
★ 4,330已汉化DeepSeek 客户端
74.5
网文长卷lingfengQAQ/webnovel-writer
基于 Claude Code 的长篇网文辅助创作系统,解决 AI 写作中的「遗忘」和「幻觉」问题,支持 200…
★ 7,826已汉化DSH
72.2
花束设计alchaincyf/huashu-design
一句话生成网页、原型、PPT 与信息图等可交付设计
★ 28,638已汉化DSH
71.7
多智能体协作HKUDS/AutoSwarm
AutoSwarm: Unify Your Agents. Unify Your Context (Codex · Claude Code · DeepSeek Harness · Muse · Grok · WorkBuddy· nanobot · and more)
★ 2,349已汉化DSH
71.6
Vox 拼贴视频生成Alisa0808/vox-director
🎬 Vox Director拼贴动效导演
★ 2,129已汉化DSH
71.4
Agent 演化引擎Q00/ouroboros
智能体 OS:智能体自己变聪明,我们只守住底线:面试准入、分阶段评估、带预算的进化循环。MCP 服务器,14 种运行时:Claude Code、Codex CLI、Gemini CLI、OpenCode、Copilot、Kiro 等。
★ 6,311已汉化DSH
71.4
这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。