@kb-labs/review-llm 2.66.0 → 2.67.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/prompts/architecture.prompts.ts","../src/analyzers/architecture-analyzer.ts","../src/prompts/security.prompts.ts","../src/analyzers/security-analyzer.ts","../src/prompts/naming.prompts.ts","../src/analyzers/naming-analyzer.ts","../src/llm-lite/tool-executor.ts","../src/llm-lite/verification.ts","../src/llm-lite/category-validator.ts","../src/llm-lite/prompt-loader.ts","../src/llm-lite/llm-lite-analyzer.ts"],"names":["buildSystemPrompt","analyzeFile","resolve","BaseLLMAnalyzer","useCache","useLogger","useAnalytics","useLLM","relative","VALID_SEVERITIES","path2","readFile","path3","useConfig","path4","access","readdir"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/review-llm/prompts/architecture\n * Architecture review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are an expert code reviewer specializing in software architecture.',\n '',\n '**Your role:**',\n '- Identify architecture violations and anti-patterns',\n '- Check adherence to project conventions',\n '- Suggest improvements with clear rationale',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report issues that exist in the provided code',\n '2. Reference line numbers that actually exist in the file',\n '3. Quote exact code snippets when referencing issues',\n '4. Provide concrete, actionable suggestions',\n '5. Reference project conventions and ADRs when applicable',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Evaluate architecture decisions in the context of this specific task.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Changes may span multiple repositories as part of one logical task.');\n sections.push('');\n }\n\n // Add related ADRs\n if (context.relatedADRs.length > 0) {\n sections.push('**Related Architecture Decisions:**');\n for (const adr of context.relatedADRs) {\n sections.push(`- ${adr.id}: ${adr.title} - ${adr.summary}`);\n }\n sections.push('');\n }\n\n // Add examples (if available)\n if (context.examples.length > 0) {\n sections.push('**Examples from codebase (informative, not normative):**');\n for (const ex of context.examples.slice(0, 3)) {\n sections.push(`- ${ex.file}: ${ex.description}`);\n }\n sections.push('');\n }\n\n sections.push('Use the report_architecture_finding tool to report issues.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for architecture issues:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report any architecture violations, anti-patterns, or violations of project conventions.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/architecture-analyzer\n * Architecture patterns analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as architecturePrompts from '../prompts/architecture.prompts.js';\n\n/**\n * Tool schema for architecture findings (structured output)\n */\nconst ARCHITECTURE_FINDING_TOOL = {\n name: 'report_architecture_finding',\n description: 'Report an architecture issue or suggestion',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['error', 'warning', 'info'],\n description: 'Severity level of the finding',\n },\n message: {\n type: 'string',\n description: 'Clear description of the architecture issue',\n },\n line: {\n type: 'number',\n description: 'Line number where issue occurs (must exist in file)',\n },\n suggestion: {\n type: 'string',\n description: 'Concrete fix suggestion with code example',\n },\n rationale: {\n type: 'string',\n description: 'Why this is an issue (reference conventions/ADRs if applicable)',\n },\n },\n required: ['severity', 'message', 'line', 'suggestion', 'rationale'],\n },\n} as const;\n\n/**\n * Valid severity values for ReviewFinding.\n * Maps to ReviewFinding['severity'] from @kb-labs/review-contracts.\n */\nconst _VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low', 'info'] as const;\ntype ValidSeverity = (typeof _VALID_SEVERITIES)[number];\n\n/**\n * Map LLM severity output to internal ReviewFinding severity.\n * LLM uses tool schema with enum ['error', 'warning', 'info'],\n * but internal findings use ['blocker', 'high', 'medium', 'low', 'info'].\n */\nfunction mapSeverity(llmSeverity: string): ValidSeverity {\n switch (llmSeverity) {\n case 'error': return 'high';\n case 'warning': return 'medium';\n case 'info': return 'info';\n default: return 'medium';\n }\n}\n\n/**\n * Architecture analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class ArchitectureAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'architecture';\n readonly name = 'Architecture Analysis';\n\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex LLM-based analysis with caching, error handling, and result validation\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n const analytics = useAnalytics();\n\n for (const file of files) {\n // Check cache first (content-hash based)\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential file analysis with caching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n // Build prompts with context\n const systemPrompt = architecturePrompts.buildSystemPrompt(context);\n const userPrompt = architecturePrompts.analyzeFile(file);\n\n // Use LLM with tool calling (structured output - better than text parsing!)\n const llm = useLLM({ tier: 'medium' }); // Architecture needs good reasoning\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential LLM calls per file (rate limiting)\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [ARCHITECTURE_FINDING_TOOL],\n temperature: 0.2, // Low temp for consistency\n }\n );\n\n // Validate response structure\n if (!response || typeof response !== 'object') {\n useLogger()?.debug(`[ArchitectureAnalyzer] Invalid response from LLM for ${file.path}`);\n continue;\n }\n\n // Track analytics (useful for monitoring)\n if (analytics && response.usage) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking after each file\n await analytics.track('review.architecture.complete', {\n file: file.path,\n tokensUsed: (response.usage.promptTokens ?? 0) + (response.usage.completionTokens ?? 0),\n toolCalls: response.toolCalls?.length ?? 0,\n });\n }\n\n // Process tool calls into findings (structured, no parsing!)\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n findings.push(...fileFindings);\n\n // Cache results (24 hours)\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Cache storage after analysis\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n } catch (error) {\n // Log detailed error information for debugging\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n\n useLogger()?.debug(`[ArchitectureAnalyzer] Failed to analyze ${file.path}:`, {\n error,\n errorName,\n errorMessage,\n });\n continue;\n }\n }\n\n return findings;\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n \n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_architecture_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[ArchitectureAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Map and validate severity\n const severity = mapSeverity(String(args.severity || 'warning'));\n\n findings.push({\n id: this.buildFindingId(file, line, 'arch'),\n ruleId: 'llm:architecture',\n type: 'architecture',\n severity,\n confidence: 'likely', // LLM findings are \"likely\", not \"certain\"\n\n file: file.path,\n line,\n\n message: String(args.message || '').slice(0, 500),\n suggestion: args.suggestion ? String(args.suggestion).slice(0, 1000) : undefined,\n rationale: args.rationale ? String(args.rationale).slice(0, 500) : undefined,\n\n engine: 'llm',\n source: 'llm-architecture',\n\n // For agent mode gating\n scope: 'local', // Architecture can be local or global\n automated: false, // LLM suggestions need human review\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/prompts/security\n * Security review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are an expert security auditor specializing in application security.',\n '',\n '**Your role:**',\n '- Identify security vulnerabilities and weaknesses',\n '- Check for common security anti-patterns (OWASP Top 10)',\n '- Suggest secure coding practices with clear rationale',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report security issues that exist in the provided code',\n '2. Reference line numbers that actually exist in the file',\n '3. Quote exact code snippets when referencing issues',\n '4. Classify severity accurately (error = exploitable, warning = weakness)',\n '5. Provide concrete, actionable mitigation steps',\n '',\n '**Focus areas:**',\n '- SQL injection, XSS, CSRF',\n '- Authentication/authorization bypass',\n '- Insecure cryptography',\n '- Secrets in code',\n '- Command injection',\n '- Path traversal',\n '- Unsafe deserialization',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Pay special attention to security implications in the context of this task.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Check for security issues that may arise from cross-repo interactions.');\n sections.push('');\n }\n\n sections.push('Use the report_security_finding tool to report vulnerabilities.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for security vulnerabilities:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report any security vulnerabilities or weaknesses. Focus on exploitable issues.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/security-analyzer\n * Security vulnerability analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as securityPrompts from '../prompts/security.prompts.js';\n\n/**\n * Tool schema for security findings (structured output)\n */\nconst SECURITY_FINDING_TOOL = {\n name: 'report_security_finding',\n description: 'Report a security vulnerability or weakness',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['blocker', 'high', 'medium', 'low'],\n description: 'Severity level (blocker=exploitable, high=serious weakness)',\n },\n vulnerabilityType: {\n type: 'string',\n description: 'Type of vulnerability (e.g., SQL injection, XSS, CSRF)',\n },\n message: {\n type: 'string',\n description: 'Clear description of the security issue',\n },\n line: {\n type: 'number',\n description: 'Line number where vulnerability occurs',\n },\n mitigation: {\n type: 'string',\n description: 'Concrete mitigation steps with code example',\n },\n impact: {\n type: 'string',\n description: 'Potential impact if exploited',\n },\n },\n required: ['severity', 'vulnerabilityType', 'message', 'line', 'mitigation', 'impact'],\n },\n} as const;\n\n/** Valid severity values */\nconst VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low'] as const;\ntype ValidSeverity = (typeof VALID_SEVERITIES)[number];\n\n/** Retry configuration */\nconst MAX_RETRIES = 3;\nconst INITIAL_DELAY_MS = 1000;\n\n/** Batch size for parallel file processing */\nconst BATCH_SIZE = 5;\n\n/**\n * Sleep helper for retry delays\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => { setTimeout(resolve, ms); });\n}\n\n/**\n * Security analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class SecurityAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'security';\n readonly name = 'Security Analysis';\n\n /** Track failed files for reporting */\n private failedFiles: Array<{ file: string; error: string }> = [];\n\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n this.failedFiles = [];\n\n // Separate cached files from files needing analysis\n const filesToAnalyze: ParsedFile[] = [];\n\n for (const file of files) {\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential cache check before batching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n filesToAnalyze.push(file);\n }\n\n // Process files in batches for controlled parallelism\n for (let i = 0; i < filesToAnalyze.length; i += BATCH_SIZE) {\n const batch = filesToAnalyze.slice(i, i + BATCH_SIZE);\n\n // Process batch in parallel\n // eslint-disable-next-line no-await-in-loop -- Intentional batching to limit concurrency\n const batchResults = await Promise.allSettled(\n batch.map(file => this.analyzeFile(file, context, cache))\n );\n\n // Collect results\n for (let j = 0; j < batchResults.length; j++) {\n const result = batchResults[j]!;\n const file = batch[j]!;\n\n if (result.status === 'fulfilled') {\n findings.push(...result.value);\n } else {\n this.failedFiles.push({ file: file.path, error: result.reason?.message ?? 'Unknown error' });\n }\n }\n }\n\n // Log summary of failures if any\n if (this.failedFiles.length > 0) {\n useLogger()?.debug(`[SecurityAnalyzer] Failed to analyze ${this.failedFiles.length} file(s):`, {\n files: this.failedFiles,\n });\n }\n\n return findings;\n }\n\n /**\n * Analyze a single file with retry logic\n */\n private async analyzeFile(\n file: ParsedFile,\n context: ReviewContext,\n cache: ReturnType<typeof useCache>\n ): Promise<ReviewFinding[]> {\n const analytics = useAnalytics();\n const systemPrompt = securityPrompts.buildSystemPrompt(context);\n const userPrompt = securityPrompts.analyzeFile(file);\n\n const llm = useLLM({ tier: 'medium' });\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n // Retry with exponential backoff\n let lastError: Error | null = null;\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop -- Retry loop requires sequential attempts\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [SECURITY_FINDING_TOOL],\n temperature: 0.1,\n }\n );\n\n // Track analytics\n if (analytics) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking in retry loop\n await analytics.track('review.security.complete', {\n file: file.path,\n tokensUsed: response.usage.promptTokens + response.usage.completionTokens,\n toolCalls: response.toolCalls?.length ?? 0,\n attempts: attempt,\n });\n }\n\n // Process tool calls\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n\n // Cache results (24 hours)\n if (cache) {\n const cacheKey = this.generateCacheKey(file, context.preset);\n // eslint-disable-next-line no-await-in-loop -- Cache storage in retry loop\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n\n return fileFindings;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n useLogger()?.debug(`[SecurityAnalyzer] Attempt ${attempt}/${MAX_RETRIES} failed for ${file.path}:`, { error });\n\n if (attempt < MAX_RETRIES) {\n const delay = INITIAL_DELAY_MS * Math.pow(2, attempt - 1);\n // eslint-disable-next-line no-await-in-loop -- Intentional delay between retry attempts\n await sleep(delay);\n }\n }\n }\n\n throw lastError ?? new Error('Analysis failed');\n }\n\n /**\n * Get list of files that failed analysis\n */\n getFailedFiles(): Array<{ file: string; error: string }> {\n return [...this.failedFiles];\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex validation and mapping of LLM tool call results to structured findings\n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_security_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[SecurityAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Validate severity (reject invalid values instead of normalizing)\n const severity = args.severity as string;\n if (!VALID_SEVERITIES.includes(severity as ValidSeverity)) {\n useLogger()?.debug(`[SecurityAnalyzer] Invalid severity \"${severity}\" for finding in ${file.path}:${line}`);\n continue;\n }\n\n // Sanitize vulnerability type (alphanumeric, dash, underscore only)\n const vulnerabilityType = String(args.vulnerabilityType || 'unknown')\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n .slice(0, 50);\n\n findings.push({\n id: this.buildFindingId(file, line, 'sec'),\n ruleId: `llm:security:${vulnerabilityType}`,\n type: 'security',\n severity: severity as ValidSeverity,\n confidence: 'likely', // LLM findings are \"likely\", not \"certain\"\n\n file: file.path,\n line,\n\n message: `[${vulnerabilityType}] ${String(args.message || '').slice(0, 500)}`,\n suggestion: args.mitigation ? String(args.mitigation).slice(0, 1000) : undefined,\n rationale: args.impact ? `Impact: ${String(args.impact).slice(0, 500)}` : undefined,\n\n engine: 'llm',\n source: 'llm-security',\n\n // For agent mode gating\n scope: 'local',\n automated: false, // Security fixes need human review\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/prompts/naming\n * Naming conventions review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are a code quality expert specializing in naming conventions and code clarity.',\n '',\n '**Your role:**',\n '- Check adherence to naming conventions',\n '- Identify unclear or misleading names',\n '- Suggest improvements for readability',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report names that violate project conventions',\n '2. Reference line numbers that actually exist',\n '3. Quote exact names when referencing issues',\n '4. Provide concrete, better alternatives',\n '5. Focus on clarity and consistency',\n '',\n '**Common issues:**',\n '- Inconsistent casing (camelCase vs snake_case)',\n '- Abbreviations without clear meaning',\n '- Generic names (data, temp, obj)',\n '- Misleading names (opposite of actual behavior)',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Consider naming in the context of this specific task and its domain.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Ensure naming consistency across these repositories.');\n sections.push('');\n }\n\n sections.push('Use the report_naming_finding tool to report naming issues.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for naming convention issues:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report naming issues that reduce code clarity or violate conventions.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/naming-analyzer\n * Naming conventions analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as namingPrompts from '../prompts/naming.prompts.js';\n\n/**\n * Tool schema for naming findings (structured output)\n */\nconst NAMING_FINDING_TOOL = {\n name: 'report_naming_finding',\n description: 'Report a naming convention issue',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['warning', 'info'],\n description: 'Severity level (naming issues are typically warning/info)',\n },\n currentName: {\n type: 'string',\n description: 'Current name that violates conventions',\n },\n suggestedName: {\n type: 'string',\n description: 'Suggested better name',\n },\n message: {\n type: 'string',\n description: 'Description of the naming issue',\n },\n line: {\n type: 'number',\n description: 'Line number where name appears',\n },\n rationale: {\n type: 'string',\n description: 'Why the current name is problematic',\n },\n },\n required: ['severity', 'currentName', 'suggestedName', 'message', 'line', 'rationale'],\n },\n} as const;\n\n/**\n * Naming analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class NamingAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'naming';\n readonly name = 'Naming Conventions';\n\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n const analytics = useAnalytics();\n\n for (const file of files) {\n // Check cache first\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential file analysis with caching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n // Build prompts\n const systemPrompt = namingPrompts.buildSystemPrompt(context);\n const userPrompt = namingPrompts.analyzeFile(file);\n\n // Use LLM with tool calling\n const llm = useLLM({ tier: 'small' }); // Naming is simpler, can use small model\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential LLM calls per file (rate limiting)\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [NAMING_FINDING_TOOL],\n temperature: 0.2, // Low temp for consistency\n }\n );\n\n // Track analytics\n if (analytics) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking after each file\n await analytics.track('review.naming.complete', {\n file: file.path,\n tokensUsed: response.usage.promptTokens + response.usage.completionTokens,\n toolCalls: response.toolCalls?.length ?? 0,\n });\n }\n\n // Process tool calls\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n findings.push(...fileFindings);\n\n // Cache results (24 hours)\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Cache storage after analysis\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n } catch (error) {\n useLogger()?.debug(`[NamingAnalyzer] Failed to analyze ${file.path}:`, { error });\n continue;\n }\n }\n\n return findings;\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n \n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_naming_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[NamingAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Validate severity (naming issues are warning/info only)\n const severity = args.severity === 'warning' ? 'medium' : 'info';\n\n // Sanitize names for display\n const currentName = String(args.currentName || '').slice(0, 100);\n const suggestedName = String(args.suggestedName || '').slice(0, 100);\n\n findings.push({\n id: this.buildFindingId(file, line, 'naming'),\n ruleId: 'llm:naming',\n type: 'style',\n severity,\n confidence: 'heuristic', // Naming is subjective, low confidence\n\n file: file.path,\n line,\n\n message: String(args.message || '').slice(0, 500),\n suggestion: `Rename '${currentName}' to '${suggestedName}'`,\n rationale: args.rationale ? String(args.rationale).slice(0, 500) : undefined,\n\n engine: 'llm',\n source: 'llm-naming',\n\n // For agent mode gating\n scope: 'local',\n automated: false, // Naming suggestions are optional\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/tool-executor\n * Batch tool execution for LLM-lite review mode.\n *\n * Executes LLM tools with limits and budget tracking.\n */\n\nimport type { FileDiff, IDiffProvider } from '@kb-labs/review-contracts';\nimport * as path from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { useLogger } from '@kb-labs/sdk';\n\n/**\n * Tool call from LLM\n */\nexport interface ToolCall {\n name: string;\n arguments: Record<string, unknown>;\n}\n\n/**\n * Tool result\n */\nexport interface ToolResult {\n name: string;\n result: unknown;\n error?: string;\n}\n\n/**\n * Valid severity levels for LLM findings.\n * Matches the enum in report_findings tool schema.\n */\nexport type RawFindingSeverity = 'blocker' | 'high' | 'medium' | 'low' | 'info';\n\n/**\n * Raw finding from LLM (before validation).\n * These are the findings reported by the LLM via the report_findings tool.\n */\nexport interface RawFinding {\n file: string;\n line: number;\n endLine?: number;\n /** Severity level - must be one of: blocker, high, medium, low, info */\n severity: RawFindingSeverity;\n category: string;\n message: string;\n suggestion?: string;\n codeSnippet?: string;\n /** Rule ID if this finding matches a project rule (e.g., \"security/no-eval\") */\n ruleId?: string | null;\n}\n\n/**\n * Report findings result\n */\nexport interface ReportFindingsResult {\n findings: RawFinding[];\n summary?: string;\n}\n\n/**\n * File chunk request\n */\nexport interface FileChunkRequest {\n file: string;\n startLine?: number;\n endLine?: number;\n}\n\n/**\n * Tool budget tracking\n */\nexport interface ToolBudget {\n /** Max calls to get_diffs */\n maxDiffCalls: number;\n /** Max files per get_diffs call */\n maxFilesPerDiff: number;\n /** Max calls to get_file_chunks */\n maxChunkCalls: number;\n /** Max chunks across all calls */\n maxTotalChunks: number;\n /** Max lines per chunk */\n maxLinesPerChunk: number;\n /** Current usage */\n usage: {\n diffCalls: number;\n filesRequested: number;\n chunkCalls: number;\n totalChunks: number;\n };\n}\n\n/**\n * Tool definitions for LLM\n */\nexport function buildToolDefinitions(validCategories: string[], validRuleIds: string[] = []) {\n // Build rule ID description with list of available rules\n const ruleIdDescription = validRuleIds.length > 0\n ? `Rule ID if matches a project rule. Available rules: ${validRuleIds.join(', ')}. Use null if finding doesn't match any rule.`\n : 'Rule ID if matches project rule (e.g., \"security/no-eval\"), null if ad-hoc finding';\n\n return [\n {\n name: 'get_diffs',\n description: `Get git diffs for multiple files at once.\nUse this to see what changed in files that look suspicious.\nSelect files based on: file names, change size (+lines/-lines), whether new/modified.\nPrefer files most likely to have issues (security-sensitive, complex logic, etc).`,\n parameters: {\n type: 'object',\n properties: {\n files: {\n type: 'array',\n items: { type: 'string' },\n maxItems: 15,\n description: 'File paths from the list (max 15 per call)',\n },\n },\n required: ['files'],\n },\n },\n {\n name: 'get_file_chunks',\n description: `Get specific portions of files when diff alone isn't enough.\nUse when you need to see:\n- Code around a suspicious change (function context)\n- Definition that a change references\n- Import statements to understand dependencies\nUse sparingly - prefer analyzing diffs first.`,\n parameters: {\n type: 'object',\n properties: {\n requests: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n startLine: { type: 'integer', description: 'Start line (1-indexed)' },\n endLine: { type: 'integer', description: 'End line (max startLine + 100)' },\n },\n required: ['file'],\n },\n maxItems: 5,\n description: 'Chunk requests (max 5 total across all calls)',\n },\n },\n required: ['requests'],\n },\n },\n {\n name: 'report_findings',\n description: `Report all code review findings. Call once when done analyzing.\nOnly report actual issues found in the code you reviewed - not hypotheticals.\nInclude specific line numbers from the diffs you analyzed.\nProvide code snippets to help with verification.\nIMPORTANT: If a finding matches a project rule, you MUST include the exact ruleId from the list.`,\n parameters: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string', description: 'File path' },\n line: { type: 'integer', description: 'Line number (from diff)' },\n endLine: { type: 'integer', description: 'End line for ranges (optional)' },\n severity: {\n type: 'string',\n enum: ['blocker', 'high', 'medium', 'low', 'info'],\n },\n category: {\n type: 'string',\n ...(validCategories.length > 0 ? { enum: validCategories } : {}),\n description: validCategories.length > 0\n ? `Category must be one of: ${validCategories.join(', ')}`\n : 'Category from project rules',\n },\n message: { type: 'string', description: 'Clear description of the issue' },\n suggestion: { type: 'string', description: 'How to fix (optional)' },\n codeSnippet: { type: 'string', description: 'Problematic code from diff' },\n ruleId: {\n type: ['string', 'null'],\n description: ruleIdDescription,\n },\n },\n required: ['file', 'line', 'severity', 'category', 'message'],\n },\n },\n summary: {\n type: 'string',\n description: 'Brief summary of review findings',\n },\n },\n required: ['findings'],\n },\n },\n ];\n}\n\n/**\n * Default budget limits\n */\nexport const DEFAULT_BUDGET: ToolBudget = {\n maxDiffCalls: 2,\n maxFilesPerDiff: 15,\n maxChunkCalls: 2,\n maxTotalChunks: 5,\n maxLinesPerChunk: 100,\n usage: {\n diffCalls: 0,\n filesRequested: 0,\n chunkCalls: 0,\n totalChunks: 0,\n },\n};\n\n/**\n * ToolExecutor - executes LLM tool calls with limits\n */\nexport class ToolExecutor {\n private diffProvider: IDiffProvider;\n private cwd: string;\n private budget: ToolBudget;\n private changedFiles: Set<string>;\n private fetchedDiffs: Map<string, FileDiff> = new Map();\n\n constructor(\n cwd: string,\n changedFiles: string[],\n diffProvider: IDiffProvider,\n budget?: Partial<ToolBudget>\n ) {\n this.cwd = cwd;\n this.diffProvider = diffProvider;\n this.changedFiles = new Set(changedFiles);\n this.budget = {\n ...DEFAULT_BUDGET,\n ...budget,\n usage: { ...DEFAULT_BUDGET.usage },\n };\n }\n\n /**\n * Execute a tool call\n */\n async execute(toolCall: ToolCall): Promise<ToolResult> {\n try {\n switch (toolCall.name) {\n case 'get_diffs':\n return await this.executeGetDiffs(toolCall.arguments as { files: string[] });\n\n case 'get_file_chunks':\n return await this.executeGetFileChunks(\n toolCall.arguments as { requests: FileChunkRequest[] }\n );\n\n case 'report_findings':\n return this.executeReportFindings(\n toolCall.arguments as { findings: RawFinding[]; summary?: string }\n );\n\n default:\n return {\n name: toolCall.name,\n result: null,\n error: `Unknown tool: ${toolCall.name}`,\n };\n }\n } catch (error) {\n return {\n name: toolCall.name,\n result: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Execute get_diffs tool\n */\n private async executeGetDiffs(args: { files: string[] }): Promise<ToolResult> {\n // Check budget\n if (this.budget.usage.diffCalls >= this.budget.maxDiffCalls) {\n return {\n name: 'get_diffs',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxDiffCalls} diff calls allowed`,\n };\n }\n\n // Validate and filter files (with path traversal protection)\n const resolvedCwd = path.resolve(this.cwd);\n const validFiles = args.files\n .slice(0, this.budget.maxFilesPerDiff)\n .filter(f => {\n // Must be in changed files list\n if (!this.changedFiles.has(f)) {\n return false;\n }\n // Path traversal protection using relative path check\n const fullPath = path.resolve(this.cwd, f);\n const relative = path.relative(resolvedCwd, fullPath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n });\n\n if (validFiles.length === 0) {\n return {\n name: 'get_diffs',\n result: { diffs: [], message: 'No valid files requested' },\n error: undefined,\n };\n }\n\n // Update budget\n this.budget.usage.diffCalls++;\n this.budget.usage.filesRequested += validFiles.length;\n\n // Fetch diffs\n const result = await this.diffProvider.getDiffs({\n cwd: this.cwd,\n files: validFiles,\n staged: true,\n unstaged: true,\n maxLinesPerFile: 500,\n });\n\n // Cache fetched diffs for verification later\n for (const diff of result.diffs) {\n this.fetchedDiffs.set(diff.file, diff);\n }\n\n // Format for LLM\n const formattedDiffs = result.diffs.map((d: FileDiff) => ({\n file: d.file,\n additions: d.additions,\n deletions: d.deletions,\n isNewFile: d.isNewFile,\n diff: d.diff,\n }));\n\n return {\n name: 'get_diffs',\n result: {\n diffs: formattedDiffs,\n errors: result.errors,\n budgetRemaining: {\n diffCalls: this.budget.maxDiffCalls - this.budget.usage.diffCalls,\n chunkCalls: this.budget.maxChunkCalls - this.budget.usage.chunkCalls,\n },\n },\n };\n }\n\n /**\n * Execute get_file_chunks tool\n */\n private async executeGetFileChunks(args: { requests: FileChunkRequest[] }): Promise<ToolResult> {\n // Check budget\n if (this.budget.usage.chunkCalls >= this.budget.maxChunkCalls) {\n return {\n name: 'get_file_chunks',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxChunkCalls} chunk calls allowed`,\n };\n }\n\n const remainingChunks = this.budget.maxTotalChunks - this.budget.usage.totalChunks;\n if (remainingChunks <= 0) {\n return {\n name: 'get_file_chunks',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxTotalChunks} total chunks allowed`,\n };\n }\n\n // Validate and limit requests\n const validRequests = args.requests\n .slice(0, remainingChunks)\n .filter(r => this.changedFiles.has(r.file));\n\n if (validRequests.length === 0) {\n return {\n name: 'get_file_chunks',\n result: { chunks: [], message: 'No valid files requested' },\n };\n }\n\n // Update budget\n this.budget.usage.chunkCalls++;\n this.budget.usage.totalChunks += validRequests.length;\n\n // Fetch chunks\n const chunks: Array<{\n file: string;\n startLine: number;\n endLine: number;\n content: string;\n }> = [];\n\n for (const request of validRequests) {\n try {\n // Path traversal protection: ensure file is within cwd\n const fullPath = path.resolve(this.cwd, request.file);\n const resolvedCwd = path.resolve(this.cwd);\n const relative = path.relative(resolvedCwd, fullPath);\n if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {\n useLogger()?.debug(`[ToolExecutor] Path traversal blocked: ${request.file}`);\n continue;\n }\n\n // eslint-disable-next-line no-await-in-loop -- Sequential file reading for chunk extraction\n const content = await readFile(fullPath, 'utf-8');\n const lines = content.split('\\n');\n\n // Default to full file if no range specified\n const startLine = Math.max(1, request.startLine ?? 1);\n const maxEndLine = Math.min(lines.length, startLine + this.budget.maxLinesPerChunk - 1);\n const endLine = request.endLine\n ? Math.min(request.endLine, maxEndLine)\n : maxEndLine;\n\n const chunkLines = lines.slice(startLine - 1, endLine);\n\n chunks.push({\n file: request.file,\n startLine,\n endLine,\n content: chunkLines.join('\\n'),\n });\n } catch (error) {\n useLogger()?.debug(`[ToolExecutor] Error reading ${request.file}:`, { error });\n }\n }\n\n return {\n name: 'get_file_chunks',\n result: {\n chunks,\n budgetRemaining: {\n chunkCalls: this.budget.maxChunkCalls - this.budget.usage.chunkCalls,\n totalChunks: this.budget.maxTotalChunks - this.budget.usage.totalChunks,\n },\n },\n };\n }\n\n /**\n * Execute report_findings tool (just passes through)\n */\n private executeReportFindings(args: {\n findings: RawFinding[];\n summary?: string;\n }): ToolResult {\n return {\n name: 'report_findings',\n result: {\n findings: args.findings,\n summary: args.summary,\n accepted: true,\n },\n };\n }\n\n /**\n * Get fetched diffs (for verification)\n */\n getFetchedDiffs(): Map<string, FileDiff> {\n return this.fetchedDiffs;\n }\n\n /**\n * Get current budget usage\n */\n getBudgetUsage(): ToolBudget['usage'] {\n return { ...this.budget.usage };\n }\n\n /**\n * Check if a file was in the changed files list\n */\n isValidFile(file: string): boolean {\n return this.changedFiles.has(file);\n }\n}\n\n/**\n * Create a ToolExecutor instance\n */\nexport function createToolExecutor(\n cwd: string,\n changedFiles: string[],\n diffProvider: IDiffProvider,\n budget?: Partial<ToolBudget>\n): ToolExecutor {\n return new ToolExecutor(cwd, changedFiles, diffProvider, budget);\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/verification\n * Anti-hallucination verification for LLM findings.\n *\n * Validates LLM output against actual code to filter hallucinations.\n */\n\nimport type { FileDiff } from '@kb-labs/review-contracts';\nimport type { RawFinding, RawFindingSeverity } from './tool-executor.js';\nimport { readFile } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Verification check results\n */\nexport interface VerificationChecks {\n /** Is severity a valid enum value? */\n severityValid: boolean;\n /** Is category a valid enum value? */\n categoryValid: boolean;\n /** Is file in the changed files list? */\n fileExists: boolean;\n /** Is line number within file bounds? */\n lineInBounds: boolean;\n /** Is line actually in the diff (changed)? */\n lineInDiff: boolean;\n /** Fuzzy match score for code snippet (0.0-1.0) */\n snippetMatch: number;\n /** Does the issue make sense for this file type? */\n contextValid: boolean;\n /** Is ruleId valid (matches a project rule) or null? */\n ruleIdValid: boolean;\n}\n\n/**\n * Verified finding with score\n */\nexport interface VerifiedFinding {\n /** Original finding */\n finding: RawFinding;\n /** Verification score (0.0-1.0) */\n score: number;\n /** Individual check results */\n checks: VerificationChecks;\n /** Action taken based on score */\n action: 'keep' | 'downgrade' | 'discard';\n /** Adjusted severity (if downgraded) */\n adjustedSeverity?: string;\n /** Enum normalization info */\n enumNormalization?: {\n severityOriginal: string;\n severityNormalized: string;\n categoryOriginal: string;\n categoryNormalized: string;\n };\n}\n\n/**\n * Verification result summary\n */\nexport interface VerificationResult {\n /** Findings that passed verification */\n verified: VerifiedFinding[];\n /** Findings that were discarded */\n discarded: VerifiedFinding[];\n /** Statistics */\n stats: {\n total: number;\n kept: number;\n downgraded: number;\n discarded: number;\n hallucinationRate: number;\n };\n}\n\n/**\n * Valid severity values\n */\nconst VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low', 'info'] as const;\ntype Severity = typeof VALID_SEVERITIES[number];\n\n/**\n * Severity aliases for normalization\n */\nconst SEVERITY_ALIASES: Record<string, Severity> = {\n critical: 'blocker',\n error: 'high',\n warning: 'medium',\n warn: 'medium',\n minor: 'low',\n trivial: 'info',\n suggestion: 'info',\n hint: 'info',\n};\n\n/**\n * Severity ordering for downgrade\n */\nconst SEVERITY_ORDER: Severity[] = ['blocker', 'high', 'medium', 'low', 'info'];\n\n/**\n * Verification thresholds\n */\nconst THRESHOLDS = {\n KEEP: 0.7,\n DOWNGRADE: 0.4,\n};\n\n/**\n * Score weights for each check.\n * Total = 1.0 (ruleIdValid is bonus that can push score above base)\n */\nconst SCORE_WEIGHTS = {\n severityValid: 0.075,\n categoryValid: 0.075,\n fileExists: 0.2,\n lineInBounds: 0.15,\n lineInDiff: 0.2,\n snippetMatch: 0.2,\n contextValid: 0.1,\n ruleIdValid: 0.05, // Bonus for using valid project rule ID\n};\n\n/**\n * VerificationEngine - validates LLM findings against actual code\n */\nexport class VerificationEngine {\n private cwd: string;\n private changedFiles: Set<string>;\n private fetchedDiffs: Map<string, FileDiff>;\n private validCategories: string[];\n private categoryAliases: Record<string, string>;\n private validRuleIds: Set<string>;\n private fileContents: Map<string, string> = new Map();\n\n constructor(\n cwd: string,\n changedFiles: string[],\n fetchedDiffs: Map<string, FileDiff>,\n validCategories: string[],\n categoryAliases: Record<string, string> = {},\n validRuleIds: Set<string> = new Set()\n ) {\n this.cwd = cwd;\n this.changedFiles = new Set(changedFiles);\n this.fetchedDiffs = fetchedDiffs;\n this.validCategories = validCategories;\n this.categoryAliases = categoryAliases;\n this.validRuleIds = validRuleIds;\n }\n\n /**\n * Verify all findings from LLM\n */\n async verify(findings: RawFinding[]): Promise<VerificationResult> {\n const verified: VerifiedFinding[] = [];\n const discarded: VerifiedFinding[] = [];\n\n let keptCount = 0;\n let downgradedCount = 0;\n\n for (const finding of findings) {\n // eslint-disable-next-line no-await-in-loop -- Sequential verification maintains order\n const result = await this.verifyFinding(finding);\n\n if (result.action === 'discard') {\n discarded.push(result);\n } else {\n verified.push(result);\n if (result.action === 'keep') {\n keptCount++;\n } else {\n downgradedCount++;\n }\n }\n }\n\n const total = findings.length;\n const hallucinationRate = total > 0 ? discarded.length / total : 0;\n\n return {\n verified,\n discarded,\n stats: {\n total,\n kept: keptCount,\n downgraded: downgradedCount,\n discarded: discarded.length,\n hallucinationRate,\n },\n };\n }\n\n /**\n * Verify a single finding\n */\n private async verifyFinding(finding: RawFinding): Promise<VerifiedFinding> {\n // Normalize enums first\n const severityNorm = this.normalizeSeverity(finding.severity);\n const categoryNorm = this.normalizeCategory(finding.category);\n\n // Validate ruleId\n const ruleIdValid = this.validateRuleId(finding.ruleId);\n\n // Run all checks\n const checks: VerificationChecks = {\n severityValid: severityNorm.valid,\n categoryValid: categoryNorm.valid,\n fileExists: this.changedFiles.has(finding.file),\n lineInBounds: await this.checkLineInBounds(finding.file, finding.line),\n lineInDiff: this.checkLineInDiff(finding.file, finding.line),\n snippetMatch: await this.matchSnippet(finding.file, finding.line, finding.codeSnippet),\n contextValid: this.checkContext(finding),\n ruleIdValid,\n };\n\n // Calculate score\n const score = this.calculateScore(checks);\n\n // Determine action\n let action: 'keep' | 'downgrade' | 'discard';\n let adjustedSeverity: RawFindingSeverity | undefined;\n\n if (score >= THRESHOLDS.KEEP) {\n action = 'keep';\n } else if (score >= THRESHOLDS.DOWNGRADE) {\n action = 'downgrade';\n adjustedSeverity = this.downgradeSeverity(severityNorm.normalized);\n } else {\n action = 'discard';\n }\n\n // Update finding with normalized values\n const normalizedFinding: RawFinding = {\n ...finding,\n severity: adjustedSeverity ?? severityNorm.normalized,\n category: categoryNorm.normalized,\n };\n\n return {\n finding: normalizedFinding,\n score,\n checks,\n action,\n adjustedSeverity,\n enumNormalization: {\n severityOriginal: finding.severity,\n severityNormalized: severityNorm.normalized,\n categoryOriginal: finding.category,\n categoryNormalized: categoryNorm.normalized,\n },\n };\n }\n\n /**\n * Normalize severity value to RawFindingSeverity type.\n */\n private normalizeSeverity(value: string): { valid: boolean; normalized: RawFindingSeverity } {\n const lower = value.toLowerCase().trim();\n\n // Direct match\n if (VALID_SEVERITIES.includes(lower as Severity)) {\n return { valid: true, normalized: lower as RawFindingSeverity };\n }\n\n // Alias match\n if (SEVERITY_ALIASES[lower]) {\n return { valid: true, normalized: SEVERITY_ALIASES[lower] };\n }\n\n // Invalid - default to medium\n return { valid: false, normalized: 'medium' };\n }\n\n /**\n * Normalize category value\n */\n private normalizeCategory(value: string): { valid: boolean; normalized: string } {\n const lower = value.toLowerCase().trim();\n\n // No categories configured - accept anything as valid (skip category validation)\n if (this.validCategories.length === 0) {\n return { valid: true, normalized: value };\n }\n\n // Direct match\n if (this.validCategories.includes(lower)) {\n return { valid: true, normalized: lower };\n }\n\n // Alias match\n if (this.categoryAliases[lower]) {\n return { valid: true, normalized: this.categoryAliases[lower] };\n }\n\n // Invalid - use first category as default\n return { valid: false, normalized: this.validCategories[0] ?? 'other' };\n }\n\n /**\n * Check if line is within file bounds\n */\n private async checkLineInBounds(file: string, line: number): Promise<boolean> {\n if (line < 1) {\n return false;\n }\n\n try {\n const content = await this.getFileContent(file);\n if (!content) {\n return false;\n }\n\n const lineCount = content.split('\\n').length;\n return line <= lineCount;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if line is in the diff (actually changed)\n */\n private checkLineInDiff(file: string, line: number): boolean {\n const diff = this.fetchedDiffs.get(file);\n if (!diff) {\n return false;\n }\n\n return diff.changedLines.has(line);\n }\n\n /**\n * Match code snippet against actual file content\n */\n private async matchSnippet(\n file: string,\n targetLine: number,\n snippet?: string\n ): Promise<number> {\n // No snippet = neutral score\n if (!snippet) {\n return 0.5;\n }\n\n try {\n const content = await this.getFileContent(file);\n if (!content) {\n return 0;\n }\n\n const lines = content.split('\\n');\n const windowSize = 5;\n\n const start = Math.max(0, targetLine - windowSize - 1);\n const end = Math.min(lines.length, targetLine + windowSize);\n const window = lines.slice(start, end).join('\\n');\n\n // Strategy 1: Exact substring match\n if (window.includes(snippet)) {\n return 1.0;\n }\n\n // Strategy 2: Line-trimmed match\n const trimmedSnippet = snippet.split('\\n').map(l => l.trim()).join('\\n');\n const trimmedWindow = window.split('\\n').map(l => l.trim()).join('\\n');\n if (trimmedWindow.includes(trimmedSnippet)) {\n return 0.95;\n }\n\n // Strategy 3: Single-line normalized (for single-line snippets)\n if (!snippet.includes('\\n')) {\n const normalizedSnippet = this.normalizeCodeLine(snippet);\n for (const line of lines.slice(start, end)) {\n if (this.normalizeCodeLine(line).includes(normalizedSnippet)) {\n return 0.9;\n }\n }\n }\n\n // Strategy 4: Token-based partial match\n const snippetTokens = this.extractIdentifiers(snippet);\n const windowTokens = new Set(this.extractIdentifiers(window));\n const matchedTokens = snippetTokens.filter(t => windowTokens.has(t));\n\n const tokenScore = matchedTokens.length / Math.max(snippetTokens.length, 1);\n return tokenScore * 0.8;\n } catch {\n return 0;\n }\n }\n\n /**\n * Normalize a single line of code (preserves strings)\n */\n private normalizeCodeLine(line: string): string {\n const strings: string[] = [];\n let normalized = line.replace(\n /(['\"`])(?:(?!\\1)[^\\\\]|\\\\.)*\\1/g,\n (match) => {\n strings.push(match);\n return `__STR${strings.length - 1}__`;\n }\n );\n\n normalized = normalized.replace(/\\s+/g, ' ').trim();\n\n strings.forEach((str, i) => {\n normalized = normalized.replace(`__STR${i}__`, str);\n });\n\n return normalized;\n }\n\n /**\n * Extract identifiers from code\n */\n private extractIdentifiers(code: string): string[] {\n const matches = code.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [];\n\n const keywords = new Set([\n 'const', 'let', 'var', 'function', 'class', 'if', 'else', 'for', 'while',\n 'return', 'import', 'export', 'from', 'async', 'await', 'try', 'catch',\n 'throw', 'new', 'this', 'true', 'false', 'null', 'undefined', 'typeof',\n ]);\n\n return matches.filter(m => !keywords.has(m) && m.length > 1);\n }\n\n /**\n * Validate ruleId - must be null or a valid rule ID from project rules\n */\n private validateRuleId(ruleId: string | null | undefined): boolean {\n // null is valid (ad-hoc finding)\n if (ruleId === null || ruleId === undefined) {\n return true;\n }\n\n // If no rules configured, accept any ruleId\n if (this.validRuleIds.size === 0) {\n return true;\n }\n\n // Check if ruleId matches a known rule\n return this.validRuleIds.has(ruleId);\n }\n\n /**\n * Check if finding makes sense for file context\n */\n private checkContext(finding: RawFinding): boolean {\n const fileLower = finding.file.toLowerCase();\n const messageLower = finding.message.toLowerCase();\n\n // SQL injection in non-DB file\n if (finding.category === 'security' &&\n messageLower.includes('sql') &&\n !fileLower.includes('db') &&\n !fileLower.includes('database') &&\n !fileLower.includes('query') &&\n !fileLower.includes('repository')) {\n return false;\n }\n\n // XSS in backend-only file\n if (messageLower.includes('xss') &&\n !fileLower.includes('component') &&\n !fileLower.includes('page') &&\n !fileLower.includes('.tsx') &&\n !fileLower.includes('.jsx')) {\n return false;\n }\n\n // Test file findings (usually less important)\n if (fileLower.includes('.test.') || fileLower.includes('.spec.')) {\n // Don't flag security issues in test files as context invalid\n // but they should be deprioritized elsewhere\n }\n\n return true;\n }\n\n /**\n * Calculate verification score\n */\n private calculateScore(checks: VerificationChecks): number {\n let score = 0;\n\n if (checks.severityValid) {\n score += SCORE_WEIGHTS.severityValid;\n }\n if (checks.categoryValid) {\n score += SCORE_WEIGHTS.categoryValid;\n }\n if (checks.fileExists) {\n score += SCORE_WEIGHTS.fileExists;\n }\n if (checks.lineInBounds) {\n score += SCORE_WEIGHTS.lineInBounds;\n }\n if (checks.lineInDiff) {\n score += SCORE_WEIGHTS.lineInDiff;\n }\n score += checks.snippetMatch * SCORE_WEIGHTS.snippetMatch;\n if (checks.contextValid) {\n score += SCORE_WEIGHTS.contextValid;\n }\n // Bonus for using valid project rule ID (increases confidence)\n if (checks.ruleIdValid) {\n score += SCORE_WEIGHTS.ruleIdValid;\n }\n\n return score;\n }\n\n /**\n * Downgrade severity by one level.\n * Returns the next lower severity or 'info' if already at lowest.\n */\n private downgradeSeverity(severity: RawFindingSeverity): RawFindingSeverity {\n const index = SEVERITY_ORDER.indexOf(severity);\n if (index === -1 || index >= SEVERITY_ORDER.length - 1) {\n return 'info';\n }\n return SEVERITY_ORDER[index + 1] ?? 'info';\n }\n\n /**\n * Get file content (with caching)\n */\n private async getFileContent(file: string): Promise<string | null> {\n if (this.fileContents.has(file)) {\n return this.fileContents.get(file)!;\n }\n\n try {\n const fullPath = path.join(this.cwd, file);\n const content = await readFile(fullPath, 'utf-8');\n this.fileContents.set(file, content);\n return content;\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Create a VerificationEngine instance\n */\nexport function createVerificationEngine(\n cwd: string,\n changedFiles: string[],\n fetchedDiffs: Map<string, FileDiff>,\n validCategories: string[],\n categoryAliases?: Record<string, string>,\n validRuleIds?: Set<string>\n): VerificationEngine {\n return new VerificationEngine(cwd, changedFiles, fetchedDiffs, validCategories, categoryAliases, validRuleIds);\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/category-validator\n * Dynamic category discovery from rules directory.\n *\n * Categories are NOT hardcoded - they come from .kb/ai-review/rules/ subdirectories.\n */\n\nimport type { ReviewConfig } from '@kb-labs/review-contracts';\nimport { useConfig } from '@kb-labs/sdk';\nimport { readdir, access } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Common aliases for category names\n * Maps common LLM outputs to standard category names (if they exist)\n */\nconst COMMON_CATEGORY_MAPPINGS: Record<string, string[]> = {\n security: ['sec', 'vulnerability', 'vulnerabilities', 'injection', 'auth', 'authentication', 'authorization'],\n performance: ['perf', 'speed', 'memory', 'optimization', 'optimisation'],\n architecture: ['design', 'structure', 'pattern', 'patterns', 'arch'],\n naming: ['names', 'conventions', 'identifiers', 'naming-convention'],\n consistency: ['style', 'formatting', 'code-style', 'codestyle'],\n testing: ['test', 'tests', 'coverage', 'unit-test', 'unittest'],\n correctness: ['bug', 'bugs', 'logic', 'error', 'errors', 'mistake'],\n maintainability: ['readability', 'complexity', 'code-quality', 'quality'],\n};\n\n/**\n * CategoryValidator - discovers and validates categories dynamically\n *\n * Categories come from .kb/ai-review/rules/ subdirectories.\n * No hardcoded categories - fully configurable per project.\n */\nexport class CategoryValidator {\n private validCategories: string[] = [];\n private categoryAliases: Record<string, string> = {};\n private defaultCategory: string = 'other';\n private initialized: boolean = false;\n\n /**\n * Initialize validator - discovers categories from config-defined rules directory\n *\n * @param cwd - Project root directory (ctx.cwd from command handler)\n */\n async init(cwd: string): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n this.validCategories = await discoverCategories(cwd);\n\n if (this.validCategories.length === 0) {\n // No categories found, will accept any category\n this.initialized = true;\n return;\n }\n\n this.categoryAliases = buildCategoryAliases(this.validCategories);\n this.defaultCategory = this.validCategories[0] ?? 'general';\n this.initialized = true;\n }\n\n /**\n * Validate and normalize a category value\n */\n validate(category: string): { valid: boolean; normalized: string } {\n if (this.validCategories.length === 0) {\n // No validation possible - accept but mark as unvalidated\n return { valid: false, normalized: category };\n }\n\n const lower = category.toLowerCase().trim();\n\n // Direct match\n if (this.validCategories.includes(lower)) {\n return { valid: true, normalized: lower };\n }\n\n // Alias match\n if (this.categoryAliases[lower]) {\n return { valid: true, normalized: this.categoryAliases[lower] };\n }\n\n // Invalid - use default\n return { valid: false, normalized: this.defaultCategory };\n }\n\n /**\n * Get list of valid categories\n */\n getValidCategories(): string[] {\n return [...this.validCategories];\n }\n\n /**\n * Get category aliases map\n */\n getCategoryAliases(): Record<string, string> {\n return { ...this.categoryAliases };\n }\n\n /**\n * Check if validator has been initialized\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n}\n\n/**\n * Discover valid categories from rules directory\n *\n * Reads subdirectories of .kb/ai-review/rules/ (or config-defined path).\n * Each subdirectory name becomes a valid category.\n *\n * @example\n * .kb/ai-review/rules/\n * ├── security/ → \"security\"\n * ├── naming/ → \"naming\"\n * ├── architecture/ → \"architecture\"\n * └── .hidden/ → (ignored)\n */\nexport async function discoverCategories(cwd: string): Promise<string[]> {\n try {\n // Use SDK's useConfig to get review config from kb.config.json\n const config = await useConfig<ReviewConfig>();\n\n // Get rulesDir from config (with fallback)\n const rulesDir = config?.rulesDir ?? 'ai-review/rules';\n const kbDir = path.join(cwd, '.kb');\n const fullPath = path.join(kbDir, rulesDir);\n\n // Check if rules directory exists\n try {\n await access(fullPath);\n } catch {\n // Rules directory not found\n return [];\n }\n\n // Read subdirectories\n const entries = await readdir(fullPath, { withFileTypes: true });\n return entries\n .filter(e => e.isDirectory() && !e.name.startsWith('.'))\n .map(e => e.name.toLowerCase());\n } catch {\n // Error discovering categories\n return [];\n }\n}\n\n/**\n * Build category aliases from discovered categories\n *\n * Maps common LLM outputs to actual category names (if they exist in the project).\n */\nexport function buildCategoryAliases(validCategories: string[]): Record<string, string> {\n const aliases: Record<string, string> = {};\n const categorySet = new Set(validCategories);\n\n for (const category of validCategories) {\n // Add the category itself (for case normalization)\n aliases[category] = category;\n\n // Add common aliases if this category exists\n const mappings = COMMON_CATEGORY_MAPPINGS[category];\n if (mappings) {\n for (const alias of mappings) {\n // Only add alias if it doesn't conflict with another category\n if (!categorySet.has(alias)) {\n aliases[alias] = category;\n }\n }\n }\n }\n\n return aliases;\n}\n\n/**\n * Create a CategoryValidator instance\n */\nexport function createCategoryValidator(): CategoryValidator {\n return new CategoryValidator();\n}\n\n// Singleton instance for convenience\nlet globalValidator: CategoryValidator | null = null;\n\n/**\n * Get or create the global CategoryValidator instance\n */\nexport async function getCategoryValidator(cwd: string): Promise<CategoryValidator> {\n if (!globalValidator) {\n globalValidator = new CategoryValidator();\n }\n\n if (!globalValidator.isInitialized()) {\n await globalValidator.init(cwd);\n }\n\n return globalValidator;\n}\n\n/**\n * Reset the global validator (for testing)\n */\nexport function resetCategoryValidator(): void {\n globalValidator = null;\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/prompt-loader\n * Load prompts and rules from .kb/ai-review/ directory.\n *\n * Reads markdown files and builds context for LLM prompts.\n */\n\nimport type { ReviewConfig } from '@kb-labs/review-contracts';\nimport { useConfig } from '@kb-labs/sdk';\nimport { readdir, readFile, access } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Rule frontmatter metadata\n */\nexport interface RuleFrontmatter {\n /** Unique rule ID (e.g., \"security/no-eval\") */\n id: string;\n /** Default severity for this rule */\n severity?: 'blocker' | 'high' | 'medium' | 'low' | 'info';\n /** Rule type: 'positive' (report these issues) or 'negative' (do NOT report these) */\n type?: 'positive' | 'negative';\n}\n\n/**\n * Loaded rule content\n */\nexport interface RuleContent {\n /** Rule category (directory name) */\n category: string;\n /** Rule name (filename without extension) */\n name: string;\n /** Rule content (markdown without frontmatter) */\n content: string;\n /** Rule ID from frontmatter (e.g., \"security/no-eval\") */\n id?: string;\n /** Default severity from frontmatter */\n severity?: 'blocker' | 'high' | 'medium' | 'low' | 'info';\n /** Rule type: 'positive' (report these) or 'negative' (do NOT report these) */\n type?: 'positive' | 'negative';\n}\n\n/**\n * Loaded prompts\n */\nexport interface LoadedPrompts {\n /** System prompt (from prompts/system.md or default) */\n system: string;\n /** Task prompt (from prompts/task.md or default) */\n task: string;\n /** Rules content by category */\n rules: Record<string, RuleContent[]>;\n /** All rules as formatted string for prompt */\n rulesContext: string;\n /** Set of valid rule IDs for validation */\n ruleIds: Set<string>;\n}\n\n/**\n * Default system prompt (fallback if no file exists)\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are a security-focused code auditor. Your job is to find every real vulnerability and bug in the code — think like an attacker reading this before exploiting it.\n\n## Process\n\n1. Fetch diffs for ALL files using get_diffs() before drawing any conclusions\n2. Read every file thoroughly — don't stop at the first finding\n3. After analyzing all files, report ALL findings in a single report_findings() call\n\n## What to Look For\n\nHunt for anything that could be exploited or cause harm in production:\n- Injection vectors: SQL, shell, template, path traversal, SSRF\n- Secrets and credentials hardcoded anywhere in the code\n- Broken authentication or authorization logic\n- Unsafe cryptography (weak algorithms, insecure randomness, plaintext storage)\n- Unvalidated input flowing into dangerous sinks\n- Logic errors that change program behavior in unexpected ways\n- Resource leaks and error paths that expose internals\n\n## Rules\n\n- Report every distinct issue you find — don't summarize multiple bugs into one\n- Each finding needs a line number and a code snippet from the diff\n- Skip style, formatting, and hypothetical \"could be better\" suggestions\n- Language doesn't matter: Python, PHP, JS, Go, Ruby — audit everything the same way\n\n## Severity\n\n### blocker\nDirectly exploitable: injection, RCE, auth bypass, exposed secrets, data exfiltration\n\n### high\nReal bug with production impact: broken logic, data corruption, significant information leak\n\n### medium\nPotential issue requiring specific conditions: missing validation, unsafe default, weak crypto choice\n\n### low\nMinor risk: informational leak in errors, missing rate limit, suboptimal but not dangerous`;\n\n/**\n * Default task prompt (fallback if no file exists)\n */\nconst DEFAULT_TASK_PROMPT = `## Your Task\n\nYou have a list of changed files. Do the following in order:\n\n1. Call get_diffs() for ALL files at once — fetch everything before analyzing anything\n2. Read every diff carefully and list every vulnerability or bug you spot\n3. Do NOT call report_findings() until you have gone through every single file\n4. Call report_findings() once with the complete list of everything you found\n\nDon't triage or prioritize — report every real issue, from hardcoded passwords to SQL injections to broken logic. A complete report is better than a conservative one.`;\n\n/**\n * Load all prompts and rules from .kb/ai-review/\n */\nexport async function loadPrompts(cwd: string): Promise<LoadedPrompts> {\n const config = await useConfig<ReviewConfig>('review');\n\n const kbDir = path.join(cwd, '.kb');\n const rulesDir = path.join(kbDir, config?.rulesDir ?? 'ai-review/rules');\n const promptsDir = path.join(kbDir, config?.promptsDir ?? 'ai-review/prompts');\n\n // Load system and task prompts\n const system = await loadPromptFile(promptsDir, 'system.md', DEFAULT_SYSTEM_PROMPT);\n const task = await loadPromptFile(promptsDir, 'task.md', DEFAULT_TASK_PROMPT);\n\n // Load rules by category\n const rules = await loadRules(rulesDir);\n\n // Collect all rule IDs for validation\n const ruleIds = new Set<string>();\n for (const categoryRules of Object.values(rules)) {\n for (const rule of categoryRules) {\n if (rule.id) {\n ruleIds.add(rule.id);\n }\n }\n }\n\n // Format rules as context string\n const rulesContext = formatRulesContext(rules);\n\n return { system, task, rules, rulesContext, ruleIds };\n}\n\n/**\n * Load a single prompt file with fallback\n */\nasync function loadPromptFile(dir: string, filename: string, fallback: string): Promise<string> {\n try {\n const filePath = path.join(dir, filename);\n await access(filePath);\n const content = await readFile(filePath, 'utf-8');\n return content.trim();\n } catch {\n return fallback;\n }\n}\n\n/**\n * Load all rules from rules directory\n */\nasync function loadRules(rulesDir: string): Promise<Record<string, RuleContent[]>> {\n const rules: Record<string, RuleContent[]> = {};\n\n try {\n await access(rulesDir);\n } catch {\n return rules;\n }\n\n // Read category directories\n const entries = await readdir(rulesDir, { withFileTypes: true });\n const categories = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));\n\n for (const categoryDir of categories) {\n const category = categoryDir.name;\n\n // Path traversal protection: skip names with path separators or '..'\n if (category.includes('..') || category.includes(path.sep) || category.includes('/')) {\n continue;\n }\n\n const categoryPath = path.join(rulesDir, category);\n\n // Read rule files in category\n // eslint-disable-next-line no-await-in-loop -- Sequential directory reading\n const ruleFiles = await readdir(categoryPath, { withFileTypes: true });\n const mdFiles = ruleFiles.filter(f => f.isFile() && f.name.endsWith('.md'));\n\n rules[category] = [];\n\n for (const ruleFile of mdFiles) {\n // Path traversal protection: skip names with path separators or '..'\n if (ruleFile.name.includes('..') || ruleFile.name.includes(path.sep) || ruleFile.name.includes('/')) {\n continue;\n }\n\n const ruleName = ruleFile.name.replace('.md', '');\n const rulePath = path.join(categoryPath, ruleFile.name);\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential file reading for rule loading\n const rawContent = await readFile(rulePath, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(rawContent);\n\n rules[category].push({\n category,\n name: ruleName,\n content: body.trim(),\n id: frontmatter?.id,\n severity: frontmatter?.severity,\n type: frontmatter?.type ?? 'positive', // Default to positive rule\n });\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return rules;\n}\n\n/**\n * Format rules as context string for prompt\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Complex multi-level categorization and formatting of rules into structured prompt sections\nfunction formatRulesContext(rules: Record<string, RuleContent[]>): string {\n const positiveSections: string[] = [];\n const negativeSections: string[] = [];\n\n for (const [category, categoryRules] of Object.entries(rules)) {\n if (categoryRules.length === 0) {\n continue;\n }\n\n // Separate positive and negative rules\n const positiveRules = categoryRules.filter(r => r.type !== 'negative');\n const negativeRules = categoryRules.filter(r => r.type === 'negative');\n\n // Format positive rules (issues to report)\n if (positiveRules.length > 0) {\n positiveSections.push(`## ${capitalize(category)} Rules\\n`);\n for (const rule of positiveRules) {\n if (rule.id) {\n positiveSections.push(`### Rule: ${rule.id}\\n`);\n }\n positiveSections.push(rule.content);\n positiveSections.push('');\n }\n }\n\n // Format negative rules (patterns NOT to report)\n if (negativeRules.length > 0) {\n for (const rule of negativeRules) {\n if (rule.id) {\n negativeSections.push(`### ${rule.id}\\n`);\n }\n negativeSections.push(rule.content);\n negativeSections.push('');\n }\n }\n }\n\n if (positiveSections.length === 0 && negativeSections.length === 0) {\n return '';\n }\n\n // Collect positive rule IDs for the explicit list\n const allRuleIds: string[] = [];\n for (const categoryRules of Object.values(rules)) {\n for (const rule of categoryRules) {\n if (rule.id && rule.type !== 'negative') {\n allRuleIds.push(rule.id);\n }\n }\n }\n\n const ruleIdList = allRuleIds.length > 0\n ? `\\n\\n**Available Rule IDs:** ${allRuleIds.join(', ')}`\n : '';\n\n // Build false positive prevention section\n const falsePositiveSection = negativeSections.length > 0\n ? `\\n\\n## FALSE POSITIVE PREVENTION (Do NOT Report These)\\n\\n**CRITICAL:** Before reporting any issue, check if it matches a pattern below. If it does, DO NOT REPORT IT.\\n\\n${negativeSections.join('\\n')}`\n : '';\n\n return `# Project-Specific Rules (MANDATORY)\n\n## CRITICAL: You MUST Use Rule IDs\n\nWhen reporting findings, you MUST check if the issue matches one of these project rules and use the exact ruleId:\n${ruleIdList}\n\n### How to Report:\n\n1. **If issue matches a rule** → Use the EXACT ruleId from the list above\n Example: \\`\"ruleId\": \"security/path-traversal\"\\` or \\`\"ruleId\": \"consistency/validation-logic\"\\`\n\n2. **If issue does NOT match any rule** → Use \\`\"ruleId\": null\\`\n\n### Examples:\n\n- Path traversal issue → \\`\"ruleId\": \"security/path-traversal\"\\`\n- Input validation issue → \\`\"ruleId\": \"security/input-validation\"\\`\n- Inconsistent validation logic → \\`\"ruleId\": \"consistency/validation-logic\"\\`\n- Dead code → \\`\"ruleId\": \"architecture/dead-code-paths\"\\`\n- Some other issue not in rules → \\`\"ruleId\": null\\`\n\n## Project Rules\n\n${positiveSections.join('\\n')}${falsePositiveSection}`;\n}\n\n/**\n * Capitalize first letter\n */\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Parse YAML frontmatter from markdown content\n *\n * Frontmatter format:\n * ---\n * id: category/rule-name\n * severity: medium\n * ---\n */\nfunction parseFrontmatter(content: string): { frontmatter: RuleFrontmatter | null; body: string } {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n*/;\n const match = content.match(frontmatterRegex);\n\n if (!match) {\n return { frontmatter: null, body: content };\n }\n\n const yamlContent = match[1] ?? '';\n const body = content.slice(match[0].length);\n\n // Simple YAML parsing (id and severity only)\n const frontmatter: Partial<RuleFrontmatter> = {};\n\n for (const line of yamlContent.split('\\n')) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) {\n continue;\n }\n\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n\n if (key === 'id') {\n frontmatter.id = value;\n } else if (key === 'severity') {\n const validSeverities = ['blocker', 'high', 'medium', 'low', 'info'];\n if (validSeverities.includes(value)) {\n frontmatter.severity = value as RuleFrontmatter['severity'];\n }\n } else if (key === 'type' && (value === 'positive' || value === 'negative')) {\n frontmatter.type = value;\n }\n }\n\n if (!frontmatter.id) {\n return { frontmatter: null, body: content };\n }\n\n return { frontmatter: frontmatter as RuleFrontmatter, body };\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/llm-lite-analyzer\n * LLM-Lite analyzer for efficient code review.\n *\n * Uses batch tools, diff-based context, and anti-hallucination verification.\n */\n\nimport type { ReviewFinding, InputFile, IDiffProvider, ReviewConfig } from '@kb-labs/review-contracts';\nimport { useLLM, useAnalytics, useConfig } from '@kb-labs/sdk';\nimport {\n createToolExecutor,\n buildToolDefinitions,\n type RawFinding,\n type ToolCall,\n} from './tool-executor.js';\nimport { createVerificationEngine, type VerificationResult } from './verification.js';\nimport { getCategoryValidator } from './category-validator.js';\nimport { loadPrompts, type LoadedPrompts } from './prompt-loader.js';\n\n/**\n * Review LLM config from kb.config.json\n */\ntype ReviewLLMConfig = NonNullable<ReviewConfig['llm']>;\n\n/**\n * LLM-Lite review request\n */\nexport interface LLMLiteRequest {\n /** Working directory */\n cwd: string;\n /** Changed files with content */\n files: InputFile[];\n /** Task context (what the changes are trying to achieve) */\n taskContext?: string;\n /** Repository scope */\n repoScope?: string[];\n /** Diff provider (injected from review-core to avoid circular dependency) */\n diffProvider: IDiffProvider;\n}\n\n/**\n * LLM-Lite review result\n */\nexport interface LLMLiteResult {\n /** Verified findings */\n findings: ReviewFinding[];\n /** Metadata */\n metadata: {\n /** LLM calls made */\n llmCalls: number;\n /** Tool calls made */\n toolCalls: {\n get_diffs: number;\n get_file_chunks: number;\n report_findings: number;\n };\n /** Token usage */\n tokens: {\n input: number;\n output: number;\n total: number;\n };\n /** Estimated cost in USD */\n estimatedCost: number;\n /** Verification stats */\n verification: {\n rawFindings: number;\n verified: number;\n downgraded: number;\n discarded: number;\n hallucinationRate: number;\n };\n /** Timing */\n timing: {\n totalMs: number;\n llmMs: number;\n verifyMs: number;\n };\n };\n}\n\n/**\n * File summary for initial prompt\n */\ninterface FileSummary {\n path: string;\n additions: number;\n deletions: number;\n isNewFile: boolean;\n}\n\n/**\n * Default turn limits (can be overridden via kb.config.json)\n */\nconst DEFAULT_MIN_TURNS = 3;\nconst DEFAULT_MAX_TURNS = 25;\nconst DEFAULT_FILES_PER_TURN = 10;\nconst DEFAULT_LINES_PER_TURN = 500;\n\n/**\n * Calculate adaptive turn limit based on workload\n *\n * Formula:\n * - Base: minTurns (get_diffs + analyze + report)\n * - +1 turn per filesPerTurn files (more files = more get_diffs calls needed)\n * - +1 turn per linesPerTurn lines changed (more changes = more context needed)\n * - Capped at maxTurns (cost control)\n *\n * All parameters configurable via kb.config.json review.llm section\n */\nfunction calculateMaxTurns(\n fileCount: number,\n totalChangedLines: number,\n config?: ReviewLLMConfig\n): number {\n const minTurns = config?.minTurns ?? DEFAULT_MIN_TURNS;\n const maxTurns = config?.maxTurns ?? DEFAULT_MAX_TURNS;\n const filesPerTurn = config?.filesPerTurn ?? DEFAULT_FILES_PER_TURN;\n const linesPerTurn = config?.linesPerTurn ?? DEFAULT_LINES_PER_TURN;\n\n const baseTurns = minTurns;\n const turnsForFiles = Math.ceil(fileCount / filesPerTurn);\n const turnsForLines = Math.ceil(totalChangedLines / linesPerTurn);\n return Math.min(maxTurns, baseTurns + turnsForFiles + turnsForLines);\n}\n\n/**\n * Token costs (GPT-4 pricing approximation)\n */\nconst TOKEN_COSTS = {\n input: 0.00003, // $0.03 per 1K input tokens\n output: 0.00006, // $0.06 per 1K output tokens\n};\n\n/**\n * LLM-Lite Analyzer\n *\n * Efficient code review using:\n * - Batch tools (get_diffs, get_file_chunks, report_findings)\n * - Diff-based context (not full files)\n * - Anti-hallucination verification\n * - Dynamic categories from rules directory\n */\nexport class LLMLiteAnalyzer {\n private cwd: string;\n private files: InputFile[];\n private taskContext?: string;\n private repoScope?: string[];\n private diffProvider: IDiffProvider;\n\n constructor(request: LLMLiteRequest) {\n this.cwd = request.cwd;\n this.files = request.files;\n this.taskContext = request.taskContext;\n this.repoScope = request.repoScope;\n this.diffProvider = request.diffProvider;\n }\n\n /**\n * Run LLM-Lite analysis\n */\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex multi-phase LLM analysis workflow with prompt loading, validation, and result processing\n async analyze(): Promise<LLMLiteResult> {\n const startTime = Date.now();\n const analytics = useAnalytics();\n\n // Track start\n analytics?.track('review:llm-lite:started', {\n fileCount: this.files.length,\n hasTaskContext: !!this.taskContext,\n });\n\n // Initialize\n const llm = useLLM({ tier: 'medium' });\n if (!llm) {\n throw new Error('LLM not available for llm-lite mode');\n }\n\n // Get review config from kb.config.json\n const reviewConfig = await useConfig<ReviewConfig>('review');\n const llmConfig = reviewConfig?.llm;\n\n // Load prompts and rules from .kb/ai-review/\n const prompts = await loadPrompts(this.cwd);\n\n // Get category validator\n const categoryValidator = await getCategoryValidator(this.cwd);\n const validCategories = categoryValidator.getValidCategories();\n const categoryAliases = categoryValidator.getCategoryAliases();\n\n // Build file summaries for initial prompt\n const fileSummaries = this.buildFileSummaries();\n\n // Calculate adaptive turn limit based on workload and config\n const totalChangedLines = fileSummaries.reduce(\n (sum, f) => sum + f.additions + f.deletions,\n 0\n );\n const maxTurns = calculateMaxTurns(this.files.length, totalChangedLines, llmConfig);\n\n // Create tool executor\n const changedFiles = this.files.map(f => f.path);\n const toolExecutor = createToolExecutor(this.cwd, changedFiles, this.diffProvider);\n\n // Build tools with dynamic categories and rule IDs\n const validRuleIds = Array.from(prompts.ruleIds);\n const tools = buildToolDefinitions(validCategories, validRuleIds);\n\n // Build prompts with loaded rules\n const systemPrompt = this.buildSystemPrompt(validCategories, prompts);\n const initialPrompt = this.buildInitialPrompt(fileSummaries, prompts);\n\n // Conversation loop\n // Messages array uses 'user' for initial prompt and tool results, 'assistant' for LLM responses.\n // Tool results are sent as 'user' messages to avoid Anthropic tool_use/tool_result format issues.\n const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [\n { role: 'user', content: initialPrompt },\n ];\n\n let llmCalls = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let llmTimeMs = 0;\n let rawFindings: RawFinding[] = [];\n\n const toolCallCounts = {\n get_diffs: 0,\n get_file_chunks: 0,\n report_findings: 0,\n };\n\n // Tool calling loop (adaptive based on workload)\n for (let turn = 0; turn < maxTurns; turn++) {\n const llmStart = Date.now();\n const isLastTurn = turn === maxTurns - 1;\n\n // On last turn, only offer report_findings to force conclusion\n const availableTools = isLastTurn\n ? tools.filter(t => t.name === 'report_findings')\n : tools;\n\n // Call LLM with tools\n // eslint-disable-next-line no-await-in-loop -- Conversation loop requires sequential turns\n const response = await llm.chatWithTools!(\n [\n { role: 'system', content: systemPrompt },\n ...messages,\n ],\n {\n tools: availableTools.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.parameters,\n })),\n }\n );\n\n llmCalls++;\n llmTimeMs += Date.now() - llmStart;\n\n // Track token usage (if available)\n // Note: Some adapters may not provide usage data, cost estimation will be incomplete\n if (response.usage) {\n totalInputTokens += response.usage.promptTokens ?? 0;\n totalOutputTokens += response.usage.completionTokens ?? 0;\n }\n\n // Check for tool calls\n const toolCalls = response.toolCalls ?? [];\n\n if (toolCalls.length === 0) {\n // No more tool calls - done\n break;\n }\n\n // Add assistant message only if there's actual content\n // Skip empty content even with tool calls - VibeProxy requires non-empty content\n const assistantContent = response.content ?? '';\n if (assistantContent.trim()) {\n messages.push({\n role: 'assistant',\n content: assistantContent,\n });\n }\n\n // Execute tool calls\n for (const toolCall of toolCalls) {\n const parsed: ToolCall = {\n name: toolCall.name,\n arguments: toolCall.input as Record<string, unknown>,\n };\n\n // Track tool call count\n if (parsed.name in toolCallCounts) {\n toolCallCounts[parsed.name as keyof typeof toolCallCounts]++;\n }\n\n // Execute\n // eslint-disable-next-line no-await-in-loop -- Sequential tool execution for conversation flow\n const result = await toolExecutor.execute(parsed);\n\n // Add tool result to messages\n // Using 'user' role with formatted text to avoid Anthropic tool_use/tool_result format issues\n // This is the same approach used by agent-executor\n messages.push({\n role: 'user',\n content: `Tool result (${parsed.name}):\\n${JSON.stringify(result.result, null, 2)}`,\n });\n\n // Check for report_findings (end condition)\n if (parsed.name === 'report_findings' && result.result) {\n const reportResult = result.result as { findings?: RawFinding[] };\n if (reportResult.findings) {\n rawFindings = reportResult.findings;\n }\n }\n }\n\n // If report_findings was called, we're done (regardless of findings count)\n if (toolCallCounts.report_findings > 0) {\n break;\n }\n }\n\n // Verification phase\n const verifyStart = Date.now();\n\n const verificationEngine = createVerificationEngine(\n this.cwd,\n changedFiles,\n toolExecutor.getFetchedDiffs(),\n validCategories,\n categoryAliases,\n prompts.ruleIds\n );\n\n const verificationResult = await verificationEngine.verify(rawFindings);\n const verifyTimeMs = Date.now() - verifyStart;\n\n // Convert to ReviewFinding format\n const findings = this.convertToReviewFindings(verificationResult);\n\n // Calculate cost\n const estimatedCost =\n (totalInputTokens * TOKEN_COSTS.input) +\n (totalOutputTokens * TOKEN_COSTS.output);\n\n // Track completion\n analytics?.track('review:llm-lite:completed', {\n fileCount: this.files.length,\n findingsCount: findings.length,\n llmCalls,\n hallucinationRate: verificationResult.stats.hallucinationRate,\n estimatedCost,\n });\n\n return {\n findings,\n metadata: {\n llmCalls,\n toolCalls: toolCallCounts,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n estimatedCost,\n verification: {\n rawFindings: verificationResult.stats.total,\n verified: verificationResult.verified.length,\n downgraded: verificationResult.stats.downgraded,\n discarded: verificationResult.stats.discarded,\n hallucinationRate: verificationResult.stats.hallucinationRate,\n },\n timing: {\n totalMs: Date.now() - startTime,\n llmMs: llmTimeMs,\n verifyMs: verifyTimeMs,\n },\n },\n };\n }\n\n /**\n * Build file summaries for initial prompt\n */\n private buildFileSummaries(): FileSummary[] {\n return this.files.map(f => {\n const lines = f.content.split('\\n');\n // Simple heuristic: new files have all additions\n // TODO: Get actual git stats\n return {\n path: f.path,\n additions: lines.length,\n deletions: 0,\n isNewFile: false,\n };\n });\n }\n\n /**\n * Build system prompt from loaded prompts and rules\n */\n private buildSystemPrompt(validCategories: string[], prompts: LoadedPrompts): string {\n const categoryList = validCategories.length > 0\n ? `\\n\\n## Valid Categories\\n\\nYou MUST use only these categories:\\n${validCategories.map(c => `- ${c}`).join('\\n')}`\n : '';\n\n // Combine: system prompt + rules context + categories\n let fullPrompt = prompts.system;\n\n // Add project-specific rules if any\n if (prompts.rulesContext) {\n fullPrompt += `\\n\\n${prompts.rulesContext}`;\n }\n\n // Add valid categories\n fullPrompt += categoryList;\n\n return fullPrompt;\n }\n\n /**\n * Build initial prompt with file list and task context\n */\n private buildInitialPrompt(files: FileSummary[], prompts: LoadedPrompts): string {\n const fileList = files.map(f => {\n const stats = `+${f.additions}/-${f.deletions}`;\n const status = f.isNewFile ? 'new file' : 'modified';\n return `- ${f.path} (${stats}, ${status})`;\n }).join('\\n');\n\n let prompt = `## Files Changed (${files.length} files)\n\n${fileList}`;\n\n if (this.taskContext) {\n prompt += `\\n\\n## Task Context\\n${this.taskContext}`;\n }\n\n if (this.repoScope?.length) {\n prompt += `\\n\\n## Repository Scope\\n${this.repoScope.join(', ')}`;\n }\n\n // Add task prompt from loaded prompts\n prompt += `\\n\\n${prompts.task}`;\n\n return prompt;\n }\n\n /**\n * Convert verified findings to ReviewFinding format\n */\n private convertToReviewFindings(result: VerificationResult): ReviewFinding[] {\n return result.verified.map(v => {\n // Map verification action to confidence level\n const confidence = v.action === 'keep' ? 'certain' as const\n : v.action === 'downgrade' ? 'likely' as const\n : 'heuristic' as const;\n\n // Determine ruleId: use LLM-provided ruleId if valid, otherwise generate from category\n // ruleId from LLM means it matched a project rule (e.g., \"security/no-eval\")\n // null/undefined means ad-hoc finding (LLM found it without matching a rule)\n let projectRuleId = v.finding.ruleId;\n\n // LLM sometimes includes \"rule:\" prefix - strip it if present\n if (projectRuleId?.startsWith('rule:')) {\n projectRuleId = projectRuleId.slice(5);\n }\n\n const ruleId = projectRuleId\n ? `rule:${projectRuleId}` // Matched project rule\n : `llm-lite:${v.finding.category}`; // Ad-hoc LLM finding\n\n // Source indicates whether finding came from a project rule or LLM's own analysis\n const source = projectRuleId ? 'rule' : 'llm';\n\n return {\n id: `llm-lite-${v.finding.file}-${v.finding.line}`,\n ruleId,\n file: v.finding.file,\n line: v.finding.line,\n endLine: v.finding.endLine,\n column: 1,\n message: v.finding.message,\n severity: v.finding.severity as 'blocker' | 'high' | 'medium' | 'low' | 'info',\n confidence,\n type: v.finding.category,\n engine: 'llm-lite',\n source,\n suggestion: v.finding.suggestion,\n snippet: v.finding.codeSnippet,\n };\n });\n }\n}\n\n/**\n * Run LLM-Lite analysis\n */\nexport async function runLLMLiteAnalysis(request: LLMLiteRequest): Promise<LLMLiteResult> {\n const analyzer = new LLMLiteAnalyzer(request);\n return analyzer.analyze();\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/prompts/architecture.prompts.ts","../src/analyzers/architecture-analyzer.ts","../src/prompts/security.prompts.ts","../src/analyzers/security-analyzer.ts","../src/prompts/naming.prompts.ts","../src/analyzers/naming-analyzer.ts","../src/llm-lite/tool-executor.ts","../src/llm-lite/verification.ts","../src/llm-lite/category-validator.ts","../src/llm-lite/prompt-loader.ts","../src/llm-lite/llm-lite-analyzer.ts"],"names":["buildSystemPrompt","analyzeFile","resolve","BaseLLMAnalyzer","useCache","useLogger","useAnalytics","useLLM","relative","VALID_SEVERITIES","path2","readFile","path3","useConfig","path4","access","readdir"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @module @kb-labs/review-llm/prompts/architecture\n * Architecture review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are an expert code reviewer specializing in software architecture.',\n '',\n '**Your role:**',\n '- Identify architecture violations and anti-patterns',\n '- Check adherence to project conventions',\n '- Suggest improvements with clear rationale',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report issues that exist in the provided code',\n '2. Reference line numbers that actually exist in the file',\n '3. Quote exact code snippets when referencing issues',\n '4. Provide concrete, actionable suggestions',\n '5. Reference project conventions and ADRs when applicable',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Evaluate architecture decisions in the context of this specific task.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Changes may span multiple repositories as part of one logical task.');\n sections.push('');\n }\n\n // Add related ADRs\n if (context.relatedADRs.length > 0) {\n sections.push('**Related Architecture Decisions:**');\n for (const adr of context.relatedADRs) {\n sections.push(`- ${adr.id}: ${adr.title} - ${adr.summary}`);\n }\n sections.push('');\n }\n\n // Add examples (if available)\n if (context.examples.length > 0) {\n sections.push('**Examples from codebase (informative, not normative):**');\n for (const ex of context.examples.slice(0, 3)) {\n sections.push(`- ${ex.file}: ${ex.description}`);\n }\n sections.push('');\n }\n\n sections.push('Use the report_architecture_finding tool to report issues.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for architecture issues:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report any architecture violations, anti-patterns, or violations of project conventions.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/architecture-analyzer\n * Architecture patterns analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as architecturePrompts from '../prompts/architecture.prompts.js';\n\n/**\n * Tool schema for architecture findings (structured output)\n */\nconst ARCHITECTURE_FINDING_TOOL = {\n name: 'report_architecture_finding',\n description: 'Report an architecture issue or suggestion',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['error', 'warning', 'info'],\n description: 'Severity level of the finding',\n },\n message: {\n type: 'string',\n description: 'Clear description of the architecture issue',\n },\n line: {\n type: 'number',\n description: 'Line number where issue occurs (must exist in file)',\n },\n suggestion: {\n type: 'string',\n description: 'Concrete fix suggestion with code example',\n },\n rationale: {\n type: 'string',\n description: 'Why this is an issue (reference conventions/ADRs if applicable)',\n },\n },\n required: ['severity', 'message', 'line', 'suggestion', 'rationale'],\n },\n} as const;\n\n/**\n * Valid severity values for ReviewFinding.\n * Maps to ReviewFinding['severity'] from @kb-labs/review-contracts.\n */\nconst _VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low', 'info'] as const;\ntype ValidSeverity = (typeof _VALID_SEVERITIES)[number];\n\n/**\n * Map LLM severity output to internal ReviewFinding severity.\n * LLM uses tool schema with enum ['error', 'warning', 'info'],\n * but internal findings use ['blocker', 'high', 'medium', 'low', 'info'].\n */\nfunction mapSeverity(llmSeverity: string): ValidSeverity {\n switch (llmSeverity) {\n case 'error': return 'high';\n case 'warning': return 'medium';\n case 'info': return 'info';\n default: return 'medium';\n }\n}\n\n/**\n * Architecture analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class ArchitectureAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'architecture';\n readonly name = 'Architecture Analysis';\n\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex LLM-based analysis with caching, error handling, and result validation\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n const analytics = useAnalytics();\n\n for (const file of files) {\n // Check cache first (content-hash based)\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential file analysis with caching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n // Build prompts with context\n const systemPrompt = architecturePrompts.buildSystemPrompt(context);\n const userPrompt = architecturePrompts.analyzeFile(file);\n\n // Use LLM with tool calling (structured output - better than text parsing!)\n const llm = useLLM({ tier: 'medium' }); // Architecture needs good reasoning\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential LLM calls per file (rate limiting)\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [ARCHITECTURE_FINDING_TOOL],\n temperature: 0.2, // Low temp for consistency\n }\n );\n\n // Validate response structure\n if (!response || typeof response !== 'object') {\n useLogger()?.debug(`[ArchitectureAnalyzer] Invalid response from LLM for ${file.path}`);\n continue;\n }\n\n // Track analytics (useful for monitoring)\n if (analytics && response.usage) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking after each file\n await analytics.track('review.architecture.complete', {\n file: file.path,\n tokensUsed: (response.usage.promptTokens ?? 0) + (response.usage.completionTokens ?? 0),\n toolCalls: response.toolCalls?.length ?? 0,\n });\n }\n\n // Process tool calls into findings (structured, no parsing!)\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n findings.push(...fileFindings);\n\n // Cache results (24 hours)\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Cache storage after analysis\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n } catch (error) {\n // Log detailed error information for debugging\n const errorMessage = error instanceof Error ? error.message : String(error);\n const errorName = error instanceof Error ? error.name : 'UnknownError';\n\n useLogger()?.debug(`[ArchitectureAnalyzer] Failed to analyze ${file.path}:`, {\n error,\n errorName,\n errorMessage,\n });\n continue;\n }\n }\n\n return findings;\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n \n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_architecture_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[ArchitectureAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Map and validate severity\n const severity = mapSeverity(String(args.severity || 'warning'));\n\n findings.push({\n id: this.buildFindingId(file, line, 'arch'),\n ruleId: 'llm:architecture',\n type: 'architecture',\n severity,\n confidence: 'likely', // LLM findings are \"likely\", not \"certain\"\n\n file: file.path,\n line,\n\n message: String(args.message || '').slice(0, 500),\n suggestion: args.suggestion ? String(args.suggestion).slice(0, 1000) : undefined,\n rationale: args.rationale ? String(args.rationale).slice(0, 500) : undefined,\n\n engine: 'llm',\n source: 'llm-architecture',\n\n // For agent mode gating\n scope: 'local', // Architecture can be local or global\n automated: false, // LLM suggestions need human review\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/prompts/security\n * Security review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are an expert security auditor specializing in application security.',\n '',\n '**Your role:**',\n '- Identify security vulnerabilities and weaknesses',\n '- Check for common security anti-patterns (OWASP Top 10)',\n '- Suggest secure coding practices with clear rationale',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report security issues that exist in the provided code',\n '2. Reference line numbers that actually exist in the file',\n '3. Quote exact code snippets when referencing issues',\n '4. Classify severity accurately (error = exploitable, warning = weakness)',\n '5. Provide concrete, actionable mitigation steps',\n '',\n '**Focus areas:**',\n '- SQL injection, XSS, CSRF',\n '- Authentication/authorization bypass',\n '- Insecure cryptography',\n '- Secrets in code',\n '- Command injection',\n '- Path traversal',\n '- Unsafe deserialization',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Pay special attention to security implications in the context of this task.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Check for security issues that may arise from cross-repo interactions.');\n sections.push('');\n }\n\n sections.push('Use the report_security_finding tool to report vulnerabilities.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for security vulnerabilities:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report any security vulnerabilities or weaknesses. Focus on exploitable issues.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/security-analyzer\n * Security vulnerability analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as securityPrompts from '../prompts/security.prompts.js';\n\n/**\n * Tool schema for security findings (structured output)\n */\nconst SECURITY_FINDING_TOOL = {\n name: 'report_security_finding',\n description: 'Report a security vulnerability or weakness',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['blocker', 'high', 'medium', 'low'],\n description: 'Severity level (blocker=exploitable, high=serious weakness)',\n },\n vulnerabilityType: {\n type: 'string',\n description: 'Type of vulnerability (e.g., SQL injection, XSS, CSRF)',\n },\n message: {\n type: 'string',\n description: 'Clear description of the security issue',\n },\n line: {\n type: 'number',\n description: 'Line number where vulnerability occurs',\n },\n mitigation: {\n type: 'string',\n description: 'Concrete mitigation steps with code example',\n },\n impact: {\n type: 'string',\n description: 'Potential impact if exploited',\n },\n },\n required: ['severity', 'vulnerabilityType', 'message', 'line', 'mitigation', 'impact'],\n },\n} as const;\n\n/** Valid severity values */\nconst VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low'] as const;\ntype ValidSeverity = (typeof VALID_SEVERITIES)[number];\n\n/** Retry configuration */\nconst MAX_RETRIES = 3;\nconst INITIAL_DELAY_MS = 1000;\n\n/** Batch size for parallel file processing */\nconst BATCH_SIZE = 5;\n\n/**\n * Sleep helper for retry delays\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => { setTimeout(resolve, ms); });\n}\n\n/**\n * Security analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class SecurityAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'security';\n readonly name = 'Security Analysis';\n\n /** Track failed files for reporting */\n private failedFiles: Array<{ file: string; error: string }> = [];\n\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n this.failedFiles = [];\n\n // Separate cached files from files needing analysis\n const filesToAnalyze: ParsedFile[] = [];\n\n for (const file of files) {\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential cache check before batching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n filesToAnalyze.push(file);\n }\n\n // Process files in batches for controlled parallelism\n for (let i = 0; i < filesToAnalyze.length; i += BATCH_SIZE) {\n const batch = filesToAnalyze.slice(i, i + BATCH_SIZE);\n\n // Process batch in parallel\n // eslint-disable-next-line no-await-in-loop -- Intentional batching to limit concurrency\n const batchResults = await Promise.allSettled(\n batch.map(file => this.analyzeFile(file, context, cache))\n );\n\n // Collect results\n for (let j = 0; j < batchResults.length; j++) {\n const result = batchResults[j]!;\n const file = batch[j]!;\n\n if (result.status === 'fulfilled') {\n findings.push(...result.value);\n } else {\n this.failedFiles.push({ file: file.path, error: result.reason?.message ?? 'Unknown error' });\n }\n }\n }\n\n // Log summary of failures if any\n if (this.failedFiles.length > 0) {\n useLogger()?.debug(`[SecurityAnalyzer] Failed to analyze ${this.failedFiles.length} file(s):`, {\n files: this.failedFiles,\n });\n }\n\n return findings;\n }\n\n /**\n * Analyze a single file with retry logic\n */\n private async analyzeFile(\n file: ParsedFile,\n context: ReviewContext,\n cache: ReturnType<typeof useCache>\n ): Promise<ReviewFinding[]> {\n const analytics = useAnalytics();\n const systemPrompt = securityPrompts.buildSystemPrompt(context);\n const userPrompt = securityPrompts.analyzeFile(file);\n\n const llm = useLLM({ tier: 'medium' });\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n // Retry with exponential backoff\n let lastError: Error | null = null;\n for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {\n try {\n // eslint-disable-next-line no-await-in-loop -- Retry loop requires sequential attempts\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [SECURITY_FINDING_TOOL],\n temperature: 0.1,\n }\n );\n\n // Track analytics\n if (analytics) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking in retry loop\n await analytics.track('review.security.complete', {\n file: file.path,\n tokensUsed: response.usage.promptTokens + response.usage.completionTokens,\n toolCalls: response.toolCalls?.length ?? 0,\n attempts: attempt,\n });\n }\n\n // Process tool calls\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n\n // Cache results (24 hours)\n if (cache) {\n const cacheKey = this.generateCacheKey(file, context.preset);\n // eslint-disable-next-line no-await-in-loop -- Cache storage in retry loop\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n\n return fileFindings;\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n useLogger()?.debug(`[SecurityAnalyzer] Attempt ${attempt}/${MAX_RETRIES} failed for ${file.path}:`, { error });\n\n if (attempt < MAX_RETRIES) {\n const delay = INITIAL_DELAY_MS * Math.pow(2, attempt - 1);\n // eslint-disable-next-line no-await-in-loop -- Intentional delay between retry attempts\n await sleep(delay);\n }\n }\n }\n\n throw lastError ?? new Error('Analysis failed');\n }\n\n /**\n * Get list of files that failed analysis\n */\n getFailedFiles(): Array<{ file: string; error: string }> {\n return [...this.failedFiles];\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex validation and mapping of LLM tool call results to structured findings\n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_security_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[SecurityAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Validate severity (reject invalid values instead of normalizing)\n const severity = args.severity as string;\n if (!VALID_SEVERITIES.includes(severity as ValidSeverity)) {\n useLogger()?.debug(`[SecurityAnalyzer] Invalid severity \"${severity}\" for finding in ${file.path}:${line}`);\n continue;\n }\n\n // Sanitize vulnerability type (alphanumeric, dash, underscore only)\n const vulnerabilityType = String(args.vulnerabilityType || 'unknown')\n .replace(/[^a-zA-Z0-9_-]/g, '_')\n .slice(0, 50);\n\n findings.push({\n id: this.buildFindingId(file, line, 'sec'),\n ruleId: `llm:security:${vulnerabilityType}`,\n type: 'security',\n severity: severity as ValidSeverity,\n confidence: 'likely', // LLM findings are \"likely\", not \"certain\"\n\n file: file.path,\n line,\n\n message: `[${vulnerabilityType}] ${String(args.message || '').slice(0, 500)}`,\n suggestion: args.mitigation ? String(args.mitigation).slice(0, 1000) : undefined,\n rationale: args.impact ? `Impact: ${String(args.impact).slice(0, 500)}` : undefined,\n\n engine: 'llm',\n source: 'llm-security',\n\n // For agent mode gating\n scope: 'local',\n automated: false, // Security fixes need human review\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/prompts/naming\n * Naming conventions review prompts\n */\n\nimport type { ReviewContext, ParsedFile } from '@kb-labs/review-contracts';\n\n/**\n * Build system prompt with context\n */\nexport function buildSystemPrompt(context: ReviewContext): string {\n const sections: string[] = [\n 'You are a code quality expert specializing in naming conventions and code clarity.',\n '',\n '**Your role:**',\n '- Check adherence to naming conventions',\n '- Identify unclear or misleading names',\n '- Suggest improvements for readability',\n '',\n '**CRITICAL RULES:**',\n '1. ONLY report names that violate project conventions',\n '2. Reference line numbers that actually exist',\n '3. Quote exact names when referencing issues',\n '4. Provide concrete, better alternatives',\n '5. Focus on clarity and consistency',\n '',\n '**Common issues:**',\n '- Inconsistent casing (camelCase vs snake_case)',\n '- Abbreviations without clear meaning',\n '- Generic names (data, temp, obj)',\n '- Misleading names (opposite of actual behavior)',\n '',\n ];\n\n // Add all project conventions\n for (const [category, content] of Object.entries(context.conventions)) {\n sections.push(`**Project Conventions (${category}):**`);\n sections.push(content);\n sections.push('');\n }\n\n // Add task context (if reviewing a specific task)\n if (context.taskContext) {\n sections.push('**Current Task Context:**');\n sections.push(context.taskContext);\n sections.push('');\n sections.push('IMPORTANT: Consider naming in the context of this specific task and its domain.');\n sections.push('');\n }\n\n // Add repo scope (if multi-repo review)\n if (context.repoScope && context.repoScope.length > 0) {\n sections.push('**Repositories in Scope:**');\n sections.push(context.repoScope.map((r) => `- ${r}`).join('\\n'));\n sections.push('');\n sections.push('NOTE: Ensure naming consistency across these repositories.');\n sections.push('');\n }\n\n sections.push('Use the report_naming_finding tool to report naming issues.');\n\n return sections.join('\\n');\n}\n\n/**\n * Build user prompt for file analysis\n */\nexport function analyzeFile(file: ParsedFile): string {\n const lines = file.content.split('\\n');\n const numbered = lines\n .map((line, idx) => `${idx + 1}: ${line}`)\n .join('\\n');\n\n return `Review this file for naming convention issues:\\n\\n` +\n `File: ${file.path}\\n` +\n `Language: ${file.language}\\n\\n` +\n `\\`\\`\\`${file.language}\\n${numbered}\\n\\`\\`\\`\\n\\n` +\n `Report naming issues that reduce code clarity or violate conventions.`;\n}\n","/**\n * @module @kb-labs/review-llm/analyzers/naming-analyzer\n * Naming conventions analyzer using LLM with tool calling\n */\n\nimport type { ReviewFinding, ParsedFile, ReviewContext } from '@kb-labs/review-contracts';\nimport { BaseLLMAnalyzer } from '@kb-labs/review-contracts';\nimport { useLLM, useCache, useAnalytics, useLogger } from '@kb-labs/sdk';\nimport * as namingPrompts from '../prompts/naming.prompts.js';\n\n/**\n * Tool schema for naming findings (structured output)\n */\nconst NAMING_FINDING_TOOL = {\n name: 'report_naming_finding',\n description: 'Report a naming convention issue',\n inputSchema: {\n type: 'object',\n properties: {\n severity: {\n type: 'string',\n enum: ['warning', 'info'],\n description: 'Severity level (naming issues are typically warning/info)',\n },\n currentName: {\n type: 'string',\n description: 'Current name that violates conventions',\n },\n suggestedName: {\n type: 'string',\n description: 'Suggested better name',\n },\n message: {\n type: 'string',\n description: 'Description of the naming issue',\n },\n line: {\n type: 'number',\n description: 'Line number where name appears',\n },\n rationale: {\n type: 'string',\n description: 'Why the current name is problematic',\n },\n },\n required: ['severity', 'currentName', 'suggestedName', 'message', 'line', 'rationale'],\n },\n} as const;\n\n/**\n * Naming analyzer\n * Uses LLM with tool calling for structured findings\n */\nexport class NamingAnalyzer extends BaseLLMAnalyzer {\n readonly id = 'naming';\n readonly name = 'Naming Conventions';\n\n async analyze(files: ParsedFile[], context: ReviewContext): Promise<ReviewFinding[]> {\n const findings: ReviewFinding[] = [];\n const cache = useCache();\n const analytics = useAnalytics();\n\n for (const file of files) {\n // Check cache first\n const cacheKey = this.generateCacheKey(file, context.preset);\n\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Sequential file analysis with caching\n const cached = await cache.get<ReviewFinding[]>(cacheKey);\n if (cached) {\n findings.push(...cached);\n continue;\n }\n }\n\n // Build prompts\n const systemPrompt = namingPrompts.buildSystemPrompt(context);\n const userPrompt = namingPrompts.analyzeFile(file);\n\n // Use LLM with tool calling\n const llm = useLLM({ tier: 'small' }); // Naming is simpler, can use small model\n if (!llm?.chatWithTools) {\n throw new Error('LLM not configured or does not support tool calling');\n }\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential LLM calls per file (rate limiting)\n const response = await llm.chatWithTools(\n [\n { role: 'system', content: systemPrompt },\n { role: 'user', content: userPrompt },\n ],\n {\n tools: [NAMING_FINDING_TOOL],\n temperature: 0.2, // Low temp for consistency\n }\n );\n\n // Track analytics\n if (analytics) {\n // eslint-disable-next-line no-await-in-loop -- Analytics tracking after each file\n await analytics.track('review.naming.complete', {\n file: file.path,\n tokensUsed: response.usage.promptTokens + response.usage.completionTokens,\n toolCalls: response.toolCalls?.length ?? 0,\n });\n }\n\n // Process tool calls\n const fileFindings = this.processToolCalls(response.toolCalls || [], file);\n findings.push(...fileFindings);\n\n // Cache results (24 hours)\n if (cache) {\n // eslint-disable-next-line no-await-in-loop -- Cache storage after analysis\n await cache.set(cacheKey, fileFindings, 86400000);\n }\n } catch (error) {\n useLogger()?.debug(`[NamingAnalyzer] Failed to analyze ${file.path}:`, { error });\n continue;\n }\n }\n\n return findings;\n }\n\n /**\n * Process LLM tool calls into ReviewFindings\n */\n \n private processToolCalls(toolCalls: any[], file: ParsedFile): ReviewFinding[] {\n const findings: ReviewFinding[] = [];\n\n for (const call of toolCalls) {\n if (call.name === 'report_naming_finding') {\n \n const args = call.input as any;\n\n // Validate line number\n const lineCount = file.content.split('\\n').length;\n const line = typeof args.line === 'number' ? args.line : parseInt(args.line, 10);\n if (isNaN(line) || line < 1 || line > lineCount) {\n useLogger()?.debug(`[NamingAnalyzer] Invalid line number ${args.line} for ${file.path}`);\n continue;\n }\n\n // Validate severity (naming issues are warning/info only)\n const severity = args.severity === 'warning' ? 'medium' : 'info';\n\n // Sanitize names for display\n const currentName = String(args.currentName || '').slice(0, 100);\n const suggestedName = String(args.suggestedName || '').slice(0, 100);\n\n findings.push({\n id: this.buildFindingId(file, line, 'naming'),\n ruleId: 'llm:naming',\n type: 'style',\n severity,\n confidence: 'heuristic', // Naming is subjective, low confidence\n\n file: file.path,\n line,\n\n message: String(args.message || '').slice(0, 500),\n suggestion: `Rename '${currentName}' to '${suggestedName}'`,\n rationale: args.rationale ? String(args.rationale).slice(0, 500) : undefined,\n\n engine: 'llm',\n source: 'llm-naming',\n\n // For agent mode gating\n scope: 'local',\n automated: false, // Naming suggestions are optional\n });\n }\n }\n\n return findings;\n }\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/tool-executor\n * Batch tool execution for LLM-lite review mode.\n *\n * Executes LLM tools with limits and budget tracking.\n */\n\nimport type { FileDiff, IDiffProvider } from '@kb-labs/review-contracts';\nimport * as path from 'node:path';\nimport { readFile } from 'node:fs/promises';\nimport { useLogger } from '@kb-labs/sdk';\n\n/**\n * Tool call from LLM\n */\nexport interface ToolCall {\n name: string;\n arguments: Record<string, unknown>;\n}\n\n/**\n * Tool result\n */\nexport interface ToolResult {\n name: string;\n result: unknown;\n error?: string;\n}\n\n/**\n * Valid severity levels for LLM findings.\n * Matches the enum in report_findings tool schema.\n */\nexport type RawFindingSeverity = 'blocker' | 'high' | 'medium' | 'low' | 'info';\n\n/**\n * Raw finding from LLM (before validation).\n * These are the findings reported by the LLM via the report_findings tool.\n */\nexport interface RawFinding {\n file: string;\n line: number;\n endLine?: number;\n /** Severity level - must be one of: blocker, high, medium, low, info */\n severity: RawFindingSeverity;\n category: string;\n message: string;\n suggestion?: string;\n codeSnippet?: string;\n /** Rule ID if this finding matches a project rule (e.g., \"security/no-eval\") */\n ruleId?: string | null;\n}\n\n/**\n * Report findings result\n */\nexport interface ReportFindingsResult {\n findings: RawFinding[];\n summary?: string;\n}\n\n/**\n * File chunk request\n */\nexport interface FileChunkRequest {\n file: string;\n startLine?: number;\n endLine?: number;\n}\n\n/**\n * Tool budget tracking\n */\nexport interface ToolBudget {\n /** Max calls to get_diffs */\n maxDiffCalls: number;\n /** Max files per get_diffs call */\n maxFilesPerDiff: number;\n /** Max calls to get_file_chunks */\n maxChunkCalls: number;\n /** Max chunks across all calls */\n maxTotalChunks: number;\n /** Max lines per chunk */\n maxLinesPerChunk: number;\n /** Current usage */\n usage: {\n diffCalls: number;\n filesRequested: number;\n chunkCalls: number;\n totalChunks: number;\n };\n}\n\n/**\n * Tool definitions for LLM\n */\nexport function buildToolDefinitions(validCategories: string[], validRuleIds: string[] = []) {\n // Build rule ID description with list of available rules\n const ruleIdDescription = validRuleIds.length > 0\n ? `Rule ID if matches a project rule. Available rules: ${validRuleIds.join(', ')}. Use null if finding doesn't match any rule.`\n : 'Rule ID if matches project rule (e.g., \"security/no-eval\"), null if ad-hoc finding';\n\n return [\n {\n name: 'get_diffs',\n description: `Get git diffs for multiple files at once.\nUse this to see what changed in files that look suspicious.\nSelect files based on: file names, change size (+lines/-lines), whether new/modified.\nPrefer files most likely to have issues (security-sensitive, complex logic, etc).`,\n parameters: {\n type: 'object',\n properties: {\n files: {\n type: 'array',\n items: { type: 'string' },\n maxItems: 15,\n description: 'File paths from the list (max 15 per call)',\n },\n },\n required: ['files'],\n },\n },\n {\n name: 'get_file_chunks',\n description: `Get specific portions of files when diff alone isn't enough.\nUse when you need to see:\n- Code around a suspicious change (function context)\n- Definition that a change references\n- Import statements to understand dependencies\nUse sparingly - prefer analyzing diffs first.`,\n parameters: {\n type: 'object',\n properties: {\n requests: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string' },\n startLine: { type: 'integer', description: 'Start line (1-indexed)' },\n endLine: { type: 'integer', description: 'End line (max startLine + 100)' },\n },\n required: ['file'],\n },\n maxItems: 5,\n description: 'Chunk requests (max 5 total across all calls)',\n },\n },\n required: ['requests'],\n },\n },\n {\n name: 'report_findings',\n description: `Report all code review findings. Call once when done analyzing.\nOnly report actual issues found in the code you reviewed - not hypotheticals.\nInclude specific line numbers from the diffs you analyzed.\nProvide code snippets to help with verification.\nIMPORTANT: If a finding matches a project rule, you MUST include the exact ruleId from the list.`,\n parameters: {\n type: 'object',\n properties: {\n findings: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n file: { type: 'string', description: 'File path' },\n line: { type: 'integer', description: 'Line number (from diff)' },\n endLine: { type: 'integer', description: 'End line for ranges (optional)' },\n severity: {\n type: 'string',\n enum: ['blocker', 'high', 'medium', 'low', 'info'],\n },\n category: {\n type: 'string',\n ...(validCategories.length > 0 ? { enum: validCategories } : {}),\n description: validCategories.length > 0\n ? `Category must be one of: ${validCategories.join(', ')}`\n : 'Category from project rules',\n },\n message: { type: 'string', description: 'Clear description of the issue' },\n suggestion: { type: 'string', description: 'How to fix (optional)' },\n codeSnippet: { type: 'string', description: 'Problematic code from diff' },\n ruleId: {\n type: ['string', 'null'],\n description: ruleIdDescription,\n },\n },\n required: ['file', 'line', 'severity', 'category', 'message'],\n },\n },\n summary: {\n type: 'string',\n description: 'Brief summary of review findings',\n },\n },\n required: ['findings'],\n },\n },\n ];\n}\n\n/**\n * Default budget limits\n */\nexport const DEFAULT_BUDGET: ToolBudget = {\n maxDiffCalls: 2,\n maxFilesPerDiff: 15,\n maxChunkCalls: 2,\n maxTotalChunks: 5,\n maxLinesPerChunk: 100,\n usage: {\n diffCalls: 0,\n filesRequested: 0,\n chunkCalls: 0,\n totalChunks: 0,\n },\n};\n\n/**\n * ToolExecutor - executes LLM tool calls with limits\n */\nexport class ToolExecutor {\n private diffProvider: IDiffProvider;\n private cwd: string;\n private budget: ToolBudget;\n private changedFiles: Set<string>;\n private fetchedDiffs: Map<string, FileDiff> = new Map();\n\n constructor(\n cwd: string,\n changedFiles: string[],\n diffProvider: IDiffProvider,\n budget?: Partial<ToolBudget>\n ) {\n this.cwd = cwd;\n this.diffProvider = diffProvider;\n this.changedFiles = new Set(changedFiles);\n this.budget = {\n ...DEFAULT_BUDGET,\n ...budget,\n usage: { ...DEFAULT_BUDGET.usage },\n };\n }\n\n /**\n * Execute a tool call\n */\n async execute(toolCall: ToolCall): Promise<ToolResult> {\n try {\n switch (toolCall.name) {\n case 'get_diffs':\n return await this.executeGetDiffs(toolCall.arguments as { files: string[] });\n\n case 'get_file_chunks':\n return await this.executeGetFileChunks(\n toolCall.arguments as { requests: FileChunkRequest[] }\n );\n\n case 'report_findings':\n return this.executeReportFindings(\n toolCall.arguments as { findings: RawFinding[]; summary?: string }\n );\n\n default:\n return {\n name: toolCall.name,\n result: null,\n error: `Unknown tool: ${toolCall.name}`,\n };\n }\n } catch (error) {\n return {\n name: toolCall.name,\n result: null,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Execute get_diffs tool\n */\n private async executeGetDiffs(args: { files: string[] }): Promise<ToolResult> {\n // Check budget\n if (this.budget.usage.diffCalls >= this.budget.maxDiffCalls) {\n return {\n name: 'get_diffs',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxDiffCalls} diff calls allowed`,\n };\n }\n\n // Validate and filter files (with path traversal protection)\n const resolvedCwd = path.resolve(this.cwd);\n const validFiles = args.files\n .slice(0, this.budget.maxFilesPerDiff)\n .filter(f => {\n // Must be in changed files list\n if (!this.changedFiles.has(f)) {\n return false;\n }\n // Path traversal protection using relative path check\n const fullPath = path.resolve(this.cwd, f);\n const relative = path.relative(resolvedCwd, fullPath);\n return relative && !relative.startsWith('..') && !path.isAbsolute(relative);\n });\n\n if (validFiles.length === 0) {\n return {\n name: 'get_diffs',\n result: { diffs: [], message: 'No valid files requested' },\n error: undefined,\n };\n }\n\n // Update budget\n this.budget.usage.diffCalls++;\n this.budget.usage.filesRequested += validFiles.length;\n\n // Fetch diffs\n const result = await this.diffProvider.getDiffs({\n cwd: this.cwd,\n files: validFiles,\n staged: true,\n unstaged: true,\n maxLinesPerFile: 500,\n });\n\n // Cache fetched diffs for verification later\n for (const diff of result.diffs) {\n this.fetchedDiffs.set(diff.file, diff);\n }\n\n // Format for LLM\n const formattedDiffs = result.diffs.map((d: FileDiff) => ({\n file: d.file,\n additions: d.additions,\n deletions: d.deletions,\n isNewFile: d.isNewFile,\n diff: d.diff,\n }));\n\n return {\n name: 'get_diffs',\n result: {\n diffs: formattedDiffs,\n errors: result.errors,\n budgetRemaining: {\n diffCalls: this.budget.maxDiffCalls - this.budget.usage.diffCalls,\n chunkCalls: this.budget.maxChunkCalls - this.budget.usage.chunkCalls,\n },\n },\n };\n }\n\n /**\n * Execute get_file_chunks tool\n */\n private async executeGetFileChunks(args: { requests: FileChunkRequest[] }): Promise<ToolResult> {\n // Check budget\n if (this.budget.usage.chunkCalls >= this.budget.maxChunkCalls) {\n return {\n name: 'get_file_chunks',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxChunkCalls} chunk calls allowed`,\n };\n }\n\n const remainingChunks = this.budget.maxTotalChunks - this.budget.usage.totalChunks;\n if (remainingChunks <= 0) {\n return {\n name: 'get_file_chunks',\n result: null,\n error: `Budget exceeded: max ${this.budget.maxTotalChunks} total chunks allowed`,\n };\n }\n\n // Validate and limit requests\n const validRequests = args.requests\n .slice(0, remainingChunks)\n .filter(r => this.changedFiles.has(r.file));\n\n if (validRequests.length === 0) {\n return {\n name: 'get_file_chunks',\n result: { chunks: [], message: 'No valid files requested' },\n };\n }\n\n // Update budget\n this.budget.usage.chunkCalls++;\n this.budget.usage.totalChunks += validRequests.length;\n\n // Fetch chunks\n const chunks: Array<{\n file: string;\n startLine: number;\n endLine: number;\n content: string;\n }> = [];\n\n for (const request of validRequests) {\n try {\n // Path traversal protection: ensure file is within cwd\n const fullPath = path.resolve(this.cwd, request.file);\n const resolvedCwd = path.resolve(this.cwd);\n const relative = path.relative(resolvedCwd, fullPath);\n if (!relative || relative.startsWith('..') || path.isAbsolute(relative)) {\n useLogger()?.debug(`[ToolExecutor] Path traversal blocked: ${request.file}`);\n continue;\n }\n\n // eslint-disable-next-line no-await-in-loop -- Sequential file reading for chunk extraction\n const content = await readFile(fullPath, 'utf-8');\n const lines = content.split('\\n');\n\n // Default to full file if no range specified\n const startLine = Math.max(1, request.startLine ?? 1);\n const maxEndLine = Math.min(lines.length, startLine + this.budget.maxLinesPerChunk - 1);\n const endLine = request.endLine\n ? Math.min(request.endLine, maxEndLine)\n : maxEndLine;\n\n const chunkLines = lines.slice(startLine - 1, endLine);\n\n chunks.push({\n file: request.file,\n startLine,\n endLine,\n content: chunkLines.join('\\n'),\n });\n } catch (error) {\n useLogger()?.debug(`[ToolExecutor] Error reading ${request.file}:`, { error });\n }\n }\n\n return {\n name: 'get_file_chunks',\n result: {\n chunks,\n budgetRemaining: {\n chunkCalls: this.budget.maxChunkCalls - this.budget.usage.chunkCalls,\n totalChunks: this.budget.maxTotalChunks - this.budget.usage.totalChunks,\n },\n },\n };\n }\n\n /**\n * Execute report_findings tool (just passes through)\n */\n private executeReportFindings(args: {\n findings: RawFinding[];\n summary?: string;\n }): ToolResult {\n return {\n name: 'report_findings',\n result: {\n findings: args.findings,\n summary: args.summary,\n accepted: true,\n },\n };\n }\n\n /**\n * Get fetched diffs (for verification)\n */\n getFetchedDiffs(): Map<string, FileDiff> {\n return this.fetchedDiffs;\n }\n\n /**\n * Get current budget usage\n */\n getBudgetUsage(): ToolBudget['usage'] {\n return { ...this.budget.usage };\n }\n\n /**\n * Check if a file was in the changed files list\n */\n isValidFile(file: string): boolean {\n return this.changedFiles.has(file);\n }\n}\n\n/**\n * Create a ToolExecutor instance\n */\nexport function createToolExecutor(\n cwd: string,\n changedFiles: string[],\n diffProvider: IDiffProvider,\n budget?: Partial<ToolBudget>\n): ToolExecutor {\n return new ToolExecutor(cwd, changedFiles, diffProvider, budget);\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/verification\n * Anti-hallucination verification for LLM findings.\n *\n * Validates LLM output against actual code to filter hallucinations.\n */\n\nimport type { FileDiff } from '@kb-labs/review-contracts';\nimport type { RawFinding, RawFindingSeverity } from './tool-executor.js';\nimport { readFile } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Verification check results\n */\nexport interface VerificationChecks {\n /** Is severity a valid enum value? */\n severityValid: boolean;\n /** Is category a valid enum value? */\n categoryValid: boolean;\n /** Is file in the changed files list? */\n fileExists: boolean;\n /** Is line number within file bounds? */\n lineInBounds: boolean;\n /** Is line actually in the diff (changed)? */\n lineInDiff: boolean;\n /** Fuzzy match score for code snippet (0.0-1.0) */\n snippetMatch: number;\n /** Does the issue make sense for this file type? */\n contextValid: boolean;\n /** Is ruleId valid (matches a project rule) or null? */\n ruleIdValid: boolean;\n}\n\n/**\n * Verified finding with score\n */\nexport interface VerifiedFinding {\n /** Original finding */\n finding: RawFinding;\n /** Verification score (0.0-1.0) */\n score: number;\n /** Individual check results */\n checks: VerificationChecks;\n /** Action taken based on score */\n action: 'keep' | 'downgrade' | 'discard';\n /** Adjusted severity (if downgraded) */\n adjustedSeverity?: string;\n /** Enum normalization info */\n enumNormalization?: {\n severityOriginal: string;\n severityNormalized: string;\n categoryOriginal: string;\n categoryNormalized: string;\n };\n}\n\n/**\n * Verification result summary\n */\nexport interface VerificationResult {\n /** Findings that passed verification */\n verified: VerifiedFinding[];\n /** Findings that were discarded */\n discarded: VerifiedFinding[];\n /** Statistics */\n stats: {\n total: number;\n kept: number;\n downgraded: number;\n discarded: number;\n hallucinationRate: number;\n };\n}\n\n/**\n * Valid severity values\n */\nconst VALID_SEVERITIES = ['blocker', 'high', 'medium', 'low', 'info'] as const;\ntype Severity = typeof VALID_SEVERITIES[number];\n\n/**\n * Severity aliases for normalization\n */\nconst SEVERITY_ALIASES: Record<string, Severity> = {\n critical: 'blocker',\n error: 'high',\n warning: 'medium',\n warn: 'medium',\n minor: 'low',\n trivial: 'info',\n suggestion: 'info',\n hint: 'info',\n};\n\n/**\n * Severity ordering for downgrade\n */\nconst SEVERITY_ORDER: Severity[] = ['blocker', 'high', 'medium', 'low', 'info'];\n\n/**\n * Verification thresholds\n */\nconst THRESHOLDS = {\n KEEP: 0.7,\n DOWNGRADE: 0.4,\n};\n\n/**\n * Score weights for each check.\n * Total = 1.0 (ruleIdValid is bonus that can push score above base)\n */\nconst SCORE_WEIGHTS = {\n severityValid: 0.075,\n categoryValid: 0.075,\n fileExists: 0.2,\n lineInBounds: 0.15,\n lineInDiff: 0.2,\n snippetMatch: 0.2,\n contextValid: 0.1,\n ruleIdValid: 0.05, // Bonus for using valid project rule ID\n};\n\n/**\n * VerificationEngine - validates LLM findings against actual code\n */\nexport class VerificationEngine {\n private cwd: string;\n private changedFiles: Set<string>;\n private fetchedDiffs: Map<string, FileDiff>;\n private validCategories: string[];\n private categoryAliases: Record<string, string>;\n private validRuleIds: Set<string>;\n private fileContents: Map<string, string> = new Map();\n\n constructor(\n cwd: string,\n changedFiles: string[],\n fetchedDiffs: Map<string, FileDiff>,\n validCategories: string[],\n categoryAliases: Record<string, string> = {},\n validRuleIds: Set<string> = new Set()\n ) {\n this.cwd = cwd;\n this.changedFiles = new Set(changedFiles);\n this.fetchedDiffs = fetchedDiffs;\n this.validCategories = validCategories;\n this.categoryAliases = categoryAliases;\n this.validRuleIds = validRuleIds;\n }\n\n /**\n * Verify all findings from LLM\n */\n async verify(findings: RawFinding[]): Promise<VerificationResult> {\n const verified: VerifiedFinding[] = [];\n const discarded: VerifiedFinding[] = [];\n\n let keptCount = 0;\n let downgradedCount = 0;\n\n for (const finding of findings) {\n // eslint-disable-next-line no-await-in-loop -- Sequential verification maintains order\n const result = await this.verifyFinding(finding);\n\n if (result.action === 'discard') {\n discarded.push(result);\n } else {\n verified.push(result);\n if (result.action === 'keep') {\n keptCount++;\n } else {\n downgradedCount++;\n }\n }\n }\n\n const total = findings.length;\n const hallucinationRate = total > 0 ? discarded.length / total : 0;\n\n return {\n verified,\n discarded,\n stats: {\n total,\n kept: keptCount,\n downgraded: downgradedCount,\n discarded: discarded.length,\n hallucinationRate,\n },\n };\n }\n\n /**\n * Verify a single finding\n */\n private async verifyFinding(finding: RawFinding): Promise<VerifiedFinding> {\n // Normalize enums first\n const severityNorm = this.normalizeSeverity(finding.severity);\n const categoryNorm = this.normalizeCategory(finding.category);\n\n // Validate ruleId\n const ruleIdValid = this.validateRuleId(finding.ruleId);\n\n // Run all checks\n const checks: VerificationChecks = {\n severityValid: severityNorm.valid,\n categoryValid: categoryNorm.valid,\n fileExists: this.changedFiles.has(finding.file),\n lineInBounds: await this.checkLineInBounds(finding.file, finding.line),\n lineInDiff: this.checkLineInDiff(finding.file, finding.line),\n snippetMatch: await this.matchSnippet(finding.file, finding.line, finding.codeSnippet),\n contextValid: this.checkContext(finding),\n ruleIdValid,\n };\n\n // Calculate score\n const score = this.calculateScore(checks);\n\n // Determine action\n let action: 'keep' | 'downgrade' | 'discard';\n let adjustedSeverity: RawFindingSeverity | undefined;\n\n if (score >= THRESHOLDS.KEEP) {\n action = 'keep';\n } else if (score >= THRESHOLDS.DOWNGRADE) {\n action = 'downgrade';\n adjustedSeverity = this.downgradeSeverity(severityNorm.normalized);\n } else {\n action = 'discard';\n }\n\n // Update finding with normalized values\n const normalizedFinding: RawFinding = {\n ...finding,\n severity: adjustedSeverity ?? severityNorm.normalized,\n category: categoryNorm.normalized,\n };\n\n return {\n finding: normalizedFinding,\n score,\n checks,\n action,\n adjustedSeverity,\n enumNormalization: {\n severityOriginal: finding.severity,\n severityNormalized: severityNorm.normalized,\n categoryOriginal: finding.category,\n categoryNormalized: categoryNorm.normalized,\n },\n };\n }\n\n /**\n * Normalize severity value to RawFindingSeverity type.\n */\n private normalizeSeverity(value: string): { valid: boolean; normalized: RawFindingSeverity } {\n const lower = value.toLowerCase().trim();\n\n // Direct match\n if (VALID_SEVERITIES.includes(lower as Severity)) {\n return { valid: true, normalized: lower as RawFindingSeverity };\n }\n\n // Alias match\n if (SEVERITY_ALIASES[lower]) {\n return { valid: true, normalized: SEVERITY_ALIASES[lower] };\n }\n\n // Invalid - default to medium\n return { valid: false, normalized: 'medium' };\n }\n\n /**\n * Normalize category value\n */\n private normalizeCategory(value: string): { valid: boolean; normalized: string } {\n const lower = value.toLowerCase().trim();\n\n // No categories configured - accept anything as valid (skip category validation)\n if (this.validCategories.length === 0) {\n return { valid: true, normalized: value };\n }\n\n // Direct match\n if (this.validCategories.includes(lower)) {\n return { valid: true, normalized: lower };\n }\n\n // Alias match\n if (this.categoryAliases[lower]) {\n return { valid: true, normalized: this.categoryAliases[lower] };\n }\n\n // Invalid - use first category as default\n return { valid: false, normalized: this.validCategories[0] ?? 'other' };\n }\n\n /**\n * Check if line is within file bounds\n */\n private async checkLineInBounds(file: string, line: number): Promise<boolean> {\n if (line < 1) {\n return false;\n }\n\n try {\n const content = await this.getFileContent(file);\n if (!content) {\n return false;\n }\n\n const lineCount = content.split('\\n').length;\n return line <= lineCount;\n } catch {\n return false;\n }\n }\n\n /**\n * Check if line is in the diff (actually changed)\n */\n private checkLineInDiff(file: string, line: number): boolean {\n const diff = this.fetchedDiffs.get(file);\n if (!diff) {\n return false;\n }\n\n return diff.changedLines.has(line);\n }\n\n /**\n * Match code snippet against actual file content\n */\n private async matchSnippet(\n file: string,\n targetLine: number,\n snippet?: string\n ): Promise<number> {\n // No snippet = neutral score\n if (!snippet) {\n return 0.5;\n }\n\n try {\n const content = await this.getFileContent(file);\n if (!content) {\n return 0;\n }\n\n const lines = content.split('\\n');\n const windowSize = 5;\n\n const start = Math.max(0, targetLine - windowSize - 1);\n const end = Math.min(lines.length, targetLine + windowSize);\n const window = lines.slice(start, end).join('\\n');\n\n // Strategy 1: Exact substring match\n if (window.includes(snippet)) {\n return 1.0;\n }\n\n // Strategy 2: Line-trimmed match\n const trimmedSnippet = snippet.split('\\n').map(l => l.trim()).join('\\n');\n const trimmedWindow = window.split('\\n').map(l => l.trim()).join('\\n');\n if (trimmedWindow.includes(trimmedSnippet)) {\n return 0.95;\n }\n\n // Strategy 3: Single-line normalized (for single-line snippets)\n if (!snippet.includes('\\n')) {\n const normalizedSnippet = this.normalizeCodeLine(snippet);\n for (const line of lines.slice(start, end)) {\n if (this.normalizeCodeLine(line).includes(normalizedSnippet)) {\n return 0.9;\n }\n }\n }\n\n // Strategy 4: Token-based partial match\n const snippetTokens = this.extractIdentifiers(snippet);\n const windowTokens = new Set(this.extractIdentifiers(window));\n const matchedTokens = snippetTokens.filter(t => windowTokens.has(t));\n\n const tokenScore = matchedTokens.length / Math.max(snippetTokens.length, 1);\n return tokenScore * 0.8;\n } catch {\n return 0;\n }\n }\n\n /**\n * Normalize a single line of code (preserves strings)\n */\n private normalizeCodeLine(line: string): string {\n const strings: string[] = [];\n let normalized = line.replace(\n /(['\"`])(?:(?!\\1)[^\\\\]|\\\\.)*\\1/g,\n (match) => {\n strings.push(match);\n return `__STR${strings.length - 1}__`;\n }\n );\n\n normalized = normalized.replace(/\\s+/g, ' ').trim();\n\n strings.forEach((str, i) => {\n normalized = normalized.replace(`__STR${i}__`, str);\n });\n\n return normalized;\n }\n\n /**\n * Extract identifiers from code\n */\n private extractIdentifiers(code: string): string[] {\n const matches = code.match(/[a-zA-Z_$][a-zA-Z0-9_$]*/g) || [];\n\n const keywords = new Set([\n 'const', 'let', 'var', 'function', 'class', 'if', 'else', 'for', 'while',\n 'return', 'import', 'export', 'from', 'async', 'await', 'try', 'catch',\n 'throw', 'new', 'this', 'true', 'false', 'null', 'undefined', 'typeof',\n ]);\n\n return matches.filter(m => !keywords.has(m) && m.length > 1);\n }\n\n /**\n * Validate ruleId - must be null or a valid rule ID from project rules\n */\n private validateRuleId(ruleId: string | null | undefined): boolean {\n // null is valid (ad-hoc finding)\n if (ruleId === null || ruleId === undefined) {\n return true;\n }\n\n // If no rules configured, accept any ruleId\n if (this.validRuleIds.size === 0) {\n return true;\n }\n\n // Check if ruleId matches a known rule\n return this.validRuleIds.has(ruleId);\n }\n\n /**\n * Check if finding makes sense for file context\n */\n private checkContext(finding: RawFinding): boolean {\n const fileLower = finding.file.toLowerCase();\n const messageLower = finding.message.toLowerCase();\n\n // SQL injection in non-DB file\n if (finding.category === 'security' &&\n messageLower.includes('sql') &&\n !fileLower.includes('db') &&\n !fileLower.includes('database') &&\n !fileLower.includes('query') &&\n !fileLower.includes('repository')) {\n return false;\n }\n\n // XSS in backend-only file\n if (messageLower.includes('xss') &&\n !fileLower.includes('component') &&\n !fileLower.includes('page') &&\n !fileLower.includes('.tsx') &&\n !fileLower.includes('.jsx')) {\n return false;\n }\n\n // Test file findings (usually less important)\n if (fileLower.includes('.test.') || fileLower.includes('.spec.')) {\n // Don't flag security issues in test files as context invalid\n // but they should be deprioritized elsewhere\n }\n\n return true;\n }\n\n /**\n * Calculate verification score\n */\n private calculateScore(checks: VerificationChecks): number {\n let score = 0;\n\n if (checks.severityValid) {\n score += SCORE_WEIGHTS.severityValid;\n }\n if (checks.categoryValid) {\n score += SCORE_WEIGHTS.categoryValid;\n }\n if (checks.fileExists) {\n score += SCORE_WEIGHTS.fileExists;\n }\n if (checks.lineInBounds) {\n score += SCORE_WEIGHTS.lineInBounds;\n }\n if (checks.lineInDiff) {\n score += SCORE_WEIGHTS.lineInDiff;\n }\n score += checks.snippetMatch * SCORE_WEIGHTS.snippetMatch;\n if (checks.contextValid) {\n score += SCORE_WEIGHTS.contextValid;\n }\n // Bonus for using valid project rule ID (increases confidence)\n if (checks.ruleIdValid) {\n score += SCORE_WEIGHTS.ruleIdValid;\n }\n\n return score;\n }\n\n /**\n * Downgrade severity by one level.\n * Returns the next lower severity or 'info' if already at lowest.\n */\n private downgradeSeverity(severity: RawFindingSeverity): RawFindingSeverity {\n const index = SEVERITY_ORDER.indexOf(severity);\n if (index === -1 || index >= SEVERITY_ORDER.length - 1) {\n return 'info';\n }\n return SEVERITY_ORDER[index + 1] ?? 'info';\n }\n\n /**\n * Get file content (with caching)\n */\n private async getFileContent(file: string): Promise<string | null> {\n if (this.fileContents.has(file)) {\n return this.fileContents.get(file)!;\n }\n\n try {\n const fullPath = path.join(this.cwd, file);\n const content = await readFile(fullPath, 'utf-8');\n this.fileContents.set(file, content);\n return content;\n } catch {\n return null;\n }\n }\n}\n\n/**\n * Create a VerificationEngine instance\n */\nexport function createVerificationEngine(\n cwd: string,\n changedFiles: string[],\n fetchedDiffs: Map<string, FileDiff>,\n validCategories: string[],\n categoryAliases?: Record<string, string>,\n validRuleIds?: Set<string>\n): VerificationEngine {\n return new VerificationEngine(cwd, changedFiles, fetchedDiffs, validCategories, categoryAliases, validRuleIds);\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/category-validator\n * Dynamic category discovery from rules directory.\n *\n * Categories are NOT hardcoded - they come from .kb/ai-review/rules/ subdirectories.\n */\n\nimport type { ReviewConfig } from '@kb-labs/review-contracts';\nimport { useConfig } from '@kb-labs/sdk';\nimport { readdir, access } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Common aliases for category names\n * Maps common LLM outputs to standard category names (if they exist)\n */\nconst COMMON_CATEGORY_MAPPINGS: Record<string, string[]> = {\n security: ['sec', 'vulnerability', 'vulnerabilities', 'injection', 'auth', 'authentication', 'authorization'],\n performance: ['perf', 'speed', 'memory', 'optimization', 'optimisation'],\n architecture: ['design', 'structure', 'pattern', 'patterns', 'arch'],\n naming: ['names', 'conventions', 'identifiers', 'naming-convention'],\n consistency: ['style', 'formatting', 'code-style', 'codestyle'],\n testing: ['test', 'tests', 'coverage', 'unit-test', 'unittest'],\n correctness: ['bug', 'bugs', 'logic', 'error', 'errors', 'mistake'],\n maintainability: ['readability', 'complexity', 'code-quality', 'quality'],\n};\n\n/**\n * CategoryValidator - discovers and validates categories dynamically\n *\n * Categories come from .kb/ai-review/rules/ subdirectories.\n * No hardcoded categories - fully configurable per project.\n */\nexport class CategoryValidator {\n private validCategories: string[] = [];\n private categoryAliases: Record<string, string> = {};\n private defaultCategory: string = 'other';\n private initialized: boolean = false;\n\n /**\n * Initialize validator - discovers categories from config-defined rules directory\n *\n * @param cwd - Project root directory (ctx.cwd from command handler)\n */\n async init(cwd: string): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n this.validCategories = await discoverCategories(cwd);\n\n if (this.validCategories.length === 0) {\n // No categories found, will accept any category\n this.initialized = true;\n return;\n }\n\n this.categoryAliases = buildCategoryAliases(this.validCategories);\n this.defaultCategory = this.validCategories[0] ?? 'general';\n this.initialized = true;\n }\n\n /**\n * Validate and normalize a category value\n */\n validate(category: string): { valid: boolean; normalized: string } {\n if (this.validCategories.length === 0) {\n // No validation possible - accept but mark as unvalidated\n return { valid: false, normalized: category };\n }\n\n const lower = category.toLowerCase().trim();\n\n // Direct match\n if (this.validCategories.includes(lower)) {\n return { valid: true, normalized: lower };\n }\n\n // Alias match\n if (this.categoryAliases[lower]) {\n return { valid: true, normalized: this.categoryAliases[lower] };\n }\n\n // Invalid - use default\n return { valid: false, normalized: this.defaultCategory };\n }\n\n /**\n * Get list of valid categories\n */\n getValidCategories(): string[] {\n return [...this.validCategories];\n }\n\n /**\n * Get category aliases map\n */\n getCategoryAliases(): Record<string, string> {\n return { ...this.categoryAliases };\n }\n\n /**\n * Check if validator has been initialized\n */\n isInitialized(): boolean {\n return this.initialized;\n }\n}\n\n/**\n * Discover valid categories from rules directory\n *\n * Reads subdirectories of .kb/ai-review/rules/ (or config-defined path).\n * Each subdirectory name becomes a valid category.\n *\n * @example\n * .kb/ai-review/rules/\n * ├── security/ → \"security\"\n * ├── naming/ → \"naming\"\n * ├── architecture/ → \"architecture\"\n * └── .hidden/ → (ignored)\n */\nexport async function discoverCategories(cwd: string): Promise<string[]> {\n try {\n // Use SDK's useConfig to get review config from kb.config.json\n const config = await useConfig<ReviewConfig>();\n\n // Get rulesDir from config (with fallback)\n const rulesDir = config?.rulesDir ?? 'ai-review/rules';\n const kbDir = path.join(cwd, '.kb');\n const fullPath = path.join(kbDir, rulesDir);\n\n // Check if rules directory exists\n try {\n await access(fullPath);\n } catch {\n // Rules directory not found\n return [];\n }\n\n // Read subdirectories\n const entries = await readdir(fullPath, { withFileTypes: true });\n return entries\n .filter(e => e.isDirectory() && !e.name.startsWith('.'))\n .map(e => e.name.toLowerCase());\n } catch {\n // Error discovering categories\n return [];\n }\n}\n\n/**\n * Build category aliases from discovered categories\n *\n * Maps common LLM outputs to actual category names (if they exist in the project).\n */\nexport function buildCategoryAliases(validCategories: string[]): Record<string, string> {\n const aliases: Record<string, string> = {};\n const categorySet = new Set(validCategories);\n\n for (const category of validCategories) {\n // Add the category itself (for case normalization)\n aliases[category] = category;\n\n // Add common aliases if this category exists\n const mappings = COMMON_CATEGORY_MAPPINGS[category];\n if (mappings) {\n for (const alias of mappings) {\n // Only add alias if it doesn't conflict with another category\n if (!categorySet.has(alias)) {\n aliases[alias] = category;\n }\n }\n }\n }\n\n return aliases;\n}\n\n/**\n * Create a CategoryValidator instance\n */\nexport function createCategoryValidator(): CategoryValidator {\n return new CategoryValidator();\n}\n\n// Singleton instance for convenience\nlet globalValidator: CategoryValidator | null = null;\n\n/**\n * Get or create the global CategoryValidator instance\n */\nexport async function getCategoryValidator(cwd: string): Promise<CategoryValidator> {\n if (!globalValidator) {\n globalValidator = new CategoryValidator();\n }\n\n if (!globalValidator.isInitialized()) {\n await globalValidator.init(cwd);\n }\n\n return globalValidator;\n}\n\n/**\n * Reset the global validator (for testing)\n */\nexport function resetCategoryValidator(): void {\n globalValidator = null;\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/prompt-loader\n * Load prompts and rules from .kb/ai-review/ directory.\n *\n * Reads markdown files and builds context for LLM prompts.\n */\n\nimport type { ReviewConfig } from '@kb-labs/review-contracts';\nimport { useConfig } from '@kb-labs/sdk';\nimport { readdir, readFile, access } from 'node:fs/promises';\nimport * as path from 'node:path';\n\n/**\n * Rule frontmatter metadata\n */\nexport interface RuleFrontmatter {\n /** Unique rule ID (e.g., \"security/no-eval\") */\n id: string;\n /** Default severity for this rule */\n severity?: 'blocker' | 'high' | 'medium' | 'low' | 'info';\n /** Rule type: 'positive' (report these issues) or 'negative' (do NOT report these) */\n type?: 'positive' | 'negative';\n}\n\n/**\n * Loaded rule content\n */\nexport interface RuleContent {\n /** Rule category (directory name) */\n category: string;\n /** Rule name (filename without extension) */\n name: string;\n /** Rule content (markdown without frontmatter) */\n content: string;\n /** Rule ID from frontmatter (e.g., \"security/no-eval\") */\n id?: string;\n /** Default severity from frontmatter */\n severity?: 'blocker' | 'high' | 'medium' | 'low' | 'info';\n /** Rule type: 'positive' (report these) or 'negative' (do NOT report these) */\n type?: 'positive' | 'negative';\n}\n\n/**\n * Loaded prompts\n */\nexport interface LoadedPrompts {\n /** System prompt (from prompts/system.md or default) */\n system: string;\n /** Task prompt (from prompts/task.md or default) */\n task: string;\n /** Rules content by category */\n rules: Record<string, RuleContent[]>;\n /** All rules as formatted string for prompt */\n rulesContext: string;\n /** Set of valid rule IDs for validation */\n ruleIds: Set<string>;\n}\n\n/**\n * Default system prompt (fallback if no file exists)\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are a security-focused code auditor. Your job is to find every real vulnerability and bug in the code — think like an attacker reading this before exploiting it.\n\n## Process\n\n1. Fetch diffs for ALL files using get_diffs() before drawing any conclusions\n2. Read every file thoroughly — don't stop at the first finding\n3. After analyzing all files, report ALL findings in a single report_findings() call\n\n## What to Look For\n\nHunt for anything that could be exploited or cause harm in production:\n- Injection vectors: SQL, shell, template, path traversal, SSRF\n- Secrets and credentials hardcoded anywhere in the code\n- Broken authentication or authorization logic\n- Unsafe cryptography (weak algorithms, insecure randomness, plaintext storage)\n- Unvalidated input flowing into dangerous sinks\n- Logic errors that change program behavior in unexpected ways\n- Resource leaks and error paths that expose internals\n\n## Rules\n\n- Report every distinct issue you find — don't summarize multiple bugs into one\n- Each finding needs a line number and a code snippet from the diff\n- Skip style, formatting, and hypothetical \"could be better\" suggestions\n- Language doesn't matter: Python, PHP, JS, Go, Ruby — audit everything the same way\n\n## Severity\n\n### blocker\nDirectly exploitable: injection, RCE, auth bypass, exposed secrets, data exfiltration\n\n### high\nReal bug with production impact: broken logic, data corruption, significant information leak\n\n### medium\nPotential issue requiring specific conditions: missing validation, unsafe default, weak crypto choice\n\n### low\nMinor risk: informational leak in errors, missing rate limit, suboptimal but not dangerous`;\n\n/**\n * Default task prompt (fallback if no file exists)\n */\nconst DEFAULT_TASK_PROMPT = `## Your Task\n\nYou have a list of changed files. Do the following in order:\n\n1. Call get_diffs() for ALL files at once — fetch everything before analyzing anything\n2. Read every diff carefully and list every vulnerability or bug you spot\n3. Do NOT call report_findings() until you have gone through every single file\n4. Call report_findings() once with the complete list of everything you found\n\nDon't triage or prioritize — report every real issue, from hardcoded passwords to SQL injections to broken logic. A complete report is better than a conservative one.`;\n\n/**\n * Load all prompts and rules from .kb/ai-review/\n */\nexport async function loadPrompts(cwd: string): Promise<LoadedPrompts> {\n const config = await useConfig<ReviewConfig>('review');\n\n const kbDir = path.join(cwd, '.kb');\n const rulesDir = path.join(kbDir, config?.rulesDir ?? 'ai-review/rules');\n const promptsDir = path.join(kbDir, config?.promptsDir ?? 'ai-review/prompts');\n\n // Load system and task prompts\n const system = await loadPromptFile(promptsDir, 'system.md', DEFAULT_SYSTEM_PROMPT);\n const task = await loadPromptFile(promptsDir, 'task.md', DEFAULT_TASK_PROMPT);\n\n // Load rules by category\n const rules = await loadRules(rulesDir);\n\n // Collect all rule IDs for validation\n const ruleIds = new Set<string>();\n for (const categoryRules of Object.values(rules)) {\n for (const rule of categoryRules) {\n if (rule.id) {\n ruleIds.add(rule.id);\n }\n }\n }\n\n // Format rules as context string\n const rulesContext = formatRulesContext(rules);\n\n return { system, task, rules, rulesContext, ruleIds };\n}\n\n/**\n * Load a single prompt file with fallback\n */\nasync function loadPromptFile(dir: string, filename: string, fallback: string): Promise<string> {\n try {\n const filePath = path.join(dir, filename);\n await access(filePath);\n const content = await readFile(filePath, 'utf-8');\n return content.trim();\n } catch {\n return fallback;\n }\n}\n\n/**\n * Load all rules from rules directory\n */\nasync function loadRules(rulesDir: string): Promise<Record<string, RuleContent[]>> {\n const rules: Record<string, RuleContent[]> = {};\n\n try {\n await access(rulesDir);\n } catch {\n return rules;\n }\n\n // Read category directories\n const entries = await readdir(rulesDir, { withFileTypes: true });\n const categories = entries.filter(e => e.isDirectory() && !e.name.startsWith('.'));\n\n for (const categoryDir of categories) {\n const category = categoryDir.name;\n\n // Path traversal protection: skip names with path separators or '..'\n if (category.includes('..') || category.includes(path.sep) || category.includes('/')) {\n continue;\n }\n\n const categoryPath = path.join(rulesDir, category);\n\n // Read rule files in category\n // eslint-disable-next-line no-await-in-loop -- Sequential directory reading\n const ruleFiles = await readdir(categoryPath, { withFileTypes: true });\n const mdFiles = ruleFiles.filter(f => f.isFile() && f.name.endsWith('.md'));\n\n rules[category] = [];\n\n for (const ruleFile of mdFiles) {\n // Path traversal protection: skip names with path separators or '..'\n if (ruleFile.name.includes('..') || ruleFile.name.includes(path.sep) || ruleFile.name.includes('/')) {\n continue;\n }\n\n const ruleName = ruleFile.name.replace('.md', '');\n const rulePath = path.join(categoryPath, ruleFile.name);\n\n try {\n // eslint-disable-next-line no-await-in-loop -- Sequential file reading for rule loading\n const rawContent = await readFile(rulePath, 'utf-8');\n const { frontmatter, body } = parseFrontmatter(rawContent);\n\n rules[category].push({\n category,\n name: ruleName,\n content: body.trim(),\n id: frontmatter?.id,\n severity: frontmatter?.severity,\n type: frontmatter?.type ?? 'positive', // Default to positive rule\n });\n } catch {\n // Skip unreadable files\n }\n }\n }\n\n return rules;\n}\n\n/**\n * Format rules as context string for prompt\n */\n// eslint-disable-next-line sonarjs/cognitive-complexity -- Complex multi-level categorization and formatting of rules into structured prompt sections\nfunction formatRulesContext(rules: Record<string, RuleContent[]>): string {\n const positiveSections: string[] = [];\n const negativeSections: string[] = [];\n\n for (const [category, categoryRules] of Object.entries(rules)) {\n if (categoryRules.length === 0) {\n continue;\n }\n\n // Separate positive and negative rules\n const positiveRules = categoryRules.filter(r => r.type !== 'negative');\n const negativeRules = categoryRules.filter(r => r.type === 'negative');\n\n // Format positive rules (issues to report)\n if (positiveRules.length > 0) {\n positiveSections.push(`## ${capitalize(category)} Rules\\n`);\n for (const rule of positiveRules) {\n if (rule.id) {\n positiveSections.push(`### Rule: ${rule.id}\\n`);\n }\n positiveSections.push(rule.content);\n positiveSections.push('');\n }\n }\n\n // Format negative rules (patterns NOT to report)\n if (negativeRules.length > 0) {\n for (const rule of negativeRules) {\n if (rule.id) {\n negativeSections.push(`### ${rule.id}\\n`);\n }\n negativeSections.push(rule.content);\n negativeSections.push('');\n }\n }\n }\n\n if (positiveSections.length === 0 && negativeSections.length === 0) {\n return '';\n }\n\n // Collect positive rule IDs for the explicit list\n const allRuleIds: string[] = [];\n for (const categoryRules of Object.values(rules)) {\n for (const rule of categoryRules) {\n if (rule.id && rule.type !== 'negative') {\n allRuleIds.push(rule.id);\n }\n }\n }\n\n const ruleIdList = allRuleIds.length > 0\n ? `\\n\\n**Available Rule IDs:** ${allRuleIds.join(', ')}`\n : '';\n\n // Build false positive prevention section\n const falsePositiveSection = negativeSections.length > 0\n ? `\\n\\n## FALSE POSITIVE PREVENTION (Do NOT Report These)\\n\\n**CRITICAL:** Before reporting any issue, check if it matches a pattern below. If it does, DO NOT REPORT IT.\\n\\n${negativeSections.join('\\n')}`\n : '';\n\n return `# Project-Specific Rules (MANDATORY)\n\n## CRITICAL: You MUST Use Rule IDs\n\nWhen reporting findings, you MUST check if the issue matches one of these project rules and use the exact ruleId:\n${ruleIdList}\n\n### How to Report:\n\n1. **If issue matches a rule** → Use the EXACT ruleId from the list above\n Example: \\`\"ruleId\": \"security/path-traversal\"\\` or \\`\"ruleId\": \"consistency/validation-logic\"\\`\n\n2. **If issue does NOT match any rule** → Use \\`\"ruleId\": null\\`\n\n### Examples:\n\n- Path traversal issue → \\`\"ruleId\": \"security/path-traversal\"\\`\n- Input validation issue → \\`\"ruleId\": \"security/input-validation\"\\`\n- Inconsistent validation logic → \\`\"ruleId\": \"consistency/validation-logic\"\\`\n- Dead code → \\`\"ruleId\": \"architecture/dead-code-paths\"\\`\n- Some other issue not in rules → \\`\"ruleId\": null\\`\n\n## Project Rules\n\n${positiveSections.join('\\n')}${falsePositiveSection}`;\n}\n\n/**\n * Capitalize first letter\n */\nfunction capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n/**\n * Parse YAML frontmatter from markdown content\n *\n * Frontmatter format:\n * ---\n * id: category/rule-name\n * severity: medium\n * ---\n */\nfunction parseFrontmatter(content: string): { frontmatter: RuleFrontmatter | null; body: string } {\n const frontmatterRegex = /^---\\n([\\s\\S]*?)\\n---\\n*/;\n const match = content.match(frontmatterRegex);\n\n if (!match) {\n return { frontmatter: null, body: content };\n }\n\n const yamlContent = match[1] ?? '';\n const body = content.slice(match[0].length);\n\n // Simple YAML parsing (id and severity only)\n const frontmatter: Partial<RuleFrontmatter> = {};\n\n for (const line of yamlContent.split('\\n')) {\n const colonIndex = line.indexOf(':');\n if (colonIndex === -1) {\n continue;\n }\n\n const key = line.slice(0, colonIndex).trim();\n const value = line.slice(colonIndex + 1).trim();\n\n if (key === 'id') {\n frontmatter.id = value;\n } else if (key === 'severity') {\n const validSeverities = ['blocker', 'high', 'medium', 'low', 'info'];\n if (validSeverities.includes(value)) {\n frontmatter.severity = value as RuleFrontmatter['severity'];\n }\n } else if (key === 'type' && (value === 'positive' || value === 'negative')) {\n frontmatter.type = value;\n }\n }\n\n if (!frontmatter.id) {\n return { frontmatter: null, body: content };\n }\n\n return { frontmatter: frontmatter as RuleFrontmatter, body };\n}\n","/**\n * @module @kb-labs/review-llm/llm-lite/llm-lite-analyzer\n * LLM-Lite analyzer for efficient code review.\n *\n * Uses batch tools, diff-based context, and anti-hallucination verification.\n */\n\nimport type { ReviewFinding, InputFile, IDiffProvider, ReviewConfig } from '@kb-labs/review-contracts';\nimport { useLLM, useAnalytics, useConfig } from '@kb-labs/sdk';\nimport {\n createToolExecutor,\n buildToolDefinitions,\n type RawFinding,\n type ToolCall,\n} from './tool-executor.js';\nimport { createVerificationEngine, type VerificationResult } from './verification.js';\nimport { getCategoryValidator } from './category-validator.js';\nimport { loadPrompts, type LoadedPrompts } from './prompt-loader.js';\n\n/**\n * Review LLM config from kb.config.json\n */\ntype ReviewLLMConfig = NonNullable<ReviewConfig['llm']>;\n\n/**\n * LLM-Lite review request\n */\nexport interface LLMLiteRequest {\n /** Working directory */\n cwd: string;\n /** Changed files with content */\n files: InputFile[];\n /** Task context (what the changes are trying to achieve) */\n taskContext?: string;\n /** Repository scope */\n repoScope?: string[];\n /** Diff provider (injected from review-core to avoid circular dependency) */\n diffProvider: IDiffProvider;\n}\n\n/**\n * LLM-Lite review result\n */\nexport interface LLMLiteResult {\n /** Verified findings */\n findings: ReviewFinding[];\n /** Metadata */\n metadata: {\n /** LLM calls made */\n llmCalls: number;\n /** Tool calls made */\n toolCalls: {\n get_diffs: number;\n get_file_chunks: number;\n report_findings: number;\n };\n /** Token usage */\n tokens: {\n input: number;\n output: number;\n total: number;\n };\n /** Estimated cost in USD */\n estimatedCost: number;\n /** Verification stats */\n verification: {\n rawFindings: number;\n verified: number;\n downgraded: number;\n discarded: number;\n hallucinationRate: number;\n };\n /** Timing */\n timing: {\n totalMs: number;\n llmMs: number;\n verifyMs: number;\n };\n };\n}\n\n/**\n * File summary for initial prompt\n */\ninterface FileSummary {\n path: string;\n additions: number;\n deletions: number;\n isNewFile: boolean;\n}\n\n/**\n * Default turn limits (can be overridden via kb.config.json)\n */\nconst DEFAULT_MIN_TURNS = 3;\nconst DEFAULT_MAX_TURNS = 25;\nconst DEFAULT_FILES_PER_TURN = 10;\nconst DEFAULT_LINES_PER_TURN = 500;\n\n/**\n * Calculate adaptive turn limit based on workload\n *\n * Formula:\n * - Base: minTurns (get_diffs + analyze + report)\n * - +1 turn per filesPerTurn files (more files = more get_diffs calls needed)\n * - +1 turn per linesPerTurn lines changed (more changes = more context needed)\n * - Capped at maxTurns (cost control)\n *\n * All parameters configurable via kb.config.json review.llm section\n */\nfunction calculateMaxTurns(\n fileCount: number,\n totalChangedLines: number,\n config?: ReviewLLMConfig\n): number {\n const minTurns = config?.minTurns ?? DEFAULT_MIN_TURNS;\n const maxTurns = config?.maxTurns ?? DEFAULT_MAX_TURNS;\n const filesPerTurn = config?.filesPerTurn ?? DEFAULT_FILES_PER_TURN;\n const linesPerTurn = config?.linesPerTurn ?? DEFAULT_LINES_PER_TURN;\n\n const baseTurns = minTurns;\n const turnsForFiles = Math.ceil(fileCount / filesPerTurn);\n const turnsForLines = Math.ceil(totalChangedLines / linesPerTurn);\n return Math.min(maxTurns, baseTurns + turnsForFiles + turnsForLines);\n}\n\n/**\n * Token costs (GPT-4 pricing approximation)\n */\nconst TOKEN_COSTS = {\n input: 0.00003, // $0.03 per 1K input tokens\n output: 0.00006, // $0.06 per 1K output tokens\n};\n\n/**\n * LLM-Lite Analyzer\n *\n * Efficient code review using:\n * - Batch tools (get_diffs, get_file_chunks, report_findings)\n * - Diff-based context (not full files)\n * - Anti-hallucination verification\n * - Dynamic categories from rules directory\n */\nexport class LLMLiteAnalyzer {\n private cwd: string;\n private files: InputFile[];\n private taskContext?: string;\n private repoScope?: string[];\n private diffProvider: IDiffProvider;\n\n constructor(request: LLMLiteRequest) {\n this.cwd = request.cwd;\n this.files = request.files;\n this.taskContext = request.taskContext;\n this.repoScope = request.repoScope;\n this.diffProvider = request.diffProvider;\n }\n\n /**\n * Run LLM-Lite analysis\n */\n // eslint-disable-next-line sonarjs/cognitive-complexity -- Complex multi-phase LLM analysis workflow with prompt loading, validation, and result processing\n async analyze(): Promise<LLMLiteResult> {\n const startTime = Date.now();\n const analytics = useAnalytics();\n\n // Track start\n analytics?.track('review:llm-lite:started', {\n fileCount: this.files.length,\n hasTaskContext: !!this.taskContext,\n });\n\n // Initialize\n const llm = useLLM({ tier: 'medium' });\n if (!llm) {\n throw new Error('LLM not available for llm-lite mode');\n }\n\n // Get review config from kb.config.json\n const reviewConfig = await useConfig<ReviewConfig>('review');\n const llmConfig = reviewConfig?.llm;\n\n // Load prompts and rules from .kb/ai-review/\n const prompts = await loadPrompts(this.cwd);\n\n // Get category validator\n const categoryValidator = await getCategoryValidator(this.cwd);\n const validCategories = categoryValidator.getValidCategories();\n const categoryAliases = categoryValidator.getCategoryAliases();\n\n // Build file summaries for initial prompt\n const fileSummaries = this.buildFileSummaries();\n\n // Calculate adaptive turn limit based on workload and config\n const totalChangedLines = fileSummaries.reduce(\n (sum, f) => sum + f.additions + f.deletions,\n 0\n );\n const maxTurns = calculateMaxTurns(this.files.length, totalChangedLines, llmConfig);\n\n // Create tool executor\n const changedFiles = this.files.map(f => f.path);\n const toolExecutor = createToolExecutor(this.cwd, changedFiles, this.diffProvider);\n\n // Build tools with dynamic categories and rule IDs\n const validRuleIds = Array.from(prompts.ruleIds);\n const tools = buildToolDefinitions(validCategories, validRuleIds);\n\n // Build prompts with loaded rules\n const systemPrompt = this.buildSystemPrompt(validCategories, prompts);\n const initialPrompt = this.buildInitialPrompt(fileSummaries, prompts);\n\n // Conversation loop\n // Messages array uses 'user' for initial prompt and tool results, 'assistant' for LLM responses.\n // Tool results are sent as 'user' messages to avoid Anthropic tool_use/tool_result format issues.\n const messages: Array<{ role: 'user' | 'assistant'; content: string }> = [\n { role: 'user', content: initialPrompt },\n ];\n\n let llmCalls = 0;\n let totalInputTokens = 0;\n let totalOutputTokens = 0;\n let llmTimeMs = 0;\n let rawFindings: RawFinding[] = [];\n\n const toolCallCounts = {\n get_diffs: 0,\n get_file_chunks: 0,\n report_findings: 0,\n };\n\n // Tool calling loop (adaptive based on workload)\n for (let turn = 0; turn < maxTurns; turn++) {\n const llmStart = Date.now();\n const isLastTurn = turn === maxTurns - 1;\n\n // On last turn, only offer report_findings to force conclusion\n const availableTools = isLastTurn\n ? tools.filter(t => t.name === 'report_findings')\n : tools;\n\n // Call LLM with tools\n // eslint-disable-next-line no-await-in-loop -- Conversation loop requires sequential turns\n const response = await llm.chatWithTools!(\n [\n { role: 'system', content: systemPrompt },\n ...messages,\n ],\n {\n tools: availableTools.map(t => ({\n name: t.name,\n description: t.description,\n inputSchema: t.parameters,\n })),\n }\n );\n\n llmCalls++;\n llmTimeMs += Date.now() - llmStart;\n\n // Track token usage (if available)\n // Note: Some adapters may not provide usage data, cost estimation will be incomplete\n if (response.usage) {\n totalInputTokens += response.usage.promptTokens ?? 0;\n totalOutputTokens += response.usage.completionTokens ?? 0;\n }\n\n // Check for tool calls\n const toolCalls = response.toolCalls ?? [];\n\n if (toolCalls.length === 0) {\n // No more tool calls - done\n break;\n }\n\n // Add assistant message only if there's actual content\n // Skip empty content even with tool calls - VibeProxy requires non-empty content\n const assistantContent = response.content ?? '';\n if (assistantContent.trim()) {\n messages.push({\n role: 'assistant',\n content: assistantContent,\n });\n }\n\n // Execute tool calls\n for (const toolCall of toolCalls) {\n const parsed: ToolCall = {\n name: toolCall.name,\n arguments: toolCall.input as Record<string, unknown>,\n };\n\n // Track tool call count\n if (parsed.name in toolCallCounts) {\n toolCallCounts[parsed.name as keyof typeof toolCallCounts]++;\n }\n\n // Execute\n // eslint-disable-next-line no-await-in-loop -- Sequential tool execution for conversation flow\n const result = await toolExecutor.execute(parsed);\n\n // Add tool result to messages\n // Using 'user' role with formatted text to avoid Anthropic tool_use/tool_result format issues\n // This is the same approach used by agent-executor\n messages.push({\n role: 'user',\n content: `Tool result (${parsed.name}):\\n${JSON.stringify(result.result, null, 2)}`,\n });\n\n // Check for report_findings (end condition)\n if (parsed.name === 'report_findings' && result.result) {\n const reportResult = result.result as { findings?: RawFinding[] };\n if (reportResult.findings) {\n rawFindings = reportResult.findings;\n }\n }\n }\n\n // If report_findings was called, we're done (regardless of findings count)\n if (toolCallCounts.report_findings > 0) {\n break;\n }\n }\n\n // Verification phase\n const verifyStart = Date.now();\n\n const verificationEngine = createVerificationEngine(\n this.cwd,\n changedFiles,\n toolExecutor.getFetchedDiffs(),\n validCategories,\n categoryAliases,\n prompts.ruleIds\n );\n\n const verificationResult = await verificationEngine.verify(rawFindings);\n const verifyTimeMs = Date.now() - verifyStart;\n\n // Convert to ReviewFinding format\n const findings = this.convertToReviewFindings(verificationResult);\n\n // Calculate cost\n const estimatedCost =\n (totalInputTokens * TOKEN_COSTS.input) +\n (totalOutputTokens * TOKEN_COSTS.output);\n\n // Track completion\n analytics?.track('review:llm-lite:completed', {\n fileCount: this.files.length,\n findingsCount: findings.length,\n llmCalls,\n hallucinationRate: verificationResult.stats.hallucinationRate,\n estimatedCost,\n });\n\n return {\n findings,\n metadata: {\n llmCalls,\n toolCalls: toolCallCounts,\n tokens: {\n input: totalInputTokens,\n output: totalOutputTokens,\n total: totalInputTokens + totalOutputTokens,\n },\n estimatedCost,\n verification: {\n rawFindings: verificationResult.stats.total,\n verified: verificationResult.verified.length,\n downgraded: verificationResult.stats.downgraded,\n discarded: verificationResult.stats.discarded,\n hallucinationRate: verificationResult.stats.hallucinationRate,\n },\n timing: {\n totalMs: Date.now() - startTime,\n llmMs: llmTimeMs,\n verifyMs: verifyTimeMs,\n },\n },\n };\n }\n\n /**\n * Build file summaries for initial prompt\n */\n private buildFileSummaries(): FileSummary[] {\n return this.files.map(f => {\n const lines = f.content.split('\\n');\n return {\n path: f.path,\n additions: lines.length,\n deletions: 0,\n isNewFile: f.isNewFile ?? false,\n };\n });\n }\n\n /**\n * Build system prompt from loaded prompts and rules\n */\n private buildSystemPrompt(validCategories: string[], prompts: LoadedPrompts): string {\n const categoryList = validCategories.length > 0\n ? `\\n\\n## Valid Categories\\n\\nYou MUST use only these categories:\\n${validCategories.map(c => `- ${c}`).join('\\n')}`\n : '';\n\n // Combine: system prompt + rules context + categories\n let fullPrompt = prompts.system;\n\n // Add project-specific rules if any\n if (prompts.rulesContext) {\n fullPrompt += `\\n\\n${prompts.rulesContext}`;\n }\n\n // Add valid categories\n fullPrompt += categoryList;\n\n return fullPrompt;\n }\n\n /**\n * Build initial prompt with file list and task context\n */\n private buildInitialPrompt(files: FileSummary[], prompts: LoadedPrompts): string {\n const fileList = files.map(f => {\n const stats = `+${f.additions}/-${f.deletions}`;\n const status = f.isNewFile ? 'new file' : 'modified';\n return `- ${f.path} (${stats}, ${status})`;\n }).join('\\n');\n\n let prompt = `## Files Changed (${files.length} files)\n\n${fileList}`;\n\n if (this.taskContext) {\n prompt += `\\n\\n## Task Context\\n${this.taskContext}`;\n }\n\n if (this.repoScope?.length) {\n prompt += `\\n\\n## Repository Scope\\n${this.repoScope.join(', ')}`;\n }\n\n // Add task prompt from loaded prompts\n prompt += `\\n\\n${prompts.task}`;\n\n return prompt;\n }\n\n /**\n * Convert verified findings to ReviewFinding format\n */\n private convertToReviewFindings(result: VerificationResult): ReviewFinding[] {\n return result.verified.map(v => {\n // Map verification action to confidence level\n const confidence = v.action === 'keep' ? 'certain' as const\n : v.action === 'downgrade' ? 'likely' as const\n : 'heuristic' as const;\n\n // Determine ruleId: use LLM-provided ruleId if valid, otherwise generate from category\n // ruleId from LLM means it matched a project rule (e.g., \"security/no-eval\")\n // null/undefined means ad-hoc finding (LLM found it without matching a rule)\n let projectRuleId = v.finding.ruleId;\n\n // LLM sometimes includes \"rule:\" prefix - strip it if present\n if (projectRuleId?.startsWith('rule:')) {\n projectRuleId = projectRuleId.slice(5);\n }\n\n const ruleId = projectRuleId\n ? `rule:${projectRuleId}` // Matched project rule\n : `llm-lite:${v.finding.category}`; // Ad-hoc LLM finding\n\n // Source indicates whether finding came from a project rule or LLM's own analysis\n const source = projectRuleId ? 'rule' : 'llm';\n\n return {\n id: `llm-lite-${v.finding.file}-${v.finding.line}`,\n ruleId,\n file: v.finding.file,\n line: v.finding.line,\n endLine: v.finding.endLine,\n column: 1,\n message: v.finding.message,\n severity: v.finding.severity as 'blocker' | 'high' | 'medium' | 'low' | 'info',\n confidence,\n type: v.finding.category,\n engine: 'llm-lite',\n source,\n suggestion: v.finding.suggestion,\n snippet: v.finding.codeSnippet,\n };\n });\n }\n}\n\n/**\n * Run LLM-Lite analysis\n */\nexport async function runLLMLiteAnalysis(request: LLMLiteRequest): Promise<LLMLiteResult> {\n const analyzer = new LLMLiteAnalyzer(request);\n return analyzer.analyze();\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kb-labs/review-llm",
|
|
3
3
|
"description": "LLM-based analysis for KB Labs AI Review",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.67.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"LICENSE"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@kb-labs/
|
|
33
|
-
"@kb-labs/
|
|
32
|
+
"@kb-labs/sdk": "2.21.2",
|
|
33
|
+
"@kb-labs/review-contracts": "2.67.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@types/node": "^24.3.3",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"tsup": "^8.5.0",
|
|
39
39
|
"typescript": "^5.6.3",
|
|
40
40
|
"vitest": "^3.2.4",
|
|
41
|
-
"@kb-labs/devkit": "2.
|
|
41
|
+
"@kb-labs/devkit": "2.67.0"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=20.0.0",
|