Merge branch 'master' into dep-updates
This commit is contained in:
+2
-1
@@ -11,4 +11,5 @@ uncaughtExceptions.log
|
|||||||
src/*.json
|
src/*.json
|
||||||
.idea
|
.idea
|
||||||
test.ts
|
test.ts
|
||||||
notes.md
|
notes.md
|
||||||
|
.nvmrc
|
||||||
@@ -109,6 +109,7 @@ Create a `.env` file and add OpenCommit config variables there like this:
|
|||||||
OCO_AI_PROVIDER=<openai (default), anthropic, azure, ollama, gemini, flowise, deepseek>
|
OCO_AI_PROVIDER=<openai (default), anthropic, azure, ollama, gemini, flowise, deepseek>
|
||||||
OCO_API_KEY=<your OpenAI API token> // or other LLM provider API token
|
OCO_API_KEY=<your OpenAI API token> // or other LLM provider API token
|
||||||
OCO_API_URL=<may be used to set proxy path to OpenAI api>
|
OCO_API_URL=<may be used to set proxy path to OpenAI api>
|
||||||
|
OCO_API_CUSTOM_HEADERS=<JSON string of custom HTTP headers to include in API requests>
|
||||||
OCO_TOKENS_MAX_INPUT=<max model token limit (default: 4096)>
|
OCO_TOKENS_MAX_INPUT=<max model token limit (default: 4096)>
|
||||||
OCO_TOKENS_MAX_OUTPUT=<max response tokens (default: 500)>
|
OCO_TOKENS_MAX_OUTPUT=<max response tokens (default: 500)>
|
||||||
OCO_DESCRIPTION=<postface a message with ~3 sentences description of the changes>
|
OCO_DESCRIPTION=<postface a message with ~3 sentences description of the changes>
|
||||||
|
|||||||
+17
-5
@@ -9,26 +9,38 @@ const config: Config = {
|
|||||||
testTimeout: 100_000,
|
testTimeout: 100_000,
|
||||||
coverageProvider: 'v8',
|
coverageProvider: 'v8',
|
||||||
moduleDirectories: ['node_modules', 'src'],
|
moduleDirectories: ['node_modules', 'src'],
|
||||||
preset: 'ts-jest/presets/js-with-ts-esm',
|
preset: 'ts-jest/presets/default-esm',
|
||||||
setupFilesAfterEnv: ['<rootDir>/test/jest-setup.ts'],
|
setupFilesAfterEnv: ['<rootDir>/test/jest-setup.ts'],
|
||||||
testEnvironment: 'node',
|
testEnvironment: 'node',
|
||||||
testRegex: ['.*\\.test\\.ts$'],
|
testRegex: ['.*\\.test\\.ts$'],
|
||||||
transformIgnorePatterns: ['node_modules/(?!cli-testing-library)'],
|
|
||||||
|
|
||||||
// Tell Jest to ignore the specific duplicate package.json files
|
// Tell Jest to ignore the specific duplicate package.json files
|
||||||
// that are causing Haste module naming collisions
|
// that are causing Haste module naming collisions
|
||||||
modulePathIgnorePatterns: [
|
modulePathIgnorePatterns: [
|
||||||
'<rootDir>/test/e2e/prompt-module/data/commitlint_18/',
|
'<rootDir>/test/e2e/prompt-module/data/commitlint_18/',
|
||||||
'<rootDir>/test/e2e/prompt-module/data/commitlint_19/'
|
'<rootDir>/test/e2e/prompt-module/data/commitlint_19/'
|
||||||
],
|
],
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
'node_modules/(?!(cli-testing-library|@clack|cleye)/.*)'
|
||||||
|
],
|
||||||
transform: {
|
transform: {
|
||||||
'^.+\\.(ts|tsx)$': [
|
'^.+\\.(ts|tsx|js|jsx|mjs)$': [
|
||||||
'ts-jest',
|
'ts-jest',
|
||||||
{
|
{
|
||||||
diagnostics: false,
|
diagnostics: false,
|
||||||
useESM: true
|
useESM: true,
|
||||||
|
tsconfig: {
|
||||||
|
module: 'ESNext',
|
||||||
|
target: 'ES2022'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
// Fix Haste module naming collision
|
||||||
|
modulePathIgnorePatterns: [
|
||||||
|
'<rootDir>/test/e2e/prompt-module/data/'
|
||||||
|
],
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^(\\.{1,2}/.*)\\.js$': '$1'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Generated
+118
-77
@@ -50,7 +50,7 @@
|
|||||||
"eslint": "^9.24.0",
|
"eslint": "^9.24.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"rimraf": "^5.0.5",
|
"rimraf": "^6.0.1",
|
||||||
"ts-jest": "^29.1.2",
|
"ts-jest": "^29.1.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3"
|
||||||
@@ -2370,17 +2370,17 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz",
|
||||||
"integrity": "sha512-ba0rr4Wfvg23vERs3eB+P3lfj2E+2g3lhWcCVukUuhtcdUx5lSIFZlGFEBHKr+3zizDa/TvZTptdNHVZWAkSBg==",
|
"integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/regexpp": "^4.10.0",
|
"@eslint-community/regexpp": "^4.10.0",
|
||||||
"@typescript-eslint/scope-manager": "8.29.1",
|
"@typescript-eslint/scope-manager": "8.30.1",
|
||||||
"@typescript-eslint/type-utils": "8.29.1",
|
"@typescript-eslint/type-utils": "8.30.1",
|
||||||
"@typescript-eslint/utils": "8.29.1",
|
"@typescript-eslint/utils": "8.30.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.29.1",
|
"@typescript-eslint/visitor-keys": "8.30.1",
|
||||||
"graphemer": "^1.4.0",
|
"graphemer": "^1.4.0",
|
||||||
"ignore": "^5.3.1",
|
"ignore": "^5.3.1",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
@@ -2400,16 +2400,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/parser": {
|
"node_modules/@typescript-eslint/parser": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz",
|
||||||
"integrity": "sha512-zczrHVEqEaTwh12gWBIJWj8nx+ayDcCJs06yoNMY0kwjMWDM6+kppljY+BxWI06d2Ja+h4+WdufDcwMnnMEWmg==",
|
"integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/scope-manager": "8.29.1",
|
"@typescript-eslint/scope-manager": "8.30.1",
|
||||||
"@typescript-eslint/types": "8.29.1",
|
"@typescript-eslint/types": "8.30.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.29.1",
|
"@typescript-eslint/typescript-estree": "8.30.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.29.1",
|
"@typescript-eslint/visitor-keys": "8.30.1",
|
||||||
"debug": "^4.3.4"
|
"debug": "^4.3.4"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2425,14 +2425,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/scope-manager": {
|
"node_modules/@typescript-eslint/scope-manager": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz",
|
||||||
"integrity": "sha512-2nggXGX5F3YrsGN08pw4XpMLO1Rgtnn4AzTegC2MDesv6q3QaTU5yU7IbS1tf1IwCR0Hv/1EFygLn9ms6LIpDA==",
|
"integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.29.1",
|
"@typescript-eslint/types": "8.30.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.29.1"
|
"@typescript-eslint/visitor-keys": "8.30.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2443,14 +2443,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/type-utils": {
|
"node_modules/@typescript-eslint/type-utils": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz",
|
||||||
"integrity": "sha512-DkDUSDwZVCYN71xA4wzySqqcZsHKic53A4BLqmrWFFpOpNSoxX233lwGu/2135ymTCR04PoKiEEEvN1gFYg4Tw==",
|
"integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/typescript-estree": "8.29.1",
|
"@typescript-eslint/typescript-estree": "8.30.1",
|
||||||
"@typescript-eslint/utils": "8.29.1",
|
"@typescript-eslint/utils": "8.30.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"ts-api-utils": "^2.0.1"
|
"ts-api-utils": "^2.0.1"
|
||||||
},
|
},
|
||||||
@@ -2467,9 +2467,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/types": {
|
"node_modules/@typescript-eslint/types": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz",
|
||||||
"integrity": "sha512-VT7T1PuJF1hpYC3AGm2rCgJBjHL3nc+A/bhOp9sGMKfi5v0WufsX/sHCFBfNTx2F+zA6qBc/PD0/kLRLjdt8mQ==",
|
"integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -2481,14 +2481,14 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/typescript-estree": {
|
"node_modules/@typescript-eslint/typescript-estree": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz",
|
||||||
"integrity": "sha512-l1enRoSaUkQxOQnbi0KPUtqeZkSiFlqrx9/3ns2rEDhGKfTa+88RmXqedC1zmVTOWrLc2e6DEJrTA51C9iLH5g==",
|
"integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.29.1",
|
"@typescript-eslint/types": "8.30.1",
|
||||||
"@typescript-eslint/visitor-keys": "8.29.1",
|
"@typescript-eslint/visitor-keys": "8.30.1",
|
||||||
"debug": "^4.3.4",
|
"debug": "^4.3.4",
|
||||||
"fast-glob": "^3.3.2",
|
"fast-glob": "^3.3.2",
|
||||||
"is-glob": "^4.0.3",
|
"is-glob": "^4.0.3",
|
||||||
@@ -2508,16 +2508,16 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/utils": {
|
"node_modules/@typescript-eslint/utils": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz",
|
||||||
"integrity": "sha512-QAkFEbytSaB8wnmB+DflhUPz6CLbFWE2SnSCrRMEa+KnXIzDYbpsn++1HGvnfAsUY44doDXmvRkO5shlM/3UfA==",
|
"integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eslint-community/eslint-utils": "^4.4.0",
|
"@eslint-community/eslint-utils": "^4.4.0",
|
||||||
"@typescript-eslint/scope-manager": "8.29.1",
|
"@typescript-eslint/scope-manager": "8.30.1",
|
||||||
"@typescript-eslint/types": "8.29.1",
|
"@typescript-eslint/types": "8.30.1",
|
||||||
"@typescript-eslint/typescript-estree": "8.29.1"
|
"@typescript-eslint/typescript-estree": "8.30.1"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||||
@@ -2532,13 +2532,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@typescript-eslint/visitor-keys": {
|
"node_modules/@typescript-eslint/visitor-keys": {
|
||||||
"version": "8.29.1",
|
"version": "8.30.1",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.29.1.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz",
|
||||||
"integrity": "sha512-RGLh5CRaUEf02viP5c1Vh1cMGffQscyHe7HPAzGpfmfflFg1wUz2rYxd+OZqwpeypYvZ8UxSxuIpF++fmOzEcg==",
|
"integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@typescript-eslint/types": "8.29.1",
|
"@typescript-eslint/types": "8.30.1",
|
||||||
"eslint-visitor-keys": "^4.2.0"
|
"eslint-visitor-keys": "^4.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3615,9 +3615,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/electron-to-chromium": {
|
"node_modules/electron-to-chromium": {
|
||||||
"version": "1.5.136",
|
"version": "1.5.137",
|
||||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.136.tgz",
|
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.137.tgz",
|
||||||
"integrity": "sha512-kL4+wUTD7RSA5FHx5YwWtjDnEEkIIikFgWHR4P6fqjw1PPLlqYkxeOb++wAauAssat0YClCy8Y3C5SxgSkjibQ==",
|
"integrity": "sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
@@ -5425,9 +5425,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/jackspeak": {
|
"node_modules/jackspeak": {
|
||||||
"version": "3.4.3",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
|
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz",
|
||||||
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
|
"integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BlueOak-1.0.0",
|
"license": "BlueOak-1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -5438,7 +5438,10 @@
|
|||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
"@pkgjs/parseargs": "^0.11.0"
|
"@pkgjs/parseargs": "^0.11.0"
|
||||||
}
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
},
|
},
|
||||||
"node_modules/jake": {
|
"node_modules/jake": {
|
||||||
"version": "10.9.2",
|
"version": "10.9.2",
|
||||||
@@ -7295,9 +7298,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/openai": {
|
"node_modules/openai": {
|
||||||
"version": "4.93.0",
|
"version": "4.94.0",
|
||||||
"resolved": "https://registry.npmjs.org/openai/-/openai-4.93.0.tgz",
|
"resolved": "https://registry.npmjs.org/openai/-/openai-4.94.0.tgz",
|
||||||
"integrity": "sha512-2kONcISbThKLfm7T9paVzg+QCE1FOZtNMMUfXyXckUAoXRRS/mTP89JSDHPMp8uM5s0bz28RISbvQjArD6mgUQ==",
|
"integrity": "sha512-WVmr9HWcwfouLJ7R3UHd2A93ClezTPuJljQxkCYQAL15Sjyt+FBNoqEz5MHSdH/ebQrVyvRhFyn/bvdqtSPyIA==",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "^18.11.18",
|
"@types/node": "^18.11.18",
|
||||||
@@ -7532,28 +7535,34 @@
|
|||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/path-scurry": {
|
"node_modules/path-scurry": {
|
||||||
"version": "1.11.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
|
"version": "2.0.0",
|
||||||
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
|
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "BlueOak-1.0.0",
|
"license": "BlueOak-1.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^10.2.0",
|
"lru-cache": "^11.0.0",
|
||||||
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
|
"minipass": "^7.1.2"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16 || 14 >=14.18"
|
"node": "20 || >=22"
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/path-scurry/node_modules/lru-cache": {
|
"node_modules/path-scurry/node_modules/lru-cache": {
|
||||||
"version": "10.4.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
|
"version": "11.1.0",
|
||||||
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz",
|
||||||
|
"integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
@@ -7936,38 +7945,70 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rimraf": {
|
"node_modules/rimraf": {
|
||||||
"version": "5.0.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz",
|
"version": "6.0.1",
|
||||||
"integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-6.0.1.tgz",
|
||||||
|
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^10.3.7"
|
"glob": "^11.0.0",
|
||||||
|
"package-json-from-dist": "^1.0.0"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"rimraf": "dist/esm/bin.mjs"
|
"rimraf": "dist/esm/bin.mjs"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/rimraf/node_modules/glob": {
|
"node_modules/rimraf/node_modules/glob": {
|
||||||
"version": "10.4.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
|
"version": "11.0.1",
|
||||||
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
|
||||||
|
"integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
|
||||||
|
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"foreground-child": "^3.1.0",
|
"foreground-child": "^3.1.0",
|
||||||
"jackspeak": "^3.1.2",
|
|
||||||
"minimatch": "^9.0.4",
|
"jackspeak": "^4.0.1",
|
||||||
|
"minimatch": "^10.0.0",
|
||||||
"minipass": "^7.1.2",
|
"minipass": "^7.1.2",
|
||||||
"package-json-from-dist": "^1.0.0",
|
"package-json-from-dist": "^1.0.0",
|
||||||
"path-scurry": "^1.11.1"
|
"path-scurry": "^2.0.0"
|
||||||
|
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"glob": "dist/esm/bin.mjs"
|
"glob": "dist/esm/bin.mjs"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/rimraf/node_modules/minimatch": {
|
||||||
|
"version": "10.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.1.tgz",
|
||||||
|
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"brace-expansion": "^2.0.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "20 || >=22"
|
||||||
|
},
|
||||||
|
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/isaacs"
|
"url": "https://github.com/sponsors/isaacs"
|
||||||
}
|
}
|
||||||
@@ -8447,9 +8488,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/ts-jest": {
|
"node_modules/ts-jest": {
|
||||||
"version": "29.3.1",
|
"version": "29.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz",
|
||||||
"integrity": "sha512-FT2PIRtZABwl6+ZCry8IY7JZ3xMuppsEV9qFVHOVe8jDzggwUZ9TsM4chyJxL9yi6LvkqcZYU3LmapEE454zBQ==",
|
"integrity": "sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8461,7 +8502,7 @@
|
|||||||
"lodash.memoize": "^4.1.2",
|
"lodash.memoize": "^4.1.2",
|
||||||
"make-error": "^1.3.6",
|
"make-error": "^1.3.6",
|
||||||
"semver": "^7.7.1",
|
"semver": "^7.7.1",
|
||||||
"type-fest": "^4.38.0",
|
"type-fest": "^4.39.1",
|
||||||
"yargs-parser": "^21.1.1"
|
"yargs-parser": "^21.1.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
+1
-1
@@ -75,7 +75,7 @@
|
|||||||
"eslint": "^9.24.0",
|
"eslint": "^9.24.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"rimraf": "^5.0.5",
|
"rimraf": "^6.0.1",
|
||||||
"ts-jest": "^29.1.2",
|
"ts-jest": "^29.1.2",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3"
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export enum CONFIG_KEYS {
|
|||||||
OCO_ONE_LINE_COMMIT = 'OCO_ONE_LINE_COMMIT',
|
OCO_ONE_LINE_COMMIT = 'OCO_ONE_LINE_COMMIT',
|
||||||
OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE',
|
OCO_TEST_MOCK_TYPE = 'OCO_TEST_MOCK_TYPE',
|
||||||
OCO_API_URL = 'OCO_API_URL',
|
OCO_API_URL = 'OCO_API_URL',
|
||||||
|
OCO_API_CUSTOM_HEADERS = 'OCO_API_CUSTOM_HEADERS',
|
||||||
OCO_OMIT_SCOPE = 'OCO_OMIT_SCOPE',
|
OCO_OMIT_SCOPE = 'OCO_OMIT_SCOPE',
|
||||||
OCO_GITPUSH = 'OCO_GITPUSH' // todo: deprecate
|
OCO_GITPUSH = 'OCO_GITPUSH' // todo: deprecate
|
||||||
}
|
}
|
||||||
@@ -204,6 +205,22 @@ export const configValidators = {
|
|||||||
return value;
|
return value;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[CONFIG_KEYS.OCO_API_CUSTOM_HEADERS](value) {
|
||||||
|
try {
|
||||||
|
// Custom headers must be a valid JSON string
|
||||||
|
if (typeof value === 'string') {
|
||||||
|
JSON.parse(value);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
} catch (error) {
|
||||||
|
validateConfig(
|
||||||
|
CONFIG_KEYS.OCO_API_CUSTOM_HEADERS,
|
||||||
|
false,
|
||||||
|
'Must be a valid JSON string of headers'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
[CONFIG_KEYS.OCO_TOKENS_MAX_INPUT](value: any) {
|
[CONFIG_KEYS.OCO_TOKENS_MAX_INPUT](value: any) {
|
||||||
value = parseInt(value);
|
value = parseInt(value);
|
||||||
validateConfig(
|
validateConfig(
|
||||||
@@ -380,6 +397,7 @@ export type ConfigType = {
|
|||||||
[CONFIG_KEYS.OCO_TOKENS_MAX_INPUT]: number;
|
[CONFIG_KEYS.OCO_TOKENS_MAX_INPUT]: number;
|
||||||
[CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT]: number;
|
[CONFIG_KEYS.OCO_TOKENS_MAX_OUTPUT]: number;
|
||||||
[CONFIG_KEYS.OCO_API_URL]?: string;
|
[CONFIG_KEYS.OCO_API_URL]?: string;
|
||||||
|
[CONFIG_KEYS.OCO_API_CUSTOM_HEADERS]?: string;
|
||||||
[CONFIG_KEYS.OCO_DESCRIPTION]: boolean;
|
[CONFIG_KEYS.OCO_DESCRIPTION]: boolean;
|
||||||
[CONFIG_KEYS.OCO_EMOJI]: boolean;
|
[CONFIG_KEYS.OCO_EMOJI]: boolean;
|
||||||
[CONFIG_KEYS.OCO_WHY]: boolean;
|
[CONFIG_KEYS.OCO_WHY]: boolean;
|
||||||
@@ -462,6 +480,7 @@ const getEnvConfig = (envPath: string) => {
|
|||||||
OCO_MODEL: process.env.OCO_MODEL,
|
OCO_MODEL: process.env.OCO_MODEL,
|
||||||
OCO_API_URL: process.env.OCO_API_URL,
|
OCO_API_URL: process.env.OCO_API_URL,
|
||||||
OCO_API_KEY: process.env.OCO_API_KEY,
|
OCO_API_KEY: process.env.OCO_API_KEY,
|
||||||
|
OCO_API_CUSTOM_HEADERS: process.env.OCO_API_CUSTOM_HEADERS,
|
||||||
OCO_AI_PROVIDER: process.env.OCO_AI_PROVIDER as OCO_AI_PROVIDER_ENUM,
|
OCO_AI_PROVIDER: process.env.OCO_AI_PROVIDER as OCO_AI_PROVIDER_ENUM,
|
||||||
|
|
||||||
OCO_TOKENS_MAX_INPUT: parseConfigVarValue(process.env.OCO_TOKENS_MAX_INPUT),
|
OCO_TOKENS_MAX_INPUT: parseConfigVarValue(process.env.OCO_TOKENS_MAX_INPUT),
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ export interface AiEngineConfig {
|
|||||||
maxTokensOutput: number;
|
maxTokensOutput: number;
|
||||||
maxTokensInput: number;
|
maxTokensInput: number;
|
||||||
baseURL?: string;
|
baseURL?: string;
|
||||||
|
customHeaders?: Record<string, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client =
|
type Client =
|
||||||
|
|||||||
@@ -11,11 +11,18 @@ export class OllamaEngine implements AiEngine {
|
|||||||
|
|
||||||
constructor(config) {
|
constructor(config) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
|
// Combine base headers with custom headers
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...config.customHeaders
|
||||||
|
};
|
||||||
|
|
||||||
this.client = axios.create({
|
this.client = axios.create({
|
||||||
url: config.baseURL
|
url: config.baseURL
|
||||||
? `${config.baseURL}/${config.apiKey}`
|
? `${config.baseURL}/${config.apiKey}`
|
||||||
: 'http://localhost:11434/api/chat',
|
: 'http://localhost:11434/api/chat',
|
||||||
headers: { 'Content-Type': 'application/json' }
|
headers
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+17
-5
@@ -1,6 +1,7 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { OpenAI } from 'openai';
|
import { OpenAI } from 'openai';
|
||||||
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
|
import { GenerateCommitMessageErrorEnum } from '../generateCommitMessageFromGitDiff';
|
||||||
|
import { parseCustomHeaders } from '../utils/engine';
|
||||||
import { removeContentTags } from '../utils/removeContentTags';
|
import { removeContentTags } from '../utils/removeContentTags';
|
||||||
import { tokenCount } from '../utils/tokenCount';
|
import { tokenCount } from '../utils/tokenCount';
|
||||||
import { AiEngine, AiEngineConfig } from './Engine';
|
import { AiEngine, AiEngineConfig } from './Engine';
|
||||||
@@ -14,11 +15,22 @@ export class OpenAiEngine implements AiEngine {
|
|||||||
constructor(config: OpenAiConfig) {
|
constructor(config: OpenAiConfig) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
|
||||||
if (!config.baseURL) {
|
const clientOptions: OpenAI.ClientOptions = {
|
||||||
this.client = new OpenAI({ apiKey: config.apiKey });
|
apiKey: config.apiKey
|
||||||
} else {
|
};
|
||||||
this.client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL });
|
|
||||||
|
if (config.baseURL) {
|
||||||
|
clientOptions.baseURL = config.baseURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.customHeaders) {
|
||||||
|
const headers = parseCustomHeaders(config.customHeaders);
|
||||||
|
if (Object.keys(headers).length > 0) {
|
||||||
|
clientOptions.defaultHeaders = headers;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client = new OpenAI(clientOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public generateCommitMessage = async (
|
public generateCommitMessage = async (
|
||||||
@@ -42,7 +54,7 @@ export class OpenAiEngine implements AiEngine {
|
|||||||
this.config.maxTokensInput - this.config.maxTokensOutput
|
this.config.maxTokensInput - this.config.maxTokensOutput
|
||||||
)
|
)
|
||||||
throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens);
|
throw new Error(GenerateCommitMessageErrorEnum.tooMuchTokens);
|
||||||
|
|
||||||
const completion = await this.client.chat.completions.create(params);
|
const completion = await this.client.chat.completions.create(params);
|
||||||
|
|
||||||
const message = completion.choices[0].message;
|
const message = completion.choices[0].message;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const configureCommitlintIntegration = async (force = false) => {
|
|||||||
|
|
||||||
spin.start('Generating consistency with given @commitlint rules');
|
spin.start('Generating consistency with given @commitlint rules');
|
||||||
|
|
||||||
const prompts = inferPromptsFromCommitlintConfig(commitLintConfig);
|
const prompts = inferPromptsFromCommitlintConfig(commitLintConfig as any);
|
||||||
|
|
||||||
const consistencyPrompts =
|
const consistencyPrompts =
|
||||||
commitlintPrompts.GEN_COMMITLINT_CONSISTENCY_PROMPT(prompts);
|
commitlintPrompts.GEN_COMMITLINT_CONSISTENCY_PROMPT(prompts);
|
||||||
|
|||||||
@@ -56,30 +56,28 @@ const llmReadableRules: {
|
|||||||
blankline: (key, applicable) =>
|
blankline: (key, applicable) =>
|
||||||
`There should ${applicable} be a blank line at the beginning of the ${key}.`,
|
`There should ${applicable} be a blank line at the beginning of the ${key}.`,
|
||||||
caseRule: (key, applicable, value: string | Array<string>) =>
|
caseRule: (key, applicable, value: string | Array<string>) =>
|
||||||
`The ${key} should ${applicable} be in ${
|
`The ${key} should ${applicable} be in ${Array.isArray(value)
|
||||||
Array.isArray(value)
|
? `one of the following case:
|
||||||
? `one of the following case:
|
|
||||||
- ${value.join('\n - ')}.`
|
- ${value.join('\n - ')}.`
|
||||||
: `${value} case.`
|
: `${value} case.`
|
||||||
}`,
|
}`,
|
||||||
emptyRule: (key, applicable) => `The ${key} should ${applicable} be empty.`,
|
emptyRule: (key, applicable) => `The ${key} should ${applicable} be empty.`,
|
||||||
enumRule: (key, applicable, value: string | Array<string>) =>
|
enumRule: (key, applicable, value: string | Array<string>) =>
|
||||||
`The ${key} should ${applicable} be one of the following values:
|
`The ${key} should ${applicable} be one of the following values:
|
||||||
- ${Array.isArray(value) ? value.join('\n - ') : value}.`,
|
- ${Array.isArray(value) ? value.join('\n - ') : value}.`,
|
||||||
enumTypeRule: (key, applicable, value: string | Array<string>, prompt) =>
|
enumTypeRule: (key, applicable, value: string | Array<string>, prompt) =>
|
||||||
`The ${key} should ${applicable} be one of the following values:
|
`The ${key} should ${applicable} be one of the following values:
|
||||||
- ${
|
- ${Array.isArray(value)
|
||||||
Array.isArray(value)
|
|
||||||
? value
|
? value
|
||||||
.map((v) => {
|
.map((v) => {
|
||||||
const description = getTypeRuleExtraDescription(v, prompt);
|
const description = getTypeRuleExtraDescription(v, prompt);
|
||||||
if (description) {
|
if (description) {
|
||||||
return `${v} (${description})`;
|
return `${v} (${description})`;
|
||||||
} else return v;
|
} else return v;
|
||||||
})
|
})
|
||||||
.join('\n - ')
|
.join('\n - ')
|
||||||
: value
|
: value
|
||||||
}.`,
|
}.`,
|
||||||
fullStopRule: (key, applicable, value: string) =>
|
fullStopRule: (key, applicable, value: string) =>
|
||||||
`The ${key} should ${applicable} end with '${value}'.`,
|
`The ${key} should ${applicable} end with '${value}'.`,
|
||||||
maxLengthRule: (key, applicable, value: string) =>
|
maxLengthRule: (key, applicable, value: string) =>
|
||||||
@@ -216,15 +214,15 @@ const STRUCTURE_OF_COMMIT = config.OCO_OMIT_SCOPE
|
|||||||
const GEN_COMMITLINT_CONSISTENCY_PROMPT = (
|
const GEN_COMMITLINT_CONSISTENCY_PROMPT = (
|
||||||
prompts: string[]
|
prompts: string[]
|
||||||
): OpenAI.Chat.Completions.ChatCompletionMessageParam[] => [
|
): OpenAI.Chat.Completions.ChatCompletionMessageParam[] => [
|
||||||
{
|
{
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: `${IDENTITY} Your mission is to create clean and comprehensive commit messages for two different changes in a single codebase and output them in the provided JSON format: one for a bug fix and another for a new feature.
|
content: `${IDENTITY} Your mission is to create clean and comprehensive commit messages for two different changes in a single codebase and output them in the provided JSON format: one for a bug fix and another for a new feature.
|
||||||
|
|
||||||
Here are the specific requirements and conventions that should be strictly followed:
|
Here are the specific requirements and conventions that should be strictly followed:
|
||||||
|
|
||||||
Commit Message Conventions:
|
Commit Message Conventions:
|
||||||
- The commit message consists of three parts: Header, Body, and Footer.
|
- The commit message consists of three parts: Header, Body, and Footer.
|
||||||
- Header:
|
- Header:
|
||||||
- Format: ${config.OCO_OMIT_SCOPE ? '`<type>: <subject>`' : '`<type>(<scope>): <subject>`'}
|
- Format: ${config.OCO_OMIT_SCOPE ? '`<type>: <subject>`' : '`<type>(<scope>): <subject>`'}
|
||||||
- ${prompts.join('\n- ')}
|
- ${prompts.join('\n- ')}
|
||||||
|
|
||||||
@@ -240,7 +238,7 @@ JSON Output Format:
|
|||||||
"commitDescription": "<Description of commit for both the bug fix and the feature>"
|
"commitDescription": "<Description of commit for both the bug fix and the feature>"
|
||||||
}
|
}
|
||||||
\`\`\`
|
\`\`\`
|
||||||
- The "commitDescription" should not include the commit message’s header, only the description.
|
- The "commitDescription" should not include the commit message's header, only the description.
|
||||||
- Description should not be more than 74 characters.
|
- Description should not be more than 74 characters.
|
||||||
|
|
||||||
Additional Details:
|
Additional Details:
|
||||||
@@ -248,9 +246,9 @@ Additional Details:
|
|||||||
- Allowing the server to listen on a port specified through the environment variable is considered a new feature.
|
- Allowing the server to listen on a port specified through the environment variable is considered a new feature.
|
||||||
|
|
||||||
Example Git Diff is to follow:`
|
Example Git Diff is to follow:`
|
||||||
},
|
},
|
||||||
INIT_DIFF_PROMPT
|
INIT_DIFF_PROMPT
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prompt to have LLM generate a message using @commitlint rules.
|
* Prompt to have LLM generate a message using @commitlint rules.
|
||||||
@@ -264,30 +262,25 @@ const INIT_MAIN_PROMPT = (
|
|||||||
prompts: string[]
|
prompts: string[]
|
||||||
): OpenAI.Chat.Completions.ChatCompletionMessageParam => ({
|
): OpenAI.Chat.Completions.ChatCompletionMessageParam => ({
|
||||||
role: 'system',
|
role: 'system',
|
||||||
content: `${IDENTITY} Your mission is to create clean and comprehensive commit messages in the given @commitlint convention and explain WHAT were the changes ${
|
content: `${IDENTITY} Your mission is to create clean and comprehensive commit messages in the given @commitlint convention and explain WHAT were the changes ${config.OCO_WHY ? 'and WHY the changes were done' : ''
|
||||||
config.OCO_WHY ? 'and WHY the changes were done' : ''
|
}. I'll send you an output of 'git diff --staged' command, and you convert it into a commit message.
|
||||||
}. I'll send you an output of 'git diff --staged' command, and you convert it into a commit message.
|
${config.OCO_EMOJI
|
||||||
${
|
? 'Use GitMoji convention to preface the commit.'
|
||||||
config.OCO_EMOJI
|
: 'Do not preface the commit with anything.'
|
||||||
? 'Use GitMoji convention to preface the commit.'
|
}
|
||||||
: 'Do not preface the commit with anything.'
|
${config.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."
|
||||||
config.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."
|
|
||||||
}
|
|
||||||
Use the present tense. Use ${language} to answer.
|
Use the present tense. Use ${language} to answer.
|
||||||
${
|
${config.OCO_ONE_LINE_COMMIT
|
||||||
config.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.'
|
||||||
? '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.'
|
: ''
|
||||||
: ''
|
}
|
||||||
}
|
${config.OCO_OMIT_SCOPE
|
||||||
${
|
? 'Do not include a scope in the commit message format. Use the format: <type>: <subject>'
|
||||||
config.OCO_OMIT_SCOPE
|
: ''
|
||||||
? 'Do not include a scope in the commit message format. Use the format: <type>: <subject>'
|
}
|
||||||
: ''
|
|
||||||
}
|
|
||||||
You will strictly follow the following conventions to generate the content of the commit message:
|
You will strictly follow the following conventions to generate the content of the commit message:
|
||||||
- ${prompts.join('\n- ')}
|
- ${prompts.join('\n- ')}
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ export const getCommitLintPWDConfig =
|
|||||||
* ES Module (commitlint@v19.x.x. <= )
|
* ES Module (commitlint@v19.x.x. <= )
|
||||||
* Directory import is not supported in ES Module resolution, so import the file directly
|
* Directory import is not supported in ES Module resolution, so import the file directly
|
||||||
*/
|
*/
|
||||||
modulePath = await findModulePath('@commitlint/load/lib/load.js');
|
modulePath = findModulePath('@commitlint/load/lib/load.js');
|
||||||
load = (await import(modulePath)).default;
|
load = (await import(modulePath)).default;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
+24
-1
@@ -12,16 +12,39 @@ import { GroqEngine } from '../engine/groq';
|
|||||||
import { MLXEngine } from '../engine/mlx';
|
import { MLXEngine } from '../engine/mlx';
|
||||||
import { DeepseekEngine } from '../engine/deepseek';
|
import { DeepseekEngine } from '../engine/deepseek';
|
||||||
|
|
||||||
|
export function parseCustomHeaders(headers: any): Record<string, string> {
|
||||||
|
let parsedHeaders = {};
|
||||||
|
|
||||||
|
if (!headers) {
|
||||||
|
return parsedHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (typeof headers === 'object' && !Array.isArray(headers)) {
|
||||||
|
parsedHeaders = headers;
|
||||||
|
} else {
|
||||||
|
parsedHeaders = JSON.parse(headers);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('Invalid OCO_API_CUSTOM_HEADERS format, ignoring custom headers');
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsedHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
export function getEngine(): AiEngine {
|
export function getEngine(): AiEngine {
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
const provider = config.OCO_AI_PROVIDER;
|
const provider = config.OCO_AI_PROVIDER;
|
||||||
|
|
||||||
|
const customHeaders = parseCustomHeaders(config.OCO_API_CUSTOM_HEADERS);
|
||||||
|
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
model: config.OCO_MODEL!,
|
model: config.OCO_MODEL!,
|
||||||
maxTokensOutput: config.OCO_TOKENS_MAX_OUTPUT!,
|
maxTokensOutput: config.OCO_TOKENS_MAX_OUTPUT!,
|
||||||
maxTokensInput: config.OCO_TOKENS_MAX_INPUT!,
|
maxTokensInput: config.OCO_TOKENS_MAX_INPUT!,
|
||||||
baseURL: config.OCO_API_URL!,
|
baseURL: config.OCO_API_URL!,
|
||||||
apiKey: config.OCO_API_KEY!
|
apiKey: config.OCO_API_KEY!,
|
||||||
|
customHeaders
|
||||||
};
|
};
|
||||||
|
|
||||||
switch (provider) {
|
switch (provider) {
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ export function removeContentTags<T extends string | null | undefined>(content:
|
|||||||
result += content[i];
|
result += content[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize spaces (replace multiple spaces with a single space)
|
// Normalize multiple spaces/tabs into a single space (preserves newlines), then trim.
|
||||||
result = result.replace(/\s+/g, ' ').trim();
|
result = result.replace(/[ \t]+/g, ' ').trim();
|
||||||
|
|
||||||
return result as unknown as T;
|
return result as unknown as T;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-9
@@ -1,13 +1,6 @@
|
|||||||
// Using Node.js module interop for ESM/CommonJS compatibility
|
|
||||||
import { createRequire } from 'module';
|
|
||||||
|
|
||||||
// Create a require function scoped to this module
|
|
||||||
const moduleRequire = createRequire(import.meta.url);
|
|
||||||
|
|
||||||
// Use the scoped require to import CommonJS modules
|
|
||||||
moduleRequire('cli-testing-library/extend-expect');
|
|
||||||
import { configure } from 'cli-testing-library';
|
|
||||||
import { jest } from '@jest/globals';
|
import { jest } from '@jest/globals';
|
||||||
|
import 'cli-testing-library/extend-expect';
|
||||||
|
import { configure } from 'cli-testing-library';
|
||||||
|
|
||||||
// Make Jest available globally
|
// Make Jest available globally
|
||||||
global.jest = jest;
|
global.jest = jest;
|
||||||
|
|||||||
@@ -122,6 +122,30 @@ describe('config', () => {
|
|||||||
expect(config.OCO_ONE_LINE_COMMIT).toEqual(false);
|
expect(config.OCO_ONE_LINE_COMMIT).toEqual(false);
|
||||||
expect(config.OCO_OMIT_SCOPE).toEqual(true);
|
expect(config.OCO_OMIT_SCOPE).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle custom HTTP headers correctly', async () => {
|
||||||
|
globalConfigFile = await generateConfig('.opencommit', {
|
||||||
|
OCO_API_CUSTOM_HEADERS: '{"X-Global-Header": "global-value"}'
|
||||||
|
});
|
||||||
|
|
||||||
|
envConfigFile = await generateConfig('.env', {
|
||||||
|
OCO_API_CUSTOM_HEADERS: '{"Authorization": "Bearer token123", "X-Custom-Header": "test-value"}'
|
||||||
|
});
|
||||||
|
|
||||||
|
const config = getConfig({
|
||||||
|
globalPath: globalConfigFile.filePath,
|
||||||
|
envPath: envConfigFile.filePath
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(config).not.toEqual(null);
|
||||||
|
expect(config.OCO_API_CUSTOM_HEADERS).toEqual({"Authorization": "Bearer token123", "X-Custom-Header": "test-value"});
|
||||||
|
|
||||||
|
// No need to parse JSON again since it's already an object
|
||||||
|
const parsedHeaders = config.OCO_API_CUSTOM_HEADERS;
|
||||||
|
expect(parsedHeaders).toHaveProperty('Authorization', 'Bearer token123');
|
||||||
|
expect(parsedHeaders).toHaveProperty('X-Custom-Header', 'test-value');
|
||||||
|
expect(parsedHeaders).not.toHaveProperty('X-Global-Header');
|
||||||
|
});
|
||||||
|
|
||||||
it('should handle empty local config correctly', async () => {
|
it('should handle empty local config correctly', async () => {
|
||||||
globalConfigFile = await generateConfig('.opencommit', {
|
globalConfigFile = await generateConfig('.opencommit', {
|
||||||
|
|||||||
Reference in New Issue
Block a user