dsh-mini-remote 0.1.9 → 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 +67 -0
- package/README.en.md +198 -141
- package/README.md +198 -148
- package/client/client.js +1931 -3
- package/lib/build.js +32 -1
- package/lib/devices.js +372 -0
- package/lib/index.js +1773 -36
- package/lib/mirror.js +1715 -0
- package/lib/page.html +1556 -71
- package/lib/page.js +4 -1
- package/lib/remotes.js +279 -0
- package/lib/server.js +1278 -24
- package/lib/store.js +41 -0
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,73 @@
|
|
|
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
|
+
|
|
46
|
+
## [0.2.0] - 2026-10-08
|
|
47
|
+
|
|
48
|
+
这一版跨了三天、50 笔改动,主体是**「进阶设置」——把电脑端那整套界面搬到手机上**,加上一颗「回到底部」的浮标,以及它俩连着带出来的一批手机端修补。
|
|
49
|
+
|
|
50
|
+
### 新加的
|
|
51
|
+
|
|
52
|
+
- **手机上能看到电脑端那整套界面了。** 手机这张遥控页是专门为手机做的,所以电脑上那些插件贡献的设置页它进不去——改模型配置、装卸插件、翻会话记录这些事,原来只能回电脑。现在设置页多了一项「进阶设置」:打开它,下面多出一行「电脑端界面」,点「打开」,**同一份电脑端页面原样嵌在手机这半边**(不跳转、不开新标签,关掉就真停)。**它默认关着,打开要付代价**:开启等于把这个访问口令的权限,从遥控页露出的那一点扩到**整个电脑端设置面**(模型配置、凭据页、插件装卸、会话记录),所以页面上写明后果,要点两次才算开;服务端拿不到电脑端地址时整行不显示——不摆一个假的开关。
|
|
53
|
+
|
|
54
|
+
- 这四十来笔里绝大多数是把它磨到能用。值得记的是几处根因:**白屏**有两处(挂载前缀不对,加上我们自己多带了一个 token 参数);**「一直正在重新连接」**是 WebSocket 没转发;**一堆 403** 是 WebSocket 握手和普通请求的 `Origin` 得换成上游自己;**界面加载不出来**是镜像前缀下面的 POST 没转;**重启后卡在「Loading plugins」**是宿主还没就绪就被问了,该等而不是立刻回 502;一次 34 MB 的大附件照旧转发;带内容指纹的静态资源补了长期缓存。
|
|
55
|
+
|
|
56
|
+
- **首帧没字**查了好几轮,最后在真面板上量出来真凶:另一个插件贴在根元素上的「卷起」标记(`opacity:0`)。我们把那个标记摘掉,从样式上根治,删掉了中途加的盲兜底。**内容区滚不动**是我们自己的适配漏了一格 `min-height:0`;**侧栏那一列不能滚、「设置」够不着**、**侧栏中间那层被压成 0**(历史会话看不见)、**主页整片空白**、**插件市场那一节被压窄**各有各的根因,都修了;插件市场的「能滚的列表窗口」从 356 做到 498 像素。
|
|
57
|
+
|
|
58
|
+
- **这一页的适配由我们自己来**:别的插件写死了「只在窄屏生效」的样式,一律摘掉(`dsh-pocket` 是真正动官方设置面板的那一个,单独挡在门外)。官方设置面板的导航掰回竖排、字始终显示;插件市场那格的社区介绍、两个用不上的按钮先藏起来,把地方让给要用的东西。
|
|
59
|
+
|
|
60
|
+
- **怎么知道 DSH 一升级、这些适配会不会悄悄失效**:多了一份**结构依赖清单**(`tools/structure-deps.mjs`),把我们靠官方界面上的哪些「标记」活着一条条登记下来,并标明失配的后果(只是这一条不生效,还是可能误伤别处);配一个**升级自检**(`tools/structure-check.mjs`)对着活界面逐条查,中文报告、失配非零退出。清单和代码之间还钉了测试:改了代码没改清单、加了新依赖没登记,都会红。
|
|
61
|
+
|
|
62
|
+
- **多了一颗「回到底部」的圆形浮标。** 照电脑端 DSH 那颗做:聊天和「完整」两个模式里,往上翻过之后右下角浮出来,点一下回到最新那一条。**单帧模式下它一律不出现**(那一模式整屏只有一条回复,没有「回去」这回事);渐出 130 毫秒;深色浅色各适配一套——浅色下那道环深一档、抬一层更轻的投影,深色下投影本来等于零就去掉;看得见的圆比按得到的地方小一档(热区是手指的下限,不该跟着缩)。尺寸和位置是量着调的:看得见的面积先减半(38 → 27)、往左让开滚动条那条带,最后又增大一档到 31。
|
|
63
|
+
|
|
64
|
+
### 修了的
|
|
65
|
+
|
|
66
|
+
- **「完整」模式里执行轨迹那个「进行中」不再竖着折行**(真机复现过);组头右侧的「模型原话」也走上 markdown 渲染,和别处的正文一个长相。
|
|
67
|
+
- **插话发送真的插话了。** 0.1.9 只做了「繁忙时是排队还是插话」那个开关,没接到发送路径上——选了插话,实际还是排队。
|
|
68
|
+
- **镜像页偶尔显示 `{"error":"not found"}`。** 那是我们自己的兜底 404:进阶设置关着的时候,门后面本来就不该回 JSON。
|
|
69
|
+
- **进阶设置关着时,那一行仍然显示。** 根因在 CSS,不在 JS。
|
|
70
|
+
- **`engines.dsh` 和 `peerDependencies` 声明的是同一个区间了。** 两处不一致时,npm 拿一个、宿主看另一个。
|
|
71
|
+
|
|
5
72
|
## [0.1.9] - 2026-10-05
|
|
6
73
|
|
|
7
74
|
这一版跨了三天、74 笔改动,主体是**设置页整屏化与插件页**、**「完整」显示模式与执行轨迹**,以及一串观感与读取速度的修补。
|
package/README.en.md
CHANGED
|
@@ -1,242 +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
|
-
##
|
|
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.
|
|
32
|
+
## Background & Pain Points
|
|
27
33
|
|
|
28
|
-
|
|
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:
|
|
29
35
|
|
|
30
|
-
|
|
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.
|
|
31
39
|
|
|
32
|
-
|
|
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.
|
|
33
41
|
|
|
34
|
-
|
|
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.
|
|
156
|
+
## Usage & Configuration
|
|
127
157
|
|
|
128
|
-
|
|
158
|
+
### Connection Route Matrix
|
|
129
159
|
|
|
130
|
-
|
|
160
|
+
Select the route that matches your current networking environment:
|
|
131
161
|
|
|
132
|
-
|
|
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 |
|
|
133
168
|
|
|
134
|
-
|
|
169
|
+
### Mobile Interface Guide
|
|
135
170
|
|
|
136
|
-
|
|
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`).
|
|
137
176
|
|
|
138
|
-
|
|
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.
|
|
139
180
|
|
|
140
|
-
|
|
181
|
+
### Advanced Settings: Embedded Desktop Interface (Phone or PC Browser)
|
|
141
182
|
|
|
142
|
-
|
|
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`.
|
|
143
184
|
|
|
144
|
-
|
|
185
|
+
How to open it:
|
|
145
186
|
|
|
146
|
-
|
|
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.
|
|
147
191
|
|
|
148
|
-
**
|
|
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.
|
|
149
193
|
|
|
150
|
-
|
|
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.
|
|
151
197
|
|
|
152
|
-
|
|
198
|
+
### Desktop "Remote Window"
|
|
153
199
|
|
|
154
|
-
**
|
|
200
|
+
**In one sentence**: open computer A's DSH interface directly inside computer B's DSH desktop window.
|
|
155
201
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
## Remote control from Feishu
|
|
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.
|
|
159
203
|
|
|
160
|
-
|
|
204
|
+
#### What it looks like in use
|
|
161
205
|
|
|
162
|
-
|
|
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.
|
|
163
209
|
|
|
164
|
-
|
|
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**.
|
|
165
211
|
|
|
166
|
-
|
|
212
|
+
#### What was done for security
|
|
167
213
|
|
|
168
|
-
|
|
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.
|
|
169
218
|
|
|
170
|
-
|
|
219
|
+
#### Cross-Machine Setup (Two Computers)
|
|
171
220
|
|
|
172
|
-
|
|
221
|
+
Below, **A** is the computer being connected to, and **B** is the one connecting to it.
|
|
173
222
|
|
|
174
|
-
|
|
223
|
+
**On A**
|
|
175
224
|
|
|
176
|
-
|
|
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.
|
|
177
228
|
|
|
178
|
-
**
|
|
229
|
+
**On B** (in B's "Settings → Phone Remote")
|
|
179
230
|
|
|
180
|
-
|
|
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.
|
|
181
232
|
|
|
182
|
-
|
|
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.
|
|
183
239
|
|
|
184
|
-
|
|
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.
|
|
185
241
|
|
|
186
|
-
|
|
242
|
+
**Which address to enter**
|
|
187
243
|
|
|
188
|
-
|
|
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.
|
|
189
248
|
|
|
190
|
-
**
|
|
191
|
-
First check that the phone and the computer are on the same Wi-Fi.
|
|
249
|
+
**How to tell it worked**
|
|
192
250
|
|
|
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**.
|
|
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.
|
|
195
252
|
|
|
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".
|
|
253
|
+
**Revoking a computer later**
|
|
198
254
|
|
|
199
|
-
**
|
|
200
|
-
Audio only plays after you've touched the page once. Tap it.
|
|
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.
|
|
201
256
|
|
|
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.
|
|
257
|
+
### Feishu Bot Setup Guide
|
|
204
258
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
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.
|
|
209
269
|
|
|
210
|
-
|
|
270
|
+
### Configuration Parameters
|
|
211
271
|
|
|
212
|
-
|
|
272
|
+
Settings can be managed either via the desktop "Phone Remote" panel or declared directly in the standard DSH profile:
|
|
213
273
|
|
|
214
|
-
|
|
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 |
|
|
215
283
|
|
|
216
284
|
---
|
|
217
285
|
|
|
218
|
-
##
|
|
219
|
-
|
|
220
|
-
The idea came from this: an agent task often takes a long time to finish, and if you step out, you need the phone to drive it remotely.
|
|
221
|
-
|
|
222
|
-
But the phone clients that exist show the PC's execution steps in faithful detail. You send one instruction; it may think for several minutes, read dozens of files, call tools a few times, and only then give you a conclusion. If you're out, or busy away from the computer, you simply don't have the time to watch the phone that closely.
|
|
223
|
-
|
|
224
|
-
I don't think that approach is bad. It's complete and controllable, and if you're going to do serious work, it's the right one.
|
|
225
|
-
|
|
226
|
-
But when I'm out, what I want is something else — **a lighter way to interact that asks less of my attention**. The phone screen is small, and so is the attention I have to spare when I'm out. Most of the time I only need one thing: **this round is done, time to send the next instruction.** And even at my desk, I rarely read the AI's running commentary while it works.
|
|
227
|
-
|
|
228
|
-
So the interface here is deliberately crude: it drops the PC's execution steps entirely and puts only the AI's final conclusion in front of you.
|
|
229
|
-
|
|
230
|
-
**In a sense, it exists so that you look at it less.**
|
|
286
|
+
## License
|
|
231
287
|
|
|
232
|
-
|
|
288
|
+
This project is licensed under the [MIT License](LICENSE).
|
|
233
289
|
|
|
234
|
-
|
|
290
|
+
### Documentation & Reference Links
|
|
235
291
|
|
|
236
|
-
|
|
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.
|
|
237
296
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
## License
|
|
297
|
+
### Credits
|
|
241
298
|
|
|
242
|
-
|
|
299
|
+
Special thanks to [dsh-pocket](https://www.npmjs.com/package/dsh-pocket) by @shaobeichen for inspiring the multi-path independent QR pairing layout.
|