gitlab-ai-review 4.1.0 → 4.1.2

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 (2) hide show
  1. package/index.js +126 -17
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -16,7 +16,7 @@ import * as ImpactAnalyzer from './lib/impact-analyzer.js';
16
16
  export class GitLabAIReview {
17
17
  constructor(options = {}) {
18
18
  this.name = 'GitLab AI Review SDK';
19
- this.version = '4.1.0';
19
+ this.version = '4.1.2';
20
20
 
21
21
  // 如果传入了配置,使用手动配置;否则使用自动检测
22
22
  if (options.token || options.gitlab) {
@@ -236,18 +236,33 @@ export class GitLabAIReview {
236
236
  for (const review of mergedReviews) {
237
237
  if (review.hasIssue) {
238
238
  try {
239
- // 构建评论位置参数
239
+ // 找到这个评论对应的变更和它所在的 hunk
240
+ let targetChange = null;
241
+ if (review.oldLine && review.newLine) {
242
+ // 修改块:找删除或新增的任意一个
243
+ targetChange = meaningfulChanges.find(c =>
244
+ (c.lineNumber === review.oldLine && c.type === 'deletion') ||
245
+ (c.lineNumber === review.newLine && c.type === 'addition')
246
+ );
247
+ } else if (review.lineNumber) {
248
+ targetChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
249
+ }
250
+
251
+ // 构建评论位置参数 - 使用 hunk 的起始位置覆盖整个变更块
240
252
  const positionParams = {
241
253
  filePath: fileName,
242
254
  oldPath: change.old_path,
243
255
  };
244
256
 
245
- // 如果是修改块(同时有 oldLine newLine),同时指定两个行号
246
- if (review.oldLine && review.newLine) {
257
+ if (targetChange && targetChange.hunkRange) {
258
+ // 使用 hunk 的起始行号,让评论覆盖整个 hunk 范围
259
+ positionParams.oldLine = targetChange.hunkRange.oldStart;
260
+ positionParams.newLine = targetChange.hunkRange.newStart;
261
+ } else if (review.oldLine && review.newLine) {
262
+ // 如果找不到 hunk 信息,回退到原来的逻辑
247
263
  positionParams.oldLine = review.oldLine;
248
264
  positionParams.newLine = review.newLine;
249
265
  } else if (review.lineNumber) {
250
- // 单独的删除或新增
251
266
  const relatedChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
252
267
  const isDeletion = relatedChange && relatedChange.type === 'deletion';
253
268
  if (isDeletion) {
@@ -257,33 +272,77 @@ export class GitLabAIReview {
257
272
  }
258
273
  }
259
274
 
275
+ // 构建评论内容,包含完整的修改块上下文
276
+ let commentBody = '🤖 **AI 代码审查**\n\n';
277
+
278
+ // 如果是修改块(同时有 oldLine 和 newLine),显示完整的删除和新增
279
+ if (review.oldLine && review.newLine) {
280
+ // 添加修改块的上下文
281
+ const oldChange = meaningfulChanges.find(c => c.lineNumber === review.oldLine && c.type === 'deletion');
282
+ const newChange = meaningfulChanges.find(c => c.lineNumber === review.newLine && c.type === 'addition');
283
+
284
+ if (oldChange || newChange) {
285
+ commentBody += '**📝 修改内容:**\n```diff\n';
286
+ if (oldChange) {
287
+ commentBody += `- ${oldChange.content}\n`;
288
+ }
289
+ if (newChange) {
290
+ commentBody += `+ ${newChange.content}\n`;
291
+ }
292
+ commentBody += '```\n\n';
293
+ }
294
+ } else if (review.lineNumber) {
295
+ // 单独的删除或新增
296
+ const relatedChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
297
+ const isDeletion = relatedChange && relatedChange.type === 'deletion';
298
+
299
+ // 添加单个变更的上下文
300
+ if (relatedChange) {
301
+ commentBody += `**📝 ${isDeletion ? '删除' : '新增'}内容:**\n\`\`\`${isDeletion ? 'diff' : 'javascript'}\n`;
302
+ commentBody += `${isDeletion ? '-' : '+'} ${relatedChange.content}\n`;
303
+ commentBody += '```\n\n';
304
+ }
305
+ }
306
+
307
+ // 添加 AI 审查意见
308
+ commentBody += review.comment;
309
+
260
310
  const commentResult = await this.gitlabClient.createLineComment(
261
311
  this.config.project.projectId,
262
312
  this.config.project.mergeRequestIid,
263
- `🤖 **AI 代码审查**\n\n${review.comment}`,
313
+ commentBody,
264
314
  positionParams
265
315
  );
266
316
 
267
317
  results.push({
268
318
  status: 'success',
269
319
  fileName,
270
- lineNumber: review.lineNumber,
320
+ lineNumber: review.lineNumber || review.oldLine,
271
321
  comment: review.comment,
272
322
  commentResult,
273
323
  });
274
324
 
275
- console.log(` ✓ ${review.lineNumber} 行:已添加评论`);
325
+ const lineDesc = review.oldLine && review.newLine
326
+ ? `第 ${review.oldLine}-${review.newLine} 行(修改块)`
327
+ : `第 ${review.lineNumber} 行`;
328
+ console.log(` ✓ ${lineDesc}:已添加评论`);
276
329
  } catch (error) {
277
330
  results.push({
278
331
  status: 'error',
279
332
  fileName,
280
- lineNumber: review.lineNumber,
333
+ lineNumber: review.lineNumber || review.oldLine,
281
334
  error: error.message,
282
335
  });
283
- console.log(` ✗ ${review.lineNumber} 行:评论失败 - ${error.message}`);
336
+ const lineDesc = review.oldLine && review.newLine
337
+ ? `第 ${review.oldLine}-${review.newLine} 行`
338
+ : `第 ${review.lineNumber} 行`;
339
+ console.log(` ✗ ${lineDesc}:评论失败 - ${error.message}`);
284
340
  }
285
341
  } else {
286
- console.log(` ✓ ${review.lineNumber} 行:代码质量良好`);
342
+ const lineDesc = review.oldLine && review.newLine
343
+ ? `第 ${review.oldLine}-${review.newLine} 行`
344
+ : `第 ${review.lineNumber} 行`;
345
+ console.log(` ✓ ${lineDesc}:代码质量良好`);
287
346
  }
288
347
  }
289
348
 
@@ -511,18 +570,33 @@ export class GitLabAIReview {
511
570
  for (const review of mergedReviews) {
512
571
  if (review.hasIssue) {
513
572
  try {
514
- // 构建评论位置参数
573
+ // 找到这个评论对应的变更和它所在的 hunk
574
+ let targetChange = null;
575
+ if (review.oldLine && review.newLine) {
576
+ // 修改块:找删除或新增的任意一个
577
+ targetChange = meaningfulChanges.find(c =>
578
+ (c.lineNumber === review.oldLine && c.type === 'deletion') ||
579
+ (c.lineNumber === review.newLine && c.type === 'addition')
580
+ );
581
+ } else if (review.lineNumber) {
582
+ targetChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
583
+ }
584
+
585
+ // 构建评论位置参数 - 使用 hunk 的起始位置覆盖整个变更块
515
586
  const positionParams = {
516
587
  filePath: fileName,
517
588
  oldPath: change.old_path,
518
589
  };
519
590
 
520
- // 如果是修改块(同时有 oldLine newLine),同时指定两个行号
521
- if (review.oldLine && review.newLine) {
591
+ if (targetChange && targetChange.hunkRange) {
592
+ // 使用 hunk 的起始行号,让评论覆盖整个 hunk 范围
593
+ positionParams.oldLine = targetChange.hunkRange.oldStart;
594
+ positionParams.newLine = targetChange.hunkRange.newStart;
595
+ } else if (review.oldLine && review.newLine) {
596
+ // 如果找不到 hunk 信息,回退到原来的逻辑
522
597
  positionParams.oldLine = review.oldLine;
523
598
  positionParams.newLine = review.newLine;
524
599
  } else if (review.lineNumber) {
525
- // 单独的删除或新增
526
600
  const relatedChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
527
601
  const isDeletion = relatedChange && relatedChange.type === 'deletion';
528
602
  if (isDeletion) {
@@ -532,10 +606,45 @@ export class GitLabAIReview {
532
606
  }
533
607
  }
534
608
 
609
+ // 构建评论内容,包含完整的修改块上下文
610
+ let commentBody = '🤖 **AI 代码审查**\n\n';
611
+
612
+ // 如果是修改块(同时有 oldLine 和 newLine),显示完整的删除和新增
613
+ if (review.oldLine && review.newLine) {
614
+ // 添加修改块的上下文
615
+ const oldChange = meaningfulChanges.find(c => c.lineNumber === review.oldLine && c.type === 'deletion');
616
+ const newChange = meaningfulChanges.find(c => c.lineNumber === review.newLine && c.type === 'addition');
617
+
618
+ if (oldChange || newChange) {
619
+ commentBody += '**📝 修改内容:**\n```diff\n';
620
+ if (oldChange) {
621
+ commentBody += `- ${oldChange.content}\n`;
622
+ }
623
+ if (newChange) {
624
+ commentBody += `+ ${newChange.content}\n`;
625
+ }
626
+ commentBody += '```\n\n';
627
+ }
628
+ } else if (review.lineNumber) {
629
+ // 单独的删除或新增
630
+ const relatedChange = meaningfulChanges.find(c => c.lineNumber === review.lineNumber);
631
+ const isDeletion = relatedChange && relatedChange.type === 'deletion';
632
+
633
+ // 添加单个变更的上下文
634
+ if (relatedChange) {
635
+ commentBody += `**📝 ${isDeletion ? '删除' : '新增'}内容:**\n\`\`\`${isDeletion ? 'diff' : 'javascript'}\n`;
636
+ commentBody += `${isDeletion ? '-' : '+'} ${relatedChange.content}\n`;
637
+ commentBody += '```\n\n';
638
+ }
639
+ }
640
+
641
+ // 添加 AI 审查意见
642
+ commentBody += review.comment;
643
+
535
644
  const commentResult = await this.gitlabClient.createLineComment(
536
645
  this.config.project.projectId,
537
646
  this.config.project.mergeRequestIid,
538
- `🤖 **AI 代码审查**\n\n${review.comment}`,
647
+ commentBody,
539
648
  positionParams
540
649
  );
541
650
 
@@ -548,7 +657,7 @@ export class GitLabAIReview {
548
657
  });
549
658
 
550
659
  const lineDesc = review.oldLine && review.newLine
551
- ? `第 ${review.oldLine}-${review.newLine} 行`
660
+ ? `第 ${review.oldLine}-${review.newLine} 行(修改块)`
552
661
  : `第 ${review.lineNumber} 行`;
553
662
  console.log(` ✓ ${lineDesc}:已添加评论`);
554
663
  } catch (error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitlab-ai-review",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
4
4
  "description": "GitLab AI Review SDK with Impact Analysis - 支持影响分析、删除符号检测、注释代码识别、文件内部冲突检查、智能文件过滤的智能代码审查工具",
5
5
  "main": "index.js",
6
6
  "type": "module",