dsh-multiview 0.0.0-stage → 0.1.10
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 +111 -0
- package/LICENSE +21 -0
- package/README.md +88 -2
- package/README.zh.md +91 -0
- package/client.js +2250 -0
- package/cordis.patch.yml +7 -0
- package/docs/DESIGN.md +81 -0
- package/docs/RELEASE_ACCEPTANCE.md +106 -0
- package/icon.svg +8 -0
- package/index.js +5 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +65 -4
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.9 — 2026-11-07
|
|
4
|
+
|
|
5
|
+
### 基础设施
|
|
6
|
+
|
|
7
|
+
- CI 发布改为 **npm Trusted Publishing(OIDC)**:仓库不再保存任何 npm token,打 tag 即发布;本次同时是该通道的验证发布。
|
|
8
|
+
|
|
9
|
+
## 0.1.8 — 2026-11-07
|
|
10
|
+
|
|
11
|
+
### 变更
|
|
12
|
+
|
|
13
|
+
- 更新按钮图标改为两种语义状态:无更新时是「圈内向上箭头」(检查/升级),有更新可装时切换为「下载入托盘」图标,配合红点表示可安装;不再使用容易被读成「刷新」的循环箭头。
|
|
14
|
+
|
|
15
|
+
## 0.1.7 — 2026-11-07
|
|
16
|
+
|
|
17
|
+
### 修复
|
|
18
|
+
|
|
19
|
+
- **顶栏两个图标完全不显示**:MvGlyph 被当成普通函数调用(MvGlyph(path) 而不是 h(MvGlyph,{path})),组件根本没渲染成 SVG,改颜色当然没用。改为正常创建元素后图标出现。
|
|
20
|
+
- 图标前景色统一 label-primary(浅色主题近黑、深色主题近白),视图数量角标改为中性底色 + 主题边框,不再盖住图标。
|
|
21
|
+
|
|
22
|
+
## 0.1.6 — 2026-11-06
|
|
23
|
+
|
|
24
|
+
### 变更
|
|
25
|
+
|
|
26
|
+
- **点分屏按当前对话进入**:从某个对话点「分屏」时,若该对话已在某个视图里就恢复那个视图;否则新建一个以它开头的视图,不再抢占别的已保存视图。
|
|
27
|
+
- **视图就地编辑**:在当前视图里调整格数/绑定/关闭格子只更新这个视图,不会因为组合变了就多出一个新视图;只有全新组合才新建(关闭到只剩 1 格时该视图会被收起)。
|
|
28
|
+
- **选择列表标出占用**:已在其他视图里的会话在列表中置灰、不可选,并在右侧标出它所在的视图名。
|
|
29
|
+
|
|
30
|
+
### 性能
|
|
31
|
+
|
|
32
|
+
- 拖动分割线不再走 React 状态:拖动期间直接改两个格的 flex-grow,松手才提交一次比例(实测拖动中 state.ratio 保持不变、松手后落到 0.3724)。
|
|
33
|
+
- 格内对话按 sessionId memo 化:聚焦切换、拖拽、悬停只重绘框架,不重绘 transcript。
|
|
34
|
+
|
|
35
|
+
### 修复
|
|
36
|
+
|
|
37
|
+
- 顶栏图标/文字对比度不足(跟随主题 token:默认 label-secondary,悬停 label-primary);视图与更新按钮保持图标化。
|
|
38
|
+
|
|
39
|
+
## 0.1.5 — 2026-11-06
|
|
40
|
+
|
|
41
|
+
### 修复
|
|
42
|
+
|
|
43
|
+
- **格内点文件不再死胡同**:分屏是全局面板,DSH 此时不挂右栏会话面,点文件会弹「sidebarRight: no session surface is mounted」。现在格内点击文件/图片引用会**自动切到该会话的原生视图**再打开预览(消息在可视范围内时预览直接弹出,否则落到原生视图再点一次)。
|
|
44
|
+
|
|
45
|
+
### 变更
|
|
46
|
+
|
|
47
|
+
- 顶栏按钮:视图改为图标 + 数量角标,检查更新移到视图按钮右侧,两者同为 24px 图标按钮。
|
|
48
|
+
|
|
49
|
+
## 0.1.4 — 2026-11-06
|
|
50
|
+
|
|
51
|
+
### 新增
|
|
52
|
+
|
|
53
|
+
- **按工作区分组的会话列表**:列表按工作区分组(顺序跟侧栏一致,默认工作区在前),组名作为小标题;只有一个工作区时不显示标题,保持干净。
|
|
54
|
+
- 发布准备:package.json 去掉 private,补 keywords(含 dsh-plugin)、homepage、ugs、publishConfig,prepack 自动跑构建 + 自检。
|
|
55
|
+
|
|
56
|
+
## 0.1.3 — 2026-11-06
|
|
57
|
+
|
|
58
|
+
### 变更
|
|
59
|
+
|
|
60
|
+
- **会话选择列表重排**:按最近活跃时间倒序(与侧栏默认工作区的顺序一致);子对话以 ↳ 缩进跟随其主对话,父会话不可见时子对话仍按子层缩进;已归档会话一律不显示。
|
|
61
|
+
|
|
62
|
+
## 0.1.2 — 2026-11-06
|
|
63
|
+
|
|
64
|
+
### 新增
|
|
65
|
+
|
|
66
|
+
- **视图(saved splits)**:分屏里绑定两个以上会话后自动记住(名称=各格标题用 `|` 连接),顶栏「视图」下拉可一键恢复;最多保存 12 个。
|
|
67
|
+
- **检查更新**:顶栏右侧新增刷新图标。每 24h 自动检查一次(结果写 `localStorage`),失败按 1h→2h→4h…→12h 指数退避;有更新时图标带红点,点击弹确认框,确认后调用插件市场的公开更新 API v1(`/dsh-market/api/v1/updates` 启动、`/operations` 轮询)自动更新。未装市场、或当前是本地 `link:` 安装时,图标会说明原因而不是假装能更新。
|
|
68
|
+
- 所有市场请求带 20s 超时,慢注册表不会把顶栏卡在「检查中」。
|
|
69
|
+
|
|
70
|
+
### 变更
|
|
71
|
+
|
|
72
|
+
- **打开分屏不再自动挑会话**:没有历史布局时,每格显示会话列表让你选,而不是随机绑一个最近会话。
|
|
73
|
+
- **关闭一格 = 回到会话列表**:对已绑定的一格点 ✕ 会清空该格(保留分屏形状),不再把两格塌成单个会话;对已空的格再点 ✕ 才移除该格。
|
|
74
|
+
|
|
75
|
+
## 0.1.1 — 2026-11-05
|
|
76
|
+
|
|
77
|
+
### 修复
|
|
78
|
+
|
|
79
|
+
- **分割线拖拽丢帧**:拖拽监听原在 `useEffect` 里挂载,React 提交晚于 `pointerdown`,快速拖动的前几帧被丢弃(在 win11-test 真实桌面窗口里复现:120px 拖动只产生 0.7px 的效果)。改为在 `pointerdown` 内**同步**挂 window 监听,并用 ref 记录最后比例。
|
|
80
|
+
|
|
81
|
+
### 变更
|
|
82
|
+
|
|
83
|
+
- `engines.dsh` 扩为 `>=0.2.1-rc.5 <0.2.2-0 || >=0.2.2-rc.1 <0.3.0`:已在 **0.2.2-rc.1** 的真实桌面应用上验证核心链路(面板、2/3/4 格、格内流式、格内 `ask_user_question` 与作答)。
|
|
84
|
+
|
|
85
|
+
### 验证(2026-11-06)
|
|
86
|
+
|
|
87
|
+
- **格内审批**:win11-test 真实桌面(0.2.2-rc.1)新建会话 → 请求 `danger-full-access` 写系统目录 → 审批卡在格内出现 → 格内拒绝 → 目标文件未生成。
|
|
88
|
+
- **四路长流式压测**:4 格同时四路长文输出(60s 采样)p50 16.7ms / p95 50ms / 最长帧 150ms / 2 个 >50ms 长任务。平均仍近 60fps,未做降频(保持"每格都是真实 Chat")。
|
|
89
|
+
- **live profile 安装**:`plugin_manager install_bundle` 装入 desktop profile,`include:multiview` 立即 active(未重启 DSH);侧栏图标需刷新一次窗口。
|
|
90
|
+
|
|
91
|
+
## 0.1.0 — 2026-11-05
|
|
92
|
+
|
|
93
|
+
首个可发布版本。
|
|
94
|
+
|
|
95
|
+
### 新增
|
|
96
|
+
|
|
97
|
+
- 侧栏「分屏」面板:一个中央舞台同时挂载 2–4 个真实会话,每格是原生 Chat(composer、流式、工具卡、审批卡、`ask_user_question`、附件、斜杠命令、停止/排队)。
|
|
98
|
+
- 递归二分布局树 + 三种预置(左右 2 格、1 大 + 2 叠、2×2)。
|
|
99
|
+
- 分割线拖拽调整比例(0.22–0.78 夹取),格头拖拽交换会话,聚焦格最大化/还原。
|
|
100
|
+
- 每格独立的会话选择器(搜索 + 最近会话,自动排除空会话与归档会话)。
|
|
101
|
+
- 布局持久化到 `localStorage['dsh.multiview.v1']`,刷新/重启后恢复;空位保留不左移。
|
|
102
|
+
- 快捷键命令(聚焦上一/下一格、最大化、移除)并出现在「设置 → 快捷键」;桌面端带默认键,Web 端按设计不绑默认。
|
|
103
|
+
- 格级 + 面板级 React 错误边界,任何一格崩溃不影响其余格与主列。
|
|
104
|
+
- 中英文文案;`scripts/check.mjs` 发布自检(manifest/产物/文案对齐/体积/无网络与 eval)。
|
|
105
|
+
|
|
106
|
+
### 已知限制
|
|
107
|
+
|
|
108
|
+
- 格内不能用右栏的文件预览与改动评审(全局面板激活时 DSH 会卸下右栏会话面);请用格头 ↗ 回到原生视图。
|
|
109
|
+
- 格内不能新建会话、不能切换 Trajectory/插件视图。
|
|
110
|
+
- 最多 4 格;不做自动休眠。
|
|
111
|
+
- `win11-test` 真机与 desktop profile 尚未验收(见 `docs/RELEASE_ACCEPTANCE.md`)。
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Awenforever
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,89 @@
|
|
|
1
|
-
#
|
|
1
|
+
# dsh-multiview — split view for DeepSeek Harness
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> Two to four **real** conversations side by side in one window. Every pane is the shipped Chat: composer, streaming, tool cards, approval cards, `ask_user_question`, attachments, slash commands, stop/queue.
|
|
4
|
+
>
|
|
5
|
+
> The goal is not "a working split view" — it is to read as a feature the app ships with: no title-bar takeover, no layout hijacking, no monkey-patching of private extension points.
|
|
6
|
+
|
|
7
|
+
[中文](README.zh.md) | English
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Install from npm with `dsh plugin add dsh-multiview`, or search for it under **Plugins → Add** in DSH Desktop (a maintainer can also run `plugin_manager install_bundle`), then **quit and reopen** DeepSeek Harness so the client bundle loads again.
|
|
12
|
+
|
|
13
|
+
A "Split" icon appears in the left panel list; click it to turn the central column into the stage, click again to return to the native conversation.
|
|
14
|
+
|
|
15
|
+
- Requires DSH `>=0.2.1-rc.5 <0.2.2-0 || >=0.2.2-rc.1 <0.3.0` (`engines.dsh`).
|
|
16
|
+
- Uninstall: disable/remove on the Plugins page, restart. The only residue is the `localStorage['dsh.multiview.v1']` layout key (the stage's "Reset" clears it).
|
|
17
|
+
|
|
18
|
+
## Using it
|
|
19
|
+
|
|
20
|
+
| Action | How |
|
|
21
|
+
|---|---|
|
|
22
|
+
| Open / close | The "Split" icon in the sidebar panel list |
|
|
23
|
+
| 2 / 3 / 4 panes | The `2` `3` `4` chips in the stage bar |
|
|
24
|
+
| Resize | Drag the divider between panes |
|
|
25
|
+
| Swap two panes | Drag a pane **title** onto another pane |
|
|
26
|
+
| Maximize / restore | The ⤢ button in the pane header; the stage bar shows "Restore" |
|
|
27
|
+
| Bind an empty pane | Search and pick a session right inside the pane |
|
|
28
|
+
| Open in the native view | The ↗ button: hands the session back to the real conversation (the right sidebar's file preview and diff review only exist there) |
|
|
29
|
+
| Remove a pane | The ✕ button; a bound pane goes **back to the session list** (the split keeps its shape), an empty pane is what ✕ actually removes |
|
|
30
|
+
| Views | Bar → Views: a split with 2+ sessions is remembered automatically; click to restore, ✕ to delete |
|
|
31
|
+
| Check for updates | Refresh icon at the right of the bar: checked every 24h, red dot on a new release, confirm to update |
|
|
32
|
+
|
|
33
|
+
Shortcuts (module defaults; rebind in **Settings → Shortcuts**):
|
|
34
|
+
|
|
35
|
+
| Command | Default (desktop) |
|
|
36
|
+
|---|---|
|
|
37
|
+
| Focus previous / next pane | `Mod+Alt+[` / `Mod+Alt+]` |
|
|
38
|
+
| Maximize or restore the focused pane | `Mod+Alt+M` |
|
|
39
|
+
| Remove the focused pane from the split | `Mod+Alt+W` |
|
|
40
|
+
|
|
41
|
+
> The browser (Web) shell gets **no default bindings**: DSH's shortcut layer accepts a very narrow set of web/Linux combinations, and forcing one fails at boot with "reserved". Desktop defaults work; bind them manually on Web.
|
|
42
|
+
|
|
43
|
+
## Not supported in v1 (on purpose)
|
|
44
|
+
|
|
45
|
+
1. **File preview / diff inside a pane** — whenever any global panel is active, DSH unmounts the right sidebar's session surface (`no session surface is mounted`; shipped panels behave the same). Use ↗ to work in the native view.
|
|
46
|
+
2. **Creating a session inside a pane** — the hero's workspace picker is application-level navigation. Create sessions natively.
|
|
47
|
+
3. **Trajectory / plugin view switching per pane** — panes are pinned to Chat; no invented tabs.
|
|
48
|
+
4. **Sidebar click routed into the focused pane** — that needs interception of a private navigation path; sidebar clicks keep their native behaviour (they leave the split).
|
|
49
|
+
5. Auto-sleep — resources are released when a pane is removed or rebound; there is no pretend "pause rendering of unfocused panes".
|
|
50
|
+
6. More than four panes.
|
|
51
|
+
|
|
52
|
+
## Performance
|
|
53
|
+
|
|
54
|
+
Measured with a CDP rAF sampler on `desktop-kfscv8c-1` (1530×851 window):
|
|
55
|
+
|
|
56
|
+
| Scenario | p50 | p95 | max | long tasks >50ms | JS heap |
|
|
57
|
+
|---|---|---|---|---|---|
|
|
58
|
+
| Native conversation (baseline) | 16.7ms | 16.7ms | 16.8ms | 0 | 43MB |
|
|
59
|
+
| Four panes mounted, idle | 16.7ms | 16.8ms | 16.8ms | 0 | 75MB |
|
|
60
|
+
| Four panes, two streams at once | 16.7ms | 16.7ms | 16.8ms | 0 | 85MB |
|
|
61
|
+
| Four panes, four long streams at once | 16.7ms | 50ms | 150ms | 2 | 53MB |
|
|
62
|
+
|
|
63
|
+
Four long streams is the heaviest case measured: still near 60fps on average, but p95 rises to 50ms with an occasional 150ms frame (four virtualized transcripts re-laying out per chunk). v1 deliberately does not throttle — "every pane stays a real Chat" wins over a frame number.
|
|
64
|
+
|
|
65
|
+
Transcripts are virtualized per turn by DSH itself, so a pane costs roughly one active turn plus one editor instance. Below 900px wide or 520px tall the stage degrades to a single pane plus a pane switcher; the layout tree is preserved.
|
|
66
|
+
|
|
67
|
+
## Development
|
|
68
|
+
|
|
69
|
+
No third-party dependencies; Node ≥ 22.18 (this repo uses 24.13).
|
|
70
|
+
|
|
71
|
+
```powershell
|
|
72
|
+
npm run build # src/client/*.ts → client.js (single-file bundle); src/host/index.ts → index.js
|
|
73
|
+
npm test # layout algebra unit tests (node --test)
|
|
74
|
+
npm run check # release self-check: manifest / artifacts / copy / size
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Isolated verification (**writes no profile**):
|
|
78
|
+
|
|
79
|
+
```powershell
|
|
80
|
+
dsh --profile web --patch <repo>\.dev\dev.patch.yml --port 40602 --no-open
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The overlay's row name is an absolute `file:///` URL to this repo's `index.js` (the Loader anchors relative row names at the profile root, not beside the patch file).
|
|
84
|
+
|
|
85
|
+
The client only uses public slot surfaces: a keyed `main` panel, a private child slot, `SessionProvider`, the `conversation.content` factory (`variant:'embedded'`), `sessions.retain`, `shortcuts` and `locale`. See [docs/DESIGN.md](docs/DESIGN.md).
|
|
86
|
+
|
|
87
|
+
## License
|
|
88
|
+
|
|
89
|
+
MIT.
|
package/README.zh.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# dsh-multiview — 多会话分屏
|
|
2
|
+
|
|
3
|
+
> 一个窗口并排打开 2–4 个**真实**对话。每一格就是原生 Chat:composer、流式输出、工具卡、审批卡、`ask_user_question`、附件、斜杠命令、停止/排队,全部照旧。
|
|
4
|
+
>
|
|
5
|
+
> 目标不是"能跑的分屏",而是**看起来像 DSH 自带的功能**:不覆盖标题栏、不抢布局、不 monkey-patch 任何非公开扩展点。
|
|
6
|
+
|
|
7
|
+
English | [中文](README.zh.md)
|
|
8
|
+
|
|
9
|
+
## 安装
|
|
10
|
+
|
|
11
|
+
已发布到 npm:`dsh plugin add dsh-multiview`,或在 DSH Desktop 的 **插件 → 添加** 里搜索安装(维护者也可用 `plugin_manager install_bundle`),然后**完全退出并重新打开** DeepSeek Harness,让客户端 bundle 重新加载。
|
|
12
|
+
|
|
13
|
+
装好后左侧面板列表多一个「分屏」图标;点它把中央列切换为分屏舞台,再点一次回到原生会话。
|
|
14
|
+
|
|
15
|
+
- 要求:DSH `>=0.2.1-rc.5 <0.2.2-0 || >=0.2.2-rc.1 <0.3.0`(`engines.dsh`)。
|
|
16
|
+
- 卸载:插件页停用/移除 → 重启即可,残留只有一个 `localStorage['dsh.multiview.v1']` 布局键(面板里「还原」会清掉它)。
|
|
17
|
+
|
|
18
|
+
## 用法
|
|
19
|
+
|
|
20
|
+
| 动作 | 操作 |
|
|
21
|
+
|---|---|
|
|
22
|
+
| 打开/收起 | 左侧面板列表「分屏」图标 |
|
|
23
|
+
| 切换 2 / 3 / 4 格 | 舞台顶栏的 `2` `3` `4` |
|
|
24
|
+
| 调整比例 | 拖动格与格之间的分割线 |
|
|
25
|
+
| 交换两格 | 拖动一格的**标题**到另一格上 |
|
|
26
|
+
| 最大化 / 还原 | 双击格头不生效,用格头右侧的 ⤢ 图标;舞台顶栏出现「还原」 |
|
|
27
|
+
| 给空格选会话 | 空格里直接搜索并点选 |
|
|
28
|
+
| 在原生视图打开 | 格头右侧 ↗ 图标:把该会话交回原生对话(右栏文件预览/改动评审要在原生视图里才可用) |
|
|
29
|
+
| 移除一格 | 格头右侧 ✕;已绑定的一格会**回到会话列表**(分屏形状不变),空格再点 ✕ 才真正移除 |
|
|
30
|
+
| 视图 | 顶栏「视图」:绑定 2 格以上会自动记住,点击恢复;✕ 删除 |
|
|
31
|
+
| 检查更新 | 顶栏右侧刷新图标:每 24h 自动检查,有更新带红点,确认后自动更新 |
|
|
32
|
+
|
|
33
|
+
快捷键(模块默认值,可在 **设置 → 快捷键** 改):
|
|
34
|
+
|
|
35
|
+
| 命令 | 默认键(桌面端) |
|
|
36
|
+
|---|---|
|
|
37
|
+
| 聚焦上一格 / 下一格 | `Mod+Alt+[` / `Mod+Alt+]` |
|
|
38
|
+
| 最大化或还原当前格 | `Mod+Alt+M` |
|
|
39
|
+
| 从分屏移除当前格 | `Mod+Alt+W` |
|
|
40
|
+
|
|
41
|
+
> 浏览器(Web)端默认**不绑定**这些键:DSH 的快捷键层对 Web/Linux 允许的组合极窄,硬绑会在启动时报"reserved"。桌面端默认值可用,Web 端请按需自绑。
|
|
42
|
+
|
|
43
|
+
## 明确不支持(v1)
|
|
44
|
+
|
|
45
|
+
这些是**刻意**不做的,不是遗漏:
|
|
46
|
+
|
|
47
|
+
1. **格内文件预览 / 改动评审**:DSH 在任何一个全局面板激活时都会卸下右栏的会话面板(`no session surface is mounted`,自带的面板也一样)。要用右栏,请用格头的 ↗ 切到原生视图。
|
|
48
|
+
2. **格内新建会话**:Hero 的工作区选择器属于应用级导航,会把整个界面带走;新建会话请在原生视图里做。
|
|
49
|
+
3. **格内 Trajectory / 插件视图切换**:每格固定 Chat,不另造 tab。
|
|
50
|
+
4. **点侧栏会话送进聚焦格**:那需要拦截非公开的导航路径;侧栏点选仍然走原生行为(会离开分屏)。
|
|
51
|
+
5. 自动休眠:只在手动移除/切格时释放资源;不伪造"非聚焦格暂停渲染"。
|
|
52
|
+
6. 最多 4 格。
|
|
53
|
+
|
|
54
|
+
## 性能
|
|
55
|
+
|
|
56
|
+
在 `desktop-kfscv8c-1`(1530×851 窗口)用 CDP rAF 采样实测:
|
|
57
|
+
|
|
58
|
+
| 场景 | p50 | p95 | 最长帧 | >50ms 长任务 | JS 堆 |
|
|
59
|
+
|---|---|---|---|---|---|
|
|
60
|
+
| 原生会话(基线) | 16.7ms | 16.7ms | 16.8ms | 0 | 43MB |
|
|
61
|
+
| 4 格挂载、空闲 | 16.7ms | 16.8ms | 16.8ms | 0 | 75MB |
|
|
62
|
+
| 4 格挂载、2 路同时流式 | 16.7ms | 16.7ms | 16.8ms | 0 | 85MB |
|
|
63
|
+
| 4 格、4 路同时长流式 | 16.7ms | 50ms | 150ms | 2 | 53MB |
|
|
64
|
+
|
|
65
|
+
四路长文同时输出是最重场景:平均仍近 60fps,但 p95 升到 50ms、偶发一次 150ms 长帧(四份 transcript 各自按 chunk 重排)。v1 不降频——"每格都是真实 Chat"优先于帧率数字。
|
|
66
|
+
|
|
67
|
+
对话历史按 turn 虚拟化(DSH 自带),因此每格成本 ≈ 一个活跃 turn 的增量渲染 + 一个编辑器实例。窗口窄于 900px 或矮于 520px 时自动降级成「单格 + 顶栏格切换器」,布局树保留。
|
|
68
|
+
|
|
69
|
+
## 开发
|
|
70
|
+
|
|
71
|
+
零第三方依赖,只用本机 Node ≥ 22.18(本仓库用 24.13):
|
|
72
|
+
|
|
73
|
+
```powershell
|
|
74
|
+
npm run build # src/client/*.ts → client.js(单文件 bundle);src/host/index.ts → index.js
|
|
75
|
+
npm test # 布局代数单测(node --test)
|
|
76
|
+
npm run check # 发布自检:manifest / 产物 / 文案 / 体积
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
隔离验证(**不写任何 profile**):
|
|
80
|
+
|
|
81
|
+
```powershell
|
|
82
|
+
dsh --profile web --patch <repo>\.dev\dev.patch.yml --port 40602 --no-open
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
`dev.patch.yml` 里的 row 名用绝对 `file:///` 指向本仓库的 `index.js`(Loader 的相对名锚定在 profile 根,不是 patch 文件旁)。
|
|
86
|
+
|
|
87
|
+
客户端契约只走公开插槽面:`main` keyed 面板 + 私有子槽 + `SessionProvider` + `conversation.content` factory(`variant:'embedded'`)+ `sessions.retain` + `shortcuts` + `locale`。详见 [docs/DESIGN.md](docs/DESIGN.md)。
|
|
88
|
+
|
|
89
|
+
## 许可
|
|
90
|
+
|
|
91
|
+
MIT。
|