gut-cli 0.1.32 → 0.1.34
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 +42 -0
- package/dist/index.js +138 -34
- package/dist/index.js.map +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +14 -6
- package/dist/lib/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -540,6 +540,48 @@ Each template uses `{{variable}}` syntax for dynamic content.
|
|
|
540
540
|
|
|
541
541
|
**Special case**: `.github/pull_request_template.md` is prioritized over `pr.md` for PR descriptions.
|
|
542
542
|
|
|
543
|
+
## Custom API Endpoints
|
|
544
|
+
|
|
545
|
+
Configure custom base URLs for AI providers (useful for proxies, local instances, or API-compatible services):
|
|
546
|
+
|
|
547
|
+
### Global Configuration
|
|
548
|
+
```bash
|
|
549
|
+
# Set base URL for all AI commands
|
|
550
|
+
gut config set baseUrl https://api.example.com/v1
|
|
551
|
+
|
|
552
|
+
# View current config
|
|
553
|
+
gut config list
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
### Per-Command Override
|
|
557
|
+
```bash
|
|
558
|
+
gut commit --base-url https://api.example.com/v1
|
|
559
|
+
gut pr --base-url https://my-proxy.com
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### Local (Project-Specific)
|
|
563
|
+
```bash
|
|
564
|
+
gut config set baseUrl https://api.example.com/v1 --local
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Examples
|
|
568
|
+
```bash
|
|
569
|
+
# OpenAI-compatible API (Groq)
|
|
570
|
+
gut config set provider openai
|
|
571
|
+
gut config set baseUrl https://api.groq.com/openai/v1
|
|
572
|
+
|
|
573
|
+
# Local Ollama on different port
|
|
574
|
+
gut commit --provider ollama --base-url http://192.168.1.100:11434/api
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
### Priority Order
|
|
578
|
+
1. CLI flag `--base-url` (highest)
|
|
579
|
+
2. Local config (`.gut/config.json`)
|
|
580
|
+
3. Global config (`~/.config/gut/config.json`)
|
|
581
|
+
4. Provider defaults (lowest)
|
|
582
|
+
|
|
583
|
+
**Note**: For Ollama, the legacy `ollamaBaseUrl` config takes priority over `baseUrl` for backward compatibility.
|
|
584
|
+
|
|
543
585
|
## Development
|
|
544
586
|
|
|
545
587
|
```bash
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
+
import { createRequire as createRequire2 } from "module";
|
|
4
5
|
import { Command as Command19 } from "commander";
|
|
5
6
|
|
|
6
7
|
// src/commands/auth.ts
|
|
@@ -133,6 +134,29 @@ function setProvider(provider, local = false) {
|
|
|
133
134
|
setGlobalConfig("provider", provider);
|
|
134
135
|
}
|
|
135
136
|
}
|
|
137
|
+
function getBaseUrl() {
|
|
138
|
+
return getConfig().baseUrl;
|
|
139
|
+
}
|
|
140
|
+
function setBaseUrl(url, local = false) {
|
|
141
|
+
if (url === "") {
|
|
142
|
+
const path2 = local ? getLocalConfigPath() : getGlobalConfigPath();
|
|
143
|
+
if (local && !path2) throw new Error("Not in a git repository");
|
|
144
|
+
const config = local ? getLocalConfig() : getGlobalConfig();
|
|
145
|
+
delete config.baseUrl;
|
|
146
|
+
writeFileSync(path2 || getGlobalConfigPath(), JSON.stringify(config, null, 2));
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
new URL(url);
|
|
151
|
+
} catch {
|
|
152
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
153
|
+
}
|
|
154
|
+
if (local) {
|
|
155
|
+
setLocalConfig("baseUrl", url);
|
|
156
|
+
} else {
|
|
157
|
+
setGlobalConfig("baseUrl", url);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
136
160
|
|
|
137
161
|
// src/lib/credentials.ts
|
|
138
162
|
var SERVICE_NAME = "gut-cli";
|
|
@@ -153,8 +177,8 @@ var FALLBACK_ENV_MAP = {
|
|
|
153
177
|
};
|
|
154
178
|
function getKeytar() {
|
|
155
179
|
try {
|
|
156
|
-
const
|
|
157
|
-
return
|
|
180
|
+
const require3 = createRequire(import.meta.url);
|
|
181
|
+
return require3("keytar");
|
|
158
182
|
} catch {
|
|
159
183
|
return null;
|
|
160
184
|
}
|
|
@@ -498,23 +522,31 @@ async function getModel(options) {
|
|
|
498
522
|
switch (options.provider) {
|
|
499
523
|
case "gemini": {
|
|
500
524
|
const apiKey = await resolveApiKey();
|
|
501
|
-
const google = createGoogleGenerativeAI({
|
|
525
|
+
const google = createGoogleGenerativeAI({
|
|
526
|
+
apiKey,
|
|
527
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
528
|
+
});
|
|
502
529
|
return google(modelName);
|
|
503
530
|
}
|
|
504
531
|
case "openai": {
|
|
505
532
|
const apiKey = await resolveApiKey();
|
|
506
|
-
const openai = createOpenAI({
|
|
533
|
+
const openai = createOpenAI({
|
|
534
|
+
apiKey,
|
|
535
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
536
|
+
});
|
|
507
537
|
return openai(modelName);
|
|
508
538
|
}
|
|
509
539
|
case "anthropic": {
|
|
510
540
|
const apiKey = await resolveApiKey();
|
|
511
|
-
const anthropic = createAnthropic({
|
|
541
|
+
const anthropic = createAnthropic({
|
|
542
|
+
apiKey,
|
|
543
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
544
|
+
});
|
|
512
545
|
return anthropic(modelName);
|
|
513
546
|
}
|
|
514
547
|
case "ollama": {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
});
|
|
548
|
+
const baseURL = options.ollamaBaseUrl || options.baseUrl || "http://localhost:11434/api";
|
|
549
|
+
const ollama = createOllama({ baseURL });
|
|
518
550
|
return ollama(modelName);
|
|
519
551
|
}
|
|
520
552
|
}
|
|
@@ -983,7 +1015,7 @@ function getIssueInfo(issueNumber) {
|
|
|
983
1015
|
return null;
|
|
984
1016
|
}
|
|
985
1017
|
}
|
|
986
|
-
var branchCommand = new Command2("branch").description("Generate a branch name from issue number or description").argument("[issue]", "Issue number (e.g., 123 or #123)").option("-d, --description <description>", "Use description instead of issue").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-t, --type <type>", "Branch type (feature, fix, hotfix, chore, refactor)").option("-c, --checkout", "Create and checkout the branch").action(async (issue, options) => {
|
|
1018
|
+
var branchCommand = new Command2("branch").description("Generate a branch name from issue number or description").argument("[issue]", "Issue number (e.g., 123 or #123)").option("-d, --description <description>", "Use description instead of issue").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-t, --type <type>", "Branch type (feature, fix, hotfix, chore, refactor)").option("-c, --checkout", "Create and checkout the branch").action(async (issue, options) => {
|
|
987
1019
|
const git = simpleGit();
|
|
988
1020
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
989
1021
|
const isRepo = await git.checkIsRepo();
|
|
@@ -1029,7 +1061,12 @@ ${issueInfo.body || ""}`;
|
|
|
1029
1061
|
try {
|
|
1030
1062
|
const branchName = await generateBranchName(
|
|
1031
1063
|
description,
|
|
1032
|
-
{
|
|
1064
|
+
{
|
|
1065
|
+
provider,
|
|
1066
|
+
model: options.model,
|
|
1067
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1068
|
+
language: getLanguage()
|
|
1069
|
+
},
|
|
1033
1070
|
{ type: options.type, issue: issueNumber },
|
|
1034
1071
|
template || void 0
|
|
1035
1072
|
);
|
|
@@ -1090,7 +1127,7 @@ function formatChangelog(changelog) {
|
|
|
1090
1127
|
}
|
|
1091
1128
|
return lines.join("\n");
|
|
1092
1129
|
}
|
|
1093
|
-
var changelogCommand = new Command3("changelog").description("Generate a changelog from commits between refs").argument("[from]", "Starting ref (tag, branch, commit)", "HEAD~10").argument("[to]", "Ending ref", "HEAD").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-t, --tag <tag>", "Generate changelog since this tag").option("--json", "Output as JSON").action(async (from, to, options) => {
|
|
1130
|
+
var changelogCommand = new Command3("changelog").description("Generate a changelog from commits between refs").argument("[from]", "Starting ref (tag, branch, commit)", "HEAD~10").argument("[to]", "Ending ref", "HEAD").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-t, --tag <tag>", "Generate changelog since this tag").option("--json", "Output as JSON").action(async (from, to, options) => {
|
|
1094
1131
|
const git = simpleGit2();
|
|
1095
1132
|
const isRepo = await git.checkIsRepo();
|
|
1096
1133
|
if (!isRepo) {
|
|
@@ -1126,7 +1163,12 @@ var changelogCommand = new Command3("changelog").description("Generate a changel
|
|
|
1126
1163
|
}
|
|
1127
1164
|
const changelog = await generateChangelog(
|
|
1128
1165
|
{ commits, diff, fromRef, toRef },
|
|
1129
|
-
{
|
|
1166
|
+
{
|
|
1167
|
+
provider,
|
|
1168
|
+
model: options.model,
|
|
1169
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1170
|
+
language: getLanguage()
|
|
1171
|
+
},
|
|
1130
1172
|
template || void 0
|
|
1131
1173
|
);
|
|
1132
1174
|
spinner.stop();
|
|
@@ -1155,7 +1197,7 @@ import chalk5 from "chalk";
|
|
|
1155
1197
|
import { Command as Command4 } from "commander";
|
|
1156
1198
|
import ora3 from "ora";
|
|
1157
1199
|
import { simpleGit as simpleGit3 } from "simple-git";
|
|
1158
|
-
var checkoutCommand = new Command4("checkout").description("Generate a branch name from current diff and checkout").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-y, --yes", "Skip confirmation and checkout directly").option("-s, --staged", "Use staged changes only instead of all changes").action(async (options) => {
|
|
1200
|
+
var checkoutCommand = new Command4("checkout").description("Generate a branch name from current diff and checkout").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-y, --yes", "Skip confirmation and checkout directly").option("-s, --staged", "Use staged changes only instead of all changes").action(async (options) => {
|
|
1159
1201
|
const git = simpleGit3();
|
|
1160
1202
|
const isRepo = await git.checkIsRepo();
|
|
1161
1203
|
if (!isRepo) {
|
|
@@ -1194,7 +1236,12 @@ ${untrackedFiles.map((f) => `+ ${f}`).join("\n")}`;
|
|
|
1194
1236
|
try {
|
|
1195
1237
|
const branchName = await generateBranchNameFromDiff(
|
|
1196
1238
|
diff,
|
|
1197
|
-
{
|
|
1239
|
+
{
|
|
1240
|
+
provider,
|
|
1241
|
+
model: options.model,
|
|
1242
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1243
|
+
language: getLanguage()
|
|
1244
|
+
},
|
|
1198
1245
|
template
|
|
1199
1246
|
);
|
|
1200
1247
|
spinner.stop();
|
|
@@ -1316,7 +1363,7 @@ import chalk7 from "chalk";
|
|
|
1316
1363
|
import { Command as Command6 } from "commander";
|
|
1317
1364
|
import ora5 from "ora";
|
|
1318
1365
|
import { simpleGit as simpleGit5 } from "simple-git";
|
|
1319
|
-
var commitCommand = new Command6("commit").description("Generate a commit message using AI").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").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) => {
|
|
1366
|
+
var commitCommand = new Command6("commit").description("Generate a commit message using AI").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").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) => {
|
|
1320
1367
|
const git = simpleGit5();
|
|
1321
1368
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
1322
1369
|
const isRepo = await git.checkIsRepo();
|
|
@@ -1349,7 +1396,12 @@ var commitCommand = new Command6("commit").description("Generate a commit messag
|
|
|
1349
1396
|
try {
|
|
1350
1397
|
const message = await generateCommitMessage(
|
|
1351
1398
|
diff,
|
|
1352
|
-
{
|
|
1399
|
+
{
|
|
1400
|
+
provider,
|
|
1401
|
+
model: options.model,
|
|
1402
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1403
|
+
language: getLanguage()
|
|
1404
|
+
},
|
|
1353
1405
|
template || void 0
|
|
1354
1406
|
);
|
|
1355
1407
|
spinner.stop();
|
|
@@ -1468,9 +1520,19 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
|
|
|
1468
1520
|
console.error(chalk8.red(err.message));
|
|
1469
1521
|
process.exit(1);
|
|
1470
1522
|
}
|
|
1523
|
+
} else if (key === "baseUrl") {
|
|
1524
|
+
try {
|
|
1525
|
+
setBaseUrl(value, options.local ?? false);
|
|
1526
|
+
const scope = options.local ? "(local)" : "(global)";
|
|
1527
|
+
console.log(chalk8.green(`\u2713 Base URL set to: ${value} ${scope}`));
|
|
1528
|
+
console.log(chalk8.gray("Applies to all AI providers (OpenAI, Anthropic, Gemini, Ollama)"));
|
|
1529
|
+
} catch (err) {
|
|
1530
|
+
console.error(chalk8.red(err.message));
|
|
1531
|
+
process.exit(1);
|
|
1532
|
+
}
|
|
1471
1533
|
} else {
|
|
1472
1534
|
console.error(chalk8.red(`Unknown config key: ${key}`));
|
|
1473
|
-
console.error(chalk8.gray("Available keys: lang, model, provider"));
|
|
1535
|
+
console.error(chalk8.gray("Available keys: lang, model, provider, baseUrl"));
|
|
1474
1536
|
process.exit(1);
|
|
1475
1537
|
}
|
|
1476
1538
|
});
|
|
@@ -1543,7 +1605,7 @@ import { simpleGit as simpleGit7 } from "simple-git";
|
|
|
1543
1605
|
var explainCommand = new Command8("explain").description("Get an AI-powered explanation of changes, commits, PRs, or files").argument(
|
|
1544
1606
|
"[target]",
|
|
1545
1607
|
"Commit hash, PR number, PR URL, or file path (default: uncommitted changes)"
|
|
1546
|
-
).option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-s, --staged", "Explain only staged changes").option("-n, --commits <n>", "Number of commits to analyze for file history (default: 1)", "1").option("--history", "Explain file change history instead of content").option("--json", "Output as JSON").action(async (target, options) => {
|
|
1608
|
+
).option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-s, --staged", "Explain only staged changes").option("-n, --commits <n>", "Number of commits to analyze for file history (default: 1)", "1").option("--history", "Explain file change history instead of content").option("--json", "Output as JSON").action(async (target, options) => {
|
|
1547
1609
|
const git = simpleGit7();
|
|
1548
1610
|
const isRepo = await git.checkIsRepo();
|
|
1549
1611
|
if (!isRepo) {
|
|
@@ -1595,7 +1657,12 @@ var explainCommand = new Command8("explain").description("Get an AI-powered expl
|
|
|
1595
1657
|
spinner.text = "AI is generating explanation...";
|
|
1596
1658
|
const explanation = await generateExplanation(
|
|
1597
1659
|
context,
|
|
1598
|
-
{
|
|
1660
|
+
{
|
|
1661
|
+
provider,
|
|
1662
|
+
model: options.model,
|
|
1663
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1664
|
+
language: getLanguage()
|
|
1665
|
+
},
|
|
1599
1666
|
template || void 0
|
|
1600
1667
|
);
|
|
1601
1668
|
spinner.stop();
|
|
@@ -1794,7 +1861,7 @@ import { simpleGit as simpleGit8 } from "simple-git";
|
|
|
1794
1861
|
var findCommand = new Command9("find").description("Find commits matching a vague description using AI").argument(
|
|
1795
1862
|
"<query>",
|
|
1796
1863
|
'Description of the change you are looking for (e.g., "login feature added")'
|
|
1797
|
-
).option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-n, --num <n>", "Number of commits to search through", "100").option("--path <path>", "Limit search to commits affecting this path").option("--author <author>", "Limit search to commits by this author").option("--since <date>", "Limit search to commits after this date").option("--until <date>", "Limit search to commits before this date").option("--max-results <n>", "Maximum number of matching commits to return", "5").option("--json", "Output as JSON").action(async (query, options) => {
|
|
1864
|
+
).option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-n, --num <n>", "Number of commits to search through", "100").option("--path <path>", "Limit search to commits affecting this path").option("--author <author>", "Limit search to commits by this author").option("--since <date>", "Limit search to commits after this date").option("--until <date>", "Limit search to commits before this date").option("--max-results <n>", "Maximum number of matching commits to return", "5").option("--json", "Output as JSON").action(async (query, options) => {
|
|
1798
1865
|
const git = simpleGit8();
|
|
1799
1866
|
const isRepo = await git.checkIsRepo();
|
|
1800
1867
|
if (!isRepo) {
|
|
@@ -1836,7 +1903,12 @@ var findCommand = new Command9("find").description("Find commits matching a vagu
|
|
|
1836
1903
|
const results = await searchCommits(
|
|
1837
1904
|
query,
|
|
1838
1905
|
commits,
|
|
1839
|
-
{
|
|
1906
|
+
{
|
|
1907
|
+
provider,
|
|
1908
|
+
model: options.model,
|
|
1909
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1910
|
+
language: getLanguage()
|
|
1911
|
+
},
|
|
1840
1912
|
parseInt(options.maxResults, 10),
|
|
1841
1913
|
template || void 0
|
|
1842
1914
|
);
|
|
@@ -1984,7 +2056,7 @@ function findConfigFiles(repoRoot) {
|
|
|
1984
2056
|
}
|
|
1985
2057
|
return found;
|
|
1986
2058
|
}
|
|
1987
|
-
var gitignoreCommand = new Command10("gitignore").description("Generate .gitignore from current codebase").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").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) => {
|
|
2059
|
+
var gitignoreCommand = new Command10("gitignore").description("Generate .gitignore from current codebase").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").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) => {
|
|
1988
2060
|
const git = simpleGit9();
|
|
1989
2061
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
1990
2062
|
const root = repoRoot.trim();
|
|
@@ -2020,7 +2092,12 @@ ${content}
|
|
|
2020
2092
|
configFiles: configFilesStr,
|
|
2021
2093
|
existingGitignore
|
|
2022
2094
|
},
|
|
2023
|
-
{
|
|
2095
|
+
{
|
|
2096
|
+
provider,
|
|
2097
|
+
model: options.model,
|
|
2098
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2099
|
+
language: getLanguage()
|
|
2100
|
+
},
|
|
2024
2101
|
template || void 0
|
|
2025
2102
|
);
|
|
2026
2103
|
spinner.stop();
|
|
@@ -2279,7 +2356,7 @@ import chalk14 from "chalk";
|
|
|
2279
2356
|
import { Command as Command13 } from "commander";
|
|
2280
2357
|
import ora10 from "ora";
|
|
2281
2358
|
import { simpleGit as simpleGit11 } from "simple-git";
|
|
2282
|
-
var mergeCommand = new Command13("merge").description("Merge a branch with AI-powered conflict resolution").argument("<branch>", "Branch to merge").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--no-commit", "Do not auto-commit after resolving").action(async (branch, options) => {
|
|
2359
|
+
var mergeCommand = new Command13("merge").description("Merge a branch with AI-powered conflict resolution").argument("<branch>", "Branch to merge").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("--no-commit", "Do not auto-commit after resolving").action(async (branch, options) => {
|
|
2283
2360
|
const git = simpleGit11();
|
|
2284
2361
|
const isRepo = await git.checkIsRepo();
|
|
2285
2362
|
if (!isRepo) {
|
|
@@ -2342,7 +2419,12 @@ Merging ${chalk14.cyan(branch)} into ${chalk14.cyan(currentBranch)}...
|
|
|
2342
2419
|
oursRef: currentBranch,
|
|
2343
2420
|
theirsRef: branch
|
|
2344
2421
|
},
|
|
2345
|
-
{
|
|
2422
|
+
{
|
|
2423
|
+
provider,
|
|
2424
|
+
model: options.model,
|
|
2425
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2426
|
+
language: getLanguage()
|
|
2427
|
+
},
|
|
2346
2428
|
template || void 0
|
|
2347
2429
|
);
|
|
2348
2430
|
spinner.stop();
|
|
@@ -2416,7 +2498,7 @@ function findPRTemplate(repoRoot) {
|
|
|
2416
2498
|
}
|
|
2417
2499
|
return findTemplate(repoRoot, "pr");
|
|
2418
2500
|
}
|
|
2419
|
-
var prCommand = new Command14("pr").description("Generate a pull request title and description using AI").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-b, --base <branch>", "Base branch to compare against (default: main or master)").option("--create", "Create the PR using gh CLI").option("--copy", "Copy the description to clipboard").action(async (options) => {
|
|
2501
|
+
var prCommand = new Command14("pr").description("Generate a pull request title and description using AI").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-b, --base <branch>", "Base branch to compare against (default: main or master)").option("--create", "Create the PR using gh CLI").option("--copy", "Copy the description to clipboard").action(async (options) => {
|
|
2420
2502
|
const git = simpleGit12();
|
|
2421
2503
|
const isRepo = await git.checkIsRepo();
|
|
2422
2504
|
if (!isRepo) {
|
|
@@ -2467,7 +2549,12 @@ var prCommand = new Command14("pr").description("Generate a pull request title a
|
|
|
2467
2549
|
commits,
|
|
2468
2550
|
diff
|
|
2469
2551
|
},
|
|
2470
|
-
{
|
|
2552
|
+
{
|
|
2553
|
+
provider,
|
|
2554
|
+
model: options.model,
|
|
2555
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2556
|
+
language: getLanguage()
|
|
2557
|
+
},
|
|
2471
2558
|
template || void 0
|
|
2472
2559
|
);
|
|
2473
2560
|
spinner.stop();
|
|
@@ -2633,7 +2720,7 @@ async function getPRDiff(prNumber) {
|
|
|
2633
2720
|
throw err;
|
|
2634
2721
|
}
|
|
2635
2722
|
}
|
|
2636
|
-
var reviewCommand = new Command15("review").description("Get an AI code review of your changes or a GitHub PR").argument("[pr-number]", "GitHub PR number to review").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-s, --staged", "Review only staged changes").option("-c, --commit <hash>", "Review a specific commit").option("--json", "Output as JSON").action(async (prNumber, options) => {
|
|
2723
|
+
var reviewCommand = new Command15("review").description("Get an AI code review of your changes or a GitHub PR").argument("[pr-number]", "GitHub PR number to review").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-s, --staged", "Review only staged changes").option("-c, --commit <hash>", "Review a specific commit").option("--json", "Output as JSON").action(async (prNumber, options) => {
|
|
2637
2724
|
const git = simpleGit13();
|
|
2638
2725
|
const isRepo = await git.checkIsRepo();
|
|
2639
2726
|
if (!isRepo) {
|
|
@@ -2677,7 +2764,12 @@ ${diff}`;
|
|
|
2677
2764
|
const template = findTemplate(repoRoot.trim(), "review");
|
|
2678
2765
|
const review = await generateCodeReview(
|
|
2679
2766
|
diff,
|
|
2680
|
-
{
|
|
2767
|
+
{
|
|
2768
|
+
provider,
|
|
2769
|
+
model: options.model,
|
|
2770
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2771
|
+
language: getLanguage()
|
|
2772
|
+
},
|
|
2681
2773
|
template || void 0
|
|
2682
2774
|
);
|
|
2683
2775
|
spinner.stop();
|
|
@@ -2749,7 +2841,7 @@ import chalk17 from "chalk";
|
|
|
2749
2841
|
import { Command as Command16 } from "commander";
|
|
2750
2842
|
import ora13 from "ora";
|
|
2751
2843
|
import { simpleGit as simpleGit14 } from "simple-git";
|
|
2752
|
-
var stashCommand = new Command16("stash").description("Stash changes with AI-generated name").argument("[name]", "Custom stash name (skips AI generation)").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("-l, --list", "List all stashes").option("-a, --apply [index]", "Apply stash (default: latest)").option("--pop [index]", "Pop stash (default: latest)").option("-d, --drop [index]", "Drop stash").option("--clear", "Clear all stashes").action(async (name, options) => {
|
|
2844
|
+
var stashCommand = new Command16("stash").description("Stash changes with AI-generated name").argument("[name]", "Custom stash name (skips AI generation)").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("-l, --list", "List all stashes").option("-a, --apply [index]", "Apply stash (default: latest)").option("--pop [index]", "Pop stash (default: latest)").option("-d, --drop [index]", "Drop stash").option("--clear", "Clear all stashes").action(async (name, options) => {
|
|
2753
2845
|
const git = simpleGit14();
|
|
2754
2846
|
const isRepo = await git.checkIsRepo();
|
|
2755
2847
|
if (!isRepo) {
|
|
@@ -2851,7 +2943,12 @@ ${stagedDiff}`;
|
|
|
2851
2943
|
const template = findTemplate(repoRoot.trim(), "stash");
|
|
2852
2944
|
stashName = await generateStashName(
|
|
2853
2945
|
fullDiff,
|
|
2854
|
-
{
|
|
2946
|
+
{
|
|
2947
|
+
provider,
|
|
2948
|
+
model: options.model,
|
|
2949
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2950
|
+
language: getLanguage()
|
|
2951
|
+
},
|
|
2855
2952
|
template || void 0
|
|
2856
2953
|
);
|
|
2857
2954
|
spinner.stop();
|
|
@@ -2870,7 +2967,7 @@ import chalk18 from "chalk";
|
|
|
2870
2967
|
import { Command as Command17 } from "commander";
|
|
2871
2968
|
import ora14 from "ora";
|
|
2872
2969
|
import { simpleGit as simpleGit15 } from "simple-git";
|
|
2873
|
-
var summaryCommand = new Command17("summary").description("Generate a work summary from your commits (for daily/weekly reports)").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--since <date>", "Start date (default: today)", "today").option("--until <date>", "End date").option("--author <author>", "Filter by author (default: current user)").option("--daily", "Generate daily report (alias for --since today)").option("--weekly", 'Generate weekly report (alias for --since "1 week ago")').option("--with-diff", "Include diff analysis for more detail").option("--markdown", "Output as markdown").option("--json", "Output as JSON").option("--copy", "Copy to clipboard").action(async (options) => {
|
|
2970
|
+
var summaryCommand = new Command17("summary").description("Generate a work summary from your commits (for daily/weekly reports)").option("-p, --provider <provider>", "AI provider (gemini, openai, anthropic, ollama)").option("-m, --model <model>", "Model to use (provider-specific)").option("--base-url <url>", "Base URL for API provider").option("--since <date>", "Start date (default: today)", "today").option("--until <date>", "End date").option("--author <author>", "Filter by author (default: current user)").option("--daily", "Generate daily report (alias for --since today)").option("--weekly", 'Generate weekly report (alias for --since "1 week ago")').option("--with-diff", "Include diff analysis for more detail").option("--markdown", "Output as markdown").option("--json", "Output as JSON").option("--copy", "Copy to clipboard").action(async (options) => {
|
|
2874
2971
|
const git = simpleGit15();
|
|
2875
2972
|
const isRepo = await git.checkIsRepo();
|
|
2876
2973
|
if (!isRepo) {
|
|
@@ -2930,7 +3027,12 @@ var summaryCommand = new Command17("summary").description("Generate a work summa
|
|
|
2930
3027
|
const template = findTemplate(repoRoot.trim(), "summary");
|
|
2931
3028
|
const summary = await generateWorkSummary(
|
|
2932
3029
|
{ commits, author, since, until: options.until, diff },
|
|
2933
|
-
{
|
|
3030
|
+
{
|
|
3031
|
+
provider,
|
|
3032
|
+
model: options.model,
|
|
3033
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
3034
|
+
language: getLanguage()
|
|
3035
|
+
},
|
|
2934
3036
|
format,
|
|
2935
3037
|
template || void 0
|
|
2936
3038
|
);
|
|
@@ -3172,8 +3274,10 @@ To set upstream: git push -u origin ${currentBranch}`));
|
|
|
3172
3274
|
});
|
|
3173
3275
|
|
|
3174
3276
|
// src/index.ts
|
|
3277
|
+
var require2 = createRequire2(import.meta.url);
|
|
3278
|
+
var pkg = require2("../package.json");
|
|
3175
3279
|
var program = new Command19();
|
|
3176
|
-
program.name("gut").description("Git Utility Tool - AI-powered git commands").version(
|
|
3280
|
+
program.name("gut").description("Git Utility Tool - AI-powered git commands").version(pkg.version, "-v, --version");
|
|
3177
3281
|
program.addCommand(cleanupCommand);
|
|
3178
3282
|
program.addCommand(authCommand);
|
|
3179
3283
|
program.addCommand(commitCommand);
|