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

远程工作区同步 go-enols/dsh-remote-workspace-sync

DeepSeek Harness
go-enols10 天前有提交已提供中文文档扫描:无法判定

通过 SSH 对比并同步本地与远程文件夹

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:仅索引
是什么
dsh 原生插件 · dev
装得上吗
本站尚未做安装检查
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 10 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
⚪ 扫描:无法判定尚无人工评估
展开查看扫描说明与证据 ↓

已尝试扫描但取不到可分析的源码:仓库或包不存在、已删除,或为非 JS/TS 实现、未随包发布源码。无法判定,不代表安全。

  • · 取源不可用(Error: github tarball HTTP 404 @ https:
  • · api.github.com
  • · repos
  • · go-enols
  • · dsh-remote-workspace-sync
  • · tarball)
扫描于 2026/10/31(1 天前)

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

DeepSeek Harness 插件:SSH 远程工作区同步,支持逐文件合并解决冲突、智能体工具,以及基于 find 的快速比对。

README

由 DeepSeek 最新模型翻译生成
远程工作区同步(Remote Workspace Sync) 一个 DeepSeek Harness(DSH)插件:把本地工作区通过 SSH 连接到远程服务器文件夹,支持对比、手动/自动同步,并把这些能力和远程文件/命令操作暴露给 AI。 - 当前版本:v1.1.0(变更见 CHANGELOG.md) - GitHub: <https://github.com/go-enols/dsh-remote-workspace-sync> - 安装后的 bundle 名为 dsh-remote-workspace-sync;唯一的运行时依赖 ssh2 由 DSH 插件管理器在 GitHub 安装时安装,本地克隆安装需先自行安装依赖(见「安装 / 升级 / 回滚」)。 前置条件与兼容性 | 项目 | 要求 | | DSH | 已在 DSH 0.2.1-rc.2(profile desktop,Web GUI)上验证。插件使用 Host 插件 API,DSH 升级可能改变 API;升级 DSH 后若插件报加载/API 错误,请回滚到已验证的插件版本 | | 界面 | 仅验证 Web 版 GUI。
展开完整文档(README 剩余 1 节)
远程工作区同步(Remote Workspace Sync)

一个 DeepSeek Harness(DSH)插件:把本地工作区通过 SSH 连接到远程服务器文件夹,支持对比、手动/自动同步,并把这些能力和远程文件/命令操作暴露给 AI。

- 当前版本:v1.1.0(变更见 CHANGELOG.md)
- GitHub: <https://github.com/go-enols/dsh-remote-workspace-sync>
- 安装后的 bundle 名为 dsh-remote-workspace-sync;唯一的运行时依赖 ssh2 由 DSH 插件管理器在 GitHub 安装时安装,本地克隆安装需先自行安装依赖(见「安装 / 升级 / 回滚」)。

前置条件与兼容性

| 项目 | 要求 |
| DSH | 已在 DSH 0.2.1-rc.2(profile desktop,Web GUI)上验证。插件使用 Host 插件 API,DSH 升级可能改变 API;升级 DSH 后若插件报加载/API 错误,请回滚到已验证的插件版本 |
| 界面 | 仅验证 Web 版 GUI。Electron file:// 桌面外壳的 IPC 传输未适配 |
| Node.js | 开发与测试需要 Node ≥ 20(package.json 的 engines.node 已声明);插件运行时使用 DSH Host 自带的 Node |
| 依赖 | 仅 ssh2(纯 JS,可用 --ignore-scripts 安装,无原生编译);v1.1.0 未新增任何运行时依赖或构建步骤 |
| 网络 | Host 进程需能 SSH 访问目标服务器(插件运行在 Host 进程,不受工作区沙箱限制) |
| 服务器 | 支持密码 / 私钥(可带口令)/ SSH Agent 认证的 OpenSSH 服务器;需要 SFTP 子系统;远程扫描在优先使用 GNU find 时最快,没有 find 时回退 SFTP 遍历 |

核心模型:服务器配置与工作区配置分离

- 服务器配置(可复用):名称、地址、端口、用户名、认证方式(密码 / 私钥 / SSH Agent)、私钥路径。服务器地址和账号只需配置一次,可被多个工作区复用。
- 工作区配置:只选择「服务器 + 远程文件夹」以及同步设置(排除规则、自动同步、备份、是否允许 AI 执行远程命令等)。

因此在对话里打开配置面板时,不需要再输入地址、账号或密码:直接选服务器、选远程文件夹、调整设置即可。

v1.2.0 主要变化

- 扫描不完整时不再删除:本地/远程任一侧出现读取失败(权限、IO)时,对比结果标记 scanIncomplete,计划里所有删除/移除空目录动作改为 skip 并计入 summary.blockedDeletes(中英文案都会说明原因);手动同步、AI 同步与启动对账同样遵守,自动同步在无法确认本地文件状态时也不删除。
- 备份失败即停止破坏性操作(fail-closed):删除/覆盖前备份失败时,该动作被跳过并记为失败(code: 'BACKUP_FAILED'),不再"备份失败但仍删除";自动同步单文件推送同样返回 skipped/backup-failed。
- 原子写:本地与远程写文件都先写同目录临时文件(名字含 .dsh-rws-tmp-)再 rename 覆盖,取消/超时/失败不会在目标路径留下截断文件;扫描器会忽略这些临时文件。
- 运行态持久化与重启对账:新增 state.json(最近同步结果、自动同步健康度、启动检测时间、未处理的 watcher 变更、inProgress);Host 重启后自动恢复,若上次运行中断则标记 lastSync.interrupted 并在约 2 秒后做一次对账(最多入队 100 个文件,超出则提示手动同步,不静默截断;工作区正忙时跳过)。
- watcher 更可靠:无文件名的监听事件不再被丢弃(标记需要重新对账);停止监听时未处理的变更会持久化并在下次启动继续;监听出错按 1s/5s/30s 退避最多重启 3 次,超限后明确提示并保留可观测状态。
- 写锁覆盖单文件操作:remote_resolve_file、合并编辑器写回与 remote_write 都纳入工作区写锁,和完整/自动同步互斥。
- 超时不再误杀连接:SFTP_TIMEOUT 先用 5 秒轻量探测确认连接是否真的失效,只有探测失败才丢弃共享连接;sftp 会话为空的"假连接"错误被识别为连接级错误并触发重连。
- 工具结果更诚实:remote_sync 在部分失败/取消时返回 ok:false(不再恒为 ok:true)并给出失败处理提示;ssh2 的数字 SFTP 状态码(如 3)归一化为插件错误码(如 SFTP_PERMISSION_DENIED)并保留原始 sftpCode;remote_diff 增加 scanIncomplete/blockedDeletes/deleteExtrasAssumed,原因统计会标注"基于已加载的前 N 条"。
- 预览与设置一致:对比预览使用工作区真实默认(manualDeleteExtras,默认不删除);改动删除/备份设置会立即让已生成的预览失效,确认时若设置已变则要求重新预览,避免"预览一种、执行另一种"。
- 工作区切换竞态修复:切换工作区会使在途的配置/状态/对比/预览/文件差异请求全部作废,不再出现旧工作区的响应覆盖新界面。

v1.1.0 主要变化

- 长任务可见、可取消:对比/同步显示阶段(等待锁 → 连接 → 对比 → 应用 → 清理)、已处理/总数、已用时间;可随时取消;超时/失败后提示「Host 可能仍在执行,请先重新对比再决定是否重试」。
- 新增 AI 工具 remote_sync_status:查询正在执行的操作与最近一次同步结果,可取消;remote_sync 增加软超时(默认 120 秒,超时返回 pending + operationId,不再让工具调用空等十分钟以上)。
- 自动同步健康度:autoSyncHealth(off/active/degraded/stopped、连续失败数、最后错误、待推送文件数)在状态、界面与 AI 工具中可见;失败指数退避(1s/2s/5s/10s/30s/60s),不再静默失败。
- 备份批次与保留:一次自动同步批次共用同一个备份目录;新增 backupKeep(默认保留 20 个,0=不清理),按 ISO 时间戳目录清理旧备份。
- 会话启动检测更可靠:新增 startupCheck 开关、120 秒内对比缓存复用、180 秒超时、检测结果(lastStartupCheck)与失败原因可见;只对真差异注入提示(除纯 mtime 候选与哈希不可用外,包含仅本地、仅远程、目录、类型冲突),不再被 mtime 假阳性刷屏。
- 危险操作更保守:手动/AI 同步的 deleteExtras 默认值改为工作区配置 manualDeleteExtras(默认 false,即只增改不删除);预览展示 Host 生成的后果说明与可展开的动作清单(默认 5 条、展开最多 30 条);批量接受前二次确认,超过 100 条客户端分批执行,Host 跳过(skipped,如超出单批上限/重复/非法路径)会提示。
- 排除规则体验:chips 编辑器、冗余/上限提示、200 条上限;新增「导入 .gitignore」(一次性预览后合并,不改变运行时语义)。
- AI 输出瘦身:remote_file_diff 只返回改动块(hunks)、remote_read 默认 64KB 且支持 offset、remote_exec 输出截断(head+tail)、remote_list/remote_diff 分页;工具错误统一为 [CODE] 说明。下一步:…。
- 重新配置路径更顺:服务器「新建」直达编辑器、浏览弹窗可新建文件夹、测试结果按「SSH/SFTP、目录存在、可写」三行 checklist 展示;设置页提供 3 步进度(服务器 → 远程目录 → 对比同步)。
- 文档与测试:README / DESIGN 按 v1.1.0 现状更新,新增 CHANGELOG;package.json 增加 scripts/engines/exports;CI 覆盖三个测试套件、全部入口语法检查,以及 Windows job。

功能

- 服务器管理:新增/编辑/删除服务器配置(删除前二次确认),可单独测试服务器连通性;被工作区使用的服务器禁止删除。
- 实时远程文件夹选择:在工作区设置里点「浏览」,实时读取远程目录并逐级选择(也可手动输入绝对路径);弹窗内可「新建文件夹」(POST /mkdir),成功后直接进入该目录。
- 测试连接:检测 SSH/SFTP、主机指纹、远程文件夹是否存在与可写、往返延迟、服务器信息;结果按 SSH/SFTP、目录存在、可写三行 checklist 展示(未测试=未知),文件夹不存在可一键创建。
- 对比与同步:比较本地工作区与远程文件夹,列出仅本地/仅远程/内容不同/类型冲突/目录等差异;显示「推送到远程」「拉取到本地」两种计划各自的新增、覆盖、删除数量、字节数与后果;执行前可预览(含 Host 生成的说明与可展开的动作清单,默认 5 条、展开最多 30 条),默认先备份到目标端 .dsh-remote-sync-backup/<时间戳>/。
- 长任务进度与取消:对比与同步过程显示当前阶段、已处理/总数与已用时间;同步中可点「取消」;超时/失败后保留 sticky 错误提示并禁用确认按钮,直到重新对比。
- 自动同步(默认关闭):开启并保存后,本地新增/修改自动推送到远程;删除传播可选;单文件 20 MiB 上限;健康度、连续失败与最后错误在状态卡与 dock 中可见。
- 自动同步健康度:off(未开启)/active(监听中且最近成功)/degraded(最近一次有失败)/stopped(应开启但 watcher 没在跑);dock 与状态卡显示失败数,可展开错误明细。
- 对话内不一致提示:打开已配置工作区的会话时,后台检测(可用 startupCheck 关闭);有真差异时注入 [远程工作区同步] 后台提示(差异摘要、两种同步后果、自动同步状态)。真差异指除「纯时间戳候选」和「哈希不可用」之外的全部差异,包括仅本地/仅远程/目录/类型冲突;纯 mtime 候选只计数、不注入。提示是背景信息,不强制打断用户当前任务,也不强制调用 ask_user_question。
- AI 操作远程服务器(12 个工具):remote_status、remote_sync_status、remote_diff、remote_sync、remote_list、remote_read、remote_write、remote_exec、remote_test_connection、remote_file_diff、remote_resolve_file、remote_exclude(详见「AI 工具」)。
- 逐文件处理(VSCode 风格冲突解决):对比列表里每个文件都可以打开「文件差异」——左右并排显示本地/远程版本与行级高亮;可以按差异块选择「用本地 / 用远程 / 两者都保留」,再一键「应用合并(本地+远程)」或只写某一侧;也可以整文件「接受本地」「接受远程」。其他差异不会被改动,直到你主动执行完整同步或逐个处理。二进制/超大文件也可以直接整文件接受。
- 多选与筛选:差异列表支持按路径搜索、按 6 种差异类型筛选(含目录)、勾选/全选可见项;可以只「推送选中 / 拉取选中 / 接受选中版本 / 排除选中」,批量操作不会动未选中的差异,超过 100 条时客户端分批执行并显示进度,Host 返回的 skipped 会提示出来。
- 排除同步项:对比列表里任意文件/目录可直接「排除」,写入该工作区的排除规则,后续对比和同步都会忽略它;不会删除本地或远程文件。设置页的「排除规则」为 chips 编辑器,支持增删单条、来源标注、目录规则识别、冗余与 200 条上限提示,并可「导入 .gitignore」。
- 配置持久化与自动保存:工作区设置修改后约 1 秒自动保存(保存时显示「已自动保存 HH:MM:SS」,失败可见),并显示配置存储位置;配置写入采用原子替换,每次写入前保留 config.json.bak,重启或异常退出不会丢配置。
- 备份批次与保留:覆盖/删除目标端前默认先备份;一次自动同步批次共用一个备份目录;backupKeep 控制每个工作区保留的备份目录数量(默认 20,0=不清理,上限 500),只清理符合 ISO 时间戳命名的目录,best-effort。
- 性能:远程目录扫描优先用一次 find 命令代替逐目录 SFTP 往返(真实服务器上约 2,000 个文件:逐目录 SFTP 约 80 秒 → 单次 find 约 1.5–2.5 秒),并缓存远程文件哈希(重复对比约 1 秒);同步支持只处理指定 paths(如选中项),不再整树扫描。打开「对比与同步」自动开始对比,界面显示本次对比耗时与扫描方式。
- 深色/浅色适配:所有界面颜色都基于 DSH 主题 token,并带有颜色回退;差异新增/删除、合并编辑器的底色会随浅色/深色主题自动变化。
- 差异/合并编辑器:支持逐行并排、行号、差异块操作、全部用本地/远程、应用合并到两侧或单侧;工具栏按「整文件采用 / 逐块合并」分组,接受/应用前有确认(说明写入侧、覆盖文件数与备份),删除型动作用危险色。

界面入口

1. 设置 → 远程同步:三个标签页 ——「工作区设置」「服务器」「对比与同步」。
2. 侧边栏底部「远程同步」按钮:随时打开同一个管理面板。
3. 对话输入框下方状态条(dock):显示当前工作区状态,按优先级为:未配置 → 同步中 mm:ss → 对比中 mm:ss → 自动同步失败 N → 启动检测失败 → N 处差异 → 自动同步已开启 → 已配置;点开即跳到对应标签页(已配置 → 对比与同步;未配置 → 工作区设置)。有操作执行时每 5 秒刷新,否则每 15 秒。

使用步骤

1. 安装插件(见「安装 / 升级 / 回滚」),重启 DSH Host 并刷新 Web 页面。
2. 打开 设置 → 远程同步(或侧边栏底部按钮)。
3. 切到「服务器」→「新建服务器」:填名称、地址、端口、用户名,选择认证方式:
- 密码:直接填写(保存后只显示「已保存」)
- 私钥:填本地私钥绝对路径,有口令则填口令
- SSH Agent:使用 Host 进程的 SSH_AUTH_SOCK 可先点「测试服务器」验证,再「保存服务器」。
4. 切到「工作区设置」:选择工作区 → 选择服务器 → 点「浏览」实时选择远程文件夹(可新建文件夹)→ 按需调整排除规则、自动同步、备份、AI 远程命令开关。顶部有 3 步进度(服务器 → 远程目录 → 对比同步);改动会在约 1 秒后自动保存(也可以点「保存配置」立即保存)。
5. 点「测试连接」确认服务器+文件夹可用;文件夹不存在时可「创建该目录」。建议此时确认「允许 AI 执行远程命令」是否符合预期(默认开启,见「同步语义与安全」)。
6. 切到「对比与同步」:打开标签页会自动对比(也可手动点「对比差异」)。在差异列表中:
- 点「查看差异」打开左右并排的合并编辑器:按块选择用本地/远程/两者,或整文件接受本地/远程;确认后应用合并结果;
- 支持搜索/类型筛选、勾选多个文件后批量推送、拉取、接受或排除(超过 100 条会分批执行并显示进度);
- 点「排除」把该文件/目录加入排除规则,之后不再参与对比和同步;
- 也可以点「全部推送到远程」「全部拉取到本地」处理全部差异;会先显示后果预览,确认后执行;执行中可取消。
7. 打开该工作区的会话时,对话底部状态条和会话内提示会反映远程状态;有真差异时 AI 会收到后台提示(设置里可用 startupCheck 关闭)。

长任务:进度、超时与取消

- 对比/同步在 Host 里是可查询的操作:GET /status 的 active[] 给出 kind(manual-sync/auto-sync/compare/startup-check)、phase(waiting-lock/connect/compare/apply/cleanup)、processed/total、startedAt、waiting。
- 同一工作区同时只允许一个写操作(手动同步/自动同步批次互斥);手动同步在等自动同步批次时显示「等待锁」。
- 界面上的「取消」调用 POST /api/remote-workspace-sync/sync/cancel;取消是在文件边界生效的部分完成语义:已完成的文件保留,返回结果带 aborted 与 partial(applied/failed/warnings/backupDir),lastSync 会保留这次取消前的结果。
- 超时/失败后界面保留 sticky 错误提示:「Host 可能仍在执行,请先重新对比再决定是否重试」;确认按钮禁用直到重新对比。
- AI 侧:remote_sync 有 waitMs 软超时(默认 120000ms,范围 5s–540s)。超时不会报工具错误,而是返回 {ok:true, pending:true, operationId, summary, hint}——提示先用 remote_sync_status 查询进度或取消,不要直接重试。

同步语义与安全

- push 让远程文件夹镜像本地;pull 让本地镜像远程。
- 手动/AI 同步默认不删除目标端多余文件:deleteExtras 未显式传入时取工作区配置 manualDeleteExtras(默认 false);AI 显式传参优先。打开删除后预览会显示「删除 N 项」及后果;自动同步的删除传播由 autoSyncDeletes 单独控制(默认关闭)。
- 覆盖/删除目标端前默认先备份(可关闭,关闭时预览会警告不可恢复);备份在目标端 .dsh-remote-sync-backup/<ISO 时间戳>/。备份失败时该删除/覆盖会被跳过并记为失败,不会出现"没备份成功却仍然删除"。
- 扫描不完整时不删除:任一侧读取失败(权限/IO)会把对比标记为 scanIncomplete,此时删除与移除空目录动作全部改为跳过,并在计划里给出 blockedDeletes(中英文说明都会写明原因);修复权限或排除规则后重新对比即可恢复删除。
- 本地与远程写文件都是原子写:先写同目录临时文件(.dsh-rws-tmp- 前缀)再 rename 覆盖;取消/超时/失败不会留下截断文件,扫描与差异列表也会忽略这些临时文件。
- 排除规则默认 .git, node_modules, .dsh-remote-sync-backup,支持分隔符(名称或相对路径通配符);保存时会归一化(\→/、去掉开头的 ./ 与结尾 /、去重),上限 200 条。对比列表中的「排除」会自动加入精确路径(目录还会加入 <dir>/)。
- 目录(含空目录)参与对比与同步,通过 mkdir/rmdir 动作处理;符号链接与特殊类型文件会跳过并给出 warning;手动同步单文件上限 512 MiB,自动同步 20 MiB;文件数超过 maxEntries(默认 20000,范围 100–200000)会中止并提示。
- 主机密钥 TOFU:首次连接信任并保存指纹;指纹变化会硬失败,需在配置页「信任新主机密钥并重试」。
- remote_exec 以远程登录用户身份执行命令,无远程沙箱;工作区配置 allowExec 默认开启,不需要时请在工作区设置里关闭(关闭后 remote_exec 会被拒绝)。插件运行在 Host 进程,只连接可信服务器。
- AI 的 remote_sync 默认只预览(dryRun:true);系统提示与工具描述要求先说明后果并经用户确认后才 dryRun:false。

自动同步:只推不拉

- 自动同步只监听本地并推送(新增/修改;删除需另开 autoSyncDeletes),不会自动拉取远程变化——远程变更请手动「对比」后拉取。
- 触发与批次:本地变更 debounce 后推送;距首个事件 ≥5 秒强制 flush;单批次最多 100 个文件或 64 MB,超出分片执行;一次批次共用一个备份时间戳;每个文件处理前重新读取配置/排除规则(保存设置后立即生效)。
- 健康度:status.autoSyncHealth.state 为 off/active/degraded/stopped,并给出 lastRunAt、lastSuccessAt、consecutiveFailures、lastError、pendingFiles。失败按指数退避重试(1s/2s/5s/10s/30s/60s 上限),不按事件立即重连;失败详情在状态卡中可展开,AI 的 remote_status summary 也会直接给出失败数与首个错误。
- 被排除、超过 20 MiB、位于 .dsh-remote-sync-backup 内的文件不会被推送。
- watcher 启动是幂等的;启动失败会体现在 autoSyncHealth(stopped/lastError),不会静默。
- watcher 出错不再永久停摆:按 1s/5s/30s 退避最多重启 3 次,超限后明确提示并标记需要重新对账;无文件名的监听事件也会标记重新对账,而不是被丢弃。
- 停止监听(关闭自动同步、切换工作区、Host 退出)时未处理的变更会持久化到 state.json,下次启动继续处理;Host 重启后若上次运行中断,会在约 2 秒后对 autoSync 工作区做一次对账(单次最多入队 100 个文件,超出会提示手动同步;工作区正忙时跳过)。

备份与保留(backupKeep)

- 覆盖/删除目标端前,若 backup=true(默认),先复制到目标端的 .dsh-remote-sync-backup/<ISO 时间戳>/;手动同步、批量接受、合并编辑器共用同一规则;自动同步一次批次共用一个时间戳目录。
- backupKeep(默认 20,范围 0–500):每个工作区最多保留最新的 N 个备份目录;0 表示不自动清理。
- 清理只针对名字严格匹配 YYYY-MM-DDTHH-MM-SS-mmmZ 的目录,且每个工作区 10 分钟内最多执行一次;清理失败只记 warning,不影响同步结果(best-effort)。
- 本地侧执行 pull/接受远程也可以产生同名备份目录;恢复时从对应时间戳目录取回文件即可。

工作区设置项

| 字段 | 默认值 | 说明 |
| serverId | 空 | 复用的服务器配置 id |
| remoteDir | 空 | 远程目录(绝对路径或服务器上可解析的路径) |
| excludes | .git, node_modules, .dsh-remote-sync-backup | 排除规则;保存时归一化,上限 200 条(超限会提示 excludesTruncated) |
| autoSync | false | 自动同步(本地 → 远程,只推不拉) |
| autoSyncDeletes | false | 自动同步是否传播本地删除 |
| backup | true | 覆盖/删除目标端前先备份 |
| backupKeep | 20 | 每个工作区保留的备份目录数(0=不清理,上限 500) |
| manualDeleteExtras | false | 手动/AI 同步的 deleteExtras 默认值(AI 显式传参优先) |
| startupCheck | true | 会话启动时做不一致检测并注入提示 |
| maxEntries | 20000 | 单侧最大条目数(范围 100–200000),超过中止并提示 |
| allowExec | true | 是否允许 AI 执行远程命令;不需要时请关闭 |

旧配置字段全部兼容:读取旧 config.json 时缺失的新字段使用上述默认值;保存时会补齐字段并保留未知字段。

排除规则与导入 .gitignore

- 排除规则是「名称/相对路径」列表,不是完整的 gitignore 引擎:data 会忽略任意层级的同名目录,data/、src/.log 这类通配符按现有匹配器工作;目录与文件都可排除。
- 归一化:反斜杠转 /、去掉开头的 ./ 与结尾的 /、trim、去重;超过 200 条会截断并在配置视图中给出 excludesTruncated 警告。
- 「导入 .gitignore」是一次性导入预览:读取工作区根目录 .gitignore,忽略空行/# 注释/! 取反行(取反行会列在 skipped 中),去掉行首 / 与行尾 /(目录规则保留目录名), 原样保留;预览最多 200 条(超出标 truncated),确认后合并进排除规则并保存。它不改变运行时语义,也不会在之后自动跟踪 .gitignore 的变化。
- 对比列表中的「排除」仍是最精确的做法(单文件精确路径,目录会追加 <dir>/)。

AI 工具(12 个)

所有工具都在 Host 侧执行,支持 workspaceId(省略时用当前会话的工作区)。错误统一为 throw new Error('[CODE] 中文说明。下一步:<hint>'),便于模型直接给出下一步操作。例如未配置时返回: [NOT_CONFIGURED] 该工作区尚未配置远程服务器。下一步:请在 Web UI 的「设置 → 远程同步 → 工作区设置」中为该工作区选择服务器并填写远程目录,然后重试。
错误码覆盖 NOT_CONFIGURED/SERVER_NOT_CONFIGURED/REMOTE_DIR_NOT_CONFIGURED/HOST_KEY_CHANGED/SSH_TIMEOUT/SFTP_TIMEOUT/BUSY/ABORTED/EXEC_DISABLED/TOO_MANY_ENTRIES/INVALID_ARGUMENT 等。

| 工具 | 作用 | 关键参数 / 说明 |
| remote_status | 状态总览(只读) | summary 含自动同步健康(失败数+首错)、最近启动检测、当前 active 操作;JSON 透传 status(含 active、autoSyncHealth、lastStartupCheck、lastSync) |
| remote_sync_status | 查询/取消正在执行的操作 | workspaceId?、operationId?、cancel?;summary 区分「进行中」与「已结束(完成/失败,含最近结果)」,返回 operation、finished、ageMs、result?;cancel:true 返回 cancelled/operationId |
| remote_diff | 对比并给出两种同步计划(只读) | limit(默认 300)、offset、refresh;summary 按差异 reason 分组(内容不同(已校验)/大小不同/仅时间戳候选 N(未校验),分页时标注「基于已加载的前 N 条」);新增 scanIncomplete/blockedDeletes/deleteExtrasAssumed;plans 只保留摘要与中文说明 |
| remote_sync | 推送/拉取(默认只预览) | direction(必填)、dryRun(默认 true)、deleteExtras(缺省取工作区 manualDeleteExtras)、paths、waitMs(默认 120000,5s–540s;超时返回 pending+operationId);部分失败或取消时 ok:false 并给出失败处理提示 |
| remote_list | 列远程目录(只读) | path、offset、limit(默认 200,最大 2000;Host 侧读取目录后按 offset/limit 切片,非服务端游标分页);返回 totalDirs/totalFiles/nextOffset/truncated 与分页提示 |
| remote_read | 读远程文本文件(只读) | path、offset(起始字节)、maxBytes(默认 64 KiB,单次上限 16 MiB);返回 truncated/nextOffset/totalSize |
| remote_write | 写远程文本文件 | path、content(≤8 MiB)、backup(默认 true,覆盖前备份) |
| remote_exec | 在远程目录执行 shell | command、timeoutMs(默认 120s,最大 600s)、maxOutputBytes(stdout/stderr 各自默认 64 KiB,最大 1 MiB;超限保留首 60% + 尾 40% 并标 truncated);需 allowExec |
| remote_file_diff | 逐文件行级差异(只读) | path、includeText(默认 false,不返回全文)、maxHunkLines(默认 200);默认只返回 hunks(±3 行上下文),超限标 truncated |
| remote_resolve_file | 单文件接受某侧版本 | path、direction(push=接受本地 / pull=接受远程);只改这一个文件,其余差异不变,目标端先备份 |
| remote_exclude | 加入排除规则 | path、kind(file/dir);不删除任何文件,后续对比/同步忽略 |
| remote_test_connection | 测试已保存配置的连通性 | 检测 SSH/SFTP、目录存在与可写、指纹、延迟;只写/删一个探针文件 |

提示:remote_sync 超时返回 pending 不代表失败,请用 remote_sync_status 查询或取消;不要在未核对前重复执行。

配置存储与持久化

- 工作区/服务器配置:$DSH_HOME/remote-workspace-sync/config.json(不含密码);DSH 重启后自动加载。
- 每次写入先原子写临时文件并 fsync,再替换主文件;写入前把上一版复制为 config.json.bak。若主文件损坏,插件会自动保留损坏文件并从 .bak 恢复。
- 密码/私钥口令:保存在 DSH 凭据服务(ctx.credentials),按服务器 id 存储,不发送到浏览器,也不受插件重启影响。
- 主机指纹:$DSH_HOME/remote-workspace-sync/known-hosts.json。
- 运行态:$DSH_HOME/remote-workspace-sync/state.json(最近同步结果、自动同步健康度、启动检测时间、未处理的 watcher 变更、inProgress 标记)。原子写(临时文件 + rename),损坏时改名为 state.json.corrupt-<时间戳> 并从空状态继续;写入失败只记日志,不影响同步。
- 面板「工作区设置」底部显示实际存储路径、最近保存时间、是否可写、是否有自动备份。
- 旧版(连接信息内联在工作区配置里)会在插件启动时自动迁移为服务器配置 + 工作区引用。
- v1.1.0 的新字段(manualDeleteExtras/startupCheck/backupKeep)在旧配置中缺省即用默认值,无需手动迁移。

开发与验证

要求 Node ≥ 20(CI 使用 Node 24)。三个测试套件与 probe 都可在本地运行:

依赖(本地开发必需;ssh2 是唯一运行时依赖,无需编译)
pnpm install --ignore-scripts

1) 对比/计划/执行/备份/排除规则(不需要 SSH)
node tests/sync-unit.mjs

2) 应用层 E2E:服务器/工作区配置、HTTP 路由、自动同步 watcher、会话提示、新路由
node tests/app-e2e.mjs

3) SSH/SFTP 传输层 E2E(本地 paramiko fixture)
node tests/remote-e2e.mjs

4) SSH fixture / 传输层自检
node probe/ssh-probe.mjs

语法检查全部入口(index.js、client.js、lib/.js)
pnpm run check # 没有 pnpm 时可用 npm run check

一次跑三个套件(需要 python3 + paramiko)
pnpm test

- E2E 的 SSH fixture:fixtures/fixture-server.mjs 会拉起 fixtures/test-ssh-server.py(仅监听 127.0.0.1,测试凭据 dsh/dsh-test,SFTP + exec,见 fixtures/README.md)。需要 python3 与 paramiko(python3 -m pip install paramiko)。
- CI(.github/workflows/tests.yml):pnpm install --ignore-scripts 后先跑语法检查与 unit;安装 python3+paramiko 后跑 app-e2e 与 remote-e2e(runner 无 python 时显式跳过并输出说明);另有 Windows job 只跑 unit + 语法检查。
- 不联网、不连接真实服务器也能跑完三套件(fixture 在 loopback)。
- 验证范围:Host 逻辑(对比/计划/应用/备份/自动同步/健康度/启动检测/运行态持久化与重启对账/HTTP 路由/12 个工具)由上述套件覆盖;传输层与完整工作流已在真实服务器(约 2,000 个文件的 PolyBot 工作区,含对比、推送/拉取、逐文件处理与备份)上实际使用验证,自动化 E2E 使用本地 paramiko fixture。浏览器视觉/交互(布局、深色浅色、焦点、语言切换)没有自动化回归,需要人工点一遍。

安装 / 升级 / 回滚

从 GitHub 安装(推荐)

在 DSH 中使用 plugin_manager 的 install_bundle,target 填 github:go-enols/dsh-remote-workspace-sync。依赖 ssh2 会由插件管理器安装。

从本地克隆安装(开发/离线)

git clone https://github.com/go-enols/dsh-remote-workspace-sync.git
cd dsh-remote-workspace-sync
pnpm install --ignore-scripts # 必须先装依赖:link 安装不会替你安装 ssh2

然后把 install_bundle 的 target 指向仓库目录(本地 bundle 以链接方式安装)。修改源码后:Host 代码需要重启 DSH Host 才生效,Client 代码需要刷新 Web 页面(Client bundle 不热更新)。

升级(v1.1.0 → v1.2.0)

1. 用上面的方式安装/更新到 v1.2.0。
2. 重启 DSH Host(Host 插件与工具注册需要重启生效)。
3. 刷新 Web 页面(Client bundle 需要重新加载;若仍显示旧 UI,强制刷新)。
4. 配置完全向后兼容,无需迁移:config.json 字段不变,新增的 state.json 会在首次运行时自动创建(不存在即视为空状态)。
5. 行为变化(都是更保守的一侧):
- 扫描不完整时不再删除目标端文件(此前会按不完整的扫描结果删除)。
- 备份失败时跳过该删除/覆盖并记为失败(此前只记 warning 后继续)。
- remote_sync 在部分失败/取消时返回 ok:false(此前恒为 ok:true);依赖旧行为的调用方请按 ok/failed 判断。
- 对比预览默认按工作区 manualDeleteExtras(默认不删除)生成;改动删除/备份设置会使预览失效,需要重新预览。

升级(v1.0.0 → v1.1.0)

1. 用上面的方式安装/更新到 v1.1.0。
2. 重启 DSH Host(Host 插件与工具注册需要重启生效)。
3. 刷新 Web 页面(Client bundle 需要重新加载;若仍显示旧 UI,强制刷新)。
4. 配置向后兼容:旧字段(autoSync/autoSyncDeletes/backup/allowExec/maxEntries/excludes 等)保持不变;新字段缺省即用默认值(manualDeleteExtras=false、startupCheck=true、backupKeep=20)。已保存的 excludes 会在读取时归一化,行为一致。
5. 升级注意事项:
- 手动同步的默认删除行为从「删除目标端多余文件」变为不删除(manualDeleteExtras 默认 false)。需要删除时在预览/设置中显式开启,或让 AI 显式传 deleteExtras:true。
- 若从早期包名(@local/remote-workspace-sync)升级,需先在插件管理器中移除旧 bundle,再安装新包名的 bundle。

回滚

1. 重新安装 v1.0.0 的 bundle(GitHub tag 或 git checkout v1.0.0 后重新 link 安装)。
2. 重启 DSH Host 并刷新页面。
3. 旧版本不读取新字段;回滚前建议先备份 $DSH_HOME/remote-workspace-sync/config.json(插件自身也会保留 config.json.bak)。新字段若被旧版本重写丢失,重新升级后会恢复默认值。

已知限制

- 仅验证 Web 版 GUI;Electron file:// 桌面外壳的 IPC 传输未适配。
- 没有自动化浏览器视觉/交互回归测试:布局、浅色/深色、焦点陷阱、Escape 关闭、实时切换语言等需要人工点一遍确认;CI 覆盖的是 Host 逻辑与 HTTP 路由。
- 自动同步只推不拉:远程变化必须手动对比后拉取;没有远程文件系统 watcher。
- 自动同步依赖 Node 的 fs.watch(dir, { recursive: true }) 文件监听:Windows/macOS 原生支持;Linux 的 recursive 监听需要较新的 Node 版本(较旧版本会启动失败)。监听未启动会以 autoSyncHealth.state='stopped' 暴露(并带 lastError),此时请改用手动同步。
- 目录(含空目录)会同步(mkdir/rmdir);符号链接与特殊类型文件跳过并给出 warning;单文件上限 512 MiB(手动)/20 MiB(自动);maxEntries 默认 20000。
- 主机密钥 TOFU,没有「每次连接询问」模式;指纹变化必须显式重新信任。
- SSH Agent 认证未纳入自动化 fixture 测试(fixture 覆盖密码与私钥认证)。
- remote_exec 无远程沙箱,且 allowExec 默认开启;不需要时请关闭。
- 备份保留只清理符合 ISO 时间戳命名的备份目录;手工创建的其他目录不会被删除。
- 运行态持久化(state.json)是 best-effort:写盘失败只记日志;重启对账只针对 autoSync=true 的工作区,单次最多入队 100 个文件(超出会提示手动同步),且同样只推不拉。删除只依赖 autoSyncDeletes 且要求扫描可信。
- 「导入 .gitignore」是一次性预览合并,不支持 ! 取反等完整 gitignore 语义。
- 插件依赖 Host 插件 API;DSH 升级后若 API 变化可能需要升级插件版本(本项目在 DSH 0.2.1-rc.2 上验证)。

License

MIT,见 LICENSE。
预览分享卡片长什么样 ↓go-enols/dsh-remote-workspace-sync
分享 · DeepSeek Harness Hub
go-enols/dsh-remote-workspace-sync

通过 SSH 对比并同步本地与远程文件夹

回到顶部