@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.
@@ -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/types/index.ts
312
- var DEFAULT_LABELS = {
313
- workflow: [
314
- {
315
- name: "ai-ready",
316
- color: "0E8A16",
317
- description: "Issue ready for AI implementation"
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
- for (const area of config.github.labels.areas) {
452
- const defaultLabel = DEFAULT_LABELS.area.find(
453
- (l) => l.name === `area:${area}`
454
- );
455
- if (defaultLabel) {
456
- labels.push(defaultLabel);
457
- } else {
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 getWorkflowLabels(config) {
468
- return {
469
- ready: config.github.labels.workflow.ready,
470
- inProgress: config.github.labels.workflow.in_progress,
471
- completed: config.github.labels.workflow.completed,
472
- blocked: config.github.labels.workflow.blocked
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 buildIssueLabels(meta) {
476
- return [
477
- "ai-ready",
478
- `type:${meta.type}`,
479
- `priority:${meta.priority}`,
480
- `risk:${meta.risk}`,
481
- `area:${meta.area}`
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 extractTypeFromLabels(labels) {
485
- for (const label of labels) {
486
- if (label.startsWith("type:")) {
487
- return label.replace("type:", "");
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 extractPriorityFromLabels(labels) {
493
- for (const label of labels) {
494
- if (label.startsWith("priority:")) {
495
- return label.replace("priority:", "");
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 sortByPriority(issues) {
501
- const priorityOrder = ["critical", "high", "medium", "low"];
502
- issues.sort((a, b) => {
503
- const aPriority = extractPriorityFromLabels(a.labels);
504
- const bPriority = extractPriorityFromLabels(b.labels);
505
- return priorityOrder.indexOf(aPriority) - priorityOrder.indexOf(bPriority);
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 execa("gh", [
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 execa("gh", [
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 execa("gh", args);
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 execa("gh", args);
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
- execa("gh", [
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
- execa("gh", [
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 execa("gh", ["issue", "comment", String(issueNumber), "--body", body]);
464
+ await execa2("gh", ["issue", "comment", String(issueNumber), "--body", body]);
627
465
  }
628
466
  async function assignIssue(issueNumber, assignee) {
629
- await execa("gh", [
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 execa("gh", [
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 execa("gh", args);
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 execa("gh", [
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 execa("gh", [
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 execa("gh", prArgs);
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 execa("gh", [
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 execa("gh", [
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 execa("gh", ["api", "user", "--jq", ".login"]);
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 execa("gh", [
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 execa("gh", ["pr", "comment", String(prNumber), "--body", body]);
627
+ await execa2("gh", ["pr", "comment", String(prNumber), "--body", body]);
790
628
  }
791
629
  async function listOpenPrs(limit = 30) {
792
- const { stdout } = await execa("gh", [
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/utils/validators.ts
814
- import { execa as execa2 } from "execa";
815
- async function checkGhAuth() {
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 execa2("gh", ["auth", "status"]);
818
- return true;
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
- return false;
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 checkClaudeCli() {
677
+ async function branchExists(name) {
824
678
  try {
825
- await execa2("claude", ["--version"]);
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 checkGeminiCli() {
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 execa2("gemini", ["--version"]);
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 checkCodexCLI() {
730
+ async function getRepoInfo() {
840
731
  try {
841
- await execa2("codex", ["--version"]);
842
- return true;
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 false;
748
+ return null;
845
749
  }
846
750
  }
847
- async function checkAIProvider(provider) {
848
- switch (provider) {
849
- case "claude":
850
- return checkClaudeCli();
851
- case "gemini":
852
- return checkGeminiCli();
853
- case "codex":
854
- return checkCodexCLI();
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 checkGitRepo() {
763
+ async function getDiffSummary(base = "main") {
858
764
  try {
859
- await execa2("git", ["rev-parse", "--git-dir"]);
860
- return true;
765
+ const { stdout } = await execa3("git", ["diff", `${base}...HEAD`, "--stat"]);
766
+ return stdout.trim();
861
767
  } catch {
862
- return false;
768
+ return "";
863
769
  }
864
770
  }
865
- function checkInitialized(cwd) {
866
- return configExists(cwd);
771
+ async function getCurrentCommitSha() {
772
+ const { stdout } = await execa3("git", ["rev-parse", "HEAD"]);
773
+ return stdout.trim();
867
774
  }
868
- function isValidIssueNumber(value) {
869
- const num = parseInt(value, 10);
870
- return !isNaN(num) && num > 0;
775
+ async function hasNewCommits(beforeSha) {
776
+ const currentSha = await getCurrentCommitSha();
777
+ return currentSha !== beforeSha;
871
778
  }
872
- function sanitizeSlug(title, maxLength = 40) {
873
- return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength);
779
+ async function getLastCommitTimestamp() {
780
+ const { stdout } = await execa3("git", ["log", "-1", "--format=%cI"]);
781
+ return stdout.trim();
874
782
  }
875
-
876
- // src/commands/setup-labels.ts
877
- async function setupLabelsCommand() {
878
- logger.bold("Setting up GitHub labels...");
879
- logger.newline();
880
- const isAuthed = await checkGhAuth();
881
- if (!isAuthed) {
882
- logger.error("Not authenticated with GitHub. Run 'gh auth login' first.");
883
- process.exit(1);
884
- }
885
- const config = loadConfig();
886
- const labels = getAllLabels(config);
887
- logger.info(`Creating ${labels.length} labels...`);
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
- logger.newline();
908
- logger.info("Labels are ready. You can now create AI-ready issues.");
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
- setupLabelsCommand
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-75KVN7ZC.js.map
856
+ //# sourceMappingURL=chunk-P5MZOU4B.js.map