dsh-visualization 0.1.3 → 0.1.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/AGENTS.md +240 -0
- package/FAQ.md +48 -61
- package/GUIDE.md +270 -0
- package/README.md +37 -293
- package/package.json +10 -2
- package/screenshots.json +5 -0
- package/wallpaper/hybrid.html +221 -0
- package/wallpaper/live.html +33 -0
- package/wallpaper/lively/LivelyInfo.json +17 -0
- package/wallpaper/lively/index.html +65 -0
- package/wallpaper/lively/preview.jpg +0 -0
- package/wallpaper/lively-package.zip +0 -0
- package/wallpaper/index.html +0 -62
package/AGENTS.md
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# AGENTS — changing dsh-visualization
|
|
2
|
+
|
|
3
|
+
For DSH agents and developers. English first, **[中文](#中文)** at the bottom.
|
|
4
|
+
For using the plugin see [GUIDE.md](GUIDE.md).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# English
|
|
9
|
+
|
|
10
|
+
## 1. Three commands
|
|
11
|
+
|
|
12
|
+
```powershell
|
|
13
|
+
node build.cjs # standalone/instrument.html → web/index.html
|
|
14
|
+
node make-wallpaper.cjs # web/index.html → wallpaper/index.html (adds <base>, drops -webkit-line-clamp)
|
|
15
|
+
node make-wallpaper-full.cjs # full page with minimal CSS (WE experiment, see §9)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Changing anything under `fold.cjs` / `index.js` (the host half) **requires a DSH restart** — the
|
|
19
|
+
plugin toggle only remounts routes, it does not re-evaluate loaded ESM.
|
|
20
|
+
|
|
21
|
+
## 2. File map
|
|
22
|
+
|
|
23
|
+
| Path | Role |
|
|
24
|
+
|---|---|
|
|
25
|
+
| `standalone/instrument.html` | **the single source of the page.** Edit this, then build. |
|
|
26
|
+
| `web/index.html` | **generated** — never edit by hand |
|
|
27
|
+
| `standalone/bridge.cjs` | standalone dev server (port 8787), not shipped |
|
|
28
|
+
| `fold.cjs` | host: session discovery, zstd frames, incremental fold, HTTP/SSE, fixed-port helper |
|
|
29
|
+
| `index.js` | host entry: registers the route, injects origin/policy, starts the helper |
|
|
30
|
+
| `client.js` | client half: sidebar icon + main-panel iframe |
|
|
31
|
+
| `build.cjs` | regenerates `web/index.html` from the source page |
|
|
32
|
+
| `wallpaper/` | wallpaper pages + Lively package |
|
|
33
|
+
| `wallpaper-live.cjs` | persistent-capture pipeline (Edge + CDP, JPEG, ~4.9 fps) |
|
|
34
|
+
| `wallpaper-capture.cjs` | crop pipeline: full shot → three strips (top/right/bottom) |
|
|
35
|
+
| `we-deploy.ps1` | deploy a page into Wallpaper Engine's project (handles the file lock) |
|
|
36
|
+
| `we-cdp.cjs` | turns on WE's CEF devtools port |
|
|
37
|
+
| `we-css-keep.cjs` | CSS bisect helper (`we-css-split.cjs` is the older variant) |
|
|
38
|
+
| `screenshots.json` | storefront screenshots declared in-repo |
|
|
39
|
+
|
|
40
|
+
## 3. Rules that bite
|
|
41
|
+
|
|
42
|
+
1. **One source.** Change `standalone/instrument.html`, run `node build.cjs`. Hand-editing
|
|
43
|
+
`web/index.html` gets overwritten.
|
|
44
|
+
2. **Host changes need a restart.** `fold.cjs` / `index.js` are ESM; a plugin toggle is not enough.
|
|
45
|
+
3. **Never overwrite the page with a one-liner.** It has been destroyed that way once — use edits or a
|
|
46
|
+
small `.cjs` patch script. Recovery is documented at the end of this file.
|
|
47
|
+
4. **Wait for the wallpaper file lock.** WE keeps `projects/.../index.html` open; copy silently fails
|
|
48
|
+
while it runs. Kill WE, delete the file, then copy (`we-deploy.ps1` does exactly this).
|
|
49
|
+
|
|
50
|
+
## 4. Data flow
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
~/.dsh/sessions/<ws>/<session>/session.v<N>.jsonl.zstd
|
|
54
|
+
└─ zstdFrames() parse RFC 8878 headers+blocks → exact frame boundaries
|
|
55
|
+
└─ unzstdAll() decode only frames appended since the last read
|
|
56
|
+
└─ makeFolder() reducer: push(newEvents) → result(); never re-scans history
|
|
57
|
+
└─ /dsh-visualization/state (one-shot, gzip, `?session=` to pin)
|
|
58
|
+
/dsh-visualization/events (SSE, pushes only on change, 250 ms check)
|
|
59
|
+
└─ page: applyState() → render() (DOM) + draw() (canvas)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Measured at ~8.7 k events: first fold 240–260 ms, then 7–12 ms per change. Idle SSE = zero bytes.
|
|
63
|
+
|
|
64
|
+
## 5. Adding things
|
|
65
|
+
|
|
66
|
+
**A ring** — three places in `standalone/instrument.html`: `RINGVIS` / `RING_NAME` / `RING_COL`, the
|
|
67
|
+
`if (RINGVIS[n])` block in `draw()`, and `hitReg({...})` so hover/click works. Add a branch in
|
|
68
|
+
`showDetail()` if the card needs fields.
|
|
69
|
+
|
|
70
|
+
**A language** — `EN` (whole-string matches), `EN_RULES` (templated phrases), `EN_FN` (logic). `LANG`
|
|
71
|
+
is `'zh' | 'en'`; to add a third, turn it into a list and key the dictionaries by code.
|
|
72
|
+
|
|
73
|
+
**A colour** — `toolColor(name)`.
|
|
74
|
+
|
|
75
|
+
## 6. Debugging
|
|
76
|
+
|
|
77
|
+
| Flag / tool | What it gives |
|
|
78
|
+
|---|---|
|
|
79
|
+
| `?debug=1` (or `#debug`, `localStorage.dshviz.debug=1`) | `window.__M` / `__HIT` / `__CHAIN` |
|
|
80
|
+
| `http://127.0.0.1:8799/state` | the fixed-port helper the wallpapers use |
|
|
81
|
+
| `node standalone/shot.cjs <url> out.png W H` | screenshot any page (CDP over pipes) |
|
|
82
|
+
| `SHOT_EVAL=...` | evaluate JS in the page and print the result |
|
|
83
|
+
| `node we-cdp.cjs` | opens WE's CEF devtools port (8080) |
|
|
84
|
+
| `node we-cdp-probe.cjs` | reads runtime state / console from the WE wallpaper page |
|
|
85
|
+
|
|
86
|
+
## 7. Release flow
|
|
87
|
+
|
|
88
|
+
```powershell
|
|
89
|
+
# 1. bump
|
|
90
|
+
node -e "const p=require('./package.json');p.version='0.1.5';require('fs').writeFileSync('package.json',JSON.stringify(p,null,2)+'\n')"
|
|
91
|
+
# 2. build the page first (web/index.html is what ships)
|
|
92
|
+
node build.cjs
|
|
93
|
+
# 3. publish (2FA-bypass token is configured on this machine)
|
|
94
|
+
npm publish --access public
|
|
95
|
+
# 4. push
|
|
96
|
+
git add -A; git commit -m "..."; git push
|
|
97
|
+
# 5. the marketplace entry needs no change unless fields changed:
|
|
98
|
+
# data/plugins/peilopielo__dsh-Visualization.yml in awesome-dsh-plugin
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## 8. Known traps
|
|
102
|
+
|
|
103
|
+
1. **WE's renderer crashes on the full page.** Reproduced on Chrome 146; independent of protocol
|
|
104
|
+
(`file://` and `http://` both crash) and of the CSS file (a minimal stylesheet still crashes). The
|
|
105
|
+
crash correlates with compositing the `.rings` subtree. Do not spend more time on it — use Lively.
|
|
106
|
+
2. **`-webkit-line-clamp` is an independent crash trigger** in WE. `make-wallpaper.cjs` strips it.
|
|
107
|
+
3. **Multi-frame zstd.** The log is append-only multi-frame; older Node decodes only frame 1. Split on
|
|
108
|
+
the magic `28 B5 2F FD`… **only as a fallback**: the correct path is `zstdFrames()`, which parses
|
|
109
|
+
headers and blocks. Magic-scanning is wrong (the real log contains 4838 magic occurrences).
|
|
110
|
+
4. **File lock, WE running** — see rule 4.
|
|
111
|
+
5. **`pointer-events` on overlay layers.** A full-screen overlay without `pointer-events:none` kills
|
|
112
|
+
all canvas hover/click. `elementFromPoint` returning the overlay instead of `#net` is the symptom.
|
|
113
|
+
6. **Init order.** `M.sSteps/sJobs/sTools/sLog/sStats` must be `[]` before the first `draw()`, or the
|
|
114
|
+
canvas freezes. `DEBUG` must be module-scope, not inside `render()`.
|
|
115
|
+
7. **`CN.turns = 0` means "all"** — guard with `turnLimit = CN.turns || 999`, else no lines are drawn.
|
|
116
|
+
8. **`tool/result` id lives at `message.source.callId`**, not `data.toolCallId`.
|
|
117
|
+
9. **Zoom-dependent layout** — the rings measure `.rings.getBoundingClientRect()`; if that element is
|
|
118
|
+
hidden or zero-sized, `G.base` is 0 and `draw()` returns early (blank panel with no error).
|
|
119
|
+
|
|
120
|
+
## 9. Wallpaper routes (and why)
|
|
121
|
+
|
|
122
|
+
| Route | Frame rate | Notes |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| Lively + `wallpaper/lively/index.html` | full | WebView2 (Edge) — renders fine, mouse input forwarded |
|
|
125
|
+
| WE + `wallpaper/live.html` + `wallpaper-live.cjs` | ~4.9 fps | JPEG 200 KB/frame, persistent Edge via CDP |
|
|
126
|
+
| WE + three strips (`wallpaper/hybrid.html`) | native rings, 8 s text | hybrid: canvas rings + screenshot panels |
|
|
127
|
+
| WE + full page (`make-wallpaper-full.cjs`) | — | dead end: crashes (trap 1) |
|
|
128
|
+
|
|
129
|
+
## 10. Recovering the page
|
|
130
|
+
|
|
131
|
+
If `standalone/instrument.html` is ever clobbered:
|
|
132
|
+
|
|
133
|
+
1. Check `instrument.bak.html` and the working tree (`git status`, `git diff`)
|
|
134
|
+
2. If the browser still has the page open, run in its console:
|
|
135
|
+
`fetch('/savehtml',{method:'POST',body:document.documentElement.outerHTML})`
|
|
136
|
+
→ the host writes `instrument.recovered.html`
|
|
137
|
+
3. Re-apply the last edits, then `node build.cjs`
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
# 中文
|
|
142
|
+
|
|
143
|
+
## 1. 三个命令
|
|
144
|
+
|
|
145
|
+
```powershell
|
|
146
|
+
node build.cjs # standalone/instrument.html → web/index.html
|
|
147
|
+
node make-wallpaper.cjs # 生成壁纸页(加 <base>、去掉 -webkit-line-clamp)
|
|
148
|
+
node make-wallpaper-full.cjs # 原版页面 + 极简 CSS(WE 实验用,见 §9)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
改 `fold.cjs` / `index.js`(宿主侧)**必须重启 DSH**——插件开关只重挂路由,不会重新求值已加载的 ESM。
|
|
152
|
+
|
|
153
|
+
## 2. 文件地图
|
|
154
|
+
|
|
155
|
+
| 路径 | 作用 |
|
|
156
|
+
|---|---|
|
|
157
|
+
| `standalone/instrument.html` | **页面唯一源文件**,改它再 build |
|
|
158
|
+
| `web/index.html` | **生成物**,不要手改 |
|
|
159
|
+
| `fold.cjs` | 宿主:会话发现、zstd 帧解析、增量折叠、HTTP/SSE、固定端口服务 |
|
|
160
|
+
| `index.js` | 宿主入口:注册路由、注入 origin/策略、启动固定端口 |
|
|
161
|
+
| `client.js` | 客户端:侧栏图标 + 主面板 iframe |
|
|
162
|
+
| `build.cjs` | 从源页面重新生成 `web/index.html` |
|
|
163
|
+
| `wallpaper/` | 壁纸页 + Lively 包 |
|
|
164
|
+
| `wallpaper-live.cjs` | 常驻截图流水线(Edge + CDP,JPEG,约 4.9 fps) |
|
|
165
|
+
| `wallpaper-capture.cjs` | 裁切流水线:整页截图 → 三块(顶/右/底) |
|
|
166
|
+
| `we-deploy.ps1` | 部署页面到 WE 工程(处理文件锁) |
|
|
167
|
+
| `we-cdp.cjs` | 打开 WE 的 CEF 调试端口 |
|
|
168
|
+
|
|
169
|
+
## 3. 会咬人的规矩
|
|
170
|
+
|
|
171
|
+
1. **单一源**:只改 `standalone/instrument.html`,然后 `node build.cjs`。手改 `web/index.html` 会被覆盖。
|
|
172
|
+
2. **改宿主必须重启 DSH**。
|
|
173
|
+
3. **绝不用单行命令整篇覆盖页面**——它被这样毁过一次。
|
|
174
|
+
4. **等文件锁**:WE 运行时锁着 `projects/.../index.html`,直接复制会静默失败。先关 WE → 删文件 → 再复制。
|
|
175
|
+
|
|
176
|
+
## 4. 数据流
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
日志 → zstdFrames()(按 RFC 8878 精确切帧)→ 只解新帧 → makeFolder().push(新事件)
|
|
180
|
+
→ /state(一次性、gzip)或 /events(SSE,变化才推)→ applyState() → render() + draw()
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
实测(约 8.7k 事件):首次折叠 240~260 ms,之后每次变化 7~12 ms;空闲 SSE 零字节。
|
|
184
|
+
|
|
185
|
+
## 5. 加东西的落点
|
|
186
|
+
|
|
187
|
+
**新环** —— `RINGVIS`/`RING_NAME`/`RING_COL`、`draw()` 里的绘制块、`hitReg(...)` 登记、`showDetail()` 分支。
|
|
188
|
+
|
|
189
|
+
**新语言** —— `EN` 词典 + `EN_RULES` 正则 + `EN_FN` 逻辑;`LANG` 现在写死两门,要加就把字典按语言代码分键。
|
|
190
|
+
|
|
191
|
+
**新配色** —— `toolColor(name)`。
|
|
192
|
+
|
|
193
|
+
## 6. 调试手段
|
|
194
|
+
|
|
195
|
+
| 手段 | 作用 |
|
|
196
|
+
|---|---|
|
|
197
|
+
| `?debug=1` | 挂出 `window.__M` / `__HIT` / `__CHAIN` |
|
|
198
|
+
| `http://127.0.0.1:8799/state` | 壁纸用的固定端口 |
|
|
199
|
+
| `node standalone/shot.cjs <url> out.png W H` | 截图任意页面(CDP over pipes) |
|
|
200
|
+
| `SHOT_EVAL=...` | 在页面里求值并打印 |
|
|
201
|
+
| `node we-cdp.cjs` / `we-cdp-probe.cjs` | 打开/读取 WE 的 CEF 调试端口 |
|
|
202
|
+
|
|
203
|
+
## 7. 发布流程
|
|
204
|
+
|
|
205
|
+
```powershell
|
|
206
|
+
node build.cjs # 先构建,web/index.html 才是要发的
|
|
207
|
+
# 改 package.json 的 version
|
|
208
|
+
npm publish --access public
|
|
209
|
+
git add -A; git commit -m "..."; git push
|
|
210
|
+
# 市场条目一般不用动(字段没变的话)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
## 8. 坑表
|
|
214
|
+
|
|
215
|
+
1. **WE 渲染器跑不动完整页**:Chrome 146 复现,与协议无关(file:// 和 http:// 都崩)、与 CSS 文件无关(换极简 CSS 也崩);崩溃与合成 `.rings` 子树相关。别再花时间,用 Lively。
|
|
216
|
+
2. **`-webkit-line-clamp` 是独立崩溃点**,`make-wallpaper.cjs` 会去掉它。
|
|
217
|
+
3. **多帧 zstd**:日志是追加写的多帧;别扫魔数(真实日志里有 4838 处魔数),用 `zstdFrames()` 解析帧头块头。
|
|
218
|
+
4. **文件锁**:见规矩 4。
|
|
219
|
+
5. **覆盖层的 `pointer-events`**:全屏遮罩若没有 `pointer-events:none`,canvas 的悬停/点击全部失效。
|
|
220
|
+
6. **初始化顺序**:`M.sSteps/sJobs/sTools/sLog/sStats` 必须在首帧前是 `[]`,否则画布卡死;`DEBUG` 要在模块作用域。
|
|
221
|
+
7. **`CN.turns = 0` 表示「全部」**:用 `turnLimit = CN.turns || 999` 兜底,否则一条线都不画。
|
|
222
|
+
8. **`tool/result` 的 id 在 `message.source.callId`**,不在 `data.toolCallId`。
|
|
223
|
+
9. **`.rings` 尺寸为 0 会让 `draw()` 直接 return**:面板空白但无报错,先查这个元素的包围盒。
|
|
224
|
+
|
|
225
|
+
## 9. 壁纸方案与取舍
|
|
226
|
+
|
|
227
|
+
| 方案 | 帧率 | 说明 |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| Lively + `wallpaper/lively/index.html` | 满帧 | WebView2(Edge),渲染正常,鼠标可交互 |
|
|
230
|
+
| WE + `wallpaper/live.html` + `wallpaper-live.cjs` | 约 4.9 fps | JPEG 200 KB/帧,常驻 Edge |
|
|
231
|
+
| WE + 三块截图(`wallpaper/hybrid.html`) | 环原生 + 文字 8 秒 | 混合方案 |
|
|
232
|
+
| WE + 完整页 | — | 死路:崩(坑 1) |
|
|
233
|
+
|
|
234
|
+
## 10. 页面被覆盖后怎么救
|
|
235
|
+
|
|
236
|
+
1. 先看 `instrument.bak.html` 和 `git status` / `git diff`
|
|
237
|
+
2. 浏览器里还开着页面时,在控制台执行:
|
|
238
|
+
`fetch('/savehtml',{method:'POST',body:document.documentElement.outerHTML})`
|
|
239
|
+
→ 宿主写出 `instrument.recovered.html`
|
|
240
|
+
3. 重新补最后的改动,然后 `node build.cjs`
|
package/FAQ.md
CHANGED
|
@@ -1,85 +1,72 @@
|
|
|
1
|
-
# FAQ
|
|
1
|
+
# FAQ
|
|
2
|
+
|
|
3
|
+
Short answers to the questions that are not "how do I use it" — for usage see [GUIDE.md](GUIDE.md),
|
|
4
|
+
for changing the code see [AGENTS.md](AGENTS.md).
|
|
2
5
|
|
|
3
6
|
## Why is the license not OSI-approved? / 为什么不用 OSI 许可?
|
|
4
7
|
|
|
5
|
-
**EN** —
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
plugin adopts the same license: free for personal use, study, research, teaching and hobby
|
|
10
|
-
projects; commercial use is not granted.
|
|
8
|
+
**EN** — Because HALOFLUX is not. The visual language — rings, palette, layered layout — derives from
|
|
9
|
+
[HALOFLUX](https://github.com/Ryder191/haloflux), which is licensed under PolyForm Noncommercial 1.0.0.
|
|
10
|
+
Those terms require derivatives to stay noncommercial and to keep the attribution, so an MIT/Apache
|
|
11
|
+
badge here would be a promise this project cannot keep.
|
|
11
12
|
|
|
12
|
-
The
|
|
13
|
-
|
|
14
|
-
credited in both the LICENSE and the page footer.
|
|
13
|
+
The **code** is original (host folding, zstd frame parsing, SSE, the page). What it borrows is the
|
|
14
|
+
design language, credited in the LICENSE and in the page footer.
|
|
15
15
|
|
|
16
|
-
**中文** —
|
|
17
|
-
[HALOFLUX](https://github.com/Ryder191/haloflux)
|
|
18
|
-
|
|
19
|
-
所以插件沿用同一许可:个人使用、学习、研究、教学、兴趣项目免费;不授予商业用途。
|
|
16
|
+
**中文** — 因为 HALOFLUX 不是。视觉语言(环、配色、分层布局)来自
|
|
17
|
+
[HALOFLUX](https://github.com/Ryder191/haloflux),它是 PolyForm Noncommercial 1.0.0。
|
|
18
|
+
该许可要求衍生作品同为非商业并保留署名,所以这里挂 MIT/Apache 就是兑现不了的承诺。
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
**代码**是为本插件新写的(宿主折叠、zstd 帧解析、SSE、页面);借用的是设计语言,
|
|
21
|
+
已在 LICENSE 和页面右下角注明。
|
|
23
22
|
|
|
24
|
-
>
|
|
25
|
-
>
|
|
26
|
-
> 插件市场并不要求 OSI 许可——本目录里已有其他非 OSI 许可的插件。
|
|
23
|
+
> The plugin market does not require an OSI license — other listed plugins ship non-OSI terms too.
|
|
24
|
+
> 插件市场并不要求 OSI 许可,目录里已有其他非 OSI 许可的插件。
|
|
27
25
|
|
|
28
26
|
## Does it send my data anywhere? / 会把数据发出去吗?
|
|
29
27
|
|
|
30
|
-
**EN** — No. The host
|
|
31
|
-
`/dsh-visualization/*` to the local page.
|
|
32
|
-
|
|
28
|
+
**EN** — No. The host reads `~/.dsh/sessions/**` read-only, folds it in memory, and serves it on
|
|
29
|
+
`/dsh-visualization/*` to the local page. Neither half makes an outbound request, and no session file
|
|
30
|
+
is written.
|
|
33
31
|
|
|
34
|
-
**中文** —
|
|
35
|
-
|
|
32
|
+
**中文** — 不会。宿主只读 `~/.dsh/sessions/**`,在内存里折叠,通过 `/dsh-visualization/*`
|
|
33
|
+
提供给本地页面。前后两端都不对外发请求,也不写任何会话文件。
|
|
36
34
|
|
|
37
|
-
## Why
|
|
35
|
+
## Why loopback only? / 为什么只能本机访问?
|
|
38
36
|
|
|
39
37
|
**EN** — Session logs contain every command you ran and every prompt you typed. The routes answer
|
|
40
|
-
loopback addresses only, so exposing the Web UI on a LAN does not expose the instrument. If you
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
loopback addresses only, so exposing the Web UI on a LAN does not expose the instrument. If you really
|
|
39
|
+
need remote access, set `allowRemote: true` — and understand that anyone who can reach the port can
|
|
40
|
+
read those logs.
|
|
41
|
+
|
|
42
|
+
**中文** — 会话日志里有你执行过的每条命令和说过的每句话。路由只响应回环地址,所以把 Web 界面
|
|
43
|
+
暴露到局域网不会顺带暴露仪表盘。确实要远程访问时写 `allowRemote: true`——但要清楚:能访问该端口的人
|
|
44
|
+
都能读到这些日志。
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
局域网并不会顺带暴露仪表盘。确实需要远程访问时,在插件配置里写 `allowRemote: true`——
|
|
46
|
-
但要清楚:任何能访问该端口的人都能读到这些日志。
|
|
46
|
+
## Can I use it at work? / 能在公司用吗?
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
**EN** — No. PolyForm Noncommercial excludes use by a for-profit company, including internal use and
|
|
49
|
+
use on behalf of a company. Personal study, and noncommercial organisations (charities, educational and
|
|
50
|
+
public research institutions), are permitted by the license text.
|
|
49
51
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
| `这个运行环境不支持 zstd 解压(需要 Node ≥ 22.15)` | 宿主 Node 太老 |
|
|
53
|
-
| `会话目录是空的 —— 先在这个 profile 里跑一轮对话` | 这个 profile 还没聊过 |
|
|
54
|
-
| `还没找到 DSH 会话目录(…),确认 DSH_HOME 是否正确` | DSH 数据不在默认位置;设 `DSH_HOME` 或 `DSHVIZ_SESSIONS_ROOT` |
|
|
55
|
-
| 面板空白 + 网络面板 403 | 不是本机访问;见上一节 |
|
|
52
|
+
**中文** — 不行。PolyForm Noncommercial 排除了在营利性公司内部或代表公司的使用。个人学习,以及慈善、
|
|
53
|
+
教育、公共研究机构等非商业组织,按许可条文是允许的。
|
|
56
54
|
|
|
57
55
|
## Does it slow the session down? / 会拖慢会话吗?
|
|
58
56
|
|
|
59
|
-
**EN** — The fold is incremental: only newly appended zstd frames are decoded, and only new events
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
heartbeat).
|
|
57
|
+
**EN** — The fold is incremental: only newly appended zstd frames are decoded, and only new events are
|
|
58
|
+
pushed into the accumulator. At ~8.7 k events the first fold is 240–260 ms; afterwards each change is
|
|
59
|
+
7–12 ms. When nothing changes the SSE connection sends zero bytes (apart from a 15 s heartbeat).
|
|
63
60
|
|
|
64
61
|
**中文** — 折叠是增量的:只解新追加的 zstd 帧,只把新事件 push 进累加器。约 8.7k 事件时首次
|
|
65
|
-
240~
|
|
66
|
-
|
|
67
|
-
## How do I uninstall it? / 怎么卸载?
|
|
68
|
-
|
|
69
|
-
```powershell
|
|
70
|
-
# DSH 插件页里关掉,或:
|
|
71
|
-
dsh plugin remove dsh-visualization
|
|
72
|
-
# npm 装的:
|
|
73
|
-
npm uninstall -g dsh-visualization
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
仪表盘不写任何持久状态;删除后 `~/.dsh/sessions` 里的日志原样不动。
|
|
77
|
-
|
|
78
|
-
## Can I use it at work? / 能在公司用吗?
|
|
62
|
+
240~260 ms,之后每次变化 7~12 ms。没有变化时 SSE 一个字节都不发(15 秒一次心跳除外)。
|
|
79
63
|
|
|
80
|
-
|
|
81
|
-
and use on behalf of a company. Personal study and noncommercial organisations (charities,
|
|
82
|
-
educational and public research institutions) are permitted by the license text.
|
|
64
|
+
## Known limits
|
|
83
65
|
|
|
84
|
-
|
|
85
|
-
|
|
66
|
+
- **Memory grows with the session**: the reducer keeps derived state for every event. Steps, tools and
|
|
67
|
+
the log are capped; counters are cumulative. At ~100 k events `result()` still sorts 1.2 k steps and
|
|
68
|
+
1.5 k tools — roughly 10–20 ms per frame.
|
|
69
|
+
- **Two UI languages** (zh/en).
|
|
70
|
+
- **Read-only**: the instrument never writes session files.
|
|
71
|
+
- **Wallpaper Engine cannot render the page** — its CEF crashes on it; use Lively instead
|
|
72
|
+
(see [GUIDE.md §8](GUIDE.md#8-as-a-desktop-wallpaper)).
|
package/GUIDE.md
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
# GUIDE — using dsh-visualization
|
|
2
|
+
|
|
3
|
+
The user guide. English first, **[中文](#中文)** at the bottom.
|
|
4
|
+
For changing the code see [AGENTS.md](AGENTS.md); for "why is it like this" see [FAQ.md](FAQ.md).
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# English
|
|
9
|
+
|
|
10
|
+
## 1. What this is
|
|
11
|
+
|
|
12
|
+
A DeepSeek Harness plugin that turns the **current session** into an instrument panel: a sidebar icon,
|
|
13
|
+
and a full panel showing seven concentric layers — session, steps, skills, tools, jobs, approvals,
|
|
14
|
+
file changes — plus a turn timeline and an event log.
|
|
15
|
+
|
|
16
|
+
Everything comes from `~/.dsh/sessions/**` (read-only). Nothing is sent anywhere.
|
|
17
|
+
|
|
18
|
+

|
|
19
|
+
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
## 2. Install
|
|
23
|
+
|
|
24
|
+
```powershell
|
|
25
|
+
# marketplace / Plugins page: search "dsh-visualization"
|
|
26
|
+
npm i dsh-visualization
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
After installing, a ring icon appears in the left rail. Click it; the panel takes the main area.
|
|
30
|
+
Nothing else to configure — it follows whichever session you have open.
|
|
31
|
+
|
|
32
|
+
**Requirement**: Node ≥ 22.15 in the host. Without it the panel says so explicitly instead of
|
|
33
|
+
rendering blank.
|
|
34
|
+
|
|
35
|
+
## 3. First look
|
|
36
|
+
|
|
37
|
+
The panel is split in three:
|
|
38
|
+
|
|
39
|
+
| Area | Content |
|
|
40
|
+
|---|---|
|
|
41
|
+
| Centre | the rings; the number in the middle is the current **turn** |
|
|
42
|
+
| Right column | session flow, context usage, background jobs, turn timeline |
|
|
43
|
+
| Bottom | event log, grouped by turn, newest on top |
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
Direction matters: on the rings, **12 o'clock is the newest data**, older data runs clockwise.
|
|
48
|
+
|
|
49
|
+
## 4. Reading the rings
|
|
50
|
+
|
|
51
|
+
| Ring | What it shows |
|
|
52
|
+
|---|---|
|
|
53
|
+
| ① Session | context-window usage + the last 12 turn ticks |
|
|
54
|
+
| ② Steps | time buckets; thicker segment = more time spent in that slice |
|
|
55
|
+
| ③ Skills | 16 slots; one lights up per loaded skill, and a link runs to when it was last used |
|
|
56
|
+
| ④ Tools | composition by call count (or by time — see `share`) |
|
|
57
|
+
| ⑤ Jobs | one arc per background job, length ∝ runtime |
|
|
58
|
+
| ⑥ Approvals | one tick per approval, colour = outcome |
|
|
59
|
+
| ⑦ Changes | one tick per file change; deliverables are taller |
|
|
60
|
+
|
|
61
|
+
Each ring can be switched off independently (see the controls below); the remaining rings re-space
|
|
62
|
+
themselves to fill the gap.
|
|
63
|
+
|
|
64
|
+

|
|
65
|
+
|
|
66
|
+
## 5. Controls (bottom left)
|
|
67
|
+
|
|
68
|
+
| Control | What it does |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `①…⑦` | toggle each layer |
|
|
71
|
+
| `spin` | slow rotation of ②③④ |
|
|
72
|
+
| `lines` | `ladders` (per-step chains), `beams` (from the core), or `both` |
|
|
73
|
+
| `share` | size the tool ring by call `count` or by `time` |
|
|
74
|
+
| `line turns` | how many turns get connectors |
|
|
75
|
+
| `show turns` | how many turns the whole panel covers (or `all`) |
|
|
76
|
+
| `⧉ window` | open a separate window you can drag to another monitor |
|
|
77
|
+
| `中 / EN` | switch language |
|
|
78
|
+
|
|
79
|
+
`line turns` is always clamped to `show turns` — a connector can never point at a turn the panel is
|
|
80
|
+
not showing.
|
|
81
|
+
|
|
82
|
+
Bright vs dim segments on ②: a **dim** segment has no connector because it is outside `line turns`;
|
|
83
|
+
a **bright** segment with no line is a text-only step that called no tools.
|
|
84
|
+
|
|
85
|
+
## 6. Hover and click
|
|
86
|
+
|
|
87
|
+
Every node on every ring answers:
|
|
88
|
+
|
|
89
|
+
- **hover** — a tooltip with the name and a one-line summary
|
|
90
|
+
- **click** — a detail card; for tools it lists the last six actual commands with timings
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
## 7. Language
|
|
95
|
+
|
|
96
|
+
The UI ships in Chinese and English. It starts from `navigator.language`, remembers your choice, and
|
|
97
|
+
can be forced per page with `?lang=en` / `?lang=zh`.
|
|
98
|
+
|
|
99
|
+
## 8. As a desktop wallpaper
|
|
100
|
+
|
|
101
|
+
Two routes. **Lively is recommended** — it renders the page natively at full frame rate.
|
|
102
|
+
|
|
103
|
+
### Lively Wallpaper (full frame rate, interactive)
|
|
104
|
+
|
|
105
|
+
1. Install [Lively Wallpaper](https://github.com/rocksdanister/lively) (free, open source)
|
|
106
|
+
2. Download [`wallpaper/lively-package.zip`](wallpaper/lively-package.zip)
|
|
107
|
+
3. Drag the zip into Lively — or **Add Wallpaper → open file** → the extracted `index.html`
|
|
108
|
+
|
|
109
|
+
The page finds the plugin on `127.0.0.1:8799` by itself. If DSH is not running it shows a hint and
|
|
110
|
+
retries every 5 seconds.
|
|
111
|
+
|
|
112
|
+
**The panel stays clickable on the desktop** — Lively forwards mouse input, so ring toggles, turn
|
|
113
|
+
pickers and detail cards work directly on the background. If that makes desktop icons hard to click,
|
|
114
|
+
turn off icon display in Lively's settings.
|
|
115
|
+
|
|
116
|
+
### Wallpaper Engine (screenshot mode, ~5 fps)
|
|
117
|
+
|
|
118
|
+
Wallpaper Engine's own renderer crashes on this page (reproduced on its Chrome 146, independent of
|
|
119
|
+
protocol). The workaround is a screenshot pipeline:
|
|
120
|
+
|
|
121
|
+
```powershell
|
|
122
|
+
node wallpaper-live.cjs 200 78 # ≈4.9 fps, 200 KB/frame
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Then set `wallpaper/live.html` as a Wallpaper Engine web wallpaper. A low-CPU variant (`node
|
|
126
|
+
wallpaper-capture.cjs 8`) refreshes every 8 seconds instead.
|
|
127
|
+
|
|
128
|
+

|
|
129
|
+
|
|
130
|
+
## 9. Troubleshooting
|
|
131
|
+
|
|
132
|
+
| Symptom | Cause |
|
|
133
|
+
|---|---|
|
|
134
|
+
| Panel says "this runtime does not support zstd" | host Node < 22.15 |
|
|
135
|
+
| Panel says the session directory is empty | no conversation has run in this profile yet |
|
|
136
|
+
| Blank panel + 403 in the network tab | you are not on loopback; `allowRemote: true` if you really need remote access |
|
|
137
|
+
| A dim ring segment has no line | it is outside `line turns` |
|
|
138
|
+
| A bright segment has no line | that step called no tools |
|
|
139
|
+
| Wallpaper says "not connected" | DSH is not running, or the plugin is disabled |
|
|
140
|
+
|
|
141
|
+
## 10. Privacy and uninstall
|
|
142
|
+
|
|
143
|
+
- The host reads `~/.dsh/sessions/**` and folds it **in memory**. It writes no session files.
|
|
144
|
+
- No outbound network requests from either half; routes answer loopback only.
|
|
145
|
+
- Uninstall: disable the plugin on the Plugins page, or `dsh plugin remove dsh-visualization`.
|
|
146
|
+
Your session logs are untouched.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
# 中文
|
|
151
|
+
|
|
152
|
+
## 1. 这是什么
|
|
153
|
+
|
|
154
|
+
一个 DeepSeek Harness 插件,把**当前会话**画成一台仪表盘:侧栏一个环图标,点开是七层同心环
|
|
155
|
+
(会话、步骤、技能、工具、任务、审批、文件变更)+ 轮次时间线 + 事件表。
|
|
156
|
+
|
|
157
|
+
数据全部来自 `~/.dsh/sessions/**`(只读),不发往任何地方。
|
|
158
|
+
|
|
159
|
+
## 2. 安装
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
# 插件市场 / 插件页搜索 "dsh-visualization"
|
|
163
|
+
npm i dsh-visualization
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
装好后左侧栏出现环图标,点开占满主面板。不用配置——它跟随你当前打开的那个会话。
|
|
167
|
+
|
|
168
|
+
**要求**:宿主 Node ≥ 22.15。不满足时面板会直接说明,不会给你一个空白页。
|
|
169
|
+
|
|
170
|
+
## 3. 第一眼看到的
|
|
171
|
+
|
|
172
|
+
面板分三块:
|
|
173
|
+
|
|
174
|
+
| 区域 | 内容 |
|
|
175
|
+
|---|---|
|
|
176
|
+
| 中间 | 环;正中的数字是当前**轮次** |
|
|
177
|
+
| 右栏 | 会话逻辑链、上下文占用、后台任务、轮次时间线 |
|
|
178
|
+
| 底部 | 事件表,按轮分组,最新的在最上面 |
|
|
179
|
+
|
|
180
|
+

|
|
181
|
+
|
|
182
|
+
方向很重要:环上**12 点方向是最新的数据**,越旧越顺时针。
|
|
183
|
+
|
|
184
|
+
## 4. 怎么读环
|
|
185
|
+
|
|
186
|
+
| 环 | 表示什么 |
|
|
187
|
+
|---|---|
|
|
188
|
+
| ① 会话 | 上下文占用 + 最近 12 轮刻度 |
|
|
189
|
+
| ② 步骤 | 时间分格;格子越粗 = 那段时间花得越久 |
|
|
190
|
+
| ③ 技能 | 16 格;加载一个技能亮一格,并连一条线到"最近一次使用"的时刻 |
|
|
191
|
+
| ④ 工具 | 按调用次数(或耗时)分扇区 |
|
|
192
|
+
| ⑤ 任务 | 每个后台任务一段弧,弧长 ∝ 运行时长 |
|
|
193
|
+
| ⑥ 审批 | 每次审批一根刻度,颜色表示结果 |
|
|
194
|
+
| ⑦ 变更 | 每次文件改动一根刻度,交付物更高 |
|
|
195
|
+
|
|
196
|
+
每层都能单独关掉(见下面的控件),剩下的环会自动重新分布填满空间。
|
|
197
|
+
|
|
198
|
+

|
|
199
|
+
|
|
200
|
+
## 5. 控件(左下角)
|
|
201
|
+
|
|
202
|
+
| 控件 | 作用 |
|
|
203
|
+
|---|---|
|
|
204
|
+
| `①…⑦` | 开关每一层 |
|
|
205
|
+
| `环旋转` | ②③④ 缓慢自转 |
|
|
206
|
+
| `连线` | `阶梯`(逐步链)/ `光束`(从核心射出)/ `两者都有` |
|
|
207
|
+
| `占比` | 工具环按调用**次数**还是按**耗时** |
|
|
208
|
+
| `连线轮数` | 多少轮画连线 |
|
|
209
|
+
| `显示轮数` | 整个面板覆盖多少轮(可选「全部」) |
|
|
210
|
+
| `⧉ 新窗口` | 开一个独立窗口,可以拖到副屏 |
|
|
211
|
+
| `中 / EN` | 切换语言 |
|
|
212
|
+
|
|
213
|
+
`连线轮数` 永远被 `显示轮数` 钳制——不可能连到面板没显示的轮次上。
|
|
214
|
+
|
|
215
|
+
② 环上亮与暗的区别:**暗**的格子表示它不在 `连线轮数` 范围内;**亮**但没线,说明那一步没有调用任何工具(纯文字步)。
|
|
216
|
+
|
|
217
|
+
## 6. 悬停与点击
|
|
218
|
+
|
|
219
|
+
环上每个节点都有反应:
|
|
220
|
+
|
|
221
|
+
- **悬停** —— 提示卡,显示名称和一句摘要
|
|
222
|
+
- **点击** —— 详情卡;工具还会列出**最近 6 次真实执行的命令**和耗时
|
|
223
|
+
|
|
224
|
+
## 7. 语言
|
|
225
|
+
|
|
226
|
+
界面中英双语。默认跟随 `navigator.language`,选择会记住,也可以用 `?lang=en` / `?lang=zh` 强制指定。
|
|
227
|
+
|
|
228
|
+
## 8. 当桌面壁纸用
|
|
229
|
+
|
|
230
|
+
两条路,**推荐 Lively**——它用原生内核满帧渲染。
|
|
231
|
+
|
|
232
|
+
### Lively(满帧、可交互)
|
|
233
|
+
|
|
234
|
+
1. 装 [Lively Wallpaper](https://github.com/rocksdanister/lively)(免费开源)
|
|
235
|
+
2. 下载 [`wallpaper/lively-package.zip`](wallpaper/lively-package.zip)
|
|
236
|
+
3. 把 zip 拖进 Lively,或者 **添加壁纸 → 打开文件** → 选解压后的 `index.html`
|
|
237
|
+
|
|
238
|
+
页面会自己找到插件的 `127.0.0.1:8799`;DSH 没开时显示提示并每 5 秒重试。
|
|
239
|
+
|
|
240
|
+
**桌面上可以直接操作面板**——Lively 会转发鼠标事件,环开关、轮次选择、详情卡都能在桌面上点。
|
|
241
|
+
如果这样导致桌面图标不好点,在 Lively 设置里关掉图标显示。
|
|
242
|
+
|
|
243
|
+
### Wallpaper Engine(截图模式,约 5 fps)
|
|
244
|
+
|
|
245
|
+
WE 自己的渲染器跑不动这个页面(在它的 Chrome 146 上复现,与协议无关)。替代方案是截图流水线:
|
|
246
|
+
|
|
247
|
+
```powershell
|
|
248
|
+
node wallpaper-live.cjs 200 78 # ≈4.9 fps,每帧 200 KB
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
然后把 `wallpaper/live.html` 设为 WE 的网页壁纸。低 CPU 版用 `node wallpaper-capture.cjs 8`(8 秒一帧)。
|
|
252
|
+
|
|
253
|
+

|
|
254
|
+
|
|
255
|
+
## 9. 排错
|
|
256
|
+
|
|
257
|
+
| 现象 | 原因 |
|
|
258
|
+
|---|---|
|
|
259
|
+
| 面板说"不支持 zstd" | 宿主 Node < 22.15 |
|
|
260
|
+
| 面板说会话目录是空的 | 这个 profile 还没聊过 |
|
|
261
|
+
| 空白 + 网络面板 403 | 不是本机访问;确实要远程才开 `allowRemote: true` |
|
|
262
|
+
| 暗格子没有线 | 不在「连线轮数」范围内 |
|
|
263
|
+
| 亮格子没有线 | 那一步没有工具调用 |
|
|
264
|
+
| 壁纸显示"未连接" | DSH 没开,或插件被禁用 |
|
|
265
|
+
|
|
266
|
+
## 10. 隐私与卸载
|
|
267
|
+
|
|
268
|
+
- 宿主只读 `~/.dsh/sessions/**`,在**内存里**折叠,不写任何会话文件
|
|
269
|
+
- 前后两端都不发起对外网络请求;路由只响应本机回环
|
|
270
|
+
- 卸载:插件页禁用,或 `dsh plugin remove dsh-visualization`;你的会话日志原样不动
|