gut-cli 0.1.27 → 0.1.29

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 godai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.js CHANGED
@@ -927,6 +927,34 @@ function requireGhCli() {
927
927
  }
928
928
  return true;
929
929
  }
930
+ function getDefaultBranch() {
931
+ if (!isGhCliInstalled()) {
932
+ return null;
933
+ }
934
+ try {
935
+ const result = execSync2('gh repo view --json defaultBranchRef --jq ".defaultBranchRef.name"', {
936
+ stdio: ["pipe", "pipe", "pipe"]
937
+ });
938
+ const branch = result.toString().trim();
939
+ return branch || null;
940
+ } catch {
941
+ return null;
942
+ }
943
+ }
944
+ function getExistingPrUrl() {
945
+ if (!isGhCliInstalled()) {
946
+ return null;
947
+ }
948
+ try {
949
+ const result = execSync2('gh pr view --json url --jq ".url"', {
950
+ stdio: ["pipe", "pipe", "pipe"]
951
+ });
952
+ const url = result.toString().trim();
953
+ return url || null;
954
+ } catch {
955
+ return null;
956
+ }
957
+ }
930
958
 
931
959
  // src/commands/branch.ts
932
960
  function getIssueInfo(issueNumber) {
@@ -2387,7 +2415,10 @@ var prCommand = new Command14("pr").description("Generate a pull request title a
2387
2415
  const currentBranch = branchInfo.current;
2388
2416
  let baseBranch = options.base;
2389
2417
  if (!baseBranch) {
2390
- if (branchInfo.all.includes("main")) {
2418
+ const ghDefaultBranch = getDefaultBranch();
2419
+ if (ghDefaultBranch) {
2420
+ baseBranch = ghDefaultBranch;
2421
+ } else if (branchInfo.all.includes("main")) {
2391
2422
  baseBranch = "main";
2392
2423
  } else if (branchInfo.all.includes("master")) {
2393
2424
  baseBranch = "master";
@@ -2452,35 +2483,55 @@ ${body}`;
2452
2483
  console.log(chalk15.gray("\nTip: Use --copy to copy to clipboard"));
2453
2484
  }
2454
2485
  } else {
2486
+ const existingPrUrl = getExistingPrUrl();
2487
+ const isUpdate = !!existingPrUrl;
2455
2488
  const readline = await import("readline");
2456
2489
  const rl = readline.createInterface({
2457
2490
  input: process.stdin,
2458
2491
  output: process.stdout
2459
2492
  });
2460
- const promptMessage = options.create ? chalk15.cyan("\nCreate PR with this description? (y/N) ") : chalk15.cyan("\nCreate PR with gh CLI? (y/N) ");
2493
+ let promptMessage;
2494
+ if (isUpdate) {
2495
+ promptMessage = chalk15.cyan(`
2496
+ Update existing PR? (${existingPrUrl}) (y/N) `);
2497
+ } else if (options.create) {
2498
+ promptMessage = chalk15.cyan("\nCreate PR with this description? (y/N) ");
2499
+ } else {
2500
+ promptMessage = chalk15.cyan("\nCreate PR with gh CLI? (y/N) ");
2501
+ }
2461
2502
  const answer = await new Promise((resolve) => {
2462
2503
  rl.question(promptMessage, resolve);
2463
2504
  });
2464
2505
  rl.close();
2465
2506
  if (answer.toLowerCase() === "y") {
2466
- const createSpinner = ora11("Creating PR...").start();
2507
+ const actionSpinner = ora11(isUpdate ? "Updating PR..." : "Creating PR...").start();
2467
2508
  try {
2468
2509
  const escapedTitle = title.replace(/"/g, '\\"').replace(/`/g, "\\`").replace(/\$/g, "\\$");
2469
- const result = execSync7(
2470
- `gh pr create --title "${escapedTitle}" --body-file - --base ${baseBranch}`,
2471
- {
2510
+ let prUrl;
2511
+ if (isUpdate) {
2512
+ execSync7(`gh pr edit --title "${escapedTitle}" --body-file -`, {
2472
2513
  stdio: ["pipe", "pipe", "pipe"],
2473
2514
  input: body
2474
- }
2475
- );
2476
- const prUrl = result.toString().trim();
2477
- createSpinner.succeed("PR created successfully!");
2515
+ });
2516
+ prUrl = existingPrUrl;
2517
+ actionSpinner.succeed("PR updated successfully!");
2518
+ } else {
2519
+ const result = execSync7(
2520
+ `gh pr create --title "${escapedTitle}" --body-file - --base ${baseBranch}`,
2521
+ {
2522
+ stdio: ["pipe", "pipe", "pipe"],
2523
+ input: body
2524
+ }
2525
+ );
2526
+ prUrl = result.toString().trim();
2527
+ actionSpinner.succeed("PR created successfully!");
2528
+ }
2478
2529
  if (prUrl) {
2479
2530
  console.log(chalk15.green(`
2480
2531
  \u{1F517} ${prUrl}`));
2481
2532
  }
2482
2533
  } catch (err) {
2483
- createSpinner.fail("Failed to create PR");
2534
+ actionSpinner.fail(isUpdate ? "Failed to update PR" : "Failed to create PR");
2484
2535
  if (err instanceof Error && "stderr" in err) {
2485
2536
  const stderr = err.stderr?.toString?.() || "";
2486
2537
  if (stderr.includes("auth")) {