@wendongfly/myhi 1.0.57 → 1.0.59
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/dist/chat.html +29 -19
- package/dist/index.html +20 -47
- package/package.json +1 -1
package/dist/chat.html
CHANGED
|
@@ -224,14 +224,14 @@
|
|
|
224
224
|
<div id="status-bar">
|
|
225
225
|
<span class="sb-item" id="work-status"><span class="sb-dot idle"></span> 空闲</span>
|
|
226
226
|
<span id="mode-badge" onclick="switchMode()">默认</span>
|
|
227
|
-
<span id="control-badge" class="readonly"
|
|
227
|
+
<span id="control-badge" class="readonly" style="display:none">只读</span>
|
|
228
228
|
<span id="viewer-count" class="sb-item"></span>
|
|
229
229
|
</div>
|
|
230
230
|
|
|
231
231
|
<div id="chat-area"></div>
|
|
232
232
|
|
|
233
233
|
<div id="input-area">
|
|
234
|
-
<div id="readonly-overlay"
|
|
234
|
+
<div id="readonly-overlay" style="display:none"></div>
|
|
235
235
|
<div id="input-box">
|
|
236
236
|
<div id="img-preview">
|
|
237
237
|
<img id="img-preview-thumb" src="" alt="">
|
|
@@ -340,36 +340,46 @@
|
|
|
340
340
|
try {
|
|
341
341
|
const res = await fetch('/api/usage');
|
|
342
342
|
const data = await res.json();
|
|
343
|
-
|
|
344
|
-
|
|
343
|
+
const C = 'style="margin-bottom:1rem;padding:0.8rem 1rem;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);border-radius:10px"';
|
|
344
|
+
const H = 'style="font-size:0.9rem;font-weight:700;margin-bottom:0.5rem;color:#e6edf3"';
|
|
345
|
+
const T = 'style="font-size:0.82rem;color:#b1bac4;line-height:1.6"';
|
|
346
|
+
let html = '<div style="padding:1.5rem">';
|
|
347
|
+
html += '<h3 style="margin:0 0 1.2rem;font-size:1.1rem;color:#fff;text-align:center">Claude 用量统计</h3>';
|
|
345
348
|
if (data.rateLimit) {
|
|
346
349
|
const rl = data.rateLimit;
|
|
347
350
|
const remaining = Math.max(0, Math.ceil((new Date(rl.resetsAt * 1000) - Date.now()) / 60000));
|
|
348
|
-
|
|
349
|
-
html +=
|
|
350
|
-
html += `<div style="font-
|
|
351
|
+
const statusColor = rl.status === 'allowed' ? '#3fb950' : '#f85149';
|
|
352
|
+
html += `<div ${C}><div ${H}>5小时窗口</div>`;
|
|
353
|
+
html += `<div ${T}><span style="color:${statusColor};font-weight:600">${rl.status === 'allowed' ? '● 正常' : '● 受限'}</span> 重置: ${remaining} 分钟后</div></div>`;
|
|
354
|
+
} else {
|
|
355
|
+
html += `<div ${C}><div ${H}>5小时窗口</div><div ${T}>发送 Agent 消息后可查看</div></div>`;
|
|
351
356
|
}
|
|
352
357
|
if (data.sevenDay) {
|
|
353
358
|
const s = data.sevenDay;
|
|
354
|
-
html +=
|
|
355
|
-
html +=
|
|
356
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">消息: ${s.messageCount.toLocaleString()} 会话: ${s.sessionCount} 工具: ${s.toolCallCount.toLocaleString()}</div></div>`;
|
|
359
|
+
html += `<div ${C}><div ${H}>近 7 天</div>`;
|
|
360
|
+
html += `<div ${T}>消息 <b style="color:#e6edf3">${s.messageCount.toLocaleString()}</b> 会话 <b style="color:#e6edf3">${s.sessionCount}</b> 工具调用 <b style="color:#e6edf3">${s.toolCallCount.toLocaleString()}</b></div></div>`;
|
|
357
361
|
}
|
|
358
362
|
if (data.activeSessions?.length) {
|
|
359
|
-
html +=
|
|
360
|
-
html += '<div style="font-size:0.85rem;font-weight:600;margin-bottom:0.4rem">当前会话</div>';
|
|
363
|
+
html += `<div ${C}><div ${H}>当前活跃会话</div>`;
|
|
361
364
|
for (const s of data.activeSessions) {
|
|
362
365
|
if (!s.usage) continue;
|
|
363
|
-
html += `<div
|
|
366
|
+
html += `<div ${T}>${s.title} <b style="color:#e6edf3">${s.usage.queryCount}</b> 次查询 <b style="color:#e6edf3">$${s.usage.totalCostUSD.toFixed(4)}</b></div>`;
|
|
364
367
|
}
|
|
365
368
|
html += '</div>';
|
|
366
369
|
}
|
|
367
|
-
|
|
370
|
+
if (data.totalStats) {
|
|
371
|
+
const t = data.totalStats;
|
|
372
|
+
html += `<div ${C}><div ${H}>累计(截至 ${t.lastComputedDate || '未知'})</div>`;
|
|
373
|
+
html += `<div ${T}>总会话 <b style="color:#e6edf3">${t.totalSessions}</b> 总消息 <b style="color:#e6edf3">${t.totalMessages?.toLocaleString()}</b></div>`;
|
|
374
|
+
if (t.modelUsage) { for (const [m, u] of Object.entries(t.modelUsage)) { if (u.outputTokens > 0) html += `<div style="font-size:0.75rem;color:#8b949e;margin-top:0.3rem">${m.replace(/claude-/,'').replace(/-\d{8}$/,'')} 输入 ${(u.inputTokens/1000).toFixed(0)}K 输出 ${(u.outputTokens/1000).toFixed(0)}K</div>`; } }
|
|
375
|
+
html += '</div>';
|
|
376
|
+
}
|
|
377
|
+
html += '<button onclick="this.parentElement.parentElement.remove()" style="margin-top:0.8rem;width:100%;padding:0.7rem;background:#7c3aed;color:#fff;border:none;border-radius:10px;cursor:pointer;font-size:0.9rem;font-weight:600">关闭</button></div>';
|
|
368
378
|
const overlay = document.createElement('div');
|
|
369
|
-
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.
|
|
379
|
+
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:999;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(4px)';
|
|
370
380
|
overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
|
|
371
381
|
const box = document.createElement('div');
|
|
372
|
-
box.style.cssText = 'background:
|
|
382
|
+
box.style.cssText = 'background:#161b22;border:1px solid rgba(255,255,255,0.12);border-radius:16px;max-height:80vh;overflow-y:auto;width:90%;max-width:420px;box-shadow:0 16px 48px rgba(0,0,0,0.4)';
|
|
373
383
|
box.innerHTML = html;
|
|
374
384
|
overlay.appendChild(box);
|
|
375
385
|
document.body.appendChild(overlay);
|
|
@@ -1354,7 +1364,7 @@
|
|
|
1354
1364
|
};
|
|
1355
1365
|
function selectModel(m) {
|
|
1356
1366
|
closeModelSheet();
|
|
1357
|
-
if (!isController) { addStatusMessage('
|
|
1367
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1358
1368
|
if (currentSession?.mode === 'agent') {
|
|
1359
1369
|
// Agent 模式:通过命令设置
|
|
1360
1370
|
cmdInput.value = '/model ' + m.id;
|
|
@@ -1374,7 +1384,7 @@
|
|
|
1374
1384
|
|
|
1375
1385
|
// ── 恢复会话 ──────────────────────────────────
|
|
1376
1386
|
window.openResumeSheet = async function() {
|
|
1377
|
-
if (!isController) { addStatusMessage('
|
|
1387
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1378
1388
|
const list = document.getElementById('resume-list');
|
|
1379
1389
|
list.innerHTML = '<div style="text-align:center;padding:1rem;color:#8b949e">加载中...</div>';
|
|
1380
1390
|
document.getElementById('resume-sheet').classList.add('open');
|
|
@@ -1422,7 +1432,7 @@
|
|
|
1422
1432
|
|
|
1423
1433
|
// ── 压缩对话 ──────────────────────────────────
|
|
1424
1434
|
window.doCompact = function() {
|
|
1425
|
-
if (!isController) { addStatusMessage('
|
|
1435
|
+
if (!isController) { if (canTakeControl()) socket.emit('take-control', { sessionId: SESSION_ID }); else { addStatusMessage('其他用户控制中'); return; } }
|
|
1426
1436
|
if (currentSession?.mode === 'agent') {
|
|
1427
1437
|
cmdInput.value = '/compact';
|
|
1428
1438
|
sendCommand();
|
package/dist/index.html
CHANGED
|
@@ -529,73 +529,46 @@
|
|
|
529
529
|
try {
|
|
530
530
|
const res = await fetch('/api/usage');
|
|
531
531
|
const data = await res.json();
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
532
|
+
const C = 'style="margin-bottom:1rem;padding:0.8rem 1rem;background:rgba(255,255,255,0.06);border:1px solid rgba(255,255,255,0.1);border-radius:10px"';
|
|
533
|
+
const H = 'style="font-size:0.9rem;font-weight:700;margin-bottom:0.5rem;color:#e6edf3"';
|
|
534
|
+
const T = 'style="font-size:0.82rem;color:#b1bac4;line-height:1.6"';
|
|
535
|
+
let html = '<div style="padding:1.5rem">';
|
|
536
|
+
html += '<h3 style="margin:0 0 1.2rem;font-size:1.1rem;color:#fff;text-align:center">Claude 用量统计</h3>';
|
|
536
537
|
if (data.rateLimit) {
|
|
537
538
|
const rl = data.rateLimit;
|
|
538
|
-
const
|
|
539
|
-
const
|
|
540
|
-
html +=
|
|
541
|
-
html +=
|
|
542
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">状态: ${rl.status === 'allowed' ? '✓ 正常' : '⚠ 受限'}</div>`;
|
|
543
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">重置时间: ${remaining} 分钟后</div>`;
|
|
544
|
-
html += '</div>';
|
|
539
|
+
const remaining = Math.max(0, Math.ceil((new Date(rl.resetsAt * 1000) - Date.now()) / 60000));
|
|
540
|
+
const statusColor = rl.status === 'allowed' ? '#3fb950' : '#f85149';
|
|
541
|
+
html += `<div ${C}><div ${H}>5小时窗口</div>`;
|
|
542
|
+
html += `<div ${T}><span style="color:${statusColor};font-weight:600">${rl.status === 'allowed' ? '● 正常' : '● 受限'}</span> 重置: ${remaining} 分钟后</div></div>`;
|
|
545
543
|
} else {
|
|
546
|
-
html +=
|
|
547
|
-
html += '<div style="font-size:0.85rem;color:var(--muted)">5小时窗口: 发送一条 Agent 消息后可查看</div></div>';
|
|
544
|
+
html += `<div ${C}><div ${H}>5小时窗口</div><div ${T}>发送 Agent 消息后可查看</div></div>`;
|
|
548
545
|
}
|
|
549
|
-
|
|
550
|
-
// 7天用量
|
|
551
546
|
if (data.sevenDay) {
|
|
552
547
|
const s = data.sevenDay;
|
|
553
|
-
html +=
|
|
554
|
-
html +=
|
|
555
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">消息: ${s.messageCount.toLocaleString()}</div>`;
|
|
556
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">会话: ${s.sessionCount}</div>`;
|
|
557
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">工具调用: ${s.toolCallCount.toLocaleString()}</div>`;
|
|
558
|
-
html += '</div>';
|
|
548
|
+
html += `<div ${C}><div ${H}>近 7 天</div>`;
|
|
549
|
+
html += `<div ${T}>消息 <b style="color:#e6edf3">${s.messageCount.toLocaleString()}</b> 会话 <b style="color:#e6edf3">${s.sessionCount}</b> 工具调用 <b style="color:#e6edf3">${s.toolCallCount.toLocaleString()}</b></div></div>`;
|
|
559
550
|
}
|
|
560
|
-
|
|
561
|
-
// 活跃会话用量
|
|
562
551
|
if (data.activeSessions?.length) {
|
|
563
|
-
html +=
|
|
564
|
-
html += '<div style="font-size:0.85rem;font-weight:600;margin-bottom:0.4rem">当前会话</div>';
|
|
552
|
+
html += `<div ${C}><div ${H}>当前活跃会话</div>`;
|
|
565
553
|
for (const s of data.activeSessions) {
|
|
566
554
|
if (!s.usage) continue;
|
|
567
|
-
|
|
568
|
-
html += `<div style="font-size:0.8rem;color:var(--muted);margin-top:0.3rem">${s.title}: ${u.queryCount}次查询, $${u.totalCostUSD.toFixed(4)}</div>`;
|
|
555
|
+
html += `<div ${T}>${s.title} <b style="color:#e6edf3">${s.usage.queryCount}</b> 次查询 <b style="color:#e6edf3">$${s.usage.totalCostUSD.toFixed(4)}</b></div>`;
|
|
569
556
|
}
|
|
570
557
|
html += '</div>';
|
|
571
558
|
}
|
|
572
|
-
|
|
573
|
-
// 累计总量
|
|
574
559
|
if (data.totalStats) {
|
|
575
560
|
const t = data.totalStats;
|
|
576
|
-
html +=
|
|
577
|
-
html +=
|
|
578
|
-
html += `<div style="font-size:0.
|
|
579
|
-
html += `<div style="font-size:0.8rem;color:var(--muted)">总消息: ${t.totalMessages?.toLocaleString()}</div>`;
|
|
580
|
-
if (t.modelUsage) {
|
|
581
|
-
for (const [model, u] of Object.entries(t.modelUsage)) {
|
|
582
|
-
if (u.outputTokens > 0) {
|
|
583
|
-
const shortName = model.replace(/claude-/, '').replace(/-\d{8}$/, '');
|
|
584
|
-
html += `<div style="font-size:0.75rem;color:var(--muted);margin-top:0.2rem">${shortName}: 输入${(u.inputTokens/1000).toFixed(0)}K 输出${(u.outputTokens/1000).toFixed(0)}K</div>`;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
}
|
|
561
|
+
html += `<div ${C}><div ${H}>累计(截至 ${t.lastComputedDate || '未知'})</div>`;
|
|
562
|
+
html += `<div ${T}>总会话 <b style="color:#e6edf3">${t.totalSessions}</b> 总消息 <b style="color:#e6edf3">${t.totalMessages?.toLocaleString()}</b></div>`;
|
|
563
|
+
if (t.modelUsage) { for (const [m, u] of Object.entries(t.modelUsage)) { if (u.outputTokens > 0) html += `<div style="font-size:0.75rem;color:#8b949e;margin-top:0.3rem">${m.replace(/claude-/,'').replace(/-\d{8}$/,'')} 输入 ${(u.inputTokens/1000).toFixed(0)}K 输出 ${(u.outputTokens/1000).toFixed(0)}K</div>`; } }
|
|
588
564
|
html += '</div>';
|
|
589
565
|
}
|
|
590
|
-
|
|
591
|
-
html += '<button onclick="this.parentElement.parentElement.remove()" style="margin-top:1rem;width:100%;padding:0.6rem;background:var(--accent);color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:0.85rem">关闭</button>';
|
|
592
|
-
html += '</div>';
|
|
593
|
-
|
|
566
|
+
html += '<button onclick="this.parentElement.parentElement.remove()" style="margin-top:0.8rem;width:100%;padding:0.7rem;background:#7c3aed;color:#fff;border:none;border-radius:10px;cursor:pointer;font-size:0.9rem;font-weight:600">关闭</button></div>';
|
|
594
567
|
const overlay = document.createElement('div');
|
|
595
|
-
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.
|
|
568
|
+
overlay.style.cssText = 'position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.6);z-index:999;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(4px)';
|
|
596
569
|
overlay.onclick = (e) => { if (e.target === overlay) overlay.remove(); };
|
|
597
570
|
const box = document.createElement('div');
|
|
598
|
-
box.style.cssText = 'background:
|
|
571
|
+
box.style.cssText = 'background:#161b22;border:1px solid rgba(255,255,255,0.12);border-radius:16px;max-height:80vh;overflow-y:auto;width:90%;max-width:420px;box-shadow:0 16px 48px rgba(0,0,0,0.4)';
|
|
599
572
|
box.innerHTML = html;
|
|
600
573
|
overlay.appendChild(box);
|
|
601
574
|
document.body.appendChild(overlay);
|