jeeves-git-commit 1.0.0
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.
- checksums.yaml +7 -0
- data/LICENSE +21 -0
- data/README.md +129 -0
- data/bin/jeeves +8 -0
- data/lib/jeeves/version.rb +3 -0
- data/lib/jeeves.rb +151 -0
- data/prompt +17 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0dd0e12b327978c0f394aabd34219bf22258b301cef48863cb3e0f9934ac22ab
|
4
|
+
data.tar.gz: aebc9e5ad350aa9590e851e60be5933762b810f1b27c5687bccbdaf7e3dcd440
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 05b9de03a92ad61959eab40ce88a8e8afdd301717cbe3a626fcea92aa2124c90682dfbbd2a36b87d0a9f63845fea062f8bdc4192efc4cf4a6f8f6a602a1f4284
|
7
|
+
data.tar.gz: cba84b40e5d16f40d929b06c30bbb3cd4ad57966373a5ae69d3099b0b48c246f93ebdfc828aa64943b537c7427731cdae33ef187b6a491b9d9917ea00adad661
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2025 Justin Bishop
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
# Jeeves
|
2
|
+
|
3
|
+
<p align="center">
|
4
|
+
<img src="jeeves.png" alt="Jeeves Logo" width="200">
|
5
|
+
</p>
|
6
|
+
|
7
|
+
Jeeves is a command-line tool that helps you create AI-powered Git commit messages. It streamlines your Git workflow by automatically generating meaningful commit messages based on your code changes.
|
8
|
+
|
9
|
+
## Features
|
10
|
+
|
11
|
+
- Generate intelligent commit messages based on your staged changes
|
12
|
+
- Option to automatically stage all changes before committing
|
13
|
+
- Option to push changes after committing
|
14
|
+
- Customizable AI prompts for tailored commit message generation
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
### Requirements
|
19
|
+
|
20
|
+
- Ruby 2.6 or higher
|
21
|
+
- Git
|
22
|
+
|
23
|
+
### Option 1: Install as a Gem (Recommended)
|
24
|
+
|
25
|
+
```bash
|
26
|
+
gem install jeeves-git-commit
|
27
|
+
```
|
28
|
+
|
29
|
+
This automatically adds Jeeves to your PATH.
|
30
|
+
|
31
|
+
### Option 2: Build and Install from Source
|
32
|
+
|
33
|
+
1. Clone this repository:
|
34
|
+
|
35
|
+
```bash
|
36
|
+
git clone https://github.com/jubishop/Jeeves.git
|
37
|
+
cd Jeeves
|
38
|
+
```
|
39
|
+
|
40
|
+
2. Build and install the gem:
|
41
|
+
|
42
|
+
```bash
|
43
|
+
gem build jeeves.gemspec
|
44
|
+
gem install jeeves-git-commit-*.gem
|
45
|
+
```
|
46
|
+
|
47
|
+
### Option 3: Use the Install Script
|
48
|
+
|
49
|
+
1. Clone this repository:
|
50
|
+
|
51
|
+
```bash
|
52
|
+
git clone https://github.com/jubishop/Jeeves.git
|
53
|
+
cd Jeeves
|
54
|
+
```
|
55
|
+
|
56
|
+
2. Run the install script:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
./install.sh
|
60
|
+
```
|
61
|
+
|
62
|
+
The script will:
|
63
|
+
- Install Jeeves to `/usr/local/bin` (or `~/.local/bin` if you don't have write access)
|
64
|
+
- Add the install location to your PATH if necessary
|
65
|
+
- Set up the config directory with the default prompt file
|
66
|
+
- Make sure the script is executable
|
67
|
+
|
68
|
+
### Option 4: Manual Installation
|
69
|
+
|
70
|
+
1. Clone this repository:
|
71
|
+
|
72
|
+
```bash
|
73
|
+
git clone https://github.com/jubishop/Jeeves.git
|
74
|
+
cd Jeeves
|
75
|
+
```
|
76
|
+
|
77
|
+
2. Make the script executable:
|
78
|
+
|
79
|
+
```bash
|
80
|
+
chmod +x bin/jeeves
|
81
|
+
```
|
82
|
+
|
83
|
+
3. Create a symbolic link to make Jeeves available globally:
|
84
|
+
|
85
|
+
```bash
|
86
|
+
ln -s "$(pwd)/bin/jeeves" /usr/local/bin/jeeves
|
87
|
+
```
|
88
|
+
|
89
|
+
## Usage
|
90
|
+
|
91
|
+
Navigate to your Git repository and run:
|
92
|
+
|
93
|
+
```bash
|
94
|
+
jeeves [options]
|
95
|
+
```
|
96
|
+
|
97
|
+
Options:
|
98
|
+
|
99
|
+
- `-a, --all`: Stage all changes before committing
|
100
|
+
- `-p, --push`: Push changes after committing
|
101
|
+
- `--version`: Show version information
|
102
|
+
- `-h, --help`: Show help message
|
103
|
+
|
104
|
+
## Configuration
|
105
|
+
|
106
|
+
Jeeves stores its configuration in `~/.config/jeeves/`. You can customize the AI prompt by editing the `prompt` file in this directory.
|
107
|
+
|
108
|
+
When you run Jeeves for the first time, if there's no prompt file in the config directory, it will check for a bundled prompt file in the same directory as the script and copy it to the config directory automatically.
|
109
|
+
|
110
|
+
## Examples
|
111
|
+
|
112
|
+
```bash
|
113
|
+
# Generate a commit message for already staged changes
|
114
|
+
jeeves
|
115
|
+
|
116
|
+
# Stage all changes and generate a commit message
|
117
|
+
jeeves -a
|
118
|
+
|
119
|
+
# Stage all changes, generate a commit message, and push
|
120
|
+
jeeves -a -p
|
121
|
+
```
|
122
|
+
|
123
|
+
## License
|
124
|
+
|
125
|
+
MIT
|
126
|
+
|
127
|
+
## Author
|
128
|
+
|
129
|
+
[Justin Bishop (jubishop)](https://github.com/jubishop)
|
data/bin/jeeves
ADDED
data/lib/jeeves.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'jeeves/version'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
require 'json'
|
5
|
+
require 'fileutils'
|
6
|
+
require 'tmpdir'
|
7
|
+
|
8
|
+
module Jeeves
|
9
|
+
class CLI
|
10
|
+
CONFIG_DIR = File.expand_path('~/.config/jeeves')
|
11
|
+
PROMPT_FILE = File.join(CONFIG_DIR, 'prompt')
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@options = {
|
15
|
+
all: false,
|
16
|
+
push: false
|
17
|
+
}
|
18
|
+
setup_config_dir
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse_options
|
22
|
+
require 'optparse'
|
23
|
+
|
24
|
+
OptionParser.new do |opts|
|
25
|
+
opts.banner = 'Usage: jeeves [options]'
|
26
|
+
opts.version = VERSION
|
27
|
+
|
28
|
+
opts.on('-a', '--all', 'Stage all changes before committing') do
|
29
|
+
@options[:all] = true
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on('-p', '--push', 'Push changes after committing') do
|
33
|
+
@options[:push] = true
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on('-h', '--help', 'Show this help message') do
|
37
|
+
puts opts
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
end.parse!
|
41
|
+
end
|
42
|
+
|
43
|
+
def run
|
44
|
+
parse_options
|
45
|
+
|
46
|
+
if @options[:all]
|
47
|
+
system('git add -A')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Get git diff of staged changes
|
51
|
+
diff = `git diff --staged`
|
52
|
+
|
53
|
+
if diff.empty?
|
54
|
+
puts "No changes staged for commit."
|
55
|
+
exit 1
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get AI-generated commit message
|
59
|
+
commit_message = generate_commit_message(diff)
|
60
|
+
|
61
|
+
# Write commit message to temp file for git to use
|
62
|
+
temp_file = File.join(Dir.tmpdir, 'jeeves_commit_message')
|
63
|
+
File.write(temp_file, commit_message)
|
64
|
+
|
65
|
+
# Commit with the generated message
|
66
|
+
system("git commit -F #{temp_file}")
|
67
|
+
|
68
|
+
# Clean up temp file
|
69
|
+
File.unlink(temp_file) if File.exist?(temp_file)
|
70
|
+
|
71
|
+
# Push if requested
|
72
|
+
if @options[:push]
|
73
|
+
puts "Pushing changes..."
|
74
|
+
system('git push')
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def setup_config_dir
|
81
|
+
unless Dir.exist?(CONFIG_DIR)
|
82
|
+
FileUtils.mkdir_p(CONFIG_DIR)
|
83
|
+
end
|
84
|
+
|
85
|
+
unless File.exist?(PROMPT_FILE)
|
86
|
+
# Check for bundled prompt file in the gem's data directory
|
87
|
+
gem_prompt = File.join(File.dirname(__FILE__), '..', '..', 'prompt')
|
88
|
+
|
89
|
+
if File.exist?(gem_prompt)
|
90
|
+
puts "Copying bundled prompt file to #{PROMPT_FILE}"
|
91
|
+
FileUtils.cp(gem_prompt, PROMPT_FILE)
|
92
|
+
puts "Prompt file installed successfully."
|
93
|
+
else
|
94
|
+
puts "Error: Prompt file not found at #{PROMPT_FILE}"
|
95
|
+
puts "No bundled prompt file found at #{gem_prompt}"
|
96
|
+
puts "Please create a prompt file with your custom prompt."
|
97
|
+
exit 1
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def generate_commit_message(diff)
|
103
|
+
api_key = ENV['OPENROUTER_API_KEY']
|
104
|
+
if api_key.nil? || api_key.empty?
|
105
|
+
puts "Error: OPENROUTER_API_KEY environment variable not set"
|
106
|
+
exit 1
|
107
|
+
end
|
108
|
+
|
109
|
+
model = ENV['GIT_COMMIT_MODEL'] || 'openai/gpt-4.1-mini'
|
110
|
+
|
111
|
+
prompt = File.read(PROMPT_FILE).gsub('{{DIFF}}', diff)
|
112
|
+
|
113
|
+
uri = URI.parse('https://openrouter.ai/api/v1/chat/completions')
|
114
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
115
|
+
http.use_ssl = true
|
116
|
+
|
117
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
118
|
+
request['Content-Type'] = 'application/json'
|
119
|
+
request['Authorization'] = "Bearer #{api_key}"
|
120
|
+
request['HTTP-Referer'] = 'https://github.com/jeeves-git-commit'
|
121
|
+
|
122
|
+
request.body = {
|
123
|
+
model: model,
|
124
|
+
messages: [
|
125
|
+
{ role: 'user', content: prompt }
|
126
|
+
],
|
127
|
+
max_tokens: 500
|
128
|
+
}.to_json
|
129
|
+
|
130
|
+
begin
|
131
|
+
response = http.request(request)
|
132
|
+
|
133
|
+
if response.code == '200'
|
134
|
+
result = JSON.parse(response.body)
|
135
|
+
commit_message = result['choices'][0]['message']['content'].strip
|
136
|
+
puts "Generated commit message:"
|
137
|
+
puts "------------------------"
|
138
|
+
puts commit_message
|
139
|
+
puts "------------------------"
|
140
|
+
return commit_message
|
141
|
+
else
|
142
|
+
puts "API Error (#{response.code}): #{response.body}"
|
143
|
+
exit 1
|
144
|
+
end
|
145
|
+
rescue => e
|
146
|
+
puts "Error: #{e.message}"
|
147
|
+
exit 1
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
data/prompt
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
Generate a git commit message based on the following diff.
|
2
|
+
|
3
|
+
The commit message should:
|
4
|
+
- Start with an appropriate gitmoji based on the nature of the changes
|
5
|
+
- Follow the Conventional Commits format (https://www.conventionalcommits.org/en/v1.0.0/)
|
6
|
+
- Explain WHAT changed, WHY it changed, and HOW it improves or fixes the current state
|
7
|
+
- Assume the audience is educated software engineers
|
8
|
+
|
9
|
+
Example format:
|
10
|
+
:emoji: type(scope): concise description
|
11
|
+
|
12
|
+
Detailed explanation of the changes, why they were necessary, and their impact.
|
13
|
+
|
14
|
+
Additional context or technical details when relevant.
|
15
|
+
|
16
|
+
DIFF:
|
17
|
+
{{DIFF}}
|
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jeeves-git-commit
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Justin Bishop
|
8
|
+
bindir: bin
|
9
|
+
cert_chain: []
|
10
|
+
date: 2025-05-20 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: json
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '2.0'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '2.0'
|
26
|
+
description: Jeeves is a command-line tool that helps you create AI-powered Git commit
|
27
|
+
messages
|
28
|
+
email:
|
29
|
+
- jubishop@gmail.com
|
30
|
+
executables:
|
31
|
+
- jeeves
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- LICENSE
|
36
|
+
- README.md
|
37
|
+
- bin/jeeves
|
38
|
+
- lib/jeeves.rb
|
39
|
+
- lib/jeeves/version.rb
|
40
|
+
- prompt
|
41
|
+
homepage: https://github.com/jubishop/Jeeves
|
42
|
+
licenses:
|
43
|
+
- MIT
|
44
|
+
metadata: {}
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 2.6.0
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubygems_version: 3.6.6
|
60
|
+
specification_version: 4
|
61
|
+
summary: AI-powered Git commit message generator
|
62
|
+
test_files: []
|