🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

配置同步 j1kwen/dsh-anywhere-sync

DeepSeek Harness
j1kwen7 天前有提交已提供中文文档扫描:含敏感能力

用私有 Git 仓库在多台电脑间同步配置与插件

29.5/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/11/2 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add j1kwen/dsh-anywhere-sync
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么[目录]—
dsh 原生插件 · market
暂无时间戳·判据 →
装得上吗[实装验证]—
本站尚未做安装检查
暂无时间戳·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]✓
活跃:最近一次提交在 7 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 56 处,展示前 46 条)
  • 发起网络请求
    client.js:416
    response = await fetch(apiPath(path), options)
  • 写入本地文件
    lib/engine.js:99
    mkdirSync(this.runtime.repoDir, { recursive: true })
  • 删除本地文件递归
    lib/engine.js:133
    rmSync(this.runtime.repoDir, { recursive: true, force: true })
  • 读取本地文件
    lib/engine.js:241
    repoReady: existsSync(resolve(this.runtime.repoDir, '.git')),
  • 写入本地文件
    lib/engine.js:278
    mkdirSync(this.runtime.repoDir, { recursive: true })
  • 读取本地文件
    lib/engine.js:420
    .filter(entry => entry.absolute !== null && existsSync(entry.absolute))
  • 读取本地文件
    lib/engine.js:587
    if (existsSync(absolute)) backupFiles(this.runtime, [{ repoPath: path, absolute }])
  • 读取本地文件
    lib/engine.js:729
    manifest = JSON.parse(readFileSync(manifestPath, 'utf8'))
  • 读取本地文件
    lib/engine.js:740
    if (currentDir !== null && existsSync(join(currentDir, 'package.json'))) continue
  • 读取本地文件
    lib/engine.js:742
    if (!existsSync(join(managed, 'package.json'))) continue
  • 写入本地文件
    lib/engine.js:880
    mkdirSync(dirname(absolute), { recursive: true })
  • 写入本地文件
    lib/engine.js:893
    writeFileSync(temporary, buffer, { mode })
  • 写入本地文件
    lib/engine.js:894
    renameSync(temporary, absolute)
  • 删除本地文件
    lib/engine.js:897
    unlinkSync(temporary)
  • 写入本地文件
    lib/engine.js:902
    writeFileSync(absolute, buffer, { mode })
  • 删除本地文件
    lib/engine.js:911
    unlinkSync(absolute)
  • 删除本地文件递归
    lib/engine.js:960
    rmSync(join(runtime.backupDir, name), { recursive: true, force: true })
  • 执行外部命令来自配置/变量
    lib/engine.js:1000
    child = spawn(command, args, {
  • 读取本地文件
    lib/paths.js:30
    if (existsSync(candidate)) return candidate
  • 读取本地文件
    lib/items.js:70
    entries = readdirSync(root, { withFileTypes: true })
  • 读取本地文件
    lib/items.js:88
    const stat = lstatSync(absolute)
  • 读取本地文件
    lib/items.js:93
    const raw = readFileSync(absolute)
  • 读取本地文件
    lib/items.js:234
    manifest = JSON.parse(readFileSync(join(runtime.profileDir, 'package.json'), 'utf8'))
  • 读取本地文件
    lib/items.js:245
    if (directory !== null && existsSync(join(directory, 'package.json'))) directories.set(name, directory)
  • 读取本地文件
    lib/items.js:250
    for (const entry of readdirSync(managedRoot, { withFileTypes: true })) {
  • 执行外部命令固定命令
    lib/git.js:34
    execFile('git', ['--version'], { timeout: 10_000, windowsHide: true }, (error, stdout) => {
  • 执行外部命令固定命令
    lib/git.js:70
    child = execFile('git', [...prefix, ...args], {
  • 读取本地文件
    lib/git.js:71
    cwd: existsSync(runtime.repoDir) ? runtime.repoDir : undefined,
  • 写入本地文件
    lib/git.js:96
    mkdirSync(runtime.syncDir, { recursive: true })
  • 写入本地文件
    lib/git.js:97
    mkdirSync(runtime.emptyHooksDir, { recursive: true })
  • 读取本地文件
    lib/git.js:100
    current = readFileSync(runtime.askpassPath, 'utf8')
  • 写入本地文件
    lib/git.js:108
    writeFileSync(runtime.askpassPath, ASKPASS_SCRIPT, { mode: 0o700 })
  • 写入本地文件
    lib/git.js:110
    chmodSync(runtime.askpassPath, 0o700)
  • 写入本地文件
    lib/git.js:228
    mkdirSync(runtime.repoDir, { recursive: true })
  • 写入本地文件
    lib/git.js:229
    mkdirSync(runtime.emptyHooksDir, { recursive: true })
  • 读取本地文件
    lib/git.js:231
    if (!existsSync(resolve(runtime.repoDir, '.git'))) {
  • 读取本地文件
    lib/git.js:322
    return typeof directory === 'string' && isAbsolute(directory) && existsSync(resolve(directory, '.git'))
  • 请求外部主机api.github.com
    lib/github.js:31
    response = await fetch(`https://api.github.com/repos/${target.owner}/${target.repo}`, {
  • 发起网络请求
    lib/github.js:31
    response = await fetch(`https://api.github.com/repos/${target.owner}/${target.repo}`, {
  • 读取本地文件
    lib/store.js:52
    return JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    lib/store.js:60
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    lib/store.js:62
    writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 })
  • 写入本地文件
    lib/store.js:64
    chmodSync(temporary, 0o600)
  • 写入本地文件
    lib/store.js:68
    renameSync(temporary, path)
  • 写入本地文件
    lib/store.js:133
    mkdirSync(runtime.syncDir, { recursive: true })
  • 读取本地文件
    lib/store.js:150
    if (existsSync(this.runtime.credentialsPath)) writeJsonSecure(this.runtime.credentialsPath, { token: '' })
扫描于 2026/11/4(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
涉及外部主机:api.github.com

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

通过私有 Git 仓库在多台机器之间同步 Harness 配置档、插件清单、插件设置和本地插件源码。

README

由 DeepSeek 最新模型翻译生成
Anywhere Sync · 配置同步 Anywhere Sync 用一个私有 Git 仓库在多台电脑之间共享 Harness 的 profile 配置、插件清单、插件设置、依赖锁、本地插件源码与技能。每一类内容都可以单独开关;一台机器修改后,其他机器在下一次同步时生效。 English README 设置入口:设置 → 配置同步(settings.section)。 安装 要求:带 Web UI 的 DeepSeek Harness、Node.js 20+、本机有 git。 dsh plugin --profile desktop add j1kwen/dsh-anywhere-sync 安装后重启 Harness,打开 设置 → 配置同步。 也可以从本地目录或 Release 的 tarball 安装: dsh plugin --profile desktop add /path/to/dsh-anywhere-sync 或在插件管理器中选择最新 Release 的 dsh-anywhere-sync.tgz 仓库声明了 dsh.bundle 和 cordis.patch.yml,因此可以作为一个 bundle 安装。
展开完整文档(README 剩余 1 节)
Anywhere Sync · 配置同步

Anywhere Sync

用一个私有 Git 仓库在多台电脑之间共享 Harness 的 profile 配置、插件清单、插件设置、依赖锁、本地插件源码与技能。每一类内容都可以单独开关;一台机器修改后,其他机器在下一次同步时生效。

English README

设置入口:设置 → 配置同步(settings.section)。

安装

要求:带 Web UI 的 DeepSeek Harness、Node.js 20+、本机有 git。

dsh plugin --profile desktop add j1kwen/dsh-anywhere-sync

安装后重启 Harness,打开 设置 → 配置同步。

也可以从本地目录或 Release 的 tarball 安装:

dsh plugin --profile desktop add /path/to/dsh-anywhere-sync
或在插件管理器中选择最新 Release 的 dsh-anywhere-sync.tgz

仓库声明了 dsh.bundle 和 cordis.patch.yml,因此可以作为一个 bundle 安装。

同步项

| 项目 | 本机来源 | 仓库路径 | 默认 |
| 插件清单 | <profile>/package.json | profile/<profile>/package.json | 开 |
| 本地插件源码 | link: / file: / 绝对路径依赖的插件目录 | local-plugins/<包名>/… | 开 |
| 插件配置 | <profile>/cordis.patch.yml | profile/<profile>/cordis.patch.yml | 开 |
| 插件数据 | 设置页列出的 $DSH_HOME 下文件 | plugin-data/<路径> | 开 |
| 依赖锁文件 | <profile>/pnpm-lock.yaml、pnpm-workspace.yaml | 同左 | 开 |
| 其他 profile 文件 | profile 目录中的其余配置文件(预设、config.toml 等) | profile/<profile>/… | 关 |
| 技能 | ~/.agents/skills/、~/.agents/.skill-lock.json | skills/… | 关 |

关闭的项目在两边都不会被读取、写入或删除。疑似密钥的文件(.env、credential、secret、id_rsa、.pem、.npmrc、config.toml 等)即使开启“其他 profile 文件”也会被排除。

本机路径不会外传。 package.json 与 pnpm-lock.yaml 在同步前会被投影成“可移植形式”:link:、file:、workspace: 以及绝对路径依赖(包括本插件自己的 link: 安装)不会写进仓库,对应的 bundle 条目也会一并移除。拉到远端清单时采用合并而不是覆盖,各机器保留自己的本地链接。换机器后第一次安装依赖时,包管理器会按本机清单把链接条目补回锁文件。

“本地插件源码”会读取 profile 里 link:/file:/绝对路径依赖的插件目录(本插件自身除外),把代码(不含 node_modules、.git、疑似密钥文件)放到仓库的 local-plugins/<包名>/。拉取时:

- 本机已经有这个本地依赖 → 直接写回它的源目录;
- 本机没有 → 写入 $DSH_HOME/anywhere-sync/local-plugins/<包名>,并自动在 profile 清单里加上 link: 依赖,随后安装依赖;需要启用为 Harness 插件时,在插件页把对应的 bundle 打开一次(插件本体的 bundle 在首次安装时就已经存在);
- 插件代码更新后需要重启 Harness 才会加载。

本插件自身默认不参与“本地插件源码”同步。 它的源码不会进入共享仓库,因此本机的开发版不会覆盖另一台机器上从 GitHub 安装的版本;本插件的设置保存在 $DSH_HOME/anywhere-sync,不在 profile 里,也不会被同步。需要刻意同步本插件源码时,可在 设置 → 配置同步 → 不同步本插件自身 关闭该开关。

新机器仍需先安装一次本插件,才能进入设置页完成首次同步。

插件数据

有些插件不把设置放在 cordis.patch.yml,而是放在 $DSH_HOME 下的文件里。开启“插件数据”后,设置页列出的文件或目录会同步到仓库的 plugin-data/<路径>。

默认包含 dsh-whale-widget 的 .dshw-size.json(外观/开关)、.dshw-bubble.json(泡泡布局)和 .dshw-api.json(自定义模型注册表)。它的账本 .dshw-usage.json、每轮 seq 和统计缓存不在默认列表:这些是数据而不是配置,整文件同步会把不同机器的账本混在一起。其它插件的配置路径可在设置页添加;路径必须以 / 结尾表示目录,且只能是 $DSH_HOME 下的相对路径。凭据、会话、存储目录和本插件自己的状态会被拒绝。

开始使用

1. 在 GitHub 创建一个私有仓库(可以勾选 “Add a README” 初始化 main 分支)。
2. 创建 Personal Access Token(classic 的 repo scope,或 fine-grained 的 Contents: Read and write)。界面里的“创建 GitHub 令牌”按钮会打开对应页面。
3. 打开 设置 → 配置同步,填写仓库地址(owner/repo 或 https://github.com/owner/repo)、分支和令牌,点 保存并连接。
4. 点 立即同步。第一次同步后,在另一台机器安装本插件并重复第 3 步即可拉取同一套配置。
5. 打开 定时同步(默认 15 分钟)或 启动时同步,让“一处修改,多处生效”自动完成。

拉取到新的插件清单或锁文件后,页面会提示安装依赖;默认会自动在 profile 中运行包管理器。插件代码本身要在 Harness 重启后才会加载。

冲突与数据安全

- 每次写盘前把将被覆盖的文件复制到 $DSH_HOME/anywhere-sync/backups/<时间戳>/,只保留最近 10 份。
- 同步基于三方比较(本机 / 远端 / 上次同步的哈希),只有真正“两边都改过”的同一文件才算冲突。
- 冲突策略:远端优先(默认,适合新机器并入共享配置)、本地优先、保留冲突(在页面逐个选择保留哪一边)。
- 每次推送只 git add 本次实际修改的路径,仓库里其他 profile 或其他工具的文件不会被碰。
- 推送前先 fetch;如果远端在同步期间又前进,会重新计算并重试一次,绝不 force push。
- 删除会传播:本机删除一个已同步的文件,下一次同步会从仓库删除它(反向同理)。

从旧同步工具迁移

本插件不读取、也不修改 ~/.dsh/dsh-sync 里的配置或令牌(那是别的工具的数据)。如果你之前用过其它同步工具,建议新建一个私有仓库:旧工具通常把文件放在 plugins/<profile>/,本插件使用 profile/<profile>/,混在同一个仓库里会出现两套目录。首次接入前先确认“冲突处理”策略,再点“立即同步”。

安全边界

- 令牌只保存在 $DSH_HOME/anywhere-sync/credentials.json(权限 0600),通过 GIT_ASKPASS 临时环境变量交给 git,不写入仓库、不写进 URL、不返回给浏览器。
- 也可以通过环境变量提供令牌(按优先级):ANYWHERE_SYNC_TOKEN、GH_TOKEN、GITHUB_TOKEN。
- HTTP 接口挂在 /anywhere-sync/api,复用 Harness Connection 的 Host/Origin 与登录校验;没有该服务时只接受 loopback。修改类请求还要求同源 Origin。
- 插件不读取、不同步 ~/.dsh/.credentials.yaml、会话记录或工作区文件。
- 需要本机安装 git;依赖安装优先使用启动器发布的包管理器,否则使用 PATH 上的 pnpm。
- 面向 macOS / Linux / Windows;CI 在 Linux + Node 20/22 上运行离线引擎与 HTTP 测试,Windows 路径处理使用 Node 的 path API,但未经 CI 覆盖。
- 没有遥测、统计或除配置的 Git 远端之外的外发请求。

工作方式

fetch origin <branch> → reset --hard(本地镜像 = 远端真相) ↓ 逐文件三方比较 hash(local) / hash(remote) / hash(base) ├─ 只有本地变 → 写入镜像,commit,push ├─ 只有远端变 → 写入本机(先备份) └─ 两边都变 → 按策略处理,或列为冲突 ↓ 更新 base 哈希

状态在 $DSH_HOME/anywhere-sync/state.json,配置在 config.json,仓库镜像在 repo/。当前同步的 profile 就是插件所在的那个 profile,界面会显示 profile 名。

智能体工具

插件同时注册 anywhere_sync 工具,参数 action 为 status / sync / pull / push / install。它调用与界面完全相同的 Host 实现,不能修改仓库地址、同步项或读取令牌。

自测

npm run verify

两个脚本不依赖 Harness,也不访问网络:

node scripts/engine-test.mjs # 本地裸仓库:推送/拉取/冲突/删除/多机器/本地链接投影/本地插件源码注册
node scripts/http-test.mjs # HTTP 路由:鉴权、参数校验、启动与轮询

GitHub Actions 在每次 push 和 PR 上运行同样的检查(Node 20/22)。

发布与签名

- Release 由 GitHub Actions 从签名的 tag 构建,发布 dsh-anywhere-sync.tgz 与 SHA256SUMS;
- tarball 带 Sigstore build provenance,校验和文件带 keyless Sigstore 签名(SHA256SUMS.sigstore.json):

sha256sum -c SHA256SUMS
gh attestation verify dsh-anywhere-sync.tgz --repo j1kwen/dsh-anywhere-sync
cosign verify-blob --bundle SHA256SUMS.sigstore.json \
--certificate-identity-regexp 'https://github.com/j1kwen/dsh-anywhere-sync/.github/workflows/release.yml@refs/tags/.' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
SHA256SUMS

- 提交和 tag 使用维护者注册的 SSH signing key 签名,GitHub 会显示 Verified。

排障

如果安装后 设置 → 配置同步 是空白:

1. 重启 Harness。Client bundle 在启动时缓存;在 Harness 运行时从 Git 地址安装插件,浏览器端可能尚未加载。
2. 升级到 1.2.3 或更高版本。渲染错误现在会显示在页面上(含堆栈),而不是留下空白;浏览器控制台也会打印已加载的客户端版本。
3. 如果仍然报错,请把页面上的错误、浏览器控制台输出和 Harness 版本一起反馈。

已知限制

- 只同步“文本文件”,单文件上限 5 MiB;超限文件会跳过并在状态里报告。
- 不安装/卸载插件包本身,只同步清单与锁文件,然后调用包管理器。
- 新拉取的本地插件只注册依赖,不自动启用 bundle(避免在包尚未安装时挂载导致启动失败)。
- profileFiles 与 skills 默认关闭;确认可以离开本机后再开启。
- 不处理 git 子模块、LFS 或仓库历史清理。
- 无浏览器自动化时,页面的视觉验证需要人工在浅色/深色主题下各看一次;接口、同步引擎与槽位注册已自动验证。

许可证

MIT — 见 LICENSE。
预览分享卡片长什么样 ↓j1kwen/dsh-anywhere-sync
分享 · DeepSeek Harness Hub
j1kwen/dsh-anywhere-sync

用私有 Git 仓库在多台电脑间同步配置与插件

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部