dsh-multi-chat 0.6.3 → 0.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -89
- package/README.zh.md +197 -0
- package/bin/dsh-multi-chat.mjs +9 -25
- package/package.json +5 -1
- package/plugin/dsh-client-ui-multi-wall/README.zh.md +26 -0
- package/plugin/dsh-client-ui-multi-wall/cordis.patch.yml +7 -0
- package/plugin/dsh-client-ui-multi-wall/package.json +5 -1
- package/scripts/install-plugin.ps1 +11 -24
- package/scripts/start-multi.ps1 +4 -3
package/README.md
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
# 💬 dsh-multi-chat
|
|
1
|
+
# 💬 dsh-multi-chat — Multi-chat, one screen
|
|
2
|
+
|
|
3
|
+
**English** | [中文](README.zh.md)
|
|
2
4
|
|
|
3
5
|
<p align="center">
|
|
4
6
|
<a href="https://www.npmjs.com/package/dsh-multi-chat"><img src="https://img.shields.io/npm/v/dsh-multi-chat" alt="npm version"></a>
|
|
@@ -7,181 +9,187 @@
|
|
|
7
9
|
<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/dsh--plugin-community-brightgreen" alt="dsh-plugin"></a>
|
|
8
10
|
</p>
|
|
9
11
|
|
|
10
|
-
>
|
|
12
|
+
> **Run N conversations in DeepSeek Harness at once, watch every Agent's live progress side-by-side, and check in from your phone or tablet.** One browser tab goes from "one conversation at a time" to "a panoramic multi-conversation cockpit."
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Install a **multi-window wall** into the official [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) Web UI: a grid that shows N running DSH conversation instances simultaneously (each instance runs its own task), so every Agent's live progress, chat, and output are **visible at a glance** — no more hopping between endless tabs and windows.
|
|
13
15
|
|
|
14
|
-
## ✨
|
|
16
|
+
## ✨ What it does
|
|
15
17
|
|
|
16
|
-
|
|
|
17
|
-
|
|
18
|
-
| 📺
|
|
19
|
-
| 🔍
|
|
20
|
-
| ➕
|
|
21
|
-
| 📱
|
|
22
|
-
| 🛑
|
|
18
|
+
| Capability | Description |
|
|
19
|
+
|------------|-------------|
|
|
20
|
+
| 📺 **Multi-window** | One-click entry from the sidebar; the chat area becomes a window grid showing every task side-by-side, one pane per port |
|
|
21
|
+
| 🔍 **Auto-discovery** | Scans a port range to auto-find running DSH instances; manual management is also supported |
|
|
22
|
+
| ➕ **One-click new window** | Launch a brand-new DSH instance right inside the wall to grow your conversation matrix |
|
|
23
|
+
| 📱 **Phone access** | The "Phone access" button starts a **built-in authenticated LAN gateway** — open the URL on your phone, enter the token, and watch progress |
|
|
24
|
+
| 🛑 **Window controls** | Maximize, refresh, open in a new tab, stop an instance, and switch column count (auto/1/2/3/4/6) |
|
|
23
25
|
|
|
24
|
-
>
|
|
26
|
+
> **Multi-chat = multi-port.** Start N `dsh web --port <n>` instances (each running one conversation/task), open the wall from any of them, and you see all of them side-by-side.
|
|
25
27
|
|
|
26
|
-
## 📸
|
|
28
|
+
## 📸 Screenshots
|
|
27
29
|
|
|
28
|
-
**🖥️ Windows ·
|
|
30
|
+
**🖥️ Windows · Two chats side-by-side** — two running DSH instances laid out together, each pane a full official conversation UI with live online status dots and per-window controls (maximize / refresh / new tab / remove):
|
|
29
31
|
|
|
30
|
-

|
|
31
33
|
|
|
32
|
-
**📱 iPad ·
|
|
34
|
+
**📱 iPad · Two chats on mobile** — on the same LAN, open the token-authenticated gateway URL on an iPad to watch two Agents' live progress on one tablet screen:
|
|
33
35
|
|
|
34
|
-

|
|
35
37
|
|
|
36
|
-
**🖥️ Windows ·
|
|
38
|
+
**🖥️ Windows · Three-chat panorama** — a 3-column grid of three running instances, all Agents on one screen, upgrading you from "one conversation at a time" to "a panoramic multi-conversation cockpit":
|
|
37
39
|
|
|
38
|
-

|
|
39
41
|
|
|
40
|
-
## 🚀 30
|
|
42
|
+
## 🚀 30-second quick start
|
|
41
43
|
|
|
42
44
|
```bash
|
|
43
|
-
# 1.
|
|
45
|
+
# 1. Install (npm / npx, no manual patch needed)
|
|
44
46
|
npx dsh-multi-chat install
|
|
45
47
|
|
|
46
|
-
# 2.
|
|
48
|
+
# 2. Start a few instances
|
|
47
49
|
npx dsh-multi-chat start --ports 3080,3081,3082
|
|
48
50
|
|
|
49
|
-
# 3.
|
|
51
|
+
# 3. Open any instance and click "Multi-window" in the sidebar footer → done 🎉
|
|
50
52
|
```
|
|
51
53
|
|
|
52
|
-
##
|
|
54
|
+
## Why this approach
|
|
53
55
|
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
56
|
+
- **No official logic is touched**: the plugin only registers two **additive list slots** (`conversation.view` ring entry, `sidebar.footer.action` sidebar shortcut) and five read-only JSON routes (`/multi/api/ports`, `/multi/api/status`, `/multi/api/stop`, `/multi/api/create`, `/multi/api/link`). No existing slot is replaced, no line is rewritten, and no core session/agent/tool logic is touched.
|
|
57
|
+
- **The UI is the official UI**: the wall is a view in the official view ring rendered inside the chat panel (not a popup). Theme, type scale, icons, and controls all use the official `--dsw-*` tokens and official primitives (Button/Input/Menu/StateDot).
|
|
58
|
+
- **Recursion guard**: the wall never embeds its own port; embedded pages carry a `?multi-wall=embed` flag and register no wall UI, preventing infinite "wall-in-wall" recursion.
|
|
59
|
+
- **Minimal footprint**: one declarative client plugin package — it ships its own `dsh.bundle.patch` + `cordis.patch.yml`, so DSH mounts it as a bundle layer automatically.
|
|
58
60
|
|
|
59
|
-
##
|
|
61
|
+
## Directory layout
|
|
60
62
|
|
|
61
63
|
```
|
|
62
|
-
plugin/dsh-client-ui-multi-wall/ #
|
|
63
|
-
lib/ #
|
|
64
|
-
src/ #
|
|
65
|
-
patches/multi-wall.yml #
|
|
64
|
+
plugin/dsh-client-ui-multi-wall/ # spec-compliant client plugin package (node half + browser half)
|
|
65
|
+
lib/ # built artifacts (lib/index.js + lib/client.js + types)
|
|
66
|
+
src/ # source (mirrors the official monorepo packages/client/ui-multi-wall)
|
|
67
|
+
patches/multi-wall.yml # optional `--patch` overlay (usually not needed; the plugin auto-mounts via dsh.bundle)
|
|
66
68
|
scripts/
|
|
67
|
-
install-plugin.ps1 #
|
|
68
|
-
start-multi.ps1 / stop-multi.ps1 #
|
|
69
|
-
gateway.mjs #
|
|
70
|
-
gateway-hidden.vbs #
|
|
71
|
-
gateway-start.ps1 / gateway-stop.ps1 #
|
|
72
|
-
bin/dsh-multi-chat.mjs #
|
|
73
|
-
harness-src/ #
|
|
69
|
+
install-plugin.ps1 # pack + install into profile (DSH auto-mounts the bundle) + prompt restart
|
|
70
|
+
start-multi.ps1 / stop-multi.ps1 # start/stop multiple dsh web instances (-Remote can carry an authenticated gateway)
|
|
71
|
+
gateway.mjs # token-authenticated / optional-TLS reverse-proxy gateway (phone/remote access)
|
|
72
|
+
gateway-hidden.vbs # no-window launcher: starts gateway.mjs hidden (no console flash)
|
|
73
|
+
gateway-start.ps1 / gateway-stop.ps1 # one-shot silent start/stop of the gateway
|
|
74
|
+
bin/dsh-multi-chat.mjs # cross-platform npx CLI (install/start/stop/gateway)
|
|
75
|
+
harness-src/ # official deepseek-harness source (dev/build reference)
|
|
74
76
|
```
|
|
75
77
|
|
|
76
|
-
##
|
|
78
|
+
## Install & enable (Windows)
|
|
77
79
|
|
|
78
80
|
```powershell
|
|
79
|
-
# 1)
|
|
81
|
+
# 1) Pack and install into the web profile. The plugin declares dsh.bundle.patch,
|
|
82
|
+
# so DSH auto-mounts its bundle layer — no manual patch edit.
|
|
80
83
|
.\scripts\install-plugin.ps1
|
|
81
84
|
|
|
82
|
-
# 2)
|
|
85
|
+
# 2) Restart dsh web and open any instance
|
|
83
86
|
dsh web --port 3084
|
|
84
|
-
#
|
|
87
|
+
# Browser: http://127.0.0.1:3084 — a "Multi-window" button appears in the sidebar footer
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or manual:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cd plugin/dsh-client-ui-multi-wall && npm pack # produce a tarball
|
|
94
|
+
dsh plugin --profile web add <tarball> # DSH adds the package to the bundle layer stack automatically
|
|
85
95
|
```
|
|
86
96
|
|
|
87
|
-
|
|
97
|
+
Uninstall (one command, nothing manual to clean up):
|
|
88
98
|
|
|
89
99
|
```bash
|
|
90
|
-
|
|
91
|
-
dsh plugin --profile web add <tarball> # 装进 profile
|
|
92
|
-
# 把 patches/multi-wall.yml 的 insert 行加进 ~/.dsh/profiles/web/cordis.patch.yml
|
|
100
|
+
dsh plugin --profile web remove @deepseek-ai/dsh-client-ui-multi-wall
|
|
93
101
|
```
|
|
94
102
|
|
|
95
|
-
##
|
|
103
|
+
## Usage
|
|
96
104
|
|
|
97
|
-
1.
|
|
98
|
-
2.
|
|
99
|
-
3.
|
|
100
|
-
4.
|
|
105
|
+
1. Start several instances: `.\scripts\start-multi.ps1 -Ports "3080,3081,3082,3084"` (or manual `dsh web --port <n>`).
|
|
106
|
+
2. Open any instance and click the "Multi-window" shortcut in the sidebar footer (or the "Multi-window" tab at the top of the chat area).
|
|
107
|
+
3. Inside the wall view: auto-discovery (own port excluded), column switching (auto/1/2/3/4/6, horizontally filled by default), click title to maximize, ⟳ refresh one, ↗ open in a new tab, ✕ remove from view, refresh all, and live online status dots. The layout is persisted to `localStorage`.
|
|
108
|
+
4. To exit the wall, click the **"Exit" button in the toolbar's top-right** to switch back to the chat view in one click.
|
|
101
109
|
|
|
102
|
-
##
|
|
110
|
+
## Phone / remote access (built-in authenticated gateway)
|
|
103
111
|
|
|
104
|
-
|
|
112
|
+
The official `dsh web` **deliberately forbids `--host 0.0.0.0`** (it would expose remote code execution to the network). This plugin ships a built-in **token-authenticated intranet gateway**: click the "Phone access" button and it **automatically** starts a gateway for the current instance (listening on `0.0.0.0`, reverse-proxying to `127.0.0.1:<this instance's port>`), returning a LAN URL + login token.
|
|
105
113
|
|
|
106
114
|
```text
|
|
107
|
-
|
|
108
|
-
|
|
115
|
+
Click "Phone access" → you get:
|
|
116
|
+
Available on your phone on the same network: http://10.105.7.204:9477 token: 2efb23eade16
|
|
109
117
|
```
|
|
110
118
|
|
|
111
|
-
|
|
119
|
+
Open that URL on your phone and enter the token to reach the full DSH UI. The gateway's security model:
|
|
112
120
|
|
|
113
|
-
- HMAC
|
|
114
|
-
-
|
|
115
|
-
- WebSocket
|
|
116
|
-
-
|
|
121
|
+
- HMAC-signed HttpOnly/SameSite session cookie (12h default), `?token=` for script convenience, per-IP rate limiting on failed logins
|
|
122
|
+
- All proxied requests rewrite Host/Origin to the loopback target, so the official `/api` browser-trust fence (the DNS-rebinding defense) treats it as a local request — no restart / `--trusted-host` needed
|
|
123
|
+
- WebSocket upgrades and SSE streams pass through unchanged
|
|
124
|
+
- When the intended port hits a Windows excluded range or is already bound, it automatically falls back to an OS-assigned free port
|
|
117
125
|
|
|
118
|
-
>
|
|
126
|
+
> A standalone `scripts/gateway.mjs` (with optional TLS) is also available for advanced manual use.
|
|
119
127
|
|
|
120
|
-
##
|
|
128
|
+
## Distribution & install
|
|
121
129
|
|
|
122
|
-
|
|
130
|
+
The repo bundles a cross-platform CLI, `dsh-multi-chat` (`bin/dsh-multi-chat.mjs`), installable through any of the three channels below. Its `install` command probes `$DSH_HOME` (default `~/.dsh`) and idempotently appends the enable patch (same behavior as `install-plugin.ps1`).
|
|
123
131
|
|
|
124
|
-
###
|
|
132
|
+
### Channel 1: npm / npx (recommended, easiest)
|
|
125
133
|
|
|
126
134
|
```bash
|
|
127
|
-
#
|
|
135
|
+
# After publishing to npm, one line installs on any machine
|
|
128
136
|
npx dsh-multi-chat install
|
|
129
137
|
|
|
130
|
-
#
|
|
131
|
-
npx dsh-multi-chat start --remote --token
|
|
132
|
-
npx dsh-multi-chat gateway --target 127.0.0.1:3080 --token
|
|
138
|
+
# Or run a single command straight from npx (no install needed)
|
|
139
|
+
npx dsh-multi-chat start --remote --token <token> --ports 3080,3081
|
|
140
|
+
npx dsh-multi-chat gateway --target 127.0.0.1:3080 --token <token>
|
|
133
141
|
```
|
|
134
142
|
|
|
135
|
-
|
|
143
|
+
Publishing (maintainer): `npm publish` (unscoped public package `dsh-multi-chat`).
|
|
136
144
|
|
|
137
|
-
###
|
|
145
|
+
### Channel 2: GitHub Release
|
|
138
146
|
|
|
139
|
-
|
|
147
|
+
Download the source zip/tarball from [Releases](https://github.com/daetz-coder/dsh-multi-chat/releases), unpack it, and cd in:
|
|
140
148
|
|
|
141
149
|
```bash
|
|
142
|
-
node bin/dsh-multi-chat.mjs install #
|
|
150
|
+
node bin/dsh-multi-chat.mjs install # pack + dsh plugin add + append enable patch
|
|
143
151
|
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
144
152
|
```
|
|
145
153
|
|
|
146
|
-
>
|
|
154
|
+
> Tagging a release makes GitHub auto-generate the source zip/tarball assets; you can also attach a `npm pack`-produced `.tgz` as an offline install bundle.
|
|
147
155
|
|
|
148
|
-
###
|
|
156
|
+
### Channel 3: direct git install
|
|
149
157
|
|
|
150
158
|
```bash
|
|
151
159
|
git clone https://github.com/daetz-coder/dsh-multi-chat.git
|
|
152
160
|
cd dsh-multi-chat
|
|
153
161
|
|
|
154
|
-
node bin/dsh-multi-chat.mjs install #
|
|
162
|
+
node bin/dsh-multi-chat.mjs install # install the plugin
|
|
155
163
|
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
156
|
-
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token
|
|
164
|
+
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token <token>
|
|
157
165
|
```
|
|
158
166
|
|
|
159
|
-
###
|
|
167
|
+
### Running straight from this repo (development)
|
|
160
168
|
|
|
161
169
|
```bash
|
|
162
170
|
node bin/dsh-multi-chat.mjs install
|
|
163
171
|
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
164
172
|
node bin/dsh-multi-chat.mjs stop
|
|
165
|
-
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token
|
|
173
|
+
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token <token>
|
|
166
174
|
```
|
|
167
175
|
|
|
168
|
-
## 🔍
|
|
176
|
+
## 🔍 Discovery & ecosystem
|
|
169
177
|
|
|
170
|
-
|
|
178
|
+
This plugin follows the official [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) client plugin spec:
|
|
171
179
|
|
|
172
|
-
-
|
|
173
|
-
-
|
|
174
|
-
-
|
|
180
|
+
- **Be found in the GitHub plugin ecosystem**: adding the [`dsh-plugin`](https://github.com/topics/dsh-plugin) topic to this repo makes it searchable on the official [`dsh-plugin` topic page](https://github.com/topics/dsh-plugin) (the officially recommended third-party discovery path).
|
|
181
|
+
- **Bilingual technical docs**: under `plugin/dsh-client-ui-multi-wall/` there is `README.md` (English), `README.zh.md` (Chinese), and `README.i18n.yaml` (bilingual consistency record), matching the structure of official `packages/client/*` plugins.
|
|
182
|
+
- **Purely additive, no core touching**: registers only the `conversation.view` / `sidebar.footer.action` list slots + `/multi/api/*` read-only routes, changing no official core logic.
|
|
175
183
|
|
|
176
|
-
##
|
|
184
|
+
## Where it lives in the official monorepo
|
|
177
185
|
|
|
178
|
-
`packages/client/ui-multi-wall`
|
|
186
|
+
`packages/client/ui-multi-wall` is a spec-compliant client plugin package (separate host/client tsconfig, tsdown clientBundle, zh/en locales, invariant companion, HMR-safe tests) wired into `packages/bundle/web-app`'s dsh.client roster and the `tsconfig.client.json` aggregate. To build:
|
|
179
187
|
|
|
180
188
|
```bash
|
|
181
189
|
cd harness-src
|
|
182
190
|
pnpm install
|
|
183
|
-
pnpm --filter @deepseek-ai/dsh-client-ui-multi-wall bundle #
|
|
184
|
-
npx vitest run packages/client/ui-multi-wall # 14
|
|
191
|
+
pnpm --filter @deepseek-ai/dsh-client-ui-multi-wall bundle # produces lib/client.js
|
|
192
|
+
npx vitest run packages/client/ui-multi-wall # 14 tests
|
|
185
193
|
```
|
|
186
194
|
|
|
187
195
|
## License
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
# 💬 dsh-multi-chat —— 多对话,一屏驾驭
|
|
2
|
+
|
|
3
|
+
[English](README.md) | **中文**
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://www.npmjs.com/package/dsh-multi-chat"><img src="https://img.shields.io/npm/v/dsh-multi-chat" alt="npm version"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/dsh-multi-chat"><img src="https://img.shields.io/npm/dm/dsh-multi-chat" alt="npm downloads"></a>
|
|
8
|
+
<a href="https://github.com/daetz-coder/dsh-multi-chat/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue" alt="license"></a>
|
|
9
|
+
<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/dsh--plugin-community-brightgreen" alt="dsh-plugin"></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
> **在 DeepSeek Harness 里同时开 N 个对话,并排盯住每一个 Agent 的实时进度,还能用手机/平板躺着看。** 一个浏览器,从「一次一个对话」升级成「全景多对话驾驶舱」。
|
|
13
|
+
|
|
14
|
+
给 [DeepSeek Harness (DSH)](https://github.com/deepseek-ai/deepseek-harness) 官方 Web 界面装上一面**多窗口墙**:在一张网格里同时显示 N 个正在运行的 DSH 对话实例(每个实例独立跑一个任务),所有 Agent 的实时进度、对话、输出**一眼尽收**,不用在无数标签页/窗口之间切来切去。
|
|
15
|
+
|
|
16
|
+
## ✨ 它能做什么
|
|
17
|
+
|
|
18
|
+
| 能力 | 说明 |
|
|
19
|
+
|------|------|
|
|
20
|
+
| 📺 **多窗口** | 侧边栏一键进入,右侧对话区原位变成窗口网格,一个端口一格,并排看全部任务 |
|
|
21
|
+
| 🔍 **自动发现** | 扫描端口区间自动发现正在运行的 DSH 实例,也可手动管理 |
|
|
22
|
+
| ➕ **一键新建窗口** | 墙内直接启动全新 DSH 实例,凑成你的多对话矩阵 |
|
|
23
|
+
| 📱 **手机访问** | 点「手机访问」自动起一个**内置带口令认证的局域网网关**,手机打开 URL、输入口令即可看进度 |
|
|
24
|
+
| 🛑 **窗口控制** | 单窗口放大、刷新、新标签页打开、关闭实例、列数切换(自动/1/2/3/4/6)|
|
|
25
|
+
|
|
26
|
+
> **多对话 = 多端口。** 启动 N 个 `dsh web --port <n>`,每个实例独立跑一个对话/任务;在任意一个实例里打开多窗口墙,即可并排看到全部。
|
|
27
|
+
|
|
28
|
+
## 📸 运行效果
|
|
29
|
+
|
|
30
|
+
**🖥️ Windows · 双对话并排** —— 两个正在运行的 DSH 实例并排列出,每格都是完整的官方对话界面,带实时在线状态点与单窗控制(放大 / 刷新 / 新标签页 / 移除):
|
|
31
|
+
|
|
32
|
+

|
|
33
|
+
|
|
34
|
+
**📱 iPad · 双对话移动端** —— 同一局域网内,iPad 打开带口令认证的网关地址,即可在平板上一屏并排盯住两个 Agent 的实时进度:
|
|
35
|
+
|
|
36
|
+

|
|
37
|
+
|
|
38
|
+
**🖥️ Windows · 三对话全景** —— 3 列网格并排显示 3 个正在运行的实例,一屏尽收全部 Agent,把「一次一个对话」升级成「全景多对话驾驶舱」:
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
## 🚀 30 秒上手
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# 1. 安装(npm / npx,免手工打包补丁)
|
|
46
|
+
npx dsh-multi-chat install
|
|
47
|
+
|
|
48
|
+
# 2. 启动几个实例
|
|
49
|
+
npx dsh-multi-chat start --ports 3080,3081,3082
|
|
50
|
+
|
|
51
|
+
# 3. 打开任意实例,点侧边栏底部「多窗口」→ 完成 🎉
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 为什么这样做
|
|
55
|
+
|
|
56
|
+
- **不改动任何官方逻辑**:插件只注册两个**增量列表槽位**(`conversation.view` 视图环条目、`sidebar.footer.action` 侧边栏快捷入口)和五个只读 JSON 路由(`/multi/api/ports`、`/multi/api/status`、`/multi/api/stop`、`/multi/api/create`、`/multi/api/link`)。不替换任何既有槽位、不改写任何行、不触碰会话/代理/工具等核心逻辑。
|
|
57
|
+
- **界面就是官方界面**:墙是官方视图环的一个视图,渲染在对话主面板内(不是弹层),主题、字号、图标、控件全部走官方 `--dsw-*` token 与官方 primitives(Button/Input/Menu/StateDot)。
|
|
58
|
+
- **递归防护**:墙永远不嵌入自身端口;被嵌入页面带 `?multi-wall=embed` 标记,不注册任何墙界面,杜绝「墙中墙」无限递归。
|
|
59
|
+
- **最小改动**:一个声明式 client 插件包 —— 包内自带 `dsh.bundle.patch` + `cordis.patch.yml`,DSH 启动时自动作为 bundle 层挂载,无需手改任何文件。
|
|
60
|
+
|
|
61
|
+
## 目录结构
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
plugin/dsh-client-ui-multi-wall/ # 官方规范 client 插件包(node half + browser half)
|
|
65
|
+
lib/ # 已构建产物(lib/index.js + lib/client.js + 类型)
|
|
66
|
+
src/ # 源码(与官方 monorepo packages/client/ui-multi-wall 一致)
|
|
67
|
+
patches/multi-wall.yml # 可选 `--patch` overlay(通常不需要;插件经 dsh.bundle 自动挂载)
|
|
68
|
+
scripts/
|
|
69
|
+
install-plugin.ps1 # 打包 + 装进 profile(DSH 自动挂载 bundle 层)+ 提示重启
|
|
70
|
+
start-multi.ps1 / stop-multi.ps1 # 启停多个 dsh web 实例(-Remote 可带认证网关)
|
|
71
|
+
gateway.mjs # 带令牌认证 / 可选 TLS 的反向代理网关(手机/远程访问)
|
|
72
|
+
gateway-hidden.vbs # 无窗口启动器:用隐藏窗口方式启动 gateway.mjs(不弹控制台)
|
|
73
|
+
gateway-start.ps1 / gateway-stop.ps1 # 一键静默启动/停止网关
|
|
74
|
+
bin/dsh-multi-chat.mjs # 跨平台 npx CLI(install/start/stop/gateway)
|
|
75
|
+
harness-src/ # 官方 deepseek-harness 源码(开发/构建用)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## 安装与启用(Windows)
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
# 1) 打包并装进 web profile。插件声明了 dsh.bundle.patch,
|
|
82
|
+
# DSH 会自动挂载其 bundle 层 —— 无需手改 patch。
|
|
83
|
+
.\scripts\install-plugin.ps1
|
|
84
|
+
|
|
85
|
+
# 2) 重启 dsh web,打开任意实例
|
|
86
|
+
dsh web --port 3084
|
|
87
|
+
# 浏览器打开 http://127.0.0.1:3084 ,侧边栏底部出现「多窗口」按钮
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
或手动:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cd plugin/dsh-client-ui-multi-wall && npm pack # 得到 tarball
|
|
94
|
+
dsh plugin --profile web add <tarball> # DSH 自动把包加入 bundle 层栈
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
卸载(一条命令,无需手动清理任何文件):
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
dsh plugin --profile web remove @deepseek-ai/dsh-client-ui-multi-wall
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## 使用
|
|
104
|
+
|
|
105
|
+
1. 先启动若干实例:`.\scripts\start-multi.ps1 -Ports "3080,3081,3082,3084"`(或手动 `dsh web --port <n>`)。
|
|
106
|
+
2. 打开任意实例,点侧边栏底部的「多窗口」快捷入口(或点对话区头部的「多窗口」标签页)。
|
|
107
|
+
3. 墙视图内:自动发现实例(自动排除自身端口)、列数切换(自动/1/2/3/4/6,默认横向铺满)、点标题放大、⟳ 单独刷新、↗ 新标签页打开、✕ 从视图移除、全部刷新、实时在线状态点。布局保存在 localStorage。
|
|
108
|
+
4. 退出墙:点工具栏**右上角的「退出」按钮**,一键切回对话视图。
|
|
109
|
+
|
|
110
|
+
## 手机 / 远程访问(内置认证网关)
|
|
111
|
+
|
|
112
|
+
官方 `dsh web` 出于安全**刻意禁止 `--host 0.0.0.0`**(会向网络暴露远程代码执行)。本插件内置了一个**带令牌认证的内联网关**:点工具栏「手机访问」按钮,它会**自动**为本实例启动一个网关(监听 `0.0.0.0`,反向代理到 `127.0.0.1:<本实例端口>`),并返回局域网 URL + 登录口令。
|
|
113
|
+
|
|
114
|
+
```text
|
|
115
|
+
点击「手机访问」→ 得到:
|
|
116
|
+
手机在同一网络时可用:http://10.105.7.204:9477 口令:2efb23eade16
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
手机打开该 URL、输入口令即可进入完整 DSH 界面。网关的安全模型:
|
|
120
|
+
|
|
121
|
+
- HMAC 签名的 HttpOnly/SameSite 会话 Cookie(默认 12h),`?token=` 供脚本快捷使用,按 IP 限流登录失败
|
|
122
|
+
- 所有代理请求把 Host/Origin 重写为回环目标,官方 `/api` 浏览器信任栅栏(DNS-rebinding 防线)判定为本地请求,无需重启加 `--trusted-host`
|
|
123
|
+
- WebSocket 升级与 SSE 流原样透传
|
|
124
|
+
- 目标端口撞上 Windows 排除段或已占用时,自动回退到 OS 分配的空闲端口
|
|
125
|
+
|
|
126
|
+
> 也有独立的 `scripts/gateway.mjs`(带可选 TLS)供进阶场景手动使用。
|
|
127
|
+
|
|
128
|
+
## 分发与安装
|
|
129
|
+
|
|
130
|
+
仓库内置跨平台 CLI `dsh-multi-chat`(`bin/dsh-multi-chat.mjs`),下面三种渠道都可安装。CLI 的 `install` 会探测 `$DSH_HOME`(缺省 `~/.dsh`)并幂等地追加启用 patch(与 `install-plugin.ps1` 行为一致)。
|
|
131
|
+
|
|
132
|
+
### 渠道一:npm / npx(推荐,最省事)
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
# 发布到 npm 后,任意机器一句话安装
|
|
136
|
+
npx dsh-multi-chat install
|
|
137
|
+
|
|
138
|
+
# 或直接 npx 跑单条命令(无需安装)
|
|
139
|
+
npx dsh-multi-chat start --remote --token <口令> --ports 3080,3081
|
|
140
|
+
npx dsh-multi-chat gateway --target 127.0.0.1:3080 --token <口令>
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
维护者发布:`npm publish`(无作用域公开包 `dsh-multi-chat`)。
|
|
144
|
+
|
|
145
|
+
### 渠道二:GitHub Release
|
|
146
|
+
|
|
147
|
+
从 [Releases](https://github.com/daetz-coder/dsh-multi-chat/releases) 下载源码 zip/tarball,解压后进目录:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
node bin/dsh-multi-chat.mjs install # 打包 + dsh plugin add + 追加启用 patch
|
|
151
|
+
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
> 打 tag 后,GitHub 会自动生成 source zip/tarball 资产;也可在 Release 附加 `npm pack` 产出的 `.tgz` 作为离线安装包。
|
|
155
|
+
|
|
156
|
+
### 渠道三:git 直接安装
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
git clone https://github.com/daetz-coder/dsh-multi-chat.git
|
|
160
|
+
cd dsh-multi-chat
|
|
161
|
+
|
|
162
|
+
node bin/dsh-multi-chat.mjs install # 装插件
|
|
163
|
+
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
164
|
+
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token <口令>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### 本仓库直接运行(开发)
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
node bin/dsh-multi-chat.mjs install
|
|
171
|
+
node bin/dsh-multi-chat.mjs start --ports 3080,3081
|
|
172
|
+
node bin/dsh-multi-chat.mjs stop
|
|
173
|
+
node bin/dsh-multi-chat.mjs gateway --target 127.0.0.1:3080 --token <口令>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## 🔍 发现与生态
|
|
177
|
+
|
|
178
|
+
本插件遵循 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 官方 client 插件规范:
|
|
179
|
+
|
|
180
|
+
- **在 GitHub 插件生态中被发现**:给本仓库添加 [`dsh-plugin`](https://github.com/topics/dsh-plugin) topic,即可在官方 [`dsh-plugin` topic 页](https://github.com/topics/dsh-plugin) 被搜索到(官方推荐的第三方插件发现方式)。
|
|
181
|
+
- **三语技术文档**:插件包 `plugin/dsh-client-ui-multi-wall/` 下提供 `README.md`(英文)、`README.zh.md`(中文)与 `README.i18n.yaml`(双语一致性记录),结构与官方 `packages/client/*` 插件一致。
|
|
182
|
+
- **纯增量、不碰核心**:只注册 `conversation.view` / `sidebar.footer.action` 两个列表槽位 + `/multi/api/*` 只读路由,不改动任何官方核心逻辑。
|
|
183
|
+
|
|
184
|
+
## 在官方 monorepo 中的位置
|
|
185
|
+
|
|
186
|
+
`packages/client/ui-multi-wall` 是遵循官方 client 插件规范的包(tsconfig host/client 分离、tsdown clientBundle、locales zh/en、invariant 伴随、HMR 安全测试),并已接入 `packages/bundle/web-app` 的 dsh.client roster 与 `tsconfig.client.json` 聚合。构建:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cd harness-src
|
|
190
|
+
pnpm install
|
|
191
|
+
pnpm --filter @deepseek-ai/dsh-client-ui-multi-wall bundle # 产出 lib/client.js
|
|
192
|
+
npx vitest run packages/client/ui-multi-wall # 14 项测试
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## License
|
|
196
|
+
|
|
197
|
+
MIT
|
package/bin/dsh-multi-chat.mjs
CHANGED
|
@@ -123,10 +123,11 @@ const INSTALL_HELP = `dsh-multi-chat install — install the multi-window wall p
|
|
|
123
123
|
Usage:
|
|
124
124
|
dsh-multi-chat install [--profile web]
|
|
125
125
|
|
|
126
|
-
Packs plugin/dsh-client-ui-multi-wall
|
|
127
|
-
with \`dsh plugin --profile <p> add
|
|
128
|
-
|
|
129
|
-
|
|
126
|
+
Packs plugin/dsh-client-ui-multi-wall and installs the tarball into the profile
|
|
127
|
+
with \`dsh plugin --profile <p> add\`. The plugin declares \`dsh.bundle.patch\`
|
|
128
|
+
(pointing at its own cordis.patch.yml), so DSH mounts it automatically as a
|
|
129
|
+
bundle layer — no manual profile patch is needed. Restart dsh web afterwards.
|
|
130
|
+
Uninstall with: dsh plugin --profile <p> remove @deepseek-ai/dsh-client-ui-multi-wall
|
|
130
131
|
`
|
|
131
132
|
|
|
132
133
|
async function cmdInstall(args) {
|
|
@@ -151,30 +152,13 @@ async function cmdInstall(args) {
|
|
|
151
152
|
const tarball = join(stableDir, tarballName)
|
|
152
153
|
if (!existsSync(tarball)) throw new Error('npm pack produced no tarball')
|
|
153
154
|
|
|
154
|
-
// 2) install into the profile.
|
|
155
|
+
// 2) install into the profile. DSH reconciles `dsh.profile.bundles` from the
|
|
156
|
+
// installed dependency set: because this package declares `dsh.bundle.patch`,
|
|
157
|
+
// `dsh plugin add` leaves it in the bundle layer stack and its own
|
|
158
|
+
// cordis.patch.yml is mounted automatically — no manual profile patch edits.
|
|
155
159
|
process.stdout.write(`installing ${tarballName} into profile '${profile}'…\n`)
|
|
156
160
|
run('dsh', ['plugin', '--profile', profile, 'add', tarball])
|
|
157
161
|
|
|
158
|
-
// 3) append the enable patch row (idempotent).
|
|
159
|
-
const patchPath = join(dshHome(), 'profiles', profile, 'cordis.patch.yml')
|
|
160
|
-
const insert = [
|
|
161
|
-
'',
|
|
162
|
-
'# Multi-window wall (dsh-multi-chat): enable the official client',
|
|
163
|
-
'# plugin that renders the wall inside the DSH web GUI.',
|
|
164
|
-
'- insert:',
|
|
165
|
-
' - id: ui-multi-wall',
|
|
166
|
-
" name: '@deepseek-ai/dsh-client-ui-multi-wall'",
|
|
167
|
-
'',
|
|
168
|
-
].join('\n')
|
|
169
|
-
let content = ''
|
|
170
|
-
if (existsSync(patchPath)) content = readFileSync(patchPath, 'utf8')
|
|
171
|
-
if (!content.includes('ui-multi-wall')) {
|
|
172
|
-
writeFileSync(patchPath, content.trimEnd() + '\n' + insert, 'utf8')
|
|
173
|
-
process.stdout.write(`patched ${patchPath}\n`)
|
|
174
|
-
} else {
|
|
175
|
-
process.stdout.write(`profile patch already enables ui-multi-wall (${patchPath})\n`)
|
|
176
|
-
}
|
|
177
|
-
|
|
178
162
|
process.stdout.write('\nDone. Restart dsh web to load the wall:\n')
|
|
179
163
|
process.stdout.write(' dsh web --port <n>\n')
|
|
180
164
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-multi-chat",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.5",
|
|
4
4
|
"description": "DSH 多对话:在官方 DeepSeek Harness Web 界面里以多窗口网格并排运行、监控多个对话实例,一屏盯住所有 Agent 的实时进度;内置带口令认证的局域网网关,手机/平板也能看。npx dsh-multi-chat install|start|stop|gateway",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -66,8 +66,12 @@
|
|
|
66
66
|
"patches/",
|
|
67
67
|
"assets/",
|
|
68
68
|
"cordis.patch.yml",
|
|
69
|
+
"README.md",
|
|
70
|
+
"README.zh.md",
|
|
69
71
|
"plugin/dsh-client-ui-multi-wall/package.json",
|
|
70
72
|
"plugin/dsh-client-ui-multi-wall/README.md",
|
|
73
|
+
"plugin/dsh-client-ui-multi-wall/README.zh.md",
|
|
74
|
+
"plugin/dsh-client-ui-multi-wall/cordis.patch.yml",
|
|
71
75
|
"plugin/dsh-client-ui-multi-wall/lib/index.js",
|
|
72
76
|
"plugin/dsh-client-ui-multi-wall/lib/invariant.js",
|
|
73
77
|
"plugin/dsh-client-ui-multi-wall/lib/client.js",
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# @deepseek-ai/dsh-client-ui-multi-wall
|
|
2
|
+
|
|
3
|
+
[English](README.md) | 中文
|
|
4
|
+
|
|
5
|
+
多窗口墙插件(浏览器端 + 服务端):把每一个正在运行的 DSH 实例铺成一张网格,一个窗口对应一个 `127.0.0.1:<port>`,作为增量 `conversation.view` 视图环条目(order 20)渲染在官方 Web 界面内。该视图将对话区原位替换为一张 iframe 墙,每个 iframe 加载带 `?multi-wall=embed` 标记的原版 DSH Web UI,该标记会在被嵌入页面内抑制墙界面——从根上杜绝「墙中墙」无限递归。侧边栏底部新增 `sidebar.footer.action` 快捷入口(order 10),点击后触发头部本插件的视图环标签页,从而经官方视图环状态机完成切换,而非直接读写对话 store。
|
|
6
|
+
|
|
7
|
+
墙的业务状态只有一个 store(`dsh.multi-wall`):已发现的端口列表与网格列数,跨视图切换与重载均可持久化。发现、探活、新建与关闭全部经服务端只读 JSON 路由完成——`/multi/api/ports`(自动发现,不排除任何端口,因此服务实例自身也可被监视)、`/multi/api/status`(指定端口列表的存活探活)、`/multi/api/stop`(终止所选实例)、`/multi/api/create`(启动全新实例,失败时回传子进程 stderr 等真实原因)、以及 `/multi/api/link`(手机访问)。
|
|
8
|
+
|
|
9
|
+
手机/远程访问:官方 CLI 出于安全禁止 `--host 0.0.0.0`(会暴露远程代码执行),因此 `/multi/api/link` 会懒启动一个**内联带令牌认证的网关**(基于 `node:net` 的反向代理,HMAC 签名的会话 Cookie 登录,目标为 `127.0.0.1:<self-port>`,重写 Host/Origin 使官方 `/api` 浏览器信任栅栏判定为本地请求,并原样透传 WebSocket 升级)。该路由返回局域网 URL 与登录口令;返回的地址会过滤掉虚拟网卡(VMware/VirtualBox/WSL/Docker/Hyper-V/VPN 等,手机无法直达),并把物理网卡(Wi-Fi/以太网)排在最前。当目标端口落入 Windows 排除段或已被占用时,网关自动回退到 OS 分配的端口。
|
|
10
|
+
|
|
11
|
+
`/client` 导出接口包括插件本体(`apply`/`inject`)、`WallView`/`WallToggle` 组件、墙 store 工厂,以及注入的探活面类型。
|
|
12
|
+
|
|
13
|
+
## 模型体验
|
|
14
|
+
|
|
15
|
+
无影响。本插件不添加任何提示词内容、不产生会话事件、不注入任何模型可见输入;墙、其 store 以及所有 `/multi/api/*` 路由都只是 UI/发现面。无 token 或 KV-cache 影响。
|
|
16
|
+
|
|
17
|
+
#### KV Cache 影响
|
|
18
|
+
|
|
19
|
+
无影响。本插件拥有的任何内容都不会进入历史尾部或模型上下文。
|
|
20
|
+
|
|
21
|
+
## 已知限制与暂缓事项
|
|
22
|
+
|
|
23
|
+
- **仅回环窗口**——墙内嵌 `127.0.0.1:<port>` 并探测回环地址;绑定到非回环主机的实例需在外部自行配置。
|
|
24
|
+
- **探活仅做标记检查**——存活判定只检查所服务页面的 index 是否含 `__DSH_BOOT__`;同端口被非 DSH 服务占用会误报为「未发现」。
|
|
25
|
+
- **会话作用域视图**——墙是 `conversation.view` 视图环条目,故仅在存在活跃会话时渲染。
|
|
26
|
+
- **内联网关为明文 HTTP**——受信任的局域网内明文输送口令可接受;跨公网时优先使用 `publicUrl`(外部 TLS 网关)或 VPN。
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# dsh-client-ui-multi-wall bundle patch — append the multi-window wall loader
|
|
2
|
+
# entry to the profile's root entry list. As a `dsh.bundle` layer this patch is
|
|
3
|
+
# applied automatically by DSH when the package is installed into a profile
|
|
4
|
+
# (`dsh plugin --profile web add <pkg>`); no manual profile patch is required.
|
|
5
|
+
- insert:
|
|
6
|
+
- id: ui-multi-wall
|
|
7
|
+
name: '@deepseek-ai/dsh-client-ui-multi-wall'
|
|
@@ -30,6 +30,9 @@
|
|
|
30
30
|
"./package.json": "./package.json"
|
|
31
31
|
},
|
|
32
32
|
"dsh": {
|
|
33
|
+
"bundle": {
|
|
34
|
+
"patch": "./cordis.patch.yml"
|
|
35
|
+
},
|
|
33
36
|
"client": {
|
|
34
37
|
"inject": [
|
|
35
38
|
"@deepseek-ai/dsh-client-runtime",
|
|
@@ -79,6 +82,7 @@
|
|
|
79
82
|
"lib/index.js",
|
|
80
83
|
"lib/invariant.js",
|
|
81
84
|
"lib/client.js",
|
|
82
|
-
"lib/types/**/*.d.ts"
|
|
85
|
+
"lib/types/**/*.d.ts",
|
|
86
|
+
"cordis.patch.yml"
|
|
83
87
|
]
|
|
84
88
|
}
|
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
#requires -Version 5.1
|
|
2
2
|
<#
|
|
3
3
|
.SYNOPSIS
|
|
4
|
-
把多窗口墙插件装进 DSH web profile
|
|
4
|
+
把多窗口墙插件装进 DSH web profile 并启用(官方声明式 bundle 形态)。
|
|
5
5
|
|
|
6
6
|
.DESCRIPTION
|
|
7
7
|
1) 将 plugin/dsh-client-ui-multi-wall 打包为 tarball;
|
|
8
8
|
2) 用 `dsh plugin --profile web add` 装进 profile;
|
|
9
|
-
3)
|
|
10
|
-
|
|
9
|
+
3) DSH 自动调和 dsh.profile.bundles:插件包声明了 dsh.bundle.patch
|
|
10
|
+
(指向包内自带 cordis.patch.yml),DSH 启动时自动挂载该 bundle 层,
|
|
11
|
+
无需手动编辑 profile 的 cordis.patch.yml;
|
|
11
12
|
4) 提示重启 `dsh web` 生效(打开 http://127.0.0.1:<port> 后,
|
|
12
13
|
侧边栏底部会出现「多窗口墙」按钮)。
|
|
13
14
|
|
|
15
|
+
卸载(一条命令,无需手动删 patch 或文件):
|
|
16
|
+
dsh plugin --profile <Profile> remove @deepseek-ai/dsh-client-ui-multi-wall
|
|
17
|
+
|
|
14
18
|
.PARAMETER Profile
|
|
15
19
|
profile 名,默认 web。
|
|
16
20
|
|
|
@@ -24,10 +28,8 @@ param(
|
|
|
24
28
|
$ErrorActionPreference = "Stop"
|
|
25
29
|
$root = Split-Path -Parent $PSScriptRoot
|
|
26
30
|
$pluginDir = Join-Path $root "plugin\dsh-client-ui-multi-wall"
|
|
27
|
-
$patchFile = Join-Path $root "patches\multi-wall.yml"
|
|
28
31
|
|
|
29
32
|
if (-not (Test-Path $pluginDir)) { throw "未找到插件目录:$pluginDir" }
|
|
30
|
-
if (-not (Test-Path $patchFile)) { throw "未找到 patch 文件:$patchFile" }
|
|
31
33
|
|
|
32
34
|
# 1) pack tarball
|
|
33
35
|
$tarball = Join-Path $root "dsh-client-ui-multi-wall.tgz"
|
|
@@ -37,29 +39,14 @@ Pop-Location
|
|
|
37
39
|
if (-not (Test-Path $tarball)) { throw "npm pack 失败,未生成 $tarball" }
|
|
38
40
|
Write-Host "已打包:$tarball"
|
|
39
41
|
|
|
40
|
-
# 2) install into profile
|
|
42
|
+
# 2) install into profile — DSH 依据插件的 dsh.bundle 声明自动把包加入
|
|
43
|
+
# dsh.profile.bundles 层栈并挂载其自带 cordis.patch.yml,无需手改 patch。
|
|
41
44
|
Write-Host "安装到 profile '$Profile'(等价于 pnpm add <tarball>)…"
|
|
42
45
|
dsh plugin --profile $Profile add $tarball
|
|
43
46
|
if ($LASTEXITCODE -ne 0) { throw "dsh plugin add 失败(exit $LASTEXITCODE)" }
|
|
44
47
|
|
|
45
|
-
# 3) append the insert row to the profile patch (idempotent)
|
|
46
|
-
$home = $env:DSH_HOME
|
|
47
|
-
if ([string]::IsNullOrEmpty($home)) { $home = Join-Path $env:USERPROFILE ".dsh" }
|
|
48
|
-
$profilePatch = Join-Path $home "profiles\$Profile\cordis.patch.yml"
|
|
49
|
-
if (-not (Test-Path $profilePatch)) { throw "未找到 profile patch:$profilePatch" }
|
|
50
|
-
$content = Get-Content $profilePatch -Raw
|
|
51
|
-
if ($content -notmatch "ui-multi-wall") {
|
|
52
|
-
$insert = Get-Content $patchFile -Raw
|
|
53
|
-
# 把 patch 文件的 insert 块合并进 profile patch(去掉头部注释,保留 YAML 列表语义)
|
|
54
|
-
$insertBlock = ($insert -split "`n" | Where-Object { $_ -notmatch "^\s*#" -and $_.Trim() -ne "" }) -join "`n"
|
|
55
|
-
$newContent = $content.TrimEnd() + "`n" + $insertBlock + "`n"
|
|
56
|
-
Set-Content -Path $profilePatch -Value $newContent -Encoding UTF8
|
|
57
|
-
Write-Host "已追加到 $profilePatch"
|
|
58
|
-
} else {
|
|
59
|
-
Write-Host "profile patch 已包含 ui-multi-wall,跳过追加。"
|
|
60
|
-
}
|
|
61
|
-
|
|
62
48
|
Write-Host ""
|
|
63
49
|
Write-Host "完成。重启 dsh web 生效:"
|
|
64
50
|
Write-Host " dsh web --port <n>"
|
|
65
51
|
Write-Host "打开后侧边栏底部应出现「多窗口墙」按钮。"
|
|
52
|
+
Write-Host "卸载:dsh plugin --profile $Profile remove @deepseek-ai/dsh-client-ui-multi-wall"
|
package/scripts/start-multi.ps1
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
#requires -Version 5.1
|
|
2
2
|
<#
|
|
3
3
|
.SYNOPSIS
|
|
4
4
|
启动多个 DSH web 实例(多窗口墙直接内嵌在官方界面里,无需独立服务器)。
|
|
@@ -19,8 +19,9 @@
|
|
|
19
19
|
默认 "3080,3081,3082,3083"。
|
|
20
20
|
|
|
21
21
|
.PARAMETER Patch
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
备用启用方式:传给 `dsh web --patch` 的 patch 文件。插件现已声明
|
|
23
|
+
dsh.bundle.patch(bundle 层自动挂载),通常无需传此参数;仅当你希望
|
|
24
|
+
以 overlay 方式临时启用时才使用。
|
|
24
25
|
|
|
25
26
|
.PARAMETER Remote
|
|
26
27
|
为每个实例启动一个带令牌认证的网关(0.0.0.0),用于手机/远程访问。
|