bitbucket-gemini-action 1.0.12 → 1.0.14

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/dist/cli.js CHANGED
@@ -169,16 +169,21 @@ class BitbucketClient {
169
169
  async getPullRequestCommits(workspace, repoSlug, prId) {
170
170
  return this.paginatedRequest(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/commits`);
171
171
  }
172
- async createPullRequestComment(workspace, repoSlug, prId, content, inline) {
172
+ async createPullRequestComment(workspace, repoSlug, prId, content, options) {
173
173
  const body = {
174
174
  content: {
175
175
  raw: content
176
176
  }
177
177
  };
178
- if (inline) {
178
+ if (options?.inline) {
179
179
  body.inline = {
180
- to: inline.line,
181
- path: inline.path
180
+ from: options.inline.line,
181
+ path: options.inline.path
182
+ };
183
+ }
184
+ if (options?.parentId) {
185
+ body.parent = {
186
+ id: options.parentId
182
187
  };
183
188
  }
184
189
  return this.request(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`, {
@@ -2849,19 +2854,21 @@ function detectMode(context, options) {
2849
2854
  reason: `Explicitly specified mode: ${options.mode}`
2850
2855
  };
2851
2856
  }
2857
+ if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2858
+ const tagTrigger = tagMode.shouldTrigger(context, {
2859
+ triggerPhrase: options.triggerPhrase
2860
+ });
2861
+ if (tagTrigger.shouldTrigger) {
2862
+ return {
2863
+ mode: tagMode,
2864
+ reason: "Trigger phrase detected in comment"
2865
+ };
2866
+ }
2867
+ }
2852
2868
  if (options.prompt) {
2853
2869
  return {
2854
2870
  mode: agentMode,
2855
- reason: "Explicit prompt provided"
2856
- };
2857
- }
2858
- const tagTrigger = tagMode.shouldTrigger(context, {
2859
- triggerPhrase: options.triggerPhrase
2860
- });
2861
- if (tagTrigger.shouldTrigger) {
2862
- return {
2863
- mode: tagMode,
2864
- reason: "Trigger phrase detected in comment"
2871
+ reason: "Explicit prompt provided for auto-review"
2865
2872
  };
2866
2873
  }
2867
2874
  if (context.eventType === "manual" || context.eventType === "schedule") {
@@ -2878,23 +2885,33 @@ function detectMode(context, options) {
2878
2885
 
2879
2886
  // src/bitbucket/validation/trigger.ts
2880
2887
  function validateTrigger(context, options) {
2881
- if (options.prompt) {
2888
+ if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2889
+ const commentResult = validateCommentTrigger(context.comment, options);
2890
+ if (commentResult.shouldTrigger) {
2891
+ return commentResult;
2892
+ }
2882
2893
  return {
2883
- shouldTrigger: true,
2884
- reason: "Explicit prompt provided",
2885
- triggerType: "automation",
2886
- userMessage: options.prompt
2894
+ shouldTrigger: false,
2895
+ reason: `Comment event but no trigger phrase found`
2887
2896
  };
2888
2897
  }
2889
2898
  if (context.eventType === "manual" || context.eventType === "schedule") {
2890
2899
  return {
2891
2900
  shouldTrigger: true,
2892
2901
  reason: `Triggered by ${context.eventType} event`,
2893
- triggerType: "manual"
2902
+ triggerType: "manual",
2903
+ userMessage: options.prompt
2894
2904
  };
2895
2905
  }
2896
- if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2897
- return validateCommentTrigger(context.comment, options);
2906
+ if (options.prompt) {
2907
+ if (context.eventType === "pullrequest:created" || context.eventType === "pullrequest:updated" || context.isPR) {
2908
+ return {
2909
+ shouldTrigger: true,
2910
+ reason: "Explicit prompt provided for PR event",
2911
+ triggerType: "automation",
2912
+ userMessage: options.prompt
2913
+ };
2914
+ }
2898
2915
  }
2899
2916
  return {
2900
2917
  shouldTrigger: false,
@@ -7214,6 +7231,7 @@ async function prepare() {
7214
7231
  containsTrigger: true,
7215
7232
  mode: mode.name,
7216
7233
  trackingCommentId: modeResult.trackingCommentId,
7234
+ triggerCommentId: context.comment?.id,
7217
7235
  prompt: triggerResult.userMessage || config.PROMPT || "",
7218
7236
  systemPrompt: modeResult.modeContext.systemPrompt,
7219
7237
  tools: modeResult.modeContext.tools,
@@ -8283,12 +8301,11 @@ async function updateTrackingComment(client, workspace, repoSlug, prId, commentI
8283
8301
  }
8284
8302
  async function createInlineComment(client, workspace, repoSlug, prId, filePath, line, content) {
8285
8303
  return client.createPullRequestComment(workspace, repoSlug, prId, content, {
8286
- path: filePath,
8287
- line
8304
+ inline: { path: filePath, line }
8288
8305
  });
8289
8306
  }
8290
- async function createPRComment(client, workspace, repoSlug, prId, content) {
8291
- return client.createPullRequestComment(workspace, repoSlug, prId, content);
8307
+ async function createPRComment(client, workspace, repoSlug, prId, content, parentId) {
8308
+ return client.createPullRequestComment(workspace, repoSlug, prId, content, parentId ? { parentId } : undefined);
8292
8309
  }
8293
8310
  function formatTrackingComment(content) {
8294
8311
  const statusEmoji = getStatusEmoji(content.status);
@@ -8482,16 +8499,15 @@ async function execute(options) {
8482
8499
  console.log(`✅ Gemini response received (${response.finishReason})`);
8483
8500
  let inlineCommentsCreated = 0;
8484
8501
  if (response.toolCalls && context.entityNumber) {
8485
- inlineCommentsCreated = await processToolCalls(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.toolCalls, opts.trackingCommentId);
8502
+ inlineCommentsCreated = await processToolCalls(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.toolCalls, opts.trackingCommentId, opts.triggerCommentId);
8486
8503
  }
8487
8504
  if (!response.toolCalls?.length && response.text && context.entityNumber) {
8488
- await createPRComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.text);
8505
+ await createPRComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.text, opts.triggerCommentId);
8489
8506
  }
8490
8507
  if (opts.trackingCommentId && context.entityNumber) {
8491
8508
  await updateTrackingComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, opts.trackingCommentId, {
8492
8509
  status: "completed",
8493
8510
  message: "Review completed successfully.",
8494
- summary: response.text.substring(0, 500),
8495
8511
  inlineCommentsCount: inlineCommentsCreated
8496
8512
  });
8497
8513
  }
@@ -8523,7 +8539,7 @@ async function execute(options) {
8523
8539
  };
8524
8540
  }
8525
8541
  }
8526
- async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, trackingCommentId) {
8542
+ async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, trackingCommentId, triggerCommentId) {
8527
8543
  let inlineCommentsCreated = 0;
8528
8544
  for (const toolCall of toolCalls) {
8529
8545
  console.log(`\uD83D\uDD27 Processing tool call: ${toolCall.name}`);
@@ -8537,7 +8553,7 @@ async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, tr
8537
8553
  }
8538
8554
  case "create_pr_comment": {
8539
8555
  const args = toolCall.args;
8540
- await createPRComment(client, workspace, repoSlug, prId, args.content);
8556
+ await createPRComment(client, workspace, repoSlug, prId, args.content, triggerCommentId);
8541
8557
  break;
8542
8558
  }
8543
8559
  case "update_tracking_comment": {
@@ -8571,7 +8587,8 @@ function loadPrepareOutput() {
8571
8587
  mode: data.mode || "tag",
8572
8588
  prompt: data.prompt || "",
8573
8589
  systemPrompt: data.systemPrompt || "",
8574
- trackingCommentId: data.trackingCommentId
8590
+ trackingCommentId: data.trackingCommentId,
8591
+ triggerCommentId: data.triggerCommentId
8575
8592
  };
8576
8593
  }
8577
8594
 
@@ -1113,16 +1113,21 @@ class BitbucketClient {
1113
1113
  async getPullRequestCommits(workspace, repoSlug, prId) {
1114
1114
  return this.paginatedRequest(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/commits`);
1115
1115
  }
1116
- async createPullRequestComment(workspace, repoSlug, prId, content, inline) {
1116
+ async createPullRequestComment(workspace, repoSlug, prId, content, options) {
1117
1117
  const body = {
1118
1118
  content: {
1119
1119
  raw: content
1120
1120
  }
1121
1121
  };
1122
- if (inline) {
1122
+ if (options?.inline) {
1123
1123
  body.inline = {
1124
- to: inline.line,
1125
- path: inline.path
1124
+ from: options.inline.line,
1125
+ path: options.inline.path
1126
+ };
1127
+ }
1128
+ if (options?.parentId) {
1129
+ body.parent = {
1130
+ id: options.parentId
1126
1131
  };
1127
1132
  }
1128
1133
  return this.request(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`, {
@@ -3741,12 +3746,11 @@ async function updateTrackingComment(client, workspace, repoSlug, prId, commentI
3741
3746
  }
3742
3747
  async function createInlineComment(client, workspace, repoSlug, prId, filePath, line, content) {
3743
3748
  return client.createPullRequestComment(workspace, repoSlug, prId, content, {
3744
- path: filePath,
3745
- line
3749
+ inline: { path: filePath, line }
3746
3750
  });
3747
3751
  }
3748
- async function createPRComment(client, workspace, repoSlug, prId, content) {
3749
- return client.createPullRequestComment(workspace, repoSlug, prId, content);
3752
+ async function createPRComment(client, workspace, repoSlug, prId, content, parentId) {
3753
+ return client.createPullRequestComment(workspace, repoSlug, prId, content, parentId ? { parentId } : undefined);
3750
3754
  }
3751
3755
  function formatTrackingComment(content) {
3752
3756
  const statusEmoji = getStatusEmoji(content.status);
@@ -7988,16 +7992,15 @@ async function execute(options) {
7988
7992
  console.log(`✅ Gemini response received (${response.finishReason})`);
7989
7993
  let inlineCommentsCreated = 0;
7990
7994
  if (response.toolCalls && context.entityNumber) {
7991
- inlineCommentsCreated = await processToolCalls(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.toolCalls, opts.trackingCommentId);
7995
+ inlineCommentsCreated = await processToolCalls(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.toolCalls, opts.trackingCommentId, opts.triggerCommentId);
7992
7996
  }
7993
7997
  if (!response.toolCalls?.length && response.text && context.entityNumber) {
7994
- await createPRComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.text);
7998
+ await createPRComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, response.text, opts.triggerCommentId);
7995
7999
  }
7996
8000
  if (opts.trackingCommentId && context.entityNumber) {
7997
8001
  await updateTrackingComment(bitbucketClient, context.workspace, context.repoSlug, context.entityNumber, opts.trackingCommentId, {
7998
8002
  status: "completed",
7999
8003
  message: "Review completed successfully.",
8000
- summary: response.text.substring(0, 500),
8001
8004
  inlineCommentsCount: inlineCommentsCreated
8002
8005
  });
8003
8006
  }
@@ -8029,7 +8032,7 @@ async function execute(options) {
8029
8032
  };
8030
8033
  }
8031
8034
  }
8032
- async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, trackingCommentId) {
8035
+ async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, trackingCommentId, triggerCommentId) {
8033
8036
  let inlineCommentsCreated = 0;
8034
8037
  for (const toolCall of toolCalls) {
8035
8038
  console.log(`\uD83D\uDD27 Processing tool call: ${toolCall.name}`);
@@ -8043,7 +8046,7 @@ async function processToolCalls(client, workspace, repoSlug, prId, toolCalls, tr
8043
8046
  }
8044
8047
  case "create_pr_comment": {
8045
8048
  const args = toolCall.args;
8046
- await createPRComment(client, workspace, repoSlug, prId, args.content);
8049
+ await createPRComment(client, workspace, repoSlug, prId, args.content, triggerCommentId);
8047
8050
  break;
8048
8051
  }
8049
8052
  case "update_tracking_comment": {
@@ -8077,7 +8080,8 @@ function loadPrepareOutput() {
8077
8080
  mode: data.mode || "tag",
8078
8081
  prompt: data.prompt || "",
8079
8082
  systemPrompt: data.systemPrompt || "",
8080
- trackingCommentId: data.trackingCommentId
8083
+ trackingCommentId: data.trackingCommentId,
8084
+ triggerCommentId: data.triggerCommentId
8081
8085
  };
8082
8086
  }
8083
8087
  export {
@@ -168,16 +168,21 @@ class BitbucketClient {
168
168
  async getPullRequestCommits(workspace, repoSlug, prId) {
169
169
  return this.paginatedRequest(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/commits`);
170
170
  }
171
- async createPullRequestComment(workspace, repoSlug, prId, content, inline) {
171
+ async createPullRequestComment(workspace, repoSlug, prId, content, options) {
172
172
  const body = {
173
173
  content: {
174
174
  raw: content
175
175
  }
176
176
  };
177
- if (inline) {
177
+ if (options?.inline) {
178
178
  body.inline = {
179
- to: inline.line,
180
- path: inline.path
179
+ from: options.inline.line,
180
+ path: options.inline.path
181
+ };
182
+ }
183
+ if (options?.parentId) {
184
+ body.parent = {
185
+ id: options.parentId
181
186
  };
182
187
  }
183
188
  return this.request(`/repositories/${workspace}/${repoSlug}/pullrequests/${prId}/comments`, {
@@ -2848,19 +2853,21 @@ function detectMode(context, options) {
2848
2853
  reason: `Explicitly specified mode: ${options.mode}`
2849
2854
  };
2850
2855
  }
2856
+ if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2857
+ const tagTrigger = tagMode.shouldTrigger(context, {
2858
+ triggerPhrase: options.triggerPhrase
2859
+ });
2860
+ if (tagTrigger.shouldTrigger) {
2861
+ return {
2862
+ mode: tagMode,
2863
+ reason: "Trigger phrase detected in comment"
2864
+ };
2865
+ }
2866
+ }
2851
2867
  if (options.prompt) {
2852
2868
  return {
2853
2869
  mode: agentMode,
2854
- reason: "Explicit prompt provided"
2855
- };
2856
- }
2857
- const tagTrigger = tagMode.shouldTrigger(context, {
2858
- triggerPhrase: options.triggerPhrase
2859
- });
2860
- if (tagTrigger.shouldTrigger) {
2861
- return {
2862
- mode: tagMode,
2863
- reason: "Trigger phrase detected in comment"
2870
+ reason: "Explicit prompt provided for auto-review"
2864
2871
  };
2865
2872
  }
2866
2873
  if (context.eventType === "manual" || context.eventType === "schedule") {
@@ -2877,23 +2884,33 @@ function detectMode(context, options) {
2877
2884
 
2878
2885
  // src/bitbucket/validation/trigger.ts
2879
2886
  function validateTrigger(context, options) {
2880
- if (options.prompt) {
2887
+ if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2888
+ const commentResult = validateCommentTrigger(context.comment, options);
2889
+ if (commentResult.shouldTrigger) {
2890
+ return commentResult;
2891
+ }
2881
2892
  return {
2882
- shouldTrigger: true,
2883
- reason: "Explicit prompt provided",
2884
- triggerType: "automation",
2885
- userMessage: options.prompt
2893
+ shouldTrigger: false,
2894
+ reason: `Comment event but no trigger phrase found`
2886
2895
  };
2887
2896
  }
2888
2897
  if (context.eventType === "manual" || context.eventType === "schedule") {
2889
2898
  return {
2890
2899
  shouldTrigger: true,
2891
2900
  reason: `Triggered by ${context.eventType} event`,
2892
- triggerType: "manual"
2901
+ triggerType: "manual",
2902
+ userMessage: options.prompt
2893
2903
  };
2894
2904
  }
2895
- if (context.eventType === "pullrequest:comment_created" || context.eventType === "pullrequest:comment_updated") {
2896
- return validateCommentTrigger(context.comment, options);
2905
+ if (options.prompt) {
2906
+ if (context.eventType === "pullrequest:created" || context.eventType === "pullrequest:updated" || context.isPR) {
2907
+ return {
2908
+ shouldTrigger: true,
2909
+ reason: "Explicit prompt provided for PR event",
2910
+ triggerType: "automation",
2911
+ userMessage: options.prompt
2912
+ };
2913
+ }
2897
2914
  }
2898
2915
  return {
2899
2916
  shouldTrigger: false,
@@ -7213,6 +7230,7 @@ async function prepare() {
7213
7230
  containsTrigger: true,
7214
7231
  mode: mode.name,
7215
7232
  trackingCommentId: modeResult.trackingCommentId,
7233
+ triggerCommentId: context.comment?.id,
7216
7234
  prompt: triggerResult.userMessage || config.PROMPT || "",
7217
7235
  systemPrompt: modeResult.modeContext.systemPrompt,
7218
7236
  tools: modeResult.modeContext.tools,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitbucket-gemini-action",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "Bitbucket Pipeline action for AI-powered code review using Google Gemini",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",