diff --git a/.agents/skills/impeccable/scripts/detector/cli/main.mjs b/.agents/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.agents/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.agents/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.claude/skills/impeccable/scripts/detector/cli/main.mjs b/.claude/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.claude/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.claude/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.cursor/skills/impeccable/scripts/detector/cli/main.mjs b/.cursor/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.cursor/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.cursor/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.gemini/skills/impeccable/scripts/detector/cli/main.mjs b/.gemini/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.gemini/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.gemini/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.github/skills/impeccable/scripts/detector/cli/main.mjs b/.github/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.github/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.github/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.kiro/skills/impeccable/scripts/detector/cli/main.mjs b/.kiro/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.kiro/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.kiro/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.opencode/skills/impeccable/scripts/detector/cli/main.mjs b/.opencode/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.opencode/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.opencode/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.pi/skills/impeccable/scripts/detector/cli/main.mjs b/.pi/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.pi/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.pi/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.qoder/skills/impeccable/scripts/detector/cli/main.mjs b/.qoder/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.qoder/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.qoder/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.rovodev/skills/impeccable/scripts/detector/cli/main.mjs b/.rovodev/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.rovodev/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.rovodev/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.trae-cn/skills/impeccable/scripts/detector/cli/main.mjs b/.trae-cn/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.trae-cn/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.trae-cn/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/.trae/skills/impeccable/scripts/detector/cli/main.mjs b/.trae/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/.trae/skills/impeccable/scripts/detector/cli/main.mjs +++ b/.trae/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); } diff --git a/plugin/skills/impeccable/scripts/detector/cli/main.mjs b/plugin/skills/impeccable/scripts/detector/cli/main.mjs index 84e7a826e..89a53579a 100644 --- a/plugin/skills/impeccable/scripts/detector/cli/main.mjs +++ b/plugin/skills/impeccable/scripts/detector/cli/main.mjs @@ -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); }