git-aicommit 3.1.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,19 @@
1
+ name: Node.js Package
2
+
3
+ on:
4
+ release:
5
+ types: [created]
6
+
7
+ jobs:
8
+ publish-npm:
9
+ runs-on: ubuntu-latest
10
+ steps:
11
+ - uses: actions/checkout@v3
12
+ - uses: actions/setup-node@v3
13
+ with:
14
+ node-version: 16
15
+ registry-url: https://registry.npmjs.org/
16
+ - run: npm ci
17
+ - run: npm publish
18
+ env:
19
+ NODE_AUTH_TOKEN: ${{secrets.npm_token}}
package/README.md CHANGED
@@ -8,8 +8,10 @@ Tired of writing commit messages? Let the computer do it for you!
8
8
 
9
9
  ## Installation
10
10
 
11
+ It's recommended to use [bun](https://bun.sh/)
12
+
11
13
  ```bash
12
- npm install -g git-aicommit
14
+ bun install -g git-aicommit
13
15
  ```
14
16
 
15
17
  ## Configuration
@@ -34,28 +36,30 @@ touch $HOME/.git-aicommitrc
34
36
 
35
37
  ```js
36
38
  // $HOME/.git-aicommitrc
37
- module.exports = {
39
+ export default {
38
40
  openAiKey: process.env.OPENAI_API_KEY,
39
41
  addAllChangesBeforeCommit: true,
40
42
  autocommit: true,
41
43
  openCommitTextEditor: false,
42
- promptBeforeDiff: 'Read the following git diff for a multiple files:',
43
- promptAfterDiff: 'Generate 1 to 3 paragraphs to explain this diff to a human without mentioning changes themselves:',
44
+ language: 'english',
45
+ systemMessagePromptTemplate: '' +
46
+ 'You are expert AI, your job is to write clear and concise Git commit messages.' +
47
+ 'Your responsibility is to ensure that these messages accurately describe the changes made in each commit,' +
48
+ 'follow established guidelines. Provide a clear history of changes to the codebase.' +
49
+ 'Write 1-2 sentences. Output only the commit message without comments or other text.',
50
+ humanPromptTemplate: '' +
51
+ 'Read the following git diff for a multiple files and ' +
52
+ 'write 1-2 sentences commit message in {language}' +
53
+ 'without mentioning lines or files:\n' +
54
+ '{diff}',
44
55
  excludeFromDiff: [
45
- '*.lock'
56
+ '*.lock', '*.lockb'
46
57
  ],
47
58
  diffFilter: 'ACMRTUXB',
48
59
  completionPromptParams: {
49
- model: "text-davinci-002",
50
- max_tokens: 500,
51
- temperature: 0.2,
52
- top_p: 1,
53
- presence_penalty: 0,
54
- frequency_penalty: 0,
55
- best_of: 1,
56
- n: 1,
57
- stream: false,
58
- stop: ["\n\n\n"],
60
+ model: "gpt-3.5-turbo",
61
+ temperature: 0.0,
62
+ maxTokens: 1000,
59
63
  }
60
64
  }
61
65
  ```
package/autocommit.js CHANGED
@@ -1,31 +1,26 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env bun
2
2
 
3
- require('dotenv').config();
4
- const {Configuration, OpenAIApi} = require("openai");
5
- const {execSync, spawn} = require("child_process");
6
- const rc = require('rc');
3
+ import { execSync, spawn } from "child_process";
4
+ import rc from 'rc';
5
+ import { ChatOpenAI } from "langchain/chat_models";
6
+ import {ChatPromptTemplate, HumanMessagePromptTemplate, SystemMessagePromptTemplate} from "langchain/prompts";
7
+ import defaultConfig from './config.js';
8
+ import dotenv from 'dotenv';
7
9
 
8
- const defaultConfig = require('./config.js');
9
-
10
- // if (!fs.existsSync(configPath)) {
11
- // TODO: param to create default config file
12
- // const { defaultConfig } = require('./config.js');
13
- //
14
- // fs.writeFileSync(configPath, `module.exports = ${JSON.stringify(defaultConfig, null, 4)}`);
15
- // console.log(`Created default config file at ${configPath}`);
16
- // }
10
+ dotenv.config();
17
11
 
18
12
  const config = rc(
19
13
  'git-aicommit',
20
- defaultConfig,
21
- null,
22
- (content) => eval(content) // not good. but is it different from require()?
14
+ {
15
+ ...defaultConfig,
16
+ openAiKey: process.env.OPENAI_API_KEY,
17
+ },
23
18
  );
24
19
 
25
20
  try {
26
21
  execSync(
27
- 'git rev-parse --is-inside-work-tree 2>/dev/null',
28
- {encoding: 'utf8'}
22
+ 'git rev-parse --is-inside-work-tree',
23
+ {encoding: 'utf8', stdio: 'ignore'}
29
24
  );
30
25
  } catch (e) {
31
26
  console.error("This is not a git repository");
@@ -39,10 +34,11 @@ if (!config.openAiKey) {
39
34
 
40
35
  const excludeFromDiff = config.excludeFromDiff || [];
41
36
  const diffFilter = config.diffFilter || 'ACMRTUXB';
42
- const diffCommand = `git diff \
37
+ const diffCommand = `git diff --staged \
43
38
  --diff-filter=${diffFilter} \
44
- ${excludeFromDiff.map((pattern) => `-- ':(exclude)${pattern}'`).join(' ')} \
45
- 2>/dev/null
39
+ -- "${excludeFromDiff.map(
40
+ (pattern) => `:(exclude)${pattern}`
41
+ ).join(' ')}"
46
42
  `;
47
43
 
48
44
  const diff = execSync(diffCommand, {encoding: 'utf8'});
@@ -52,47 +48,43 @@ if (!diff) {
52
48
  process.exit(1);
53
49
  }
54
50
 
55
- const openai = new OpenAIApi(new Configuration({
56
- apiKey: config.openAiKey,
57
- }));
51
+ const openai = new ChatOpenAI({
52
+ modelName: config.modelName,
53
+ openAIApiKey: config.openAiKey,
54
+ temperature: config.temperature,
55
+ maxTokens: config.maxTokens,
56
+ });
58
57
 
59
- // create a prompt
60
- const prompt = `${config.promptBeforeDiff}
58
+ const systemMessagePromptTemplate = SystemMessagePromptTemplate.fromTemplate(config.systemMessagePromptTemplate)
59
+ const humanPromptTemplate = HumanMessagePromptTemplate.fromTemplate(config.humanPromptTemplate)
61
60
 
62
- ${diff}
61
+ const chatPrompt = ChatPromptTemplate.fromPromptMessages([
62
+ systemMessagePromptTemplate,
63
+ humanPromptTemplate,
64
+ ])
63
65
 
64
- ${config.promptAfterDiff}
66
+ const prompt = await chatPrompt.formatMessages({
67
+ diff: diff,
68
+ language: config.language,
69
+ })
65
70
 
66
- `;
71
+ const res = await openai.call(prompt)
72
+
73
+ const commitMessage = res.text.trim();
67
74
 
68
- openai
69
- .createCompletion({
70
- prompt,
71
- ...config.completionPromptParams
72
- })
73
- .then((data) => {
74
- const commitMessage = data.data.choices[0].text;
75
-
76
- if (!config.addAllChangesBeforeCommit) {
77
- console.log('addAllChangesBeforeCommit is false. Skipping git add --all');
78
- } else {
79
- execSync('git add --all', {encoding: 'utf8'});
80
- }
81
-
82
- if (!config.autocommit) {
83
- console.log(`Autocommit is disabled. Here is the message:\n ${commitMessage}`);
84
- } else {
85
- console.log(`Committing with following message:\n ${commitMessage}`);
86
- execSync(
87
- `git commit -m "${commitMessage.replace(/"/g, '')}"`,
88
- {encoding: 'utf8'}
89
- );
90
-
91
- if (config.openCommitTextEditor) {
92
- spawn('git', ['commit', '--amend'], {
93
- stdio: 'inherit'
94
- });
95
- }
96
- }
97
- });
98
75
 
76
+ if (!config.autocommit) {
77
+ console.log(`Autocommit is disabled. Here is the message:\n ${commitMessage}`);
78
+ } else {
79
+ console.log(`Committing with following message:\n ${commitMessage}`);
80
+ execSync(
81
+ `git commit -m "${commitMessage.replace(/"/g, '')}"`,
82
+ {encoding: 'utf8'}
83
+ );
84
+ }
85
+
86
+ if (config.openCommitTextEditor) {
87
+ spawn('git', ['commit', '--amend'], {
88
+ stdio: 'inherit'
89
+ });
90
+ }
package/config.js CHANGED
@@ -1,24 +1,26 @@
1
- module.exports = {
1
+ export default {
2
2
  openAiKey: process.env.OPENAI_API_KEY,
3
3
  addAllChangesBeforeCommit: true,
4
4
  autocommit: true,
5
5
  openCommitTextEditor: false,
6
- promptBeforeDiff: 'Read the following git diff for a multiple files:',
7
- promptAfterDiff: 'Generate 1 to 3 paragraphs to explain this diff to a human without mentioning changes themselves:',
6
+ language: 'english',
7
+ systemMessagePromptTemplate: '' +
8
+ 'You are expert AI, your job is to write clear and concise Git commit messages.' +
9
+ 'Your responsibility is to ensure that these messages accurately describe the changes made in each commit,' +
10
+ 'follow established guidelines. Provide a clear history of changes to the codebase.' +
11
+ 'Write 1-2 sentences. Output only the commit message without comments or other text.',
12
+ humanPromptTemplate: '' +
13
+ 'Read the following git diff for a multiple files and ' +
14
+ 'write 1-2 sentences commit message in {language}' +
15
+ 'without mentioning lines or files:\n' +
16
+ '{diff}',
8
17
  excludeFromDiff: [
9
- '*.lock'
18
+ '*.lock', '*.lockb'
10
19
  ],
11
20
  diffFilter: 'ACMRTUXB',
12
21
  completionPromptParams: {
13
- model: "text-davinci-002",
14
- max_tokens: 500,
15
- temperature: 0.2,
16
- top_p: 1,
17
- presence_penalty: 0,
18
- frequency_penalty: 0,
19
- best_of: 1,
20
- n: 1,
21
- stream: false,
22
- stop: ["\n\n\n"],
22
+ model: "gpt-3.5-turbo",
23
+ temperature: 0.0,
24
+ maxTokens: 1000,
23
25
  }
24
26
  }
package/package.json CHANGED
@@ -1,13 +1,15 @@
1
1
  {
2
2
  "name": "git-aicommit",
3
- "version": "3.1.0",
3
+ "version": "4.0.1",
4
4
  "description": "Generates auto commit messages with OpenAI GPT3 model",
5
5
  "main": "autocommit.js",
6
6
  "repository": "https://github.com/shanginn/autocommit",
7
7
  "author": "shanginn@gmail.com",
8
8
  "license": "MIT",
9
+ "type": "module",
9
10
  "dependencies": {
10
11
  "dotenv": "^16.0.2",
12
+ "langchain": "^0.0.47",
11
13
  "openai": "^3.0.0",
12
14
  "rc": "1.2.8"
13
15
  },
package/yarn-error.log DELETED
@@ -1,36 +0,0 @@
1
- Arguments:
2
- /Users/shanginn/.nvm/versions/node/v16.16.0/bin/node /usr/local/Cellar/yarn/1.22.19/libexec/bin/yarn.js init
3
-
4
- PATH:
5
- /Users/shanginn/.nvm/versions/node/v16.16.0/bin:/Users/shanginn/.bun/bin:/Users/shanginn/bin:/usr/local/bin:/Users/shanginn/go/bin:/Users/shanginn/.composer/vendor/bin/:/Users/shanginn/.local/share/solana/install/active_release/bin:/Users/shanginn/.bun/bin/:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Apple/usr/bin:/Applications/Wireshark.app/Contents/MacOS:/Users/shanginn/.cargo/bin
6
-
7
- Yarn version:
8
- 1.22.19
9
-
10
- Node version:
11
- 16.16.0
12
-
13
- Platform:
14
- darwin x64
15
-
16
- Trace:
17
- Error: canceled
18
- at Interface.<anonymous> (/usr/local/Cellar/yarn/1.22.19/libexec/lib/cli.js:137150:13)
19
- at Interface.emit (node:events:527:28)
20
- at Interface._ttyWrite (node:readline:1081:16)
21
- at ReadStream.onkeypress (node:readline:288:10)
22
- at ReadStream.emit (node:events:527:28)
23
- at emitKeys (node:internal/readline/utils:358:14)
24
- at emitKeys.next (<anonymous>)
25
- at ReadStream.onData (node:internal/readline/emitKeypressEvents:61:36)
26
- at ReadStream.emit (node:events:527:28)
27
- at addChunk (node:internal/streams/readable:315:12)
28
-
29
- npm manifest:
30
- No manifest
31
-
32
- yarn manifest:
33
- No manifest
34
-
35
- Lockfile:
36
- No lockfile