ai-commit-message 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ef95bc52d9e0600b53c10e093a2d3c057e61f8746d59495f16e0f29c68699995
4
+ data.tar.gz: 531a062526261dd27b1927660b817509aaa0fd79490f82ca3d16883aeab4c736
5
+ SHA512:
6
+ metadata.gz: e8306cabe049db41c31b8cf9568c8cb52771041e5d9c26671984de3bd9c3b16957a6de1178a5aebd6af35990faa0b634e7f888c61cbcc95aa3a4d49d6342c332
7
+ data.tar.gz: 6348572010d2362c88ec3e7a5bd53fa94233663b0887ab3f9201dc20803aabe11e434c9fb7ebbfa1c59ecc3afb195e18f6f8e6fbb9c035795b2675edd82c357e
data/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # ai-commit-message
2
+ Git commit message suggested by AI
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ require_relative '../lib/ai-commit-message/cli'
@@ -0,0 +1,41 @@
1
+ require 'thor'
2
+ require 'tty-prompt'
3
+ require_relative '../ai-commit-message/suggester'
4
+ require_relative 'config_manager'
5
+
6
+ module AiCommitMessage
7
+ class CLI < Thor
8
+ desc "commit", "Generate git commit message"
9
+ method_option :url, type: :string, default: 'http://localhost:11434/api/generate'
10
+ method_option :model, type: :string, default: 'qwen2.5-coder:7b'
11
+
12
+ def commit(options = {})
13
+ git_diff_output = `git diff --cached --no-color`
14
+ git_log_output = `git log --format=%s -n 30`
15
+ git_current_branch = `git branch --show-current`
16
+
17
+ url = options[:url] || ConfigManager.get_url || 'http://localhost:11434/api/generate'
18
+ model = options[:model] || ConfigManager.get_model || 'qwen2.5-coder:7b'
19
+
20
+ suggester = AiCommitMessage::Suggester.new(git_diff_output, git_log_output, git_current_branch)
21
+ commit_message = suggester.generate_commit_message(url:, model:)
22
+
23
+ puts commit_message
24
+ end
25
+
26
+ desc "config", "Set global configs. API URL and Model name"
27
+ def config
28
+ prompt = TTY::Prompt.new
29
+
30
+ url = prompt.ask("API URL:", default: ConfigManager.get_url || 'http://localhost:11434/api/generate')
31
+ model = prompt.ask("Model name:", default: ConfigManager.get_model || 'qwen2.5-coder:7b')
32
+
33
+ ConfigManager.set_url(url)
34
+ ConfigManager.set_model(model)
35
+
36
+ puts "Configuration updated successfully!"
37
+ end
38
+ end
39
+ end
40
+
41
+ AiCommitMessage::CLI.start
@@ -0,0 +1,38 @@
1
+ require 'fileutils'
2
+
3
+ class ConfigManager
4
+ CONFIG_FILE = File.expand_path('~/.ai-commit-message.conf')
5
+
6
+ def self.get_url = config['url']
7
+
8
+ def self.set_url(url)
9
+ config['url'] = url
10
+ save_config
11
+ end
12
+
13
+ def self.get_model = config['model']
14
+
15
+ def self.set_model(model)
16
+ config['model'] = model
17
+ save_config
18
+ end
19
+
20
+ private_class_method
21
+
22
+ def self.config
23
+ return @config if defined?(@config)
24
+
25
+ @config ||= {}
26
+
27
+ if File.exist?(CONFIG_FILE)
28
+ File.read(CONFIG_FILE).each_line do |line|
29
+ key, value = line.chomp.split('=')
30
+ @config[key.to_sym] = value
31
+ end
32
+ end
33
+
34
+ @config
35
+ end
36
+
37
+ def self.save_config = File.write(CONFIG_FILE, config.map { |key, value| "#{key}=#{value}" }.join("\n"))
38
+ end
@@ -0,0 +1,41 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'json'
4
+
5
+ module AiCommitMessage
6
+ class Suggester
7
+ def initialize(git_diff_output, git_log_output, git_current_branch)
8
+ @git_diff_output = git_diff_output
9
+ @git_log_output = git_log_output
10
+ @git_current_branch = git_current_branch
11
+ end
12
+
13
+ def generate_commit_message(url:, model:)
14
+ url = URI(url)
15
+ body = {
16
+ model: model,
17
+ prompt: "Create a concise git commit message with no more than 250 characters. Exclude anything unnecessary such as translation, backticks characters or multiple suggestions, since your entire response will be passed directly into git commit. Consider the following messages as example to follow: #{@git_log_output}.
18
+ The First [#XXX] option is the branch name. The current branch name is: #{@git_current_branch}. Now Do it for the following git diff: #{@git_diff_output}",
19
+ stream: false,
20
+ options: { temperature: 0.8 }
21
+ }
22
+ json_body = body.to_json
23
+ headers = { 'Content-Type' => 'application/json' }
24
+
25
+ http = Net::HTTP.new(url.host, url.port)
26
+ request = Net::HTTP::Post.new(url)
27
+ request.body = json_body
28
+ headers.each { |key, value| request[key] = value }
29
+ response = http.request(request)
30
+
31
+ begin
32
+ json = JSON.parse(response.body)
33
+ return json['response'] if json
34
+ rescue JSON::ParserError => e
35
+ puts "Failed to parse API response as JSON: #{e.message}"
36
+ end
37
+
38
+ nil
39
+ end
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ai-commit-message
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Afonso Neto
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2025-03-16 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: tty-prompt
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: net-http
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: json
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Git commit messages suggested by AI
70
+ email:
71
+ - afonso.pontesneto@gmail.com
72
+ executables:
73
+ - ai-commit-message
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - README.md
78
+ - bin/ai-commit-message
79
+ - lib/ai-commit-message/cli.rb
80
+ - lib/ai-commit-message/config_manager.rb
81
+ - lib/ai-commit-message/suggester.rb
82
+ homepage: https://github.com/AfonsoNeto/ai-commit-message
83
+ licenses:
84
+ -
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '3.0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubygems_version: 3.5.11
102
+ signing_key:
103
+ specification_version: 4
104
+ summary: Git commit messages suggested by AI
105
+ test_files: []