@rotorsoft/gent 1.22.0 → 1.24.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-OIHSXI5X.js +43 -0
- package/dist/chunk-OIHSXI5X.js.map +1 -0
- package/dist/{chunk-75KVN7ZC.js → chunk-P5MZOU4B.js} +211 -308
- package/dist/chunk-P5MZOU4B.js.map +1 -0
- package/dist/chunk-YS7HWP4W.js +283 -0
- package/dist/chunk-YS7HWP4W.js.map +1 -0
- package/dist/github-remote-G6UKRDUB.js +9 -0
- package/dist/index.js +187 -259
- package/dist/index.js.map +1 -1
- package/dist/setup-labels-FZEN5TKM.js +9 -0
- package/dist/setup-labels-FZEN5TKM.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-G6UKRDUB.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,68 @@ 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
|
-
const
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
});
|
|
339
|
+
function isValidIssueNumber(value) {
|
|
340
|
+
const num = parseInt(value, 10);
|
|
341
|
+
return !isNaN(num) && num > 0;
|
|
342
|
+
}
|
|
343
|
+
function sanitizeSlug(title, maxLength = 40) {
|
|
344
|
+
return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength);
|
|
507
345
|
}
|
|
508
346
|
|
|
509
347
|
// src/lib/github.ts
|
|
510
|
-
import { execa } from "execa";
|
|
348
|
+
import { execa as execa2 } from "execa";
|
|
511
349
|
var WORKFLOW_LABELS = [
|
|
512
350
|
"ai-ready",
|
|
513
351
|
"ai-in-progress",
|
|
@@ -516,7 +354,7 @@ var WORKFLOW_LABELS = [
|
|
|
516
354
|
];
|
|
517
355
|
async function checkLabelsExist() {
|
|
518
356
|
try {
|
|
519
|
-
const { stdout } = await
|
|
357
|
+
const { stdout } = await execa2("gh", [
|
|
520
358
|
"label",
|
|
521
359
|
"list",
|
|
522
360
|
"--json",
|
|
@@ -532,7 +370,7 @@ async function checkLabelsExist() {
|
|
|
532
370
|
}
|
|
533
371
|
}
|
|
534
372
|
async function getIssue(issueNumber) {
|
|
535
|
-
const { stdout } = await
|
|
373
|
+
const { stdout } = await execa2("gh", [
|
|
536
374
|
"issue",
|
|
537
375
|
"view",
|
|
538
376
|
String(issueNumber),
|
|
@@ -564,7 +402,7 @@ async function listIssues(options) {
|
|
|
564
402
|
args.push("--state", options.state);
|
|
565
403
|
}
|
|
566
404
|
args.push("--limit", String(options.limit || 50));
|
|
567
|
-
const { stdout } = await
|
|
405
|
+
const { stdout } = await execa2("gh", args);
|
|
568
406
|
const data = JSON.parse(stdout);
|
|
569
407
|
return data.map(
|
|
570
408
|
(d) => ({
|
|
@@ -589,7 +427,7 @@ async function createIssue(options) {
|
|
|
589
427
|
if (options.labels?.length) {
|
|
590
428
|
args.push("--label", options.labels.join(","));
|
|
591
429
|
}
|
|
592
|
-
const { stdout } = await
|
|
430
|
+
const { stdout } = await execa2("gh", args);
|
|
593
431
|
const match = stdout.match(/\/issues\/(\d+)/);
|
|
594
432
|
if (!match) {
|
|
595
433
|
throw new Error("Failed to extract issue number from gh output");
|
|
@@ -600,7 +438,7 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
600
438
|
const promises = [];
|
|
601
439
|
if (options.add?.length) {
|
|
602
440
|
promises.push(
|
|
603
|
-
|
|
441
|
+
execa2("gh", [
|
|
604
442
|
"issue",
|
|
605
443
|
"edit",
|
|
606
444
|
String(issueNumber),
|
|
@@ -611,7 +449,7 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
611
449
|
}
|
|
612
450
|
if (options.remove?.length) {
|
|
613
451
|
promises.push(
|
|
614
|
-
|
|
452
|
+
execa2("gh", [
|
|
615
453
|
"issue",
|
|
616
454
|
"edit",
|
|
617
455
|
String(issueNumber),
|
|
@@ -623,10 +461,10 @@ async function updateIssueLabels(issueNumber, options) {
|
|
|
623
461
|
await Promise.all(promises);
|
|
624
462
|
}
|
|
625
463
|
async function addIssueComment(issueNumber, body) {
|
|
626
|
-
await
|
|
464
|
+
await execa2("gh", ["issue", "comment", String(issueNumber), "--body", body]);
|
|
627
465
|
}
|
|
628
466
|
async function assignIssue(issueNumber, assignee) {
|
|
629
|
-
await
|
|
467
|
+
await execa2("gh", [
|
|
630
468
|
"issue",
|
|
631
469
|
"edit",
|
|
632
470
|
String(issueNumber),
|
|
@@ -636,7 +474,7 @@ async function assignIssue(issueNumber, assignee) {
|
|
|
636
474
|
}
|
|
637
475
|
async function createLabel(label) {
|
|
638
476
|
try {
|
|
639
|
-
await
|
|
477
|
+
await execa2("gh", [
|
|
640
478
|
"label",
|
|
641
479
|
"create",
|
|
642
480
|
label.name,
|
|
@@ -666,12 +504,12 @@ async function createPullRequest(options) {
|
|
|
666
504
|
if (options.draft) {
|
|
667
505
|
args.push("--draft");
|
|
668
506
|
}
|
|
669
|
-
const { stdout } = await
|
|
507
|
+
const { stdout } = await execa2("gh", args);
|
|
670
508
|
return stdout.trim();
|
|
671
509
|
}
|
|
672
510
|
async function getPrForBranch() {
|
|
673
511
|
try {
|
|
674
|
-
const { stdout } = await
|
|
512
|
+
const { stdout } = await execa2("gh", [
|
|
675
513
|
"pr",
|
|
676
514
|
"view",
|
|
677
515
|
"--json",
|
|
@@ -685,7 +523,7 @@ async function getPrForBranch() {
|
|
|
685
523
|
}
|
|
686
524
|
async function getPrStatus() {
|
|
687
525
|
try {
|
|
688
|
-
const { stdout } = await
|
|
526
|
+
const { stdout } = await execa2("gh", [
|
|
689
527
|
"pr",
|
|
690
528
|
"view",
|
|
691
529
|
"--json",
|
|
@@ -711,11 +549,11 @@ async function getPrReviewData(prNumber) {
|
|
|
711
549
|
prArgs.push(String(prNumber));
|
|
712
550
|
}
|
|
713
551
|
prArgs.push("--json", "reviews,comments");
|
|
714
|
-
const { stdout: prStdout } = await
|
|
552
|
+
const { stdout: prStdout } = await execa2("gh", prArgs);
|
|
715
553
|
const prData = JSON.parse(prStdout);
|
|
716
554
|
let reviewThreads = [];
|
|
717
555
|
try {
|
|
718
|
-
const { stdout: repoStdout } = await
|
|
556
|
+
const { stdout: repoStdout } = await execa2("gh", [
|
|
719
557
|
"repo",
|
|
720
558
|
"view",
|
|
721
559
|
"--json",
|
|
@@ -725,7 +563,7 @@ async function getPrReviewData(prNumber) {
|
|
|
725
563
|
const owner = repoData.owner?.login ?? repoData.owner;
|
|
726
564
|
const repo = repoData.name;
|
|
727
565
|
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
|
|
566
|
+
const { stdout: graphqlStdout } = await execa2("gh", [
|
|
729
567
|
"api",
|
|
730
568
|
"graphql",
|
|
731
569
|
"-f",
|
|
@@ -774,11 +612,11 @@ async function getPrReviewData(prNumber) {
|
|
|
774
612
|
};
|
|
775
613
|
}
|
|
776
614
|
async function getCurrentUser() {
|
|
777
|
-
const { stdout } = await
|
|
615
|
+
const { stdout } = await execa2("gh", ["api", "user", "--jq", ".login"]);
|
|
778
616
|
return stdout.trim();
|
|
779
617
|
}
|
|
780
618
|
async function replyToReviewComment(prNumber, commentId, body) {
|
|
781
|
-
await
|
|
619
|
+
await execa2("gh", [
|
|
782
620
|
"api",
|
|
783
621
|
`repos/{owner}/{repo}/pulls/${prNumber}/comments/${commentId}/replies`,
|
|
784
622
|
"-f",
|
|
@@ -786,10 +624,10 @@ async function replyToReviewComment(prNumber, commentId, body) {
|
|
|
786
624
|
]);
|
|
787
625
|
}
|
|
788
626
|
async function addPrComment(prNumber, body) {
|
|
789
|
-
await
|
|
627
|
+
await execa2("gh", ["pr", "comment", String(prNumber), "--body", body]);
|
|
790
628
|
}
|
|
791
629
|
async function listOpenPrs(limit = 30) {
|
|
792
|
-
const { stdout } = await
|
|
630
|
+
const { stdout } = await execa2("gh", [
|
|
793
631
|
"pr",
|
|
794
632
|
"list",
|
|
795
633
|
"--state",
|
|
@@ -810,102 +648,156 @@ async function listOpenPrs(limit = 30) {
|
|
|
810
648
|
);
|
|
811
649
|
}
|
|
812
650
|
|
|
813
|
-
// src/
|
|
814
|
-
import { execa as
|
|
815
|
-
async function
|
|
651
|
+
// src/lib/git.ts
|
|
652
|
+
import { execa as execa3 } from "execa";
|
|
653
|
+
async function getCurrentBranch() {
|
|
654
|
+
const { stdout } = await execa3("git", ["branch", "--show-current"]);
|
|
655
|
+
return stdout.trim();
|
|
656
|
+
}
|
|
657
|
+
async function isOnMainBranch() {
|
|
658
|
+
const branch = await getCurrentBranch();
|
|
659
|
+
return branch === "main" || branch === "master";
|
|
660
|
+
}
|
|
661
|
+
async function getDefaultBranch() {
|
|
816
662
|
try {
|
|
817
|
-
await
|
|
818
|
-
|
|
663
|
+
const { stdout } = await execa3("git", [
|
|
664
|
+
"symbolic-ref",
|
|
665
|
+
"refs/remotes/origin/HEAD"
|
|
666
|
+
]);
|
|
667
|
+
return stdout.trim().replace("refs/remotes/origin/", "");
|
|
819
668
|
} catch {
|
|
820
|
-
|
|
669
|
+
try {
|
|
670
|
+
await execa3("git", ["rev-parse", "--verify", "main"]);
|
|
671
|
+
return "main";
|
|
672
|
+
} catch {
|
|
673
|
+
return "master";
|
|
674
|
+
}
|
|
821
675
|
}
|
|
822
676
|
}
|
|
823
|
-
async function
|
|
677
|
+
async function branchExists(name) {
|
|
824
678
|
try {
|
|
825
|
-
await
|
|
679
|
+
await execa3("git", ["rev-parse", "--verify", name]);
|
|
826
680
|
return true;
|
|
827
681
|
} catch {
|
|
828
682
|
return false;
|
|
829
683
|
}
|
|
830
684
|
}
|
|
831
|
-
async function
|
|
685
|
+
async function createBranch(name, from) {
|
|
686
|
+
if (from) {
|
|
687
|
+
await execa3("git", ["checkout", "-b", name, from]);
|
|
688
|
+
} else {
|
|
689
|
+
await execa3("git", ["checkout", "-b", name]);
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
async function checkoutBranch(name) {
|
|
693
|
+
await execa3("git", ["checkout", name]);
|
|
694
|
+
}
|
|
695
|
+
async function hasUncommittedChanges() {
|
|
696
|
+
const { stdout } = await execa3("git", ["status", "--porcelain"]);
|
|
697
|
+
return stdout.trim().length > 0;
|
|
698
|
+
}
|
|
699
|
+
async function getUnpushedCommits() {
|
|
832
700
|
try {
|
|
833
|
-
await
|
|
701
|
+
const { stdout } = await execa3("git", ["log", "@{u}..HEAD", "--oneline"]);
|
|
702
|
+
return stdout.trim().length > 0;
|
|
703
|
+
} catch {
|
|
834
704
|
return true;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
async function pushBranch(branch) {
|
|
708
|
+
const branchName = branch || await getCurrentBranch();
|
|
709
|
+
await execa3("git", ["push", "-u", "origin", branchName]);
|
|
710
|
+
}
|
|
711
|
+
async function getAuthorInitials() {
|
|
712
|
+
try {
|
|
713
|
+
const { stdout } = await execa3("git", ["config", "user.initials"]);
|
|
714
|
+
if (stdout.trim()) {
|
|
715
|
+
return stdout.trim();
|
|
716
|
+
}
|
|
835
717
|
} catch {
|
|
836
|
-
return false;
|
|
837
718
|
}
|
|
719
|
+
try {
|
|
720
|
+
const { stdout } = await execa3("git", ["config", "user.name"]);
|
|
721
|
+
const name = stdout.trim();
|
|
722
|
+
if (name) {
|
|
723
|
+
const parts = name.split(/\s+/);
|
|
724
|
+
return parts.map((p) => p[0]?.toLowerCase() || "").join("");
|
|
725
|
+
}
|
|
726
|
+
} catch {
|
|
727
|
+
}
|
|
728
|
+
return "dev";
|
|
838
729
|
}
|
|
839
|
-
async function
|
|
730
|
+
async function getRepoInfo() {
|
|
840
731
|
try {
|
|
841
|
-
await
|
|
842
|
-
|
|
732
|
+
const { stdout } = await execa3("git", [
|
|
733
|
+
"config",
|
|
734
|
+
"--get",
|
|
735
|
+
"remote.origin.url"
|
|
736
|
+
]);
|
|
737
|
+
const url = stdout.trim();
|
|
738
|
+
const sshMatch = url.match(/git@github\.com:([^/]+)\/([^.]+)/);
|
|
739
|
+
if (sshMatch) {
|
|
740
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
741
|
+
}
|
|
742
|
+
const httpsMatch = url.match(/github\.com\/([^/]+)\/([^.]+)/);
|
|
743
|
+
if (httpsMatch) {
|
|
744
|
+
return { owner: httpsMatch[1], repo: httpsMatch[2] };
|
|
745
|
+
}
|
|
746
|
+
return null;
|
|
843
747
|
} catch {
|
|
844
|
-
return
|
|
748
|
+
return null;
|
|
845
749
|
}
|
|
846
750
|
}
|
|
847
|
-
async function
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
751
|
+
async function getCommitsSinceBase(base = "main") {
|
|
752
|
+
try {
|
|
753
|
+
const { stdout } = await execa3("git", [
|
|
754
|
+
"log",
|
|
755
|
+
`${base}..HEAD`,
|
|
756
|
+
"--pretty=format:%s"
|
|
757
|
+
]);
|
|
758
|
+
return stdout.trim().split("\n").filter(Boolean);
|
|
759
|
+
} catch {
|
|
760
|
+
return [];
|
|
855
761
|
}
|
|
856
762
|
}
|
|
857
|
-
async function
|
|
763
|
+
async function getDiffSummary(base = "main") {
|
|
858
764
|
try {
|
|
859
|
-
await
|
|
860
|
-
return
|
|
765
|
+
const { stdout } = await execa3("git", ["diff", `${base}...HEAD`, "--stat"]);
|
|
766
|
+
return stdout.trim();
|
|
861
767
|
} catch {
|
|
862
|
-
return
|
|
768
|
+
return "";
|
|
863
769
|
}
|
|
864
770
|
}
|
|
865
|
-
function
|
|
866
|
-
|
|
771
|
+
async function getCurrentCommitSha() {
|
|
772
|
+
const { stdout } = await execa3("git", ["rev-parse", "HEAD"]);
|
|
773
|
+
return stdout.trim();
|
|
867
774
|
}
|
|
868
|
-
function
|
|
869
|
-
const
|
|
870
|
-
return
|
|
775
|
+
async function hasNewCommits(beforeSha) {
|
|
776
|
+
const currentSha = await getCurrentCommitSha();
|
|
777
|
+
return currentSha !== beforeSha;
|
|
871
778
|
}
|
|
872
|
-
function
|
|
873
|
-
|
|
779
|
+
async function getLastCommitTimestamp() {
|
|
780
|
+
const { stdout } = await execa3("git", ["log", "-1", "--format=%cI"]);
|
|
781
|
+
return stdout.trim();
|
|
874
782
|
}
|
|
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`);
|
|
783
|
+
async function listLocalBranches() {
|
|
784
|
+
const { stdout } = await execa3("git", [
|
|
785
|
+
"branch",
|
|
786
|
+
"--format=%(refname:short)"
|
|
787
|
+
]);
|
|
788
|
+
return stdout.trim().split("\n").filter(Boolean);
|
|
789
|
+
}
|
|
790
|
+
async function remoteBranchExists(name) {
|
|
791
|
+
try {
|
|
792
|
+
await execa3("git", ["ls-remote", "--exit-code", "--heads", "origin", name]);
|
|
793
|
+
return true;
|
|
794
|
+
} catch {
|
|
795
|
+
return false;
|
|
906
796
|
}
|
|
907
|
-
|
|
908
|
-
|
|
797
|
+
}
|
|
798
|
+
async function fetchAndCheckout(name) {
|
|
799
|
+
await execa3("git", ["fetch", "origin", `${name}:${name}`]);
|
|
800
|
+
await execa3("git", ["checkout", name]);
|
|
909
801
|
}
|
|
910
802
|
|
|
911
803
|
export {
|
|
@@ -923,16 +815,8 @@ export {
|
|
|
923
815
|
checkGeminiCli,
|
|
924
816
|
checkAIProvider,
|
|
925
817
|
checkGitRepo,
|
|
926
|
-
checkInitialized,
|
|
927
818
|
isValidIssueNumber,
|
|
928
819
|
sanitizeSlug,
|
|
929
|
-
aiSpinnerText,
|
|
930
|
-
createSpinner,
|
|
931
|
-
withSpinner,
|
|
932
|
-
getWorkflowLabels,
|
|
933
|
-
buildIssueLabels,
|
|
934
|
-
extractTypeFromLabels,
|
|
935
|
-
sortByPriority,
|
|
936
820
|
checkLabelsExist,
|
|
937
821
|
getIssue,
|
|
938
822
|
listIssues,
|
|
@@ -940,6 +824,7 @@ export {
|
|
|
940
824
|
updateIssueLabels,
|
|
941
825
|
addIssueComment,
|
|
942
826
|
assignIssue,
|
|
827
|
+
createLabel,
|
|
943
828
|
createPullRequest,
|
|
944
829
|
getPrForBranch,
|
|
945
830
|
getPrStatus,
|
|
@@ -948,6 +833,24 @@ export {
|
|
|
948
833
|
replyToReviewComment,
|
|
949
834
|
addPrComment,
|
|
950
835
|
listOpenPrs,
|
|
951
|
-
|
|
836
|
+
getCurrentBranch,
|
|
837
|
+
isOnMainBranch,
|
|
838
|
+
getDefaultBranch,
|
|
839
|
+
branchExists,
|
|
840
|
+
createBranch,
|
|
841
|
+
checkoutBranch,
|
|
842
|
+
hasUncommittedChanges,
|
|
843
|
+
getUnpushedCommits,
|
|
844
|
+
pushBranch,
|
|
845
|
+
getAuthorInitials,
|
|
846
|
+
getRepoInfo,
|
|
847
|
+
getCommitsSinceBase,
|
|
848
|
+
getDiffSummary,
|
|
849
|
+
getCurrentCommitSha,
|
|
850
|
+
hasNewCommits,
|
|
851
|
+
getLastCommitTimestamp,
|
|
852
|
+
listLocalBranches,
|
|
853
|
+
remoteBranchExists,
|
|
854
|
+
fetchAndCheckout
|
|
952
855
|
};
|
|
953
|
-
//# sourceMappingURL=chunk-
|
|
856
|
+
//# sourceMappingURL=chunk-P5MZOU4B.js.map
|