@bragduck/cli 2.37.0 → 2.38.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.
@@ -4275,6 +4275,13 @@ init_errors();
4275
4275
  init_logger();
4276
4276
  init_storage_service();
4277
4277
  init_constants();
4278
+ function adfToText(node) {
4279
+ if (!node) return "";
4280
+ if (typeof node === "string") return node;
4281
+ if (node.text) return node.text;
4282
+ if (node.content) return node.content.map(adfToText).join("");
4283
+ return "";
4284
+ }
4278
4285
  var JiraService = class {
4279
4286
  MAX_DESCRIPTION_LENGTH = 5e3;
4280
4287
  /**
@@ -4469,9 +4476,10 @@ var JiraService = class {
4469
4476
  * Determine the type of contribution the current user made to an issue
4470
4477
  * Returns: 'created' | 'reported' | 'assigned-resolved' | 'edited'
4471
4478
  */
4472
- async determineJiraContributionType(issue, userEmail) {
4473
- const isCreator = issue.fields.creator.emailAddress === userEmail;
4474
- const isReporter = issue.fields.reporter?.emailAddress === userEmail;
4479
+ async determineJiraContributionType(issue, userIdentifier) {
4480
+ const matchesUser = (person) => !!person && (person.accountId === userIdentifier || person.emailAddress === userIdentifier);
4481
+ const isCreator = matchesUser(issue.fields.creator);
4482
+ const isReporter = matchesUser(issue.fields.reporter);
4475
4483
  if (isCreator) {
4476
4484
  return {
4477
4485
  type: "created",
@@ -4484,9 +4492,9 @@ var JiraService = class {
4484
4492
  details: `Reported ${issue.fields.issuetype.name}: ${issue.fields.status.name}`
4485
4493
  };
4486
4494
  }
4487
- const isAssigned = issue.fields.assignee?.emailAddress === userEmail;
4495
+ const isAssigned = matchesUser(issue.fields.assignee);
4488
4496
  const isResolved = issue.fields.resolutiondate !== null && issue.fields.resolutiondate !== void 0;
4489
- const userEdits = issue.changelog?.histories?.filter((history) => history.author.emailAddress === userEmail) || [];
4497
+ const userEdits = issue.changelog?.histories?.filter((history) => matchesUser(history.author)) || [];
4490
4498
  const hasEdits = userEdits.length > 0;
4491
4499
  if (isAssigned && isResolved) {
4492
4500
  return {
@@ -4558,7 +4566,7 @@ var JiraService = class {
4558
4566
  );
4559
4567
  break;
4560
4568
  }
4561
- const endpoint = `/rest/api/3/search/jql?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(",")}`;
4569
+ const endpoint = `/rest/api/3/search?jql=${encodeURIComponent(jql)}&startAt=${startAt}&maxResults=${maxResults}&fields=${fields.join(",")}`;
4562
4570
  try {
4563
4571
  const response = await this.request(endpoint);
4564
4572
  if (response.issues.length === 0) {
@@ -4663,7 +4671,8 @@ var JiraService = class {
4663
4671
 
4664
4672
  ${contribution.details}`;
4665
4673
  if (contribution.type === "created" && issue.fields.description) {
4666
- const truncatedDesc = issue.fields.description.substring(0, this.MAX_DESCRIPTION_LENGTH);
4674
+ const plainDesc = adfToText(issue.fields.description);
4675
+ const truncatedDesc = plainDesc.substring(0, this.MAX_DESCRIPTION_LENGTH);
4667
4676
  message = `${contributionPrefix}${issue.fields.summary}
4668
4677
 
4669
4678
  ${truncatedDesc}
@@ -4673,7 +4682,8 @@ ${contribution.details}`;
4673
4682
  } else {
4674
4683
  message = issue.fields.summary;
4675
4684
  if (issue.fields.description) {
4676
- const truncatedDesc = issue.fields.description.substring(0, this.MAX_DESCRIPTION_LENGTH);
4685
+ const plainDesc = adfToText(issue.fields.description);
4686
+ const truncatedDesc = plainDesc.substring(0, this.MAX_DESCRIPTION_LENGTH);
4677
4687
  message = `${issue.fields.summary}
4678
4688
 
4679
4689
  ${truncatedDesc}`;
@@ -4921,16 +4931,13 @@ var ConfluenceService = class {
4921
4931
  }
4922
4932
  /**
4923
4933
  * Build CQL query from options
4924
- * Returns empty string if no filters need CQL (will use simple endpoint instead)
4934
+ * Always returns a CQL string with at least a user filter so we never return all pages.
4925
4935
  */
4926
4936
  buildCQL(options) {
4927
- if (!options.days && !options.author && !options.cql) {
4928
- return "";
4929
- }
4930
4937
  const queries = [];
4931
4938
  queries.push("type = page");
4932
4939
  if (options.days) {
4933
- queries.push(`lastModified > startOfDay("-${options.days}d")`);
4940
+ queries.push(`lastmodified > startOfDay("-${options.days}d")`);
4934
4941
  }
4935
4942
  if (options.author) {
4936
4943
  const escapedAuthor = options.author.replace(/"/g, '\\"');
@@ -4954,17 +4961,16 @@ var ConfluenceService = class {
4954
4961
  * Determine the type of contribution the current user made to a page
4955
4962
  * Returns: 'created' | 'edited' | 'commented'
4956
4963
  */
4957
- async determineContributionType(page, userEmail) {
4958
- if (page.history?.createdBy?.email === userEmail) {
4964
+ async determineContributionType(page, userIdentifier) {
4965
+ const matchesUser = (by) => !!by && (by.accountId === userIdentifier || by.email === userIdentifier);
4966
+ if (matchesUser(page.history?.createdBy)) {
4959
4967
  return {
4960
4968
  type: "created",
4961
4969
  details: `Created page with ${page.version?.number || 1} version${(page.version?.number || 1) > 1 ? "s" : ""}`
4962
4970
  };
4963
4971
  }
4964
- const hasEdits = page.version?.by?.email === userEmail && (page.version?.number || 0) > 1;
4965
- const userComments = page.children?.comment?.results?.filter(
4966
- (comment) => comment.version?.by?.email === userEmail
4967
- ) || [];
4972
+ const hasEdits = matchesUser(page.version?.by) && (page.version?.number || 0) > 1;
4973
+ const userComments = page.children?.comment?.results?.filter((comment) => matchesUser(comment.version?.by)) || [];
4968
4974
  const hasComments = userComments.length > 0;
4969
4975
  if (hasEdits && hasComments) {
4970
4976
  return {
@@ -5008,9 +5014,7 @@ var ConfluenceService = class {
5008
5014
  */
5009
5015
  async getPages(options = {}) {
5010
5016
  const cql = this.buildCQL(options);
5011
- if (cql) {
5012
- logger.debug(`Using CQL query: ${cql}`);
5013
- }
5017
+ logger.debug(`Using CQL query: ${cql}`);
5014
5018
  const allPages = [];
5015
5019
  const seenPageIds = /* @__PURE__ */ new Set();
5016
5020
  let start = 0;
@@ -5025,29 +5029,14 @@ var ConfluenceService = class {
5025
5029
  );
5026
5030
  break;
5027
5031
  }
5028
- let endpoint;
5029
- let params;
5030
- if (cql) {
5031
- params = {
5032
- cql,
5033
- start: start.toString(),
5034
- limit: limit.toString(),
5035
- expand: "version,history,children.comment,body.storage"
5036
- };
5037
- const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
5038
- endpoint = `/wiki/rest/api/content/search?${queryString}`;
5039
- } else {
5040
- logger.debug("Using simple content list (no CQL filters)");
5041
- params = {
5042
- type: "page",
5043
- status: "current",
5044
- start: start.toString(),
5045
- limit: limit.toString(),
5046
- expand: "version,history,children.comment,body.storage"
5047
- };
5048
- const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
5049
- endpoint = `/wiki/rest/api/content?${queryString}`;
5050
- }
5032
+ const params = {
5033
+ cql,
5034
+ start: start.toString(),
5035
+ limit: limit.toString(),
5036
+ expand: "version,history,children.comment,body.storage"
5037
+ };
5038
+ const queryString = Object.entries(params).map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`).join("&");
5039
+ const endpoint = `/wiki/rest/api/content/search?${queryString}`;
5051
5040
  try {
5052
5041
  const response = await this.request(endpoint);
5053
5042
  if (response.results.length === 0) {
@@ -5892,6 +5881,10 @@ function formatSuccessMessage(count, brags) {
5892
5881
  const dateFormatted = formatDate(brag.date);
5893
5882
  bragsList += `
5894
5883
  ${colors.dim("\u2022")} ${colors.white(brag.title)} ${theme.secondary(`(${dateFormatted} \xB7 ${sourceLabel})`)}`;
5884
+ if (brag.url) {
5885
+ bragsList += `
5886
+ ${colors.info(brag.url)}`;
5887
+ }
5895
5888
  }
5896
5889
  }
5897
5890
  const hint = theme.secondary("\n\nRun ") + theme.command("bragduck list") + theme.secondary(" to see all your brags");
@@ -6977,7 +6970,7 @@ async function syncSingleService(sourceType, options, TOTAL_STEPS, sharedDays, s
6977
6970
  typeKey: refined.suggested_type_key,
6978
6971
  impactDescription: refined.impact_description,
6979
6972
  impact_description: refined.impact_description,
6980
- attachments: originalCommit?.url ? [originalCommit.url] : [],
6973
+ attachments: [],
6981
6974
  orgId: selectedOrgId || void 0,
6982
6975
  // External fields for non-git sources (Jira, Confluence, etc.)
6983
6976
  externalId: originalCommit?.externalId,
@@ -7016,7 +7009,8 @@ async function syncSingleService(sourceType, options, TOTAL_STEPS, sharedDays, s
7016
7009
  const createdBrags = createResponse.brags.map((brag, index) => ({
7017
7010
  title: brag.title,
7018
7011
  date: selectedCommits[index]?.date || (/* @__PURE__ */ new Date()).toISOString(),
7019
- source: sourceType
7012
+ source: sourceType,
7013
+ url: brag.url
7020
7014
  }));
7021
7015
  return { created: createResponse.created, skipped: duplicates.length, createdBrags };
7022
7016
  }