#!/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