dsh-mini-remote 0.2.0 → 0.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/CHANGELOG.md +41 -0
- package/README.en.md +198 -147
- package/README.md +198 -154
- package/client/client.js +1931 -3
- package/lib/build.js +32 -1
- package/lib/devices.js +372 -0
- package/lib/index.js +1625 -32
- package/lib/mirror.js +296 -3
- package/lib/page.html +938 -71
- package/lib/page.js +4 -1
- package/lib/remotes.js +279 -0
- package/lib/server.js +937 -55
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,47 @@
|
|
|
2
2
|
|
|
3
3
|
本文件记录每个版本改了什么。格式参考 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.1.0/),版本号遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
|
|
4
4
|
|
|
5
|
+
## [0.2.1] - 2026-10-17
|
|
6
|
+
|
|
7
|
+
这一版跨了十天、46 笔改动,主体是**「远程窗口」真的能跨电脑了** —— 在另一台电脑的 DSH 桌面端里,打开这台电脑的界面。它前面压着一件必须先做的事:**多设备身份**(原来一个口令管所有设备,撤销一台等于全撤)。后面跟着一串"让它用起来不别扭"的修补,以及一件拖了很久的工程账:**这个仓库终于有 CI 了**。
|
|
8
|
+
|
|
9
|
+
### 新加的
|
|
10
|
+
|
|
11
|
+
- **跨电脑「远程窗口」。** 在 B 电脑的 DSH 桌面端里,打开 A 电脑的界面——不用切窗口、不用远程桌面。做法是"一次性票据过门":A 发一张 30 秒、只能兑一次的票,B 的浏览器拿着它进门,进门那一刻换成窗口会话;**访问口令和长期凭据一个字节都不进浏览器**。跨站嵌入默认只许同源,带票那一次才放开。
|
|
12
|
+
- **地址怎么填**:填那台电脑「手机遥控」页里那条,**必须 https**(明文能配对、能取票,但框里是白的——通行凭据在非 https 的地址上会被浏览器丢掉,这是实测出来的)。推荐 Tailscale:地址固定,设一次就好。
|
|
13
|
+
- **A 侧有一个默认关的总开关「允许别的电脑连接」**。关着的时候,配对和取票两条路一条都不接——"关"是一个用户能读懂的整体状态。
|
|
14
|
+
|
|
15
|
+
- **多设备身份。** 每台设备一枚自己的凭据,可以单独撤销(撤销是即时的,连已经开着的窗口下次请求也会 401)。**手机页的地址栏不再带着访问口令**——口令退回它本来的角色:入场邀请函,扫一次码就发一张凭据。
|
|
16
|
+
- 电脑端设置页多了设备列表:看得到谁连过、能改名、能撤销。
|
|
17
|
+
|
|
18
|
+
- **自检。** 设置页最末多了一块,回答三个问题:**这台跑的是哪一版**、**哪些接口现在真的在**、**开关什么状态**。它还会说一句"进程比代码旧"——那是真机上真出过的事:桌面端连开一天,装是新版,跑的却是旧的。
|
|
19
|
+
|
|
20
|
+
- **出错的时候,看得见了。** 原来错误只打在终端里,用户看着图形界面一个字也看不到;跨机那条路连状态都不留,退出面板就再也查不到。现在有一圈"最近 20 条错误"进自检,**进去之前先脱敏**(口令、飞书密钥、地址里的凭据参数、设备凭据形状,四类都换成 `***`)。
|
|
21
|
+
|
|
22
|
+
- **电脑端界面的顶栏改成鼠标碰顶才滑出**,感应带从 6 像素加高到 16(原来几乎要精确放到那条线上)。
|
|
23
|
+
|
|
24
|
+
### 改了的
|
|
25
|
+
|
|
26
|
+
- **侧栏那枚「远程窗口」点开是「其他电脑」名单,不再显示本机界面。** 人坐在电脑前,为什么还要在面板里再看一遍自己的界面——"看本机"是跨机做不出来时的中间验证,跨机做完了它就退休了。底层那套取票、嵌框、过门的零件保留(跨机在复用)。
|
|
27
|
+
- 手机侧栏的会话条目补齐了执行功能:重命名、置顶、归档、分叉。归档相关的两个按钮先藏起来(代码不删)。
|
|
28
|
+
- 「完整」模式回答落定后,停在这一轮内容的开头,不再停在总结正文的开头。
|
|
29
|
+
|
|
30
|
+
### 修了的
|
|
31
|
+
|
|
32
|
+
- **远程窗口每约 25 秒整屏重载一次。** 根因是面板自己在定时换票(票一变,框的地址就变)。那个凭据本来就不会按时间过期——它只在 DSH 重启或对面撤销时失效——所以定时换票纯属多余,拆掉。
|
|
33
|
+
- **取票请求没有超时。** 对面不回话时,那一屏会永远停在"正在向那台电脑换一张通行证…"。现在 15 秒上限(比宿主自己那条 8 秒长,不会把"慢但会成"的请求掐掉),超时给一句人话 + 「再试一次」。
|
|
34
|
+
- **那个 20 秒兜底在框加载成功之后不取消**,会在加载好 19 秒后把正常界面换成"一直没打开"。现在框一加载好就掐钟。
|
|
35
|
+
- **框没打开时自动重取一次票。** 上一版拆掉定时换票之后只剩人手动重试,而"第一次加载被拖过 30 秒"本来能救回来——补上这条约束:自动重取永远跟着一次人的动作,最多一次,不会变成每 20 秒自己转。
|
|
36
|
+
- **「再点一下退出远程窗口」失效**:退出入口只挂在 16×16 的图标上,人点的是 252×36 那一行。改成整行都认。
|
|
37
|
+
|
|
38
|
+
### 工程
|
|
39
|
+
|
|
40
|
+
- **加了 CI(GitHub Actions)。** 两个 job:`gate` 在 Windows 上跑 Node 22 与 24(红了就是真红),`probe` 在 Linux 上跑一遍(允许红,但要看得见——它红一般是"某条测试只在 Windows 上成立")。加载探针、活体检查、真机这三层仍然手跑:它们要活的 DSH,塞进 CI 只会长期红着然后没人看。
|
|
41
|
+
- **版本号与 CHANGELOG 改成互证。** 原来测试里钉着一个字面量版本,发一次版要改三个地方,其中一个纯粹是为了让测试继续绿。现在断言"`package.json` 的 version 必须等于 CHANGELOG 最顶上那条",忘一处必红。
|
|
42
|
+
- **体量守门**:手机页不超过 8,700 行 / 480 KB,发布包不超过 3 MB(问 `npm pack` 要真实数字,不自己遍历目录)。
|
|
43
|
+
- **发版清单入仓**(`docs/发版清单.md`):七步,从改版本到 publish 之后的核对。
|
|
44
|
+
- CI 首跑红了两次,抓到的都是**本机永远发现不了**的问题:一条测试要 `numpy` 而 skip 条件只探了 python;三条测试把时间钉死在 `+08:00`,而界面按本地时区显示(本机是 UTC+8 所以一直绿)。顺带记下一个能在本地预演 CI 的办法:`$env:TZ="UTC"` 之后再跑。
|
|
45
|
+
|
|
5
46
|
## [0.2.0] - 2026-10-08
|
|
6
47
|
|
|
7
48
|
这一版跨了三天、50 笔改动,主体是**「进阶设置」——把电脑端那整套界面搬到手机上**,加上一颗「回到底部」的浮标,以及它俩连着带出来的一批手机端修补。
|
package/README.en.md
CHANGED
|
@@ -1,248 +1,299 @@
|
|
|
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="#desktop-remote-window">Remote Window</a> ·
|
|
25
|
+
<a href="#quick-start">Quick Start</a> ·
|
|
26
|
+
<a href="#usage--configuration">Usage & Configuration</a> ·
|
|
27
|
+
<a href="#license">License</a>
|
|
28
|
+
</p>
|
|
16
29
|
|
|
17
30
|
---
|
|
18
31
|
|
|
19
|
-
##
|
|
32
|
+
## Background & Pain Points
|
|
20
33
|
|
|
21
|
-
|
|
34
|
+
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:
|
|
22
35
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
- the only thing that "talks" is the whale girl: the line the model mutters between steps, spoken in her speech bubble.
|
|
36
|
+
- **Imbalanced Information Density**: Raw reasoning traces, verbose tool parameters, and large unified diffs overwhelm small displays, burying the primary conclusion.
|
|
37
|
+
- **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.
|
|
38
|
+
- **Inflexible Connectivity**: Pure LAN routes disconnect as soon as you step outside, while centralised cloud relays introduce external credential custody risks.
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
**Minimal Remote** was built to solve this: by default, the mobile view presents only your input and the AI's final answer, filtering out execution noise while allowing you to drill down into the full trace on demand.
|
|
29
41
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
It is **not** a second screen for the desktop interface. Approval dialogs, file diffs and tool-call chains exist on the computer and nowhere on the default page — deliberately. It does very little. (If you want the **whole** desktop interface, there is an off-by-default entry in settings — see the last paragraph of [What the phone can do](#what-the-phone-can-do).)
|
|
33
|
-
|
|
34
|
-
Other phone clients copy the computer's execution process over to the phone in full. This one does the opposite: **it sends only the two lines you asked for.** That is the single biggest difference between it and them.
|
|
42
|
+
---
|
|
35
43
|
|
|
36
|
-
##
|
|
44
|
+
## Core Features
|
|
37
45
|
|
|
38
|
-
- **
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
46
|
+
- 🎛️ **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).
|
|
47
|
+
- 📱 **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.
|
|
48
|
+
- 🌐 **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.
|
|
49
|
+
- 🐬 **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.
|
|
50
|
+
- 💬 **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.
|
|
51
|
+
- 🗂️ **In-Place Mobile Session Management**: Rename, pin, archive, or fork sessions from the most recent completed turn directly on your phone, with clear indicators for pending approvals and questions.
|
|
52
|
+
- 💻 **Desktop Embedded "Remote Window"**: Adds a "Remote Window" shortcut to the left sidebar of the DSH desktop app: it lists the other computers you have paired, and clicking a row embeds that computer's DSH desktop interface in the main view; click the row again to exit and return to where you were. Cross-machine access is supported; see "Desktop \"Remote Window\"" below for the pairing steps.
|
|
53
|
+
- 🔒 **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
54
|
|
|
42
55
|
---
|
|
43
56
|
|
|
44
|
-
##
|
|
57
|
+
## UI Preview
|
|
45
58
|
|
|
46
|
-
|
|
47
|
-
dsh plugin --profile web add dsh-mini-remote
|
|
48
|
-
```
|
|
59
|
+
### Conversation Screen (Single Frame / Chat / Full)
|
|
49
60
|
|
|
50
|
-
|
|
61
|
+
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
62
|
|
|
52
|
-
|
|
63
|
+
<div align="center">
|
|
64
|
+
<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" />
|
|
65
|
+
<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" />
|
|
66
|
+
</div>
|
|
53
67
|
|
|
54
|
-
|
|
55
|
-
<summary>Installing from GitHub source, from a local folder, and which DSH versions it fits</summary>
|
|
68
|
+
### Settings Panel & Appearance
|
|
56
69
|
|
|
57
|
-
|
|
70
|
+
Switch presentation modes, color themes, or trigger manual reconnects from the settings overlay:
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
72
|
+
<div align="center">
|
|
73
|
+
<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" />
|
|
74
|
+
<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" />
|
|
75
|
+
</div>
|
|
62
76
|
|
|
63
|
-
|
|
77
|
+
### Execution Animation
|
|
64
78
|
|
|
65
|
-
|
|
66
|
-
dsh plugin --profile web add <the folder you put the source in>
|
|
67
|
-
```
|
|
79
|
+
During task execution, the view presents an animated running state, elapsed timer, and queued task scale without unverified progress guesses:
|
|
68
80
|
|
|
69
|
-
|
|
81
|
+
<div align="center">
|
|
82
|
+
<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" />
|
|
83
|
+
<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" />
|
|
84
|
+
</div>
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
### Remote Window (Desktop)
|
|
72
87
|
|
|
73
|
-
|
|
88
|
+
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
89
|
|
|
75
|
-
|
|
90
|
+
<div align="center">
|
|
91
|
+
<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" />
|
|
92
|
+
</div>
|
|
76
93
|
|
|
77
|
-
|
|
94
|
+
---
|
|
78
95
|
|
|
79
|
-
|
|
96
|
+
## Quick Start
|
|
80
97
|
|
|
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 |
|
|
98
|
+
### Prerequisites
|
|
86
99
|
|
|
87
|
-
|
|
100
|
+
Before installing, make sure this computer meets the following requirements:
|
|
88
101
|
|
|
89
|
-
|
|
102
|
+
- **Node.js**: `^22.19.0 || >=24.0.0`
|
|
103
|
+
- **DSH (DeepSeek Harness)**: `>=0.1.5-rc.2 <0.3.0`
|
|
104
|
+
- **OS**: Windows, macOS, or Linux
|
|
90
105
|
|
|
91
|
-
|
|
106
|
+
> ⚠️ **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
107
|
|
|
93
|
-
###
|
|
108
|
+
### Installation
|
|
94
109
|
|
|
95
|
-
|
|
110
|
+
#### Option 1: Install via DSH Desktop UI (Recommended)
|
|
96
111
|
|
|
97
|
-
|
|
112
|
+
1. Click the "Plugins" button on the top navigation bar of DSH to open the plugin manager.
|
|
113
|
+
2. Click the "Add Plugin" button in the upper-right corner to open the installation dialog.
|
|
114
|
+
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").
|
|
115
|
+
4. Click the "Install" button at the bottom of the dialog.
|
|
98
116
|
|
|
99
|
-
|
|
117
|
+
> ⚠️ **Notice**:
|
|
118
|
+
> 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.
|
|
119
|
+
> 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
120
|
|
|
101
|
-
|
|
121
|
+
#### Option 2: Install from npm (Command Line)
|
|
102
122
|
|
|
103
|
-
|
|
123
|
+
Execute the installation command in your terminal. Replace `web` with your custom profile name if you are not using the default profile:
|
|
104
124
|
|
|
105
|
-
|
|
125
|
+
```powershell
|
|
126
|
+
dsh plugin --profile web add dsh-mini-remote
|
|
127
|
+
```
|
|
106
128
|
|
|
107
|
-
|
|
129
|
+
#### Option 3: Install from GitHub
|
|
108
130
|
|
|
109
|
-
|
|
131
|
+
```powershell
|
|
132
|
+
dsh plugin --profile web add github:xingzhen199186/dsh-mini-remote
|
|
133
|
+
```
|
|
110
134
|
|
|
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.
|
|
135
|
+
#### Option 4: Install from Local Directory
|
|
113
136
|
|
|
114
|
-
|
|
137
|
+
```powershell
|
|
138
|
+
dsh plugin --profile web add C:\path\to\dsh-mini-remote
|
|
139
|
+
```
|
|
115
140
|
|
|
116
|
-
###
|
|
141
|
+
### Starting the Service
|
|
117
142
|
|
|
118
|
-
|
|
143
|
+
1. Restart the DSH service (close the active `dsh web` window and launch it again).
|
|
144
|
+
2. Check the console log for the listening port and pairing token:
|
|
145
|
+
```text
|
|
146
|
+
[dsh-mini-remote] 已启动:http://127.0.0.1:3090/mini?token=xxxxxxxxxxxx
|
|
147
|
+
```
|
|
148
|
+
3. Open the DSH desktop UI, navigate to "Settings" → "Phone Remote" in the left sidebar, and view the pairing QR codes and links.
|
|
119
149
|
|
|
120
|
-
|
|
150
|
+
> **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.
|
|
151
|
+
>
|
|
152
|
+
> 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
153
|
|
|
122
154
|
---
|
|
123
155
|
|
|
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" />
|
|
137
|
-
|
|
138
|
-
**The screen while a task is running.** She is mid-stride, the progress bar is moving, and the queue lists what goes next once this round ends. No tool calls and no file diffs on this screen — only the fact that something is running.
|
|
139
|
-
|
|
140
|
-
<img width="290" alt="Running (dark, photographed on a phone): the whale girl running, 15s elapsed" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/running-dark-phone.jpg" /> <img width="290" alt="Running (light, photographed on a phone): the whale girl running, 7m43s elapsed, one instruction queued" src="https://raw.githubusercontent.com/xingzhen199186/dsh-mini-remote/main/docs/running-light-phone.jpg" />
|
|
141
|
-
|
|
142
|
-
**Three display modes.** Tap the ⚙ in the top right to switch. "Single frame" (the default) keeps only the newest reply on screen — good for "I just want to see how this one turned out". "Chat" is a back-and-forth bubble list — good for several rounds of follow-up questions. "Full" takes that same list and **puts each step's process back in its original place** (the same shape the desktop app uses), with layers you can open one by one to see what that step read — and it is searchable. Use it for a while and you'll know which you prefer.
|
|
156
|
+
## Usage & Configuration
|
|
143
157
|
|
|
144
|
-
|
|
158
|
+
### Connection Route Matrix
|
|
145
159
|
|
|
146
|
-
|
|
160
|
+
Select the route that matches your current networking environment:
|
|
147
161
|
|
|
148
|
-
|
|
162
|
+
| Route | Scenario | Prerequisites | Trade-offs |
|
|
163
|
+
| :--- | :--- | :--- | :--- |
|
|
164
|
+
| **LAN** | Phone and computer on the same Wi-Fi subnet | None | Ready immediately; disconnects upon leaving Wi-Fi |
|
|
165
|
+
| **Tailscale** | Stable remote access across locations | Tailscale installed and logged in on both devices | Fixed private IP; optional HTTPS certificate support |
|
|
166
|
+
| **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 |
|
|
167
|
+
| **Feishu Long Connection** | Direct enterprise IM messaging without browser | Feishu custom bot credentials configured | No inbound ports required; bidirectional mobile approvals |
|
|
149
168
|
|
|
150
|
-
|
|
169
|
+
### Mobile Interface Guide
|
|
151
170
|
|
|
152
|
-
|
|
171
|
+
- **Sending & Queuing**: Enter instructions in the bottom input box. When an agent is busy, subsequent messages queue up sequentially and appear on the scale.
|
|
172
|
+
- **Slash Commands**: Type `/` to bring up available session commands with parameter guidance and search filtering.
|
|
173
|
+
- **Interactive Questions**: When the agent requests clarification or user choice, an interactive card pops up for one-tap answers or custom replies.
|
|
174
|
+
- **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).
|
|
175
|
+
- **Permission Switching**: Tap the top status bar to cycle between View Only (`read-only`), Workspace Write (`workspace-write`), and Full Access (`danger-full-access`).
|
|
153
176
|
|
|
154
|
-
|
|
177
|
+
> ⚠️ **Notice**:
|
|
178
|
+
> 1. Elevating permissions to "Full Access" permits the agent to run arbitrary system commands and modify files across the machine. Proceed with caution.
|
|
179
|
+
> 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.
|
|
155
180
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
## Remote control from Feishu
|
|
159
|
-
|
|
160
|
-
**Talk to the session on your computer from inside Feishu.** You send a line, the session runs a round, and the answer comes back under your message — with one more line underneath saying which session it came from (`会话:deploy script`, and `未命名会话` when the session has no name yet). Those two labels are Chinese and stay as they are.
|
|
181
|
+
### Advanced Settings: Embedded Desktop Interface (Phone or PC Browser)
|
|
161
182
|
|
|
162
|
-
|
|
183
|
+
**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`.
|
|
163
184
|
|
|
164
|
-
|
|
185
|
+
How to open it:
|
|
165
186
|
|
|
166
|
-
|
|
187
|
+
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.
|
|
188
|
+
2. It asks once more — **you must confirm a second time**.
|
|
189
|
+
3. A "Desktop interface" row appears right below (hint: "the complete desktop DSH page"). Click "Open".
|
|
190
|
+
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.
|
|
167
191
|
|
|
168
|
-
|
|
192
|
+
**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.
|
|
169
193
|
|
|
170
|
-
|
|
194
|
+
> ⚠️ **Notice**:
|
|
195
|
+
> 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.
|
|
196
|
+
> 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.
|
|
171
197
|
|
|
172
|
-
|
|
198
|
+
### Desktop "Remote Window"
|
|
173
199
|
|
|
174
|
-
|
|
200
|
+
**In one sentence**: open computer A's DSH interface directly inside computer B's DSH desktop window.
|
|
175
201
|
|
|
176
|
-
|
|
202
|
+
**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.
|
|
177
203
|
|
|
178
|
-
|
|
204
|
+
#### What it looks like in use
|
|
179
205
|
|
|
180
|
-
|
|
206
|
+
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.
|
|
207
|
+
2. Click a row and that computer's interface is embedded in the panel.
|
|
208
|
+
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.
|
|
181
209
|
|
|
182
|
-
|
|
210
|
+
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**.
|
|
183
211
|
|
|
184
|
-
|
|
212
|
+
#### What was done for security
|
|
185
213
|
|
|
186
|
-
|
|
214
|
+
- **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.
|
|
215
|
+
- **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.
|
|
216
|
+
- **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.
|
|
217
|
+
- **It dies with DSH**: restarting DSH invalidates that screen's pass; click once more to reopen.
|
|
187
218
|
|
|
188
|
-
|
|
219
|
+
#### Cross-Machine Setup (Two Computers)
|
|
189
220
|
|
|
190
|
-
**
|
|
191
|
-
First check that the phone and the computer are on the same Wi-Fi.
|
|
221
|
+
Below, **A** is the computer being connected to, and **B** is the one connecting to it.
|
|
192
222
|
|
|
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**.
|
|
223
|
+
**On A**
|
|
195
224
|
|
|
196
|
-
**
|
|
197
|
-
|
|
225
|
+
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.
|
|
226
|
+
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.
|
|
227
|
+
3. In the "Password" section of the same settings page, click "Copy" to get A's pass.
|
|
198
228
|
|
|
199
|
-
**
|
|
200
|
-
Audio only plays after you've touched the page once. Tap it.
|
|
229
|
+
**On B** (in B's "Settings → Phone Remote")
|
|
201
230
|
|
|
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.
|
|
231
|
+
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.
|
|
204
232
|
|
|
205
|
-
|
|
206
|
-
|
|
233
|
+
1. Click "Add a computer" to unfold three fields.
|
|
234
|
+
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.
|
|
235
|
+
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.
|
|
236
|
+
4. **Give it a name (optional; the address is used if you leave it blank)** — so you can tell it apart in the list.
|
|
237
|
+
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.
|
|
238
|
+
6. Click that row in the list.
|
|
207
239
|
|
|
208
|
-
|
|
240
|
+
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.
|
|
209
241
|
|
|
210
|
-
|
|
242
|
+
**Which address to enter**
|
|
211
243
|
|
|
212
|
-
|
|
244
|
+
- 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.
|
|
245
|
+
- **It must be `https://`.** A plain `http://` address can pair and can obtain the pass, but the frame stays blank — the browser drops that pass on a non-HTTPS address.
|
|
246
|
+
- 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.
|
|
247
|
+
- The "Public access" tunnel address changes on every restart, so it is not suitable for cross-machine use.
|
|
213
248
|
|
|
214
|
-
|
|
249
|
+
**How to tell it worked**
|
|
215
250
|
|
|
216
|
-
|
|
251
|
+
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.
|
|
217
252
|
|
|
218
|
-
|
|
253
|
+
**Revoking a computer later**
|
|
219
254
|
|
|
220
|
-
|
|
255
|
+
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.
|
|
221
256
|
|
|
222
|
-
|
|
257
|
+
### Feishu Bot Setup Guide
|
|
223
258
|
|
|
224
|
-
|
|
259
|
+
1. Log in to the [Feishu Open Platform](https://open.feishu.cn/) and create a custom enterprise application.
|
|
260
|
+
2. Record the `App ID` and `App Secret` under Credentials & Basic Info.
|
|
261
|
+
3. Navigate to "Add Capabilities" and add the "Bot" capability.
|
|
262
|
+
4. Navigate to "Events & Callbacks", set the subscription mode to "Receive events over a long connection", and subscribe to `im.message.receive_v1`.
|
|
263
|
+
5. Under "Permissions", grant the following 3 scopes:
|
|
264
|
+
- Receive messages (`im:message:receive_v1`)
|
|
265
|
+
- Send messages as bot (`im:message:send_as_bot`)
|
|
266
|
+
- Read and send single/group chat messages (`im:message.group_at_msg:readonly` suite)
|
|
267
|
+
6. Create and **publish an application version**.
|
|
268
|
+
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.
|
|
225
269
|
|
|
226
|
-
|
|
270
|
+
### Configuration Parameters
|
|
227
271
|
|
|
228
|
-
|
|
272
|
+
Settings can be managed either via the desktop "Phone Remote" panel or declared directly in the standard DSH profile:
|
|
229
273
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
274
|
+
| Parameter | Type | Default | Lifecycle | Description |
|
|
275
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
276
|
+
| `port` | `number` | `3090` | Restart required | Local HTTP port for the remote service (auto-increments on conflict) |
|
|
277
|
+
| `token` | `string` | *(generated)* | Restart required | Access token (must be at least 12 characters if customized) |
|
|
278
|
+
| `defaultMode` | `string` | `"minimal"` | Immediate | Default view mode on mobile: `"minimal"`, `"chat"`, `"full"` |
|
|
279
|
+
| `externalNotify` | `boolean` | `true` | Immediate | Play chimes and vibrate on task completion |
|
|
280
|
+
| `tunnel.enabled` | `boolean` | `false` | Restart required | Enable Cloudflare temporary public tunnel |
|
|
281
|
+
| `tailscale.serve` | `boolean` | `false` | Restart required | Enable Tailscale HTTPS certificate listener |
|
|
282
|
+
| `feishu.enabled` | `boolean` | `false` | Immediate | Enable Feishu WebSocket long connection |
|
|
233
283
|
|
|
234
284
|
---
|
|
235
285
|
|
|
236
|
-
##
|
|
286
|
+
## License
|
|
237
287
|
|
|
238
|
-
|
|
288
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
239
289
|
|
|
240
|
-
|
|
290
|
+
### Documentation & Reference Links
|
|
241
291
|
|
|
242
|
-
|
|
292
|
+
- [Sprites and Animation Guide](docs/character.md) (Chinese): Image tool pipelines, shared prompt templates, dimensions, and acceptance criteria.
|
|
293
|
+
- [Sprite Reference Frames (Frozen 2026-09-28)](docs/art-refs/2026-09-28/) (Chinese): Reference frames and prompt baselines.
|
|
294
|
+
- [Changelog](CHANGELOG.md): Historical evolution and bug fix records.
|
|
295
|
+
- [Repository](https://github.com/xingzhen199186/dsh-mini-remote): Official GitHub home.
|
|
243
296
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
## License
|
|
297
|
+
### Credits
|
|
247
298
|
|
|
248
|
-
|
|
299
|
+
Special thanks to [dsh-pocket](https://www.npmjs.com/package/dsh-pocket) by @shaobeichen for inspiring the multi-path independent QR pairing layout.
|