gut-cli 0.1.17 → 0.1.19

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/README.md CHANGED
@@ -361,6 +361,15 @@ gut config set lang en --local
361
361
 
362
362
  # Get current language
363
363
  gut config get lang
364
+
365
+ # Open global config folder
366
+ gut config open
367
+
368
+ # Open global templates folder
369
+ gut config open --templates
370
+
371
+ # Open project's .gut/ folder
372
+ gut config open --local
364
373
  ```
365
374
 
366
375
  **Available settings:**
@@ -372,12 +381,19 @@ gut config get lang
372
381
 
373
382
  ### `gut init`
374
383
 
375
- Initialize `.gut/` templates in your project for customization.
384
+ Initialize templates for customization (project-level or global).
376
385
 
377
386
  ```bash
378
387
  # Copy all templates to .gut/ (translates if language is not English)
379
388
  gut init
380
389
 
390
+ # Initialize global templates (~/.config/gut/templates/)
391
+ gut init --global
392
+
393
+ # Initialize and open folder
394
+ gut init --open
395
+ gut init --global --open
396
+
381
397
  # Force overwrite existing templates
382
398
  gut init --force
383
399
 
@@ -388,8 +404,15 @@ gut init --no-translate
388
404
  gut init --provider openai
389
405
  ```
390
406
 
407
+ To open templates folder without initializing, use `gut config open --templates`.
408
+
391
409
  Templates are automatically translated to your configured language (set via `gut lang`).
392
410
 
411
+ **Template precedence:**
412
+ 1. Project templates: `.gut/` (highest priority)
413
+ 2. Global templates: `~/.config/gut/templates/`
414
+ 3. Built-in templates (lowest priority)
415
+
393
416
  ### `gut gitignore`
394
417
 
395
418
  Generate a .gitignore file by analyzing your project structure.
@@ -466,26 +489,35 @@ API keys are stored securely using your operating system's native credential sto
466
489
 
467
490
  Keys are never stored in plain text files or configuration files. When you run `gut auth login`, the key is encrypted and managed by your OS.
468
491
 
469
- ## Project Configuration
492
+ ## Template Configuration
493
+
494
+ gut supports customizable templates at two levels:
495
+
496
+ **Project templates** (`.gut/`): Repository-specific customizations that apply only to the current project.
497
+
498
+ **Global templates** (`~/.config/gut/templates/`): User-wide defaults that apply across all projects.
499
+
500
+ **Precedence**: Project > Global > Built-in
470
501
 
471
- gut looks for template files in your repository's `.gut/` folder. Each template uses `{{variable}}` syntax for dynamic content.
502
+ Each template uses `{{variable}}` syntax for dynamic content.
472
503
 
473
504
  | File | Purpose |
474
505
  |------|---------|
475
- | `.gut/commit.md` | Commit message prompt |
476
- | `.gut/pr.md` | PR description prompt |
477
- | `.gut/branch.md` | Branch naming rules |
478
- | `.gut/checkout.md` | Checkout branch name prompt |
479
- | `.gut/merge.md` | Merge conflict resolution rules |
480
- | `.gut/review.md` | Code review criteria |
481
- | `.gut/explain.md` | Explanation context |
482
- | `.gut/explain-file.md` | File explanation context |
483
- | `.gut/find.md` | Commit search context |
484
- | `.gut/changelog.md` | Changelog format |
485
- | `.gut/stash.md` | Stash name prompt |
486
- | `.gut/summary.md` | Work summary format |
487
- | `.gut/gitignore.md` | Gitignore generation prompt |
488
- | `.github/pull_request_template.md` | GitHub PR template (prioritized over `.gut/pr.md`) |
506
+ | `commit.md` | Commit message prompt |
507
+ | `pr.md` | PR description prompt |
508
+ | `branch.md` | Branch naming rules |
509
+ | `checkout.md` | Checkout branch name prompt |
510
+ | `merge.md` | Merge conflict resolution rules |
511
+ | `review.md` | Code review criteria |
512
+ | `explain.md` | Explanation context |
513
+ | `explain-file.md` | File explanation context |
514
+ | `find.md` | Commit search context |
515
+ | `changelog.md` | Changelog format |
516
+ | `stash.md` | Stash name prompt |
517
+ | `summary.md` | Work summary format |
518
+ | `gitignore.md` | Gitignore generation prompt |
519
+
520
+ **Special case**: `.github/pull_request_template.md` is prioritized over `pr.md` for PR descriptions.
489
521
 
490
522
  ## Development
491
523
 
package/dist/index.js CHANGED
@@ -90,6 +90,7 @@ import { Command as Command2 } from "commander";
90
90
  import chalk2 from "chalk";
91
91
 
92
92
  // src/lib/credentials.ts
93
+ import { createRequire } from "module";
93
94
  var SERVICE_NAME = "gut-cli";
94
95
  var PROVIDER_KEY_MAP = {
95
96
  gemini: "gemini-api-key",
@@ -106,10 +107,10 @@ var FALLBACK_ENV_MAP = {
106
107
  openai: "OPENAI_API_KEY",
107
108
  anthropic: "ANTHROPIC_API_KEY"
108
109
  };
109
- async function getKeytar() {
110
+ function getKeytar() {
110
111
  try {
111
- const keytar = await import("keytar");
112
- return keytar.default || keytar;
112
+ const require2 = createRequire(import.meta.url);
113
+ return require2("keytar");
113
114
  } catch {
114
115
  return null;
115
116
  }
@@ -118,7 +119,7 @@ async function saveApiKey(provider, apiKey) {
118
119
  if (provider === "ollama") {
119
120
  throw new Error("Ollama does not require an API key");
120
121
  }
121
- const keytar = await getKeytar();
122
+ const keytar = getKeytar();
122
123
  if (!keytar) {
123
124
  throw new Error("Keychain not available. Set environment variable instead.");
124
125
  }
@@ -132,7 +133,7 @@ async function getApiKey(provider) {
132
133
  if (envKey) return envKey;
133
134
  const fallbackKey = process.env[FALLBACK_ENV_MAP[provider]];
134
135
  if (fallbackKey) return fallbackKey;
135
- const keytar = await getKeytar();
136
+ const keytar = getKeytar();
136
137
  if (!keytar) return null;
137
138
  return keytar.getPassword(SERVICE_NAME, PROVIDER_KEY_MAP[provider]);
138
139
  }
@@ -140,7 +141,7 @@ async function deleteApiKey(provider) {
140
141
  if (provider === "ollama") {
141
142
  throw new Error("Ollama does not use an API key");
142
143
  }
143
- const keytar = await getKeytar();
144
+ const keytar = getKeytar();
144
145
  if (!keytar) {
145
146
  throw new Error("Keychain not available.");
146
147
  }
@@ -289,6 +290,7 @@ import { createOllama } from "ollama-ai-provider";
289
290
  import { z } from "zod";
290
291
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
291
292
  import { join as join2, dirname } from "path";
293
+ import { homedir as homedir2 } from "os";
292
294
  import { fileURLToPath } from "url";
293
295
 
294
296
  // src/lib/config.ts
@@ -413,13 +415,27 @@ function loadTemplate(name) {
413
415
  }
414
416
  throw new Error(`Template not found: ${templatePath}`);
415
417
  }
416
- function findTemplate(repoRoot, templateName) {
417
- const templatePath = join2(repoRoot, ".gut", `${templateName}.md`);
418
+ function getGlobalTemplatesDir() {
419
+ return join2(homedir2(), ".config", "gut", "templates");
420
+ }
421
+ function findGlobalTemplate(templateName) {
422
+ const templatePath = join2(getGlobalTemplatesDir(), `${templateName}.md`);
418
423
  if (existsSync2(templatePath)) {
419
424
  return readFileSync2(templatePath, "utf-8");
420
425
  }
421
426
  return null;
422
427
  }
428
+ function findTemplate(repoRoot, templateName) {
429
+ const projectTemplatePath = join2(repoRoot, ".gut", `${templateName}.md`);
430
+ if (existsSync2(projectTemplatePath)) {
431
+ return readFileSync2(projectTemplatePath, "utf-8");
432
+ }
433
+ const globalTemplate = findGlobalTemplate(templateName);
434
+ if (globalTemplate) {
435
+ return globalTemplate;
436
+ }
437
+ return null;
438
+ }
423
439
  function applyTemplate(userTemplate, templateName, variables) {
424
440
  const langInstruction = getLanguageInstruction(getLanguage());
425
441
  let result = userTemplate || loadTemplate(templateName);
@@ -851,14 +867,14 @@ var commitCommand = new Command3("commit").description("Generate a commit messag
851
867
  console.log(chalk3.green("\u2713 Committed successfully"));
852
868
  } else if (answer.toLowerCase() === "e") {
853
869
  console.log(chalk3.gray("Opening editor..."));
854
- const { execSync: execSync7 } = await import("child_process");
870
+ const { execSync: execSync9 } = await import("child_process");
855
871
  const editor = process.env.EDITOR || process.env.VISUAL || "vi";
856
872
  const fs2 = await import("fs");
857
873
  const os = await import("os");
858
874
  const path2 = await import("path");
859
875
  const tmpFile = path2.join(os.tmpdir(), "gut-commit-msg.txt");
860
876
  fs2.writeFileSync(tmpFile, message);
861
- execSync7(`${editor} "${tmpFile}"`, { stdio: "inherit" });
877
+ execSync9(`${editor} "${tmpFile}"`, { stdio: "inherit" });
862
878
  const editedMessage = fs2.readFileSync(tmpFile, "utf-8").trim();
863
879
  fs2.unlinkSync(tmpFile);
864
880
  if (editedMessage) {
@@ -2196,9 +2212,9 @@ var summaryCommand = new Command14("summary").description("Generate a work summa
2196
2212
  const output = options.markdown ? formatMarkdown(summary, author, since, options.until) : null;
2197
2213
  if (options.copy) {
2198
2214
  const textToCopy = output || formatMarkdown(summary, author, since, options.until);
2199
- const { execSync: execSync7 } = await import("child_process");
2215
+ const { execSync: execSync9 } = await import("child_process");
2200
2216
  try {
2201
- execSync7("pbcopy", { input: textToCopy });
2217
+ execSync9("pbcopy", { input: textToCopy });
2202
2218
  console.log(chalk15.green("Summary copied to clipboard!"));
2203
2219
  console.log();
2204
2220
  } catch {
@@ -2314,6 +2330,16 @@ function printSummary(summary, author, since, until) {
2314
2330
  // src/commands/config.ts
2315
2331
  import { Command as Command15 } from "commander";
2316
2332
  import chalk16 from "chalk";
2333
+ import { execSync as execSync7 } from "child_process";
2334
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2 } from "fs";
2335
+ import { join as join5 } from "path";
2336
+ import { homedir as homedir3 } from "os";
2337
+ import { simpleGit as simpleGit14 } from "simple-git";
2338
+ function openFolder(path2) {
2339
+ const platform = process.platform;
2340
+ const cmd = platform === "darwin" ? "open" : platform === "win32" ? 'start ""' : "xdg-open";
2341
+ execSync7(`${cmd} "${path2}"`);
2342
+ }
2317
2343
  var configCommand = new Command15("config").description("Manage gut configuration");
2318
2344
  configCommand.command("set <key> <value>").description("Set a configuration value").option("--local", "Set for current repository only").action((key, value, options) => {
2319
2345
  if (key === "lang") {
@@ -2362,6 +2388,39 @@ configCommand.command("list").description("List all configuration values").actio
2362
2388
  console.log(chalk16.gray("Local config: .gut/config.json"));
2363
2389
  }
2364
2390
  });
2391
+ configCommand.command("open").description("Open configuration or templates folder").option("-t, --templates", "Open templates folder instead of config").option("-g, --global", "Open global folder (default)").option("-l, --local", "Open local/project folder").action(async (options) => {
2392
+ const git = simpleGit14();
2393
+ const isLocal = options.local === true;
2394
+ let targetPath;
2395
+ if (isLocal) {
2396
+ const isRepo = await git.checkIsRepo();
2397
+ if (!isRepo) {
2398
+ console.error(chalk16.red("Error: Not a git repository"));
2399
+ console.error(chalk16.gray("Use --global to open global config folder"));
2400
+ process.exit(1);
2401
+ }
2402
+ const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
2403
+ targetPath = join5(repoRoot.trim(), ".gut");
2404
+ } else {
2405
+ if (options.templates) {
2406
+ targetPath = join5(homedir3(), ".config", "gut", "templates");
2407
+ } else {
2408
+ targetPath = join5(homedir3(), ".config", "gut");
2409
+ }
2410
+ }
2411
+ if (!existsSync5(targetPath)) {
2412
+ mkdirSync2(targetPath, { recursive: true });
2413
+ console.log(chalk16.green(`Created ${targetPath}`));
2414
+ }
2415
+ try {
2416
+ openFolder(targetPath);
2417
+ console.log(chalk16.green(`Opened: ${targetPath}`));
2418
+ } catch (error) {
2419
+ console.error(chalk16.red(`Failed to open folder: ${targetPath}`));
2420
+ console.error(chalk16.gray(error.message));
2421
+ process.exit(1);
2422
+ }
2423
+ });
2365
2424
 
2366
2425
  // src/commands/lang.ts
2367
2426
  import { Command as Command16 } from "commander";
@@ -2394,17 +2453,24 @@ var langCommand = new Command16("lang").description("Set or show output language
2394
2453
  import { Command as Command17 } from "commander";
2395
2454
  import chalk18 from "chalk";
2396
2455
  import ora14 from "ora";
2397
- import { simpleGit as simpleGit14 } from "simple-git";
2398
- import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
2399
- import { join as join5, dirname as dirname2 } from "path";
2456
+ import { simpleGit as simpleGit15 } from "simple-git";
2457
+ import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "fs";
2458
+ import { join as join6, dirname as dirname2 } from "path";
2459
+ import { homedir as homedir4 } from "os";
2400
2460
  import { fileURLToPath as fileURLToPath2 } from "url";
2461
+ import { execSync as execSync8 } from "child_process";
2401
2462
  import { generateText as generateText2 } from "ai";
2402
2463
  import { createGoogleGenerativeAI as createGoogleGenerativeAI2 } from "@ai-sdk/google";
2403
2464
  import { createOpenAI as createOpenAI2 } from "@ai-sdk/openai";
2404
2465
  import { createAnthropic as createAnthropic2 } from "@ai-sdk/anthropic";
2466
+ function openFolder2(path2) {
2467
+ const platform = process.platform;
2468
+ const cmd = platform === "darwin" ? "open" : platform === "win32" ? 'start ""' : "xdg-open";
2469
+ execSync8(`${cmd} "${path2}"`);
2470
+ }
2405
2471
  var __filename2 = fileURLToPath2(import.meta.url);
2406
2472
  var __dirname2 = dirname2(__filename2);
2407
- var GUT_ROOT2 = join5(__dirname2, "..");
2473
+ var GUT_ROOT2 = join6(__dirname2, "..");
2408
2474
  var TEMPLATE_FILES = [
2409
2475
  "branch.md",
2410
2476
  "changelog.md",
@@ -2467,20 +2533,28 @@ Translated template:`
2467
2533
  });
2468
2534
  return text.trim();
2469
2535
  }
2470
- var initCommand = new Command17("init").description("Initialize .gut/ templates in your project").option("-p, --provider <provider>", "AI provider for translation (gemini, openai, anthropic)", "gemini").option("-f, --force", "Overwrite existing templates").option("--no-translate", "Skip translation even if language is not English").action(async (options) => {
2471
- const git = simpleGit14();
2472
- const isRepo = await git.checkIsRepo();
2473
- if (!isRepo) {
2474
- console.error(chalk18.red("Error: Not a git repository"));
2475
- process.exit(1);
2536
+ var initCommand = new Command17("init").description("Initialize .gut/ templates in your project or globally").option("-p, --provider <provider>", "AI provider for translation (gemini, openai, anthropic)", "gemini").option("-f, --force", "Overwrite existing templates").option("-g, --global", "Initialize templates globally (~/.config/gut/templates/)").option("-o, --open", "Open the templates folder (can be used alone)").option("--no-translate", "Skip translation even if language is not English").action(async (options) => {
2537
+ const isGlobal = options.global === true;
2538
+ const git = simpleGit15();
2539
+ let targetDir;
2540
+ if (isGlobal) {
2541
+ targetDir = join6(homedir4(), ".config", "gut", "templates");
2542
+ } else {
2543
+ const isRepo = await git.checkIsRepo();
2544
+ if (!isRepo) {
2545
+ console.error(chalk18.red("Error: Not a git repository"));
2546
+ console.error(chalk18.gray("Use --global to initialize templates globally"));
2547
+ process.exit(1);
2548
+ }
2549
+ const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
2550
+ targetDir = join6(repoRoot.trim(), ".gut");
2476
2551
  }
2477
- const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
2478
- const targetDir = join5(repoRoot.trim(), ".gut");
2479
- const sourceDir = join5(GUT_ROOT2, ".gut");
2480
- if (!existsSync5(targetDir)) {
2481
- mkdirSync2(targetDir, { recursive: true });
2552
+ if (!existsSync6(targetDir)) {
2553
+ mkdirSync3(targetDir, { recursive: true });
2482
2554
  console.log(chalk18.green(`Created ${targetDir}`));
2483
2555
  }
2556
+ console.log(chalk18.blue(isGlobal ? "Initializing global templates...\n" : "Initializing project templates...\n"));
2557
+ const sourceDir = join6(GUT_ROOT2, ".gut");
2484
2558
  const lang = getLanguage();
2485
2559
  const needsTranslation = options.translate !== false && lang !== "en";
2486
2560
  const provider = options.provider.toLowerCase();
@@ -2492,12 +2566,12 @@ var initCommand = new Command17("init").description("Initialize .gut/ templates
2492
2566
  let copied = 0;
2493
2567
  let skipped = 0;
2494
2568
  for (const filename of TEMPLATE_FILES) {
2495
- const sourcePath = join5(sourceDir, filename);
2496
- const targetPath = join5(targetDir, filename);
2497
- if (!existsSync5(sourcePath)) {
2569
+ const sourcePath = join6(sourceDir, filename);
2570
+ const targetPath = join6(targetDir, filename);
2571
+ if (!existsSync6(sourcePath)) {
2498
2572
  continue;
2499
2573
  }
2500
- if (existsSync5(targetPath) && !options.force) {
2574
+ if (existsSync6(targetPath) && !options.force) {
2501
2575
  console.log(chalk18.gray(` Skipped: ${filename} (already exists)`));
2502
2576
  skipped++;
2503
2577
  continue;
@@ -2521,21 +2595,37 @@ var initCommand = new Command17("init").description("Initialize .gut/ templates
2521
2595
  }
2522
2596
  console.log();
2523
2597
  if (copied > 0) {
2524
- console.log(chalk18.green(`\u2713 ${copied} template(s) initialized in .gut/`));
2598
+ const location = isGlobal ? "~/.config/gut/templates/" : ".gut/";
2599
+ console.log(chalk18.green(`\u2713 ${copied} template(s) initialized in ${location}`));
2525
2600
  }
2526
2601
  if (skipped > 0) {
2527
2602
  console.log(chalk18.gray(` ${skipped} template(s) skipped (use --force to overwrite)`));
2528
2603
  }
2529
- console.log(chalk18.gray("\nYou can now customize these templates for your project."));
2604
+ if (isGlobal) {
2605
+ console.log(chalk18.gray("\nGlobal templates will be used as fallback for all projects."));
2606
+ console.log(chalk18.gray("Project-level templates (.gut/) take priority over global templates."));
2607
+ } else {
2608
+ console.log(chalk18.gray("\nYou can now customize these templates for your project."));
2609
+ }
2610
+ if (options.open) {
2611
+ try {
2612
+ openFolder2(targetDir);
2613
+ console.log(chalk18.green(`
2614
+ Opened: ${targetDir}`));
2615
+ } catch (error) {
2616
+ console.error(chalk18.red(`
2617
+ Failed to open folder: ${targetDir}`));
2618
+ }
2619
+ }
2530
2620
  });
2531
2621
 
2532
2622
  // src/commands/gitignore.ts
2533
2623
  import { Command as Command18 } from "commander";
2534
2624
  import chalk19 from "chalk";
2535
2625
  import ora15 from "ora";
2536
- import { simpleGit as simpleGit15 } from "simple-git";
2537
- import { readdirSync as readdirSync2, readFileSync as readFileSync7, existsSync as existsSync6, writeFileSync as writeFileSync4 } from "fs";
2538
- import { join as join6 } from "path";
2626
+ import { simpleGit as simpleGit16 } from "simple-git";
2627
+ import { readdirSync as readdirSync2, readFileSync as readFileSync7, existsSync as existsSync7, writeFileSync as writeFileSync4 } from "fs";
2628
+ import { join as join7 } from "path";
2539
2629
  var CONFIG_FILES = [
2540
2630
  // JavaScript/TypeScript
2541
2631
  "package.json",
@@ -2588,7 +2678,7 @@ function getFiles(dir, maxDepth = 3, currentDepth = 0) {
2588
2678
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "vendor" || entry.name === "target" || entry.name === "__pycache__" || entry.name === "venv" || entry.name === ".venv") {
2589
2679
  continue;
2590
2680
  }
2591
- const fullPath = join6(dir, entry.name);
2681
+ const fullPath = join7(dir, entry.name);
2592
2682
  if (entry.isDirectory()) {
2593
2683
  files.push(entry.name + "/");
2594
2684
  const subFiles = getFiles(fullPath, maxDepth, currentDepth + 1);
@@ -2610,15 +2700,15 @@ function findConfigFiles(repoRoot) {
2610
2700
  const entries = readdirSync2(repoRoot);
2611
2701
  for (const entry of entries) {
2612
2702
  if (entry.endsWith(ext)) {
2613
- const content = readFileSync7(join6(repoRoot, entry), "utf-8");
2703
+ const content = readFileSync7(join7(repoRoot, entry), "utf-8");
2614
2704
  found.set(entry, content.slice(0, 2e3));
2615
2705
  }
2616
2706
  }
2617
2707
  } catch {
2618
2708
  }
2619
2709
  } else {
2620
- const filePath = join6(repoRoot, configFile);
2621
- if (existsSync6(filePath)) {
2710
+ const filePath = join7(repoRoot, configFile);
2711
+ if (existsSync7(filePath)) {
2622
2712
  try {
2623
2713
  const content = readFileSync7(filePath, "utf-8");
2624
2714
  found.set(configFile, content.slice(0, 2e3));
@@ -2630,7 +2720,7 @@ function findConfigFiles(repoRoot) {
2630
2720
  return found;
2631
2721
  }
2632
2722
  var gitignoreCommand = new Command18("gitignore").description("Generate .gitignore from current codebase").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic)", "gemini").option("-m, --model <model>", "Model to use (provider-specific)").option("-o, --output <file>", "Output file (default: .gitignore)", ".gitignore").option("--stdout", "Print to stdout instead of file").option("-y, --yes", "Overwrite existing .gitignore without confirmation").action(async (options) => {
2633
- const git = simpleGit15();
2723
+ const git = simpleGit16();
2634
2724
  const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
2635
2725
  const root = repoRoot.trim();
2636
2726
  const provider = options.provider.toLowerCase();
@@ -2641,9 +2731,9 @@ var gitignoreCommand = new Command18("gitignore").description("Generate .gitigno
2641
2731
  const spinner = ora15("Analyzing project structure...").start();
2642
2732
  const files = getFiles(root);
2643
2733
  const configFiles = findConfigFiles(root);
2644
- const gitignorePath = join6(root, options.output);
2734
+ const gitignorePath = join7(root, options.output);
2645
2735
  let existingGitignore;
2646
- if (existsSync6(gitignorePath)) {
2736
+ if (existsSync7(gitignorePath)) {
2647
2737
  existingGitignore = readFileSync7(gitignorePath, "utf-8");
2648
2738
  }
2649
2739
  let configFilesStr = "";
@@ -2678,7 +2768,7 @@ ${content}
2678
2768
  console.log(gitignoreContent);
2679
2769
  console.log(chalk19.gray("\u2500".repeat(50)));
2680
2770
  console.log();
2681
- if (existsSync6(gitignorePath) && !options.yes) {
2771
+ if (existsSync7(gitignorePath) && !options.yes) {
2682
2772
  const readline = await import("readline");
2683
2773
  const rl = readline.createInterface({
2684
2774
  input: process.stdin,