@bragduck/cli 2.36.4 → 2.37.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.
package/README.md CHANGED
@@ -212,8 +212,6 @@ bragduck config set autoVersionCheck false
212
212
  - `defaultCommitDays` - Default days to scan (1-365, default: 30)
213
213
  - `autoVersionCheck` - Automatic version checking (true/false, default: true)
214
214
 
215
- **Note:** The API base URL is set to `https://api.bragduck.com` by default. You can override it using the `API_BASE_URL` environment variable if needed for custom deployments.
216
-
217
215
  #### `bragduck logout`
218
216
 
219
217
  Clear stored credentials from your system.
@@ -276,8 +274,6 @@ Configuration is stored in `~/.config/bragduck/config.json` (or equivalent on yo
276
274
  | `defaultCommitDays` | number | `30` | Default days to scan (1-365) |
277
275
  | `autoVersionCheck` | boolean | `true` | Automatic version checking |
278
276
 
279
- **API Base URL:** The CLI connects to `https://api.bragduck.com` by default. For custom deployments, set the `API_BASE_URL` environment variable.
280
-
281
277
  ### Credentials Storage
282
278
 
283
279
  Credentials are encrypted and stored at:
@@ -38,7 +38,8 @@ var init_constants = __esm({
38
38
  SOURCE_PRIORITY: "sourcePriority",
39
39
  JIRA_INSTANCE: "jiraInstance",
40
40
  CONFLUENCE_INSTANCE: "confluenceInstance",
41
- GITLAB_INSTANCE: "gitlabInstance"
41
+ GITLAB_INSTANCE: "gitlabInstance",
42
+ DEFAULT_COMPANY: "defaultCompany"
42
43
  };
43
44
  DEFAULT_CONFIG = {
44
45
  defaultCommitDays: 30,
@@ -47,7 +48,8 @@ var init_constants = __esm({
47
48
  sourcePriority: void 0,
48
49
  jiraInstance: void 0,
49
50
  confluenceInstance: void 0,
50
- gitlabInstance: void 0
51
+ gitlabInstance: void 0,
52
+ defaultCompany: void 0
51
53
  };
52
54
  OAUTH_CONFIG = {
53
55
  CLIENT_ID: "bragduck-cli",
@@ -1475,7 +1477,7 @@ var init_api_service = __esm({
1475
1477
  logger.debug("Token refreshed, retrying request");
1476
1478
  throw new Error("RETRY_WITH_NEW_TOKEN");
1477
1479
  } catch (error) {
1478
- if (error.message === "RETRY_WITH_NEW_TOKEN") {
1480
+ if (error instanceof Error && error.message === "RETRY_WITH_NEW_TOKEN") {
1479
1481
  throw error;
1480
1482
  }
1481
1483
  throw new TokenExpiredError(
@@ -1512,13 +1514,15 @@ var init_api_service = __esm({
1512
1514
  try {
1513
1515
  return await this.client(url, options);
1514
1516
  } catch (error) {
1515
- if (error.message === "RETRY_WITH_NEW_TOKEN") {
1517
+ if (error instanceof Error && error.message === "RETRY_WITH_NEW_TOKEN") {
1516
1518
  logger.debug("Retrying request with refreshed token");
1517
1519
  return await this.client(url, options);
1518
1520
  }
1519
- if (error.name === "FetchError" || error.code === "ECONNREFUSED") {
1521
+ const err = error instanceof Error ? error : new Error(String(error));
1522
+ const errCode = "code" in err ? err.code : void 0;
1523
+ if (err.name === "FetchError" || errCode === "ECONNREFUSED") {
1520
1524
  throw new NetworkError("Failed to connect to Bragduck API", {
1521
- originalError: error.message,
1525
+ originalError: err.message,
1522
1526
  baseURL: this.baseURL
1523
1527
  });
1524
1528
  }
@@ -1800,9 +1804,10 @@ var AtlassianAuthService = class {
1800
1804
  logger.debug("Atlassian token exchange successful");
1801
1805
  return response;
1802
1806
  } catch (error) {
1803
- logger.debug(`Atlassian token exchange failed: ${error.message}`);
1807
+ const message = error instanceof Error ? error.message : String(error);
1808
+ logger.debug(`Atlassian token exchange failed: ${message}`);
1804
1809
  throw new AtlassianError("Failed to exchange Atlassian authorization code", {
1805
- originalError: error.message
1810
+ originalError: message
1806
1811
  });
1807
1812
  }
1808
1813
  }
@@ -1824,9 +1829,10 @@ var AtlassianAuthService = class {
1824
1829
  logger.debug(`Found ${resources.length} accessible resource(s)`);
1825
1830
  return resources;
1826
1831
  } catch (error) {
1827
- logger.debug(`Failed to fetch accessible resources: ${error.message}`);
1832
+ const message = error instanceof Error ? error.message : String(error);
1833
+ logger.debug(`Failed to fetch accessible resources: ${message}`);
1828
1834
  throw new AtlassianError("Failed to fetch Atlassian Cloud sites", {
1829
- originalError: error.message
1835
+ originalError: message
1830
1836
  });
1831
1837
  }
1832
1838
  }
@@ -5886,6 +5892,10 @@ function formatSuccessMessage(count, brags) {
5886
5892
  const dateFormatted = formatDate(brag.date);
5887
5893
  bragsList += `
5888
5894
  ${colors.dim("\u2022")} ${colors.white(brag.title)} ${theme.secondary(`(${dateFormatted} \xB7 ${sourceLabel})`)}`;
5895
+ if (brag.url) {
5896
+ bragsList += `
5897
+ ${colors.info(brag.url)}`;
5898
+ }
5889
5899
  }
5890
5900
  }
5891
5901
  const hint = theme.secondary("\n\nRun ") + theme.command("bragduck list") + theme.secondary(" to see all your brags");
@@ -6968,8 +6978,7 @@ async function syncSingleService(sourceType, options, TOTAL_STEPS, sharedDays, s
6968
6978
  date: originalCommit?.date || (/* @__PURE__ */ new Date()).toISOString(),
6969
6979
  commit_url: originalCommit?.url || "",
6970
6980
  impactLevel: refined.suggested_impactLevel,
6971
- typeId: refined.suggested_typeId,
6972
- impact_score: refined.suggested_impactLevel,
6981
+ typeKey: refined.suggested_type_key,
6973
6982
  impactDescription: refined.impact_description,
6974
6983
  impact_description: refined.impact_description,
6975
6984
  attachments: originalCommit?.url ? [originalCommit.url] : [],
@@ -7011,7 +7020,8 @@ async function syncSingleService(sourceType, options, TOTAL_STEPS, sharedDays, s
7011
7020
  const createdBrags = createResponse.brags.map((brag, index) => ({
7012
7021
  title: brag.title,
7013
7022
  date: selectedCommits[index]?.date || (/* @__PURE__ */ new Date()).toISOString(),
7014
- source: sourceType
7023
+ source: sourceType,
7024
+ url: brag.url
7015
7025
  }));
7016
7026
  return { created: createResponse.created, skipped: duplicates.length, createdBrags };
7017
7027
  }
@@ -7549,6 +7559,32 @@ async function listCommand(options = {}) {
7549
7559
  if (!isAuthenticated) {
7550
7560
  process.exit(1);
7551
7561
  }
7562
+ const subSpinner = createValidateSpinner("Checking subscription...");
7563
+ subSpinner.start();
7564
+ let subscriptionStatus;
7565
+ try {
7566
+ subscriptionStatus = await apiService.getSubscriptionStatus();
7567
+ } catch (error) {
7568
+ failSpinner(subSpinner, "Failed to check subscription");
7569
+ throw error;
7570
+ }
7571
+ if (subscriptionStatus.tier === "FREE") {
7572
+ failSpinner(subSpinner, "Free plan \u2014 upgrade to use the CLI");
7573
+ logger.log("");
7574
+ logger.log(
7575
+ boxen7(
7576
+ theme.warning("CLI Access Requires Subscription") + "\n\nThe BragDuck CLI is available for Plus and Pro subscribers.\nUpgrade now to unlock:\n\n \u2022 List and manage your brags from the terminal\n \u2022 Automatic work item scanning\n \u2022 AI-powered brag generation\n\n" + colors.highlight("Upgrade at: https://bragduck.com/app/settings/plans"),
7577
+ {
7578
+ ...boxStyles.warning,
7579
+ padding: 1,
7580
+ margin: 1
7581
+ }
7582
+ )
7583
+ );
7584
+ logger.log("");
7585
+ return;
7586
+ }
7587
+ subSpinner.stop();
7552
7588
  const limit = options.limit || 50;
7553
7589
  const offset = options.offset || 0;
7554
7590
  const tags = options.tags ? options.tags.split(",").map((t) => t.trim()) : void 0;
@@ -7638,12 +7674,31 @@ function formatBragsTable(brags) {
7638
7674
  colors.info(repository)
7639
7675
  ]);
7640
7676
  });
7641
- return table.toString();
7677
+ const links = formatBragLinks(brags);
7678
+ return table.toString() + (links ? "\n\n" + links : "");
7679
+ }
7680
+ function formatBragLinks(brags) {
7681
+ const lines = brags.filter((brag) => brag.url || brag.goalIds && brag.goalIds.length > 0).map((brag) => {
7682
+ const parts = [` ${colors.white(brag.title)}`];
7683
+ if (brag.url) {
7684
+ parts.push(` ${colors.info(brag.url)}`);
7685
+ }
7686
+ if (brag.goalIds && brag.goalIds.length > 0) {
7687
+ parts.push(` ${colors.dim("Linked to key result:")} ${colors.primary(brag.goalIds[0])}`);
7688
+ }
7689
+ return parts.join("\n");
7690
+ });
7691
+ if (lines.length === 0) return "";
7692
+ return colors.primary("Brag links:") + "\n" + lines.join("\n\n");
7642
7693
  }
7643
7694
  function formatBragsOneline(brags) {
7644
7695
  return brags.map((brag) => {
7645
7696
  const date = formatDate(brag.date);
7646
- return `${colors.highlight(date)} ${colors.white(brag.title)}`;
7697
+ const urlLine = brag.url ? `
7698
+ ${colors.info(brag.url)}` : "";
7699
+ const goalLine = brag.goalIds && brag.goalIds.length > 0 ? `
7700
+ ${colors.dim("Linked to key result:")} ${colors.primary(brag.goalIds[0])}` : "";
7701
+ return `${colors.highlight(date)} ${colors.white(brag.title)}${urlLine}${goalLine}`;
7647
7702
  }).join("\n");
7648
7703
  }
7649
7704
  function truncateText(text, maxLength) {
@@ -7899,7 +7954,7 @@ Must be a valid hostname (e.g., company.atlassian.net, gitlab.company.com)`
7899
7954
  }
7900
7955
  }
7901
7956
  function getConfigHint(error) {
7902
- if (error.name === "ValidationError") {
7957
+ if (error instanceof Error && error.name === "ValidationError") {
7903
7958
  return 'Run "bragduck config list" to see all available configuration keys';
7904
7959
  }
7905
7960
  return 'Run "bragduck config --help" for usage information';