dsh-remote-panel 0.3.8 → 0.4.0
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/lib/client.js +83 -44
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -1174,52 +1174,35 @@ window.__ModuleLoader__.load({
|
|
|
1174
1174
|
问候语留在屏幕中间(原生居中),输入条钉到底部 */
|
|
1175
1175
|
/* 输入条下方那排统计(轮次/步数、token、缓存):手机上会撑高输入区,
|
|
1176
1176
|
按「托盘状态」的思路挪到右上角,做成一行半透明小字,不再占输入条的垂直空间 */
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
align-items: center
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
line-height: 15px !important;
|
|
1199
|
-
z-index: 56 !important;
|
|
1200
|
-
overflow: hidden !important;
|
|
1201
|
-
transform: none !important;
|
|
1202
|
-
}
|
|
1203
|
-
/* 前两颗外面那层是 display:contents,Chrome 里不参与 flex 计算,实体化才能并排 */
|
|
1204
|
-
.uV2eYG_dock > div {
|
|
1205
|
-
display: flex !important;
|
|
1206
|
-
align-items: center !important;
|
|
1207
|
-
gap: 8px !important;
|
|
1208
|
-
min-width: 0 !important;
|
|
1177
|
+
/* 原生的统计条藏在输入条下方、文案又长,手机上只能挤;这里整体隐藏,
|
|
1178
|
+
由 installStatsTray() 读它的文本、精简后放到顶部右上角 */
|
|
1179
|
+
.uV2eYG_dock { display: none !important; }
|
|
1180
|
+
|
|
1181
|
+
/* 顶部状态条:左边分支、右边统计,两端对齐(像手机状态栏的左右两组) */
|
|
1182
|
+
.dsh-stats-tray {
|
|
1183
|
+
position: fixed;
|
|
1184
|
+
top: max(2px, calc(var(--dsh-safe-top, 0px) - 24px));
|
|
1185
|
+
left: 14px;
|
|
1186
|
+
right: 14px;
|
|
1187
|
+
z-index: 57;
|
|
1188
|
+
display: flex;
|
|
1189
|
+
align-items: center;
|
|
1190
|
+
justify-content: space-between;
|
|
1191
|
+
gap: 16px;
|
|
1192
|
+
font-size: 10px;
|
|
1193
|
+
line-height: 16px;
|
|
1194
|
+
font-variant-numeric: tabular-nums;
|
|
1195
|
+
color: rgba(255, 255, 255, .5);
|
|
1196
|
+
pointer-events: none;
|
|
1197
|
+
letter-spacing: .01em;
|
|
1209
1198
|
}
|
|
1210
|
-
.
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
text-overflow: clip !important;
|
|
1216
|
-
white-space: nowrap !important;
|
|
1199
|
+
.dsh-stats-tray > span {
|
|
1200
|
+
overflow: hidden;
|
|
1201
|
+
text-overflow: ellipsis;
|
|
1202
|
+
white-space: nowrap;
|
|
1203
|
+
min-width: 0;
|
|
1217
1204
|
}
|
|
1218
|
-
|
|
1219
|
-
[data-composer-stat="git-branch"] { display: none !important; }
|
|
1220
|
-
.uV2eYG_dock > span[class*="_root"] { display: none !important; }
|
|
1221
|
-
/* 没有统计时不渲染空壳(hero 页就是这样) */
|
|
1222
|
-
.uV2eYG_dock:empty { display: none !important; }
|
|
1205
|
+
.dsh-stats-tray > span:last-child { text-align: right; flex: 0 0 auto; }
|
|
1223
1206
|
|
|
1224
1207
|
/* 输入条座位顶部有一段渐隐(DSH 原本渐到 #151517),在纯黑底上会显出一条灰带,
|
|
1225
1208
|
这里把终点色换成纯黑,观感才对得上;底部那行状态(轮次/token/缓存)同理 */
|
|
@@ -1708,6 +1691,60 @@ window.__ModuleLoader__.load({
|
|
|
1708
1691
|
}
|
|
1709
1692
|
|
|
1710
1693
|
|
|
1694
|
+
/**
|
|
1695
|
+
* 顶部统计托盘:DSH 的统计条文案太长(「2 轮 8 步 · 211 tok/s」「1.7M tok · 缓存命中 99%」),
|
|
1696
|
+
* 手机上一行放不下。这里读它的文本、精简成 `2 轮 · 211 tok/s · 缓存 99%` 放到右上角,
|
|
1697
|
+
* 原条隐藏,既省高度又不挤。
|
|
1698
|
+
*/
|
|
1699
|
+
function installStatsTray() {
|
|
1700
|
+
if (typeof document === 'undefined' || typeof MutationObserver === 'undefined') return () => {}
|
|
1701
|
+
const tray = document.createElement('div')
|
|
1702
|
+
tray.className = 'dsh-stats-tray'
|
|
1703
|
+
tray.setAttribute('aria-hidden', 'true')
|
|
1704
|
+
const left = document.createElement('span')
|
|
1705
|
+
const right = document.createElement('span')
|
|
1706
|
+
tray.append(left, right)
|
|
1707
|
+
document.body.appendChild(tray)
|
|
1708
|
+
|
|
1709
|
+
let frame = 0
|
|
1710
|
+
let shown = ''
|
|
1711
|
+
const format = (text) => {
|
|
1712
|
+
const rounds = text.match(/(\d+)\s*轮/)
|
|
1713
|
+
const speed = text.match(/([\d.]+)\s*tok\/s/i)
|
|
1714
|
+
const cache = text.match(/(\d+(?:\.\d+)?)\s*%/)
|
|
1715
|
+
const parts = []
|
|
1716
|
+
if (rounds !== null) parts.push(`${rounds[1]} 轮`)
|
|
1717
|
+
if (speed !== null) parts.push(`${speed[1]} tok/s`)
|
|
1718
|
+
if (cache !== null) parts.push(`缓存 ${cache[1]}%`)
|
|
1719
|
+
return parts.join(' · ')
|
|
1720
|
+
}
|
|
1721
|
+
const sync = () => {
|
|
1722
|
+
frame = 0
|
|
1723
|
+
const dock = document.querySelector('.uV2eYG_dock')
|
|
1724
|
+
const raw = dock?.textContent ?? ''
|
|
1725
|
+
const branch = dock?.querySelector('[data-composer-stat="git-branch"]')?.textContent?.trim() ?? ''
|
|
1726
|
+
const stats = raw.trim() === '' ? '' : format(raw)
|
|
1727
|
+
const next = `${branch}|${stats}`
|
|
1728
|
+
if (next === shown) return
|
|
1729
|
+
shown = next
|
|
1730
|
+
left.textContent = branch
|
|
1731
|
+
right.textContent = stats
|
|
1732
|
+
tray.style.display = branch === '' && stats === '' ? 'none' : 'flex'
|
|
1733
|
+
}
|
|
1734
|
+
const schedule = () => {
|
|
1735
|
+
if (frame !== 0) return
|
|
1736
|
+
frame = requestAnimationFrame(sync)
|
|
1737
|
+
}
|
|
1738
|
+
const observer = new MutationObserver(schedule)
|
|
1739
|
+
observer.observe(document.body, { subtree: true, childList: true, characterData: true })
|
|
1740
|
+
sync()
|
|
1741
|
+
return () => {
|
|
1742
|
+
observer.disconnect()
|
|
1743
|
+
if (frame !== 0) cancelAnimationFrame(frame)
|
|
1744
|
+
tray.remove()
|
|
1745
|
+
}
|
|
1746
|
+
}
|
|
1747
|
+
|
|
1711
1748
|
/**
|
|
1712
1749
|
* 外壳挂点自检:DSH 升级后这些 hash 类名可能全变,样式就整体失配。
|
|
1713
1750
|
* 启动后检查一遍 DOM,把结果报给宿主,面板里能直接看到「外壳适配」这盏灯。
|
|
@@ -2349,6 +2386,7 @@ window.__ModuleLoader__.load({
|
|
|
2349
2386
|
const cleanupFocus = installComposerFocusGuard()
|
|
2350
2387
|
const cleanupFps = installFpsMeter()
|
|
2351
2388
|
const cleanupContract = installShellContractReport()
|
|
2389
|
+
const cleanupTray = installStatsTray()
|
|
2352
2390
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupClear, 'remote-panel: workspace clear')
|
|
2353
2391
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupBack, 'remote-panel: back gesture')
|
|
2354
2392
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupAttention, 'remote-panel: attention')
|
|
@@ -2357,6 +2395,7 @@ window.__ModuleLoader__.load({
|
|
|
2357
2395
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupFocus, 'remote-panel: composer focus guard')
|
|
2358
2396
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupFps, 'remote-panel: fps meter')
|
|
2359
2397
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupContract, 'remote-panel: shell contract report')
|
|
2398
|
+
if (typeof ctx.effect === 'function') ctx.effect(() => cleanupTray, 'remote-panel: stats tray')
|
|
2360
2399
|
if (typeof ctx.effect === 'function') ctx.effect(() => cleanup, 'remote-panel: mobile shell css')
|
|
2361
2400
|
|
|
2362
2401
|
ctx.slots.inject('shell.overlay', () =>
|