dsh-mini-remote 0.2.0 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +69 -0
- package/README.en.md +207 -141
- package/README.md +207 -148
- package/client/client.js +1984 -6
- package/lib/build.js +32 -1
- package/lib/devices.js +372 -0
- package/lib/index.js +1628 -33
- package/lib/mirror.js +373 -7
- package/lib/page.html +955 -71
- package/lib/page.js +4 -1
- package/lib/remotes.js +279 -0
- package/lib/server.js +984 -55
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -1,248 +1,314 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
1
3
|
# Minimal Remote · dsh-mini-remote
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
<img src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/promo.webp" alt="Minimal Remote: the phone keeps your instruction and its conclusion, and shows you the process only when you ask for it" width="720" />
|
|
7
|
+
</p>
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
**A lightweight mobile remote plugin crafted for DeepSeek Harness (DSH) users, resolving screen clutter and process fatigue when checking Agent status and dispatching instructions away from the desk.**
|
|
8
10
|
|
|
9
|
-
](https://www.npmjs.com/package/dsh-mini-remote)
|
|
12
|
+
[](https://nodejs.org/)
|
|
13
|
+
[](https://github.com/deepseek-ai/DeepSeek-Harness)
|
|
14
|
+
[](LICENSE)
|
|
10
15
|
|
|
11
|
-
|
|
16
|
+
[English](README.en.md) · [简体中文](README.md)
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
</div>
|
|
14
19
|
|
|
15
|
-
|
|
20
|
+
<p align="center">
|
|
21
|
+
<a href="#background--pain-points">Background & Pain Points</a> ·
|
|
22
|
+
<a href="#core-features">Core Features</a> ·
|
|
23
|
+
<a href="#ui-preview">UI Preview</a> ·
|
|
24
|
+
<a href="#mobile-interface-guide">Mobile Usage</a> ·
|
|
25
|
+
<a href="#desktop-remote-window">Remote Window</a> ·
|
|
26
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
27
|
+
<a href="#usage--configuration">Usage & Configuration</a> ·
|
|
28
|
+
<a href="#license">License</a>
|
|
29
|
+
</p>
|
|
16
30
|
|
|
17
31
|
---
|
|
18
32
|
|
|
19
|
-
##
|
|
20
|
-
|
|
21
|
-
A plugin for [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) (DSH, a plugin-extensible AI agent framework). Once installed:
|
|
22
|
-
|
|
23
|
-
- a web page opens on your phone with exactly one input box and the latest reply;
|
|
24
|
-
- instructions you send from the phone go straight to the session already running on your computer;
|
|
25
|
-
- everything in between — tool calls, files read and written, sub-agents, the reasoning trace itself — **is never pushed to the phone**;
|
|
26
|
-
- the only thing that "talks" is the whale girl: the line the model mutters between steps, spoken in her speech bubble.
|
|
33
|
+
## Background & Pain Points
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
When running complex engineering tasks with desktop or web AI agents, a single turn often involves several minutes of deep reasoning, dozens of file operations, and intensive tool executions. Existing mobile remote setups typically mirror the full desktop workspace onto the phone screen, causing practical friction:
|
|
29
36
|
|
|
30
|
-
|
|
37
|
+
- **Imbalanced Information Density**: Raw reasoning traces, verbose tool parameters, and large unified diffs overwhelm small displays, burying the primary conclusion.
|
|
38
|
+
- **Attention Overload**: During commutes, meals, or brief breaks away from the keyboard, the primary goal is simply checking whether a round finished and dispatching the next instruction, without dissecting every intermediate step.
|
|
39
|
+
- **Inflexible Connectivity**: Pure LAN routes disconnect as soon as you step outside, while centralised cloud relays introduce external credential custody risks.
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
**Minimal Remote** is built around exactly that: it fits several ways of working and hands attention control back to you. On mobile, three modes — "Single frame", "Chat" and "Full" — let you hide execution noise entirely, or expand the full trace whenever you want. On PC, the "Remote Window" feature lets you drive the DeepSeek Harness on your main machine from other devices, inside its own native desktop UI.
|
|
33
42
|
|
|
34
|
-
|
|
43
|
+
---
|
|
35
44
|
|
|
36
|
-
##
|
|
45
|
+
## Core Features
|
|
37
46
|
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
47
|
+
- 🎛️ **Three On-Demand Presentation Modes**: Switch instantly between "Single frame" (the cleanest view, keeping only the latest conclusion), "Chat" (standard conversation bubbles), and "Full" (inline tool calls and file diffs with keyword search).
|
|
48
|
+
- 📱 **Zero-Install Mobile Client**: the phone side is simply a web page — scan, open it in a browser, and that is the whole setup. No app to install, no account to create, no third-party server in between; you can add it to the home screen and it opens full-screen from there.
|
|
49
|
+
- 🌐 **Multi-Route Secure Connectivity**: Connect via LAN, Tailscale private network (supporting MagicDNS and HTTPS certificates), or Cloudflare Tunnel (for environments without public IPs). All routes coexist with dedicated QR codes and tokens.
|
|
50
|
+
- 🐬 **Lightweight Anthropomorphic Feedback**: Inter-step narrations are spoken aloud by the whale girl sprite in speech bubbles; execution progress and queued instructions are visualized on an exact scale, filtering out raw reasoning blocks.
|
|
51
|
+
- 💬 **Feishu Long-Connection Remote**: Direct bidirectional communication through the Feishu Open Platform WebSocket long connection without public ports, supporting text dialogue, multiple-choice responses, and the `/会话` switch command.
|
|
52
|
+
- 🗂️ **In-Place Mobile Session Management**: Open it as a web page in your phone's browser and rename, pin, archive, or fork sessions right there, with clear indicators for pending approvals and questions.
|
|
53
|
+
- 💻 **Desktop Embedded "Remote Window"**: A "Remote Window" shortcut in the DSH desktop left sidebar lets you operate another computer's DSH desktop remotely, with native-feeling window transitions and no page switch; see "Desktop \"Remote Window\"" below for the pairing steps.
|
|
54
|
+
- 🔒 **Rigorous Security Boundaries**: All API routes enforce constant-time token comparison to prevent timing side-channel attacks; built-in rate limiting locks out sources after 5 failed attempts in 1 minute; pairing data is accessible solely from the host loopback interface.
|
|
41
55
|
|
|
42
56
|
---
|
|
43
57
|
|
|
44
|
-
##
|
|
58
|
+
## UI Preview
|
|
45
59
|
|
|
46
|
-
|
|
47
|
-
dsh plugin --profile web add dsh-mini-remote
|
|
48
|
-
```
|
|
60
|
+
### Conversation Screen (Single Frame / Chat / Full)
|
|
49
61
|
|
|
50
|
-
|
|
62
|
+
The mobile client is built with zero-dependency vanilla JavaScript and supports both high-contrast Dark and Light themes. One conversation has three readings: **Single Frame** keeps only the latest conclusion on screen, **Chat** lays the history out as back-and-forth bubbles, and **Full** puts every turn's execution trail back where it happened:
|
|
51
63
|
|
|
52
|
-
|
|
64
|
+
<div align="center">
|
|
65
|
+
<img width="290" alt="Chat (dark): several turns of history laid out as back-and-forth bubbles" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/screen-chat-dark.png" />
|
|
66
|
+
<img width="290" alt="Chat (light): the same conversation in the light theme" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/screen-chat-light.png" />
|
|
67
|
+
</div>
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
<summary>Installing from GitHub source, from a local folder, and which DSH versions it fits</summary>
|
|
69
|
+
### Settings Panel & Appearance
|
|
56
70
|
|
|
57
|
-
|
|
71
|
+
Switch presentation modes, color themes, or trigger manual reconnects from the settings overlay:
|
|
58
72
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
73
|
+
<div align="center">
|
|
74
|
+
<img width="290" alt="Settings (dark): three display modes, appearance set to dark" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/settings-dark.png" />
|
|
75
|
+
<img width="290" alt="Settings (light): the selected states and the primary button turn royal blue too" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/settings-light.png" />
|
|
76
|
+
</div>
|
|
62
77
|
|
|
63
|
-
|
|
78
|
+
### Execution Animation
|
|
64
79
|
|
|
65
|
-
|
|
66
|
-
dsh plugin --profile web add <the folder you put the source in>
|
|
67
|
-
```
|
|
80
|
+
During task execution, the view presents an animated running state, elapsed timer, and queued task scale without unverified progress guesses:
|
|
68
81
|
|
|
69
|
-
|
|
82
|
+
<div align="center">
|
|
83
|
+
<img width="290" alt="Running (dark): the whale girl running, 14s elapsed, one instruction on the queue scale" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/running-dark-phone.jpg" />
|
|
84
|
+
<img width="290" alt="Running (light): the same run in the light theme, 14s elapsed, one instruction queued" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/running-light-phone.jpg" />
|
|
85
|
+
</div>
|
|
70
86
|
|
|
71
|
-
|
|
87
|
+
### Remote Window (Desktop)
|
|
72
88
|
|
|
73
|
-
|
|
89
|
+
No window switching and no remote desktop: click "Remote Window" in the DSH desktop left sidebar and the other computer's DSH interface is embedded right in the main panel. The bar on top holds "← Back to list / which computer this is / Try again"; while the interface displays normally it auto-hides, sliding out only when the mouse reaches the top edge.
|
|
74
90
|
|
|
75
|
-
|
|
91
|
+
<div align="center">
|
|
92
|
+
<img width="720" alt="Remote Window: another computer's DSH interface embedded in the main panel, with Remote Window selected in the left sidebar" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/remote-window.png" />
|
|
93
|
+
</div>
|
|
76
94
|
|
|
77
|
-
|
|
95
|
+
---
|
|
78
96
|
|
|
79
|
-
|
|
97
|
+
## Quick Start
|
|
80
98
|
|
|
81
|
-
|
|
82
|
-
| --- | --- | --- | --- |
|
|
83
|
-
| **LAN** | Phone and computer on the same Wi-Fi — at home only | Nothing at all | It stops the moment you leave the house |
|
|
84
|
-
| **Tailscale** | You need it outside, and you want the address to stay fixed | Tailscale on the computer and on the phone | An app on both sides |
|
|
85
|
-
| **Public tunnel** | Nothing installed, reachable on any network | Nothing at all | The address changes on every restart; the first run downloads a ~50 MB component |
|
|
99
|
+
### Prerequisites
|
|
86
100
|
|
|
87
|
-
|
|
101
|
+
Before installing, make sure this computer meets the following requirements:
|
|
88
102
|
|
|
89
|
-
|
|
103
|
+
- **Node.js**: `^22.19.0 || >=24.0.0`
|
|
104
|
+
- **DSH (DeepSeek Harness)**: `>=0.1.5-rc.2 <0.3.0`
|
|
105
|
+
- **OS**: Windows, macOS, or Linux
|
|
90
106
|
|
|
91
|
-
|
|
107
|
+
> ⚠️ **Notice**: DSH is in active development. This plugin is verified across `0.1.5-rc.2`, `0.1.7-rc.2`, `0.2.0-rc.1`, and `0.2.0-rc.2`. Versions below `0.1.5` are untested, and versions above `0.3.0` risk breaking changes in upstream host interfaces — **`0.3.0` is the upper bound this release declares**. Once DSH moves past it, wait for the plugin to catch up instead of upgrading straight away.
|
|
92
108
|
|
|
93
|
-
###
|
|
109
|
+
### Installation
|
|
94
110
|
|
|
95
|
-
|
|
111
|
+
#### Option 1: Install via DSH Desktop UI (Recommended)
|
|
96
112
|
|
|
97
|
-
|
|
113
|
+
1. Click the "Plugins" button on the top navigation bar of DSH to open the plugin manager.
|
|
114
|
+
2. Click the "Add Plugin" button in the upper-right corner to open the installation dialog.
|
|
115
|
+
3. Enter the package name `dsh-mini-remote` into the input field (GitHub repository URL `github:xingzhen199186/dsh-mini-remote` or local directory path is also supported). Keep the default registry ("npm official registry").
|
|
116
|
+
4. Click the "Install" button at the bottom of the dialog.
|
|
98
117
|
|
|
99
|
-
|
|
118
|
+
> ⚠️ **Notice**:
|
|
119
|
+
> 1. **Verify trusted source**: Plugins run on your machine with your current user privileges. Plugins from untrusted sources may damage DeepSeek Harness or read and leak sensitive data.
|
|
120
|
+
> 2. **No automatic updates yet**: Installed plugins currently do not support automatic updates. To upgrade to a newer version, uninstall the existing version before installing the new one.
|
|
100
121
|
|
|
101
|
-
|
|
122
|
+
#### Option 2: Install from npm (Command Line)
|
|
102
123
|
|
|
103
|
-
|
|
124
|
+
Execute the installation command in your terminal. Replace `web` with your custom profile name if you are not using the default profile:
|
|
104
125
|
|
|
105
|
-
|
|
126
|
+
```powershell
|
|
127
|
+
dsh plugin --profile web add dsh-mini-remote
|
|
128
|
+
```
|
|
106
129
|
|
|
107
|
-
|
|
130
|
+
#### Option 3: Install from GitHub
|
|
108
131
|
|
|
109
|
-
|
|
132
|
+
```powershell
|
|
133
|
+
dsh plugin --profile web add github:xingzhen199186/dsh-mini-remote
|
|
134
|
+
```
|
|
110
135
|
|
|
111
|
-
|
|
112
|
-
- **The first time is slow** — it's downloading a component of about 50 MB, and only that once. While it does, the status line reads "opening…", which is normal, not a hang. Registration occasionally fails; the plugin retries three times on its own.
|
|
136
|
+
#### Option 4: Install from Local Directory
|
|
113
137
|
|
|
114
|
-
|
|
138
|
+
```powershell
|
|
139
|
+
dsh plugin --profile web add C:\path\to\dsh-mini-remote
|
|
140
|
+
```
|
|
115
141
|
|
|
116
|
-
###
|
|
142
|
+
### Starting the Service
|
|
117
143
|
|
|
118
|
-
|
|
144
|
+
1. Restart the DSH service (close the active `dsh web` window and launch it again).
|
|
145
|
+
2. Check the console log for the listening port and pairing token:
|
|
146
|
+
```text
|
|
147
|
+
[dsh-mini-remote] 已启动:http://127.0.0.1:3090/mini?token=xxxxxxxxxxxx
|
|
148
|
+
```
|
|
149
|
+
3. Open the DSH desktop UI, navigate to "Settings" → "Phone Remote" in the left sidebar, and view the pairing QR codes and links.
|
|
119
150
|
|
|
120
|
-
|
|
151
|
+
> **The phone side is browser-only.** Scanning and opening it in a browser is the entire client — there is no standalone app and no mini-program. You can add the page to your home screen: the resulting icon opens full-screen and looks much like an app, but it is still the browser running the page. Switch phones or clear browser data, and you are back to scanning the code again.
|
|
152
|
+
>
|
|
153
|
+
> Conversely, this page **is not picky about the device either**: open the same address in a PC browser and it works just as well — and from there you can open the complete DSH desktop interface. See "Advanced Settings: Embedded Desktop Interface".
|
|
121
154
|
|
|
122
155
|
---
|
|
123
156
|
|
|
124
|
-
##
|
|
125
|
-
|
|
126
|
-
Open the link and that's the whole interface: one input box, and the latest reply.
|
|
127
|
-
|
|
128
|
-
**Send instructions.** Type and send; the AI starts working on the computer.
|
|
129
|
-
|
|
130
|
-
**Wait for the conclusion.** While it runs, the page shows "running…". You can keep sending during that time — instructions queue up. When the task ends, the conclusion appears on the page, and the phone chimes and buzzes.
|
|
131
|
-
|
|
132
|
-
**She speaks up while she works.** On the computer, the model often mutters a line between steps ("let me look at this file first"). That line is now spoken by the whale girl through her speech bubble — the talking pose is a newly drawn sprite, the rotation pauses for it, and afterwards picks up from where it stopped. It stays **in the bubble** and never bleeds into the answer area below. Only the line it deliberately writes *for a human reader* is spoken; its own working thoughts — often English, often a whole paragraph — never reach the phone at all. Should that one narration line itself be in English, it is shown as-is, untranslated (translating would mean putting words in its mouth).
|
|
133
|
-
|
|
134
|
-
**Two appearances, switchable anytime.** Settings has an "Appearance" row: **Dark**, **Light** (the default), and **Follow system**. Dark is deep-sea navy; the light palette is taken from the promo artwork — near-white ice blue for the ground, deep royal blue for the text, and the same royal blue on primary buttons. Your choice is stored on the phone, so it is still there next time you open the page.
|
|
135
|
-
|
|
136
|
-
<img width="290" alt="Settings (dark): display mode and appearance" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/settings-dark.png" /> <img width="290" alt="Settings (light): the selected states and the primary button turn royal blue too" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/settings-light.png" />
|
|
157
|
+
## Usage & Configuration
|
|
137
158
|
|
|
138
|
-
|
|
159
|
+
### Connection Route Matrix
|
|
139
160
|
|
|
140
|
-
|
|
161
|
+
Select the route that matches your current networking environment:
|
|
141
162
|
|
|
142
|
-
|
|
163
|
+
| Route | Scenario | Prerequisites | Trade-offs |
|
|
164
|
+
| :--- | :--- | :--- | :--- |
|
|
165
|
+
| **LAN** | Phone and computer on the same Wi-Fi subnet | None | Ready immediately; disconnects upon leaving Wi-Fi |
|
|
166
|
+
| **Tailscale** | Stable remote access across locations | Tailscale installed and logged in on both devices | Fixed private IP; optional HTTPS certificate support |
|
|
167
|
+
| **Public Tunnel** | No public IP and no third-party client installation | Enable Cloudflare Tunnel in settings | Temporary URL rotates on each DSH restart; initial setup downloads ~50 MB binary |
|
|
168
|
+
| **Feishu Long Connection** | Direct enterprise IM messaging without browser | Feishu custom bot credentials configured | No inbound ports required; bidirectional mobile approvals |
|
|
143
169
|
|
|
144
|
-
|
|
170
|
+
### Mobile Interface Guide
|
|
145
171
|
|
|
146
|
-
**
|
|
172
|
+
**First, get the address of this page.** Open "Settings → Phone Remote" in the DSH desktop app; it lists **every address this computer can be reached at** — "This machine", "LAN", "Tailscale", "Tailscale (encrypted)", "Public access". Which ones appear depends on what this computer has installed and switched on.
|
|
147
173
|
|
|
148
|
-
|
|
174
|
+
Each one is a block: **QR code on the left, the full URL on the right**. Scanning the QR code with the phone is the easiest way; to type it on another device, click "Copy" on the right, or click into the URL field (it selects the whole address for you).
|
|
149
175
|
|
|
150
|
-
|
|
176
|
+
An address looks like this:
|
|
151
177
|
|
|
152
|
-
|
|
178
|
+
```text
|
|
179
|
+
http://192.168.1.2:3090/mini?token=xxxxxxxxxxxx
|
|
180
|
+
```
|
|
153
181
|
|
|
154
|
-
|
|
182
|
+
> ⚠️ **That URL carries the access pass** — whoever gets it can operate this computer. Do not screenshot it to others, and do not paste it anywhere public. To change the pass, see the "Password" section in the settings page.
|
|
155
183
|
|
|
156
|
-
|
|
184
|
+
Once you are in, this page lets you:
|
|
157
185
|
|
|
158
|
-
|
|
186
|
+
- **Sending & Queuing**: Enter instructions in the bottom input box. When an agent is busy, subsequent messages queue up sequentially and appear on the scale.
|
|
187
|
+
- **Slash Commands**: Type `/` to bring up available session commands with parameter guidance and search filtering.
|
|
188
|
+
- **Interactive Questions**: When the agent requests clarification or user choice, an interactive card pops up for one-tap answers or custom replies.
|
|
189
|
+
- **Back to Bottom**: When scrolling through long message histories, a floating "Back to bottom" button appears in the lower-right corner (disabled in Single frame mode).
|
|
190
|
+
- **Permission Switching**: Tap the top status bar to cycle between View Only (`read-only`), Workspace Write (`workspace-write`), and Full Access (`danger-full-access`).
|
|
159
191
|
|
|
160
|
-
|
|
192
|
+
> ⚠️ **Notice**:
|
|
193
|
+
> 1. Elevating permissions to "Full Access" permits the agent to run arbitrary system commands and modify files across the machine. Proceed with caution.
|
|
194
|
+
> 2. System-level confirmation dialogs for dangerous commands belong to the DSH on your computer itself — the phone cannot approve them, so you will need to handle those on the computer.
|
|
161
195
|
|
|
162
|
-
|
|
196
|
+
### Advanced Settings: Embedded Desktop Interface (Phone or PC Browser)
|
|
163
197
|
|
|
164
|
-
|
|
198
|
+
**The remote page is not phone-only.** Open the same address (the one the QR code points at) in a PC browser and it works just the same — the layout is simply tuned for a phone screen. What makes this route genuinely useful on a PC is "Advanced settings": it embeds the complete DSH desktop interface, so you do not have to spin up a separate `dsh web`.
|
|
165
199
|
|
|
166
|
-
|
|
200
|
+
How to open it:
|
|
167
201
|
|
|
168
|
-
|
|
202
|
+
1. Click the gear in the top-right corner, find the "Advanced settings" row (its hint reads "Open the DSH interface on the computer and change the settings the phone does not have"), and switch it to on.
|
|
203
|
+
2. It asks once more — **you must confirm a second time**.
|
|
204
|
+
3. A "Desktop interface" row appears right below (hint: "the complete desktop DSH page"). Click "Open".
|
|
205
|
+
4. A full-screen copy of the DSH desktop interface is embedded right in this page: plugin management, model configuration, session history, and full logs. The bar on top exits back to the remote page.
|
|
169
206
|
|
|
170
|
-
|
|
207
|
+
**It moves this computer's own interface over — it does not start a second one.** Whatever you change or send here happens **on this DSH**; the desktop app and this view share one state. Nor is it "spinning up another web instance": the plugin's server authenticates once through the official door, then **proxies every request** to the local interface in real time (even live UI refreshes are forwarded as they come, never buffered). The phone never touches any official credential.
|
|
171
208
|
|
|
172
|
-
|
|
209
|
+
> ⚠️ **Notice**:
|
|
210
|
+
> 1. **This is a permission switch, not an ordinary preference.** Turning it on extends the token's reach from "what the phone page exposes" to the **entire desktop management plane** — model configuration, credentials, plugin install/uninstall, session history. It is therefore off by default and takes two confirmations to enable.
|
|
211
|
+
> 2. What gets embedded is the desktop interface as-is — on a narrow phone screen it adapts to its mobile layout; in a PC browser you get the original.
|
|
173
212
|
|
|
174
|
-
|
|
213
|
+
### Desktop "Remote Window"
|
|
175
214
|
|
|
176
|
-
|
|
215
|
+
**In one sentence**: open computer A's DSH interface directly inside computer B's DSH desktop window.
|
|
177
216
|
|
|
178
|
-
**
|
|
217
|
+
**What it replaces**: when both machines run their own DSH, looking at the other one used to take one of two detours — an extra browser window (so you keep switching between two sets of windows), or full remote desktop (the entire screen comes over, with all the resolution and shortcut friction). This entry turns "that machine" into one panel: click and it is there, click again and you are back where you were.
|
|
179
218
|
|
|
180
|
-
|
|
219
|
+
#### What it looks like in use
|
|
181
220
|
|
|
182
|
-
|
|
221
|
+
1. Click "Remote Window" in the left sidebar; the main view lists the computers you have paired — one row each, with name, address, and when it last connected.
|
|
222
|
+
2. Click a row and that computer's interface is embedded in the panel.
|
|
223
|
+
3. Click the sidebar row again (icon, label, or any blank part of the row) to leave and return to the panel you were on.
|
|
183
224
|
|
|
184
|
-
**
|
|
225
|
+
While the interface displays normally, the bar at the top **auto-hides** — move the mouse to the top edge and it slides out. The bar carries "← Back to list", which computer this is, and "Try again": that is the only way out (and the way to retry) when something goes wrong, so in the connecting, failed, and never-loaded states **it stays visible and never hides**.
|
|
185
226
|
|
|
186
|
-
|
|
227
|
+
#### What was done for security
|
|
187
228
|
|
|
188
|
-
|
|
229
|
+
- **The pass never changes hands**: opening a window makes the server sign a one-time ticket (valid for 30 seconds, redeemable once). The browser receives that ticket only — **your access pass and long-lived credentials never enter the browser**, so they cannot end up in browsing history or inside the embedded page.
|
|
230
|
+
- **Only a page carrying a valid ticket may embed**: cross-site embedding is denied by default and allowed only for that one ticket-bearing load. An outside page that learns the address still cannot get in.
|
|
231
|
+
- **Revocation is immediate**: once you revoke device B on A, B's already-open window fails on its next request — no waiting for it to disconnect on its own.
|
|
232
|
+
- **It dies with DSH**: restarting DSH invalidates that screen's pass; click once more to reopen.
|
|
189
233
|
|
|
190
|
-
|
|
191
|
-
First check that the phone and the computer are on the same Wi-Fi.
|
|
234
|
+
#### Cross-Machine Setup (Two Computers)
|
|
192
235
|
|
|
193
|
-
**
|
|
194
|
-
Wait half a minute and try again. If it still won't, the pairing page shows the reason directly. The most common one is **a proxy or VPN running on the computer** — the "TUN mode" in tools like Clash cuts the tunnel's connections; the process looks fine while not a single connection has actually been established. Turn it off and try again. Another possibility: that network simply can't reach Cloudflare (it's intermittent in mainland China, and not something you misconfigured). If so, don't burn time on the public route — **switch to the Tailscale route**.
|
|
236
|
+
Below, **A** is the computer being connected to, and **B** is the one connecting to it.
|
|
195
237
|
|
|
196
|
-
**
|
|
197
|
-
This happens often after the phone has been in the background. The page reconnects by itself; give it a few seconds. If that doesn't work, open settings and tap "Reconnect".
|
|
238
|
+
**On A**
|
|
198
239
|
|
|
199
|
-
**
|
|
200
|
-
|
|
240
|
+
1. **Install this plugin, version `0.2.1` or newer.** "Remote Window" first shipped in `0.2.1` — B connects to the code running on A, so if A is on an older version, B sees the old interface.
|
|
241
|
+
2. Open "Settings → Phone Remote → Allow other computers to connect" and switch it on. It is off by default; while it is off, A does not accept pairing requests at all.
|
|
242
|
+
3. In the "Password" section of the same settings page, click "Copy" to get A's pass.
|
|
201
243
|
|
|
202
|
-
**
|
|
203
|
-
That means the link you opened didn't carry one — for example, you typed the address by hand. Go back to the computer and scan the QR code again.
|
|
244
|
+
**On B** (in B's "Settings → Phone Remote")
|
|
204
245
|
|
|
205
|
-
|
|
206
|
-
Change it in the password section of "Settings → Phone Remote". **At least 12 characters.** A DSH restart is required afterwards, and the phone has to scan a new code.
|
|
246
|
+
The section you need is "Other computers", near the bottom of the settings page. It is the mirror image of the "Devices" section above — that one lists who can get in, this one lists whom you can reach.
|
|
207
247
|
|
|
208
|
-
|
|
248
|
+
1. Click "Add a computer" to unfold three fields.
|
|
249
|
+
2. **That computer's address (the one on its "Phone Remote" page, no `/mini`)** — enter A's address. This is the field that matters most; see "Which address to enter" below.
|
|
250
|
+
3. **That computer's pass (copy it from its "Phone Remote" settings)** — paste what you copied in step 3 on A. This field is masked.
|
|
251
|
+
4. **Give it a name (optional; the address is used if you leave it blank)** — so you can tell it apart in the list.
|
|
252
|
+
5. Click "Confirm add". This really does pair with A once — afterwards A's settings page gains a "this computer" entry and B gains a row.
|
|
253
|
+
6. Click that row in the list.
|
|
209
254
|
|
|
210
|
-
|
|
255
|
+
Each row shows the name, the address, `last ok <time>` (or "no record yet"), and two buttons on the right: **"Reconnect"** fetches a fresh pass, **"Disconnect"** removes the pairing. Disconnecting asks once and states that the entry on the far computer **stays** — to revoke it fully, remove this device on A.
|
|
211
256
|
|
|
212
|
-
**
|
|
257
|
+
**Which address to enter**
|
|
213
258
|
|
|
214
|
-
|
|
259
|
+
- Enter the address shown on A's "Phone Remote" page (no trailing `/mini` needed) — **not** the one you use to open the DSH interface on A itself.
|
|
260
|
+
- **It must be `https://`.** A plain `http://` address can pair and can fetch a ticket, but the frame stays blank: on the way in, the browser has to store a cookie for this screen (every request inside the frame is then identified by it), and it will only store such a cookie over an encrypted connection. On an http address that cookie is dropped outright, so every later request is refused. Local `127.0.0.1` is the one exception — browsers treat loopback as a trusted origin — which is why this restriction only bites cross-machine setups.
|
|
261
|
+
- Tailscale is recommended: switch on "HTTPS address (Tailscale)" on A, then enter `https://<machine>.<your-tailnet>.ts.net` on B — **no port needed**. The address is stable, so you set it once.
|
|
262
|
+
- The "Public access" tunnel address changes on every restart, so it is not suitable for cross-machine use.
|
|
215
263
|
|
|
216
|
-
|
|
264
|
+
**How to tell it worked**
|
|
217
265
|
|
|
218
|
-
|
|
266
|
+
Click the row in the list and that computer's interface appears in the frame. When something fails, an explanation appears under that row — the far side has not switched it on, the pairing was revoked, it is unreachable, or the address is wrong; each has its own message.
|
|
219
267
|
|
|
220
|
-
|
|
268
|
+
**Revoking a computer later**
|
|
221
269
|
|
|
222
|
-
|
|
270
|
+
On A, open "Settings → Phone Remote → Devices" — the list of who can get in, each row carrying "Rename" and "Revoke". Find that computer, click "Revoke", then "Confirm revoke". **It takes effect immediately**: a window the far side already has open fails on its next request; no need to wait for it to disconnect.
|
|
223
271
|
|
|
224
|
-
|
|
272
|
+
### Feishu Bot Setup Guide
|
|
225
273
|
|
|
226
|
-
|
|
274
|
+
1. Log in to the [Feishu Open Platform](https://open.feishu.cn/) and create a custom enterprise application.
|
|
275
|
+
2. Record the `App ID` and `App Secret` under Credentials & Basic Info.
|
|
276
|
+
3. Navigate to "Add Capabilities" and add the "Bot" capability.
|
|
277
|
+
4. Navigate to "Events & Callbacks", set the subscription mode to "Receive events over a long connection", and subscribe to `im.message.receive_v1`.
|
|
278
|
+
5. Under "Permissions", grant the following 3 scopes:
|
|
279
|
+
- Receive messages (`im:message:receive_v1`)
|
|
280
|
+
- Send messages as bot (`im:message:send_as_bot`)
|
|
281
|
+
- Read and send single/group chat messages (`im:message.group_at_msg:readonly` suite)
|
|
282
|
+
6. Create and **publish an application version**.
|
|
283
|
+
7. Return to DSH desktop "Settings" → "Phone Remote" → "Feishu", paste the credentials, and turn the toggle on. The first time you message the bot, it replies with your `open_id`. Add this ID to the allow-list to finish onboarding.
|
|
227
284
|
|
|
228
|
-
|
|
285
|
+
### Configuration Parameters
|
|
229
286
|
|
|
230
|
-
|
|
287
|
+
Settings can be managed either via the desktop "Phone Remote" panel or declared directly in the standard DSH profile:
|
|
231
288
|
|
|
232
|
-
|
|
289
|
+
| Parameter | Type | Default | Lifecycle | Description |
|
|
290
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
291
|
+
| `port` | `number` | `3090` | Restart required | Local HTTP port for the remote service (auto-increments on conflict) |
|
|
292
|
+
| `token` | `string` | *(generated)* | Restart required | Access token (must be at least 12 characters if customized) |
|
|
293
|
+
| `defaultMode` | `string` | `"minimal"` | Immediate | Default view mode on mobile: `"minimal"`, `"chat"`, `"full"` |
|
|
294
|
+
| `externalNotify` | `boolean` | `true` | Immediate | Play chimes and vibrate on task completion |
|
|
295
|
+
| `tunnel.enabled` | `boolean` | `false` | Restart required | Enable Cloudflare temporary public tunnel |
|
|
296
|
+
| `tailscale.serve` | `boolean` | `false` | Restart required | Enable Tailscale HTTPS certificate listener |
|
|
297
|
+
| `feishu.enabled` | `boolean` | `false` | Immediate | Enable Feishu WebSocket long connection |
|
|
233
298
|
|
|
234
299
|
---
|
|
235
300
|
|
|
236
|
-
##
|
|
237
|
-
|
|
238
|
-
After upgrading DSH, run `node tools/structure-check.mjs` once. It reports entry by entry: which ones still hold, which have drifted, and whether a drifted one actually needs attention. When anything has drifted the exit code is 1, so the check can be wired into a pipeline later.
|
|
301
|
+
## License
|
|
239
302
|
|
|
240
|
-
|
|
303
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
241
304
|
|
|
242
|
-
|
|
305
|
+
### Documentation & Reference Links
|
|
243
306
|
|
|
244
|
-
|
|
307
|
+
- [Sprites and Animation Guide](docs/character.md) (Chinese): Image tool pipelines, shared prompt templates, dimensions, and acceptance criteria.
|
|
308
|
+
- [Sprite Reference Frames (Frozen 2026-09-28)](docs/art-refs/2026-09-28/) (Chinese): Reference frames and prompt baselines.
|
|
309
|
+
- [Changelog](CHANGELOG.md): Historical evolution and bug fix records.
|
|
310
|
+
- [Repository](https://github.com/xingzhen199186/dsh-mini-remote): Official GitHub home.
|
|
245
311
|
|
|
246
|
-
|
|
312
|
+
### Credits
|
|
247
313
|
|
|
248
|
-
|
|
314
|
+
Special thanks to [dsh-pocket](https://www.npmjs.com/package/dsh-pocket) by @shaobeichen for inspiring the multi-path independent QR pairing layout.
|