mirror of
https://github.com/di-sukharev/opencommit.git
synced 2026-01-13 07:38:01 -05:00
Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
226e21c28f | ||
|
|
0bb89abccc | ||
|
|
ad70a90b1f | ||
|
|
4deaf56e5a | ||
|
|
7c1fc10248 | ||
|
|
0c25a9e32c | ||
|
|
3f5df6ef7c | ||
|
|
6cb85e40e9 | ||
|
|
ba82d4d476 | ||
|
|
9bf2ed34a5 | ||
|
|
f6ab25ed1b | ||
|
|
83abd5ffd6 | ||
|
|
42c26cbaaa | ||
|
|
51613c2aea | ||
|
|
f04757f8af | ||
|
|
70f048672c | ||
|
|
a8a548ba5a | ||
|
|
eb09d5f4f6 | ||
|
|
801f6a9e7a | ||
|
|
b4f1bbdfe0 | ||
|
|
1ecad09e44 | ||
|
|
c57b5e394d | ||
|
|
8100d9beb8 | ||
|
|
84997faea2 | ||
|
|
8f60345008 | ||
|
|
c148048452 | ||
|
|
add8855bf9 | ||
|
|
0cc5be10f2 | ||
|
|
30d2d9d284 | ||
|
|
d69fa6c2d7 | ||
|
|
bf3b8c6ded | ||
|
|
f851ea1fff | ||
|
|
d6cbaf5f5f |
76
.github/workflows/codeql.yml
vendored
Normal file
76
.github/workflows/codeql.yml
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# For most projects, this workflow file will not need changing; you simply need
|
||||
# to commit it to your repository.
|
||||
#
|
||||
# You may wish to alter this file to override the set of languages analyzed,
|
||||
# or to provide custom queries or build logic.
|
||||
#
|
||||
# ******** NOTE ********
|
||||
# We have attempted to detect the languages in your repository. Please check
|
||||
# the `language` matrix defined below to confirm you have the correct set of
|
||||
# supported CodeQL languages.
|
||||
#
|
||||
name: "CodeQL"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ "master" ]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ "master" ]
|
||||
schedule:
|
||||
- cron: '21 16 * * 0'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'javascript' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
|
||||
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
||||
|
||||
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
||||
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
||||
|
||||
# - run: |
|
||||
# echo "Run, Build Application using script"
|
||||
# ./location_of_script_within_repo/buildscript.sh
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
20
.github/workflows/dependency-review.yml
vendored
Normal file
20
.github/workflows/dependency-review.yml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Dependency Review Action
|
||||
#
|
||||
# This Action will scan dependency manifest files that change as part of a Pull Request, surfacing known-vulnerable versions of the packages declared or updated in the PR. Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable packages will be blocked from merging.
|
||||
#
|
||||
# Source repository: https://github.com/actions/dependency-review-action
|
||||
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
|
||||
name: 'Dependency Review'
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
dependency-review:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 'Checkout Repository'
|
||||
uses: actions/checkout@v3
|
||||
- name: 'Dependency Review'
|
||||
uses: actions/dependency-review-action@v2
|
||||
28
.github/workflows/stale.yml
vendored
Normal file
28
.github/workflows/stale.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
# This workflow warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Mark stale issues and pull requests
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '27 21 * * *'
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 40
|
||||
stale-issue-message: 'Stale issue message'
|
||||
stale-pr-message: 'Stale pull request message'
|
||||
stale-issue-label: 'no-issue-activity'
|
||||
stale-pr-label: 'no-pr-activity'
|
||||
16
README.md
16
README.md
@@ -54,6 +54,18 @@ oc
|
||||
|
||||
## Features
|
||||
|
||||
### Switch to GPT-4
|
||||
|
||||
By default OpenCommit uses GPT-3.5-turbo (ChatGPT).
|
||||
|
||||
You may switch to GPT-4 which performs better, but costs ~x15 times more 🤠
|
||||
|
||||
```sh
|
||||
oc config set model=gpt-4
|
||||
```
|
||||
|
||||
Make sure you do lowercase `gpt-4`.
|
||||
|
||||
### Preface commits with emoji 🤠
|
||||
|
||||
[GitMoji](https://gitmoji.dev/) convention is used.
|
||||
@@ -99,6 +111,7 @@ oc config set language=fr
|
||||
oc config set language=French
|
||||
oc config set language=française
|
||||
```
|
||||
|
||||
The default language set is **English**
|
||||
All available languages are currently listed in the [i18n](https://github.com/di-sukharev/opencommit/tree/master/src/i18n) folder
|
||||
|
||||
@@ -117,6 +130,7 @@ git commit -m "${generatedMessage}" --no-verify
|
||||
```
|
||||
|
||||
### Ignore files
|
||||
|
||||
You can ignore files from submission to OpenAI by creating a `.opencommitignore` file. For example:
|
||||
|
||||
```ignorelang
|
||||
@@ -155,4 +169,4 @@ Or follow the process of your IDE Source Control feature, when it calls `git com
|
||||
|
||||
## Payments
|
||||
|
||||
You pay for your own requests to OpenAI API. OpenCommit uses ChatGPT official model, that is ~10x times cheaper than GPT-3 and ~6x times cheaper than GPT-4.
|
||||
You pay for your own requests to OpenAI API. OpenCommit uses ChatGPT (3.5-turbo) official model, that is ~15x times cheaper than GPT-4.
|
||||
|
||||
11
package-lock.json
generated
11
package-lock.json
generated
@@ -1,15 +1,16 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "1.1.47",
|
||||
"version": "2.0.8",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "opencommit",
|
||||
"version": "1.1.47",
|
||||
"version": "2.0.8",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "^0.6.1",
|
||||
"@dqbd/tiktoken": "^1.0.2",
|
||||
"axios": "^1.3.4",
|
||||
"chalk": "^5.2.0",
|
||||
"cleye": "^1.3.2",
|
||||
@@ -21,6 +22,7 @@
|
||||
},
|
||||
"bin": {
|
||||
"oc": "out/cli.cjs",
|
||||
"oco": "out/cli.cjs",
|
||||
"opencommit": "out/cli.cjs"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -83,6 +85,11 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@dqbd/tiktoken": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@dqbd/tiktoken/-/tiktoken-1.0.6.tgz",
|
||||
"integrity": "sha512-umSdeZTy/SbPPKVuZKV/XKyFPmXSN145CcM3iHjBbmhlohBJg7vaDp4cPCW+xNlWL6L2U1sp7T2BD+di2sUKdA=="
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.15.18",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.15.18.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "opencommit",
|
||||
"version": "1.1.47",
|
||||
"version": "2.0.8",
|
||||
"description": "GPT CLI to auto-generate impressive commits in 1 second. Killing lame commits with AI 🤯🔫",
|
||||
"keywords": [
|
||||
"git",
|
||||
@@ -17,7 +17,8 @@
|
||||
"main": "cli.js",
|
||||
"bin": {
|
||||
"opencommit": "./out/cli.cjs",
|
||||
"oc": "./out/cli.cjs"
|
||||
"oc": "./out/cli.cjs",
|
||||
"oco": "./out/cli.cjs"
|
||||
},
|
||||
"repository": {
|
||||
"url": "https://github.com/di-sukharev/opencommit"
|
||||
|
||||
@@ -13,6 +13,7 @@ const config = getConfig();
|
||||
|
||||
let apiKey = config?.OPENAI_API_KEY;
|
||||
let basePath = config?.OPENAI_BASE_PATH;
|
||||
let maxTokens = config?.OPENAI_MAX_TOKENS;
|
||||
|
||||
const [command, mode] = process.argv.slice(2);
|
||||
|
||||
@@ -29,6 +30,8 @@ if (!apiKey && command !== 'config' && mode !== CONFIG_MODES.set) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const MODEL = config?.model || 'gpt-3.5-turbo';
|
||||
|
||||
class OpenAi {
|
||||
private openAiApiConfiguration = new OpenAiApiConfiguration({
|
||||
apiKey: apiKey
|
||||
@@ -47,11 +50,11 @@ class OpenAi {
|
||||
): Promise<string | undefined> => {
|
||||
try {
|
||||
const { data } = await this.openAI.createChatCompletion({
|
||||
model: 'gpt-3.5-turbo',
|
||||
model: MODEL,
|
||||
messages,
|
||||
temperature: 0,
|
||||
top_p: 0.1,
|
||||
max_tokens: 196
|
||||
max_tokens: maxTokens ?? 196
|
||||
});
|
||||
|
||||
const message = data.choices[0].message;
|
||||
|
||||
@@ -73,7 +73,7 @@ ${chalk.grey('——————————————————')}`
|
||||
...extraArgs
|
||||
]);
|
||||
|
||||
outro(`${chalk.green('✔')} successfully committed`);
|
||||
outro(`${chalk.green('✔')} Successfully committed`);
|
||||
|
||||
outro(stdout);
|
||||
|
||||
@@ -102,7 +102,7 @@ ${chalk.grey('——————————————————')}`
|
||||
]);
|
||||
|
||||
pushSpinner.stop(
|
||||
`${chalk.green('✔')} successfully pushed all commits to ${remotes[0]}`
|
||||
`${chalk.green('✔')} Successfully pushed all commits to ${remotes[0]}`
|
||||
);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
@@ -126,7 +126,7 @@ ${chalk.grey('——————————————————')}`
|
||||
pushSpinner.stop(
|
||||
`${chalk.green(
|
||||
'✔'
|
||||
)} successfully pushed all commits to ${selectedRemote}`
|
||||
)} Successfully pushed all commits to ${selectedRemote}`
|
||||
);
|
||||
|
||||
if (stdout) outro(stdout);
|
||||
|
||||
@@ -10,9 +10,11 @@ import { getI18nLocal } from '../i18n';
|
||||
|
||||
export enum CONFIG_KEYS {
|
||||
OPENAI_API_KEY = 'OPENAI_API_KEY',
|
||||
OPENAI_MAX_TOKENS = 'OPENAI_MAX_TOKENS',
|
||||
OPENAI_BASE_PATH = 'OPENAI_BASE_PATH',
|
||||
description = 'description',
|
||||
emoji = 'emoji',
|
||||
model = 'model',
|
||||
language = 'language'
|
||||
}
|
||||
|
||||
@@ -62,6 +64,16 @@ export const configValidators = {
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.OPENAI_MAX_TOKENS](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.OPENAI_MAX_TOKENS,
|
||||
typeof value === 'number',
|
||||
'Must be a number'
|
||||
);
|
||||
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.emoji](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.emoji,
|
||||
@@ -88,6 +100,15 @@ export const configValidators = {
|
||||
`${value} is not supported yet`
|
||||
);
|
||||
return value;
|
||||
},
|
||||
|
||||
[CONFIG_KEYS.model](value: any) {
|
||||
validateConfig(
|
||||
CONFIG_KEYS.OPENAI_BASE_PATH,
|
||||
value === 'gpt-3.5-turbo' || value === 'gpt-4',
|
||||
`${value} is not supported yet, use 'gpt-4' or 'gpt-3.5-turbo' (default)`
|
||||
);
|
||||
return value;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -138,7 +159,7 @@ export const setConfig = (keyValues: [key: string, value: string][]) => {
|
||||
|
||||
writeFileSync(configPath, iniStringify(config), 'utf8');
|
||||
|
||||
outro(`${chalk.green('✔')} config successfully set`);
|
||||
outro(`${chalk.green('✔')} Config successfully set`);
|
||||
};
|
||||
|
||||
export const configCommand = command(
|
||||
|
||||
@@ -92,7 +92,7 @@ export const hookCommand = command(
|
||||
}
|
||||
|
||||
throw new Error(
|
||||
`unsupported mode: ${mode}. Supported modes are: 'set' or 'unset'`
|
||||
`Unsupported mode: ${mode}. Supported modes are: 'set' or 'unset'`
|
||||
);
|
||||
} catch (error) {
|
||||
outro(`${chalk.red('✖')} ${error}`);
|
||||
|
||||
@@ -15,7 +15,7 @@ const INIT_MESSAGES_PROMPT: Array<ChatCompletionRequestMessage> = [
|
||||
{
|
||||
role: ChatCompletionRequestMessageRoleEnum.System,
|
||||
// prettier-ignore
|
||||
content: `You are to act as the author of a commit message in git. Your mission is to create clean and comprehensive commit messages in the conventional commit convention and explain why a change was done. I'll send you an output of 'git diff --staged' command, and you convert it into a commit message.
|
||||
content: `You are to act as the author of a commit message in git. Your mission is to create clean and comprehensive commit messages in the conventional commit convention and explain WHAT were the changes 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.
|
||||
${config?.emoji? 'Use GitMoji convention to preface the commit.': 'Do not preface the commit with anything.'}
|
||||
${config?.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. Lines must not be longer than 74 characters. Use ${translation.localLanguage} to answer.`
|
||||
|
||||
6
src/i18n/cs.json
Normal file
6
src/i18n/cs.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"localLanguage": "česky",
|
||||
"commitFix": "fix(server.ts): zlepšení velikosti proměnné port na velká písmena PORT",
|
||||
"commitFeat": "feat(server.ts): přidání podpory pro proměnnou prostředí process.env.PORT",
|
||||
"commitDescription": "Proměnná port se nyní jmenuje PORT, což odpovídá konvenci pojmenování, protože PORT je konstanta. Podpora proměnné prostředí process.env.PORT umožňuje snadnější správu nastavení při spuštění."
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"localLanguage": "english",
|
||||
"commitFix": "fix(server.ts): change port variable case from lowercase port to uppercase PORT",
|
||||
"commitFeat": "feat(server.ts): add support for process.env.PORT environment variable",
|
||||
"commitFix": "fix(server.ts): change port variable case from lowercase port to uppercase PORT to improve semantics",
|
||||
"commitFeat": "feat(server.ts): add support for process.env.PORT environment variable to be able to run app on a configurable port",
|
||||
"commitDescription": "The port variable is now named PORT, which improves consistency with the naming conventions as PORT is a constant. Support for an environment variable allows the application to be more flexible as it can now run on any available port specified via the process.env.PORT environment variable."
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import en from '../i18n/en.json' assert { type: 'json' };
|
||||
import cs from '../i18n/cs.json' assert { type: 'json' };
|
||||
import de from '../i18n/de.json' assert { type: 'json' };
|
||||
import fr from '../i18n/fr.json' assert { type: 'json' };
|
||||
import it from '../i18n/it.json' assert { type: 'json' };
|
||||
@@ -14,6 +15,7 @@ import nl from '../i18n/nl.json' assert { type: 'json' };
|
||||
import ru from '../i18n/ru.json' assert { type: 'json' };
|
||||
import id_ID from '../i18n/id_ID.json' assert { type: 'json' };
|
||||
import pl from '../i18n/pl.json' assert { type: 'json' };
|
||||
import tr from '../i18n/tr.json' assert { type: 'json' };
|
||||
import th from '../i18n/th.json' assert { type: 'json' };
|
||||
|
||||
export enum I18nLocals {
|
||||
@@ -21,6 +23,7 @@ export enum I18nLocals {
|
||||
'zh_CN' = 'zh_CN',
|
||||
'zh_TW' = 'zh_TW',
|
||||
'ja' = 'ja',
|
||||
'cs' = 'cs',
|
||||
'de' = 'de',
|
||||
'fr' = 'fr',
|
||||
'nl' = 'nl',
|
||||
@@ -32,6 +35,7 @@ export enum I18nLocals {
|
||||
'ru' = 'ru',
|
||||
'id_ID' = 'id_ID',
|
||||
'pl' = 'pl',
|
||||
'tr' = 'tr',
|
||||
'th' = 'th',
|
||||
}
|
||||
|
||||
@@ -40,6 +44,7 @@ export const i18n = {
|
||||
zh_CN,
|
||||
zh_TW,
|
||||
ja,
|
||||
cs,
|
||||
de,
|
||||
fr,
|
||||
it,
|
||||
@@ -52,6 +57,7 @@ export const i18n = {
|
||||
nl,
|
||||
ru,
|
||||
pl,
|
||||
tr,
|
||||
th
|
||||
};
|
||||
|
||||
@@ -60,6 +66,7 @@ export const I18N_CONFIG_ALIAS: { [key: string]: string[] } = {
|
||||
zh_TW: ['zh_TW', '繁體中文', '繁體'],
|
||||
ja: ['ja', 'Japanese', 'にほんご'],
|
||||
ko: ['ko', 'Korean', '한국어'],
|
||||
cs: ['cs', 'Czech', 'česky'],
|
||||
de: ['de', 'German', 'Deutsch'],
|
||||
fr: ['fr', 'French', 'française'],
|
||||
it: ['it', 'Italian', 'italiano'],
|
||||
@@ -72,6 +79,7 @@ export const I18N_CONFIG_ALIAS: { [key: string]: string[] } = {
|
||||
ru: ['ru', 'Russian', 'русский'],
|
||||
id_ID: ['id_ID', 'Bahasa', 'bahasa'],
|
||||
pl: ['pl', 'Polish', 'Polski'],
|
||||
tr: ['tr', 'Turkish', 'Turkish'],
|
||||
th: ['th', 'Thai', 'ไทย']
|
||||
};
|
||||
|
||||
|
||||
6
src/i18n/tr.json
Normal file
6
src/i18n/tr.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"localLanguage": "Turkish",
|
||||
"commitFix": "fix(server.ts): port değişkeni küçük harfli porttan büyük harfli PORT'a değiştirildi",
|
||||
"commitFeat": "feat(server.ts): process.env.PORT ortam değişkeni için destek eklendi.",
|
||||
"commitDescription": "Bağlantı noktası değişkeni artık PORT olarak adlandırıldı ve PORT bir sabit değişken olduğu için bu adlandırma tutarlılığı artırır. Ortam değişkeni desteği, artık process.env.PORT ortam değişkeni aracılığıyla belirtilen herhangi bir kullanılabilir bağlantı noktasında çalışabileceğinden uygulamanın daha esnek olmasını sağlar."
|
||||
}
|
||||
@@ -10,6 +10,4 @@ export function tokenCount(content: string): number {
|
||||
const tokens = encoding.encode(content);
|
||||
encoding.free();
|
||||
return tokens.length;
|
||||
|
||||
//return content.length / 2.7;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user