@aipanel/dsh-plugin 1.2.21 → 1.2.22
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/dist/index.js +237 -60
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -306,10 +306,10 @@ function isJsFile(filePath) {
|
|
|
306
306
|
return JS_EXTENSIONS.has(path.extname(filePath));
|
|
307
307
|
}
|
|
308
308
|
var DIAGNOSTICS_TOOL_DESCRIPTION = [
|
|
309
|
-
"\u8FD0\u884C
|
|
309
|
+
"\u8FD0\u884C Lint\uFF08ESLint / oxlint\uFF09\u4E0E TypeScript \u7C7B\u578B\u8BCA\u65AD\uFF0C\u8FD4\u56DE\u8BCA\u65AD\u7ED3\u679C\u3002",
|
|
310
310
|
"",
|
|
311
311
|
"**\u652F\u6301\u7684\u6587\u4EF6\u7C7B\u578B**\uFF1A",
|
|
312
|
-
`-
|
|
312
|
+
`- Lint\uFF1AJavaScript / TypeScript / Vue \u6E90\u7801\uFF08${[...JS_EXTENSIONS].map((e) => `*${e}`).join(" ")}\uFF09\uFF1B\u4E24\u5F15\u64CE\u5747\u5B89\u88C5\u65F6\u5E76\u884C\u4E92\u8865\u8FD0\u884C\uFF08\u8BCA\u65AD\u6309\u6765\u6E90\u6807\u6CE8\uFF09`,
|
|
313
313
|
"- TypeScript \u7C7B\u578B\u68C0\u67E5\uFF1A*.ts *.tsx *.vue",
|
|
314
314
|
"",
|
|
315
315
|
"**\u4F55\u65F6\u4F7F\u7528\u6B64\u5DE5\u5177**\uFF1A",
|
|
@@ -333,12 +333,68 @@ function loadESLint(workspace) {
|
|
|
333
333
|
}
|
|
334
334
|
async function lintFiles(pattern, cwd, warnLimit = 5) {
|
|
335
335
|
loadESLint(cwd);
|
|
336
|
-
|
|
336
|
+
const [eslintOutput, oxlintOutput] = await Promise.all([
|
|
337
|
+
ESLintClass ? runEslintFiles(pattern, cwd, warnLimit) : Promise.resolve(null),
|
|
338
|
+
runOxlintFiles(pattern, cwd, warnLimit)
|
|
339
|
+
]);
|
|
340
|
+
const engines = [];
|
|
341
|
+
const texts = [];
|
|
342
|
+
const diagnostics = [];
|
|
343
|
+
for (const output of [eslintOutput, oxlintOutput]) {
|
|
344
|
+
if (!output) continue;
|
|
345
|
+
engines.push(...output.engines ?? []);
|
|
346
|
+
if (output.text) texts.push(output.text);
|
|
347
|
+
diagnostics.push(...output.diagnostics ?? []);
|
|
348
|
+
}
|
|
349
|
+
if (engines.length === 0) {
|
|
337
350
|
return {
|
|
338
|
-
text: `[
|
|
351
|
+
text: `[Lint] \u672A\u8FD0\u884C\uFF1A\u65E0\u6CD5\u5728 workspace "${cwd}" \u89E3\u6790\u5230 eslint \u6216 oxlint`,
|
|
339
352
|
diagnostics: []
|
|
340
353
|
};
|
|
341
354
|
}
|
|
355
|
+
return { text: texts.join("\n\n") || void 0, diagnostics, engines };
|
|
356
|
+
}
|
|
357
|
+
function formatLintMessages(messages, engine, warnLimit) {
|
|
358
|
+
if (messages.length === 0) return { engines: [engine.label] };
|
|
359
|
+
const ESLINT_ERROR = 2;
|
|
360
|
+
const ESLINT_WARN = 1;
|
|
361
|
+
const lines = [];
|
|
362
|
+
const errors = messages.filter((m) => m.severity === ESLINT_ERROR);
|
|
363
|
+
const warnings = messages.filter((m) => m.severity === ESLINT_WARN);
|
|
364
|
+
if (errors.length > 0) {
|
|
365
|
+
lines.push(
|
|
366
|
+
...errors.map(
|
|
367
|
+
(m) => `ERROR [${m.filePath}:${m.line}:${m.column}] ${m.message} (${m.ruleId})`
|
|
368
|
+
)
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
if (warnings.length > 0) {
|
|
372
|
+
lines.push(
|
|
373
|
+
...warnings.slice(0, warnLimit).map((m) => `WARN [${m.filePath}:${m.line}:${m.column}] ${m.message} (${m.ruleId})`)
|
|
374
|
+
);
|
|
375
|
+
if (warnings.length > warnLimit)
|
|
376
|
+
lines.push(`... and ${warnings.length - warnLimit} more warnings`);
|
|
377
|
+
}
|
|
378
|
+
const diagnostics = messages.map((m) => ({
|
|
379
|
+
severity: m.severity === ESLINT_ERROR ? SEVERITY_ERROR : m.severity === ESLINT_WARN ? SEVERITY_WARN : m.severity,
|
|
380
|
+
file: m.filePath,
|
|
381
|
+
range: {
|
|
382
|
+
start: { line: (m.line || 1) - 1, character: (m.column || 1) - 1 },
|
|
383
|
+
end: {
|
|
384
|
+
line: (m.endLine || m.line || 1) - 1,
|
|
385
|
+
character: (m.endColumn || m.column || 1) - 1
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
message: `[${engine.label}] ${m.message} (${m.ruleId})`,
|
|
389
|
+
source: engine.source
|
|
390
|
+
}));
|
|
391
|
+
return {
|
|
392
|
+
text: lines.length > 0 ? lines.join("\n") : void 0,
|
|
393
|
+
diagnostics,
|
|
394
|
+
engines: [engine.label]
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
async function runEslintFiles(pattern, cwd, warnLimit) {
|
|
342
398
|
try {
|
|
343
399
|
const eslint = new ESLintClass({ cwd });
|
|
344
400
|
const results = await eslint.lintFiles(pattern);
|
|
@@ -350,48 +406,111 @@ async function lintFiles(pattern, cwd, warnLimit = 5) {
|
|
|
350
406
|
fileCount: results.length,
|
|
351
407
|
messageCount: messages.length
|
|
352
408
|
});
|
|
353
|
-
|
|
354
|
-
const ESLINT_ERROR = 2;
|
|
355
|
-
const ESLINT_WARN = 1;
|
|
356
|
-
const lines = [];
|
|
357
|
-
const errors = messages.filter((m) => m.severity === ESLINT_ERROR);
|
|
358
|
-
const warnings = messages.filter((m) => m.severity === ESLINT_WARN);
|
|
359
|
-
if (errors.length > 0) {
|
|
360
|
-
lines.push(
|
|
361
|
-
...errors.map(
|
|
362
|
-
(m) => `ERROR [${m.filePath}:${m.line}:${m.column}] ${m.message} (${m.ruleId})`
|
|
363
|
-
)
|
|
364
|
-
);
|
|
365
|
-
}
|
|
366
|
-
if (warnings.length > 0) {
|
|
367
|
-
lines.push(
|
|
368
|
-
...warnings.slice(0, warnLimit).map((m) => `WARN [${m.filePath}:${m.line}:${m.column}] ${m.message} (${m.ruleId})`)
|
|
369
|
-
);
|
|
370
|
-
if (warnings.length > warnLimit)
|
|
371
|
-
lines.push(`... and ${warnings.length - warnLimit} more warnings`);
|
|
372
|
-
}
|
|
373
|
-
const diagnostics = messages.map((m) => ({
|
|
374
|
-
severity: m.severity === ESLINT_ERROR ? SEVERITY_ERROR : m.severity === ESLINT_WARN ? SEVERITY_WARN : m.severity,
|
|
375
|
-
file: m.filePath,
|
|
376
|
-
range: {
|
|
377
|
-
start: { line: (m.line || 1) - 1, character: (m.column || 1) - 1 },
|
|
378
|
-
end: {
|
|
379
|
-
line: (m.endLine || m.line || 1) - 1,
|
|
380
|
-
character: (m.endColumn || m.column || 1) - 1
|
|
381
|
-
}
|
|
382
|
-
},
|
|
383
|
-
message: `[ESLint] ${m.message} (${m.ruleId})`,
|
|
384
|
-
source: "eslint"
|
|
385
|
-
}));
|
|
386
|
-
return { text: lines.length > 0 ? lines.join("\n") : void 0, diagnostics };
|
|
409
|
+
return formatLintMessages(messages, { label: "ESLint", source: "eslint" }, warnLimit);
|
|
387
410
|
} catch (err) {
|
|
388
411
|
log2.warn("ESLint failed", { pattern, error: err.message });
|
|
389
412
|
return {
|
|
390
413
|
text: `[ESLint] \u8FD0\u884C\u5931\u8D25\uFF1A${err.message}\uFF08\u4EC5\u663E\u793A TypeScript \u8BCA\u65AD\uFF09`,
|
|
391
|
-
diagnostics: []
|
|
414
|
+
diagnostics: [],
|
|
415
|
+
engines: ["ESLint"]
|
|
392
416
|
};
|
|
393
417
|
}
|
|
394
418
|
}
|
|
419
|
+
var _oxlintBin;
|
|
420
|
+
function resolveOxlintBin(workspace) {
|
|
421
|
+
if (_oxlintBin !== void 0) return _oxlintBin;
|
|
422
|
+
try {
|
|
423
|
+
const req = createRequire(path.join(workspace, "package.json"));
|
|
424
|
+
const pkgJsonPath = req.resolve("oxlint/package.json");
|
|
425
|
+
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, "utf8"));
|
|
426
|
+
const binRel = typeof pkg.bin === "string" ? pkg.bin : pkg.bin?.oxlint;
|
|
427
|
+
_oxlintBin = binRel ? path.join(path.dirname(pkgJsonPath), binRel) : null;
|
|
428
|
+
} catch {
|
|
429
|
+
_oxlintBin = null;
|
|
430
|
+
}
|
|
431
|
+
return _oxlintBin;
|
|
432
|
+
}
|
|
433
|
+
function oxlintRuleName(code) {
|
|
434
|
+
if (!code) return null;
|
|
435
|
+
const match = /\(([^)]*)\)$/.exec(code);
|
|
436
|
+
return match ? match[1] : code;
|
|
437
|
+
}
|
|
438
|
+
function parseOxlintOutput(stdout, cwd) {
|
|
439
|
+
let parsed;
|
|
440
|
+
try {
|
|
441
|
+
parsed = JSON.parse(stdout);
|
|
442
|
+
} catch {
|
|
443
|
+
const start = stdout.indexOf("{");
|
|
444
|
+
const end = stdout.lastIndexOf("}");
|
|
445
|
+
if (start >= 0 && end > start) {
|
|
446
|
+
try {
|
|
447
|
+
parsed = JSON.parse(stdout.slice(start, end + 1));
|
|
448
|
+
} catch {
|
|
449
|
+
parsed = void 0;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
if (!parsed) throw new Error("\u65E0\u6CD5\u89E3\u6790 oxlint JSON \u8F93\u51FA");
|
|
454
|
+
return (parsed.diagnostics ?? []).flatMap((d) => {
|
|
455
|
+
const filePath = d.filename ? path.isAbsolute(d.filename) ? d.filename : path.resolve(cwd, d.filename) : "";
|
|
456
|
+
if (!filePath) return [];
|
|
457
|
+
const span = d.labels?.[0]?.span;
|
|
458
|
+
const line = span?.line ?? 1;
|
|
459
|
+
const column = span?.column ?? 1;
|
|
460
|
+
return [
|
|
461
|
+
{
|
|
462
|
+
// oxlint 无 endLine/endColumn,同行按 span.length 延伸近似
|
|
463
|
+
severity: d.severity === "error" ? 2 : 1,
|
|
464
|
+
line,
|
|
465
|
+
column,
|
|
466
|
+
endLine: line,
|
|
467
|
+
endColumn: column + (span?.length ?? 0),
|
|
468
|
+
message: d.message ?? "\u672A\u77E5\u8BCA\u65AD",
|
|
469
|
+
ruleId: oxlintRuleName(d.code),
|
|
470
|
+
filePath
|
|
471
|
+
}
|
|
472
|
+
];
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
async function runOxlintFiles(pattern, cwd, warnLimit) {
|
|
476
|
+
const bin = resolveOxlintBin(cwd);
|
|
477
|
+
if (!bin) return {};
|
|
478
|
+
return new Promise((resolve) => {
|
|
479
|
+
exec(
|
|
480
|
+
// 与 ESLint 默认行为对齐:忽略 node_modules(oxlint 默认不排除)
|
|
481
|
+
`node "${bin}" --format=json --ignore-pattern node_modules "${pattern}"`,
|
|
482
|
+
{ cwd, timeout: 6e4, maxBuffer: 50 * 1024 * 1024 },
|
|
483
|
+
(error, stdout, stderr) => {
|
|
484
|
+
const killed = error?.killed;
|
|
485
|
+
if (killed) {
|
|
486
|
+
log2.warn("oxlint timed out", { pattern });
|
|
487
|
+
resolve({
|
|
488
|
+
text: "[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A\u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u3002",
|
|
489
|
+
diagnostics: [],
|
|
490
|
+
engines: ["oxlint"]
|
|
491
|
+
});
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
const messages = parseOxlintOutput(stdout, cwd);
|
|
496
|
+
log2.debug("oxlint lint", {
|
|
497
|
+
pattern,
|
|
498
|
+
messageCount: messages.length,
|
|
499
|
+
stderr: stderr || void 0
|
|
500
|
+
});
|
|
501
|
+
resolve(formatLintMessages(messages, { label: "oxlint", source: "oxlint" }, warnLimit));
|
|
502
|
+
} catch (e) {
|
|
503
|
+
log2.warn("oxlint failed", { pattern, error: e.message });
|
|
504
|
+
resolve({
|
|
505
|
+
text: `[oxlint] \u8FD0\u884C\u5931\u8D25\uFF1A${e.message}`,
|
|
506
|
+
diagnostics: [],
|
|
507
|
+
engines: ["oxlint"]
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
);
|
|
512
|
+
});
|
|
513
|
+
}
|
|
395
514
|
var _vueTscBin;
|
|
396
515
|
function resolveVueTscBin() {
|
|
397
516
|
if (_vueTscBin !== void 0) return _vueTscBin;
|
|
@@ -403,6 +522,46 @@ function resolveVueTscBin() {
|
|
|
403
522
|
}
|
|
404
523
|
return _vueTscBin;
|
|
405
524
|
}
|
|
525
|
+
var _tscBinByPkgDir = /* @__PURE__ */ new Map();
|
|
526
|
+
function nearestPackageJsonDir(startDir) {
|
|
527
|
+
let dir = path.resolve(startDir);
|
|
528
|
+
while (true) {
|
|
529
|
+
if (fs.existsSync(path.join(dir, "package.json"))) return dir;
|
|
530
|
+
const parent = path.dirname(dir);
|
|
531
|
+
if (parent === dir) return null;
|
|
532
|
+
dir = parent;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
function isVuePackage(pkgDir) {
|
|
536
|
+
try {
|
|
537
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(pkgDir, "package.json"), "utf8"));
|
|
538
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
539
|
+
return "vue" in deps || "nuxt" in deps;
|
|
540
|
+
} catch {
|
|
541
|
+
return false;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
function resolveTypeCheckBin(projectDir) {
|
|
545
|
+
const pkgDir = nearestPackageJsonDir(projectDir);
|
|
546
|
+
if (!pkgDir || isVuePackage(pkgDir)) {
|
|
547
|
+
const bin2 = resolveVueTscBin();
|
|
548
|
+
return bin2 ? { bin: bin2, source: "vue-tsc" } : null;
|
|
549
|
+
}
|
|
550
|
+
let bin = _tscBinByPkgDir.get(pkgDir);
|
|
551
|
+
if (bin === void 0) {
|
|
552
|
+
try {
|
|
553
|
+
const req = createRequire(path.join(pkgDir, "package.json"));
|
|
554
|
+
bin = req.resolve("typescript/bin/tsc");
|
|
555
|
+
} catch {
|
|
556
|
+
bin = null;
|
|
557
|
+
}
|
|
558
|
+
_tscBinByPkgDir.set(pkgDir, bin);
|
|
559
|
+
if (!bin) log2.debug("workspace tsc not resolvable, fallback to vue-tsc", { pkgDir });
|
|
560
|
+
}
|
|
561
|
+
if (bin) return { bin, source: "tsc" };
|
|
562
|
+
const vueBin = resolveVueTscBin();
|
|
563
|
+
return vueBin ? { bin: vueBin, source: "vue-tsc" } : null;
|
|
564
|
+
}
|
|
406
565
|
function findTsconfigDir(filePath) {
|
|
407
566
|
const resolved = path.resolve(filePath);
|
|
408
567
|
let dir = path.dirname(resolved);
|
|
@@ -448,7 +607,7 @@ function findAllTsconfigDirs(workspace) {
|
|
|
448
607
|
});
|
|
449
608
|
return dirs;
|
|
450
609
|
}
|
|
451
|
-
function parseTscDiags(rawOutput, filePath, projectDir) {
|
|
610
|
+
function parseTscDiags(rawOutput, filePath, projectDir, source = "tsc") {
|
|
452
611
|
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS(\d+):\s+(.+)$/;
|
|
453
612
|
const diags = [];
|
|
454
613
|
const resolved = filePath ? path.resolve(filePath) : void 0;
|
|
@@ -469,40 +628,40 @@ function parseTscDiags(rawOutput, filePath, projectDir) {
|
|
|
469
628
|
end: { line: Number(lineNum) - 1, character: Number(col) - 1 }
|
|
470
629
|
},
|
|
471
630
|
message: `[TS${code}] ${message}`,
|
|
472
|
-
source
|
|
631
|
+
source
|
|
473
632
|
});
|
|
474
633
|
}
|
|
475
634
|
}
|
|
476
635
|
return diags;
|
|
477
636
|
}
|
|
478
|
-
async function
|
|
637
|
+
async function runTypeCheck(filePath, cwd) {
|
|
479
638
|
const dir = cwd;
|
|
480
639
|
const projectDir = filePath ? findTsconfigDir(filePath) ?? dir : dir;
|
|
481
|
-
log2.debug("
|
|
640
|
+
log2.debug("runTypeCheck", {
|
|
482
641
|
filePath: filePath || "(all)",
|
|
483
642
|
cwd: dir,
|
|
484
643
|
projectDir,
|
|
485
644
|
processCwd: process.cwd()
|
|
486
645
|
});
|
|
487
|
-
const
|
|
488
|
-
if (!
|
|
489
|
-
log2.warn("
|
|
646
|
+
const engine = resolveTypeCheckBin(projectDir);
|
|
647
|
+
if (!engine) {
|
|
648
|
+
log2.warn("type-check bin not found", { projectDir });
|
|
490
649
|
return { rawOutput: "", exitCode: 0 };
|
|
491
650
|
}
|
|
492
651
|
const timeout = filePath ? 6e4 : 12e4;
|
|
493
652
|
const maxBuffer = filePath ? 10 * 1024 * 1024 : 50 * 1024 * 1024;
|
|
494
653
|
return new Promise((resolve) => {
|
|
495
654
|
exec(
|
|
496
|
-
`node "${bin}" --build --noEmit --pretty false`,
|
|
655
|
+
`node "${engine.bin}" --build --noEmit --pretty false`,
|
|
497
656
|
{ cwd: projectDir, timeout, maxBuffer },
|
|
498
657
|
(error, stdout, stderr) => {
|
|
499
658
|
let rawOutput = stdout + stderr;
|
|
500
659
|
const killed = error?.killed;
|
|
501
660
|
const exitCode = typeof error?.code === "number" ? error.code : killed ? 1 : 0;
|
|
502
661
|
if (killed && !rawOutput) {
|
|
503
|
-
rawOutput =
|
|
662
|
+
rawOutput = `${engine.source} \u68C0\u67E5\u8D85\u65F6\uFF0C\u8BF7\u5C1D\u8BD5\u7F29\u5C0F\u68C0\u67E5\u8303\u56F4\u6216\u4F18\u5316\u9879\u76EE\u914D\u7F6E\u3002`;
|
|
504
663
|
}
|
|
505
|
-
const diagnostics = parseTscDiags(rawOutput, filePath, projectDir);
|
|
664
|
+
const diagnostics = parseTscDiags(rawOutput, filePath, projectDir, engine.source);
|
|
506
665
|
if (filePath) {
|
|
507
666
|
const resolved = path.resolve(filePath);
|
|
508
667
|
const errorLinePat = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+TS\d+:/;
|
|
@@ -520,12 +679,13 @@ async function runVueTsc(filePath, cwd) {
|
|
|
520
679
|
}
|
|
521
680
|
rawOutput = filtered.join("\n");
|
|
522
681
|
}
|
|
523
|
-
log2.debug("
|
|
682
|
+
log2.debug("type-check finished", {
|
|
683
|
+
engine: engine.source,
|
|
524
684
|
filePath: filePath || "(all)",
|
|
525
685
|
exitCode,
|
|
526
686
|
outputLength: rawOutput.length
|
|
527
687
|
});
|
|
528
|
-
resolve({ rawOutput, exitCode, diagnostics });
|
|
688
|
+
resolve({ rawOutput, exitCode, diagnostics, source: engine.source });
|
|
529
689
|
}
|
|
530
690
|
);
|
|
531
691
|
});
|
|
@@ -534,7 +694,7 @@ async function runAllChecks(pattern, cwd) {
|
|
|
534
694
|
log2.debug("runAllChecks", { pattern, cwd });
|
|
535
695
|
const [eslintOutput, tscOutput] = await Promise.all([
|
|
536
696
|
lintFiles(pattern, cwd),
|
|
537
|
-
|
|
697
|
+
runTypeCheck(pattern, cwd)
|
|
538
698
|
]);
|
|
539
699
|
return { eslintOutput, tscOutput };
|
|
540
700
|
}
|
|
@@ -543,20 +703,31 @@ async function runProjectDiagnostics(workspace) {
|
|
|
543
703
|
log2.debug("Tsc dirs to check", { count: tscDirs.length, dirs: tscDirs });
|
|
544
704
|
const [eslintOutput, ...tscOutputs] = await Promise.all([
|
|
545
705
|
lintFiles(".", workspace, 10),
|
|
546
|
-
...tscDirs.map((dir) =>
|
|
706
|
+
...tscDirs.map((dir) => runTypeCheck(void 0, dir))
|
|
547
707
|
]);
|
|
548
708
|
const mergedTsc = {
|
|
549
709
|
rawOutput: tscOutputs.flatMap((o) => o.rawOutput).filter(Boolean).join("\n"),
|
|
550
710
|
exitCode: tscOutputs.reduce((max, o) => Math.max(max, o.exitCode), 0),
|
|
551
|
-
diagnostics: tscOutputs.flatMap((o) => o.diagnostics ?? [])
|
|
711
|
+
diagnostics: tscOutputs.flatMap((o) => o.diagnostics ?? []),
|
|
712
|
+
source: tscOutputs.find((o) => o.source)?.source
|
|
552
713
|
};
|
|
553
714
|
return { eslintOutput, tscOutput: mergedTsc };
|
|
554
715
|
}
|
|
716
|
+
function tscSectionTitle(tscOutput) {
|
|
717
|
+
return tscOutput.source ?? "tsc";
|
|
718
|
+
}
|
|
719
|
+
function lintSectionTitle(lintOutput) {
|
|
720
|
+
return lintOutput.engines?.length ? lintOutput.engines.join(" + ") : "ESLint";
|
|
721
|
+
}
|
|
555
722
|
function formatDiagnosticsSections(title, eslintOutput, tscOutput) {
|
|
556
723
|
const parts = [];
|
|
557
|
-
parts.push(
|
|
724
|
+
parts.push(`## ${lintSectionTitle(eslintOutput)}
|
|
725
|
+
|
|
726
|
+
` + (eslintOutput.text || "\u6CA1\u6709\u53D1\u73B0\u95EE\u9898"));
|
|
558
727
|
const tscLines = tscOutput.rawOutput.trim();
|
|
559
|
-
parts.push(
|
|
728
|
+
parts.push(`## ${tscSectionTitle(tscOutput)}
|
|
729
|
+
|
|
730
|
+
` + (tscLines || "\u6CA1\u6709\u53D1\u73B0\u7C7B\u578B\u9519\u8BEF"));
|
|
560
731
|
return `${title}
|
|
561
732
|
|
|
562
733
|
` + parts.join("\n\n");
|
|
@@ -870,8 +1041,8 @@ function buildDiagnosticsCanonical(title, eslintOutput, tscOutput) {
|
|
|
870
1041
|
return {
|
|
871
1042
|
title,
|
|
872
1043
|
sections: [
|
|
873
|
-
{ title:
|
|
874
|
-
{ title:
|
|
1044
|
+
{ title: lintSectionTitle(eslintOutput), text: eslintOutput.text || "\u6CA1\u6709\u53D1\u73B0\u95EE\u9898" },
|
|
1045
|
+
{ title: tscSectionTitle(tscOutput), text: tscOutput.rawOutput.trim() || "\u6CA1\u6709\u53D1\u73B0\u7C7B\u578B\u9519\u8BEF" }
|
|
875
1046
|
],
|
|
876
1047
|
diagnostics: [
|
|
877
1048
|
...toDiagnosticEntries(eslintOutput.diagnostics ?? []),
|
|
@@ -1074,8 +1245,14 @@ function apply(ctx, config = {}) {
|
|
|
1074
1245
|
tscOutput: { rawOutput: "", exitCode: 0 }
|
|
1075
1246
|
}));
|
|
1076
1247
|
const parts = [];
|
|
1077
|
-
if (tscOutput.rawOutput.trim())
|
|
1078
|
-
|
|
1248
|
+
if (tscOutput.rawOutput.trim())
|
|
1249
|
+
parts.push(`## ${tscSectionTitle(tscOutput)}
|
|
1250
|
+
|
|
1251
|
+
` + tscOutput.rawOutput.trim());
|
|
1252
|
+
if (eslintOutput.text)
|
|
1253
|
+
parts.push(`## ${lintSectionTitle(eslintOutput)}
|
|
1254
|
+
|
|
1255
|
+
` + eslintOutput.text);
|
|
1079
1256
|
const diagText = parts.join("\n\n");
|
|
1080
1257
|
if (!diagText) return decision;
|
|
1081
1258
|
const existing = decision.kind === "accept" && decision.content || result.content;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aipanel/dsh-plugin",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.22",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AIPanel for DeepSeek Harness (dsh):注入审查工具 run_diagnostics、编辑后自动诊断。",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"@deepseek-ai/dsh-user-questions": "^0.1.5-rc.1",
|
|
26
26
|
"@deepseek-ai/dsh-util-values": "^0.1.5-rc.1",
|
|
27
27
|
"esbuild": "^0.25.0",
|
|
28
|
-
"@aipanel/core": "1.2.
|
|
28
|
+
"@aipanel/core": "1.2.22"
|
|
29
29
|
},
|
|
30
30
|
"scripts": {
|
|
31
31
|
"build": "esbuild src/index.ts --bundle --outfile=dist/index.js --platform=node --format=esm --target=node18 --external:@deepseek-ai/* --external:node:* --external:vue-tsc",
|