uilint-eslint 0.2.21 → 0.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils/create-rule.ts","../src/rules/no-arbitrary-tailwind.ts","../src/rules/consistent-spacing.ts","../src/rules/consistent-dark-mode.ts","../src/rules/no-direct-store-import.ts","../src/rules/prefer-zustand-state-management.ts","../src/utils/export-resolver.ts","../src/utils/component-parser.ts","../src/utils/import-graph.ts","../src/rules/no-mixed-component-libraries.ts","../src/rules/semantic.ts","../src/utils/cache.ts","../src/utils/styleguide-loader.ts","../src/rules/semantic-vision.ts","../src/rules/enforce-absolute-imports.ts","../src/rules/no-any-in-props.ts","../src/rules/zustand-use-selectors.ts","../src/rules/no-prop-drilling-depth.ts","../src/rules/no-secrets-in-code.ts","../src/rules/require-input-validation.ts","../src/rule-registry.ts","../src/index.ts"],"sourcesContent":["/**\n * Rule creation helper using @typescript-eslint/utils\n */\n\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\n\nexport const createRule = ESLintUtils.RuleCreator(\n (name) =>\n `https://github.com/peter-suggate/uilint/blob/main/packages/uilint-eslint/docs/rules/${name}.md`\n);\n\n/**\n * Schema for prompting user to configure a rule option in the CLI\n */\nexport interface OptionFieldSchema {\n /** Field name in the options object */\n key: string;\n /** Display label for the prompt */\n label: string;\n /** Prompt type */\n type: \"text\" | \"number\" | \"boolean\" | \"select\" | \"multiselect\";\n /** Default value */\n defaultValue: unknown;\n /** Placeholder text (for text/number inputs) */\n placeholder?: string;\n /** Options for select/multiselect */\n options?: Array<{ value: string | number; label: string }>;\n /** Description/hint for the field */\n description?: string;\n}\n\n/**\n * Schema describing how to prompt for rule options during installation\n */\nexport interface RuleOptionSchema {\n /** Fields that can be configured for this rule */\n fields: OptionFieldSchema[];\n}\n\n/**\n * Colocated rule metadata - exported alongside each rule\n *\n * This structure keeps all rule metadata in the same file as the rule implementation,\n * making it easy to maintain and extend as new rules are added.\n */\nexport interface RuleMeta {\n /** Rule identifier (e.g., \"no-arbitrary-tailwind\") - must match filename */\n id: string;\n\n /** Display name for CLI (e.g., \"No Arbitrary Tailwind\") */\n name: string;\n\n /** Short description for CLI selection prompts (one line) */\n description: string;\n\n /** Default severity level */\n defaultSeverity: \"error\" | \"warn\" | \"off\";\n\n /** Category for grouping in CLI */\n category: \"static\" | \"semantic\";\n\n /** Whether this rule requires a styleguide file */\n requiresStyleguide?: boolean;\n\n /** Default options for the rule (passed as second element in ESLint config) */\n defaultOptions?: unknown[];\n\n /** Schema for prompting user to configure options during install */\n optionSchema?: RuleOptionSchema;\n\n /**\n * Detailed documentation in markdown format.\n * Should include:\n * - What the rule does\n * - Why it's useful\n * - Examples of incorrect and correct code\n * - Configuration options explained\n */\n docs: string;\n}\n\n/**\n * Helper to define rule metadata with type safety\n */\nexport function defineRuleMeta(meta: RuleMeta): RuleMeta {\n return meta;\n}\n","/**\n * Rule: no-arbitrary-tailwind\n *\n * Forbids arbitrary Tailwind values like w-[123px], bg-[#fff], etc.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"noArbitraryValue\";\ntype Options = [];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-arbitrary-tailwind\",\n name: \"No Arbitrary Tailwind\",\n description: \"Forbid arbitrary values like w-[123px], bg-[#fff]\",\n defaultSeverity: \"error\",\n category: \"static\",\n docs: `\n## What it does\n\nPrevents the use of arbitrary Tailwind CSS values (bracket notation) in your codebase.\nArbitrary values like \\`w-[123px]\\`, \\`bg-[#ff5500]\\`, or \\`text-[14px]\\` bypass Tailwind's\ndesign system and can lead to inconsistent UI.\n\n## Why it's useful\n\n- **Consistency**: Forces use of your design system's spacing, colors, and typography scales\n- **Maintainability**: Changes to design tokens automatically propagate everywhere\n- **Performance**: Arbitrary values generate extra CSS that can't be deduplicated\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n<div className=\"w-[123px] h-[456px]\"> // Arbitrary dimensions\n<div className=\"bg-[#ff5500]\"> // Arbitrary color\n<div className=\"text-[14px]\"> // Arbitrary font size\n<div className=\"p-[7px]\"> // Arbitrary padding\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n<div className=\"w-32 h-96\"> // Use spacing scale\n<div className=\"bg-orange-500\"> // Use color palette\n<div className=\"text-sm\"> // Use typography scale\n<div className=\"p-2\"> // Use spacing scale\n\\`\\`\\`\n\n## Notes\n\n- Data attributes like \\`data-[state=open]\\` are allowed as they don't affect styling\n- If you need a truly custom value, consider extending your Tailwind config instead\n`,\n});\n\n// Regex to match arbitrary Tailwind values: word-[anything]\nconst ARBITRARY_VALUE_REGEX = /\\b[\\w-]+-\\[[^\\]]+\\]/g;\n\nexport default createRule<Options, MessageIds>({\n name: \"no-arbitrary-tailwind\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Forbid arbitrary Tailwind values like w-[123px]\",\n },\n messages: {\n noArbitraryValue:\n \"Avoid arbitrary Tailwind value '{{value}}'. Use the spacing/color scale instead.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n // Handle string literal: className=\"...\"\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n checkClassString(context, value, value.value);\n }\n\n // Handle JSX expression: className={...}\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n\n // Direct string: className={\"...\"}\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n checkClassString(context, expr, expr.value);\n }\n\n // Template literal: className={`...`}\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n checkClassString(context, quasi, quasi.value.raw);\n }\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (name === \"cn\" || name === \"clsx\" || name === \"classnames\") {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n checkClassString(context, arg, arg.value);\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n checkClassString(context, quasi, quasi.value.raw);\n }\n }\n }\n }\n },\n };\n },\n});\n\nfunction checkClassString(\n context: Parameters<\n ReturnType<typeof createRule<[], \"noArbitraryValue\">>[\"create\"]\n >[0],\n node: TSESTree.Node,\n classString: string\n) {\n const matches = classString.matchAll(ARBITRARY_VALUE_REGEX);\n\n for (const match of matches) {\n // Ignore data attributes (e.g., data-[value], data-test-[something])\n if (match[0].startsWith(\"data-\")) {\n continue;\n }\n\n context.report({\n node,\n messageId: \"noArbitraryValue\",\n data: { value: match[0] },\n });\n }\n}\n","/**\n * Rule: consistent-spacing\n *\n * Enforces use of spacing scale values in gap, padding, margin utilities.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"invalidSpacing\";\ntype Options = [\n {\n scale?: number[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"consistent-spacing\",\n name: \"Consistent Spacing\",\n description: \"Enforce spacing scale (no magic numbers in gap/padding)\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ scale: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16] }],\n optionSchema: {\n fields: [\n {\n key: \"scale\",\n label: \"Allowed spacing values\",\n type: \"text\",\n defaultValue: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16],\n placeholder: \"0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16\",\n description: \"Comma-separated list of allowed spacing values\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnsures all spacing utilities (padding, margin, gap, etc.) use values from a defined scale.\nThis prevents \"magic number\" spacing values that create visual inconsistency.\n\n## Why it's useful\n\n- **Visual rhythm**: Consistent spacing creates a professional, cohesive feel\n- **Design system compliance**: Enforces your spacing tokens\n- **Easier maintenance**: Spacing changes can be made systematically\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n<div className=\"p-7\"> // 7 isn't in the default scale\n<div className=\"gap-13\"> // 13 isn't in the default scale\n<div className=\"mt-9\"> // 9 isn't in the default scale\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n<div className=\"p-8\"> // 8 is in the scale\n<div className=\"gap-12\"> // 12 is in the scale\n<div className=\"mt-10\"> // 10 is in the scale\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/consistent-spacing\": [\"warn\", {\n scale: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24]\n}]\n\\`\\`\\`\n\nThe default scale is Tailwind's standard spacing values. Customize it to match your design system.\n`,\n});\n\n// Default Tailwind spacing scale\nconst DEFAULT_SCALE = [\n 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24,\n 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96,\n];\n\n// Spacing utilities that take numeric values\nconst SPACING_PREFIXES = [\n \"p-\",\n \"px-\",\n \"py-\",\n \"pt-\",\n \"pr-\",\n \"pb-\",\n \"pl-\",\n \"ps-\",\n \"pe-\",\n \"m-\",\n \"mx-\",\n \"my-\",\n \"mt-\",\n \"mr-\",\n \"mb-\",\n \"ml-\",\n \"ms-\",\n \"me-\",\n \"gap-\",\n \"gap-x-\",\n \"gap-y-\",\n \"space-x-\",\n \"space-y-\",\n \"inset-\",\n \"inset-x-\",\n \"inset-y-\",\n \"top-\",\n \"right-\",\n \"bottom-\",\n \"left-\",\n \"w-\",\n \"h-\",\n \"min-w-\",\n \"min-h-\",\n \"max-w-\",\n \"max-h-\",\n \"size-\",\n];\n\n// Build regex to match spacing utilities with numeric values\nfunction buildSpacingRegex(): RegExp {\n const prefixes = SPACING_PREFIXES.map((p) => p.replace(\"-\", \"\\\\-\")).join(\"|\");\n // Match prefix followed by a number (possibly with decimal)\n return new RegExp(`\\\\b(${prefixes})(\\\\d+\\\\.?\\\\d*)\\\\b`, \"g\");\n}\n\nconst SPACING_REGEX = buildSpacingRegex();\n\nexport default createRule<Options, MessageIds>({\n name: \"consistent-spacing\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Enforce spacing scale (no magic numbers in gap/padding)\",\n },\n messages: {\n invalidSpacing:\n \"Spacing value '{{value}}' is not in the allowed scale. Use one of: {{allowed}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n scale: {\n type: \"array\",\n items: { type: \"number\" },\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ scale: DEFAULT_SCALE }],\n create(context) {\n const options = context.options[0] || {};\n const scale = new Set((options.scale || DEFAULT_SCALE).map(String));\n const scaleList = [...scale].slice(0, 10).join(\", \") + \"...\";\n\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n checkSpacing(context, node, value.value, scale, scaleList);\n }\n\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n checkSpacing(context, node, expr.value, scale, scaleList);\n }\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n checkSpacing(context, node, quasi.value.raw, scale, scaleList);\n }\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (name === \"cn\" || name === \"clsx\" || name === \"classnames\") {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n checkSpacing(context, arg, arg.value, scale, scaleList);\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n checkSpacing(context, quasi, quasi.value.raw, scale, scaleList);\n }\n }\n }\n }\n },\n };\n },\n});\n\nfunction checkSpacing(\n context: Parameters<\n ReturnType<typeof createRule<Options, \"invalidSpacing\">>[\"create\"]\n >[0],\n node: TSESTree.Node,\n classString: string,\n scale: Set<string>,\n scaleList: string\n) {\n // Reset regex state\n SPACING_REGEX.lastIndex = 0;\n\n let match;\n while ((match = SPACING_REGEX.exec(classString)) !== null) {\n const [, , value] = match;\n if (value && !scale.has(value)) {\n context.report({\n node,\n messageId: \"invalidSpacing\",\n data: { value, allowed: scaleList },\n });\n }\n }\n}\n","/**\n * Rule: consistent-dark-mode\n *\n * Ensures consistent dark mode theming in Tailwind CSS classes.\n * - Error: When some color classes have dark: variants but others don't within the same element\n * - Warning: When Tailwind color classes are used in a file but no dark: theming exists\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"inconsistentDarkMode\" | \"missingDarkMode\";\ntype Options = [\n {\n /** Whether to warn when no dark mode classes are found in a file that uses Tailwind colors. Default: true */\n warnOnMissingDarkMode?: boolean;\n }?\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"consistent-dark-mode\",\n name: \"Consistent Dark Mode\",\n description: \"Ensure consistent dark: theming (error on mix, warn on missing)\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ warnOnMissingDarkMode: true }],\n optionSchema: {\n fields: [\n {\n key: \"warnOnMissingDarkMode\",\n label: \"Warn when elements lack dark: variant\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Enable warnings for elements missing dark mode variants\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects inconsistent dark mode theming in Tailwind CSS classes. Reports errors when\nsome color classes in an element have \\`dark:\\` variants but others don't, and optionally\nwarns when a file uses color classes without any dark mode theming.\n\n## Why it's useful\n\n- **Prevents broken dark mode**: Catches cases where some colors change in dark mode but others don't\n- **Encourages completeness**: Prompts you to add dark mode support where it's missing\n- **Supports semantic colors**: Automatically ignores shadcn/CSS variable colors that handle dark mode internally\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Some colors have dark variants, others don't\n<div className=\"bg-white dark:bg-slate-900 text-black\">\n// ^^^^^^^^^ missing dark: variant\n\n// Mix of themed and unthemed\n<button className=\"bg-blue-500 dark:bg-blue-600 border-gray-300\">\n// ^^^^^^^^^^^^^^^ missing dark: variant\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// All color classes have dark variants\n<div className=\"bg-white dark:bg-slate-900 text-black dark:text-white\">\n\n// Using semantic colors (automatically themed)\n<div className=\"bg-background text-foreground\">\n\n// Consistent theming\n<button className=\"bg-blue-500 dark:bg-blue-600 border-gray-300 dark:border-gray-600\">\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/consistent-dark-mode\": [\"error\", {\n warnOnMissingDarkMode: true // Warn if file uses colors without any dark mode\n}]\n\\`\\`\\`\n\n## Notes\n\n- Semantic colors (like shadcn's \\`background\\`, \\`foreground\\`, \\`primary\\`, etc.) are exempt\n- Transparent, inherit, and current values are exempt\n- Non-color utilities (like \\`text-lg\\`, \\`border-2\\`) are correctly ignored\n`,\n});\n\n// Color-related class prefixes that should have dark mode variants\nconst COLOR_PREFIXES = [\n \"bg-\",\n \"text-\",\n \"border-\",\n \"border-t-\",\n \"border-r-\",\n \"border-b-\",\n \"border-l-\",\n \"border-x-\",\n \"border-y-\",\n \"ring-\",\n \"ring-offset-\",\n \"divide-\",\n \"outline-\",\n \"shadow-\",\n \"accent-\",\n \"caret-\",\n \"fill-\",\n \"stroke-\",\n \"decoration-\",\n \"placeholder-\",\n \"from-\",\n \"via-\",\n \"to-\",\n];\n\n// Values that don't need dark variants (colorless or inherited)\nconst EXEMPT_SUFFIXES = [\"transparent\", \"inherit\", \"current\", \"auto\", \"none\"];\n\n// Known non-color utilities that use color prefixes\n// These are utilities like text-lg (font size), text-center (alignment), etc.\nconst NON_COLOR_UTILITIES = new Set([\n // Exempt values (colorless or inherited) - don't need dark variants\n \"transparent\",\n \"inherit\",\n \"current\",\n \"auto\",\n \"none\",\n // text- utilities that aren't colors\n \"xs\",\n \"sm\",\n \"base\",\n \"lg\",\n \"xl\",\n \"2xl\",\n \"3xl\",\n \"4xl\",\n \"5xl\",\n \"6xl\",\n \"7xl\",\n \"8xl\",\n \"9xl\",\n \"left\",\n \"center\",\n \"right\",\n \"justify\",\n \"start\",\n \"end\",\n \"wrap\",\n \"nowrap\",\n \"balance\",\n \"pretty\",\n \"ellipsis\",\n \"clip\",\n // border- utilities that aren't colors\n \"0\",\n \"2\",\n \"4\",\n \"8\",\n \"solid\",\n \"dashed\",\n \"dotted\",\n \"double\",\n \"hidden\",\n \"collapse\",\n \"separate\",\n // shadow- utilities that aren't colors\n // Note: \"sm\", \"lg\", \"xl\", \"2xl\" already included above\n \"md\",\n \"inner\",\n // ring- utilities that aren't colors\n // Note: \"0\", \"2\", \"4\", \"8\" already included above\n \"1\",\n \"inset\",\n // outline- utilities that aren't colors\n // Note: numeric values already included\n \"offset-0\",\n \"offset-1\",\n \"offset-2\",\n \"offset-4\",\n \"offset-8\",\n // decoration- utilities that aren't colors\n // Note: \"solid\", \"double\", \"dotted\", \"dashed\" already included\n \"wavy\",\n \"from-font\",\n \"clone\",\n \"slice\",\n // divide- utilities that aren't colors\n \"x\",\n \"y\",\n \"x-0\",\n \"x-2\",\n \"x-4\",\n \"x-8\",\n \"y-0\",\n \"y-2\",\n \"y-4\",\n \"y-8\",\n \"x-reverse\",\n \"y-reverse\",\n // gradient direction utilities (from-, via-, to- prefixes)\n \"t\",\n \"tr\",\n \"r\",\n \"br\",\n \"b\",\n \"bl\",\n \"l\",\n \"tl\",\n]);\n\n// Semantic color names used by theming systems like shadcn\n// These are CSS variable-based colors that handle dark mode automatically\nconst SEMANTIC_COLOR_NAMES = new Set([\n // Core shadcn colors\n \"background\",\n \"foreground\",\n // Component colors\n \"card\",\n \"card-foreground\",\n \"popover\",\n \"popover-foreground\",\n \"primary\",\n \"primary-foreground\",\n \"secondary\",\n \"secondary-foreground\",\n \"muted\",\n \"muted-foreground\",\n \"accent\",\n \"accent-foreground\",\n \"destructive\",\n \"destructive-foreground\",\n // Form/UI colors\n \"border\",\n \"input\",\n \"ring\",\n // Sidebar colors (shadcn sidebar component)\n \"sidebar\",\n \"sidebar-foreground\",\n \"sidebar-border\",\n \"sidebar-primary\",\n \"sidebar-primary-foreground\",\n \"sidebar-accent\",\n \"sidebar-accent-foreground\",\n \"sidebar-ring\",\n]);\n\n// Pattern for semantic chart colors (chart-1, chart-2, etc.)\nconst CHART_COLOR_PATTERN = /^chart-\\d+$/;\n\n/**\n * Check if a class has 'dark' in its variant chain\n */\nfunction hasDarkVariant(className: string): boolean {\n const parts = className.split(\":\");\n // All parts except the last are variants\n const variants = parts.slice(0, -1);\n return variants.includes(\"dark\");\n}\n\n/**\n * Get the base class (without any variants like hover:, dark:, md:, etc.)\n */\nfunction getBaseClass(className: string): string {\n const parts = className.split(\":\");\n return parts[parts.length - 1] || \"\";\n}\n\n/**\n * Find the color prefix this class uses, if any\n */\nfunction getColorPrefix(baseClass: string): string | null {\n // Sort by length descending to match more specific prefixes first\n // (e.g., \"border-t-\" before \"border-\")\n const sortedPrefixes = [...COLOR_PREFIXES].sort(\n (a, b) => b.length - a.length\n );\n return sortedPrefixes.find((p) => baseClass.startsWith(p)) || null;\n}\n\n/**\n * Check if the value is a semantic/themed color (e.g., shadcn)\n * These colors use CSS variables that automatically handle dark mode\n */\nfunction isSemanticColor(value: string): boolean {\n // Check for exact semantic color names\n if (SEMANTIC_COLOR_NAMES.has(value)) {\n return true;\n }\n\n // Check for chart colors (chart-1, chart-2, etc.)\n if (CHART_COLOR_PATTERN.test(value)) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if the value after the prefix looks like a color value\n * Uses an exclusion-based approach: anything that's not a known non-color utility\n * and not a semantic color is treated as a potential color.\n */\nfunction isColorValue(baseClass: string, prefix: string): boolean {\n const value = baseClass.slice(prefix.length);\n\n // Empty value is not a color\n if (!value) {\n return false;\n }\n\n // Check if it's a semantic/themed color (exempt from dark mode requirements)\n if (isSemanticColor(value)) {\n return false;\n }\n\n // Check if it's a known non-color utility\n if (NON_COLOR_UTILITIES.has(value)) {\n return false;\n }\n\n // Treat everything else as a potential color\n // This catches:\n // - Standard Tailwind colors: blue-500, slate-900, white, black\n // - Custom colors defined in tailwind.config: brand, primary (non-shadcn), custom-blue\n // - Arbitrary values: [#fff], [rgb(255,0,0)], [var(--my-color)]\n // - Opacity modifiers: blue-500/50, white/80\n return true;\n}\n\n/**\n * Check if a class is exempt from dark mode requirements\n */\nfunction isExempt(baseClass: string): boolean {\n return EXEMPT_SUFFIXES.some((suffix) => baseClass.endsWith(suffix));\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"consistent-dark-mode\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Ensure consistent dark mode theming in Tailwind classes\",\n },\n messages: {\n inconsistentDarkMode:\n \"Inconsistent dark mode: '{{unthemed}}' lack dark: variants while other color classes have them.\",\n missingDarkMode:\n \"No dark mode theming detected. Consider adding dark: variants for color classes.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n warnOnMissingDarkMode: {\n type: \"boolean\",\n description:\n \"Whether to warn when no dark mode classes are found in a file that uses Tailwind colors\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ warnOnMissingDarkMode: true }],\n create(context) {\n const options = context.options[0] || {};\n const warnOnMissingDarkMode = options.warnOnMissingDarkMode ?? true;\n\n let fileHasColorClasses = false;\n let fileHasDarkMode = false;\n const reportedNodes = new Set<TSESTree.Node>();\n\n function checkClassString(node: TSESTree.Node, classString: string) {\n const classes = classString.split(/\\s+/).filter(Boolean);\n if (classes.length === 0) return;\n\n // Track usage per color prefix: { hasLight, hasDark, lightClasses }\n const prefixUsage = new Map<\n string,\n { hasLight: boolean; hasDark: boolean; lightClasses: string[] }\n >();\n\n for (const cls of classes) {\n const baseClass = getBaseClass(cls);\n const prefix = getColorPrefix(baseClass);\n\n if (!prefix) continue;\n if (isExempt(baseClass)) continue;\n\n // Verify this is actually a color class, not something like text-lg\n if (!isColorValue(baseClass, prefix)) continue;\n\n if (!prefixUsage.has(prefix)) {\n prefixUsage.set(prefix, {\n hasLight: false,\n hasDark: false,\n lightClasses: [],\n });\n }\n\n const usage = prefixUsage.get(prefix)!;\n\n if (hasDarkVariant(cls)) {\n usage.hasDark = true;\n fileHasDarkMode = true;\n } else {\n usage.hasLight = true;\n usage.lightClasses.push(cls);\n }\n }\n\n // Track if file uses color classes\n if (prefixUsage.size > 0) {\n fileHasColorClasses = true;\n }\n\n // Check for inconsistency: some prefixes have dark variants, others don't\n const entries = Array.from(prefixUsage.entries());\n const hasSomeDark = entries.some(([_, u]) => u.hasDark);\n\n if (hasSomeDark) {\n const unthemedEntries = entries.filter(\n ([_, usage]) => usage.hasLight && !usage.hasDark\n );\n\n if (unthemedEntries.length > 0 && !reportedNodes.has(node)) {\n reportedNodes.add(node);\n // Collect the actual class names that lack dark variants\n const unthemedClasses = unthemedEntries.flatMap(\n ([_, u]) => u.lightClasses\n );\n\n context.report({\n node,\n messageId: \"inconsistentDarkMode\",\n data: { unthemed: unthemedClasses.join(\", \") },\n });\n }\n }\n }\n\n function processStringValue(node: TSESTree.Node, value: string) {\n checkClassString(node, value);\n }\n\n function processTemplateLiteral(node: TSESTree.TemplateLiteral) {\n for (const quasi of node.quasis) {\n checkClassString(quasi, quasi.value.raw);\n }\n }\n\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n // Handle string literal: className=\"...\"\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n processStringValue(value, value.value);\n }\n\n // Handle JSX expression: className={...}\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n\n // Direct string: className={\"...\"}\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n processStringValue(expr, expr.value);\n }\n\n // Template literal: className={`...`}\n if (expr.type === \"TemplateLiteral\") {\n processTemplateLiteral(expr);\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames(), cva() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (\n name === \"cn\" ||\n name === \"clsx\" ||\n name === \"classnames\" ||\n name === \"cva\" ||\n name === \"twMerge\"\n ) {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n processStringValue(arg, arg.value);\n }\n if (arg.type === \"TemplateLiteral\") {\n processTemplateLiteral(arg);\n }\n // Handle arrays of class strings\n if (arg.type === \"ArrayExpression\") {\n for (const element of arg.elements) {\n if (\n element?.type === \"Literal\" &&\n typeof element.value === \"string\"\n ) {\n processStringValue(element, element.value);\n }\n if (element?.type === \"TemplateLiteral\") {\n processTemplateLiteral(element);\n }\n }\n }\n }\n }\n },\n\n // At the end of the file, check if Tailwind colors are used without any dark mode\n \"Program:exit\"(node) {\n if (warnOnMissingDarkMode && fileHasColorClasses && !fileHasDarkMode) {\n context.report({\n node,\n messageId: \"missingDarkMode\",\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: no-direct-store-import\n *\n * Forbids direct Zustand store imports - prefer using hooks via context.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"noDirectImport\";\ntype Options = [\n {\n storePattern?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-direct-store-import\",\n name: \"No Direct Store Import\",\n description: \"Forbid direct Zustand store imports (use context hooks)\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ storePattern: \"use*Store\" }],\n optionSchema: {\n fields: [\n {\n key: \"storePattern\",\n label: \"Glob pattern for store files\",\n type: \"text\",\n defaultValue: \"use*Store\",\n placeholder: \"use*Store\",\n description: \"Pattern to match store file names\",\n },\n ],\n },\n docs: `\n## What it does\n\nPrevents direct imports of Zustand stores, encouraging the use of context-based hooks\nfor better dependency injection and testability.\n\n## Why it's useful\n\n- **Testability**: Context-based access allows easy mocking in tests\n- **Flexibility**: Store implementation can change without updating all consumers\n- **Dependency Injection**: Stores can be provided at different levels of the component tree\n- **Server Components**: Helps avoid accidentally importing stores in server components\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Directly importing the store\nimport { useAuthStore } from '../stores/auth-store';\nimport { useCartStore } from '@/stores/useCartStore';\n\nfunction MyComponent() {\n const user = useAuthStore((s) => s.user);\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using context-provided hooks\nimport { useAuth } from '../contexts/auth-context';\nimport { useCart } from '@/hooks/useCart';\n\nfunction MyComponent() {\n const { user } = useAuth();\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-direct-store-import\": [\"warn\", {\n storePattern: \"use*Store\" // Pattern to match store names\n}]\n\\`\\`\\`\n\n## Notes\n\n- The pattern uses glob syntax (\\`*\\` matches any characters)\n- Only triggers for imports from paths containing \"store\"\n- Works with both named and default imports\n`,\n});\n\n// Convert glob pattern to regex\nfunction patternToRegex(pattern: string): RegExp {\n const escaped = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\");\n return new RegExp(`^${escaped}$`);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-direct-store-import\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Forbid direct Zustand store imports (use hooks via context)\",\n },\n messages: {\n noDirectImport:\n \"Avoid importing store '{{name}}' directly. Use the store via a context hook instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n storePattern: {\n type: \"string\",\n description: \"Glob pattern for store names\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ storePattern: \"use*Store\" }],\n create(context) {\n const options = context.options[0] || {};\n const pattern = options.storePattern || \"use*Store\";\n const regex = patternToRegex(pattern);\n\n return {\n ImportDeclaration(node) {\n // Check if importing from a store file\n const source = node.source.value as string;\n if (!source.includes(\"store\")) return;\n\n // Check imported specifiers\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportSpecifier\") {\n const importedName =\n specifier.imported.type === \"Identifier\"\n ? specifier.imported.name\n : specifier.imported.value;\n\n if (regex.test(importedName)) {\n context.report({\n node: specifier,\n messageId: \"noDirectImport\",\n data: { name: importedName },\n });\n }\n }\n\n if (specifier.type === \"ImportDefaultSpecifier\") {\n const localName = specifier.local.name;\n if (regex.test(localName)) {\n context.report({\n node: specifier,\n messageId: \"noDirectImport\",\n data: { name: localName },\n });\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: prefer-zustand-state-management\n *\n * Detects excessive use of React state hooks (useState, useReducer, useContext)\n * in components and suggests using Zustand stores for better state management.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"excessiveStateHooks\";\ntype Options = [\n {\n /** Maximum number of state hooks before warning. Default: 3 */\n maxStateHooks?: number;\n /** Whether to count useState calls. Default: true */\n countUseState?: boolean;\n /** Whether to count useReducer calls. Default: true */\n countUseReducer?: boolean;\n /** Whether to count useContext calls. Default: true */\n countUseContext?: boolean;\n }?\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"prefer-zustand-state-management\",\n name: \"Prefer Zustand State Management\",\n description: \"Detect excessive useState/useReducer/useContext; suggest Zustand\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n maxStateHooks: 3,\n countUseState: true,\n countUseReducer: true,\n countUseContext: true,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"maxStateHooks\",\n label: \"Max state hooks before warning\",\n type: \"number\",\n defaultValue: 3,\n placeholder: \"3\",\n description: \"Maximum number of state hooks allowed before warning\",\n },\n {\n key: \"countUseState\",\n label: \"Count useState hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n {\n key: \"countUseReducer\",\n label: \"Count useReducer hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n {\n key: \"countUseContext\",\n label: \"Count useContext hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n ],\n },\n docs: `\n## What it does\n\nDetects components that use many React state hooks (\\`useState\\`, \\`useReducer\\`, \\`useContext\\`)\nand suggests consolidating state into a Zustand store for better maintainability.\n\n## Why it's useful\n\n- **Simplifies components**: Fewer hooks means less cognitive overhead\n- **Centralizes state**: Related state lives together in a store\n- **Better performance**: Zustand's selector pattern prevents unnecessary re-renders\n- **Easier testing**: Store logic can be tested independently of components\n\n## Examples\n\n### ❌ Incorrect (with default maxStateHooks: 3)\n\n\\`\\`\\`tsx\nfunction UserProfile() {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [avatar, setAvatar] = useState(null);\n const [isLoading, setIsLoading] = useState(false); // 4 hooks = warning\n // ...\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using a Zustand store\nconst useUserStore = create((set) => ({\n name: '',\n email: '',\n avatar: null,\n isLoading: false,\n setName: (name) => set({ name }),\n // ...\n}));\n\nfunction UserProfile() {\n const { name, email, avatar, isLoading } = useUserStore();\n // Much cleaner!\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/prefer-zustand-state-management\": [\"warn\", {\n maxStateHooks: 3, // Warn when exceeding this count\n countUseState: true, // Include useState in count\n countUseReducer: true, // Include useReducer in count\n countUseContext: true // Include useContext in count\n}]\n\\`\\`\\`\n\n## Notes\n\n- Custom hooks (starting with \\`use\\` lowercase) are exempt from this rule\n- Only counts hooks at the top level of the component, not in nested functions\n- Adjust \\`maxStateHooks\\` based on your team's preferences\n`,\n});\n\ninterface ComponentInfo {\n name: string;\n node: TSESTree.Node;\n hookCount: number;\n functionNode:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression;\n}\n\nconst STATE_HOOKS = new Set([\"useState\", \"useReducer\", \"useContext\"]);\n\nexport default createRule<Options, MessageIds>({\n name: \"prefer-zustand-state-management\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Detect excessive use of React state hooks and suggest Zustand stores\",\n },\n messages: {\n excessiveStateHooks:\n \"Component '{{component}}' has {{count}} state hooks (max: {{max}}). Consider using a Zustand store for state management.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxStateHooks: {\n type: \"number\",\n minimum: 1,\n description: \"Maximum number of state hooks before warning\",\n },\n countUseState: {\n type: \"boolean\",\n description: \"Whether to count useState calls\",\n },\n countUseReducer: {\n type: \"boolean\",\n description: \"Whether to count useReducer calls\",\n },\n countUseContext: {\n type: \"boolean\",\n description: \"Whether to count useContext calls\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxStateHooks: 3,\n countUseState: true,\n countUseReducer: true,\n countUseContext: true,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxStateHooks = options.maxStateHooks ?? 3;\n const countUseState = options.countUseState ?? true;\n const countUseReducer = options.countUseReducer ?? true;\n const countUseContext = options.countUseContext ?? true;\n\n // Stack to track current component context\n const componentStack: ComponentInfo[] = [];\n\n // Set of function nodes we've identified as components to check\n const componentFunctions = new Map<TSESTree.Node, ComponentInfo>();\n\n /**\n * Check if a function name indicates a React component (PascalCase)\n */\n function isComponentName(name: string | null | undefined): boolean {\n if (!name) return false;\n // Components start with uppercase, hooks start with lowercase \"use\"\n return /^[A-Z]/.test(name);\n }\n\n /**\n * Check if a function name indicates a custom hook (starts with \"use\")\n */\n function isCustomHookName(name: string | null | undefined): boolean {\n if (!name) return false;\n return /^use[A-Z]/.test(name);\n }\n\n /**\n * Get the name of a function from various declaration patterns\n */\n function getFunctionName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ): string | null {\n // Function declaration: function MyComponent() {}\n if (node.type === \"FunctionDeclaration\" && node.id) {\n return node.id.name;\n }\n\n // Check parent for variable declaration: const MyComponent = () => {}\n const parent = node.parent;\n\n if (\n parent?.type === \"VariableDeclarator\" &&\n parent.id.type === \"Identifier\"\n ) {\n return parent.id.name;\n }\n\n // Check for forwardRef/memo: const MyComponent = forwardRef(function MyComponent() {})\n // or const MyComponent = forwardRef(() => {})\n if (parent?.type === \"CallExpression\") {\n const callParent = parent.parent;\n if (\n callParent?.type === \"VariableDeclarator\" &&\n callParent.id.type === \"Identifier\"\n ) {\n return callParent.id.name;\n }\n }\n\n // Named function expression: const x = function MyComponent() {}\n if (node.type === \"FunctionExpression\" && node.id) {\n return node.id.name;\n }\n\n return null;\n }\n\n /**\n * Check if a hook call should be counted based on options\n */\n function shouldCountHook(hookName: string): boolean {\n switch (hookName) {\n case \"useState\":\n return countUseState;\n case \"useReducer\":\n return countUseReducer;\n case \"useContext\":\n return countUseContext;\n default:\n return false;\n }\n }\n\n /**\n * Get hook name from a call expression (handles both useState and React.useState)\n */\n function getHookName(callee: TSESTree.Expression): string | null {\n // Direct call: useState()\n if (callee.type === \"Identifier\" && STATE_HOOKS.has(callee.name)) {\n return callee.name;\n }\n\n // Member expression: React.useState()\n if (\n callee.type === \"MemberExpression\" &&\n callee.object.type === \"Identifier\" &&\n callee.object.name === \"React\" &&\n callee.property.type === \"Identifier\" &&\n STATE_HOOKS.has(callee.property.name)\n ) {\n return callee.property.name;\n }\n\n return null;\n }\n\n /**\n * Check if we're directly inside a component function (not in a nested function)\n */\n function isDirectChildOfComponent(\n node: TSESTree.Node,\n componentNode: TSESTree.Node\n ): boolean {\n let current: TSESTree.Node | undefined = node.parent;\n\n while (current) {\n // If we hit the component node, we're a direct child\n if (current === componentNode) {\n return true;\n }\n\n // If we hit another function first, we're nested\n if (\n current.type === \"FunctionDeclaration\" ||\n current.type === \"FunctionExpression\" ||\n current.type === \"ArrowFunctionExpression\"\n ) {\n return false;\n }\n\n current = current.parent;\n }\n\n return false;\n }\n\n /**\n * Enter a function that might be a component\n */\n function enterFunction(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ) {\n const name = getFunctionName(node);\n\n // Skip custom hooks - they're allowed to have many state hooks\n if (isCustomHookName(name)) {\n return;\n }\n\n // Skip non-component functions (lowercase names that aren't anonymous)\n if (name && !isComponentName(name)) {\n return;\n }\n\n // Track this as a potential component\n const componentInfo: ComponentInfo = {\n name: name || \"AnonymousComponent\",\n node,\n hookCount: 0,\n functionNode: node,\n };\n\n componentStack.push(componentInfo);\n componentFunctions.set(node, componentInfo);\n }\n\n /**\n * Exit a function and report if it had too many hooks\n */\n function exitFunction(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ) {\n const componentInfo = componentFunctions.get(node);\n\n if (!componentInfo) {\n return;\n }\n\n // Remove from stack\n const index = componentStack.findIndex((c) => c.functionNode === node);\n if (index !== -1) {\n componentStack.splice(index, 1);\n }\n\n // Check if exceeded threshold\n if (componentInfo.hookCount > maxStateHooks) {\n context.report({\n node: componentInfo.node,\n messageId: \"excessiveStateHooks\",\n data: {\n component: componentInfo.name,\n count: componentInfo.hookCount,\n max: maxStateHooks,\n },\n });\n }\n\n componentFunctions.delete(node);\n }\n\n return {\n FunctionDeclaration: enterFunction,\n FunctionExpression: enterFunction,\n ArrowFunctionExpression: enterFunction,\n \"FunctionDeclaration:exit\": exitFunction,\n \"FunctionExpression:exit\": exitFunction,\n \"ArrowFunctionExpression:exit\": exitFunction,\n\n CallExpression(node) {\n const hookName = getHookName(node.callee);\n\n if (!hookName || !shouldCountHook(hookName)) {\n return;\n }\n\n // Find the innermost component this hook belongs to\n // We iterate from the end to find the most recent (innermost) component\n for (let i = componentStack.length - 1; i >= 0; i--) {\n const component = componentStack[i];\n\n if (isDirectChildOfComponent(node, component.functionNode)) {\n component.hookCount++;\n break;\n }\n }\n },\n };\n },\n});\n","/**\n * Export Resolver\n *\n * Resolves import paths and finds export definitions, following re-exports\n * to their original source files.\n */\n\nimport { ResolverFactory } from \"oxc-resolver\";\nimport { parse } from \"@typescript-eslint/typescript-estree\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { dirname, join, extname } from \"path\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\n// Module-level resolver instance (reused across calls)\nlet resolverInstance: ReturnType<typeof ResolverFactory.prototype.sync> | null =\n null;\nlet resolverFactory: ResolverFactory | null = null;\n\n/**\n * Information about a resolved export\n */\nexport interface ResolvedExport {\n /** The name of the export (e.g., \"Button\") */\n name: string;\n /** Absolute path to the file containing the actual definition */\n filePath: string;\n /** The local name in the source file (may differ from export name) */\n localName: string;\n /** Whether this is a re-export (export { X } from './other') */\n isReexport: boolean;\n}\n\n/**\n * Cache for file exports to avoid re-parsing\n */\nconst exportCache = new Map<\n string,\n Map<string, { localName: string; reexportSource?: string }>\n>();\n\n/**\n * Cache for parsed ASTs\n */\nconst astCache = new Map<string, TSESTree.Program>();\n\n/**\n * Cache for resolved paths\n */\nconst resolvedPathCache = new Map<string, string | null>();\n\n/**\n * Get or create the resolver factory\n */\nfunction getResolverFactory(): ResolverFactory {\n if (!resolverFactory) {\n resolverFactory = new ResolverFactory({\n extensions: [\".tsx\", \".ts\", \".jsx\", \".js\"],\n mainFields: [\"module\", \"main\"],\n conditionNames: [\"import\", \"require\", \"node\", \"default\"],\n // Enable TypeScript path resolution\n tsconfig: {\n configFile: \"tsconfig.json\",\n references: \"auto\",\n },\n });\n }\n return resolverFactory;\n}\n\n/**\n * Resolve an import path to an absolute file path\n */\nexport function resolveImportPath(\n importSource: string,\n fromFile: string\n): string | null {\n const cacheKey = `${fromFile}::${importSource}`;\n\n if (resolvedPathCache.has(cacheKey)) {\n return resolvedPathCache.get(cacheKey) ?? null;\n }\n\n // Skip node_modules\n if (\n importSource.startsWith(\"react\") ||\n importSource.startsWith(\"next\") ||\n (!importSource.startsWith(\".\") &&\n !importSource.startsWith(\"@/\") &&\n !importSource.startsWith(\"~/\"))\n ) {\n // Check if it's a known external package\n if (\n importSource.includes(\"@mui/\") ||\n importSource.includes(\"@chakra-ui/\") ||\n importSource.includes(\"antd\") ||\n importSource.includes(\"@radix-ui/\")\n ) {\n // Return a marker for external packages - we don't resolve them but track them\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n\n try {\n const factory = getResolverFactory();\n const fromDir = dirname(fromFile);\n const result = factory.sync(fromDir, importSource);\n\n if (result.path) {\n resolvedPathCache.set(cacheKey, result.path);\n return result.path;\n }\n } catch {\n // Fallback: try manual resolution for common patterns\n const resolved = manualResolve(importSource, fromFile);\n resolvedPathCache.set(cacheKey, resolved);\n return resolved;\n }\n\n resolvedPathCache.set(cacheKey, null);\n return null;\n}\n\n/**\n * Manual fallback resolution for common patterns\n */\nfunction manualResolve(importSource: string, fromFile: string): string | null {\n const fromDir = dirname(fromFile);\n const extensions = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\n // Handle @/ alias - find tsconfig and resolve\n if (importSource.startsWith(\"@/\")) {\n const projectRoot = findProjectRoot(fromFile);\n if (projectRoot) {\n const relativePath = importSource.slice(2); // Remove @/\n for (const ext of extensions) {\n const candidate = join(projectRoot, relativePath + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(projectRoot, relativePath, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n }\n\n // Handle relative imports\n if (importSource.startsWith(\".\")) {\n for (const ext of extensions) {\n const candidate = join(fromDir, importSource + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(fromDir, importSource, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Find the project root by looking for tsconfig.json or package.json\n */\nfunction findProjectRoot(fromFile: string): string | null {\n let dir = dirname(fromFile);\n const root = \"/\";\n\n while (dir !== root) {\n if (existsSync(join(dir, \"tsconfig.json\"))) {\n return dir;\n }\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n dir = dirname(dir);\n }\n\n return null;\n}\n\n/**\n * Parse a file and cache the AST\n */\nexport function parseFile(filePath: string): TSESTree.Program | null {\n if (astCache.has(filePath)) {\n return astCache.get(filePath)!;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const ast = parse(content, {\n jsx: true,\n loc: true,\n range: true,\n });\n astCache.set(filePath, ast);\n return ast;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract export information from a file\n */\nfunction extractExports(\n filePath: string\n): Map<string, { localName: string; reexportSource?: string }> {\n if (exportCache.has(filePath)) {\n return exportCache.get(filePath)!;\n }\n\n const exports = new Map<\n string,\n { localName: string; reexportSource?: string }\n >();\n const ast = parseFile(filePath);\n\n if (!ast) {\n exportCache.set(filePath, exports);\n return exports;\n }\n\n for (const node of ast.body) {\n // Handle: export function Button() {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(node.declaration.id.name, {\n localName: node.declaration.id.name,\n });\n }\n\n // Handle: export const Button = () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (decl.id.type === \"Identifier\") {\n exports.set(decl.id.name, { localName: decl.id.name });\n }\n }\n }\n\n // Handle: export { Button } or export { Button as Btn }\n if (node.type === \"ExportNamedDeclaration\" && node.specifiers.length > 0) {\n const source = node.source?.value as string | undefined;\n for (const spec of node.specifiers) {\n if (spec.type === \"ExportSpecifier\") {\n const exportedName =\n spec.exported.type === \"Identifier\"\n ? spec.exported.name\n : spec.exported.value;\n const localName =\n spec.local.type === \"Identifier\"\n ? spec.local.name\n : spec.local.value;\n\n exports.set(exportedName, {\n localName,\n reexportSource: source,\n });\n }\n }\n }\n\n // Handle: export default function Button() {}\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(\"default\", { localName: node.declaration.id.name });\n }\n\n // Handle: export default Button\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"Identifier\"\n ) {\n exports.set(\"default\", { localName: node.declaration.name });\n }\n }\n\n exportCache.set(filePath, exports);\n return exports;\n}\n\n/**\n * Resolve an export to its original definition, following re-exports\n */\nexport function resolveExport(\n exportName: string,\n filePath: string,\n visited = new Set<string>()\n): ResolvedExport | null {\n // Cycle detection\n const key = `${filePath}::${exportName}`;\n if (visited.has(key)) {\n return null;\n }\n visited.add(key);\n\n const exports = extractExports(filePath);\n const exportInfo = exports.get(exportName);\n\n if (!exportInfo) {\n return null;\n }\n\n // If it's a re-export, follow the chain\n if (exportInfo.reexportSource) {\n const resolvedPath = resolveImportPath(exportInfo.reexportSource, filePath);\n if (resolvedPath) {\n return resolveExport(exportInfo.localName, resolvedPath, visited);\n }\n return null;\n }\n\n // This is the actual definition\n return {\n name: exportName,\n filePath,\n localName: exportInfo.localName,\n isReexport: false,\n };\n}\n\n/**\n * Clear all caches (useful for testing or watch mode)\n */\nexport function clearResolverCaches(): void {\n exportCache.clear();\n astCache.clear();\n resolvedPathCache.clear();\n}\n","/**\n * Component Parser\n *\n * Parses a single component's body to extract styling information\n * and identify nested component usage.\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { parseFile } from \"./export-resolver.js\";\n\n/**\n * Known UI library import patterns\n */\nexport type LibraryName = \"shadcn\" | \"mui\" | \"chakra\" | \"antd\";\n\nexport const LIBRARY_PATTERNS: Record<LibraryName, string[]> = {\n shadcn: [\"@/components/ui\", \"@radix-ui/\", \"components/ui/\"],\n mui: [\"@mui/material\", \"@mui/icons-material\", \"@emotion/\"],\n chakra: [\"@chakra-ui/\"],\n antd: [\"antd\", \"@ant-design/\"],\n};\n\n/**\n * Information about a component used within another component\n */\nexport interface UsedComponent {\n /** Component name (e.g., \"Button\", \"Card\") */\n name: string;\n /** Import source path (e.g., \"@mui/material\", \"./button\") */\n importSource: string;\n /** Line number where the component is used */\n line: number;\n /** Column number where the component is used */\n column: number;\n}\n\n/**\n * Styling information extracted from a component\n */\nexport interface ComponentStyleInfo {\n /** Tailwind classes used in the component */\n tailwindClasses: string[];\n /** Inline style objects (as string representations) */\n inlineStyles: string[];\n /** Other components used within this component */\n usedComponents: UsedComponent[];\n /** Directly detected library (from import source) */\n directLibrary: LibraryName | null;\n}\n\n/**\n * Import map for a file: localName -> importSource\n */\nexport type ImportMap = Map<string, string>;\n\n/**\n * Extract imports from a file's AST\n */\nexport function extractImports(ast: TSESTree.Program): ImportMap {\n const imports = new Map<string, string>();\n\n for (const node of ast.body) {\n if (node.type === \"ImportDeclaration\") {\n const source = node.source.value as string;\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\") {\n imports.set(spec.local.name, source);\n } else if (spec.type === \"ImportDefaultSpecifier\") {\n imports.set(spec.local.name, source);\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n imports.set(spec.local.name, source);\n }\n }\n }\n }\n\n return imports;\n}\n\n/**\n * Detect which UI library an import source belongs to\n */\nexport function detectLibraryFromSource(\n importSource: string\n): LibraryName | null {\n for (const [library, patterns] of Object.entries(LIBRARY_PATTERNS)) {\n if (patterns.some((p) => importSource.includes(p))) {\n return library as LibraryName;\n }\n }\n return null;\n}\n\n/**\n * Find a function/arrow function component definition by name in an AST\n */\nexport function findComponentDefinition(\n ast: TSESTree.Program,\n componentName: string\n): TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression | null {\n for (const node of ast.body) {\n // export function ComponentName() {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id?.name === componentName\n ) {\n return node.declaration;\n }\n\n // export const ComponentName = () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (\n decl.id.type === \"Identifier\" &&\n decl.id.name === componentName &&\n decl.init?.type === \"ArrowFunctionExpression\"\n ) {\n return decl.init;\n }\n }\n }\n\n // function ComponentName() {} (not exported directly)\n if (\n node.type === \"FunctionDeclaration\" &&\n node.id?.name === componentName\n ) {\n return node;\n }\n\n // const ComponentName = () => {}\n if (node.type === \"VariableDeclaration\") {\n for (const decl of node.declarations) {\n if (\n decl.id.type === \"Identifier\" &&\n decl.id.name === componentName &&\n decl.init?.type === \"ArrowFunctionExpression\"\n ) {\n return decl.init;\n }\n }\n }\n\n // export default function ComponentName() {}\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"FunctionDeclaration\" &&\n node.declaration.id?.name === componentName\n ) {\n return node.declaration;\n }\n }\n\n return null;\n}\n\n/**\n * Extract Tailwind classes from a className string\n */\nfunction extractTailwindClasses(classString: string): string[] {\n return classString.split(/\\s+/).filter(Boolean);\n}\n\n/**\n * Recursively traverse a node and extract styling info\n */\nfunction traverseForStyling(\n node: TSESTree.Node,\n imports: ImportMap,\n result: ComponentStyleInfo\n): void {\n if (!node || typeof node !== \"object\") return;\n\n // Handle JSX elements\n if (node.type === \"JSXElement\" && node.openingElement) {\n const opening = node.openingElement;\n\n // Check if this is a component (PascalCase) or HTML element\n if (\n opening.name.type === \"JSXIdentifier\" &&\n /^[A-Z]/.test(opening.name.name)\n ) {\n const componentName = opening.name.name;\n const importSource = imports.get(componentName);\n\n if (importSource) {\n result.usedComponents.push({\n name: componentName,\n importSource,\n line: opening.loc.start.line,\n column: opening.loc.start.column,\n });\n\n // Check if this import is from a known UI library\n const library = detectLibraryFromSource(importSource);\n if (library && !result.directLibrary) {\n result.directLibrary = library;\n }\n }\n }\n\n // Handle JSX member expressions like Modal.Header\n if (opening.name.type === \"JSXMemberExpression\") {\n let objectName: string | null = null;\n let current = opening.name.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n if (current.type === \"JSXIdentifier\") {\n objectName = current.name;\n }\n\n if (objectName) {\n const importSource = imports.get(objectName);\n if (importSource) {\n const library = detectLibraryFromSource(importSource);\n if (library && !result.directLibrary) {\n result.directLibrary = library;\n }\n }\n }\n }\n\n // Extract className/class attributes\n for (const attr of opening.attributes) {\n if (\n attr.type === \"JSXAttribute\" &&\n attr.name.type === \"JSXIdentifier\" &&\n (attr.name.name === \"className\" || attr.name.name === \"class\")\n ) {\n if (\n attr.value?.type === \"Literal\" &&\n typeof attr.value.value === \"string\"\n ) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(attr.value.value)\n );\n }\n if (attr.value?.type === \"JSXExpressionContainer\") {\n const expr = attr.value.expression;\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n result.tailwindClasses.push(...extractTailwindClasses(expr.value));\n }\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(quasi.value.raw)\n );\n }\n }\n }\n }\n\n // Extract inline styles\n if (\n attr.type === \"JSXAttribute\" &&\n attr.name.type === \"JSXIdentifier\" &&\n attr.name.name === \"style\"\n ) {\n if (attr.value?.type === \"JSXExpressionContainer\") {\n // Just note that there's an inline style - we don't parse the object\n result.inlineStyles.push(\"[inline style]\");\n }\n }\n }\n }\n\n // Handle cn(), clsx(), twMerge() calls\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"Identifier\" &&\n [\"cn\", \"clsx\", \"classnames\", \"twMerge\"].includes(node.callee.name)\n ) {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n result.tailwindClasses.push(...extractTailwindClasses(arg.value));\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(quasi.value.raw)\n );\n }\n }\n }\n }\n\n // Recursively traverse all properties\n for (const key of Object.keys(node)) {\n if (key === \"parent\" || key === \"loc\" || key === \"range\") continue;\n\n const child = (node as unknown as Record<string, unknown>)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\") {\n traverseForStyling(item as TSESTree.Node, imports, result);\n }\n }\n } else if (child && typeof child === \"object\") {\n traverseForStyling(child as TSESTree.Node, imports, result);\n }\n }\n}\n\n/**\n * Parse a component's body and extract styling information\n */\nexport function parseComponentBody(\n filePath: string,\n componentName: string\n): ComponentStyleInfo | null {\n const ast = parseFile(filePath);\n if (!ast) return null;\n\n const imports = extractImports(ast);\n const componentDef = findComponentDefinition(ast, componentName);\n\n if (!componentDef) {\n return null;\n }\n\n const result: ComponentStyleInfo = {\n tailwindClasses: [],\n inlineStyles: [],\n usedComponents: [],\n directLibrary: null,\n };\n\n // Traverse the component body\n if (componentDef.body) {\n traverseForStyling(componentDef.body, imports, result);\n }\n\n // Deduplicate classes\n result.tailwindClasses = [...new Set(result.tailwindClasses)];\n\n return result;\n}\n\n/**\n * Analyze a file and extract all component usages with their libraries\n * (used for the entry file analysis)\n */\nexport function analyzeFileImports(\n filePath: string\n): Map<string, { importSource: string; library: LibraryName | null }> {\n const ast = parseFile(filePath);\n if (!ast) return new Map();\n\n const result = new Map<\n string,\n { importSource: string; library: LibraryName | null }\n >();\n const imports = extractImports(ast);\n\n for (const [name, source] of imports) {\n result.set(name, {\n importSource: source,\n library: detectLibraryFromSource(source),\n });\n }\n\n return result;\n}\n","/**\n * Import Graph Service\n *\n * Provides demand-driven cross-file analysis to detect UI library usage\n * across component trees. Uses in-memory caching for performance.\n */\n\nimport {\n resolveImportPath,\n resolveExport,\n clearResolverCaches,\n} from \"./export-resolver.js\";\nimport {\n parseComponentBody,\n detectLibraryFromSource,\n type LibraryName,\n type ComponentStyleInfo,\n} from \"./component-parser.js\";\n\n/**\n * Information about a component's UI library usage\n */\nexport interface ComponentLibraryInfo {\n /** Direct library (from import source, e.g., \"@mui/material\" -> \"mui\") */\n library: LibraryName | null;\n /** Libraries used internally by this component (for local components) */\n internalLibraries: Set<LibraryName>;\n /** Evidence of which internal components caused the library detection */\n libraryEvidence: Array<{\n componentName: string;\n library: LibraryName;\n }>;\n /** Whether this is a local component (resolved from project files) */\n isLocalComponent: boolean;\n}\n\n/**\n * Cache for analyzed components: \"filePath::componentName\" -> ComponentLibraryInfo\n */\nconst componentLibraryCache = new Map<string, ComponentLibraryInfo>();\n\n/**\n * Get a singleton instance of the import graph service\n */\nexport function getImportGraphService() {\n return {\n getComponentLibrary,\n clearCache,\n };\n}\n\n/**\n * Analyze a component's library usage, including transitive dependencies\n *\n * @param contextFilePath - The file where the component is used (for resolving relative imports)\n * @param componentName - The name of the component (e.g., \"Button\", \"MyCard\")\n * @param importSource - The import source (e.g., \"@mui/material\", \"./components/cards\")\n * @returns Library information including direct and transitive library usage\n */\nexport function getComponentLibrary(\n contextFilePath: string,\n componentName: string,\n importSource: string\n): ComponentLibraryInfo {\n // Check if import source directly indicates a known library\n const directLibrary = detectLibraryFromSource(importSource);\n\n if (directLibrary) {\n // It's a direct import from a known library (e.g., @mui/material)\n return {\n library: directLibrary,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: false,\n };\n }\n\n // It's a local component - resolve and analyze it\n const resolvedPath = resolveImportPath(importSource, contextFilePath);\n\n if (!resolvedPath) {\n // Could not resolve - might be external or invalid\n return {\n library: null,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: false,\n };\n }\n\n // Check cache\n const cacheKey = `${resolvedPath}::${componentName}`;\n if (componentLibraryCache.has(cacheKey)) {\n return componentLibraryCache.get(cacheKey)!;\n }\n\n // Resolve re-exports to find the actual component definition\n const resolvedExport = resolveExport(componentName, resolvedPath);\n const actualFilePath = resolvedExport?.filePath ?? resolvedPath;\n const actualComponentName = resolvedExport?.localName ?? componentName;\n\n // Analyze the component body\n const result = analyzeComponentLibraries(\n actualFilePath,\n actualComponentName,\n new Set([cacheKey]) // Track visited to prevent cycles\n );\n\n componentLibraryCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Recursively analyze a component's library usage\n */\nfunction analyzeComponentLibraries(\n filePath: string,\n componentName: string,\n visited: Set<string>\n): ComponentLibraryInfo {\n const styleInfo = parseComponentBody(filePath, componentName);\n\n if (!styleInfo) {\n return {\n library: null,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: true,\n };\n }\n\n const internalLibraries = new Set<LibraryName>();\n const libraryEvidence: Array<{\n componentName: string;\n library: LibraryName;\n }> = [];\n\n // Check direct library usage within this component\n if (styleInfo.directLibrary) {\n internalLibraries.add(styleInfo.directLibrary);\n }\n\n // Analyze each used component\n for (const usedComponent of styleInfo.usedComponents) {\n const usedLibrary = detectLibraryFromSource(usedComponent.importSource);\n\n if (usedLibrary) {\n // Direct import from a known library\n internalLibraries.add(usedLibrary);\n libraryEvidence.push({\n componentName: usedComponent.name,\n library: usedLibrary,\n });\n } else {\n // It's a local component - recurse into it\n const resolvedPath = resolveImportPath(\n usedComponent.importSource,\n filePath\n );\n\n if (resolvedPath) {\n const cacheKey = `${resolvedPath}::${usedComponent.name}`;\n\n // Skip if already visited (cycle detection)\n if (!visited.has(cacheKey)) {\n visited.add(cacheKey);\n\n // Check cache first\n let nestedInfo: ComponentLibraryInfo;\n if (componentLibraryCache.has(cacheKey)) {\n nestedInfo = componentLibraryCache.get(cacheKey)!;\n } else {\n // Resolve re-exports\n const resolvedExport = resolveExport(\n usedComponent.name,\n resolvedPath\n );\n const actualFilePath = resolvedExport?.filePath ?? resolvedPath;\n const actualComponentName =\n resolvedExport?.localName ?? usedComponent.name;\n\n nestedInfo = analyzeComponentLibraries(\n actualFilePath,\n actualComponentName,\n visited\n );\n componentLibraryCache.set(cacheKey, nestedInfo);\n }\n\n // Aggregate the nested component's libraries\n if (nestedInfo.library) {\n internalLibraries.add(nestedInfo.library);\n libraryEvidence.push({\n componentName: usedComponent.name,\n library: nestedInfo.library,\n });\n }\n\n for (const lib of nestedInfo.internalLibraries) {\n internalLibraries.add(lib);\n }\n\n // Add evidence from nested components\n for (const evidence of nestedInfo.libraryEvidence) {\n libraryEvidence.push({\n componentName: `${usedComponent.name} → ${evidence.componentName}`,\n library: evidence.library,\n });\n }\n }\n }\n }\n }\n\n return {\n library: styleInfo.directLibrary,\n internalLibraries,\n libraryEvidence,\n isLocalComponent: true,\n };\n}\n\n/**\n * Clear all caches (useful for testing or between ESLint runs)\n */\nexport function clearCache(): void {\n componentLibraryCache.clear();\n clearResolverCaches();\n}\n\n// Re-export types for convenience\nexport type { LibraryName };\n","/**\n * Rule: no-mixed-component-libraries\n *\n * Forbids using non-preferred UI component libraries. Reports errors at\n * the JSX usage site, including transitive usage through local components.\n *\n * Examples:\n * - <MuiButton> from @mui/material -> error at <MuiButton> usage\n * - <MyCard> that internally uses MUI -> error at <MyCard> usage\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport {\n getComponentLibrary,\n type LibraryName,\n} from \"../utils/import-graph.js\";\n\ntype MessageIds = \"nonPreferredLibrary\" | \"transitiveNonPreferred\";\ntype Options = [\n {\n /** The preferred UI library. Components from other libraries will be flagged. */\n preferred: LibraryName;\n /** Additional libraries to detect (defaults to common ones) */\n libraries?: LibraryName[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-mixed-component-libraries\",\n name: \"No Mixed Component Libraries\",\n description: \"Forbid mixing component libraries (e.g., shadcn + MUI)\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ preferred: \"shadcn\", libraries: [\"shadcn\", \"mui\"] }],\n optionSchema: {\n fields: [\n {\n key: \"preferred\",\n label: \"Preferred component library\",\n type: \"select\",\n defaultValue: \"shadcn\",\n options: [\n { value: \"shadcn\", label: \"shadcn/ui\" },\n { value: \"mui\", label: \"MUI (Material-UI)\" },\n { value: \"chakra\", label: \"Chakra UI\" },\n { value: \"antd\", label: \"Ant Design\" },\n ],\n description: \"The preferred UI library. Components from other libraries will be flagged.\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects and reports when components from non-preferred UI libraries are used in your codebase.\nThis includes both direct imports and transitive usage through your own components that wrap\nnon-preferred libraries internally.\n\n## Why it's useful\n\n- **Consistency**: Ensures a uniform look and feel across your application\n- **Bundle size**: Prevents accidentally including multiple UI frameworks\n- **Maintenance**: Reduces the number of styling systems to maintain\n- **Migration support**: Helps identify what needs to change when migrating UI libraries\n\n## Examples\n\n### ❌ Incorrect (with preferred: \"shadcn\")\n\n\\`\\`\\`tsx\n// Direct MUI usage\nimport { Button } from '@mui/material';\n<Button>Click me</Button> // Error: Component <Button> is from mui\n\n// Transitive usage through local component\nimport { MyCard } from './components/MyCard'; // MyCard uses MUI internally\n<MyCard /> // Error: Component <MyCard> internally uses mui components\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using the preferred library\nimport { Button } from '@/components/ui/button';\nimport { Card } from '@/components/ui/card';\n\n<Button>Click me</Button>\n<Card>Content</Card>\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-mixed-component-libraries\": [\"error\", {\n preferred: \"shadcn\", // Your preferred library\n libraries: [\"shadcn\", \"mui\", \"chakra\", \"antd\"] // Libraries to detect\n}]\n\\`\\`\\`\n\n## Supported Libraries\n\n- **shadcn**: shadcn/ui components (imports from \\`@/components/ui/\\`)\n- **mui**: Material-UI (\\`@mui/material\\`, \\`@mui/joy\\`)\n- **chakra**: Chakra UI (\\`@chakra-ui/react\\`)\n- **antd**: Ant Design (\\`antd\\`)\n`,\n});\n\n/**\n * Information about a component usage in the file\n */\ninterface ComponentUsage {\n /** The JSX element node (for error reporting) */\n node: TSESTree.JSXOpeningElement;\n /** Component name (e.g., \"Button\", \"MuiCard\") */\n componentName: string;\n /** Import source (e.g., \"@mui/material\", \"./components/cards\") */\n importSource: string;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-mixed-component-libraries\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Forbid using non-preferred UI component libraries. Reports at JSX usage sites, including transitive usage.\",\n },\n messages: {\n nonPreferredLibrary:\n \"Component <{{component}}> is from {{library}}, but {{preferred}} is the preferred library.\",\n transitiveNonPreferred:\n \"Component <{{component}}> internally uses {{libraries}} components ({{internalComponents}}). The preferred library is {{preferred}}.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n preferred: {\n type: \"string\",\n enum: [\"shadcn\", \"mui\", \"chakra\", \"antd\"],\n description: \"The preferred UI library\",\n },\n libraries: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"shadcn\", \"mui\", \"chakra\", \"antd\"],\n },\n description: \"Libraries to detect (defaults to all)\",\n },\n },\n required: [\"preferred\"],\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n { preferred: \"shadcn\", libraries: [\"shadcn\", \"mui\", \"chakra\", \"antd\"] },\n ],\n create(context) {\n const options = context.options[0];\n const preferred = options.preferred;\n\n // Track imports: localName -> importSource\n const importMap = new Map<string, string>();\n\n // Track all component usages for analysis at Program:exit\n const componentUsages: ComponentUsage[] = [];\n\n return {\n ImportDeclaration(node) {\n const source = node.source.value as string;\n\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\") {\n importMap.set(spec.local.name, source);\n } else if (spec.type === \"ImportDefaultSpecifier\") {\n importMap.set(spec.local.name, source);\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n importMap.set(spec.local.name, source);\n }\n }\n },\n\n JSXOpeningElement(node) {\n // Get the component name\n let componentName: string | null = null;\n\n if (node.name.type === \"JSXIdentifier\") {\n componentName = node.name.name;\n } else if (node.name.type === \"JSXMemberExpression\") {\n // Handle Namespace.Component (e.g., Modal.Header)\n let current = node.name.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n if (current.type === \"JSXIdentifier\") {\n componentName = current.name;\n }\n }\n\n // Skip HTML elements (lowercase) and missing names\n if (!componentName || !/^[A-Z]/.test(componentName)) {\n return;\n }\n\n // Skip components that aren't imported (might be defined in same file)\n const importSource = importMap.get(componentName);\n if (!importSource) {\n return;\n }\n\n componentUsages.push({\n node,\n componentName,\n importSource,\n });\n },\n\n \"Program:exit\"() {\n const filename = context.filename || context.getFilename();\n\n for (const usage of componentUsages) {\n const libraryInfo = getComponentLibrary(\n filename,\n usage.componentName,\n usage.importSource\n );\n\n // Case 1: Direct import from non-preferred library\n if (libraryInfo.library && libraryInfo.library !== preferred) {\n context.report({\n node: usage.node,\n messageId: \"nonPreferredLibrary\",\n data: {\n component: usage.componentName,\n library: libraryInfo.library,\n preferred,\n },\n });\n continue;\n }\n\n // Case 2: Local component that uses non-preferred library internally\n if (\n libraryInfo.isLocalComponent &&\n libraryInfo.internalLibraries.size > 0\n ) {\n const nonPreferredLibs = [...libraryInfo.internalLibraries].filter(\n (lib) => lib !== preferred\n );\n\n if (nonPreferredLibs.length > 0) {\n // Get evidence of which internal components caused the violation\n const internalComponents = libraryInfo.libraryEvidence\n .filter((e) => e.library !== preferred)\n .map((e) => e.componentName)\n .slice(0, 3) // Limit to first 3 for readability\n .join(\", \");\n\n context.report({\n node: usage.node,\n messageId: \"transitiveNonPreferred\",\n data: {\n component: usage.componentName,\n libraries: nonPreferredLibs.join(\", \"),\n internalComponents: internalComponents || \"unknown\",\n preferred,\n },\n });\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: semantic\n *\n * LLM-powered semantic UI analysis using the project's styleguide.\n * This is the only rule that reads .uilint/styleguide.md.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { spawnSync } from \"child_process\";\nimport { dirname, join, relative } from \"path\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport {\n getCacheEntry,\n hashContentSync,\n setCacheEntry,\n type CachedIssue,\n} from \"../utils/cache.js\";\nimport { getStyleguide } from \"../utils/styleguide-loader.js\";\nimport { UILINT_DEFAULT_OLLAMA_MODEL } from \"uilint-core\";\nimport { buildSourceScanPrompt } from \"uilint-core\";\n\ntype MessageIds = \"semanticIssue\" | \"styleguideNotFound\" | \"analysisError\";\ntype Options = [\n {\n model?: string;\n styleguidePath?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"semantic\",\n name: \"Semantic Analysis\",\n description: \"LLM-powered semantic UI analysis using your styleguide\",\n defaultSeverity: \"warn\",\n category: \"semantic\",\n requiresStyleguide: true,\n defaultOptions: [{ model: \"qwen3-coder:30b\", styleguidePath: \".uilint/styleguide.md\" }],\n optionSchema: {\n fields: [\n {\n key: \"model\",\n label: \"Ollama model to use\",\n type: \"text\",\n defaultValue: \"qwen3-coder:30b\",\n placeholder: \"qwen3-coder:30b\",\n description: \"The Ollama model name for semantic analysis\",\n },\n {\n key: \"styleguidePath\",\n label: \"Path to styleguide file\",\n type: \"text\",\n defaultValue: \".uilint/styleguide.md\",\n placeholder: \".uilint/styleguide.md\",\n description: \"Relative path to the styleguide markdown file\",\n },\n ],\n },\n docs: `\n## What it does\n\nUses a local LLM (via Ollama) to analyze your React components against your project's\nstyleguide. It catches semantic issues that pattern-based rules can't detect, like:\n- Using incorrect spacing that doesn't match your design system conventions\n- Inconsistent button styles across similar contexts\n- Missing accessibility patterns defined in your styleguide\n\n## Why it's useful\n\n- **Custom rules**: Enforces your project's unique conventions without writing custom ESLint rules\n- **Context-aware**: Understands component intent, not just syntax\n- **Evolving standards**: Update your styleguide, and the rule adapts automatically\n- **Local & private**: Runs entirely on your machine using Ollama\n\n## Prerequisites\n\n1. **Ollama installed**: \\`brew install ollama\\` or from ollama.ai\n2. **Model pulled**: \\`ollama pull qwen3-coder:30b\\` (or your preferred model)\n3. **Styleguide created**: Create \\`.uilint/styleguide.md\\` describing your conventions\n\n## Example Styleguide\n\n\\`\\`\\`markdown\n# UI Style Guide\n\n## Spacing\n- Use gap-4 for spacing between card elements\n- Use py-2 px-4 for button padding\n\n## Colors\n- Primary actions: bg-primary text-primary-foreground\n- Destructive actions: bg-destructive text-destructive-foreground\n\n## Components\n- All forms must include a Cancel button\n- Modal headers should use text-lg font-semibold\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/semantic\": [\"warn\", {\n model: \"qwen3-coder:30b\", // Ollama model name\n styleguidePath: \".uilint/styleguide.md\" // Path to styleguide\n}]\n\\`\\`\\`\n\n## Notes\n\n- Results are cached based on file content and styleguide hash\n- First run may be slow as the model loads; subsequent runs use cache\n- Works best with detailed, specific styleguide documentation\n- Set to \"off\" in CI to avoid slow builds (use pre-commit hooks locally)\n`,\n});\n\nexport default createRule<Options, MessageIds>({\n name: \"semantic\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"LLM-powered semantic UI analysis using styleguide\",\n },\n messages: {\n semanticIssue: \"{{message}}\",\n styleguideNotFound:\n \"No styleguide found. Create .uilint/styleguide.md or specify styleguidePath.\",\n analysisError: \"Semantic analysis failed: {{error}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n model: {\n type: \"string\",\n description: \"Ollama model to use\",\n },\n styleguidePath: {\n type: \"string\",\n description: \"Path to styleguide file\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ model: UILINT_DEFAULT_OLLAMA_MODEL }],\n create(context) {\n const options = context.options[0] || {};\n const filePath = context.filename;\n const fileDir = dirname(filePath);\n\n // Get styleguide\n const { path: styleguidePath, content: styleguide } = getStyleguide(\n fileDir,\n options.styleguidePath\n );\n\n // Skip if no styleguide\n if (!styleguide) {\n console.error(\n `[uilint] Styleguide not found (styleguidePath=${String(\n options.styleguidePath ?? \"\"\n )}, startDir=${fileDir})`\n );\n\n return {\n Program(node) {\n context.report({\n node,\n messageId: \"styleguideNotFound\",\n });\n },\n };\n }\n\n // Read and hash file contents\n let fileContent: string;\n try {\n fileContent = readFileSync(filePath, \"utf-8\");\n } catch {\n console.error(`[uilint] Failed to read file ${filePath}`);\n return {\n Program(node) {\n context.report({\n node,\n messageId: \"analysisError\",\n data: { error: `Failed to read source file ${filePath}` },\n });\n },\n };\n }\n\n const fileHash = hashContentSync(fileContent);\n const styleguideHash = hashContentSync(styleguide);\n\n // Check cache\n const projectRoot = findProjectRoot(fileDir);\n const relativeFilePath = relative(projectRoot, filePath);\n const cached = getCacheEntry(\n projectRoot,\n relativeFilePath,\n fileHash,\n styleguideHash\n );\n\n const ENABLE_CACHE = false;\n if (ENABLE_CACHE && cached) {\n console.error(`[uilint] Cache hit for ${filePath}`);\n\n // Report cached issues\n return {\n Program(node) {\n for (const issue of cached.issues) {\n context.report({\n node,\n loc: { line: issue.line, column: issue.column || 0 },\n messageId: \"semanticIssue\",\n data: { message: issue.message },\n });\n }\n },\n };\n }\n\n // Cache miss: run sync analysis now (slow), cache, then report.\n ENABLE_CACHE &&\n console.error(\n `[uilint] Cache miss for ${filePath}, running semantic analysis`\n );\n\n return {\n Program(node) {\n const issues = runSemanticAnalysisSync(\n fileContent,\n styleguide,\n options.model || UILINT_DEFAULT_OLLAMA_MODEL,\n filePath\n );\n\n setCacheEntry(projectRoot, relativeFilePath, {\n fileHash,\n styleguideHash,\n issues,\n timestamp: Date.now(),\n });\n\n for (const issue of issues) {\n context.report({\n node,\n loc: { line: issue.line, column: issue.column || 0 },\n messageId: \"semanticIssue\",\n data: { message: issue.message },\n });\n }\n },\n };\n },\n});\n\n/**\n * Find project root by looking for package.json\n */\nfunction findProjectRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Run semantic analysis using Ollama (synchronously).\n *\n * Implementation detail:\n * - ESLint rules are synchronous.\n * - Blocking on a Promise (sleep-loop/Atomics) would also block Node's event loop,\n * preventing the HTTP request to Ollama from ever completing.\n * - To keep this simple & debuggable, we run the async LLM call in a child Node\n * process and synchronously wait for it to exit.\n */\nfunction runSemanticAnalysisSync(\n sourceCode: string,\n styleguide: string,\n model: string,\n filePath?: string\n): CachedIssue[] {\n const startTime = Date.now();\n const fileDisplay = filePath ? ` ${filePath}` : \"\";\n\n console.error(`[uilint] Starting semantic analysis (sync)${fileDisplay}`);\n console.error(`[uilint] Model: ${model}`);\n\n // Build prompt in-process (pure string building).\n const prompt = buildSourceScanPrompt(sourceCode, styleguide, {});\n\n // Avoid `uilint-core/node` exports *and* CJS resolution:\n // resolve the installed dependency by file URL relative to this plugin bundle.\n // When built, `import.meta.url` points at `.../uilint-eslint/dist/index.js`,\n // and the dependency lives at `.../uilint-eslint/node_modules/uilint-core/dist/node.js`.\n const coreNodeUrl = new URL(\n \"../node_modules/uilint-core/dist/node.js\",\n import.meta.url\n ).href;\n\n const childScript = `\n import * as coreNode from ${JSON.stringify(coreNodeUrl)};\n const { OllamaClient, logInfo, logWarning, createProgress, pc } = coreNode;\n const chunks = [];\n for await (const c of process.stdin) chunks.push(c);\n const input = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n const model = input.model;\n const prompt = input.prompt;\n\n const client = new OllamaClient({ model });\n const ok = await client.isAvailable();\n if (!ok) {\n logWarning(\"Ollama not available, skipping semantic analysis\");\n process.stdout.write(JSON.stringify({ issues: [] }));\n process.exit(0);\n }\n\n logInfo(\\`Ollama connected \\${pc.dim(\\`(model: \\${model})\\`)}\\`);\n const progress = createProgress(\"Analyzing with LLM...\");\n try {\n const response = await client.complete(prompt, {\n json: true,\n stream: true,\n onProgress: (latestLine) => {\n const maxLen = 60;\n const display =\n latestLine.length > maxLen\n ? latestLine.slice(0, maxLen) + \"…\"\n : latestLine;\n progress.update(\\`LLM: \\${pc.dim(display || \"...\")}\\`);\n },\n });\n progress.succeed(\"LLM complete\");\n process.stdout.write(response);\n } catch (e) {\n progress.fail(\\`LLM failed: \\${e instanceof Error ? e.message : String(e)}\\`);\n process.exit(1);\n }\n `;\n\n const child = spawnSync(\n process.execPath,\n [\"--input-type=module\", \"-e\", childScript],\n {\n input: JSON.stringify({ model, prompt }),\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n maxBuffer: 20 * 1024 * 1024,\n }\n );\n\n const elapsed = Date.now() - startTime;\n\n if (child.error) {\n console.error(\n `[uilint] Semantic analysis failed after ${elapsed}ms: ${child.error.message}`\n );\n return [];\n }\n\n if (typeof child.status === \"number\" && child.status !== 0) {\n console.error(\n `[uilint] Semantic analysis failed after ${elapsed}ms: child exited ${child.status}`\n );\n return [];\n }\n\n const responseText = (child.stdout || \"\").trim();\n if (!responseText) {\n console.error(\n `[uilint] Semantic analysis returned empty response (${elapsed}ms)`\n );\n return [];\n }\n\n try {\n const parsed = JSON.parse(responseText) as {\n issues?: Array<{ line?: number; column?: number; message?: string }>;\n };\n\n const issues = (parsed.issues || []).map((issue) => ({\n line: issue.line || 1,\n column: issue.column,\n message: issue.message || \"Semantic issue detected\",\n ruleId: \"uilint/semantic\",\n severity: 1 as const,\n }));\n\n if (issues.length > 0) {\n console.error(`[uilint] Found ${issues.length} issue(s) (${elapsed}ms)`);\n } else {\n console.error(`[uilint] No issues found (${elapsed}ms)`);\n }\n\n return issues;\n } catch (e) {\n console.error(\n `[uilint] Semantic analysis failed to parse response after ${elapsed}ms: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n return [];\n }\n}\n","/**\n * File-hash based caching for LLM semantic rule\n *\n * Uses xxhash for fast hashing of file contents.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n// Lazy-loaded xxhash\nlet xxhashInstance: Awaited<\n ReturnType<typeof import(\"xxhash-wasm\")[\"default\"]>\n> | null = null;\n\nasync function getXxhash() {\n if (!xxhashInstance) {\n const xxhash = await import(\"xxhash-wasm\");\n xxhashInstance = await xxhash.default();\n }\n return xxhashInstance;\n}\n\n/**\n * Synchronous hash using a simple djb2 algorithm (fallback when xxhash not available)\n */\nfunction djb2Hash(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash * 33) ^ str.charCodeAt(i);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Hash content using xxhash (async) or djb2 (sync fallback)\n */\nexport async function hashContent(content: string): Promise<string> {\n try {\n const xxhash = await getXxhash();\n return xxhash.h64ToString(content);\n } catch {\n return djb2Hash(content);\n }\n}\n\n/**\n * Synchronous hash for when async is not possible\n */\nexport function hashContentSync(content: string): string {\n return djb2Hash(content);\n}\n\nexport interface CacheEntry {\n fileHash: string;\n styleguideHash: string;\n issues: CachedIssue[];\n timestamp: number;\n}\n\nexport interface CachedIssue {\n line: number;\n column?: number;\n message: string;\n ruleId: string;\n severity: 1 | 2; // 1 = warn, 2 = error\n}\n\nexport interface CacheStore {\n version: number;\n entries: Record<string, CacheEntry>;\n}\n\nconst CACHE_VERSION = 1;\nconst CACHE_FILE = \".uilint/.cache/eslint-semantic.json\";\n\n/**\n * Get the cache file path for a project\n */\nexport function getCachePath(projectRoot: string): string {\n return join(projectRoot, CACHE_FILE);\n}\n\n/**\n * Load the cache store\n */\nexport function loadCache(projectRoot: string): CacheStore {\n const cachePath = getCachePath(projectRoot);\n\n if (!existsSync(cachePath)) {\n return { version: CACHE_VERSION, entries: {} };\n }\n\n try {\n const content = readFileSync(cachePath, \"utf-8\");\n const cache = JSON.parse(content) as CacheStore;\n\n // Invalidate if version mismatch\n if (cache.version !== CACHE_VERSION) {\n return { version: CACHE_VERSION, entries: {} };\n }\n\n return cache;\n } catch {\n return { version: CACHE_VERSION, entries: {} };\n }\n}\n\n/**\n * Save the cache store\n */\nexport function saveCache(projectRoot: string, cache: CacheStore): void {\n const cachePath = getCachePath(projectRoot);\n\n try {\n const cacheDir = dirname(cachePath);\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n\n writeFileSync(cachePath, JSON.stringify(cache, null, 2), \"utf-8\");\n } catch {\n // Silently fail - caching is optional\n }\n}\n\n/**\n * Get cached entry for a file\n */\nexport function getCacheEntry(\n projectRoot: string,\n filePath: string,\n fileHash: string,\n styleguideHash: string\n): CacheEntry | null {\n const cache = loadCache(projectRoot);\n const entry = cache.entries[filePath];\n\n if (!entry) return null;\n\n // Check if hashes match\n if (entry.fileHash !== fileHash || entry.styleguideHash !== styleguideHash) {\n return null;\n }\n\n return entry;\n}\n\n/**\n * Set cached entry for a file\n */\nexport function setCacheEntry(\n projectRoot: string,\n filePath: string,\n entry: CacheEntry\n): void {\n const cache = loadCache(projectRoot);\n cache.entries[filePath] = entry;\n saveCache(projectRoot, cache);\n}\n\n/**\n * Clear cache for a specific file\n */\nexport function clearCacheEntry(projectRoot: string, filePath: string): void {\n const cache = loadCache(projectRoot);\n delete cache.entries[filePath];\n saveCache(projectRoot, cache);\n}\n\n/**\n * Clear entire cache\n */\nexport function clearCache(projectRoot: string): void {\n saveCache(projectRoot, { version: CACHE_VERSION, entries: {} });\n}\n","/**\n * Styleguide loader for the LLM semantic rule\n *\n * Only the semantic rule reads the styleguide - static rules use ESLint options.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { dirname, isAbsolute, join, resolve } from \"path\";\n\nconst DEFAULT_STYLEGUIDE_PATHS = [\n \".uilint/styleguide.md\",\n \".uilint/styleguide.yaml\",\n \".uilint/styleguide.yml\",\n];\n\n/**\n * Find workspace root by walking up looking for pnpm-workspace.yaml, package.json, or .git\n */\nfunction findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (\n existsSync(join(dir, \"pnpm-workspace.yaml\")) ||\n existsSync(join(dir, \".git\"))\n ) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Find the nearest package root (directory containing package.json),\n * stopping at the workspace root.\n */\nfunction findNearestPackageRoot(\n startDir: string,\n workspaceRoot: string\n): string {\n let dir = startDir;\n for (let i = 0; i < 30; i++) {\n if (existsSync(join(dir, \"package.json\"))) return dir;\n if (dir === workspaceRoot) break;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Find the styleguide file path\n */\nexport function findStyleguidePath(\n startDir: string,\n explicitPath?: string\n): string | null {\n // Explicit path takes precedence\n if (explicitPath) {\n if (isAbsolute(explicitPath)) {\n return existsSync(explicitPath) ? explicitPath : null;\n }\n\n // For relative explicit paths, try:\n // 1) relative to the file dir (back-compat)\n // 2) relative to the nearest package root (typical \"project root\")\n // 3) relative to workspace root (monorepo root)\n const workspaceRoot = findWorkspaceRoot(startDir);\n const packageRoot = findNearestPackageRoot(startDir, workspaceRoot);\n\n const candidates = [\n resolve(startDir, explicitPath),\n resolve(packageRoot, explicitPath),\n resolve(workspaceRoot, explicitPath),\n ];\n\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n\n return null;\n }\n\n // Check from start dir up to workspace root\n const workspaceRoot = findWorkspaceRoot(startDir);\n let dir = startDir;\n\n while (true) {\n for (const relativePath of DEFAULT_STYLEGUIDE_PATHS) {\n const fullPath = join(dir, relativePath);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n // Stop at workspace root\n if (dir === workspaceRoot) break;\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return null;\n}\n\n/**\n * Load styleguide content from file\n */\nexport function loadStyleguide(\n startDir: string,\n explicitPath?: string\n): string | null {\n const path = findStyleguidePath(startDir, explicitPath);\n if (!path) return null;\n\n try {\n return readFileSync(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Get styleguide path and content\n */\nexport function getStyleguide(\n startDir: string,\n explicitPath?: string\n): { path: string | null; content: string | null } {\n const path = findStyleguidePath(startDir, explicitPath);\n if (!path) return { path: null, content: null };\n\n try {\n const content = readFileSync(path, \"utf-8\");\n return { path, content };\n } catch {\n return { path, content: null };\n }\n}\n","/**\n * Rule: semantic-vision\n *\n * ESLint rule that reports cached vision analysis results for UI elements.\n * Vision analysis is performed by the UILint browser overlay and results are\n * cached in .uilint/screenshots/{timestamp}-{route}.json files.\n *\n * This rule:\n * 1. Finds cached vision analysis results for the current file\n * 2. Reports any issues that match elements in this file (by data-loc)\n * 3. If no cached results exist, silently passes (analysis is triggered by browser)\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { dirname, join, relative } from \"path\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"visionIssue\" | \"analysisStale\";\n\ntype Options = [\n {\n /** Maximum age of cached results in milliseconds (default: 1 hour) */\n maxAgeMs?: number;\n /** Path to screenshots directory (default: .uilint/screenshots) */\n screenshotsPath?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"semantic-vision\",\n name: \"Vision Analysis\",\n description: \"Report cached vision analysis results from UILint browser overlay\",\n defaultSeverity: \"warn\",\n category: \"semantic\",\n requiresStyleguide: false,\n defaultOptions: [{ maxAgeMs: 3600000, screenshotsPath: \".uilint/screenshots\" }],\n optionSchema: {\n fields: [\n {\n key: \"maxAgeMs\",\n label: \"Max cache age (milliseconds)\",\n type: \"number\",\n defaultValue: 3600000,\n placeholder: \"3600000\",\n description: \"Maximum age of cached results in milliseconds (default: 1 hour)\",\n },\n {\n key: \"screenshotsPath\",\n label: \"Screenshots directory path\",\n type: \"text\",\n defaultValue: \".uilint/screenshots\",\n placeholder: \".uilint/screenshots\",\n description: \"Relative path to the screenshots directory containing analysis results\",\n },\n ],\n },\n docs: `\n## What it does\n\nReports UI issues found by the UILint browser overlay's vision analysis. The overlay\ncaptures screenshots and analyzes them using vision AI, then caches the results.\nThis ESLint rule reads those cached results and reports them as linting errors.\n\n## How it works\n\n1. **Browser overlay**: When running your dev server with the UILint overlay, it captures\n screenshots and analyzes them using vision AI\n2. **Results cached**: Analysis results are saved to \\`.uilint/screenshots/*.json\\`\n3. **ESLint reports**: This rule reads cached results and reports issues at the correct\n source locations using \\`data-loc\\` attributes\n\n## Why it's useful\n\n- **Visual issues**: Catches problems that can only be seen in rendered UI\n- **Continuous feedback**: Issues appear in your editor as you develop\n- **No manual review**: AI spots spacing, alignment, and consistency issues automatically\n\n## Prerequisites\n\n1. **UILint overlay installed**: Add the overlay component to your app\n2. **Run analysis**: Load pages in the browser with the overlay active\n3. **Results cached**: Wait for analysis to complete and cache results\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/semantic-vision\": [\"warn\", {\n maxAgeMs: 3600000, // Ignore results older than 1 hour\n screenshotsPath: \".uilint/screenshots\" // Where cached results are stored\n}]\n\\`\\`\\`\n\n## Notes\n\n- If no cached results exist, the rule passes silently\n- Results are matched to source files using \\`data-loc\\` attributes\n- Stale results (older than \\`maxAgeMs\\`) are reported as warnings\n- Run the browser overlay to refresh cached analysis\n`,\n});\n\n/**\n * Vision analysis result structure stored in JSON files\n */\ninterface VisionAnalysisResult {\n /** Timestamp when analysis was performed */\n timestamp: number;\n /** Route that was analyzed (e.g., \"/\", \"/profile\") */\n route: string;\n /** Screenshot filename (for reference) */\n screenshotFile?: string;\n /** Issues found by vision analysis */\n issues: VisionIssue[];\n}\n\n/**\n * Individual issue from vision analysis\n */\ninterface VisionIssue {\n /** Element text that the LLM referenced */\n elementText?: string;\n /** data-loc reference (format: \"path:line:column\") */\n dataLoc?: string;\n /** Human-readable description of the issue */\n message: string;\n /** Issue category */\n category?: \"spacing\" | \"color\" | \"typography\" | \"alignment\" | \"accessibility\" | \"layout\" | \"other\";\n /** Severity level */\n severity?: \"error\" | \"warning\" | \"info\";\n}\n\n/**\n * Find project root by looking for package.json\n */\nfunction findProjectRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Get all vision analysis result files from screenshots directory\n */\nfunction getVisionResultFiles(screenshotsDir: string): string[] {\n if (!existsSync(screenshotsDir)) {\n return [];\n }\n\n try {\n const files = readdirSync(screenshotsDir);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => join(screenshotsDir, f))\n .sort()\n .reverse(); // Most recent first\n } catch {\n return [];\n }\n}\n\n/**\n * Load and parse a vision analysis result file\n */\nfunction loadVisionResult(filePath: string): VisionAnalysisResult | null {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as VisionAnalysisResult;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse a data-loc string into file path and location\n * Format: \"path/to/file.tsx:line:column\"\n */\nfunction parseDataLoc(dataLoc: string): { filePath: string; line: number; column: number } | null {\n // Match pattern: path:line:column (line and column are numbers)\n const match = dataLoc.match(/^(.+):(\\d+):(\\d+)$/);\n if (!match) return null;\n\n return {\n filePath: match[1]!,\n line: parseInt(match[2]!, 10),\n column: parseInt(match[3]!, 10),\n };\n}\n\n/**\n * Normalize file path for comparison (handle relative vs absolute paths)\n */\nfunction normalizeFilePath(filePath: string, projectRoot: string): string {\n // If it's already a relative path, return as-is\n if (!filePath.startsWith(\"/\")) {\n return filePath;\n }\n // Convert absolute to relative\n return relative(projectRoot, filePath);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"semantic-vision\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Report cached vision analysis results from UILint browser overlay\",\n },\n messages: {\n visionIssue: \"[Vision] {{message}}\",\n analysisStale:\n \"Vision analysis results are stale (older than {{age}}). Re-run analysis in browser.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxAgeMs: {\n type: \"number\",\n description:\n \"Maximum age of cached results in milliseconds (default: 1 hour)\",\n },\n screenshotsPath: {\n type: \"string\",\n description:\n \"Path to screenshots directory (default: .uilint/screenshots)\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ maxAgeMs: 60 * 60 * 1000 }], // 1 hour default\n create(context) {\n const options = context.options[0] || {};\n const maxAgeMs = options.maxAgeMs ?? 60 * 60 * 1000;\n const filePath = context.filename;\n const fileDir = dirname(filePath);\n\n // Find project root and screenshots directory\n const projectRoot = findProjectRoot(fileDir);\n const screenshotsDir = options.screenshotsPath\n ? join(projectRoot, options.screenshotsPath)\n : join(projectRoot, \".uilint\", \"screenshots\");\n\n // Get the relative path of the current file for matching against data-loc\n const relativeFilePath = normalizeFilePath(filePath, projectRoot);\n\n // Find all vision result files\n const resultFiles = getVisionResultFiles(screenshotsDir);\n if (resultFiles.length === 0) {\n // No cached results - silently pass (analysis happens in browser)\n return {};\n }\n\n // Collect issues that match this file from all recent results\n const matchingIssues: Array<{\n issue: VisionIssue;\n line: number;\n column: number;\n isStale: boolean;\n }> = [];\n\n const now = Date.now();\n\n for (const resultFile of resultFiles) {\n const result = loadVisionResult(resultFile);\n if (!result || !result.issues) continue;\n\n const isStale = now - result.timestamp > maxAgeMs;\n\n for (const issue of result.issues) {\n if (!issue.dataLoc) continue;\n\n const parsed = parseDataLoc(issue.dataLoc);\n if (!parsed) continue;\n\n // Check if this issue is for the current file\n const issueFilePath = normalizeFilePath(parsed.filePath, projectRoot);\n if (issueFilePath === relativeFilePath) {\n matchingIssues.push({\n issue,\n line: parsed.line,\n column: parsed.column,\n isStale,\n });\n }\n }\n }\n\n // De-duplicate issues by line:column:message\n const seenIssues = new Set<string>();\n const uniqueIssues = matchingIssues.filter((item) => {\n const key = `${item.line}:${item.column}:${item.issue.message}`;\n if (seenIssues.has(key)) return false;\n seenIssues.add(key);\n return true;\n });\n\n return {\n Program(node) {\n for (const { issue, line, column, isStale } of uniqueIssues) {\n // Build message with category prefix if available\n const categoryPrefix = issue.category\n ? `[${issue.category}] `\n : \"\";\n const message = `${categoryPrefix}${issue.message}`;\n\n // Report stale warning separately if enabled\n if (isStale) {\n const ageHours = Math.round(maxAgeMs / (60 * 60 * 1000));\n context.report({\n node,\n loc: { line, column },\n messageId: \"analysisStale\",\n data: { age: `${ageHours}h` },\n });\n }\n\n context.report({\n node,\n loc: { line, column },\n messageId: \"visionIssue\",\n data: { message },\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: enforce-absolute-imports\n *\n * Requires alias imports (e.g., @/) for imports that traverse more than a\n * configurable number of directory levels. Prevents fragile relative import\n * paths like ../../../utils/helper.\n *\n * Examples:\n * - Bad: import { x } from '../../utils/helper'\n * - Good: import { x } from '@/utils/helper'\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"preferAbsoluteImport\";\ntype Options = [\n {\n /** Maximum allowed parent directory traversals (default: 1, allows ../ but not ../../) */\n maxRelativeDepth?: number;\n /** The alias prefix to suggest (default: \"@/\") */\n aliasPrefix?: string;\n /** Patterns to ignore (e.g., [\"node_modules\", \".css\"]) */\n ignorePaths?: string[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"enforce-absolute-imports\",\n name: \"Enforce Absolute Imports\",\n description:\n \"Require alias imports for paths beyond a configurable directory depth\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ maxRelativeDepth: 1, aliasPrefix: \"@/\" }],\n optionSchema: {\n fields: [\n {\n key: \"maxRelativeDepth\",\n label: \"Maximum relative depth\",\n type: \"number\",\n defaultValue: 1,\n description:\n \"Maximum number of parent directory traversals allowed (../ counts as 1)\",\n },\n {\n key: \"aliasPrefix\",\n label: \"Alias prefix\",\n type: \"text\",\n defaultValue: \"@/\",\n description: \"The path alias prefix to use (e.g., @/, ~/)\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnforces the use of path aliases (like \\`@/\\`) for imports that traverse multiple\nparent directories. This prevents fragile relative imports that are hard to\nmaintain and refactor.\n\n## Why it's useful\n\n- **Maintainability**: Absolute imports don't break when files move\n- **Readability**: Clear indication of where imports come from\n- **Consistency**: Standardizes import style across the codebase\n- **Refactoring**: Easier to move files without updating import paths\n\n## Examples\n\n### ❌ Incorrect (with maxRelativeDepth: 1)\n\n\\`\\`\\`tsx\n// Too many parent traversals\nimport { Button } from '../../components/Button';\nimport { utils } from '../../../lib/utils';\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using alias imports\nimport { Button } from '@/components/Button';\nimport { utils } from '@/lib/utils';\n\n// Single parent traversal (within threshold)\nimport { sibling } from '../sibling';\nimport { local } from './local';\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/enforce-absolute-imports\": [\"warn\", {\n maxRelativeDepth: 1, // Allow ../ but not ../../\n aliasPrefix: \"@/\", // Suggested alias prefix\n ignorePaths: [\".css\", \".scss\", \"node_modules\"]\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Count the number of parent directory traversals in an import path\n */\nfunction countParentTraversals(importSource: string): number {\n // Match all occurrences of ../ or ..\\\\ (Windows)\n const matches = importSource.match(/\\.\\.\\//g);\n return matches ? matches.length : 0;\n}\n\n/**\n * Check if an import is a relative path\n */\nfunction isRelativeImport(importSource: string): boolean {\n return importSource.startsWith(\"./\") || importSource.startsWith(\"../\");\n}\n\n/**\n * Check if the import should be ignored\n */\nfunction shouldIgnore(importSource: string, ignorePaths: string[]): boolean {\n return ignorePaths.some((pattern) => importSource.includes(pattern));\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"enforce-absolute-imports\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Require alias imports for paths beyond a configurable directory depth\",\n },\n messages: {\n preferAbsoluteImport:\n \"Import traverses {{depth}} parent director{{plural}}. Use an alias like '{{aliasPrefix}}...' instead of '{{importSource}}'.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxRelativeDepth: {\n type: \"number\",\n minimum: 0,\n description:\n \"Maximum number of parent directory traversals allowed\",\n },\n aliasPrefix: {\n type: \"string\",\n description: \"The path alias prefix to suggest\",\n },\n ignorePaths: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Patterns to ignore\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxRelativeDepth: 1,\n aliasPrefix: \"@/\",\n ignorePaths: [],\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxRelativeDepth = options.maxRelativeDepth ?? 1;\n const aliasPrefix = options.aliasPrefix ?? \"@/\";\n const ignorePaths = options.ignorePaths ?? [];\n\n /**\n * Check an import source and report if it exceeds the depth threshold\n */\n function checkImportSource(\n source: string,\n node: { loc?: { start: { line: number; column: number } } }\n ): void {\n // Skip non-relative imports (node_modules, aliases, etc.)\n if (!isRelativeImport(source)) {\n return;\n }\n\n // Skip ignored paths\n if (shouldIgnore(source, ignorePaths)) {\n return;\n }\n\n const depth = countParentTraversals(source);\n\n if (depth > maxRelativeDepth) {\n context.report({\n node: node as Parameters<typeof context.report>[0][\"node\"],\n messageId: \"preferAbsoluteImport\",\n data: {\n depth: String(depth),\n plural: depth === 1 ? \"y\" : \"ies\",\n aliasPrefix,\n importSource: source,\n },\n });\n }\n }\n\n return {\n // Standard import declarations: import { x } from '../../utils'\n ImportDeclaration(node) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n },\n\n // Re-exports with source: export { x } from '../../utils'\n ExportNamedDeclaration(node) {\n if (node.source) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n }\n },\n\n // Export all: export * from '../../utils'\n ExportAllDeclaration(node) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n },\n };\n },\n});\n","/**\n * Rule: no-any-in-props\n *\n * Prevents React components from using `any` type in their props, ensuring\n * type safety at component boundaries.\n *\n * Examples:\n * - Bad: function Component(props: any) {}\n * - Bad: function Component({ x }: { x: any }) {}\n * - Bad: const Component: FC<any> = () => {}\n * - Good: function Component(props: { name: string }) {}\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"anyInProps\" | \"anyInPropsProperty\";\ntype Options = [\n {\n /** Also check FC<any> and React.FC<any> patterns */\n checkFCGenerics?: boolean;\n /** Allow any in generic defaults (e.g., <T = any>) */\n allowInGenericDefaults?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-any-in-props\",\n name: \"No Any in Props\",\n description: \"Disallow 'any' type in React component props\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ checkFCGenerics: true, allowInGenericDefaults: false }],\n optionSchema: {\n fields: [\n {\n key: \"checkFCGenerics\",\n label: \"Check FC generics\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Check FC<any> and React.FC<any> patterns\",\n },\n {\n key: \"allowInGenericDefaults\",\n label: \"Allow in generic defaults\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Allow any in generic type parameter defaults\",\n },\n ],\n },\n docs: `\n## What it does\n\nPrevents the use of \\`any\\` type in React component props. This ensures type\nsafety at component boundaries, catching type errors at compile time rather\nthan runtime.\n\n## Why it's useful\n\n- **Type Safety**: Catches prop type errors at compile time\n- **Documentation**: Props serve as self-documenting API\n- **Refactoring**: IDE can track prop usage across codebase\n- **Code Quality**: Encourages thoughtful API design\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Direct any annotation\nfunction Component(props: any) {}\n\n// Any in destructured props\nfunction Component({ data }: { data: any }) {}\n\n// FC with any generic\nconst Component: FC<any> = () => {};\n\n// Any in props interface\ninterface Props { value: any }\nfunction Component(props: Props) {}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Properly typed props\nfunction Component(props: { name: string }) {}\n\n// Using unknown for truly unknown types\nfunction Component({ data }: { data: unknown }) {}\n\n// Typed FC\nconst Component: FC<{ count: number }> = () => {};\n\n// Generic component with constraint\nfunction List<T extends object>(props: { items: T[] }) {}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-any-in-props\": [\"error\", {\n checkFCGenerics: true, // Check FC<any> patterns\n allowInGenericDefaults: false // Disallow <T = any>\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Check if a name is likely a React component (PascalCase, not a hook)\n */\nfunction isComponentName(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name) && !name.startsWith(\"Use\");\n}\n\n/**\n * Check if a type node contains 'any'\n */\nfunction containsAnyType(\n node: TSESTree.TypeNode,\n allowInGenericDefaults: boolean\n): { hasAny: boolean; location: string | null } {\n if (!node) {\n return { hasAny: false, location: null };\n }\n\n switch (node.type) {\n case \"TSAnyKeyword\":\n return { hasAny: true, location: null };\n\n case \"TSTypeLiteral\":\n // Check each property in { prop: any }\n for (const member of node.members) {\n if (\n member.type === \"TSPropertySignature\" &&\n member.typeAnnotation?.typeAnnotation\n ) {\n const result = containsAnyType(\n member.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n const propName =\n member.key.type === \"Identifier\" ? member.key.name : \"property\";\n return { hasAny: true, location: `property '${propName}'` };\n }\n }\n // Index signature [key: string]: any\n if (\n member.type === \"TSIndexSignature\" &&\n member.typeAnnotation?.typeAnnotation\n ) {\n const result = containsAnyType(\n member.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"index signature\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSUnionType\":\n case \"TSIntersectionType\":\n for (const typeNode of node.types) {\n const result = containsAnyType(typeNode, allowInGenericDefaults);\n if (result.hasAny) {\n return result;\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSArrayType\":\n return containsAnyType(node.elementType, allowInGenericDefaults);\n\n case \"TSTypeReference\":\n // Check generic arguments like Array<any>, Record<string, any>\n if (node.typeArguments) {\n for (const param of node.typeArguments.params) {\n const result = containsAnyType(param, allowInGenericDefaults);\n if (result.hasAny) {\n return { hasAny: true, location: \"generic argument\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSFunctionType\":\n // Check return type and parameters\n if (node.returnType?.typeAnnotation) {\n const result = containsAnyType(\n node.returnType.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"function return type\" };\n }\n }\n for (const param of node.params) {\n if (\n param.typeAnnotation?.typeAnnotation &&\n param.type !== \"RestElement\"\n ) {\n const result = containsAnyType(\n param.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"function parameter\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSTupleType\":\n for (const elementType of node.elementTypes) {\n // Handle both TSNamedTupleMember and regular type nodes\n const typeToCheck =\n elementType.type === \"TSNamedTupleMember\"\n ? elementType.elementType\n : elementType;\n const result = containsAnyType(typeToCheck, allowInGenericDefaults);\n if (result.hasAny) {\n return { hasAny: true, location: \"tuple element\" };\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSConditionalType\":\n // Check all parts of conditional type\n const checkResult = containsAnyType(\n node.checkType,\n allowInGenericDefaults\n );\n if (checkResult.hasAny) return checkResult;\n const extendsResult = containsAnyType(\n node.extendsType,\n allowInGenericDefaults\n );\n if (extendsResult.hasAny) return extendsResult;\n const trueResult = containsAnyType(\n node.trueType,\n allowInGenericDefaults\n );\n if (trueResult.hasAny) return trueResult;\n const falseResult = containsAnyType(\n node.falseType,\n allowInGenericDefaults\n );\n if (falseResult.hasAny) return falseResult;\n return { hasAny: false, location: null };\n\n case \"TSMappedType\":\n if (node.typeAnnotation) {\n return containsAnyType(node.typeAnnotation, allowInGenericDefaults);\n }\n return { hasAny: false, location: null };\n\n default:\n return { hasAny: false, location: null };\n }\n}\n\n/**\n * Get the name of a function or component\n */\nfunction getComponentName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.ArrowFunctionExpression\n | TSESTree.FunctionExpression\n): string | null {\n // Function declaration: function Foo() {}\n if (node.type === \"FunctionDeclaration\" && node.id) {\n return node.id.name;\n }\n\n // Variable declarator: const Foo = () => {}\n const parent = node.parent;\n if (\n parent?.type === \"VariableDeclarator\" &&\n parent.id.type === \"Identifier\"\n ) {\n return parent.id.name;\n }\n\n // forwardRef/memo wrapper: const Foo = forwardRef(() => {})\n if (parent?.type === \"CallExpression\") {\n const callParent = parent.parent;\n if (\n callParent?.type === \"VariableDeclarator\" &&\n callParent.id.type === \"Identifier\"\n ) {\n return callParent.id.name;\n }\n }\n\n // Named function expression: const x = function Foo() {}\n if (node.type === \"FunctionExpression\" && node.id) {\n return node.id.name;\n }\n\n return null;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-any-in-props\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow 'any' type in React component props\",\n },\n messages: {\n anyInProps:\n \"Component '{{componentName}}' has 'any' type in props. Use a specific type or 'unknown' instead.\",\n anyInPropsProperty:\n \"Component '{{componentName}}' has 'any' type in {{location}}. Use a specific type or 'unknown' instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n checkFCGenerics: {\n type: \"boolean\",\n description: \"Check FC<any> and React.FC<any> patterns\",\n },\n allowInGenericDefaults: {\n type: \"boolean\",\n description: \"Allow any in generic type parameter defaults\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n checkFCGenerics: true,\n allowInGenericDefaults: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const checkFCGenerics = options.checkFCGenerics ?? true;\n const allowInGenericDefaults = options.allowInGenericDefaults ?? false;\n\n /**\n * Check a function's first parameter for any type\n */\n function checkFunctionProps(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.ArrowFunctionExpression\n | TSESTree.FunctionExpression\n ): void {\n const componentName = getComponentName(node);\n\n // Skip if not a component (not PascalCase)\n if (!componentName || !isComponentName(componentName)) {\n return;\n }\n\n // Check first parameter (props)\n const firstParam = node.params[0];\n if (!firstParam) {\n return;\n }\n\n // Get type annotation\n let typeAnnotation: TSESTree.TypeNode | null = null;\n\n if (firstParam.type === \"Identifier\" && firstParam.typeAnnotation) {\n typeAnnotation = firstParam.typeAnnotation.typeAnnotation;\n } else if (\n firstParam.type === \"ObjectPattern\" &&\n firstParam.typeAnnotation\n ) {\n typeAnnotation = firstParam.typeAnnotation.typeAnnotation;\n }\n\n if (typeAnnotation) {\n const result = containsAnyType(typeAnnotation, allowInGenericDefaults);\n if (result.hasAny) {\n context.report({\n node: firstParam,\n messageId: result.location ? \"anyInPropsProperty\" : \"anyInProps\",\n data: {\n componentName,\n location: result.location || \"props\",\n },\n });\n }\n }\n }\n\n /**\n * Check FC<any> or React.FC<any> patterns\n */\n function checkFCGeneric(node: TSESTree.VariableDeclarator): void {\n if (!checkFCGenerics) {\n return;\n }\n\n // Get variable name\n if (node.id.type !== \"Identifier\") {\n return;\n }\n const componentName = node.id.name;\n\n // Skip if not a component name\n if (!isComponentName(componentName)) {\n return;\n }\n\n // Check type annotation\n const typeAnnotation = node.id.typeAnnotation?.typeAnnotation;\n if (!typeAnnotation || typeAnnotation.type !== \"TSTypeReference\") {\n return;\n }\n\n // Check if it's FC or React.FC\n let isFCType = false;\n if (\n typeAnnotation.typeName.type === \"Identifier\" &&\n [\"FC\", \"FunctionComponent\", \"VFC\"].includes(typeAnnotation.typeName.name)\n ) {\n isFCType = true;\n } else if (\n typeAnnotation.typeName.type === \"TSQualifiedName\" &&\n typeAnnotation.typeName.left.type === \"Identifier\" &&\n typeAnnotation.typeName.left.name === \"React\" &&\n [\"FC\", \"FunctionComponent\", \"VFC\"].includes(\n typeAnnotation.typeName.right.name\n )\n ) {\n isFCType = true;\n }\n\n if (!isFCType || !typeAnnotation.typeArguments) {\n return;\n }\n\n // Check the type argument\n const firstTypeArg = typeAnnotation.typeArguments.params[0];\n if (firstTypeArg) {\n const result = containsAnyType(firstTypeArg, allowInGenericDefaults);\n if (result.hasAny) {\n context.report({\n node: firstTypeArg,\n messageId: result.location ? \"anyInPropsProperty\" : \"anyInProps\",\n data: {\n componentName,\n location: result.location || \"FC type parameter\",\n },\n });\n }\n }\n }\n\n return {\n FunctionDeclaration(node) {\n checkFunctionProps(node);\n },\n\n ArrowFunctionExpression(node) {\n checkFunctionProps(node);\n },\n\n FunctionExpression(node) {\n checkFunctionProps(node);\n },\n\n VariableDeclarator(node) {\n checkFCGeneric(node);\n },\n };\n },\n});\n","/**\n * Rule: zustand-use-selectors\n *\n * Requires selector functions when accessing Zustand store state to prevent\n * unnecessary re-renders.\n *\n * Examples:\n * - Bad: const state = useStore()\n * - Bad: const { count } = useStore()\n * - Good: const count = useStore((s) => s.count)\n * - Good: const count = useStore(selectCount)\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"missingSelector\" | \"useSelectorFunction\";\ntype Options = [\n {\n /** Regex pattern for store hook names (default: \"^use\\\\w*Store$\") */\n storePattern?: string;\n /** Allow useShallow() wrapper without selector */\n allowShallow?: boolean;\n /** Require named selector functions instead of inline arrows */\n requireNamedSelectors?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"zustand-use-selectors\",\n name: \"Zustand Use Selectors\",\n description: \"Require selector functions when accessing Zustand store state\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n { storePattern: \"^use\\\\w*Store$\", allowShallow: true, requireNamedSelectors: false },\n ],\n optionSchema: {\n fields: [\n {\n key: \"storePattern\",\n label: \"Store hook pattern\",\n type: \"text\",\n defaultValue: \"^use\\\\w*Store$\",\n description: \"Regex pattern for identifying Zustand store hooks\",\n },\n {\n key: \"allowShallow\",\n label: \"Allow useShallow\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Allow useShallow() wrapper without explicit selector\",\n },\n {\n key: \"requireNamedSelectors\",\n label: \"Require named selectors\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Require named selector functions instead of inline arrows\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnforces the use of selector functions when accessing Zustand store state.\nWhen you call a Zustand store without a selector, your component subscribes\nto the entire store and re-renders on any state change.\n\n## Why it's useful\n\n- **Performance**: Prevents unnecessary re-renders\n- **Optimization**: Components only update when selected state changes\n- **Best Practice**: Follows Zustand's recommended patterns\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Subscribes to entire store - re-renders on any change\nconst state = useStore();\nconst { count, user } = useStore();\n\n// Component re-renders when anything changes, not just count\nfunction Counter() {\n const { count } = useStore();\n return <span>{count}</span>;\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Only re-renders when count changes\nconst count = useStore((state) => state.count);\n\n// Named selector\nconst selectCount = (state) => state.count;\nconst count = useStore(selectCount);\n\n// Multiple values with shallow\nimport { useShallow } from 'zustand/shallow';\nconst { count, user } = useStore(\n useShallow((state) => ({ count: state.count, user: state.user }))\n);\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/zustand-use-selectors\": [\"warn\", {\n storePattern: \"^use\\\\\\\\w*Store$\", // Match useXxxStore pattern\n allowShallow: true, // Allow useShallow without inline selector\n requireNamedSelectors: false // Allow inline arrow selectors\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Check if a node is a Zustand store call based on the pattern\n */\nfunction isZustandStoreCall(\n callee: TSESTree.Node,\n storePattern: RegExp\n): boolean {\n if (callee.type === \"Identifier\") {\n return storePattern.test(callee.name);\n }\n return false;\n}\n\n/**\n * Check if the first argument is a selector function or reference\n */\nfunction hasSelector(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n\n // Arrow function: (s) => s.count\n if (firstArg.type === \"ArrowFunctionExpression\") {\n return true;\n }\n\n // Function expression: function(s) { return s.count; }\n if (firstArg.type === \"FunctionExpression\") {\n return true;\n }\n\n // Named selector reference: selectCount\n if (firstArg.type === \"Identifier\") {\n return true;\n }\n\n // Member expression: selectors.count or module.selectCount\n if (firstArg.type === \"MemberExpression\") {\n return true;\n }\n\n // Call expression (might be useShallow or similar)\n if (firstArg.type === \"CallExpression\") {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if the selector is wrapped in useShallow\n */\nfunction isShallowWrapped(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n\n if (firstArg.type === \"CallExpression\") {\n if (\n firstArg.callee.type === \"Identifier\" &&\n firstArg.callee.name === \"useShallow\"\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the selector is an inline arrow function\n */\nfunction isInlineSelector(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n return (\n firstArg.type === \"ArrowFunctionExpression\" ||\n firstArg.type === \"FunctionExpression\"\n );\n}\n\n/**\n * Get the store name from the call expression\n */\nfunction getStoreName(callee: TSESTree.Node): string {\n if (callee.type === \"Identifier\") {\n return callee.name;\n }\n return \"useStore\";\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"zustand-use-selectors\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Require selector functions when accessing Zustand store state\",\n },\n messages: {\n missingSelector:\n \"Call to '{{storeName}}' is missing a selector. Use '{{storeName}}((state) => state.property)' to prevent unnecessary re-renders.\",\n useSelectorFunction:\n \"Consider using a named selector function instead of an inline arrow for '{{storeName}}'. Example: '{{storeName}}(selectProperty)'\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n storePattern: {\n type: \"string\",\n description: \"Regex pattern for store hook names\",\n },\n allowShallow: {\n type: \"boolean\",\n description: \"Allow useShallow() wrapper\",\n },\n requireNamedSelectors: {\n type: \"boolean\",\n description: \"Require named selector functions\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n storePattern: \"^use\\\\w*Store$\",\n allowShallow: true,\n requireNamedSelectors: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const storePatternStr = options.storePattern ?? \"^use\\\\w*Store$\";\n const allowShallow = options.allowShallow ?? true;\n const requireNamedSelectors = options.requireNamedSelectors ?? false;\n\n let storePattern: RegExp;\n try {\n storePattern = new RegExp(storePatternStr);\n } catch {\n // If invalid regex, use default\n storePattern = /^use\\w*Store$/;\n }\n\n return {\n CallExpression(node) {\n // Check if this is a Zustand store call\n if (!isZustandStoreCall(node.callee, storePattern)) {\n return;\n }\n\n const storeName = getStoreName(node.callee);\n\n // Check for selector\n if (!hasSelector(node.arguments)) {\n context.report({\n node,\n messageId: \"missingSelector\",\n data: { storeName },\n });\n return;\n }\n\n // If useShallow is used and allowed, that's fine\n if (allowShallow && isShallowWrapped(node.arguments)) {\n return;\n }\n\n // Check for named selectors if required\n if (requireNamedSelectors && isInlineSelector(node.arguments)) {\n context.report({\n node,\n messageId: \"useSelectorFunction\",\n data: { storeName },\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: no-prop-drilling-depth\n *\n * Warns when a prop is passed through multiple intermediate components\n * without being used, indicating prop drilling that should be refactored\n * to context or state management.\n *\n * Examples:\n * - Bad: Prop passed through 3+ components without use\n * - Good: Prop used directly in receiving component\n * - Good: Using Context or Zustand instead of drilling\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport {\n resolveImportPath,\n parseFile,\n clearResolverCaches,\n} from \"../utils/export-resolver.js\";\n\ntype MessageIds = \"propDrilling\";\ntype Options = [\n {\n /** Maximum depth before warning (default: 2) */\n maxDepth?: number;\n /** Props to ignore (e.g., className, style, children) */\n ignoredProps?: string[];\n /** Component patterns to skip (regex strings) */\n ignoreComponents?: string[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-prop-drilling-depth\",\n name: \"No Prop Drilling Depth\",\n description: \"Warn when props are drilled through too many components\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n maxDepth: 2,\n ignoredProps: [\"className\", \"style\", \"children\", \"key\", \"ref\", \"id\"],\n ignoreComponents: [],\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"maxDepth\",\n label: \"Maximum drilling depth\",\n type: \"number\",\n defaultValue: 2,\n description:\n \"Maximum number of components a prop can pass through without use\",\n },\n {\n key: \"ignoredProps\",\n label: \"Ignored props\",\n type: \"array\",\n defaultValue: [\"className\", \"style\", \"children\", \"key\", \"ref\", \"id\"],\n description: \"Prop names to ignore (common pass-through props)\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects when props are passed through multiple intermediate components without\nbeing used (prop drilling). This is often a sign that you should use React\nContext, Zustand, or another state management solution.\n\n## Why it's useful\n\n- **Maintainability**: Deep prop drilling creates tight coupling\n- **Refactoring**: Changes require updates in many files\n- **Readability**: Hard to trace where props come from\n- **Performance**: Unnecessary re-renders in intermediate components\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Grandparent passes user through Parent to Child\nfunction Grandparent({ user }) {\n return <Parent user={user} />;\n}\n\nfunction Parent({ user }) {\n // Parent doesn't use 'user', just passes it along\n return <Child user={user} />;\n}\n\nfunction Child({ user }) {\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Use Context instead\nconst UserContext = createContext();\n\nfunction Grandparent({ user }) {\n return (\n <UserContext.Provider value={user}>\n <Parent />\n </UserContext.Provider>\n );\n}\n\nfunction Child() {\n const user = useContext(UserContext);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-prop-drilling-depth\": [\"warn\", {\n maxDepth: 2, // Allow passing through 2 components\n ignoredProps: [\"className\", \"style\", \"children\"], // Common pass-through props\n ignoreComponents: [\"^Layout\", \"^Wrapper\"] // Skip wrapper components\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Information about a component's prop usage\n */\ninterface ComponentPropInfo {\n /** Props received by the component */\n receivedProps: Set<string>;\n /** Props passed to child components: propName -> childComponentNames[] */\n passedProps: Map<string, string[]>;\n /** Props actually used in the component (not just passed) */\n usedProps: Set<string>;\n /** Child components that receive props from this component */\n childComponents: string[];\n}\n\n/**\n * Cache for analyzed component prop information\n */\nconst componentPropCache = new Map<string, ComponentPropInfo>();\n\n/**\n * Clear the prop analysis cache\n */\nexport function clearPropCache(): void {\n componentPropCache.clear();\n clearResolverCaches();\n}\n\n/**\n * Check if a name is a React component (PascalCase)\n */\nfunction isComponentName(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name);\n}\n\n/**\n * Extract props from a function parameter\n */\nfunction extractPropsFromParam(\n param: TSESTree.Parameter\n): { propNames: Set<string>; isSpread: boolean } {\n const propNames = new Set<string>();\n let isSpread = false;\n\n if (param.type === \"ObjectPattern\") {\n for (const prop of param.properties) {\n if (prop.type === \"RestElement\") {\n isSpread = true;\n } else if (\n prop.type === \"Property\" &&\n prop.key.type === \"Identifier\"\n ) {\n propNames.add(prop.key.name);\n }\n }\n } else if (param.type === \"Identifier\") {\n // Single props parameter - assume all props accessed via props.x\n isSpread = true;\n }\n\n return { propNames, isSpread };\n}\n\n/**\n * Find all JSX elements in a function body and extract prop passing info\n */\nfunction analyzeJSXPropPassing(\n body: TSESTree.Node,\n receivedProps: Set<string>\n): { passedProps: Map<string, string[]>; usedProps: Set<string> } {\n const passedProps = new Map<string, string[]>();\n const usedProps = new Set<string>();\n\n function visit(node: TSESTree.Node): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check JSX elements for prop passing\n if (node.type === \"JSXOpeningElement\") {\n const elementName = getJSXElementName(node.name);\n\n // Only care about component elements (PascalCase)\n if (elementName && isComponentName(elementName)) {\n for (const attr of node.attributes) {\n if (attr.type === \"JSXAttribute\" && attr.name.type === \"JSXIdentifier\") {\n const attrName = attr.name.name;\n const propValue = attr.value;\n\n // Check if the attribute value is a received prop\n if (propValue?.type === \"JSXExpressionContainer\") {\n const expr = propValue.expression;\n if (expr.type === \"Identifier\" && receivedProps.has(expr.name)) {\n // This prop is being passed to a child\n const existing = passedProps.get(expr.name) || [];\n existing.push(elementName);\n passedProps.set(expr.name, existing);\n } else if (\n expr.type === \"MemberExpression\" &&\n expr.object.type === \"Identifier\" &&\n expr.object.name === \"props\" &&\n expr.property.type === \"Identifier\"\n ) {\n // props.x pattern\n const propName = expr.property.name;\n if (receivedProps.has(propName) || receivedProps.size === 0) {\n const existing = passedProps.get(propName) || [];\n existing.push(elementName);\n passedProps.set(propName, existing);\n }\n }\n }\n }\n\n // Check for spread props: {...props} or {...rest}\n if (attr.type === \"JSXSpreadAttribute\") {\n if (attr.argument.type === \"Identifier\") {\n const spreadName = attr.argument.name;\n if (spreadName === \"props\" || receivedProps.has(spreadName)) {\n // All props are being spread\n for (const prop of receivedProps) {\n const existing = passedProps.get(prop) || [];\n existing.push(elementName);\n passedProps.set(prop, existing);\n }\n }\n }\n }\n }\n }\n }\n\n // Check for prop usage (not just passing)\n // e.g., {user.name} or {props.user.name} or just {user}\n if (\n node.type === \"MemberExpression\" &&\n node.object.type === \"Identifier\" &&\n receivedProps.has(node.object.name)\n ) {\n usedProps.add(node.object.name);\n }\n\n if (\n node.type === \"Identifier\" &&\n receivedProps.has(node.name) &&\n node.parent?.type !== \"JSXExpressionContainer\"\n ) {\n // Prop used in expression (but not directly passed to child)\n usedProps.add(node.name);\n }\n\n // Check for props.x.something usage\n if (\n node.type === \"MemberExpression\" &&\n node.object.type === \"MemberExpression\" &&\n node.object.object.type === \"Identifier\" &&\n node.object.object.name === \"props\" &&\n node.object.property.type === \"Identifier\"\n ) {\n usedProps.add(node.object.property.name);\n }\n\n // Recurse into children\n for (const key of Object.keys(node)) {\n if (key === \"parent\" || key === \"loc\" || key === \"range\") continue;\n const child = (node as Record<string, unknown>)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\") {\n visit(item as TSESTree.Node);\n }\n }\n } else if (child && typeof child === \"object\") {\n visit(child as TSESTree.Node);\n }\n }\n }\n\n visit(body);\n return { passedProps, usedProps };\n}\n\n/**\n * Get the name of a JSX element\n */\nfunction getJSXElementName(node: TSESTree.JSXTagNameExpression): string | null {\n if (node.type === \"JSXIdentifier\") {\n return node.name;\n }\n if (node.type === \"JSXMemberExpression\") {\n // Get the root object for namespace components\n let current = node.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n return current.type === \"JSXIdentifier\" ? current.name : null;\n }\n return null;\n}\n\n/**\n * Track prop drilling within a single file\n */\ninterface PropDrillingInfo {\n propName: string;\n component: string;\n passedTo: string[];\n usedDirectly: boolean;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-prop-drilling-depth\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Warn when props are drilled through too many components\",\n },\n messages: {\n propDrilling:\n \"Prop '{{propName}}' is passed through {{depth}} component(s) without being used. Consider using Context or state management. Path: {{path}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxDepth: {\n type: \"number\",\n minimum: 1,\n description: \"Maximum drilling depth before warning\",\n },\n ignoredProps: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Props to ignore\",\n },\n ignoreComponents: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Component patterns to skip (regex)\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxDepth: 2,\n ignoredProps: [\"className\", \"style\", \"children\", \"key\", \"ref\", \"id\"],\n ignoreComponents: [],\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxDepth = options.maxDepth ?? 2;\n const ignoredProps = new Set(\n options.ignoredProps ?? [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\",\n ]\n );\n const ignoreComponentPatterns = (options.ignoreComponents ?? []).map(\n (p) => new RegExp(p)\n );\n\n // Track components and their prop flows within the file\n const componentProps = new Map<string, ComponentPropInfo>();\n const imports = new Map<string, string>(); // localName -> importSource\n const componentNodes = new Map<string, TSESTree.Node>(); // componentName -> node\n\n function shouldIgnoreComponent(name: string): boolean {\n return ignoreComponentPatterns.some((pattern) => pattern.test(name));\n }\n\n function shouldIgnoreProp(name: string): boolean {\n return ignoredProps.has(name);\n }\n\n /**\n * Analyze a component function for prop drilling\n */\n function analyzeComponent(\n name: string,\n node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression,\n reportNode: TSESTree.Node\n ): void {\n if (shouldIgnoreComponent(name)) return;\n\n const firstParam = node.params[0];\n if (!firstParam) return;\n\n const { propNames, isSpread } = extractPropsFromParam(firstParam);\n\n // If using spread without destructuring, we can't easily track props\n if (isSpread && propNames.size === 0) return;\n\n const body = node.body;\n if (!body) return;\n\n const { passedProps, usedProps } = analyzeJSXPropPassing(body, propNames);\n\n componentProps.set(name, {\n receivedProps: propNames,\n passedProps,\n usedProps,\n childComponents: [...new Set([...passedProps.values()].flat())],\n });\n\n componentNodes.set(name, reportNode);\n }\n\n return {\n // Track imports for cross-file analysis\n ImportDeclaration(node) {\n const source = node.source.value as string;\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\" || spec.type === \"ImportDefaultSpecifier\") {\n imports.set(spec.local.name, source);\n }\n }\n },\n\n // Analyze function declarations\n FunctionDeclaration(node) {\n if (node.id && isComponentName(node.id.name)) {\n analyzeComponent(node.id.name, node, node);\n }\n },\n\n // Analyze arrow functions\n VariableDeclarator(node) {\n if (\n node.id.type === \"Identifier\" &&\n isComponentName(node.id.name) &&\n node.init?.type === \"ArrowFunctionExpression\"\n ) {\n analyzeComponent(node.id.name, node.init, node);\n }\n },\n\n // Analyze at the end of the file\n \"Program:exit\"() {\n // Find drilling chains within the file\n for (const [componentName, info] of componentProps) {\n for (const [propName, children] of info.passedProps) {\n if (shouldIgnoreProp(propName)) continue;\n\n // Check if prop is used directly\n if (info.usedProps.has(propName)) continue;\n\n // Track the drilling chain\n const chain: string[] = [componentName];\n let depth = 0;\n let current = children;\n\n while (current.length > 0 && depth < maxDepth + 1) {\n depth++;\n const nextChildren: string[] = [];\n\n for (const child of current) {\n chain.push(child);\n const childInfo = componentProps.get(child);\n\n if (childInfo) {\n // Check if child uses the prop\n if (childInfo.usedProps.has(propName)) {\n // Prop is used here, drilling stops\n break;\n }\n\n // Check if child passes the prop further\n const childPasses = childInfo.passedProps.get(propName);\n if (childPasses) {\n nextChildren.push(...childPasses);\n }\n }\n }\n\n current = nextChildren;\n }\n\n // Report if depth exceeds threshold\n if (depth > maxDepth) {\n const reportNode = componentNodes.get(componentName);\n if (reportNode) {\n context.report({\n node: reportNode,\n messageId: \"propDrilling\",\n data: {\n propName,\n depth: String(depth),\n path: chain.slice(0, maxDepth + 2).join(\" → \"),\n },\n });\n }\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: no-secrets-in-code\n *\n * Detects hardcoded secrets, API keys, passwords, and tokens in source code.\n * Prevents accidental exposure of sensitive credentials.\n *\n * Examples:\n * - Bad: const apiKey = 'AKIA1234567890ABCDEF'\n * - Bad: const password = 'mySecretPassword123'\n * - Good: const apiKey = process.env.API_KEY\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"secretDetected\" | \"suspiciousVariable\";\ntype Options = [\n {\n /** Additional regex patterns to detect (as strings) */\n additionalPatterns?: Array<{ name: string; pattern: string }>;\n /** Check variable names for suspicious patterns */\n checkVariableNames?: boolean;\n /** Minimum length for generic secret detection */\n minSecretLength?: number;\n /** Relax rules in test files */\n allowInTestFiles?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-secrets-in-code\",\n name: \"No Secrets in Code\",\n description: \"Detect hardcoded secrets, API keys, and tokens\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [\n {\n checkVariableNames: true,\n minSecretLength: 16,\n allowInTestFiles: false,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"checkVariableNames\",\n label: \"Check variable names\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Check for suspicious variable names with high-entropy values\",\n },\n {\n key: \"minSecretLength\",\n label: \"Minimum secret length\",\n type: \"number\",\n defaultValue: 16,\n description: \"Minimum string length for generic secret detection\",\n },\n {\n key: \"allowInTestFiles\",\n label: \"Allow in test files\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Skip detection in test files (*.test.*, *.spec.*)\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects hardcoded secrets, API keys, passwords, and tokens in source code.\nThese should be stored in environment variables or secure vaults instead.\n\n## Why it's useful\n\n- **Security**: Prevents credential leaks in version control\n- **Compliance**: Helps meet security audit requirements\n- **Best Practice**: Enforces proper secrets management\n\n## Detected Patterns\n\n- AWS Access Keys and Secret Keys\n- GitHub Personal Access Tokens (ghp_*)\n- Stripe API Keys (sk_live_*, sk_test_*)\n- Google API Keys\n- Firebase Keys\n- Slack Tokens\n- npm Tokens\n- JWT Tokens\n- Private Keys (PEM format)\n- Generic API keys, passwords, and secrets in suspicious variables\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Hardcoded AWS credentials\nconst accessKey = 'AKIA1234567890ABCDEF';\nconst secretKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';\n\n// Hardcoded passwords\nconst dbPassword = 'supersecretpassword123';\n\n// Hardcoded tokens\nconst token = 'ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Use environment variables\nconst accessKey = process.env.AWS_ACCESS_KEY_ID;\nconst secretKey = process.env.AWS_SECRET_ACCESS_KEY;\n\n// Reference from config\nconst dbPassword = config.database.password;\n\n// Use a secrets manager\nconst token = await secretsManager.getSecret('github-token');\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-secrets-in-code\": [\"error\", {\n checkVariableNames: true, // Check suspicious variable names\n minSecretLength: 16, // Minimum length for generic detection\n allowInTestFiles: false, // Don't skip test files\n additionalPatterns: [ // Add custom patterns\n { name: \"Custom API\", pattern: \"^myapi_[a-z0-9]{32}$\" }\n ]\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Known secret patterns with names and regex\n */\nconst SECRET_PATTERNS: Array<{ name: string; pattern: RegExp }> = [\n // AWS\n { name: \"AWS Access Key ID\", pattern: /\\bAKIA[0-9A-Z]{16}\\b/ },\n { name: \"AWS Secret Access Key\", pattern: /\\b[A-Za-z0-9/+=]{40}\\b/ },\n\n // GitHub\n { name: \"GitHub Personal Access Token\", pattern: /\\bghp_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub OAuth Token\", pattern: /\\bgho_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub App Token\", pattern: /\\bghu_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub Refresh Token\", pattern: /\\bghr_[A-Za-z0-9]{36}\\b/ },\n\n // Stripe\n { name: \"Stripe Live Secret Key\", pattern: /\\bsk_live_[A-Za-z0-9]{24,}\\b/ },\n { name: \"Stripe Test Secret Key\", pattern: /\\bsk_test_[A-Za-z0-9]{24,}\\b/ },\n { name: \"Stripe Restricted Key\", pattern: /\\brk_live_[A-Za-z0-9]{24,}\\b/ },\n\n // Google\n { name: \"Google API Key\", pattern: /\\bAIza[A-Za-z0-9_-]{35}\\b/ },\n\n // Slack\n { name: \"Slack Token\", pattern: /\\bxox[baprs]-[A-Za-z0-9-]{10,48}\\b/ },\n { name: \"Slack Webhook\", pattern: /\\bhooks\\.slack\\.com\\/services\\/T[A-Za-z0-9]+\\/B[A-Za-z0-9]+\\/[A-Za-z0-9]+\\b/ },\n\n // npm\n { name: \"npm Token\", pattern: /\\bnpm_[A-Za-z0-9]{36}\\b/ },\n\n // SendGrid\n { name: \"SendGrid API Key\", pattern: /\\bSG\\.[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}\\b/ },\n\n // Twilio\n { name: \"Twilio API Key\", pattern: /\\bSK[a-z0-9]{32}\\b/ },\n\n // Firebase\n { name: \"Firebase Key\", pattern: /\\bAAAA[A-Za-z0-9_-]{7}:[A-Za-z0-9_-]{140}\\b/ },\n\n // Generic patterns\n { name: \"Private Key\", pattern: /-----BEGIN\\s+(RSA\\s+|EC\\s+|DSA\\s+|OPENSSH\\s+)?PRIVATE\\s+KEY-----/ },\n { name: \"JWT Token\", pattern: /\\beyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/ },\n\n // Anthropic\n { name: \"Anthropic API Key\", pattern: /\\bsk-ant-api[A-Za-z0-9_-]{20,}\\b/ },\n\n // OpenAI\n { name: \"OpenAI API Key\", pattern: /\\bsk-proj-[A-Za-z0-9_-]{20,}\\b/ },\n { name: \"OpenAI API Key (old)\", pattern: /\\bsk-[A-Za-z0-9]{48}\\b/ },\n];\n\n/**\n * Variable name patterns that suggest secrets\n */\nconst SUSPICIOUS_VARIABLE_PATTERNS: RegExp[] = [\n /^api[_-]?key$/i,\n /^secret[_-]?key$/i,\n /^private[_-]?key$/i,\n /^access[_-]?key$/i,\n /^auth[_-]?key$/i,\n /^access[_-]?token$/i,\n /^auth[_-]?token$/i,\n /^api[_-]?token$/i,\n /^bearer[_-]?token$/i,\n /^jwt[_-]?token$/i,\n /^refresh[_-]?token$/i,\n /^password$/i,\n /^passwd$/i,\n /^pwd$/i,\n /^db[_-]?password$/i,\n /^database[_-]?password$/i,\n /^secret$/i,\n /^client[_-]?secret$/i,\n /^app[_-]?secret$/i,\n];\n\n/**\n * Patterns that indicate safe/placeholder values\n */\nconst PLACEHOLDER_PATTERNS: RegExp[] = [\n /^your[_-]?/i,\n /^xxx+$/i,\n /^placeholder/i,\n /^example/i,\n /^test[_-]?/i,\n /^fake[_-]?/i,\n /^dummy/i,\n /^sample/i,\n /<[^>]+>/, // <your-key-here>\n /\\${[^}]+}/, // ${API_KEY}\n /^\\*+$/, // ****\n];\n\n/**\n * Calculate Shannon entropy of a string\n */\nfunction calculateEntropy(str: string): number {\n if (str.length === 0) return 0;\n\n const freq: Record<string, number> = {};\n for (const char of str) {\n freq[char] = (freq[char] || 0) + 1;\n }\n\n let entropy = 0;\n const len = str.length;\n for (const count of Object.values(freq)) {\n const p = count / len;\n entropy -= p * Math.log2(p);\n }\n\n return entropy;\n}\n\n/**\n * Check if a value looks like a placeholder\n */\nfunction isPlaceholder(value: string): boolean {\n return PLACEHOLDER_PATTERNS.some((pattern) => pattern.test(value));\n}\n\n/**\n * Check if a value is likely an environment variable reference\n */\nfunction isEnvReference(value: string): boolean {\n return value.includes(\"process.env\") || value.includes(\"import.meta.env\");\n}\n\n/**\n * Get a preview of the secret (first and last few chars)\n */\nfunction getPreview(value: string, maxLength: number = 20): string {\n if (value.length <= maxLength) {\n return value.substring(0, 8) + \"...\";\n }\n return value.substring(0, 8) + \"...\" + value.substring(value.length - 4);\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(filename: string): boolean {\n return /\\.(test|spec)\\.[jt]sx?$/.test(filename) ||\n /\\/__tests__\\//.test(filename) ||\n /\\/test\\//.test(filename);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-secrets-in-code\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Detect hardcoded secrets, API keys, and tokens\",\n },\n messages: {\n secretDetected:\n \"Potential {{secretType}} detected: '{{preview}}'. Use environment variables instead of hardcoding secrets.\",\n suspiciousVariable:\n \"Variable '{{variableName}}' appears to contain a secret. Use environment variables instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n additionalPatterns: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n pattern: { type: \"string\" },\n },\n required: [\"name\", \"pattern\"],\n },\n description: \"Additional patterns to detect\",\n },\n checkVariableNames: {\n type: \"boolean\",\n description: \"Check variable names for suspicious patterns\",\n },\n minSecretLength: {\n type: \"number\",\n description: \"Minimum length for generic secret detection\",\n },\n allowInTestFiles: {\n type: \"boolean\",\n description: \"Skip detection in test files\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n checkVariableNames: true,\n minSecretLength: 16,\n allowInTestFiles: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const checkVariableNames = options.checkVariableNames ?? true;\n const minSecretLength = options.minSecretLength ?? 16;\n const allowInTestFiles = options.allowInTestFiles ?? false;\n const additionalPatterns = options.additionalPatterns ?? [];\n\n const filename = context.filename || context.getFilename?.() || \"\";\n\n // Skip test files if configured\n if (allowInTestFiles && isTestFile(filename)) {\n return {};\n }\n\n // Build full pattern list\n const allPatterns = [...SECRET_PATTERNS];\n for (const custom of additionalPatterns) {\n try {\n allPatterns.push({\n name: custom.name,\n pattern: new RegExp(custom.pattern),\n });\n } catch {\n // Invalid regex, skip\n }\n }\n\n /**\n * Check a string value for secrets\n */\n function checkStringForSecrets(\n value: string,\n node: TSESTree.Node,\n variableName?: string\n ): void {\n // Skip empty strings and short strings\n if (!value || value.length < 8) {\n return;\n }\n\n // Skip placeholders\n if (isPlaceholder(value)) {\n return;\n }\n\n // Check against known patterns\n for (const { name, pattern } of allPatterns) {\n if (pattern.test(value)) {\n context.report({\n node,\n messageId: \"secretDetected\",\n data: {\n secretType: name,\n preview: getPreview(value),\n },\n });\n return;\n }\n }\n\n // Check for suspicious variable names with high-entropy values\n if (checkVariableNames && variableName) {\n const isSuspiciousName = SUSPICIOUS_VARIABLE_PATTERNS.some((pattern) =>\n pattern.test(variableName)\n );\n\n if (isSuspiciousName && value.length >= minSecretLength) {\n const entropy = calculateEntropy(value);\n // High entropy (> 3.5) suggests random/secret data\n if (entropy > 3.5) {\n context.report({\n node,\n messageId: \"suspiciousVariable\",\n data: {\n variableName,\n },\n });\n }\n }\n }\n }\n\n /**\n * Get variable name from declarator\n */\n function getVariableName(node: TSESTree.Node): string | undefined {\n if (node.parent?.type === \"VariableDeclarator\") {\n const declarator = node.parent;\n if (declarator.id.type === \"Identifier\") {\n return declarator.id.name;\n }\n }\n if (node.parent?.type === \"Property\") {\n const prop = node.parent;\n if (prop.key.type === \"Identifier\") {\n return prop.key.name;\n }\n }\n return undefined;\n }\n\n return {\n // Check string literals\n Literal(node) {\n if (typeof node.value === \"string\") {\n const variableName = getVariableName(node);\n checkStringForSecrets(node.value, node, variableName);\n }\n },\n\n // Check template literals\n TemplateLiteral(node) {\n // Only check if no expressions (pure string)\n if (node.expressions.length === 0 && node.quasis.length === 1) {\n const value = node.quasis[0].value.raw;\n const variableName = getVariableName(node);\n checkStringForSecrets(value, node, variableName);\n }\n },\n };\n },\n});\n","/**\n * Rule: require-input-validation\n *\n * Requires API route handlers to validate request body using schema validation\n * libraries like Zod, Yup, or Joi before accessing request data.\n *\n * Examples:\n * - Bad: const { name } = await req.json()\n * - Good: const data = schema.parse(await req.json())\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"missingValidation\" | \"unvalidatedBodyAccess\";\ntype Options = [\n {\n /** HTTP methods that require validation (default: POST, PUT, PATCH, DELETE) */\n httpMethods?: string[];\n /** File patterns that indicate API routes */\n routePatterns?: string[];\n /** Allow manual type guards/if-checks as validation */\n allowManualValidation?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"require-input-validation\",\n name: \"Require Input Validation\",\n description: \"Require schema validation in API route handlers\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"route.tsx\", \"/api/\", \"/app/api/\"],\n allowManualValidation: false,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"httpMethods\",\n label: \"HTTP methods requiring validation\",\n type: \"multiselect\",\n defaultValue: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ],\n description: \"HTTP methods that require request body validation\",\n },\n {\n key: \"allowManualValidation\",\n label: \"Allow manual validation\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Allow if-checks and type guards instead of schema validation\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnsures that API route handlers validate request body data using a schema\nvalidation library (Zod, Yup, Joi, etc.) before accessing it.\n\n## Why it's useful\n\n- **Security**: Prevents injection attacks and malformed data\n- **Type Safety**: Ensures runtime data matches expected types\n- **Error Handling**: Provides clear validation error messages\n- **Best Practice**: Follows defense-in-depth principles\n\n## Supported Validation Libraries\n\n- Zod: \\`parse()\\`, \\`safeParse()\\`, \\`parseAsync()\\`\n- Yup: \\`validate()\\`, \\`validateSync()\\`\n- Joi: \\`validate()\\`\n- Superstruct: \\`create()\\`, \\`assert()\\`\n- io-ts: \\`decode()\\`\n- Valibot: \\`parse()\\`, \\`safeParse()\\`\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Next.js App Router\nexport async function POST(request: Request) {\n const body = await request.json();\n // Body accessed without validation\n await db.users.create({ name: body.name });\n}\n\n// Next.js Pages API\nexport default function handler(req, res) {\n const { email } = req.body; // Unvalidated\n sendEmail(email);\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\nimport { z } from 'zod';\n\nconst CreateUserSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n});\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const data = CreateUserSchema.parse(body); // Validated!\n await db.users.create(data);\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/require-input-validation\": [\"warn\", {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"/api/\"],\n allowManualValidation: false\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * HTTP method names (Next.js App Router style)\n */\nconst HTTP_METHODS = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"];\n\n/**\n * Validation method names from common libraries\n */\nconst VALIDATION_METHODS = [\n // Zod\n \"parse\",\n \"safeParse\",\n \"parseAsync\",\n \"safeParseAsync\",\n // Yup\n \"validate\",\n \"validateSync\",\n \"validateAt\",\n \"validateSyncAt\",\n // Joi\n \"validate\",\n \"validateAsync\",\n // Superstruct\n \"create\",\n \"assert\",\n // io-ts\n \"decode\",\n // Valibot\n \"parse\",\n \"safeParse\",\n // Generic\n \"validateBody\",\n \"validateRequest\",\n \"validateInput\",\n];\n\n/**\n * Check if file matches route patterns\n */\nfunction isApiRouteFile(filename: string, patterns: string[]): boolean {\n return patterns.some((pattern) => filename.includes(pattern));\n}\n\n/**\n * Check if a function is an HTTP method handler\n */\nfunction isHttpMethodHandler(\n node: TSESTree.Node,\n methods: string[]\n): { isHandler: boolean; method: string | null } {\n // Check export function GET/POST/etc\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n const name = node.declaration.id.name.toUpperCase();\n if (methods.includes(name)) {\n return { isHandler: true, method: name };\n }\n }\n\n // Check export const GET = async () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (decl.id.type === \"Identifier\") {\n const name = decl.id.name.toUpperCase();\n if (methods.includes(name)) {\n return { isHandler: true, method: name };\n }\n }\n }\n }\n\n return { isHandler: false, method: null };\n}\n\n/**\n * Check if a call expression is a validation call\n */\nfunction isValidationCall(node: TSESTree.CallExpression): boolean {\n // Check method calls: schema.parse(), schema.validate()\n if (\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\"\n ) {\n const methodName = node.callee.property.name;\n\n // Exclude JSON.parse as it's not schema validation\n if (\n node.callee.object.type === \"Identifier\" &&\n node.callee.object.name === \"JSON\" &&\n methodName === \"parse\"\n ) {\n return false;\n }\n\n return VALIDATION_METHODS.includes(methodName);\n }\n\n // Check direct calls: validate(schema, data)\n if (node.callee.type === \"Identifier\") {\n const funcName = node.callee.name;\n return VALIDATION_METHODS.includes(funcName);\n }\n\n return false;\n}\n\n/**\n * Check if a node is a body access pattern\n */\nfunction isBodyAccess(node: TSESTree.Node): {\n isAccess: boolean;\n accessType: string | null;\n} {\n // req.body\n if (\n node.type === \"MemberExpression\" &&\n node.property.type === \"Identifier\" &&\n node.property.name === \"body\"\n ) {\n return { isAccess: true, accessType: \"req.body\" };\n }\n\n // request.json() or req.json()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"json\"\n ) {\n return { isAccess: true, accessType: \"request.json()\" };\n }\n\n // request.formData()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"formData\"\n ) {\n return { isAccess: true, accessType: \"request.formData()\" };\n }\n\n // request.text()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"text\"\n ) {\n return { isAccess: true, accessType: \"request.text()\" };\n }\n\n return { isAccess: false, accessType: null };\n}\n\n/**\n * Track if we're inside a validation context\n */\ninterface ValidationContext {\n hasValidation: boolean;\n bodyAccessNodes: Array<{ node: TSESTree.Node; accessType: string }>;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"require-input-validation\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Require schema validation in API route handlers\",\n },\n messages: {\n missingValidation:\n \"API route handler '{{method}}' accesses request body without validation. Use a schema validation library like Zod.\",\n unvalidatedBodyAccess:\n \"Accessing '{{accessType}}' without prior validation. Validate the data first using a schema.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n httpMethods: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"HTTP methods that require validation\",\n },\n routePatterns: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"File patterns that indicate API routes\",\n },\n allowManualValidation: {\n type: \"boolean\",\n description: \"Allow manual type guards as validation\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"route.tsx\", \"/api/\", \"/app/api/\"],\n allowManualValidation: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const httpMethods = (options.httpMethods ?? [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]).map(\n (m) => m.toUpperCase()\n );\n const routePatterns = options.routePatterns ?? [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\",\n ];\n\n const filename = context.filename || context.getFilename?.() || \"\";\n\n // Only check API route files\n if (!isApiRouteFile(filename, routePatterns)) {\n return {};\n }\n\n // Track handlers and their validation status\n const handlerContexts = new Map<TSESTree.Node, ValidationContext>();\n let currentHandler: TSESTree.Node | null = null;\n let currentMethod: string | null = null;\n\n return {\n // Detect HTTP method handlers\n ExportNamedDeclaration(node) {\n const { isHandler, method } = isHttpMethodHandler(node, httpMethods);\n if (isHandler) {\n currentHandler = node;\n currentMethod = method;\n handlerContexts.set(node, {\n hasValidation: false,\n bodyAccessNodes: [],\n });\n }\n },\n\n // Track body access within handlers\n MemberExpression(node) {\n if (!currentHandler) return;\n\n const ctx = handlerContexts.get(currentHandler);\n if (!ctx) return;\n\n const { isAccess, accessType } = isBodyAccess(node);\n if (isAccess && accessType) {\n ctx.bodyAccessNodes.push({ node, accessType });\n }\n },\n\n CallExpression(node) {\n if (!currentHandler) return;\n\n const ctx = handlerContexts.get(currentHandler);\n if (!ctx) return;\n\n // Check for body access\n const { isAccess, accessType } = isBodyAccess(node);\n if (isAccess && accessType) {\n // Check if this is inside a validation call\n // e.g., schema.parse(await request.json())\n if (\n node.parent?.type === \"AwaitExpression\" &&\n node.parent.parent?.type === \"CallExpression\" &&\n isValidationCall(node.parent.parent)\n ) {\n ctx.hasValidation = true;\n return;\n }\n\n // Check if this is directly wrapped in validation\n if (\n node.parent?.type === \"CallExpression\" &&\n isValidationCall(node.parent)\n ) {\n ctx.hasValidation = true;\n return;\n }\n\n ctx.bodyAccessNodes.push({ node, accessType });\n }\n\n // Check for validation calls\n if (isValidationCall(node)) {\n ctx.hasValidation = true;\n }\n },\n\n \"ExportNamedDeclaration:exit\"(node: TSESTree.ExportNamedDeclaration) {\n const ctx = handlerContexts.get(node);\n if (!ctx) return;\n\n // If we have body access but no validation, report\n if (ctx.bodyAccessNodes.length > 0 && !ctx.hasValidation) {\n // Report on the first body access\n const firstAccess = ctx.bodyAccessNodes[0];\n context.report({\n node: firstAccess.node,\n messageId: \"unvalidatedBodyAccess\",\n data: {\n accessType: firstAccess.accessType,\n },\n });\n }\n\n // Clean up\n if (currentHandler === node) {\n currentHandler = null;\n currentMethod = null;\n }\n handlerContexts.delete(node);\n },\n };\n },\n});\n","/**\n * Rule Registry\n *\n * Central registry of all UILint ESLint rules with metadata for CLI tooling.\n * Metadata is now colocated with each rule file - this module re-exports\n * the collected metadata for use by installers and other tools.\n */\n\n// Re-export types from create-rule for consumers\nexport type {\n RuleMeta,\n RuleOptionSchema,\n OptionFieldSchema,\n} from \"./utils/create-rule.js\";\n\n// Backward compatibility alias\nexport type { RuleMeta as RuleMetadata } from \"./utils/create-rule.js\";\n\n// Import colocated metadata from each rule file\nimport { meta as noArbitraryTailwind } from \"./rules/no-arbitrary-tailwind.js\";\nimport { meta as consistentSpacing } from \"./rules/consistent-spacing.js\";\nimport { meta as consistentDarkMode } from \"./rules/consistent-dark-mode.js\";\nimport { meta as noDirectStoreImport } from \"./rules/no-direct-store-import.js\";\nimport { meta as preferZustandStateManagement } from \"./rules/prefer-zustand-state-management.js\";\nimport { meta as noMixedComponentLibraries } from \"./rules/no-mixed-component-libraries.js\";\nimport { meta as semantic } from \"./rules/semantic.js\";\nimport { meta as semanticVision } from \"./rules/semantic-vision.js\";\n\n// New rules\nimport { meta as enforceAbsoluteImports } from \"./rules/enforce-absolute-imports.js\";\nimport { meta as noAnyInProps } from \"./rules/no-any-in-props.js\";\nimport { meta as zustandUseSelectors } from \"./rules/zustand-use-selectors.js\";\nimport { meta as noSecretsInCode } from \"./rules/no-secrets-in-code.js\";\nimport { meta as requireInputValidation } from \"./rules/require-input-validation.js\";\nimport { meta as noPropDrillingDepth } from \"./rules/no-prop-drilling-depth.js\";\n\nimport type { RuleMeta } from \"./utils/create-rule.js\";\n\n/**\n * Registry of all available UILint ESLint rules\n *\n * When adding a new rule:\n * 1. Create the rule file in src/rules/\n * 2. Export a `meta` object using `defineRuleMeta()`\n * 3. Import and add the meta to this array\n * 4. Run `pnpm generate:index` to regenerate exports\n */\nexport const ruleRegistry: RuleMeta[] = [\n // Existing rules\n noArbitraryTailwind,\n consistentSpacing,\n consistentDarkMode,\n noDirectStoreImport,\n preferZustandStateManagement,\n noMixedComponentLibraries,\n semantic,\n semanticVision,\n // New UI rules\n enforceAbsoluteImports,\n noAnyInProps,\n zustandUseSelectors,\n noPropDrillingDepth,\n // New security rules\n noSecretsInCode,\n requireInputValidation,\n];\n\n/**\n * Get rule metadata by ID\n */\nexport function getRuleMetadata(id: string): RuleMeta | undefined {\n return ruleRegistry.find((rule) => rule.id === id);\n}\n\n/**\n * Get all rules in a category\n */\nexport function getRulesByCategory(\n category: \"static\" | \"semantic\"\n): RuleMeta[] {\n return ruleRegistry.filter((rule) => rule.category === category);\n}\n\n/**\n * Get documentation for a rule (useful for CLI help commands)\n */\nexport function getRuleDocs(id: string): string | undefined {\n const rule = getRuleMetadata(id);\n return rule?.docs;\n}\n\n/**\n * Get all rule IDs\n */\nexport function getAllRuleIds(): string[] {\n return ruleRegistry.map((rule) => rule.id);\n}\n","/**\n * UILint ESLint Plugin\n *\n * THIS FILE IS AUTO-GENERATED from src/rule-registry.ts.\n * Do not edit by hand. Run: pnpm -C packages/uilint-eslint generate:index\n */\n\nimport type { Linter } from \"eslint\";\nimport noArbitraryTailwind from \"./rules/no-arbitrary-tailwind.js\";\nimport consistentSpacing from \"./rules/consistent-spacing.js\";\nimport consistentDarkMode from \"./rules/consistent-dark-mode.js\";\nimport noDirectStoreImport from \"./rules/no-direct-store-import.js\";\nimport preferZustandStateManagement from \"./rules/prefer-zustand-state-management.js\";\nimport noMixedComponentLibraries from \"./rules/no-mixed-component-libraries.js\";\nimport semantic from \"./rules/semantic.js\";\nimport semanticVision from \"./rules/semantic-vision.js\";\nimport enforceAbsoluteImports from \"./rules/enforce-absolute-imports.js\";\nimport noAnyInProps from \"./rules/no-any-in-props.js\";\nimport zustandUseSelectors from \"./rules/zustand-use-selectors.js\";\nimport noPropDrillingDepth from \"./rules/no-prop-drilling-depth.js\";\nimport noSecretsInCode from \"./rules/no-secrets-in-code.js\";\nimport requireInputValidation from \"./rules/require-input-validation.js\";\n\n/**\n * All available rules\n */\nconst rules = {\n \"no-arbitrary-tailwind\": noArbitraryTailwind,\n \"consistent-spacing\": consistentSpacing,\n \"consistent-dark-mode\": consistentDarkMode,\n \"no-direct-store-import\": noDirectStoreImport,\n \"prefer-zustand-state-management\": preferZustandStateManagement,\n \"no-mixed-component-libraries\": noMixedComponentLibraries,\n \"semantic\": semantic,\n \"semantic-vision\": semanticVision,\n \"enforce-absolute-imports\": enforceAbsoluteImports,\n \"no-any-in-props\": noAnyInProps,\n \"zustand-use-selectors\": zustandUseSelectors,\n \"no-prop-drilling-depth\": noPropDrillingDepth,\n \"no-secrets-in-code\": noSecretsInCode,\n \"require-input-validation\": requireInputValidation,\n};\n\n// Package version (injected at build time or fallback)\nconst version = \"0.1.0\";\n\n/**\n * Plugin metadata\n */\nconst meta = {\n name: \"uilint\",\n version,\n};\n\n/**\n * The ESLint plugin object\n */\nconst plugin = {\n meta,\n rules,\n};\n\n/**\n * Shared language options for all configs\n */\nconst jsxLanguageOptions: Linter.Config[\"languageOptions\"] = {\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n};\n\n/**\n * Recommended config - static rules only\n *\n * Usage:\n * ```js\n * import uilint from 'uilint-eslint';\n * export default [uilint.configs.recommended];\n * ```\n */\nconst recommendedConfig: Linter.Config = {\n name: \"uilint/recommended\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n uilint: plugin as any,\n },\n languageOptions: jsxLanguageOptions,\n rules: {\n \"uilint/no-arbitrary-tailwind\": \"error\",\n \"uilint/consistent-spacing\": [\"warn\", ...[\n {\n \"scale\": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 8,\n 10,\n 12,\n 16\n ]\n }\n ]],\n \"uilint/consistent-dark-mode\": [\"error\", ...[\n {\n \"warnOnMissingDarkMode\": true\n }\n ]],\n \"uilint/no-direct-store-import\": [\"warn\", ...[\n {\n \"storePattern\": \"use*Store\"\n }\n ]],\n \"uilint/prefer-zustand-state-management\": [\"warn\", ...[\n {\n \"maxStateHooks\": 3,\n \"countUseState\": true,\n \"countUseReducer\": true,\n \"countUseContext\": true\n }\n ]],\n \"uilint/no-mixed-component-libraries\": [\"error\", ...[\n {\n \"preferred\": \"shadcn\",\n \"libraries\": [\n \"shadcn\",\n \"mui\"\n ]\n }\n ]],\n \"uilint/enforce-absolute-imports\": [\"warn\", ...[\n {\n \"maxRelativeDepth\": 1,\n \"aliasPrefix\": \"@/\"\n }\n ]],\n \"uilint/no-any-in-props\": [\"error\", ...[\n {\n \"checkFCGenerics\": true,\n \"allowInGenericDefaults\": false\n }\n ]],\n \"uilint/zustand-use-selectors\": [\"warn\", ...[\n {\n \"storePattern\": \"^use\\\\w*Store$\",\n \"allowShallow\": true,\n \"requireNamedSelectors\": false\n }\n ]],\n \"uilint/no-prop-drilling-depth\": [\"warn\", ...[\n {\n \"maxDepth\": 2,\n \"ignoredProps\": [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\"\n ],\n \"ignoreComponents\": []\n }\n ]],\n \"uilint/no-secrets-in-code\": [\"error\", ...[\n {\n \"checkVariableNames\": true,\n \"minSecretLength\": 16,\n \"allowInTestFiles\": false\n }\n ]],\n \"uilint/require-input-validation\": [\"warn\", ...[\n {\n \"httpMethods\": [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n ],\n \"routePatterns\": [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\"\n ],\n \"allowManualValidation\": false\n }\n ]],\n },\n};\n\n/**\n * Strict config - static rules + semantic rules\n *\n * Usage:\n * ```js\n * import uilint from 'uilint-eslint';\n * export default [uilint.configs.strict];\n * ```\n */\nconst strictConfig: Linter.Config = {\n name: \"uilint/strict\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n uilint: plugin as any,\n },\n languageOptions: jsxLanguageOptions,\n rules: {\n \"uilint/no-arbitrary-tailwind\": \"error\",\n \"uilint/consistent-spacing\": [\"warn\", ...[\n {\n \"scale\": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 8,\n 10,\n 12,\n 16\n ]\n }\n ]],\n \"uilint/consistent-dark-mode\": [\"error\", ...[\n {\n \"warnOnMissingDarkMode\": true\n }\n ]],\n \"uilint/no-direct-store-import\": [\"warn\", ...[\n {\n \"storePattern\": \"use*Store\"\n }\n ]],\n \"uilint/prefer-zustand-state-management\": [\"warn\", ...[\n {\n \"maxStateHooks\": 3,\n \"countUseState\": true,\n \"countUseReducer\": true,\n \"countUseContext\": true\n }\n ]],\n \"uilint/no-mixed-component-libraries\": [\"error\", ...[\n {\n \"preferred\": \"shadcn\",\n \"libraries\": [\n \"shadcn\",\n \"mui\"\n ]\n }\n ]],\n \"uilint/semantic\": [\"warn\", ...[\n {\n \"model\": \"qwen3-coder:30b\",\n \"styleguidePath\": \".uilint/styleguide.md\"\n }\n ]],\n \"uilint/semantic-vision\": [\"warn\", ...[\n {\n \"maxAgeMs\": 3600000,\n \"screenshotsPath\": \".uilint/screenshots\"\n }\n ]],\n \"uilint/enforce-absolute-imports\": [\"warn\", ...[\n {\n \"maxRelativeDepth\": 1,\n \"aliasPrefix\": \"@/\"\n }\n ]],\n \"uilint/no-any-in-props\": [\"error\", ...[\n {\n \"checkFCGenerics\": true,\n \"allowInGenericDefaults\": false\n }\n ]],\n \"uilint/zustand-use-selectors\": [\"warn\", ...[\n {\n \"storePattern\": \"^use\\\\w*Store$\",\n \"allowShallow\": true,\n \"requireNamedSelectors\": false\n }\n ]],\n \"uilint/no-prop-drilling-depth\": [\"warn\", ...[\n {\n \"maxDepth\": 2,\n \"ignoredProps\": [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\"\n ],\n \"ignoreComponents\": []\n }\n ]],\n \"uilint/no-secrets-in-code\": [\"error\", ...[\n {\n \"checkVariableNames\": true,\n \"minSecretLength\": 16,\n \"allowInTestFiles\": false\n }\n ]],\n \"uilint/require-input-validation\": [\"warn\", ...[\n {\n \"httpMethods\": [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n ],\n \"routePatterns\": [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\"\n ],\n \"allowManualValidation\": false\n }\n ]],\n },\n};\n\n/**\n * Pre-configured configs\n */\nconst configs: Record<string, Linter.Config> = {\n recommended: recommendedConfig,\n strict: strictConfig,\n};\n\n/**\n * UILint ESLint export interface\n */\nexport interface UILintESLint {\n meta: typeof meta;\n plugin: typeof plugin;\n rules: typeof rules;\n configs: Record<string, Linter.Config>;\n}\n\n/**\n * Default export for ESLint flat config\n */\nconst uilintEslint: UILintESLint = {\n meta,\n plugin,\n rules,\n configs,\n};\n\nexport default uilintEslint;\n\n// Named exports for convenience\nexport { plugin, rules, configs, meta };\n\n// Re-export utilities for custom rule creation\nexport { createRule } from \"./utils/create-rule.js\";\nexport {\n loadStyleguide,\n findStyleguidePath,\n getStyleguide,\n} from \"./utils/styleguide-loader.js\";\nexport {\n hashContent,\n hashContentSync,\n getCacheEntry,\n setCacheEntry,\n clearCache,\n clearCacheEntry,\n loadCache,\n saveCache,\n type CacheEntry,\n type CachedIssue,\n type CacheStore,\n} from \"./utils/cache.js\";\n\n// Re-export import graph utilities (used by rules like no-mixed-component-libraries)\nexport {\n getComponentLibrary,\n clearCache as clearImportGraphCache,\n type LibraryName,\n} from \"./utils/import-graph.js\";\n\n// Re-export rule registry for CLI tooling\nexport {\n ruleRegistry,\n getRuleMetadata,\n getRulesByCategory,\n getRuleDocs,\n getAllRuleIds,\n type RuleMeta,\n type RuleMetadata, // Backward compatibility alias\n type OptionFieldSchema,\n type RuleOptionSchema,\n} from \"./rule-registry.js\";\n\n// Re-export defineRuleMeta for rule authors\nexport { defineRuleMeta } from \"./utils/create-rule.js\";\n"],"mappings":"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","names":["meta","meta","meta","checkClassString","meta","meta","isComponentName","meta","existsSync","readFileSync","dirname","join","existsSync","readFileSync","dirname","join","clearCache","existsSync","readFileSync","dirname","join","workspaceRoot","meta","dirname","readFileSync","findProjectRoot","existsSync","join","existsSync","readFileSync","dirname","join","relative","meta","findProjectRoot","existsSync","join","dirname","readFileSync","relative","meta","meta","meta","meta","isComponentName","meta","meta","meta","meta"]}
1
+ {"version":3,"sources":["../src/utils/create-rule.ts","../src/rules/no-arbitrary-tailwind.ts","../src/rules/consistent-spacing.ts","../src/rules/consistent-dark-mode.ts","../src/rules/no-direct-store-import.ts","../src/rules/prefer-zustand-state-management.ts","../src/utils/export-resolver.ts","../src/utils/component-parser.ts","../src/utils/import-graph.ts","../src/rules/no-mixed-component-libraries.ts","../src/rules/semantic.ts","../src/utils/cache.ts","../src/utils/styleguide-loader.ts","../src/rules/semantic-vision.ts","../src/rules/enforce-absolute-imports.ts","../src/rules/no-any-in-props.ts","../src/rules/zustand-use-selectors.ts","../src/rules/no-prop-drilling-depth.ts","../src/rules/no-secrets-in-code.ts","../src/rules/require-input-validation.ts","../src/rule-registry.ts","../src/index.ts"],"sourcesContent":["/**\n * Rule creation helper using @typescript-eslint/utils\n */\n\nimport { ESLintUtils } from \"@typescript-eslint/utils\";\n\nexport const createRule = ESLintUtils.RuleCreator(\n (name) =>\n `https://github.com/peter-suggate/uilint/blob/main/packages/uilint-eslint/docs/rules/${name}.md`\n);\n\n/**\n * Schema for prompting user to configure a rule option in the CLI\n */\nexport interface OptionFieldSchema {\n /** Field name in the options object */\n key: string;\n /** Display label for the prompt */\n label: string;\n /** Prompt type */\n type: \"text\" | \"number\" | \"boolean\" | \"select\" | \"multiselect\";\n /** Default value */\n defaultValue: unknown;\n /** Placeholder text (for text/number inputs) */\n placeholder?: string;\n /** Options for select/multiselect */\n options?: Array<{ value: string | number; label: string }>;\n /** Description/hint for the field */\n description?: string;\n}\n\n/**\n * Schema describing how to prompt for rule options during installation\n */\nexport interface RuleOptionSchema {\n /** Fields that can be configured for this rule */\n fields: OptionFieldSchema[];\n}\n\n/**\n * Colocated rule metadata - exported alongside each rule\n *\n * This structure keeps all rule metadata in the same file as the rule implementation,\n * making it easy to maintain and extend as new rules are added.\n */\nexport interface RuleMeta {\n /** Rule identifier (e.g., \"no-arbitrary-tailwind\") - must match filename */\n id: string;\n\n /** Display name for CLI (e.g., \"No Arbitrary Tailwind\") */\n name: string;\n\n /** Short description for CLI selection prompts (one line) */\n description: string;\n\n /** Default severity level */\n defaultSeverity: \"error\" | \"warn\" | \"off\";\n\n /** Category for grouping in CLI */\n category: \"static\" | \"semantic\";\n\n /** Whether this rule requires a styleguide file */\n requiresStyleguide?: boolean;\n\n /** Default options for the rule (passed as second element in ESLint config) */\n defaultOptions?: unknown[];\n\n /** Schema for prompting user to configure options during install */\n optionSchema?: RuleOptionSchema;\n\n /**\n * Detailed documentation in markdown format.\n * Should include:\n * - What the rule does\n * - Why it's useful\n * - Examples of incorrect and correct code\n * - Configuration options explained\n */\n docs: string;\n}\n\n/**\n * Helper to define rule metadata with type safety\n */\nexport function defineRuleMeta(meta: RuleMeta): RuleMeta {\n return meta;\n}\n","/**\n * Rule: no-arbitrary-tailwind\n *\n * Forbids arbitrary Tailwind values like w-[123px], bg-[#fff], etc.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"noArbitraryValue\";\ntype Options = [];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-arbitrary-tailwind\",\n name: \"No Arbitrary Tailwind\",\n description: \"Forbid arbitrary values like w-[123px], bg-[#fff]\",\n defaultSeverity: \"error\",\n category: \"static\",\n docs: `\n## What it does\n\nPrevents the use of arbitrary Tailwind CSS values (bracket notation) in your codebase.\nArbitrary values like \\`w-[123px]\\`, \\`bg-[#ff5500]\\`, or \\`text-[14px]\\` bypass Tailwind's\ndesign system and can lead to inconsistent UI.\n\n## Why it's useful\n\n- **Consistency**: Forces use of your design system's spacing, colors, and typography scales\n- **Maintainability**: Changes to design tokens automatically propagate everywhere\n- **Performance**: Arbitrary values generate extra CSS that can't be deduplicated\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n<div className=\"w-[123px] h-[456px]\"> // Arbitrary dimensions\n<div className=\"bg-[#ff5500]\"> // Arbitrary color\n<div className=\"text-[14px]\"> // Arbitrary font size\n<div className=\"p-[7px]\"> // Arbitrary padding\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n<div className=\"w-32 h-96\"> // Use spacing scale\n<div className=\"bg-orange-500\"> // Use color palette\n<div className=\"text-sm\"> // Use typography scale\n<div className=\"p-2\"> // Use spacing scale\n\\`\\`\\`\n\n## Notes\n\n- Data attributes like \\`data-[state=open]\\` are allowed as they don't affect styling\n- If you need a truly custom value, consider extending your Tailwind config instead\n`,\n});\n\n// Regex to match arbitrary Tailwind values: word-[anything]\nconst ARBITRARY_VALUE_REGEX = /\\b[\\w-]+-\\[[^\\]]+\\]/g;\n\nexport default createRule<Options, MessageIds>({\n name: \"no-arbitrary-tailwind\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Forbid arbitrary Tailwind values like w-[123px]\",\n },\n messages: {\n noArbitraryValue:\n \"Avoid arbitrary Tailwind value '{{value}}'. Use the spacing/color scale instead.\",\n },\n schema: [],\n },\n defaultOptions: [],\n create(context) {\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n // Handle string literal: className=\"...\"\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n checkClassString(context, value, value.value);\n }\n\n // Handle JSX expression: className={...}\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n\n // Direct string: className={\"...\"}\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n checkClassString(context, expr, expr.value);\n }\n\n // Template literal: className={`...`}\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n checkClassString(context, quasi, quasi.value.raw);\n }\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (name === \"cn\" || name === \"clsx\" || name === \"classnames\") {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n checkClassString(context, arg, arg.value);\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n checkClassString(context, quasi, quasi.value.raw);\n }\n }\n }\n }\n },\n };\n },\n});\n\nfunction checkClassString(\n context: Parameters<\n ReturnType<typeof createRule<[], \"noArbitraryValue\">>[\"create\"]\n >[0],\n node: TSESTree.Node,\n classString: string\n) {\n const matches = classString.matchAll(ARBITRARY_VALUE_REGEX);\n\n for (const match of matches) {\n // Ignore data attributes (e.g., data-[value], data-test-[something])\n if (match[0].startsWith(\"data-\")) {\n continue;\n }\n\n context.report({\n node,\n messageId: \"noArbitraryValue\",\n data: { value: match[0] },\n });\n }\n}\n","/**\n * Rule: consistent-spacing\n *\n * Enforces use of spacing scale values in gap, padding, margin utilities.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"invalidSpacing\";\ntype Options = [\n {\n scale?: number[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"consistent-spacing\",\n name: \"Consistent Spacing\",\n description: \"Enforce spacing scale (no magic numbers in gap/padding)\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ scale: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16] }],\n optionSchema: {\n fields: [\n {\n key: \"scale\",\n label: \"Allowed spacing values\",\n type: \"text\",\n defaultValue: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16],\n placeholder: \"0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16\",\n description: \"Comma-separated list of allowed spacing values\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnsures all spacing utilities (padding, margin, gap, etc.) use values from a defined scale.\nThis prevents \"magic number\" spacing values that create visual inconsistency.\n\n## Why it's useful\n\n- **Visual rhythm**: Consistent spacing creates a professional, cohesive feel\n- **Design system compliance**: Enforces your spacing tokens\n- **Easier maintenance**: Spacing changes can be made systematically\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n<div className=\"p-7\"> // 7 isn't in the default scale\n<div className=\"gap-13\"> // 13 isn't in the default scale\n<div className=\"mt-9\"> // 9 isn't in the default scale\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n<div className=\"p-8\"> // 8 is in the scale\n<div className=\"gap-12\"> // 12 is in the scale\n<div className=\"mt-10\"> // 10 is in the scale\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/consistent-spacing\": [\"warn\", {\n scale: [0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24]\n}]\n\\`\\`\\`\n\nThe default scale is Tailwind's standard spacing values. Customize it to match your design system.\n`,\n});\n\n// Default Tailwind spacing scale\nconst DEFAULT_SCALE = [\n 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 16, 20, 24,\n 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 72, 80, 96,\n];\n\n// Spacing utilities that take numeric values\nconst SPACING_PREFIXES = [\n \"p-\",\n \"px-\",\n \"py-\",\n \"pt-\",\n \"pr-\",\n \"pb-\",\n \"pl-\",\n \"ps-\",\n \"pe-\",\n \"m-\",\n \"mx-\",\n \"my-\",\n \"mt-\",\n \"mr-\",\n \"mb-\",\n \"ml-\",\n \"ms-\",\n \"me-\",\n \"gap-\",\n \"gap-x-\",\n \"gap-y-\",\n \"space-x-\",\n \"space-y-\",\n \"inset-\",\n \"inset-x-\",\n \"inset-y-\",\n \"top-\",\n \"right-\",\n \"bottom-\",\n \"left-\",\n \"w-\",\n \"h-\",\n \"min-w-\",\n \"min-h-\",\n \"max-w-\",\n \"max-h-\",\n \"size-\",\n];\n\n// Build regex to match spacing utilities with numeric values\nfunction buildSpacingRegex(): RegExp {\n const prefixes = SPACING_PREFIXES.map((p) => p.replace(\"-\", \"\\\\-\")).join(\"|\");\n // Match prefix followed by a number (possibly with decimal)\n return new RegExp(`\\\\b(${prefixes})(\\\\d+\\\\.?\\\\d*)\\\\b`, \"g\");\n}\n\nconst SPACING_REGEX = buildSpacingRegex();\n\nexport default createRule<Options, MessageIds>({\n name: \"consistent-spacing\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Enforce spacing scale (no magic numbers in gap/padding)\",\n },\n messages: {\n invalidSpacing:\n \"Spacing value '{{value}}' is not in the allowed scale. Use one of: {{allowed}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n scale: {\n type: \"array\",\n items: { type: \"number\" },\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ scale: DEFAULT_SCALE }],\n create(context) {\n const options = context.options[0] || {};\n const scale = new Set((options.scale || DEFAULT_SCALE).map(String));\n const scaleList = [...scale].slice(0, 10).join(\", \") + \"...\";\n\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n checkSpacing(context, node, value.value, scale, scaleList);\n }\n\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n checkSpacing(context, node, expr.value, scale, scaleList);\n }\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n checkSpacing(context, node, quasi.value.raw, scale, scaleList);\n }\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (name === \"cn\" || name === \"clsx\" || name === \"classnames\") {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n checkSpacing(context, arg, arg.value, scale, scaleList);\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n checkSpacing(context, quasi, quasi.value.raw, scale, scaleList);\n }\n }\n }\n }\n },\n };\n },\n});\n\nfunction checkSpacing(\n context: Parameters<\n ReturnType<typeof createRule<Options, \"invalidSpacing\">>[\"create\"]\n >[0],\n node: TSESTree.Node,\n classString: string,\n scale: Set<string>,\n scaleList: string\n) {\n // Reset regex state\n SPACING_REGEX.lastIndex = 0;\n\n let match;\n while ((match = SPACING_REGEX.exec(classString)) !== null) {\n const [, , value] = match;\n if (value && !scale.has(value)) {\n context.report({\n node,\n messageId: \"invalidSpacing\",\n data: { value, allowed: scaleList },\n });\n }\n }\n}\n","/**\n * Rule: consistent-dark-mode\n *\n * Ensures consistent dark mode theming in Tailwind CSS classes.\n * - Error: When some color classes have dark: variants but others don't within the same element\n * - Warning: When Tailwind color classes are used in a file but no dark: theming exists\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"inconsistentDarkMode\" | \"missingDarkMode\";\ntype Options = [\n {\n /** Whether to warn when no dark mode classes are found in a file that uses Tailwind colors. Default: true */\n warnOnMissingDarkMode?: boolean;\n }?\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"consistent-dark-mode\",\n name: \"Consistent Dark Mode\",\n description: \"Ensure consistent dark: theming (error on mix, warn on missing)\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ warnOnMissingDarkMode: true }],\n optionSchema: {\n fields: [\n {\n key: \"warnOnMissingDarkMode\",\n label: \"Warn when elements lack dark: variant\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Enable warnings for elements missing dark mode variants\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects inconsistent dark mode theming in Tailwind CSS classes. Reports errors when\nsome color classes in an element have \\`dark:\\` variants but others don't, and optionally\nwarns when a file uses color classes without any dark mode theming.\n\n## Why it's useful\n\n- **Prevents broken dark mode**: Catches cases where some colors change in dark mode but others don't\n- **Encourages completeness**: Prompts you to add dark mode support where it's missing\n- **No false positives**: Only flags explicit Tailwind colors, not custom/CSS variable colors\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Some colors have dark variants, others don't\n<div className=\"bg-white dark:bg-slate-900 text-black\">\n// ^^^^^^^^^ missing dark: variant\n\n// Mix of themed and unthemed\n<button className=\"bg-blue-500 dark:bg-blue-600 border-gray-300\">\n// ^^^^^^^^^^^^^^^ missing dark: variant\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// All color classes have dark variants\n<div className=\"bg-white dark:bg-slate-900 text-black dark:text-white\">\n\n// Using semantic/custom colors (automatically themed via CSS variables)\n<div className=\"bg-background text-foreground\">\n<div className=\"bg-brand text-brand-foreground\">\n<div className=\"bg-primary text-primary-foreground\">\n\n// Consistent theming\n<button className=\"bg-blue-500 dark:bg-blue-600 border-gray-300 dark:border-gray-600\">\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/consistent-dark-mode\": [\"error\", {\n warnOnMissingDarkMode: true // Warn if file uses colors without any dark mode\n}]\n\\`\\`\\`\n\n## Notes\n\n- Only explicit Tailwind colors (like \\`blue-500\\`, \\`white\\`, \\`slate-900\\`) require dark variants\n- Custom/semantic colors (\\`background\\`, \\`foreground\\`, \\`brand\\`, \\`primary\\`, etc.) are exempt\n- These are assumed to be CSS variables that handle dark mode automatically\n- Transparent, inherit, and current values are exempt\n- Non-color utilities (like \\`text-lg\\`, \\`border-2\\`) are correctly ignored\n`,\n});\n\n// Color-related class prefixes that should have dark mode variants\nconst COLOR_PREFIXES = [\n \"bg-\",\n \"text-\",\n \"border-\",\n \"border-t-\",\n \"border-r-\",\n \"border-b-\",\n \"border-l-\",\n \"border-x-\",\n \"border-y-\",\n \"ring-\",\n \"ring-offset-\",\n \"divide-\",\n \"outline-\",\n \"shadow-\",\n \"accent-\",\n \"caret-\",\n \"fill-\",\n \"stroke-\",\n \"decoration-\",\n \"placeholder-\",\n \"from-\",\n \"via-\",\n \"to-\",\n];\n\n// Values that don't need dark variants (colorless or inherited)\nconst EXEMPT_SUFFIXES = [\"transparent\", \"inherit\", \"current\", \"auto\", \"none\"];\n\n// Built-in Tailwind CSS color palette names\n// These are the ONLY colors that should trigger dark mode warnings.\n// Custom colors (like 'brand', 'company-primary') are assumed to be\n// CSS variables that handle dark mode automatically.\nconst TAILWIND_COLOR_NAMES = new Set([\n // Special colors\n \"white\",\n \"black\",\n // Gray scale palettes\n \"slate\",\n \"gray\",\n \"zinc\",\n \"neutral\",\n \"stone\",\n // Warm colors\n \"red\",\n \"orange\",\n \"amber\",\n \"yellow\",\n // Green colors\n \"lime\",\n \"green\",\n \"emerald\",\n \"teal\",\n // Blue colors\n \"cyan\",\n \"sky\",\n \"blue\",\n \"indigo\",\n // Purple/Pink colors\n \"violet\",\n \"purple\",\n \"fuchsia\",\n \"pink\",\n \"rose\",\n]);\n\n/**\n * Check if a class has 'dark' in its variant chain\n */\nfunction hasDarkVariant(className: string): boolean {\n const parts = className.split(\":\");\n // All parts except the last are variants\n const variants = parts.slice(0, -1);\n return variants.includes(\"dark\");\n}\n\n/**\n * Get the base class (without any variants like hover:, dark:, md:, etc.)\n */\nfunction getBaseClass(className: string): string {\n const parts = className.split(\":\");\n return parts[parts.length - 1] || \"\";\n}\n\n/**\n * Find the color prefix this class uses, if any\n */\nfunction getColorPrefix(baseClass: string): string | null {\n // Sort by length descending to match more specific prefixes first\n // (e.g., \"border-t-\" before \"border-\")\n const sortedPrefixes = [...COLOR_PREFIXES].sort(\n (a, b) => b.length - a.length\n );\n return sortedPrefixes.find((p) => baseClass.startsWith(p)) || null;\n}\n\n/**\n * Check if the value is an explicit Tailwind color.\n * Uses an allowlist approach: only built-in Tailwind color names trigger warnings.\n * Custom colors (like 'brand', 'primary', 'company-blue') are assumed to be\n * CSS variables that handle dark mode automatically and should NOT trigger.\n *\n * Matches patterns like:\n * - white, black (standalone colors)\n * - blue-500, slate-900 (color-scale)\n * - blue-500/50, gray-900/80 (with opacity modifier)\n */\nfunction isTailwindColor(value: string): boolean {\n // Remove opacity modifier if present (e.g., \"blue-500/50\" -> \"blue-500\")\n const valueWithoutOpacity = value.split(\"/\")[0] || value;\n\n // Check for standalone colors (white, black)\n if (TAILWIND_COLOR_NAMES.has(valueWithoutOpacity)) {\n return true;\n }\n\n // Check for color-scale pattern (e.g., \"blue-500\", \"slate-900\")\n // Pattern: colorName-number where number is 50, 100, 200, ..., 950\n const match = valueWithoutOpacity.match(/^([a-z]+)-(\\d+)$/);\n if (match) {\n const colorName = match[1];\n const scale = match[2];\n // Valid Tailwind scales are: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950\n const validScales = [\n \"50\",\n \"100\",\n \"200\",\n \"300\",\n \"400\",\n \"500\",\n \"600\",\n \"700\",\n \"800\",\n \"900\",\n \"950\",\n ];\n if (colorName && TAILWIND_COLOR_NAMES.has(colorName) && validScales.includes(scale || \"\")) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the value after the prefix looks like an explicit Tailwind color.\n * Uses allowlist approach: only built-in Tailwind colors should trigger dark mode warnings.\n * Custom/semantic colors (brand, primary, foreground, etc.) are NOT flagged.\n */\nfunction isColorValue(baseClass: string, prefix: string): boolean {\n const value = baseClass.slice(prefix.length);\n\n // Empty value is not a color\n if (!value) {\n return false;\n }\n\n // Only flag explicit Tailwind colors\n // Custom colors, CSS variable colors, and semantic colors are exempt\n return isTailwindColor(value);\n}\n\n/**\n * Check if a class is exempt from dark mode requirements\n */\nfunction isExempt(baseClass: string): boolean {\n return EXEMPT_SUFFIXES.some((suffix) => baseClass.endsWith(suffix));\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"consistent-dark-mode\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Ensure consistent dark mode theming in Tailwind classes\",\n },\n messages: {\n inconsistentDarkMode:\n \"Inconsistent dark mode: '{{unthemed}}' lack dark: variants while other color classes have them.\",\n missingDarkMode:\n \"No dark mode theming detected. Consider adding dark: variants for color classes.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n warnOnMissingDarkMode: {\n type: \"boolean\",\n description:\n \"Whether to warn when no dark mode classes are found in a file that uses Tailwind colors\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ warnOnMissingDarkMode: true }],\n create(context) {\n const options = context.options[0] || {};\n const warnOnMissingDarkMode = options.warnOnMissingDarkMode ?? true;\n\n let fileHasColorClasses = false;\n let fileHasDarkMode = false;\n const reportedNodes = new Set<TSESTree.Node>();\n\n function checkClassString(node: TSESTree.Node, classString: string) {\n const classes = classString.split(/\\s+/).filter(Boolean);\n if (classes.length === 0) return;\n\n // Track usage per color prefix: { hasLight, hasDark, lightClasses }\n const prefixUsage = new Map<\n string,\n { hasLight: boolean; hasDark: boolean; lightClasses: string[] }\n >();\n\n for (const cls of classes) {\n const baseClass = getBaseClass(cls);\n const prefix = getColorPrefix(baseClass);\n\n if (!prefix) continue;\n if (isExempt(baseClass)) continue;\n\n // Verify this is actually a color class, not something like text-lg\n if (!isColorValue(baseClass, prefix)) continue;\n\n if (!prefixUsage.has(prefix)) {\n prefixUsage.set(prefix, {\n hasLight: false,\n hasDark: false,\n lightClasses: [],\n });\n }\n\n const usage = prefixUsage.get(prefix)!;\n\n if (hasDarkVariant(cls)) {\n usage.hasDark = true;\n fileHasDarkMode = true;\n } else {\n usage.hasLight = true;\n usage.lightClasses.push(cls);\n }\n }\n\n // Track if file uses color classes\n if (prefixUsage.size > 0) {\n fileHasColorClasses = true;\n }\n\n // Check for inconsistency: some prefixes have dark variants, others don't\n const entries = Array.from(prefixUsage.entries());\n const hasSomeDark = entries.some(([_, u]) => u.hasDark);\n\n if (hasSomeDark) {\n const unthemedEntries = entries.filter(\n ([_, usage]) => usage.hasLight && !usage.hasDark\n );\n\n if (unthemedEntries.length > 0 && !reportedNodes.has(node)) {\n reportedNodes.add(node);\n // Collect the actual class names that lack dark variants\n const unthemedClasses = unthemedEntries.flatMap(\n ([_, u]) => u.lightClasses\n );\n\n context.report({\n node,\n messageId: \"inconsistentDarkMode\",\n data: { unthemed: unthemedClasses.join(\", \") },\n });\n }\n }\n }\n\n function processStringValue(node: TSESTree.Node, value: string) {\n checkClassString(node, value);\n }\n\n function processTemplateLiteral(node: TSESTree.TemplateLiteral) {\n for (const quasi of node.quasis) {\n checkClassString(quasi, quasi.value.raw);\n }\n }\n\n return {\n // Check className attributes in JSX\n JSXAttribute(node) {\n if (\n node.name.type === \"JSXIdentifier\" &&\n (node.name.name === \"className\" || node.name.name === \"class\")\n ) {\n const value = node.value;\n\n // Handle string literal: className=\"...\"\n if (value?.type === \"Literal\" && typeof value.value === \"string\") {\n processStringValue(value, value.value);\n }\n\n // Handle JSX expression: className={...}\n if (value?.type === \"JSXExpressionContainer\") {\n const expr = value.expression;\n\n // Direct string: className={\"...\"}\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n processStringValue(expr, expr.value);\n }\n\n // Template literal: className={`...`}\n if (expr.type === \"TemplateLiteral\") {\n processTemplateLiteral(expr);\n }\n }\n }\n },\n\n // Check cn(), clsx(), classnames(), cva() calls\n CallExpression(node) {\n if (node.callee.type !== \"Identifier\") return;\n const name = node.callee.name;\n\n if (\n name === \"cn\" ||\n name === \"clsx\" ||\n name === \"classnames\" ||\n name === \"cva\" ||\n name === \"twMerge\"\n ) {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n processStringValue(arg, arg.value);\n }\n if (arg.type === \"TemplateLiteral\") {\n processTemplateLiteral(arg);\n }\n // Handle arrays of class strings\n if (arg.type === \"ArrayExpression\") {\n for (const element of arg.elements) {\n if (\n element?.type === \"Literal\" &&\n typeof element.value === \"string\"\n ) {\n processStringValue(element, element.value);\n }\n if (element?.type === \"TemplateLiteral\") {\n processTemplateLiteral(element);\n }\n }\n }\n }\n }\n },\n\n // At the end of the file, check if Tailwind colors are used without any dark mode\n \"Program:exit\"(node) {\n if (warnOnMissingDarkMode && fileHasColorClasses && !fileHasDarkMode) {\n context.report({\n node,\n messageId: \"missingDarkMode\",\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: no-direct-store-import\n *\n * Forbids direct Zustand store imports - prefer using hooks via context.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"noDirectImport\";\ntype Options = [\n {\n storePattern?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-direct-store-import\",\n name: \"No Direct Store Import\",\n description: \"Forbid direct Zustand store imports (use context hooks)\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ storePattern: \"use*Store\" }],\n optionSchema: {\n fields: [\n {\n key: \"storePattern\",\n label: \"Glob pattern for store files\",\n type: \"text\",\n defaultValue: \"use*Store\",\n placeholder: \"use*Store\",\n description: \"Pattern to match store file names\",\n },\n ],\n },\n docs: `\n## What it does\n\nPrevents direct imports of Zustand stores, encouraging the use of context-based hooks\nfor better dependency injection and testability.\n\n## Why it's useful\n\n- **Testability**: Context-based access allows easy mocking in tests\n- **Flexibility**: Store implementation can change without updating all consumers\n- **Dependency Injection**: Stores can be provided at different levels of the component tree\n- **Server Components**: Helps avoid accidentally importing stores in server components\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Directly importing the store\nimport { useAuthStore } from '../stores/auth-store';\nimport { useCartStore } from '@/stores/useCartStore';\n\nfunction MyComponent() {\n const user = useAuthStore((s) => s.user);\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using context-provided hooks\nimport { useAuth } from '../contexts/auth-context';\nimport { useCart } from '@/hooks/useCart';\n\nfunction MyComponent() {\n const { user } = useAuth();\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-direct-store-import\": [\"warn\", {\n storePattern: \"use*Store\" // Pattern to match store names\n}]\n\\`\\`\\`\n\n## Notes\n\n- The pattern uses glob syntax (\\`*\\` matches any characters)\n- Only triggers for imports from paths containing \"store\"\n- Works with both named and default imports\n`,\n});\n\n// Convert glob pattern to regex\nfunction patternToRegex(pattern: string): RegExp {\n const escaped = pattern\n .replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(/\\*/g, \".*\")\n .replace(/\\?/g, \".\");\n return new RegExp(`^${escaped}$`);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-direct-store-import\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Forbid direct Zustand store imports (use hooks via context)\",\n },\n messages: {\n noDirectImport:\n \"Avoid importing store '{{name}}' directly. Use the store via a context hook instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n storePattern: {\n type: \"string\",\n description: \"Glob pattern for store names\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ storePattern: \"use*Store\" }],\n create(context) {\n const options = context.options[0] || {};\n const pattern = options.storePattern || \"use*Store\";\n const regex = patternToRegex(pattern);\n\n return {\n ImportDeclaration(node) {\n // Check if importing from a store file\n const source = node.source.value as string;\n if (!source.includes(\"store\")) return;\n\n // Check imported specifiers\n for (const specifier of node.specifiers) {\n if (specifier.type === \"ImportSpecifier\") {\n const importedName =\n specifier.imported.type === \"Identifier\"\n ? specifier.imported.name\n : specifier.imported.value;\n\n if (regex.test(importedName)) {\n context.report({\n node: specifier,\n messageId: \"noDirectImport\",\n data: { name: importedName },\n });\n }\n }\n\n if (specifier.type === \"ImportDefaultSpecifier\") {\n const localName = specifier.local.name;\n if (regex.test(localName)) {\n context.report({\n node: specifier,\n messageId: \"noDirectImport\",\n data: { name: localName },\n });\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: prefer-zustand-state-management\n *\n * Detects excessive use of React state hooks (useState, useReducer, useContext)\n * in components and suggests using Zustand stores for better state management.\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"excessiveStateHooks\";\ntype Options = [\n {\n /** Maximum number of state hooks before warning. Default: 3 */\n maxStateHooks?: number;\n /** Whether to count useState calls. Default: true */\n countUseState?: boolean;\n /** Whether to count useReducer calls. Default: true */\n countUseReducer?: boolean;\n /** Whether to count useContext calls. Default: true */\n countUseContext?: boolean;\n }?\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"prefer-zustand-state-management\",\n name: \"Prefer Zustand State Management\",\n description: \"Detect excessive useState/useReducer/useContext; suggest Zustand\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n maxStateHooks: 3,\n countUseState: true,\n countUseReducer: true,\n countUseContext: true,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"maxStateHooks\",\n label: \"Max state hooks before warning\",\n type: \"number\",\n defaultValue: 3,\n placeholder: \"3\",\n description: \"Maximum number of state hooks allowed before warning\",\n },\n {\n key: \"countUseState\",\n label: \"Count useState hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n {\n key: \"countUseReducer\",\n label: \"Count useReducer hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n {\n key: \"countUseContext\",\n label: \"Count useContext hooks\",\n type: \"boolean\",\n defaultValue: true,\n },\n ],\n },\n docs: `\n## What it does\n\nDetects components that use many React state hooks (\\`useState\\`, \\`useReducer\\`, \\`useContext\\`)\nand suggests consolidating state into a Zustand store for better maintainability.\n\n## Why it's useful\n\n- **Simplifies components**: Fewer hooks means less cognitive overhead\n- **Centralizes state**: Related state lives together in a store\n- **Better performance**: Zustand's selector pattern prevents unnecessary re-renders\n- **Easier testing**: Store logic can be tested independently of components\n\n## Examples\n\n### ❌ Incorrect (with default maxStateHooks: 3)\n\n\\`\\`\\`tsx\nfunction UserProfile() {\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [avatar, setAvatar] = useState(null);\n const [isLoading, setIsLoading] = useState(false); // 4 hooks = warning\n // ...\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using a Zustand store\nconst useUserStore = create((set) => ({\n name: '',\n email: '',\n avatar: null,\n isLoading: false,\n setName: (name) => set({ name }),\n // ...\n}));\n\nfunction UserProfile() {\n const { name, email, avatar, isLoading } = useUserStore();\n // Much cleaner!\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/prefer-zustand-state-management\": [\"warn\", {\n maxStateHooks: 3, // Warn when exceeding this count\n countUseState: true, // Include useState in count\n countUseReducer: true, // Include useReducer in count\n countUseContext: true // Include useContext in count\n}]\n\\`\\`\\`\n\n## Notes\n\n- Custom hooks (starting with \\`use\\` lowercase) are exempt from this rule\n- Only counts hooks at the top level of the component, not in nested functions\n- Adjust \\`maxStateHooks\\` based on your team's preferences\n`,\n});\n\ninterface ComponentInfo {\n name: string;\n node: TSESTree.Node;\n hookCount: number;\n functionNode:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression;\n}\n\nconst STATE_HOOKS = new Set([\"useState\", \"useReducer\", \"useContext\"]);\n\nexport default createRule<Options, MessageIds>({\n name: \"prefer-zustand-state-management\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Detect excessive use of React state hooks and suggest Zustand stores\",\n },\n messages: {\n excessiveStateHooks:\n \"Component '{{component}}' has {{count}} state hooks (max: {{max}}). Consider using a Zustand store for state management.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxStateHooks: {\n type: \"number\",\n minimum: 1,\n description: \"Maximum number of state hooks before warning\",\n },\n countUseState: {\n type: \"boolean\",\n description: \"Whether to count useState calls\",\n },\n countUseReducer: {\n type: \"boolean\",\n description: \"Whether to count useReducer calls\",\n },\n countUseContext: {\n type: \"boolean\",\n description: \"Whether to count useContext calls\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxStateHooks: 3,\n countUseState: true,\n countUseReducer: true,\n countUseContext: true,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxStateHooks = options.maxStateHooks ?? 3;\n const countUseState = options.countUseState ?? true;\n const countUseReducer = options.countUseReducer ?? true;\n const countUseContext = options.countUseContext ?? true;\n\n // Stack to track current component context\n const componentStack: ComponentInfo[] = [];\n\n // Set of function nodes we've identified as components to check\n const componentFunctions = new Map<TSESTree.Node, ComponentInfo>();\n\n /**\n * Check if a function name indicates a React component (PascalCase)\n */\n function isComponentName(name: string | null | undefined): boolean {\n if (!name) return false;\n // Components start with uppercase, hooks start with lowercase \"use\"\n return /^[A-Z]/.test(name);\n }\n\n /**\n * Check if a function name indicates a custom hook (starts with \"use\")\n */\n function isCustomHookName(name: string | null | undefined): boolean {\n if (!name) return false;\n return /^use[A-Z]/.test(name);\n }\n\n /**\n * Get the name of a function from various declaration patterns\n */\n function getFunctionName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ): string | null {\n // Function declaration: function MyComponent() {}\n if (node.type === \"FunctionDeclaration\" && node.id) {\n return node.id.name;\n }\n\n // Check parent for variable declaration: const MyComponent = () => {}\n const parent = node.parent;\n\n if (\n parent?.type === \"VariableDeclarator\" &&\n parent.id.type === \"Identifier\"\n ) {\n return parent.id.name;\n }\n\n // Check for forwardRef/memo: const MyComponent = forwardRef(function MyComponent() {})\n // or const MyComponent = forwardRef(() => {})\n if (parent?.type === \"CallExpression\") {\n const callParent = parent.parent;\n if (\n callParent?.type === \"VariableDeclarator\" &&\n callParent.id.type === \"Identifier\"\n ) {\n return callParent.id.name;\n }\n }\n\n // Named function expression: const x = function MyComponent() {}\n if (node.type === \"FunctionExpression\" && node.id) {\n return node.id.name;\n }\n\n return null;\n }\n\n /**\n * Check if a hook call should be counted based on options\n */\n function shouldCountHook(hookName: string): boolean {\n switch (hookName) {\n case \"useState\":\n return countUseState;\n case \"useReducer\":\n return countUseReducer;\n case \"useContext\":\n return countUseContext;\n default:\n return false;\n }\n }\n\n /**\n * Get hook name from a call expression (handles both useState and React.useState)\n */\n function getHookName(callee: TSESTree.Expression): string | null {\n // Direct call: useState()\n if (callee.type === \"Identifier\" && STATE_HOOKS.has(callee.name)) {\n return callee.name;\n }\n\n // Member expression: React.useState()\n if (\n callee.type === \"MemberExpression\" &&\n callee.object.type === \"Identifier\" &&\n callee.object.name === \"React\" &&\n callee.property.type === \"Identifier\" &&\n STATE_HOOKS.has(callee.property.name)\n ) {\n return callee.property.name;\n }\n\n return null;\n }\n\n /**\n * Check if we're directly inside a component function (not in a nested function)\n */\n function isDirectChildOfComponent(\n node: TSESTree.Node,\n componentNode: TSESTree.Node\n ): boolean {\n let current: TSESTree.Node | undefined = node.parent;\n\n while (current) {\n // If we hit the component node, we're a direct child\n if (current === componentNode) {\n return true;\n }\n\n // If we hit another function first, we're nested\n if (\n current.type === \"FunctionDeclaration\" ||\n current.type === \"FunctionExpression\" ||\n current.type === \"ArrowFunctionExpression\"\n ) {\n return false;\n }\n\n current = current.parent;\n }\n\n return false;\n }\n\n /**\n * Enter a function that might be a component\n */\n function enterFunction(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ) {\n const name = getFunctionName(node);\n\n // Skip custom hooks - they're allowed to have many state hooks\n if (isCustomHookName(name)) {\n return;\n }\n\n // Skip non-component functions (lowercase names that aren't anonymous)\n if (name && !isComponentName(name)) {\n return;\n }\n\n // Track this as a potential component\n const componentInfo: ComponentInfo = {\n name: name || \"AnonymousComponent\",\n node,\n hookCount: 0,\n functionNode: node,\n };\n\n componentStack.push(componentInfo);\n componentFunctions.set(node, componentInfo);\n }\n\n /**\n * Exit a function and report if it had too many hooks\n */\n function exitFunction(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.FunctionExpression\n | TSESTree.ArrowFunctionExpression\n ) {\n const componentInfo = componentFunctions.get(node);\n\n if (!componentInfo) {\n return;\n }\n\n // Remove from stack\n const index = componentStack.findIndex((c) => c.functionNode === node);\n if (index !== -1) {\n componentStack.splice(index, 1);\n }\n\n // Check if exceeded threshold\n if (componentInfo.hookCount > maxStateHooks) {\n context.report({\n node: componentInfo.node,\n messageId: \"excessiveStateHooks\",\n data: {\n component: componentInfo.name,\n count: componentInfo.hookCount,\n max: maxStateHooks,\n },\n });\n }\n\n componentFunctions.delete(node);\n }\n\n return {\n FunctionDeclaration: enterFunction,\n FunctionExpression: enterFunction,\n ArrowFunctionExpression: enterFunction,\n \"FunctionDeclaration:exit\": exitFunction,\n \"FunctionExpression:exit\": exitFunction,\n \"ArrowFunctionExpression:exit\": exitFunction,\n\n CallExpression(node) {\n const hookName = getHookName(node.callee);\n\n if (!hookName || !shouldCountHook(hookName)) {\n return;\n }\n\n // Find the innermost component this hook belongs to\n // We iterate from the end to find the most recent (innermost) component\n for (let i = componentStack.length - 1; i >= 0; i--) {\n const component = componentStack[i];\n\n if (isDirectChildOfComponent(node, component.functionNode)) {\n component.hookCount++;\n break;\n }\n }\n },\n };\n },\n});\n","/**\n * Export Resolver\n *\n * Resolves import paths and finds export definitions, following re-exports\n * to their original source files.\n */\n\nimport { ResolverFactory } from \"oxc-resolver\";\nimport { parse } from \"@typescript-eslint/typescript-estree\";\nimport { readFileSync, existsSync } from \"fs\";\nimport { dirname, join, extname } from \"path\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\n// Module-level resolver instance (reused across calls)\nlet resolverInstance: ReturnType<typeof ResolverFactory.prototype.sync> | null =\n null;\nlet resolverFactory: ResolverFactory | null = null;\n\n/**\n * Information about a resolved export\n */\nexport interface ResolvedExport {\n /** The name of the export (e.g., \"Button\") */\n name: string;\n /** Absolute path to the file containing the actual definition */\n filePath: string;\n /** The local name in the source file (may differ from export name) */\n localName: string;\n /** Whether this is a re-export (export { X } from './other') */\n isReexport: boolean;\n}\n\n/**\n * Cache for file exports to avoid re-parsing\n */\nconst exportCache = new Map<\n string,\n Map<string, { localName: string; reexportSource?: string }>\n>();\n\n/**\n * Cache for parsed ASTs\n */\nconst astCache = new Map<string, TSESTree.Program>();\n\n/**\n * Cache for resolved paths\n */\nconst resolvedPathCache = new Map<string, string | null>();\n\n/**\n * Get or create the resolver factory\n */\nfunction getResolverFactory(): ResolverFactory {\n if (!resolverFactory) {\n resolverFactory = new ResolverFactory({\n extensions: [\".tsx\", \".ts\", \".jsx\", \".js\"],\n mainFields: [\"module\", \"main\"],\n conditionNames: [\"import\", \"require\", \"node\", \"default\"],\n // Enable TypeScript path resolution\n tsconfig: {\n configFile: \"tsconfig.json\",\n references: \"auto\",\n },\n });\n }\n return resolverFactory;\n}\n\n/**\n * Resolve an import path to an absolute file path\n */\nexport function resolveImportPath(\n importSource: string,\n fromFile: string\n): string | null {\n const cacheKey = `${fromFile}::${importSource}`;\n\n if (resolvedPathCache.has(cacheKey)) {\n return resolvedPathCache.get(cacheKey) ?? null;\n }\n\n // Skip node_modules\n if (\n importSource.startsWith(\"react\") ||\n importSource.startsWith(\"next\") ||\n (!importSource.startsWith(\".\") &&\n !importSource.startsWith(\"@/\") &&\n !importSource.startsWith(\"~/\"))\n ) {\n // Check if it's a known external package\n if (\n importSource.includes(\"@mui/\") ||\n importSource.includes(\"@chakra-ui/\") ||\n importSource.includes(\"antd\") ||\n importSource.includes(\"@radix-ui/\")\n ) {\n // Return a marker for external packages - we don't resolve them but track them\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n resolvedPathCache.set(cacheKey, null);\n return null;\n }\n\n try {\n const factory = getResolverFactory();\n const fromDir = dirname(fromFile);\n const result = factory.sync(fromDir, importSource);\n\n if (result.path) {\n resolvedPathCache.set(cacheKey, result.path);\n return result.path;\n }\n } catch {\n // Fallback: try manual resolution for common patterns\n const resolved = manualResolve(importSource, fromFile);\n resolvedPathCache.set(cacheKey, resolved);\n return resolved;\n }\n\n resolvedPathCache.set(cacheKey, null);\n return null;\n}\n\n/**\n * Manual fallback resolution for common patterns\n */\nfunction manualResolve(importSource: string, fromFile: string): string | null {\n const fromDir = dirname(fromFile);\n const extensions = [\".tsx\", \".ts\", \".jsx\", \".js\"];\n\n // Handle @/ alias - find tsconfig and resolve\n if (importSource.startsWith(\"@/\")) {\n const projectRoot = findProjectRoot(fromFile);\n if (projectRoot) {\n const relativePath = importSource.slice(2); // Remove @/\n for (const ext of extensions) {\n const candidate = join(projectRoot, relativePath + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(projectRoot, relativePath, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n }\n\n // Handle relative imports\n if (importSource.startsWith(\".\")) {\n for (const ext of extensions) {\n const candidate = join(fromDir, importSource + ext);\n if (existsSync(candidate)) {\n return candidate;\n }\n // Try index file\n const indexCandidate = join(fromDir, importSource, `index${ext}`);\n if (existsSync(indexCandidate)) {\n return indexCandidate;\n }\n }\n }\n\n return null;\n}\n\n/**\n * Find the project root by looking for tsconfig.json or package.json\n */\nfunction findProjectRoot(fromFile: string): string | null {\n let dir = dirname(fromFile);\n const root = \"/\";\n\n while (dir !== root) {\n if (existsSync(join(dir, \"tsconfig.json\"))) {\n return dir;\n }\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n dir = dirname(dir);\n }\n\n return null;\n}\n\n/**\n * Parse a file and cache the AST\n */\nexport function parseFile(filePath: string): TSESTree.Program | null {\n if (astCache.has(filePath)) {\n return astCache.get(filePath)!;\n }\n\n try {\n const content = readFileSync(filePath, \"utf-8\");\n const ast = parse(content, {\n jsx: true,\n loc: true,\n range: true,\n });\n astCache.set(filePath, ast);\n return ast;\n } catch {\n return null;\n }\n}\n\n/**\n * Extract export information from a file\n */\nfunction extractExports(\n filePath: string\n): Map<string, { localName: string; reexportSource?: string }> {\n if (exportCache.has(filePath)) {\n return exportCache.get(filePath)!;\n }\n\n const exports = new Map<\n string,\n { localName: string; reexportSource?: string }\n >();\n const ast = parseFile(filePath);\n\n if (!ast) {\n exportCache.set(filePath, exports);\n return exports;\n }\n\n for (const node of ast.body) {\n // Handle: export function Button() {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(node.declaration.id.name, {\n localName: node.declaration.id.name,\n });\n }\n\n // Handle: export const Button = () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (decl.id.type === \"Identifier\") {\n exports.set(decl.id.name, { localName: decl.id.name });\n }\n }\n }\n\n // Handle: export { Button } or export { Button as Btn }\n if (node.type === \"ExportNamedDeclaration\" && node.specifiers.length > 0) {\n const source = node.source?.value as string | undefined;\n for (const spec of node.specifiers) {\n if (spec.type === \"ExportSpecifier\") {\n const exportedName =\n spec.exported.type === \"Identifier\"\n ? spec.exported.name\n : spec.exported.value;\n const localName =\n spec.local.type === \"Identifier\"\n ? spec.local.name\n : spec.local.value;\n\n exports.set(exportedName, {\n localName,\n reexportSource: source,\n });\n }\n }\n }\n\n // Handle: export default function Button() {}\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n exports.set(\"default\", { localName: node.declaration.id.name });\n }\n\n // Handle: export default Button\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"Identifier\"\n ) {\n exports.set(\"default\", { localName: node.declaration.name });\n }\n }\n\n exportCache.set(filePath, exports);\n return exports;\n}\n\n/**\n * Resolve an export to its original definition, following re-exports\n */\nexport function resolveExport(\n exportName: string,\n filePath: string,\n visited = new Set<string>()\n): ResolvedExport | null {\n // Cycle detection\n const key = `${filePath}::${exportName}`;\n if (visited.has(key)) {\n return null;\n }\n visited.add(key);\n\n const exports = extractExports(filePath);\n const exportInfo = exports.get(exportName);\n\n if (!exportInfo) {\n return null;\n }\n\n // If it's a re-export, follow the chain\n if (exportInfo.reexportSource) {\n const resolvedPath = resolveImportPath(exportInfo.reexportSource, filePath);\n if (resolvedPath) {\n return resolveExport(exportInfo.localName, resolvedPath, visited);\n }\n return null;\n }\n\n // This is the actual definition\n return {\n name: exportName,\n filePath,\n localName: exportInfo.localName,\n isReexport: false,\n };\n}\n\n/**\n * Clear all caches (useful for testing or watch mode)\n */\nexport function clearResolverCaches(): void {\n exportCache.clear();\n astCache.clear();\n resolvedPathCache.clear();\n}\n","/**\n * Component Parser\n *\n * Parses a single component's body to extract styling information\n * and identify nested component usage.\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { parseFile } from \"./export-resolver.js\";\n\n/**\n * Known UI library import patterns\n */\nexport type LibraryName = \"shadcn\" | \"mui\" | \"chakra\" | \"antd\";\n\nexport const LIBRARY_PATTERNS: Record<LibraryName, string[]> = {\n shadcn: [\"@/components/ui\", \"@radix-ui/\", \"components/ui/\"],\n mui: [\"@mui/material\", \"@mui/icons-material\", \"@emotion/\"],\n chakra: [\"@chakra-ui/\"],\n antd: [\"antd\", \"@ant-design/\"],\n};\n\n/**\n * Information about a component used within another component\n */\nexport interface UsedComponent {\n /** Component name (e.g., \"Button\", \"Card\") */\n name: string;\n /** Import source path (e.g., \"@mui/material\", \"./button\") */\n importSource: string;\n /** Line number where the component is used */\n line: number;\n /** Column number where the component is used */\n column: number;\n}\n\n/**\n * Styling information extracted from a component\n */\nexport interface ComponentStyleInfo {\n /** Tailwind classes used in the component */\n tailwindClasses: string[];\n /** Inline style objects (as string representations) */\n inlineStyles: string[];\n /** Other components used within this component */\n usedComponents: UsedComponent[];\n /** Directly detected library (from import source) */\n directLibrary: LibraryName | null;\n}\n\n/**\n * Import map for a file: localName -> importSource\n */\nexport type ImportMap = Map<string, string>;\n\n/**\n * Extract imports from a file's AST\n */\nexport function extractImports(ast: TSESTree.Program): ImportMap {\n const imports = new Map<string, string>();\n\n for (const node of ast.body) {\n if (node.type === \"ImportDeclaration\") {\n const source = node.source.value as string;\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\") {\n imports.set(spec.local.name, source);\n } else if (spec.type === \"ImportDefaultSpecifier\") {\n imports.set(spec.local.name, source);\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n imports.set(spec.local.name, source);\n }\n }\n }\n }\n\n return imports;\n}\n\n/**\n * Detect which UI library an import source belongs to\n */\nexport function detectLibraryFromSource(\n importSource: string\n): LibraryName | null {\n for (const [library, patterns] of Object.entries(LIBRARY_PATTERNS)) {\n if (patterns.some((p) => importSource.includes(p))) {\n return library as LibraryName;\n }\n }\n return null;\n}\n\n/**\n * Find a function/arrow function component definition by name in an AST\n */\nexport function findComponentDefinition(\n ast: TSESTree.Program,\n componentName: string\n): TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression | null {\n for (const node of ast.body) {\n // export function ComponentName() {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id?.name === componentName\n ) {\n return node.declaration;\n }\n\n // export const ComponentName = () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (\n decl.id.type === \"Identifier\" &&\n decl.id.name === componentName &&\n decl.init?.type === \"ArrowFunctionExpression\"\n ) {\n return decl.init;\n }\n }\n }\n\n // function ComponentName() {} (not exported directly)\n if (\n node.type === \"FunctionDeclaration\" &&\n node.id?.name === componentName\n ) {\n return node;\n }\n\n // const ComponentName = () => {}\n if (node.type === \"VariableDeclaration\") {\n for (const decl of node.declarations) {\n if (\n decl.id.type === \"Identifier\" &&\n decl.id.name === componentName &&\n decl.init?.type === \"ArrowFunctionExpression\"\n ) {\n return decl.init;\n }\n }\n }\n\n // export default function ComponentName() {}\n if (\n node.type === \"ExportDefaultDeclaration\" &&\n node.declaration.type === \"FunctionDeclaration\" &&\n node.declaration.id?.name === componentName\n ) {\n return node.declaration;\n }\n }\n\n return null;\n}\n\n/**\n * Extract Tailwind classes from a className string\n */\nfunction extractTailwindClasses(classString: string): string[] {\n return classString.split(/\\s+/).filter(Boolean);\n}\n\n/**\n * Recursively traverse a node and extract styling info\n */\nfunction traverseForStyling(\n node: TSESTree.Node,\n imports: ImportMap,\n result: ComponentStyleInfo\n): void {\n if (!node || typeof node !== \"object\") return;\n\n // Handle JSX elements\n if (node.type === \"JSXElement\" && node.openingElement) {\n const opening = node.openingElement;\n\n // Check if this is a component (PascalCase) or HTML element\n if (\n opening.name.type === \"JSXIdentifier\" &&\n /^[A-Z]/.test(opening.name.name)\n ) {\n const componentName = opening.name.name;\n const importSource = imports.get(componentName);\n\n if (importSource) {\n result.usedComponents.push({\n name: componentName,\n importSource,\n line: opening.loc.start.line,\n column: opening.loc.start.column,\n });\n\n // Check if this import is from a known UI library\n const library = detectLibraryFromSource(importSource);\n if (library && !result.directLibrary) {\n result.directLibrary = library;\n }\n }\n }\n\n // Handle JSX member expressions like Modal.Header\n if (opening.name.type === \"JSXMemberExpression\") {\n let objectName: string | null = null;\n let current = opening.name.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n if (current.type === \"JSXIdentifier\") {\n objectName = current.name;\n }\n\n if (objectName) {\n const importSource = imports.get(objectName);\n if (importSource) {\n const library = detectLibraryFromSource(importSource);\n if (library && !result.directLibrary) {\n result.directLibrary = library;\n }\n }\n }\n }\n\n // Extract className/class attributes\n for (const attr of opening.attributes) {\n if (\n attr.type === \"JSXAttribute\" &&\n attr.name.type === \"JSXIdentifier\" &&\n (attr.name.name === \"className\" || attr.name.name === \"class\")\n ) {\n if (\n attr.value?.type === \"Literal\" &&\n typeof attr.value.value === \"string\"\n ) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(attr.value.value)\n );\n }\n if (attr.value?.type === \"JSXExpressionContainer\") {\n const expr = attr.value.expression;\n if (expr.type === \"Literal\" && typeof expr.value === \"string\") {\n result.tailwindClasses.push(...extractTailwindClasses(expr.value));\n }\n if (expr.type === \"TemplateLiteral\") {\n for (const quasi of expr.quasis) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(quasi.value.raw)\n );\n }\n }\n }\n }\n\n // Extract inline styles\n if (\n attr.type === \"JSXAttribute\" &&\n attr.name.type === \"JSXIdentifier\" &&\n attr.name.name === \"style\"\n ) {\n if (attr.value?.type === \"JSXExpressionContainer\") {\n // Just note that there's an inline style - we don't parse the object\n result.inlineStyles.push(\"[inline style]\");\n }\n }\n }\n }\n\n // Handle cn(), clsx(), twMerge() calls\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"Identifier\" &&\n [\"cn\", \"clsx\", \"classnames\", \"twMerge\"].includes(node.callee.name)\n ) {\n for (const arg of node.arguments) {\n if (arg.type === \"Literal\" && typeof arg.value === \"string\") {\n result.tailwindClasses.push(...extractTailwindClasses(arg.value));\n }\n if (arg.type === \"TemplateLiteral\") {\n for (const quasi of arg.quasis) {\n result.tailwindClasses.push(\n ...extractTailwindClasses(quasi.value.raw)\n );\n }\n }\n }\n }\n\n // Recursively traverse all properties\n for (const key of Object.keys(node)) {\n if (key === \"parent\" || key === \"loc\" || key === \"range\") continue;\n\n const child = (node as unknown as Record<string, unknown>)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\") {\n traverseForStyling(item as TSESTree.Node, imports, result);\n }\n }\n } else if (child && typeof child === \"object\") {\n traverseForStyling(child as TSESTree.Node, imports, result);\n }\n }\n}\n\n/**\n * Parse a component's body and extract styling information\n */\nexport function parseComponentBody(\n filePath: string,\n componentName: string\n): ComponentStyleInfo | null {\n const ast = parseFile(filePath);\n if (!ast) return null;\n\n const imports = extractImports(ast);\n const componentDef = findComponentDefinition(ast, componentName);\n\n if (!componentDef) {\n return null;\n }\n\n const result: ComponentStyleInfo = {\n tailwindClasses: [],\n inlineStyles: [],\n usedComponents: [],\n directLibrary: null,\n };\n\n // Traverse the component body\n if (componentDef.body) {\n traverseForStyling(componentDef.body, imports, result);\n }\n\n // Deduplicate classes\n result.tailwindClasses = [...new Set(result.tailwindClasses)];\n\n return result;\n}\n\n/**\n * Analyze a file and extract all component usages with their libraries\n * (used for the entry file analysis)\n */\nexport function analyzeFileImports(\n filePath: string\n): Map<string, { importSource: string; library: LibraryName | null }> {\n const ast = parseFile(filePath);\n if (!ast) return new Map();\n\n const result = new Map<\n string,\n { importSource: string; library: LibraryName | null }\n >();\n const imports = extractImports(ast);\n\n for (const [name, source] of imports) {\n result.set(name, {\n importSource: source,\n library: detectLibraryFromSource(source),\n });\n }\n\n return result;\n}\n","/**\n * Import Graph Service\n *\n * Provides demand-driven cross-file analysis to detect UI library usage\n * across component trees. Uses in-memory caching for performance.\n */\n\nimport {\n resolveImportPath,\n resolveExport,\n clearResolverCaches,\n} from \"./export-resolver.js\";\nimport {\n parseComponentBody,\n detectLibraryFromSource,\n type LibraryName,\n type ComponentStyleInfo,\n} from \"./component-parser.js\";\n\n/**\n * Information about a component's UI library usage\n */\nexport interface ComponentLibraryInfo {\n /** Direct library (from import source, e.g., \"@mui/material\" -> \"mui\") */\n library: LibraryName | null;\n /** Libraries used internally by this component (for local components) */\n internalLibraries: Set<LibraryName>;\n /** Evidence of which internal components caused the library detection */\n libraryEvidence: Array<{\n componentName: string;\n library: LibraryName;\n }>;\n /** Whether this is a local component (resolved from project files) */\n isLocalComponent: boolean;\n}\n\n/**\n * Cache for analyzed components: \"filePath::componentName\" -> ComponentLibraryInfo\n */\nconst componentLibraryCache = new Map<string, ComponentLibraryInfo>();\n\n/**\n * Get a singleton instance of the import graph service\n */\nexport function getImportGraphService() {\n return {\n getComponentLibrary,\n clearCache,\n };\n}\n\n/**\n * Analyze a component's library usage, including transitive dependencies\n *\n * @param contextFilePath - The file where the component is used (for resolving relative imports)\n * @param componentName - The name of the component (e.g., \"Button\", \"MyCard\")\n * @param importSource - The import source (e.g., \"@mui/material\", \"./components/cards\")\n * @returns Library information including direct and transitive library usage\n */\nexport function getComponentLibrary(\n contextFilePath: string,\n componentName: string,\n importSource: string\n): ComponentLibraryInfo {\n // Check if import source directly indicates a known library\n const directLibrary = detectLibraryFromSource(importSource);\n\n if (directLibrary) {\n // It's a direct import from a known library (e.g., @mui/material)\n return {\n library: directLibrary,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: false,\n };\n }\n\n // It's a local component - resolve and analyze it\n const resolvedPath = resolveImportPath(importSource, contextFilePath);\n\n if (!resolvedPath) {\n // Could not resolve - might be external or invalid\n return {\n library: null,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: false,\n };\n }\n\n // Check cache\n const cacheKey = `${resolvedPath}::${componentName}`;\n if (componentLibraryCache.has(cacheKey)) {\n return componentLibraryCache.get(cacheKey)!;\n }\n\n // Resolve re-exports to find the actual component definition\n const resolvedExport = resolveExport(componentName, resolvedPath);\n const actualFilePath = resolvedExport?.filePath ?? resolvedPath;\n const actualComponentName = resolvedExport?.localName ?? componentName;\n\n // Analyze the component body\n const result = analyzeComponentLibraries(\n actualFilePath,\n actualComponentName,\n new Set([cacheKey]) // Track visited to prevent cycles\n );\n\n componentLibraryCache.set(cacheKey, result);\n return result;\n}\n\n/**\n * Recursively analyze a component's library usage\n */\nfunction analyzeComponentLibraries(\n filePath: string,\n componentName: string,\n visited: Set<string>\n): ComponentLibraryInfo {\n const styleInfo = parseComponentBody(filePath, componentName);\n\n if (!styleInfo) {\n return {\n library: null,\n internalLibraries: new Set(),\n libraryEvidence: [],\n isLocalComponent: true,\n };\n }\n\n const internalLibraries = new Set<LibraryName>();\n const libraryEvidence: Array<{\n componentName: string;\n library: LibraryName;\n }> = [];\n\n // Check direct library usage within this component\n if (styleInfo.directLibrary) {\n internalLibraries.add(styleInfo.directLibrary);\n }\n\n // Analyze each used component\n for (const usedComponent of styleInfo.usedComponents) {\n const usedLibrary = detectLibraryFromSource(usedComponent.importSource);\n\n if (usedLibrary) {\n // Direct import from a known library\n internalLibraries.add(usedLibrary);\n libraryEvidence.push({\n componentName: usedComponent.name,\n library: usedLibrary,\n });\n } else {\n // It's a local component - recurse into it\n const resolvedPath = resolveImportPath(\n usedComponent.importSource,\n filePath\n );\n\n if (resolvedPath) {\n const cacheKey = `${resolvedPath}::${usedComponent.name}`;\n\n // Skip if already visited (cycle detection)\n if (!visited.has(cacheKey)) {\n visited.add(cacheKey);\n\n // Check cache first\n let nestedInfo: ComponentLibraryInfo;\n if (componentLibraryCache.has(cacheKey)) {\n nestedInfo = componentLibraryCache.get(cacheKey)!;\n } else {\n // Resolve re-exports\n const resolvedExport = resolveExport(\n usedComponent.name,\n resolvedPath\n );\n const actualFilePath = resolvedExport?.filePath ?? resolvedPath;\n const actualComponentName =\n resolvedExport?.localName ?? usedComponent.name;\n\n nestedInfo = analyzeComponentLibraries(\n actualFilePath,\n actualComponentName,\n visited\n );\n componentLibraryCache.set(cacheKey, nestedInfo);\n }\n\n // Aggregate the nested component's libraries\n if (nestedInfo.library) {\n internalLibraries.add(nestedInfo.library);\n libraryEvidence.push({\n componentName: usedComponent.name,\n library: nestedInfo.library,\n });\n }\n\n for (const lib of nestedInfo.internalLibraries) {\n internalLibraries.add(lib);\n }\n\n // Add evidence from nested components\n for (const evidence of nestedInfo.libraryEvidence) {\n libraryEvidence.push({\n componentName: `${usedComponent.name} → ${evidence.componentName}`,\n library: evidence.library,\n });\n }\n }\n }\n }\n }\n\n return {\n library: styleInfo.directLibrary,\n internalLibraries,\n libraryEvidence,\n isLocalComponent: true,\n };\n}\n\n/**\n * Clear all caches (useful for testing or between ESLint runs)\n */\nexport function clearCache(): void {\n componentLibraryCache.clear();\n clearResolverCaches();\n}\n\n// Re-export types for convenience\nexport type { LibraryName };\n","/**\n * Rule: no-mixed-component-libraries\n *\n * Forbids using non-preferred UI component libraries. Reports errors at\n * the JSX usage site, including transitive usage through local components.\n *\n * Examples:\n * - <MuiButton> from @mui/material -> error at <MuiButton> usage\n * - <MyCard> that internally uses MUI -> error at <MyCard> usage\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport {\n getComponentLibrary,\n type LibraryName,\n} from \"../utils/import-graph.js\";\n\ntype MessageIds = \"nonPreferredLibrary\" | \"transitiveNonPreferred\";\ntype Options = [\n {\n /** The preferred UI library. Components from other libraries will be flagged. */\n preferred: LibraryName;\n /** Additional libraries to detect (defaults to common ones) */\n libraries?: LibraryName[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-mixed-component-libraries\",\n name: \"No Mixed Component Libraries\",\n description: \"Forbid mixing component libraries (e.g., shadcn + MUI)\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ preferred: \"shadcn\", libraries: [\"shadcn\", \"mui\"] }],\n optionSchema: {\n fields: [\n {\n key: \"preferred\",\n label: \"Preferred component library\",\n type: \"select\",\n defaultValue: \"shadcn\",\n options: [\n { value: \"shadcn\", label: \"shadcn/ui\" },\n { value: \"mui\", label: \"MUI (Material-UI)\" },\n { value: \"chakra\", label: \"Chakra UI\" },\n { value: \"antd\", label: \"Ant Design\" },\n ],\n description: \"The preferred UI library. Components from other libraries will be flagged.\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects and reports when components from non-preferred UI libraries are used in your codebase.\nThis includes both direct imports and transitive usage through your own components that wrap\nnon-preferred libraries internally.\n\n## Why it's useful\n\n- **Consistency**: Ensures a uniform look and feel across your application\n- **Bundle size**: Prevents accidentally including multiple UI frameworks\n- **Maintenance**: Reduces the number of styling systems to maintain\n- **Migration support**: Helps identify what needs to change when migrating UI libraries\n\n## Examples\n\n### ❌ Incorrect (with preferred: \"shadcn\")\n\n\\`\\`\\`tsx\n// Direct MUI usage\nimport { Button } from '@mui/material';\n<Button>Click me</Button> // Error: Component <Button> is from mui\n\n// Transitive usage through local component\nimport { MyCard } from './components/MyCard'; // MyCard uses MUI internally\n<MyCard /> // Error: Component <MyCard> internally uses mui components\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using the preferred library\nimport { Button } from '@/components/ui/button';\nimport { Card } from '@/components/ui/card';\n\n<Button>Click me</Button>\n<Card>Content</Card>\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-mixed-component-libraries\": [\"error\", {\n preferred: \"shadcn\", // Your preferred library\n libraries: [\"shadcn\", \"mui\", \"chakra\", \"antd\"] // Libraries to detect\n}]\n\\`\\`\\`\n\n## Supported Libraries\n\n- **shadcn**: shadcn/ui components (imports from \\`@/components/ui/\\`)\n- **mui**: Material-UI (\\`@mui/material\\`, \\`@mui/joy\\`)\n- **chakra**: Chakra UI (\\`@chakra-ui/react\\`)\n- **antd**: Ant Design (\\`antd\\`)\n`,\n});\n\n/**\n * Information about a component usage in the file\n */\ninterface ComponentUsage {\n /** The JSX element node (for error reporting) */\n node: TSESTree.JSXOpeningElement;\n /** Component name (e.g., \"Button\", \"MuiCard\") */\n componentName: string;\n /** Import source (e.g., \"@mui/material\", \"./components/cards\") */\n importSource: string;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-mixed-component-libraries\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Forbid using non-preferred UI component libraries. Reports at JSX usage sites, including transitive usage.\",\n },\n messages: {\n nonPreferredLibrary:\n \"Component <{{component}}> is from {{library}}, but {{preferred}} is the preferred library.\",\n transitiveNonPreferred:\n \"Component <{{component}}> internally uses {{libraries}} components ({{internalComponents}}). The preferred library is {{preferred}}.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n preferred: {\n type: \"string\",\n enum: [\"shadcn\", \"mui\", \"chakra\", \"antd\"],\n description: \"The preferred UI library\",\n },\n libraries: {\n type: \"array\",\n items: {\n type: \"string\",\n enum: [\"shadcn\", \"mui\", \"chakra\", \"antd\"],\n },\n description: \"Libraries to detect (defaults to all)\",\n },\n },\n required: [\"preferred\"],\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n { preferred: \"shadcn\", libraries: [\"shadcn\", \"mui\", \"chakra\", \"antd\"] },\n ],\n create(context) {\n const options = context.options[0];\n const preferred = options.preferred;\n\n // Track imports: localName -> importSource\n const importMap = new Map<string, string>();\n\n // Track all component usages for analysis at Program:exit\n const componentUsages: ComponentUsage[] = [];\n\n return {\n ImportDeclaration(node) {\n const source = node.source.value as string;\n\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\") {\n importMap.set(spec.local.name, source);\n } else if (spec.type === \"ImportDefaultSpecifier\") {\n importMap.set(spec.local.name, source);\n } else if (spec.type === \"ImportNamespaceSpecifier\") {\n importMap.set(spec.local.name, source);\n }\n }\n },\n\n JSXOpeningElement(node) {\n // Get the component name\n let componentName: string | null = null;\n\n if (node.name.type === \"JSXIdentifier\") {\n componentName = node.name.name;\n } else if (node.name.type === \"JSXMemberExpression\") {\n // Handle Namespace.Component (e.g., Modal.Header)\n let current = node.name.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n if (current.type === \"JSXIdentifier\") {\n componentName = current.name;\n }\n }\n\n // Skip HTML elements (lowercase) and missing names\n if (!componentName || !/^[A-Z]/.test(componentName)) {\n return;\n }\n\n // Skip components that aren't imported (might be defined in same file)\n const importSource = importMap.get(componentName);\n if (!importSource) {\n return;\n }\n\n componentUsages.push({\n node,\n componentName,\n importSource,\n });\n },\n\n \"Program:exit\"() {\n const filename = context.filename || context.getFilename();\n\n for (const usage of componentUsages) {\n const libraryInfo = getComponentLibrary(\n filename,\n usage.componentName,\n usage.importSource\n );\n\n // Case 1: Direct import from non-preferred library\n if (libraryInfo.library && libraryInfo.library !== preferred) {\n context.report({\n node: usage.node,\n messageId: \"nonPreferredLibrary\",\n data: {\n component: usage.componentName,\n library: libraryInfo.library,\n preferred,\n },\n });\n continue;\n }\n\n // Case 2: Local component that uses non-preferred library internally\n if (\n libraryInfo.isLocalComponent &&\n libraryInfo.internalLibraries.size > 0\n ) {\n const nonPreferredLibs = [...libraryInfo.internalLibraries].filter(\n (lib) => lib !== preferred\n );\n\n if (nonPreferredLibs.length > 0) {\n // Get evidence of which internal components caused the violation\n const internalComponents = libraryInfo.libraryEvidence\n .filter((e) => e.library !== preferred)\n .map((e) => e.componentName)\n .slice(0, 3) // Limit to first 3 for readability\n .join(\", \");\n\n context.report({\n node: usage.node,\n messageId: \"transitiveNonPreferred\",\n data: {\n component: usage.componentName,\n libraries: nonPreferredLibs.join(\", \"),\n internalComponents: internalComponents || \"unknown\",\n preferred,\n },\n });\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: semantic\n *\n * LLM-powered semantic UI analysis using the project's styleguide.\n * This is the only rule that reads .uilint/styleguide.md.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { spawnSync } from \"child_process\";\nimport { dirname, join, relative } from \"path\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport {\n getCacheEntry,\n hashContentSync,\n setCacheEntry,\n type CachedIssue,\n} from \"../utils/cache.js\";\nimport { getStyleguide } from \"../utils/styleguide-loader.js\";\nimport { UILINT_DEFAULT_OLLAMA_MODEL } from \"uilint-core\";\nimport { buildSourceScanPrompt } from \"uilint-core\";\n\ntype MessageIds = \"semanticIssue\" | \"styleguideNotFound\" | \"analysisError\";\ntype Options = [\n {\n model?: string;\n styleguidePath?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"semantic\",\n name: \"Semantic Analysis\",\n description: \"LLM-powered semantic UI analysis using your styleguide\",\n defaultSeverity: \"warn\",\n category: \"semantic\",\n requiresStyleguide: true,\n defaultOptions: [{ model: \"qwen3-coder:30b\", styleguidePath: \".uilint/styleguide.md\" }],\n optionSchema: {\n fields: [\n {\n key: \"model\",\n label: \"Ollama model to use\",\n type: \"text\",\n defaultValue: \"qwen3-coder:30b\",\n placeholder: \"qwen3-coder:30b\",\n description: \"The Ollama model name for semantic analysis\",\n },\n {\n key: \"styleguidePath\",\n label: \"Path to styleguide file\",\n type: \"text\",\n defaultValue: \".uilint/styleguide.md\",\n placeholder: \".uilint/styleguide.md\",\n description: \"Relative path to the styleguide markdown file\",\n },\n ],\n },\n docs: `\n## What it does\n\nUses a local LLM (via Ollama) to analyze your React components against your project's\nstyleguide. It catches semantic issues that pattern-based rules can't detect, like:\n- Using incorrect spacing that doesn't match your design system conventions\n- Inconsistent button styles across similar contexts\n- Missing accessibility patterns defined in your styleguide\n\n## Why it's useful\n\n- **Custom rules**: Enforces your project's unique conventions without writing custom ESLint rules\n- **Context-aware**: Understands component intent, not just syntax\n- **Evolving standards**: Update your styleguide, and the rule adapts automatically\n- **Local & private**: Runs entirely on your machine using Ollama\n\n## Prerequisites\n\n1. **Ollama installed**: \\`brew install ollama\\` or from ollama.ai\n2. **Model pulled**: \\`ollama pull qwen3-coder:30b\\` (or your preferred model)\n3. **Styleguide created**: Create \\`.uilint/styleguide.md\\` describing your conventions\n\n## Example Styleguide\n\n\\`\\`\\`markdown\n# UI Style Guide\n\n## Spacing\n- Use gap-4 for spacing between card elements\n- Use py-2 px-4 for button padding\n\n## Colors\n- Primary actions: bg-primary text-primary-foreground\n- Destructive actions: bg-destructive text-destructive-foreground\n\n## Components\n- All forms must include a Cancel button\n- Modal headers should use text-lg font-semibold\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/semantic\": [\"warn\", {\n model: \"qwen3-coder:30b\", // Ollama model name\n styleguidePath: \".uilint/styleguide.md\" // Path to styleguide\n}]\n\\`\\`\\`\n\n## Notes\n\n- Results are cached based on file content and styleguide hash\n- First run may be slow as the model loads; subsequent runs use cache\n- Works best with detailed, specific styleguide documentation\n- Set to \"off\" in CI to avoid slow builds (use pre-commit hooks locally)\n`,\n});\n\nexport default createRule<Options, MessageIds>({\n name: \"semantic\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"LLM-powered semantic UI analysis using styleguide\",\n },\n messages: {\n semanticIssue: \"{{message}}\",\n styleguideNotFound:\n \"No styleguide found. Create .uilint/styleguide.md or specify styleguidePath.\",\n analysisError: \"Semantic analysis failed: {{error}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n model: {\n type: \"string\",\n description: \"Ollama model to use\",\n },\n styleguidePath: {\n type: \"string\",\n description: \"Path to styleguide file\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ model: UILINT_DEFAULT_OLLAMA_MODEL }],\n create(context) {\n const options = context.options[0] || {};\n const filePath = context.filename;\n const fileDir = dirname(filePath);\n\n // Get styleguide\n const { path: styleguidePath, content: styleguide } = getStyleguide(\n fileDir,\n options.styleguidePath\n );\n\n // Skip if no styleguide\n if (!styleguide) {\n console.error(\n `[uilint] Styleguide not found (styleguidePath=${String(\n options.styleguidePath ?? \"\"\n )}, startDir=${fileDir})`\n );\n\n return {\n Program(node) {\n context.report({\n node,\n messageId: \"styleguideNotFound\",\n });\n },\n };\n }\n\n // Read and hash file contents\n let fileContent: string;\n try {\n fileContent = readFileSync(filePath, \"utf-8\");\n } catch {\n console.error(`[uilint] Failed to read file ${filePath}`);\n return {\n Program(node) {\n context.report({\n node,\n messageId: \"analysisError\",\n data: { error: `Failed to read source file ${filePath}` },\n });\n },\n };\n }\n\n const fileHash = hashContentSync(fileContent);\n const styleguideHash = hashContentSync(styleguide);\n\n // Check cache\n const projectRoot = findProjectRoot(fileDir);\n const relativeFilePath = relative(projectRoot, filePath);\n const cached = getCacheEntry(\n projectRoot,\n relativeFilePath,\n fileHash,\n styleguideHash\n );\n\n const ENABLE_CACHE = false;\n if (ENABLE_CACHE && cached) {\n console.error(`[uilint] Cache hit for ${filePath}`);\n\n // Report cached issues\n return {\n Program(node) {\n for (const issue of cached.issues) {\n context.report({\n node,\n loc: { line: issue.line, column: issue.column || 0 },\n messageId: \"semanticIssue\",\n data: { message: issue.message },\n });\n }\n },\n };\n }\n\n // Cache miss: run sync analysis now (slow), cache, then report.\n ENABLE_CACHE &&\n console.error(\n `[uilint] Cache miss for ${filePath}, running semantic analysis`\n );\n\n return {\n Program(node) {\n const issues = runSemanticAnalysisSync(\n fileContent,\n styleguide,\n options.model || UILINT_DEFAULT_OLLAMA_MODEL,\n filePath\n );\n\n setCacheEntry(projectRoot, relativeFilePath, {\n fileHash,\n styleguideHash,\n issues,\n timestamp: Date.now(),\n });\n\n for (const issue of issues) {\n context.report({\n node,\n loc: { line: issue.line, column: issue.column || 0 },\n messageId: \"semanticIssue\",\n data: { message: issue.message },\n });\n }\n },\n };\n },\n});\n\n/**\n * Find project root by looking for package.json\n */\nfunction findProjectRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Run semantic analysis using Ollama (synchronously).\n *\n * Implementation detail:\n * - ESLint rules are synchronous.\n * - Blocking on a Promise (sleep-loop/Atomics) would also block Node's event loop,\n * preventing the HTTP request to Ollama from ever completing.\n * - To keep this simple & debuggable, we run the async LLM call in a child Node\n * process and synchronously wait for it to exit.\n */\nfunction runSemanticAnalysisSync(\n sourceCode: string,\n styleguide: string,\n model: string,\n filePath?: string\n): CachedIssue[] {\n const startTime = Date.now();\n const fileDisplay = filePath ? ` ${filePath}` : \"\";\n\n console.error(`[uilint] Starting semantic analysis (sync)${fileDisplay}`);\n console.error(`[uilint] Model: ${model}`);\n\n // Build prompt in-process (pure string building).\n const prompt = buildSourceScanPrompt(sourceCode, styleguide, {});\n\n // Avoid `uilint-core/node` exports *and* CJS resolution:\n // resolve the installed dependency by file URL relative to this plugin bundle.\n // When built, `import.meta.url` points at `.../uilint-eslint/dist/index.js`,\n // and the dependency lives at `.../uilint-eslint/node_modules/uilint-core/dist/node.js`.\n const coreNodeUrl = new URL(\n \"../node_modules/uilint-core/dist/node.js\",\n import.meta.url\n ).href;\n\n const childScript = `\n import * as coreNode from ${JSON.stringify(coreNodeUrl)};\n const { OllamaClient, logInfo, logWarning, createProgress, pc } = coreNode;\n const chunks = [];\n for await (const c of process.stdin) chunks.push(c);\n const input = JSON.parse(Buffer.concat(chunks).toString(\"utf8\"));\n const model = input.model;\n const prompt = input.prompt;\n\n const client = new OllamaClient({ model });\n const ok = await client.isAvailable();\n if (!ok) {\n logWarning(\"Ollama not available, skipping semantic analysis\");\n process.stdout.write(JSON.stringify({ issues: [] }));\n process.exit(0);\n }\n\n logInfo(\\`Ollama connected \\${pc.dim(\\`(model: \\${model})\\`)}\\`);\n const progress = createProgress(\"Analyzing with LLM...\");\n try {\n const response = await client.complete(prompt, {\n json: true,\n stream: true,\n onProgress: (latestLine) => {\n const maxLen = 60;\n const display =\n latestLine.length > maxLen\n ? latestLine.slice(0, maxLen) + \"…\"\n : latestLine;\n progress.update(\\`LLM: \\${pc.dim(display || \"...\")}\\`);\n },\n });\n progress.succeed(\"LLM complete\");\n process.stdout.write(response);\n } catch (e) {\n progress.fail(\\`LLM failed: \\${e instanceof Error ? e.message : String(e)}\\`);\n process.exit(1);\n }\n `;\n\n const child = spawnSync(\n process.execPath,\n [\"--input-type=module\", \"-e\", childScript],\n {\n input: JSON.stringify({ model, prompt }),\n encoding: \"utf8\",\n stdio: [\"pipe\", \"pipe\", \"inherit\"],\n maxBuffer: 20 * 1024 * 1024,\n }\n );\n\n const elapsed = Date.now() - startTime;\n\n if (child.error) {\n console.error(\n `[uilint] Semantic analysis failed after ${elapsed}ms: ${child.error.message}`\n );\n return [];\n }\n\n if (typeof child.status === \"number\" && child.status !== 0) {\n console.error(\n `[uilint] Semantic analysis failed after ${elapsed}ms: child exited ${child.status}`\n );\n return [];\n }\n\n const responseText = (child.stdout || \"\").trim();\n if (!responseText) {\n console.error(\n `[uilint] Semantic analysis returned empty response (${elapsed}ms)`\n );\n return [];\n }\n\n try {\n const parsed = JSON.parse(responseText) as {\n issues?: Array<{ line?: number; column?: number; message?: string }>;\n };\n\n const issues = (parsed.issues || []).map((issue) => ({\n line: issue.line || 1,\n column: issue.column,\n message: issue.message || \"Semantic issue detected\",\n ruleId: \"uilint/semantic\",\n severity: 1 as const,\n }));\n\n if (issues.length > 0) {\n console.error(`[uilint] Found ${issues.length} issue(s) (${elapsed}ms)`);\n } else {\n console.error(`[uilint] No issues found (${elapsed}ms)`);\n }\n\n return issues;\n } catch (e) {\n console.error(\n `[uilint] Semantic analysis failed to parse response after ${elapsed}ms: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n return [];\n }\n}\n","/**\n * File-hash based caching for LLM semantic rule\n *\n * Uses xxhash for fast hashing of file contents.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"fs\";\nimport { dirname, join } from \"path\";\n\n// Lazy-loaded xxhash\nlet xxhashInstance: Awaited<\n ReturnType<typeof import(\"xxhash-wasm\")[\"default\"]>\n> | null = null;\n\nasync function getXxhash() {\n if (!xxhashInstance) {\n const xxhash = await import(\"xxhash-wasm\");\n xxhashInstance = await xxhash.default();\n }\n return xxhashInstance;\n}\n\n/**\n * Synchronous hash using a simple djb2 algorithm (fallback when xxhash not available)\n */\nfunction djb2Hash(str: string): string {\n let hash = 5381;\n for (let i = 0; i < str.length; i++) {\n hash = (hash * 33) ^ str.charCodeAt(i);\n }\n return (hash >>> 0).toString(16);\n}\n\n/**\n * Hash content using xxhash (async) or djb2 (sync fallback)\n */\nexport async function hashContent(content: string): Promise<string> {\n try {\n const xxhash = await getXxhash();\n return xxhash.h64ToString(content);\n } catch {\n return djb2Hash(content);\n }\n}\n\n/**\n * Synchronous hash for when async is not possible\n */\nexport function hashContentSync(content: string): string {\n return djb2Hash(content);\n}\n\nexport interface CacheEntry {\n fileHash: string;\n styleguideHash: string;\n issues: CachedIssue[];\n timestamp: number;\n}\n\nexport interface CachedIssue {\n line: number;\n column?: number;\n message: string;\n ruleId: string;\n severity: 1 | 2; // 1 = warn, 2 = error\n}\n\nexport interface CacheStore {\n version: number;\n entries: Record<string, CacheEntry>;\n}\n\nconst CACHE_VERSION = 1;\nconst CACHE_FILE = \".uilint/.cache/eslint-semantic.json\";\n\n/**\n * Get the cache file path for a project\n */\nexport function getCachePath(projectRoot: string): string {\n return join(projectRoot, CACHE_FILE);\n}\n\n/**\n * Load the cache store\n */\nexport function loadCache(projectRoot: string): CacheStore {\n const cachePath = getCachePath(projectRoot);\n\n if (!existsSync(cachePath)) {\n return { version: CACHE_VERSION, entries: {} };\n }\n\n try {\n const content = readFileSync(cachePath, \"utf-8\");\n const cache = JSON.parse(content) as CacheStore;\n\n // Invalidate if version mismatch\n if (cache.version !== CACHE_VERSION) {\n return { version: CACHE_VERSION, entries: {} };\n }\n\n return cache;\n } catch {\n return { version: CACHE_VERSION, entries: {} };\n }\n}\n\n/**\n * Save the cache store\n */\nexport function saveCache(projectRoot: string, cache: CacheStore): void {\n const cachePath = getCachePath(projectRoot);\n\n try {\n const cacheDir = dirname(cachePath);\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n\n writeFileSync(cachePath, JSON.stringify(cache, null, 2), \"utf-8\");\n } catch {\n // Silently fail - caching is optional\n }\n}\n\n/**\n * Get cached entry for a file\n */\nexport function getCacheEntry(\n projectRoot: string,\n filePath: string,\n fileHash: string,\n styleguideHash: string\n): CacheEntry | null {\n const cache = loadCache(projectRoot);\n const entry = cache.entries[filePath];\n\n if (!entry) return null;\n\n // Check if hashes match\n if (entry.fileHash !== fileHash || entry.styleguideHash !== styleguideHash) {\n return null;\n }\n\n return entry;\n}\n\n/**\n * Set cached entry for a file\n */\nexport function setCacheEntry(\n projectRoot: string,\n filePath: string,\n entry: CacheEntry\n): void {\n const cache = loadCache(projectRoot);\n cache.entries[filePath] = entry;\n saveCache(projectRoot, cache);\n}\n\n/**\n * Clear cache for a specific file\n */\nexport function clearCacheEntry(projectRoot: string, filePath: string): void {\n const cache = loadCache(projectRoot);\n delete cache.entries[filePath];\n saveCache(projectRoot, cache);\n}\n\n/**\n * Clear entire cache\n */\nexport function clearCache(projectRoot: string): void {\n saveCache(projectRoot, { version: CACHE_VERSION, entries: {} });\n}\n","/**\n * Styleguide loader for the LLM semantic rule\n *\n * Only the semantic rule reads the styleguide - static rules use ESLint options.\n */\n\nimport { existsSync, readFileSync } from \"fs\";\nimport { dirname, isAbsolute, join, resolve } from \"path\";\n\nconst DEFAULT_STYLEGUIDE_PATHS = [\n \".uilint/styleguide.md\",\n \".uilint/styleguide.yaml\",\n \".uilint/styleguide.yml\",\n];\n\n/**\n * Find workspace root by walking up looking for pnpm-workspace.yaml, package.json, or .git\n */\nfunction findWorkspaceRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (\n existsSync(join(dir, \"pnpm-workspace.yaml\")) ||\n existsSync(join(dir, \".git\"))\n ) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Find the nearest package root (directory containing package.json),\n * stopping at the workspace root.\n */\nfunction findNearestPackageRoot(\n startDir: string,\n workspaceRoot: string\n): string {\n let dir = startDir;\n for (let i = 0; i < 30; i++) {\n if (existsSync(join(dir, \"package.json\"))) return dir;\n if (dir === workspaceRoot) break;\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Find the styleguide file path\n */\nexport function findStyleguidePath(\n startDir: string,\n explicitPath?: string\n): string | null {\n // Explicit path takes precedence\n if (explicitPath) {\n if (isAbsolute(explicitPath)) {\n return existsSync(explicitPath) ? explicitPath : null;\n }\n\n // For relative explicit paths, try:\n // 1) relative to the file dir (back-compat)\n // 2) relative to the nearest package root (typical \"project root\")\n // 3) relative to workspace root (monorepo root)\n const workspaceRoot = findWorkspaceRoot(startDir);\n const packageRoot = findNearestPackageRoot(startDir, workspaceRoot);\n\n const candidates = [\n resolve(startDir, explicitPath),\n resolve(packageRoot, explicitPath),\n resolve(workspaceRoot, explicitPath),\n ];\n\n for (const p of candidates) {\n if (existsSync(p)) return p;\n }\n\n return null;\n }\n\n // Check from start dir up to workspace root\n const workspaceRoot = findWorkspaceRoot(startDir);\n let dir = startDir;\n\n while (true) {\n for (const relativePath of DEFAULT_STYLEGUIDE_PATHS) {\n const fullPath = join(dir, relativePath);\n if (existsSync(fullPath)) {\n return fullPath;\n }\n }\n\n // Stop at workspace root\n if (dir === workspaceRoot) break;\n\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n\n return null;\n}\n\n/**\n * Load styleguide content from file\n */\nexport function loadStyleguide(\n startDir: string,\n explicitPath?: string\n): string | null {\n const path = findStyleguidePath(startDir, explicitPath);\n if (!path) return null;\n\n try {\n return readFileSync(path, \"utf-8\");\n } catch {\n return null;\n }\n}\n\n/**\n * Get styleguide path and content\n */\nexport function getStyleguide(\n startDir: string,\n explicitPath?: string\n): { path: string | null; content: string | null } {\n const path = findStyleguidePath(startDir, explicitPath);\n if (!path) return { path: null, content: null };\n\n try {\n const content = readFileSync(path, \"utf-8\");\n return { path, content };\n } catch {\n return { path, content: null };\n }\n}\n","/**\n * Rule: semantic-vision\n *\n * ESLint rule that reports cached vision analysis results for UI elements.\n * Vision analysis is performed by the UILint browser overlay and results are\n * cached in .uilint/screenshots/{timestamp}-{route}.json files.\n *\n * This rule:\n * 1. Finds cached vision analysis results for the current file\n * 2. Reports any issues that match elements in this file (by data-loc)\n * 3. If no cached results exist, silently passes (analysis is triggered by browser)\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"fs\";\nimport { dirname, join, relative } from \"path\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"visionIssue\" | \"analysisStale\";\n\ntype Options = [\n {\n /** Maximum age of cached results in milliseconds (default: 1 hour) */\n maxAgeMs?: number;\n /** Path to screenshots directory (default: .uilint/screenshots) */\n screenshotsPath?: string;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"semantic-vision\",\n name: \"Vision Analysis\",\n description: \"Report cached vision analysis results from UILint browser overlay\",\n defaultSeverity: \"warn\",\n category: \"semantic\",\n requiresStyleguide: false,\n defaultOptions: [{ maxAgeMs: 3600000, screenshotsPath: \".uilint/screenshots\" }],\n optionSchema: {\n fields: [\n {\n key: \"maxAgeMs\",\n label: \"Max cache age (milliseconds)\",\n type: \"number\",\n defaultValue: 3600000,\n placeholder: \"3600000\",\n description: \"Maximum age of cached results in milliseconds (default: 1 hour)\",\n },\n {\n key: \"screenshotsPath\",\n label: \"Screenshots directory path\",\n type: \"text\",\n defaultValue: \".uilint/screenshots\",\n placeholder: \".uilint/screenshots\",\n description: \"Relative path to the screenshots directory containing analysis results\",\n },\n ],\n },\n docs: `\n## What it does\n\nReports UI issues found by the UILint browser overlay's vision analysis. The overlay\ncaptures screenshots and analyzes them using vision AI, then caches the results.\nThis ESLint rule reads those cached results and reports them as linting errors.\n\n## How it works\n\n1. **Browser overlay**: When running your dev server with the UILint overlay, it captures\n screenshots and analyzes them using vision AI\n2. **Results cached**: Analysis results are saved to \\`.uilint/screenshots/*.json\\`\n3. **ESLint reports**: This rule reads cached results and reports issues at the correct\n source locations using \\`data-loc\\` attributes\n\n## Why it's useful\n\n- **Visual issues**: Catches problems that can only be seen in rendered UI\n- **Continuous feedback**: Issues appear in your editor as you develop\n- **No manual review**: AI spots spacing, alignment, and consistency issues automatically\n\n## Prerequisites\n\n1. **UILint overlay installed**: Add the overlay component to your app\n2. **Run analysis**: Load pages in the browser with the overlay active\n3. **Results cached**: Wait for analysis to complete and cache results\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/semantic-vision\": [\"warn\", {\n maxAgeMs: 3600000, // Ignore results older than 1 hour\n screenshotsPath: \".uilint/screenshots\" // Where cached results are stored\n}]\n\\`\\`\\`\n\n## Notes\n\n- If no cached results exist, the rule passes silently\n- Results are matched to source files using \\`data-loc\\` attributes\n- Stale results (older than \\`maxAgeMs\\`) are reported as warnings\n- Run the browser overlay to refresh cached analysis\n`,\n});\n\n/**\n * Vision analysis result structure stored in JSON files\n */\ninterface VisionAnalysisResult {\n /** Timestamp when analysis was performed */\n timestamp: number;\n /** Route that was analyzed (e.g., \"/\", \"/profile\") */\n route: string;\n /** Screenshot filename (for reference) */\n screenshotFile?: string;\n /** Issues found by vision analysis */\n issues: VisionIssue[];\n}\n\n/**\n * Individual issue from vision analysis\n */\ninterface VisionIssue {\n /** Element text that the LLM referenced */\n elementText?: string;\n /** data-loc reference (format: \"path:line:column\") */\n dataLoc?: string;\n /** Human-readable description of the issue */\n message: string;\n /** Issue category */\n category?: \"spacing\" | \"color\" | \"typography\" | \"alignment\" | \"accessibility\" | \"layout\" | \"other\";\n /** Severity level */\n severity?: \"error\" | \"warning\" | \"info\";\n}\n\n/**\n * Find project root by looking for package.json\n */\nfunction findProjectRoot(startDir: string): string {\n let dir = startDir;\n for (let i = 0; i < 20; i++) {\n if (existsSync(join(dir, \"package.json\"))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return startDir;\n}\n\n/**\n * Get all vision analysis result files from screenshots directory\n */\nfunction getVisionResultFiles(screenshotsDir: string): string[] {\n if (!existsSync(screenshotsDir)) {\n return [];\n }\n\n try {\n const files = readdirSync(screenshotsDir);\n return files\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => join(screenshotsDir, f))\n .sort()\n .reverse(); // Most recent first\n } catch {\n return [];\n }\n}\n\n/**\n * Load and parse a vision analysis result file\n */\nfunction loadVisionResult(filePath: string): VisionAnalysisResult | null {\n try {\n const content = readFileSync(filePath, \"utf-8\");\n return JSON.parse(content) as VisionAnalysisResult;\n } catch {\n return null;\n }\n}\n\n/**\n * Parse a data-loc string into file path and location\n * Format: \"path/to/file.tsx:line:column\"\n */\nfunction parseDataLoc(dataLoc: string): { filePath: string; line: number; column: number } | null {\n // Match pattern: path:line:column (line and column are numbers)\n const match = dataLoc.match(/^(.+):(\\d+):(\\d+)$/);\n if (!match) return null;\n\n return {\n filePath: match[1]!,\n line: parseInt(match[2]!, 10),\n column: parseInt(match[3]!, 10),\n };\n}\n\n/**\n * Normalize file path for comparison (handle relative vs absolute paths)\n */\nfunction normalizeFilePath(filePath: string, projectRoot: string): string {\n // If it's already a relative path, return as-is\n if (!filePath.startsWith(\"/\")) {\n return filePath;\n }\n // Convert absolute to relative\n return relative(projectRoot, filePath);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"semantic-vision\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Report cached vision analysis results from UILint browser overlay\",\n },\n messages: {\n visionIssue: \"[Vision] {{message}}\",\n analysisStale:\n \"Vision analysis results are stale (older than {{age}}). Re-run analysis in browser.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxAgeMs: {\n type: \"number\",\n description:\n \"Maximum age of cached results in milliseconds (default: 1 hour)\",\n },\n screenshotsPath: {\n type: \"string\",\n description:\n \"Path to screenshots directory (default: .uilint/screenshots)\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [{ maxAgeMs: 60 * 60 * 1000 }], // 1 hour default\n create(context) {\n const options = context.options[0] || {};\n const maxAgeMs = options.maxAgeMs ?? 60 * 60 * 1000;\n const filePath = context.filename;\n const fileDir = dirname(filePath);\n\n // Find project root and screenshots directory\n const projectRoot = findProjectRoot(fileDir);\n const screenshotsDir = options.screenshotsPath\n ? join(projectRoot, options.screenshotsPath)\n : join(projectRoot, \".uilint\", \"screenshots\");\n\n // Get the relative path of the current file for matching against data-loc\n const relativeFilePath = normalizeFilePath(filePath, projectRoot);\n\n // Find all vision result files\n const resultFiles = getVisionResultFiles(screenshotsDir);\n if (resultFiles.length === 0) {\n // No cached results - silently pass (analysis happens in browser)\n return {};\n }\n\n // Collect issues that match this file from all recent results\n const matchingIssues: Array<{\n issue: VisionIssue;\n line: number;\n column: number;\n isStale: boolean;\n }> = [];\n\n const now = Date.now();\n\n for (const resultFile of resultFiles) {\n const result = loadVisionResult(resultFile);\n if (!result || !result.issues) continue;\n\n const isStale = now - result.timestamp > maxAgeMs;\n\n for (const issue of result.issues) {\n if (!issue.dataLoc) continue;\n\n const parsed = parseDataLoc(issue.dataLoc);\n if (!parsed) continue;\n\n // Check if this issue is for the current file\n const issueFilePath = normalizeFilePath(parsed.filePath, projectRoot);\n if (issueFilePath === relativeFilePath) {\n matchingIssues.push({\n issue,\n line: parsed.line,\n column: parsed.column,\n isStale,\n });\n }\n }\n }\n\n // De-duplicate issues by line:column:message\n const seenIssues = new Set<string>();\n const uniqueIssues = matchingIssues.filter((item) => {\n const key = `${item.line}:${item.column}:${item.issue.message}`;\n if (seenIssues.has(key)) return false;\n seenIssues.add(key);\n return true;\n });\n\n return {\n Program(node) {\n for (const { issue, line, column, isStale } of uniqueIssues) {\n // Build message with category prefix if available\n const categoryPrefix = issue.category\n ? `[${issue.category}] `\n : \"\";\n const message = `${categoryPrefix}${issue.message}`;\n\n // Report stale warning separately if enabled\n if (isStale) {\n const ageHours = Math.round(maxAgeMs / (60 * 60 * 1000));\n context.report({\n node,\n loc: { line, column },\n messageId: \"analysisStale\",\n data: { age: `${ageHours}h` },\n });\n }\n\n context.report({\n node,\n loc: { line, column },\n messageId: \"visionIssue\",\n data: { message },\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: enforce-absolute-imports\n *\n * Requires alias imports (e.g., @/) for imports that traverse more than a\n * configurable number of directory levels. Prevents fragile relative import\n * paths like ../../../utils/helper.\n *\n * Examples:\n * - Bad: import { x } from '../../utils/helper'\n * - Good: import { x } from '@/utils/helper'\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"preferAbsoluteImport\";\ntype Options = [\n {\n /** Maximum allowed parent directory traversals (default: 1, allows ../ but not ../../) */\n maxRelativeDepth?: number;\n /** The alias prefix to suggest (default: \"@/\") */\n aliasPrefix?: string;\n /** Patterns to ignore (e.g., [\"node_modules\", \".css\"]) */\n ignorePaths?: string[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"enforce-absolute-imports\",\n name: \"Enforce Absolute Imports\",\n description:\n \"Require alias imports for paths beyond a configurable directory depth\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [{ maxRelativeDepth: 1, aliasPrefix: \"@/\" }],\n optionSchema: {\n fields: [\n {\n key: \"maxRelativeDepth\",\n label: \"Maximum relative depth\",\n type: \"number\",\n defaultValue: 1,\n description:\n \"Maximum number of parent directory traversals allowed (../ counts as 1)\",\n },\n {\n key: \"aliasPrefix\",\n label: \"Alias prefix\",\n type: \"text\",\n defaultValue: \"@/\",\n description: \"The path alias prefix to use (e.g., @/, ~/)\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnforces the use of path aliases (like \\`@/\\`) for imports that traverse multiple\nparent directories. This prevents fragile relative imports that are hard to\nmaintain and refactor.\n\n## Why it's useful\n\n- **Maintainability**: Absolute imports don't break when files move\n- **Readability**: Clear indication of where imports come from\n- **Consistency**: Standardizes import style across the codebase\n- **Refactoring**: Easier to move files without updating import paths\n\n## Examples\n\n### ❌ Incorrect (with maxRelativeDepth: 1)\n\n\\`\\`\\`tsx\n// Too many parent traversals\nimport { Button } from '../../components/Button';\nimport { utils } from '../../../lib/utils';\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Using alias imports\nimport { Button } from '@/components/Button';\nimport { utils } from '@/lib/utils';\n\n// Single parent traversal (within threshold)\nimport { sibling } from '../sibling';\nimport { local } from './local';\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/enforce-absolute-imports\": [\"warn\", {\n maxRelativeDepth: 1, // Allow ../ but not ../../\n aliasPrefix: \"@/\", // Suggested alias prefix\n ignorePaths: [\".css\", \".scss\", \"node_modules\"]\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Count the number of parent directory traversals in an import path\n */\nfunction countParentTraversals(importSource: string): number {\n // Match all occurrences of ../ or ..\\\\ (Windows)\n const matches = importSource.match(/\\.\\.\\//g);\n return matches ? matches.length : 0;\n}\n\n/**\n * Check if an import is a relative path\n */\nfunction isRelativeImport(importSource: string): boolean {\n return importSource.startsWith(\"./\") || importSource.startsWith(\"../\");\n}\n\n/**\n * Check if the import should be ignored\n */\nfunction shouldIgnore(importSource: string, ignorePaths: string[]): boolean {\n return ignorePaths.some((pattern) => importSource.includes(pattern));\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"enforce-absolute-imports\",\n meta: {\n type: \"suggestion\",\n docs: {\n description:\n \"Require alias imports for paths beyond a configurable directory depth\",\n },\n messages: {\n preferAbsoluteImport:\n \"Import traverses {{depth}} parent director{{plural}}. Use an alias like '{{aliasPrefix}}...' instead of '{{importSource}}'.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxRelativeDepth: {\n type: \"number\",\n minimum: 0,\n description:\n \"Maximum number of parent directory traversals allowed\",\n },\n aliasPrefix: {\n type: \"string\",\n description: \"The path alias prefix to suggest\",\n },\n ignorePaths: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Patterns to ignore\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxRelativeDepth: 1,\n aliasPrefix: \"@/\",\n ignorePaths: [],\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxRelativeDepth = options.maxRelativeDepth ?? 1;\n const aliasPrefix = options.aliasPrefix ?? \"@/\";\n const ignorePaths = options.ignorePaths ?? [];\n\n /**\n * Check an import source and report if it exceeds the depth threshold\n */\n function checkImportSource(\n source: string,\n node: TSESTree.StringLiteral\n ): void {\n // Skip non-relative imports (node_modules, aliases, etc.)\n if (!isRelativeImport(source)) {\n return;\n }\n\n // Skip ignored paths\n if (shouldIgnore(source, ignorePaths)) {\n return;\n }\n\n const depth = countParentTraversals(source);\n\n if (depth > maxRelativeDepth) {\n context.report({\n node,\n messageId: \"preferAbsoluteImport\",\n data: {\n depth: String(depth),\n plural: depth === 1 ? \"y\" : \"ies\",\n aliasPrefix,\n importSource: source,\n },\n });\n }\n }\n\n return {\n // Standard import declarations: import { x } from '../../utils'\n ImportDeclaration(node) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n },\n\n // Re-exports with source: export { x } from '../../utils'\n ExportNamedDeclaration(node) {\n if (node.source) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n }\n },\n\n // Export all: export * from '../../utils'\n ExportAllDeclaration(node) {\n const source = node.source.value as string;\n checkImportSource(source, node.source);\n },\n };\n },\n});\n","/**\n * Rule: no-any-in-props\n *\n * Prevents React components from using `any` type in their props, ensuring\n * type safety at component boundaries.\n *\n * Examples:\n * - Bad: function Component(props: any) {}\n * - Bad: function Component({ x }: { x: any }) {}\n * - Bad: const Component: FC<any> = () => {}\n * - Good: function Component(props: { name: string }) {}\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"anyInProps\" | \"anyInPropsProperty\";\ntype Options = [\n {\n /** Also check FC<any> and React.FC<any> patterns */\n checkFCGenerics?: boolean;\n /** Allow any in generic defaults (e.g., <T = any>) */\n allowInGenericDefaults?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-any-in-props\",\n name: \"No Any in Props\",\n description: \"Disallow 'any' type in React component props\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [{ checkFCGenerics: true, allowInGenericDefaults: false }],\n optionSchema: {\n fields: [\n {\n key: \"checkFCGenerics\",\n label: \"Check FC generics\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Check FC<any> and React.FC<any> patterns\",\n },\n {\n key: \"allowInGenericDefaults\",\n label: \"Allow in generic defaults\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Allow any in generic type parameter defaults\",\n },\n ],\n },\n docs: `\n## What it does\n\nPrevents the use of \\`any\\` type in React component props. This ensures type\nsafety at component boundaries, catching type errors at compile time rather\nthan runtime.\n\n## Why it's useful\n\n- **Type Safety**: Catches prop type errors at compile time\n- **Documentation**: Props serve as self-documenting API\n- **Refactoring**: IDE can track prop usage across codebase\n- **Code Quality**: Encourages thoughtful API design\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Direct any annotation\nfunction Component(props: any) {}\n\n// Any in destructured props\nfunction Component({ data }: { data: any }) {}\n\n// FC with any generic\nconst Component: FC<any> = () => {};\n\n// Any in props interface\ninterface Props { value: any }\nfunction Component(props: Props) {}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Properly typed props\nfunction Component(props: { name: string }) {}\n\n// Using unknown for truly unknown types\nfunction Component({ data }: { data: unknown }) {}\n\n// Typed FC\nconst Component: FC<{ count: number }> = () => {};\n\n// Generic component with constraint\nfunction List<T extends object>(props: { items: T[] }) {}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-any-in-props\": [\"error\", {\n checkFCGenerics: true, // Check FC<any> patterns\n allowInGenericDefaults: false // Disallow <T = any>\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Check if a name is likely a React component (PascalCase, not a hook)\n */\nfunction isComponentName(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name) && !name.startsWith(\"Use\");\n}\n\n/**\n * Check if a type node contains 'any'\n */\nfunction containsAnyType(\n node: TSESTree.TypeNode,\n allowInGenericDefaults: boolean\n): { hasAny: boolean; location: string | null } {\n if (!node) {\n return { hasAny: false, location: null };\n }\n\n switch (node.type) {\n case \"TSAnyKeyword\":\n return { hasAny: true, location: null };\n\n case \"TSTypeLiteral\":\n // Check each property in { prop: any }\n for (const member of node.members) {\n if (\n member.type === \"TSPropertySignature\" &&\n member.typeAnnotation?.typeAnnotation\n ) {\n const result = containsAnyType(\n member.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n const propName =\n member.key.type === \"Identifier\" ? member.key.name : \"property\";\n return { hasAny: true, location: `property '${propName}'` };\n }\n }\n // Index signature [key: string]: any\n if (\n member.type === \"TSIndexSignature\" &&\n member.typeAnnotation?.typeAnnotation\n ) {\n const result = containsAnyType(\n member.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"index signature\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSUnionType\":\n case \"TSIntersectionType\":\n for (const typeNode of node.types) {\n const result = containsAnyType(typeNode, allowInGenericDefaults);\n if (result.hasAny) {\n return result;\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSArrayType\":\n return containsAnyType(node.elementType, allowInGenericDefaults);\n\n case \"TSTypeReference\":\n // Check generic arguments like Array<any>, Record<string, any>\n if (node.typeArguments) {\n for (const param of node.typeArguments.params) {\n const result = containsAnyType(param, allowInGenericDefaults);\n if (result.hasAny) {\n return { hasAny: true, location: \"generic argument\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSFunctionType\":\n // Check return type and parameters\n if (node.returnType?.typeAnnotation) {\n const result = containsAnyType(\n node.returnType.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"function return type\" };\n }\n }\n for (const param of node.params) {\n // Skip TSParameterProperty (doesn't have typeAnnotation) and RestElement\n if (\n param.type !== \"RestElement\" &&\n param.type !== \"TSParameterProperty\" &&\n \"typeAnnotation\" in param &&\n param.typeAnnotation?.typeAnnotation\n ) {\n const result = containsAnyType(\n param.typeAnnotation.typeAnnotation,\n allowInGenericDefaults\n );\n if (result.hasAny) {\n return { hasAny: true, location: \"function parameter\" };\n }\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSTupleType\":\n for (const elementType of node.elementTypes) {\n // Handle both TSNamedTupleMember and regular type nodes\n const typeToCheck =\n elementType.type === \"TSNamedTupleMember\"\n ? elementType.elementType\n : elementType;\n const result = containsAnyType(typeToCheck, allowInGenericDefaults);\n if (result.hasAny) {\n return { hasAny: true, location: \"tuple element\" };\n }\n }\n return { hasAny: false, location: null };\n\n case \"TSConditionalType\":\n // Check all parts of conditional type\n const checkResult = containsAnyType(\n node.checkType,\n allowInGenericDefaults\n );\n if (checkResult.hasAny) return checkResult;\n const extendsResult = containsAnyType(\n node.extendsType,\n allowInGenericDefaults\n );\n if (extendsResult.hasAny) return extendsResult;\n const trueResult = containsAnyType(\n node.trueType,\n allowInGenericDefaults\n );\n if (trueResult.hasAny) return trueResult;\n const falseResult = containsAnyType(\n node.falseType,\n allowInGenericDefaults\n );\n if (falseResult.hasAny) return falseResult;\n return { hasAny: false, location: null };\n\n case \"TSMappedType\":\n if (node.typeAnnotation) {\n return containsAnyType(node.typeAnnotation, allowInGenericDefaults);\n }\n return { hasAny: false, location: null };\n\n default:\n return { hasAny: false, location: null };\n }\n}\n\n/**\n * Get the name of a function or component\n */\nfunction getComponentName(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.ArrowFunctionExpression\n | TSESTree.FunctionExpression\n): string | null {\n // Function declaration: function Foo() {}\n if (node.type === \"FunctionDeclaration\" && node.id) {\n return node.id.name;\n }\n\n // Variable declarator: const Foo = () => {}\n const parent = node.parent;\n if (\n parent?.type === \"VariableDeclarator\" &&\n parent.id.type === \"Identifier\"\n ) {\n return parent.id.name;\n }\n\n // forwardRef/memo wrapper: const Foo = forwardRef(() => {})\n if (parent?.type === \"CallExpression\") {\n const callParent = parent.parent;\n if (\n callParent?.type === \"VariableDeclarator\" &&\n callParent.id.type === \"Identifier\"\n ) {\n return callParent.id.name;\n }\n }\n\n // Named function expression: const x = function Foo() {}\n if (node.type === \"FunctionExpression\" && node.id) {\n return node.id.name;\n }\n\n return null;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-any-in-props\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Disallow 'any' type in React component props\",\n },\n messages: {\n anyInProps:\n \"Component '{{componentName}}' has 'any' type in props. Use a specific type or 'unknown' instead.\",\n anyInPropsProperty:\n \"Component '{{componentName}}' has 'any' type in {{location}}. Use a specific type or 'unknown' instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n checkFCGenerics: {\n type: \"boolean\",\n description: \"Check FC<any> and React.FC<any> patterns\",\n },\n allowInGenericDefaults: {\n type: \"boolean\",\n description: \"Allow any in generic type parameter defaults\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n checkFCGenerics: true,\n allowInGenericDefaults: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const checkFCGenerics = options.checkFCGenerics ?? true;\n const allowInGenericDefaults = options.allowInGenericDefaults ?? false;\n\n /**\n * Check a function's first parameter for any type\n */\n function checkFunctionProps(\n node:\n | TSESTree.FunctionDeclaration\n | TSESTree.ArrowFunctionExpression\n | TSESTree.FunctionExpression\n ): void {\n const componentName = getComponentName(node);\n\n // Skip if not a component (not PascalCase)\n if (!componentName || !isComponentName(componentName)) {\n return;\n }\n\n // Check first parameter (props)\n const firstParam = node.params[0];\n if (!firstParam) {\n return;\n }\n\n // Get type annotation\n let typeAnnotation: TSESTree.TypeNode | null = null;\n\n if (firstParam.type === \"Identifier\" && firstParam.typeAnnotation) {\n typeAnnotation = firstParam.typeAnnotation.typeAnnotation;\n } else if (\n firstParam.type === \"ObjectPattern\" &&\n firstParam.typeAnnotation\n ) {\n typeAnnotation = firstParam.typeAnnotation.typeAnnotation;\n }\n\n if (typeAnnotation) {\n const result = containsAnyType(typeAnnotation, allowInGenericDefaults);\n if (result.hasAny) {\n context.report({\n node: firstParam,\n messageId: result.location ? \"anyInPropsProperty\" : \"anyInProps\",\n data: {\n componentName,\n location: result.location || \"props\",\n },\n });\n }\n }\n }\n\n /**\n * Check FC<any> or React.FC<any> patterns\n */\n function checkFCGeneric(node: TSESTree.VariableDeclarator): void {\n if (!checkFCGenerics) {\n return;\n }\n\n // Get variable name\n if (node.id.type !== \"Identifier\") {\n return;\n }\n const componentName = node.id.name;\n\n // Skip if not a component name\n if (!isComponentName(componentName)) {\n return;\n }\n\n // Check type annotation\n const typeAnnotation = node.id.typeAnnotation?.typeAnnotation;\n if (!typeAnnotation || typeAnnotation.type !== \"TSTypeReference\") {\n return;\n }\n\n // Check if it's FC or React.FC\n let isFCType = false;\n if (\n typeAnnotation.typeName.type === \"Identifier\" &&\n [\"FC\", \"FunctionComponent\", \"VFC\"].includes(typeAnnotation.typeName.name)\n ) {\n isFCType = true;\n } else if (\n typeAnnotation.typeName.type === \"TSQualifiedName\" &&\n typeAnnotation.typeName.left.type === \"Identifier\" &&\n typeAnnotation.typeName.left.name === \"React\" &&\n [\"FC\", \"FunctionComponent\", \"VFC\"].includes(\n typeAnnotation.typeName.right.name\n )\n ) {\n isFCType = true;\n }\n\n if (!isFCType || !typeAnnotation.typeArguments) {\n return;\n }\n\n // Check the type argument\n const firstTypeArg = typeAnnotation.typeArguments.params[0];\n if (firstTypeArg) {\n const result = containsAnyType(firstTypeArg, allowInGenericDefaults);\n if (result.hasAny) {\n context.report({\n node: firstTypeArg,\n messageId: result.location ? \"anyInPropsProperty\" : \"anyInProps\",\n data: {\n componentName,\n location: result.location || \"FC type parameter\",\n },\n });\n }\n }\n }\n\n return {\n FunctionDeclaration(node) {\n checkFunctionProps(node);\n },\n\n ArrowFunctionExpression(node) {\n checkFunctionProps(node);\n },\n\n FunctionExpression(node) {\n checkFunctionProps(node);\n },\n\n VariableDeclarator(node) {\n checkFCGeneric(node);\n },\n };\n },\n});\n","/**\n * Rule: zustand-use-selectors\n *\n * Requires selector functions when accessing Zustand store state to prevent\n * unnecessary re-renders.\n *\n * Examples:\n * - Bad: const state = useStore()\n * - Bad: const { count } = useStore()\n * - Good: const count = useStore((s) => s.count)\n * - Good: const count = useStore(selectCount)\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"missingSelector\" | \"useSelectorFunction\";\ntype Options = [\n {\n /** Regex pattern for store hook names (default: \"^use\\\\w*Store$\") */\n storePattern?: string;\n /** Allow useShallow() wrapper without selector */\n allowShallow?: boolean;\n /** Require named selector functions instead of inline arrows */\n requireNamedSelectors?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"zustand-use-selectors\",\n name: \"Zustand Use Selectors\",\n description: \"Require selector functions when accessing Zustand store state\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n { storePattern: \"^use\\\\w*Store$\", allowShallow: true, requireNamedSelectors: false },\n ],\n optionSchema: {\n fields: [\n {\n key: \"storePattern\",\n label: \"Store hook pattern\",\n type: \"text\",\n defaultValue: \"^use\\\\w*Store$\",\n description: \"Regex pattern for identifying Zustand store hooks\",\n },\n {\n key: \"allowShallow\",\n label: \"Allow useShallow\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Allow useShallow() wrapper without explicit selector\",\n },\n {\n key: \"requireNamedSelectors\",\n label: \"Require named selectors\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Require named selector functions instead of inline arrows\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnforces the use of selector functions when accessing Zustand store state.\nWhen you call a Zustand store without a selector, your component subscribes\nto the entire store and re-renders on any state change.\n\n## Why it's useful\n\n- **Performance**: Prevents unnecessary re-renders\n- **Optimization**: Components only update when selected state changes\n- **Best Practice**: Follows Zustand's recommended patterns\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Subscribes to entire store - re-renders on any change\nconst state = useStore();\nconst { count, user } = useStore();\n\n// Component re-renders when anything changes, not just count\nfunction Counter() {\n const { count } = useStore();\n return <span>{count}</span>;\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Only re-renders when count changes\nconst count = useStore((state) => state.count);\n\n// Named selector\nconst selectCount = (state) => state.count;\nconst count = useStore(selectCount);\n\n// Multiple values with shallow\nimport { useShallow } from 'zustand/shallow';\nconst { count, user } = useStore(\n useShallow((state) => ({ count: state.count, user: state.user }))\n);\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/zustand-use-selectors\": [\"warn\", {\n storePattern: \"^use\\\\\\\\w*Store$\", // Match useXxxStore pattern\n allowShallow: true, // Allow useShallow without inline selector\n requireNamedSelectors: false // Allow inline arrow selectors\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Check if a node is a Zustand store call based on the pattern\n */\nfunction isZustandStoreCall(\n callee: TSESTree.Node,\n storePattern: RegExp\n): boolean {\n if (callee.type === \"Identifier\") {\n return storePattern.test(callee.name);\n }\n return false;\n}\n\n/**\n * Check if the first argument is a selector function or reference\n */\nfunction hasSelector(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n\n // Arrow function: (s) => s.count\n if (firstArg.type === \"ArrowFunctionExpression\") {\n return true;\n }\n\n // Function expression: function(s) { return s.count; }\n if (firstArg.type === \"FunctionExpression\") {\n return true;\n }\n\n // Named selector reference: selectCount\n if (firstArg.type === \"Identifier\") {\n return true;\n }\n\n // Member expression: selectors.count or module.selectCount\n if (firstArg.type === \"MemberExpression\") {\n return true;\n }\n\n // Call expression (might be useShallow or similar)\n if (firstArg.type === \"CallExpression\") {\n return true;\n }\n\n return false;\n}\n\n/**\n * Check if the selector is wrapped in useShallow\n */\nfunction isShallowWrapped(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n\n if (firstArg.type === \"CallExpression\") {\n if (\n firstArg.callee.type === \"Identifier\" &&\n firstArg.callee.name === \"useShallow\"\n ) {\n return true;\n }\n }\n\n return false;\n}\n\n/**\n * Check if the selector is an inline arrow function\n */\nfunction isInlineSelector(args: TSESTree.CallExpressionArgument[]): boolean {\n if (args.length === 0) {\n return false;\n }\n\n const firstArg = args[0];\n return (\n firstArg.type === \"ArrowFunctionExpression\" ||\n firstArg.type === \"FunctionExpression\"\n );\n}\n\n/**\n * Get the store name from the call expression\n */\nfunction getStoreName(callee: TSESTree.Node): string {\n if (callee.type === \"Identifier\") {\n return callee.name;\n }\n return \"useStore\";\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"zustand-use-selectors\",\n meta: {\n type: \"problem\",\n docs: {\n description:\n \"Require selector functions when accessing Zustand store state\",\n },\n messages: {\n missingSelector:\n \"Call to '{{storeName}}' is missing a selector. Use '{{storeName}}((state) => state.property)' to prevent unnecessary re-renders.\",\n useSelectorFunction:\n \"Consider using a named selector function instead of an inline arrow for '{{storeName}}'. Example: '{{storeName}}(selectProperty)'\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n storePattern: {\n type: \"string\",\n description: \"Regex pattern for store hook names\",\n },\n allowShallow: {\n type: \"boolean\",\n description: \"Allow useShallow() wrapper\",\n },\n requireNamedSelectors: {\n type: \"boolean\",\n description: \"Require named selector functions\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n storePattern: \"^use\\\\w*Store$\",\n allowShallow: true,\n requireNamedSelectors: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const storePatternStr = options.storePattern ?? \"^use\\\\w*Store$\";\n const allowShallow = options.allowShallow ?? true;\n const requireNamedSelectors = options.requireNamedSelectors ?? false;\n\n let storePattern: RegExp;\n try {\n storePattern = new RegExp(storePatternStr);\n } catch {\n // If invalid regex, use default\n storePattern = /^use\\w*Store$/;\n }\n\n return {\n CallExpression(node) {\n // Check if this is a Zustand store call\n if (!isZustandStoreCall(node.callee, storePattern)) {\n return;\n }\n\n const storeName = getStoreName(node.callee);\n\n // Check for selector\n if (!hasSelector(node.arguments)) {\n context.report({\n node,\n messageId: \"missingSelector\",\n data: { storeName },\n });\n return;\n }\n\n // If useShallow is used and allowed, that's fine\n if (allowShallow && isShallowWrapped(node.arguments)) {\n return;\n }\n\n // Check for named selectors if required\n if (requireNamedSelectors && isInlineSelector(node.arguments)) {\n context.report({\n node,\n messageId: \"useSelectorFunction\",\n data: { storeName },\n });\n }\n },\n };\n },\n});\n","/**\n * Rule: no-prop-drilling-depth\n *\n * Warns when a prop is passed through multiple intermediate components\n * without being used, indicating prop drilling that should be refactored\n * to context or state management.\n *\n * Examples:\n * - Bad: Prop passed through 3+ components without use\n * - Good: Prop used directly in receiving component\n * - Good: Using Context or Zustand instead of drilling\n */\n\nimport type { TSESTree } from \"@typescript-eslint/utils\";\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\n\ntype MessageIds = \"propDrilling\";\ntype Options = [\n {\n /** Maximum depth before warning (default: 2) */\n maxDepth?: number;\n /** Props to ignore (e.g., className, style, children) */\n ignoredProps?: string[];\n /** Component patterns to skip (regex strings) */\n ignoreComponents?: string[];\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-prop-drilling-depth\",\n name: \"No Prop Drilling Depth\",\n description: \"Warn when props are drilled through too many components\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n maxDepth: 2,\n ignoredProps: [\"className\", \"style\", \"children\", \"key\", \"ref\", \"id\"],\n ignoreComponents: [],\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"maxDepth\",\n label: \"Maximum drilling depth\",\n type: \"number\",\n defaultValue: 2,\n description:\n \"Maximum number of components a prop can pass through without use\",\n },\n {\n key: \"ignoredProps\",\n label: \"Ignored props\",\n type: \"text\",\n defaultValue: \"className, style, children, key, ref, id\",\n description: \"Comma-separated prop names to ignore (common pass-through props)\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects when props are passed through multiple intermediate components without\nbeing used (prop drilling). This is often a sign that you should use React\nContext, Zustand, or another state management solution.\n\n## Why it's useful\n\n- **Maintainability**: Deep prop drilling creates tight coupling\n- **Refactoring**: Changes require updates in many files\n- **Readability**: Hard to trace where props come from\n- **Performance**: Unnecessary re-renders in intermediate components\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Grandparent passes user through Parent to Child\nfunction Grandparent({ user }) {\n return <Parent user={user} />;\n}\n\nfunction Parent({ user }) {\n // Parent doesn't use 'user', just passes it along\n return <Child user={user} />;\n}\n\nfunction Child({ user }) {\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Use Context instead\nconst UserContext = createContext();\n\nfunction Grandparent({ user }) {\n return (\n <UserContext.Provider value={user}>\n <Parent />\n </UserContext.Provider>\n );\n}\n\nfunction Child() {\n const user = useContext(UserContext);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-prop-drilling-depth\": [\"warn\", {\n maxDepth: 2, // Allow passing through 2 components\n ignoredProps: [\"className\", \"style\", \"children\"], // Common pass-through props\n ignoreComponents: [\"^Layout\", \"^Wrapper\"] // Skip wrapper components\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Information about a component's prop usage\n */\ninterface ComponentPropInfo {\n /** Props received by the component */\n receivedProps: Set<string>;\n /** Props passed to child components: propName -> childComponentNames[] */\n passedProps: Map<string, string[]>;\n /** Props actually used in the component (not just passed) */\n usedProps: Set<string>;\n /** Child components that receive props from this component */\n childComponents: string[];\n}\n\n/**\n * Cache for analyzed component prop information\n */\nconst componentPropCache = new Map<string, ComponentPropInfo>();\n\n/**\n * Clear the prop analysis cache\n */\nexport function clearPropCache(): void {\n componentPropCache.clear();\n}\n\n/**\n * Check if a name is a React component (PascalCase)\n */\nfunction isComponentName(name: string): boolean {\n return /^[A-Z][a-zA-Z0-9]*$/.test(name);\n}\n\n/**\n * Extract props from a function parameter\n */\nfunction extractPropsFromParam(\n param: TSESTree.Parameter\n): { propNames: Set<string>; isSpread: boolean } {\n const propNames = new Set<string>();\n let isSpread = false;\n\n if (param.type === \"ObjectPattern\") {\n for (const prop of param.properties) {\n if (prop.type === \"RestElement\") {\n isSpread = true;\n } else if (\n prop.type === \"Property\" &&\n prop.key.type === \"Identifier\"\n ) {\n propNames.add(prop.key.name);\n }\n }\n } else if (param.type === \"Identifier\") {\n // Single props parameter - assume all props accessed via props.x\n isSpread = true;\n }\n\n return { propNames, isSpread };\n}\n\n/**\n * Find all JSX elements in a function body and extract prop passing info\n */\nfunction analyzeJSXPropPassing(\n body: TSESTree.Node,\n receivedProps: Set<string>\n): { passedProps: Map<string, string[]>; usedProps: Set<string> } {\n const passedProps = new Map<string, string[]>();\n const usedProps = new Set<string>();\n\n function visit(node: TSESTree.Node): void {\n if (!node || typeof node !== \"object\") return;\n\n // Check JSX elements for prop passing\n if (node.type === \"JSXOpeningElement\") {\n const elementName = getJSXElementName(node.name);\n\n // Only care about component elements (PascalCase)\n if (elementName && isComponentName(elementName)) {\n for (const attr of node.attributes) {\n if (attr.type === \"JSXAttribute\" && attr.name.type === \"JSXIdentifier\") {\n const attrName = attr.name.name;\n const propValue = attr.value;\n\n // Check if the attribute value is a received prop\n if (propValue?.type === \"JSXExpressionContainer\") {\n const expr = propValue.expression;\n if (expr.type === \"Identifier\" && receivedProps.has(expr.name)) {\n // This prop is being passed to a child\n const existing = passedProps.get(expr.name) || [];\n existing.push(elementName);\n passedProps.set(expr.name, existing);\n } else if (\n expr.type === \"MemberExpression\" &&\n expr.object.type === \"Identifier\" &&\n expr.object.name === \"props\" &&\n expr.property.type === \"Identifier\"\n ) {\n // props.x pattern\n const propName = expr.property.name;\n if (receivedProps.has(propName) || receivedProps.size === 0) {\n const existing = passedProps.get(propName) || [];\n existing.push(elementName);\n passedProps.set(propName, existing);\n }\n }\n }\n }\n\n // Check for spread props: {...props} or {...rest}\n if (attr.type === \"JSXSpreadAttribute\") {\n if (attr.argument.type === \"Identifier\") {\n const spreadName = attr.argument.name;\n if (spreadName === \"props\" || receivedProps.has(spreadName)) {\n // All props are being spread\n for (const prop of receivedProps) {\n const existing = passedProps.get(prop) || [];\n existing.push(elementName);\n passedProps.set(prop, existing);\n }\n }\n }\n }\n }\n }\n }\n\n // Check for prop usage (not just passing)\n // e.g., {user.name} or {props.user.name} or just {user}\n if (\n node.type === \"MemberExpression\" &&\n node.object.type === \"Identifier\" &&\n receivedProps.has(node.object.name)\n ) {\n usedProps.add(node.object.name);\n }\n\n if (\n node.type === \"Identifier\" &&\n receivedProps.has(node.name) &&\n node.parent?.type !== \"JSXExpressionContainer\"\n ) {\n // Prop used in expression (but not directly passed to child)\n usedProps.add(node.name);\n }\n\n // Check for props.x.something usage\n if (\n node.type === \"MemberExpression\" &&\n node.object.type === \"MemberExpression\" &&\n node.object.object.type === \"Identifier\" &&\n node.object.object.name === \"props\" &&\n node.object.property.type === \"Identifier\"\n ) {\n usedProps.add(node.object.property.name);\n }\n\n // Recurse into children\n for (const key of Object.keys(node)) {\n if (key === \"parent\" || key === \"loc\" || key === \"range\") continue;\n const child = (node as unknown as Record<string, unknown>)[key];\n if (Array.isArray(child)) {\n for (const item of child) {\n if (item && typeof item === \"object\") {\n visit(item as TSESTree.Node);\n }\n }\n } else if (child && typeof child === \"object\") {\n visit(child as TSESTree.Node);\n }\n }\n }\n\n visit(body);\n return { passedProps, usedProps };\n}\n\n/**\n * Get the name of a JSX element\n */\nfunction getJSXElementName(node: TSESTree.JSXTagNameExpression): string | null {\n if (node.type === \"JSXIdentifier\") {\n return node.name;\n }\n if (node.type === \"JSXMemberExpression\") {\n // Get the root object for namespace components\n let current = node.object;\n while (current.type === \"JSXMemberExpression\") {\n current = current.object;\n }\n return current.type === \"JSXIdentifier\" ? current.name : null;\n }\n return null;\n}\n\n/**\n * Track prop drilling within a single file\n */\ninterface PropDrillingInfo {\n propName: string;\n component: string;\n passedTo: string[];\n usedDirectly: boolean;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-prop-drilling-depth\",\n meta: {\n type: \"suggestion\",\n docs: {\n description: \"Warn when props are drilled through too many components\",\n },\n messages: {\n propDrilling:\n \"Prop '{{propName}}' is passed through {{depth}} component(s) without being used. Consider using Context or state management. Path: {{path}}\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n maxDepth: {\n type: \"number\",\n minimum: 1,\n description: \"Maximum drilling depth before warning\",\n },\n ignoredProps: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Props to ignore\",\n },\n ignoreComponents: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Component patterns to skip (regex)\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n maxDepth: 2,\n ignoredProps: [\"className\", \"style\", \"children\", \"key\", \"ref\", \"id\"],\n ignoreComponents: [],\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const maxDepth = options.maxDepth ?? 2;\n const ignoredProps = new Set(\n options.ignoredProps ?? [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\",\n ]\n );\n const ignoreComponentPatterns = (options.ignoreComponents ?? []).map(\n (p) => new RegExp(p)\n );\n\n // Track components and their prop flows within the file\n const componentProps = new Map<string, ComponentPropInfo>();\n const imports = new Map<string, string>(); // localName -> importSource\n const componentNodes = new Map<string, TSESTree.Node>(); // componentName -> node\n\n function shouldIgnoreComponent(name: string): boolean {\n return ignoreComponentPatterns.some((pattern) => pattern.test(name));\n }\n\n function shouldIgnoreProp(name: string): boolean {\n return ignoredProps.has(name);\n }\n\n /**\n * Analyze a component function for prop drilling\n */\n function analyzeComponent(\n name: string,\n node: TSESTree.FunctionDeclaration | TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression,\n reportNode: TSESTree.Node\n ): void {\n if (shouldIgnoreComponent(name)) return;\n\n const firstParam = node.params[0];\n if (!firstParam) return;\n\n const { propNames, isSpread } = extractPropsFromParam(firstParam);\n\n // If using spread without destructuring, we can't easily track props\n if (isSpread && propNames.size === 0) return;\n\n const body = node.body;\n if (!body) return;\n\n const { passedProps, usedProps } = analyzeJSXPropPassing(body, propNames);\n\n componentProps.set(name, {\n receivedProps: propNames,\n passedProps,\n usedProps,\n childComponents: [...new Set([...passedProps.values()].flat())],\n });\n\n componentNodes.set(name, reportNode);\n }\n\n return {\n // Track imports for cross-file analysis\n ImportDeclaration(node) {\n const source = node.source.value as string;\n for (const spec of node.specifiers) {\n if (spec.type === \"ImportSpecifier\" || spec.type === \"ImportDefaultSpecifier\") {\n imports.set(spec.local.name, source);\n }\n }\n },\n\n // Analyze function declarations\n FunctionDeclaration(node) {\n if (node.id && isComponentName(node.id.name)) {\n analyzeComponent(node.id.name, node, node);\n }\n },\n\n // Analyze arrow functions\n VariableDeclarator(node) {\n if (\n node.id.type === \"Identifier\" &&\n isComponentName(node.id.name) &&\n node.init?.type === \"ArrowFunctionExpression\"\n ) {\n analyzeComponent(node.id.name, node.init, node);\n }\n },\n\n // Analyze at the end of the file\n \"Program:exit\"() {\n // Find drilling chains within the file\n for (const [componentName, info] of componentProps) {\n for (const [propName, children] of info.passedProps) {\n if (shouldIgnoreProp(propName)) continue;\n\n // Check if prop is used directly\n if (info.usedProps.has(propName)) continue;\n\n // Track the drilling chain\n const chain: string[] = [componentName];\n let depth = 0;\n let current = children;\n\n while (current.length > 0 && depth < maxDepth + 1) {\n depth++;\n const nextChildren: string[] = [];\n\n for (const child of current) {\n chain.push(child);\n const childInfo = componentProps.get(child);\n\n if (childInfo) {\n // Check if child uses the prop\n if (childInfo.usedProps.has(propName)) {\n // Prop is used here, drilling stops\n break;\n }\n\n // Check if child passes the prop further\n const childPasses = childInfo.passedProps.get(propName);\n if (childPasses) {\n nextChildren.push(...childPasses);\n }\n }\n }\n\n current = nextChildren;\n }\n\n // Report if depth exceeds threshold\n if (depth > maxDepth) {\n const reportNode = componentNodes.get(componentName);\n if (reportNode) {\n context.report({\n node: reportNode,\n messageId: \"propDrilling\",\n data: {\n propName,\n depth: String(depth),\n path: chain.slice(0, maxDepth + 2).join(\" → \"),\n },\n });\n }\n }\n }\n }\n },\n };\n },\n});\n","/**\n * Rule: no-secrets-in-code\n *\n * Detects hardcoded secrets, API keys, passwords, and tokens in source code.\n * Prevents accidental exposure of sensitive credentials.\n *\n * Examples:\n * - Bad: const apiKey = 'AKIA1234567890ABCDEF'\n * - Bad: const password = 'mySecretPassword123'\n * - Good: const apiKey = process.env.API_KEY\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"secretDetected\" | \"suspiciousVariable\";\ntype Options = [\n {\n /** Additional regex patterns to detect (as strings) */\n additionalPatterns?: Array<{ name: string; pattern: string }>;\n /** Check variable names for suspicious patterns */\n checkVariableNames?: boolean;\n /** Minimum length for generic secret detection */\n minSecretLength?: number;\n /** Relax rules in test files */\n allowInTestFiles?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"no-secrets-in-code\",\n name: \"No Secrets in Code\",\n description: \"Detect hardcoded secrets, API keys, and tokens\",\n defaultSeverity: \"error\",\n category: \"static\",\n defaultOptions: [\n {\n checkVariableNames: true,\n minSecretLength: 16,\n allowInTestFiles: false,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"checkVariableNames\",\n label: \"Check variable names\",\n type: \"boolean\",\n defaultValue: true,\n description: \"Check for suspicious variable names with high-entropy values\",\n },\n {\n key: \"minSecretLength\",\n label: \"Minimum secret length\",\n type: \"number\",\n defaultValue: 16,\n description: \"Minimum string length for generic secret detection\",\n },\n {\n key: \"allowInTestFiles\",\n label: \"Allow in test files\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Skip detection in test files (*.test.*, *.spec.*)\",\n },\n ],\n },\n docs: `\n## What it does\n\nDetects hardcoded secrets, API keys, passwords, and tokens in source code.\nThese should be stored in environment variables or secure vaults instead.\n\n## Why it's useful\n\n- **Security**: Prevents credential leaks in version control\n- **Compliance**: Helps meet security audit requirements\n- **Best Practice**: Enforces proper secrets management\n\n## Detected Patterns\n\n- AWS Access Keys and Secret Keys\n- GitHub Personal Access Tokens (ghp_*)\n- Stripe API Keys (sk_live_*, sk_test_*)\n- Google API Keys\n- Firebase Keys\n- Slack Tokens\n- npm Tokens\n- JWT Tokens\n- Private Keys (PEM format)\n- Generic API keys, passwords, and secrets in suspicious variables\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Hardcoded AWS credentials\nconst accessKey = 'AKIA1234567890ABCDEF';\nconst secretKey = 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY';\n\n// Hardcoded passwords\nconst dbPassword = 'supersecretpassword123';\n\n// Hardcoded tokens\nconst token = 'ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\n// Use environment variables\nconst accessKey = process.env.AWS_ACCESS_KEY_ID;\nconst secretKey = process.env.AWS_SECRET_ACCESS_KEY;\n\n// Reference from config\nconst dbPassword = config.database.password;\n\n// Use a secrets manager\nconst token = await secretsManager.getSecret('github-token');\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/no-secrets-in-code\": [\"error\", {\n checkVariableNames: true, // Check suspicious variable names\n minSecretLength: 16, // Minimum length for generic detection\n allowInTestFiles: false, // Don't skip test files\n additionalPatterns: [ // Add custom patterns\n { name: \"Custom API\", pattern: \"^myapi_[a-z0-9]{32}$\" }\n ]\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * Known secret patterns with names and regex\n */\nconst SECRET_PATTERNS: Array<{ name: string; pattern: RegExp }> = [\n // AWS\n { name: \"AWS Access Key ID\", pattern: /\\bAKIA[0-9A-Z]{16}\\b/ },\n { name: \"AWS Secret Access Key\", pattern: /\\b[A-Za-z0-9/+=]{40}\\b/ },\n\n // GitHub\n { name: \"GitHub Personal Access Token\", pattern: /\\bghp_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub OAuth Token\", pattern: /\\bgho_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub App Token\", pattern: /\\bghu_[A-Za-z0-9]{36}\\b/ },\n { name: \"GitHub Refresh Token\", pattern: /\\bghr_[A-Za-z0-9]{36}\\b/ },\n\n // Stripe\n { name: \"Stripe Live Secret Key\", pattern: /\\bsk_live_[A-Za-z0-9]{24,}\\b/ },\n { name: \"Stripe Test Secret Key\", pattern: /\\bsk_test_[A-Za-z0-9]{24,}\\b/ },\n { name: \"Stripe Restricted Key\", pattern: /\\brk_live_[A-Za-z0-9]{24,}\\b/ },\n\n // Google\n { name: \"Google API Key\", pattern: /\\bAIza[A-Za-z0-9_-]{35}\\b/ },\n\n // Slack\n { name: \"Slack Token\", pattern: /\\bxox[baprs]-[A-Za-z0-9-]{10,48}\\b/ },\n { name: \"Slack Webhook\", pattern: /\\bhooks\\.slack\\.com\\/services\\/T[A-Za-z0-9]+\\/B[A-Za-z0-9]+\\/[A-Za-z0-9]+\\b/ },\n\n // npm\n { name: \"npm Token\", pattern: /\\bnpm_[A-Za-z0-9]{36}\\b/ },\n\n // SendGrid\n { name: \"SendGrid API Key\", pattern: /\\bSG\\.[A-Za-z0-9_-]{22}\\.[A-Za-z0-9_-]{43}\\b/ },\n\n // Twilio\n { name: \"Twilio API Key\", pattern: /\\bSK[a-z0-9]{32}\\b/ },\n\n // Firebase\n { name: \"Firebase Key\", pattern: /\\bAAAA[A-Za-z0-9_-]{7}:[A-Za-z0-9_-]{140}\\b/ },\n\n // Generic patterns\n { name: \"Private Key\", pattern: /-----BEGIN\\s+(RSA\\s+|EC\\s+|DSA\\s+|OPENSSH\\s+)?PRIVATE\\s+KEY-----/ },\n { name: \"JWT Token\", pattern: /\\beyJ[A-Za-z0-9_-]+\\.eyJ[A-Za-z0-9_-]+\\.[A-Za-z0-9_-]+\\b/ },\n\n // Anthropic\n { name: \"Anthropic API Key\", pattern: /\\bsk-ant-api[A-Za-z0-9_-]{20,}\\b/ },\n\n // OpenAI\n { name: \"OpenAI API Key\", pattern: /\\bsk-proj-[A-Za-z0-9_-]{20,}\\b/ },\n { name: \"OpenAI API Key (old)\", pattern: /\\bsk-[A-Za-z0-9]{48}\\b/ },\n];\n\n/**\n * Variable name patterns that suggest secrets\n */\nconst SUSPICIOUS_VARIABLE_PATTERNS: RegExp[] = [\n /^api[_-]?key$/i,\n /^secret[_-]?key$/i,\n /^private[_-]?key$/i,\n /^access[_-]?key$/i,\n /^auth[_-]?key$/i,\n /^access[_-]?token$/i,\n /^auth[_-]?token$/i,\n /^api[_-]?token$/i,\n /^bearer[_-]?token$/i,\n /^jwt[_-]?token$/i,\n /^refresh[_-]?token$/i,\n /^password$/i,\n /^passwd$/i,\n /^pwd$/i,\n /^db[_-]?password$/i,\n /^database[_-]?password$/i,\n /^secret$/i,\n /^client[_-]?secret$/i,\n /^app[_-]?secret$/i,\n];\n\n/**\n * Patterns that indicate safe/placeholder values\n */\nconst PLACEHOLDER_PATTERNS: RegExp[] = [\n /^your[_-]?/i,\n /^xxx+$/i,\n /^placeholder/i,\n /^example/i,\n /^test[_-]?/i,\n /^fake[_-]?/i,\n /^dummy/i,\n /^sample/i,\n /<[^>]+>/, // <your-key-here>\n /\\${[^}]+}/, // ${API_KEY}\n /^\\*+$/, // ****\n];\n\n/**\n * Calculate Shannon entropy of a string\n */\nfunction calculateEntropy(str: string): number {\n if (str.length === 0) return 0;\n\n const freq: Record<string, number> = {};\n for (const char of str) {\n freq[char] = (freq[char] || 0) + 1;\n }\n\n let entropy = 0;\n const len = str.length;\n for (const count of Object.values(freq)) {\n const p = count / len;\n entropy -= p * Math.log2(p);\n }\n\n return entropy;\n}\n\n/**\n * Check if a value looks like a placeholder\n */\nfunction isPlaceholder(value: string): boolean {\n return PLACEHOLDER_PATTERNS.some((pattern) => pattern.test(value));\n}\n\n/**\n * Check if a value is likely an environment variable reference\n */\nfunction isEnvReference(value: string): boolean {\n return value.includes(\"process.env\") || value.includes(\"import.meta.env\");\n}\n\n/**\n * Get a preview of the secret (first and last few chars)\n */\nfunction getPreview(value: string, maxLength: number = 20): string {\n if (value.length <= maxLength) {\n return value.substring(0, 8) + \"...\";\n }\n return value.substring(0, 8) + \"...\" + value.substring(value.length - 4);\n}\n\n/**\n * Check if file is a test file\n */\nfunction isTestFile(filename: string): boolean {\n return /\\.(test|spec)\\.[jt]sx?$/.test(filename) ||\n /\\/__tests__\\//.test(filename) ||\n /\\/test\\//.test(filename);\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"no-secrets-in-code\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Detect hardcoded secrets, API keys, and tokens\",\n },\n messages: {\n secretDetected:\n \"Potential {{secretType}} detected: '{{preview}}'. Use environment variables instead of hardcoding secrets.\",\n suspiciousVariable:\n \"Variable '{{variableName}}' appears to contain a secret. Use environment variables instead.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n additionalPatterns: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n pattern: { type: \"string\" },\n },\n required: [\"name\", \"pattern\"],\n },\n description: \"Additional patterns to detect\",\n },\n checkVariableNames: {\n type: \"boolean\",\n description: \"Check variable names for suspicious patterns\",\n },\n minSecretLength: {\n type: \"number\",\n description: \"Minimum length for generic secret detection\",\n },\n allowInTestFiles: {\n type: \"boolean\",\n description: \"Skip detection in test files\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n checkVariableNames: true,\n minSecretLength: 16,\n allowInTestFiles: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const checkVariableNames = options.checkVariableNames ?? true;\n const minSecretLength = options.minSecretLength ?? 16;\n const allowInTestFiles = options.allowInTestFiles ?? false;\n const additionalPatterns = options.additionalPatterns ?? [];\n\n const filename = context.filename || context.getFilename?.() || \"\";\n\n // Skip test files if configured\n if (allowInTestFiles && isTestFile(filename)) {\n return {};\n }\n\n // Build full pattern list\n const allPatterns = [...SECRET_PATTERNS];\n for (const custom of additionalPatterns) {\n try {\n allPatterns.push({\n name: custom.name,\n pattern: new RegExp(custom.pattern),\n });\n } catch {\n // Invalid regex, skip\n }\n }\n\n /**\n * Check a string value for secrets\n */\n function checkStringForSecrets(\n value: string,\n node: TSESTree.Node,\n variableName?: string\n ): void {\n // Skip empty strings and short strings\n if (!value || value.length < 8) {\n return;\n }\n\n // Skip placeholders\n if (isPlaceholder(value)) {\n return;\n }\n\n // Check against known patterns\n for (const { name, pattern } of allPatterns) {\n if (pattern.test(value)) {\n context.report({\n node,\n messageId: \"secretDetected\",\n data: {\n secretType: name,\n preview: getPreview(value),\n },\n });\n return;\n }\n }\n\n // Check for suspicious variable names with high-entropy values\n if (checkVariableNames && variableName) {\n const isSuspiciousName = SUSPICIOUS_VARIABLE_PATTERNS.some((pattern) =>\n pattern.test(variableName)\n );\n\n if (isSuspiciousName && value.length >= minSecretLength) {\n const entropy = calculateEntropy(value);\n // High entropy (> 3.5) suggests random/secret data\n if (entropy > 3.5) {\n context.report({\n node,\n messageId: \"suspiciousVariable\",\n data: {\n variableName,\n },\n });\n }\n }\n }\n }\n\n /**\n * Get variable name from declarator\n */\n function getVariableName(node: TSESTree.Node): string | undefined {\n if (node.parent?.type === \"VariableDeclarator\") {\n const declarator = node.parent;\n if (declarator.id.type === \"Identifier\") {\n return declarator.id.name;\n }\n }\n if (node.parent?.type === \"Property\") {\n const prop = node.parent;\n if (prop.key.type === \"Identifier\") {\n return prop.key.name;\n }\n }\n return undefined;\n }\n\n return {\n // Check string literals\n Literal(node) {\n if (typeof node.value === \"string\") {\n const variableName = getVariableName(node);\n checkStringForSecrets(node.value, node, variableName);\n }\n },\n\n // Check template literals\n TemplateLiteral(node) {\n // Only check if no expressions (pure string)\n if (node.expressions.length === 0 && node.quasis.length === 1) {\n const value = node.quasis[0].value.raw;\n const variableName = getVariableName(node);\n checkStringForSecrets(value, node, variableName);\n }\n },\n };\n },\n});\n","/**\n * Rule: require-input-validation\n *\n * Requires API route handlers to validate request body using schema validation\n * libraries like Zod, Yup, or Joi before accessing request data.\n *\n * Examples:\n * - Bad: const { name } = await req.json()\n * - Good: const data = schema.parse(await req.json())\n */\n\nimport { createRule, defineRuleMeta } from \"../utils/create-rule.js\";\nimport type { TSESTree } from \"@typescript-eslint/utils\";\n\ntype MessageIds = \"missingValidation\" | \"unvalidatedBodyAccess\";\ntype Options = [\n {\n /** HTTP methods that require validation (default: POST, PUT, PATCH, DELETE) */\n httpMethods?: string[];\n /** File patterns that indicate API routes */\n routePatterns?: string[];\n /** Allow manual type guards/if-checks as validation */\n allowManualValidation?: boolean;\n }\n];\n\n/**\n * Rule metadata - colocated with implementation for maintainability\n */\nexport const meta = defineRuleMeta({\n id: \"require-input-validation\",\n name: \"Require Input Validation\",\n description: \"Require schema validation in API route handlers\",\n defaultSeverity: \"warn\",\n category: \"static\",\n defaultOptions: [\n {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"route.tsx\", \"/api/\", \"/app/api/\"],\n allowManualValidation: false,\n },\n ],\n optionSchema: {\n fields: [\n {\n key: \"httpMethods\",\n label: \"HTTP methods requiring validation\",\n type: \"multiselect\",\n defaultValue: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n options: [\n { value: \"GET\", label: \"GET\" },\n { value: \"POST\", label: \"POST\" },\n { value: \"PUT\", label: \"PUT\" },\n { value: \"PATCH\", label: \"PATCH\" },\n { value: \"DELETE\", label: \"DELETE\" },\n ],\n description: \"HTTP methods that require request body validation\",\n },\n {\n key: \"allowManualValidation\",\n label: \"Allow manual validation\",\n type: \"boolean\",\n defaultValue: false,\n description: \"Allow if-checks and type guards instead of schema validation\",\n },\n ],\n },\n docs: `\n## What it does\n\nEnsures that API route handlers validate request body data using a schema\nvalidation library (Zod, Yup, Joi, etc.) before accessing it.\n\n## Why it's useful\n\n- **Security**: Prevents injection attacks and malformed data\n- **Type Safety**: Ensures runtime data matches expected types\n- **Error Handling**: Provides clear validation error messages\n- **Best Practice**: Follows defense-in-depth principles\n\n## Supported Validation Libraries\n\n- Zod: \\`parse()\\`, \\`safeParse()\\`, \\`parseAsync()\\`\n- Yup: \\`validate()\\`, \\`validateSync()\\`\n- Joi: \\`validate()\\`\n- Superstruct: \\`create()\\`, \\`assert()\\`\n- io-ts: \\`decode()\\`\n- Valibot: \\`parse()\\`, \\`safeParse()\\`\n\n## Examples\n\n### ❌ Incorrect\n\n\\`\\`\\`tsx\n// Next.js App Router\nexport async function POST(request: Request) {\n const body = await request.json();\n // Body accessed without validation\n await db.users.create({ name: body.name });\n}\n\n// Next.js Pages API\nexport default function handler(req, res) {\n const { email } = req.body; // Unvalidated\n sendEmail(email);\n}\n\\`\\`\\`\n\n### ✅ Correct\n\n\\`\\`\\`tsx\nimport { z } from 'zod';\n\nconst CreateUserSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n});\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const data = CreateUserSchema.parse(body); // Validated!\n await db.users.create(data);\n}\n\\`\\`\\`\n\n## Configuration\n\n\\`\\`\\`js\n// eslint.config.js\n\"uilint/require-input-validation\": [\"warn\", {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"/api/\"],\n allowManualValidation: false\n}]\n\\`\\`\\`\n`,\n});\n\n/**\n * HTTP method names (Next.js App Router style)\n */\nconst HTTP_METHODS = [\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"HEAD\", \"OPTIONS\"];\n\n/**\n * Validation method names from common libraries\n */\nconst VALIDATION_METHODS = [\n // Zod\n \"parse\",\n \"safeParse\",\n \"parseAsync\",\n \"safeParseAsync\",\n // Yup\n \"validate\",\n \"validateSync\",\n \"validateAt\",\n \"validateSyncAt\",\n // Joi\n \"validate\",\n \"validateAsync\",\n // Superstruct\n \"create\",\n \"assert\",\n // io-ts\n \"decode\",\n // Valibot\n \"parse\",\n \"safeParse\",\n // Generic\n \"validateBody\",\n \"validateRequest\",\n \"validateInput\",\n];\n\n/**\n * Check if file matches route patterns\n */\nfunction isApiRouteFile(filename: string, patterns: string[]): boolean {\n return patterns.some((pattern) => filename.includes(pattern));\n}\n\n/**\n * Check if a function is an HTTP method handler\n */\nfunction isHttpMethodHandler(\n node: TSESTree.Node,\n methods: string[]\n): { isHandler: boolean; method: string | null } {\n // Check export function GET/POST/etc\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"FunctionDeclaration\" &&\n node.declaration.id\n ) {\n const name = node.declaration.id.name.toUpperCase();\n if (methods.includes(name)) {\n return { isHandler: true, method: name };\n }\n }\n\n // Check export const GET = async () => {}\n if (\n node.type === \"ExportNamedDeclaration\" &&\n node.declaration?.type === \"VariableDeclaration\"\n ) {\n for (const decl of node.declaration.declarations) {\n if (decl.id.type === \"Identifier\") {\n const name = decl.id.name.toUpperCase();\n if (methods.includes(name)) {\n return { isHandler: true, method: name };\n }\n }\n }\n }\n\n return { isHandler: false, method: null };\n}\n\n/**\n * Check if a call expression is a validation call\n */\nfunction isValidationCall(node: TSESTree.CallExpression): boolean {\n // Check method calls: schema.parse(), schema.validate()\n if (\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\"\n ) {\n const methodName = node.callee.property.name;\n\n // Exclude JSON.parse as it's not schema validation\n if (\n node.callee.object.type === \"Identifier\" &&\n node.callee.object.name === \"JSON\" &&\n methodName === \"parse\"\n ) {\n return false;\n }\n\n return VALIDATION_METHODS.includes(methodName);\n }\n\n // Check direct calls: validate(schema, data)\n if (node.callee.type === \"Identifier\") {\n const funcName = node.callee.name;\n return VALIDATION_METHODS.includes(funcName);\n }\n\n return false;\n}\n\n/**\n * Check if a node is a body access pattern\n */\nfunction isBodyAccess(node: TSESTree.Node): {\n isAccess: boolean;\n accessType: string | null;\n} {\n // req.body\n if (\n node.type === \"MemberExpression\" &&\n node.property.type === \"Identifier\" &&\n node.property.name === \"body\"\n ) {\n return { isAccess: true, accessType: \"req.body\" };\n }\n\n // request.json() or req.json()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"json\"\n ) {\n return { isAccess: true, accessType: \"request.json()\" };\n }\n\n // request.formData()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"formData\"\n ) {\n return { isAccess: true, accessType: \"request.formData()\" };\n }\n\n // request.text()\n if (\n node.type === \"CallExpression\" &&\n node.callee.type === \"MemberExpression\" &&\n node.callee.property.type === \"Identifier\" &&\n node.callee.property.name === \"text\"\n ) {\n return { isAccess: true, accessType: \"request.text()\" };\n }\n\n return { isAccess: false, accessType: null };\n}\n\n/**\n * Track if we're inside a validation context\n */\ninterface ValidationContext {\n hasValidation: boolean;\n bodyAccessNodes: Array<{ node: TSESTree.Node; accessType: string }>;\n}\n\nexport default createRule<Options, MessageIds>({\n name: \"require-input-validation\",\n meta: {\n type: \"problem\",\n docs: {\n description: \"Require schema validation in API route handlers\",\n },\n messages: {\n missingValidation:\n \"API route handler '{{method}}' accesses request body without validation. Use a schema validation library like Zod.\",\n unvalidatedBodyAccess:\n \"Accessing '{{accessType}}' without prior validation. Validate the data first using a schema.\",\n },\n schema: [\n {\n type: \"object\",\n properties: {\n httpMethods: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"HTTP methods that require validation\",\n },\n routePatterns: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"File patterns that indicate API routes\",\n },\n allowManualValidation: {\n type: \"boolean\",\n description: \"Allow manual type guards as validation\",\n },\n },\n additionalProperties: false,\n },\n ],\n },\n defaultOptions: [\n {\n httpMethods: [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"],\n routePatterns: [\"route.ts\", \"route.tsx\", \"/api/\", \"/app/api/\"],\n allowManualValidation: false,\n },\n ],\n create(context) {\n const options = context.options[0] || {};\n const httpMethods = (options.httpMethods ?? [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"]).map(\n (m) => m.toUpperCase()\n );\n const routePatterns = options.routePatterns ?? [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\",\n ];\n\n const filename = context.filename || context.getFilename?.() || \"\";\n\n // Only check API route files\n if (!isApiRouteFile(filename, routePatterns)) {\n return {};\n }\n\n // Track handlers and their validation status\n const handlerContexts = new Map<TSESTree.Node, ValidationContext>();\n let currentHandler: TSESTree.Node | null = null;\n let currentMethod: string | null = null;\n\n return {\n // Detect HTTP method handlers\n ExportNamedDeclaration(node) {\n const { isHandler, method } = isHttpMethodHandler(node, httpMethods);\n if (isHandler) {\n currentHandler = node;\n currentMethod = method;\n handlerContexts.set(node, {\n hasValidation: false,\n bodyAccessNodes: [],\n });\n }\n },\n\n // Track body access within handlers\n MemberExpression(node) {\n if (!currentHandler) return;\n\n const ctx = handlerContexts.get(currentHandler);\n if (!ctx) return;\n\n const { isAccess, accessType } = isBodyAccess(node);\n if (isAccess && accessType) {\n ctx.bodyAccessNodes.push({ node, accessType });\n }\n },\n\n CallExpression(node) {\n if (!currentHandler) return;\n\n const ctx = handlerContexts.get(currentHandler);\n if (!ctx) return;\n\n // Check for body access\n const { isAccess, accessType } = isBodyAccess(node);\n if (isAccess && accessType) {\n // Check if this is inside a validation call\n // e.g., schema.parse(await request.json())\n if (\n node.parent?.type === \"AwaitExpression\" &&\n node.parent.parent?.type === \"CallExpression\" &&\n isValidationCall(node.parent.parent)\n ) {\n ctx.hasValidation = true;\n return;\n }\n\n // Check if this is directly wrapped in validation\n if (\n node.parent?.type === \"CallExpression\" &&\n isValidationCall(node.parent)\n ) {\n ctx.hasValidation = true;\n return;\n }\n\n ctx.bodyAccessNodes.push({ node, accessType });\n }\n\n // Check for validation calls\n if (isValidationCall(node)) {\n ctx.hasValidation = true;\n }\n },\n\n \"ExportNamedDeclaration:exit\"(node: TSESTree.ExportNamedDeclaration) {\n const ctx = handlerContexts.get(node);\n if (!ctx) return;\n\n // If we have body access but no validation, report\n if (ctx.bodyAccessNodes.length > 0 && !ctx.hasValidation) {\n // Report on the first body access\n const firstAccess = ctx.bodyAccessNodes[0];\n context.report({\n node: firstAccess.node,\n messageId: \"unvalidatedBodyAccess\",\n data: {\n accessType: firstAccess.accessType,\n },\n });\n }\n\n // Clean up\n if (currentHandler === node) {\n currentHandler = null;\n currentMethod = null;\n }\n handlerContexts.delete(node);\n },\n };\n },\n});\n","/**\n * Rule Registry\n *\n * Central registry of all UILint ESLint rules with metadata for CLI tooling.\n * Metadata is now colocated with each rule file - this module re-exports\n * the collected metadata for use by installers and other tools.\n */\n\n// Re-export types from create-rule for consumers\nexport type {\n RuleMeta,\n RuleOptionSchema,\n OptionFieldSchema,\n} from \"./utils/create-rule.js\";\n\n// Backward compatibility alias\nexport type { RuleMeta as RuleMetadata } from \"./utils/create-rule.js\";\n\n// Import colocated metadata from each rule file\nimport { meta as noArbitraryTailwind } from \"./rules/no-arbitrary-tailwind.js\";\nimport { meta as consistentSpacing } from \"./rules/consistent-spacing.js\";\nimport { meta as consistentDarkMode } from \"./rules/consistent-dark-mode.js\";\nimport { meta as noDirectStoreImport } from \"./rules/no-direct-store-import.js\";\nimport { meta as preferZustandStateManagement } from \"./rules/prefer-zustand-state-management.js\";\nimport { meta as noMixedComponentLibraries } from \"./rules/no-mixed-component-libraries.js\";\nimport { meta as semantic } from \"./rules/semantic.js\";\nimport { meta as semanticVision } from \"./rules/semantic-vision.js\";\n\n// New rules\nimport { meta as enforceAbsoluteImports } from \"./rules/enforce-absolute-imports.js\";\nimport { meta as noAnyInProps } from \"./rules/no-any-in-props.js\";\nimport { meta as zustandUseSelectors } from \"./rules/zustand-use-selectors.js\";\nimport { meta as noSecretsInCode } from \"./rules/no-secrets-in-code.js\";\nimport { meta as requireInputValidation } from \"./rules/require-input-validation.js\";\nimport { meta as noPropDrillingDepth } from \"./rules/no-prop-drilling-depth.js\";\n\nimport type { RuleMeta } from \"./utils/create-rule.js\";\n\n/**\n * Registry of all available UILint ESLint rules\n *\n * When adding a new rule:\n * 1. Create the rule file in src/rules/\n * 2. Export a `meta` object using `defineRuleMeta()`\n * 3. Import and add the meta to this array\n * 4. Run `pnpm generate:index` to regenerate exports\n */\nexport const ruleRegistry: RuleMeta[] = [\n // Existing rules\n noArbitraryTailwind,\n consistentSpacing,\n consistentDarkMode,\n noDirectStoreImport,\n preferZustandStateManagement,\n noMixedComponentLibraries,\n semantic,\n semanticVision,\n // New UI rules\n enforceAbsoluteImports,\n noAnyInProps,\n zustandUseSelectors,\n noPropDrillingDepth,\n // New security rules\n noSecretsInCode,\n requireInputValidation,\n];\n\n/**\n * Get rule metadata by ID\n */\nexport function getRuleMetadata(id: string): RuleMeta | undefined {\n return ruleRegistry.find((rule) => rule.id === id);\n}\n\n/**\n * Get all rules in a category\n */\nexport function getRulesByCategory(\n category: \"static\" | \"semantic\"\n): RuleMeta[] {\n return ruleRegistry.filter((rule) => rule.category === category);\n}\n\n/**\n * Get documentation for a rule (useful for CLI help commands)\n */\nexport function getRuleDocs(id: string): string | undefined {\n const rule = getRuleMetadata(id);\n return rule?.docs;\n}\n\n/**\n * Get all rule IDs\n */\nexport function getAllRuleIds(): string[] {\n return ruleRegistry.map((rule) => rule.id);\n}\n","/**\n * UILint ESLint Plugin\n *\n * THIS FILE IS AUTO-GENERATED from src/rule-registry.ts.\n * Do not edit by hand. Run: pnpm -C packages/uilint-eslint generate:index\n */\n\nimport type { Linter } from \"eslint\";\nimport noArbitraryTailwind from \"./rules/no-arbitrary-tailwind.js\";\nimport consistentSpacing from \"./rules/consistent-spacing.js\";\nimport consistentDarkMode from \"./rules/consistent-dark-mode.js\";\nimport noDirectStoreImport from \"./rules/no-direct-store-import.js\";\nimport preferZustandStateManagement from \"./rules/prefer-zustand-state-management.js\";\nimport noMixedComponentLibraries from \"./rules/no-mixed-component-libraries.js\";\nimport semantic from \"./rules/semantic.js\";\nimport semanticVision from \"./rules/semantic-vision.js\";\nimport enforceAbsoluteImports from \"./rules/enforce-absolute-imports.js\";\nimport noAnyInProps from \"./rules/no-any-in-props.js\";\nimport zustandUseSelectors from \"./rules/zustand-use-selectors.js\";\nimport noPropDrillingDepth from \"./rules/no-prop-drilling-depth.js\";\nimport noSecretsInCode from \"./rules/no-secrets-in-code.js\";\nimport requireInputValidation from \"./rules/require-input-validation.js\";\n\n/**\n * All available rules\n */\nconst rules = {\n \"no-arbitrary-tailwind\": noArbitraryTailwind,\n \"consistent-spacing\": consistentSpacing,\n \"consistent-dark-mode\": consistentDarkMode,\n \"no-direct-store-import\": noDirectStoreImport,\n \"prefer-zustand-state-management\": preferZustandStateManagement,\n \"no-mixed-component-libraries\": noMixedComponentLibraries,\n \"semantic\": semantic,\n \"semantic-vision\": semanticVision,\n \"enforce-absolute-imports\": enforceAbsoluteImports,\n \"no-any-in-props\": noAnyInProps,\n \"zustand-use-selectors\": zustandUseSelectors,\n \"no-prop-drilling-depth\": noPropDrillingDepth,\n \"no-secrets-in-code\": noSecretsInCode,\n \"require-input-validation\": requireInputValidation,\n};\n\n// Package version (injected at build time or fallback)\nconst version = \"0.1.0\";\n\n/**\n * Plugin metadata\n */\nconst meta = {\n name: \"uilint\",\n version,\n};\n\n/**\n * The ESLint plugin object\n */\nconst plugin = {\n meta,\n rules,\n};\n\n/**\n * Shared language options for all configs\n */\nconst jsxLanguageOptions: Linter.Config[\"languageOptions\"] = {\n parserOptions: {\n ecmaFeatures: {\n jsx: true,\n },\n },\n};\n\n/**\n * Recommended config - static rules only\n *\n * Usage:\n * ```js\n * import uilint from 'uilint-eslint';\n * export default [uilint.configs.recommended];\n * ```\n */\nconst recommendedConfig: Linter.Config = {\n name: \"uilint/recommended\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n uilint: plugin as any,\n },\n languageOptions: jsxLanguageOptions,\n rules: {\n \"uilint/no-arbitrary-tailwind\": \"error\",\n \"uilint/consistent-spacing\": [\"warn\", ...[\n {\n \"scale\": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 8,\n 10,\n 12,\n 16\n ]\n }\n ]],\n \"uilint/consistent-dark-mode\": [\"error\", ...[\n {\n \"warnOnMissingDarkMode\": true\n }\n ]],\n \"uilint/no-direct-store-import\": [\"warn\", ...[\n {\n \"storePattern\": \"use*Store\"\n }\n ]],\n \"uilint/prefer-zustand-state-management\": [\"warn\", ...[\n {\n \"maxStateHooks\": 3,\n \"countUseState\": true,\n \"countUseReducer\": true,\n \"countUseContext\": true\n }\n ]],\n \"uilint/no-mixed-component-libraries\": [\"error\", ...[\n {\n \"preferred\": \"shadcn\",\n \"libraries\": [\n \"shadcn\",\n \"mui\"\n ]\n }\n ]],\n \"uilint/enforce-absolute-imports\": [\"warn\", ...[\n {\n \"maxRelativeDepth\": 1,\n \"aliasPrefix\": \"@/\"\n }\n ]],\n \"uilint/no-any-in-props\": [\"error\", ...[\n {\n \"checkFCGenerics\": true,\n \"allowInGenericDefaults\": false\n }\n ]],\n \"uilint/zustand-use-selectors\": [\"warn\", ...[\n {\n \"storePattern\": \"^use\\\\w*Store$\",\n \"allowShallow\": true,\n \"requireNamedSelectors\": false\n }\n ]],\n \"uilint/no-prop-drilling-depth\": [\"warn\", ...[\n {\n \"maxDepth\": 2,\n \"ignoredProps\": [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\"\n ],\n \"ignoreComponents\": []\n }\n ]],\n \"uilint/no-secrets-in-code\": [\"error\", ...[\n {\n \"checkVariableNames\": true,\n \"minSecretLength\": 16,\n \"allowInTestFiles\": false\n }\n ]],\n \"uilint/require-input-validation\": [\"warn\", ...[\n {\n \"httpMethods\": [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n ],\n \"routePatterns\": [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\"\n ],\n \"allowManualValidation\": false\n }\n ]],\n },\n};\n\n/**\n * Strict config - static rules + semantic rules\n *\n * Usage:\n * ```js\n * import uilint from 'uilint-eslint';\n * export default [uilint.configs.strict];\n * ```\n */\nconst strictConfig: Linter.Config = {\n name: \"uilint/strict\",\n plugins: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n uilint: plugin as any,\n },\n languageOptions: jsxLanguageOptions,\n rules: {\n \"uilint/no-arbitrary-tailwind\": \"error\",\n \"uilint/consistent-spacing\": [\"warn\", ...[\n {\n \"scale\": [\n 0,\n 1,\n 2,\n 3,\n 4,\n 5,\n 6,\n 8,\n 10,\n 12,\n 16\n ]\n }\n ]],\n \"uilint/consistent-dark-mode\": [\"error\", ...[\n {\n \"warnOnMissingDarkMode\": true\n }\n ]],\n \"uilint/no-direct-store-import\": [\"warn\", ...[\n {\n \"storePattern\": \"use*Store\"\n }\n ]],\n \"uilint/prefer-zustand-state-management\": [\"warn\", ...[\n {\n \"maxStateHooks\": 3,\n \"countUseState\": true,\n \"countUseReducer\": true,\n \"countUseContext\": true\n }\n ]],\n \"uilint/no-mixed-component-libraries\": [\"error\", ...[\n {\n \"preferred\": \"shadcn\",\n \"libraries\": [\n \"shadcn\",\n \"mui\"\n ]\n }\n ]],\n \"uilint/semantic\": [\"warn\", ...[\n {\n \"model\": \"qwen3-coder:30b\",\n \"styleguidePath\": \".uilint/styleguide.md\"\n }\n ]],\n \"uilint/semantic-vision\": [\"warn\", ...[\n {\n \"maxAgeMs\": 3600000,\n \"screenshotsPath\": \".uilint/screenshots\"\n }\n ]],\n \"uilint/enforce-absolute-imports\": [\"warn\", ...[\n {\n \"maxRelativeDepth\": 1,\n \"aliasPrefix\": \"@/\"\n }\n ]],\n \"uilint/no-any-in-props\": [\"error\", ...[\n {\n \"checkFCGenerics\": true,\n \"allowInGenericDefaults\": false\n }\n ]],\n \"uilint/zustand-use-selectors\": [\"warn\", ...[\n {\n \"storePattern\": \"^use\\\\w*Store$\",\n \"allowShallow\": true,\n \"requireNamedSelectors\": false\n }\n ]],\n \"uilint/no-prop-drilling-depth\": [\"warn\", ...[\n {\n \"maxDepth\": 2,\n \"ignoredProps\": [\n \"className\",\n \"style\",\n \"children\",\n \"key\",\n \"ref\",\n \"id\"\n ],\n \"ignoreComponents\": []\n }\n ]],\n \"uilint/no-secrets-in-code\": [\"error\", ...[\n {\n \"checkVariableNames\": true,\n \"minSecretLength\": 16,\n \"allowInTestFiles\": false\n }\n ]],\n \"uilint/require-input-validation\": [\"warn\", ...[\n {\n \"httpMethods\": [\n \"POST\",\n \"PUT\",\n \"PATCH\",\n \"DELETE\"\n ],\n \"routePatterns\": [\n \"route.ts\",\n \"route.tsx\",\n \"/api/\",\n \"/app/api/\"\n ],\n \"allowManualValidation\": false\n }\n ]],\n },\n};\n\n/**\n * Pre-configured configs\n */\nconst configs: Record<string, Linter.Config> = {\n recommended: recommendedConfig,\n strict: strictConfig,\n};\n\n/**\n * UILint ESLint export interface\n */\nexport interface UILintESLint {\n meta: typeof meta;\n plugin: typeof plugin;\n rules: typeof rules;\n configs: Record<string, Linter.Config>;\n}\n\n/**\n * Default export for ESLint flat config\n */\nconst uilintEslint: UILintESLint = {\n meta,\n plugin,\n rules,\n configs,\n};\n\nexport default uilintEslint;\n\n// Named exports for convenience\nexport { plugin, rules, configs, meta };\n\n// Re-export utilities for custom rule creation\nexport { createRule } from \"./utils/create-rule.js\";\nexport {\n loadStyleguide,\n findStyleguidePath,\n getStyleguide,\n} from \"./utils/styleguide-loader.js\";\nexport {\n hashContent,\n hashContentSync,\n getCacheEntry,\n setCacheEntry,\n clearCache,\n clearCacheEntry,\n loadCache,\n saveCache,\n type CacheEntry,\n type CachedIssue,\n type CacheStore,\n} from \"./utils/cache.js\";\n\n// Re-export import graph utilities (used by rules like no-mixed-component-libraries)\nexport {\n getComponentLibrary,\n clearCache as clearImportGraphCache,\n type LibraryName,\n} from \"./utils/import-graph.js\";\n\n// Re-export rule registry for CLI tooling\nexport {\n ruleRegistry,\n getRuleMetadata,\n getRulesByCategory,\n getRuleDocs,\n getAllRuleIds,\n type RuleMeta,\n type RuleMetadata, // Backward compatibility alias\n type OptionFieldSchema,\n type RuleOptionSchema,\n} from \"./rule-registry.js\";\n\n// Re-export defineRuleMeta for rule authors\nexport { defineRuleMeta } from \"./utils/create-rule.js\";\n"],"mappings":"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","names":["meta","meta","meta","checkClassString","meta","meta","isComponentName","meta","existsSync","readFileSync","dirname","join","existsSync","readFileSync","dirname","join","clearCache","existsSync","readFileSync","dirname","join","workspaceRoot","meta","dirname","readFileSync","findProjectRoot","existsSync","join","existsSync","readFileSync","dirname","join","relative","meta","findProjectRoot","existsSync","join","dirname","readFileSync","relative","meta","meta","meta","meta","isComponentName","meta","meta","meta","meta"]}