dsh-zen-remote 1.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/AGENTS.md +51 -0
- package/LICENSE +38 -0
- package/README.md +237 -0
- package/assets/home.png +0 -0
- package/assets/info.png +0 -0
- package/assets/pairing.png +0 -0
- package/assets/session.png +0 -0
- package/assets/sheet.png +0 -0
- package/cordis.patch.yml +17 -0
- package/cordis.patch.yml.example +16 -0
- package/docs/interface.md +200 -0
- package/docs/remote-access.en.md +335 -0
- package/docs/remote-access.md +422 -0
- package/dsh-push.mjs +213 -0
- package/lan-gate.mjs +78 -0
- package/lib/client.js +6615 -0
- package/lib/index.js +310 -0
- package/lib/index.js.map +1 -0
- package/lib/lan-gate-server.cjs +626 -0
- package/lib/types/client/MobileAttachButton.d.ts +25 -0
- package/lib/types/client/MobileAttachButton.d.ts.map +1 -0
- package/lib/types/client/MobileAttachChips.d.ts +32 -0
- package/lib/types/client/MobileAttachChips.d.ts.map +1 -0
- package/lib/types/client/MobileDrawerFooter.d.ts +21 -0
- package/lib/types/client/MobileDrawerFooter.d.ts.map +1 -0
- package/lib/types/client/MobileHome.d.ts +24 -0
- package/lib/types/client/MobileHome.d.ts.map +1 -0
- package/lib/types/client/MobileHomeChips.d.ts +76 -0
- package/lib/types/client/MobileHomeChips.d.ts.map +1 -0
- package/lib/types/client/MobileNavOverlay.d.ts +15 -0
- package/lib/types/client/MobileNavOverlay.d.ts.map +1 -0
- package/lib/types/client/MobileNavToggle.d.ts +18 -0
- package/lib/types/client/MobileNavToggle.d.ts.map +1 -0
- package/lib/types/client/MobileSessionHeader.d.ts +58 -0
- package/lib/types/client/MobileSessionHeader.d.ts.map +1 -0
- package/lib/types/client/MobileSessionInfo.d.ts +41 -0
- package/lib/types/client/MobileSessionInfo.d.ts.map +1 -0
- package/lib/types/client/attach-upload.d.ts +78 -0
- package/lib/types/client/attach-upload.d.ts.map +1 -0
- package/lib/types/client/chips-store.d.ts +13 -0
- package/lib/types/client/chips-store.d.ts.map +1 -0
- package/lib/types/client/debug.d.ts +9 -0
- package/lib/types/client/debug.d.ts.map +1 -0
- package/lib/types/client/effects/aionui-compat.d.ts +4 -0
- package/lib/types/client/effects/aionui-compat.d.ts.map +1 -0
- package/lib/types/client/effects/gestures.d.ts +7 -0
- package/lib/types/client/effects/gestures.d.ts.map +1 -0
- package/lib/types/client/effects/header-status.d.ts +15 -0
- package/lib/types/client/effects/header-status.d.ts.map +1 -0
- package/lib/types/client/effects/phone-chrome.d.ts +106 -0
- package/lib/types/client/effects/phone-chrome.d.ts.map +1 -0
- package/lib/types/client/effects/turn-fold.d.ts +25 -0
- package/lib/types/client/effects/turn-fold.d.ts.map +1 -0
- package/lib/types/client/index.d.ts +18 -0
- package/lib/types/client/index.d.ts.map +1 -0
- package/lib/types/client/locales.d.ts +58 -0
- package/lib/types/client/locales.d.ts.map +1 -0
- package/lib/types/client/nav-store.d.ts +73 -0
- package/lib/types/client/nav-store.d.ts.map +1 -0
- package/lib/types/client/session-dot.d.ts +12 -0
- package/lib/types/client/session-dot.d.ts.map +1 -0
- package/lib/types/client/styles/base.css.d.ts +2 -0
- package/lib/types/client/styles/base.css.d.ts.map +1 -0
- package/lib/types/client/styles/chips.css.d.ts +2 -0
- package/lib/types/client/styles/chips.css.d.ts.map +1 -0
- package/lib/types/client/styles/compat.css.d.ts +2 -0
- package/lib/types/client/styles/compat.css.d.ts.map +1 -0
- package/lib/types/client/styles/composer.css.d.ts +2 -0
- package/lib/types/client/styles/composer.css.d.ts.map +1 -0
- package/lib/types/client/styles/header.css.d.ts +2 -0
- package/lib/types/client/styles/header.css.d.ts.map +1 -0
- package/lib/types/client/styles/home.css.d.ts +2 -0
- package/lib/types/client/styles/home.css.d.ts.map +1 -0
- package/lib/types/client/styles/index.d.ts +15 -0
- package/lib/types/client/styles/index.d.ts.map +1 -0
- package/lib/types/client/styles/info.css.d.ts +2 -0
- package/lib/types/client/styles/info.css.d.ts.map +1 -0
- package/lib/types/client/styles/layout.css.d.ts +2 -0
- package/lib/types/client/styles/layout.css.d.ts.map +1 -0
- package/lib/types/client/styles/misc.css.d.ts +2 -0
- package/lib/types/client/styles/misc.css.d.ts.map +1 -0
- package/lib/types/client/styles/turn-fold.css.d.ts +2 -0
- package/lib/types/client/styles/turn-fold.css.d.ts.map +1 -0
- package/lib/types/index.d.ts +83 -0
- package/lib/types/index.d.ts.map +1 -0
- package/llms.txt +20 -0
- package/package.json +128 -0
- package/pwa/app.css +95 -0
- package/pwa/icons/icon-192.png +0 -0
- package/pwa/icons/icon-512.png +0 -0
- package/pwa/icons/icon-maskable-512.png +0 -0
- package/pwa/icons/icon-maskable.svg +1 -0
- package/pwa/icons/icon.svg +1 -0
- package/pwa/inject.js +190 -0
- package/pwa/manifest.json +29 -0
- package/pwa/offline.html +38 -0
- package/pwa/sw.js +176 -0
- package/pwa/touch-gestures.js +94 -0
- package/scripts/build-client.mjs +101 -0
- package/scripts/cdp-probe.mjs +64 -0
- package/scripts/check-attach-upload.mjs +99 -0
- package/scripts/check-sunk-viewport.mjs +33 -0
- package/scripts/check-upload-endpoint.mjs +168 -0
- package/src/client/MobileAttachButton.tsx +125 -0
- package/src/client/MobileAttachChips.tsx +85 -0
- package/src/client/MobileDrawerFooter.tsx +56 -0
- package/src/client/MobileHome.tsx +348 -0
- package/src/client/MobileHomeChips.tsx +426 -0
- package/src/client/MobileNavOverlay.tsx +279 -0
- package/src/client/MobileNavToggle.tsx +52 -0
- package/src/client/MobileSessionHeader.tsx +242 -0
- package/src/client/MobileSessionInfo.tsx +303 -0
- package/src/client/attach-upload.ts +140 -0
- package/src/client/chips-store.ts +41 -0
- package/src/client/debug.ts +253 -0
- package/src/client/effects/aionui-compat.ts +183 -0
- package/src/client/effects/gestures.ts +265 -0
- package/src/client/effects/header-status.ts +30 -0
- package/src/client/effects/phone-chrome.ts +265 -0
- package/src/client/effects/turn-fold.ts +258 -0
- package/src/client/index.tsx +227 -0
- package/src/client/locales.ts +109 -0
- package/src/client/nav-store.ts +78 -0
- package/src/client/session-dot.ts +17 -0
- package/src/client/styles/base.css.ts +167 -0
- package/src/client/styles/chips.css.ts +224 -0
- package/src/client/styles/compat.css.ts +681 -0
- package/src/client/styles/composer.css.ts +504 -0
- package/src/client/styles/header.css.ts +368 -0
- package/src/client/styles/home.css.ts +477 -0
- package/src/client/styles/index.ts +25 -0
- package/src/client/styles/info.css.ts +238 -0
- package/src/client/styles/layout.css.ts +501 -0
- package/src/client/styles/misc.css.ts +128 -0
- package/src/client/styles/turn-fold.css.ts +106 -0
- package/src/index.ts +343 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# AGENTS.md — dsh-zen-remote
|
|
2
|
+
|
|
3
|
+
单一 npm 包 `dsh-zen-remote`,DSH(DeepSeek Harness)的 bundle 插件。
|
|
4
|
+
一个包里有两半代码,但**对用户是一个插件**:文档、安装说明、README 都不要
|
|
5
|
+
再按「两个包」叙述(2026-08-17 由 monorepo 的 `packages/gateway` +
|
|
6
|
+
`packages/mobile-ui` 合并而来,包名 `dsh-mobile-pwa` 与
|
|
7
|
+
`@dsh-external/dsh-mobile-nav` 已作废)。
|
|
8
|
+
|
|
9
|
+
## 目录
|
|
10
|
+
|
|
11
|
+
| 路径 | 作用 |
|
|
12
|
+
| --- | --- |
|
|
13
|
+
| `package.json` | 单包声明:`dsh.bundle.patch` → `cordis.patch.yml`,`dsh.client` → `exports["./client"]` |
|
|
14
|
+
| `cordis.patch.yml` | 组合层,三行 insert(界面 / 网关 / 推送),随包自带 |
|
|
15
|
+
| `src/index.ts` → `lib/index.js` | host 半边入口(插件行 `dsh-zen-remote`):唯一一条路由 `POST /_dsh/mobile-nav/upload` |
|
|
16
|
+
| `src/client/**` → `lib/client.js` | 浏览器半边(同一插件行,经 `dsh.client` 发现):app 外壳、slot、样式 |
|
|
17
|
+
| `lan-gate.mjs` | 网关 Cordis entry(插件行 `dsh-zen-remote-gateway`):spawn 子进程 |
|
|
18
|
+
| `lib/lan-gate-server.cjs` | 网关本体(独立 Node 子进程,Node stdlib + `web-push`) |
|
|
19
|
+
| `dsh-push.mjs` | 推送 entry(插件行 `dsh-zen-remote-push`):回合结束推送 + `push_notify` 工具 |
|
|
20
|
+
| `pwa/**` | manifest / service worker / 注入脚本 / 手势 / 壳级 CSS / 图标 |
|
|
21
|
+
| `test/*.test.cjs` | 网关侧测试(真子进程 + mock 上游) |
|
|
22
|
+
| `scripts/check-*.mjs` | 界面侧自检(纯 `node:assert`,靠 Node ≥23.6 类型剥离直接 import `.ts`) |
|
|
23
|
+
| `scripts/build-client.mjs` | client 打包器(内联相对模块 → `__ModuleLoader__.load({id:"dsh-zen-remote"})`) |
|
|
24
|
+
| `docs/**` | 深度文档,见下 |
|
|
25
|
+
|
|
26
|
+
## 命令
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
pnpm install
|
|
30
|
+
pnpm build # tsc host + tsc client + build-client.mjs → lib/(产物入库,改 src/ 必须重跑并提交 lib/)
|
|
31
|
+
pnpm verify # 两个 tsconfig 的 --noEmit 类型检查
|
|
32
|
+
pnpm test # 网关 43 个 node:test 用例 + 三个界面自检脚本,一条命令全跑
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 深度文档
|
|
36
|
+
|
|
37
|
+
| 文件 | 内容 |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| [`docs/remote-access.md`](docs/remote-access.md) | 通道半边:反代配置(nginx/Caddy/Lucky)、配对流程、环境变量表、管理 API、推送、安全边界 |
|
|
40
|
+
| [`docs/interface.md`](docs/interface.md) | 界面半边:断点策略、调试徽章、安全区体系、兼容插件清单 |
|
|
41
|
+
|
|
42
|
+
## 合仓后仍然成立的硬约束
|
|
43
|
+
|
|
44
|
+
- **网关是子进程**:`lan-gate.mjs` 只负责 spawn + 生命周期,永远不要把
|
|
45
|
+
`lib/lan-gate-server.cjs` import 进 DSH 进程。
|
|
46
|
+
- **CSS 分工没变**:排版类规则在 `src/client/styles/`;`pwa/app.css` 只留壳级
|
|
47
|
+
规则(iOS 输入框防缩放、安全区滚动补偿、代码块横向滚动)。两边抢同一个元素
|
|
48
|
+
是历史事故的根源,加规则前先确认归属。
|
|
49
|
+
- **`lib/` 是产物,不手改**:改 `src/` → `pnpm build` → 提交 `lib/`。
|
|
50
|
+
- **桌面必须 no-op**:≥1024px 逐像素与未安装时一致。
|
|
51
|
+
是从真机事故里攒出来的,改相关代码前先读。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dsh-zen-remote contributors
|
|
4
|
+
Copyright (c) 2026 mexiaosqwq — original dsh-web-mobile — 界面层上游 / upstream of the interface half
|
|
5
|
+
Copyright (c) 2026 dsh-mobile-pwa contributors — 通道层上游 / upstream of the gateway half
|
|
6
|
+
Copyright (c) 2026 Bernardxu123 — original dsh-mobile-gate (base for lib/lan-gate-server.cjs)
|
|
7
|
+
|
|
8
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
9
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
10
|
+
in the Software without restriction, including without limitation the rights
|
|
11
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
12
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
13
|
+
furnished to do so, subject to the following conditions:
|
|
14
|
+
|
|
15
|
+
The above copyright notice and this permission notice shall be included in all
|
|
16
|
+
copies or substantial portions of the Software.
|
|
17
|
+
|
|
18
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
19
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
20
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
21
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
22
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
23
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
24
|
+
SOFTWARE.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
NOTICE — provenance of the two packages merged into this repository:
|
|
29
|
+
|
|
30
|
+
* `packages/mobile-ui` derives from `dsh-web-mobile` (MIT, mexiaosqwq), rewritten
|
|
31
|
+
into an app-shell information architecture for phone widths (v2.0).
|
|
32
|
+
* `packages/gateway` derives from `dsh-mobile-pwa` (MIT), which itself derives
|
|
33
|
+
from `dsh-mobile-gate` (MIT, Bernardxu123). The gateway
|
|
34
|
+
`packages/gateway/lib/lan-gate-server.cjs` is based on that original, extended
|
|
35
|
+
with pairing-code authentication, per-device tokens, PWA manifest/service-worker
|
|
36
|
+
injection and VAPID Web Push.
|
|
37
|
+
|
|
38
|
+
Each package keeps its own LICENSE file with the upstream copyright lines intact.
|
package/README.md
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
<h1 align="center">dsh-zen-remote</h1>
|
|
2
|
+
<p align="center">把 DeepSeek Harness 变成一个能从公网安全访问的手机 App:移动端界面重排 + 配对认证网关 + 装到主屏 + 锁屏推送。</p>
|
|
3
|
+
|
|
4
|
+
<p align="center">
|
|
5
|
+
<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-0B7285?style=flat-square" alt="MIT"></a>
|
|
6
|
+
<img src="https://img.shields.io/badge/release-v1.0.0-5B4CF0?style=flat-square" alt="v1.0.0">
|
|
7
|
+
<img src="https://img.shields.io/badge/DSH-Web%20Profile-5B4CF0?style=flat-square" alt="DSH Web Profile">
|
|
8
|
+
</p>
|
|
9
|
+
|
|
10
|
+
| 会话列表主屏 | 会话页 | 会话信息卡 |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
|  |  |  |
|
|
13
|
+
|
|
14
|
+
| composer 权限 sheet | 公网设备看到的配对页 |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
|  |  |
|
|
17
|
+
|
|
18
|
+
> 截图为 390×844 手机视口、浅色主题;深浅主题均适配。配对页是网关自绘页面,固定深色设计。
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## 安装
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
dsh plugin add dsh-zen-remote
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
装完重启 `dsh web`,手机界面与网关一起生效,不需要再手写任何配置行。
|
|
29
|
+
|
|
30
|
+
> 兼容性:在 DSH `0.1.0-rc.6`(web profile)上开发并实测,最后验证 2026-08-18。
|
|
31
|
+
|
|
32
|
+
卸载:`dsh plugin remove dsh-zen-remote`(或从 profile 的 `dependencies` 与 `bundles` 里删掉那两行),重启 `dsh web` 即恢复原状;要清掉配对数据再删 `~/.dsh/lan-gate-state.json` 与 `~/.dsh/lan-gate.config.json`。
|
|
33
|
+
|
|
34
|
+
<details>
|
|
35
|
+
<summary>手动写法 / 本地开发</summary>
|
|
36
|
+
|
|
37
|
+
手动改 `~/.dsh/profiles/web/package.json`——`dependencies` 一行、`bundles` 一行:
|
|
38
|
+
|
|
39
|
+
```jsonc
|
|
40
|
+
{
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"dsh-zen-remote": "^1.0.0" // 本地开发换成 "link:/path/to/dsh-zen-remote"
|
|
43
|
+
},
|
|
44
|
+
"dsh": { "profile": { "bundles": [
|
|
45
|
+
"@deepseek-ai/dsh-base",
|
|
46
|
+
"@deepseek-ai/dsh-web-app",
|
|
47
|
+
"dsh-zen-remote"
|
|
48
|
+
] } }
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
cd ~/.dsh/profiles/web && pnpm install
|
|
54
|
+
# 重启 dsh web
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
不想走 profile 安装流程的静态挂载写法见 [`cordis.patch.yml.example`](cordis.patch.yml.example)。
|
|
58
|
+
|
|
59
|
+
从旧的两包结构(`dsh-mobile-pwa` + `@dsh-external/dsh-mobile-nav`)升级:两行依赖、两条 bundle 换成上面的一行一条,并把 profile 的 `cordis.patch.yml` 里手挂 `dsh-mobile-pwa/dsh-push.mjs` 的那行删掉——推送现在随包自带。
|
|
60
|
+
</details>
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 配置公网访问
|
|
65
|
+
|
|
66
|
+
装完在本机 `127.0.0.1:3080` 就能用手机界面。要从外面访问,按下面三步走。
|
|
67
|
+
|
|
68
|
+
### 1. 配一个反代终结 HTTPS
|
|
69
|
+
|
|
70
|
+
网关默认只监听 `127.0.0.1:3088`,必须由你自己的反代对外。**家宽没有公网 IP、或者不想开路由器端口**,就跳过 nginx/Caddy 直接看第三个块(Cloudflare Tunnel)。
|
|
71
|
+
|
|
72
|
+
<details open>
|
|
73
|
+
<summary><b>nginx</b></summary>
|
|
74
|
+
|
|
75
|
+
```nginx
|
|
76
|
+
# http {} 块里加一次
|
|
77
|
+
map $http_upgrade $connection_upgrade { default upgrade; '' close; }
|
|
78
|
+
|
|
79
|
+
server {
|
|
80
|
+
listen 443 ssl http2;
|
|
81
|
+
server_name dsh.example.com;
|
|
82
|
+
|
|
83
|
+
ssl_certificate /etc/letsencrypt/live/dsh.example.com/fullchain.pem;
|
|
84
|
+
ssl_certificate_key /etc/letsencrypt/live/dsh.example.com/privkey.pem;
|
|
85
|
+
|
|
86
|
+
location / {
|
|
87
|
+
proxy_pass http://127.0.0.1:3088;
|
|
88
|
+
proxy_http_version 1.1;
|
|
89
|
+
|
|
90
|
+
proxy_set_header Upgrade $http_upgrade;
|
|
91
|
+
proxy_set_header Connection $connection_upgrade;
|
|
92
|
+
|
|
93
|
+
proxy_set_header Host $host;
|
|
94
|
+
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
95
|
+
proxy_set_header X-Forwarded-Proto $scheme;
|
|
96
|
+
|
|
97
|
+
proxy_buffering off;
|
|
98
|
+
proxy_read_timeout 3600s;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
<details open>
|
|
106
|
+
<summary><b>Caddy</b></summary>
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
dsh.example.com {
|
|
110
|
+
reverse_proxy 127.0.0.1:3088
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details open>
|
|
117
|
+
<summary><b>没有公网 IP?用 Cloudflare Tunnel</b></summary>
|
|
118
|
+
|
|
119
|
+
家宽拿不到公网 IP、或者不想在路由器上开端口时用这个:`cloudflared` 从你这台机器主动连出去,Cloudflare 那边负责域名、证书和入口,路由器一个端口都不用开。免费版够用。
|
|
120
|
+
|
|
121
|
+
前置:域名托管在 Cloudflare(NS 指过去)。
|
|
122
|
+
|
|
123
|
+
1. 打开 [Zero Trust 控制台](https://one.dash.cloudflare.com/) → **Networks → Tunnels → Create a tunnel** → 选 **Cloudflared**,起个名字,创建后页面会给你一条带 token 的安装命令;
|
|
124
|
+
2. 在跑 DSH 的这台机器上执行那条命令(就是下面这个形状,token 用页面给的):
|
|
125
|
+
|
|
126
|
+
```sh
|
|
127
|
+
# macOS / Linux:装成常驻服务,开机自启
|
|
128
|
+
cloudflared service install eyJhIjoi...你的token
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
3. 回到隧道详情页 → **Public Hostname** → **Add a public hostname**:
|
|
132
|
+
|
|
133
|
+
| 字段 | 填什么 |
|
|
134
|
+
| --- | --- |
|
|
135
|
+
| Subdomain / Domain | `dsh` / `example.com`(即 `dsh.example.com`) |
|
|
136
|
+
| Service Type | `HTTP` |
|
|
137
|
+
| URL | `127.0.0.1:3088` |
|
|
138
|
+
|
|
139
|
+
保存后 `https://dsh.example.com` 就通了,证书 Cloudflare 自动签。网关的 `LAN_GATE_HOST` 保持默认 `127.0.0.1` 即可——`cloudflared` 就在本机。
|
|
140
|
+
|
|
141
|
+
**装完必须做第 2 步的 403 自检**,这一步对隧道尤其要紧:`cloudflared` 和网关走的是本机回环连接,网关区分「公网访客」和「坐在这台电脑前的你」,全靠隧道有没有带上 `X-Forwarded-For`。`cloudflared` 默认是带的,所以配对墙正常生效;但万一你的版本或配置把它去掉了,公网请求就会被当成本机管理员,配对墙形同虚设——**用手机流量访问 `/lan-gate/admin`,看到 403 才算安全**。
|
|
142
|
+
|
|
143
|
+
> 提示:不用设 `LAN_GATE_TRUSTED_PROXIES`——网关本来就把回环来的连接当作可信反代,填 `127.0.0.1` 是空操作,也**不能**替代上面那个自检。
|
|
144
|
+
>
|
|
145
|
+
> Cloudflare 免费版支持 WebSocket(DSH 对话流需要),单个请求体上限 100MB,高于本插件默认的 20MB 上传上限,不影响使用。
|
|
146
|
+
|
|
147
|
+
命令行流程(`cloudflared tunnel login` / `create` / `route dns` + `config.yml` 里写 ingress)见 [docs/remote-access.md](docs/remote-access.md#cloudflare-tunnel没有公网-ip-时的接入方式)。
|
|
148
|
+
</details>
|
|
149
|
+
|
|
150
|
+
Lucky(路由器/NAS)的配法见 [docs/remote-access.md](docs/remote-access.md#lucky)。反代与网关不在同一台机器时,要把反代出口 IP 填进 `LAN_GATE_TRUSTED_PROXIES`。
|
|
151
|
+
|
|
152
|
+
### 2. 自检
|
|
153
|
+
|
|
154
|
+
用**手机流量**(别连家里 Wi-Fi)访问 `https://你的域名/lan-gate/admin`,正确结果是 **403**。
|
|
155
|
+
|
|
156
|
+
能看到管理页说明反代没带 `X-Forwarded-*` 头,公网请求被当成了本机用户——回去检查转发头再往下走。
|
|
157
|
+
|
|
158
|
+
### 3. 配对设备
|
|
159
|
+
|
|
160
|
+
```sh
|
|
161
|
+
# 在跑 DSH 的这台机器上,用本机浏览器打开
|
|
162
|
+
open http://127.0.0.1:3088/lan-gate/admin
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
1. 点「生成配对码」,得到 8 位码(10 分钟有效、只能用一次);
|
|
166
|
+
2. 手机打开你的 HTTPS 域名,在配对页输入这个码;
|
|
167
|
+
3. 配对成功即进入 DSH,身份存在长期 Cookie 里,换网络不掉线;
|
|
168
|
+
4. 浏览器菜单「添加到主屏幕」装成 App;
|
|
169
|
+
5. 同意通知权限,agent 干完活推到锁屏。
|
|
170
|
+
|
|
171
|
+
管理页还能改设备名、设备类型,或单独/全部吊销设备。
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 可选配置
|
|
176
|
+
|
|
177
|
+
环境变量,或 `~/.dsh/lan-gate.config.json`(键名是变量去前缀转小驼峰,如 `port` / `trustedProxies`;显式环境变量优先)。改完重启 `dsh web`。
|
|
178
|
+
|
|
179
|
+
| 变量 | 默认 | 说明 |
|
|
180
|
+
| --- | --- | --- |
|
|
181
|
+
| `LAN_GATE_PORT` | `3088` | 网关端口;被占用自动往上试(最多 +20) |
|
|
182
|
+
| `LAN_GATE_HOST` | `127.0.0.1` | 监听地址;反代不在本机时才需要放开 |
|
|
183
|
+
| `LAN_GATE_TARGET_PORT` | `3080` | 本机 DSH Web UI 端口 |
|
|
184
|
+
| `LAN_GATE_RATE_LIMIT` | `120` | 未配对请求的每分钟上限(按真实客户端 IP) |
|
|
185
|
+
| `LAN_GATE_TRUSTED_PROXIES` | 空 | 逗号分隔 IP;反代不在本机时必填 |
|
|
186
|
+
| `LAN_GATE_VAPID_SUBJECT` | `mailto:admin@localhost` | 推送联系人。**iOS 必须改成真实邮箱或 https 网址**,否则 Apple 拒发 |
|
|
187
|
+
| `DSH_PUSH_EVENTS` | `agent/turn-stopping` | 触发自动推送的事件名,逗号分隔 |
|
|
188
|
+
| `DSH_PUSH_DEBOUNCE_MS` | `15000` | 两条自动推送的最小间隔 |
|
|
189
|
+
| `DSH_PUSH_SUMMARY` | 关 | 设 `1` 让通知带上本回合最后一条回复(截 120 字) |
|
|
190
|
+
| `DSH_PUSH_TOOL` | 开 | 设 `0` 关掉模型可调用的 `push_notify` 工具 |
|
|
191
|
+
|
|
192
|
+
上传大小上限(默认 20MB)在插件行的 `config.maxUploadBytes` 里改。
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## 功能
|
|
197
|
+
|
|
198
|
+
- 会话列表主屏 + 独立会话页两级页面栈,横向推入推出
|
|
199
|
+
- 主屏插件入口 chips,按已装插件自动出现,显隐可自定义
|
|
200
|
+
- composer 重排:控件图标化,权限/模型菜单变成底部 sheet
|
|
201
|
+
- 会话信息卡:六格统计 + 导出日志 / 重命名 / Fork / 归档
|
|
202
|
+
- 同一回合的推理与工具调用默认折叠成一条「过程 · N 步」
|
|
203
|
+
- 手势:左边缘右滑返回、底部 sheet 下滑关闭
|
|
204
|
+
- 手机本地附件上传:落到会话工作目录 `.dsh-uploads/`,输入框追加 `@` 引用,发不发你说了算
|
|
205
|
+
- 配对码换长期设备令牌,认令牌不认 IP,可随时吊销
|
|
206
|
+
- 管理面(生成配对码 / 管理设备 / 触发推送)只认本机直连,经反代一律 403
|
|
207
|
+
- 真 PWA:manifest + service worker,可装到主屏、可离线打开
|
|
208
|
+
- 真 Web Push:VAPID + aes128gcm,通知默认不带对话正文
|
|
209
|
+
- `push_notify` 工具:模型可在关键节点自己推一条,带限流
|
|
210
|
+
|
|
211
|
+
深度说明:[界面](docs/interface.md) · [公网接入](docs/remote-access.md)
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 已知问题
|
|
216
|
+
|
|
217
|
+
**iOS 26.x 独立 PWA 视口缩水**:加到主屏后视口底部会少掉一条状态栏高度,普通 Safari 标签页正常。这是 iOS 系统缺陷,缺掉的区域在文档之外,CSS 够不着;本插件做了三层缓解(浅色 manifest 背景 + 安全区补偿 + 强制重排),能减轻但不保证复原。彻底恢复只能整个 App 退出重开。
|
|
218
|
+
|
|
219
|
+
**经反代访问时设置页的插件配置列表空白**:直连 `127.0.0.1:3080` 正常。根因在 DSH 官方客户端的连接就绪超时判定,不在网关。绕法是要改插件配置时回本机浏览器改,配置存在后端,改完手机侧其它功能不受影响。
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 权限与数据
|
|
224
|
+
|
|
225
|
+
- **网络**:网关只监听本机(默认 `127.0.0.1:3088`),对外暴露完全由你的反代/隧道决定;推送经浏览器推送服务商中转(内容 aes128gcm 端到端加密,服务商读不到);插件自身不向任何第三方上报数据。
|
|
226
|
+
- **文件**:附件上传只写入当前会话工作目录下的 `.dsh-uploads/`;配对状态与配置存在 `~/.dsh/lan-gate-state.json` / `lan-gate.config.json`。
|
|
227
|
+
- **凭据**:不收集、不存储任何账号密码;设备身份是本插件自己签发的随机令牌(HttpOnly Cookie)。
|
|
228
|
+
|
|
229
|
+
排障:运行日志在 `~/.dsh/logs/web.log`(网关与推送的行带 `[dsh-zen-remote-*]` 前缀);手机端界面自检可用调试徽章(首页顶栏连点 5 下开关)。安全问题请走 GitHub Security Advisories 私下报告,不要公开提 issue。
|
|
230
|
+
|
|
231
|
+
## 上游致谢
|
|
232
|
+
|
|
233
|
+
本插件的界面层衍生自 [mexiaosqwq/dsh-web-mobile](https://github.com/mexiaosqwq/dsh-web-mobile),通道层衍生自 [zylzyqzz/dsh-mobile-pwa](https://github.com/zylzyqzz/dsh-mobile-pwa)(其自身衍生自 [Bernardxu123/dsh-mobile-gate](https://github.com/Bernardxu123/dsh-mobile-gate)),均为 MIT,原始版权行保留在 [LICENSE](LICENSE)。
|
|
234
|
+
|
|
235
|
+
## License
|
|
236
|
+
|
|
237
|
+
[MIT](LICENSE)
|
package/assets/home.png
ADDED
|
Binary file
|
package/assets/info.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/assets/sheet.png
ADDED
|
Binary file
|
package/cordis.patch.yml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# dsh-zen-remote — bundle patch layer(一个包,三行 insert)
|
|
2
|
+
#
|
|
3
|
+
# 当 profile 的 dsh.profile.bundles 列了这个包时整层生效
|
|
4
|
+
# (`dsh plugin --profile web add dsh-zen-remote` 会自动写进去)。
|
|
5
|
+
# 三行都随包自带,用户不需要在自己的 profile patch 里手挂任何一行。
|
|
6
|
+
- insert:
|
|
7
|
+
# 界面半边:浏览器端 app 外壳(经 package.json 的 dsh.client 发现)
|
|
8
|
+
# + host 侧唯一一条路由(手机附件上传端点)。
|
|
9
|
+
- id: dsh-zen-remote
|
|
10
|
+
name: dsh-zen-remote
|
|
11
|
+
# 通道半边:spawn 网关子进程(配对认证 / PWA 注入 / 反代到 DSH)。
|
|
12
|
+
- id: dsh-zen-remote-gateway
|
|
13
|
+
name: dsh-zen-remote/lan-gate.mjs
|
|
14
|
+
# 推送半边:agent 回合结束推送 + 模型工具 push_notify。
|
|
15
|
+
# 以前要用户自己在 profile 的 cordis.patch.yml 里手挂,现在随包自带。
|
|
16
|
+
- id: dsh-zen-remote-push
|
|
17
|
+
name: dsh-zen-remote/dsh-push.mjs
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# dsh-zen-remote — 静态挂载示例
|
|
2
|
+
#
|
|
3
|
+
# 不想走 `dsh plugin add` 的话,把下面这段抄进你 DSH profile 的
|
|
4
|
+
# cordis.patch.yml,并把 <ABSOLUTE_PATH> 换成本仓库的 clone 目录。
|
|
5
|
+
# 走 `dsh plugin add` 的正常安装不需要这个文件——包自带的
|
|
6
|
+
# cordis.patch.yml 已经把三行都挂好了。
|
|
7
|
+
- insert:
|
|
8
|
+
- id: dsh-zen-remote
|
|
9
|
+
name: dsh-zen-remote
|
|
10
|
+
path: file:///ABSOLUTE_PATH/dsh-zen-remote/lib/index.js
|
|
11
|
+
- id: dsh-zen-remote-gateway
|
|
12
|
+
name: dsh-zen-remote-gateway
|
|
13
|
+
path: file:///ABSOLUTE_PATH/dsh-zen-remote/lan-gate.mjs
|
|
14
|
+
- id: dsh-zen-remote-push
|
|
15
|
+
name: dsh-zen-remote-push
|
|
16
|
+
path: file:///ABSOLUTE_PATH/dsh-zen-remote/dsh-push.mjs
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# 手机界面(界面半边详解)
|
|
2
|
+
|
|
3
|
+
> `dsh-zen-remote` 的界面半边完整文档:信息架构、断点策略、安全区体系、调试徽章、兼容插件。
|
|
4
|
+
> 安装与快速上手见[根 README](../README.md);通道侧细节见 [remote-access.md](remote-access.md)。
|
|
5
|
+
> 界面基座衍生自 MIT 的 [mexiaosqwq/dsh-web-mobile](https://github.com/mexiaosqwq/dsh-web-mobile)。
|
|
6
|
+
|
|
7
|
+
## v2.0:从「窄屏适配」到「app 化外壳」
|
|
8
|
+
|
|
9
|
+
v1.0.0(fork 自 [mexiaosqwq/dsh-web-mobile](https://github.com/mexiaosqwq/dsh-web-mobile))做的是「桌面布局压成窄屏」——保留桌面那套抽屉/侧栏,靠 CSS 把它们塞进手机宽度。v2.0 把手机端重写成「两级页面栈」的 app 信息架构:启动直接落会话列表主屏,点进去是独立的会话页,两页之间横向推入/推出,不再是「桌面页面的缩小版」。改造范围只到手机断点(<768px);平板保持 v1.0.0 抽屉行为不倒退,桌面逐像素不变。
|
|
10
|
+
|
|
11
|
+
这次重写建立在上游 v1.0.0 打下的底子上(分主题 CSS 结构、构建脚本、平板兼容段大量沿用),在此向 [mexiaosqwq](https://github.com/mexiaosqwq/dsh-web-mobile) 的原始工作表示感谢。
|
|
12
|
+
|
|
13
|
+
## 效果
|
|
14
|
+
|
|
15
|
+
| 会话列表主屏 | 会话页 | 会话信息卡 | composer 权限 sheet |
|
|
16
|
+
| --- | --- | --- | --- |
|
|
17
|
+
|  |  |  |  |
|
|
18
|
+
|
|
19
|
+
## 特性
|
|
20
|
+
|
|
21
|
+
### 会话列表主屏
|
|
22
|
+
|
|
23
|
+
启动永远落在这一屏(推送深链直达会话除外),不再是桌面抽屉的窄屏版本:
|
|
24
|
+
|
|
25
|
+
- 会话按圆角卡片排列(左侧头像色块 + 标题/状态两行 + 右侧时间),运行中的会话带状态点;
|
|
26
|
+
- 顶部就是当前 workspace 名,点开弹出切换单(含「全部」);
|
|
27
|
+
- 会话列表上方一条可横滑的插件入口 chips(文件浏览、用量、Session log 等,按你实际装的插件动态出现):手写适配的几个之外,**任何在官方侧栏注册了快捷入口的插件都会被自动发现**,装上就长出对应 chip,卸载后自动消失,不用等插件适配更新;行尾「···」打开显隐自定义单,选择保存在本地,刷新后还在;
|
|
28
|
+
- 右下「+ 新建会话」文字胶囊,点按直接在当前 workspace 建会话;
|
|
29
|
+
- 右上角设置图标是官方设置弹窗的入口(迁到这里,不再挤在抽屉里)。
|
|
30
|
+
|
|
31
|
+
### 两级页面栈与转场
|
|
32
|
+
|
|
33
|
+
会话列表(主屏)与会话页是两个独立层,横向推入/推出转场;进会话页点行,回列表点头部返回按钮或左缘右滑。官方侧栏在手机断点下直接隐藏,不再是「点开的抽屉」——因为已经没有抽屉需要点开了。
|
|
34
|
+
|
|
35
|
+
### 会话页头部五件套
|
|
36
|
+
|
|
37
|
+
会话页头部只留五样东西:返回 · 会话名(+ 运行状态点)· 当前视图名(对话/轨迹,带双点指示)· 信息卡入口 · better-sidebar 入口。官方的 Chat/Trajectory 页签视觉隐藏但 DOM 还在,点信息卡里的分段控件相当于代点它。
|
|
38
|
+
|
|
39
|
+
### composer 重排
|
|
40
|
+
|
|
41
|
+
输入区整个按 app 输入条的思路重排:
|
|
42
|
+
|
|
43
|
+
- 底排控件全部图标化(附件 · 权限 · 模型 · 上下文环 · 发送),不再是挤在一起的文字按钮;
|
|
44
|
+
- 权限、模型这两个官方弹出菜单被 CSS 整成从底部升起的 sheet 样式(结构还是官方的,只换了皮肤);
|
|
45
|
+
- 分支/Todo 这类 mini chips 挪到输入卡外上方;
|
|
46
|
+
- composer 顶部不画分割线,改用渐变 mask——消息滚动到顶部/底部时自然淡入淡出,比一条硬边界更贴近原生 app。
|
|
47
|
+
|
|
48
|
+
### 会话信息卡
|
|
49
|
+
|
|
50
|
+
会话页头部的 ⓘ 打开一张底部信息卡,把原来占位置的统计栏收纳进来:轮数/步数/首字延迟/模型耗时/工具耗时/token 与缓存命中六格统计、Chat/Trajectory 切换、以及导出日志/重命名/Fork 会话/归档四个操作。
|
|
51
|
+
|
|
52
|
+
### 回合过程折叠
|
|
53
|
+
|
|
54
|
+
Chat 视图里,同一回合内的推理块、工具调用块默认折叠成一条「过程 · N 步」摘要行,点开才展开;最终回复文本永远直接可见。运行中的回合摘要行会跟着步数实时更新。仅手机断点生效。
|
|
55
|
+
|
|
56
|
+
### 手势
|
|
57
|
+
|
|
58
|
+
- 会话页左边缘往右滑 = 返回列表(有浮层或工作台开着的话先关掉它);
|
|
59
|
+
- 各类底部 sheet(信息卡、chips 自定义单、权限/模型菜单)支持下滑关闭。
|
|
60
|
+
|
|
61
|
+
### 附件上传
|
|
62
|
+
|
|
63
|
+
composer 最左的回形针打开的是**手机本地**的文件选择器(iOS 上会弹相册/拍照/选取文件三选一)——官方那套文件选择器是在跑 DSH 的电脑上弹窗,手机远程用不了。图片和文件一视同仁:都上传到会话工作目录的 `.dsh-uploads/`,composer 上方出现可删除的预览 chip(图片缩略图、文件图标+文件名),并把 `@.dsh-uploads/文件名` 追加到输入框——发不发、什么时候发,由你按官方发送键决定,不会替你自动发出。
|
|
64
|
+
|
|
65
|
+
安全上的几句话:这个功能给插件的 host 半区新增了一条 HTTP 路由(`POST /_dsh/mobile-nav/upload`),只接受同源请求,文件名清洗后只取叶子名,写入路径校验不允许越出工作目录,单文件默认上限 20MB(可在 profile 里的插件行用 `maxUploadBytes` 调整)。远程访问时,这条路由和其它请求一样在 网关半边的配对墙之后。
|
|
66
|
+
|
|
67
|
+
### 设置页与用量面板打通
|
|
68
|
+
|
|
69
|
+
主屏右上角的设置图标就是官方设置弹窗的入口(近全宽 sheet 皮肤,沿用 v1.0.0 的适配);如果你装了 dsh-usage-stats,它的用量/余额入口会作为一个 chip 出现在主屏 chips 行里,点开即用,不用先钻进设置。
|
|
70
|
+
|
|
71
|
+
### 调试徽章
|
|
72
|
+
|
|
73
|
+
手机主屏顶栏连续点 5 下(或访问 `?mobile-nav-debug=1`)唤出悬浮诊断条,显示 URL/视口/媒体查询/浮层状态/JS 错误,手机端问题取证用。桌面调试时可以用 `?mobile-nav-inset=54` 或 `?mobile-nav-inset=54,34` 伪造安全区(假刘海),在没有真实刘海屏的浏览器里也能复现顶部/底部安全区相关的布局。
|
|
74
|
+
|
|
75
|
+
### 安全区体系与 iOS 26.x 视口缩水
|
|
76
|
+
|
|
77
|
+
页面各表面的安全区留白统一收进两个可注入的 CSS 变量(`--mnav-sat`/`--mnav-sab`),平时读 `env(safe-area-inset-*)`,调试参数在时可以整体假冒——这是后面两层缓解的基础。
|
|
78
|
+
|
|
79
|
+
在这套变量之上,iOS 26.x 的 Safari/PWA 上出现了一个已知系统缺陷:独立(加到主屏)PWA 第一次弹出软键盘后,布局视口会永久性地比屏幕矮一截(`innerHeight`/`visualViewport.height`/`100dvh` 一起变小),直到整个 app 被彻底退出重开。这不是本插件的 bug,社区已有记录([参考文章](https://dev.to/cederhook/fixing-the-ios-standalone-pwa-keyboard-bug-that-shrinks-your-viewport-for-good-63d)),本插件只做了两层缓解,不是根治:
|
|
80
|
+
|
|
81
|
+
1. **视口下沉检测**——检测到系统在底部裁掉一截可视区域时,把底部安全区补偿归零,避免在已经空白的系统条上再叠一层空白;
|
|
82
|
+
2. **主动摘窗重排**——在输入框失焦、冷启动 1 秒/3 秒、切回前台后各触发一次「强制页面重排」,逼 WebKit 重新测量视口;能不能真正治好缩水,取决于具体机型和 iOS 版本,失败几次后会自动停手不再重试。
|
|
83
|
+
|
|
84
|
+
苹果修好这个系统级问题之前,两层缓解只能减少影响面,不能保证每次都完全复原。
|
|
85
|
+
|
|
86
|
+
## 断点策略
|
|
87
|
+
|
|
88
|
+
| 宽度 | 行为 |
|
|
89
|
+
| --- | --- |
|
|
90
|
+
| < 768px(手机) | 本文档描述的 app 化布局全量生效 |
|
|
91
|
+
| 768–1023px(平板) | 保持 v1.0.0 现状:抽屉 + 设置/预览浮层限宽居中,不倒退 |
|
|
92
|
+
| ≥ 1024px(桌面) | 严格 no-op,逐像素与未安装时一致 |
|
|
93
|
+
|
|
94
|
+
## 更新日志
|
|
95
|
+
|
|
96
|
+
### v2.0.0
|
|
97
|
+
|
|
98
|
+
**新增**
|
|
99
|
+
|
|
100
|
+
- 两级页面栈 app 化重排:会话列表主屏 + 独立会话页,横向转场取代桌面抽屉;
|
|
101
|
+
- 会话页头部五件套(返回/会话名/视图指示/信息卡/better-sidebar 入口);
|
|
102
|
+
- composer 重排:图标化底排控件、权限与模型菜单变身底部 sheet、顶部渐变 mask 取代硬分割线;
|
|
103
|
+
- 会话信息卡:Chat/Trajectory 切换 + 六格统计 + 导出/重命名/Fork/归档四个操作,从占地方的底部统计栏搬进按需打开的 sheet;
|
|
104
|
+
- 手势两件套:左缘右滑返回列表、各类底部 sheet 支持下滑关闭;
|
|
105
|
+
- 回合过程默认折叠:多步回合收成一条「过程 · N 步」摘要行,最终回复始终可见;
|
|
106
|
+
- 移动端附件上传:手机本地选择器 + 会话工作目录落盘 + composer 预览 chip + 草稿 @ 引用手动发送(见「附件上传」一节的安全说明);
|
|
107
|
+
- 主屏插件入口 chips:任务看板/SSH/文件浏览/用量等按已装插件动态出现,显隐可自定义并本地持久化;未手写适配的插件也能自动长出 chip——从官方侧栏的快捷入口区里现场收割图标/文案/点击目标;
|
|
108
|
+
- 调试徽章:顶栏 5 连点或 `?mobile-nav-debug=1` 唤出,新增 `?mobile-nav-inset=` 伪造安全区参数,方便桌面复现刘海相关布局。
|
|
109
|
+
|
|
110
|
+
**修复**
|
|
111
|
+
|
|
112
|
+
- iOS 独立 PWA 键盘弹出后视口永久变矮的缓解(检测 + 主动重排,非根治,见上文说明);
|
|
113
|
+
- 整页橡皮筋回弹导致顶栏/composer/FAB 跟手指一起位移的问题(锁文档滚动 + 消息区单独滚动);
|
|
114
|
+
- PWA 冷启动首帧安全区未就位(首帧 `viewport-fit=cover` 改由 网关半边注入,不再等插件 JS 迟到补);
|
|
115
|
+
- 会话行三点菜单弹出时抽屉/列表状态错乱、workbench 关闭按钮在桌面端泄漏等一系列实机反馈热修。
|
|
116
|
+
|
|
117
|
+
**内部**
|
|
118
|
+
|
|
119
|
+
- 作用域与 网关半边 理清分工:本插件管排版与交互,网关半边 只管通道(认证/推送/PWA 壳),两边 CSS 不再重叠;
|
|
120
|
+
- 新增 host 半区(`src/index.ts`):从纯 client 插件变为带一条上传路由的插件;
|
|
121
|
+
- 大量实机反馈驱动的迭代热修(S1–S8 各切片)。
|
|
122
|
+
|
|
123
|
+
### v1.0.0
|
|
124
|
+
|
|
125
|
+
**新增 / 改进**
|
|
126
|
+
|
|
127
|
+
- 全屏预览浮层:预览底部浮层可一键放大到全视口(标题栏缩放按钮,刘海安全区适配),关闭预览或抽屉时自动还原;
|
|
128
|
+
- 设置弹窗重构:分类标签收进单行横向滚动(细滚动条提示),顶部工具栏并入标签行共用一行,手机上隐藏「打开配置文件」按钮,选项区显著变大;
|
|
129
|
+
- 分支胶囊:git 分支芯片移入输入卡片(todo 卡片之上),点击目标加大、按压即时反馈;
|
|
130
|
+
- 会话头部紧凑与顺序稳定:模式徽标窄处省略、subagent 按钮居中、文件按钮固定保留;
|
|
131
|
+
- 抽屉底部顺序:文件浏览 / 导出会话日志 固定在用量徽章之上;
|
|
132
|
+
- 模型 ID 完整显示:composer 行内有空间时不再省略;
|
|
133
|
+
- 文件树 / 预览交互:仅文件行可打开预览(目录行不再误弹缓存预览)、已选中行可重开、折叠按钮可靠关闭、预览打开时文件树自动让位;
|
|
134
|
+
- 诊断徽章:`?mobile-nav-debug=1` 实时显示 URL/视口/媒体查询/浮层/JS 错误,默认 no-op。
|
|
135
|
+
|
|
136
|
+
**修复**
|
|
137
|
+
|
|
138
|
+
- 目录选择器被设置弹窗规则劫持(issue #12):点笔形「编辑」进入手动输入后弹窗被顶到屏幕顶部、路径输入框被隐藏——目录选择器不再命中移动端设置适配规则;
|
|
139
|
+
- 预览浮层全屏几何规则回归(1779cd4)以及关闭后全屏标记残留;
|
|
140
|
+
- 抽屉底部徽章平票错序;subagent 弹层小屏溢出;统计栏误标 todo 面板。
|
|
141
|
+
|
|
142
|
+
**内部**
|
|
143
|
+
|
|
144
|
+
- CSS 按主题拆为 `src/client/styles/`(base / layout / compat / misc),client effects 拆分为独立模块;构建器支持子目录递归内联。
|
|
145
|
+
|
|
146
|
+
### v0.2.0
|
|
147
|
+
|
|
148
|
+
**新增 / 改进**
|
|
149
|
+
|
|
150
|
+
- 平板/宽幅移动端(768–1023px):设置弹窗与 Explorer/Preview 浮层限宽居中,避免右侧大块空白;
|
|
151
|
+
- Markdown 表格在移动端撑满消息列宽,减少表格内/右侧留白;
|
|
152
|
+
- 用户消息气泡自适应宽度:短消息紧凑靠右,长消息可撑满消息列宽;
|
|
153
|
+
- 模型选择器:模型名可完整显示,切换菜单在触发按钮上方水平居中;
|
|
154
|
+
- 底部权限/模型选择/上下文小圈间距优化(12/10/12)。
|
|
155
|
+
|
|
156
|
+
**修复**
|
|
157
|
+
|
|
158
|
+
- 预览浮层右上角缩放/收起按钮无法关闭的问题;
|
|
159
|
+
- 用户消息气泡全宽后因 `content-box` 导致溢出屏幕的问题;
|
|
160
|
+
- 模型切换菜单在小屏下偏左/溢出的问题。
|
|
161
|
+
|
|
162
|
+
## 兼容插件
|
|
163
|
+
|
|
164
|
+
- [dsh-better-sidebar](https://github.com/omdsh-dev/DSH-better-sidebar)(移动端全宽抽屉,本插件在会话页头部给它留入口位)——本机实测 **0.12.2**
|
|
165
|
+
- [dsh-usage-stats](https://github.com/Ychris12138/dsh-usage-stats)(用量与余额,主屏 chips 行可直接打开)
|
|
166
|
+
- [@opendsh/dsh-plugin-scheduled-tasks](https://github.com/Ceelog/dsh-plugins)(定时任务,主屏 chips 行自动收割入口)——本机实测 **0.2.0**
|
|
167
|
+
- dsh-at-file(@文件引用)
|
|
168
|
+
- [dsh-vision-toolkit](https://www.npmjs.com/package/@anionex/dsh-vision-toolkit)(图像 Q&A/OCR,配合手机端附件上传使用)
|
|
169
|
+
- [dsh-web-ui 全家桶](https://www.npmjs.com/package/@linxin666/dsh-web-ui-all)(文件树 / 预览 / 任务看板 / SSH / 宠物 / 会话统计 / 远程配对 / 设置)——沿用上游兼容规则,本次未扩展
|
|
170
|
+
|
|
171
|
+
## 安装
|
|
172
|
+
|
|
173
|
+
```sh
|
|
174
|
+
dsh plugin add dsh-zen-remote
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
装完重启 `dsh web`。手动写法与本地开发装法见[根 README](../README.md#安装)。
|
|
178
|
+
|
|
179
|
+
## 构建
|
|
180
|
+
|
|
181
|
+
```sh
|
|
182
|
+
pnpm install
|
|
183
|
+
pnpm build # 产物 lib/ 与源码同步入库,改动源码后重新构建再提交
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## 验证
|
|
187
|
+
|
|
188
|
+
- `pnpm verify` 类型检查、`pnpm test` 全量测试;`dsh --profile web --dump-config` 应出现插件层;
|
|
189
|
+
- 自检脚本:`node scripts/check-sunk-viewport.mjs`、`node scripts/check-attach-upload.mjs`、`node scripts/check-upload-endpoint.mjs`(需 Node ≥ 23.6);
|
|
190
|
+
- 移动端(390px):启动落会话列表、进出会话页转场、composer 权限/模型 sheet、信息卡统计与四个操作、附件上传;
|
|
191
|
+
- 平板(768px):抽屉 + 限宽居中,与 v1.0.0 一致;
|
|
192
|
+
- 桌面端(≥1024px):与未安装时一致。
|
|
193
|
+
|
|
194
|
+
## 兼容性
|
|
195
|
+
|
|
196
|
+
需要 `:has()`(Chromium 105+);`prefers-reduced-motion: reduce` 下自动禁用动画。
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
[MIT](../LICENSE)
|