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

远程工作区 januory/dsh-remote-workspaces

DeepSeek Harnessv0.3.6
januory49 天前有提交已提供中文文档扫描:含敏感能力

通过 SSH 把远程主机目录当本地工作区打开

30.6/100
综合分
1
GitHub 星标
292
npm 周下载
—/5
用户评分

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-remote-workspaces
npm 源 · dsh-remote-workspaces 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · other
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/10/25·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/04·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 49 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

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

验证判据与等级说明 →

可信度证据

安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-remote-workspaces @ 0.3.6
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/13 15:40:39

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

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

读写/删除本地文件
查看扫描证据(共 38 处,展示前 35 条)
  • 读取本地文件
    src/index.js:241
    if (!existsSync(path)) return { ok: true, path, aliases: [] }
  • 读取本地文件
    src/transport.js:287
    if (!existsSync(configPath)) return []
  • 读取本地文件
    src/transport.js:288
    return parseSshConfig(readFileSync(configPath, 'utf8'))
  • 读取本地文件
    src/transport.js:715
    config.privateKey = readFileSync(this.identityFile)
  • 读取本地文件
    src/machine-store.js:57
    const hex = readFileSync(path, 'utf8').trim()
  • 写入本地文件
    src/machine-store.js:63
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    src/machine-store.js:64
    writeFileSync(path, key.toString('hex') + '\n', { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    src/machine-store.js:65
    try { chmodSync(path, 0o600) } catch {}
  • 读取本地文件
    src/machine-store.js:127
    if (!existsSync(path)) return []
  • 读取本地文件
    src/machine-store.js:129
    const parsed = JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    src/machine-store.js:141
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    src/machine-store.js:142
    writeFileSync(path, JSON.stringify({ machines: machines.map(encryptMachineSecrets) }, null, 2) + '\n', 'utf8')
  • 写入本地文件
    src/machine-store.js:143
    try { chmodSync(path, 0o600) } catch {}
  • 读取本地文件
    src/machine-store.js:154
    if (!existsSync(path)) return false
  • 读取本地文件
    src/machine-store.js:156
    const raw = JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    src/anchor.js:54
    mkdirSync(dir, { recursive: true })
  • 写入本地文件
    src/anchor.js:55
    writeFileSync(
  • 读取本地文件
    src/shell-exec.js:146
    const st = lstatSync(candidate)
  • 读取本地文件
    src/registry.js:22
    if (!existsSync(file)) return {}
  • 读取本地文件
    src/registry.js:24
    const parsed = JSON.parse(readFileSync(file, 'utf8'))
  • 写入本地文件
    src/registry.js:33
    try { mkdirSync(root, { recursive: true }) } catch {}
  • 写入本地文件
    src/registry.js:34
    writeFileSync(anchorsPath(), JSON.stringify(anchors, null, 2) + '\n', 'utf8')
  • 读取本地文件
    src/local-browse.js:44
    await access(root)
  • 读取本地文件
    src/local-browse.js:113
    return { name: dirent.name, dir: (await stat(join(target, dirent.name))).isDirectory() }
  • 读取本地文件
    src/local-browse.js:135
    const entries = (await readdir(target, { withFileTypes: true }))
  • 读取本地文件
    src/local-backend.js:40
    targetKey = await realpath(displayPath)
  • 读取本地文件
    src/local-backend.js:60
    async stat(target) {
  • 读取本地文件
    src/local-backend.js:62
    const st = await stat(target.targetKey)
  • 读取本地文件
    src/local-backend.js:70
    async lstat(path, opts = {}) {
  • 读取本地文件
    src/local-backend.js:74
    const st = await lstat(full)
  • 读取本地文件
    src/local-backend.js:85
    const text = await readFile(target.targetKey, 'utf8')
  • 写入本地文件
    src/local-backend.js:255
    await writeFile(tmp, content, 'utf8')
  • 写入本地文件
    src/local-backend.js:256
    await rename(tmp, targetKey)
  • 删除本地文件
    src/local-backend.js:258
    await rm(tmp, { force: true }).catch(() => {})
  • 读取本地文件
    src/containment.js:49
    return await stat(path, { bigint: true })
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

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

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

功能亮点

  • SSH连接远程主机
  • 远程目录作本地工作区
v0.3.42026-09-16
中文 | English 适配新版 DSH 的 Typert 契约,并让终端标签页更好认、可多开。 新增功能 · 终端标签页标题显示实际登录的 shell(POSIX 远端 bash/zsh、Windows 远端 PowerShell/cmd、本机 PowerShell/bash),连接中或探测不出时回退为「RW终端」。 · 体验优化 · 右侧标签栏的「Shell」标签页与开始页入口统一改名为「RW终端」,面板按钮提示同步为「新建 RW终端」。 · 问题修复 · 适配新版 DSH 的 Typert strict codec 契约(create() 工厂):修复设置页出现「Remote 命名空间挂载失败:typert: remoteWorkspaces/listMachines result strict codec has no create() factory」、远程工作区整个 Remote 命名空间不可用的问题。 · 面板的「+ 新建」、开始页入口与标签栏的加号现在每次都会新开一个终端标签页;此前它们只是把已经打开的那个标签页翻到前面。 Full Changelog: --- Adapt to the new DSH Typert contract, and make the terminal tab easier to identify and to open more than once. New Features · The terminal tab's title shows the live login shell (bash/zsh on a POSIX remote, PowerShell/cmd on a Windows one, PowerShell/bash for the local PTY), falling back to "RW终端" while connecting or when the probe cannot name the shell. · Improvements · Rename the right tab strip's "Shell" tab and its Start-page entry to "RW终端", including the pane button's tooltip ("新建 RW终端"). · Bug Fixes · Adapt to the new DSH Typert strict-codec contract (the create() factory): fixes the settings section showing "Remote 命名空间挂载失败:typert: remoteWorkspaces/listMachines result strict codec has no create() factory", which took the whole remoteWorkspaces Remote namespace down. · The pane's "+ 新建", the Start-page entry and the tab strip's add control now open a new terminal tab every time; previously they only revealed the tab already open. Full Changelog:
v0.3.32026-09-10
中文 | English 严格回收远程命令,并补上 Shell 标签页的图标。 新增功能 · 右侧标签栏的 Shell 标签页显示终端图标,与开始页一致,颜色随主题。 · 问题修复 · POSIX 远端关闭后台任务或超时后,不再留下仍在运行的进程树。 · 远端拒绝 exec 请求时不再静默丢输出,而是换一份等价载荷自动重试,失败时报出目标、阶段与尝试次数。 Full Changelog: --- Tighter remote command cleanup, plus the Shell tab's glyph. New Features · The Shell tab in the right tab strip shows its terminal glyph, matching the Start page and following the theme. · Bug Fixes · Closing a background job or hitting a timeout on a POSIX remote no longer leaves the process tree running. · An exec request the remote refuses no longer loses its output silently: it is retried with an equivalent payload, and a failure now names the target, stage, and attempt count. Full Changelog:
v0.3.22026-09-10
中文 | English 连接与路由的稳定性修复:复用连接、按会话路由、错误文案分读者。 问题修复 · 短连接按目标复用:run/execShell 与后台任务共享连接池,死掉的 SFTP 通道自动重开。 · 远程会话中的路径一律按该远端解释,无法归属该主机的路径明确报错,绝不静默落到本地执行。 · 连接失败统一报出「目标 + 阶段」(智能体英文 / 用户中文),远端不可达时也不再打断整个回合。 · 远端默认 shell 变化后自动重新探测,无需重启 DSH。 · 超时的 Windows 命令按自报 PID 回收整棵进程树。 Full Changelog: --- Stability fixes for connections and routing: shared connections, session-scoped routing, and error text split by audience. Bug Fixes · Reuse short-lived exec connections per target: run/execShell and background jobs share one pool, and a dead SFTP channel reopens automatically. · Resolve paths in a remote session in that host's namespace, and refuse a path that cannot belong to it instead of silently running it on the local host. · Report connection failures with the target and stage (English for the agent, Chinese for the user), and no longer abort the whole turn when the remote workspace is unreachable. · Re-probe the remote shell profile when the host's default shell changes, with no DSH restart. · Reap a timed-out Windows command's whole tree by the PID it self-reports. Full Changelog:
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
dsh-remote-workspaces 通过 SSH 把远程主机上的目录,像打开本地文件夹一样,作为DeepSeek Harness 的工作区打开工作。 它做了什么 远程目录一旦被打开为工作区,agent 的文件工具(read / write / edit /grep / glob)和 shell 命令都会直接落到远主机上执行,而不是本地镜像。这里没有镜像、没有同步:每个操作都在远端实时执行,而本地工作区仍保留 harness 自身的完整沙箱行为。 功能特性 - 把远程目录当作工作区打开 —— 浏览远程文件系统、选中目录,harness 会像对待本地目录一样接纳它;所有 I/O 都路由到远端。 - 多主机注册表 —— 增删改 SSH 主机(别名 / 主机 / 端口 / 用户 / 密钥或密码)。凭据在本地用 AES-256-GCM 加密落盘,绝不会回传到浏览器。 - ~/.ssh/config 导入 —— 列出已配置的别名并自动填充连接表单。 - 连接测试 —— 使用前先验证主机连通性。 - 透明的工具路由 —— read/write/edit 走 SFTP,grep/glob 在远端跑ripgrep,bash/pwsh 命令通过 ssh2 exec 执行。
展开完整文档(README 剩余 1 节)
dsh-remote-workspaces

通过 SSH 把远程主机上的目录,像打开本地文件夹一样,作为DeepSeek Harness 的工作区打开工作。

它做了什么

远程目录一旦被打开为工作区,agent 的文件工具(read / write / edit /grep / glob)和 shell 命令都会直接落到远主机上执行,而不是本地镜像。这里没有镜像、没有同步:每个操作都在远端实时执行,而本地工作区仍保留 harness 自身的完整沙箱行为。

功能特性

- 把远程目录当作工作区打开 —— 浏览远程文件系统、选中目录,harness 会像对待本地目录一样接纳它;所有 I/O 都路由到远端。
- 多主机注册表 —— 增删改 SSH 主机(别名 / 主机 / 端口 / 用户 / 密钥或密码)。凭据在本地用 AES-256-GCM 加密落盘,绝不会回传到浏览器。
- ~/.ssh/config 导入 —— 列出已配置的别名并自动填充连接表单。
- 连接测试 —— 使用前先验证主机连通性。
- 透明的工具路由 —— read/write/edit 走 SFTP,grep/glob 在远端跑ripgrep,bash/pwsh 命令通过 ssh2 exec 执行。路由由会话决定,而不是由路径写法决定:远程工作区内每条命令都在那台主机上执行,指向该主机上不存在路径的 workdir 会被拒绝,而不是落到本地执行。本地会话沿用 harness 自身的沙箱。
- 感知权限策略的远端写操作 —— harness 的文件策略同样作用于远程工作区:read-only 会拒绝 write/edit 和远程 shell 命令,workspace-write 把 write/edit 限制在远程工作区根目录(以及 /tmp)内、而远程 shell 命令需经 danger-full-access 审批后放行,danger-full-access 则交由 SSH 账号自身权限决定。

工作原理

bundle 分为宿主机侧(host)和浏览器侧(browser)两半:

- Host(src/index.js)—— 基于 ssh2 的 SSH/SFTP 传输、加密主机存储、分流文件系统(ctx.fs)与 shell(ctx.shell)provider、远程感知的grep/glob 工具,以及通过 Typert 暴露的 remoteWorkspaces Remote 命名空间。
- Browser(src/client.js)—— “远程工作区”设置页(按主机分组)以及一个“添加工作区”的选择器。

打开远程目录会创建一个锚点(anchor):一个被 harness 接纳为工作区身份的真实但为空的本地目录,外加一个记录其远程来源的元数据文件。注册表(anchors.json)把该锚点映射到远程主机与路径,所有文件/命令操作都据此查表路由到远端:

$DSH_HOME/remote-workspaces/
├── machines.json # 主机注册表(凭据加密落盘) ├── anchors.json # 锚点 → 远程来源 路由注册表 └── --/ # 每台主机的锚点 └── / # 每个远程路径对应一个空锚点 │ └── .dsh-remote-meta.json

远程完整路径会被编码进锚点目录名(路径分隔符和 Windows 非法字符变成 --),因此 /home/test 和 /data/test 会落到不同的目录(home--test vs data--test)。

环境要求

- 一个 DeepSeek Harness 安装(插件在运行时解析其宿主服务)。
- Node.js ≥ 18(harness 本身运行在 Node 22+)。
- ssh2 是唯一的传输依赖;不需要外部 ssh 命令。
- 远端主机需要 rg(ripgrep)以支持 grep/glob,以及 sha256sum(或shasum)用于写入后校验——二者缺失时都会优雅降级。

安装

从本仓库在线安装:

dsh plugin --profile web add github:januory/dsh-remote-workspaces

发布到 npm 后,也可以直接安装已发布的包:

dsh plugin --profile web add dsh-remote-workspaces

从源码安装:

git clone https://github.com/januory/dsh-remote-workspaces.git

cd dsh-remote-workspaces

pnpm install # 安装 ssh2 传输依赖

dsh plugin --profile web add .

卸载:

dsh plugin --profile web remove dsh-remote-workspaces

维护者注:npm 包名现为 dsh-remote-workspaces(早期 git 安装时的包名是 remote-workspaces);旧安装请先 dsh plugin --profile remove remote-workspaces,再按新名安装。

使用

1. 打开 设置 → 远程工作区。
2. 添加一台 SSH 主机(或从 ~/.ssh/config 导入),然后点 测试连接。
3. 在“添加工作区”流程里选择远程主机、浏览到某个目录并打开。harness 会把空锚点接纳为工作区,之后的读取、写入、搜索和 shell 命令都在远端执行。

Remote API

宿主通过 Typert 暴露 remoteWorkspaces Remote 命名空间,包含这些调用: listMachines、saveMachine、deleteMachine、listSshAliases、sshAliasDetail、testConnection、listRemoteDir、openRemoteWorkspace。

目录结构

src/ # DSH bundle 源码 index.js # 宿主入口(分流 fs/shell、搜索工具、Remote 命名空间) client.js # 浏览器入口(设置页 UI + 选择器) transport.js # ssh2 传输(SshClient、exec、sha256) routing-fs.js # 分流文件系统(远端 SFTP / 本地围栏) fs-sftp.js # SFTP 文件系统后端 local-backend.js # 本地文件系统后端 containment.js # 本地沙箱围栏 shell-exec.js # SshShellExecutor(远端 ssh2 exec / 本地 subprocess) search.js # 远程感知的 grep/glob 工具 anchor.js # 本地锚点布局(空目录 + 元数据) registry.js # anchors.json 路由注册表 machine-store.js # 主机注册表(加密落盘) ssh-config.js # ~/.ssh/config 解析 ssh-uri.js # ssh:// URI 解析与识别 errors.js # 错误码 cordis.patch.yml # DSH bundle patch(换入分流 provider) package.json # 包 + dsh 清单 test/ # 单元 + 集成测试

测试

纯单元测试(无需任何主机)可在任意环境运行:

pnpm test

集成测试需要访问真实 SSH 主机,且需先配置好主机注册表(默认使用注册表里的第一台主机,或别名为 test 的那台):

pnpm test:integration

发布(维护者)

发布完全手动触发、零输入:版本号直接取自 package.json,发布前先在 main 上提交改好的 version,然后 GitHub Actions → release → Run workflow 即可。工作流会自动执行:跑单元测试(npm test)→ 校验 v tag 尚未存在(防止重复发布)→ npm publish(带 provenance)→ 打 v tag 并推送 → 用 --generate-notes 创建 GitHub Release。

前提:在仓库 Settings → Secrets and variables → Actions 中配置名为 NPM_TOKEN 的 secret(npm automation token,或对该包有 publish 权限的 granular token);发布账号须是持有该包名的 npm 用户。

等价的手工流程:

npm login

npm publish --provenance

git tag "v$(node -p \"require('./package.json').version\")"

git push origin --tags

开源协议

MIT
预览分享卡片长什么样 ↓januory/dsh-remote-workspaces
分享 · DeepSeek Harness Hub
januory/dsh-remote-workspaces

通过 SSH 把远程主机目录当本地工作区打开

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