@juspay/yama 1.1.0 โ†’ 1.1.1

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