Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
316 lines (302 loc) · 19.7 KB
/
Copy pathindex.html
File metadata and controls
316 lines (302 loc) · 19.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ZCode 速度仪表盘</title>
</head>
<body>
<div id="app">
<header id="app-header" data-tauri-drag-region>
<div class="brand">
<img class="logo" src="/app-icon.png" alt="ZCode" />
<span>ZCode 速度仪表盘</span>
</div>
<div class="status">
<span id="live-dot" class="dot idle"></span>
<span id="live-text">待机</span>
<span class="sep">·</span>
<span id="updated-at">--:--:--</span>
<div id="float-style" class="dropdown" title="悬浮窗样式">
<button id="float-style-btn" class="ghost-btn" type="button" aria-haspopup="listbox" aria-expanded="false">
<span id="float-style-label">仪表悬浮窗</span>
<span class="caret">▾</span>
</button>
<div id="float-style-list" class="dropdown-list" role="listbox" aria-label="悬浮窗样式">
<button type="button" role="option" data-value="pet">桌宠</button>
<button type="button" role="option" data-value="gauge">仪表悬浮窗</button>
<button type="button" role="option" data-value="pill">胶囊悬浮窗</button>
</div>
</div>
<button
id="pet-last-toggle"
class="ghost-btn pet-last-toggle"
type="button"
title="桌宠气泡常驻显示两行(实时速度 / 上轮均速),待机时也显示,无需鼠标悬停;与桌宠右键菜单里的勾选是同一开关"
><span class="pet-chk" aria-hidden="true"></span>常显上轮均速</button>
<!-- 设置:模块显隐与排序(齿轮用内联 SVG,同 ⟳ 按钮——符号字形居中不可靠) -->
<button
id="btn-settings"
class="ghost-btn settings-btn"
type="button"
title="设置:勾选显示的模块、调整上下顺序(即时生效并记住)"
>
<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" fill="currentColor">
<path d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>
</svg>
</button>
<button id="btn-float" class="ghost-btn accent-btn" title="收起为悬浮窗(置顶、可拖动;点窗口关闭按钮效果相同)">⧉ 收起为悬浮窗</button>
</div>
<span id="win-controls" title="拖动顶栏移动窗口;双击顶栏最大化/还原">
<button id="wc-min" title="最小化">—</button>
<button id="wc-max" title="全屏 / 还原(mac)· 最大化 / 还原(Windows)">▢</button>
<button id="wc-close" title="收起为悬浮窗">✕</button>
</span>
</header>
<main>
<!-- 模块显隐与排序(顶栏 ⚙ 设置):每个模块包一层 module-wrap[data-module],
main.ts 按 localStorage 配置(modules.v1)重排 DOM 顺序并隐藏未勾选的模块;
wrapper 为 display:contents 不参与布局——卡片仍是 main 的直接 flex 项,
卡片间距(gap 14px)与曲线卡的 flex:1 拉伸口径都不变 -->
<div class="module-wrap" data-module="gauges">
<section class="cards">
<div class="card gauge-card">
<button
id="btn-recal"
class="ghost-btn recal-btn"
type="button"
aria-label="重新校准"
title="重新校准:丢弃已学习的字节→token 系数样本,回到默认先验由后续调用重新收敛(换模型后实时读数异常时用;轮均速突变 3 倍以上会自动触发)"
>
<!-- 图标用内联 SVG:⟳ 一类符号字形在字体里墨迹相对字宽偏心,文字渲染无法可靠居中;
取左右对称的双箭头循环(autorenew)而非单箭头 refresh——后者右侧实心箭头
与左侧细弧墨迹失衡,几何包围盒虽居中、视觉仍偏右贴边 -->
<svg viewBox="0 0 24 24" width="14" height="14" aria-hidden="true" fill="currentColor">
<path class="recal-refresh" d="M12 6V3L8 7l4 4V8c2.21 0 4 1.79 4 4 0 .58-.13 1.13-.33 1.64l1.49 1.49C17.68 14.87 18 13.97 18 12c0-3.31-2.69-6-6-6zm0 10c-2.21 0-4-1.79-4-4 0-.58.13-1.13.33-1.64L6.84 8.87C6.32 9.73 6 10.63 6 11.6c0 3.31 2.69 6 6 6v3l4-4-4-4v3z"/>
<path class="recal-done" d="M9 16.17 4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/>
</svg>
</button>
<canvas id="g-current"></canvas>
<canvas
id="g-last"
class="corner-gauge"
title="上一轮调用速度:最近一次已完成调用(输出+思考 ÷ 纯生成时长,落盘口径)"
></canvas>
<div class="sub" id="sub-current">等待数据…</div>
</div>
<div class="card gauge-card">
<canvas
id="g-peak"
class="corner-gauge corner-left"
title="近 7 天最高速度:近 7 个自然日(含今日,每日零点滑动过期)内有效输出 ≥300 token 且纯生成 ≥1s 的调用中最快一次(毫秒级小调用时间戳噪声大,不计入记录)"
></canvas>
<canvas id="g-avg"></canvas>
<canvas
id="g-histavg"
class="corner-gauge"
title="近 7 天平均速度:近 7 个自然日(含今日)内已完成调用 Σ(输出+思考) ÷ Σ纯生成时长(与今日平均同口径,不过滤,每日零点滑动过期)"
></canvas>
<div class="sub" id="sub-avg">等待数据…</div>
</div>
<div class="card gauge-card">
<canvas id="g-total"></canvas>
<div class="sub" id="sub-total">等待数据…</div>
</div>
</section>
<!-- 并发任务明细:≥2 个任务时出现(单任务时不占位)。属仪表盘模块(只在
其下方出现,不单独排序/开关)。一个 CLI 进程 = 一行;同进程内并行的
多个会话/子代理在字节层不可拆分,计为一行合计(标注会话数),按会话数
计入任务总数 -->
<section class="card task-card" id="task-card" hidden>
<div class="chart-head">
<span>并发任务(按 CLI 进程实测)</span>
<span class="dim">各行合计 = 当前速度表 · 同进程多会话计为一行</span>
</div>
<div id="task-list"></div>
</section>
</div>
<!-- 网速监控:整机接口实测速度 + 会话上传估算拆分。
按进程直测网络字节无公开原语(socket 不进进程 IO 计数、ESTATS 已坏),
口径分层:整机=真实 / 会话=token 估算(≈) -->
<div class="module-wrap" data-module="net">
<section class="card net-card" id="net-card" hidden>
<div class="chart-head">
<span>网速监控</span>
<span class="dim" id="net-scope">整机实测</span>
</div>
<!-- 单行三段:速度居左 · 进程连接数居中 · 今日上传/下载最右(窄窗自动换行) -->
<div class="net-body">
<div class="net-speeds">
<div class="net-speed up" title="整机口径:本机全部应用(含系统/浏览器/代理隧道)的网络上传,非仅 ZCode。约 1 秒滑窗平均,单位为字节;全部非回环接口求和(虚拟网卡/VPN 隧道的流量内外层各计一次)。与任务管理器对比:任务管理器显示比特(×8 ≈ 字节)且 Wi-Fi 页仅统计所选适配器,读数对不上是口径差异。ZCode 的部分见连接归属与今日累计拆分">
<span class="net-arrow">↑</span>
<div class="net-speed-body">
<span class="net-val" id="net-up-bps">--</span>
<span class="net-sub">整机上传 · 全部应用</span>
</div>
</div>
<div class="net-speed down" title="整机口径:本机全部应用(含系统/浏览器/代理隧道)的网络下载,非仅 ZCode。约 1 秒滑窗平均,单位为字节;全部非回环接口求和(虚拟网卡/VPN 隧道的流量内外层各计一次)。与任务管理器对比:任务管理器显示比特(×8 ≈ 字节)且 Wi-Fi 页仅统计所选适配器,读数对不上是口径差异。会话(模型输出)的估算值见今日下载一栏">
<span class="net-arrow">↓</span>
<div class="net-speed-body">
<span class="net-val" id="net-down-bps">--</span>
<span class="net-sub">整机下载 · 全部应用</span>
</div>
</div>
</div>
<div class="net-conns" id="net-conns" title="两组都是 ZCode 自身进程的连接(不含其他应用):会话进程 = CLI(app-server),走对话 API 流量;桌面端 = ZCode 桌面端(Electron 主/渲染/GPU/工具进程),走遥测、更新等非对话流量。悬停下方两行可看每条连接的远端与归属进程">
<span class="net-conn-row" id="net-conn-cli" title="">ZCode 会话进程 <b id="net-cli-conns">0</b> 连接</span>
<span class="net-conn-row" id="net-conn-app" title="">ZCode 桌面端 <b id="net-app-conns">0</b> 连接</span>
</div>
<div class="net-today">
<div class="net-today-row">
<span class="net-today-label">今日上传</span>
<span class="net-part">会话 ≈<b id="net-sess-up">--</b></span>
<span class="net-part" title="仅面板运行时段的接口计数差分累加,面板未运行时段不计入">整机 <b id="net-up-today">--</b></span>
</div>
<div class="net-today-row">
<span class="net-today-label">今日下载</span>
<span class="net-part">会话 ≈<b id="net-sess-down">--</b></span>
<span class="net-part" title="仅面板运行时段的接口计数差分累加,面板未运行时段不计入">整机 <b id="net-down-today">--</b></span>
</div>
</div>
</div>
</section>
</div>
<div class="module-wrap" data-module="chart">
<section class="card chart-card">
<div class="chart-head">
<span id="chart-title">近 15 分钟输出速度(10 秒一档 · token/s,横轴为真实时刻)</span>
<span class="chart-head-right">
<!-- 峰值标签在时间范围下拉左侧;下拉两视图共用:切换拨杆只换序列,
不改变统计范围 -->
<span id="chart-max" class="dim">峰值 0</span>
<div id="chart-window" class="dropdown" title="曲线时间范围(整体曲线与模型详情共用,默认 15 分钟,记住选择)">
<button id="chart-window-btn" class="ghost-btn" type="button" aria-haspopup="listbox" aria-expanded="false">
<span id="chart-window-label">15 分钟</span>
<span class="caret">▾</span>
</button>
<div id="chart-window-list" class="dropdown-list" role="listbox" aria-label="曲线时间范围">
<button type="button" role="option" data-value="15" class="selected">15 分钟</button>
<button type="button" role="option" data-value="60">1 小时</button>
<button type="button" role="option" data-value="360">6 小时</button>
<button type="button" role="option" data-value="1440">24 小时</button>
</div>
</div>
<!-- 分段拨杆:整体曲线 / 模型详情两个视图互斥切换(记住选择)。
文字分居左右,色块滑到激活一侧 -->
<button id="chart-view-toggle" class="view-toggle" type="button" role="switch" aria-checked="false" title="切换曲线卡视图:整体输出速度曲线 / 模型速度趋势(互斥显示,共用时间范围,记住选择)">
<span class="vt-knob" aria-hidden="true"></span>
<span class="vt-opt">整体曲线</span>
<span class="vt-opt">模型详情</span>
</button>
</span>
</div>
<canvas id="spark"></canvas>
<!-- 模型详情视图:图例 chips + 按模型折线 + 统计条,与 #spark 互斥 -->
<div id="model-view">
<div id="model-legend"></div>
<div id="model-chart-wrap">
<canvas id="model-chart"></canvas>
<div id="model-empty">窗口内暂无调用数据</div>
</div>
<div id="model-summary"></div>
</div>
</section>
</div>
<!-- 全部模块都被隐藏时的占位(设置按钮在顶栏,始终可再打开) -->
<div id="modules-empty" hidden>所有模块都已隐藏 · 点顶栏 ⚙ 重新开启</div>
<footer class="dim" id="statusbar">
<span id="st-dir">监控目录:…</span>
<span id="st-calls"></span>
<span id="st-sessions"></span>
<span id="st-last"></span>
<span id="st-version" title="点击检查更新">v…</span>
</footer>
</main>
<!-- 悬浮窗·桌宠样式(默认):精灵动画 + 头顶速度气泡,整块可拖动,右键出菜单 -->
<div id="float-pet">
<canvas id="pet-canvas"></canvas>
<button id="float-pet-cycle" class="float-expand ghost-btn" title="换一只宠物" style="right: 34px;">🔄</button>
<button id="float-pet-expand" class="float-expand ghost-btn" title="展开完整面板">⤢</button>
</div>
<!-- 悬浮窗·仪表样式:主环(实时)+ 右上角"上轮"小环(最近一轮已完成调用) -->
<div id="float-gauge">
<canvas id="mini-gauge"></canvas>
<canvas
id="mini-last"
class="float-badge"
title="上轮均速:最近一次已完成调用(输出+思考 ÷ 纯生成时长,落盘口径)"
></canvas>
<button id="float-gauge-expand" class="float-expand ghost-btn" title="展开完整面板">⤢</button>
</div>
<!-- 悬浮窗·胶囊样式:整块可拖动,⤢ 展开;第二行为上轮均速 -->
<div id="float-pill">
<span id="float-dot" class="dot idle"></span>
<div id="float-val">
<div class="float-val">
<span id="float-approx">≈</span>
<span id="float-tps">0.0</span>
<span class="float-unit">t/s</span>
</div>
<div class="float-sub">
<span class="float-sub-label">上轮均速</span>
<span id="float-last">--</span>
<span class="float-unit">t/s</span>
</div>
</div>
<button id="float-pill-expand" class="float-expand ghost-btn" title="展开完整面板">⤢</button>
</div>
<!-- 悬浮窗右键菜单:恢复窗体 / 退出;桌宠样式下多一项"常显上轮均速"勾选(CSS 按样式门控) -->
<div id="float-menu">
<button
id="float-menu-pet-last"
title="勾选后气泡常驻显示两行(实时速度 / 上轮均速),待机时也显示,无需鼠标悬停"
><span class="pet-chk" aria-hidden="true"></span>常显上轮均速</button>
<button id="float-menu-restore">⤢ 恢复窗体</button>
<button id="float-menu-quit">✕ 退出程序</button>
</div>
<!-- mac 引导提示:应用常驻菜单栏(无 Dock 图标),窗口每次从隐藏到显示时出现,6 秒自动淡出 -->
<div id="tray-hint" title="点击关闭">应用常驻菜单栏 ↗ 点菜单栏图标可显示面板 / 退出</div>
<!-- 设置弹窗:模块显隐与排序 + 自动启动(顶栏 ⚙ 打开;复用弹窗的遮罩+卡片风格)。
行由 main.ts 按 MODULE_DEFS 动态渲染:自绘勾选框(.pet-chk 同款)+ ↑↓ 排序,
变更即时生效并存 localStorage(modules.v1);自动启动三态行也由 main.ts 渲染,
读写后端命令(Windows 注册表 / mac LaunchAgent 即事实源,不存 localStorage) -->
<div id="settings-modal">
<div id="settings-modal-box">
<div class="model-modal-head">
<span class="model-modal-title">设置</span>
<button id="settings-reset" class="ghost-btn" type="button" title="恢复默认:仪表盘 / 网速监控 / 输出速度曲线全部显示,顺序还原(自动启动不受影响)">恢复默认</button>
<button id="settings-close" class="ghost-btn" type="button" title="关闭">✕</button>
</div>
<div class="settings-section-title">显示模块</div>
<div id="settings-hint" class="dim">勾选要显示的模块;↑↓ 调整顺序(列表从上到下 = 面板从上到下)。即时生效并记住。</div>
<div id="settings-modules"></div>
<div class="settings-section-title">自动启动</div>
<div id="settings-autostart"></div>
<div id="settings-autostart-note" class="dim">开机自启 = 登录后按上次形态常驻启动;跟随 ZCode = 登录后静默待命(仅托盘),检测到 ZCode 正在运行时自动亮出面板。面板手动退出后不再自动复活,重新登录或手动打开恢复。</div>
</div>
</div>
<!-- 应用内更新:发现新版本时的提示卡片(右下角,版本号在 footer 最右、点击即检查);
下载进度与安装状态都在这张卡上 -->
<div id="update-card" role="dialog" aria-label="应用更新">
<div class="update-head">
<span>🆕 发现新版本 <b id="update-version"></b></span>
<button id="update-close" title="暂不更新(下次检查到更新仍会提醒)">✕</button>
</div>
<div class="update-sub">当前 <span id="update-current"></span> · <a id="update-link" title="在浏览器中打开更新说明">更新内容 ↗</a></div>
<pre id="update-notes" class="update-notes"></pre>
<div id="update-progress" class="update-progress">
<div class="update-bar"><i id="update-bar-fill"></i></div>
<span id="update-progress-text"></span>
</div>
<div class="update-actions">
<button id="update-install" class="ghost-btn accent-btn" type="button">⤓ 立即更新</button>
<button id="update-manual" class="ghost-btn" type="button" title="在浏览器打开本版本页面,自行下载安装">手动下载 ↗</button>
<span id="update-status"></span>
</div>
</div>
<!-- 手动检查更新的轻提示(已是最新/失败),自动消失 -->
<div id="update-toast"></div>
</div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>