@codesherlock/codesherlock-alpha-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.
- package/.env +9 -0
- package/README.md +185 -0
- package/build/handlers/analyzeCommitHandler.d.ts +55 -0
- package/build/handlers/analyzeCommitHandler.d.ts.map +1 -0
- package/build/handlers/analyzeCommitHandler.js +345 -0
- package/build/handlers/analyzeCommitHandler.js.map +1 -0
- package/build/handlers/events.d.ts +7 -0
- package/build/handlers/events.d.ts.map +1 -0
- package/build/handlers/events.js +15 -0
- package/build/handlers/events.js.map +1 -0
- package/build/handlers/resources.d.ts +10 -0
- package/build/handlers/resources.d.ts.map +1 -0
- package/build/handlers/resources.js +14 -0
- package/build/handlers/resources.js.map +1 -0
- package/build/handlers/tools.d.ts +6 -0
- package/build/handlers/tools.d.ts.map +1 -0
- package/build/handlers/tools.js +24 -0
- package/build/handlers/tools.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +82 -0
- package/build/index.js.map +1 -0
- package/build/schemas/toolSchemas.d.ts +40 -0
- package/build/schemas/toolSchemas.d.ts.map +1 -0
- package/build/schemas/toolSchemas.js +42 -0
- package/build/schemas/toolSchemas.js.map +1 -0
- package/build/services/backendApiService.d.ts +81 -0
- package/build/services/backendApiService.d.ts.map +1 -0
- package/build/services/backendApiService.js +211 -0
- package/build/services/backendApiService.js.map +1 -0
- package/build/services/commitReviewService.d.ts +61 -0
- package/build/services/commitReviewService.d.ts.map +1 -0
- package/build/services/commitReviewService.js +306 -0
- package/build/services/commitReviewService.js.map +1 -0
- package/build/services/gitService.d.ts +120 -0
- package/build/services/gitService.d.ts.map +1 -0
- package/build/services/gitService.js +360 -0
- package/build/services/gitService.js.map +1 -0
- package/build/services/loggingService.d.ts +64 -0
- package/build/services/loggingService.d.ts.map +1 -0
- package/build/services/loggingService.js +185 -0
- package/build/services/loggingService.js.map +1 -0
- package/build/services/zipService.d.ts +9 -0
- package/build/services/zipService.d.ts.map +1 -0
- package/build/services/zipService.js +47 -0
- package/build/services/zipService.js.map +1 -0
- package/build/tests/backendApiService.test.d.ts +2 -0
- package/build/tests/backendApiService.test.d.ts.map +1 -0
- package/build/tests/backendApiService.test.js +109 -0
- package/build/tests/backendApiService.test.js.map +1 -0
- package/build/tests/commitReviewService.test.d.ts +2 -0
- package/build/tests/commitReviewService.test.d.ts.map +1 -0
- package/build/tests/commitReviewService.test.js +118 -0
- package/build/tests/commitReviewService.test.js.map +1 -0
- package/build/tests/loggingService.test.d.ts +2 -0
- package/build/tests/loggingService.test.d.ts.map +1 -0
- package/build/tests/loggingService.test.js +156 -0
- package/build/tests/loggingService.test.js.map +1 -0
- package/build/tests/setup.test.d.ts +2 -0
- package/build/tests/setup.test.d.ts.map +1 -0
- package/build/tests/setup.test.js +7 -0
- package/build/tests/setup.test.js.map +1 -0
- package/build/utils/analysisFormatter.d.ts +40 -0
- package/build/utils/analysisFormatter.d.ts.map +1 -0
- package/build/utils/analysisFormatter.js +97 -0
- package/build/utils/analysisFormatter.js.map +1 -0
- package/build/utils/errorExtractor.d.ts +36 -0
- package/build/utils/errorExtractor.d.ts.map +1 -0
- package/build/utils/errorExtractor.js +178 -0
- package/build/utils/errorExtractor.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { logger } from "./loggingService.js";
|
|
2
|
+
/**
|
|
3
|
+
* Commit Review Service
|
|
4
|
+
* Handles the full flow of submitting commit review and receiving results via WebSocket
|
|
5
|
+
*/
|
|
6
|
+
export class CommitReviewService {
|
|
7
|
+
backendApiService;
|
|
8
|
+
constructor(backendApiService) {
|
|
9
|
+
this.backendApiService = backendApiService;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Submit commit review and wait for analysis results via WebSocket
|
|
13
|
+
* @param params - Commit review parameters
|
|
14
|
+
* @returns Analysis results
|
|
15
|
+
*/
|
|
16
|
+
async submitAndWaitForResults(params) {
|
|
17
|
+
let wsConnection;
|
|
18
|
+
try {
|
|
19
|
+
// IMPORTANT: Establish WebSocket connection (and listeners) BEFORE
|
|
20
|
+
// calling the backend HTTP API so we don't miss any early messages.
|
|
21
|
+
logger.logInfo("Establishing WebSocket connection before submitting review", {
|
|
22
|
+
user_id: params.user_id,
|
|
23
|
+
});
|
|
24
|
+
const analysisResultsPromise = this.collectResultsViaWebSocket(params.user_id, (ws) => {
|
|
25
|
+
wsConnection = ws;
|
|
26
|
+
});
|
|
27
|
+
// Step 1: Submit commit review via HTTP POST
|
|
28
|
+
logger.logInfo("Submitting commit review to backend", {
|
|
29
|
+
user_id: params.user_id,
|
|
30
|
+
factor: params.factor,
|
|
31
|
+
fileCount: String(params.file_changes.length),
|
|
32
|
+
});
|
|
33
|
+
const submitResponse = await this.backendApiService.submitCommitReview({
|
|
34
|
+
factor: params.factor,
|
|
35
|
+
user_id: params.user_id,
|
|
36
|
+
repo_name: params.repo_name,
|
|
37
|
+
commit_id: params.commit_id,
|
|
38
|
+
username: params.username,
|
|
39
|
+
files_json: JSON.stringify(params.file_changes),
|
|
40
|
+
organization_name: params.organization_name,
|
|
41
|
+
});
|
|
42
|
+
logger.logInfo("Commit review submitted", {
|
|
43
|
+
analysisId: submitResponse.analysisId || "none",
|
|
44
|
+
});
|
|
45
|
+
// Step 2: Wait for WebSocket‑delivered analysis results
|
|
46
|
+
const analysisResults = await analysisResultsPromise;
|
|
47
|
+
// Handle edge case: WebSocket completed but no results received
|
|
48
|
+
// This can happen when:
|
|
49
|
+
// 1. No relevant code files were found (all files are deleted or non-code files)
|
|
50
|
+
// 2. All file processing failed silently
|
|
51
|
+
// 3. Backend pipeline completed but didn't send any analysis results
|
|
52
|
+
if (!analysisResults || analysisResults.length === 0) {
|
|
53
|
+
logger.logWarning("WebSocket completed but no analysis results received", {
|
|
54
|
+
user_id: params.user_id,
|
|
55
|
+
commit_id: params.commit_id,
|
|
56
|
+
fileCount: String(params.file_changes.length),
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
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.",
|
|
61
|
+
analysisId: submitResponse.analysisId,
|
|
62
|
+
results: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Filter out any invalid results (files with no analysis data)
|
|
66
|
+
const validResults = analysisResults.filter(result => result &&
|
|
67
|
+
result.file_name &&
|
|
68
|
+
(result.analysis !== undefined && result.analysis !== null));
|
|
69
|
+
if (validResults.length === 0) {
|
|
70
|
+
logger.logWarning("All analysis results were invalid or empty", {
|
|
71
|
+
user_id: params.user_id,
|
|
72
|
+
commit_id: params.commit_id,
|
|
73
|
+
totalResults: String(analysisResults.length),
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
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.",
|
|
78
|
+
analysisId: submitResponse.analysisId,
|
|
79
|
+
results: analysisResults,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
logger.logInfo("Analysis results received successfully", {
|
|
83
|
+
user_id: params.user_id,
|
|
84
|
+
commit_id: params.commit_id,
|
|
85
|
+
resultCount: String(validResults.length),
|
|
86
|
+
totalResults: String(analysisResults.length),
|
|
87
|
+
});
|
|
88
|
+
return {
|
|
89
|
+
success: true,
|
|
90
|
+
analysisId: submitResponse.analysisId,
|
|
91
|
+
message: submitResponse.message,
|
|
92
|
+
results: validResults,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
logger.logError("Error in commit review flow", error);
|
|
97
|
+
// If we get a 401 (Unauthorized) from the backend, close the WebSocket connection
|
|
98
|
+
// because the backend won't be sending any analysis results.
|
|
99
|
+
if (error instanceof Error && error.message.includes("status: 401")) {
|
|
100
|
+
if (wsConnection) {
|
|
101
|
+
logger.logInfo("Closing WebSocket connection due to 401 Unauthorized error");
|
|
102
|
+
wsConnection.close();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error: error instanceof Error ? error.message : String(error),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Connect to WebSocket and collect analysis results
|
|
113
|
+
* Handles edge cases:
|
|
114
|
+
* - Timeout scenarios (backend takes too long)
|
|
115
|
+
* - Empty results (no files to analyze)
|
|
116
|
+
* - Partial results (some files succeed, others fail)
|
|
117
|
+
* - WebSocket completion without explicit completion signal
|
|
118
|
+
* @param userId - User ID for WebSocket connection
|
|
119
|
+
* @param timeoutMs - Maximum time to wait for results (default: 10 minutes)
|
|
120
|
+
* @returns Array of analysis results
|
|
121
|
+
*/
|
|
122
|
+
async collectResultsViaWebSocket(userId, onConnection, timeoutMs = 10 * 60 * 1000 // 10 minutes default timeout
|
|
123
|
+
) {
|
|
124
|
+
const analysisResults = [];
|
|
125
|
+
let wsError = null;
|
|
126
|
+
let wsStatusCode;
|
|
127
|
+
let wsErrorMessage;
|
|
128
|
+
let isComplete = false;
|
|
129
|
+
let timeoutId;
|
|
130
|
+
let wsConnection;
|
|
131
|
+
// Set up timeout to prevent indefinite waiting
|
|
132
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
133
|
+
timeoutId = setTimeout(() => {
|
|
134
|
+
if (!isComplete) {
|
|
135
|
+
wsError = "Analysis timeout: The analysis took too long to complete. Please try again with fewer files or contact support if the issue persists.";
|
|
136
|
+
logger.logError("WebSocket timeout", new Error(wsError), {
|
|
137
|
+
user_id: userId,
|
|
138
|
+
timeoutMs: String(timeoutMs),
|
|
139
|
+
});
|
|
140
|
+
if (wsConnection) {
|
|
141
|
+
wsConnection.close();
|
|
142
|
+
}
|
|
143
|
+
reject(new Error(wsError));
|
|
144
|
+
}
|
|
145
|
+
}, timeoutMs);
|
|
146
|
+
});
|
|
147
|
+
try {
|
|
148
|
+
await Promise.race([
|
|
149
|
+
new Promise((resolve, reject) => {
|
|
150
|
+
this.backendApiService.connectWebSocket(userId, (message) => {
|
|
151
|
+
// Clear timeout on first message (analysis has started)
|
|
152
|
+
if (timeoutId) {
|
|
153
|
+
clearTimeout(timeoutId);
|
|
154
|
+
// Reset timeout to allow more time for completion
|
|
155
|
+
timeoutId = setTimeout(() => {
|
|
156
|
+
if (!isComplete) {
|
|
157
|
+
wsError = "Analysis timeout: The analysis is taking longer than expected. Please try again or contact support.";
|
|
158
|
+
logger.logError("WebSocket timeout after receiving initial results", new Error(wsError), {
|
|
159
|
+
user_id: userId,
|
|
160
|
+
resultsReceived: String(analysisResults.length),
|
|
161
|
+
});
|
|
162
|
+
if (wsConnection) {
|
|
163
|
+
wsConnection.close();
|
|
164
|
+
}
|
|
165
|
+
reject(new Error(wsError));
|
|
166
|
+
}
|
|
167
|
+
}, timeoutMs);
|
|
168
|
+
}
|
|
169
|
+
// Handle WebSocket error messages from backend
|
|
170
|
+
// Backend sends errors via WebSocket with status_code and error_message
|
|
171
|
+
if (message.status_code !== 200 && message.status_code !== undefined) {
|
|
172
|
+
wsStatusCode = message.status_code;
|
|
173
|
+
wsErrorMessage = message.error_message || "Unknown error from backend";
|
|
174
|
+
wsError = wsErrorMessage;
|
|
175
|
+
isComplete = true;
|
|
176
|
+
if (timeoutId)
|
|
177
|
+
clearTimeout(timeoutId);
|
|
178
|
+
logger.logError("WebSocket error message received", new Error(wsErrorMessage), {
|
|
179
|
+
status_code: String(wsStatusCode),
|
|
180
|
+
user_id: userId,
|
|
181
|
+
});
|
|
182
|
+
resolve();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
if (message.content) {
|
|
186
|
+
const isCommitReview = message.content.analysis_type === "commit_review";
|
|
187
|
+
if (isCommitReview) {
|
|
188
|
+
// Validate analysis data before storing
|
|
189
|
+
const file_name = message.content.file_name?.replace(/\\/g, "/") || "";
|
|
190
|
+
const analysis = message.content.analysis;
|
|
191
|
+
if (file_name && analysis !== undefined && analysis !== null) {
|
|
192
|
+
// Store commit review analysis
|
|
193
|
+
analysisResults.push({
|
|
194
|
+
analysis: analysis,
|
|
195
|
+
language: message.content.language,
|
|
196
|
+
file_name: file_name,
|
|
197
|
+
analysisId: message.analysis_id ?? 0,
|
|
198
|
+
});
|
|
199
|
+
logger.logInfo("Analysis result received for file", {
|
|
200
|
+
user_id: userId,
|
|
201
|
+
file_name: file_name,
|
|
202
|
+
result_count: String(analysisResults.length),
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
logger.logWarning("Received invalid analysis result (missing file_name or analysis)", {
|
|
207
|
+
user_id: userId,
|
|
208
|
+
has_file_name: String(!!file_name),
|
|
209
|
+
has_analysis: String(analysis !== undefined && analysis !== null),
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// Check if analysis is complete
|
|
213
|
+
if (message.content.is_complete || message.content.status === "complete") {
|
|
214
|
+
isComplete = true;
|
|
215
|
+
if (timeoutId)
|
|
216
|
+
clearTimeout(timeoutId);
|
|
217
|
+
logger.logInfo("Analysis marked as complete", {
|
|
218
|
+
user_id: userId,
|
|
219
|
+
total_results: String(analysisResults.length),
|
|
220
|
+
});
|
|
221
|
+
resolve();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// Non-commit-review message, log for debugging
|
|
226
|
+
logger.logInfo("Received non-commit-review WebSocket message", {
|
|
227
|
+
user_id: userId,
|
|
228
|
+
analysis_type: message.content.analysis_type || "unknown",
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// Content is null - backend may be signaling completion
|
|
234
|
+
// Wait a bit to see if more messages come, but don't resolve immediately
|
|
235
|
+
// The WebSocket close handler will handle this case
|
|
236
|
+
logger.logInfo("Received WebSocket message with null content", {
|
|
237
|
+
user_id: userId,
|
|
238
|
+
results_so_far: String(analysisResults.length),
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}, (error) => {
|
|
242
|
+
// WebSocket connection error
|
|
243
|
+
if (timeoutId)
|
|
244
|
+
clearTimeout(timeoutId);
|
|
245
|
+
wsError = error.message;
|
|
246
|
+
logger.logError("WebSocket connection error", error, { user_id: userId });
|
|
247
|
+
reject(error);
|
|
248
|
+
}, (code, reason) => {
|
|
249
|
+
// WebSocket closed
|
|
250
|
+
if (timeoutId)
|
|
251
|
+
clearTimeout(timeoutId);
|
|
252
|
+
if (code !== 1000 && !isComplete) {
|
|
253
|
+
wsError = `Connection closed unexpectedly: ${reason}`;
|
|
254
|
+
logger.logWarning("WebSocket closed unexpectedly", {
|
|
255
|
+
code: String(code),
|
|
256
|
+
reason: reason.toString(),
|
|
257
|
+
user_id: userId,
|
|
258
|
+
isComplete: String(isComplete),
|
|
259
|
+
results_received: String(analysisResults.length),
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
else if (code === 1000 && !isComplete) {
|
|
263
|
+
// Normal closure but no completion signal received
|
|
264
|
+
// This can happen when backend completes but doesn't send explicit completion
|
|
265
|
+
logger.logInfo("WebSocket closed normally, treating as completion", {
|
|
266
|
+
user_id: userId,
|
|
267
|
+
results_received: String(analysisResults.length),
|
|
268
|
+
});
|
|
269
|
+
isComplete = true;
|
|
270
|
+
}
|
|
271
|
+
resolve();
|
|
272
|
+
}).then((ws) => {
|
|
273
|
+
wsConnection = ws;
|
|
274
|
+
if (onConnection) {
|
|
275
|
+
onConnection(ws);
|
|
276
|
+
}
|
|
277
|
+
}).catch(reject);
|
|
278
|
+
}),
|
|
279
|
+
timeoutPromise
|
|
280
|
+
]);
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
if (timeoutId)
|
|
284
|
+
clearTimeout(timeoutId);
|
|
285
|
+
throw error;
|
|
286
|
+
}
|
|
287
|
+
if (wsError) {
|
|
288
|
+
// Create error with status code and message for proper error extraction
|
|
289
|
+
const error = new Error(wsError);
|
|
290
|
+
if (wsStatusCode !== undefined) {
|
|
291
|
+
error.statusCode = wsStatusCode;
|
|
292
|
+
}
|
|
293
|
+
if (wsErrorMessage) {
|
|
294
|
+
error.errorDetail = wsErrorMessage;
|
|
295
|
+
}
|
|
296
|
+
throw error;
|
|
297
|
+
}
|
|
298
|
+
logger.logInfo("WebSocket collection completed", {
|
|
299
|
+
user_id: userId,
|
|
300
|
+
results_count: String(analysisResults.length),
|
|
301
|
+
isComplete: String(isComplete),
|
|
302
|
+
});
|
|
303
|
+
return analysisResults;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
//# 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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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git Service
|
|
3
|
+
* Handles all Git-related operations like getting diffs, file content, etc.
|
|
4
|
+
*/
|
|
5
|
+
export declare class GitService {
|
|
6
|
+
private getGitInstance;
|
|
7
|
+
/**
|
|
8
|
+
* Get diff for a specific commit or PR
|
|
9
|
+
* @param repoPath - Path to the git repository
|
|
10
|
+
* @param commitHash - Commit hash or PR reference
|
|
11
|
+
* @returns Git diff content
|
|
12
|
+
*/
|
|
13
|
+
getDiff(repoPath: string, commitHash: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Get diff for uncommitted changes
|
|
16
|
+
* @param repoPath - Path to the git repository
|
|
17
|
+
* @returns Git diff content for uncommitted changes
|
|
18
|
+
*/
|
|
19
|
+
getUncommittedDiff(repoPath: string): Promise<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Get file content from repository
|
|
22
|
+
* @param repoPath - Path to the git repository
|
|
23
|
+
* @param filePath - Path to the file within the repo
|
|
24
|
+
* @param ref - Git reference (branch, tag, commit hash)
|
|
25
|
+
* @returns File content as string
|
|
26
|
+
*/
|
|
27
|
+
getFileContent(repoPath: string, filePath: string, ref?: string): Promise<string>;
|
|
28
|
+
/**
|
|
29
|
+
* Get list of changed files in a commit or PR
|
|
30
|
+
* @param repoPath - Path to the git repository
|
|
31
|
+
* @param commitHash - Commit hash or PR reference
|
|
32
|
+
* @returns Array of changed file paths
|
|
33
|
+
*/
|
|
34
|
+
getChangedFiles(repoPath: string, commitHash: string): Promise<string[]>;
|
|
35
|
+
/**
|
|
36
|
+
* Get commit information
|
|
37
|
+
* @param repoPath - Path to the git repository
|
|
38
|
+
* @param commitHash - Commit hash
|
|
39
|
+
* @returns Commit metadata
|
|
40
|
+
*/
|
|
41
|
+
getCommitInfo(repoPath: string, commitHash: string): Promise<CommitInfo>;
|
|
42
|
+
/**
|
|
43
|
+
* Get repository status
|
|
44
|
+
* @param repoPath - Path to the git repository
|
|
45
|
+
* @returns Repository status information
|
|
46
|
+
*/
|
|
47
|
+
getRepoStatus(repoPath: string): Promise<RepoStatus>;
|
|
48
|
+
/**
|
|
49
|
+
* Get the hash of the current HEAD commit.
|
|
50
|
+
* Falls back to a placeholder when repository has no commits.
|
|
51
|
+
*/
|
|
52
|
+
getCurrentCommitHash(repoPath: string): Promise<string>;
|
|
53
|
+
/**
|
|
54
|
+
* Get diff for a specific file
|
|
55
|
+
* @param repoPath - Path to the git repository
|
|
56
|
+
* @param filePath - Path to the file
|
|
57
|
+
* @param commitHash - Commit hash (optional, if null/empty uses HEAD)
|
|
58
|
+
* @returns Diff content
|
|
59
|
+
*/
|
|
60
|
+
getFileDiff(repoPath: string, filePath: string, commitHash?: string): Promise<string>;
|
|
61
|
+
/**
|
|
62
|
+
* Get changed files with status
|
|
63
|
+
* @param repoPath - Path to the git repository
|
|
64
|
+
* @param commitHash - Commit hash (optional)
|
|
65
|
+
* @returns Array of objects with path and status
|
|
66
|
+
*/
|
|
67
|
+
getChangedFilesWithStatus(repoPath: string, commitHash?: string): Promise<Array<{
|
|
68
|
+
path: string;
|
|
69
|
+
status: string;
|
|
70
|
+
}>>;
|
|
71
|
+
/**
|
|
72
|
+
* Analyze git changes for a commit or uncommitted changes
|
|
73
|
+
* @param uncommitted - If true, analyze uncommitted changes. If false, analyze HEAD.
|
|
74
|
+
* @param directory - Path to git repository
|
|
75
|
+
*/
|
|
76
|
+
analyzeGitChanges(uncommitted: boolean, directory: string): Promise<Array<{
|
|
77
|
+
filename: string;
|
|
78
|
+
status: string;
|
|
79
|
+
new_content: string;
|
|
80
|
+
patch: string;
|
|
81
|
+
}>>;
|
|
82
|
+
/**
|
|
83
|
+
* Get file changes for a commit or uncommitted changes
|
|
84
|
+
* @param uncommitted - true for unstaged changes, false for specific commit
|
|
85
|
+
* @param commitHash - Git commit hash (required when uncommitted=false)
|
|
86
|
+
* @param directory - Path to the Git repository root
|
|
87
|
+
* @returns Array of file changes with filename, status, new_content, and patch
|
|
88
|
+
*/
|
|
89
|
+
getFileChanges(uncommitted: boolean, commitHash: string | undefined, directory: string): Promise<FileChange[]>;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Commit information interface
|
|
93
|
+
*/
|
|
94
|
+
export interface CommitInfo {
|
|
95
|
+
hash: string;
|
|
96
|
+
author: string;
|
|
97
|
+
email: string;
|
|
98
|
+
date: string;
|
|
99
|
+
message: string;
|
|
100
|
+
files: string[];
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Repository status interface
|
|
104
|
+
*/
|
|
105
|
+
export interface RepoStatus {
|
|
106
|
+
branch: string;
|
|
107
|
+
modified: string[];
|
|
108
|
+
staged: string[];
|
|
109
|
+
untracked: string[];
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* File change interface
|
|
113
|
+
*/
|
|
114
|
+
export interface FileChange {
|
|
115
|
+
filename: string;
|
|
116
|
+
status: string;
|
|
117
|
+
new_content: string;
|
|
118
|
+
patch: string;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=gitService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitService.d.ts","sourceRoot":"","sources":["../../src/services/gitService.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,cAAc;IAItB;;;;;OAKG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBpE;;;;OAIG;IACG,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK3D;;;;;;OAMG;IACG,cAAc,CAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC;IAmBlB;;;;;OAKG;IACG,eAAe,CACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,EAAE,CAAC;IAwBpB;;;;;OAKG;IACG,aAAa,CACf,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC;IA6BtB;;;;OAIG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAiB1D;;;OAGG;IACG,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAe7D;;;;;;OAMG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuB3F;;;;;OAKG;IACG,yBAAyB,CAC3B,QAAQ,EAAE,MAAM,EAChB,UAAU,CAAC,EAAE,MAAM,GACpB,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IA2CnD;;;;OAIG;IACG,iBAAiB,CACnB,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,KAAK,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;KACjB,CAAC,CAAC;IAyCH;;;;;;OAMG;IACG,cAAc,CAChB,WAAW,EAAE,OAAO,EACpB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,SAAS,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,EAAE,CAAC;CAiE3B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACjB"}
|