packages/dsh-remote-web-ui
zhu1090093659/dsh-web手机/PC 远程操控 dsh web 工作区:扫码配对、令牌门控通道、SSE 实时同步,提供移动端与完整桌面 GUI 两种远程形态。
仅内网的远程访问:手机或另一台电脑通过扫码或令牌接入同一份 DSH Web 界面,并可选内网免密钥直连。
内网配对远程访问插件,用于 DSH(DeepSeek Harness):让手机或另一台电脑通过扫码 / 配对令牌接入同一份 DSH Web 界面,并且可以选择让内网设备无需密钥直接打开界面。
本插件由 @linxin666/dsh-remote-web-ui 0.4.4 改造而来,已彻底移除全部公网功能,只保留内网场景。
上游提供公网访问能力(Cloudflare 隧道等)。本插件把这些全部删除,只做内网:
| 已移除 | 说明 |
|---|---|
| Cloudflare 快速隧道 / 命名隧道 | 含 cloudflared 依赖、tunnelToken、autoTunnel 配置 |
| dsh-market 固定域名中继 | relay 注册与身份文件 |
publicBaseUrl 与公网状态帧 | 含面板上的公网地址单选与角标 |
| 每日匿名遥测上报 | 上游会向 dsh-market.com 上报心跳,已改为惰性空函数 |
0.0.0.0,并维护主机防火墙放行规则本插件以「本地包」形式装入 DSH profile。以 desktop profile 为例:
把本仓库放进 profile 的依赖目录:
<DSH_HOME>/profiles/<profile>/node_modules/dsh-lan-pair/
在该 profile 的 package.json 中登记依赖与 bundle:
{
"dependencies": {
"dsh-lan-pair": "file:./node_modules/dsh-lan-pair"
},
"dsh": {
"profile": {
"bundles": [
// ... 其他 bundle
"dsh-lan-pair"
]
}
}
}
重启 DSH。插件代码位于 node_modules 下,而 DSH 的热重载会忽略该目录,因此改动插件后必须重启才能生效。
在 profile 的 cordis.patch.yml 中配置插件行:
- id: lan-pair
name: "dsh-lan-pair"
config:
lanBind: true # 把 Web 服务绑定改写为 0.0.0.0,并维护防火墙规则
allowLanWithoutKey: true # 内网设备无需配对/令牌直接打开界面
maxDevices: 4 # 已授权设备上限(默认 4,最大 64)
idleExpireMs: 2592000000 # 设备空闲过期(毫秒),默认 30 天
# requirePairingForLan: true # 默认 true,通常无需显式设置
也可以在 DSH 的设置卡片里图形化调整这些开关。
内网免密钥的实现依赖门控的 /remote 通道——只有它会把内网请求送到 harness,并附上进程自身的凭据。因此:
allowLanWithoutKey: true 时,插件会强制保留该通道,与 requirePairingForLan 取值无关;/api,被 harness 的信任围栏挡为 403。这一点在实现里已做兜底,不会出现「界面能打开、但所有 API 全废」的情况。
allowLanWithoutKey: true 意味着同一内网内的任何设备都能直接打开完整的 DSH Web 界面,其权限等同于该 DSH 实例本身的权限(若你的 profile 是 danger-full-access,则等同于完整控制权)。
在不可信网络(公共 WiFi、合租网络)中请关闭该开关,改为必须扫码配对。关闭后配对闸门立即恢复。
lib/*.js),不含 TypeScript 源码。产物为未压缩 ESM,保留了 //#region 标记与完整注释,可直接阅读与修改。lib/index.js)与 Client 半(浏览器 bundle,lib/client.js)。/ 路由以支持内网免密钥:内网来源直接获得注入好的应用外壳,其余来源原样交回 harness 的 fallback,因此桌面端行为完全不受影响。lib/invariant.js 是不变量伴生插件,需要 composition 挂载 @deepseek-ai/dsh-invariants 才会运行。DSH 桌面版默认的 dsh-base / dsh-web-app 两个 bundle 都不挂载该服务,因此这条检查在桌面版下不会执行;它只在自定义 composition(如 dsh-sdk-minimal)下生效。本仓库是唯一权威来源。若你把插件装进 profile 的 node_modules 并由其他工具(如 dsh-purge)改写过该副本,副本会与仓库产生差异。差异只影响运行时,不影响本仓库;要回到权威状态,用本仓库覆盖副本后重启 DSH。仓库中的 lib/index.js 已经包含 stripManagedBlock 保留外来行的修复,不需要任何外部补丁再改一次。
lanBind: true 时插件会通过 netsh(Windows)维护一条入站放行规则,规则名为 lan-pair (auto),参数为 dir=in action=allow protocol=TCP localport=<端口> profile=private,domain。状态可从 /api/pair/lan-bind 的 firewall 字段读取:
{ "ok": true, "managed": true, "note": "netsh" }
这一步需要管理员权限。 若 DSH 以普通权限运行,规则写入会失败,字段返回 ok: false,而 Windows 防火墙默认阻止未匹配的入站连接——此时同内网的其他设备打不开界面,但本机访问自己的局域网 IP 仍然正常,容易误判为「已经连通」。
要判断是否真的放行,应看 firewall.ok,而不是从本机访问自己的局域网 IP。修复方式是以管理员身份启动一次 DSH(插件会自动补上规则),或在管理员终端里手工执行:
netsh advfirewall firewall add rule name="lan-pair (auto)" dir=in action=allow protocol=TCP localport=19387 profile=private,domain
注意规则名必须与插件一致。若手工用了别的名字,插件检测不到,firewall.ok 会一直为 false。
Apache-2.0,见 LICENSE。
Copyright 2026 Hughes
本项目基于 @linxin666/dsh-remote-web-ui 0.4.4 改造,其原始许可证一并保留在 LICENSE 中。
LICENSE末尾的Copyright [yyyy] [name of copyright owner]属于 Apache-2.0 的 APPENDIX 教学示例,按标准做法原样保留、不填写。