@juspay/yama 1.1.0 โ†’ 1.2.0

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.
@@ -1,23 +1,156 @@
1
- "use strict";
2
1
  /**
3
2
  * Enhanced Configuration Manager for Yama
4
3
  * Handles configuration loading, validation, and merging from multiple sources
5
4
  */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.configManager = exports.ConfigManager = void 0;
11
- exports.createConfigManager = createConfigManager;
12
- const fs_1 = __importDefault(require("fs"));
13
- const path_1 = __importDefault(require("path"));
14
- const yaml_1 = __importDefault(require("yaml"));
15
- const types_1 = require("../types");
16
- const Logger_1 = require("./Logger");
17
- class ConfigManager {
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import yaml from "yaml";
8
+ import { homedir } from "os";
9
+ import { ConfigurationError } from "../types/index.js";
10
+ import { logger } from "./Logger.js";
11
+ import { validateProviderTokenLimit } from "./ProviderLimits.js";
12
+ export class ConfigManager {
13
+ config = null;
14
+ configPaths = [];
15
+ /**
16
+ * Default configuration
17
+ */
18
+ static DEFAULT_CONFIG = {
19
+ providers: {
20
+ ai: {
21
+ provider: "auto",
22
+ enableFallback: true,
23
+ enableAnalytics: false,
24
+ enableEvaluation: false,
25
+ timeout: "10m",
26
+ retryAttempts: 3,
27
+ temperature: 0.3,
28
+ maxTokens: 65000,
29
+ },
30
+ git: {
31
+ platform: "bitbucket",
32
+ credentials: {
33
+ username: process.env.BITBUCKET_USERNAME || "",
34
+ token: process.env.BITBUCKET_TOKEN || "",
35
+ baseUrl: process.env.BITBUCKET_BASE_URL ||
36
+ "https://your-bitbucket-server.com",
37
+ },
38
+ },
39
+ },
40
+ features: {
41
+ codeReview: {
42
+ enabled: true,
43
+ severityLevels: ["CRITICAL", "MAJOR", "MINOR", "SUGGESTION"],
44
+ categories: [
45
+ "security",
46
+ "performance",
47
+ "maintainability",
48
+ "functionality",
49
+ "error_handling",
50
+ "testing",
51
+ ],
52
+ excludePatterns: ["*.lock", "*.svg", "*.min.js", "*.map"],
53
+ contextLines: 3,
54
+ systemPrompt: "You are an Expert Security Code Reviewer for enterprise applications. Your role is to:\n\n๐Ÿ”’ SECURITY FIRST: Prioritize security vulnerabilities and data protection\nโšก PERFORMANCE AWARE: Identify performance bottlenecks and optimization opportunities\n๐Ÿ—๏ธ QUALITY FOCUSED: Ensure maintainable, readable, and robust code\n๐Ÿ›ก๏ธ ERROR RESILIENT: Verify comprehensive error handling and edge cases\n\nYou provide actionable, educational feedback with specific examples and solutions.\nFocus on critical issues that could impact production systems.",
55
+ focusAreas: [
56
+ "๐Ÿ”’ Security Analysis (CRITICAL PRIORITY)",
57
+ "โšก Performance Review",
58
+ "๐Ÿ—๏ธ Code Quality",
59
+ "๐Ÿงช Testing & Error Handling",
60
+ ],
61
+ },
62
+ descriptionEnhancement: {
63
+ enabled: true,
64
+ preserveContent: true,
65
+ requiredSections: [
66
+ {
67
+ key: "changelog",
68
+ name: "Changelog (Modules Modified)",
69
+ required: true,
70
+ },
71
+ {
72
+ key: "testcases",
73
+ name: "Test Cases (What to be tested)",
74
+ required: true,
75
+ },
76
+ {
77
+ key: "config_changes",
78
+ name: "CAC Config Or Service Config Changes",
79
+ required: true,
80
+ },
81
+ ],
82
+ autoFormat: true,
83
+ systemPrompt: "You are an Expert Technical Writer specializing in pull request documentation. Your role is to:\n\n๐Ÿ“ CLARITY FIRST: Create clear, comprehensive PR descriptions that help reviewers understand the changes\n๐ŸŽฅ STORY TELLING: Explain the 'why' behind changes, not just the 'what'\n๐Ÿ“ˆ STRUCTURED: Follow consistent formatting with required sections\n๐Ÿ”— CONTEXTUAL: Link changes to business value and technical rationale\n\nCRITICAL INSTRUCTION: Return ONLY the enhanced PR description content as clean markdown. Do NOT include any meta-commentary, explanations about what you're doing, or introductory text like \"I will enhance...\" or \"Here is the enhanced description:\". \n\nOutput the enhanced description directly without any wrapper text or explanations.",
84
+ outputTemplate: "# PR Title Enhancement (if needed)\n\n## Summary\n[Clear overview of what this PR accomplishes]\n\n## Changes Made\n[Specific technical changes - be precise]\n\n## Testing\n[How the changes were tested]\n\n## Impact\n[Business/technical impact and considerations]\n\n## Additional Notes\n[Any deployment notes, follow-ups, or special considerations]",
85
+ enhancementInstructions: 'Return ONLY the enhanced PR description as clean markdown. Do NOT include any explanatory text, meta-commentary, or phrases like "Here is the enhanced description:" or "I will enhance...".\n\nStart directly with the enhanced description content using this structure:',
86
+ },
87
+ securityScan: {
88
+ enabled: true,
89
+ level: "strict",
90
+ scanTypes: ["secrets", "vulnerabilities", "dependencies"],
91
+ },
92
+ analytics: {
93
+ enabled: true,
94
+ trackMetrics: true,
95
+ exportFormat: "json",
96
+ },
97
+ },
98
+ cache: {
99
+ enabled: true,
100
+ ttl: "1h",
101
+ maxSize: "100MB",
102
+ storage: "memory",
103
+ },
104
+ performance: {
105
+ batch: {
106
+ enabled: true,
107
+ maxConcurrent: 5,
108
+ delayBetween: "1s",
109
+ },
110
+ optimization: {
111
+ reuseConnections: true,
112
+ compressRequests: true,
113
+ enableHttp2: true,
114
+ },
115
+ },
116
+ rules: {
117
+ security: [
118
+ {
119
+ name: "No hardcoded secrets",
120
+ pattern: "(password|secret|key|token)\\s*[=:]\\s*['\"][^'\"]{8,}['\"]",
121
+ severity: "CRITICAL",
122
+ message: "Hardcoded secrets detected",
123
+ suggestion: "Use environment variables or secure configuration management",
124
+ },
125
+ ],
126
+ performance: [
127
+ {
128
+ name: "Avoid N+1 queries",
129
+ pattern: "for.*\\.(find|get|query|select)",
130
+ severity: "MAJOR",
131
+ message: "Potential N+1 query pattern detected",
132
+ suggestion: "Consider using batch queries or joins",
133
+ },
134
+ ],
135
+ },
136
+ reporting: {
137
+ formats: ["markdown", "json"],
138
+ includeAnalytics: true,
139
+ includeMetrics: true,
140
+ },
141
+ monitoring: {
142
+ enabled: true,
143
+ metrics: ["performance", "cache", "api_calls"],
144
+ exportFormat: "json",
145
+ interval: "5m",
146
+ },
147
+ memoryBank: {
148
+ enabled: true,
149
+ path: "memory-bank",
150
+ fallbackPaths: ["docs/memory-bank", ".memory-bank"],
151
+ },
152
+ };
18
153
  constructor() {
19
- this.config = null;
20
- this.configPaths = [];
21
154
  this.setupConfigPaths();
22
155
  }
23
156
  /**
@@ -25,20 +158,20 @@ class ConfigManager {
25
158
  */
26
159
  setupConfigPaths() {
27
160
  const cwd = process.cwd();
28
- const homeDir = require('os').homedir();
161
+ const homeDir = homedir();
29
162
  this.configPaths = [
30
- path_1.default.join(cwd, 'yama.config.yaml'),
31
- path_1.default.join(cwd, 'yama.config.yml'),
32
- path_1.default.join(cwd, 'yama.config.json'),
33
- path_1.default.join(cwd, '.yama.yaml'),
34
- path_1.default.join(cwd, '.yama.yml'),
35
- path_1.default.join(cwd, '.yama.json'),
36
- path_1.default.join(homeDir, '.yama', 'config.yaml'),
37
- path_1.default.join(homeDir, '.yama', 'config.yml'),
38
- path_1.default.join(homeDir, '.yama', 'config.json'),
39
- path_1.default.join(homeDir, '.config', 'yama', 'config.yaml'),
40
- path_1.default.join(homeDir, '.config', 'yama', 'config.yml'),
41
- path_1.default.join(homeDir, '.config', 'yama', 'config.json')
163
+ path.join(cwd, "yama.config.yaml"),
164
+ path.join(cwd, "yama.config.yml"),
165
+ path.join(cwd, "yama.config.json"),
166
+ path.join(cwd, ".yama.yaml"),
167
+ path.join(cwd, ".yama.yml"),
168
+ path.join(cwd, ".yama.json"),
169
+ path.join(homeDir, ".yama", "config.yaml"),
170
+ path.join(homeDir, ".yama", "config.yml"),
171
+ path.join(homeDir, ".yama", "config.json"),
172
+ path.join(homeDir, ".config", "yama", "config.yaml"),
173
+ path.join(homeDir, ".config", "yama", "config.yml"),
174
+ path.join(homeDir, ".config", "yama", "config.json"),
42
175
  ];
43
176
  }
44
177
  /**
@@ -48,40 +181,42 @@ class ConfigManager {
48
181
  if (this.config) {
49
182
  return this.config;
50
183
  }
51
- Logger_1.logger.debug('Loading Yama configuration...');
184
+ logger.debug("Loading Yama configuration...");
52
185
  // Start with default config
53
186
  let config = this.deepClone(ConfigManager.DEFAULT_CONFIG);
54
187
  // If specific config path provided, use only that
55
188
  if (configPath) {
56
- if (!fs_1.default.existsSync(configPath)) {
57
- throw new types_1.ConfigurationError(`Configuration file not found: ${configPath}`);
189
+ if (!fs.existsSync(configPath)) {
190
+ throw new ConfigurationError(`Configuration file not found: ${configPath}`);
58
191
  }
59
192
  const fileConfig = await this.loadConfigFile(configPath);
60
193
  config = this.mergeConfigs(config, fileConfig);
61
- Logger_1.logger.debug(`Loaded configuration from: ${configPath}`);
194
+ logger.debug(`Loaded configuration from: ${configPath}`);
62
195
  }
63
196
  else {
64
197
  // Search for config files in predefined paths
65
198
  for (const configFilePath of this.configPaths) {
66
- if (fs_1.default.existsSync(configFilePath)) {
199
+ if (fs.existsSync(configFilePath)) {
67
200
  try {
68
201
  const fileConfig = await this.loadConfigFile(configFilePath);
69
202
  config = this.mergeConfigs(config, fileConfig);
70
- Logger_1.logger.debug(`Loaded configuration from: ${configFilePath}`);
203
+ logger.debug(`Loaded configuration from: ${configFilePath}`);
71
204
  break;
72
205
  }
73
206
  catch (error) {
74
- Logger_1.logger.warn(`Failed to load config from ${configFilePath}:`, error);
207
+ logger.warn(`Failed to load config from ${configFilePath}:`, error);
75
208
  }
76
209
  }
77
210
  }
78
211
  }
79
212
  // Override with environment variables
80
213
  config = this.applyEnvironmentOverrides(config);
214
+ // Apply provider-aware token limits
215
+ config = this.applyProviderTokenLimits(config);
81
216
  // Validate configuration
82
217
  this.validateConfig(config);
83
218
  this.config = config;
84
- Logger_1.logger.debug('Configuration loaded successfully');
219
+ logger.debug("Configuration loaded successfully");
85
220
  return config;
86
221
  }
87
222
  /**
@@ -89,22 +224,34 @@ class ConfigManager {
89
224
  */
90
225
  async loadConfigFile(filePath) {
91
226
  try {
92
- const content = fs_1.default.readFileSync(filePath, 'utf8');
93
- const ext = path_1.default.extname(filePath).toLowerCase();
227
+ const content = fs.readFileSync(filePath, "utf8");
228
+ const ext = path.extname(filePath).toLowerCase();
94
229
  switch (ext) {
95
- case '.yaml':
96
- case '.yml':
97
- return yaml_1.default.parse(content);
98
- case '.json':
230
+ case ".yaml":
231
+ case ".yml":
232
+ return yaml.parse(content);
233
+ case ".json":
99
234
  return JSON.parse(content);
100
235
  default:
101
- throw new types_1.ConfigurationError(`Unsupported config file format: ${ext}`);
236
+ throw new ConfigurationError(`Unsupported config file format: ${ext}`);
102
237
  }
103
238
  }
104
239
  catch (error) {
105
- throw new types_1.ConfigurationError(`Failed to parse config file ${filePath}: ${error.message}`);
240
+ throw new ConfigurationError(`Failed to parse config file ${filePath}: ${error.message}`);
106
241
  }
107
242
  }
243
+ /**
244
+ * Apply provider-aware token limits using shared utility
245
+ */
246
+ applyProviderTokenLimits(config) {
247
+ const provider = config.providers.ai.provider || 'auto';
248
+ const configuredTokens = config.providers.ai.maxTokens;
249
+ // Use the shared utility to validate and adjust token limits
250
+ const validatedTokens = validateProviderTokenLimit(provider, configuredTokens, false // Use standard limits for configuration
251
+ );
252
+ config.providers.ai.maxTokens = validatedTokens;
253
+ return config;
254
+ }
108
255
  /**
109
256
  * Apply environment variable overrides
110
257
  */
@@ -138,20 +285,22 @@ class ConfigManager {
138
285
  }
139
286
  // Feature toggles
140
287
  if (env.ENABLE_CODE_REVIEW !== undefined) {
141
- config.features.codeReview.enabled = env.ENABLE_CODE_REVIEW === 'true';
288
+ config.features.codeReview.enabled = env.ENABLE_CODE_REVIEW === "true";
142
289
  }
143
290
  if (env.ENABLE_DESCRIPTION_ENHANCEMENT !== undefined) {
144
- config.features.descriptionEnhancement.enabled = env.ENABLE_DESCRIPTION_ENHANCEMENT === 'true';
291
+ config.features.descriptionEnhancement.enabled =
292
+ env.ENABLE_DESCRIPTION_ENHANCEMENT === "true";
145
293
  }
146
294
  if (env.ENABLE_SECURITY_SCAN !== undefined) {
147
- config.features.securityScan.enabled = env.ENABLE_SECURITY_SCAN === 'true';
295
+ config.features.securityScan.enabled =
296
+ env.ENABLE_SECURITY_SCAN === "true";
148
297
  }
149
298
  if (env.ENABLE_ANALYTICS !== undefined) {
150
- config.features.analytics.enabled = env.ENABLE_ANALYTICS === 'true';
299
+ config.features.analytics.enabled = env.ENABLE_ANALYTICS === "true";
151
300
  }
152
301
  // Cache configuration
153
302
  if (env.CACHE_ENABLED !== undefined) {
154
- config.cache.enabled = env.CACHE_ENABLED === 'true';
303
+ config.cache.enabled = env.CACHE_ENABLED === "true";
155
304
  }
156
305
  if (env.CACHE_TTL) {
157
306
  config.cache.ttl = env.CACHE_TTL;
@@ -160,11 +309,11 @@ class ConfigManager {
160
309
  config.cache.storage = env.CACHE_STORAGE;
161
310
  }
162
311
  // Debug mode
163
- if (env.GUARDIAN_DEBUG === 'true') {
164
- Logger_1.logger.setLevel('debug');
165
- Logger_1.logger.setVerbose(true);
312
+ if (env.GUARDIAN_DEBUG === "true") {
313
+ logger.setLevel("debug");
314
+ logger.setVerbose(true);
166
315
  }
167
- Logger_1.logger.debug('Applied environment variable overrides');
316
+ logger.debug("Applied environment variable overrides");
168
317
  return config;
169
318
  }
170
319
  /**
@@ -174,36 +323,36 @@ class ConfigManager {
174
323
  const errors = [];
175
324
  // Validate AI provider credentials
176
325
  if (!config.providers.ai.provider) {
177
- errors.push('AI provider must be specified');
326
+ errors.push("AI provider must be specified");
178
327
  }
179
328
  // Validate Git provider credentials
180
329
  if (!config.providers.git.credentials.username) {
181
- errors.push('Git username must be specified');
330
+ errors.push("Git username must be specified");
182
331
  }
183
332
  if (!config.providers.git.credentials.token) {
184
- errors.push('Git token must be specified');
333
+ errors.push("Git token must be specified");
185
334
  }
186
335
  // Validate enabled features have required configuration
187
336
  if (config.features.codeReview.enabled) {
188
337
  if (!config.features.codeReview.severityLevels?.length) {
189
- errors.push('Code review severity levels must be specified when enabled');
338
+ errors.push("Code review severity levels must be specified when enabled");
190
339
  }
191
340
  }
192
341
  if (config.features.descriptionEnhancement.enabled) {
193
342
  if (!config.features.descriptionEnhancement.requiredSections?.length) {
194
- errors.push('Description enhancement required sections must be specified when enabled');
343
+ errors.push("Description enhancement required sections must be specified when enabled");
195
344
  }
196
345
  }
197
346
  // Validate cache configuration
198
347
  if (config.cache?.enabled) {
199
348
  if (!config.cache.storage) {
200
- errors.push('Cache storage type must be specified when cache is enabled');
349
+ errors.push("Cache storage type must be specified when cache is enabled");
201
350
  }
202
351
  }
203
352
  if (errors.length > 0) {
204
- throw new types_1.ConfigurationError(`Configuration validation failed:\n${errors.map(e => ` - ${e}`).join('\n')}`);
353
+ throw new ConfigurationError(`Configuration validation failed:\n${errors.map((e) => ` - ${e}`).join("\n")}`);
205
354
  }
206
- Logger_1.logger.debug('Configuration validation passed');
355
+ logger.debug("Configuration validation passed");
207
356
  }
208
357
  /**
209
358
  * Merge two configuration objects deeply
@@ -217,7 +366,9 @@ class ConfigManager {
217
366
  deepMerge(target, source) {
218
367
  const result = { ...target };
219
368
  for (const key in source) {
220
- if (source[key] !== null && typeof source[key] === 'object' && !Array.isArray(source[key])) {
369
+ if (source[key] !== null &&
370
+ typeof source[key] === "object" &&
371
+ !Array.isArray(source[key])) {
221
372
  result[key] = this.deepMerge(target[key] || {}, source[key]);
222
373
  }
223
374
  else {
@@ -237,7 +388,7 @@ class ConfigManager {
237
388
  */
238
389
  getConfig() {
239
390
  if (!this.config) {
240
- throw new types_1.ConfigurationError('Configuration not loaded. Call loadConfig() first.');
391
+ throw new ConfigurationError("Configuration not loaded. Call loadConfig() first.");
241
392
  }
242
393
  return this.config;
243
394
  }
@@ -245,15 +396,15 @@ class ConfigManager {
245
396
  * Create default configuration file
246
397
  */
247
398
  async createDefaultConfig(outputPath) {
248
- const defaultPath = outputPath || path_1.default.join(process.cwd(), 'yama.config.yaml');
249
- const configContent = yaml_1.default.stringify(ConfigManager.DEFAULT_CONFIG, {
399
+ const defaultPath = outputPath || path.join(process.cwd(), "yama.config.yaml");
400
+ const configContent = yaml.stringify(ConfigManager.DEFAULT_CONFIG, {
250
401
  indent: 2,
251
- lineWidth: 100
402
+ lineWidth: 100,
252
403
  });
253
404
  // Add comments to make the config file more user-friendly
254
405
  const commentedConfig = this.addConfigComments(configContent);
255
- fs_1.default.writeFileSync(defaultPath, commentedConfig, 'utf8');
256
- Logger_1.logger.info(`Default configuration created at: ${defaultPath}`);
406
+ fs.writeFileSync(defaultPath, commentedConfig, "utf8");
407
+ logger.info(`Default configuration created at: ${defaultPath}`);
257
408
  return defaultPath;
258
409
  }
259
410
  /**
@@ -266,19 +417,19 @@ class ConfigManager {
266
417
 
267
418
  `;
268
419
  const sections = [
269
- '# AI Provider Configuration',
270
- '# Git Platform Configuration',
271
- '# Feature Configuration',
272
- '# Cache Configuration',
273
- '# Performance Configuration',
274
- '# Custom Rules Configuration',
275
- '# Reporting Configuration'
420
+ "# AI Provider Configuration",
421
+ "# Git Platform Configuration",
422
+ "# Feature Configuration",
423
+ "# Cache Configuration",
424
+ "# Performance Configuration",
425
+ "# Custom Rules Configuration",
426
+ "# Reporting Configuration",
276
427
  ];
277
428
  let commented = header + content;
278
429
  // Add section comments (this is a simplified approach)
279
- sections.forEach(section => {
280
- const key = section.split(' ')[1].toLowerCase();
281
- commented = commented.replace(new RegExp(`^(${key}:)`, 'm'), `${section}\n$1`);
430
+ sections.forEach((section) => {
431
+ const key = section.split(" ")[1].toLowerCase();
432
+ commented = commented.replace(new RegExp(`^(${key}:)`, "m"), `${section}\n$1`);
282
433
  });
283
434
  return commented;
284
435
  }
@@ -288,30 +439,33 @@ class ConfigManager {
288
439
  validateSection(section, config) {
289
440
  try {
290
441
  switch (section) {
291
- case 'providers':
442
+ case "providers":
292
443
  return this.validateProviders(config);
293
- case 'features':
444
+ case "features":
294
445
  return this.validateFeatures(config);
295
- case 'cache':
446
+ case "cache":
296
447
  return this.validateCache(config);
297
448
  default:
298
449
  return true;
299
450
  }
300
451
  }
301
452
  catch (error) {
302
- Logger_1.logger.error(`Validation failed for section ${section}:`, error);
453
+ logger.error(`Validation failed for section ${String(section)}:`, error);
303
454
  return false;
304
455
  }
305
456
  }
306
457
  validateProviders(providers) {
307
- return !!(providers?.ai?.provider && providers?.git?.credentials?.username && providers?.git?.credentials?.token);
458
+ return !!(providers?.ai?.provider &&
459
+ providers?.git?.credentials?.username &&
460
+ providers?.git?.credentials?.token);
308
461
  }
309
462
  validateFeatures(features) {
310
- return !!(features && typeof features === 'object');
463
+ return !!(features && typeof features === "object");
311
464
  }
312
465
  validateCache(cacheConfig) {
313
- if (!cacheConfig?.enabled)
466
+ if (!cacheConfig?.enabled) {
314
467
  return true;
468
+ }
315
469
  return !!(cacheConfig.storage && cacheConfig.ttl);
316
470
  }
317
471
  /**
@@ -319,71 +473,74 @@ class ConfigManager {
319
473
  */
320
474
  getSchema() {
321
475
  return {
322
- type: 'object',
323
- required: ['providers', 'features'],
476
+ type: "object",
477
+ required: ["providers", "features"],
324
478
  properties: {
325
479
  providers: {
326
- type: 'object',
327
- required: ['ai', 'git'],
480
+ type: "object",
481
+ required: ["ai", "git"],
328
482
  properties: {
329
483
  ai: {
330
- type: 'object',
331
- required: ['provider'],
484
+ type: "object",
485
+ required: ["provider"],
332
486
  properties: {
333
- provider: { type: 'string' },
334
- model: { type: 'string' },
335
- enableFallback: { type: 'boolean' },
336
- enableAnalytics: { type: 'boolean' },
337
- timeout: { type: ['string', 'number'] },
338
- temperature: { type: 'number', minimum: 0, maximum: 2 },
339
- maxTokens: { type: 'number', minimum: 1 }
340
- }
487
+ provider: { type: "string" },
488
+ model: { type: "string" },
489
+ enableFallback: { type: "boolean" },
490
+ enableAnalytics: { type: "boolean" },
491
+ timeout: { type: ["string", "number"] },
492
+ temperature: { type: "number", minimum: 0, maximum: 2 },
493
+ maxTokens: { type: "number", minimum: 1 },
494
+ },
341
495
  },
342
496
  git: {
343
- type: 'object',
344
- required: ['platform', 'credentials'],
497
+ type: "object",
498
+ required: ["platform", "credentials"],
345
499
  properties: {
346
- platform: { type: 'string', enum: ['bitbucket', 'github', 'gitlab', 'azure-devops'] },
500
+ platform: {
501
+ type: "string",
502
+ enum: ["bitbucket", "github", "gitlab", "azure-devops"],
503
+ },
347
504
  credentials: {
348
- type: 'object',
349
- required: ['username', 'token'],
505
+ type: "object",
506
+ required: ["username", "token"],
350
507
  properties: {
351
- username: { type: 'string' },
352
- token: { type: 'string' },
353
- baseUrl: { type: 'string' }
354
- }
355
- }
356
- }
357
- }
358
- }
508
+ username: { type: "string" },
509
+ token: { type: "string" },
510
+ baseUrl: { type: "string" },
511
+ },
512
+ },
513
+ },
514
+ },
515
+ },
359
516
  },
360
517
  features: {
361
- type: 'object',
362
- required: ['codeReview', 'descriptionEnhancement'],
518
+ type: "object",
519
+ required: ["codeReview", "descriptionEnhancement"],
363
520
  properties: {
364
521
  codeReview: {
365
- type: 'object',
366
- required: ['enabled'],
522
+ type: "object",
523
+ required: ["enabled"],
367
524
  properties: {
368
- enabled: { type: 'boolean' },
369
- severityLevels: { type: 'array', items: { type: 'string' } },
370
- categories: { type: 'array', items: { type: 'string' } },
371
- excludePatterns: { type: 'array', items: { type: 'string' } }
372
- }
525
+ enabled: { type: "boolean" },
526
+ severityLevels: { type: "array", items: { type: "string" } },
527
+ categories: { type: "array", items: { type: "string" } },
528
+ excludePatterns: { type: "array", items: { type: "string" } },
529
+ },
373
530
  },
374
531
  descriptionEnhancement: {
375
- type: 'object',
376
- required: ['enabled'],
532
+ type: "object",
533
+ required: ["enabled"],
377
534
  properties: {
378
- enabled: { type: 'boolean' },
379
- preserveContent: { type: 'boolean' },
380
- requiredSections: { type: 'array' },
381
- autoFormat: { type: 'boolean' }
382
- }
383
- }
384
- }
385
- }
386
- }
535
+ enabled: { type: "boolean" },
536
+ preserveContent: { type: "boolean" },
537
+ requiredSections: { type: "array" },
538
+ autoFormat: { type: "boolean" },
539
+ },
540
+ },
541
+ },
542
+ },
543
+ },
387
544
  };
388
545
  }
389
546
  /**
@@ -391,7 +548,7 @@ class ConfigManager {
391
548
  */
392
549
  findConfigFile() {
393
550
  for (const configPath of this.configPaths) {
394
- if (fs_1.default.existsSync(configPath)) {
551
+ if (fs.existsSync(configPath)) {
395
552
  return configPath;
396
553
  }
397
554
  }
@@ -402,32 +559,32 @@ class ConfigManager {
402
559
  */
403
560
  watchConfig(callback) {
404
561
  if (!this.configPaths.length) {
405
- Logger_1.logger.warn('No configuration file found to watch');
562
+ logger.warn("No configuration file found to watch");
406
563
  return () => { };
407
564
  }
408
565
  const configPath = this.findConfigFile();
409
566
  if (!configPath) {
410
- Logger_1.logger.warn('No configuration file found to watch');
567
+ logger.warn("No configuration file found to watch");
411
568
  return () => { };
412
569
  }
413
- Logger_1.logger.debug(`Watching configuration file: ${configPath}`);
414
- fs_1.default.watchFile(configPath, { interval: 1000 }, async () => {
570
+ logger.debug(`Watching configuration file: ${configPath}`);
571
+ fs.watchFile(configPath, { interval: 1000 }, async () => {
415
572
  try {
416
- Logger_1.logger.info('Configuration file changed, reloading...');
573
+ logger.info("Configuration file changed, reloading...");
417
574
  const newConfig = await this.loadConfig();
418
575
  if (callback) {
419
576
  callback(newConfig);
420
577
  }
421
- Logger_1.logger.success('Configuration reloaded successfully');
578
+ logger.success("Configuration reloaded successfully");
422
579
  }
423
580
  catch (error) {
424
- Logger_1.logger.error(`Failed to reload configuration: ${error.message}`);
581
+ logger.error(`Failed to reload configuration: ${error.message}`);
425
582
  }
426
583
  });
427
584
  // Return cleanup function
428
585
  return () => {
429
- fs_1.default.unwatchFile(configPath);
430
- Logger_1.logger.debug('Stopped watching configuration file');
586
+ fs.unwatchFile(configPath);
587
+ logger.debug("Stopped watching configuration file");
431
588
  };
432
589
  }
433
590
  /**
@@ -437,119 +594,10 @@ class ConfigManager {
437
594
  return this.watchConfig(callback);
438
595
  }
439
596
  }
440
- exports.ConfigManager = ConfigManager;
441
- /**
442
- * Default configuration
443
- */
444
- ConfigManager.DEFAULT_CONFIG = {
445
- providers: {
446
- ai: {
447
- provider: 'auto',
448
- enableFallback: true,
449
- enableAnalytics: false,
450
- enableEvaluation: false,
451
- timeout: '10m',
452
- retryAttempts: 3,
453
- temperature: 0.3,
454
- maxTokens: 1000000
455
- },
456
- git: {
457
- platform: 'bitbucket',
458
- credentials: {
459
- username: process.env.BITBUCKET_USERNAME || '',
460
- token: process.env.BITBUCKET_TOKEN || '',
461
- baseUrl: process.env.BITBUCKET_BASE_URL || 'https://your-bitbucket-server.com'
462
- }
463
- }
464
- },
465
- features: {
466
- codeReview: {
467
- enabled: true,
468
- severityLevels: ['CRITICAL', 'MAJOR', 'MINOR', 'SUGGESTION'],
469
- categories: ['security', 'performance', 'maintainability', 'functionality', 'error_handling', 'testing'],
470
- excludePatterns: ['*.lock', '*.svg', '*.min.js', '*.map'],
471
- contextLines: 3,
472
- systemPrompt: 'You are an Expert Security Code Reviewer for enterprise applications. Your role is to:\n\n๐Ÿ”’ SECURITY FIRST: Prioritize security vulnerabilities and data protection\nโšก PERFORMANCE AWARE: Identify performance bottlenecks and optimization opportunities\n๐Ÿ—๏ธ QUALITY FOCUSED: Ensure maintainable, readable, and robust code\n๐Ÿ›ก๏ธ ERROR RESILIENT: Verify comprehensive error handling and edge cases\n\nYou provide actionable, educational feedback with specific examples and solutions.\nFocus on critical issues that could impact production systems.',
473
- focusAreas: ['๐Ÿ”’ Security Analysis (CRITICAL PRIORITY)', 'โšก Performance Review', '๐Ÿ—๏ธ Code Quality', '๐Ÿงช Testing & Error Handling']
474
- },
475
- descriptionEnhancement: {
476
- enabled: true,
477
- preserveContent: true,
478
- requiredSections: [
479
- { key: 'changelog', name: 'Changelog (Modules Modified)', required: true },
480
- { key: 'testcases', name: 'Test Cases (What to be tested)', required: true },
481
- { key: 'config_changes', name: 'CAC Config Or Service Config Changes', required: true }
482
- ],
483
- autoFormat: true,
484
- systemPrompt: 'You are an Expert Technical Writer specializing in pull request documentation. Your role is to:\n\n๐Ÿ“ CLARITY FIRST: Create clear, comprehensive PR descriptions that help reviewers understand the changes\n๐ŸŽฅ STORY TELLING: Explain the \'why\' behind changes, not just the \'what\'\n๐Ÿ“ˆ STRUCTURED: Follow consistent formatting with required sections\n๐Ÿ”— CONTEXTUAL: Link changes to business value and technical rationale\n\nCRITICAL INSTRUCTION: Return ONLY the enhanced PR description content as clean markdown. Do NOT include any meta-commentary, explanations about what you\'re doing, or introductory text like "I will enhance..." or "Here is the enhanced description:". \n\nOutput the enhanced description directly without any wrapper text or explanations.',
485
- outputTemplate: '# PR Title Enhancement (if needed)\n\n## Summary\n[Clear overview of what this PR accomplishes]\n\n## Changes Made\n[Specific technical changes - be precise]\n\n## Testing\n[How the changes were tested]\n\n## Impact\n[Business/technical impact and considerations]\n\n## Additional Notes\n[Any deployment notes, follow-ups, or special considerations]',
486
- enhancementInstructions: 'Return ONLY the enhanced PR description as clean markdown. Do NOT include any explanatory text, meta-commentary, or phrases like "Here is the enhanced description:" or "I will enhance...".\n\nStart directly with the enhanced description content using this structure:'
487
- },
488
- securityScan: {
489
- enabled: true,
490
- level: 'strict',
491
- scanTypes: ['secrets', 'vulnerabilities', 'dependencies']
492
- },
493
- analytics: {
494
- enabled: true,
495
- trackMetrics: true,
496
- exportFormat: 'json'
497
- }
498
- },
499
- cache: {
500
- enabled: true,
501
- ttl: '1h',
502
- maxSize: '100MB',
503
- storage: 'memory'
504
- },
505
- performance: {
506
- batch: {
507
- enabled: true,
508
- maxConcurrent: 5,
509
- delayBetween: '1s'
510
- },
511
- optimization: {
512
- reuseConnections: true,
513
- compressRequests: true,
514
- enableHttp2: true
515
- }
516
- },
517
- rules: {
518
- security: [
519
- {
520
- name: 'No hardcoded secrets',
521
- pattern: '(password|secret|key|token)\\s*[=:]\\s*[\'"][^\'"]{8,}[\'"]',
522
- severity: 'CRITICAL',
523
- message: 'Hardcoded secrets detected',
524
- suggestion: 'Use environment variables or secure configuration management'
525
- }
526
- ],
527
- performance: [
528
- {
529
- name: 'Avoid N+1 queries',
530
- pattern: 'for.*\\.(find|get|query|select)',
531
- severity: 'MAJOR',
532
- message: 'Potential N+1 query pattern detected',
533
- suggestion: 'Consider using batch queries or joins'
534
- }
535
- ]
536
- },
537
- reporting: {
538
- formats: ['markdown', 'json'],
539
- includeAnalytics: true,
540
- includeMetrics: true
541
- },
542
- monitoring: {
543
- enabled: true,
544
- metrics: ['performance', 'cache', 'api_calls'],
545
- exportFormat: 'json',
546
- interval: '5m'
547
- }
548
- };
549
597
  // Export singleton instance
550
- exports.configManager = new ConfigManager();
598
+ export const configManager = new ConfigManager();
551
599
  // Export factory function
552
- function createConfigManager() {
600
+ export function createConfigManager() {
553
601
  return new ConfigManager();
554
602
  }
555
603
  //# sourceMappingURL=ConfigManager.js.map