tt-help-cli-ycl 1.4.80 → 1.4.83
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 +1 -1
- package/src/clash/api.js +31 -0
- package/src/clash/benchmark/lib/clash-api.js +234 -0
- package/src/clash/benchmark/speedtest-result.json +431 -0
- package/src/clash/benchmark/speedtest-tiktok.mjs +384 -0
- package/src/clash/checker.js +178 -41
- package/src/clash/daemon.js +62 -94
- package/src/cli/clash-daemon.js +1 -1
- package/src/cli/watchdog.js +8 -1
- package/src/lib/args.js +6 -2
- package/src/lib/constants.js +4 -3
- package/src/watchdog/agent.js +52 -13
package/src/lib/args.js
CHANGED
|
@@ -629,6 +629,7 @@ function parseWatchdogArgs(args) {
|
|
|
629
629
|
let watchdogServer = null;
|
|
630
630
|
let watchdogInterval = 15;
|
|
631
631
|
let watchdogClientId = null;
|
|
632
|
+
let watchdogNoDaemon = false;
|
|
632
633
|
|
|
633
634
|
for (let i = 0; i < args.length; i++) {
|
|
634
635
|
const arg = args[i];
|
|
@@ -638,6 +639,8 @@ function parseWatchdogArgs(args) {
|
|
|
638
639
|
watchdogInterval = parseInt(args[++i]) || 15;
|
|
639
640
|
} else if (arg === "--client-id") {
|
|
640
641
|
watchdogClientId = args[++i];
|
|
642
|
+
} else if (arg === "--no-daemon") {
|
|
643
|
+
watchdogNoDaemon = true;
|
|
641
644
|
}
|
|
642
645
|
}
|
|
643
646
|
|
|
@@ -646,6 +649,7 @@ function parseWatchdogArgs(args) {
|
|
|
646
649
|
watchdogServer,
|
|
647
650
|
watchdogInterval,
|
|
648
651
|
watchdogClientId,
|
|
652
|
+
watchdogNoDaemon,
|
|
649
653
|
urls: [],
|
|
650
654
|
outputFormat: "json",
|
|
651
655
|
exploreCount: 0,
|
|
@@ -660,7 +664,7 @@ function parseWatchdogArgs(args) {
|
|
|
660
664
|
}
|
|
661
665
|
|
|
662
666
|
function parseClashDaemonArgs(args) {
|
|
663
|
-
let interval =
|
|
667
|
+
let interval = 120;
|
|
664
668
|
let benchmark = 40;
|
|
665
669
|
let dryRun = false;
|
|
666
670
|
let country = null;
|
|
@@ -668,7 +672,7 @@ function parseClashDaemonArgs(args) {
|
|
|
668
672
|
for (let i = 0; i < args.length; i++) {
|
|
669
673
|
const arg = args[i];
|
|
670
674
|
if (arg === "--interval") {
|
|
671
|
-
interval = parseInt(args[++i]) ||
|
|
675
|
+
interval = parseInt(args[++i]) || 120;
|
|
672
676
|
} else if (arg === "--benchmark") {
|
|
673
677
|
benchmark = parseInt(args[++i]) || 40;
|
|
674
678
|
} else if (arg === "--country") {
|
package/src/lib/constants.js
CHANGED
|
@@ -383,6 +383,7 @@ const HELP_TEXT = [
|
|
|
383
383
|
" --server <URL>, -s 服务端地址(默认使用 ~/.tt-help.json 中的 server)",
|
|
384
384
|
" --interval <秒>, -i 心跳间隔,默认 15 秒(最小 5 秒)",
|
|
385
385
|
" --client-id <ID> 客户端标识(默认本机 hostname)",
|
|
386
|
+
" --no-daemon 不启动 clash daemon(默认启动)",
|
|
386
387
|
" 示例: tt-help watchdog",
|
|
387
388
|
" tt-help watchdog --server http://117.71.53.99:17301",
|
|
388
389
|
" tt-help watchdog -i 30 --client-id my-server-01",
|
|
@@ -391,8 +392,8 @@ const HELP_TEXT = [
|
|
|
391
392
|
" Clash Verge 代理节点健康守护:定时巡检 TikTok 可达性,异常时自动切换节点",
|
|
392
393
|
" 看门狗启动时会自动拉起此守护进程",
|
|
393
394
|
" 选项:",
|
|
394
|
-
" --interval <秒> 巡检间隔,默认
|
|
395
|
-
" --benchmark <分钟>
|
|
395
|
+
" --interval <秒> 巡检间隔,默认 120 秒(2分钟)",
|
|
396
|
+
" --benchmark <分钟> 候选集 delay 初测间隔,默认 40 分钟",
|
|
396
397
|
" --country <国家代码> 只保留指定国家节点,默认不过滤",
|
|
397
398
|
" 支持: US, GB, DE, FR, JP, KR, SG, HK, TW, RU 等",
|
|
398
399
|
" --dry-run 只检测不切换(调试用)",
|
|
@@ -400,7 +401,7 @@ const HELP_TEXT = [
|
|
|
400
401
|
' {"action":"switchNode","node":"节点名"} 一次性切换到指定节点(不干扰自检)',
|
|
401
402
|
' {"action":"setCountryFilter","country":"US"} 切换国家过滤',
|
|
402
403
|
' {"action":"setCountryFilter","country":null} 取消过滤',
|
|
403
|
-
' {"action":"runBenchmark"}
|
|
404
|
+
' {"action":"runBenchmark"} 手动刷新候选集(delay 初测)',
|
|
404
405
|
' {"action":"setInterval","seconds":60} 修改巡检间隔',
|
|
405
406
|
" 示例: tt-help clash-daemon",
|
|
406
407
|
" tt-help clash-daemon --country US",
|
package/src/watchdog/agent.js
CHANGED
|
@@ -32,7 +32,12 @@ const TT_HELP_CONFIG = join(homeDir, ".tt-help.json");
|
|
|
32
32
|
|
|
33
33
|
/** 自动发现 daemon.js 路径 */
|
|
34
34
|
function findDaemonPath() {
|
|
35
|
-
// 1.
|
|
35
|
+
// 1. 内部打包路径优先(npm publish 后 src/clash/daemon.js,升级即最新)
|
|
36
|
+
// 避免 ~/.tt-help.json 的 clashDaemonPath 指向旧版外部 daemon
|
|
37
|
+
const internalPath = join(__dirname, "..", "clash", "daemon.js");
|
|
38
|
+
if (existsSync(internalPath)) return internalPath;
|
|
39
|
+
|
|
40
|
+
// 2. 显式配置覆盖(仅当包内缺失时)
|
|
36
41
|
try {
|
|
37
42
|
if (existsSync(TT_HELP_CONFIG)) {
|
|
38
43
|
const cfg = JSON.parse(readFileSync(TT_HELP_CONFIG, "utf-8"));
|
|
@@ -42,10 +47,6 @@ function findDaemonPath() {
|
|
|
42
47
|
}
|
|
43
48
|
} catch {}
|
|
44
49
|
|
|
45
|
-
// 2. 内部打包路径(npm publish 后 src/clash/daemon.js)
|
|
46
|
-
const internalPath = join(__dirname, "..", "clash", "daemon.js");
|
|
47
|
-
if (existsSync(internalPath)) return internalPath;
|
|
48
|
-
|
|
49
50
|
// 3. 开发模式:clash-verge-explore 同级目录
|
|
50
51
|
const candidates = [
|
|
51
52
|
join(__dirname, "..", "..", "..", "clash-verge-explore", "daemon.js"),
|
|
@@ -117,11 +118,13 @@ export class WatchdogAgent {
|
|
|
117
118
|
* @param {string} opts.serverUrl - 服务端地址
|
|
118
119
|
* @param {string} opts.clientId - 客户端标识
|
|
119
120
|
* @param {number} opts.intervalMs - 心跳间隔(毫秒)
|
|
121
|
+
* @param {boolean} [opts.spawnDaemon=true] - 是否自动启动 clash daemon
|
|
120
122
|
*/
|
|
121
|
-
constructor({ serverUrl, clientId, intervalMs = 15000 }) {
|
|
123
|
+
constructor({ serverUrl, clientId, intervalMs = 15000, spawnDaemon = true }) {
|
|
122
124
|
this.serverUrl = serverUrl.replace(/\/+$/, "");
|
|
123
125
|
this.clientId = clientId;
|
|
124
126
|
this.intervalMs = intervalMs;
|
|
127
|
+
this.spawnDaemon = !!spawnDaemon;
|
|
125
128
|
this.running = false;
|
|
126
129
|
this.heartbeatTimer = null;
|
|
127
130
|
this.thresholdTimer = null;
|
|
@@ -160,8 +163,8 @@ export class WatchdogAgent {
|
|
|
160
163
|
// 注册信号处理
|
|
161
164
|
this._setupSignalHandlers();
|
|
162
165
|
|
|
163
|
-
// 启动 clash daemon
|
|
164
|
-
this._spawnClashDaemon();
|
|
166
|
+
// 启动 clash daemon(保代理通道,--no-daemon 可关闭)
|
|
167
|
+
if (this.spawnDaemon) this._spawnClashDaemon();
|
|
165
168
|
|
|
166
169
|
// 首次立即发送心跳
|
|
167
170
|
await this._sendHeartbeat();
|
|
@@ -395,17 +398,21 @@ export class WatchdogAgent {
|
|
|
395
398
|
this.upgradeChecker = startUpgradeChecker({
|
|
396
399
|
onUpdateAvailable: async ({ current, latest }) => {
|
|
397
400
|
console.error(`[upgrade] ${current} → ${latest}`);
|
|
401
|
+
// 停掉所有子进程与 clash daemon,避免新旧并存
|
|
398
402
|
this.processManager.stopAll();
|
|
403
|
+
this._killClashDaemon();
|
|
399
404
|
|
|
400
405
|
const result = await performUpgrade();
|
|
401
406
|
if (result.success) {
|
|
402
407
|
this.ttHelpVersion = latest;
|
|
403
|
-
console.error(
|
|
404
|
-
|
|
405
|
-
|
|
408
|
+
console.error(
|
|
409
|
+
`[upgrade] 升级成功 (${latest}),重启 watchdog 使新版 clash daemon 生效`,
|
|
410
|
+
);
|
|
411
|
+
// 重启自身进程加载新代码(内部 daemon 路径优先),新进程会拉起新版 daemon
|
|
412
|
+
this._restartSelf();
|
|
413
|
+
return;
|
|
406
414
|
}
|
|
407
|
-
|
|
408
|
-
// 立即心跳(同步命令,重启进程)
|
|
415
|
+
console.error(`[upgrade] 失败: ${result.output.substring(0, 200)}`);
|
|
409
416
|
await this._sendHeartbeat();
|
|
410
417
|
},
|
|
411
418
|
});
|
|
@@ -481,6 +488,38 @@ export class WatchdogAgent {
|
|
|
481
488
|
this.clashDaemon = null;
|
|
482
489
|
}
|
|
483
490
|
|
|
491
|
+
/**
|
|
492
|
+
* 升级后重启自身进程(加载新代码)
|
|
493
|
+
* 用 cli.js watchdog 子进程替换当前进程,保证新版本内部 daemon 路径逻辑生效
|
|
494
|
+
*/
|
|
495
|
+
_restartSelf() {
|
|
496
|
+
const cliPath = join(__dirname, "..", "..", "cli.js");
|
|
497
|
+
const args = ["watchdog"];
|
|
498
|
+
if (this.serverUrl) args.push("--server", this.serverUrl);
|
|
499
|
+
if (this.clientId) args.push("--client-id", this.clientId);
|
|
500
|
+
if (!this.spawnDaemon) args.push("--no-daemon");
|
|
501
|
+
args.push(
|
|
502
|
+
"--interval",
|
|
503
|
+
String(Math.max(5, Math.round(this.intervalMs / 1000))),
|
|
504
|
+
);
|
|
505
|
+
let child;
|
|
506
|
+
try {
|
|
507
|
+
child = spawn(process.execPath, [cliPath, ...args], {
|
|
508
|
+
detached: true,
|
|
509
|
+
stdio: "ignore",
|
|
510
|
+
});
|
|
511
|
+
child.unref();
|
|
512
|
+
} catch (e) {
|
|
513
|
+
console.error(`[upgrade] 重启自身失败: ${e.message}`);
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
console.error(
|
|
517
|
+
`[upgrade] 新版 watchdog 已启动 (pid=${child.pid}),当前进程退出`,
|
|
518
|
+
);
|
|
519
|
+
this.stop();
|
|
520
|
+
setTimeout(() => process.exit(0), 500);
|
|
521
|
+
}
|
|
522
|
+
|
|
484
523
|
/**
|
|
485
524
|
* 信号处理
|
|
486
525
|
*/
|