@bragduck/cli 2.2.1 → 2.3.3

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.
@@ -60,6 +60,9 @@ var init_constants = __esm({
60
60
  SUBSCRIPTION: {
61
61
  STATUS: "/v1/subscriptions/status"
62
62
  },
63
+ ORGANISATIONS: {
64
+ LIST: "/v1/users/{userId}/organisations"
65
+ },
63
66
  VERSION: "/v1/cli/version",
64
67
  /**
65
68
  * @deprecated Use BRAGS.REFINE instead
@@ -1211,11 +1214,13 @@ var init_api_service = __esm({
1211
1214
  */
1212
1215
  async createBrags(request) {
1213
1216
  logger.debug(`Creating ${request.brags.length} brags`);
1217
+ logger.debug(`Request body: ${JSON.stringify(request, null, 2)}`);
1214
1218
  try {
1215
1219
  const response = await this.makeRequest(API_ENDPOINTS.BRAGS.CREATE, {
1216
1220
  method: "POST",
1217
1221
  body: request
1218
1222
  });
1223
+ logger.debug(`Response: ${JSON.stringify(response, null, 2)}`);
1219
1224
  logger.debug(`Successfully created ${response.created} brags`);
1220
1225
  return response;
1221
1226
  } catch (_error) {
@@ -1253,6 +1258,23 @@ var init_api_service = __esm({
1253
1258
  throw _error;
1254
1259
  }
1255
1260
  }
1261
+ /**
1262
+ * List user's organisations
1263
+ */
1264
+ async listUserOrganisations(userId) {
1265
+ logger.debug(`Listing organisations for user: ${userId}`);
1266
+ try {
1267
+ const url = API_ENDPOINTS.ORGANISATIONS.LIST.replace("{userId}", userId);
1268
+ const response = await this.makeRequest(url, {
1269
+ method: "GET"
1270
+ });
1271
+ logger.debug(`Successfully fetched ${response.items.length} organisations`);
1272
+ return response;
1273
+ } catch (_error) {
1274
+ logger.debug("Failed to list organisations");
1275
+ throw _error;
1276
+ }
1277
+ }
1256
1278
  /**
1257
1279
  * Get user's subscription status
1258
1280
  */
@@ -2310,6 +2332,21 @@ async function promptSortOption() {
2310
2332
  default: "date"
2311
2333
  });
2312
2334
  }
2335
+ async function promptSelectOrganisation(organisations) {
2336
+ const choices = [
2337
+ { name: "No company", value: "none" },
2338
+ ...organisations.map((org) => ({
2339
+ name: org.name,
2340
+ value: org.id
2341
+ }))
2342
+ ];
2343
+ const selected = await select({
2344
+ message: "Attach brags to which company?",
2345
+ choices,
2346
+ default: "none"
2347
+ });
2348
+ return selected === "none" ? null : selected;
2349
+ }
2313
2350
  async function promptReviewBrags(refinedBrags, selectedCommits) {
2314
2351
  const acceptedBrags = [];
2315
2352
  console.log("\n" + theme.info("Review each brag before creation:") + "\n");
@@ -2451,6 +2488,9 @@ async function ensureAuthenticated() {
2451
2488
  }
2452
2489
  }
2453
2490
 
2491
+ // src/commands/scan.ts
2492
+ init_auth_service();
2493
+
2454
2494
  // src/ui/spinners.ts
2455
2495
  init_esm_shims();
2456
2496
  import ora3 from "ora";
@@ -2589,23 +2629,25 @@ async function scanCommand(options = {}) {
2589
2629
  logger.log("");
2590
2630
  logger.log(formatCommitStats(commits));
2591
2631
  logger.log("");
2592
- const sortOption = await promptSortOption();
2593
- logger.log("");
2594
2632
  let sortedCommits = [...commits];
2595
- if (sortOption === "date") {
2596
- sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
2597
- } else if (sortOption === "size") {
2598
- sortedCommits.sort((a, b) => {
2599
- const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);
2600
- const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);
2601
- return sizeB - sizeA;
2602
- });
2603
- } else if (sortOption === "files") {
2604
- sortedCommits.sort((a, b) => {
2605
- const filesA = a.diffStats?.filesChanged || 0;
2606
- const filesB = b.diffStats?.filesChanged || 0;
2607
- return filesB - filesA;
2608
- });
2633
+ if (commits.length > 1) {
2634
+ const sortOption = await promptSortOption();
2635
+ logger.log("");
2636
+ if (sortOption === "date") {
2637
+ sortedCommits.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime());
2638
+ } else if (sortOption === "size") {
2639
+ sortedCommits.sort((a, b) => {
2640
+ const sizeA = (a.diffStats?.insertions || 0) + (a.diffStats?.deletions || 0);
2641
+ const sizeB = (b.diffStats?.insertions || 0) + (b.diffStats?.deletions || 0);
2642
+ return sizeB - sizeA;
2643
+ });
2644
+ } else if (sortOption === "files") {
2645
+ sortedCommits.sort((a, b) => {
2646
+ const filesA = a.diffStats?.filesChanged || 0;
2647
+ const filesB = b.diffStats?.filesChanged || 0;
2648
+ return filesB - filesA;
2649
+ });
2650
+ }
2609
2651
  }
2610
2652
  const selectedShas = await promptSelectCommits(sortedCommits);
2611
2653
  if (selectedShas.length === 0) {
@@ -2617,14 +2659,38 @@ async function scanCommand(options = {}) {
2617
2659
  const selectedCommits = sortedCommits.filter((c) => selectedShas.includes(c.sha));
2618
2660
  logger.log(formatSelectionSummary(selectedCommits.length, selectedCommits));
2619
2661
  logger.log("");
2662
+ const existingBrags = await apiService.listBrags({ limit: 100 });
2663
+ logger.debug(`Fetched ${existingBrags.brags.length} existing brags`);
2664
+ const existingUrls = new Set(existingBrags.brags.flatMap((b) => b.attachments || []));
2665
+ logger.debug(`Existing PR URLs in attachments: ${existingUrls.size}`);
2666
+ const duplicates = selectedCommits.filter((c) => c.url && existingUrls.has(c.url));
2667
+ const newCommits = selectedCommits.filter((c) => !c.url || !existingUrls.has(c.url));
2668
+ logger.debug(`Duplicates: ${duplicates.length}, New: ${newCommits.length}`);
2669
+ if (duplicates.length > 0) {
2670
+ logger.log("");
2671
+ logger.info(
2672
+ colors.warning(
2673
+ `${duplicates.length} PR${duplicates.length > 1 ? "s" : ""} already added to Bragduck - skipping`
2674
+ )
2675
+ );
2676
+ logger.log("");
2677
+ }
2678
+ if (newCommits.length === 0) {
2679
+ logger.log("");
2680
+ logger.info(
2681
+ theme.secondary("All selected PRs already exist in Bragduck. Nothing to refine.")
2682
+ );
2683
+ logger.log("");
2684
+ return;
2685
+ }
2620
2686
  const refineSpinner = createStepSpinner(
2621
2687
  3,
2622
2688
  TOTAL_STEPS,
2623
- `Refining ${theme.count(selectedCommits.length)} PR${selectedCommits.length > 1 ? "s" : ""} with AI`
2689
+ `Refining ${theme.count(newCommits.length)} PR${newCommits.length > 1 ? "s" : ""} with AI`
2624
2690
  );
2625
2691
  refineSpinner.start();
2626
2692
  const refineRequest = {
2627
- brags: selectedCommits.map((c) => ({
2693
+ brags: newCommits.map((c) => ({
2628
2694
  text: c.message,
2629
2695
  date: c.date,
2630
2696
  title: c.message.split("\n")[0]
@@ -2637,9 +2703,9 @@ async function scanCommand(options = {}) {
2637
2703
  logger.log("");
2638
2704
  logger.info("Preview of refined brags:");
2639
2705
  logger.log("");
2640
- logger.log(formatRefinedCommitsTable(refinedBrags, selectedCommits));
2706
+ logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));
2641
2707
  logger.log("");
2642
- const acceptedBrags = await promptReviewBrags(refinedBrags, selectedCommits);
2708
+ const acceptedBrags = await promptReviewBrags(refinedBrags, newCommits);
2643
2709
  if (acceptedBrags.length === 0) {
2644
2710
  logger.log("");
2645
2711
  logger.info(theme.secondary("No brags selected for creation. Scan cancelled."));
@@ -2647,6 +2713,19 @@ async function scanCommand(options = {}) {
2647
2713
  return;
2648
2714
  }
2649
2715
  logger.log("");
2716
+ let selectedOrgId = null;
2717
+ const userInfo = authService.getUserInfo();
2718
+ if (userInfo?.id) {
2719
+ try {
2720
+ const orgsResponse = await apiService.listUserOrganisations(userInfo.id);
2721
+ if (orgsResponse.items.length > 0) {
2722
+ selectedOrgId = await promptSelectOrganisation(orgsResponse.items);
2723
+ logger.log("");
2724
+ }
2725
+ } catch {
2726
+ logger.debug("Failed to fetch organisations, skipping org selection");
2727
+ }
2728
+ }
2650
2729
  const createSpinner2 = createStepSpinner(
2651
2730
  4,
2652
2731
  TOTAL_STEPS,
@@ -2655,7 +2734,7 @@ async function scanCommand(options = {}) {
2655
2734
  createSpinner2.start();
2656
2735
  const createRequest = {
2657
2736
  brags: acceptedBrags.map((refined, index) => {
2658
- const originalCommit = selectedCommits[index];
2737
+ const originalCommit = newCommits[index];
2659
2738
  return {
2660
2739
  commit_sha: originalCommit?.sha || `brag-${index}`,
2661
2740
  title: refined.refined_title,
@@ -2665,7 +2744,9 @@ async function scanCommand(options = {}) {
2665
2744
  date: refined.date,
2666
2745
  commit_url: originalCommit?.url || "",
2667
2746
  impact_score: refined.suggested_impactLevel,
2668
- impact_description: refined.impact_description
2747
+ impact_description: refined.impact_description,
2748
+ attachments: originalCommit?.url ? [originalCommit.url] : [],
2749
+ orgId: selectedOrgId || void 0
2669
2750
  };
2670
2751
  })
2671
2752
  };