@rotorsoft/gent 1.22.0 → 1.23.0
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/{chunk-75KVN7ZC.js → chunk-HCJWQPMW.js} +214 -307
- package/dist/chunk-HCJWQPMW.js.map +1 -0
- package/dist/chunk-ZDOEOZDC.js +43 -0
- package/dist/chunk-ZDOEOZDC.js.map +1 -0
- package/dist/chunk-ZQDWILU5.js +283 -0
- package/dist/chunk-ZQDWILU5.js.map +1 -0
- package/dist/github-remote-4TLUL2HX.js +9 -0
- package/dist/index.js +180 -246
- package/dist/index.js.map +1 -1
- package/dist/setup-labels-2SNO3QQL.js +9 -0
- package/dist/setup-labels-2SNO3QQL.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-75KVN7ZC.js.map +0 -1
- package/dist/setup-labels-STWAFV2E.js +0 -8
- /package/dist/{setup-labels-STWAFV2E.js.map → github-remote-4TLUL2HX.js.map} +0 -0
|
@@ -54,30 +54,6 @@ var colors = {
|
|
|
54
54
|
provider: chalk.cyan.bold
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
// src/utils/spinner.ts
|
|
58
|
-
import ora from "ora";
|
|
59
|
-
function aiSpinnerText(provider, action) {
|
|
60
|
-
return `Waiting for ${provider} to ${action}...`;
|
|
61
|
-
}
|
|
62
|
-
function createSpinner(text) {
|
|
63
|
-
return ora({
|
|
64
|
-
text,
|
|
65
|
-
spinner: "dots"
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
async function withSpinner(text, fn) {
|
|
69
|
-
const spinner = createSpinner(text);
|
|
70
|
-
spinner.start();
|
|
71
|
-
try {
|
|
72
|
-
const result = await fn();
|
|
73
|
-
spinner.succeed();
|
|
74
|
-
return result;
|
|
75
|
-
} catch (error) {
|
|
76
|
-
spinner.fail();
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
57
|
// src/lib/config.ts
|
|
82
58
|
import { existsSync, readFileSync, writeFileSync } from "fs";
|
|
83
59
|
import { join } from "path";
|
|
@@ -308,206 +284,71 @@ validation:
|
|
|
308
284
|
`;
|
|
309
285
|
}
|
|
310
286
|
|
|
311
|
-
// src/
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
{
|
|
320
|
-
name: "ai-in-progress",
|
|
321
|
-
color: "FFA500",
|
|
322
|
-
description: "AI currently working on this"
|
|
323
|
-
},
|
|
324
|
-
{
|
|
325
|
-
name: "ai-completed",
|
|
326
|
-
color: "1D76DB",
|
|
327
|
-
description: "AI done, needs human review"
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
name: "ai-blocked",
|
|
331
|
-
color: "D93F0B",
|
|
332
|
-
description: "AI couldn't complete, needs help"
|
|
333
|
-
}
|
|
334
|
-
],
|
|
335
|
-
priority: [
|
|
336
|
-
{
|
|
337
|
-
name: "priority:critical",
|
|
338
|
-
color: "B60205",
|
|
339
|
-
description: "Blocking production"
|
|
340
|
-
},
|
|
341
|
-
{
|
|
342
|
-
name: "priority:high",
|
|
343
|
-
color: "D93F0B",
|
|
344
|
-
description: "Important features/bugs"
|
|
345
|
-
},
|
|
346
|
-
{
|
|
347
|
-
name: "priority:medium",
|
|
348
|
-
color: "FBCA04",
|
|
349
|
-
description: "Nice-to-have improvements"
|
|
350
|
-
},
|
|
351
|
-
{ name: "priority:low", color: "0E8A16", description: "Minor tweaks" }
|
|
352
|
-
],
|
|
353
|
-
risk: [
|
|
354
|
-
{
|
|
355
|
-
name: "risk:low",
|
|
356
|
-
color: "C2E0C6",
|
|
357
|
-
description: "UI changes, tests, non-critical"
|
|
358
|
-
},
|
|
359
|
-
{
|
|
360
|
-
name: "risk:medium",
|
|
361
|
-
color: "FEF2C0",
|
|
362
|
-
description: "API changes, new features"
|
|
363
|
-
},
|
|
364
|
-
{
|
|
365
|
-
name: "risk:high",
|
|
366
|
-
color: "F9D0C4",
|
|
367
|
-
description: "Migrations, auth, security"
|
|
368
|
-
}
|
|
369
|
-
],
|
|
370
|
-
type: [
|
|
371
|
-
{ name: "type:feature", color: "1D76DB", description: "New feature" },
|
|
372
|
-
{ name: "type:fix", color: "D73A4A", description: "Bug fix" },
|
|
373
|
-
{
|
|
374
|
-
name: "type:refactor",
|
|
375
|
-
color: "5319E7",
|
|
376
|
-
description: "Code improvement"
|
|
377
|
-
},
|
|
378
|
-
{ name: "type:chore", color: "FEF2C0", description: "Maintenance" },
|
|
379
|
-
{ name: "type:docs", color: "0075CA", description: "Documentation" },
|
|
380
|
-
{ name: "type:test", color: "D4C5F9", description: "Testing" }
|
|
381
|
-
],
|
|
382
|
-
area: [
|
|
383
|
-
{ name: "area:ui", color: "C5DEF5", description: "User interface" },
|
|
384
|
-
{ name: "area:api", color: "D4C5F9", description: "API/Backend" },
|
|
385
|
-
{ name: "area:database", color: "FEF2C0", description: "Database/Models" },
|
|
386
|
-
{
|
|
387
|
-
name: "area:workers",
|
|
388
|
-
color: "F9D0C4",
|
|
389
|
-
description: "Background workers"
|
|
390
|
-
},
|
|
391
|
-
{ name: "area:shared", color: "C2E0C6", description: "Shared libraries" },
|
|
392
|
-
{
|
|
393
|
-
name: "area:testing",
|
|
394
|
-
color: "E99695",
|
|
395
|
-
description: "Test infrastructure"
|
|
396
|
-
},
|
|
397
|
-
{
|
|
398
|
-
name: "area:infra",
|
|
399
|
-
color: "BFD4F2",
|
|
400
|
-
description: "Infrastructure/DevOps"
|
|
401
|
-
}
|
|
402
|
-
]
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
// src/lib/labels.ts
|
|
406
|
-
function getAllLabels(config) {
|
|
407
|
-
const labels = [];
|
|
408
|
-
labels.push(...DEFAULT_LABELS.workflow);
|
|
409
|
-
for (const priority of config.github.labels.priorities) {
|
|
410
|
-
const defaultLabel = DEFAULT_LABELS.priority.find(
|
|
411
|
-
(l) => l.name === `priority:${priority}`
|
|
412
|
-
);
|
|
413
|
-
if (defaultLabel) {
|
|
414
|
-
labels.push(defaultLabel);
|
|
415
|
-
} else {
|
|
416
|
-
labels.push({
|
|
417
|
-
name: `priority:${priority}`,
|
|
418
|
-
color: "FBCA04",
|
|
419
|
-
description: `Priority: ${priority}`
|
|
420
|
-
});
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
for (const risk of config.github.labels.risks) {
|
|
424
|
-
const defaultLabel = DEFAULT_LABELS.risk.find(
|
|
425
|
-
(l) => l.name === `risk:${risk}`
|
|
426
|
-
);
|
|
427
|
-
if (defaultLabel) {
|
|
428
|
-
labels.push(defaultLabel);
|
|
429
|
-
} else {
|
|
430
|
-
labels.push({
|
|
431
|
-
name: `risk:${risk}`,
|
|
432
|
-
color: "FEF2C0",
|
|
433
|
-
description: `Risk: ${risk}`
|
|
434
|
-
});
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
for (const type of config.github.labels.types) {
|
|
438
|
-
const defaultLabel = DEFAULT_LABELS.type.find(
|
|
439
|
-
(l) => l.name === `type:${type}`
|
|
440
|
-
);
|
|
441
|
-
if (defaultLabel) {
|
|
442
|
-
labels.push(defaultLabel);
|
|
443
|
-
} else {
|
|
444
|
-
labels.push({
|
|
445
|
-
name: `type:${type}`,
|
|
446
|
-
color: "1D76DB",
|
|
447
|
-
description: `Type: ${type}`
|
|
448
|
-
});
|
|
449
|
-
}
|
|
287
|
+
// src/utils/validators.ts
|
|
288
|
+
import { execa } from "execa";
|
|
289
|
+
async function checkGhAuth() {
|
|
290
|
+
try {
|
|
291
|
+
await execa("gh", ["auth", "status"]);
|
|
292
|
+
return true;
|
|
293
|
+
} catch {
|
|
294
|
+
return false;
|
|
450
295
|
}
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
labels.push({
|
|
459
|
-
name: `area:${area}`,
|
|
460
|
-
color: "C5DEF5",
|
|
461
|
-
description: `Area: ${area}`
|
|
462
|
-
});
|
|
463
|
-
}
|
|
296
|
+
}
|
|
297
|
+
async function checkClaudeCli() {
|
|
298
|
+
try {
|
|
299
|
+
await execa("claude", ["--version"]);
|
|
300
|
+
return true;
|
|
301
|
+
} catch {
|
|
302
|
+
return false;
|
|
464
303
|
}
|
|
465
|
-
return labels;
|
|
466
304
|
}
|
|
467
|
-
function
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
305
|
+
async function checkGeminiCli() {
|
|
306
|
+
try {
|
|
307
|
+
await execa("gemini", ["--version"]);
|
|
308
|
+
return true;
|
|
309
|
+
} catch {
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
474
312
|
}
|
|
475
|
-
function
|
|
476
|
-
|
|
477
|
-
"
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
];
|
|
313
|
+
async function checkCodexCLI() {
|
|
314
|
+
try {
|
|
315
|
+
await execa("codex", ["--version"]);
|
|
316
|
+
return true;
|
|
317
|
+
} catch {
|
|
318
|
+
return false;
|
|
319
|
+
}
|
|
483
320
|
}
|
|
484
|
-
function
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
return
|
|
488
|
-
|
|
321
|
+
async function checkAIProvider(provider) {
|
|
322
|
+
switch (provider) {
|
|
323
|
+
case "claude":
|
|
324
|
+
return checkClaudeCli();
|
|
325
|
+
case "gemini":
|
|
326
|
+
return checkGeminiCli();
|
|
327
|
+
case "codex":
|
|
328
|
+
return checkCodexCLI();
|
|
489
329
|
}
|
|
490
|
-
return "feature";
|
|
491
330
|
}
|
|
492
|
-
function
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
331
|
+
async function checkGitRepo() {
|
|
332
|
+
try {
|
|
333
|
+
await execa("git", ["rev-parse", "--git-dir"]);
|
|
334
|
+
return true;
|
|
335
|
+
} catch {
|
|
336
|
+
return false;
|
|
497
337
|
}
|
|
498
|
-
return "medium";
|
|
499
338
|
}
|
|
500
|
-
function
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
339
|
+
function checkInitialized(cwd) {
|
|
340
|
+
return configExists(cwd);
|
|
341
|
+
}
|
|
342
|
+
function isValidIssueNumber(value) {
|
|
343
|
+
const num = parseInt(value, 10);
|
|
344
|
+
return !isNaN(num) && num > 0;
|
|
345
|
+
}
|
|
346
|
+
function sanitizeSlug(title, maxLength = 40) {
|
|
347
|
+
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength);
|
|
507
348
|
}
|
|
508
349
|
|
|
509
350
|
// src/lib/github.ts
|
|
510
|
-
import { execa } from "execa";
|
|
351
|
+
import { execa as execa2 } from "execa";
|
|
511
352
|
var WORKFLOW_LABELS = [
|
|
512
353
|
"ai-ready",
|
|
513
354
|
"ai-in-progress",
|
|
@@ -516,7 +357,7 @@ var WORKFLOW_LABELS = [
|
|
|
516
357
|
];
|
|
517
358
|
async function checkLabelsExist() {
|
|
518
359
|
try {
|
|
519
|
-
const { stdout } = await
|
|
360
|
+
const { stdout } = await execa2("gh", [
|
|
520
361
|
"label",
|
|
521
362
|
"list",
|
|
522
363
|
"--json",
|
|
@@ -532,7 +373,7 @@ async function checkLabelsExist() {
|
|
|
532
373
|
}
|
|
533
374
|
}
|
|
534
375
|
async function getIssue(issueNumber) {
|
|
535
|
-
const { stdout } = await
|
|
376
|
+
const { stdout } = await execa2("gh", [
|
|
536
377
|
"issue",
|
|
537
378
|
"view",
|
|
538
379
|
String(issueNumber),
|
|
@@ -564,7 +405,7 @@ async function listIssues(options) {
|
|
|
564
405
|
args.push("--state", options.state);
|
|
565
406
|
}
|
|
566
407
|
args.push("--limit", String(options.limit || 50));
|
|
567
|
-
const { stdout } = await
|
|
408
|
+
const { stdout } = await execa2("gh", args);
|
|
568
409
|
const data = JSON.parse(stdout);
|
|
569
410
|
return data.map(
|
|
570
411
|
(d) => ({
|
|
@@ -589,7 +430,7 @@ async function createIssue(options) {
|
|
|
589
430
|
if (options.labels?.length) {
|
|
590
431
|
args.push("--label", options.labels.join(","));
|
|
591
432
|
}
|
|
592
|
-
const { stdout } = await
|
|
433
|
+
const { stdout } = await execa2("gh", args);
|
|
593
434
|
const match = stdout.match(/\/issues\/(\d+)/);
|
|
594
435
|
if (!match) {
|
|
595
436
|
throw new Error("Failed to extract issue number from gh output");
|
|
@@ -600,7 +441,7 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
600
441
|
const promises = [];
|
|
601
442
|
if (options.add?.length) {
|
|
602
443
|
promises.push(
|
|
603
|
-
|
|
444
|
+
execa2("gh", [
|
|
604
445
|
"issue",
|
|
605
446
|
"edit",
|
|
606
447
|
String(issueNumber),
|
|
@@ -611,7 +452,7 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
611
452
|
}
|
|
612
453
|
if (options.remove?.length) {
|
|
613
454
|
promises.push(
|
|
614
|
-
|
|
455
|
+
execa2("gh", [
|
|
615
456
|
"issue",
|
|
616
457
|
"edit",
|
|
617
458
|
String(issueNumber),
|
|
@@ -623,10 +464,10 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
623
464
|
await Promise.all(promises);
|
|
624
465
|
}
|
|
625
466
|
async function addIssueComment(issueNumber, body) {
|
|
626
|
-
await
|
|
467
|
+
await execa2("gh", ["issue", "comment", String(issueNumber), "--body", body]);
|
|
627
468
|
}
|
|
628
469
|
async function assignIssue(issueNumber, assignee) {
|
|
629
|
-
await
|
|
470
|
+
await execa2("gh", [
|
|
630
471
|
"issue",
|
|
631
472
|
"edit",
|
|
632
473
|
String(issueNumber),
|
|
@@ -636,7 +477,7 @@ async function assignIssue(issueNumber, assignee) {
|
|
|
636
477
|
}
|
|
637
478
|
async function createLabel(label) {
|
|
638
479
|
try {
|
|
639
|
-
await
|
|
480
|
+
await execa2("gh", [
|
|
640
481
|
"label",
|
|
641
482
|
"create",
|
|
642
483
|
label.name,
|
|
@@ -666,12 +507,12 @@ async function createPullRequest(options) {
|
|
|
666
507
|
if (options.draft) {
|
|
667
508
|
args.push("--draft");
|
|
668
509
|
}
|
|
669
|
-
const { stdout } = await
|
|
510
|
+
const { stdout } = await execa2("gh", args);
|
|
670
511
|
return stdout.trim();
|
|
671
512
|
}
|
|
672
513
|
async function getPrForBranch() {
|
|
673
514
|
try {
|
|
674
|
-
const { stdout } = await
|
|
515
|
+
const { stdout } = await execa2("gh", [
|
|
675
516
|
"pr",
|
|
676
517
|
"view",
|
|
677
518
|
"--json",
|
|
@@ -685,7 +526,7 @@ async function getPrForBranch() {
|
|
|
685
526
|
}
|
|
686
527
|
async function getPrStatus() {
|
|
687
528
|
try {
|
|
688
|
-
const { stdout } = await
|
|
529
|
+
const { stdout } = await execa2("gh", [
|
|
689
530
|
"pr",
|
|
690
531
|
"view",
|
|
691
532
|
"--json",
|
|
@@ -711,11 +552,11 @@ async function getPrReviewData(prNumber) {
|
|
|
711
552
|
prArgs.push(String(prNumber));
|
|
712
553
|
}
|
|
713
554
|
prArgs.push("--json", "reviews,comments");
|
|
714
|
-
const { stdout: prStdout } = await
|
|
555
|
+
const { stdout: prStdout } = await execa2("gh", prArgs);
|
|
715
556
|
const prData = JSON.parse(prStdout);
|
|
716
557
|
let reviewThreads = [];
|
|
717
558
|
try {
|
|
718
|
-
const { stdout: repoStdout } = await
|
|
559
|
+
const { stdout: repoStdout } = await execa2("gh", [
|
|
719
560
|
"repo",
|
|
720
561
|
"view",
|
|
721
562
|
"--json",
|
|
@@ -725,7 +566,7 @@ async function getPrReviewData(prNumber) {
|
|
|
725
566
|
const owner = repoData.owner?.login ?? repoData.owner;
|
|
726
567
|
const repo = repoData.name;
|
|
727
568
|
const graphqlQuery = `query { repository(owner: "${owner}", name: "${repo}") { pullRequest(number: ${prNumber}) { reviewThreads(first: 100) { nodes { isResolved isOutdated path line comments(first: 100) { nodes { databaseId author { login } body path line createdAt } } } } } } }`;
|
|
728
|
-
const { stdout: graphqlStdout } = await
|
|
569
|
+
const { stdout: graphqlStdout } = await execa2("gh", [
|
|
729
570
|
"api",
|
|
730
571
|
"graphql",
|
|
731
572
|
"-f",
|
|
@@ -774,11 +615,11 @@ async function getPrReviewData(prNumber) {
|
|
|
774
615
|
};
|
|
775
616
|
}
|
|
776
617
|
async function getCurrentUser() {
|
|
777
|
-
const { stdout } = await
|
|
618
|
+
const { stdout } = await execa2("gh", ["api", "user", "--jq", ".login"]);
|
|
778
619
|
return stdout.trim();
|
|
779
620
|
}
|
|
780
621
|
async function replyToReviewComment(prNumber, commentId, body) {
|
|
781
|
-
await
|
|
622
|
+
await execa2("gh", [
|
|
782
623
|
"api",
|
|
783
624
|
`repos/{owner}/{repo}/pulls/${prNumber}/comments/${commentId}/replies`,
|
|
784
625
|
"-f",
|
|
@@ -786,10 +627,10 @@ async function replyToReviewComment(prNumber, commentId, body) {
|
|
|
786
627
|
]);
|
|
787
628
|
}
|
|
788
629
|
async function addPrComment(prNumber, body) {
|
|
789
|
-
await
|
|
630
|
+
await execa2("gh", ["pr", "comment", String(prNumber), "--body", body]);
|
|
790
631
|
}
|
|
791
632
|
async function listOpenPrs(limit = 30) {
|
|
792
|
-
const { stdout } = await
|
|
633
|
+
const { stdout } = await execa2("gh", [
|
|
793
634
|
"pr",
|
|
794
635
|
"list",
|
|
795
636
|
"--state",
|
|
@@ -810,102 +651,156 @@ async function listOpenPrs(limit = 30) {
|
|
|
810
651
|
);
|
|
811
652
|
}
|
|
812
653
|
|
|
813
|
-
// src/
|
|
814
|
-
import { execa as
|
|
815
|
-
async function
|
|
654
|
+
// src/lib/git.ts
|
|
655
|
+
import { execa as execa3 } from "execa";
|
|
656
|
+
async function getCurrentBranch() {
|
|
657
|
+
const { stdout } = await execa3("git", ["branch", "--show-current"]);
|
|
658
|
+
return stdout.trim();
|
|
659
|
+
}
|
|
660
|
+
async function isOnMainBranch() {
|
|
661
|
+
const branch = await getCurrentBranch();
|
|
662
|
+
return branch === "main" || branch === "master";
|
|
663
|
+
}
|
|
664
|
+
async function getDefaultBranch() {
|
|
816
665
|
try {
|
|
817
|
-
await
|
|
818
|
-
|
|
666
|
+
const { stdout } = await execa3("git", [
|
|
667
|
+
"symbolic-ref",
|
|
668
|
+
"refs/remotes/origin/HEAD"
|
|
669
|
+
]);
|
|
670
|
+
return stdout.trim().replace("refs/remotes/origin/", "");
|
|
819
671
|
} catch {
|
|
820
|
-
|
|
672
|
+
try {
|
|
673
|
+
await execa3("git", ["rev-parse", "--verify", "main"]);
|
|
674
|
+
return "main";
|
|
675
|
+
} catch {
|
|
676
|
+
return "master";
|
|
677
|
+
}
|
|
821
678
|
}
|
|
822
679
|
}
|
|
823
|
-
async function
|
|
680
|
+
async function branchExists(name) {
|
|
824
681
|
try {
|
|
825
|
-
await
|
|
682
|
+
await execa3("git", ["rev-parse", "--verify", name]);
|
|
826
683
|
return true;
|
|
827
684
|
} catch {
|
|
828
685
|
return false;
|
|
829
686
|
}
|
|
830
687
|
}
|
|
831
|
-
async function
|
|
688
|
+
async function createBranch(name, from) {
|
|
689
|
+
if (from) {
|
|
690
|
+
await execa3("git", ["checkout", "-b", name, from]);
|
|
691
|
+
} else {
|
|
692
|
+
await execa3("git", ["checkout", "-b", name]);
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
async function checkoutBranch(name) {
|
|
696
|
+
await execa3("git", ["checkout", name]);
|
|
697
|
+
}
|
|
698
|
+
async function hasUncommittedChanges() {
|
|
699
|
+
const { stdout } = await execa3("git", ["status", "--porcelain"]);
|
|
700
|
+
return stdout.trim().length > 0;
|
|
701
|
+
}
|
|
702
|
+
async function getUnpushedCommits() {
|
|
832
703
|
try {
|
|
833
|
-
await
|
|
704
|
+
const { stdout } = await execa3("git", ["log", "@{u}..HEAD", "--oneline"]);
|
|
705
|
+
return stdout.trim().length > 0;
|
|
706
|
+
} catch {
|
|
834
707
|
return true;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
async function pushBranch(branch) {
|
|
711
|
+
const branchName = branch || await getCurrentBranch();
|
|
712
|
+
await execa3("git", ["push", "-u", "origin", branchName]);
|
|
713
|
+
}
|
|
714
|
+
async function getAuthorInitials() {
|
|
715
|
+
try {
|
|
716
|
+
const { stdout } = await execa3("git", ["config", "user.initials"]);
|
|
717
|
+
if (stdout.trim()) {
|
|
718
|
+
return stdout.trim();
|
|
719
|
+
}
|
|
720
|
+
} catch {
|
|
721
|
+
}
|
|
722
|
+
try {
|
|
723
|
+
const { stdout } = await execa3("git", ["config", "user.name"]);
|
|
724
|
+
const name = stdout.trim();
|
|
725
|
+
if (name) {
|
|
726
|
+
const parts = name.split(/\s+/);
|
|
727
|
+
return parts.map((p) => p[0]?.toLowerCase() || "").join("");
|
|
728
|
+
}
|
|
835
729
|
} catch {
|
|
836
|
-
return false;
|
|
837
730
|
}
|
|
731
|
+
return "dev";
|
|
838
732
|
}
|
|
839
|
-
async function
|
|
733
|
+
async function getRepoInfo() {
|
|
840
734
|
try {
|
|
841
|
-
await
|
|
842
|
-
|
|
735
|
+
const { stdout } = await execa3("git", [
|
|
736
|
+
"config",
|
|
737
|
+
"--get",
|
|
738
|
+
"remote.origin.url"
|
|
739
|
+
]);
|
|
740
|
+
const url = stdout.trim();
|
|
741
|
+
const sshMatch = url.match(/git@github\.com:([^/]+)\/([^.]+)/);
|
|
742
|
+
if (sshMatch) {
|
|
743
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
744
|
+
}
|
|
745
|
+
const httpsMatch = url.match(/github\.com\/([^/]+)\/([^.]+)/);
|
|
746
|
+
if (httpsMatch) {
|
|
747
|
+
return { owner: httpsMatch[1], repo: httpsMatch[2] };
|
|
748
|
+
}
|
|
749
|
+
return null;
|
|
843
750
|
} catch {
|
|
844
|
-
return
|
|
751
|
+
return null;
|
|
845
752
|
}
|
|
846
753
|
}
|
|
847
|
-
async function
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
754
|
+
async function getCommitsSinceBase(base = "main") {
|
|
755
|
+
try {
|
|
756
|
+
const { stdout } = await execa3("git", [
|
|
757
|
+
"log",
|
|
758
|
+
`${base}..HEAD`,
|
|
759
|
+
"--pretty=format:%s"
|
|
760
|
+
]);
|
|
761
|
+
return stdout.trim().split("\n").filter(Boolean);
|
|
762
|
+
} catch {
|
|
763
|
+
return [];
|
|
855
764
|
}
|
|
856
765
|
}
|
|
857
|
-
async function
|
|
766
|
+
async function getDiffSummary(base = "main") {
|
|
858
767
|
try {
|
|
859
|
-
await
|
|
860
|
-
return
|
|
768
|
+
const { stdout } = await execa3("git", ["diff", `${base}...HEAD`, "--stat"]);
|
|
769
|
+
return stdout.trim();
|
|
861
770
|
} catch {
|
|
862
|
-
return
|
|
771
|
+
return "";
|
|
863
772
|
}
|
|
864
773
|
}
|
|
865
|
-
function
|
|
866
|
-
|
|
774
|
+
async function getCurrentCommitSha() {
|
|
775
|
+
const { stdout } = await execa3("git", ["rev-parse", "HEAD"]);
|
|
776
|
+
return stdout.trim();
|
|
867
777
|
}
|
|
868
|
-
function
|
|
869
|
-
const
|
|
870
|
-
return
|
|
778
|
+
async function hasNewCommits(beforeSha) {
|
|
779
|
+
const currentSha = await getCurrentCommitSha();
|
|
780
|
+
return currentSha !== beforeSha;
|
|
871
781
|
}
|
|
872
|
-
function
|
|
873
|
-
|
|
782
|
+
async function getLastCommitTimestamp() {
|
|
783
|
+
const { stdout } = await execa3("git", ["log", "-1", "--format=%cI"]);
|
|
784
|
+
return stdout.trim();
|
|
874
785
|
}
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
logger.newline();
|
|
889
|
-
let created = 0;
|
|
890
|
-
let failed = 0;
|
|
891
|
-
for (const label of labels) {
|
|
892
|
-
try {
|
|
893
|
-
await withSpinner(`Creating ${colors.label(label.name)}`, async () => {
|
|
894
|
-
await createLabel(label);
|
|
895
|
-
});
|
|
896
|
-
created++;
|
|
897
|
-
} catch (error) {
|
|
898
|
-
logger.error(`Failed to create ${label.name}: ${error}`);
|
|
899
|
-
failed++;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
logger.newline();
|
|
903
|
-
logger.success(`Created ${created} labels`);
|
|
904
|
-
if (failed > 0) {
|
|
905
|
-
logger.warning(`Failed to create ${failed} labels`);
|
|
786
|
+
async function listLocalBranches() {
|
|
787
|
+
const { stdout } = await execa3("git", [
|
|
788
|
+
"branch",
|
|
789
|
+
"--format=%(refname:short)"
|
|
790
|
+
]);
|
|
791
|
+
return stdout.trim().split("\n").filter(Boolean);
|
|
792
|
+
}
|
|
793
|
+
async function remoteBranchExists(name) {
|
|
794
|
+
try {
|
|
795
|
+
await execa3("git", ["ls-remote", "--exit-code", "--heads", "origin", name]);
|
|
796
|
+
return true;
|
|
797
|
+
} catch {
|
|
798
|
+
return false;
|
|
906
799
|
}
|
|
907
|
-
|
|
908
|
-
|
|
800
|
+
}
|
|
801
|
+
async function fetchAndCheckout(name) {
|
|
802
|
+
await execa3("git", ["fetch", "origin", `${name}:${name}`]);
|
|
803
|
+
await execa3("git", ["checkout", name]);
|
|
909
804
|
}
|
|
910
805
|
|
|
911
806
|
export {
|
|
@@ -926,13 +821,6 @@ export {
|
|
|
926
821
|
checkInitialized,
|
|
927
822
|
isValidIssueNumber,
|
|
928
823
|
sanitizeSlug,
|
|
929
|
-
aiSpinnerText,
|
|
930
|
-
createSpinner,
|
|
931
|
-
withSpinner,
|
|
932
|
-
getWorkflowLabels,
|
|
933
|
-
buildIssueLabels,
|
|
934
|
-
extractTypeFromLabels,
|
|
935
|
-
sortByPriority,
|
|
936
824
|
checkLabelsExist,
|
|
937
825
|
getIssue,
|
|
938
826
|
listIssues,
|
|
@@ -940,6 +828,7 @@ export {
|
|
|
940
828
|
updateIssueLabels,
|
|
941
829
|
addIssueComment,
|
|
942
830
|
assignIssue,
|
|
831
|
+
createLabel,
|
|
943
832
|
createPullRequest,
|
|
944
833
|
getPrForBranch,
|
|
945
834
|
getPrStatus,
|
|
@@ -948,6 +837,24 @@ export {
|
|
|
948
837
|
replyToReviewComment,
|
|
949
838
|
addPrComment,
|
|
950
839
|
listOpenPrs,
|
|
951
|
-
|
|
840
|
+
getCurrentBranch,
|
|
841
|
+
isOnMainBranch,
|
|
842
|
+
getDefaultBranch,
|
|
843
|
+
branchExists,
|
|
844
|
+
createBranch,
|
|
845
|
+
checkoutBranch,
|
|
846
|
+
hasUncommittedChanges,
|
|
847
|
+
getUnpushedCommits,
|
|
848
|
+
pushBranch,
|
|
849
|
+
getAuthorInitials,
|
|
850
|
+
getRepoInfo,
|
|
851
|
+
getCommitsSinceBase,
|
|
852
|
+
getDiffSummary,
|
|
853
|
+
getCurrentCommitSha,
|
|
854
|
+
hasNewCommits,
|
|
855
|
+
getLastCommitTimestamp,
|
|
856
|
+
listLocalBranches,
|
|
857
|
+
remoteBranchExists,
|
|
858
|
+
fetchAndCheckout
|
|
952
859
|
};
|
|
953
|
-
//# sourceMappingURL=chunk-
|
|
860
|
+
//# sourceMappingURL=chunk-HCJWQPMW.js.map
|