@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.
- package/CHANGELOG.md +27 -1
- package/README.md +151 -119
- package/dist/cli/index.js +201 -200
- package/dist/core/ContextGatherer.d.ts +3 -3
- package/dist/core/ContextGatherer.js +145 -149
- package/dist/core/Guardian.d.ts +1 -1
- package/dist/core/Guardian.js +122 -122
- package/dist/core/providers/BitbucketProvider.d.ts +3 -3
- package/dist/core/providers/BitbucketProvider.js +129 -121
- package/dist/features/CodeReviewer.d.ts +3 -3
- package/dist/features/CodeReviewer.js +290 -221
- package/dist/features/DescriptionEnhancer.d.ts +3 -3
- package/dist/features/DescriptionEnhancer.js +115 -94
- package/dist/index.d.ts +11 -11
- package/dist/index.js +10 -48
- package/dist/types/index.d.ts +21 -21
- package/dist/types/index.js +13 -18
- package/dist/utils/Cache.d.ts +1 -1
- package/dist/utils/Cache.js +62 -68
- package/dist/utils/ConfigManager.d.ts +1 -1
- package/dist/utils/ConfigManager.js +281 -253
- package/dist/utils/Logger.d.ts +2 -2
- package/dist/utils/Logger.js +69 -67
- package/package.json +7 -6
- package/yama.config.example.yaml +28 -21
package/dist/core/Guardian.js
CHANGED
|
@@ -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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
+
logger.badge();
|
|
36
|
+
logger.phase("🚀 Initializing Yama...");
|
|
35
37
|
// Load configuration
|
|
36
|
-
this.config = await
|
|
38
|
+
this.config = await configManager.loadConfig(configPath);
|
|
37
39
|
// Initialize providers
|
|
38
|
-
this.bitbucketProvider = new
|
|
40
|
+
this.bitbucketProvider = new BitbucketProvider(this.config.providers.git.credentials);
|
|
39
41
|
await this.bitbucketProvider.initialize();
|
|
40
|
-
// Initialize NeuroLink with
|
|
41
|
-
const
|
|
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
|
|
46
|
-
this.codeReviewer = new
|
|
47
|
-
this.descriptionEnhancer = new
|
|
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
|
-
|
|
50
|
+
logger.success("✅ Yama initialized successfully");
|
|
50
51
|
}
|
|
51
52
|
catch (error) {
|
|
52
|
-
|
|
53
|
-
throw new
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
-
|
|
70
|
+
logger.phase("📋 Gathering unified context...");
|
|
70
71
|
const context = await this.gatherUnifiedContext(options);
|
|
71
|
-
|
|
72
|
-
|
|
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 ===
|
|
76
|
+
if (operation === "all") {
|
|
76
77
|
// Execute all available operations
|
|
77
|
-
operations.push(await this.executeOperation(
|
|
78
|
-
operations.push(await this.executeOperation(
|
|
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 ===
|
|
86
|
-
const errorCount = operations.filter(op => op.status ===
|
|
87
|
-
const skippedCount = operations.filter(op => op.status ===
|
|
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
|
-
|
|
100
|
-
|
|
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
|
-
|
|
106
|
-
|
|
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:
|
|
120
|
-
status:
|
|
121
|
-
message:
|
|
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:
|
|
127
|
-
status:
|
|
127
|
+
operation: "all",
|
|
128
|
+
status: "progress",
|
|
128
129
|
progress: 10,
|
|
129
|
-
message:
|
|
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:
|
|
135
|
-
status:
|
|
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:
|
|
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 ===
|
|
154
|
+
if (result.status === "error") {
|
|
154
155
|
yield {
|
|
155
156
|
operation,
|
|
156
|
-
status:
|
|
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:
|
|
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:
|
|
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:
|
|
187
|
-
status:
|
|
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:
|
|
196
|
-
status:
|
|
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
|
-
|
|
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 ===
|
|
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
|
|
238
|
+
case "review":
|
|
238
239
|
data = await this.executeCodeReview(context, options);
|
|
239
240
|
break;
|
|
240
|
-
case
|
|
241
|
+
case "enhance-description":
|
|
241
242
|
data = await this.executeDescriptionEnhancement(context, options);
|
|
242
243
|
break;
|
|
243
|
-
case
|
|
244
|
+
case "security-scan":
|
|
244
245
|
// TODO: Implement in future phases
|
|
245
|
-
throw new Error(
|
|
246
|
-
case
|
|
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(
|
|
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:
|
|
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
|
-
|
|
262
|
+
logger.error(`Operation ${operation} failed: ${error.message}`);
|
|
262
263
|
return {
|
|
263
264
|
operation,
|
|
264
|
-
status:
|
|
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
|
-
|
|
277
|
-
return { skipped: true, reason:
|
|
277
|
+
logger.info("Code review is disabled in configuration");
|
|
278
|
+
return { skipped: true, reason: "disabled in config" };
|
|
278
279
|
}
|
|
279
|
-
|
|
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:
|
|
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
|
-
|
|
298
|
-
return { skipped: true, reason:
|
|
298
|
+
logger.info("Description enhancement is disabled in configuration");
|
|
299
|
+
return { skipped: true, reason: "disabled in config" };
|
|
299
300
|
}
|
|
300
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
338
|
+
logger.operation("Code Review", "completed");
|
|
338
339
|
return result;
|
|
339
340
|
}
|
|
340
341
|
catch (error) {
|
|
341
|
-
|
|
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
|
-
|
|
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
|
-
|
|
364
|
+
logger.operation("Description Enhancement", "completed");
|
|
364
365
|
return result;
|
|
365
366
|
}
|
|
366
367
|
catch (error) {
|
|
367
|
-
|
|
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:
|
|
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:
|
|
420
|
+
cache: cache.stats(),
|
|
420
421
|
};
|
|
421
422
|
}
|
|
422
423
|
/**
|
|
423
424
|
* Clear all caches
|
|
424
425
|
*/
|
|
425
426
|
clearCache() {
|
|
426
|
-
|
|
427
|
+
cache.clear();
|
|
427
428
|
this.bitbucketProvider?.clearCache();
|
|
428
|
-
|
|
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
|
-
|
|
443
|
+
logger.info("Shutting down Yama...");
|
|
443
444
|
// Clear caches
|
|
444
445
|
this.clearCache();
|
|
445
446
|
// Reset state
|
|
446
447
|
this.initialized = false;
|
|
447
|
-
|
|
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
|
-
|
|
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
|
|
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?:
|
|
64
|
+
lineType?: "ADDED" | "REMOVED" | "CONTEXT";
|
|
65
65
|
codeSnippet?: string;
|
|
66
66
|
searchContext?: {
|
|
67
67
|
before: string[];
|
|
68
68
|
after: string[];
|
|
69
69
|
};
|
|
70
|
-
matchStrategy?:
|
|
70
|
+
matchStrategy?: "exact" | "best" | "strict";
|
|
71
71
|
suggestion?: string;
|
|
72
72
|
}): Promise<{
|
|
73
73
|
success: boolean;
|