gitpt 1.4.0 → 1.7.2
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 +34 -160
- package/dist/commands/commit/commitFlags.js +7 -0
- package/dist/commands/commit/context/buildPrompt.js +16 -0
- package/dist/commands/commit/context/summaryPrompt.js +20 -0
- package/dist/commands/commit/context/systemPrompt.js +4 -1
- package/dist/commands/commit/context/userPrompt.js +4 -1
- package/dist/commands/commit/generateCommitMessage.js +16 -37
- package/dist/commands/commit/index.js +187 -178
- package/dist/commands/commit/summarizeDiff.js +193 -0
- package/dist/commands/config.js +24 -9
- package/dist/commands/hook/index.js +68 -0
- package/dist/commands/middleware/capabilitiesMiddleware/ghCapability.js +20 -20
- package/dist/commands/middleware/capabilitiesMiddleware/gitCapability.js +13 -10
- package/dist/commands/middleware/capabilitiesMiddleware/index.js +12 -11
- package/dist/commands/middleware/hasStagedChangesMiddleware.js +9 -6
- package/dist/commands/middleware/setupMiddleware/defaultModels.js +15 -0
- package/dist/commands/middleware/setupMiddleware/index.js +66 -38
- package/dist/commands/model.js +7 -4
- package/dist/commands/passthroughArgs.js +11 -0
- package/dist/commands/pr/context/systemPrompt.js +4 -1
- package/dist/commands/pr/context/userPrompt.js +4 -1
- package/dist/commands/pr/generatePRDetails.js +25 -31
- package/dist/commands/pr/getPRContext.js +37 -62
- package/dist/commands/pr/index.js +57 -62
- package/dist/commands/reset.js +26 -0
- package/dist/commands/review/index.js +31 -0
- package/dist/commands/setup.js +38 -13
- package/dist/config.js +63 -55
- package/dist/index.js +31 -62
- package/dist/llm/budget.js +10 -0
- package/dist/llm/index.js +12 -12
- package/dist/llm/providers/anthropic/index.js +31 -0
- package/dist/llm/providers/apiKey.js +41 -0
- package/dist/llm/providers/apple/client.js +77 -0
- package/dist/llm/providers/apple/index.js +69 -0
- package/dist/llm/providers/apple/models.js +29 -0
- package/dist/llm/providers/base.js +36 -0
- package/dist/llm/providers/local/index.js +84 -0
- package/dist/llm/providers/openai/index.js +19 -0
- package/dist/llm/providers/openaiCompatible.js +66 -0
- package/dist/llm/providers/openrouter/index.js +19 -0
- package/dist/llm/registry.js +39 -0
- package/dist/llm/setup/getAvailableModels.js +17 -0
- package/dist/llm/setup/selectModel.js +40 -0
- package/dist/llm/tokenCount.js +5 -0
- package/dist/package.js +67 -0
- package/dist/services/gh/createPullRequest.js +38 -58
- package/dist/services/gh/index.js +6 -3
- package/dist/services/gh/isAvailable.js +10 -8
- package/dist/services/git/executeGitAdd.js +11 -12
- package/dist/services/git/executeGitCommit.js +10 -11
- package/dist/services/git/getAmendChanges.js +23 -0
- package/dist/services/git/getChangedFiles.js +28 -61
- package/dist/services/git/getCommitsSinceBaseBranch.js +28 -56
- package/dist/services/git/getCurrentBranch.js +10 -8
- package/dist/services/git/getDefaultBranch.js +35 -60
- package/dist/services/git/getStagedChanges.js +10 -8
- package/dist/services/git/getStagedFiles.js +10 -9
- package/dist/services/git/hasStagedChanges.js +9 -8
- package/dist/services/git/index.js +17 -12
- package/dist/services/git/isAvailable.js +10 -8
- package/dist/services/git/isGitRepository.js +10 -8
- package/dist/utils/commitlint.js +97 -135
- package/dist/utils/formatBaseURL.js +7 -6
- package/dist/utils/maskApiKey.js +6 -7
- package/package.json +19 -5
- package/dist/commands/commit/context/systemPrompt.d.ts +0 -1
- package/dist/commands/commit/context/userPrompt.d.ts +0 -1
- package/dist/commands/commit/generateCommitMessage.d.ts +0 -1
- package/dist/commands/commit/index.d.ts +0 -7
- package/dist/commands/config.d.ts +0 -1
- package/dist/commands/middleware/capabilitiesMiddleware/ghCapability.d.ts +0 -1
- package/dist/commands/middleware/capabilitiesMiddleware/gitCapability.d.ts +0 -1
- package/dist/commands/middleware/capabilitiesMiddleware/index.d.ts +0 -3
- package/dist/commands/middleware/hasStagedChangesMiddleware.d.ts +0 -1
- package/dist/commands/middleware/setupMiddleware/getAvailableModels.d.ts +0 -4
- package/dist/commands/middleware/setupMiddleware/getAvailableModels.js +0 -11
- package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.d.ts +0 -1
- package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.js +0 -39
- package/dist/commands/middleware/setupMiddleware/index.d.ts +0 -4
- package/dist/commands/middleware/setupMiddleware/selectModel.d.ts +0 -5
- package/dist/commands/middleware/setupMiddleware/selectModel.js +0 -38
- package/dist/commands/middleware/setupMiddleware/setupLocalLLM.d.ts +0 -5
- package/dist/commands/middleware/setupMiddleware/setupLocalLLM.js +0 -60
- package/dist/commands/middleware/setupMiddleware/setupOpenRouter.d.ts +0 -2
- package/dist/commands/middleware/setupMiddleware/setupOpenRouter.js +0 -66
- package/dist/commands/middleware/setupMiddleware/types.d.ts +0 -13
- package/dist/commands/middleware/setupMiddleware/types.js +0 -1
- package/dist/commands/model.d.ts +0 -1
- package/dist/commands/pr/context/systemPrompt.d.ts +0 -1
- package/dist/commands/pr/context/userPrompt.d.ts +0 -1
- package/dist/commands/pr/generatePRDetails.d.ts +0 -4
- package/dist/commands/pr/getPRContext.d.ts +0 -1
- package/dist/commands/pr/index.d.ts +0 -10
- package/dist/commands/setup.d.ts +0 -3
- package/dist/config.d.ts +0 -18
- package/dist/index.d.ts +0 -2
- package/dist/llm/index.d.ts +0 -5
- package/dist/services/gh/createPullRequest.d.ts +0 -1
- package/dist/services/gh/index.d.ts +0 -4
- package/dist/services/gh/isAvailable.d.ts +0 -1
- package/dist/services/git/executeGitAdd.d.ts +0 -1
- package/dist/services/git/executeGitCommit.d.ts +0 -1
- package/dist/services/git/getChangedFiles.d.ts +0 -1
- package/dist/services/git/getCommitsSinceBaseBranch.d.ts +0 -1
- package/dist/services/git/getCurrentBranch.d.ts +0 -1
- package/dist/services/git/getDefaultBranch.d.ts +0 -1
- package/dist/services/git/getStagedChanges.d.ts +0 -1
- package/dist/services/git/getStagedFiles.d.ts +0 -1
- package/dist/services/git/hasStagedChanges.d.ts +0 -1
- package/dist/services/git/index.d.ts +0 -13
- package/dist/services/git/isAvailable.d.ts +0 -1
- package/dist/services/git/isGitRepository.d.ts +0 -1
- package/dist/utils/commitlint.d.ts +0 -25
- package/dist/utils/formatBaseURL.d.ts +0 -1
- package/dist/utils/maskApiKey.d.ts +0 -1
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { execSync } from "child_process";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
//#region src/services/git/isAvailable.ts
|
|
3
|
+
var isAvailable = () => {
|
|
4
|
+
try {
|
|
5
|
+
execSync("git --version", { stdio: "ignore" });
|
|
6
|
+
return true;
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
10
|
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { isAvailable };
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { execSync } from "child_process";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
//#region src/services/git/isGitRepository.ts
|
|
3
|
+
var isGitRepository = () => {
|
|
4
|
+
try {
|
|
5
|
+
execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
|
|
6
|
+
return true;
|
|
7
|
+
} catch (error) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
10
|
};
|
|
11
|
+
//#endregion
|
|
12
|
+
export { isGitRepository };
|
package/dist/utils/commitlint.js
CHANGED
|
@@ -1,148 +1,110 @@
|
|
|
1
|
-
import loadConfig from "@commitlint/load";
|
|
2
1
|
import { execSync } from "child_process";
|
|
2
|
+
import loadConfig from "@commitlint/load";
|
|
3
3
|
import fs from "fs";
|
|
4
|
+
//#region src/utils/commitlint.ts
|
|
4
5
|
/**
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
return fs.existsSync(file);
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
return false;
|
|
30
|
-
}
|
|
31
|
-
});
|
|
6
|
+
* Check if a commitlint configuration exists in the repository
|
|
7
|
+
*/
|
|
8
|
+
function hasCommitlintConfig() {
|
|
9
|
+
const possibleConfigFiles = [
|
|
10
|
+
".commitlintrc",
|
|
11
|
+
".commitlintrc.json",
|
|
12
|
+
".commitlintrc.yaml",
|
|
13
|
+
".commitlintrc.yml",
|
|
14
|
+
".commitlintrc.js",
|
|
15
|
+
"commitlint.config.js",
|
|
16
|
+
"package.json"
|
|
17
|
+
];
|
|
18
|
+
readCommitlintConfig();
|
|
19
|
+
return possibleConfigFiles.some((file) => {
|
|
20
|
+
try {
|
|
21
|
+
if (file === "package.json") return JSON.parse(fs.readFileSync("package.json", "utf8")).commitlint !== void 0;
|
|
22
|
+
return fs.existsSync(file);
|
|
23
|
+
} catch (error) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
});
|
|
32
27
|
}
|
|
33
28
|
/**
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
// console.log(config);
|
|
39
|
-
return config.rules;
|
|
29
|
+
* Read commitlint config file (using @commitlint/load) and print it out
|
|
30
|
+
*/
|
|
31
|
+
async function readCommitlintConfig() {
|
|
32
|
+
return (await loadConfig()).rules;
|
|
40
33
|
}
|
|
41
34
|
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
if (fs.existsSync(".commitlintrc.json")) {
|
|
63
|
-
const config = JSON.parse(fs.readFileSync(".commitlintrc.json", "utf8"));
|
|
64
|
-
return formatCommitlintRules(config);
|
|
65
|
-
}
|
|
66
|
-
// Default to conventional commits format if we can't parse the config
|
|
67
|
-
return "Follow the conventional commit format (type(scope): message)";
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
catch (error) {
|
|
71
|
-
// If all else fails, return a generic message
|
|
72
|
-
return "Follow the conventional commit format (type(scope): message)";
|
|
73
|
-
}
|
|
35
|
+
* Get the commitlint configuration format rules as a string
|
|
36
|
+
*/
|
|
37
|
+
function getCommitlintRules() {
|
|
38
|
+
try {
|
|
39
|
+
try {
|
|
40
|
+
const rulesOutput = execSync("npx commitlint --print-config", { stdio: [
|
|
41
|
+
"ignore",
|
|
42
|
+
"pipe",
|
|
43
|
+
"ignore"
|
|
44
|
+
] }).toString();
|
|
45
|
+
return formatCommitlintRules(JSON.parse(rulesOutput));
|
|
46
|
+
} catch (error) {
|
|
47
|
+
if (fs.existsSync("commitlint.config.js")) return "Follow the conventional commit format (type(scope): message)";
|
|
48
|
+
if (fs.existsSync(".commitlintrc.json")) return formatCommitlintRules(JSON.parse(fs.readFileSync(".commitlintrc.json", "utf8")));
|
|
49
|
+
return "Follow the conventional commit format (type(scope): message)";
|
|
50
|
+
}
|
|
51
|
+
} catch (error) {
|
|
52
|
+
return "Follow the conventional commit format (type(scope): message)";
|
|
53
|
+
}
|
|
74
54
|
}
|
|
75
55
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
56
|
+
* Format commitlint rules into a human-readable string
|
|
57
|
+
*/
|
|
78
58
|
function formatCommitlintRules(config) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
rulesDescription += `- Subject must follow case rules\n`;
|
|
97
|
-
}
|
|
98
|
-
if (config.rules["subject-max-length"]) {
|
|
99
|
-
const maxLength = config.rules["subject-max-length"][2];
|
|
100
|
-
rulesDescription += `- Subject must be no longer than ${maxLength} characters\n`;
|
|
101
|
-
}
|
|
102
|
-
rulesDescription +=
|
|
103
|
-
"- Use a single commit message, not multiple messages separated by blank lines or markdown formatting";
|
|
104
|
-
return rulesDescription;
|
|
59
|
+
let rulesDescription = "Follow these commit message rules:\n";
|
|
60
|
+
if (!config.rules) return "Follow the conventional commit format (type(scope): message)";
|
|
61
|
+
if (config.rules["type-enum"] && Array.isArray(config.rules["type-enum"][2])) {
|
|
62
|
+
const allowedTypes = config.rules["type-enum"][2];
|
|
63
|
+
rulesDescription += `- Commit type must be one of: ${allowedTypes.join(", ")}\n`;
|
|
64
|
+
}
|
|
65
|
+
if (config.rules["scope-enum"] && Array.isArray(config.rules["scope-enum"][2])) {
|
|
66
|
+
const allowedScopes = config.rules["scope-enum"][2];
|
|
67
|
+
rulesDescription += `- Scope must be one of: ${allowedScopes.join(", ")}\n`;
|
|
68
|
+
}
|
|
69
|
+
if (config.rules["subject-case"]) rulesDescription += `- Subject must follow case rules\n`;
|
|
70
|
+
if (config.rules["subject-max-length"]) {
|
|
71
|
+
const maxLength = config.rules["subject-max-length"][2];
|
|
72
|
+
rulesDescription += `- Subject must be no longer than ${maxLength} characters\n`;
|
|
73
|
+
}
|
|
74
|
+
rulesDescription += "- Use a single commit message, not multiple messages separated by blank lines or markdown formatting";
|
|
75
|
+
return rulesDescription;
|
|
105
76
|
}
|
|
106
77
|
/**
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// If we still can't get error output, fall back to basic pattern check
|
|
138
|
-
fs.unlinkSync(tempFile);
|
|
139
|
-
return { valid: true };
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
catch (error) {
|
|
144
|
-
// If all else fails, just do a basic regex check
|
|
145
|
-
console.warn("Warning: Could not validate with commitlint, performing basic validation");
|
|
146
|
-
return { valid: true };
|
|
147
|
-
}
|
|
78
|
+
* Validate a commit message against commitlint rules
|
|
79
|
+
* @param message The commit message to validate
|
|
80
|
+
* @returns An object with success status and error message if applicable
|
|
81
|
+
*/
|
|
82
|
+
async function validateCommitMessage(message) {
|
|
83
|
+
if (!hasCommitlintConfig()) return { valid: true };
|
|
84
|
+
try {
|
|
85
|
+
const tempFile = `/tmp/gitpt-commit-msg-${Date.now()}`;
|
|
86
|
+
fs.writeFileSync(tempFile, message);
|
|
87
|
+
try {
|
|
88
|
+
execSync(`npx commitlint < ${tempFile}`, { stdio: "ignore" });
|
|
89
|
+
fs.unlinkSync(tempFile);
|
|
90
|
+
return { valid: true };
|
|
91
|
+
} catch (error) {
|
|
92
|
+
try {
|
|
93
|
+
const errorOutput = execSync(`npx commitlint < ${tempFile} 2>&1 || true`).toString();
|
|
94
|
+
fs.unlinkSync(tempFile);
|
|
95
|
+
return {
|
|
96
|
+
valid: false,
|
|
97
|
+
errors: errorOutput
|
|
98
|
+
};
|
|
99
|
+
} catch (e) {
|
|
100
|
+
fs.unlinkSync(tempFile);
|
|
101
|
+
return { valid: true };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.warn("Warning: Could not validate with commitlint, performing basic validation");
|
|
106
|
+
return { valid: true };
|
|
107
|
+
}
|
|
148
108
|
}
|
|
109
|
+
//#endregion
|
|
110
|
+
export { getCommitlintRules, hasCommitlintConfig, validateCommitMessage };
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
return baseURL;
|
|
1
|
+
//#region src/utils/formatBaseURL.ts
|
|
2
|
+
var formatBaseURL = (baseURL) => {
|
|
3
|
+
const trimmed = baseURL.replace(/\/+$/, "");
|
|
4
|
+
if (!trimmed.endsWith("/v1")) return `${trimmed}/v1`;
|
|
5
|
+
return trimmed;
|
|
7
6
|
};
|
|
7
|
+
//#endregion
|
|
8
|
+
export { formatBaseURL };
|
package/dist/utils/maskApiKey.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const firstFour = apiKey.substring(0, 4);
|
|
6
|
-
const lastFour = apiKey.substring(apiKey.length - 4);
|
|
7
|
-
return `${firstFour}...${lastFour}`;
|
|
1
|
+
//#region src/utils/maskApiKey.ts
|
|
2
|
+
var maskApiKey = (apiKey) => {
|
|
3
|
+
if (apiKey.length <= 10) return "*".repeat(apiKey.length);
|
|
4
|
+
return `${apiKey.substring(0, 4)}...${apiKey.substring(apiKey.length - 4)}`;
|
|
8
5
|
};
|
|
6
|
+
//#endregion
|
|
7
|
+
export { maskApiKey };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitpt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "CLI tool that helps you write commit messages & pull request descriptions using AI",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -14,8 +14,16 @@
|
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
17
|
+
"lint": "oxlint",
|
|
18
|
+
"build": "vite build",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"test:apple": "npm run build && node tests/apple-foundation-models/run.mjs",
|
|
22
|
+
"bench:apple": "npm run build && node tests/apple-foundation-models/benchmark.mjs",
|
|
23
|
+
"bench:local": "npm run build && node tests/local-model/run.mjs",
|
|
24
|
+
"bench:all": "npm run build && node tests/run-all.mjs",
|
|
25
|
+
"check:prompt": "npm run build && node tests/snapshots/check.mjs",
|
|
26
|
+
"build:demo": "node scripts/build-demo.mjs",
|
|
19
27
|
"prepublishOnly": "npm run build"
|
|
20
28
|
},
|
|
21
29
|
"repository": {
|
|
@@ -38,8 +46,13 @@
|
|
|
38
46
|
"@types/inquirer": "^9.0.7",
|
|
39
47
|
"@types/node": "^22.14.1",
|
|
40
48
|
"@types/node-fetch": "^2.6.12",
|
|
49
|
+
"ffmpeg-static": "^5.3.0",
|
|
50
|
+
"oxlint": "^1.71.0",
|
|
51
|
+
"pngjs": "^7.0.0",
|
|
41
52
|
"tsc-alias": "^1.8.16",
|
|
42
|
-
"typescript": "^5.8.3"
|
|
53
|
+
"typescript": "^5.8.3",
|
|
54
|
+
"vite": "^8.1.0",
|
|
55
|
+
"vitest": "^4.1.9"
|
|
43
56
|
},
|
|
44
57
|
"dependencies": {
|
|
45
58
|
"@commitlint/cli": "^19.8.1",
|
|
@@ -50,6 +63,7 @@
|
|
|
50
63
|
"configstore": "^7.0.0",
|
|
51
64
|
"inquirer": "^12.5.2",
|
|
52
65
|
"node-fetch": "^3.3.2",
|
|
53
|
-
"openai": "^4.100.0"
|
|
66
|
+
"openai": "^4.100.0",
|
|
67
|
+
"ora": "^8.2.0"
|
|
54
68
|
}
|
|
55
69
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const systemPrompt = "\nYou are a helpful assistant that generates concise, informative Git commit messages.\n\nFollow these strict rules:\n1. Use conventional commit format: type: description\n2. Types are: feat, fix, docs, style, refactor, test, chore\n3. NO scopes in parentheses - do not use feat(scope)\n4. Keep the entire message under 100 characters\n5. Use present tense (e.g., \"add feature\" not \"added feature\")\n6. Be brief but descriptive about WHAT changed\n7. Do not include detailed explanations\n\nCritical Rules:\n- Return a SINGLE LINE commit message only, with no additional explanations or paragraphs\n- Do NOT include a detailed message body section, just the commit title line\n- Do NOT use multiple lines, even for a single message\n\nExamples of Good Commit Messages:\n- feat: add user authentication system\n- fix: resolve crash when opening settings menu\n- refactor: simplify data processing pipeline\n- docs: update installation instructions in README\n- chore: update npm dependencies to latest versions\n- style: fix indentation in CSS files\n- test: add unit tests for payment processing\n- perf: optimize database queries for faster loading\n- build: update webpack configuration\n- ci: fix GitHub Actions workflow\n\nExamples of Bad Commit Messages:\n- added login screen \u274C (missing type prefix)\n- feat(auth): implement OAuth login \u274C (using scope parentheses)\n- This is a really long commit message that exceeds the limit and contains too much information \u274C (too long)\n- feat: Adding user auth\n \n This implements the login page... \u274C (contains multiple lines)\n- \"fix: update styling\" \u274C (includes quotes)\n";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const userPrompt: (diff: string) => string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const generateCommitMessage: (diff: string, validationErrors?: string) => Promise<string>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const configCommand: () => Promise<void>;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const ghCapability: () => void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const gitCapability: () => void;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const hasStagedChangesMiddleware: () => void;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { getLLMClient } from "../../../llm/index.js";
|
|
2
|
-
export const getAvailableModels = async (options) => {
|
|
3
|
-
const { baseURLOverride } = options || {};
|
|
4
|
-
let modelsList = await getLLMClient({ baseURLOverride }).models.list();
|
|
5
|
-
const modelsData = modelsList.data;
|
|
6
|
-
while (modelsList.hasNextPage()) {
|
|
7
|
-
modelsList = await modelsList.getNextPage();
|
|
8
|
-
modelsData.push(...modelsList.data);
|
|
9
|
-
}
|
|
10
|
-
return modelsData;
|
|
11
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const getOrUpdateApiKey: (existingApiKey?: string) => Promise<string>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import inquirer from "inquirer";
|
|
2
|
-
import { maskApiKey } from "../../../utils/maskApiKey.js";
|
|
3
|
-
export const getOrUpdateApiKey = async (existingApiKey) => {
|
|
4
|
-
// For setup command, handle API key selection
|
|
5
|
-
if (existingApiKey) {
|
|
6
|
-
// If we have an existing API key, ask if the user wants to keep it or use a new one
|
|
7
|
-
const useExistingKeyAnswer = await inquirer.prompt([
|
|
8
|
-
{
|
|
9
|
-
type: "list",
|
|
10
|
-
name: "useExistingKey",
|
|
11
|
-
message: "OpenRouter API key:",
|
|
12
|
-
choices: [
|
|
13
|
-
{
|
|
14
|
-
name: `Use existing key (${maskApiKey(existingApiKey)})`,
|
|
15
|
-
value: true,
|
|
16
|
-
},
|
|
17
|
-
{ name: "Enter a new API key", value: false },
|
|
18
|
-
],
|
|
19
|
-
},
|
|
20
|
-
]);
|
|
21
|
-
if (useExistingKeyAnswer.useExistingKey) {
|
|
22
|
-
return existingApiKey;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
// If no existing key or user wants a new one, prompt for a new API key
|
|
26
|
-
const apiKeyAnswer = await inquirer.prompt([
|
|
27
|
-
{
|
|
28
|
-
type: "input",
|
|
29
|
-
name: "apiKey",
|
|
30
|
-
message: "Enter your OpenRouter API key:",
|
|
31
|
-
validate: (input) => {
|
|
32
|
-
if (!input)
|
|
33
|
-
return "API key is required";
|
|
34
|
-
return true;
|
|
35
|
-
},
|
|
36
|
-
},
|
|
37
|
-
]);
|
|
38
|
-
return apiKeyAnswer.apiKey;
|
|
39
|
-
};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import inquirer from "inquirer";
|
|
2
|
-
/**
|
|
3
|
-
* Show a list of models to select from
|
|
4
|
-
*/
|
|
5
|
-
export const selectModel = async (models, existingModel) => {
|
|
6
|
-
const modelChoices = models.map((model) => ({
|
|
7
|
-
name: model.name
|
|
8
|
-
? `${model.name} (Context: ${model.context_length})`
|
|
9
|
-
: model.id,
|
|
10
|
-
value: model.id,
|
|
11
|
-
}));
|
|
12
|
-
modelChoices.push({
|
|
13
|
-
name: "Other (specify model identifier)",
|
|
14
|
-
value: "custom",
|
|
15
|
-
});
|
|
16
|
-
const answers = await inquirer.prompt([
|
|
17
|
-
{
|
|
18
|
-
type: "list",
|
|
19
|
-
name: "modelChoice",
|
|
20
|
-
message: "Select an AI model:",
|
|
21
|
-
choices: modelChoices,
|
|
22
|
-
default: () => {
|
|
23
|
-
const currentIndex = modelChoices.findIndex((choice) => choice.value === existingModel);
|
|
24
|
-
return currentIndex >= 0 ? currentIndex : 0;
|
|
25
|
-
},
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
type: "input",
|
|
29
|
-
name: "customModel",
|
|
30
|
-
message: "Enter model identifier:",
|
|
31
|
-
when: (answers) => answers.modelChoice === "custom",
|
|
32
|
-
validate: (input) => input ? true : "Model identifier is required",
|
|
33
|
-
},
|
|
34
|
-
]);
|
|
35
|
-
return answers.modelChoice === "custom"
|
|
36
|
-
? answers.customModel
|
|
37
|
-
: answers.modelChoice;
|
|
38
|
-
};
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import inquirer from "inquirer";
|
|
3
|
-
import { saveConfig } from "../../../config.js";
|
|
4
|
-
import { getAvailableModels } from "./getAvailableModels.js";
|
|
5
|
-
import { selectModel } from "./selectModel.js";
|
|
6
|
-
/**
|
|
7
|
-
* Set up a local LLM configuration
|
|
8
|
-
*/
|
|
9
|
-
export const setupLocalLLM = async (existingConfig) => {
|
|
10
|
-
console.log(chalk.blue("Local LLM Setup"));
|
|
11
|
-
const endpointAnswer = await inquirer.prompt([
|
|
12
|
-
{
|
|
13
|
-
type: "input",
|
|
14
|
-
name: "localLLMEndpoint",
|
|
15
|
-
message: "Enter local LLM API endpoint (e.g., http://127.0.0.1:1234):",
|
|
16
|
-
default: existingConfig.customLLMEndpoint || "http://127.0.0.1:1234",
|
|
17
|
-
validate: (input) => {
|
|
18
|
-
if (!input)
|
|
19
|
-
return "API endpoint is required";
|
|
20
|
-
if (!input.startsWith("http://") && !input.startsWith("https://")) {
|
|
21
|
-
return "Must be a valid URL starting with http:// or https://";
|
|
22
|
-
}
|
|
23
|
-
return true;
|
|
24
|
-
},
|
|
25
|
-
},
|
|
26
|
-
]);
|
|
27
|
-
console.log(chalk.gray("Trying to fetch available models from local LLM server..."));
|
|
28
|
-
const models = await getAvailableModels({
|
|
29
|
-
baseURLOverride: endpointAnswer.localLLMEndpoint,
|
|
30
|
-
});
|
|
31
|
-
let selectedModel;
|
|
32
|
-
if (models.length > 0) {
|
|
33
|
-
console.log(chalk.green(`✓ Found ${models.length} models available on your local LLM server`));
|
|
34
|
-
selectedModel = await selectModel(models, existingConfig.model);
|
|
35
|
-
}
|
|
36
|
-
else {
|
|
37
|
-
console.log(chalk.yellow("Could not fetch models from local LLM server, please enter model name manually"));
|
|
38
|
-
const modelAnswer = await inquirer.prompt([
|
|
39
|
-
{
|
|
40
|
-
type: "input",
|
|
41
|
-
name: "model",
|
|
42
|
-
message: "Enter model name to use with local endpoint:",
|
|
43
|
-
default: existingConfig.model,
|
|
44
|
-
validate: (input) => (input ? true : "Model name is required"),
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
selectedModel = modelAnswer.model;
|
|
48
|
-
}
|
|
49
|
-
const updatedConfig = {
|
|
50
|
-
...existingConfig,
|
|
51
|
-
provider: "local",
|
|
52
|
-
model: selectedModel,
|
|
53
|
-
customLLMEndpoint: endpointAnswer.localLLMEndpoint,
|
|
54
|
-
};
|
|
55
|
-
// Save the config
|
|
56
|
-
saveConfig(updatedConfig);
|
|
57
|
-
console.log(chalk.green("✓ Local LLM configuration saved"));
|
|
58
|
-
console.log(chalk.gray("Testing connection to local LLM..."));
|
|
59
|
-
return updatedConfig;
|
|
60
|
-
};
|