dsh-remote-bridge 0.0.0-stage → 2.2.1
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/LICENSE +661 -0
- package/README.en.md +322 -0
- package/README.md +318 -2
- package/assets/app-qr-gitee.png +0 -0
- package/assets/app-qr-gitee.svg +1 -0
- package/assets/app-qr-github.png +0 -0
- package/assets/app-qr-github.svg +1 -0
- package/cordis.patch.yml +16 -0
- package/docs/api/asyncapi.yaml +86 -0
- package/docs/api/openapi.yaml +1065 -0
- package/kotlin-sdk/README.md +28 -0
- package/kotlin-sdk/build.gradle.kts +19 -0
- package/kotlin-sdk/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/kotlin-sdk/gradle/wrapper/gradle-wrapper.properties +7 -0
- package/kotlin-sdk/gradlew +252 -0
- package/kotlin-sdk/gradlew.bat +94 -0
- package/kotlin-sdk/settings.gradle.kts +1 -0
- package/kotlin-sdk/src/main/kotlin/ai/deepseek/dsh/workspace/DshWorkspaceClient.kt +691 -0
- package/lib/client.cjs +30855 -0
- package/lib/index.d.ts +1261 -0
- package/lib/index.js +4008 -0
- package/package.json +108 -4
package/README.en.md
ADDED
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
# dsh-remote-bridge
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Translates DSH's private remote protocol into a versioned REST API for mobile and third-party clients, plus a centralized settings center on the desktop.</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="./README.md">中文</a> · English
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img alt="Version" src="https://img.shields.io/badge/version-v2.2.1-087f8c">
|
|
13
|
+
<img alt="DSH plugin" src="https://img.shields.io/badge/DeepSeek_Harness-plugin-1f2328">
|
|
14
|
+
<img alt="Platforms" src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-586069">
|
|
15
|
+
<img alt="License" src="https://img.shields.io/badge/license-AGPL--3.0-2da44e">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
`dsh-remote-bridge` is the remote-access bridge plugin for DeepSeek Harness (DSH). It translates DSH's private remote protocol into a versioned REST API so dsh-companion ([GitHub](https://github.com/westanke/dsh-companion) · [Gitee](https://gitee.com/westanke/dsh-companion)) and other trusted clients can keep using the same chat, workspace, and file capabilities while away from the machine. On the desktop it provides a **Phone settings** section inside your DSH settings, rendering six tabs inline (Roots / Remote / Devices / Trash / Audit / App download). **The desktop no longer offers a file-management UI**: the file tree and editor were deleted in 2.2.0 — manage files from the phone app, or ask the agent to use its tools in a conversation (see "No file-management UI on the desktop").
|
|
19
|
+
|
|
20
|
+
The interface is bilingual and defaults to Chinese. Prebuilt packages run on Windows, macOS, and Linux without compiling on the target server.
|
|
21
|
+
|
|
22
|
+
> **Version warning**: the published `v2.0.0` and `v2.0.1` have serious defects (`v2.0.0` fails to read any historical images; `v2.0.1` cannot activate the plugin). Use **`v2.2.0`** (or ≥ `v2.0.4`).
|
|
23
|
+
> `v2.0.2` and `v2.0.3` were **never released** — do not look for installers under those version numbers.
|
|
24
|
+
|
|
25
|
+
> **DSH 0.2.x compatibility**: this branch adds a compatibility layer for DSH `0.2.0-rc.2` on top of
|
|
26
|
+
> upstream `v1.0.0`. DSH 0.2.x replaced `dsh-host-apiproxy` (which provided the `apiProxy` service)
|
|
27
|
+
> with `dsh-api-gateway`, leaving the upstream release unable to start on 0.2.x — it surfaces as
|
|
28
|
+
> "adding an authorized root returns 405". Background, rationale, changes, and test results are in
|
|
29
|
+
> [DSH 0.2.x compatibility notes](./docs/project/DSH-0.2-COMPAT.md).
|
|
30
|
+
|
|
31
|
+
## What it looks like
|
|
32
|
+
|
|
33
|
+
The desktop entry lives **inside your DSH settings**: under **📱 Phone access** you will find **📱 Phone settings**, which renders six tabs inline — no second dialog. It is settings-only and contains **no file tree**: the standalone page `/dsh-workspace` and its file tree and CodeMirror editor were deleted in 2.2.0. The reason and the cost are covered in "No file-management UI on the desktop" below.
|
|
34
|
+
|
|
35
|
+
Remote access remains disabled until a local administrator chooses a bind address, port, and initial device permissions.
|
|
36
|
+
|
|
37
|
+
> This section used to carry two UI screenshots, but both showed the pre-rename interface (titled "DSH 文件工作区"; the remote-access one was still labelled v1.0.0 and showed the file tree and settings as two stacked dialogs). They no longer match the shape described above, so they were removed rather than left to mislead. Re-recording needs a browser environment that can drive the plugin panel, which is not available here.
|
|
38
|
+
|
|
39
|
+
## About the rename (2.0.4)
|
|
40
|
+
|
|
41
|
+
The plugin was renamed from `dsh-workspace` to `dsh-remote-bridge`. The old name was narrower than the content: the plugin actually translates DSH's private remote protocol into versioned REST so a phone can reach this machine remotely, and adds a settings center on top — "workspace" is only one page of that.
|
|
42
|
+
|
|
43
|
+
**The rename only changes what you install and what the bundle is called. The following external contracts are deliberately unchanged:**
|
|
44
|
+
|
|
45
|
+
| Unchanged | Location | Why it must stay |
|
|
46
|
+
| --- | --- | --- |
|
|
47
|
+
| REST prefix `/dsh-workspace-api` | `src/host/server.ts` | Published apps hard-code it |
|
|
48
|
+
| State directory (`dataDir`, default `dsh-workspace`) | DSH profile config | A new directory would erase every authorized root and the trash |
|
|
49
|
+
|
|
50
|
+
**Two items that are no longer contracts** (both retired with the standalone page in 2.2.0):
|
|
51
|
+
|
|
52
|
+
- **The standalone page path `/dsh-workspace`**: that page (file tree + CodeMirror editor) was deleted, so the path went with it. It is a different thing from the REST prefix `/dsh-workspace-api` — **the prefix stays and remains the app's contract; the page is gone and promises nothing**.
|
|
53
|
+
- **The browser storage key `dsh-workspace-device-token`**: only that deleted page ever read or wrote it; nothing in this repo or in the app touches it now. A key nobody reads is not a contract, so it is not listed above. The name itself is not recycled, to avoid adding a red herring when debugging later.
|
|
54
|
+
|
|
55
|
+
So seeing `dsh-workspace` in a REST address or the state directory is **expected**, not an incomplete rename.
|
|
56
|
+
|
|
57
|
+
## Quick install
|
|
58
|
+
|
|
59
|
+
### Requirements
|
|
60
|
+
|
|
61
|
+
- A working DeepSeek Harness WebUI installation
|
|
62
|
+
- DSH kernel `0.1.x` or `0.2.x` (0.2.x is supported by this branch's compatibility layer — see [DSH 0.2.x compatibility notes](./docs/project/DSH-0.2-COMPAT.md))
|
|
63
|
+
- Node.js `^22.19.0` or `>=24.0.0`
|
|
64
|
+
- Port `3090`, or another available port
|
|
65
|
+
|
|
66
|
+
Run as the same operating-system user that runs DSH WebUI. **The npm package name is recommended** — all three routes install the same build:
|
|
67
|
+
|
|
68
|
+
```sh
|
|
69
|
+
# 1. npm package name (recommended: a prebuilt tarball, so pnpm never asks to approve a build)
|
|
70
|
+
dsh plugin --profile web add dsh-remote-bridge
|
|
71
|
+
|
|
72
|
+
# ...or point at the mainland-China mirror
|
|
73
|
+
dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
|
|
74
|
+
|
|
75
|
+
# 2. tarball from the GitHub release
|
|
76
|
+
dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.2.1/dsh-remote-bridge-2.2.1.tgz
|
|
77
|
+
|
|
78
|
+
# 3. tarball from the Gitee release (faster from mainland China)
|
|
79
|
+
dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.2.0/dsh-remote-bridge-2.2.0.tgz
|
|
80
|
+
|
|
81
|
+
npx @deepseek-ai/dsh web
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> `dsh plugin add` is a thin wrapper over `pnpm add`, so pnpm options such as `--registry` work directly.
|
|
85
|
+
>
|
|
86
|
+
> This README is shared verbatim by GitHub and Gitee, so any address that must carry a hostname
|
|
87
|
+
> (the install commands, release downloads) lists both hosts. Relative links follow the site you
|
|
88
|
+
> are reading on, but `/releases/download/...` has no relative form. The npm package name is the
|
|
89
|
+
> same as the GitHub repository, so it reads identically on both hosts.
|
|
90
|
+
|
|
91
|
+
Restart DSH after installation, then open settings — **Phone settings** sits right below **Phone access**. It is settings-only and does **not** contain the file tree. The in-conversation **Files** tab was removed in 2.0.4. **The desktop no longer offers a UI for browsing or editing files**: the standalone page `/dsh-workspace` was deleted in 2.2.0 — use the phone app, or ask the agent to use its tools in a conversation.
|
|
92
|
+
|
|
93
|
+
To install a downloaded release archive:
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
dsh plugin --profile web add ./dsh-remote-bridge-2.2.1.tgz
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## First connection
|
|
100
|
+
|
|
101
|
+
1. Open DSH settings and go to **Phone settings** (below **Phone access**; it lands on **Roots**).
|
|
102
|
+
2. Add a local directory under **Roots** and give it a recognizable label.
|
|
103
|
+
3. For mobile access, go to **Remote**, enter the bind IP and port, and save them.
|
|
104
|
+
4. Select **Enable and create pairing**, then enter the ten-minute one-time code in the app.
|
|
105
|
+
5. In the phone app's file page, select that root to browse and edit files.
|
|
106
|
+
|
|
107
|
+
Remote access cannot be enabled before at least one root exists. Installing the plugin does not expose it to the LAN; it listens on loopback until a local administrator enables remote access.
|
|
108
|
+
|
|
109
|
+
## Features
|
|
110
|
+
|
|
111
|
+
### No file-management UI on the desktop
|
|
112
|
+
|
|
113
|
+
2.2.0 deleted the standalone page `/dsh-workspace`, including the whole file tree, the upload/download entry points, and the CodeMirror 6 editor. The phone app's file page already covers the same ground natively, nobody used the desktop page, and it bloated the published package from **0.25 MB to 1.72 MB**.
|
|
114
|
+
|
|
115
|
+
The cost, stated plainly — **on the desktop there are now only two ways to touch files**:
|
|
116
|
+
|
|
117
|
+
1. Talk to the agent in a conversation and let it read and write files with its tools;
|
|
118
|
+
2. Open a terminal and do it yourself.
|
|
119
|
+
|
|
120
|
+
Mobile is unaffected: the app's file page still works against the same REST file endpoints the plugin kept (`/dsh-workspace-api` prefix, `/roots`, `/roots/{rootId}/content`, and so on — none were removed). Trash entries now come only from the phone app.
|
|
121
|
+
|
|
122
|
+
### Desktop settings panel
|
|
123
|
+
|
|
124
|
+
The entry lives in DSH settings under the title **Phone settings**. It renders its rail and content **inline** — no pop-up — with a horizontal rail, landing on **Roots**:
|
|
125
|
+
|
|
126
|
+
| Section | Purpose |
|
|
127
|
+
| --- | --- |
|
|
128
|
+
| Roots | Add or remove authorized directories and set display labels |
|
|
129
|
+
| Remote | Set bind IP/port, enable remote access, and create pairing codes |
|
|
130
|
+
| Devices | Inspect and revoke device scopes and per-root grants |
|
|
131
|
+
| Trash | View and restore deleted entries (only deletions made from the phone app appear here) |
|
|
132
|
+
| Audit | Operation type and target audit records |
|
|
133
|
+
| App download | Scan to install the Android client; the codes point at both hosts' Releases list pages |
|
|
134
|
+
|
|
135
|
+
The sidebar gear button was **removed**: having the entry in both the sidebar and the settings page gave one thing two starting points. The in-conversation **Files** tab is gone too, so the desktop now has exactly one entry point.
|
|
136
|
+
|
|
137
|
+
### Stable client API
|
|
138
|
+
|
|
139
|
+
The companion Android client is [dsh-companion](https://github.com/westanke/dsh-companion)
|
|
140
|
+
([Gitee](https://gitee.com/westanke/dsh-companion)) — scan either code below with your phone to
|
|
141
|
+
download it. Both point at the **Releases list page** of their host, so publishing a new version
|
|
142
|
+
never requires regenerating them:
|
|
143
|
+
|
|
144
|
+
| GitHub | Gitee (faster from mainland China) |
|
|
145
|
+
| --- | --- |
|
|
146
|
+
|  |  |
|
|
147
|
+
| <https://github.com/westanke/dsh-companion/releases> | <https://gitee.com/westanke/dsh-companion/releases> |
|
|
148
|
+
|
|
149
|
+
> The codes encode the Releases **list page**, not a specific APK filename — so a new release
|
|
150
|
+
> never needs new artwork, and whoever scans always lands on the latest version. Both images are
|
|
151
|
+
> produced by `pnpm qr:app` (`scripts/generate-app-qr.mjs`), which verifies its own output with an
|
|
152
|
+
> independent decoder; the test suite also decodes the committed files back and checks the address.
|
|
153
|
+
|
|
154
|
+
Once the app is installed, generate a config text or pairing code under
|
|
155
|
+
**Phone settings → Remote access** to connect it to this machine.
|
|
156
|
+
|
|
157
|
+
The public API is independent of DSH private wire protocols. Authorized clients can:
|
|
158
|
+
|
|
159
|
+
- list, register, rename, and remove DSH workspace registrations;
|
|
160
|
+
- create, rename, fork, and archive sessions;
|
|
161
|
+
- read history, stream text and reasoning, steer messages, and cancel runs;
|
|
162
|
+
- display TODOs, slash commands, permission modes, and approval requests;
|
|
163
|
+
- select Agents, models, and reasoning effort;
|
|
164
|
+
- inspect or update built-in and fully custom model providers;
|
|
165
|
+
- manage files and trash within explicitly granted roots.
|
|
166
|
+
|
|
167
|
+
## Remote access and security
|
|
168
|
+
|
|
169
|
+
The default remote target is `0.0.0.0:3090`; both values are configurable. Clients may connect through any reachable IP address or domain name.
|
|
170
|
+
|
|
171
|
+
HTTP is supported and TLS is not mandatory. That keeps trusted-LAN and temporary deployments simple, but plain HTTP sends device tokens, chat, and file content in clear text. Use HTTPS through Caddy/Nginx, a VPN, Tailscale/WireGuard, or a trusted tunnel on public or untrusted networks.
|
|
172
|
+
|
|
173
|
+
The following controls remain active over both HTTP and HTTPS:
|
|
174
|
+
|
|
175
|
+
- ten-minute, single-use pairing codes;
|
|
176
|
+
- 256-bit device tokens stored server-side only as digests;
|
|
177
|
+
- revocable scopes and per-root grants;
|
|
178
|
+
- separate rate limits for pairing, authentication failures, and normal requests;
|
|
179
|
+
- audit records that omit tokens, file bodies, and chat bodies;
|
|
180
|
+
- no automatic access to roots added after a device was paired.
|
|
181
|
+
|
|
182
|
+
Only a loopback client may add roots, change device grants, create pairing codes, configure the listener, or permanently purge trash.
|
|
183
|
+
|
|
184
|
+
## Path boundary
|
|
185
|
+
|
|
186
|
+
External requests use `rootId + relativePath`, never an absolute server path.
|
|
187
|
+
|
|
188
|
+
- Wire paths use `/`.
|
|
189
|
+
- Absolute paths, drive letters, UNC paths, backslashes, null bytes, and `.` or `..` segments are rejected.
|
|
190
|
+
- Every operation checks path segments for symlinks, junctions, and reparse points.
|
|
191
|
+
- Deleting a final link removes the link itself without traversing its target.
|
|
192
|
+
- Save temp files are placed beside the destination to avoid cross-device replacement failures.
|
|
193
|
+
|
|
194
|
+
Removing a DSH workspace removes only its WebUI registration. Directories, files, and session logs remain. Archiving a session hides it from the default list while preserving its log.
|
|
195
|
+
|
|
196
|
+
## Public API
|
|
197
|
+
|
|
198
|
+
REST base URL:
|
|
199
|
+
|
|
200
|
+
```text
|
|
201
|
+
http://HOST:PORT/api/v1
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Every request except health and pairing exchange uses:
|
|
205
|
+
|
|
206
|
+
```http
|
|
207
|
+
Authorization: Bearer DEVICE_TOKEN
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
| Endpoint | Purpose |
|
|
211
|
+
| --- | --- |
|
|
212
|
+
| `GET /healthz` | Service, API, and plugin version |
|
|
213
|
+
| `POST /pairings/exchange` | Exchange a one-time code for a device token |
|
|
214
|
+
| `GET /devices/self` | Current device, scopes, and root grants |
|
|
215
|
+
| `GET /roots` | Granted file roots |
|
|
216
|
+
| `GET/POST/PATCH/DELETE /roots/{rootId}/entries` | List, create, move, rename, and trash entries |
|
|
217
|
+
| `GET/PUT /roots/{rootId}/content` | Read, Range download, upload, and ETag-safe save |
|
|
218
|
+
| `GET /trash`, `POST /trash/{id}/restore` | List and restore trash items |
|
|
219
|
+
| `GET/POST /chat/workspaces` | List or register DSH workspaces |
|
|
220
|
+
| `PATCH/DELETE /chat/workspaces/{id}` | Rename or remove workspace registrations |
|
|
221
|
+
| `GET/POST /chat/sessions` | List or create sessions |
|
|
222
|
+
| `PATCH /chat/sessions/{id}` | Rename a session |
|
|
223
|
+
| `POST /chat/sessions/{id}/fork` | Fork a session |
|
|
224
|
+
| `POST /chat/sessions/{id}/archive` | Archive a session |
|
|
225
|
+
| `GET/POST /chat/sessions/{id}/messages` | Read history, send, or steer messages |
|
|
226
|
+
| `GET/POST /chat/sessions/{id}/commands` | List or run host slash commands |
|
|
227
|
+
| `GET/POST /chat/sessions/{id}/approvals...` | View and decide approval requests |
|
|
228
|
+
| `GET /chat/sessions/{id}/models`, `PUT .../model` | Model catalog, selection, and reasoning effort |
|
|
229
|
+
| `PUT /chat/sessions/{id}/agent-preset` | Select an Agent before the first message |
|
|
230
|
+
| `POST /chat/runs/{id}/cancel` | Cancel a running session |
|
|
231
|
+
| `GET/POST/PATCH/DELETE /settings/...` | Providers, credential status, model discovery, and custom providers |
|
|
232
|
+
| `WS /events` | Chat deltas, runs, approvals, and file events |
|
|
233
|
+
|
|
234
|
+
See the [OpenAPI 3.1 contract](./docs/api/openapi.yaml), [AsyncAPI contract](./docs/api/asyncapi.yaml), and included [Kotlin SDK](./kotlin-sdk/README.md) for exact schemas.
|
|
235
|
+
|
|
236
|
+
Errors use one envelope:
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{"error":{"code":"ERROR_CODE","message":"Readable message","requestId":"..."}}
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
## Device scopes
|
|
243
|
+
|
|
244
|
+
| Scope | Access |
|
|
245
|
+
| --- | --- |
|
|
246
|
+
| `chat.read` | Workspaces, sessions, messages, TODOs, commands, and approvals |
|
|
247
|
+
| `chat.write` | Manage workspaces/sessions, send, configure, run commands, and decide approvals |
|
|
248
|
+
| `files.read` | Browse, read, download, and view trash |
|
|
249
|
+
| `files.write` | Create, edit, upload, move, and rename |
|
|
250
|
+
| `files.delete` | Move files or directories to plugin trash |
|
|
251
|
+
| `settings.read` | Effective provider configuration and credential presence |
|
|
252
|
+
| `settings.write` | Provider changes, credential writes, and custom providers |
|
|
253
|
+
|
|
254
|
+
A device also needs an explicit grant for every `rootId`. Local administrators may change or revoke both scopes and root grants at any time.
|
|
255
|
+
|
|
256
|
+
## Upgrade and uninstall
|
|
257
|
+
|
|
258
|
+
Stop DSH WebUI before upgrading, install the new package, then restart it. To uninstall:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
dsh plugin --profile web remove dsh-remote-bridge
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
State is stored under `dsh-workspace` in the active `DSH_HOME`. Uninstalling does not erase state or trash, preventing accidental loss of recoverable files.
|
|
265
|
+
|
|
266
|
+
The 2.0.4 rename does not change that directory name: after upgrading, existing root grants and trash stay where they are. No migration is needed.
|
|
267
|
+
|
|
268
|
+
## Compatibility and known limits
|
|
269
|
+
|
|
270
|
+
### Some DSH builds have no attachment store
|
|
271
|
+
|
|
272
|
+
DSH's cordis injection properties (`ctx.attachments` / `ctx.fileUploads`) resolve lazily, and reading a service that nothing provides throws. Since 2.0.3 the plugin reads them tolerantly: when a service is absent the plugin still activates, and only the endpoint that actually needs it returns a readable error:
|
|
273
|
+
|
|
274
|
+
- `ATTACHMENT_STORE_UNAVAILABLE`: no `ctx.attachments`, so stored image bytes cannot be read.
|
|
275
|
+
- `FILE_UPLOADS_UNAVAILABLE`: no `ctx.fileUploads`, so attachments cannot be sent.
|
|
276
|
+
|
|
277
|
+
The user-visible consequence: **if this DSH build provides no attachment store, historical images in conversations cannot be displayed, but everything else in the plugin works normally** — and clients show the specific reason instead of a vague "image unavailable".
|
|
278
|
+
|
|
279
|
+
## Troubleshooting
|
|
280
|
+
|
|
281
|
+
**Phone settings is missing**
|
|
282
|
+
|
|
283
|
+
The entry is inside DSH settings, right below **Phone access**. If you cannot see it, make sure the plugin was installed into the `web` profile and **restart DSH** — plugins load in-process and a restart is required.
|
|
284
|
+
|
|
285
|
+
**There is no UI for browsing or editing files on the desktop**
|
|
286
|
+
|
|
287
|
+
That is intentional in 2.2.0: the standalone page `/dsh-workspace` was deleted and the desktop no longer offers a file-management UI. Use the phone app's file page, or ask the agent to read and write files with its tools in a conversation.
|
|
288
|
+
|
|
289
|
+
**Enable and create pairing is disabled**
|
|
290
|
+
|
|
291
|
+
Add at least one root. If the bind IP or port changed, save the listener settings first.
|
|
292
|
+
|
|
293
|
+
**The phone cannot connect**
|
|
294
|
+
|
|
295
|
+
Confirm remote access is enabled, the firewall/security group allows the port, and the address is reachable from the phone. Do not use the server's own `127.0.0.1` address.
|
|
296
|
+
|
|
297
|
+
**A save reports a conflict**
|
|
298
|
+
|
|
299
|
+
Another window or process changed the file. Reload it, merge the desired changes, and save again.
|
|
300
|
+
|
|
301
|
+
## Build from source
|
|
302
|
+
|
|
303
|
+
```sh
|
|
304
|
+
pnpm install --frozen-lockfile
|
|
305
|
+
pnpm check
|
|
306
|
+
pnpm pack
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
`pnpm check` covers type-checking, documentation consistency, and tests. It currently passes **19 test files / 113 cases**, plus **3 browser-layer cases** (Playwright measuring real computed styles).
|
|
310
|
+
|
|
311
|
+
`npm pack` produces roughly a **0.25 MB** archive: 2.2.0 dropped the standalone page and its editor dependencies and turned source maps off, down from 1.72 MB.
|
|
312
|
+
|
|
313
|
+
v2.2.1 was developed against DSH `master@47f943859bef60e4160492346772ded9b24f765a`. CI covers Windows, Ubuntu, and macOS.
|
|
314
|
+
|
|
315
|
+
## Project
|
|
316
|
+
|
|
317
|
+
- Version: `v2.2.1`
|
|
318
|
+
- Author: upstream [Hakunm](https://github.com/Hakunm); this fork maintained by [westanke](https://github.com/westanke)
|
|
319
|
+
- Repository: [GitHub](https://github.com/westanke/dsh-remote-bridge) · [Gitee](https://gitee.com/westanke/dsh-remote-bridge)
|
|
320
|
+
- npm: [`dsh-remote-bridge`](https://www.npmjs.com/package/dsh-remote-bridge) ([mainland-China mirror](https://registry.npmmirror.com/dsh-remote-bridge))
|
|
321
|
+
- License: [GNU Affero General Public License v3.0](./LICENSE)
|
|
322
|
+
- Android client: dsh-companion ([GitHub](https://github.com/westanke/dsh-companion) · [Gitee](https://gitee.com/westanke/dsh-companion)), a fork of the upstream [dsh-android-app](https://github.com/Hakunm/dsh-android-app), kept in step with this plugin
|
package/README.md
CHANGED
|
@@ -1,3 +1,319 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-remote-bridge
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>把 DSH 内核的私有 remote 协议翻译成版本化 REST,供手机与第三方客户端远程访问这台机器;桌面端则提供一个集中设置中心。</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
中文 · <a href="./README.en.md">English</a>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<img alt="Version" src="https://img.shields.io/badge/version-v2.2.1-087f8c">
|
|
13
|
+
<img alt="DSH plugin" src="https://img.shields.io/badge/DeepSeek_Harness-plugin-1f2328">
|
|
14
|
+
<img alt="Platforms" src="https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-586069">
|
|
15
|
+
<img alt="License" src="https://img.shields.io/badge/license-AGPL--3.0-2da44e">
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
`dsh-remote-bridge` 是 DeepSeek Harness(DSH)的远程访问桥接插件:它把 DSH 内核的私有 remote 协议翻译成版本化的 REST 接口,让 dsh-companion([GitHub](https://github.com/westanke/dsh-companion) · [Gitee](https://gitee.com/westanke/dsh-companion))等受信任客户端在离开电脑后仍能使用同一套聊天、工作区与文件能力;桌面端在你的 DSH 设置里提供一个「手机设置」,内联六个分区(根目录 / 远程访问 / 设备 / 回收站 / 审计 / App 下载)。**桌面端不再提供文件管理界面**:文件树与编辑器已于 2.2.0 删除,电脑上管理文件请走手机 App,或在会话里让 agent 用工具完成(见「桌面端不再有文件管理界面」)。
|
|
19
|
+
|
|
20
|
+
界面默认中文,可随时切换 English。插件支持 Windows、macOS 和 Linux,安装包已经包含编译产物,不要求用户在服务器上重新构建。
|
|
21
|
+
|
|
22
|
+
> **版本警告**:已发布的 `v2.0.0` 与 `v2.0.1` 存在严重缺陷(`v2.0.0` 历史图片读取全部失败,`v2.0.1` 插件无法激活)。请务必使用 **`v2.2.0`**(或 ≥ `v2.0.4`)。
|
|
23
|
+
> `v2.0.2` 与 `v2.0.3` **从未发布**,请不要按这两个版本号寻找安装包。
|
|
24
|
+
|
|
25
|
+
> **DSH 0.2.x 兼容性**:本分支在上游 `v1.0.0` 的基础上增加了对 DSH `0.2.0-rc.2` 的兼容层。
|
|
26
|
+
> 0.2.x 用 `dsh-api-gateway` 替换了提供 `apiProxy` 服务的 `dsh-host-apiproxy`,导致上游版本在
|
|
27
|
+
> 0.2.x 上无法启动(表现为「添加根目录返回 405」)。兼容层的完整说明——基于什么、为什么、改了什么、
|
|
28
|
+
> 测了什么——见 [DSH 0.2.x 兼容性适配说明](./docs/project/DSH-0.2-COMPAT.md)。
|
|
29
|
+
|
|
30
|
+
## 实际效果
|
|
31
|
+
|
|
32
|
+
桌面端的入口**就在你的 DSH 设置里**:打开设置,在「📱 手机访问」下面就是「📱 手机设置」,点进去直接内联渲染六个分区,不再另开弹窗。它只做设置,**不含文件树**——独立页 `/dsh-workspace` 以及其中的文件树、CodeMirror 编辑器已于 2.2.0 一并删除,理由与代价见下文「桌面端不再有文件管理界面」。
|
|
33
|
+
|
|
34
|
+
远程访问默认关闭。管理员可在本机 WebUI 中设置绑定 IP、端口和新设备的初始权限。
|
|
35
|
+
|
|
36
|
+
> 本节原先配有两张界面截图,但那是改名前的旧界面(标题仍是「DSH 文件工作区」;远程访问那张还标着 v1.0.0,且是文件树与设置两个弹窗叠加的形态),与上面描述的当前形态完全不符,已删除以免误导。缓存的旧截图不会自动更新,请以本节文字与 `docs/project/ARCHITECTURE.md` 为准。
|
|
37
|
+
|
|
38
|
+
## 关于改名(2.0.4)
|
|
39
|
+
|
|
40
|
+
插件由 `dsh-workspace` 改名为 `dsh-remote-bridge`。改名理由是:旧名字比内容窄——插件实际承担的是「把 DSH 内核的私有 remote 协议翻译成版本化 REST,供手机端远程访问这台机器」再加一个设置中心,而「workspace」只是其中一页。
|
|
41
|
+
|
|
42
|
+
**改名只动「安装时叫什么、bundle 叫什么」,以下几处对外契约刻意保持不变:**
|
|
43
|
+
|
|
44
|
+
| 保持不变 | 位置 | 为什么不能改 |
|
|
45
|
+
| --- | --- | --- |
|
|
46
|
+
| REST 前缀 `/dsh-workspace-api` | `src/host/server.ts` | 已发布的 App 把它写死了 |
|
|
47
|
+
| 状态目录(`dataDir`,默认 `dsh-workspace`) | DSH profile 配置 | 换目录等于让用户的授权根配置与回收站全部消失 |
|
|
48
|
+
|
|
49
|
+
**已不再列入契约的两项**(2.2.0 随独立页一并退役):
|
|
50
|
+
|
|
51
|
+
- **独立页路径 `/dsh-workspace`**:该页面(文件树 + CodeMirror 编辑器)已删除,路径随之下线。注意它与 REST 前缀 `/dsh-workspace-api` 是两回事 —— **前缀还在,是 App 的对外契约;页面没了,不再承诺任何东西**。
|
|
52
|
+
- **浏览器存储键 `dsh-workspace-device-token`**:它只被那个已删的页面读写过,现在全仓库(含 App)已无任何读写方。一个没人读的键不构成契约,所以不列入上表;键名本身也不回收,以免日后排查时多一个迷惑项。
|
|
53
|
+
|
|
54
|
+
所以安装后看到 REST 地址或状态目录里仍然是 `dsh-workspace`,是**预期行为**,不是改名没改干净。
|
|
55
|
+
|
|
56
|
+
## 快速安装
|
|
57
|
+
|
|
58
|
+
### 环境要求
|
|
59
|
+
|
|
60
|
+
- 已安装并能正常启动的 DeepSeek Harness WebUI
|
|
61
|
+
- DSH 内核 `0.1.x` 或 `0.2.x`(0.2.x 由本分支的兼容层支持,见 [DSH 0.2.x 兼容性适配说明](./docs/project/DSH-0.2-COMPAT.md))
|
|
62
|
+
- Node.js `^22.19.0` 或 `>=24.0.0`
|
|
63
|
+
- 默认端口 `3090` 可用,或准备一个其他端口
|
|
64
|
+
|
|
65
|
+
使用运行 DSH WebUI 的同一系统用户执行。**推荐用 npm 包名**(三种方式装的是同一份产物):
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
# ① npm 包名(推荐:装的是预构建产物,不需要 pnpm 的构建授权)
|
|
69
|
+
dsh plugin --profile web add dsh-remote-bridge
|
|
70
|
+
|
|
71
|
+
# 国内镜像更快时,指定 registry
|
|
72
|
+
dsh plugin --profile web add dsh-remote-bridge --registry https://registry.npmmirror.com
|
|
73
|
+
|
|
74
|
+
# ② GitHub Release 的 tarball
|
|
75
|
+
dsh plugin --profile web add https://github.com/westanke/dsh-remote-bridge/releases/download/v2.2.1/dsh-remote-bridge-2.2.1.tgz
|
|
76
|
+
|
|
77
|
+
# ③ Gitee Release 的 tarball(国内访问更快)
|
|
78
|
+
dsh plugin --profile web add https://gitee.com/westanke/dsh-remote-bridge/releases/download/v2.2.0/dsh-remote-bridge-2.2.0.tgz
|
|
79
|
+
|
|
80
|
+
npx @deepseek-ai/dsh web
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
> `dsh plugin add` 底层就是 `pnpm add`,因此 `--registry` 等 pnpm 选项可直接使用。
|
|
84
|
+
>
|
|
85
|
+
> 本 README 由 GitHub 与 Gitee 共用同一份文件,因此凡是必须带主机名的地址(安装命令、Release 下载)
|
|
86
|
+
> 都会把两站都列出来 —— 相对链接可以跟着站点走,但 `/releases/download/...` 没有相对形式。
|
|
87
|
+
> npm 包名与 GitHub 上的仓库同名,两站看到的都一样。
|
|
88
|
+
|
|
89
|
+
重启 DSH 后,打开设置就能看到「手机设置」(在「手机访问」下面)。它是**纯设置**,不含文件树;会话视图中工具轨迹旁的「文件」标签页已在 2.0.4 移除。**桌面端不再有浏览或编辑文件的界面**:独立页 `/dsh-workspace` 已在 2.2.0 删除,文件操作请走手机 App,或在会话里让 agent 用工具完成。
|
|
90
|
+
|
|
91
|
+
从 GitHub Release 下载离线安装包时,可直接安装 tarball:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
dsh plugin --profile web add ./dsh-remote-bridge-2.2.1.tgz
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## 第一次使用
|
|
98
|
+
|
|
99
|
+
1. 打开 DSH 设置,进入「手机设置」(在「手机访问」下面;默认落在「根目录」页)。
|
|
100
|
+
2. 在「根目录」页添加允许管理的本机目录,并为它起一个容易识别的名字。
|
|
101
|
+
3. 需要连接手机时,进入「远程访问」,填写绑定 IP 和端口并保存。
|
|
102
|
+
4. 点击“启用并创建配对”,再将十分钟内有效的一次性配对码填入 App。
|
|
103
|
+
5. 在手机 App 的文件页里选择授权根,即可浏览和编辑文件。
|
|
104
|
+
|
|
105
|
+
远程访问只有在至少存在一个授权根时才能开启。安装插件本身不会把服务暴露到局域网,未启用时只监听回环地址。
|
|
106
|
+
|
|
107
|
+
## 你可以做什么
|
|
108
|
+
|
|
109
|
+
### 桌面端不再有文件管理界面
|
|
110
|
+
|
|
111
|
+
2.2.0 删除了独立页 `/dsh-workspace`,包括整个文件树、上传下载入口和 CodeMirror 6 编辑器。原因是手机 App 的文件页已经原生覆盖同一套能力,桌面端这个页面没人用,却让发布包从 **0.25 MB 撑到 1.72 MB**。
|
|
112
|
+
|
|
113
|
+
代价要说清楚:**现在在电脑上动文件只剩两条路** ——
|
|
114
|
+
|
|
115
|
+
1. 在会话里对 agent 说话,让它用工具读写文件;
|
|
116
|
+
2. 打开终端自己操作。
|
|
117
|
+
|
|
118
|
+
手机端不受影响:App 的文件页照旧可用,走的是插件保留的同一套 REST 文件接口(`/dsh-workspace-api` 前缀与 `/roots`、`/roots/{rootId}/content` 等端点一个都没删)。回收站里的删除记录现在只来自手机 App。
|
|
119
|
+
|
|
120
|
+
### 桌面端设置面板
|
|
121
|
+
|
|
122
|
+
入口在 DSH 设置里,标题为「手机设置」。设置区**内联渲染**导航与内容,不另开弹窗;导航横排,默认落在「根目录」:
|
|
123
|
+
|
|
124
|
+
| 分区 | 用途 |
|
|
125
|
+
| --- | --- |
|
|
126
|
+
| 根目录 | 添加、移除授权目录并设置显示名称 |
|
|
127
|
+
| 远程访问 | 设置绑定 IP / 端口,启用远程访问并创建配对码 |
|
|
128
|
+
| 设备 | 查看设备权限与根目录授权,随时撤销 |
|
|
129
|
+
| 回收站 | 查看与恢复被删除的条目(只列出来自手机 App 的删除记录) |
|
|
130
|
+
| 审计 | 查看操作类型与对象的审计记录 |
|
|
131
|
+
| App 下载 | 扫码下载 Android 客户端,二维码指向两个站点的 Releases 列表页 |
|
|
132
|
+
|
|
133
|
+
侧栏那个齿轮按钮**已移除**:入口分散在侧栏图标和设置页两处,会让同一件事有两个起点。会话视图中工具轨迹旁的「文件」标签页也早已移除,桌面端现在只有这一个入口。
|
|
134
|
+
|
|
135
|
+
### 连接 Android App 或其他客户端
|
|
136
|
+
|
|
137
|
+
配套的 Android 客户端是 [dsh-companion](https://github.com/westanke/dsh-companion)([Gitee](https://gitee.com/westanke/dsh-companion))。
|
|
138
|
+
用手机扫描下面任意一个码即可下载 —— 两个码都指向**对应站点的 Releases 列表页**,
|
|
139
|
+
所以发新版不需要更换二维码:
|
|
140
|
+
|
|
141
|
+
| GitHub | Gitee(国内访问更快) |
|
|
142
|
+
| --- | --- |
|
|
143
|
+
|  |  |
|
|
144
|
+
| <https://github.com/westanke/dsh-companion/releases> | <https://gitee.com/westanke/dsh-companion/releases> |
|
|
145
|
+
|
|
146
|
+
> 二维码里写的是 Releases **列表页**,不是某个具体的 APK 文件名 ——
|
|
147
|
+
> 这样每次发新版都不必重新出图,扫码的人总能拿到最新版。
|
|
148
|
+
> 两张图由 `pnpm qr:app` 生成(`scripts/generate-app-qr.mjs`),
|
|
149
|
+
> 生成时用独立的解码器回读校验,测试也会把提交进仓库的图解回来核对。
|
|
150
|
+
|
|
151
|
+
装好 App 后,在「手机设置 → 远程访问」里生成配置文本或配对码即可连上本机。
|
|
152
|
+
公开 API 不依赖 DSH 私有协议,也可用于其他客户端:
|
|
153
|
+
|
|
154
|
+
- 查看、新建、重命名和移除 DSH 工作区登记。
|
|
155
|
+
- 创建、重命名、分叉和归档会话。
|
|
156
|
+
- 读取消息、流式接收正文和思考、追加引导或取消运行。
|
|
157
|
+
- 查看 TODO、斜杠命令、权限模式和待审批操作。
|
|
158
|
+
- 选择 Agent、模型和思考强度。
|
|
159
|
+
- 查看或修改模型供应商,支持完全自定义供应商。
|
|
160
|
+
- 管理设备获准访问的文件和回收站项目。
|
|
161
|
+
|
|
162
|
+
## 远程访问与安全
|
|
163
|
+
|
|
164
|
+
默认远程地址为 `0.0.0.0:3090`,IP 和端口都可修改。客户端可以使用能到达服务器的 IP 或域名连接。
|
|
165
|
+
|
|
166
|
+
插件允许直接使用 HTTP,不强制配置证书。这对可信局域网和临时部署比较方便,但要清楚它的代价:
|
|
167
|
+
|
|
168
|
+
> HTTP 会明文传输设备令牌、聊天内容和文件内容。在公网或不可信网络中,请使用 Caddy/Nginx 配置 HTTPS,或通过 VPN、Tailscale/WireGuard、SSH 隧道等可信通道连接。
|
|
169
|
+
|
|
170
|
+
无论是否使用 HTTPS,以下保护都会生效:
|
|
171
|
+
|
|
172
|
+
- 十分钟有效且只能使用一次的配对码。
|
|
173
|
+
- 256 位设备令牌,服务器只保存摘要。
|
|
174
|
+
- 可撤销的设备权限与独立根目录授权。
|
|
175
|
+
- 配对、认证和普通请求分别限流。
|
|
176
|
+
- 审计记录操作类型和对象,但不记录令牌、文件正文或聊天正文。
|
|
177
|
+
- 新增根目录不会自动授权给已经配对的设备。
|
|
178
|
+
|
|
179
|
+
只有来自回环地址的管理界面可以添加根目录、调整设备权限、生成配对码、修改监听设置和永久清理回收站。
|
|
180
|
+
|
|
181
|
+
## 文件边界
|
|
182
|
+
|
|
183
|
+
外部接口只接受 `rootId + relativePath`,不会接收服务器绝对路径。路径还会经过以下检查:
|
|
184
|
+
|
|
185
|
+
- wire path 统一使用 `/`。
|
|
186
|
+
- 拒绝绝对路径、盘符、UNC、反斜杠、空字节以及 `.`、`..` 路径段。
|
|
187
|
+
- 每次操作逐段检查 symlink、junction 和 reparse point,禁止借助链接逃出授权根。
|
|
188
|
+
- 删除末端链接时只删除链接本身,不递归进入链接目标。
|
|
189
|
+
- 临时保存文件放在目标目录中,避免跨挂载点替换失败。
|
|
190
|
+
|
|
191
|
+
“移除 DSH 工作区”只删除 WebUI 中的登记,服务器目录、文件和会话日志不会被删除。“归档会话”只将会话从默认列表隐藏,日志仍会保留。
|
|
192
|
+
|
|
193
|
+
## 对外接口
|
|
194
|
+
|
|
195
|
+
REST 基址:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
http://HOST:PORT/api/v1
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
除健康检查和配对交换外,请求需要设备令牌:
|
|
202
|
+
|
|
203
|
+
```http
|
|
204
|
+
Authorization: Bearer DEVICE_TOKEN
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
| 接口 | 用途 |
|
|
208
|
+
| --- | --- |
|
|
209
|
+
| `GET /healthz` | 查看服务状态、API 版本和插件版本 |
|
|
210
|
+
| `POST /pairings/exchange` | 使用一次性配对码换取设备令牌 |
|
|
211
|
+
| `GET /devices/self` | 查看当前设备、权限和根目录授权 |
|
|
212
|
+
| `GET /roots` | 列出设备可访问的文件根 |
|
|
213
|
+
| `GET/POST/PATCH/DELETE /roots/{rootId}/entries` | 列目录、新建、移动、重命名和移入回收站 |
|
|
214
|
+
| `GET/PUT /roots/{rootId}/content` | 读取、Range 下载、上传和带 ETag 保存 |
|
|
215
|
+
| `GET /trash`、`POST /trash/{id}/restore` | 查看与恢复回收项 |
|
|
216
|
+
| `GET/POST /chat/workspaces` | 列出或登记 DSH 工作区 |
|
|
217
|
+
| `PATCH/DELETE /chat/workspaces/{id}` | 重命名或移除工作区登记 |
|
|
218
|
+
| `GET/POST /chat/sessions` | 列出或创建会话 |
|
|
219
|
+
| `PATCH /chat/sessions/{id}` | 重命名会话 |
|
|
220
|
+
| `POST /chat/sessions/{id}/fork` | 分叉会话 |
|
|
221
|
+
| `POST /chat/sessions/{id}/archive` | 归档会话 |
|
|
222
|
+
| `GET/POST /chat/sessions/{id}/messages` | 读取历史、发送消息或追加引导 |
|
|
223
|
+
| `GET/POST /chat/sessions/{id}/commands` | 列出或执行 host 斜杠命令 |
|
|
224
|
+
| `GET/POST /chat/sessions/{id}/approvals...` | 查看和处理待审批操作 |
|
|
225
|
+
| `GET /chat/sessions/{id}/models`、`PUT .../model` | 读取模型目录并切换模型或思考强度 |
|
|
226
|
+
| `PUT /chat/sessions/{id}/agent-preset` | 在首条消息前切换 Agent |
|
|
227
|
+
| `POST /chat/runs/{id}/cancel` | 取消正在运行的会话 |
|
|
228
|
+
| `GET/POST/PATCH/DELETE /settings/...` | 管理供应商、凭据状态、模型发现和自定义供应商 |
|
|
229
|
+
| `WS /events` | 接收聊天增量、运行、审批和文件变更事件 |
|
|
230
|
+
|
|
231
|
+
完整字段、响应和错误模型见 [OpenAPI 3.1](./docs/api/openapi.yaml),实时事件格式见 [AsyncAPI](./docs/api/asyncapi.yaml)。仓库同时提供 [Kotlin SDK](./kotlin-sdk/README.md)。
|
|
232
|
+
|
|
233
|
+
错误响应保持统一:
|
|
234
|
+
|
|
235
|
+
```json
|
|
236
|
+
{"error":{"code":"ERROR_CODE","message":"Readable message","requestId":"..."}}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## 设备权限
|
|
240
|
+
|
|
241
|
+
| Scope | 允许的操作 |
|
|
242
|
+
| --- | --- |
|
|
243
|
+
| `chat.read` | 查看工作区、会话、消息、TODO、命令和审批 |
|
|
244
|
+
| `chat.write` | 管理工作区与会话、发消息、切换配置、执行命令和处理审批 |
|
|
245
|
+
| `files.read` | 浏览、读取和下载文件,查看回收站 |
|
|
246
|
+
| `files.write` | 新建、编辑、上传、移动和重命名 |
|
|
247
|
+
| `files.delete` | 将文件或目录移入插件回收站 |
|
|
248
|
+
| `settings.read` | 查看供应商有效配置和凭据是否已配置 |
|
|
249
|
+
| `settings.write` | 修改供应商、写入凭据和创建自定义供应商 |
|
|
250
|
+
|
|
251
|
+
设备还必须获得相应 `rootId` 的授权。权限和根目录授权都可以在本机 WebUI 的“设备”页随时修改或撤销。
|
|
252
|
+
|
|
253
|
+
## 升级与卸载
|
|
254
|
+
|
|
255
|
+
升级前建议先停止 DSH WebUI,再安装新版本并重新启动。卸载命令:
|
|
256
|
+
|
|
257
|
+
```sh
|
|
258
|
+
dsh plugin --profile web remove dsh-remote-bridge
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
默认状态保存在当前 `DSH_HOME` 下的 `dsh-workspace` 目录。卸载插件不会自动删除状态目录或回收站,以免误删尚未恢复的数据。
|
|
262
|
+
|
|
263
|
+
插件改名(2.0.4)不会改变这个目录名:升级后原有的授权根配置与回收站仍在原处,无需迁移。
|
|
264
|
+
|
|
265
|
+
## 兼容性与已知限制
|
|
266
|
+
|
|
267
|
+
### 某些 DSH 构建缺少附件存储服务
|
|
268
|
+
|
|
269
|
+
DSH 的 cordis 注入属性(`ctx.attachments` / `ctx.fileUploads`)是惰性解析的:读取一个没有任何组件提供的服务会抛错。2.0.3 起改为**容错读取**——服务缺席时插件照常激活,只有真正用到该能力的接口返回可读错误:
|
|
270
|
+
|
|
271
|
+
- `ATTACHMENT_STORE_UNAVAILABLE`:拿不到 `ctx.attachments`,历史图片的字节无法读取。
|
|
272
|
+
- `FILE_UPLOADS_UNAVAILABLE`:拿不到 `ctx.fileUploads`,无法发送附件。
|
|
273
|
+
|
|
274
|
+
用户可见的后果:**如果这台机器的 DSH 不提供附件存储服务,会话历史里的图片会读不出来,但插件其余功能全部正常**;客户端会显示具体原因,而不是含糊的「图片不可用」。
|
|
275
|
+
|
|
276
|
+
## 常见问题
|
|
277
|
+
|
|
278
|
+
**安装后看不到「手机设置」**
|
|
279
|
+
|
|
280
|
+
入口在 DSH 设置里,位于「手机访问」下面。如果看不到,确认插件安装在 `web` profile,并在安装后**重启 DSH**(插件为进程内加载,不重启不生效)。
|
|
281
|
+
|
|
282
|
+
**桌面上找不到浏览或编辑文件的界面**
|
|
283
|
+
|
|
284
|
+
这是 2.2.0 的有意改动:独立页 `/dsh-workspace` 已删除,桌面端不再提供文件管理界面。请在手机 App 的文件页操作,或在会话里让 agent 用工具读写文件。
|
|
285
|
+
|
|
286
|
+
**“启用并创建配对”按钮不可用**
|
|
287
|
+
|
|
288
|
+
先添加至少一个授权根。如果刚修改过绑定 IP 或端口,还需要先保存监听设置。
|
|
289
|
+
|
|
290
|
+
**手机无法连接**
|
|
291
|
+
|
|
292
|
+
检查远程访问是否已启用,服务器防火墙和云安全组是否放行端口,以及 App 中填写的地址是否能从手机到达。不要填写服务器自己的 `127.0.0.1`。
|
|
293
|
+
|
|
294
|
+
**保存文件时提示冲突**
|
|
295
|
+
|
|
296
|
+
文件已经被其他窗口或程序修改。重新加载,合并需要保留的内容后再保存。
|
|
297
|
+
|
|
298
|
+
## 从源码构建
|
|
299
|
+
|
|
300
|
+
```sh
|
|
301
|
+
pnpm install --frozen-lockfile
|
|
302
|
+
pnpm check
|
|
303
|
+
pnpm pack
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
`pnpm check` 覆盖类型检查、文档一致性与测试;当前 **19 个测试文件 / 113 个用例**,外加 **3 个浏览器层用例**(Playwright 实测量出的计算样式),全部通过。
|
|
307
|
+
|
|
308
|
+
`npm pack` 的产物约 **0.25 MB**:2.2.0 删除独立页及其编辑器依赖、并关闭 source map 之后,从 1.72 MB 降下来。
|
|
309
|
+
|
|
310
|
+
v2.2.1 基于 DSH `master@47f943859bef60e4160492346772ded9b24f765a` 开发,CI 覆盖 Windows、Ubuntu 和 macOS。
|
|
311
|
+
|
|
312
|
+
## 项目信息
|
|
313
|
+
|
|
314
|
+
- 当前版本:`v2.2.1`
|
|
315
|
+
- 作者:上游 [Hakunm](https://github.com/Hakunm),本 fork 维护 [westanke](https://github.com/westanke)
|
|
316
|
+
- 仓库:[GitHub](https://github.com/westanke/dsh-remote-bridge) · [Gitee](https://gitee.com/westanke/dsh-remote-bridge)
|
|
317
|
+
- npm:[`dsh-remote-bridge`](https://www.npmjs.com/package/dsh-remote-bridge)([国内镜像](https://registry.npmmirror.com/dsh-remote-bridge))
|
|
318
|
+
- 许可证:[GNU Affero General Public License v3.0](./LICENSE)
|
|
319
|
+
- Android 客户端:dsh-companion([GitHub](https://github.com/westanke/dsh-companion) · [Gitee](https://gitee.com/westanke/dsh-companion)),上游 [dsh-android-app](https://github.com/Hakunm/dsh-android-app) 的 fork,与本插件配套
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="264" height="264" viewBox="0 0 41 41" shape-rendering="crispEdges"><path fill="#ffffff" d="M0 0h41v41H0z"/><path stroke="#000000" d="M4 4.5h7m1 0h1m1 0h2m1 0h4m6 0h2m1 0h7M4 5.5h1m5 0h1m3 0h2m1 0h2m1 0h1m1 0h2m2 0h1m3 0h1m5 0h1M4 6.5h1m1 0h3m1 0h1m2 0h2m1 0h1m1 0h1m1 0h4m1 0h1m1 0h2m1 0h1m1 0h3m1 0h1M4 7.5h1m1 0h3m1 0h1m1 0h5m2 0h3m5 0h1m2 0h1m1 0h3m1 0h1M4 8.5h1m1 0h3m1 0h1m1 0h1m1 0h3m3 0h1m2 0h1m1 0h1m1 0h1m2 0h1m1 0h3m1 0h1M4 9.5h1m5 0h1m1 0h2m3 0h3m4 0h3m1 0h1m1 0h1m5 0h1M4 10.5h7m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m1 0h7M12 11.5h5m4 0h1m1 0h6M4 12.5h1m3 0h1m1 0h4m1 0h2m1 0h4m3 0h9m2 0h1M4 13.5h1m1 0h3m5 0h1m1 0h1m1 0h5m4 0h1m1 0h1m3 0h3M4 14.5h1m1 0h1m1 0h1m1 0h4m3 0h4m1 0h1m1 0h7m2 0h1m1 0h1M5 15.5h1m3 0h1m1 0h2m2 0h1m1 0h1m1 0h1m4 0h2m1 0h4m4 0h2M4 16.5h2m2 0h1m1 0h1m2 0h2m2 0h1m2 0h1m2 0h1m1 0h2m1 0h1m1 0h1m1 0h2M8 17.5h2m1 0h1m2 0h3m1 0h1m3 0h3m1 0h2m1 0h1m1 0h1m1 0h1M4 18.5h1m1 0h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h2m1 0h1m2 0h1m1 0h5m1 0h1m2 0h1M4 19.5h1m4 0h1m2 0h1m2 0h3m1 0h4m2 0h1m1 0h5M4 20.5h5m1 0h5m2 0h1m3 0h1m1 0h4m1 0h1m1 0h1m1 0h2m1 0h1M5 21.5h1m5 0h2m5 0h3m1 0h1m4 0h1m1 0h1m3 0h3M5 22.5h2m2 0h3m2 0h1m1 0h1m1 0h2m1 0h1m2 0h1m1 0h2m1 0h3m1 0h1m1 0h1M4 23.5h1m2 0h1m3 0h5m5 0h5m1 0h2m1 0h2m3 0h2M4 24.5h4m1 0h2m1 0h2m1 0h1m2 0h2m2 0h5m1 0h3m1 0h2m1 0h2M4 25.5h4m4 0h3m1 0h1m3 0h2m1 0h1m1 0h1m1 0h1m1 0h1m1 0h1m2 0h2M8 26.5h5m2 0h4m1 0h1m1 0h2m3 0h1m1 0h1m1 0h1m1 0h1m1 0h1M6 27.5h1m2 0h1m4 0h3m4 0h1m1 0h3m3 0h2m4 0h1M4 28.5h3m3 0h3m4 0h1m1 0h1m1 0h1m3 0h2m1 0h5m2 0h2M12 29.5h1m2 0h1m3 0h1m1 0h2m4 0h2m3 0h1m1 0h2M4 30.5h7m1 0h1m3 0h4m2 0h1m1 0h2m2 0h1m1 0h1m1 0h2m1 0h1M4 31.5h1m5 0h1m2 0h1m2 0h1m2 0h1m3 0h3m2 0h1m3 0h1m2 0h1M4 32.5h1m1 0h3m1 0h1m1 0h1m1 0h1m1 0h2m2 0h1m3 0h3m1 0h6M4 33.5h1m1 0h3m1 0h1m2 0h1m2 0h1m4 0h8m1 0h3m1 0h1M4 34.5h1m1 0h3m1 0h1m2 0h1m1 0h2m1 0h2m4 0h2m1 0h2m1 0h3M4 35.5h1m5 0h1m4 0h3m1 0h5m1 0h1m2 0h3M4 36.5h7m1 0h1m2 0h2m1 0h1m2 0h1m1 0h3m1 0h2m7 0h1"/></svg>
|
|
Binary file
|