#!/usr/bin/env sh set -eu MODE="${1:-report}" ROOT_DIR="$(CDPATH= cd "$(dirname "$0")/.." && pwd -P)" WEB_SRC="${ROOT_DIR}/web/src" if [ ! -d "${WEB_SRC}" ]; then echo "error: web source directory not found: ${WEB_SRC}" >&2 exit 2 fi RG_BASE='--glob=*.ts --glob=*.tsx --glob=*.css --glob=!**/*.test.ts --glob=!**/*.test.tsx --glob=!**/*.dom.test.tsx --glob=!**/test/** --glob=!**/assets/**' APPROVED_UI_GLOB='!components/ui/**' section() { printf '\n== %s ==\n' "$1" } count_matches() { pattern="$1" shift # shellcheck disable=SC2086 rg -n $RG_BASE "$@" "${pattern}" "${WEB_SRC}" | wc -l | tr -d ' ' } print_matches() { pattern="$1" shift # shellcheck disable=SC2086 rg -n $RG_BASE "$@" "${pattern}" "${WEB_SRC}" || true } raw_controls_count="$(count_matches '<(button|input|textarea|select)(\s|>)' --glob="${APPROVED_UI_GLOB}")" legacy_classes_count="$(count_matches '\b(surface-card|surface-muted|badge|input-shell)\b')" hardcoded_colors_count="$(count_matches '(#[0-9a-f]{3,8}\b|rgba?\()')" direct_common_ui_count="$(count_matches '@bytelyst/ui' --glob="${APPROVED_UI_GLOB}")" echo "UI drift audit mode=${MODE}" echo "raw interactive controls outside approved primitives: ${raw_controls_count}" echo "legacy global surface classes: ${legacy_classes_count}" echo "hardcoded color literals: ${hardcoded_colors_count}" echo "direct @bytelyst/ui imports outside product adapter: ${direct_common_ui_count}" section "Raw Interactive Controls" print_matches '<(button|input|textarea|select)(\s|>)' --glob="${APPROVED_UI_GLOB}" section "Legacy Global Surface Classes" print_matches '\b(surface-card|surface-muted|badge|input-shell)\b' section "Hardcoded Color Literals" print_matches '(#[0-9a-f]{3,8}\b|rgba?\()' section "Direct Common UI Imports Outside Adapter" print_matches '@bytelyst/ui' --glob="${APPROVED_UI_GLOB}" total_findings=$((raw_controls_count + legacy_classes_count + hardcoded_colors_count + direct_common_ui_count)) if [ "${MODE}" = "strict" ] && [ "${total_findings}" -gt 0 ]; then echo "error: strict UI drift audit failed with ${total_findings} findings" >&2 exit 1 fi exit 0