@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.
@@ -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/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 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 execa("gh", [
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 execa("gh", [
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 execa("gh", args);
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 execa("gh", args);
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
- execa("gh", [
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
- execa("gh", [
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 execa("gh", ["issue", "comment", String(issueNumber), "--body", body]);
467
+ await execa2("gh", ["issue", "comment", String(issueNumber), "--body", body]);
627
468
  }
628
469
  async function assignIssue(issueNumber, assignee) {
629
- await execa("gh", [
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 execa("gh", [
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 execa("gh", args);
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 execa("gh", [
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 execa("gh", [
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 execa("gh", prArgs);
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 execa("gh", [
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 execa("gh", [
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 execa("gh", ["api", "user", "--jq", ".login"]);
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 execa("gh", [
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 execa("gh", ["pr", "comment", String(prNumber), "--body", body]);
630
+ await execa2("gh", ["pr", "comment", String(prNumber), "--body", body]);
790
631
  }
791
632
  async function listOpenPrs(limit = 30) {
792
- const { stdout } = await execa("gh", [
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/utils/validators.ts
814
- import { execa as execa2 } from "execa";
815
- async function checkGhAuth() {
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 execa2("gh", ["auth", "status"]);
818
- return true;
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
- return false;
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 checkClaudeCli() {
680
+ async function branchExists(name) {
824
681
  try {
825
- await execa2("claude", ["--version"]);
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 checkGeminiCli() {
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 execa2("gemini", ["--version"]);
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 checkCodexCLI() {
733
+ async function getRepoInfo() {
840
734
  try {
841
- await execa2("codex", ["--version"]);
842
- return true;
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 false;
751
+ return null;
845
752
  }
846
753
  }
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();
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 checkGitRepo() {
766
+ async function getDiffSummary(base = "main") {
858
767
  try {
859
- await execa2("git", ["rev-parse", "--git-dir"]);
860
- return true;
768
+ const { stdout } = await execa3("git", ["diff", `${base}...HEAD`, "--stat"]);
769
+ return stdout.trim();
861
770
  } catch {
862
- return false;
771
+ return "";
863
772
  }
864
773
  }
865
- function checkInitialized(cwd) {
866
- return configExists(cwd);
774
+ async function getCurrentCommitSha() {
775
+ const { stdout } = await execa3("git", ["rev-parse", "HEAD"]);
776
+ return stdout.trim();
867
777
  }
868
- function isValidIssueNumber(value) {
869
- const num = parseInt(value, 10);
870
- return !isNaN(num) && num > 0;
778
+ async function hasNewCommits(beforeSha) {
779
+ const currentSha = await getCurrentCommitSha();
780
+ return currentSha !== beforeSha;
871
781
  }
872
- function sanitizeSlug(title, maxLength = 40) {
873
- return title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, maxLength);
782
+ async function getLastCommitTimestamp() {
783
+ const { stdout } = await execa3("git", ["log", "-1", "--format=%cI"]);
784
+ return stdout.trim();
874
785
  }
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`);
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
- logger.newline();
908
- logger.info("Labels are ready. You can now create AI-ready issues.");
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
- setupLabelsCommand
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-75KVN7ZC.js.map
860
+ //# sourceMappingURL=chunk-HCJWQPMW.js.map