@probelabs/visor 0.1.97 → 0.1.100

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 (110) hide show
  1. package/README.md +16 -15
  2. package/action.yml +7 -2
  3. package/defaults/.visor.yaml +7 -6
  4. package/dist/action-cli-bridge.d.ts +1 -0
  5. package/dist/action-cli-bridge.d.ts.map +1 -1
  6. package/dist/ai-review-service.d.ts.map +1 -1
  7. package/dist/check-execution-engine.d.ts +8 -2
  8. package/dist/check-execution-engine.d.ts.map +1 -1
  9. package/dist/cli-main.d.ts.map +1 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/config.d.ts +5 -0
  12. package/dist/config.d.ts.map +1 -1
  13. package/dist/debug-visualizer/debug-span-exporter.d.ts +47 -0
  14. package/dist/debug-visualizer/debug-span-exporter.d.ts.map +1 -0
  15. package/dist/debug-visualizer/trace-reader.d.ts +117 -0
  16. package/dist/debug-visualizer/trace-reader.d.ts.map +1 -0
  17. package/dist/debug-visualizer/ui/index.html +2568 -0
  18. package/dist/debug-visualizer/ws-server.d.ts +99 -0
  19. package/dist/debug-visualizer/ws-server.d.ts.map +1 -0
  20. package/dist/defaults/.visor.yaml +7 -6
  21. package/dist/failure-condition-evaluator.d.ts.map +1 -1
  22. package/dist/generated/config-schema.d.ts +7 -3
  23. package/dist/generated/config-schema.d.ts.map +1 -1
  24. package/dist/generated/config-schema.json +7 -3
  25. package/dist/git-repository-analyzer.d.ts +1 -7
  26. package/dist/git-repository-analyzer.d.ts.map +1 -1
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +17668 -1760
  29. package/dist/liquid-extensions.d.ts +1 -1
  30. package/dist/liquid-extensions.d.ts.map +1 -1
  31. package/dist/output/code-review/schema.json +2 -2
  32. package/dist/output/traces/run-2025-10-22T10-40-34-055Z.ndjson +218 -0
  33. package/dist/pr-analyzer.d.ts +2 -1
  34. package/dist/pr-analyzer.d.ts.map +1 -1
  35. package/dist/providers/ai-check-provider.d.ts.map +1 -1
  36. package/dist/providers/check-provider-registry.d.ts.map +1 -1
  37. package/dist/providers/check-provider.interface.d.ts +17 -6
  38. package/dist/providers/check-provider.interface.d.ts.map +1 -1
  39. package/dist/providers/command-check-provider.d.ts.map +1 -1
  40. package/dist/providers/github-ops-provider.d.ts.map +1 -1
  41. package/dist/providers/http-check-provider.d.ts.map +1 -1
  42. package/dist/providers/human-input-check-provider.d.ts +78 -0
  43. package/dist/providers/human-input-check-provider.d.ts.map +1 -0
  44. package/dist/providers/index.d.ts +2 -1
  45. package/dist/providers/index.d.ts.map +1 -1
  46. package/dist/providers/mcp-check-provider.d.ts.map +1 -1
  47. package/dist/providers/memory-check-provider.d.ts.map +1 -1
  48. package/dist/sdk/check-execution-engine-F3662LY7.mjs +11 -0
  49. package/dist/sdk/{chunk-I3GQJIR7.mjs → chunk-B5QBV2QJ.mjs} +2 -2
  50. package/dist/sdk/chunk-B5QBV2QJ.mjs.map +1 -0
  51. package/dist/sdk/{chunk-IG3BFIIN.mjs → chunk-FVS5CJ5S.mjs} +30 -1
  52. package/dist/sdk/chunk-FVS5CJ5S.mjs.map +1 -0
  53. package/dist/sdk/{chunk-YXOWIDEF.mjs → chunk-TUTOLSFV.mjs} +15 -3
  54. package/dist/sdk/chunk-TUTOLSFV.mjs.map +1 -0
  55. package/dist/sdk/{chunk-4VK6WTYU.mjs → chunk-X2JKUOE5.mjs} +1375 -570
  56. package/dist/sdk/chunk-X2JKUOE5.mjs.map +1 -0
  57. package/dist/sdk/{liquid-extensions-GMEGEGC3.mjs → liquid-extensions-KVL4MKRH.mjs} +2 -2
  58. package/dist/sdk/{mermaid-telemetry-4DUEYCLE.mjs → mermaid-telemetry-FBF6D35S.mjs} +2 -2
  59. package/dist/sdk/sdk.d.mts +62 -4
  60. package/dist/sdk/sdk.d.ts +62 -4
  61. package/dist/sdk/sdk.js +1658 -723
  62. package/dist/sdk/sdk.js.map +1 -1
  63. package/dist/sdk/sdk.mjs +60 -15
  64. package/dist/sdk/sdk.mjs.map +1 -1
  65. package/dist/sdk/{tracer-init-RJGAIOBP.mjs → tracer-init-WC75N5NW.mjs} +2 -2
  66. package/dist/sdk.d.ts +5 -2
  67. package/dist/sdk.d.ts.map +1 -1
  68. package/dist/telemetry/file-span-exporter.d.ts.map +1 -1
  69. package/dist/telemetry/opentelemetry.d.ts +2 -0
  70. package/dist/telemetry/opentelemetry.d.ts.map +1 -1
  71. package/dist/telemetry/state-capture.d.ts +53 -0
  72. package/dist/telemetry/state-capture.d.ts.map +1 -0
  73. package/dist/telemetry/trace-helpers.d.ts.map +1 -1
  74. package/dist/traces/run-2025-10-22T10-40-34-055Z.ndjson +218 -0
  75. package/dist/types/cli.d.ts +6 -0
  76. package/dist/types/cli.d.ts.map +1 -1
  77. package/dist/types/config.d.ts +44 -3
  78. package/dist/types/config.d.ts.map +1 -1
  79. package/dist/utils/config-loader.d.ts +5 -0
  80. package/dist/utils/config-loader.d.ts.map +1 -1
  81. package/dist/utils/file-exclusion.d.ts +50 -0
  82. package/dist/utils/file-exclusion.d.ts.map +1 -0
  83. package/dist/utils/interactive-prompt.d.ts +26 -0
  84. package/dist/utils/interactive-prompt.d.ts.map +1 -0
  85. package/dist/utils/sandbox.d.ts +26 -0
  86. package/dist/utils/sandbox.d.ts.map +1 -0
  87. package/dist/utils/stdin-reader.d.ts +22 -0
  88. package/dist/utils/stdin-reader.d.ts.map +1 -0
  89. package/dist/utils/tracer-init.d.ts +0 -5
  90. package/dist/utils/tracer-init.d.ts.map +1 -1
  91. package/package.json +8 -4
  92. package/dist/output/traces/run-2025-10-19T14-24-36-341Z.ndjson +0 -40
  93. package/dist/output/traces/run-2025-10-19T14-24-48-674Z.ndjson +0 -40
  94. package/dist/output/traces/run-2025-10-19T14-24-49-238Z.ndjson +0 -40
  95. package/dist/output/traces/run-2025-10-19T14-24-49-761Z.ndjson +0 -40
  96. package/dist/output/traces/run-2025-10-19T14-24-50-279Z.ndjson +0 -12
  97. package/dist/sdk/check-execution-engine-S7BFPVWA.mjs +0 -11
  98. package/dist/sdk/chunk-4VK6WTYU.mjs.map +0 -1
  99. package/dist/sdk/chunk-I3GQJIR7.mjs.map +0 -1
  100. package/dist/sdk/chunk-IG3BFIIN.mjs.map +0 -1
  101. package/dist/sdk/chunk-YXOWIDEF.mjs.map +0 -1
  102. package/dist/traces/run-2025-10-19T14-24-36-341Z.ndjson +0 -40
  103. package/dist/traces/run-2025-10-19T14-24-48-674Z.ndjson +0 -40
  104. package/dist/traces/run-2025-10-19T14-24-49-238Z.ndjson +0 -40
  105. package/dist/traces/run-2025-10-19T14-24-49-761Z.ndjson +0 -40
  106. package/dist/traces/run-2025-10-19T14-24-50-279Z.ndjson +0 -12
  107. /package/dist/sdk/{check-execution-engine-S7BFPVWA.mjs.map → check-execution-engine-F3662LY7.mjs.map} +0 -0
  108. /package/dist/sdk/{liquid-extensions-GMEGEGC3.mjs.map → liquid-extensions-KVL4MKRH.mjs.map} +0 -0
  109. /package/dist/sdk/{mermaid-telemetry-4DUEYCLE.mjs.map → mermaid-telemetry-FBF6D35S.mjs.map} +0 -0
  110. /package/dist/sdk/{tracer-init-RJGAIOBP.mjs.map → tracer-init-WC75N5NW.mjs.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/session-registry.ts","../../src/github-comments.ts","../../src/footer.ts","../../src/ai-review-service.ts","../../src/utils/diff-processor.ts","../../src/reviewer.ts","../../src/git-repository-analyzer.ts","../../src/utils/file-exclusion.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/telemetry/state-capture.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/utils/sandbox.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/mcp-check-provider.ts","../../src/utils/interactive-prompt.ts","../../src/utils/stdin-reader.ts","../../src/providers/human-input-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';\n\n/**\n * Extended ProbeAgent interface that includes tracing properties\n */\ninterface TracedProbeAgent extends ProbeAgent {\n tracer?: any; // AppTracer removed from probe\n _telemetryConfig?: any; // TelemetryConfig removed from probe\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 as any).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';\nimport { generateFooter } from './footer';\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 footer = generateFooter({\n includeMetadata: {\n lastUpdated,\n triggeredBy,\n commitSha,\n },\n });\n\n return `<!-- visor-comment-id:${commentId} -->\n${content}\n\n${footer}\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","/**\n * Centralized footer generation for Visor comments and outputs\n */\n\nexport interface FooterOptions {\n /**\n * Include metadata like lastUpdated, triggeredBy, commitSha\n */\n includeMetadata?: {\n lastUpdated: string;\n triggeredBy: string;\n commitSha?: string;\n };\n /**\n * Include horizontal rule separator before footer\n */\n includeSeparator?: boolean;\n}\n\n/**\n * Generate a standard Visor footer with branding and optional tip\n */\nexport function generateFooter(options: FooterOptions = {}): string {\n const { includeMetadata, includeSeparator = true } = options;\n\n const parts: string[] = [];\n\n // Add separator\n if (includeSeparator) {\n parts.push('---');\n parts.push('');\n }\n\n // Add branding\n parts.push(\n '*Powered by [Visor](https://probelabs.com/visor) from [Probelabs](https://probelabs.com)*'\n );\n\n // Add metadata if provided\n if (includeMetadata) {\n const { lastUpdated, triggeredBy, commitSha } = includeMetadata;\n const commitInfo = commitSha ? ` | Commit: ${commitSha.substring(0, 7)}` : '';\n parts.push('');\n parts.push(`*Last updated: ${lastUpdated} | Triggered by: ${triggeredBy}${commitInfo}*`);\n }\n\n // Add tip\n parts.push('');\n parts.push('💡 **TIP:** You can chat with Visor using `/visor ask <your question>`');\n\n return parts.join('\\n');\n}\n\n/**\n * Check if a string contains a Visor footer\n */\nexport function hasVisorFooter(text: string): boolean {\n return (\n text.includes('*Powered by [Visor](https://probelabs.com/visor)') ||\n text.includes('*Powered by [Visor](https://github.com/probelabs/visor)')\n );\n}\n","import { ProbeAgent } from '@probelabs/probe';\nimport type { ProbeAgentOptions } 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';\nimport { processDiffWithOutline } from './utils/diff-processor';\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?: unknown; // SimpleTelemetry tracer (probe removed AppTracer)\n _telemetryConfig?: unknown; // SimpleTelemetry config (probe removed TelemetryConfig)\n _traceFilePath?: string;\n}\n\n/**\n * Extended ProbeAgentOptions interface that includes tracing properties\n */\ninterface TracedProbeAgentOptions extends ProbeAgentOptions {\n tracer?: unknown; // SimpleTelemetry tracer\n _telemetryConfig?: unknown; // SimpleTelemetry config\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 // NOTE: per request, no additional redaction/encryption helpers are used.\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; checkName?: string }\n ): Promise<string> {\n // When reusing sessions, skip PR context to avoid sending duplicate diff data\n const skipPRContext = options?.skipPRContext === true;\n\n // Check if we're using the code-review schema\n const isCodeReviewSchema = schema === 'code-review';\n\n const prContext = skipPRContext ? '' : await this.formatPRContext(prInfo, isCodeReviewSchema);\n const isIssue = (prInfo as PRInfo & { isIssue?: boolean }).isIssue === true;\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 async formatPRContext(prInfo: PRInfo, isCodeReviewSchema?: boolean): Promise<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 (debug level)\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 let historicalComments = triggeringComment\n ? issueComments.filter(c => c.id !== triggeringComment.id)\n : issueComments;\n\n // For code-review schema checks, filter out previous Visor code-review comments to avoid self-bias\n // Comment IDs look like: <!-- visor-comment-id:pr-review-244-review -->\n if (isCodeReviewSchema) {\n historicalComments = historicalComments.filter(\n c => !c.body || !c.body.includes('visor-comment-id:pr-review-')\n );\n }\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 // Process the diff with outline-diff format for better structure\n const processedFullDiff = await processDiffWithOutline(prInfo.fullDiff);\n context += `\n <!-- Complete unified diff showing all changes in the pull request (processed with outline-diff) -->\n <full_diff>\n${this.escapeXml(processedFullDiff)}\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 // Process the commit diff with outline-diff format for better structure\n const processedCommitDiff = await processDiffWithOutline(prInfo.commitDiff);\n context += `\n <!-- Diff of only the latest commit for incremental analysis (processed with outline-diff) -->\n <commit_diff>\n${this.escapeXml(processedCommitDiff)}\n </commit_diff>`;\n } else {\n // Process the fallback full diff with outline-diff format\n const processedFallbackDiff = prInfo.fullDiff\n ? await processDiffWithOutline(prInfo.fullDiff)\n : '';\n context += `\n <!-- Commit diff could not be retrieved - falling back to full diff analysis (processed with outline-diff) -->\n <commit_diff>\n${this.escapeXml(processedFallbackDiff)}\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 let historicalComments = triggeringComment\n ? prComments.filter(c => c.id !== triggeringComment.id)\n : prComments;\n\n // For code-review schema checks, filter out previous Visor code-review comments to avoid self-bias\n // Comment IDs look like: <!-- visor-comment-id:pr-review-244-review -->\n if (isCodeReviewSchema) {\n historicalComments = historicalComments.filter(\n c => !c.body || !c.body.includes('visor-comment-id:pr-review-')\n );\n }\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 // do not enforce directory perms here\n\n // Save complete session history (all messages sent and received)\n const sessionBase = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}`\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 totalMessages: fullHistory.length,\n };\n fs.writeFileSync(sessionBase + '.json', JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Redacted textual summary\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 fullHistory.forEach((msg: any, idx: number) => {\n const role = msg.role || 'unknown';\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += `\n${'='.repeat(60)}\nMESSAGE ${idx + 1}/${fullHistory.length}\nRole: ${role}\n${'='.repeat(60)}\n`;\n readable += content + '\\n';\n });\n fs.writeFileSync(sessionBase + '.summary.txt', readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n // (paths omitted)\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 logger.warn(`⚠️ Warning: Failed to export trace for cloned session: ${exportError}`);\n }\n }\n\n return { response, effectiveSchema };\n } catch (error) {\n logger.error(\n `❌ ProbeAgent session reuse failed: ${error instanceof Error ? error.message : 'Unknown error'}`\n );\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 SimpleTelemetry for lightweight tracing\n let traceFilePath = '';\n let telemetryConfig: unknown = 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 // do not enforce fs permissions here\n const base = path.join(\n debugArtifactsDir,\n `prompt-${_checkName || 'unknown'}-${timestamp}`\n );\n fs.writeFileSync(base + '.json', debugJson, 'utf-8');\n fs.writeFileSync(base + '.summary.txt', readableVersion, 'utf-8');\n log(`\n💾 Full debug info saved to directory: ${debugArtifactsDir}`);\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 as {\n withSpan?: (\n name: string,\n fn: () => Promise<string>,\n attrs?: Record<string, unknown>\n ) => Promise<string>;\n };\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 // do not enforce fs permissions here\n\n // Save complete session history (all messages sent and received)\n const sessionBase = path.join(\n debugArtifactsDir,\n `session-${_checkName || 'unknown'}-${timestamp}`\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 totalMessages: fullHistory.length,\n };\n fs.writeFileSync(sessionBase + '.json', JSON.stringify(sessionData, null, 2), 'utf-8');\n\n // Redacted textual summary\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 fullHistory.forEach((msg: any, idx: number) => {\n const role = msg.role || 'unknown';\n const content =\n typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content, null, 2);\n readable += `\n${'='.repeat(60)}\nMESSAGE ${idx + 1}/${fullHistory.length}\nRole: ${role}\n${'='.repeat(60)}\n`;\n readable += content + '\\n';\n });\n fs.writeFileSync(sessionBase + '.summary.txt', readable, 'utf-8');\n\n log(`💾 Complete session history saved:`);\n // (paths omitted)\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 telemetry to ensure all spans are exported\n if (traceFilePath && telemetryConfig) {\n try {\n // Cast telemetryConfig to have optional methods\n const telemetry = telemetryConfig as {\n flush?: () => Promise<void>;\n shutdown?: () => Promise<void>;\n };\n const tracerWithMethods = tracer as {\n flush?: () => Promise<void>;\n shutdown?: () => Promise<void>;\n };\n\n // First flush the tracer to export pending spans\n if (tracerWithMethods && typeof tracerWithMethods.flush === 'function') {\n await tracerWithMethods.flush();\n log(`🔄 Flushed tracer spans`);\n }\n\n // Then shutdown the telemetry config to finalize all exporters\n if (telemetry && typeof telemetry.shutdown === 'function') {\n await telemetry.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 (tracerWithMethods && typeof tracerWithMethods.shutdown === 'function') {\n // Fallback for SimpleTelemetry\n await tracerWithMethods.shutdown();\n log(`📊 Trace saved to: ${traceFilePath}`);\n }\n } catch (exportError) {\n logger.warn(`⚠️ 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 const _debugSchemaLogging =\n this.config.debug === true || process.env.VISOR_DEBUG_AI_SESSIONS === 'true';\n if (_debugSchemaLogging) {\n const details = {\n schema: _schema,\n isCustomSchema,\n isCustomLiteral: _schema === 'custom',\n startsWithDotSlash: typeof _schema === 'string' ? _schema.startsWith('./') : false,\n endsWithJson: typeof _schema === 'string' ? _schema.endsWith('.json') : false,\n notCodeReview: _schema !== 'code-review',\n noOutputPrefix: typeof _schema === 'string' ? !_schema.includes('output/') : false,\n };\n try {\n log(`🔍 Schema detection: ${JSON.stringify(details)}`);\n } catch {\n // Fallback if JSON.stringify throws on unexpected values\n log(\n `🔍 Schema detection: _schema=\"${String(_schema)}\", isCustomSchema=${isCustomSchema}`\n );\n }\n }\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 const detailed = this.config.debug === true || process.env.VISOR_DEBUG_AI_SESSIONS === 'true';\n const message = error instanceof Error ? error.message : String(error);\n\n if (detailed) {\n logger.debug(`❌ Failed to parse AI response: ${message}`);\n logger.debug('📄 FULL RAW RESPONSE:');\n logger.debug('='.repeat(80));\n logger.debug(response);\n logger.debug('='.repeat(80));\n logger.debug(`📏 Response length: ${response.length} characters`);\n\n if (error instanceof SyntaxError) {\n logger.debug('🔍 JSON parsing error - the response may not be valid JSON');\n logger.debug(`🔍 Error details: ${error.message}`);\n\n const errorMatch = error.message.match(/position (\\d+)/);\n if (errorMatch) {\n const position = parseInt(errorMatch[1]);\n logger.debug(`🔍 Error at position ${position}:`);\n const start = Math.max(0, position - 50);\n const end = Math.min(response.length, position + 50);\n logger.debug(`🔍 Context: \"${response.substring(start, end)}\"`);\n logger.debug(`🔍 Response beginning: \"${response.substring(0, 100)}\"`);\n }\n\n if (response.includes('I cannot')) {\n logger.debug('🔍 Response appears to be a refusal/explanation rather than JSON');\n }\n if (response.includes('```')) {\n logger.debug('🔍 Response appears to contain markdown code blocks');\n }\n if (response.startsWith('<')) {\n logger.debug('🔍 Response appears to start with XML/HTML');\n }\n }\n } else {\n logger.error(`❌ Failed to parse AI response: ${message}`);\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 { extract } from '@probelabs/probe';\nimport * as path from 'path';\n\n/**\n * Process diff content using the outline-diff format from @probelabs/probe\n * This extracts a structured outline from the diff without requiring a temporary file\n */\nexport async function processDiffWithOutline(diffContent: string): Promise<string> {\n if (!diffContent || diffContent.trim().length === 0) {\n return diffContent;\n }\n\n try {\n // Set PROBE_PATH to use the bundled binary with outline-diff support\n // The SDK by default may download an older binary that doesn't support outline-diff\n const originalProbePath = process.env.PROBE_PATH;\n\n // Try multiple possible locations for the probe binary\n // When bundled with ncc, __dirname may not be reliable\n const fs = require('fs');\n const possiblePaths = [\n // Relative to current working directory (most common in production)\n path.join(process.cwd(), 'node_modules/@probelabs/probe/bin/probe-binary'),\n // Relative to __dirname (for unbundled development)\n path.join(__dirname, '../..', 'node_modules/@probelabs/probe/bin/probe-binary'),\n // Relative to dist directory (for bundled CLI)\n path.join(__dirname, 'node_modules/@probelabs/probe/bin/probe-binary'),\n ];\n\n let probeBinaryPath: string | undefined;\n for (const candidatePath of possiblePaths) {\n if (fs.existsSync(candidatePath)) {\n probeBinaryPath = candidatePath;\n break;\n }\n }\n\n // Only process if binary exists, otherwise fall back to original diff\n if (!probeBinaryPath) {\n if (process.env.DEBUG === '1' || process.env.VERBOSE === '1') {\n console.error('Probe binary not found. Tried:', possiblePaths);\n }\n return diffContent;\n }\n\n process.env.PROBE_PATH = probeBinaryPath;\n\n // Use extract with content parameter (can be string or Buffer)\n // The TypeScript types haven't been updated yet, but the runtime supports it\n // Add timeout to avoid hanging\n const extractPromise = (extract as any)({\n content: diffContent,\n format: 'outline-diff',\n allowTests: true, // Allow test files and test code blocks in extraction results\n });\n\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => reject(new Error('Extract timeout after 30s')), 30000);\n });\n\n const result = await Promise.race([extractPromise, timeoutPromise]);\n\n // Restore original PROBE_PATH\n if (originalProbePath !== undefined) {\n process.env.PROBE_PATH = originalProbePath;\n } else {\n delete process.env.PROBE_PATH;\n }\n\n // Return the processed outline diff\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n // If outline-diff processing fails, fall back to the original diff\n // Use console.error instead of console.warn to avoid polluting JSON output\n if (process.env.DEBUG === '1' || process.env.VERBOSE === '1') {\n console.error('Failed to process diff with outline-diff format:', error);\n }\n return diffContent;\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 is comment-generating\n * Comment-generating schemas include:\n * - Built-in schemas: code-review, overview, plain, text\n * - Custom schemas with a \"text\" field in properties\n */\n private async isCommentGeneratingSchema(\n schema: string | Record<string, unknown>\n ): Promise<boolean> {\n try {\n // Check for built-in comment-generating schemas\n if (typeof schema === 'string') {\n // Well-known comment-generating schemas\n if (['code-review', 'overview', 'plain', 'text'].includes(schema)) {\n return true;\n }\n\n // Try to load and check custom string 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 const schemaObj = JSON.parse(schemaContent);\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 // Schema file not found or invalid, return false\n return false;\n }\n } else {\n // Inline schema object - check if it has a \"text\" field in properties\n const properties = schema.properties as Record<string, unknown> | undefined;\n return !!(properties && 'text' in properties);\n }\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 {\n // Check if the schema is comment-generating (built-in or custom with text field)\n shouldPostComment = await this.isCommentGeneratingSchema(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';\nimport { FileExclusionHelper } from './utils/file-exclusion';\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 private fileExclusionHelper: FileExclusionHelper;\n\n constructor(workingDirectory: string = process.cwd()) {\n this.cwd = workingDirectory;\n this.git = simpleGit(workingDirectory);\n this.fileExclusionHelper = new FileExclusionHelper(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 * 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 // FileExclusionHelper uses .gitignore patterns, which is sufficient\n if (this.fileExclusionHelper.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 // FileExclusionHelper uses .gitignore patterns, which is sufficient\n if (this.fileExclusionHelper.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 ignore from 'ignore';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Default exclusion patterns for common build artifacts and dependencies.\n * These can be overridden by providing custom patterns to the constructor.\n */\nconst DEFAULT_EXCLUSION_PATTERNS = [\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n 'node_modules/',\n 'coverage/',\n '.turbo/',\n 'bundled/',\n];\n\n/**\n * Shared utility for filtering files based on .gitignore patterns\n *\n * Design Decision: Synchronous I/O in Constructor\n * ------------------------------------------------\n * This class intentionally uses synchronous file I/O in the constructor for the following reasons:\n *\n * 1. **Initialization Context**: The constructor is called once during application startup,\n * not in request handling or performance-critical paths.\n *\n * 2. **Small File Sizes**: .gitignore files are typically <10KB. Even in large monorepos,\n * they rarely exceed 100KB. Reading such small files synchronously has negligible impact.\n *\n * 3. **Immediate Availability**: The exclusion patterns must be ready immediately for use.\n * Asynchronous initialization would require either:\n * - Async factory method (adds API complexity)\n * - Lazy loading (race conditions, repeated checks)\n * - Promise-based initialization (complicates usage across codebase)\n *\n * 4. **Simplicity**: Synchronous loading keeps the API simple and prevents async contagion\n * throughout the codebase. Methods like shouldExcludeFile() remain synchronous.\n *\n * 5. **No DoS Risk**: The file reading happens exactly once per instance during construction.\n * Attackers cannot trigger repeated synchronous reads.\n *\n * 6. **Consistency**: This follows the same pattern as other configuration loaders in Node.js\n * ecosystem (e.g., require(), cosmiconfig's sync mode).\n *\n * Alternative Considered: Async factory pattern would add complexity without meaningful benefit\n * given the usage patterns and file sizes involved.\n */\nexport class FileExclusionHelper {\n private gitignore: ReturnType<typeof ignore> | null = null;\n private workingDirectory: string;\n\n /**\n * @param workingDirectory - Directory to search for .gitignore\n * @param additionalPatterns - Additional patterns to include (optional, defaults to common build artifacts)\n */\n constructor(\n workingDirectory: string = process.cwd(),\n additionalPatterns: string[] | null = DEFAULT_EXCLUSION_PATTERNS\n ) {\n // Validate and normalize workingDirectory to prevent path traversal\n const normalizedPath = path.resolve(workingDirectory);\n\n // Ensure path doesn't contain suspicious patterns after normalization\n // Check for null bytes which could be used for injection\n if (normalizedPath.includes('\\0')) {\n throw new Error('Invalid workingDirectory: contains null bytes');\n }\n\n this.workingDirectory = normalizedPath;\n\n // Load gitignore synchronously during construction\n // This is acceptable because:\n // 1. Constructor is called once during initialization\n // 2. .gitignore files are typically small (<10KB)\n // 3. Synchronous loading ensures patterns are ready immediately\n // 4. Avoids async constructor complexity\n this.loadGitignore(additionalPatterns);\n }\n\n /**\n * Load .gitignore patterns from the working directory (called once in constructor)\n * @param additionalPatterns - Additional patterns to add to gitignore rules\n */\n private loadGitignore(additionalPatterns: string[] | null): void {\n // Resolve both paths to absolute, normalized forms\n const gitignorePath = path.resolve(this.workingDirectory, '.gitignore');\n const resolvedWorkingDir = path.resolve(this.workingDirectory);\n\n try {\n // Robust path validation using path.relative()\n // This handles symlinks and edge cases better than string comparison\n const relativePath = path.relative(resolvedWorkingDir, gitignorePath);\n\n // Security check: ensure .gitignore is within working directory\n // Reject if:\n // - Starts with '..' (parent directory)\n // - Is an absolute path (should be relative after path.relative())\n if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {\n throw new Error('Invalid gitignore path: path traversal detected');\n }\n\n // Additionally verify it's exactly '.gitignore' (no subdirectories)\n if (relativePath !== '.gitignore') {\n throw new Error('Invalid gitignore path: must be .gitignore in working directory');\n }\n\n this.gitignore = ignore();\n\n // Add additional patterns first (lower priority)\n if (additionalPatterns && additionalPatterns.length > 0) {\n this.gitignore.add(additionalPatterns);\n }\n\n // Load and add .gitignore patterns (higher priority)\n if (fs.existsSync(gitignorePath)) {\n const rawContent = fs.readFileSync(gitignorePath, 'utf8');\n\n // Comprehensive sanitization to prevent injection attacks\n const gitignoreContent = rawContent\n .replace(/[\\r\\n]+/g, '\\n') // Normalize line endings first\n .replace(/[\\x00-\\x09\\x0B-\\x1F\\x7F]/g, '') // Remove control chars except \\n (0x0A)\n .split('\\n')\n .filter(line => line.length < 1000) // Reject extremely long lines that could cause DoS\n .join('\\n')\n .trim();\n\n this.gitignore.add(gitignoreContent);\n console.error('✅ Loaded .gitignore patterns for file filtering');\n } else if (additionalPatterns && additionalPatterns.length > 0) {\n console.error('⚠️ No .gitignore found, using default exclusion patterns');\n }\n } catch (error) {\n console.warn('⚠️ Failed to load .gitignore:', error instanceof Error ? error.message : error);\n }\n }\n\n /**\n * Check if a file should be excluded based on .gitignore patterns\n */\n shouldExcludeFile(filename: string): boolean {\n // Check against .gitignore patterns if loaded\n if (this.gitignore) {\n return this.gitignore.ignores(filename);\n }\n\n return false;\n }\n}\n","import { Octokit } from '@octokit/rest';\nimport * as path from 'path';\nimport { FileExclusionHelper } from './utils/file-exclusion';\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 private fileExclusionHelper: FileExclusionHelper;\n\n constructor(\n private octokit: Octokit,\n private maxRetries: number = 3,\n workingDirectory: string = path.resolve(process.cwd())\n ) {\n this.fileExclusionHelper = new FileExclusionHelper(workingDirectory);\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 // Apply exclusion filtering early to avoid unnecessary processing\n let skippedCount = 0;\n const validFiles = files\n ? files\n .filter(file => file && typeof file === 'object' && file.filename)\n .filter(file => {\n // Early filtering: check exclusion before processing\n const filename =\n typeof file.filename === 'string'\n ? file.filename\n : String(file.filename || 'unknown');\n if (!filename || this.fileExclusionHelper.shouldExcludeFile(filename)) {\n skippedCount++;\n return false;\n }\n return true;\n })\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 : [];\n\n // Log skipped files summary\n if (skippedCount > 0) {\n console.log(`⏭️ Skipped ${skippedCount} excluded file(s)`);\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, HumanInputRequest } 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 * Execution context passed to check providers\n */\nexport interface ExecutionContext {\n /** Session information for AI session reuse */\n parentSessionId?: string;\n reuseSession?: boolean;\n /** CLI message value (from --message argument) */\n cliMessage?: string;\n /** SDK hooks for human input */\n hooks?: {\n onHumanInput?: (request: HumanInputRequest) => Promise<string>;\n };\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 context Optional execution context with session info, hooks, and CLI state\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 context?: ExecutionContext\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';\nimport { trace, context as otContext } from '@opentelemetry/api';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureProviderCall,\n} from '../telemetry/state-capture';\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 // Build template context for state capture\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 outputs: _dependencyResults\n ? Object.fromEntries(\n Array.from(_dependencyResults.entries()).map(([checkName, result]) => [\n checkName,\n (result as any).output !== undefined ? (result as any).output : result,\n ])\n )\n : {},\n };\n\n // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for input context (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const ctxJson = JSON.stringify(templateContext);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.input.context': ctxJson },\n []\n );\n } catch {}\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 const finalResult = {\n ...result,\n issues: filteredIssues,\n };\n\n // Capture AI provider call and output in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureProviderCall(\n span,\n 'ai',\n {\n prompt: processedPrompt.substring(0, 500), // Preview only\n model: aiConfig.model,\n },\n {\n content: JSON.stringify(finalResult).substring(0, 500),\n tokens: (result as any).usage?.totalTokens,\n }\n );\n const outputForSpan = (finalResult as { output?: unknown }).output ?? finalResult;\n captureCheckOutput(span, outputForSpan);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for output (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const outJson = JSON.stringify((finalResult as any).output ?? finalResult);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.output': outJson },\n []\n );\n } catch {}\n\n return finalResult;\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","/**\n * Enhanced state capture for OTEL spans to enable interactive debugging.\n *\n * This module provides utilities to capture complete execution state in span\n * attributes, enabling time-travel debugging and full state inspection.\n */\n\nimport { Span } from '@opentelemetry/api';\n\nconst MAX_ATTRIBUTE_LENGTH = 10000; // Truncate large values\nconst MAX_ARRAY_ITEMS = 100; // Limit array size in attributes\n\n/**\n * Safely serialize a value for OTEL span attributes.\n * Handles truncation, circular refs, and type conversions.\n */\nfunction safeSerialize(value: unknown, maxLength = MAX_ATTRIBUTE_LENGTH): string {\n try {\n if (value === undefined || value === null) return String(value);\n\n // Detect circular references\n const seen = new WeakSet();\n const json = JSON.stringify(value, (key, val) => {\n if (typeof val === 'object' && val !== null) {\n if (seen.has(val)) return '[Circular]';\n seen.add(val);\n }\n // Truncate long strings\n if (typeof val === 'string' && val.length > maxLength) {\n return val.substring(0, maxLength) + '...[truncated]';\n }\n return val;\n });\n\n if (json.length > maxLength) {\n return json.substring(0, maxLength) + '...[truncated]';\n }\n return json;\n } catch (err) {\n return `[Error serializing: ${err instanceof Error ? err.message : String(err)}]`;\n }\n}\n\n/**\n * Capture check input context (Liquid template variables) in span.\n */\nexport function captureCheckInputContext(span: Span, context: Record<string, unknown>): void {\n try {\n // Capture key context variables\n const keys = Object.keys(context);\n span.setAttribute('visor.check.input.keys', keys.join(','));\n span.setAttribute('visor.check.input.count', keys.length);\n\n // Capture full context as JSON (with size limit)\n span.setAttribute('visor.check.input.context', safeSerialize(context));\n\n // Capture specific important variables separately for easy querying\n if (context.pr) {\n span.setAttribute('visor.check.input.pr', safeSerialize(context.pr, 1000));\n }\n if (context.outputs) {\n span.setAttribute('visor.check.input.outputs', safeSerialize(context.outputs, 5000));\n }\n if (context.env) {\n span.setAttribute('visor.check.input.env_keys', Object.keys(context.env as object).join(','));\n }\n } catch (err) {\n try {\n span.setAttribute('visor.check.input.error', String(err));\n } catch {\n // Ignore if we can't even set the error attribute\n }\n }\n}\n\n/**\n * Capture check output in span.\n */\nexport function captureCheckOutput(span: Span, output: unknown): void {\n try {\n span.setAttribute('visor.check.output.type', typeof output);\n\n if (Array.isArray(output)) {\n span.setAttribute('visor.check.output.length', output.length);\n // Store first few items for preview\n const preview = output.slice(0, 10);\n span.setAttribute('visor.check.output.preview', safeSerialize(preview, 2000));\n }\n\n // Full output (truncated if needed)\n span.setAttribute('visor.check.output', safeSerialize(output));\n } catch (err) {\n try {\n span.setAttribute('visor.check.output.error', String(err));\n } catch {\n // Ignore if we can't even set the error attribute\n }\n }\n}\n\n/**\n * Capture forEach iteration state.\n */\nexport function captureForEachState(\n span: Span,\n items: unknown[],\n index: number,\n currentItem: unknown\n): void {\n try {\n span.setAttribute('visor.foreach.total', items.length);\n span.setAttribute('visor.foreach.index', index);\n span.setAttribute('visor.foreach.current_item', safeSerialize(currentItem, 500));\n\n // Store all items if not too large\n if (items.length <= MAX_ARRAY_ITEMS) {\n span.setAttribute('visor.foreach.items', safeSerialize(items));\n } else {\n span.setAttribute(\n 'visor.foreach.items.preview',\n safeSerialize(items.slice(0, MAX_ARRAY_ITEMS))\n );\n span.setAttribute('visor.foreach.items.truncated', true);\n }\n } catch (err) {\n span.setAttribute('visor.foreach.error', String(err));\n }\n}\n\n/**\n * Capture Liquid template evaluation details.\n */\nexport function captureLiquidEvaluation(\n span: Span,\n template: string,\n context: Record<string, unknown>,\n result: string\n): void {\n try {\n span.setAttribute('visor.liquid.template', template.substring(0, 1000));\n span.setAttribute('visor.liquid.template.length', template.length);\n span.setAttribute('visor.liquid.result', result.substring(0, 2000));\n span.setAttribute('visor.liquid.result.length', result.length);\n span.setAttribute('visor.liquid.context', safeSerialize(context, 3000));\n } catch (err) {\n span.setAttribute('visor.liquid.error', String(err));\n }\n}\n\n/**\n * Capture JavaScript transform execution.\n */\nexport function captureTransformJS(\n span: Span,\n code: string,\n input: unknown,\n output: unknown\n): void {\n try {\n // Truncate long code while keeping plain string (no JSON quoting)\n const codePreview = code.length > 2000 ? code.substring(0, 2000) + '...[truncated]' : code;\n span.setAttribute('visor.transform.code', codePreview);\n span.setAttribute('visor.transform.code.length', code.length);\n span.setAttribute('visor.transform.input', safeSerialize(input, 2000));\n span.setAttribute('visor.transform.output', safeSerialize(output, 2000));\n } catch (err) {\n span.setAttribute('visor.transform.error', String(err));\n }\n}\n\n/**\n * Capture provider request/response summary (safe, no raw AI content).\n */\nexport function captureProviderCall(\n span: Span,\n providerType: string,\n request: { prompt?: string; model?: string; [key: string]: unknown },\n response: { content?: string; tokens?: number; [key: string]: unknown }\n): void {\n try {\n span.setAttribute('visor.provider.type', providerType);\n\n // Request summary\n if (request.model) span.setAttribute('visor.provider.request.model', String(request.model));\n if (request.prompt) {\n span.setAttribute('visor.provider.request.prompt.length', request.prompt.length);\n span.setAttribute('visor.provider.request.prompt.preview', request.prompt.substring(0, 500));\n }\n\n // Response summary\n if (response.content) {\n span.setAttribute('visor.provider.response.length', response.content.length);\n span.setAttribute('visor.provider.response.preview', response.content.substring(0, 500));\n }\n if (response.tokens) {\n span.setAttribute('visor.provider.response.tokens', response.tokens);\n }\n } catch (err) {\n span.setAttribute('visor.provider.error', String(err));\n }\n}\n\n/**\n * Capture conditional evaluation (if/fail_if).\n */\nexport function captureConditionalEvaluation(\n span: Span,\n condition: string,\n result: boolean,\n context: Record<string, unknown>\n): void {\n try {\n span.setAttribute('visor.condition.expression', condition.substring(0, 500));\n span.setAttribute('visor.condition.result', result);\n span.setAttribute('visor.condition.context', safeSerialize(context, 2000));\n } catch (err) {\n span.setAttribute('visor.condition.error', String(err));\n }\n}\n\n/**\n * Capture routing decision (retry/goto/run).\n */\nexport function captureRoutingDecision(\n span: Span,\n action: 'retry' | 'goto' | 'run',\n target: string | string[],\n condition?: string\n): void {\n try {\n span.setAttribute('visor.routing.action', action);\n span.setAttribute('visor.routing.target', Array.isArray(target) ? target.join(',') : target);\n if (condition) {\n span.setAttribute('visor.routing.condition', condition.substring(0, 500));\n }\n } catch (err) {\n span.setAttribute('visor.routing.error', String(err));\n }\n}\n\n/**\n * Create a snapshot of the entire execution state at a point in time.\n * This is added as a span event for time-travel debugging.\n */\nexport function captureStateSnapshot(\n span: Span,\n checkId: string,\n outputs: Record<string, unknown>,\n memory: Record<string, unknown>\n): void {\n try {\n span.addEvent('state.snapshot', {\n 'visor.snapshot.check_id': checkId,\n 'visor.snapshot.outputs': safeSerialize(outputs, 5000),\n 'visor.snapshot.memory': safeSerialize(memory, 5000),\n 'visor.snapshot.timestamp': new Date().toISOString(),\n });\n } catch (err) {\n span.setAttribute('visor.snapshot.error', String(err));\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';\nimport { trace, context as otContext } from '@opentelemetry/api';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureProviderCall,\n} from '../telemetry/state-capture';\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 // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\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 const finalResult = {\n ...result,\n issues: filteredIssues,\n };\n\n // Capture HTTP provider call and output in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureProviderCall(\n span,\n 'http',\n {\n url,\n method,\n body: JSON.stringify(payload).substring(0, 500),\n },\n {\n content: JSON.stringify(response).substring(0, 500),\n }\n );\n const outputForSpan = (finalResult as { output?: unknown }).output ?? finalResult;\n captureCheckOutput(span, outputForSpan);\n }\n } catch {\n // Ignore telemetry errors\n }\n\n return finalResult;\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 Sandbox from '@nyariv/sandboxjs';\n\n/**\n * Centralized helpers for creating and using SandboxJS instances consistently\n * across providers. The goal is to have one place to define allowed globals\n * and prototype whitelists, and to offer a small helper to inject a `log`\n * utility inside user-provided JS snippets.\n */\n\nexport interface CompileOptions {\n injectLog?: boolean;\n logPrefix?: string;\n /** When true, wrap the code in a function and `return` its result */\n wrapFunction?: boolean;\n}\n\n/**\n * Create a hardened Sandbox with a consistent set of globals and prototype\n * whitelists. This is a superset of the sets previously used by individual\n * providers, kept intentionally minimal and side‑effect free.\n */\nexport function createSecureSandbox(): Sandbox {\n const globals = {\n ...Sandbox.SAFE_GLOBALS,\n Math,\n JSON,\n // Provide console with limited surface. Calls are harmless in CI logs and\n // help with debugging value_js / transform_js expressions.\n console: {\n log: console.log,\n warn: console.warn,\n error: console.error,\n },\n } as Record<string, unknown>;\n\n const prototypeWhitelist = new Map(Sandbox.SAFE_PROTOTYPES);\n\n // Arrays — union of methods used around the codebase\n const arrayMethods = new Set<string>([\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 'flat',\n 'flatMap',\n ]);\n prototypeWhitelist.set(Array.prototype, arrayMethods);\n\n // Strings — allow common, safe manipulation helpers\n const stringMethods = new Set<string>([\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 // Objects — keep to basic safe operations\n const objectMethods = new Set<string>([\n 'hasOwnProperty',\n 'toString',\n 'valueOf',\n 'keys',\n 'values',\n ]);\n prototypeWhitelist.set(Object.prototype, objectMethods);\n\n return new Sandbox({ globals, prototypeWhitelist });\n}\n\n/**\n * Compile and execute user-provided JS inside the sandbox with optional\n * helper injection. By default, code is wrapped in a function to keep the\n * global scope clean.\n */\nexport function compileAndRun<T = unknown>(\n sandbox: Sandbox,\n userCode: string,\n scope: Record<string, unknown>,\n opts: CompileOptions = { injectLog: true, wrapFunction: true, logPrefix: '[sandbox]' }\n): T {\n const inject = opts?.injectLog === true;\n let safePrefix = String(opts?.logPrefix ?? '[sandbox]');\n // Sanitize prefix aggressively: drop control chars and risky tokens, limit length\n safePrefix = safePrefix\n .replace(/[\\r\\n\\t\\0]/g, '')\n .replace(/[`$\\\\]/g, '') // strip backticks, dollar (template) and backslashes\n .replace(/\\$\\{/g, '') // remove template openings if present\n .slice(0, 64);\n // Build a safe header without string concatenation inside user code\n const header = inject\n ? `const __lp = ${JSON.stringify(safePrefix)}; const log = (...a) => { try { console.log(__lp, ...a); } catch {} };\\n`\n : '';\n const body = opts.wrapFunction\n ? `const __fn = () => {\\n${userCode}\\n};\\nreturn __fn();\\n`\n : `${userCode}`;\n const code = `${header}${body}`;\n let exec: ReturnType<typeof sandbox.compile>;\n try {\n exec = sandbox.compile(code);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`sandbox_compile_error: ${msg}`);\n }\n\n let out: any;\n try {\n out = exec(scope);\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`sandbox_execution_error: ${msg}`);\n }\n\n if (out && typeof out.run === 'function') {\n try {\n return out.run();\n } catch (e) {\n const msg = e instanceof Error ? e.message : String(e);\n throw new Error(`sandbox_runner_error: ${msg}`);\n }\n }\n return out as T;\n}\n","import { CheckProvider, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\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 // IMPORTANT: Always prefer authenticated octokit from event context (GitHub App or token)\n // This ensures proper bot identity in reactions, labels, and comments\n const octokit: import('@octokit/rest').Octokit | undefined = config.eventContext?.octokit as\n | import('@octokit/rest').Octokit\n | undefined;\n\n if (!octokit) {\n return {\n issues: [\n {\n file: 'system',\n line: 0,\n ruleId: 'github/missing_octokit',\n message:\n 'No authenticated Octokit instance available in event context. GitHub operations require proper authentication context.',\n severity: 'error',\n category: 'logic',\n },\n ],\n };\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\n // Build dependency outputs map (mirrors Liquid context construction)\n const depOutputs: Record<string, unknown> = {};\n if (dependencyResults) {\n for (const [name, result] of dependencyResults.entries()) {\n const summary = result as ReviewSummary & { output?: unknown };\n depOutputs[name] = summary.output !== undefined ? summary.output : summary;\n }\n }\n\n const res = compileAndRun<unknown>(\n sandbox,\n cfg.value_js,\n { pr: prInfo, values, outputs: depOutputs },\n { injectLog: true, wrapFunction: true, logPrefix: '[github:value_js]' }\n );\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 this.sandbox = createSecureSandbox();\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 { createSecureSandbox, compileAndRun } from '../utils/sandbox';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { logger } from '../logger';\nimport {\n createPermissionHelpers,\n detectLocalMode,\n resolveAssociationFromEvent,\n} from '../utils/author-permissions';\nimport { trace, context as otContext } from '@opentelemetry/api';\nimport {\n captureCheckInputContext,\n captureCheckOutput,\n captureTransformJS,\n} from '../telemetry/state-capture';\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 return createSecureSandbox();\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 // Capture input context in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckInputContext(span, templateContext);\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for input context (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const ctxJson = JSON.stringify(templateContext);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n // Emit both start and completion markers together for deterministic E2E assertions\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.input.context': ctxJson },\n [{ name: 'check.started' }, { name: 'check.completed' }]\n );\n } catch {}\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 finalOutput = compileAndRun<unknown>(\n this.sandbox,\n code,\n { scope: jsContext },\n { injectLog: false, wrapFunction: false }\n );\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 // Capture output and transform details in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureCheckOutput(span, outputForDependents);\n if (transformJs && output !== finalOutput) {\n captureTransformJS(span, transformJs, output, finalOutput);\n }\n }\n } catch {\n // Ignore telemetry errors\n }\n // Fallback NDJSON for output (non-OTEL environments)\n try {\n const checkId = (config as any).checkName || (config as any).id || 'unknown';\n const outJson = JSON.stringify((result as any).output ?? result);\n const { emitNdjsonSpanWithEvents } = require('../telemetry/fallback-ndjson');\n emitNdjsonSpanWithEvents(\n 'visor.check',\n { 'visor.check.id': checkId, 'visor.check.output': outJson },\n [{ name: 'check.started' }, { name: 'check.completed' }]\n );\n } catch {}\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';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\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 return createSecureSandbox();\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 const scope: Record<string, unknown> = { ...context };\n return compileAndRun<unknown>(this.sandbox, `return (${expression});`, scope, {\n injectLog: true,\n wrapFunction: false,\n logPrefix: '[memory:value_js]',\n });\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 const scope: Record<string, unknown> = { ...context };\n return compileAndRun<unknown>(this.sandbox, script, scope, {\n injectLog: true,\n wrapFunction: false,\n logPrefix: '[memory:exec_js]',\n });\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, CheckProviderConfig } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary, ReviewIssue } from '../reviewer';\nimport { logger } from '../logger';\nimport { Liquid } from 'liquidjs';\nimport { createExtendedLiquid } from '../liquid-extensions';\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport Sandbox from '@nyariv/sandboxjs';\nimport { createSecureSandbox, compileAndRun } from '../utils/sandbox';\n\n/**\n * MCP Check Provider Configuration\n */\nexport interface McpCheckConfig extends CheckProviderConfig {\n /** Transport type: stdio (default), sse (legacy), or http (streamable HTTP) */\n transport?: 'stdio' | 'sse' | 'http';\n /** Command to execute (for stdio transport) */\n command?: string;\n /** Command arguments (for stdio transport) */\n args?: string[];\n /** Environment variables (for stdio transport) */\n env?: Record<string, string>;\n /** Working directory (for stdio transport) */\n workingDirectory?: string;\n /** URL for SSE/HTTP transport */\n url?: string;\n /** HTTP headers (for SSE/HTTP transport) */\n headers?: Record<string, string>;\n /** Session ID for HTTP transport (optional, server may generate one) */\n sessionId?: string;\n /** MCP method/tool to call */\n method: string;\n /** Arguments to pass to the MCP method (supports Liquid templates) */\n methodArgs?: Record<string, unknown>;\n /** Transform template for method arguments (Liquid) */\n argsTransform?: string;\n /** Transform template for output (Liquid) */\n transform?: string;\n /** Transform using JavaScript expressions */\n transform_js?: string;\n /** Timeout in seconds */\n timeout?: number;\n}\n\n/**\n * Check provider that calls MCP tools directly\n * Supports stdio, SSE (legacy), and Streamable HTTP transports\n */\nexport class McpCheckProvider 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 }\n\n /**\n * Create a secure sandbox for JavaScript execution\n * - Uses Sandbox.SAFE_GLOBALS which excludes: Function, eval, require, process, etc.\n * - Only allows explicitly whitelisted prototype methods\n * - No access to filesystem, network, or system resources\n */\n private createSecureSandbox(): Sandbox {\n return createSecureSandbox();\n }\n\n getName(): string {\n return 'mcp';\n }\n\n getDescription(): string {\n return 'Call MCP tools directly using stdio, SSE, or Streamable HTTP transport';\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 McpCheckConfig;\n\n // Method is required\n if (!cfg.method || typeof cfg.method !== 'string') {\n logger.error('MCP check requires a method name');\n return false;\n }\n\n const transport = cfg.transport || 'stdio';\n\n // Validate transport-specific requirements\n if (transport === 'stdio') {\n if (!cfg.command || typeof cfg.command !== 'string') {\n logger.error('MCP stdio transport requires a command');\n return false;\n }\n\n // Basic command injection prevention - check for shell metacharacters\n // Allow common safe commands like 'npx', 'node', 'python', etc.\n if (/[;&|`$(){}[\\]]/.test(cfg.command)) {\n logger.error('MCP stdio command contains potentially unsafe characters');\n return false;\n }\n } else if (transport === 'sse' || transport === 'http') {\n if (!cfg.url || typeof cfg.url !== 'string') {\n logger.error(`MCP ${transport} transport requires a URL`);\n return false;\n }\n\n // Validate URL format\n try {\n const parsedUrl = new URL(cfg.url);\n // Only allow http and https protocols\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n logger.error(\n `Invalid URL protocol for MCP ${transport} transport: ${parsedUrl.protocol}. Only http: and https: are allowed.`\n );\n return false;\n }\n } catch {\n logger.error(`Invalid URL format for MCP ${transport} transport: ${cfg.url}`);\n return false;\n }\n } else {\n logger.error(`Invalid MCP transport: ${transport}. Must be 'stdio', 'sse', or 'http'`);\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 const cfg = config as McpCheckConfig;\n\n try {\n // Prepare template context\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(dependencyResults),\n env: this.getSafeEnvironmentVariables(),\n };\n\n // Render method arguments if needed\n let methodArgs = cfg.methodArgs || {};\n if (cfg.argsTransform) {\n const rendered = await this.liquid.parseAndRender(cfg.argsTransform, templateContext);\n try {\n methodArgs = JSON.parse(rendered);\n } catch (error) {\n logger.error(`Failed to parse argsTransform as JSON: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/args_transform_error',\n message: `Failed to parse argsTransform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Create MCP client and execute method\n const result = await this.executeMcpMethod(cfg, methodArgs);\n\n // Apply transforms if specified\n let finalOutput = result;\n\n // Apply Liquid transform\n if (cfg.transform) {\n try {\n const transformContext = {\n ...templateContext,\n output: result,\n };\n const rendered = await this.liquid.parseAndRender(cfg.transform, transformContext);\n try {\n finalOutput = JSON.parse(rendered.trim());\n } catch {\n finalOutput = rendered.trim();\n }\n } catch (error) {\n logger.error(`Failed to apply Liquid transform: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/transform_error',\n message: `Failed to apply transform: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n // Apply JavaScript transform using secure sandbox\n if (cfg.transform_js) {\n try {\n if (!this.sandbox) {\n this.sandbox = this.createSecureSandbox();\n }\n\n // Build scope with all context variables\n const scope = {\n output: finalOutput,\n pr: templateContext.pr,\n files: templateContext.files,\n outputs: templateContext.outputs,\n env: templateContext.env,\n };\n\n // Compile and execute the transform in sandboxed environment\n finalOutput = compileAndRun<unknown>(\n this.sandbox,\n `return (${cfg.transform_js});`,\n scope,\n { injectLog: true, wrapFunction: false, logPrefix: '[mcp:transform_js]' }\n );\n } catch (error) {\n logger.error(`Failed to apply JavaScript transform: ${error}`);\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/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 issues from output\n const extracted = this.extractIssuesFromOutput(finalOutput);\n if (extracted) {\n return {\n issues: extracted.issues,\n ...(extracted.remainingOutput ? { output: extracted.remainingOutput } : {}),\n } as ReviewSummary;\n }\n\n // Return output directly\n return {\n issues: [],\n ...(finalOutput ? { output: finalOutput } : {}),\n } as ReviewSummary;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n logger.error(`MCP check failed: ${errorMessage}`);\n\n return {\n issues: [\n {\n file: 'mcp',\n line: 0,\n ruleId: 'mcp/execution_error',\n message: `MCP check failed: ${errorMessage}`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n /**\n * Execute an MCP method using the configured transport\n */\n private async executeMcpMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>\n ): Promise<unknown> {\n const transport = config.transport || 'stdio';\n const timeout = (config.timeout || 60) * 1000; // Convert to milliseconds\n\n if (transport === 'stdio') {\n return await this.executeStdioMethod(config, methodArgs, timeout);\n } else if (transport === 'sse') {\n return await this.executeSseMethod(config, methodArgs, timeout);\n } else if (transport === 'http') {\n return await this.executeHttpMethod(config, methodArgs, timeout);\n } else {\n throw new Error(`Unsupported transport: ${transport}`);\n }\n }\n\n /**\n * Generic method to execute MCP method with any transport\n */\n private async executeWithTransport(\n transport: StdioClientTransport | SSEClientTransport | StreamableHTTPClientTransport,\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number,\n transportName: string\n ): Promise<unknown> {\n // Create client\n const client = new Client(\n {\n name: 'visor-mcp-client',\n version: '1.0.0',\n },\n {\n capabilities: {},\n }\n );\n\n try {\n // Connect with timeout\n let timeoutId: NodeJS.Timeout | undefined;\n try {\n await Promise.race([\n client.connect(transport),\n new Promise((_, reject) => {\n timeoutId = setTimeout(() => reject(new Error('Connection timeout')), timeout);\n }),\n ]);\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n }\n\n logger.debug(`Connected to MCP server via ${transportName}`);\n\n // Log session ID for HTTP transport\n if (transport instanceof StreamableHTTPClientTransport && transport.sessionId) {\n logger.debug(`MCP Session ID: ${transport.sessionId}`);\n }\n\n // List available tools (for debugging)\n try {\n const toolsResult = await client.listTools();\n logger.debug(`Available MCP tools: ${JSON.stringify(toolsResult?.tools || [])}`);\n } catch (error) {\n logger.debug(`Could not list MCP tools: ${error}`);\n }\n\n // Call the tool with timeout\n let callTimeoutId: NodeJS.Timeout | undefined;\n try {\n const result = await Promise.race([\n client.callTool({\n name: config.method,\n arguments: methodArgs,\n }),\n new Promise((_, reject) => {\n callTimeoutId = setTimeout(() => reject(new Error('Request timeout')), timeout);\n }),\n ]);\n\n logger.debug(`MCP method result: ${JSON.stringify(result)}`);\n return result;\n } finally {\n if (callTimeoutId) {\n clearTimeout(callTimeoutId);\n }\n }\n } finally {\n try {\n await client.close();\n } catch (error) {\n logger.debug(`Error closing MCP client: ${error}`);\n }\n }\n }\n\n /**\n * Execute MCP method using stdio transport\n */\n private async executeStdioMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const transport = new StdioClientTransport({\n command: config.command!,\n args: config.args,\n env: config.env,\n cwd: config.workingDirectory,\n });\n\n return this.executeWithTransport(\n transport,\n config,\n methodArgs,\n timeout,\n `stdio: ${config.command}`\n );\n }\n\n /**\n * Execute MCP method using SSE transport\n */\n private async executeSseMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const requestInit: RequestInit = {};\n if (config.headers) {\n requestInit.headers = config.headers;\n }\n\n const transport = new SSEClientTransport(new URL(config.url!), {\n requestInit,\n });\n\n return this.executeWithTransport(transport, config, methodArgs, timeout, `SSE: ${config.url}`);\n }\n\n /**\n * Execute MCP method using Streamable HTTP transport\n */\n private async executeHttpMethod(\n config: McpCheckConfig,\n methodArgs: Record<string, unknown>,\n timeout: number\n ): Promise<unknown> {\n const requestInit: RequestInit = {};\n if (config.headers) {\n requestInit.headers = config.headers;\n }\n\n const transport = new StreamableHTTPClientTransport(new URL(config.url!), {\n requestInit,\n sessionId: config.sessionId,\n });\n\n return this.executeWithTransport(\n transport,\n config,\n methodArgs,\n timeout,\n `Streamable HTTP: ${config.url}`\n );\n }\n\n /**\n * Build output context from dependency results\n */\n private buildOutputContext(\n dependencyResults?: Map<string, ReviewSummary>\n ): Record<string, unknown> {\n if (!dependencyResults) {\n return {};\n }\n\n const outputs: Record<string, unknown> = {};\n for (const [checkName, result] of dependencyResults) {\n const summary = result as ReviewSummary & { output?: unknown };\n outputs[checkName] = summary.output !== undefined ? summary.output : summary;\n }\n\n return outputs;\n }\n\n /**\n * Get safe environment variables\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 safeVars['PWD'] = process.cwd();\n return safeVars;\n }\n\n /**\n * Extract issues from MCP output\n */\n private extractIssuesFromOutput(\n output: unknown\n ): { issues: ReviewIssue[]; remainingOutput: unknown } | null {\n if (output === null || output === undefined) {\n return null;\n }\n\n // If output is a string, try to parse as JSON\n if (typeof output === 'string') {\n try {\n const parsed = JSON.parse(output);\n return this.extractIssuesFromOutput(parsed);\n } catch {\n return null;\n }\n }\n\n // If output is an array of issues\n if (Array.isArray(output)) {\n const issues = this.normalizeIssueArray(output);\n if (issues) {\n return { issues, remainingOutput: undefined };\n }\n return null;\n }\n\n // If output is an object with issues property\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 return {\n issues,\n remainingOutput: Object.keys(remaining).length > 0 ? remaining : undefined,\n };\n }\n\n // Check if output itself is a single issue\n const singleIssue = this.normalizeIssue(record);\n if (singleIssue) {\n return { issues: [singleIssue], remainingOutput: undefined };\n }\n }\n\n return null;\n }\n\n /**\n * Normalize an array of issues\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 /**\n * Normalize a single issue\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 }\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 const line = this.toNumber(data.line || data.startLine || data.lineNumber) ?? 0;\n const endLine = this.toNumber(data.endLine || data.end_line || data.stopLine);\n const suggestion = this.toTrimmedString(data.suggestion);\n const replacement = this.toTrimmedString(data.replacement);\n const ruleId = this.toTrimmedString(data.ruleId || data.rule || data.id || data.check) || 'mcp';\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 getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'transport',\n 'command',\n 'args',\n 'env',\n 'workingDirectory',\n 'url',\n 'headers',\n 'sessionId',\n 'method',\n 'methodArgs',\n 'argsTransform',\n 'transform',\n 'transform_js',\n 'timeout',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // MCP SDK is now a required dependency, so always available\n return true;\n }\n\n getRequirements(): string[] {\n return ['MCP method name specified', 'Transport configuration (stdio: command, sse/http: url)'];\n }\n}\n","/**\n * Interactive terminal prompting with beautiful UI\n */\n\nimport * as readline from 'readline';\n\nexport interface PromptOptions {\n /** The prompt text to display */\n prompt: string;\n /** Placeholder text (shown in dim color) */\n placeholder?: string;\n /** Allow multiline input (Ctrl+D to finish) */\n multiline?: boolean;\n /** Timeout in milliseconds */\n timeout?: number;\n /** Default value if timeout occurs */\n defaultValue?: string;\n /** Allow empty input */\n allowEmpty?: boolean;\n}\n\n// ANSI color codes\nconst colors = {\n reset: '\\x1b[0m',\n dim: '\\x1b[2m',\n bold: '\\x1b[1m',\n cyan: '\\x1b[36m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n gray: '\\x1b[90m',\n};\n\n// Box drawing characters (with ASCII fallback)\nconst supportsUnicode = process.env.LANG?.includes('UTF-8') || process.platform === 'darwin';\n\nconst box = supportsUnicode\n ? {\n topLeft: '┌',\n topRight: '┐',\n bottomLeft: '└',\n bottomRight: '┘',\n horizontal: '─',\n vertical: '│',\n leftT: '├',\n rightT: '┤',\n }\n : {\n topLeft: '+',\n topRight: '+',\n bottomLeft: '+',\n bottomRight: '+',\n horizontal: '-',\n vertical: '|',\n leftT: '+',\n rightT: '+',\n };\n\n/**\n * Format time in mm:ss\n */\nfunction formatTime(ms: number): string {\n const seconds = Math.ceil(ms / 1000);\n const mins = Math.floor(seconds / 60);\n const secs = seconds % 60;\n return `${mins}:${secs.toString().padStart(2, '0')}`;\n}\n\n/**\n * Draw a horizontal line\n */\nfunction drawLine(char: string, width: number): string {\n return char.repeat(width);\n}\n\n/**\n * Wrap text to fit within a given width\n */\nfunction wrapText(text: string, width: number): string[] {\n const words = text.split(' ');\n const lines: string[] = [];\n let currentLine = '';\n\n for (const word of words) {\n if (currentLine.length + word.length + 1 <= width) {\n currentLine += (currentLine ? ' ' : '') + word;\n } else {\n if (currentLine) lines.push(currentLine);\n currentLine = word;\n }\n }\n if (currentLine) lines.push(currentLine);\n\n return lines;\n}\n\n/**\n * Display the prompt UI\n */\nfunction displayPromptUI(options: PromptOptions, remainingMs?: number): void {\n const width = Math.min(process.stdout.columns || 80, 80) - 4;\n const icon = supportsUnicode ? '💬' : '>';\n\n console.log('\\n'); // Add some spacing\n\n // Top border\n console.log(`${box.topLeft}${drawLine(box.horizontal, width + 2)}${box.topRight}`);\n\n // Title\n console.log(\n `${box.vertical} ${colors.bold}${icon} Human Input Required${colors.reset}${' '.repeat(\n width - 22\n )} ${box.vertical}`\n );\n\n // Separator\n console.log(`${box.leftT}${drawLine(box.horizontal, width + 2)}${box.rightT}`);\n\n // Empty line\n console.log(`${box.vertical} ${' '.repeat(width)} ${box.vertical}`);\n\n // Prompt text (wrapped)\n const promptLines = wrapText(options.prompt, width - 2);\n for (const line of promptLines) {\n console.log(\n `${box.vertical} ${colors.cyan}${line}${colors.reset}${' '.repeat(\n width - line.length\n )} ${box.vertical}`\n );\n }\n\n // Empty line\n console.log(`${box.vertical} ${' '.repeat(width)} ${box.vertical}`);\n\n // Instructions\n const instruction = options.multiline\n ? '(Type your response, press Ctrl+D when done)'\n : '(Type your response and press Enter)';\n console.log(\n `${box.vertical} ${colors.dim}${instruction}${colors.reset}${' '.repeat(\n width - instruction.length\n )} ${box.vertical}`\n );\n\n // Placeholder if provided\n if (options.placeholder && !options.multiline) {\n console.log(\n `${box.vertical} ${colors.dim}${options.placeholder}${colors.reset}${' '.repeat(\n width - options.placeholder.length\n )} ${box.vertical}`\n );\n }\n\n // Empty line\n console.log(`${box.vertical} ${' '.repeat(width)} ${box.vertical}`);\n\n // Timeout indicator\n if (remainingMs !== undefined && options.timeout) {\n const timeIcon = supportsUnicode ? '⏱ ' : 'Time: ';\n const timeStr = `${timeIcon} ${formatTime(remainingMs)} remaining`;\n console.log(\n `${box.vertical} ${colors.yellow}${timeStr}${colors.reset}${' '.repeat(\n width - timeStr.length\n )} ${box.vertical}`\n );\n }\n\n // Bottom border\n console.log(`${box.bottomLeft}${drawLine(box.horizontal, width + 2)}${box.bottomRight}`);\n\n console.log(''); // Empty line before input\n process.stdout.write(`${colors.green}>${colors.reset} `);\n}\n\n/**\n * Prompt user for input with a beautiful interactive UI\n */\nexport async function interactivePrompt(options: PromptOptions): Promise<string> {\n return new Promise((resolve, reject) => {\n let input = '';\n let timeoutId: NodeJS.Timeout | undefined;\n let countdownInterval: NodeJS.Timeout | undefined;\n let remainingMs = options.timeout;\n\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true,\n });\n\n // Display initial UI\n displayPromptUI(options, remainingMs);\n\n const cleanup = () => {\n if (timeoutId) clearTimeout(timeoutId);\n if (countdownInterval) clearInterval(countdownInterval);\n rl.close();\n };\n\n const finish = (value: string) => {\n cleanup();\n console.log(''); // New line after input\n resolve(value);\n };\n\n // Setup timeout if specified\n if (options.timeout) {\n timeoutId = setTimeout(() => {\n cleanup();\n console.log(`\\n${colors.yellow}⏱ Timeout reached${colors.reset}`);\n if (options.defaultValue !== undefined) {\n console.log(\n `${colors.gray}Using default value: ${options.defaultValue}${colors.reset}\\n`\n );\n resolve(options.defaultValue);\n } else {\n reject(new Error('Input timeout'));\n }\n }, options.timeout);\n\n // Update countdown every second\n if (remainingMs) {\n countdownInterval = setInterval(() => {\n remainingMs = remainingMs! - 1000;\n if (remainingMs <= 0) {\n if (countdownInterval) clearInterval(countdownInterval);\n }\n }, 1000);\n }\n }\n\n if (options.multiline) {\n // Multiline mode: collect lines until EOF (Ctrl+D)\n rl.on('line', line => {\n input += (input ? '\\n' : '') + line;\n });\n\n rl.on('close', () => {\n cleanup();\n const trimmed = input.trim();\n if (!trimmed && !options.allowEmpty) {\n console.log(`${colors.yellow}⚠ Empty input not allowed${colors.reset}`);\n reject(new Error('Empty input not allowed'));\n } else {\n finish(trimmed);\n }\n });\n } else {\n // Single line mode\n rl.question('', answer => {\n const trimmed = answer.trim();\n if (!trimmed && !options.allowEmpty && !options.defaultValue) {\n cleanup();\n console.log(`${colors.yellow}⚠ Empty input not allowed${colors.reset}`);\n reject(new Error('Empty input not allowed'));\n } else {\n finish(trimmed || options.defaultValue || '');\n }\n });\n }\n\n // Handle Ctrl+C\n rl.on('SIGINT', () => {\n cleanup();\n console.log('\\n\\n' + colors.yellow + '⚠ Cancelled by user' + colors.reset);\n reject(new Error('Cancelled by user'));\n });\n });\n}\n\n/**\n * Simple prompt without fancy UI (for non-TTY environments)\n */\nexport async function simplePrompt(prompt: string): Promise<string> {\n return new Promise(resolve => {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n rl.question(`${prompt}\\n> `, answer => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n","/**\n * Utilities for reading from stdin\n */\n\n/**\n * Check if stdin has data available (is being piped)\n */\nexport function isStdinAvailable(): boolean {\n // Check if stdin is a TTY (interactive terminal)\n // If it's not a TTY, it means data is being piped\n return !process.stdin.isTTY;\n}\n\n/**\n * Read all data from stdin\n * @param timeout Optional timeout in milliseconds\n * @param maxSize Maximum size in bytes (default: 1MB)\n * @returns Promise that resolves with the stdin content\n */\nexport async function readStdin(timeout?: number, maxSize: number = 1024 * 1024): Promise<string> {\n return new Promise((resolve, reject) => {\n let data = '';\n let timeoutId: NodeJS.Timeout | undefined;\n\n if (timeout) {\n timeoutId = setTimeout(() => {\n cleanup();\n reject(new Error(`Stdin read timeout after ${timeout}ms`));\n }, timeout);\n }\n\n const cleanup = () => {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n process.stdin.removeListener('data', onData);\n process.stdin.removeListener('end', onEnd);\n process.stdin.removeListener('error', onError);\n // Pause stdin to prevent resource leaks\n process.stdin.pause();\n };\n\n const onData = (chunk: Buffer) => {\n data += chunk.toString();\n // Security: Prevent DoS through large input\n if (data.length > maxSize) {\n cleanup();\n reject(new Error(`Input exceeds maximum size of ${maxSize} bytes`));\n }\n };\n\n const onEnd = () => {\n cleanup();\n resolve(data.trim());\n };\n\n const onError = (err: Error) => {\n cleanup();\n reject(err);\n };\n\n process.stdin.setEncoding('utf8');\n process.stdin.on('data', onData);\n process.stdin.on('end', onEnd);\n process.stdin.on('error', onError);\n\n // Resume stdin in case it's paused\n process.stdin.resume();\n });\n}\n\n/**\n * Try to read from stdin if available, otherwise return null\n * @param timeout Optional timeout in milliseconds\n * @param maxSize Maximum size in bytes (default: 1MB)\n * @returns Promise that resolves with stdin content or null if not available\n */\nexport async function tryReadStdin(\n timeout?: number,\n maxSize: number = 1024 * 1024\n): Promise<string | null> {\n if (!isStdinAvailable()) {\n return null;\n }\n\n try {\n return await readStdin(timeout, maxSize);\n } catch {\n // If reading fails, return null\n return null;\n }\n}\n","import { CheckProvider, CheckProviderConfig, ExecutionContext } from './check-provider.interface';\nimport { PRInfo } from '../pr-analyzer';\nimport { ReviewSummary } from '../reviewer';\nimport { HumanInputRequest } from '../types/config';\nimport { interactivePrompt, simplePrompt } from '../utils/interactive-prompt';\nimport { tryReadStdin } from '../utils/stdin-reader';\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Human input check provider that pauses workflow to request user input.\n *\n * Supports four modes:\n * 1. CLI with --message argument (inline or file path)\n * 2. CLI with piped stdin\n * 3. CLI interactive mode (beautiful terminal UI)\n * 4. SDK mode with onHumanInput hook\n *\n * Example config:\n * ```yaml\n * checks:\n * approval:\n * type: human-input\n * prompt: \"Do you approve? (yes/no)\"\n * allow_empty: false\n * timeout: 300000\n * ```\n */\nexport class HumanInputCheckProvider extends CheckProvider {\n /**\n * @deprecated Use ExecutionContext.cliMessage instead\n * Kept for backward compatibility\n */\n private static cliMessage: string | undefined;\n\n /**\n * @deprecated Use ExecutionContext.hooks instead\n * Kept for backward compatibility\n */\n private static hooks: { onHumanInput?: (request: HumanInputRequest) => Promise<string> } = {};\n\n /**\n * Set the CLI message value (from --message argument)\n * @deprecated Use ExecutionContext.cliMessage instead\n */\n static setCLIMessage(message: string | undefined): void {\n HumanInputCheckProvider.cliMessage = message;\n }\n\n /**\n * Get the current CLI message value\n * @deprecated Use ExecutionContext.cliMessage instead\n */\n static getCLIMessage(): string | undefined {\n return HumanInputCheckProvider.cliMessage;\n }\n\n /**\n * Set hooks for SDK mode\n * @deprecated Use ExecutionContext.hooks instead\n */\n static setHooks(hooks: { onHumanInput?: (request: HumanInputRequest) => Promise<string> }): void {\n HumanInputCheckProvider.hooks = hooks;\n }\n\n getName(): string {\n return 'human-input';\n }\n\n getDescription(): string {\n return 'Prompts for human input during workflow execution (CLI interactive or SDK hook)';\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 'human-input'\n if (cfg.type !== 'human-input') {\n return false;\n }\n\n // Prompt is required\n if (!cfg.prompt || typeof cfg.prompt !== 'string') {\n console.error('human-input check requires a \"prompt\" field');\n return false;\n }\n\n return true;\n }\n\n /**\n * Check if a string looks like a file path\n */\n private looksLikePath(str: string): boolean {\n return str.includes('/') || str.includes('\\\\');\n }\n\n /**\n * Sanitize user input to prevent injection attacks in dependent checks\n * Removes potentially dangerous characters while preserving useful input\n */\n private sanitizeInput(input: string): string {\n // Remove null bytes (C-string injection)\n let sanitized = input.replace(/\\0/g, '');\n\n // Remove control characters except newlines and tabs\n sanitized = sanitized.replace(/[\\x00-\\x08\\x0B-\\x0C\\x0E-\\x1F\\x7F]/g, '');\n\n // Limit length to prevent memory issues (100KB max)\n const maxLength = 100 * 1024;\n if (sanitized.length > maxLength) {\n sanitized = sanitized.substring(0, maxLength);\n }\n\n return sanitized;\n }\n\n /**\n * Try to read message from file if it exists\n * Validates path to prevent directory traversal attacks\n */\n private async tryReadFile(filePath: string): Promise<string | null> {\n try {\n // Handle both absolute and relative paths\n const absolutePath = path.isAbsolute(filePath)\n ? filePath\n : path.resolve(process.cwd(), filePath);\n\n // Normalize path to resolve .. and . components\n const normalizedPath = path.normalize(absolutePath);\n\n // Security: Prevent path traversal attacks\n // Only allow files within current working directory or its subdirectories\n const cwd = process.cwd();\n if (!normalizedPath.startsWith(cwd + path.sep) && normalizedPath !== cwd) {\n // Path is outside working directory\n return null;\n }\n\n // Use async file access check instead of sync existsSync\n try {\n await fs.promises.access(normalizedPath, fs.constants.R_OK);\n const stats = await fs.promises.stat(normalizedPath);\n\n // Only read regular files, not directories or special files\n if (!stats.isFile()) {\n return null;\n }\n\n const content = await fs.promises.readFile(normalizedPath, 'utf-8');\n return content.trim();\n } catch {\n // File doesn't exist or isn't readable\n return null;\n }\n } catch {\n // If file read fails, treat as literal string\n }\n return null;\n }\n\n /**\n * Get user input through various methods\n */\n private async getUserInput(\n checkName: string,\n config: CheckProviderConfig,\n context?: ExecutionContext\n ): Promise<string> {\n const prompt = config.prompt || 'Please provide input:';\n const placeholder = (config.placeholder as string | undefined) || 'Enter your response...';\n const allowEmpty = (config.allow_empty as boolean | undefined) ?? false;\n const multiline = (config.multiline as boolean | undefined) ?? false;\n const timeout = config.timeout ? config.timeout * 1000 : undefined; // Convert to ms\n const defaultValue = config.default as string | undefined;\n\n // Get cliMessage from context (new way) or static property (backward compat)\n const cliMessage = context?.cliMessage ?? HumanInputCheckProvider.cliMessage;\n\n // Priority 1: Check for --message CLI argument\n if (cliMessage !== undefined) {\n const message = cliMessage;\n\n // Check if it looks like a path and try to read the file\n if (this.looksLikePath(message)) {\n const fileContent = await this.tryReadFile(message);\n if (fileContent !== null) {\n return fileContent;\n }\n }\n\n // Otherwise, use as literal message\n return message;\n }\n\n // Priority 2: Check for piped stdin\n const stdinInput = await tryReadStdin(timeout);\n if (stdinInput !== null && stdinInput.length > 0) {\n return stdinInput;\n }\n\n // Priority 3: SDK hook mode\n // Get hooks from context (new way) or static property (backward compat)\n const hooks = context?.hooks ?? HumanInputCheckProvider.hooks;\n\n if (hooks?.onHumanInput) {\n const request: HumanInputRequest = {\n checkId: checkName,\n prompt,\n placeholder,\n allowEmpty,\n multiline,\n timeout,\n default: defaultValue,\n };\n\n try {\n const result = await hooks.onHumanInput(request);\n return result;\n } catch (error) {\n throw new Error(\n `Hook onHumanInput failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n // Priority 4: Interactive terminal prompt (if TTY available)\n if (process.stdin.isTTY) {\n try {\n const result = await interactivePrompt({\n prompt,\n placeholder,\n multiline,\n timeout,\n defaultValue,\n allowEmpty,\n });\n return result;\n } catch (error) {\n throw new Error(\n `Interactive prompt failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n // Priority 5: Simple prompt (fallback for non-TTY)\n try {\n const result = await simplePrompt(prompt);\n if (!result && !allowEmpty && !defaultValue) {\n throw new Error('Empty input not allowed');\n }\n return result || defaultValue || '';\n } catch (error) {\n throw new Error(\n `Simple prompt failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n\n async execute(\n _prInfo: PRInfo,\n config: CheckProviderConfig,\n _dependencyResults?: Map<string, ReviewSummary>,\n context?: ExecutionContext\n ): Promise<ReviewSummary> {\n const checkName = config.checkName || 'human-input';\n\n try {\n // Get user input (pass context for non-static state)\n const userInput = await this.getUserInput(checkName, config, context);\n\n // Sanitize input to prevent injection attacks in dependent checks\n const sanitizedInput = this.sanitizeInput(userInput);\n\n // Return the input as the check output (stored in output field for dependent checks)\n return {\n issues: [],\n output: sanitizedInput,\n } as ReviewSummary & { output: string };\n } catch (error) {\n // If there's an error getting input, return an error issue\n return {\n issues: [\n {\n file: '',\n line: 0,\n ruleId: 'human-input-error',\n message: `Failed to get user input: ${\n error instanceof Error ? error.message : String(error)\n }`,\n severity: 'error',\n category: 'logic',\n },\n ],\n };\n }\n }\n\n getSupportedConfigKeys(): string[] {\n return [\n 'type',\n 'prompt',\n 'placeholder',\n 'allow_empty',\n 'multiline',\n 'timeout',\n 'default',\n 'depends_on',\n 'on',\n 'if',\n 'group',\n ];\n }\n\n async isAvailable(): Promise<boolean> {\n // Human input provider is always available\n // It will fall back to simple prompts if interactive mode isn't available\n return true;\n }\n\n getRequirements(): string[] {\n return [\n 'No external dependencies required',\n 'Works in CLI mode with --message argument, piped stdin, or interactive prompts',\n 'SDK mode requires onHumanInput hook to be configured',\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';\nimport { McpCheckProvider } from './mcp-check-provider';\nimport { HumanInputCheckProvider } from './human-input-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 this.register(new HumanInputCheckProvider());\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 // Try to register McpCheckProvider - it may fail if dependencies are missing\n try {\n this.register(new McpCheckProvider());\n } catch (error) {\n console.error(\n `Warning: Failed to register McpCheckProvider: ${\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 { createSecureSandbox } from './utils/sandbox';\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 return createSecureSandbox();\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 // 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\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 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 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';\nimport { generateFooter } from './footer';\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(generateFooter());\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 { createSecureSandbox, compileAndRun } from './utils/sandbox';\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, withActiveSpan } from './telemetry/trace-helpers';\nimport { addFailIfTriggered } from './telemetry/metrics';\nimport { trace, context as otContext } from '@opentelemetry/api';\nimport { captureForEachState, captureStateSnapshot } from './telemetry/state-capture';\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 // Execution context for providers (CLI message, hooks, etc.)\n private executionContext?: import('./providers/check-provider.interface').ExecutionContext;\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 * Set execution context for providers (CLI message, hooks, etc.)\n * This allows passing state without using static properties\n */\n setExecutionContext(\n context: import('./providers/check-provider.interface').ExecutionContext\n ): void {\n this.executionContext = context;\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 this.routingSandbox = createSecureSandbox();\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 prelude = `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 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 code = `${prelude}\\n${expr}`;\n const result = compileAndRun<unknown>(\n sandbox,\n code,\n { scope },\n { injectLog: false, wrapFunction: true }\n );\n const res = Array.isArray(result) ? result : result ? [result] : [];\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 prelude2 = `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 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 code2 = `${prelude2}\\n${expr}`;\n const res = compileAndRun<string | null>(\n sandbox,\n code2,\n { scope },\n { injectLog: false, wrapFunction: true }\n );\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 // Merge sessionInfo with execution context for inline execution\n const inlineContext: import('./providers/check-provider.interface').ExecutionContext = {\n ...sessionInfo,\n ...this.executionContext,\n };\n r = await prov.execute(prInfoForInline, provCfg, depResults, inlineContext);\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 // Merge sessionInfo with execution context\n const context: import('./providers/check-provider.interface').ExecutionContext = {\n ...sessionInfo,\n ...this.executionContext,\n };\n // Execute check within a span for telemetry while passing merged execution context\n const res = await withActiveSpan(\n `visor.check.${checkName}`,\n {\n 'visor.check.id': checkName,\n 'visor.check.type': providerConfig.type || 'ai',\n 'visor.check.attempt': attempt,\n },\n async () => {\n try {\n return await provider.execute(prInfo, providerConfig, dependencyResults, context);\n } finally {\n try {\n emitNdjsonSpanWithEvents('visor.check', { 'visor.check.id': checkName }, [\n { name: 'check.started' },\n { name: 'check.completed' },\n ]);\n } catch {}\n }\n }\n );\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 _pauseGate?: () => Promise<void>\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 _pauseGate\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 _pauseGate\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 _pauseGate?: () => Promise<void>\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 checkName, // propagate for fallback NDJSON attribution\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 pauseGate?: () => Promise<void>\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 pauseGate\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 pauseGate?: () => Promise<void>\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 if (pauseGate) {\n try {\n await pauseGate();\n } catch {\n return { checkName, error: '__STOP__', result: null, skipped: true };\n }\n }\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 (\n !hasFatalFailure &&\n config &&\n (config.fail_if || config.checks![depId]?.fail_if)\n ) {\n try {\n hasFatalFailure = await this.failIfTriggered(depId, depRes, config, results);\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 prInfo,\n results\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 if (pauseGate) {\n try {\n await pauseGate();\n } catch {\n throw new Error('__STOP__');\n }\n }\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\n // Capture forEach state in active OTEL span\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n captureForEachState(span, forEachItems, itemIndex, item);\n }\n } catch {\n // Ignore telemetry errors\n }\n\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 prInfo,\n results\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 prInfo,\n results\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(\n node,\n nodeItemRes,\n config,\n prInfo,\n results\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 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(\n parent,\n rForEval,\n config,\n prInfo,\n results\n );\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 prInfo,\n results\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 prInfo,\n results\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 // Stop signal propagation\n if (result.status === 'fulfilled' && (result.value as any)?.error === '__STOP__') {\n shouldStopExecution = true;\n break;\n }\n if (\n result.status === 'rejected' &&\n result.reason instanceof Error &&\n (result.reason as Error).message === '__STOP__'\n ) {\n shouldStopExecution = true;\n break;\n }\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\n // Capture state snapshot after check completion\n try {\n const span = trace.getSpan(otContext.active());\n if (span) {\n const allOutputs: Record<string, unknown> = {};\n results.forEach((result, name) => {\n if ((result as any).output !== undefined) {\n allOutputs[name] = (result as any).output;\n }\n });\n const memoryStore = MemoryStore.getInstance();\n const memoryData = await memoryStore.getAll();\n captureStateSnapshot(span, checkName, allOutputs, memoryData);\n }\n } catch {\n // Ignore telemetry errors\n }\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 previousOutputs?: Record<string, ReviewSummary> | Map<string, ReviewSummary>\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 // Convert previousOutputs Map to Record if needed\n const outputsRecord: Record<string, ReviewSummary> | undefined = previousOutputs\n ? previousOutputs instanceof Map\n ? Object.fromEntries(previousOutputs.entries())\n : previousOutputs\n : undefined;\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 outputsRecord\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 outputsRecord\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 previousOutputs?: Record<string, ReviewSummary> | Map<string, ReviewSummary>\n ): Promise<boolean> {\n if (!config) return false;\n const failures = await this.evaluateFailureConditions(\n checkName,\n result,\n config,\n undefined,\n previousOutputs\n );\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","resolve","fs","context","triggeringComment","fs","path","agentAny","schemaPath","result","resolve","CheckExecutionEngine","fs","path","normalize","path","fs","path","status","path","resolve","fs","path","content","lines","fs","path","path","fs","emitNdjsonSpanWithEvents","trace","otContext","trace","otContext","fs","path","path","fs","trace","otContext","trace","otContext","emitNdjsonSpanWithEvents","arr","resolve","resolve","fs","path","emitNdjsonSpanWithEvents","checkName","normalize","log","issues","trace","otContext","resolve","log","focus","path","createExtendedLiquid","fs","trace","otContext","directDeps","agg","validation","result","emitNdjsonSpanWithEvents"]}