mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
Sync generated provider output
This commit is contained in:
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ import {
|
||||
// Output formatting
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function formatFindingSummary(count) {
|
||||
return `${count} anti-pattern${count === 1 ? '' : 's'} found.`;
|
||||
}
|
||||
|
||||
function formatFindings(findings, jsonMode) {
|
||||
if (jsonMode) return JSON.stringify(findings, null, 2);
|
||||
|
||||
@@ -39,7 +43,7 @@ function formatFindings(findings, jsonMode) {
|
||||
out.push(` → ${item.description}`);
|
||||
}
|
||||
}
|
||||
out.push(`\n${findings.length} anti-pattern${findings.length === 1 ? '' : 's'} found.`);
|
||||
out.push(`\n${formatFindingSummary(findings.length)}`);
|
||||
return out.join('\n');
|
||||
}
|
||||
|
||||
@@ -86,6 +90,7 @@ Scan files or URLs for UI anti-patterns and design quality issues.
|
||||
|
||||
Options:
|
||||
--json Output results as JSON
|
||||
--quiet In text mode, only print the final findings count
|
||||
--gpt Also report GPT-specific provider tells (off by default)
|
||||
--gemini Also report Gemini-specific provider tells (off by default)
|
||||
--no-config Do not apply project config, detector ignores, or DESIGN.md
|
||||
@@ -118,6 +123,7 @@ async function detectCli() {
|
||||
});
|
||||
if (args[0] === 'detect') args = args.slice(1);
|
||||
const jsonMode = args.includes('--json');
|
||||
const quietMode = args.includes('--quiet');
|
||||
const helpMode = args.includes('--help');
|
||||
// --fast (regex-only) is deprecated: since the jsdom removal, the static
|
||||
// HTML/CSS analysis is fast and covers every rule, so the regex-only path
|
||||
@@ -169,8 +175,8 @@ async function detectCli() {
|
||||
catch { process.stderr.write(`Warning: cannot access ${target}\n`); continue; }
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
// Check for framework dev server config (skip in JSON mode to avoid polluting output)
|
||||
if (!jsonMode) {
|
||||
// Check for framework dev server config (skip in JSON/quiet modes to avoid polluting output)
|
||||
if (!jsonMode && !quietMode) {
|
||||
const fwConfig = detectFrameworkConfig(resolved);
|
||||
if (fwConfig) {
|
||||
const probe = await isPortListening(fwConfig.port, fwConfig.fingerprint);
|
||||
@@ -200,7 +206,7 @@ async function detectCli() {
|
||||
const htmlCount = files.filter(f => HTML_EXTENSIONS.has(path.extname(f).toLowerCase())).length;
|
||||
|
||||
// Warn and confirm if scanning many files (static HTML/CSS processes each HTML file)
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode) {
|
||||
if (files.length > 50 && process.stdin.isTTY && !jsonMode && !quietMode) {
|
||||
process.stderr.write(
|
||||
`\nFound ${files.length} files (${htmlCount} HTML) in ${target}.\n` +
|
||||
`Scanning may take a while${htmlCount > 10 ? ' (static HTML/CSS processes each HTML file individually)' : ''}.\n` +
|
||||
@@ -258,6 +264,7 @@ async function detectCli() {
|
||||
|
||||
if (allFindings.length > 0) {
|
||||
if (jsonMode) process.stdout.write(formatFindings(allFindings, true) + '\n');
|
||||
else if (quietMode) process.stderr.write(formatFindingSummary(allFindings.length) + '\n');
|
||||
else process.stderr.write(formatFindings(allFindings, false) + '\n');
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user