@probelabs/visor 0.1.178 → 0.1.179-ee
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/defaults/assistant.yaml +38 -16
- package/defaults/skills/code-explorer.yaml +8 -8
- package/dist/agent-protocol/tasks-cli-handler.d.ts.map +1 -1
- package/dist/agent-protocol/track-execution.d.ts.map +1 -1
- package/dist/defaults/assistant.yaml +38 -16
- package/dist/defaults/skills/code-explorer.yaml +8 -8
- package/dist/frontends/slack-frontend.d.ts +6 -0
- package/dist/frontends/slack-frontend.d.ts.map +1 -1
- package/dist/index.js +2143 -108
- package/dist/providers/ai-check-provider.d.ts.map +1 -1
- package/dist/sdk/{a2a-frontend-WYBMBBYG.mjs → a2a-frontend-KJFLIZJT.mjs} +2 -2
- package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs → check-provider-registry-J27YX4IT.mjs} +5 -5
- package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs → check-provider-registry-SYAHJMWJ.mjs} +5 -5
- package/dist/sdk/{chunk-6YGCACBF.mjs → chunk-CHARL3TY.mjs} +2 -2
- package/dist/sdk/{chunk-6YGCACBF.mjs.map → chunk-CHARL3TY.mjs.map} +1 -1
- package/dist/sdk/{chunk-B7XHSG3L.mjs → chunk-FTPLYUQ3.mjs} +163 -124
- package/dist/sdk/chunk-FTPLYUQ3.mjs.map +1 -0
- package/dist/sdk/{chunk-AK64Y6Y2.mjs → chunk-KWHLB5E3.mjs} +164 -125
- package/dist/sdk/chunk-KWHLB5E3.mjs.map +1 -0
- package/dist/sdk/{chunk-4ECMTCOM.mjs → chunk-OYHDBTKY.mjs} +2 -2
- package/dist/sdk/{chunk-ENSZDV3O.mjs → chunk-ZJYQMNPA.mjs} +3 -3
- package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs → failure-condition-evaluator-V2YGFRKO.mjs} +3 -3
- package/dist/sdk/{github-frontend-7RLEBJWG.mjs → github-frontend-4LM4NAZK.mjs} +3 -3
- package/dist/sdk/{host-I2TBBKD5.mjs → host-GBXJKNHL.mjs} +4 -4
- package/dist/sdk/{host-SE3MQHWG.mjs → host-XXPPPC76.mjs} +4 -4
- package/dist/sdk/knex-store-QCEW4I4R.mjs +527 -0
- package/dist/sdk/knex-store-QCEW4I4R.mjs.map +1 -0
- package/dist/sdk/loader-Q7K76ZIY.mjs +89 -0
- package/dist/sdk/loader-Q7K76ZIY.mjs.map +1 -0
- package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs +655 -0
- package/dist/sdk/opa-policy-engine-QCSSIMUF.mjs.map +1 -0
- package/dist/sdk/{routing-2X6QF5IW.mjs → routing-YAYBIVPL.mjs} +4 -4
- package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs → schedule-tool-OIVJDIDK.mjs} +5 -5
- package/dist/sdk/{schedule-tool-W4SQ334O.mjs → schedule-tool-WACIV77L.mjs} +5 -5
- package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs → schedule-tool-handler-ODKY57FO.mjs} +5 -5
- package/dist/sdk/{schedule-tool-handler-MPJFLH4J.mjs → schedule-tool-handler-SJF4ZKSB.mjs} +5 -5
- package/dist/sdk/sdk.js +1778 -328
- package/dist/sdk/sdk.js.map +1 -1
- package/dist/sdk/sdk.mjs +4 -4
- package/dist/sdk/{slack-frontend-XKSIOUXB.mjs → slack-frontend-OWD7BSWF.mjs} +22 -3
- package/dist/sdk/slack-frontend-OWD7BSWF.mjs.map +1 -0
- package/dist/sdk/{trace-helpers-4ADQ4GB3.mjs → trace-helpers-QL2B75AK.mjs} +2 -2
- package/dist/sdk/{track-execution-XTCZBUWX.mjs → track-execution-2Q66SXBZ.mjs} +20 -2
- package/dist/sdk/{track-execution-XTCZBUWX.mjs.map → track-execution-2Q66SXBZ.mjs.map} +1 -1
- package/dist/sdk/validator-XTZJZZJH.mjs +134 -0
- package/dist/sdk/validator-XTZJZZJH.mjs.map +1 -0
- package/dist/sdk/{workflow-check-provider-WHZP7BDF.mjs → workflow-check-provider-IXW6BMQA.mjs} +5 -5
- package/dist/sdk/{workflow-check-provider-WZN3B2S2.mjs → workflow-check-provider-UZQZYPOE.mjs} +5 -5
- package/dist/utils/workspace-manager.d.ts +2 -0
- package/dist/utils/workspace-manager.d.ts.map +1 -1
- package/package.json +2 -2
- package/dist/output/traces/run-2026-03-11T06-33-05-398Z.ndjson +0 -138
- package/dist/output/traces/run-2026-03-11T06-33-47-884Z.ndjson +0 -2296
- package/dist/sdk/a2a-frontend-U3PTNCLR.mjs +0 -1658
- package/dist/sdk/a2a-frontend-WYBMBBYG.mjs.map +0 -1
- package/dist/sdk/check-provider-registry-ZX76MY2L.mjs +0 -30
- package/dist/sdk/chunk-AK64Y6Y2.mjs.map +0 -1
- package/dist/sdk/chunk-ANEKFNAS.mjs +0 -45424
- package/dist/sdk/chunk-ANEKFNAS.mjs.map +0 -1
- package/dist/sdk/chunk-B7XHSG3L.mjs.map +0 -1
- package/dist/sdk/chunk-CDRKH5HH.mjs +0 -739
- package/dist/sdk/chunk-CDRKH5HH.mjs.map +0 -1
- package/dist/sdk/chunk-KG6PM4OL.mjs +0 -516
- package/dist/sdk/chunk-KG6PM4OL.mjs.map +0 -1
- package/dist/sdk/chunk-WZS4ARZB.mjs +0 -1502
- package/dist/sdk/chunk-WZS4ARZB.mjs.map +0 -1
- package/dist/sdk/failure-condition-evaluator-MMPKQGUA.mjs +0 -18
- package/dist/sdk/github-frontend-QTKOYB56.mjs +0 -1394
- package/dist/sdk/github-frontend-QTKOYB56.mjs.map +0 -1
- package/dist/sdk/routing-QHXBQS6X.mjs +0 -26
- package/dist/sdk/schedule-tool-MKT5FZ6J.mjs +0 -36
- package/dist/sdk/schedule-tool-handler-MPJFLH4J.mjs.map +0 -1
- package/dist/sdk/schedule-tool-handler-WY7WCFE5.mjs +0 -40
- package/dist/sdk/schedule-tool-handler-WY7WCFE5.mjs.map +0 -1
- package/dist/sdk/slack-frontend-XKSIOUXB.mjs.map +0 -1
- package/dist/sdk/trace-helpers-4ADQ4GB3.mjs.map +0 -1
- package/dist/sdk/trace-helpers-K47ZVJSU.mjs +0 -29
- package/dist/sdk/trace-helpers-K47ZVJSU.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-A3YH2UZJ.mjs +0 -30
- package/dist/sdk/workflow-check-provider-A3YH2UZJ.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-WHZP7BDF.mjs.map +0 -1
- package/dist/sdk/workflow-check-provider-WZN3B2S2.mjs.map +0 -1
- package/dist/traces/run-2026-03-11T06-33-05-398Z.ndjson +0 -138
- package/dist/traces/run-2026-03-11T06-33-47-884Z.ndjson +0 -2296
- /package/dist/sdk/{a2a-frontend-U3PTNCLR.mjs.map → a2a-frontend-KJFLIZJT.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-3DZOXYIA.mjs.map → check-provider-registry-J27YX4IT.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-T5J3H2N7.mjs.map → check-provider-registry-SYAHJMWJ.mjs.map} +0 -0
- /package/dist/sdk/{chunk-4ECMTCOM.mjs.map → chunk-OYHDBTKY.mjs.map} +0 -0
- /package/dist/sdk/{chunk-ENSZDV3O.mjs.map → chunk-ZJYQMNPA.mjs.map} +0 -0
- /package/dist/sdk/{check-provider-registry-ZX76MY2L.mjs.map → failure-condition-evaluator-V2YGFRKO.mjs.map} +0 -0
- /package/dist/sdk/{github-frontend-7RLEBJWG.mjs.map → github-frontend-4LM4NAZK.mjs.map} +0 -0
- /package/dist/sdk/{host-I2TBBKD5.mjs.map → host-GBXJKNHL.mjs.map} +0 -0
- /package/dist/sdk/{host-SE3MQHWG.mjs.map → host-XXPPPC76.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-MMPKQGUA.mjs.map → routing-YAYBIVPL.mjs.map} +0 -0
- /package/dist/sdk/{failure-condition-evaluator-P3MS5DRL.mjs.map → schedule-tool-OIVJDIDK.mjs.map} +0 -0
- /package/dist/sdk/{routing-2X6QF5IW.mjs.map → schedule-tool-WACIV77L.mjs.map} +0 -0
- /package/dist/sdk/{routing-QHXBQS6X.mjs.map → schedule-tool-handler-ODKY57FO.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-MKT5FZ6J.mjs.map → schedule-tool-handler-SJF4ZKSB.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-R6JJIDZ6.mjs.map → trace-helpers-QL2B75AK.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-W4SQ334O.mjs.map → workflow-check-provider-IXW6BMQA.mjs.map} +0 -0
- /package/dist/sdk/{schedule-tool-handler-AOMZV3Q3.mjs.map → workflow-check-provider-UZQZYPOE.mjs.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
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 * All write operations are serialized through an internal queue to prevent\n * concurrent GitHub API calls from racing against each other.\n */\nexport class CommentManager {\n private octokit: Octokit;\n private retryConfig: RetryConfig;\n // Serial write queue: chains all updateOrCreateComment calls so only one\n // GitHub comment write is in-flight at a time within a job.\n private _writeQueue: Promise<void> = Promise.resolve();\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 // Serialize all comment writes through a single queue so only one\n // GitHub API write is in-flight at a time, preventing races between\n // concurrent checks updating the same or different comments.\n return new Promise<Comment>((resolve, reject) => {\n this._writeQueue = this._writeQueue\n .then(() => this._doUpdateOrCreate(owner, repo, prNumber, content, options))\n .then(resolve, reject);\n });\n }\n\n private async _doUpdateOrCreate(\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 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 update to complete (if any)\n if (existingLock) {\n logger.info(\n `[github-frontend] Comment update for group \"${group}\" queued, waiting for previous update to finish...`\n );\n const queuedAt = Date.now();\n const reminder = setInterval(() => {\n const waited = Math.round((Date.now() - queuedAt) / 1000);\n logger.info(\n `[github-frontend] Comment update for group \"${group}\" still queued (${waited}s).`\n );\n }, 10000);\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 } finally {\n clearInterval(reminder);\n const waitedMs = Date.now() - queuedAt;\n if (waitedMs > 100) {\n logger.info(\n `[github-frontend] Comment update for group \"${group}\" dequeued after ${Math.round(waitedMs / 1000)}s.`\n );\n }\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"]}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
checkLoopBudget,
|
|
3
|
-
evaluateGoto,
|
|
4
|
-
evaluateTransitions,
|
|
5
|
-
handleRouting,
|
|
6
|
-
init_routing
|
|
7
|
-
} from "./chunk-WZS4ARZB.mjs";
|
|
8
|
-
import "./chunk-CDRKH5HH.mjs";
|
|
9
|
-
import "./chunk-KG6PM4OL.mjs";
|
|
10
|
-
import "./chunk-6VVXKXTI.mjs";
|
|
11
|
-
import "./chunk-34QX63WK.mjs";
|
|
12
|
-
import "./chunk-PQWZ6NFL.mjs";
|
|
13
|
-
import "./chunk-25IC7KXZ.mjs";
|
|
14
|
-
import "./chunk-LW3INISN.mjs";
|
|
15
|
-
import "./chunk-UFHOIB3R.mjs";
|
|
16
|
-
import "./chunk-FT3I25QV.mjs";
|
|
17
|
-
import "./chunk-UCMJJ3IM.mjs";
|
|
18
|
-
import "./chunk-J7LXIPZS.mjs";
|
|
19
|
-
init_routing();
|
|
20
|
-
export {
|
|
21
|
-
checkLoopBudget,
|
|
22
|
-
evaluateGoto,
|
|
23
|
-
evaluateTransitions,
|
|
24
|
-
handleRouting
|
|
25
|
-
};
|
|
26
|
-
//# sourceMappingURL=routing-QHXBQS6X.mjs.map
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
buildScheduleToolContext,
|
|
3
|
-
getScheduleToolDefinition,
|
|
4
|
-
handleScheduleAction,
|
|
5
|
-
init_schedule_tool,
|
|
6
|
-
isScheduleTool
|
|
7
|
-
} from "./chunk-AK64Y6Y2.mjs";
|
|
8
|
-
import "./chunk-YSOIR46P.mjs";
|
|
9
|
-
import "./chunk-PDQTEBOJ.mjs";
|
|
10
|
-
import "./chunk-7VTZDC2X.mjs";
|
|
11
|
-
import "./chunk-B7BVQM5K.mjs";
|
|
12
|
-
import "./chunk-XXAEN5KU.mjs";
|
|
13
|
-
import "./chunk-RHKPFJLG.mjs";
|
|
14
|
-
import "./chunk-UBTZE3FO.mjs";
|
|
15
|
-
import "./chunk-BMXVAJ2M.mjs";
|
|
16
|
-
import "./chunk-KWTCTEFT.mjs";
|
|
17
|
-
import "./chunk-WZS4ARZB.mjs";
|
|
18
|
-
import "./chunk-CDRKH5HH.mjs";
|
|
19
|
-
import "./chunk-KG6PM4OL.mjs";
|
|
20
|
-
import "./chunk-6VVXKXTI.mjs";
|
|
21
|
-
import "./chunk-34QX63WK.mjs";
|
|
22
|
-
import "./chunk-PQWZ6NFL.mjs";
|
|
23
|
-
import "./chunk-25IC7KXZ.mjs";
|
|
24
|
-
import "./chunk-LW3INISN.mjs";
|
|
25
|
-
import "./chunk-UFHOIB3R.mjs";
|
|
26
|
-
import "./chunk-FT3I25QV.mjs";
|
|
27
|
-
import "./chunk-UCMJJ3IM.mjs";
|
|
28
|
-
import "./chunk-J7LXIPZS.mjs";
|
|
29
|
-
init_schedule_tool();
|
|
30
|
-
export {
|
|
31
|
-
buildScheduleToolContext,
|
|
32
|
-
getScheduleToolDefinition,
|
|
33
|
-
handleScheduleAction,
|
|
34
|
-
isScheduleTool
|
|
35
|
-
};
|
|
36
|
-
//# sourceMappingURL=schedule-tool-MKT5FZ6J.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createScheduleToolWithContext,
|
|
3
|
-
ensureReminderStoreInitialized,
|
|
4
|
-
ensureScheduleStoreInitialized,
|
|
5
|
-
executeScheduleTool,
|
|
6
|
-
extractSlackContext,
|
|
7
|
-
init_schedule_tool_handler,
|
|
8
|
-
isScheduleToolCall
|
|
9
|
-
} from "./chunk-ANEKFNAS.mjs";
|
|
10
|
-
import "./chunk-YSOIR46P.mjs";
|
|
11
|
-
import "./chunk-PDQTEBOJ.mjs";
|
|
12
|
-
import "./chunk-7VTZDC2X.mjs";
|
|
13
|
-
import "./chunk-B7BVQM5K.mjs";
|
|
14
|
-
import "./chunk-XXAEN5KU.mjs";
|
|
15
|
-
import "./chunk-RHKPFJLG.mjs";
|
|
16
|
-
import "./chunk-UBTZE3FO.mjs";
|
|
17
|
-
import "./chunk-BMXVAJ2M.mjs";
|
|
18
|
-
import "./chunk-KWTCTEFT.mjs";
|
|
19
|
-
import "./chunk-ENSZDV3O.mjs";
|
|
20
|
-
import "./chunk-4ECMTCOM.mjs";
|
|
21
|
-
import "./chunk-6YGCACBF.mjs";
|
|
22
|
-
import "./chunk-6VVXKXTI.mjs";
|
|
23
|
-
import "./chunk-34QX63WK.mjs";
|
|
24
|
-
import "./chunk-PQWZ6NFL.mjs";
|
|
25
|
-
import "./chunk-25IC7KXZ.mjs";
|
|
26
|
-
import "./chunk-LW3INISN.mjs";
|
|
27
|
-
import "./chunk-UFHOIB3R.mjs";
|
|
28
|
-
import "./chunk-FT3I25QV.mjs";
|
|
29
|
-
import "./chunk-UCMJJ3IM.mjs";
|
|
30
|
-
import "./chunk-J7LXIPZS.mjs";
|
|
31
|
-
init_schedule_tool_handler();
|
|
32
|
-
export {
|
|
33
|
-
createScheduleToolWithContext,
|
|
34
|
-
ensureReminderStoreInitialized,
|
|
35
|
-
ensureScheduleStoreInitialized,
|
|
36
|
-
executeScheduleTool,
|
|
37
|
-
extractSlackContext,
|
|
38
|
-
isScheduleToolCall
|
|
39
|
-
};
|
|
40
|
-
//# sourceMappingURL=schedule-tool-handler-WY7WCFE5.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/slack/client.ts","../../src/frontends/slack-frontend.ts"],"sourcesContent":["// Lightweight Slack Web API wrapper implemented with fetch (no external deps).\n// Only methods needed by SlackFrontend are implemented.\n\nexport class SlackClient {\n private token: string;\n\n constructor(botToken: string) {\n if (!botToken || typeof botToken !== 'string') {\n throw new Error('SlackClient: botToken is required');\n }\n this.token = botToken;\n }\n\n public readonly reactions = {\n add: async ({\n channel,\n timestamp,\n name,\n }: {\n channel: string;\n timestamp: string;\n name: string;\n }) => {\n const resp: any = await this.api('reactions.add', { channel, timestamp, name });\n if (!resp || resp.ok !== true) {\n // Non-fatal in CLI/test runs – log and continue\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(`Slack reactions.add failed (non-fatal): ${err}`);\n return { ok: false as const };\n }\n return { ok: true } as const;\n },\n remove: async ({\n channel,\n timestamp,\n name,\n }: {\n channel: string;\n timestamp: string;\n name: string;\n }) => {\n const resp: any = await this.api('reactions.remove', { channel, timestamp, name });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(`Slack reactions.remove failed (non-fatal): ${err}`);\n return { ok: false as const };\n }\n return { ok: true } as const;\n },\n };\n\n public readonly chat = {\n postMessage: async ({\n channel,\n text,\n thread_ts,\n }: {\n channel: string;\n text: string;\n thread_ts?: string;\n }) => {\n try {\n const resp: any = await this.api('chat.postMessage', { channel, text, thread_ts });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n const warnings = Array.isArray(resp?.response_metadata?.warnings)\n ? resp.response_metadata.warnings.join(',')\n : '';\n console.warn(\n `Slack chat.postMessage failed (non-fatal): error=${err} channel=${channel} thread_ts=${\n thread_ts || '-'\n } text_len=${text.length}${warnings ? ` warnings=${warnings}` : ''}`\n );\n return {\n ok: false as const,\n ts: undefined,\n message: undefined,\n data: resp,\n error: err,\n };\n }\n // Normalize common fields for tests/frontend\n return {\n ok: true as const,\n ts: resp.ts || (resp.message && resp.message.ts) || undefined,\n message: resp.message,\n data: resp,\n error: undefined,\n };\n } catch (e) {\n console.warn(\n `Slack chat.postMessage threw (non-fatal): channel=${channel} thread_ts=${thread_ts || '-'} text_len=${\n text.length\n } error=${e instanceof Error ? e.message : String(e)}`\n );\n return {\n ok: false as const,\n ts: undefined,\n message: undefined,\n data: undefined,\n error: e instanceof Error ? e.message : String(e),\n };\n }\n },\n update: async ({ channel, ts, text }: { channel: string; ts: string; text: string }) => {\n try {\n const resp: any = await this.api('chat.update', { channel, ts, text });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n const warnings = Array.isArray(resp?.response_metadata?.warnings)\n ? resp.response_metadata.warnings.join(',')\n : '';\n console.warn(\n `Slack chat.update failed (non-fatal): error=${err} channel=${channel} ts=${ts} text_len=${\n text.length\n }${warnings ? ` warnings=${warnings}` : ''}`\n );\n return { ok: false as const, ts, error: err, data: resp };\n }\n return { ok: true as const, ts: resp.ts || ts, error: undefined, data: resp };\n } catch (e) {\n console.warn(\n `Slack chat.update threw (non-fatal): channel=${channel} ts=${ts} text_len=${text.length} error=${\n e instanceof Error ? e.message : String(e)\n }`\n );\n return {\n ok: false as const,\n ts,\n error: e instanceof Error ? e.message : String(e),\n data: undefined,\n };\n }\n },\n };\n\n async getBotUserId(): Promise<string> {\n const resp: any = await this.api('auth.test', {});\n if (!resp || resp.ok !== true || !resp.user_id) {\n console.warn('Slack auth.test failed (non-fatal); bot user id unavailable');\n return 'UNKNOWN_BOT';\n }\n return String(resp.user_id);\n }\n\n /**\n * Fetch user info from Slack API.\n * Returns user profile including guest status flags, email, display name, and timezone.\n */\n async getUserInfo(userId: string): Promise<{\n ok: boolean;\n user?: {\n id: string;\n name?: string; // username\n real_name?: string; // full name\n email?: string; // requires users:read.email scope\n is_restricted?: boolean; // Multi-channel guest\n is_ultra_restricted?: boolean; // Single-channel guest\n is_bot?: boolean;\n is_app_user?: boolean;\n deleted?: boolean;\n tz?: string; // IANA timezone (e.g., \"America/New_York\")\n tz_offset?: number; // Timezone offset in seconds from UTC\n };\n }> {\n try {\n const resp: any = await this.api('users.info', { user: userId });\n if (!resp || resp.ok !== true || !resp.user) {\n return { ok: false };\n }\n return {\n ok: true,\n user: {\n id: resp.user.id,\n name: resp.user.name,\n real_name: resp.user.real_name || resp.user.profile?.real_name,\n email: resp.user.profile?.email,\n is_restricted: resp.user.is_restricted,\n is_ultra_restricted: resp.user.is_ultra_restricted,\n is_bot: resp.user.is_bot,\n is_app_user: resp.user.is_app_user,\n deleted: resp.user.deleted,\n tz: resp.user.tz,\n tz_offset: resp.user.tz_offset,\n },\n };\n } catch (e) {\n console.warn(`Slack users.info failed: ${e instanceof Error ? e.message : String(e)}`);\n return { ok: false };\n }\n }\n\n /**\n * Open a DM channel with a user.\n * Returns the DM channel ID.\n */\n async openDM(userId: string): Promise<{ ok: boolean; channel?: string }> {\n try {\n const resp: any = await this.api('conversations.open', { users: userId });\n if (!resp || resp.ok !== true || !resp.channel?.id) {\n console.warn(`Slack conversations.open failed: ${resp?.error || 'unknown_error'}`);\n return { ok: false };\n }\n return { ok: true, channel: resp.channel.id };\n } catch (e) {\n console.warn(\n `Slack conversations.open failed: ${e instanceof Error ? e.message : String(e)}`\n );\n return { ok: false };\n }\n }\n\n async fetchThreadReplies(\n channel: string,\n thread_ts: string,\n limit: number = 40\n ): Promise<\n Array<{\n ts: string;\n user?: string;\n text?: string;\n bot_id?: string;\n thread_ts?: string;\n files?: any[];\n }>\n > {\n try {\n // Use query-string GET semantics similar to Slack WebClient to avoid\n // subtle JSON/form encoding issues that can cause invalid_arguments\n const params = new URLSearchParams({\n channel,\n ts: thread_ts,\n limit: String(limit),\n });\n const res = await fetch(`https://slack.com/api/conversations.replies?${params.toString()}`, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.token}`,\n },\n });\n const resp: any = await res.json();\n if (!resp || resp.ok !== true || !Array.isArray(resp.messages)) {\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(\n `Slack conversations.replies failed (non-fatal): ${err} (channel=${channel}, ts=${thread_ts}, limit=${limit})`\n );\n return [];\n }\n return resp.messages.map((m: any) => ({\n ts: String(m.ts || ''),\n user: m.user,\n text: m.text,\n bot_id: m.bot_id,\n thread_ts: m.thread_ts,\n files: Array.isArray(m.files) ? m.files : undefined,\n }));\n } catch (e) {\n console.warn(\n `Slack conversations.replies failed (non-fatal): ${\n e instanceof Error ? e.message : String(e)\n } (channel=${channel}, ts=${thread_ts}, limit=${limit})`\n );\n return [];\n }\n }\n\n public readonly files = {\n /**\n * Upload a file to Slack using files.uploadV2 API\n * @param options Upload options including file content, filename, channel, and thread_ts\n */\n uploadV2: async ({\n content,\n filename,\n channel,\n thread_ts,\n title,\n initial_comment,\n }: {\n content: Buffer;\n filename: string;\n channel: string;\n thread_ts?: string;\n title?: string;\n initial_comment?: string;\n }): Promise<{ ok: boolean; file?: { id: string; permalink?: string } }> => {\n try {\n // Step 1: Get upload URL (uses form-urlencoded — this endpoint rejects JSON bodies)\n const getUrlResp: any = await this.apiForm('files.getUploadURLExternal', {\n filename,\n length: String(content.length),\n });\n if (!getUrlResp || getUrlResp.ok !== true || !getUrlResp.upload_url) {\n console.warn(\n `Slack files.getUploadURLExternal failed: ${getUrlResp?.error || 'unknown'}`\n );\n return { ok: false };\n }\n\n // Step 2: Upload file content to the URL\n const uploadResp = await fetch(getUrlResp.upload_url, {\n method: 'POST',\n body: content,\n });\n if (!uploadResp.ok) {\n console.warn(`Slack file upload to URL failed: ${uploadResp.status}`);\n return { ok: false };\n }\n\n // Step 3: Complete the upload and share to channel\n const completeResp: any = await this.api('files.completeUploadExternal', {\n files: [{ id: getUrlResp.file_id, title: title || filename }],\n channel_id: channel,\n thread_ts,\n initial_comment,\n });\n if (!completeResp || completeResp.ok !== true) {\n console.warn(\n `Slack files.completeUploadExternal failed: ${completeResp?.error || 'unknown'}`\n );\n return { ok: false };\n }\n\n return {\n ok: true,\n file: completeResp.files?.[0] || { id: getUrlResp.file_id },\n };\n } catch (e) {\n console.warn(`Slack file upload failed: ${e instanceof Error ? e.message : String(e)}`);\n return { ok: false };\n }\n },\n };\n\n public readonly views = {\n publish: async ({\n user_id,\n view,\n }: {\n user_id: string;\n view: Record<string, unknown>;\n }): Promise<{ ok: boolean; error?: string }> => {\n try {\n const resp: any = await this.api('views.publish', { user_id, view });\n if (!resp || resp.ok !== true) {\n const err = (resp && resp.error) || 'unknown_error';\n console.warn(`Slack views.publish failed (non-fatal): ${err}`);\n return { ok: false, error: err };\n }\n return { ok: true };\n } catch (e) {\n console.warn(\n `Slack views.publish threw (non-fatal): ${e instanceof Error ? e.message : String(e)}`\n );\n return { ok: false, error: e instanceof Error ? e.message : String(e) };\n }\n },\n };\n\n getWebClient(): any {\n return {\n conversations: {\n history: async ({ channel, limit }: { channel: string; limit?: number }) =>\n (await this.api('conversations.history', { channel, limit })) as any,\n open: async ({ users }: { users: string }) =>\n (await this.api('conversations.open', { users })) as any,\n replies: async ({ channel, ts, limit }: { channel: string; ts: string; limit?: number }) =>\n (await this.api('conversations.replies', { channel, ts, limit })) as any,\n },\n };\n }\n\n private async api(method: string, body: Record<string, unknown>): Promise<unknown> {\n // Node 18+ global fetch\n const res = await fetch(`https://slack.com/api/${method}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json; charset=utf-8',\n Authorization: `Bearer ${this.token}`,\n },\n body: JSON.stringify(body),\n });\n return (await res.json()) as unknown;\n }\n\n /** Send a Slack API request as application/x-www-form-urlencoded (required by some file methods). */\n private async apiForm(method: string, params: Record<string, string>): Promise<unknown> {\n const body = new URLSearchParams(params);\n const res = await fetch(`https://slack.com/api/${method}`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Bearer ${this.token}`,\n },\n body: body.toString(),\n });\n return (await res.json()) as unknown;\n }\n}\n","/**\n * Slack Frontend for Visor workflows.\n *\n * Features:\n * - Posts AI replies to Slack threads\n * - Converts Markdown to Slack mrkdwn format\n * - Renders mermaid diagrams to PNG and uploads as images\n * - Manages 👀/👍 reactions for acknowledgement\n * - Handles human input prompts via prompt-state\n *\n * Mermaid Diagram Rendering:\n * - Detects ```mermaid code blocks in AI responses\n * - Renders to PNG using @mermaid-js/mermaid-cli (mmdc)\n * - Uploads rendered images to Slack thread\n * - Replaces mermaid blocks with \"_(See diagram above)_\" placeholder\n *\n * Requirements for mermaid rendering:\n * - Node.js and npx in PATH\n * - Puppeteer/Chromium dependencies (mermaid-cli uses headless browser)\n * - On Linux: apt-get install chromium-browser libatk-bridge2.0-0 libgtk-3-0\n */\nimport type { Frontend, FrontendContext } from './host';\nimport { SlackClient } from '../slack/client';\nimport {\n formatSlackText,\n type MermaidDiagram,\n renderMermaidToPng,\n replaceMermaidBlocks,\n extractFileSections,\n replaceFileSections,\n} from '../slack/markdown';\nimport { context as otContext, trace } from '../telemetry/lazy-otel';\n\ntype SlackFrontendConfig = {\n defaultChannel?: string;\n groupChannels?: Record<string, string>;\n debounceMs?: number;\n maxWaitMs?: number;\n showRawOutput?: boolean;\n telemetry?: {\n enabled?: boolean;\n };\n};\n\nexport class SlackFrontend implements Frontend {\n public readonly name = 'slack';\n private subs: Array<{ unsubscribe(): void }> = [];\n private cfg: SlackFrontendConfig;\n // Reactions ack/done per run (inbound Slack events only)\n private acked: boolean = false;\n private ackRef: { channel: string; ts: string } | null = null;\n private ackName: string = 'eyes';\n private doneName: string = 'thumbsup';\n private errorNotified: boolean = false;\n private cachedTraceInfo: { traceId: string; spanId: string } | null = null;\n\n constructor(config?: SlackFrontendConfig) {\n this.cfg = config || {};\n }\n\n start(ctx: FrontendContext): void {\n const bus = ctx.eventBus;\n\n // Capture trace info now while the OTel span may still be active.\n // EventBus handlers run in a different async context where the span is lost.\n if (!this.cachedTraceInfo) {\n this.cachedTraceInfo = this.getTraceInfo();\n }\n // Also check ctx.run.traceId which is injected by the execution engine\n if (!this.cachedTraceInfo) {\n const runTraceId = (ctx as any)?.run?.traceId;\n if (typeof runTraceId === 'string' && runTraceId) {\n this.cachedTraceInfo = { traceId: runTraceId, spanId: '' };\n }\n }\n\n // Info-level boot log\n try {\n const hasClient = !!(\n (ctx as any).slack ||\n (ctx as any).slackClient ||\n (this.cfg as any)?.botToken ||\n process.env.SLACK_BOT_TOKEN\n );\n ctx.logger.info(`[slack-frontend] started; hasClient=${hasClient} defaultChannel=unset`);\n } catch {}\n\n // If this run was triggered by a Slack event, log key attributes\n try {\n const payload = this.getInboundSlackPayload(ctx);\n if (payload) {\n const ev: any = payload.event || {};\n const ch = String(ev.channel || '-');\n const ts = String(ev.ts || ev.event_ts || '-');\n const user = String(ev.user || ev.bot_id || '-');\n const type = String(ev.type || '-');\n const thread = String(ev.thread_ts || '');\n ctx.logger.info(\n `[slack-frontend] inbound event received: type=${type} channel=${ch} ts=${ts}` +\n (thread ? ` thread_ts=${thread}` : '') +\n ` user=${user}`\n );\n }\n } catch {}\n\n // Listen to check lifecycle; we only post on completion/error (no queued placeholders)\n this.subs.push(\n bus.on('CheckCompleted', async (env: any) => {\n const ev = (env && env.payload) || env;\n // For chat-style AI checks, post direct replies into the Slack thread\n await this.maybePostDirectReply(ctx, ev.checkId, ev.result).catch(() => {});\n // Post execution failure notices when a check completes with fatal issues\n await this.maybePostExecutionFailure(ctx, ev.checkId, ev.result).catch(() => {});\n })\n );\n this.subs.push(\n bus.on('CheckErrored', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Execution error';\n await this.maybePostError(ctx, 'Check failed', message, ev?.checkId).catch(() => {});\n })\n );\n\n // On terminal state, replace 👀 with 👍 if we acked an inbound Slack message\n this.subs.push(\n bus.on('StateTransition', async (env: any) => {\n const ev = (env && env.payload) || env;\n if (ev && (ev.to === 'Completed' || ev.to === 'Error')) {\n await this.finalizeReactions(ctx).catch(() => {});\n }\n })\n );\n this.subs.push(\n bus.on('Shutdown', async (env: any) => {\n const ev = (env && env.payload) || env;\n const message = ev?.error?.message || 'Fatal error';\n await this.maybePostError(ctx, 'Run failed', message).catch(() => {});\n })\n );\n // Add 👀 acknowledgement as soon as first check is scheduled for Slack-driven runs\n this.subs.push(\n bus.on('CheckScheduled', async () => {\n await this.ensureAcknowledgement(ctx).catch(() => {});\n })\n );\n\n // Human-input requests: post prompt to Slack and mark waiting using prompt-state\n this.subs.push(\n bus.on('HumanInputRequested', async (env: any) => {\n try {\n const ev = (env && env.payload) || env;\n if (!ev || typeof ev.prompt !== 'string' || !ev.checkId) return;\n // Determine channel/thread (Slack SocketMode); if we can't, just ignore.\n let channel = ev.channel as string | undefined;\n let threadTs = ev.threadTs as string | undefined;\n if (!channel || !threadTs) {\n const payload = this.getInboundSlackPayload(ctx);\n const e: any = payload?.event;\n const derivedTs = String(e?.thread_ts || e?.ts || e?.event_ts || '');\n const derivedCh = String(e?.channel || '');\n if (derivedCh && derivedTs) {\n channel = channel || derivedCh;\n threadTs = threadTs || derivedTs;\n }\n }\n if (!channel || !threadTs) return;\n\n // Mark waiting in prompt-state without posting the prompt text to Slack.\n const { getPromptStateManager } = await import('../slack/prompt-state');\n const mgr = getPromptStateManager();\n const prev = mgr.getWaiting(channel, threadTs);\n const text = String(ev.prompt);\n mgr.setWaiting(channel, threadTs, {\n checkName: String(ev.checkId),\n prompt: text,\n promptMessageTs: prev?.promptMessageTs,\n promptsPosted: ((prev?.promptsPosted || 0) + 1) as any,\n });\n try {\n ctx.logger.info(\n `[slack-frontend] registered human-input waiting state for ${channel} thread=${threadTs}`\n );\n } catch {}\n } catch (e) {\n try {\n ctx.logger.warn(\n `[slack-frontend] HumanInputRequested handling failed: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n } catch {}\n }\n })\n );\n\n // SnapshotSaved: attach snapshot path to waiting entry for this thread\n this.subs.push(\n bus.on('SnapshotSaved', async (env: any) => {\n try {\n const ev = (env && env.payload) || env;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.threadTs || '');\n const filePath = String(ev?.filePath || '');\n if (!channel || !threadTs || !filePath) return;\n const { getPromptStateManager } = await import('../slack/prompt-state');\n const mgr = getPromptStateManager();\n mgr.update(channel, threadTs, { snapshotPath: filePath });\n try {\n ctx.logger.info(\n `[slack-frontend] snapshot path attached to waiting prompt: ${filePath}`\n );\n } catch {}\n } catch {}\n })\n );\n }\n\n stop(): void {\n for (const s of this.subs) s.unsubscribe();\n this.subs = [];\n }\n\n private getSlack(ctx: FrontendContext): any | undefined {\n // Prefer injected fake client in tests: ctx.slack or ctx.slackClient\n const injected = (ctx as any).slack || (ctx as any).slackClient;\n if (injected) return injected;\n // Else try to lazy-create from env or frontend config\n try {\n const token = (this.cfg as any)?.botToken || process.env.SLACK_BOT_TOKEN;\n if (typeof token === 'string' && token.trim()) {\n return new SlackClient(token.trim());\n }\n } catch {}\n return undefined;\n }\n\n private getInboundSlackPayload(ctx: FrontendContext): any | null {\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n const endpoint: string = slackCfg.endpoint || '/bots/slack/support';\n const payload: any = (ctx as any).webhookContext?.webhookData?.get(endpoint);\n return payload || null;\n } catch {\n return null;\n }\n }\n\n private getInboundSlackEvent(ctx: FrontendContext): { channel: string; ts: string } | null {\n try {\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const ts = String(ev?.ts || ev?.event_ts || '');\n if (channel && ts) return { channel, ts };\n } catch {}\n return null;\n }\n\n private isTelemetryEnabled(ctx: FrontendContext): boolean {\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n const telemetryCfg = slackCfg.telemetry ?? (this.cfg as any)?.telemetry;\n return (\n telemetryCfg === true ||\n (telemetryCfg && typeof telemetryCfg === 'object' && telemetryCfg.enabled === true)\n );\n } catch {\n return false;\n }\n }\n\n private async maybePostError(\n ctx: FrontendContext,\n title: string,\n message: string,\n checkId?: string\n ): Promise<void> {\n if (this.errorNotified) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || '');\n if (!channel || !threadTs) {\n try {\n ctx.logger.warn(\n `[slack-frontend] skip posting error notice: missing channel/thread (channel=${\n channel || '-'\n } thread=${threadTs || '-'})`\n );\n } catch {}\n return;\n }\n\n let text = `❌ ${title}`;\n if (checkId) text += `\\nCheck: ${checkId}`;\n if (message) text += `\\n${message}`;\n\n if (this.isTelemetryEnabled(ctx)) {\n const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;\n if (traceInfo?.traceId) {\n text += `\\n\\n\\`trace_id: ${traceInfo.traceId}\\``;\n }\n }\n\n const formattedText = formatSlackText(text);\n const postResult = await slack.chat.postMessage({\n channel,\n text: formattedText,\n thread_ts: threadTs,\n });\n if (!postResult?.ok) {\n try {\n ctx.logger.warn(\n `[slack-frontend] failed to post error notice to ${channel} thread=${threadTs} check=${\n checkId || 'run'\n } error=${postResult?.error || 'unknown_error'}`\n );\n } catch {}\n return;\n }\n try {\n ctx.logger.info(\n `[slack-frontend] posted error notice to ${channel} thread=${threadTs} check=${checkId || 'run'}`\n );\n } catch {}\n this.errorNotified = true;\n }\n\n private isExecutionFailureIssue(issue: any): boolean {\n const ruleId = String(issue?.ruleId || '');\n const msg = String(issue?.message || '');\n const msgLower = msg.toLowerCase();\n return (\n ruleId.endsWith('/error') ||\n ruleId.includes('/execution_error') ||\n ruleId.includes('timeout') ||\n ruleId.includes('sandbox_runner_error') ||\n msgLower.includes('timed out') ||\n msg.includes('Command execution failed')\n );\n }\n\n private async maybePostExecutionFailure(\n ctx: FrontendContext,\n checkId: string,\n result: { issues?: any[] }\n ): Promise<void> {\n try {\n if (this.errorNotified) return;\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n if (checkCfg.type === 'human-input') return;\n if (checkCfg.criticality === 'internal') return;\n const issues = (result as any)?.issues;\n if (!Array.isArray(issues) || issues.length === 0) return;\n\n const failureIssue = issues.find(issue => this.isExecutionFailureIssue(issue));\n if (!failureIssue) return;\n if (\n typeof failureIssue.message === 'string' &&\n failureIssue.message.toLowerCase().includes('awaiting human input')\n ) {\n return;\n }\n\n const msg =\n typeof failureIssue.message === 'string' && failureIssue.message.trim().length > 0\n ? failureIssue.message.trim()\n : `Execution failed (${String(failureIssue.ruleId || 'unknown')})`;\n await this.maybePostError(ctx, 'Check failed', msg, checkId);\n } catch {}\n }\n\n private async ensureAcknowledgement(ctx: FrontendContext): Promise<void> {\n if (this.acked) return;\n const ref = this.getInboundSlackEvent(ctx);\n if (!ref) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n // Skip ack for our own bot messages to avoid loops (allow other bots)\n try {\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n // If we can resolve bot user id, skip if the sender is the bot\n try {\n const botId = await slack.getBotUserId?.();\n if (botId && ev?.user && String(ev.user) === String(botId)) return;\n } catch {}\n } catch {}\n // Allow overrides via config\n try {\n const anyCfg: any = ctx.config || {};\n const slackCfg: any = anyCfg.slack || {};\n if (slackCfg?.reactions?.enabled === false) return;\n this.ackName = slackCfg?.reactions?.ack || this.ackName;\n this.doneName = slackCfg?.reactions?.done || this.doneName;\n } catch {}\n await slack.reactions.add({ channel: ref.channel, timestamp: ref.ts, name: this.ackName });\n try {\n ctx.logger.info(\n `[slack-frontend] added acknowledgement reaction :${this.ackName}: channel=${ref.channel} ts=${ref.ts}`\n );\n } catch {}\n this.acked = true;\n this.ackRef = ref;\n // Capture trace info while span is active (event handlers lose OTel context)\n if (!this.cachedTraceInfo) {\n this.cachedTraceInfo = this.getTraceInfo();\n }\n }\n\n private async finalizeReactions(ctx: FrontendContext): Promise<void> {\n if (!this.acked || !this.ackRef) return;\n const slack = this.getSlack(ctx);\n if (!slack) return;\n try {\n try {\n await slack.reactions.remove({\n channel: this.ackRef.channel,\n timestamp: this.ackRef.ts,\n name: this.ackName,\n });\n } catch {}\n await slack.reactions.add({\n channel: this.ackRef.channel,\n timestamp: this.ackRef.ts,\n name: this.doneName,\n });\n try {\n ctx.logger.info(\n `[slack-frontend] replaced acknowledgement with completion reaction :${this.doneName}: channel=${this.ackRef.channel} ts=${this.ackRef.ts}`\n );\n } catch {}\n } finally {\n // Reset for safety\n this.acked = false;\n this.ackRef = null;\n }\n }\n\n /**\n * Post direct replies into the originating Slack thread when appropriate.\n * This is independent of summary messages and is intended for chat-style flows\n * (e.g., AI answers and explicit chat/notify steps).\n */\n private async maybePostDirectReply(\n ctx: FrontendContext,\n checkId: string,\n result: { output?: any; content?: string }\n ): Promise<void> {\n try {\n const cfg: any = ctx.config || {};\n const checkCfg: any = cfg.checks?.[checkId];\n if (!checkCfg) return;\n\n // Per-workflow / per-frontend flag to allow posting raw JSON\n // outputs for AI steps (useful for debugging router outputs).\n const slackRoot: any = (cfg as any).slack || {};\n const showRawOutput =\n slackRoot.show_raw_output === true || (this.cfg as any)?.showRawOutput === true;\n const telemetryCfg = slackRoot.telemetry ?? (this.cfg as any)?.telemetry;\n\n const providerType = (checkCfg.type as string) || '';\n const isAi = providerType === 'ai';\n const isLogChat = providerType === 'log' && checkCfg.group === 'chat';\n const isWorkflow = providerType === 'workflow';\n\n // Allow ai, log-chat, and workflow types; skip everything else\n if (!isAi && !isLogChat && !isWorkflow) return;\n\n // Skip internal steps - they're intermediate processing and shouldn't post to Slack\n if (checkCfg.criticality === 'internal') return;\n\n // For AI checks, only post when using simple/unstructured schemas (or none).\n if (isAi) {\n const schema = checkCfg.schema;\n // String schemas: allow only simple/plain ones\n if (typeof schema === 'string') {\n const simpleSchemas = ['code-review', 'markdown', 'text', 'plain'];\n if (!simpleSchemas.includes(schema)) return;\n }\n // Object schemas (custom JSON): treat as structured; require output.text\n }\n\n const slack = this.getSlack(ctx);\n if (!slack) return;\n\n const payload = this.getInboundSlackPayload(ctx);\n const ev: any = payload?.event;\n const channel = String(ev?.channel || '');\n const threadTs = String(ev?.thread_ts || ev?.ts || ev?.event_ts || '');\n if (!channel || !threadTs) {\n ctx.logger.warn(\n `[slack-frontend] skip posting AI reply for ${checkId}: missing channel/thread (channel=${\n channel || '-'\n } thread=${threadTs || '-'})`\n );\n return;\n }\n\n // Prefer output.text; fall back to content ONLY for string/simple schemas.\n const out: any = (result as any)?.output;\n let text: string | undefined;\n if (out && typeof out.text === 'string' && out.text.trim().length > 0) {\n text = out.text.trim();\n } else if (isAi && typeof checkCfg.schema === 'string') {\n if (\n typeof (result as any)?.content === 'string' &&\n (result as any).content.trim().length > 0\n ) {\n text = (result as any).content.trim();\n }\n } else if (isLogChat && typeof (result as any)?.logOutput === 'string') {\n // For log-based chat checks, render the formatted log output as the\n // Slack message when no structured text field is present.\n const raw = (result as any).logOutput;\n if (raw.trim().length > 0) {\n text = raw.trim();\n }\n } else if (isAi && showRawOutput && out !== undefined) {\n try {\n text = JSON.stringify(out, null, 2);\n } catch {\n text = String(out);\n }\n }\n // Append raw output from DSL execute_plan (bypasses LLM rewriting chain)\n if (out && typeof out._rawOutput === 'string' && out._rawOutput.trim().length > 0) {\n text = (text || '') + '\\n\\n' + out._rawOutput.trim();\n }\n\n // Fallback: if no text was extracted, check for error issues (e.g. timeout)\n // and post an error message so the user isn't left with silence.\n if (!text) {\n const issues: any[] = (result as any)?.issues || [];\n const errorIssues = issues.filter(\n (i: any) =>\n i.severity === 'error' &&\n (i.ruleId?.startsWith('system/') || i.ruleId?.endsWith('/error'))\n );\n if (errorIssues.length > 0) {\n const errorMessages = errorIssues.map((i: any) => i.message).join('\\n');\n text = `:warning: Something went wrong while processing your request:\\n${errorMessages}`;\n // Prevent maybePostExecutionFailure from double-posting the same error\n this.errorNotified = true;\n ctx.logger.warn(\n `[slack-frontend] posting error fallback for ${checkId}: ${errorIssues.length} system error(s)`\n );\n }\n }\n\n if (!text) {\n ctx.logger.info(\n `[slack-frontend] skip posting AI reply for ${checkId}: no renderable text in check output`\n );\n return;\n }\n\n // Mermaid rendering is temporarily disabled — mmdc/puppeteer is too\n // heavy for the current deployment and frequently times out.\n // TODO: re-enable once a lighter renderer (e.g. kroki) is available.\n const diagrams: MermaidDiagram[] = []; // was: extractMermaidDiagrams(text);\n let processedText = text;\n\n if (diagrams.length > 0) {\n try {\n ctx.logger.info(\n `[slack-frontend] found ${diagrams.length} mermaid diagram(s) to render for ${checkId}`\n );\n } catch {}\n\n // Render and upload each diagram\n const uploadedCount: number[] = [];\n for (let i = 0; i < diagrams.length; i++) {\n const diagram = diagrams[i];\n try {\n ctx.logger.info(`[slack-frontend] rendering mermaid diagram ${i + 1}...`);\n const pngBuffer = await renderMermaidToPng(diagram.code);\n if (pngBuffer) {\n ctx.logger.info(\n `[slack-frontend] rendered diagram ${i + 1}, size=${pngBuffer.length} bytes, uploading...`\n );\n const filename = `diagram-${i + 1}.png`;\n const uploadResult = await slack.files.uploadV2({\n content: pngBuffer,\n filename,\n channel,\n thread_ts: threadTs,\n title: `Diagram ${i + 1}`,\n });\n if (uploadResult.ok) {\n uploadedCount.push(i);\n ctx.logger.info(`[slack-frontend] uploaded mermaid diagram ${i + 1} to ${channel}`);\n } else {\n ctx.logger.warn(`[slack-frontend] upload failed for diagram ${i + 1}`);\n }\n } else {\n ctx.logger.warn(\n `[slack-frontend] mermaid rendering returned null for diagram ${i + 1} (mmdc failed or not installed)`\n );\n }\n } catch (e) {\n ctx.logger.warn(\n `[slack-frontend] failed to render/upload mermaid diagram ${i + 1}: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n }\n\n // Replace mermaid blocks with placeholder text\n if (uploadedCount.length > 0) {\n processedText = replaceMermaidBlocks(text, diagrams, idx =>\n uploadedCount.includes(idx) ? '_(See diagram above)_' : '_(Diagram rendering failed)_'\n );\n }\n }\n\n // Normalize literal \\n escape sequences from DSL output buffer before extraction.\n // AI-generated DSL code often writes \"\\\\n\" producing literal backslash-n instead of\n // actual newlines, which prevents the --- delimiter --- from matching on its own line.\n processedText = processedText.replace(/\\\\n/g, '\\n');\n\n // Extract and upload file sections (--- filename.ext --- delimiters)\n const fileSections = extractFileSections(processedText);\n if (fileSections.length > 0) {\n const uploadedFileIndices: number[] = [];\n for (let i = 0; i < fileSections.length; i++) {\n const section = fileSections[i];\n try {\n const buffer = Buffer.from(section.content, 'utf-8');\n const uploadResult = await slack.files.uploadV2({\n content: buffer,\n filename: section.filename,\n channel,\n thread_ts: threadTs,\n title: section.filename,\n });\n if (uploadResult.ok) {\n uploadedFileIndices.push(i);\n ctx.logger.info(`[slack-frontend] uploaded file ${section.filename} to ${channel}`);\n } else {\n ctx.logger.warn(`[slack-frontend] upload failed for file ${section.filename}`);\n }\n } catch (e) {\n ctx.logger.warn(\n `[slack-frontend] failed to upload file ${section.filename}: ${\n e instanceof Error ? e.message : String(e)\n }`\n );\n }\n }\n processedText = replaceFileSections(processedText, fileSections, idx =>\n uploadedFileIndices.includes(idx)\n ? `_(See file: ${fileSections[idx].filename} above)_`\n : `_(File upload failed: ${fileSections[idx].filename})_`\n );\n }\n\n let decoratedText = processedText;\n const telemetryEnabled =\n telemetryCfg === true ||\n (telemetryCfg && typeof telemetryCfg === 'object' && telemetryCfg.enabled === true);\n if (telemetryEnabled) {\n const traceInfo = this.getTraceInfo() || this.cachedTraceInfo;\n if (traceInfo?.traceId) {\n const suffix = `\\`trace_id: ${traceInfo.traceId}\\``;\n decoratedText = `${decoratedText}\\n\\n${suffix}`;\n }\n }\n\n const formattedText = formatSlackText(decoratedText);\n const postResult = await slack.chat.postMessage({\n channel,\n text: formattedText,\n thread_ts: threadTs,\n });\n if (!postResult?.ok) {\n ctx.logger.warn(\n `[slack-frontend] failed to post AI reply for ${checkId} to ${channel} thread=${threadTs} error=${\n postResult?.error || 'unknown_error'\n }`\n );\n return;\n }\n ctx.logger.info(\n `[slack-frontend] posted AI reply for ${checkId} to ${channel} thread=${threadTs} ts=${\n postResult.ts || '-'\n }`\n );\n\n // Capture response for scheduled reminders (allows storing previousResponse)\n const responseCapture = (ctx as any).responseCapture as ((text: string) => void) | undefined;\n if (responseCapture && typeof responseCapture === 'function') {\n try {\n // Store the original text (before mrkdwn formatting) for continuity\n responseCapture(processedText);\n } catch {}\n }\n } catch (outerErr) {\n // Log errors instead of silently swallowing them\n try {\n ctx.logger.warn(\n `[slack-frontend] maybePostDirectReply failed for ${checkId}: ${\n outerErr instanceof Error ? outerErr.message : String(outerErr)\n }`\n );\n } catch {}\n }\n }\n\n private getTraceInfo(): { traceId: string; spanId: string } | null {\n try {\n const span = trace.getSpan(otContext.active());\n if (!span) return null;\n const ctx = span.spanContext();\n if (!ctx || !ctx.traceId) return null;\n return { traceId: ctx.traceId, spanId: ctx.spanId };\n } catch {\n return null;\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,IAGa;AAHb;AAAA;AAAA;AAGO,IAAM,cAAN,MAAkB;AAAA,MACf;AAAA,MAER,YAAY,UAAkB;AAC5B,YAAI,CAAC,YAAY,OAAO,aAAa,UAAU;AAC7C,gBAAM,IAAI,MAAM,mCAAmC;AAAA,QACrD;AACA,aAAK,QAAQ;AAAA,MACf;AAAA,MAEgB,YAAY;AAAA,QAC1B,KAAK,OAAO;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAIM;AACJ,gBAAM,OAAY,MAAM,KAAK,IAAI,iBAAiB,EAAE,SAAS,WAAW,KAAK,CAAC;AAC9E,cAAI,CAAC,QAAQ,KAAK,OAAO,MAAM;AAE7B,kBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,oBAAQ,KAAK,2CAA2C,GAAG,EAAE;AAC7D,mBAAO,EAAE,IAAI,MAAe;AAAA,UAC9B;AACA,iBAAO,EAAE,IAAI,KAAK;AAAA,QACpB;AAAA,QACA,QAAQ,OAAO;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAIM;AACJ,gBAAM,OAAY,MAAM,KAAK,IAAI,oBAAoB,EAAE,SAAS,WAAW,KAAK,CAAC;AACjF,cAAI,CAAC,QAAQ,KAAK,OAAO,MAAM;AAC7B,kBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,oBAAQ,KAAK,8CAA8C,GAAG,EAAE;AAChE,mBAAO,EAAE,IAAI,MAAe;AAAA,UAC9B;AACA,iBAAO,EAAE,IAAI,KAAK;AAAA,QACpB;AAAA,MACF;AAAA,MAEgB,OAAO;AAAA,QACrB,aAAa,OAAO;AAAA,UAClB;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAIM;AACJ,cAAI;AACF,kBAAM,OAAY,MAAM,KAAK,IAAI,oBAAoB,EAAE,SAAS,MAAM,UAAU,CAAC;AACjF,gBAAI,CAAC,QAAQ,KAAK,OAAO,MAAM;AAC7B,oBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,oBAAM,WAAW,MAAM,QAAQ,MAAM,mBAAmB,QAAQ,IAC5D,KAAK,kBAAkB,SAAS,KAAK,GAAG,IACxC;AACJ,sBAAQ;AAAA,gBACN,oDAAoD,GAAG,YAAY,OAAO,cACxE,aAAa,GACf,aAAa,KAAK,MAAM,GAAG,WAAW,aAAa,QAAQ,KAAK,EAAE;AAAA,cACpE;AACA,qBAAO;AAAA,gBACL,IAAI;AAAA,gBACJ,IAAI;AAAA,gBACJ,SAAS;AAAA,gBACT,MAAM;AAAA,gBACN,OAAO;AAAA,cACT;AAAA,YACF;AAEA,mBAAO;AAAA,cACL,IAAI;AAAA,cACJ,IAAI,KAAK,MAAO,KAAK,WAAW,KAAK,QAAQ,MAAO;AAAA,cACpD,SAAS,KAAK;AAAA,cACd,MAAM;AAAA,cACN,OAAO;AAAA,YACT;AAAA,UACF,SAAS,GAAG;AACV,oBAAQ;AAAA,cACN,qDAAqD,OAAO,cAAc,aAAa,GAAG,aACxF,KAAK,MACP,UAAU,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,YACtD;AACA,mBAAO;AAAA,cACL,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,SAAS;AAAA,cACT,MAAM;AAAA,cACN,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,YAClD;AAAA,UACF;AAAA,QACF;AAAA,QACA,QAAQ,OAAO,EAAE,SAAS,IAAI,KAAK,MAAqD;AACtF,cAAI;AACF,kBAAM,OAAY,MAAM,KAAK,IAAI,eAAe,EAAE,SAAS,IAAI,KAAK,CAAC;AACrE,gBAAI,CAAC,QAAQ,KAAK,OAAO,MAAM;AAC7B,oBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,oBAAM,WAAW,MAAM,QAAQ,MAAM,mBAAmB,QAAQ,IAC5D,KAAK,kBAAkB,SAAS,KAAK,GAAG,IACxC;AACJ,sBAAQ;AAAA,gBACN,+CAA+C,GAAG,YAAY,OAAO,OAAO,EAAE,aAC5E,KAAK,MACP,GAAG,WAAW,aAAa,QAAQ,KAAK,EAAE;AAAA,cAC5C;AACA,qBAAO,EAAE,IAAI,OAAgB,IAAI,OAAO,KAAK,MAAM,KAAK;AAAA,YAC1D;AACA,mBAAO,EAAE,IAAI,MAAe,IAAI,KAAK,MAAM,IAAI,OAAO,QAAW,MAAM,KAAK;AAAA,UAC9E,SAAS,GAAG;AACV,oBAAQ;AAAA,cACN,gDAAgD,OAAO,OAAO,EAAE,aAAa,KAAK,MAAM,UACtF,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA,YACF;AACA,mBAAO;AAAA,cACL,IAAI;AAAA,cACJ;AAAA,cACA,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC;AAAA,cAChD,MAAM;AAAA,YACR;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAM,eAAgC;AACpC,cAAM,OAAY,MAAM,KAAK,IAAI,aAAa,CAAC,CAAC;AAChD,YAAI,CAAC,QAAQ,KAAK,OAAO,QAAQ,CAAC,KAAK,SAAS;AAC9C,kBAAQ,KAAK,6DAA6D;AAC1E,iBAAO;AAAA,QACT;AACA,eAAO,OAAO,KAAK,OAAO;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,YAAY,QAef;AACD,YAAI;AACF,gBAAM,OAAY,MAAM,KAAK,IAAI,cAAc,EAAE,MAAM,OAAO,CAAC;AAC/D,cAAI,CAAC,QAAQ,KAAK,OAAO,QAAQ,CAAC,KAAK,MAAM;AAC3C,mBAAO,EAAE,IAAI,MAAM;AAAA,UACrB;AACA,iBAAO;AAAA,YACL,IAAI;AAAA,YACJ,MAAM;AAAA,cACJ,IAAI,KAAK,KAAK;AAAA,cACd,MAAM,KAAK,KAAK;AAAA,cAChB,WAAW,KAAK,KAAK,aAAa,KAAK,KAAK,SAAS;AAAA,cACrD,OAAO,KAAK,KAAK,SAAS;AAAA,cAC1B,eAAe,KAAK,KAAK;AAAA,cACzB,qBAAqB,KAAK,KAAK;AAAA,cAC/B,QAAQ,KAAK,KAAK;AAAA,cAClB,aAAa,KAAK,KAAK;AAAA,cACvB,SAAS,KAAK,KAAK;AAAA,cACnB,IAAI,KAAK,KAAK;AAAA,cACd,WAAW,KAAK,KAAK;AAAA,YACvB;AAAA,UACF;AAAA,QACF,SAAS,GAAG;AACV,kBAAQ,KAAK,4BAA4B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AACrF,iBAAO,EAAE,IAAI,MAAM;AAAA,QACrB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,MAAM,OAAO,QAA4D;AACvE,YAAI;AACF,gBAAM,OAAY,MAAM,KAAK,IAAI,sBAAsB,EAAE,OAAO,OAAO,CAAC;AACxE,cAAI,CAAC,QAAQ,KAAK,OAAO,QAAQ,CAAC,KAAK,SAAS,IAAI;AAClD,oBAAQ,KAAK,oCAAoC,MAAM,SAAS,eAAe,EAAE;AACjF,mBAAO,EAAE,IAAI,MAAM;AAAA,UACrB;AACA,iBAAO,EAAE,IAAI,MAAM,SAAS,KAAK,QAAQ,GAAG;AAAA,QAC9C,SAAS,GAAG;AACV,kBAAQ;AAAA,YACN,oCAAoC,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,UAChF;AACA,iBAAO,EAAE,IAAI,MAAM;AAAA,QACrB;AAAA,MACF;AAAA,MAEA,MAAM,mBACJ,SACA,WACA,QAAgB,IAUhB;AACA,YAAI;AAGF,gBAAM,SAAS,IAAI,gBAAgB;AAAA,YACjC;AAAA,YACA,IAAI;AAAA,YACJ,OAAO,OAAO,KAAK;AAAA,UACrB,CAAC;AACD,gBAAM,MAAM,MAAM,MAAM,+CAA+C,OAAO,SAAS,CAAC,IAAI;AAAA,YAC1F,QAAQ;AAAA,YACR,SAAS;AAAA,cACP,eAAe,UAAU,KAAK,KAAK;AAAA,YACrC;AAAA,UACF,CAAC;AACD,gBAAM,OAAY,MAAM,IAAI,KAAK;AACjC,cAAI,CAAC,QAAQ,KAAK,OAAO,QAAQ,CAAC,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9D,kBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,oBAAQ;AAAA,cACN,mDAAmD,GAAG,aAAa,OAAO,QAAQ,SAAS,WAAW,KAAK;AAAA,YAC7G;AACA,mBAAO,CAAC;AAAA,UACV;AACA,iBAAO,KAAK,SAAS,IAAI,CAAC,OAAY;AAAA,YACpC,IAAI,OAAO,EAAE,MAAM,EAAE;AAAA,YACrB,MAAM,EAAE;AAAA,YACR,MAAM,EAAE;AAAA,YACR,QAAQ,EAAE;AAAA,YACV,WAAW,EAAE;AAAA,YACb,OAAO,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,QAAQ;AAAA,UAC5C,EAAE;AAAA,QACJ,SAAS,GAAG;AACV,kBAAQ;AAAA,YACN,mDACE,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C,aAAa,OAAO,QAAQ,SAAS,WAAW,KAAK;AAAA,UACvD;AACA,iBAAO,CAAC;AAAA,QACV;AAAA,MACF;AAAA,MAEgB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,QAKtB,UAAU,OAAO;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAO2E;AACzE,cAAI;AAEF,kBAAM,aAAkB,MAAM,KAAK,QAAQ,8BAA8B;AAAA,cACvE;AAAA,cACA,QAAQ,OAAO,QAAQ,MAAM;AAAA,YAC/B,CAAC;AACD,gBAAI,CAAC,cAAc,WAAW,OAAO,QAAQ,CAAC,WAAW,YAAY;AACnE,sBAAQ;AAAA,gBACN,4CAA4C,YAAY,SAAS,SAAS;AAAA,cAC5E;AACA,qBAAO,EAAE,IAAI,MAAM;AAAA,YACrB;AAGA,kBAAM,aAAa,MAAM,MAAM,WAAW,YAAY;AAAA,cACpD,QAAQ;AAAA,cACR,MAAM;AAAA,YACR,CAAC;AACD,gBAAI,CAAC,WAAW,IAAI;AAClB,sBAAQ,KAAK,oCAAoC,WAAW,MAAM,EAAE;AACpE,qBAAO,EAAE,IAAI,MAAM;AAAA,YACrB;AAGA,kBAAM,eAAoB,MAAM,KAAK,IAAI,gCAAgC;AAAA,cACvE,OAAO,CAAC,EAAE,IAAI,WAAW,SAAS,OAAO,SAAS,SAAS,CAAC;AAAA,cAC5D,YAAY;AAAA,cACZ;AAAA,cACA;AAAA,YACF,CAAC;AACD,gBAAI,CAAC,gBAAgB,aAAa,OAAO,MAAM;AAC7C,sBAAQ;AAAA,gBACN,8CAA8C,cAAc,SAAS,SAAS;AAAA,cAChF;AACA,qBAAO,EAAE,IAAI,MAAM;AAAA,YACrB;AAEA,mBAAO;AAAA,cACL,IAAI;AAAA,cACJ,MAAM,aAAa,QAAQ,CAAC,KAAK,EAAE,IAAI,WAAW,QAAQ;AAAA,YAC5D;AAAA,UACF,SAAS,GAAG;AACV,oBAAQ,KAAK,6BAA6B,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC,EAAE;AACtF,mBAAO,EAAE,IAAI,MAAM;AAAA,UACrB;AAAA,QACF;AAAA,MACF;AAAA,MAEgB,QAAQ;AAAA,QACtB,SAAS,OAAO;AAAA,UACd;AAAA,UACA;AAAA,QACF,MAGgD;AAC9C,cAAI;AACF,kBAAM,OAAY,MAAM,KAAK,IAAI,iBAAiB,EAAE,SAAS,KAAK,CAAC;AACnE,gBAAI,CAAC,QAAQ,KAAK,OAAO,MAAM;AAC7B,oBAAM,MAAO,QAAQ,KAAK,SAAU;AACpC,sBAAQ,KAAK,2CAA2C,GAAG,EAAE;AAC7D,qBAAO,EAAE,IAAI,OAAO,OAAO,IAAI;AAAA,YACjC;AACA,mBAAO,EAAE,IAAI,KAAK;AAAA,UACpB,SAAS,GAAG;AACV,oBAAQ;AAAA,cACN,0CAA0C,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAAC;AAAA,YACtF;AACA,mBAAO,EAAE,IAAI,OAAO,OAAO,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,EAAE;AAAA,UACxE;AAAA,QACF;AAAA,MACF;AAAA,MAEA,eAAoB;AAClB,eAAO;AAAA,UACL,eAAe;AAAA,YACb,SAAS,OAAO,EAAE,SAAS,MAAM,MAC9B,MAAM,KAAK,IAAI,yBAAyB,EAAE,SAAS,MAAM,CAAC;AAAA,YAC7D,MAAM,OAAO,EAAE,MAAM,MAClB,MAAM,KAAK,IAAI,sBAAsB,EAAE,MAAM,CAAC;AAAA,YACjD,SAAS,OAAO,EAAE,SAAS,IAAI,MAAM,MAClC,MAAM,KAAK,IAAI,yBAAyB,EAAE,SAAS,IAAI,MAAM,CAAC;AAAA,UACnE;AAAA,QACF;AAAA,MACF;AAAA,MAEA,MAAc,IAAI,QAAgB,MAAiD;AAEjF,cAAM,MAAM,MAAM,MAAM,yBAAyB,MAAM,IAAI;AAAA,UACzD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,KAAK,KAAK;AAAA,UACrC;AAAA,UACA,MAAM,KAAK,UAAU,IAAI;AAAA,QAC3B,CAAC;AACD,eAAQ,MAAM,IAAI,KAAK;AAAA,MACzB;AAAA;AAAA,MAGA,MAAc,QAAQ,QAAgB,QAAkD;AACtF,cAAM,OAAO,IAAI,gBAAgB,MAAM;AACvC,cAAM,MAAM,MAAM,MAAM,yBAAyB,MAAM,IAAI;AAAA,UACzD,QAAQ;AAAA,UACR,SAAS;AAAA,YACP,gBAAgB;AAAA,YAChB,eAAe,UAAU,KAAK,KAAK;AAAA,UACrC;AAAA,UACA,MAAM,KAAK,SAAS;AAAA,QACtB,CAAC;AACD,eAAQ,MAAM,IAAI,KAAK;AAAA,MACzB;AAAA,IACF;AAAA;AAAA;;;AC9YA,IA4Ca;AA5Cb;AAAA;AAsBA;AACA;AAQA;AAaO,IAAM,gBAAN,MAAwC;AAAA,MAC7B,OAAO;AAAA,MACf,OAAuC,CAAC;AAAA,MACxC;AAAA;AAAA,MAEA,QAAiB;AAAA,MACjB,SAAiD;AAAA,MACjD,UAAkB;AAAA,MAClB,WAAmB;AAAA,MACnB,gBAAyB;AAAA,MACzB,kBAA8D;AAAA,MAEtE,YAAY,QAA8B;AACxC,aAAK,MAAM,UAAU,CAAC;AAAA,MACxB;AAAA,MAEA,MAAM,KAA4B;AAChC,cAAM,MAAM,IAAI;AAIhB,YAAI,CAAC,KAAK,iBAAiB;AACzB,eAAK,kBAAkB,KAAK,aAAa;AAAA,QAC3C;AAEA,YAAI,CAAC,KAAK,iBAAiB;AACzB,gBAAM,aAAc,KAAa,KAAK;AACtC,cAAI,OAAO,eAAe,YAAY,YAAY;AAChD,iBAAK,kBAAkB,EAAE,SAAS,YAAY,QAAQ,GAAG;AAAA,UAC3D;AAAA,QACF;AAGA,YAAI;AACF,gBAAM,YAAY,CAAC,EAChB,IAAY,SACZ,IAAY,eACZ,KAAK,KAAa,YACnB,QAAQ,IAAI;AAEd,cAAI,OAAO,KAAK,uCAAuC,SAAS,uBAAuB;AAAA,QACzF,QAAQ;AAAA,QAAC;AAGT,YAAI;AACF,gBAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,cAAI,SAAS;AACX,kBAAM,KAAU,QAAQ,SAAS,CAAC;AAClC,kBAAM,KAAK,OAAO,GAAG,WAAW,GAAG;AACnC,kBAAM,KAAK,OAAO,GAAG,MAAM,GAAG,YAAY,GAAG;AAC7C,kBAAM,OAAO,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG;AAC/C,kBAAM,OAAO,OAAO,GAAG,QAAQ,GAAG;AAClC,kBAAM,SAAS,OAAO,GAAG,aAAa,EAAE;AACxC,gBAAI,OAAO;AAAA,cACT,iDAAiD,IAAI,YAAY,EAAE,OAAO,EAAE,MACzE,SAAS,cAAc,MAAM,KAAK,MACnC,SAAS,IAAI;AAAA,YACjB;AAAA,UACF;AAAA,QACF,QAAQ;AAAA,QAAC;AAGT,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,kBAAkB,OAAO,QAAa;AAC3C,kBAAM,KAAM,OAAO,IAAI,WAAY;AAEnC,kBAAM,KAAK,qBAAqB,KAAK,GAAG,SAAS,GAAG,MAAM,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAE1E,kBAAM,KAAK,0BAA0B,KAAK,GAAG,SAAS,GAAG,MAAM,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACjF,CAAC;AAAA,QACH;AACA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,gBAAgB,OAAO,QAAa;AACzC,kBAAM,KAAM,OAAO,IAAI,WAAY;AACnC,kBAAM,UAAU,IAAI,OAAO,WAAW;AACtC,kBAAM,KAAK,eAAe,KAAK,gBAAgB,SAAS,IAAI,OAAO,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACrF,CAAC;AAAA,QACH;AAGA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,mBAAmB,OAAO,QAAa;AAC5C,kBAAM,KAAM,OAAO,IAAI,WAAY;AACnC,gBAAI,OAAO,GAAG,OAAO,eAAe,GAAG,OAAO,UAAU;AACtD,oBAAM,KAAK,kBAAkB,GAAG,EAAE,MAAM,MAAM;AAAA,cAAC,CAAC;AAAA,YAClD;AAAA,UACF,CAAC;AAAA,QACH;AACA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,YAAY,OAAO,QAAa;AACrC,kBAAM,KAAM,OAAO,IAAI,WAAY;AACnC,kBAAM,UAAU,IAAI,OAAO,WAAW;AACtC,kBAAM,KAAK,eAAe,KAAK,cAAc,OAAO,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACtE,CAAC;AAAA,QACH;AAEA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,kBAAkB,YAAY;AACnC,kBAAM,KAAK,sBAAsB,GAAG,EAAE,MAAM,MAAM;AAAA,YAAC,CAAC;AAAA,UACtD,CAAC;AAAA,QACH;AAGA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,uBAAuB,OAAO,QAAa;AAChD,gBAAI;AACF,oBAAM,KAAM,OAAO,IAAI,WAAY;AACnC,kBAAI,CAAC,MAAM,OAAO,GAAG,WAAW,YAAY,CAAC,GAAG,QAAS;AAEzD,kBAAI,UAAU,GAAG;AACjB,kBAAI,WAAW,GAAG;AAClB,kBAAI,CAAC,WAAW,CAAC,UAAU;AACzB,sBAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,sBAAM,IAAS,SAAS;AACxB,sBAAM,YAAY,OAAO,GAAG,aAAa,GAAG,MAAM,GAAG,YAAY,EAAE;AACnE,sBAAM,YAAY,OAAO,GAAG,WAAW,EAAE;AACzC,oBAAI,aAAa,WAAW;AAC1B,4BAAU,WAAW;AACrB,6BAAW,YAAY;AAAA,gBACzB;AAAA,cACF;AACA,kBAAI,CAAC,WAAW,CAAC,SAAU;AAG3B,oBAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,6BAAuB;AACtE,oBAAM,MAAM,sBAAsB;AAClC,oBAAM,OAAO,IAAI,WAAW,SAAS,QAAQ;AAC7C,oBAAM,OAAO,OAAO,GAAG,MAAM;AAC7B,kBAAI,WAAW,SAAS,UAAU;AAAA,gBAChC,WAAW,OAAO,GAAG,OAAO;AAAA,gBAC5B,QAAQ;AAAA,gBACR,iBAAiB,MAAM;AAAA,gBACvB,gBAAiB,MAAM,iBAAiB,KAAK;AAAA,cAC/C,CAAC;AACD,kBAAI;AACF,oBAAI,OAAO;AAAA,kBACT,6DAA6D,OAAO,WAAW,QAAQ;AAAA,gBACzF;AAAA,cACF,QAAQ;AAAA,cAAC;AAAA,YACX,SAAS,GAAG;AACV,kBAAI;AACF,oBAAI,OAAO;AAAA,kBACT,yDACE,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA,gBACF;AAAA,cACF,QAAQ;AAAA,cAAC;AAAA,YACX;AAAA,UACF,CAAC;AAAA,QACH;AAGA,aAAK,KAAK;AAAA,UACR,IAAI,GAAG,iBAAiB,OAAO,QAAa;AAC1C,gBAAI;AACF,oBAAM,KAAM,OAAO,IAAI,WAAY;AACnC,oBAAM,UAAU,OAAO,IAAI,WAAW,EAAE;AACxC,oBAAM,WAAW,OAAO,IAAI,YAAY,EAAE;AAC1C,oBAAM,WAAW,OAAO,IAAI,YAAY,EAAE;AAC1C,kBAAI,CAAC,WAAW,CAAC,YAAY,CAAC,SAAU;AACxC,oBAAM,EAAE,sBAAsB,IAAI,MAAM,OAAO,6BAAuB;AACtE,oBAAM,MAAM,sBAAsB;AAClC,kBAAI,OAAO,SAAS,UAAU,EAAE,cAAc,SAAS,CAAC;AACxD,kBAAI;AACF,oBAAI,OAAO;AAAA,kBACT,8DAA8D,QAAQ;AAAA,gBACxE;AAAA,cACF,QAAQ;AAAA,cAAC;AAAA,YACX,QAAQ;AAAA,YAAC;AAAA,UACX,CAAC;AAAA,QACH;AAAA,MACF;AAAA,MAEA,OAAa;AACX,mBAAW,KAAK,KAAK,KAAM,GAAE,YAAY;AACzC,aAAK,OAAO,CAAC;AAAA,MACf;AAAA,MAEQ,SAAS,KAAuC;AAEtD,cAAM,WAAY,IAAY,SAAU,IAAY;AACpD,YAAI,SAAU,QAAO;AAErB,YAAI;AACF,gBAAM,QAAS,KAAK,KAAa,YAAY,QAAQ,IAAI;AACzD,cAAI,OAAO,UAAU,YAAY,MAAM,KAAK,GAAG;AAC7C,mBAAO,IAAI,YAAY,MAAM,KAAK,CAAC;AAAA,UACrC;AAAA,QACF,QAAQ;AAAA,QAAC;AACT,eAAO;AAAA,MACT;AAAA,MAEQ,uBAAuB,KAAkC;AAC/D,YAAI;AACF,gBAAM,SAAc,IAAI,UAAU,CAAC;AACnC,gBAAM,WAAgB,OAAO,SAAS,CAAC;AACvC,gBAAM,WAAmB,SAAS,YAAY;AAC9C,gBAAM,UAAgB,IAAY,gBAAgB,aAAa,IAAI,QAAQ;AAC3E,iBAAO,WAAW;AAAA,QACpB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEQ,qBAAqB,KAA8D;AACzF,YAAI;AACF,gBAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,gBAAM,KAAU,SAAS;AACzB,gBAAM,UAAU,OAAO,IAAI,WAAW,EAAE;AACxC,gBAAM,KAAK,OAAO,IAAI,MAAM,IAAI,YAAY,EAAE;AAC9C,cAAI,WAAW,GAAI,QAAO,EAAE,SAAS,GAAG;AAAA,QAC1C,QAAQ;AAAA,QAAC;AACT,eAAO;AAAA,MACT;AAAA,MAEQ,mBAAmB,KAA+B;AACxD,YAAI;AACF,gBAAM,SAAc,IAAI,UAAU,CAAC;AACnC,gBAAM,WAAgB,OAAO,SAAS,CAAC;AACvC,gBAAM,eAAe,SAAS,aAAc,KAAK,KAAa;AAC9D,iBACE,iBAAiB,QAChB,gBAAgB,OAAO,iBAAiB,YAAY,aAAa,YAAY;AAAA,QAElF,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,MAEA,MAAc,eACZ,KACA,OACA,SACA,SACe;AACf,YAAI,KAAK,cAAe;AACxB,cAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,YAAI,CAAC,MAAO;AACZ,cAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,cAAM,KAAU,SAAS;AACzB,cAAM,UAAU,OAAO,IAAI,WAAW,EAAE;AACxC,cAAM,WAAW,OAAO,IAAI,aAAa,IAAI,MAAM,IAAI,YAAY,EAAE;AACrE,YAAI,CAAC,WAAW,CAAC,UAAU;AACzB,cAAI;AACF,gBAAI,OAAO;AAAA,cACT,+EACE,WAAW,GACb,WAAW,YAAY,GAAG;AAAA,YAC5B;AAAA,UACF,QAAQ;AAAA,UAAC;AACT;AAAA,QACF;AAEA,YAAI,OAAO,UAAK,KAAK;AACrB,YAAI,QAAS,SAAQ;AAAA,SAAY,OAAO;AACxC,YAAI,QAAS,SAAQ;AAAA,EAAK,OAAO;AAEjC,YAAI,KAAK,mBAAmB,GAAG,GAAG;AAChC,gBAAM,YAAY,KAAK,aAAa,KAAK,KAAK;AAC9C,cAAI,WAAW,SAAS;AACtB,oBAAQ;AAAA;AAAA,cAAmB,UAAU,OAAO;AAAA,UAC9C;AAAA,QACF;AAEA,cAAM,gBAAgB,gBAAgB,IAAI;AAC1C,cAAM,aAAa,MAAM,MAAM,KAAK,YAAY;AAAA,UAC9C;AAAA,UACA,MAAM;AAAA,UACN,WAAW;AAAA,QACb,CAAC;AACD,YAAI,CAAC,YAAY,IAAI;AACnB,cAAI;AACF,gBAAI,OAAO;AAAA,cACT,mDAAmD,OAAO,WAAW,QAAQ,UAC3E,WAAW,KACb,UAAU,YAAY,SAAS,eAAe;AAAA,YAChD;AAAA,UACF,QAAQ;AAAA,UAAC;AACT;AAAA,QACF;AACA,YAAI;AACF,cAAI,OAAO;AAAA,YACT,2CAA2C,OAAO,WAAW,QAAQ,UAAU,WAAW,KAAK;AAAA,UACjG;AAAA,QACF,QAAQ;AAAA,QAAC;AACT,aAAK,gBAAgB;AAAA,MACvB;AAAA,MAEQ,wBAAwB,OAAqB;AACnD,cAAM,SAAS,OAAO,OAAO,UAAU,EAAE;AACzC,cAAM,MAAM,OAAO,OAAO,WAAW,EAAE;AACvC,cAAM,WAAW,IAAI,YAAY;AACjC,eACE,OAAO,SAAS,QAAQ,KACxB,OAAO,SAAS,kBAAkB,KAClC,OAAO,SAAS,SAAS,KACzB,OAAO,SAAS,sBAAsB,KACtC,SAAS,SAAS,WAAW,KAC7B,IAAI,SAAS,0BAA0B;AAAA,MAE3C;AAAA,MAEA,MAAc,0BACZ,KACA,SACA,QACe;AACf,YAAI;AACF,cAAI,KAAK,cAAe;AACxB,gBAAM,MAAW,IAAI,UAAU,CAAC;AAChC,gBAAM,WAAgB,IAAI,SAAS,OAAO;AAC1C,cAAI,CAAC,SAAU;AACf,cAAI,SAAS,SAAS,cAAe;AACrC,cAAI,SAAS,gBAAgB,WAAY;AACzC,gBAAM,SAAU,QAAgB;AAChC,cAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,WAAW,EAAG;AAEnD,gBAAM,eAAe,OAAO,KAAK,WAAS,KAAK,wBAAwB,KAAK,CAAC;AAC7E,cAAI,CAAC,aAAc;AACnB,cACE,OAAO,aAAa,YAAY,YAChC,aAAa,QAAQ,YAAY,EAAE,SAAS,sBAAsB,GAClE;AACA;AAAA,UACF;AAEA,gBAAM,MACJ,OAAO,aAAa,YAAY,YAAY,aAAa,QAAQ,KAAK,EAAE,SAAS,IAC7E,aAAa,QAAQ,KAAK,IAC1B,qBAAqB,OAAO,aAAa,UAAU,SAAS,CAAC;AACnE,gBAAM,KAAK,eAAe,KAAK,gBAAgB,KAAK,OAAO;AAAA,QAC7D,QAAQ;AAAA,QAAC;AAAA,MACX;AAAA,MAEA,MAAc,sBAAsB,KAAqC;AACvE,YAAI,KAAK,MAAO;AAChB,cAAM,MAAM,KAAK,qBAAqB,GAAG;AACzC,YAAI,CAAC,IAAK;AACV,cAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,YAAI,CAAC,MAAO;AAEZ,YAAI;AACF,gBAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,gBAAM,KAAU,SAAS;AAEzB,cAAI;AACF,kBAAM,QAAQ,MAAM,MAAM,eAAe;AACzC,gBAAI,SAAS,IAAI,QAAQ,OAAO,GAAG,IAAI,MAAM,OAAO,KAAK,EAAG;AAAA,UAC9D,QAAQ;AAAA,UAAC;AAAA,QACX,QAAQ;AAAA,QAAC;AAET,YAAI;AACF,gBAAM,SAAc,IAAI,UAAU,CAAC;AACnC,gBAAM,WAAgB,OAAO,SAAS,CAAC;AACvC,cAAI,UAAU,WAAW,YAAY,MAAO;AAC5C,eAAK,UAAU,UAAU,WAAW,OAAO,KAAK;AAChD,eAAK,WAAW,UAAU,WAAW,QAAQ,KAAK;AAAA,QACpD,QAAQ;AAAA,QAAC;AACT,cAAM,MAAM,UAAU,IAAI,EAAE,SAAS,IAAI,SAAS,WAAW,IAAI,IAAI,MAAM,KAAK,QAAQ,CAAC;AACzF,YAAI;AACF,cAAI,OAAO;AAAA,YACT,oDAAoD,KAAK,OAAO,aAAa,IAAI,OAAO,OAAO,IAAI,EAAE;AAAA,UACvG;AAAA,QACF,QAAQ;AAAA,QAAC;AACT,aAAK,QAAQ;AACb,aAAK,SAAS;AAEd,YAAI,CAAC,KAAK,iBAAiB;AACzB,eAAK,kBAAkB,KAAK,aAAa;AAAA,QAC3C;AAAA,MACF;AAAA,MAEA,MAAc,kBAAkB,KAAqC;AACnE,YAAI,CAAC,KAAK,SAAS,CAAC,KAAK,OAAQ;AACjC,cAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,YAAI,CAAC,MAAO;AACZ,YAAI;AACF,cAAI;AACF,kBAAM,MAAM,UAAU,OAAO;AAAA,cAC3B,SAAS,KAAK,OAAO;AAAA,cACrB,WAAW,KAAK,OAAO;AAAA,cACvB,MAAM,KAAK;AAAA,YACb,CAAC;AAAA,UACH,QAAQ;AAAA,UAAC;AACT,gBAAM,MAAM,UAAU,IAAI;AAAA,YACxB,SAAS,KAAK,OAAO;AAAA,YACrB,WAAW,KAAK,OAAO;AAAA,YACvB,MAAM,KAAK;AAAA,UACb,CAAC;AACD,cAAI;AACF,gBAAI,OAAO;AAAA,cACT,uEAAuE,KAAK,QAAQ,aAAa,KAAK,OAAO,OAAO,OAAO,KAAK,OAAO,EAAE;AAAA,YAC3I;AAAA,UACF,QAAQ;AAAA,UAAC;AAAA,QACX,UAAE;AAEA,eAAK,QAAQ;AACb,eAAK,SAAS;AAAA,QAChB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA,MAAc,qBACZ,KACA,SACA,QACe;AACf,YAAI;AACF,gBAAM,MAAW,IAAI,UAAU,CAAC;AAChC,gBAAM,WAAgB,IAAI,SAAS,OAAO;AAC1C,cAAI,CAAC,SAAU;AAIf,gBAAM,YAAkB,IAAY,SAAS,CAAC;AAC9C,gBAAM,gBACJ,UAAU,oBAAoB,QAAS,KAAK,KAAa,kBAAkB;AAC7E,gBAAM,eAAe,UAAU,aAAc,KAAK,KAAa;AAE/D,gBAAM,eAAgB,SAAS,QAAmB;AAClD,gBAAM,OAAO,iBAAiB;AAC9B,gBAAM,YAAY,iBAAiB,SAAS,SAAS,UAAU;AAC/D,gBAAM,aAAa,iBAAiB;AAGpC,cAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,WAAY;AAGxC,cAAI,SAAS,gBAAgB,WAAY;AAGzC,cAAI,MAAM;AACR,kBAAM,SAAS,SAAS;AAExB,gBAAI,OAAO,WAAW,UAAU;AAC9B,oBAAM,gBAAgB,CAAC,eAAe,YAAY,QAAQ,OAAO;AACjE,kBAAI,CAAC,cAAc,SAAS,MAAM,EAAG;AAAA,YACvC;AAAA,UAEF;AAEA,gBAAM,QAAQ,KAAK,SAAS,GAAG;AAC/B,cAAI,CAAC,MAAO;AAEZ,gBAAM,UAAU,KAAK,uBAAuB,GAAG;AAC/C,gBAAM,KAAU,SAAS;AACzB,gBAAM,UAAU,OAAO,IAAI,WAAW,EAAE;AACxC,gBAAM,WAAW,OAAO,IAAI,aAAa,IAAI,MAAM,IAAI,YAAY,EAAE;AACrE,cAAI,CAAC,WAAW,CAAC,UAAU;AACzB,gBAAI,OAAO;AAAA,cACT,8CAA8C,OAAO,qCACnD,WAAW,GACb,WAAW,YAAY,GAAG;AAAA,YAC5B;AACA;AAAA,UACF;AAGA,gBAAM,MAAY,QAAgB;AAClC,cAAI;AACJ,cAAI,OAAO,OAAO,IAAI,SAAS,YAAY,IAAI,KAAK,KAAK,EAAE,SAAS,GAAG;AACrE,mBAAO,IAAI,KAAK,KAAK;AAAA,UACvB,WAAW,QAAQ,OAAO,SAAS,WAAW,UAAU;AACtD,gBACE,OAAQ,QAAgB,YAAY,YACnC,OAAe,QAAQ,KAAK,EAAE,SAAS,GACxC;AACA,qBAAQ,OAAe,QAAQ,KAAK;AAAA,YACtC;AAAA,UACF,WAAW,aAAa,OAAQ,QAAgB,cAAc,UAAU;AAGtE,kBAAM,MAAO,OAAe;AAC5B,gBAAI,IAAI,KAAK,EAAE,SAAS,GAAG;AACzB,qBAAO,IAAI,KAAK;AAAA,YAClB;AAAA,UACF,WAAW,QAAQ,iBAAiB,QAAQ,QAAW;AACrD,gBAAI;AACF,qBAAO,KAAK,UAAU,KAAK,MAAM,CAAC;AAAA,YACpC,QAAQ;AACN,qBAAO,OAAO,GAAG;AAAA,YACnB;AAAA,UACF;AAEA,cAAI,OAAO,OAAO,IAAI,eAAe,YAAY,IAAI,WAAW,KAAK,EAAE,SAAS,GAAG;AACjF,oBAAQ,QAAQ,MAAM,SAAS,IAAI,WAAW,KAAK;AAAA,UACrD;AAIA,cAAI,CAAC,MAAM;AACT,kBAAM,SAAiB,QAAgB,UAAU,CAAC;AAClD,kBAAM,cAAc,OAAO;AAAA,cACzB,CAAC,MACC,EAAE,aAAa,YACd,EAAE,QAAQ,WAAW,SAAS,KAAK,EAAE,QAAQ,SAAS,QAAQ;AAAA,YACnE;AACA,gBAAI,YAAY,SAAS,GAAG;AAC1B,oBAAM,gBAAgB,YAAY,IAAI,CAAC,MAAW,EAAE,OAAO,EAAE,KAAK,IAAI;AACtE,qBAAO;AAAA,EAAkE,aAAa;AAEtF,mBAAK,gBAAgB;AACrB,kBAAI,OAAO;AAAA,gBACT,+CAA+C,OAAO,KAAK,YAAY,MAAM;AAAA,cAC/E;AAAA,YACF;AAAA,UACF;AAEA,cAAI,CAAC,MAAM;AACT,gBAAI,OAAO;AAAA,cACT,8CAA8C,OAAO;AAAA,YACvD;AACA;AAAA,UACF;AAKA,gBAAM,WAA6B,CAAC;AACpC,cAAI,gBAAgB;AAEpB,cAAI,SAAS,SAAS,GAAG;AACvB,gBAAI;AACF,kBAAI,OAAO;AAAA,gBACT,0BAA0B,SAAS,MAAM,qCAAqC,OAAO;AAAA,cACvF;AAAA,YACF,QAAQ;AAAA,YAAC;AAGT,kBAAM,gBAA0B,CAAC;AACjC,qBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACxC,oBAAM,UAAU,SAAS,CAAC;AAC1B,kBAAI;AACF,oBAAI,OAAO,KAAK,8CAA8C,IAAI,CAAC,KAAK;AACxE,sBAAM,YAAY,MAAM,mBAAmB,QAAQ,IAAI;AACvD,oBAAI,WAAW;AACb,sBAAI,OAAO;AAAA,oBACT,qCAAqC,IAAI,CAAC,UAAU,UAAU,MAAM;AAAA,kBACtE;AACA,wBAAM,WAAW,WAAW,IAAI,CAAC;AACjC,wBAAM,eAAe,MAAM,MAAM,MAAM,SAAS;AAAA,oBAC9C,SAAS;AAAA,oBACT;AAAA,oBACA;AAAA,oBACA,WAAW;AAAA,oBACX,OAAO,WAAW,IAAI,CAAC;AAAA,kBACzB,CAAC;AACD,sBAAI,aAAa,IAAI;AACnB,kCAAc,KAAK,CAAC;AACpB,wBAAI,OAAO,KAAK,6CAA6C,IAAI,CAAC,OAAO,OAAO,EAAE;AAAA,kBACpF,OAAO;AACL,wBAAI,OAAO,KAAK,8CAA8C,IAAI,CAAC,EAAE;AAAA,kBACvE;AAAA,gBACF,OAAO;AACL,sBAAI,OAAO;AAAA,oBACT,gEAAgE,IAAI,CAAC;AAAA,kBACvE;AAAA,gBACF;AAAA,cACF,SAAS,GAAG;AACV,oBAAI,OAAO;AAAA,kBACT,4DAA4D,IAAI,CAAC,KAC/D,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAGA,gBAAI,cAAc,SAAS,GAAG;AAC5B,8BAAgB;AAAA,gBAAqB;AAAA,gBAAM;AAAA,gBAAU,SACnD,cAAc,SAAS,GAAG,IAAI,0BAA0B;AAAA,cAC1D;AAAA,YACF;AAAA,UACF;AAKA,0BAAgB,cAAc,QAAQ,QAAQ,IAAI;AAGlD,gBAAM,eAAe,oBAAoB,aAAa;AACtD,cAAI,aAAa,SAAS,GAAG;AAC3B,kBAAM,sBAAgC,CAAC;AACvC,qBAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,oBAAM,UAAU,aAAa,CAAC;AAC9B,kBAAI;AACF,sBAAM,SAAS,OAAO,KAAK,QAAQ,SAAS,OAAO;AACnD,sBAAM,eAAe,MAAM,MAAM,MAAM,SAAS;AAAA,kBAC9C,SAAS;AAAA,kBACT,UAAU,QAAQ;AAAA,kBAClB;AAAA,kBACA,WAAW;AAAA,kBACX,OAAO,QAAQ;AAAA,gBACjB,CAAC;AACD,oBAAI,aAAa,IAAI;AACnB,sCAAoB,KAAK,CAAC;AAC1B,sBAAI,OAAO,KAAK,kCAAkC,QAAQ,QAAQ,OAAO,OAAO,EAAE;AAAA,gBACpF,OAAO;AACL,sBAAI,OAAO,KAAK,2CAA2C,QAAQ,QAAQ,EAAE;AAAA,gBAC/E;AAAA,cACF,SAAS,GAAG;AACV,oBAAI,OAAO;AAAA,kBACT,0CAA0C,QAAQ,QAAQ,KACxD,aAAa,QAAQ,EAAE,UAAU,OAAO,CAAC,CAC3C;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AACA,4BAAgB;AAAA,cAAoB;AAAA,cAAe;AAAA,cAAc,SAC/D,oBAAoB,SAAS,GAAG,IAC5B,eAAe,aAAa,GAAG,EAAE,QAAQ,aACzC,yBAAyB,aAAa,GAAG,EAAE,QAAQ;AAAA,YACzD;AAAA,UACF;AAEA,cAAI,gBAAgB;AACpB,gBAAM,mBACJ,iBAAiB,QAChB,gBAAgB,OAAO,iBAAiB,YAAY,aAAa,YAAY;AAChF,cAAI,kBAAkB;AACpB,kBAAM,YAAY,KAAK,aAAa,KAAK,KAAK;AAC9C,gBAAI,WAAW,SAAS;AACtB,oBAAM,SAAS,eAAe,UAAU,OAAO;AAC/C,8BAAgB,GAAG,aAAa;AAAA;AAAA,EAAO,MAAM;AAAA,YAC/C;AAAA,UACF;AAEA,gBAAM,gBAAgB,gBAAgB,aAAa;AACnD,gBAAM,aAAa,MAAM,MAAM,KAAK,YAAY;AAAA,YAC9C;AAAA,YACA,MAAM;AAAA,YACN,WAAW;AAAA,UACb,CAAC;AACD,cAAI,CAAC,YAAY,IAAI;AACnB,gBAAI,OAAO;AAAA,cACT,gDAAgD,OAAO,OAAO,OAAO,WAAW,QAAQ,UACtF,YAAY,SAAS,eACvB;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,OAAO;AAAA,YACT,wCAAwC,OAAO,OAAO,OAAO,WAAW,QAAQ,OAC9E,WAAW,MAAM,GACnB;AAAA,UACF;AAGA,gBAAM,kBAAmB,IAAY;AACrC,cAAI,mBAAmB,OAAO,oBAAoB,YAAY;AAC5D,gBAAI;AAEF,8BAAgB,aAAa;AAAA,YAC/B,QAAQ;AAAA,YAAC;AAAA,UACX;AAAA,QACF,SAAS,UAAU;AAEjB,cAAI;AACF,gBAAI,OAAO;AAAA,cACT,oDAAoD,OAAO,KACzD,oBAAoB,QAAQ,SAAS,UAAU,OAAO,QAAQ,CAChE;AAAA,YACF;AAAA,UACF,QAAQ;AAAA,UAAC;AAAA,QACX;AAAA,MACF;AAAA,MAEQ,eAA2D;AACjE,YAAI;AACF,gBAAM,OAAO,MAAM,QAAQ,QAAU,OAAO,CAAC;AAC7C,cAAI,CAAC,KAAM,QAAO;AAClB,gBAAM,MAAM,KAAK,YAAY;AAC7B,cAAI,CAAC,OAAO,CAAC,IAAI,QAAS,QAAO;AACjC,iBAAO,EAAE,SAAS,IAAI,SAAS,QAAQ,IAAI,OAAO;AAAA,QACpD,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA;AAAA;","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__getOrCreateNdjsonPath,
|
|
3
|
-
_appendRunMarker,
|
|
4
|
-
addEvent,
|
|
5
|
-
getTracer,
|
|
6
|
-
getVisorRunAttributes,
|
|
7
|
-
init_trace_helpers,
|
|
8
|
-
setSpanAttributes,
|
|
9
|
-
setSpanError,
|
|
10
|
-
withActiveSpan,
|
|
11
|
-
withVisorRun
|
|
12
|
-
} from "./chunk-6YGCACBF.mjs";
|
|
13
|
-
import "./chunk-6VVXKXTI.mjs";
|
|
14
|
-
import "./chunk-34QX63WK.mjs";
|
|
15
|
-
import "./chunk-UCMJJ3IM.mjs";
|
|
16
|
-
import "./chunk-J7LXIPZS.mjs";
|
|
17
|
-
init_trace_helpers();
|
|
18
|
-
export {
|
|
19
|
-
__getOrCreateNdjsonPath,
|
|
20
|
-
_appendRunMarker,
|
|
21
|
-
addEvent,
|
|
22
|
-
getTracer,
|
|
23
|
-
getVisorRunAttributes,
|
|
24
|
-
setSpanAttributes,
|
|
25
|
-
setSpanError,
|
|
26
|
-
withActiveSpan,
|
|
27
|
-
withVisorRun
|
|
28
|
-
};
|
|
29
|
-
//# sourceMappingURL=trace-helpers-K47ZVJSU.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
WorkflowCheckProvider,
|
|
3
|
-
init_workflow_check_provider
|
|
4
|
-
} from "./chunk-B7XHSG3L.mjs";
|
|
5
|
-
import "./chunk-YSOIR46P.mjs";
|
|
6
|
-
import "./chunk-PDQTEBOJ.mjs";
|
|
7
|
-
import "./chunk-7VTZDC2X.mjs";
|
|
8
|
-
import "./chunk-B7BVQM5K.mjs";
|
|
9
|
-
import "./chunk-XXAEN5KU.mjs";
|
|
10
|
-
import "./chunk-RHKPFJLG.mjs";
|
|
11
|
-
import "./chunk-UBTZE3FO.mjs";
|
|
12
|
-
import "./chunk-BMXVAJ2M.mjs";
|
|
13
|
-
import "./chunk-KWTCTEFT.mjs";
|
|
14
|
-
import "./chunk-ENSZDV3O.mjs";
|
|
15
|
-
import "./chunk-4ECMTCOM.mjs";
|
|
16
|
-
import "./chunk-6YGCACBF.mjs";
|
|
17
|
-
import "./chunk-6VVXKXTI.mjs";
|
|
18
|
-
import "./chunk-34QX63WK.mjs";
|
|
19
|
-
import "./chunk-PQWZ6NFL.mjs";
|
|
20
|
-
import "./chunk-25IC7KXZ.mjs";
|
|
21
|
-
import "./chunk-LW3INISN.mjs";
|
|
22
|
-
import "./chunk-UFHOIB3R.mjs";
|
|
23
|
-
import "./chunk-FT3I25QV.mjs";
|
|
24
|
-
import "./chunk-UCMJJ3IM.mjs";
|
|
25
|
-
import "./chunk-J7LXIPZS.mjs";
|
|
26
|
-
init_workflow_check_provider();
|
|
27
|
-
export {
|
|
28
|
-
WorkflowCheckProvider
|
|
29
|
-
};
|
|
30
|
-
//# sourceMappingURL=workflow-check-provider-A3YH2UZJ.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|