tt-help-cli-ycl 1.4.62 → 1.4.64
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/package.json
CHANGED
package/src/cli/watchdog.js
CHANGED
|
@@ -21,8 +21,14 @@ export async function handleWatchdog(options) {
|
|
|
21
21
|
const serverUrl =
|
|
22
22
|
watchdogServer || clientConfig.server || "http://127.0.0.1:3001";
|
|
23
23
|
|
|
24
|
-
// 客户端 ID
|
|
25
|
-
const
|
|
24
|
+
// 客户端 ID:优先 --client-id,其次 userId@hostname,最后 hostname+pid
|
|
25
|
+
const userId = clientConfig.userId || "";
|
|
26
|
+
const hostname = os.hostname() || "";
|
|
27
|
+
const clientId =
|
|
28
|
+
watchdogClientId ||
|
|
29
|
+
(userId && hostname ? `${userId}@${hostname}` : null) ||
|
|
30
|
+
hostname ||
|
|
31
|
+
`node-${process.pid}`;
|
|
26
32
|
|
|
27
33
|
// 心跳间隔
|
|
28
34
|
const intervalSec = Math.max(5, parseInt(watchdogInterval) || 15);
|
package/src/watch/public/app.js
CHANGED
|
@@ -3475,7 +3475,10 @@ function esc(s) {
|
|
|
3475
3475
|
|
|
3476
3476
|
// ── 渲染主函数 ──
|
|
3477
3477
|
|
|
3478
|
+
var _wdLastRendered = "";
|
|
3479
|
+
|
|
3478
3480
|
function renderWatchdogDashboard(clients, clientCommands) {
|
|
3481
|
+
// 顶栏统计始终更新(textContent 不闪烁)
|
|
3479
3482
|
var onlineCount = clients.filter(function (c) {
|
|
3480
3483
|
return c.online;
|
|
3481
3484
|
}).length;
|
|
@@ -3484,27 +3487,48 @@ function renderWatchdogDashboard(clients, clientCommands) {
|
|
|
3484
3487
|
}, 0);
|
|
3485
3488
|
var cmdCount = 0;
|
|
3486
3489
|
for (var k in clientCommands) cmdCount += clientCommands[k].length;
|
|
3487
|
-
|
|
3488
3490
|
document.getElementById("wdOnlineCount").textContent = onlineCount;
|
|
3489
3491
|
document.getElementById("wdProcessCount").textContent = procCount;
|
|
3490
3492
|
document.getElementById("wdCmdCount").textContent = cmdCount;
|
|
3491
3493
|
|
|
3492
3494
|
var el = document.getElementById("wdClientsList");
|
|
3493
3495
|
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
+
// 空状态:无客户端且无配置的命令
|
|
3497
|
+
if (clients.length === 0 && cmdCount === 0) {
|
|
3498
|
+
var emptyHtml = styled(
|
|
3496
3499
|
"div",
|
|
3497
3500
|
"color:#666;padding:30px;text-align:center",
|
|
3498
3501
|
"暂无客户端连接,等待看门狗上线...(每10秒自动刷新)",
|
|
3499
3502
|
);
|
|
3503
|
+
if (_wdLastRendered !== emptyHtml) {
|
|
3504
|
+
_wdLastRendered = emptyHtml;
|
|
3505
|
+
el.innerHTML = emptyHtml;
|
|
3506
|
+
}
|
|
3500
3507
|
return;
|
|
3501
3508
|
}
|
|
3502
3509
|
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3510
|
+
// 构建 userId → 在线客户端 映射
|
|
3511
|
+
var userClients = {};
|
|
3512
|
+
clients.forEach(function (c) {
|
|
3513
|
+
var uid = (c.config && c.config.userId) || "";
|
|
3514
|
+
if (uid) userClients[uid] = c;
|
|
3515
|
+
});
|
|
3516
|
+
|
|
3517
|
+
// 收集所有卡片:在线客户端 + 离线但有命令配置的 userId
|
|
3518
|
+
var allCards = [];
|
|
3519
|
+
clients.forEach(function (c) {
|
|
3520
|
+
allCards.push(renderClientCard(c, clientCommands));
|
|
3521
|
+
});
|
|
3522
|
+
for (var uid in clientCommands) {
|
|
3523
|
+
if (!userClients[uid]) {
|
|
3524
|
+
allCards.push(renderOfflineCard(uid, clientCommands[uid]));
|
|
3525
|
+
}
|
|
3526
|
+
}
|
|
3527
|
+
|
|
3528
|
+
// 数据指纹:只有变化时才重建卡片 HTML
|
|
3529
|
+
var fingerprint = JSON.stringify(allCards);
|
|
3530
|
+
if (fingerprint === _wdLastRendered) return;
|
|
3531
|
+
_wdLastRendered = fingerprint;
|
|
3508
3532
|
|
|
3509
3533
|
el.innerHTML = styled(
|
|
3510
3534
|
"div",
|
|
@@ -3512,7 +3536,41 @@ function renderWatchdogDashboard(clients, clientCommands) {
|
|
|
3512
3536
|
style:
|
|
3513
3537
|
"display:grid;grid-template-columns:repeat(auto-fill,minmax(440px,1fr));gap:16px",
|
|
3514
3538
|
},
|
|
3515
|
-
|
|
3539
|
+
allCards.join(""),
|
|
3540
|
+
);
|
|
3541
|
+
}
|
|
3542
|
+
|
|
3543
|
+
function renderOfflineCard(userId, cmds) {
|
|
3544
|
+
var cmdCount = cmds ? cmds.length : 0;
|
|
3545
|
+
return styled(
|
|
3546
|
+
"div",
|
|
3547
|
+
"background:#1e1e2e;border:1px solid #333;border-radius:12px;padding:16px;opacity:0.7",
|
|
3548
|
+
styled(
|
|
3549
|
+
"div",
|
|
3550
|
+
"display:flex;justify-content:space-between;align-items:center;margin-bottom:8px",
|
|
3551
|
+
styled(
|
|
3552
|
+
"div",
|
|
3553
|
+
"",
|
|
3554
|
+
styled("strong", "color:#666;font-size:14px", userId) +
|
|
3555
|
+
styled(
|
|
3556
|
+
"span",
|
|
3557
|
+
"color:#555;font-size:11px;margin-left:8px",
|
|
3558
|
+
"(未上线)",
|
|
3559
|
+
),
|
|
3560
|
+
) +
|
|
3561
|
+
styled(
|
|
3562
|
+
"div",
|
|
3563
|
+
"display:flex;gap:10px;align-items:center",
|
|
3564
|
+
styled("span", "color:#f87171", "● 离线") +
|
|
3565
|
+
styled("span", "color:#555;font-size:10px", "—"),
|
|
3566
|
+
),
|
|
3567
|
+
) +
|
|
3568
|
+
styled(
|
|
3569
|
+
"div",
|
|
3570
|
+
"color:#555;font-size:10px",
|
|
3571
|
+
"该机器尚未连接看门狗,配置了 " + cmdCount + " 条命令",
|
|
3572
|
+
) +
|
|
3573
|
+
renderCmdList(cmds || [], userId),
|
|
3516
3574
|
);
|
|
3517
3575
|
}
|
|
3518
3576
|
|
|
@@ -506,6 +506,10 @@
|
|
|
506
506
|
<div class="label">命令池</div>
|
|
507
507
|
<div class="value slate" id="wdCmdCount">0</div>
|
|
508
508
|
</div>
|
|
509
|
+
<div class="stat-card clickable" onclick="fetchWatchdogData()" style="background:rgba(96,165,250,0.05)">
|
|
510
|
+
<div class="label" style="font-size:18px">🔄</div>
|
|
511
|
+
<div class="value" style="font-size:11px;color:#60a5fa">刷新</div>
|
|
512
|
+
</div>
|
|
509
513
|
</div>
|
|
510
514
|
<div id="wdClientsList" style="color:#666;font-size:12px">加载中...</div>
|
|
511
515
|
</div>
|
|
@@ -83,7 +83,12 @@ function getOnlineClients() {
|
|
|
83
83
|
|
|
84
84
|
function normalizeCmd(c) {
|
|
85
85
|
if (typeof c === "string")
|
|
86
|
-
return {
|
|
86
|
+
return {
|
|
87
|
+
cmd: c.replace(/^[▶\n\r\s]+/, "").trim(),
|
|
88
|
+
enabled: true,
|
|
89
|
+
maxUptimeSeconds: 0,
|
|
90
|
+
maxMemoryMB: 0,
|
|
91
|
+
};
|
|
87
92
|
return {
|
|
88
93
|
cmd: (c.cmd || "").replace(/^[▶\n\r\s]+/, "").trim(),
|
|
89
94
|
enabled: c.enabled !== false,
|
|
@@ -18,7 +18,7 @@ const IS_WIN = process.platform === "win32";
|
|
|
18
18
|
function getProcessStats(pid) {
|
|
19
19
|
try {
|
|
20
20
|
const cmd = IS_WIN
|
|
21
|
-
? `
|
|
21
|
+
? `powershell -NoProfile -Command "(Get-Process -Id ${pid} -ErrorAction SilentlyContinue).WorkingSet64"`
|
|
22
22
|
: `ps -p ${pid} -o rss=,etime=`;
|
|
23
23
|
const stdout = execSync(cmd, {
|
|
24
24
|
encoding: "utf-8",
|
|
@@ -28,13 +28,13 @@ function getProcessStats(pid) {
|
|
|
28
28
|
if (!stdout) return null;
|
|
29
29
|
|
|
30
30
|
if (IS_WIN) {
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
-
const memStr = (cols[4] || "").replace(/[^0-9.]/g, "");
|
|
34
|
-
const memKB = parseInt(memStr, 10);
|
|
31
|
+
// PowerShell 返回字节数,运行时长从内部 startTime 计算
|
|
32
|
+
const memBytes = parseInt(stdout, 10);
|
|
35
33
|
return {
|
|
36
|
-
memoryMB: isNaN(
|
|
37
|
-
|
|
34
|
+
memoryMB: isNaN(memBytes)
|
|
35
|
+
? 0
|
|
36
|
+
: Math.round((memBytes / 1048576) * 10) / 10,
|
|
37
|
+
elapsed: null,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
40
|
|
|
@@ -218,7 +218,21 @@ export class ProcessManager extends EventEmitter {
|
|
|
218
218
|
: "error",
|
|
219
219
|
memoryMB: stats?.memoryMB ?? 0,
|
|
220
220
|
uptimeSeconds,
|
|
221
|
-
uptimeDisplay:
|
|
221
|
+
uptimeDisplay:
|
|
222
|
+
stats?.elapsed ||
|
|
223
|
+
(function (s) {
|
|
224
|
+
var m = Math.floor(s / 60);
|
|
225
|
+
var h = Math.floor(m / 60);
|
|
226
|
+
m = m % 60;
|
|
227
|
+
s = s % 60;
|
|
228
|
+
return h > 0
|
|
229
|
+
? h +
|
|
230
|
+
":" +
|
|
231
|
+
String(m).padStart(2, "0") +
|
|
232
|
+
":" +
|
|
233
|
+
String(s).padStart(2, "0")
|
|
234
|
+
: m + ":" + String(s).padStart(2, "0");
|
|
235
|
+
})(uptimeSeconds),
|
|
222
236
|
restartCount: info.restartCount,
|
|
223
237
|
error: info.spawnError || null,
|
|
224
238
|
});
|