@aipanel/core 1.2.27 → 1.2.28
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/es/node/diagnostics.d.ts +26 -2
- package/es/node/diagnostics.mjs +83 -22
- package/lib/node/diagnostics.cjs +86 -22
- package/lib/node/diagnostics.d.ts +26 -2
- package/package.json +1 -1
package/es/node/diagnostics.d.ts
CHANGED
|
@@ -51,8 +51,20 @@ export declare function findTsconfigDir(filePath: string): string | null;
|
|
|
51
51
|
export declare function findAllTsconfigDirs(workspace: string): string[];
|
|
52
52
|
/** 运行 TypeScript 类型检查(tsc / vue-tsc 按项目自动选择)--build --noEmit,返回原始输出 */
|
|
53
53
|
export declare function runTypeCheck(filePath: string | undefined, cwd: string): Promise<TscResult>;
|
|
54
|
+
/**
|
|
55
|
+
* 多文件类型检查:按最近的 tsconfig 项目分组,每个项目只跑一次 `--build --noEmit`,
|
|
56
|
+
* 再把项目输出切分回各文件(与单文件路径共用 filterTscOutputForFile)。
|
|
57
|
+
* 一次编辑批次里的 N 个文件因此从 N 次项目构建降到 1 次。
|
|
58
|
+
*/
|
|
59
|
+
export declare function runTypeChecksForFiles(files: string[], cwd: string): Promise<Map<string, TscResult>>;
|
|
54
60
|
/** 并行运行 ESLint + 类型检查(单文件或 glob) */
|
|
55
61
|
export declare function runAllChecks(pattern: string, cwd: string): Promise<DiagnosticsResult>;
|
|
62
|
+
/**
|
|
63
|
+
* 批量运行 ESLint + 类型检查:Lint 逐文件(ESLint 进程内、oxlint 单次 CLI),
|
|
64
|
+
* 类型检查按 tsconfig 项目合并为一次(见 runTypeChecksForFiles)。
|
|
65
|
+
* 返回"文件绝对路径 → 诊断结果",供 step 边界的一次性收尾诊断使用。
|
|
66
|
+
*/
|
|
67
|
+
export declare function runAllChecksForFiles(files: string[], cwd: string): Promise<Map<string, DiagnosticsResult>>;
|
|
56
68
|
/**
|
|
57
69
|
* 全量项目诊断:优先从根 tsconfig 运行一次类型检查 --build,
|
|
58
70
|
* 根无 tsconfig 时回退到逐个子目录 build;ESLint 以 "." 全量扫描。
|
|
@@ -62,5 +74,17 @@ export declare function runProjectDiagnostics(workspace: string): Promise<Diagno
|
|
|
62
74
|
export declare function tscSectionTitle(tscOutput: TscResult): string;
|
|
63
75
|
/** Lint 分区标题(单一来源:跟随实际运行的引擎组合,如 "ESLint + oxlint") */
|
|
64
76
|
export declare function lintSectionTitle(lintOutput: EslintOutput): string;
|
|
65
|
-
/**
|
|
66
|
-
export declare function
|
|
77
|
+
/** 分区发现被条数上限折叠时的提示(自动诊断摘要与 run_diagnostics 完整输出的分界) */
|
|
78
|
+
export declare function omittedFindingsHint(omitted: number): string;
|
|
79
|
+
/**
|
|
80
|
+
* 组装统一的分区诊断文本(Lint / 类型检查)。
|
|
81
|
+
* 默认保留空分区的占位文案(run_diagnostics 要正面回答"有没有问题");
|
|
82
|
+
* `onlyFindings: true` 只输出有发现的分区、全空返回空串(编辑后自动诊断不刷占位噪音);
|
|
83
|
+
* `maxFindingsPerSection` 把每个分区的发现折叠成有界摘要——编辑后自动诊断每个 step 都会投递,
|
|
84
|
+
* 因此用条数上限控制重复成本,完整结果仍由不带上限的 run_diagnostics 给出。
|
|
85
|
+
* `title` 允许为空串,此时直接返回分区正文(追加式投递场景无需标题)。
|
|
86
|
+
*/
|
|
87
|
+
export declare function formatDiagnosticsSections(title: string, eslintOutput: EslintOutput, tscOutput: TscResult, options?: {
|
|
88
|
+
onlyFindings?: boolean;
|
|
89
|
+
maxFindingsPerSection?: number;
|
|
90
|
+
}): string;
|
package/es/node/diagnostics.mjs
CHANGED
|
@@ -342,6 +342,22 @@ function parseTscDiags(rawOutput, filePath, projectDir, source = "tsc") {
|
|
|
342
342
|
}
|
|
343
343
|
return diags;
|
|
344
344
|
}
|
|
345
|
+
function filterTscOutputForFile(rawOutput, filePath, projectDir) {
|
|
346
|
+
const resolved = path.resolve(filePath);
|
|
347
|
+
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
|
|
348
|
+
const filtered = [];
|
|
349
|
+
let keep = false;
|
|
350
|
+
for (const line of rawOutput.split("\n")) {
|
|
351
|
+
const m = errorLinePat.exec(line);
|
|
352
|
+
if (m) {
|
|
353
|
+
keep = path.resolve(projectDir, m[1]) === resolved;
|
|
354
|
+
} else if (!/^\s/.test(line)) {
|
|
355
|
+
keep = false;
|
|
356
|
+
}
|
|
357
|
+
if (keep) filtered.push(line);
|
|
358
|
+
}
|
|
359
|
+
return filtered.join("\n");
|
|
360
|
+
}
|
|
345
361
|
async function runTypeCheck(filePath, cwd) {
|
|
346
362
|
const dir = cwd;
|
|
347
363
|
const projectDir = filePath ? findTsconfigDir(filePath) ?? dir : dir;
|
|
@@ -372,21 +388,7 @@ async function runTypeCheck(filePath, cwd) {
|
|
|
372
388
|
}
|
|
373
389
|
const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
|
|
374
390
|
if (filePath) {
|
|
375
|
-
|
|
376
|
-
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
|
|
377
|
-
const lines = rawOutput.split("\n");
|
|
378
|
-
const filtered = [];
|
|
379
|
-
let keep = false;
|
|
380
|
-
for (const line of lines) {
|
|
381
|
-
const m = errorLinePat.exec(line);
|
|
382
|
-
if (m) {
|
|
383
|
-
keep = path.resolve(projectDir, m[1]) === resolved;
|
|
384
|
-
} else if (!/^\s/.test(line)) {
|
|
385
|
-
keep = false;
|
|
386
|
-
}
|
|
387
|
-
if (keep) filtered.push(line);
|
|
388
|
-
}
|
|
389
|
-
rawOutput = filtered.join("\n");
|
|
391
|
+
rawOutput = filterTscOutputForFile(rawOutput, filePath, projectDir);
|
|
390
392
|
}
|
|
391
393
|
log.debug("type-check finished", {
|
|
392
394
|
engine: engine.source,
|
|
@@ -396,6 +398,32 @@ async function runTypeCheck(filePath, cwd) {
|
|
|
396
398
|
});
|
|
397
399
|
return { rawOutput, exitCode, diagnostics, source: engine.source };
|
|
398
400
|
}
|
|
401
|
+
async function runTypeChecksForFiles(files, cwd) {
|
|
402
|
+
const groups = /* @__PURE__ */ new Map();
|
|
403
|
+
for (const file of files) {
|
|
404
|
+
const resolved = path.resolve(file);
|
|
405
|
+
const projectDir = findTsconfigDir(resolved) ?? cwd;
|
|
406
|
+
const group = groups.get(projectDir);
|
|
407
|
+
if (group) group.push(resolved);
|
|
408
|
+
else groups.set(projectDir, [resolved]);
|
|
409
|
+
}
|
|
410
|
+
const results = /* @__PURE__ */ new Map();
|
|
411
|
+
for (const [projectDir, group] of groups) {
|
|
412
|
+
const whole = await runTypeCheck(void 0, projectDir).catch(() => ({
|
|
413
|
+
rawOutput: "",
|
|
414
|
+
exitCode: 0
|
|
415
|
+
}));
|
|
416
|
+
for (const file of group) {
|
|
417
|
+
results.set(file, {
|
|
418
|
+
rawOutput: filterTscOutputForFile(whole.rawOutput, file, projectDir),
|
|
419
|
+
exitCode: whole.exitCode,
|
|
420
|
+
diagnostics: (whole.diagnostics ?? []).filter((d) => d.file === file),
|
|
421
|
+
source: whole.source
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return results;
|
|
426
|
+
}
|
|
399
427
|
async function runAllChecks(pattern, cwd) {
|
|
400
428
|
log.debug("runAllChecks", { pattern, cwd });
|
|
401
429
|
const [eslintOutput, tscOutput] = await Promise.all([
|
|
@@ -404,6 +432,18 @@ async function runAllChecks(pattern, cwd) {
|
|
|
404
432
|
]);
|
|
405
433
|
return { eslintOutput, tscOutput };
|
|
406
434
|
}
|
|
435
|
+
async function runAllChecksForFiles(files, cwd) {
|
|
436
|
+
const targets = [...new Set(files.map((file) => path.resolve(file)))];
|
|
437
|
+
const tscByFile = await runTypeChecksForFiles(targets, cwd);
|
|
438
|
+
const results = /* @__PURE__ */ new Map();
|
|
439
|
+
for (const file of targets) {
|
|
440
|
+
results.set(file, {
|
|
441
|
+
eslintOutput: await lintFiles(file, cwd),
|
|
442
|
+
tscOutput: tscByFile.get(file) ?? { rawOutput: "", exitCode: 0 }
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
return results;
|
|
446
|
+
}
|
|
407
447
|
async function runProjectDiagnostics(workspace) {
|
|
408
448
|
const tscDirs = fs.existsSync(path.join(workspace, "tsconfig.json")) ? [workspace] : findAllTsconfigDirs(workspace);
|
|
409
449
|
log.debug("Tsc dirs to check", { count: tscDirs.length, dirs: tscDirs });
|
|
@@ -425,18 +465,36 @@ function tscSectionTitle(tscOutput) {
|
|
|
425
465
|
function lintSectionTitle(lintOutput) {
|
|
426
466
|
return lintOutput.engines?.length ? lintOutput.engines.join(" + ") : "ESLint";
|
|
427
467
|
}
|
|
428
|
-
function
|
|
468
|
+
function omittedFindingsHint(omitted) {
|
|
469
|
+
return `\u2026\u8FD8\u6709 ${omitted} \u6761\uFF0C\u5B8C\u6574\u7ED3\u679C\u8BF7\u8C03\u7528 run_diagnostics`;
|
|
470
|
+
}
|
|
471
|
+
function boundFindings(text, maxFindings) {
|
|
472
|
+
if (!maxFindings || !text) return text;
|
|
473
|
+
const lines = text.split("\n").filter((line) => line.trim() !== "");
|
|
474
|
+
if (lines.length <= maxFindings) return text;
|
|
475
|
+
return [...lines.slice(0, maxFindings), omittedFindingsHint(lines.length - maxFindings)].join(
|
|
476
|
+
"\n"
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
function formatDiagnosticsSections(title, eslintOutput, tscOutput, options = {}) {
|
|
480
|
+
const lintLines = boundFindings(eslintOutput.text, options.maxFindingsPerSection);
|
|
481
|
+
const tscLines = boundFindings(tscOutput.rawOutput.trim(), options.maxFindingsPerSection);
|
|
429
482
|
const parts = [];
|
|
430
|
-
|
|
483
|
+
if (!options.onlyFindings || lintLines) {
|
|
484
|
+
parts.push(`## ${lintSectionTitle(eslintOutput)}
|
|
431
485
|
|
|
432
|
-
` + (
|
|
433
|
-
|
|
434
|
-
|
|
486
|
+
` + (lintLines || "\u6CA1\u6709\u53D1\u73B0\u95EE\u9898"));
|
|
487
|
+
}
|
|
488
|
+
if (!options.onlyFindings || tscLines) {
|
|
489
|
+
parts.push(`## ${tscSectionTitle(tscOutput)}
|
|
435
490
|
|
|
436
491
|
` + (tscLines || "\u6CA1\u6709\u53D1\u73B0\u7C7B\u578B\u9519\u8BEF"));
|
|
437
|
-
|
|
492
|
+
}
|
|
493
|
+
if (parts.length === 0) return "";
|
|
494
|
+
const body = parts.join("\n\n");
|
|
495
|
+
return title ? `${title}
|
|
438
496
|
|
|
439
|
-
`
|
|
497
|
+
${body}` : body;
|
|
440
498
|
}
|
|
441
499
|
export {
|
|
442
500
|
DIAGNOSTICS_TOOL_DESCRIPTION,
|
|
@@ -446,8 +504,11 @@ export {
|
|
|
446
504
|
isJsFile,
|
|
447
505
|
lintFiles,
|
|
448
506
|
lintSectionTitle,
|
|
507
|
+
omittedFindingsHint,
|
|
449
508
|
runAllChecks,
|
|
509
|
+
runAllChecksForFiles,
|
|
450
510
|
runProjectDiagnostics,
|
|
451
511
|
runTypeCheck,
|
|
512
|
+
runTypeChecksForFiles,
|
|
452
513
|
tscSectionTitle
|
|
453
514
|
};
|
package/lib/node/diagnostics.cjs
CHANGED
|
@@ -34,9 +34,12 @@ __export(diagnostics_exports, {
|
|
|
34
34
|
isJsFile: () => isJsFile,
|
|
35
35
|
lintFiles: () => lintFiles,
|
|
36
36
|
lintSectionTitle: () => lintSectionTitle,
|
|
37
|
+
omittedFindingsHint: () => omittedFindingsHint,
|
|
37
38
|
runAllChecks: () => runAllChecks,
|
|
39
|
+
runAllChecksForFiles: () => runAllChecksForFiles,
|
|
38
40
|
runProjectDiagnostics: () => runProjectDiagnostics,
|
|
39
41
|
runTypeCheck: () => runTypeCheck,
|
|
42
|
+
runTypeChecksForFiles: () => runTypeChecksForFiles,
|
|
40
43
|
tscSectionTitle: () => tscSectionTitle
|
|
41
44
|
});
|
|
42
45
|
module.exports = __toCommonJS(diagnostics_exports);
|
|
@@ -385,6 +388,22 @@ function parseTscDiags(rawOutput, filePath, projectDir, source = "tsc") {
|
|
|
385
388
|
}
|
|
386
389
|
return diags;
|
|
387
390
|
}
|
|
391
|
+
function filterTscOutputForFile(rawOutput, filePath, projectDir) {
|
|
392
|
+
const resolved = import_node_path.default.resolve(filePath);
|
|
393
|
+
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
|
|
394
|
+
const filtered = [];
|
|
395
|
+
let keep = false;
|
|
396
|
+
for (const line of rawOutput.split("\n")) {
|
|
397
|
+
const m = errorLinePat.exec(line);
|
|
398
|
+
if (m) {
|
|
399
|
+
keep = import_node_path.default.resolve(projectDir, m[1]) === resolved;
|
|
400
|
+
} else if (!/^\s/.test(line)) {
|
|
401
|
+
keep = false;
|
|
402
|
+
}
|
|
403
|
+
if (keep) filtered.push(line);
|
|
404
|
+
}
|
|
405
|
+
return filtered.join("\n");
|
|
406
|
+
}
|
|
388
407
|
async function runTypeCheck(filePath, cwd) {
|
|
389
408
|
const dir = cwd;
|
|
390
409
|
const projectDir = filePath ? findTsconfigDir(filePath) ?? dir : dir;
|
|
@@ -415,21 +434,7 @@ async function runTypeCheck(filePath, cwd) {
|
|
|
415
434
|
}
|
|
416
435
|
const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
|
|
417
436
|
if (filePath) {
|
|
418
|
-
|
|
419
|
-
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
|
|
420
|
-
const lines = rawOutput.split("\n");
|
|
421
|
-
const filtered = [];
|
|
422
|
-
let keep = false;
|
|
423
|
-
for (const line of lines) {
|
|
424
|
-
const m = errorLinePat.exec(line);
|
|
425
|
-
if (m) {
|
|
426
|
-
keep = import_node_path.default.resolve(projectDir, m[1]) === resolved;
|
|
427
|
-
} else if (!/^\s/.test(line)) {
|
|
428
|
-
keep = false;
|
|
429
|
-
}
|
|
430
|
-
if (keep) filtered.push(line);
|
|
431
|
-
}
|
|
432
|
-
rawOutput = filtered.join("\n");
|
|
437
|
+
rawOutput = filterTscOutputForFile(rawOutput, filePath, projectDir);
|
|
433
438
|
}
|
|
434
439
|
log.debug("type-check finished", {
|
|
435
440
|
engine: engine.source,
|
|
@@ -439,6 +444,32 @@ async function runTypeCheck(filePath, cwd) {
|
|
|
439
444
|
});
|
|
440
445
|
return { rawOutput, exitCode, diagnostics, source: engine.source };
|
|
441
446
|
}
|
|
447
|
+
async function runTypeChecksForFiles(files, cwd) {
|
|
448
|
+
const groups = /* @__PURE__ */ new Map();
|
|
449
|
+
for (const file of files) {
|
|
450
|
+
const resolved = import_node_path.default.resolve(file);
|
|
451
|
+
const projectDir = findTsconfigDir(resolved) ?? cwd;
|
|
452
|
+
const group = groups.get(projectDir);
|
|
453
|
+
if (group) group.push(resolved);
|
|
454
|
+
else groups.set(projectDir, [resolved]);
|
|
455
|
+
}
|
|
456
|
+
const results = /* @__PURE__ */ new Map();
|
|
457
|
+
for (const [projectDir, group] of groups) {
|
|
458
|
+
const whole = await runTypeCheck(void 0, projectDir).catch(() => ({
|
|
459
|
+
rawOutput: "",
|
|
460
|
+
exitCode: 0
|
|
461
|
+
}));
|
|
462
|
+
for (const file of group) {
|
|
463
|
+
results.set(file, {
|
|
464
|
+
rawOutput: filterTscOutputForFile(whole.rawOutput, file, projectDir),
|
|
465
|
+
exitCode: whole.exitCode,
|
|
466
|
+
diagnostics: (whole.diagnostics ?? []).filter((d) => d.file === file),
|
|
467
|
+
source: whole.source
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
return results;
|
|
472
|
+
}
|
|
442
473
|
async function runAllChecks(pattern, cwd) {
|
|
443
474
|
log.debug("runAllChecks", { pattern, cwd });
|
|
444
475
|
const [eslintOutput, tscOutput] = await Promise.all([
|
|
@@ -447,6 +478,18 @@ async function runAllChecks(pattern, cwd) {
|
|
|
447
478
|
]);
|
|
448
479
|
return { eslintOutput, tscOutput };
|
|
449
480
|
}
|
|
481
|
+
async function runAllChecksForFiles(files, cwd) {
|
|
482
|
+
const targets = [...new Set(files.map((file) => import_node_path.default.resolve(file)))];
|
|
483
|
+
const tscByFile = await runTypeChecksForFiles(targets, cwd);
|
|
484
|
+
const results = /* @__PURE__ */ new Map();
|
|
485
|
+
for (const file of targets) {
|
|
486
|
+
results.set(file, {
|
|
487
|
+
eslintOutput: await lintFiles(file, cwd),
|
|
488
|
+
tscOutput: tscByFile.get(file) ?? { rawOutput: "", exitCode: 0 }
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return results;
|
|
492
|
+
}
|
|
450
493
|
async function runProjectDiagnostics(workspace) {
|
|
451
494
|
const tscDirs = import_node_fs.default.existsSync(import_node_path.default.join(workspace, "tsconfig.json")) ? [workspace] : findAllTsconfigDirs(workspace);
|
|
452
495
|
log.debug("Tsc dirs to check", { count: tscDirs.length, dirs: tscDirs });
|
|
@@ -468,18 +511,36 @@ function tscSectionTitle(tscOutput) {
|
|
|
468
511
|
function lintSectionTitle(lintOutput) {
|
|
469
512
|
return lintOutput.engines?.length ? lintOutput.engines.join(" + ") : "ESLint";
|
|
470
513
|
}
|
|
471
|
-
function
|
|
514
|
+
function omittedFindingsHint(omitted) {
|
|
515
|
+
return `\u2026\u8FD8\u6709 ${omitted} \u6761\uFF0C\u5B8C\u6574\u7ED3\u679C\u8BF7\u8C03\u7528 run_diagnostics`;
|
|
516
|
+
}
|
|
517
|
+
function boundFindings(text, maxFindings) {
|
|
518
|
+
if (!maxFindings || !text) return text;
|
|
519
|
+
const lines = text.split("\n").filter((line) => line.trim() !== "");
|
|
520
|
+
if (lines.length <= maxFindings) return text;
|
|
521
|
+
return [...lines.slice(0, maxFindings), omittedFindingsHint(lines.length - maxFindings)].join(
|
|
522
|
+
"\n"
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
function formatDiagnosticsSections(title, eslintOutput, tscOutput, options = {}) {
|
|
526
|
+
const lintLines = boundFindings(eslintOutput.text, options.maxFindingsPerSection);
|
|
527
|
+
const tscLines = boundFindings(tscOutput.rawOutput.trim(), options.maxFindingsPerSection);
|
|
472
528
|
const parts = [];
|
|
473
|
-
|
|
529
|
+
if (!options.onlyFindings || lintLines) {
|
|
530
|
+
parts.push(`## ${lintSectionTitle(eslintOutput)}
|
|
474
531
|
|
|
475
|
-
` + (
|
|
476
|
-
|
|
477
|
-
|
|
532
|
+
` + (lintLines || "\u6CA1\u6709\u53D1\u73B0\u95EE\u9898"));
|
|
533
|
+
}
|
|
534
|
+
if (!options.onlyFindings || tscLines) {
|
|
535
|
+
parts.push(`## ${tscSectionTitle(tscOutput)}
|
|
478
536
|
|
|
479
537
|
` + (tscLines || "\u6CA1\u6709\u53D1\u73B0\u7C7B\u578B\u9519\u8BEF"));
|
|
480
|
-
|
|
538
|
+
}
|
|
539
|
+
if (parts.length === 0) return "";
|
|
540
|
+
const body = parts.join("\n\n");
|
|
541
|
+
return title ? `${title}
|
|
481
542
|
|
|
482
|
-
`
|
|
543
|
+
${body}` : body;
|
|
483
544
|
}
|
|
484
545
|
// Annotate the CommonJS export names for ESM import in node:
|
|
485
546
|
0 && (module.exports = {
|
|
@@ -490,8 +551,11 @@ function formatDiagnosticsSections(title, eslintOutput, tscOutput) {
|
|
|
490
551
|
isJsFile,
|
|
491
552
|
lintFiles,
|
|
492
553
|
lintSectionTitle,
|
|
554
|
+
omittedFindingsHint,
|
|
493
555
|
runAllChecks,
|
|
556
|
+
runAllChecksForFiles,
|
|
494
557
|
runProjectDiagnostics,
|
|
495
558
|
runTypeCheck,
|
|
559
|
+
runTypeChecksForFiles,
|
|
496
560
|
tscSectionTitle
|
|
497
561
|
});
|
|
@@ -51,8 +51,20 @@ export declare function findTsconfigDir(filePath: string): string | null;
|
|
|
51
51
|
export declare function findAllTsconfigDirs(workspace: string): string[];
|
|
52
52
|
/** 运行 TypeScript 类型检查(tsc / vue-tsc 按项目自动选择)--build --noEmit,返回原始输出 */
|
|
53
53
|
export declare function runTypeCheck(filePath: string | undefined, cwd: string): Promise<TscResult>;
|
|
54
|
+
/**
|
|
55
|
+
* 多文件类型检查:按最近的 tsconfig 项目分组,每个项目只跑一次 `--build --noEmit`,
|
|
56
|
+
* 再把项目输出切分回各文件(与单文件路径共用 filterTscOutputForFile)。
|
|
57
|
+
* 一次编辑批次里的 N 个文件因此从 N 次项目构建降到 1 次。
|
|
58
|
+
*/
|
|
59
|
+
export declare function runTypeChecksForFiles(files: string[], cwd: string): Promise<Map<string, TscResult>>;
|
|
54
60
|
/** 并行运行 ESLint + 类型检查(单文件或 glob) */
|
|
55
61
|
export declare function runAllChecks(pattern: string, cwd: string): Promise<DiagnosticsResult>;
|
|
62
|
+
/**
|
|
63
|
+
* 批量运行 ESLint + 类型检查:Lint 逐文件(ESLint 进程内、oxlint 单次 CLI),
|
|
64
|
+
* 类型检查按 tsconfig 项目合并为一次(见 runTypeChecksForFiles)。
|
|
65
|
+
* 返回"文件绝对路径 → 诊断结果",供 step 边界的一次性收尾诊断使用。
|
|
66
|
+
*/
|
|
67
|
+
export declare function runAllChecksForFiles(files: string[], cwd: string): Promise<Map<string, DiagnosticsResult>>;
|
|
56
68
|
/**
|
|
57
69
|
* 全量项目诊断:优先从根 tsconfig 运行一次类型检查 --build,
|
|
58
70
|
* 根无 tsconfig 时回退到逐个子目录 build;ESLint 以 "." 全量扫描。
|
|
@@ -62,5 +74,17 @@ export declare function runProjectDiagnostics(workspace: string): Promise<Diagno
|
|
|
62
74
|
export declare function tscSectionTitle(tscOutput: TscResult): string;
|
|
63
75
|
/** Lint 分区标题(单一来源:跟随实际运行的引擎组合,如 "ESLint + oxlint") */
|
|
64
76
|
export declare function lintSectionTitle(lintOutput: EslintOutput): string;
|
|
65
|
-
/**
|
|
66
|
-
export declare function
|
|
77
|
+
/** 分区发现被条数上限折叠时的提示(自动诊断摘要与 run_diagnostics 完整输出的分界) */
|
|
78
|
+
export declare function omittedFindingsHint(omitted: number): string;
|
|
79
|
+
/**
|
|
80
|
+
* 组装统一的分区诊断文本(Lint / 类型检查)。
|
|
81
|
+
* 默认保留空分区的占位文案(run_diagnostics 要正面回答"有没有问题");
|
|
82
|
+
* `onlyFindings: true` 只输出有发现的分区、全空返回空串(编辑后自动诊断不刷占位噪音);
|
|
83
|
+
* `maxFindingsPerSection` 把每个分区的发现折叠成有界摘要——编辑后自动诊断每个 step 都会投递,
|
|
84
|
+
* 因此用条数上限控制重复成本,完整结果仍由不带上限的 run_diagnostics 给出。
|
|
85
|
+
* `title` 允许为空串,此时直接返回分区正文(追加式投递场景无需标题)。
|
|
86
|
+
*/
|
|
87
|
+
export declare function formatDiagnosticsSections(title: string, eslintOutput: EslintOutput, tscOutput: TscResult, options?: {
|
|
88
|
+
onlyFindings?: boolean;
|
|
89
|
+
maxFindingsPerSection?: number;
|
|
90
|
+
}): string;
|