From 2769121842b83977e511b14446dd9827ba151cd5 Mon Sep 17 00:00:00 2001 From: GPT8 <57486732+di-sukharev@users.noreply.github.com> Date: Sat, 7 Sep 2024 18:17:17 +0300 Subject: [PATCH 1/7] 3.2.2 (#413) * feat(config): add support for groq AI provider, including config validation and engine implementation (#381) * fix migrations (#414) --------- Co-authored-by: Takanori Matsumoto Co-authored-by: BILLY Maxime --- out/cli.cjs | 74 ++++++++++++++++--- out/github-action.cjs | 62 ++++++++++++++-- package-lock.json | 4 +- package.json | 2 +- src/commands/commit.ts | 6 +- src/commands/config.ts | 51 +++++++++++-- src/engine/groq.ts | 10 +++ src/engine/openAi.ts | 9 ++- .../02_set_missing_default_values.ts | 4 +- src/migrations/_run.ts | 1 + src/utils/engine.ts | 4 + 11 files changed, 199 insertions(+), 28 deletions(-) create mode 100644 src/engine/groq.ts diff --git a/out/cli.cjs b/out/cli.cjs index 50fd4e2e..a4fe603b 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -27331,7 +27331,7 @@ function G3(t2, e3) { // package.json var package_default = { name: "opencommit", - version: "3.2.1", + version: "3.2.2", description: "Auto-generate impressive commits in 1 second. Killing lame commits with AI \u{1F92F}\u{1F52B}", keywords: [ "git", @@ -29918,6 +29918,15 @@ 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) => { @@ -29928,6 +29937,8 @@ var getDefaultModel = (provider) => { 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]; } @@ -30051,9 +30062,15 @@ var configValidators = { value = "openai"; validateConfig( "OCO_AI_PROVIDER" /* OCO_AI_PROVIDER */, - ["openai", "anthropic", "gemini", "azure", "test", "flowise"].includes( - value - ) || value.startsWith("ollama"), + [ + "openai", + "anthropic", + "gemini", + "azure", + "test", + "flowise", + "groq" + ].includes(value) || value.startsWith("ollama"), `${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)` ); return value; @@ -30093,6 +30110,7 @@ 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"; return OCO_AI_PROVIDER_ENUM2; })(OCO_AI_PROVIDER_ENUM || {}); var defaultConfigPath = (0, import_path.join)((0, import_os.homedir)(), ".opencommit"); @@ -30109,7 +30127,6 @@ 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 }; @@ -30169,6 +30186,25 @@ 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 @@ -30176,7 +30212,8 @@ var getConfig = ({ const envConfig = getEnvConfig(envPath); const globalConfig = getGlobalConfig(globalPath); const config7 = mergeConfigs(envConfig, globalConfig); - return config7; + const cleanConfig = cleanUndefinedValues(config7); + return cleanConfig; }; var setConfig = (keyValues, globalConfigPath = defaultConfigPath) => { const config7 = getConfig({ @@ -44471,7 +44508,19 @@ var OpenAiEngine = class { } }; this.config = config7; - this.client = new OpenAI({ apiKey: config7.apiKey }); + 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); } }; @@ -44499,6 +44548,8 @@ function getEngine() { return new AzureEngine(DEFAULT_CONFIG2); case "flowise" /* FLOWISE */: return new FlowiseEngine(DEFAULT_CONFIG2); + case "groq" /* GROQ */: + return new GroqEngine(DEFAULT_CONFIG2); default: return new OpenAiEngine(DEFAULT_CONFIG2); } @@ -45342,7 +45393,10 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2 } } } catch (error) { - commitGenerationSpinner.stop("\u{1F4DD} Commit message generated"); + commitGenerationSpinner.stop( + `${source_default.red("\u2716")} Failed to generate the commit message` + ); + console.log(error); const err = error; ce(`${source_default.red("\u2716")} ${err?.message || err}`); process.exit(1); @@ -45677,11 +45731,12 @@ function set_missing_default_values_default() { const entriesToSet = []; for (const entry of Object.entries(DEFAULT_CONFIG)) { const [key, _value] = entry; - if (config7[key] === "undefined") + if (config7[key] === "undefined" || config7[key] === void 0) entriesToSet.push(entry); } if (entriesToSet.length > 0) setConfig(entriesToSet); + console.log(entriesToSet); }; setDefaultConfigValues(getGlobalConfig()); } @@ -45738,6 +45793,7 @@ var runMigrations = async () => { ce( `${source_default.red("Failed to apply migration")} ${migration.name}: ${error}` ); + process.exit(1); } isMigrated = true; } diff --git a/out/github-action.cjs b/out/github-action.cjs index 68b14210..5acd5e08 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -48730,6 +48730,15 @@ 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) => { @@ -48740,6 +48749,8 @@ var getDefaultModel = (provider) => { 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]; } @@ -48863,9 +48874,15 @@ var configValidators = { value = "openai"; validateConfig( "OCO_AI_PROVIDER" /* OCO_AI_PROVIDER */, - ["openai", "anthropic", "gemini", "azure", "test", "flowise"].includes( - value - ) || value.startsWith("ollama"), + [ + "openai", + "anthropic", + "gemini", + "azure", + "test", + "flowise", + "groq" + ].includes(value) || value.startsWith("ollama"), `${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)` ); return value; @@ -48911,7 +48928,6 @@ 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 }; @@ -48971,6 +48987,25 @@ 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 @@ -48978,7 +49013,8 @@ var getConfig = ({ const envConfig = getEnvConfig(envPath); const globalConfig = getGlobalConfig(globalPath); const config6 = mergeConfigs(envConfig, globalConfig); - return config6; + const cleanConfig = cleanUndefinedValues(config6); + return cleanConfig; }; var setConfig = (keyValues, globalConfigPath = defaultConfigPath) => { const config6 = getConfig({ @@ -63273,7 +63309,19 @@ var OpenAiEngine = class { } }; this.config = config6; - this.client = new OpenAI({ apiKey: config6.apiKey }); + 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); } }; @@ -63301,6 +63349,8 @@ function getEngine() { return new AzureEngine(DEFAULT_CONFIG2); case "flowise" /* FLOWISE */: return new FlowiseEngine(DEFAULT_CONFIG2); + case "groq" /* GROQ */: + return new GroqEngine(DEFAULT_CONFIG2); default: return new OpenAiEngine(DEFAULT_CONFIG2); } diff --git a/package-lock.json b/package-lock.json index 5d34e5e6..aede6fed 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "opencommit", - "version": "3.2.1", + "version": "3.2.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "opencommit", - "version": "3.2.1", + "version": "3.2.2", "license": "MIT", "dependencies": { "@actions/core": "^1.10.0", diff --git a/package.json b/package.json index 777867b4..24d37d58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "opencommit", - "version": "3.2.1", + "version": "3.2.2", "description": "Auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫", "keywords": [ "git", diff --git a/src/commands/commit.ts b/src/commands/commit.ts index 8d61df0d..a26df269 100644 --- a/src/commands/commit.ts +++ b/src/commands/commit.ts @@ -183,7 +183,11 @@ ${chalk.grey('——————————————————')}` } } } catch (error) { - commitGenerationSpinner.stop('📝 Commit message generated'); + commitGenerationSpinner.stop( + `${chalk.red('✖')} Failed to generate the commit message` + ); + + console.log(error); const err = error as Error; outro(`${chalk.red('✖')} ${err?.message || err}`); diff --git a/src/commands/config.ts b/src/commands/config.ts index c45e2f2f..e6736334 100644 --- a/src/commands/config.ts +++ b/src/commands/config.ts @@ -76,6 +76,16 @@ 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 ] }; @@ -87,6 +97,8 @@ const getDefaultModel = (provider: string | undefined): string => { 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]; } @@ -241,9 +253,15 @@ export const configValidators = { validateConfig( CONFIG_KEYS.OCO_AI_PROVIDER, - ['openai', 'anthropic', 'gemini', 'azure', 'test', 'flowise'].includes( - value - ) || value.startsWith('ollama'), + [ + 'openai', + 'anthropic', + 'gemini', + 'azure', + 'test', + 'flowise', + 'groq' + ].includes(value) || value.startsWith('ollama'), `${value} is not supported yet, use 'ollama', 'anthropic', 'azure', 'gemini', 'flowise' or 'openai' (default)` ); @@ -288,7 +306,8 @@ export enum OCO_AI_PROVIDER_ENUM { GEMINI = 'gemini', AZURE = 'azure', TEST = 'test', - FLOWISE = 'flowise' + FLOWISE = 'flowise', + GROQ = 'groq' } export type ConfigType = { @@ -352,7 +371,6 @@ 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 }; @@ -444,6 +462,25 @@ 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 @@ -453,7 +490,9 @@ export const getConfig = ({ const config = mergeConfigs(envConfig, globalConfig); - return config; + const cleanConfig = cleanUndefinedValues(config); + + return cleanConfig as ConfigType; }; export const setConfig = ( diff --git a/src/engine/groq.ts b/src/engine/groq.ts new file mode 100644 index 00000000..baa6410c --- /dev/null +++ b/src/engine/groq.ts @@ -0,0 +1,10 @@ +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); + } +} \ No newline at end of file diff --git a/src/engine/openAi.ts b/src/engine/openAi.ts index 2f231eed..ea5d9e9a 100644 --- a/src/engine/openAi.ts +++ b/src/engine/openAi.ts @@ -4,7 +4,7 @@ import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitD import { tokenCount } from '../utils/tokenCount'; import { AiEngine, AiEngineConfig } from './Engine'; -interface OpenAiConfig extends AiEngineConfig {} +export interface OpenAiConfig extends AiEngineConfig {} export class OpenAiEngine implements AiEngine { config: OpenAiConfig; @@ -12,7 +12,12 @@ export class OpenAiEngine implements AiEngine { constructor(config: OpenAiConfig) { this.config = config; - this.client = new OpenAI({ apiKey: config.apiKey }); + + if (!config.baseURL) { + this.client = new OpenAI({ apiKey: config.apiKey }); + } else { + this.client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL }); + } } public generateCommitMessage = async ( diff --git a/src/migrations/02_set_missing_default_values.ts b/src/migrations/02_set_missing_default_values.ts index 107fc06b..c93779a5 100644 --- a/src/migrations/02_set_missing_default_values.ts +++ b/src/migrations/02_set_missing_default_values.ts @@ -10,10 +10,12 @@ 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') entriesToSet.push(entry); + if (config[key] === 'undefined' || config[key] === undefined) + entriesToSet.push(entry); } if (entriesToSet.length > 0) setConfig(entriesToSet); + console.log(entriesToSet); }; setDefaultConfigValues(getGlobalConfig()); diff --git a/src/migrations/_run.ts b/src/migrations/_run.ts index 03a6b1bc..bbf3bb82 100644 --- a/src/migrations/_run.ts +++ b/src/migrations/_run.ts @@ -53,6 +53,7 @@ export const runMigrations = async () => { migration.name }: ${error}` ); + process.exit(1); } isMigrated = true; diff --git a/src/utils/engine.ts b/src/utils/engine.ts index f3b3ae0a..5930c2ff 100644 --- a/src/utils/engine.ts +++ b/src/utils/engine.ts @@ -7,6 +7,7 @@ import { GeminiEngine } from '../engine/gemini'; import { OllamaEngine } from '../engine/ollama'; import { OpenAiEngine } from '../engine/openAi'; import { TestAi, TestMockType } from '../engine/testAi'; +import { GroqEngine } from '../engine/groq'; export function getEngine(): AiEngine { const config = getConfig(); @@ -39,6 +40,9 @@ 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); + default: return new OpenAiEngine(DEFAULT_CONFIG); } From 25105e4c3a8e04e08235349912ff29681dba1e9c Mon Sep 17 00:00:00 2001 From: di-sukharev Date: Sat, 7 Sep 2024 19:11:37 +0300 Subject: [PATCH 2/7] docs(CONTRIBUTING.md): update links to point to the correct repository name for consistency and clarity --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 35f0d629..b1d32633 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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 From 906e10733ea57dd87e8dc0917c0b9602fc96fb41 Mon Sep 17 00:00:00 2001 From: di-sukharev Date: Sat, 7 Sep 2024 19:11:37 +0300 Subject: [PATCH 3/7] docs(CONTRIBUTING.md): update links to point to the correct repository name for consistency and clarity --- .github/CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 35f0d629..b1d32633 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -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 From 3616da6585e0e0cfd2524d04d2021383c725a314 Mon Sep 17 00:00:00 2001 From: Welington Sampaio Date: Mon, 7 Oct 2024 19:08:19 -0300 Subject: [PATCH 4/7] feat(prompts): add user input context to commit message generation --- out/cli.cjs | 17 ++++++++++++++++- out/github-action.cjs | 17 ++++++++++++++++- src/prompts.ts | 23 ++++++++++++++++++++++- 3 files changed, 54 insertions(+), 3 deletions(-) diff --git a/out/cli.cjs b/out/cli.cjs index a4fe603b..20ce6afa 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -44931,6 +44931,19 @@ 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 = () => { + const args = process.argv; + const dashIndex = args.indexOf("--"); + if (dashIndex !== -1) { + const context = args.slice(dashIndex + 1).join(" "); + if (context !== "" && context !== " ") { + return `Additional context provided by the user: ${context} + +Consider this context when generating the commit message, incorporating relevant information when appropriate.`; + } + } + return ""; +}; var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({ role: "system", content: (() => { @@ -44941,12 +44954,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(); return `${missionStatement} ${diffInstruction} ${conventionGuidelines} ${descriptionGuideline} ${oneLineCommitGuideline} -${generalGuidelines}`; +${generalGuidelines} +${userInputContext}`; })() }); var INIT_DIFF_PROMPT = { diff --git a/out/github-action.cjs b/out/github-action.cjs index 5acd5e08..9c9339f6 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -63732,6 +63732,19 @@ 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 = () => { + const args = process.argv; + const dashIndex = args.indexOf("--"); + if (dashIndex !== -1) { + const context2 = args.slice(dashIndex + 1).join(" "); + if (context2 !== "" && context2 !== " ") { + return `Additional context provided by the user: ${context2} + +Consider this context when generating the commit message, incorporating relevant information when appropriate.`; + } + } + return ""; +}; var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({ role: "system", content: (() => { @@ -63742,12 +63755,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(); return `${missionStatement} ${diffInstruction} ${conventionGuidelines} ${descriptionGuideline} ${oneLineCommitGuideline} -${generalGuidelines}`; +${generalGuidelines} +${userInputContext}`; })() }); var INIT_DIFF_PROMPT = { diff --git a/src/prompts.ts b/src/prompts.ts index 6cc64b9f..4cf96f9a 100644 --- a/src/prompts.ts +++ b/src/prompts.ts @@ -111,6 +111,26 @@ 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 = () => { + const args = process.argv; + // Find all arguments after '--' + const dashIndex = args.indexOf('--'); + if (dashIndex !== -1) { + const context = args.slice(dashIndex + 1).join(' '); + if (context !== '' && context !== ' ') { + return `Additional context provided by the user: ${context}\n\nConsider this context when generating the commit message, incorporating relevant information when appropriate.`; + } + } + return ''; +}; + const INIT_MAIN_PROMPT = ( language: string, fullGitMojiSpec: boolean @@ -127,8 +147,9 @@ 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(); - 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}`; })() }); From 53e1b8d1f0fead00cd3c63bad9442c0b9ff3390f Mon Sep 17 00:00:00 2001 From: Welington Sampaio Date: Mon, 7 Oct 2024 21:35:22 -0300 Subject: [PATCH 5/7] feat(commit): add cleanupContext function to remove args after '--' --- src/commands/commit.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/commands/commit.ts b/src/commands/commit.ts index a26df269..04cca991 100644 --- a/src/commands/commit.ts +++ b/src/commands/commit.ts @@ -36,6 +36,16 @@ const checkMessageTemplate = (extraArgs: string[]): string | false => { return false; }; +// remove all args after '--' +const cleanupContext = (extraArgs: string[]): string[] => { + // remove all args after '--' + const index = extraArgs.indexOf('--'); + if (index !== -1) { + extraArgs = extraArgs.slice(0, index); + } + return extraArgs; +}; + interface GenerateCommitMessageFromGitDiffParams { diff: string; extraArgs: string[]; @@ -97,7 +107,7 @@ ${chalk.grey('——————————————————')}` 'commit', '-m', commitMessage, - ...extraArgs + ...cleanupContext(extraArgs) ]); committingChangesSpinner.stop( `${chalk.green('✔')} Successfully committed` From 589311f3c9796d1669e0dcb1e3c9ed9faeada668 Mon Sep 17 00:00:00 2001 From: Welington Sampaio Date: Mon, 7 Oct 2024 21:52:32 -0300 Subject: [PATCH 6/7] add build file --- out/cli.cjs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/out/cli.cjs b/out/cli.cjs index 20ce6afa..0e27dd94 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -45295,6 +45295,13 @@ var checkMessageTemplate = (extraArgs2) => { } return false; }; +var cleanupContext = (extraArgs2) => { + const index = extraArgs2.indexOf("--"); + if (index !== -1) { + extraArgs2 = extraArgs2.slice(0, index); + } + return extraArgs2; +}; var generateCommitMessageFromGitDiff = async ({ diff, extraArgs: extraArgs2, @@ -45337,7 +45344,7 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2 "commit", "-m", commitMessage, - ...extraArgs2 + ...cleanupContext(extraArgs2) ]); committingChangesSpinner.stop( `${source_default.green("\u2714")} Successfully committed` @@ -45837,6 +45844,12 @@ Z2( alias: "y", description: "Skip commit confirmation prompt", default: false + }, + context: { + type: String, + alias: "c", + description: "Context used to generate the commit message", + default: "" } }, ignoreArgv: (type2) => type2 === "unknown-flag" || type2 === "argument", From e33a82c720e0137572f41e3f401a79f9531151c9 Mon Sep 17 00:00:00 2001 From: Welington Sampaio Date: Tue, 19 Nov 2024 15:49:08 -0300 Subject: [PATCH 7/7] feat(cli): add context flag for providing additional commit message input --- out/cli.cjs | 68 +++++++++++-------------- out/github-action.cjs | 34 ++++++------- src/cli.ts | 8 ++- src/commands/commit.ts | 26 ++++------ src/generateCommitMessageFromGitDiff.ts | 16 ++++-- src/prompts.ts | 32 +++++------- 6 files changed, 89 insertions(+), 95 deletions(-) diff --git a/out/cli.cjs b/out/cli.cjs index 0e27dd94..8c67547c 100755 --- a/out/cli.cjs +++ b/out/cli.cjs @@ -44931,20 +44931,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 userInputCodeContext = () => { - const args = process.argv; - const dashIndex = args.indexOf("--"); - if (dashIndex !== -1) { - const context = args.slice(dashIndex + 1).join(" "); - if (context !== "" && context !== " ") { - return `Additional context provided by the user: ${context} - +var userInputCodeContext = (context) => { + if (context !== "" && context !== " ") { + return `Additional context provided by the user: ${context} Consider this context when generating the commit message, incorporating relevant information when appropriate.`; - } } return ""; }; -var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({ +var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context) => ({ role: "system", content: (() => { const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention"; @@ -44954,7 +44948,7 @@ 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(); + const userInputContext = userInputCodeContext(context); return `${missionStatement} ${diffInstruction} ${conventionGuidelines} @@ -45003,7 +44997,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()) { @@ -45025,7 +45019,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) ]; @@ -45052,8 +45046,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", @@ -45069,9 +45063,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); @@ -45091,7 +45088,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => { } const messages = await generateCommitMessageChatCompletionPrompt( diff, - fullGitMojiSpec + fullGitMojiSpec, + context ); const engine = getEngine(); const commitMessage = await engine.generateCommitMessage(messages); @@ -45295,16 +45293,10 @@ var checkMessageTemplate = (extraArgs2) => { } return false; }; -var cleanupContext = (extraArgs2) => { - const index = extraArgs2.indexOf("--"); - if (index !== -1) { - extraArgs2 = extraArgs2.slice(0, index); - } - return extraArgs2; -}; var generateCommitMessageFromGitDiff = async ({ diff, extraArgs: extraArgs2, + context = "", fullGitMojiSpec = false, skipCommitConfirmation = false }) => { @@ -45314,7 +45306,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") { @@ -45344,7 +45337,7 @@ ${source_default.grey("\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2014\u2 "commit", "-m", commitMessage, - ...cleanupContext(extraArgs2) + ...extraArgs2 ]); committingChangesSpinner.stop( `${source_default.green("\u2714")} Successfully committed` @@ -45424,7 +45417,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) @@ -45455,7 +45448,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) { @@ -45470,7 +45463,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( @@ -45481,6 +45474,7 @@ ${stagedFiles.map((file) => ` ${file}`).join("\n")}` generateCommitMessageFromGitDiff({ diff: await getDiff({ files: stagedFiles }), extraArgs: extraArgs2, + context, fullGitMojiSpec, skipCommitConfirmation }) @@ -45839,17 +45833,17 @@ 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", description: "Skip commit confirmation prompt", default: false - }, - context: { - type: String, - alias: "c", - description: "Context used to generate the commit message", - default: "" } }, ignoreArgv: (type2) => type2 === "unknown-flag" || type2 === "argument", @@ -45861,7 +45855,7 @@ Z2( if (await isHookCalled()) { prepareCommitMessageHook(); } else { - commit(extraArgs, false, flags.fgm, flags.yes); + commit(extraArgs, flags.context, false, flags.fgm, flags.yes); } }, extraArgs diff --git a/out/github-action.cjs b/out/github-action.cjs index 9c9339f6..5140c41b 100644 --- a/out/github-action.cjs +++ b/out/github-action.cjs @@ -63732,20 +63732,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 userInputCodeContext = () => { - const args = process.argv; - const dashIndex = args.indexOf("--"); - if (dashIndex !== -1) { - const context2 = args.slice(dashIndex + 1).join(" "); - if (context2 !== "" && context2 !== " ") { - return `Additional context provided by the user: ${context2} - +var userInputCodeContext = (context2) => { + if (context2 !== "" && context2 !== " ") { + return `Additional context provided by the user: ${context2} Consider this context when generating the commit message, incorporating relevant information when appropriate.`; - } } return ""; }; -var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec) => ({ +var INIT_MAIN_PROMPT2 = (language, fullGitMojiSpec, context2) => ({ role: "system", content: (() => { const commitConvention = fullGitMojiSpec ? "GitMoji specification" : "Conventional Commit Convention"; @@ -63755,7 +63749,7 @@ 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(); + const userInputContext = userInputCodeContext(context2); return `${missionStatement} ${diffInstruction} ${conventionGuidelines} @@ -63804,7 +63798,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()) { @@ -63826,7 +63820,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) ]; @@ -63853,8 +63847,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", @@ -63870,9 +63864,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); @@ -63892,7 +63889,8 @@ var generateCommitMessageByDiff = async (diff, fullGitMojiSpec = false) => { } const messages = await generateCommitMessageChatCompletionPrompt( diff, - fullGitMojiSpec + fullGitMojiSpec, + context2 ); const engine = getEngine(); const commitMessage = await engine.generateCommitMessage(messages); diff --git a/src/cli.ts b/src/cli.ts index 7d731d9f..fd07a907 100755 --- a/src/cli.ts +++ b/src/cli.ts @@ -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 diff --git a/src/commands/commit.ts b/src/commands/commit.ts index 04cca991..0707ea94 100644 --- a/src/commands/commit.ts +++ b/src/commands/commit.ts @@ -36,19 +36,10 @@ const checkMessageTemplate = (extraArgs: string[]): string | false => { return false; }; -// remove all args after '--' -const cleanupContext = (extraArgs: string[]): string[] => { - // remove all args after '--' - const index = extraArgs.indexOf('--'); - if (index !== -1) { - extraArgs = extraArgs.slice(0, index); - } - return extraArgs; -}; - interface GenerateCommitMessageFromGitDiffParams { diff: string; extraArgs: string[]; + context?: string; fullGitMojiSpec?: boolean; skipCommitConfirmation?: boolean; } @@ -56,6 +47,7 @@ interface GenerateCommitMessageFromGitDiffParams { const generateCommitMessageFromGitDiff = async ({ diff, extraArgs, + context = '', fullGitMojiSpec = false, skipCommitConfirmation = false }: GenerateCommitMessageFromGitDiffParams): Promise => { @@ -66,7 +58,8 @@ const generateCommitMessageFromGitDiff = async ({ try { let commitMessage = await generateCommitMessageByDiff( diff, - fullGitMojiSpec + fullGitMojiSpec, + context ); const messageTemplate = checkMessageTemplate(extraArgs); @@ -107,7 +100,7 @@ ${chalk.grey('——————————————————')}` 'commit', '-m', commitMessage, - ...cleanupContext(extraArgs) + ...extraArgs ]); committingChangesSpinner.stop( `${chalk.green('✔')} Successfully committed` @@ -145,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] }` ); @@ -207,6 +199,7 @@ ${chalk.grey('——————————————————')}` export async function commit( extraArgs: string[] = [], + context: string = '', isStageAllFlag: Boolean = false, fullGitMojiSpec: boolean = false, skipCommitConfirmation: boolean = false @@ -248,7 +241,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); } @@ -266,7 +259,7 @@ export async function commit( await gitAdd({ files }); } - await commit(extraArgs, false, fullGitMojiSpec); + await commit(extraArgs, context, false, fullGitMojiSpec); process.exit(1); } @@ -280,6 +273,7 @@ export async function commit( generateCommitMessageFromGitDiff({ diff: await getDiff({ files: stagedFiles }), extraArgs, + context, fullGitMojiSpec, skipCommitConfirmation }) diff --git a/src/generateCommitMessageFromGitDiff.ts b/src/generateCommitMessageFromGitDiff.ts index 8ba87407..546de68a 100644 --- a/src/generateCommitMessageFromGitDiff.ts +++ b/src/generateCommitMessageFromGitDiff.ts @@ -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> => { - 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 => { 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(); diff --git a/src/prompts.ts b/src/prompts.ts index 4cf96f9a..78a5ecd7 100644 --- a/src/prompts.ts +++ b/src/prompts.ts @@ -118,22 +118,17 @@ const getOneLineCommitInstruction = () => * $ oco -- This is a context used to generate the commit message * @returns - The context of the user input */ -const userInputCodeContext = () => { - const args = process.argv; - // Find all arguments after '--' - const dashIndex = args.indexOf('--'); - if (dashIndex !== -1) { - const context = args.slice(dashIndex + 1).join(' '); - if (context !== '' && context !== ' ') { - return `Additional context provided by the user: ${context}\n\nConsider this context when generating the commit message, incorporating relevant information when appropriate.`; - } +const userInputCodeContext = (context: string) => { + if (context !== '' && context !== ' ') { + return `Additional context provided by the user: ${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: (() => { @@ -147,16 +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(); + const userInputContext = userInputCodeContext(context); 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 @@ -180,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 @@ -206,7 +201,8 @@ const INIT_CONSISTENCY_PROMPT = ( }); export const getMainCommitPrompt = async ( - fullGitMojiSpec: boolean + fullGitMojiSpec: boolean, + context: string ): Promise> => { switch (config.OCO_PROMPT_MODULE) { case '@commitlint': @@ -228,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) ];