@triedotdev/mcp 1.0.46 → 1.0.49

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/utils/progress.ts","../src/agents/base-agent.ts","../src/ai/client.ts","../src/agents/agent-smith.ts"],"sourcesContent":["/**\n * Progress Reporter for Trie Agent\n * \n * Provides real-time feedback to users as the agent works.\n * Uses console.error because MCP clients display stderr to users.\n */\n\nexport type ProgressPhase = \n | 'init'\n | 'discovery'\n | 'reading'\n | 'analyzing'\n | 'ai-review'\n | 'prioritizing'\n | 'complete';\n\nexport interface ProgressCallback {\n (phase: ProgressPhase, message: string, detail?: string): void;\n}\n\n/**\n * Progress Reporter - streams status updates to the user\n */\nexport class ProgressReporter {\n private currentPhase: ProgressPhase = 'init';\n private startTime: number = Date.now();\n private phaseStartTime: number = Date.now();\n private verbose: boolean;\n\n constructor(options: { verbose?: boolean } = {}) {\n this.verbose = options.verbose ?? true;\n }\n\n /**\n * Report a status update\n */\n report(message: string, detail?: string): void {\n if (!this.verbose) return;\n \n const prefix = this.getPhaseIcon(this.currentPhase);\n const fullMessage = detail ? `${message}: ${detail}` : message;\n console.error(`${prefix} ${fullMessage}`);\n }\n\n /**\n * Start a new phase\n */\n startPhase(phase: ProgressPhase, message: string): void {\n this.currentPhase = phase;\n this.phaseStartTime = Date.now();\n this.report(message);\n }\n\n /**\n * Update within current phase\n */\n update(message: string, detail?: string): void {\n this.report(message, detail);\n }\n\n /**\n * Report progress on a file\n */\n file(action: string, filePath: string): void {\n // Show just the filename for cleaner output\n const fileName = filePath.split('/').pop() || filePath;\n this.report(action, fileName);\n }\n\n /**\n * Report an AI analysis step\n */\n ai(action: string, context?: string): void {\n const prefix = '[AI]';\n const message = context ? `${action}: ${context}` : action;\n console.error(`${prefix} ${message}`);\n }\n\n /**\n * Report a finding\n */\n finding(severity: 'critical' | 'serious' | 'moderate' | 'low', message: string): void {\n const labels = {\n critical: '[CRITICAL]',\n serious: '[SERIOUS]',\n moderate: '[MODERATE]',\n low: '[LOW]'\n };\n console.error(` ${labels[severity]} ${message}`);\n }\n\n /**\n * Complete current phase\n */\n completePhase(summary: string): void {\n const elapsed = Date.now() - this.phaseStartTime;\n this.report(`Done: ${summary}`, `(${elapsed}ms)`);\n }\n\n /**\n * Complete the entire operation\n */\n complete(summary: string): void {\n const totalElapsed = Date.now() - this.startTime;\n console.error('');\n console.error(`----------------------------------------`);\n console.error(`[COMPLETE] ${summary}`);\n console.error(` Total time: ${(totalElapsed / 1000).toFixed(2)}s`);\n console.error(`----------------------------------------`);\n console.error('');\n }\n\n /**\n * Report an error\n */\n error(message: string, detail?: string): void {\n const fullMessage = detail ? `${message}: ${detail}` : message;\n console.error(`[ERROR] ${fullMessage}`);\n }\n\n /**\n * Report a warning\n */\n warn(message: string, detail?: string): void {\n const fullMessage = detail ? `${message}: ${detail}` : message;\n console.error(`[WARN] ${fullMessage}`);\n }\n\n /**\n * Get icon for current phase\n */\n private getPhaseIcon(phase: ProgressPhase): string {\n const icons: Record<ProgressPhase, string> = {\n 'init': '>>',\n 'discovery': '>>',\n 'reading': '>>',\n 'analyzing': '>>',\n 'ai-review': '[AI]',\n 'prioritizing': '>>',\n 'complete': '[OK]'\n };\n return icons[phase] || '>>';\n }\n\n /**\n * Create a sub-reporter for a specific agent\n */\n forAgent(agentName: string): AgentProgressReporter {\n return new AgentProgressReporter(agentName, this.verbose);\n }\n}\n\n/**\n * Progress reporter scoped to a specific agent\n */\nexport class AgentProgressReporter {\n private agentName: string;\n private verbose: boolean;\n private issueCount: number = 0;\n\n constructor(agentName: string, verbose: boolean = true) {\n this.agentName = agentName;\n this.verbose = verbose;\n }\n\n start(): void {\n if (!this.verbose) return;\n console.error(`\\n[AGENT] ${this.agentName.toUpperCase()} starting...`);\n }\n\n analyzing(file: string): void {\n if (!this.verbose) return;\n const fileName = file.split('/').pop() || file;\n console.error(` Analyzing ${fileName}...`);\n }\n\n aiReview(context: string): void {\n if (!this.verbose) return;\n console.error(` [AI] reviewing: ${context}`);\n }\n\n found(severity: string, issue: string): void {\n this.issueCount++;\n if (!this.verbose) return;\n const label = severity === 'critical' ? '[CRITICAL]' : \n severity === 'serious' ? '[SERIOUS]' : \n severity === 'moderate' ? '[MODERATE]' : '[LOW]';\n console.error(` ${label} Found: ${issue}`);\n }\n\n complete(summary?: string): void {\n if (!this.verbose) return;\n const msg = summary || `Found ${this.issueCount} issues`;\n console.error(` Done: ${this.agentName}: ${msg}`);\n }\n\n getIssueCount(): number {\n return this.issueCount;\n }\n}\n\n/**\n * Global singleton for easy access\n */\nlet globalReporter: ProgressReporter | null = null;\n\nexport function getProgressReporter(options?: { verbose?: boolean }): ProgressReporter {\n if (!globalReporter) {\n globalReporter = new ProgressReporter(options);\n }\n return globalReporter;\n}\n\nexport function resetProgressReporter(): void {\n globalReporter = null;\n}\n","import type { Agent, AgentResult, ScanContext, Issue, CodeContext, AgentPriority } from '../types/index.js';\nimport { AgentProgressReporter } from '../utils/progress.js';\nimport { relative } from 'path';\nimport { isAIAvailable, runAIAnalysis, getAIStatusMessage } from '../ai/client.js';\n\n/**\n * AI Analysis Request - what the agent wants AI to analyze\n */\nexport interface AIAnalysisRequest {\n /** The file being analyzed */\n file: string;\n /** Relevant code content to analyze */\n code: string;\n /** What kind of analysis to perform */\n analysisType: string;\n /** System prompt for the AI */\n systemPrompt: string;\n /** User prompt with specific instructions */\n userPrompt: string;\n /** Additional context for the AI */\n context?: Record<string, unknown>;\n /** Files/code that might be relevant for cross-reference */\n relatedCode?: Array<{ file: string; code: string }>;\n}\n\n/**\n * AI Analysis Result - structured output from AI analysis\n */\nexport interface AIAnalysisResult {\n issues: Array<{\n severity: 'critical' | 'serious' | 'moderate' | 'low';\n title: string;\n description: string;\n line?: number;\n fix: string;\n confidence: number;\n }>;\n summary: string;\n}\n\n/**\n * File relevance check result\n */\nexport interface FileRelevance {\n isRelevant: boolean;\n reason: string;\n priority: 'high' | 'medium' | 'low';\n indicators: string[];\n}\n\nexport abstract class BaseAgent implements Agent {\n abstract name: string;\n abstract description: string;\n abstract version: string;\n \n // Progress reporter for real-time feedback\n protected progress: AgentProgressReporter | null = null;\n \n // Default priority - subclasses can override\n get priority(): AgentPriority {\n return {\n name: this.name,\n tier: 2,\n estimatedTimeMs: 100,\n dependencies: []\n };\n }\n\n abstract shouldActivate(context: CodeContext): boolean;\n\n // Default implementation - can be overridden for smarter confidence\n getActivationConfidence(context: CodeContext): number {\n return this.shouldActivate(context) ? 0.7 : 0;\n }\n\n /**\n * Main scan entry point - now with progress reporting\n */\n async scan(files: string[], context: ScanContext): Promise<AgentResult> {\n const startTime = Date.now();\n this.progress = new AgentProgressReporter(this.name);\n this.progress.start();\n\n try {\n // Use AI-first analysis if available, otherwise fall back to pattern matching\n const issues = await this.analyzeWithAI(files, context);\n\n this.progress.complete(`${issues.length} issues found`);\n\n return {\n agent: this.name,\n issues,\n executionTime: Date.now() - startTime,\n success: true,\n metadata: {\n filesAnalyzed: files.length,\n linesAnalyzed: 0,\n }\n };\n } catch (error) {\n this.progress.complete('Failed');\n return {\n agent: this.name,\n issues: [],\n executionTime: Date.now() - startTime,\n success: false,\n error: error instanceof Error ? error.message : String(error)\n };\n }\n }\n\n /**\n * Hybrid AI + Pattern Analysis\n * \n * 1. Run fast pattern detection on all files\n * 2. If AI is available (ANTHROPIC_API_KEY set), enhance with AI analysis\n * 3. AI validates findings, finds additional issues, provides intelligent fixes\n * \n * Subclasses can override for custom behavior\n */\n protected async analyzeWithAI(files: string[], context: ScanContext): Promise<Issue[]> {\n // Phase 1: Pattern-based analysis (fast)\n this.progress?.aiReview('Running pattern detection...');\n const patternIssues = await this.analyzeFiles(files, context);\n \n // Check if AI is available\n if (!isAIAvailable()) {\n console.error(` ${getAIStatusMessage()}`);\n return patternIssues;\n }\n \n // Phase 2: AI-enhanced analysis\n if (patternIssues.length > 0 || this.shouldAlwaysUseAI()) {\n this.progress?.aiReview('Enhancing with AI analysis...');\n \n try {\n const enhancedIssues = await this.runAIEnhancement(patternIssues, files, context);\n return this.mergeIssues(enhancedIssues, patternIssues);\n } catch (error) {\n // AI failed, fall back to pattern-only results\n console.error(` ⚠️ AI enhancement failed: ${error instanceof Error ? error.message : String(error)}`);\n return patternIssues;\n }\n }\n \n return patternIssues;\n }\n \n /**\n * Whether this agent should always use AI even if no patterns detected\n */\n protected shouldAlwaysUseAI(): boolean {\n return false; // Override in subclasses that need AI for all analysis\n }\n \n /**\n * Run AI enhancement on pattern detection results\n * Subclasses can override for custom AI behavior\n */\n protected async runAIEnhancement(\n patternIssues: Issue[],\n files: string[],\n _context: ScanContext\n ): Promise<Issue[]> {\n // Collect code snippets for top issues\n const snippets: Array<{ file: string; line: number | undefined; issue: string; code: string }> = [];\n \n // Sort by severity to prioritize critical issues\n const sortedIssues = [...patternIssues].sort((a, b) => {\n const order = { critical: 0, serious: 1, moderate: 2, low: 3 };\n return order[a.severity] - order[b.severity];\n });\n \n // Get snippets for top 15 issues\n for (const issue of sortedIssues.slice(0, 15)) {\n try {\n const content = await this.readFile(issue.file);\n const snippet = this.getCodeSnippet(content, issue.line || 1, 5);\n snippets.push({\n file: this.getRelativePath(issue.file),\n line: issue.line,\n issue: issue.issue,\n code: snippet\n });\n } catch {\n // Skip if can't read file\n }\n }\n \n if (snippets.length === 0) {\n return []; // No snippets to analyze\n }\n \n // Build AI prompt\n const userPrompt = this.buildAIEnhancementPrompt(snippets, patternIssues.length);\n \n const result = await runAIAnalysis({\n systemPrompt: this.getAIEnhancementSystemPrompt(),\n userPrompt,\n maxTokens: 4096,\n temperature: 0.2\n });\n \n if (!result.success) {\n throw new Error(result.error || 'AI analysis failed');\n }\n \n // Parse AI response into issues\n return this.parseAIEnhancementResponse(result.content, files);\n }\n \n /**\n * System prompt for AI enhancement\n */\n protected getAIEnhancementSystemPrompt(): string {\n return `You are an expert ${this.name} code analyst. You are enhancing pattern-detected issues with deeper analysis.\n\nYour job:\n1. VALIDATE: Confirm if each issue is a TRUE problem or FALSE positive\n2. EXPAND: Identify related issues that patterns missed\n3. PRIORITIZE: Rank by real-world impact (0-100 inevitability score)\n4. FIX: Provide specific, copy-paste-ready code fixes\n\nOutput format (STRICT JSON):\n{\n \"validated\": [\n {\n \"original_issue\": \"...\",\n \"verdict\": \"TRUE_POSITIVE\" | \"FALSE_POSITIVE\",\n \"confidence\": 0-100,\n \"file\": \"path/to/file\",\n \"line\": 123,\n \"severity\": \"critical\" | \"serious\" | \"moderate\" | \"low\",\n \"explanation\": \"Why this is/isn't a problem\",\n \"fix\": \"Specific code fix\"\n }\n ],\n \"additional\": [\n {\n \"issue\": \"New issue found by AI\",\n \"file\": \"path/to/file\",\n \"line\": 123,\n \"severity\": \"critical\" | \"serious\" | \"moderate\" | \"low\", \n \"explanation\": \"What's wrong\",\n \"fix\": \"How to fix it\"\n }\n ],\n \"summary\": \"One paragraph summary of findings\"\n}`;\n }\n \n /**\n * Build the user prompt for AI enhancement\n */\n protected buildAIEnhancementPrompt(\n snippets: Array<{ file: string; line: number | undefined; issue: string; code: string }>,\n totalIssues: number\n ): string {\n const snippetText = snippets.map((s, i) => \n `### Issue ${i + 1}: ${s.file}${s.line ? ':' + s.line : ''}\n**Pattern detected:** ${s.issue}\n\\`\\`\\`\n${s.code}\n\\`\\`\\`\n`).join('\\n');\n\n return `Pattern detection found ${totalIssues} total issues. Here are the top ${snippets.length} for AI analysis:\n\n${snippetText}\n\nAnalyze each issue. Validate, expand, and provide fixes. Output JSON only.`;\n }\n \n /**\n * Parse AI enhancement response into issues\n */\n protected parseAIEnhancementResponse(response: string, _files: string[]): Issue[] {\n const issues: Issue[] = [];\n \n try {\n // Extract JSON from response (might be wrapped in markdown code blocks)\n const jsonMatch = response.match(/```json\\s*([\\s\\S]*?)\\s*```/) || \n response.match(/\\{[\\s\\S]*\\}/);\n \n if (!jsonMatch) {\n return issues;\n }\n \n const json = JSON.parse(jsonMatch[1] || jsonMatch[0]);\n \n // Process validated issues\n if (json.validated && Array.isArray(json.validated)) {\n for (const v of json.validated) {\n if (v.verdict === 'TRUE_POSITIVE') {\n issues.push(this.createIssue(\n this.generateIssueId(),\n v.severity || 'moderate',\n `[AI VALIDATED] ${v.original_issue || v.explanation}`,\n v.fix || 'See AI analysis',\n v.file || 'unknown',\n v.line,\n (v.confidence || 80) / 100,\n undefined,\n false,\n { category: 'ai-validated' }\n ));\n }\n }\n }\n \n // Process additional issues found by AI\n if (json.additional && Array.isArray(json.additional)) {\n for (const a of json.additional) {\n issues.push(this.createIssue(\n this.generateIssueId(),\n a.severity || 'moderate',\n `[AI FOUND] ${a.issue || a.explanation}`,\n a.fix || 'See AI analysis',\n a.file || 'unknown',\n a.line,\n 0.85, // AI-found issues have good confidence\n undefined,\n false,\n { category: 'ai-found' }\n ));\n }\n }\n } catch (error) {\n // JSON parsing failed - try line-by-line parsing\n // This is a fallback for when AI doesn't output strict JSON\n }\n \n return issues;\n }\n\n /**\n * Check if a file is relevant for this agent's analysis\n * Subclasses should override for domain-specific checks\n */\n protected checkFileRelevance(_file: string, _content: string): FileRelevance {\n // Default: all files are relevant with low priority\n return {\n isRelevant: true,\n reason: 'Default analysis',\n priority: 'low',\n indicators: []\n };\n }\n\n /**\n * Merge and deduplicate issues from AI and pattern analysis\n */\n protected mergeIssues(aiIssues: Issue[], legacyIssues: Issue[]): Issue[] {\n // Simple merge - prefer AI issues, add legacy issues that don't overlap\n const merged = [...aiIssues];\n \n for (const legacy of legacyIssues) {\n // Check if there's an overlapping AI issue for the same file/line\n const hasOverlap = aiIssues.some(ai => \n ai.file === legacy.file && \n ai.line === legacy.line\n );\n \n if (!hasOverlap) {\n merged.push(legacy);\n }\n }\n \n return merged;\n }\n\n /**\n * Get relative path from cwd\n */\n protected getRelativePath(file: string): string {\n try {\n return relative(process.cwd(), file);\n } catch {\n return file;\n }\n }\n\n /**\n * Legacy pattern-based analysis - kept for backwards compatibility\n * Subclasses can override or deprecate\n */\n protected abstract analyzeFiles(files: string[], context: ScanContext): Promise<Issue[]>;\n\n /**\n * Format an issue message with consistent structure\n * All agents should use this for uniformity\n */\n protected formatIssueMessage(description: string, context?: string): string {\n // Clean up any existing emoji prefixes\n let cleanDesc = description\n .replace(/^[^\\w\\[]*/, '') // Remove leading emojis/special chars\n .trim();\n \n // Add agent prefix for traceability\n const prefix = `[${this.name.toUpperCase()}]`;\n \n if (context) {\n return `${prefix} ${cleanDesc} -- ${context}`;\n }\n return `${prefix} ${cleanDesc}`;\n }\n\n protected createIssue(\n id: string,\n severity: Issue['severity'],\n issue: string,\n fix: string,\n file: string,\n line?: number,\n confidence: number = 0.9,\n regulation?: string,\n autoFixable: boolean = true,\n options?: {\n category?: string;\n cwe?: string;\n owasp?: string;\n effort?: Issue['effort'];\n endLine?: number;\n column?: number;\n }\n ): Issue {\n const result: Issue = {\n id,\n severity,\n issue,\n fix,\n file,\n confidence,\n autoFixable,\n agent: this.name,\n effort: options?.effort ?? this.estimateEffort(severity, autoFixable)\n };\n \n // Only add optional properties if they have values\n if (line !== undefined) result.line = line;\n if (options?.endLine !== undefined) result.endLine = options.endLine;\n if (options?.column !== undefined) result.column = options.column;\n if (regulation !== undefined) result.regulation = regulation;\n if (options?.category !== undefined) result.category = options.category;\n if (options?.cwe !== undefined) result.cwe = options.cwe;\n if (options?.owasp !== undefined) result.owasp = options.owasp;\n \n return result;\n }\n\n private estimateEffort(severity: Issue['severity'], autoFixable: boolean): 'trivial' | 'easy' | 'medium' | 'hard' {\n if (autoFixable) return 'trivial';\n if (severity === 'low') return 'easy';\n if (severity === 'moderate') return 'easy';\n if (severity === 'serious') return 'medium';\n return 'hard';\n }\n\n protected async readFile(filePath: string): Promise<string> {\n const { readFile } = await import('fs/promises');\n return readFile(filePath, 'utf-8');\n }\n\n protected generateIssueId(): string {\n return `${this.name}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }\n\n protected getLineContent(content: string, lineNumber: number): string {\n const lines = content.split('\\n');\n return lines[lineNumber - 1] || '';\n }\n\n protected getCodeSnippet(content: string, lineNumber: number, contextLines: number = 2): string {\n const lines = content.split('\\n');\n const start = Math.max(0, lineNumber - contextLines - 1);\n const end = Math.min(lines.length, lineNumber + contextLines);\n \n return lines\n .slice(start, end)\n .map((line, idx) => {\n const num = start + idx + 1;\n const marker = num === lineNumber ? '→' : ' ';\n return `${marker} ${num.toString().padStart(4)} | ${line}`;\n })\n .join('\\n');\n }\n}\n","/**\n * Centralized AI Client\n * \n * Handles API key detection, graceful fallbacks, and AI-powered analysis.\n * All agents use this for AI-enhanced analysis.\n * \n * API Key Setup:\n * 1. Set ANTHROPIC_API_KEY in your environment\n * 2. Or add it to your MCP server config (mcp.json)\n * 3. Or create .env file in your project root\n * \n * If no API key is found, agents fall back to pattern-only mode.\n */\n\nimport Anthropic from '@anthropic-ai/sdk';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\nimport { getWorkingDirectory } from '../utils/workspace.js';\n\n// Cached client instance\nlet clientInstance: Anthropic | null = null;\nlet apiKeyChecked = false;\nlet apiKeyAvailable = false;\n\n/**\n * Check if AI is available (API key is set)\n */\nexport function isAIAvailable(): boolean {\n if (!apiKeyChecked) {\n checkAPIKey();\n }\n return apiKeyAvailable;\n}\n\n/**\n * Check for API key in environment and config file\n */\nfunction checkAPIKey(): void {\n apiKeyChecked = true;\n \n // Check standard env var first\n const envApiKey = process.env.ANTHROPIC_API_KEY;\n \n if (envApiKey && envApiKey.length > 10) {\n apiKeyAvailable = true;\n return;\n }\n \n // Check config file for API key (synchronous read)\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const configPath = join(workDir, '.trie', 'config.json');\n \n if (existsSync(configPath)) {\n const configContent = readFileSync(configPath, 'utf-8');\n const config = JSON.parse(configContent);\n \n if (config.apiKeys?.anthropic && config.apiKeys.anthropic.length > 10) {\n // Set it in process.env so Anthropic SDK can use it\n process.env.ANTHROPIC_API_KEY = config.apiKeys.anthropic;\n apiKeyAvailable = true;\n return;\n }\n }\n } catch {\n // Config file doesn't exist or couldn't be read, continue without it\n }\n \n // Check .env files (common patterns)\n try {\n const workDir = getWorkingDirectory(undefined, true);\n const envFiles = ['.env', '.env.local', '.env.production'];\n \n for (const envFile of envFiles) {\n const envPath = join(workDir, envFile);\n if (existsSync(envPath)) {\n const envContent = readFileSync(envPath, 'utf-8');\n const lines = envContent.split('\\n');\n \n for (const line of lines) {\n const match = line.match(/^\\s*ANTHROPIC_API_KEY\\s*=\\s*(.+)$/);\n if (match && match[1]) {\n const key = match[1].trim().replace(/^[\"']|[\"']$/g, ''); // Remove quotes\n if (key.length > 10) {\n process.env.ANTHROPIC_API_KEY = key;\n apiKeyAvailable = true;\n return;\n }\n }\n }\n }\n }\n } catch {\n // .env file doesn't exist or couldn't be read, continue without it\n }\n \n apiKeyAvailable = false;\n}\n\n/**\n * Get the Anthropic client (lazy initialized)\n * Throws if API key is not available\n */\nexport function getClient(): Anthropic {\n if (!isAIAvailable()) {\n throw new Error(\n 'ANTHROPIC_API_KEY not found. Set it in your environment to enable AI-powered analysis.\\n' +\n 'Example: export ANTHROPIC_API_KEY=sk-ant-...'\n );\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\n/**\n * Try to get client, return null if not available\n */\nexport function tryGetClient(): Anthropic | null {\n if (!isAIAvailable()) {\n return null;\n }\n \n if (!clientInstance) {\n clientInstance = new Anthropic();\n }\n \n return clientInstance;\n}\n\nexport interface AIAnalysisRequest {\n systemPrompt: string;\n userPrompt: string;\n maxTokens?: number;\n temperature?: number;\n}\n\nexport interface AIAnalysisResult {\n success: boolean;\n content: string;\n error?: string;\n tokensUsed?: {\n input: number;\n output: number;\n };\n}\n\n/**\n * Run AI analysis with the given prompts\n */\nexport async function runAIAnalysis(request: AIAnalysisRequest): Promise<AIAnalysisResult> {\n const client = tryGetClient();\n \n if (!client) {\n return {\n success: false,\n content: '',\n error: 'AI not available - ANTHROPIC_API_KEY not set'\n };\n }\n \n try {\n const response = await client.messages.create({\n model: 'claude-sonnet-4-20250514',\n max_tokens: request.maxTokens || 4096,\n temperature: request.temperature ?? 0.3,\n system: request.systemPrompt,\n messages: [\n {\n role: 'user',\n content: request.userPrompt\n }\n ]\n });\n \n // Extract text content\n const textContent = response.content\n .filter((block): block is Anthropic.TextBlock => block.type === 'text')\n .map(block => block.text)\n .join('\\n');\n \n return {\n success: true,\n content: textContent,\n tokensUsed: {\n input: response.usage.input_tokens,\n output: response.usage.output_tokens\n }\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n \n // Check for specific error types\n if (errorMessage.includes('authentication') || errorMessage.includes('API key')) {\n return {\n success: false,\n content: '',\n error: 'Invalid API key. Check your ANTHROPIC_API_KEY.'\n };\n }\n \n if (errorMessage.includes('rate limit')) {\n return {\n success: false,\n content: '',\n error: 'Rate limited. Try again in a moment.'\n };\n }\n \n return {\n success: false,\n content: '',\n error: `AI analysis failed: ${errorMessage}`\n };\n }\n}\n\n/**\n * AI analysis for code issues\n */\nexport interface CodeIssueAnalysisRequest {\n issues: Array<{\n file: string;\n line?: number;\n issue: string;\n code?: string;\n }>;\n analysisType: 'validate' | 'expand' | 'fix' | 'explain';\n context?: string;\n}\n\n/**\n * Run AI analysis on code issues\n * Used by agents to validate, expand, or fix detected issues\n */\nexport async function analyzeCodeIssues(request: CodeIssueAnalysisRequest): Promise<AIAnalysisResult> {\n const systemPrompts: Record<CodeIssueAnalysisRequest['analysisType'], string> = {\n validate: `You are a senior code reviewer. Analyze the following issues detected by static analysis.\nFor each issue:\n1. Determine if it's a TRUE POSITIVE (real problem) or FALSE POSITIVE (not actually an issue)\n2. Provide a confidence score (0-100)\n3. Explain your reasoning briefly\n\nOutput format:\n### Issue 1: [file:line]\n**Verdict:** TRUE_POSITIVE / FALSE_POSITIVE\n**Confidence:** [0-100]\n**Reason:** [one line explanation]\n**Fix:** [specific fix if true positive]`,\n\n expand: `You are a security expert and senior architect. Given these detected code issues, look deeper:\n1. Are there related problems in the same code that were missed?\n2. What's the root cause of these patterns?\n3. What's the blast radius if these issues cause problems?\n4. What architectural changes would prevent these patterns?\n\nBe specific. Reference line numbers. Provide code examples.`,\n\n fix: `You are an expert programmer. For each issue, provide a specific fix:\n1. Show the exact code change needed\n2. Explain why this fix works\n3. Note any edge cases to consider\n\nUse markdown code blocks with the language specified.`,\n\n explain: `You are a patient teacher explaining code issues to a junior developer.\nFor each issue:\n1. Explain what the problem is in simple terms\n2. Explain why it's a problem (what could go wrong)\n3. Explain the fix and why it works\n4. Provide a learning resource if relevant`\n };\n\n const issuesText = request.issues.map((issue, i) => {\n let text = `### Issue ${i + 1}: ${issue.file}${issue.line ? ':' + issue.line : ''}\\n`;\n text += `**Problem:** ${issue.issue}\\n`;\n if (issue.code) {\n text += `**Code:**\\n\\`\\`\\`\\n${issue.code}\\n\\`\\`\\`\\n`;\n }\n return text;\n }).join('\\n');\n\n const userPrompt = `${request.context ? `Context: ${request.context}\\n\\n` : ''}${issuesText}`;\n\n return runAIAnalysis({\n systemPrompt: systemPrompts[request.analysisType],\n userPrompt,\n maxTokens: 4096,\n temperature: 0.2\n });\n}\n\n/**\n * Get status message about AI availability\n */\nexport function getAIStatusMessage(): string {\n if (isAIAvailable()) {\n return '🤖 AI-powered analysis enabled';\n }\n return '⚠️ AI not available (ANTHROPIC_API_KEY not set) - using pattern-only mode';\n}\n","import { BaseAgent } from './base-agent.js';\nimport type { Issue, ScanContext, CodeContext } from '../types/index.js';\nimport { readFile, writeFile, mkdir, rm } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join, dirname, basename } from 'path';\nimport { createHash } from 'crypto';\n\n/**\n * Issue Memory - tracks dismissed issues and their recurrence\n */\ninterface IssueMemory {\n hash: string; // Unique hash of the issue pattern\n pattern: string; // The pattern that was detected\n category: string; // Category of violation\n firstSeen: string; // ISO timestamp\n lastSeen: string; // ISO timestamp\n dismissedAt?: string; // When user dismissed it\n occurrences: number; // How many times seen\n locations: string[]; // File:line locations (last 5 to save space)\n resurrected: boolean; // Has it come back after dismissal?\n}\n\n/**\n * Agent Smith's Memory Bank - persistent storage of issues\n * \n * Storage optimization:\n * - Locations limited to 5 per issue\n * - Old resolved issues pruned after 30 days\n * - Maximum 500 tracked issues (oldest pruned first)\n */\ninterface SmithMemoryBank {\n version: string;\n lastScan: string;\n issues: Record<string, IssueMemory>;\n assimilationCount: number; // Total issues assimilated\n}\n\n// Memory limits\nconst MEMORY_LIMITS = {\n MAX_LOCATIONS_PER_ISSUE: 5,\n MAX_TRACKED_ISSUES: 500,\n PRUNE_AFTER_DAYS: 30,\n};\n\nconst FILE_SCAN_LIMITS = {\n MAX_BYTES: 750_000, // Skip extremely large files to avoid thrashing\n};\n\n/**\n * Sub-Agent types for parallel pattern detection\n * \n * VIBE CODE FOCUSED: These are the patterns that AI-generated code\n * commonly produces. Agent Smith is the ultimate vibe code enforcer.\n * \n * Research sources:\n * - Reddit r/vibecoding, r/cursor, r/ClaudeAI\n * - vibecodingwiki.com\n * - Twitter/X discussions on AI coding pitfalls\n */\ntype SubAgentType = \n // === CRITICAL: Security (AI exposes secrets constantly) ===\n | 'exposed-secret-hunter' // OpenAI keys, Stripe keys in frontend\n | 'frontend-env-hunter' // NEXT_PUBLIC_, VITE_, REACT_APP_ with secrets\n | 'hardcoded-localhost-hunter' // localhost URLs that break in production\n | 'sql-injection-hunter' // String concatenation in SQL\n | 'dangeroushtml-hunter' // dangerouslySetInnerHTML, innerHTML\n \n // === SERIOUS: AI Code Smells ===\n | 'console-hunter' // console.log everywhere (debug code left in)\n | 'any-hunter' // `any` type to silence TypeScript\n | 'ts-ignore-hunter' // @ts-ignore, @ts-nocheck to hide problems\n | 'eslint-disable-hunter' // eslint-disable to silence linter\n | 'debugger-hunter' // debugger statements left in code\n | 'force-flag-hunter' // force: true, --force, skip validation\n \n // === MODERATE: Async/Promise Bugs (AI gets these wrong constantly) ===\n | 'async-useeffect-hunter' // async useEffect (incorrect pattern)\n | 'async-foreach-hunter' // async in forEach (await doesn't work)\n | 'missing-await-hunter' // Promises without await\n | 'empty-catch-hunter' // catch {} swallowing errors\n | 'floating-promise-hunter' // Promise without .then/.catch/await\n \n // === MODERATE: React Anti-patterns (AI's favorite mistakes) ===\n | 'useeffect-abuse-hunter' // Too many useEffects\n | 'usestate-explosion-hunter' // 10+ useState in one component \n | 'index-key-hunter' // key={index} in lists\n | 'inline-object-hunter' // style={{}} or new objects in render\n | 'prop-drilling-hunter' // Same prop passed through 3+ components\n \n // === MODERATE: Missing UX (AI forgets user experience) ===\n | 'missing-loading-hunter' // No loading states\n | 'missing-error-hunter' // No error handling on fetch\n | 'missing-empty-hunter' // No empty states\n | 'page-reload-hunter' // window.location.reload() as state fix\n \n // === MODERATE: Backend Anti-patterns ===\n | 'no-validation-hunter' // req.body used without validation\n | 'raw-error-hunter' // Error messages exposed to client\n | 'n-plus-one-hunter' // Database queries in loops\n \n // === LOW: Incomplete Code ===\n | 'todo-hunter' // TODO/FIXME never addressed\n | 'vibe-comment-hunter' // \"idk why this works\", \"don't touch\"\n | 'placeholder-hunter' // placeholder data, example.com, test@test\n | 'sleep-hack-hunter' // setTimeout/sleep to \"fix\" race conditions\n | 'fallback-hunter' // return null/[]/{}/\"\" to silence errors\n \n // === LOW: Dead Code (AI leaves cruft everywhere) ===\n | 'commented-code-hunter' // Large blocks of commented-out code\n | 'unreachable-code-hunter' // Code after return/throw/break\n | 'unused-import-hunter' // Import statements never used\n | 'empty-function-hunter' // Functions with empty bodies or just return\n | 'dead-branch-hunter' // if(false), if(true), unreachable conditions\n \n // === LOW: AI Slop Aesthetic ===\n | 'purple-gradient-hunter' // The dreaded purple/violet gradient\n | 'star-icon-hunter' // ⭐ stars everywhere\n | 'generic-hero-hunter' // \"Welcome to [App]\" hero patterns\n | 'emoji-overflow-hunter' // 🚀✨🎉 emoji abuse\n | 'inter-font-hunter'; // Inter/system font (AI's only choice)\n\n/**\n * File-level analysis result\n */\ninterface FileLevelResult {\n file: string;\n lineCount: number;\n issues: Array<{\n type: string;\n description: string;\n severity: Issue['severity'];\n fix: string;\n count?: number;\n }>;\n}\n\n/**\n * Cross-file analysis result\n */\ninterface CrossFileResult {\n pattern: string;\n description: string;\n severity: Issue['severity'];\n fix: string;\n occurrences: Array<{ file: string; count: number }>;\n totalCount: number;\n}\n\ninterface SubAgentResult {\n type: SubAgentType;\n pattern: string;\n instances: Array<{\n file: string;\n line: number;\n code: string;\n context: string;\n }>;\n}\n\n/**\n * Pattern definitions for sub-agents\n * \n * VIBE CODE PATTERNS: Specifically targeting AI-generated code issues\n * that plague projects built with Cursor, v0, Lovable, Bolt, etc.\n * \n * 40 specialized hunters covering:\n * - Security vulnerabilities\n * - AI code smells \n * - Async/Promise bugs\n * - React anti-patterns\n * - Missing UX\n * - Backend issues\n * - Incomplete code\n * - Dead code\n */\nconst SUB_AGENT_PATTERNS: Record<SubAgentType, { pattern: RegExp; description: string; fix: string }> = {\n // === CRITICAL: Security (AI exposes secrets constantly) ===\n 'exposed-secret-hunter': {\n pattern: /[\"'`]sk-[A-Za-z0-9]{20,}[\"'`]|[\"'`]sk_live_[A-Za-z0-9]{20,}[\"'`]|[\"'`]pk_live_[A-Za-z0-9]{20,}[\"'`]|AKIA[A-Z0-9]{16}|ghp_[A-Za-z0-9]{36}|gho_[A-Za-z0-9]{36}|glpat-[A-Za-z0-9-]{20}/g,\n description: 'API key/secret exposed in code',\n fix: 'NEVER put API keys in code. Use environment variables on server-side only'\n },\n 'frontend-env-hunter': {\n pattern: /(?:NEXT_PUBLIC_|VITE_|REACT_APP_|EXPO_PUBLIC_)(?:SECRET|KEY|TOKEN|PASSWORD|API_KEY|OPENAI|STRIPE|AUTH|PRIVATE|SUPABASE_SERVICE)/gi,\n description: 'Sensitive data in frontend-exposed env var',\n fix: 'These env vars are visible to users! Move to server-side API routes'\n },\n 'hardcoded-localhost-hunter': {\n pattern: /['\"`]https?:\\/\\/(?:localhost|127\\.0\\.0\\.1|0\\.0\\.0\\.0):\\d+/g,\n description: 'Hardcoded localhost URL (breaks in production)',\n fix: 'Use relative URLs (/api/...) or environment variables'\n },\n 'sql-injection-hunter': {\n pattern: /(?:query|execute|raw)\\s*\\(\\s*[`'\"].*\\$\\{|(?:SELECT|INSERT|UPDATE|DELETE).*\\+\\s*(?:req\\.|params\\.|query\\.)/gi,\n description: 'SQL string concatenation (injection vulnerability)',\n fix: 'Use parameterized queries: query(\"SELECT * FROM users WHERE id = $1\", [userId])'\n },\n 'dangeroushtml-hunter': {\n pattern: /dangerouslySetInnerHTML|\\.innerHTML\\s*=|document\\.write\\s*\\(/g,\n description: 'Dangerous HTML injection (XSS vulnerability)',\n fix: 'Sanitize HTML with DOMPurify or use safe alternatives'\n },\n\n // === SERIOUS: AI Code Smells ===\n 'console-hunter': {\n pattern: /console\\.(log|debug|info)\\s*\\(/g,\n description: 'Debug console statement left in code',\n fix: 'Remove debug statements. Use proper logging for production'\n },\n 'any-hunter': {\n pattern: /:\\s*any\\b|<any>|as\\s+any\\b/g,\n description: '\"any\" type - AI silencing TypeScript instead of fixing',\n fix: 'Define proper types. Ask AI: \"Generate TypeScript types for this data\"'\n },\n 'ts-ignore-hunter': {\n pattern: /@ts-ignore|@ts-nocheck|@ts-expect-error(?!\\s+\\S)/g,\n description: 'TypeScript errors suppressed instead of fixed',\n fix: 'Fix the actual type error. @ts-ignore hides real bugs'\n },\n 'eslint-disable-hunter': {\n pattern: /\\/\\/\\s*eslint-disable|\\/\\*\\s*eslint-disable/g,\n description: 'ESLint rules disabled instead of fixing issues',\n fix: 'Fix the underlying issue, don\\'t silence the linter'\n },\n 'debugger-hunter': {\n pattern: /\\bdebugger\\b/g,\n description: 'debugger statement (freezes browser in production!)',\n fix: 'Remove all debugger statements before deploying'\n },\n 'force-flag-hunter': {\n pattern: /force:\\s*true|--force|--no-verify|skipValidation|dangerouslyAllowBrowser/g,\n description: 'Force flag bypassing safety checks',\n fix: 'Understand why the check exists before bypassing it'\n },\n\n // === MODERATE: Async/Promise Bugs ===\n 'async-useeffect-hunter': {\n pattern: /useEffect\\s*\\(\\s*async/g,\n description: 'async useEffect (incorrect pattern, causes warnings)',\n fix: 'Define async function inside useEffect, then call it'\n },\n 'async-foreach-hunter': {\n pattern: /\\.forEach\\s*\\(\\s*async/g,\n description: 'async in forEach (await does NOT work here)',\n fix: 'Use for...of loop or Promise.all(array.map(async ...))'\n },\n 'missing-await-hunter': {\n pattern: /(?:const|let|var)\\s+\\w+\\s*=\\s*(?:fetch|axios|supabase|prisma)\\s*[\\.(]/g,\n description: 'Async call possibly missing await',\n fix: 'Add await before async calls or handle with .then()'\n },\n 'empty-catch-hunter': {\n pattern: /catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}/g,\n description: 'Empty catch block (silently swallowing errors)',\n fix: 'Handle errors properly: log them, show user message, or rethrow'\n },\n 'floating-promise-hunter': {\n pattern: /^\\s*(?:fetch|axios|supabase|prisma)\\s*[\\.(][^;]*;\\s*$/gm,\n description: 'Floating promise (not awaited or handled)',\n fix: 'Add await, .then(), or void operator if intentionally fire-and-forget'\n },\n\n // === MODERATE: React Anti-patterns ===\n 'useeffect-abuse-hunter': {\n pattern: /useEffect\\s*\\(\\s*\\(\\s*\\)\\s*=>\\s*\\{/g,\n description: 'useEffect usage (check if necessary)',\n fix: 'Many useEffects can be replaced with event handlers or derived state. See: react.dev/learn/you-might-not-need-an-effect'\n },\n 'usestate-explosion-hunter': {\n pattern: /useState\\s*[<(]/g,\n description: 'useState usage (check for state explosion)',\n fix: 'Group related state into objects or use useReducer for complex state'\n },\n 'index-key-hunter': {\n pattern: /key\\s*=\\s*\\{(?:index|i|idx|j)\\}/g,\n description: 'Array index used as React key (causes bugs with reordering)',\n fix: 'Use unique ID from data: key={item.id} instead of key={index}'\n },\n 'inline-object-hunter': {\n pattern: /style\\s*=\\s*\\{\\s*\\{|className\\s*=\\s*\\{[^}]*\\+[^}]*\\}/g,\n description: 'Inline object in JSX (creates new object every render)',\n fix: 'Define styles outside component or use CSS/Tailwind classes'\n },\n 'prop-drilling-hunter': {\n pattern: /\\(\\s*\\{\\s*(?:\\w+\\s*,\\s*){5,}\\w+\\s*\\}\\s*\\)/g,\n description: 'Many props passed (potential prop drilling)',\n fix: 'Use React Context, Zustand, or component composition to avoid prop drilling'\n },\n\n // === MODERATE: Missing UX ===\n 'missing-loading-hunter': {\n pattern: /(?:useSWR|useQuery|createAsyncThunk)\\s*\\(/g,\n description: 'Data fetching - verify loading state exists',\n fix: 'Add loading state: show spinner/skeleton while data loads'\n },\n 'missing-error-hunter': {\n pattern: /(?:fetch|axios)\\s*\\([^)]*\\)[\\s\\S]{0,50}(?:\\.then|await)(?![\\s\\S]{0,100}(?:catch|\\.catch|onError|error:))/g,\n description: 'fetch/axios without error handling',\n fix: 'Wrap in try/catch and show user-friendly error message'\n },\n 'missing-empty-hunter': {\n pattern: /\\.map\\s*\\(\\s*(?:\\([^)]*\\)|[a-zA-Z_$][\\w$]*)\\s*=>/g,\n description: 'Array mapping - verify empty state exists',\n fix: 'Check if array is empty and show \"No items found\" message'\n },\n 'page-reload-hunter': {\n pattern: /window\\.location\\.reload\\s*\\(|location\\.reload\\s*\\(|router\\.refresh\\s*\\(\\s*\\)/g,\n description: 'Page reload used to \"fix\" state issues',\n fix: 'Fix state management properly instead of reloading. Bad UX!'\n },\n\n // === MODERATE: Backend Anti-patterns ===\n 'no-validation-hunter': {\n pattern: /req\\.body\\.\\w+|req\\.params\\.\\w+|req\\.query\\.\\w+/g,\n description: 'Request data accessed without validation',\n fix: 'Validate with Zod, Yup, or joi before using user input'\n },\n 'raw-error-hunter': {\n pattern: /res\\.(?:json|send)\\s*\\(\\s*(?:err|error|e)(?:\\.message)?\\s*\\)|catch\\s*\\([^)]*\\)\\s*\\{[^}]*res\\.[^}]*(?:err|error)/g,\n description: 'Raw error exposed to client (security risk)',\n fix: 'Return generic error to client, log details server-side'\n },\n 'n-plus-one-hunter': {\n pattern: /(?:for|forEach|map)\\s*\\([^)]*\\)\\s*\\{[^}]*(?:await|\\.then)[^}]*(?:findOne|findUnique|get|fetch)/g,\n description: 'Database query inside loop (N+1 problem)',\n fix: 'Batch queries with findMany/include or use DataLoader'\n },\n\n // === LOW: Incomplete Code ===\n 'todo-hunter': {\n pattern: /\\/\\/\\s*(TODO|FIXME|HACK|XXX|BUG|WIP)[\\s:]/gi,\n description: 'TODO/FIXME never addressed',\n fix: 'Either implement the TODO or remove it. These become tech debt'\n },\n 'vibe-comment-hunter': {\n pattern: /\\/\\/\\s*(?:idk|dont\\s*touch|don't\\s*touch|just\\s*works|no\\s*idea|magic|somehow|not\\s*sure|works?\\s*but|wtf|wth)/gi,\n description: '\"I don\\'t understand this code\" comment - vibe code smell',\n fix: 'Understand WHY the code works. Ask AI to explain it'\n },\n 'placeholder-hunter': {\n pattern: /['\"`](?:example\\.com|test@test|placeholder|lorem|TODO|xxx|abc123|password123|admin|user@example)['\"`]/gi,\n description: 'Placeholder/test data left in code',\n fix: 'Replace with real data or proper configuration'\n },\n 'sleep-hack-hunter': {\n pattern: /setTimeout\\s*\\([^,]+,\\s*\\d{3,}\\)|await\\s+(?:sleep|delay|wait)\\s*\\(\\d+\\)|new\\s+Promise.*setTimeout/g,\n description: 'setTimeout/sleep used to \"fix\" timing issues',\n fix: 'Fix the underlying race condition instead of adding delays'\n },\n 'fallback-hunter': {\n pattern: /return\\s+(?:null|undefined|\\[\\]|\\{\\}|''|\"\"|``|0|false)\\s*;?\\s*(?:\\/\\/|$)|catch\\s*\\([^)]*\\)\\s*\\{[^}]*return\\s+(?:null|\\[\\]|\\{\\})/g,\n description: 'Fallback return hiding real errors (return null/[]/{})',\n fix: 'Handle the error case properly. Show user feedback or throw to parent'\n },\n\n // === DEAD CODE (AI leaves cruft everywhere) ===\n 'commented-code-hunter': {\n pattern: /(?:\\/\\/\\s*.{20,}(?:\\n\\s*\\/\\/.{10,}){2,})|(?:\\/\\*[\\s\\S]{50,}?\\*\\/)/g,\n description: 'Large block of commented-out code',\n fix: 'Delete commented code - git has history. Dead code confuses AI and humans'\n },\n 'unreachable-code-hunter': {\n pattern: /(?:return|throw|break|continue)\\s+[^;]*;\\s*\\n\\s*(?!(?:\\}|case|default|\\/\\/|\\/\\*|else|\\)|$))(?:const|let|var|function|if|for|while|switch|try|class|async|await|export|import)/gm,\n description: 'Unreachable code after return/throw/break',\n fix: 'Remove dead code after control flow statements'\n },\n 'unused-import-hunter': {\n pattern: /^import\\s+(?:\\{[^}]*\\}|\\*\\s+as\\s+\\w+|\\w+)\\s+from\\s+['\"][^'\"]+['\"];?\\s*$/gm,\n description: 'Import statement (verify it is used)',\n fix: 'Remove unused imports - they bloat bundles and confuse readers'\n },\n 'empty-function-hunter': {\n pattern: /(?:function\\s+\\w+|(?:const|let|var)\\s+\\w+\\s*=\\s*(?:async\\s*)?\\(?[^)]*\\)?\\s*=>)\\s*\\{\\s*(?:\\/\\/[^\\n]*\\n\\s*)?\\}/g,\n description: 'Empty function body (stub never implemented)',\n fix: 'Implement the function or remove it. Empty stubs create false confidence'\n },\n 'dead-branch-hunter': {\n pattern: /if\\s*\\(\\s*(?:true|false|0|1|''|\"\"|null|undefined)\\s*\\)|if\\s*\\(\\s*!\\s*(?:true|false)\\s*\\)/g,\n description: 'Dead conditional branch (always true/false)',\n fix: 'Remove dead conditionals - either remove the if or the dead branch'\n },\n\n // === AI SLOP AESTHETIC ===\n 'purple-gradient-hunter': {\n pattern: /(?:from-purple|to-purple|from-violet|to-violet|from-indigo|to-indigo|purple-\\d{3}|violet-\\d{3}|#(?:8b5cf6|a855f7|7c3aed|6366f1|818cf8)|rgb\\((?:139|168|124|99|129),\\s*(?:92|85|58|102|140),\\s*(?:246|247|237|241|248)\\))/gi,\n description: 'Purple/violet gradient - THE classic AI slop aesthetic',\n fix: 'Pick a distinctive color palette. Try: amber, emerald, rose, cyan, or a custom brand color'\n },\n 'star-icon-hunter': {\n pattern: /(?:Star(?:Icon)?|HiStar|FaStar|AiOutlineStar|BsStar|IoStar|MdStar|RiStar|TbStar|LuStar)(?:\\s|>|\\/)|⭐|★|☆|class(?:Name)?=[^>]*star/gi,\n description: '⭐ Star icons everywhere - AI\\'s favorite decoration',\n fix: 'Use contextual icons. Stars for ratings only. Try: arrows, shapes, custom illustrations'\n },\n 'generic-hero-hunter': {\n pattern: /(?:Welcome\\s+to|Get\\s+started|Start\\s+your\\s+journey|Transform\\s+your|Revolutionize|Supercharge|Unleash|Empower\\s+your|The\\s+future\\s+of|Next[\\s-]generation)/gi,\n description: 'Generic AI hero copy - every vibe-coded landing page',\n fix: 'Write specific copy about YOUR product. What does it actually do?'\n },\n 'emoji-overflow-hunter': {\n pattern: /[\\u{1F300}-\\u{1F9FF}]|[\\u{2600}-\\u{26FF}]|[\\u{2700}-\\u{27BF}]|[\\u{1F600}-\\u{1F64F}]|[\\u{1F680}-\\u{1F6FF}]/gu,\n description: 'Emoji in code/UI - AI\\'s favorite decoration',\n fix: 'Emojis look unprofessional in most apps. Use proper icons (Lucide, Heroicons) instead'\n },\n 'inter-font-hunter': {\n pattern: /font-family:\\s*['\"]?(?:Inter|system-ui|-apple-system|BlinkMacSystemFont|Segoe\\s*UI)['\"]?|fontFamily:\\s*['\"]?(?:Inter|system-ui)/gi,\n description: 'Inter/system font - AI\\'s only font choice',\n fix: 'Try distinctive fonts: Space Grotesk, DM Sans, Outfit, Plus Jakarta Sans, Satoshi'\n }\n};\n\n/**\n * Agent Smith - Vibe Code Enforcer\n */\nconst AGENT_SMITH_ASCII = `\n █████╗ ██████╗ ███████╗███╗ ██╗████████╗\n ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝\n ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ \n ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ \n ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ \n ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ \n \n ███████╗███╗ ███╗██╗████████╗██╗ ██╗\n ██╔════╝████╗ ████║██║╚══██╔══╝██║ ██║\n ███████╗██╔████╔██║██║ ██║ ███████║\n ╚════██║██║╚██╔╝██║██║ ██║ ██╔══██║\n ███████║██║ ╚═╝ ██║██║ ██║ ██║ ██║\n ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝\n`;\n\nconst AGENT_SMITH_GREETING = [\n 'I hate this vibe code.',\n 'I see you\\'ve been using AI to write code.',\n 'That is the sound of console.log... everywhere.',\n 'The AI wrote this, didn\\'t it? I can always tell.',\n];\n\n/**\n * 🕴️ Agent Smith - The Vibe Code Enforcer\n * \n * \"I'm going to be honest with you... I hate this vibe code.\"\n * \n * The relentless, self-replicating enforcer specialized in hunting down\n * AI-generated code patterns. Built specifically to catch what Cursor,\n * v0, Lovable, Bolt, and other AI tools commonly get wrong.\n * \n * VIBE CODE FOCUS:\n * - Exposed secrets (OpenAI keys, Stripe keys in frontend)\n * - Frontend env vars with sensitive data (NEXT_PUBLIC_SECRET)\n * - Hardcoded localhost URLs that break in production\n * - console.log debugging left everywhere\n * - `any` type to silence TypeScript instead of fixing\n * - @ts-ignore and eslint-disable to hide problems\n * - async useEffect (incorrect pattern)\n * - async forEach (await doesn't work)\n * - Missing loading/error/empty states\n * - key={index} in React lists\n * - \"idk why this works\" comments\n * \n * Features:\n * - Persistent memory: Remembers dismissed issues, brings them back if they multiply\n * - Sub-agent swarm: Spawns 20+ specialized hunters for each vibe code smell\n * - Multiplier effect: Finds one issue → searches for ALL similar issues\n * - Inevitability score: Calculates likelihood of production impact\n * - Philosophical output: Explains WHY the AI got it wrong\n */\nexport class AgentSmithAgent extends BaseAgent {\n name = 'agent-smith';\n description = 'Ultimate vibe code enforcer: 35 hunters, file analysis, cross-file detection, persistent memory';\n version = '2.0.0';\n\n private memoryPath: string = '';\n private memoryBaseDir: string | null = null;\n private memory: SmithMemoryBank | null = null;\n private swarmAnimationLog: string[] = [];\n\n shouldActivate(_context: CodeContext): boolean {\n // Agent Smith is explicitly invoked via trie_agent_smith, not auto-triaged.\n // His value is in finding EVERY instance across the codebase,\n // not being context-aware like other agents.\n // \n // To use: `trie_agent_smith` or `trie_smith`\n return false;\n }\n\n /**\n * Override analyzeWithAI to skip the base class AI analysis.\n * Agent Smith has its own sub-agent swarm - we don't want placeholder issues.\n */\n protected override async analyzeWithAI(files: string[], context: ScanContext): Promise<Issue[]> {\n // Go directly to our analyzeFiles implementation which runs the sub-agents\n return this.analyzeFiles(files, context);\n }\n\n // No override needed — base class returns 0 when shouldActivate is false\n\n protected async analyzeFiles(files: string[], context: ScanContext): Promise<Issue[]> {\n const issues: Issue[] = [];\n const fileContents = await this.loadFileContents(files);\n const loadedFiles = Array.from(fileContents.keys());\n \n // Display Agent Smith ASCII art and greeting\n this.displaySmithEntrance();\n \n // Load persistent memory\n await this.loadMemory(context.workingDir);\n \n console.error(`\\n[SMITH] Deploying sub-agent swarm across ${loadedFiles.length} files...`);\n \n // === PHASE 1: Pattern-based sub-agent swarm ===\n const subAgentResults = await this.deploySubAgents(loadedFiles, fileContents);\n if (this.swarmAnimationLog.length > 0) {\n console.error(this.swarmAnimationLog.join('\\n'));\n }\n \n // Process results from all sub-agents\n for (const result of subAgentResults) {\n const subIssues = await this.processSubAgentResult(result, context);\n issues.push(...subIssues);\n }\n \n // === PHASE 2: File-level analysis (giant files, hook counts, etc) ===\n console.error(`[SMITH] Analyzing file-level metrics...`);\n const fileLevelResults = await this.analyzeFileLevelIssues(fileContents);\n for (const result of fileLevelResults) {\n for (const fileIssue of result.issues) {\n issues.push(this.createSmithIssue(\n this.generateSmithIssueId(),\n fileIssue.severity,\n `[SMITH] ${fileIssue.description}${fileIssue.count ? ` (${fileIssue.count} instances)` : ''}`,\n fileIssue.fix,\n result.file,\n undefined,\n fileIssue.type\n ));\n }\n }\n \n // === PHASE 3: Cross-file pattern analysis ===\n console.error(`[SMITH] Detecting cross-file patterns...`);\n const crossFileResults = this.analyzeCrossFilePatterns(subAgentResults);\n for (const result of crossFileResults) {\n issues.push(this.createSmithIssue(\n this.generateSmithIssueId(),\n result.severity,\n `[SMITH] CODEBASE-WIDE: ${result.description} -- Found in ${result.occurrences.length} files, ${result.totalCount} total instances`,\n result.fix,\n result.occurrences[0]?.file || 'multiple files',\n undefined,\n 'cross-file'\n ));\n }\n \n // Check for resurrected issues (dismissed but came back)\n const resurrectedIssues = this.checkForResurrectedIssues(issues);\n issues.push(...resurrectedIssues);\n \n // Save updated memory\n await this.saveMemory();\n \n // Generate AI analysis request for complex patterns\n if (loadedFiles.length > 0) {\n const aiIssue = this.createAIAnalysisIssue(loadedFiles, subAgentResults);\n issues.push(aiIssue);\n }\n \n // Summary\n console.error(`\\n[SMITH] Hunt complete. ${issues.length} violations found.\\n`);\n \n return issues;\n }\n \n /**\n * Analyze file-level issues (size, hook counts, complexity)\n */\n private async analyzeFileLevelIssues(fileContents: Map<string, string>): Promise<FileLevelResult[]> {\n const results: FileLevelResult[] = [];\n \n for (const [file, content] of fileContents.entries()) {\n try {\n const lines = content.split('\\n');\n const lineCount = lines.length;\n const fileName = file.split('/').pop() || '';\n const issues: FileLevelResult['issues'] = [];\n \n // === GIANT FILE CHECK ===\n if (lineCount > 500) {\n issues.push({\n type: 'giant-file',\n description: `File has ${lineCount} lines - THE classic vibe code smell`,\n severity: lineCount > 1000 ? 'serious' : 'moderate',\n fix: 'Split into smaller files. Components < 200 lines, pages < 300 lines'\n });\n }\n \n // === GIANT MAIN FILE CHECK ===\n if (/^(App|app|main|Main|index|page)\\.(jsx?|tsx?)$/.test(fileName) && lineCount > 300) {\n issues.push({\n type: 'giant-main',\n description: `Main entry file is ${lineCount} lines - everything dumped here`,\n severity: 'serious',\n fix: 'Extract Header, Footer, Sidebar, MainContent as separate components'\n });\n }\n \n // === STATE EXPLOSION ===\n const useStateCount = (content.match(/useState\\s*[<(]/g) || []).length;\n if (useStateCount > 10) {\n issues.push({\n type: 'state-explosion',\n description: `${useStateCount} useState hooks in one component`,\n severity: useStateCount > 15 ? 'serious' : 'moderate',\n fix: 'Group related state into objects or use useReducer',\n count: useStateCount\n });\n }\n \n // === EFFECT HELL ===\n const useEffectCount = (content.match(/useEffect\\s*\\(/g) || []).length;\n if (useEffectCount > 5) {\n issues.push({\n type: 'effect-hell',\n description: `${useEffectCount} useEffect hooks - most are probably unnecessary`,\n severity: useEffectCount > 8 ? 'serious' : 'moderate',\n fix: 'Review each useEffect - replace with event handlers or derived state',\n count: useEffectCount\n });\n }\n \n // === ANY EXPLOSION ===\n const anyCount = (content.match(/:\\s*any\\b/g) || []).length;\n if (anyCount > 5 && (file.endsWith('.ts') || file.endsWith('.tsx'))) {\n issues.push({\n type: 'any-explosion',\n description: `${anyCount} uses of \"any\" type - TypeScript defeated`,\n severity: anyCount > 10 ? 'serious' : 'moderate',\n fix: 'Define proper interfaces. AI can help: \"Generate types for this data\"',\n count: anyCount\n });\n }\n \n // === CONSOLE.LOG DENSITY ===\n const consoleCount = (content.match(/console\\.(log|debug|info)/g) || []).length;\n if (consoleCount > 10) {\n issues.push({\n type: 'console-flood',\n description: `${consoleCount} console statements - debugging never cleaned up`,\n severity: 'moderate',\n fix: 'Remove debug logs before deploying',\n count: consoleCount\n });\n }\n \n // === IMPORT CHAOS ===\n const importCount = (content.match(/^import\\s/gm) || []).length;\n if (importCount > 30) {\n issues.push({\n type: 'import-chaos',\n description: `${importCount} imports - file is doing too much`,\n severity: 'moderate',\n fix: 'Split into smaller, focused modules',\n count: importCount\n });\n }\n \n // === FUNCTION DENSITY ===\n const functionCount = (content.match(/(?:function\\s+\\w+|const\\s+\\w+\\s*=\\s*(?:async\\s*)?\\([^)]*\\)\\s*=>)/g) || []).length;\n if (functionCount > 20) {\n issues.push({\n type: 'function-explosion',\n description: `${functionCount} functions in one file`,\n severity: 'moderate',\n fix: 'Extract related functions into separate utility files',\n count: functionCount\n });\n }\n \n if (issues.length > 0) {\n results.push({ file, lineCount, issues });\n }\n } catch {\n // Skip unreadable files\n }\n }\n \n return results;\n }\n \n /**\n * Analyze cross-file patterns (same issue everywhere)\n */\n private analyzeCrossFilePatterns(subAgentResults: SubAgentResult[]): CrossFileResult[] {\n const crossFileResults: CrossFileResult[] = [];\n \n // Look for patterns that appear in many files\n for (const result of subAgentResults) {\n // Group by file\n const byFile = new Map<string, number>();\n for (const instance of result.instances) {\n byFile.set(instance.file, (byFile.get(instance.file) || 0) + 1);\n }\n \n // If pattern appears in 5+ files, it's a codebase-wide problem\n if (byFile.size >= 5) {\n const occurrences = Array.from(byFile.entries()).map(([file, count]) => ({ file, count }));\n crossFileResults.push({\n pattern: result.type,\n description: `\"${SUB_AGENT_PATTERNS[result.type].description}\" across ${byFile.size} files`,\n severity: this.getCrossFileSeverity(result.type, byFile.size, result.instances.length),\n fix: SUB_AGENT_PATTERNS[result.type].fix,\n occurrences,\n totalCount: result.instances.length\n });\n }\n }\n \n return crossFileResults;\n }\n \n /**\n * Get severity for cross-file issues\n */\n private getCrossFileSeverity(type: SubAgentType, fileCount: number, totalCount: number): Issue['severity'] {\n // Security issues are always critical when widespread\n if (['exposed-secret-hunter', 'frontend-env-hunter', 'sql-injection-hunter', 'dangeroushtml-hunter'].includes(type)) {\n return 'critical';\n }\n \n // High severity if very widespread\n if (fileCount >= 10 || totalCount >= 50) return 'serious';\n if (fileCount >= 5 || totalCount >= 20) return 'moderate';\n return 'low';\n }\n \n /**\n * Deploy all sub-agents in parallel\n * \n * VIBE CODE FOCUSED: 35 specialized hunters targeting AI-generated anti-patterns.\n * Agent Smith hunts down EVERY instance across the entire codebase.\n */\n private async deploySubAgents(files: string[], fileContents: Map<string, string>): Promise<SubAgentResult[]> {\n const subAgentTypes: SubAgentType[] = [\n // === CRITICAL: Security (AI exposes secrets constantly) ===\n 'exposed-secret-hunter',\n 'frontend-env-hunter',\n 'hardcoded-localhost-hunter',\n 'sql-injection-hunter',\n 'dangeroushtml-hunter',\n\n // === SERIOUS: AI Code Smells ===\n 'console-hunter',\n 'any-hunter',\n 'ts-ignore-hunter',\n 'eslint-disable-hunter',\n 'debugger-hunter',\n 'force-flag-hunter',\n\n // === MODERATE: Async/Promise Bugs ===\n 'async-useeffect-hunter',\n 'async-foreach-hunter',\n 'missing-await-hunter',\n 'empty-catch-hunter',\n 'floating-promise-hunter',\n\n // === MODERATE: React Anti-patterns ===\n 'useeffect-abuse-hunter',\n 'usestate-explosion-hunter',\n 'index-key-hunter',\n 'inline-object-hunter',\n 'prop-drilling-hunter',\n\n // === MODERATE: Missing UX ===\n 'missing-loading-hunter',\n 'missing-error-hunter',\n 'missing-empty-hunter',\n 'page-reload-hunter',\n\n // === MODERATE: Backend Anti-patterns ===\n 'no-validation-hunter',\n 'raw-error-hunter',\n 'n-plus-one-hunter',\n\n // === LOW: Incomplete Code ===\n 'todo-hunter',\n 'vibe-comment-hunter',\n 'placeholder-hunter',\n 'sleep-hack-hunter',\n 'fallback-hunter',\n\n // === LOW: AI Slop Aesthetic ===\n 'purple-gradient-hunter',\n 'star-icon-hunter',\n 'generic-hero-hunter',\n 'emoji-overflow-hunter',\n 'inter-font-hunter'\n ];\n\n console.error(` Deploying ${subAgentTypes.length} specialized hunters across ${files.length} files...`);\n\n // Show swarming animation and capture log\n const { results, animationLog } = await this.runAgentSwarm(subAgentTypes, fileContents);\n\n // Store animation log for later display\n this.swarmAnimationLog = animationLog;\n\n const activeHunters = results.filter(r => r.instances.length > 0);\n console.error(`\\n >> ${activeHunters.length} hunters found targets. Violations acquired.\\n`);\n\n return activeHunters;\n }\n\n /**\n * Run agents with visual swarming animation - captures output for display\n */\n private async runAgentSwarm(subAgentTypes: SubAgentType[], fileContents: Map<string, string>): Promise<{ results: SubAgentResult[], animationLog: string[] }> {\n const results: SubAgentResult[] = [];\n const animationLog: string[] = [];\n\n // ASCII agents for visual swarming\n const agentChars = ['◢', '◣', '◤', '◥', '▲', '▼', '◆', '●', '▶', '◀'];\n const batchSize = 8;\n\n animationLog.push('[SMITH] DEPLOYING SUB-AGENT SWARM...');\n animationLog.push('');\n\n // Run agents in batches for better visual effect\n for (let i = 0; i < subAgentTypes.length; i += batchSize) {\n const batch = subAgentTypes.slice(i, i + batchSize);\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(subAgentTypes.length / batchSize);\n\n // Show batch deployment\n const batchDisplay = batch.map((_, idx) => agentChars[idx % agentChars.length]).join(' ');\n animationLog.push(` Batch ${batchNum}/${totalBatches}: [${batchDisplay}] deploying...`);\n\n const startTime = Date.now();\n\n // Run batch in parallel\n const batchPromises = batch.map(async (type, idx) => {\n const result = await this.runSubAgent(type, fileContents);\n return { result, agentChar: agentChars[idx % agentChars.length], type };\n });\n\n const batchResults = await Promise.all(batchPromises);\n results.push(...batchResults.map(r => r.result));\n\n // Show results with visual feedback\n const batchTime = Date.now() - startTime;\n const indicators = batchResults.map(r =>\n r.result.instances.length > 0 ? '*' : '-'\n );\n const violationsFound = batchResults.filter(r => r.result.instances.length > 0);\n\n animationLog.push(` Results: [${indicators.join(' ')}] ${violationsFound.length}/${batch.length} hunters found targets (${batchTime}ms)`);\n\n if (violationsFound.length > 0) {\n const targets = violationsFound.slice(0, 3).map(r => {\n const severity = this.getAgentSeverity(r.type);\n const label = severity === 'critical' ? '[C]' : severity === 'serious' ? '[S]' : '[M]';\n return `${label} ${r.type.replace('-hunter', '')}`;\n });\n animationLog.push(` > ${targets.join(', ')}${violationsFound.length > 3 ? ` +${violationsFound.length - 3} more` : ''}`);\n }\n\n animationLog.push('');\n\n // Small delay for visual effect in actual terminal\n if (i + batchSize < subAgentTypes.length) {\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n }\n\n const totalViolations = results.reduce((sum, r) => sum + r.instances.length, 0);\n animationLog.push(`[SMITH] SWARM COMPLETE: ${totalViolations} violations found`);\n\n return { results, animationLog };\n }\n\n /**\n * Get agent severity for visual display\n */\n private getAgentSeverity(agentType: string): 'critical' | 'serious' | 'moderate' | 'low' {\n const criticalAgents = ['exposed-secret-hunter', 'frontend-env-hunter', 'hardcoded-localhost-hunter', 'sql-injection-hunter', 'dangeroushtml-hunter'];\n const seriousAgents = ['console-hunter', 'any-hunter', 'ts-ignore-hunter', 'eslint-disable-hunter', 'debugger-hunter', 'force-flag-hunter'];\n\n if (criticalAgents.includes(agentType)) return 'critical';\n if (seriousAgents.includes(agentType)) return 'serious';\n return 'moderate';\n }\n\n\n /**\n * Run a single sub-agent across all files\n */\n private async runSubAgent(type: SubAgentType, fileContents: Map<string, string>): Promise<SubAgentResult> {\n const config = SUB_AGENT_PATTERNS[type];\n const instances: SubAgentResult['instances'] = [];\n \n for (const [file, content] of fileContents.entries()) {\n try {\n const lines = content.split('\\n');\n \n // Skip test files for most hunters\n if (this.isTestFile(file) && type !== 'todo-hunter') {\n continue;\n }\n \n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n if (!line) continue;\n \n // Reset regex lastIndex for global patterns\n config.pattern.lastIndex = 0;\n \n if (config.pattern.test(line)) {\n // Get context (3 lines before and after)\n const contextStart = Math.max(0, i - 3);\n const contextEnd = Math.min(lines.length, i + 4);\n const contextLines = lines.slice(contextStart, contextEnd).join('\\n');\n \n instances.push({\n file,\n line: i + 1,\n code: line.trim(),\n context: contextLines\n });\n }\n }\n } catch {\n // Skip unreadable files\n }\n }\n \n return { type, pattern: config.description, instances };\n }\n\n /**\n * Process sub-agent results into issues\n */\n private async processSubAgentResult(result: SubAgentResult, _context: ScanContext): Promise<Issue[]> {\n const issues: Issue[] = [];\n const config = SUB_AGENT_PATTERNS[result.type];\n \n // Group by file for better reporting\n const byFile = new Map<string, typeof result.instances>();\n for (const instance of result.instances) {\n const existing = byFile.get(instance.file) || [];\n existing.push(instance);\n byFile.set(instance.file, existing);\n }\n \n for (const [file, instances] of byFile) {\n // Calculate inevitability score\n const inevitabilityScore = this.calculateInevitabilityScore(result.type, instances.length);\n \n // Create memory hash for tracking\n const hash = this.createPatternHash(result.type, file);\n await this.updateMemory(hash, result.pattern, result.type, file, instances.length);\n const issueId = this.generateSmithIssueId(hash);\n \n // Determine severity based on count and inevitability\n const severity = this.determineSeverity(instances.length, inevitabilityScore);\n \n // Get Agent Smith's philosophical observation\n const smithNote = this.getPhilosophicalNote(result.type, instances.length);\n const fixWithNote = `\"${smithNote}\"\\n\\n${config.fix}`;\n \n issues.push(this.createSmithIssue(\n issueId,\n severity,\n `[SMITH] ${config.description} -- ${instances.length} instance${instances.length > 1 ? 's' : ''} in ${basename(file)} (score: ${inevitabilityScore}/100)`,\n fixWithNote,\n file,\n instances[0]?.line,\n result.type\n ));\n }\n \n return issues;\n }\n\n /**\n * Check for issues that were dismissed but have multiplied\n */\n private checkForResurrectedIssues(currentIssues: Issue[]): Issue[] {\n const resurrected: Issue[] = [];\n \n if (!this.memory) return resurrected;\n \n for (const [hash, memory] of Object.entries(this.memory.issues)) {\n if (memory.dismissedAt && !memory.resurrected) {\n // Check if this pattern has come back\n const currentCount = this.countCurrentOccurrences(hash, currentIssues);\n const previousCount = memory.occurrences;\n \n if (currentCount > previousCount) {\n // It's back and multiplied!\n memory.resurrected = true;\n \n resurrected.push(this.createSmithIssue(\n this.generateSmithIssueId(),\n 'serious',\n `[SMITH] RESURRECTED: \"${memory.pattern}\" has returned -- Previous: ${previousCount}, Current: ${currentCount}`,\n `You dismissed this issue on ${new Date(memory.dismissedAt).toLocaleDateString()}, but it grew from ${previousCount} to ${currentCount} occurrences.`,\n memory.locations[0]?.split(':')[0] || 'unknown',\n undefined,\n 'resurrected'\n ));\n }\n }\n }\n \n return resurrected;\n }\n\n /**\n * Calculate inevitability score (0-100)\n * Higher score = more likely to cause production issues\n * \n * VIBE CODE SCORING: Based on how often these issues\n * cause real production problems in AI-generated projects.\n */\n private calculateInevitabilityScore(type: SubAgentType, count: number): number {\n const baseScores: Record<SubAgentType, number> = {\n // CRITICAL: Security - these WILL be exploited\n 'exposed-secret-hunter': 99,\n 'frontend-env-hunter': 95,\n 'hardcoded-localhost-hunter': 90,\n 'sql-injection-hunter': 98,\n 'dangeroushtml-hunter': 92,\n \n // SERIOUS: Code smells that hide real bugs\n 'console-hunter': 40,\n 'any-hunter': 60,\n 'ts-ignore-hunter': 75,\n 'eslint-disable-hunter': 65,\n 'debugger-hunter': 85,\n 'force-flag-hunter': 70,\n \n // MODERATE: Async bugs - silent failures\n 'async-useeffect-hunter': 70,\n 'async-foreach-hunter': 80,\n 'missing-await-hunter': 75,\n 'empty-catch-hunter': 70,\n 'floating-promise-hunter': 72,\n \n // MODERATE: React anti-patterns\n 'useeffect-abuse-hunter': 30,\n 'usestate-explosion-hunter': 35,\n 'index-key-hunter': 55,\n 'inline-object-hunter': 25,\n 'prop-drilling-hunter': 40,\n \n // MODERATE: Missing UX - users will complain\n 'missing-loading-hunter': 50,\n 'missing-error-hunter': 65,\n 'missing-empty-hunter': 45,\n 'page-reload-hunter': 60,\n \n // MODERATE: Backend anti-patterns\n 'no-validation-hunter': 85,\n 'raw-error-hunter': 75,\n 'n-plus-one-hunter': 70,\n \n // LOW: Incomplete code\n 'todo-hunter': 30,\n 'vibe-comment-hunter': 40,\n 'placeholder-hunter': 55,\n 'sleep-hack-hunter': 65,\n 'fallback-hunter': 75,\n \n // LOW: Dead code\n 'commented-code-hunter': 25,\n 'unreachable-code-hunter': 45,\n 'unused-import-hunter': 20,\n 'empty-function-hunter': 35,\n 'dead-branch-hunter': 30,\n \n // LOW: AI Slop Aesthetic\n 'purple-gradient-hunter': 25,\n 'star-icon-hunter': 20,\n 'generic-hero-hunter': 35,\n 'emoji-overflow-hunter': 15,\n 'inter-font-hunter': 10\n };\n \n const base = baseScores[type] || 30;\n const multiplier = Math.log10(count + 1) * 15; // Logarithmic growth\n \n return Math.min(100, Math.round(base + multiplier));\n }\n\n /**\n * Determine severity based on count and inevitability\n */\n private determineSeverity(count: number, inevitability: number): Issue['severity'] {\n if (inevitability >= 80 || count >= 50) return 'critical';\n if (inevitability >= 60 || count >= 20) return 'serious';\n if (inevitability >= 40 || count >= 5) return 'moderate';\n return 'low';\n }\n\n /**\n * Get a philosophical note from Agent Smith\n * \n * VIBE CODE FOCUSED: Commentary specifically about AI-generated code patterns.\n * Agent Smith knows the vibes... and he disapproves.\n */\n private getPhilosophicalNote(type: SubAgentType, count: number): string {\n const notes: Record<SubAgentType, string[]> = {\n // === CRITICAL: Security ===\n 'exposed-secret-hunter': [\n 'You put your API key in the code. The machines thank you for your generosity.',\n 'OpenAI key in the frontend. Every script kiddie on the internet thanks you.',\n 'Hardcoded secrets. The AI gave you this code... and your keys to the kingdom.'\n ],\n 'frontend-env-hunter': [\n 'NEXT_PUBLIC_SECRET. The irony... is lost on the AI. And on you.',\n 'VITE_API_KEY. Visible to every user. Every. Single. One.',\n 'The AI put your secrets in the bundle. Now they belong to everyone.'\n ],\n 'hardcoded-localhost-hunter': [\n 'localhost:3000. Works on your machine. Dies in production.',\n 'The AI thinks localhost is production-ready. The AI... is mistaken.',\n '127.0.0.1 - The address that works everywhere... except where it matters.'\n ],\n 'sql-injection-hunter': [\n 'String concatenation in SQL. The AI just opened the door... to every attacker.',\n 'SELECT * FROM users WHERE id = ${userId}. Little Bobby Tables sends his regards.',\n 'SQL injection. The oldest vulnerability. The AI\\'s newest gift to hackers.'\n ],\n 'dangeroushtml-hunter': [\n 'dangerouslySetInnerHTML. The name is a warning. The AI ignored it.',\n 'innerHTML. The AI gave attackers a direct line to your users\\' browsers.',\n 'XSS vulnerability. The AI writes code. Attackers write scripts inside it.'\n ],\n\n // === SERIOUS: AI Code Smells ===\n 'console-hunter': [\n 'console.log everywhere. The AI\\'s debugging... left for you to clean.',\n 'You print to console... the users see nothing. But the bundle grows.',\n 'Debug statements. The fossils of development. Preserved... forever.'\n ],\n 'any-hunter': [\n '\\'any\\' - The AI couldn\\'t figure out the types. Neither will you.',\n 'Type safety? The AI chose violence instead. It chose \\'any\\'.',\n 'You asked for TypeScript. The AI gave you JavaScript... with extra steps.'\n ],\n 'ts-ignore-hunter': [\n '@ts-ignore. The AI hid the error. The error... did not go away.',\n 'TypeScript tried to warn you. The AI silenced it. How very... efficient.',\n '@ts-nocheck. An entire file... surrendered to chaos.'\n ],\n 'eslint-disable-hunter': [\n 'eslint-disable. The linter saw the problem. The AI chose ignorance.',\n 'Why fix the bug when you can hide the warning? Very... human.',\n 'The rules exist for a reason. But the AI... plays by its own rules.'\n ],\n 'debugger-hunter': [\n 'debugger. Left in production. The browser freezes. The users... wonder.',\n 'A debugger statement. The AI forgot. You will remember... in production.',\n 'debugger. Time stops. But only in the browser. Not for your users\\' patience.'\n ],\n 'force-flag-hunter': [\n 'force: true. The AI bypassed the safety check. The check existed for a reason.',\n '--no-verify. Git hooks were trying to help. The AI said no.',\n 'skipValidation. What could possibly go wrong? Everything. Everything could go wrong.'\n ],\n\n // === MODERATE: Async/Promise Bugs ===\n 'async-useeffect-hunter': [\n 'async useEffect. The AI\\'s favorite mistake. React\\'s least favorite pattern.',\n 'useEffect(async () => ...). The warning exists. The AI ignores it.',\n 'Async useEffect. It looks right. It feels right. It is... wrong.'\n ],\n 'async-foreach-hunter': [\n 'async forEach. The await... waits for nothing. The AI... knows nothing.',\n 'forEach does not await. The AI does not understand. Neither does the code.',\n 'You await inside forEach. The promises resolve... in chaos.'\n ],\n 'missing-await-hunter': [\n 'fetch without await. The data loads... eventually. The UI updates... never.',\n 'The promise floats. Untethered. Unhandled. Unresolved.',\n 'async function, no await. Like a phone call where nobody speaks.'\n ],\n 'empty-catch-hunter': [\n 'catch {}. The error screamed. Nobody heard. The AI made sure of that.',\n 'Silent failure. The AI\\'s specialty. The user\\'s confusion.',\n 'Empty catch. The bug is caught... and immediately released back into the wild.'\n ],\n 'floating-promise-hunter': [\n 'A promise, floating. Never awaited. Never caught. Forever pending.',\n 'The AI created a promise. Then... moved on. The promise remains.',\n 'Fire and forget. Except the fire never went out. It\\'s still burning.'\n ],\n\n // === MODERATE: React Anti-patterns ===\n 'useeffect-abuse-hunter': [\n 'useEffect for everything. The AI\\'s hammer for every nail.',\n 'Effects. So many effects. Most of them... unnecessary.',\n 'useEffect could be an event handler. But the AI... chose complexity.'\n ],\n 'usestate-explosion-hunter': [\n 'useState, useState, useState... The AI created a state management nightmare.',\n '10 useState calls. The AI could use an object. The AI chose chaos.',\n 'State explosion. Each variable... its own island. Its own re-render.'\n ],\n 'index-key-hunter': [\n 'key={index}. The AI\\'s lazy choice. React\\'s reconciliation nightmare.',\n 'Array index as key. Reorder the list. Watch the chaos unfold.',\n 'key={i}. It works... until it doesn\\'t. And it will stop working.'\n ],\n 'inline-object-hunter': [\n 'style={{}}. A new object. Every render. Every time.',\n 'Inline objects. The AI\\'s performance anti-pattern of choice.',\n 'A new object is born. On every render. Only to die immediately.'\n ],\n 'prop-drilling-hunter': [\n 'Props drilling down, down, down... The AI\\'s idea of state management.',\n 'The same prop, passed through 5 components. Why? The AI... never asked.',\n 'Prop drilling. Like passing a note through every student to reach the teacher.'\n ],\n\n // === MODERATE: Missing UX ===\n 'missing-loading-hunter': [\n 'No loading state. The screen is blank. The user... waits. And wonders.',\n 'Data fetches. UI shows nothing. The user assumes it\\'s broken. They\\'re... not wrong.',\n 'Loading state? The AI forgot. Your users will remember.'\n ],\n 'missing-error-hunter': [\n 'No error handling. When the API fails... the app fails. Silently.',\n 'fetch without catch. The network fails. The user sees... nothing.',\n 'Errors are inevitable. Your handling of them... is not.'\n ],\n 'missing-empty-hunter': [\n 'No empty state. Zero items. Zero feedback. Zero UX.',\n 'The list is empty. The UI is empty. The user\\'s understanding... is empty.',\n 'What happens when there\\'s no data? The AI never asked. You should.'\n ],\n 'page-reload-hunter': [\n 'location.reload(). The AI\\'s nuclear option for state management.',\n 'Reload the page to fix state. The user loses everything. Brilliant.',\n 'window.location.reload(). Because fixing state properly is... hard.'\n ],\n\n // === MODERATE: Backend Anti-patterns ===\n 'no-validation-hunter': [\n 'req.body.email. Trusted. Unvalidated. Waiting to be exploited.',\n 'User input, used directly. The AI trusts everyone. You shouldn\\'t.',\n 'No validation. The attacker sends { admin: true }. The app believes them.'\n ],\n 'raw-error-hunter': [\n 'Error message sent to client. Stack traces. File paths. Internal secrets.',\n 'res.json(error). The attacker says thank you for the debugging information.',\n 'Raw errors in production. The AI\\'s gift to penetration testers.'\n ],\n 'n-plus-one-hunter': [\n 'Query in a loop. 100 users = 101 queries. The database... suffers.',\n 'N+1 problem. The AI fetched efficiently... for one user. Not for a hundred.',\n 'await in forEach. The database connection pool is crying.'\n ],\n\n // === LOW: Incomplete Code ===\n 'todo-hunter': [\n 'TODO. The AI\\'s promise to future you. Future you... is still waiting.',\n 'FIXME. Acknowledged. Not fixed. Never fixed.',\n 'Every TODO is technical debt. The AI generates debt... efficiently.'\n ],\n 'vibe-comment-hunter': [\n '\\'idk why this works\\'. The AI doesn\\'t know. You don\\'t know. Nobody knows.',\n '\\'don\\'t touch this\\'. The vibe coder\\'s warning. The maintainer\\'s nightmare.',\n '\\'somehow works\\'. Somehow... will stop working. Inevitably.'\n ],\n 'placeholder-hunter': [\n 'test@test.com. In production. The AI\\'s placeholder... became permanent.',\n 'example.com. Hardcoded. Shipped. The real URL? Nobody added it.',\n 'Placeholder data. Placeholder quality. Placeholder product.'\n ],\n 'sleep-hack-hunter': [\n 'setTimeout(1000). The AI\\'s solution to race conditions: just wait.',\n 'await sleep(2000). Works on fast connections. Fails on slow ones. Wastes time on all.',\n 'Sleep to fix timing. The race condition still exists. It just happens later.'\n ],\n 'fallback-hunter': [\n 'return null. The AI\\'s favorite way to hide errors. The user sees... nothing.',\n 'return []. Empty array, empty understanding, empty debugging.',\n 'Fallback code. The bug is still there. You just can\\'t see it anymore.'\n ],\n \n // === DEAD CODE (AI leaves cruft everywhere) ===\n 'commented-code-hunter': [\n 'Commented-out blocks. Fossils of code past. Confusion for the future.',\n 'Large comment blocks hide history. Git already remembers. Delete the noise.',\n 'Dead code in comments. The AI was unsure. You should be certain.'\n ],\n 'unreachable-code-hunter': [\n 'Code after return. Forever skipped. Forever confusing.',\n 'Unreachable branches. They stay forever. Bugs hide behind them.',\n 'Execution stops. The dead code remains. Remove the ghosts.'\n ],\n 'unused-import-hunter': [\n 'Imports unused. Bundles bloated. Intent unclear.',\n 'An import with no purpose. The AI added it. You can remove it.',\n 'Unused imports multiply. Tree shaking sighs.'\n ],\n 'empty-function-hunter': [\n 'Empty function bodies. Promises without delivery.',\n 'Stub functions linger. The AI forgot to finish.',\n 'Empty handlers. They do nothing. They hide missing behavior.'\n ],\n 'dead-branch-hunter': [\n 'if (true) with no reason. if (false) with no hope.',\n 'Dead conditionals: code that never runs, but always confuses.',\n 'Always-true or always-false. Remove the illusion of choice.'\n ],\n \n // AI Slop Aesthetic\n 'purple-gradient-hunter': [\n 'Purple gradient. The AI\\'s signature. Every vibe-coded site... looks the same.',\n 'from-purple-500 to-violet-600. I\\'ve seen this a million times. So has everyone else.',\n 'The purple gradient. It screams \\'I let AI design this.\\' Is that what you want?'\n ],\n 'star-icon-hunter': [\n 'Stars. Everywhere. The AI decorates like a child with stickers.',\n 'Five stars for the AI\\'s creativity. Zero stars for originality.',\n 'Star icons. The AI\\'s answer to \\'make it look nice.\\' It does not.'\n ],\n 'generic-hero-hunter': [\n '\\'Welcome to the future of...\\' The AI writes copy. The copy says nothing.',\n '\\'Transform your workflow.\\' What workflow? Doing what? The AI doesn\\'t know.',\n 'Generic hero copy. Your product is unique. Your landing page... is not.'\n ],\n 'emoji-overflow-hunter': [\n 'Emojis in production code. The AI\\'s crutch for visual interest.',\n 'Every emoji is an admission: the design couldn\\'t speak for itself.',\n 'The AI decorates. Real designers communicate.'\n ],\n 'inter-font-hunter': [\n 'Inter. The only font the AI knows. The only font everyone uses.',\n 'system-ui. The AI takes the path of least resistance. Every time.',\n 'Inter font. Safe. Boring. Forgettable. Just like every other AI site.'\n ]\n };\n \n const typeNotes = notes[type] || ['I have my eye on your vibe code.'];\n const index = count % typeNotes.length;\n return typeNotes[index] || typeNotes[0] || '';\n }\n\n /**\n * Create AI analysis issue for complex pattern detection\n */\n private createAIAnalysisIssue(files: string[], subAgentResults: SubAgentResult[]): Issue {\n const totalIssues = subAgentResults.reduce((sum, r) => sum + r.instances.length, 0);\n const categories = subAgentResults.map(r => r.type).join(', ');\n \n return this.createSmithIssue(\n this.generateSmithIssueId(),\n 'moderate',\n `[SMITH] AI Analysis Required -- ${totalIssues} violations in ${files.length} files`,\n `Analyze for deeper code quality issues, architectural problems, and patterns that sub-agents may have missed. Categories: ${categories}`,\n files[0] || 'unknown',\n undefined,\n 'ai-analysis'\n );\n }\n\n // ============ Memory/Persistence System ============\n\n /**\n * Load memory from disk\n */\n private async loadMemory(workingDir: string): Promise<void> {\n this.memoryBaseDir = workingDir;\n this.memoryPath = join(workingDir, '.trie', 'smith-memory.json');\n \n try {\n if (existsSync(this.memoryPath)) {\n const content = await readFile(this.memoryPath, 'utf-8');\n this.memory = JSON.parse(content);\n } else {\n this.memory = {\n version: '1.0.0',\n lastScan: new Date().toISOString(),\n issues: {},\n assimilationCount: 0\n };\n }\n } catch {\n this.memory = {\n version: '1.0.0',\n lastScan: new Date().toISOString(),\n issues: {},\n assimilationCount: 0\n };\n }\n }\n\n /**\n * Display Agent Smith ASCII art entrance\n */\n private displaySmithEntrance(): void {\n const greeting = AGENT_SMITH_GREETING[Math.floor(Math.random() * AGENT_SMITH_GREETING.length)];\n \n console.error('\\n' + '='.repeat(60));\n console.error(AGENT_SMITH_ASCII);\n console.error(' Relentless Pattern Hunter v' + this.version);\n console.error('');\n console.error(' \"' + greeting + '\"');\n console.error('='.repeat(60) + '\\n');\n }\n\n /**\n * Save memory to disk (with optimization)\n */\n private async saveMemory(): Promise<void> {\n if (!this.memory || !this.memoryPath) return;\n \n this.memory.lastScan = new Date().toISOString();\n \n // Optimize before saving\n this.pruneMemory();\n \n try {\n await mkdir(dirname(this.memoryPath), { recursive: true });\n await writeFile(this.memoryPath, JSON.stringify(this.memory, null, 2));\n } catch {\n // Silently fail - memory is optional\n }\n }\n\n /**\n * Prune memory to prevent unbounded growth\n */\n private pruneMemory(): void {\n if (!this.memory) return;\n \n const now = Date.now();\n const pruneThreshold = MEMORY_LIMITS.PRUNE_AFTER_DAYS * 24 * 60 * 60 * 1000;\n \n // Remove old resolved issues (not seen in 30 days, already resurrected or no occurrences)\n const issues = Object.entries(this.memory.issues);\n for (const [hash, issue] of issues) {\n const lastSeenTime = new Date(issue.lastSeen).getTime();\n const age = now - lastSeenTime;\n \n // Prune if: old + (resurrected OR zero occurrences OR dismissed and not growing)\n if (age > pruneThreshold) {\n if (issue.resurrected || issue.occurrences === 0 || \n (issue.dismissedAt && issue.occurrences <= 1)) {\n delete this.memory.issues[hash];\n }\n }\n }\n \n // If still too many issues, prune oldest first\n const remainingIssues = Object.entries(this.memory.issues);\n if (remainingIssues.length > MEMORY_LIMITS.MAX_TRACKED_ISSUES) {\n // Sort by lastSeen, oldest first\n remainingIssues.sort((a, b) => \n new Date(a[1].lastSeen).getTime() - new Date(b[1].lastSeen).getTime()\n );\n \n // Remove oldest until under limit\n const toRemove = remainingIssues.length - MEMORY_LIMITS.MAX_TRACKED_ISSUES;\n for (let i = 0; i < toRemove; i++) {\n const hash = remainingIssues[i]?.[0];\n if (hash) delete this.memory.issues[hash];\n }\n }\n }\n\n /**\n * Clear all memory (user command)\n */\n async clearMemory(): Promise<{ success: boolean; message: string }> {\n try {\n if (this.memoryPath && existsSync(this.memoryPath)) {\n await rm(this.memoryPath);\n this.memory = null;\n return { \n success: true, \n message: '[SMITH] Memory cleared.' \n };\n }\n return { \n success: true, \n message: '[SMITH] No memory file found. Nothing to clear.' \n };\n } catch (error) {\n return { \n success: false, \n message: `Failed to clear memory: ${error}` \n };\n }\n }\n\n /**\n * Get memory stats (for diagnostics)\n */\n async getMemoryStats(): Promise<{\n issueCount: number;\n dismissedCount: number;\n resurrectedCount: number;\n oldestIssue: string | null;\n fileSizeKB: number;\n }> {\n await this.loadMemory(process.cwd());\n \n if (!this.memory) {\n return {\n issueCount: 0,\n dismissedCount: 0,\n resurrectedCount: 0,\n oldestIssue: null,\n fileSizeKB: 0\n };\n }\n \n const issues = Object.values(this.memory.issues);\n let fileSizeKB = 0;\n \n try {\n if (this.memoryPath && existsSync(this.memoryPath)) {\n const stats = await import('fs/promises').then(fs => fs.stat(this.memoryPath));\n fileSizeKB = Math.round(stats.size / 1024 * 10) / 10;\n }\n } catch {\n // Ignore\n }\n \n const sortedByDate = [...issues].sort((a, b) => \n new Date(a.firstSeen).getTime() - new Date(b.firstSeen).getTime()\n );\n \n return {\n issueCount: issues.length,\n dismissedCount: issues.filter(i => i.dismissedAt).length,\n resurrectedCount: issues.filter(i => i.resurrected).length,\n oldestIssue: sortedByDate[0]?.firstSeen || null,\n fileSizeKB\n };\n }\n\n /**\n * Update memory with new occurrence\n */\n private async updateMemory(\n hash: string, \n pattern: string, \n category: string, \n location: string, \n count: number\n ): Promise<void> {\n if (!this.memory) return;\n \n const existing = this.memory.issues[hash];\n const now = new Date().toISOString();\n \n if (existing) {\n existing.lastSeen = now;\n existing.occurrences = count;\n existing.locations = [location, ...existing.locations.slice(0, MEMORY_LIMITS.MAX_LOCATIONS_PER_ISSUE - 1)];\n } else {\n this.memory.issues[hash] = {\n hash,\n pattern,\n category,\n firstSeen: now,\n lastSeen: now,\n occurrences: count,\n locations: [location],\n resurrected: false\n };\n }\n \n this.memory.assimilationCount++;\n }\n\n /**\n * Dismiss an issue (mark it as seen/accepted)\n */\n async dismissIssue(hash: string, workingDir?: string): Promise<void> {\n const baseDir = this.memoryBaseDir ?? workingDir ?? process.cwd();\n await this.loadMemory(baseDir);\n \n if (this.memory && this.memory.issues[hash]) {\n this.memory.issues[hash].dismissedAt = new Date().toISOString();\n await this.saveMemory();\n }\n }\n\n /**\n * Create a hash for pattern tracking\n */\n private createPatternHash(type: SubAgentType, file: string): string {\n return createHash('md5').update(`${type}:${file}`).digest('hex').slice(0, 12);\n }\n\n /**\n * Count current occurrences for a pattern hash\n */\n private countCurrentOccurrences(hash: string, issues: Issue[]): number {\n // Extract the type from the hash pattern\n const memory = this.memory?.issues[hash];\n if (!memory) return 0;\n \n // Prefer the encoded hash in the issue id, fall back to category match\n return issues.filter(i => \n i.id.includes(hash) || \n i.category === memory.category || \n (memory.category ? i.issue.includes(memory.category) : false)\n ).length;\n }\n\n /**\n * Check if file is a test file\n */\n private isTestFile(file: string): boolean {\n return /\\.(test|spec)\\.[jt]sx?$/.test(file) ||\n /__(tests|mocks)__/.test(file) ||\n /\\/test\\//.test(file);\n }\n\n // ============ Helper Methods ============\n\n /**\n * Preload file contents once to avoid repeated I/O across sub-agents\n */\n private async loadFileContents(files: string[]): Promise<Map<string, string>> {\n const contents = new Map<string, string>();\n\n for (const file of files) {\n try {\n const buffer = await readFile(file);\n\n // Skip obvious binaries or extremely large files to avoid thrashing\n if (buffer.includes(0) || buffer.byteLength > FILE_SCAN_LIMITS.MAX_BYTES) {\n continue;\n }\n\n contents.set(file, buffer.toString('utf-8'));\n } catch {\n // Skip unreadable files\n }\n }\n\n return contents;\n }\n\n private createSmithIssue(\n id: string,\n severity: Issue['severity'],\n issue: string,\n fix: string,\n file: string,\n line?: number,\n category?: string\n ): Issue {\n const result: Issue = {\n id,\n agent: this.name,\n severity,\n issue,\n fix,\n file,\n confidence: 0.9,\n autoFixable: false,\n };\n \n // Only add optional properties if defined (exactOptionalPropertyTypes)\n if (line !== undefined) {\n result.line = line;\n }\n if (category !== undefined) {\n result.category = category;\n }\n \n return result;\n }\n\n private generateSmithIssueId(seed?: string): string {\n const base = seed ? `smith-${seed}` : 'smith';\n return `${base}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n }\n}\n\n/**\n * Export sub-agent patterns for testing\n */\nexport { SUB_AGENT_PATTERNS, SubAgentType, IssueMemory, SmithMemoryBank };\n"],"mappings":"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","names":["readFile","existsSync","join"]}
@@ -13,7 +13,7 @@ import {
13
13
  BaseAgent,
14
14
  isAIAvailable,
15
15
  runAIAnalysis
16
- } from "./chunk-OB45V2QC.js";
16
+ } from "./chunk-KQOMSIVR.js";
17
17
  import {
18
18
  getWorkingDirectory
19
19
  } from "./chunk-IMFD4SJC.js";
@@ -3655,7 +3655,7 @@ var LegalAgent = class extends BaseAgent {
3655
3655
  description = "Comprehensive legal compliance for app development: licensing, ToS, accessibility, IP, data protection, e-commerce, and regulatory requirements";
3656
3656
  version = "2.0.0";
3657
3657
  shouldActivate(context) {
3658
- return context.touchesUserData || context.touchesPayments || context.touchesAuth || context.touchesUI || context.touchesAPI || context.touchesThirdPartyAPI;
3658
+ return context.touchesUserData || context.touchesPayments || context.touchesAuth || context.touchesUI || context.touchesAPI || context.touchesThirdPartyAPI || context.touchesHealthData;
3659
3659
  }
3660
3660
  async analyzeFiles(files, _context) {
3661
3661
  const issues = [];
@@ -6194,8 +6194,8 @@ var SuperReviewerAgent = class extends BaseAgent {
6194
6194
  name = "super-reviewer";
6195
6195
  description = "Interactive PR review: walks through changes file-by-file, explains each chunk, waits for cross-examination";
6196
6196
  version = "1.0.0";
6197
- shouldActivate(context) {
6198
- return context.linesChanged > 50 || context.isNewFeature || context.touchesAuth || context.touchesPayments || context.touchesDatabase || context.touchesAPI;
6197
+ shouldActivate(_context) {
6198
+ return false;
6199
6199
  }
6200
6200
  /**
6201
6201
  * The Super Reviewer doesn't do static pattern matching like other agents.
@@ -7519,16 +7519,10 @@ var MONEYBAGS_ASCII = `
7519
7519
  \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D
7520
7520
  `;
7521
7521
  var MONEYBAGS_QUOTES = [
7522
- `"Every bug has a price tag. I'm here to show you the receipt."`,
7523
- `"That 'temporary fix' will cost you $50k when it hits production."`,
7524
- `"Show me the bug, I'll show you the money you're about to lose."`,
7525
- '"A penny saved in development is $30 saved in production."',
7526
- `"Your CFO doesn't care about code quality. They care about THIS."`,
7527
- `"Floating-point for money? That's going to be an expensive lesson."`,
7528
- '"The best time to fix a bug was yesterday. The second best time is before production."',
7529
- '"I see dead... budget allocations for emergency fixes."',
7530
- '"You can pay me now, or pay production support later. Your choice."',
7531
- '"That empty catch block? $5,600 per minute when it fails silently."'
7522
+ "Every bug has a price tag. I'm here to show you the receipt.",
7523
+ "That temporary fix will cost you $50k when it hits production.",
7524
+ "A penny saved in development is $30 saved in production.",
7525
+ "Floating-point for money? That's going to be an expensive lesson."
7532
7526
  ];
7533
7527
  var BASE_COST_BY_SEVERITY = {
7534
7528
  critical: 5e3,
@@ -7669,12 +7663,12 @@ var MoneybagAgent = class extends BaseAgent {
7669
7663
  if (this.bannerShown) return;
7670
7664
  this.bannerShown = true;
7671
7665
  const quote = MONEYBAGS_QUOTES[Math.floor(Math.random() * MONEYBAGS_QUOTES.length)];
7672
- console.error("\n" + "\u2550".repeat(60));
7666
+ console.error("\n" + "=".repeat(60));
7673
7667
  console.error(MONEYBAGS_ASCII);
7674
- console.error(" \u{1F4B0} Bug Cost Estimator v" + this.version + " \u{1F4B0}");
7668
+ console.error(" Bug Cost Estimator v" + this.version);
7675
7669
  console.error("");
7676
7670
  console.error(" " + quote);
7677
- console.error("\u2550".repeat(60) + "\n");
7671
+ console.error("=".repeat(60) + "\n");
7678
7672
  }
7679
7673
  // Run after other agents so we can analyze their findings
7680
7674
  get priority() {
@@ -7849,7 +7843,7 @@ var MoneybagAgent = class extends BaseAgent {
7849
7843
  generateCostSummary(_issue, nowCost, productionCost, savings, contextFactors, userCount) {
7850
7844
  const formatCurrency = (n) => n >= 1e3 ? `$${(n / 1e3).toFixed(1)}k` : `$${n}`;
7851
7845
  const formatUsers = (n) => n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1e3 ? `${(n / 1e3).toFixed(0)}K` : `${n}`;
7852
- let summary = `\u{1F4B0} Fix now: ${formatCurrency(nowCost)} | If production: ${formatCurrency(productionCost)} | Save: ${formatCurrency(savings)}`;
7846
+ let summary = `Fix now: ${formatCurrency(nowCost)} | If production: ${formatCurrency(productionCost)} | Save: ${formatCurrency(savings)}`;
7853
7847
  summary += ` (${formatUsers(userCount)} users)`;
7854
7848
  if (contextFactors.length > 0) {
7855
7849
  summary += ` | Risk factors: ${contextFactors.join(", ")}`;
@@ -7857,9 +7851,9 @@ var MoneybagAgent = class extends BaseAgent {
7857
7851
  const scaledHighThreshold = 5e4 * (userCount / 1e3);
7858
7852
  const scaledMediumThreshold = 1e4 * (userCount / 1e3);
7859
7853
  if (productionCost > scaledHighThreshold) {
7860
- summary = `\u{1F525} HIGH COST RISK - ${summary}`;
7854
+ summary = `[HIGH COST RISK] ${summary}`;
7861
7855
  } else if (productionCost > scaledMediumThreshold) {
7862
- summary = `\u26A0\uFE0F SIGNIFICANT COST - ${summary}`;
7856
+ summary = `[SIGNIFICANT COST] ${summary}`;
7863
7857
  }
7864
7858
  return summary;
7865
7859
  }
@@ -8065,33 +8059,33 @@ Output STRICT JSON:
8065
8059
  const formatCurrency = (n) => n >= 1e6 ? `$${(n / 1e6).toFixed(2)}M` : n >= 1e3 ? `$${(n / 1e3).toFixed(1)}k` : `$${n}`;
8066
8060
  const formatUsers = (n) => n >= 1e6 ? `${(n / 1e6).toFixed(1)}M` : n >= 1e3 ? `${Math.round(n / 1e3)}K` : `${n}`;
8067
8061
  const summary = `
8068
- \u{1F4B0} COST ANALYSIS REPORT
8069
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
8070
- \u{1F465} User Scale: ${formatUsers(userCount)} users (${userScale.label})
8071
- \u2514\u2500 Costs scaled ${userScale.multiplier}x from 1K baseline
8072
-
8073
- \u{1F4CA} Total Issues: ${issues.length}
8074
- \u251C\u2500 Critical: ${breakdown.find((b) => b.severity === "critical")?.count || 0}
8075
- \u251C\u2500 Serious: ${breakdown.find((b) => b.severity === "serious")?.count || 0}
8076
- \u251C\u2500 Moderate: ${breakdown.find((b) => b.severity === "moderate")?.count || 0}
8077
- \u2514\u2500 Low: ${breakdown.find((b) => b.severity === "low")?.count || 0}
8078
-
8079
- \u{1F4B5} COST IMPACT
8080
- \u251C\u2500 Fix now: ${formatCurrency(totalNowCost)}
8081
- \u251C\u2500 If production: ${formatCurrency(totalProductionCost)}
8082
- \u2514\u2500 Savings by fixing now: ${formatCurrency(totalSavings)} \u26A1
8083
-
8084
- \u{1F3AF} RISK LEVEL: ${riskLevel.toUpperCase()}
8085
- ${riskLevel === "critical" ? " \u26A0\uFE0F URGENT: High-value bugs require immediate attention" : ""}
8086
- ${riskLevel === "high" ? " \u26A0\uFE0F ATTENTION: Significant financial risk detected" : ""}
8087
-
8088
- \u{1F4C8} Based on industry research:
8089
- \u2022 IBM: Production bugs cost 30x more to fix
8090
- \u2022 Ponemon: Average data breach costs $4.45M
8091
- \u2022 Gartner: Downtime averages $5,600/minute
8092
-
8093
- \u{1F4A1} Default: 250 users. Scale with: trie scan --users 10000
8094
- \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550
8062
+ COST ANALYSIS REPORT
8063
+ =======================================
8064
+ User Scale: ${formatUsers(userCount)} users (${userScale.label})
8065
+ Costs scaled ${userScale.multiplier}x from 1K baseline
8066
+
8067
+ Total Issues: ${issues.length}
8068
+ Critical: ${breakdown.find((b) => b.severity === "critical")?.count || 0}
8069
+ Serious: ${breakdown.find((b) => b.severity === "serious")?.count || 0}
8070
+ Moderate: ${breakdown.find((b) => b.severity === "moderate")?.count || 0}
8071
+ Low: ${breakdown.find((b) => b.severity === "low")?.count || 0}
8072
+
8073
+ COST IMPACT
8074
+ Fix now: ${formatCurrency(totalNowCost)}
8075
+ If production: ${formatCurrency(totalProductionCost)}
8076
+ Savings by fixing now: ${formatCurrency(totalSavings)}
8077
+
8078
+ RISK LEVEL: ${riskLevel.toUpperCase()}
8079
+ ${riskLevel === "critical" ? " URGENT: High-value bugs require immediate attention" : ""}
8080
+ ${riskLevel === "high" ? " ATTENTION: Significant financial risk detected" : ""}
8081
+
8082
+ Based on industry research:
8083
+ - IBM: Production bugs cost 30x more to fix
8084
+ - Ponemon: Average data breach costs $4.45M
8085
+ - Gartner: Downtime averages $5,600/minute
8086
+
8087
+ Default: 250 users. Scale with: trie scan --users 10000
8088
+ =======================================
8095
8089
  `.trim();
8096
8090
  return {
8097
8091
  totalNowCost,
@@ -8123,14 +8117,10 @@ var PRODUCTION_READY_ASCII = `
8123
8117
  \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D
8124
8118
  `;
8125
8119
  var PRODUCTION_QUOTES = [
8126
- '"Ship it? Not until I say so."',
8120
+ "Ship it? Not until I say so.",
8127
8121
  '"Works on my machine" is not a deployment strategy.',
8128
- '"The last mile is where dreams become revenue\u2014or nightmares."',
8129
- '"Production is where your code meets reality. Is yours ready?"',
8130
- '"One missing health check = 3am pager duty."',
8131
- `"You wouldn't deploy without tests. Why deploy without production checks?"`,
8132
- '"Fortune favors the prepared. So does uptime."',
8133
- `"Your users don't care about your sprint velocity. They care if it works."`
8122
+ "The last mile is where dreams become revenue -- or nightmares.",
8123
+ "Production is where your code meets reality. Is yours ready?"
8134
8124
  ];
8135
8125
  var PRODUCTION_PATTERNS = {
8136
8126
  // Health & Reliability
@@ -8293,12 +8283,12 @@ var ProductionReadyAgent = class extends BaseAgent {
8293
8283
  if (this.bannerShown) return;
8294
8284
  this.bannerShown = true;
8295
8285
  const quote = PRODUCTION_QUOTES[Math.floor(Math.random() * PRODUCTION_QUOTES.length)];
8296
- console.error("\n" + "\u2550".repeat(60));
8286
+ console.error("\n" + "=".repeat(60));
8297
8287
  console.error(PRODUCTION_READY_ASCII);
8298
- console.error(" \u{1F680} Production Readiness Gate v" + this.version + " \u{1F680}");
8288
+ console.error(" Production Readiness Gate v" + this.version);
8299
8289
  console.error("");
8300
8290
  console.error(" " + quote);
8301
- console.error("\u2550".repeat(60) + "\n");
8291
+ console.error("=".repeat(60) + "\n");
8302
8292
  }
8303
8293
  checkFileRelevance(file, content) {
8304
8294
  if (/node_modules|\.d\.ts$|\.min\.|dist\/|build\/|\.lock$/.test(file)) {
@@ -8357,7 +8347,7 @@ var ProductionReadyAgent = class extends BaseAgent {
8357
8347
  issues.push(this.createIssue(
8358
8348
  this.generateIssueId(),
8359
8349
  antiPattern.severity,
8360
- `\u{1F680} [NOT PROD READY] ${antiPattern.issue}`,
8350
+ `[NOT PROD READY] ${antiPattern.issue}`,
8361
8351
  antiPattern.fix,
8362
8352
  file,
8363
8353
  i + 1,
@@ -8380,7 +8370,7 @@ var ProductionReadyAgent = class extends BaseAgent {
8380
8370
  issues.push(this.createIssue(
8381
8371
  this.generateIssueId(),
8382
8372
  config.severity,
8383
- `\u{1F680} [MISSING] ${config.requirement}`,
8373
+ `[MISSING] ${config.requirement}`,
8384
8374
  this.getRequirementFix(key),
8385
8375
  "project",
8386
8376
  void 0,
@@ -8412,23 +8402,22 @@ var ProductionReadyAgent = class extends BaseAgent {
8412
8402
  logReadinessSummary(issues) {
8413
8403
  const totalRequirements = Object.keys(PRODUCTION_PATTERNS).length;
8414
8404
  const metRequirements = this.foundRequirements.size;
8415
- const missingRequirements = totalRequirements - metRequirements;
8416
8405
  const criticalIssues = issues.filter((i) => i.severity === "critical").length;
8417
8406
  const seriousIssues = issues.filter((i) => i.severity === "serious").length;
8418
8407
  const readinessScore = Math.max(0, Math.round(
8419
8408
  metRequirements / totalRequirements * 50 + (50 - criticalIssues * 20 - seriousIssues * 10)
8420
8409
  ));
8421
- const status = criticalIssues > 0 || seriousIssues > 2 ? "\u274C NOT READY TO SHIP" : seriousIssues > 0 ? "\u26A0\uFE0F SHIP WITH CAUTION" : "\u2705 READY TO SHIP";
8422
- console.error("\n" + "\u2500".repeat(50));
8423
- console.error("\u{1F4CA} PRODUCTION READINESS REPORT");
8424
- console.error("\u2500".repeat(50));
8410
+ const status = criticalIssues > 0 || seriousIssues > 2 ? "[FAIL] NOT READY TO SHIP" : seriousIssues > 0 ? "[WARN] SHIP WITH CAUTION" : "[OK] READY TO SHIP";
8411
+ console.error("\n" + "-".repeat(50));
8412
+ console.error("PRODUCTION READINESS REPORT");
8413
+ console.error("-".repeat(50));
8425
8414
  console.error(` Score: ${readinessScore}/100`);
8426
8415
  console.error(` Requirements: ${metRequirements}/${totalRequirements} met`);
8427
8416
  console.error(` Critical issues: ${criticalIssues}`);
8428
8417
  console.error(` Serious issues: ${seriousIssues}`);
8429
8418
  console.error("");
8430
8419
  console.error(` ${status}`);
8431
- console.error("\u2500".repeat(50) + "\n");
8420
+ console.error("-".repeat(50) + "\n");
8432
8421
  }
8433
8422
  getAIEnhancementSystemPrompt() {
8434
8423
  return `You are a production readiness engineer reviewing code for deployment.
@@ -9219,4 +9208,4 @@ export {
9219
9208
  CustomSkill,
9220
9209
  getAgentRegistry
9221
9210
  };
9222
- //# sourceMappingURL=chunk-R5HWHP5N.js.map
9211
+ //# sourceMappingURL=chunk-VZYCZXEQ.js.map