gitpt 1.4.0 → 1.6.1
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 +7 -0
- package/dist/commands/commit/context/buildPrompt.d.ts +4 -0
- package/dist/commands/commit/context/buildPrompt.js +13 -0
- package/dist/commands/commit/context/summaryPrompt.d.ts +2 -0
- package/dist/commands/commit/context/summaryPrompt.js +17 -0
- package/dist/commands/commit/generateCommitMessage.js +8 -26
- package/dist/commands/commit/index.js +4 -2
- package/dist/commands/commit/summarizeDiff.d.ts +1 -0
- package/dist/commands/commit/summarizeDiff.js +172 -0
- package/dist/commands/middleware/setupMiddleware/defaultModels.d.ts +8 -0
- package/dist/commands/middleware/setupMiddleware/defaultModels.js +11 -0
- package/dist/commands/middleware/setupMiddleware/index.js +58 -24
- package/dist/commands/pr/generatePRDetails.js +7 -14
- package/dist/commands/reset.d.ts +3 -0
- package/dist/commands/reset.js +26 -0
- package/dist/config.d.ts +6 -10
- package/dist/config.js +25 -20
- package/dist/index.js +6 -0
- package/dist/llm/client.d.ts +24 -0
- package/dist/llm/index.d.ts +3 -2
- package/dist/llm/index.js +4 -9
- package/dist/llm/providers/anthropic/index.d.ts +9 -0
- package/dist/llm/providers/anthropic/index.js +31 -0
- package/dist/llm/providers/apiKey.d.ts +3 -0
- package/dist/llm/providers/apiKey.js +40 -0
- package/dist/llm/providers/apple/client.d.ts +3 -0
- package/dist/llm/providers/apple/client.js +87 -0
- package/dist/llm/providers/apple/index.d.ts +13 -0
- package/dist/llm/providers/apple/index.js +77 -0
- package/dist/llm/providers/apple/models.d.ts +14 -0
- package/dist/llm/providers/apple/models.js +21 -0
- package/dist/llm/providers/base.d.ts +30 -0
- package/dist/llm/providers/base.js +36 -0
- package/dist/llm/providers/local/index.d.ts +11 -0
- package/dist/llm/providers/local/index.js +96 -0
- package/dist/llm/providers/openai/index.d.ts +10 -0
- package/dist/llm/providers/openai/index.js +16 -0
- package/dist/llm/providers/openaiCompatible.d.ts +15 -0
- package/dist/llm/providers/openaiCompatible.js +69 -0
- package/dist/llm/providers/openrouter/index.d.ts +9 -0
- package/dist/llm/providers/openrouter/index.js +16 -0
- package/dist/llm/registry.d.ts +8 -0
- package/dist/llm/registry.js +43 -0
- package/dist/{commands/middleware/setupMiddleware → llm/setup}/getAvailableModels.d.ts +1 -0
- package/dist/{commands/middleware/setupMiddleware → llm/setup}/getAvailableModels.js +3 -3
- package/dist/{commands/middleware/setupMiddleware → llm/setup}/selectModel.d.ts +1 -1
- package/dist/{commands/middleware/setupMiddleware → llm/setup}/selectModel.js +13 -3
- package/dist/llm/setup/types.js +1 -0
- package/dist/llm/tokenCount.d.ts +3 -0
- package/dist/llm/tokenCount.js +4 -0
- package/dist/services/git/getStagedChanges.js +1 -1
- package/package.json +6 -2
- package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.d.ts +0 -1
- package/dist/commands/middleware/setupMiddleware/getOrUpdateApiKey.js +0 -39
- 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.js → llm/client.js} +0 -0
- /package/dist/{commands/middleware/setupMiddleware → llm/setup}/types.d.ts +0 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { getConfig } from "../config.js";
|
|
2
|
+
import { AnthropicProvider } from "./providers/anthropic/index.js";
|
|
3
|
+
import { getApiKey } from "./providers/apiKey.js";
|
|
4
|
+
import { AppleProvider } from "./providers/apple/index.js";
|
|
5
|
+
import { LocalProvider } from "./providers/local/index.js";
|
|
6
|
+
import { OpenAIProvider } from "./providers/openai/index.js";
|
|
7
|
+
import { OpenRouterProvider } from "./providers/openrouter/index.js";
|
|
8
|
+
export const PROVIDERS = [
|
|
9
|
+
AppleProvider,
|
|
10
|
+
OpenRouterProvider,
|
|
11
|
+
OpenAIProvider,
|
|
12
|
+
AnthropicProvider,
|
|
13
|
+
LocalProvider,
|
|
14
|
+
];
|
|
15
|
+
export const getProviderClass = (id) => PROVIDERS.find((p) => p.id === id);
|
|
16
|
+
export const getProvider = () => {
|
|
17
|
+
const { provider, model } = getConfig();
|
|
18
|
+
const ProviderImpl = getProviderClass(provider);
|
|
19
|
+
if (!ProviderImpl) {
|
|
20
|
+
throw new Error(`Unknown provider: ${provider ?? "(none)"}. Run "gitpt setup".`);
|
|
21
|
+
}
|
|
22
|
+
return new ProviderImpl(model ?? "");
|
|
23
|
+
};
|
|
24
|
+
export const validateConfig = () => {
|
|
25
|
+
const { provider, customLLMEndpoint, model } = getConfig();
|
|
26
|
+
const errors = [];
|
|
27
|
+
const spec = getProviderClass(provider);
|
|
28
|
+
if (!spec) {
|
|
29
|
+
errors.push("No provider configured. Run 'gitpt setup'.");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
if (spec.requiresApiKey && !getApiKey()) {
|
|
33
|
+
errors.push(`API key is required for ${spec.label}.`);
|
|
34
|
+
}
|
|
35
|
+
if (spec.requiresEndpoint && !customLLMEndpoint) {
|
|
36
|
+
errors.push(`Custom endpoint is required for ${spec.label}.`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (!model) {
|
|
40
|
+
errors.push("Model is required.");
|
|
41
|
+
}
|
|
42
|
+
return { isValid: errors.length === 0, errors };
|
|
43
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { getLLMClient } from "
|
|
1
|
+
import { getLLMClient } from "../index.js";
|
|
2
2
|
export const getAvailableModels = async (options) => {
|
|
3
|
-
const { baseURLOverride } = options || {};
|
|
4
|
-
let modelsList = await getLLMClient({ baseURLOverride }).models.list();
|
|
3
|
+
const { baseURLOverride, apiKey } = options || {};
|
|
4
|
+
let modelsList = await getLLMClient({ baseURLOverride, apiKey }).models.list();
|
|
5
5
|
const modelsData = modelsList.data;
|
|
6
6
|
while (modelsList.hasNextPage()) {
|
|
7
7
|
modelsList = await modelsList.getNextPage();
|
|
@@ -2,4 +2,4 @@ import { Model } from "./types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Show a list of models to select from
|
|
4
4
|
*/
|
|
5
|
-
export declare const selectModel: (models: Model[], existingModel?: string) => Promise<string>;
|
|
5
|
+
export declare const selectModel: (models: Model[], existingModel?: string, notes?: string[]) => Promise<string>;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
import chalk from "chalk";
|
|
1
2
|
import inquirer from "inquirer";
|
|
2
3
|
/**
|
|
3
4
|
* Show a list of models to select from
|
|
4
5
|
*/
|
|
5
|
-
export const selectModel = async (models, existingModel) => {
|
|
6
|
+
export const selectModel = async (models, existingModel, notes) => {
|
|
6
7
|
const modelChoices = models.map((model) => ({
|
|
7
8
|
name: model.name
|
|
8
|
-
?
|
|
9
|
+
? model.context_length
|
|
10
|
+
? `${model.name} (Context: ${model.context_length})`
|
|
11
|
+
: model.name
|
|
9
12
|
: model.id,
|
|
10
13
|
value: model.id,
|
|
11
14
|
}));
|
|
@@ -13,12 +16,19 @@ export const selectModel = async (models, existingModel) => {
|
|
|
13
16
|
name: "Other (specify model identifier)",
|
|
14
17
|
value: "custom",
|
|
15
18
|
});
|
|
19
|
+
const choices = [...modelChoices];
|
|
20
|
+
if (notes && notes.length > 0) {
|
|
21
|
+
choices.push(new inquirer.Separator(" "));
|
|
22
|
+
for (const note of notes) {
|
|
23
|
+
choices.push(new inquirer.Separator(chalk.gray(note)));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
16
26
|
const answers = await inquirer.prompt([
|
|
17
27
|
{
|
|
18
28
|
type: "list",
|
|
19
29
|
name: "modelChoice",
|
|
20
30
|
message: "Select an AI model:",
|
|
21
|
-
choices
|
|
31
|
+
choices,
|
|
22
32
|
default: () => {
|
|
23
33
|
const currentIndex = modelChoices.findIndex((choice) => choice.value === existingModel);
|
|
24
34
|
return currentIndex >= 0 ? currentIndex : 0;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,7 +2,7 @@ import chalk from "chalk";
|
|
|
2
2
|
import { execSync } from "child_process";
|
|
3
3
|
export const getStagedChanges = () => {
|
|
4
4
|
try {
|
|
5
|
-
return execSync("git diff --staged").toString();
|
|
5
|
+
return execSync("git diff --staged --function-context").toString();
|
|
6
6
|
}
|
|
7
7
|
catch (error) {
|
|
8
8
|
console.error(chalk.red("Error getting staged changes:"), error);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitpt",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.1",
|
|
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",
|
|
@@ -16,6 +16,9 @@
|
|
|
16
16
|
"typecheck": "tsc --noEmit",
|
|
17
17
|
"build": "tsc",
|
|
18
18
|
"test": "npm run typecheck",
|
|
19
|
+
"test:apple": "npm run build && node tests/apple-foundation-models/run.mjs",
|
|
20
|
+
"bench:apple": "npm run build && node tests/apple-foundation-models/benchmark.mjs",
|
|
21
|
+
"check:prompt": "npm run build && node tests/snapshots/check.mjs",
|
|
19
22
|
"prepublishOnly": "npm run build"
|
|
20
23
|
},
|
|
21
24
|
"repository": {
|
|
@@ -50,6 +53,7 @@
|
|
|
50
53
|
"configstore": "^7.0.0",
|
|
51
54
|
"inquirer": "^12.5.2",
|
|
52
55
|
"node-fetch": "^3.3.2",
|
|
53
|
-
"openai": "^4.100.0"
|
|
56
|
+
"openai": "^4.100.0",
|
|
57
|
+
"ora": "^8.2.0"
|
|
54
58
|
}
|
|
55
59
|
}
|
|
@@ -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,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
|
-
};
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import chalk from "chalk";
|
|
2
|
-
import inquirer from "inquirer";
|
|
3
|
-
import { OPENROUTER_API_URL } from "../../../llm/index.js";
|
|
4
|
-
import { saveConfig } from "../../../config.js";
|
|
5
|
-
import { getAvailableModels } from "./getAvailableModels.js";
|
|
6
|
-
import { getOrUpdateApiKey } from "./getOrUpdateApiKey.js";
|
|
7
|
-
import { selectModel } from "./selectModel.js";
|
|
8
|
-
export const setupOpenRouter = async (existingConfig) => {
|
|
9
|
-
// Get API key - either the existing one or a new one
|
|
10
|
-
const apiKey = await getOrUpdateApiKey(existingConfig.apiKey);
|
|
11
|
-
if (!apiKey) {
|
|
12
|
-
console.error(chalk.red("API key is required for OpenRouter."));
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
// Update the config with the potentially new API key
|
|
16
|
-
const updatedConfig = { ...existingConfig, apiKey };
|
|
17
|
-
// Display current model if any
|
|
18
|
-
if (updatedConfig.model) {
|
|
19
|
-
console.log("Current model:", chalk.yellow(updatedConfig.model));
|
|
20
|
-
console.log("");
|
|
21
|
-
}
|
|
22
|
-
try {
|
|
23
|
-
console.log(chalk.gray("Fetching available models from OpenRouter..."));
|
|
24
|
-
const models = await getAvailableModels({
|
|
25
|
-
baseURLOverride: OPENROUTER_API_URL,
|
|
26
|
-
});
|
|
27
|
-
if (models.length > 0) {
|
|
28
|
-
console.log(chalk.green(`✓ Found ${models.length} models available with your API key`));
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
console.log(chalk.yellow("No models found from OpenRouter. Please specify a model manually."));
|
|
32
|
-
}
|
|
33
|
-
const selectedModel = await selectModel(models, updatedConfig.model);
|
|
34
|
-
const finalConfig = {
|
|
35
|
-
...updatedConfig,
|
|
36
|
-
model: selectedModel,
|
|
37
|
-
useLocalLLM: false,
|
|
38
|
-
};
|
|
39
|
-
// Save the config
|
|
40
|
-
saveConfig(finalConfig);
|
|
41
|
-
console.log(chalk.green(`✓ Model set to: ${chalk.yellow(selectedModel)}`));
|
|
42
|
-
return finalConfig;
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
console.error(chalk.yellow(`Error fetching models: ${error}`));
|
|
46
|
-
// Fallback to manual input if API call fails
|
|
47
|
-
const modelAnswer = await inquirer.prompt([
|
|
48
|
-
{
|
|
49
|
-
type: "input",
|
|
50
|
-
name: "model",
|
|
51
|
-
message: "Enter model identifier:",
|
|
52
|
-
validate: (input) => input ? true : "Model identifier is required",
|
|
53
|
-
},
|
|
54
|
-
]);
|
|
55
|
-
const selectedModel = modelAnswer.model;
|
|
56
|
-
const finalConfig = {
|
|
57
|
-
...updatedConfig,
|
|
58
|
-
model: selectedModel,
|
|
59
|
-
useLocalLLM: false,
|
|
60
|
-
};
|
|
61
|
-
// Save the config
|
|
62
|
-
saveConfig(finalConfig);
|
|
63
|
-
console.log(chalk.green(`✓ Model set to: ${chalk.yellow(selectedModel)}`));
|
|
64
|
-
return finalConfig;
|
|
65
|
-
}
|
|
66
|
-
};
|
|
File without changes
|
|
File without changes
|