feat(detector): deprecate --fast (now a no-op, full scan always)

Since the jsdom removal the static HTML/CSS analysis is fast (~4ms/file) and
covers every rule, so the regex-only `--fast` path only loses coverage (it
ran ~10 of 41 rules) for no real speed win. It's a foot-gun: a `--fast` scan
can read "clean" because most rules silently don't run.

Deprecate gracefully rather than hard-remove: the flag is still accepted (so
existing CI scripts don't break) but ignored, with a one-line stderr notice,
and the full scan always runs. Dropped from --help and the example. Removed
the `--fast` suggestion from the many-files warning and from critique.md's
scan guidance.

Ships to users via a CLI release (npm) and rides the next skill release in
the bundled detector. Tests updated to assert the deprecation behavior.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-05-28 15:50:53 -07:00
co-authored by Claude Opus 4.8
parent 772aa73aa3
commit f7f2bfc800
30 changed files with 215 additions and 130 deletions
@@ -58,12 +58,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .agents/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .agents/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .claude/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .claude/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .cursor/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .cursor/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .gemini/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .gemini/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .github/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .github/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .kiro/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .kiro/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .opencode/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .opencode/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
+2 -2
View File
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .pi/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .pi/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .qoder/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .qoder/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .rovodev/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .rovodev/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .trae-cn/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .trae-cn/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .trae/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .trae/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
+13 -7
View File
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
@@ -50,12 +50,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node .claude/skills/impeccable/scripts/detect.mjs --json [--fast] [target]
node .claude/skills/impeccable/scripts/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
@@ -79,7 +79,6 @@ function printUsage() {
Scan files or URLs for UI anti-patterns and design quality issues.
Options:
--fast Regex-only mode (skip static HTML/CSS analysis, faster but misses linked stylesheets)
--json Output results as JSON
--gpt Also report GPT-specific provider tells (off by default)
--gemini Also report Gemini-specific provider tells (off by default)
@@ -89,13 +88,12 @@ Detection modes:
HTML files Static HTML/CSS analysis (default, catches linked CSS)
Non-HTML files Regex pattern matching (CSS, JSX, TSX, etc.)
URLs Puppeteer full browser rendering (auto-detected)
--fast Forces regex for all files
Examples:
impeccable detect src/
impeccable detect index.html
impeccable detect https://example.com
impeccable detect --fast --json .`);
impeccable detect --json .`);
}
async function detectCli() {
@@ -107,7 +105,15 @@ async function detectCli() {
if (args[0] === 'detect') args = args.slice(1);
const jsonMode = args.includes('--json');
const helpMode = args.includes('--help');
const fastMode = args.includes('--fast');
// --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
// only loses coverage for no real speed win. Accept the flag for back-compat
// but ignore it and run the full scan.
if (args.includes('--fast')) {
process.stderr.write(
'Note: --fast is deprecated and ignored. The full scan is fast now and runs every rule.\n',
);
}
const providers = [];
if (args.includes('--gpt')) providers.push('gpt');
if (args.includes('--gemini')) providers.push('gemini');
@@ -177,7 +183,7 @@ async function detectCli() {
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` +
`Use --fast to skip static HTML/CSS analysis, or target a specific subdirectory.\n`
`Target a specific subdirectory to narrow scope.\n`
);
const ok = await confirm('Continue?');
if (!ok) { process.stderr.write('Aborted.\n'); process.exit(0); }
@@ -197,7 +203,7 @@ async function detectCli() {
for (const file of files) {
const ext = path.extname(file).toLowerCase();
let fileFindings;
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
fileFindings = await detectHtml(file, scanOptions);
} else {
fileFindings = detectText(fs.readFileSync(file, 'utf-8'), file, scanOptions);
@@ -214,7 +220,7 @@ async function detectCli() {
}
} else if (stat.isFile()) {
const ext = path.extname(resolved).toLowerCase();
if (!fastMode && HTML_EXTENSIONS.has(ext)) {
if (HTML_EXTENSIONS.has(ext)) {
allFindings.push(...await detectHtml(resolved, scanOptions));
} else {
allFindings.push(...detectText(fs.readFileSync(resolved, 'utf-8'), resolved, scanOptions));
+2 -2
View File
@@ -60,12 +60,12 @@ Run the bundled detector and browser visualization evidence. Assessment B is man
CLI scan:
```bash
node {{scripts_path}}/detect.mjs --json [--fast] [target]
node {{scripts_path}}/detect.mjs --json [target]
```
- Pass markup files/directories as `[target]`; do not pass CSS-only files.
- For URLs, skip CLI scan and use browser visualization.
- For 200+ scannable files, use `--fast`; for 500+, narrow scope or ask.
- For very large trees (500+ scannable files), narrow scope or ask.
- Exit code 0 = clean; 2 = findings.
- If the detector entrypoint is missing or fails to load, report deterministic scan unavailable and continue with browser/manual review.
+4 -3
View File
@@ -720,9 +720,10 @@ describe('CLI', () => {
expect(JSON.parse(stdout.trim())).toEqual([]);
});
test('--fast mode works', () => {
const { code } = run('--fast', path.join(FIXTURES, 'should-flag.html'));
expect(code).toBe(2);
test('--fast is accepted but deprecated (no-op, full scan still runs)', () => {
const { code, stderr } = run('--fast', path.join(FIXTURES, 'should-flag.html'));
expect(code).toBe(2); // still flags the planted anti-patterns via the full scan
expect(stderr).toContain('--fast is deprecated');
});
test('linked stylesheet detected (static HTML/CSS default)', () => {
+1 -1
View File
@@ -21,7 +21,7 @@ describe('skill detector bundle', () => {
test('critique references the bundled detector command', () => {
const critique = fs.readFileSync(path.join(ROOT, 'skill/reference/critique.md'), 'utf-8');
expect(critique).toContain('node {{scripts_path}}/detect.mjs --json [--fast] [target]');
expect(critique).toContain('node {{scripts_path}}/detect.mjs --json [target]');
expect(critique).not.toContain('npx impeccable detect');
});
});