@probelabs/visor 0.1.147-ee → 0.1.148
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frontends/github-frontend.d.ts +2 -1
- package/dist/frontends/github-frontend.d.ts.map +1 -1
- package/dist/index.js +747 -1831
- package/dist/output/traces/run-2026-03-02T18-32-11-359Z.ndjson +138 -0
- package/dist/output/traces/run-2026-03-02T18-32-55-702Z.ndjson +1442 -0
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/scheduler/schedule-tool.d.ts.map +1 -1
- package/dist/scheduler/scheduler.d.ts +5 -0
- package/dist/scheduler/scheduler.d.ts.map +1 -1
- package/dist/sdk/{check-provider-registry-LBYIKFYM.mjs → check-provider-registry-35BPTY4W.mjs} +5 -6
- package/dist/sdk/{check-provider-registry-SCPM6DIT.mjs → check-provider-registry-DVQDGTOE.mjs} +5 -6
- package/dist/sdk/check-provider-registry-KHPY6LB4.mjs +29 -0
- package/dist/sdk/{chunk-4F5UVWAN.mjs → chunk-62TNF5PJ.mjs} +2 -2
- package/dist/sdk/{chunk-4F5UVWAN.mjs.map → chunk-62TNF5PJ.mjs.map} +1 -1
- package/dist/sdk/{chunk-PNZH3JSI.mjs → chunk-6N6JRWCW.mjs} +2743 -277
- package/dist/sdk/chunk-6N6JRWCW.mjs.map +1 -0
- package/dist/sdk/{chunk-FBJ7MC7R.mjs → chunk-AYQE4JCU.mjs} +3 -3
- package/dist/sdk/chunk-CISJ6DJW.mjs +1502 -0
- package/dist/sdk/chunk-CISJ6DJW.mjs.map +1 -0
- package/dist/sdk/chunk-EGUHXVWS.mjs +443 -0
- package/dist/sdk/chunk-EGUHXVWS.mjs.map +1 -0
- package/dist/sdk/{chunk-EWGX7LI7.mjs → chunk-H4AYMOAT.mjs} +2742 -276
- package/dist/sdk/chunk-H4AYMOAT.mjs.map +1 -0
- package/dist/sdk/chunk-IF2UD2KS.mjs +43159 -0
- package/dist/sdk/chunk-IF2UD2KS.mjs.map +1 -0
- package/dist/sdk/{chunk-V2QW6ECX.mjs → chunk-RJLJUTSU.mjs} +2 -2
- package/dist/sdk/chunk-S2YO4ZE3.mjs +739 -0
- package/dist/sdk/chunk-S2YO4ZE3.mjs.map +1 -0
- package/dist/sdk/{failure-condition-evaluator-FHNZL2US.mjs → failure-condition-evaluator-I6QWFKV3.mjs} +3 -3
- package/dist/sdk/failure-condition-evaluator-IVCTD4BZ.mjs +17 -0
- package/dist/sdk/{github-frontend-47EU2HBY.mjs → github-frontend-2MC77L7F.mjs} +16 -4
- package/dist/sdk/github-frontend-2MC77L7F.mjs.map +1 -0
- package/dist/sdk/github-frontend-DFT5G32K.mjs +1368 -0
- package/dist/sdk/github-frontend-DFT5G32K.mjs.map +1 -0
- package/dist/sdk/{host-GVR4UGZ3.mjs → host-4F6I3ZXN.mjs} +2 -2
- package/dist/sdk/{host-KGN5OIAM.mjs → host-H7IX4GBK.mjs} +2 -2
- package/dist/sdk/{routing-CZ36LVVS.mjs → routing-LU5PAREW.mjs} +4 -4
- package/dist/sdk/routing-UT3BXBXH.mjs +25 -0
- package/dist/sdk/schedule-tool-CONR4VW3.mjs +35 -0
- package/dist/sdk/schedule-tool-K3GQXCBN.mjs +35 -0
- package/dist/sdk/schedule-tool-SBXAEBDD.mjs +35 -0
- package/dist/sdk/{schedule-tool-handler-KFYNV7HL.mjs → schedule-tool-handler-GFQCJAVZ.mjs} +5 -6
- package/dist/sdk/schedule-tool-handler-GFQCJAVZ.mjs.map +1 -0
- package/dist/sdk/{schedule-tool-handler-E7XHMU5G.mjs → schedule-tool-handler-R7PG3VMR.mjs} +5 -6
- package/dist/sdk/schedule-tool-handler-R7PG3VMR.mjs.map +1 -0
- package/dist/sdk/schedule-tool-handler-YUC6CAXX.mjs +39 -0
- package/dist/sdk/schedule-tool-handler-YUC6CAXX.mjs.map +1 -0
- package/dist/sdk/sdk.js +1573 -1629
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -5
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/{trace-helpers-EHDZ42HH.mjs → trace-helpers-6ROJR7N3.mjs} +2 -2
- package/dist/sdk/trace-helpers-6ROJR7N3.mjs.map +1 -0
- package/dist/sdk/trace-helpers-J463EU4B.mjs +25 -0
- package/dist/sdk/trace-helpers-J463EU4B.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-5453TW65.mjs → workflow-check-provider-DYSO3PML.mjs} +5 -6
- package/dist/sdk/workflow-check-provider-DYSO3PML.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-BSUSPFOF.mjs → workflow-check-provider-FIFFQDQU.mjs} +5 -6
- package/dist/sdk/workflow-check-provider-FIFFQDQU.mjs.map +1 -0
- package/dist/sdk/workflow-check-provider-GJNGTS3F.mjs +29 -0
- package/dist/sdk/workflow-check-provider-GJNGTS3F.mjs.map +1 -0
- package/dist/state-machine/context/build-engine-context.d.ts.map +1 -1
- package/dist/traces/run-2026-03-02T18-32-11-359Z.ndjson +138 -0
- package/dist/traces/run-2026-03-02T18-32-55-702Z.ndjson +1442 -0
- package/dist/utils/tool-resolver.d.ts.map +1 -1
- package/dist/utils/workspace-manager.d.ts +31 -8
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/dist/utils/worktree-manager.d.ts +6 -0
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/sdk/chunk-EWGX7LI7.mjs.map +0 -1
- package/dist/sdk/chunk-PNZH3JSI.mjs.map +0 -1
- package/dist/sdk/chunk-XKCER23W.mjs +0 -1490
- package/dist/sdk/chunk-XKCER23W.mjs.map +0 -1
- package/dist/sdk/github-frontend-47EU2HBY.mjs.map +0 -1
- package/dist/sdk/knex-store-HPXJILBL.mjs +0 -411
- package/dist/sdk/knex-store-HPXJILBL.mjs.map +0 -1
- package/dist/sdk/loader-YSRMVXC3.mjs +0 -89
- package/dist/sdk/loader-YSRMVXC3.mjs.map +0 -1
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs +0 -655
- package/dist/sdk/opa-policy-engine-S2S2ULEI.mjs.map +0 -1
- package/dist/sdk/schedule-tool-2COUUTF7.mjs +0 -18
- package/dist/sdk/validator-XTZJZZJH.mjs +0 -134
- package/dist/sdk/validator-XTZJZZJH.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-LBYIKFYM.mjs.map → check-provider-registry-35BPTY4W.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-SCPM6DIT.mjs.map → check-provider-registry-DVQDGTOE.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-FHNZL2US.mjs.map → check-provider-registry-KHPY6LB4.mjs.map} +0 -0
- /package/dist/sdk/{chunk-FBJ7MC7R.mjs.map → chunk-AYQE4JCU.mjs.map} +0 -0
- /package/dist/sdk/{chunk-V2QW6ECX.mjs.map → chunk-RJLJUTSU.mjs.map} +0 -0
- /package/dist/sdk/{routing-CZ36LVVS.mjs.map → failure-condition-evaluator-I6QWFKV3.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-2COUUTF7.mjs.map → failure-condition-evaluator-IVCTD4BZ.mjs.map} +0 -0
- /package/dist/sdk/{host-GVR4UGZ3.mjs.map → host-4F6I3ZXN.mjs.map} +0 -0
- /package/dist/sdk/{host-KGN5OIAM.mjs.map → host-H7IX4GBK.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-E7XHMU5G.mjs.map → routing-LU5PAREW.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-KFYNV7HL.mjs.map → routing-UT3BXBXH.mjs.map} +0 -0
- /package/dist/sdk/{trace-helpers-EHDZ42HH.mjs.map → schedule-tool-CONR4VW3.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-5453TW65.mjs.map → schedule-tool-K3GQXCBN.mjs.map} +0 -0
- /package/dist/sdk/{workflow-check-provider-BSUSPFOF.mjs.map → schedule-tool-SBXAEBDD.mjs.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/failure-condition-evaluator.ts"],"sourcesContent":["/**\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 workflowInputs?: Record<string, unknown>;\n /** Current step's output for guarantee evaluation */\n output?: unknown;\n /** Conversation context for TUI/CLI/Slack messages */\n conversation?: {\n transport?: string;\n thread?: { id: string };\n messages?: Array<{ role: string; text: string; timestamp: string }>;\n current?: { role: string; text: string; timestamp: string };\n attributes?: Record<string, unknown>;\n };\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 // Workflow inputs (for workflows)\n inputs: contextData?.workflowInputs || {},\n\n // Output property: use provided output for guarantee evaluation, or empty for if conditions\n output:\n contextData?.output !== undefined &&\n contextData.output !== null &&\n typeof contextData.output === 'object'\n ? (contextData.output as Record<string, unknown>)\n : { issues: [] },\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 // Conversation context (for TUI/CLI/Slack)\n conversation: contextData?.conversation,\n };\n\n try {\n const res = this.evaluateExpression(expression, context);\n try {\n if (process.env.VISOR_DEBUG === 'true') {\n // Debug if-eval output (only when VISOR_DEBUG enabled)\n const outputKeys = Object.keys(context.outputs || {});\n console.error(\n `[if-eval] check=${checkName} expr=\"${expression}\" result=${String(res)} outputKeys=[${outputKeys.join(',')}]`\n );\n }\n } catch {}\n return res;\n } catch (error) {\n console.warn(`Failed to evaluate if expression for check '${checkName}': ${error}`);\n // Fail-secure: do not run the check on evaluation errors\n return false;\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 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 // Ensure issues is an array - it might be a JSON string from workflow outputs\n let issues = output.issues || [];\n if (typeof issues === 'string') {\n try {\n issues = JSON.parse(issues);\n } catch {\n issues = [];\n }\n }\n if (!Array.isArray(issues)) {\n issues = [];\n }\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 // Do not mutate output shape here. Output contracts are defined by providers and\n // workflow outputs. Tests and expressions should rely on those schemas directly.\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 inputs = context.inputs || {};\n const debugData = context.debug || null;\n const conversation = context.conversation || 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 inputs,\n // Conversation context (TUI/CLI/Slack)\n conversation,\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 exec = this.sandbox.compile(`return (${raw});`);\n } catch {\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 by evaluateSingleCondition\n // and properly populate the error field in the result\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"],"mappings":"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","names":["checkName","issues"]}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
FailureConditionEvaluator,
|
|
3
3
|
init_failure_condition_evaluator
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-S2YO4ZE3.mjs";
|
|
5
|
+
import "./chunk-EGUHXVWS.mjs";
|
|
6
6
|
import "./chunk-JL7JXCET.mjs";
|
|
7
7
|
import "./chunk-25IC7KXZ.mjs";
|
|
8
8
|
import "./chunk-LW3INISN.mjs";
|
|
@@ -14,4 +14,4 @@ init_failure_condition_evaluator();
|
|
|
14
14
|
export {
|
|
15
15
|
FailureConditionEvaluator
|
|
16
16
|
};
|
|
17
|
-
//# sourceMappingURL=failure-condition-evaluator-
|
|
17
|
+
//# sourceMappingURL=failure-condition-evaluator-I6QWFKV3.mjs.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FailureConditionEvaluator,
|
|
3
|
+
init_failure_condition_evaluator
|
|
4
|
+
} from "./chunk-RJLJUTSU.mjs";
|
|
5
|
+
import "./chunk-62TNF5PJ.mjs";
|
|
6
|
+
import "./chunk-JL7JXCET.mjs";
|
|
7
|
+
import "./chunk-25IC7KXZ.mjs";
|
|
8
|
+
import "./chunk-LW3INISN.mjs";
|
|
9
|
+
import "./chunk-VPC3QSPW.mjs";
|
|
10
|
+
import "./chunk-SZXICFQ3.mjs";
|
|
11
|
+
import "./chunk-UCMJJ3IM.mjs";
|
|
12
|
+
import "./chunk-J7LXIPZS.mjs";
|
|
13
|
+
init_failure_condition_evaluator();
|
|
14
|
+
export {
|
|
15
|
+
FailureConditionEvaluator
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=failure-condition-evaluator-IVCTD4BZ.mjs.map
|
|
@@ -9,8 +9,8 @@ import {
|
|
|
9
9
|
import {
|
|
10
10
|
failure_condition_evaluator_exports,
|
|
11
11
|
init_failure_condition_evaluator
|
|
12
|
-
} from "./chunk-
|
|
13
|
-
import "./chunk-
|
|
12
|
+
} from "./chunk-S2YO4ZE3.mjs";
|
|
13
|
+
import "./chunk-EGUHXVWS.mjs";
|
|
14
14
|
import "./chunk-JL7JXCET.mjs";
|
|
15
15
|
import "./chunk-25IC7KXZ.mjs";
|
|
16
16
|
import "./chunk-LW3INISN.mjs";
|
|
@@ -834,6 +834,7 @@ var init_github_frontend = __esm({
|
|
|
834
834
|
// Minimum delay between updates (public for testing)
|
|
835
835
|
// Cache of created GitHub comment IDs per group to handle API eventual consistency
|
|
836
836
|
createdCommentGithubIds = /* @__PURE__ */ new Map();
|
|
837
|
+
_stopped = false;
|
|
837
838
|
start(ctx) {
|
|
838
839
|
const log = ctx.logger;
|
|
839
840
|
const bus = ctx.eventBus;
|
|
@@ -978,9 +979,19 @@ var init_github_frontend = __esm({
|
|
|
978
979
|
})
|
|
979
980
|
);
|
|
980
981
|
}
|
|
981
|
-
stop() {
|
|
982
|
+
async stop() {
|
|
983
|
+
this._stopped = true;
|
|
982
984
|
for (const s of this.subs) s.unsubscribe();
|
|
983
985
|
this.subs = [];
|
|
986
|
+
if (this._timer) {
|
|
987
|
+
clearTimeout(this._timer);
|
|
988
|
+
this._timer = null;
|
|
989
|
+
}
|
|
990
|
+
this._pendingIds.clear();
|
|
991
|
+
const pending = Array.from(this.updateLocks.values());
|
|
992
|
+
if (pending.length > 0) {
|
|
993
|
+
await Promise.allSettled(pending);
|
|
994
|
+
}
|
|
984
995
|
}
|
|
985
996
|
async buildFullBody(ctx, group) {
|
|
986
997
|
const header = this.renderThreadHeader(ctx, group);
|
|
@@ -1058,6 +1069,7 @@ ${end}`);
|
|
|
1058
1069
|
*/
|
|
1059
1070
|
async performGroupedCommentUpdate(ctx, comments, group, changedIds) {
|
|
1060
1071
|
try {
|
|
1072
|
+
if (this._stopped) return;
|
|
1061
1073
|
if (!ctx.run.repo || !ctx.run.pr) return;
|
|
1062
1074
|
const config = ctx.config;
|
|
1063
1075
|
const prCommentEnabled = config?.output?.pr_comment?.enabled !== false;
|
|
@@ -1353,4 +1365,4 @@ init_github_frontend();
|
|
|
1353
1365
|
export {
|
|
1354
1366
|
GitHubFrontend
|
|
1355
1367
|
};
|
|
1356
|
-
//# sourceMappingURL=github-frontend-
|
|
1368
|
+
//# sourceMappingURL=github-frontend-2MC77L7F.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/footer.ts","../../src/github-check-service.ts","../../src/github-comments.ts","../../src/frontends/github-frontend.ts"],"sourcesContent":["/**\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","/**\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 engine_mode?: 'legacy' | 'state-machine'; // M4: Track which engine mode was used\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 * M4: Includes engine_mode metadata in summary\n */\n async createCheckRun(\n options: CheckRunOptions,\n summary?: CheckRunSummary\n ): Promise<{ id: number; url: string }> {\n try {\n // M4: Add engine mode metadata to summary if provided\n const enhancedSummary =\n summary && options.engine_mode\n ? {\n ...summary,\n summary: `${summary.summary}\\n\\n_Engine: ${options.engine_mode}_`,\n }\n : summary;\n\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: enhancedSummary\n ? {\n title: enhancedSummary.title,\n summary: enhancedSummary.summary,\n text: enhancedSummary.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) {\n const icon = this.getSeverityEmoji(condition.severity);\n sections.push(` - Severity: ${icon} ${condition.severity}`);\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 `### ${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.getSeverityEmoji(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 severity (allowed; step/category emojis are removed)\n */\n private getSeverityEmoji(severity: string): string {\n const iconMap: Record<string, string> = {\n critical: '🚨',\n error: '❌',\n warning: '⚠️',\n info: 'ℹ️',\n };\n return iconMap[String(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 { Octokit } from '@octokit/rest';\nimport { generateShortHumanId } from './utils/human-id';\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 /** Cached GitHub comment ID to use for updates when listComments may not return it yet (eventual consistency) */\n cachedGithubCommentId?: number;\n } = {}\n ): Promise<Comment> {\n const {\n commentId = this.generateCommentId(),\n triggeredBy = 'unknown',\n allowConcurrentUpdates = false,\n commitSha,\n cachedGithubCommentId,\n } = options;\n\n return this.withRetry(async () => {\n // First try to find the comment via listComments API\n let existingComment = await this.findVisorComment(owner, repo, prNumber, commentId);\n\n // If not found but we have a cached GitHub ID, try to fetch it directly\n // This handles GitHub API eventual consistency where newly created comments\n // may not appear in listComments immediately\n if (!existingComment && cachedGithubCommentId) {\n try {\n const cachedComment = await this.octokit.rest.issues.getComment({\n owner,\n repo,\n comment_id: cachedGithubCommentId,\n });\n if (cachedComment.data && this.isVisorComment(cachedComment.data.body || '', commentId)) {\n existingComment = cachedComment.data as Comment;\n logger.debug(\n `[github-comments] Found comment via cached ID ${cachedGithubCommentId} (not visible in listComments yet)`\n );\n }\n } catch (_e) {\n // Comment may have been deleted, continue with create flow\n logger.debug(\n `[github-comments] Cached comment ${cachedGithubCommentId} not found, will create new`\n );\n }\n }\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 title = 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 generateShortHumanId();\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 computed =\n this.retryConfig.baseDelay * Math.pow(this.retryConfig.backoffFactor, attempt);\n const delay =\n computed > this.retryConfig.maxDelay\n ? Math.max(0, this.retryConfig.maxDelay - 1)\n : computed;\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 => {\n const t = setTimeout(resolve, ms);\n if (typeof (t as any).unref === 'function') {\n try {\n (t as any).unref();\n } catch {}\n }\n });\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 // Emoji helper removed: plain titles are used in group headers\n\n /**\n * Format group title with score and issue count\n */\n private formatGroupTitle(groupKey: string, score: number, issuesFound: number): string {\n const formattedScore = Math.round(score);\n return `${groupKey} Review (Score: ${formattedScore}/100)${issuesFound > 0 ? ` - ${issuesFound} issues found` : ''}`;\n }\n}\n","import type { Frontend, FrontendContext } from './host';\nimport { logger } from '../logger';\nimport { extractTextFromJson } from '../utils/json-text-extractor';\n\n/**\n * Skeleton GitHub frontend.\n * - Subscribes to engine events via EventBus when present\n * - Maps key events to debug logs for now (no side effects)\n * - Real implementation will upsert checks and manage grouped PR comments\n */\ntype SectionState = {\n status: 'queued' | 'in_progress' | 'completed' | 'errored';\n conclusion?: 'success' | 'failure' | 'neutral' | 'skipped';\n issues?: number;\n lastUpdated: string;\n error?: string;\n content?: string;\n};\n\nexport class GitHubFrontend implements Frontend {\n public readonly name = 'github';\n private subs: Array<{ unsubscribe(): void }> = [];\n private checkRunIds: Map<string, number> = new Map();\n private revision = 0;\n private cachedCommentId?: string; // legacy single-thread id (kept for compatibility)\n // Group → (checkId → SectionState)\n private stepStatusByGroup: Map<string, Map<string, SectionState>> = new Map();\n\n // Debounce/coalescing state\n private debounceMs: number = 400;\n private maxWaitMs: number = 2000;\n private _timer: NodeJS.Timeout | null = null;\n private _lastFlush: number = 0;\n private _pendingIds: Set<string> = new Set<string>();\n\n // Mutex for serializing comment updates per group\n private updateLocks: Map<string, Promise<void>> = new Map();\n public minUpdateDelayMs: number = 1000; // Minimum delay between updates (public for testing)\n // Cache of created GitHub comment IDs per group to handle API eventual consistency\n private createdCommentGithubIds: Map<string, number> = new Map();\n private _stopped = false;\n\n start(ctx: FrontendContext): void {\n const log = ctx.logger;\n const bus = ctx.eventBus;\n const octokit = (ctx as any).octokit;\n const repo = ctx.run.repo;\n const pr = ctx.run.pr;\n const headSha = ctx.run.headSha;\n\n // Determine capabilities separately for comments vs check runs\n const canPostComments = !!(octokit && repo && pr);\n const canPostChecks = !!(octokit && repo && pr && headSha);\n\n // Create helpers if possible\n const svc = canPostChecks\n ? new (require('../github-check-service').GitHubCheckService)(octokit)\n : null;\n const CommentManager = require('../github-comments').CommentManager;\n const comments = canPostComments ? new CommentManager(octokit) : null;\n\n const threadKey =\n repo && pr && headSha\n ? `${repo.owner}/${repo.name}#${pr}@${(headSha || '').substring(0, 7)}`\n : ctx.run.runId;\n this.cachedCommentId = `visor-thread-${threadKey}`;\n\n // CheckScheduled → create queued check run\n this.subs.push(\n bus.on('CheckScheduled', async (env: any) => {\n const ev = (env && env.payload) || env;\n try {\n if (!canPostChecks || !svc) return;\n if (this.checkRunIds.has(ev.checkId)) return; // already created\n // Update local model only (no comment yet; wait for content)\n const group = this.getGroupForCheck(ctx, ev.checkId);\n this.upsertSectionState(group, ev.checkId, {\n status: 'queued',\n lastUpdated: new Date().toISOString(),\n });\n // Do not call updateGroupedComment here — avoid \"queued\" placeholder comments\n const res = await svc.createCheckRun(\n {\n owner: repo!.owner,\n repo: repo!.name,\n head_sha: headSha!,\n name: `Visor: ${ev.checkId}`,\n external_id: `visor:${ctx.run.runId}:${ev.checkId}`,\n engine_mode: 'state-machine',\n },\n { title: `${ev.checkId}`, summary: 'Queued' }\n );\n this.checkRunIds.set(ev.checkId, res.id);\n } catch (e) {\n log.warn(\n `[github-frontend] createCheckRun failed for ${ev.checkId}: ${e instanceof Error ? e.message : e}`\n );\n }\n })\n );\n\n // CheckCompleted → complete check run and update grouped comment\n this.subs.push(\n bus.on('CheckCompleted', async (env: any) => {\n const ev = (env && env.payload) || env;\n try {\n // Complete check run (only when we have headSha)\n if (canPostChecks && svc && this.checkRunIds.has(ev.checkId)) {\n const id = this.checkRunIds.get(ev.checkId)!;\n const issues = Array.isArray(ev.result?.issues) ? ev.result.issues : [];\n // Evaluate failure conditions so GitHub conclusion reflects actual pass/fail\n const failureResults = await this.evaluateFailureResults(ctx, ev.checkId, ev.result);\n await svc.completeCheckRun(\n repo!.owner,\n repo!.name,\n id,\n ev.checkId,\n failureResults,\n issues,\n undefined,\n undefined,\n pr!,\n headSha!\n );\n }\n\n // Update grouped summary comment\n if (canPostComments && comments) {\n const count = Array.isArray(ev.result?.issues) ? ev.result.issues.length : 0;\n const failureResults = await this.evaluateFailureResults(ctx, ev.checkId, ev.result);\n const failed = Array.isArray(failureResults)\n ? failureResults.some((r: any) => r && r.failed)\n : false;\n const group = this.getGroupForCheck(ctx, ev.checkId);\n // Extract text from JSON-like content if template didn't unwrap it properly\n const rawContent = (ev?.result as any)?.content;\n const extractedContent = extractTextFromJson(rawContent);\n this.upsertSectionState(group, ev.checkId, {\n status: 'completed',\n conclusion: failed ? 'failure' : 'success',\n issues: count,\n lastUpdated: new Date().toISOString(),\n content: extractedContent,\n });\n await this.updateGroupedComment(ctx, comments, group, ev.checkId);\n }\n } catch (e) {\n log.warn(\n `[github-frontend] handle CheckCompleted failed: ${e instanceof Error ? e.message : e}`\n );\n }\n })\n );\n\n // CheckErrored → mark failure and update comment\n this.subs.push(\n bus.on('CheckErrored', async (env: any) => {\n const ev = (env && env.payload) || env;\n try {\n if (canPostChecks && svc && this.checkRunIds.has(ev.checkId)) {\n const id = this.checkRunIds.get(ev.checkId)!;\n await svc.completeCheckRun(\n repo!.owner,\n repo!.name,\n id,\n ev.checkId,\n [],\n [],\n ev.error?.message || 'Execution error',\n undefined,\n pr!,\n headSha!\n );\n }\n if (canPostComments && comments) {\n const group = this.getGroupForCheck(ctx, ev.checkId);\n this.upsertSectionState(group, ev.checkId, {\n status: 'errored',\n conclusion: 'failure',\n issues: 0,\n lastUpdated: new Date().toISOString(),\n error: ev.error?.message || 'Execution error',\n });\n await this.updateGroupedComment(ctx, comments, group, ev.checkId);\n }\n } catch (e) {\n log.warn(\n `[github-frontend] handle CheckErrored failed: ${e instanceof Error ? e.message : e}`\n );\n }\n })\n );\n\n // StateTransition: update summary on terminal\n this.subs.push(\n bus.on('StateTransition', async (env: any) => {\n const ev = (env && env.payload) || env;\n try {\n if (ev.to === 'Completed' || ev.to === 'Error') {\n if (canPostComments && comments) {\n for (const group of this.stepStatusByGroup.keys()) {\n await this.updateGroupedComment(ctx, comments, group);\n }\n }\n }\n } catch (e) {\n log.warn(\n `[github-frontend] handle StateTransition failed: ${e instanceof Error ? e.message : e}`\n );\n }\n })\n );\n }\n\n async stop(): Promise<void> {\n this._stopped = true;\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n this._pendingIds.clear();\n // Drain any in-flight updateGroupedComment operations so callers that\n // await stop() (e.g. FrontendsHost.stopAll) are guaranteed no async\n // work leaks after stop resolves.\n const pending = Array.from(this.updateLocks.values());\n if (pending.length > 0) {\n await Promise.allSettled(pending);\n }\n }\n\n private async buildFullBody(ctx: FrontendContext, group: string): Promise<string> {\n const header = this.renderThreadHeader(ctx, group);\n const sections = this.renderSections(ctx, group);\n return `${header}\n\n${sections}\n\n<!-- visor:thread-end key=\"${this.threadKeyFor(ctx)}\" -->`;\n }\n\n private threadKeyFor(ctx: FrontendContext): string {\n const r = ctx.run;\n return r.repo && r.pr && r.headSha\n ? `${r.repo.owner}/${r.repo.name}#${r.pr}@${(r.headSha || '').substring(0, 7)}`\n : r.runId;\n }\n\n private renderThreadHeader(ctx: FrontendContext, group: string): string {\n const header = {\n key: this.threadKeyFor(ctx),\n runId: ctx.run.runId,\n workflowId: ctx.run.workflowId,\n revision: this.revision,\n group,\n generatedAt: new Date().toISOString(),\n } as any;\n return `<!-- visor:thread=${JSON.stringify(header)} -->`;\n }\n\n private renderSections(ctx: FrontendContext, group: string): string {\n const lines: string[] = [];\n const groupMap = this.stepStatusByGroup.get(group) || new Map<string, SectionState>();\n for (const [checkId, st] of groupMap.entries()) {\n const start = `<!-- visor:section=${JSON.stringify({ id: checkId, revision: this.revision })} -->`;\n const end = `<!-- visor:section-end id=\"${checkId}\" -->`;\n const body =\n st.content && st.content.toString().trim().length > 0 ? st.content.toString().trim() : '';\n lines.push(`${start}\n${body}\n${end}`);\n }\n return lines.join('\\\\n\\\\n');\n }\n\n /**\n * Acquires a mutex lock for the given group and executes the update.\n * This ensures only one comment update happens at a time per group,\n * preventing race conditions where updates overwrite each other.\n *\n * Uses a proper queue-based mutex: each new caller chains onto the previous\n * lock, ensuring strict serialization even when multiple callers wait\n * simultaneously.\n */\n private async updateGroupedComment(\n ctx: FrontendContext,\n comments: any,\n group: string,\n changedIds?: string | string[]\n ) {\n // Get the current lock (if any) - we'll wait for it before proceeding\n const existingLock = this.updateLocks.get(group);\n\n // Create our own lock promise that we'll resolve when done\n // This must be created BEFORE awaiting existingLock to ensure proper chaining\n let resolveLock: () => void;\n const ourLock = new Promise<void>(resolve => {\n resolveLock = resolve;\n });\n\n // Immediately set our lock so subsequent callers will wait for us\n this.updateLocks.set(group, ourLock);\n\n try {\n // Wait for the previous lock to complete (if any)\n if (existingLock) {\n try {\n await existingLock;\n } catch (error) {\n logger.warn(\n `[github-frontend] Previous update for group ${group} failed: ${error instanceof Error ? error.message : error}`\n );\n // Continue with current update despite previous failure\n }\n }\n\n // Now perform our update\n await this.performGroupedCommentUpdate(ctx, comments, group, changedIds);\n } finally {\n // Clean up the lock from the map if it's still ours (no one else is waiting)\n if (this.updateLocks.get(group) === ourLock) {\n this.updateLocks.delete(group);\n }\n // Always resolve our lock - this allows the next waiter (if any) to proceed.\n // Even if another caller replaced our lock in the map, they're waiting on\n // our lock promise, so we must resolve it.\n resolveLock!();\n }\n }\n\n /**\n * Performs the actual comment update with delay enforcement.\n */\n private async performGroupedCommentUpdate(\n ctx: FrontendContext,\n comments: any,\n group: string,\n changedIds?: string | string[]\n ) {\n try {\n if (this._stopped) return;\n if (!ctx.run.repo || !ctx.run.pr) return;\n\n // Check if PR comments are enabled (default to true if not specified)\n const config = ctx.config as any;\n const prCommentEnabled = config?.output?.pr_comment?.enabled !== false;\n if (!prCommentEnabled) {\n logger.debug(\n `[github-frontend] PR comments disabled in config, skipping comment for group: ${group}`\n );\n return;\n }\n\n // Enforce minimum delay between updates to prevent API rate limiting\n const timeSinceLastFlush = Date.now() - this._lastFlush;\n if (this._lastFlush > 0 && timeSinceLastFlush < this.minUpdateDelayMs) {\n const delay = this.minUpdateDelayMs - timeSinceLastFlush;\n logger.debug(\n `[github-frontend] Waiting ${delay}ms before next update to prevent rate limiting`\n );\n await this.sleep(delay);\n }\n\n this.revision++;\n const commentId = this.commentIdForGroup(ctx, group);\n const mergedBody = await this.mergeIntoExistingBody(ctx, comments, group, changedIds);\n\n // Check if we have a cached GitHub comment ID from a previous creation\n // This handles GitHub API eventual consistency where listComments may not\n // immediately return a newly created comment\n const cachedGithubId = this.createdCommentGithubIds.get(commentId);\n\n const result = await comments.updateOrCreateComment(\n ctx.run.repo.owner,\n ctx.run.repo.name,\n ctx.run.pr,\n mergedBody,\n {\n commentId,\n triggeredBy: this.deriveTriggeredBy(ctx),\n commitSha: ctx.run.headSha,\n // Pass the cached GitHub comment ID if available\n cachedGithubCommentId: cachedGithubId,\n }\n );\n\n // Cache the GitHub comment ID for future updates\n if (result && result.id) {\n this.createdCommentGithubIds.set(commentId, result.id);\n }\n\n this._lastFlush = Date.now();\n } catch (e) {\n logger.debug(\n `[github-frontend] updateGroupedComment failed: ${e instanceof Error ? e.message : e}`\n );\n }\n }\n\n private deriveTriggeredBy(ctx: FrontendContext): string {\n const ev = (ctx.run as any).event || '';\n const actor = (ctx.run as any).actor;\n const commentEvents = new Set([\n 'issue_comment',\n 'issue_comment_created',\n 'pr_comment',\n 'comment',\n 'pull_request_review_comment',\n ]);\n if (commentEvents.has(ev) && actor) return actor;\n if (ev) return ev;\n return actor || 'unknown';\n }\n\n private async mergeIntoExistingBody(\n ctx: FrontendContext,\n comments: any,\n group: string,\n changedIds?: string | string[]\n ): Promise<string> {\n const repo = ctx.run.repo!;\n const pr = ctx.run.pr!;\n const existing = await comments.findVisorComment(\n repo.owner,\n repo.name,\n pr,\n this.commentIdForGroup(ctx, group)\n );\n if (!existing || !existing.body) return this.buildFullBody(ctx, group);\n const body = String(existing.body);\n const doc = this.parseSections(body);\n doc.header = {\n ...(doc.header || {}),\n key: this.threadKeyFor(ctx),\n revision: this.revision,\n group,\n } as any;\n if (changedIds) {\n const ids = Array.isArray(changedIds) ? changedIds : [changedIds];\n const fresh = this.renderSections(ctx, group);\n for (const id of ids) {\n const block = this.extractSectionById(fresh, id);\n if (block) doc.sections.set(id, block);\n }\n } else {\n // Add any missing new sections; leave others untouched to preserve text\n const fresh = this.renderSections(ctx, group);\n const map = this.stepStatusByGroup.get(group) || new Map<string, SectionState>();\n for (const [checkId] of map.entries()) {\n if (!doc.sections.has(checkId)) {\n const block = this.extractSectionById(fresh, checkId);\n if (block) doc.sections.set(checkId, block);\n }\n }\n }\n return this.serializeSections(doc);\n }\n\n private parseSections(body: string): { header?: any; sections: Map<string, string> } {\n const sections = new Map<string, string>();\n const headerRe = /<!--\\s*visor:thread=(\\{[\\s\\S]*?\\})\\s*-->/m;\n const startRe = /<!--\\s*visor:section=(\\{[\\s\\S]*?\\})\\s*-->/g;\n const endRe = /<!--\\s*visor:section-end\\s+id=\\\"([^\\\"]+)\\\"\\s*-->/g;\n\n // Helper: safely parse JSON and pick only allowed keys\n const safePick = (obj: any, allowed: Record<string, 'string' | 'number'>) => {\n if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return undefined;\n const out: Record<string, unknown> = Object.create(null);\n for (const [k, t] of Object.entries(allowed)) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n const v = (obj as any)[k];\n if (t === 'string' && typeof v === 'string') out[k] = v;\n else if (t === 'number' && typeof v === 'number' && Number.isFinite(v)) out[k] = v;\n }\n }\n return out;\n };\n\n const safeParse = (text: string) => {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n };\n\n let header: any;\n try {\n const h = headerRe.exec(body);\n if (h) {\n const parsed = safeParse(h[1]);\n const picked = safePick(parsed, {\n key: 'string',\n runId: 'string',\n workflowId: 'string',\n revision: 'number',\n group: 'string',\n generatedAt: 'string',\n });\n header = picked;\n }\n } catch {}\n\n let cursor = 0;\n while (true) {\n const s = startRe.exec(body);\n if (!s) break;\n const metaRaw = safeParse(s[1]);\n const meta = safePick(metaRaw, { id: 'string', revision: 'number' }) || { id: '' };\n const startIdx = startRe.lastIndex;\n endRe.lastIndex = startIdx;\n const e = endRe.exec(body);\n if (!e) break;\n const id =\n typeof (meta as any).id === 'string' && (meta as any).id\n ? String((meta as any).id)\n : String(e[1]);\n const content = body.substring(startIdx, e.index).trim();\n const block = `<!-- visor:section=${JSON.stringify(meta)} -->\\n${content}\\n<!-- visor:section-end id=\"${id}\" -->`;\n sections.set(id, block);\n cursor = endRe.lastIndex;\n startRe.lastIndex = cursor;\n }\n return { header, sections };\n }\n\n private serializeSections(doc: { header?: any; sections: Map<string, string> }): string {\n const header = `<!-- visor:thread=${JSON.stringify({ ...(doc.header || {}), generatedAt: new Date().toISOString() })} -->`;\n const blocks = Array.from(doc.sections.values()).join('\\n\\n');\n const key = (doc.header && (doc.header as any).key) || '';\n return `${header}\\n\\n${blocks}\\n\\n<!-- visor:thread-end key=\"${key}\" -->`;\n }\n\n private extractSectionById(rendered: string, id: string): string | undefined {\n const rx = new RegExp(\n `<!--\\\\s*visor:section=(\\\\{[\\\\s\\\\S]*?\\\\})\\\\s*-->[\\\\s\\\\S]*?<!--\\\\s*visor:section-end\\\\s+id=\\\\\"${this.escapeRegExp(id)}\\\\\"\\\\s*-->`,\n 'm'\n );\n const m = rx.exec(rendered);\n return m ? m[0] : undefined;\n }\n\n private escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\\\]\\\\]/g, '\\\\$&');\n }\n\n private getGroupForCheck(ctx: FrontendContext, checkId: string): string {\n try {\n const cfg: any = ctx.config || {};\n const g = cfg?.checks?.[checkId]?.group || cfg?.steps?.[checkId]?.group;\n if (typeof g === 'string' && g.trim().length > 0) return g;\n } catch {}\n return 'review';\n }\n\n private upsertSectionState(group: string, checkId: string, patch: Partial<SectionState>): void {\n let groupMap = this.stepStatusByGroup.get(group);\n if (!groupMap) {\n groupMap = new Map<string, SectionState>();\n this.stepStatusByGroup.set(group, groupMap);\n }\n const prev =\n groupMap.get(checkId) ||\n ({ status: 'queued', lastUpdated: new Date().toISOString() } as SectionState);\n groupMap.set(checkId, { ...prev, ...patch });\n }\n\n private commentIdForGroup(ctx: FrontendContext, group: string): string {\n // For \"dynamic\" group, each run creates a new comment (not updated across runs)\n // This is used for assistants that respond to issue comments where each\n // response should be a separate comment rather than updating a previous one.\n // Within a single run, the comment ID stays stable so updates work correctly.\n if (group === 'dynamic') {\n return `visor-thread-dynamic-${ctx.run.runId}`;\n }\n // Stable per-PR per-group ID (does not include commit SHA)\n const r = ctx.run;\n const base = r.repo && r.pr ? `${r.repo.owner}/${r.repo.name}#${r.pr}` : r.runId;\n return `visor-thread-${group}-${base}`;\n }\n\n /**\n * Compute failure condition results for a completed check so Check Runs map to the\n * correct GitHub conclusion. This mirrors the engine's evaluation for fail_if.\n */\n private async evaluateFailureResults(\n ctx: FrontendContext,\n checkId: string,\n result: { issues?: any[]; output?: unknown }\n ): Promise<any[]> {\n try {\n const config: any = ctx.config || {};\n const checks = (config && config.checks) || {};\n const checkCfg = checks[checkId] || {};\n const checkSchema = typeof checkCfg.schema === 'string' ? checkCfg.schema : 'code-review';\n const checkGroup = checkCfg.group || 'default';\n\n const { FailureConditionEvaluator } = require('../failure-condition-evaluator');\n const evaluator = new FailureConditionEvaluator();\n const reviewSummary = { issues: Array.isArray(result?.issues) ? result.issues : [] };\n\n const failures: any[] = [];\n\n // Global fail_if\n if (config.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkId,\n checkSchema,\n checkGroup,\n reviewSummary,\n config.fail_if\n );\n failures.push({\n conditionName: 'global_fail_if',\n failed,\n expression: config.fail_if,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n // Check-level fail_if\n if (checkCfg.fail_if) {\n const failed = await evaluator.evaluateSimpleCondition(\n checkId,\n checkSchema,\n checkGroup,\n reviewSummary,\n checkCfg.fail_if\n );\n failures.push({\n conditionName: `${checkId}_fail_if`,\n failed,\n expression: checkCfg.fail_if,\n severity: 'error',\n haltExecution: false,\n });\n }\n\n return failures;\n } catch {\n return [];\n }\n }\n\n // Debounce helpers\n private scheduleUpdate(ctx: FrontendContext, comments: any, group: string, id?: string) {\n if (id) this._pendingIds.add(id);\n const now = Date.now();\n const since = now - this._lastFlush;\n const remaining = this.maxWaitMs - since;\n if (this._timer) clearTimeout(this._timer);\n const wait = Math.max(0, Math.min(this.debounceMs, remaining));\n this._timer = setTimeout(async () => {\n const ids = Array.from(this._pendingIds);\n this._pendingIds.clear();\n this._timer = null;\n await this.updateGroupedComment(ctx, comments, group, ids.length > 0 ? ids : undefined);\n this._lastFlush = Date.now();\n }, wait);\n }\n\n private async flushNow(ctx: FrontendContext, comments: any, group: string) {\n if (this._timer) {\n clearTimeout(this._timer);\n this._timer = null;\n }\n const ids = Array.from(this._pendingIds);\n this._pendingIds.clear();\n await this.updateGroupedComment(ctx, comments, group, ids.length > 0 ? ids : undefined);\n this._lastFlush = Date.now();\n }\n\n /**\n * Sleep utility for enforcing delays\n */\n private sleep(ms: number): Promise<void> {\n return new Promise(resolve => setTimeout(resolve, ms));\n }\n}\n"],"mappings":"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","names":["CommentManager"]}
|