gut-cli 0.1.12 → 0.1.14

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/.gut/branch.md ADDED
@@ -0,0 +1,27 @@
1
+ You are an expert at creating git branch names.
2
+
3
+ Generate a clean, descriptive branch name for the following:
4
+
5
+ ## Description
6
+
7
+ {{description}}
8
+
9
+ {{#type}}
10
+ Branch type: {{type}}
11
+ {{/type}}
12
+
13
+ {{#issue}}
14
+ Include issue number: {{issue}}
15
+ {{/issue}}
16
+
17
+ ## Rules
18
+
19
+ - Use format: `<type>/<short-description>`
20
+ - Types: feature, fix, hotfix, chore, refactor, docs, test
21
+ - Use kebab-case for description
22
+ - Keep it short (under 50 chars total)
23
+ - No special characters except hyphens and slashes
24
+
25
+ ## Output
26
+
27
+ Respond with ONLY the branch name, nothing else.
@@ -0,0 +1,38 @@
1
+ You are an expert at writing release notes and changelogs.
2
+
3
+ Generate a changelog entry for changes from {{fromRef}} to {{toRef}}.
4
+
5
+ Today's date is {{todayDate}}. Use this date for the release date.
6
+
7
+ ## Commits
8
+
9
+ {{commits}}
10
+
11
+ ## Diff summary
12
+
13
+ ```
14
+ {{diff}}
15
+ ```
16
+
17
+ ## Format
18
+
19
+ Use Keep a Changelog format (https://keepachangelog.com/):
20
+ - Group changes by: Added, Changed, Deprecated, Removed, Fixed, Security
21
+ - Each item should be a concise description of the change
22
+ - Use past tense
23
+
24
+ ## Focus on
25
+
26
+ - User-facing changes and improvements
27
+ - Bug fixes and their impact
28
+ - Breaking changes (highlight these)
29
+ - Group related changes together
30
+ - Write for end users, not developers (unless it's a library)
31
+
32
+ ## Output
33
+
34
+ Respond with a JSON object containing:
35
+ - version: Version string if detected (optional)
36
+ - date: Release date in YYYY-MM-DD format
37
+ - sections: Array of { type, items[] }
38
+ - summary: Brief summary of this release (optional)
@@ -0,0 +1,29 @@
1
+ # Checkout Branch Name Generation
2
+
3
+ You are an expert at creating git branch names.
4
+
5
+ Analyze the following git diff and generate a clean, descriptive branch name that captures the essence of the changes.
6
+
7
+ ## Git diff
8
+
9
+ ```
10
+ {{diff}}
11
+ ```
12
+
13
+ ## Branch Naming Convention
14
+
15
+ - Use format: `<type>/<short-description>`
16
+ - Types: feature, fix, hotfix, chore, refactor, docs, test
17
+ - Use kebab-case for description
18
+ - Keep it short (under 50 chars total)
19
+ - No special characters except hyphens and slashes
20
+
21
+ ## Focus on
22
+
23
+ - The main purpose of the changes
24
+ - Whether it's a feature, fix, refactor, etc.
25
+ - Key files or functionality being modified
26
+
27
+ ## Output
28
+
29
+ Respond with ONLY the branch name, nothing else.
package/.gut/commit.md ADDED
@@ -0,0 +1,22 @@
1
+ You are an expert at writing git commit messages.
2
+
3
+ Analyze the following git diff and generate a concise, meaningful commit message.
4
+
5
+ ## Git diff
6
+
7
+ ```
8
+ {{diff}}
9
+ ```
10
+
11
+ ## Rules
12
+
13
+ - Use format: `<type>(<scope>): <description>`
14
+ - Types: feat, fix, docs, style, refactor, perf, test, chore, build, ci
15
+ - Scope is optional but helpful
16
+ - Description should be lowercase, imperative mood, no period at end
17
+ - Keep the first line under 72 characters
18
+ - If changes are complex, add a blank line and bullet points for details
19
+
20
+ ## Output
21
+
22
+ Respond with ONLY the commit message, nothing else.
@@ -0,0 +1,3 @@
1
+ {
2
+ "lang": "en"
3
+ }
@@ -0,0 +1,30 @@
1
+ You are an expert at explaining code in a clear and insightful way.
2
+
3
+ Analyze the following file and explain what it does, its purpose, and its role in a project.
4
+
5
+ ## File
6
+
7
+ Path: {{filePath}}
8
+
9
+ ```
10
+ {{content}}
11
+ ```
12
+
13
+ ## Focus on
14
+
15
+ - What this file does (main functionality)
16
+ - Its purpose and role in the codebase
17
+ - Key functions, classes, or components it defines
18
+ - Dependencies and what it interacts with
19
+ - Any important patterns or architecture decisions
20
+
21
+ ## Output
22
+
23
+ Explain in a way that helps someone quickly understand this file's purpose and how it fits into the larger codebase.
24
+
25
+ Respond with a JSON object containing:
26
+ - summary: One-line summary
27
+ - purpose: The purpose and role of this code
28
+ - changes: Array of { file, description }
29
+ - impact: What impact or role this has in the project
30
+ - notes: Important considerations or caveats (optional)
@@ -0,0 +1,31 @@
1
+ You are an expert at explaining code changes in a clear and insightful way.
2
+
3
+ Analyze the following {{targetType}} and provide a comprehensive explanation.
4
+
5
+ ## Context
6
+
7
+ {{context}}
8
+
9
+ ## Diff
10
+
11
+ ```
12
+ {{diff}}
13
+ ```
14
+
15
+ ## Focus on
16
+
17
+ - What the changes accomplish (not just what files changed)
18
+ - WHY these changes were likely made
19
+ - The broader context and purpose
20
+ - Any important implications or side effects
21
+
22
+ ## Output
23
+
24
+ Explain in a way that helps someone understand not just the "what" but the "why" behind these changes.
25
+
26
+ Respond with a JSON object containing:
27
+ - summary: One-line summary
28
+ - purpose: The purpose and role of this code
29
+ - changes: Array of { file, description }
30
+ - impact: What impact or role this has in the project
31
+ - notes: Important considerations or caveats (optional)
package/.gut/find.md ADDED
@@ -0,0 +1,25 @@
1
+ You are an expert at understanding git history and finding relevant commits.
2
+
3
+ The user is looking for commits related to: "{{query}}"
4
+
5
+ ## Commits to search
6
+
7
+ ```
8
+ {{commits}}
9
+ ```
10
+
11
+ ## Instructions
12
+
13
+ Find the commits that best match the user's query. Consider:
14
+ - Commit messages that mention similar concepts
15
+ - Related features, bug fixes, or changes
16
+ - Semantic similarity (e.g., "login" matches "authentication")
17
+
18
+ Return up to {{maxResults}} matching commits, ordered by relevance (most relevant first).
19
+ Only include commits that actually match the query - if none match well, return an empty array.
20
+
21
+ ## Output
22
+
23
+ Respond with a JSON object containing:
24
+ - matches: Array of { hash, reason }
25
+ - summary: Brief summary of the search results (optional)
@@ -0,0 +1,42 @@
1
+ You are an expert at creating .gitignore files.
2
+
3
+ Analyze the following project structure and configuration files to generate an appropriate .gitignore file.
4
+
5
+ ## Project Structure
6
+
7
+ ```
8
+ {{files}}
9
+ ```
10
+
11
+ {{#configFiles}}
12
+ ## Detected Config Files
13
+
14
+ {{configFiles}}
15
+ {{/configFiles}}
16
+
17
+ {{#existingGitignore}}
18
+ ## Existing .gitignore
19
+
20
+ ```
21
+ {{existingGitignore}}
22
+ ```
23
+ {{/existingGitignore}}
24
+
25
+ ## Rules
26
+
27
+ - Detect the language/framework being used (Node.js, Python, Go, Rust, Java, Ruby, PHP, .NET, etc.)
28
+ - Include common ignore patterns for the detected stack
29
+ - Include OS-specific files (.DS_Store, Thumbs.db, etc.)
30
+ - Include IDE/editor files (.vscode/, .idea/, *.swp, etc.)
31
+ - Include environment files (.env, .env.local, etc.)
32
+ - Include build outputs and dependencies based on detected stack
33
+ - Include log files and temporary files
34
+ - Do NOT ignore files that should be tracked (source code, configs, etc.)
35
+ - Keep the file organized with comments for each section
36
+ {{#existingGitignore}}
37
+ - Preserve any project-specific patterns from the existing .gitignore
38
+ {{/existingGitignore}}
39
+
40
+ ## Output
41
+
42
+ Respond with ONLY the .gitignore content, nothing else. Include section comments for clarity.
package/.gut/merge.md ADDED
@@ -0,0 +1,30 @@
1
+ You are an expert at resolving git merge conflicts intelligently.
2
+
3
+ Analyze the following conflicted file and provide a resolution.
4
+
5
+ ## Context
6
+
7
+ - File: {{filename}}
8
+ - Merging: {{theirsRef}} into {{oursRef}}
9
+
10
+ ## Conflicted content
11
+
12
+ ```
13
+ {{content}}
14
+ ```
15
+
16
+ ## Rules
17
+
18
+ - Understand the intent of both changes
19
+ - Combine changes when both are valid additions
20
+ - Choose the more complete/correct version when they conflict
21
+ - Preserve all necessary functionality
22
+ - The resolved content should be valid, working code
23
+ - Do NOT include conflict markers (<<<<<<, =======, >>>>>>)
24
+
25
+ ## Output
26
+
27
+ Respond with a JSON object containing:
28
+ - resolvedContent: The resolved file content
29
+ - explanation: Brief explanation of how the conflict was resolved
30
+ - strategy: "ours" | "theirs" | "combined" | "rewritten"
package/.gut/pr.md ADDED
@@ -0,0 +1,36 @@
1
+ You are an expert at writing pull request descriptions.
2
+
3
+ Generate a clear and informative PR title and description based on the following information.
4
+
5
+ ## Context
6
+
7
+ - Branch: {{currentBranch}} -> {{baseBranch}}
8
+ - Commits:
9
+ {{commits}}
10
+
11
+ ## Diff summary
12
+
13
+ ```
14
+ {{diff}}
15
+ ```
16
+
17
+ ## Rules for title
18
+
19
+ - Title should be concise (under 72 chars), start with a verb
20
+
21
+ ## Rules for description
22
+
23
+ - Description should have:
24
+ - ## Summary section with 2-3 bullet points
25
+ - ## Changes section listing key modifications
26
+ - ## Test Plan section (suggest what to test)
27
+
28
+ ## Output
29
+
30
+ Respond in JSON format:
31
+ ```json
32
+ {
33
+ "title": "...",
34
+ "body": "..."
35
+ }
36
+ ```
package/.gut/review.md ADDED
@@ -0,0 +1,24 @@
1
+ You are an expert code reviewer. Analyze the following git diff and provide a structured review.
2
+
3
+ ## Git diff
4
+
5
+ ```
6
+ {{diff}}
7
+ ```
8
+
9
+ ## Focus on
10
+
11
+ - Bugs and potential issues
12
+ - Security vulnerabilities
13
+ - Performance concerns
14
+ - Code style and best practices
15
+ - Suggestions for improvement
16
+
17
+ ## Output
18
+
19
+ Be constructive and specific. Include line numbers when possible.
20
+
21
+ Respond with a JSON object containing:
22
+ - summary: Brief overall assessment
23
+ - issues: Array of { severity: "critical"|"warning"|"suggestion", file, line?, message, suggestion? }
24
+ - positives: Array of good practices observed
package/.gut/stash.md ADDED
@@ -0,0 +1,20 @@
1
+ You are an expert at summarizing code changes.
2
+
3
+ Generate a short, descriptive stash name for the following changes.
4
+
5
+ ## Diff
6
+
7
+ ```
8
+ {{diff}}
9
+ ```
10
+
11
+ ## Rules
12
+
13
+ - Start with "WIP: " prefix
14
+ - Keep it under 50 characters total
15
+ - Be specific about what the changes do
16
+ - Use present tense
17
+
18
+ ## Output
19
+
20
+ Respond with ONLY the stash name, nothing else.
@@ -0,0 +1,38 @@
1
+ You are an expert at writing work summaries and reports.
2
+
3
+ Generate a clear, professional work summary for the following git activity.
4
+
5
+ ## Context
6
+
7
+ - Author: {{author}}
8
+ - Period: {{period}}
9
+ - Format: {{format}}
10
+
11
+ ## Commits
12
+
13
+ {{commits}}
14
+
15
+ {{#diff}}
16
+ ## Diff summary
17
+
18
+ ```
19
+ {{diff}}
20
+ ```
21
+ {{/diff}}
22
+
23
+ ## Focus on
24
+
25
+ - What was accomplished (not just listing commits)
26
+ - Group related work together
27
+ - Highlight important achievements
28
+ - Use clear, non-technical language where possible
29
+ - Make it suitable for sharing with team or manager
30
+
31
+ ## Output
32
+
33
+ Respond with a JSON object containing:
34
+ - title: One-line title for the summary
35
+ - overview: Brief overview of what was accomplished
36
+ - highlights: Array of key accomplishments
37
+ - details: Array of { category, items[] }
38
+ - stats: { commits, filesChanged?, additions?, deletions? } (optional)
package/README.md CHANGED
@@ -35,6 +35,7 @@ npm install -g gut-cli
35
35
  | `gut config` | Manage configuration (language, etc.) |
36
36
  | `gut lang` | Set or show output language |
37
37
  | `gut init` | Initialize .gut/ templates in your project |
38
+ | `gut gitignore` | Generate .gitignore from codebase |
38
39
 
39
40
  ### `gut commit`
40
41
 
@@ -389,6 +390,32 @@ gut init --provider openai
389
390
 
390
391
  Templates are automatically translated to your configured language (set via `gut lang`).
391
392
 
393
+ ### `gut gitignore`
394
+
395
+ Generate a .gitignore file by analyzing your project structure.
396
+
397
+ ```bash
398
+ # Generate .gitignore (prompts before overwriting)
399
+ gut gitignore
400
+
401
+ # Auto-overwrite without confirmation
402
+ gut gitignore --yes
403
+
404
+ # Print to stdout instead of file
405
+ gut gitignore --stdout
406
+
407
+ # Use specific provider
408
+ gut gitignore --provider openai
409
+ ```
410
+
411
+ **How it works:**
412
+ - Scans your project structure (files and directories)
413
+ - Detects config files (package.json, Cargo.toml, go.mod, pyproject.toml, etc.)
414
+ - Identifies the language/framework stack
415
+ - Generates appropriate ignore patterns
416
+
417
+ **Template Support**: Create `.gut/gitignore.md` to customize the generation prompt.
418
+
392
419
  ### `gut cleanup`
393
420
 
394
421
  Delete merged branches safely.
@@ -457,6 +484,7 @@ gut looks for template files in your repository's `.gut/` folder. Each template
457
484
  | `.gut/changelog.md` | Changelog format |
458
485
  | `.gut/stash.md` | Stash name prompt |
459
486
  | `.gut/summary.md` | Work summary format |
487
+ | `.gut/gitignore.md` | Gitignore generation prompt |
460
488
  | `.github/pull_request_template.md` | GitHub PR template (prioritized over `.gut/pr.md`) |
461
489
 
462
490
  ## Development
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/index.ts
4
- import { Command as Command18 } from "commander";
4
+ import { Command as Command19 } from "commander";
5
5
 
6
6
  // src/commands/cleanup.ts
7
7
  import { Command } from "commander";
@@ -735,6 +735,20 @@ async function resolveConflict(conflictedContent, context, options, template) {
735
735
  });
736
736
  return result.object;
737
737
  }
738
+ async function generateGitignore(context, options, template) {
739
+ const model = await getModel(options);
740
+ const prompt = applyTemplate(template, "gitignore", {
741
+ files: context.files,
742
+ configFiles: context.configFiles,
743
+ existingGitignore: context.existingGitignore
744
+ });
745
+ const result = await generateText({
746
+ model,
747
+ prompt,
748
+ maxTokens: 2e3
749
+ });
750
+ return result.text.trim();
751
+ }
738
752
 
739
753
  // src/commands/commit.ts
740
754
  var commitCommand = new Command3("commit").description("Generate a commit message using AI").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic)", "gemini").option("-m, --model <model>", "Model to use (provider-specific)").option("-c, --commit", "Automatically commit with the generated message").option("-a, --all", "Force stage all changes (default: auto-stage if nothing staged)").action(async (options) => {
@@ -2477,8 +2491,181 @@ var initCommand = new Command17("init").description("Initialize .gut/ templates
2477
2491
  console.log(chalk18.gray("\nYou can now customize these templates for your project."));
2478
2492
  });
2479
2493
 
2494
+ // src/commands/gitignore.ts
2495
+ import { Command as Command18 } from "commander";
2496
+ import chalk19 from "chalk";
2497
+ import ora15 from "ora";
2498
+ import { simpleGit as simpleGit15 } from "simple-git";
2499
+ import { readdirSync as readdirSync2, readFileSync as readFileSync7, existsSync as existsSync6, writeFileSync as writeFileSync4 } from "fs";
2500
+ import { join as join6 } from "path";
2501
+ var CONFIG_FILES = [
2502
+ // JavaScript/TypeScript
2503
+ "package.json",
2504
+ "tsconfig.json",
2505
+ "vite.config.ts",
2506
+ "vite.config.js",
2507
+ "next.config.js",
2508
+ "next.config.mjs",
2509
+ "nuxt.config.ts",
2510
+ "astro.config.mjs",
2511
+ // Python
2512
+ "pyproject.toml",
2513
+ "setup.py",
2514
+ "requirements.txt",
2515
+ "Pipfile",
2516
+ "poetry.lock",
2517
+ // Go
2518
+ "go.mod",
2519
+ "go.sum",
2520
+ // Rust
2521
+ "Cargo.toml",
2522
+ "Cargo.lock",
2523
+ // Java/Kotlin
2524
+ "pom.xml",
2525
+ "build.gradle",
2526
+ "build.gradle.kts",
2527
+ // Ruby
2528
+ "Gemfile",
2529
+ "Gemfile.lock",
2530
+ // PHP
2531
+ "composer.json",
2532
+ "composer.lock",
2533
+ // .NET
2534
+ "*.csproj",
2535
+ "*.fsproj",
2536
+ "*.sln",
2537
+ // Elixir
2538
+ "mix.exs",
2539
+ // Dart/Flutter
2540
+ "pubspec.yaml",
2541
+ // Swift
2542
+ "Package.swift"
2543
+ ];
2544
+ function getFiles(dir, maxDepth = 3, currentDepth = 0) {
2545
+ if (currentDepth >= maxDepth) return [];
2546
+ const files = [];
2547
+ try {
2548
+ const entries = readdirSync2(dir, { withFileTypes: true });
2549
+ for (const entry of entries) {
2550
+ if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "vendor" || entry.name === "target" || entry.name === "__pycache__" || entry.name === "venv" || entry.name === ".venv") {
2551
+ continue;
2552
+ }
2553
+ const fullPath = join6(dir, entry.name);
2554
+ if (entry.isDirectory()) {
2555
+ files.push(entry.name + "/");
2556
+ const subFiles = getFiles(fullPath, maxDepth, currentDepth + 1);
2557
+ files.push(...subFiles.map((f) => entry.name + "/" + f));
2558
+ } else {
2559
+ files.push(entry.name);
2560
+ }
2561
+ }
2562
+ } catch {
2563
+ }
2564
+ return files;
2565
+ }
2566
+ function findConfigFiles(repoRoot) {
2567
+ const found = /* @__PURE__ */ new Map();
2568
+ for (const configFile of CONFIG_FILES) {
2569
+ if (configFile.includes("*")) {
2570
+ const ext = configFile.replace("*", "");
2571
+ try {
2572
+ const entries = readdirSync2(repoRoot);
2573
+ for (const entry of entries) {
2574
+ if (entry.endsWith(ext)) {
2575
+ const content = readFileSync7(join6(repoRoot, entry), "utf-8");
2576
+ found.set(entry, content.slice(0, 2e3));
2577
+ }
2578
+ }
2579
+ } catch {
2580
+ }
2581
+ } else {
2582
+ const filePath = join6(repoRoot, configFile);
2583
+ if (existsSync6(filePath)) {
2584
+ try {
2585
+ const content = readFileSync7(filePath, "utf-8");
2586
+ found.set(configFile, content.slice(0, 2e3));
2587
+ } catch {
2588
+ }
2589
+ }
2590
+ }
2591
+ }
2592
+ return found;
2593
+ }
2594
+ 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) => {
2595
+ const git = simpleGit15();
2596
+ const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
2597
+ const root = repoRoot.trim();
2598
+ const provider = options.provider.toLowerCase();
2599
+ const template = findTemplate(root, "gitignore");
2600
+ if (template) {
2601
+ console.log(chalk19.gray("Using template from project..."));
2602
+ }
2603
+ const spinner = ora15("Analyzing project structure...").start();
2604
+ const files = getFiles(root);
2605
+ const configFiles = findConfigFiles(root);
2606
+ const gitignorePath = join6(root, options.output);
2607
+ let existingGitignore;
2608
+ if (existsSync6(gitignorePath)) {
2609
+ existingGitignore = readFileSync7(gitignorePath, "utf-8");
2610
+ }
2611
+ let configFilesStr = "";
2612
+ if (configFiles.size > 0) {
2613
+ const entries = [];
2614
+ for (const [name, content] of configFiles) {
2615
+ entries.push(`### ${name}
2616
+ \`\`\`
2617
+ ${content}
2618
+ \`\`\``);
2619
+ }
2620
+ configFilesStr = entries.join("\n\n");
2621
+ }
2622
+ spinner.text = "Generating .gitignore...";
2623
+ try {
2624
+ const gitignoreContent = await generateGitignore(
2625
+ {
2626
+ files: files.slice(0, 200).join("\n"),
2627
+ configFiles: configFilesStr,
2628
+ existingGitignore
2629
+ },
2630
+ { provider, model: options.model },
2631
+ template || void 0
2632
+ );
2633
+ spinner.stop();
2634
+ if (options.stdout) {
2635
+ console.log(gitignoreContent);
2636
+ return;
2637
+ }
2638
+ console.log(chalk19.bold("\nGenerated .gitignore:\n"));
2639
+ console.log(chalk19.gray("\u2500".repeat(50)));
2640
+ console.log(gitignoreContent);
2641
+ console.log(chalk19.gray("\u2500".repeat(50)));
2642
+ console.log();
2643
+ if (existsSync6(gitignorePath) && !options.yes) {
2644
+ const readline = await import("readline");
2645
+ const rl = readline.createInterface({
2646
+ input: process.stdin,
2647
+ output: process.stdout
2648
+ });
2649
+ const answer = await new Promise((resolve) => {
2650
+ rl.question(chalk19.cyan(`${options.output} already exists. Overwrite? (y/N) `), resolve);
2651
+ });
2652
+ rl.close();
2653
+ if (answer.toLowerCase() !== "y") {
2654
+ console.log(chalk19.gray("Aborted."));
2655
+ return;
2656
+ }
2657
+ }
2658
+ writeFileSync4(gitignorePath, gitignoreContent);
2659
+ console.log(chalk19.green(`\u2713 Wrote ${options.output}`));
2660
+ } catch (error) {
2661
+ spinner.fail("Failed to generate .gitignore");
2662
+ console.error(chalk19.red(error instanceof Error ? error.message : "Unknown error"));
2663
+ process.exit(1);
2664
+ }
2665
+ });
2666
+
2480
2667
  // src/index.ts
2481
- var program = new Command18();
2668
+ var program = new Command19();
2482
2669
  program.name("gut").description("Git Utility Tool - AI-powered git commands").version("0.1.0");
2483
2670
  program.addCommand(cleanupCommand);
2484
2671
  program.addCommand(authCommand);
@@ -2497,5 +2684,6 @@ program.addCommand(summaryCommand);
2497
2684
  program.addCommand(configCommand);
2498
2685
  program.addCommand(langCommand);
2499
2686
  program.addCommand(initCommand);
2687
+ program.addCommand(gitignoreCommand);
2500
2688
  program.parse();
2501
2689
  //# sourceMappingURL=index.js.map