dsh-desktop-link 1.0.0 → 1.2.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/README.md +197 -159
- package/assets/icon-180.png +0 -0
- package/assets/icon-96.png +0 -0
- package/client.js +419 -81
- package/index.js +397 -164
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,159 +1,197 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
在 **DeepSeek Harness(DSH)**
|
|
4
|
-
|
|
5
|
-
专门为 **DSHA(DeepSeek Harness 安卓启动器)** 设计 —— 在手机上的 DSHA 里点这个按钮,会交给系统浏览器打开你电脑上的 DSH,而 DSHA 自己那套 agent 照常独立运行。
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
dsh plugin --profile web add
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
###
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
1
|
+
# dsh-desktop-link
|
|
2
|
+
|
|
3
|
+
在 **DeepSeek Harness(DSH)** 的侧栏底部加两个按钮:一个点一下就在系统浏览器 / 新标签页里打开**桌面版 DSH** 的 Web GUI,另一个(齿轮)用来**在界面里直接填地址**。
|
|
4
|
+
|
|
5
|
+
专门为 **DSHA(DeepSeek Harness 安卓启动器)** 设计 —— 在手机上的 DSHA 里点这个按钮,会交给系统浏览器打开你电脑上的 DSH,而 DSHA 自己那套 agent 照常独立运行。
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
🖥 → 桌面版 ⚙
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
[](https://www.npmjs.com/package/dsh-desktop-link)
|
|
12
|
+
[](LICENSE)
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
dsh plugin --profile web add dsh-desktop-link
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 它解决什么
|
|
21
|
+
|
|
22
|
+
DSHA 的内置浏览器只导航它自己的 `http://127.0.0.1:<端口>`,没有「填个网址去连别的机器」的入口。
|
|
23
|
+
但 DSHA 本来就有这条规则:**顶层导航离开本机 DSH 服务时,交给系统浏览器**(`WebPreviewActivity.shouldOverrideUrlLoading` → `ACTION_VIEW`)。
|
|
24
|
+
|
|
25
|
+
这个插件就是给这条已有规则加一个按钮入口 —— 不改 DSHA、不需要 root、不需要 `am start`。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 行为
|
|
30
|
+
|
|
31
|
+
| 点击环境 | 结果 |
|
|
32
|
+
|---|---|
|
|
33
|
+
| **手机**(DSHA 的 WebView 或手机浏览器) | 导航离开 DSH 服务 → DSHA 交给系统浏览器 → 打开桌面版 GUI |
|
|
34
|
+
| **电脑浏览器** | `target="_blank"` 开新标签页,当前 GUI 不受影响 |
|
|
35
|
+
|
|
36
|
+
未配置地址时按钮变灰;此时点它会直接打开齿轮那个设置框,不会跳到一个死链。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 安装
|
|
41
|
+
|
|
42
|
+
### 从 npm(推荐)
|
|
43
|
+
|
|
44
|
+
```sh
|
|
45
|
+
dsh plugin --profile web add dsh-desktop-link
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 从本仓库(开发循环)
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
git clone https://github.com/lzlrt/dsha-desktop-link
|
|
52
|
+
dsh plugin --profile web add link:$(pwd)/dsha-desktop-link
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 从打包好的 tgz
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
dsh plugin --profile web add /path/to/dsh-desktop-link-1.2.0.tgz
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### 装到手机上的 DSHA
|
|
62
|
+
|
|
63
|
+
DSHA → 插件 → 添加 → 粘贴一个能下到这个包的 URL,例如:
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
https://registry.npmjs.org/dsh-desktop-link/-/dsh-desktop-link-1.2.0.tgz
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
或在 DSHA 插件页直接填包名 `dsh-desktop-link`。
|
|
70
|
+
|
|
71
|
+
或从本地导入(`adb push` 到 `/sdcard/Download/` 后在插件页选文件)。
|
|
72
|
+
|
|
73
|
+
装完在插件管理页点「重启 Web」。
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## 配置地址
|
|
78
|
+
|
|
79
|
+
### 在界面上填(手机推荐)
|
|
80
|
+
|
|
81
|
+
点侧栏底部那个**齿轮** → 填两个框 → 保存。写盘、立即生效,不用重启、不用碰命令行。
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
┌─────────────────────────────┐
|
|
85
|
+
│ 桌面版地址 │
|
|
86
|
+
│ 填一次就存在这台电脑上,手机和电脑都读同一份。 │
|
|
87
|
+
│ 当前生效(桌面地址文件):https://… │
|
|
88
|
+
│ │
|
|
89
|
+
│ 桌面版地址 │
|
|
90
|
+
│ [https://xxxx.dsh-market.com] │
|
|
91
|
+
│ 长期地址,留空则自动用固定中继。 │
|
|
92
|
+
│ │
|
|
93
|
+
│ 点按钮时打开的地址 │
|
|
94
|
+
│ [https://…/open.html?k=… ] │
|
|
95
|
+
│ 留空就等于上面的地址。 │
|
|
96
|
+
│ [取消] [保存] │
|
|
97
|
+
└─────────────────────────────┘
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
保存会写进 `$DSH_HOME/desktop-url.txt`(先写临时文件再 rename,半个文件不会被读走)。
|
|
101
|
+
两个框都清空 = 删掉该文件,退回自动探测。
|
|
102
|
+
|
|
103
|
+
### 用配置文件
|
|
104
|
+
|
|
105
|
+
插件自身不带默认地址 —— 它从下面这些地方按顺序找,命中即停:
|
|
106
|
+
|
|
107
|
+
| 优先级 | 来源 |
|
|
108
|
+
|---|---|
|
|
109
|
+
| 1 | 本行 `config.desktopUrl` / `config.launchUrl`(profile 补丁里) |
|
|
110
|
+
| 2 | 环境变量 `DSH_DESKTOP_URL` / `DSH_DESKTOP_LAUNCH_URL` |
|
|
111
|
+
| 3 | `$DSH_HOME/desktop-url.txt` 第 1 行(桌面地址)/ 第 2 行(点击时打开的地址) |
|
|
112
|
+
| 4 | `$DSH_HOME/remote-web-ui-registry/web.json` 的 `id` → `https://<id>.dsh-market.com`(仅当装了 `dsh-remote-web-ui` 并开了固定域名中继) |
|
|
113
|
+
|
|
114
|
+
`desktop-url.txt` 是最好改的一个 —— **改完刷新页面即生效**,不用重启:
|
|
115
|
+
|
|
116
|
+
```text
|
|
117
|
+
# 第一行:桌面版长期地址(书签、复制链接用)
|
|
118
|
+
https://your-desktop.example.com
|
|
119
|
+
|
|
120
|
+
# 第二行(可选):点按钮时真正打开的地址。
|
|
121
|
+
# 指向一个「每次铸新配对码」的端点,未配对的手机也能一次进。
|
|
122
|
+
https://your-desktop.example.com/pair-entry
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
只写一行 = 按钮直接开那一行。删掉文件 = 退回优先级 4。
|
|
126
|
+
|
|
127
|
+
### 两种地址的区别
|
|
128
|
+
|
|
129
|
+
| 字段 | 用途 |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `desktopUrl` | 长期地址。锚点的 `href` 用它,中间键 / 复制链接 / 收藏都按这个走 |
|
|
132
|
+
| `launchUrl` | 点击时实际打开的地址。可以是一个会临时铸码的端点,让从未配对过的设备也能一次进入 |
|
|
133
|
+
|
|
134
|
+
没配 `launchUrl` 时它等于 `desktopUrl`。
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## 未配对的手机会看到 401
|
|
139
|
+
|
|
140
|
+
DSH 的远程访问是要配对的。未配对设备直接打开桌面地址会被 harness 的认证栅栏拒绝 —— 这是配对机制正常工作,不是这个插件的 bug。
|
|
141
|
+
|
|
142
|
+
三种处理方式:
|
|
143
|
+
|
|
144
|
+
1. **先配对一次**:配对 cookie 默认有效期一年,之后点按钮直接进。
|
|
145
|
+
2. **配 `launchUrl` 指向铸码端点**:每次点击拿新码,永远有效。
|
|
146
|
+
3. **手机端自动铸码**:若本机装了 `dsh-remote-web-ui`,手机点击时插件会先调同源 `/api/pair/issue` 铸一枚一次性码再跳转(该接口只应答回环,所以页面能直接调)。没装则自动退回直接打开 `desktopUrl`。
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 接口
|
|
151
|
+
|
|
152
|
+
| 方法 | 路径 | 说明 |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| GET | `/api/desktop-link/info` | `{"ok":true,"launchUrl":"…","desktopUrl":"…","source":"…"}` |
|
|
155
|
+
| POST | `/api/desktop-link/config` | body `{"desktopUrl":"…","launchUrl":"…"}` → 写入 `desktop-url.txt`,返回写入后的解析结果与 `path` |
|
|
156
|
+
|
|
157
|
+
POST 只接受 `http(s)` URL:传了非空值但格式不对会返回 `400` 并说明原因,不会静默清空。
|
|
158
|
+
请求体上限 8 KiB,非 `POST` 返回 `405`。
|
|
159
|
+
|
|
160
|
+
每次请求重新解析地址,所以改配置文件不需要重启。
|
|
161
|
+
另外 Host 半区会在 `webserver/index-inject` 里注入 `globalThis.__DSHA_DESKTOP_LINK__`,让按钮首帧就能拿到地址;全局缺失时 Client 半区回退到上面那个接口。
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## 结构
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
package.json 清单:dsh.bundle.patch + dsh.client(platform: web)
|
|
169
|
+
cordis.patch.yml 插入一行 dsha-desktop-link
|
|
170
|
+
index.js Host 半区:地址解析 + /info + /config + index 全局
|
|
171
|
+
client.js Client 半区:注册 sidebar.footer.action ×2 + 设置框
|
|
172
|
+
icon.svg 显示器 + 外跳箭头
|
|
173
|
+
locale/{zh,en}.json meta.title / meta.description
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### 实现要点
|
|
177
|
+
|
|
178
|
+
- 注册 `sidebar.footer.action` 两次(`replaceRisk: none`):启动按钮 `order: 10`,齿轮 `order: 11`,都排在官方「远程访问」之后。
|
|
179
|
+
- 设置框跟齿轮挂在同一棵组件树里(`position: fixed` 覆盖层),不额外 `createRoot` —— 这样不依赖 `react-dom/client` 是否在页面可 require 的白名单里。
|
|
180
|
+
- 两个按钮之间的状态用一个模块级 store 同步,保存完另一个立刻拿到新地址,不用刷新。
|
|
181
|
+
- `Config` 导出是**可选**的:`@deepseek-ai/schemastery` 只存在于 DSH 安装内部,运行时按包名 → `process.argv[1]` 上溯 → Node 全局路径依次找;找不到就整个不导出 `Config`,插件照常工作,只是没有 DSH 自带的设置表单。
|
|
182
|
+
- 手机与电脑的分支靠 `navigator.userAgent` 判定;桌面侧完全走原生锚点行为,不拦点击。
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 已知限制
|
|
187
|
+
|
|
188
|
+
1. **Host 半区(`index.js`)改动需要重装插件或重启 `dsh web`**;Client 半区(`client.js`)刷新页面即生效(有 `pnpm run dev:web` 监听时可免刷新)。
|
|
189
|
+
2. 侧栏折叠成 56px 轨道时只显示图标,展开后才显示「桌面版」文字。
|
|
190
|
+
3. 手机端「点击时铸码」依赖本机装了 `dsh-remote-web-ui`(本插件不声明这个依赖,装不装都能用,只是没有自动铸码)。
|
|
191
|
+
4. 需要 DSH `>= 0.2.1-rc.2`(`webserver/index-inject` 事件与 `sidebar.footer.action` 槽位)。
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
|
Binary file
|
|
Binary file
|