mirror of
https://github.com/di-sukharev/opencommit.git
synced 2026-01-13 07:38:01 -05:00
Compare commits
6 Commits
fix_migrat
...
v3.2.4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
98afbe21ea | ||
|
|
041465a81c | ||
|
|
40fa275b4f | ||
|
|
6f16191af2 | ||
|
|
25105e4c3a | ||
|
|
2769121842 |
4
.github/CONTRIBUTING.md
vendored
4
.github/CONTRIBUTING.md
vendored
@@ -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/open-commit/issues) or [TODO.md](../TODO.md) to help the project.
|
||||
4. See [issues](https://github.com/di-sukharev/opencommit/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/open-commit/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/opencommit/issues) on the GitHub issue tracker.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
106
out/cli.cjs
106
out/cli.cjs
@@ -431,8 +431,8 @@ var require_escape = __commonJS({
|
||||
}
|
||||
function escapeArgument(arg, doubleEscapeMetaChars) {
|
||||
arg = `${arg}`;
|
||||
arg = arg.replace(/(\\*)"/g, '$1$1\\"');
|
||||
arg = arg.replace(/(\\*)$/, "$1$1");
|
||||
arg = arg.replace(/(?=(\\+?)?)\1"/g, '$1$1\\"');
|
||||
arg = arg.replace(/(?=(\\+?)?)\1$/, "$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, "spawn");
|
||||
const err = verifyENOENT(arg1, parsed);
|
||||
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";
|
||||
var punycode = require("punycode");
|
||||
const 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";
|
||||
var punycode = require("punycode");
|
||||
const punycode = require('punycode/');
|
||||
var tr46 = require_tr46();
|
||||
var specialSchemes = {
|
||||
ftp: 21,
|
||||
@@ -27389,7 +27389,8 @@ 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"
|
||||
"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"
|
||||
},
|
||||
devDependencies: {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
@@ -29933,6 +29934,8 @@ var getDefaultModel = (provider) => {
|
||||
switch (provider) {
|
||||
case "ollama":
|
||||
return "";
|
||||
case "mlx":
|
||||
return "";
|
||||
case "anthropic":
|
||||
return MODEL_LIST.anthropic[0];
|
||||
case "gemini":
|
||||
@@ -29964,7 +29967,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 "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 "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
|
||||
);
|
||||
return value;
|
||||
},
|
||||
@@ -30070,8 +30073,8 @@ var configValidators = {
|
||||
"test",
|
||||
"flowise",
|
||||
"groq"
|
||||
].includes(value) || value.startsWith("ollama"),
|
||||
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||
].includes(value) || value.startsWith("ollama") || value.startsWith("mlx"),
|
||||
`${value} is not supported yet, use 'ollama', 'mlx', anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||
);
|
||||
return value;
|
||||
},
|
||||
@@ -30111,6 +30114,7 @@ var OCO_AI_PROVIDER_ENUM = /* @__PURE__ */ ((OCO_AI_PROVIDER_ENUM2) => {
|
||||
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");
|
||||
@@ -44524,6 +44528,38 @@ var GroqEngine = class extends OpenAiEngine {
|
||||
}
|
||||
};
|
||||
|
||||
// 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}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// src/utils/engine.ts
|
||||
function getEngine() {
|
||||
const config7 = getConfig();
|
||||
@@ -44550,6 +44586,8 @@ function getEngine() {
|
||||
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);
|
||||
}
|
||||
@@ -44931,7 +44969,14 @@ 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 INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
|
||||
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) => ({
|
||||
role: "system",
|
||||
content: (() => {
|
||||
const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention";
|
||||
@@ -44941,12 +44986,14 @@ var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
|
||||
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}`;
|
||||
${generalGuidelines}
|
||||
${userInputContext}`;
|
||||
})()
|
||||
});
|
||||
var INIT_DIFF_PROMPT = {
|
||||
@@ -44988,7 +45035,7 @@ var INIT_CONSISTENCY_PROMPT = (translation4) => ({
|
||||
role: "assistant",
|
||||
content: getContent(translation4)
|
||||
});
|
||||
var getMainCommitPrompt = async (fullGitMojiSpec) => {
|
||||
var getMainCommitPrompt = async (fullGitMojiSpec, context) => {
|
||||
switch (config4.OCO_PROMPT_MODULE) {
|
||||
case "@commitlint":
|
||||
if (!await commitlintLLMConfigExists()) {
|
||||
@@ -45010,7 +45057,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec) => {
|
||||
];
|
||||
default:
|
||||
return [
|
||||
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec),
|
||||
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec, context),
|
||||
INIT_DIFF_PROMPT,
|
||||
INIT_CONSISTENCY_PROMPT(translation3)
|
||||
];
|
||||
@@ -45037,8 +45084,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) => {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec, context) => {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context);
|
||||
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
|
||||
chatContextAsCompletionRequest.push({
|
||||
role: "user",
|
||||
@@ -45054,9 +45101,12 @@ var GenerateCommitMessageErrorEnum = ((GenerateCommitMessageErrorEnum2) => {
|
||||
return GenerateCommitMessageErrorEnum2;
|
||||
})(GenerateCommitMessageErrorEnum || {});
|
||||
var ADJUSTMENT_FACTOR = 20;
|
||||
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
|
||||
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context = "") => {
|
||||
try {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
|
||||
fullGitMojiSpec,
|
||||
context
|
||||
);
|
||||
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
|
||||
(msg) => tokenCount(msg.content) + 4
|
||||
).reduce((a4, b7) => a4 + b7, 0);
|
||||
@@ -45076,7 +45126,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
|
||||
}
|
||||
const messages = await generateCommitMessageChatCompletionPrompt(
|
||||
diff,
|
||||
fullGitMojiSpec
|
||||
fullGitMojiSpec,
|
||||
context
|
||||
);
|
||||
const engine = getEngine();
|
||||
const commitMessage = await engine.generateCommitMessage(messages);
|
||||
@@ -45283,6 +45334,7 @@ var checkMessageTemplate = (extraArgs2) => {
|
||||
var generateCommitMessageFromGitDiff = async ({
|
||||
diff,
|
||||
extraArgs: extraArgs2,
|
||||
context = "",
|
||||
fullGitMojiSpec = false,
|
||||
skipCommitConfirmation = false
|
||||
}) => {
|
||||
@@ -45292,7 +45344,8 @@ var generateCommitMessageFromGitDiff = async ({
|
||||
try {
|
||||
let commitMessage = await generateCommitMessageByDiff(
|
||||
diff,
|
||||
fullGitMojiSpec
|
||||
fullGitMojiSpec,
|
||||
context
|
||||
);
|
||||
const messageTemplate = checkMessageTemplate(extraArgs2);
|
||||
if (config6.OCO_MESSAGE_TEMPLATE_PLACEHOLDER && typeof messageTemplate === "string") {
|
||||
@@ -45402,7 +45455,7 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2
|
||||
process.exit(1);
|
||||
}
|
||||
};
|
||||
async function commit(extraArgs2 = [], isStageAllFlag = false, fullGitMojiSpec = false, skipCommitConfirmation = false) {
|
||||
async function commit(extraArgs2 = [], context = "", isStageAllFlag = false, fullGitMojiSpec = false, skipCommitConfirmation = false) {
|
||||
if (isStageAllFlag) {
|
||||
const changedFiles2 = await getChangedFiles();
|
||||
if (changedFiles2)
|
||||
@@ -45433,7 +45486,7 @@ async function commit(extraArgs2 = [], isStageAllFlag = false, fullGitMojiSpec =
|
||||
if (hD2(isStageAllAndCommitConfirmedByUser))
|
||||
process.exit(1);
|
||||
if (isStageAllAndCommitConfirmedByUser) {
|
||||
await commit(extraArgs2, true, fullGitMojiSpec);
|
||||
await commit(extraArgs2, context, true, fullGitMojiSpec);
|
||||
process.exit(1);
|
||||
}
|
||||
if (stagedFiles.length === 0 && changedFiles.length > 0) {
|
||||
@@ -45448,7 +45501,7 @@ async function commit(extraArgs2 = [], isStageAllFlag = false, fullGitMojiSpec =
|
||||
process.exit(1);
|
||||
await gitAdd({ files });
|
||||
}
|
||||
await commit(extraArgs2, false, fullGitMojiSpec);
|
||||
await commit(extraArgs2, context, false, fullGitMojiSpec);
|
||||
process.exit(1);
|
||||
}
|
||||
stagedFilesSpinner.stop(
|
||||
@@ -45459,6 +45512,7 @@ ${stagedFiles.map((file) => ` ${file}`).join("\n")}`
|
||||
generateCommitMessageFromGitDiff({
|
||||
diff: await getDiff({ files: stagedFiles }),
|
||||
extraArgs: extraArgs2,
|
||||
context,
|
||||
fullGitMojiSpec,
|
||||
skipCommitConfirmation
|
||||
})
|
||||
@@ -45817,6 +45871,12 @@ 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",
|
||||
@@ -45833,7 +45893,7 @@ Z2(
|
||||
if (await isHookCalled()) {
|
||||
prepareCommitMessageHook();
|
||||
} else {
|
||||
commit(extraArgs, false, flags.fgm, flags.yes);
|
||||
commit(extraArgs, flags.context, false, flags.fgm, flags.yes);
|
||||
}
|
||||
},
|
||||
extraArgs
|
||||
|
||||
@@ -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";
|
||||
var punycode = require("punycode");
|
||||
const 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";
|
||||
var punycode = require("punycode");
|
||||
const punycode = require('punycode/');
|
||||
var tr46 = require_tr46();
|
||||
var specialSchemes = {
|
||||
ftp: 21,
|
||||
@@ -48745,6 +48745,8 @@ var getDefaultModel = (provider) => {
|
||||
switch (provider) {
|
||||
case "ollama":
|
||||
return "";
|
||||
case "mlx":
|
||||
return "";
|
||||
case "anthropic":
|
||||
return MODEL_LIST.anthropic[0];
|
||||
case "gemini":
|
||||
@@ -48776,7 +48778,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 "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 "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
|
||||
);
|
||||
return value;
|
||||
},
|
||||
@@ -48882,8 +48884,8 @@ var configValidators = {
|
||||
"test",
|
||||
"flowise",
|
||||
"groq"
|
||||
].includes(value) || value.startsWith("ollama"),
|
||||
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||
].includes(value) || value.startsWith("ollama") || value.startsWith("mlx"),
|
||||
`${value} is not supported yet, use 'ollama', 'mlx', anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||
);
|
||||
return value;
|
||||
},
|
||||
@@ -63325,6 +63327,38 @@ var GroqEngine = class extends OpenAiEngine {
|
||||
}
|
||||
};
|
||||
|
||||
// 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}`);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// src/utils/engine.ts
|
||||
function getEngine() {
|
||||
const config6 = getConfig();
|
||||
@@ -63351,6 +63385,8 @@ function getEngine() {
|
||||
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);
|
||||
}
|
||||
@@ -63732,7 +63768,14 @@ 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 INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
|
||||
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) => ({
|
||||
role: "system",
|
||||
content: (() => {
|
||||
const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention";
|
||||
@@ -63742,12 +63785,14 @@ var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({
|
||||
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}`;
|
||||
${generalGuidelines}
|
||||
${userInputContext}`;
|
||||
})()
|
||||
});
|
||||
var INIT_DIFF_PROMPT = {
|
||||
@@ -63789,7 +63834,7 @@ var INIT_CONSISTENCY_PROMPT = (translation4) => ({
|
||||
role: "assistant",
|
||||
content: getContent(translation4)
|
||||
});
|
||||
var getMainCommitPrompt = async (fullGitMojiSpec) => {
|
||||
var getMainCommitPrompt = async (fullGitMojiSpec, context2) => {
|
||||
switch (config4.OCO_PROMPT_MODULE) {
|
||||
case "@commitlint":
|
||||
if (!await commitlintLLMConfigExists()) {
|
||||
@@ -63811,7 +63856,7 @@ var getMainCommitPrompt = async (fullGitMojiSpec) => {
|
||||
];
|
||||
default:
|
||||
return [
|
||||
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec),
|
||||
INIT_MAIN_PROMPT2(translation3.localLanguage, fullGitMojiSpec, context2),
|
||||
INIT_DIFF_PROMPT,
|
||||
INIT_CONSISTENCY_PROMPT(translation3)
|
||||
];
|
||||
@@ -63838,8 +63883,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) => {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
var generateCommitMessageChatCompletionPrompt = async (diff, fullGitMojiSpec, context2) => {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context2);
|
||||
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
|
||||
chatContextAsCompletionRequest.push({
|
||||
role: "user",
|
||||
@@ -63855,9 +63900,12 @@ var GenerateCommitMessageErrorEnum = ((GenerateCommitMessageErrorEnum2) => {
|
||||
return GenerateCommitMessageErrorEnum2;
|
||||
})(GenerateCommitMessageErrorEnum || {});
|
||||
var ADJUSTMENT_FACTOR = 20;
|
||||
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
|
||||
var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false, context2 = "") => {
|
||||
try {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
|
||||
fullGitMojiSpec,
|
||||
context2
|
||||
);
|
||||
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
|
||||
(msg) => tokenCount(msg.content) + 4
|
||||
).reduce((a3, b3) => a3 + b3, 0);
|
||||
@@ -63877,7 +63925,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => {
|
||||
}
|
||||
const messages = await generateCommitMessageChatCompletionPrompt(
|
||||
diff,
|
||||
fullGitMojiSpec
|
||||
fullGitMojiSpec,
|
||||
context2
|
||||
);
|
||||
const engine = getEngine();
|
||||
const commitMessage = await engine.generateCommitMessage(messages);
|
||||
|
||||
592
package-lock.json
generated
592
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.4",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "opencommit",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.4",
|
||||
"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,7 +28,9 @@
|
||||
"ignore": "^5.2.4",
|
||||
"ini": "^3.0.1",
|
||||
"inquirer": "^9.1.4",
|
||||
"openai": "^4.57.0"
|
||||
"openai": "^4.57.0",
|
||||
"punycode": "^2.3.1",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
"bin": {
|
||||
"oco": "out/cli.cjs",
|
||||
@@ -108,6 +110,7 @@
|
||||
"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"
|
||||
@@ -574,6 +577,7 @@
|
||||
"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"
|
||||
},
|
||||
@@ -1728,6 +1732,7 @@
|
||||
"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",
|
||||
@@ -1741,6 +1746,7 @@
|
||||
"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"
|
||||
}
|
||||
@@ -1749,6 +1755,7 @@
|
||||
"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"
|
||||
}
|
||||
@@ -1756,12 +1763,14 @@
|
||||
"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=="
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true
|
||||
},
|
||||
"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"
|
||||
@@ -1778,6 +1787,16 @@
|
||||
"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",
|
||||
@@ -2013,12 +2032,6 @@
|
||||
"@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",
|
||||
@@ -2333,117 +2346,6 @@
|
||||
"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",
|
||||
@@ -2459,6 +2361,7 @@
|
||||
"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"
|
||||
},
|
||||
@@ -2506,43 +2409,6 @@
|
||||
"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",
|
||||
@@ -2629,15 +2495,6 @@
|
||||
"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",
|
||||
@@ -2671,15 +2528,6 @@
|
||||
"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",
|
||||
@@ -3256,19 +3104,6 @@
|
||||
"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",
|
||||
@@ -3390,9 +3225,10 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.3",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||
"integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -3408,25 +3244,6 @@
|
||||
"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",
|
||||
@@ -3512,14 +3329,6 @@
|
||||
"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",
|
||||
@@ -3606,18 +3415,6 @@
|
||||
"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",
|
||||
@@ -4259,15 +4056,6 @@
|
||||
"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",
|
||||
@@ -4285,14 +4073,6 @@
|
||||
"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",
|
||||
@@ -5156,15 +4936,6 @@
|
||||
"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",
|
||||
@@ -6826,12 +6597,6 @@
|
||||
"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",
|
||||
@@ -6928,6 +6693,7 @@
|
||||
"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"
|
||||
@@ -6954,18 +6720,6 @@
|
||||
"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",
|
||||
@@ -6996,12 +6750,6 @@
|
||||
"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",
|
||||
@@ -7017,12 +6765,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
|
||||
"integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
|
||||
"version": "4.0.8",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"braces": "^3.0.2",
|
||||
"braces": "^3.0.3",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -7093,23 +6842,6 @@
|
||||
"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",
|
||||
@@ -7494,17 +7226,6 @@
|
||||
"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",
|
||||
@@ -7595,52 +7316,6 @@
|
||||
"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",
|
||||
@@ -7701,7 +7376,7 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -7757,9 +7432,10 @@
|
||||
]
|
||||
},
|
||||
"node_modules/react": {
|
||||
"version": "18.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz",
|
||||
"integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==",
|
||||
"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",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"loose-envify": "^1.1.0"
|
||||
@@ -7768,6 +7444,20 @@
|
||||
"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",
|
||||
@@ -7993,6 +7683,16 @@
|
||||
"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",
|
||||
@@ -8026,27 +7726,6 @@
|
||||
"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",
|
||||
@@ -8168,29 +7847,6 @@
|
||||
"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",
|
||||
@@ -8200,15 +7856,6 @@
|
||||
"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",
|
||||
@@ -8225,17 +7872,6 @@
|
||||
"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",
|
||||
@@ -8367,66 +8003,6 @@
|
||||
"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",
|
||||
@@ -8667,7 +8243,7 @@
|
||||
"version": "4.9.5",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||
"devOptional": true,
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
@@ -8736,14 +8312,6 @@
|
||||
"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",
|
||||
@@ -8777,27 +8345,6 @@
|
||||
"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",
|
||||
@@ -8960,6 +8507,15 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
10
package.json
10
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "3.2.2",
|
||||
"version": "3.2.4",
|
||||
"description": "Auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
||||
"keywords": [
|
||||
"git",
|
||||
@@ -58,7 +58,8 @@
|
||||
"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"
|
||||
"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"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/types": "^17.4.4",
|
||||
@@ -87,6 +88,7 @@
|
||||
"@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",
|
||||
@@ -97,6 +99,8 @@
|
||||
"ignore": "^5.2.4",
|
||||
"ini": "^3.0.1",
|
||||
"inquirer": "^9.1.4",
|
||||
"openai": "^4.57.0"
|
||||
"openai": "^4.57.0",
|
||||
"punycode": "^2.3.1",
|
||||
"zod": "^3.23.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,12 @@ 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',
|
||||
@@ -37,7 +43,7 @@ cli(
|
||||
if (await isHookCalled()) {
|
||||
prepareCommitMessageHook();
|
||||
} else {
|
||||
commit(extraArgs, false, flags.fgm, flags.yes);
|
||||
commit(extraArgs, flags.context, false, flags.fgm, flags.yes);
|
||||
}
|
||||
},
|
||||
extraArgs
|
||||
|
||||
@@ -39,6 +39,7 @@ const checkMessageTemplate = (extraArgs: string[]): string | false => {
|
||||
interface GenerateCommitMessageFromGitDiffParams {
|
||||
diff: string;
|
||||
extraArgs: string[];
|
||||
context?: string;
|
||||
fullGitMojiSpec?: boolean;
|
||||
skipCommitConfirmation?: boolean;
|
||||
}
|
||||
@@ -46,6 +47,7 @@ interface GenerateCommitMessageFromGitDiffParams {
|
||||
const generateCommitMessageFromGitDiff = async ({
|
||||
diff,
|
||||
extraArgs,
|
||||
context = '',
|
||||
fullGitMojiSpec = false,
|
||||
skipCommitConfirmation = false
|
||||
}: GenerateCommitMessageFromGitDiffParams): Promise<void> => {
|
||||
@@ -56,7 +58,8 @@ const generateCommitMessageFromGitDiff = async ({
|
||||
try {
|
||||
let commitMessage = await generateCommitMessageByDiff(
|
||||
diff,
|
||||
fullGitMojiSpec
|
||||
fullGitMojiSpec,
|
||||
context
|
||||
);
|
||||
|
||||
const messageTemplate = checkMessageTemplate(extraArgs);
|
||||
@@ -135,8 +138,7 @@ ${chalk.grey('——————————————————')}`
|
||||
]);
|
||||
|
||||
pushSpinner.stop(
|
||||
`${chalk.green('✔')} Successfully pushed all commits to ${
|
||||
remotes[0]
|
||||
`${chalk.green('✔')} Successfully pushed all commits to ${remotes[0]
|
||||
}`
|
||||
);
|
||||
|
||||
@@ -146,26 +148,29 @@ ${chalk.grey('——————————————————')}`
|
||||
process.exit(0);
|
||||
}
|
||||
} else {
|
||||
const skipOption = `don't push`
|
||||
const selectedRemote = (await select({
|
||||
message: 'Choose a remote to push to',
|
||||
options: remotes.map((remote) => ({ value: remote, label: remote }))
|
||||
options: [...remotes, skipOption].map((remote) => ({ value: remote, label: remote })),
|
||||
})) as string;
|
||||
|
||||
if (isCancel(selectedRemote)) process.exit(1);
|
||||
|
||||
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}`
|
||||
);
|
||||
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}`
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const regenerateMessage = await confirm({
|
||||
@@ -197,6 +202,7 @@ ${chalk.grey('——————————————————')}`
|
||||
|
||||
export async function commit(
|
||||
extraArgs: string[] = [],
|
||||
context: string = '',
|
||||
isStageAllFlag: Boolean = false,
|
||||
fullGitMojiSpec: boolean = false,
|
||||
skipCommitConfirmation: boolean = false
|
||||
@@ -238,7 +244,7 @@ export async function commit(
|
||||
if (isCancel(isStageAllAndCommitConfirmedByUser)) process.exit(1);
|
||||
|
||||
if (isStageAllAndCommitConfirmedByUser) {
|
||||
await commit(extraArgs, true, fullGitMojiSpec);
|
||||
await commit(extraArgs, context, true, fullGitMojiSpec);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -256,7 +262,7 @@ export async function commit(
|
||||
await gitAdd({ files });
|
||||
}
|
||||
|
||||
await commit(extraArgs, false, fullGitMojiSpec);
|
||||
await commit(extraArgs, context, false, fullGitMojiSpec);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -270,6 +276,7 @@ export async function commit(
|
||||
generateCommitMessageFromGitDiff({
|
||||
diff: await getDiff({ files: stagedFiles }),
|
||||
extraArgs,
|
||||
context,
|
||||
fullGitMojiSpec,
|
||||
skipCommitConfirmation
|
||||
})
|
||||
|
||||
@@ -86,6 +86,48 @@ export const MODEL_LIST = {
|
||||
'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',
|
||||
]
|
||||
};
|
||||
|
||||
@@ -93,12 +135,16 @@ 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];
|
||||
}
|
||||
@@ -138,7 +184,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 "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 "mlx" or "azure" or "gemini" or "flowise" or "anthropic". Run `oco config set OCO_API_KEY=your_key OCO_AI_PROVIDER=openai`'
|
||||
);
|
||||
|
||||
return value;
|
||||
@@ -255,6 +301,7 @@ export const configValidators = {
|
||||
CONFIG_KEYS.OCO_AI_PROVIDER,
|
||||
[
|
||||
'openai',
|
||||
'mistral',
|
||||
'anthropic',
|
||||
'gemini',
|
||||
'azure',
|
||||
@@ -262,7 +309,7 @@ export const configValidators = {
|
||||
'flowise',
|
||||
'groq'
|
||||
].includes(value) || value.startsWith('ollama'),
|
||||
`${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)`
|
||||
`${value} is not supported yet, use 'ollama', 'mlx', 'anthropic', 'azure', 'gemini', 'flowise', 'mistral' or 'openai' (default)`
|
||||
);
|
||||
|
||||
return value;
|
||||
@@ -307,7 +354,9 @@ export enum OCO_AI_PROVIDER_ENUM {
|
||||
AZURE = 'azure',
|
||||
TEST = 'test',
|
||||
FLOWISE = 'flowise',
|
||||
GROQ = 'groq'
|
||||
GROQ = 'groq',
|
||||
MISTRAL = 'mistral',
|
||||
MLX = 'mlx'
|
||||
}
|
||||
|
||||
export type ConfigType = {
|
||||
|
||||
@@ -3,6 +3,7 @@ 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;
|
||||
@@ -17,7 +18,8 @@ type Client =
|
||||
| AzureOpenAIClient
|
||||
| AnthropicClient
|
||||
| RawAxiosClient
|
||||
| GeminiClient;
|
||||
| GeminiClient
|
||||
| MistralClient;
|
||||
|
||||
export interface AiEngine {
|
||||
config: AiEngineConfig;
|
||||
|
||||
82
src/engine/mistral.ts
Normal file
82
src/engine/mistral.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
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;
|
||||
}
|
||||
};
|
||||
}
|
||||
47
src/engine/mlx.ts
Normal file
47
src/engine/mlx.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
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}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,10 @@ const MAX_TOKENS_OUTPUT = config.OCO_TOKENS_MAX_OUTPUT;
|
||||
|
||||
const generateCommitMessageChatCompletionPrompt = async (
|
||||
diff: string,
|
||||
fullGitMojiSpec: boolean
|
||||
fullGitMojiSpec: boolean,
|
||||
context: string
|
||||
): Promise<Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>> => {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec, context);
|
||||
|
||||
const chatContextAsCompletionRequest = [...INIT_MESSAGES_PROMPT];
|
||||
|
||||
@@ -36,10 +37,14 @@ const ADJUSTMENT_FACTOR = 20;
|
||||
|
||||
export const generateCommitMessageByDiff = async (
|
||||
diff: string,
|
||||
fullGitMojiSpec: boolean = false
|
||||
fullGitMojiSpec: boolean = false,
|
||||
context: string = ""
|
||||
): Promise<string> => {
|
||||
try {
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(fullGitMojiSpec);
|
||||
const INIT_MESSAGES_PROMPT = await getMainCommitPrompt(
|
||||
fullGitMojiSpec,
|
||||
context
|
||||
);
|
||||
|
||||
const INIT_MESSAGES_PROMPT_LENGTH = INIT_MESSAGES_PROMPT.map(
|
||||
(msg) => tokenCount(msg.content as string) + 4
|
||||
@@ -69,7 +74,8 @@ export const generateCommitMessageByDiff = async (
|
||||
|
||||
const messages = await generateCommitMessageChatCompletionPrompt(
|
||||
diff,
|
||||
fullGitMojiSpec
|
||||
fullGitMojiSpec,
|
||||
context,
|
||||
);
|
||||
|
||||
const engine = getEngine();
|
||||
|
||||
@@ -111,9 +111,24 @@ 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
|
||||
fullGitMojiSpec: boolean,
|
||||
context: string
|
||||
): OpenAI.Chat.Completions.ChatCompletionMessageParam => ({
|
||||
role: 'system',
|
||||
content: (() => {
|
||||
@@ -127,15 +142,16 @@ 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}`;
|
||||
return `${missionStatement}\n${diffInstruction}\n${conventionGuidelines}\n${descriptionGuideline}\n${oneLineCommitGuideline}\n${generalGuidelines}\n${userInputContext}`;
|
||||
})()
|
||||
});
|
||||
|
||||
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
|
||||
@@ -159,7 +175,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
|
||||
@@ -185,7 +201,8 @@ const INIT_CONSISTENCY_PROMPT = (
|
||||
});
|
||||
|
||||
export const getMainCommitPrompt = async (
|
||||
fullGitMojiSpec: boolean
|
||||
fullGitMojiSpec: boolean,
|
||||
context: string
|
||||
): Promise<Array<OpenAI.Chat.Completions.ChatCompletionMessageParam>> => {
|
||||
switch (config.OCO_PROMPT_MODULE) {
|
||||
case '@commitlint':
|
||||
@@ -207,14 +224,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),
|
||||
INIT_MAIN_PROMPT(translation.localLanguage, fullGitMojiSpec, context),
|
||||
INIT_DIFF_PROMPT,
|
||||
INIT_CONSISTENCY_PROMPT(translation)
|
||||
];
|
||||
|
||||
@@ -6,8 +6,10 @@ 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();
|
||||
@@ -43,6 +45,12 @@ export function getEngine(): AiEngine {
|
||||
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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user