| "use strict"; |
| Object.defineProperty(exports, "__esModule", { value: true }); |
| exports.configLoader = exports.PrixConfigLoader = exports.DEFAULT_PRIX_CONFIG = void 0; |
| exports.getConfig = getConfig; |
| exports.meetsConfidenceThreshold = meetsConfidenceThreshold; |
| exports.meetsMinimumSeverity = meetsMinimumSeverity; |
| exports.lintSuggestion = lintSuggestion; |
| const fs_1 = require("fs"); |
| const path_1 = require("path"); |
| const context_1 = require("./context"); |
| const utils_1 = require("./utils"); |
| exports.DEFAULT_PRIX_CONFIG = { |
| version: '1.0', |
| severity: { |
| minimumLevel: 'minor', |
| showConfidenceThreshold: 50 |
| }, |
| filters: { |
| excludePatterns: [], |
| includePatterns: ['**/*'], |
| disableTypes: [] |
| }, |
| linting: { |
| enabled: true, |
| eslint: true, |
| prettier: true, |
| failOnError: false |
| }, |
| review: { |
| maxFilesPerPR: 50, |
| maxCommentsPerFile: 10, |
| denseMode: false, |
| showImpactAnalysis: true |
| }, |
| remedies: { |
| enabled: false, |
| autoCreatePR: false, |
| requireApproval: true |
| }, |
| confidence: { |
| minCritical: 0, |
| minMajor: 60, |
| minMinor: 70, |
| minInfo: 80 |
| } |
| }; |
| class PrixConfigLoader { |
| config = null; |
| load(workingDir) { |
| if (this.config) { |
| return this.config; |
| } |
| const possiblePaths = [ |
| (0, path_1.join)(workingDir, '.prix.yml'), |
| (0, path_1.join)(workingDir, 'prix.yml'), |
| (0, path_1.join)(workingDir, '.prix.yaml'), |
| (0, path_1.join)(workingDir, 'prix.yaml') |
| ]; |
| for (const configPath of possiblePaths) { |
| if ((0, fs_1.existsSync)(configPath)) { |
| try { |
| const content = (0, fs_1.readFileSync)(configPath, 'utf8'); |
| this.config = this.mergeWithDefaults(this.parseYAML(content)); |
| return this.config; |
| } |
| catch (e) { |
| console.warn(`Failed to load prix config from ${configPath}: ${e}`); |
| } |
| } |
| } |
| this.config = exports.DEFAULT_PRIX_CONFIG; |
| return this.config; |
| } |
| parseYAML(content) { |
| const result = {}; |
| const lines = content.split('\n'); |
| let currentSection = null; |
| let currentSectionObj = {}; |
| let sectionKey = ''; |
| for (const line of lines) { |
| const sectionMatch = line.match(/^(\w+):\s*$/); |
| if (sectionMatch) { |
| if (currentSection && sectionKey) { |
| ; |
| result[sectionKey] = currentSectionObj; |
| } |
| currentSection = sectionMatch[1]; |
| sectionKey = currentSection; |
| currentSectionObj = {}; |
| continue; |
| } |
| const keyValueMatch = line.match(/^\s*(\w+):\s*(.+)$/); |
| if (keyValueMatch && currentSection) { |
| const key = keyValueMatch[1]; |
| let value = keyValueMatch[2].trim(); |
| if (value === 'true') |
| value = true; |
| else if (value === 'false') |
| value = false; |
| else if (!isNaN(Number(value))) |
| value = Number(value); |
| currentSectionObj[key] = value; |
| } |
| } |
| if (currentSection && sectionKey) { |
| ; |
| result[sectionKey] = currentSectionObj; |
| } |
| return result; |
| } |
| mergeWithDefaults(config) { |
| return { |
| version: config.version || exports.DEFAULT_PRIX_CONFIG.version, |
| severity: { |
| ...exports.DEFAULT_PRIX_CONFIG.severity, |
| ...config.severity |
| }, |
| filters: { |
| ...exports.DEFAULT_PRIX_CONFIG.filters, |
| ...config.filters |
| }, |
| linting: { |
| ...exports.DEFAULT_PRIX_CONFIG.linting, |
| ...config.linting |
| }, |
| review: { |
| ...exports.DEFAULT_PRIX_CONFIG.review, |
| ...config.review |
| }, |
| remedies: { |
| ...exports.DEFAULT_PRIX_CONFIG.remedies, |
| ...config.remedies |
| }, |
| confidence: { |
| ...exports.DEFAULT_PRIX_CONFIG.confidence, |
| ...config.confidence |
| } |
| }; |
| } |
| shouldIncludeFile(config, filename) { |
| const { excludePatterns, includePatterns } = config.filters; |
| for (const pattern of excludePatterns) { |
| if (this.matchesPattern(filename, pattern)) { |
| return false; |
| } |
| } |
| if (includePatterns.length === 0) { |
| return true; |
| } |
| for (const pattern of includePatterns) { |
| if (this.matchesPattern(filename, pattern)) { |
| return true; |
| } |
| } |
| return false; |
| } |
| matchesPattern(filename, pattern) { |
| const regexPattern = pattern |
| .replace(/\./g, '\\.') |
| .replace(/\*/g, '.*') |
| .replace(/\?/g, '.') |
| .replace(/\*\*/g, '.*'); |
| return new RegExp(`^${regexPattern}$`).test(filename); |
| } |
| } |
| exports.PrixConfigLoader = PrixConfigLoader; |
| exports.configLoader = new PrixConfigLoader(); |
| function getConfig() { |
| const ctx = context_1.als.getStore(); |
| const workingDir = ctx?.workingDir || process.cwd(); |
| return exports.configLoader.load(workingDir); |
| } |
| function meetsConfidenceThreshold(severity, confidence) { |
| const config = getConfig(); |
| const thresholds = config.confidence; |
| switch (severity) { |
| case 'critical': |
| return confidence >= thresholds.minCritical; |
| case 'major': |
| return confidence >= thresholds.minMajor; |
| case 'minor': |
| return confidence >= thresholds.minMinor; |
| case 'info': |
| return confidence >= thresholds.minInfo; |
| default: |
| return true; |
| } |
| } |
| function meetsMinimumSeverity(severity) { |
| const config = getConfig(); |
| const levels = ['critical', 'major', 'minor', 'info']; |
| const minimumLevel = config.severity.minimumLevel; |
| const minimumIndex = levels.indexOf(minimumLevel); |
| const severityIndex = levels.indexOf(severity.toLowerCase()); |
| return severityIndex >= minimumIndex; |
| } |
| async function lintSuggestion(suggestion, filename, language) { |
| const config = getConfig(); |
| if (!config.linting.enabled) { |
| return { valid: true, errors: [] }; |
| } |
| const errors = []; |
| const workingDir = context_1.als.getStore()?.workingDir || process.cwd(); |
| if (config.linting.prettier) { |
| try { |
| (0, utils_1.prixExec)(`echo "${suggestion.replace(/"/g, '\\"')}" | prettier --stdin-filepath ${filename}`, { |
| cwd: workingDir, |
| stdio: 'pipe' |
| }); |
| } |
| catch { |
| errors.push('Prettier formatting check failed'); |
| } |
| } |
| if (config.linting.eslint && |
| (language === 'javascript' || language === 'typescript')) { |
| try { |
| const ext = filename.endsWith('.ts') ? 'ts' : 'js'; |
| const tempFile = `.prix_temp_suggestion.${ext}`; |
| (0, utils_1.prixExec)(`echo "${suggestion.replace(/"/g, '\\"')}" > ${tempFile} && npx eslint ${tempFile} --format json 2>&1 || true`, { |
| cwd: workingDir, |
| stdio: 'pipe' |
| }); |
| } |
| catch { |
| errors.push('ESLint check failed'); |
| } |
| } |
| return { |
| valid: config.linting.failOnError ? errors.length === 0 : true, |
| errors |
| }; |
| } |
| //# sourceMappingURL=config.js.map |