@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.
- package/dist/bin/bragduck.js +231 -87
- package/dist/bin/bragduck.js.map +1 -1
- package/dist/index.js +89 -40
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/bin/bragduck.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
1093
|
+
newHeaders.Authorization = `Bearer ${token}`;
|
|
1080
1094
|
}
|
|
1081
1095
|
if (options.method && ["POST", "PUT", "PATCH"].includes(options.method)) {
|
|
1082
|
-
|
|
1096
|
+
newHeaders["Content-Type"] = "application/json";
|
|
1083
1097
|
}
|
|
1084
|
-
options.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(
|
|
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
|
|
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
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
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
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
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(
|
|
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
|
-
|
|
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(
|
|
1447
|
+
boxen2(
|
|
1448
|
+
`${chalk3.yellow("Not currently authenticated")}
|
|
1399
1449
|
|
|
1400
|
-
${chalk3.dim("Nothing to logout from")}`,
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
2161
|
+
brags.forEach((brag, index) => {
|
|
2162
|
+
const isNewBragType = !("sha" in brag);
|
|
2102
2163
|
let displaySha;
|
|
2103
|
-
if (
|
|
2104
|
-
|
|
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 =
|
|
2179
|
+
displaySha = `#${index + 1}`;
|
|
2107
2180
|
}
|
|
2108
|
-
const original =
|
|
2109
|
-
const title =
|
|
2110
|
-
const description =
|
|
2111
|
-
const tags = (
|
|
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
|
-
{
|
|
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 ? [
|
|
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(
|
|
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(
|
|
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.
|
|
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
|
-
|
|
2446
|
-
|
|
2447
|
-
message: c.message,
|
|
2448
|
-
author: c.author,
|
|
2579
|
+
brags: selectedCommits.map((c) => ({
|
|
2580
|
+
text: c.message,
|
|
2449
2581
|
date: c.date,
|
|
2450
|
-
|
|
2451
|
-
|
|
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.
|
|
2458
|
-
let
|
|
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(
|
|
2592
|
+
logger.log(formatRefinedCommitsTable(refinedBrags, selectedCommits));
|
|
2464
2593
|
logger.log("");
|
|
2465
|
-
const acceptedBrags = await promptReviewBrags(
|
|
2594
|
+
const acceptedBrags = await promptReviewBrags(refinedBrags, selectedCommits);
|
|
2466
2595
|
if (acceptedBrags.length === 0) {
|
|
2467
|
-
logger.
|
|
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
|
|
2609
|
+
brags: acceptedBrags.map((refined, index) => {
|
|
2610
|
+
const originalCommit = selectedCommits[index];
|
|
2480
2611
|
return {
|
|
2481
|
-
commit_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:
|
|
2487
|
-
commit_url:
|
|
2488
|
-
impact_score: refined.
|
|
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(
|
|
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(
|
|
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
|
}
|