@renfeng/ai-code-review 1.1.1 → 1.2.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.
@@ -1,121 +1,149 @@
1
1
  /**
2
2
  * Git Tools Service
3
3
  *
4
- * Provides local git operations as MCP tools, eliminating the need for
5
- * shell commands that are prone to terminal hang issues (Kiro #4132).
6
- *
7
- * Uses simple-git for all git operations.
4
+ * Thin 1-to-1 wrapper over the git CLI using child_process.execFile.
5
+ * No third-party git libraries requires git to be installed.
8
6
  */
9
- import simpleGit from 'simple-git';
10
- import { existsSync, rmSync, writeFileSync } from 'fs';
11
- import { join } from 'path';
7
+ import { execFile, execFileSync } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { existsSync, rmSync, readFileSync, writeFileSync } from 'fs';
10
+ import { basename, join, resolve } from 'path';
12
11
  import { Logger } from '../logging/logger.service.js';
12
+ const execFileAsync = promisify(execFile);
13
+ const MAX_BUFFER = 50 * 1024 * 1024; // 50 MB
14
+ /**
15
+ * Resolve the absolute path to the git binary at module load.
16
+ * MCP servers spawned by Kiro may not inherit the user's shell PATH,
17
+ * causing execFile('git', ...) to fail with ENOENT.
18
+ */
19
+ function resolveGitBinary() {
20
+ // Try 'which' first (works when PATH is available)
21
+ try {
22
+ return execFileSync('which', ['git'], { encoding: 'utf-8' }).trim();
23
+ }
24
+ catch { /* PATH doesn't include git */ }
25
+ // Fall back to well-known locations (macOS / Linux)
26
+ const candidates = ['/usr/bin/git', '/usr/local/bin/git', '/opt/homebrew/bin/git'];
27
+ for (const candidate of candidates) {
28
+ if (existsSync(candidate))
29
+ return candidate;
30
+ }
31
+ // Last resort — let execFile try PATH resolution (original behavior)
32
+ return 'git';
33
+ }
34
+ const GIT_BINARY = resolveGitBinary();
35
+ /**
36
+ * Resolve a cwd parameter to an absolute path.
37
+ *
38
+ * Kiro's multi-root workspace passes workspace folder names (e.g. "reviewer")
39
+ * as cwd, but the MCP server's process.cwd() may already BE that folder.
40
+ * This causes double-nesting: resolve("reviewer") → "<server-cwd>/reviewer".
41
+ *
42
+ * Strategy:
43
+ * 1. If cwd is not provided, use process.cwd()
44
+ * 2. If cwd is already absolute and exists, use it
45
+ * 3. Resolve relative to process.cwd() — if it exists, use it
46
+ * 4. If the resolved path doesn't exist but process.cwd() basename matches
47
+ * the cwd parameter, use process.cwd() directly (the caller passed the
48
+ * workspace folder name redundantly)
49
+ * 5. Fall through to the resolved path (will fail with a clear error)
50
+ */
51
+ function resolveCwd(cwd) {
52
+ if (!cwd)
53
+ return process.cwd();
54
+ const absolute = resolve(cwd);
55
+ if (existsSync(absolute))
56
+ return absolute;
57
+ // Check if process.cwd() already IS the requested directory
58
+ if (basename(process.cwd()) === cwd && existsSync(process.cwd())) {
59
+ return process.cwd();
60
+ }
61
+ return absolute;
62
+ }
63
+ async function git(cwd, args) {
64
+ const absCwd = resolve(cwd);
65
+ const { stdout } = await execFileAsync(GIT_BINARY, args, { cwd: absCwd, maxBuffer: MAX_BUFFER });
66
+ return stdout;
67
+ }
13
68
  export class GitToolsService {
14
69
  logger;
15
70
  constructor(logger) {
16
71
  this.logger = logger || new Logger('GitToolsService');
17
72
  }
18
- git(cwd) {
19
- return simpleGit(cwd);
20
- }
21
73
  async clone(params) {
22
- const cwd = params.cwd || process.cwd();
74
+ const cwd = resolveCwd(params.cwd);
23
75
  const targetDir = join(cwd, params.directory);
24
76
  this.logger.info('Cloning repository', { url: params.url, directory: targetDir });
25
77
  if (existsSync(targetDir)) {
26
78
  this.logger.info('Directory exists, fetching instead', { directory: targetDir });
27
- const git = this.git(targetDir);
28
- await git.fetch(['--all', '--prune']);
79
+ await git(targetDir, ['fetch', '--all', '--prune']);
29
80
  return { directory: targetDir };
30
81
  }
31
- const git = simpleGit(cwd);
32
- await git.clone(params.url, params.directory);
82
+ await git(cwd, ['clone', params.url, params.directory]);
33
83
  return { directory: targetDir };
34
84
  }
35
85
  async cloneLocal(params) {
36
- const cwd = params.cwd || process.cwd();
86
+ const cwd = resolveCwd(params.cwd);
37
87
  const refDir = join(cwd, params.referenceDir);
38
88
  const workDir = join(cwd, params.workDir);
39
89
  this.logger.info('Local clone from reference', { referenceDir: refDir, workDir });
40
- const git = simpleGit(cwd);
41
- await git.clone(refDir, params.workDir, ['--local']);
42
- const refGit = this.git(refDir);
43
- const remoteUrl = (await refGit.remote(['get-url', 'origin']))?.trim();
90
+ await git(cwd, ['clone', '--local', refDir, params.workDir]);
91
+ const remoteUrl = (await git(refDir, ['remote', 'get-url', 'origin'])).trim();
44
92
  if (remoteUrl) {
45
- const workGit = this.git(workDir);
46
- await workGit.remote(['set-url', 'origin', remoteUrl]);
93
+ await git(workDir, ['remote', 'set-url', 'origin', remoteUrl]);
47
94
  this.logger.info('Set origin from reference repo', { remoteUrl });
48
95
  }
49
96
  return { directory: workDir };
50
97
  }
51
98
  async fetch(params) {
52
- const git = this.git(params.repoDir);
53
99
  if (params.all) {
54
100
  this.logger.info('Fetching all remotes', { repoDir: params.repoDir });
55
- await git.fetch(['--all', '--prune']);
101
+ await git(params.repoDir, ['fetch', '--all', '--prune']);
56
102
  }
57
103
  else if (params.branches?.length) {
58
104
  this.logger.info('Fetching branches', { repoDir: params.repoDir, branches: params.branches });
59
105
  for (const refspec of params.branches) {
60
- await git.fetch('origin', refspec);
106
+ await git(params.repoDir, ['fetch', 'origin', refspec]);
61
107
  }
62
108
  }
63
109
  else {
64
- await git.fetch();
110
+ await git(params.repoDir, ['fetch']);
65
111
  }
66
112
  return { success: true };
67
113
  }
68
114
  async checkout(params) {
69
- const git = this.git(params.repoDir);
70
115
  this.logger.info('Checking out branch', { repoDir: params.repoDir, branch: params.branch });
71
- await git.checkout(params.branch);
116
+ await git(params.repoDir, ['checkout', params.branch]);
72
117
  return { branch: params.branch };
73
118
  }
74
119
  async reset(params) {
75
- const git = this.git(params.repoDir);
76
120
  const mode = params.mode || 'mixed';
77
121
  this.logger.info('Resetting to ref', { repoDir: params.repoDir, ref: params.ref, mode });
78
- await git.raw(['reset', `--${mode}`, params.ref]);
122
+ await git(params.repoDir, ['reset', `--${mode}`, params.ref]);
79
123
  return { success: true, ref: params.ref, mode };
80
124
  }
81
125
  async mergeBase(params) {
82
- const git = this.git(params.repoDir);
83
126
  this.logger.info('Computing merge base', { repoDir: params.repoDir, ref1: params.ref1, ref2: params.ref2 });
84
- const result = await git.raw(['merge-base', params.ref1, params.ref2]);
127
+ const result = await git(params.repoDir, ['merge-base', params.ref1, params.ref2]);
85
128
  return { mergeBase: result.trim() };
86
129
  }
87
130
  async diff(params) {
88
- const git = this.git(params.repoDir);
89
- const head = params.head || 'HEAD';
90
131
  const mode = params.mode || 'stat';
91
- this.logger.info('Running diff', { repoDir: params.repoDir, base: params.base, head, mode });
92
- let args;
93
- switch (mode) {
94
- case 'stat':
95
- args = ['diff', params.base, head, '--stat'];
96
- break;
97
- case 'name-only':
98
- args = ['diff', params.base, head, '--name-only'];
99
- break;
100
- case 'full':
101
- args = ['diff', params.base, head];
102
- break;
103
- default: args = ['diff', params.base, head, '--stat'];
104
- }
105
- const result = await git.raw(args);
132
+ this.logger.info('Running diff', { repoDir: params.repoDir, base: params.base, head: params.head, mode });
133
+ const refs = params.head ? [params.base, params.head] : [params.base];
134
+ const modeFlag = mode === 'stat' ? ['--stat'] : mode === 'name-only' ? ['--name-only'] : [];
135
+ const result = await git(params.repoDir, ['diff', ...refs, ...modeFlag]);
106
136
  return { diff: result };
107
137
  }
108
138
  async show(params) {
109
- const git = this.git(params.repoDir);
110
139
  this.logger.info('Showing file at ref', { repoDir: params.repoDir, ref: params.ref, path: params.path });
111
- const result = await git.show([`${params.ref}:${params.path}`]);
140
+ const result = await git(params.repoDir, ['show', `${params.ref}:${params.path}`]);
112
141
  return { content: result };
113
142
  }
114
143
  async log(params) {
115
- const git = this.git(params.repoDir);
116
144
  const maxCount = params.maxCount || 10;
117
145
  this.logger.info('Getting log', { repoDir: params.repoDir, maxCount });
118
- const result = await git.raw(['log', '--oneline', '--decorate', `-${maxCount}`]);
146
+ const result = await git(params.repoDir, ['log', '--oneline', '--decorate', `-${maxCount}`]);
119
147
  return { log: result };
120
148
  }
121
149
  async cleanup(params) {
@@ -126,20 +154,14 @@ export class GitToolsService {
126
154
  }
127
155
  return { removed: false };
128
156
  }
129
- async writeFile(params) {
130
- this.logger.info('Writing file', { filePath: params.filePath });
131
- writeFileSync(params.filePath, params.content, 'utf-8');
132
- return { written: true };
133
- }
134
157
  async grep(params) {
135
- const git = this.git(params.repoDir);
136
158
  const maxResults = params.maxResults || 50;
137
159
  this.logger.info('Running git grep', { repoDir: params.repoDir, pattern: params.pattern, paths: params.paths });
138
160
  const args = ['grep', '-n', '--no-color', params.pattern];
139
161
  if (params.paths?.length)
140
162
  args.push('--', ...params.paths);
141
163
  try {
142
- const result = await git.raw(args);
164
+ const result = await git(params.repoDir, args);
143
165
  const lines = result.split('\n').filter(Boolean);
144
166
  const matchCount = lines.length;
145
167
  const truncated = lines.slice(0, maxResults).join('\n');
@@ -147,11 +169,217 @@ export class GitToolsService {
147
169
  return { results: truncated + suffix, matchCount };
148
170
  }
149
171
  catch (error) {
150
- if (error?.message?.includes('exit code 1') || error?.exitCode === 1) {
172
+ if (error?.code === 1 || error?.message?.includes('exit code 1')) {
151
173
  return { results: '', matchCount: 0 };
152
174
  }
153
175
  throw error;
154
176
  }
155
177
  }
178
+ /**
179
+ * Resolve anchor-based findings to line numbers by parsing the diff.
180
+ *
181
+ * Each finding has a file, hunk header, and anchor (line content).
182
+ * This method finds the anchor in the diff and sets the line number.
183
+ */
184
+ async resolveAnchors(params) {
185
+ this.logger.info('Resolving anchors', {
186
+ repoDir: params.repoDir, mergeBase: params.mergeBase, findingsPath: params.findingsPath,
187
+ });
188
+ const raw = readFileSync(params.findingsPath, 'utf-8');
189
+ const findings = JSON.parse(raw);
190
+ const diffCache = new Map();
191
+ let resolved = 0;
192
+ let fallbackToGeneral = 0;
193
+ for (const comment of findings.comments) {
194
+ if (!comment.file || !comment.anchor || comment.changed === 'general')
195
+ continue;
196
+ const fileDiff = await this.getFileDiff(params.repoDir, params.mergeBase, comment.file, diffCache);
197
+ if (!fileDiff) {
198
+ comment.changed = 'general';
199
+ fallbackToGeneral++;
200
+ continue;
201
+ }
202
+ const result = this.resolveAnchorInDiff(fileDiff, comment);
203
+ if (result) {
204
+ comment.changed = result.changed;
205
+ comment.line = result.line;
206
+ comment.old_line = result.old_line;
207
+ resolved++;
208
+ }
209
+ else {
210
+ comment.changed = 'general';
211
+ fallbackToGeneral++;
212
+ }
213
+ }
214
+ writeFileSync(params.findingsPath, JSON.stringify(findings, null, 2));
215
+ this.logger.info('Anchor resolution complete', { resolved, fallbackToGeneral, total: findings.comments.length });
216
+ return { resolved, fallbackToGeneral, total: findings.comments.length };
217
+ }
218
+ /**
219
+ * Check which draft notes are stale by comparing their target line
220
+ * against the current file content on HEAD.
221
+ */
222
+ async checkDraftStaleness(params) {
223
+ this.logger.info('Checking draft staleness', { repoDir: params.repoDir, draftCount: params.drafts.length });
224
+ const results = [];
225
+ const fileCache = new Map();
226
+ for (const draft of params.drafts) {
227
+ if (!draft.file || draft.line == null) {
228
+ results.push({ id: draft.id, stale: false, reason: 'general comment (no file/line)' });
229
+ continue;
230
+ }
231
+ const lines = await this.getFileLines(params.repoDir, draft.file, fileCache);
232
+ if (!lines) {
233
+ results.push({ id: draft.id, stale: true, reason: `file no longer exists: ${draft.file}` });
234
+ continue;
235
+ }
236
+ const lineIdx = draft.line - 1;
237
+ if (lineIdx < 0 || lineIdx >= lines.length) {
238
+ results.push({ id: draft.id, stale: true, reason: `line ${draft.line} out of range (file has ${lines.length} lines)` });
239
+ continue;
240
+ }
241
+ results.push({ id: draft.id, stale: false, reason: 'line exists in current file' });
242
+ }
243
+ const staleCount = results.filter(r => r.stale).length;
244
+ const freshCount = results.filter(r => !r.stale).length;
245
+ this.logger.info('Draft staleness check complete', { staleCount, freshCount });
246
+ return { results, staleCount, freshCount };
247
+ }
248
+ /**
249
+ * Compile non-blocking findings into a markdown checklist with file links.
250
+ */
251
+ async compileChecklist(params) {
252
+ this.logger.info('Compiling checklist', { findingsPath: params.findingsPath, project: params.project });
253
+ const raw = readFileSync(params.findingsPath, 'utf-8');
254
+ const findings = JSON.parse(raw);
255
+ const gitlabUrl = params.gitlabUrl.replace(/\/+$/, '');
256
+ const nonBlocking = findings.comments.filter(c => !c.blocking);
257
+ if (nonBlocking.length === 0) {
258
+ return { markdown: '', itemCount: 0 };
259
+ }
260
+ const lines = ['### Suggestions', ''];
261
+ for (const comment of nonBlocking) {
262
+ const firstLine = comment.note.split('\n')[0];
263
+ const noteOneLine = comment.note.includes('\n') ? firstLine + ' …' : firstLine;
264
+ if (!comment.file) {
265
+ lines.push(`- [ ] **General**: ${noteOneLine}`);
266
+ continue;
267
+ }
268
+ const fileUrl = `${gitlabUrl}/${params.project}/-/blob/${params.headSha}/${comment.file}`;
269
+ const lineNum = comment.line ?? comment.old_line;
270
+ if (lineNum) {
271
+ lines.push(`- [ ] **${comment.file}** ([L${lineNum}](${fileUrl}#L${lineNum})): ${noteOneLine}`);
272
+ }
273
+ else {
274
+ lines.push(`- [ ] **${comment.file}** ([link](${fileUrl})): ${noteOneLine}`);
275
+ }
276
+ }
277
+ const markdown = lines.join('\n');
278
+ this.logger.info('Checklist compiled', { itemCount: nonBlocking.length });
279
+ return { markdown, itemCount: nonBlocking.length };
280
+ }
281
+ // --- Private helpers for anchor resolution ---
282
+ async getFileDiff(repoDir, mergeBase, filePath, cache) {
283
+ if (cache.has(filePath))
284
+ return cache.get(filePath);
285
+ try {
286
+ const result = await git(repoDir, ['diff', mergeBase, 'HEAD', '--', filePath]);
287
+ cache.set(filePath, result);
288
+ return result;
289
+ }
290
+ catch {
291
+ return null;
292
+ }
293
+ }
294
+ async getFileLines(repoDir, filePath, cache) {
295
+ if (cache.has(filePath))
296
+ return cache.get(filePath);
297
+ try {
298
+ const content = await git(repoDir, ['show', `HEAD:${filePath}`]);
299
+ const lines = content.split('\n');
300
+ cache.set(filePath, lines);
301
+ return lines;
302
+ }
303
+ catch {
304
+ return null;
305
+ }
306
+ }
307
+ resolveAnchorInDiff(diff, comment) {
308
+ const rawAnchor = comment.anchor;
309
+ const isOldAnchor = rawAnchor.startsWith('OLD:');
310
+ const anchorText = (isOldAnchor ? rawAnchor.slice(4) : rawAnchor).trim();
311
+ const hunks = this.parseHunks(diff);
312
+ const targetHunk = comment.hunk ? this.findMatchingHunk(hunks, comment.hunk) : null;
313
+ const searchHunks = targetHunk ? [targetHunk] : hunks;
314
+ for (const hunk of searchHunks) {
315
+ const result = this.findAnchorInHunk(hunk, anchorText, isOldAnchor);
316
+ if (result)
317
+ return result;
318
+ }
319
+ return null;
320
+ }
321
+ parseHunks(diff) {
322
+ const lines = diff.split('\n');
323
+ const hunks = [];
324
+ let current = null;
325
+ for (const line of lines) {
326
+ const hunkMatch = line.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);
327
+ if (hunkMatch) {
328
+ current = {
329
+ header: line,
330
+ oldStart: parseInt(hunkMatch[1], 10),
331
+ newStart: parseInt(hunkMatch[2], 10),
332
+ lines: [],
333
+ };
334
+ hunks.push(current);
335
+ continue;
336
+ }
337
+ if (current && (line.startsWith('+') || line.startsWith('-') || line.startsWith(' '))) {
338
+ current.lines.push(line);
339
+ }
340
+ }
341
+ return hunks;
342
+ }
343
+ findMatchingHunk(hunks, hunkHeader) {
344
+ const m = hunkHeader.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);
345
+ if (!m)
346
+ return null;
347
+ const targetOld = parseInt(m[1], 10);
348
+ const targetNew = parseInt(m[2], 10);
349
+ return hunks.find(h => h.oldStart === targetOld && h.newStart === targetNew) || null;
350
+ }
351
+ findAnchorInHunk(hunk, anchorText, isOldAnchor) {
352
+ // Search preferred line type first, then fallback
353
+ const passes = isOldAnchor
354
+ ? [{ prefixes: ['-'] }]
355
+ : [{ prefixes: ['+'] }, { prefixes: [' '] }];
356
+ for (const pass of passes) {
357
+ let oldLine = hunk.oldStart;
358
+ let newLine = hunk.newStart;
359
+ for (const line of hunk.lines) {
360
+ const prefix = line[0];
361
+ const content = line.slice(1).trim();
362
+ if (pass.prefixes.includes(prefix) && content === anchorText) {
363
+ if (prefix === '+')
364
+ return { changed: 'new', line: newLine };
365
+ if (prefix === '-')
366
+ return { changed: 'old', old_line: oldLine };
367
+ if (prefix === ' ')
368
+ return { changed: 'context', line: newLine, old_line: oldLine };
369
+ }
370
+ if (prefix === '+') {
371
+ newLine++;
372
+ }
373
+ else if (prefix === '-') {
374
+ oldLine++;
375
+ }
376
+ else {
377
+ oldLine++;
378
+ newLine++;
379
+ }
380
+ }
381
+ }
382
+ return null;
383
+ }
156
384
  }
157
385
  //# sourceMappingURL=git-tools.service.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"git-tools.service.js","sourceRoot":"","sources":["../../src/services/git-tools.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"git-tools.service.js","sourceRoot":"","sources":["../../src/services/git-tools.service.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  * Implements business logic for the code review and todo triage MCP tools.
5
5
  */
6
6
  import { Logger } from '../logging/logger.service.js';
7
- import { ExtractMrMetadataParams, ExtractVersionRefsParams, ExtractPriorDiscussionsParams, PostDraftNotesParams, DeleteDraftNotesParams, PublishReviewParams, FetchAndCategorizeTodosParams, MarkTodosDoneParams } from '../types.js';
7
+ import { ExtractMrMetadataParams, ExtractVersionRefsParams, ExtractPriorDiscussionsParams, ExtractDraftNotesParams, PostDraftNotesParams, DeleteDraftNotesParams, PublishReviewParams, PostCommentParams, FetchAndCategorizeTodosParams, MarkTodosDoneParams } from '../types.js';
8
8
  interface PriorDiscussion {
9
9
  file: string | null;
10
10
  line: number | null;
@@ -45,6 +45,13 @@ export declare class ReviewToolsService {
45
45
  start_sha: string;
46
46
  }>;
47
47
  extractPriorDiscussions(params: ExtractPriorDiscussionsParams, gitlabUrl: string, token: string): Promise<PriorDiscussion[]>;
48
+ extractDraftNotes(params: ExtractDraftNotesParams, gitlabUrl: string, token: string): Promise<Array<{
49
+ id: number;
50
+ note: string;
51
+ file: string | null;
52
+ line: number | null;
53
+ old_line: number | null;
54
+ }>>;
48
55
  postDraftNotes(params: PostDraftNotesParams, gitlabUrl: string, token: string): Promise<{
49
56
  posted: number;
50
57
  blocking: number;
@@ -65,6 +72,10 @@ export declare class ReviewToolsService {
65
72
  action: string;
66
73
  action_success: boolean;
67
74
  }>;
75
+ postComment(params: PostCommentParams, gitlabUrl: string, token: string): Promise<{
76
+ id: number;
77
+ url: string;
78
+ }>;
68
79
  private isRenovate;
69
80
  fetchAndCategorizeTodos(_params: FetchAndCategorizeTodosParams, gitlabUrl: string, token: string): Promise<TodoCategories>;
70
81
  markTodosDone(params: MarkTodosDoneParams, gitlabUrl: string, token: string): Promise<Array<{
@@ -1 +1 @@
1
- {"version":3,"file":"review-tools.service.d.ts","sourceRoot":"","sources":["../../src/services/review-tools.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"review-tools.service.d.ts","sourceRoot":"","sources":["../../src/services/review-tools.service.ts"],"names":[],"mappings":"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"}
@@ -49,6 +49,17 @@ export class ReviewToolsService {
49
49
  }
50
50
  return result;
51
51
  }
52
+ async extractDraftNotes(params, gitlabUrl, token) {
53
+ const api = this.createApi(gitlabUrl, token);
54
+ const drafts = await api.getDraftNotes(String(params.project), params.mergeRequestIid);
55
+ return drafts.map(d => ({
56
+ id: d.id,
57
+ note: (d.note || '').slice(0, 500),
58
+ file: d.position?.new_path ?? d.position?.old_path ?? null,
59
+ line: d.position?.new_line ?? null,
60
+ old_line: d.position?.old_line ?? null,
61
+ }));
62
+ }
52
63
  async postDraftNotes(params, gitlabUrl, token) {
53
64
  const api = this.createApi(gitlabUrl, token);
54
65
  const project = String(params.project);
@@ -125,12 +136,18 @@ export class ReviewToolsService {
125
136
  const api = this.createApi(gitlabUrl, token);
126
137
  const project = String(params.project);
127
138
  const mr = params.mergeRequestIid;
128
- const drafts = await api.getDraftNotes(project, mr);
129
- if (drafts.length === 0)
139
+ let draftsToDelete;
140
+ if (params.draftNoteIds?.length) {
141
+ draftsToDelete = params.draftNoteIds.map(id => ({ id }));
142
+ }
143
+ else {
144
+ draftsToDelete = await api.getDraftNotes(project, mr);
145
+ }
146
+ if (draftsToDelete.length === 0)
130
147
  return { deleted: 0, errors: [] };
131
148
  let deleted = 0;
132
149
  const errors = [];
133
- for (const draft of drafts) {
150
+ for (const draft of draftsToDelete) {
134
151
  try {
135
152
  await api.deleteDraftNote(project, mr, draft.id);
136
153
  deleted++;
@@ -139,7 +156,7 @@ export class ReviewToolsService {
139
156
  errors.push(`Failed to delete draft ${draft.id}: ${err instanceof Error ? err.message : String(err)}`);
140
157
  }
141
158
  }
142
- this.logger.info('Draft notes deleted', { deleted, total: drafts.length, errors: errors.length });
159
+ this.logger.info('Draft notes deleted', { deleted, total: draftsToDelete.length, errors: errors.length });
143
160
  return { deleted, errors };
144
161
  }
145
162
  async publishReview(params, gitlabUrl, token) {
@@ -219,6 +236,17 @@ export class ReviewToolsService {
219
236
  }
220
237
  return { publish_ok: publishOk, resolved_threads: resolvedCount, reviewer_assigned: username, action, action_success: actionSuccess };
221
238
  }
239
+ async postComment(params, gitlabUrl, token) {
240
+ const api = this.createApi(gitlabUrl, token);
241
+ const project = String(params.project);
242
+ const mr = params.mergeRequestIid;
243
+ // Unescape double-escaped newlines from MCP JSON serialization round-trip
244
+ const body = params.body.replace(/\\n/g, '\n');
245
+ const result = await api.postNote(project, mr, body);
246
+ const noteUrl = `${gitlabUrl}/${project}/-/merge_requests/${mr}#note_${result.id}`;
247
+ this.logger.info('Comment posted', { noteId: result.id, mr });
248
+ return { id: result.id, url: noteUrl };
249
+ }
222
250
  isRenovate(title, sourceBranch = '') {
223
251
  const t = title.toLowerCase();
224
252
  return t.startsWith('[renovate') || title.includes('chore(deps):') || title.includes('fix(deps):') || sourceBranch.startsWith('renovate/');
@@ -266,8 +294,30 @@ export class ReviewToolsService {
266
294
  item.reason = `action=${action}, not a review request or mention`;
267
295
  skip.push(item);
268
296
  }
269
- this.logger.info(`Categorized ${todos.length} todos`, { done: done.length, review: review.length, skip: skip.length });
270
- return { done, review, skip };
297
+ // Deduplicate review list by MR keep the highest-priority action per unique MR
298
+ const actionPriority = { marked: 0, review_requested: 1, mentioned: 2 };
299
+ const reviewByMr = new Map();
300
+ for (const item of review) {
301
+ const key = `${item.project}:${item.mr_iid}`;
302
+ const existing = reviewByMr.get(key);
303
+ if (!existing || (actionPriority[item.action] ?? 99) < (actionPriority[existing.action] ?? 99)) {
304
+ if (existing) {
305
+ existing.reason = 'duplicate';
306
+ done.push(existing);
307
+ }
308
+ reviewByMr.set(key, item);
309
+ }
310
+ else {
311
+ item.reason = 'duplicate';
312
+ done.push(item);
313
+ }
314
+ }
315
+ const deduplicatedReview = [...reviewByMr.values()];
316
+ const dupeCount = review.length - deduplicatedReview.length;
317
+ if (dupeCount > 0)
318
+ this.logger.info(`Deduplicated ${dupeCount} duplicate MR todos`);
319
+ this.logger.info(`Categorized ${todos.length} todos`, { done: done.length, review: deduplicatedReview.length, skip: skip.length });
320
+ return { done, review: deduplicatedReview, skip };
271
321
  }
272
322
  async markTodosDone(params, gitlabUrl, token) {
273
323
  const api = this.createApi(gitlabUrl, token);