aijunjiang/dsh-remote-ssh--packages-ssh-gui ↗★ 0
dsh-ssh-gui
适用于 DSH 远程工作区的用户层:包含连接注册表、/dsh-ssh RPC 通道、远程目录浏览器及 React 侧边栏。
AI 分析
将 DSH 的工作区文件读写和命令执行路由到远程 SSH 主机上,本地仅保留界面与配置。适合需要进行远程开发、在多台远端服务器之间切换工作目录的开发者。
安装
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:aijunjiang/dsh-remote-ssh#5c713e4c726c046f2b5fec4c684791e1699b3de0&path:packages/ssh-gui说明文档
阅读完整 README ↗dsh-remote-ssh
Move the workspace's file IO and command execution onto an SSH target — while sessions, the web GUI, and
$DSH_HOMEstay on this machine. A DSH plugin set for remote development over SSH.
把 DSH 的工作区放到远端机器上:本机保留会话、浏览器界面与配置,文件的读写、命令的执行都发生在你指定的 SSH 主机上。侧边栏里管理连接、浏览远端目录,会话按路由在多台远端机器之间切换,互不干扰。
本文件面向使用者;设计取舍、契约与审计细节见 DESIGN.md 与 specs/。
它能做什么
| 能力 | 说明 |
|---|---|
| SSH 连接管理 | web GUI 侧边栏添加/测试/删除连接:密码、密钥、SSH agent、ProxyJump 跳板 |
| 远端目录浏览 | GUI 内浏览远端目录树,在任意目录建立工作区(不必手打 ssh) |
| 会话级路由 | 每个会话的工作目录决定“这台会话跑在哪台机器”:ssh:/// 或本地占位目录两种拼写等价;多台远端可同时并行 |
| 远端执行/文件(完整模式) | ctx.fs / ctx.subprocess 指向远端:命令、git、测试、构建、读写在远端发生 |
| Agent 引导(内置) | 路由会话的运行时上下文自动声明“你在哪台机器”,附使用指南、ssh_exec / ssh_route_status 工具与 DSH_SSH_* 环境变量,防止把远端当本地、把空占位当空项目 |
| 凭据驻留本机 | 密码与身份密钥只存在本机 DSH home;远端只看到你授权的账号 |
安装
前置:
- 本机:DSH(deepseek-harness)与 Node ≥ 22
- 远端:可 SSH 登录的账号,主机上有
python3与bash(helper 依赖)
仓库是多包 monorepo(包之间互相相对引用),所以发布安装走官方兼容的“整仓链接 + profile 自动注册”,装完重启即可,启动命令不用加任何参数:
git clone https://github.com/aijunjiang/dsh-remote-ssh
cd dsh-remote-ssh
# 一条命令:链接 4 个包 + 把 SSH GUI 用户层注册进 web profile
# (幂等,可重复执行)
node scripts/install.mjs
# 选项:--home | --profile (默认 web)| --remove(卸载)
# 然后照常启动,不加 --patch:
pnpm dsh web
安装脚本做了什么:把
packages/*用 junction/符号链接挂进/profiles/node_modules,并在/profiles/web/cordis.patch.yml末尾写入一段带管理标记的 GUI 用户层(每次启动自动应用)。卸载用node scripts/install.mjs --remove(同时移除段落与链接,不影响其它插件)。
启动形态:
# A.(默认,安装脚本注册的就是这层)SSH GUI 用户层:连接管理 + 远端目录浏览 +
# agent 路由身份/指南 + ssh_exec/ssh_route_status。本机 fs/subprocess 保持不变。
pnpm dsh web
# B. 完整远端工作区:本机文件与命令整体切到远端(另起实例跑,勿装在常用实例上)
export DSH_REMOTE_HOST=your-host
export DSH_REMOTE_USER=your-user
export DSH_REMOTE_PASSWORD=your-password # 仅首次;随后自动改用密钥
export DSH_REMOTE_CWD=/home/you/workspace
pnpm dsh web --patch /cordis.patch.yml
快速开始(GUI)
- 打开 web GUI,左侧 Connections 面板 Add 一个连接(目标 IP、账号、认证方式),Test 确认连通。
- 在 Connections 中进入该连接,浏览远端目录,在目标目录上“选择为工作区”。
- 以该工作区开一个新会话。
开出来的就是路由会话:运行时上下文会显示类似
This session's working directory is on SSH route
c1(amax@192.168.10.125:22); its remote absolute path is /home/haitang/JunHeAssemblyLine.
并附一段使用指南(何时用 ssh_exec、镜像目录不可信、路由断了先查 ssh_route_status、输出上限等)。直接说“看下这台设备的硬件”即可——agent 会用内置 ssh_exec 在远端执行,而不是本机。
Agent 侧已内置的能力
ssh_exec:把整段脚本作为一条command在远端 bash 执行。走插件自带的 ssh2/helper 通道——不要手搓本机 ssh.exe(Windows 受限沙箱下无法 spawn,且纯属绕路)。locale 固定C;输出上限 256 KiB/流,截断会标记;每条结果带结束哨兵校验:exit 0 + 空输出只有标了 sentinel-verified 才算真空,疑似丢输出自动重试一次并显式报错。ssh_route_status:查看当前会话的路由、目标主机、已知连接清单与路由清单文件;checkLive: true可做真实连通性探测。- 环境变量:路由会话的 shell 自带
DSH_SSH_ROUTE_ID / HOST / USER / PORT / REMOTE_CWD / ENDPOINT。 - 路由清单文件:
/dsh-ssh-routes.json——明文、无密钥,离线时也能查到“c1 是哪台机”。 - 读写语义自适应:完整模式下你的 read/write/glob/grep 直接打在远端;仅 GUI 层时它们仍是本机,指南会明说“远端文件用
ssh_exec里的cat/sed -n/ heredoc,绝不写本地占位目录”。
完整模式(把本地世界整体切到远端)
cordis.patch.yml(仓库根)做的是一次性切换而非叠加:
- 关闭本地
subprocess、fs-sandbox、sandbox、两套沙箱 shell、本地目录选择器与权限预设; - 挂上远端
fs-ssh、subprocess-ssh(含远端shell)与会话路由所需 GUI 层; sandbox-policy.workspaceRoot指向DSH_REMOTE_CWD。
环境变量:
| 变量 | 作用 |
|---|---|
DSH_REMOTE_HOST | 目标主机(必填) |
DSH_REMOTE_USER | 远端账号(必填) |
DSH_REMOTE_PASSWORD | 仅首次连接;随后自动置备密钥 |
DSH_REMOTE_PORT | 默认 22 |
DSH_REMOTE_CWD | 远端工作目录(默认 /root/workspace) |
DSH_REMOTE_RIPGREP | 可选:远端 rg 绝对路径(不设则自动探测) |
同一个目录只有一个出处:
cwd与sandbox-policy.workspaceRoot都从DSH_REMOTE_CWD派生,保证“文件与命令在同一个世界”。
安全模型(务必阅读)
- 远端只有账号权限做围栏。 完整模式下本机沙箱行被关闭:把命令与文件交给哪台机器,就是让 agent 以该账号的权限在那台机器上操作。请用专用账号 / 最小权限 / 定期轮换密钥,或经 ProxyJump 限定可达范围。
- 连接密码与密钥只存本机
/dsh-ssh-connections.json与身份目录;路由清单不含任何密钥。 - 仅 GUI 模式(A 启动)不动本机文件/命令世界,风险面小得多——先用它熟悉,再上完整模式。
限制(诚实清单)
- 仅 GUI 模式不切 fs/subprocess:文件/命令仍是本机,
dsh-ssh-routes/...只是占位目录(agent 指南会提示)。 - PTY 未实现:
spawnTerminal在远端连接上不可用(helper PTY 子面未完成),终端类功能暂不可用;普通执行不受影响。 ssh_exec单次调用串行执行;一次调用内可跑多条命令。- 远端
read无行号标注;大文件请用sed -n开窗。 - 执行远端命令的目标需要 Python helper(首次调用自动部署到该账号 home 下)。
目录结构(概览)
cordis.patch.yml # 完整模式组合(one-world 切换 + 远端行)
packages/
ssh/ # 连接 owner:认证阶梯、密钥置备、helper 通道与协议
fs-ssh/ # ctx.fs → 远端文件系统(单次往返列出、流式限长读、CAS 写)
subprocess-ssh/ # ctx.subprocess → 远端进程(真实 pid/pgid、树级终止、spill 落远端)
remote-argv/ # 远端 rg/grep argv 翻译
ssh-gui/ # GUI:注册表 /dsh-ssh RPC / 侧边栏 / React bundle + agent 体验
scripts/
install.mjs # 发布安装(链接进 profile loader 树)
build-gui-client.mjs # 重建 ssh-gui 的 client bundle(ssh-gui/lib)
test.mjs # 全部本地测试:node scripts/test.mjs
specs/ DESIGN.md # 契约、审计、设计依据(技术细节入口)
开发、测试、bundle 构建与设计依据见 DESIGN.md;与上游 fork 的差异见 specs/upstream-dsh-ssh-audit.md。连接侧边栏与目录浏览器为 UynajGI/dsh-ssh (MIT) 的 fork。