@feiyang666/dsh-mobile-remote 1.9.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/README.md +3 -2
- package/README.zh.md +6 -8
- package/RELEASE_NOTES.md +36 -43
- package/cordis.patch.yml +4 -1
- package/lib/client.js +1096 -1059
- package/lib/external.js +97 -8
- package/lib/index.js +143 -956
- package/lib/lanproxy.js +40 -10
- package/lib/password.js +245 -245
- package/package.json +2 -2
- package/lib/patch.js.bak-0000 +0 -244
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# 更新日志 / Changelog
|
|
2
2
|
|
|
3
|
+
## v2.0.0 (2026-11-07)
|
|
4
|
+
|
|
5
|
+
> 适配 **dsh 0.2.2-rc.1**。这一版修掉两个真实故障,并把自研移动端适配全部删除。
|
|
6
|
+
|
|
7
|
+
### 修复 / Fixed
|
|
8
|
+
|
|
9
|
+
- **局域网能访问但面板显示「未开启」、没有二维码**:dsh 用 `--host <网卡IP>` 启动时只监听那块
|
|
10
|
+
网卡(`127.0.0.1` 上没有任何监听),旧版旁挂听众去绑同一个 `<网卡IP>:<端口>` 必然
|
|
11
|
+
`EADDRINUSE`,于是 `running=false`。新增 `bindInfo()` 区分两种形态:
|
|
12
|
+
`direct`(宿主自己绑网卡)直接视为「局域网已可达」,只补其余网卡并跳过宿主已占用的地址。
|
|
13
|
+
- **外网域名 502 Bad Gateway**:frpc 配置里的 `localIP = "127.0.0.1"` 指向没人监听的端口。
|
|
14
|
+
现在 `localIP` 跟随宿主真实监听地址;并新增**外网入口 30s HTTP 可达性探测**,
|
|
15
|
+
502 / 连不上会直接在设置页标红并显示 frpc 实际转发地址(进程活着不再等于「在线」)。
|
|
16
|
+
|
|
17
|
+
### 移除 / Removed(官方已自带移动端适配)
|
|
18
|
+
|
|
19
|
+
- 移动端 CSS 全部删除(composer 换行、选择器限宽、iOS 16px 防缩放、Tooltip 抑制、
|
|
20
|
+
设置页单栏、菜单水平钳制、侧栏抽屉样式)。
|
|
21
|
+
- 「上传图片」按钮与图片 intake(模拟 paste/drop)删除 —— 官方 `+ → 文件` 与粘贴/拖放已覆盖。
|
|
22
|
+
- 自研 Toast、composer 发送状态浮层、侧栏悬浮按钮 / 覆盖式抽屉、设置弹窗结构打标。
|
|
23
|
+
- 保留设备心跳脚本(设置页「已连接设备」)、`crypto.randomUUID` 内网兜底(在门禁脚本内)、
|
|
24
|
+
远程访问密码门禁。
|
|
25
|
+
|
|
26
|
+
### 变更 / Changed
|
|
27
|
+
|
|
28
|
+
- `lib/lanproxy.js`:`start(hosts, port, { upstreamHost, skipHosts })`;`status()` 增加 `upstream`。
|
|
29
|
+
- `lib/index.js`:`/status` 增加 `direct`、`lan.upstream`、`external.localHost`、`external.probe`。
|
|
30
|
+
- `lib/client.js`:直连形态开关置灰 + 「局域网直连 · 由 dsh 提供」说明卡;外网卡片展示探测结果。
|
|
31
|
+
- `lib/external.js`:`startExternal(..., localHost)`、`autoRestoreExternal(..., localHost)`;
|
|
32
|
+
导出 `finalizeFrpcConfig` 供测试。
|
|
33
|
+
|
|
34
|
+
### 测试 / Tests
|
|
35
|
+
|
|
36
|
+
- 新增 `tests/bind-aware.test.mjs`(4 项):上游可定制、`skipHosts` 不重复绑、
|
|
37
|
+
全部地址被占用时不误报失败、frpc `localIP` 跟随宿主。
|
|
38
|
+
- `tests/patch.test.mjs` 43 项断言仍全部通过。
|
|
39
|
+
|
|
40
|
+
## v1.9.1 (2026-10-24)
|
|
41
|
+
|
|
42
|
+
### 修复 / Fixed
|
|
43
|
+
|
|
44
|
+
- **1.9.0 的 npm 包里误带了一个本地备份文件** `lib/patch.js.bak-0000`(`files` 声明的是整个 `lib`
|
|
45
|
+
目录)。已将该文件移出 `lib/` 并加入 `.gitignore`,发布物恢复干净(16 个文件)。
|
|
46
|
+
功能与 1.9.0 完全一致,无代码变更。
|
|
47
|
+
|
|
3
48
|
## v1.9.0 (2026-10-24)
|
|
4
49
|
|
|
5
50
|
> 适配 **dsh 0.2.1-rc.3**。这一版重做了「对局域网开放」的实现方式——**不再改 webserver 绑定**。
|
package/README.md
CHANGED
|
@@ -188,8 +188,9 @@ So for users, **installing is one command** — no YAML editing, no manual file
|
|
|
188
188
|
- **Toggle**: `POST /__dsh_remote/toggle` → writes/removes a `webserver` override block in the profile's `cordis.patch.yml` → dsh's `watchUserPatches` (Cordis HMR) hot-reloads the webserver entry to re-listen.
|
|
189
189
|
- **Device count**: mobile-injected JS heartbeats every 30s; the host keeps an active-device map (90s TTL). Each heartbeat now reports full device metadata (screen / viewport / DPR / network / current page / language / platform), shown in the expandable device rows of the settings panel.
|
|
190
190
|
- **QR code**: `GET /__dsh_remote/qr?url=...` returns SVG.
|
|
191
|
-
- **
|
|
192
|
-
-
|
|
191
|
+
- **No mobile UI patches any more** (v2.0.0): `tapIndex` only injects a ~40-line device-heartbeat script (`CLIENT_JS`). dsh 0.2.2+ already ships the mobile layout (drawer sidebar below 768px, auto-collapse at 1024px, no focus stealing on mobile UA, iOS keyboard fix, PWA), so the old mobile CSS, sidebar drawer, "Upload image" button, toast and sending indicator were removed — duplicated adaptation only fights the official implementation.
|
|
192
|
+
- **`crypto.randomUUID` fallback for insecure contexts** (kept in `GATE_JS`): DSH clients call `crypto.randomUUID()` on the wire; it only exists on HTTPS or localhost, so LAN `http://` access used to fail with `settings are unavailable in this browser`. The injected head script provides an RFC 4122 v4 shim backed by `getRandomValues`.
|
|
193
|
+
- **Tunnel reachability probe** (v2.0.0): frpc being alive only means it logged into frps. Every 30s the host now issues an HTTP probe against the public URL, so a 502 (wrong local forward address/port) is surfaced in the panel together with the local address frpc actually forwards to.
|
|
193
194
|
|
|
194
195
|
---
|
|
195
196
|
|
package/README.zh.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[GitHub](https://github.com/feiyang-dev/dsh-mobile-remote) · [npm](https://www.npmjs.com/package/@feiyang666/dsh-mobile-remote) · MIT License
|
|
8
8
|
|
|
9
|
-
**由开发者制作的 DeepSeek Harness 插件** —— 在 Web UI
|
|
9
|
+
**由开发者制作的 DeepSeek Harness 插件** —— 在 Web UI 设置页内置「远程控制」:连接二维码、一键开关、在线设备数,让手机通过局域网/外网访问并操控电脑上的 DeepSeek Harness(移动端界面由官方 dsh 自带,插件不再注入 UI 补丁)。
|
|
10
10
|
|
|
11
11
|

|
|
12
12
|

|
|
@@ -20,16 +20,15 @@
|
|
|
20
20
|
|
|
21
21
|
`dsh-mobile-remote` 是 DeepSeek Harness 生态的**移动端远程控制插件**(DSH plugin,Host + Client 双面一体包)。装好后在 WebUI **设置 → 远程控制** 出现一个管理面板:
|
|
22
22
|
|
|
23
|
-
-
|
|
24
|
-
- **移动端侧栏默认收起**(v1.9.0):窄屏下把侧栏轨道压到 0,内容区吃满整屏;左上角悬浮按钮点开为**覆盖式抽屉**(不挤压中栏),点遮罩 / Esc / 选中会话自动收起;
|
|
23
|
+
- **不再自带移动端 UI 补丁**(v2.0.0):官方 dsh 0.2.2 起已内置移动端适配(<768px 侧栏浮层抽屉 + 遮罩、1024px 自动塌缩、移动 UA 不抢焦点、iOS 软键盘修正、PWA),插件只保留一个设备心跳脚本;旧的移动端 CSS、侧栏抽屉、「上传图片」按钮、Toast 与发送状态浮层**全部移除**,界面完全交回官方实现;
|
|
25
24
|
- **连接二维码**:自动生成 `http://<局域网IP>:<端口>` 的二维码,手机相机 / 浏览器扫码即连;
|
|
26
25
|
- **裸地址直达,自动登录**(v1.8.0):直接访问裸地址 `http://192.168.x.x:3080`(不带任何 token)即可自动进入——服务端自动完成新版 dsh 的浏览器会话认证(`≥0.1.2-rc.1`),无需复制带 `?token=` 的长链接;老版 dsh 自动回退,行为不变;
|
|
27
|
-
- **开启 / 关闭开关**(
|
|
26
|
+
- **开启 / 关闭开关**(v2.0.0 适配两种绑定形态):dsh 只听回环时,在局域网网卡上**旁挂一个转发听众**(`<局域网IP>:<端口>` → `127.0.0.1:<端口>`);dsh 自己就用 `--host <网卡IP>` 启动时,直接以那块网卡为上游、只补其余网卡(同地址不再重复绑,避免 `EADDRINUSE` 导致「明明能访问却显示未开启」)。dsh 的监听地址与端口**完全不动**——本机窗口、桌面端、会话都不会被打断,开关**即时生效、无需重启、不写配置**;
|
|
28
27
|
- **当前连接的设备数量**:移动端心跳上报,实时统计在线设备数;
|
|
29
28
|
- **远程访问密码门禁**(v1.2.0+):管理员本机设置密码,外网隧道访问进入页面需先输密码,本机/局域网不受影响;
|
|
30
29
|
- **远程访问提速**(v1.2.0+):frpc 连接池调大,缓解外网访问首屏转圈慢;
|
|
31
30
|
- **更丰富的数据展示**(v1.4.0):设备列表可点击展开完整上报信息(系统 / 浏览器 / 屏幕 / 视口 / DPR / 设备内存 / CPU 核数 / 电池 / 网络 / 当前页面 / 首次连接 / 心跳次数);「运行时信息」卡(运行时长 / 开机时长 / Node 版本 / PID / CPU 型号与核数 / 系统负载 / 内存使用率 / RSS / 堆内存);**「DSH 状态」卡**(dsh 版本 / 会话总数 / 工作区列表 / 已安装插件 / 模型提供方,后台缓存);「网络接口」卡(网卡名 / IP / 掩码 / MAC);外网隧道详情(域名 / 端口 / frpc 版本 / PID / 运行时长 / 脱敏绑定码 / 日志查看);
|
|
32
|
-
- **外网隧道真实状态**(v1.4.1
|
|
31
|
+
- **外网隧道真实状态**(v1.4.1+ / v2.0.0 增强):面板探测 frpc 日志确认隧道真正建立,断线重连降级「连接中」,token 鉴权失败显示红色「出错」+ 精确原因(如 `token in login doesn't match`)+ 一键重试;**v2.0.0 起每 30 秒再对外网入口做一次 HTTP 探测**——frpc 进程活着只代表连上了 frps,本机转发地址/端口不对时中转侧对外只会回 502,现在这种「假在线」会直接在面板上标红,并显示 frpc 实际使用的本地转发地址;
|
|
33
32
|
- 局域网地址列表、手机访问地址、配置位置一目了然。
|
|
34
33
|
|
|
35
34
|
**核心卖点:纯命令行用户无需安装桌面端。** 官方 CLI 出于安全拒绝 `--host 0.0.0.0`;而 dsh **0.2.1-rc.3 起连 patch 层也不再接受通配地址**(`host: '0.0.0.0'` 会在配置校验阶段直接让进程退出),改绑具体网卡又会让本机回环监听消失(桌面端窗口白屏)。所以 v1.9.0 改用**旁挂 LAN 听众**:dsh 保持只听回环,插件在局域网网卡上再监听一份并转发过去——手机与电脑仍共享同一个后端进程与同一份 `~/.dsh` 数据,**会话列表、历史记录、工作区、设置全部天然双向同步,无需任何数据复制**。
|
|
@@ -185,9 +184,8 @@ dsh --profile web --patch remote-control.patch.yml
|
|
|
185
184
|
- **开关**:`POST /__dsh_remote/toggle` → 在局域网网卡上开启 / 关闭旁挂听众。请求被转发到 `127.0.0.1:<端口>`,并把 `Host` / `Origin` 改写成回环 authority(dsh 的信任围栏对回环一律放行),因此**不需要改 dsh 任何配置、也不需要重启**。
|
|
186
185
|
- **设备数**:移动端注入 JS 每 30s 心跳上报,host 维护活跃设备表(90s 过期)。每次心跳会上报完整设备元数据(屏幕 / 视口 / DPR / 网络 / 当前页面 / 语言 / 平台),设置面板的设备行可展开查看。
|
|
187
186
|
- **二维码**:`GET /__dsh_remote/qr?url=...` 返回 SVG。
|
|
188
|
-
-
|
|
189
|
-
-
|
|
190
|
-
- **移动端设置页适配**(v1.4.2+):原生设置弹窗在手机上自动变为全屏单栏——导航栏变顶部横向滚动标签、内容区占满剩余空间;同时抑制触屏上常驻的原生 Tooltip 气泡(如「停止 / 开始 / 关闭菜单栏」提示文字)。通过结构标记识别设置弹窗,**不依赖 harness 内部哈希类名**,harness 升级后无需修改插件即可直接适配。**v1.4.3** 修复该单栏布局——面板原本仍是横向 `flex`,内容列被压成 0 宽度(内容空白)且无法上下滚动;现强制 `flex-direction: column` + `min-height: 0`,设置选项区在手机上可正常滚动。并新增**内网(非安全上下文)`crypto.randomUUID` 兜底**:当前 DSH 客户端在连接时直接调用 `crypto.randomUUID()`,该 Web Crypto API 仅在 HTTPS / localhost 存在,内网 http 直连会报 `crypto.randomUUID is not a function` / `settings are unavailable in this browser`;插件注入的头部脚本用 `getRandomValues` 补一个 RFC 4122 v4 实现,内网访问 / 扫码连接恢复正常。
|
|
187
|
+
- **前端只注入心跳脚本**(v2.0.0 起):`tapIndex` 只插一个约 40 行的设备心跳脚本(`lib/index.js` 的 `CLIENT_JS`),**不再注入任何移动端 CSS / 交互补丁**——官方 dsh 0.2.2 已自带窄屏抽屉、软键盘修正等适配,重复适配只会与官方改动打架;
|
|
188
|
+
- **内网(非安全上下文)`crypto.randomUUID` 兜底**(保留,见 `GATE_JS`):当前 DSH 客户端连接时直接调用 `crypto.randomUUID()`,该 Web Crypto API 仅在 HTTPS / localhost 存在,内网 http 直连会报 `crypto.randomUUID is not a function` / `settings are unavailable in this browser`;门禁脚本用 `getRandomValues` 补一个 RFC 4122 v4 实现,内网访问 / 扫码连接正常。
|
|
191
189
|
|
|
192
190
|
---
|
|
193
191
|
|
package/RELEASE_NOTES.md
CHANGED
|
@@ -1,43 +1,36 @@
|
|
|
1
|
-
# dsh-mobile-remote
|
|
2
|
-
|
|
3
|
-
**DeepSeek Harness
|
|
4
|
-
|
|
5
|
-
## 本版更新(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
###
|
|
10
|
-
|
|
11
|
-
| 症状 | 根因 |
|
|
12
|
-
| --- | --- |
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
36
|
-
|
|
37
|
-
- 端口变化时局域网听众 15s 内自适应重绑;`remoteEnabled` 持久化,重启自动恢复。
|
|
38
|
-
|
|
39
|
-
### 验证
|
|
40
|
-
|
|
41
|
-
- `tests/patch.test.mjs`:43 项断言全通过(含「绝不写 webserver」「`!!js` 必须加引号」「旧配置迁移」)。
|
|
42
|
-
- 实测环境:dsh 0.2.1-rc.3 + Windows;验证了「本机端口不变 + 局域网同端口可访问 +
|
|
43
|
-
扫码自动登录 + `/api` 不再 403 + WebSocket 升级透传 + 开关即时生效(无需重启)」。
|
|
1
|
+
# dsh-mobile-remote v2.0.0
|
|
2
|
+
|
|
3
|
+
**DeepSeek Harness 远程访问插件** —— 在 Web UI 设置页内置「远程控制」:连接二维码、一键开关、在线设备数,让手机通过局域网 / 外网访问并操控电脑上的 DeepSeek Harness。移动端界面从 v2.0.0 起**完全交给官方 dsh**(0.2.2 已自带)。
|
|
4
|
+
|
|
5
|
+
## 本版更新(v2.0.0)
|
|
6
|
+
|
|
7
|
+
一句话:**适配「dsh 自己就绑在网卡上」的启动方式,并把外网 502 从"假在线"里揪出来;同时删掉所有自研移动端 UI 补丁。**
|
|
8
|
+
|
|
9
|
+
### 修掉的两个真实故障
|
|
10
|
+
|
|
11
|
+
| 症状 | 根因 | 修复 |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| 局域网明明能访问,插件却显示**未开启**、**不显示二维码** | dsh 用 `--host 192.168.x.x` 启动时只监听那块网卡,`127.0.0.1` 上没有任何监听。旧版旁挂听众去绑**同一个** `<网卡IP>:<端口>` → `EADDRINUSE` → `running=false` | 新增 `bindInfo()`:`direct` 形态直接认定「局域网已可达」,只补其余网卡并跳过宿主已占用的地址;二维码/地址列表把宿主绑定地址排第一 |
|
|
14
|
+
| 外网域名打开就是 **502 Bad Gateway**,面板却显示「在线」 | frpc 配置里的 `localIP = "127.0.0.1"` 转发到一个没人监听的端口,frps 与 nginx 侧只能回 502 | frpc 的 `localIP` 跟随宿主真实监听地址(非回环时改成网卡 IP);并新增**外网入口 30s HTTP 可达性探测**,502 直接在面板标红 |
|
|
15
|
+
|
|
16
|
+
### 移动端适配全部移除
|
|
17
|
+
|
|
18
|
+
官方 dsh 0.2.2 起自带移动端适配(`<768px` 侧栏浮层抽屉 + 遮罩、`1024px` 自动塌缩、移动 UA 不抢焦点、iOS 软键盘光标修正、PWA 清单),继续注入自己的 CSS 只会和官方改动互相打架:
|
|
19
|
+
|
|
20
|
+
- 删除全部移动端 CSS(composer 换行 / 选择器限宽 / 16px 防缩放 / Tooltip 抑制 / 设置页单栏 / 菜单钳制 / 抽屉样式);
|
|
21
|
+
- 删除「上传图片」按钮与模拟 paste/drop 的图片 intake 逻辑(官方 `+ → 文件` 与粘贴/拖放链路已有);
|
|
22
|
+
- 删除自研 Toast、发送状态浮层、侧栏悬浮按钮与抽屉、设置弹窗结构打标;
|
|
23
|
+
- 保留:设备心跳脚本(设置页「已连接设备」需要)、`crypto.randomUUID` 内网兜底(在门禁脚本里)、远程访问密码门禁。
|
|
24
|
+
|
|
25
|
+
### 其它
|
|
26
|
+
|
|
27
|
+
- `lib/lanproxy.js`:`start(hosts, port, { upstreamHost, skipHosts })`,转发上游可定制、已占用地址自动跳过;`status()` 增加 `upstream`。
|
|
28
|
+
- `lib/index.js`:`/status` 新增 `direct`(宿主直连形态)与 `lan.upstream`;`toggle` 在直连形态返回 `direct: true` 并说明需要改启动参数才能关闭;`external` 新增 `localHost` / `probe`。
|
|
29
|
+
- `lib/client.js`:直连形态下开关置灰并显示「局域网直连 · 由 dsh 提供」说明卡;外网卡片展示入口探测结果。
|
|
30
|
+
- 版本号提升到 **2.0.0**(移除移动端 UI 属于行为变更)。
|
|
31
|
+
|
|
32
|
+
### 验证
|
|
33
|
+
|
|
34
|
+
- `node --test tests/patch.test.mjs`:43 项断言通过。
|
|
35
|
+
- 新增 `tests/bind-aware.test.mjs`:4 项断言通过(上游可定制、`skipHosts` 不重复绑、全部被占用时不误报失败、frpc `localIP` 跟随宿主)。
|
|
36
|
+
- 实测环境:Windows + dsh 0.2.2(`--host 192.168.3.119 --port 3080`)。修复前:`127.0.0.1:3080` = `ECONNREFUSED`,`/status` 返回 `remoteEnabled:false`,公网域名 nginx 502;修复后 `direct` 形态下 `remoteEnabled:true`、二维码正常,frpc `localIP` 改为宿主网卡地址。
|
package/cordis.patch.yml
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
#
|
|
9
9
|
# 插件是 host + client 双面插件:
|
|
10
10
|
# - host 侧(lib/index.js,inject [webServer]):
|
|
11
|
-
# *
|
|
11
|
+
# * 局域网:宿主只绑回环时旁挂 LAN 听众;宿主用 --host <网卡IP> 启动时直接复用它;
|
|
12
|
+
# * 外网:经中转服务器 + frpc 隧道,并对公网入口做 30s 可达性探测(暴露 502);
|
|
13
|
+
# * 通过 ctx.webServer.tapIndex 仅注入一个设备心跳脚本(不含任何移动端 UI 补丁,
|
|
14
|
+
# 官方 dsh 0.2.2 起自带移动端适配);
|
|
12
15
|
# * 通过 ctx.webServer.register 提供 /__dsh_remote/* API
|
|
13
16
|
# (status / toggle / heartbeat / qr),支持设置页远程控制开关、二维码、设备数。
|
|
14
17
|
# - client 侧(lib/client.js,package.json 的 dsh.client 声明):
|