@triedotdev/mcp 1.0.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trie/vibe-code-signatures.ts"],"sourcesContent":["/**\n * Vibe Code Signatures\n * \n * Patterns commonly found in AI-generated and \"vibe coded\" projects.\n * These are issues that non-technical users encounter when using\n * AI tools like Cursor, v0, Lovable, Bolt, Replit, etc.\n * \n * Research sources:\n * - Reddit r/vibecoding (~130k members) - Andrej Karpathy's vibe coding movement\n * - Reddit r/ClaudeAI (~431k members) - Claude usage patterns\n * - Reddit r/cursor - Cursor IDE specific issues\n * - vibecodingwiki.com - Community documentation\n * - Twitter/X discussions on AI coding\n * \n * \"Vibe coding\" (coined by Andrej Karpathy, Feb 2025):\n * AI-assisted development where you describe tasks to LLMs and they generate code.\n * Focus on iterative experimentation over code correctness.\n * \n * Common issues we detect:\n * - Massive single files (1000+ line App.jsx - THE classic vibe code smell)\n * - API keys exposed in frontend (NEXT_PUBLIC_, VITE_, etc.)\n * - No error handling on fetch/axios calls\n * - No loading states (blank screens while data loads)\n * - No empty states (nothing shown when no data)\n * - Hardcoded localhost URLs that break in production\n * - Console.log debugging left everywhere\n * - TypeScript 'any' used to silence all type errors\n * - useEffect misuse (async useEffect, missing deps)\n * - No input validation on req.body\n * - Database calls directly in React components\n * - Copy-paste duplication instead of components\n * - @ts-ignore and eslint-disable to hide problems\n */\n\nimport { AhoCorasick, PatternMetadata } from './trie.js';\n\nexport interface VibeCodeMatch {\n pattern: string;\n line: number;\n column: number;\n severity: 'critical' | 'serious' | 'moderate' | 'low';\n category: string;\n description: string;\n commonMistake: string;\n fix: string;\n learnMore?: string;\n}\n\n/**\n * Vibe code anti-patterns - things AI often generates wrong\n */\nconst VIBE_CODE_PATTERNS: Array<{\n pattern: string;\n metadata: PatternMetadata & { commonMistake: string; learnMore?: string };\n}> = [\n // ============================================\n // CRITICAL: Security issues AI often creates\n // ============================================\n {\n pattern: 'NEXT_PUBLIC_',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'exposed-secrets',\n description: 'Environment variable exposed to browser',\n commonMistake: 'AI puts API keys in NEXT_PUBLIC_ variables, exposing them to users',\n fix: 'Only NEXT_PUBLIC_ for non-sensitive data. Move secrets to server-side API routes',\n learnMore: 'https://nextjs.org/docs/basic-features/environment-variables',\n },\n },\n {\n pattern: 'VITE_',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'exposed-secrets',\n description: 'Environment variable exposed to browser',\n commonMistake: 'AI puts API keys in VITE_ variables, exposing them to users',\n fix: 'Only VITE_ for non-sensitive data. Create a backend API to hide secrets',\n learnMore: 'https://vitejs.dev/guide/env-and-mode.html',\n },\n },\n {\n pattern: 'REACT_APP_',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'exposed-secrets',\n description: 'Environment variable exposed to browser',\n commonMistake: 'AI puts sensitive keys in REACT_APP_ making them visible in bundle',\n fix: 'Never put secrets in REACT_APP_. Use a backend proxy for API calls',\n },\n },\n {\n pattern: '\"sk-',\n metadata: {\n type: 'pattern',\n severity: 'critical',\n category: 'exposed-secrets',\n description: 'OpenAI API key pattern detected in string',\n commonMistake: 'AI generates code with OpenAI key in frontend - anyone can steal it!',\n fix: 'NEVER put sk- keys in frontend. Create /api/chat endpoint on server',\n },\n },\n {\n pattern: \"'sk-\",\n metadata: {\n type: 'pattern',\n severity: 'critical',\n category: 'exposed-secrets',\n description: 'OpenAI API key pattern detected in string',\n commonMistake: 'AI generates code with OpenAI key in frontend - anyone can steal it!',\n fix: 'NEVER put sk- keys in frontend. Create /api/chat endpoint on server',\n },\n },\n {\n pattern: '`sk-',\n metadata: {\n type: 'pattern',\n severity: 'critical',\n category: 'exposed-secrets',\n description: 'OpenAI API key pattern detected in template',\n commonMistake: 'AI generates code with OpenAI key in frontend - anyone can steal it!',\n fix: 'NEVER put sk- keys in frontend. Create /api/chat endpoint on server',\n },\n },\n {\n pattern: 'sk_live_',\n metadata: {\n type: 'pattern',\n severity: 'critical',\n category: 'exposed-secrets',\n description: 'Stripe live secret key detected',\n commonMistake: 'Stripe secret key in frontend = attackers can charge your account',\n fix: 'Use Stripe.js with publishable key only. Secret key stays on server',\n },\n },\n {\n pattern: 'sk_test_',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'exposed-secrets',\n description: 'Stripe test secret key in code',\n commonMistake: 'Even test keys shouldnt be in frontend - bad habit',\n fix: 'Move to environment variables on server side',\n },\n },\n\n // ============================================\n // SERIOUS: Giant file anti-patterns\n // ============================================\n {\n pattern: 'function App()',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'giant-file',\n description: 'Main App component - check file size',\n commonMistake: 'AI puts EVERYTHING in App.jsx - 1000+ lines, impossible to maintain',\n fix: 'Split into components: Header, Sidebar, MainContent, Footer, etc.',\n },\n },\n {\n pattern: 'export default function Home',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'giant-file',\n description: 'Next.js page component - check file size',\n commonMistake: 'AI dumps entire page logic in one file including API calls',\n fix: 'Extract components to /components, hooks to /hooks, API to /lib',\n },\n },\n {\n pattern: 'useState(',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'state-management',\n description: 'useState hook - check if overused',\n commonMistake: 'AI creates 20+ useState calls in one component instead of useReducer',\n fix: 'Group related state with useReducer or create custom hooks',\n },\n },\n\n // ============================================\n // No error handling\n // ============================================\n {\n pattern: 'fetch(',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'no-error-handling',\n description: 'fetch call - verify error handling exists',\n commonMistake: 'AI generates fetch() without try/catch or .catch() - app crashes on network error',\n fix: 'Wrap in try/catch, add loading state, show error message to user',\n },\n },\n {\n pattern: 'axios.',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'no-error-handling',\n description: 'axios call - verify error handling exists',\n commonMistake: 'AI uses axios without error handling or loading states',\n fix: 'Add try/catch, loading state, and user-friendly error messages',\n },\n },\n {\n pattern: '.then(',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'no-error-handling',\n description: 'Promise chain - check for .catch()',\n commonMistake: 'AI chains .then() without .catch() - silent failures',\n fix: 'Always add .catch() or use async/await with try/catch',\n },\n },\n {\n pattern: 'await ',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'no-error-handling',\n description: 'await - verify try/catch exists',\n commonMistake: 'AI uses await without try/catch wrapper',\n fix: 'Wrap async operations in try/catch blocks',\n },\n },\n\n // ============================================\n // Missing loading/empty states\n // ============================================\n {\n pattern: 'isLoading',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'loading-state',\n description: 'Loading state exists - good!',\n commonMistake: 'This is actually good! Just verify its being used',\n fix: 'Make sure to show spinner/skeleton while isLoading is true',\n },\n },\n {\n pattern: 'loading ?',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'loading-state',\n description: 'Conditional loading render',\n commonMistake: 'AI sometimes forgets the else case for loading',\n fix: 'Show meaningful loading UI, not just null',\n },\n },\n {\n pattern: '{data &&',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'empty-state',\n description: 'Conditional data render',\n commonMistake: 'AI checks if data exists but no UI for when its missing',\n fix: 'Add empty state: \"No items found\" or call-to-action',\n },\n },\n {\n pattern: '{data?.map(',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'empty-state',\n description: 'Optional chaining on map',\n commonMistake: 'Shows nothing when data is empty - confusing for users',\n fix: 'Check data.length and show \"No items yet\" message',\n },\n },\n\n // ============================================\n // Hardcoded values\n // ============================================\n {\n pattern: 'localhost:',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'hardcoded',\n description: 'Hardcoded localhost URL',\n commonMistake: 'AI hardcodes localhost:3000 URLs - breaks in production',\n fix: 'Use environment variable: process.env.NEXT_PUBLIC_API_URL',\n },\n },\n {\n pattern: 'http://localhost',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'hardcoded',\n description: 'Hardcoded localhost URL',\n commonMistake: 'Works locally, fails when deployed',\n fix: 'Use relative URLs (/api/...) or environment variables',\n },\n },\n {\n pattern: '127.0.0.1',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'hardcoded',\n description: 'Hardcoded localhost IP',\n commonMistake: 'Hardcoded local IP wont work in production',\n fix: 'Use environment variables for all URLs',\n },\n },\n\n // ============================================\n // Copy-paste code smells\n // ============================================\n {\n pattern: 'TODO',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'incomplete',\n description: 'TODO comment left behind',\n commonMistake: 'AI leaves TODO comments that never get done',\n fix: 'Either implement the TODO or remove it',\n },\n },\n {\n pattern: 'FIXME',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'incomplete',\n description: 'FIXME comment - known issue',\n commonMistake: 'AI acknowledges a problem but doesnt fix it',\n fix: 'Actually fix the issue or create a GitHub issue to track it',\n },\n },\n {\n pattern: '// eslint-disable',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'code-smell',\n description: 'ESLint rule disabled',\n commonMistake: 'AI disables linter instead of fixing the actual problem',\n fix: 'Fix the underlying issue, dont silence the linter',\n },\n },\n {\n pattern: '@ts-ignore',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'code-smell',\n description: 'TypeScript error ignored',\n commonMistake: 'AI uses @ts-ignore to hide type errors instead of fixing them',\n fix: 'Fix the type error properly or use @ts-expect-error with explanation',\n },\n },\n {\n pattern: '@ts-nocheck',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'code-smell',\n description: 'TypeScript checking disabled for entire file',\n commonMistake: 'AI disables all type checking - defeats the purpose of TypeScript',\n fix: 'Remove @ts-nocheck and fix type errors one by one',\n },\n },\n {\n pattern: ': any',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'code-smell',\n description: 'any type used',\n commonMistake: 'AI uses \"any\" to avoid writing proper types',\n fix: 'Define proper interfaces/types for your data',\n },\n },\n {\n pattern: 'as any',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'code-smell',\n description: 'Type assertion to any',\n commonMistake: 'AI casts to \"any\" to silence type errors',\n fix: 'Use proper type narrowing or define correct types',\n },\n },\n\n // ============================================\n // Debug code left in\n // ============================================\n {\n pattern: 'console.log(',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'debug-code',\n description: 'console.log left in code',\n commonMistake: 'AI adds console.log for debugging, forgets to remove',\n fix: 'Remove before production or use proper logging library',\n },\n },\n {\n pattern: 'console.error(',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'debug-code',\n description: 'console.error in code',\n commonMistake: 'Error logging is fine but should use proper error tracking',\n fix: 'Consider using Sentry, LogRocket, or similar for production',\n },\n },\n {\n pattern: 'debugger',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'debug-code',\n description: 'debugger statement left in code',\n commonMistake: 'AI leaves debugger statements - freezes browser in production!',\n fix: 'Remove all debugger statements before deploying',\n },\n },\n\n // ============================================\n // Bad practices specific to frameworks\n // ============================================\n {\n pattern: 'useEffect(() => {',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'react-antipattern',\n description: 'useEffect usage - verify necessity',\n commonMistake: 'AI overuses useEffect for things that dont need it',\n fix: 'Consider: Is this really a side effect? Could use useMemo, derived state, or event handler instead?',\n learnMore: 'https://react.dev/learn/you-might-not-need-an-effect',\n },\n },\n {\n pattern: 'useEffect(async',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'react-antipattern',\n description: 'async useEffect - incorrect pattern',\n commonMistake: 'AI makes useEffect async directly - causes warnings and bugs',\n fix: 'Define async function inside useEffect, then call it',\n },\n },\n {\n pattern: ', [])',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'react-antipattern',\n description: 'Empty dependency array',\n commonMistake: 'AI uses [] to \"fix\" useEffect warnings without understanding why',\n fix: 'Verify all dependencies are listed, or intentionally run once',\n },\n },\n {\n pattern: 'key={index}',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'react-antipattern',\n description: 'Array index used as key',\n commonMistake: 'AI uses array index as key - causes bugs with reordering/filtering',\n fix: 'Use unique identifier from data: key={item.id}',\n },\n },\n {\n pattern: 'key={i}',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'react-antipattern',\n description: 'Loop index used as key',\n commonMistake: 'Using loop index as key breaks React reconciliation',\n fix: 'Use unique identifier: key={item.id} or key={item.slug}',\n },\n },\n\n // ============================================\n // No input validation\n // ============================================\n {\n pattern: 'req.body.',\n metadata: {\n type: 'pattern',\n severity: 'serious',\n category: 'no-validation',\n description: 'Request body accessed directly',\n commonMistake: 'AI trusts user input without validation - security risk!',\n fix: 'Validate with Zod, Yup, or joi before using req.body',\n },\n },\n {\n pattern: 'req.query.',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'no-validation',\n description: 'Query param accessed directly',\n commonMistake: 'AI doesnt validate query parameters',\n fix: 'Validate and sanitize query parameters before use',\n },\n },\n {\n pattern: 'req.params.',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'no-validation',\n description: 'URL param accessed directly',\n commonMistake: 'AI trusts URL parameters without validation',\n fix: 'Validate params (especially IDs) before database queries',\n },\n },\n\n // ============================================\n // Mixing concerns (DB in components)\n // ============================================\n {\n pattern: 'prisma.',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'mixing-concerns',\n description: 'Prisma in component/page',\n commonMistake: 'AI puts database calls directly in React components',\n fix: 'Move to API routes, server actions, or /lib/db.ts',\n },\n },\n {\n pattern: 'mongoose.',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'mixing-concerns',\n description: 'Mongoose in component',\n commonMistake: 'Database logic mixed with UI code',\n fix: 'Create separate /lib/db.ts or /services/ for data access',\n },\n },\n {\n pattern: 'supabase.',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'mixing-concerns',\n description: 'Supabase client usage',\n commonMistake: 'AI puts Supabase calls everywhere instead of centralizing',\n fix: 'Create /lib/supabase.ts with helper functions',\n },\n },\n\n // ============================================\n // Common AI oversights\n // ============================================\n {\n pattern: 'onClick={() =>',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'performance',\n description: 'Inline arrow function in onClick',\n commonMistake: 'AI creates new function on every render',\n fix: 'For simple cases its fine, but consider useCallback for expensive components',\n },\n },\n {\n pattern: 'style={{',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'performance',\n description: 'Inline style object',\n commonMistake: 'AI uses inline styles creating new objects every render',\n fix: 'Use CSS classes, Tailwind, or define styles outside component',\n },\n },\n {\n pattern: 'new Date()',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'dates',\n description: 'Date creation',\n commonMistake: 'AI uses new Date() without considering timezones',\n fix: 'Consider timezone handling, use date-fns or dayjs for complex date logic',\n },\n },\n\n // ============================================\n // Vibe coding specific patterns (r/vibecoding)\n // ============================================\n {\n pattern: 'just works',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'vibe-smell',\n description: 'Comment suggesting \"it just works\"',\n commonMistake: 'Classic vibe coding - accepting code without understanding it',\n fix: 'Take time to understand WHY it works, or it will break later',\n },\n },\n {\n pattern: 'idk why',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'vibe-smell',\n description: 'Comment admitting confusion',\n commonMistake: 'AI generated something you dont understand - tech debt waiting to happen',\n fix: 'Ask the AI to explain what this code does and why',\n },\n },\n {\n pattern: 'dont touch',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'vibe-smell',\n description: 'Warning comment about fragile code',\n commonMistake: 'Code that \"works but nobody knows how\" - very fragile',\n fix: 'Refactor this section or at least document what it does',\n },\n },\n {\n pattern: '// ai generated',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'vibe-smell',\n description: 'AI generated code marker',\n commonMistake: 'At least you labeled it! But did you review it?',\n fix: 'Review AI-generated code for security issues and edge cases',\n },\n },\n {\n pattern: '// cursor',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'vibe-smell',\n description: 'Cursor-generated code marker',\n commonMistake: 'Marked as Cursor-generated - make sure to review',\n fix: 'Verify the logic is correct and handles errors properly',\n },\n },\n {\n pattern: '// copilot',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'vibe-smell',\n description: 'Copilot-generated code marker',\n commonMistake: 'Copilot suggestion accepted without review',\n fix: 'Always review Copilot suggestions for correctness',\n },\n },\n\n // ============================================\n // Deployment/Production issues\n // ============================================\n {\n pattern: 'npm run dev',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'deployment',\n description: 'Dev script reference',\n commonMistake: 'Make sure you also have build and start scripts for production',\n fix: 'Verify you can run: npm run build && npm start',\n },\n },\n {\n pattern: 'development',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'deployment',\n description: 'Development mode reference',\n commonMistake: 'Ensure dev-only code doesnt run in production',\n fix: 'Check NODE_ENV and use proper environment detection',\n },\n },\n {\n pattern: '.env.local',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'deployment',\n description: 'Local env file reference',\n commonMistake: 'Local env works, but did you set up production env vars?',\n fix: 'Set up environment variables in your deployment platform',\n },\n },\n\n // ============================================\n // Common LLM hallucination patterns\n // ============================================\n {\n pattern: 'import { something }',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'hallucination',\n description: 'Named import - verify it exists',\n commonMistake: 'AI sometimes imports functions that dont exist in the library',\n fix: 'If you get \"X is not exported\" error, check library docs',\n },\n },\n {\n pattern: 'v3',\n metadata: {\n type: 'pattern',\n severity: 'low',\n category: 'hallucination',\n description: 'Version number in code',\n commonMistake: 'AI may use outdated API patterns from old library versions',\n fix: 'Check you are using the correct API for your installed version',\n },\n },\n\n // ============================================\n // Quick prototyping shortcuts that become problems\n // ============================================\n {\n pattern: 'setTimeout(',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'timing-hack',\n description: 'setTimeout usage',\n commonMistake: 'AI uses setTimeout to \"fix\" race conditions instead of proper async',\n fix: 'Use proper async/await, promises, or state management instead',\n },\n },\n {\n pattern: 'sleep(',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'timing-hack',\n description: 'Sleep function usage',\n commonMistake: 'Artificial delays hide real timing issues',\n fix: 'Fix the underlying race condition instead of adding delays',\n },\n },\n {\n pattern: 'window.location.reload',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'hack',\n description: 'Page reload to \"fix\" state issues',\n commonMistake: 'AI reloads page instead of properly managing state',\n fix: 'Fix state management - reloading is bad UX',\n },\n },\n {\n pattern: 'force: true',\n metadata: {\n type: 'pattern',\n severity: 'moderate',\n category: 'hack',\n description: 'Force flag usage',\n commonMistake: 'AI uses force flags to bypass checks instead of fixing root cause',\n fix: 'Understand why the check exists before bypassing it',\n },\n },\n];\n\n/**\n * File-level checks (not pattern based, but size/structure based)\n */\nexport interface FileLevelIssue {\n file: string;\n issue: string;\n severity: 'critical' | 'serious' | 'moderate' | 'low';\n category: string;\n commonMistake: string;\n fix: string;\n}\n\nexport function checkFileLevelIssues(filePath: string, content: string): FileLevelIssue[] {\n const issues: FileLevelIssue[] = [];\n const lines = content.split('\\n');\n const lineCount = lines.length;\n const fileName = filePath.split('/').pop() || '';\n\n // Giant file check\n if (lineCount > 500) {\n issues.push({\n file: filePath,\n issue: `File has ${lineCount} lines - way too big!`,\n severity: lineCount > 1000 ? 'serious' : 'moderate',\n category: 'giant-file',\n commonMistake: 'AI dumps everything in one file. Reddit is FULL of posts about 2000 line App.jsx files',\n fix: `Split into smaller files. Rule of thumb: components < 200 lines, pages < 300 lines`,\n });\n }\n\n // Too many useState\n const useStateCount = (content.match(/useState\\(/g) || []).length;\n if (useStateCount > 10) {\n issues.push({\n file: filePath,\n issue: `${useStateCount} useState hooks in one component`,\n severity: useStateCount > 15 ? 'serious' : 'moderate',\n category: 'state-explosion',\n commonMistake: 'AI creates separate useState for every field instead of grouping',\n fix: 'Group related state into objects, or use useReducer for complex state',\n });\n }\n\n // Too many useEffect\n const useEffectCount = (content.match(/useEffect\\(/g) || []).length;\n if (useEffectCount > 5) {\n issues.push({\n file: filePath,\n issue: `${useEffectCount} useEffect hooks - probably too many`,\n severity: 'moderate',\n category: 'effect-hell',\n commonMistake: 'AI creates useEffect for everything. Most effects are unnecessary',\n fix: 'Review each useEffect - many can be replaced with event handlers or derived state',\n });\n }\n\n // Main file patterns\n if (/^(App|app|main|Main|index|page)\\.(jsx?|tsx?)$/.test(fileName) && lineCount > 300) {\n issues.push({\n file: filePath,\n issue: `Main entry file is ${lineCount} lines`,\n severity: 'serious',\n category: 'giant-main',\n commonMistake: 'Classic AI pattern: everything in App.jsx or page.tsx',\n fix: 'Extract: Header, Footer, Sidebar, MainContent as separate components',\n });\n }\n\n // No TypeScript types\n if (filePath.endsWith('.tsx') || filePath.endsWith('.ts')) {\n const anyCount = (content.match(/:\\s*any\\b/g) || []).length;\n if (anyCount > 5) {\n issues.push({\n file: filePath,\n issue: `${anyCount} uses of \"any\" type`,\n severity: 'moderate',\n category: 'weak-typing',\n commonMistake: 'AI uses \"any\" to avoid writing proper types',\n fix: 'Define interfaces for your data shapes. AI can help: \"Generate types for this data\"',\n });\n }\n }\n\n // Console.log density\n const consoleLogCount = (content.match(/console\\.(log|warn|error|debug)/g) || []).length;\n if (consoleLogCount > 10) {\n issues.push({\n file: filePath,\n issue: `${consoleLogCount} console statements - cleanup needed`,\n severity: 'low',\n category: 'debug-code',\n commonMistake: 'AI adds console.log for debugging, user never removes them',\n fix: 'Remove debug logs before deploying. Use proper error tracking for production.',\n });\n }\n\n return issues;\n}\n\n/**\n * Build the vibe code trie\n */\nlet vibeCodeTrie: AhoCorasick<PatternMetadata & { commonMistake: string }> | null = null;\n\nexport function getVibeCodeTrie(): AhoCorasick<PatternMetadata & { commonMistake: string }> {\n if (!vibeCodeTrie) {\n vibeCodeTrie = new AhoCorasick<PatternMetadata & { commonMistake: string }>();\n \n for (const { pattern, metadata } of VIBE_CODE_PATTERNS) {\n vibeCodeTrie.addPattern(pattern, metadata, metadata);\n }\n \n vibeCodeTrie.build();\n console.error(` 🎯 Loaded ${VIBE_CODE_PATTERNS.length} vibe-code patterns into trie`);\n }\n \n return vibeCodeTrie;\n}\n\n/**\n * Files/patterns to exclude from vibe code checks\n */\nconst VIBE_EXCLUDED_PATTERNS = [\n /package-lock\\.json$/,\n /yarn\\.lock$/,\n /pnpm-lock\\.yaml$/,\n /node_modules\\//,\n /\\.min\\.[jt]s$/,\n /dist\\//,\n /build\\//,\n /\\.d\\.ts$/,\n];\n\n/**\n * Check if a file should be excluded from vibe code scans\n */\nfunction shouldExcludeVibeFile(filePath: string): boolean {\n return VIBE_EXCLUDED_PATTERNS.some(pattern => pattern.test(filePath));\n}\n\n/**\n * Check if line is a false positive for vibe patterns\n */\nfunction isVibeFalsePositive(line: string, pattern: string, filePath: string, category: string): boolean {\n const trimmedLine = line.trim();\n \n // Skip comments\n if (trimmedLine.startsWith('//') || \n trimmedLine.startsWith('*') || \n trimmedLine.startsWith('/*') ||\n trimmedLine.startsWith('#')) {\n return true;\n }\n \n // Skip type definitions\n if (/^\\s*(interface|type|export\\s+interface|export\\s+type)\\s/.test(line)) {\n return true;\n }\n \n // Skip when reading from environment\n if (/process\\.env|import\\.meta\\.env/.test(line)) {\n // Allow NEXT_PUBLIC_, VITE_, REACT_APP_ when reading env\n if (['exposed-secrets'].includes(category) && !/=\\s*['\"`]/.test(line)) {\n return true;\n }\n }\n \n // Pattern-specific false positive detection\n switch (pattern) {\n case 'console.log(':\n case 'console.error(':\n // Allow in development/debug files\n if (/debug|dev|development/i.test(filePath)) return true;\n // Allow console.error for error handling\n if (pattern === 'console.error(') return true;\n break;\n \n case 'useState(':\n // Low severity, only flag if excessive (handled by file-level checks)\n return true; // Don't flag individual useState\n \n case 'await ':\n // Very common, only flag if there's obvious missing try/catch\n // Let the file-level check handle this\n return true;\n \n case '.then(':\n // Only flag if no .catch in nearby context\n return true; // Too noisy, disable\n \n case 'TODO':\n case 'FIXME':\n // These are intentional markers, low priority\n break;\n \n case 'useEffect(() => {':\n // Very common, only flag excessive usage via file-level checks\n return true;\n \n case ', [])':\n // Common and often correct, disable as too noisy\n return true;\n \n case 'development':\n // Too generic\n return true;\n \n case 'import { something }':\n // Way too generic, disable\n return true;\n \n case 'v3':\n // Too generic\n return true;\n \n case 'new Date()':\n // Very common and usually fine\n return true;\n \n case 'style={{':\n case 'onClick={() =>':\n // Common patterns, not always a problem\n return true;\n }\n \n // Skip test files for most patterns\n if (/\\.(test|spec)\\.[jt]sx?$/.test(filePath) || /__tests__\\//.test(filePath)) {\n // Only keep critical patterns (exposed secrets) in test files\n if (!['exposed-secrets'].includes(category)) {\n return true;\n }\n }\n \n return false;\n}\n\n/**\n * Scan for vibe code issues\n */\nexport function scanForVibeCodeIssues(code: string, filePath: string): VibeCodeMatch[] {\n // Skip excluded files entirely\n if (shouldExcludeVibeFile(filePath)) {\n return [];\n }\n \n const trie = getVibeCodeTrie();\n const rawMatches = trie.search(code);\n const lines = code.split('\\n');\n \n const matches: VibeCodeMatch[] = [];\n const seen = new Set<string>();\n \n for (const match of rawMatches) {\n const key = `${match.line}:${match.pattern}`;\n if (seen.has(key)) continue;\n seen.add(key);\n \n const line = lines[match.line - 1] || '';\n const meta = match.metadata as any;\n const category = meta.category || 'unknown';\n \n // Check for false positives\n if (isVibeFalsePositive(line, match.pattern, filePath, category)) continue;\n \n matches.push({\n pattern: match.pattern,\n line: match.line,\n column: match.column,\n severity: meta.severity,\n category,\n description: meta.description || '',\n commonMistake: meta.commonMistake || '',\n fix: meta.fix || '',\n learnMore: meta.learnMore,\n });\n }\n \n return matches;\n}\n\n/**\n * Get vibe code pattern statistics\n */\nexport function getVibeCodeStats(): { total: number; byCategory: Record<string, number> } {\n const byCategory: Record<string, number> = {};\n \n for (const { metadata } of VIBE_CODE_PATTERNS) {\n const cat = metadata.category || 'unknown';\n byCategory[cat] = (byCategory[cat] || 0) + 1;\n }\n \n return {\n total: VIBE_CODE_PATTERNS.length,\n byCategory,\n };\n}\n\n"],"mappings":"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","names":[]}
@@ -0,0 +1,344 @@
1
+ // src/trie/trie.ts
2
+ var Trie = class _Trie {
3
+ root;
4
+ size = 0;
5
+ constructor() {
6
+ this.root = this.createNode();
7
+ }
8
+ createNode() {
9
+ return {
10
+ children: /* @__PURE__ */ new Map(),
11
+ isEnd: false
12
+ };
13
+ }
14
+ /**
15
+ * Insert a pattern into the trie
16
+ * O(m) where m = pattern length
17
+ */
18
+ insert(pattern, value, metadata) {
19
+ let node = this.root;
20
+ for (const char of pattern) {
21
+ if (!node.children.has(char)) {
22
+ node.children.set(char, this.createNode());
23
+ }
24
+ node = node.children.get(char);
25
+ }
26
+ node.isEnd = true;
27
+ if (value !== void 0) {
28
+ node.value = value;
29
+ }
30
+ if (metadata !== void 0) {
31
+ node.metadata = metadata;
32
+ }
33
+ this.size++;
34
+ }
35
+ /**
36
+ * Search for an exact pattern
37
+ * O(m) where m = pattern length
38
+ */
39
+ search(pattern) {
40
+ let node = this.root;
41
+ for (const char of pattern) {
42
+ if (!node.children.has(char)) {
43
+ return { found: false };
44
+ }
45
+ node = node.children.get(char);
46
+ }
47
+ const result = {
48
+ found: node.isEnd
49
+ };
50
+ if (node.value !== void 0) {
51
+ result.value = node.value;
52
+ }
53
+ if (node.metadata !== void 0) {
54
+ result.metadata = node.metadata;
55
+ }
56
+ return result;
57
+ }
58
+ /**
59
+ * Check if any pattern starts with the given prefix
60
+ * O(m) where m = prefix length
61
+ */
62
+ startsWith(prefix) {
63
+ let node = this.root;
64
+ for (const char of prefix) {
65
+ if (!node.children.has(char)) {
66
+ return false;
67
+ }
68
+ node = node.children.get(char);
69
+ }
70
+ return true;
71
+ }
72
+ /**
73
+ * Find all patterns that match within the given text
74
+ * Uses Aho-Corasick-like multi-pattern matching
75
+ * O(n + m) where n = text length, m = total matches
76
+ */
77
+ findAllMatches(text) {
78
+ const matches = [];
79
+ const lines = text.split("\n");
80
+ let globalPos = 0;
81
+ for (let lineNum = 0; lineNum < lines.length; lineNum++) {
82
+ const line = lines[lineNum];
83
+ for (let i = 0; i < line.length; i++) {
84
+ let node = this.root;
85
+ let matchLen = 0;
86
+ let j = i;
87
+ while (j < line.length && node.children.has(line[j])) {
88
+ node = node.children.get(line[j]);
89
+ matchLen++;
90
+ j++;
91
+ if (node.isEnd) {
92
+ const matchResult = {
93
+ pattern: line.substring(i, i + matchLen),
94
+ position: globalPos + i,
95
+ line: lineNum + 1,
96
+ column: i + 1
97
+ };
98
+ if (node.value !== void 0) {
99
+ matchResult.value = node.value;
100
+ }
101
+ if (node.metadata !== void 0) {
102
+ matchResult.metadata = node.metadata;
103
+ }
104
+ matches.push(matchResult);
105
+ }
106
+ }
107
+ }
108
+ globalPos += line.length + 1;
109
+ }
110
+ return matches;
111
+ }
112
+ /**
113
+ * Find the longest matching prefix at a position
114
+ * O(m) where m = longest pattern length
115
+ */
116
+ findLongestMatch(text, startPos = 0) {
117
+ let node = this.root;
118
+ let lastMatch = null;
119
+ let matchLen = 0;
120
+ for (let i = startPos; i < text.length; i++) {
121
+ const char = text[i];
122
+ if (!node.children.has(char)) {
123
+ break;
124
+ }
125
+ node = node.children.get(char);
126
+ matchLen++;
127
+ if (node.isEnd) {
128
+ lastMatch = {
129
+ pattern: text.substring(startPos, startPos + matchLen),
130
+ position: startPos,
131
+ line: this.getLineNumber(text, startPos),
132
+ column: this.getColumnNumber(text, startPos)
133
+ };
134
+ if (node.value !== void 0) {
135
+ lastMatch.value = node.value;
136
+ }
137
+ if (node.metadata !== void 0) {
138
+ lastMatch.metadata = node.metadata;
139
+ }
140
+ }
141
+ }
142
+ return lastMatch;
143
+ }
144
+ /**
145
+ * Get all patterns with a given prefix
146
+ * O(p + n) where p = prefix length, n = number of matches
147
+ */
148
+ getWithPrefix(prefix) {
149
+ let node = this.root;
150
+ for (const char of prefix) {
151
+ if (!node.children.has(char)) {
152
+ return [];
153
+ }
154
+ node = node.children.get(char);
155
+ }
156
+ const results = [];
157
+ this.collectPatterns(node, prefix, results);
158
+ return results;
159
+ }
160
+ collectPatterns(node, prefix, results) {
161
+ if (node.isEnd) {
162
+ const entry = { pattern: prefix };
163
+ if (node.value !== void 0) {
164
+ entry.value = node.value;
165
+ }
166
+ if (node.metadata !== void 0) {
167
+ entry.metadata = node.metadata;
168
+ }
169
+ results.push(entry);
170
+ }
171
+ for (const [char, child] of node.children) {
172
+ this.collectPatterns(child, prefix + char, results);
173
+ }
174
+ }
175
+ getLineNumber(text, position) {
176
+ let line = 1;
177
+ for (let i = 0; i < position && i < text.length; i++) {
178
+ if (text[i] === "\n") line++;
179
+ }
180
+ return line;
181
+ }
182
+ getColumnNumber(text, position) {
183
+ let column = 1;
184
+ for (let i = position - 1; i >= 0 && text[i] !== "\n"; i--) {
185
+ column++;
186
+ }
187
+ return column;
188
+ }
189
+ /**
190
+ * Get the number of patterns in the trie
191
+ */
192
+ getSize() {
193
+ return this.size;
194
+ }
195
+ /**
196
+ * Clear all patterns
197
+ */
198
+ clear() {
199
+ this.root = this.createNode();
200
+ this.size = 0;
201
+ }
202
+ /**
203
+ * Serialize trie to JSON for persistence
204
+ */
205
+ toJSON() {
206
+ return this.serializeNode(this.root);
207
+ }
208
+ serializeNode(node) {
209
+ const children = {};
210
+ for (const [char, child] of node.children) {
211
+ children[char] = this.serializeNode(child);
212
+ }
213
+ return {
214
+ children,
215
+ isEnd: node.isEnd,
216
+ value: node.value,
217
+ metadata: node.metadata
218
+ };
219
+ }
220
+ /**
221
+ * Load trie from JSON
222
+ */
223
+ static fromJSON(json) {
224
+ const trie = new _Trie();
225
+ trie.root = trie.deserializeNode(json);
226
+ return trie;
227
+ }
228
+ deserializeNode(data) {
229
+ const node = this.createNode();
230
+ node.isEnd = data.isEnd;
231
+ node.value = data.value;
232
+ node.metadata = data.metadata;
233
+ for (const [char, childData] of Object.entries(data.children)) {
234
+ node.children.set(char, this.deserializeNode(childData));
235
+ }
236
+ return node;
237
+ }
238
+ };
239
+ var AhoCorasick = class {
240
+ root;
241
+ built = false;
242
+ constructor() {
243
+ this.root = this.createNode();
244
+ }
245
+ createNode() {
246
+ return {
247
+ children: /* @__PURE__ */ new Map(),
248
+ fail: null,
249
+ output: []
250
+ };
251
+ }
252
+ /**
253
+ * Add a pattern to the automaton
254
+ */
255
+ addPattern(pattern, value, metadata) {
256
+ let node = this.root;
257
+ for (const char of pattern) {
258
+ if (!node.children.has(char)) {
259
+ node.children.set(char, this.createNode());
260
+ }
261
+ node = node.children.get(char);
262
+ }
263
+ const outputEntry = { pattern };
264
+ if (value !== void 0) {
265
+ outputEntry.value = value;
266
+ }
267
+ if (metadata !== void 0) {
268
+ outputEntry.metadata = metadata;
269
+ }
270
+ node.output.push(outputEntry);
271
+ this.built = false;
272
+ }
273
+ /**
274
+ * Build failure links (call after adding all patterns)
275
+ */
276
+ build() {
277
+ const queue = [];
278
+ for (const child of this.root.children.values()) {
279
+ child.fail = this.root;
280
+ queue.push(child);
281
+ }
282
+ while (queue.length > 0) {
283
+ const current = queue.shift();
284
+ for (const [char, child] of current.children) {
285
+ queue.push(child);
286
+ let fail = current.fail;
287
+ while (fail !== null && !fail.children.has(char)) {
288
+ fail = fail.fail;
289
+ }
290
+ child.fail = fail ? fail.children.get(char) : this.root;
291
+ if (child.fail !== this.root) {
292
+ child.output = [...child.output, ...child.fail.output];
293
+ }
294
+ }
295
+ }
296
+ this.built = true;
297
+ }
298
+ /**
299
+ * Search text for all pattern matches
300
+ * O(n + z) where n = text length, z = number of matches
301
+ */
302
+ search(text) {
303
+ if (!this.built) {
304
+ this.build();
305
+ }
306
+ const matches = [];
307
+ let node = this.root;
308
+ let line = 1;
309
+ let lineStart = 0;
310
+ for (let i = 0; i < text.length; i++) {
311
+ const char = text[i];
312
+ if (char === "\n") {
313
+ line++;
314
+ lineStart = i + 1;
315
+ }
316
+ while (node !== this.root && !node.children.has(char)) {
317
+ node = node.fail || this.root;
318
+ }
319
+ node = node.children.get(char) || this.root;
320
+ for (const output of node.output) {
321
+ const matchResult = {
322
+ pattern: output.pattern,
323
+ position: i - output.pattern.length + 1,
324
+ line,
325
+ column: i - output.pattern.length + 1 - lineStart + 1
326
+ };
327
+ if (output.value !== void 0) {
328
+ matchResult.value = output.value;
329
+ }
330
+ if (output.metadata !== void 0) {
331
+ matchResult.metadata = output.metadata;
332
+ }
333
+ matches.push(matchResult);
334
+ }
335
+ }
336
+ return matches;
337
+ }
338
+ };
339
+
340
+ export {
341
+ Trie,
342
+ AhoCorasick
343
+ };
344
+ //# sourceMappingURL=chunk-6NLHFIYA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/trie/trie.ts"],"sourcesContent":["/**\n * Trie Data Structure\n * \n * A prefix tree for O(m) pattern matching where m = pattern length.\n * Used for:\n * - Fast vulnerability signature matching\n * - Code symbol indexing\n * - Pattern-based triaging\n */\n\nexport interface TrieNode<T = any> {\n children: Map<string, TrieNode<T>>;\n isEnd: boolean;\n value?: T;\n // For pattern matching - store metadata about what this pattern means\n metadata?: PatternMetadata;\n}\n\nexport interface PatternMetadata {\n type: 'vulnerability' | 'symbol' | 'pattern' | 'keyword';\n severity?: 'critical' | 'serious' | 'moderate' | 'low';\n category?: string;\n description?: string;\n cwe?: string;\n fix?: string;\n}\n\nexport interface MatchResult<T = any> {\n pattern: string;\n position: number;\n line: number;\n column: number;\n value?: T;\n metadata?: PatternMetadata;\n}\n\n/**\n * Core Trie implementation with pattern matching\n */\nexport class Trie<T = any> {\n private root: TrieNode<T>;\n private size: number = 0;\n\n constructor() {\n this.root = this.createNode();\n }\n\n private createNode(): TrieNode<T> {\n return {\n children: new Map(),\n isEnd: false,\n };\n }\n\n /**\n * Insert a pattern into the trie\n * O(m) where m = pattern length\n */\n insert(pattern: string, value?: T, metadata?: PatternMetadata): void {\n let node = this.root;\n\n for (const char of pattern) {\n if (!node.children.has(char)) {\n node.children.set(char, this.createNode());\n }\n node = node.children.get(char)!;\n }\n\n node.isEnd = true;\n if (value !== undefined) {\n node.value = value;\n }\n if (metadata !== undefined) {\n node.metadata = metadata;\n }\n this.size++;\n }\n\n /**\n * Search for an exact pattern\n * O(m) where m = pattern length\n */\n search(pattern: string): { found: boolean; value?: T; metadata?: PatternMetadata } {\n let node = this.root;\n\n for (const char of pattern) {\n if (!node.children.has(char)) {\n return { found: false };\n }\n node = node.children.get(char)!;\n }\n\n const result: { found: boolean; value?: T; metadata?: PatternMetadata } = {\n found: node.isEnd,\n };\n if (node.value !== undefined) {\n result.value = node.value;\n }\n if (node.metadata !== undefined) {\n result.metadata = node.metadata;\n }\n return result;\n }\n\n /**\n * Check if any pattern starts with the given prefix\n * O(m) where m = prefix length\n */\n startsWith(prefix: string): boolean {\n let node = this.root;\n\n for (const char of prefix) {\n if (!node.children.has(char)) {\n return false;\n }\n node = node.children.get(char)!;\n }\n\n return true;\n }\n\n /**\n * Find all patterns that match within the given text\n * Uses Aho-Corasick-like multi-pattern matching\n * O(n + m) where n = text length, m = total matches\n */\n findAllMatches(text: string): MatchResult<T>[] {\n const matches: MatchResult<T>[] = [];\n const lines = text.split('\\n');\n \n let globalPos = 0;\n\n for (let lineNum = 0; lineNum < lines.length; lineNum++) {\n const line = lines[lineNum]!;\n \n // Try matching at each position in the line\n for (let i = 0; i < line.length; i++) {\n let node = this.root;\n let matchLen = 0;\n let j = i;\n\n // Walk the trie as far as we can\n while (j < line.length && node.children.has(line[j]!)) {\n node = node.children.get(line[j]!)!;\n matchLen++;\n j++;\n\n // Check if we found a complete pattern\n if (node.isEnd) {\n const matchResult: MatchResult<T> = {\n pattern: line.substring(i, i + matchLen),\n position: globalPos + i,\n line: lineNum + 1,\n column: i + 1,\n };\n if (node.value !== undefined) {\n matchResult.value = node.value;\n }\n if (node.metadata !== undefined) {\n matchResult.metadata = node.metadata;\n }\n matches.push(matchResult);\n }\n }\n }\n\n globalPos += line.length + 1; // +1 for newline\n }\n\n return matches;\n }\n\n /**\n * Find the longest matching prefix at a position\n * O(m) where m = longest pattern length\n */\n findLongestMatch(text: string, startPos: number = 0): MatchResult<T> | null {\n let node = this.root;\n let lastMatch: MatchResult<T> | null = null;\n let matchLen = 0;\n\n for (let i = startPos; i < text.length; i++) {\n const char = text[i]!;\n \n if (!node.children.has(char)) {\n break;\n }\n\n node = node.children.get(char)!;\n matchLen++;\n\n if (node.isEnd) {\n lastMatch = {\n pattern: text.substring(startPos, startPos + matchLen),\n position: startPos,\n line: this.getLineNumber(text, startPos),\n column: this.getColumnNumber(text, startPos),\n };\n if (node.value !== undefined) {\n lastMatch.value = node.value;\n }\n if (node.metadata !== undefined) {\n lastMatch.metadata = node.metadata;\n }\n }\n }\n\n return lastMatch;\n }\n\n /**\n * Get all patterns with a given prefix\n * O(p + n) where p = prefix length, n = number of matches\n */\n getWithPrefix(prefix: string): Array<{ pattern: string; value?: T; metadata?: PatternMetadata }> {\n let node = this.root;\n\n // Navigate to prefix node\n for (const char of prefix) {\n if (!node.children.has(char)) {\n return [];\n }\n node = node.children.get(char)!;\n }\n\n // Collect all patterns under this prefix\n const results: Array<{ pattern: string; value?: T; metadata?: PatternMetadata }> = [];\n this.collectPatterns(node, prefix, results);\n return results;\n }\n\n private collectPatterns(\n node: TrieNode<T>,\n prefix: string,\n results: Array<{ pattern: string; value?: T; metadata?: PatternMetadata }>\n ): void {\n if (node.isEnd) {\n const entry: { pattern: string; value?: T; metadata?: PatternMetadata } = { pattern: prefix };\n if (node.value !== undefined) {\n entry.value = node.value;\n }\n if (node.metadata !== undefined) {\n entry.metadata = node.metadata;\n }\n results.push(entry);\n }\n\n for (const [char, child] of node.children) {\n this.collectPatterns(child, prefix + char, results);\n }\n }\n\n private getLineNumber(text: string, position: number): number {\n let line = 1;\n for (let i = 0; i < position && i < text.length; i++) {\n if (text[i] === '\\n') line++;\n }\n return line;\n }\n\n private getColumnNumber(text: string, position: number): number {\n let column = 1;\n for (let i = position - 1; i >= 0 && text[i] !== '\\n'; i--) {\n column++;\n }\n return column;\n }\n\n /**\n * Get the number of patterns in the trie\n */\n getSize(): number {\n return this.size;\n }\n\n /**\n * Clear all patterns\n */\n clear(): void {\n this.root = this.createNode();\n this.size = 0;\n }\n\n /**\n * Serialize trie to JSON for persistence\n */\n toJSON(): object {\n return this.serializeNode(this.root);\n }\n\n private serializeNode(node: TrieNode<T>): object {\n const children: Record<string, object> = {};\n for (const [char, child] of node.children) {\n children[char] = this.serializeNode(child);\n }\n return {\n children,\n isEnd: node.isEnd,\n value: node.value,\n metadata: node.metadata,\n };\n }\n\n /**\n * Load trie from JSON\n */\n static fromJSON<T>(json: object): Trie<T> {\n const trie = new Trie<T>();\n trie.root = trie.deserializeNode(json as any);\n return trie;\n }\n\n private deserializeNode(data: any): TrieNode<T> {\n const node = this.createNode();\n node.isEnd = data.isEnd;\n node.value = data.value;\n node.metadata = data.metadata;\n \n for (const [char, childData] of Object.entries(data.children)) {\n node.children.set(char, this.deserializeNode(childData));\n }\n \n return node;\n }\n}\n\n/**\n * Aho-Corasick implementation for efficient multi-pattern matching\n * O(n + m + z) where n = text length, m = total pattern length, z = number of matches\n */\nexport class AhoCorasick<T = any> {\n private root: ACNode<T>;\n private built: boolean = false;\n\n constructor() {\n this.root = this.createNode();\n }\n\n private createNode(): ACNode<T> {\n return {\n children: new Map(),\n fail: null,\n output: [],\n };\n }\n\n /**\n * Add a pattern to the automaton\n */\n addPattern(pattern: string, value?: T, metadata?: PatternMetadata): void {\n let node = this.root;\n\n for (const char of pattern) {\n if (!node.children.has(char)) {\n node.children.set(char, this.createNode());\n }\n node = node.children.get(char)!;\n }\n\n const outputEntry: { pattern: string; value?: T; metadata?: PatternMetadata } = { pattern };\n if (value !== undefined) {\n outputEntry.value = value;\n }\n if (metadata !== undefined) {\n outputEntry.metadata = metadata;\n }\n node.output.push(outputEntry);\n this.built = false;\n }\n\n /**\n * Build failure links (call after adding all patterns)\n */\n build(): void {\n const queue: ACNode<T>[] = [];\n\n // Initialize failure links for depth 1\n for (const child of this.root.children.values()) {\n child.fail = this.root;\n queue.push(child);\n }\n\n // BFS to build failure links\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n for (const [char, child] of current.children) {\n queue.push(child);\n\n // Find failure link\n let fail = current.fail;\n while (fail !== null && !fail.children.has(char)) {\n fail = fail.fail;\n }\n\n child.fail = fail ? fail.children.get(char)! : this.root;\n\n // Merge outputs from failure chain\n if (child.fail !== this.root) {\n child.output = [...child.output, ...child.fail.output];\n }\n }\n }\n\n this.built = true;\n }\n\n /**\n * Search text for all pattern matches\n * O(n + z) where n = text length, z = number of matches\n */\n search(text: string): MatchResult<T>[] {\n if (!this.built) {\n this.build();\n }\n\n const matches: MatchResult<T>[] = [];\n let node = this.root;\n let line = 1;\n let lineStart = 0;\n\n for (let i = 0; i < text.length; i++) {\n const char = text[i]!;\n\n // Track line numbers\n if (char === '\\n') {\n line++;\n lineStart = i + 1;\n }\n\n // Follow failure links until we find a match or reach root\n while (node !== this.root && !node.children.has(char)) {\n node = node.fail || this.root;\n }\n\n node = node.children.get(char) || this.root;\n\n // Report all matches at this position\n for (const output of node.output) {\n const matchResult: MatchResult<T> = {\n pattern: output.pattern,\n position: i - output.pattern.length + 1,\n line,\n column: i - output.pattern.length + 1 - lineStart + 1,\n };\n if (output.value !== undefined) {\n matchResult.value = output.value;\n }\n if (output.metadata !== undefined) {\n matchResult.metadata = output.metadata;\n }\n matches.push(matchResult);\n }\n }\n\n return matches;\n }\n}\n\ninterface ACNode<T> {\n children: Map<string, ACNode<T>>;\n fail: ACNode<T> | null;\n output: Array<{ pattern: string; value?: T; metadata?: PatternMetadata }>;\n}\n\n"],"mappings":";AAuCO,IAAM,OAAN,MAAM,MAAc;AAAA,EACjB;AAAA,EACA,OAAe;AAAA,EAEvB,cAAc;AACZ,SAAK,OAAO,KAAK,WAAW;AAAA,EAC9B;AAAA,EAEQ,aAA0B;AAChC,WAAO;AAAA,MACL,UAAU,oBAAI,IAAI;AAAA,MAClB,OAAO;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,SAAiB,OAAW,UAAkC;AACnE,QAAI,OAAO,KAAK;AAEhB,eAAW,QAAQ,SAAS;AAC1B,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,aAAK,SAAS,IAAI,MAAM,KAAK,WAAW,CAAC;AAAA,MAC3C;AACA,aAAO,KAAK,SAAS,IAAI,IAAI;AAAA,IAC/B;AAEA,SAAK,QAAQ;AACb,QAAI,UAAU,QAAW;AACvB,WAAK,QAAQ;AAAA,IACf;AACA,QAAI,aAAa,QAAW;AAC1B,WAAK,WAAW;AAAA,IAClB;AACA,SAAK;AAAA,EACP;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,SAA4E;AACjF,QAAI,OAAO,KAAK;AAEhB,eAAW,QAAQ,SAAS;AAC1B,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,eAAO,EAAE,OAAO,MAAM;AAAA,MACxB;AACA,aAAO,KAAK,SAAS,IAAI,IAAI;AAAA,IAC/B;AAEA,UAAM,SAAoE;AAAA,MACxE,OAAO,KAAK;AAAA,IACd;AACA,QAAI,KAAK,UAAU,QAAW;AAC5B,aAAO,QAAQ,KAAK;AAAA,IACtB;AACA,QAAI,KAAK,aAAa,QAAW;AAC/B,aAAO,WAAW,KAAK;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,WAAW,QAAyB;AAClC,QAAI,OAAO,KAAK;AAEhB,eAAW,QAAQ,QAAQ;AACzB,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,eAAO;AAAA,MACT;AACA,aAAO,KAAK,SAAS,IAAI,IAAI;AAAA,IAC/B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,eAAe,MAAgC;AAC7C,UAAM,UAA4B,CAAC;AACnC,UAAM,QAAQ,KAAK,MAAM,IAAI;AAE7B,QAAI,YAAY;AAEhB,aAAS,UAAU,GAAG,UAAU,MAAM,QAAQ,WAAW;AACvD,YAAM,OAAO,MAAM,OAAO;AAG1B,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAI,OAAO,KAAK;AAChB,YAAI,WAAW;AACf,YAAI,IAAI;AAGR,eAAO,IAAI,KAAK,UAAU,KAAK,SAAS,IAAI,KAAK,CAAC,CAAE,GAAG;AACrD,iBAAO,KAAK,SAAS,IAAI,KAAK,CAAC,CAAE;AACjC;AACA;AAGA,cAAI,KAAK,OAAO;AACd,kBAAM,cAA8B;AAAA,cAClC,SAAS,KAAK,UAAU,GAAG,IAAI,QAAQ;AAAA,cACvC,UAAU,YAAY;AAAA,cACtB,MAAM,UAAU;AAAA,cAChB,QAAQ,IAAI;AAAA,YACd;AACA,gBAAI,KAAK,UAAU,QAAW;AAC5B,0BAAY,QAAQ,KAAK;AAAA,YAC3B;AACA,gBAAI,KAAK,aAAa,QAAW;AAC/B,0BAAY,WAAW,KAAK;AAAA,YAC9B;AACA,oBAAQ,KAAK,WAAW;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAEA,mBAAa,KAAK,SAAS;AAAA,IAC7B;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,iBAAiB,MAAc,WAAmB,GAA0B;AAC1E,QAAI,OAAO,KAAK;AAChB,QAAI,YAAmC;AACvC,QAAI,WAAW;AAEf,aAAS,IAAI,UAAU,IAAI,KAAK,QAAQ,KAAK;AAC3C,YAAM,OAAO,KAAK,CAAC;AAEnB,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B;AAAA,MACF;AAEA,aAAO,KAAK,SAAS,IAAI,IAAI;AAC7B;AAEA,UAAI,KAAK,OAAO;AACd,oBAAY;AAAA,UACV,SAAS,KAAK,UAAU,UAAU,WAAW,QAAQ;AAAA,UACrD,UAAU;AAAA,UACV,MAAM,KAAK,cAAc,MAAM,QAAQ;AAAA,UACvC,QAAQ,KAAK,gBAAgB,MAAM,QAAQ;AAAA,QAC7C;AACA,YAAI,KAAK,UAAU,QAAW;AAC5B,oBAAU,QAAQ,KAAK;AAAA,QACzB;AACA,YAAI,KAAK,aAAa,QAAW;AAC/B,oBAAU,WAAW,KAAK;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,cAAc,QAAmF;AAC/F,QAAI,OAAO,KAAK;AAGhB,eAAW,QAAQ,QAAQ;AACzB,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,eAAO,CAAC;AAAA,MACV;AACA,aAAO,KAAK,SAAS,IAAI,IAAI;AAAA,IAC/B;AAGA,UAAM,UAA6E,CAAC;AACpF,SAAK,gBAAgB,MAAM,QAAQ,OAAO;AAC1C,WAAO;AAAA,EACT;AAAA,EAEQ,gBACN,MACA,QACA,SACM;AACN,QAAI,KAAK,OAAO;AACd,YAAM,QAAoE,EAAE,SAAS,OAAO;AAC5F,UAAI,KAAK,UAAU,QAAW;AAC5B,cAAM,QAAQ,KAAK;AAAA,MACrB;AACA,UAAI,KAAK,aAAa,QAAW;AAC/B,cAAM,WAAW,KAAK;AAAA,MACxB;AACA,cAAQ,KAAK,KAAK;AAAA,IACpB;AAEA,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,UAAU;AACzC,WAAK,gBAAgB,OAAO,SAAS,MAAM,OAAO;AAAA,IACpD;AAAA,EACF;AAAA,EAEQ,cAAc,MAAc,UAA0B;AAC5D,QAAI,OAAO;AACX,aAAS,IAAI,GAAG,IAAI,YAAY,IAAI,KAAK,QAAQ,KAAK;AACpD,UAAI,KAAK,CAAC,MAAM,KAAM;AAAA,IACxB;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,MAAc,UAA0B;AAC9D,QAAI,SAAS;AACb,aAAS,IAAI,WAAW,GAAG,KAAK,KAAK,KAAK,CAAC,MAAM,MAAM,KAAK;AAC1D;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,UAAkB;AAChB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,SAAK,OAAO,KAAK,WAAW;AAC5B,SAAK,OAAO;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,SAAiB;AACf,WAAO,KAAK,cAAc,KAAK,IAAI;AAAA,EACrC;AAAA,EAEQ,cAAc,MAA2B;AAC/C,UAAM,WAAmC,CAAC;AAC1C,eAAW,CAAC,MAAM,KAAK,KAAK,KAAK,UAAU;AACzC,eAAS,IAAI,IAAI,KAAK,cAAc,KAAK;AAAA,IAC3C;AACA,WAAO;AAAA,MACL;AAAA,MACA,OAAO,KAAK;AAAA,MACZ,OAAO,KAAK;AAAA,MACZ,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,SAAY,MAAuB;AACxC,UAAM,OAAO,IAAI,MAAQ;AACzB,SAAK,OAAO,KAAK,gBAAgB,IAAW;AAC5C,WAAO;AAAA,EACT;AAAA,EAEQ,gBAAgB,MAAwB;AAC9C,UAAM,OAAO,KAAK,WAAW;AAC7B,SAAK,QAAQ,KAAK;AAClB,SAAK,QAAQ,KAAK;AAClB,SAAK,WAAW,KAAK;AAErB,eAAW,CAAC,MAAM,SAAS,KAAK,OAAO,QAAQ,KAAK,QAAQ,GAAG;AAC7D,WAAK,SAAS,IAAI,MAAM,KAAK,gBAAgB,SAAS,CAAC;AAAA,IACzD;AAEA,WAAO;AAAA,EACT;AACF;AAMO,IAAM,cAAN,MAA2B;AAAA,EACxB;AAAA,EACA,QAAiB;AAAA,EAEzB,cAAc;AACZ,SAAK,OAAO,KAAK,WAAW;AAAA,EAC9B;AAAA,EAEQ,aAAwB;AAC9B,WAAO;AAAA,MACL,UAAU,oBAAI,IAAI;AAAA,MAClB,MAAM;AAAA,MACN,QAAQ,CAAC;AAAA,IACX;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,SAAiB,OAAW,UAAkC;AACvE,QAAI,OAAO,KAAK;AAEhB,eAAW,QAAQ,SAAS;AAC1B,UAAI,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAC5B,aAAK,SAAS,IAAI,MAAM,KAAK,WAAW,CAAC;AAAA,MAC3C;AACA,aAAO,KAAK,SAAS,IAAI,IAAI;AAAA,IAC/B;AAEA,UAAM,cAA0E,EAAE,QAAQ;AAC1F,QAAI,UAAU,QAAW;AACvB,kBAAY,QAAQ;AAAA,IACtB;AACA,QAAI,aAAa,QAAW;AAC1B,kBAAY,WAAW;AAAA,IACzB;AACA,SAAK,OAAO,KAAK,WAAW;AAC5B,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACZ,UAAM,QAAqB,CAAC;AAG5B,eAAW,SAAS,KAAK,KAAK,SAAS,OAAO,GAAG;AAC/C,YAAM,OAAO,KAAK;AAClB,YAAM,KAAK,KAAK;AAAA,IAClB;AAGA,WAAO,MAAM,SAAS,GAAG;AACvB,YAAM,UAAU,MAAM,MAAM;AAE5B,iBAAW,CAAC,MAAM,KAAK,KAAK,QAAQ,UAAU;AAC5C,cAAM,KAAK,KAAK;AAGhB,YAAI,OAAO,QAAQ;AACnB,eAAO,SAAS,QAAQ,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AAChD,iBAAO,KAAK;AAAA,QACd;AAEA,cAAM,OAAO,OAAO,KAAK,SAAS,IAAI,IAAI,IAAK,KAAK;AAGpD,YAAI,MAAM,SAAS,KAAK,MAAM;AAC5B,gBAAM,SAAS,CAAC,GAAG,MAAM,QAAQ,GAAG,MAAM,KAAK,MAAM;AAAA,QACvD;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,OAAO,MAAgC;AACrC,QAAI,CAAC,KAAK,OAAO;AACf,WAAK,MAAM;AAAA,IACb;AAEA,UAAM,UAA4B,CAAC;AACnC,QAAI,OAAO,KAAK;AAChB,QAAI,OAAO;AACX,QAAI,YAAY;AAEhB,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,OAAO,KAAK,CAAC;AAGnB,UAAI,SAAS,MAAM;AACjB;AACA,oBAAY,IAAI;AAAA,MAClB;AAGA,aAAO,SAAS,KAAK,QAAQ,CAAC,KAAK,SAAS,IAAI,IAAI,GAAG;AACrD,eAAO,KAAK,QAAQ,KAAK;AAAA,MAC3B;AAEA,aAAO,KAAK,SAAS,IAAI,IAAI,KAAK,KAAK;AAGvC,iBAAW,UAAU,KAAK,QAAQ;AAChC,cAAM,cAA8B;AAAA,UAClC,SAAS,OAAO;AAAA,UAChB,UAAU,IAAI,OAAO,QAAQ,SAAS;AAAA,UACtC;AAAA,UACA,QAAQ,IAAI,OAAO,QAAQ,SAAS,IAAI,YAAY;AAAA,QACtD;AACA,YAAI,OAAO,UAAU,QAAW;AAC9B,sBAAY,QAAQ,OAAO;AAAA,QAC7B;AACA,YAAI,OAAO,aAAa,QAAW;AACjC,sBAAY,WAAW,OAAO;AAAA,QAChC;AACA,gBAAQ,KAAK,WAAW;AAAA,MAC1B;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;","names":[]}
@@ -0,0 +1,11 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ export {
9
+ __require
10
+ };
11
+ //# sourceMappingURL=chunk-DGUM43GV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}