@bragduck/cli 2.0.3 → 2.0.23

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.
@@ -29,7 +29,7 @@ var init_constants = __esm({
29
29
  init_esm_shims();
30
30
  __filename = fileURLToPath2(import.meta.url);
31
31
  __dirname = dirname(__filename);
32
- config({ path: join(__dirname, "..", "..", ".env") });
32
+ config({ path: join(__dirname, "..", "..", ".env"), debug: false, quiet: true });
33
33
  APP_NAME = "bragduck";
34
34
  CONFIG_KEYS = {
35
35
  DEFAULT_COMMIT_DAYS: "defaultCommitDays",
@@ -52,14 +52,21 @@ var init_constants = __esm({
52
52
  INITIATE: "/v1/auth/cli/initiate",
53
53
  TOKEN: "/v1/auth/cli/token"
54
54
  },
55
- COMMITS: {
56
- REFINE: "/v1/commits/refine"
57
- },
58
55
  BRAGS: {
59
56
  CREATE: "/v1/brags",
60
- LIST: "/v1/brags"
57
+ LIST: "/v1/brags",
58
+ REFINE: "/v1/brags/refine"
59
+ },
60
+ SUBSCRIPTION: {
61
+ STATUS: "/v1/subscriptions/status"
61
62
  },
62
- VERSION: "/v1/cli/version"
63
+ VERSION: "/v1/cli/version",
64
+ /**
65
+ * @deprecated Use BRAGS.REFINE instead
66
+ */
67
+ COMMITS: {
68
+ REFINE: "/v1/commits/refine"
69
+ }
63
70
  };
64
71
  ENCRYPTION_CONFIG = {
65
72
  ALGORITHM: "aes-256-gcm",
@@ -522,7 +529,9 @@ async function startOAuthCallbackServer(expectedState) {
522
529
  reject(new OAuthError(`OAuth server error: ${error.message}`));
523
530
  });
524
531
  server.listen(port, "127.0.0.1", () => {
525
- logger.debug(`OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`);
532
+ logger.debug(
533
+ `OAuth callback server listening on http://127.0.0.1:${port}${OAUTH_CONFIG.CALLBACK_PATH}`
534
+ );
526
535
  });
527
536
  timeoutId = globalThis.setTimeout(() => {
528
537
  logger.debug("OAuth callback timeout");
@@ -683,10 +692,8 @@ async function openBrowser(url) {
683
692
  logger.debug("Browser opened successfully");
684
693
  } catch (error) {
685
694
  logger.debug(`Failed to open browser: ${error}`);
686
- throw new Error(
687
- `Failed to open browser automatically. Please open this URL manually:
688
- ${url}`
689
- );
695
+ throw new Error(`Failed to open browser automatically. Please open this URL manually:
696
+ ${url}`);
690
697
  }
691
698
  }
692
699
  var execAsync;
@@ -1066,22 +1073,29 @@ var init_api_service = __esm({
1066
1073
  // Request interceptor
1067
1074
  onRequest: async ({ options }) => {
1068
1075
  const extendedOptions = options;
1069
- logger.debug(`API Request: ${options.method} ${extendedOptions.baseURL}${extendedOptions.url}`);
1076
+ logger.debug(
1077
+ `API Request: ${options.method} ${extendedOptions.baseURL}${extendedOptions.url}`
1078
+ );
1070
1079
  const cliVersion = getCliVersion();
1071
1080
  const platform = getPlatformInfo();
1072
1081
  const userAgent = `BragDuck-CLI/${cliVersion} (${platform})`;
1073
1082
  const token = await authService.getAccessToken();
1074
- const headers = {
1075
- ...options.headers,
1083
+ const newHeaders = {
1076
1084
  "User-Agent": userAgent
1077
1085
  };
1086
+ if (options.headers) {
1087
+ const existingHeaders = new Headers(options.headers);
1088
+ existingHeaders.forEach((value, key) => {
1089
+ newHeaders[key] = value;
1090
+ });
1091
+ }
1078
1092
  if (token) {
1079
- headers.Authorization = `Bearer ${token}`;
1093
+ newHeaders.Authorization = `Bearer ${token}`;
1080
1094
  }
1081
1095
  if (options.method && ["POST", "PUT", "PATCH"].includes(options.method)) {
1082
- headers["Content-Type"] = "application/json";
1096
+ newHeaders["Content-Type"] = "application/json";
1083
1097
  }
1084
- options.headers = headers;
1098
+ options.headers = newHeaders;
1085
1099
  },
1086
1100
  // Response interceptor for success
1087
1101
  onResponse: ({ response }) => {
@@ -1103,7 +1117,9 @@ var init_api_service = __esm({
1103
1117
  if (error.message === "RETRY_WITH_NEW_TOKEN") {
1104
1118
  throw error;
1105
1119
  }
1106
- throw new TokenExpiredError('Your session has expired. Please run "bragduck init" to login again.');
1120
+ throw new TokenExpiredError(
1121
+ 'Your session has expired. Please run "bragduck init" to login again.'
1122
+ );
1107
1123
  }
1108
1124
  }
1109
1125
  let errorMessage = "An unexpected error occurred";
@@ -1149,18 +1165,34 @@ var init_api_service = __esm({
1149
1165
  }
1150
1166
  }
1151
1167
  /**
1152
- * Refine commits using AI
1168
+ * Refine brags using AI
1169
+ */
1170
+ async refineBrags(request) {
1171
+ logger.debug(`Refining ${request.brags.length} brags`);
1172
+ try {
1173
+ const response = await this.makeRequest(API_ENDPOINTS.BRAGS.REFINE, {
1174
+ method: "POST",
1175
+ body: request
1176
+ });
1177
+ logger.debug(`Successfully refined ${response.refined_brags.length} brags`);
1178
+ return response;
1179
+ } catch (_error) {
1180
+ logger.debug("Failed to refine brags");
1181
+ throw _error;
1182
+ }
1183
+ }
1184
+ /**
1185
+ * @deprecated Use refineBrags() instead. Will be removed in v3.0.0
1186
+ * Refine commits using AI (legacy endpoint)
1153
1187
  */
1154
1188
  async refineCommits(request) {
1189
+ logger.debug(`[DEPRECATED] Using legacy refineCommits - migrate to refineBrags`);
1155
1190
  logger.debug(`Refining ${request.commits.length} commits`);
1156
1191
  try {
1157
- const response = await this.makeRequest(
1158
- API_ENDPOINTS.COMMITS.REFINE,
1159
- {
1160
- method: "POST",
1161
- body: request
1162
- }
1163
- );
1192
+ const response = await this.makeRequest(API_ENDPOINTS.COMMITS.REFINE, {
1193
+ method: "POST",
1194
+ body: request
1195
+ });
1164
1196
  logger.debug(`Successfully refined ${response.refined_commits.length} commits`);
1165
1197
  return response;
1166
1198
  } catch (_error) {
@@ -1174,13 +1206,10 @@ var init_api_service = __esm({
1174
1206
  async createBrags(request) {
1175
1207
  logger.debug(`Creating ${request.brags.length} brags`);
1176
1208
  try {
1177
- const response = await this.makeRequest(
1178
- API_ENDPOINTS.BRAGS.CREATE,
1179
- {
1180
- method: "POST",
1181
- body: request
1182
- }
1183
- );
1209
+ const response = await this.makeRequest(API_ENDPOINTS.BRAGS.CREATE, {
1210
+ method: "POST",
1211
+ body: request
1212
+ });
1184
1213
  logger.debug(`Successfully created ${response.created} brags`);
1185
1214
  return response;
1186
1215
  } catch (_error) {
@@ -1209,25 +1238,45 @@ var init_api_service = __esm({
1209
1238
  const response = await this.makeRequest(url, {
1210
1239
  method: "GET"
1211
1240
  });
1212
- logger.debug(`Successfully fetched ${response.brags.length} brags (total: ${response.total})`);
1241
+ logger.debug(
1242
+ `Successfully fetched ${response.brags.length} brags (total: ${response.total})`
1243
+ );
1213
1244
  return response;
1214
1245
  } catch (_error) {
1215
1246
  logger.debug("Failed to list brags");
1216
1247
  throw _error;
1217
1248
  }
1218
1249
  }
1250
+ /**
1251
+ * Get user's subscription status
1252
+ */
1253
+ async getSubscriptionStatus() {
1254
+ logger.debug(`Fetching subscription status from ${API_ENDPOINTS.SUBSCRIPTION.STATUS}`);
1255
+ try {
1256
+ const response = await this.makeRequest(API_ENDPOINTS.SUBSCRIPTION.STATUS, {
1257
+ method: "GET"
1258
+ });
1259
+ logger.debug(`Subscription API response: ${JSON.stringify(response)}`);
1260
+ const subscriptionData = response.data;
1261
+ logger.debug(
1262
+ `Subscription tier: ${subscriptionData.tier}, status: ${subscriptionData.status}`
1263
+ );
1264
+ return subscriptionData;
1265
+ } catch (error) {
1266
+ logger.debug(`Failed to fetch subscription status: ${error}`);
1267
+ logger.debug(`Error details: ${JSON.stringify(error, null, 2)}`);
1268
+ throw error;
1269
+ }
1270
+ }
1219
1271
  /**
1220
1272
  * Check for CLI updates
1221
1273
  */
1222
1274
  async checkVersion() {
1223
1275
  logger.debug("Checking for CLI updates");
1224
1276
  try {
1225
- const response = await this.makeRequest(
1226
- API_ENDPOINTS.VERSION,
1227
- {
1228
- method: "GET"
1229
- }
1230
- );
1277
+ const response = await this.makeRequest(API_ENDPOINTS.VERSION, {
1278
+ method: "GET"
1279
+ });
1231
1280
  logger.debug(`Latest version: ${response.latest_version}`);
1232
1281
  return response;
1233
1282
  } catch {
@@ -1395,14 +1444,17 @@ async function logoutCommand() {
1395
1444
  const isAuthenticated = await authService.isAuthenticated();
1396
1445
  if (!isAuthenticated) {
1397
1446
  logger.log(
1398
- boxen2(`${chalk3.yellow("Not currently authenticated")}
1447
+ boxen2(
1448
+ `${chalk3.yellow("Not currently authenticated")}
1399
1449
 
1400
- ${chalk3.dim("Nothing to logout from")}`, {
1401
- padding: 1,
1402
- margin: 1,
1403
- borderStyle: "round",
1404
- borderColor: "yellow"
1405
- })
1450
+ ${chalk3.dim("Nothing to logout from")}`,
1451
+ {
1452
+ padding: 1,
1453
+ margin: 1,
1454
+ borderStyle: "round",
1455
+ borderColor: "yellow"
1456
+ }
1457
+ )
1406
1458
  );
1407
1459
  return;
1408
1460
  }
@@ -1448,6 +1500,13 @@ ${chalk3.dim("Run")} ${chalk3.cyan("bragduck init")} ${chalk3.dim("to login agai
1448
1500
  init_esm_shims();
1449
1501
  import boxen6 from "boxen";
1450
1502
 
1503
+ // node_modules/@inquirer/core/dist/esm/lib/errors.mjs
1504
+ init_esm_shims();
1505
+ var CancelPromptError = class extends Error {
1506
+ name = "CancelPromptError";
1507
+ message = "Prompt was canceled";
1508
+ };
1509
+
1451
1510
  // src/services/github.service.ts
1452
1511
  init_esm_shims();
1453
1512
  init_errors();
@@ -1585,7 +1644,9 @@ var GitService = class {
1585
1644
  insertions: diffSummary.insertions,
1586
1645
  deletions: diffSummary.deletions
1587
1646
  };
1588
- logger.debug(`Commit ${sha}: ${stats.filesChanged} files, +${stats.insertions} -${stats.deletions}`);
1647
+ logger.debug(
1648
+ `Commit ${sha}: ${stats.filesChanged} files, +${stats.insertions} -${stats.deletions}`
1649
+ );
1589
1650
  return stats;
1590
1651
  } catch (error) {
1591
1652
  if (error.message && error.message.includes("unknown revision")) {
@@ -1876,6 +1937,7 @@ var githubService = new GitHubService();
1876
1937
  init_api_service();
1877
1938
  init_storage_service();
1878
1939
  init_logger();
1940
+ init_browser();
1879
1941
 
1880
1942
  // src/utils/auth-helper.ts
1881
1943
  init_esm_shims();
@@ -2078,14 +2140,12 @@ function formatCommitChoice(commit) {
2078
2140
  if (commit.diffStats) {
2079
2141
  const { filesChanged, insertions, deletions } = commit.diffStats;
2080
2142
  sizeIndicator = ` ${getSizeIndicator(insertions, deletions)}`;
2081
- stats = colors.info(
2082
- ` [${filesChanged} files, ${formatDiffStats(insertions, deletions)}]`
2083
- );
2143
+ stats = colors.info(` [${filesChanged} files, ${formatDiffStats(insertions, deletions)}]`);
2084
2144
  }
2085
2145
  return `${displaySha} ${title}${sizeIndicator}${stats}
2086
2146
  ${author} \u2022 ${date}${bodyPreview}`;
2087
2147
  }
2088
- function formatRefinedCommitsTable(commits) {
2148
+ function formatRefinedCommitsTable(brags, selectedCommits) {
2089
2149
  const table = new Table({
2090
2150
  head: [
2091
2151
  colors.primary("SHA"),
@@ -2098,17 +2158,30 @@ function formatRefinedCommitsTable(commits) {
2098
2158
  wordWrap: true,
2099
2159
  style: tableStyles.default.style
2100
2160
  });
2101
- commits.forEach((commit, index) => {
2161
+ brags.forEach((brag, index) => {
2162
+ const isNewBragType = !("sha" in brag);
2102
2163
  let displaySha;
2103
- if (commit.sha.startsWith("pr-")) {
2104
- displaySha = commit.sha.replace("pr-", "#");
2164
+ if (isNewBragType && selectedCommits) {
2165
+ const commit = selectedCommits[index];
2166
+ if (commit.sha.startsWith("pr-")) {
2167
+ displaySha = commit.sha.replace("pr-", "#");
2168
+ } else {
2169
+ displaySha = commit.sha.substring(0, 7);
2170
+ }
2171
+ } else if (!isNewBragType) {
2172
+ const commit = brag;
2173
+ if (commit.sha.startsWith("pr-")) {
2174
+ displaySha = commit.sha.replace("pr-", "#");
2175
+ } else {
2176
+ displaySha = commit.sha.substring(0, 7);
2177
+ }
2105
2178
  } else {
2106
- displaySha = commit.sha.substring(0, 7);
2179
+ displaySha = `#${index + 1}`;
2107
2180
  }
2108
- const original = commit.original_message.split("\n")[0] || "";
2109
- const title = commit.refined_title;
2110
- const description = commit.refined_description.length > 100 ? commit.refined_description.substring(0, 97) + "..." : commit.refined_description;
2111
- const tags = (commit.suggested_tags || []).join(", ") || "none";
2181
+ const original = isNewBragType ? typeof brag.original_input === "string" ? brag.original_input.split("\n")[0] || "" : "Raw input" : brag.original_message.split("\n")[0] || "";
2182
+ const title = brag.refined_title;
2183
+ const description = brag.refined_description.length > 100 ? brag.refined_description.substring(0, 97) + "..." : brag.refined_description;
2184
+ const tags = (brag.suggested_tags || []).join(", ") || "none";
2112
2185
  const rowNum = colors.infoDim(`${index + 1}.`);
2113
2186
  table.push([
2114
2187
  `${rowNum} ${colors.highlight(displaySha)}`,
@@ -2213,7 +2286,11 @@ async function promptDaysToScan(defaultDays = 30) {
2213
2286
  }
2214
2287
  async function promptSortOption() {
2215
2288
  const choices = [
2216
- { name: "By date (newest first)", value: "date", description: "Most recent PRs first" },
2289
+ {
2290
+ name: "By date (newest first)",
2291
+ value: "date",
2292
+ description: "Most recent PRs first"
2293
+ },
2217
2294
  { name: "By size (largest first)", value: "size", description: "Most lines changed" },
2218
2295
  { name: "By files (most files)", value: "files", description: "Most files changed" },
2219
2296
  { name: "No sorting", value: "none", description: "Keep original order" }
@@ -2252,7 +2329,13 @@ ${theme.label("Impact Score")} ${colors.highlight(commit.impact_score?.toString(
2252
2329
  { name: "\u270E Edit description", value: "edit-desc", description: "Modify the description" },
2253
2330
  { name: "\u270E Edit both", value: "edit-both", description: "Modify title and description" },
2254
2331
  { name: "\u2717 Skip", value: "skip", description: "Skip this brag" },
2255
- ...current < total ? [{ name: "\u2713 Accept all remaining", value: "accept-all", description: "Accept this and all remaining brags" }] : [],
2332
+ ...current < total ? [
2333
+ {
2334
+ name: "\u2713 Accept all remaining",
2335
+ value: "accept-all",
2336
+ description: "Accept this and all remaining brags"
2337
+ }
2338
+ ] : [],
2256
2339
  { name: "\u2717 Cancel", value: "cancel", description: "Cancel and discard all brags" }
2257
2340
  ]
2258
2341
  });
@@ -2373,6 +2456,46 @@ async function scanCommand(options = {}) {
2373
2456
  if (!isAuthenticated) {
2374
2457
  process.exit(1);
2375
2458
  }
2459
+ logger.debug("Fetching subscription status...");
2460
+ const subscriptionStatus = await apiService.getSubscriptionStatus();
2461
+ logger.debug("Subscription status response:", JSON.stringify(subscriptionStatus, null, 2));
2462
+ logger.debug(
2463
+ `Checking tier: "${subscriptionStatus.tier}" (type: ${typeof subscriptionStatus.tier})`
2464
+ );
2465
+ logger.debug(`Tier === 'FREE': ${subscriptionStatus.tier === "FREE"}`);
2466
+ if (subscriptionStatus.tier === "FREE") {
2467
+ logger.debug("FREE tier detected - blocking scan command");
2468
+ logger.log("");
2469
+ logger.log(
2470
+ boxen6(
2471
+ theme.warning("CLI Access Requires Subscription") + "\n\nThe Bragduck CLI is available for Plus and Pro subscribers.\nUpgrade now to unlock:\n\n \u2022 Automatic PR scanning\n \u2022 AI-powered brag generation\n \u2022 Unlimited brags\n\n" + colors.highlight("Start your free trial today!"),
2472
+ {
2473
+ ...boxStyles.warning,
2474
+ padding: 1,
2475
+ margin: 1
2476
+ }
2477
+ )
2478
+ );
2479
+ logger.log("");
2480
+ const shouldOpenBrowser = await promptConfirm(
2481
+ "Open subscription plans in your browser?",
2482
+ true
2483
+ );
2484
+ if (shouldOpenBrowser) {
2485
+ logger.log("");
2486
+ const plansUrl = "https://bragduck.com/app/settings/plans";
2487
+ try {
2488
+ await openBrowser(plansUrl);
2489
+ logger.info(theme.secondary("Opening browser..."));
2490
+ } catch {
2491
+ logger.warning("Could not open browser automatically");
2492
+ logger.info(`Please visit: ${theme.value(plansUrl)}`);
2493
+ }
2494
+ }
2495
+ logger.log("");
2496
+ return;
2497
+ }
2498
+ logger.debug(`Subscription tier "${subscriptionStatus.tier}" - proceeding with scan`);
2376
2499
  const repoSpinner = createStepSpinner(1, TOTAL_STEPS, "Validating GitHub repository");
2377
2500
  repoSpinner.start();
2378
2501
  await githubService.validateGitHubRepository();
@@ -2390,7 +2513,11 @@ async function scanCommand(options = {}) {
2390
2513
  days = await promptDaysToScan(defaultDays);
2391
2514
  logger.log("");
2392
2515
  }
2393
- const prSpinner = createStepSpinner(2, TOTAL_STEPS, `Fetching merged PRs from the last ${days} days`);
2516
+ const prSpinner = createStepSpinner(
2517
+ 2,
2518
+ TOTAL_STEPS,
2519
+ `Fetching merged PRs from the last ${days} days`
2520
+ );
2394
2521
  prSpinner.start();
2395
2522
  let prs;
2396
2523
  if (options.all) {
@@ -2405,7 +2532,12 @@ async function scanCommand(options = {}) {
2405
2532
  logger.info("Try increasing the number of days or check your GitHub activity");
2406
2533
  return;
2407
2534
  }
2408
- succeedStepSpinner(prSpinner, 2, TOTAL_STEPS, `Found ${theme.count(commits.length)} PR${commits.length > 1 ? "s" : ""}`);
2535
+ succeedStepSpinner(
2536
+ prSpinner,
2537
+ 2,
2538
+ TOTAL_STEPS,
2539
+ `Found ${theme.count(commits.length)} PR${commits.length > 1 ? "s" : ""}`
2540
+ );
2409
2541
  logger.log("");
2410
2542
  logger.log(formatCommitStats(commits));
2411
2543
  logger.log("");
@@ -2429,7 +2561,9 @@ async function scanCommand(options = {}) {
2429
2561
  }
2430
2562
  const selectedShas = await promptSelectCommits(sortedCommits);
2431
2563
  if (selectedShas.length === 0) {
2432
- logger.warning("No PRs selected");
2564
+ logger.log("");
2565
+ logger.info(theme.secondary("No PRs selected. Scan cancelled."));
2566
+ logger.log("");
2433
2567
  return;
2434
2568
  }
2435
2569
  const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));
@@ -2442,29 +2576,26 @@ async function scanCommand(options = {}) {
2442
2576
  );
2443
2577
  refineSpinner.start();
2444
2578
  const refineRequest = {
2445
- commits: selectedCommits.map((c) => ({
2446
- sha: c.sha,
2447
- message: c.message,
2448
- author: c.author,
2579
+ brags: selectedCommits.map((c) => ({
2580
+ text: c.message,
2449
2581
  date: c.date,
2450
- diff_stats: c.diffStats ? {
2451
- files_changed: c.diffStats.filesChanged,
2452
- insertions: c.diffStats.insertions,
2453
- deletions: c.diffStats.deletions
2454
- } : void 0
2582
+ title: c.message.split("\n")[0]
2583
+ // First line as initial title
2455
2584
  }))
2456
2585
  };
2457
- const refineResponse = await apiService.refineCommits(refineRequest);
2458
- let refinedCommits = refineResponse.refined_commits;
2586
+ const refineResponse = await apiService.refineBrags(refineRequest);
2587
+ let refinedBrags = refineResponse.refined_brags;
2459
2588
  succeedStepSpinner(refineSpinner, 3, TOTAL_STEPS, "PRs refined successfully");
2460
2589
  logger.log("");
2461
2590
  logger.info("Preview of refined brags:");
2462
2591
  logger.log("");
2463
- logger.log(formatRefinedCommitsTable(refinedCommits));
2592
+ logger.log(formatRefinedCommitsTable(refinedBrags, selectedCommits));
2464
2593
  logger.log("");
2465
- const acceptedBrags = await promptReviewBrags(refinedCommits);
2594
+ const acceptedBrags = await promptReviewBrags(refinedBrags, selectedCommits);
2466
2595
  if (acceptedBrags.length === 0) {
2467
- logger.warning("No brags selected for creation");
2596
+ logger.log("");
2597
+ logger.info(theme.secondary("No brags selected for creation. Scan cancelled."));
2598
+ logger.log("");
2468
2599
  return;
2469
2600
  }
2470
2601
  logger.log("");
@@ -2475,26 +2606,37 @@ async function scanCommand(options = {}) {
2475
2606
  );
2476
2607
  createSpinner2.start();
2477
2608
  const createRequest = {
2478
- brags: acceptedBrags.map((refined) => {
2479
- const originalCommit = selectedCommits.find((c) => c.sha === refined.sha);
2609
+ brags: acceptedBrags.map((refined, index) => {
2610
+ const originalCommit = selectedCommits[index];
2480
2611
  return {
2481
- commit_sha: refined.sha,
2612
+ commit_sha: originalCommit?.sha || `brag-${index}`,
2482
2613
  title: refined.refined_title,
2483
2614
  description: refined.refined_description,
2484
2615
  tags: refined.suggested_tags,
2485
2616
  repository: repoInfo.url,
2486
- date: originalCommit?.date || (/* @__PURE__ */ new Date()).toISOString(),
2487
- commit_url: refined.commit_url,
2488
- impact_score: refined.impact_score,
2617
+ date: refined.date,
2618
+ commit_url: originalCommit?.url || "",
2619
+ impact_score: refined.suggested_impactLevel,
2489
2620
  impact_description: refined.impact_description
2490
2621
  };
2491
2622
  })
2492
2623
  };
2493
2624
  const createResponse = await apiService.createBrags(createRequest);
2494
- succeedStepSpinner(createSpinner2, 4, TOTAL_STEPS, `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? "s" : ""}`);
2625
+ succeedStepSpinner(
2626
+ createSpinner2,
2627
+ 4,
2628
+ TOTAL_STEPS,
2629
+ `Created ${theme.count(createResponse.created)} brag${createResponse.created > 1 ? "s" : ""}`
2630
+ );
2495
2631
  logger.log("");
2496
2632
  logger.log(boxen6(formatSuccessMessage(createResponse.created), boxStyles.success));
2497
2633
  } catch (error) {
2634
+ if (error instanceof CancelPromptError) {
2635
+ logger.log("");
2636
+ logger.info(theme.secondary("Scan cancelled."));
2637
+ logger.log("");
2638
+ return;
2639
+ }
2498
2640
  const err = error;
2499
2641
  logger.log("");
2500
2642
  logger.log(boxen6(formatErrorMessage(err.message, getErrorHint2(err)), boxStyles.error));
@@ -2551,7 +2693,9 @@ async function listCommand(options = {}) {
2551
2693
  if (search || tags) {
2552
2694
  logger.info("Try adjusting your filters or run without filters to see all brags");
2553
2695
  } else {
2554
- logger.info(theme.secondary("Run ") + theme.command("bragduck scan") + theme.secondary(" to create your first brag!"));
2696
+ logger.info(
2697
+ theme.secondary("Run ") + theme.command("bragduck scan") + theme.secondary(" to create your first brag!")
2698
+ );
2555
2699
  }
2556
2700
  return;
2557
2701
  }