gitlab-auto-reviewers 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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1878 -0
  3. package/dist/api/gitlab-api.d.ts +136 -0
  4. package/dist/api/gitlab-api.d.ts.map +1 -0
  5. package/dist/api/gitlab-api.js +334 -0
  6. package/dist/api/gitlab-api.js.map +1 -0
  7. package/dist/bin/cli.d.ts +10 -0
  8. package/dist/bin/cli.d.ts.map +1 -0
  9. package/dist/bin/cli.js +186 -0
  10. package/dist/bin/cli.js.map +1 -0
  11. package/dist/bin/deprecated-mcp.d.ts +12 -0
  12. package/dist/bin/deprecated-mcp.d.ts.map +1 -0
  13. package/dist/bin/deprecated-mcp.js +73 -0
  14. package/dist/bin/deprecated-mcp.js.map +1 -0
  15. package/dist/bin/index.d.ts +18 -0
  16. package/dist/bin/index.d.ts.map +1 -0
  17. package/dist/bin/index.js +78 -0
  18. package/dist/bin/index.js.map +1 -0
  19. package/dist/bin/mcp.d.ts +11 -0
  20. package/dist/bin/mcp.d.ts.map +1 -0
  21. package/dist/bin/mcp.js +43 -0
  22. package/dist/bin/mcp.js.map +1 -0
  23. package/dist/cache/cache.service.d.ts +113 -0
  24. package/dist/cache/cache.service.d.ts.map +1 -0
  25. package/dist/cache/cache.service.js +213 -0
  26. package/dist/cache/cache.service.js.map +1 -0
  27. package/dist/cli/commands.d.ts +40 -0
  28. package/dist/cli/commands.d.ts.map +1 -0
  29. package/dist/cli/commands.js +142 -0
  30. package/dist/cli/commands.js.map +1 -0
  31. package/dist/cli/output.d.ts +24 -0
  32. package/dist/cli/output.d.ts.map +1 -0
  33. package/dist/cli/output.js +143 -0
  34. package/dist/cli/output.js.map +1 -0
  35. package/dist/config/config.service.d.ts +89 -0
  36. package/dist/config/config.service.d.ts.map +1 -0
  37. package/dist/config/config.service.js +169 -0
  38. package/dist/config/config.service.js.map +1 -0
  39. package/dist/datasources/git-data-source.interface.d.ts +140 -0
  40. package/dist/datasources/git-data-source.interface.d.ts.map +1 -0
  41. package/dist/datasources/git-data-source.interface.js +2 -0
  42. package/dist/datasources/git-data-source.interface.js.map +1 -0
  43. package/dist/datasources/gitlab-api-data-source.d.ts +127 -0
  44. package/dist/datasources/gitlab-api-data-source.d.ts.map +1 -0
  45. package/dist/datasources/gitlab-api-data-source.js +248 -0
  46. package/dist/datasources/gitlab-api-data-source.js.map +1 -0
  47. package/dist/datasources/local-git-data-source.d.ts +124 -0
  48. package/dist/datasources/local-git-data-source.d.ts.map +1 -0
  49. package/dist/datasources/local-git-data-source.js +580 -0
  50. package/dist/datasources/local-git-data-source.js.map +1 -0
  51. package/dist/errors/error-handler.d.ts +113 -0
  52. package/dist/errors/error-handler.d.ts.map +1 -0
  53. package/dist/errors/error-handler.js +230 -0
  54. package/dist/errors/error-handler.js.map +1 -0
  55. package/dist/index.d.ts +139 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +139 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/logging/example.d.ts +15 -0
  60. package/dist/logging/example.d.ts.map +1 -0
  61. package/dist/logging/example.js +79 -0
  62. package/dist/logging/example.js.map +1 -0
  63. package/dist/logging/index.d.ts +7 -0
  64. package/dist/logging/index.d.ts.map +1 -0
  65. package/dist/logging/index.js +7 -0
  66. package/dist/logging/index.js.map +1 -0
  67. package/dist/logging/logger.service.d.ts +98 -0
  68. package/dist/logging/logger.service.d.ts.map +1 -0
  69. package/dist/logging/logger.service.js +160 -0
  70. package/dist/logging/logger.service.js.map +1 -0
  71. package/dist/mcp/server.d.ts +67 -0
  72. package/dist/mcp/server.d.ts.map +1 -0
  73. package/dist/mcp/server.js +213 -0
  74. package/dist/mcp/server.js.map +1 -0
  75. package/dist/mcp/tools.d.ts +22 -0
  76. package/dist/mcp/tools.d.ts.map +1 -0
  77. package/dist/mcp/tools.js +176 -0
  78. package/dist/mcp/tools.js.map +1 -0
  79. package/dist/services/blacklist.service.d.ts +32 -0
  80. package/dist/services/blacklist.service.d.ts.map +1 -0
  81. package/dist/services/blacklist.service.js +59 -0
  82. package/dist/services/blacklist.service.js.map +1 -0
  83. package/dist/services/codeowners.service.d.ts +45 -0
  84. package/dist/services/codeowners.service.d.ts.map +1 -0
  85. package/dist/services/codeowners.service.js +200 -0
  86. package/dist/services/codeowners.service.js.map +1 -0
  87. package/dist/services/comment-builder.service.d.ts +48 -0
  88. package/dist/services/comment-builder.service.d.ts.map +1 -0
  89. package/dist/services/comment-builder.service.js +61 -0
  90. package/dist/services/comment-builder.service.js.map +1 -0
  91. package/dist/services/contributors.service.d.ts +52 -0
  92. package/dist/services/contributors.service.d.ts.map +1 -0
  93. package/dist/services/contributors.service.js +144 -0
  94. package/dist/services/contributors.service.js.map +1 -0
  95. package/dist/services/reviewer-service.d.ts +125 -0
  96. package/dist/services/reviewer-service.d.ts.map +1 -0
  97. package/dist/services/reviewer-service.js +554 -0
  98. package/dist/services/reviewer-service.js.map +1 -0
  99. package/dist/services/team-members.service.d.ts +29 -0
  100. package/dist/services/team-members.service.d.ts.map +1 -0
  101. package/dist/services/team-members.service.js +45 -0
  102. package/dist/services/team-members.service.js.map +1 -0
  103. package/dist/services/whitelist.service.d.ts +31 -0
  104. package/dist/services/whitelist.service.d.ts.map +1 -0
  105. package/dist/services/whitelist.service.js +51 -0
  106. package/dist/services/whitelist.service.js.map +1 -0
  107. package/dist/tools.d.ts +22 -0
  108. package/dist/tools.d.ts.map +1 -0
  109. package/dist/tools.js +176 -0
  110. package/dist/tools.js.map +1 -0
  111. package/dist/types/index.d.ts +502 -0
  112. package/dist/types/index.d.ts.map +1 -0
  113. package/dist/types/index.js +91 -0
  114. package/dist/types/index.js.map +1 -0
  115. package/dist/types.d.ts +219 -0
  116. package/dist/types.d.ts.map +1 -0
  117. package/dist/types.js +7 -0
  118. package/dist/types.js.map +1 -0
  119. package/package.json +71 -0
@@ -0,0 +1,580 @@
1
+ import { readFileSync } from "fs";
2
+ import { join } from "path";
3
+ import simpleGit from "simple-git";
4
+ import { GitLabAPIDataSource } from "./gitlab-api-data-source.js";
5
+ import { Logger } from "../logging/logger.service.js";
6
+ import { ErrorHandler } from "../errors/error-handler.js";
7
+ import { ConfigService } from "../config/config.service.js";
8
+ /**
9
+ * Local git repository data source implementation
10
+ *
11
+ * Provides access to git data through local git operations using simple-git.
12
+ * Falls back to GitLab API for operations that fail locally.
13
+ * Extends GitLabAPIDataSource to inherit API-based methods.
14
+ */
15
+ export class LocalGitDataSource extends GitLabAPIDataSource {
16
+ repoPath;
17
+ config;
18
+ /**
19
+ * Create a new local git data source
20
+ *
21
+ * @param gitlabApi - GitLab API client instance for fallback operations
22
+ * @param repoPath - Path to the local git repository
23
+ * @param logger - Optional logger instance for logging operations
24
+ * @param config - Optional configuration service for settings
25
+ */
26
+ constructor(gitlabApi, repoPath, logger, config) {
27
+ super(gitlabApi, logger || new Logger('LocalGitDataSource'));
28
+ this.repoPath = repoPath;
29
+ this.config = config || new ConfigService();
30
+ }
31
+ /**
32
+ * Get the project path from the git remote URL
33
+ *
34
+ * Parses the origin remote URL to extract the project path.
35
+ * Supports SSH, HTTPS, and git protocol URLs.
36
+ *
37
+ * @returns Promise resolving to the project path (e.g., "group/project")
38
+ * @throws {MCPError} If no origin remote is found or URL format is unsupported
39
+ */
40
+ async getProjectFromRemote() {
41
+ const context = { repoPath: this.repoPath, dataSource: 'LocalGit' };
42
+ try {
43
+ const git = simpleGit(this.repoPath);
44
+ const remotes = await git.getRemotes(true);
45
+ const origin = remotes.find((r) => r.name === "origin");
46
+ if (!origin?.refs?.fetch) {
47
+ const remoteNames = remotes.map(r => r.name);
48
+ throw ErrorHandler.gitOperationError('No origin remote found in repository. Ensure the repository has an origin remote configured.', { ...context, remotes: remoteNames }, new Error('No origin remote'));
49
+ }
50
+ const url = origin.refs.fetch.replace(/\.git$/, "");
51
+ // ssh://user@host:port/path or ssh://user@host/path
52
+ const sshProtocol = /^ssh:\/\/(?:[^@]+@)?[^/]+(?::\d+)?\/(.*)/;
53
+ // https://host/path
54
+ const https = /^https?:\/\/[^/]+\/(.*)/;
55
+ // git://host/path
56
+ const gitProtocol = /^git:\/\/[^/]+\/(.*)/;
57
+ // user@host:path (SSH shorthand)
58
+ const sshShorthand = /^[^@]+@[^:]+:(.*)$/;
59
+ for (const pattern of [sshProtocol, https, gitProtocol, sshShorthand]) {
60
+ const match = url.match(pattern);
61
+ if (match) {
62
+ this.logger.debug('Parsed project from remote', {
63
+ project: match[1],
64
+ remoteUrl: url,
65
+ dataSource: 'LocalGit',
66
+ });
67
+ return match[1];
68
+ }
69
+ }
70
+ throw ErrorHandler.gitOperationError(`Cannot parse project path from remote URL. The URL format may not be supported.`, { ...context, remoteUrl: origin.refs.fetch }, new Error('Unsupported remote URL format'));
71
+ }
72
+ catch (error) {
73
+ if (error instanceof Error && error.message.includes('MCP')) {
74
+ throw error;
75
+ }
76
+ throw ErrorHandler.gitOperationError('Failed to get project from remote', context, error instanceof Error ? error : new Error(String(error)));
77
+ }
78
+ }
79
+ /**
80
+ * Get the current branch name from the local repository
81
+ *
82
+ * @returns Promise resolving to the current branch name
83
+ * @throws {MCPError} If repository is in detached HEAD state or branch cannot be determined
84
+ */
85
+ async getCurrentBranch() {
86
+ const context = { repoPath: this.repoPath, dataSource: 'LocalGit' };
87
+ try {
88
+ const git = simpleGit(this.repoPath);
89
+ const status = await git.status();
90
+ if (!status.current) {
91
+ const errorContext = { ...context, isDetached: status.detached };
92
+ throw ErrorHandler.gitOperationError('Repository is in detached HEAD state or branch cannot be determined', errorContext, new Error('No current branch'));
93
+ }
94
+ this.logger.debug('Current branch detected', {
95
+ branch: status.current,
96
+ repoPath: this.repoPath,
97
+ dataSource: 'LocalGit',
98
+ });
99
+ return status.current;
100
+ }
101
+ catch (error) {
102
+ if (error instanceof Error && error.message.includes('MCP')) {
103
+ throw error;
104
+ }
105
+ throw ErrorHandler.gitOperationError('Failed to get current branch', context, error instanceof Error ? error : new Error(String(error)));
106
+ }
107
+ }
108
+ /**
109
+ * Get the default branch from local git repository
110
+ *
111
+ * Queries the remote HEAD to determine the default branch.
112
+ * Falls back to GitLab API if local detection fails.
113
+ *
114
+ * @param project - The project ID or path
115
+ * @returns Promise resolving to the default branch name
116
+ * @throws {MCPError} If both local and API detection fail
117
+ */
118
+ async getDefaultBranch(project) {
119
+ const endTimer = this.logger.startTimer('getDefaultBranch');
120
+ const context = { project, repoPath: this.repoPath, dataSource: 'LocalGit' };
121
+ try {
122
+ this.logger.info('Getting default branch from local git', {
123
+ project,
124
+ repoPath: this.repoPath,
125
+ dataSource: 'LocalGit',
126
+ });
127
+ const git = simpleGit(this.repoPath);
128
+ // Wrap git operation with retry logic
129
+ const result = await ErrorHandler.withRetry(async () => {
130
+ return await git.raw(['symbolic-ref', 'refs/remotes/origin/HEAD']);
131
+ }, {
132
+ maxRetries: this.config.get().maxRetries,
133
+ delayMs: this.config.get().retryDelayMs,
134
+ });
135
+ // Parse: refs/remotes/origin/main → main
136
+ const branch = result.trim().replace('refs/remotes/origin/', '');
137
+ if (!branch) {
138
+ throw new Error('Empty branch name returned from git');
139
+ }
140
+ this.logger.info('Default branch detected from local git', {
141
+ branch,
142
+ project,
143
+ dataSource: 'LocalGit',
144
+ });
145
+ endTimer();
146
+ return branch;
147
+ }
148
+ catch (error) {
149
+ endTimer();
150
+ // Graceful fallback to API
151
+ this.logger.warn('Local git default branch detection failed, falling back to API', {
152
+ ...context,
153
+ error: error instanceof Error ? error.message : String(error),
154
+ });
155
+ try {
156
+ const branch = await super.getDefaultBranch(project);
157
+ this.logger.info('Default branch retrieved from API fallback', {
158
+ branch,
159
+ project,
160
+ dataSource: 'GitLabAPI (fallback)',
161
+ });
162
+ return branch;
163
+ }
164
+ catch (apiError) {
165
+ // If both local and API fail, throw error
166
+ this.logger.error('Both local and API default branch detection failed', apiError instanceof Error ? apiError : new Error(String(apiError)), context);
167
+ throw ErrorHandler.gitOperationError('Failed to get default branch from both local git and API', context, apiError instanceof Error ? apiError : new Error(String(apiError)));
168
+ }
169
+ }
170
+ }
171
+ /**
172
+ * Get project contributors from local git history
173
+ *
174
+ * Analyzes commit history using configurable date range to identify contributors.
175
+ * Uses retry logic for git operations.
176
+ *
177
+ * @param project - The project ID or path (used for logging)
178
+ * @param commitSha - The commit SHA to analyze history from
179
+ * @returns Promise resolving to array of contributor email addresses (up to 100)
180
+ */
181
+ async getProjectContributors(project, commitSha) {
182
+ const endTimer = this.logger.startTimer('getProjectContributors');
183
+ const context = { project, commitSha, repoPath: this.repoPath, dataSource: 'LocalGit' };
184
+ try {
185
+ this.logger.info('Getting contributors for commit', {
186
+ commitSha,
187
+ repoPath: this.repoPath,
188
+ dataSource: 'LocalGit',
189
+ });
190
+ // Use configurable date range from configuration (Requirement 6.5)
191
+ const contributorDays = this.config.get().contributorDays;
192
+ const sinceDate = new Date();
193
+ sinceDate.setDate(sinceDate.getDate() - contributorDays);
194
+ const sinceDateStr = sinceDate.toISOString().split("T")[0];
195
+ const git = simpleGit(this.repoPath);
196
+ // Wrap git operation with retry logic (Requirement 3.2)
197
+ const output = await ErrorHandler.withRetry(async () => {
198
+ return await git.raw([
199
+ "log",
200
+ commitSha,
201
+ "--format=%ae",
202
+ `--since=${sinceDateStr}`,
203
+ "--no-merges",
204
+ ]);
205
+ }, {
206
+ maxRetries: this.config.get().maxRetries,
207
+ delayMs: this.config.get().retryDelayMs,
208
+ });
209
+ const commits = output
210
+ .trim()
211
+ .split("\n")
212
+ .filter((e) => e);
213
+ this.logger.debug('Contributor analysis complete', {
214
+ dateRange: sinceDateStr,
215
+ totalCommits: commits.length,
216
+ dataSource: 'LocalGit',
217
+ });
218
+ const contributorCounts = {};
219
+ commits
220
+ .filter((email) => email)
221
+ .forEach((email) => {
222
+ const normalizedEmail = email.toLowerCase();
223
+ contributorCounts[normalizedEmail] =
224
+ (contributorCounts[normalizedEmail] || 0) + 1;
225
+ });
226
+ const result = Object.entries(contributorCounts)
227
+ .sort(([, a], [, b]) => b - a)
228
+ .slice(0, 100)
229
+ .map(([email]) => email);
230
+ this.logger.info('Contributors retrieved', {
231
+ count: result.length,
232
+ dateRange: sinceDateStr,
233
+ dataSource: 'LocalGit',
234
+ });
235
+ endTimer();
236
+ return result;
237
+ }
238
+ catch (error) {
239
+ endTimer();
240
+ throw ErrorHandler.gitOperationError('Failed to get project contributors', context, error instanceof Error ? error : new Error(String(error)));
241
+ }
242
+ }
243
+ /**
244
+ * Get git blame information from local repository
245
+ *
246
+ * Validates commit existence before attempting blame.
247
+ * Falls back to API if local blame fails (graceful degradation).
248
+ *
249
+ * @param project - The project ID or path
250
+ * @param path - The file path within the repository
251
+ * @param ref - The commit SHA to blame
252
+ * @returns Promise resolving to array of blame lines (empty array if both local and API fail)
253
+ */
254
+ async getBlame(project, path, ref) {
255
+ const endTimer = this.logger.startTimer('getBlame');
256
+ const context = { project, path, ref: ref.substring(0, 8), repoPath: this.repoPath, dataSource: 'LocalGit' };
257
+ try {
258
+ // Validate commit exists before attempting blame (Requirement 6.1)
259
+ await this.validateCommitExists(ref);
260
+ const git = simpleGit(this.repoPath);
261
+ // Wrap git operation with retry logic (Requirement 3.2)
262
+ const result = await ErrorHandler.withRetry(async () => {
263
+ return await git.raw([
264
+ "blame",
265
+ "--line-porcelain",
266
+ ref,
267
+ "--",
268
+ path,
269
+ ]);
270
+ }, {
271
+ maxRetries: this.config.get().maxRetries,
272
+ delayMs: this.config.get().retryDelayMs,
273
+ });
274
+ const lines = result.split("\n");
275
+ const blameData = [];
276
+ let currentCommit = null;
277
+ for (const line of lines) {
278
+ if (line.match(/^[0-9a-f]{40}/)) {
279
+ if (currentCommit && currentCommit.commit) {
280
+ blameData.push(currentCommit);
281
+ }
282
+ currentCommit = {
283
+ commit: {
284
+ id: line.split(" ")[0],
285
+ message: '',
286
+ parent_ids: [],
287
+ authored_date: '',
288
+ author_name: '',
289
+ author_email: '',
290
+ committed_date: '',
291
+ committer_name: '',
292
+ committer_email: ''
293
+ },
294
+ lines: ['1']
295
+ };
296
+ }
297
+ else if (line.startsWith("author-mail ") && currentCommit?.commit) {
298
+ currentCommit.commit.author_email = line.substring(13, line.length - 1);
299
+ }
300
+ }
301
+ if (currentCommit && currentCommit.commit) {
302
+ blameData.push(currentCommit);
303
+ }
304
+ this.logger.debug('Blame operation successful', {
305
+ ...context,
306
+ entries: blameData.length,
307
+ });
308
+ endTimer();
309
+ return blameData;
310
+ }
311
+ catch (error) {
312
+ endTimer();
313
+ // Graceful fallback to API (Requirement 6.2)
314
+ this.logger.warn('Local git blame failed, falling back to API', {
315
+ ...context,
316
+ error: error instanceof Error ? error.message : String(error),
317
+ });
318
+ try {
319
+ const apiResult = await super.getBlame(project, path, ref);
320
+ return apiResult || [];
321
+ }
322
+ catch (apiError) {
323
+ // If both local and API fail, log and return empty array (graceful degradation)
324
+ this.logger.error('Both local and API blame failed', apiError instanceof Error ? apiError : new Error(String(apiError)), context);
325
+ return [];
326
+ }
327
+ }
328
+ }
329
+ /**
330
+ * Validates that a commit exists in the repository (Requirement 6.1)
331
+ */
332
+ async validateCommitExists(commitSha) {
333
+ try {
334
+ const git = simpleGit(this.repoPath);
335
+ await git.catFile(["-e", commitSha]);
336
+ }
337
+ catch (error) {
338
+ const shortSha = commitSha.substring(0, 8);
339
+ throw ErrorHandler.gitOperationError(`Commit ${shortSha} does not exist in repository`, {
340
+ commitSha,
341
+ repoPath: this.repoPath,
342
+ dataSource: 'LocalGit',
343
+ }, error instanceof Error ? error : new Error(String(error)));
344
+ }
345
+ }
346
+ /**
347
+ * Get diffs for a merge request from local git repository
348
+ *
349
+ * Validates commits exist, handles special characters in paths,
350
+ * and fetches diffs in parallel for performance.
351
+ *
352
+ * @param project - The project ID or path
353
+ * @param mr - The merge request internal ID
354
+ * @returns Promise resolving to array of diffs
355
+ * @throws {MCPError} If merge request data is invalid or commits don't exist
356
+ */
357
+ async getDiffs(project, mr) {
358
+ const endTimer = this.logger.startTimer('getDiffs');
359
+ const context = { project, mr, repoPath: this.repoPath, dataSource: 'LocalGit' };
360
+ try {
361
+ const mrData = await this.getMergeRequest(project, mr);
362
+ // Validate merge request data (Requirement 6.4)
363
+ if (!mrData?.diff_refs?.base_sha || !mrData?.diff_refs?.head_sha) {
364
+ throw ErrorHandler.validationError('Merge request data is missing diff_refs. The MR may not have been fetched correctly or may be in an invalid state.', {
365
+ ...context,
366
+ diff_refs: mrData?.diff_refs,
367
+ });
368
+ }
369
+ const baseSha = mrData.diff_refs.base_sha;
370
+ const headSha = mrData.diff_refs.head_sha;
371
+ this.logger.debug('Processing diffs', {
372
+ ...context,
373
+ baseSha: baseSha.substring(0, 8),
374
+ headSha: headSha.substring(0, 8),
375
+ });
376
+ // Validate commits exist (Requirement 6.1)
377
+ await this.validateCommitExists(baseSha);
378
+ await this.validateCommitExists(headSha);
379
+ const git = simpleGit(this.repoPath);
380
+ // Get file changes with retry logic (Requirement 3.2)
381
+ const nameStatus = await ErrorHandler.withRetry(async () => {
382
+ return await git.raw([
383
+ "diff",
384
+ "--name-status",
385
+ `${baseSha}..${headSha}`,
386
+ ]);
387
+ }, {
388
+ maxRetries: this.config.get().maxRetries,
389
+ delayMs: this.config.get().retryDelayMs,
390
+ });
391
+ // Parse file changes with special character handling (Requirement 6.3)
392
+ const files = this.parseGitNameStatus(nameStatus);
393
+ this.logger.debug('Files changed', {
394
+ ...context,
395
+ fileCount: files.length,
396
+ });
397
+ // Fetch diffs in parallel (Requirement 4.1)
398
+ const diffs = await Promise.all(files.map(async ({ status, path }) => {
399
+ return await this.getDiffForFile(git, baseSha, headSha, status, path, context);
400
+ }));
401
+ const withDiff = diffs.filter((d) => d.diff).length;
402
+ const addedOrDeletedFiles = diffs.filter((d) => d.new_file || d.deleted_file).length;
403
+ const modifiedFiles = diffs.length - addedOrDeletedFiles;
404
+ this.logger.info('Diffs retrieved', {
405
+ ...context,
406
+ totalFiles: diffs.length,
407
+ filesWithDiff: withDiff,
408
+ addedOrDeleted: addedOrDeletedFiles,
409
+ modified: modifiedFiles,
410
+ });
411
+ // Validate we got meaningful results (Requirement 6.4)
412
+ // Only throw error if we have modified files but no diff content
413
+ // Added/deleted files legitimately have no diff content
414
+ if (withDiff === 0 && modifiedFiles > 0) {
415
+ const shortBaseSha = baseSha.substring(0, 8);
416
+ const shortHeadSha = headSha.substring(0, 8);
417
+ throw ErrorHandler.gitOperationError('No diff content was generated for modified files. This may indicate a repository state issue or that the commits are identical.', {
418
+ ...context,
419
+ baseSha: shortBaseSha,
420
+ headSha: shortHeadSha,
421
+ fileCount: diffs.length,
422
+ modifiedFiles,
423
+ }, new Error('No diff content generated'));
424
+ }
425
+ endTimer();
426
+ return diffs;
427
+ }
428
+ catch (error) {
429
+ endTimer();
430
+ // Provide clear error context (Requirement 6.4)
431
+ if (error instanceof Error && error.message.includes('MCP')) {
432
+ // Already an MCPError, just rethrow
433
+ throw error;
434
+ }
435
+ throw ErrorHandler.gitOperationError('Failed to get diffs from local git repository', context, error instanceof Error ? error : new Error(String(error)));
436
+ }
437
+ }
438
+ /**
439
+ * Parses git name-status output with special character handling (Requirement 6.3)
440
+ */
441
+ parseGitNameStatus(nameStatus) {
442
+ return nameStatus
443
+ .trim()
444
+ .split("\n")
445
+ .filter((line) => line)
446
+ .map((line) => {
447
+ // Handle tabs in file paths by splitting only on the first tab
448
+ const [status, ...pathParts] = line.split("\t");
449
+ // Rejoin path parts to handle paths with tabs or special characters
450
+ const path = pathParts.join("\t");
451
+ return { status, path };
452
+ });
453
+ }
454
+ /**
455
+ * Gets diff for a single file with error handling
456
+ */
457
+ async getDiffForFile(git, baseSha, headSha, status, path, context) {
458
+ const oldPath = status !== "A" ? path : null;
459
+ const newPath = status !== "D" ? path : null;
460
+ let diff = "";
461
+ if (oldPath) {
462
+ try {
463
+ // Wrap git operation with retry logic
464
+ const rawDiff = await ErrorHandler.withRetry(async () => {
465
+ return await git.raw([
466
+ "diff",
467
+ `${baseSha}..${headSha}`,
468
+ "--",
469
+ oldPath,
470
+ ]);
471
+ }, {
472
+ maxRetries: this.config.get().maxRetries,
473
+ delayMs: this.config.get().retryDelayMs,
474
+ });
475
+ // Strip git headers to match GitLab API format (only keep hunks starting with @@)
476
+ const lines = rawDiff.split("\n");
477
+ const firstHunkIndex = lines.findIndex((line) => line.startsWith("@@"));
478
+ diff =
479
+ firstHunkIndex >= 0
480
+ ? lines.slice(firstHunkIndex).join("\n")
481
+ : rawDiff;
482
+ }
483
+ catch (e) {
484
+ // Log but don't fail - graceful degradation (Requirement 3.5)
485
+ this.logger.warn('Failed to get diff for file', {
486
+ ...context,
487
+ path: oldPath,
488
+ error: e instanceof Error ? e.message : String(e),
489
+ });
490
+ }
491
+ }
492
+ return {
493
+ new_path: newPath || '',
494
+ old_path: oldPath || '',
495
+ a_mode: '',
496
+ b_mode: '',
497
+ deleted_file: status === "D",
498
+ new_file: status === "A",
499
+ renamed_file: false,
500
+ diff,
501
+ };
502
+ }
503
+ /**
504
+ * Get raw file content from local repository
505
+ *
506
+ * Tries git show first, falls back to filesystem read if that fails.
507
+ *
508
+ * @param project - The project ID or path (used for logging)
509
+ * @param branch - The branch name
510
+ * @param path - The file path within the repository
511
+ * @returns Promise resolving to file content or null if not found
512
+ * @throws {MCPError} If file is not found in git or filesystem
513
+ */
514
+ async getRawFile(project, branch, path) {
515
+ const context = { project, branch, path, repoPath: this.repoPath, dataSource: 'LocalGit' };
516
+ try {
517
+ const git = simpleGit(this.repoPath);
518
+ // Try git show first with retry logic
519
+ const content = await ErrorHandler.withRetry(async () => {
520
+ return await git.show([`origin/${branch}:${path}`]);
521
+ }, {
522
+ maxRetries: this.config.get().maxRetries,
523
+ delayMs: this.config.get().retryDelayMs,
524
+ });
525
+ this.logger.debug('File retrieved from git', context);
526
+ return content;
527
+ }
528
+ catch (error) {
529
+ // Fallback to filesystem read
530
+ this.logger.debug('Git show failed, trying filesystem', {
531
+ ...context,
532
+ error: error instanceof Error ? error.message : String(error),
533
+ });
534
+ try {
535
+ const filePath = join(this.repoPath, path);
536
+ const content = readFileSync(filePath, "utf-8");
537
+ this.logger.debug('File retrieved from filesystem', { ...context, filePath });
538
+ return content;
539
+ }
540
+ catch (fsError) {
541
+ const gitErrorMsg = error instanceof Error ? error.message : String(error);
542
+ const fsErrorMsg = fsError instanceof Error ? fsError.message : String(fsError);
543
+ throw ErrorHandler.notFoundError(`File not found in git or filesystem: ${path}`, {
544
+ ...context,
545
+ gitError: gitErrorMsg,
546
+ fsError: fsErrorMsg,
547
+ });
548
+ }
549
+ }
550
+ }
551
+ /**
552
+ * Get and parse a JSON file from local repository
553
+ *
554
+ * @param project - The project ID or path
555
+ * @param branch - The branch name
556
+ * @param path - The file path within the repository
557
+ * @returns Promise resolving to parsed JSON object or null if not found
558
+ * @throws {MCPError} If the file cannot be parsed as JSON
559
+ */
560
+ async getJsonFile(project, branch, path) {
561
+ const context = { project, branch, path, dataSource: 'LocalGit' };
562
+ try {
563
+ const content = await this.getRawFile(project, branch, path);
564
+ if (!content)
565
+ return null;
566
+ return JSON.parse(content);
567
+ }
568
+ catch (error) {
569
+ if (error instanceof Error && error.message.includes('MCP')) {
570
+ throw error;
571
+ }
572
+ const errorMsg = error instanceof Error ? error.message : String(error);
573
+ throw ErrorHandler.validationError(`Failed to parse JSON file: ${path}`, {
574
+ ...context,
575
+ error: errorMsg,
576
+ });
577
+ }
578
+ }
579
+ }
580
+ //# sourceMappingURL=local-git-data-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-git-data-source.js","sourceRoot":"","sources":["../../src/datasources/local-git-data-source.ts"],"names":[],"mappings":"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"}