@rotorsoft/gent 1.19.0 → 1.20.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/index.js CHANGED
@@ -2242,7 +2242,7 @@ import { homedir } from "os";
2242
2242
  // package.json
2243
2243
  var package_default = {
2244
2244
  name: "@rotorsoft/gent",
2245
- version: "1.19.0",
2245
+ version: "1.20.0",
2246
2246
  description: "AI-powered GitHub workflow CLI - leverage AI (Claude, Gemini, or Codex) to create tickets, implement features, and manage PRs",
2247
2247
  keywords: [
2248
2248
  "cli",
@@ -2664,7 +2664,7 @@ async function statusCommand() {
2664
2664
  }
2665
2665
 
2666
2666
  // src/commands/tui.ts
2667
- import { execa as execa4 } from "execa";
2667
+ import { execa as execa5 } from "execa";
2668
2668
 
2669
2669
  // src/tui/state.ts
2670
2670
  var envCache = null;
@@ -2821,7 +2821,11 @@ function getAvailableActions(state) {
2821
2821
  actions.push({ id: "run", label: "run", shortcut: "r" });
2822
2822
  }
2823
2823
  }
2824
- actions.push({ id: "list", label: "list", shortcut: "l" });
2824
+ if (state.hasValidRemote) {
2825
+ actions.push({ id: "list", label: "list", shortcut: "l" });
2826
+ } else {
2827
+ actions.push({ id: "github-remote", label: "github", shortcut: "g" });
2828
+ }
2825
2829
  actions.push({ id: "refresh", label: "refresh", shortcut: "f" });
2826
2830
  actions.push({ id: "switch-provider", label: "ai", shortcut: "a" });
2827
2831
  actions.push({ id: "quit", label: "quit", shortcut: "q" });
@@ -3114,7 +3118,7 @@ function buildDashboardLines(state, actions, hint, refreshing, versionCheck) {
3114
3118
  out(
3115
3119
  row(
3116
3120
  chalk3.yellow(
3117
- "Add a GitHub remote to create tickets and pull requests"
3121
+ "Press [g] to create a GitHub repo and push"
3118
3122
  ),
3119
3123
  w
3120
3124
  )
@@ -3632,6 +3636,38 @@ function showStatus(title, message, dashboardLines) {
3632
3636
  renderOverlay(dashboardLines, lines, w);
3633
3637
  }
3634
3638
 
3639
+ // src/commands/github-remote.ts
3640
+ import { execa as execa4 } from "execa";
3641
+ async function githubRemoteCommand() {
3642
+ const isAuthenticated = await checkGhAuth();
3643
+ if (!isAuthenticated) {
3644
+ logger.error("GitHub CLI is not authenticated. Run: gh auth login");
3645
+ return false;
3646
+ }
3647
+ try {
3648
+ try {
3649
+ const { stdout } = await execa4("git", [
3650
+ "config",
3651
+ "--get",
3652
+ "remote.origin.url"
3653
+ ]);
3654
+ if (stdout.trim()) {
3655
+ logger.error("Remote origin already exists: " + stdout.trim());
3656
+ return false;
3657
+ }
3658
+ } catch {
3659
+ }
3660
+ logger.info("Creating GitHub repository...");
3661
+ await execa4("gh", ["repo", "create", "--source=.", "--push", "--private"]);
3662
+ const branch = await getCurrentBranch();
3663
+ logger.success(`Repository created and ${branch} pushed to GitHub`);
3664
+ return true;
3665
+ } catch (error) {
3666
+ logger.error(`Failed to create remote: ${error}`);
3667
+ return false;
3668
+ }
3669
+ }
3670
+
3635
3671
  // src/commands/tui.ts
3636
3672
  var CANCEL = /* @__PURE__ */ Symbol("cancel");
3637
3673
  async function waitForKey(validKeys) {
@@ -3701,6 +3737,17 @@ async function executeAction(actionId, state, dashboardLines) {
3701
3737
  await handleRun(state);
3702
3738
  return CONTINUE;
3703
3739
  }
3740
+ case "github-remote": {
3741
+ const confirmed = await showConfirm({
3742
+ title: "Push to GitHub",
3743
+ message: "Create a private GitHub repo and push?",
3744
+ dashboardLines
3745
+ });
3746
+ if (!confirmed) return SKIP_REFRESH;
3747
+ showStatus("Pushing", "Creating GitHub repo and pushing...", dashboardLines);
3748
+ await githubRemoteCommand();
3749
+ return CONTINUE;
3750
+ }
3704
3751
  case "switch-provider":
3705
3752
  await handleSwitchProvider(state, dashboardLines);
3706
3753
  return SKIP_REFRESH;
@@ -3712,19 +3759,19 @@ async function executeAction(actionId, state, dashboardLines) {
3712
3759
  }
3713
3760
  async function handleCommit(state, dashboardLines) {
3714
3761
  try {
3715
- const { stdout: status } = await execa4("git", ["status", "--short"]);
3762
+ const { stdout: status } = await execa5("git", ["status", "--short"]);
3716
3763
  if (!status.trim()) {
3717
3764
  showStatus("Commit", "No changes to commit", dashboardLines);
3718
3765
  await new Promise((r) => setTimeout(r, 1500));
3719
3766
  return false;
3720
3767
  }
3721
- await execa4("git", ["add", "-A"]);
3722
- const { stdout: diffStat } = await execa4("git", [
3768
+ await execa5("git", ["add", "-A"]);
3769
+ const { stdout: diffStat } = await execa5("git", [
3723
3770
  "diff",
3724
3771
  "--cached",
3725
3772
  "--stat"
3726
3773
  ]);
3727
- const { stdout: diffPatch } = await execa4("git", ["diff", "--cached"]);
3774
+ const { stdout: diffPatch } = await execa5("git", ["diff", "--cached"]);
3728
3775
  const diffContent = (diffStat + "\n\n" + diffPatch).slice(0, 4e3);
3729
3776
  const issueNumber = state.issue?.number ?? null;
3730
3777
  const issueTitle = state.issue?.title ?? null;
@@ -3739,7 +3786,7 @@ async function handleCommit(state, dashboardLines) {
3739
3786
  dashboardLines
3740
3787
  });
3741
3788
  if (!mode) {
3742
- await execa4("git", ["reset", "HEAD"]);
3789
+ await execa5("git", ["reset", "HEAD"]);
3743
3790
  return false;
3744
3791
  }
3745
3792
  let message;
@@ -3761,7 +3808,7 @@ async function handleCommit(state, dashboardLines) {
3761
3808
  );
3762
3809
  }
3763
3810
  if (message === CANCEL) {
3764
- await execa4("git", ["reset", "HEAD"]);
3811
+ await execa5("git", ["reset", "HEAD"]);
3765
3812
  return false;
3766
3813
  }
3767
3814
  const confirmed = await showConfirm({
@@ -3770,7 +3817,7 @@ async function handleCommit(state, dashboardLines) {
3770
3817
  dashboardLines
3771
3818
  });
3772
3819
  if (!confirmed) {
3773
- await execa4("git", ["reset", "HEAD"]);
3820
+ await execa5("git", ["reset", "HEAD"]);
3774
3821
  return false;
3775
3822
  }
3776
3823
  const providerEmail = getProviderEmail(provider);
@@ -3778,7 +3825,7 @@ async function handleCommit(state, dashboardLines) {
3778
3825
 
3779
3826
  Co-Authored-By: ${providerName} <${providerEmail}>`;
3780
3827
  showStatus("Committing", "Committing changes...", dashboardLines);
3781
- await execa4("git", ["commit", "-m", fullMessage]);
3828
+ await execa5("git", ["commit", "-m", fullMessage]);
3782
3829
  return true;
3783
3830
  } catch (error) {
3784
3831
  logger.error(`Commit failed: ${error}`);
@@ -3858,10 +3905,10 @@ ${feedbackLines}`);
3858
3905
  }
3859
3906
  async function handlePush(dashboardLines) {
3860
3907
  try {
3861
- const { stdout: branch } = await execa4("git", ["branch", "--show-current"]);
3908
+ const { stdout: branch } = await execa5("git", ["branch", "--show-current"]);
3862
3909
  const branchName = branch.trim();
3863
3910
  showStatus("Pushing", `Pushing ${branchName} to remote...`, dashboardLines);
3864
- await execa4("git", ["push", "-u", "origin", branchName]);
3911
+ await execa5("git", ["push", "-u", "origin", branchName]);
3865
3912
  } catch (error) {
3866
3913
  logger.error(`Push failed: ${error}`);
3867
3914
  }
@@ -4176,6 +4223,9 @@ program.command("fix").description("Apply PR review feedback using AI").option(
4176
4223
  program.command("status").description("Show current workflow status").action(async () => {
4177
4224
  await statusCommand();
4178
4225
  });
4226
+ program.command("github-remote").description("Create a GitHub repository and push local repo").action(async () => {
4227
+ await githubRemoteCommand();
4228
+ });
4179
4229
  program.command("ui").description("Launch interactive dashboard").action(async () => {
4180
4230
  await tuiCommand();
4181
4231
  });