dsh-multi-remote

DSH PLUGIN会话与消息

仓库 jk-uzi/dsh-multi-remote · npm @jk-uzi/dsh-multi-remote

会话与消息 未标注验证等级 安全审查:未标注 可信度:未标注 可安装插件
安装这个插件

为 DeepSeek Harness 接入 SSH、WSL、Docker 三种远程开发环境,让 agent 的文件读写、命令执行与搜索全部落在远端,本地只保留有界只读镜像。

一句话选型结论

按资料字段整理

dsh-multi-remote 是会话与消息类的 DSH 可安装插件,未做沙盒验证,暂无安全审查结论,列出 5 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类会话与消息 收录类型可安装插件 验证等级未标注验证等级 安全审查未标注
验证等级 UNKNOWN 未标注验证等级
GitHub 星标 1 复刻 0 · 未关闭 issue 0
最近更新 2026-10-09 创建于 2026-10-09
README 31.9 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add @jk-uzi/dsh-multi-remote
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名@jk-uzi/dsh-multi-remote可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-multi-remote:让 DeepSeek Harness 的文件与命令落在远程环境

  • SSH / WSL / Docker 三后端
  • 文件与命令自动落到远端
  • 远程真 PTY 交互终端
  • glob / grep 在远端执行
  • 本地有界只读镜像

上游标签

dsh-plugin

验证等级与安全审查

未标注验证等级
自动化流程结论,不是人工审核
验证等级未标注验证等级上游未给出验证结论,安装前请自行确认
安全审查未标注静态分析结论,未标注不代表已通过审查
仓库健康度未标注按仓库活跃度与最近更新时间给出
可信度未标注综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 安全审查还没结论,装之前先看仓库改了什么、要什么权限。
  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在会话与消息场景里给 DSH 补能力的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-multi-remote当前 未做沙盒验证 未标注 1 未标注 有
dsh-desktop L3 · 安装规范通过 低风险 3.0 万 未标注 无
openpets L4 · 沙盒安装通过 低风险 1,274 未标注 有
deeptide L4 · 沙盒安装通过 低风险 1,104 0.1.1-rc.2 有
jingyun-dsh L3 · 安装规范通过 低风险 1,004 未标注 有
study-mate 未做沙盒验证 未标注 856 未标注 无

仓库档案

会话与消息
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方jk-uzi仓库 dsh-multi-remote · 默认分支 main
分类会话与消息client
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue1 / 0 / 0收录时的数值,非实时
创建 / 更新2026-10-09 · 2026-10-09最后推送 2026-10-09
本站收录2026-10-11首次进入本站目录的时间

README 全文

31.9 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-multi-remote

DSH(DeepSeek Harness)插件:同时支持 SSH / WSL / Docker 三种远程环境。
连上之后,agent 的文件读写、bash 执行、搜索全部在目标环境里执行——大脑留在本地,文件和命令在远端。

> 当前状态:三种后端全部可用(SSH / WSL / Docker)。 见 CHANGELOG。

这是什么

在哪
模型调用、思考、决策 本地(装了 DSH 的这台机器)
文件读写、命令执行 远端(文件只有一份,就在远端)
界面要看的文件树 / @ 补全 / 改动对比 本地锚点目录里的只读镜像

那个本地锚点目录是干什么的?会把我整个项目拉下来吗?

不会。 它是给界面看的:DSH 的文件树、编辑器、改动对比读的都是本地文件,
没有这份镜像,界面上就是空的。但它是有界的、只读的、且不是 agent 干活的地方。

分两个阶段,各有边界(都超出即停,并如实标记截断):

① 打开工作区时(要快 —— 用户在等着):

边界 默认值 超了会怎样
目录深度 12 层 更深的子树不搬
条目数 20 000 个(文件 + 目录) 剩下的不搬
单文件大小 256 KiB 本地留一个占位文件(见下)
墙钟时间 30 秒 到点就停,树可能只覆盖一部分

> 拉取有多快(2026-10-09 实测,WSL、197 个文本文件的项目):
> 首次全量 ~2.3 秒(批量读:一次调用拉一批,而不是每文件一次);
> 重连 ~1.1 秒(指纹命中跳过);改动一两个文件后重连,只拉变化的那几个。
> SSH 走并发拉取(SFTP 长连接天然支持流水线),Docker 的文件内容本来就走
> Engine API 的 archive(一次请求拿一批)。

② 连上之后的「后台补拉」(可以慢 —— 不阻塞任何操作):

边界 默认值 说明
只拉文本类文件 按扩展名(源码/配置/文档/脚本…) 网格、数据库、压缩包、图片不拉 —— 它们本来也不适合在界面里读
单文件大小 2 MiB 比首轮大得多,覆盖绝大多数源码与文档
总字节上限 64 MiB 到点就停(不会因为连了个 8 GB 的工程就往本地灌 8 GB)
墙钟时间 120 秒 每次连接都会补一次;上一轮拉过的会跳过,所以会一轮比一轮覆盖得多

> 为什么要后台补拉:界面的读文件路径是宿主独占的(我们插不进手),
> 所以「点开文件时自动从远程拉」做不到。退而求其次 —— 在点开之前把
> 你真正会看的文件先补到本地。实测:一个 1.5 GB 的代码仓库,后台补拉
> 拉回 138 个文本文件(3.1 MB),README / 配置 / 源码点开就有内容。

占位文件:超过单文件上限的文件,本地会留一个几百字节的说明文件,内容形如:

<!-- dsh-multi-remote:not-synced -->
这个文件没有同步到本地镜像。

远端大小:69.8 MB(单文件上限 256.0 KB)
远端路径:/home/user/my-project/data/mesh.msh

它只在远端 —— 内容没有拉下来(避免为了显示一个文件把几十 MB 搬过来)。
要看或改它,直接在会话里让 agent 读(agent 的文件读写走的是远端,不受这里限制),
或者在会话里用 bash 查看(head / less / file / python 都行)。

这样文件在界面的文件树里看得见(以前是直接跳过 → 树里根本不显示,用户以为不存在),
点开也能立刻知道「它在哪、多大、怎么看」。

> ⚙️ 后台补拉可以关掉或调参:插件配置 mirrorDeepen = { enabled, maxFileBytes, maxTotalBytes, maxDurationMs }。

实测例子(一个 8.2 GB / 44 662 个文件的工程):

远端:8.2 GB,44 662 个文件
本地锚点:0.37 MB,30 个文件      ← 0.005%,且 >256 KiB 的内容一个字节都没拉

> 上面量的是首轮格局层(①)的边界效果。之后的后台补拉(②)会在此基础上再补进
> 「文本类 + ≤ 2 MiB」的文件,所以实际落到本地的会比这个数字多一些 —— 但仍然有界。

> ⚠️ 代价要如实说(2026-10-09 按代码复核过):
>
> - 项目特别大时,镜像会被边界截断 —— 被截掉的那部分子树本地根本没有,
> 界面的文件树里也不显示(首轮的深度 / 条目数 / 30 秒墙钟这三个边界)
> - 首轮超限(> 256 KiB)的文件,本地只有占位:文件树里看得见、点开有一句说明,
> 但内容没有拉下来 —— 所以界面里看不到内容、也不能编辑
> (2026-10-07 之前是直接跳过:那些文件在树里根本不显示,用户以为不存在)
> - 后台补拉会把占位换成真内容 —— 只要它是文本类且 ≤ 2 MiB;
> 非文本类(网格 / 数据库 / 压缩包 / 图片)或超过 2 MiB 的,保持占位
>
> 这几条都不影响 agent 干活(读写、命令、搜索全在远端,不受镜像边界约束),
> 只影响界面里能看到多少。想看得更全,就把工作区指向更小的目录(比如指向代码仓库本身,
> 而不是包含备份和数据集的上层目录)。

远端不需要装任何东西:

  • SSH:只要有 sshd 和一个能登录的账号 —— 不需要联网、不需要 API key、不需要装 DSH
  • WSL:只要有发行版本身(本机进程,连凭据都不需要)
  • Docker:只要容器已在运行(连凭据都不需要)

支持的后端

后端 状态 说明
SSH ✅ 可用 用 ssh2 库;host key TOFU,变更一律拒绝
WSL ✅ 可用 驱动 wsl.exe;不需要凭据
Docker ✅ 可用 直连 Engine API(不依赖 docker CLI);只连已运行的容器,不需要凭据

三者共用同一套上层(镜像层 / 预设层 / 会话绑定 / 工具)——
加一个后端只需要写一个 transport 文件,上层零改动。

模型能用上的能力

工具 干什么
remote_connect / remote_profiles / remote_list / remote_disconnect / remote_refresh 连接管理
宿主自带的 bash / read / write / edit 自动落到远程(在隔离域内换掉了 fs 与 shell)
glob / grep 也在远程执行(我们自己实现,用远程的 find / grep;见下)
人设 / AGENTS.md / 技能 / 目标 / 计划模式 / 后台任务 与本地会话同一套(预设里逐项对齐)
remote_terminal 远程交互式终端(真 PTY):步进调试器、REPL、需要跨调用保留状态的探索

remote_terminal 的要点:

  • 真 PTY(Docker / WSL 实测拿到 /dev/pts/N),不是管道 —— sudo、密码输入、
    全屏 TUI 都正常
  • 状态跨调用保留:cd、导出的变量、函数、后台任务都留着
  • 有界滚动缓冲 + 分页读,不会因为一条 yes 把内存吃光
  • SIGINT 真的能打断前台命令(走 PTY 控制字符,命中前台进程组)
  • 返回的 waitReason 告诉你「跑完了」有多可靠:session_exit 最确定,
    inferred_idle 是推断,timeout 表示可能还在跑

> 有界的一次性命令请用 bash —— 它更省事,而且有输出上限与超时保护。
> 终端是给「状态必须留在终端里」的场景用的。

搜索也是在远程执行的

glob / grep 由本项目自己实现(src/world/search.js),在隔离域内通过
ctx.shell 调用远程的 find / grep。

之所以不用宿主自带的那两个:它们用的是打包在宿主里的 ripgrep 可执行文件,
通过 subprocess 接缝运行(宿主源码注释明确写着 "never ctx.shell")——
也就是说跑在你本机、搜的是本地镜像:大于 256 KiB 的文件、
超过 12 层或 2 万条目之外的部分根本搜不到,而且不会告诉你漏了。

自己实现之后,搜索与读文件、跑命令一样是原生远程的 —— 实测在一个
328 KB 的文件里搜到了内容,而那个文件本地镜像里压根没有。

与宿主那份的差异(已写进工具描述,不静默):

项 说明
正则方言 用远程的 grep -E(POSIX 扩展正则),不是 ripgrep 语法;rg 特有的写法(如 lookaround)不支持
忽略规则 用内置剪枝名单(.git、node_modules、__pycache__…),不读远程的 .gitignore
结果上限 超过上限截断并如实标注(宿主那份会写 spill 文件)
include 支持简单 glob 与大括号(*.{js,jsx} 会展开成多个 -name)

> 需要的话仍可用 bash 跑 rg(若远程装了)—— 那是另一条路,不受上面的方言限制。

连接远程工作区

有两个入口,它们最终走同一套内部实现,所以行为不会漂移。

入口一:侧边栏的「远程开发」弹窗(推荐)

侧边栏里(和官方的 插件 并列)有一行 远程开发 —— 点开是一个固定大小的弹窗:
左边选后端,右边是识别出来的目标(不用自己填名字):

┌────────────────────────────────────────┐
│  远程开发                            ✕ │
│  连上 SSH / WSL / Docker 机器…          │
├───────────┬────────────────────────────┤
│ WSL  2 个 │ 选择发行版                  │
│ SSH  用过 │ ○ Ubuntu-24.04             │
│ Docker    │ ○ docker-desktop           │
├───────────┴────────────────────────────┤
│                       [取消]  [连接]    │
└────────────────────────────────────────┘

三个后端各自怎么选目标:

后端 怎么选
WSL 自动识别已安装的发行版(wsl -l -q,不会启动发行版)—— 一个就直接点,多个就在列表里挑。列表与 wsl -l -q 完全一致;Docker Desktop 自己装的那个系统发行版(docker-desktop)只是排在最后。busybox 发行版也支持(没有 bash 就用 sh,find/stat 走 busybox 兼容写法)
Docker 自动识别容器(运行中的排在前面并标出状态);守护进程没跑时如实说明原因
SSH 没有「自动识别」这回事(那需要凭据),所以列出用过的连接 —— 点一条就把主机 / 端口 / 账号 / 私钥路径填好,只需再给密码;也可以「新建连接」

> 列表长了会自己出现筛选框(容器可能几十个);标题栏的 ↻ 是「重新识别」——
> Docker Desktop 是按需启动的,启动完点一下就有容器了,不用关掉弹窗再开。
>
> 「探测失败」和「成功但没有」是两回事:探测失败(守护进程没跑、API 不对…)
> 会显示原因并给一条手填兜底;而探测成功、只是没有目标(没有容器 / 没装发行版)时,
> 给的是空状态 + 引导(docker run / wsl --install,然后点 ↻)——
> 那种情况下给输入框只会让人以为「填对了就能连」。

然后分两步(和 VS Code / ZCode 一样):

  1. 连机器 —— 只连机器,不用填项目路径
  2. 选项目文件夹 —— 连上后显示远程真实的目录树:点进去、返回上一层,
    找到项目后点「就用这个文件夹」。

选好之后插件自动建好工作区(镜像 + 预设 + 锚点),关掉弹窗并切回会话 ——
你只要在那个工作区下面新建会话。

> 弹窗里没有「打开本机文件夹」:那是 DSH 自己「添加工作区」的活。
> 本地目录不属于远程开发流程,混在一起只会让人以为它也是远程的一步。

> 为什么不用一次填完:那要求你盲填远程项目根。填错了(比如漏写一层
> 桌面/)连接照样「成功」,但之后每条命令都切不到目录 —— 非常难排查。
> 改成点选之后,路径不再靠猜。

> ⚠️ 为什么入口在侧边栏,而不是「工作区」旁的 + 按钮里:
> 我们试过把 + 按钮的选目录流程换成自己的界面 —— 结果官方的
> 选文件夹插件激活失败,整个 DSH 打不开
(那个流程已经有官方归属,
> 插件之间会冲突)。所以改成完全加法式的入口:多一行导航,谁也不影响谁。
>
> 实现上用的是宿主自己的三个槽位:sidebar.panellist(列表型 —— 多一行导航)、
> main(keyed —— 那一行必须对应一格,用一个新 key 就是加法)、
> shell.overlay(全窗口浮层 —— 弹窗挂在这里才盖得住整个框架)。
> 图标由宿主画,我们只交一个 currentColor 线框 SVG,
> 所以选中态、配色、留白都和官方一致;弹窗配色走 --dsw-alias-* 主题变量。

入口二:让 agent 调用 remote_connect

连到 WSL 的 Ubuntu-24.04,远程目录 /home/user/我的项目

agent 会调用 remote_connect(kind 为 ssh / wsl / docker),
然后把返回的锚点目录告诉你。

连上之后(两个入口都一样)

  1. 把返回的锚点目录作为工作区打开
  2. 在那个工作区里新建会话 —— 预设只能在会话第一轮之前选定

> 这一步不能省:旧会话已经定型了。漏了它,你会发现命令还是跑在本机。

关于「模式」:列表里为什么会多一个「远程模式」

新建会话时可以选模式(标准 / PTC / 极简 / 创造)。连上远程之后,
列表里会多出一个「远程模式」 —— 那不是另一种功能,而是远程会话的载体:

  • DSH 要求一个会话的插件组合来自一个已注册的预设;
    插件要把会话切到「文件与命令都在远程执行」,就必须先注册这么一个预设
  • 它的功能与标准模式逐项对齐(读/写/编辑、命令、搜索、终端、计划、目标、技能、
    后台任务、AGENTS.md 全都有)—— 差别只在「底下的文件系统与命令执行换成了远程版」
  • 它排在最后,是因为连接时才注册(前四个是 DSH 开机就有的)
  • DSH 没有「注册但不显示」的开关,所以它一定会出现在列表里

名字固定叫「远程模式」,「是哪台机器、项目在哪」写在它下面那行说明里:

远程模式
WSL docker-desktop · /root/.docker/desktop      ← 发行版/容器/主机 · 项目根

> 为什么名字不拼目标:拼出来是 远程:<派生 id>(WSL <发行版>),
> 而派生 id 又长又没信息量,会把真正有用的部分挤出显示宽度(实测被截断成
> 远程:wsl-root-docker-desktop(WSL docker-de)。现在把目标放进说明里,整行都是它的。

你不用管它。 在那个远程工作区里新建会话时,插件会自动把会话切到它:

会话创建 → 工作目录在某个远程工作区里吗?
├─ 不在 → 什么都不做(本地会话完全不受影响)
└─ 在   → 切到该工作区的远程预设 → **回读确认**真的生效
→ 失败就拒绝这一步并报错,**绝不让你在本机跑**

> ⚠️ 所以:在远程工作区里选别的模式会被切回来 —— 这是故意的。
> 不切的话,那个会话的文件读写会落在本地镜像上:
> 你以为在改远程的代码,其实改的是本地那份副本(改了、以为生效了、远程根本没变)。

工作区的名字形如 ssh:my-proj、wsl:test-proj —— 后端 + 最后一层目录名。
(完整路径不挤进名字里:选目录那一步的弹窗里已经显示过。)

安装

用自带安装器(推荐)

node scripts/install.mjs --profile <你的 profile>

安装器会按顺序做完三件事,并把每一步的结果打出来:

  1. 往你的 profile 写入 pnpm 构建脚本表态(本插件零原生依赖,见下)
  2. 调用 dsh plugin --profile add @jk-uzi/dsh-multi-remote
  3. 回读校验插件真的被登记进了 dsh.profile.bundles,没登记就非零退出

> 为什么需要第 1 步和第 3 步:pnpm 11+ 默认拒绝任何「没提前表态」的依赖构建脚本,
> 并且以非零退出码失败;而 dsh plugin 只在安装成功时才把插件登记进 bundle 栈。
> 结果是包装进了 node_modules、却永远不会被加载,而且没有任何提示。
> 安装器就是用来堵这个洞的。

手动安装

dsh plugin --profile  add @jk-uzi/dsh-multi-remote

手动装完之后请确认 dsh.profile.bundles 里有 @jk-uzi/dsh-multi-remote。
没有的话插件不会生效。

从源码(开发用)

git clone https://github.com/jk-uzi/dsh-multi-remote.git
dsh plugin --profile  add "link:$PWD/dsh-multi-remote"

卸载

dsh plugin --profile  remove @jk-uzi/dsh-multi-remote

使用

连上一台机器,然后用 agent 的常规工具干活。

SSH

> 连接 user@example.com:22,项目根 /home/user/proj,用 ~/.ssh/id_ed25519

(调用 remote_connect 工具,kind='ssh')

已连接 …(user@example.com:22)
远程项目根:/home/user/proj
本地镜像锚点:<本地锚点目录>/mr-…
预设:multi-remote-…(可用)

下一步:把上面的「本地镜像锚点」作为工作区打开,然后新建会话。

> SSH 掉线了怎么办? 长连接会被网络抖动、服务端重启 sshd、NAT 表项过期打断。
> 断掉之后插件会自动重连一次,通常你不需要做任何事。
> 重连时 host key 校验照旧生效(不会因为重连就放行陌生主机)。

WSL

> 连上本机的 Ubuntu-24.04,项目根 /home/user/proj

(调用 remote_connect 工具,kind='wsl', distro='Ubuntu-24.04')

已连接 …(WSL Ubuntu-24.04)
远程项目根:/home/user/proj
本地镜像锚点:…
预设:multi-remote-…(可用)

> WSL 不需要任何凭据 —— 它是本机进程。用 wsl -l -q 可以列出可用发行版。

Docker

> 连上容器 my-app,项目根 /app

(调用 remote_connect 工具,kind='docker', container='my-app')

已连接 …(容器 my-app)
远程项目根:/app
本地镜像锚点:…
预设:multi-remote-…(可用)

> Docker 不需要任何凭据 —— 它连的是本机守护进程。用 docker ps 看有哪些容器在跑。
> 只连已运行的容器,不会替你创建或启动。

> Docker Desktop 重启过怎么办? 引擎重启会让旧连接失效,插件会自动重连一次,
> 通常你不需要做任何事。但注意引擎重启会把容器也停掉 —— 此时报错会说清
> 「容器没有在运行」并提示 docker start,而不是丢一个看不懂的错误给你。

> ⚠️ 用户流程有硬约束:必须先选远程工作区(= 锚点目录)、再新建会话。
> 远程预设只能在会话第一轮开始之前选定,反过来换不了。
> 走反了的话,插件会拒绝这一步并明确报错,而不是让命令静默落在本机。

工具

工具 作用
remote_connect 连接一台机器,建立本地镜像 + 注册远程预设
remote_profiles 列出 / 删除已保存的连接档案(list / delete)
remote_list 列出当前已连接的远程工作区
remote_disconnect 断开(本地镜像保留,重连后界面立刻有内容)
remote_refresh 重新拉取远程目录结构到本地镜像

凭据

  • 连接档案只保存非敏感字段(主机、端口、账号、路径、私钥路径)
  • 口令与私钥内容永不落盘,每次连接现给
  • 档案文件权限 0600

设置

设置 → 远程开发 里可以直接改这几项(不用编辑配置文件):

项 说明 默认
连上之后在后台补拉镜像 把「文本类 + 上限内」的文件补到本地镜像,界面里点开就有内容 开
后台补拉的单个文件上限 只管后台补拉那一趟(MiB)。首轮遍历另有一套更小的常量,不受这项影响 2
后台补拉的总量上限 同上(MiB) 64
审计日志条数上限 GET /multi-remote/audit 的环形缓冲容量 500

> 想彻底关掉插件? 用 DSH 自己的插件开关(插件管理器里关掉它,
> 或往 profile 的 cordis.patch.yml 写 disabled: true)—— 宿主会整行不加载。
> 我们不自造第二个「显示 / 隐藏入口」的开关:既和宿主重复,又半残
> (客户端半边跑在浏览器里,改了配置要刷新页面才生效)。

> ⚠️ 保存后会重载插件:已连接的远程工作区会断开,重新连一次即可。
> 这是宿主 configEditor 的正常行为 —— 配置变更走 Loader 重新应用。

改动不自己写文件:走宿主的 configEditor 服务(校验 + 持久化 + 重新应用),
落点是 profile 的 cordis.patch.yml 里一条 id: multi-remote 的定向覆盖。

> 如果那个 profile 没有 configEditor 服务(精简 profile),这一页会如实说明改不了,
> 并给出手工改 cordis.patch.yml 的办法 —— 不会假装有个能用的开关。

本地开发

不要动你日常在用的 profile。 用独立的 DSH_HOME 建一个隔离 profile:

# 1) 找一个仓库外的目录当隔离 DSH_HOME
export DSH_HOME="$HOME/.dsh-multi-remote"        # Windows PowerShell: $env:DSH_HOME = "$HOME\.dsh-multi-remote"

# 2) 从内置模板建一个隔离 profile
dsh --profile dev --from-default-profile web --dump-config

# 3) 挂载本仓库
dsh plugin --profile dev add "link:$PWD"

# 4) 启动
dsh --profile dev --no-open --port 19388

> 本仓库无构建步骤——宿主直接加载 src/*.js,改完代码重启 profile 即可生效。

自检

检查 期望
GET http://127.0.0.1:19388/multi-remote/ping {"ok":true,...},含已连接工作区
GET http://127.0.0.1:19388/multi-remote/selfcheck 5 个工具 registered: true、visibleToModel: true,并报告三种后端各自的可用性
GET http://127.0.0.1:19388/multi-remote/workspaces 已连接工作区的安全描述(不含凭据)
GET http://127.0.0.1:19388/multi-remote/audit 审计日志(?limit= / ?event= 过滤,?clear=1 清空)

审计日志

记面向操作的轨迹:连过哪些机器、成没成、失败原因、栅栏拒绝(安全事件)。

三条约束:有界(环形缓冲,默认 500 条,超界会报 dropped)、
绝不落凭据(统一脱敏 —— 字段名、错误信息、连 URL 里的 ?token= 都会抹掉)、
绝不抛错(审计坏了不能让连接失败)。

curl 'http://127.0.0.1:19388/multi-remote/audit?limit=20'
curl 'http://127.0.0.1:19388/multi-remote/audit?event=connect-failed'
curl 'http://127.0.0.1:19388/multi-remote/audit?clear=1'

自检最有用的部分是 backends 那一段 —— 它先回答「这台机器上哪种后端能用」:

{
"ssh":    { "status": "client-ready", "detail": "客户端可用;能不能连上取决于目标 sshd 与账号" },
"wsl":    { "status": "available", "detail": "找到 2 个发行版", "distros": ["Ubuntu-24.04"] },
"docker": { "status": "available", "detail": "守护进程 29.8.1,API 1.56",
"endpoint": "\\\\.\\pipe\\dockerDesktopLinuxEngine" }
}

status 的取值:available / unavailable / unsupported / client-ready / unknown。
探不到时会带上原始错误,不会只说一句「失败」。

> SSH 那条永远只说「客户端可用」,不会说「你的服务器连得上」——
> 自检不该要凭据,也不该在你没让它连的时候发连接。
>
> 探测默认开启(三个并行,实测约 50 ms)。脚本里只想要工具状态可以加 ?backends=0 跳过。

跑测试

node --test          # 静态闸门 + 镜像层 + 预设 + transport + 安装器

其中 SSH / WSL / Docker 的端到端测试需要真机,默认跳过:

# SSH(需要一台能登录的机器)
DSH_MR_SSH_TEST=1 \
DSH_MR_SSH_HOST= DSH_MR_SSH_PORT= DSH_MR_SSH_USER= \
DSH_MR_SSH_KEY=<私钥路径> DSH_MR_SSH_SANDBOX=/tmp/dsh-mr-e2e \
node --test

# WSL(需要 Windows + WSL2)
DSH_MR_WSL_TEST=1 DSH_MR_WSL_DISTRO=Ubuntu-24.04 \
DSH_MR_WSL_SANDBOX=/tmp/dsh-mr-wsl-e2e \
node --test

# Docker(需要一个已在运行的容器)
DSH_MR_DOCKER_TEST=1 DSH_MR_DOCKER_CONTAINER=<容器名> \
DSH_MR_DOCKER_SANDBOX=/tmp/dsh-mr-docker-e2e \
node --test

> 端到端测试只会在 *_SANDBOX 指定的远程目录里读写,不会碰其他文件。

结构

路径 作用
src/index.js 宿主半边入口:组装各层、注册 remote_* 工具与自检路由
src/diagnostics.js 后端可用性探测(自检里的 backends 那一段)
src/audit.js 审计日志:有界、脱敏、绝不抛错
src/transport/ Transport 契约 + 三个后端:SSH(ssh.js)/ WSL(wsl.js)/ Docker(docker.js)+ 最小 tar(tar.js)
src/mirror/ 锚点目录的只读镜像(格局层 / 照片层 / 路径围栏 / git 基线)
src/session/ 连接档案、连接管理、预设注册(preset.js:单一「远程模式」预设)、会话绑定、工作区路由(workspace-routes.js:路径→连接)
src/session/plan-mode-section.js 计划模式的提示词段(由 scripts/sync-plan-mode-section.mjs 生成,别手改)
src/world/ 隔离域内的 provider:fs / shell / search(远程 glob/grep)、终端后端与工具的挂载点(terminal.js);按路径动态路由(见 session/workspace-routes.js)
src/terminal/ 交互式终端:与后端无关的会话机械(session.js)、三个后端的 PTY(backends.js)、宿主 TerminalBackend 适配(backend.js)、模型工具(tool.js)
src/http/fence.js HTTP 路由的 Host / Origin 栅栏(fail-closed)
src/client.js 客户端半边:设置页小节(文案走宿主 i18n,中英双语)
scripts/install.mjs 安装器(构建脚本表态 + 安装 + 回读校验)
scripts/sync-plan-mode-section.mjs 从宿主的默认预设同步计划模式提示词段

依赖

只有一个运行时依赖:ssh2(纯 JavaScript)。

它的可选原生加速 cpu-features 被显式拒绝构建(见 pnpm-workspace.yaml):
允许它会让没有 C++ 工具链的用户直接装不上,换来的只是一点特性探测。
所以本插件零原生依赖,任何平台都能直接装上。

兼容性与测试矩阵

宿主与运行时

项 要求 实测于
DSH 见 peerDependencies(@deepseek-ai/dsh-tools >=0.2.0-rc.2 <0.3.0) 0.2.0-rc.2
Node >=20(engines) v24.14.0
插件主机 Windows / macOS / Linux Windows 11 25H2
目标环境 POSIX shell(原生 Windows 远端不在范围) Ubuntu / Debian / Alpine

三个后端各自的前置条件

后端 需要什么 不需要什么 可用平台
SSH 可达的 sshd + 一个能登录的账号 远端不装任何东西(无 DSH、无 API key、不联网) 全部
WSL Windows + WSL2 + 一个发行版 凭据、网络、远端安装 仅 Windows
Docker 可达的 Docker 守护进程 + 已在运行的容器 docker CLI(我们直连 Engine API)、凭据 全部(按平台自动选端点)

Docker 的端点按平台解析:Windows 用命名管道(dockerDesktopLinuxEngine → docker_engine),
类 Unix 用 /var/run/docker.sock → /run/docker.sock;DOCKER_HOST 显式给出时优先。
tcp:// 与 ssh:// 不在支持范围(需要 TLS 与额外协议),会明确报错而不是假装能连。

> WSL 的交互式终端额外需要发行版里有 util-linux 的 script
> (用来分配 PTY)。没有的话终端会明确报错,其他功能不受影响。

目标环境的实测覆盖

目标 文件读写 命令执行 交互式终端
真实 OpenSSH 服务器(Linux,有登录 banner) ✅ ✅ ✅ PTY /dev/pts/N、resize 生效
OpenSSH 服务器(容器夹具,CI 可复现) ✅ ✅ ✅ PTY /dev/pts/0、resize 生效
Ubuntu-24.04(WSL) ✅ ✅ ✅ PTY /dev/pts/N
node:22-bookworm-slim(Docker) ✅ ✅ ✅ PTY /dev/pts/N
alpine:3.20(Docker) ✅ ✅ 未测
scratch(无 shell、已停止) ✅ 内容读写仍可用 ⛔ 明确报错 ⛔ 明确报错

> 真机比夹具多测出三件事(夹具环境太干净,这些都不出现):
> 登录 banner、中文 motd 造成的终端折行、以及 shell 启动期间的就绪竞态。
> 其中就绪竞态是个真 bug,已修(见 CHANGELOG)。

> alpine 上实测发现 busybox 的 find 没有 -printf、stat 没有 --printf,
> 所以内部脚本用的是两者都支持的写法(见 CONTRIBUTING §4.11)。

> 交互式终端的窗口大小变更:SSH / Docker 支持;WSL 不支持
> (util-linux 的 script 没有这个能力),resize 是空操作 —— 如实的能力差异。

> 交互式终端首次发送前会先等登录 banner 打完再写命令
> (否则命令输出会被 banner 的间隙吞掉)。已经安静的终端几乎不增加延迟;
> 一直不安静也会照常发送,并在结果里如实标 readyReason: 'not-quiet-yet'。

实测过的宿主版本

组件 版本
DSH 0.2.0-rc.2
Node v24.14.0
宿主 OS Windows 11 25H2(build 26200.9457)
WSL 2.7.3.0 / kernel 6.6.114.1-1 / Ubuntu-24.04
Docker Desktop 4.93.0 / Engine 29.8.1 / API 1.56

> 上表是实测过的组合,不是支持范围的下界。engines 声明的是 node >=20;
> 其他平台(macOS / Linux)上 SSH 与 Docker 应当可用,但没有实测过 ——
> 按本项目惯例,没测过的就标成没测过。

测试怎么跑

node --test                      # 全部单元与契约测试(不需要任何外部环境)

真机端到端测试默认跳过,按环境变量开关(见下一节)。当前规模
(2026-10-13 复核:node --test → 521 通过 / 14 跳过 / 0 失败):

类别 数量
单元与契约测试 521
真机端到端(默认跳过) 14
合计 535

> SSH 的多数测试不需要靶机:断线重连那组用 ssh2 自带的 Server 在进程内
> 起一个真 SSH 服务端(真握手、真认证、真断线),所以不需要网络也不需要 Docker,
> 已经算在上面「单元与契约测试」里。只有「容器里跑 sshd」那组真机端到端默认跳过。

> ⚠️ 同时打开多个真机端到端时请加 --test-concurrency=1:
> Node 的测试运行器默认并行跑不同测试文件,而 wsl.exe 在并发下会明显退化
> (见 CONTRIBUTING §4.6),会把 Docker 的用例拖到超时。
> 实测:两个都开 + 默认并发 → Docker 用例 32 秒超时;--test-concurrency=1 则通过。
> 这不是代码问题,是测试环境互相干扰。

贡献

欢迎参与。动手前请先读 CONTRIBUTING.md——里面写了开发环境、
插件 API 契约,以及几个很容易踩的坑。

许可证

MIT

常见问题

7 问
答案由本站依据条目字段整理,不引用上游原文
dsh-multi-remote 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add @jk-uzi/dsh-multi-remote` 即可。对应的 npm 包名是 `@jk-uzi/dsh-multi-remote`。

dsh-multi-remote 的验证等级是什么意思?

未标注验证等级。上游未给出验证结论,安装前请自行确认

dsh-multi-remote 安全吗?

未标注。

dsh-multi-remote 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-multi-remote 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

dsh-multi-remote 有哪些功能?

SSH / WSL / Docker 三后端、文件与命令自动落到远端、远程真 PTY 交互终端、glob / grep 在远端执行、本地有界只读镜像。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

会话与消息
按星标排序,可作替代方案

dsh-desktop

dsh-desktop

为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。

L3 · 安装规范通过 3.0 万 星

openpets

openpets

L4 · 沙盒安装通过 1,274 星

deeptide

deeptide

L4 · 沙盒安装通过 1,104 星

jingyun-dsh

jingyun-dsh

井云 DSH 客户端插件,为 DeepSeek Harness 注入会员登录、订阅支付、算力管控与应用市场,让智能体和技能快速变成可交易商品

L3 · 安装规范通过 1,004 星

study-mate

study-mate

StudyMate 是 DSH 的「学习模式」预设与技能包,为数学、计算机科目定制学习路线、讲解课件与练习评估,跨科目共享记忆。

未标注验证等级 856 星

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。