@bragduck/cli 2.27.2 → 2.28.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.
@@ -3657,6 +3657,7 @@ var JiraService = class {
3657
3657
  * Check if a user object matches the given identifier (accountId, email, or username)
3658
3658
  */
3659
3659
  isMatchingUser(candidate, userIdentifier) {
3660
+ if (!candidate) return false;
3660
3661
  return candidate.email === userIdentifier || candidate.emailAddress === userIdentifier || candidate.accountId === userIdentifier || candidate.username === userIdentifier || candidate.name === userIdentifier;
3661
3662
  }
3662
3663
  /**
@@ -3736,7 +3737,7 @@ var JiraService = class {
3736
3737
  }
3737
3738
  const isAssigned = issue.fields.assignee?.emailAddress === userEmail;
3738
3739
  const isResolved = issue.fields.resolutiondate !== null && issue.fields.resolutiondate !== void 0;
3739
- const userEdits = issue.changelog?.histories?.filter((history) => history.author.emailAddress === userEmail) || [];
3740
+ const userEdits = issue.changelog?.histories?.filter((history) => history.author?.emailAddress === userEmail) || [];
3740
3741
  const hasEdits = userEdits.length > 0;
3741
3742
  if (isAssigned && isResolved) {
3742
3743
  return {
@@ -3771,6 +3772,77 @@ var JiraService = class {
3771
3772
  };
3772
3773
  return Math.ceil(baseComplexity * multipliers[contributionType]);
3773
3774
  }
3775
+ /**
3776
+ * Summarize the user's specific changes from changelog entries into human-readable lines.
3777
+ * This enriches the brag message so the AI refinement can generate a more specific brag.
3778
+ */
3779
+ summarizeUserChanges(userChanges) {
3780
+ const MAX_LINES = 10;
3781
+ const allItems = [];
3782
+ for (const entry of userChanges) {
3783
+ for (const item of entry.items) {
3784
+ allItems.push(item);
3785
+ }
3786
+ }
3787
+ if (allItems.length === 0) return "";
3788
+ const latestByField = /* @__PURE__ */ new Map();
3789
+ for (const item of allItems) {
3790
+ latestByField.set(item.field, { fromString: item.fromString, toString: item.toString });
3791
+ }
3792
+ const lines = [];
3793
+ for (const [field, change] of latestByField) {
3794
+ if (lines.length >= MAX_LINES) break;
3795
+ const from = change.fromString || "";
3796
+ const to = change.toString || "";
3797
+ switch (field.toLowerCase()) {
3798
+ case "status":
3799
+ lines.push(from ? `Moved status from '${from}' to '${to}'` : `Set status to '${to}'`);
3800
+ break;
3801
+ case "resolution":
3802
+ lines.push(to ? `Resolved as '${to}'` : "Reopened issue");
3803
+ break;
3804
+ case "assignee":
3805
+ lines.push(to ? `Assigned to ${to}` : "Unassigned");
3806
+ break;
3807
+ case "priority":
3808
+ lines.push(
3809
+ from ? `Changed priority from '${from}' to '${to}'` : `Set priority to '${to}'`
3810
+ );
3811
+ break;
3812
+ case "summary":
3813
+ lines.push("Updated issue title");
3814
+ break;
3815
+ case "description":
3816
+ lines.push("Updated description");
3817
+ break;
3818
+ case "comment":
3819
+ lines.push("Added comment");
3820
+ break;
3821
+ case "labels":
3822
+ lines.push(to ? `Updated labels: ${to}` : "Removed labels");
3823
+ break;
3824
+ case "fix version":
3825
+ case "fixversions":
3826
+ lines.push(to ? `Set fix version: ${to}` : "Removed fix version");
3827
+ break;
3828
+ case "sprint":
3829
+ lines.push(to ? `Moved to sprint: ${to}` : "Removed from sprint");
3830
+ break;
3831
+ case "story points":
3832
+ case "story point estimate":
3833
+ lines.push(`Set story points to ${to}`);
3834
+ break;
3835
+ default:
3836
+ if (to) {
3837
+ lines.push(`Updated ${field}`);
3838
+ }
3839
+ break;
3840
+ }
3841
+ }
3842
+ if (lines.length === 0) return "";
3843
+ return `User changes:
3844
+ ${lines.map((l) => `- ${l}`).join("\n")}`;
3845
+ }
3774
3846
  /**
3775
3847
  * Fetch issues with optional filtering
3776
3848
  */
@@ -3933,6 +4005,14 @@ ${contribution.details}`;
3933
4005
  ${truncatedDesc}`;
3934
4006
  }
3935
4007
  }
4008
+ if (userChanges && userChanges.length > 0) {
4009
+ const changeSummary = this.summarizeUserChanges(userChanges);
4010
+ if (changeSummary) {
4011
+ message += `
4012
+
4013
+ ${changeSummary}`;
4014
+ }
4015
+ }
3936
4016
  let date;
3937
4017
  if (contribution?.type === "created" || contribution?.type === "reported") {
3938
4018
  date = issue.fields.created;
@@ -4133,6 +4213,7 @@ var ConfluenceService = class {
4133
4213
  * Check if a user object matches the given identifier (accountId, email, or username)
4134
4214
  */
4135
4215
  isMatchingUser(candidate, userIdentifier) {
4216
+ if (!candidate) return false;
4136
4217
  return candidate.email === userIdentifier || candidate.emailAddress === userIdentifier || candidate.accountId === userIdentifier || candidate.username === userIdentifier || candidate.name === userIdentifier;
4137
4218
  }
4138
4219
  /**
@@ -4269,6 +4350,31 @@ var ConfluenceService = class {
4269
4350
  };
4270
4351
  return Math.ceil(baseSize * multipliers[contributionType]);
4271
4352
  }
4353
+ /**
4354
+ * Summarize the user's version edits into human-readable lines.
4355
+ * This enriches the brag message so the AI refinement can generate a more specific brag.
4356
+ */
4357
+ summarizeUserVersions(userVersions) {
4358
+ const MAX_ENTRIES = 5;
4359
+ const versionsWithMessages = userVersions.filter((v) => v.message && v.message.trim());
4360
+ if (versionsWithMessages.length > 0) {
4361
+ const lines = versionsWithMessages.slice(0, MAX_ENTRIES).map((v) => {
4362
+ const suffix = v.minorEdit ? " (minor edit)" : "";
4363
+ return `- v${v.number}: ${v.message.trim()}${suffix}`;
4364
+ });
4365
+ return `Edit notes:
4366
+ ${lines.join("\n")}`;
4367
+ }
4368
+ if (userVersions.length > 0) {
4369
+ const major = userVersions.filter((v) => !v.minorEdit).length;
4370
+ const minor = userVersions.filter((v) => v.minorEdit).length;
4371
+ const parts = [];
4372
+ if (major > 0) parts.push(`${major} major`);
4373
+ if (minor > 0) parts.push(`${minor} minor`);
4374
+ return `Made ${userVersions.length} edit${userVersions.length > 1 ? "s" : ""} to this page (${parts.join(", ")})`;
4375
+ }
4376
+ return "";
4377
+ }
4272
4378
  /**
4273
4379
  * Fetch pages with optional filtering
4274
4380
  */
@@ -4425,6 +4531,14 @@ ${contribution.details}
4425
4531
 
4426
4532
  [Confluence Page v${page.version?.number || 1}]`;
4427
4533
  }
4534
+ if (userVersions && userVersions.length > 0) {
4535
+ const versionSummary = this.summarizeUserVersions(userVersions);
4536
+ if (versionSummary) {
4537
+ message += `
4538
+
4539
+ ${versionSummary}`;
4540
+ }
4541
+ }
4428
4542
  let baseUrl = "https://confluence.atlassian.net";
4429
4543
  if (instanceUrl) {
4430
4544
  baseUrl = instanceUrl.startsWith("http") ? instanceUrl : `https://${instanceUrl}`;