@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.
- package/dist/bin/bragduck.js +103 -22
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/bin/bragduck.js
CHANGED
|
@@ -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 (
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
|
|
2607
|
-
|
|
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(
|
|
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:
|
|
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,
|
|
2706
|
+
logger.log(formatRefinedCommitsTable(refinedBrags, newCommits));
|
|
2641
2707
|
logger.log("");
|
|
2642
|
-
const acceptedBrags = await promptReviewBrags(refinedBrags,
|
|
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 =
|
|
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
|
};
|