dsh-roam
把电脑上正在运行的 DeepSeek Harness 会话带到手机:手机浏览器扫码即用;已经装了 AI-HUB App 的,用同一个地址、同一个配对码接入。不用换 DSH 发行版,不用把会话搬到云端。
它解决什么问题
DeepSeek Harness 官方版把工作台放在电脑上,人一离开电脑,正在跑的会话就断了。社区版虽然自带手机远控,但要用它就得换一套发行版;AI-HUB 的原生 App 体验更好,又需要单独安装 dsh-mobile-plugin,还要维护中转和另一套配对方式。
dsh-roam 把这两条路合并成一个官方 DSH 插件:
- 不装 App 也能用:手机浏览器扫码,直接看会话列表、继续对话、新建会话、切换模型、发送和取消。
- 装了 AI-HUB 更好用:同一个公网域名、同一个 6 位连接密码,原生 App 直接配对;局域网内也能扫码配对。
- 不绑定中转账号:局域网直连;公网可以用 Cloudflare 临时隧道,也可以接自己的固定域名和 frpc。固定域名可申请 Let's Encrypt 证书并在到期前自动续期。
- 默认不敞开门:设置面板只接受本机回环请求;局域网二维码带一次性令牌;公网入口必须输入连接密码;每台 AI-HUB 设备有独立凭据。
它不是远程桌面,也不复制整个 DSH 桌面:手机端是一条为会话操作设计的轻量通道,设置、插件、终端、文件管理仍然留在电脑上。
和同类项目的区别
| 能力 | dsh-roam | AI-HUB 原插件 | 浏览器远控类插件 | DSH 社区版手机远控 |
|---|---|---|---|---|
| 手机浏览器零安装 | ✅ | ❌ | ✅ | ✅ |
| AI-HUB 原生 App | ✅ 共用地址和配对码 | ✅ | ❌ | ❌ |
| 官方 DSH 插件形态 | ✅ | ✅ | 多为独立服务 | ❌ 需要换发行版 |
| 固定域名 + 本机证书 | ✅ | 依赖中转 | 视实现 | 视实现 |
| 设备台账 / 单独移除 | ✅ | ✅ | 有限 | 视实现 |
| 复用旧 AI-HUB 身份与设备 | ✅ | — | ❌ | ❌ |
一句话:dsh-roam 是官方 DSH 的“本地优先移动接入层”——浏览器和 AI-HUB 是两种客户端,局域网和公网是两种到达方式,配对、证书和设备数据都留在这台电脑上。
快速开始
要求:DeepSeek Harness 0.2.x、Node.js 22.19+,电脑和手机在同一 Wi-Fi(首次配对)。
安装插件(npm 发布后):
dsh plugin --profile web add dsh-roam@0.2.2本地开发时也可以在 profile 里用
link:指向仓库目录,改完代码执行pnpm build后重载插件。重启 DSH,打开 设置 → 连接手机。
手机用相机或浏览器扫面板上的二维码。二维码 5 分钟内有效,过期会自动换一张。
手机浏览器里选择会话,直接继续。
第一次打开时如果只想在局域网用,不需要做任何公网配置。
用 AI-HUB App 连接
AI-HUB 和浏览器共用同一个 6 位连接密码。
- 在面板里点 AI-HUB App 标签页。
- 没有固定密码时先点 设为固定,保存 6 位数字。AI-HUB 只接受固定密码;浏览器仍可使用临时随机密码。
- 同一 Wi-Fi:扫 AI-HUB 标签页里的二维码,或在 App 里手动填
http://电脑局域网IP:端口,配对码填面板上的 6 位数字。 - 外网:在 App 里选
https,地址填面板上的公网地址(例如https://dsh.example.com),配对码相同。
AI-HUB 的配对二维码里包含固定密码,不要截图外发,也不要在投屏时展示。
公网访问
两种方式,任选一种:
临时隧道:面板里没有固定域名时,点 开启临时隧道。插件优先使用 cloudflared 快速隧道,失败时切到 pinggy。地址每次开启都会变化,适合临时外出使用。
固定域名:有自己的域名和 frpc / SakuraFrp 时,填 https://你的域名 并保存。要求:
- 域名直接解析到隧道节点,不要套 CDN;
- 开一条 HTTP 隧道(80 端口)用于 Let's Encrypt 验证和跳转,一条 HTTPS 隧道(443 端口)指向本机
43128; - frpc 的「自动 HTTPS」填同一个域名,并在自定义设置里加
auto_https_mode = http; - 面板里点 申请证书,插件会把
<域名>.crt/<域名>.key写进 frpc 工作目录。证书 90 天有效,剩 30 天时自动续期;续期后需要重启隧道才会加载新证书。
固定公网地址只接受 https://。公网入口的密码、会话内容和设备凭据都不应该走明文 HTTP。反向代理必须保留原始 Host:插件按 Host 判定公网入口,Host 被改写会让入口降级为局域网。
安全边界
/phone-bridge/*管理接口只接受本机回环请求,并校验 Host 与同源;面板不会把管理接口暴露到公网。- 局域网二维码里是 32 字节一次性令牌,5 分钟有效,配对后作废。
- 公网入口必须输入 6 位连接密码;连续输错会触发限速。
- 每台 AI-HUB 设备单独签发凭据,移除设备会删除本机台账并断开它的事件流。
- 修改连接密码会让已连接的浏览器重新输入;已配对的 AI-HUB 设备凭据不会被自动吊销。
- 嵌入层只接受可吊销的设备凭据(
dshc_…);仅携带旧版无状态 Bearer token 的客户端会被拒绝,需要升级 App 或重新配对。移除设备后,该设备的凭据和事件流立即失效。
更强的隔离(例如把公网入口只暴露给指定设备、给移动 API 分权)仍在路线图上。在完成这些加固前,不建议把面板暴露在不可信网络,也不建议在多人共用的 Windows 账户下运行。
数据与网络
| 项目 | 位置 / 行为 |
|---|---|
| 数据目录 | %USERPROFILE%\.dsh\dsh-roam(设置 DSH_HOME 时跟随) |
| 设置 | settings.json |
| 连接密码 | mobile-pairing-pin.json,仅本机可读 |
| 设备台账 | mobile-devices.json |
| 兼容身份与设备凭据 | %USERPROFILE%\.dsh\relay.json、relay-device-credentials.json |
| 离线归属地库 | ip2region/,查询在本机完成,手机 IP 不发给第三方 |
| cloudflared | 首次开启临时隧道时下载到数据目录 |
| 端口 | 默认 43128,被占用时自动顺延 |
网络请求只发生在:开启临时隧道时(Cloudflare / pinggy)、申请或续期证书时(Let's Encrypt)、首次需要归属地时下载离线库(GitHub)。没有遥测,没有账号体系,不把会话内容上传到第三方。
常见问题
手机打不开二维码里的地址:确认同一 Wi-Fi、电脑防火墙放行实际端口,并确认手机没有连访客网络。端口不是 43128 时以面板显示为准。
公网一直转圈:多半是 cloudflared 下载失败,换网络或改用固定域名。临时隧道地址每次开启都会变,出门前重新扫一次。
二维码提示失效:令牌 5 分钟过期,面板会自动换码;也可以点「重新生成」。
AI-HUB 配对失败:确认保存了固定 6 位密码,协议和地址匹配(局域网 http、公网 https),并且没有在另一台设备上重复使用旧二维码。
改了密码后 AI-HUB 还在线:这是预期行为——改密码只影响浏览器会话;要移除 App 设备,请在「AI-HUB 设备」里操作,移除会吊销该设备的凭据。
开发
pnpm install
pnpm build # 清空 lib,tsc 编译 src/,client.js 原样复制
pnpm test # 先构建,再跑全部测试
src/是唯一源码:index.js(宿主入口)、client.js(设置面板,浏览器经典脚本)、bridge/*.ts(桥接、隧道、证书、移动 API)。lib/是构建产物,不提交、不手改。测试跑的是lib/,所以改完源码必须先构建。src/client.js不能加顶层import/export,否则设置页白屏。
发布前检查:
pnpm test
npm pack --dry-run
版本记录
许可证
MIT。第三方组件与许可证见 THIRD_PARTY_NOTICES.md。
No comments yet. Be the first to write one.