tt-help-cli-ycl 1.4.183 → 1.4.185
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/scripts/test-candidate-retry.mjs +496 -0
- package/scripts/test-crash-circuit-breaker.mjs +250 -0
- package/scripts/test-error-auto-reset.mjs +103 -0
- package/scripts/test-error-report.mjs +215 -0
- package/scripts/test-login-pool-acquire-order.mjs +92 -26
- package/scripts/test-login-pool-faceban-e2e.mjs +131 -0
- package/scripts/test-login-pool-faceban.mjs +235 -0
- package/scripts/test-login-pool-ui.mjs +2 -1
- package/scripts/test-login-pool.mjs +97 -54
- package/scripts/test-process-manager-label.mjs +145 -0
- package/src/cli/explore.js +171 -25
- package/src/cli/search.js +171 -18
- package/src/lib/browser/health-checker.js +19 -3
- package/src/lib/browser/page.js +23 -0
- package/src/lib/error-report.js +119 -0
- package/src/lib/login-pool-client.js +123 -0
- package/src/watch/data-store.js +25 -0
- package/src/watch/login-pool.js +118 -81
- package/src/watch/public/app.js +7 -2
- package/src/watch/public/index.html +2 -1
- package/src/watch/server.js +53 -8
- package/src/watchdog/process-manager.js +71 -6
- package/src/watchdog/reporter.js +2 -0
|
@@ -31,8 +31,10 @@ const RESTART_SPAWN_STAGGER_MS = 60000; // 启动错峰 60s
|
|
|
31
31
|
const STALE_LOG_TIMEOUT_MS = 15 * 60 * 1000; // 15 分钟无日志输出视为假死
|
|
32
32
|
|
|
33
33
|
// === 控制台日志格式化(仅显示层增强,不影响任何功能链路) ===
|
|
34
|
-
// 目标:多进程日志交错打印时,通过时间戳 + 固定宽度彩色 [
|
|
34
|
+
// 目标:多进程日志交错打印时,通过时间戳 + 固定宽度彩色 [程序名:端口] 前缀方便人眼分流。
|
|
35
35
|
// 兼容:Windows(Windows Terminal 彩色 / 旧 conhost 自动降级纯文本)与 macOS(原生 ANSI 彩色)。
|
|
36
|
+
// 前缀标签由 deriveDisplayLabel 从命令行派生(如 [explore:9223]/[explore:9223-9225]),
|
|
37
|
+
// 解析失败退回 cmdDef.name || id。内部 cmdId 完全不动(stop/toggle/日志拉取/LLM 分析按它索引)。
|
|
36
38
|
|
|
37
39
|
// 每进程固定一种颜色(按 cmdId 哈希取色),新增进程自动分配且不重复
|
|
38
40
|
const PROC_COLORS = [32, 36, 33, 35, 34, 92, 96, 93, 95, 94];
|
|
@@ -141,6 +143,61 @@ function splitCommand(cmdLine) {
|
|
|
141
143
|
return parts;
|
|
142
144
|
}
|
|
143
145
|
|
|
146
|
+
// === 显示层标签派生(仅显示层增强,不影响任何功能链路;2026-11-04 定稿) ===
|
|
147
|
+
// 规则:[程序名:端口],端口解析不到就只显示程序名,程序名也解析不到退回 fallbackId。
|
|
148
|
+
// 端口提取复用 extractCdpPorts 原样逻辑(多端口区间压缩为 首-尾,端口天然连续)。
|
|
149
|
+
|
|
150
|
+
// 启动器 token(basename 去掉 .exe/.cmd/.bat 后比对):其后的 token 才是程序名/子命令
|
|
151
|
+
const LAUNCHER_RE = /^(?:tt-help|node|npx)(?:\.(?:exe|cmd|bat))?$/i;
|
|
152
|
+
const SCRIPT_EXT_RE = /\.(?:mjs|cjs|js)$/i;
|
|
153
|
+
|
|
154
|
+
// 跨平台 basename(同时处理 / 与 Windows \)
|
|
155
|
+
function pathBaseName(p) {
|
|
156
|
+
const s = String(p || "");
|
|
157
|
+
const idx = Math.max(s.lastIndexOf("/"), s.lastIndexOf("\\"));
|
|
158
|
+
return idx >= 0 ? s.slice(idx + 1) : s;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* 从拆分后的 token 中解析程序名。
|
|
163
|
+
* token[0] 为启动器(tt-help/node/npx)时取 token[1];
|
|
164
|
+
* 取到的 token 是脚本文件路径(.js/.mjs/.cjs)时:
|
|
165
|
+
* - 后面还有非 flag token(子命令)→ 取子命令(node src/main.js watch → watch)
|
|
166
|
+
* - 否则取 basename 去扩展名(node scraper.js --port X → scraper)
|
|
167
|
+
* 解析不出返回 null(调用方退回 fallbackId)。
|
|
168
|
+
*/
|
|
169
|
+
function deriveProgramName(tokens) {
|
|
170
|
+
if (!Array.isArray(tokens) || tokens.length === 0) return null;
|
|
171
|
+
let idx = 0;
|
|
172
|
+
const firstBase = pathBaseName(tokens[0]).replace(/\.(?:exe|cmd|bat)$/i, "");
|
|
173
|
+
if (LAUNCHER_RE.test(firstBase) && tokens.length > 1) idx = 1;
|
|
174
|
+
const base = pathBaseName(tokens[idx]);
|
|
175
|
+
if (SCRIPT_EXT_RE.test(base)) {
|
|
176
|
+
const next = tokens[idx + 1];
|
|
177
|
+
if (next && !next.startsWith("-")) return next;
|
|
178
|
+
return base.replace(SCRIPT_EXT_RE, "") || null;
|
|
179
|
+
}
|
|
180
|
+
return base || null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* 派生日志前缀显示标签:[程序名:端口](纯函数,导出供单测覆盖全部分支)。
|
|
185
|
+
* - tt-help explore --base-port 9223 --port-count 3 → "explore:9223-9225"
|
|
186
|
+
* - tt-help refresh-mini --port 5222 → "refresh-mini:5222"(单端口仅浏览器类命令提取)
|
|
187
|
+
* - tt-help comments(无端口参数) → "comments"(不猜默认端口,避免误导)
|
|
188
|
+
* - 全部解析不出 → fallbackId(即 cmdDef.name || id,兜底回现状)
|
|
189
|
+
*/
|
|
190
|
+
export function deriveDisplayLabel(cmdLine, fallbackId) {
|
|
191
|
+
const tokens = splitCommand(String(cmdLine || ""));
|
|
192
|
+
if (tokens.length === 0) return fallbackId;
|
|
193
|
+
const prog = deriveProgramName(tokens);
|
|
194
|
+
if (!prog) return fallbackId;
|
|
195
|
+
const ports = extractCdpPorts(String(cmdLine || ""));
|
|
196
|
+
if (ports.length === 1) return `${prog}:${ports[0]}`;
|
|
197
|
+
if (ports.length > 1) return `${prog}:${ports[0]}-${ports[ports.length - 1]}`;
|
|
198
|
+
return prog;
|
|
199
|
+
}
|
|
200
|
+
|
|
144
201
|
function getProcessStats(pid) {
|
|
145
202
|
try {
|
|
146
203
|
if (IS_WIN) {
|
|
@@ -244,7 +301,7 @@ function getChildPid(parentPid) {
|
|
|
244
301
|
export class ProcessManager extends EventEmitter {
|
|
245
302
|
constructor() {
|
|
246
303
|
super();
|
|
247
|
-
/** @type {Map<string, {cmdId:string, cmdDef:object, child:ChildProcess, startTime:number, restartCount:number, thresholds:object, stopped:boolean}>} */
|
|
304
|
+
/** @type {Map<string, {cmdId:string, cmdDef:object, displayLabel:string, child:ChildProcess, startTime:number, restartCount:number, thresholds:object, stopped:boolean}>} */
|
|
248
305
|
this.processes = new Map();
|
|
249
306
|
/** @type {Map<string, number>} cmdId → 连续异常重启次数(跨实例累计;稳定运行后清零)
|
|
250
307
|
* 2026-09-25 修复: 原先计数存在每个实例的 info 上,自动重启重建 info 后归零,
|
|
@@ -258,6 +315,12 @@ export class ProcessManager extends EventEmitter {
|
|
|
258
315
|
*/
|
|
259
316
|
startCommand(cmdDef) {
|
|
260
317
|
let { id, command, args = [] } = cmdDef;
|
|
318
|
+
// 显示层标签(仅显示用;cmdId 不动)。在 splitCommand 改写 command/args 前派生,
|
|
319
|
+
// 重启路径(自动重启/假死/阈值)都经 startCommand,标签随之重建。
|
|
320
|
+
const displayLabel = deriveDisplayLabel(
|
|
321
|
+
[command, ...(Array.isArray(args) ? args : [])].join(" "),
|
|
322
|
+
(cmdDef && cmdDef.name) || id,
|
|
323
|
+
);
|
|
261
324
|
if (this.processes.has(id)) {
|
|
262
325
|
// 已有进程在运行(或 stopCommand 还未清理),跳过
|
|
263
326
|
const existing = this.processes.get(id);
|
|
@@ -309,6 +372,7 @@ export class ProcessManager extends EventEmitter {
|
|
|
309
372
|
this.processes.set(id, {
|
|
310
373
|
cmdId: id,
|
|
311
374
|
cmdDef,
|
|
375
|
+
displayLabel,
|
|
312
376
|
child: null,
|
|
313
377
|
startTime,
|
|
314
378
|
restartCount: 0,
|
|
@@ -327,9 +391,8 @@ export class ProcessManager extends EventEmitter {
|
|
|
327
391
|
if (msg) {
|
|
328
392
|
const short = msg.substring(0, 200);
|
|
329
393
|
// 仅显示层格式化:时间戳 + 彩色固定宽度前缀,内容不变。
|
|
330
|
-
//
|
|
331
|
-
|
|
332
|
-
printProcessLine(displayId, short);
|
|
394
|
+
// 前缀用启动时派生的 [程序名:端口] 标签,解析失败已退回 name||id。
|
|
395
|
+
printProcessLine(displayLabel, short);
|
|
333
396
|
// 环形缓冲:保留最近 N 行供 LLM 分析
|
|
334
397
|
const info = this.processes.get(id);
|
|
335
398
|
if (info) {
|
|
@@ -388,6 +451,7 @@ export class ProcessManager extends EventEmitter {
|
|
|
388
451
|
this.processes.set(id, {
|
|
389
452
|
cmdId: id,
|
|
390
453
|
cmdDef,
|
|
454
|
+
displayLabel,
|
|
391
455
|
child,
|
|
392
456
|
startTime,
|
|
393
457
|
restartCount: 0,
|
|
@@ -466,7 +530,8 @@ export class ProcessManager extends EventEmitter {
|
|
|
466
530
|
|
|
467
531
|
result.push({
|
|
468
532
|
cmdId,
|
|
469
|
-
|
|
533
|
+
// 显示层 name 与日志前缀同源([程序名:端口]),web 页面进程列表与日志一致
|
|
534
|
+
name: info.displayLabel || info.cmdDef.name || cmdId,
|
|
470
535
|
pid,
|
|
471
536
|
status: info.child
|
|
472
537
|
? info.child.exitCode === null
|
package/src/watchdog/reporter.js
CHANGED
|
@@ -88,6 +88,8 @@ export function getClientConfig() {
|
|
|
88
88
|
maxComments: cfg.maxComments,
|
|
89
89
|
maxFollowing: cfg.maxFollowing,
|
|
90
90
|
maxFollowers: cfg.maxFollowers,
|
|
91
|
+
// 内存阈值覆盖(HealthChecker 用;顶层级键——cfg.browser 是 Edge 路径字符串,无法嵌套)
|
|
92
|
+
memoryThreshold: cfg.memoryThreshold,
|
|
91
93
|
};
|
|
92
94
|
}
|
|
93
95
|
} catch {
|