@codesherlock/codesherlock-beta-mcp-server 0.0.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.
Files changed (87) hide show
  1. package/.env +9 -0
  2. package/README.md +185 -0
  3. package/build/handlers/analyzeCommitHandler.d.ts +36 -0
  4. package/build/handlers/analyzeCommitHandler.d.ts.map +1 -0
  5. package/build/handlers/analyzeCommitHandler.js +397 -0
  6. package/build/handlers/analyzeCommitHandler.js.map +1 -0
  7. package/build/handlers/events.d.ts +7 -0
  8. package/build/handlers/events.d.ts.map +1 -0
  9. package/build/handlers/events.js +15 -0
  10. package/build/handlers/events.js.map +1 -0
  11. package/build/handlers/resources.d.ts +10 -0
  12. package/build/handlers/resources.d.ts.map +1 -0
  13. package/build/handlers/resources.js +14 -0
  14. package/build/handlers/resources.js.map +1 -0
  15. package/build/handlers/tools.d.ts +6 -0
  16. package/build/handlers/tools.d.ts.map +1 -0
  17. package/build/handlers/tools.js +29 -0
  18. package/build/handlers/tools.js.map +1 -0
  19. package/build/index.d.ts +3 -0
  20. package/build/index.d.ts.map +1 -0
  21. package/build/index.js +82 -0
  22. package/build/index.js.map +1 -0
  23. package/build/schemas/toolSchemas.d.ts +50 -0
  24. package/build/schemas/toolSchemas.d.ts.map +1 -0
  25. package/build/schemas/toolSchemas.js +48 -0
  26. package/build/schemas/toolSchemas.js.map +1 -0
  27. package/build/services/backendApiService.d.ts +81 -0
  28. package/build/services/backendApiService.d.ts.map +1 -0
  29. package/build/services/backendApiService.js +265 -0
  30. package/build/services/backendApiService.js.map +1 -0
  31. package/build/services/commitReviewService.d.ts +71 -0
  32. package/build/services/commitReviewService.d.ts.map +1 -0
  33. package/build/services/commitReviewService.js +506 -0
  34. package/build/services/commitReviewService.js.map +1 -0
  35. package/build/services/gitService.d.ts +159 -0
  36. package/build/services/gitService.d.ts.map +1 -0
  37. package/build/services/gitService.js +778 -0
  38. package/build/services/gitService.js.map +1 -0
  39. package/build/services/loggingService.d.ts +64 -0
  40. package/build/services/loggingService.d.ts.map +1 -0
  41. package/build/services/loggingService.js +185 -0
  42. package/build/services/loggingService.js.map +1 -0
  43. package/build/services/zipService.d.ts +9 -0
  44. package/build/services/zipService.d.ts.map +1 -0
  45. package/build/services/zipService.js +47 -0
  46. package/build/services/zipService.js.map +1 -0
  47. package/build/tests/analysisFormatter.test.d.ts +2 -0
  48. package/build/tests/analysisFormatter.test.d.ts.map +1 -0
  49. package/build/tests/analysisFormatter.test.js +92 -0
  50. package/build/tests/analysisFormatter.test.js.map +1 -0
  51. package/build/tests/analyzeCommitHandler.test.d.ts +2 -0
  52. package/build/tests/analyzeCommitHandler.test.d.ts.map +1 -0
  53. package/build/tests/analyzeCommitHandler.test.js +111 -0
  54. package/build/tests/analyzeCommitHandler.test.js.map +1 -0
  55. package/build/tests/backendApiService.test.d.ts +2 -0
  56. package/build/tests/backendApiService.test.d.ts.map +1 -0
  57. package/build/tests/backendApiService.test.js +109 -0
  58. package/build/tests/backendApiService.test.js.map +1 -0
  59. package/build/tests/commitReviewService.test.d.ts +2 -0
  60. package/build/tests/commitReviewService.test.d.ts.map +1 -0
  61. package/build/tests/commitReviewService.test.js +120 -0
  62. package/build/tests/commitReviewService.test.js.map +1 -0
  63. package/build/tests/errorExtractor.test.d.ts +2 -0
  64. package/build/tests/errorExtractor.test.d.ts.map +1 -0
  65. package/build/tests/errorExtractor.test.js +61 -0
  66. package/build/tests/errorExtractor.test.js.map +1 -0
  67. package/build/tests/loggingService.test.d.ts +2 -0
  68. package/build/tests/loggingService.test.d.ts.map +1 -0
  69. package/build/tests/loggingService.test.js +153 -0
  70. package/build/tests/loggingService.test.js.map +1 -0
  71. package/build/tests/setup.test.d.ts +2 -0
  72. package/build/tests/setup.test.d.ts.map +1 -0
  73. package/build/tests/setup.test.js +7 -0
  74. package/build/tests/setup.test.js.map +1 -0
  75. package/build/tests/tools.test.d.ts +2 -0
  76. package/build/tests/tools.test.d.ts.map +1 -0
  77. package/build/tests/tools.test.js +58 -0
  78. package/build/tests/tools.test.js.map +1 -0
  79. package/build/utils/analysisFormatter.d.ts +40 -0
  80. package/build/utils/analysisFormatter.d.ts.map +1 -0
  81. package/build/utils/analysisFormatter.js +97 -0
  82. package/build/utils/analysisFormatter.js.map +1 -0
  83. package/build/utils/errorExtractor.d.ts +36 -0
  84. package/build/utils/errorExtractor.d.ts.map +1 -0
  85. package/build/utils/errorExtractor.js +178 -0
  86. package/build/utils/errorExtractor.js.map +1 -0
  87. package/package.json +55 -0
@@ -0,0 +1,506 @@
1
+ import { logger } from "./loggingService.js";
2
+ import WebSocket from "ws";
3
+ /**
4
+ * Commit Review Service
5
+ * Handles the full flow of submitting commit review and receiving results via WebSocket
6
+ */
7
+ export class CommitReviewService {
8
+ backendApiService;
9
+ constructor(backendApiService) {
10
+ this.backendApiService = backendApiService;
11
+ }
12
+ /**
13
+ * Submit commit review and wait for analysis results via WebSocket
14
+ * @param params - Commit review parameters
15
+ * @returns Analysis results
16
+ */
17
+ async submitAndWaitForResults(params) {
18
+ let wsConnection;
19
+ try {
20
+ // IMPORTANT: Establish WebSocket connection (and listeners) BEFORE
21
+ // calling the backend HTTP API so we don't miss any early messages.
22
+ logger.logInfo("Step 1: Establishing WebSocket connection BEFORE submitting review", {
23
+ user_id: params.user_id,
24
+ });
25
+ // Step 1: Establish WebSocket connection FIRST and wait for it to be fully connected
26
+ const wsConnectionPromise = new Promise((resolve, reject) => {
27
+ this.backendApiService.connectWebSocket(params.user_id, () => { }, // onMessage will be handled by collectResultsViaWebSocket
28
+ (error) => {
29
+ logger.logError("WebSocket connection failed before submit", error, { user_id: params.user_id });
30
+ reject(error);
31
+ }, () => { } // onClose will be handled by collectResultsViaWebSocket
32
+ ).then((ws) => {
33
+ // Verify WebSocket is actually open
34
+ if (ws.readyState === WebSocket.OPEN) {
35
+ wsConnection = ws;
36
+ logger.logInfo("✅ WebSocket connection fully established and verified OPEN", {
37
+ user_id: params.user_id,
38
+ readyState: String(ws.readyState)
39
+ });
40
+ resolve(ws);
41
+ }
42
+ else {
43
+ const error = new Error(`WebSocket connection not fully open. ReadyState: ${ws.readyState}`);
44
+ logger.logError("❌ WebSocket not in OPEN state", error, {
45
+ user_id: params.user_id,
46
+ readyState: String(ws.readyState)
47
+ });
48
+ reject(error);
49
+ }
50
+ }).catch(reject);
51
+ });
52
+ // CRITICAL: Wait for WebSocket to be fully connected before proceeding
53
+ const establishedWs = await wsConnectionPromise;
54
+ logger.logInfo("✅ WebSocket connection confirmed OPEN, proceeding with HTTP call", {
55
+ user_id: params.user_id,
56
+ });
57
+ // Step 2: Start collecting results via WebSocket (reuse the established connection)
58
+ // We'll set up message handlers on the already-established connection
59
+ const analysisResultsPromise = this.collectResultsViaEstablishedWebSocket(establishedWs, params.user_id);
60
+ // Step 3: Submit commit review via HTTP POST (WebSocket is now connected and ready)
61
+ logger.logInfo("Submitting commit review to backend", {
62
+ user_id: params.user_id,
63
+ factor: params.factor,
64
+ fileCount: String(params.file_changes.length),
65
+ });
66
+ const submitResponse = await this.backendApiService.submitCommitReview({
67
+ factor: params.factor,
68
+ user_id: params.user_id,
69
+ repo_name: params.repo_name,
70
+ commit_id: params.commit_id,
71
+ username: params.username,
72
+ files_json: JSON.stringify(params.file_changes),
73
+ organization_name: params.organization_name,
74
+ });
75
+ logger.logInfo("Commit review submitted", {
76
+ analysisId: submitResponse.analysisId || "none",
77
+ });
78
+ // Step 2: Wait for WebSocket‑delivered analysis results
79
+ const analysisResults = await analysisResultsPromise;
80
+ // Handle edge case: WebSocket completed but no results received
81
+ // This can happen when:
82
+ // 1. No relevant code files were found (all files are deleted or non-code files)
83
+ // 2. All file processing failed silently
84
+ // 3. Backend pipeline completed but didn't send any analysis results
85
+ if (!analysisResults || analysisResults.length === 0) {
86
+ logger.logWarning("WebSocket completed but no analysis results received", {
87
+ user_id: params.user_id,
88
+ commit_id: params.commit_id,
89
+ fileCount: String(params.file_changes.length),
90
+ });
91
+ return {
92
+ success: false,
93
+ error: "No analysis results received. This may occur if no valid code files were found in the commit, or if all file processing failed. Please ensure your commit contains code files that can be analyzed.",
94
+ analysisId: submitResponse.analysisId,
95
+ results: [],
96
+ };
97
+ }
98
+ // Filter out any invalid results (files with no analysis data)
99
+ const validResults = analysisResults.filter(result => result &&
100
+ result.file_name &&
101
+ (result.analysis !== undefined && result.analysis !== null));
102
+ if (validResults.length === 0) {
103
+ logger.logWarning("All analysis results were invalid or empty", {
104
+ user_id: params.user_id,
105
+ commit_id: params.commit_id,
106
+ totalResults: String(analysisResults.length),
107
+ });
108
+ return {
109
+ success: false,
110
+ error: "Analysis completed but no valid results were generated. This may occur if the files could not be analyzed or if the analysis pipeline encountered errors.",
111
+ analysisId: submitResponse.analysisId,
112
+ results: analysisResults,
113
+ };
114
+ }
115
+ logger.logInfo("Analysis results received successfully", {
116
+ user_id: params.user_id,
117
+ commit_id: params.commit_id,
118
+ resultCount: String(validResults.length),
119
+ totalResults: String(analysisResults.length),
120
+ });
121
+ return {
122
+ success: true,
123
+ analysisId: submitResponse.analysisId,
124
+ message: submitResponse.message,
125
+ results: validResults,
126
+ };
127
+ }
128
+ catch (error) {
129
+ logger.logError("Error in commit review flow", error);
130
+ // If we get a 401 (Unauthorized) from the backend, close the WebSocket connection
131
+ // because the backend won't be sending any analysis results.
132
+ if (error instanceof Error && error.message.includes("status: 401")) {
133
+ if (wsConnection) {
134
+ logger.logInfo("Closing WebSocket connection due to 401 Unauthorized error");
135
+ wsConnection.close();
136
+ }
137
+ }
138
+ return {
139
+ success: false,
140
+ error: error instanceof Error ? error.message : String(error),
141
+ };
142
+ }
143
+ }
144
+ /**
145
+ * Collect analysis results via an already-established WebSocket connection
146
+ * This method reuses an existing WebSocket connection instead of creating a new one
147
+ * @param ws - Already-established WebSocket connection (must be in OPEN state)
148
+ * @param userId - User ID for logging
149
+ * @param timeoutMs - Maximum time to wait for results (default: 10 minutes)
150
+ * @returns Array of analysis results
151
+ */
152
+ async collectResultsViaEstablishedWebSocket(ws, userId, timeoutMs = 10 * 60 * 1000 // 10 minutes default timeout
153
+ ) {
154
+ const analysisResults = [];
155
+ let wsError = null;
156
+ let wsStatusCode;
157
+ let wsErrorMessage;
158
+ let isComplete = false;
159
+ let timeoutId;
160
+ // Verify WebSocket is open
161
+ if (ws.readyState !== WebSocket.OPEN) {
162
+ throw new Error(`WebSocket must be in OPEN state. Current state: ${ws.readyState}`);
163
+ }
164
+ // Set up timeout to prevent indefinite waiting
165
+ const timeoutPromise = new Promise((_, reject) => {
166
+ timeoutId = setTimeout(() => {
167
+ if (!isComplete) {
168
+ wsError = "Analysis timeout: The analysis took too long to complete. Please try again with fewer files or contact support if the issue persists.";
169
+ logger.logError("WebSocket timeout", new Error(wsError), {
170
+ user_id: userId,
171
+ timeoutMs: String(timeoutMs),
172
+ });
173
+ ws.close();
174
+ reject(new Error(wsError));
175
+ }
176
+ }, timeoutMs);
177
+ });
178
+ return new Promise((resolve, reject) => {
179
+ // Set up message handler
180
+ const messageHandler = (data) => {
181
+ try {
182
+ const message = JSON.parse(data.toString());
183
+ // Clear timeout on first message (analysis has started)
184
+ if (timeoutId) {
185
+ clearTimeout(timeoutId);
186
+ // Reset timeout to allow more time for completion
187
+ timeoutId = setTimeout(() => {
188
+ if (!isComplete) {
189
+ wsError = "Analysis timeout: The analysis is taking longer than expected. Please try again or contact support.";
190
+ logger.logError("WebSocket timeout after receiving initial results", new Error(wsError), {
191
+ user_id: userId,
192
+ resultsReceived: String(analysisResults.length),
193
+ });
194
+ ws.close();
195
+ cleanup();
196
+ reject(new Error(wsError));
197
+ }
198
+ }, timeoutMs);
199
+ }
200
+ // Handle WebSocket error messages from backend
201
+ if (message.status_code !== 200 && message.status_code !== undefined) {
202
+ wsStatusCode = message.status_code;
203
+ wsErrorMessage = message.error_message || "Unknown error from backend";
204
+ wsError = wsErrorMessage || "Unknown error from backend";
205
+ isComplete = true;
206
+ if (timeoutId)
207
+ clearTimeout(timeoutId);
208
+ // Log full WebSocket error payload from backend for debugging
209
+ logger.logError("WebSocket error message received", new Error(wsErrorMessage), {
210
+ status_code: String(wsStatusCode),
211
+ user_id: userId,
212
+ raw_message: JSON.stringify(message),
213
+ });
214
+ cleanup();
215
+ reject(new Error(wsError || "Unknown error from backend"));
216
+ return;
217
+ }
218
+ if (message.content) {
219
+ const isCommitReview = message.content.analysis_type === "commit_review";
220
+ if (isCommitReview) {
221
+ const file_name = message.content.file_name?.replace(/\\/g, "/") || "";
222
+ const analysis = message.content.analysis;
223
+ if (file_name && analysis !== undefined && analysis !== null) {
224
+ analysisResults.push({
225
+ analysis: analysis,
226
+ language: message.content.language,
227
+ file_name: file_name,
228
+ analysisId: message.analysis_id ?? 0,
229
+ });
230
+ logger.logInfo("Analysis result received for file", {
231
+ user_id: userId,
232
+ file_name: file_name,
233
+ result_count: String(analysisResults.length),
234
+ });
235
+ }
236
+ // Check if analysis is complete
237
+ if (message.content.is_complete || message.content.status === "complete") {
238
+ isComplete = true;
239
+ if (timeoutId)
240
+ clearTimeout(timeoutId);
241
+ logger.logInfo("Analysis marked as complete", {
242
+ user_id: userId,
243
+ total_results: String(analysisResults.length),
244
+ });
245
+ cleanup();
246
+ resolve(analysisResults);
247
+ }
248
+ }
249
+ }
250
+ }
251
+ catch (error) {
252
+ logger.logError("Error parsing WebSocket message", error);
253
+ }
254
+ };
255
+ const errorHandler = (error) => {
256
+ if (timeoutId)
257
+ clearTimeout(timeoutId);
258
+ wsError = error.message;
259
+ logger.logError("WebSocket connection error", error, { user_id: userId });
260
+ cleanup();
261
+ reject(error);
262
+ };
263
+ const closeHandler = (code, reason) => {
264
+ if (timeoutId)
265
+ clearTimeout(timeoutId);
266
+ const reasonStr = reason.toString();
267
+ if (code !== 1000 && !isComplete) {
268
+ wsError = `Connection closed unexpectedly: ${reasonStr}`;
269
+ logger.logWarning("WebSocket closed unexpectedly", {
270
+ code: String(code),
271
+ reason: reasonStr,
272
+ user_id: userId,
273
+ isComplete: String(isComplete),
274
+ results_received: String(analysisResults.length),
275
+ });
276
+ cleanup();
277
+ reject(new Error(wsError));
278
+ }
279
+ else if (code === 1000 && !isComplete) {
280
+ logger.logInfo("WebSocket closed normally, treating as completion", {
281
+ user_id: userId,
282
+ results_received: String(analysisResults.length),
283
+ });
284
+ isComplete = true;
285
+ cleanup();
286
+ resolve(analysisResults);
287
+ }
288
+ else {
289
+ cleanup();
290
+ resolve(analysisResults);
291
+ }
292
+ };
293
+ const cleanup = () => {
294
+ ws.removeListener("message", messageHandler);
295
+ ws.removeListener("error", errorHandler);
296
+ ws.removeListener("close", closeHandler);
297
+ };
298
+ // Attach event handlers to the already-established connection
299
+ ws.on("message", messageHandler);
300
+ ws.on("error", errorHandler);
301
+ ws.on("close", closeHandler);
302
+ // Race timeout - will be resolved by handlers
303
+ timeoutPromise.catch(() => {
304
+ // Timeout already handled in timeoutPromise
305
+ });
306
+ });
307
+ }
308
+ /**
309
+ * Connect to WebSocket and collect analysis results
310
+ * Handles edge cases:
311
+ * - Timeout scenarios (backend takes too long)
312
+ * - Empty results (no files to analyze)
313
+ * - Partial results (some files succeed, others fail)
314
+ * - WebSocket completion without explicit completion signal
315
+ * @param userId - User ID for WebSocket connection
316
+ * @param onConnection - Callback when connection is established
317
+ * @param timeoutMs - Maximum time to wait for results (default: 10 minutes)
318
+ * @returns Array of analysis results
319
+ */
320
+ async collectResultsViaWebSocket(userId, onConnection, timeoutMs = 10 * 60 * 1000 // 10 minutes default timeout
321
+ ) {
322
+ const analysisResults = [];
323
+ let wsError = null;
324
+ let wsStatusCode;
325
+ let wsErrorMessage;
326
+ let isComplete = false;
327
+ let timeoutId;
328
+ let wsConnection;
329
+ // Set up timeout to prevent indefinite waiting
330
+ const timeoutPromise = new Promise((_, reject) => {
331
+ timeoutId = setTimeout(() => {
332
+ if (!isComplete) {
333
+ wsError = "Analysis timeout: The analysis took too long to complete. Please try again with fewer files or contact support if the issue persists.";
334
+ logger.logError("WebSocket timeout", new Error(wsError), {
335
+ user_id: userId,
336
+ timeoutMs: String(timeoutMs),
337
+ });
338
+ if (wsConnection) {
339
+ wsConnection.close();
340
+ }
341
+ reject(new Error(wsError));
342
+ }
343
+ }, timeoutMs);
344
+ });
345
+ try {
346
+ await Promise.race([
347
+ new Promise((resolve, reject) => {
348
+ this.backendApiService.connectWebSocket(userId, (message) => {
349
+ // Clear timeout on first message (analysis has started)
350
+ if (timeoutId) {
351
+ clearTimeout(timeoutId);
352
+ // Reset timeout to allow more time for completion
353
+ timeoutId = setTimeout(() => {
354
+ if (!isComplete) {
355
+ wsError = "Analysis timeout: The analysis is taking longer than expected. Please try again or contact support.";
356
+ logger.logError("WebSocket timeout after receiving initial results", new Error(wsError), {
357
+ user_id: userId,
358
+ resultsReceived: String(analysisResults.length),
359
+ });
360
+ if (wsConnection) {
361
+ wsConnection.close();
362
+ }
363
+ reject(new Error(wsError));
364
+ }
365
+ }, timeoutMs);
366
+ }
367
+ // Handle WebSocket error messages from backend
368
+ // Backend sends errors via WebSocket with status_code and error_message
369
+ if (message.status_code !== 200 && message.status_code !== undefined) {
370
+ wsStatusCode = message.status_code;
371
+ wsErrorMessage = message.error_message || "Unknown error from backend";
372
+ wsError = wsErrorMessage;
373
+ isComplete = true;
374
+ if (timeoutId)
375
+ clearTimeout(timeoutId);
376
+ // Log full WebSocket error payload from backend for debugging
377
+ logger.logError("WebSocket error message received", new Error(wsErrorMessage), {
378
+ status_code: String(wsStatusCode),
379
+ user_id: userId,
380
+ raw_message: JSON.stringify(message),
381
+ });
382
+ resolve();
383
+ return;
384
+ }
385
+ if (message.content) {
386
+ const isCommitReview = message.content.analysis_type === "commit_review";
387
+ if (isCommitReview) {
388
+ // Validate analysis data before storing
389
+ const file_name = message.content.file_name?.replace(/\\/g, "/") || "";
390
+ const analysis = message.content.analysis;
391
+ if (file_name && analysis !== undefined && analysis !== null) {
392
+ // Store commit review analysis
393
+ analysisResults.push({
394
+ analysis: analysis,
395
+ language: message.content.language,
396
+ file_name: file_name,
397
+ analysisId: message.analysis_id ?? 0,
398
+ });
399
+ logger.logInfo("Analysis result received for file", {
400
+ user_id: userId,
401
+ file_name: file_name,
402
+ result_count: String(analysisResults.length),
403
+ });
404
+ }
405
+ else {
406
+ logger.logWarning("Received invalid analysis result (missing file_name or analysis)", {
407
+ user_id: userId,
408
+ has_file_name: String(!!file_name),
409
+ has_analysis: String(analysis !== undefined && analysis !== null),
410
+ });
411
+ }
412
+ // Check if analysis is complete
413
+ if (message.content.is_complete || message.content.status === "complete") {
414
+ isComplete = true;
415
+ if (timeoutId)
416
+ clearTimeout(timeoutId);
417
+ logger.logInfo("Analysis marked as complete", {
418
+ user_id: userId,
419
+ total_results: String(analysisResults.length),
420
+ });
421
+ resolve();
422
+ }
423
+ }
424
+ else {
425
+ // Non-commit-review message, log for debugging
426
+ logger.logInfo("Received non-commit-review WebSocket message", {
427
+ user_id: userId,
428
+ analysis_type: message.content.analysis_type || "unknown",
429
+ });
430
+ }
431
+ }
432
+ else {
433
+ // Content is null - backend may be signaling completion
434
+ // Wait a bit to see if more messages come, but don't resolve immediately
435
+ // The WebSocket close handler will handle this case
436
+ logger.logInfo("Received WebSocket message with null content", {
437
+ user_id: userId,
438
+ results_so_far: String(analysisResults.length),
439
+ });
440
+ }
441
+ }, (error) => {
442
+ // WebSocket connection error
443
+ if (timeoutId)
444
+ clearTimeout(timeoutId);
445
+ wsError = error.message;
446
+ logger.logError("WebSocket connection error", error, { user_id: userId });
447
+ reject(error);
448
+ }, (code, reason) => {
449
+ // WebSocket closed
450
+ if (timeoutId)
451
+ clearTimeout(timeoutId);
452
+ if (code !== 1000 && !isComplete) {
453
+ wsError = `Connection closed unexpectedly: ${reason}`;
454
+ logger.logWarning("WebSocket closed unexpectedly", {
455
+ code: String(code),
456
+ reason: reason.toString(),
457
+ user_id: userId,
458
+ isComplete: String(isComplete),
459
+ results_received: String(analysisResults.length),
460
+ });
461
+ }
462
+ else if (code === 1000 && !isComplete) {
463
+ // Normal closure but no completion signal received
464
+ // This can happen when backend completes but doesn't send explicit completion
465
+ logger.logInfo("WebSocket closed normally, treating as completion", {
466
+ user_id: userId,
467
+ results_received: String(analysisResults.length),
468
+ });
469
+ isComplete = true;
470
+ }
471
+ resolve();
472
+ }).then((ws) => {
473
+ wsConnection = ws;
474
+ if (onConnection) {
475
+ onConnection(ws);
476
+ }
477
+ }).catch(reject);
478
+ }),
479
+ timeoutPromise
480
+ ]);
481
+ }
482
+ catch (error) {
483
+ if (timeoutId)
484
+ clearTimeout(timeoutId);
485
+ throw error;
486
+ }
487
+ if (wsError) {
488
+ // Create error with status code and message for proper error extraction
489
+ const error = new Error(wsError);
490
+ if (wsStatusCode !== undefined) {
491
+ error.statusCode = wsStatusCode;
492
+ }
493
+ if (wsErrorMessage) {
494
+ error.errorDetail = wsErrorMessage;
495
+ }
496
+ throw error;
497
+ }
498
+ logger.logInfo("WebSocket collection completed", {
499
+ user_id: userId,
500
+ results_count: String(analysisResults.length),
501
+ isComplete: String(isComplete),
502
+ });
503
+ return analysisResults;
504
+ }
505
+ }
506
+ //# sourceMappingURL=commitReviewService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"commitReviewService.js","sourceRoot":"","sources":["../../src/services/commitReviewService.ts"],"names":[],"mappings":"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"}