dsh-bridge-gateway 0.2.1 → 0.3.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +25 -3
  3. package/README.zh.md +35 -2
  4. package/assets/apple-touch-icon-180.png +0 -0
  5. package/assets/icon-192.png +0 -0
  6. package/assets/icon-512.png +0 -0
  7. package/assets/icon-maskable-192.png +0 -0
  8. package/assets/icon-maskable-512.png +0 -0
  9. package/client/client.js +302 -41
  10. package/client/index.js +438 -42
  11. package/docs/banner.jpg +0 -0
  12. package/docs/custom-tunnel.md +5 -5
  13. package/docs/platform-abstraction-design.md +1 -1
  14. package/docs/qq-usage.md +6 -6
  15. package/docs/screenshots/remote-auth-login-light.jpg +0 -0
  16. package/docs/screenshots/remote-auth-login.jpg +0 -0
  17. package/docs/wechat-usage.md +1 -1
  18. package/lib/auth/brand-assets.js +131 -0
  19. package/lib/auth/login-template.js +503 -361
  20. package/lib/auth/manager.js +47 -12
  21. package/lib/auth/theme-tokens.js +142 -0
  22. package/lib/bridge-rpc.js +2 -2
  23. package/lib/cloudflared-manager.mjs +1 -1
  24. package/lib/feishu/gateway.js +17 -17
  25. package/lib/feishu/index.js +3 -3
  26. package/lib/feishu/lark-bundled.mjs +284 -446
  27. package/lib/feishu/node.js +7 -7
  28. package/lib/gateway/cert.js +1 -1
  29. package/lib/index.js +289 -80
  30. package/lib/paths.js +43 -14
  31. package/lib/platform/base.js +2 -2
  32. package/lib/platform/conversation-bridge.js +17 -17
  33. package/lib/platform/index.js +1 -1
  34. package/lib/platform/manager.js +4 -4
  35. package/lib/qq/gateway.js +10 -10
  36. package/lib/qq/index.js +11 -11
  37. package/lib/qq/node.js +17 -17
  38. package/lib/telegram/gateway.js +10 -10
  39. package/lib/telegram/index.js +3 -3
  40. package/lib/telegram/node.js +5 -5
  41. package/lib/wechat/gateway.js +6 -6
  42. package/lib/wechat/index.js +4 -4
  43. package/lib/wechat/media.js +1 -1
  44. package/lib/wechat/node.js +13 -13
  45. package/package.json +6 -3
package/CHANGELOG.md CHANGED
@@ -2,6 +2,112 @@
2
2
 
3
3
  本项目 `dsh-bridge-gateway` 是基于 [dsh-bridge](https://github.com/wenbin-wb/dsh-bridge) 的移植增强分支,在保留原版能力之外,重点新增「公网直连网关」。
4
4
 
5
+ ## [0.3.0] - 2026-10-17
6
+
7
+ ### 新增:PWA 主屏图标(真 PNG + DSH 业务蓝)
8
+
9
+ 此前 manifest 只声明了 `image/svg+xml` 图标,且 `/apple-touch-icon.png` 也返回 SVG。
10
+ **华为 HarmonyOS 与多数 Android 启动器不支持 SVG 图标**,于是「添加到桌面」后得到的是一块
11
+ 空白图标。底色也由近黑 `#151517` 改为 DSH 业务蓝 `#4176e6` —— 近黑底在深色桌面上会糊成
12
+ 一块「光板」,这也是「图标是空白的」观感来源之一。
13
+
14
+ - 新增 `scripts/generate-icons.mjs`:用无头 Chrome 渲染 192/512 的 `any` 与 `maskable` 两版,
15
+ 外加 iOS 的 180;产物入库 `assets/`
16
+ - manifest 声明 4 个 PNG;`/apple-touch-icon.png` 改为返回真 PNG
17
+ - `maskable` 版满幅不留圆角 —— 启动器会按自己的形状裁切,自带圆角会被裁掉一半
18
+
19
+ ### 新增:远程登录页改版(DSH 元素)
20
+
21
+ 登录页重做为门厅式设计,与 DSH 本体同源同一枚鲸鱼。
22
+
23
+ - `lib/auth/brand-assets.js`:品牌资产单一来源,附 sha256 前缀校验
24
+ - `lib/auth/theme-tokens.js`:18 个 `--dsw-*` token 的静态十六进制回落 —— 登录页在 DSH
25
+ 之前渲染、加载不到 token,**每个 token 都必须有回落**
26
+ - 响应头:`no-store` + CSP。其中 `connect-src 'self'` 是登录 `fetch` 的必需项,漏掉会登录失败
27
+
28
+ ### 修复:移动端 8 项问题
29
+
30
+ | # | 症状 | 根因 |
31
+ |---|---|---|
32
+ | 1 | 主屏图标空白 | 见上:HarmonyOS 不支持 SVG 图标 |
33
+ | 2 | 打开渠道中心时面板标题被顶栏盖住 | 插件顶栏 `position:fixed` + `z-index:9998` 不感知面板状态(面板 `z-index:80`,其标题落在 y19,正被顶栏的 y0-40 覆盖) |
34
+ | 3 | 会话名恒为「新会话」 | DSH 0.1.7 起 sessions list 快照不再提供 `current` 字段,旧实现读它 → 恒 `undefined` → **静默回落**默认文案(不报错,很难发现)。改读 `retainedBy.mainView > 0` 的那一个(与 `dsh-client-ui-session` 的判据一致) |
35
+ | 4 | 轨迹视图内容被裁 | `table` 元素的 `overflow` 在 CSS 里**是被忽略的**,只写 `overflow-x:auto` 无效,必须配 `display:block`。另:工具调用参数列内容宽 3049px 而可见仅 180px(17×),横滑读不了,改为换行 |
36
+ | 5 | 输入框压住内容 | 见下「已知问题」(两次尝试均已回退) |
37
+ | 6 | 顶部两层头过高、挤压对话区 | **DSH 自带 `min-height:76px`**,只改 padding 压不下去;显式清零后内容区 +51px |
38
+ | 7 | 「对话」视图下拉被内容盖住 | 祖先链 `titleRow` 与 `wSkVaW_root` 都是 `overflow:hidden`,下拉落在头部下方被**整块裁掉**(z-index 再高也没用,裁剪发生在层叠之前)。改为 body 级 portal |
39
+ | 8 | **滚不到最新会话**(只渲染约 4 条消息) | 插件给 `_frame` 注入的 `height:100dvh` + `overflow:hidden` 组合使 DSH 的布局测量算错,驻留窗口塌缩成 4 条。去掉这两个属性组后 `scrollHeight` 由 996 恢复到 11295 |
40
+
41
+ ### 已知问题:#5 输入框压住内容(未修)
42
+
43
+ `composerSeat` 是 `position:sticky` 且为 `scrollBody` 的直接 flex 子项,吸住时会盖在滚动内容
44
+ 之上。**两次尝试修复(改 `fixed` + 补 padding;再用 `visualViewport` 算键盘高度)都破坏了 DSH
45
+ 的滚动锚定,均已回退。**
46
+
47
+ DSH 另有「覆盖层模式」(`:has([data-conversation-composer-overlay])`:`composerSeat` 转
48
+ `absolute`、`viewArea` 自己滚),但那是 `dsh-client-ui-trajectory`(轨迹视图)在用的,对话
49
+ 视图没有开。**要根治得走 DSH 侧,插件 CSS 补不了。**
50
+
51
+ ### 新增:真机诊断能力(长期保留)
52
+
53
+ 真机上稳定复现、桌面视口复现不出的问题,可以不改代码直接二分:
54
+
55
+ | 参数 | 作用 |
56
+ |---|---|
57
+ | `?dsh-diag=1` | 只读指标叠加层(滚动容器几何、`scrollHeight` / `clientHeight`、输入框位置、视口三件套)。与 `dsh-mobile` 独立,因此可对比「移动层开/关」两态 |
58
+ | `?dsh-mobile=off` | 完全禁用移动端增强层(CSS + JS) |
59
+ | `?dsh-mobile=no-new` | 保留承重布局,只关掉最近新增的那批规则 |
60
+ | `?dsh-mobile=no-<分组>` | 关掉某一组规则(`no-frameLayout` / `no-centercol` / `no-pad` / `no-observer`),逗号分隔可叠加 |
61
+ | `?dsh-mobile=on` | 恢复正常 |
62
+
63
+ 选择记进 `localStorage`,因此在没有地址栏的 PWA 里同样生效。
64
+
65
+ ### 变更:品牌名统一为 dsh-bridge-gateway
66
+
67
+ 插件自身标识、日志前缀、数据目录、cloudflared 缓存目录全部改名,并对旧名做**两级链自动迁移**
68
+ (`~/.dsh-bridge/` → `~/.dsh-bridge-cloudflared/` → `~/.dsh-bridge-gateway-cloudflared/`),
69
+ 用户无需重下 cloudflared。
70
+
71
+ 上游仓库名 `wenbin-wb/dsh-bridge` 与兼容性标识(`LEGACY_DATA_DIR_NAME`、
72
+ `BRIDGE_RPC_CHANNEL_LEGACY`、CHANGELOG 历史)按约定保留。
73
+
74
+ ### 测试
75
+
76
+ 269 项全绿;新增 12 条护栏,逐条用注入 bug 验证过会变红。每条护栏都写了「为什么」(踩过的坑)。
77
+ 中英 README 同步(章节数 / 标题层级 / 逐章节条目数 / 表格行数零差异)。
78
+
79
+ ## [0.2.2] - 2026-10-11
80
+
81
+ ### 修复:旧内核浏览器打开后工作区永远加载不了
82
+
83
+ 远程浏览器(统信 UOS、360 浏览器,内核均为 Chromium 108)访问时外壳能渲染出来,但工作区
84
+ 一直停在「选择一个工作区开始」;DevTools 报 `Promise.withResolvers is not a function` 与
85
+ `AbortSignal.any is not a function`,并伴随 `connection lost, retry #N` 无限重连。
86
+
87
+ 根因是 DSH `0.2.0-rc.2` 的浏览器端直接使用了三个较新的 Web API,旧内核上没有:
88
+
89
+ | API | 要求版本 | 调用点 |
90
+ |---|---|---|
91
+ | `Promise.withResolvers` | Chrome/Edge ≥ 119、Firefox ≥ 121、Safari ≥ 17.4 | index.html 末尾的启动门 `(globalThis.__DSH_BOOT_READY__ ??= Promise.withResolvers())`;`dsh-api-workspace-files` 客户端的工作区文件流 |
92
+ | `AbortSignal.any` | Chrome/Edge ≥ 116、Firefox ≥ 124、Safari ≥ 17.4 | `dsh-api-gateway` 的 `RemoteStream.read`、`dsh-api-session-controller`、`dsh-client-ui-workspace`、`dsh-client-ui-sidebar-files` 等 |
93
+ | `Array.prototype.toSorted` | Chrome/Edge ≥ 110 | `dsh-client-ui-model-selection` / `-schedule` / `-settings-models` |
94
+
95
+ 缺前两个的后果是启动门永不 resolve、远程流层直接抛错 —— 于是插件全部注册成功,工作区却
96
+ 永远加载不出来。
97
+
98
+ 修复走官方 `webserver/index-inject` 机制(与既有的 `crypto.randomUUID` polyfill 同一处),
99
+ 向 index.html 的 `<head>` 注入一段兜底脚本;该位置早于 `<body>` 末尾的启动门,所以一定先执行。
100
+ 三个 polyfill 全部带 `typeof` 守卫且幂等,现代浏览器上原样跳过、**绝不覆盖原生实现**;
101
+ `AbortSignal.any` 对齐原生语义:空数组不 abort、已 abort 的成员立即短路并沿用其 reason、
102
+ 组合信号 abort 后摘掉监听器(避免在 `lifetime` / `generation` 这类长命 signal 上堆积)。
103
+
104
+ 新增 `test/legacy-compat.test.mjs` 第 3 节共 10 条断言,在 `node:vm` 沙箱里剥离这三个 API 后
105
+ 验证注入脚本本身,其中两条是反向断言:原生齐全时三个函数引用必须原封不动、重复执行必须是 no-op。
106
+
107
+ > 附带说明:同一现场出现的 `404` / `net::ERR_HTTP_RESPONSE_CODE_FAILURE` 与本次故障无关 ——
108
+ > 那是 DevTools 打开时去取不存在的 source map(`/assets/index-*.js.map`)以及
109
+ > `/api/changes.summary`(deliverables 的 RPC)返回 404;工作区在零 4xx 的情况下照样加载失败。
110
+
5
111
  ## [0.2.1] - 2026-09-25
6
112
 
7
113
  ### 兼容性核查:DSH 0.1.7 无需改动
package/README.md CHANGED
@@ -14,7 +14,7 @@ This project's **upstream is [wenbin-wb/dsh-bridge](https://github.com/wenbin-wb
14
14
 
15
15
  ### Who upstream is
16
16
 
17
- | | |
17
+ | Field | Value |
18
18
  |---|---|
19
19
  | Repository | [wenbin-wb/dsh-bridge](https://github.com/wenbin-wb/dsh-bridge) |
20
20
  | Role | Multi-channel remote access and security plugin for DSH |
@@ -61,6 +61,12 @@ Upstream iterates quickly and this repository keeps up. Ported fixes are listed
61
61
 
62
62
  > Both sides evolve, so **feature coverage may lead on either side**. When in doubt, check upstream's README to see which side owns a given capability.
63
63
 
64
+ **5. Fixed: old-kernel browsers could not load the workspace (still present upstream)**
65
+
66
+ DSH's browser client calls `Promise.withResolvers` (Chrome/Edge ≥ 119) and `AbortSignal.any` (Chrome/Edge ≥ 116) directly. On an older kernel — UOS and 360 Browser, both Chromium 108 — the boot gate never resolves and the remote-stream layer throws, so the shell renders but the workspace stays stuck on "pick a workspace" while the console loops on `connection lost`.
67
+
68
+ This repository injects a small shim through the official `webserver/index-inject` mechanism (the same place as the existing `crypto.randomUUID` polyfill), covering `Promise.withResolvers`, `AbortSignal.any` and `Array.prototype.toSorted`. Every shim is `typeof`-guarded and idempotent, so a modern browser skips it untouched and never loses its native implementation.
69
+
64
70
  ### Naming
65
71
 
66
72
  The plugin was renamed from `dsh-bridge` to **`dsh-bridge-gateway`** (reflecting the added gateway capability). Existing users need no manual work — the data directory, configuration, passwords, certificates, and login state all migrate automatically:
@@ -68,7 +74,7 @@ The plugin was renamed from `dsh-bridge` to **`dsh-bridge-gateway`** (reflecting
68
74
  | Path | Change |
69
75
  |---|---|
70
76
  | `<DSH_HOME>/dsh-bridge/` | → `<DSH_HOME>/dsh-bridge-gateway/` (migrated automatically at startup) |
71
- | `~/.dsh-bridge/` | → `~/.dsh-bridge-cloudflared/` (cloudflared cache; migrated automatically, no re-download) |
77
+ | `~/.dsh-bridge/` | → `~/.dsh-bridge-gateway-cloudflared/` (cloudflared cache; **two-hop auto-migration**, no 39MB re-download) |
72
78
  | RPC channel `/dsh-bridge` | → `/dsh-bridge-gateway`, with **both channels served**, so stale cached pages keep working |
73
79
 
74
80
  ## Features
@@ -78,11 +84,12 @@ The plugin was renamed from `dsh-bridge` to **`dsh-bridge-gateway`** (reflecting
78
84
  - **LAN access.** Scan a QR code from the remote-access panel on the same Wi-Fi and you are in.
79
85
  - **Public tunnels.** Cloudflare (temporary or fixed hostname) or a self-built tunnel, selectable per need alongside the direct gateway and Tailscale.
80
86
  - **Remote workspace.** Browse the host's directory tree and pick workspace conversations from the phone (via DSH's official browse picker).
87
+ - **Legacy browser support.** The gateway injects `Promise.withResolvers` / `AbortSignal.any` / `Array.prototype.toSorted` polyfills into the page, so Chromium 108-class kernels (UOS, 360 Browser) load the workspace too. Modern browsers skip them untouched.
81
88
  - **Security.** Password gate + QR-based password-free token + admin unlock/lock for sensitive config + rate limiting against brute force, plus persisted login state (no re-login after a host restart). Client-claimed `isLocalhost` is never trusted.
82
89
  - **Visitor management.** See live who is currently connected (LAN / direct gateway / tunnel, with the real source IP behind a tunnel) plus an IP blacklist. **Viewing is open to every visitor**; disconnecting and blacklisting require admin rights.
83
90
  - **IM bots.** WeChat / QQ / Feishu / Telegram bots connect through their own gateway links — no public IP needed. Per-platform workspace / agent preset / model selection is configurable. Guides live in [docs/](./docs).
84
91
  - **Collapsible cards.** Cards in the Access and Security tabs collapse; only the first in each group is expanded by default, and a collapsed card keeps its status tag plus one line of key information.
85
- - **Mobile-friendly web.** The remote web UI is deeply adapted for phone screens (drawer sidebar, ~44px touch targets, bottom-stuck composer, and more).
92
+ - **Mobile-friendly web.** The remote web UI is deeply adapted for phone screens (drawer sidebar, ~44px touch targets, bottom-stuck composer, and more). The gateway also serves real **PNG** home-screen icons (DSH business blue + white whale, in both `any` and `maskable` variants) together with a Web App Manifest, so "Add to Home Screen" yields a proper icon rather than a blank tile.
86
93
  - **All configuration in the UI.** Every feature above is configured from DSH Web's remote-access panel; nothing is edited by hand.
87
94
 
88
95
  ## Interface
@@ -101,6 +108,7 @@ The panel has 5 tabs: **Access** / **Visitors** / **IM Bots** / **Security** / *
101
108
 
102
109
  - Node `^22.19.0 || >=24.0.0`.
103
110
  - DSH with a web profile (built and tested against `0.1.7-rc.2`, and still compatible with the `0.1.5` line: the host services, client slots and settings entry points it uses exist in both, so no extra adaptation is needed).
111
+ - A modern browser for the web UI: Chrome/Edge ≥ 119, Safari ≥ 17.4 or Firefox ≥ 121. Older kernels are kept working by the injected polyfills described above (Chromium 108-class UOS / 360 Browser included).
104
112
 
105
113
  ## Install
106
114
 
@@ -208,6 +216,20 @@ dsh plugin --profile web add .
208
216
 
209
217
  Tests point `DSH_HOME` at a throwaway temporary directory via `test/isolate-home.mjs`, so they never touch your real environment.
210
218
 
219
+ ### Diagnosing phone-only layout problems
220
+
221
+ Bugs that reproduce on a phone but never in a desktop viewport can be bisected without touching code. Append a query parameter to the remote URL; the choice is remembered in `localStorage`, so it also works inside an installed PWA (which has no address bar).
222
+
223
+ | Parameter | Effect |
224
+ |---|---|
225
+ | `?dsh-diag=1` | Overlays a read-only metrics panel (scroll-container geometry, `scrollHeight` / `clientHeight`, composer position, viewport triple). It is independent of `dsh-mobile`, so the layer can be compared on against off. |
226
+ | `?dsh-mobile=off` | Disables the whole mobile enhancement layer (CSS and JS). |
227
+ | `?dsh-mobile=no-new` | Keeps the load-bearing layout and drops only the most recently added rules. |
228
+ | `?dsh-mobile=no-<group>` | Drops one rule group: `no-frameLayout`, `no-centercol`, `no-pad`, `no-observer`. Comma-separate to combine. |
229
+ | `?dsh-mobile=on` | Restores normal behaviour. |
230
+
231
+ Start by capturing `?dsh-diag=1` twice — once as-is and once with `?dsh-mobile=off` — because the delta between those two states is usually enough to name the culprit.
232
+
211
233
  This project is forked from [wenbin-wb/dsh-bridge](https://github.com/wenbin-wb/dsh-bridge). Report general issues upstream and direct-gateway issues to this repository.
212
234
 
213
235
  ## Release notes
package/README.zh.md CHANGED
@@ -77,6 +77,18 @@ DeepSeek Harness(DSH)远程访问插件。以 [wenbin-wb/dsh-bridge](https:/
77
77
  > 由于两边都在演进,**功能上可能各有先后**。遇到问题时建议对照上游 README 确认某项能力
78
78
  > 归属哪一侧。
79
79
 
80
+ **五、修正:旧内核浏览器打开后工作区永远加载不了(上游至今保留)**
81
+
82
+ DSH 的浏览器端直接调用了 `Promise.withResolvers`(Chrome/Edge ≥ 119)与 `AbortSignal.any`
83
+ (Chrome/Edge ≥ 116)。旧内核上(统信 UOS、360 浏览器,内核均为 Chromium 108)启动门永不
84
+ resolve、远程流层直接抛错 —— 于是外壳渲染得出来,工作区却一直停在「选择一个工作区」,
85
+ 控制台刷 `connection lost` 重连。
86
+
87
+ 本仓库经官方 `webserver/index-inject` 机制(与既有的 `crypto.randomUUID` polyfill 同一处)
88
+ 注入一段兜底脚本,覆盖 `Promise.withResolvers`、`AbortSignal.any` 与
89
+ `Array.prototype.toSorted`。每段都带 `typeof` 守卫且幂等,现代浏览器上原样跳过,
90
+ **绝不覆盖原生实现**。
91
+
80
92
  ### 命名说明
81
93
 
82
94
  插件名由 `dsh-bridge` 改为 **`dsh-bridge-gateway`**(体现「网关」这一新增能力)。
@@ -85,7 +97,7 @@ DeepSeek Harness(DSH)远程访问插件。以 [wenbin-wb/dsh-bridge](https:/
85
97
  | 路径 | 变化 |
86
98
  |---|---|
87
99
  | `<DSH_HOME>/dsh-bridge/` | → `<DSH_HOME>/dsh-bridge-gateway/`(启动时自动迁移) |
88
- | `~/.dsh-bridge/` | → `~/.dsh-bridge-cloudflared/`(cloudflared 缓存,自动迁移,免重下) |
100
+ | `~/.dsh-bridge/` | → `~/.dsh-bridge-gateway-cloudflared/`(cloudflared 缓存,**两级链自动迁移**,免重下 39MB) |
89
101
  | RPC 通道 `/dsh-bridge` | → `/dsh-bridge-gateway`,**新旧双通道并存**,旧缓存页面仍可用 |
90
102
 
91
103
  ## 功能
@@ -99,6 +111,9 @@ DeepSeek Harness(DSH)远程访问插件。以 [wenbin-wb/dsh-bridge](https:/
99
111
  - **局域网访问。** 同一 Wi-Fi 下用手机扫远程访问面板里的二维码即可进入。
100
112
  - **公网隧道。** Cloudflare(临时/固定域名)或自建隧道,与直连网关、Tailscale 按需选用。
101
113
  - **远程工作区。** 手机端网页目录树直接浏览并选择工作区对话(走 DSH 官方 browse 选择器)。
114
+ - **旧内核浏览器支持。** 网关向页面注入 `Promise.withResolvers` / `AbortSignal.any` /
115
+ `Array.prototype.toSorted` 三段 polyfill,Chromium 108 档内核(统信 UOS、360 浏览器)
116
+ 也能正常加载工作区;现代浏览器上原样跳过。
102
117
  - **安全认证。** 密码门禁 + 扫码免密 Token + 敏感配置的管理员解锁/锁定 + 防暴力破解限频、
103
118
  登录态持久化(宿主重启不必重新登录);永不信任客户端自称的 `isLocalhost`。
104
119
  - **访客管理。** 实时查看「谁正连着本机」(局域网 / 直连 / 隧道,隧道场景显示真实来源 IP),
@@ -108,7 +123,8 @@ DeepSeek Harness(DSH)远程访问插件。以 [wenbin-wb/dsh-bridge](https:/
108
123
  - **卡片折叠。** 访问配置与安全认证两个 Tab 的卡片都可折叠,默认只展开首张,
109
124
  折叠后仍保留状态标签与一行关键信息。
110
125
  - **移动端适配。** 远程网页 UI 针对手机屏幕深度适配(抽屉化侧边栏、点击热区扩至约 44px、
111
- 输入框贴底等)。
126
+ 输入框贴底等)。网关另外提供真实的 **PNG** 主屏图标(DSH 业务蓝 + 白色鲸鱼,含 `any`
127
+ 与 `maskable` 两版)与 Web App Manifest,"添加到桌面"得到的是正常图标而非空白方块。
112
128
  - **全界面配置。** 以上全部功能都在 DSH Web 远程访问面板里配置,无需手改任何文件。
113
129
 
114
130
  ## 界面
@@ -128,6 +144,8 @@ DeepSeek Harness(DSH)远程访问插件。以 [wenbin-wb/dsh-bridge](https:/
128
144
  - Node `^22.19.0 || >=24.0.0`。
129
145
  - DSH web profile(构建与测试基于 `0.1.7-rc.2`,同时兼容 `0.1.5` 线:宿主服务、客户端槽位与
130
146
  设置接口在两个版本上都存在,无需额外适配)。
147
+ - 网页端建议使用现代浏览器:Chrome/Edge ≥ 119、Safari ≥ 17.4 或 Firefox ≥ 121。
148
+ 旧内核由上文注入的 polyfill 兜底(含 Chromium 108 档的统信 UOS / 360 浏览器)。
131
149
 
132
150
  ## 安装
133
151
 
@@ -260,6 +278,21 @@ dsh plugin --profile web add .
260
278
  测试会通过 `test/isolate-home.mjs` 把 `DSH_HOME` 指向一次性临时目录,不会污染你本机的
261
279
  真实环境。
262
280
 
281
+ ### 排查只在手机上出现的问题
282
+
283
+ 桌面视口复现不出、真机稳定复现的问题,可以不改代码直接二分。在远程地址后加查询参数即可;
284
+ 选择会记进 `localStorage`,所以在没有地址栏的 PWA 里同样生效。
285
+
286
+ | 参数 | 作用 |
287
+ |---|---|
288
+ | `?dsh-diag=1` | 叠加只读指标面板(滚动容器几何、`scrollHeight` / `clientHeight`、输入框位置、视口三件套)。它与 `dsh-mobile` 相互独立,因此能对比移动层「开」与「关」两种状态。 |
289
+ | `?dsh-mobile=off` | 完全禁用移动端增强层(CSS 与 JS)。 |
290
+ | `?dsh-mobile=no-new` | 保留承重布局,只关掉最近新增的那批规则。 |
291
+ | `?dsh-mobile=no-<分组>` | 关掉某一组规则:`no-frameLayout`、`no-centercol`、`no-pad`、`no-observer`,逗号分隔可叠加。 |
292
+ | `?dsh-mobile=on` | 恢复正常。 |
293
+
294
+ 第一步先取两次 `?dsh-diag=1` —— 一次原样、一次带 `?dsh-mobile=off` —— 两者差值通常就足以定位元凶。
295
+
263
296
  本项目 fork 自 [wenbin-wb/dsh-bridge](https://github.com/wenbin-wb/dsh-bridge)。
264
297
  向上游反馈通用问题、向本仓库反馈直连网关相关问题。
265
298
 
Binary file
Binary file
Binary file
Binary file
Binary file