@juspay/yama 1.6.0 → 2.1.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.
- package/.mcp-config.example.json +26 -0
- package/CHANGELOG.md +46 -0
- package/README.md +311 -685
- package/dist/cli/v2.cli.d.ts +13 -0
- package/dist/cli/v2.cli.js +359 -0
- package/dist/index.d.ts +12 -13
- package/dist/index.js +18 -19
- package/dist/v2/config/ConfigLoader.d.ts +50 -0
- package/dist/v2/config/ConfigLoader.js +205 -0
- package/dist/v2/config/DefaultConfig.d.ts +9 -0
- package/dist/v2/config/DefaultConfig.js +187 -0
- package/dist/v2/core/LearningOrchestrator.d.ts +65 -0
- package/dist/v2/core/LearningOrchestrator.js +499 -0
- package/dist/v2/core/MCPServerManager.d.ts +22 -0
- package/dist/v2/core/MCPServerManager.js +100 -0
- package/dist/v2/core/SessionManager.d.ts +72 -0
- package/dist/v2/core/SessionManager.js +200 -0
- package/dist/v2/core/YamaV2Orchestrator.d.ts +112 -0
- package/dist/v2/core/YamaV2Orchestrator.js +549 -0
- package/dist/v2/learning/FeedbackExtractor.d.ts +46 -0
- package/dist/v2/learning/FeedbackExtractor.js +237 -0
- package/dist/v2/learning/KnowledgeBaseManager.d.ts +91 -0
- package/dist/v2/learning/KnowledgeBaseManager.js +475 -0
- package/dist/v2/learning/types.d.ts +121 -0
- package/dist/v2/learning/types.js +15 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/EnhancementSystemPrompt.js +216 -0
- package/dist/v2/prompts/LangfusePromptManager.d.ts +48 -0
- package/dist/v2/prompts/LangfusePromptManager.js +144 -0
- package/dist/v2/prompts/LearningSystemPrompt.d.ts +11 -0
- package/dist/v2/prompts/LearningSystemPrompt.js +180 -0
- package/dist/v2/prompts/PromptBuilder.d.ts +45 -0
- package/dist/v2/prompts/PromptBuilder.js +257 -0
- package/dist/v2/prompts/ReviewSystemPrompt.d.ts +8 -0
- package/dist/v2/prompts/ReviewSystemPrompt.js +270 -0
- package/dist/v2/types/config.types.d.ts +141 -0
- package/dist/v2/types/config.types.js +5 -0
- package/dist/v2/types/mcp.types.d.ts +191 -0
- package/dist/v2/types/mcp.types.js +6 -0
- package/dist/v2/types/v2.types.d.ts +182 -0
- package/dist/v2/types/v2.types.js +42 -0
- package/dist/v2/utils/ObservabilityConfig.d.ts +22 -0
- package/dist/v2/utils/ObservabilityConfig.js +48 -0
- package/package.json +16 -10
- package/yama.config.example.yaml +259 -204
- package/dist/cli/index.d.ts +0 -12
- package/dist/cli/index.js +0 -538
- package/dist/core/ContextGatherer.d.ts +0 -110
- package/dist/core/ContextGatherer.js +0 -470
- package/dist/core/Guardian.d.ts +0 -81
- package/dist/core/Guardian.js +0 -480
- package/dist/core/providers/BitbucketProvider.d.ts +0 -105
- package/dist/core/providers/BitbucketProvider.js +0 -489
- package/dist/features/CodeReviewer.d.ts +0 -173
- package/dist/features/CodeReviewer.js +0 -1707
- package/dist/features/DescriptionEnhancer.d.ts +0 -70
- package/dist/features/DescriptionEnhancer.js +0 -511
- package/dist/features/MultiInstanceProcessor.d.ts +0 -74
- package/dist/features/MultiInstanceProcessor.js +0 -360
- package/dist/types/index.d.ts +0 -624
- package/dist/types/index.js +0 -104
- package/dist/utils/Cache.d.ts +0 -103
- package/dist/utils/Cache.js +0 -444
- package/dist/utils/ConfigManager.d.ts +0 -88
- package/dist/utils/ConfigManager.js +0 -602
- package/dist/utils/ContentSimilarityService.d.ts +0 -74
- package/dist/utils/ContentSimilarityService.js +0 -215
- package/dist/utils/ExactDuplicateRemover.d.ts +0 -77
- package/dist/utils/ExactDuplicateRemover.js +0 -361
- package/dist/utils/Logger.d.ts +0 -31
- package/dist/utils/Logger.js +0 -214
- package/dist/utils/MemoryBankManager.d.ts +0 -73
- package/dist/utils/MemoryBankManager.js +0 -310
- package/dist/utils/ParallelProcessing.d.ts +0 -140
- package/dist/utils/ParallelProcessing.js +0 -333
- package/dist/utils/ProviderLimits.d.ts +0 -58
- package/dist/utils/ProviderLimits.js +0 -143
- package/dist/utils/RetryManager.d.ts +0 -78
- package/dist/utils/RetryManager.js +0 -205
package/dist/core/Guardian.js
DELETED
|
@@ -1,480 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Yama - Unified orchestrator class
|
|
3
|
-
* The main class that coordinates all operations using shared context
|
|
4
|
-
*/
|
|
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, createLogger } 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;
|
|
21
|
-
logger = logger; // Default logger, will be updated after config load
|
|
22
|
-
constructor(config) {
|
|
23
|
-
this.config = {};
|
|
24
|
-
if (config) {
|
|
25
|
-
this.config = { ...this.config, ...config };
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Initialize Guardian with configuration
|
|
30
|
-
*/
|
|
31
|
-
async initialize(configPath) {
|
|
32
|
-
if (this.initialized) {
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
// Load configuration first
|
|
37
|
-
const loaded = await configManager.loadConfig(configPath);
|
|
38
|
-
// Loaded file first, then in-memory overrides last
|
|
39
|
-
this.config = { ...loaded, ...this.config };
|
|
40
|
-
// Create logger with banner configuration if needed
|
|
41
|
-
const showBanner = this.config.display?.showBanner ?? true;
|
|
42
|
-
if (showBanner !== true) {
|
|
43
|
-
// Only create a new logger if we need to change the banner setting
|
|
44
|
-
this.logger = createLogger(logger.getConfig(), showBanner);
|
|
45
|
-
}
|
|
46
|
-
// Otherwise, keep using the default logger
|
|
47
|
-
this.logger.badge();
|
|
48
|
-
this.logger.phase("🚀 Initializing Yama...");
|
|
49
|
-
// Initialize providers
|
|
50
|
-
this.bitbucketProvider = new BitbucketProvider(this.config.providers.git.credentials);
|
|
51
|
-
await this.bitbucketProvider.initialize();
|
|
52
|
-
// Initialize NeuroLink with native ESM dynamic import
|
|
53
|
-
const { NeuroLink } = await import("@juspay/neurolink");
|
|
54
|
-
this.neurolink = new NeuroLink();
|
|
55
|
-
// Initialize core components
|
|
56
|
-
this.contextGatherer = new ContextGatherer(this.bitbucketProvider, this.config.providers.ai, this.config.memoryBank || {
|
|
57
|
-
enabled: true,
|
|
58
|
-
path: "memory-bank",
|
|
59
|
-
fallbackPaths: ["docs/memory-bank", ".memory-bank"],
|
|
60
|
-
});
|
|
61
|
-
this.codeReviewer = new CodeReviewer(this.bitbucketProvider, this.config.providers.ai, this.config.features.codeReview);
|
|
62
|
-
this.descriptionEnhancer = new DescriptionEnhancer(this.bitbucketProvider, this.config.providers.ai, this.config.features.descriptionEnhancement);
|
|
63
|
-
logger.debug("Description Enhancement Configuration:");
|
|
64
|
-
logger.debug(` - Enabled: ${this.config.features.descriptionEnhancement.enabled}`);
|
|
65
|
-
logger.debug(` - Required Sections: ${this.config.features.descriptionEnhancement.requiredSections.length} (${this.config.features.descriptionEnhancement.requiredSections.map((s) => s.key).join(", ")})`);
|
|
66
|
-
logger.debug(` - Custom systemPrompt: ${this.config.features.descriptionEnhancement.systemPrompt ? "Yes" : "No (using default)"}`);
|
|
67
|
-
logger.debug(` - Custom enhancementInstructions: ${this.config.features.descriptionEnhancement.enhancementInstructions ? "Yes" : "No (using default)"}`);
|
|
68
|
-
logger.debug(` - outputTemplate: ${this.config.features.descriptionEnhancement.outputTemplate ? "Provided" : "Not provided"}`);
|
|
69
|
-
this.initialized = true;
|
|
70
|
-
logger.success("✅ Yama initialized successfully");
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
logger.error(`Failed to initialize Yama: ${error.message}`);
|
|
74
|
-
throw new GuardianError("INITIALIZATION_ERROR", `Initialization failed: ${error.message}`);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Main method: Process PR with multiple operations using unified context
|
|
79
|
-
*/
|
|
80
|
-
async processPR(options) {
|
|
81
|
-
await this.ensureInitialized();
|
|
82
|
-
const startTime = Date.now();
|
|
83
|
-
const operations = [];
|
|
84
|
-
try {
|
|
85
|
-
logger.operation("PR Processing", "started");
|
|
86
|
-
logger.info(`Target: ${options.workspace}/${options.repository}`);
|
|
87
|
-
logger.info(`Operations: ${options.operations.join(", ")}`);
|
|
88
|
-
logger.info(`Mode: ${options.dryRun ? "DRY RUN" : "LIVE"}`);
|
|
89
|
-
// Step 1: Gather unified context ONCE for all operations
|
|
90
|
-
logger.phase("📋 Gathering unified context...");
|
|
91
|
-
const context = await this.gatherUnifiedContext(options);
|
|
92
|
-
logger.success(`Context ready: PR #${context.pr.id} - "${context.pr.title}"`);
|
|
93
|
-
logger.info(`Files: ${context.diffStrategy.fileCount}, Strategy: ${context.diffStrategy.strategy}`);
|
|
94
|
-
// Step 2: Execute requested operations using shared context
|
|
95
|
-
for (const operation of options.operations) {
|
|
96
|
-
if (operation === "all") {
|
|
97
|
-
// Execute all available operations
|
|
98
|
-
operations.push(await this.executeOperation("review", context, options));
|
|
99
|
-
operations.push(await this.executeOperation("enhance-description", context, options));
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
operations.push(await this.executeOperation(operation, context, options));
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
const duration = Date.now() - startTime;
|
|
106
|
-
const successCount = operations.filter((op) => op.status === "success").length;
|
|
107
|
-
const errorCount = operations.filter((op) => op.status === "error").length;
|
|
108
|
-
const skippedCount = operations.filter((op) => op.status === "skipped").length;
|
|
109
|
-
const result = {
|
|
110
|
-
pullRequest: context.pr,
|
|
111
|
-
operations,
|
|
112
|
-
summary: {
|
|
113
|
-
totalOperations: operations.length,
|
|
114
|
-
successCount,
|
|
115
|
-
errorCount,
|
|
116
|
-
skippedCount,
|
|
117
|
-
totalDuration: duration,
|
|
118
|
-
},
|
|
119
|
-
};
|
|
120
|
-
logger.operation("PR Processing", "completed");
|
|
121
|
-
logger.success(`✅ Processing completed in ${Math.round(duration / 1000)}s: ` +
|
|
122
|
-
`${successCount} success, ${errorCount} errors, ${skippedCount} skipped`);
|
|
123
|
-
return result;
|
|
124
|
-
}
|
|
125
|
-
catch (error) {
|
|
126
|
-
logger.operation("PR Processing", "failed");
|
|
127
|
-
logger.error(`Processing failed: ${error.message}`);
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Streaming version of processPR for real-time updates
|
|
133
|
-
*/
|
|
134
|
-
async *processPRStream(options, _streamOptions) {
|
|
135
|
-
await this.ensureInitialized();
|
|
136
|
-
const startTime = Date.now();
|
|
137
|
-
try {
|
|
138
|
-
// Initial update
|
|
139
|
-
yield {
|
|
140
|
-
operation: "all",
|
|
141
|
-
status: "started",
|
|
142
|
-
message: "Yama processing initiated",
|
|
143
|
-
timestamp: new Date().toISOString(),
|
|
144
|
-
};
|
|
145
|
-
// Context gathering phase
|
|
146
|
-
yield {
|
|
147
|
-
operation: "all",
|
|
148
|
-
status: "progress",
|
|
149
|
-
progress: 10,
|
|
150
|
-
message: "Gathering unified context...",
|
|
151
|
-
timestamp: new Date().toISOString(),
|
|
152
|
-
};
|
|
153
|
-
const context = await this.gatherUnifiedContext(options);
|
|
154
|
-
yield {
|
|
155
|
-
operation: "all",
|
|
156
|
-
status: "progress",
|
|
157
|
-
progress: 30,
|
|
158
|
-
message: `Context ready: PR #${context.pr.id}`,
|
|
159
|
-
data: { prId: context.pr.id, title: context.pr.title },
|
|
160
|
-
timestamp: new Date().toISOString(),
|
|
161
|
-
};
|
|
162
|
-
// Execute operations with progress updates
|
|
163
|
-
const totalOps = options.operations.length;
|
|
164
|
-
let completedOps = 0;
|
|
165
|
-
for (const operation of options.operations) {
|
|
166
|
-
yield {
|
|
167
|
-
operation,
|
|
168
|
-
status: "started",
|
|
169
|
-
message: `Starting ${operation}...`,
|
|
170
|
-
timestamp: new Date().toISOString(),
|
|
171
|
-
};
|
|
172
|
-
try {
|
|
173
|
-
const result = await this.executeOperation(operation, context, options);
|
|
174
|
-
if (result.status === "error") {
|
|
175
|
-
yield {
|
|
176
|
-
operation,
|
|
177
|
-
status: "error",
|
|
178
|
-
message: `${operation} failed: ${result.error}`,
|
|
179
|
-
timestamp: new Date().toISOString(),
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
else {
|
|
183
|
-
completedOps++;
|
|
184
|
-
yield {
|
|
185
|
-
operation,
|
|
186
|
-
status: "completed",
|
|
187
|
-
progress: 30 + Math.round((completedOps / totalOps) * 60),
|
|
188
|
-
message: `${operation} completed`,
|
|
189
|
-
data: result,
|
|
190
|
-
timestamp: new Date().toISOString(),
|
|
191
|
-
};
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
catch (error) {
|
|
195
|
-
// This catch is for unexpected errors that bypass executeOperation's own error handling
|
|
196
|
-
yield {
|
|
197
|
-
operation,
|
|
198
|
-
status: "error",
|
|
199
|
-
message: `${operation} failed: ${error.message}`,
|
|
200
|
-
timestamp: new Date().toISOString(),
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
// Final completion
|
|
205
|
-
const duration = Date.now() - startTime;
|
|
206
|
-
yield {
|
|
207
|
-
operation: "all",
|
|
208
|
-
status: "completed",
|
|
209
|
-
progress: 100,
|
|
210
|
-
message: `Processing completed in ${Math.round(duration / 1000)}s`,
|
|
211
|
-
timestamp: new Date().toISOString(),
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
catch (error) {
|
|
215
|
-
yield {
|
|
216
|
-
operation: "all",
|
|
217
|
-
status: "error",
|
|
218
|
-
message: `Processing failed: ${error.message}`,
|
|
219
|
-
timestamp: new Date().toISOString(),
|
|
220
|
-
};
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
/**
|
|
224
|
-
* Gather unified context (cached and reusable)
|
|
225
|
-
*/
|
|
226
|
-
async gatherUnifiedContext(options) {
|
|
227
|
-
const identifier = {
|
|
228
|
-
workspace: options.workspace,
|
|
229
|
-
repository: options.repository,
|
|
230
|
-
branch: options.branch,
|
|
231
|
-
pullRequestId: options.pullRequestId,
|
|
232
|
-
};
|
|
233
|
-
// Check if we have cached context first
|
|
234
|
-
const cachedContext = await this.contextGatherer.getCachedContext(identifier);
|
|
235
|
-
if (cachedContext && options.config?.cache?.enabled !== false) {
|
|
236
|
-
logger.debug("✓ Using cached context");
|
|
237
|
-
return cachedContext;
|
|
238
|
-
}
|
|
239
|
-
// Determine what operations need diff data
|
|
240
|
-
const needsDiff = options.operations.some((op) => op === "review" || op === "security-scan" || op === "all");
|
|
241
|
-
const contextOptions = {
|
|
242
|
-
excludePatterns: this.config.features.codeReview.excludePatterns,
|
|
243
|
-
contextLines: this.config.features.codeReview.contextLines,
|
|
244
|
-
forceRefresh: false,
|
|
245
|
-
includeDiff: needsDiff,
|
|
246
|
-
diffStrategyConfig: this.config.features.diffStrategy,
|
|
247
|
-
};
|
|
248
|
-
return await this.contextGatherer.gatherContext(identifier, contextOptions);
|
|
249
|
-
}
|
|
250
|
-
/**
|
|
251
|
-
* Execute individual operation using shared context
|
|
252
|
-
*/
|
|
253
|
-
async executeOperation(operation, context, options) {
|
|
254
|
-
const startTime = Date.now();
|
|
255
|
-
try {
|
|
256
|
-
let data;
|
|
257
|
-
switch (operation) {
|
|
258
|
-
case "review":
|
|
259
|
-
data = await this.executeCodeReview(context, options);
|
|
260
|
-
break;
|
|
261
|
-
case "enhance-description":
|
|
262
|
-
data = await this.executeDescriptionEnhancement(context, options);
|
|
263
|
-
break;
|
|
264
|
-
case "security-scan":
|
|
265
|
-
// TODO: Implement in future phases
|
|
266
|
-
throw new Error("Security scan not implemented in Phase 1");
|
|
267
|
-
case "analytics":
|
|
268
|
-
// TODO: Implement in future phases
|
|
269
|
-
throw new Error("Analytics not implemented in Phase 1");
|
|
270
|
-
default:
|
|
271
|
-
throw new Error(`Unknown operation: ${operation}`);
|
|
272
|
-
}
|
|
273
|
-
return {
|
|
274
|
-
operation,
|
|
275
|
-
status: "success",
|
|
276
|
-
data,
|
|
277
|
-
duration: Date.now() - startTime,
|
|
278
|
-
timestamp: new Date().toISOString(),
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
catch (error) {
|
|
282
|
-
logger.error(`Operation ${operation} failed: ${error.message}`);
|
|
283
|
-
return {
|
|
284
|
-
operation,
|
|
285
|
-
status: "error",
|
|
286
|
-
error: error.message,
|
|
287
|
-
duration: Date.now() - startTime,
|
|
288
|
-
timestamp: new Date().toISOString(),
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
/**
|
|
293
|
-
* Execute code review using shared context
|
|
294
|
-
*/
|
|
295
|
-
async executeCodeReview(context, options) {
|
|
296
|
-
if (!this.config.features.codeReview.enabled) {
|
|
297
|
-
logger.info("Code review is disabled in configuration");
|
|
298
|
-
return { skipped: true, reason: "disabled in config" };
|
|
299
|
-
}
|
|
300
|
-
const reviewOptions = {
|
|
301
|
-
workspace: context.identifier.workspace,
|
|
302
|
-
repository: context.identifier.repository,
|
|
303
|
-
pullRequestId: context.identifier.pullRequestId,
|
|
304
|
-
dryRun: options.dryRun,
|
|
305
|
-
verbose: logger.getConfig().verbose,
|
|
306
|
-
excludePatterns: this.config.features.codeReview.excludePatterns,
|
|
307
|
-
contextLines: this.config.features.codeReview.contextLines,
|
|
308
|
-
};
|
|
309
|
-
logger.phase("🔍 Executing code review...");
|
|
310
|
-
// Check if multi-instance processing is configured
|
|
311
|
-
const multiInstanceConfig = this.config.features?.codeReview
|
|
312
|
-
?.multiInstance;
|
|
313
|
-
// Use code review with multi-instance support
|
|
314
|
-
return await this.codeReviewer.reviewCodeWithContext(context, reviewOptions, multiInstanceConfig);
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Execute description enhancement using shared context
|
|
318
|
-
*/
|
|
319
|
-
async executeDescriptionEnhancement(context, options) {
|
|
320
|
-
if (!this.config.features.descriptionEnhancement.enabled) {
|
|
321
|
-
logger.info("Description enhancement is disabled in configuration");
|
|
322
|
-
return { skipped: true, reason: "disabled in config" };
|
|
323
|
-
}
|
|
324
|
-
logger.phase("📝 Executing description enhancement...");
|
|
325
|
-
const enhancementOptions = {
|
|
326
|
-
workspace: context.identifier.workspace,
|
|
327
|
-
repository: context.identifier.repository,
|
|
328
|
-
pullRequestId: context.identifier.pullRequestId,
|
|
329
|
-
dryRun: options.dryRun,
|
|
330
|
-
verbose: logger.getConfig().verbose,
|
|
331
|
-
preserveContent: this.config.features.descriptionEnhancement.preserveContent,
|
|
332
|
-
ensureRequiredSections: true,
|
|
333
|
-
customSections: this.config.features.descriptionEnhancement.requiredSections,
|
|
334
|
-
};
|
|
335
|
-
// Use the already gathered context instead of gathering again
|
|
336
|
-
return await this.descriptionEnhancer.enhanceWithContext(context, enhancementOptions);
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Individual operation methods for backwards compatibility
|
|
340
|
-
*/
|
|
341
|
-
/**
|
|
342
|
-
* Code review operation (standalone)
|
|
343
|
-
*/
|
|
344
|
-
async reviewCode(options) {
|
|
345
|
-
await this.ensureInitialized();
|
|
346
|
-
const identifier = {
|
|
347
|
-
workspace: options.workspace,
|
|
348
|
-
repository: options.repository,
|
|
349
|
-
branch: options.branch,
|
|
350
|
-
pullRequestId: options.pullRequestId,
|
|
351
|
-
};
|
|
352
|
-
logger.operation("Code Review", "started");
|
|
353
|
-
try {
|
|
354
|
-
// Gather context specifically for code review
|
|
355
|
-
const context = await this.contextGatherer.gatherContext(identifier, {
|
|
356
|
-
excludePatterns: options.excludePatterns,
|
|
357
|
-
contextLines: options.contextLines,
|
|
358
|
-
includeDiff: true,
|
|
359
|
-
});
|
|
360
|
-
const result = await this.codeReviewer.reviewCodeWithContext(context, options);
|
|
361
|
-
logger.operation("Code Review", "completed");
|
|
362
|
-
return result;
|
|
363
|
-
}
|
|
364
|
-
catch (error) {
|
|
365
|
-
logger.operation("Code Review", "failed");
|
|
366
|
-
throw error;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
/**
|
|
370
|
-
* Description enhancement operation (standalone)
|
|
371
|
-
*/
|
|
372
|
-
async enhanceDescription(options) {
|
|
373
|
-
await this.ensureInitialized();
|
|
374
|
-
const identifier = {
|
|
375
|
-
workspace: options.workspace,
|
|
376
|
-
repository: options.repository,
|
|
377
|
-
branch: options.branch,
|
|
378
|
-
pullRequestId: options.pullRequestId,
|
|
379
|
-
};
|
|
380
|
-
logger.operation("Description Enhancement", "started");
|
|
381
|
-
try {
|
|
382
|
-
// Gather context specifically for description enhancement
|
|
383
|
-
const context = await this.contextGatherer.gatherContext(identifier, {
|
|
384
|
-
includeDiff: true, // Description enhancement may need to see changes
|
|
385
|
-
});
|
|
386
|
-
const result = await this.descriptionEnhancer.enhanceWithContext(context, options);
|
|
387
|
-
logger.operation("Description Enhancement", "completed");
|
|
388
|
-
return result;
|
|
389
|
-
}
|
|
390
|
-
catch (error) {
|
|
391
|
-
logger.operation("Description Enhancement", "failed");
|
|
392
|
-
throw error;
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
/**
|
|
396
|
-
* Health check for all components
|
|
397
|
-
*/
|
|
398
|
-
async healthCheck() {
|
|
399
|
-
const components = {};
|
|
400
|
-
try {
|
|
401
|
-
// Check Bitbucket provider
|
|
402
|
-
components.bitbucket = await this.bitbucketProvider.healthCheck();
|
|
403
|
-
// Check cache
|
|
404
|
-
components.cache = {
|
|
405
|
-
healthy: true,
|
|
406
|
-
stats: cache.stats(),
|
|
407
|
-
};
|
|
408
|
-
// Check NeuroLink (if initialized)
|
|
409
|
-
components.neurolink = {
|
|
410
|
-
healthy: true,
|
|
411
|
-
initialized: !!this.neurolink,
|
|
412
|
-
};
|
|
413
|
-
const allHealthy = Object.values(components).every((comp) => comp.healthy);
|
|
414
|
-
return {
|
|
415
|
-
healthy: allHealthy,
|
|
416
|
-
components,
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
catch (error) {
|
|
420
|
-
return {
|
|
421
|
-
healthy: false,
|
|
422
|
-
components: {
|
|
423
|
-
...components,
|
|
424
|
-
error: error.message,
|
|
425
|
-
},
|
|
426
|
-
};
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Get comprehensive statistics
|
|
431
|
-
*/
|
|
432
|
-
getStats() {
|
|
433
|
-
return {
|
|
434
|
-
initialized: this.initialized,
|
|
435
|
-
config: {
|
|
436
|
-
features: Object.keys(this.config.features || {}),
|
|
437
|
-
cacheEnabled: this.config.cache?.enabled,
|
|
438
|
-
},
|
|
439
|
-
providers: {
|
|
440
|
-
bitbucket: this.bitbucketProvider?.getStats(),
|
|
441
|
-
context: this.contextGatherer?.getStats(),
|
|
442
|
-
},
|
|
443
|
-
cache: cache.stats(),
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
/**
|
|
447
|
-
* Clear all caches
|
|
448
|
-
*/
|
|
449
|
-
clearCache() {
|
|
450
|
-
cache.clear();
|
|
451
|
-
this.bitbucketProvider?.clearCache();
|
|
452
|
-
logger.info("All caches cleared");
|
|
453
|
-
}
|
|
454
|
-
/**
|
|
455
|
-
* Ensure Guardian is initialized
|
|
456
|
-
*/
|
|
457
|
-
async ensureInitialized() {
|
|
458
|
-
if (!this.initialized) {
|
|
459
|
-
await this.initialize();
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
/**
|
|
463
|
-
* Shutdown Guardian gracefully
|
|
464
|
-
*/
|
|
465
|
-
async shutdown() {
|
|
466
|
-
logger.info("Shutting down Yama...");
|
|
467
|
-
// Clear caches
|
|
468
|
-
this.clearCache();
|
|
469
|
-
// Reset state
|
|
470
|
-
this.initialized = false;
|
|
471
|
-
logger.success("Yama shutdown complete");
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
// Export factory function
|
|
475
|
-
export function createGuardian(config) {
|
|
476
|
-
return new Guardian(config);
|
|
477
|
-
}
|
|
478
|
-
// Export default instance
|
|
479
|
-
export const guardian = new Guardian();
|
|
480
|
-
//# sourceMappingURL=Guardian.js.map
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Enhanced Bitbucket Provider - Optimized from both pr-police.js and pr-describe.js
|
|
3
|
-
* Provides unified, cached, and optimized Bitbucket operations
|
|
4
|
-
*/
|
|
5
|
-
import { PRIdentifier, PRInfo, PRDiff, GitCredentials } from "../../types/index.js";
|
|
6
|
-
export interface BitbucketMCPResponse {
|
|
7
|
-
content?: Array<{
|
|
8
|
-
text?: string;
|
|
9
|
-
}>;
|
|
10
|
-
message?: string;
|
|
11
|
-
error?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare class BitbucketProvider {
|
|
14
|
-
private apiClient;
|
|
15
|
-
private branchHandlers;
|
|
16
|
-
private pullRequestHandlers;
|
|
17
|
-
private reviewHandlers;
|
|
18
|
-
private fileHandlers;
|
|
19
|
-
private initialized;
|
|
20
|
-
private baseUrl;
|
|
21
|
-
private credentials;
|
|
22
|
-
constructor(credentials: GitCredentials);
|
|
23
|
-
/**
|
|
24
|
-
* Initialize MCP handlers with lazy loading and connection reuse
|
|
25
|
-
*/
|
|
26
|
-
initialize(): Promise<void>;
|
|
27
|
-
/**
|
|
28
|
-
* Parse MCP response - exactly matching the working pr-police.js implementation
|
|
29
|
-
*/
|
|
30
|
-
private parseMCPResponse;
|
|
31
|
-
/**
|
|
32
|
-
* Find PR for branch with intelligent caching
|
|
33
|
-
*/
|
|
34
|
-
findPRForBranch(identifier: PRIdentifier): Promise<PRInfo>;
|
|
35
|
-
/**
|
|
36
|
-
* Get PR details with enhanced caching
|
|
37
|
-
*/
|
|
38
|
-
getPRDetails(identifier: PRIdentifier): Promise<PRInfo>;
|
|
39
|
-
/**
|
|
40
|
-
* Get PR diff with smart caching and filtering
|
|
41
|
-
*/
|
|
42
|
-
getPRDiff(identifier: PRIdentifier, contextLines?: number, excludePatterns?: string[], includePatterns?: string[]): Promise<PRDiff>;
|
|
43
|
-
/**
|
|
44
|
-
* Get file content with caching
|
|
45
|
-
*/
|
|
46
|
-
getFileContent(workspace: string, repository: string, filePath: string, branch: string): Promise<string>;
|
|
47
|
-
/**
|
|
48
|
-
* List directory content with caching
|
|
49
|
-
*/
|
|
50
|
-
listDirectoryContent(workspace: string, repository: string, path: string, branch: string): Promise<any[]>;
|
|
51
|
-
/**
|
|
52
|
-
* Update PR description with reviewer preservation
|
|
53
|
-
*/
|
|
54
|
-
updatePRDescription(identifier: PRIdentifier, description: string): Promise<{
|
|
55
|
-
success: boolean;
|
|
56
|
-
message: string;
|
|
57
|
-
}>;
|
|
58
|
-
/**
|
|
59
|
-
* Add comment to PR with smart positioning and validation
|
|
60
|
-
*/
|
|
61
|
-
addComment(identifier: PRIdentifier, commentText: string, options?: {
|
|
62
|
-
filePath?: string;
|
|
63
|
-
lineNumber?: number;
|
|
64
|
-
lineType?: "ADDED" | "REMOVED" | "CONTEXT";
|
|
65
|
-
codeSnippet?: string;
|
|
66
|
-
searchContext?: {
|
|
67
|
-
before: string[];
|
|
68
|
-
after: string[];
|
|
69
|
-
};
|
|
70
|
-
matchStrategy?: "exact" | "best" | "strict";
|
|
71
|
-
suggestion?: string;
|
|
72
|
-
}): Promise<{
|
|
73
|
-
success: boolean;
|
|
74
|
-
commentId?: number;
|
|
75
|
-
}>;
|
|
76
|
-
/**
|
|
77
|
-
* Batch operation support for multiple API calls
|
|
78
|
-
*/
|
|
79
|
-
batchOperations<T>(operations: Array<() => Promise<T>>, options?: {
|
|
80
|
-
maxConcurrent?: number;
|
|
81
|
-
delayBetween?: number;
|
|
82
|
-
continueOnError?: boolean;
|
|
83
|
-
}): Promise<Array<{
|
|
84
|
-
success: boolean;
|
|
85
|
-
data?: T;
|
|
86
|
-
error?: string;
|
|
87
|
-
}>>;
|
|
88
|
-
/**
|
|
89
|
-
* Health check for the provider
|
|
90
|
-
*/
|
|
91
|
-
healthCheck(): Promise<{
|
|
92
|
-
healthy: boolean;
|
|
93
|
-
details: any;
|
|
94
|
-
}>;
|
|
95
|
-
/**
|
|
96
|
-
* Get provider statistics and cache metrics
|
|
97
|
-
*/
|
|
98
|
-
getStats(): any;
|
|
99
|
-
/**
|
|
100
|
-
* Clear provider-related cache entries
|
|
101
|
-
*/
|
|
102
|
-
clearCache(): void;
|
|
103
|
-
}
|
|
104
|
-
export declare function createBitbucketProvider(credentials: GitCredentials): BitbucketProvider;
|
|
105
|
-
//# sourceMappingURL=BitbucketProvider.d.ts.map
|