#!/usr/bin/env node
/**
* Anti-Pattern Detector for Impeccable
* Copyright (c) 2026 Paul Bakaus
* SPDX-License-Identifier: Apache-2.0
*
* Universal file — auto-detects environment (browser vs Node) and adapts.
*
* Node usage:
* node detect-antipatterns.mjs [file-or-dir...] # jsdom for HTML, regex for rest
* node detect-antipatterns.mjs https://... # Puppeteer (auto)
* node detect-antipatterns.mjs --fast [files...] # regex-only (skip jsdom)
* node detect-antipatterns.mjs --json # JSON output
*
* Browser usage:
*
* Re-scan: window.impeccableScan()
*
* Exit codes: 0 = clean, 2 = findings
*/
// ─── Environment ────────────────────────────────────────────────────────────
const IS_BROWSER = typeof window !== 'undefined';
const IS_NODE = !IS_BROWSER;
// @browser-strip-start
let fs, path, fileURLToPath;
if (!IS_BROWSER) {
fs = (await import('node:fs')).default;
path = (await import('node:path')).default;
fileURLToPath = (await import('node:url')).fileURLToPath;
}
// @browser-strip-end
// ─── Section 1: Constants ───────────────────────────────────────────────────
const SAFE_TAGS = new Set([
'blockquote', 'nav', 'a', 'input', 'textarea', 'select',
'pre', 'code', 'span', 'th', 'td', 'tr', 'li', 'label',
'button', 'hr', 'html', 'head', 'body', 'script', 'style',
'link', 'meta', 'title', 'br', 'img', 'svg', 'path', 'circle',
'rect', 'line', 'polyline', 'polygon', 'g', 'defs', 'use',
]);
// Per-check safe-tags override for the border (side-tab / border-accent)
// rule. We intentionally re-allow