@probelabs/visor 0.1.94 → 0.1.95

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.
Files changed (41) hide show
  1. package/README.md +4 -4
  2. package/defaults/.visor.yaml +86 -6
  3. package/dist/ai-review-service.d.ts +1 -1
  4. package/dist/ai-review-service.d.ts.map +1 -1
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/commands.d.ts.map +1 -1
  8. package/dist/config.d.ts +6 -1
  9. package/dist/config.d.ts.map +1 -1
  10. package/dist/defaults/.visor.yaml +86 -6
  11. package/dist/failure-condition-evaluator.d.ts.map +1 -1
  12. package/dist/footer.d.ts +25 -0
  13. package/dist/footer.d.ts.map +1 -0
  14. package/dist/github-check-service.d.ts.map +1 -1
  15. package/dist/github-comments.d.ts.map +1 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +926 -476
  18. package/dist/output/code-review/schema.json +0 -23
  19. package/dist/reviewer.d.ts +5 -2
  20. package/dist/reviewer.d.ts.map +1 -1
  21. package/dist/sdk/{check-execution-engine-YBRPVUWD.mjs → check-execution-engine-NMPXJ7FQ.mjs} +2 -2
  22. package/dist/sdk/{chunk-DQRFOQAP.mjs → chunk-Q4S5A5TO.mjs} +199 -113
  23. package/dist/sdk/chunk-Q4S5A5TO.mjs.map +1 -0
  24. package/dist/sdk/sdk.js +249 -149
  25. package/dist/sdk/sdk.js.map +1 -1
  26. package/dist/sdk/sdk.mjs +23 -19
  27. package/dist/sdk/sdk.mjs.map +1 -1
  28. package/dist/traces/{run-2025-10-16T11-33-32-682Z.ndjson → run-2025-10-18T18-27-25-085Z.ndjson} +8 -1
  29. package/dist/traces/{run-2025-10-16T11-33-43-618Z.ndjson → run-2025-10-18T18-27-35-400Z.ndjson} +8 -1
  30. package/dist/traces/{run-2025-10-16T11-33-44-157Z.ndjson → run-2025-10-18T18-27-35-937Z.ndjson} +8 -1
  31. package/dist/traces/{run-2025-10-16T11-33-44-647Z.ndjson → run-2025-10-18T18-27-36-428Z.ndjson} +8 -1
  32. package/dist/types/cli.d.ts +3 -2
  33. package/dist/types/cli.d.ts.map +1 -1
  34. package/dist/types/config.d.ts +0 -2
  35. package/dist/types/config.d.ts.map +1 -1
  36. package/dist/utils/diff-processor.d.ts +6 -0
  37. package/dist/utils/diff-processor.d.ts.map +1 -0
  38. package/package.json +2 -2
  39. package/dist/sdk/chunk-DQRFOQAP.mjs.map +0 -1
  40. /package/dist/sdk/{check-execution-engine-YBRPVUWD.mjs.map → check-execution-engine-NMPXJ7FQ.mjs.map} +0 -0
  41. /package/dist/traces/{run-2025-10-16T11-33-45-128Z.ndjson → run-2025-10-18T18-27-36-917Z.ndjson} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/session-registry.ts","../../src/github-comments.ts","../../src/ai-review-service.ts","../../src/reviewer.ts","../../src/git-repository-analyzer.ts","../../src/pr-analyzer.ts","../../src/providers/check-provider.interface.ts","../../src/utils/env-resolver.ts","../../src/issue-filter.ts","../../src/providers/ai-check-provider.ts","../../src/providers/http-check-provider.ts","../../src/providers/http-input-provider.ts","../../src/providers/http-client-provider.ts","../../src/providers/noop-check-provider.ts","../../src/providers/log-check-provider.ts","../../src/providers/github-ops-provider.ts","../../src/providers/claude-code-check-provider.ts","../../src/providers/claude-code-types.ts","../../src/providers/command-check-provider.ts","../../src/providers/memory-check-provider.ts","../../src/providers/check-provider-registry.ts","../../src/dependency-resolver.ts","../../src/failure-condition-evaluator.ts","../../src/github-check-service.ts","../../src/check-execution-engine.ts"],"sourcesContent":["import { ProbeAgent } from '@probelabs/probe';\nimport type { AppTracer, TelemetryConfig } from '@probelabs/probe';\n\n/**\n * Extended ProbeAgent interface that includes tracing properties\n */\ninterface TracedProbeAgent extends ProbeAgent {\n tracer?: AppTracer;\n _telemetryConfig?: TelemetryConfig;\n _traceFilePath?: string;\n}\n\n/**\n * Registry to manage active ProbeAgent sessions for session reuse\n */\nexport class SessionRegistry {\n private static instance: SessionRegistry;\n private sessions: Map<string, TracedProbeAgent> = new Map();\n private exitHandlerRegistered = false;\n\n private constructor() {\n // Register process exit handlers to cleanup sessions\n this.registerExitHandlers();\n }\n\n /**\n * Get the singleton instance of SessionRegistry\n */\n public static getInstance(): SessionRegistry {\n if (!SessionRegistry.instance) {\n SessionRegistry.instance = new SessionRegistry();\n }\n return SessionRegistry.instance;\n }\n\n /**\n * Register a ProbeAgent session\n */\n public registerSession(sessionId: string, agent: TracedProbeAgent): void {\n console.error(`🔄 Registering AI session: ${sessionId}`);\n this.sessions.set(sessionId, agent);\n }\n\n /**\n * Get an existing ProbeAgent session\n */\n public getSession(sessionId: string): TracedProbeAgent | undefined {\n const agent = this.sessions.get(sessionId);\n if (agent) {\n console.error(`♻️ Reusing AI session: ${sessionId}`);\n }\n return agent;\n }\n\n /**\n * Remove a session from the registry\n */\n public unregisterSession(sessionId: string): void {\n if (this.sessions.has(sessionId)) {\n console.error(`🗑️ Unregistering AI session: ${sessionId}`);\n const agent = this.sessions.get(sessionId);\n this.sessions.delete(sessionId);\n\n // Cleanup the ProbeAgent instance to prevent hanging processes\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (agent && typeof (agent as any).cleanup === 'function') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (agent as any).cleanup();\n } catch (error) {\n console.error(`⚠️ Warning: Failed to cleanup ProbeAgent: ${error}`);\n }\n }\n }\n }\n\n /**\n * Clear all sessions (useful for cleanup)\n */\n public clearAllSessions(): void {\n console.error(`🧹 Clearing all AI sessions (${this.sessions.size} sessions)`);\n\n // Cleanup each ProbeAgent instance before clearing\n for (const [, agent] of this.sessions.entries()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (agent && typeof (agent as any).cleanup === 'function') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (agent as any).cleanup();\n } catch {\n // Silent fail during bulk cleanup\n }\n }\n }\n\n this.sessions.clear();\n }\n\n /**\n * Get all active session IDs\n */\n public getActiveSessionIds(): string[] {\n return Array.from(this.sessions.keys());\n }\n\n /**\n * Check if a session exists\n */\n public hasSession(sessionId: string): boolean {\n return this.sessions.has(sessionId);\n }\n\n /**\n * Clone a session with a new session ID using ProbeAgent's official clone() method\n * This uses ProbeAgent's built-in cloning which automatically handles:\n * - Intelligent filtering of internal messages (schema reminders, tool prompts, etc.)\n * - Preserving system message for cache efficiency\n * - Deep copying conversation history\n * - Copying agent configuration\n */\n public async cloneSession(\n sourceSessionId: string,\n newSessionId: string,\n checkName?: string\n ): Promise<ProbeAgent | undefined> {\n const sourceAgent = this.sessions.get(sourceSessionId);\n if (!sourceAgent) {\n console.error(`⚠️ Cannot clone session: ${sourceSessionId} not found`);\n return undefined;\n }\n\n try {\n // Use ProbeAgent's official clone() method with options\n // This handles intelligent message filtering automatically\n const clonedAgent = sourceAgent.clone({\n sessionId: newSessionId,\n stripInternalMessages: true, // Remove schema reminders, tool prompts, etc.\n keepSystemMessage: true, // Keep for cache efficiency\n deepCopy: true, // Safe deep copy of history\n }) as TracedProbeAgent;\n\n // Set up tracing for cloned session if debug mode is enabled\n if ((sourceAgent as any).debug && checkName) {\n try {\n const { initializeTracer } = await import('./utils/tracer-init');\n const tracerResult = await initializeTracer(newSessionId, checkName);\n if (tracerResult) {\n clonedAgent.tracer = tracerResult.tracer;\n // Store telemetry config and trace file path for proper shutdown\n clonedAgent._telemetryConfig = tracerResult.telemetryConfig;\n clonedAgent._traceFilePath = tracerResult.filePath;\n }\n } catch (traceError) {\n console.error(\n '⚠️ Warning: Failed to initialize tracing for cloned session:',\n traceError\n );\n }\n }\n\n // Initialize MCP tools if the source agent had them initialized\n if (\n (sourceAgent as any)._mcpInitialized &&\n typeof (clonedAgent as any).initialize === 'function'\n ) {\n try {\n await (clonedAgent as any).initialize();\n console.error(`🔧 Initialized MCP tools for cloned session`);\n } catch (initError) {\n console.error(`⚠️ Warning: Failed to initialize cloned agent: ${initError}`);\n }\n }\n\n // Get history length for logging\n const historyLength = (clonedAgent as any).history?.length || 0;\n\n console.error(\n `📋 Cloned session ${sourceSessionId} → ${newSessionId} using ProbeAgent.clone() (${historyLength} messages, internal messages filtered)`\n );\n\n // Register the cloned session\n this.registerSession(newSessionId, clonedAgent);\n\n return clonedAgent;\n } catch (error) {\n console.error(`⚠️ Failed to clone session ${sourceSessionId}:`, error);\n return undefined;\n }\n }\n\n /**\n * Register process exit handlers to cleanup sessions on exit\n */\n private registerExitHandlers(): void {\n if (this.exitHandlerRegistered) {\n return;\n }\n\n const cleanupAndExit = (signal: string) => {\n if (this.sessions.size > 0) {\n console.error(`\\n🧹 [${signal}] Cleaning up ${this.sessions.size} active AI sessions...`);\n this.clearAllSessions();\n }\n };\n\n // Handle normal process exit\n process.on('exit', () => {\n if (this.sessions.size > 0) {\n console.error(`🧹 [exit] Cleaning up ${this.sessions.size} active AI sessions...`);\n // Note: async operations won't complete here, but sync cleanup methods will\n for (const [, agent] of this.sessions.entries()) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n if (agent && typeof (agent as any).cleanup === 'function') {\n try {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (agent as any).cleanup();\n } catch {\n // Silent fail on exit\n }\n }\n }\n this.sessions.clear();\n }\n });\n\n // Handle SIGINT (Ctrl+C)\n process.on('SIGINT', () => {\n cleanupAndExit('SIGINT');\n process.exit(0);\n });\n\n // Handle SIGTERM\n process.on('SIGTERM', () => {\n cleanupAndExit('SIGTERM');\n process.exit(0);\n });\n\n this.exitHandlerRegistered = true;\n }\n}\n","import { Octokit } from '@octokit/rest';\nimport { v4 as uuidv4 } from 'uuid';\nimport { logger } from './logger';\n\nexport interface Comment {\n id: number;\n body: string;\n user: {\n login: string;\n };\n created_at: string;\n updated_at: string;\n}\n\nexport interface RetryConfig {\n maxRetries: number;\n baseDelay: number;\n maxDelay: number;\n backoffFactor: number;\n}\n\nexport interface CommentMetadata {\n commentId: string;\n lastUpdated: string;\n triggeredBy: string;\n commitSha?: string;\n}\n\ninterface GitHubApiError {\n status?: number;\n response?: {\n status?: number;\n data?: {\n message?: string;\n };\n };\n}\n\n/**\n * Manages GitHub PR comments with dynamic updating capabilities\n */\nexport class CommentManager {\n private octokit: Octokit;\n private retryConfig: RetryConfig;\n\n constructor(octokit: Octokit, retryConfig?: Partial<RetryConfig>) {\n this.octokit = octokit;\n this.retryConfig = {\n maxRetries: 3,\n baseDelay: 1000,\n maxDelay: 10000,\n backoffFactor: 2,\n ...retryConfig,\n };\n }\n\n /**\n * Find existing Visor comment by comment ID marker\n */\n public async findVisorComment(\n owner: string,\n repo: string,\n prNumber: number,\n commentId?: string\n ): Promise<Comment | null> {\n try {\n const comments = await this.octokit.rest.issues.listComments({\n owner,\n repo,\n issue_number: prNumber,\n per_page: 100, // GitHub default max\n });\n\n for (const comment of comments.data) {\n if (comment.body && this.isVisorComment(comment.body, commentId)) {\n return comment as Comment;\n }\n }\n\n return null;\n } catch (error) {\n if (\n this.isRateLimitError(\n error as { status?: number; response?: { data?: { message?: string } } }\n )\n ) {\n await this.handleRateLimit(error as { response?: { headers?: Record<string, string> } });\n return this.findVisorComment(owner, repo, prNumber, commentId);\n }\n throw error;\n }\n }\n\n /**\n * Update existing comment or create new one with collision detection\n */\n public async updateOrCreateComment(\n owner: string,\n repo: string,\n prNumber: number,\n content: string,\n options: {\n commentId?: string;\n triggeredBy?: string;\n allowConcurrentUpdates?: boolean;\n commitSha?: string;\n } = {}\n ): Promise<Comment> {\n const {\n commentId = this.generateCommentId(),\n triggeredBy = 'unknown',\n allowConcurrentUpdates = false,\n commitSha,\n } = options;\n\n return this.withRetry(async () => {\n const existingComment = await this.findVisorComment(owner, repo, prNumber, commentId);\n\n const formattedContent = this.formatCommentWithMetadata(content, {\n commentId,\n lastUpdated: new Date().toISOString(),\n triggeredBy,\n commitSha,\n });\n\n if (existingComment) {\n // Check for collision if not allowing concurrent updates\n if (!allowConcurrentUpdates) {\n const currentComment = await this.octokit.rest.issues.getComment({\n owner,\n repo,\n comment_id: existingComment.id,\n });\n\n if (currentComment.data.updated_at !== existingComment.updated_at) {\n throw new Error(\n `Comment collision detected for comment ${commentId}. Another process may have updated it.`\n );\n }\n }\n\n const updatedComment = await this.octokit.rest.issues.updateComment({\n owner,\n repo,\n comment_id: existingComment.id,\n body: formattedContent,\n });\n\n logger.info(\n `✅ Successfully updated comment (ID: ${commentId}, GitHub ID: ${existingComment.id}) on PR #${prNumber} in ${owner}/${repo}`\n );\n\n return updatedComment.data as Comment;\n } else {\n const newComment = await this.octokit.rest.issues.createComment({\n owner,\n repo,\n issue_number: prNumber,\n body: formattedContent,\n });\n\n logger.info(\n `✅ Successfully created comment (ID: ${commentId}, GitHub ID: ${newComment.data.id}) on PR #${prNumber} in ${owner}/${repo}`\n );\n\n return newComment.data as Comment;\n }\n });\n }\n\n /**\n * Format comment content with metadata markers\n */\n public formatCommentWithMetadata(content: string, metadata: CommentMetadata): string {\n const { commentId, lastUpdated, triggeredBy, commitSha } = metadata;\n\n const commitInfo = commitSha ? ` | Commit: ${commitSha.substring(0, 7)}` : '';\n\n return `<!-- visor-comment-id:${commentId} -->\n${content}\n\n---\n\n*Powered by [Visor](https://probelabs.com/visor) from [Probelabs](https://probelabs.com)*\n\n*Last updated: ${lastUpdated} | Triggered by: ${triggeredBy}${commitInfo}*\n<!-- /visor-comment-id:${commentId} -->`;\n }\n\n /**\n * Create collapsible sections for comment content\n */\n public createCollapsibleSection(\n title: string,\n content: string,\n isExpanded: boolean = false\n ): string {\n const openAttribute = isExpanded ? ' open' : '';\n return `<details${openAttribute}>\n<summary>${title}</summary>\n\n${content}\n\n</details>`;\n }\n\n /**\n * Group review results by check type with collapsible sections\n */\n public formatGroupedResults(\n results: Array<{ checkType: string; content: string; score?: number; issuesFound?: number }>,\n groupBy: 'check' | 'severity' = 'check'\n ): string {\n const grouped = this.groupResults(results, groupBy);\n const sections: string[] = [];\n\n for (const [groupKey, items] of Object.entries(grouped)) {\n const totalScore = items.reduce((sum, item) => sum + (item.score || 0), 0) / items.length;\n const totalIssues = items.reduce((sum, item) => sum + (item.issuesFound || 0), 0);\n\n const emoji = this.getCheckTypeEmoji(groupKey);\n const title = `${emoji} ${this.formatGroupTitle(groupKey, totalScore, totalIssues)}`;\n\n const sectionContent = items.map(item => item.content).join('\\n\\n');\n sections.push(this.createCollapsibleSection(title, sectionContent, totalIssues > 0));\n }\n\n return sections.join('\\n\\n');\n }\n\n /**\n * Generate unique comment ID\n */\n private generateCommentId(): string {\n return uuidv4().substring(0, 8);\n }\n\n /**\n * Check if comment is a Visor comment\n */\n private isVisorComment(body: string, commentId?: string): boolean {\n if (commentId) {\n // Check for the new format with exact matching - look for the exact ID followed by space or \" -->\"\n if (\n body.includes(`visor-comment-id:${commentId} `) ||\n body.includes(`visor-comment-id:${commentId} -->`)\n ) {\n return true;\n }\n // Check for legacy format (visor-review-* pattern) for backwards compatibility\n if (commentId.startsWith('pr-review-') && body.includes('visor-review-')) {\n return true;\n }\n // If we have a specific commentId but no exact match, return false\n return false;\n }\n // General Visor comment detection (only when no specific commentId provided)\n return (\n (body.includes('visor-comment-id:') && body.includes('<!-- /visor-comment-id:')) ||\n body.includes('visor-review-')\n );\n }\n\n /**\n * Extract comment ID from comment body\n */\n public extractCommentId(body: string): string | null {\n const match = body.match(/visor-comment-id:([a-f0-9-]+)/);\n return match ? match[1] : null;\n }\n\n /**\n * Handle rate limiting with exponential backoff\n */\n private async handleRateLimit(error: {\n response?: { headers?: Record<string, string> };\n }): Promise<void> {\n const resetTime = error.response?.headers?.['x-ratelimit-reset'];\n if (resetTime) {\n const resetDate = new Date(parseInt(resetTime) * 1000);\n const waitTime = Math.max(resetDate.getTime() - Date.now(), this.retryConfig.baseDelay);\n console.log(`Rate limit exceeded. Waiting ${Math.round(waitTime / 1000)}s until reset...`);\n await this.sleep(Math.min(waitTime, this.retryConfig.maxDelay));\n } else {\n await this.sleep(this.retryConfig.baseDelay);\n }\n }\n\n /**\n * Check if error is a rate limit error\n */\n private isRateLimitError(error: GitHubApiError): boolean {\n return error.status === 403 && (error.response?.data?.message?.includes('rate limit') ?? false);\n }\n\n /**\n * Check if error should not be retried (auth errors, not found, etc.)\n */\n private isNonRetryableError(error: GitHubApiError): boolean {\n // Don't retry auth errors, not found, etc., but allow rate limit errors to be handled separately\n const nonRetryableStatuses = [401, 404, 422]; // Unauthorized, Not Found, Unprocessable Entity\n const status = error.status || error.response?.status;\n\n // 403 is non-retryable unless it's a rate limit error\n if (status === 403) {\n return !this.isRateLimitError(error);\n }\n\n return status !== undefined && nonRetryableStatuses.includes(status);\n }\n\n /**\n * Retry wrapper with exponential backoff\n */\n private async withRetry<T>(operation: () => Promise<T>): Promise<T> {\n let lastError: Error = new Error('Unknown error');\n\n for (let attempt = 0; attempt <= this.retryConfig.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt === this.retryConfig.maxRetries) {\n break;\n }\n\n if (\n this.isRateLimitError(\n error as { status?: number; response?: { data?: { message?: string } } }\n )\n ) {\n await this.handleRateLimit(error as { response?: { headers?: Record<string, string> } });\n } else if (this.isNonRetryableError(error as GitHubApiError)) {\n // Don't retry auth errors, not found errors, etc.\n throw error;\n } else {\n const delay = Math.min(\n this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffFactor, attempt),\n this.retryConfig.maxDelay\n );\n await this.sleep(delay);\n }\n }\n }\n\n throw lastError;\n }\n\n /**\n * Sleep utility\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n /**\n * Group results by specified criteria\n */\n private groupResults(\n results: Array<{ checkType: string; content: string; score?: number; issuesFound?: number }>,\n groupBy: 'check' | 'severity'\n ): Record<\n string,\n Array<{ checkType: string; content: string; score?: number; issuesFound?: number }>\n > {\n const grouped: Record<\n string,\n Array<{ checkType: string; content: string; score?: number; issuesFound?: number }>\n > = {};\n\n for (const result of results) {\n const key = groupBy === 'check' ? result.checkType : this.getSeverityGroup(result.score);\n if (!grouped[key]) {\n grouped[key] = [];\n }\n grouped[key].push(result);\n }\n\n return grouped;\n }\n\n /**\n * Get severity group based on score\n */\n private getSeverityGroup(score?: number): string {\n if (!score) return 'Unknown';\n if (score >= 90) return 'Excellent';\n if (score >= 75) return 'Good';\n if (score >= 50) return 'Needs Improvement';\n return 'Critical Issues';\n }\n\n /**\n * Get emoji for check type\n */\n private getCheckTypeEmoji(checkType: string): string {\n const emojiMap: Record<string, string> = {\n performance: '📈',\n security: '🔒',\n architecture: '🏗️',\n style: '🎨',\n all: '🔍',\n Excellent: '✅',\n Good: '👍',\n 'Needs Improvement': '⚠️',\n 'Critical Issues': '🚨',\n Unknown: '❓',\n };\n return emojiMap[checkType] || '📝';\n }\n\n /**\n * Format group title with score and issue count\n */\n private formatGroupTitle(groupKey: string, score: number, issuesFound: number): string {\n const formattedScore = Math.round(score);\n return `${groupKey} Review (Score: ${formattedScore}/100)${issuesFound > 0 ? ` - ${issuesFound} issues found` : ''}`;\n }\n}\n","import { ProbeAgent } from '@probelabs/probe';\nimport type { ProbeAgentOptions } from '@probelabs/probe';\nimport type { AppTracer, TelemetryConfig } from '@probelabs/probe';\nimport { PRInfo } from './pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from './reviewer';\nimport { SessionRegistry } from './session-registry';\nimport { logger } from './logger';\nimport { initializeTracer } from './utils/tracer-init';\n\n/**\n * Helper function to log debug messages using the centralized logger\n */\nfunction log(...args: unknown[]): void {\n logger.debug(args.join(' '));\n}\n\n/**\n * Extended ProbeAgent interface that includes tracing properties\n */\ninterface TracedProbeAgent extends ProbeAgent {\n tracer?: AppTracer;\n _telemetryConfig?: TelemetryConfig;\n _traceFilePath?: string;\n}\n\n/**\n * Extended ProbeAgentOptions interface that includes tracing properties\n */\ninterface TracedProbeAgentOptions extends ProbeAgentOptions {\n tracer?: AppTracer;\n _telemetryConfig?: TelemetryConfig;\n _traceFilePath?: string;\n}\n\nexport interface AIReviewConfig {\n apiKey?: string; // From env: GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, CLAUDE_CODE_API_KEY, or AWS credentials\n model?: string; // From env: MODEL_NAME (e.g., gemini-2.5-pro-preview-06-05)\n timeout?: number; // Default: 600000ms (10 minutes)\n provider?: 'google' | 'anthropic' | 'openai' | 'bedrock' | 'mock' | 'claude-code';\n debug?: boolean; // Enable debug mode\n tools?: Array<{ name: string; [key: string]: unknown }>; // (unused) Legacy tool listing\n // Pass-through MCP server configuration for ProbeAgent\n mcpServers?: Record<string, import('./types/config').McpServerConfig>;\n}\n\nexport interface AIDebugInfo {\n /** The prompt sent to the AI */\n prompt: string;\n /** Raw response from the AI service */\n rawResponse: string;\n /** Provider used (google, anthropic, openai) */\n provider: string;\n /** Model used */\n model: string;\n /** API key source (for privacy, just show which env var) */\n apiKeySource: string;\n /** Processing time in milliseconds */\n processingTime: number;\n /** Prompt length in characters */\n promptLength: number;\n /** Response length in characters */\n responseLength: number;\n /** Any errors encountered */\n errors?: string[];\n /** Whether JSON parsing succeeded */\n jsonParseSuccess: boolean;\n /** Schema used for response validation */\n schema?: string;\n /** Schema name/type requested */\n schemaName?: string;\n /** Checks executed during this review */\n checksExecuted?: string[];\n /** Whether parallel execution was used */\n parallelExecution?: boolean;\n /** Timestamp when request was made */\n timestamp: string;\n /** Total API calls made */\n totalApiCalls?: number;\n /** Details about API calls made */\n apiCallDetails?: Array<{\n checkName: string;\n provider: string;\n model: string;\n processingTime: number;\n success: boolean;\n }>;\n}\n\n// REMOVED: ReviewFocus type - only use custom prompts from .visor.yaml\n\ninterface AIResponseFormat {\n // Array of issues for code review\n issues?: Array<{\n file: string;\n line: number;\n endLine?: number;\n ruleId: string;\n message: string;\n severity: 'info' | 'warning' | 'error' | 'critical';\n category: 'security' | 'performance' | 'style' | 'logic' | 'documentation';\n suggestion?: string;\n replacement?: string;\n }>;\n}\n\nexport class AIReviewService {\n private config: AIReviewConfig;\n private sessionRegistry: SessionRegistry;\n\n constructor(config: AIReviewConfig = {}) {\n this.config = {\n timeout: 600000, // Increased timeout to 10 minutes for AI responses\n ...config,\n };\n\n this.sessionRegistry = SessionRegistry.getInstance();\n\n // Auto-detect provider and API key from environment\n if (!this.config.apiKey) {\n if (process.env.CLAUDE_CODE_API_KEY) {\n this.config.apiKey = process.env.CLAUDE_CODE_API_KEY;\n this.config.provider = 'claude-code';\n } else if (process.env.GOOGLE_API_KEY) {\n this.config.apiKey = process.env.GOOGLE_API_KEY;\n this.config.provider = 'google';\n } else if (process.env.ANTHROPIC_API_KEY) {\n this.config.apiKey = process.env.ANTHROPIC_API_KEY;\n this.config.provider = 'anthropic';\n } else if (process.env.OPENAI_API_KEY) {\n this.config.apiKey = process.env.OPENAI_API_KEY;\n this.config.provider = 'openai';\n } else if (\n // Check for AWS Bedrock credentials\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_BEDROCK_API_KEY\n ) {\n // For Bedrock, we don't set apiKey as it uses AWS credentials\n // ProbeAgent will handle the authentication internally\n this.config.provider = 'bedrock';\n // Set a placeholder to pass validation\n this.config.apiKey = 'AWS_CREDENTIALS';\n }\n }\n\n // Auto-detect model from environment\n if (!this.config.model && process.env.MODEL_NAME) {\n this.config.model = process.env.MODEL_NAME;\n }\n }\n\n /**\n * Execute AI review using probe agent\n */\n async executeReview(\n prInfo: PRInfo,\n customPrompt: string,\n schema?: string | Record<string, unknown>,\n _checkName?: string,\n sessionId?: string\n ): Promise<ReviewSummary> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Build prompt from custom instructions\n const prompt = await this.buildCustomPrompt(prInfo, customPrompt, schema);\n\n log(`Executing AI review with ${this.config.provider} provider...`);\n log(`🔧 Debug: Raw schema parameter: ${JSON.stringify(schema)} (type: ${typeof schema})`);\n log(`Schema type: ${schema || 'none (no schema)'}`);\n\n let debugInfo: AIDebugInfo | undefined;\n if (this.config.debug) {\n debugInfo = {\n prompt,\n rawResponse: '',\n provider: this.config.provider || 'unknown',\n model: this.config.model || 'default',\n apiKeySource: this.getApiKeySource(),\n processingTime: 0,\n promptLength: prompt.length,\n responseLength: 0,\n errors: [],\n jsonParseSuccess: false,\n timestamp,\n schemaName: typeof schema === 'object' ? 'custom' : schema,\n schema: undefined, // Will be populated when schema is loaded\n };\n }\n\n // Handle mock model/provider first (no API key needed)\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n log('🎭 Using mock AI model/provider for testing - skipping API key validation');\n } else {\n // Check if API key is available for real AI models\n if (!this.config.apiKey) {\n const errorMessage =\n 'No API key configured. Please set GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY environment variable, or configure AWS credentials for Bedrock (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY).';\n\n // In debug mode, return a review with the error captured\n if (debugInfo) {\n debugInfo.errors = [errorMessage];\n debugInfo.processingTime = Date.now() - startTime;\n debugInfo.rawResponse = 'API call not attempted - no API key configured';\n\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'system/api-key-missing',\n message: errorMessage,\n severity: 'error',\n category: 'logic',\n },\n ],\n debug: debugInfo,\n };\n }\n\n throw new Error(errorMessage);\n }\n }\n\n try {\n const { response, effectiveSchema } = await this.callProbeAgent(\n prompt,\n schema,\n debugInfo,\n _checkName,\n sessionId\n );\n const processingTime = Date.now() - startTime;\n\n if (debugInfo) {\n debugInfo.rawResponse = response;\n debugInfo.responseLength = response.length;\n debugInfo.processingTime = processingTime;\n }\n\n const result = this.parseAIResponse(response, debugInfo, effectiveSchema);\n\n if (debugInfo) {\n result.debug = debugInfo;\n }\n\n return result;\n } catch (error) {\n if (debugInfo) {\n debugInfo.errors = [error instanceof Error ? error.message : String(error)];\n debugInfo.processingTime = Date.now() - startTime;\n\n // In debug mode, return a review with the error captured\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'system/ai-execution-error',\n message: error instanceof Error ? error.message : String(error),\n severity: 'error',\n category: 'logic',\n },\n ],\n debug: debugInfo,\n };\n }\n throw error;\n }\n }\n\n /**\n * Execute AI review using session reuse - reuses an existing ProbeAgent session\n * @param sessionMode - 'clone' (default) clones history, 'append' shares history\n */\n async executeReviewWithSessionReuse(\n prInfo: PRInfo,\n customPrompt: string,\n parentSessionId: string,\n schema?: string | Record<string, unknown>,\n checkName?: string,\n sessionMode: 'clone' | 'append' = 'clone'\n ): Promise<ReviewSummary> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n // Get the existing session\n const existingAgent = this.sessionRegistry.getSession(parentSessionId);\n if (!existingAgent) {\n throw new Error(\n `Session not found for reuse: ${parentSessionId}. Ensure the parent check completed successfully.`\n );\n }\n\n // Build prompt from custom instructions\n // When reusing session, skip PR context since it's already in the conversation history\n const prompt = await this.buildCustomPrompt(prInfo, customPrompt, schema, {\n skipPRContext: true,\n });\n\n // Determine which agent to use based on session mode\n let agentToUse: typeof existingAgent;\n let currentSessionId: string;\n\n if (sessionMode === 'clone') {\n // Clone the session - creates a new agent with copied history\n // Include check name in the session ID for better tracing\n currentSessionId = `${checkName}-session-${Date.now()}`;\n log(\n `📋 Cloning AI session ${parentSessionId} → ${currentSessionId} for ${checkName} check...`\n );\n\n const clonedAgent = await this.sessionRegistry.cloneSession(\n parentSessionId,\n currentSessionId,\n checkName // Pass checkName for tracing\n );\n if (!clonedAgent) {\n throw new Error(`Failed to clone session ${parentSessionId}`);\n }\n agentToUse = clonedAgent;\n } else {\n // Append mode - use the same agent instance\n log(`🔄 Appending to AI session ${parentSessionId} (shared history)...`);\n agentToUse = existingAgent;\n currentSessionId = parentSessionId;\n }\n\n log(`🔧 Debug: Raw schema parameter: ${JSON.stringify(schema)} (type: ${typeof schema})`);\n log(`📋 Schema for this check: ${schema || 'none (no schema)'}`);\n if (sessionMode === 'clone') {\n log(`✅ Cloned agent will use NEW schema (${schema}) - parent schema does not persist`);\n log(`🔄 Clone operation ensures fresh agent with copied history but new configuration`);\n } else {\n log(`🔄 Append mode - using existing agent instance with shared history and configuration`);\n }\n\n let debugInfo: AIDebugInfo | undefined;\n if (this.config.debug) {\n debugInfo = {\n prompt,\n rawResponse: '',\n provider: this.config.provider || 'unknown',\n model: this.config.model || 'default',\n apiKeySource: this.getApiKeySource(),\n processingTime: 0,\n promptLength: prompt.length,\n responseLength: 0,\n errors: [],\n jsonParseSuccess: false,\n timestamp,\n schemaName: typeof schema === 'object' ? 'custom' : schema,\n schema: undefined, // Will be populated when schema is loaded\n };\n }\n\n try {\n // Use the determined agent (cloned or original)\n const { response, effectiveSchema } = await this.callProbeAgentWithExistingSession(\n agentToUse,\n prompt,\n schema,\n debugInfo,\n checkName\n );\n const processingTime = Date.now() - startTime;\n\n if (debugInfo) {\n debugInfo.rawResponse = response;\n debugInfo.responseLength = response.length;\n debugInfo.processingTime = processingTime;\n }\n\n const result = this.parseAIResponse(response, debugInfo, effectiveSchema);\n\n if (debugInfo) {\n result.debug = debugInfo;\n }\n\n // Include the session ID in the result for cleanup tracking\n // Only include if we created a new cloned session\n if (sessionMode === 'clone' && currentSessionId !== parentSessionId) {\n result.sessionId = currentSessionId;\n }\n\n return result;\n } catch (error) {\n if (debugInfo) {\n debugInfo.errors = [error instanceof Error ? error.message : String(error)];\n debugInfo.processingTime = Date.now() - startTime;\n\n // In debug mode, return a review with the error captured\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'system/ai-session-reuse-error',\n message: error instanceof Error ? error.message : String(error),\n severity: 'error',\n category: 'logic',\n },\n ],\n debug: debugInfo,\n };\n }\n throw error;\n }\n }\n\n /**\n * Register a new AI session in the session registry\n */\n registerSession(sessionId: string, agent: TracedProbeAgent): void {\n this.sessionRegistry.registerSession(sessionId, agent);\n }\n\n /**\n * Cleanup a session from the registry\n */\n cleanupSession(sessionId: string): void {\n this.sessionRegistry.unregisterSession(sessionId);\n }\n\n /**\n * Build a custom prompt for AI review with XML-formatted data\n */\n private async buildCustomPrompt(\n prInfo: PRInfo,\n customInstructions: string,\n schema?: string | Record<string, unknown>,\n options?: { skipPRContext?: boolean }\n ): Promise<string> {\n // When reusing sessions, skip PR context to avoid sending duplicate diff data\n const skipPRContext = options?.skipPRContext === true;\n\n const prContext = skipPRContext ? '' : this.formatPRContext(prInfo);\n const isIssue = (prInfo as PRInfo & { isIssue?: boolean }).isIssue === true;\n\n // Check if we're using the code-review schema\n const isCodeReviewSchema = schema === 'code-review';\n\n if (isIssue) {\n // Issue context - no code analysis needed\n if (skipPRContext) {\n // Session reuse: just send new instructions\n return `<instructions>\n${customInstructions}\n</instructions>`;\n }\n\n return `<review_request>\n <instructions>\n${customInstructions}\n </instructions>\n\n <context>\n${prContext}\n </context>\n\n <rules>\n <rule>Understand the issue context and requirements from the XML data structure</rule>\n <rule>Provide helpful, actionable guidance based on the issue details</rule>\n <rule>Be constructive and supportive in your analysis</rule>\n <rule>Consider project conventions and patterns when making recommendations</rule>\n <rule>Suggest practical solutions or next steps that address the specific concern</rule>\n <rule>Focus on addressing the specific concern raised in the issue</rule>\n <rule>Reference relevant XML elements like metadata, description, labels, assignees when providing context</rule>\n </rules>\n</review_request>`;\n }\n\n // Only add review_request wrapper and PR-specific rules for code-review schema\n if (isCodeReviewSchema) {\n // PR context with code-review schema - structured XML format\n const analysisType = prInfo.isIncremental ? 'INCREMENTAL' : 'FULL';\n\n if (skipPRContext) {\n // Session reuse: just send new instructions without repeating the context\n return `<instructions>\n${customInstructions}\n</instructions>\n\n<reminder>\n <rule>The code context and diff were provided in the previous message</rule>\n <rule>Focus on the new analysis instructions above</rule>\n <rule>Only analyze code that appears with + (additions) or - (deletions) in the diff sections</rule>\n <rule>STRICT OUTPUT POLICY: Report only actual problems, risks, or deficiencies</rule>\n <rule>SEVERITY ASSIGNMENT: Assign severity ONLY to problems introduced or left unresolved by this change</rule>\n</reminder>`;\n }\n\n return `<review_request>\n <analysis_type>${analysisType}</analysis_type>\n\n <analysis_focus>\n ${\n analysisType === 'INCREMENTAL'\n ? 'You are analyzing a NEW COMMIT added to an existing PR. Focus on the changes in the commit_diff section for this specific commit.'\n : 'You are analyzing the COMPLETE PR. Review all changes in the full_diff section.'\n }\n </analysis_focus>\n\n <instructions>\n${customInstructions}\n </instructions>\n\n <context>\n${prContext}\n </context>\n\n <rules>\n <rule>Only analyze code that appears with + (additions) or - (deletions) in the diff sections</rule>\n <rule>Ignore unchanged code unless directly relevant to understanding a change</rule>\n <rule>Line numbers in your response should match actual file line numbers from the diff</rule>\n <rule>Focus on real issues, not nitpicks or cosmetic concerns</rule>\n <rule>Provide actionable, specific feedback with clear remediation steps</rule>\n <rule>For INCREMENTAL analysis, ONLY review changes in commit_diff section</rule>\n <rule>For FULL analysis, review all changes in full_diff section</rule>\n <rule>Reference specific XML elements like files_summary, metadata when providing context</rule>\n <rule>STRICT OUTPUT POLICY: Report only actual problems, risks, or deficiencies. Do not write praise, congratulations, or celebratory text. Do not create issues that merely restate improvements or say \"no action needed\".</rule>\n <rule>SEVERITY ASSIGNMENT: Assign severity ONLY to problems introduced or left unresolved by this change (critical/error/warning/info as appropriate). Do NOT create issue entries solely to acknowledge improvements; if no problems exist, return zero issues.</rule>\n </rules>\n</review_request>`;\n }\n\n // For non-code-review schemas, just provide instructions and context without review-specific wrapper\n if (skipPRContext) {\n // Session reuse: just send new instructions\n return `<instructions>\n${customInstructions}\n</instructions>`;\n }\n\n return `<instructions>\n${customInstructions}\n</instructions>\n\n<context>\n${prContext}\n</context>`;\n }\n\n // REMOVED: Built-in prompts - only use custom prompts from .visor.yaml\n\n // REMOVED: getFocusInstructions - only use custom prompts from .visor.yaml\n\n /**\n * Format PR or Issue context for the AI using XML structure\n */\n private formatPRContext(prInfo: PRInfo): string {\n // Check if this is an issue (not a PR)\n const prContextInfo = prInfo as PRInfo & {\n isPRContext?: boolean;\n includeCodeContext?: boolean;\n };\n const isIssue = prContextInfo.isIssue === true;\n\n // Check if we should include code context (diffs)\n const isPRContext = prContextInfo.isPRContext === true;\n // In PR context, always include diffs. Otherwise check the flag.\n const includeCodeContext = isPRContext || prContextInfo.includeCodeContext !== false;\n\n // Log the decision for transparency\n const log = this.config.debug ? console.error : () => {};\n if (isPRContext) {\n log('🔍 Including full code diffs in AI context (PR mode)');\n } else if (!includeCodeContext) {\n log('📊 Including only file summary in AI context (no diffs)');\n } else {\n log('🔍 Including code diffs in AI context');\n }\n\n if (isIssue) {\n // Format as issue context\n let context = `<issue>\n <!-- Core issue metadata including identification, status, and timeline information -->\n <metadata>\n <number>${prInfo.number}</number>\n <title>${this.escapeXml(prInfo.title)}</title>\n <author>${prInfo.author}</author>\n <state>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; created_at?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.state || 'open'}</state>\n <created_at>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; created_at?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.created_at || ''}</created_at>\n <updated_at>${(prInfo as PRInfo & { eventContext?: { issue?: { state?: string; updated_at?: string; comments?: number } } }).eventContext?.issue?.updated_at || ''}</updated_at>\n <comments_count>${(prInfo as PRInfo & { eventContext?: { issue?: { comments?: number } } }).eventContext?.issue?.comments || 0}</comments_count>\n </metadata>`;\n\n // Add issue body/description if available\n if (prInfo.body) {\n context += `\n <!-- Full issue description and body text provided by the issue author -->\n <description>\n${this.escapeXml(prInfo.body)}\n </description>`;\n }\n\n // Add labels if available\n const eventContext = prInfo as PRInfo & {\n eventContext?: { issue?: { labels?: Array<{ name?: string } | string> } };\n };\n const labels = eventContext.eventContext?.issue?.labels;\n if (labels && labels.length > 0) {\n context += `\n <!-- Applied labels for issue categorization and organization -->\n <labels>`;\n labels.forEach((label: { name?: string } | string) => {\n const labelName = typeof label === 'string' ? label : label.name || 'unknown';\n context += `\n <label>${this.escapeXml(labelName)}</label>`;\n });\n context += `\n </labels>`;\n }\n\n // Add assignees if available\n const assignees = (\n prInfo as PRInfo & {\n eventContext?: { issue?: { assignees?: Array<{ login?: string } | string> } };\n }\n ).eventContext?.issue?.assignees;\n if (assignees && assignees.length > 0) {\n context += `\n <!-- Users assigned to work on this issue -->\n <assignees>`;\n assignees.forEach((assignee: { login?: string } | string) => {\n const assigneeName =\n typeof assignee === 'string' ? assignee : assignee.login || 'unknown';\n context += `\n <assignee>${this.escapeXml(assigneeName)}</assignee>`;\n });\n context += `\n </assignees>`;\n }\n\n // Add milestone if available\n const milestone = (\n prInfo as PRInfo & {\n eventContext?: {\n issue?: { milestone?: { title?: string; state?: string; due_on?: string } };\n };\n }\n ).eventContext?.issue?.milestone;\n if (milestone) {\n context += `\n <!-- Associated project milestone information -->\n <milestone>\n <title>${this.escapeXml(milestone.title || '')}</title>\n <state>${milestone.state || 'open'}</state>\n <due_on>${milestone.due_on || ''}</due_on>\n </milestone>`;\n }\n\n // Add current/triggering comment if this is a comment event\n const triggeringComment = (\n prInfo as PRInfo & {\n eventContext?: {\n comment?: {\n user?: { login?: string };\n created_at?: string;\n body?: string;\n id?: number;\n };\n };\n }\n ).eventContext?.comment;\n if (triggeringComment) {\n context += `\n <!-- The comment that triggered this analysis -->\n <triggering_comment>\n <author>${this.escapeXml(triggeringComment.user?.login || 'unknown')}</author>\n <created_at>${triggeringComment.created_at || ''}</created_at>\n <body>${this.escapeXml(triggeringComment.body || '')}</body>\n </triggering_comment>`;\n }\n\n // Add comment history (excluding the current comment if it exists)\n const issueComments = (\n prInfo as PRInfo & {\n comments?: Array<{ id?: number; author?: string; body?: string; createdAt?: string }>;\n }\n ).comments;\n if (issueComments && issueComments.length > 0) {\n // Filter out the triggering comment from history if present\n const historicalComments = triggeringComment\n ? issueComments.filter(c => c.id !== triggeringComment.id)\n : issueComments;\n\n if (historicalComments.length > 0) {\n context += `\n <!-- Previous comments in chronological order (excluding triggering comment) -->\n <comment_history>`;\n historicalComments.forEach(comment => {\n context += `\n <comment>\n <author>${this.escapeXml(comment.author || 'unknown')}</author>\n <created_at>${comment.createdAt || ''}</created_at>\n <body>${this.escapeXml(comment.body || '')}</body>\n </comment>`;\n });\n context += `\n </comment_history>`;\n }\n }\n\n // Close the issue tag\n context += `\n</issue>`;\n\n return context;\n }\n\n // Original PR context formatting\n let context = `<pull_request>\n <!-- Core pull request metadata including identification, branches, and change statistics -->\n <metadata>\n <number>${prInfo.number}</number>\n <title>${this.escapeXml(prInfo.title)}</title>\n <author>${prInfo.author}</author>\n <base_branch>${prInfo.base}</base_branch>\n <target_branch>${prInfo.head}</target_branch>\n <total_additions>${prInfo.totalAdditions}</total_additions>\n <total_deletions>${prInfo.totalDeletions}</total_deletions>\n <files_changed_count>${prInfo.files.length}</files_changed_count>\n </metadata>`;\n\n // Add PR description if available\n if (prInfo.body) {\n context += `\n <!-- Full pull request description provided by the author -->\n <description>\n${this.escapeXml(prInfo.body)}\n </description>`;\n }\n\n // Add diffs only if includeCodeContext is true (or in PR mode)\n if (includeCodeContext) {\n // Add full diff if available (for complete PR review)\n if (prInfo.fullDiff) {\n context += `\n <!-- Complete unified diff showing all changes in the pull request -->\n <full_diff>\n${this.escapeXml(prInfo.fullDiff)}\n </full_diff>`;\n }\n\n // Add incremental commit diff if available (for new commit analysis)\n if (prInfo.isIncremental) {\n if (prInfo.commitDiff && prInfo.commitDiff.length > 0) {\n context += `\n <!-- Diff of only the latest commit for incremental analysis -->\n <commit_diff>\n${this.escapeXml(prInfo.commitDiff)}\n </commit_diff>`;\n } else {\n context += `\n <!-- Commit diff could not be retrieved - falling back to full diff analysis -->\n <commit_diff>\n${prInfo.fullDiff ? this.escapeXml(prInfo.fullDiff) : ''}\n </commit_diff>`;\n }\n }\n } else {\n // When not including diffs, add a note about it\n context += `\n <!-- Code diffs excluded to reduce token usage (no code-review schema detected or disabled by flag) -->`;\n }\n\n // Add file summary for context\n if (prInfo.files.length > 0) {\n context += `\n <!-- Summary of all files changed with statistics -->\n <files_summary>`;\n prInfo.files.forEach(file => {\n context += `\n <file>\n <filename>${this.escapeXml(file.filename)}</filename>\n <status>${file.status}</status>\n <additions>${file.additions}</additions>\n <deletions>${file.deletions}</deletions>\n </file>`;\n });\n context += `\n </files_summary>`;\n }\n\n // Add current/triggering comment if this is a comment event\n const triggeringComment = (\n prInfo as PRInfo & {\n eventContext?: {\n comment?: { user?: { login?: string }; created_at?: string; body?: string; id?: number };\n };\n }\n ).eventContext?.comment;\n if (triggeringComment) {\n context += `\n <!-- The comment that triggered this analysis -->\n <triggering_comment>\n <author>${this.escapeXml(triggeringComment.user?.login || 'unknown')}</author>\n <created_at>${triggeringComment.created_at || ''}</created_at>\n <body>${this.escapeXml(triggeringComment.body || '')}</body>\n </triggering_comment>`;\n }\n\n // Add comment history (excluding the current comment if it exists)\n const prComments = (\n prInfo as PRInfo & {\n comments?: Array<{ id?: number; author?: string; body?: string; createdAt?: string }>;\n }\n ).comments;\n if (prComments && prComments.length > 0) {\n // Filter out the triggering comment from history if present\n const historicalComments = triggeringComment\n ? prComments.filter(c => c.id !== triggeringComment.id)\n : prComments;\n\n if (historicalComments.length > 0) {\n context += `\n <!-- Previous PR comments in chronological order (excluding triggering comment) -->\n <comment_history>`;\n historicalComments.forEach(comment => {\n context += `\n <comment>\n <author>${this.escapeXml(comment.author || 'unknown')}</author>\n <created_at>${comment.createdAt || ''}</created_at>\n <body>${this.escapeXml(comment.body || '')}</body>\n </comment>`;\n });\n context += `\n </comment_history>`;\n }\n }\n\n context += `\n</pull_request>`;\n\n return context;\n }\n\n /**\n * No longer escaping XML - returning text as-is\n */\n private escapeXml(text: string): string {\n return text;\n }\n\n /**\n * Call ProbeAgent with an existing session\n */\n private async callProbeAgentWithExistingSession(\n agent: TracedProbeAgent,\n prompt: string,\n schema?: string | Record<string, unknown>,\n debugInfo?: AIDebugInfo,\n _checkName?: string\n ): Promise<{ response: string; effectiveSchema?: string }> {\n // Handle mock model/provider for testing\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n log('🎭 Using mock AI model/provider for testing (session reuse)');\n const response = await this.generateMockResponse(prompt);\n return { response, effectiveSchema: typeof schema === 'object' ? 'custom' : schema };\n }\n\n log('🔄 Reusing existing ProbeAgent session for AI review...');\n log(`📝 Prompt length: ${prompt.length} characters`);\n log(`⚙️ Model: ${this.config.model || 'default'}, Provider: ${this.config.provider || 'auto'}`);\n\n try {\n log('🚀 Calling existing ProbeAgent with answer()...');\n\n // Load and pass the actual schema content if provided (skip for plain schema)\n let schemaString: string | undefined = undefined;\n let effectiveSchema: string | undefined = typeof schema === 'object' ? 'custom' : schema;\n\n if (schema && schema !== 'plain') {\n try {\n schemaString = await this.loadSchemaContent(schema);\n log(`📋 Loaded schema content for: ${schema}`);\n log(`📄 Raw schema JSON:\\n${schemaString}`);\n } catch (error) {\n log(`⚠️ Failed to load schema ${schema}, proceeding without schema:`, error);\n schemaString = undefined;\n effectiveSchema = undefined; // Schema loading failed, treat as no schema\n if (debugInfo && debugInfo.errors) {\n debugInfo.errors.push(`Failed to load schema: ${error}`);\n }\n }\n } else if (schema === 'plain') {\n log(`📋 Using plain schema - no JSON validation will be applied`);\n }\n\n // Pass schema in options object with 'schema' property\n const schemaOptions = schemaString ? { schema: schemaString } : undefined;\n\n // Store the exact schema options being passed to ProbeAgent in debug info\n if (debugInfo && schemaOptions) {\n debugInfo.schema = JSON.stringify(schemaOptions, null, 2);\n }\n\n // Log the schema options being passed to ProbeAgent\n if (schemaOptions) {\n log(`🎯 Schema options passed to ProbeAgent.answer() (session reuse):`);\n log(JSON.stringify(schemaOptions, null, 2));\n }\n\n // Save prompt and debug info for session reuse too (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const provider = this.config.provider || 'auto';\n const model = this.config.model || 'default';\n\n // Try to extract conversation history from ProbeAgent\n let conversationHistory: any[] = [];\n try {\n // ProbeAgent stores history in different ways depending on version\n const agentAny = agent as any;\n if (agentAny.history) {\n conversationHistory = agentAny.history;\n } else if (agentAny.messages) {\n conversationHistory = agentAny.messages;\n } else if (agentAny._messages) {\n conversationHistory = agentAny._messages;\n }\n } catch {\n // Ignore if we can't access history\n }\n\n const debugData = {\n timestamp: timestamp,\n checkName: _checkName || 'unknown',\n provider: provider,\n model: model,\n schema: effectiveSchema,\n schemaOptions: schemaOptions || 'none',\n sessionInfo: {\n isSessionReuse: true,\n historyMessageCount: conversationHistory.length,\n },\n currentPromptLength: prompt.length,\n currentPrompt: prompt,\n conversationHistory: conversationHistory,\n };\n\n const debugJson = JSON.stringify(debugData, null, 2);\n\n // Also create a human-readable version with clear separators\n let readableVersion = `=============================================================\\n`;\n readableVersion += `VISOR DEBUG REPORT - SESSION REUSE\\n`;\n readableVersion += `=============================================================\\n`;\n readableVersion += `Timestamp: ${timestamp}\\n`;\n readableVersion += `Check Name: ${_checkName || 'unknown'}\\n`;\n readableVersion += `Provider: ${provider}\\n`;\n readableVersion += `Model: ${model}\\n`;\n readableVersion += `Schema: ${effectiveSchema}\\n`;\n readableVersion += `Schema Options: ${schemaOptions ? 'provided' : 'none'}\\n`;\n readableVersion += `History Messages: ${conversationHistory.length}\\n`;\n readableVersion += `=============================================================\\n\\n`;\n\n // Add schema details if provided\n if (schemaOptions) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `SCHEMA CONFIGURATION\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += JSON.stringify(schemaOptions, null, 2);\n readableVersion += `\\n`;\n }\n\n // Add conversation history with clear separators\n if (conversationHistory.length > 0) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `CONVERSATION HISTORY (${conversationHistory.length} messages)\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n conversationHistory.forEach((msg: any, index: number) => {\n readableVersion += `\\n${'-'.repeat(60)}\\n`;\n readableVersion += `MESSAGE #${index + 1}\\n`;\n readableVersion += `Role: ${msg.role || 'unknown'}\\n`;\n if (msg.content) {\n const contentStr =\n typeof msg.content === 'string'\n ? msg.content\n : JSON.stringify(msg.content, null, 2);\n readableVersion += `Length: ${contentStr.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${contentStr}\\n`;\n }\n });\n }\n\n // Add current prompt\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `CURRENT PROMPT (NEW MESSAGE)\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += `Length: ${prompt.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${prompt}\\n`;\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `END OF DEBUG REPORT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n if (!fs.existsSync(debugArtifactsDir)) {\n fs.mkdirSync(debugArtifactsDir, { recursive: true });\n }\n\n // Save JSON version\n const debugFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.json`\n );\n fs.writeFileSync(debugFile, debugJson, 'utf-8');\n\n // Save readable version\n const readableFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n fs.writeFileSync(readableFile, readableVersion, 'utf-8');\n\n log(`\\n💾 Full debug info saved to:`);\n log(` JSON: ${debugFile}`);\n log(` TXT: ${readableFile}`);\n log(` - Includes: full conversation history, schema, current prompt`);\n } catch (error) {\n log(`⚠️ Could not save debug file: ${error}`);\n }\n }\n\n // Use existing agent's answer method - this reuses the conversation context\n // Wrap in a span for hierarchical tracing\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const agentAny = agent as any;\n let response: string;\n if (agentAny.tracer && typeof agentAny.tracer.withSpan === 'function') {\n response = await agentAny.tracer.withSpan(\n 'visor.ai_check_reuse',\n async () => {\n return await agent.answer(prompt, undefined, schemaOptions);\n },\n {\n 'check.name': _checkName || 'unknown',\n 'check.mode': 'session_reuse',\n 'prompt.length': prompt.length,\n 'schema.type': effectiveSchema || 'none',\n }\n );\n } else {\n response = await agent.answer(prompt, undefined, schemaOptions);\n }\n\n log('✅ ProbeAgent session reuse completed successfully');\n log(`📤 Response length: ${response.length} characters`);\n\n // Save COMPLETE conversation history AFTER AI response (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Extract FULL conversation history AFTER the AI call\n const agentAny = agent as any;\n let fullHistory: any[] = [];\n\n // Try multiple properties to get complete history\n if (agentAny.history) {\n fullHistory = agentAny.history;\n } else if (agentAny.messages) {\n fullHistory = agentAny.messages;\n } else if (agentAny._messages) {\n fullHistory = agentAny._messages;\n }\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Save complete session history (all messages sent and received)\n const sessionFile = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}.json`\n );\n const sessionData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider: this.config.provider || 'auto',\n model: this.config.model || 'default',\n schema: effectiveSchema,\n fullConversationHistory: fullHistory,\n totalMessages: fullHistory.length,\n latestResponse: response,\n };\n\n fs.writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Save human-readable version\n const sessionTxtFile = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n let readable = `=============================================================\\n`;\n readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)\\n`;\n readable += `=============================================================\\n`;\n readable += `Timestamp: ${timestamp}\\n`;\n readable += `Check: ${_checkName || 'unknown'}\\n`;\n readable += `Total Messages: ${fullHistory.length}\\n`;\n readable += `=============================================================\\n\\n`;\n\n fullHistory.forEach((msg: any, idx: number) => {\n readable += `\\n${'='.repeat(60)}\\n`;\n readable += `MESSAGE ${idx + 1}/${fullHistory.length}\\n`;\n readable += `Role: ${msg.role || 'unknown'}\\n`;\n readable += `${'='.repeat(60)}\\n`;\n\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += content + '\\n';\n });\n\n fs.writeFileSync(sessionTxtFile, readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n log(` JSON: ${sessionFile}`);\n log(` TXT: ${sessionTxtFile}`);\n log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);\n } catch (error) {\n log(`⚠️ Could not save complete session history: ${error}`);\n }\n }\n\n // Save response if debug is enabled\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Create a response file with the same timestamp pattern\n const responseFile = path.join(\n debugArtifactsDir,\n `response-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n\n let responseContent = `=============================================================\\n`;\n responseContent += `VISOR AI RESPONSE - SESSION REUSE\\n`;\n responseContent += `=============================================================\\n`;\n responseContent += `Timestamp: ${timestamp}\\n`;\n responseContent += `Check Name: ${_checkName || 'unknown'}\\n`;\n responseContent += `Response Length: ${response.length} characters\\n`;\n responseContent += `=============================================================\\n\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += `AI RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += response;\n responseContent += `\\n${'='.repeat(60)}\\n`;\n responseContent += `END OF RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n\n fs.writeFileSync(responseFile, responseContent, 'utf-8');\n log(`💾 Response saved to: ${responseFile}`);\n } catch (error) {\n log(`⚠️ Could not save response file: ${error}`);\n }\n }\n\n // Finalize and save trace if this is a cloned session with tracing enabled\n // Properly flush and shutdown OpenTelemetry to ensure all spans are exported\n if (agentAny._traceFilePath && agentAny._telemetryConfig) {\n try {\n // First flush the tracer to export pending spans\n if (agentAny.tracer && typeof agentAny.tracer.flush === 'function') {\n await agentAny.tracer.flush();\n log(`🔄 Flushed tracer spans for cloned session`);\n }\n\n // Then shutdown the telemetry config to finalize all exporters\n if (\n agentAny._telemetryConfig &&\n typeof agentAny._telemetryConfig.shutdown === 'function'\n ) {\n await agentAny._telemetryConfig.shutdown();\n log(`📊 OpenTelemetry trace saved to: ${agentAny._traceFilePath}`);\n\n // In GitHub Actions, also log file size for verification\n if (process.env.GITHUB_ACTIONS) {\n const fs = require('fs');\n if (fs.existsSync(agentAny._traceFilePath)) {\n const stats = fs.statSync(agentAny._traceFilePath);\n console.log(\n `::notice title=AI Trace Saved::${agentAny._traceFilePath} (${stats.size} bytes)`\n );\n }\n }\n } else if (agentAny.tracer && typeof agentAny.tracer.shutdown === 'function') {\n // Fallback for SimpleTelemetry\n await agentAny.tracer.shutdown();\n log(`📊 Trace saved to: ${agentAny._traceFilePath}`);\n }\n } catch (exportError) {\n console.error('⚠️ Warning: Failed to export trace for cloned session:', exportError);\n }\n }\n\n return { response, effectiveSchema };\n } catch (error) {\n console.error('❌ ProbeAgent session reuse failed:', error);\n throw new Error(\n `ProbeAgent session reuse failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Call ProbeAgent SDK with built-in schema validation\n */\n private async callProbeAgent(\n prompt: string,\n schema?: string | Record<string, unknown>,\n debugInfo?: AIDebugInfo,\n _checkName?: string,\n providedSessionId?: string\n ): Promise<{ response: string; effectiveSchema?: string }> {\n // Handle mock model/provider for testing\n if (this.config.model === 'mock' || this.config.provider === 'mock') {\n log('🎭 Using mock AI model/provider for testing');\n const response = await this.generateMockResponse(prompt);\n return { response, effectiveSchema: typeof schema === 'object' ? 'custom' : schema };\n }\n\n // Create ProbeAgent instance with proper options\n const sessionId =\n providedSessionId ||\n (() => {\n const timestamp = new Date().toISOString();\n return `visor-${timestamp.replace(/[:.]/g, '-')}-${_checkName || 'unknown'}`;\n })();\n\n log('🤖 Creating ProbeAgent for AI review...');\n log(`🆔 Session ID: ${sessionId}`);\n log(`📝 Prompt length: ${prompt.length} characters`);\n log(`⚙️ Model: ${this.config.model || 'default'}, Provider: ${this.config.provider || 'auto'}`);\n\n // Store original env vars to restore later\n const originalEnv: Record<string, string | undefined> = {\n CLAUDE_CODE_API_KEY: process.env.CLAUDE_CODE_API_KEY,\n GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,\n ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY,\n OPENAI_API_KEY: process.env.OPENAI_API_KEY,\n };\n\n try {\n // Set environment variables for ProbeAgent\n // ProbeAgent SDK expects these to be in the environment\n if (this.config.provider === 'claude-code' && this.config.apiKey) {\n process.env.CLAUDE_CODE_API_KEY = this.config.apiKey;\n // Also set ANTHROPIC_API_KEY as fallback since Claude Code uses Anthropic API\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'google' && this.config.apiKey) {\n process.env.GOOGLE_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'anthropic' && this.config.apiKey) {\n process.env.ANTHROPIC_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'openai' && this.config.apiKey) {\n process.env.OPENAI_API_KEY = this.config.apiKey;\n } else if (this.config.provider === 'bedrock') {\n // For Bedrock, ProbeAgent will use AWS credentials from environment\n // No need to set apiKey as it uses AWS SDK authentication\n // ProbeAgent will check for AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, etc.\n }\n const options: TracedProbeAgentOptions = {\n sessionId: sessionId,\n promptType: schema ? ('code-review-template' as 'code-review') : undefined,\n allowEdit: false, // We don't want the agent to modify files\n debug: this.config.debug || false,\n };\n\n // Enable tracing in debug mode for better diagnostics\n // This uses OpenTelemetry for proper hierarchical span relationships\n let traceFilePath = '';\n let telemetryConfig: TelemetryConfig | null = null;\n if (this.config.debug) {\n const tracerResult = await initializeTracer(sessionId, _checkName);\n if (tracerResult) {\n options.tracer = tracerResult.tracer;\n telemetryConfig = tracerResult.telemetryConfig;\n traceFilePath = tracerResult.filePath;\n }\n }\n\n // Wire MCP configuration when provided\n if (this.config.mcpServers && Object.keys(this.config.mcpServers).length > 0) {\n (options as any).enableMcp = true;\n (options as any).mcpConfig = { mcpServers: this.config.mcpServers };\n }\n\n // Add provider-specific options if configured\n if (this.config.provider) {\n // Map claude-code to anthropic for ProbeAgent compatibility\n // Map bedrock to anthropic temporarily until ProbeAgent adds bedrock type\n const providerOverride: ProbeAgentOptions['provider'] | undefined =\n this.config.provider === 'claude-code' || this.config.provider === 'bedrock'\n ? 'anthropic'\n : this.config.provider === 'anthropic' ||\n this.config.provider === 'openai' ||\n this.config.provider === 'google'\n ? this.config.provider\n : undefined;\n\n if (providerOverride) {\n options.provider = providerOverride;\n }\n }\n if (this.config.model) {\n options.model = this.config.model;\n }\n\n const agent = new ProbeAgent(options);\n\n log('🚀 Calling ProbeAgent...');\n // Load and pass the actual schema content if provided (skip for plain schema)\n let schemaString: string | undefined = undefined;\n let effectiveSchema: string | undefined = typeof schema === 'object' ? 'custom' : schema;\n\n if (schema && schema !== 'plain') {\n try {\n schemaString = await this.loadSchemaContent(schema);\n log(`📋 Loaded schema content for: ${schema}`);\n log(`📄 Raw schema JSON:\\n${schemaString}`);\n } catch (error) {\n log(`⚠️ Failed to load schema ${schema}, proceeding without schema:`, error);\n schemaString = undefined;\n effectiveSchema = undefined; // Schema loading failed, treat as no schema\n if (debugInfo && debugInfo.errors) {\n debugInfo.errors.push(`Failed to load schema: ${error}`);\n }\n }\n } else if (schema === 'plain') {\n log(`📋 Using plain schema - no JSON validation will be applied`);\n }\n\n // ProbeAgent now handles schema formatting internally!\n // Pass schema in options object with 'schema' property\n const schemaOptions = schemaString ? { schema: schemaString } : undefined;\n\n // Store the exact schema options being passed to ProbeAgent in debug info\n if (debugInfo && schemaOptions) {\n debugInfo.schema = JSON.stringify(schemaOptions, null, 2);\n }\n\n // Log the schema options being passed to ProbeAgent\n if (schemaOptions) {\n log(`🎯 Schema options passed to ProbeAgent.answer():`);\n log(JSON.stringify(schemaOptions, null, 2));\n }\n\n // Log the equivalent CLI command for local reproduction\n const provider = this.config.provider || 'auto';\n const model = this.config.model || 'default';\n\n // Save prompt to a temp file AND debug artifacts for easier reproduction (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const os = require('os');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Prepare debug info with full details\n const debugData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider,\n model,\n schema: effectiveSchema,\n schemaOptions: schemaOptions || 'none',\n sessionInfo: {\n isSessionReuse: false,\n isNewSession: true,\n },\n promptLength: prompt.length,\n prompt: prompt,\n };\n\n const debugJson = JSON.stringify(debugData, null, 2);\n\n // Create human-readable version with clear separators\n let readableVersion = `=============================================================\\n`;\n readableVersion += `VISOR DEBUG REPORT - NEW SESSION\\n`;\n readableVersion += `=============================================================\\n`;\n readableVersion += `Timestamp: ${timestamp}\\n`;\n readableVersion += `Check Name: ${_checkName || 'unknown'}\\n`;\n readableVersion += `Provider: ${provider}\\n`;\n readableVersion += `Model: ${model}\\n`;\n readableVersion += `Schema: ${effectiveSchema}\\n`;\n readableVersion += `Schema Options: ${schemaOptions ? 'provided' : 'none'}\\n`;\n readableVersion += `Session Type: New Session (no history)\\n`;\n readableVersion += `=============================================================\\n\\n`;\n\n // Add schema details if provided\n if (schemaOptions) {\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `SCHEMA CONFIGURATION\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += JSON.stringify(schemaOptions, null, 2);\n readableVersion += `\\n`;\n }\n\n // Add prompt\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `PROMPT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n readableVersion += `Length: ${prompt.length} characters\\n`;\n readableVersion += `${'-'.repeat(60)}\\n`;\n readableVersion += `${prompt}\\n`;\n readableVersion += `\\n${'='.repeat(60)}\\n`;\n readableVersion += `END OF DEBUG REPORT\\n`;\n readableVersion += `${'='.repeat(60)}\\n`;\n\n // Save to temp directory\n const tempDir = os.tmpdir();\n const promptFile = path.join(tempDir, `visor-prompt-${timestamp}.txt`);\n fs.writeFileSync(promptFile, prompt, 'utf-8');\n log(`\\n💾 Prompt saved to: ${promptFile}`);\n\n // Also save to debug-artifacts directory if available\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n try {\n if (!fs.existsSync(debugArtifactsDir)) {\n fs.mkdirSync(debugArtifactsDir, { recursive: true });\n }\n\n // Save JSON version\n const debugFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.json`\n );\n fs.writeFileSync(debugFile, debugJson, 'utf-8');\n\n // Save readable version\n const readableFile = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n fs.writeFileSync(readableFile, readableVersion, 'utf-8');\n\n log(`\\n💾 Full debug info saved to:`);\n log(` JSON: ${debugFile}`);\n log(` TXT: ${readableFile}`);\n log(` - Includes: prompt, schema, provider, model, and schema options`);\n } catch {\n // Ignore if we can't write to debug-artifacts\n }\n\n log(`\\n📝 To reproduce locally, run:`);\n\n let cliCommand = `npx @probelabs/probe@latest agent`;\n cliCommand += ` --provider ${provider}`;\n if (model !== 'default') {\n cliCommand += ` --model ${model}`;\n }\n if (schema) {\n cliCommand += ` --schema output/${schema}/schema.json`;\n }\n cliCommand += ` \"${promptFile}\"`;\n\n log(`\\n$ ${cliCommand}\\n`);\n } catch (error) {\n log(`⚠️ Could not save prompt file: ${error}`);\n }\n }\n\n // Wrap the agent.answer() call in a span for hierarchical tracing\n // This creates a parent span that will contain all ProbeAgent's child spans\n let response: string;\n const tracer = options.tracer;\n if (tracer && typeof tracer.withSpan === 'function') {\n response = await tracer.withSpan(\n 'visor.ai_check',\n async () => {\n return await agent.answer(prompt, undefined, schemaOptions);\n },\n {\n 'check.name': _checkName || 'unknown',\n 'check.session_id': sessionId,\n 'prompt.length': prompt.length,\n 'schema.type': effectiveSchema || 'none',\n }\n );\n } else {\n response = await agent.answer(prompt, undefined, schemaOptions);\n }\n\n log('✅ ProbeAgent completed successfully');\n log(`📤 Response length: ${response.length} characters`);\n\n // Save COMPLETE conversation history AFTER AI response (only if debug enabled)\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n // Extract FULL conversation history AFTER the AI call\n const agentAny = agent as any;\n let fullHistory: any[] = [];\n\n // Try multiple properties to get complete history\n if (agentAny.history) {\n fullHistory = agentAny.history;\n } else if (agentAny.messages) {\n fullHistory = agentAny.messages;\n } else if (agentAny._messages) {\n fullHistory = agentAny._messages;\n }\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Save complete session history (all messages sent and received)\n const sessionFile = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}.json`\n );\n const sessionData = {\n timestamp,\n checkName: _checkName || 'unknown',\n provider: this.config.provider || 'auto',\n model: this.config.model || 'default',\n schema: effectiveSchema,\n fullConversationHistory: fullHistory,\n totalMessages: fullHistory.length,\n latestResponse: response,\n };\n\n fs.writeFileSync(sessionFile, JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Save human-readable version\n const sessionTxtFile = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n let readable = `=============================================================\\n`;\n readable += `COMPLETE AI SESSION HISTORY (AFTER RESPONSE)\\n`;\n readable += `=============================================================\\n`;\n readable += `Timestamp: ${timestamp}\\n`;\n readable += `Check: ${_checkName || 'unknown'}\\n`;\n readable += `Total Messages: ${fullHistory.length}\\n`;\n readable += `=============================================================\\n\\n`;\n\n fullHistory.forEach((msg: any, idx: number) => {\n readable += `\\n${'='.repeat(60)}\\n`;\n readable += `MESSAGE ${idx + 1}/${fullHistory.length}\\n`;\n readable += `Role: ${msg.role || 'unknown'}\\n`;\n readable += `${'='.repeat(60)}\\n`;\n\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += content + '\\n';\n });\n\n fs.writeFileSync(sessionTxtFile, readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n log(` JSON: ${sessionFile}`);\n log(` TXT: ${sessionTxtFile}`);\n log(` - Contains ALL ${fullHistory.length} messages (prompts + responses)`);\n } catch (error) {\n log(`⚠️ Could not save complete session history: ${error}`);\n }\n }\n\n // Save response if debug is enabled\n if (process.env.VISOR_DEBUG_AI_SESSIONS === 'true') {\n try {\n const fs = require('fs');\n const path = require('path');\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n\n const debugArtifactsDir =\n process.env.VISOR_DEBUG_ARTIFACTS || path.join(process.cwd(), 'debug-artifacts');\n\n // Create a response file\n const responseFile = path.join(\n debugArtifactsDir,\n `response-${_checkName || 'unknown'}-${timestamp}.txt`\n );\n\n let responseContent = `=============================================================\\n`;\n responseContent += `VISOR AI RESPONSE - NEW SESSION\\n`;\n responseContent += `=============================================================\\n`;\n responseContent += `Timestamp: ${timestamp}\\n`;\n responseContent += `Check Name: ${_checkName || 'unknown'}\\n`;\n responseContent += `Response Length: ${response.length} characters\\n`;\n responseContent += `=============================================================\\n\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += `AI RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n responseContent += response;\n responseContent += `\\n${'='.repeat(60)}\\n`;\n responseContent += `END OF RESPONSE\\n`;\n responseContent += `${'='.repeat(60)}\\n`;\n\n fs.writeFileSync(responseFile, responseContent, 'utf-8');\n log(`💾 Response saved to: ${responseFile}`);\n } catch (error) {\n log(`⚠️ Could not save response file: ${error}`);\n }\n }\n\n // Finalize and save trace if enabled\n // Properly flush and shutdown OpenTelemetry to ensure all spans are exported\n if (traceFilePath && telemetryConfig) {\n try {\n // First flush the tracer to export pending spans\n if (tracer && typeof tracer.flush === 'function') {\n await tracer.flush();\n log(`🔄 Flushed tracer spans`);\n }\n\n // Then shutdown the telemetry config to finalize all exporters\n if (telemetryConfig && typeof telemetryConfig.shutdown === 'function') {\n await telemetryConfig.shutdown();\n log(`📊 OpenTelemetry trace saved to: ${traceFilePath}`);\n\n // In GitHub Actions, also log file size for verification\n if (process.env.GITHUB_ACTIONS) {\n const fs = require('fs');\n if (fs.existsSync(traceFilePath)) {\n const stats = fs.statSync(traceFilePath);\n console.log(\n `::notice title=AI Trace Saved::OpenTelemetry trace file size: ${stats.size} bytes`\n );\n }\n }\n } else if (tracer && typeof tracer.shutdown === 'function') {\n // Fallback for SimpleTelemetry\n await tracer.shutdown();\n log(`📊 Trace saved to: ${traceFilePath}`);\n }\n } catch (exportError) {\n console.error('⚠️ Warning: Failed to export trace:', exportError);\n }\n }\n\n // Register the session for potential reuse by dependent checks\n if (_checkName) {\n // ProbeAgent.clone() will handle history filtering when this session is cloned\n this.registerSession(sessionId, agent);\n log(`🔧 Debug: Registered AI session for potential reuse: ${sessionId}`);\n }\n\n return { response, effectiveSchema };\n } catch (error) {\n console.error('❌ ProbeAgent failed:', error);\n throw new Error(\n `ProbeAgent execution failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n } finally {\n // Restore original environment variables\n Object.keys(originalEnv).forEach(key => {\n if (originalEnv[key] === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalEnv[key];\n }\n });\n }\n }\n\n /**\n * Load schema content from schema files or inline definitions\n */\n private async loadSchemaContent(schema: string | Record<string, unknown>): Promise<string> {\n const fs = require('fs').promises;\n const path = require('path');\n\n // Check if schema is already an object (inline definition from YAML)\n if (typeof schema === 'object' && schema !== null) {\n // It's already a schema object, convert to JSON string\n log('📋 Using inline schema object from configuration');\n return JSON.stringify(schema);\n }\n\n // Check if schema string is already a JSON schema (inline JSON string)\n // This happens when a schema is passed directly as JSON instead of a reference\n try {\n const parsed = JSON.parse(schema);\n if (typeof parsed === 'object' && parsed !== null) {\n // It's already a valid JSON schema, return it as-is\n log('📋 Using inline schema JSON string');\n return schema;\n }\n } catch {\n // Not JSON, treat as schema name reference or file path\n }\n\n // Check if it's a file path (starts with ./ or contains .json but not absolute paths)\n if ((schema.startsWith('./') || schema.includes('.json')) && !path.isAbsolute(schema)) {\n // It's a relative file path to a custom schema\n // Validate the path to prevent traversal attacks\n if (schema.includes('..') || schema.includes('\\x00')) {\n throw new Error('Invalid schema path: path traversal not allowed');\n }\n\n try {\n const schemaPath = path.resolve(process.cwd(), schema);\n log(`📋 Loading custom schema from file: ${schemaPath}`);\n const schemaContent = await fs.readFile(schemaPath, 'utf-8');\n return schemaContent.trim();\n } catch (error) {\n throw new Error(\n `Failed to load custom schema from ${schema}: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n // Otherwise, treat as a built-in schema name\n // Sanitize schema name to prevent path traversal attacks\n const sanitizedSchemaName = schema.replace(/[^a-zA-Z0-9-]/g, '');\n if (!sanitizedSchemaName || sanitizedSchemaName !== schema) {\n throw new Error('Invalid schema name');\n }\n\n // Construct path to built-in schema file\n const schemaPath = path.join(process.cwd(), 'output', sanitizedSchemaName, 'schema.json');\n\n try {\n // Return the schema as a string, not parsed JSON\n const schemaContent = await fs.readFile(schemaPath, 'utf-8');\n return schemaContent.trim();\n } catch (error) {\n throw new Error(\n `Failed to load schema from ${schemaPath}: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Parse AI response JSON\n */\n private parseAIResponse(\n response: string,\n debugInfo?: AIDebugInfo,\n _schema?: string\n ): ReviewSummary {\n log('🔍 Parsing AI response...');\n log(`📊 Raw response length: ${response.length} characters`);\n\n // Log first and last 200 chars for debugging\n if (response.length > 400) {\n log('📋 Response preview (first 200 chars):', response.substring(0, 200));\n log('📋 Response preview (last 200 chars):', response.substring(response.length - 200));\n } else {\n log('📋 Full response preview:', response);\n }\n\n // Note: Removed overly aggressive Liquid template check that was causing false positives\n // JSON parsing below will catch actual malformed responses\n\n try {\n // Handle different schema types differently\n let reviewData: AIResponseFormat;\n\n // Handle plain schema or no schema - no JSON parsing, return response as-is\n if (_schema === 'plain' || !_schema) {\n log(\n `📋 ${_schema === 'plain' ? 'Plain' : 'No'} schema detected - returning raw response without JSON parsing`\n );\n\n // For plain schema, return the raw response as an issue\n\n return {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n debug: debugInfo,\n };\n }\n\n {\n // For other schemas (code-review, etc.), extract and parse JSON with boundary detection\n log('🔍 Extracting JSON from AI response...');\n\n // Try direct parsing first - if AI returned pure JSON\n try {\n reviewData = JSON.parse(response.trim());\n log('✅ Successfully parsed direct JSON response');\n if (debugInfo) debugInfo.jsonParseSuccess = true;\n } catch {\n log('🔍 Direct parsing failed, trying to extract JSON from response...');\n\n // If the response starts with \"I cannot\" or similar, it's likely a refusal\n if (\n response.toLowerCase().includes('i cannot') ||\n response.toLowerCase().includes('unable to')\n ) {\n console.error('🚫 AI refused to analyze - returning empty result');\n return {\n issues: [],\n };\n }\n\n // Try to extract JSON using improved method with proper bracket matching\n const jsonString = this.extractJsonFromResponse(response);\n\n if (jsonString) {\n try {\n reviewData = JSON.parse(jsonString);\n log('✅ Successfully parsed extracted JSON');\n if (debugInfo) debugInfo.jsonParseSuccess = true;\n } catch {\n log('🔧 Extracted JSON parsing failed, falling back to plain text handling...');\n\n // Check if response is plain text and doesn't contain structured data\n if (!response.includes('{') && !response.includes('}')) {\n log('🔧 Plain text response detected, creating structured fallback...');\n\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n } else {\n // Fallback: treat the entire response as an issue\n log('🔧 Creating fallback response from non-JSON content...');\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n }\n }\n } else {\n // No JSON found at all - treat as plain text response\n log('🔧 No JSON found in response, treating as plain text...');\n reviewData = {\n issues: [\n {\n file: 'AI_RESPONSE',\n line: 1,\n ruleId: 'ai/raw_response',\n message: response,\n severity: 'info',\n category: 'documentation',\n },\n ],\n };\n }\n }\n }\n\n // Check if this is a custom schema (free-form data)\n // Custom schemas are:\n // 1. Inline schemas (effectiveSchema === 'custom')\n // 2. File-based custom schemas (starts with ./ or contains .json)\n // 3. Any schema that is NOT 'code-review' or other built-in schemas\n const isCustomSchema =\n _schema === 'custom' ||\n (_schema && (_schema.startsWith('./') || _schema.endsWith('.json'))) ||\n (_schema && _schema !== 'code-review' && !_schema.includes('output/'));\n\n if (isCustomSchema) {\n // For custom schemas, preserve ALL fields from the parsed JSON\n // Don't force the response into the standard ReviewSummary format\n log('📋 Custom schema detected - preserving all fields from parsed JSON');\n log(`📊 Schema: ${_schema}`);\n log(`📊 Custom schema keys: ${Object.keys(reviewData).join(', ')}`);\n\n // Return the full parsed data as the output, with an empty issues array\n // This allows downstream checks to access all custom fields via outputs\n const result: ReviewSummary & { output?: unknown } = {\n issues: [], // Empty array for custom schemas (no code review issues)\n output: reviewData, // Preserve ALL custom schema fields here\n };\n\n log('✅ Successfully created ReviewSummary with custom schema output');\n return result;\n }\n\n // Standard code-review schema processing\n log('🔍 Validating parsed review data...');\n log(`📊 Overall score: ${0}`);\n log(`📋 Total issues: ${reviewData.issues?.length || 0}`);\n log(\n `🚨 Critical issues: ${reviewData.issues?.filter((i: { severity?: string }) => i.severity === 'critical').length || 0}`\n );\n log(`💬 Comments count: ${Array.isArray(reviewData.issues) ? reviewData.issues.length : 0}`);\n\n // Process issues from the simplified format\n const processedIssues = Array.isArray(reviewData.issues)\n ? reviewData.issues.map((issue, index) => {\n log(`🔍 Processing issue ${index + 1}:`, issue);\n return {\n file: issue.file || 'unknown',\n line: issue.line || 1,\n endLine: issue.endLine,\n ruleId: issue.ruleId || `${issue.category || 'general'}/unknown`,\n message: issue.message || '',\n severity: issue.severity,\n category: issue.category,\n suggestion: issue.suggestion,\n replacement: issue.replacement,\n } as ReviewIssue;\n })\n : [];\n\n // Validate and convert to ReviewSummary format\n const result: ReviewSummary = {\n issues: processedIssues,\n };\n\n // Log issue counts\n const criticalCount = (result.issues || []).filter(i => i.severity === 'critical').length;\n if (criticalCount > 0) {\n log(`🚨 Found ${criticalCount} critical severity issue(s)`);\n }\n log(`📈 Total issues: ${(result.issues || []).length}`);\n\n log('✅ Successfully created ReviewSummary');\n return result;\n } catch (error) {\n console.error('❌ Failed to parse AI response:', error);\n console.error('📄 FULL RAW RESPONSE:');\n console.error('='.repeat(80));\n console.error(response);\n console.error('='.repeat(80));\n console.error(`📏 Response length: ${response.length} characters`);\n\n // Try to provide more helpful error information\n if (error instanceof SyntaxError) {\n console.error('🔍 JSON parsing error - the response may not be valid JSON');\n console.error('🔍 Error details:', error.message);\n\n // Try to identify where the parsing failed\n const errorMatch = error.message.match(/position (\\d+)/);\n if (errorMatch) {\n const position = parseInt(errorMatch[1]);\n console.error(`🔍 Error at position ${position}:`);\n const start = Math.max(0, position - 50);\n const end = Math.min(response.length, position + 50);\n console.error(`🔍 Context: \"${response.substring(start, end)}\"`);\n\n // Show the first 100 characters to understand what format the AI returned\n console.error(`🔍 Response beginning: \"${response.substring(0, 100)}\"`);\n }\n\n // Check if response contains common non-JSON patterns\n if (response.includes('I cannot')) {\n console.error('🔍 Response appears to be a refusal/explanation rather than JSON');\n }\n if (response.includes('```')) {\n console.error('🔍 Response appears to contain markdown code blocks');\n }\n if (response.startsWith('<')) {\n console.error('🔍 Response appears to start with XML/HTML');\n }\n }\n\n throw new Error(\n `Invalid AI response format: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Extract JSON from a response that might contain surrounding text\n * Uses proper bracket matching to find valid JSON objects or arrays\n */\n private extractJsonFromResponse(response: string): string | null {\n const text = response.trim();\n\n // Try to find JSON objects first (higher priority)\n let bestJson = this.findJsonWithBracketMatching(text, '{', '}');\n\n // If no object found, try arrays\n if (!bestJson) {\n bestJson = this.findJsonWithBracketMatching(text, '[', ']');\n }\n\n return bestJson;\n }\n\n /**\n * Find JSON with proper bracket matching to avoid false positives\n */\n private findJsonWithBracketMatching(\n text: string,\n openChar: string,\n closeChar: string\n ): string | null {\n const firstIndex = text.indexOf(openChar);\n if (firstIndex === -1) return null;\n\n let depth = 0;\n let inString = false;\n let escaping = false;\n\n for (let i = firstIndex; i < text.length; i++) {\n const char = text[i];\n\n if (escaping) {\n escaping = false;\n continue;\n }\n\n if (char === '\\\\' && inString) {\n escaping = true;\n continue;\n }\n\n if (char === '\"' && !escaping) {\n inString = !inString;\n continue;\n }\n\n if (!inString) {\n if (char === openChar) {\n depth++;\n } else if (char === closeChar) {\n depth--;\n if (depth === 0) {\n // Found matching closing bracket\n const candidate = text.substring(firstIndex, i + 1);\n try {\n JSON.parse(candidate); // Validate it's actually valid JSON\n return candidate;\n } catch {\n // This wasn't valid JSON, keep looking\n break;\n }\n }\n }\n }\n }\n\n return null;\n }\n\n /**\n * Generate mock response for testing\n */\n private async generateMockResponse(_prompt: string): Promise<string> {\n // Simulate some processing time\n await new Promise(resolve => setTimeout(resolve, 500));\n\n // Generate mock response based on prompt content\n const mockResponse = {\n content: JSON.stringify({\n issues: [\n {\n file: 'test.ts',\n line: 7,\n endLine: 11,\n ruleId: 'security/sql-injection',\n message: 'SQL injection vulnerability detected in dynamic query construction',\n severity: 'critical',\n category: 'security',\n suggestion: 'Use parameterized queries or ORM methods to prevent SQL injection',\n },\n {\n file: 'test.ts',\n line: 14,\n endLine: 23,\n ruleId: 'performance/nested-loops',\n message: 'Inefficient nested loops with O(n²) complexity',\n severity: 'warning',\n category: 'performance',\n suggestion: 'Consider using more efficient algorithms or caching mechanisms',\n },\n {\n file: 'test.ts',\n line: 28,\n ruleId: 'style/inconsistent-naming',\n message: 'Inconsistent variable naming and formatting',\n severity: 'info',\n category: 'style',\n suggestion: 'Use consistent camelCase naming and proper spacing',\n },\n ],\n summary: {\n totalIssues: 3,\n criticalIssues: 1,\n },\n }),\n };\n\n return JSON.stringify(mockResponse);\n }\n\n /**\n * Get the API key source for debugging (without revealing the key)\n */\n private getApiKeySource(): string {\n if (process.env.CLAUDE_CODE_API_KEY && this.config.provider === 'claude-code') {\n return 'CLAUDE_CODE_API_KEY';\n }\n if (process.env.GOOGLE_API_KEY && this.config.provider === 'google') {\n return 'GOOGLE_API_KEY';\n }\n if (process.env.ANTHROPIC_API_KEY && this.config.provider === 'anthropic') {\n return 'ANTHROPIC_API_KEY';\n }\n if (process.env.OPENAI_API_KEY && this.config.provider === 'openai') {\n return 'OPENAI_API_KEY';\n }\n if (this.config.provider === 'bedrock') {\n if (process.env.AWS_BEDROCK_API_KEY) {\n return 'AWS_BEDROCK_API_KEY';\n }\n if (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) {\n return 'AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY';\n }\n }\n return 'unknown';\n }\n}\n","import { Octokit } from '@octokit/rest';\nimport { PRInfo } from './pr-analyzer';\nimport { CommentManager } from './github-comments';\nimport { AIReviewService, AIDebugInfo } from './ai-review-service';\n\nexport interface ReviewIssue {\n // Location\n file: string;\n line: number;\n endLine?: number;\n // Issue details\n ruleId: string;\n message: string;\n severity: 'info' | 'warning' | 'error' | 'critical';\n category: 'security' | 'performance' | 'style' | 'logic' | 'documentation';\n // Check identification - which check created this issue\n checkName?: string;\n // Group and schema for comment separation\n group?: string;\n schema?: string;\n // Timestamp when the issue was created (for ordering)\n timestamp?: number;\n // Optional enhancement\n suggestion?: string;\n replacement?: string;\n}\n\n// Legacy interface - ONLY for GitHub integration compatibility\nexport interface ReviewComment {\n file: string;\n line: number;\n message: string;\n severity: 'info' | 'warning' | 'error' | 'critical';\n category: 'security' | 'performance' | 'style' | 'logic' | 'documentation';\n suggestion?: string;\n replacement?: string;\n ruleId?: string;\n}\n\n// Individual check result - each check produces one of these\nexport interface CheckResult {\n checkName: string;\n content: string; // Rendered output for this specific check\n group: string; // Which group this check belongs to\n // Optional structured output for custom schemas (e.g., overview, issue-assistant)\n output?: unknown;\n debug?: AIDebugInfo;\n issues?: ReviewIssue[]; // Structured issues alongside rendered content\n}\n\n// Results grouped by group name\nexport interface GroupedCheckResults {\n [groupName: string]: CheckResult[];\n}\n\n// Legacy interface - only for backward compatibility\nexport interface ReviewSummary {\n issues?: ReviewIssue[];\n debug?: AIDebugInfo;\n /** Session ID created for this check (for cleanup tracking) */\n sessionId?: string;\n}\n\n// Test utility function - Convert old ReviewSummary to new GroupedCheckResults format\n// This is for backward compatibility with tests only\nexport function convertReviewSummaryToGroupedResults(\n reviewSummary: ReviewSummary,\n checkName: string = 'test-check',\n groupName: string = 'default'\n): GroupedCheckResults {\n // Create a simple content string from issues\n let content = '';\n\n if (reviewSummary.issues && reviewSummary.issues.length > 0) {\n content += `## Issues Found (${reviewSummary.issues.length})\\n\\n`;\n reviewSummary.issues.forEach(issue => {\n content += `- **${issue.severity.toUpperCase()}**: ${issue.message} (${issue.file}:${issue.line})\\n`;\n });\n content += '\\n';\n }\n\n if (!content) {\n content = 'No issues found.';\n }\n\n const checkResult: CheckResult = {\n checkName,\n content: content.trim(),\n group: groupName,\n debug: reviewSummary.debug,\n issues: reviewSummary.issues, // Include structured issues\n };\n\n const groupedResults: GroupedCheckResults = {};\n groupedResults[groupName] = [checkResult];\n\n return groupedResults;\n}\n\n// Helper functions for GitHub checks - ONLY for structured schemas that have issues\n// These are the ONLY acceptable hardcoded schema dependencies, and only for GitHub integration\nexport function calculateTotalIssues(issues?: ReviewIssue[]): number {\n return (issues || []).length;\n}\n\nexport function calculateCriticalIssues(issues?: ReviewIssue[]): number {\n return (issues || []).filter(i => i.severity === 'critical').length;\n}\n\n// Legacy converter - ONLY for GitHub integration compatibility\nexport function convertIssuesToComments(issues: ReviewIssue[]): ReviewComment[] {\n return issues.map(issue => ({\n file: issue.file,\n line: issue.line,\n message: issue.message,\n severity: issue.severity,\n category: issue.category,\n suggestion: issue.suggestion,\n replacement: issue.replacement,\n ruleId: issue.ruleId,\n }));\n}\n\nexport interface ReviewOptions {\n focus?: 'security' | 'performance' | 'style' | 'all';\n format?: 'table' | 'json' | 'markdown' | 'sarif';\n debug?: boolean;\n config?: import('./types/config').VisorConfig;\n checks?: string[];\n parallelExecution?: boolean;\n // Optional tag filter to include/exclude checks by tags when running via GitHub Action path\n tagFilter?: import('./types/config').TagFilter;\n}\n\nexport class PRReviewer {\n private commentManager: CommentManager;\n private aiReviewService: AIReviewService;\n\n constructor(private octokit: Octokit) {\n this.commentManager = new CommentManager(octokit);\n this.aiReviewService = new AIReviewService();\n }\n\n async reviewPR(\n owner: string,\n repo: string,\n prNumber: number,\n prInfo: PRInfo,\n options: ReviewOptions = {}\n ): Promise<GroupedCheckResults> {\n const { debug = false, config, checks } = options;\n\n if (config && checks && checks.length > 0) {\n const { CheckExecutionEngine } = await import('./check-execution-engine');\n const engine = new CheckExecutionEngine();\n const { results } = await engine.executeGroupedChecks(\n prInfo,\n checks,\n undefined,\n config,\n undefined,\n debug,\n undefined,\n undefined,\n options.tagFilter\n );\n return results;\n }\n\n throw new Error(\n 'No configuration provided. Please create a .visor.yaml file with check definitions. ' +\n 'Built-in prompts have been removed - all checks must be explicitly configured.'\n );\n }\n\n /**\n * Helper to check if a schema definition has a \"text\" field in its properties\n */\n private async schemaHasTextField(schema: string | Record<string, unknown>): Promise<boolean> {\n try {\n let schemaObj: Record<string, unknown>;\n\n if (typeof schema === 'object') {\n // Inline schema object\n schemaObj = schema;\n } else {\n // String reference - load the schema\n const fs = require('fs').promises;\n const path = require('path');\n\n // Sanitize schema name\n const sanitizedSchemaName = schema.replace(/[^a-zA-Z0-9-]/g, '');\n if (!sanitizedSchemaName || sanitizedSchemaName !== schema) {\n return false;\n }\n\n // Construct path to built-in schema file\n const schemaPath = path.join(process.cwd(), 'output', sanitizedSchemaName, 'schema.json');\n\n try {\n const schemaContent = await fs.readFile(schemaPath, 'utf-8');\n schemaObj = JSON.parse(schemaContent);\n } catch {\n // Schema file not found or invalid, return false\n return false;\n }\n }\n\n // Check if schema has a \"text\" field in properties\n const properties = schemaObj.properties as Record<string, unknown> | undefined;\n return !!(properties && 'text' in properties);\n } catch {\n return false;\n }\n }\n\n /**\n * Filter check results to only include those that should post GitHub comments\n */\n private async filterCommentGeneratingChecks(\n checkResults: CheckResult[],\n config: import('./types/config').VisorConfig\n ): Promise<CheckResult[]> {\n const filtered: CheckResult[] = [];\n\n for (const r of checkResults) {\n const cfg = config.checks?.[r.checkName];\n const type = cfg?.type || 'ai'; // Default to 'ai' if not specified\n const schema = cfg?.schema;\n\n // Determine if this check should generate a comment\n // Include checks with:\n // 1. type: 'ai' or 'claude-code' with no schema or comment-generating schemas\n // 2. Other types ONLY if they have explicit comment-generating schemas\n let shouldPostComment = false;\n\n // AI-powered checks generate comments by default\n const isAICheck = type === 'ai' || type === 'claude-code';\n\n if (!schema || schema === '') {\n // No schema specified - only AI checks generate comments by default\n // Other types (github, command, http, etc.) without schema are for orchestration\n shouldPostComment = isAICheck;\n } else if (typeof schema === 'string') {\n // String schema - check if it's a known plain text schema OR has a text field\n if (schema === 'text' || schema === 'plain') {\n shouldPostComment = true;\n } else {\n // Load the schema and check if it has a text field\n shouldPostComment = await this.schemaHasTextField(schema);\n }\n } else if (typeof schema === 'object') {\n // Custom inline schema object - check if it has a \"text\" field in properties\n shouldPostComment = await this.schemaHasTextField(schema);\n }\n\n if (shouldPostComment) {\n filtered.push(r);\n }\n }\n\n return filtered;\n }\n\n async postReviewComment(\n owner: string,\n repo: string,\n prNumber: number,\n groupedResults: GroupedCheckResults,\n options: ReviewOptions & { commentId?: string; triggeredBy?: string; commitSha?: string } = {}\n ): Promise<void> {\n // Post separate comments for each group\n for (const [groupName, checkResults] of Object.entries(groupedResults)) {\n // Only checks with comment-generating schemas should post PR comments\n // AI checks (ai, claude-code) generate comments by default\n // Other types need explicit comment-generating schemas\n const filteredResults = options.config\n ? await this.filterCommentGeneratingChecks(checkResults, options.config)\n : checkResults;\n\n // If nothing to report after filtering, skip this group\n if (!filteredResults || filteredResults.length === 0) {\n continue;\n }\n\n const comment = await this.formatGroupComment(filteredResults, options, {\n owner,\n repo,\n prNumber,\n commitSha: options.commitSha,\n });\n\n // Generate comment ID - use unique ID for \"dynamic\" group\n let commentId: string;\n if (groupName === 'dynamic') {\n // Dynamic group creates a new comment each time with timestamp-based ID\n const timestamp = Date.now();\n commentId = `visor-dynamic-${timestamp}`;\n } else {\n // Regular groups use static IDs that get updated\n commentId = options.commentId\n ? `${options.commentId}-${groupName}`\n : `visor-review-${groupName}`;\n }\n\n // Do not post empty comments (possible if content is blank after fallbacks)\n if (!comment || !comment.trim()) continue;\n\n await this.commentManager.updateOrCreateComment(owner, repo, prNumber, comment, {\n commentId,\n triggeredBy: options.triggeredBy || 'unknown',\n allowConcurrentUpdates: false,\n commitSha: options.commitSha,\n });\n }\n }\n\n private async formatGroupComment(\n checkResults: CheckResult[],\n _options: ReviewOptions,\n _githubContext?: { owner: string; repo: string; prNumber: number; commitSha?: string }\n ): Promise<string> {\n // Concatenate all check outputs in this group; fall back to structured output fields\n const normalize = (s: string) => s.replace(/\\\\n/g, '\\n');\n const checkContents = checkResults\n .map(result => {\n const trimmed = result.content?.trim();\n if (trimmed) return normalize(trimmed);\n // Fallback: if provider returned structured output with a common text field\n const out = (result as unknown as { debug?: unknown; issues?: unknown; output?: any })\n .output;\n if (out) {\n if (typeof out === 'string' && out.trim()) return normalize(out.trim());\n if (typeof out === 'object') {\n const txt = (out.text || out.response || out.message) as unknown;\n if (typeof txt === 'string' && txt.trim()) return normalize(txt.trim());\n }\n }\n return '';\n })\n .filter(content => content && content.trim());\n\n // Add debug info if any check has it\n const debugInfo = checkResults.find(result => result.debug)?.debug;\n\n // Only generate comment if there's actual content or debug info\n if (checkContents.length === 0 && !debugInfo) {\n return '';\n }\n\n let comment = '';\n comment += `## 🔍 Code Analysis Results\\n\\n`;\n comment += checkContents.join('\\n\\n');\n\n if (debugInfo) {\n comment += '\\n\\n' + this.formatDebugSection(debugInfo);\n comment += '\\n\\n';\n }\n\n // Footer will be added by formatCommentWithMetadata in github-comments.ts\n return comment;\n }\n\n private formatDebugSection(debug: AIDebugInfo): string {\n const formattedContent = [\n `**Provider:** ${debug.provider}`,\n `**Model:** ${debug.model}`,\n `**API Key Source:** ${debug.apiKeySource}`,\n `**Processing Time:** ${debug.processingTime}ms`,\n `**Timestamp:** ${debug.timestamp}`,\n `**Prompt Length:** ${debug.promptLength} characters`,\n `**Response Length:** ${debug.responseLength} characters`,\n `**JSON Parse Success:** ${debug.jsonParseSuccess ? '✅' : '❌'}`,\n ];\n\n if (debug.errors && debug.errors.length > 0) {\n formattedContent.push('', '### Errors');\n debug.errors.forEach(error => {\n formattedContent.push(`- ${error}`);\n });\n }\n\n const fullDebugContent = [\n ...formattedContent,\n '',\n '### AI Prompt',\n '```',\n debug.prompt,\n '```',\n '',\n '### Raw AI Response',\n '```json',\n debug.rawResponse,\n '```',\n ].join('\\n');\n\n if (fullDebugContent.length > 60000) {\n const artifactPath = this.saveDebugArtifact(debug);\n formattedContent.push('');\n formattedContent.push('### Debug Details');\n formattedContent.push('⚠️ Debug information is too large for GitHub comments.');\n if (artifactPath) {\n formattedContent.push(\n `📁 **Full debug information saved to artifact:** \\`${artifactPath}\\``\n );\n formattedContent.push('');\n const runId = process.env.GITHUB_RUN_ID;\n const repoUrl =\n process.env.GITHUB_SERVER_URL && process.env.GITHUB_REPOSITORY\n ? `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}`\n : null;\n if (runId && repoUrl) {\n formattedContent.push(\n `🔗 **Download Link:** [visor-debug-${process.env.GITHUB_RUN_NUMBER || runId}](${repoUrl}/actions/runs/${runId})`\n );\n }\n formattedContent.push(\n '💡 Go to the GitHub Action run above and download the debug artifact to view complete prompts and responses.'\n );\n } else {\n formattedContent.push('📝 **Prompt preview:** ' + debug.prompt.substring(0, 500) + '...');\n formattedContent.push(\n '📝 **Response preview:** ' + debug.rawResponse.substring(0, 500) + '...'\n );\n }\n } else {\n formattedContent.push('');\n formattedContent.push('### AI Prompt');\n formattedContent.push('```');\n formattedContent.push(debug.prompt);\n formattedContent.push('```');\n formattedContent.push('');\n formattedContent.push('### Raw AI Response');\n formattedContent.push('```json');\n formattedContent.push(debug.rawResponse);\n formattedContent.push('```');\n }\n\n return this.commentManager.createCollapsibleSection(\n '🐛 Debug Information',\n formattedContent.join('\\n'),\n false\n );\n }\n\n private saveDebugArtifact(debug: AIDebugInfo): string | null {\n try {\n const fs = require('fs');\n const path = require('path');\n const debugDir = path.join(process.cwd(), 'debug-artifacts');\n if (!fs.existsSync(debugDir)) {\n fs.mkdirSync(debugDir, { recursive: true });\n }\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const filename = `visor-debug-${timestamp}.md`;\n const filepath = path.join(debugDir, filename);\n\n const content = [\n `# Visor Debug Information`,\n ``,\n `**Timestamp:** ${debug.timestamp}`,\n `**Provider:** ${debug.provider}`,\n `**Model:** ${debug.model}`,\n `**Processing Time:** ${debug.processingTime}ms`,\n ``,\n `## AI Prompt`,\n ``,\n '```',\n debug.prompt,\n '```',\n ``,\n `## Raw AI Response`,\n ``,\n '```json',\n debug.rawResponse,\n '```',\n ].join('\\n');\n\n fs.writeFileSync(filepath, content, 'utf8');\n return filename;\n } catch (error) {\n console.error('Failed to save debug artifact:', error);\n return null;\n }\n }\n}\n","import { simpleGit, SimpleGit, type DefaultLogFields, type ListLogLine } from 'simple-git';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport { PRInfo, PRDiff } from './pr-analyzer';\n\nexport interface GitFileChange {\n filename: string;\n status: 'added' | 'removed' | 'modified' | 'renamed';\n additions: number;\n deletions: number;\n changes: number;\n content?: string;\n patch?: string;\n truncated?: boolean;\n}\n\n// Maximum patch size in bytes (50KB) - helps prevent token limit issues\nconst MAX_PATCH_SIZE = 50 * 1024;\n\nexport interface GitRepositoryInfo {\n title: string;\n body: string;\n author: string;\n base: string;\n head: string;\n files: GitFileChange[];\n totalAdditions: number;\n totalDeletions: number;\n isGitRepository: boolean;\n workingDirectory: string;\n}\n\nexport class GitRepositoryAnalyzer {\n private git: SimpleGit;\n private cwd: string;\n\n constructor(workingDirectory: string = process.cwd()) {\n this.cwd = workingDirectory;\n this.git = simpleGit(workingDirectory);\n }\n\n /**\n * Analyze the current git repository state and return data compatible with PRInfo interface\n */\n async analyzeRepository(\n includeContext: boolean = true,\n enableBranchDiff: boolean = false\n ): Promise<GitRepositoryInfo> {\n // Check if we're in a git repository\n const isRepo = await this.isGitRepository();\n if (!isRepo) {\n return this.createEmptyRepositoryInfo('Not a git repository');\n }\n\n try {\n // Get current branch and status\n const [status, currentBranch, baseBranch] = await Promise.all([\n this.git.status(),\n this.getCurrentBranch(),\n this.getBaseBranch(),\n ]);\n\n // Determine if we're on a feature branch\n const isFeatureBranch =\n currentBranch !== baseBranch && currentBranch !== 'main' && currentBranch !== 'master';\n\n // Get uncommitted changes first\n let uncommittedFiles = await this.getUncommittedChanges(includeContext);\n\n // If branch diff is explicitly enabled, use branch diff (ignoring uncommitted changes)\n // Otherwise, if on a feature branch with no uncommitted changes AND branch diff is enabled, get diff vs base branch\n if (isFeatureBranch && includeContext && enableBranchDiff) {\n if (uncommittedFiles.length > 0) {\n console.error(`📊 Feature branch detected: ${currentBranch}`);\n console.error(\n `⚠️ Ignoring ${uncommittedFiles.length} uncommitted file(s) due to --analyze-branch-diff flag`\n );\n } else {\n console.error(`📊 Feature branch detected: ${currentBranch}`);\n }\n console.error(\n `📂 Analyzing diff vs ${baseBranch} (${uncommittedFiles.length > 0 ? 'forced by --analyze-branch-diff' : 'auto-enabled for code-review schemas'})`\n );\n uncommittedFiles = await this.getBranchDiff(baseBranch, includeContext);\n } else if (uncommittedFiles.length > 0) {\n console.error(`📝 Analyzing uncommitted changes (${uncommittedFiles.length} files)`);\n }\n\n // Get recent commit info (handle repos with no commits)\n let lastCommit: (ListLogLine & DefaultLogFields) | null = null;\n try {\n const recentCommits = await this.git.log({ maxCount: 1 });\n lastCommit = recentCommits.latest;\n } catch {\n // Repository has no commits yet - this is OK\n console.error('📝 Repository has no commits yet, analyzing uncommitted changes');\n }\n\n // Get author from git config if no commits exist\n let author = lastCommit?.author_name;\n if (!author) {\n try {\n // Read ONLY repository-local config to avoid leaking global user identity into tests\n const [userName, userEmail] = await Promise.all([\n this.git.raw(['config', '--local', 'user.name']).catch(() => null),\n this.git.raw(['config', '--local', 'user.email']).catch(() => null),\n ]);\n author = userName?.trim() || userEmail?.trim() || 'unknown';\n } catch {\n author = 'unknown';\n }\n }\n\n // Create repository info\n const repositoryInfo: GitRepositoryInfo = {\n title: this.generateTitle(status, currentBranch),\n body: this.generateDescription(status, lastCommit),\n author,\n base: baseBranch,\n head: currentBranch,\n files: uncommittedFiles,\n totalAdditions: uncommittedFiles.reduce((sum, file) => sum + file.additions, 0),\n totalDeletions: uncommittedFiles.reduce((sum, file) => sum + file.deletions, 0),\n isGitRepository: true,\n workingDirectory: this.cwd,\n };\n\n return repositoryInfo;\n } catch (error) {\n // Don't log the full error object to avoid confusing stack traces\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n console.error('Error analyzing git repository:', errorMessage);\n return this.createEmptyRepositoryInfo('Error analyzing git repository');\n }\n }\n\n /**\n * Convert GitRepositoryInfo to PRInfo format for compatibility with existing PRReviewer\n */\n toPRInfo(repositoryInfo: GitRepositoryInfo, includeContext: boolean = true): PRInfo {\n const files = repositoryInfo.files.map(\n (file): PRDiff => ({\n filename: file.filename,\n additions: file.additions,\n deletions: file.deletions,\n changes: file.changes,\n patch: includeContext ? file.patch : undefined,\n status: file.status,\n })\n );\n\n // Generate fullDiff from patches if includeContext is true\n let fullDiff: string | undefined;\n if (includeContext) {\n fullDiff = files\n .filter(file => file.patch)\n .map(file => `--- ${file.filename}\\n${file.patch}`)\n .join('\\n\\n');\n }\n\n return {\n number: 0, // Local analysis doesn't have PR number\n title: repositoryInfo.title,\n body: repositoryInfo.body,\n author: repositoryInfo.author,\n base: repositoryInfo.base,\n head: repositoryInfo.head,\n files,\n totalAdditions: repositoryInfo.totalAdditions,\n totalDeletions: repositoryInfo.totalDeletions,\n fullDiff,\n };\n }\n\n private async isGitRepository(): Promise<boolean> {\n try {\n await this.git.checkIsRepo();\n return true;\n } catch {\n return false;\n }\n }\n\n private async getCurrentBranch(): Promise<string> {\n try {\n const branchSummary = await this.git.branch();\n return branchSummary.current || 'unknown';\n } catch {\n return 'unknown';\n }\n }\n\n private async getBaseBranch(): Promise<string> {\n try {\n // Try to get the default branch from remote\n const branches = await this.git.branch(['-r']);\n const mainBranches = ['origin/main', 'origin/master', 'origin/develop'];\n\n for (const mainBranch of mainBranches) {\n if (branches.all.includes(mainBranch)) {\n return mainBranch.replace('origin/', '');\n }\n }\n\n // Fallback to main/master\n return 'main';\n } catch {\n return 'main';\n }\n }\n\n /**\n * Check if a file should be excluded from analysis\n * This includes:\n * - Files in .gitignore (even if force-added)\n * - Built/generated files (dist/, build/, .next/, etc.)\n */\n private async shouldExcludeFile(filename: string): Promise<boolean> {\n // Check common build directories that should be excluded even if tracked\n const excludePatterns = [\n /^dist\\//,\n /^build\\//,\n /^\\.next\\//,\n /^out\\//,\n /^node_modules\\//,\n /^coverage\\//,\n /^\\.turbo\\//,\n ];\n\n for (const pattern of excludePatterns) {\n if (pattern.test(filename)) {\n return true;\n }\n }\n\n // Also check if file is in .gitignore\n try {\n const result = await this.git.raw(['check-ignore', filename]);\n return result.trim().length > 0;\n } catch {\n // If check-ignore returns non-zero exit code, the file is not ignored\n return false;\n }\n }\n\n /**\n * Truncate a patch if it exceeds MAX_PATCH_SIZE\n */\n private truncatePatch(patch: string, filename: string): { patch: string; truncated: boolean } {\n const patchSize = Buffer.byteLength(patch, 'utf8');\n\n if (patchSize <= MAX_PATCH_SIZE) {\n return { patch, truncated: false };\n }\n\n // Truncate to MAX_PATCH_SIZE and add a notice\n const truncated = patch.substring(0, MAX_PATCH_SIZE);\n const truncatedPatch = `${truncated}\\n\\n... [TRUNCATED: Diff too large (${(patchSize / 1024).toFixed(1)}KB), showing first ${(MAX_PATCH_SIZE / 1024).toFixed(0)}KB] ...`;\n\n console.error(\n `⚠️ Truncated diff for ${filename} (${(patchSize / 1024).toFixed(1)}KB → ${(MAX_PATCH_SIZE / 1024).toFixed(0)}KB)`\n );\n\n return { patch: truncatedPatch, truncated: true };\n }\n\n private async getRemoteInfo(): Promise<{ name: string; url: string } | null> {\n try {\n const remotes = await this.git.getRemotes(true);\n const origin = remotes.find(r => r.name === 'origin');\n return origin\n ? { name: origin.name, url: origin.refs.fetch || origin.refs.push || '' }\n : null;\n } catch {\n return null;\n }\n }\n\n private async getUncommittedChanges(includeContext: boolean = true): Promise<GitFileChange[]> {\n try {\n const status = await this.git.status();\n const changes: GitFileChange[] = [];\n\n // Process different types of changes\n const fileChanges = [\n ...status.created.map(f => ({ file: f, status: 'added' as const })),\n ...status.deleted.map(f => ({ file: f, status: 'removed' as const })),\n ...status.modified.map(f => ({ file: f, status: 'modified' as const })),\n ...status.renamed.map(f => ({\n file: typeof f === 'string' ? f : f.to || f.from,\n status: 'renamed' as const,\n })),\n ];\n\n for (const { file, status } of fileChanges) {\n // Skip files that should be excluded from analysis\n if (await this.shouldExcludeFile(file)) {\n console.error(`⏭️ Skipping excluded file: ${file}`);\n continue;\n }\n\n const filePath = path.join(this.cwd, file);\n const fileChange = await this.analyzeFileChange(file, status, filePath, includeContext);\n changes.push(fileChange);\n }\n\n return changes;\n } catch (error) {\n console.error('Error getting uncommitted changes:', error);\n return [];\n }\n }\n\n /**\n * Get diff between current branch and base branch (for feature branch analysis)\n */\n private async getBranchDiff(\n baseBranch: string,\n includeContext: boolean = true\n ): Promise<GitFileChange[]> {\n try {\n // Get the list of changed files between base and current branch\n const diffSummary = await this.git.diffSummary([baseBranch]);\n const changes: GitFileChange[] = [];\n\n if (!diffSummary || !diffSummary.files) {\n return [];\n }\n\n for (const file of diffSummary.files) {\n // Skip files that should be excluded from analysis\n if (await this.shouldExcludeFile(file.file)) {\n console.error(`⏭️ Skipping excluded file: ${file.file}`);\n continue;\n }\n\n // Handle different file types (binary files don't have insertions/deletions)\n const isBinary = 'binary' in file && file.binary;\n const insertions = 'insertions' in file ? file.insertions : 0;\n const deletions = 'deletions' in file ? file.deletions : 0;\n const fileChanges = 'changes' in file ? file.changes : 0;\n\n // Determine status based on insertions/deletions\n let status: 'added' | 'removed' | 'modified' | 'renamed';\n if (isBinary) {\n status = 'modified';\n } else if (insertions > 0 && deletions === 0) {\n status = 'added';\n } else if (insertions === 0 && deletions > 0) {\n status = 'removed';\n } else {\n status = 'modified';\n }\n\n // Get the actual diff patch if needed\n let patch: string | undefined;\n let truncated = false;\n if (includeContext && !isBinary) {\n try {\n const rawPatch = await this.git.diff([baseBranch, '--', file.file]);\n if (rawPatch) {\n const result = this.truncatePatch(rawPatch, file.file);\n patch = result.patch;\n truncated = result.truncated;\n }\n } catch {\n // Ignore diff errors for specific files\n }\n }\n\n const fileChange: GitFileChange = {\n filename: file.file,\n additions: insertions,\n deletions: deletions,\n changes: fileChanges,\n status,\n patch,\n truncated,\n };\n\n changes.push(fileChange);\n }\n\n return changes;\n } catch (error) {\n console.error('Error getting branch diff:', error);\n return [];\n }\n }\n\n private async analyzeFileChange(\n filename: string,\n status: 'added' | 'removed' | 'modified' | 'renamed',\n filePath: string,\n includeContext: boolean = true\n ): Promise<GitFileChange> {\n let additions = 0;\n let deletions = 0;\n let patch: string | undefined;\n let content: string | undefined;\n let truncated = false;\n\n try {\n // Get diff for the file if it exists and is not binary\n if (includeContext && status !== 'added' && fs.existsSync(filePath)) {\n const diff = await this.git.diff(['--', filename]).catch(() => '');\n if (diff) {\n const result = this.truncatePatch(diff, filename);\n patch = result.patch;\n truncated = result.truncated;\n // Count additions and deletions from diff\n const lines = diff.split('\\n');\n additions = lines.filter(line => line.startsWith('+')).length;\n deletions = lines.filter(line => line.startsWith('-')).length;\n }\n } else if (status !== 'added' && fs.existsSync(filePath)) {\n // If not including context, still count changes for statistics\n const diff = await this.git.diff(['--', filename]).catch(() => '');\n if (diff) {\n const lines = diff.split('\\n');\n additions = lines.filter(line => line.startsWith('+')).length;\n deletions = lines.filter(line => line.startsWith('-')).length;\n }\n }\n\n // For added files\n if (status === 'added' && fs.existsSync(filePath)) {\n try {\n const stats = fs.statSync(filePath);\n if (stats.isFile() && stats.size < 1024 * 1024) {\n // Skip files larger than 1MB\n if (includeContext) {\n content = fs.readFileSync(filePath, 'utf8');\n const result = this.truncatePatch(content, filename);\n patch = result.patch; // For new files, the entire content is the \"patch\"\n truncated = result.truncated;\n }\n // Always count additions for statistics\n const fileContent = includeContext ? content : fs.readFileSync(filePath, 'utf8');\n additions = fileContent!.split('\\n').length;\n }\n } catch {\n // Skip binary or unreadable files\n }\n }\n\n // For removed files, we can't easily count the lines without the previous version\n if (status === 'removed') {\n deletions = 1; // Placeholder - in real git we'd need the previous version\n }\n } catch (error) {\n console.error(`Error analyzing file change for ${filename}:`, error);\n }\n\n return {\n filename,\n status,\n additions,\n deletions,\n changes: additions + deletions,\n content,\n patch,\n truncated,\n };\n }\n\n private generateTitle(status: import('simple-git').StatusResult, branch: string): string {\n if (status.files.length === 0) {\n return `Local Analysis: ${branch} (No changes)`;\n }\n\n const changeTypes = [];\n if (status.created.length > 0) changeTypes.push(`${status.created.length} added`);\n if (status.modified.length > 0) changeTypes.push(`${status.modified.length} modified`);\n if (status.deleted.length > 0) changeTypes.push(`${status.deleted.length} deleted`);\n if (status.renamed.length > 0) changeTypes.push(`${status.renamed.length} renamed`);\n\n return `Local Analysis: ${branch} (${changeTypes.join(', ')})`;\n }\n\n private generateDescription(\n status: import('simple-git').StatusResult,\n lastCommit: import('simple-git').DefaultLogFields | null\n ): string {\n let description = `Analysis of local git repository working directory.\\n\\n`;\n\n if (lastCommit) {\n description += `**Last Commit:** ${lastCommit.message}\\n`;\n description += `**Author:** ${lastCommit.author_name} <${lastCommit.author_email}>\\n`;\n description += `**Date:** ${lastCommit.date}\\n\\n`;\n }\n\n if (status.files.length === 0) {\n description += `**Status:** Working directory is clean - no uncommitted changes found.\\n`;\n } else {\n description += `**Changes Summary:**\\n`;\n description += `- Files to be committed: ${status.staged.length}\\n`;\n description += `- Modified files: ${status.modified.length}\\n`;\n description += `- Untracked files: ${status.not_added.length}\\n`;\n\n if (status.conflicted.length > 0) {\n description += `- Conflicted files: ${status.conflicted.length}\\n`;\n }\n }\n\n return description;\n }\n\n private createEmptyRepositoryInfo(reason: string): GitRepositoryInfo {\n return {\n title: `Local Analysis: ${reason}`,\n body: `Unable to analyze repository: ${reason}`,\n author: 'system',\n base: 'main',\n head: 'HEAD',\n files: [],\n totalAdditions: 0,\n totalDeletions: 0,\n isGitRepository: false,\n workingDirectory: this.cwd,\n };\n }\n}\n","import { Octokit } from '@octokit/rest';\n\nexport interface PRFile {\n filename: string;\n additions: number;\n deletions: number;\n changes: number;\n patch?: string;\n status: 'added' | 'removed' | 'modified' | 'renamed';\n}\n\nexport interface PRDiff {\n filename: string;\n additions: number;\n deletions: number;\n changes: number;\n patch?: string;\n status: 'added' | 'removed' | 'modified' | 'renamed';\n}\n\nexport interface PRComment {\n id: number;\n author: string;\n body: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface PRInfo {\n number: number;\n title: string;\n body: string;\n author: string;\n authorAssociation?: string; // GitHub author_association: OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, etc.\n base: string;\n head: string;\n files: PRDiff[];\n totalAdditions: number;\n totalDeletions: number;\n eventType?: import('./types/config').EventTrigger;\n fullDiff?: string;\n commitDiff?: string;\n isIncremental?: boolean; // Flag to indicate if this was intended as incremental analysis\n isIssue?: boolean; // Flag to indicate this is an issue, not a PR\n eventContext?: Record<string, unknown>; // GitHub event context for templates\n comments?: PRComment[]; // Comments added dynamically\n labels?: string[]; // Labels applied to the PR (for behavior overrides)\n}\n\ninterface NetworkError {\n code?: string;\n message?: string;\n status?: number;\n}\n\nexport class PRAnalyzer {\n constructor(\n private octokit: Octokit,\n private maxRetries: number = 3\n ) {}\n\n /**\n * Fetch commit diff for incremental analysis\n */\n async fetchCommitDiff(owner: string, repo: string, commitSha: string): Promise<string> {\n try {\n const { data: commit } = await this.withRetry(() =>\n this.octokit.rest.repos.getCommit({\n owner,\n repo,\n ref: commitSha,\n })\n );\n\n // Extract patches from all files in the commit\n const patches =\n commit.files\n ?.filter(file => file.patch)\n .map(file => `--- ${file.filename}\\n${file.patch}`)\n .join('\\n\\n') || '';\n\n return patches;\n } catch (error) {\n console.warn(`Failed to fetch commit diff for ${commitSha}:`, error);\n return '';\n }\n }\n\n /**\n * Generate unified diff for all PR files\n */\n private generateFullDiff(files: PRDiff[]): string {\n return files\n .filter(file => file.patch)\n .map(file => `--- ${file.filename}\\n${file.patch}`)\n .join('\\n\\n');\n }\n\n async fetchPRDiff(\n owner: string,\n repo: string,\n prNumber: number,\n commitSha?: string,\n eventType?: import('./types/config').EventTrigger\n ): Promise<PRInfo> {\n const [prData, filesData] = await Promise.all([\n this.withRetry(() =>\n this.octokit.rest.pulls.get({\n owner,\n repo,\n pull_number: prNumber,\n })\n ),\n this.withRetry(() =>\n this.octokit.rest.pulls.listFiles({\n owner,\n repo,\n pull_number: prNumber,\n })\n ),\n ]);\n\n const pr = prData?.data;\n const files = filesData?.data || [];\n\n // Handle missing or malformed PR data gracefully\n if (!pr) {\n throw new Error('Invalid or missing pull request data');\n }\n\n // Validate critical fields and provide defaults for missing data\n const title = typeof pr.title === 'string' ? pr.title : pr.title ? String(pr.title) : 'MISSING';\n const body = typeof pr.body === 'string' ? pr.body : pr.body ? String(pr.body) : '';\n const author =\n pr.user && typeof pr.user === 'object' && pr.user.login\n ? typeof pr.user.login === 'string'\n ? pr.user.login\n : String(pr.user.login)\n : 'unknown';\n const authorAssociation =\n pr.author_association && typeof pr.author_association === 'string'\n ? pr.author_association\n : undefined;\n const base =\n pr.base && typeof pr.base === 'object' && pr.base.ref\n ? typeof pr.base.ref === 'string'\n ? pr.base.ref\n : String(pr.base.ref)\n : 'main';\n const head =\n pr.head && typeof pr.head === 'object' && pr.head.ref\n ? typeof pr.head.ref === 'string'\n ? pr.head.ref\n : String(pr.head.ref)\n : 'feature';\n\n // Filter out malformed files and handle invalid data types\n const validFiles = files\n ? files\n .filter(file => file && typeof file === 'object' && file.filename)\n .map(file => ({\n filename:\n typeof file.filename === 'string'\n ? file.filename\n : String(file.filename || 'unknown'),\n additions: typeof file.additions === 'number' ? Math.max(0, file.additions) : 0,\n deletions: typeof file.deletions === 'number' ? Math.max(0, file.deletions) : 0,\n changes: typeof file.changes === 'number' ? Math.max(0, file.changes) : 0,\n patch: typeof file.patch === 'string' ? file.patch : undefined,\n status: (['added', 'removed', 'modified', 'renamed'].includes(file.status)\n ? file.status\n : 'modified') as 'added' | 'removed' | 'modified' | 'renamed',\n }))\n .filter(file => file.filename.length > 0) // Remove files with empty names\n : [];\n\n const prInfo: PRInfo = {\n number: typeof pr.number === 'number' ? pr.number : parseInt(String(pr.number || 1), 10),\n title,\n body,\n author,\n authorAssociation,\n base,\n head,\n files: validFiles,\n totalAdditions: validFiles.reduce((sum, file) => sum + file.additions, 0),\n totalDeletions: validFiles.reduce((sum, file) => sum + file.deletions, 0),\n fullDiff: this.generateFullDiff(validFiles),\n eventType,\n };\n\n // Fetch comment history for better context\n try {\n console.log(`💬 Fetching comment history for PR #${prInfo.number}`);\n const comments = await this.fetchPRComments(owner, repo, prInfo.number);\n (prInfo as PRInfo & { comments: PRComment[] }).comments = comments;\n console.log(`✅ Retrieved ${comments.length} comments`);\n } catch (error) {\n console.warn(\n `⚠️ Could not fetch comments: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n (prInfo as PRInfo & { comments: PRComment[] }).comments = [];\n }\n\n // Add commit diff for incremental analysis\n if (commitSha) {\n console.log(`🔧 Fetching incremental diff for commit: ${commitSha}`);\n prInfo.commitDiff = await this.fetchCommitDiff(owner, repo, commitSha);\n prInfo.isIncremental = true;\n if (!prInfo.commitDiff || prInfo.commitDiff.length === 0) {\n console.warn(\n `⚠️ No commit diff retrieved for ${commitSha}, will use full diff as fallback`\n );\n } else {\n console.log(`✅ Incremental diff retrieved (${prInfo.commitDiff.length} chars)`);\n }\n } else {\n prInfo.isIncremental = false;\n }\n\n return prInfo;\n }\n\n async fetchPRComments(owner: string, repo: string, prNumber: number) {\n const { data: comments } = await this.withRetry(() =>\n this.octokit.rest.issues.listComments({\n owner,\n repo,\n issue_number: prNumber,\n })\n );\n\n return comments.map(comment => ({\n id: comment.id,\n author: comment.user?.login || 'unknown',\n body: comment.body || '',\n createdAt: comment.created_at,\n updatedAt: comment.updated_at,\n }));\n }\n\n private async withRetry<T>(operation: () => Promise<T>): Promise<T> {\n let lastError: Error = new Error('Unknown error');\n\n for (let attempt = 0; attempt <= this.maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n // Preserve the original error object if possible\n if (error instanceof Error) {\n lastError = error;\n } else if (typeof error === 'object' && error !== null) {\n // For objects like {code: 'ETIMEDOUT', message: 'Network timeout'}\n const errorObj = error as NetworkError;\n const message = errorObj.message || errorObj.code || 'Unknown error';\n lastError = new Error(String(message));\n // Preserve important properties\n Object.assign(lastError, error);\n } else {\n lastError = new Error(String(error));\n }\n\n // Don't retry on the last attempt\n if (attempt === this.maxRetries) {\n break;\n }\n\n // Check if this is a retryable error\n if (this.isRetryableError(error)) {\n const delay = Math.min(1000 * Math.pow(2, attempt), 5000); // Exponential backoff, max 5s\n await new Promise(resolve => setTimeout(resolve, delay));\n } else {\n // Non-retryable error, fail immediately with original error\n throw error;\n }\n }\n }\n\n throw lastError;\n }\n\n private isRetryableError(error: unknown): boolean {\n // Retry on network timeouts, connection errors, and temporary server errors\n const retryableErrors = ['ETIMEDOUT', 'ECONNRESET', 'ECONNREFUSED', 'ENOTFOUND', 'EAI_AGAIN'];\n const retryableStatuses = [408, 429, 500, 502, 503, 504];\n\n // Type guard for error objects\n if (typeof error !== 'object' || error === null) {\n return false;\n }\n\n const err = error as NetworkError & { response?: { status?: number } };\n\n return (\n (err.code !== undefined && retryableErrors.includes(err.code)) ||\n (err.status !== undefined && retryableStatuses.includes(err.status)) ||\n (err.response?.status !== undefined && retryableStatuses.includes(err.response.status))\n );\n }\n}\n","import { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { EnvConfig } from '../types/config';\n\n/**\n * Configuration for a check provider\n */\nexport interface CheckProviderConfig {\n type: string;\n prompt?: string;\n eventContext?: Record<string, unknown>;\n focus?: string;\n command?: string; // For PR comment triggers\n exec?: string; // For command execution (supports Liquid templates)\n stdin?: string; // Optional stdin input (supports Liquid templates)\n args?: string[]; // Deprecated: use exec with inline args instead\n interpreter?: string;\n url?: string;\n method?: string;\n headers?: Record<string, string>;\n timeout?: number;\n metadata?: Record<string, unknown>;\n workingDirectory?: string;\n env?: EnvConfig;\n ai?: import('../types/config').AIProviderConfig;\n /** AI model to use for this check - overrides global setting */\n ai_model?: string;\n /** AI provider to use for this check - overrides global setting */\n ai_provider?: 'google' | 'anthropic' | 'openai' | string;\n /** Check name for sessionID and logging purposes */\n checkName?: string;\n /** Session ID for AI session management */\n sessionId?: string;\n [key: string]: unknown;\n}\n\n/**\n * Abstract base class for all check providers\n * Implementing classes provide specific check functionality (AI, tool, script, etc.)\n */\nexport abstract class CheckProvider {\n /**\n * Get the unique name/type of this provider\n */\n abstract getName(): string;\n\n /**\n * Get a human-readable description of this provider\n */\n abstract getDescription(): string;\n\n /**\n * Validate provider-specific configuration\n * @param config The configuration to validate\n * @returns true if configuration is valid, false otherwise\n */\n abstract validateConfig(config: unknown): Promise<boolean>;\n\n /**\n * Execute the check on the given PR information\n * @param prInfo Information about the pull request\n * @param config Provider-specific configuration\n * @param dependencyResults Optional results from dependency checks that this check depends on\n * @param sessionInfo Optional session information for AI session reuse\n * @returns Review summary with scores, issues, and comments\n */\n abstract execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary>;\n\n /**\n * Get the list of configuration keys this provider supports\n * Used for documentation and validation\n */\n abstract getSupportedConfigKeys(): string[];\n\n /**\n * Check if this provider is available (e.g., has required API keys)\n * @returns true if provider can be used, false otherwise\n */\n abstract isAvailable(): Promise<boolean>;\n\n /**\n * Get provider requirements (e.g., environment variables needed)\n */\n abstract getRequirements(): string[];\n\n /**\n * Set webhook context for providers that need access to webhook data\n * This is optional and only used by http_input providers\n * @param webhookContext Map of endpoint paths to webhook data\n */\n setWebhookContext?(webhookContext: Map<string, unknown>): void;\n}\n","/**\n * Environment variable resolution utilities\n * Supports GitHub Actions-like syntax for referencing environment variables\n */\n\nimport { EnvConfig } from '../types/config';\n\n/**\n * Resolves environment variables in configuration values\n * Supports the following syntaxes:\n * - ${{ env.VARIABLE_NAME }} (GitHub Actions style)\n * - ${VARIABLE_NAME} (shell style)\n * - $VARIABLE_NAME (simple shell style)\n * - Direct environment variable names\n */\nexport class EnvironmentResolver {\n /**\n * Resolves a single configuration value that may contain environment variable references\n */\n static resolveValue(value: string | number | boolean): string | number | boolean {\n if (typeof value !== 'string') {\n return value;\n }\n\n // GitHub Actions style: ${{ env.VARIABLE_NAME }}\n let resolved = value.replace(/\\$\\{\\{\\s*env\\.([A-Z_][A-Z0-9_]*)\\s*\\}\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Shell style: ${VARIABLE_NAME}\n resolved = resolved.replace(/\\$\\{([A-Z_][A-Z0-9_]*)\\}/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n // Simple shell style: $VARIABLE_NAME\n resolved = resolved.replace(/\\$([A-Z_][A-Z0-9_]*)/g, (match, envVar) => {\n return process.env[envVar] || match;\n });\n\n return resolved;\n }\n\n /**\n * Resolves all environment variables in an EnvConfig object\n */\n static resolveEnvConfig(envConfig: EnvConfig): EnvConfig {\n const resolved: EnvConfig = {};\n\n for (const [key, value] of Object.entries(envConfig)) {\n resolved[key] = this.resolveValue(value);\n }\n\n return resolved;\n }\n\n /**\n * Applies environment configuration to the process environment\n * This allows checks to access their specific environment variables\n */\n static applyEnvConfig(envConfig: EnvConfig): void {\n const resolved = this.resolveEnvConfig(envConfig);\n\n for (const [key, value] of Object.entries(resolved)) {\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n }\n\n /**\n * Creates a temporary environment for a specific check execution\n * Returns a cleanup function to restore the original environment\n */\n static withTemporaryEnv<T>(envConfig: EnvConfig, callback: () => T | Promise<T>): T | Promise<T> {\n const resolved = this.resolveEnvConfig(envConfig);\n const originalValues: Record<string, string | undefined> = {};\n\n // Store original values and apply new ones\n for (const [key, value] of Object.entries(resolved)) {\n originalValues[key] = process.env[key];\n if (value !== undefined) {\n process.env[key] = String(value);\n }\n }\n\n try {\n const result = callback();\n\n // If callback returns a promise, handle cleanup after it resolves\n if (result instanceof Promise) {\n return result.finally(() => {\n // Restore original values\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n });\n }\n\n // Restore original values immediately for sync callbacks\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n\n return result;\n } catch (error) {\n // Restore original values on error\n for (const [key, originalValue] of Object.entries(originalValues)) {\n if (originalValue === undefined) {\n delete process.env[key];\n } else {\n process.env[key] = originalValue;\n }\n }\n throw error;\n }\n }\n\n /**\n * Validates that all required environment variables are available\n */\n static validateRequiredEnvVars(envConfig: EnvConfig, requiredVars: string[]): string[] {\n const resolved = this.resolveEnvConfig(envConfig);\n const missing: string[] = [];\n\n for (const varName of requiredVars) {\n const value = resolved[varName] || process.env[varName];\n if (!value) {\n missing.push(varName);\n }\n }\n\n return missing;\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { ReviewIssue } from './reviewer';\n\n/**\n * Filter for suppressing Visor issues based on special comments in code\n */\nexport class IssueFilter {\n private fileCache: Map<string, string[]> = new Map();\n private suppressionEnabled: boolean;\n\n constructor(suppressionEnabled: boolean = true) {\n this.suppressionEnabled = suppressionEnabled;\n }\n\n /**\n * Filter out issues that have suppression comments\n * @param issues Array of issues to filter\n * @param workingDir Working directory for resolving file paths\n * @returns Filtered array of issues with suppressed ones removed\n */\n public filterIssues(issues: ReviewIssue[], workingDir: string = process.cwd()): ReviewIssue[] {\n if (!this.suppressionEnabled || !issues || issues.length === 0) {\n return issues;\n }\n\n const filteredIssues: ReviewIssue[] = [];\n const suppressedCount: { [file: string]: number } = {};\n\n for (const issue of issues) {\n if (this.shouldSuppressIssue(issue, workingDir)) {\n // Track suppressed issues for logging\n suppressedCount[issue.file] = (suppressedCount[issue.file] || 0) + 1;\n } else {\n filteredIssues.push(issue);\n }\n }\n\n // Log suppression summary if any issues were suppressed\n const totalSuppressed = Object.values(suppressedCount).reduce((sum, count) => sum + count, 0);\n if (totalSuppressed > 0) {\n console.log(`🔇 Suppressed ${totalSuppressed} issue(s) via visor-disable comments:`);\n for (const [file, count] of Object.entries(suppressedCount)) {\n console.log(` - ${file}: ${count} issue(s)`);\n }\n }\n\n return filteredIssues;\n }\n\n /**\n * Check if an issue should be suppressed based on comments in the file\n */\n private shouldSuppressIssue(issue: ReviewIssue, workingDir: string): boolean {\n // Skip system-level issues or issues without file/line info\n if (!issue.file || issue.file === 'system' || issue.file === 'webhook' || issue.line === 0) {\n return false;\n }\n\n const lines = this.getFileLines(issue.file, workingDir);\n if (!lines || lines.length === 0) {\n return false;\n }\n\n // Check for file-level suppression (visor-disable-file in first 5 lines)\n const firstFiveLines = lines.slice(0, 5).join('\\n').toLowerCase();\n if (firstFiveLines.includes('visor-disable-file')) {\n return true;\n }\n\n // Check for line-level suppression (visor-disable within ±2 lines)\n const lineIndex = issue.line - 1; // Convert to 0-based index\n const startLine = Math.max(0, lineIndex - 2);\n const endLine = Math.min(lines.length - 1, lineIndex + 2);\n\n for (let i = startLine; i <= endLine; i++) {\n if (lines[i].toLowerCase().includes('visor-disable')) {\n return true;\n }\n }\n\n return false;\n }\n\n /**\n * Get file lines from cache or read from disk\n */\n private getFileLines(filePath: string, workingDir: string): string[] | null {\n // Check cache first\n if (this.fileCache.has(filePath)) {\n return this.fileCache.get(filePath)!;\n }\n\n try {\n // Resolve the file path\n const resolvedPath = path.isAbsolute(filePath) ? filePath : path.join(workingDir, filePath);\n\n if (!fs.existsSync(resolvedPath)) {\n // Try without working directory if the file doesn't exist\n if (fs.existsSync(filePath)) {\n const content = fs.readFileSync(filePath, 'utf8');\n const lines = content.split('\\n');\n this.fileCache.set(filePath, lines);\n return lines;\n }\n return null;\n }\n\n const content = fs.readFileSync(resolvedPath, 'utf8');\n const lines = content.split('\\n');\n this.fileCache.set(filePath, lines);\n return lines;\n } catch {\n // Silently skip files that can't be read\n return null;\n }\n }\n\n /**\n * Clear the file cache (useful for testing or long-running processes)\n */\n public clearCache(): void {\n this.fileCache.clear();\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { AIReviewService, AIReviewConfig } from '../ai-review-service';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { IssueFilter } from '../issue-filter';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport fs from 'fs/promises';\nimport path from 'path';\n\n/**\n * AI-powered check provider using probe agent\n */\nexport class AICheckProvider extends CheckProvider {\n private aiReviewService: AIReviewService;\n private liquidEngine: Liquid;\n\n constructor() {\n super();\n this.aiReviewService = new AIReviewService();\n this.liquidEngine = createExtendedLiquid();\n }\n\n getName(): string {\n return 'ai';\n }\n\n getDescription(): string {\n return 'AI-powered code review using Google Gemini, Anthropic Claude, OpenAI GPT, or AWS Bedrock models';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'ai'\n if (cfg.type !== 'ai') {\n return false;\n }\n\n // Check for prompt or focus\n const prompt = cfg.prompt || cfg.focus;\n if (typeof prompt !== 'string') {\n return false;\n }\n\n // Validate focus if specified\n if (cfg.focus && !['security', 'performance', 'style', 'all'].includes(cfg.focus as string)) {\n return false;\n }\n\n // Validate AI provider config if present\n if (cfg.ai) {\n if (\n cfg.ai.provider &&\n !['google', 'anthropic', 'openai', 'bedrock', 'mock'].includes(cfg.ai.provider as string)\n ) {\n return false;\n }\n\n // Validate mcpServers if present\n if (cfg.ai.mcpServers) {\n if (!this.validateMcpServers(cfg.ai.mcpServers)) {\n return false;\n }\n }\n }\n\n // Validate check-level MCP servers if present\n const checkLevelMcpServers = (cfg as CheckProviderConfig & { ai_mcp_servers?: unknown })\n .ai_mcp_servers;\n if (checkLevelMcpServers) {\n if (!this.validateMcpServers(checkLevelMcpServers)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Validate MCP servers configuration\n */\n private validateMcpServers(mcpServers: unknown): boolean {\n if (typeof mcpServers !== 'object' || mcpServers === null) {\n return false;\n }\n\n for (const serverConfig of Object.values(mcpServers)) {\n if (!serverConfig || typeof serverConfig !== 'object') {\n return false;\n }\n const config = serverConfig as { command?: unknown; args?: unknown };\n if (typeof config.command !== 'string') {\n return false;\n }\n if (config.args !== undefined && !Array.isArray(config.args)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n * Group files by their file extension for template context\n */\n private groupFilesByExtension(\n files: import('../pr-analyzer').PRFile[]\n ): Record<string, import('../pr-analyzer').PRFile[]> {\n const grouped: Record<string, import('../pr-analyzer').PRFile[]> = {};\n\n files.forEach(file => {\n const parts = file.filename.split('.');\n const ext = parts.length > 1 ? parts.pop()?.toLowerCase() || 'noext' : 'noext';\n if (!grouped[ext]) {\n grouped[ext] = [];\n }\n grouped[ext].push(file);\n });\n\n return grouped;\n }\n\n /**\n * Process prompt configuration to resolve final prompt string\n */\n private async processPrompt(\n promptConfig: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n let promptContent: string;\n\n // Auto-detect if it's a file path or inline content\n if (await this.isFilePath(promptConfig)) {\n promptContent = await this.loadPromptFromFile(promptConfig);\n } else {\n promptContent = promptConfig;\n }\n\n // Process Liquid templates in the prompt\n return await this.renderPromptTemplate(promptContent, prInfo, eventContext, dependencyResults);\n }\n\n /**\n * Detect if a string is likely a file path and if the file exists\n */\n private async isFilePath(str: string): Promise<boolean> {\n // Quick checks to exclude obvious non-file-path content\n if (!str || str.trim() !== str || str.length > 512) {\n return false;\n }\n\n // Exclude strings that are clearly content (contain common content indicators)\n // But be more careful with paths that might contain common words as directory names\n if (\n /\\s{2,}/.test(str) || // Multiple consecutive spaces\n /\\n/.test(str) || // Contains newlines\n /^(please|analyze|review|check|find|identify|look|search)/i.test(str.trim()) || // Starts with command words\n str.split(' ').length > 8 // Too many words for a typical file path\n ) {\n return false;\n }\n\n // For strings with path separators, be more lenient about common words\n // as they might be legitimate directory names\n if (!/[\\/\\\\]/.test(str)) {\n // Only apply strict English word filter to non-path strings\n if (/\\b(the|and|or|but|for|with|by|from|in|on|at|as)\\b/i.test(str)) {\n return false;\n }\n }\n\n // Positive indicators for file paths\n const hasFileExtension = /\\.[a-zA-Z0-9]{1,10}$/i.test(str);\n const hasPathSeparators = /[\\/\\\\]/.test(str);\n const isRelativePath = /^\\.{1,2}\\//.test(str);\n const isAbsolutePath = path.isAbsolute(str);\n const hasTypicalFileChars = /^[a-zA-Z0-9._\\-\\/\\\\:~]+$/.test(str);\n\n // Must have at least one strong indicator\n if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {\n return false;\n }\n\n // Must contain only typical file path characters\n if (!hasTypicalFileChars) {\n return false;\n }\n\n // Additional validation for suspected file paths\n try {\n // Try to resolve and check if file exists\n let resolvedPath: string;\n\n if (path.isAbsolute(str)) {\n resolvedPath = path.normalize(str);\n } else {\n // Resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), str);\n }\n\n // Check if file exists\n const fs = require('fs').promises;\n try {\n const stat = await fs.stat(resolvedPath);\n return stat.isFile();\n } catch {\n // File doesn't exist, but might still be a valid file path format\n // Return true if it has strong file path indicators\n return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);\n }\n } catch {\n return false;\n }\n }\n\n /**\n * Load prompt content from file with security validation\n */\n private async loadPromptFromFile(promptPath: string): Promise<string> {\n // Enforce .liquid file extension for all prompt files\n if (!promptPath.endsWith('.liquid')) {\n throw new Error('Prompt file must have .liquid extension');\n }\n\n let resolvedPath: string;\n\n if (path.isAbsolute(promptPath)) {\n // Absolute path - use as-is\n resolvedPath = promptPath;\n } else {\n // Relative path - resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), promptPath);\n }\n\n // Security: For relative paths, ensure they don't escape the current directory\n if (!path.isAbsolute(promptPath)) {\n const normalizedPath = path.normalize(resolvedPath);\n const currentDir = path.resolve(process.cwd());\n if (!normalizedPath.startsWith(currentDir)) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n }\n\n // Security: Check for obvious path traversal patterns\n if (promptPath.includes('../..')) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n\n try {\n const promptContent = await fs.readFile(resolvedPath, 'utf-8');\n return promptContent;\n } catch (error) {\n throw new Error(\n `Failed to load prompt from ${resolvedPath}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Render Liquid template in prompt with comprehensive event context\n */\n private async renderPromptTemplate(\n promptContent: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n // Create comprehensive template context with PR and event information\n const templateContext = {\n // PR Information\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n baseBranch: prInfo.base,\n headBranch: prInfo.head,\n isIncremental: prInfo.isIncremental,\n filesChanged: prInfo.files?.map(f => f.filename) || [],\n totalAdditions: prInfo.files?.reduce((sum, f) => sum + f.additions, 0) || 0,\n totalDeletions: prInfo.files?.reduce((sum, f) => sum + f.deletions, 0) || 0,\n totalChanges: prInfo.files?.reduce((sum, f) => sum + f.changes, 0) || 0,\n base: prInfo.base,\n head: prInfo.head,\n },\n\n // File Details\n files: prInfo.files || [],\n description: prInfo.body || '',\n\n // GitHub Event Context\n event: eventContext\n ? {\n name: eventContext.event_name || 'unknown',\n action: eventContext.action,\n isPullRequest: !prInfo.isIssue, // Set based on whether this is a PR or an issue\n\n // Repository Info\n repository: eventContext.repository\n ? {\n owner: (eventContext.repository as { owner?: { login?: string } })?.owner?.login,\n name: (eventContext.repository as { name?: string })?.name,\n fullName: eventContext.repository\n ? `${(eventContext.repository as { owner?: { login?: string } })?.owner?.login}/${(eventContext.repository as { name?: string })?.name}`\n : undefined,\n }\n : undefined,\n\n // Comment Data (for comment events)\n comment: eventContext.comment\n ? {\n body: (eventContext.comment as { body?: string })?.body,\n author: (eventContext.comment as { user?: { login?: string } })?.user?.login,\n }\n : undefined,\n\n // Issue Data (for issue events)\n issue: eventContext.issue\n ? {\n number: (eventContext.issue as { number?: number })?.number,\n title: (eventContext.issue as { title?: string })?.title,\n body: (eventContext.issue as { body?: string })?.body,\n state: (eventContext.issue as { state?: string })?.state,\n author: (eventContext.issue as { user?: { login?: string } })?.user?.login,\n labels: (eventContext.issue as { labels?: unknown[] })?.labels || [],\n assignees:\n (\n eventContext as { issue?: { assignees?: Array<{ login: string }> } }\n )?.issue?.assignees?.map(a => a.login) || [],\n createdAt: (eventContext.issue as { created_at?: string })?.created_at,\n updatedAt: (eventContext.issue as { updated_at?: string })?.updated_at,\n isPullRequest: !!(eventContext.issue as { pull_request?: unknown })?.pull_request,\n }\n : undefined,\n\n // Pull Request Event Data\n pullRequest: eventContext.pull_request\n ? {\n number: (eventContext.pull_request as { number?: number })?.number,\n state: (eventContext.pull_request as { state?: string })?.state,\n draft: (eventContext.pull_request as { draft?: boolean })?.draft,\n headSha: (eventContext.pull_request as { head?: { sha?: string } })?.head?.sha,\n headRef: (eventContext.pull_request as { head?: { ref?: string } })?.head?.ref,\n baseSha: (eventContext.pull_request as { base?: { sha?: string } })?.base?.sha,\n baseRef: (eventContext.pull_request as { base?: { ref?: string } })?.base?.ref,\n }\n : undefined,\n\n // Raw event payload for advanced use cases\n payload: eventContext,\n }\n : undefined,\n\n // Utility data for templates\n utils: {\n // Date/time helpers\n now: new Date().toISOString(),\n today: new Date().toISOString().split('T')[0],\n\n // Dynamic file grouping by extension\n filesByExtension: this.groupFilesByExtension(prInfo.files || []),\n\n // File status categorizations\n addedFiles: (prInfo.files || []).filter(f => f.status === 'added'),\n modifiedFiles: (prInfo.files || []).filter(f => f.status === 'modified'),\n removedFiles: (prInfo.files || []).filter(f => f.status === 'removed'),\n renamedFiles: (prInfo.files || []).filter(f => f.status === 'renamed'),\n\n // Change analysis\n hasLargeChanges: (prInfo.files || []).some(f => f.changes > 50),\n totalFiles: (prInfo.files || []).length,\n },\n\n // Previous check outputs (dependency results)\n // Expose raw output directly if available, otherwise expose the result as-is\n outputs: dependencyResults\n ? Object.fromEntries(\n Array.from(dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n (() => {\n const summary = result as ReviewSummary & { output?: unknown };\n return summary.output !== undefined ? summary.output : summary;\n })(),\n ])\n )\n : {},\n };\n\n try {\n return await this.liquidEngine.parseAndRender(promptContent, templateContext);\n } catch (error) {\n throw new Error(\n `Failed to render prompt template: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Apply environment configuration if present\n if (config.env) {\n const result = EnvironmentResolver.withTemporaryEnv(config.env, () => {\n // This will be executed with the temporary environment\n return this.executeWithConfig(prInfo, config, _dependencyResults, sessionInfo);\n });\n\n if (result instanceof Promise) {\n return result;\n }\n return result;\n }\n\n return this.executeWithConfig(prInfo, config, _dependencyResults, sessionInfo);\n }\n\n private async executeWithConfig(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Extract AI configuration - only set properties that are explicitly provided\n const aiConfig: AIReviewConfig = {};\n\n // Check-level AI configuration (ai object)\n if (config.ai) {\n // Only set properties that are actually defined to avoid overriding env vars\n if (config.ai.apiKey !== undefined) {\n aiConfig.apiKey = config.ai.apiKey as string;\n }\n if (config.ai.model !== undefined) {\n aiConfig.model = config.ai.model as string;\n }\n if (config.ai.timeout !== undefined) {\n aiConfig.timeout = config.ai.timeout as number;\n }\n if (config.ai.provider !== undefined) {\n aiConfig.provider = config.ai.provider as\n | 'google'\n | 'anthropic'\n | 'openai'\n | 'bedrock'\n | 'mock';\n }\n if (config.ai.debug !== undefined) {\n aiConfig.debug = config.ai.debug as boolean;\n }\n }\n\n // Check-level AI model and provider (top-level properties)\n if (config.ai_model !== undefined) {\n aiConfig.model = config.ai_model as string;\n }\n if (config.ai_provider !== undefined) {\n aiConfig.provider = config.ai_provider as\n | 'google'\n | 'anthropic'\n | 'openai'\n | 'bedrock'\n | 'mock';\n }\n\n // Get custom prompt from config - REQUIRED, no fallbacks\n const customPrompt = config.prompt;\n\n if (!customPrompt) {\n throw new Error(\n `No prompt defined for check. All checks must have prompts defined in .visor.yaml configuration.`\n );\n }\n\n // Setup MCP tools from multiple configuration levels\n const mcpServers: Record<string, import('../types/config').McpServerConfig> = {};\n\n // 1. Start with global MCP servers (from visor config root)\n const globalConfig = config as CheckProviderConfig & {\n ai_mcp_servers?: Record<string, import('../types/config').McpServerConfig>;\n };\n if (globalConfig.ai_mcp_servers) {\n Object.assign(mcpServers, globalConfig.ai_mcp_servers);\n }\n\n // 2. Add check-level MCP servers (overrides global)\n if (config.ai_mcp_servers) {\n Object.assign(mcpServers, config.ai_mcp_servers);\n }\n\n // 3. Add ai.mcpServers (overrides everything)\n if (config.ai?.mcpServers) {\n Object.assign(mcpServers, config.ai.mcpServers);\n }\n\n // Pass MCP server config directly to AI service\n if (Object.keys(mcpServers).length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (aiConfig as any).mcpServers = mcpServers;\n if (aiConfig.debug) {\n console.error(\n `🔧 Debug: AI check MCP configured with ${Object.keys(mcpServers).length} servers`\n );\n }\n }\n\n // Process prompt with Liquid templates and file loading\n const processedPrompt = await this.processPrompt(\n customPrompt,\n prInfo,\n config.eventContext,\n _dependencyResults\n );\n\n // Create AI service with config - environment variables will be used if aiConfig is empty\n const service = new AIReviewService(aiConfig);\n\n // Pass the custom prompt and schema - no fallbacks\n const schema = config.schema as string | Record<string, unknown> | undefined;\n\n // Only output debug messages if debug mode is enabled\n if (aiConfig.debug) {\n console.error(\n `🔧 Debug: AICheckProvider using processed prompt: ${processedPrompt.substring(0, 100)}...`\n );\n console.error(`🔧 Debug: AICheckProvider schema from config: ${JSON.stringify(schema)}`);\n console.error(`🔧 Debug: AICheckProvider full config: ${JSON.stringify(config, null, 2)}`);\n }\n\n try {\n if (aiConfig.debug) {\n console.error(\n `🔧 Debug: AICheckProvider passing checkName: ${config.checkName} to service`\n );\n }\n\n let result: ReviewSummary;\n\n // Check if we should use session reuse\n if (sessionInfo?.reuseSession && sessionInfo.parentSessionId) {\n // Get session_mode from config, default to 'clone'\n const sessionMode = (config.session_mode as 'clone' | 'append') || 'clone';\n\n if (aiConfig.debug) {\n console.error(\n `🔄 Debug: Using session reuse with parent session: ${sessionInfo.parentSessionId} (mode: ${sessionMode})`\n );\n }\n result = await service.executeReviewWithSessionReuse(\n prInfo,\n processedPrompt,\n sessionInfo.parentSessionId,\n schema,\n config.checkName,\n sessionMode\n );\n } else {\n if (aiConfig.debug) {\n console.error(`🆕 Debug: Creating new AI session for check: ${config.checkName}`);\n }\n result = await service.executeReview(\n prInfo,\n processedPrompt,\n schema,\n config.checkName,\n config.sessionId\n );\n }\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n return {\n ...result,\n issues: filteredIssues,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Log detailed error information\n console.error(`❌ AI Check Provider Error for check: ${errorMessage}`);\n\n // Check if this is a critical error (authentication, rate limits, etc)\n const isCriticalError =\n errorMessage.includes('API rate limit') ||\n errorMessage.includes('403') ||\n errorMessage.includes('401') ||\n errorMessage.includes('authentication') ||\n errorMessage.includes('API key');\n\n if (isCriticalError) {\n console.error(`🚨 CRITICAL ERROR: AI provider authentication or rate limit issue detected`);\n console.error(`🚨 This check cannot proceed without valid API credentials`);\n }\n\n // Re-throw with more context\n throw new Error(`AI analysis failed: ${errorMessage}`);\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'focus',\n 'schema',\n 'group',\n 'ai.provider',\n 'ai.model',\n 'ai.apiKey',\n 'ai.timeout',\n 'ai.mcpServers',\n 'ai_model',\n 'ai_provider',\n 'ai_mcp_servers',\n 'env',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Check if any AI API key is available\n return !!(\n process.env.GOOGLE_API_KEY ||\n process.env.ANTHROPIC_API_KEY ||\n process.env.OPENAI_API_KEY ||\n // AWS Bedrock credentials check\n (process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY) ||\n process.env.AWS_BEDROCK_API_KEY\n );\n }\n\n getRequirements(): string[] {\n return [\n 'At least one of: GOOGLE_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY, or AWS credentials (AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY)',\n 'Optional: MODEL_NAME environment variable',\n 'Optional: AWS_REGION for Bedrock provider',\n 'Network access to AI provider APIs',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { IssueFilter } from '../issue-filter';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\n\n/**\n * Check provider that sends data to an HTTP endpoint, typically used as an output/notification provider\n */\nexport class HttpCheckProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n getName(): string {\n return 'http';\n }\n\n getDescription(): string {\n return 'Send data to external HTTP endpoint for notifications or integration';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http'\n if (cfg.type !== 'http') {\n return false;\n }\n\n // Must have URL specified\n if (typeof cfg.url !== 'string' || !cfg.url) {\n return false;\n }\n\n // Must have body template specified\n if (typeof cfg.body !== 'string' || !cfg.body) {\n return false;\n }\n\n // Validate URL format\n try {\n new URL(cfg.url as string);\n return true;\n } catch {\n return false;\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const url = config.url as string;\n const bodyTemplate = config.body as string;\n const method = (config.method as string) || 'POST';\n const headers = (config.headers as Record<string, string>) || {};\n const timeout = (config.timeout as number) || 30000;\n\n // Prepare template context with all available data\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n },\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n patch: f.patch,\n })),\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n metadata: config.metadata || {},\n };\n\n // Render the body template\n let payload: Record<string, unknown>;\n try {\n const renderedBody = await this.liquid.parseAndRender(bodyTemplate, templateContext);\n // Try to parse as JSON, otherwise send as plain text\n try {\n payload = JSON.parse(renderedBody);\n } catch {\n payload = { message: renderedBody };\n }\n } catch (error) {\n return this.createErrorResult(\n url,\n new Error(\n `Template rendering failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n )\n );\n }\n\n try {\n // Send webhook request\n const response = await this.sendWebhookRequest(url, method, headers, payload, timeout);\n\n // Parse webhook response\n const result = this.parseWebhookResponse(response, url);\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n return {\n ...result,\n issues: filteredIssues,\n };\n } catch (error) {\n return this.createErrorResult(url, error);\n }\n }\n\n private async sendWebhookRequest(\n url: string,\n method: string,\n headers: Record<string, string>,\n payload: Record<string, unknown>,\n timeout: number\n ): Promise<Record<string, unknown>> {\n // Check if fetch is available (Node 18+)\n if (typeof fetch === 'undefined') {\n throw new Error('Webhook provider requires Node.js 18+ or node-fetch package');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n 'Content-Type': 'application/json',\n ...headers,\n },\n body: JSON.stringify(payload),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`Webhook returned ${response.status}: ${response.statusText}`);\n }\n\n return (await response.json()) as Record<string, unknown>;\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Webhook request timed out after ${timeout}ms`);\n }\n\n throw error;\n }\n }\n\n private parseWebhookResponse(response: Record<string, unknown>, url: string): ReviewSummary {\n // Validate and normalize the webhook response\n if (!response || typeof response !== 'object') {\n return this.createErrorResult(url, new Error('Invalid webhook response format'));\n }\n\n const issues: ReviewIssue[] = Array.isArray(response.comments)\n ? (response.comments as Array<Record<string, unknown>>).map(c => ({\n file: (c.file as string) || 'unknown',\n line: (c.line as number) || 0,\n endLine: c.endLine as number | undefined,\n ruleId: (c.ruleId as string) || `webhook/${this.validateCategory(c.category)}`,\n message: (c.message as string) || '',\n severity: this.validateSeverity(c.severity),\n category: this.validateCategory(c.category),\n suggestion: c.suggestion as string | undefined,\n replacement: c.replacement as string | undefined,\n }))\n : [];\n\n return {\n issues,\n };\n }\n\n private createErrorResult(url: string, error: unknown): ReviewSummary {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n return {\n issues: [\n {\n file: 'webhook',\n line: 0,\n endLine: undefined,\n ruleId: 'webhook/error',\n message: `Webhook execution error: ${errorMessage}`,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n };\n }\n\n private validateSeverity(severity: unknown): 'info' | 'warning' | 'error' | 'critical' {\n const valid = ['info', 'warning', 'error', 'critical'];\n return valid.includes(severity as string)\n ? (severity as 'info' | 'warning' | 'error' | 'critical')\n : 'info';\n }\n\n private validateCategory(\n category: unknown\n ): 'security' | 'performance' | 'style' | 'logic' | 'documentation' {\n const valid = ['security', 'performance', 'style', 'logic', 'documentation'];\n return valid.includes(category as string)\n ? (category as 'security' | 'performance' | 'style' | 'logic' | 'documentation')\n : 'logic';\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'url',\n 'body',\n 'method',\n 'headers',\n 'timeout',\n 'metadata',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'schedule',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // HTTP provider is available if fetch is available\n return typeof fetch !== 'undefined';\n }\n\n getRequirements(): string[] {\n return [\n 'Valid HTTP URL',\n 'Body template (Liquid) for payload construction',\n 'Network access to HTTP endpoint',\n 'Optional: Dependencies for accessing their outputs in templates',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\n\n/**\n * Check provider that receives input from HTTP webhooks and makes it available to dependent checks\n */\nexport class HttpInputProvider extends CheckProvider {\n private liquid: Liquid;\n private webhookContext?: Map<string, unknown>;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n\n /**\n * Set webhook context for accessing webhook data\n */\n setWebhookContext(webhookContext: Map<string, unknown>): void {\n this.webhookContext = webhookContext;\n }\n\n getName(): string {\n return 'http_input';\n }\n\n getDescription(): string {\n return 'Receive and process HTTP webhook input data for use by dependent checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http_input'\n if (cfg.type !== 'http_input') {\n return false;\n }\n\n // Must have endpoint specified\n if (typeof cfg.endpoint !== 'string' || !cfg.endpoint) {\n return false;\n }\n\n // Transform is optional but must be string if provided\n if (cfg.transform !== undefined && typeof cfg.transform !== 'string') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const endpoint = config.endpoint as string;\n const transform = config.transform as string | undefined;\n\n // In actual implementation, this would receive data from the webhook server\n // For now, we'll check if there's webhook data in the execution context\n const webhookData = this.getWebhookData(endpoint);\n\n if (!webhookData) {\n return {\n issues: [],\n };\n }\n\n // Apply transformation if specified\n let processedData = webhookData;\n if (transform) {\n try {\n const templateContext = {\n webhook: webhookData,\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n },\n };\n const rendered = await this.liquid.parseAndRender(transform, templateContext);\n processedData = JSON.parse(rendered);\n logger.verbose(`✓ Applied webhook transform successfully`);\n } catch (error) {\n logger.error(\n `✗ Failed to transform webhook data: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'webhook_input',\n line: 0,\n ruleId: 'webhook_input/transform_error',\n message: `Failed to transform webhook data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Return the processed data as a custom field for dependent checks to access\n // This will be available in outputs for dependent checks\n return {\n issues: [],\n // Add custom data field that will be passed through\n data: processedData,\n } as ReviewSummary & { data: unknown };\n }\n\n private getWebhookData(endpoint: string): Record<string, unknown> | null {\n // Use webhook context if available (preferred method)\n if (this.webhookContext) {\n return (this.webhookContext.get(endpoint) as Record<string, unknown>) || null;\n }\n\n // Fallback to global store for backwards compatibility\n // This should be removed once all usages are migrated\n const globalWebhookStore = (global as Record<string, unknown>).__visor_webhook_data as\n | Map<string, Record<string, unknown>>\n | undefined;\n if (globalWebhookStore && globalWebhookStore.get) {\n console.warn(\n 'HttpInputProvider: Using deprecated global webhook store. Please use webhook context instead.'\n );\n return globalWebhookStore.get(endpoint) || null;\n }\n\n return null;\n }\n\n getSupportedConfigKeys(): string[] {\n return ['type', 'endpoint', 'transform', 'on', 'depends_on', 'if', 'group'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Available if webhook server is configured and running\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'HTTP server must be configured and running',\n 'Valid endpoint path specified',\n 'Optional: Transform template for data processing',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\n\n/**\n * Check provider that fetches data from HTTP endpoints\n */\nexport class HttpClientProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid();\n }\n\n getName(): string {\n return 'http_client';\n }\n\n getDescription(): string {\n return 'Fetch data from HTTP endpoints for use by dependent checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'http_client'\n if (cfg.type !== 'http_client') {\n return false;\n }\n\n // Must have URL specified\n if (typeof cfg.url !== 'string' || !cfg.url) {\n return false;\n }\n\n // Validate URL format\n try {\n new URL(cfg.url as string);\n return true;\n } catch {\n return false;\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const url = config.url as string;\n const method = (config.method as string) || 'GET';\n const headers = (config.headers as Record<string, string>) || {};\n const timeout = (config.timeout as number) || 30000;\n const transform = config.transform as string | undefined;\n const bodyTemplate = config.body as string | undefined;\n\n try {\n // Prepare template context for URL and body\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n },\n outputs: dependencyResults ? Object.fromEntries(dependencyResults) : {},\n env: process.env,\n };\n\n // Render URL with template if it contains liquid syntax\n let renderedUrl = url;\n if (url.includes('{{') || url.includes('{%')) {\n renderedUrl = await this.liquid.parseAndRender(url, templateContext);\n }\n\n // Prepare request body if provided\n let requestBody: string | undefined;\n if (bodyTemplate) {\n const renderedBody = await this.liquid.parseAndRender(bodyTemplate, templateContext);\n requestBody = renderedBody;\n }\n\n // Fetch data from the endpoint\n const data = await this.fetchData(renderedUrl, method, headers, requestBody, timeout);\n\n // Apply transformation if specified\n let processedData = data;\n if (transform) {\n try {\n const transformContext = {\n response: data,\n pr: templateContext.pr,\n outputs: templateContext.outputs,\n };\n const rendered = await this.liquid.parseAndRender(transform, transformContext);\n // Try to parse as JSON if the transform result looks like JSON\n if (rendered.trim().startsWith('{') || rendered.trim().startsWith('[')) {\n processedData = JSON.parse(rendered);\n } else {\n processedData = rendered;\n }\n } catch (error) {\n return {\n issues: [\n {\n file: 'http_client',\n line: 0,\n ruleId: 'http_client/transform_error',\n message: `Failed to transform response data: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Return the fetched data as a custom field for dependent checks to access\n return {\n issues: [],\n // Add custom data field that will be passed through to dependent checks\n data: processedData,\n } as ReviewSummary & { data: unknown };\n } catch (error) {\n return {\n issues: [\n {\n file: 'http_client',\n line: 0,\n ruleId: 'http_client/fetch_error',\n message: `Failed to fetch from ${url}: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n private async fetchData(\n url: string,\n method: string,\n headers: Record<string, string>,\n body?: string,\n timeout: number = 30000\n ): Promise<unknown> {\n // Check if fetch is available (Node 18+)\n if (typeof fetch === 'undefined') {\n throw new Error('HTTP client provider requires Node.js 18+ or node-fetch package');\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n\n try {\n const requestOptions: RequestInit = {\n method,\n headers: {\n ...headers,\n },\n signal: controller.signal,\n };\n\n // Add body for non-GET requests\n if (method !== 'GET' && body) {\n requestOptions.body = body;\n // Set Content-Type if not already set\n if (!headers['Content-Type'] && !headers['content-type']) {\n requestOptions.headers = {\n ...requestOptions.headers,\n 'Content-Type': 'application/json',\n };\n }\n }\n\n const response = await fetch(url, requestOptions);\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n // Try to parse as JSON first\n const contentType = response.headers.get('content-type');\n if (contentType && contentType.includes('application/json')) {\n return await response.json();\n }\n\n // Otherwise return as text\n const text = await response.text();\n\n // Try to parse as JSON if it looks like JSON\n if (text.trim().startsWith('{') || text.trim().startsWith('[')) {\n try {\n return JSON.parse(text);\n } catch {\n // Not JSON, return as text\n return text;\n }\n }\n\n return text;\n } catch (error: unknown) {\n clearTimeout(timeoutId);\n\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timed out after ${timeout}ms`);\n }\n\n throw error;\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'url',\n 'method',\n 'headers',\n 'body',\n 'transform',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'schedule',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // HTTP client is available if fetch is available\n return typeof fetch !== 'undefined';\n }\n\n getRequirements(): string[] {\n return [\n 'Valid HTTP/HTTPS URL to fetch from',\n 'Network access to the endpoint',\n 'Optional: Transform template for processing response data',\n 'Optional: Body template for POST/PUT requests',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\n\n/**\n * No-operation check provider that doesn't perform any analysis.\n *\n * This provider is designed for command orchestration - it allows creating\n * checks that exist purely to trigger other checks through dependencies.\n *\n * Example use case: A \"/review\" command that triggers multiple analysis checks\n * without performing any analysis itself.\n */\nexport class NoopCheckProvider extends CheckProvider {\n getName(): string {\n return 'noop';\n }\n\n getDescription(): string {\n return 'No-operation provider for command orchestration and dependency triggering';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'noop'\n if (cfg.type !== 'noop') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n _prInfo: PRInfo,\n _config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Noop provider doesn't perform any analysis\n // It exists purely for command orchestration and dependency triggering\n return {\n issues: [],\n };\n }\n\n getSupportedConfigKeys(): string[] {\n return ['type', 'command', 'depends_on', 'on', 'if', 'group'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Noop provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for command orchestration and dependency triggering',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\n\n/**\n * Log levels supported by the log provider\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Check provider that outputs debugging and logging information.\n * Useful for troubleshooting check workflows and understanding execution flow.\n */\nexport class LogCheckProvider extends CheckProvider {\n private liquid: Liquid;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n strictVariables: false,\n strictFilters: false,\n });\n }\n\n getName(): string {\n return 'log';\n }\n\n getDescription(): string {\n return 'Output debugging and logging information for troubleshooting check workflows';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'log'\n if (cfg.type !== 'log') {\n return false;\n }\n\n // Message is required\n if (!cfg.message || typeof cfg.message !== 'string') {\n return false;\n }\n\n // Validate log level if provided\n if (cfg.level && !['debug', 'info', 'warn', 'error'].includes(cfg.level as string)) {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const message = config.message as string;\n const level = (config.level as LogLevel) || 'info';\n const includePrContext = config.include_pr_context !== false;\n const includeDependencies = config.include_dependencies !== false;\n const includeMetadata = config.include_metadata !== false;\n\n // Prepare template context\n const templateContext = this.buildTemplateContext(\n prInfo,\n dependencyResults,\n includePrContext,\n includeDependencies,\n includeMetadata,\n config.__outputHistory as Map<string, unknown[]> | undefined\n );\n\n // Render the log message template\n const renderedMessage = await this.liquid.parseAndRender(message, templateContext);\n\n // Build the log output\n const logOutput = this.formatLogOutput(\n level,\n renderedMessage,\n templateContext,\n includePrContext,\n includeDependencies,\n includeMetadata\n );\n\n // Route through centralized logger to keep stdout clean in JSON/SARIF\n if (level === 'error') logger.error(logOutput);\n else if (level === 'warn') logger.warn(logOutput);\n else if (level === 'debug') logger.debug(logOutput);\n else logger.info(logOutput);\n\n // Return with the log content as custom data for dependent checks\n return {\n issues: [],\n // Add log output as custom field\n logOutput,\n } as ReviewSummary & { logOutput: string };\n }\n\n private buildTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n _includePrContext: boolean = true,\n _includeDependencies: boolean = true,\n includeMetadata: boolean = true,\n outputHistory?: Map<string, unknown[]>\n ): Record<string, unknown> {\n const context: Record<string, unknown> = {};\n\n // Always provide pr context for template rendering\n context.pr = {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n })),\n };\n\n // Add convenience data\n context.filenames = prInfo.files.map(f => f.filename);\n context.fileCount = prInfo.files.length;\n\n // Always provide dependency data for template rendering\n if (dependencyResults) {\n const dependencies: Record<string, unknown> = {};\n const outputs: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n context.dependencyCount = dependencyResults.size;\n\n for (const [checkName, result] of dependencyResults.entries()) {\n dependencies[checkName] = {\n issueCount: result.issues?.length || 0,\n suggestionCount: 0,\n issues: result.issues || [],\n };\n\n // Add outputs namespace for accessing dependency results directly\n const summary = result as import('../reviewer').ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n\n // Add history for each check if available\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n history[checkName] = historyArray;\n }\n }\n\n // Attach history to the outputs object\n (outputs as any).history = history;\n\n context.dependencies = dependencies;\n context.outputs = outputs;\n }\n\n if (includeMetadata) {\n context.metadata = {\n timestamp: new Date().toISOString(),\n executionTime: Date.now(),\n nodeVersion: process.version,\n platform: process.platform,\n workingDirectory: process.cwd(),\n };\n }\n\n return context;\n }\n\n private formatLogOutput(\n level: LogLevel,\n message: string,\n templateContext: Record<string, unknown>,\n includePrContext: boolean,\n includeDependencies: boolean,\n includeMetadata: boolean\n ): string {\n const sections: string[] = [];\n\n // Log level and message\n const levelEmoji = this.getLevelEmoji(level);\n sections.push(`${levelEmoji} **${level.toUpperCase()}**: ${message}`);\n\n // PR context section\n if (includePrContext && templateContext.pr) {\n const pr = templateContext.pr as Record<string, unknown>;\n sections.push('');\n sections.push('### PR Context');\n sections.push(`- **PR #${pr.number}**: ${pr.title}`);\n sections.push(`- **Author**: ${pr.author}`);\n sections.push(`- **Base**: ${pr.base} → **Head**: ${pr.head}`);\n sections.push(`- **Changes**: +${pr.totalAdditions} -${pr.totalDeletions}`);\n sections.push(`- **Files Modified**: ${templateContext.fileCount}`);\n }\n\n // Dependencies section\n if (includeDependencies && templateContext.dependencies) {\n const deps = templateContext.dependencies as Record<string, Record<string, unknown>>;\n sections.push('');\n sections.push('### Dependency Results');\n\n if (Object.keys(deps).length === 0) {\n sections.push('- No dependency results available');\n } else {\n for (const [checkName, result] of Object.entries(deps)) {\n sections.push(\n `- **${checkName}**: ${result.issueCount} issues, ${result.suggestionCount} suggestions`\n );\n }\n }\n }\n\n // Metadata section\n if (includeMetadata && templateContext.metadata) {\n const meta = templateContext.metadata as Record<string, unknown>;\n sections.push('');\n sections.push('### Execution Metadata');\n sections.push(`- **Timestamp**: ${meta.timestamp}`);\n sections.push(`- **Node Version**: ${meta.nodeVersion}`);\n sections.push(`- **Platform**: ${meta.platform}`);\n sections.push(`- **Working Directory**: ${meta.workingDirectory}`);\n }\n\n return sections.join('\\n');\n }\n\n private getLevelEmoji(level: LogLevel): string {\n switch (level) {\n case 'debug':\n return '🐛';\n case 'info':\n return 'ℹ️';\n case 'warn':\n return '⚠️';\n case 'error':\n return '❌';\n default:\n return 'ℹ️';\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'message',\n 'level',\n 'include_pr_context',\n 'include_dependencies',\n 'include_metadata',\n 'group',\n 'command',\n 'depends_on',\n 'on',\n 'if',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Log provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for debugging and logging check execution flow',\n ];\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\n\nexport class GitHubOpsProvider extends CheckProvider {\n private sandbox?: Sandbox;\n\n getName(): string {\n return 'github';\n }\n\n getDescription(): string {\n return 'Native GitHub operations (labels, comments, reviewers) executed via Octokit';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') return false;\n const cfg = config as CheckProviderConfig & { op?: string };\n return typeof cfg.op === 'string' && cfg.op.length > 0;\n }\n\n getSupportedConfigKeys(): string[] {\n return ['op', 'values', 'value', 'value_js'];\n }\n\n async isAvailable(): Promise<boolean> {\n // Available when running in GitHub context or when a token is provided\n return Boolean(\n process.env.GITHUB_TOKEN || process.env['INPUT_GITHUB-TOKEN'] || process.env.GITHUB_REPOSITORY\n );\n }\n\n getRequirements(): string[] {\n return ['GITHUB_TOKEN or INPUT_GITHUB-TOKEN', 'GITHUB_REPOSITORY'];\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<ReviewSummary> {\n const cfg = config as CheckProviderConfig & {\n op: string;\n values?: string[] | string;\n value?: string;\n value_js?: string;\n };\n\n // Use authenticated octokit from event context if available, otherwise create from env token\n let octokit: import('@octokit/rest').Octokit | undefined = config.eventContext?.octokit as\n | import('@octokit/rest').Octokit\n | undefined;\n\n if (!octokit) {\n const token = process.env['INPUT_GITHUB-TOKEN'] || process.env['GITHUB_TOKEN'];\n if (!token) {\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/missing_token',\n message:\n 'No GitHub token available; set GITHUB_TOKEN or pass github-token input for native GitHub operations',\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n const { Octokit } = await import('@octokit/rest');\n octokit = new Octokit({ auth: token });\n }\n\n const repoEnv = process.env.GITHUB_REPOSITORY || '';\n const [owner, repo] = repoEnv.split('/') as [string, string];\n if (!owner || !repo || !prInfo?.number) {\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/missing_context',\n message: 'Missing owner/repo or PR number; GitHub operations require Action context',\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n // Build values list (allow string or array), render Liquid templates if present, and normalize\n let valuesRaw: string[] = [];\n if (Array.isArray(cfg.values)) valuesRaw = (cfg.values as unknown[]).map(v => String(v));\n else if (typeof cfg.values === 'string') valuesRaw = [cfg.values];\n else if (typeof cfg.value === 'string') valuesRaw = [cfg.value];\n\n // Liquid render helper for values\n const renderValues = async (arr: string[]): Promise<string[]> => {\n if (!arr || arr.length === 0) return [];\n const liq = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n const outputs: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [name, result] of dependencyResults.entries()) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n const ctx = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n authorAssociation: prInfo.authorAssociation,\n },\n outputs,\n };\n const out: string[] = [];\n for (const item of arr) {\n if (typeof item === 'string' && (item.includes('{{') || item.includes('{%'))) {\n try {\n const rendered = await liq.parseAndRender(item, ctx);\n out.push(rendered);\n } catch (e) {\n // If Liquid fails, surface as a provider error\n const msg = e instanceof Error ? e.message : String(e);\n return Promise.reject({\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/liquid_render_error',\n message: `Failed to render template: ${msg}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n } as ReviewSummary);\n }\n } else {\n out.push(String(item));\n }\n }\n return out;\n };\n\n let values: string[] = await renderValues(valuesRaw);\n\n if (cfg.value_js && cfg.value_js.trim()) {\n try {\n // Evaluate user-provided value_js in a restricted sandbox (no process/global exposure)\n const sandbox = this.getSecureSandbox();\n const code = `\n const __fn = () => {\\n${cfg.value_js}\\n};\n return __fn();\n `;\n const exec = sandbox.compile(code);\n const res = exec({ pr: prInfo, values });\n if (typeof res === 'string') values = [res];\n else if (Array.isArray(res)) values = (res as unknown[]).map(v => String(v));\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/value_js_error',\n message: `value_js evaluation failed: ${msg}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Trim, drop empty, and de-duplicate values regardless of source\n values = values.map(v => v.trim()).filter(v => v.length > 0);\n values = Array.from(new Set(values));\n\n try {\n switch (cfg.op) {\n case 'labels.add': {\n if (values.length === 0) break; // no-op if nothing to add\n await octokit.rest.issues.addLabels({\n owner,\n repo,\n issue_number: prInfo.number,\n labels: values,\n });\n break;\n }\n case 'labels.remove': {\n for (const l of values) {\n await octokit.rest.issues.removeLabel({\n owner,\n repo,\n issue_number: prInfo.number,\n name: l,\n });\n }\n break;\n }\n case 'comment.create': {\n const body = values.join('\\n').trim();\n if (body)\n await octokit.rest.issues.createComment({\n owner,\n repo,\n issue_number: prInfo.number,\n body,\n });\n break;\n }\n default:\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/unsupported_op',\n message: `Unsupported GitHub op: ${cfg.op}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n\n return { issues: [] };\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/op_failed',\n message: `GitHub operation failed (${cfg.op}): ${msg}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n /**\n * Create a secure sandbox for evaluating small expressions without access to process/env\n */\n private getSecureSandbox(): Sandbox {\n if (this.sandbox) return this.sandbox;\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n Math,\n } as Record<string, unknown>;\n\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n const arrayMethods = new Set([\n 'some',\n 'every',\n 'filter',\n 'map',\n 'reduce',\n 'find',\n 'includes',\n 'indexOf',\n 'length',\n 'slice',\n 'concat',\n 'join',\n ]);\n prototypeWhitelist.set(Array.prototype, arrayMethods);\n\n const stringMethods = new Set([\n 'toLowerCase',\n 'toUpperCase',\n 'includes',\n 'indexOf',\n 'startsWith',\n 'endsWith',\n 'slice',\n 'substring',\n 'length',\n 'trim',\n 'split',\n 'replace',\n ]);\n prototypeWhitelist.set(String.prototype, stringMethods);\n\n const objectMethods = new Set(['hasOwnProperty', 'toString', 'valueOf']);\n prototypeWhitelist.set(Object.prototype, objectMethods);\n\n this.sandbox = new Sandbox({ globals, prototypeWhitelist });\n return this.sandbox;\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { EnvironmentResolver } from '../utils/env-resolver';\nimport { IssueFilter } from '../issue-filter';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport {\n ClaudeCodeQuery,\n ClaudeCodeResponse,\n ClaudeCodeConfig,\n ClaudeCodeClient,\n safeImport,\n} from './claude-code-types';\n\ntype ClaudeCodeConstructor = new (options: { apiKey: string }) => ClaudeCodeClient;\n\nfunction isClaudeCodeConstructor(value: unknown): value is ClaudeCodeConstructor {\n return typeof value === 'function';\n}\n\n/**\n * Error thrown when Claude Code SDK is not installed\n */\nexport class ClaudeCodeSDKNotInstalledError extends Error {\n constructor() {\n super(\n 'Claude Code SDK is not installed. Install with: npm install @anthropic/claude-code-sdk @modelcontextprotocol/sdk'\n );\n this.name = 'ClaudeCodeSDKNotInstalledError';\n }\n}\n\n/**\n * Error thrown when Claude Code API key is not configured\n */\nexport class ClaudeCodeAPIKeyMissingError extends Error {\n constructor() {\n super(\n 'No API key found for Claude Code provider. Set CLAUDE_CODE_API_KEY or ANTHROPIC_API_KEY environment variable.'\n );\n this.name = 'ClaudeCodeAPIKeyMissingError';\n }\n}\n\n/**\n * Claude Code check provider using the Claude Code TypeScript SDK\n * Supports MCP tools and streaming responses\n */\nexport class ClaudeCodeCheckProvider extends CheckProvider {\n private liquidEngine: Liquid;\n private claudeCodeClient: ClaudeCodeClient | null = null;\n\n constructor() {\n super();\n this.liquidEngine = createExtendedLiquid();\n }\n\n getName(): string {\n return 'claude-code';\n }\n\n getDescription(): string {\n return 'AI-powered code review using Claude Code with MCP tools support';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'claude-code'\n if (cfg.type !== 'claude-code') {\n return false;\n }\n\n // Check for prompt\n if (!cfg.prompt || typeof cfg.prompt !== 'string') {\n return false;\n }\n\n // Validate Claude Code specific configuration\n if (cfg.claude_code) {\n const claudeCodeConfig = cfg.claude_code as ClaudeCodeConfig;\n\n // Validate allowedTools if present\n if (claudeCodeConfig.allowedTools && !Array.isArray(claudeCodeConfig.allowedTools)) {\n return false;\n }\n\n // Validate maxTurns if present\n if (claudeCodeConfig.maxTurns && typeof claudeCodeConfig.maxTurns !== 'number') {\n return false;\n }\n\n // Validate systemPrompt if present\n if (claudeCodeConfig.systemPrompt && typeof claudeCodeConfig.systemPrompt !== 'string') {\n return false;\n }\n\n // Validate mcpServers if present\n if (claudeCodeConfig.mcpServers) {\n if (typeof claudeCodeConfig.mcpServers !== 'object') {\n return false;\n }\n\n for (const serverConfig of Object.values(claudeCodeConfig.mcpServers)) {\n if (!serverConfig.command || typeof serverConfig.command !== 'string') {\n return false;\n }\n if (serverConfig.args && !Array.isArray(serverConfig.args)) {\n return false;\n }\n }\n }\n }\n\n return true;\n }\n\n /**\n * Initialize Claude Code SDK client\n */\n private async initializeClaudeCodeClient(): Promise<ClaudeCodeClient> {\n if (this.claudeCodeClient) {\n return this.claudeCodeClient;\n }\n\n // Use safe import to avoid TypeScript compilation errors\n const claudeCodeModule = await safeImport<{\n ClaudeCode?: unknown;\n default?: { ClaudeCode?: unknown };\n }>('@anthropic/claude-code-sdk');\n\n if (!claudeCodeModule) {\n throw new ClaudeCodeSDKNotInstalledError();\n }\n\n const ClaudeCodeCtor = claudeCodeModule.ClaudeCode || claudeCodeModule.default?.ClaudeCode;\n\n if (!isClaudeCodeConstructor(ClaudeCodeCtor)) {\n throw new Error('ClaudeCode class not found in @anthropic/claude-code-sdk');\n }\n\n // Initialize with API key from environment\n const apiKey = process.env.CLAUDE_CODE_API_KEY || process.env.ANTHROPIC_API_KEY;\n if (!apiKey) {\n throw new ClaudeCodeAPIKeyMissingError();\n }\n\n try {\n const client = new ClaudeCodeCtor({\n apiKey,\n }) as ClaudeCodeClient;\n\n this.claudeCodeClient = client;\n return client;\n } catch (error) {\n throw new Error(\n `Failed to initialize Claude Code SDK: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n }\n }\n\n /**\n * Group files by their file extension for template context\n */\n private groupFilesByExtension(\n files: import('../pr-analyzer').PRFile[]\n ): Record<string, import('../pr-analyzer').PRFile[]> {\n const grouped: Record<string, import('../pr-analyzer').PRFile[]> = {};\n\n files.forEach(file => {\n const parts = file.filename.split('.');\n const ext = parts.length > 1 ? parts.pop()?.toLowerCase() || 'noext' : 'noext';\n if (!grouped[ext]) {\n grouped[ext] = [];\n }\n grouped[ext].push(file);\n });\n\n return grouped;\n }\n\n /**\n * Process prompt configuration to resolve final prompt string\n */\n private async processPrompt(\n promptConfig: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n let promptContent: string;\n\n // Auto-detect if it's a file path or inline content\n if (await this.isFilePath(promptConfig)) {\n promptContent = await this.loadPromptFromFile(promptConfig);\n } else {\n promptContent = promptConfig;\n }\n\n // Process Liquid templates in the prompt\n return await this.renderPromptTemplate(promptContent, prInfo, eventContext, dependencyResults);\n }\n\n /**\n * Detect if a string is likely a file path and if the file exists\n */\n private async isFilePath(str: string): Promise<boolean> {\n // Quick checks to exclude obvious non-file-path content\n if (!str || str.trim() !== str || str.length > 512) {\n return false;\n }\n\n // Exclude strings that are clearly content (contain common content indicators)\n if (\n /\\s{2,}/.test(str) || // Multiple consecutive spaces\n /\\n/.test(str) || // Contains newlines\n /^(please|analyze|review|check|find|identify|look|search)/i.test(str.trim()) || // Starts with command words\n str.split(' ').length > 8 // Too many words for a typical file path\n ) {\n return false;\n }\n\n // For strings with path separators, be more lenient about common words\n if (!/[\\/\\\\]/.test(str)) {\n // Only apply strict English word filter to non-path strings\n if (/\\b(the|and|or|but|for|with|by|from|in|on|at|as)\\b/i.test(str)) {\n return false;\n }\n }\n\n // Positive indicators for file paths\n const hasFileExtension = /\\.[a-zA-Z0-9]{1,10}$/i.test(str);\n const hasPathSeparators = /[\\/\\\\]/.test(str);\n const isRelativePath = /^\\.{1,2}\\//.test(str);\n const isAbsolutePath = path.isAbsolute(str);\n const hasTypicalFileChars = /^[a-zA-Z0-9._\\-\\/\\\\:~]+$/.test(str);\n\n // Must have at least one strong indicator\n if (!(hasFileExtension || isRelativePath || isAbsolutePath || hasPathSeparators)) {\n return false;\n }\n\n // Must contain only typical file path characters\n if (!hasTypicalFileChars) {\n return false;\n }\n\n // Additional validation for suspected file paths\n try {\n // Try to resolve and check if file exists\n let resolvedPath: string;\n\n if (path.isAbsolute(str)) {\n resolvedPath = path.normalize(str);\n } else {\n // Resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), str);\n }\n\n // Check if file exists\n try {\n const stat = await fs.stat(resolvedPath);\n return stat.isFile();\n } catch {\n // File doesn't exist, but might still be a valid file path format\n return hasFileExtension && (isRelativePath || isAbsolutePath || hasPathSeparators);\n }\n } catch {\n return false;\n }\n }\n\n /**\n * Load prompt content from file with security validation\n */\n private async loadPromptFromFile(promptPath: string): Promise<string> {\n // Enforce .liquid file extension for all prompt files\n if (!promptPath.endsWith('.liquid')) {\n throw new Error('Prompt file must have .liquid extension');\n }\n\n let resolvedPath: string;\n\n if (path.isAbsolute(promptPath)) {\n // Absolute path - use as-is\n resolvedPath = promptPath;\n } else {\n // Relative path - resolve relative to current working directory\n resolvedPath = path.resolve(process.cwd(), promptPath);\n }\n\n // Security: For relative paths, ensure they don't escape the current directory\n if (!path.isAbsolute(promptPath)) {\n const normalizedPath = path.normalize(resolvedPath);\n const currentDir = path.resolve(process.cwd());\n if (!normalizedPath.startsWith(currentDir)) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n }\n\n // Security: Check for obvious path traversal patterns\n if (promptPath.includes('../..')) {\n throw new Error('Invalid prompt file path: path traversal detected');\n }\n\n try {\n const promptContent = await fs.readFile(resolvedPath, 'utf-8');\n return promptContent;\n } catch (error) {\n throw new Error(\n `Failed to load prompt from ${resolvedPath}: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Render Liquid template in prompt with comprehensive context\n */\n private async renderPromptTemplate(\n promptContent: string,\n prInfo: PRInfo,\n eventContext?: Record<string, unknown>,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<string> {\n // Create comprehensive template context with PR and event information\n const templateContext = {\n // PR Information\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n baseBranch: prInfo.base,\n headBranch: prInfo.head,\n isIncremental: prInfo.isIncremental,\n filesChanged: prInfo.files?.map(f => f.filename) || [],\n totalAdditions: prInfo.files?.reduce((sum, f) => sum + f.additions, 0) || 0,\n totalDeletions: prInfo.files?.reduce((sum, f) => sum + f.deletions, 0) || 0,\n totalChanges: prInfo.files?.reduce((sum, f) => sum + f.changes, 0) || 0,\n base: prInfo.base,\n head: prInfo.head,\n },\n\n // File Details\n files: prInfo.files || [],\n description: prInfo.body || '',\n\n // GitHub Event Context\n event: eventContext\n ? {\n name: eventContext.event_name || 'unknown',\n action: eventContext.action,\n isPullRequest: !prInfo.isIssue,\n\n // Repository Info\n repository: eventContext.repository\n ? {\n owner: (eventContext.repository as { owner?: { login?: string } })?.owner?.login,\n name: (eventContext.repository as { name?: string })?.name,\n fullName: eventContext.repository\n ? `${(eventContext.repository as { owner?: { login?: string } })?.owner?.login}/${(eventContext.repository as { name?: string })?.name}`\n : undefined,\n }\n : undefined,\n\n // Comment Data (for comment events)\n comment: eventContext.comment\n ? {\n body: (eventContext.comment as { body?: string })?.body,\n author: (eventContext.comment as { user?: { login?: string } })?.user?.login,\n }\n : undefined,\n\n // Raw event payload for advanced use cases\n payload: eventContext,\n }\n : undefined,\n\n // Utility data for templates\n utils: {\n // Date/time helpers\n now: new Date().toISOString(),\n today: new Date().toISOString().split('T')[0],\n\n // Dynamic file grouping by extension\n filesByExtension: this.groupFilesByExtension(prInfo.files || []),\n\n // File status categorizations\n addedFiles: (prInfo.files || []).filter(f => f.status === 'added'),\n modifiedFiles: (prInfo.files || []).filter(f => f.status === 'modified'),\n removedFiles: (prInfo.files || []).filter(f => f.status === 'removed'),\n renamedFiles: (prInfo.files || []).filter(f => f.status === 'renamed'),\n\n // Change analysis\n hasLargeChanges: (prInfo.files || []).some(f => f.changes > 50),\n totalFiles: (prInfo.files || []).length,\n },\n\n // Previous check outputs (dependency results)\n // Expose raw output directly if available, otherwise expose the result as-is\n outputs: dependencyResults\n ? Object.fromEntries(\n Array.from(dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result\n (() => {\n const summary = result as ReviewSummary & { output?: unknown };\n return summary.output !== undefined ? summary.output : summary;\n })(),\n ])\n )\n : {},\n };\n\n try {\n return await this.liquidEngine.parseAndRender(promptContent, templateContext);\n } catch (error) {\n throw new Error(\n `Failed to render prompt template: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Parse structured response from Claude Code\n */\n private parseStructuredResponse(content: string): ReviewSummary {\n try {\n // Try to parse as JSON first\n const parsed = JSON.parse(content);\n\n // Convert to ReviewSummary format\n return {\n issues: parsed.issues || [],\n };\n } catch {\n // If not JSON, treat as plain text comment\n return {\n issues: [],\n };\n }\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Apply environment configuration if present\n if (config.env) {\n const result = EnvironmentResolver.withTemporaryEnv(config.env, () => {\n return this.executeWithConfig(prInfo, config, dependencyResults, sessionInfo);\n });\n\n if (result instanceof Promise) {\n return result;\n }\n return result;\n }\n\n return this.executeWithConfig(prInfo, config, dependencyResults, sessionInfo);\n }\n\n private async executeWithConfig(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n // Extract Claude Code configuration\n const claudeCodeConfig = (config.claude_code as ClaudeCodeConfig) || {};\n\n // Get custom prompt from config - REQUIRED\n const customPrompt = config.prompt;\n if (!customPrompt) {\n throw new Error(\n `No prompt defined for check. All checks must have prompts defined in .visor.yaml configuration.`\n );\n }\n\n // Process prompt with Liquid templates and file loading\n const processedPrompt = await this.processPrompt(\n customPrompt,\n prInfo,\n config.eventContext,\n dependencyResults\n );\n\n const startTime = Date.now();\n\n try {\n // Initialize Claude Code client\n const client = await this.initializeClaudeCodeClient();\n\n // Prepare query object with MCP servers passed directly to SDK\n const query: ClaudeCodeQuery = {\n query: processedPrompt,\n maxTurns: claudeCodeConfig.maxTurns || 5,\n systemPrompt: claudeCodeConfig.systemPrompt,\n subagent: claudeCodeConfig.subagent,\n };\n\n // Add allowed tools if specified\n if (claudeCodeConfig.allowedTools && claudeCodeConfig.allowedTools.length > 0) {\n query.tools = claudeCodeConfig.allowedTools.map(name => ({ name }));\n }\n\n // Pass MCP servers directly to the SDK - let it handle spawning and tool discovery\n if (claudeCodeConfig.mcpServers && Object.keys(claudeCodeConfig.mcpServers).length > 0) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (query as any).mcpServers = claudeCodeConfig.mcpServers;\n }\n\n // Execute query with Claude Code\n let response: ClaudeCodeResponse;\n\n if (sessionInfo?.reuseSession && sessionInfo.parentSessionId) {\n // Use session reuse if available\n response = await client.query({\n ...query,\n sessionId: sessionInfo.parentSessionId,\n });\n } else {\n // Create new session\n response = await client.query(query);\n }\n\n // Parse the response\n const result = this.parseStructuredResponse(response.content) as ReviewSummary & {\n debug?: import('../ai-review-service').AIDebugInfo & {\n sessionId?: string;\n turnCount?: number;\n usage?: unknown;\n toolsUsed?: string[];\n };\n };\n\n result.debug = {\n prompt: processedPrompt,\n rawResponse: response.content,\n provider: 'claude-code',\n model: 'claude-code',\n apiKeySource: 'CLAUDE_CODE_API_KEY',\n processingTime: Date.now() - startTime,\n promptLength: processedPrompt.length,\n responseLength: response.content.length,\n jsonParseSuccess: true,\n errors: [],\n checksExecuted: [config.checkName || 'claude-code-check'],\n parallelExecution: false,\n timestamp: new Date().toISOString(),\n // Claude Code specific debug info\n sessionId: response.session_id,\n turnCount: response.turn_count,\n usage: response.usage,\n };\n\n // Apply issue suppression filtering\n const suppressionEnabled = config.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(result.issues || [], process.cwd());\n\n return {\n ...result,\n issues: filteredIssues,\n };\n } catch (error) {\n // Re-throw setup/configuration errors that should terminate the application\n if (\n error instanceof ClaudeCodeSDKNotInstalledError ||\n error instanceof ClaudeCodeAPIKeyMissingError\n ) {\n throw error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Log detailed error information\n console.error(`❌ Claude Code Check Provider Error: ${errorMessage}`);\n\n // Check if this is a critical error\n const isCriticalError =\n errorMessage.includes('API rate limit') ||\n errorMessage.includes('403') ||\n errorMessage.includes('401') ||\n errorMessage.includes('authentication');\n\n if (isCriticalError) {\n console.error(\n `🚨 CRITICAL ERROR: Claude Code provider authentication or setup issue detected`\n );\n console.error(\n `🚨 This check cannot proceed without valid API credentials and SDK installation`\n );\n }\n\n // Re-throw with more context\n throw new Error(`Claude Code analysis failed: ${errorMessage}`);\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'claude_code.allowedTools',\n 'claude_code.maxTurns',\n 'claude_code.systemPrompt',\n 'claude_code.mcpServers',\n 'claude_code.subagent',\n 'claude_code.hooks',\n 'env',\n 'checkName',\n 'sessionId',\n 'suppressionEnabled',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n try {\n // Check if Claude Code API key is available\n const hasApiKey = !!(process.env.CLAUDE_CODE_API_KEY || process.env.ANTHROPIC_API_KEY);\n\n if (!hasApiKey) {\n return false;\n }\n\n // Try to import the SDK to check if it's installed\n const claudeCodeModule = await safeImport<{\n ClaudeCode?: unknown;\n default?: { ClaudeCode?: unknown };\n }>('@anthropic/claude-code-sdk');\n if (!claudeCodeModule) {\n return false;\n }\n const ClaudeCode = claudeCodeModule.ClaudeCode || claudeCodeModule.default?.ClaudeCode;\n\n return !!ClaudeCode;\n } catch {\n // If import fails, the SDK is not installed\n return false;\n }\n }\n\n getRequirements(): string[] {\n return [\n 'CLAUDE_CODE_API_KEY or ANTHROPIC_API_KEY environment variable',\n '@anthropic/claude-code-sdk npm package',\n '@modelcontextprotocol/sdk npm package (for MCP support)',\n 'Network access to Claude Code API',\n ];\n }\n}\n","/**\n * Type definitions for Claude Code SDK and MCP SDK\n * These are placeholder types for when the packages aren't installed\n */\n\n// Claude Code SDK types\nexport interface ClaudeCodeQuery {\n query: string;\n tools?: Array<{\n name: string;\n [key: string]: unknown;\n }>;\n subagent?: string;\n maxTurns?: number;\n systemPrompt?: string;\n sessionId?: string;\n}\n\nexport interface ClaudeCodeResponse {\n content: string;\n usage?: {\n input_tokens: number;\n output_tokens: number;\n };\n turn_count?: number;\n session_id?: string;\n}\n\nexport interface ClaudeCodeClient {\n query(options: ClaudeCodeQuery): Promise<ClaudeCodeResponse>;\n}\n\n// MCP Server configuration interface\nexport interface McpServerConfig {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\n\n// MCP Tool interface\nexport interface McpTool {\n name: string;\n description?: string;\n inputSchema?: Record<string, unknown>;\n handler?: (args: Record<string, unknown>) => Promise<unknown>;\n}\n\n// MCP Server interface\nexport interface McpServer {\n name: string;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n tools?: McpTool[];\n}\n\n// MCP Server Instance interface\nexport interface McpServerInstance {\n name: string;\n listTools(): Promise<McpTool[]>;\n callTool(name: string, args: Record<string, unknown>): Promise<unknown>;\n close(): Promise<void>;\n}\n\n// Claude Code configuration interface\nexport interface ClaudeCodeConfig {\n allowedTools?: string[];\n maxTurns?: number;\n systemPrompt?: string;\n mcpServers?: Record<string, McpServerConfig>;\n subagent?: string;\n hooks?: {\n onStart?: string;\n onEnd?: string;\n onError?: string;\n };\n}\n\n/**\n * Utility function to safely import optional dependencies\n */\nexport async function safeImport<T>(moduleName: string): Promise<T | null> {\n try {\n return await import(moduleName);\n } catch {\n return null;\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { Liquid } from 'liquidjs';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport {\n createPermissionHelpers,\n detectLocalMode,\n resolveAssociationFromEvent,\n} from '../utils/author-permissions';\n\n/**\n * Check provider that executes shell commands and captures their output\n * Supports JSON parsing and integration with forEach functionality\n */\nexport class CommandCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n cache: false,\n strictFilters: false,\n strictVariables: false,\n });\n // Lazily create sandbox only when transform_js is used\n }\n\n private createSecureSandbox(): Sandbox {\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n console: console,\n JSON: JSON,\n };\n\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n return new Sandbox({ globals, prototypeWhitelist });\n }\n\n getName(): string {\n return 'command';\n }\n\n getDescription(): string {\n return 'Execute shell commands and capture output for processing';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Must have exec specified\n if (!cfg.exec || typeof cfg.exec !== 'string') {\n return false;\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>\n ): Promise<ReviewSummary> {\n try {\n logger.info(\n ` command provider: executing check=${String((config as any).checkName || config.type)} hasTransformJs=${Boolean(\n (config as any).transform_js\n )}`\n );\n } catch {}\n const command = config.exec as string;\n const transform = config.transform as string | undefined;\n const transformJs = config.transform_js as string | undefined;\n\n // Prepare template context for Liquid rendering\n const templateContext = {\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n fileCount: prInfo.files.length,\n outputs: this.buildOutputContext(\n dependencyResults,\n config.__outputHistory as Map<string, unknown[]> | undefined\n ),\n env: this.getSafeEnvironmentVariables(),\n };\n\n logger.debug(\n `🔧 Debug: Template outputs keys: ${Object.keys(templateContext.outputs || {}).join(', ')}`\n );\n\n try {\n // Render the command with Liquid templates if needed\n let renderedCommand = command;\n if (command.includes('{{') || command.includes('{%')) {\n renderedCommand = await this.renderCommandTemplate(command, templateContext);\n }\n logger.debug(`🔧 Debug: Rendered command: ${renderedCommand}`);\n\n // Prepare environment variables - convert all to strings\n const scriptEnv: Record<string, string> = {};\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined) {\n scriptEnv[key] = value;\n }\n }\n if (config.env) {\n for (const [key, value] of Object.entries(config.env)) {\n if (value !== undefined && value !== null) {\n scriptEnv[key] = String(value);\n }\n }\n }\n\n // Execute the script using dynamic import to avoid Jest issues\n const { exec } = await import('child_process');\n const { promisify } = await import('util');\n const execAsync = promisify(exec);\n\n // Get timeout from config (in seconds) or use default (60 seconds)\n const timeoutSeconds = (config.timeout as number) || 60;\n const timeoutMs = timeoutSeconds * 1000;\n\n // Normalize only the eval payload for `node -e|--eval` invocations that may contain\n // literal newlines due to YAML processing (\"\\n\" -> newline). We re-escape newlines\n // inside the quoted eval argument to keep JS string literals valid, without touching\n // the rest of the command.\n const normalizeNodeEval = (cmd: string): string => {\n const re =\n /^(?<prefix>\\s*(?:\\/usr\\/bin\\/env\\s+)?node(?:\\.exe)?\\s+(?:-e|--eval)\\s+)(['\"])([\\s\\S]*?)\\2(?<suffix>\\s|$)/;\n const m = cmd.match(re) as\n | (RegExpMatchArray & { groups?: { prefix: string; suffix?: string } })\n | null;\n if (!m || !m.groups) return cmd;\n const prefix = m.groups.prefix;\n const quote = m[2];\n const code = m[3];\n const suffix = m.groups.suffix || '';\n if (!code.includes('\\n')) return cmd;\n const escaped = code.replace(/\\n/g, '\\\\n');\n return cmd.replace(re, `${prefix}${quote}${escaped}${quote}${suffix}`);\n };\n\n const safeCommand = normalizeNodeEval(renderedCommand);\n\n const { stdout, stderr } = await execAsync(safeCommand, {\n env: scriptEnv,\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024, // 10MB buffer\n });\n\n if (stderr) {\n logger.debug(`Command stderr: ${stderr}`);\n }\n\n // Keep raw output for transforms\n const rawOutput = stdout.trim();\n\n // Try to parse output as JSON for default behavior\n // no debug\n let output: unknown = rawOutput;\n try {\n // Attempt to parse as JSON\n const parsed = JSON.parse(rawOutput);\n output = parsed;\n logger.debug(`🔧 Debug: Parsed entire output as JSON successfully`);\n } catch {\n // Try to extract JSON from the end of output (for commands with debug logs)\n const extractedTail = this.extractJsonFromEnd(rawOutput);\n if (extractedTail) {\n try {\n output = JSON.parse(extractedTail);\n } catch {\n output = rawOutput;\n }\n } else {\n // Try to extract any balanced JSON substring anywhere\n const extractedAny = this.extractJsonAnywhere(rawOutput);\n if (extractedAny) {\n try {\n output = JSON.parse(extractedAny);\n } catch {\n output = rawOutput;\n }\n } else {\n // Last resort: detect common boolean flags like error:true or error=false for fail_if gating\n const m = /\\berror\\b\\s*[:=]\\s*(true|false)/i.exec(rawOutput);\n if (m) {\n output = { error: m[1].toLowerCase() === 'true' } as any;\n } else {\n output = rawOutput;\n }\n }\n }\n }\n\n // Log the parsed structure for debugging\n // no debug\n\n // Apply transform if specified (Liquid or JavaScript)\n let finalOutput = output;\n\n // First apply Liquid transform if present\n if (transform) {\n try {\n const transformContext = {\n ...templateContext,\n output: output, // Use parsed output for Liquid (object if JSON, string otherwise)\n };\n const rendered = await this.liquid.parseAndRender(transform, transformContext);\n\n // Try to parse the transformed result as JSON\n try {\n finalOutput = JSON.parse(rendered.trim());\n logger.verbose(`✓ Applied Liquid transform successfully (parsed as JSON)`);\n } catch {\n finalOutput = rendered.trim();\n logger.verbose(`✓ Applied Liquid transform successfully (string output)`);\n }\n } catch (error) {\n logger.error(\n `✗ Failed to apply Liquid transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/transform_error',\n message: `Failed to apply Liquid transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Then apply JavaScript transform if present\n if (transformJs) {\n try {\n // For transform_js, provide a JSON-smart wrapper that:\n // - behaves like a string when coerced (so JSON.parse(output) still works)\n // - exposes parsed JSON properties if stdout is valid JSON (so output.key works)\n const jsContext = {\n output: this.makeJsonSmart(rawOutput),\n pr: templateContext.pr,\n files: templateContext.files,\n outputs: this.makeOutputsJsonSmart(templateContext.outputs),\n env: templateContext.env,\n permissions: createPermissionHelpers(\n resolveAssociationFromEvent((prInfo as any).eventContext, prInfo.authorAssociation),\n detectLocalMode()\n ),\n };\n\n // Compile and execute the JavaScript expression\n // Use direct property access instead of destructuring to avoid syntax issues\n const trimmedTransform = transformJs.trim();\n // Build a safe function body that supports statements + implicit last-expression return.\n const buildBodyWithReturn = (raw: string): string => {\n const t = raw.trim();\n // Find last non-empty line\n const lines = t.split(/\\n/);\n let i = lines.length - 1;\n while (i >= 0 && lines[i].trim().length === 0) i--;\n if (i < 0) return 'return undefined;';\n const lastLine = lines[i].trim();\n if (/^return\\b/i.test(lastLine)) {\n return t;\n }\n const idx = t.lastIndexOf(lastLine);\n const head = idx >= 0 ? t.slice(0, idx) : '';\n const lastExpr = lastLine.replace(/;\\s*$/, '');\n return `${head}\\nreturn (${lastExpr});`;\n };\n const bodyWithReturn = buildBodyWithReturn(trimmedTransform);\n\n const code = `\n const output = scope.output;\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const env = scope.env;\n const log = (...args) => { console.log('🔍 Debug:', ...args); };\n const hasMinPermission = scope.permissions.hasMinPermission;\n const isOwner = scope.permissions.isOwner;\n const isMember = scope.permissions.isMember;\n const isCollaborator = scope.permissions.isCollaborator;\n const isContributor = scope.permissions.isContributor;\n const isFirstTimer = scope.permissions.isFirstTimer;\n const __result = (function(){\n${bodyWithReturn}\n })();\n return __result;\n `;\n\n // Execute user code exclusively inside the sandbox\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n // Try to serialize result to JSON string inside sandbox to preserve primitives like booleans\n let parsedFromSandboxJson: any = undefined;\n try {\n const stringifyCode = `\n const output = scope.output;\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const env = scope.env;\n const log = (...args) => { console.log('🔍 Debug:', ...args); };\n const hasMinPermission = scope.permissions.hasMinPermission;\n const isOwner = scope.permissions.isOwner;\n const isMember = scope.permissions.isMember;\n const isCollaborator = scope.permissions.isCollaborator;\n const isContributor = scope.permissions.isContributor;\n const isFirstTimer = scope.permissions.isFirstTimer;\n const __ret = (function(){\n${bodyWithReturn}\n })();\n return typeof __ret === 'object' && __ret !== null ? JSON.stringify(__ret) : null;\n `;\n const stringifyExec = this.sandbox.compile(stringifyCode);\n const jsonStr = stringifyExec({ scope: jsContext }).run();\n if (typeof jsonStr === 'string' && jsonStr.trim().startsWith('{')) {\n parsedFromSandboxJson = JSON.parse(jsonStr);\n }\n } catch {}\n\n if (parsedFromSandboxJson !== undefined) {\n finalOutput = parsedFromSandboxJson;\n } else {\n const exec = this.sandbox.compile(code);\n finalOutput = exec({ scope: jsContext }).run();\n }\n\n // Fallback: if sandbox could not preserve primitives (e.g., booleans lost),\n // attempt to re-evaluate the transform in a locked Node VM context to get plain JS values.\n try {\n if (\n finalOutput &&\n typeof finalOutput === 'object' &&\n !Array.isArray(finalOutput) &&\n ((finalOutput as any).error === undefined ||\n (finalOutput as any).issues === undefined)\n ) {\n const vm = await import('node:vm');\n const vmContext = vm.createContext({ scope: jsContext });\n const vmCode = `\n (function(){\n const output = scope.output; const pr = scope.pr; const files = scope.files; const outputs = scope.outputs; const env = scope.env; const log = ()=>{};\n${bodyWithReturn}\n })()\n `;\n const vmResult = vm.runInContext(vmCode, vmContext, { timeout: 1000 });\n if (vmResult && typeof vmResult === 'object') {\n finalOutput = vmResult;\n }\n }\n } catch {}\n // Create a plain JSON snapshot of the transform result to avoid proxy/getter surprises\n // Prefer JSON stringify inside the sandbox realm (so it knows how to serialize its own objects),\n // then fall back to host-side JSON clone and finally to a shallow copy of own enumerable properties.\n let finalSnapshot: Record<string, unknown> | null = null;\n try {\n if (finalOutput && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n // Try realm-local stringify first\n try {\n const stringifyExec = this.sandbox!.compile('return JSON.stringify(scope.obj);');\n const jsonStr = stringifyExec({ obj: finalOutput }).run();\n if (typeof jsonStr === 'string' && jsonStr.trim().startsWith('{')) {\n finalSnapshot = JSON.parse(jsonStr);\n }\n } catch {}\n if (!finalSnapshot) {\n try {\n finalSnapshot = JSON.parse(JSON.stringify(finalOutput));\n } catch {}\n }\n if (!finalSnapshot) {\n const tmp: Record<string, unknown> = {};\n for (const k of Object.keys(finalOutput as Record<string, unknown>)) {\n (tmp as any)[k] = (finalOutput as any)[k];\n }\n finalSnapshot = tmp;\n }\n }\n } catch {}\n // @ts-ignore store for later extraction path\n (this as any).__lastTransformSnapshot = finalSnapshot;\n try {\n const isObj =\n finalOutput && typeof finalOutput === 'object' && !Array.isArray(finalOutput);\n const keys = isObj\n ? Object.keys(finalOutput as Record<string, unknown>).join(',')\n : typeof finalOutput;\n logger.debug(\n ` transform_js: output typeof=${Array.isArray(finalOutput) ? 'array' : typeof finalOutput} keys=${keys}`\n );\n if (isObj && (finalOutput as any).issues) {\n const mi: any = (finalOutput as any).issues;\n logger.debug(\n ` transform_js: issues typeof=${Array.isArray(mi) ? 'array' : typeof mi} len=${(mi && mi.length) || 0}`\n );\n }\n try {\n if (isObj)\n logger.debug(` transform_js: error value=${String((finalOutput as any).error)}`);\n } catch {}\n } catch {}\n\n logger.verbose(`✓ Applied JavaScript transform successfully`);\n // Already normalized in sandbox result\n // no debug\n } catch (error) {\n logger.error(\n `✗ Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId: 'command/transform_js_error',\n message: `Failed to apply JavaScript transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Extract structured issues when the command returns them (skip for forEach parents)\n // no debug\n let issues: ReviewIssue[] = [];\n let outputForDependents: unknown = finalOutput;\n // Capture a shallow snapshot created earlier if available (within transform_js path)\n // @ts-ignore - finalSnapshot is defined in the transform_js scope above when applicable\n // @ts-ignore retrieve snapshot captured after transform_js (if any)\n const snapshotForExtraction: Record<string, unknown> | null =\n (this as any).__lastTransformSnapshot || null;\n try {\n if (snapshotForExtraction) {\n logger.debug(` provider: snapshot keys=${Object.keys(snapshotForExtraction).join(',')}`);\n } else {\n logger.debug(` provider: snapshot is null`);\n }\n } catch {}\n // Some shells may wrap JSON output inside a one-element array due to quoting.\n // If we see a single-element array containing a JSON string or object, unwrap it.\n try {\n if (Array.isArray(outputForDependents) && (outputForDependents as unknown[]).length === 1) {\n const first = (outputForDependents as unknown[])[0];\n if (typeof first === 'string') {\n try {\n outputForDependents = JSON.parse(first);\n } catch {}\n } else if (first && typeof first === 'object') {\n outputForDependents = first as unknown;\n }\n }\n } catch {}\n\n let content: string | undefined;\n let extracted: { issues: ReviewIssue[]; remainingOutput: unknown } | null = null;\n\n const trimmedRawOutput = typeof rawOutput === 'string' ? rawOutput.trim() : undefined;\n\n const commandConfig = config as CheckProviderConfig & { forEach?: boolean };\n const isForEachParent = commandConfig.forEach === true;\n\n if (!isForEachParent) {\n // Generic: if transform output is an object and contains an 'issues' field,\n // expose all other fields to dependents regardless of whether we successfully\n // normalized the issues array. This preserves flags like 'error' for fail_if.\n try {\n const baseObj = (snapshotForExtraction || (finalOutput as any)) as Record<\n string,\n unknown\n >;\n if (\n baseObj &&\n typeof baseObj === 'object' &&\n Object.prototype.hasOwnProperty.call(baseObj, 'issues')\n ) {\n const remaining = { ...baseObj } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n try {\n const k =\n outputForDependents && typeof outputForDependents === 'object'\n ? Object.keys(outputForDependents as any).join(',')\n : String(outputForDependents);\n logger.debug(` provider: generic-remaining keys=${k}`);\n } catch {}\n }\n } catch {}\n // Fast path for transform_js objects that include an issues array (realm-agnostic)\n const objForExtraction = (snapshotForExtraction || (finalOutput as any)) as Record<\n string,\n unknown\n >;\n if (objForExtraction && typeof objForExtraction === 'object') {\n try {\n const rec = objForExtraction;\n const maybeIssues: any = (rec as any).issues;\n const toPlainArray = (v: any): any[] | null => {\n if (Array.isArray(v)) return v;\n try {\n if (v && typeof v === 'object' && typeof v[Symbol.iterator] === 'function') {\n return Array.from(v);\n }\n } catch {}\n const len = Number((v || {}).length);\n if (Number.isFinite(len) && len >= 0) {\n const arr: any[] = [];\n for (let i = 0; i < len; i++) arr.push(v[i]);\n return arr;\n }\n try {\n const cloned = JSON.parse(JSON.stringify(v));\n return Array.isArray(cloned) ? cloned : null;\n } catch {\n return null;\n }\n };\n try {\n const ctor =\n maybeIssues && (maybeIssues as any).constructor\n ? (maybeIssues as any).constructor.name\n : 'unknown';\n logger.debug(\n ` provider: issues inspect typeof=${typeof maybeIssues} Array.isArray=${Array.isArray(\n maybeIssues\n )} ctor=${ctor} keys=${Object.keys((maybeIssues || {}) as any).join(',')}`\n );\n } catch {}\n const arr = toPlainArray(maybeIssues);\n if (arr) {\n const norm = this.normalizeIssueArray(arr);\n if (norm) {\n issues = norm;\n const remaining = { ...rec } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n try {\n const keys =\n outputForDependents && typeof outputForDependents === 'object'\n ? Object.keys(outputForDependents as any).join(',')\n : String(outputForDependents);\n logger.info(\n ` provider: fast-path issues=${issues.length} remaining keys=${keys}`\n );\n } catch {}\n } else {\n try {\n logger.info(' provider: fast-path norm failed');\n } catch {}\n }\n } else {\n try {\n logger.info(' provider: fast-path arr unavailable');\n } catch {}\n }\n } catch {}\n }\n // Normalize extraction target: unwrap one-element arrays like [\"{...}\"] or [{...}]\n let extractionTarget: unknown = snapshotForExtraction || finalOutput;\n try {\n if (Array.isArray(extractionTarget) && (extractionTarget as unknown[]).length === 1) {\n const first = (extractionTarget as unknown[])[0];\n if (typeof first === 'string') {\n try {\n extractionTarget = JSON.parse(first);\n } catch {\n extractionTarget = first;\n }\n } else if (first && typeof first === 'object') {\n extractionTarget = first as unknown;\n }\n }\n } catch {}\n extracted = this.extractIssuesFromOutput(extractionTarget);\n try {\n if (extractionTarget !== (snapshotForExtraction || finalOutput)) {\n finalOutput = extractionTarget;\n }\n } catch {}\n // no debug\n // Handle cross-realm Arrays from sandbox: issues may look like an array but fail Array.isArray\n if (!extracted && finalOutput && typeof finalOutput === 'object') {\n try {\n const rec = finalOutput as Record<string, unknown>;\n const maybeIssues: any = (rec as any).issues;\n if (maybeIssues && typeof maybeIssues === 'object') {\n let arr: any[] | null = null;\n // Prefer iterator if present\n try {\n if (typeof maybeIssues[Symbol.iterator] === 'function') {\n arr = Array.from(maybeIssues);\n }\n } catch {}\n // Fallback to length-based copy\n if (!arr) {\n const len = Number((maybeIssues as any).length);\n if (Number.isFinite(len) && len >= 0) {\n arr = [];\n for (let i = 0; i < len; i++) arr.push(maybeIssues[i]);\n }\n }\n // Last resort: JSON clone\n if (!arr) {\n try {\n arr = JSON.parse(JSON.stringify(maybeIssues));\n } catch {}\n }\n if (arr && Array.isArray(arr)) {\n const norm = this.normalizeIssueArray(arr);\n if (norm) {\n issues = norm;\n const remaining = { ...rec } as Record<string, unknown>;\n delete (remaining as any).issues;\n outputForDependents = Object.keys(remaining).length > 0 ? remaining : undefined;\n }\n }\n }\n } catch {}\n }\n if (!extracted && typeof finalOutput === 'string') {\n // Attempt to parse string output as JSON and extract issues again\n try {\n const parsed = JSON.parse(finalOutput);\n extracted = this.extractIssuesFromOutput(parsed);\n if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n // If remainingOutput carries a content field, pick it up\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n } catch {\n // Try to salvage JSON from anywhere within the string (stripped logs/ansi)\n try {\n const any = this.extractJsonAnywhere(finalOutput);\n if (any) {\n const parsed = JSON.parse(any);\n extracted = this.extractIssuesFromOutput(parsed);\n if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n }\n } catch {\n // leave as-is\n }\n }\n } else if (extracted) {\n issues = extracted.issues;\n outputForDependents = extracted.remainingOutput;\n // Also propagate embedded content when remainingOutput is an object { content, ... }\n if (\n typeof extracted.remainingOutput === 'object' &&\n extracted.remainingOutput !== null &&\n typeof (extracted.remainingOutput as any).content === 'string'\n ) {\n const c = String((extracted.remainingOutput as any).content).trim();\n if (c) content = c;\n }\n }\n\n if (!issues.length && this.shouldTreatAsTextOutput(trimmedRawOutput)) {\n content = trimmedRawOutput;\n } else if (issues.length && typeof extracted?.remainingOutput === 'string') {\n const trimmed = extracted.remainingOutput.trim();\n if (trimmed) {\n content = trimmed;\n }\n }\n\n // Generic fallback: if issues are still empty, try to parse raw stdout as JSON and extract issues.\n if (!issues.length && typeof trimmedRawOutput === 'string') {\n try {\n const tryParsed = JSON.parse(trimmedRawOutput);\n const reextract = this.extractIssuesFromOutput(tryParsed);\n if (reextract && reextract.issues && reextract.issues.length) {\n issues = reextract.issues;\n if (!outputForDependents && reextract.remainingOutput) {\n outputForDependents = reextract.remainingOutput;\n }\n } else if (Array.isArray(tryParsed)) {\n // Treat parsed array as potential issues array or array of { issues: [...] }\n const first = tryParsed[0];\n if (first && typeof first === 'object' && Array.isArray((first as any).issues)) {\n const merged: unknown[] = [];\n for (const el of tryParsed as unknown[]) {\n if (el && typeof el === 'object' && Array.isArray((el as any).issues)) {\n merged.push(...((el as any).issues as unknown[]));\n }\n }\n const flat = this.normalizeIssueArray(merged);\n if (flat) issues = flat;\n } else {\n // Try to parse string elements into JSON objects and extract\n const converted: unknown[] = [];\n for (const el of tryParsed as unknown[]) {\n if (typeof el === 'string') {\n try {\n const obj = JSON.parse(el);\n converted.push(obj);\n } catch {\n // keep as-is\n }\n } else {\n converted.push(el);\n }\n }\n const flat = this.normalizeIssueArray(converted as unknown[]);\n if (flat) issues = flat;\n }\n }\n } catch {}\n if (!issues.length) {\n try {\n const any = this.extractJsonAnywhere(trimmedRawOutput);\n if (any) {\n const tryParsed = JSON.parse(any);\n const reextract = this.extractIssuesFromOutput(tryParsed);\n if (reextract && reextract.issues && reextract.issues.length) {\n issues = reextract.issues;\n if (!outputForDependents && reextract.remainingOutput) {\n outputForDependents = reextract.remainingOutput;\n }\n }\n }\n } catch {}\n }\n }\n\n // Preserve all primitive flags (boolean/number/string) from original transform output\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (\n outputForDependents &&\n typeof outputForDependents === 'object' &&\n srcObj &&\n typeof srcObj === 'object'\n ) {\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean' || typeof v === 'number' || typeof v === 'string') {\n (outputForDependents as any)[k] = v;\n }\n }\n }\n } catch {}\n\n // Normalize output object to a plain shallow object (avoid JSON stringify drop of false booleans)\n try {\n if (\n outputForDependents &&\n typeof outputForDependents === 'object' &&\n !Array.isArray(outputForDependents)\n ) {\n const plain: Record<string, unknown> = {};\n for (const k of Object.keys(outputForDependents as any)) {\n (plain as any)[k] = (outputForDependents as any)[k];\n }\n outputForDependents = plain;\n }\n } catch {}\n }\n\n if (!content && this.shouldTreatAsTextOutput(trimmedRawOutput) && !isForEachParent) {\n content = trimmedRawOutput;\n }\n\n // Normalize output object to plain JSON to avoid cross-realm proxy quirks\n try {\n if (outputForDependents && typeof outputForDependents === 'object') {\n outputForDependents = JSON.parse(JSON.stringify(outputForDependents));\n }\n } catch {}\n\n // Promote primitive flags from original transform output to top-level result fields (schema-agnostic)\n const promoted: Record<string, unknown> = {};\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (srcObj && typeof srcObj === 'object') {\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean') {\n if (v === true && promoted[k] === undefined) promoted[k] = true;\n } else if (\n (typeof v === 'number' || typeof v === 'string') &&\n promoted[k] === undefined\n ) {\n promoted[k] = v;\n }\n }\n }\n } catch {}\n\n // Return the output and issues as part of the review summary so dependent checks can use them\n const result = {\n issues,\n output: outputForDependents,\n ...(content ? { content } : {}),\n ...promoted,\n } as ReviewSummary;\n\n // Attach raw transform object only when transform_js was used (avoid polluting plain command outputs)\n try {\n if (transformJs) {\n const rawObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n if (rawObj && typeof rawObj === 'object') {\n (result as any).__raw = rawObj;\n }\n }\n } catch {}\n\n // Final safeguard: ensure primitive flags from original transform output are present in result.output.\n // Do this without dropping explicit false values (important for fail_if like `output.error`).\n try {\n const srcObj = (snapshotForExtraction || (finalOutput as any)) as Record<string, unknown>;\n const srcErr = ((): boolean | undefined => {\n try {\n if (\n snapshotForExtraction &&\n typeof snapshotForExtraction === 'object' &&\n (snapshotForExtraction as any).error !== undefined\n ) {\n return Boolean((snapshotForExtraction as any).error);\n }\n if (\n finalOutput &&\n typeof finalOutput === 'object' &&\n (finalOutput as any).error !== undefined\n ) {\n return Boolean((finalOutput as any).error);\n }\n } catch {}\n return undefined;\n })();\n const dst = (result as any).output;\n if (srcObj && typeof srcObj === 'object' && dst && typeof dst === 'object') {\n try {\n logger.debug(\n ` provider: safeguard src.error typeof=${typeof (srcObj as any).error} val=${String((srcObj as any).error)} dst.hasErrorBefore=${String((dst as any).error !== undefined)}`\n );\n } catch {}\n for (const k of Object.keys(srcObj)) {\n const v: any = (srcObj as any)[k];\n if (typeof v === 'boolean' || typeof v === 'number' || typeof v === 'string') {\n (dst as any)[k] = v;\n }\n }\n // Explicitly normalize a common flag used in tests/pipelines\n if (srcErr !== undefined && (dst as any).error === undefined) {\n (dst as any).error = srcErr;\n try {\n const k = Object.keys(dst as any).join(',');\n logger.debug(\n ` provider: safeguard merged error -> output keys=${k} val=${String((dst as any).error)}`\n );\n } catch {}\n }\n }\n } catch {}\n\n try {\n const out: any = (result as any).output;\n if (out && typeof out === 'object') {\n const k = Object.keys(out as Record<string, unknown>).join(',');\n logger.debug(` provider: return output keys=${k}`);\n } else {\n logger.debug(` provider: return output type=${typeof out}`);\n }\n } catch {}\n\n // no debug\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n\n // Check if this is a timeout error\n let isTimeout = false;\n if (error && typeof error === 'object') {\n const execError = error as { killed?: boolean; signal?: string; code?: string | number };\n // Node's child_process sets killed=true and signal='SIGTERM' on timeout\n if (execError.killed && execError.signal === 'SIGTERM') {\n isTimeout = true;\n }\n // Some versions may also set code to 'ETIMEDOUT'\n if (execError.code === 'ETIMEDOUT') {\n isTimeout = true;\n }\n }\n\n // Extract stderr from the error if available (child_process errors include stdout/stderr)\n let stderrOutput = '';\n if (error && typeof error === 'object') {\n const execError = error as { stderr?: string; stdout?: string };\n if (execError.stderr) {\n stderrOutput = execError.stderr.trim();\n }\n }\n\n // Construct detailed error message\n let detailedMessage: string;\n let ruleId: string;\n\n if (isTimeout) {\n const timeoutSeconds = (config.timeout as number) || 60;\n detailedMessage = `Command execution timed out after ${timeoutSeconds} seconds`;\n if (stderrOutput) {\n detailedMessage += `\\n\\nStderr output:\\n${stderrOutput}`;\n }\n ruleId = 'command/timeout';\n } else {\n detailedMessage = stderrOutput\n ? `Command execution failed: ${errorMessage}\\n\\nStderr output:\\n${stderrOutput}`\n : `Command execution failed: ${errorMessage}`;\n ruleId = 'command/execution_error';\n }\n\n logger.error(`✗ ${detailedMessage}`);\n\n return {\n issues: [\n {\n file: 'command',\n line: 0,\n ruleId,\n message: detailedMessage,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n private buildOutputContext(\n dependencyResults?: Map<string, ReviewSummary>,\n outputHistory?: Map<string, unknown[]>\n ): Record<string, unknown> {\n if (!dependencyResults) {\n return {};\n }\n\n const outputs: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n\n for (const [checkName, result] of dependencyResults) {\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result as-is\n const summary = result as ReviewSummary & { output?: unknown };\n const value = summary.output !== undefined ? summary.output : summary;\n outputs[checkName] = this.makeJsonSmart(value);\n }\n\n // Add history for each check if available\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n history[checkName] = historyArray.map(val => this.makeJsonSmart(val));\n }\n }\n\n // Attach history to the outputs object\n (outputs as any).history = history;\n\n return outputs;\n }\n\n /**\n * Wrap a value with JSON-smart behavior:\n * - If it's a JSON string, expose parsed properties via Proxy (e.g., value.key)\n * - When coerced to string (toString/valueOf/Symbol.toPrimitive), return the original raw string\n * - If parsing fails or value is not a string, return the value unchanged\n * - Attempts to extract JSON from the end of the output if full parse fails\n */\n private makeJsonSmart<T = unknown>(value: T): T | any {\n if (typeof value !== 'string') {\n return value;\n }\n\n const raw = value as unknown as string;\n let parsed: any;\n\n // First try: parse the entire string as JSON\n try {\n parsed = JSON.parse(raw);\n } catch {\n // Second try: extract JSON from the end of the output\n // Look for { or [ at the start of a line and take everything after it\n const jsonMatch = this.extractJsonFromEnd(raw);\n if (jsonMatch) {\n try {\n parsed = JSON.parse(jsonMatch);\n logger.debug(\n `🔧 Debug: Extracted JSON from end of output (${jsonMatch.length} chars from ${raw.length} total)`\n );\n } catch {\n // Not valid JSON even after extraction, return original string\n return raw;\n }\n } else {\n // Not JSON, return original string\n return raw;\n }\n }\n\n // Use a boxed string so string methods still work via Proxy fallback\n const boxed = new String(raw);\n const handler: ProxyHandler<any> = {\n get(target, prop, receiver) {\n if (prop === 'toString' || prop === 'valueOf') {\n return () => raw;\n }\n if (prop === Symbol.toPrimitive) {\n return () => raw;\n }\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n if (prop in parsed) {\n return (parsed as any)[prop as any];\n }\n }\n return Reflect.get(target, prop, receiver);\n },\n has(_target, prop) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n if (prop in parsed) return true;\n }\n return false;\n },\n ownKeys(_target) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n try {\n return Reflect.ownKeys(parsed);\n } catch {\n return [];\n }\n }\n return [];\n },\n getOwnPropertyDescriptor(_target, prop) {\n if (parsed != null && (typeof parsed === 'object' || Array.isArray(parsed))) {\n const descriptor = Object.getOwnPropertyDescriptor(parsed, prop as any);\n if (descriptor) return descriptor;\n }\n return {\n configurable: true,\n enumerable: true,\n writable: false,\n value: undefined,\n };\n },\n };\n return new Proxy(boxed, handler);\n }\n\n /**\n * Extract JSON from the end of a string that may contain logs/debug output\n * Looks for the last occurrence of { or [ and tries to parse from there\n */\n private extractJsonFromEnd(text: string): string | null {\n // Robust strategy: find the last closing brace/bracket, then walk backwards to the matching opener\n const lastBrace = Math.max(text.lastIndexOf('}'), text.lastIndexOf(']'));\n if (lastBrace === -1) return null;\n // Scan backwards to find matching opener with a simple counter\n let open = 0;\n for (let i = lastBrace; i >= 0; i--) {\n const ch = text[i];\n if (ch === '}' || ch === ']') open++;\n else if (ch === '{' || ch === '[') open--;\n if (open === 0 && (ch === '{' || ch === '[')) {\n const candidate = text.slice(i, lastBrace + 1).trim();\n try {\n JSON.parse(candidate);\n return candidate;\n } catch {\n return null;\n }\n }\n }\n return null;\n }\n\n // Extract any balanced JSON object/array substring from anywhere in the text\n private extractJsonAnywhere(text: string): string | null {\n const n = text.length;\n let best: string | null = null;\n for (let i = 0; i < n; i++) {\n const start = text[i];\n if (start !== '{' && start !== '[') continue;\n let open = 0;\n let inString = false;\n let escape = false;\n for (let j = i; j < n; j++) {\n const ch = text[j];\n if (escape) {\n escape = false;\n continue;\n }\n if (ch === '\\\\') {\n escape = true;\n continue;\n }\n if (ch === '\"') {\n inString = !inString;\n continue;\n }\n if (inString) continue;\n if (ch === '{' || ch === '[') open++;\n else if (ch === '}' || ch === ']') open--;\n if (open === 0 && (ch === '}' || ch === ']')) {\n const candidate = text.slice(i, j + 1).trim();\n try {\n JSON.parse(candidate);\n best = candidate; // keep the last valid one we find\n } catch {\n // Try a loose-to-strict conversion (quote keys and barewords)\n const strict = this.looseJsonToStrict(candidate);\n if (strict) {\n try {\n JSON.parse(strict);\n best = strict;\n } catch {}\n }\n }\n break;\n }\n }\n }\n return best;\n }\n\n // Best-effort conversion of object-literal-like strings to strict JSON\n private looseJsonToStrict(candidate: string): string | null {\n try {\n let s = candidate.trim();\n // Convert single quotes to double quotes conservatively\n s = s.replace(/'/g, '\"');\n // Quote unquoted keys: {key: ...} or ,key: ...\n s = s.replace(/([\\{,]\\s*)([A-Za-z_][A-Za-z0-9_-]*)\\s*:/g, '$1\"$2\":');\n // Quote bareword values except true/false/null and numbers\n s = s.replace(/:\\s*([A-Za-z_][A-Za-z0-9_-]*)\\s*(?=[,}])/g, (m, word) => {\n const lw = String(word).toLowerCase();\n if (lw === 'true' || lw === 'false' || lw === 'null') return `:${lw}`;\n return `:\"${word}\"`;\n });\n return s;\n } catch {\n return null;\n }\n }\n\n /**\n * Recursively apply JSON-smart wrapper to outputs object values\n */\n private makeOutputsJsonSmart(outputs: Record<string, unknown>): Record<string, unknown> {\n const wrapped: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(outputs || {})) {\n wrapped[k] = this.makeJsonSmart(v);\n }\n return wrapped;\n }\n\n private getSafeEnvironmentVariables(): Record<string, string> {\n const safeVars: Record<string, string> = {};\n const allowedPrefixes = ['CI_', 'GITHUB_', 'RUNNER_', 'NODE_', 'npm_', 'PATH', 'HOME', 'USER'];\n\n for (const [key, value] of Object.entries(process.env)) {\n if (value !== undefined && allowedPrefixes.some(prefix => key.startsWith(prefix))) {\n safeVars[key] = value;\n }\n }\n\n // Add current working directory\n safeVars['PWD'] = process.cwd();\n\n return safeVars;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'exec',\n 'transform',\n 'transform_js',\n 'env',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n 'forEach',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Command provider is always available as long as we can execute commands\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'Valid shell command to execute',\n 'Shell environment available',\n 'Optional: Transform template for processing output',\n ];\n }\n\n private extractIssuesFromOutput(\n output: unknown\n ): { issues: ReviewIssue[]; remainingOutput: unknown } | null {\n try {\n logger.info(\n ` extractIssuesFromOutput: typeof=${Array.isArray(output) ? 'array' : typeof output}`\n );\n if (typeof output === 'object' && output) {\n const rec = output as Record<string, unknown>;\n logger.info(\n ` extractIssuesFromOutput: keys=${Object.keys(rec).join(',')} issuesIsArray=${Array.isArray(\n (rec as any).issues\n )}`\n );\n }\n } catch {}\n if (output === null || output === undefined) {\n return null;\n }\n\n // If output is already a string, do not treat it as issues here (caller may try parsing JSON)\n if (typeof output === 'string') {\n return null;\n }\n\n if (Array.isArray(output)) {\n // Two supported shapes:\n // 1) Array<ReviewIssue-like>\n // 2) Array<{ issues: Array<ReviewIssue-like> }>\n const first = output[0];\n if (\n first &&\n typeof first === 'object' &&\n !Array.isArray((first as any).message) &&\n Array.isArray((first as any).issues)\n ) {\n // flatten nested issues arrays\n const merged: unknown[] = [];\n for (const el of output as unknown[]) {\n if (el && typeof el === 'object' && Array.isArray((el as any).issues)) {\n merged.push(...((el as any).issues as unknown[]));\n }\n }\n const flat = this.normalizeIssueArray(merged);\n if (flat) return { issues: flat, remainingOutput: undefined };\n } else {\n const issues = this.normalizeIssueArray(output);\n if (issues) {\n return { issues, remainingOutput: undefined };\n }\n }\n return null;\n }\n\n if (typeof output === 'object') {\n const record = output as Record<string, unknown>;\n\n if (Array.isArray(record.issues)) {\n const issues = this.normalizeIssueArray(record.issues);\n if (!issues) {\n return null;\n }\n\n const remaining = { ...record };\n delete (remaining as { issues?: unknown }).issues;\n\n const remainingKeys = Object.keys(remaining);\n const remainingOutput = remainingKeys.length > 0 ? remaining : undefined;\n\n return {\n issues,\n remainingOutput,\n };\n }\n\n const singleIssue = this.normalizeIssue(record);\n if (singleIssue) {\n return { issues: [singleIssue], remainingOutput: undefined };\n }\n }\n\n return null;\n }\n\n private shouldTreatAsTextOutput(value?: string): value is string {\n if (!value) {\n return false;\n }\n\n const trimmed = value.trim();\n if (!trimmed) {\n return false;\n }\n\n // Heuristic: consider it JSON-like if it starts with { or [ and ends with } or ]\n const startsJson =\n (trimmed.startsWith('{') && trimmed.endsWith('}')) ||\n (trimmed.startsWith('[') && trimmed.endsWith(']'));\n\n return !startsJson;\n }\n\n private normalizeIssueArray(values: unknown[]): ReviewIssue[] | null {\n const normalized: ReviewIssue[] = [];\n\n for (const value of values) {\n const issue = this.normalizeIssue(value);\n if (!issue) {\n return null;\n }\n normalized.push(issue);\n }\n\n return normalized;\n }\n\n private normalizeIssue(raw: unknown): ReviewIssue | null {\n if (!raw || typeof raw !== 'object') {\n return null;\n }\n\n const data = raw as Record<string, unknown>;\n\n const message = this.toTrimmedString(\n data.message || data.text || data.description || data.summary\n );\n if (!message) {\n return null;\n }\n\n const allowedSeverities = new Set(['info', 'warning', 'error', 'critical']);\n const severityRaw = this.toTrimmedString(data.severity || data.level || data.priority);\n let severity: ReviewIssue['severity'] = 'warning';\n if (severityRaw) {\n const lower = severityRaw.toLowerCase();\n if (allowedSeverities.has(lower)) {\n severity = lower as ReviewIssue['severity'];\n } else if (['fatal', 'high'].includes(lower)) {\n severity = 'error';\n } else if (['medium', 'moderate'].includes(lower)) {\n severity = 'warning';\n } else if (['low', 'minor'].includes(lower)) {\n severity = 'info';\n }\n }\n\n const allowedCategories = new Set([\n 'security',\n 'performance',\n 'style',\n 'logic',\n 'documentation',\n ]);\n const categoryRaw = this.toTrimmedString(data.category || data.type || data.group);\n let category: ReviewIssue['category'] = 'logic';\n if (categoryRaw && allowedCategories.has(categoryRaw.toLowerCase())) {\n category = categoryRaw.toLowerCase() as ReviewIssue['category'];\n }\n\n const file = this.toTrimmedString(data.file || data.path || data.filename) || 'system';\n\n const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;\n const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);\n\n const suggestion = this.toTrimmedString(data.suggestion);\n const replacement = this.toTrimmedString(data.replacement);\n\n const ruleId =\n this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || 'command';\n\n return {\n file,\n line,\n endLine: endLine ?? undefined,\n ruleId,\n message,\n severity,\n category,\n suggestion: suggestion || undefined,\n replacement: replacement || undefined,\n };\n }\n\n private toTrimmedString(value: unknown): string | null {\n if (typeof value === 'string') {\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : null;\n }\n if (value !== null && value !== undefined && typeof value.toString === 'function') {\n const converted = String(value).trim();\n return converted.length > 0 ? converted : null;\n }\n return null;\n }\n\n private toNumber(value: unknown): number | null {\n if (value === null || value === undefined) {\n return null;\n }\n const num = Number(value);\n if (Number.isFinite(num)) {\n return Math.trunc(num);\n }\n return null;\n }\n\n private async renderCommandTemplate(\n template: string,\n context: {\n pr: Record<string, unknown>;\n files: unknown[];\n outputs: Record<string, unknown>;\n env: Record<string, string>;\n }\n ): Promise<string> {\n try {\n // Best-effort compatibility: allow double-quoted bracket keys inside Liquid tags.\n // e.g., {{ outputs[\"fetch-tickets\"].key }} → {{ outputs['fetch-tickets'].key }}\n let tpl = template;\n if (tpl.includes('{{')) {\n tpl = tpl.replace(/\\{\\{([\\s\\S]*?)\\}\\}/g, (_m, inner) => {\n const fixed = String(inner).replace(/\\[\\\"/g, \"['\").replace(/\\\"\\]/g, \"']\");\n return `{{ ${fixed} }}`;\n });\n }\n let rendered = await this.liquid.parseAndRender(tpl, context);\n // If Liquid left unresolved tags (common when users write JS expressions inside {{ }}),\n // fall back to a safe JS-expression renderer for the remaining tags.\n if (/\\{\\{[\\s\\S]*?\\}\\}/.test(rendered)) {\n try {\n rendered = this.renderWithJsExpressions(rendered, context);\n } catch {\n // keep Liquid-rendered result as-is\n }\n }\n return rendered;\n } catch (error) {\n logger.debug(`🔧 Debug: Liquid templating failed, trying JS-expression fallback: ${error}`);\n try {\n return this.renderWithJsExpressions(template, context);\n } catch {\n return template;\n }\n }\n }\n\n private renderWithJsExpressions(\n template: string,\n context: {\n pr: Record<string, unknown>;\n files: unknown[];\n outputs: Record<string, unknown>;\n env: Record<string, string>;\n }\n ): string {\n const scope = {\n pr: context.pr,\n files: context.files,\n outputs: context.outputs,\n env: context.env,\n };\n\n const expressionRegex = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n return template.replace(expressionRegex, (_match, expr) => {\n const expression = String(expr).trim();\n if (!expression) return '';\n try {\n const evalCode = `\n const pr = scope.pr;\n const files = scope.files;\n const outputs = scope.outputs;\n const env = scope.env;\n return (${expression});\n `;\n if (!this.sandbox) this.sandbox = this.createSecureSandbox();\n const evaluator = this.sandbox.compile(evalCode);\n const result = evaluator({ scope }).run();\n return result === undefined || result === null ? '' : String(result);\n } catch {\n return '';\n }\n });\n }\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { MemoryStore } from '../memory-store';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport Sandbox from '@nyariv/sandboxjs';\n\n/**\n * Memory operation types\n */\nexport type MemoryOperation =\n | 'get'\n | 'set'\n | 'append'\n | 'increment'\n | 'delete'\n | 'clear'\n | 'list'\n | 'exec_js';\n\n/**\n * Check provider for memory/state management\n * Supports in-memory and persistent storage with namespace isolation\n */\nexport class MemoryCheckProvider extends CheckProvider {\n private liquid: Liquid;\n private sandbox?: Sandbox;\n\n constructor() {\n super();\n this.liquid = createExtendedLiquid({\n strictVariables: false,\n strictFilters: false,\n });\n }\n\n /**\n * Create a secure sandbox for JavaScript execution\n */\n private createSecureSandbox(): Sandbox {\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n Math,\n console: {\n log: console.log,\n warn: console.warn,\n error: console.error,\n },\n };\n\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n\n // Allow array methods\n const arrayMethods = new Set([\n 'some',\n 'every',\n 'filter',\n 'map',\n 'reduce',\n 'find',\n 'includes',\n 'indexOf',\n 'length',\n 'slice',\n 'concat',\n 'join',\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'sort',\n 'reverse',\n ]);\n prototypeWhitelist.set(Array.prototype, arrayMethods);\n\n // Allow string methods\n const stringMethods = new Set([\n 'toLowerCase',\n 'toUpperCase',\n 'includes',\n 'indexOf',\n 'startsWith',\n 'endsWith',\n 'slice',\n 'substring',\n 'length',\n 'trim',\n 'split',\n 'replace',\n 'match',\n 'padStart',\n 'padEnd',\n ]);\n prototypeWhitelist.set(String.prototype, stringMethods);\n\n // Allow object methods\n const objectMethods = new Set(['hasOwnProperty', 'toString', 'valueOf']);\n prototypeWhitelist.set(Object.prototype, objectMethods);\n\n return new Sandbox({\n globals,\n prototypeWhitelist,\n });\n }\n\n getName(): string {\n return 'memory';\n }\n\n getDescription(): string {\n return 'Memory/state management provider for persistent key-value storage across checks';\n }\n\n async validateConfig(config: unknown): Promise<boolean> {\n if (!config || typeof config !== 'object') {\n return false;\n }\n\n const cfg = config as CheckProviderConfig;\n\n // Type must be 'memory'\n if (cfg.type !== 'memory') {\n return false;\n }\n\n // Operation is required\n if (!cfg.operation || typeof cfg.operation !== 'string') {\n return false;\n }\n\n const operation = cfg.operation as string;\n const validOps = ['get', 'set', 'append', 'increment', 'delete', 'clear', 'list', 'exec_js'];\n if (!validOps.includes(operation)) {\n return false;\n }\n\n // Key is required for get, set, append, increment, delete\n if (['get', 'set', 'append', 'increment', 'delete'].includes(operation)) {\n if (!cfg.key || typeof cfg.key !== 'string') {\n return false;\n }\n }\n\n // Value or value_js is required for set and append\n if (['set', 'append'].includes(operation)) {\n if (cfg.value === undefined && !cfg.value_js) {\n return false;\n }\n }\n\n // exec_js requires memory_js\n if (operation === 'exec_js') {\n if (!cfg.memory_js || typeof cfg.memory_js !== 'string') {\n return false;\n }\n }\n\n return true;\n }\n\n async execute(\n prInfo: PRInfo,\n config: CheckProviderConfig,\n dependencyResults?: Map<string, ReviewSummary>,\n _sessionInfo?: { parentSessionId?: string; reuseSession?: boolean }\n ): Promise<ReviewSummary> {\n const operation = config.operation as MemoryOperation;\n const key = config.key as string | undefined;\n const namespace = config.namespace as string | undefined;\n\n // Get memory store instance\n const memoryStore = MemoryStore.getInstance();\n\n // Build template context for value computation\n const templateContext = this.buildTemplateContext(\n prInfo,\n dependencyResults,\n memoryStore,\n config.__outputHistory as Map<string, unknown[]> | undefined\n );\n\n let result: unknown;\n\n try {\n switch (operation) {\n case 'get':\n result = await this.handleGet(memoryStore, key!, namespace);\n break;\n case 'set':\n result = await this.handleSet(memoryStore, key!, config, namespace, templateContext);\n break;\n case 'append':\n result = await this.handleAppend(memoryStore, key!, config, namespace, templateContext);\n break;\n case 'increment':\n result = await this.handleIncrement(\n memoryStore,\n key!,\n config,\n namespace,\n templateContext\n );\n break;\n case 'delete':\n result = await this.handleDelete(memoryStore, key!, namespace);\n break;\n case 'clear':\n result = await this.handleClear(memoryStore, namespace);\n break;\n case 'list':\n result = await this.handleList(memoryStore, namespace);\n break;\n case 'exec_js':\n result = await this.handleExecJs(memoryStore, config, templateContext);\n break;\n default:\n throw new Error(`Unknown memory operation: ${operation}`);\n }\n\n // Return result as output\n return {\n issues: [],\n output: result,\n } as ReviewSummary & { output: unknown };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error in memory operation';\n logger.error(`Memory operation failed: ${errorMsg}`);\n\n return {\n issues: [],\n output: null,\n error: errorMsg,\n } as ReviewSummary & { output: null; error: string };\n }\n }\n\n private async handleGet(store: MemoryStore, key: string, namespace?: string): Promise<unknown> {\n const value = store.get(key, namespace);\n logger.debug(\n `Memory GET: ${namespace || store.getDefaultNamespace()}.${key} = ${JSON.stringify(value)}`\n );\n return value;\n }\n\n private async handleSet(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<unknown> {\n const value = await this.computeValue(config, context);\n await store.set(key, value, namespace);\n logger.debug(\n `Memory SET: ${namespace || store.getDefaultNamespace()}.${key} = ${JSON.stringify(value)}`\n );\n return value;\n }\n\n private async handleAppend(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<unknown> {\n const value = await this.computeValue(config, context);\n await store.append(key, value, namespace);\n const result = store.get(key, namespace);\n logger.debug(\n `Memory APPEND: ${namespace || store.getDefaultNamespace()}.${key} += ${JSON.stringify(value)} (now: ${JSON.stringify(result)})`\n );\n return result;\n }\n\n private async handleIncrement(\n store: MemoryStore,\n key: string,\n config: CheckProviderConfig,\n namespace: string | undefined,\n context: Record<string, unknown>\n ): Promise<number> {\n // Compute amount - default to 1 if not specified\n let amount = 1;\n if (config.value !== undefined || config.value_js) {\n const computedValue = await this.computeValue(config, context);\n if (typeof computedValue === 'number') {\n amount = computedValue;\n } else {\n throw new Error(`Increment amount must be a number, got ${typeof computedValue}`);\n }\n }\n\n const result = await store.increment(key, amount, namespace);\n logger.debug(\n `Memory INCREMENT: ${namespace || store.getDefaultNamespace()}.${key} += ${amount} (now: ${result})`\n );\n return result;\n }\n\n private async handleDelete(\n store: MemoryStore,\n key: string,\n namespace?: string\n ): Promise<boolean> {\n const deleted = await store.delete(key, namespace);\n logger.debug(\n `Memory DELETE: ${namespace || store.getDefaultNamespace()}.${key} (deleted: ${deleted})`\n );\n return deleted;\n }\n\n private async handleClear(store: MemoryStore, namespace?: string): Promise<void> {\n await store.clear(namespace);\n logger.debug(`Memory CLEAR: ${namespace ? `namespace ${namespace}` : 'all namespaces'}`);\n }\n\n private async handleList(store: MemoryStore, namespace?: string): Promise<string[]> {\n const keys = store.list(namespace);\n logger.debug(`Memory LIST: ${namespace || store.getDefaultNamespace()} (${keys.length} keys)`);\n return keys;\n }\n\n private async handleExecJs(\n store: MemoryStore,\n config: CheckProviderConfig,\n context: Record<string, unknown>\n ): Promise<unknown> {\n const script = config.memory_js as string;\n\n // Track operations that need to be saved\n const pendingOps: Array<() => Promise<void>> = [];\n\n // Create enhanced context with memory operations\n // Note: These operations are synchronous for simplicity in scripts\n // The actual async save happens after script execution\n const enhancedContext = {\n ...context,\n memory: {\n get: (key: string, ns?: string) => store.get(key, ns),\n set: (key: string, value: unknown, ns?: string) => {\n // Store operation synchronously in memory\n const nsName = ns || store.getDefaultNamespace();\n if (!store['data'].has(nsName)) {\n store['data'].set(nsName, new Map());\n }\n store['data'].get(nsName)!.set(key, value);\n // Queue async save for later\n pendingOps.push(async () => {\n if (store.getConfig().storage === 'file' && store.getConfig().auto_save) {\n await store.save();\n }\n });\n return value;\n },\n append: (key: string, value: unknown, ns?: string) => {\n const existing = store.get(key, ns);\n let newValue: unknown[];\n if (existing === undefined) {\n newValue = [value];\n } else if (Array.isArray(existing)) {\n newValue = [...existing, value];\n } else {\n newValue = [existing, value];\n }\n // Use sync set\n const nsName = ns || store.getDefaultNamespace();\n if (!store['data'].has(nsName)) {\n store['data'].set(nsName, new Map());\n }\n store['data'].get(nsName)!.set(key, newValue);\n // Queue async save\n pendingOps.push(async () => {\n if (store.getConfig().storage === 'file' && store.getConfig().auto_save) {\n await store.save();\n }\n });\n return newValue;\n },\n increment: (key: string, amount = 1, ns?: string) => {\n const existing = store.get(key, ns);\n let newValue: number;\n if (existing === undefined || existing === null) {\n newValue = amount;\n } else if (typeof existing === 'number') {\n newValue = existing + amount;\n } else {\n throw new Error(\n `Cannot increment non-numeric value at key '${key}' (type: ${typeof existing})`\n );\n }\n // Use sync set\n const nsName = ns || store.getDefaultNamespace();\n if (!store['data'].has(nsName)) {\n store['data'].set(nsName, new Map());\n }\n store['data'].get(nsName)!.set(key, newValue);\n // Queue async save\n pendingOps.push(async () => {\n if (store.getConfig().storage === 'file' && store.getConfig().auto_save) {\n await store.save();\n }\n });\n return newValue;\n },\n delete: (key: string, ns?: string) => {\n const nsName = ns || store.getDefaultNamespace();\n const nsData = store['data'].get(nsName);\n const deleted = nsData?.delete(key) || false;\n // Queue async save\n if (deleted) {\n pendingOps.push(async () => {\n if (store.getConfig().storage === 'file' && store.getConfig().auto_save) {\n await store.save();\n }\n });\n }\n return deleted;\n },\n clear: (ns?: string) => {\n if (ns) {\n store['data'].delete(ns);\n } else {\n store['data'].clear();\n }\n // Queue async save\n pendingOps.push(async () => {\n if (store.getConfig().storage === 'file' && store.getConfig().auto_save) {\n await store.save();\n }\n });\n },\n list: (ns?: string) => store.list(ns),\n has: (key: string, ns?: string) => store.has(key, ns),\n getAll: (ns?: string) => store.getAll(ns),\n listNamespaces: () => store.listNamespaces(),\n },\n };\n\n const result = this.evaluateJavaScriptBlock(script, enhancedContext);\n\n // Execute pending async operations\n if (\n pendingOps.length > 0 &&\n store.getConfig().storage === 'file' &&\n store.getConfig().auto_save\n ) {\n // Only save once after all operations\n await store.save();\n }\n\n logger.debug(`Memory EXEC_JS: Executed custom script with ${pendingOps.length} operations`);\n return result;\n }\n\n /**\n * Compute value from config using value, value_js, transform, or transform_js\n */\n private async computeValue(\n config: CheckProviderConfig,\n context: Record<string, unknown>\n ): Promise<unknown> {\n let value: unknown;\n\n // Start with direct value or value_js\n if (config.value_js && typeof config.value_js === 'string') {\n value = this.evaluateJavaScript(config.value_js, context);\n } else {\n value = config.value;\n }\n\n // Apply transform template if provided\n if (config.transform && typeof config.transform === 'string') {\n const rendered = await this.liquid.parseAndRender(config.transform, {\n ...context,\n value,\n });\n value = rendered;\n }\n\n // Apply transform_js if provided\n if (config.transform_js && typeof config.transform_js === 'string') {\n value = this.evaluateJavaScript(config.transform_js, { ...context, value });\n }\n\n return value;\n }\n\n /**\n * Evaluate JavaScript expression in context using SandboxJS for secure execution\n */\n private evaluateJavaScript(expression: string, context: Record<string, unknown>): unknown {\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n\n try {\n // Add log function for debugging\n const log = (...args: unknown[]) => {\n logger.info(`🔍 [memory-js] ${args.map(a => JSON.stringify(a)).join(' ')}`);\n };\n\n // Build scope with all context, including memory object\n // SandboxJS allows calling functions on plain objects\n const scope: Record<string, unknown> = {\n ...context,\n log,\n };\n\n // Wrap expression in return statement for SandboxJS\n const exec = this.sandbox.compile(`return (${expression});`);\n return exec(scope).run();\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to evaluate value_js: ${errorMsg}`);\n }\n }\n\n /**\n * Evaluate JavaScript block (multi-line script) using SandboxJS for secure execution\n * Unlike evaluateJavaScript, this supports full scripts with statements, not just expressions\n */\n private evaluateJavaScriptBlock(script: string, context: Record<string, unknown>): unknown {\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n\n try {\n // Add log function for debugging\n const log = (...args: unknown[]) => {\n logger.info(`🔍 [memory-js] ${args.map(a => JSON.stringify(a)).join(' ')}`);\n };\n\n // Build scope with all context, but keep memory object as-is\n // SandboxJS allows calling functions on plain objects\n const scope: Record<string, unknown> = {\n ...context,\n log,\n };\n\n // Compile script as-is. SandboxJS treats it as a function body\n // where return statements work at the top level.\n const exec = this.sandbox.compile(script);\n const result = exec(scope).run();\n return result;\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : 'Unknown error';\n logger.error(`[memory-js] Script execution error: ${errorMsg}`);\n throw new Error(`Failed to execute memory_js: ${errorMsg}`);\n }\n }\n\n /**\n * Build template context for Liquid and JS evaluation\n */\n private buildTemplateContext(\n prInfo: PRInfo,\n dependencyResults?: Map<string, ReviewSummary>,\n memoryStore?: MemoryStore,\n outputHistory?: Map<string, unknown[]>\n ): Record<string, unknown> {\n const context: Record<string, unknown> = {};\n\n // Add PR context\n context.pr = {\n number: prInfo.number,\n title: prInfo.title,\n body: prInfo.body,\n author: prInfo.author,\n base: prInfo.base,\n head: prInfo.head,\n totalAdditions: prInfo.totalAdditions,\n totalDeletions: prInfo.totalDeletions,\n files: prInfo.files.map(f => ({\n filename: f.filename,\n status: f.status,\n additions: f.additions,\n deletions: f.deletions,\n changes: f.changes,\n })),\n };\n\n // Add dependency outputs - always create outputs object even if no dependencies\n const outputs: Record<string, unknown> = {};\n const history: Record<string, unknown[]> = {};\n\n if (dependencyResults) {\n for (const [checkName, result] of dependencyResults.entries()) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n }\n\n // Add history for each check if available\n if (outputHistory) {\n for (const [checkName, historyArray] of outputHistory) {\n history[checkName] = historyArray;\n }\n }\n\n // Attach history to the outputs object\n (outputs as any).history = history;\n\n context.outputs = outputs;\n\n // Add memory accessor\n if (memoryStore) {\n context.memory = {\n get: (key: string, ns?: string) => memoryStore.get(key, ns),\n has: (key: string, ns?: string) => memoryStore.has(key, ns),\n list: (ns?: string) => memoryStore.list(ns),\n getAll: (ns?: string) => memoryStore.getAll(ns),\n };\n }\n\n // SECURITY: Do NOT expose process.env to user-controlled scripts\n // Removed: context.env = process.env;\n // Environment variables, especially secrets like GITHUB_TOKEN, must not be\n // accessible to scripts defined in .visor.yaml as this would allow credential theft\n\n return context;\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'operation',\n 'key',\n 'value',\n 'value_js',\n 'memory_js',\n 'transform',\n 'transform_js',\n 'namespace',\n 'depends_on',\n 'group',\n 'command',\n 'on',\n 'if',\n 'fail_if',\n 'on_fail',\n 'on_success',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Memory provider is always available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Used for state management and persistent storage across checks',\n ];\n }\n}\n","import { CheckProvider } from './check-provider.interface';\nimport { AICheckProvider } from './ai-check-provider';\nimport { HttpCheckProvider } from './http-check-provider';\nimport { HttpInputProvider } from './http-input-provider';\nimport { HttpClientProvider } from './http-client-provider';\nimport { NoopCheckProvider } from './noop-check-provider';\nimport { LogCheckProvider } from './log-check-provider';\nimport { GitHubOpsProvider } from './github-ops-provider';\nimport { ClaudeCodeCheckProvider } from './claude-code-check-provider';\nimport { CommandCheckProvider } from './command-check-provider';\nimport { MemoryCheckProvider } from './memory-check-provider';\n\n/**\n * Registry for managing check providers\n */\nexport class CheckProviderRegistry {\n private providers: Map<string, CheckProvider> = new Map();\n private static instance: CheckProviderRegistry;\n\n private constructor() {\n // Register default providers\n this.registerDefaultProviders();\n }\n\n /**\n * Get singleton instance\n */\n static getInstance(): CheckProviderRegistry {\n if (!CheckProviderRegistry.instance) {\n CheckProviderRegistry.instance = new CheckProviderRegistry();\n }\n return CheckProviderRegistry.instance;\n }\n\n /**\n * Register default built-in providers\n */\n private registerDefaultProviders(): void {\n // Register all built-in providers\n this.register(new AICheckProvider());\n this.register(new CommandCheckProvider());\n this.register(new HttpCheckProvider());\n this.register(new HttpInputProvider());\n this.register(new HttpClientProvider());\n this.register(new NoopCheckProvider());\n this.register(new LogCheckProvider());\n this.register(new MemoryCheckProvider());\n this.register(new GitHubOpsProvider());\n\n // Try to register ClaudeCodeCheckProvider - it may fail if dependencies are missing\n try {\n this.register(new ClaudeCodeCheckProvider());\n } catch (error) {\n console.error(\n `Warning: Failed to register ClaudeCodeCheckProvider: ${\n error instanceof Error ? error.message : 'Unknown error'\n }`\n );\n }\n }\n\n /**\n * Register a check provider\n */\n register(provider: CheckProvider): void {\n const name = provider.getName();\n if (this.providers.has(name)) {\n throw new Error(`Provider '${name}' is already registered`);\n }\n this.providers.set(name, provider);\n // Only log provider registration in debug mode to avoid contaminating output\n if (process.env.VISOR_DEBUG === 'true') {\n console.error(`Registered check provider: ${name}`);\n }\n }\n\n /**\n * Unregister a check provider\n */\n unregister(name: string): void {\n if (!this.providers.has(name)) {\n throw new Error(`Provider '${name}' not found`);\n }\n this.providers.delete(name);\n // Send provider unregistration messages to stderr to avoid contaminating JSON output\n console.error(`Unregistered check provider: ${name}`);\n }\n\n /**\n * Get a provider by name\n */\n getProvider(name: string): CheckProvider | undefined {\n return this.providers.get(name);\n }\n\n /**\n * Get provider or throw if not found\n */\n getProviderOrThrow(name: string): CheckProvider {\n const provider = this.providers.get(name);\n if (!provider) {\n throw new Error(\n `Check provider '${name}' not found. Available providers: ${this.getAvailableProviders().join(', ')}`\n );\n }\n return provider;\n }\n\n /**\n * Check if a provider exists\n */\n hasProvider(name: string): boolean {\n return this.providers.has(name);\n }\n\n /**\n * Get all registered provider names\n */\n getAvailableProviders(): string[] {\n return Array.from(this.providers.keys());\n }\n\n /**\n * Get all providers\n */\n getAllProviders(): CheckProvider[] {\n return Array.from(this.providers.values());\n }\n\n /**\n * Get providers that are currently available (have required dependencies)\n */\n async getActiveProviders(): Promise<CheckProvider[]> {\n const providers = this.getAllProviders();\n const activeProviders: CheckProvider[] = [];\n\n for (const provider of providers) {\n if (await provider.isAvailable()) {\n activeProviders.push(provider);\n }\n }\n\n return activeProviders;\n }\n\n /**\n * List provider information\n */\n async listProviders(): Promise<\n Array<{\n name: string;\n description: string;\n available: boolean;\n requirements: string[];\n }>\n > {\n const providers = this.getAllProviders();\n const info = [];\n\n for (const provider of providers) {\n info.push({\n name: provider.getName(),\n description: provider.getDescription(),\n available: await provider.isAvailable(),\n requirements: provider.getRequirements(),\n });\n }\n\n return info;\n }\n\n /**\n * Reset registry (mainly for testing)\n */\n reset(): void {\n this.providers.clear();\n this.registerDefaultProviders();\n }\n\n /**\n * Clear singleton instance (for testing)\n */\n static clearInstance(): void {\n CheckProviderRegistry.instance = undefined!;\n }\n}\n","/**\n * Dependency resolution and execution ordering for checks\n */\n\nexport interface CheckNode {\n id: string;\n dependencies: string[];\n dependents: string[];\n depth: number;\n}\n\nexport interface ExecutionGroup {\n /** Checks that can run in parallel */\n parallel: string[];\n /** Execution level/wave (0 = no dependencies, 1 = depends on level 0, etc.) */\n level: number;\n}\n\nexport interface DependencyGraph {\n nodes: Map<string, CheckNode>;\n executionOrder: ExecutionGroup[];\n hasCycles: boolean;\n cycleNodes?: string[];\n}\n\nexport class DependencyResolver {\n /**\n * Build dependency graph from check dependencies\n */\n static buildDependencyGraph(checkDependencies: Record<string, string[]>): DependencyGraph {\n const nodes = new Map<string, CheckNode>();\n\n // Initialize all nodes\n for (const checkId of Object.keys(checkDependencies)) {\n nodes.set(checkId, {\n id: checkId,\n dependencies: checkDependencies[checkId] || [],\n dependents: [],\n depth: 0,\n });\n }\n\n // Build bidirectional relationships\n for (const [checkId, dependencies] of Object.entries(checkDependencies)) {\n for (const depId of dependencies || []) {\n if (!nodes.has(depId)) {\n throw new Error(`Check \"${checkId}\" depends on \"${depId}\" but \"${depId}\" is not defined`);\n }\n\n const depNode = nodes.get(depId)!;\n depNode.dependents.push(checkId);\n }\n }\n\n // Detect cycles using DFS\n const cycleDetection = this.detectCycles(nodes);\n if (cycleDetection.hasCycles) {\n return {\n nodes,\n executionOrder: [],\n hasCycles: true,\n cycleNodes: cycleDetection.cycleNodes,\n };\n }\n\n // Calculate execution order using topological sort\n const executionOrder = this.topologicalSort(nodes);\n\n return {\n nodes,\n executionOrder,\n hasCycles: false,\n };\n }\n\n /**\n * Detect cycles in the dependency graph using DFS\n */\n private static detectCycles(nodes: Map<string, CheckNode>): {\n hasCycles: boolean;\n cycleNodes?: string[];\n } {\n const visited = new Set<string>();\n const recursionStack = new Set<string>();\n const cycleNodes: string[] = [];\n\n const dfs = (nodeId: string): boolean => {\n if (recursionStack.has(nodeId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n if (visited.has(nodeId)) {\n return false;\n }\n\n visited.add(nodeId);\n recursionStack.add(nodeId);\n\n const node = nodes.get(nodeId);\n if (node) {\n for (const depId of node.dependencies) {\n if (dfs(depId)) {\n cycleNodes.push(nodeId);\n return true;\n }\n }\n }\n\n recursionStack.delete(nodeId);\n return false;\n };\n\n for (const nodeId of nodes.keys()) {\n if (!visited.has(nodeId)) {\n if (dfs(nodeId)) {\n return { hasCycles: true, cycleNodes: [...new Set(cycleNodes)] };\n }\n }\n }\n\n return { hasCycles: false };\n }\n\n /**\n * Perform topological sort to determine execution order\n * Groups checks that can run in parallel at each level\n */\n private static topologicalSort(nodes: Map<string, CheckNode>): ExecutionGroup[] {\n const remainingNodes = new Map(nodes);\n const executionGroups: ExecutionGroup[] = [];\n let level = 0;\n\n while (remainingNodes.size > 0) {\n // Find nodes with no remaining dependencies\n const readyNodes: string[] = [];\n\n for (const [nodeId, node] of remainingNodes.entries()) {\n const unmetDependencies = node.dependencies.filter(depId => remainingNodes.has(depId));\n if (unmetDependencies.length === 0) {\n readyNodes.push(nodeId);\n }\n }\n\n if (readyNodes.length === 0) {\n // This shouldn't happen if cycle detection worked correctly\n throw new Error('Unable to resolve dependencies - possible circular dependency detected');\n }\n\n // Add this group to execution order\n executionGroups.push({\n parallel: readyNodes,\n level,\n });\n\n // Remove processed nodes\n for (const nodeId of readyNodes) {\n remainingNodes.delete(nodeId);\n }\n\n level++;\n }\n\n return executionGroups;\n }\n\n /**\n * Validate that all dependencies exist\n */\n static validateDependencies(\n checkIds: string[],\n dependencies: Record<string, string[]>\n ): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n const checkIdSet = new Set(checkIds);\n\n for (const [checkId, deps] of Object.entries(dependencies)) {\n if (!checkIdSet.has(checkId)) {\n errors.push(`Check \"${checkId}\" is not in the list of available checks`);\n continue;\n }\n\n for (const depId of deps || []) {\n if (!checkIdSet.has(depId)) {\n errors.push(`Check \"${checkId}\" depends on \"${depId}\" which is not available`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n }\n\n /**\n * Get all transitive dependencies (ancestors) for a given check\n * This returns all checks that must complete before the given check can run,\n * not just the direct dependencies.\n *\n * For example, if A -> B -> C, then:\n * - getAllDependencies(C) returns [A, B]\n * - getAllDependencies(B) returns [A]\n * - getAllDependencies(A) returns []\n *\n * @param checkId The check to find dependencies for\n * @param nodes The dependency graph nodes\n * @returns Array of all transitive dependency IDs\n */\n static getAllDependencies(checkId: string, nodes: Map<string, CheckNode>): string[] {\n const allDeps = new Set<string>();\n const visited = new Set<string>();\n\n const collectDependencies = (currentId: string) => {\n if (visited.has(currentId)) {\n return;\n }\n visited.add(currentId);\n\n const node = nodes.get(currentId);\n if (!node) {\n return;\n }\n\n // Add direct dependencies and recurse\n for (const depId of node.dependencies) {\n allDeps.add(depId);\n collectDependencies(depId);\n }\n };\n\n collectDependencies(checkId);\n return Array.from(allDeps);\n }\n\n /**\n * Get execution statistics for debugging\n */\n static getExecutionStats(graph: DependencyGraph): {\n totalChecks: number;\n parallelLevels: number;\n maxParallelism: number;\n averageParallelism: number;\n checksWithDependencies: number;\n } {\n const totalChecks = graph.nodes.size;\n const parallelLevels = graph.executionOrder.length;\n const maxParallelism = Math.max(...graph.executionOrder.map(group => group.parallel.length));\n const averageParallelism = totalChecks / parallelLevels;\n const checksWithDependencies = Array.from(graph.nodes.values()).filter(\n node => node.dependencies.length > 0\n ).length;\n\n return {\n totalChecks,\n parallelLevels,\n maxParallelism,\n averageParallelism,\n checksWithDependencies,\n };\n }\n}\n","/**\n * Failure condition evaluation engine using SandboxJS for secure expression evaluation\n */\n\nimport { ReviewSummary } from './reviewer';\nimport { addEvent } from './telemetry/trace-helpers';\nimport { addFailIfTriggered } from './telemetry/metrics';\nimport {\n FailureConditions,\n FailureCondition,\n FailureConditionContext,\n FailureConditionResult,\n FailureConditionSeverity,\n} from './types/config';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createPermissionHelpers, detectLocalMode } from './utils/author-permissions';\nimport { MemoryStore } from './memory-store';\n\n/**\n * Evaluates failure conditions using SandboxJS for secure evaluation\n */\nexport class FailureConditionEvaluator {\n private sandbox?: Sandbox;\n\n constructor() {}\n\n /**\n * Create a secure sandbox with whitelisted functions and globals\n */\n private createSecureSandbox(): Sandbox {\n // Start with safe globals and prototypes\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n // Allow Math for calculations\n Math,\n // Allow console for debugging (in controlled environment)\n console: {\n log: console.log,\n warn: console.warn,\n error: console.error,\n },\n };\n\n // Create prototype whitelist - use safe defaults\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n\n // Explicitly allow array methods that we need\n const arrayMethods = new Set([\n 'some',\n 'every',\n 'filter',\n 'map',\n 'reduce',\n 'find',\n 'includes',\n 'indexOf',\n 'length',\n 'slice',\n 'concat',\n 'join',\n ]);\n prototypeWhitelist.set(Array.prototype, arrayMethods);\n\n // Allow string methods\n const stringMethods = new Set([\n 'toLowerCase',\n 'toUpperCase',\n 'includes',\n 'indexOf',\n 'startsWith',\n 'endsWith',\n 'slice',\n 'substring',\n 'length',\n 'trim',\n 'split',\n 'replace',\n ]);\n prototypeWhitelist.set(String.prototype, stringMethods);\n\n // Allow basic object methods\n const objectMethods = new Set(['hasOwnProperty', 'toString', 'valueOf']);\n prototypeWhitelist.set(Object.prototype, objectMethods);\n\n return new Sandbox({\n globals,\n prototypeWhitelist,\n });\n }\n\n /**\n * Evaluate simple fail_if condition\n */\n async evaluateSimpleCondition(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n expression: string,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): Promise<boolean> {\n const context = this.buildEvaluationContext(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n previousOutputs,\n authorAssociation\n );\n\n try {\n try {\n const isObj = context.output && typeof context.output === 'object';\n const keys = isObj ? Object.keys(context.output as any).join(',') : typeof context.output;\n let errorVal: unknown = undefined;\n if (isObj && (context.output as any).error !== undefined)\n errorVal = (context.output as any).error;\n require('./logger').logger.debug(\n ` fail_if: evaluating '${expression}' with output keys=${keys} error=${String(errorVal)}`\n );\n } catch {}\n const res = this.evaluateExpression(expression, context);\n if (res === true) {\n try {\n addEvent('fail_if.triggered', {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression,\n severity: 'error',\n });\n } catch {}\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: checkName, scope: 'check', name: `${checkName}_fail_if` },\n [\n {\n name: 'fail_if.triggered',\n attrs: {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression,\n severity: 'error',\n },\n },\n ]\n );\n } catch {}\n }\n return res;\n } catch (error) {\n console.warn(`Failed to evaluate fail_if expression: ${error}`);\n return false; // Don't fail on evaluation errors\n }\n }\n\n /**\n * Determine if the event is related to pull requests\n */\n private determineIfPullRequest(eventType?: string): boolean {\n if (!eventType) return false;\n\n const prEvents = ['pr_opened', 'pr_updated', 'pr_closed', 'pull_request'];\n return prEvents.includes(eventType) || eventType.startsWith('pr_');\n }\n\n /**\n * Determine if the event is related to issues\n */\n private determineIfIssue(eventType?: string): boolean {\n if (!eventType) return false;\n\n const issueEvents = ['issue_opened', 'issue_comment', 'issues'];\n return issueEvents.includes(eventType) || eventType.startsWith('issue_');\n }\n\n /**\n * Evaluate if condition to determine whether a check should run\n */\n async evaluateIfCondition(\n checkName: string,\n expression: string,\n contextData?: {\n branch?: string;\n baseBranch?: string;\n filesChanged?: string[];\n event?: string;\n environment?: Record<string, string>;\n previousResults?: Map<string, ReviewSummary>;\n authorAssociation?: string;\n }\n ): Promise<boolean> {\n // Build context for if evaluation\n const context = {\n // Check metadata\n checkName,\n\n // Git context\n branch: contextData?.branch || 'unknown',\n baseBranch: contextData?.baseBranch || 'main',\n filesChanged: contextData?.filesChanged || [],\n filesCount: contextData?.filesChanged?.length || 0,\n\n // GitHub event context\n event: {\n event_name: contextData?.event || 'manual',\n action: undefined, // Would be populated from actual GitHub context\n repository: undefined, // Would be populated from actual GitHub context\n },\n\n // Environment variables\n env: contextData?.environment || {},\n\n // Previous check results (unwrap output field like templates do)\n outputs: contextData?.previousResults\n ? (() => {\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of contextData.previousResults) {\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result as-is\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n return outputs;\n })()\n : {},\n\n // Required output property (empty for if conditions)\n output: {\n issues: [],\n },\n // Author association (used by permission helpers)\n authorAssociation: contextData?.authorAssociation,\n\n // Utility metadata\n metadata: {\n checkName,\n schema: '',\n group: '',\n criticalIssues: 0,\n errorIssues: 0,\n warningIssues: 0,\n infoIssues: 0,\n totalIssues: 0,\n hasChanges: (contextData?.filesChanged?.length || 0) > 0,\n branch: contextData?.branch || 'unknown',\n event: contextData?.event || 'manual',\n },\n };\n\n try {\n return this.evaluateExpression(expression, context);\n } catch (error) {\n console.warn(`Failed to evaluate if expression for check '${checkName}': ${error}`);\n // Default to running the check if evaluation fails\n return true;\n }\n }\n\n /**\n * Evaluate all failure conditions for a check result\n */\n async evaluateConditions(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n globalConditions?: FailureConditions,\n checkConditions?: FailureConditions,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): Promise<FailureConditionResult[]> {\n const context = this.buildEvaluationContext(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n previousOutputs,\n authorAssociation\n );\n\n const results: FailureConditionResult[] = [];\n\n // Evaluate global conditions first\n if (globalConditions) {\n const globalResults = await this.evaluateConditionSet(globalConditions, context, 'global');\n results.push(...globalResults);\n }\n\n // Evaluate check-specific conditions (these override global ones with same name)\n if (checkConditions) {\n const checkResults = await this.evaluateConditionSet(checkConditions, context, 'check');\n\n // Remove global conditions that are overridden by check-specific ones\n const overriddenConditions = new Set(Object.keys(checkConditions));\n const filteredResults = results.filter(\n result => !overriddenConditions.has(result.conditionName)\n );\n\n results.length = 0;\n results.push(...filteredResults, ...checkResults);\n }\n\n try {\n if (checkName === 'B') {\n console.error(\n `🔧 Debug: fail_if results for ${checkName}: ${JSON.stringify(results)} context.output=${JSON.stringify(\n context.output\n )}`\n );\n }\n } catch {}\n return results;\n }\n\n /**\n * Evaluate a set of failure conditions\n */\n private async evaluateConditionSet(\n conditions: FailureConditions,\n context: FailureConditionContext,\n source: 'global' | 'check'\n ): Promise<FailureConditionResult[]> {\n const results: FailureConditionResult[] = [];\n\n for (const [conditionName, condition] of Object.entries(conditions)) {\n try {\n addEvent('fail_if.evaluated', {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: this.extractExpression(condition),\n });\n } catch {}\n\n // File fallback: append an NDJSON span with the evaluation event\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: context.checkName || 'unknown', scope: source, name: conditionName },\n [\n {\n name: 'fail_if.evaluated',\n attrs: {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: this.extractExpression(condition),\n },\n },\n ]\n );\n } catch {}\n\n try {\n const result = await this.evaluateSingleCondition(conditionName, condition, context);\n results.push(result);\n\n if (result.failed) {\n try {\n addEvent('fail_if.triggered', {\n check: context.checkName,\n scope: source,\n name: conditionName,\n expression: result.expression,\n severity: result.severity,\n halt_execution: result.haltExecution,\n });\n } catch {}\n try {\n addFailIfTriggered(context.checkName || 'unknown', source);\n } catch {}\n }\n } catch (error) {\n // If evaluation fails, create an error result\n results.push({\n conditionName,\n failed: false,\n expression: this.extractExpression(condition),\n severity: 'error',\n haltExecution: false,\n error: `Failed to evaluate ${source} condition '${conditionName}': ${\n error instanceof Error ? error.message : String(error)\n }`,\n });\n }\n }\n\n return results;\n }\n\n /**\n * Evaluate a single failure condition\n */\n private async evaluateSingleCondition(\n conditionName: string,\n condition: FailureCondition,\n context: FailureConditionContext\n ): Promise<FailureConditionResult> {\n const expression = this.extractExpression(condition);\n const config = this.extractConditionConfig(condition);\n\n try {\n const failed = this.evaluateExpression(expression, context);\n\n return {\n conditionName,\n failed,\n expression,\n message: config.message,\n severity: config.severity || 'error',\n haltExecution: config.halt_execution || false,\n };\n } catch (error) {\n throw new Error(\n `Expression evaluation error: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Secure expression evaluation using SandboxJS\n * Supports the same GitHub Actions-style functions as the previous implementation\n */\n private evaluateExpression(condition: string, context: FailureConditionContext): boolean {\n try {\n // Normalize multi-line or semicolon-separated expressions.\n // Allows writing debug statements on separate lines, e.g.:\n // log(\"start\")\n // log(outputs)\n // outputs[\"fetch-tickets\"].issueType === 'Bug'\n // We convert to a single expression using the comma operator so the\n // final expression determines the boolean result.\n const normalize = (expr: string): string => {\n const trimmed = expr.trim();\n // If it's already a single-line expression without semicolons, keep it.\n if (!/[\\n;]/.test(trimmed)) return trimmed;\n\n // Split on newlines/semicolons, drop empty and comment-only lines.\n const parts = trimmed\n .split(/[\\n;]+/)\n .map(s => s.trim())\n .filter(s => s.length > 0 && !s.startsWith('//'));\n\n if (parts.length === 0) return 'true';\n\n // Support an explicit return in the last statement.\n const lastRaw = parts.pop() as string;\n const last = lastRaw.replace(/^return\\s+/i, '').trim();\n\n // Join leading statements with comma operator; last expression returns value.\n if (parts.length === 0) return last;\n return `(${parts.join(', ')}, ${last})`;\n };\n\n // note: normalization happens later only if raw compilation fails\n // Helper functions for GitHub Actions-style expressions\n const contains = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().includes(String(searchValue).toLowerCase());\n\n const startsWith = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().startsWith(String(searchValue).toLowerCase());\n\n const endsWith = (searchString: string, searchValue: string): boolean =>\n String(searchString).toLowerCase().endsWith(String(searchValue).toLowerCase());\n\n const length = (value: string | unknown[] | Record<string, unknown>): number => {\n if (typeof value === 'string' || Array.isArray(value)) {\n return value.length;\n }\n if (value && typeof value === 'object') {\n return Object.keys(value).length;\n }\n return 0;\n };\n\n const always = (): boolean => true;\n const success = (): boolean => true;\n const failure = (): boolean => false;\n\n // Debug logging function for printing to console\n const log = (...args: unknown[]): void => {\n console.log('🔍 Debug:', ...args);\n };\n\n // Helper functions for array operations\n const hasIssue = (issues: unknown[], field: string, value: unknown): boolean => {\n if (!Array.isArray(issues)) return false;\n return issues.some(issue => (issue as Record<string, unknown>)[field] === value);\n };\n\n const countIssues = (issues: unknown[], field: string, value: unknown): number => {\n if (!Array.isArray(issues)) return 0;\n return issues.filter(issue => (issue as Record<string, unknown>)[field] === value).length;\n };\n\n const hasFileMatching = (issues: unknown[], pattern: string): boolean => {\n if (!Array.isArray(issues)) return false;\n return issues.some(issue => (issue as { file?: string }).file?.includes(pattern));\n };\n\n const hasSuggestion = (suggestions: string[], text: string): boolean => {\n if (!Array.isArray(suggestions)) return false;\n return suggestions.some(s => s.toLowerCase().includes(text.toLowerCase()));\n };\n\n // Backward compatibility aliases\n const hasIssueWith = hasIssue;\n const hasFileWith = hasFileMatching;\n\n // Permission helper functions\n const permissionHelpers = createPermissionHelpers(\n context.authorAssociation,\n detectLocalMode()\n );\n const hasMinPermission = permissionHelpers.hasMinPermission;\n const isOwner = permissionHelpers.isOwner;\n const isMember = permissionHelpers.isMember;\n const isCollaborator = permissionHelpers.isCollaborator;\n const isContributor = permissionHelpers.isContributor;\n const isFirstTimer = permissionHelpers.isFirstTimer;\n\n // Extract context variables\n const output = context.output || {};\n const issues = output.issues || [];\n const suggestions: string[] = [];\n\n // Backward compatibility: provide metadata for transition period\n // TODO: Remove after all configurations are updated\n const metadata = context.metadata || {\n checkName: context.checkName || '',\n schema: context.schema || '',\n group: context.group || '',\n criticalIssues: issues.filter((i: { severity?: string }) => i.severity === 'critical')\n .length,\n errorIssues: issues.filter((i: { severity?: string }) => i.severity === 'error').length,\n warningIssues: issues.filter((i: { severity?: string }) => i.severity === 'warning').length,\n infoIssues: issues.filter((i: { severity?: string }) => i.severity === 'info').length,\n totalIssues: issues.length,\n hasChanges: context.hasChanges || false,\n };\n\n // Legacy variables for backward compatibility\n const criticalIssues = metadata.criticalIssues;\n const errorIssues = metadata.errorIssues;\n const totalIssues = metadata.totalIssues;\n const warningIssues = metadata.warningIssues;\n const infoIssues = metadata.infoIssues;\n\n // Additional context for 'if' conditions and some failure conditions\n const checkName = context.checkName || '';\n const schema = context.schema || '';\n const group = context.group || '';\n const branch = context.branch || 'unknown';\n const baseBranch = context.baseBranch || 'main';\n const filesChanged = context.filesChanged || [];\n const filesCount = context.filesCount || 0;\n const event = context.event || 'manual';\n const env = context.env || {};\n const outputs = context.outputs || {};\n const debugData = context.debug || null;\n\n // Get memory store and create accessor for fail_if expressions\n const memoryStore = MemoryStore.getInstance();\n const memoryAccessor = {\n get: (key: string, ns?: string) => memoryStore.get(key, ns),\n has: (key: string, ns?: string) => memoryStore.has(key, ns),\n list: (ns?: string) => memoryStore.list(ns),\n getAll: (ns?: string) => memoryStore.getAll(ns),\n };\n\n // Create scope with all context variables and helper functions\n const scope = {\n // Primary context variables\n output,\n outputs,\n debug: debugData,\n // Memory accessor for fail_if expressions\n memory: memoryAccessor,\n // Legacy compatibility variables\n issues,\n suggestions,\n metadata,\n criticalIssues,\n errorIssues,\n totalIssues,\n warningIssues,\n infoIssues,\n // If condition context\n checkName,\n schema,\n group,\n branch,\n baseBranch,\n filesChanged,\n filesCount,\n event,\n env,\n // Helper functions\n contains,\n startsWith,\n endsWith,\n length,\n always,\n success,\n failure,\n log,\n hasIssue,\n countIssues,\n hasFileMatching,\n hasSuggestion,\n hasIssueWith,\n hasFileWith,\n // Permission helpers\n hasMinPermission,\n isOwner,\n isMember,\n isCollaborator,\n isContributor,\n isFirstTimer,\n };\n\n // Compile and execute the expression in the sandbox\n const raw = condition.trim();\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n let exec: ReturnType<typeof this.sandbox.compile>;\n try {\n // Try compiling the raw expression as-is first (supports multi-line logical expressions)\n exec = this.sandbox.compile(`return (${raw});`);\n } catch {\n // Fallback: normalize multi-line statements into a comma-chain expression\n const normalizedExpr = normalize(condition);\n exec = this.sandbox.compile(`return (${normalizedExpr});`);\n }\n const result = exec(scope).run();\n try {\n require('./logger').logger.debug(` fail_if: result=${Boolean(result)}`);\n } catch {}\n // Ensure we return a boolean\n return Boolean(result);\n } catch (error) {\n console.error('❌ Failed to evaluate expression:', condition, error);\n // Re-throw the error so it can be caught at a higher level for error reporting\n throw error;\n }\n }\n\n /**\n * Extract the expression from a failure condition\n */\n private extractExpression(condition: FailureCondition): string {\n if (typeof condition === 'string') {\n return condition;\n }\n return condition.condition;\n }\n\n /**\n * Extract configuration from a failure condition\n */\n private extractConditionConfig(condition: FailureCondition): {\n message?: string;\n severity?: FailureConditionSeverity;\n halt_execution?: boolean;\n } {\n if (typeof condition === 'string') {\n return {};\n }\n return {\n message: condition.message,\n severity: condition.severity,\n halt_execution: condition.halt_execution,\n };\n }\n\n /**\n * Build the evaluation context for expressions\n */\n private buildEvaluationContext(\n checkName: string,\n checkSchema: string,\n checkGroup: string,\n reviewSummary: ReviewSummary,\n previousOutputs?: Record<string, ReviewSummary>,\n authorAssociation?: string\n ): FailureConditionContext {\n const { issues, debug } = reviewSummary;\n const reviewSummaryWithOutput = reviewSummary as ReviewSummary & { output?: unknown };\n\n // Extract output field to avoid nesting (output.output)\n const {\n output: extractedOutput,\n // Exclude issues from otherFields since we handle it separately\n issues: _issues, // eslint-disable-line @typescript-eslint/no-unused-vars\n ...otherFields\n } = reviewSummaryWithOutput as any;\n\n // Build output object with safety for array-based outputs (forEach aggregation)\n const aggregatedOutput: Record<string, unknown> = {\n issues: (issues || []).map(issue => ({\n file: issue.file,\n line: issue.line,\n endLine: issue.endLine,\n ruleId: issue.ruleId,\n message: issue.message,\n severity: issue.severity,\n category: issue.category,\n group: issue.group,\n schema: issue.schema,\n suggestion: issue.suggestion,\n replacement: issue.replacement,\n })),\n // Include additional schema-specific data from reviewSummary\n ...otherFields,\n };\n\n if (Array.isArray(extractedOutput)) {\n // Preserve items array and lift common flags for convenience (e.g., output.error)\n aggregatedOutput.items = extractedOutput;\n const anyError = extractedOutput.find(\n it => it && typeof it === 'object' && (it as Record<string, unknown>).error\n ) as Record<string, unknown> | undefined;\n if (anyError && anyError.error !== undefined) {\n aggregatedOutput.error = anyError.error;\n }\n } else if (extractedOutput && typeof extractedOutput === 'object') {\n Object.assign(aggregatedOutput, extractedOutput as Record<string, unknown>);\n }\n\n // If provider attached a raw transform snapshot, merge its fields generically.\n try {\n const raw = (reviewSummaryWithOutput as any).__raw;\n if (raw && typeof raw === 'object') {\n Object.assign(aggregatedOutput, raw as Record<string, unknown>);\n }\n } catch {}\n\n // If output is a string, try to parse JSON (full or from end) to enrich context,\n // and also derive common boolean flags generically (e.g., key:true/false) for fail_if usage.\n try {\n if (typeof extractedOutput === 'string') {\n const parsed =\n this.tryExtractJsonFromEnd(extractedOutput) ??\n (() => {\n try {\n return JSON.parse(extractedOutput);\n } catch {\n return null;\n }\n })();\n if (parsed !== null) {\n if (Array.isArray(parsed)) {\n (aggregatedOutput as any).items = parsed;\n } else if (typeof parsed === 'object') {\n Object.assign(aggregatedOutput, parsed as Record<string, unknown>);\n }\n }\n // Generic boolean key extraction for simple text outputs (no special provider cases)\n const lower = extractedOutput.toLowerCase();\n const boolFrom = (key: string): boolean | null => {\n const reTrue = new RegExp(\n `(?:^|[^a-z0-9_])${key}[^a-z0-9_]*[:=][^a-z0-9_]*true(?:[^a-z0-9_]|$)`\n );\n const reFalse = new RegExp(\n `(?:^|[^a-z0-9_])${key}[^a-z0-9_]*[:=][^a-z0-9_]*false(?:[^a-z0-9_]|$)`\n );\n if (reTrue.test(lower)) return true;\n if (reFalse.test(lower)) return false;\n return null;\n };\n const keys = ['error'];\n for (const k of keys) {\n const v = boolFrom(k);\n if (v !== null && (aggregatedOutput as any)[k] === undefined) {\n (aggregatedOutput as any)[k] = v;\n }\n }\n }\n } catch {}\n\n // Try to parse JSON from content as a last resort when no structured output is present\n try {\n const rsAny = reviewSummaryWithOutput as any;\n const hasStructuredOutput = extractedOutput !== undefined && extractedOutput !== null;\n if (!hasStructuredOutput && typeof rsAny?.content === 'string') {\n const parsedFromContent = this.tryExtractJsonFromEnd(rsAny.content);\n if (parsedFromContent !== null && parsedFromContent !== undefined) {\n if (Array.isArray(parsedFromContent)) {\n (aggregatedOutput as any).items = parsedFromContent;\n } else if (typeof parsedFromContent === 'object') {\n Object.assign(aggregatedOutput, parsedFromContent as Record<string, unknown>);\n }\n }\n }\n } catch {}\n\n // Get memory store instance\n const memoryStore = MemoryStore.getInstance();\n\n const context: FailureConditionContext = {\n output: aggregatedOutput,\n outputs: (() => {\n if (!previousOutputs) return {};\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of Object.entries(previousOutputs)) {\n // If the result has a direct output field, use it directly\n // Otherwise, expose the entire result as-is\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n return outputs;\n })(),\n // Add memory accessor for fail_if expressions\n memory: {\n get: (key: string, ns?: string) => memoryStore.get(key, ns),\n has: (key: string, ns?: string) => memoryStore.has(key, ns),\n list: (ns?: string) => memoryStore.list(ns),\n getAll: (ns?: string) => memoryStore.getAll(ns),\n } as any,\n // Add basic context info for failure conditions\n checkName: checkName,\n schema: checkSchema,\n group: checkGroup,\n authorAssociation: authorAssociation,\n };\n\n // Add debug information if available\n if (debug) {\n context.debug = {\n errors: debug.errors || [],\n processingTime: debug.processingTime || 0,\n provider: debug.provider || 'unknown',\n model: debug.model || 'unknown',\n };\n }\n\n return context;\n }\n\n // Minimal JSON-from-end extractor for fail_if context fallback\n private tryExtractJsonFromEnd(text: string): unknown | null {\n try {\n const lines = text.split('\\n');\n for (let i = lines.length - 1; i >= 0; i--) {\n const t = lines[i].trim();\n if (t.startsWith('{') || t.startsWith('[')) {\n const candidate = lines.slice(i).join('\\n').trim();\n if (\n (candidate.startsWith('{') && candidate.endsWith('}')) ||\n (candidate.startsWith('[') && candidate.endsWith(']'))\n ) {\n return JSON.parse(candidate);\n }\n }\n }\n } catch {}\n return null;\n }\n\n /**\n * Check if any failure condition requires halting execution\n */\n static shouldHaltExecution(results: FailureConditionResult[]): boolean {\n return results.some(result => result.failed && result.haltExecution);\n }\n\n /**\n * Get all failed conditions\n */\n static getFailedConditions(results: FailureConditionResult[]): FailureConditionResult[] {\n return results.filter(result => result.failed);\n }\n\n /**\n * Group results by severity\n */\n static groupResultsBySeverity(results: FailureConditionResult[]): {\n error: FailureConditionResult[];\n warning: FailureConditionResult[];\n info: FailureConditionResult[];\n } {\n return {\n // Only 'error' severity now (no backward compatibility needed here as this is internal)\n error: results.filter(r => r.severity === 'error'),\n warning: results.filter(r => r.severity === 'warning'),\n info: results.filter(r => r.severity === 'info'),\n };\n }\n\n /**\n * Format results for display\n */\n static formatResults(results: FailureConditionResult[]): string {\n const failed = FailureConditionEvaluator.getFailedConditions(results);\n\n if (failed.length === 0) {\n return '✅ All failure conditions passed';\n }\n\n const grouped = FailureConditionEvaluator.groupResultsBySeverity(failed);\n const sections: string[] = [];\n\n if (grouped.error.length > 0) {\n sections.push(`❌ **Error severity conditions (${grouped.error.length}):**`);\n grouped.error.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n if (grouped.warning.length > 0) {\n sections.push(`⚠️ **Warning conditions (${grouped.warning.length}):**`);\n grouped.warning.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n if (grouped.info.length > 0) {\n sections.push(`ℹ️ **Info conditions (${grouped.info.length}):**`);\n grouped.info.forEach(result => {\n sections.push(` - ${result.conditionName}: ${result.message || result.expression}`);\n });\n }\n\n return sections.join('\\n');\n }\n}\n","/**\n * GitHub Check Service for creating and managing check runs based on failure conditions\n */\n\nimport { Octokit } from '@octokit/rest';\nimport { FailureConditionResult } from './types/config';\nimport { ReviewIssue } from './reviewer';\n\nexport interface CheckRunOptions {\n owner: string;\n repo: string;\n head_sha: string;\n name: string;\n details_url?: string;\n external_id?: string;\n}\n\nexport interface CheckRunAnnotation {\n path: string;\n start_line: number;\n end_line: number;\n annotation_level: 'notice' | 'warning' | 'failure';\n message: string;\n title?: string;\n raw_details?: string;\n}\n\nexport interface CheckRunSummary {\n title: string;\n summary: string;\n text?: string;\n}\n\nexport type CheckRunStatus = 'queued' | 'in_progress' | 'completed';\nexport type CheckRunConclusion =\n | 'success'\n | 'failure'\n | 'neutral'\n | 'cancelled'\n | 'timed_out'\n | 'action_required';\n\n/**\n * Service for managing GitHub Check Runs based on Visor failure conditions\n */\nexport class GitHubCheckService {\n private octokit: Octokit;\n private maxAnnotations = 50; // GitHub API limit\n\n constructor(octokit: Octokit) {\n this.octokit = octokit;\n }\n\n /**\n * Create a new check run in queued status\n */\n async createCheckRun(\n options: CheckRunOptions,\n summary?: CheckRunSummary\n ): Promise<{ id: number; url: string }> {\n try {\n const response = await this.octokit.rest.checks.create({\n owner: options.owner,\n repo: options.repo,\n name: options.name,\n head_sha: options.head_sha,\n status: 'queued',\n details_url: options.details_url,\n external_id: options.external_id,\n output: summary\n ? {\n title: summary.title,\n summary: summary.summary,\n text: summary.text,\n }\n : undefined,\n });\n\n return {\n id: response.data.id,\n url: response.data.html_url || '',\n };\n } catch (error) {\n throw new Error(\n `Failed to create check run: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Update check run to in_progress status\n */\n async updateCheckRunInProgress(\n owner: string,\n repo: string,\n check_run_id: number,\n summary?: CheckRunSummary\n ): Promise<void> {\n try {\n await this.octokit.rest.checks.update({\n owner,\n repo,\n check_run_id,\n status: 'in_progress',\n output: summary\n ? {\n title: summary.title,\n summary: summary.summary,\n text: summary.text,\n }\n : undefined,\n });\n } catch (error) {\n throw new Error(\n `Failed to update check run to in_progress: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Complete a check run with results based on failure conditions\n */\n async completeCheckRun(\n owner: string,\n repo: string,\n check_run_id: number,\n checkName: string,\n failureResults: FailureConditionResult[],\n reviewIssues: ReviewIssue[] = [],\n executionError?: string,\n filesChangedInCommit?: string[],\n prNumber?: number,\n currentCommitSha?: string\n ): Promise<void> {\n try {\n // Clear old annotations from ALL previous check runs (including older runs on the same commit)\n // This prevents annotation accumulation when a check runs multiple times\n if (prNumber && currentCommitSha) {\n await this.clearOldAnnotations(\n owner,\n repo,\n prNumber,\n checkName,\n currentCommitSha,\n check_run_id\n );\n }\n\n const { conclusion, summary } = this.determineCheckRunConclusion(\n checkName,\n failureResults,\n reviewIssues,\n executionError\n );\n\n // Filter out system-level issues (fail_if conditions, internal errors)\n // These should not appear as annotations but affect the check conclusion\n let filteredIssues = reviewIssues.filter(\n issue => !(issue.file === 'system' && issue.line === 0)\n );\n\n // Filter annotations to only include files changed in this commit\n // This prevents old annotations from previous commits showing up in the Files tab\n if (filesChangedInCommit && filesChangedInCommit.length > 0) {\n filteredIssues = filteredIssues.filter(issue =>\n filesChangedInCommit.some(changedFile => issue.file === changedFile)\n );\n }\n\n const annotations = this.convertIssuesToAnnotations(filteredIssues);\n\n await this.octokit.rest.checks.update({\n owner,\n repo,\n check_run_id,\n status: 'completed',\n conclusion,\n completed_at: new Date().toISOString(),\n output: {\n title: summary.title,\n summary: summary.summary,\n text: summary.text,\n annotations: annotations.slice(0, this.maxAnnotations), // GitHub limit\n },\n });\n } catch (error) {\n throw new Error(\n `Failed to complete check run: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Determine check run conclusion based on failure conditions and issues\n */\n private determineCheckRunConclusion(\n checkName: string,\n failureResults: FailureConditionResult[],\n reviewIssues: ReviewIssue[],\n executionError?: string\n ): { conclusion: CheckRunConclusion; summary: CheckRunSummary } {\n // Handle execution errors first\n if (executionError) {\n return {\n conclusion: 'failure',\n summary: {\n title: '❌ Check Execution Failed',\n summary: `The ${checkName} check failed to execute properly.`,\n text: `**Error:** ${executionError}\\n\\nPlease check your configuration and try again.`,\n },\n };\n }\n\n // Check if any fail_if conditions were met\n const failedConditions = failureResults.filter(result => result.failed);\n\n // Count issues by severity (for informational display only)\n const criticalIssues = reviewIssues.filter(issue => issue.severity === 'critical').length;\n const errorIssues = reviewIssues.filter(issue => issue.severity === 'error').length;\n const warningIssues = reviewIssues.filter(issue => issue.severity === 'warning').length;\n const totalIssues = reviewIssues.length;\n\n // Determine conclusion ONLY based on fail_if evaluation results\n // The presence of issues (critical, error, warning) does NOT affect the conclusion\n // Only the fail_if condition determines pass/fail status\n let conclusion: CheckRunConclusion;\n let title: string;\n let summaryText: string;\n let details: string;\n\n if (failedConditions.length > 0) {\n // Check fails if fail_if condition is met\n conclusion = 'failure';\n title = '🚨 Check Failed';\n summaryText = `${checkName} check failed because fail_if condition was met.`;\n\n details = this.formatCheckDetails(failureResults, reviewIssues, {\n failedConditions: failedConditions.length,\n warningConditions: 0,\n criticalIssues,\n errorIssues,\n warningIssues,\n totalIssues,\n });\n } else {\n // No fail_if conditions met - check passes regardless of issues found\n conclusion = 'success';\n\n // Adjust the title and summary based on issues found, but conclusion remains success\n if (criticalIssues > 0 || errorIssues > 0) {\n title = '✅ Check Passed (Issues Found)';\n summaryText = `${checkName} check passed. Found ${criticalIssues} critical and ${errorIssues} error issues, but fail_if condition was not met.`;\n } else if (warningIssues > 0) {\n title = '✅ Check Passed (Warnings Found)';\n summaryText = `${checkName} check passed. Found ${warningIssues} warning${warningIssues === 1 ? '' : 's'}, but fail_if condition was not met.`;\n } else {\n title = '✅ Check Passed';\n summaryText = `${checkName} check completed successfully with no issues found.`;\n }\n\n details = this.formatCheckDetails(failureResults, reviewIssues, {\n failedConditions: 0,\n warningConditions: 0,\n criticalIssues,\n errorIssues,\n warningIssues,\n totalIssues,\n });\n }\n\n return {\n conclusion,\n summary: {\n title,\n summary: summaryText,\n text: details,\n },\n };\n }\n\n /**\n * Format detailed check results for the check run summary\n */\n private formatCheckDetails(\n failureResults: FailureConditionResult[],\n reviewIssues: ReviewIssue[],\n counts: {\n failedConditions: number;\n warningConditions: number;\n criticalIssues: number;\n errorIssues: number;\n warningIssues: number;\n totalIssues: number;\n }\n ): string {\n const sections: string[] = [];\n\n // Summary section\n sections.push('## 📊 Summary');\n sections.push(`- **Total Issues:** ${counts.totalIssues}`);\n if (counts.criticalIssues > 0) {\n sections.push(`- **Critical Issues:** ${counts.criticalIssues}`);\n }\n if (counts.errorIssues > 0) {\n sections.push(`- **Error Issues:** ${counts.errorIssues}`);\n }\n if (counts.warningIssues > 0) {\n sections.push(`- **Warning Issues:** ${counts.warningIssues}`);\n }\n sections.push('');\n\n // Failure conditions section\n if (failureResults.length > 0) {\n sections.push('## 🔍 Failure Condition Results');\n\n const failedConditions = failureResults.filter(result => result.failed);\n const passedConditions = failureResults.filter(result => !result.failed);\n\n if (failedConditions.length > 0) {\n sections.push('### ❌ Failed Conditions');\n failedConditions.forEach(condition => {\n sections.push(\n `- **${condition.conditionName}**: ${condition.message || condition.expression}`\n );\n if (condition.severity === 'error') {\n sections.push(` - ⚠️ **Severity:** Error`);\n }\n });\n sections.push('');\n }\n\n if (passedConditions.length > 0) {\n sections.push('### ✅ Passed Conditions');\n passedConditions.forEach(condition => {\n sections.push(\n `- **${condition.conditionName}**: ${condition.message || 'Condition passed'}`\n );\n });\n sections.push('');\n }\n }\n\n // Issues by category section\n if (reviewIssues.length > 0) {\n const issuesByCategory = this.groupIssuesByCategory(reviewIssues);\n sections.push('## 🐛 Issues by Category');\n\n Object.entries(issuesByCategory).forEach(([category, issues]) => {\n if (issues.length > 0) {\n sections.push(\n `### ${this.getCategoryEmoji(category)} ${category.charAt(0).toUpperCase() + category.slice(1)} (${issues.length})`\n );\n\n // Show only first 5 issues per category to keep the summary concise\n const displayIssues = issues.slice(0, 5);\n displayIssues.forEach(issue => {\n const severityIcon = this.getSeverityIcon(issue.severity);\n sections.push(`- ${severityIcon} **${issue.file}:${issue.line}** - ${issue.message}`);\n });\n\n if (issues.length > 5) {\n sections.push(`- *...and ${issues.length - 5} more ${category} issues*`);\n }\n sections.push('');\n }\n });\n }\n\n // Footer\n sections.push('');\n sections.push('---');\n sections.push('');\n sections.push(\n '*Powered by [Visor](https://probelabs.com/visor) from [Probelabs](https://probelabs.com)*'\n );\n\n return sections.join('\\n');\n }\n\n /**\n * Convert review issues to GitHub check run annotations\n */\n private convertIssuesToAnnotations(reviewIssues: ReviewIssue[]): CheckRunAnnotation[] {\n return reviewIssues\n .slice(0, this.maxAnnotations) // Respect GitHub's annotation limit\n .map(issue => ({\n path: issue.file,\n start_line: issue.line,\n end_line: issue.endLine || issue.line,\n annotation_level: this.mapSeverityToAnnotationLevel(issue.severity),\n message: issue.message,\n title: `${issue.category} Issue`,\n raw_details: issue.suggestion || undefined,\n }));\n }\n\n /**\n * Map Visor issue severity to GitHub annotation level\n */\n private mapSeverityToAnnotationLevel(severity: string): 'notice' | 'warning' | 'failure' {\n switch (severity) {\n case 'critical':\n case 'error':\n return 'failure';\n case 'warning':\n return 'warning';\n case 'info':\n default:\n return 'notice';\n }\n }\n\n /**\n * Group issues by category\n */\n private groupIssuesByCategory(issues: ReviewIssue[]): Record<string, ReviewIssue[]> {\n const grouped: Record<string, ReviewIssue[]> = {};\n\n issues.forEach(issue => {\n const category = issue.category || 'general';\n if (!grouped[category]) {\n grouped[category] = [];\n }\n grouped[category].push(issue);\n });\n\n return grouped;\n }\n\n /**\n * Get emoji for issue category\n */\n private getCategoryEmoji(category: string): string {\n const emojiMap: Record<string, string> = {\n security: '🔐',\n performance: '⚡',\n style: '🎨',\n logic: '🧠',\n architecture: '🏗️',\n documentation: '📚',\n general: '📝',\n };\n return emojiMap[category.toLowerCase()] || '📝';\n }\n\n /**\n * Get icon for issue severity\n */\n private getSeverityIcon(severity: string): string {\n const iconMap: Record<string, string> = {\n critical: '🚨',\n error: '❌',\n warning: '⚠️',\n info: 'ℹ️',\n };\n return iconMap[severity.toLowerCase()] || 'ℹ️';\n }\n\n /**\n * Create multiple check runs for different checks with failure condition support\n */\n async createMultipleCheckRuns(\n options: CheckRunOptions,\n checkResults: Array<{\n checkName: string;\n failureResults: FailureConditionResult[];\n reviewIssues: ReviewIssue[];\n executionError?: string;\n }>\n ): Promise<Array<{ checkName: string; id: number; url: string }>> {\n const results: Array<{ checkName: string; id: number; url: string }> = [];\n\n for (const checkResult of checkResults) {\n try {\n // Create check run\n const checkRun = await this.createCheckRun({\n ...options,\n name: `Visor: ${checkResult.checkName}`,\n external_id: `visor-${checkResult.checkName}-${options.head_sha.substring(0, 7)}`,\n });\n\n // Update to in progress\n await this.updateCheckRunInProgress(options.owner, options.repo, checkRun.id, {\n title: `Running ${checkResult.checkName} check...`,\n summary: `Analyzing code with ${checkResult.checkName} check using AI.`,\n });\n\n // Complete with results\n await this.completeCheckRun(\n options.owner,\n options.repo,\n checkRun.id,\n checkResult.checkName,\n checkResult.failureResults,\n checkResult.reviewIssues,\n checkResult.executionError\n );\n\n results.push({\n checkName: checkResult.checkName,\n id: checkRun.id,\n url: checkRun.url,\n });\n } catch (error) {\n console.error(`Failed to create check run for ${checkResult.checkName}:`, error);\n // Continue with other checks even if one fails\n }\n }\n\n return results;\n }\n\n /**\n * Get check runs for a specific commit\n */\n async getCheckRuns(\n owner: string,\n repo: string,\n ref: string\n ): Promise<Array<{ id: number; name: string; status: string; conclusion: string | null }>> {\n try {\n const response = await this.octokit.rest.checks.listForRef({\n owner,\n repo,\n ref,\n filter: 'all',\n });\n\n return response.data.check_runs\n .filter(check => check.name.startsWith('Visor:'))\n .map(check => ({\n id: check.id,\n name: check.name,\n status: check.status,\n conclusion: check.conclusion,\n }));\n } catch (error) {\n throw new Error(\n `Failed to get check runs: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Get check runs for a specific commit SHA\n * Returns all check runs with the given name on this commit\n */\n async getCheckRunsForCommit(\n owner: string,\n repo: string,\n commitSha: string,\n checkName: string\n ): Promise<Array<{ id: number; head_sha: string }>> {\n try {\n const checksResponse = await this.octokit.rest.checks.listForRef({\n owner,\n repo,\n ref: commitSha,\n check_name: `Visor: ${checkName}`,\n });\n\n return checksResponse.data.check_runs.map(check => ({\n id: check.id,\n head_sha: commitSha,\n }));\n } catch (error) {\n throw new Error(\n `Failed to get check runs for commit ${commitSha}: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n /**\n * Clear annotations from old check runs on the current commit\n * This prevents annotation accumulation when a check runs multiple times on the same commit\n * (e.g., force push, re-running checks)\n */\n async clearOldAnnotations(\n owner: string,\n repo: string,\n prNumber: number, // Not used, kept for backward compatibility\n checkName: string,\n currentCommitSha: string,\n currentCheckRunId: number\n ): Promise<void> {\n try {\n // Get all check runs for this check name on the current commit\n const allCheckRuns = await this.getCheckRunsForCommit(\n owner,\n repo,\n currentCommitSha,\n checkName\n );\n\n // Filter out the CURRENT check run (by ID)\n // This handles the case where Visor runs multiple times on the same commit\n const oldRuns = allCheckRuns.filter(run => run.id !== currentCheckRunId);\n\n if (oldRuns.length === 0) {\n console.debug(`No old check runs to clear for ${checkName} on commit ${currentCommitSha}`);\n return;\n }\n\n console.debug(\n `Clearing ${oldRuns.length} old check run(s) for ${checkName} on commit ${currentCommitSha.substring(0, 7)} (keeping current run ${currentCheckRunId})`\n );\n\n // Update each old check run to have empty annotations\n for (const run of oldRuns) {\n try {\n await this.octokit.rest.checks.update({\n owner,\n repo,\n check_run_id: run.id,\n output: {\n title: 'Outdated',\n summary: 'This check has been superseded by a newer run.',\n annotations: [], // Clear annotations\n },\n });\n console.debug(`✓ Cleared annotations from check run ${run.id}`);\n } catch (error) {\n console.debug(`Could not clear annotations for check run ${run.id}:`, error);\n }\n }\n } catch (error) {\n // Don't fail the whole check if we can't clear old annotations\n console.warn('Failed to clear old annotations:', error);\n }\n }\n}\n","import {\n PRReviewer,\n ReviewSummary,\n ReviewOptions,\n GroupedCheckResults,\n CheckResult,\n ReviewIssue,\n} from './reviewer';\nimport { GitRepositoryAnalyzer, GitRepositoryInfo } from './git-repository-analyzer';\nimport { AnalysisResult } from './output-formatters';\nimport { PRInfo } from './pr-analyzer';\nimport { PRAnalyzer } from './pr-analyzer';\nimport { CheckProviderRegistry } from './providers/check-provider-registry';\nimport { CheckProviderConfig } from './providers/check-provider.interface';\nimport { DependencyResolver, DependencyGraph } from './dependency-resolver';\nimport { FailureConditionEvaluator } from './failure-condition-evaluator';\nimport { FailureConditionResult, CheckConfig } from './types/config';\nimport { GitHubCheckService, CheckRunOptions } from './github-check-service';\nimport { IssueFilter } from './issue-filter';\nimport { logger } from './logger';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { VisorConfig, OnFailConfig, OnSuccessConfig } from './types/config';\nimport {\n createPermissionHelpers,\n detectLocalMode,\n resolveAssociationFromEvent,\n} from './utils/author-permissions';\nimport { MemoryStore } from './memory-store';\nimport { emitNdjsonSpanWithEvents, emitNdjsonFallback } from './telemetry/fallback-ndjson';\nimport { addEvent } from './telemetry/trace-helpers';\nimport { addFailIfTriggered } from './telemetry/metrics';\n\ntype ExtendedReviewSummary = ReviewSummary & {\n output?: unknown;\n content?: string;\n isForEach?: boolean;\n forEachItems?: unknown[];\n // Preserve per-item results for forEach-dependent checks so children can gate per item\n forEachItemResults?: ReviewSummary[];\n // Per-item fatal mask: true means this item is fatal/should gate descendants\n forEachFatalMask?: boolean[];\n};\n\n/**\n * Statistics for a single check execution\n */\nexport interface CheckExecutionStats {\n checkName: string;\n totalRuns: number; // How many times the check executed (1 or forEach iterations)\n successfulRuns: number;\n failedRuns: number;\n skipped: boolean;\n skipReason?: 'if_condition' | 'fail_fast' | 'dependency_failed';\n skipCondition?: string; // The actual if condition text\n totalDuration: number; // Total duration in milliseconds\n perIterationDuration?: number[]; // Duration for each iteration (if forEach)\n issuesFound: number;\n issuesBySeverity: {\n critical: number;\n error: number;\n warning: number;\n info: number;\n };\n outputsProduced?: number; // Number of outputs for forEach checks\n errorMessage?: string; // Error message if failed\n forEachPreview?: string[]; // Preview of forEach items processed (first few)\n}\n\n/**\n * Overall execution statistics for all checks\n */\nexport interface ExecutionStatistics {\n totalChecksConfigured: number;\n totalExecutions: number; // Sum of all runs including forEach iterations\n successfulExecutions: number;\n failedExecutions: number;\n skippedChecks: number;\n totalDuration: number;\n checks: CheckExecutionStats[];\n}\n\n/**\n * Result of executing checks, including both the grouped results and execution statistics\n */\nexport interface ExecutionResult {\n results: GroupedCheckResults;\n statistics: ExecutionStatistics;\n}\n\n/**\n * Filter environment variables to only include safe ones for sandbox evaluation\n */\nfunction getSafeEnvironmentVariables(): Record<string, string> {\n const safeEnvVars = [\n 'CI',\n 'GITHUB_EVENT_NAME',\n 'GITHUB_REPOSITORY',\n 'GITHUB_REF',\n 'GITHUB_SHA',\n 'GITHUB_HEAD_REF',\n 'GITHUB_BASE_REF',\n 'GITHUB_ACTOR',\n 'GITHUB_WORKFLOW',\n 'GITHUB_RUN_ID',\n 'GITHUB_RUN_NUMBER',\n 'NODE_ENV',\n ];\n\n const safeEnv: Record<string, string> = {};\n\n for (const key of safeEnvVars) {\n if (process.env[key]) {\n safeEnv[key] = process.env[key];\n }\n }\n\n return safeEnv;\n}\n\nexport interface MockOctokit {\n rest: {\n pulls: {\n get: () => Promise<{ data: Record<string, unknown> }>;\n listFiles: () => Promise<{ data: Record<string, unknown>[] }>;\n };\n issues: {\n listComments: () => Promise<{ data: Record<string, unknown>[] }>;\n createComment: () => Promise<{ data: Record<string, unknown> }>;\n };\n };\n request: () => Promise<{ data: Record<string, unknown> }>;\n graphql: () => Promise<Record<string, unknown>>;\n log: {\n debug: (...args: unknown[]) => void;\n info: (...args: unknown[]) => void;\n warn: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n };\n hook: {\n before: (...args: unknown[]) => void;\n after: (...args: unknown[]) => void;\n error: (...args: unknown[]) => void;\n wrap: (...args: unknown[]) => void;\n };\n auth: () => Promise<{ token: string }>;\n}\n\nexport interface CheckExecutionOptions {\n checks: string[];\n workingDirectory?: string;\n showDetails?: boolean;\n timeout?: number;\n maxParallelism?: number; // Maximum number of checks to run in parallel (default: 3)\n failFast?: boolean; // Stop execution when any check fails (default: false)\n outputFormat?: string;\n config?: import('./types/config').VisorConfig;\n debug?: boolean; // Enable debug mode to collect AI execution details\n // Tag filter for selective check execution\n tagFilter?: import('./types/config').TagFilter;\n // Webhook context for passing webhook data to http_input providers\n webhookContext?: {\n webhookData: Map<string, unknown>;\n };\n // GitHub Check integration options\n githubChecks?: {\n enabled: boolean;\n octokit?: import('@octokit/rest').Octokit;\n owner?: string;\n repo?: string;\n headSha?: string;\n prNumber?: number;\n };\n}\n\nexport class CheckExecutionEngine {\n private gitAnalyzer: GitRepositoryAnalyzer;\n private mockOctokit: MockOctokit;\n private reviewer: PRReviewer;\n private providerRegistry: CheckProviderRegistry;\n private failureEvaluator: FailureConditionEvaluator;\n private githubCheckService?: GitHubCheckService;\n private checkRunMap?: Map<string, { id: number; url: string }>;\n private githubContext?: { owner: string; repo: string };\n private workingDirectory: string;\n private config?: import('./types/config').VisorConfig;\n private webhookContext?: { webhookData: Map<string, unknown> };\n private routingSandbox?: Sandbox;\n private executionStats: Map<string, CheckExecutionStats> = new Map();\n // Track history of all outputs for each check (useful for loops and goto)\n private outputHistory: Map<string, unknown[]> = new Map();\n // Event override to simulate alternate event (used during routing goto)\n private routingEventOverride?: import('./types/config').EventTrigger;\n // Cached GitHub context for context elevation when running in Actions\n private actionContext?: {\n owner: string;\n repo: string;\n octokit?: import('@octokit/rest').Octokit;\n };\n\n constructor(workingDirectory?: string, octokit?: import('@octokit/rest').Octokit) {\n this.workingDirectory = workingDirectory || process.cwd();\n this.gitAnalyzer = new GitRepositoryAnalyzer(this.workingDirectory);\n this.providerRegistry = CheckProviderRegistry.getInstance();\n this.failureEvaluator = new FailureConditionEvaluator();\n\n // If authenticated octokit is provided, cache it for provider use\n if (octokit) {\n const repoEnv = process.env.GITHUB_REPOSITORY || '';\n const [owner, repo] = repoEnv.split('/') as [string, string];\n if (owner && repo) {\n this.actionContext = { owner, repo, octokit };\n }\n }\n\n // Create a mock Octokit instance for local analysis\n // This allows us to reuse the existing PRReviewer logic without network calls\n this.mockOctokit = this.createMockOctokit();\n this.reviewer = new PRReviewer(this.mockOctokit as unknown as import('@octokit/rest').Octokit);\n }\n\n /**\n * Enrich event context with authenticated octokit instance\n * @param eventContext - The event context to enrich\n * @returns Enriched event context with octokit if available\n */\n private enrichEventContext(eventContext?: Record<string, unknown>): Record<string, unknown> {\n const baseContext = eventContext || {};\n if (this.actionContext?.octokit) {\n return { ...baseContext, octokit: this.actionContext.octokit };\n }\n return baseContext;\n }\n\n /**\n * Lazily create a secure sandbox for routing JS (goto_js, run_js)\n */\n private getRoutingSandbox(): Sandbox {\n if (this.routingSandbox) return this.routingSandbox;\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n Math,\n JSON,\n console: { log: console.log },\n };\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n this.routingSandbox = new Sandbox({ globals, prototypeWhitelist });\n return this.routingSandbox;\n }\n\n private redact(str: unknown, limit = 200): string {\n try {\n const s = typeof str === 'string' ? str : JSON.stringify(str);\n return s.length > limit ? s.slice(0, limit) + '…' : s;\n } catch {\n return String(str).slice(0, limit);\n }\n }\n\n private async sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n\n private deterministicJitter(baseMs: number, seedStr: string): number {\n let h = 2166136261;\n for (let i = 0; i < seedStr.length; i++) h = (h ^ seedStr.charCodeAt(i)) * 16777619;\n const frac = ((h >>> 0) % 1000) / 1000; // 0..1\n return Math.floor(baseMs * 0.15 * frac); // up to 15% jitter\n }\n\n private computeBackoffDelay(\n attempt: number,\n mode: 'fixed' | 'exponential',\n baseMs: number,\n seed: string\n ): number {\n const jitter = this.deterministicJitter(baseMs, seed);\n if (mode === 'exponential') {\n return baseMs * Math.pow(2, Math.max(0, attempt - 1)) + jitter;\n }\n return baseMs + jitter;\n }\n\n /**\n * Execute a check with retry/backoff and routing semantics (on_fail/on_success)\n */\n private async executeWithRouting(\n checkName: string,\n checkConfig: CheckConfig,\n provider: import('./providers/check-provider.interface').CheckProvider,\n providerConfig: CheckProviderConfig,\n prInfo: PRInfo,\n dependencyResults: Map<string, ReviewSummary>,\n sessionInfo: { parentSessionId?: string; reuseSession?: boolean } | undefined,\n config: VisorConfig | undefined,\n dependencyGraph: DependencyGraph,\n debug?: boolean,\n resultsMap?: Map<string, ReviewSummary>,\n foreachContext?: { index: number; total: number; parent: string }\n ): Promise<ReviewSummary> {\n const log = (msg: string) =>\n (this.config?.output?.pr_comment ? console.error : console.log)(msg);\n const maxLoops = config?.routing?.max_loops ?? 10;\n const defaults = config?.routing?.defaults?.on_fail || {};\n\n const onFail: OnFailConfig | undefined = checkConfig.on_fail\n ? { ...defaults, ...checkConfig.on_fail }\n : Object.keys(defaults).length\n ? defaults\n : undefined;\n const onSuccess: OnSuccessConfig | undefined = checkConfig.on_success;\n\n let attempt = 1;\n let loopCount = 0;\n const seed = `${checkName}-${prInfo.number || 'local'}`;\n\n const allAncestors = DependencyResolver.getAllDependencies(checkName, dependencyGraph.nodes);\n // Expose current check's structured output to routing JS (run_js/goto_js)\n // so templates can reference `output` similarly to `outputs` (deps).\n let currentRouteOutput: unknown = undefined;\n\n const evalRunJs = async (expr?: string, error?: unknown): Promise<string[]> => {\n if (!expr) return [];\n try {\n const sandbox = this.getRoutingSandbox();\n const eventObj = { name: prInfo.eventType || 'manual' } as const;\n const scope = {\n step: { id: checkName, tags: checkConfig.tags || [], group: checkConfig.group },\n attempt,\n loop: loopCount,\n error,\n foreach: foreachContext\n ? {\n index: foreachContext.index,\n total: foreachContext.total,\n parent: foreachContext.parent,\n }\n : null,\n outputs: Object.fromEntries((dependencyResults || new Map()).entries()),\n output: currentRouteOutput,\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n env: getSafeEnvironmentVariables(),\n permissions: createPermissionHelpers(\n resolveAssociationFromEvent((prInfo as any).eventContext, prInfo.authorAssociation),\n detectLocalMode()\n ),\n event: eventObj,\n };\n const code = `\n const step = scope.step; const attempt = scope.attempt; const loop = scope.loop; const error = scope.error; const foreach = scope.foreach; const outputs = scope.outputs; const output = scope.output; const pr = scope.pr; const files = scope.files; const env = scope.env; const event = scope.event; const log = (...a)=>console.log('🔍 Debug:',...a); const hasMinPermission = scope.permissions.hasMinPermission; const isOwner = scope.permissions.isOwner; const isMember = scope.permissions.isMember; const isCollaborator = scope.permissions.isCollaborator; const isContributor = scope.permissions.isContributor; const isFirstTimer = scope.permissions.isFirstTimer;\n const __fn = () => {\\n${expr}\\n};\n const __res = __fn();\n return Array.isArray(__res) ? __res : (__res ? [__res] : []);\n `;\n const exec = sandbox.compile(code);\n const res = exec({ scope }).run();\n if (debug) {\n log(`🔧 Debug: run_js evaluated → [${this.redact(res)}]`);\n }\n return Array.isArray(res) ? res.filter(x => typeof x === 'string') : [];\n } catch (e) {\n if (debug) {\n log(`⚠️ Debug: run_js evaluation failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n return [];\n }\n };\n\n const evalGotoJs = async (expr?: string, error?: unknown): Promise<string | null> => {\n if (!expr) return null;\n try {\n const sandbox = this.getRoutingSandbox();\n const eventObj = { name: prInfo.eventType || 'manual' } as const;\n const scope = {\n step: { id: checkName, tags: checkConfig.tags || [], group: checkConfig.group },\n attempt,\n loop: loopCount,\n error,\n foreach: foreachContext\n ? {\n index: foreachContext.index,\n total: foreachContext.total,\n parent: foreachContext.parent,\n }\n : null,\n outputs: Object.fromEntries((dependencyResults || new Map()).entries()),\n output: currentRouteOutput,\n pr: {\n number: prInfo.number,\n title: prInfo.title,\n author: prInfo.author,\n branch: prInfo.head,\n base: prInfo.base,\n },\n files: prInfo.files,\n env: getSafeEnvironmentVariables(),\n permissions: createPermissionHelpers(\n resolveAssociationFromEvent((prInfo as any).eventContext, prInfo.authorAssociation),\n detectLocalMode()\n ),\n event: eventObj,\n };\n const code = `\n const step = scope.step; const attempt = scope.attempt; const loop = scope.loop; const error = scope.error; const foreach = scope.foreach; const outputs = scope.outputs; const output = scope.output; const pr = scope.pr; const files = scope.files; const env = scope.env; const event = scope.event; const log = (...a)=>console.log('🔍 Debug:',...a); const hasMinPermission = scope.permissions.hasMinPermission; const isOwner = scope.permissions.isOwner; const isMember = scope.permissions.isMember; const isCollaborator = scope.permissions.isCollaborator; const isContributor = scope.permissions.isContributor; const isFirstTimer = scope.permissions.isFirstTimer;\n const __fn = () => {\\n${expr}\\n};\n const __res = __fn();\n return (typeof __res === 'string' && __res) ? __res : null;\n `;\n const exec = sandbox.compile(code);\n const res = exec({ scope }).run();\n if (debug) {\n log(`🔧 Debug: goto_js evaluated → ${this.redact(res)}`);\n }\n return typeof res === 'string' && res ? res : null;\n } catch (e) {\n if (debug) {\n log(`⚠️ Debug: goto_js evaluation failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n return null;\n }\n };\n\n const getAllDepsFromConfig = (name: string): string[] => {\n const visited = new Set<string>();\n const acc: string[] = [];\n const dfs = (n: string) => {\n if (visited.has(n)) return;\n visited.add(n);\n const cfg = config?.checks?.[n];\n const deps = cfg?.depends_on || [];\n for (const d of deps) {\n acc.push(d);\n dfs(d);\n }\n };\n dfs(name);\n return Array.from(new Set(acc));\n };\n\n const executeNamedCheckInline = async (\n target: string,\n opts?: { eventOverride?: import('./types/config').EventTrigger }\n ): Promise<ReviewSummary> => {\n const targetCfg = config?.checks?.[target];\n if (!targetCfg) {\n throw new Error(`on_* referenced unknown check '${target}'`);\n }\n // Ensure all dependencies of target are available; execute missing ones in topological order\n // Use config graph (not only current dependencyGraph) so inline steps can bring their own deps\n const allTargetDeps = getAllDepsFromConfig(target);\n if (allTargetDeps.length > 0) {\n // Build subgraph mapping for ordered execution\n const subSet = new Set<string>([...allTargetDeps]);\n const subDeps: Record<string, string[]> = {};\n for (const id of subSet) {\n const cfg = config?.checks?.[id];\n subDeps[id] = (cfg?.depends_on || []).filter(d => subSet.has(d));\n }\n const subGraph = DependencyResolver.buildDependencyGraph(subDeps);\n for (const group of subGraph.executionOrder) {\n for (const depId of group.parallel) {\n // Skip if already have results\n if (resultsMap?.has(depId) || dependencyResults.has(depId)) continue;\n // Execute dependency inline (recursively ensures its deps are also present)\n await executeNamedCheckInline(depId);\n }\n }\n }\n const providerType = targetCfg.type || 'ai';\n const prov = this.providerRegistry.getProviderOrThrow(providerType);\n this.setProviderWebhookContext(prov);\n const provCfg: CheckProviderConfig = {\n type: providerType,\n prompt: targetCfg.prompt,\n exec: targetCfg.exec,\n focus: targetCfg.focus || this.mapCheckNameToFocus(target),\n schema: targetCfg.schema,\n group: targetCfg.group,\n checkName: target,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n transform: targetCfg.transform,\n transform_js: targetCfg.transform_js,\n env: targetCfg.env,\n forEach: targetCfg.forEach,\n // Pass output history for loop/goto scenarios\n __outputHistory: this.outputHistory,\n // Include provider-specific keys (e.g., op/values for github)\n ...targetCfg,\n ai: {\n ...(targetCfg.ai || {}),\n timeout: providerConfig.ai?.timeout || 600000,\n debug: !!debug,\n },\n };\n // Build dependencyResults for target using already computed global results (after ensuring deps executed)\n const targetDeps = getAllDepsFromConfig(target);\n const depResults = new Map<string, ReviewSummary>();\n for (const depId of targetDeps) {\n // Prefer per-scope dependencyResults (e.g., forEach item context) over global results\n const res = dependencyResults.get(depId) || resultsMap?.get(depId);\n if (res) depResults.set(depId, res);\n }\n // Debug: log key dependent outputs for visibility\n try {\n // Try to log a small preview of dependent outputs if available\n const depPreview: Record<string, unknown> = {};\n for (const [k, v] of depResults.entries()) {\n const out = (v as any)?.output;\n if (out !== undefined) depPreview[k] = out;\n }\n if (debug) {\n log(`🔧 Debug: inline exec '${target}' deps output: ${JSON.stringify(depPreview)}`);\n }\n } catch {}\n\n if (debug) {\n const execStr = (provCfg as any).exec;\n if (execStr) log(`🔧 Debug: inline exec '${target}' command: ${execStr}`);\n }\n // If event override provided, clone prInfo with overridden eventType\n let prInfoForInline = prInfo;\n const prevEventOverride = this.routingEventOverride;\n if (opts?.eventOverride) {\n // Try to elevate to PR context when routing to PR events from issue threads\n const elevated = await this.elevateContextToPullRequest(\n { ...(prInfo as any), eventType: opts.eventOverride } as PRInfo,\n opts.eventOverride,\n log,\n debug\n );\n if (elevated) {\n prInfoForInline = elevated;\n } else {\n prInfoForInline = { ...(prInfo as any), eventType: opts.eventOverride } as PRInfo;\n }\n this.routingEventOverride = opts.eventOverride;\n const msg = `↪ goto_event: inline '${target}' with event=${opts.eventOverride}${\n elevated ? ' (elevated to PR context)' : ''\n }`;\n if (debug) log(`🔧 Debug: ${msg}`);\n try {\n require('./logger').logger.info(msg);\n } catch {}\n }\n let r: ReviewSummary;\n try {\n r = await prov.execute(prInfoForInline, provCfg, depResults, sessionInfo);\n } finally {\n // Restore previous override\n this.routingEventOverride = prevEventOverride;\n }\n // enrich with metadata similar to main flow\n const enrichedIssues = (r.issues || []).map(issue => ({\n ...issue,\n checkName: target,\n ruleId: `${target}/${issue.ruleId}`,\n group: targetCfg.group,\n schema: typeof targetCfg.schema === 'object' ? 'custom' : targetCfg.schema,\n template: targetCfg.template,\n timestamp: Date.now(),\n }));\n const enriched = { ...r, issues: enrichedIssues } as ReviewSummary;\n\n // Track output history for loop/goto scenarios\n const enrichedWithOutput = enriched as ReviewSummary & { output?: unknown };\n if (enrichedWithOutput.output !== undefined) {\n this.trackOutputHistory(target, enrichedWithOutput.output);\n }\n\n resultsMap?.set(target, enriched);\n if (debug) log(`🔧 Debug: inline executed '${target}', issues: ${enrichedIssues.length}`);\n return enriched;\n };\n\n // Begin attempts loop\n // We treat each retry/goto/run as consuming one loop budget entry\n while (true) {\n try {\n try {\n emitNdjsonFallback('visor.provider', {\n 'visor.check.id': checkName,\n 'visor.provider.type': providerConfig.type || 'ai',\n });\n } catch {}\n const res = await provider.execute(prInfo, providerConfig, dependencyResults, sessionInfo);\n try {\n currentRouteOutput = (res as any)?.output;\n } catch {}\n // Success path\n // Treat result issues with severity error/critical as a soft-failure eligible for on_fail routing\n const hasSoftFailure = (res.issues || []).some(\n i => i.severity === 'error' || i.severity === 'critical'\n );\n if (hasSoftFailure && onFail) {\n if (debug)\n log(\n `🔧 Debug: Soft failure detected for '${checkName}' with ${(res.issues || []).length} issue(s)`\n );\n const lastError: any = {\n message: 'soft-failure: issues present',\n code: 'soft_failure',\n issues: res.issues,\n };\n const dynamicRun = await evalRunJs(onFail.run_js, lastError);\n let runList = [...(onFail.run || []), ...dynamicRun].filter(Boolean);\n runList = Array.from(new Set(runList));\n if (debug) log(`🔧 Debug: on_fail.run (soft) list = [${runList.join(', ')}]`);\n if (runList.length > 0) {\n try {\n require('./logger').logger.info(\n `▶ on_fail.run: scheduling [${runList.join(', ')}] after '${checkName}'`\n );\n } catch {}\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_fail run`\n );\n }\n if (debug) log(`🔧 Debug: on_fail.run (soft) executing [${runList.join(', ')}]`);\n for (const stepId of runList) {\n await executeNamedCheckInline(stepId);\n }\n }\n let target = await evalGotoJs(onFail.goto_js, lastError);\n if (!target && onFail.goto) target = onFail.goto;\n if (debug) log(`🔧 Debug: on_fail.goto (soft) target = ${target}`);\n if (target) {\n try {\n require('./logger').logger.info(\n `↪ on_fail.goto: jumping to '${target}' from '${checkName}'`\n );\n } catch {}\n if (!allAncestors.includes(target)) {\n if (debug)\n log(\n `⚠️ Debug: on_fail.goto (soft) '${target}' is not an ancestor of '${checkName}' — skipping`\n );\n } else {\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_fail goto`\n );\n }\n await executeNamedCheckInline(target, { eventOverride: onFail.goto_event });\n }\n }\n\n const retryMax = onFail.retry?.max ?? 0;\n const base = onFail.retry?.backoff?.delay_ms ?? 0;\n const mode = onFail.retry?.backoff?.mode ?? 'fixed';\n if (attempt <= retryMax) {\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(`Routing loop budget exceeded (max_loops=${maxLoops}) during retry`);\n }\n const delay = base > 0 ? this.computeBackoffDelay(attempt, mode, base, seed) : 0;\n if (debug)\n log(\n `🔁 Debug: retrying '${checkName}' (soft) attempt ${attempt + 1}/${retryMax + 1} after ${delay}ms`\n );\n if (delay > 0) await this.sleep(delay);\n attempt++;\n continue; // loop\n }\n // No retry configured: return existing result\n return res;\n }\n let needRerun = false;\n let rerunEventOverride: import('./types/config').EventTrigger | undefined;\n if (onSuccess) {\n // Compute run list\n const dynamicRun = await evalRunJs(onSuccess.run_js);\n const runList = [...(onSuccess.run || []), ...dynamicRun].filter(Boolean);\n if (runList.length > 0) {\n try {\n require('./logger').logger.info(\n `▶ on_success.run: scheduling [${Array.from(new Set(runList)).join(', ')}] after '${checkName}'`\n );\n } catch {}\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_success run`\n );\n }\n for (const stepId of Array.from(new Set(runList))) {\n await executeNamedCheckInline(stepId);\n }\n } else {\n // Provide a lightweight reason when nothing is scheduled via on_success.run\n try {\n const assoc = resolveAssociationFromEvent(\n (prInfo as any)?.eventContext,\n prInfo.authorAssociation\n );\n const perms = createPermissionHelpers(assoc, detectLocalMode());\n const allowedMember = perms.hasMinPermission('MEMBER');\n let intent: string | undefined;\n try {\n intent = (res as any)?.output?.intent;\n } catch {}\n require('./logger').logger.info(\n `⏭ on_success.run: none after '${checkName}' (event=${prInfo.eventType || 'manual'}, intent=${intent || 'n/a'}, assoc=${assoc || 'unknown'}, memberOrHigher=${allowedMember})`\n );\n } catch {}\n }\n // Optional goto\n let target = await evalGotoJs(onSuccess.goto_js);\n if (!target && onSuccess.goto) target = onSuccess.goto;\n if (target) {\n try {\n require('./logger').logger.info(\n `↪ on_success.goto: jumping to '${target}' from '${checkName}'`\n );\n } catch {}\n if (!allAncestors.includes(target)) {\n // Forward-run from target under goto_event: execute target and all dependents matching event\n const prevEventOverride2 = this.routingEventOverride;\n if (onSuccess.goto_event) {\n this.routingEventOverride = onSuccess.goto_event;\n }\n try {\n // Build forward closure (target + transitive dependents)\n const cfgChecks = (config?.checks || {}) as Record<\n string,\n import('./types/config').CheckConfig\n >;\n const forwardSet = new Set<string>();\n if (cfgChecks[target]) forwardSet.add(target);\n const dependsOn = (name: string, root: string): boolean => {\n const seen = new Set<string>();\n const dfs = (n: string): boolean => {\n if (seen.has(n)) return false;\n seen.add(n);\n const deps = cfgChecks[n]?.depends_on || [];\n if (deps.includes(root)) return true;\n return deps.some(d => dfs(d));\n };\n return dfs(name);\n };\n const ev = onSuccess.goto_event || prInfo.eventType || 'issue_comment';\n for (const name of Object.keys(cfgChecks)) {\n if (name === target) continue;\n const onArr = cfgChecks[name]?.on as any;\n const eventMatches = !onArr || (Array.isArray(onArr) && onArr.includes(ev));\n if (!eventMatches) continue;\n if (dependsOn(name, target)) forwardSet.add(name);\n }\n // Topologically order forwardSet based on depends_on within this subset\n const order: string[] = [];\n const inSet = (n: string) => forwardSet.has(n);\n const tempMarks = new Set<string>();\n const permMarks = new Set<string>();\n const stack: string[] = [];\n const visit = (n: string) => {\n if (permMarks.has(n)) return;\n if (tempMarks.has(n)) {\n // Cycle detected — build a readable cycle path\n const idx = stack.indexOf(n);\n const cyclePath = idx >= 0 ? [...stack.slice(idx), n] : [n];\n throw new Error(\n `Cycle detected in forward-run dependency subset: ${cyclePath.join(' -> ')}`\n );\n }\n tempMarks.add(n);\n stack.push(n);\n const deps = (cfgChecks[n]?.depends_on || []).filter(inSet);\n for (const d of deps) visit(d);\n stack.pop();\n tempMarks.delete(n);\n permMarks.add(n);\n order.push(n);\n };\n for (const n of forwardSet) visit(n);\n // Execute in order with event override, updating statistics per child\n for (const stepId of order) {\n if (!this.executionStats.has(stepId)) this.initializeCheckStats(stepId);\n const childStart = this.recordIterationStart(stepId);\n const childRes = await executeNamedCheckInline(stepId, {\n eventOverride: onSuccess.goto_event,\n });\n const childIssues = (childRes.issues || []).map(i => ({ ...i }));\n const childSuccess = !this.hasFatal(childIssues);\n const childOutput: unknown = (childRes as any)?.output;\n this.recordIterationComplete(\n stepId,\n childStart,\n childSuccess,\n childIssues,\n childOutput\n );\n }\n // Do NOT append forward-run child issues to the current check result.\n // Child results are recorded independently in resultsMap and statistics,\n // and aggregators will include them without double-counting under the parent.\n } finally {\n this.routingEventOverride = prevEventOverride2;\n }\n } else {\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_success goto`\n );\n }\n await executeNamedCheckInline(target, { eventOverride: onSuccess.goto_event });\n // After jumping back to an ancestor, re-run the current check to re-validate with new state\n needRerun = true;\n rerunEventOverride = onSuccess.goto_event;\n }\n }\n }\n if (needRerun) {\n if (debug) log(`🔄 Debug: Re-running '${checkName}' after on_success.goto`);\n try {\n require('./logger').logger.info(`🔁 Re-running '${checkName}' after goto`);\n } catch {}\n // Apply same event override as goto (if any) for this re-run by setting routingEventOverride\n const prev = this.routingEventOverride;\n if (rerunEventOverride) this.routingEventOverride = rerunEventOverride;\n attempt++;\n // Loop will execute the check again with evaluateIfCondition seeing override\n // Restore after loop iteration completes for safety\n // We can't restore here; we'll restore at start of next iteration when override applied,\n // but ensure no lingering by resetting immediately after attempt increment\n this.routingEventOverride = prev;\n continue;\n }\n return res;\n } catch (err) {\n // Failure path\n if (!onFail) {\n throw err; // no routing policy\n }\n\n const lastError = err instanceof Error ? err : new Error(String(err));\n\n // Dynamic compute run/goto\n const dynamicRun = await evalRunJs(onFail.run_js, lastError);\n let runList = [...(onFail.run || []), ...dynamicRun].filter(Boolean);\n // Dedup while preserving order\n runList = Array.from(new Set(runList));\n\n if (runList.length > 0) {\n try {\n require('./logger').logger.info(\n `▶ on_fail.run: scheduling [${runList.join(', ')}] after '${checkName}'`\n );\n } catch {}\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_fail run`\n );\n }\n if (debug) log(`🔧 Debug: on_fail.run executing [${runList.join(', ')}]`);\n for (const stepId of runList) {\n await executeNamedCheckInline(stepId);\n }\n }\n\n let target = await evalGotoJs(onFail.goto_js, lastError);\n if (!target && onFail.goto) target = onFail.goto;\n if (target) {\n try {\n require('./logger').logger.info(\n `↪ on_fail.goto: jumping to '${target}' from '${checkName}'`\n );\n } catch {}\n if (!allAncestors.includes(target)) {\n if (debug)\n log(\n `⚠️ Debug: on_fail.goto '${target}' is not an ancestor of '${checkName}' — skipping`\n );\n } else {\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(\n `Routing loop budget exceeded (max_loops=${maxLoops}) during on_fail goto`\n );\n }\n await executeNamedCheckInline(target, { eventOverride: onFail.goto_event });\n }\n }\n\n // Retry if allowed\n const retryMax = onFail.retry?.max ?? 0;\n const base = onFail.retry?.backoff?.delay_ms ?? 0;\n const mode = onFail.retry?.backoff?.mode ?? 'fixed';\n if (attempt <= retryMax) {\n loopCount++;\n if (loopCount > maxLoops) {\n throw new Error(`Routing loop budget exceeded (max_loops=${maxLoops}) during retry`);\n }\n const delay = base > 0 ? this.computeBackoffDelay(attempt, mode, base, seed) : 0;\n if (debug)\n log(\n `🔁 Debug: retrying '${checkName}' attempt ${attempt + 1}/${retryMax + 1} after ${delay}ms`\n );\n if (delay > 0) await this.sleep(delay);\n attempt++;\n continue; // loop\n }\n\n // Exhausted retry budget; rethrow\n throw lastError;\n }\n }\n }\n\n /**\n * Set webhook context on a provider if it supports it\n */\n private setProviderWebhookContext(\n provider: import('./providers/check-provider.interface').CheckProvider\n ): void {\n if (this.webhookContext && provider.setWebhookContext) {\n provider.setWebhookContext(this.webhookContext.webhookData);\n }\n }\n\n /**\n * Filter checks based on tag filter configuration\n */\n private filterChecksByTags(\n checks: string[],\n config: import('./types/config').VisorConfig | undefined,\n tagFilter: import('./types/config').TagFilter | undefined\n ): string[] {\n const logFn = this.config?.output?.pr_comment ? console.error : console.log;\n\n return checks.filter(checkName => {\n const checkConfig = config?.checks?.[checkName];\n if (!checkConfig) {\n // If no config for this check, include it by default\n return true;\n }\n\n const checkTags = checkConfig.tags || [];\n\n // If check has tags but no tag filter is specified, exclude it\n if (checkTags.length > 0 && (!tagFilter || (!tagFilter.include && !tagFilter.exclude))) {\n logFn(`⏭️ Skipping check '${checkName}' - check has tags but no tag filter specified`);\n return false;\n }\n\n // If no tag filter is specified and check has no tags, include it\n if (!tagFilter || (!tagFilter.include && !tagFilter.exclude)) {\n return true;\n }\n\n // If check has no tags and a tag filter is specified, include it (untagged checks always run)\n if (checkTags.length === 0) {\n return true;\n }\n\n // Check exclude tags first (if any exclude tag matches, skip the check)\n if (tagFilter.exclude && tagFilter.exclude.length > 0) {\n const hasExcludedTag = tagFilter.exclude.some(tag => checkTags.includes(tag));\n if (hasExcludedTag) {\n logFn(`⏭️ Skipping check '${checkName}' - has excluded tag`);\n return false;\n }\n }\n\n // Check include tags (if specified, at least one must match)\n if (tagFilter.include && tagFilter.include.length > 0) {\n const hasIncludedTag = tagFilter.include.some(tag => checkTags.includes(tag));\n if (!hasIncludedTag) {\n logFn(`⏭️ Skipping check '${checkName}' - does not have required tags`);\n return false;\n }\n }\n\n return true;\n });\n }\n\n /**\n * Execute checks on the local repository\n */\n async executeChecks(options: CheckExecutionOptions): Promise<AnalysisResult> {\n const startTime = Date.now();\n const timestamp = new Date().toISOString();\n\n try {\n // Initialize memory store if configured\n if (options.config?.memory) {\n const memoryStore = MemoryStore.getInstance(options.config.memory);\n await memoryStore.initialize();\n logger.debug('Memory store initialized');\n }\n\n // Store webhook context if provided\n this.webhookContext = options.webhookContext;\n\n // Determine where to send log messages based on output format\n const logFn = (msg: string) => logger.info(msg);\n\n // Initialize GitHub checks if enabled\n if (options.githubChecks?.enabled && options.githubChecks.octokit) {\n await this.initializeGitHubChecks(options, logFn);\n }\n\n // Analyze the repository\n logFn('🔍 Analyzing local git repository...');\n const repositoryInfo = await this.gitAnalyzer.analyzeRepository();\n\n if (!repositoryInfo.isGitRepository) {\n // Complete GitHub checks with error if they were initialized\n if (this.checkRunMap) {\n await this.completeGitHubChecksWithError('Not a git repository or no changes found');\n }\n\n return this.createErrorResult(\n repositoryInfo,\n 'Not a git repository or no changes found',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // Convert to PRInfo format for compatibility with existing reviewer\n const prInfo = this.gitAnalyzer.toPRInfo(repositoryInfo);\n\n // Apply tag filtering if specified\n const filteredChecks = this.filterChecksByTags(\n options.checks,\n options.config,\n options.tagFilter || options.config?.tag_filter\n );\n\n if (filteredChecks.length === 0) {\n logger.warn('⚠️ No checks match the tag filter criteria');\n // Complete GitHub checks with no checks message if they were initialized\n if (this.checkRunMap) {\n await this.completeGitHubChecksWithError('No checks match the tag filter criteria');\n }\n return this.createErrorResult(\n repositoryInfo,\n 'No checks match the tag filter criteria',\n startTime,\n timestamp,\n options.checks\n );\n }\n\n // Update GitHub checks to in-progress status\n if (this.checkRunMap) {\n await this.updateGitHubChecksInProgress(options);\n }\n\n // Execute checks using the existing PRReviewer\n logFn(`🤖 Executing checks: ${filteredChecks.join(', ')}`);\n const reviewSummary = await this.executeReviewChecks(\n prInfo,\n filteredChecks,\n options.timeout,\n options.config,\n options.outputFormat,\n options.debug,\n options.maxParallelism,\n options.failFast\n );\n\n // Complete GitHub checks with results\n if (this.checkRunMap) {\n await this.completeGitHubChecksWithResults(reviewSummary, options, prInfo);\n }\n\n const executionTime = Date.now() - startTime;\n\n // Collect debug information when debug mode is enabled\n let debugInfo: import('./output-formatters').DebugInfo | undefined;\n if (options.debug && reviewSummary.debug) {\n debugInfo = {\n provider: reviewSummary.debug.provider,\n model: reviewSummary.debug.model,\n processingTime: reviewSummary.debug.processingTime,\n parallelExecution: options.checks.length > 1,\n checksExecuted: options.checks,\n totalApiCalls: reviewSummary.debug.totalApiCalls || options.checks.length,\n apiCallDetails: reviewSummary.debug.apiCallDetails,\n };\n }\n\n // Build execution statistics\n const executionStatistics = this.buildExecutionStatistics();\n\n return {\n repositoryInfo,\n reviewSummary,\n executionTime,\n timestamp,\n checksExecuted: filteredChecks,\n executionStatistics,\n debug: debugInfo,\n };\n } catch (error) {\n logger.error(\n 'Error executing checks: ' + (error instanceof Error ? error.message : String(error))\n );\n\n // Complete GitHub checks with error if they were initialized\n if (this.checkRunMap) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';\n await this.completeGitHubChecksWithError(errorMessage);\n }\n\n const fallbackRepositoryInfo: GitRepositoryInfo = {\n title: 'Error during analysis',\n body: `Error: ${error instanceof Error ? error.message : 'Unknown error'}`,\n author: 'system',\n base: 'main',\n head: 'HEAD',\n files: [],\n totalAdditions: 0,\n totalDeletions: 0,\n isGitRepository: false,\n workingDirectory: options.workingDirectory || process.cwd(),\n };\n\n return this.createErrorResult(\n fallbackRepositoryInfo,\n error instanceof Error ? error.message : 'Unknown error occurred',\n startTime,\n timestamp,\n options.checks\n );\n }\n }\n\n /**\n * Execute tasks with controlled parallelism using a pool pattern\n */\n private async executeWithLimitedParallelism<T>(\n tasks: (() => Promise<T>)[],\n maxParallelism: number,\n failFast?: boolean\n ): Promise<PromiseSettledResult<T>[]> {\n if (maxParallelism <= 0) {\n throw new Error('Max parallelism must be greater than 0');\n }\n\n if (tasks.length === 0) {\n return [];\n }\n\n const results: PromiseSettledResult<T>[] = new Array(tasks.length);\n let currentIndex = 0;\n let shouldStop = false;\n\n // Worker function that processes tasks\n const worker = async (): Promise<void> => {\n while (currentIndex < tasks.length && !shouldStop) {\n const taskIndex = currentIndex++;\n if (taskIndex >= tasks.length) break;\n\n try {\n const result = await tasks[taskIndex]();\n results[taskIndex] = { status: 'fulfilled', value: result };\n\n // Check if we should stop due to fail-fast\n if (failFast && this.shouldFailFast(result)) {\n shouldStop = true;\n break;\n }\n } catch (error) {\n results[taskIndex] = { status: 'rejected', reason: error };\n\n // If fail-fast is enabled and we have an error, stop execution\n if (failFast) {\n shouldStop = true;\n break;\n }\n }\n }\n };\n\n // Create workers up to the parallelism limit\n const workers: Promise<void>[] = [];\n const workerCount = Math.min(maxParallelism, tasks.length);\n\n for (let i = 0; i < workerCount; i++) {\n workers.push(worker());\n }\n\n // Wait for all workers to complete\n await Promise.all(workers);\n\n return results;\n }\n\n /**\n * Execute review checks using parallel execution for multiple AI checks\n */\n private async executeReviewChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n outputFormat?: string,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean\n ): Promise<ReviewSummary> {\n // Store config for use in filtering\n this.config = config;\n\n // Determine where to send log messages based on output format\n // Use debug logger for internal engine messages; important notices use logger.warn/info directly.\n const logFn = (msg: string) => logger.debug(msg);\n\n // Only output debug messages if debug mode is enabled\n if (debug) {\n logFn(`🔧 Debug: executeReviewChecks called with checks: ${JSON.stringify(checks)}`);\n logFn(`🔧 Debug: Config available: ${!!config}, Config has checks: ${!!config?.checks}`);\n }\n\n // Filter checks based on current event type to prevent execution of checks that shouldn't run\n const filteredChecks = this.filterChecksByEvent(checks, config, prInfo, logFn, debug);\n if (filteredChecks.length !== checks.length && debug) {\n logFn(\n `🔧 Debug: Event filtering reduced checks from ${checks.length} to ${filteredChecks.length}: ${JSON.stringify(filteredChecks)}`\n );\n }\n\n // Use filtered checks for execution\n checks = filteredChecks;\n\n // If we have a config with individual check definitions, prefer dependency-aware execution\n // even for a single check, so provider types other than 'ai' work consistently.\n const allConfigured = config?.checks ? checks.every(name => !!config.checks[name]) : false;\n if (allConfigured) {\n if (debug) {\n logFn(\n `🔧 Debug: Using dependency-aware execution for ${checks.length} configured check(s)`\n );\n }\n return await this.executeDependencyAwareChecks(\n prInfo,\n checks,\n timeout,\n config,\n logFn,\n debug,\n maxParallelism,\n failFast\n );\n }\n\n // Single check execution (existing logic)\n if (checks.length === 1) {\n if (debug) {\n logFn(`🔧 Debug: Using single check execution for: ${checks[0]}`);\n }\n\n // If we have a config definition for this check, use it\n if (config?.checks?.[checks[0]]) {\n return await this.executeSingleConfiguredCheck(prInfo, checks[0], timeout, config, logFn);\n }\n\n // Try provider system for single checks\n if (this.providerRegistry.hasProvider(checks[0])) {\n const provider = this.providerRegistry.getProviderOrThrow(checks[0]);\n this.setProviderWebhookContext(provider);\n const providerConfig: CheckProviderConfig = {\n type: checks[0],\n prompt: 'all',\n eventContext: this.enrichEventContext(prInfo.eventContext),\n ai: timeout ? { timeout } : undefined,\n };\n const result = await provider.execute(prInfo, providerConfig);\n\n // Prefix issues with check name for consistent grouping\n const prefixedIssues = (result.issues || []).map(issue => ({\n ...issue,\n ruleId: `${checks[0]}/${issue.ruleId}`,\n }));\n\n return {\n ...result,\n issues: prefixedIssues,\n };\n }\n }\n\n // Check if 'ai' provider is available for focus-based checks (legacy support)\n if (this.providerRegistry.hasProvider('ai')) {\n if (debug) {\n logFn(`🔧 Debug: Using AI provider with focus mapping`);\n }\n const provider = this.providerRegistry.getProviderOrThrow('ai');\n this.setProviderWebhookContext(provider);\n\n let focus = 'all';\n let checkName = 'all';\n if (checks.length === 1) {\n checkName = checks[0];\n if (checks[0] === 'security' || checks[0] === 'performance' || checks[0] === 'style') {\n focus = checks[0];\n }\n } else {\n // For multiple checks, combine them into 'all' focus\n focus = 'all';\n }\n\n const providerConfig: CheckProviderConfig = {\n type: 'ai',\n prompt: focus,\n focus: focus,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n ai: timeout ? { timeout } : undefined,\n // Inherit global AI provider and model settings if config is available\n ai_provider: config?.ai_provider,\n ai_model: config?.ai_model,\n };\n\n const result = await provider.execute(prInfo, providerConfig);\n\n // Prefix issues with check name for consistent grouping\n const prefixedIssues = (result.issues || []).map(issue => ({\n ...issue,\n ruleId: `${checkName}/${issue.ruleId}`,\n }));\n\n return {\n ...result,\n issues: prefixedIssues,\n };\n }\n\n // Fallback to existing PRReviewer for backward compatibility\n if (debug) {\n logFn(`🔧 Debug: Using legacy PRReviewer fallback`);\n }\n const focusMap: Record<string, ReviewOptions['focus']> = {\n security: 'security',\n performance: 'performance',\n style: 'style',\n all: 'all',\n architecture: 'all',\n };\n\n let focus: ReviewOptions['focus'] = 'all';\n if (checks.length === 1 && focusMap[checks[0]]) {\n focus = focusMap[checks[0]];\n }\n\n return await this.reviewer.reviewPR('local', 'repository', 0, prInfo, {\n focus,\n format: 'table',\n });\n }\n\n /**\n * Execute review checks and return grouped results with statistics for new architecture\n */\n public async executeGroupedChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n outputFormat?: string,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean,\n tagFilter?: import('./types/config').TagFilter\n ): Promise<ExecutionResult> {\n // Determine where to send log messages based on output format\n const logFn =\n outputFormat === 'json' || outputFormat === 'sarif'\n ? debug\n ? console.error\n : () => {}\n : console.log;\n\n // Only output debug messages if debug mode is enabled\n if (debug) {\n logger.debug(`🔧 Debug: executeGroupedChecks called with checks: ${JSON.stringify(checks)}`);\n logger.debug(\n `🔧 Debug: Config available: ${!!config}, Config has checks: ${!!config?.checks}`\n );\n }\n\n // Filter checks based on current event type to prevent execution of checks that shouldn't run\n const filteredChecks = this.filterChecksByEvent(checks, config, prInfo, logFn, debug);\n if (filteredChecks.length !== checks.length && debug) {\n logger.debug(\n `🔧 Debug: Event filtering reduced checks from ${checks.length} to ${filteredChecks.length}: ${JSON.stringify(filteredChecks)}`\n );\n }\n\n // Apply tag filtering if specified\n const tagFilteredChecks = this.filterChecksByTags(\n filteredChecks,\n config,\n tagFilter || config?.tag_filter\n );\n\n if (tagFilteredChecks.length !== filteredChecks.length && debug) {\n logger.debug(\n `🔧 Debug: Tag filtering reduced checks from ${filteredChecks.length} to ${tagFilteredChecks.length}: ${JSON.stringify(tagFilteredChecks)}`\n );\n }\n\n // Use filtered checks for execution\n checks = tagFilteredChecks;\n\n // Capture GitHub Action context (owner/repo/octokit) if available from environment\n // This is used for context elevation when routing via goto_event\n // Only initialize if not already set by constructor (which has the authenticated octokit)\n if (!this.actionContext) {\n try {\n const repoEnv = process.env.GITHUB_REPOSITORY || '';\n const [owner, repo] = repoEnv.split('/') as [string, string];\n const token = process.env['INPUT_GITHUB-TOKEN'] || process.env['GITHUB_TOKEN'];\n if (owner && repo) {\n this.actionContext = { owner, repo };\n if (token) {\n const { Octokit } = await import('@octokit/rest');\n this.actionContext.octokit = new Octokit({ auth: token });\n }\n }\n } catch {\n // Non-fatal: context elevation will be skipped if not available\n }\n }\n\n // Check if we have any checks left after filtering\n if (checks.length === 0) {\n logger.warn('⚠️ No checks remain after tag filtering');\n return {\n results: {},\n statistics: this.buildExecutionStatistics(),\n };\n }\n\n if (!config?.checks) {\n throw new Error('Config with check definitions required for grouped execution');\n }\n\n // If we have a config with individual check definitions, use dependency-aware execution\n const hasDependencies = checks.some(checkName => {\n const checkConfig = config.checks[checkName];\n return checkConfig?.depends_on && checkConfig.depends_on.length > 0;\n });\n const hasRouting = checks.some(checkName => {\n const c = config.checks[checkName];\n return Boolean(c?.on_success || c?.on_fail);\n });\n\n if (checks.length > 1 || hasDependencies || hasRouting) {\n if (debug) {\n logger.debug(\n `🔧 Debug: Using grouped dependency-aware execution for ${checks.length} checks (has dependencies: ${hasDependencies}, has routing: ${hasRouting})`\n );\n }\n return await this.executeGroupedDependencyAwareChecks(\n prInfo,\n checks,\n timeout,\n config,\n logFn,\n debug,\n maxParallelism,\n failFast\n );\n }\n\n // Single check execution\n if (checks.length === 1) {\n if (debug) {\n logger.debug(`🔧 Debug: Using grouped single check execution for: ${checks[0]}`);\n }\n const checkResult = await this.executeSingleGroupedCheck(\n prInfo,\n checks[0],\n timeout,\n config,\n logFn,\n debug\n );\n\n const groupedResults: GroupedCheckResults = {};\n groupedResults[checkResult.group] = [checkResult];\n return {\n results: groupedResults,\n statistics: this.buildExecutionStatistics(),\n };\n }\n\n // No checks to execute\n return {\n results: {},\n statistics: this.buildExecutionStatistics(),\n };\n }\n\n /**\n * Execute single check and return grouped result\n */\n private async executeSingleGroupedCheck(\n prInfo: PRInfo,\n checkName: string,\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n logFn?: (message: string) => void,\n debug?: boolean\n ): Promise<CheckResult> {\n if (!config?.checks?.[checkName]) {\n throw new Error(`No configuration found for check: ${checkName}`);\n }\n\n const checkConfig = config.checks[checkName];\n const providerType = checkConfig.type || 'ai';\n const provider = this.providerRegistry.getProviderOrThrow(providerType);\n this.setProviderWebhookContext(provider);\n\n const providerConfig: CheckProviderConfig = {\n type: providerType,\n prompt: checkConfig.prompt,\n focus: checkConfig.focus || this.mapCheckNameToFocus(checkName),\n schema: checkConfig.schema,\n group: checkConfig.group,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n ai: {\n timeout: timeout || 600000,\n debug: debug,\n ...(checkConfig.ai || {}),\n },\n ai_provider: checkConfig.ai_provider || config.ai_provider,\n ai_model: checkConfig.ai_model || config.ai_model,\n // Pass claude_code config if present\n claude_code: checkConfig.claude_code,\n // Pass output history for loop/goto scenarios\n __outputHistory: this.outputHistory,\n // Pass any provider-specific config\n ...checkConfig,\n };\n providerConfig.forEach = checkConfig.forEach;\n\n const result = await provider.execute(prInfo, providerConfig);\n\n // Validate forEach output (skip if there are already errors from transform_js or other sources)\n if (checkConfig.forEach && (!result.issues || result.issues.length === 0)) {\n const reviewSummaryWithOutput = result as ReviewSummary & { output?: unknown };\n const validation = this.validateAndNormalizeForEachOutput(\n checkName,\n reviewSummaryWithOutput.output,\n checkConfig.group\n );\n\n if (!validation.isValid) {\n return validation.error;\n }\n }\n\n // Evaluate fail_if conditions\n if (config && (config.fail_if || checkConfig.fail_if)) {\n const failureResults = await this.evaluateFailureConditions(\n checkName,\n result,\n config,\n prInfo\n );\n\n // Add failure condition issues to the result\n if (failureResults.length > 0) {\n const failureIssues = failureResults\n .filter(f => f.failed)\n .map(f => ({\n file: 'system',\n line: 0,\n ruleId: f.conditionName,\n message: f.message || `Failure condition met: ${f.expression}`,\n severity: (f.severity || 'error') as 'info' | 'warning' | 'error' | 'critical',\n category: 'logic' as const,\n }));\n\n result.issues = [...(result.issues || []), ...failureIssues];\n }\n }\n\n // Render the check content using the appropriate template\n const content = await this.renderCheckContent(checkName, result, checkConfig, prInfo);\n\n // Determine the group: if group_by is 'check', use the check name; otherwise use configured group or 'default'\n let group = checkConfig.group || 'default';\n if (config?.output?.pr_comment?.group_by === 'check' && !checkConfig.group) {\n group = checkName;\n }\n\n return {\n checkName,\n content,\n group,\n output: (result as any).output,\n debug: result.debug,\n issues: result.issues, // Include structured issues\n };\n }\n\n /**\n * Validate and normalize forEach output\n * Returns normalized array or throws validation error result\n */\n private validateAndNormalizeForEachOutput(\n checkName: string,\n output: unknown,\n checkGroup?: string\n ):\n | {\n isValid: true;\n normalizedOutput: unknown[];\n }\n | {\n isValid: false;\n error: {\n checkName: string;\n content: string;\n group: string;\n issues: Array<{\n file: string;\n line: number;\n ruleId: string;\n message: string;\n severity: 'error';\n category: 'logic';\n }>;\n };\n } {\n if (output === undefined) {\n logger.error(`✗ forEach check \"${checkName}\" produced undefined output`);\n return {\n isValid: false,\n error: {\n checkName,\n content: '',\n group: checkGroup || 'default',\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'forEach/undefined_output',\n message: `forEach check \"${checkName}\" produced undefined output. Verify your command outputs valid data and your transform_js returns a value.`,\n severity: 'error',\n category: 'logic',\n },\n ],\n },\n };\n }\n\n // Normalize output to array\n let normalizedOutput: unknown[];\n\n if (Array.isArray(output)) {\n normalizedOutput = output;\n } else if (output && typeof output === 'object' && Array.isArray((output as any).items)) {\n normalizedOutput = (output as any).items as unknown[];\n } else if (typeof output === 'string') {\n try {\n const parsed = JSON.parse(output);\n normalizedOutput = Array.isArray(parsed) ? parsed : [parsed];\n } catch {\n normalizedOutput = [output];\n }\n } else if (output === null) {\n normalizedOutput = [];\n } else {\n normalizedOutput = [output];\n }\n\n // Log the result (empty arrays are valid, just result in 0 iterations)\n logger.info(` Found ${normalizedOutput.length} items for forEach iteration`);\n return {\n isValid: true,\n normalizedOutput,\n };\n }\n\n /**\n * Execute multiple checks with dependency awareness - return grouped results with statistics\n */\n private async executeGroupedDependencyAwareChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n logFn?: (message: string) => void,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean\n ): Promise<ExecutionResult> {\n // Use the existing dependency-aware execution logic\n const reviewSummary = await this.executeDependencyAwareChecks(\n prInfo,\n checks,\n timeout,\n config,\n logFn,\n debug,\n maxParallelism,\n failFast\n );\n\n // Build execution statistics\n const executionStatistics = this.buildExecutionStatistics();\n\n // Convert the flat ReviewSummary to grouped CheckResults\n const groupedResults = await this.convertReviewSummaryToGroupedResults(\n reviewSummary,\n checks,\n config,\n prInfo\n );\n\n return {\n results: groupedResults,\n statistics: executionStatistics,\n };\n }\n\n /**\n * Convert ReviewSummary to GroupedCheckResults\n */\n private async convertReviewSummaryToGroupedResults(\n reviewSummary: ReviewSummary,\n checks: string[],\n config?: import('./types/config').VisorConfig,\n prInfo?: PRInfo\n ): Promise<GroupedCheckResults> {\n const groupedResults: GroupedCheckResults = {};\n const agg = reviewSummary as ReviewSummary & {\n __contents?: Record<string, string | undefined>;\n __outputs?: Record<string, unknown>;\n __executed?: string[];\n };\n const contentMap = agg.__contents;\n const outputMap = agg.__outputs;\n // Build a unified list of all checks that produced results:\n // - originally requested checks\n // - any checks that produced content/output during routing (e.g., forward-run after goto)\n // - any checks that emitted issues with checkName set\n const allCheckNames: string[] = [];\n const seen = new Set<string>();\n const pushUnique = (n?: string) => {\n if (!n) return;\n if (!seen.has(n)) {\n seen.add(n);\n allCheckNames.push(n);\n }\n };\n for (const n of checks) pushUnique(n);\n if (contentMap) for (const n of Object.keys(contentMap)) pushUnique(n);\n if (outputMap) for (const n of Object.keys(outputMap)) pushUnique(n);\n for (const issue of reviewSummary.issues || []) pushUnique(issue.checkName);\n if (Array.isArray(agg.__executed)) for (const n of agg.__executed) pushUnique(n);\n\n // Process each discovered check individually\n for (const checkName of allCheckNames) {\n const checkConfig = config?.checks?.[checkName];\n if (!checkConfig) continue;\n\n // Extract issues for this check\n const checkIssues = (reviewSummary.issues || []).filter(\n issue => issue.checkName === checkName\n );\n\n // Create a mini ReviewSummary for this check\n const checkSummary: ReviewSummary & { output?: unknown } = {\n issues: checkIssues,\n debug: reviewSummary.debug,\n };\n\n if (contentMap?.[checkName]) {\n (checkSummary as any).content = contentMap[checkName];\n }\n if (outputMap && Object.prototype.hasOwnProperty.call(outputMap, checkName)) {\n checkSummary.output = outputMap[checkName];\n }\n\n // Render content for this check (never let template errors abort the whole run)\n let content: string = '';\n let issuesForCheck = [...checkIssues];\n try {\n content = await this.renderCheckContent(checkName, checkSummary, checkConfig, prInfo);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n console.error(`❌ Failed to render content for check '${checkName}': ${msg}`);\n // Add a synthetic issue so it appears in output and GitHub Checks\n issuesForCheck = [\n ...issuesForCheck,\n {\n file: 'system',\n line: 0,\n ruleId: `${checkName}/render-error`,\n message: `Template rendering failed: ${msg}`,\n severity: 'error' as const,\n category: 'logic' as const,\n },\n ];\n }\n\n // Determine the group: if group_by is 'check', use the check name; otherwise use configured group or 'default'\n let group = checkConfig.group || 'default';\n if (config?.output?.pr_comment?.group_by === 'check' && !checkConfig.group) {\n group = checkName;\n }\n\n const checkResult: CheckResult = {\n checkName,\n content,\n group,\n output: checkSummary.output,\n debug: reviewSummary.debug,\n issues: issuesForCheck, // Include structured issues + rendering error if any\n };\n\n // Add to appropriate group\n if (!groupedResults[group]) {\n groupedResults[group] = [];\n }\n groupedResults[group].push(checkResult);\n }\n\n return groupedResults;\n }\n\n /**\n * Validates that a file path is safe and within the project directory\n * Prevents path traversal attacks by:\n * - Blocking absolute paths\n * - Blocking paths with \"..\" segments\n * - Ensuring resolved path is within project directory\n * - Blocking special characters and null bytes\n * - Enforcing .liquid file extension\n */\n private async validateTemplatePath(templatePath: string): Promise<string> {\n const path = await import('path');\n\n // Validate input\n if (!templatePath || typeof templatePath !== 'string' || templatePath.trim() === '') {\n throw new Error('Template path must be a non-empty string');\n }\n\n // Block null bytes and other dangerous characters\n if (templatePath.includes('\\0') || templatePath.includes('\\x00')) {\n throw new Error('Template path contains invalid characters');\n }\n\n // Enforce .liquid file extension\n if (!templatePath.endsWith('.liquid')) {\n throw new Error('Template file must have .liquid extension');\n }\n\n // Block absolute paths\n if (path.isAbsolute(templatePath)) {\n throw new Error('Template path must be relative to project directory');\n }\n\n // Block paths with \"..\" segments\n if (templatePath.includes('..')) {\n throw new Error('Template path cannot contain \"..\" segments');\n }\n\n // Block paths starting with ~ (home directory)\n if (templatePath.startsWith('~')) {\n throw new Error('Template path cannot reference home directory');\n }\n\n // Get the project root directory from git analyzer\n const repositoryInfo = await this.gitAnalyzer.analyzeRepository();\n const projectRoot = repositoryInfo.workingDirectory;\n\n // Validate project root\n if (!projectRoot || typeof projectRoot !== 'string') {\n throw new Error('Unable to determine project root directory');\n }\n\n // Resolve the template path relative to project root\n const resolvedPath = path.resolve(projectRoot, templatePath);\n const resolvedProjectRoot = path.resolve(projectRoot);\n\n // Validate resolved paths\n if (\n !resolvedPath ||\n !resolvedProjectRoot ||\n resolvedPath === '' ||\n resolvedProjectRoot === ''\n ) {\n throw new Error(\n `Unable to resolve template path: projectRoot=\"${projectRoot}\", templatePath=\"${templatePath}\", resolvedPath=\"${resolvedPath}\", resolvedProjectRoot=\"${resolvedProjectRoot}\"`\n );\n }\n\n // Ensure the resolved path is still within the project directory\n if (\n !resolvedPath.startsWith(resolvedProjectRoot + path.sep) &&\n resolvedPath !== resolvedProjectRoot\n ) {\n throw new Error('Template path escapes project directory');\n }\n\n return resolvedPath;\n }\n\n /**\n * Evaluate `if` condition for a check\n * @param checkName Name of the check\n * @param condition The condition string to evaluate\n * @param prInfo PR information\n * @param results Current check results\n * @param debug Whether debug mode is enabled\n * @returns true if the check should run, false if it should be skipped\n */\n private async evaluateCheckCondition(\n checkName: string,\n condition: string,\n prInfo: PRInfo,\n results: Map<string, ReviewSummary>,\n debug?: boolean\n ): Promise<boolean> {\n // Determine event name for condition context, honoring any routing override\n const override = this.routingEventOverride;\n const eventName = override\n ? override.startsWith('pr_')\n ? 'pull_request'\n : override === 'issue_comment'\n ? 'issue_comment'\n : override.startsWith('issue_')\n ? 'issues'\n : 'manual'\n : 'issue_comment';\n\n const commenterAssoc = resolveAssociationFromEvent(\n (prInfo as any)?.eventContext,\n prInfo.authorAssociation\n );\n const shouldRun = await this.failureEvaluator.evaluateIfCondition(checkName, condition, {\n branch: prInfo.head,\n baseBranch: prInfo.base,\n filesChanged: prInfo.files.map(f => f.filename),\n event: eventName,\n environment: getSafeEnvironmentVariables(),\n previousResults: results,\n authorAssociation: commenterAssoc,\n });\n\n if (!shouldRun && debug) {\n logger.debug(`🔧 Debug: Skipping check '${checkName}' - if condition evaluated to false`);\n }\n\n return shouldRun;\n }\n\n /**\n * Render check content using the appropriate template\n */\n private async renderCheckContent(\n checkName: string,\n reviewSummary: ReviewSummary,\n checkConfig: CheckConfig,\n _prInfo?: PRInfo\n ): Promise<string> {\n const directContent = (reviewSummary as ReviewSummary & { content?: string }).content;\n if (typeof directContent === 'string' && directContent.trim()) {\n return directContent.trim();\n }\n\n // Import the liquid template system\n const { createExtendedLiquid } = await import('./liquid-extensions');\n const fs = await import('fs/promises');\n const path = await import('path');\n\n const liquid = createExtendedLiquid({\n trimTagLeft: false,\n trimTagRight: false,\n trimOutputLeft: false,\n trimOutputRight: false,\n greedy: false,\n });\n\n // Determine template to use\n // If schema is an object (inline JSON schema), use 'plain' rendering\n // If schema is a file path (legitimate path with / and ends with .json), treat as plain (schema file reference)\n let schemaName: string;\n if (typeof checkConfig.schema === 'object') {\n schemaName = 'plain';\n } else if (\n typeof checkConfig.schema === 'string' &&\n checkConfig.schema.includes('/') &&\n checkConfig.schema.endsWith('.json') &&\n !checkConfig.schema.includes('..') // Reject paths containing .. (parent directory)\n ) {\n // Schema is a file path reference - use plain rendering\n // The schema file will be handled by the AI provider when making the request\n schemaName = 'plain';\n } else {\n schemaName = checkConfig.schema || 'plain';\n }\n\n let templateContent: string;\n let enrichAssistantContext = false;\n\n if (checkConfig.template) {\n // Custom template\n if (checkConfig.template.content) {\n templateContent = checkConfig.template.content;\n } else if (checkConfig.template.file) {\n // Validate the template file path to prevent path traversal attacks\n const validatedPath = await this.validateTemplatePath(checkConfig.template.file);\n templateContent = await fs.readFile(validatedPath, 'utf-8');\n } else {\n throw new Error('Custom template must specify either \"file\" or \"content\"');\n }\n } else if (schemaName === 'plain') {\n // Plain schema - return raw content directly\n return reviewSummary.issues?.[0]?.message || '';\n } else {\n // Use built-in schema template\n const sanitizedSchema = schemaName.replace(/[^a-zA-Z0-9-]/g, '');\n if (!sanitizedSchema) {\n throw new Error('Invalid schema name');\n }\n const templatePath = path.join(__dirname, `../output/${sanitizedSchema}/template.liquid`);\n templateContent = await fs.readFile(templatePath, 'utf-8');\n // Only enrich built-in issue-assistant with event/permission context\n if (sanitizedSchema === 'issue-assistant') {\n enrichAssistantContext = true;\n }\n }\n\n // Prepare template data\n // Filter out system-level issues (fail_if conditions, internal errors) which should not appear in output\n const filteredIssues = (reviewSummary.issues || []).filter(\n issue => !(issue.file === 'system' && issue.line === 0)\n );\n\n const templateData: Record<string, unknown> = {\n issues: filteredIssues,\n checkName: checkName,\n // Expose structured output for custom schemas/templates (e.g., overview)\n // This allows templates to render fields like output.text or output.tags\n output: (reviewSummary as unknown as { output?: unknown }).output,\n };\n\n if (enrichAssistantContext) {\n // Provide minimal event and permission context for the assistant template only\n let authorAssociation: string | undefined;\n let eventName = 'manual';\n let eventAction: string | undefined;\n try {\n const anyInfo = _prInfo as unknown as { eventContext?: any; authorAssociation?: string };\n authorAssociation = resolveAssociationFromEvent(\n anyInfo?.eventContext,\n anyInfo?.authorAssociation\n );\n eventName = anyInfo?.eventContext?.event_name || (anyInfo as any)?.eventType || 'manual';\n eventAction = anyInfo?.eventContext?.action;\n } catch {}\n templateData.authorAssociation = authorAssociation;\n templateData.event = { name: eventName, action: eventAction };\n }\n\n // Establish permissions context for filters so templates can call permission filters\n // without passing authorAssociation explicitly.\n const { withPermissionsContext } = (await import('./liquid-extensions')) as unknown as {\n withPermissionsContext?: (\n ctx: { authorAssociation?: string },\n fn: () => Promise<string>\n ) => Promise<string>;\n };\n // Try to derive author association from PR info (commenter preferred)\n let authorAssociationForFilters: string | undefined;\n try {\n const anyInfo = _prInfo as unknown as { eventContext?: any; authorAssociation?: string };\n authorAssociationForFilters = resolveAssociationFromEvent(\n anyInfo?.eventContext,\n anyInfo?.authorAssociation\n );\n } catch {}\n\n let rendered: string;\n if (typeof withPermissionsContext === 'function') {\n rendered = await withPermissionsContext(\n { authorAssociation: authorAssociationForFilters },\n async () => await liquid.parseAndRender(templateContent, templateData)\n );\n if (rendered === undefined || rendered === null) {\n // Defensive: some test environments mock the helper without implementation\n rendered = await liquid.parseAndRender(templateContent, templateData);\n }\n } else {\n rendered = await liquid.parseAndRender(templateContent, templateData);\n }\n const finalRendered = rendered.trim();\n try {\n const { emitMermaidFromMarkdown } = await import('./utils/mermaid-telemetry');\n emitMermaidFromMarkdown(checkName, finalRendered, 'content');\n } catch {}\n return finalRendered;\n }\n\n /**\n * Attempt to elevate an issue/issue_comment context to full PR context when routing via goto_event.\n * Returns a new PRInfo with files/diff when possible; otherwise returns null.\n */\n private async elevateContextToPullRequest(\n prInfo: PRInfo,\n targetEvent: import('./types/config').EventTrigger,\n log?: (msg: string) => void,\n debug?: boolean\n ): Promise<PRInfo | null> {\n try {\n // Only elevate for PR-style events\n if (targetEvent !== 'pr_opened' && targetEvent !== 'pr_updated') return null;\n\n // Only meaningful to elevate from issue contexts\n const isIssueContext = (prInfo as PRInfo & { isIssue?: boolean }).isIssue === true;\n const ctx: any = (prInfo as any).eventContext || {};\n const isPRThread = Boolean(ctx?.issue?.pull_request);\n if (!isIssueContext || !isPRThread) return null;\n\n // Resolve owner/repo from cached action context or environment\n let owner = this.actionContext?.owner;\n let repo = this.actionContext?.repo;\n if (!owner || !repo) {\n const repoEnv = process.env.GITHUB_REPOSITORY || '';\n [owner, repo] = repoEnv.split('/') as [string, string];\n }\n if (!owner || !repo) return null;\n\n // Determine PR number from event context or prInfo.number\n const prNumber = (ctx?.issue?.number as number) || prInfo.number;\n if (!prNumber) return null;\n\n // Build Octokit; prefer cached instance\n let octokit = this.actionContext?.octokit;\n if (!octokit) {\n const token = process.env['INPUT_GITHUB-TOKEN'] || process.env['GITHUB_TOKEN'];\n if (!token) return null;\n const { Octokit } = await import('@octokit/rest');\n octokit = new Octokit({ auth: token });\n }\n\n // Fetch full PR diff\n const analyzer = new PRAnalyzer(octokit);\n const elevated = await analyzer.fetchPRDiff(owner, repo, prNumber, undefined, targetEvent);\n // Preserve event context and helpful flags\n (elevated as any).eventContext = (prInfo as any).eventContext || ctx;\n (elevated as any).isPRContext = true;\n (elevated as any).includeCodeContext = true;\n if (debug)\n log?.(`🔧 Debug: Elevated context to PR #${prNumber} for goto_event=${targetEvent}`);\n return elevated;\n } catch (e) {\n if (debug) {\n const msg = e instanceof Error ? e.message : String(e);\n log?.(`⚠️ Debug: Context elevation to PR failed: ${msg}`);\n }\n return null;\n }\n }\n\n /**\n * Execute multiple checks with dependency awareness - intelligently parallel and sequential\n */\n private async executeDependencyAwareChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n logFn?: (message: string) => void,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean\n ): Promise<ReviewSummary> {\n const log = logFn || console.error;\n\n if (debug) {\n log(`🔧 Debug: Starting dependency-aware execution of ${checks.length} checks`);\n }\n\n if (!config?.checks) {\n throw new Error('Config with check definitions required for dependency-aware execution');\n }\n\n // Determine effective max parallelism (CLI > config > default)\n const effectiveMaxParallelism = maxParallelism ?? config.max_parallelism ?? 3;\n // Determine effective fail-fast setting (CLI > config > default)\n const effectiveFailFast = failFast ?? config.fail_fast ?? false;\n\n if (debug) {\n log(`🔧 Debug: Using max parallelism: ${effectiveMaxParallelism}`);\n log(`🔧 Debug: Using fail-fast: ${effectiveFailFast}`);\n }\n\n // Build dependency graph and check for session reuse requirements\n const dependencies: Record<string, string[]> = {};\n const sessionReuseChecks = new Set<string>();\n const sessionProviders = new Map<string, string>(); // checkName -> parent session provider\n\n for (const checkName of checks) {\n const checkConfig = config.checks[checkName];\n if (checkConfig) {\n dependencies[checkName] = checkConfig.depends_on || [];\n\n // Track checks that need session reuse\n if (checkConfig.reuse_ai_session) {\n sessionReuseChecks.add(checkName);\n\n // Determine the session provider check name\n if (typeof checkConfig.reuse_ai_session === 'string') {\n // Explicit check name provided\n sessionProviders.set(checkName, checkConfig.reuse_ai_session);\n } else if (checkConfig.reuse_ai_session === true) {\n // Use first dependency as fallback\n if (checkConfig.depends_on && checkConfig.depends_on.length > 0) {\n sessionProviders.set(checkName, checkConfig.depends_on[0]);\n }\n }\n }\n } else {\n dependencies[checkName] = [];\n }\n }\n\n if (sessionReuseChecks.size > 0 && debug) {\n log(\n `🔄 Debug: Found ${sessionReuseChecks.size} checks requiring session reuse: ${Array.from(sessionReuseChecks).join(', ')}`\n );\n }\n\n // Validate dependencies for the initially requested checks first\n const validation = DependencyResolver.validateDependencies(checks, dependencies);\n if (!validation.valid) {\n return {\n issues: [\n {\n severity: 'error' as const,\n message: `Dependency validation failed: ${validation.errors.join(', ')}`,\n file: '',\n line: 0,\n ruleId: 'dependency-validation-error',\n category: 'logic' as const,\n },\n ],\n };\n }\n\n // Expand requested checks with transitive dependencies present in config for execution\n const expandWithTransitives = (rootChecks: string[]): string[] => {\n if (!config?.checks) return rootChecks;\n const set = new Set<string>(rootChecks);\n const visit = (name: string) => {\n const cfg = config.checks[name];\n if (!cfg || !cfg.depends_on) return;\n for (const dep of cfg.depends_on) {\n if (!set.has(dep)) {\n set.add(dep);\n visit(dep);\n }\n }\n };\n for (const c of rootChecks) visit(c);\n return Array.from(set);\n };\n\n checks = expandWithTransitives(checks);\n\n // Rebuild dependencies map for the expanded set\n for (const checkName of checks) {\n const checkConfig = config.checks[checkName];\n dependencies[checkName] = checkConfig?.depends_on || [];\n }\n\n // Build dependency graph\n const dependencyGraph = DependencyResolver.buildDependencyGraph(dependencies);\n\n if (dependencyGraph.hasCycles) {\n return {\n issues: [\n {\n severity: 'error' as const,\n message: `Circular dependencies detected: ${dependencyGraph.cycleNodes?.join(' -> ')}`,\n file: '',\n line: 0,\n ruleId: 'circular-dependency-error',\n category: 'logic' as const,\n },\n ],\n };\n }\n\n // Build children-by-parent mapping for inline branch-first execution\n const childrenByParent = new Map<string, string[]>();\n for (const [child, depsArr] of Object.entries(dependencies)) {\n for (const p of depsArr || []) {\n if (!childrenByParent.has(p)) childrenByParent.set(p, []);\n childrenByParent.get(p)!.push(child);\n }\n }\n\n // Log execution plan\n const stats = DependencyResolver.getExecutionStats(dependencyGraph);\n if (debug) {\n log(\n `🔧 Debug: Execution plan - ${stats.totalChecks} checks in ${stats.parallelLevels} levels, max parallelism: ${stats.maxParallelism}`\n );\n }\n\n // Execute checks level by level\n const results = new Map<string, ReviewSummary>();\n const sessionRegistry = require('./session-registry').SessionRegistry.getInstance();\n // Note: We'll get the provider dynamically per check, not a single one for all\n const sessionIds = new Map<string, string>(); // checkName -> sessionId\n let shouldStopExecution = false;\n let completedChecksCount = 0;\n const totalChecksCount = stats.totalChecks;\n\n // Initialize execution statistics for all checks\n for (const checkName of checks) {\n this.initializeCheckStats(checkName);\n }\n\n for (\n let levelIndex = 0;\n levelIndex < dependencyGraph.executionOrder.length && !shouldStopExecution;\n levelIndex++\n ) {\n const executionGroup = dependencyGraph.executionOrder[levelIndex];\n\n // Check if any checks in this level require session reuse - if so, force sequential execution\n const checksInLevel = executionGroup.parallel;\n const hasSessionReuseInLevel = checksInLevel.some(checkName =>\n sessionReuseChecks.has(checkName)\n );\n\n let actualParallelism = Math.min(effectiveMaxParallelism, executionGroup.parallel.length);\n if (hasSessionReuseInLevel) {\n // Force sequential execution when session reuse is involved\n actualParallelism = 1;\n if (debug) {\n log(\n `🔄 Debug: Level ${executionGroup.level} contains session reuse checks - forcing sequential execution (parallelism: 1)`\n );\n }\n }\n\n if (debug) {\n log(\n `🔧 Debug: Executing level ${executionGroup.level} with ${executionGroup.parallel.length} checks (parallelism: ${actualParallelism})`\n );\n }\n\n // Create task functions for checks in this level, skip those already completed inline\n const levelChecks = executionGroup.parallel.filter(name => !results.has(name));\n const levelTaskFunctions = levelChecks.map(checkName => async () => {\n // Skip if this check was already completed by item-level branch scheduler\n if (results.has(checkName)) {\n if (debug) log(`🔧 Debug: Skipping ${checkName} (already satisfied earlier)`);\n return { checkName, error: null, result: results.get(checkName)! };\n }\n const checkConfig = config.checks[checkName];\n if (!checkConfig) {\n return {\n checkName,\n error: `No configuration found for check: ${checkName}`,\n result: null,\n };\n }\n\n // (no early gating; rely on per-item scheduler after parents run)\n\n const checkStartTime = Date.now();\n completedChecksCount++;\n logger.step(`Running check: ${checkName} [${completedChecksCount}/${totalChecksCount}]`);\n\n try {\n if (debug) {\n log(`🔧 Debug: Starting check: ${checkName} at level ${executionGroup.level}`);\n }\n\n // Get the appropriate provider for this check type\n const providerType = checkConfig.type || 'ai';\n const provider = this.providerRegistry.getProviderOrThrow(providerType);\n if (debug) {\n log(`🔧 Debug: Provider for '${checkName}' is '${providerType}'`);\n }\n this.setProviderWebhookContext(provider);\n\n // Create provider config for this specific check\n const extendedCheckConfig = checkConfig as CheckConfig & {\n level?: string;\n message?: string;\n };\n\n const providerConfig: CheckProviderConfig = {\n type: providerType,\n prompt: checkConfig.prompt,\n exec: checkConfig.exec,\n focus: checkConfig.focus || this.mapCheckNameToFocus(checkName),\n schema: checkConfig.schema,\n group: checkConfig.group,\n checkName: checkName, // Add checkName for sessionID\n eventContext: this.enrichEventContext(prInfo.eventContext),\n transform: checkConfig.transform,\n transform_js: checkConfig.transform_js,\n // Important: pass through provider-level timeout from check config\n // (e.g., command/http_client providers expect seconds/ms here)\n timeout: checkConfig.timeout,\n level: extendedCheckConfig.level,\n message: extendedCheckConfig.message,\n env: checkConfig.env,\n forEach: checkConfig.forEach,\n // Pass through any provider-specific keys (e.g., op/values for github provider)\n ...checkConfig,\n ai: {\n ...(checkConfig.ai || {}),\n timeout: timeout || 600000,\n debug: debug,\n },\n };\n\n // Pass results from ALL transitive dependencies (not just direct ones)\n // This ensures the \"outputs\" variable has access to all ancestor check results\n const dependencyResults = new Map<string, ReviewSummary>();\n let isForEachDependent = false;\n let forEachItems: unknown[] = [];\n let forEachParentName: string | undefined;\n const forEachParents: string[] = []; // Track ALL forEach parents\n\n // Get all transitive dependencies (ancestors) for this check\n const allDependencies = DependencyResolver.getAllDependencies(\n checkName,\n dependencyGraph.nodes\n );\n\n // Include results from ALL dependencies (direct and transitive)\n for (const depId of allDependencies) {\n if (results.has(depId)) {\n const depResult = results.get(depId)!;\n dependencyResults.set(depId, depResult);\n }\n }\n\n // If any direct dependency failed or was skipped, skip this check\n const directDeps = checkConfig.depends_on || [];\n const failedDeps: string[] = [];\n for (const depId of directDeps) {\n const depRes = results.get(depId);\n if (!depRes) continue;\n\n // Check if dependency was skipped\n const wasSkipped = (depRes.issues || []).some(issue => {\n const id = issue.ruleId || '';\n return id.endsWith('/__skipped');\n });\n\n // If dependency is a forEach parent, do NOT apply global fatal gating here.\n // We'll gate per-item inside the forEach loop to avoid stopping other branches.\n const depExtended = depRes as ExtendedReviewSummary;\n const isDepForEachParent = !!depExtended.isForEach;\n\n // Treat these as fatal in direct dependencies (non-forEach only):\n // - command provider execution/transform failures\n // - forEach validation/iteration errors\n // - fail_if conditions (global or check-specific)\n // For non-forEach parents, only provider-fatal or fail_if/global_fail_if should gate.\n let hasFatalFailure = false;\n if (!isDepForEachParent) {\n const issues = depRes.issues || [];\n hasFatalFailure = issues.some(issue => {\n const id = issue.ruleId || '';\n return (\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output') ||\n id.endsWith('/forEach/iteration_error') ||\n id.endsWith('_fail_if') ||\n id.endsWith('/global_fail_if')\n );\n });\n // As a fallback, evaluate fail_if on the dependency result now\n if (!hasFatalFailure && config && (config.fail_if || config.checks[depId]?.fail_if)) {\n try {\n hasFatalFailure = await this.failIfTriggered(depId, depRes, config);\n } catch {}\n }\n }\n\n if (debug) {\n log(\n `🔧 Debug: gating check '${checkName}' against dep '${depId}': wasSkipped=${wasSkipped} hasFatalFailure=${hasFatalFailure}`\n );\n }\n if (wasSkipped || hasFatalFailure) failedDeps.push(depId);\n }\n\n if (failedDeps.length > 0) {\n // Record skip and provide a concise console message\n this.recordSkip(checkName, 'dependency_failed');\n logger.info(`⏭ Skipped (dependency failed: ${failedDeps.join(', ')})`);\n return {\n checkName,\n error: null,\n result: { issues: [] },\n skipped: true,\n };\n }\n\n // Check direct dependencies for forEach behavior\n for (const depId of checkConfig.depends_on || []) {\n if (results.has(depId)) {\n const depResult = results.get(depId)!;\n\n // Check if this dependency has forEach enabled\n const depForEachResult = depResult as ExtendedReviewSummary;\n\n if (\n depForEachResult.isForEach ||\n Array.isArray(depForEachResult.forEachItemResults) ||\n Array.isArray(depForEachResult.forEachItems)\n ) {\n if (!isForEachDependent) {\n // First forEach dependency found - use it as the primary\n isForEachDependent = true;\n forEachItems = Array.isArray(depForEachResult.forEachItems)\n ? depForEachResult.forEachItems!\n : new Array(\n Array.isArray(depForEachResult.forEachItemResults)\n ? depForEachResult.forEachItemResults!.length\n : 0\n ).fill(undefined);\n forEachParentName = depId;\n }\n // Track all forEach parents for unwrapping\n forEachParents.push(depId);\n }\n }\n }\n\n // Determine if we should use session reuse\n let sessionInfo: { parentSessionId?: string; reuseSession?: boolean } | undefined =\n undefined;\n if (sessionReuseChecks.has(checkName)) {\n const parentCheckName = sessionProviders.get(checkName);\n if (parentCheckName && sessionIds.has(parentCheckName)) {\n const parentSessionId = sessionIds.get(parentCheckName)!;\n\n sessionInfo = {\n parentSessionId: parentSessionId,\n reuseSession: true,\n };\n\n if (debug) {\n log(\n `🔄 Debug: Check ${checkName} will reuse session from parent ${parentCheckName}: ${parentSessionId}`\n );\n }\n } else {\n if (debug) {\n log(\n `⚠️ Warning: Check ${checkName} requires session reuse but parent ${parentCheckName} session not found`\n );\n }\n }\n }\n\n // For checks that create new sessions, generate a session ID\n let currentSessionId: string | undefined = undefined;\n if (!sessionInfo?.reuseSession) {\n const timestamp = new Date().toISOString();\n currentSessionId = `visor-${timestamp.replace(/[:.]/g, '-')}-${checkName}`;\n sessionIds.set(checkName, currentSessionId);\n if (debug) {\n log(`🆕 Debug: Check ${checkName} will create new session: ${currentSessionId}`);\n }\n\n // Add session ID to provider config\n providerConfig.sessionId = currentSessionId;\n }\n\n // Handle forEach dependent execution\n let finalResult: ReviewSummary;\n\n if (isForEachDependent && forEachParentName) {\n if (!Array.isArray(forEachItems)) {\n forEachItems = [];\n }\n if (!Array.isArray(forEachItems)) {\n this.recordSkip(checkName, 'dependency_failed');\n return {\n checkName,\n error: null,\n result: { issues: [] },\n skipped: true,\n };\n }\n // Record forEach preview items\n this.recordForEachPreview(checkName, forEachItems);\n\n // If the forEach parent returned an empty array, skip this check entirely\n if (forEachItems.length === 0) {\n if (debug) {\n log(\n `🔄 Debug: Skipping check \"${checkName}\" - forEach check \"${forEachParentName}\" returned 0 items`\n );\n }\n logger.info(` forEach: no items from \"${forEachParentName}\", skipping check...`);\n this.recordSkip(checkName, 'dependency_failed');\n\n // Return a special marker result so that dependent checks can detect the skip\n finalResult = {\n issues: [],\n output: [],\n } as ReviewSummary;\n\n // Mark this result as forEach-capable but with empty items\n (finalResult as ExtendedReviewSummary).isForEach = true;\n (finalResult as ExtendedReviewSummary).forEachItems = [];\n\n // Skip to the end - don't execute this check\n } else {\n // Emit explicit debug to stdout so CLI e2e can assert it\n if (debug) {\n console.log(\n `🔄 Debug: Check \"${checkName}\" depends on forEach check \"${forEachParentName}\", executing ${forEachItems.length} times`\n );\n }\n\n // Log forEach processing start (non-debug)\n const __itemCount = Array.isArray(forEachItems) ? forEachItems.length : 0;\n logger.info(\n ` forEach: processing ${__itemCount} items from \"${forEachParentName}\"...`\n );\n\n const allIssues: ReviewIssue[] = [];\n const allOutputs: unknown[] = new Array(forEachItems.length);\n const aggregatedContents: string[] = [];\n const perItemResults: Array<ReviewSummary | undefined> = new Array(\n forEachItems.length\n );\n\n // Aggregators for inline descendant execution (branch-first mode for simple chains)\n const inlineAgg = new Map<\n string,\n {\n issues: ReviewIssue[];\n outputs: unknown[];\n contents: string[];\n perItemResults: ReviewSummary[];\n }\n >();\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const execInlineDescendants = async (\n parentName: string,\n itemIndex: number,\n baseDeps: Map<string, ReviewSummary>\n ): Promise<void> => {\n const children = (childrenByParent.get(parentName) || []).filter(child => {\n const deps = dependencies[child] || [];\n // Only handle simple chains inline: exactly one dependency which is the parent\n return deps.length === 1 && deps[0] === parentName;\n });\n\n for (const childName of children) {\n const childCfg = config.checks[childName];\n const childProviderType = childCfg.type || 'ai';\n const childProv = this.providerRegistry.getProviderOrThrow(childProviderType);\n this.setProviderWebhookContext(childProv);\n const childProviderConfig: CheckProviderConfig = {\n type: childProviderType,\n prompt: childCfg.prompt,\n exec: childCfg.exec,\n focus: childCfg.focus || this.mapCheckNameToFocus(childName),\n schema: childCfg.schema,\n group: childCfg.group,\n checkName: childName,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n transform: childCfg.transform,\n transform_js: childCfg.transform_js,\n env: childCfg.env,\n forEach: childCfg.forEach,\n // Include provider-specific keys like op/values for non-AI providers\n ...childCfg,\n ai: {\n ...(childCfg.ai || {}),\n timeout: timeout || 600000,\n debug: debug,\n },\n };\n try {\n emitNdjsonSpanWithEvents('visor.check', { 'visor.check.id': checkName }, [\n { name: 'check.started' },\n { name: 'check.completed' },\n ]);\n } catch {}\n\n // Build per-item dependency results for child, including transitive ancestors\n const childDepResults = new Map<string, ReviewSummary>();\n const childAllDeps = DependencyResolver.getAllDependencies(\n childName,\n dependencyGraph.nodes\n );\n for (const dep of childAllDeps) {\n const baseRes = baseDeps.get(dep);\n if (baseRes) {\n childDepResults.set(dep, baseRes);\n continue;\n }\n const globalRes = results.get(dep) as ExtendedReviewSummary | undefined;\n if (!globalRes) continue;\n if (\n globalRes &&\n (globalRes.isForEach ||\n Array.isArray(globalRes.forEachItemResults) ||\n Array.isArray((globalRes as any).output))\n ) {\n // Prefer precise per-item result when available\n if (\n Array.isArray(globalRes.forEachItemResults) &&\n globalRes.forEachItemResults[itemIndex]\n ) {\n childDepResults.set(dep, globalRes.forEachItemResults[itemIndex]!);\n } else if (\n Array.isArray((globalRes as any).output) &&\n (globalRes as any).output[itemIndex] !== undefined\n ) {\n childDepResults.set(dep, {\n issues: [],\n output: (globalRes as any).output[itemIndex],\n } as ReviewSummary);\n } else {\n childDepResults.set(dep, globalRes);\n }\n } else {\n childDepResults.set(dep, globalRes);\n }\n }\n\n // If the parent item had a fatal failure, skip this child for this branch\n const parentItemRes = childDepResults.get(parentName);\n if (parentItemRes) {\n // Skip when parent explicitly signaled error in its output for this item\n try {\n const pout: any = (parentItemRes as any).output;\n if (pout && typeof pout === 'object' && pout.error === true) {\n continue;\n }\n } catch {}\n\n const fatal = (parentItemRes.issues || []).some(issue => {\n const id = issue.ruleId || '';\n const sev = issue.severity || 'error';\n return (\n sev === 'error' ||\n sev === 'critical' ||\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id.endsWith('/forEach/iteration_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output') ||\n id.endsWith('_fail_if') ||\n id.endsWith('/global_fail_if')\n );\n });\n if (fatal) {\n continue;\n }\n }\n\n // Evaluate per-item if condition\n if (childCfg.if) {\n const condResults = new Map(results);\n for (const [k, v] of childDepResults) condResults.set(k, v);\n const shouldRunChild = await this.evaluateCheckCondition(\n childName,\n childCfg.if,\n prInfo,\n condResults,\n debug\n );\n if (!shouldRunChild) {\n continue;\n }\n }\n\n // Execute child for this item (record stats)\n const childIterStart = this.recordIterationStart(childName);\n const childItemRes = await this.executeWithRouting(\n childName,\n childCfg,\n childProv,\n childProviderConfig,\n prInfo,\n childDepResults,\n sessionInfo,\n config,\n dependencyGraph,\n debug,\n results,\n { index: itemIndex, total: forEachItems.length, parent: parentName }\n );\n\n // Per-item fail_if\n if (config && (config.fail_if || childCfg.fail_if)) {\n const fRes = await this.evaluateFailureConditions(\n childName,\n childItemRes,\n config\n );\n if (fRes.length > 0) {\n const fIssues = fRes\n .filter(f => f.failed)\n .map(f => ({\n file: 'system',\n line: 0,\n ruleId: f.conditionName,\n message: f.message || `Failure condition met: ${f.expression}`,\n severity: (f.severity || 'error') as\n | 'info'\n | 'warning'\n | 'error'\n | 'critical',\n category: 'logic' as const,\n }));\n childItemRes.issues = [...(childItemRes.issues || []), ...fIssues];\n }\n }\n\n if (!inlineAgg.has(childName)) {\n inlineAgg.set(childName, {\n issues: [],\n outputs: new Array(forEachItems.length),\n contents: [],\n perItemResults: new Array(forEachItems.length),\n });\n }\n const agg = inlineAgg.get(childName)!;\n if (childItemRes.issues) agg.issues.push(...childItemRes.issues);\n const out = (childItemRes as any).output;\n agg.outputs[itemIndex] = out;\n agg.perItemResults[itemIndex] = childItemRes;\n const c = (childItemRes as any).content;\n if (typeof c === 'string' && c.trim()) agg.contents.push(c.trim());\n\n // Record iteration completion for stats\n const childHadFatal = this.hasFatal(childItemRes.issues || []);\n this.recordIterationComplete(\n childName,\n childIterStart,\n !childHadFatal,\n childItemRes.issues || [],\n (childItemRes as any).output\n );\n\n // Recurse further for simple chains\n const nextBase = new Map(baseDeps);\n nextBase.set(childName, childItemRes);\n await execInlineDescendants(childName, itemIndex, nextBase);\n }\n };\n\n // Create task functions (not executed yet) - these will be executed with controlled concurrency\n // via executeWithLimitedParallelism to respect maxParallelism setting\n const itemTasks = forEachItems.map((item, itemIndex) => async () => {\n try {\n emitNdjsonSpanWithEvents(\n 'visor.foreach.item',\n {\n 'visor.check.id': checkName,\n 'visor.foreach.index': itemIndex,\n 'visor.foreach.total': forEachItems.length,\n },\n []\n );\n } catch {}\n // Create modified dependency results with current item\n // For forEach branching: unwrap ALL forEach parents to create isolated execution branch\n const forEachDependencyResults = new Map<string, ReviewSummary>();\n for (const [depName, depResult] of dependencyResults) {\n if (forEachParents.includes(depName)) {\n // This is a forEach parent - unwrap its output for this iteration\n const depForEachResult = depResult as ReviewSummary & {\n output?: unknown;\n forEachItems?: unknown[];\n forEachItemResults?: ReviewSummary[];\n };\n\n if (\n Array.isArray(depForEachResult.forEachItemResults) &&\n depForEachResult.forEachItemResults[itemIndex]\n ) {\n // Use precise per-item result (includes issues + output)\n forEachDependencyResults.set(\n depName,\n depForEachResult.forEachItemResults[itemIndex]!\n );\n // Also provide -raw access to the full array\n const rawResult: ReviewSummary & { output?: unknown } = {\n issues: [],\n output: depForEachResult.output,\n };\n forEachDependencyResults.set(`${depName}-raw`, rawResult);\n } else if (\n Array.isArray(depForEachResult.output) &&\n (depForEachResult as any).output[itemIndex] !== undefined\n ) {\n // Fallback to output-only unwrapping\n const modifiedResult: ReviewSummary & { output?: unknown } = {\n issues: [],\n output: (depForEachResult as any).output[itemIndex],\n };\n\n forEachDependencyResults.set(depName, modifiedResult);\n const rawResult: ReviewSummary & { output?: unknown } = {\n issues: [],\n output: depForEachResult.output,\n };\n forEachDependencyResults.set(`${depName}-raw`, rawResult);\n } else {\n // Fallback: use the result as-is\n forEachDependencyResults.set(depName, depResult);\n }\n } else {\n forEachDependencyResults.set(depName, depResult);\n }\n }\n\n // Per-item dependency gating for forEach parents: if a dependency failed for this item, skip this iteration\n if ((checkConfig.depends_on || []).length > 0) {\n const directDeps = checkConfig.depends_on || [];\n for (const depId of directDeps) {\n if (!forEachParents.includes(depId)) continue;\n const depItemRes = forEachDependencyResults.get(depId);\n if (!depItemRes) continue;\n const wasSkippedDep = (depItemRes.issues || []).some(i =>\n (i.ruleId || '').endsWith('/__skipped')\n );\n let hasFatalDepFailure = (depItemRes.issues || []).some(issue => {\n const id = issue.ruleId || '';\n return (\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id.endsWith('/forEach/iteration_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output') ||\n id.endsWith('_fail_if') ||\n id.endsWith('/global_fail_if')\n );\n });\n if (\n !hasFatalDepFailure &&\n config &&\n (config.fail_if || config.checks[depId]?.fail_if)\n ) {\n try {\n const depFailures = await this.evaluateFailureConditions(\n depId,\n depItemRes,\n config\n );\n hasFatalDepFailure = depFailures.some(f => f.failed);\n } catch {}\n }\n const depAgg = dependencyResults.get(depId) as\n | ExtendedReviewSummary\n | undefined;\n const maskFatal =\n !!depAgg?.forEachFatalMask && depAgg!.forEachFatalMask![itemIndex] === true;\n if (wasSkippedDep || hasFatalDepFailure || maskFatal) {\n if (debug) {\n log(\n `🔄 Debug: Skipping item ${itemIndex + 1}/${forEachItems.length} for check \"${checkName}\" due to failed dependency '${depId}'`\n );\n }\n return {\n index: itemIndex,\n itemResult: { issues: [] } as ReviewSummary,\n skipped: true,\n };\n }\n }\n }\n\n // Evaluate if condition for this forEach item\n if (checkConfig.if) {\n // Merge current results with forEach-specific dependency results for condition evaluation\n const conditionResults = new Map(results);\n for (const [depName, depResult] of forEachDependencyResults) {\n conditionResults.set(depName, depResult);\n }\n\n const shouldRun = await this.evaluateCheckCondition(\n checkName,\n checkConfig.if,\n prInfo,\n conditionResults,\n debug\n );\n\n if (!shouldRun) {\n if (debug) {\n log(\n `🔄 Debug: Skipping forEach item ${itemIndex + 1} for check \"${checkName}\" (if condition evaluated to false)`\n );\n }\n // Return empty result for skipped items\n return {\n index: itemIndex,\n itemResult: { issues: [] } as ReviewSummary,\n skipped: true,\n };\n }\n }\n\n if (debug) {\n log(\n `🔄 Debug: Executing check \"${checkName}\" for item ${itemIndex + 1}/${forEachItems.length}`\n );\n }\n\n // Track iteration start\n const iterationStart = this.recordIterationStart(checkName);\n\n // Execute with retry/routing semantics per item\n const itemResult = await this.executeWithRouting(\n checkName,\n checkConfig,\n provider,\n providerConfig,\n prInfo,\n forEachDependencyResults,\n sessionInfo,\n config,\n dependencyGraph,\n debug,\n results,\n /*foreachContext*/ {\n index: itemIndex,\n total: forEachItems.length,\n parent: forEachParentName,\n }\n );\n // no-op\n\n // Evaluate fail_if per item so a single failing branch does not stop others\n if (config && (config.fail_if || checkConfig.fail_if)) {\n const itemFailures = await this.evaluateFailureConditions(\n checkName,\n itemResult,\n config\n );\n if (itemFailures.length > 0) {\n const failureIssues = itemFailures\n .filter(f => f.failed)\n .map(f => ({\n file: 'system',\n line: 0,\n ruleId: f.conditionName,\n message: f.message || `Failure condition met: ${f.expression}`,\n severity: (f.severity || 'error') as\n | 'info'\n | 'warning'\n | 'error'\n | 'critical',\n category: 'logic' as const,\n }));\n itemResult.issues = [...(itemResult.issues || []), ...failureIssues];\n }\n }\n\n // Record iteration completion\n // Check if this iteration had fatal errors\n const hadFatalError = (itemResult.issues || []).some(issue => {\n const id = issue.ruleId || '';\n return (\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output')\n );\n });\n const iterationDuration = (Date.now() - iterationStart) / 1000;\n this.recordIterationComplete(\n checkName,\n iterationStart,\n !hadFatalError, // Success if no fatal errors\n itemResult.issues || [],\n (itemResult as any).output\n );\n\n // Track output history for forEach iterations\n const itemOutput = (itemResult as any).output;\n if (itemOutput !== undefined) {\n this.trackOutputHistory(checkName, itemOutput);\n }\n\n // General branch-first scheduling for this item: execute all descendants (from current node only) when ready\n const descendantSet = (() => {\n const visited = new Set<string>();\n const stack = [checkName];\n while (stack.length) {\n const p = stack.pop()!;\n const kids = childrenByParent.get(p) || [];\n for (const k of kids) {\n if (!visited.has(k)) {\n visited.add(k);\n stack.push(k);\n }\n }\n }\n return visited;\n })();\n\n const perItemDone = new Set<string>([...forEachParents, checkName]);\n const perItemDepMap = new Map<string, ReviewSummary>();\n for (const [k, v] of forEachDependencyResults) perItemDepMap.set(k, v);\n perItemDepMap.set(checkName, itemResult);\n\n const isFatal = (r: ReviewSummary | undefined): boolean => {\n if (!r) return true;\n return this.hasFatal(r.issues || []);\n };\n\n while (true) {\n let progressed = false;\n for (const node of descendantSet) {\n if (perItemDone.has(node)) continue;\n const nodeCfg = config.checks[node];\n if (!nodeCfg) continue;\n const deps = dependencies[node] || [];\n\n // Are all deps satisfied for this item?\n let ready = true;\n const childDepsMap = new Map<string, ReviewSummary>();\n for (const d of deps) {\n // Prefer per-item result if already computed in this branch\n const perItemRes = perItemDepMap.get(d);\n if (perItemRes) {\n if (isFatal(perItemRes)) {\n ready = false;\n break;\n }\n childDepsMap.set(d, perItemRes);\n continue;\n }\n\n const agg = results.get(d) as ExtendedReviewSummary | undefined;\n // If dependency is a forEach-capable result, require per-item unwrap\n if (agg && (agg.isForEach || Array.isArray(agg.forEachItemResults))) {\n const r =\n (agg.forEachItemResults && agg.forEachItemResults[itemIndex]) ||\n undefined;\n const maskFatal =\n !!agg.forEachFatalMask && agg.forEachFatalMask[itemIndex] === true;\n if (!r || maskFatal || isFatal(r)) {\n ready = false;\n break;\n }\n childDepsMap.set(d, r);\n continue;\n }\n\n // Fallback: use global dependency result (non-forEach)\n if (!agg || isFatal(agg)) {\n ready = false;\n break;\n }\n childDepsMap.set(d, agg);\n }\n if (!ready) continue;\n\n // if condition per item\n if (nodeCfg.if) {\n const condResults = new Map(results);\n for (const [k, v] of childDepsMap) condResults.set(k, v);\n const shouldRun = await this.evaluateCheckCondition(\n node,\n nodeCfg.if,\n prInfo,\n condResults,\n debug\n );\n if (!shouldRun) {\n perItemDone.add(node);\n progressed = true;\n continue;\n }\n }\n\n // Execute node for this item\n const nodeProvType = nodeCfg.type || 'ai';\n const nodeProv = this.providerRegistry.getProviderOrThrow(nodeProvType);\n this.setProviderWebhookContext(nodeProv);\n const nodeProviderConfig: CheckProviderConfig = {\n type: nodeProvType,\n prompt: nodeCfg.prompt,\n exec: nodeCfg.exec,\n focus: nodeCfg.focus || this.mapCheckNameToFocus(node),\n schema: nodeCfg.schema,\n group: nodeCfg.group,\n checkName: node,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n transform: nodeCfg.transform,\n transform_js: nodeCfg.transform_js,\n env: nodeCfg.env,\n forEach: nodeCfg.forEach,\n ai: { timeout: timeout || 600000, debug: debug, ...(nodeCfg.ai || {}) },\n };\n\n const iterStart = this.recordIterationStart(node);\n // Expand dependency map for execution context to include transitive ancestors\n const execDepMap = new Map<string, ReviewSummary>(childDepsMap);\n const nodeAllDeps = DependencyResolver.getAllDependencies(\n node,\n dependencyGraph.nodes\n );\n for (const dep of nodeAllDeps) {\n if (execDepMap.has(dep)) continue;\n // Prefer per-item map first\n const perItemRes = perItemDepMap.get(dep);\n if (perItemRes) {\n execDepMap.set(dep, perItemRes);\n continue;\n }\n const agg = results.get(dep) as ExtendedReviewSummary | undefined;\n if (!agg) continue;\n if (\n agg &&\n (agg.isForEach ||\n Array.isArray(agg.forEachItemResults) ||\n Array.isArray((agg as any).output))\n ) {\n if (\n Array.isArray(agg.forEachItemResults) &&\n agg.forEachItemResults[itemIndex]\n ) {\n execDepMap.set(dep, agg.forEachItemResults[itemIndex]!);\n } else if (\n Array.isArray((agg as any).output) &&\n (agg as any).output[itemIndex] !== undefined\n ) {\n execDepMap.set(dep, {\n issues: [],\n output: (agg as any).output[itemIndex],\n } as ReviewSummary);\n } else {\n execDepMap.set(dep, agg);\n }\n } else {\n execDepMap.set(dep, agg);\n }\n }\n\n const nodeItemRes = await this.executeWithRouting(\n node,\n nodeCfg,\n nodeProv,\n nodeProviderConfig,\n prInfo,\n execDepMap,\n sessionInfo,\n config,\n dependencyGraph,\n debug,\n results,\n { index: itemIndex, total: forEachItems.length, parent: forEachParentName }\n );\n\n if (config && (config.fail_if || nodeCfg.fail_if)) {\n const fRes = await this.evaluateFailureConditions(node, nodeItemRes, config);\n if (fRes.length > 0) {\n const fIssues = fRes\n .filter(f => f.failed)\n .map(f => ({\n file: 'system',\n line: 0,\n ruleId: f.conditionName,\n message: f.message || `Failure condition met: ${f.expression}`,\n severity: (f.severity || 'error') as\n | 'info'\n | 'warning'\n | 'error'\n | 'critical',\n category: 'logic' as const,\n }));\n nodeItemRes.issues = [...(nodeItemRes.issues || []), ...fIssues];\n }\n }\n\n const hadFatal = isFatal(nodeItemRes);\n this.recordIterationComplete(\n node,\n iterStart,\n !hadFatal,\n nodeItemRes.issues || [],\n (nodeItemRes as any).output\n );\n\n // Aggregate results for this node across items\n if (!inlineAgg.has(node))\n inlineAgg.set(node, {\n issues: [],\n outputs: [],\n contents: [],\n perItemResults: [],\n });\n const agg = inlineAgg.get(node)!;\n if (nodeItemRes.issues) agg.issues.push(...nodeItemRes.issues);\n const nout = (nodeItemRes as any).output;\n if (nout !== undefined) agg.outputs.push(nout);\n agg.perItemResults.push(nodeItemRes);\n const ncontent = (nodeItemRes as any).content;\n if (typeof ncontent === 'string' && ncontent.trim())\n agg.contents.push(ncontent.trim());\n\n perItemDepMap.set(node, nodeItemRes);\n perItemDone.add(node);\n progressed = true;\n }\n if (!progressed) break;\n }\n\n // Log iteration progress\n logger.info(\n ` ✔ ${itemIndex + 1}/${forEachItems.length} (${iterationDuration.toFixed(1)}s)`\n );\n\n perItemResults[itemIndex] = itemResult;\n return { index: itemIndex, itemResult };\n });\n\n // Determine runnable indices by intersecting masks across all direct forEach parents\n const directForEachParents = (checkConfig.depends_on || []).filter(dep => {\n const r = results.get(dep) as ExtendedReviewSummary | undefined;\n return (\n !!r &&\n (r.isForEach ||\n Array.isArray(r.forEachItemResults) ||\n Array.isArray(r.forEachItems))\n );\n });\n if (directForEachParents.length > 0) {\n logger.debug(\n ` forEach: direct parents for \"${checkName}\": ${directForEachParents.join(', ')}`\n );\n }\n\n const isIndexFatalForParent = async (\n parent: string,\n idx: number\n ): Promise<boolean> => {\n const agg = results.get(parent) as ExtendedReviewSummary | undefined;\n if (!agg) return false; // if missing, do not gate\n if (agg.forEachFatalMask && agg.forEachFatalMask[idx] === true) return true;\n const r = (agg.forEachItemResults && agg.forEachItemResults[idx]) || undefined;\n if (!r) return false;\n // 1) Issues-based fatality (provider/transform/timeout/fail_if markers)\n const hadFatalByIssues = this.hasFatal(r.issues || []);\n if (hadFatalByIssues) return true;\n // 2) Fail_if based fatality evaluated directly on the parent per-item result\n try {\n if (config && (config.fail_if || config.checks[parent]?.fail_if)) {\n // If output is a string, try parsing JSON (full or tail) to honor fail_if semantics\n let rForEval: ReviewSummary = r;\n const rawOut = (r as any)?.output;\n if (typeof rawOut === 'string') {\n const parseTail = (text: string): unknown | null => {\n try {\n const lines = text.split('\\n');\n for (let i = lines.length - 1; i >= 0; i--) {\n const t = lines[i].trim();\n if (t.startsWith('{') || t.startsWith('[')) {\n const candidate = lines.slice(i).join('\\n').trim();\n if (\n (candidate.startsWith('{') && candidate.endsWith('}')) ||\n (candidate.startsWith('[') && candidate.endsWith(']'))\n ) {\n return JSON.parse(candidate);\n }\n }\n }\n } catch {}\n try {\n return JSON.parse(text);\n } catch {\n return null;\n }\n };\n const parsed = parseTail(rawOut);\n if (parsed && typeof parsed === 'object') {\n rForEval = { ...r, output: parsed } as ReviewSummary & { output?: unknown };\n }\n }\n const failures = await this.evaluateFailureConditions(parent, rForEval, config);\n if (failures.some(f => f.failed)) {\n // Temporary: surface why index is gated\n }\n if (failures.some(f => f.failed)) return true;\n }\n } catch {}\n return false;\n };\n\n const runnableIndices: number[] = [];\n for (let idx = 0; idx < forEachItems.length; idx++) {\n let ok = true;\n for (const p of directForEachParents) {\n if (await isIndexFatalForParent(p, idx)) {\n ok = false;\n break;\n }\n }\n // Only schedule indices that have a corresponding task function\n if (ok && typeof itemTasks[idx] === 'function') runnableIndices.push(idx);\n }\n\n // no-op\n // Early skip if no runnable items after intersecting masks across all direct forEach parents\n if (runnableIndices.length === 0) {\n this.recordSkip(checkName, 'dependency_failed');\n logger.info(`⏭ Skipped (dependency failed: no runnable items)`);\n return {\n checkName,\n error: null,\n result: { issues: [] },\n skipped: true,\n };\n }\n\n const forEachConcurrency = Math.max(\n 1,\n Math.min(runnableIndices.length, effectiveMaxParallelism)\n );\n\n if (debug && forEachConcurrency > 1) {\n log(\n `🔄 Debug: Limiting forEach concurrency for check \"${checkName}\" to ${forEachConcurrency}`\n );\n }\n\n const scheduledTasks = runnableIndices\n .map(i => itemTasks[i])\n .filter(fn => typeof fn === 'function');\n const forEachResults = await this.executeWithLimitedParallelism(\n scheduledTasks,\n forEachConcurrency,\n false\n );\n\n let processedCount = 0;\n for (const result of forEachResults) {\n if (result.status === 'rejected') {\n // Instead of throwing, record the failure and continue with other iterations\n const error = result.reason;\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Create an error issue for this failed iteration\n allIssues.push({\n ruleId: `${checkName}/forEach/iteration_error`,\n severity: 'error',\n category: 'logic',\n message: `forEach iteration failed: ${errorMessage}`,\n file: '',\n line: 0,\n });\n\n if (debug) {\n log(\n `🔄 Debug: forEach iteration for check \"${checkName}\" failed: ${errorMessage}`\n );\n }\n continue;\n }\n\n // Skip results from skipped items (those gated by dependencies/if)\n if ((result.value as any).skipped) {\n continue;\n }\n\n const { index: finishedIndex, itemResult } = result.value as any;\n processedCount++;\n\n if (itemResult.issues) {\n allIssues.push(...itemResult.issues);\n }\n\n const resultWithOutput = itemResult as ReviewSummary & {\n output?: unknown;\n content?: string;\n };\n\n allOutputs[finishedIndex] = resultWithOutput.output;\n\n const itemContent = resultWithOutput.content;\n if (typeof itemContent === 'string' && itemContent.trim()) {\n aggregatedContents.push(itemContent.trim());\n } else {\n const outStr =\n typeof resultWithOutput.output === 'string'\n ? (resultWithOutput.output as string).trim()\n : '';\n if (outStr) aggregatedContents.push(outStr);\n }\n }\n\n // If no items were processed (all gated), mark this check as skipped for dependency_failed\n if (processedCount === 0) {\n this.recordSkip(checkName, 'dependency_failed');\n logger.info(`⏭ Skipped (dependency failed for all items)`);\n return {\n checkName,\n error: null,\n result: { issues: [] },\n skipped: true,\n };\n }\n\n const finalOutput = allOutputs.length > 0 ? allOutputs : undefined;\n\n finalResult = {\n issues: allIssues,\n ...(finalOutput !== undefined ? { output: finalOutput } : {}),\n } as ExtendedReviewSummary;\n\n // Mark this result as forEach-capable and attach per-item results for precise downstream gating\n (finalResult as ExtendedReviewSummary).isForEach = true;\n (finalResult as ExtendedReviewSummary).forEachItems = allOutputs;\n (finalResult as ExtendedReviewSummary).forEachItemResults =\n perItemResults as ReviewSummary[];\n // Compute fatal mask\n try {\n const mask: boolean[] = (finalResult as ExtendedReviewSummary).forEachItemResults\n ? await Promise.all(\n Array.from({ length: forEachItems.length }, async (_, idx) => {\n const r = (finalResult as ExtendedReviewSummary).forEachItemResults![idx];\n if (!r) return false; // no result (skipped) → not fatal for descendants\n let hadFatal = this.hasFatal(r.issues || []);\n try {\n const ids = (r.issues || []).map(i => i.ruleId).join(',');\n logger.debug(\n ` forEach: item ${idx + 1}/${forEachItems.length} issues=${(r.issues || []).length} ids=[${ids}]`\n );\n } catch {}\n if (!hadFatal && config && (config.fail_if || checkConfig.fail_if)) {\n try {\n const failures = await this.evaluateFailureConditions(\n checkName,\n r,\n config\n );\n hadFatal = failures.some(f => f.failed);\n } catch {}\n }\n return hadFatal;\n })\n )\n : [];\n (finalResult as ExtendedReviewSummary).forEachFatalMask = mask;\n logger.debug(\n ` forEach: mask for \"${checkName}\" → fatals=${mask.filter(Boolean).length}/${mask.length}`\n );\n } catch {}\n\n if (aggregatedContents.length > 0) {\n (finalResult as ReviewSummary & { content?: string }).content =\n aggregatedContents.join('\\n');\n }\n\n // Finalize inline descendant aggregations to full results, so later levels skip them\n for (const [childName, agg] of inlineAgg.entries()) {\n const childCfg = config.checks[childName];\n const childEnrichedIssues = (agg.issues || []).map(issue => ({\n ...issue,\n checkName: childName,\n ruleId: `${childName}/${issue.ruleId}`,\n group: childCfg.group,\n schema: typeof childCfg.schema === 'object' ? 'custom' : childCfg.schema,\n template: childCfg.template,\n timestamp: Date.now(),\n }));\n const childFinal: ExtendedReviewSummary = {\n issues: childEnrichedIssues,\n ...(agg.outputs.length > 0 ? { output: agg.outputs } : {}),\n isForEach: true,\n forEachItems: agg.outputs,\n forEachItemResults: agg.perItemResults,\n ...(agg.contents.length > 0 ? { content: agg.contents.join('\\n') } : {}),\n };\n // Compute fatal mask for child aggregate\n try {\n const mask: boolean[] = Array.from(\n { length: agg.perItemResults.length },\n (_, idx) => {\n const r = agg.perItemResults[idx];\n if (!r) return false; // skipped item is not fatal for descendants\n const hadFatal = (r.issues || []).some(issue => {\n const id = issue.ruleId || '';\n return (\n issue.severity === 'error' ||\n issue.severity === 'critical' ||\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id.endsWith('/forEach/iteration_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output') ||\n id.endsWith('_fail_if') ||\n id.endsWith('/global_fail_if')\n );\n });\n return hadFatal;\n }\n );\n childFinal.forEachFatalMask = mask;\n } catch {}\n results.set(childName, childFinal);\n }\n\n if (\n debug &&\n process.env.VISOR_OUTPUT_FORMAT !== 'json' &&\n process.env.VISOR_OUTPUT_FORMAT !== 'sarif'\n ) {\n console.log(\n `🔄 Debug: Completed forEach execution for check \"${checkName}\", total issues: ${allIssues.length}`\n );\n }\n } // End of else block for forEachItems.length > 0\n } else {\n // Normal single execution\n // Evaluate if condition for non-forEach-dependent checks\n if (checkConfig.if) {\n const shouldRun = await this.evaluateCheckCondition(\n checkName,\n checkConfig.if,\n prInfo,\n results,\n debug\n );\n\n if (!shouldRun) {\n // Record skip with condition\n this.recordSkip(checkName, 'if_condition', checkConfig.if);\n logger.info(`⏭ Skipped (if: ${this.truncate(checkConfig.if, 40)})`);\n return {\n checkName,\n error: null,\n result: {\n issues: [],\n },\n skipped: true,\n };\n }\n }\n\n // Execute with retry/routing semantics\n finalResult = await this.executeWithRouting(\n checkName,\n checkConfig,\n provider,\n providerConfig,\n prInfo,\n dependencyResults,\n sessionInfo,\n config,\n dependencyGraph,\n debug,\n results\n );\n try {\n emitNdjsonSpanWithEvents('visor.check', { 'visor.check.id': checkName }, [\n { name: 'check.started' },\n { name: 'check.completed' },\n ]);\n } catch {}\n\n // Evaluate fail_if for normal (non-forEach) execution\n if (config && (config.fail_if || checkConfig.fail_if)) {\n const failureResults = await this.evaluateFailureConditions(\n checkName,\n finalResult,\n config\n );\n if (failureResults.length > 0) {\n const failureIssues = failureResults\n .filter(f => f.failed)\n .map(f => ({\n file: 'system',\n line: 0,\n ruleId: f.conditionName,\n message: f.message || `Failure condition met: ${f.expression}`,\n severity: (f.severity || 'error') as 'info' | 'warning' | 'error' | 'critical',\n category: 'logic' as const,\n }));\n finalResult.issues = [...(finalResult.issues || []), ...failureIssues];\n }\n }\n\n // Record normal (non-forEach) execution\n // Check if this check had fatal errors\n const hadFatalError = (finalResult.issues || []).some(issue => {\n const id = issue.ruleId || '';\n return (\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output')\n );\n });\n this.recordIterationComplete(\n checkName,\n checkStartTime,\n !hadFatalError, // Success if no fatal errors\n finalResult.issues || [],\n (finalResult as any).output\n );\n\n if (checkConfig.forEach) {\n try {\n const finalResultWithOutput = finalResult as ExtendedReviewSummary;\n const outputPreview =\n JSON.stringify(finalResultWithOutput.output)?.slice(0, 200) || '(empty)';\n logger.debug(`🔧 Debug: Check \"${checkName}\" provider returned: ${outputPreview}`);\n } catch {\n // Ignore logging errors\n }\n }\n\n if (debug) {\n log(\n `🔧 Debug: Completed check: ${checkName}, issues found: ${(finalResult.issues || []).length}`\n );\n }\n\n // Track cloned session IDs for cleanup\n if (finalResult.sessionId) {\n sessionIds.set(checkName, finalResult.sessionId);\n if (debug) {\n log(`🔧 Debug: Tracked cloned session for cleanup: ${finalResult.sessionId}`);\n }\n }\n }\n\n // Add checkName, group, schema, template info and timestamp to issues from config\n const enrichedIssues = (finalResult.issues || []).map(issue => ({\n ...issue,\n checkName: checkName,\n ruleId: `${checkName}/${issue.ruleId}`,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n template: checkConfig.template,\n timestamp: Date.now(),\n }));\n\n const enrichedResult = {\n ...finalResult,\n issues: enrichedIssues,\n };\n\n const checkDuration = ((Date.now() - checkStartTime) / 1000).toFixed(1);\n const issueCount = enrichedIssues.length;\n const checkStats = this.executionStats.get(checkName);\n\n // Enhanced completion message with forEach stats\n if (checkStats && checkStats.totalRuns > 1) {\n if (issueCount > 0) {\n logger.success(\n `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs, ${issueCount} issue${issueCount === 1 ? '' : 's'}`\n );\n } else {\n logger.success(\n `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.totalRuns} runs`\n );\n }\n } else if (checkStats && checkStats.outputsProduced && checkStats.outputsProduced > 0) {\n logger.success(\n `Check complete: ${checkName} (${checkDuration}s) - ${checkStats.outputsProduced} items`\n );\n } else if (issueCount > 0) {\n logger.success(\n `Check complete: ${checkName} (${checkDuration}s) - ${issueCount} issue${issueCount === 1 ? '' : 's'} found`\n );\n } else {\n logger.success(`Check complete: ${checkName} (${checkDuration}s)`);\n }\n\n return {\n checkName,\n error: null,\n result: enrichedResult,\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? `${error.message}\\n${error.stack || ''}` : String(error);\n const checkDuration = ((Date.now() - checkStartTime) / 1000).toFixed(1);\n\n // Record error in stats\n this.recordError(checkName, error instanceof Error ? error : new Error(String(error)));\n this.recordIterationComplete(checkName, checkStartTime, false, [], undefined);\n\n logger.error(`✖ Check failed: ${checkName} (${checkDuration}s) - ${errorMessage}`);\n\n if (debug) {\n log(`🔧 Debug: Error in check ${checkName}: ${errorMessage}`);\n }\n\n return {\n checkName,\n error: errorMessage,\n result: null,\n };\n }\n });\n\n // Execute checks in this level with controlled parallelism\n const levelResults = await this.executeWithLimitedParallelism(\n levelTaskFunctions,\n actualParallelism,\n effectiveFailFast\n );\n\n // Process results and store them for next level\n const levelChecksList = executionGroup.parallel.filter(name => !results.has(name));\n for (let i = 0; i < levelResults.length; i++) {\n const checkName = levelChecksList[i];\n const result = levelResults[i];\n const checkConfig = config.checks[checkName];\n\n if (result.status === 'fulfilled' && result.value.result && !result.value.error) {\n // For skipped checks, store a marker so dependent checks can detect the skip\n if ((result.value as any).skipped) {\n if (debug) {\n log(`🔧 Debug: Storing skip marker for skipped check \"${checkName}\"`);\n }\n // Store a special marker result with a skip issue so dependencies can detect it\n results.set(checkName, {\n issues: [\n {\n ruleId: `${checkName}/__skipped`,\n severity: 'info',\n category: 'logic',\n message: 'Check was skipped',\n file: '',\n line: 0,\n },\n ],\n });\n continue;\n }\n\n const reviewResult = result.value.result;\n\n // Handle forEach logic - process array outputs\n const reviewSummaryWithOutput = reviewResult as ExtendedReviewSummary;\n\n if (checkConfig?.forEach && (!reviewResult.issues || reviewResult.issues.length === 0)) {\n const validation = this.validateAndNormalizeForEachOutput(\n checkName,\n reviewSummaryWithOutput.output,\n checkConfig.group\n );\n\n if (!validation.isValid) {\n results.set(\n checkName,\n validation.error.issues ? { issues: validation.error.issues } : {}\n );\n continue;\n }\n\n const normalizedOutput = validation.normalizedOutput;\n\n logger.debug(\n `🔧 Debug: Raw output for forEach check ${checkName}: ${\n Array.isArray(reviewSummaryWithOutput.output)\n ? `array(${reviewSummaryWithOutput.output.length})`\n : typeof reviewSummaryWithOutput.output\n }`\n );\n\n try {\n const preview = JSON.stringify(normalizedOutput);\n logger.debug(\n `🔧 Debug: Check \"${checkName}\" forEach output: ${preview?.slice(0, 200) || '(empty)'}`\n );\n } catch {\n // Ignore logging errors\n }\n\n // Store the array for iteration by dependent checks\n reviewSummaryWithOutput.forEachItems = normalizedOutput;\n reviewSummaryWithOutput.isForEach = true;\n }\n\n try {\n emitNdjsonSpanWithEvents('visor.check', { 'visor.check.id': checkName }, [\n { name: 'check.started' },\n { name: 'check.completed' },\n ]);\n } catch {}\n\n // Track output history for loop/goto scenarios\n const reviewResultWithOutput = reviewResult as ReviewSummary & { output?: unknown };\n if (reviewResultWithOutput.output !== undefined) {\n this.trackOutputHistory(checkName, reviewResultWithOutput.output);\n }\n\n results.set(checkName, reviewResult);\n } else {\n // Store error result for dependency tracking\n const errorSummary: ReviewSummary = {\n issues: [\n {\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: `${checkName}/error`,\n message:\n result.status === 'fulfilled'\n ? result.value.error || 'Unknown error'\n : result.reason instanceof Error\n ? result.reason.message\n : String(result.reason),\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n };\n results.set(checkName, errorSummary);\n\n // Check if we should stop execution due to fail-fast\n if (effectiveFailFast) {\n if (debug) {\n log(`🛑 Check \"${checkName}\" failed and fail-fast is enabled - stopping execution`);\n }\n shouldStopExecution = true;\n break;\n }\n }\n }\n\n // If fail-fast is enabled, check if any successful checks have failure conditions\n if (effectiveFailFast && !shouldStopExecution) {\n for (let i = 0; i < levelResults.length; i++) {\n const checkName = executionGroup.parallel[i];\n const result = levelResults[i];\n\n if (result.status === 'fulfilled' && result.value.result && !result.value.error) {\n // Check for issues that should trigger fail-fast\n const hasFailuresToReport = (result.value.result.issues || []).some(\n issue => issue.severity === 'error' || issue.severity === 'critical'\n );\n\n if (hasFailuresToReport) {\n if (debug) {\n log(\n `🛑 Check \"${checkName}\" found critical/high issues and fail-fast is enabled - stopping execution`\n );\n }\n shouldStopExecution = true;\n break;\n }\n }\n }\n }\n }\n\n if (debug) {\n if (shouldStopExecution) {\n log(\n `🛑 Execution stopped early due to fail-fast after processing ${results.size} of ${checks.length} checks`\n );\n } else {\n log(`✅ Dependency-aware execution completed successfully for all ${results.size} checks`);\n }\n }\n\n // Cleanup sessions BEFORE printing summary to avoid mixing debug logs with table output\n if (sessionIds.size > 0 && debug) {\n log(`🧹 Cleaning up ${sessionIds.size} AI sessions...`);\n for (const [checkName, sessionId] of sessionIds) {\n try {\n sessionRegistry.unregisterSession(sessionId);\n log(`🗑️ Cleaned up session for check ${checkName}: ${sessionId}`);\n } catch (error) {\n log(`⚠️ Failed to cleanup session for check ${checkName}: ${error}`);\n }\n }\n }\n\n // Build and log final execution summary\n const executionStatistics = this.buildExecutionStatistics();\n\n // Show detailed summary table (only if logFn outputs to console)\n // Skip when output format is JSON/SARIF to avoid polluting structured output\n // Check if logFn is console.log (not a no-op or console.error)\n if (logFn === console.log) {\n this.logExecutionSummary(executionStatistics);\n }\n\n // Add warning if execution stopped early\n if (shouldStopExecution) {\n logger.info('');\n logger.warn(`⚠️ Execution stopped early due to fail-fast`);\n }\n\n // Aggregate all results\n return this.aggregateDependencyAwareResults(\n results,\n dependencyGraph,\n debug,\n shouldStopExecution\n );\n }\n\n /**\n * Execute multiple checks in parallel using controlled parallelism (legacy method)\n */\n private async executeParallelChecks(\n prInfo: PRInfo,\n checks: string[],\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n logFn?: (message: string) => void,\n debug?: boolean,\n maxParallelism?: number,\n failFast?: boolean\n ): Promise<ReviewSummary> {\n const log = logFn || console.error;\n log(`🔧 Debug: Starting parallel execution of ${checks.length} checks`);\n\n if (!config?.checks) {\n throw new Error('Config with check definitions required for parallel execution');\n }\n\n // Determine effective max parallelism (CLI > config > default)\n const effectiveMaxParallelism = maxParallelism ?? config.max_parallelism ?? 3;\n // Determine effective fail-fast setting (CLI > config > default)\n const effectiveFailFast = failFast ?? config.fail_fast ?? false;\n log(`🔧 Debug: Using max parallelism: ${effectiveMaxParallelism}`);\n log(`🔧 Debug: Using fail-fast: ${effectiveFailFast}`);\n\n const provider = this.providerRegistry.getProviderOrThrow('ai');\n this.setProviderWebhookContext(provider);\n\n // Create individual check task functions\n const checkTaskFunctions = checks.map(checkName => async () => {\n const checkConfig = config.checks[checkName];\n if (!checkConfig) {\n log(`🔧 Debug: No config found for check: ${checkName}`);\n return {\n checkName,\n error: `No configuration found for check: ${checkName}`,\n result: null,\n };\n }\n\n try {\n console.error(\n `🔧 Debug: Starting check: ${checkName} with prompt type: ${typeof checkConfig.prompt}`\n );\n\n // Evaluate if condition to determine whether to run this check\n if (checkConfig.if) {\n // Evaluate if condition using any routing override event (e.g., goto_event)\n const override = this.routingEventOverride;\n const eventName = override\n ? override.startsWith('pr_')\n ? 'pull_request'\n : override === 'issue_comment'\n ? 'issue_comment'\n : override.startsWith('issue_')\n ? 'issues'\n : 'manual'\n : 'issue_comment';\n const commenterAssoc = resolveAssociationFromEvent(\n (prInfo as any)?.eventContext,\n prInfo.authorAssociation\n );\n const shouldRun = await this.failureEvaluator.evaluateIfCondition(\n checkName,\n checkConfig.if,\n {\n branch: prInfo.head,\n baseBranch: prInfo.base,\n filesChanged: prInfo.files.map(f => f.filename),\n event: eventName, // honor routing override if present\n environment: getSafeEnvironmentVariables(),\n previousResults: new Map(), // No previous results in parallel execution\n authorAssociation: commenterAssoc,\n }\n );\n\n if (!shouldRun) {\n console.error(\n `🔧 Debug: Skipping check '${checkName}' - if condition evaluated to false`\n );\n return {\n checkName,\n error: null,\n result: {\n issues: [],\n },\n };\n }\n }\n\n // Create provider config for this specific check\n const providerConfig: CheckProviderConfig = {\n type: 'ai',\n prompt: checkConfig.prompt,\n focus: checkConfig.focus || this.mapCheckNameToFocus(checkName),\n schema: checkConfig.schema,\n group: checkConfig.group,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n ai: {\n timeout: timeout || 600000,\n debug: debug, // Pass debug flag to AI provider\n ...(checkConfig.ai || {}),\n },\n };\n\n const result = await provider.execute(prInfo, providerConfig);\n console.error(\n `🔧 Debug: Completed check: ${checkName}, issues found: ${(result.issues || []).length}`\n );\n\n // Add group, schema info and timestamp to issues from config\n const enrichedIssues = (result.issues || []).map(issue => ({\n ...issue,\n ruleId: `${checkName}/${issue.ruleId}`,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n template: checkConfig.template,\n timestamp: Date.now(),\n }));\n\n const enrichedResult = {\n ...result,\n issues: enrichedIssues,\n };\n\n return {\n checkName,\n error: null,\n result: enrichedResult,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log(`🔧 Debug: Error in check ${checkName}: ${errorMessage}`);\n\n return {\n checkName,\n error: errorMessage,\n result: null,\n };\n }\n });\n\n // Execute all checks with controlled parallelism\n log(\n `🔧 Debug: Executing ${checkTaskFunctions.length} checks with max parallelism: ${effectiveMaxParallelism}`\n );\n const results = await this.executeWithLimitedParallelism(\n checkTaskFunctions,\n effectiveMaxParallelism,\n effectiveFailFast\n );\n\n // Check if execution was stopped early\n const completedChecks = results.filter(\n r => r.status === 'fulfilled' || r.status === 'rejected'\n ).length;\n const stoppedEarly = completedChecks < checks.length;\n\n if (stoppedEarly && effectiveFailFast) {\n log(\n `🛑 Parallel execution stopped early due to fail-fast after processing ${completedChecks} of ${checks.length} checks`\n );\n } else {\n log(`✅ Parallel execution completed for all ${completedChecks} checks`);\n }\n\n // Aggregate results from all checks\n return this.aggregateParallelResults(results, checks, debug, stoppedEarly);\n }\n\n /**\n * Execute a single configured check\n */\n private async executeSingleConfiguredCheck(\n prInfo: PRInfo,\n checkName: string,\n timeout?: number,\n config?: import('./types/config').VisorConfig,\n _logFn?: (message: string) => void\n ): Promise<ReviewSummary> {\n if (!config?.checks?.[checkName]) {\n throw new Error(`No configuration found for check: ${checkName}`);\n }\n\n const checkConfig = config.checks[checkName];\n const provider = this.providerRegistry.getProviderOrThrow('ai');\n this.setProviderWebhookContext(provider);\n\n const providerConfig: CheckProviderConfig = {\n type: 'ai',\n prompt: checkConfig.prompt,\n focus: checkConfig.focus || this.mapCheckNameToFocus(checkName),\n schema: checkConfig.schema,\n group: checkConfig.group,\n eventContext: this.enrichEventContext(prInfo.eventContext),\n ai: {\n timeout: timeout || 600000,\n ...(checkConfig.ai || {}),\n },\n // Inherit global AI provider and model settings\n ai_provider: checkConfig.ai_provider || config.ai_provider,\n ai_model: checkConfig.ai_model || config.ai_model,\n };\n\n const result = await provider.execute(prInfo, providerConfig);\n\n // Prefix issues with check name and add group/schema info and timestamp from config\n const prefixedIssues = (result.issues || []).map(issue => ({\n ...issue,\n ruleId: `${checkName}/${issue.ruleId}`,\n group: checkConfig.group,\n schema: typeof checkConfig.schema === 'object' ? 'custom' : checkConfig.schema,\n timestamp: Date.now(),\n }));\n\n return {\n ...result,\n issues: prefixedIssues,\n };\n }\n\n /**\n * Map check name to focus for AI provider\n * This is a fallback when focus is not explicitly configured\n */\n private mapCheckNameToFocus(checkName: string): string {\n const focusMap: Record<string, string> = {\n security: 'security',\n performance: 'performance',\n style: 'style',\n architecture: 'architecture',\n };\n\n return focusMap[checkName] || 'all';\n }\n\n /**\n * Aggregate results from dependency-aware check execution\n */\n private aggregateDependencyAwareResults(\n results: Map<string, ReviewSummary>,\n dependencyGraph: DependencyGraph,\n debug?: boolean,\n stoppedEarly?: boolean\n ): ReviewSummary {\n const aggregatedIssues: ReviewSummary['issues'] = [];\n const debugInfo: string[] = [];\n const contentMap: Record<string, string> = {};\n const outputsMap: Record<string, unknown> = {};\n\n // Add execution plan info\n const stats = DependencyResolver.getExecutionStats(dependencyGraph);\n const executionInfo = [\n stoppedEarly\n ? `🛑 Dependency-aware execution stopped early (fail-fast):`\n : `🔍 Dependency-aware execution completed:`,\n ` - ${results.size} of ${stats.totalChecks} checks processed`,\n ` - Execution levels: ${stats.parallelLevels}`,\n ` - Maximum parallelism: ${stats.maxParallelism}`,\n ` - Average parallelism: ${stats.averageParallelism.toFixed(1)}`,\n ` - Checks with dependencies: ${stats.checksWithDependencies}`,\n stoppedEarly ? ` - Stopped early due to fail-fast behavior` : ``,\n ].filter(Boolean);\n\n debugInfo.push(...executionInfo);\n\n // Track which checks we've aggregated already\n const processed = new Set<string>();\n\n // Process results in dependency order for better output organization\n for (const executionGroup of dependencyGraph.executionOrder) {\n for (const checkName of executionGroup.parallel) {\n const result = results.get(checkName);\n\n if (!result) {\n debugInfo.push(`❌ Check \"${checkName}\" had no result`);\n continue;\n }\n\n // Check if this was a successful result\n const hasErrors = (result.issues || []).some(\n issue => issue.ruleId?.includes('/error') || issue.ruleId?.includes('/promise-error')\n );\n\n if (hasErrors) {\n debugInfo.push(`❌ Check \"${checkName}\" failed with errors`);\n } else {\n debugInfo.push(\n `✅ Check \"${checkName}\" completed: ${(result.issues || []).length} issues found (level ${executionGroup.level})`\n );\n }\n\n // Mark as processed\n processed.add(checkName);\n\n // Issues are already prefixed and enriched with group/schema info\n // Filter out internal __skipped markers\n const nonInternalIssues = (result.issues || []).filter(\n issue => !issue.ruleId?.endsWith('/__skipped')\n );\n aggregatedIssues.push(...nonInternalIssues);\n\n const resultSummary = result as ExtendedReviewSummary & { output?: unknown };\n const resultContent = resultSummary.content;\n if (typeof resultContent === 'string' && resultContent.trim()) {\n contentMap[checkName] = resultContent.trim();\n }\n if (resultSummary.output !== undefined) {\n outputsMap[checkName] = resultSummary.output;\n }\n }\n }\n\n // Include any additional results that were produced at runtime (e.g., forward-run via goto)\n // but were not part of the original execution DAG for the selected checks.\n for (const [checkName, result] of results.entries()) {\n if (processed.has(checkName)) continue;\n if (!result) continue;\n\n // Issues (already enriched)\n const nonInternalIssues = (result.issues || []).filter(\n issue => !issue.ruleId?.endsWith('/__skipped')\n );\n aggregatedIssues.push(...nonInternalIssues);\n\n const resultSummary = result as ExtendedReviewSummary & { output?: unknown };\n const resultContent = (resultSummary as any).content;\n if (typeof resultContent === 'string' && resultContent.trim()) {\n contentMap[checkName] = resultContent.trim();\n }\n if (resultSummary.output !== undefined) {\n outputsMap[checkName] = resultSummary.output;\n }\n\n debugInfo.push(\n `✅ (dynamic) Check \"${checkName}\" included: ${(result.issues || []).length} issues found`\n );\n }\n\n if (debug) {\n console.error(\n `🔧 Debug: Aggregated ${aggregatedIssues.length} issues from ${results.size} dependency-aware checks`\n );\n }\n\n // Apply issue suppression filtering\n const suppressionEnabled = this.config?.output?.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(aggregatedIssues, this.workingDirectory);\n\n // Collect debug information when debug mode is enabled\n let aggregatedDebug: import('./ai-review-service').AIDebugInfo | undefined;\n if (debug) {\n const debugResults = Array.from(results.entries()).filter(([_, result]) => result.debug);\n\n if (debugResults.length > 0) {\n const [, firstResult] = debugResults[0];\n const firstDebug = firstResult.debug!;\n\n const totalProcessingTime = debugResults.reduce((sum, [_, result]) => {\n return sum + (result.debug!.processingTime || 0);\n }, 0);\n\n aggregatedDebug = {\n provider: firstDebug.provider,\n model: firstDebug.model,\n apiKeySource: firstDebug.apiKeySource,\n processingTime: totalProcessingTime,\n prompt: debugResults\n .map(([checkName, result]) => `[${checkName}]\\n${result.debug!.prompt}`)\n .join('\\n\\n'),\n rawResponse: debugResults\n .map(([checkName, result]) => `[${checkName}]\\n${result.debug!.rawResponse}`)\n .join('\\n\\n'),\n promptLength: debugResults.reduce(\n (sum, [_, result]) => sum + (result.debug!.promptLength || 0),\n 0\n ),\n responseLength: debugResults.reduce(\n (sum, [_, result]) => sum + (result.debug!.responseLength || 0),\n 0\n ),\n jsonParseSuccess: debugResults.every(([_, result]) => result.debug!.jsonParseSuccess),\n errors: debugResults.flatMap(([checkName, result]) =>\n (result.debug!.errors || []).map((error: string) => `[${checkName}] ${error}`)\n ),\n timestamp: new Date().toISOString(),\n totalApiCalls: debugResults.length,\n apiCallDetails: debugResults.map(([checkName, result]) => ({\n checkName,\n provider: result.debug!.provider,\n model: result.debug!.model,\n processingTime: result.debug!.processingTime,\n success: result.debug!.jsonParseSuccess,\n })),\n };\n }\n }\n\n const summary: ReviewSummary & {\n __contents?: Record<string, string>;\n __outputs?: Record<string, unknown>;\n __executed?: string[];\n } = {\n issues: filteredIssues,\n debug: aggregatedDebug,\n };\n\n if (Object.keys(contentMap).length > 0) {\n summary.__contents = contentMap;\n }\n if (Object.keys(outputsMap).length > 0) {\n summary.__outputs = outputsMap;\n }\n\n // Preserve the list of executed checks (keys in results Map) so downstream\n // grouping/formatting can include dynamically routed children even when they\n // produced neither issues nor output content (e.g., log-only steps).\n summary.__executed = Array.from(results.keys());\n\n return summary;\n }\n\n /**\n * Aggregate results from parallel check execution (legacy method)\n */\n private aggregateParallelResults(\n results: PromiseSettledResult<{\n checkName: string;\n error: string | null;\n result: ReviewSummary | null;\n }>[],\n checkNames: string[],\n debug?: boolean,\n _stoppedEarly?: boolean\n ): ReviewSummary {\n const aggregatedIssues: ReviewSummary['issues'] = [];\n const debugInfo: string[] = [];\n\n results.forEach((result, index) => {\n const checkName = checkNames[index];\n\n if (result.status === 'fulfilled') {\n const checkResult = result.value;\n\n if (checkResult.error) {\n logger.debug(`🔧 Debug: Check ${checkName} failed: ${checkResult.error}`);\n debugInfo.push(`❌ Check \"${checkName}\" failed: ${checkResult.error}`);\n\n // Check if this is a critical error\n const isCriticalError =\n checkResult.error.includes('API rate limit') ||\n checkResult.error.includes('403') ||\n checkResult.error.includes('401') ||\n checkResult.error.includes('authentication') ||\n checkResult.error.includes('API key');\n\n // Add error as an issue with appropriate severity\n aggregatedIssues.push({\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: `${checkName}/error`,\n message: `Check \"${checkName}\" failed: ${checkResult.error}`,\n severity: isCriticalError ? 'critical' : 'error',\n category: 'logic',\n suggestion: isCriticalError\n ? 'Please check your API credentials and rate limits'\n : undefined,\n replacement: undefined,\n });\n } else if (checkResult.result) {\n logger.debug(\n `🔧 Debug: Check ${checkName} succeeded with ${(checkResult.result.issues || []).length} issues`\n );\n debugInfo.push(\n `✅ Check \"${checkName}\" completed: ${(checkResult.result.issues || []).length} issues found`\n );\n\n // Issues are already prefixed and enriched with group/schema info\n aggregatedIssues.push(...(checkResult.result.issues || []));\n }\n } else {\n const errorMessage =\n result.reason instanceof Error ? result.reason.message : String(result.reason);\n logger.debug(`🔧 Debug: Check ${checkName} promise rejected: ${errorMessage}`);\n debugInfo.push(`❌ Check \"${checkName}\" promise rejected: ${errorMessage}`);\n\n // Check if this is a critical error\n const isCriticalError =\n errorMessage.includes('API rate limit') ||\n errorMessage.includes('403') ||\n errorMessage.includes('401') ||\n errorMessage.includes('authentication') ||\n errorMessage.includes('API key');\n\n aggregatedIssues.push({\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: `${checkName}/promise-error`,\n message: `Check \"${checkName}\" execution failed: ${errorMessage}`,\n severity: isCriticalError ? 'critical' : 'error',\n category: 'logic',\n suggestion: isCriticalError\n ? 'Please check your API credentials and rate limits'\n : undefined,\n replacement: undefined,\n });\n }\n });\n\n if (debug) {\n console.error(\n `🔧 Debug: Aggregated ${aggregatedIssues.length} issues from ${results.length} checks`\n );\n }\n\n // Apply issue suppression filtering\n const suppressionEnabled = this.config?.output?.suppressionEnabled !== false;\n const issueFilter = new IssueFilter(suppressionEnabled);\n const filteredIssues = issueFilter.filterIssues(aggregatedIssues, this.workingDirectory);\n\n // Collect debug information when debug mode is enabled\n let aggregatedDebug: import('./ai-review-service').AIDebugInfo | undefined;\n if (debug) {\n // Find the first successful result with debug information to use as template\n const debugResults = results\n .map((result, index) => ({\n result,\n checkName: checkNames[index],\n }))\n .filter(({ result }) => result.status === 'fulfilled' && result.value?.result?.debug);\n\n if (debugResults.length > 0) {\n const firstResult = debugResults[0].result;\n if (firstResult.status === 'fulfilled') {\n const firstDebug = firstResult.value!.result!.debug!;\n const totalProcessingTime = debugResults.reduce((sum, { result }) => {\n if (result.status === 'fulfilled') {\n return sum + (result.value!.result!.debug!.processingTime || 0);\n }\n return sum;\n }, 0);\n\n aggregatedDebug = {\n // Use first result as template for provider/model info\n provider: firstDebug.provider,\n model: firstDebug.model,\n apiKeySource: firstDebug.apiKeySource,\n // Aggregate processing time from all checks\n processingTime: totalProcessingTime,\n // Combine prompts with check names\n prompt: debugResults\n .map(({ checkName, result }) => {\n if (result.status === 'fulfilled') {\n return `[${checkName}]\\n${result.value!.result!.debug!.prompt}`;\n }\n return `[${checkName}] Error: Promise was rejected`;\n })\n .join('\\n\\n'),\n // Combine responses\n rawResponse: debugResults\n .map(({ checkName, result }) => {\n if (result.status === 'fulfilled') {\n return `[${checkName}]\\n${result.value!.result!.debug!.rawResponse}`;\n }\n return `[${checkName}] Error: Promise was rejected`;\n })\n .join('\\n\\n'),\n promptLength: debugResults.reduce((sum, { result }) => {\n if (result.status === 'fulfilled') {\n return sum + (result.value!.result!.debug!.promptLength || 0);\n }\n return sum;\n }, 0),\n responseLength: debugResults.reduce((sum, { result }) => {\n if (result.status === 'fulfilled') {\n return sum + (result.value!.result!.debug!.responseLength || 0);\n }\n return sum;\n }, 0),\n jsonParseSuccess: debugResults.every(({ result }) => {\n if (result.status === 'fulfilled') {\n return result.value!.result!.debug!.jsonParseSuccess;\n }\n return false;\n }),\n errors: debugResults.flatMap(({ result, checkName }) => {\n if (result.status === 'fulfilled') {\n return (result.value!.result!.debug!.errors || []).map(\n (error: string) => `[${checkName}] ${error}`\n );\n }\n return [`[${checkName}] Promise was rejected`];\n }),\n timestamp: new Date().toISOString(),\n // Add additional debug information for parallel execution\n totalApiCalls: debugResults.length,\n apiCallDetails: debugResults.map(({ checkName, result }) => {\n if (result.status === 'fulfilled') {\n return {\n checkName,\n provider: result.value!.result!.debug!.provider,\n model: result.value!.result!.debug!.model,\n processingTime: result.value!.result!.debug!.processingTime,\n success: result.value!.result!.debug!.jsonParseSuccess,\n };\n }\n return {\n checkName,\n provider: 'unknown',\n model: 'unknown',\n processingTime: 0,\n success: false,\n };\n }),\n };\n }\n }\n }\n\n return {\n issues: filteredIssues,\n debug: aggregatedDebug,\n };\n }\n\n /**\n * Get available check types\n */\n static getAvailableCheckTypes(): string[] {\n const registry = CheckProviderRegistry.getInstance();\n const providerTypes = registry.getAvailableProviders();\n // Add standard focus-based checks\n const standardTypes = ['security', 'performance', 'style', 'architecture', 'all'];\n // Combine provider types with standard types (remove duplicates)\n return [...new Set([...providerTypes, ...standardTypes])];\n }\n\n /**\n * Validate check types\n */\n static validateCheckTypes(checks: string[]): { valid: string[]; invalid: string[] } {\n const availableChecks = CheckExecutionEngine.getAvailableCheckTypes();\n const valid: string[] = [];\n const invalid: string[] = [];\n\n for (const check of checks) {\n if (availableChecks.includes(check)) {\n valid.push(check);\n } else {\n invalid.push(check);\n }\n }\n\n return { valid, invalid };\n }\n\n /**\n * List available providers with their status\n */\n async listProviders(): Promise<\n Array<{\n name: string;\n description: string;\n available: boolean;\n requirements: string[];\n }>\n > {\n return await this.providerRegistry.listProviders();\n }\n\n /**\n * Create a mock Octokit instance for local analysis\n */\n private createMockOctokit(): MockOctokit {\n // Create simple mock functions that return promises\n const mockGet = async () => ({\n data: {\n number: 0,\n title: 'Local Analysis',\n body: 'Local repository analysis',\n user: { login: 'local-user' },\n base: { ref: 'main' },\n head: { ref: 'HEAD' },\n },\n });\n\n const mockListFiles = async () => ({\n data: [],\n });\n\n const mockListComments = async () => ({\n data: [],\n });\n\n const mockCreateComment = async () => ({\n data: { id: 1 },\n });\n\n return {\n rest: {\n pulls: {\n get: mockGet,\n listFiles: mockListFiles,\n },\n issues: {\n listComments: mockListComments,\n createComment: mockCreateComment,\n },\n },\n request: async () => ({ data: {} }),\n graphql: async () => ({}),\n log: {\n debug: () => {},\n info: () => {},\n warn: () => {},\n error: () => {},\n },\n hook: {\n before: () => {},\n after: () => {},\n error: () => {},\n wrap: () => {},\n },\n auth: async () => ({ token: 'mock-token' }),\n };\n }\n\n /**\n * Create an error result\n */\n private createErrorResult(\n repositoryInfo: GitRepositoryInfo,\n errorMessage: string,\n startTime: number,\n timestamp: string,\n checksExecuted: string[]\n ): AnalysisResult {\n const executionTime = Date.now() - startTime;\n\n return {\n repositoryInfo,\n reviewSummary: {\n issues: [\n {\n file: 'system',\n line: 0,\n endLine: undefined,\n ruleId: 'system/error',\n message: errorMessage,\n severity: 'error',\n category: 'logic',\n suggestion: undefined,\n replacement: undefined,\n },\n ],\n },\n executionTime,\n timestamp,\n checksExecuted,\n };\n }\n\n /**\n * Check if a task result should trigger fail-fast behavior\n */\n private isFailFastCandidate(value: unknown): value is {\n error?: string;\n result?: { issues?: Array<{ severity?: string }> };\n } {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n\n const candidate = value as {\n error?: unknown;\n result?: unknown;\n };\n\n if (candidate.error !== undefined && typeof candidate.error !== 'string') {\n return false;\n }\n\n if (candidate.result !== undefined) {\n if (typeof candidate.result !== 'object' || candidate.result === null) {\n return false;\n }\n\n const issues = (candidate.result as { issues?: unknown }).issues;\n if (issues !== undefined && !Array.isArray(issues)) {\n return false;\n }\n }\n\n return true;\n }\n\n private shouldFailFast(result: unknown): boolean {\n if (!this.isFailFastCandidate(result)) {\n return false;\n }\n\n if (result.error) {\n return true;\n }\n\n // If the result has a result with critical or error issues, it should fail fast\n const issues = result.result?.issues;\n if (Array.isArray(issues)) {\n return issues.some(issue => issue?.severity === 'error' || issue?.severity === 'critical');\n }\n\n return false;\n }\n\n /**\n * Check if the working directory is a valid git repository\n */\n async isGitRepository(): Promise<boolean> {\n try {\n const repositoryInfo = await this.gitAnalyzer.analyzeRepository();\n return repositoryInfo.isGitRepository;\n } catch {\n return false;\n }\n }\n\n /**\n * Evaluate failure conditions for a check result\n */\n async evaluateFailureConditions(\n checkName: string,\n reviewSummary: ReviewSummary,\n config?: import('./types/config').VisorConfig,\n prInfo?: PRInfo\n ): Promise<FailureConditionResult[]> {\n if (!config) {\n return [];\n }\n\n const checkConfig = config.checks[checkName];\n const checkSchema =\n typeof checkConfig?.schema === 'object' ? 'custom' : checkConfig?.schema || '';\n const checkGroup = checkConfig?.group || '';\n\n // Handle new simple fail_if syntax\n const globalFailIf = config.fail_if;\n const checkFailIf = checkConfig?.fail_if;\n\n // If using new fail_if syntax\n if (globalFailIf || checkFailIf) {\n const results: FailureConditionResult[] = [];\n\n // Evaluate global fail_if\n if (globalFailIf) {\n const failed = await this.failureEvaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n globalFailIf\n );\n\n try {\n addEvent('fail_if.evaluated', {\n check: checkName,\n scope: 'global',\n name: 'global_fail_if',\n expression: globalFailIf,\n });\n } catch {}\n if (failed) {\n try {\n addEvent('fail_if.triggered', {\n check: checkName,\n scope: 'global',\n name: 'global_fail_if',\n expression: globalFailIf,\n severity: 'error',\n });\n } catch {}\n try {\n addFailIfTriggered(checkName, 'global');\n } catch {}\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: checkName, scope: 'global', name: 'global_fail_if' },\n [\n {\n name: 'fail_if.triggered',\n attrs: {\n check: checkName,\n scope: 'global',\n name: 'global_fail_if',\n expression: globalFailIf,\n severity: 'error',\n },\n },\n ]\n );\n } catch {}\n logger.warn(`⚠️ Check \"${checkName}\" - global fail_if condition met: ${globalFailIf}`);\n results.push({\n conditionName: 'global_fail_if',\n expression: globalFailIf,\n failed: true,\n severity: 'error',\n message: 'Global failure condition met',\n haltExecution: false,\n });\n } else {\n logger.debug(`✓ Check \"${checkName}\" - global fail_if condition passed`);\n }\n }\n\n // Evaluate check-specific fail_if (overrides global if present)\n if (checkFailIf) {\n const failed = await this.failureEvaluator.evaluateSimpleCondition(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n checkFailIf\n );\n\n try {\n addEvent('fail_if.evaluated', {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression: checkFailIf,\n });\n } catch {}\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: checkName, scope: 'check', name: `${checkName}_fail_if` },\n [\n {\n name: 'fail_if.evaluated',\n attrs: {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression: checkFailIf,\n },\n },\n ]\n );\n } catch {}\n if (failed) {\n try {\n addEvent('fail_if.triggered', {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression: checkFailIf,\n severity: 'error',\n });\n } catch {}\n try {\n addEvent('fail_if.evaluated', {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression: checkFailIf,\n });\n } catch {}\n try {\n addFailIfTriggered(checkName, 'check');\n } catch {}\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n { check: checkName, scope: 'check', name: `${checkName}_fail_if` },\n [\n {\n name: 'fail_if.triggered',\n attrs: {\n check: checkName,\n scope: 'check',\n name: `${checkName}_fail_if`,\n expression: checkFailIf,\n severity: 'error',\n },\n },\n ]\n );\n } catch {}\n logger.warn(`⚠️ Check \"${checkName}\" - fail_if condition met: ${checkFailIf}`);\n results.push({\n conditionName: `${checkName}_fail_if`,\n expression: checkFailIf,\n failed: true,\n severity: 'error',\n message: `Check ${checkName} failure condition met`,\n haltExecution: false,\n });\n } else {\n logger.debug(`✓ Check \"${checkName}\" - fail_if condition passed`);\n }\n }\n\n try {\n const { emitNdjsonSpanWithEvents } = require('./telemetry/fallback-ndjson');\n const hadTriggered = results.some(r => r.failed === true);\n emitNdjsonSpanWithEvents(\n 'visor.fail_if',\n {\n check: checkName,\n scope: hadTriggered\n ? checkFailIf\n ? 'check'\n : 'global'\n : checkFailIf\n ? 'check'\n : 'global',\n },\n [\n {\n name: 'fail_if.evaluated',\n attrs: { check: checkName, scope: checkFailIf ? 'check' : 'global' },\n },\n ].concat(\n hadTriggered\n ? [\n {\n name: 'fail_if.triggered',\n attrs: { check: checkName, scope: checkFailIf ? 'check' : 'global' },\n },\n ]\n : []\n )\n );\n } catch {}\n return results;\n }\n\n // Fall back to old failure_conditions syntax\n const globalConditions = config.failure_conditions;\n const checkConditions = checkConfig?.failure_conditions;\n\n return await this.failureEvaluator.evaluateConditions(\n checkName,\n checkSchema,\n checkGroup,\n reviewSummary,\n globalConditions,\n checkConditions,\n undefined, // previousOutputs\n prInfo?.authorAssociation\n );\n }\n\n /**\n * Get repository status summary\n */\n async getRepositoryStatus(): Promise<{\n isGitRepository: boolean;\n hasChanges: boolean;\n branch: string;\n filesChanged: number;\n }> {\n try {\n const repositoryInfo = await this.gitAnalyzer.analyzeRepository();\n return {\n isGitRepository: repositoryInfo.isGitRepository,\n hasChanges: repositoryInfo.files.length > 0,\n branch: repositoryInfo.head,\n filesChanged: repositoryInfo.files.length,\n };\n } catch {\n return {\n isGitRepository: false,\n hasChanges: false,\n branch: 'unknown',\n filesChanged: 0,\n };\n }\n }\n\n /**\n * Initialize GitHub check runs for each configured check\n */\n private async initializeGitHubChecks(\n options: CheckExecutionOptions,\n logFn: (message: string) => void\n ): Promise<void> {\n if (\n !options.githubChecks?.octokit ||\n !options.githubChecks.owner ||\n !options.githubChecks.repo ||\n !options.githubChecks.headSha\n ) {\n logFn('⚠️ GitHub checks enabled but missing required parameters');\n return;\n }\n\n try {\n this.githubCheckService = new GitHubCheckService(options.githubChecks.octokit);\n this.checkRunMap = new Map();\n this.githubContext = {\n owner: options.githubChecks.owner,\n repo: options.githubChecks.repo,\n };\n\n logFn(`🔍 Creating GitHub check runs for ${options.checks.length} checks...`);\n\n for (const checkName of options.checks) {\n try {\n const checkRunOptions: CheckRunOptions = {\n owner: options.githubChecks.owner,\n repo: options.githubChecks.repo,\n head_sha: options.githubChecks.headSha,\n name: `Visor: ${checkName}`,\n external_id: `visor-${checkName}-${options.githubChecks.headSha.substring(0, 7)}`,\n };\n\n const checkRun = await this.githubCheckService.createCheckRun(checkRunOptions, {\n title: `${checkName} Analysis`,\n summary: `Running ${checkName} check using AI-powered analysis...`,\n });\n\n this.checkRunMap.set(checkName, checkRun);\n logFn(`✅ Created check run for ${checkName}: ${checkRun.url}`);\n } catch (error) {\n logFn(`❌ Failed to create check run for ${checkName}: ${error}`);\n }\n }\n } catch (error) {\n // Check if this is a permissions error\n if (\n error instanceof Error &&\n (error.message.includes('403') || error.message.includes('checks:write'))\n ) {\n logFn(\n '⚠️ GitHub checks API not available - insufficient permissions. Check runs will be skipped.'\n );\n logFn('💡 To enable check runs, ensure your GitHub token has \"checks:write\" permission.');\n this.githubCheckService = undefined;\n this.checkRunMap = undefined;\n } else {\n logFn(`❌ Failed to initialize GitHub check runs: ${error}`);\n this.githubCheckService = undefined;\n this.checkRunMap = undefined;\n }\n }\n }\n\n /**\n * Update GitHub check runs to in-progress status\n */\n private async updateGitHubChecksInProgress(options: CheckExecutionOptions): Promise<void> {\n if (\n !this.githubCheckService ||\n !this.checkRunMap ||\n !options.githubChecks?.owner ||\n !options.githubChecks.repo\n ) {\n return;\n }\n\n for (const [checkName, checkRun] of this.checkRunMap) {\n try {\n await this.githubCheckService.updateCheckRunInProgress(\n options.githubChecks.owner,\n options.githubChecks.repo,\n checkRun.id,\n {\n title: `Analyzing with ${checkName}...`,\n summary: `AI-powered analysis is in progress for ${checkName} check.`,\n }\n );\n console.log(`🔄 Updated ${checkName} check to in-progress status`);\n } catch (error) {\n console.error(`❌ Failed to update ${checkName} check to in-progress: ${error}`);\n }\n }\n }\n\n /**\n * Complete GitHub check runs with results\n */\n private async completeGitHubChecksWithResults(\n reviewSummary: ReviewSummary,\n options: CheckExecutionOptions,\n prInfo: import('./pr-analyzer').PRInfo\n ): Promise<void> {\n if (\n !this.githubCheckService ||\n !this.checkRunMap ||\n !options.githubChecks?.owner ||\n !options.githubChecks.repo\n ) {\n return;\n }\n\n // Group issues by check name\n const issuesByCheck = new Map<string, import('./reviewer').ReviewIssue[]>();\n\n // Initialize empty arrays for all checks\n for (const checkName of this.checkRunMap.keys()) {\n issuesByCheck.set(checkName, []);\n }\n\n // Group issues by their check name\n for (const issue of reviewSummary.issues || []) {\n if (issue.checkName && issuesByCheck.has(issue.checkName)) {\n issuesByCheck.get(issue.checkName)!.push(issue);\n }\n }\n\n console.log(`🏁 Completing ${this.checkRunMap.size} GitHub check runs...`);\n\n for (const [checkName, checkRun] of this.checkRunMap) {\n try {\n const checkIssues = issuesByCheck.get(checkName) || [];\n\n // Evaluate failure conditions for this specific check\n const failureResults = await this.evaluateFailureConditions(\n checkName,\n { issues: checkIssues },\n options.config\n );\n\n // Detect command execution failure patterns to mark check as failed without requiring fail_if\n // We treat issues with ruleId starting with 'command/' as execution errors\n const execErrorIssue = checkIssues.find(i => i.ruleId?.startsWith('command/'));\n\n await this.githubCheckService.completeCheckRun(\n options.githubChecks.owner,\n options.githubChecks.repo,\n checkRun.id,\n checkName,\n failureResults,\n checkIssues,\n execErrorIssue ? execErrorIssue.message : undefined, // executionError\n prInfo.files.map((f: import('./pr-analyzer').PRFile) => f.filename), // filesChangedInCommit\n options.githubChecks.prNumber, // prNumber\n options.githubChecks.headSha // currentCommitSha\n );\n\n console.log(`✅ Completed ${checkName} check with ${checkIssues.length} issues`);\n } catch (error) {\n console.error(`❌ Failed to complete ${checkName} check: ${error}`);\n\n // Try to mark the check as failed due to execution error\n try {\n await this.githubCheckService.completeCheckRun(\n options.githubChecks.owner,\n options.githubChecks.repo,\n checkRun.id,\n checkName,\n [],\n [],\n error instanceof Error ? error.message : 'Unknown error occurred'\n );\n } catch (finalError) {\n console.error(`❌ Failed to mark ${checkName} check as failed: ${finalError}`);\n }\n }\n }\n }\n\n /**\n * Complete GitHub check runs with error status\n */\n private async completeGitHubChecksWithError(errorMessage: string): Promise<void> {\n if (!this.githubCheckService || !this.checkRunMap || !this.githubContext) {\n return;\n }\n\n console.log(`❌ Completing ${this.checkRunMap.size} GitHub check runs with error...`);\n\n for (const [checkName, checkRun] of this.checkRunMap) {\n try {\n await this.githubCheckService.completeCheckRun(\n this.githubContext.owner,\n this.githubContext.repo,\n checkRun.id,\n checkName,\n [],\n [],\n errorMessage\n );\n console.log(`❌ Completed ${checkName} check with error: ${errorMessage}`);\n } catch (error) {\n console.error(`❌ Failed to complete ${checkName} check with error: ${error}`);\n }\n }\n }\n\n /**\n * Filter checks based on their event triggers to prevent execution of checks\n * that shouldn't run for the current event type\n */\n private filterChecksByEvent(\n checks: string[],\n config?: import('./types/config').VisorConfig,\n prInfo?: PRInfo,\n logFn?: (message: string) => void,\n debug?: boolean\n ): string[] {\n if (!config?.checks) {\n // No config available, return all checks (fallback behavior)\n return checks;\n }\n\n // If we have event context from GitHub (prInfo with eventType), apply strict filtering\n // Otherwise (CLI, tests), use conservative filtering\n const prInfoWithEvent = prInfo as PRInfo & {\n eventType?: import('./types/config').EventTrigger;\n };\n const hasEventContext =\n prInfoWithEvent && 'eventType' in prInfoWithEvent && prInfoWithEvent.eventType;\n\n if (hasEventContext) {\n // GitHub Action context - apply strict event filtering\n const currentEvent = prInfoWithEvent.eventType!;\n if (debug) {\n logFn?.(`🔧 Debug: GitHub Action context, current event: ${currentEvent}`);\n }\n\n const filteredChecks: string[] = [];\n for (const checkName of checks) {\n const checkConfig = config.checks[checkName];\n if (!checkConfig) {\n filteredChecks.push(checkName);\n continue;\n }\n\n const eventTriggers = checkConfig.on || [];\n if (eventTriggers.length === 0) {\n // No triggers specified, include it\n filteredChecks.push(checkName);\n if (debug) {\n logFn?.(`🔧 Debug: Check '${checkName}' has no event triggers, including`);\n }\n } else if (eventTriggers.includes(currentEvent)) {\n // Check matches current event\n filteredChecks.push(checkName);\n if (debug) {\n logFn?.(`🔧 Debug: Check '${checkName}' matches event '${currentEvent}', including`);\n }\n } else {\n // Check doesn't match current event\n if (debug) {\n logFn?.(\n `🔧 Debug: Check '${checkName}' does not match event '${currentEvent}' (triggers: ${JSON.stringify(eventTriggers)}), skipping`\n );\n }\n }\n }\n return filteredChecks;\n } else {\n // CLI/Test context - conservative filtering (only exclude manual-only checks)\n if (debug) {\n logFn?.(`🔧 Debug: CLI/Test context, using conservative filtering`);\n }\n\n const filteredChecks: string[] = [];\n for (const checkName of checks) {\n const checkConfig = config.checks[checkName];\n if (!checkConfig) {\n filteredChecks.push(checkName);\n continue;\n }\n\n const eventTriggers = checkConfig.on || [];\n\n // Only exclude checks that are explicitly manual-only\n if (eventTriggers.length === 1 && eventTriggers[0] === 'manual') {\n if (debug) {\n logFn?.(`🔧 Debug: Check '${checkName}' is manual-only, skipping`);\n }\n } else {\n filteredChecks.push(checkName);\n if (debug) {\n logFn?.(\n `🔧 Debug: Check '${checkName}' included (triggers: ${JSON.stringify(eventTriggers)})`\n );\n }\n }\n }\n return filteredChecks;\n }\n }\n\n /**\n * Determine the current event type from PR info\n */\n private getCurrentEventType(prInfo?: PRInfo): import('./types/config').EventTrigger {\n if (!prInfo) {\n return 'pr_opened'; // Default fallback\n }\n\n // For now, assume all PR-related operations are 'pr_updated' since we don't have\n // direct access to the original GitHub event here. This is a simplification.\n // In the future, we could pass the actual event type through the call chain.\n\n // The key insight is that issue-assistant should only run on issue_opened/issue_comment\n // events, which don't generate PRInfo objects in the first place.\n return 'pr_updated';\n }\n\n /**\n * Initialize execution statistics for a check\n */\n private initializeCheckStats(checkName: string): void {\n this.executionStats.set(checkName, {\n checkName,\n totalRuns: 0,\n successfulRuns: 0,\n failedRuns: 0,\n skipped: false,\n totalDuration: 0,\n issuesFound: 0,\n issuesBySeverity: {\n critical: 0,\n error: 0,\n warning: 0,\n info: 0,\n },\n perIterationDuration: [],\n });\n }\n\n /**\n * Record the start of a check iteration\n * Returns the start timestamp for duration tracking\n */\n private recordIterationStart(_checkName: string): number {\n return Date.now();\n }\n\n /**\n * Record completion of a check iteration\n */\n private recordIterationComplete(\n checkName: string,\n startTime: number,\n success: boolean,\n issues: ReviewIssue[],\n output?: unknown\n ): void {\n const stats = this.executionStats.get(checkName);\n if (!stats) return;\n\n const duration = Date.now() - startTime;\n stats.totalRuns++;\n if (success) {\n stats.successfulRuns++;\n } else {\n stats.failedRuns++;\n }\n stats.totalDuration += duration;\n stats.perIterationDuration!.push(duration);\n\n // Count issues by severity\n for (const issue of issues) {\n stats.issuesFound++;\n if (issue.severity === 'critical') stats.issuesBySeverity.critical++;\n else if (issue.severity === 'error') stats.issuesBySeverity.error++;\n else if (issue.severity === 'warning') stats.issuesBySeverity.warning++;\n else if (issue.severity === 'info') stats.issuesBySeverity.info++;\n }\n\n // Track outputs produced\n if (output !== undefined) {\n stats.outputsProduced = (stats.outputsProduced || 0) + 1;\n }\n }\n\n /**\n * Track output in history for loop/goto scenarios\n */\n private trackOutputHistory(checkName: string, output: unknown): void {\n if (output === undefined) return;\n\n if (!this.outputHistory.has(checkName)) {\n this.outputHistory.set(checkName, []);\n }\n this.outputHistory.get(checkName)!.push(output);\n }\n\n /**\n * Record that a check was skipped\n */\n private recordSkip(\n checkName: string,\n reason: 'if_condition' | 'fail_fast' | 'dependency_failed',\n condition?: string\n ): void {\n const stats = this.executionStats.get(checkName);\n if (!stats) return;\n\n stats.skipped = true;\n stats.skipReason = reason;\n if (condition) {\n stats.skipCondition = condition;\n }\n }\n\n /**\n * Record forEach preview items\n */\n private recordForEachPreview(checkName: string, items: unknown[] | undefined): void {\n const stats = this.executionStats.get(checkName);\n if (!stats) return;\n if (!Array.isArray(items) || items.length === 0) return;\n\n // Store preview of first 3 items\n const preview = items.slice(0, 3).map(item => {\n let str: string;\n if (typeof item === 'string') {\n str = item;\n } else if (item === undefined || item === null) {\n str = '(empty)';\n } else {\n try {\n const j = JSON.stringify(item);\n str = typeof j === 'string' ? j : String(item);\n } catch {\n str = String(item);\n }\n }\n return str.length > 50 ? str.substring(0, 47) + '...' : str;\n });\n\n if (items.length > 3) {\n preview.push(`...${items.length - 3} more`);\n }\n\n stats.forEachPreview = preview;\n }\n\n /**\n * Record an error for a check\n */\n private recordError(checkName: string, error: Error | string): void {\n const stats = this.executionStats.get(checkName);\n if (!stats) return;\n\n stats.errorMessage = error instanceof Error ? error.message : String(error);\n }\n\n /**\n * Build the final execution statistics object\n */\n private buildExecutionStatistics(): ExecutionStatistics {\n const checks = Array.from(this.executionStats.values());\n const totalExecutions = checks.reduce((sum, s) => sum + s.totalRuns, 0);\n const successfulExecutions = checks.reduce((sum, s) => sum + s.successfulRuns, 0);\n const failedExecutions = checks.reduce((sum, s) => sum + s.failedRuns, 0);\n const skippedChecks = checks.filter(s => s.skipped).length;\n const totalDuration = checks.reduce((sum, s) => sum + s.totalDuration, 0);\n\n return {\n totalChecksConfigured: checks.length,\n totalExecutions,\n successfulExecutions,\n failedExecutions,\n skippedChecks,\n totalDuration,\n checks,\n };\n }\n\n // Generic fatality helpers to avoid duplication\n private isFatalRule(id: string, severity?: string): boolean {\n const sev = (severity || '').toLowerCase();\n return (\n sev === 'error' ||\n sev === 'critical' ||\n id === 'command/execution_error' ||\n id.endsWith('/command/execution_error') ||\n id === 'command/timeout' ||\n id.endsWith('/command/timeout') ||\n id === 'command/transform_js_error' ||\n id.endsWith('/command/transform_js_error') ||\n id === 'command/transform_error' ||\n id.endsWith('/command/transform_error') ||\n id.endsWith('/forEach/iteration_error') ||\n id === 'forEach/undefined_output' ||\n id.endsWith('/forEach/undefined_output') ||\n id.endsWith('_fail_if') ||\n id.endsWith('/global_fail_if')\n );\n }\n\n private hasFatal(issues: ReviewIssue[] | undefined): boolean {\n if (!issues || issues.length === 0) return false;\n return issues.some(i => this.isFatalRule(i.ruleId || '', i.severity));\n }\n\n private async failIfTriggered(\n checkName: string,\n result: ReviewSummary,\n config?: import('./types/config').VisorConfig\n ): Promise<boolean> {\n if (!config) return false;\n const failures = await this.evaluateFailureConditions(checkName, result, config);\n return failures.some(f => f.failed);\n }\n\n /**\n * Truncate a string to max length with ellipsis\n */\n private truncate(str: string, maxLen: number): string {\n if (str.length <= maxLen) return str;\n return str.substring(0, maxLen - 3) + '...';\n }\n\n /**\n * Format the Status column for execution summary table\n */\n private formatStatusColumn(stats: CheckExecutionStats): string {\n if (stats.skipped) {\n if (stats.skipReason === 'if_condition') return '⏭ if';\n if (stats.skipReason === 'fail_fast') return '⏭ ff';\n if (stats.skipReason === 'dependency_failed') return '⏭ dep';\n return '⏭';\n }\n\n if (stats.totalRuns === 0) return '-';\n\n const symbol = stats.failedRuns === 0 ? '✔' : stats.successfulRuns === 0 ? '✖' : '✔/✖';\n\n // Show iteration count if > 1\n if (stats.totalRuns > 1) {\n if (stats.failedRuns > 0 && stats.successfulRuns > 0) {\n // Partial success\n return `${symbol} ${stats.successfulRuns}/${stats.totalRuns}`;\n } else {\n // All success or all failed\n return `${symbol} ×${stats.totalRuns}`;\n }\n }\n\n return symbol;\n }\n\n /**\n * Format the Details column for execution summary table\n */\n private formatDetailsColumn(stats: CheckExecutionStats): string {\n const parts: string[] = [];\n\n // Outputs produced (forEach)\n if (stats.outputsProduced && stats.outputsProduced > 0) {\n parts.push(`→${stats.outputsProduced}`);\n }\n\n // Critical issues\n if (stats.issuesBySeverity.critical > 0) {\n parts.push(`${stats.issuesBySeverity.critical}🔴`);\n }\n\n // Warnings\n if (stats.issuesBySeverity.warning > 0) {\n parts.push(`${stats.issuesBySeverity.warning}⚠️`);\n }\n\n // Info (only if no critical/warnings)\n if (\n stats.issuesBySeverity.info > 0 &&\n stats.issuesBySeverity.critical === 0 &&\n stats.issuesBySeverity.warning === 0\n ) {\n parts.push(`${stats.issuesBySeverity.info}💡`);\n }\n\n // Error message or skip condition\n if (stats.errorMessage) {\n parts.push(this.truncate(stats.errorMessage, 20));\n } else if (stats.skipCondition) {\n parts.push(this.truncate(stats.skipCondition, 20));\n }\n\n return parts.join(' ');\n }\n\n /**\n * Log the execution summary table\n */\n private logExecutionSummary(stats: ExecutionStatistics): void {\n const totalIssues = stats.checks.reduce((sum, s) => sum + s.issuesFound, 0);\n const criticalIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.critical, 0);\n const warningIssues = stats.checks.reduce((sum, s) => sum + s.issuesBySeverity.warning, 0);\n const durationSec = (stats.totalDuration / 1000).toFixed(1);\n\n // Summary box\n const summaryTable = new (require('cli-table3'))({\n style: {\n head: [],\n border: [],\n },\n colWidths: [41],\n });\n\n summaryTable.push(\n [`Execution Complete (${durationSec}s)`],\n [`Checks: ${stats.totalChecksConfigured} configured → ${stats.totalExecutions} executions`],\n [\n `Status: ${stats.successfulExecutions} ✔ │ ${stats.failedExecutions} ✖ │ ${stats.skippedChecks} ⏭`,\n ]\n );\n\n if (totalIssues > 0) {\n let issuesLine = `Issues: ${totalIssues} total`;\n if (criticalIssues > 0) issuesLine += ` (${criticalIssues} 🔴`;\n if (warningIssues > 0) issuesLine += `${criticalIssues > 0 ? ' ' : ' ('}${warningIssues} ⚠️)`;\n else if (criticalIssues > 0) issuesLine += ')';\n summaryTable.push([issuesLine]);\n }\n\n logger.info('');\n logger.info(summaryTable.toString());\n\n // Details table\n logger.info('');\n logger.info('Check Details:');\n\n const detailsTable = new (require('cli-table3'))({\n head: ['Check', 'Duration', 'Status', 'Details'],\n colWidths: [21, 10, 10, 21],\n style: {\n head: ['cyan'],\n border: ['grey'],\n },\n });\n\n for (const checkStats of stats.checks) {\n const duration = checkStats.skipped\n ? '-'\n : `${(checkStats.totalDuration / 1000).toFixed(1)}s`;\n const status = this.formatStatusColumn(checkStats);\n const details = this.formatDetailsColumn(checkStats);\n\n detailsTable.push([checkStats.checkName, duration, status, details]);\n }\n\n logger.info(detailsTable.toString());\n\n // Legend\n logger.info('');\n logger.info(\n 'Legend: ✔=success │ ✖=failed │ ⏭=skipped │ ×N=iterations │ →N=outputs │ N🔴=critical │ N⚠️=warnings'\n );\n }\n}\n"],"mappings":"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","names":["initializeTracer","log","context","triggeringComment","fs","path","agentAny","schemaPath","result","CheckExecutionEngine","fs","path","status","fs","path","content","lines","fs","path","fs","path","path","fs","Sandbox","Sandbox","exec","arr","Sandbox","log","Sandbox","Sandbox","emitNdjsonSpanWithEvents","checkName","log","issues","suggestions","Sandbox","Sandbox","log","focus","path","createExtendedLiquid","fs","directDeps","agg","validation","emitNdjsonSpanWithEvents"]}