gut-cli 0.1.31 → 0.1.33
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 +136 -35
- package/dist/index.js.map +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.js +18 -10
- 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
|
@@ -133,6 +133,29 @@ function setProvider(provider, local = false) {
|
|
|
133
133
|
setGlobalConfig("provider", provider);
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
function getBaseUrl() {
|
|
137
|
+
return getConfig().baseUrl;
|
|
138
|
+
}
|
|
139
|
+
function setBaseUrl(url, local = false) {
|
|
140
|
+
if (url === "") {
|
|
141
|
+
const path2 = local ? getLocalConfigPath() : getGlobalConfigPath();
|
|
142
|
+
if (local && !path2) throw new Error("Not in a git repository");
|
|
143
|
+
const config = local ? getLocalConfig() : getGlobalConfig();
|
|
144
|
+
delete config.baseUrl;
|
|
145
|
+
writeFileSync(path2 || getGlobalConfigPath(), JSON.stringify(config, null, 2));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
try {
|
|
149
|
+
new URL(url);
|
|
150
|
+
} catch {
|
|
151
|
+
throw new Error(`Invalid URL: ${url}`);
|
|
152
|
+
}
|
|
153
|
+
if (local) {
|
|
154
|
+
setLocalConfig("baseUrl", url);
|
|
155
|
+
} else {
|
|
156
|
+
setGlobalConfig("baseUrl", url);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
136
159
|
|
|
137
160
|
// src/lib/credentials.ts
|
|
138
161
|
var SERVICE_NAME = "gut-cli";
|
|
@@ -498,23 +521,31 @@ async function getModel(options) {
|
|
|
498
521
|
switch (options.provider) {
|
|
499
522
|
case "gemini": {
|
|
500
523
|
const apiKey = await resolveApiKey();
|
|
501
|
-
const google = createGoogleGenerativeAI({
|
|
524
|
+
const google = createGoogleGenerativeAI({
|
|
525
|
+
apiKey,
|
|
526
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
527
|
+
});
|
|
502
528
|
return google(modelName);
|
|
503
529
|
}
|
|
504
530
|
case "openai": {
|
|
505
531
|
const apiKey = await resolveApiKey();
|
|
506
|
-
const openai = createOpenAI({
|
|
532
|
+
const openai = createOpenAI({
|
|
533
|
+
apiKey,
|
|
534
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
535
|
+
});
|
|
507
536
|
return openai(modelName);
|
|
508
537
|
}
|
|
509
538
|
case "anthropic": {
|
|
510
539
|
const apiKey = await resolveApiKey();
|
|
511
|
-
const anthropic = createAnthropic({
|
|
540
|
+
const anthropic = createAnthropic({
|
|
541
|
+
apiKey,
|
|
542
|
+
...options.baseUrl && { baseURL: options.baseUrl }
|
|
543
|
+
});
|
|
512
544
|
return anthropic(modelName);
|
|
513
545
|
}
|
|
514
546
|
case "ollama": {
|
|
515
|
-
const
|
|
516
|
-
|
|
517
|
-
});
|
|
547
|
+
const baseURL = options.ollamaBaseUrl || options.baseUrl || "http://localhost:11434/api";
|
|
548
|
+
const ollama = createOllama({ baseURL });
|
|
518
549
|
return ollama(modelName);
|
|
519
550
|
}
|
|
520
551
|
}
|
|
@@ -533,7 +564,7 @@ async function generateCommitMessage(diff, options, template) {
|
|
|
533
564
|
const result = await generateText({
|
|
534
565
|
model,
|
|
535
566
|
prompt,
|
|
536
|
-
maxTokens:
|
|
567
|
+
maxTokens: 1024
|
|
537
568
|
});
|
|
538
569
|
return result.text.trim();
|
|
539
570
|
}
|
|
@@ -769,7 +800,7 @@ async function generateBranchName(description, options, context, template) {
|
|
|
769
800
|
const result = await generateText({
|
|
770
801
|
model,
|
|
771
802
|
prompt,
|
|
772
|
-
maxTokens:
|
|
803
|
+
maxTokens: 1024
|
|
773
804
|
});
|
|
774
805
|
return result.text.trim().replace(/[^a-zA-Z0-9/_-]/g, "");
|
|
775
806
|
}
|
|
@@ -787,7 +818,7 @@ async function generateBranchNameFromDiff(diff, options, template) {
|
|
|
787
818
|
const result = await generateText({
|
|
788
819
|
model,
|
|
789
820
|
prompt,
|
|
790
|
-
maxTokens:
|
|
821
|
+
maxTokens: 1024
|
|
791
822
|
});
|
|
792
823
|
return result.text.trim().replace(/[^a-zA-Z0-9/_-]/g, "");
|
|
793
824
|
}
|
|
@@ -805,7 +836,7 @@ async function generateStashName(diff, options, template) {
|
|
|
805
836
|
const result = await generateText({
|
|
806
837
|
model,
|
|
807
838
|
prompt,
|
|
808
|
-
maxTokens:
|
|
839
|
+
maxTokens: 1024
|
|
809
840
|
});
|
|
810
841
|
return result.text.trim();
|
|
811
842
|
}
|
|
@@ -983,7 +1014,7 @@ function getIssueInfo(issueNumber) {
|
|
|
983
1014
|
return null;
|
|
984
1015
|
}
|
|
985
1016
|
}
|
|
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) => {
|
|
1017
|
+
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
1018
|
const git = simpleGit();
|
|
988
1019
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
989
1020
|
const isRepo = await git.checkIsRepo();
|
|
@@ -1029,7 +1060,12 @@ ${issueInfo.body || ""}`;
|
|
|
1029
1060
|
try {
|
|
1030
1061
|
const branchName = await generateBranchName(
|
|
1031
1062
|
description,
|
|
1032
|
-
{
|
|
1063
|
+
{
|
|
1064
|
+
provider,
|
|
1065
|
+
model: options.model,
|
|
1066
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1067
|
+
language: getLanguage()
|
|
1068
|
+
},
|
|
1033
1069
|
{ type: options.type, issue: issueNumber },
|
|
1034
1070
|
template || void 0
|
|
1035
1071
|
);
|
|
@@ -1090,7 +1126,7 @@ function formatChangelog(changelog) {
|
|
|
1090
1126
|
}
|
|
1091
1127
|
return lines.join("\n");
|
|
1092
1128
|
}
|
|
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) => {
|
|
1129
|
+
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
1130
|
const git = simpleGit2();
|
|
1095
1131
|
const isRepo = await git.checkIsRepo();
|
|
1096
1132
|
if (!isRepo) {
|
|
@@ -1126,7 +1162,12 @@ var changelogCommand = new Command3("changelog").description("Generate a changel
|
|
|
1126
1162
|
}
|
|
1127
1163
|
const changelog = await generateChangelog(
|
|
1128
1164
|
{ commits, diff, fromRef, toRef },
|
|
1129
|
-
{
|
|
1165
|
+
{
|
|
1166
|
+
provider,
|
|
1167
|
+
model: options.model,
|
|
1168
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1169
|
+
language: getLanguage()
|
|
1170
|
+
},
|
|
1130
1171
|
template || void 0
|
|
1131
1172
|
);
|
|
1132
1173
|
spinner.stop();
|
|
@@ -1155,7 +1196,7 @@ import chalk5 from "chalk";
|
|
|
1155
1196
|
import { Command as Command4 } from "commander";
|
|
1156
1197
|
import ora3 from "ora";
|
|
1157
1198
|
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) => {
|
|
1199
|
+
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
1200
|
const git = simpleGit3();
|
|
1160
1201
|
const isRepo = await git.checkIsRepo();
|
|
1161
1202
|
if (!isRepo) {
|
|
@@ -1194,7 +1235,12 @@ ${untrackedFiles.map((f) => `+ ${f}`).join("\n")}`;
|
|
|
1194
1235
|
try {
|
|
1195
1236
|
const branchName = await generateBranchNameFromDiff(
|
|
1196
1237
|
diff,
|
|
1197
|
-
{
|
|
1238
|
+
{
|
|
1239
|
+
provider,
|
|
1240
|
+
model: options.model,
|
|
1241
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1242
|
+
language: getLanguage()
|
|
1243
|
+
},
|
|
1198
1244
|
template
|
|
1199
1245
|
);
|
|
1200
1246
|
spinner.stop();
|
|
@@ -1316,7 +1362,7 @@ import chalk7 from "chalk";
|
|
|
1316
1362
|
import { Command as Command6 } from "commander";
|
|
1317
1363
|
import ora5 from "ora";
|
|
1318
1364
|
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) => {
|
|
1365
|
+
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
1366
|
const git = simpleGit5();
|
|
1321
1367
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
1322
1368
|
const isRepo = await git.checkIsRepo();
|
|
@@ -1349,7 +1395,12 @@ var commitCommand = new Command6("commit").description("Generate a commit messag
|
|
|
1349
1395
|
try {
|
|
1350
1396
|
const message = await generateCommitMessage(
|
|
1351
1397
|
diff,
|
|
1352
|
-
{
|
|
1398
|
+
{
|
|
1399
|
+
provider,
|
|
1400
|
+
model: options.model,
|
|
1401
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1402
|
+
language: getLanguage()
|
|
1403
|
+
},
|
|
1353
1404
|
template || void 0
|
|
1354
1405
|
);
|
|
1355
1406
|
spinner.stop();
|
|
@@ -1468,9 +1519,19 @@ configCommand.command("set <key> <value>").description("Set a configuration valu
|
|
|
1468
1519
|
console.error(chalk8.red(err.message));
|
|
1469
1520
|
process.exit(1);
|
|
1470
1521
|
}
|
|
1522
|
+
} else if (key === "baseUrl") {
|
|
1523
|
+
try {
|
|
1524
|
+
setBaseUrl(value, options.local ?? false);
|
|
1525
|
+
const scope = options.local ? "(local)" : "(global)";
|
|
1526
|
+
console.log(chalk8.green(`\u2713 Base URL set to: ${value} ${scope}`));
|
|
1527
|
+
console.log(chalk8.gray("Applies to all AI providers (OpenAI, Anthropic, Gemini, Ollama)"));
|
|
1528
|
+
} catch (err) {
|
|
1529
|
+
console.error(chalk8.red(err.message));
|
|
1530
|
+
process.exit(1);
|
|
1531
|
+
}
|
|
1471
1532
|
} else {
|
|
1472
1533
|
console.error(chalk8.red(`Unknown config key: ${key}`));
|
|
1473
|
-
console.error(chalk8.gray("Available keys: lang, model, provider"));
|
|
1534
|
+
console.error(chalk8.gray("Available keys: lang, model, provider, baseUrl"));
|
|
1474
1535
|
process.exit(1);
|
|
1475
1536
|
}
|
|
1476
1537
|
});
|
|
@@ -1543,7 +1604,7 @@ import { simpleGit as simpleGit7 } from "simple-git";
|
|
|
1543
1604
|
var explainCommand = new Command8("explain").description("Get an AI-powered explanation of changes, commits, PRs, or files").argument(
|
|
1544
1605
|
"[target]",
|
|
1545
1606
|
"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) => {
|
|
1607
|
+
).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
1608
|
const git = simpleGit7();
|
|
1548
1609
|
const isRepo = await git.checkIsRepo();
|
|
1549
1610
|
if (!isRepo) {
|
|
@@ -1595,7 +1656,12 @@ var explainCommand = new Command8("explain").description("Get an AI-powered expl
|
|
|
1595
1656
|
spinner.text = "AI is generating explanation...";
|
|
1596
1657
|
const explanation = await generateExplanation(
|
|
1597
1658
|
context,
|
|
1598
|
-
{
|
|
1659
|
+
{
|
|
1660
|
+
provider,
|
|
1661
|
+
model: options.model,
|
|
1662
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1663
|
+
language: getLanguage()
|
|
1664
|
+
},
|
|
1599
1665
|
template || void 0
|
|
1600
1666
|
);
|
|
1601
1667
|
spinner.stop();
|
|
@@ -1794,7 +1860,7 @@ import { simpleGit as simpleGit8 } from "simple-git";
|
|
|
1794
1860
|
var findCommand = new Command9("find").description("Find commits matching a vague description using AI").argument(
|
|
1795
1861
|
"<query>",
|
|
1796
1862
|
'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) => {
|
|
1863
|
+
).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
1864
|
const git = simpleGit8();
|
|
1799
1865
|
const isRepo = await git.checkIsRepo();
|
|
1800
1866
|
if (!isRepo) {
|
|
@@ -1836,7 +1902,12 @@ var findCommand = new Command9("find").description("Find commits matching a vagu
|
|
|
1836
1902
|
const results = await searchCommits(
|
|
1837
1903
|
query,
|
|
1838
1904
|
commits,
|
|
1839
|
-
{
|
|
1905
|
+
{
|
|
1906
|
+
provider,
|
|
1907
|
+
model: options.model,
|
|
1908
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
1909
|
+
language: getLanguage()
|
|
1910
|
+
},
|
|
1840
1911
|
parseInt(options.maxResults, 10),
|
|
1841
1912
|
template || void 0
|
|
1842
1913
|
);
|
|
@@ -1984,7 +2055,7 @@ function findConfigFiles(repoRoot) {
|
|
|
1984
2055
|
}
|
|
1985
2056
|
return found;
|
|
1986
2057
|
}
|
|
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) => {
|
|
2058
|
+
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
2059
|
const git = simpleGit9();
|
|
1989
2060
|
const repoRoot = await git.revparse(["--show-toplevel"]).catch(() => process.cwd());
|
|
1990
2061
|
const root = repoRoot.trim();
|
|
@@ -2020,7 +2091,12 @@ ${content}
|
|
|
2020
2091
|
configFiles: configFilesStr,
|
|
2021
2092
|
existingGitignore
|
|
2022
2093
|
},
|
|
2023
|
-
{
|
|
2094
|
+
{
|
|
2095
|
+
provider,
|
|
2096
|
+
model: options.model,
|
|
2097
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2098
|
+
language: getLanguage()
|
|
2099
|
+
},
|
|
2024
2100
|
template || void 0
|
|
2025
2101
|
);
|
|
2026
2102
|
spinner.stop();
|
|
@@ -2279,7 +2355,7 @@ import chalk14 from "chalk";
|
|
|
2279
2355
|
import { Command as Command13 } from "commander";
|
|
2280
2356
|
import ora10 from "ora";
|
|
2281
2357
|
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) => {
|
|
2358
|
+
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
2359
|
const git = simpleGit11();
|
|
2284
2360
|
const isRepo = await git.checkIsRepo();
|
|
2285
2361
|
if (!isRepo) {
|
|
@@ -2342,7 +2418,12 @@ Merging ${chalk14.cyan(branch)} into ${chalk14.cyan(currentBranch)}...
|
|
|
2342
2418
|
oursRef: currentBranch,
|
|
2343
2419
|
theirsRef: branch
|
|
2344
2420
|
},
|
|
2345
|
-
{
|
|
2421
|
+
{
|
|
2422
|
+
provider,
|
|
2423
|
+
model: options.model,
|
|
2424
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2425
|
+
language: getLanguage()
|
|
2426
|
+
},
|
|
2346
2427
|
template || void 0
|
|
2347
2428
|
);
|
|
2348
2429
|
spinner.stop();
|
|
@@ -2416,7 +2497,7 @@ function findPRTemplate(repoRoot) {
|
|
|
2416
2497
|
}
|
|
2417
2498
|
return findTemplate(repoRoot, "pr");
|
|
2418
2499
|
}
|
|
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) => {
|
|
2500
|
+
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
2501
|
const git = simpleGit12();
|
|
2421
2502
|
const isRepo = await git.checkIsRepo();
|
|
2422
2503
|
if (!isRepo) {
|
|
@@ -2467,7 +2548,12 @@ var prCommand = new Command14("pr").description("Generate a pull request title a
|
|
|
2467
2548
|
commits,
|
|
2468
2549
|
diff
|
|
2469
2550
|
},
|
|
2470
|
-
{
|
|
2551
|
+
{
|
|
2552
|
+
provider,
|
|
2553
|
+
model: options.model,
|
|
2554
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2555
|
+
language: getLanguage()
|
|
2556
|
+
},
|
|
2471
2557
|
template || void 0
|
|
2472
2558
|
);
|
|
2473
2559
|
spinner.stop();
|
|
@@ -2633,7 +2719,7 @@ async function getPRDiff(prNumber) {
|
|
|
2633
2719
|
throw err;
|
|
2634
2720
|
}
|
|
2635
2721
|
}
|
|
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) => {
|
|
2722
|
+
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
2723
|
const git = simpleGit13();
|
|
2638
2724
|
const isRepo = await git.checkIsRepo();
|
|
2639
2725
|
if (!isRepo) {
|
|
@@ -2677,7 +2763,12 @@ ${diff}`;
|
|
|
2677
2763
|
const template = findTemplate(repoRoot.trim(), "review");
|
|
2678
2764
|
const review = await generateCodeReview(
|
|
2679
2765
|
diff,
|
|
2680
|
-
{
|
|
2766
|
+
{
|
|
2767
|
+
provider,
|
|
2768
|
+
model: options.model,
|
|
2769
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2770
|
+
language: getLanguage()
|
|
2771
|
+
},
|
|
2681
2772
|
template || void 0
|
|
2682
2773
|
);
|
|
2683
2774
|
spinner.stop();
|
|
@@ -2749,7 +2840,7 @@ import chalk17 from "chalk";
|
|
|
2749
2840
|
import { Command as Command16 } from "commander";
|
|
2750
2841
|
import ora13 from "ora";
|
|
2751
2842
|
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) => {
|
|
2843
|
+
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
2844
|
const git = simpleGit14();
|
|
2754
2845
|
const isRepo = await git.checkIsRepo();
|
|
2755
2846
|
if (!isRepo) {
|
|
@@ -2851,7 +2942,12 @@ ${stagedDiff}`;
|
|
|
2851
2942
|
const template = findTemplate(repoRoot.trim(), "stash");
|
|
2852
2943
|
stashName = await generateStashName(
|
|
2853
2944
|
fullDiff,
|
|
2854
|
-
{
|
|
2945
|
+
{
|
|
2946
|
+
provider,
|
|
2947
|
+
model: options.model,
|
|
2948
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
2949
|
+
language: getLanguage()
|
|
2950
|
+
},
|
|
2855
2951
|
template || void 0
|
|
2856
2952
|
);
|
|
2857
2953
|
spinner.stop();
|
|
@@ -2870,7 +2966,7 @@ import chalk18 from "chalk";
|
|
|
2870
2966
|
import { Command as Command17 } from "commander";
|
|
2871
2967
|
import ora14 from "ora";
|
|
2872
2968
|
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) => {
|
|
2969
|
+
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
2970
|
const git = simpleGit15();
|
|
2875
2971
|
const isRepo = await git.checkIsRepo();
|
|
2876
2972
|
if (!isRepo) {
|
|
@@ -2930,7 +3026,12 @@ var summaryCommand = new Command17("summary").description("Generate a work summa
|
|
|
2930
3026
|
const template = findTemplate(repoRoot.trim(), "summary");
|
|
2931
3027
|
const summary = await generateWorkSummary(
|
|
2932
3028
|
{ commits, author, since, until: options.until, diff },
|
|
2933
|
-
{
|
|
3029
|
+
{
|
|
3030
|
+
provider,
|
|
3031
|
+
model: options.model,
|
|
3032
|
+
baseUrl: options.baseUrl || getBaseUrl(),
|
|
3033
|
+
language: getLanguage()
|
|
3034
|
+
},
|
|
2934
3035
|
format,
|
|
2935
3036
|
template || void 0
|
|
2936
3037
|
);
|