@juspay/yama 1.6.0 → 2.0.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.
Files changed (67) hide show
  1. package/.mcp-config.example.json +26 -0
  2. package/CHANGELOG.md +34 -0
  3. package/README.md +311 -685
  4. package/dist/cli/v2.cli.d.ts +13 -0
  5. package/dist/cli/v2.cli.js +290 -0
  6. package/dist/index.d.ts +12 -13
  7. package/dist/index.js +18 -19
  8. package/dist/v2/config/ConfigLoader.d.ts +50 -0
  9. package/dist/v2/config/ConfigLoader.js +205 -0
  10. package/dist/v2/config/DefaultConfig.d.ts +9 -0
  11. package/dist/v2/config/DefaultConfig.js +191 -0
  12. package/dist/v2/core/MCPServerManager.d.ts +22 -0
  13. package/dist/v2/core/MCPServerManager.js +92 -0
  14. package/dist/v2/core/SessionManager.d.ts +72 -0
  15. package/dist/v2/core/SessionManager.js +200 -0
  16. package/dist/v2/core/YamaV2Orchestrator.d.ts +112 -0
  17. package/dist/v2/core/YamaV2Orchestrator.js +549 -0
  18. package/dist/v2/prompts/EnhancementSystemPrompt.d.ts +8 -0
  19. package/dist/v2/prompts/EnhancementSystemPrompt.js +216 -0
  20. package/dist/v2/prompts/PromptBuilder.d.ts +38 -0
  21. package/dist/v2/prompts/PromptBuilder.js +228 -0
  22. package/dist/v2/prompts/ReviewSystemPrompt.d.ts +8 -0
  23. package/dist/v2/prompts/ReviewSystemPrompt.js +270 -0
  24. package/dist/v2/types/config.types.d.ts +120 -0
  25. package/dist/v2/types/config.types.js +5 -0
  26. package/dist/v2/types/mcp.types.d.ts +191 -0
  27. package/dist/v2/types/mcp.types.js +6 -0
  28. package/dist/v2/types/v2.types.d.ts +182 -0
  29. package/dist/v2/types/v2.types.js +42 -0
  30. package/dist/v2/utils/ObservabilityConfig.d.ts +22 -0
  31. package/dist/v2/utils/ObservabilityConfig.js +48 -0
  32. package/package.json +11 -9
  33. package/yama.config.example.yaml +214 -204
  34. package/dist/cli/index.d.ts +0 -12
  35. package/dist/cli/index.js +0 -538
  36. package/dist/core/ContextGatherer.d.ts +0 -110
  37. package/dist/core/ContextGatherer.js +0 -470
  38. package/dist/core/Guardian.d.ts +0 -81
  39. package/dist/core/Guardian.js +0 -480
  40. package/dist/core/providers/BitbucketProvider.d.ts +0 -105
  41. package/dist/core/providers/BitbucketProvider.js +0 -489
  42. package/dist/features/CodeReviewer.d.ts +0 -173
  43. package/dist/features/CodeReviewer.js +0 -1707
  44. package/dist/features/DescriptionEnhancer.d.ts +0 -70
  45. package/dist/features/DescriptionEnhancer.js +0 -511
  46. package/dist/features/MultiInstanceProcessor.d.ts +0 -74
  47. package/dist/features/MultiInstanceProcessor.js +0 -360
  48. package/dist/types/index.d.ts +0 -624
  49. package/dist/types/index.js +0 -104
  50. package/dist/utils/Cache.d.ts +0 -103
  51. package/dist/utils/Cache.js +0 -444
  52. package/dist/utils/ConfigManager.d.ts +0 -88
  53. package/dist/utils/ConfigManager.js +0 -602
  54. package/dist/utils/ContentSimilarityService.d.ts +0 -74
  55. package/dist/utils/ContentSimilarityService.js +0 -215
  56. package/dist/utils/ExactDuplicateRemover.d.ts +0 -77
  57. package/dist/utils/ExactDuplicateRemover.js +0 -361
  58. package/dist/utils/Logger.d.ts +0 -31
  59. package/dist/utils/Logger.js +0 -214
  60. package/dist/utils/MemoryBankManager.d.ts +0 -73
  61. package/dist/utils/MemoryBankManager.js +0 -310
  62. package/dist/utils/ParallelProcessing.d.ts +0 -140
  63. package/dist/utils/ParallelProcessing.js +0 -333
  64. package/dist/utils/ProviderLimits.d.ts +0 -58
  65. package/dist/utils/ProviderLimits.js +0 -143
  66. package/dist/utils/RetryManager.d.ts +0 -78
  67. package/dist/utils/RetryManager.js +0 -205
@@ -1,70 +0,0 @@
1
- /**
2
- * Enhanced Description Enhancer - Optimized to work with Unified Context
3
- * Preserves all original functionality from pr-describe.js but optimized
4
- */
5
- import { EnhancementOptions, EnhancementResult, AIProviderConfig, DescriptionEnhancementConfig } from "../types/index.js";
6
- import { UnifiedContext } from "../core/ContextGatherer.js";
7
- import { BitbucketProvider } from "../core/providers/BitbucketProvider.js";
8
- export declare class DescriptionEnhancer {
9
- private neurolink;
10
- private bitbucketProvider;
11
- private aiConfig;
12
- private enhancementConfig;
13
- private defaultRequiredSections;
14
- constructor(bitbucketProvider: BitbucketProvider, aiConfig: AIProviderConfig, enhancementConfig: DescriptionEnhancementConfig);
15
- /**
16
- * Get system prompt for description enhancement
17
- * Uses config.systemPrompt if provided, otherwise uses default
18
- */
19
- private getSystemPrompt;
20
- /**
21
- * Enhance description using pre-gathered unified context (OPTIMIZED)
22
- */
23
- enhanceWithContext(context: UnifiedContext, options: EnhancementOptions): Promise<EnhancementResult>;
24
- /**
25
- * Analyze existing PR description content
26
- */
27
- private analyzeExistingContent;
28
- /**
29
- * Extract preservable content (media, files, links)
30
- */
31
- private extractPreservableContent;
32
- /**
33
- * Validate presence of required sections
34
- */
35
- private validateRequiredSections;
36
- /**
37
- * Extract content for a specific section
38
- */
39
- private extractSectionContent;
40
- /**
41
- * Identify content gaps (TODOs, unanswered questions, etc.)
42
- */
43
- private identifyContentGaps;
44
- /**
45
- * Generate enhanced description using AI and unified context
46
- */
47
- private generateEnhancedDescription;
48
- /**
49
- * Build comprehensive enhancement prompt using unified context
50
- */
51
- private buildEnhancementPrompt;
52
- /**
53
- * Update PR description in Bitbucket
54
- */
55
- private updatePRDescription;
56
- /**
57
- * Show description preview for dry run
58
- */
59
- private showDescriptionPreview;
60
- /**
61
- * Generate enhancement result summary
62
- */
63
- private generateEnhancementResult;
64
- /**
65
- * Get enhancement statistics
66
- */
67
- getStats(): any;
68
- }
69
- export declare function createDescriptionEnhancer(bitbucketProvider: BitbucketProvider, aiConfig: AIProviderConfig, enhancementConfig: DescriptionEnhancementConfig): DescriptionEnhancer;
70
- //# sourceMappingURL=DescriptionEnhancer.d.ts.map
@@ -1,511 +0,0 @@
1
- /**
2
- * Enhanced Description Enhancer - Optimized to work with Unified Context
3
- * Preserves all original functionality from pr-describe.js but optimized
4
- */
5
- import { ProviderError, } from "../types/index.js";
6
- import { logger } from "../utils/Logger.js";
7
- export class DescriptionEnhancer {
8
- neurolink;
9
- bitbucketProvider;
10
- aiConfig;
11
- enhancementConfig;
12
- defaultRequiredSections = [
13
- { key: "changelog", name: "Changelog (Modules Modified)", required: true },
14
- {
15
- key: "testcases",
16
- name: "Test Cases (What to be tested)",
17
- required: true,
18
- },
19
- {
20
- key: "config_changes",
21
- name: "CAC Config Or Service Config Changes",
22
- required: true,
23
- },
24
- ];
25
- constructor(bitbucketProvider, aiConfig, enhancementConfig) {
26
- this.bitbucketProvider = bitbucketProvider;
27
- this.aiConfig = aiConfig;
28
- this.enhancementConfig = enhancementConfig;
29
- }
30
- /**
31
- * Get system prompt for description enhancement
32
- * Uses config.systemPrompt if provided, otherwise uses default
33
- */
34
- getSystemPrompt() {
35
- const isCustomPrompt = !!this.enhancementConfig.systemPrompt;
36
- if (isCustomPrompt) {
37
- logger.debug("✓ Using custom systemPrompt from configuration");
38
- logger.debug(`Custom prompt preview: ${this.enhancementConfig.systemPrompt?.substring(0, 100)}...`);
39
- }
40
- else {
41
- logger.debug("Using default systemPrompt (no custom prompt configured)");
42
- }
43
- return (this.enhancementConfig.systemPrompt ||
44
- `You are an Expert Technical Writer specializing in pull request documentation.
45
- Focus on clarity, completeness, and helping reviewers understand the changes.
46
-
47
- CRITICAL INSTRUCTION: Return ONLY the enhanced PR description content.
48
- - DO NOT add meta-commentary like "No description provided" or "Here is the enhanced description"
49
- - DO NOT add explanatory text about what you're doing
50
- - START directly with the actual PR content (title, sections, etc.)
51
- - If there's no existing description, just write the new sections without mentioning it`);
52
- }
53
- /**
54
- * Enhance description using pre-gathered unified context (OPTIMIZED)
55
- */
56
- async enhanceWithContext(context, options) {
57
- const startTime = Date.now();
58
- try {
59
- logger.phase("📝 Enhancing PR description...");
60
- logger.info(`Processing PR #${context.pr.id}: "${context.pr.title}"`);
61
- // Step 1: Analyze existing content and identify what needs enhancement
62
- const sectionsToUse = options.customSections || this.defaultRequiredSections;
63
- logger.debug(`Checking ${sectionsToUse.length} required sections: ${sectionsToUse.map((s) => s.key).join(", ")}`);
64
- const analysisResult = this.analyzeExistingContent(context.pr.description, sectionsToUse);
65
- const presentSections = analysisResult.requiredSections
66
- .filter((s) => s.present)
67
- .map((s) => s.key);
68
- const missingSections = analysisResult.requiredSections
69
- .filter((s) => !s.present)
70
- .map((s) => s.key);
71
- if (presentSections.length > 0) {
72
- logger.debug(`✓ Present sections: ${presentSections.join(", ")}`);
73
- }
74
- if (missingSections.length > 0) {
75
- logger.debug(`✗ Missing sections: ${missingSections.join(", ")}`);
76
- }
77
- logger.info(`Content analysis: ${analysisResult.preservedContent.media.length} media items, ` +
78
- `${analysisResult.missingCount} missing sections`);
79
- // Step 2: Generate enhanced description using AI
80
- const enhancedDescription = await this.generateEnhancedDescription(context, analysisResult, options);
81
- // Step 3: Update PR description if not dry run
82
- if (!options.dryRun) {
83
- await this.updatePRDescription(context, enhancedDescription);
84
- }
85
- else {
86
- this.showDescriptionPreview(enhancedDescription, analysisResult);
87
- }
88
- const duration = Math.round((Date.now() - startTime) / 1000);
89
- const result = this.generateEnhancementResult(context.pr.description, enhancedDescription, analysisResult, duration);
90
- logger.success(`Description enhancement completed in ${duration}s: ` +
91
- `${result.sectionsAdded.length} sections added, ${result.sectionsEnhanced.length} enhanced`);
92
- return result;
93
- }
94
- catch (error) {
95
- logger.error(`Description enhancement failed: ${error.message}`);
96
- throw new ProviderError(`Description enhancement failed: ${error.message}`);
97
- }
98
- }
99
- /**
100
- * Analyze existing PR description content
101
- */
102
- analyzeExistingContent(description, requiredSections) {
103
- logger.debug("Analyzing existing PR description content...");
104
- // Extract preservable content (media, files, links)
105
- const preservedContent = this.extractPreservableContent(description);
106
- // Validate required sections
107
- const sectionsAnalysis = this.validateRequiredSections(description, requiredSections);
108
- const missingCount = sectionsAnalysis.filter((s) => !s.present).length;
109
- // Identify content gaps
110
- const gaps = this.identifyContentGaps(description);
111
- return {
112
- requiredSections: sectionsAnalysis,
113
- missingCount,
114
- preservedContent,
115
- gaps,
116
- };
117
- }
118
- /**
119
- * Extract preservable content (media, files, links)
120
- */
121
- extractPreservableContent(description) {
122
- const preservableContent = {
123
- media: [],
124
- files: [],
125
- links: [],
126
- originalText: description || "",
127
- };
128
- if (!description) {
129
- return preservableContent;
130
- }
131
- // Extract images and media (screenshots, etc.)
132
- const mediaRegex = /!\[.*?\]\(.*?\)|<img[^>]*>|<video[^>]*>|<audio[^>]*>/g;
133
- preservableContent.media = description.match(mediaRegex) || [];
134
- // Extract file attachments
135
- const fileRegex = /\[.*?\]\([^)]*\.(pdf|doc|docx|xls|xlsx|ppt|pptx|zip|rar|tar|gz)[^)]*\)/gi;
136
- preservableContent.files = description.match(fileRegex) || [];
137
- // Extract links (excluding images and files)
138
- const linkRegex = /\[[^\]]*\]\([^)]+\)/g;
139
- const allLinks = description.match(linkRegex) || [];
140
- preservableContent.links = allLinks.filter((link) => !mediaRegex.test(link) && !fileRegex.test(link));
141
- logger.debug(`Preservable content: ${preservableContent.media.length} media, ` +
142
- `${preservableContent.files.length} files, ${preservableContent.links.length} links`);
143
- return preservableContent;
144
- }
145
- /**
146
- * Validate presence of required sections
147
- */
148
- validateRequiredSections(description, requiredSections) {
149
- if (!description) {
150
- return requiredSections.map((section) => ({
151
- ...section,
152
- present: false,
153
- content: "",
154
- }));
155
- }
156
- const sectionPatterns = {
157
- changelog: [
158
- /##.*?[Cc]hangelog/i,
159
- /##.*?[Mm]odules?\s+[Mm]odified/i,
160
- /##.*?[Cc]hanges?\s+[Mm]ade/i,
161
- /📋.*?[Cc]hangelog/i,
162
- ],
163
- testcases: [
164
- /##.*?[Tt]est\s+[Cc]ases?/i,
165
- /##.*?[Tt]esting/i,
166
- /🧪.*?[Tt]est/i,
167
- /##.*?[Tt]est\s+[Pp]lan/i,
168
- ],
169
- config_changes: [
170
- /##.*?[Cc]onfig/i,
171
- /##.*?CAC/i,
172
- /##.*?[Ss]ervice\s+[Cc]onfig/i,
173
- /⚙️.*?[Cc]onfig/i,
174
- ],
175
- };
176
- return requiredSections.map((section) => {
177
- let patterns = sectionPatterns[section.key];
178
- if (!patterns) {
179
- logger.debug(`No predefined pattern for section "${section.key}", using dynamic pattern based on name`);
180
- const nameWords = section.name.split(/\s+/).filter((w) => w.length > 2); // Filter out short words like "Or", "Of"
181
- const namePattern = new RegExp(`##.*?${nameWords.join(".*?")}`, "i");
182
- const keyWords = section.key.split("_").filter((w) => w.length > 2);
183
- const keyPattern = new RegExp(`##.*?${keyWords.join(".*?")}`, "i");
184
- patterns = [namePattern, keyPattern];
185
- }
186
- const isPresent = patterns.some((pattern) => pattern.test(description));
187
- return {
188
- ...section,
189
- present: isPresent,
190
- content: isPresent
191
- ? this.extractSectionContent(description, patterns)
192
- : "",
193
- };
194
- });
195
- }
196
- /**
197
- * Extract content for a specific section
198
- */
199
- extractSectionContent(description, patterns) {
200
- for (const pattern of patterns) {
201
- const match = description.match(pattern);
202
- if (match) {
203
- const startIndex = match.index + match[0].length;
204
- const nextHeaderIndex = description
205
- .substring(startIndex)
206
- .search(/\n##/);
207
- const endIndex = nextHeaderIndex === -1
208
- ? description.length
209
- : startIndex + nextHeaderIndex;
210
- return description.substring(startIndex, endIndex).trim();
211
- }
212
- }
213
- return "";
214
- }
215
- /**
216
- * Identify content gaps (TODOs, unanswered questions, etc.)
217
- */
218
- identifyContentGaps(description) {
219
- const gaps = [];
220
- if (!description) {
221
- gaps.push("No description provided");
222
- return gaps;
223
- }
224
- // Check for unanswered questions and placeholders
225
- const gapMarkers = [
226
- { pattern: /\?\s*$/gm, name: "unanswered questions" },
227
- { pattern: /TODO/gi, name: "TODO items" },
228
- { pattern: /FIXME/gi, name: "FIXME items" },
229
- { pattern: /\[TBD\]/gi, name: "TBD placeholders" },
230
- { pattern: /\[TO BE DETERMINED\]/gi, name: "TBD placeholders" },
231
- { pattern: /\[PENDING\]/gi, name: "pending items" },
232
- ];
233
- gapMarkers.forEach((marker) => {
234
- const matches = description.match(marker.pattern);
235
- if (matches) {
236
- gaps.push(`${matches.length} ${marker.name}`);
237
- }
238
- });
239
- return gaps;
240
- }
241
- /**
242
- * Generate enhanced description using AI and unified context
243
- */
244
- async generateEnhancedDescription(context, analysisResult, options) {
245
- logger.debug("Generating AI-enhanced description...");
246
- // Initialize NeuroLink with eval-based dynamic import
247
- if (!this.neurolink) {
248
- const { NeuroLink } = await import("@juspay/neurolink");
249
- this.neurolink = new NeuroLink();
250
- }
251
- const enhancementPrompt = this.buildEnhancementPrompt(context, analysisResult, options);
252
- try {
253
- const result = await this.neurolink.generate({
254
- input: { text: enhancementPrompt },
255
- systemPrompt: this.getSystemPrompt(), // Use config or default system prompt
256
- provider: this.aiConfig.provider,
257
- model: this.aiConfig.model,
258
- temperature: this.aiConfig.temperature || 0.7,
259
- maxTokens: this.aiConfig.maxTokens || 1000000,
260
- timeout: "8m", // Longer timeout for description generation
261
- enableAnalytics: this.aiConfig.enableAnalytics,
262
- enableEvaluation: this.aiConfig.enableEvaluation,
263
- });
264
- let enhancedDescription = result.content ||
265
- result.text ||
266
- result.response ||
267
- "";
268
- // Clean up any markdown code blocks if AI wrapped the response
269
- enhancedDescription = enhancedDescription
270
- .replace(/^```markdown\s*/, "")
271
- .replace(/\s*```$/, "")
272
- .trim();
273
- // Remove any meta-commentary that AI might have added
274
- enhancedDescription = enhancedDescription
275
- .replace(/^No description provided\.?\s*/i, "")
276
- .replace(/^Here is the enhanced description:?\s*/i, "")
277
- .replace(/^I will enhance.*?:\s*/i, "")
278
- .replace(/^Enhanced description:?\s*/i, "")
279
- .trim();
280
- if (!enhancedDescription) {
281
- throw new Error("AI generated empty description");
282
- }
283
- // Validate that required sections are present after enhancement
284
- const finalValidation = this.validateRequiredSections(enhancedDescription, options.customSections || this.defaultRequiredSections);
285
- const stillMissing = finalValidation.filter((s) => !s.present);
286
- if (stillMissing.length > 0) {
287
- const missingSectionNames = stillMissing.map((s) => s.key).join(", ");
288
- logger.warn(`Warning: ${stillMissing.length} required sections still missing after AI enhancement: ${missingSectionNames}`);
289
- logger.debug(`AI may not have added these sections or they don't match detection patterns`);
290
- }
291
- else {
292
- logger.debug(`✓ All ${finalValidation.length} required sections are now present`);
293
- }
294
- return enhancedDescription;
295
- }
296
- catch (error) {
297
- if (error.message?.includes("timeout")) {
298
- logger.error("⏰ Description enhancement timed out after 8 minutes");
299
- throw new Error("Enhancement timeout - try with smaller diff or adjust timeout");
300
- }
301
- logger.error(`AI description generation failed: ${error.message}`);
302
- throw error;
303
- }
304
- }
305
- /**
306
- * Build comprehensive enhancement prompt using unified context
307
- */
308
- buildEnhancementPrompt(context, analysisResult, _options) {
309
- // Prepare diff information based on strategy
310
- let diffInfo = "";
311
- if (context.diffStrategy.strategy === "whole" && context.prDiff) {
312
- diffInfo = `**Diff Strategy**: Whole PR diff (${context.diffStrategy.fileCount} files)
313
- **Changes**: ${JSON.stringify(context.prDiff.fileChanges?.slice(0, 20) || [], null, 2)}`;
314
- }
315
- else if (context.diffStrategy.strategy === "file-by-file" &&
316
- context.fileDiffs) {
317
- const fileList = Array.from(context.fileDiffs.keys()).slice(0, 20);
318
- diffInfo = `**Diff Strategy**: File-by-file analysis (${context.diffStrategy.fileCount} files)
319
- **Modified Files**: ${JSON.stringify(fileList, null, 2)}`;
320
- }
321
- const customInstructions = this.enhancementConfig.enhancementInstructions || "";
322
- if (customInstructions) {
323
- logger.debug("✓ Using custom enhancementInstructions from configuration");
324
- logger.debug(`Instructions preview: ${customInstructions.substring(0, 80)}...`);
325
- }
326
- else {
327
- logger.debug("Using default enhancementInstructions");
328
- }
329
- return `${customInstructions || "You are an expert technical writer specializing in comprehensive PR descriptions."}
330
-
331
- ## PR INFORMATION:
332
- **Title**: ${context.pr.title}
333
- **Author**: ${context.pr.author}
334
- **Current Description**:
335
- ${analysisResult.preservedContent.originalText || "[No existing description]"}
336
-
337
- ## CODE CHANGES ANALYSIS:
338
- ${diffInfo}
339
-
340
- ## PROJECT CONTEXT:
341
- ${context.projectContext.memoryBank.summary}
342
-
343
- ## PROJECT RULES:
344
- ${context.projectContext.clinerules || "No specific rules defined"}
345
-
346
- ## CONTENT PRESERVATION REQUIREMENTS:
347
- **CRITICAL**: This is content ENHANCEMENT, not replacement!
348
-
349
- ### Preserved Content Analysis:
350
- - **Media Items**: ${analysisResult.preservedContent.media.length} (${analysisResult.preservedContent.media.join(", ")})
351
- - **File Attachments**: ${analysisResult.preservedContent.files.length} (${analysisResult.preservedContent.files.join(", ")})
352
- - **Links**: ${analysisResult.preservedContent.links.length}
353
- - **Content Gaps**: ${analysisResult.gaps.join(", ") || "None identified"}
354
-
355
- ### PRESERVATION RULES:
356
- - **NEVER REMOVE**: Screenshots, images, file attachments, existing explanations, or links
357
- - **PRESERVE EXACTLY**: All media links, file references, and existing valuable content
358
- - **ONLY ADD**: Missing required sections or enhance clearly incomplete ones
359
- - **MAINTAIN**: Original structure, tone, and author's explanations
360
-
361
- ## REQUIRED SECTIONS STATUS:
362
- ${analysisResult.requiredSections
363
- .map((section) => `
364
- **${section.name}**:
365
- - Present: ${section.present ? "✅ Yes" : "❌ Missing"}
366
- - Content: ${section.content ? `"${section.content.substring(0, 100)}..."` : "None"}
367
- - Action Needed: ${section.present ? ((section.content?.length || 0) < 50 ? "Enhancement" : "None") : "Add Section"}`)
368
- .join("")}
369
-
370
- ## REQUIRED SECTIONS TO IMPLEMENT:
371
-
372
- ### 1. 📋 CHANGELOG (Modules Modified)
373
- **Purpose**: Clear documentation of what changed
374
- **Content Requirements**:
375
- - List specific files/modules modified, added, or removed
376
- - Categorize changes (Features, Bug Fixes, Improvements, Breaking Changes)
377
- - Mention key components affected
378
- - Highlight any architectural changes
379
-
380
- ### 2. 🧪 TEST CASES (What to be tested)
381
- **Purpose**: Comprehensive testing guidance
382
- **Content Requirements**:
383
- - Unit tests to run or add
384
- - Integration test scenarios
385
- - Manual testing steps for reviewers
386
- - Edge cases to verify
387
- - Regression testing considerations
388
- - Performance testing if applicable
389
-
390
- ### 3. ⚙️ CAC CONFIG OR SERVICE CONFIG CHANGES
391
- **Purpose**: Infrastructure and configuration impact
392
- **Content Requirements**:
393
- - Configuration files modified
394
- - Environment variables added/changed/removed
395
- - Service configuration updates
396
- - Database schema changes
397
- - Deployment considerations
398
- - If no config changes: explicitly state "No configuration changes required"
399
-
400
- ## ENHANCEMENT STRATEGY:
401
-
402
- ### For Missing Sections:
403
- 1. **START** with the complete existing description
404
- 2. **ANALYZE** the code changes to understand the scope
405
- 3. **ADD** each missing required section with comprehensive content
406
- 4. **EXTRACT** relevant information from the diff to populate sections
407
-
408
- ### For Incomplete Sections:
409
- 1. **PRESERVE** all existing content in the section
410
- 2. **ENHANCE** with additional details based on code analysis
411
- 3. **MAINTAIN** the original structure and format
412
-
413
- ### Content Generation Guidelines:
414
- - **Be Specific**: Use actual file names, function names, and module names from the changes
415
- - **Be Actionable**: Provide clear, executable test instructions
416
- - **Be Complete**: Cover all aspects of the change comprehensively
417
- - **Be Professional**: Maintain technical accuracy and clear communication
418
-
419
- ## OUTPUT REQUIREMENTS:
420
- Return the COMPLETE enhanced description as properly formatted markdown text (NOT JSON).
421
-
422
- **CRITICAL INSTRUCTIONS**:
423
- 1. **START WITH**: The entire existing description as your foundation
424
- 2. **PRESERVE**: Every single piece of existing content (media, links, explanations)
425
- 3. **ADD ONLY**: Missing required sections at appropriate locations
426
- 4. **ENHANCE ONLY**: Clearly incomplete sections with additional details
427
- 5. **EXTRACT**: Specific details from the code changes for accuracy
428
- 6. **MAINTAIN**: Professional tone and clear markdown formatting
429
-
430
- Generate the enhanced description now, ensuring ALL preservation requirements are met:`;
431
- }
432
- /**
433
- * Update PR description in Bitbucket
434
- */
435
- async updatePRDescription(context, enhancedDescription) {
436
- logger.debug(`Updating PR description for #${context.pr.id}...`);
437
- try {
438
- await this.bitbucketProvider.updatePRDescription(context.identifier, enhancedDescription);
439
- logger.success("✅ PR description updated successfully");
440
- }
441
- catch (error) {
442
- logger.error(`Failed to update PR description: ${error.message}`);
443
- throw new ProviderError(`Description update failed: ${error.message}`);
444
- }
445
- }
446
- /**
447
- * Show description preview for dry run
448
- */
449
- showDescriptionPreview(enhancedDescription, analysisResult) {
450
- console.log("\n" + "═".repeat(80));
451
- console.log("📝 ENHANCED PR DESCRIPTION PREVIEW");
452
- console.log("═".repeat(80));
453
- console.log(enhancedDescription);
454
- console.log("═".repeat(80));
455
- console.log("\n📊 ENHANCEMENT SUMMARY:");
456
- console.log(`✅ Required sections completed: ${analysisResult.requiredSections.filter((s) => s.present).length}/${analysisResult.requiredSections.length}`);
457
- console.log(`📎 Preserved content: ${analysisResult.preservedContent.media.length} media items, ${analysisResult.preservedContent.files.length} files`);
458
- console.log(`📏 Enhanced description length: ${enhancedDescription.length} characters`);
459
- if (analysisResult.gaps.length > 0) {
460
- console.log(`🔍 Content gaps addressed: ${analysisResult.gaps.join(", ")}`);
461
- }
462
- }
463
- /**
464
- * Generate enhancement result summary
465
- */
466
- generateEnhancementResult(originalDescription, enhancedDescription, analysisResult, _duration) {
467
- // Determine what sections were added or enhanced
468
- const originalSections = this.validateRequiredSections(originalDescription, analysisResult.requiredSections);
469
- const enhancedSections = this.validateRequiredSections(enhancedDescription, analysisResult.requiredSections);
470
- const sectionsAdded = enhancedSections
471
- .filter((enhanced, i) => enhanced.present && !originalSections[i].present)
472
- .map((s) => s.name);
473
- const sectionsEnhanced = enhancedSections
474
- .filter((enhanced, i) => enhanced.present &&
475
- originalSections[i].present &&
476
- (enhanced.content?.length || 0) >
477
- (originalSections[i].content?.length || 0) + 50)
478
- .map((s) => s.name);
479
- const completedSections = enhancedSections.filter((s) => s.present).length;
480
- return {
481
- originalDescription: originalDescription || "",
482
- enhancedDescription,
483
- sectionsAdded,
484
- sectionsEnhanced,
485
- preservedItems: {
486
- media: analysisResult.preservedContent.media.length,
487
- files: analysisResult.preservedContent.files.length,
488
- links: analysisResult.preservedContent.links.length,
489
- },
490
- statistics: {
491
- originalLength: originalDescription?.length || 0,
492
- enhancedLength: enhancedDescription.length,
493
- completedSections,
494
- totalSections: analysisResult.requiredSections.length,
495
- },
496
- };
497
- }
498
- /**
499
- * Get enhancement statistics
500
- */
501
- getStats() {
502
- return {
503
- defaultSections: this.defaultRequiredSections.length,
504
- aiProvider: this.aiConfig.provider,
505
- };
506
- }
507
- }
508
- export function createDescriptionEnhancer(bitbucketProvider, aiConfig, enhancementConfig) {
509
- return new DescriptionEnhancer(bitbucketProvider, aiConfig, enhancementConfig);
510
- }
511
- //# sourceMappingURL=DescriptionEnhancer.js.map
@@ -1,74 +0,0 @@
1
- /**
2
- * Multi-Instance Processor for Parallel Code Review
3
- * Orchestrates multiple Neurolink SDK instances for diverse code analysis
4
- */
5
- import { MultiInstanceConfig, MultiInstanceResult, CodeReviewConfig, ReviewOptions } from "../types/index.js";
6
- import { UnifiedContext } from "../core/ContextGatherer.js";
7
- import { BitbucketProvider } from "../core/providers/BitbucketProvider.js";
8
- /**
9
- * Multi-Instance Processor
10
- * Manages parallel execution of multiple CodeReviewer instances
11
- */
12
- export declare class MultiInstanceProcessor {
13
- private bitbucketProvider;
14
- private baseReviewConfig;
15
- private duplicateRemover;
16
- constructor(bitbucketProvider: BitbucketProvider, baseReviewConfig: CodeReviewConfig);
17
- /**
18
- * Process code review using multiple instances
19
- */
20
- processWithMultipleInstances(context: UnifiedContext, options: ReviewOptions, multiInstanceConfig: MultiInstanceConfig): Promise<MultiInstanceResult>;
21
- /**
22
- * Execute all instances in parallel with concurrency control
23
- */
24
- private executeInstancesInParallel;
25
- /**
26
- * Execute a single instance with concurrency control
27
- */
28
- private executeInstanceWithConcurrency;
29
- /**
30
- * Validate provider string against allowed provider types
31
- */
32
- private validateProvider;
33
- /**
34
- * Execute a single instance
35
- */
36
- private executeInstance;
37
- /**
38
- * Validate multi-instance configuration
39
- */
40
- private validateMultiInstanceConfig;
41
- /**
42
- * Estimate tokens per instance based on context
43
- */
44
- private estimateTokensPerInstance;
45
- /**
46
- * Calculate total token budget for all instances
47
- */
48
- private calculateTotalTokenBudget;
49
- /**
50
- * Extract token usage from review result (if available)
51
- */
52
- private extractTokenUsage;
53
- /**
54
- * Create non-deduplicated result (when deduplication is disabled)
55
- */
56
- private createNonDeduplicatedResult;
57
- /**
58
- * Apply final filtering based on configuration
59
- */
60
- private applyFinalFiltering;
61
- /**
62
- * Prioritize violations based on strategy
63
- */
64
- private prioritizeViolations;
65
- /**
66
- * Create summary of multi-instance processing
67
- */
68
- private createSummary;
69
- }
70
- /**
71
- * Factory function to create MultiInstanceProcessor
72
- */
73
- export declare function createMultiInstanceProcessor(bitbucketProvider: BitbucketProvider, baseReviewConfig: CodeReviewConfig): MultiInstanceProcessor;
74
- //# sourceMappingURL=MultiInstanceProcessor.d.ts.map