Compare commits

..

14 Commits

Author SHA1 Message Date
di-sukharev
88d6a92567 fix gemini test 2024-09-06 12:10:21 +03:00
di-sukharev
36aab60393 Merge remote-tracking branch 'origin/dev' into refactoring_v2 2024-09-06 12:07:25 +03:00
di-sukharev
ba3c0b7e0b refactor(config.ts): remove unused setDefaultConfigValues function to clean up code
feat(config.ts): create getIsGlobalConfigFileExist function to check for config file existence
feat(migrations): add migration to set missing default values for configuration
fix(migrations): update migration functions to improve clarity and functionality
chore(migrations): register new migration for setting missing default values
style(migrations): format code for better readability in migration files
test(config.test.ts): update tests to improve readability and maintainability
2024-09-06 12:05:28 +03:00
Takanori Matsumoto
fa1cf46050 Fix: a bug that causes an error when pushing without setting git remote (#396) 2024-09-04 18:42:54 +03:00
di-sukharev
5209610236 fix(config.ts): ensure setConfig is only called when there are entries to set to prevent unnecessary function calls
feat(run.ts): add conditional to skip migrations if OCO_AI_PROVIDER is set to TEST to improve migration handling during testing
2024-09-04 11:54:54 +03:00
di-sukharev
d1f03f1105 feat(config): rename OCO_OPENAI_API_KEY to OCO_API_KEY for consistency and clarity
fix(config): add validation for OCO_WHY configuration key to ensure it is a boolean
refactor(config): extract default config setting logic into setDefaultConfigValues function
fix(cli): reorder function calls to ensure checkIsLatestVersion runs after runMigrations
chore(migrations): update getConfig calls to disable caching and default value setting
chore(migrations): remove obsolete configuration keys from global config file
fix(migrations): improve migration logging with consistent output formatting
style(migrations): enhance migration success and failure messages for better user feedback
2024-09-04 11:46:43 +03:00
di-sukharev
3df5b241dc fix(config.ts): set default values for OCO_TOKENS_MAX_INPUT and OCO_TOKENS_MAX_OUTPUT to ensure proper configuration
refactor(generateCommitMessageFromGitDiff.ts): simplify MAX_TOKENS_INPUT and MAX_TOKENS_OUTPUT assignments by removing redundant default value logic
2024-09-04 11:04:44 +03:00
di-sukharev
5ddf2cb21a Merge remote-tracking branch 'origin/dev' into refactoring_v2 2024-09-04 10:56:34 +03:00
GPT10
1d19ddd9e2 378: fix hook env (#402)
* fix(prepare-commit-msg-hook): update error handling to provide clearer instructions for setting API keys and improve user guidance

* build
2024-09-03 13:14:45 +03:00
di-sukharev
c6b6b2f3fd chore(package.json): remove unused dependency "ai" to clean up package.json
fix(commit.ts): update success message to start with a lowercase letter for consistency
2024-09-03 13:13:38 +03:00
di-sukharev
e1ce774538 chore(config): remove debug console logs to clean up the codebase
feat(migrations): add migration to remove obsolete config keys from global file to streamline configuration management
2024-09-02 12:29:41 +03:00
di-sukharev
f1ea54cf1c feat(docs): update README to reflect changes in API key and URL configuration for better clarity and usability
feat(migrations): implement migration to consolidate API key and URL into a single configuration for improved simplicity
refactor(config): rename configuration keys to use a single API key and URL for all LLM providers, enhancing consistency
fix(engine): update engine initialization to use new unified API key and URL configuration
test(config): update tests to validate new configuration structure and ensure backward compatibility with existing setups
2024-09-02 12:25:49 +03:00
di-sukharev
ccb7cd99e5 Merge branch 'dev' into refactoring_v2 2024-09-02 11:13:57 +03:00
di-sukharev
ce6ae0b514 refactor(engine): rename classes from FlowiseAi, Gemini, and OllamaAi to FlowiseEngine, GeminiEngine, and OllamaEngine for consistency and clarity
fix(engine): update imports and instantiation of renamed classes in engine utility functions to ensure proper functionality
2024-09-02 11:13:49 +03:00
18 changed files with 625 additions and 693 deletions

View File

@@ -18,7 +18,7 @@ To get started, follow these steps:
1. Clone the project repository locally.
2. Install dependencies with `npm install`.
3. Run the project with `npm run dev`.
4. See [issues](https://github.com/di-sukharev/opencommit/issues) or [TODO.md](TODO.md) to help the project.
4. See [issues](https://github.com/di-sukharev/open-commit/issues) or [TODO.md](../TODO.md) to help the project.
## Commit message guidelines
@@ -30,7 +30,7 @@ If you encounter any issues while using the project, please report them on the G
## Contacts
If you have any questions about contributing to the project, please contact by [creating an issue](https://github.com/di-sukharev/opencommit/issues) on the GitHub issue tracker.
If you have any questions about contributing to the project, please contact by [creating an issue](https://github.com/di-sukharev/open-commit/issues) on the GitHub issue tracker.
## License

View File

@@ -431,8 +431,8 @@ var require_escape = __commonJS({
}
function escapeArgument(arg, doubleEscapeMetaChars) {
arg = `${arg}`;
arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
arg = arg.replace(/(?=(\\+?)?)\1$/, "$1$1");
arg = arg.replace(/(\\*)"/g, '$1$1\\"');
arg = arg.replace(/(\\*)$/, "$1$1");
arg = `"${arg}"`;
arg = arg.replace(metaCharsRegExp, "^$1");
if (doubleEscapeMetaChars) {
@@ -578,7 +578,7 @@ var require_enoent = __commonJS({
const originalEmit = cp.emit;
cp.emit = function(name, arg1) {
if (name === "exit") {
const err = verifyENOENT(arg1, parsed);
const err = verifyENOENT(arg1, parsed, "spawn");
if (err) {
return originalEmit.call(cp, "error", err);
}
@@ -1672,7 +1672,7 @@ var require_mappingTable = __commonJS({
var require_tr46 = __commonJS({
"node_modules/node-fetch/node_modules/tr46/index.js"(exports, module2) {
"use strict";
const punycode = require('punycode/');
var punycode = require("punycode");
var mappingTable = require_mappingTable();
var PROCESSING_OPTIONS = {
TRANSITIONAL: 0,
@@ -1834,7 +1834,7 @@ var require_tr46 = __commonJS({
var require_url_state_machine = __commonJS({
"node_modules/node-fetch/node_modules/whatwg-url/lib/url-state-machine.js"(exports, module2) {
"use strict";
const punycode = require('punycode/');
var punycode = require("punycode");
var tr46 = require_tr46();
var specialSchemes = {
ftp: 21,
@@ -27331,7 +27331,7 @@ function G3(t2, e3) {
// package.json
var package_default = {
name: "opencommit",
version: "3.2.2",
version: "3.1.2",
description: "Auto-generate impressive commits in 1 second. Killing lame commits with AI \u{1F92F}\u{1F52B}",
keywords: [
"git",
@@ -27377,9 +27377,8 @@ var package_default = {
"dev:gemini": "OCO_AI_PROVIDER='gemini' ts-node ./src/cli.ts",
build: "rimraf out && node esbuild.config.js",
"build:push": "npm run build && git add . && git commit -m 'build' && git push",
deploy: "npm publish --tag latest",
"deploy:build": "npm run build:push && git push --tags && npm run deploy",
"deploy:patch": "npm version patch && npm run deploy:build",
deploy: "npm run build:push && git push --tags && npm publish --tag latest",
"deploy:patch": "npm version patch && npm run deploy",
lint: "eslint src --ext ts && tsc --noEmit",
format: "prettier --write src",
test: "node --no-warnings --experimental-vm-modules $( [ -f ./node_modules/.bin/jest ] && echo ./node_modules/.bin/jest || which jest ) test/unit",
@@ -27389,8 +27388,7 @@ var package_default = {
"test:unit:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:unit",
"test:e2e": "npm run test:e2e:setup && jest test/e2e",
"test:e2e:setup": "sh test/e2e/setup.sh",
"test:e2e:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:e2e",
"mlx:start": "OCO_AI_PROVIDER='mlx' node ./out/cli.cjs"
"test:e2e:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:e2e"
},
devDependencies: {
"@commitlint/types": "^17.4.4",
@@ -29919,29 +29917,16 @@ var MODEL_LIST = {
"gemini-1.0-pro",
"gemini-pro-vision",
"text-embedding-004"
],
groq: [
"llama3-70b-8192",
"llama3-8b-8192",
"llama-guard-3-8b",
"llama-3.1-8b-instant",
"llama-3.1-70b-versatile",
"gemma-7b-it",
"gemma2-9b-it"
]
};
var getDefaultModel = (provider) => {
switch (provider) {
case "ollama":
return "";
case "mlx":
return "";
case "anthropic":
return MODEL_LIST.anthropic[0];
case "gemini":
return MODEL_LIST.gemini[0];
case "groq":
return MODEL_LIST.groq[0];
default:
return MODEL_LIST.openai[0];
}
@@ -29967,7 +29952,7 @@ var configValidators = {
validateConfig(
"OCO_API_KEY",
value,
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
);
return value;
},
@@ -30065,16 +30050,10 @@ var configValidators = {
value = "openai";
validateConfig(
"OCO_AI_PROVIDER" /* OCO_AI_PROVIDER */,
[
"openai",
"anthropic",
"gemini",
"azure",
"test",
"flowise",
"groq"
].includes(value) || value.startsWith("ollama") || value.startsWith("mlx"),
`${value} is not supported yet, use 'ollama', 'mlx', anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
["openai", "anthropic", "gemini", "azure", "test", "flowise"].includes(
value
) || value.startsWith("ollama"),
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
);
return value;
},
@@ -30113,8 +30092,6 @@ var OCO_AI_PROVIDER_ENUM = /* @__PURE__ */ ((OCO_AI_PROVIDER_ENUM2) => {
OCO_AI_PROVIDER_ENUM2["AZURE"] = "azure";
OCO_AI_PROVIDER_ENUM2["TEST"] = "test";
OCO_AI_PROVIDER_ENUM2["FLOWISE"] = "flowise";
OCO_AI_PROVIDER_ENUM2["GROQ"] = "groq";
OCO_AI_PROVIDER_ENUM2["MLX"] = "mlx";
return OCO_AI_PROVIDER_ENUM2;
})(OCO_AI_PROVIDER_ENUM || {});
var defaultConfigPath = (0, import_path.join)((0, import_os.homedir)(), ".opencommit");
@@ -30131,6 +30108,7 @@ var DEFAULT_CONFIG = {
OCO_AI_PROVIDER: "openai" /* OPENAI */,
OCO_ONE_LINE_COMMIT: false,
OCO_TEST_MOCK_TYPE: "commit-message",
OCO_FLOWISE_ENDPOINT: ":",
OCO_WHY: false,
OCO_GITPUSH: true
};
@@ -30190,25 +30168,6 @@ var mergeConfigs = (main, fallback) => {
return acc;
}, {});
};
var cleanUndefinedValues = (config7) => {
return Object.fromEntries(
Object.entries(config7).map(([_7, v5]) => {
try {
if (typeof v5 === "string") {
if (v5 === "undefined")
return [_7, void 0];
if (v5 === "null")
return [_7, null];
const parsedValue = JSON.parse(v5);
return [_7, parsedValue];
}
return [_7, v5];
} catch (error) {
return [_7, v5];
}
})
);
};
var getConfig = ({
envPath = defaultEnvPath,
globalPath = defaultConfigPath
@@ -30216,8 +30175,7 @@ var getConfig = ({
const envConfig = getEnvConfig(envPath);
const globalConfig = getGlobalConfig(globalPath);
const config7 = mergeConfigs(envConfig, globalConfig);
const cleanConfig = cleanUndefinedValues(config7);
return cleanConfig;
return config7;
};
var setConfig = (keyValues, globalConfigPath = defaultConfigPath) => {
const config7 = getConfig({
@@ -44512,51 +44470,7 @@ var OpenAiEngine = class {
}
};
this.config = config7;
if (!config7.baseURL) {
this.client = new OpenAI({ apiKey: config7.apiKey });
} else {
this.client = new OpenAI({ apiKey: config7.apiKey, baseURL: config7.baseURL });
}
}
};
// src/engine/groq.ts
var GroqEngine = class extends OpenAiEngine {
constructor(config7) {
config7.baseURL = "https://api.groq.com/openai/v1";
super(config7);
}
};
// src/engine/mlx.ts
var MLXEngine = class {
constructor(config7) {
this.config = config7;
this.client = axios_default.create({
url: config7.baseURL ? `${config7.baseURL}/${config7.apiKey}` : "http://localhost:8080/v1/chat/completions",
headers: { "Content-Type": "application/json" }
});
}
async generateCommitMessage(messages) {
const params = {
messages,
temperature: 0,
top_p: 0.1,
repetition_penalty: 1.5,
stream: false
};
try {
const response = await this.client.post(
this.client.getUri(this.config),
params
);
const choices = response.data.choices;
const message = choices[0].message;
return message?.content;
} catch (err) {
const message = err.response?.data?.error ?? err.message;
throw new Error(`MLX provider error: ${message}`);
}
this.client = new OpenAI({ apiKey: config7.apiKey });
}
};
@@ -44584,10 +44498,6 @@ function getEngine() {
return new AzureEngine(DEFAULT_CONFIG2);
case "flowise" /* FLOWISE */:
return new FlowiseEngine(DEFAULT_CONFIG2);
case "groq" /* GROQ */:
return new GroqEngine(DEFAULT_CONFIG2);
case "mlx" /* MLX */:
return new MLXEngine(DEFAULT_CONFIG2);
default:
return new OpenAiEngine(DEFAULT_CONFIG2);
}
@@ -44969,14 +44879,7 @@ var CONVENTIONAL_COMMIT_KEYWORDS = "Do not preface the commit with anything, exc
var getCommitConvention = (fullGitMojiSpec) => config4.OCO_EMOJI ? fullGitMojiSpec ? FULL_GITMOJI_SPEC : GITMOJI_HELP : CONVENTIONAL_COMMIT_KEYWORDS;
var getDescriptionInstruction = () => config4.OCO_DESCRIPTION ? `Add a short description of WHY the changes are done after the commit message. Don't start it with "This commit", just describe the changes.` : "Don't add any descriptions to the commit, only commit message.";
var getOneLineCommitInstruction = () => config4.OCO_ONE_LINE_COMMIT ? "Craft a concise commit message that encapsulates all changes made, with an emphasis on the primary updates. If the modifications share a common theme or scope, mention it succinctly; otherwise, leave the scope out to maintain focus. The goal is to provide a clear and unified overview of the changes in a one single message, without diverging into a list of commit per file change." : "";
var userInputCodeContext = (context) => {
if (context !== "" && context !== " ") {
return `Additional context provided by the user: <context>${context}</context>
Consider this context when generating the commit message, incorporating relevant information when appropriate.`;
}
return "";
};
var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context) => ({
var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
role: "system",
content: (() => {
const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention";
@@ -44986,14 +44889,12 @@ var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context) => ({
const descriptionGuideline = getDescriptionInstruction();
const oneLineCommitGuideline = getOneLineCommitInstruction();
const generalGuidelines = `Use the present tense. Lines must not be longer than 74 characters. Use ${language} for the commit message.`;
const userInputContext = userInputCodeContext(context);
return `${missionStatement}
${diffInstruction}
${conventionGuidelines}
${descriptionGuideline}
${oneLineCommitGuideline}
${generalGuidelines}
${userInputContext}`;
${generalGuidelines}`;
})()
});
var INIT_DIFF_PROMPT = {
@@ -45035,7 +44936,7 @@ var INIT_CONSISTENCY_PROMPT = (translation4) => ({
role: "assistant",
content: getContent(translation4)
});
var getMainCommitPrompt = async (fullGitMojiSpec, context) => {
var getMainCommitPrompt = async (fullGitMojiSpec) => {
switch (config4.OCO_PROMPT_MODULE) {
case "@commitlint":
if (!await commitlintLLMConfigExists()) {
@@ -45057,7 +44958,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec, context) => {
];
default:
return [
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec, context),
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec),
INIT_DIFF_PROMPT,
INIT_CONSISTENCY_PROMPT(translation3)
];
@@ -45084,8 +44985,8 @@ function mergeDiffs(arr, maxStringLength) {
var config5 = getConfig();
var MAX_TOKENS_INPUT = config5.OCO_TOKENS_MAX_INPUT;
var MAX_TOKENS_OUTPUT = config5.OCO_TOKENS_MAX_OUTPUT;
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec, context) => {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context);
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec) => {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
chatContextAsCompletionRequest.push({
role: "user",
@@ -45101,12 +45002,9 @@ var GenerateCommitMessageErrorEnum = ((GenerateCommitMessageErrorEnum2) => {
return GenerateCommitMessageErrorEnum2;
})(GenerateCommitMessageErrorEnum || {});
var ADJUSTMENT_FACTOR = 20;
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context = "") => {
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
try {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
fullGitMojiSpec,
context
);
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
(msg) => tokenCount(msg.content) + 4
).reduce((a4, b7) => a4 + b7, 0);
@@ -45126,8 +45024,7 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context
}
const messages = await generateCommitMessageChatCompletionPrompt(
diff,
fullGitMojiSpec,
context
fullGitMojiSpec
);
const engine = getEngine();
const commitMessage = await engine.generateCommitMessage(messages);
@@ -45334,7 +45231,6 @@ var checkMessageTemplate = (extraArgs2) => {
var generateCommitMessageFromGitDiff = async ({
diff,
extraArgs: extraArgs2,
context = "",
fullGitMojiSpec = false,
skipCommitConfirmation = false
}) => {
@@ -45344,8 +45240,7 @@ var generateCommitMessageFromGitDiff = async ({
try {
let commitMessage = await generateCommitMessageByDiff(
diff,
fullGitMojiSpec,
context
fullGitMojiSpec
);
const messageTemplate = checkMessageTemplate(extraArgs2);
if (config6.OCO_MESSAGE_TEMPLATE_PLACEHOLDER && typeof messageTemplate === "string") {
@@ -45382,15 +45277,13 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2
);
ce(stdout);
const remotes = await getGitRemotes();
if (config6.OCO_GITPUSH === false)
return;
if (!remotes.length) {
const { stdout: stdout2 } = await execa("git", ["push"]);
if (stdout2)
ce(stdout2);
process.exit(0);
}
if (remotes.length === 1) {
if (remotes.length === 1 && config6.OCO_GITPUSH !== true) {
const isPushConfirmedByUser = await Q3({
message: "Do you want to run `git push`?"
});
@@ -45446,16 +45339,13 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2
}
}
} catch (error) {
commitGenerationSpinner.stop(
`${source_default.red("\u2716")} Failed to generate the commit message`
);
console.log(error);
commitGenerationSpinner.stop("\u{1F4DD} Commit message generated");
const err = error;
ce(`${source_default.red("\u2716")} ${err?.message || err}`);
process.exit(1);
}
};
async function commit(extraArgs2 = [], context = "", isStageAllFlag = false, fullGitMojiSpec = false, skipCommitConfirmation = false) {
async function commit(extraArgs2 = [], isStageAllFlag = false, fullGitMojiSpec = false, skipCommitConfirmation = false) {
if (isStageAllFlag) {
const changedFiles2 = await getChangedFiles();
if (changedFiles2)
@@ -45486,7 +45376,7 @@ async function commit(extraArgs2 = [], context = "", isStageAllFlag = false, ful
if (hD2(isStageAllAndCommitConfirmedByUser))
process.exit(1);
if (isStageAllAndCommitConfirmedByUser) {
await commit(extraArgs2, context, true, fullGitMojiSpec);
await commit(extraArgs2, true, fullGitMojiSpec);
process.exit(1);
}
if (stagedFiles.length === 0 && changedFiles.length > 0) {
@@ -45501,7 +45391,7 @@ async function commit(extraArgs2 = [], context = "", isStageAllFlag = false, ful
process.exit(1);
await gitAdd({ files });
}
await commit(extraArgs2, context, false, fullGitMojiSpec);
await commit(extraArgs2, false, fullGitMojiSpec);
process.exit(1);
}
stagedFilesSpinner.stop(
@@ -45512,7 +45402,6 @@ ${stagedFiles.map((file) => ` ${file}`).join("\n")}`
generateCommitMessageFromGitDiff({
diff: await getDiff({ files: stagedFiles }),
extraArgs: extraArgs2,
context,
fullGitMojiSpec,
skipCommitConfirmation
})
@@ -45785,12 +45674,11 @@ function set_missing_default_values_default() {
const entriesToSet = [];
for (const entry of Object.entries(DEFAULT_CONFIG)) {
const [key, _value] = entry;
if (config7[key] === "undefined" || config7[key] === void 0)
if (config7[key] === "undefined")
entriesToSet.push(entry);
}
if (entriesToSet.length > 0)
setConfig(entriesToSet);
console.log(entriesToSet);
};
setDefaultConfigValues(getGlobalConfig());
}
@@ -45847,7 +45735,6 @@ var runMigrations = async () => {
ce(
`${source_default.red("Failed to apply migration")} ${migration.name}: ${error}`
);
process.exit(1);
}
isMigrated = true;
}
@@ -45871,12 +45758,6 @@ Z2(
commands: [configCommand, hookCommand, commitlintConfigCommand],
flags: {
fgm: Boolean,
context: {
type: String,
alias: "c",
description: "Additional user input context for the commit message",
default: ""
},
yes: {
type: Boolean,
alias: "y",
@@ -45893,7 +45774,7 @@ Z2(
if (await isHookCalled()) {
prepareCommitMessageHook();
} else {
commit(extraArgs, flags.context, false, flags.fgm, flags.yes);
commit(extraArgs, false, flags.fgm, flags.yes);
}
},
extraArgs

View File

@@ -20487,7 +20487,7 @@ var require_mappingTable = __commonJS({
var require_tr46 = __commonJS({
"node_modules/node-fetch/node_modules/tr46/index.js"(exports, module2) {
"use strict";
const punycode = require('punycode/');
var punycode = require("punycode");
var mappingTable = require_mappingTable();
var PROCESSING_OPTIONS = {
TRANSITIONAL: 0,
@@ -20649,7 +20649,7 @@ var require_tr46 = __commonJS({
var require_url_state_machine = __commonJS({
"node_modules/node-fetch/node_modules/whatwg-url/lib/url-state-machine.js"(exports, module2) {
"use strict";
const punycode = require('punycode/');
var punycode = require("punycode");
var tr46 = require_tr46();
var specialSchemes = {
ftp: 21,
@@ -48730,29 +48730,16 @@ var MODEL_LIST = {
"gemini-1.0-pro",
"gemini-pro-vision",
"text-embedding-004"
],
groq: [
"llama3-70b-8192",
"llama3-8b-8192",
"llama-guard-3-8b",
"llama-3.1-8b-instant",
"llama-3.1-70b-versatile",
"gemma-7b-it",
"gemma2-9b-it"
]
};
var getDefaultModel = (provider) => {
switch (provider) {
case "ollama":
return "";
case "mlx":
return "";
case "anthropic":
return MODEL_LIST.anthropic[0];
case "gemini":
return MODEL_LIST.gemini[0];
case "groq":
return MODEL_LIST.groq[0];
default:
return MODEL_LIST.openai[0];
}
@@ -48778,7 +48765,7 @@ var configValidators = {
validateConfig(
"OCO_API_KEY",
value,
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
);
return value;
},
@@ -48876,16 +48863,10 @@ var configValidators = {
value = "openai";
validateConfig(
"OCO_AI_PROVIDER" /* OCO_AI_PROVIDER */,
[
"openai",
"anthropic",
"gemini",
"azure",
"test",
"flowise",
"groq"
].includes(value) || value.startsWith("ollama") || value.startsWith("mlx"),
`${value} is not supported yet, use 'ollama', 'mlx', anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
["openai", "anthropic", "gemini", "azure", "test", "flowise"].includes(
value
) || value.startsWith("ollama"),
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
);
return value;
},
@@ -48930,6 +48911,7 @@ var DEFAULT_CONFIG = {
OCO_AI_PROVIDER: "openai" /* OPENAI */,
OCO_ONE_LINE_COMMIT: false,
OCO_TEST_MOCK_TYPE: "commit-message",
OCO_FLOWISE_ENDPOINT: ":",
OCO_WHY: false,
OCO_GITPUSH: true
};
@@ -48989,25 +48971,6 @@ var mergeConfigs = (main, fallback) => {
return acc;
}, {});
};
var cleanUndefinedValues = (config6) => {
return Object.fromEntries(
Object.entries(config6).map(([_3, v2]) => {
try {
if (typeof v2 === "string") {
if (v2 === "undefined")
return [_3, void 0];
if (v2 === "null")
return [_3, null];
const parsedValue = JSON.parse(v2);
return [_3, parsedValue];
}
return [_3, v2];
} catch (error) {
return [_3, v2];
}
})
);
};
var getConfig = ({
envPath = defaultEnvPath,
globalPath = defaultConfigPath
@@ -49015,8 +48978,7 @@ var getConfig = ({
const envConfig = getEnvConfig(envPath);
const globalConfig = getGlobalConfig(globalPath);
const config6 = mergeConfigs(envConfig, globalConfig);
const cleanConfig = cleanUndefinedValues(config6);
return cleanConfig;
return config6;
};
var setConfig = (keyValues, globalConfigPath = defaultConfigPath) => {
const config6 = getConfig({
@@ -63311,51 +63273,7 @@ var OpenAiEngine = class {
}
};
this.config = config6;
if (!config6.baseURL) {
this.client = new OpenAI({ apiKey: config6.apiKey });
} else {
this.client = new OpenAI({ apiKey: config6.apiKey, baseURL: config6.baseURL });
}
}
};
// src/engine/groq.ts
var GroqEngine = class extends OpenAiEngine {
constructor(config6) {
config6.baseURL = "https://api.groq.com/openai/v1";
super(config6);
}
};
// src/engine/mlx.ts
var MLXEngine = class {
constructor(config6) {
this.config = config6;
this.client = axios_default.create({
url: config6.baseURL ? `${config6.baseURL}/${config6.apiKey}` : "http://localhost:8080/v1/chat/completions",
headers: { "Content-Type": "application/json" }
});
}
async generateCommitMessage(messages) {
const params = {
messages,
temperature: 0,
top_p: 0.1,
repetition_penalty: 1.5,
stream: false
};
try {
const response = await this.client.post(
this.client.getUri(this.config),
params
);
const choices = response.data.choices;
const message = choices[0].message;
return message?.content;
} catch (err) {
const message = err.response?.data?.error ?? err.message;
throw new Error(`MLX provider error: ${message}`);
}
this.client = new OpenAI({ apiKey: config6.apiKey });
}
};
@@ -63383,10 +63301,6 @@ function getEngine() {
return new AzureEngine(DEFAULT_CONFIG2);
case "flowise" /* FLOWISE */:
return new FlowiseEngine(DEFAULT_CONFIG2);
case "groq" /* GROQ */:
return new GroqEngine(DEFAULT_CONFIG2);
case "mlx" /* MLX */:
return new MLXEngine(DEFAULT_CONFIG2);
default:
return new OpenAiEngine(DEFAULT_CONFIG2);
}
@@ -63768,14 +63682,7 @@ var CONVENTIONAL_COMMIT_KEYWORDS = "Do not preface the commit with anything, exc
var getCommitConvention = (fullGitMojiSpec) => config4.OCO_EMOJI ? fullGitMojiSpec ? FULL_GITMOJI_SPEC : GITMOJI_HELP : CONVENTIONAL_COMMIT_KEYWORDS;
var getDescriptionInstruction = () => config4.OCO_DESCRIPTION ? `Add a short description of WHY the changes are done after the commit message. Don't start it with "This commit", just describe the changes.` : "Don't add any descriptions to the commit, only commit message.";
var getOneLineCommitInstruction = () => config4.OCO_ONE_LINE_COMMIT ? "Craft a concise commit message that encapsulates all changes made, with an emphasis on the primary updates. If the modifications share a common theme or scope, mention it succinctly; otherwise, leave the scope out to maintain focus. The goal is to provide a clear and unified overview of the changes in a one single message, without diverging into a list of commit per file change." : "";
var userInputCodeContext = (context2) => {
if (context2 !== "" && context2 !== " ") {
return `Additional context provided by the user: <context>${context2}</context>
Consider this context when generating the commit message, incorporating relevant information when appropriate.`;
}
return "";
};
var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context2) => ({
var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
role: "system",
content: (() => {
const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention";
@@ -63785,14 +63692,12 @@ var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context2) => ({
const descriptionGuideline = getDescriptionInstruction();
const oneLineCommitGuideline = getOneLineCommitInstruction();
const generalGuidelines = `Use the present tense. Lines must not be longer than 74 characters. Use ${language} for the commit message.`;
const userInputContext = userInputCodeContext(context2);
return `${missionStatement}
${diffInstruction}
${conventionGuidelines}
${descriptionGuideline}
${oneLineCommitGuideline}
${generalGuidelines}
${userInputContext}`;
${generalGuidelines}`;
})()
});
var INIT_DIFF_PROMPT = {
@@ -63834,7 +63739,7 @@ var INIT_CONSISTENCY_PROMPT = (translation4) => ({
role: "assistant",
content: getContent(translation4)
});
var getMainCommitPrompt = async (fullGitMojiSpec, context2) => {
var getMainCommitPrompt = async (fullGitMojiSpec) => {
switch (config4.OCO_PROMPT_MODULE) {
case "@commitlint":
if (!await commitlintLLMConfigExists()) {
@@ -63856,7 +63761,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec, context2) => {
];
default:
return [
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec, context2),
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec),
INIT_DIFF_PROMPT,
INIT_CONSISTENCY_PROMPT(translation3)
];
@@ -63883,8 +63788,8 @@ function mergeDiffs(arr, maxStringLength) {
var config5 = getConfig();
var MAX_TOKENS_INPUT = config5.OCO_TOKENS_MAX_INPUT;
var MAX_TOKENS_OUTPUT = config5.OCO_TOKENS_MAX_OUTPUT;
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec, context2) => {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context2);
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec) => {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
chatContextAsCompletionRequest.push({
role: "user",
@@ -63900,12 +63805,9 @@ var GenerateCommitMessageErrorEnum = ((GenerateCommitMessageErrorEnum2) => {
return GenerateCommitMessageErrorEnum2;
})(GenerateCommitMessageErrorEnum || {});
var ADJUSTMENT_FACTOR = 20;
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context2 = "") => {
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
try {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
fullGitMojiSpec,
context2
);
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
(msg) => tokenCount(msg.content) + 4
).reduce((a3, b3) => a3 + b3, 0);
@@ -63925,8 +63827,7 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context2
}
const messages = await generateCommitMessageChatCompletionPrompt(
diff,
fullGitMojiSpec,
context2
fullGitMojiSpec
);
const engine = getEngine();
const commitMessage = await engine.generateCommitMessage(messages);

592
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "opencommit",
"version": "3.2.4",
"version": "3.1.2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "opencommit",
"version": "3.2.4",
"version": "3.1.2",
"license": "MIT",
"dependencies": {
"@actions/core": "^1.10.0",
@@ -17,9 +17,9 @@
"@clack/prompts": "^0.6.1",
"@dqbd/tiktoken": "^1.0.2",
"@google/generative-ai": "^0.11.4",
"@mistralai/mistralai": "^1.3.5",
"@octokit/webhooks-schemas": "^6.11.0",
"@octokit/webhooks-types": "^6.11.0",
"ai": "^2.2.14",
"axios": "^1.3.4",
"chalk": "^5.2.0",
"cleye": "^1.3.2",
@@ -28,9 +28,7 @@
"ignore": "^5.2.4",
"ini": "^3.0.1",
"inquirer": "^9.1.4",
"openai": "^4.57.0",
"punycode": "^2.3.1",
"zod": "^3.23.8"
"openai": "^4.57.0"
},
"bin": {
"oco": "out/cli.cjs",
@@ -110,7 +108,6 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.24"
@@ -577,7 +574,6 @@
"version": "7.24.1",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.1.tgz",
"integrity": "sha512-Zo9c7N3xdOIQrNip7Lc9wvRPzlRtovHVE4lkz8WEDr7uYh/GMQhSiIgFxGIArRHYdJE5kxtZjAf8rT0xhdLCzg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
},
@@ -1732,7 +1728,6 @@
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
@@ -1746,7 +1741,6 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
@@ -1755,7 +1749,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"engines": {
"node": ">=6.0.0"
}
@@ -1763,14 +1756,12 @@
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
@@ -1787,16 +1778,6 @@
"node": ">= 0.4"
}
},
"node_modules/@mistralai/mistralai": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/@mistralai/mistralai/-/mistralai-1.3.5.tgz",
"integrity": "sha512-yC91oJ5ScEPqbXmv3mJTwTFgu/ZtsYoOPOhaVXSsy6x4zXTqTI57yEC1flC9uiA8GpG/yhpn2BBUXF95+U9Blw==",
"peerDependencies": {
"react": "^18 || ^19",
"react-dom": "^18 || ^19",
"zod": ">= 3"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -2032,6 +2013,12 @@
"@babel/types": "^7.20.7"
}
},
"node_modules/@types/estree": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"peer": true
},
"node_modules/@types/graceful-fs": {
"version": "4.1.9",
"resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz",
@@ -2346,6 +2333,117 @@
"integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
"dev": true
},
"node_modules/@vue/compiler-core": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.21.tgz",
"integrity": "sha512-MjXawxZf2SbZszLPYxaFCjxfibYrzr3eYbKxwpLR9EQN+oaziSu3qKVbwBERj1IFIB8OLUewxB5m/BFzi613og==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.23.9",
"@vue/shared": "3.4.21",
"entities": "^4.5.0",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"node_modules/@vue/compiler-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.21.tgz",
"integrity": "sha512-IZC6FKowtT1sl0CR5DpXSiEB5ayw75oT2bma1BEhV7RRR1+cfwLrxc2Z8Zq/RGFzJ8w5r9QtCOvTjQgdn0IKmA==",
"peer": true,
"dependencies": {
"@vue/compiler-core": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/compiler-sfc": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.21.tgz",
"integrity": "sha512-me7epoTxYlY+2CUM7hy9PCDdpMPfIwrOvAXud2Upk10g4YLv9UBW7kL798TvMeDhPthkZ0CONNrK2GoeI1ODiQ==",
"peer": true,
"dependencies": {
"@babel/parser": "^7.23.9",
"@vue/compiler-core": "3.4.21",
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.7",
"postcss": "^8.4.35",
"source-map-js": "^1.0.2"
}
},
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"peer": true
},
"node_modules/@vue/compiler-ssr": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.21.tgz",
"integrity": "sha512-M5+9nI2lPpAsgXOGQobnIueVqc9sisBFexh5yMIMRAPYLa7+5wEJs8iqOZc1WAa9WQbx9GR2twgznU8LTIiZ4Q==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/reactivity": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.21.tgz",
"integrity": "sha512-UhenImdc0L0/4ahGCyEzc/pZNwVgcglGy9HVzJ1Bq2Mm9qXOpP8RyNTjookw/gOCUlXSEtuZ2fUg5nrHcoqJcw==",
"peer": true,
"dependencies": {
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/runtime-core": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.21.tgz",
"integrity": "sha512-pQthsuYzE1XcGZznTKn73G0s14eCJcjaLvp3/DKeYWoFacD9glJoqlNBxt3W2c5S40t6CCcpPf+jG01N3ULyrA==",
"peer": true,
"dependencies": {
"@vue/reactivity": "3.4.21",
"@vue/shared": "3.4.21"
}
},
"node_modules/@vue/runtime-dom": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.21.tgz",
"integrity": "sha512-gvf+C9cFpevsQxbkRBS1NpU8CqxKw0ebqMvLwcGQrNpx6gqRDodqKqA+A2VZZpQ9RpK2f9yfg8VbW/EpdFUOJw==",
"peer": true,
"dependencies": {
"@vue/runtime-core": "3.4.21",
"@vue/shared": "3.4.21",
"csstype": "^3.1.3"
}
},
"node_modules/@vue/server-renderer": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.21.tgz",
"integrity": "sha512-aV1gXyKSN6Rz+6kZ6kr5+Ll14YzmIbeuWe7ryJl5muJ4uwSwY/aStXTixx76TwkZFJLm1aAlA/HSWEJ4EyiMkg==",
"peer": true,
"dependencies": {
"@vue/compiler-ssr": "3.4.21",
"@vue/shared": "3.4.21"
},
"peerDependencies": {
"vue": "3.4.21"
}
},
"node_modules/@vue/shared": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.21.tgz",
"integrity": "sha512-PuJe7vDIi6VYSinuEbUIQgMIRZGgM8e4R+G+/dQTk0X1NEdvgvvgv7m+rfmDH1gZzyA1OjjoWskvHlfRNfQf3g==",
"peer": true
},
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -2361,7 +2459,6 @@
"version": "8.11.3",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -2409,6 +2506,43 @@
"node": ">= 8.0.0"
}
},
"node_modules/ai": {
"version": "2.2.37",
"resolved": "https://registry.npmjs.org/ai/-/ai-2.2.37.tgz",
"integrity": "sha512-JIYm5N1muGVqBqWnvkt29FmXhESoO5TcDxw74OE41SsM+uIou6NPDDs0XWb/ABcd1gmp6k5zym64KWMPM2xm0A==",
"dependencies": {
"eventsource-parser": "1.0.0",
"nanoid": "3.3.6",
"solid-swr-store": "0.10.7",
"sswr": "2.0.0",
"swr": "2.2.0",
"swr-store": "0.10.6",
"swrv": "1.0.4"
},
"engines": {
"node": ">=14.6"
},
"peerDependencies": {
"react": "^18.2.0",
"solid-js": "^1.7.7",
"svelte": "^3.0.0 || ^4.0.0",
"vue": "^3.3.4"
},
"peerDependenciesMeta": {
"react": {
"optional": true
},
"solid-js": {
"optional": true
},
"svelte": {
"optional": true
},
"vue": {
"optional": true
}
}
},
"node_modules/ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
@@ -2495,6 +2629,15 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
"node_modules/aria-query": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
"peer": true,
"dependencies": {
"dequal": "^2.0.3"
}
},
"node_modules/array-union": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
@@ -2528,6 +2671,15 @@
"proxy-from-env": "^1.1.0"
}
},
"node_modules/axobject-query": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.0.0.tgz",
"integrity": "sha512-+60uv1hiVFhHZeO+Lz0RYzsVHy5Wr1ayX0mwda9KPDVLNJgZ1T9Ny7VmFbLDzxsH0D87I86vgj3gFrjTJUYznw==",
"peer": true,
"dependencies": {
"dequal": "^2.0.3"
}
},
"node_modules/babel-jest": {
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz",
@@ -3104,6 +3256,19 @@
"node": ">= 0.12.0"
}
},
"node_modules/code-red": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/code-red/-/code-red-1.0.4.tgz",
"integrity": "sha512-7qJWqItLA8/VPVlKJlFXU+NBlo/qyfs39aJcuMT/2ere32ZqvF5OSxgdM5xOfJJ7O429gg2HM47y8v9P+9wrNw==",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15",
"@types/estree": "^1.0.1",
"acorn": "^8.10.0",
"estree-walker": "^3.0.3",
"periscopic": "^3.1.0"
}
},
"node_modules/collect-v8-coverage": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz",
@@ -3225,10 +3390,9 @@
"dev": true
},
"node_modules/cross-spawn": {
"version": "7.0.6",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
"license": "MIT",
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
"dependencies": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
@@ -3244,6 +3408,25 @@
"integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==",
"deprecated": "This package is no longer supported. It's now a built-in Node module. If you've depended on crypto, you should switch to the one that's built-in."
},
"node_modules/css-tree": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz",
"integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==",
"peer": true,
"dependencies": {
"mdn-data": "2.0.30",
"source-map-js": "^1.0.1"
},
"engines": {
"node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"peer": true
},
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -3329,6 +3512,14 @@
"resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
"integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ=="
},
"node_modules/dequal": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
"engines": {
"node": ">=6"
}
},
"node_modules/detect-newline": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz",
@@ -3415,6 +3606,18 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
"peer": true,
"engines": {
"node": ">=0.12"
},
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
},
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -4056,6 +4259,15 @@
"node": ">=4.0"
}
},
"node_modules/estree-walker": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"peer": true,
"dependencies": {
"@types/estree": "^1.0.0"
}
},
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -4073,6 +4285,14 @@
"node": ">=6"
}
},
"node_modules/eventsource-parser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-1.0.0.tgz",
"integrity": "sha512-9jgfSCa3dmEme2ES3mPByGXfgZ87VbP97tng1G2nWwWx6bV2nYxm2AWCrbQjXToSe+yYlqaZNtxffR9IeQr95g==",
"engines": {
"node": ">=14.18"
}
},
"node_modules/execa": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz",
@@ -4936,6 +5156,15 @@
"node": ">=0.10.0"
}
},
"node_modules/is-reference": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.2.tgz",
"integrity": "sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==",
"peer": true,
"dependencies": {
"@types/estree": "*"
}
},
"node_modules/is-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
@@ -6597,6 +6826,12 @@
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"dev": true
},
"node_modules/locate-character": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-character/-/locate-character-3.0.0.tgz",
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==",
"peer": true
},
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -6693,7 +6928,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0"
@@ -6720,6 +6954,18 @@
"lz-string": "bin/bin.js"
}
},
"node_modules/magic-string": {
"version": "0.30.8",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz",
"integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==",
"peer": true,
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.4.15"
},
"engines": {
"node": ">=12"
}
},
"node_modules/make-dir": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
@@ -6750,6 +6996,12 @@
"tmpl": "1.0.5"
}
},
"node_modules/mdn-data": {
"version": "2.0.30",
"resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz",
"integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==",
"peer": true
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
@@ -6765,13 +7017,12 @@
}
},
"node_modules/micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
"braces": "^3.0.2",
"picomatch": "^2.3.1"
},
"engines": {
@@ -6842,6 +7093,23 @@
"node": "^14.17.0 || ^16.13.0 || >=18.0.0"
}
},
"node_modules/nanoid": {
"version": "3.3.6",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -7226,6 +7494,17 @@
"node": ">=8"
}
},
"node_modules/periscopic": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz",
"integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==",
"peer": true,
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^3.0.0",
"is-reference": "^3.0.0"
}
},
"node_modules/picocolors": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
@@ -7316,6 +7595,52 @@
"node": ">=8"
}
},
"node_modules/postcss": {
"version": "8.4.38",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
"integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.0.0",
"source-map-js": "^1.2.0"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/postcss/node_modules/nanoid": {
"version": "3.3.7",
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
"integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"peer": true,
"bin": {
"nanoid": "bin/nanoid.cjs"
},
"engines": {
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
}
},
"node_modules/prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -7376,7 +7701,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"license": "MIT",
"dev": true,
"engines": {
"node": ">=6"
}
@@ -7432,10 +7757,9 @@
]
},
"node_modules/react": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
"license": "MIT",
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
@@ -7444,20 +7768,6 @@
"node": ">=0.10.0"
}
},
"node_modules/react-dom": {
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
},
"peerDependencies": {
"react": "^18.3.1"
}
},
"node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
@@ -7683,16 +7993,6 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/scheduler": {
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
},
"node_modules/semver": {
"version": "7.6.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
@@ -7726,6 +8026,27 @@
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/seroval": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/seroval/-/seroval-1.0.5.tgz",
"integrity": "sha512-TM+Z11tHHvQVQKeNlOUonOWnsNM+2IBwZ4vwoi4j3zKzIpc5IDw8WPwCfcc8F17wy6cBcJGbZbFOR0UCuTZHQA==",
"peer": true,
"engines": {
"node": ">=10"
}
},
"node_modules/seroval-plugins": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.0.5.tgz",
"integrity": "sha512-8+pDC1vOedPXjKG7oz8o+iiHrtF2WswaMQJ7CKFpccvSYfrzmvKY9zOJWCg+881722wIHfwkdnRmiiDm9ym+zQ==",
"peer": true,
"engines": {
"node": ">=10"
},
"peerDependencies": {
"seroval": "^1.0"
}
},
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -7847,6 +8168,29 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"node_modules/solid-js": {
"version": "1.8.16",
"resolved": "https://registry.npmjs.org/solid-js/-/solid-js-1.8.16.tgz",
"integrity": "sha512-rja94MNU9flF3qQRLNsu60QHKBDKBkVE1DldJZPIfn2ypIn3NV2WpSbGTQIvsyGPBo+9E2IMjwqnqpbgfWuzeg==",
"peer": true,
"dependencies": {
"csstype": "^3.1.0",
"seroval": "^1.0.4",
"seroval-plugins": "^1.0.3"
}
},
"node_modules/solid-swr-store": {
"version": "0.10.7",
"resolved": "https://registry.npmjs.org/solid-swr-store/-/solid-swr-store-0.10.7.tgz",
"integrity": "sha512-A6d68aJmRP471aWqKKPE2tpgOiR5fH4qXQNfKIec+Vap+MGQm3tvXlT8n0I8UgJSlNAsSAUuw2VTviH2h3Vv5g==",
"engines": {
"node": ">=10"
},
"peerDependencies": {
"solid-js": "^1.2",
"swr-store": "^0.10"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
@@ -7856,6 +8200,15 @@
"node": ">=0.10.0"
}
},
"node_modules/source-map-js": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
"integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.13",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz",
@@ -7872,6 +8225,17 @@
"integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
"dev": true
},
"node_modules/sswr": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/sswr/-/sswr-2.0.0.tgz",
"integrity": "sha512-mV0kkeBHcjcb0M5NqKtKVg/uTIYNlIIniyDfSGrSfxpEdM9C365jK0z55pl9K0xAkNTJi2OAOVFQpgMPUk+V0w==",
"dependencies": {
"swrev": "^4.0.0"
},
"peerDependencies": {
"svelte": "^4.0.0"
}
},
"node_modules/stack-utils": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz",
@@ -8003,6 +8367,66 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/svelte": {
"version": "4.2.12",
"resolved": "https://registry.npmjs.org/svelte/-/svelte-4.2.12.tgz",
"integrity": "sha512-d8+wsh5TfPwqVzbm4/HCXC783/KPHV60NvwitJnyTA5lWn1elhXMNWhXGCJ7PwPa8qFUnyJNIyuIRt2mT0WMug==",
"peer": true,
"dependencies": {
"@ampproject/remapping": "^2.2.1",
"@jridgewell/sourcemap-codec": "^1.4.15",
"@jridgewell/trace-mapping": "^0.3.18",
"@types/estree": "^1.0.1",
"acorn": "^8.9.0",
"aria-query": "^5.3.0",
"axobject-query": "^4.0.0",
"code-red": "^1.0.3",
"css-tree": "^2.3.1",
"estree-walker": "^3.0.3",
"is-reference": "^3.0.1",
"locate-character": "^3.0.0",
"magic-string": "^0.30.4",
"periscopic": "^3.1.0"
},
"engines": {
"node": ">=16"
}
},
"node_modules/swr": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/swr/-/swr-2.2.0.tgz",
"integrity": "sha512-AjqHOv2lAhkuUdIiBu9xbuettzAzWXmCEcLONNKJRba87WAefz8Ca9d6ds/SzrPc235n1IxWYdhJ2zF3MNUaoQ==",
"dependencies": {
"use-sync-external-store": "^1.2.0"
},
"peerDependencies": {
"react": "^16.11.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/swr-store": {
"version": "0.10.6",
"resolved": "https://registry.npmjs.org/swr-store/-/swr-store-0.10.6.tgz",
"integrity": "sha512-xPjB1hARSiRaNNlUQvWSVrG5SirCjk2TmaUyzzvk69SZQan9hCJqw/5rG9iL7xElHU784GxRPISClq4488/XVw==",
"dependencies": {
"dequal": "^2.0.3"
},
"engines": {
"node": ">=10"
}
},
"node_modules/swrev": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/swrev/-/swrev-4.0.0.tgz",
"integrity": "sha512-LqVcOHSB4cPGgitD1riJ1Hh4vdmITOp+BkmfmXRh4hSF/t7EnS4iD+SOTmq7w5pPm/SiPeto4ADbKS6dHUDWFA=="
},
"node_modules/swrv": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/swrv/-/swrv-1.0.4.tgz",
"integrity": "sha512-zjEkcP8Ywmj+xOJW3lIT65ciY/4AL4e/Or7Gj0MzU3zBJNMdJiT8geVZhINavnlHRMMCcJLHhraLTAiDOTmQ9g==",
"peerDependencies": {
"vue": ">=3.2.26 < 4"
}
},
"node_modules/terminal-columns": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/terminal-columns/-/terminal-columns-1.4.1.tgz",
@@ -8243,7 +8667,7 @@
"version": "4.9.5",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
"dev": true,
"devOptional": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -8312,6 +8736,14 @@
"punycode": "^2.1.0"
}
},
"node_modules/use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
"integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
}
},
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -8345,6 +8777,27 @@
"node": ">=10.12.0"
}
},
"node_modules/vue": {
"version": "3.4.21",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.4.21.tgz",
"integrity": "sha512-5hjyV/jLEIKD/jYl4cavMcnzKwjMKohureP8ejn3hhEjwhWIhWeuzL2kJAjzl/WyVsgPY56Sy4Z40C3lVshxXA==",
"peer": true,
"dependencies": {
"@vue/compiler-dom": "3.4.21",
"@vue/compiler-sfc": "3.4.21",
"@vue/runtime-dom": "3.4.21",
"@vue/server-renderer": "3.4.21",
"@vue/shared": "3.4.21"
},
"peerDependencies": {
"typescript": "*"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",
@@ -8507,15 +8960,6 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod": {
"version": "3.23.8",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz",
"integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "opencommit",
"version": "3.2.4",
"version": "3.1.2",
"description": "Auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
"keywords": [
"git",
@@ -46,9 +46,8 @@
"dev:gemini": "OCO_AI_PROVIDER='gemini' ts-node ./src/cli.ts",
"build": "rimraf out && node esbuild.config.js",
"build:push": "npm run build && git add . && git commit -m 'build' && git push",
"deploy": "npm publish --tag latest",
"deploy:build": "npm run build:push && git push --tags && npm run deploy",
"deploy:patch": "npm version patch && npm run deploy:build",
"deploy": "npm run build:push && git push --tags && npm publish --tag latest",
"deploy:patch": "npm version patch && npm run deploy",
"lint": "eslint src --ext ts && tsc --noEmit",
"format": "prettier --write src",
"test": "node --no-warnings --experimental-vm-modules $( [ -f ./node_modules/.bin/jest ] && echo ./node_modules/.bin/jest || which jest ) test/unit",
@@ -58,8 +57,7 @@
"test:unit:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:unit",
"test:e2e": "npm run test:e2e:setup && jest test/e2e",
"test:e2e:setup": "sh test/e2e/setup.sh",
"test:e2e:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:e2e",
"mlx:start": "OCO_AI_PROVIDER='mlx' node ./out/cli.cjs"
"test:e2e:docker": "npm run test:docker-build && DOCKER_CONTENT_TRUST=0 docker run --rm oco-test npm run test:e2e"
},
"devDependencies": {
"@commitlint/types": "^17.4.4",
@@ -88,7 +86,6 @@
"@clack/prompts": "^0.6.1",
"@dqbd/tiktoken": "^1.0.2",
"@google/generative-ai": "^0.11.4",
"@mistralai/mistralai": "^1.3.5",
"@octokit/webhooks-schemas": "^6.11.0",
"@octokit/webhooks-types": "^6.11.0",
"axios": "^1.3.4",
@@ -99,8 +96,6 @@
"ignore": "^5.2.4",
"ini": "^3.0.1",
"inquirer": "^9.1.4",
"openai": "^4.57.0",
"punycode": "^2.3.1",
"zod": "^3.23.8"
"openai": "^4.57.0"
}
}

View File

@@ -20,12 +20,6 @@ cli(
commands: [configCommand, hookCommand, commitlintConfigCommand],
flags: {
fgm: Boolean,
context: {
type: String,
alias: 'c',
description: 'Additional user input context for the commit message',
default: ''
},
yes: {
type: Boolean,
alias: 'y',
@@ -43,7 +37,7 @@ cli(
if (await isHookCalled()) {
prepareCommitMessageHook();
} else {
commit(extraArgs, flags.context, false, flags.fgm, flags.yes);
commit(extraArgs, false, flags.fgm, flags.yes);
}
},
extraArgs

View File

@@ -39,7 +39,6 @@ const checkMessageTemplate = (extraArgs: string[]): string | false => {
interface GenerateCommitMessageFromGitDiffParams {
diff: string;
extraArgs: string[];
context?: string;
fullGitMojiSpec?: boolean;
skipCommitConfirmation?: boolean;
}
@@ -47,7 +46,6 @@ interface GenerateCommitMessageFromGitDiffParams {
const generateCommitMessageFromGitDiff = async ({
diff,
extraArgs,
context = '',
fullGitMojiSpec = false,
skipCommitConfirmation = false
}: GenerateCommitMessageFromGitDiffParams): Promise<void> => {
@@ -58,8 +56,7 @@ const generateCommitMessageFromGitDiff = async ({
try {
let commitMessage = await generateCommitMessageByDiff(
diff,
fullGitMojiSpec,
context
fullGitMojiSpec
);
const messageTemplate = checkMessageTemplate(extraArgs);
@@ -138,7 +135,8 @@ ${chalk.grey('——————————————————')}`
]);
pushSpinner.stop(
`${chalk.green('✔')} Successfully pushed all commits to ${remotes[0]
`${chalk.green('✔')} Successfully pushed all commits to ${
remotes[0]
}`
);
@@ -148,29 +146,26 @@ ${chalk.grey('——————————————————')}`
process.exit(0);
}
} else {
const skipOption = `don't push`
const selectedRemote = (await select({
message: 'Choose a remote to push to',
options: [...remotes, skipOption].map((remote) => ({ value: remote, label: remote })),
options: remotes.map((remote) => ({ value: remote, label: remote }))
})) as string;
if (isCancel(selectedRemote)) process.exit(1);
if (selectedRemote !== skipOption) {
const pushSpinner = spinner();
pushSpinner.start(`Running 'git push ${selectedRemote}'`);
const { stdout } = await execa('git', ['push', selectedRemote]);
if (stdout) outro(stdout);
pushSpinner.stop(
`${chalk.green(
'✔'
)} successfully pushed all commits to ${selectedRemote}`
);
}
const pushSpinner = spinner();
pushSpinner.start(`Running 'git push ${selectedRemote}'`);
const { stdout } = await execa('git', ['push', selectedRemote]);
if (stdout) outro(stdout);
pushSpinner.stop(
`${chalk.green(
'✔'
)} successfully pushed all commits to ${selectedRemote}`
);
}
} else {
const regenerateMessage = await confirm({
@@ -188,11 +183,7 @@ ${chalk.grey('——————————————————')}`
}
}
} catch (error) {
commitGenerationSpinner.stop(
`${chalk.red('✖')} Failed to generate the commit message`
);
console.log(error);
commitGenerationSpinner.stop('📝 Commit message generated');
const err = error as Error;
outro(`${chalk.red('✖')} ${err?.message || err}`);
@@ -202,7 +193,6 @@ ${chalk.grey('——————————————————')}`
export async function commit(
extraArgs: string[] = [],
context: string = '',
isStageAllFlag: Boolean = false,
fullGitMojiSpec: boolean = false,
skipCommitConfirmation: boolean = false
@@ -244,7 +234,7 @@ export async function commit(
if (isCancel(isStageAllAndCommitConfirmedByUser)) process.exit(1);
if (isStageAllAndCommitConfirmedByUser) {
await commit(extraArgs, context, true, fullGitMojiSpec);
await commit(extraArgs, true, fullGitMojiSpec);
process.exit(1);
}
@@ -262,7 +252,7 @@ export async function commit(
await gitAdd({ files });
}
await commit(extraArgs, context, false, fullGitMojiSpec);
await commit(extraArgs, false, fullGitMojiSpec);
process.exit(1);
}
@@ -276,7 +266,6 @@ export async function commit(
generateCommitMessageFromGitDiff({
diff: await getDiff({ files: stagedFiles }),
extraArgs,
context,
fullGitMojiSpec,
skipCommitConfirmation
})

View File

@@ -76,58 +76,6 @@ export const MODEL_LIST = {
'gemini-1.0-pro',
'gemini-pro-vision',
'text-embedding-004'
],
groq: [
'llama3-70b-8192', // Meta Llama 3 70B (default one, no daily token limit and 14 400 reqs/day)
'llama3-8b-8192', // Meta Llama 3 8B
'llama-guard-3-8b', // Llama Guard 3 8B
'llama-3.1-8b-instant', // Llama 3.1 8B (Preview)
'llama-3.1-70b-versatile', // Llama 3.1 70B (Preview)
'gemma-7b-it', // Gemma 7B
'gemma2-9b-it' // Gemma 2 9B
],
mistral: [
'ministral-3b-2410',
'ministral-3b-latest',
'ministral-8b-2410',
'ministral-8b-latest',
'open-mistral-7b',
'mistral-tiny',
'mistral-tiny-2312',
'open-mistral-nemo',
'open-mistral-nemo-2407',
'mistral-tiny-2407',
'mistral-tiny-latest',
'open-mixtral-8x7b',
'mistral-small',
'mistral-small-2312',
'open-mixtral-8x22b',
'open-mixtral-8x22b-2404',
'mistral-small-2402',
'mistral-small-2409',
'mistral-small-latest',
'mistral-medium-2312',
'mistral-medium',
'mistral-medium-latest',
'mistral-large-2402',
'mistral-large-2407',
'mistral-large-2411',
'mistral-large-latest',
'pixtral-large-2411',
'pixtral-large-latest',
'codestral-2405',
'codestral-latest',
'codestral-mamba-2407',
'open-codestral-mamba',
'codestral-mamba-latest',
'pixtral-12b-2409',
'pixtral-12b',
'pixtral-12b-latest',
'mistral-embed',
'mistral-moderation-2411',
'mistral-moderation-latest',
]
};
@@ -135,16 +83,10 @@ const getDefaultModel = (provider: string | undefined): string => {
switch (provider) {
case 'ollama':
return '';
case 'mlx':
return '';
case 'anthropic':
return MODEL_LIST.anthropic[0];
case 'gemini':
return MODEL_LIST.gemini[0];
case 'groq':
return MODEL_LIST.groq[0];
case 'mistral':
return MODEL_LIST.mistral[0];
default:
return MODEL_LIST.openai[0];
}
@@ -184,7 +126,7 @@ export const configValidators = {
validateConfig(
'OCO_API_KEY',
value,
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
'You need to provide the OCO_API_KEY when OCO_AI_PROVIDER set to "openai" (default) or "ollama" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
);
return value;
@@ -299,17 +241,10 @@ export const configValidators = {
validateConfig(
CONFIG_KEYS.OCO_AI_PROVIDER,
[
'openai',
'mistral',
'anthropic',
'gemini',
'azure',
'test',
'flowise',
'groq'
].includes(value) || value.startsWith('ollama'),
`${value} is not supported yet, use 'ollama', 'mlx', 'anthropic', 'azure', 'gemini', 'flowise', 'mistral' or 'openai' (default)`
['openai', 'anthropic', 'gemini', 'azure', 'test', 'flowise'].includes(
value
) || value.startsWith('ollama'),
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
);
return value;
@@ -353,10 +288,7 @@ export enum OCO_AI_PROVIDER_ENUM {
GEMINI = 'gemini',
AZURE = 'azure',
TEST = 'test',
FLOWISE = 'flowise',
GROQ = 'groq',
MISTRAL = 'mistral',
MLX = 'mlx'
FLOWISE = 'flowise'
}
export type ConfigType = {
@@ -420,6 +352,7 @@ export const DEFAULT_CONFIG = {
OCO_AI_PROVIDER: OCO_AI_PROVIDER_ENUM.OPENAI,
OCO_ONE_LINE_COMMIT: false,
OCO_TEST_MOCK_TYPE: 'commit-message',
OCO_FLOWISE_ENDPOINT: ':',
OCO_WHY: false,
OCO_GITPUSH: true // todo: deprecate
};
@@ -511,25 +444,6 @@ interface GetConfigOptions {
setDefaultValues?: boolean;
}
const cleanUndefinedValues = (config: ConfigType) => {
return Object.fromEntries(
Object.entries(config).map(([_, v]) => {
try {
if (typeof v === 'string') {
if (v === 'undefined') return [_, undefined];
if (v === 'null') return [_, null];
const parsedValue = JSON.parse(v);
return [_, parsedValue];
}
return [_, v];
} catch (error) {
return [_, v];
}
})
);
};
export const getConfig = ({
envPath = defaultEnvPath,
globalPath = defaultConfigPath
@@ -539,9 +453,7 @@ export const getConfig = ({
const config = mergeConfigs(envConfig, globalConfig);
const cleanConfig = cleanUndefinedValues(config);
return cleanConfig as ConfigType;
return config;
};
export const setConfig = (

View File

@@ -3,7 +3,6 @@ import { OpenAIClient as AzureOpenAIClient } from '@azure/openai';
import { GoogleGenerativeAI as GeminiClient } from '@google/generative-ai';
import { AxiosInstance as RawAxiosClient } from 'axios';
import { OpenAI as OpenAIClient } from 'openai';
import { Mistral as MistralClient } from '@mistralai/mistralai';
export interface AiEngineConfig {
apiKey: string;
@@ -18,8 +17,7 @@ type Client =
| AzureOpenAIClient
| AnthropicClient
| RawAxiosClient
| GeminiClient
| MistralClient;
| GeminiClient;
export interface AiEngine {
config: AiEngineConfig;

View File

@@ -1,10 +0,0 @@
import { OpenAiConfig, OpenAiEngine } from './openAi';
interface GroqConfig extends OpenAiConfig {}
export class GroqEngine extends OpenAiEngine {
constructor(config: GroqConfig) {
config.baseURL = 'https://api.groq.com/openai/v1';
super(config);
}
}

View File

@@ -1,82 +0,0 @@
import axios from 'axios';
import { Mistral } from '@mistralai/mistralai';
import { OpenAI } from 'openai';
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
import { tokenCount } from '../utils/tokenCount';
import { AiEngine, AiEngineConfig } from './Engine';
import {
AssistantMessage as MistralAssistantMessage,
SystemMessage as MistralSystemMessage,
ToolMessage as MistralToolMessage,
UserMessage as MistralUserMessage
} from '@mistralai/mistralai/models/components';
export interface MistralAiConfig extends AiEngineConfig {}
export type MistralCompletionMessageParam = Array<
| (MistralSystemMessage & { role: "system" })
| (MistralUserMessage & { role: "user" })
| (MistralAssistantMessage & { role: "assistant" })
| (MistralToolMessage & { role: "tool" })
>
export class MistralAiEngine implements AiEngine {
config: MistralAiConfig;
client: Mistral;
constructor(config: MistralAiConfig) {
this.config = config;
if (!config.baseURL) {
this.client = new Mistral({ apiKey: config.apiKey });
} else {
this.client = new Mistral({ apiKey: config.apiKey, serverURL: config.baseURL });
}
}
public generateCommitMessage = async (
messages: Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>
): Promise<string | null> => {
const params = {
model: this.config.model,
messages: messages as MistralCompletionMessageParam,
topP: 0.1,
maxTokens: this.config.maxTokensOutput
};
try {
const REQUEST_TOKENS = messages
.map((msg) => tokenCount(msg.content as string) + 4)
.reduce((a, b) => a + b, 0);
if (
REQUEST_TOKENS >
this.config.maxTokensInput - this.config.maxTokensOutput
)
throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens);
const completion = await this.client.chat.complete(params);
if (!completion.choices)
throw Error('No completion choice available.')
const message = completion.choices[0].message;
if (!message || !message.content)
throw Error('No completion choice available.')
return message.content as string;
} catch (error) {
const err = error as Error;
if (
axios.isAxiosError<{ error?: { message: string } }>(error) &&
error.response?.status === 401
) {
const mistralError = error.response.data.error;
if (mistralError) throw new Error(mistralError.message);
}
throw err;
}
};
}

View File

@@ -1,47 +0,0 @@
import axios, { AxiosInstance } from 'axios';
import { OpenAI } from 'openai';
import { AiEngine, AiEngineConfig } from './Engine';
import { chown } from 'fs';
interface MLXConfig extends AiEngineConfig {}
export class MLXEngine implements AiEngine {
config: MLXConfig;
client: AxiosInstance;
constructor(config) {
this.config = config;
this.client = axios.create({
url: config.baseURL
? `${config.baseURL}/${config.apiKey}`
: 'http://localhost:8080/v1/chat/completions',
headers: { 'Content-Type': 'application/json' }
});
}
async generateCommitMessage(
messages: Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>):
Promise<string | undefined> {
const params = {
messages,
temperature: 0,
top_p: 0.1,
repetition_penalty: 1.5,
stream: false
};
try {
const response = await this.client.post(
this.client.getUri(this.config),
params
);
const choices = response.data.choices;
const message = choices[0].message;
return message?.content;
} catch (err: any) {
const message = err.response?.data?.error ?? err.message;
throw new Error(`MLX provider error: ${message}`);
}
}
}

View File

@@ -4,7 +4,7 @@ import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitD
import { tokenCount } from '../utils/tokenCount';
import { AiEngine, AiEngineConfig } from './Engine';
export interface OpenAiConfig extends AiEngineConfig {}
interface OpenAiConfig extends AiEngineConfig {}
export class OpenAiEngine implements AiEngine {
config: OpenAiConfig;
@@ -12,12 +12,7 @@ export class OpenAiEngine implements AiEngine {
constructor(config: OpenAiConfig) {
this.config = config;
if (!config.baseURL) {
this.client = new OpenAI({ apiKey: config.apiKey });
} else {
this.client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL });
}
this.client = new OpenAI({ apiKey: config.apiKey });
}
public generateCommitMessage = async (

View File

@@ -11,10 +11,9 @@ const MAX_TOKENS_OUTPUT = config.OCO_TOKENS_MAX_OUTPUT;
const generateCommitMessageChatCompletionPrompt = async (
diff: string,
fullGitMojiSpec: boolean,
context: string
fullGitMojiSpec: boolean
): Promise<Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>> => {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context);
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
@@ -37,14 +36,10 @@ const ADJUSTMENT_FACTOR = 20;
export const generateCommitMessageByDiff = async (
diff: string,
fullGitMojiSpec: boolean = false,
context: string = ""
fullGitMojiSpec: boolean = false
): Promise<string> => {
try {
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
fullGitMojiSpec,
context
);
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
(msg) => tokenCount(msg.content as string) + 4
@@ -74,8 +69,7 @@ export const generateCommitMessageByDiff = async (
const messages = await generateCommitMessageChatCompletionPrompt(
diff,
fullGitMojiSpec,
context,
fullGitMojiSpec
);
const engine = getEngine();

View File

@@ -10,12 +10,10 @@ export default function () {
const entriesToSet: [key: string, value: string | boolean | number][] = [];
for (const entry of Object.entries(DEFAULT_CONFIG)) {
const [key, _value] = entry;
if (config[key] === 'undefined' || config[key] === undefined)
entriesToSet.push(entry);
if (config[key] === 'undefined') entriesToSet.push(entry);
}
if (entriesToSet.length > 0) setConfig(entriesToSet);
console.log(entriesToSet);
};
setDefaultConfigValues(getGlobalConfig());

View File

@@ -53,7 +53,6 @@ export const runMigrations = async () => {
migration.name
}: ${error}`
);
process.exit(1);
}
isMigrated = true;

View File

@@ -111,24 +111,9 @@ const getOneLineCommitInstruction = () =>
? 'Craft a concise commit message that encapsulates all changes made, with an emphasis on the primary updates. If the modifications share a common theme or scope, mention it succinctly; otherwise, leave the scope out to maintain focus. The goal is to provide a clear and unified overview of the changes in a one single message, without diverging into a list of commit per file change.'
: '';
/**
* Get the context of the user input
* @param extraArgs - The arguments passed to the command line
* @example
* $ oco -- This is a context used to generate the commit message
* @returns - The context of the user input
*/
const userInputCodeContext = (context: string) => {
if (context !== '' && context !== ' ') {
return `Additional context provided by the user: <context>${context}</context>\nConsider this context when generating the commit message, incorporating relevant information when appropriate.`;
}
return '';
};
const INIT_MAIN_PROMPT = (
language: string,
fullGitMojiSpec: boolean,
context: string
fullGitMojiSpec: boolean
): OpenAI.Chat.Completions.ChatCompletionMessageParam => ({
role: 'system',
content: (() => {
@@ -142,16 +127,15 @@ const INIT_MAIN_PROMPT = (
const descriptionGuideline = getDescriptionInstruction();
const oneLineCommitGuideline = getOneLineCommitInstruction();
const generalGuidelines = `Use the present tense. Lines must not be longer than 74 characters. Use ${language} for the commit message.`;
const userInputContext = userInputCodeContext(context);
return `${missionStatement}\n${diffInstruction}\n${conventionGuidelines}\n${descriptionGuideline}\n${oneLineCommitGuideline}\n${generalGuidelines}\n${userInputContext}`;
return `${missionStatement}\n${diffInstruction}\n${conventionGuidelines}\n${descriptionGuideline}\n${oneLineCommitGuideline}\n${generalGuidelines}`;
})()
});
export const INIT_DIFF_PROMPT: OpenAI.Chat.Completions.ChatCompletionMessageParam =
{
role: 'user',
content: `diff --git a/src/server.ts b/src/server.ts
{
role: 'user',
content: `diff --git a/src/server.ts b/src/server.ts
index ad4db42..f3b18a9 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -175,7 +159,7 @@ export const INIT_DIFF_PROMPT: OpenAI.Chat.Completions.ChatCompletionMessagePara
+app.listen(process.env.PORT || PORT, () => {
+ console.log(\`Server listening on port \${PORT}\`);
});`
};
};
const getContent = (translation: ConsistencyPrompt) => {
const fix = config.OCO_EMOJI
@@ -201,8 +185,7 @@ const INIT_CONSISTENCY_PROMPT = (
});
export const getMainCommitPrompt = async (
fullGitMojiSpec: boolean,
context: string
fullGitMojiSpec: boolean
): Promise<Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>> => {
switch (config.OCO_PROMPT_MODULE) {
case '@commitlint':
@@ -224,14 +207,14 @@ export const getMainCommitPrompt = async (
INIT_DIFF_PROMPT,
INIT_CONSISTENCY_PROMPT(
commitLintConfig.consistency[
translation.localLanguage
translation.localLanguage
] as ConsistencyPrompt
)
];
default:
return [
INIT_MAIN_PROMPT(translation.localLanguage, fullGitMojiSpec, context),
INIT_MAIN_PROMPT(translation.localLanguage, fullGitMojiSpec),
INIT_DIFF_PROMPT,
INIT_CONSISTENCY_PROMPT(translation)
];

View File

@@ -6,10 +6,7 @@ import { FlowiseEngine } from '../engine/flowise';
import { GeminiEngine } from '../engine/gemini';
import { OllamaEngine } from '../engine/ollama';
import { OpenAiEngine } from '../engine/openAi';
import { MistralAiEngine } from '../engine/mistral';
import { TestAi, TestMockType } from '../engine/testAi';
import { GroqEngine } from '../engine/groq';
import { MLXEngine } from '../engine/mlx';
export function getEngine(): AiEngine {
const config = getConfig();
@@ -42,15 +39,6 @@ export function getEngine(): AiEngine {
case OCO_AI_PROVIDER_ENUM.FLOWISE:
return new FlowiseEngine(DEFAULT_CONFIG);
case OCO_AI_PROVIDER_ENUM.GROQ:
return new GroqEngine(DEFAULT_CONFIG);
case OCO_AI_PROVIDER_ENUM.MISTRAL:
return new MistralAiEngine(DEFAULT_CONFIG);
case OCO_AI_PROVIDER_ENUM.MLX:
return new MLXEngine(DEFAULT_CONFIG);
default:
return new OpenAiEngine(DEFAULT_CONFIG);
}