gitpt 1.6.1 → 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 -167
- package/dist/commands/commit/commitFlags.js +7 -0
- package/dist/commands/commit/context/buildPrompt.js +13 -10
- package/dist/commands/commit/context/summaryPrompt.js +5 -2
- package/dist/commands/commit/context/systemPrompt.js +4 -1
- package/dist/commands/commit/context/userPrompt.js +4 -1
- package/dist/commands/commit/generateCommitMessage.js +14 -17
- package/dist/commands/commit/index.js +186 -179
- package/dist/commands/commit/summarizeDiff.js +183 -162
- 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 +14 -10
- package/dist/commands/middleware/setupMiddleware/index.js +65 -71
- 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 +24 -23
- package/dist/commands/pr/getPRContext.js +37 -62
- package/dist/commands/pr/index.js +57 -62
- package/dist/commands/reset.js +23 -23
- package/dist/commands/review/index.js +31 -0
- package/dist/commands/setup.js +38 -13
- package/dist/config.js +63 -60
- package/dist/index.js +30 -67
- package/dist/llm/budget.js +10 -0
- package/dist/llm/index.js +12 -7
- package/dist/llm/providers/anthropic/index.js +30 -30
- package/dist/llm/providers/apiKey.js +36 -35
- package/dist/llm/providers/apple/client.js +73 -83
- package/dist/llm/providers/apple/index.js +64 -72
- package/dist/llm/providers/apple/models.js +27 -19
- package/dist/llm/providers/base.js +36 -36
- package/dist/llm/providers/local/index.js +79 -91
- package/dist/llm/providers/openai/index.js +19 -16
- package/dist/llm/providers/openaiCompatible.js +59 -62
- package/dist/llm/providers/openrouter/index.js +18 -15
- package/dist/llm/registry.js +30 -34
- package/dist/llm/setup/getAvailableModels.js +15 -9
- package/dist/llm/setup/selectModel.js +36 -44
- package/dist/llm/tokenCount.js +4 -3
- 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 +14 -4
- package/dist/commands/commit/context/buildPrompt.d.ts +0 -4
- package/dist/commands/commit/context/summaryPrompt.d.ts +0 -2
- 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/commit/summarizeDiff.d.ts +0 -1
- 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/defaultModels.d.ts +0 -8
- package/dist/commands/middleware/setupMiddleware/index.d.ts +0 -4
- 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/reset.d.ts +0 -3
- package/dist/commands/setup.d.ts +0 -3
- package/dist/config.d.ts +0 -14
- package/dist/index.d.ts +0 -2
- package/dist/llm/client.d.ts +0 -24
- package/dist/llm/client.js +0 -1
- package/dist/llm/index.d.ts +0 -6
- package/dist/llm/providers/anthropic/index.d.ts +0 -9
- package/dist/llm/providers/apiKey.d.ts +0 -3
- package/dist/llm/providers/apple/client.d.ts +0 -3
- package/dist/llm/providers/apple/index.d.ts +0 -13
- package/dist/llm/providers/apple/models.d.ts +0 -14
- package/dist/llm/providers/base.d.ts +0 -30
- package/dist/llm/providers/local/index.d.ts +0 -11
- package/dist/llm/providers/openai/index.d.ts +0 -10
- package/dist/llm/providers/openaiCompatible.d.ts +0 -15
- package/dist/llm/providers/openrouter/index.d.ts +0 -9
- package/dist/llm/registry.d.ts +0 -8
- package/dist/llm/setup/getAvailableModels.d.ts +0 -5
- package/dist/llm/setup/selectModel.d.ts +0 -5
- package/dist/llm/setup/types.d.ts +0 -13
- package/dist/llm/setup/types.js +0 -1
- package/dist/llm/tokenCount.d.ts +0 -3
- 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,74 +1,68 @@
|
|
|
1
|
+
import { clearAcceptedDefault, getAcceptedDefault, getConfig, saveConfig, setAcceptedDefault, unsetConfigKey } from "../../../config.js";
|
|
2
|
+
import { PROVIDERS, getProviderClass, validateConfig } from "../../../llm/registry.js";
|
|
3
|
+
import { resolveDefaultModel } from "./defaultModels.js";
|
|
1
4
|
import chalk from "chalk";
|
|
2
5
|
import inquirer from "inquirer";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
message: "Select LLM provider:",
|
|
64
|
-
choices: providerChoices,
|
|
65
|
-
default: Math.max(providerChoices.findIndex((c) => c.value === existingConfig.provider), 0),
|
|
66
|
-
},
|
|
67
|
-
]);
|
|
68
|
-
existingConfig.provider = providerAnswer.provider;
|
|
69
|
-
const spec = getProviderClass(existingConfig.provider);
|
|
70
|
-
if (!spec) {
|
|
71
|
-
throw new Error(`Unknown provider: ${existingConfig.provider ?? "(none)"}.`);
|
|
72
|
-
}
|
|
73
|
-
return spec.setup(existingConfig);
|
|
6
|
+
//#region src/commands/middleware/setupMiddleware/index.ts
|
|
7
|
+
var setupMiddleware = async (options) => {
|
|
8
|
+
const context = options?.context || "command";
|
|
9
|
+
const existingConfig = getConfig();
|
|
10
|
+
const defaultModel = resolveDefaultModel();
|
|
11
|
+
const acceptedDefault = getAcceptedDefault();
|
|
12
|
+
const interactive = Boolean(process.stdin.isTTY);
|
|
13
|
+
const applyDefault = (model) => {
|
|
14
|
+
saveConfig(model.config);
|
|
15
|
+
setAcceptedDefault(model.id);
|
|
16
|
+
return getConfig();
|
|
17
|
+
};
|
|
18
|
+
const confirmDefault = async (message) => {
|
|
19
|
+
const { useDefault } = await inquirer.prompt([{
|
|
20
|
+
type: "confirm",
|
|
21
|
+
name: "useDefault",
|
|
22
|
+
message,
|
|
23
|
+
default: true
|
|
24
|
+
}]);
|
|
25
|
+
return useDefault;
|
|
26
|
+
};
|
|
27
|
+
if (context === "command") {
|
|
28
|
+
if (validateConfig().isValid) {
|
|
29
|
+
if (!acceptedDefault) return getConfig();
|
|
30
|
+
if (!defaultModel || defaultModel.id === acceptedDefault) return getConfig();
|
|
31
|
+
if (!interactive || await confirmDefault(`The recommended default changed to ${defaultModel.label}. Use it?`)) {
|
|
32
|
+
const result = applyDefault(defaultModel);
|
|
33
|
+
if (interactive) console.log(chalk.green(`✓ Now using ${defaultModel.label}.`));
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
return getConfig();
|
|
37
|
+
}
|
|
38
|
+
if (!existingConfig.provider && defaultModel) {
|
|
39
|
+
if (!interactive) return applyDefault(defaultModel);
|
|
40
|
+
if (await confirmDefault(`No model configured. Use ${defaultModel.label} by default?`)) {
|
|
41
|
+
const result = applyDefault(defaultModel);
|
|
42
|
+
console.log(chalk.green(`✓ Using ${defaultModel.label}. Run 'gitpt model' to change.`));
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
} else if (!interactive) throw new Error("GitPT is not configured. Run 'gitpt setup' in an interactive terminal.");
|
|
46
|
+
}
|
|
47
|
+
clearAcceptedDefault();
|
|
48
|
+
const providerChoices = PROVIDERS.filter((p) => p.isAvailable()).map((p) => ({
|
|
49
|
+
name: p.label,
|
|
50
|
+
value: p.id
|
|
51
|
+
}));
|
|
52
|
+
existingConfig.provider = (await inquirer.prompt([{
|
|
53
|
+
type: "list",
|
|
54
|
+
name: "provider",
|
|
55
|
+
message: "Select LLM provider:",
|
|
56
|
+
choices: providerChoices,
|
|
57
|
+
default: Math.max(providerChoices.findIndex((c) => c.value === existingConfig.provider), 0)
|
|
58
|
+
}])).provider;
|
|
59
|
+
if (existingConfig.provider !== "local") {
|
|
60
|
+
delete existingConfig.contextWindow;
|
|
61
|
+
unsetConfigKey("contextWindow");
|
|
62
|
+
}
|
|
63
|
+
const spec = getProviderClass(existingConfig.provider);
|
|
64
|
+
if (!spec) throw new Error(`Unknown provider: ${existingConfig.provider ?? "(none)"}.`);
|
|
65
|
+
return spec.setup(existingConfig);
|
|
74
66
|
};
|
|
67
|
+
//#endregion
|
|
68
|
+
export { setupMiddleware };
|
package/dist/commands/model.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
1
|
import { setupMiddleware } from "./middleware/setupMiddleware/index.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
//#region src/commands/model.ts
|
|
4
|
+
var modelCommand = async () => {
|
|
5
|
+
console.log(chalk.blue("GitPT Model Selection"));
|
|
6
|
+
await setupMiddleware({ context: "model" });
|
|
6
7
|
};
|
|
8
|
+
//#endregion
|
|
9
|
+
export { modelCommand };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/commands/passthroughArgs.ts
|
|
2
|
+
/**
|
|
3
|
+
* Extra tokens the user passed to a GitPT command that aren't GitPT's own
|
|
4
|
+
* options (e.g. --allow-empty, --amend) — to forward to the wrapped git command.
|
|
5
|
+
* Commander leaves these in `command.args`; we drop the command's own name in
|
|
6
|
+
* case it leaks in. Shared so every command forwards passthrough flags the same
|
|
7
|
+
* way.
|
|
8
|
+
*/
|
|
9
|
+
var passthroughArgs = (command) => (command.args ?? []).filter((arg) => arg !== command.name());
|
|
10
|
+
//#endregion
|
|
11
|
+
export { passthroughArgs };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/commands/pr/context/systemPrompt.ts
|
|
2
|
+
var systemPrompt = `
|
|
2
3
|
You are a helpful assistant that generates clear, informative GitHub pull request titles and descriptions.
|
|
3
4
|
|
|
4
5
|
For the title:
|
|
@@ -16,3 +17,5 @@ For the description:
|
|
|
16
17
|
Format the description in Markdown with sections.
|
|
17
18
|
Do not include "PR" or "Pull Request" in the title.
|
|
18
19
|
`;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { systemPrompt };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
//#region src/commands/pr/context/userPrompt.ts
|
|
2
|
+
var userPrompt = (context) => `
|
|
2
3
|
Generate a pull request title and description for the following changes:
|
|
3
4
|
|
|
4
5
|
${context}
|
|
@@ -20,3 +21,5 @@ This PR adds user authentication using JWT tokens.
|
|
|
20
21
|
2. Login with the new user credentials
|
|
21
22
|
3. Use the returned token to access protected endpoints
|
|
22
23
|
`;
|
|
24
|
+
//#endregion
|
|
25
|
+
export { userPrompt };
|
|
@@ -1,28 +1,29 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
1
|
import { getProvider } from "../../llm/registry.js";
|
|
3
2
|
import { systemPrompt } from "./context/systemPrompt.js";
|
|
4
3
|
import { userPrompt } from "./context/userPrompt.js";
|
|
5
4
|
import { getPRContext } from "./getPRContext.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
//#region src/commands/pr/generatePRDetails.ts
|
|
7
|
+
var generatePRDetails = async () => {
|
|
8
|
+
const context = getPRContext().join("\n\n");
|
|
9
|
+
try {
|
|
10
|
+
const provider = getProvider();
|
|
11
|
+
const result = (await provider.complete({
|
|
12
|
+
system: systemPrompt,
|
|
13
|
+
user: userPrompt(context),
|
|
14
|
+
maxTokens: provider.maxOutputTokens
|
|
15
|
+
})).trim();
|
|
16
|
+
if (!result) throw new Error("No response from LLM");
|
|
17
|
+
const titleMatch = result.match(/Title:\s*(.+?)(?:\n|$)/);
|
|
18
|
+
const descMatch = result.match(/Description:\s*\n([\s\S]+)$/);
|
|
19
|
+
return {
|
|
20
|
+
title: titleMatch ? titleMatch[1].trim() : "",
|
|
21
|
+
body: descMatch ? descMatch[1].trim() : result
|
|
22
|
+
};
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(chalk.red("Error generating PR details:"), error);
|
|
25
|
+
throw new Error("Failed to generate PR details");
|
|
26
|
+
}
|
|
28
27
|
};
|
|
28
|
+
//#endregion
|
|
29
|
+
export { generatePRDetails };
|
|
@@ -1,65 +1,40 @@
|
|
|
1
|
+
import { git } from "../../services/git/index.js";
|
|
1
2
|
import chalk from "chalk";
|
|
2
3
|
import { execSync } from "child_process";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (repoDescription) {
|
|
38
|
-
contextSections.push(`Repository description: ${repoDescription}`);
|
|
39
|
-
}
|
|
40
|
-
// Add commit messages if available
|
|
41
|
-
if (commitMessages.length > 0) {
|
|
42
|
-
contextSections.push("Commit messages in this branch:", commitMessages.map((msg) => `- ${msg}`).join("\n"));
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
contextSections.push("No commit messages available.");
|
|
46
|
-
// Try to extract intent from branch name if no commits
|
|
47
|
-
if (currentBranch.includes("/")) {
|
|
48
|
-
const branchParts = currentBranch.split("/");
|
|
49
|
-
const branchType = branchParts[0]; // e.g., "feature", "fix", "chore"
|
|
50
|
-
const branchDescription = branchParts
|
|
51
|
-
.slice(1)
|
|
52
|
-
.join("/")
|
|
53
|
-
.replace(/-/g, " ");
|
|
54
|
-
contextSections.push("Branch name analysis:", `Type: ${branchType}`, `Description: ${branchDescription}`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// Add changed files if available
|
|
58
|
-
if (changedFiles.length > 0) {
|
|
59
|
-
contextSections.push("Files changed in this branch:", changedFiles.map((file) => `- ${file}`).join("\n"));
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
contextSections.push("No file changes detected.");
|
|
63
|
-
}
|
|
64
|
-
return contextSections;
|
|
4
|
+
//#region src/commands/pr/getPRContext.ts
|
|
5
|
+
var getPRContext = () => {
|
|
6
|
+
const currentBranch = git.getCurrentBranch();
|
|
7
|
+
const baseBranch = git.getDefaultBranch();
|
|
8
|
+
const commitMessages = git.getCommitsSinceBaseBranch(baseBranch);
|
|
9
|
+
const changedFiles = git.getChangedFiles(baseBranch);
|
|
10
|
+
if (commitMessages.length === 0 && changedFiles.length === 0) {
|
|
11
|
+
console.log(chalk.yellow("No commits or changed files detected."));
|
|
12
|
+
console.log(chalk.yellow("Will attempt to generate PR details using branch name and repository context."));
|
|
13
|
+
}
|
|
14
|
+
let repoName = "";
|
|
15
|
+
let repoDescription = "";
|
|
16
|
+
try {
|
|
17
|
+
const repoInfo = JSON.parse(execSync("gh repo view --json name,description").toString().trim());
|
|
18
|
+
repoName = repoInfo.name || "";
|
|
19
|
+
repoDescription = repoInfo.description || "";
|
|
20
|
+
} catch (error) {}
|
|
21
|
+
console.log(chalk.blue("Generating PR title and description..."));
|
|
22
|
+
let contextSections = [`Branch: ${currentBranch}`, `Base branch: ${baseBranch}`];
|
|
23
|
+
if (repoName) contextSections.push(`Repository: ${repoName}`);
|
|
24
|
+
if (repoDescription) contextSections.push(`Repository description: ${repoDescription}`);
|
|
25
|
+
if (commitMessages.length > 0) contextSections.push("Commit messages in this branch:", commitMessages.map((msg) => `- ${msg}`).join("\n"));
|
|
26
|
+
else {
|
|
27
|
+
contextSections.push("No commit messages available.");
|
|
28
|
+
if (currentBranch.includes("/")) {
|
|
29
|
+
const branchParts = currentBranch.split("/");
|
|
30
|
+
const branchType = branchParts[0];
|
|
31
|
+
const branchDescription = branchParts.slice(1).join("/").replace(/-/g, " ");
|
|
32
|
+
contextSections.push("Branch name analysis:", `Type: ${branchType}`, `Description: ${branchDescription}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (changedFiles.length > 0) contextSections.push("Files changed in this branch:", changedFiles.map((file) => `- ${file}`).join("\n"));
|
|
36
|
+
else contextSections.push("No file changes detected.");
|
|
37
|
+
return contextSections;
|
|
65
38
|
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { getPRContext };
|
|
@@ -1,66 +1,61 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import inquirer from "inquirer";
|
|
3
|
-
import { capabilitiesMiddleware } from "../middleware/capabilitiesMiddleware/index.js";
|
|
4
|
-
import { setupMiddleware } from "../middleware/setupMiddleware/index.js";
|
|
5
1
|
import { gh } from "../../services/gh/index.js";
|
|
6
2
|
import { git } from "../../services/git/index.js";
|
|
3
|
+
import { capabilitiesMiddleware } from "../middleware/capabilitiesMiddleware/index.js";
|
|
4
|
+
import { setupMiddleware } from "../middleware/setupMiddleware/index.js";
|
|
7
5
|
import { generatePRDetails } from "./generatePRDetails.js";
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
64
|
-
process.exit(1);
|
|
65
|
-
}
|
|
6
|
+
import chalk from "chalk";
|
|
7
|
+
import inquirer from "inquirer";
|
|
8
|
+
//#region src/commands/pr/index.ts
|
|
9
|
+
var prCreateCommand = async (options = {}) => {
|
|
10
|
+
capabilitiesMiddleware(["git", "gh"]);
|
|
11
|
+
await setupMiddleware();
|
|
12
|
+
try {
|
|
13
|
+
const baseBranch = options.base || git.getDefaultBranch();
|
|
14
|
+
let title = options.title || "";
|
|
15
|
+
let body = options.body || "";
|
|
16
|
+
if (!title || !body) {
|
|
17
|
+
const generatedDetails = await generatePRDetails();
|
|
18
|
+
title = title || generatedDetails.title;
|
|
19
|
+
body = body || generatedDetails.body;
|
|
20
|
+
console.log(chalk.green("✓ PR details generated"));
|
|
21
|
+
console.log("");
|
|
22
|
+
console.log(chalk.cyan("Title:"));
|
|
23
|
+
console.log(title);
|
|
24
|
+
console.log("");
|
|
25
|
+
console.log(chalk.cyan("Description:"));
|
|
26
|
+
console.log(body);
|
|
27
|
+
console.log("");
|
|
28
|
+
}
|
|
29
|
+
if (options.edit !== false) {
|
|
30
|
+
const answers = await inquirer.prompt([
|
|
31
|
+
{
|
|
32
|
+
type: "input",
|
|
33
|
+
name: "title",
|
|
34
|
+
message: "Edit PR title:",
|
|
35
|
+
default: title
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "editor",
|
|
39
|
+
name: "body",
|
|
40
|
+
message: "Edit PR description:",
|
|
41
|
+
default: body
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
type: "confirm",
|
|
45
|
+
name: "draft",
|
|
46
|
+
message: "Create as draft PR?",
|
|
47
|
+
default: options.draft || false
|
|
48
|
+
}
|
|
49
|
+
]);
|
|
50
|
+
title = answers.title;
|
|
51
|
+
body = answers.body;
|
|
52
|
+
const isDraft = answers.draft;
|
|
53
|
+
gh.createPullRequest(title, body, baseBranch, isDraft);
|
|
54
|
+
} else gh.createPullRequest(title, body, baseBranch, options.draft || false);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error(chalk.red("Error:"), error instanceof Error ? error.message : String(error));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
66
59
|
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { prCreateCommand };
|
package/dist/commands/reset.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
+
import { clearConfig, getConfig } from "../config.js";
|
|
1
2
|
import chalk from "chalk";
|
|
2
3
|
import inquirer from "inquirer";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
clearConfig();
|
|
25
|
-
console.log(chalk.green("✓ GitPT configuration reset. Run 'gitpt setup' to reconfigure."));
|
|
4
|
+
//#region src/commands/reset.ts
|
|
5
|
+
var resetCommand = async (options = {}) => {
|
|
6
|
+
if (!Object.values(getConfig()).some((value) => value !== void 0)) {
|
|
7
|
+
console.log(chalk.gray("GitPT has no saved configuration to reset."));
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
if (!options.yes) {
|
|
11
|
+
const { confirm } = await inquirer.prompt([{
|
|
12
|
+
type: "confirm",
|
|
13
|
+
name: "confirm",
|
|
14
|
+
message: "Reset GitPT? This clears the saved provider, model, and API key.",
|
|
15
|
+
default: false
|
|
16
|
+
}]);
|
|
17
|
+
if (!confirm) {
|
|
18
|
+
console.log(chalk.gray("Reset cancelled."));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
clearConfig();
|
|
23
|
+
console.log(chalk.green("✓ GitPT configuration reset. Run 'gitpt setup' to reconfigure."));
|
|
26
24
|
};
|
|
25
|
+
//#endregion
|
|
26
|
+
export { resetCommand };
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { git } from "../../services/git/index.js";
|
|
2
|
+
import { capabilitiesMiddleware } from "../middleware/capabilitiesMiddleware/index.js";
|
|
3
|
+
import { getProvider } from "../../llm/registry.js";
|
|
4
|
+
import { setupMiddleware } from "../middleware/setupMiddleware/index.js";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
//#region src/commands/review/index.ts
|
|
7
|
+
var REVIEW_SYSTEM = `You are a concise senior code reviewer. You are given a git diff of staged changes.
|
|
8
|
+
Respond with:
|
|
9
|
+
- one short sentence summarising what changed,
|
|
10
|
+
- then up to 5 brief bullet points flagging real risks, likely bugs, or concrete suggestions (drop a bullet if there's nothing worth saying).
|
|
11
|
+
Be specific. Skip praise and preamble.`;
|
|
12
|
+
var reviewCommand = async () => {
|
|
13
|
+
capabilitiesMiddleware(["git"]);
|
|
14
|
+
await setupMiddleware();
|
|
15
|
+
const diff = git.getStagedChanges();
|
|
16
|
+
if (!diff || !diff.trim()) {
|
|
17
|
+
console.log(chalk.yellow("No staged changes to review. Stage some with `git add` first."));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
console.log(chalk.blue("Reviewing staged changes..."));
|
|
21
|
+
const provider = getProvider();
|
|
22
|
+
const review = await provider.complete({
|
|
23
|
+
system: REVIEW_SYSTEM,
|
|
24
|
+
user: diff,
|
|
25
|
+
maxTokens: provider.maxOutputTokens
|
|
26
|
+
});
|
|
27
|
+
console.log("");
|
|
28
|
+
console.log(review.trim());
|
|
29
|
+
};
|
|
30
|
+
//#endregion
|
|
31
|
+
export { reviewCommand };
|
package/dist/commands/setup.js
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { clearConfig, saveConfig } from "../config.js";
|
|
2
|
+
import { getApiKey, saveApiKey } from "../llm/providers/apiKey.js";
|
|
3
|
+
import { getProviderClass } from "../llm/registry.js";
|
|
3
4
|
import { setupMiddleware } from "./middleware/setupMiddleware/index.js";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
//#region src/commands/setup.ts
|
|
7
|
+
var fail = (message) => {
|
|
8
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
9
|
+
process.exit(1);
|
|
10
|
+
};
|
|
11
|
+
var headlessSetup = (options) => {
|
|
12
|
+
const spec = getProviderClass(options.provider);
|
|
13
|
+
if (!spec) return fail(`Unknown provider "${options.provider}". Valid: local, openrouter, openai, anthropic, apple.`);
|
|
14
|
+
if (!options.model) fail("--model is required.");
|
|
15
|
+
if (spec.requiresEndpoint && !options.endpoint) fail(`Provider "${spec.id}" requires --endpoint.`);
|
|
16
|
+
if (spec.requiresApiKey && !options.apiKey && !getApiKey()) fail(`Provider "${spec.id}" requires --api-key.`);
|
|
17
|
+
const config = {
|
|
18
|
+
provider: spec.id,
|
|
19
|
+
model: options.model
|
|
20
|
+
};
|
|
21
|
+
if (options.endpoint) config.customLLMEndpoint = options.endpoint;
|
|
22
|
+
saveConfig(config);
|
|
23
|
+
if (options.apiKey) saveApiKey(spec.id, options.apiKey);
|
|
24
|
+
console.log(chalk.green(`✓ Configured ${spec.label} with model ${options.model}.`));
|
|
25
|
+
};
|
|
26
|
+
var setupCommand = async (options = {}) => {
|
|
27
|
+
if (options.provider) {
|
|
28
|
+
headlessSetup(options);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log(chalk.blue("GitPT Setup"));
|
|
32
|
+
console.log("This will configure GitPT to use an LLM for generating commit messages.");
|
|
33
|
+
console.log("");
|
|
34
|
+
if (options.clearConfig) clearConfig();
|
|
35
|
+
await setupMiddleware({ context: "setup" });
|
|
36
|
+
console.log("");
|
|
37
|
+
console.log(`Use ${chalk.cyan("gitpt commit")} to create commits with AI-generated messages.`);
|
|
15
38
|
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { setupCommand };
|