@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,22 +1,24 @@
1
- "use strict";
2
1
  /**
3
2
  * Yama - Unified orchestrator class
4
3
  * The main class that coordinates all operations using shared context
5
4
  */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.guardian = exports.Guardian = void 0;
8
- exports.createGuardian = createGuardian;
9
- const types_1 = require("../types");
10
- const BitbucketProvider_1 = require("./providers/BitbucketProvider");
11
- const ContextGatherer_1 = require("./ContextGatherer");
12
- const CodeReviewer_1 = require("../features/CodeReviewer");
13
- const DescriptionEnhancer_1 = require("../features/DescriptionEnhancer");
14
- const Logger_1 = require("../utils/Logger");
15
- const ConfigManager_1 = require("../utils/ConfigManager");
16
- const Cache_1 = require("../utils/Cache");
17
- class Guardian {
5
+ import { GuardianError, } from "../types/index.js";
6
+ import { BitbucketProvider } from "./providers/BitbucketProvider.js";
7
+ import { ContextGatherer } from "./ContextGatherer.js";
8
+ import { CodeReviewer } from "../features/CodeReviewer.js";
9
+ import { DescriptionEnhancer } from "../features/DescriptionEnhancer.js";
10
+ import { logger } from "../utils/Logger.js";
11
+ import { configManager } from "../utils/ConfigManager.js";
12
+ import { cache } from "../utils/Cache.js";
13
+ export class Guardian {
14
+ config;
15
+ bitbucketProvider;
16
+ contextGatherer;
17
+ codeReviewer;
18
+ descriptionEnhancer;
19
+ neurolink;
20
+ initialized = false;
18
21
  constructor(config) {
19
- this.initialized = false;
20
22
  this.config = {};
21
23
  if (config) {
22
24
  this.config = { ...this.config, ...config };
@@ -30,27 +32,26 @@ class Guardian {
30
32
  return;
31
33
  }
32
34
  try {
33
- Logger_1.logger.badge();
34
- Logger_1.logger.phase('🚀 Initializing Yama...');
35
+ logger.badge();
36
+ logger.phase("🚀 Initializing Yama...");
35
37
  // Load configuration
36
- this.config = await ConfigManager_1.configManager.loadConfig(configPath);
38
+ this.config = await configManager.loadConfig(configPath);
37
39
  // Initialize providers
38
- this.bitbucketProvider = new BitbucketProvider_1.BitbucketProvider(this.config.providers.git.credentials);
40
+ this.bitbucketProvider = new BitbucketProvider(this.config.providers.git.credentials);
39
41
  await this.bitbucketProvider.initialize();
40
- // Initialize NeuroLink with eval-based dynamic import to bypass TypeScript compilation
41
- const dynamicImport = eval('(specifier) => import(specifier)');
42
- const { NeuroLink } = await dynamicImport('@juspay/neurolink');
42
+ // Initialize NeuroLink with native ESM dynamic import
43
+ const { NeuroLink } = await import("@juspay/neurolink");
43
44
  this.neurolink = new NeuroLink();
44
45
  // Initialize core components
45
- this.contextGatherer = new ContextGatherer_1.ContextGatherer(this.bitbucketProvider, this.config.providers.ai);
46
- this.codeReviewer = new CodeReviewer_1.CodeReviewer(this.bitbucketProvider, this.config.providers.ai, this.config.features.codeReview);
47
- this.descriptionEnhancer = new DescriptionEnhancer_1.DescriptionEnhancer(this.bitbucketProvider, this.config.providers.ai);
46
+ this.contextGatherer = new ContextGatherer(this.bitbucketProvider, this.config.providers.ai);
47
+ this.codeReviewer = new CodeReviewer(this.bitbucketProvider, this.config.providers.ai, this.config.features.codeReview);
48
+ this.descriptionEnhancer = new DescriptionEnhancer(this.bitbucketProvider, this.config.providers.ai);
48
49
  this.initialized = true;
49
- Logger_1.logger.success('✅ Yama initialized successfully');
50
+ logger.success("✅ Yama initialized successfully");
50
51
  }
51
52
  catch (error) {
52
- Logger_1.logger.error(`Failed to initialize Yama: ${error.message}`);
53
- throw new types_1.GuardianError('INITIALIZATION_ERROR', `Initialization failed: ${error.message}`);
53
+ logger.error(`Failed to initialize Yama: ${error.message}`);
54
+ throw new GuardianError("INITIALIZATION_ERROR", `Initialization failed: ${error.message}`);
54
55
  }
55
56
  }
56
57
  /**
@@ -61,30 +62,30 @@ class Guardian {
61
62
  const startTime = Date.now();
62
63
  const operations = [];
63
64
  try {
64
- Logger_1.logger.operation('PR Processing', 'started');
65
- Logger_1.logger.info(`Target: ${options.workspace}/${options.repository}`);
66
- Logger_1.logger.info(`Operations: ${options.operations.join(', ')}`);
67
- Logger_1.logger.info(`Mode: ${options.dryRun ? 'DRY RUN' : 'LIVE'}`);
65
+ logger.operation("PR Processing", "started");
66
+ logger.info(`Target: ${options.workspace}/${options.repository}`);
67
+ logger.info(`Operations: ${options.operations.join(", ")}`);
68
+ logger.info(`Mode: ${options.dryRun ? "DRY RUN" : "LIVE"}`);
68
69
  // Step 1: Gather unified context ONCE for all operations
69
- Logger_1.logger.phase('📋 Gathering unified context...');
70
+ logger.phase("📋 Gathering unified context...");
70
71
  const context = await this.gatherUnifiedContext(options);
71
- Logger_1.logger.success(`Context ready: PR #${context.pr.id} - "${context.pr.title}"`);
72
- Logger_1.logger.info(`Files: ${context.diffStrategy.fileCount}, Strategy: ${context.diffStrategy.strategy}`);
72
+ logger.success(`Context ready: PR #${context.pr.id} - "${context.pr.title}"`);
73
+ logger.info(`Files: ${context.diffStrategy.fileCount}, Strategy: ${context.diffStrategy.strategy}`);
73
74
  // Step 2: Execute requested operations using shared context
74
75
  for (const operation of options.operations) {
75
- if (operation === 'all') {
76
+ if (operation === "all") {
76
77
  // Execute all available operations
77
- operations.push(await this.executeOperation('review', context, options));
78
- operations.push(await this.executeOperation('enhance-description', context, options));
78
+ operations.push(await this.executeOperation("review", context, options));
79
+ operations.push(await this.executeOperation("enhance-description", context, options));
79
80
  }
80
81
  else {
81
82
  operations.push(await this.executeOperation(operation, context, options));
82
83
  }
83
84
  }
84
85
  const duration = Date.now() - startTime;
85
- const successCount = operations.filter(op => op.status === 'success').length;
86
- const errorCount = operations.filter(op => op.status === 'error').length;
87
- const skippedCount = operations.filter(op => op.status === 'skipped').length;
86
+ const successCount = operations.filter((op) => op.status === "success").length;
87
+ const errorCount = operations.filter((op) => op.status === "error").length;
88
+ const skippedCount = operations.filter((op) => op.status === "skipped").length;
88
89
  const result = {
89
90
  pullRequest: context.pr,
90
91
  operations,
@@ -93,17 +94,17 @@ class Guardian {
93
94
  successCount,
94
95
  errorCount,
95
96
  skippedCount,
96
- totalDuration: duration
97
- }
97
+ totalDuration: duration,
98
+ },
98
99
  };
99
- Logger_1.logger.operation('PR Processing', 'completed');
100
- Logger_1.logger.success(`✅ Processing completed in ${Math.round(duration / 1000)}s: ` +
100
+ logger.operation("PR Processing", "completed");
101
+ logger.success(`✅ Processing completed in ${Math.round(duration / 1000)}s: ` +
101
102
  `${successCount} success, ${errorCount} errors, ${skippedCount} skipped`);
102
103
  return result;
103
104
  }
104
105
  catch (error) {
105
- Logger_1.logger.operation('PR Processing', 'failed');
106
- Logger_1.logger.error(`Processing failed: ${error.message}`);
106
+ logger.operation("PR Processing", "failed");
107
+ logger.error(`Processing failed: ${error.message}`);
107
108
  throw error;
108
109
  }
109
110
  }
@@ -116,27 +117,27 @@ class Guardian {
116
117
  try {
117
118
  // Initial update
118
119
  yield {
119
- operation: 'all',
120
- status: 'started',
121
- message: 'Yama processing initiated',
122
- timestamp: new Date().toISOString()
120
+ operation: "all",
121
+ status: "started",
122
+ message: "Yama processing initiated",
123
+ timestamp: new Date().toISOString(),
123
124
  };
124
125
  // Context gathering phase
125
126
  yield {
126
- operation: 'all',
127
- status: 'progress',
127
+ operation: "all",
128
+ status: "progress",
128
129
  progress: 10,
129
- message: 'Gathering unified context...',
130
- timestamp: new Date().toISOString()
130
+ message: "Gathering unified context...",
131
+ timestamp: new Date().toISOString(),
131
132
  };
132
133
  const context = await this.gatherUnifiedContext(options);
133
134
  yield {
134
- operation: 'all',
135
- status: 'progress',
135
+ operation: "all",
136
+ status: "progress",
136
137
  progress: 30,
137
138
  message: `Context ready: PR #${context.pr.id}`,
138
139
  data: { prId: context.pr.id, title: context.pr.title },
139
- timestamp: new Date().toISOString()
140
+ timestamp: new Date().toISOString(),
140
141
  };
141
142
  // Execute operations with progress updates
142
143
  const totalOps = options.operations.length;
@@ -144,29 +145,29 @@ class Guardian {
144
145
  for (const operation of options.operations) {
145
146
  yield {
146
147
  operation,
147
- status: 'started',
148
+ status: "started",
148
149
  message: `Starting ${operation}...`,
149
- timestamp: new Date().toISOString()
150
+ timestamp: new Date().toISOString(),
150
151
  };
151
152
  try {
152
153
  const result = await this.executeOperation(operation, context, options);
153
- if (result.status === 'error') {
154
+ if (result.status === "error") {
154
155
  yield {
155
156
  operation,
156
- status: 'error',
157
+ status: "error",
157
158
  message: `${operation} failed: ${result.error}`,
158
- timestamp: new Date().toISOString()
159
+ timestamp: new Date().toISOString(),
159
160
  };
160
161
  }
161
162
  else {
162
163
  completedOps++;
163
164
  yield {
164
165
  operation,
165
- status: 'completed',
166
+ status: "completed",
166
167
  progress: 30 + Math.round((completedOps / totalOps) * 60),
167
168
  message: `${operation} completed`,
168
169
  data: result,
169
- timestamp: new Date().toISOString()
170
+ timestamp: new Date().toISOString(),
170
171
  };
171
172
  }
172
173
  }
@@ -174,28 +175,28 @@ class Guardian {
174
175
  // This catch is for unexpected errors that bypass executeOperation's own error handling
175
176
  yield {
176
177
  operation,
177
- status: 'error',
178
+ status: "error",
178
179
  message: `${operation} failed: ${error.message}`,
179
- timestamp: new Date().toISOString()
180
+ timestamp: new Date().toISOString(),
180
181
  };
181
182
  }
182
183
  }
183
184
  // Final completion
184
185
  const duration = Date.now() - startTime;
185
186
  yield {
186
- operation: 'all',
187
- status: 'completed',
187
+ operation: "all",
188
+ status: "completed",
188
189
  progress: 100,
189
190
  message: `Processing completed in ${Math.round(duration / 1000)}s`,
190
- timestamp: new Date().toISOString()
191
+ timestamp: new Date().toISOString(),
191
192
  };
192
193
  }
193
194
  catch (error) {
194
195
  yield {
195
- operation: 'all',
196
- status: 'error',
196
+ operation: "all",
197
+ status: "error",
197
198
  message: `Processing failed: ${error.message}`,
198
- timestamp: new Date().toISOString()
199
+ timestamp: new Date().toISOString(),
199
200
  };
200
201
  }
201
202
  }
@@ -207,22 +208,22 @@ class Guardian {
207
208
  workspace: options.workspace,
208
209
  repository: options.repository,
209
210
  branch: options.branch,
210
- pullRequestId: options.pullRequestId
211
+ pullRequestId: options.pullRequestId,
211
212
  };
212
213
  // Check if we have cached context first
213
214
  const cachedContext = await this.contextGatherer.getCachedContext(identifier);
214
215
  if (cachedContext && options.config?.cache?.enabled !== false) {
215
- Logger_1.logger.debug('✓ Using cached context');
216
+ logger.debug("✓ Using cached context");
216
217
  return cachedContext;
217
218
  }
218
219
  // Determine what operations need diff data
219
- const needsDiff = options.operations.some(op => op === 'review' || op === 'security-scan' || op === 'all');
220
+ const needsDiff = options.operations.some((op) => op === "review" || op === "security-scan" || op === "all");
220
221
  const contextOptions = {
221
222
  excludePatterns: this.config.features.codeReview.excludePatterns,
222
223
  contextLines: this.config.features.codeReview.contextLines,
223
224
  forceRefresh: false,
224
225
  includeDiff: needsDiff,
225
- diffStrategyConfig: this.config.features.diffStrategy
226
+ diffStrategyConfig: this.config.features.diffStrategy,
226
227
  };
227
228
  return await this.contextGatherer.gatherContext(identifier, contextOptions);
228
229
  }
@@ -234,37 +235,37 @@ class Guardian {
234
235
  try {
235
236
  let data;
236
237
  switch (operation) {
237
- case 'review':
238
+ case "review":
238
239
  data = await this.executeCodeReview(context, options);
239
240
  break;
240
- case 'enhance-description':
241
+ case "enhance-description":
241
242
  data = await this.executeDescriptionEnhancement(context, options);
242
243
  break;
243
- case 'security-scan':
244
+ case "security-scan":
244
245
  // TODO: Implement in future phases
245
- throw new Error('Security scan not implemented in Phase 1');
246
- case 'analytics':
246
+ throw new Error("Security scan not implemented in Phase 1");
247
+ case "analytics":
247
248
  // TODO: Implement in future phases
248
- throw new Error('Analytics not implemented in Phase 1');
249
+ throw new Error("Analytics not implemented in Phase 1");
249
250
  default:
250
251
  throw new Error(`Unknown operation: ${operation}`);
251
252
  }
252
253
  return {
253
254
  operation,
254
- status: 'success',
255
+ status: "success",
255
256
  data,
256
257
  duration: Date.now() - startTime,
257
- timestamp: new Date().toISOString()
258
+ timestamp: new Date().toISOString(),
258
259
  };
259
260
  }
260
261
  catch (error) {
261
- Logger_1.logger.error(`Operation ${operation} failed: ${error.message}`);
262
+ logger.error(`Operation ${operation} failed: ${error.message}`);
262
263
  return {
263
264
  operation,
264
- status: 'error',
265
+ status: "error",
265
266
  error: error.message,
266
267
  duration: Date.now() - startTime,
267
- timestamp: new Date().toISOString()
268
+ timestamp: new Date().toISOString(),
268
269
  };
269
270
  }
270
271
  }
@@ -273,18 +274,18 @@ class Guardian {
273
274
  */
274
275
  async executeCodeReview(context, options) {
275
276
  if (!this.config.features.codeReview.enabled) {
276
- Logger_1.logger.info('Code review is disabled in configuration');
277
- return { skipped: true, reason: 'disabled in config' };
277
+ logger.info("Code review is disabled in configuration");
278
+ return { skipped: true, reason: "disabled in config" };
278
279
  }
279
- Logger_1.logger.phase('🔍 Executing code review...');
280
+ logger.phase("🔍 Executing code review...");
280
281
  const reviewOptions = {
281
282
  workspace: context.identifier.workspace,
282
283
  repository: context.identifier.repository,
283
284
  pullRequestId: context.identifier.pullRequestId,
284
285
  dryRun: options.dryRun,
285
- verbose: Logger_1.logger.getConfig().verbose,
286
+ verbose: logger.getConfig().verbose,
286
287
  excludePatterns: this.config.features.codeReview.excludePatterns,
287
- contextLines: this.config.features.codeReview.contextLines
288
+ contextLines: this.config.features.codeReview.contextLines,
288
289
  };
289
290
  // Use the already gathered context instead of gathering again
290
291
  return await this.codeReviewer.reviewCodeWithContext(context, reviewOptions);
@@ -294,19 +295,19 @@ class Guardian {
294
295
  */
295
296
  async executeDescriptionEnhancement(context, options) {
296
297
  if (!this.config.features.descriptionEnhancement.enabled) {
297
- Logger_1.logger.info('Description enhancement is disabled in configuration');
298
- return { skipped: true, reason: 'disabled in config' };
298
+ logger.info("Description enhancement is disabled in configuration");
299
+ return { skipped: true, reason: "disabled in config" };
299
300
  }
300
- Logger_1.logger.phase('📝 Executing description enhancement...');
301
+ logger.phase("📝 Executing description enhancement...");
301
302
  const enhancementOptions = {
302
303
  workspace: context.identifier.workspace,
303
304
  repository: context.identifier.repository,
304
305
  pullRequestId: context.identifier.pullRequestId,
305
306
  dryRun: options.dryRun,
306
- verbose: Logger_1.logger.getConfig().verbose,
307
+ verbose: logger.getConfig().verbose,
307
308
  preserveContent: this.config.features.descriptionEnhancement.preserveContent,
308
309
  ensureRequiredSections: true,
309
- customSections: this.config.features.descriptionEnhancement.requiredSections
310
+ customSections: this.config.features.descriptionEnhancement.requiredSections,
310
311
  };
311
312
  // Use the already gathered context instead of gathering again
312
313
  return await this.descriptionEnhancer.enhanceWithContext(context, enhancementOptions);
@@ -323,22 +324,22 @@ class Guardian {
323
324
  workspace: options.workspace,
324
325
  repository: options.repository,
325
326
  branch: options.branch,
326
- pullRequestId: options.pullRequestId
327
+ pullRequestId: options.pullRequestId,
327
328
  };
328
- Logger_1.logger.operation('Code Review', 'started');
329
+ logger.operation("Code Review", "started");
329
330
  try {
330
331
  // Gather context specifically for code review
331
332
  const context = await this.contextGatherer.gatherContext(identifier, {
332
333
  excludePatterns: options.excludePatterns,
333
334
  contextLines: options.contextLines,
334
- includeDiff: true
335
+ includeDiff: true,
335
336
  });
336
337
  const result = await this.codeReviewer.reviewCodeWithContext(context, options);
337
- Logger_1.logger.operation('Code Review', 'completed');
338
+ logger.operation("Code Review", "completed");
338
339
  return result;
339
340
  }
340
341
  catch (error) {
341
- Logger_1.logger.operation('Code Review', 'failed');
342
+ logger.operation("Code Review", "failed");
342
343
  throw error;
343
344
  }
344
345
  }
@@ -351,20 +352,20 @@ class Guardian {
351
352
  workspace: options.workspace,
352
353
  repository: options.repository,
353
354
  branch: options.branch,
354
- pullRequestId: options.pullRequestId
355
+ pullRequestId: options.pullRequestId,
355
356
  };
356
- Logger_1.logger.operation('Description Enhancement', 'started');
357
+ logger.operation("Description Enhancement", "started");
357
358
  try {
358
359
  // Gather context specifically for description enhancement
359
360
  const context = await this.contextGatherer.gatherContext(identifier, {
360
- includeDiff: true // Description enhancement may need to see changes
361
+ includeDiff: true, // Description enhancement may need to see changes
361
362
  });
362
363
  const result = await this.descriptionEnhancer.enhanceWithContext(context, options);
363
- Logger_1.logger.operation('Description Enhancement', 'completed');
364
+ logger.operation("Description Enhancement", "completed");
364
365
  return result;
365
366
  }
366
367
  catch (error) {
367
- Logger_1.logger.operation('Description Enhancement', 'failed');
368
+ logger.operation("Description Enhancement", "failed");
368
369
  throw error;
369
370
  }
370
371
  }
@@ -379,17 +380,17 @@ class Guardian {
379
380
  // Check cache
380
381
  components.cache = {
381
382
  healthy: true,
382
- stats: Cache_1.cache.stats()
383
+ stats: cache.stats(),
383
384
  };
384
385
  // Check NeuroLink (if initialized)
385
386
  components.neurolink = {
386
387
  healthy: true,
387
- initialized: !!this.neurolink
388
+ initialized: !!this.neurolink,
388
389
  };
389
390
  const allHealthy = Object.values(components).every((comp) => comp.healthy);
390
391
  return {
391
392
  healthy: allHealthy,
392
- components
393
+ components,
393
394
  };
394
395
  }
395
396
  catch (error) {
@@ -397,8 +398,8 @@ class Guardian {
397
398
  healthy: false,
398
399
  components: {
399
400
  ...components,
400
- error: error.message
401
- }
401
+ error: error.message,
402
+ },
402
403
  };
403
404
  }
404
405
  }
@@ -410,22 +411,22 @@ class Guardian {
410
411
  initialized: this.initialized,
411
412
  config: {
412
413
  features: Object.keys(this.config.features || {}),
413
- cacheEnabled: this.config.cache?.enabled
414
+ cacheEnabled: this.config.cache?.enabled,
414
415
  },
415
416
  providers: {
416
417
  bitbucket: this.bitbucketProvider?.getStats(),
417
- context: this.contextGatherer?.getStats()
418
+ context: this.contextGatherer?.getStats(),
418
419
  },
419
- cache: Cache_1.cache.stats()
420
+ cache: cache.stats(),
420
421
  };
421
422
  }
422
423
  /**
423
424
  * Clear all caches
424
425
  */
425
426
  clearCache() {
426
- Cache_1.cache.clear();
427
+ cache.clear();
427
428
  this.bitbucketProvider?.clearCache();
428
- Logger_1.logger.info('All caches cleared');
429
+ logger.info("All caches cleared");
429
430
  }
430
431
  /**
431
432
  * Ensure Guardian is initialized
@@ -439,19 +440,18 @@ class Guardian {
439
440
  * Shutdown Guardian gracefully
440
441
  */
441
442
  async shutdown() {
442
- Logger_1.logger.info('Shutting down Yama...');
443
+ logger.info("Shutting down Yama...");
443
444
  // Clear caches
444
445
  this.clearCache();
445
446
  // Reset state
446
447
  this.initialized = false;
447
- Logger_1.logger.success('Yama shutdown complete');
448
+ logger.success("Yama shutdown complete");
448
449
  }
449
450
  }
450
- exports.Guardian = Guardian;
451
451
  // Export factory function
452
- function createGuardian(config) {
452
+ export function createGuardian(config) {
453
453
  return new Guardian(config);
454
454
  }
455
455
  // Export default instance
456
- exports.guardian = new Guardian();
456
+ export const guardian = new Guardian();
457
457
  //# sourceMappingURL=Guardian.js.map
@@ -2,7 +2,7 @@
2
2
  * Enhanced Bitbucket Provider - Optimized from both pr-police.js and pr-describe.js
3
3
  * Provides unified, cached, and optimized Bitbucket operations
4
4
  */
5
- import { PRIdentifier, PRInfo, PRDiff, GitCredentials } from '../../types';
5
+ import { PRIdentifier, PRInfo, PRDiff, GitCredentials } from "../../types/index.js";
6
6
  export interface BitbucketMCPResponse {
7
7
  content?: Array<{
8
8
  text?: string;
@@ -61,13 +61,13 @@ export declare class BitbucketProvider {
61
61
  addComment(identifier: PRIdentifier, commentText: string, options?: {
62
62
  filePath?: string;
63
63
  lineNumber?: number;
64
- lineType?: 'ADDED' | 'REMOVED' | 'CONTEXT';
64
+ lineType?: "ADDED" | "REMOVED" | "CONTEXT";
65
65
  codeSnippet?: string;
66
66
  searchContext?: {
67
67
  before: string[];
68
68
  after: string[];
69
69
  };
70
- matchStrategy?: 'exact' | 'best' | 'strict';
70
+ matchStrategy?: "exact" | "best" | "strict";
71
71
  suggestion?: string;
72
72
  }): Promise<{
73
73
  success: boolean;