@probelabs/visor 0.1.124 → 0.1.125
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/config.d.ts.map +1 -1
- package/dist/docs/DEPLOYMENT.md +117 -11
- package/dist/docs/GITHUB_CHECKS.md +18 -4
- package/dist/docs/NPM_USAGE.md +112 -39
- package/dist/docs/action-reference.md +63 -9
- package/dist/docs/advanced-ai.md +58 -51
- package/dist/docs/ai-configuration.md +99 -11
- package/dist/docs/ai-custom-tools-usage.md +70 -33
- package/dist/docs/ai-custom-tools.md +50 -27
- package/dist/docs/architecture.md +1232 -0
- package/dist/docs/bot-transports-rfc.md +13 -3
- package/dist/docs/ci-cli-mode.md +116 -8
- package/dist/docs/claude-code.md +111 -41
- package/dist/docs/command-provider.md +37 -15
- package/dist/docs/commands.md +252 -6
- package/dist/docs/configuration.md +138 -4
- package/dist/docs/contributing.md +737 -0
- package/dist/docs/custom-tools.md +39 -8
- package/dist/docs/dashboards/README.md +33 -19
- package/dist/docs/debug-visualizer-progress.md +14 -13
- package/dist/docs/debug-visualizer-rfc.md +14 -13
- package/dist/docs/debug-visualizer.md +30 -5
- package/dist/docs/debugging.md +73 -8
- package/dist/docs/default-output-schema.md +24 -20
- package/dist/docs/dependencies.md +75 -21
- package/dist/docs/dev-playbook.md +85 -9
- package/dist/docs/engine-pause-resume-rfc.md +11 -11
- package/dist/docs/engine-state-machine-plan.md +10 -3
- package/dist/docs/event-driven-github-integration-rfc.md +20 -11
- package/dist/docs/event-triggers.md +95 -6
- package/dist/docs/execution-statistics-rfc.md +16 -4
- package/dist/docs/fact-validator-gap-analysis.md +12 -1
- package/dist/docs/fact-validator-implementation-plan.md +19 -11
- package/dist/docs/fail-if.md +116 -11
- package/dist/docs/failure-conditions-implementation.md +40 -6
- package/dist/docs/failure-conditions-schema.md +243 -87
- package/dist/docs/failure-routing-rfc.md +43 -18
- package/dist/docs/failure-routing.md +80 -23
- package/dist/docs/faq.md +836 -0
- package/dist/docs/foreach-dependency-propagation.md +32 -15
- package/dist/docs/github-ops.md +6 -5
- package/dist/docs/glossary.md +322 -0
- package/dist/docs/goto-forward-run-plan.md +23 -10
- package/dist/docs/guides/criticality-modes.md +15 -13
- package/dist/docs/guides/fault-management-and-contracts.md +8 -5
- package/dist/docs/guides/workflow-style-guide.md +17 -8
- package/dist/docs/http.md +102 -3
- package/dist/docs/human-input-provider.md +20 -36
- package/dist/docs/index.md +206 -0
- package/dist/docs/lifecycle-hooks.md +322 -2
- package/dist/docs/limits.md +20 -5
- package/dist/docs/liquid-templates.md +86 -14
- package/dist/docs/loop-routing-refactor.md +4 -2
- package/dist/docs/mcp-provider.md +53 -19
- package/dist/docs/mcp.md +27 -1
- package/dist/docs/memory.md +7 -2
- package/dist/docs/migration.md +596 -0
- package/dist/docs/observability.md +227 -6
- package/dist/docs/output-formats.md +388 -9
- package/dist/docs/output-history.md +36 -6
- package/dist/docs/performance.md +510 -4
- package/dist/docs/pluggable.md +95 -4
- package/dist/docs/proposals/snapshot-scope-execution.md +6 -5
- package/dist/docs/providers/git-checkout.md +16 -14
- package/dist/docs/providers/noop.md +696 -0
- package/dist/docs/recipes.md +8 -9
- package/dist/docs/rfc/git-checkout-step.md +3 -1
- package/dist/docs/rfc/on_init-hook.md +18 -5
- package/dist/docs/rfc/workspace-isolation.md +16 -0
- package/dist/docs/roadmap/criticality-implementation-tasks.md +27 -27
- package/dist/docs/router-patterns.md +155 -43
- package/dist/docs/schema-templates.md +51 -15
- package/dist/docs/script.md +162 -13
- package/dist/docs/sdk.md +46 -12
- package/dist/docs/security.md +464 -5
- package/dist/docs/slack-integration.md +475 -0
- package/dist/docs/tag-filtering.md +60 -20
- package/dist/docs/telemetry-setup.md +157 -46
- package/dist/docs/test-framework-rfc.md +37 -36
- package/dist/docs/testing/assertions.md +92 -4
- package/dist/docs/testing/ci.md +56 -7
- package/dist/docs/testing/cli.md +57 -15
- package/dist/docs/testing/cookbook.md +53 -20
- package/dist/docs/testing/dsl-reference.md +110 -9
- package/dist/docs/testing/fixtures-and-mocks.md +28 -3
- package/dist/docs/testing/flows.md +59 -4
- package/dist/docs/testing/getting-started.md +14 -13
- package/dist/docs/testing/troubleshooting.md +39 -2
- package/dist/docs/timeouts.md +174 -18
- package/dist/docs/troubleshooting.md +176 -6
- package/dist/docs/workflow-creation-guide.md +101 -3
- package/dist/docs/workflows.md +138 -41
- package/dist/examples/README.md +169 -4
- package/dist/examples/ai-custom-tools-simple.yaml +2 -3
- package/dist/examples/cron-webhook-config.yaml +15 -0
- package/dist/examples/forEach-example.yaml +6 -0
- package/dist/examples/git-checkout-basic.yaml +4 -0
- package/dist/examples/git-checkout-compare.yaml +6 -0
- package/dist/examples/git-checkout-cross-repo.yaml +7 -0
- package/dist/examples/http-integration-config.yaml +30 -0
- package/dist/examples/https-server-config.yaml +15 -0
- package/dist/examples/mcp-provider-example.yaml +10 -10
- package/dist/examples/transform-example.yaml +3 -0
- package/dist/examples/webhook-pipeline-config.yaml +18 -0
- package/dist/examples/workflows/workflow-composition-example.yaml +4 -0
- package/dist/generated/config-schema.d.ts +7 -7
- package/dist/generated/config-schema.d.ts.map +1 -1
- package/dist/generated/config-schema.json +7 -7
- package/dist/index.js +9946 -7087
- package/dist/output/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-30T09-25-36-981Z.ndjson} +84 -84
- package/dist/output/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-30T09-26-20-969Z.ndjson} +1026 -1026
- package/dist/providers/ai-check-provider.d.ts +9 -2
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/providers/command-check-provider.d.ts.map +1 -1
- package/dist/providers/mcp-custom-sse-server.d.ts +17 -1
- package/dist/providers/mcp-custom-sse-server.d.ts.map +1 -1
- package/dist/providers/workflow-check-provider.d.ts.map +1 -1
- package/dist/providers/workflow-tool-executor.d.ts +68 -0
- package/dist/providers/workflow-tool-executor.d.ts.map +1 -0
- package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs → check-provider-registry-3KI5RKXT.mjs} +6 -5
- package/dist/sdk/{chunk-YLQ4UN62.mjs → chunk-A4PGHURG.mjs} +6838 -6257
- package/dist/sdk/chunk-A4PGHURG.mjs.map +1 -0
- package/dist/sdk/chunk-EXFGO4FX.mjs +147 -0
- package/dist/sdk/chunk-EXFGO4FX.mjs.map +1 -0
- package/dist/sdk/{chunk-BHZ4CKUS.mjs → chunk-PXFIALUH.mjs} +77 -8
- package/dist/sdk/chunk-PXFIALUH.mjs.map +1 -0
- package/dist/sdk/{chunk-PVITVJ6J.mjs → chunk-RTKJXNZS.mjs} +32 -9
- package/dist/sdk/chunk-RTKJXNZS.mjs.map +1 -0
- package/dist/sdk/{config-RQQPMLRD.mjs → config-6CUVEH7H.mjs} +2 -2
- package/dist/sdk/{github-frontend-6Q4BISZX.mjs → github-frontend-BZ4N3BFZ.mjs} +7 -3
- package/dist/sdk/github-frontend-BZ4N3BFZ.mjs.map +1 -0
- package/dist/sdk/{host-P5NQICP7.mjs → host-NYWXLIFC.mjs} +2 -2
- package/dist/sdk/{routing-DEY2AIXM.mjs → routing-7FXPULTO.mjs} +2 -2
- package/dist/sdk/sdk.d.mts +1 -1
- package/dist/sdk/sdk.d.ts +1 -1
- package/dist/sdk/sdk.js +12129 -11321
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +13 -9
- package/dist/sdk/sdk.mjs.map +1 -1
- package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs +28 -0
- package/dist/sdk/workflow-check-provider-YUNNF4KC.mjs.map +1 -0
- package/dist/state-machine/context/workflow-inputs.d.ts +20 -0
- package/dist/state-machine/context/workflow-inputs.d.ts.map +1 -0
- package/dist/state-machine/dispatch/execution-invoker.d.ts.map +1 -1
- package/dist/state-machine/dispatch/foreach-processor.d.ts.map +1 -1
- package/dist/state-machine/states/level-dispatch.d.ts.map +1 -1
- package/dist/state-machine/states/routing.d.ts +2 -1
- package/dist/state-machine/states/routing.d.ts.map +1 -1
- package/dist/traces/{run-2026-01-28T16-15-24-569Z.ndjson → run-2026-01-30T09-25-36-981Z.ndjson} +84 -84
- package/dist/traces/{run-2026-01-28T16-16-09-757Z.ndjson → run-2026-01-30T09-26-20-969Z.ndjson} +1026 -1026
- package/dist/types/config.d.ts +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/utils/human-id.d.ts +12 -0
- package/dist/utils/human-id.d.ts.map +1 -0
- package/dist/utils/worktree-manager.d.ts +3 -0
- package/dist/utils/worktree-manager.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/sdk/chunk-BHZ4CKUS.mjs.map +0 -1
- package/dist/sdk/chunk-PVITVJ6J.mjs.map +0 -1
- package/dist/sdk/chunk-YLQ4UN62.mjs.map +0 -1
- package/dist/sdk/github-frontend-6Q4BISZX.mjs.map +0 -1
- /package/dist/sdk/{check-provider-registry-AQ3JETBG.mjs.map → check-provider-registry-3KI5RKXT.mjs.map} +0 -0
- /package/dist/sdk/{config-RQQPMLRD.mjs.map → config-6CUVEH7H.mjs.map} +0 -0
- /package/dist/sdk/{host-P5NQICP7.mjs.map → host-NYWXLIFC.mjs.map} +0 -0
- /package/dist/sdk/{routing-DEY2AIXM.mjs.map → routing-7FXPULTO.mjs.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/footer.ts","../../src/github-check-service.ts","../../src/github-comments.ts","../../src/frontends/github-frontend.ts","../../src/utils/json-text-extractor.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\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 stop(): void {\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\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 (!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","/**\n * Utility for extracting text content from JSON-like output.\n *\n * When AI models return structured JSON with text/response/message fields,\n * but template rendering fails to unwrap them, this utility provides a\n * fallback to extract the actual text content.\n */\n\n/**\n * Extract text/response/message field from malformed JSON-like string using regex.\n * Handles cases where AI returns incomplete JSON like:\n * {\"text\": \"content here...\\n\\n## More content\" (missing closing brace)\n *\n * @param content - The malformed JSON-like string\n * @returns The extracted text content, or undefined if not found\n */\nfunction extractTextFieldFromMalformedJson(content: string): string | undefined {\n // Try to match \"text\", \"response\", or \"message\" field at the start of JSON\n // Pattern: {\"text\": \"...\" or { \"text\": \"...\" (with optional whitespace)\n // The value can be a quoted string that we need to extract\n\n // First, try to find a field like \"text\": \"value\" or \"text\": value\n // We look for the field name followed by : and then extract everything after\n const fieldPatterns = [\n /^\\s*\\{\\s*\"text\"\\s*:\\s*\"/i,\n /^\\s*\\{\\s*\"response\"\\s*:\\s*\"/i,\n /^\\s*\\{\\s*\"message\"\\s*:\\s*\"/i,\n ];\n\n for (const pattern of fieldPatterns) {\n const match = pattern.exec(content);\n if (match) {\n // Found a field, extract the value starting after the opening quote\n const valueStart = match[0].length;\n const remaining = content.substring(valueStart);\n\n // Try to find the end of the string value by looking for unescaped quotes\n // Handle escaped quotes (\\\") within the string\n let value = '';\n let i = 0;\n while (i < remaining.length) {\n const char = remaining[i];\n if (char === '\\\\' && i + 1 < remaining.length) {\n // Escape sequence - handle common ones\n const nextChar = remaining[i + 1];\n if (nextChar === 'n') {\n value += '\\n';\n } else if (nextChar === 'r') {\n value += '\\r';\n } else if (nextChar === 't') {\n value += '\\t';\n } else if (nextChar === '\"') {\n value += '\"';\n } else if (nextChar === '\\\\') {\n value += '\\\\';\n } else {\n // Unknown escape, keep as-is\n value += char + nextChar;\n }\n i += 2;\n } else if (char === '\"') {\n // End of string value (unescaped quote)\n break;\n } else {\n value += char;\n i++;\n }\n }\n\n // If we extracted something meaningful, return it\n if (value.trim().length > 0) {\n return value.trim();\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract text from a JSON-like object or JSON string.\n * If the input is a string that looks like JSON with a text/response/message field,\n * extracts and returns that field. Otherwise returns the original content.\n *\n * @param content - The content to extract text from (can be string, object, or any)\n * @returns The extracted text, or undefined if no content\n */\nexport function extractTextFromJson(content: unknown): string | undefined {\n if (content === undefined || content === null) return undefined;\n\n let parsed = content;\n\n // If it's a string, check if it looks like JSON\n if (typeof content === 'string') {\n const trimmed = content.trim();\n\n // If it doesn't look like JSON, return as-is\n if (!trimmed.startsWith('{') && !trimmed.startsWith('[')) {\n return trimmed.length > 0 ? trimmed : undefined;\n }\n\n // Try to parse as JSON\n try {\n parsed = JSON.parse(trimmed);\n } catch {\n // JSON parsing failed - try to extract text field using regex\n // This handles malformed JSON like: {\"text\": \"content...\\n\\n## More content\" (missing closing brace)\n const extracted = extractTextFieldFromMalformedJson(trimmed);\n if (extracted) {\n return extracted;\n }\n // Couldn't extract, return as-is\n return trimmed.length > 0 ? trimmed : undefined;\n }\n }\n\n // Extract text field from parsed object\n if (parsed && typeof parsed === 'object') {\n const txt =\n (parsed as Record<string, unknown>).text ||\n (parsed as Record<string, unknown>).response ||\n (parsed as Record<string, unknown>).message;\n if (typeof txt === 'string' && txt.trim()) {\n return txt.trim();\n }\n }\n\n // If we got here with a string, return it\n if (typeof content === 'string') {\n const trimmed = content.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n }\n\n return undefined;\n}\n"],"mappings":"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","names":["CommentManager"]}
|
|
@@ -16,7 +16,7 @@ var FrontendsHost = class {
|
|
|
16
16
|
const { NdjsonSink } = await import("./ndjson-sink-B4V4NTAQ.mjs");
|
|
17
17
|
this.frontends.push(new NdjsonSink(spec.config));
|
|
18
18
|
} else if (spec.name === "github") {
|
|
19
|
-
const { GitHubFrontend } = await import("./github-frontend-
|
|
19
|
+
const { GitHubFrontend } = await import("./github-frontend-BZ4N3BFZ.mjs");
|
|
20
20
|
this.frontends.push(new GitHubFrontend());
|
|
21
21
|
} else if (spec.name === "slack") {
|
|
22
22
|
const { SlackFrontend } = await import("./slack-frontend-J442FJWZ.mjs");
|
|
@@ -49,4 +49,4 @@ var FrontendsHost = class {
|
|
|
49
49
|
export {
|
|
50
50
|
FrontendsHost
|
|
51
51
|
};
|
|
52
|
-
//# sourceMappingURL=host-
|
|
52
|
+
//# sourceMappingURL=host-NYWXLIFC.mjs.map
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
evaluateTransitions,
|
|
5
5
|
handleRouting,
|
|
6
6
|
init_routing
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PXFIALUH.mjs";
|
|
8
8
|
import "./chunk-SWEEZ5D5.mjs";
|
|
9
9
|
import "./chunk-BOVFH3LI.mjs";
|
|
10
10
|
import "./chunk-ZYAUYXSW.mjs";
|
|
@@ -21,4 +21,4 @@ export {
|
|
|
21
21
|
evaluateTransitions,
|
|
22
22
|
handleRouting
|
|
23
23
|
};
|
|
24
|
-
//# sourceMappingURL=routing-
|
|
24
|
+
//# sourceMappingURL=routing-7FXPULTO.mjs.map
|
package/dist/sdk/sdk.d.mts
CHANGED
|
@@ -364,7 +364,7 @@ interface CheckConfig {
|
|
|
364
364
|
claude_code?: ClaudeCodeConfig;
|
|
365
365
|
/** Environment variables for this check */
|
|
366
366
|
env?: EnvConfig;
|
|
367
|
-
/** Timeout in
|
|
367
|
+
/** Timeout in milliseconds for command execution (default: 60000, i.e., 60 seconds) */
|
|
368
368
|
timeout?: number;
|
|
369
369
|
/** Check IDs that this check depends on (optional). Accepts single string or array. */
|
|
370
370
|
depends_on?: string | string[];
|
package/dist/sdk/sdk.d.ts
CHANGED
|
@@ -364,7 +364,7 @@ interface CheckConfig {
|
|
|
364
364
|
claude_code?: ClaudeCodeConfig;
|
|
365
365
|
/** Environment variables for this check */
|
|
366
366
|
env?: EnvConfig;
|
|
367
|
-
/** Timeout in
|
|
367
|
+
/** Timeout in milliseconds for command execution (default: 60000, i.e., 60 seconds) */
|
|
368
368
|
timeout?: number;
|
|
369
369
|
/** Check IDs that this check depends on (optional). Accepts single string or array. */
|
|
370
370
|
depends_on?: string | string[];
|