fix(cli): hide info-level lint findings by default, show with --verbose

Info findings are noisy for agents and day-to-day use. Only errors and
warnings are shown by default. Pass --verbose to include info findings
in both CLI and JSON output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Miguel Ángel
2026-03-31 02:05:40 +02:00
co-authored by Claude Opus 4.6
parent 8e76580318
commit 7a228fcd40
2 changed files with 40 additions and 10 deletions
+29 -8
View File
@@ -1,15 +1,31 @@
import { defineCommand } from "citty";
import { c } from "../ui/colors.js";
import { resolveProject } from "../utils/project.js";
import { lintProject } from "../utils/lintProject.js";
import { formatLintFindings } from "../utils/lintFormat.js";
import { lintProject } from "../utils/lintProject.js";
import { resolveProject } from "../utils/project.js";
import { withMeta } from "../utils/updateCheck.js";
export default defineCommand({
meta: { name: "lint", description: "Validate a composition for common mistakes" },
meta: {
name: "lint",
description: "Validate a composition for common mistakes",
},
args: {
dir: { type: "positional", description: "Project directory", required: false },
json: { type: "boolean", description: "Output findings as JSON", default: false },
dir: {
type: "positional",
description: "Project directory",
required: false,
},
json: {
type: "boolean",
description: "Output findings as JSON",
default: false,
},
verbose: {
type: "boolean",
description: "Show info-level findings (hidden by default)",
default: false,
},
},
async run({ args }) {
try {
@@ -17,12 +33,13 @@ export default defineCommand({
const lintResult = lintProject(project);
if (args.json) {
const allFindings = lintResult.results.flatMap((r) => r.result.findings);
const combined = {
ok: lintResult.totalErrors === 0,
errorCount: lintResult.totalErrors,
warningCount: lintResult.totalWarnings,
infoCount: lintResult.totalInfos,
findings: lintResult.results.flatMap((r) => r.result.findings),
findings: args.verbose ? allFindings : allFindings.filter((f) => f.severity !== "info"),
filesScanned: lintResult.results.length,
};
console.log(JSON.stringify(withMeta(combined), null, 2));
@@ -32,7 +49,7 @@ export default defineCommand({
const fileCount = lintResult.results.length;
const fileLabel =
fileCount === 1 ? (lintResult.results[0]?.file ?? "index.html") : `${fileCount} files`;
console.log(`${c.accent("◆")} Linting ${c.accent(project.name + "/" + fileLabel)}`);
console.log(`${c.accent("◆")} Linting ${c.accent(`${project.name}/${fileLabel}`)}`);
console.log();
if (lintResult.totalErrors === 0 && lintResult.totalWarnings === 0) {
@@ -40,7 +57,11 @@ export default defineCommand({
return;
}
const lines = formatLintFindings(lintResult, { showElementId: true, showSummary: true });
const lines = formatLintFindings(lintResult, {
showElementId: true,
showSummary: true,
verbose: args.verbose,
});
for (const line of lines) console.log(line);
process.exit(lintResult.totalErrors > 0 ? 1 : 0);
+11 -2
View File
@@ -8,6 +8,8 @@ export interface LintFormatOptions {
showSummary?: boolean;
/** Group errors before warnings per file (default: false — interleaved) */
errorsFirst?: boolean;
/** Include info-level findings in output (default: false — only errors/warnings) */
verbose?: boolean;
}
/**
@@ -17,7 +19,12 @@ export function formatLintFindings(
{ results, totalErrors, totalWarnings, totalInfos }: ProjectLintResult,
options: LintFormatOptions = {},
): string[] {
const { showElementId = true, showSummary = false, errorsFirst = false } = options;
const {
showElementId = true,
showSummary = false,
errorsFirst = false,
verbose = false,
} = options;
const lines: string[] = [];
const multiFile = results.length > 1;
@@ -25,6 +32,7 @@ export function formatLintFindings(
if (result.findings.length === 0) continue;
const format = (finding: (typeof result.findings)[0]) => {
if (!verbose && finding.severity === "info") return;
const prefix =
finding.severity === "error"
? c.error("✗")
@@ -41,6 +49,7 @@ export function formatLintFindings(
if (errorsFirst) {
for (const f of result.findings) if (f.severity === "error") format(f);
for (const f of result.findings) if (f.severity === "warning") format(f);
if (verbose) for (const f of result.findings) if (f.severity === "info") format(f);
} else {
for (const f of result.findings) format(f);
}
@@ -50,7 +59,7 @@ export function formatLintFindings(
const icon = totalErrors > 0 ? c.error("◇") : c.success("◇");
lines.push("");
const summaryParts = [`${totalErrors} error(s)`, `${totalWarnings} warning(s)`];
if (totalInfos > 0) summaryParts.push(`${totalInfos} info(s)`);
if (verbose && totalInfos > 0) summaryParts.push(`${totalInfos} info(s)`);
lines.push(`${icon} ${summaryParts.join(", ")}`);
}