在侧边栏顶部加一行,点击后整页切换成另一台 DSH 主机的 Web GUI(通过回环端口访问),并在该行显示那台主机的会话状态(运行中、有新活动、正等你回答)。
安装
# npm 包(预构建)
dsh plugin --profile web add dsh-remote-dsh
# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)
dsh plugin --profile web add github:hutao562/dsh-remote-dsh
装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWED 或 ERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yaml 的 allowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。
README
English | 中文
A DeepSeek Harness (DSH) plugin. It adds a 「远程」 row at the top of the sidebar; clicking it turns the whole page into another host's DSH Web GUI. The row also carries a session-state dot for that remote — blue while it is running something, green when activity arrived since you last looked.
┌────────────┬──────────────────────────────────┐
│ DSH │ │
│ 🌐 远程 ●1 │ │
│ + 新会话 │ 另一台主机上的 DSH │
│ 会话列表… │ (整个页面都是它) │
└────────────┴──────────────────────────────────┘
实际长这样。侧边栏顶部那一行 —— 蓝色胶囊就是远端的状态点(这里远端正跑着东西,数字是会话数):

点开之后,整个页面都变成远端那台机器的 DSH:顶栏是插件的(返回 / 主机 / 添加 / 设置 / 连通状态),下面是它的 GUI,连侧边栏都是它的:

装
dsh plugin --profile web add dsh-remote-dsh
然后重启一次 DSH。 想跟 main 分支的话,换成 github:hutao562/dsh-remote-dsh 也一样。
用
- 在另一台主机上装好 DSH 并跑
dsh web(它会打印带?token=的 URL)。 - 把它映射到本机的回环端口:
ssh -L 3081:127.0.0.1:3080 you@remote-host - 侧边栏点「远程」→「+ 添加」→ 地址填
http://127.0.0.1:3081。 - 点「⚙」展开设置行,把远程
dsh web打印的 token 粘进去 →「配对」。
之后只要 cookie 没过期(默认 30 天)就直接进。cookie 能扛远程重启;但 token 是每进程生成的,重新配对要用当前这次的。
一条硬规则:必须是本地回环端口
远程 DSH 的会话 cookie 是 HttpOnly; SameSite=Strict,跨 site 的 iframe 连它的 index.html 都取不到,直接 401:
| 远程在浏览器里的地址 | 结果 |
|---|---|
http://127.0.0.1:<端口>(ssh -L,或 frpc stcp / xtcp + visitor) |
✅ 可用 |
https://remote.example.com(frps http/tcp 公网域名) |
❌ 401 |
http://100.x.y.z:3080(Tailscale IP 直连) |
❌ 403 + 401 |
即使用 FRP,也要用 stcp/xtcp + frpc visitor 模式映射成本地回环端口。 这样被控端一行配置都不用改。
原因、推论,以及确实需要公网域名时的做法 → docs/why-loopback.md
rail 上的状态点
| 颜色 | 含义 | 何时消失 |
|---|---|---|
| 琥珀 | 远端有会话卡在等你回答(批准 / 提问 / 计划评审) | 在那边答完 |
| 蓝 | 远端正跑着东西(含子代理) | 跑完 |
| 绿 | 自你上次打开远程视图之后,有会话跑完了一轮 | 打开远程即清零 |
| 红 | 读不到(该远端没装 peer) | 恢复后 |
配色和形状都取自远端侧边栏自己那套状态点 —— 蓝色就是会话列表里那个 8 格追逐动画,不是另画一个圆点。
展开时,状态是行最右端的计数胶囊(点 + 数字),和会话行的时间戳在同一条竖线上;侧边栏收起成 rail 时没有文字的位置,点就挂在图标右上角,计数留给 tooltip。
行上的「远程」两个字由外壳渲染,插件隔着 :has() 只定三样 —— UI 字族、14px、字重 500 —— 让它和「新会话」(14/500) 一个腔调,而不是像段正文。order: 1 把胶囊排到文字之后,所以文字回到文字列、胶囊落到行尾。
琥珀是唯一一个"看一眼不会消失"的状态 —— 它是阻塞,不是通知。点进远程视图就能看到那边弹出的批准框或提问,答完即灭。
绿点按会话计数:一个会话即便既被提示过、又刚跑完,也只算一个。
要让状态点工作,被控端也要装本插件并以 peer 角色运行。它只发布匿名计数(没有会话 id、标题或内容),而且不需要任何凭据 —— 这是它相比"本地保存 token"的关键优势。
角色配置、为什么不比时钟、以及唯一一处围栏放宽的范围 → docs/peer-status-badge.md
被控端还要做的配置
被远程访问的机器很容易被 DSH 判定成"本机工作站",于是几处面向它自己桌面的功能会打开:文件夹对话框弹在它的屏幕上、Open In 在它那边启动程序、每次启动在它桌面弹一个浏览器……这些都得在被控端关掉,否则你只会对着白屏和 401 猜。
一份可直接抄的清单(五组配置,附原因和验证方法)→ docs/remote-host-setup.md
文件
lib/index.js |
Node 半面:主机注册表、/api/remote-dsh 路由、回环围栏、存活探测 |
lib/client.js |
浏览器半面:手写 __ModuleLoader__ bundle,注册三个官方 slot |
cordis.patch.yml |
bundle 层插入行(走 dsh plugin add 时生效) |
docs/ |
上面链接的深度说明 |
.verify/host-pending.mjs |
Node 半面自检:pending 的记账与归因 |
.verify/client-smoke.mjs |
浏览器半面冒烟测试 |
没有构建步骤 —— lib/ 就是源码,改完即生效。
开发
npm install
npm test # 112 项断言
npm run test:host # 只跑 Node 半面:waterfall 记账、resolve / reject / 同步抛出、子代理归因
npm run test:client # 只跑浏览器半面:module loader 契约 + 真 React 渲染 + jsdom 真实点击
想在源码目录里改并让本机 DSH 立刻加载(首次插入即热加载,不需要重启)→ docs/implementation.md
已知限制
- 琥珀色只在被控端装了 v4 以上的 peer 时才出现。 旧版 peer 不上报
pending,不会因此变红,但也不会有琥珀。 - 接管时会盖住本地侧边栏,返回靠顶栏按钮;焦点进了 iframe 之后 Esc 会失效。
- 改
lib/index.js需要重启 DSH;lib/client.js的改动刷新页面即可。 - 只做"用起来",没做 agent 集成 —— 没有把远程主机暴露成模型工具。
其余取舍与实现细节 → docs/implementation.md
链接
同类插件
zhu1090093659/dsh-web#packages/dsh-remote-web-ui★ 9321
手机/PC 远程操控 dsh web 工作区:扫码配对、令牌门控通道、SSE 实时同步,提供移动端与完整桌面 GUI 两种远程形态。
zhu1090093659/dsh-web#packages/dsh-ssh★ 9321
SSH 远程运维面板:Web 终端、SFTP 传输、本地端口转发与一条命令并发集群执行,Agent 与面板共用同一份主机配置。
saya-ch/dsh-mobile★ 569
通过 Android App 或手机浏览器访问 DeepSeek Harness,支持安全局域网连接、远程访问、持久设备配对和可自定义移动界面。
liguobao/ds-harness-remote★ 516
DeepSeek Harness 多端远程访问:从手机、平板、浏览器或另一台电脑继续进行中的会话,端到端加密通道(Noise IK + 自适应 Relay/WebRTC 传输),设备授权管理;远程端仅开放 ApiProxy 能力,支持 dsh-file-viewer 只读文件预览,不提供 Shell、远程桌面或写入权限。
ZSeven-W/dsh-ios★ 337
在对话里直接操作 iOS 模拟器或 USB 连接的 iPhone:22 个 Agent 工具用于启动、构建、按无障碍标识或 OCR 文本驱动 UI、列表行操作与 SwiftUI 预览热重载,并附带可点击拖拽的流式侧边栏面板。
wenbin-wb/dsh-bridge★ 211
DeepSeek Harness 远程与移动端接入插件:提供局域网扫码直连、Cloudflare 与自建公网隧道,以及微信、QQ、飞书、Telegram 机器人交互,内置安全认证与访问控制。
社区评论
评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。