@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
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Enhanced Bitbucket Provider - Optimized from both pr-police.js and pr-describe.js
|
|
4
3
|
* Provides unified, cached, and optimized Bitbucket operations
|
|
5
4
|
*/
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
import { ProviderError, } from "../../types/index.js";
|
|
6
|
+
import { logger } from "../../utils/Logger.js";
|
|
7
|
+
import { cache, Cache } from "../../utils/Cache.js";
|
|
8
|
+
export class BitbucketProvider {
|
|
9
|
+
apiClient;
|
|
10
|
+
branchHandlers;
|
|
11
|
+
pullRequestHandlers;
|
|
12
|
+
reviewHandlers;
|
|
13
|
+
fileHandlers;
|
|
14
|
+
initialized = false;
|
|
15
|
+
baseUrl;
|
|
16
|
+
credentials;
|
|
13
17
|
constructor(credentials) {
|
|
14
|
-
this.initialized = false;
|
|
15
18
|
this.credentials = credentials;
|
|
16
|
-
this.baseUrl = credentials.baseUrl ||
|
|
19
|
+
this.baseUrl = credentials.baseUrl || "https://your-bitbucket-server.com";
|
|
17
20
|
}
|
|
18
21
|
/**
|
|
19
22
|
* Initialize MCP handlers with lazy loading and connection reuse
|
|
@@ -23,14 +26,14 @@ class BitbucketProvider {
|
|
|
23
26
|
return;
|
|
24
27
|
}
|
|
25
28
|
try {
|
|
26
|
-
|
|
27
|
-
const dynamicImport = eval(
|
|
28
|
-
const [{ BitbucketApiClient }, { BranchHandlers }, { PullRequestHandlers }, { ReviewHandlers }, { FileHandlers }] = await Promise.all([
|
|
29
|
-
dynamicImport(
|
|
30
|
-
dynamicImport(
|
|
31
|
-
dynamicImport(
|
|
32
|
-
dynamicImport(
|
|
33
|
-
dynamicImport(
|
|
29
|
+
logger.debug("Initializing Bitbucket MCP handlers...");
|
|
30
|
+
const dynamicImport = eval("(specifier) => import(specifier)");
|
|
31
|
+
const [{ BitbucketApiClient }, { BranchHandlers }, { PullRequestHandlers }, { ReviewHandlers }, { FileHandlers },] = await Promise.all([
|
|
32
|
+
dynamicImport("@nexus2520/bitbucket-mcp-server/build/utils/api-client.js"),
|
|
33
|
+
dynamicImport("@nexus2520/bitbucket-mcp-server/build/handlers/branch-handlers.js"),
|
|
34
|
+
dynamicImport("@nexus2520/bitbucket-mcp-server/build/handlers/pull-request-handlers.js"),
|
|
35
|
+
dynamicImport("@nexus2520/bitbucket-mcp-server/build/handlers/review-handlers.js"),
|
|
36
|
+
dynamicImport("@nexus2520/bitbucket-mcp-server/build/handlers/file-handlers.js"),
|
|
34
37
|
]);
|
|
35
38
|
this.apiClient = new BitbucketApiClient(this.baseUrl, this.credentials.username, undefined, this.credentials.token);
|
|
36
39
|
this.branchHandlers = new BranchHandlers(this.apiClient, this.baseUrl);
|
|
@@ -38,10 +41,10 @@ class BitbucketProvider {
|
|
|
38
41
|
this.reviewHandlers = new ReviewHandlers(this.apiClient, this.credentials.username);
|
|
39
42
|
this.fileHandlers = new FileHandlers(this.apiClient, this.baseUrl);
|
|
40
43
|
this.initialized = true;
|
|
41
|
-
|
|
44
|
+
logger.debug("Bitbucket MCP handlers initialized successfully");
|
|
42
45
|
}
|
|
43
46
|
catch (error) {
|
|
44
|
-
throw new
|
|
47
|
+
throw new ProviderError(`Failed to initialize Bitbucket provider: ${error.message}`);
|
|
45
48
|
}
|
|
46
49
|
}
|
|
47
50
|
/**
|
|
@@ -56,7 +59,7 @@ class BitbucketProvider {
|
|
|
56
59
|
if (result.content && result.content[0] && result.content[0].text) {
|
|
57
60
|
const text = result.content[0].text;
|
|
58
61
|
// Check if it's an error message
|
|
59
|
-
if (typeof text ===
|
|
62
|
+
if (typeof text === "string" && text.startsWith("Error:")) {
|
|
60
63
|
throw new Error(text);
|
|
61
64
|
}
|
|
62
65
|
try {
|
|
@@ -79,11 +82,11 @@ class BitbucketProvider {
|
|
|
79
82
|
await this.initialize();
|
|
80
83
|
const { workspace, repository, branch } = identifier;
|
|
81
84
|
if (!branch) {
|
|
82
|
-
throw new
|
|
85
|
+
throw new ProviderError("Branch name is required");
|
|
83
86
|
}
|
|
84
|
-
const cacheKey =
|
|
85
|
-
return
|
|
86
|
-
|
|
87
|
+
const cacheKey = Cache.keys.branchInfo(workspace, repository, branch);
|
|
88
|
+
return cache.getOrSet(cacheKey, async () => {
|
|
89
|
+
logger.debug(`Finding PR for branch: ${workspace}/${repository}@${branch}`);
|
|
87
90
|
const rawBranchData = await this.branchHandlers.handleGetBranch({
|
|
88
91
|
workspace,
|
|
89
92
|
repository,
|
|
@@ -92,28 +95,31 @@ class BitbucketProvider {
|
|
|
92
95
|
});
|
|
93
96
|
const branchData = this.parseMCPResponse(rawBranchData);
|
|
94
97
|
// Direct data extraction
|
|
95
|
-
if (branchData.open_pull_requests &&
|
|
98
|
+
if (branchData.open_pull_requests &&
|
|
99
|
+
branchData.open_pull_requests.length > 0) {
|
|
96
100
|
const firstPR = branchData.open_pull_requests[0];
|
|
97
101
|
// Debug author data structure
|
|
98
|
-
|
|
99
|
-
|
|
102
|
+
logger.debug(`Author data structure: ${JSON.stringify(firstPR.author, null, 2)}`);
|
|
103
|
+
logger.debug(`Raw firstPR keys: ${Object.keys(firstPR).join(", ")}`);
|
|
100
104
|
return {
|
|
101
105
|
id: firstPR.id,
|
|
102
106
|
title: firstPR.title,
|
|
103
|
-
description: firstPR.description ||
|
|
104
|
-
author: firstPR.author?.displayName ||
|
|
105
|
-
|
|
107
|
+
description: firstPR.description || "",
|
|
108
|
+
author: firstPR.author?.displayName ||
|
|
109
|
+
firstPR.author?.name ||
|
|
110
|
+
firstPR.author ||
|
|
111
|
+
"Unknown",
|
|
112
|
+
state: "OPEN",
|
|
106
113
|
sourceRef: branch,
|
|
107
|
-
targetRef: firstPR.destination?.branch?.name ||
|
|
114
|
+
targetRef: firstPR.destination?.branch?.name || "main",
|
|
108
115
|
createdDate: firstPR.createdDate || new Date().toISOString(),
|
|
109
116
|
updatedDate: firstPR.updatedDate || new Date().toISOString(),
|
|
110
117
|
reviewers: firstPR.reviewers || [],
|
|
111
|
-
fileChanges: firstPR.file_changes || []
|
|
118
|
+
fileChanges: firstPR.file_changes || [],
|
|
112
119
|
};
|
|
113
120
|
}
|
|
114
|
-
throw new
|
|
115
|
-
}, 3600
|
|
116
|
-
);
|
|
121
|
+
throw new ProviderError(`No open PR found for branch: ${branch}`);
|
|
122
|
+
}, 3600);
|
|
117
123
|
}
|
|
118
124
|
/**
|
|
119
125
|
* Get PR details with enhanced caching
|
|
@@ -122,11 +128,11 @@ class BitbucketProvider {
|
|
|
122
128
|
await this.initialize();
|
|
123
129
|
const { workspace, repository, pullRequestId } = identifier;
|
|
124
130
|
if (!pullRequestId) {
|
|
125
|
-
throw new
|
|
131
|
+
throw new ProviderError("Pull request ID is required");
|
|
126
132
|
}
|
|
127
|
-
const cacheKey =
|
|
128
|
-
return
|
|
129
|
-
|
|
133
|
+
const cacheKey = Cache.keys.prInfo(workspace, repository, pullRequestId);
|
|
134
|
+
return cache.getOrSet(cacheKey, async () => {
|
|
135
|
+
logger.debug(`Getting PR details: ${workspace}/${repository}#${pullRequestId}`);
|
|
130
136
|
const rawPRDetails = await this.pullRequestHandlers.handleGetPullRequest({
|
|
131
137
|
workspace,
|
|
132
138
|
repository,
|
|
@@ -134,42 +140,45 @@ class BitbucketProvider {
|
|
|
134
140
|
});
|
|
135
141
|
const prData = this.parseMCPResponse(rawPRDetails);
|
|
136
142
|
// Debug author data structure
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
logger.debug(`PR Details author data structure: ${JSON.stringify(prData.author, null, 2)}`);
|
|
144
|
+
logger.debug(`PR Details raw keys: ${Object.keys(prData).join(", ")}`);
|
|
139
145
|
return {
|
|
140
146
|
id: prData.id,
|
|
141
147
|
title: prData.title,
|
|
142
|
-
description: prData.description ||
|
|
143
|
-
author: prData.author?.displayName ||
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
description: prData.description || "",
|
|
149
|
+
author: prData.author?.displayName ||
|
|
150
|
+
prData.author?.name ||
|
|
151
|
+
prData.author ||
|
|
152
|
+
"Unknown",
|
|
153
|
+
state: prData.state || "OPEN",
|
|
154
|
+
sourceRef: prData.source?.branch?.name || "",
|
|
155
|
+
targetRef: prData.destination?.branch?.name || "",
|
|
147
156
|
createdDate: prData.createdDate || new Date().toISOString(),
|
|
148
157
|
updatedDate: prData.updatedDate || new Date().toISOString(),
|
|
149
158
|
reviewers: prData.reviewers || [],
|
|
150
159
|
comments: prData.active_comments || [],
|
|
151
|
-
fileChanges: prData.file_changes?.map((f) => f.path || f.file) ||
|
|
160
|
+
fileChanges: prData.file_changes?.map((f) => f.path || f.file) ||
|
|
161
|
+
[],
|
|
152
162
|
};
|
|
153
|
-
}, 1800
|
|
154
|
-
);
|
|
163
|
+
}, 1800);
|
|
155
164
|
}
|
|
156
165
|
/**
|
|
157
166
|
* Get PR diff with smart caching and filtering
|
|
158
167
|
*/
|
|
159
|
-
async getPRDiff(identifier, contextLines = 3, excludePatterns = [
|
|
168
|
+
async getPRDiff(identifier, contextLines = 3, excludePatterns = ["*.lock", "*.svg"], includePatterns) {
|
|
160
169
|
await this.initialize();
|
|
161
170
|
const { workspace, repository, pullRequestId } = identifier;
|
|
162
171
|
if (!pullRequestId) {
|
|
163
|
-
throw new
|
|
172
|
+
throw new ProviderError("Pull request ID is required");
|
|
164
173
|
}
|
|
165
174
|
// Create a cache key that includes include patterns if specified
|
|
166
175
|
const cacheKey = includePatterns && includePatterns.length === 1
|
|
167
176
|
? `file-diff:${workspace}:${repository}:${pullRequestId}:${includePatterns[0]}`
|
|
168
|
-
:
|
|
169
|
-
return
|
|
170
|
-
|
|
177
|
+
: Cache.keys.prDiff(workspace, repository, pullRequestId);
|
|
178
|
+
return cache.getOrSet(cacheKey, async () => {
|
|
179
|
+
logger.debug(`Getting PR diff: ${workspace}/${repository}#${pullRequestId}`);
|
|
171
180
|
if (includePatterns) {
|
|
172
|
-
|
|
181
|
+
logger.debug(`Include patterns: ${includePatterns.join(", ")}`);
|
|
173
182
|
}
|
|
174
183
|
const args = {
|
|
175
184
|
workspace,
|
|
@@ -185,22 +194,21 @@ class BitbucketProvider {
|
|
|
185
194
|
const rawDiff = await this.reviewHandlers.handleGetPullRequestDiff(args);
|
|
186
195
|
const diffData = this.parseMCPResponse(rawDiff);
|
|
187
196
|
return {
|
|
188
|
-
diff: diffData.diff ||
|
|
197
|
+
diff: diffData.diff || "",
|
|
189
198
|
fileChanges: diffData.file_changes || [],
|
|
190
199
|
totalAdditions: diffData.total_additions || 0,
|
|
191
|
-
totalDeletions: diffData.total_deletions || 0
|
|
200
|
+
totalDeletions: diffData.total_deletions || 0,
|
|
192
201
|
};
|
|
193
|
-
}, 1800
|
|
194
|
-
);
|
|
202
|
+
}, 1800);
|
|
195
203
|
}
|
|
196
204
|
/**
|
|
197
205
|
* Get file content with caching
|
|
198
206
|
*/
|
|
199
207
|
async getFileContent(workspace, repository, filePath, branch) {
|
|
200
208
|
await this.initialize();
|
|
201
|
-
const cacheKey =
|
|
202
|
-
return
|
|
203
|
-
|
|
209
|
+
const cacheKey = Cache.keys.fileContent(workspace, repository, filePath, branch);
|
|
210
|
+
return cache.getOrSet(cacheKey, async () => {
|
|
211
|
+
logger.debug(`Getting file content: ${workspace}/${repository}/${filePath}@${branch}`);
|
|
204
212
|
const result = await this.fileHandlers.handleGetFileContent({
|
|
205
213
|
workspace,
|
|
206
214
|
repository,
|
|
@@ -210,21 +218,20 @@ class BitbucketProvider {
|
|
|
210
218
|
// Handle file content response directly (don't JSON parse)
|
|
211
219
|
if (result.content && result.content[0] && result.content[0].text) {
|
|
212
220
|
const fileResponse = JSON.parse(result.content[0].text);
|
|
213
|
-
return fileResponse.content ||
|
|
221
|
+
return fileResponse.content || "";
|
|
214
222
|
}
|
|
215
223
|
// Handle direct response format
|
|
216
|
-
return result.content ||
|
|
217
|
-
}, 7200
|
|
218
|
-
);
|
|
224
|
+
return result.content || "";
|
|
225
|
+
}, 7200);
|
|
219
226
|
}
|
|
220
227
|
/**
|
|
221
228
|
* List directory content with caching
|
|
222
229
|
*/
|
|
223
230
|
async listDirectoryContent(workspace, repository, path, branch) {
|
|
224
231
|
await this.initialize();
|
|
225
|
-
const cacheKey =
|
|
226
|
-
return
|
|
227
|
-
|
|
232
|
+
const cacheKey = Cache.keys.directoryContent(workspace, repository, path, branch);
|
|
233
|
+
return cache.getOrSet(cacheKey, async () => {
|
|
234
|
+
logger.debug(`Listing directory: ${workspace}/${repository}/${path}@${branch}`);
|
|
228
235
|
const result = await this.fileHandlers.handleListDirectoryContent({
|
|
229
236
|
workspace,
|
|
230
237
|
repository,
|
|
@@ -233,8 +240,7 @@ class BitbucketProvider {
|
|
|
233
240
|
});
|
|
234
241
|
const dirData = this.parseMCPResponse(result);
|
|
235
242
|
return dirData.contents || [];
|
|
236
|
-
}, 3600
|
|
237
|
-
);
|
|
243
|
+
}, 3600);
|
|
238
244
|
}
|
|
239
245
|
/**
|
|
240
246
|
* Update PR description with reviewer preservation
|
|
@@ -243,40 +249,40 @@ class BitbucketProvider {
|
|
|
243
249
|
await this.initialize();
|
|
244
250
|
const { workspace, repository, pullRequestId } = identifier;
|
|
245
251
|
if (!pullRequestId) {
|
|
246
|
-
throw new
|
|
252
|
+
throw new ProviderError("Pull request ID is required");
|
|
247
253
|
}
|
|
248
254
|
try {
|
|
249
|
-
|
|
250
|
-
|
|
255
|
+
logger.debug(`Updating PR description: ${workspace}/${repository}#${pullRequestId}`);
|
|
256
|
+
logger.debug(`Description length: ${description.length} characters`);
|
|
251
257
|
const result = await this.pullRequestHandlers.handleUpdatePullRequest({
|
|
252
258
|
workspace,
|
|
253
259
|
repository,
|
|
254
260
|
pull_request_id: pullRequestId,
|
|
255
|
-
description: description
|
|
261
|
+
description: description,
|
|
256
262
|
});
|
|
257
263
|
// Log the raw MCP response
|
|
258
|
-
|
|
264
|
+
logger.debug(`Raw MCP update response: ${JSON.stringify(result, null, 2)}`);
|
|
259
265
|
const updateData = this.parseMCPResponse(result);
|
|
260
266
|
// Log the parsed response
|
|
261
|
-
|
|
267
|
+
logger.debug(`Parsed update response: ${JSON.stringify(updateData, null, 2)}`);
|
|
262
268
|
// Invalidate related cache entries
|
|
263
|
-
|
|
269
|
+
cache.del(Cache.keys.prInfo(workspace, repository, pullRequestId));
|
|
264
270
|
// Check if the response indicates actual success
|
|
265
|
-
if (typeof updateData ===
|
|
266
|
-
|
|
271
|
+
if (typeof updateData === "string" && updateData.includes("Error")) {
|
|
272
|
+
logger.error(`Update response contains error: ${updateData}`);
|
|
267
273
|
return {
|
|
268
274
|
success: false,
|
|
269
|
-
message: updateData
|
|
275
|
+
message: updateData,
|
|
270
276
|
};
|
|
271
277
|
}
|
|
272
278
|
return {
|
|
273
279
|
success: true,
|
|
274
|
-
message: updateData.message ||
|
|
280
|
+
message: updateData.message || "PR description updated successfully",
|
|
275
281
|
};
|
|
276
282
|
}
|
|
277
283
|
catch (error) {
|
|
278
|
-
|
|
279
|
-
throw new
|
|
284
|
+
logger.error(`Failed to update PR description: ${error.message}`);
|
|
285
|
+
throw new ProviderError(`Update failed: ${error.message}`);
|
|
280
286
|
}
|
|
281
287
|
}
|
|
282
288
|
/**
|
|
@@ -286,10 +292,10 @@ class BitbucketProvider {
|
|
|
286
292
|
await this.initialize();
|
|
287
293
|
const { workspace, repository, pullRequestId } = identifier;
|
|
288
294
|
if (!pullRequestId) {
|
|
289
|
-
throw new
|
|
295
|
+
throw new ProviderError("Pull request ID is required");
|
|
290
296
|
}
|
|
291
297
|
try {
|
|
292
|
-
|
|
298
|
+
logger.debug(`Adding comment to PR: ${workspace}/${repository}#${pullRequestId}`);
|
|
293
299
|
const args = {
|
|
294
300
|
workspace,
|
|
295
301
|
repository,
|
|
@@ -300,32 +306,35 @@ class BitbucketProvider {
|
|
|
300
306
|
if (options.filePath && options.codeSnippet) {
|
|
301
307
|
args.file_path = options.filePath;
|
|
302
308
|
args.code_snippet = options.codeSnippet;
|
|
303
|
-
if (options.searchContext)
|
|
309
|
+
if (options.searchContext) {
|
|
304
310
|
args.search_context = options.searchContext;
|
|
305
|
-
|
|
311
|
+
}
|
|
312
|
+
if (options.matchStrategy) {
|
|
306
313
|
args.match_strategy = options.matchStrategy;
|
|
307
|
-
|
|
314
|
+
}
|
|
315
|
+
if (options.suggestion) {
|
|
308
316
|
args.suggestion = options.suggestion;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
317
|
+
}
|
|
318
|
+
logger.debug(`🔍 Inline comment details:`);
|
|
319
|
+
logger.debug(` File: ${options.filePath}`);
|
|
320
|
+
logger.debug(` Code snippet: "${options.codeSnippet}"`);
|
|
321
|
+
logger.debug(` Match strategy: ${options.matchStrategy}`);
|
|
313
322
|
if (options.searchContext) {
|
|
314
|
-
|
|
315
|
-
|
|
323
|
+
logger.debug(` Search context before: ${JSON.stringify(options.searchContext.before)}`);
|
|
324
|
+
logger.debug(` Search context after: ${JSON.stringify(options.searchContext.after)}`);
|
|
316
325
|
}
|
|
317
326
|
}
|
|
318
327
|
else if (options.filePath && options.lineNumber) {
|
|
319
328
|
// Fallback to line number if no code snippet
|
|
320
329
|
args.file_path = options.filePath;
|
|
321
330
|
args.line_number = options.lineNumber;
|
|
322
|
-
args.line_type = options.lineType ||
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
331
|
+
args.line_type = options.lineType || "CONTEXT";
|
|
332
|
+
logger.debug(`🔍 Line-based comment details:`);
|
|
333
|
+
logger.debug(` File: ${options.filePath}`);
|
|
334
|
+
logger.debug(` Line: ${options.lineNumber}`);
|
|
335
|
+
logger.debug(` Type: ${options.lineType || "CONTEXT"}`);
|
|
327
336
|
}
|
|
328
|
-
|
|
337
|
+
logger.debug(`🔍 MCP addComment args: ${JSON.stringify(args, null, 2)}`);
|
|
329
338
|
const result = await this.pullRequestHandlers.handleAddComment(args);
|
|
330
339
|
// Parse response exactly like pr-police.js
|
|
331
340
|
let commentData;
|
|
@@ -337,19 +346,19 @@ class BitbucketProvider {
|
|
|
337
346
|
}
|
|
338
347
|
return {
|
|
339
348
|
success: true,
|
|
340
|
-
commentId: commentData.id || commentData.comment_id
|
|
349
|
+
commentId: commentData.id || commentData.comment_id,
|
|
341
350
|
};
|
|
342
351
|
}
|
|
343
352
|
catch (error) {
|
|
344
|
-
|
|
345
|
-
throw new
|
|
353
|
+
logger.error(`Failed to add comment: ${error.message}`);
|
|
354
|
+
throw new ProviderError(`Comment failed: ${error.message}`);
|
|
346
355
|
}
|
|
347
356
|
}
|
|
348
357
|
/**
|
|
349
358
|
* Batch operation support for multiple API calls
|
|
350
359
|
*/
|
|
351
360
|
async batchOperations(operations, options = {}) {
|
|
352
|
-
const { maxConcurrent = 5, delayBetween = 1000, continueOnError = true } = options;
|
|
361
|
+
const { maxConcurrent = 5, delayBetween = 1000, continueOnError = true, } = options;
|
|
353
362
|
const results = [];
|
|
354
363
|
// Process operations in batches
|
|
355
364
|
for (let i = 0; i < operations.length; i += maxConcurrent) {
|
|
@@ -371,7 +380,7 @@ class BitbucketProvider {
|
|
|
371
380
|
results.push(...batchResults);
|
|
372
381
|
// Add delay between batches (except for the last batch)
|
|
373
382
|
if (i + maxConcurrent < operations.length && delayBetween > 0) {
|
|
374
|
-
await new Promise(resolve => setTimeout(resolve, delayBetween));
|
|
383
|
+
await new Promise((resolve) => setTimeout(resolve, delayBetween));
|
|
375
384
|
}
|
|
376
385
|
}
|
|
377
386
|
return results;
|
|
@@ -384,9 +393,9 @@ class BitbucketProvider {
|
|
|
384
393
|
await this.initialize();
|
|
385
394
|
// Try a simple API call to verify connectivity
|
|
386
395
|
const testResult = await this.branchHandlers.handleGetBranch({
|
|
387
|
-
workspace:
|
|
388
|
-
repository:
|
|
389
|
-
branch_name:
|
|
396
|
+
workspace: "test",
|
|
397
|
+
repository: "test",
|
|
398
|
+
branch_name: "test",
|
|
390
399
|
include_merged_prs: false,
|
|
391
400
|
});
|
|
392
401
|
return {
|
|
@@ -395,8 +404,8 @@ class BitbucketProvider {
|
|
|
395
404
|
initialized: this.initialized,
|
|
396
405
|
baseUrl: this.baseUrl,
|
|
397
406
|
username: this.credentials.username,
|
|
398
|
-
apiConnected: !!testResult
|
|
399
|
-
}
|
|
407
|
+
apiConnected: !!testResult,
|
|
408
|
+
},
|
|
400
409
|
};
|
|
401
410
|
}
|
|
402
411
|
catch (error) {
|
|
@@ -404,8 +413,8 @@ class BitbucketProvider {
|
|
|
404
413
|
healthy: false,
|
|
405
414
|
details: {
|
|
406
415
|
initialized: this.initialized,
|
|
407
|
-
error: error.message
|
|
408
|
-
}
|
|
416
|
+
error: error.message,
|
|
417
|
+
},
|
|
409
418
|
};
|
|
410
419
|
}
|
|
411
420
|
}
|
|
@@ -414,11 +423,11 @@ class BitbucketProvider {
|
|
|
414
423
|
*/
|
|
415
424
|
getStats() {
|
|
416
425
|
return {
|
|
417
|
-
provider:
|
|
426
|
+
provider: "bitbucket",
|
|
418
427
|
initialized: this.initialized,
|
|
419
428
|
baseUrl: this.baseUrl,
|
|
420
|
-
cacheStats:
|
|
421
|
-
cacheHitRatio:
|
|
429
|
+
cacheStats: cache.stats(),
|
|
430
|
+
cacheHitRatio: cache.getHitRatio(),
|
|
422
431
|
};
|
|
423
432
|
}
|
|
424
433
|
/**
|
|
@@ -426,13 +435,12 @@ class BitbucketProvider {
|
|
|
426
435
|
*/
|
|
427
436
|
clearCache() {
|
|
428
437
|
// Clear all cache entries (could be made more specific)
|
|
429
|
-
|
|
430
|
-
|
|
438
|
+
cache.clear();
|
|
439
|
+
logger.debug("BitbucketProvider cache cleared");
|
|
431
440
|
}
|
|
432
441
|
}
|
|
433
|
-
exports.BitbucketProvider = BitbucketProvider;
|
|
434
442
|
// Export factory function
|
|
435
|
-
function createBitbucketProvider(credentials) {
|
|
443
|
+
export function createBitbucketProvider(credentials) {
|
|
436
444
|
return new BitbucketProvider(credentials);
|
|
437
445
|
}
|
|
438
446
|
//# sourceMappingURL=BitbucketProvider.js.map
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Enhanced Code Reviewer - Optimized to work with Unified Context
|
|
3
3
|
* Preserves all original functionality from pr-police.js but optimized
|
|
4
4
|
*/
|
|
5
|
-
import { ReviewResult, ReviewOptions, AIProviderConfig, CodeReviewConfig } from
|
|
6
|
-
import { UnifiedContext } from
|
|
7
|
-
import { BitbucketProvider } from
|
|
5
|
+
import { ReviewResult, ReviewOptions, AIProviderConfig, CodeReviewConfig } from "../types/index.js";
|
|
6
|
+
import { UnifiedContext } from "../core/ContextGatherer.js";
|
|
7
|
+
import { BitbucketProvider } from "../core/providers/BitbucketProvider.js";
|
|
8
8
|
export declare class CodeReviewer {
|
|
9
9
|
private neurolink;
|
|
10
10
|
private bitbucketProvider;
|