tt-help-cli-ycl 1.4.68 → 1.4.70
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/cli/auto.js +6 -1
- package/src/cli/explore.js +7 -1
- package/src/cli/refresh.js +7 -1
- package/src/watch/public/app.js +15 -1
- package/src/watchdog/process-manager.js +24 -2
package/package.json
CHANGED
package/src/cli/auto.js
CHANGED
|
@@ -5,7 +5,10 @@ import {
|
|
|
5
5
|
} from "../lib/browser/page.js";
|
|
6
6
|
import { userId as configuredUserId, saveUserId } from "../lib/constants.js";
|
|
7
7
|
import { getMacOrUuid } from "../lib/mac-or-uuid.js";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
ensureBrowserReady as ensureBrowserReadyCDP,
|
|
10
|
+
killEdgeProcesses,
|
|
11
|
+
} from "../lib/browser/cdp.js";
|
|
9
12
|
import { createApiClient } from "../lib/api-client.js";
|
|
10
13
|
|
|
11
14
|
const MAX_RETRY_WAIT = 5 * 60 * 1000;
|
|
@@ -47,6 +50,8 @@ export async function handleAuto(options) {
|
|
|
47
50
|
if (shuttingDown) return;
|
|
48
51
|
shuttingDown = true;
|
|
49
52
|
console.error(`\n[Auto] 收到 ${signal},正在关闭浏览器...`);
|
|
53
|
+
// 先杀死 Edge 进程(CDP 模式下 browser.close() 只断开连接,不杀进程)
|
|
54
|
+
await killEdgeProcesses();
|
|
50
55
|
await browser?.close().catch(() => {});
|
|
51
56
|
console.error("[Auto] 已退出");
|
|
52
57
|
process.exit(0);
|
package/src/cli/explore.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import { getMacOrUuid } from "../lib/mac-or-uuid.js";
|
|
21
21
|
import {
|
|
22
22
|
ensureBrowserReady as ensureBrowserReadyCDP,
|
|
23
|
+
killEdgeProcesses,
|
|
23
24
|
switchAccount,
|
|
24
25
|
} from "../lib/browser/cdp.js";
|
|
25
26
|
import { showResourceUsage } from "../utils/index.js";
|
|
@@ -73,12 +74,17 @@ export async function handleExplore(options) {
|
|
|
73
74
|
|
|
74
75
|
let userId = exploreUserId || configuredUserId;
|
|
75
76
|
let browser = null;
|
|
77
|
+
let cdpOptions = null;
|
|
76
78
|
let shuttingDown = false;
|
|
77
79
|
|
|
78
80
|
const shutdown = async (signal) => {
|
|
79
81
|
if (shuttingDown) return;
|
|
80
82
|
shuttingDown = true;
|
|
81
83
|
console.error(`\n[Explore] 收到 ${signal},正在关闭浏览器...`);
|
|
84
|
+
// 先杀死 Edge 进程(CDP 模式下 browser.close() 只断开连接,不杀进程)
|
|
85
|
+
if (cdpOptions) {
|
|
86
|
+
await killEdgeProcesses(cdpOptions.userDataDir, cdpOptions.port);
|
|
87
|
+
}
|
|
82
88
|
await browser?.close().catch(() => {});
|
|
83
89
|
console.error("[Explore] 已退出");
|
|
84
90
|
process.exit(0);
|
|
@@ -117,7 +123,7 @@ export async function handleExplore(options) {
|
|
|
117
123
|
});
|
|
118
124
|
let currentAccount = healthChecker.getCurrentAccount();
|
|
119
125
|
|
|
120
|
-
|
|
126
|
+
cdpOptions = {};
|
|
121
127
|
if (explorePort) {
|
|
122
128
|
// 固定端口模式(调试用,关闭自动轮换)
|
|
123
129
|
cdpOptions.port = explorePort;
|
package/src/cli/refresh.js
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
import { getMacOrUuid } from "../lib/mac-or-uuid.js";
|
|
21
21
|
import {
|
|
22
22
|
ensureBrowserReady as ensureBrowserReadyCDP,
|
|
23
|
+
killEdgeProcesses,
|
|
23
24
|
switchAccount,
|
|
24
25
|
} from "../lib/browser/cdp.js";
|
|
25
26
|
import { HealthChecker } from "../lib/browser/health-checker.js";
|
|
@@ -72,12 +73,17 @@ export async function handleRefresh(options) {
|
|
|
72
73
|
|
|
73
74
|
let userId = exploreUserId || configuredUserId;
|
|
74
75
|
let browser = null;
|
|
76
|
+
let cdpOptions = null;
|
|
75
77
|
let shuttingDown = false;
|
|
76
78
|
|
|
77
79
|
const shutdown = async (signal) => {
|
|
78
80
|
if (shuttingDown) return;
|
|
79
81
|
shuttingDown = true;
|
|
80
82
|
console.error(`\n[Refresh] 收到 ${signal},正在关闭浏览器...`);
|
|
83
|
+
// 先杀死 Edge 进程(CDP 模式下 browser.close() 只断开连接,不杀进程)
|
|
84
|
+
if (cdpOptions) {
|
|
85
|
+
await killEdgeProcesses(cdpOptions.userDataDir, cdpOptions.port);
|
|
86
|
+
}
|
|
81
87
|
await browser?.close().catch(() => {});
|
|
82
88
|
console.error("[Refresh] 已退出");
|
|
83
89
|
process.exit(0);
|
|
@@ -124,7 +130,7 @@ export async function handleRefresh(options) {
|
|
|
124
130
|
});
|
|
125
131
|
let currentAccount = healthChecker.getCurrentAccount();
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
cdpOptions = {};
|
|
128
134
|
if (explorePort) {
|
|
129
135
|
cdpOptions.port = explorePort;
|
|
130
136
|
cdpOptions.userDataDir = path.join(
|
package/src/watch/public/app.js
CHANGED
|
@@ -1344,6 +1344,11 @@ function showMainPage() {
|
|
|
1344
1344
|
document.getElementById("targetPage").classList.remove("active");
|
|
1345
1345
|
document.getElementById("tagsPage").classList.remove("active");
|
|
1346
1346
|
document.getElementById("settingsPage").classList.remove("active");
|
|
1347
|
+
document.getElementById("watchdogPage").classList.remove("active");
|
|
1348
|
+
if (_wdRefreshTimer) {
|
|
1349
|
+
clearInterval(_wdRefreshTimer);
|
|
1350
|
+
_wdRefreshTimer = null;
|
|
1351
|
+
}
|
|
1347
1352
|
}
|
|
1348
1353
|
|
|
1349
1354
|
function navigateToTarget() {
|
|
@@ -3816,7 +3821,7 @@ function renderCmdList(myCmds, userId) {
|
|
|
3816
3821
|
);
|
|
3817
3822
|
});
|
|
3818
3823
|
|
|
3819
|
-
return html
|
|
3824
|
+
return html;
|
|
3820
3825
|
}
|
|
3821
3826
|
|
|
3822
3827
|
// ── 命令管理操作 ──
|
|
@@ -3896,6 +3901,13 @@ function wdToggleClientCmd(userId, idx) {
|
|
|
3896
3901
|
} else {
|
|
3897
3902
|
cmd.enabled = !cmd.enabled;
|
|
3898
3903
|
}
|
|
3904
|
+
// 立即更新按钮为 loading 状态
|
|
3905
|
+
var btn = event.target;
|
|
3906
|
+
if (btn && btn.tagName === "BUTTON") {
|
|
3907
|
+
btn.textContent = "⏳";
|
|
3908
|
+
btn.style.pointerEvents = "none";
|
|
3909
|
+
btn.style.opacity = "0.5";
|
|
3910
|
+
}
|
|
3899
3911
|
wdSaveClientCmds(userId, myCmds);
|
|
3900
3912
|
}
|
|
3901
3913
|
|
|
@@ -3909,6 +3921,8 @@ async function wdSaveClientCmds(userId, commands) {
|
|
|
3909
3921
|
fetchWatchdogData();
|
|
3910
3922
|
} catch (e) {
|
|
3911
3923
|
alert("保存失败: " + e.message);
|
|
3924
|
+
// 失败时立即刷新恢复按钮状态
|
|
3925
|
+
fetchWatchdogData();
|
|
3912
3926
|
}
|
|
3913
3927
|
}
|
|
3914
3928
|
|
|
@@ -11,10 +11,23 @@
|
|
|
11
11
|
|
|
12
12
|
import { spawn, execSync } from "child_process";
|
|
13
13
|
import { EventEmitter } from "events";
|
|
14
|
+
import { killEdgeProcesses } from "../lib/browser/cdp.js";
|
|
14
15
|
|
|
15
16
|
const MAX_RESTART = 3;
|
|
16
17
|
const IS_WIN = process.platform === "win32";
|
|
17
18
|
|
|
19
|
+
// 从命令行中提取 CDP 端口列表(解析 --base-port 和 --port-count)
|
|
20
|
+
function extractCdpPorts(cmdLine) {
|
|
21
|
+
const match = cmdLine.match(/--base-port\s+(\d+)/);
|
|
22
|
+
if (!match) return [];
|
|
23
|
+
const base = parseInt(match[1], 10);
|
|
24
|
+
const countMatch = cmdLine.match(/--port-count\s+(\d+)/);
|
|
25
|
+
const count = countMatch ? parseInt(countMatch[1], 10) : 1;
|
|
26
|
+
const ports = [];
|
|
27
|
+
for (let i = 0; i < count; i++) ports.push(base + i);
|
|
28
|
+
return ports;
|
|
29
|
+
}
|
|
30
|
+
|
|
18
31
|
// 引号感知的命令拆分:"a b" "c d" → ["a b", "c d"]
|
|
19
32
|
function splitCommand(cmdLine) {
|
|
20
33
|
const parts = [];
|
|
@@ -112,9 +125,9 @@ export class ProcessManager extends EventEmitter {
|
|
|
112
125
|
command = parts[0] || command;
|
|
113
126
|
args = parts.slice(1);
|
|
114
127
|
}
|
|
115
|
-
// Windows .cmd
|
|
128
|
+
// Windows .cmd 必须 shell:true;为免 DEP0190 警告,传完整命令行字符串
|
|
116
129
|
child = IS_WIN
|
|
117
|
-
? spawn(command, args, {
|
|
130
|
+
? spawn([command, ...args].join(" "), {
|
|
118
131
|
stdio: ["ignore", "pipe", "pipe"],
|
|
119
132
|
detached: false,
|
|
120
133
|
shell: true,
|
|
@@ -210,6 +223,10 @@ export class ProcessManager extends EventEmitter {
|
|
|
210
223
|
|
|
211
224
|
if (info.child) {
|
|
212
225
|
try {
|
|
226
|
+
// 先从命令行提取 CDP 端口,用于关闭脱离进程树的浏览器
|
|
227
|
+
const cmdLine = info.cmdDef?.command || "";
|
|
228
|
+
const ports = extractCdpPorts(cmdLine);
|
|
229
|
+
|
|
213
230
|
if (IS_WIN) {
|
|
214
231
|
// Windows: shell:true 产生 cmd.exe 中间层,必须杀整个进程树
|
|
215
232
|
execSync(`taskkill /PID ${info.child.pid} /T /F`, {
|
|
@@ -227,6 +244,11 @@ export class ProcessManager extends EventEmitter {
|
|
|
227
244
|
} catch {}
|
|
228
245
|
}, 2000);
|
|
229
246
|
}
|
|
247
|
+
|
|
248
|
+
// 全平台:关闭脱离进程树的浏览器(open -a / start msedge 启动的)
|
|
249
|
+
for (const port of ports) {
|
|
250
|
+
killEdgeProcesses(null, port);
|
|
251
|
+
}
|
|
230
252
|
} catch (e) {
|
|
231
253
|
console.error(`[watchdog] 停止命令 ${cmdId} 失败: ${e.message}`);
|
|
232
254
|
}
|