smart-commit 0.1.0 ā 0.3.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 +4 -4
- data/CHANGELOG.md +16 -0
- data/lib/ai/commit/claude_client.rb +45 -0
- data/lib/ai/commit/cli.rb +114 -6
- data/lib/ai/commit/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dad9d6b1f2eb509d7db0ebdfec326224fbba0d93d03a58ef499c19c5cc09edce
|
4
|
+
data.tar.gz: 330abdd45bc9b6b2203d7095a006dd8e28ee5e6a5ab70b46e4eb508024a25970
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a6cf9f1cf6f8ebed20bd9cd5d30d2e749ee225b2d30f7ed42030f711e72fd03d9f3394414c8606e8716e6ac814fde14c8141b8e0218b2421a7bb36a449a4f1d8
|
7
|
+
data.tar.gz: ba82f0de0a01dca041914cca4e714f8f4a142b1d606e66461426252b3633697094c51d472252c2a25f410c95b43484a0dc90e220bc10dd51821058b15c3a25b9
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
## [Unreleased]
|
2
2
|
|
3
|
+
## [0.3.0] - 2025-01-27
|
4
|
+
|
5
|
+
### Added
|
6
|
+
- Regenerate functionality for commit messages with user feedback
|
7
|
+
- Users can now provide specific feedback to improve AI-generated commit messages
|
8
|
+
- Recursive regeneration - users can regenerate multiple times with different feedback
|
9
|
+
- Enhanced prompt that incorporates user feedback for better message generation
|
10
|
+
|
11
|
+
## [0.2.0] - 2025-01-27
|
12
|
+
|
13
|
+
### Added
|
14
|
+
- Edit functionality for commit messages in the `commit` command
|
15
|
+
- Users can now modify AI-generated commit messages before committing
|
16
|
+
- Support for custom editor via `$EDITOR` or `$VISUAL` environment variables
|
17
|
+
- Fallback to `nano` editor if no default editor is configured
|
18
|
+
|
3
19
|
## [0.1.0] - 2025-08-25
|
4
20
|
|
5
21
|
- Initial release
|
@@ -20,6 +20,13 @@ module Ai
|
|
20
20
|
extract_message(response)
|
21
21
|
end
|
22
22
|
|
23
|
+
def generate_commit_message_with_feedback(prev_message, diff, feedback)
|
24
|
+
prompt = build_prompt_with_feedback(prev_message, diff, feedback)
|
25
|
+
|
26
|
+
response = make_request(prompt)
|
27
|
+
extract_message(response)
|
28
|
+
end
|
29
|
+
|
23
30
|
private
|
24
31
|
|
25
32
|
def build_prompt(diff)
|
@@ -54,6 +61,44 @@ module Ai
|
|
54
61
|
PROMPT
|
55
62
|
end
|
56
63
|
|
64
|
+
def build_prompt_with_feedback(prev_message, diff, feedback)
|
65
|
+
custom_prompts = Config.custom_prompts
|
66
|
+
custom_prompt_text = custom_prompts.empty? ? '' : "\n\nAdditional context and preferences:\n#{custom_prompts.join("\n")}"
|
67
|
+
|
68
|
+
<<~PROMPT
|
69
|
+
You are a helpful assistant that generates conventional commit messages.
|
70
|
+
|
71
|
+
Based on the following git diff,
|
72
|
+
1. Use conventional commit format: type(scope): description
|
73
|
+
2. Keep subject line under 50 characters
|
74
|
+
3. Use imperative mood ("add" not "added")
|
75
|
+
4. Separate subject from body with blank line
|
76
|
+
5. Wrap body at 72 characters
|
77
|
+
6. Use 'feat' for new features, 'fix' for bug fixes, 'docs' for documentation, 'style' for formatting, 'refactor' for code refactoring, 'test' for tests, 'chore' for build/tooling
|
78
|
+
7. Be clear and specific about what changed, not just "update"
|
79
|
+
8. Explain the impact/benefit when relevant
|
80
|
+
9. Include scope based on file structure (e.g., auth, bank, api, components)
|
81
|
+
10. Reference any related components or services affected
|
82
|
+
11. For breaking changes, start with 'BREAKING CHANGE:'
|
83
|
+
12. Use bullet points in body for multiple changes
|
84
|
+
13. Reference ticket numbers when applicable
|
85
|
+
14. Match existing project commit style
|
86
|
+
|
87
|
+
#{custom_prompt_text}
|
88
|
+
|
89
|
+
You suggested a commit message of:
|
90
|
+
#{prev_message}
|
91
|
+
|
92
|
+
IMPORTANT: The user has provided feedback on a previous attempt. Please address their feedback:
|
93
|
+
"#{feedback}"
|
94
|
+
|
95
|
+
Git diff:
|
96
|
+
#{diff}
|
97
|
+
|
98
|
+
Change the commit message to address the feedback. and respond with the updated commit message.
|
99
|
+
PROMPT
|
100
|
+
end
|
101
|
+
|
57
102
|
def make_request(prompt)
|
58
103
|
uri = URI(API_URL)
|
59
104
|
http = Net::HTTP.new(uri.host, uri.port)
|
data/lib/ai/commit/cli.rb
CHANGED
@@ -94,21 +94,37 @@ module Ai
|
|
94
94
|
puts message
|
95
95
|
puts "=" * 50
|
96
96
|
|
97
|
-
print "\nCommit with this message? (y/N): "
|
97
|
+
print "\nCommit with this message? (y/N/e to edit/r to regenerate): "
|
98
98
|
response = STDIN.gets.chomp.downcase
|
99
99
|
|
100
100
|
if response == 'y' || response == 'yes'
|
101
101
|
puts "\nš Committing..."
|
102
|
-
result =
|
102
|
+
result = system("git", "commit", "-m", message)
|
103
103
|
|
104
|
-
if
|
104
|
+
if result
|
105
105
|
puts "ā
Successfully committed!"
|
106
|
-
puts result
|
107
106
|
else
|
108
|
-
puts "ā Failed to commit
|
109
|
-
puts result
|
107
|
+
puts "ā Failed to commit"
|
110
108
|
exit 1
|
111
109
|
end
|
110
|
+
elsif response == 'e' || response == 'edit'
|
111
|
+
edited_message = edit_message(message)
|
112
|
+
if edited_message && !edited_message.strip.empty?
|
113
|
+
puts "\nš Committing with edited message..."
|
114
|
+
result = system("git", "commit", "-m", edited_message)
|
115
|
+
|
116
|
+
if result
|
117
|
+
puts "ā
Successfully committed!"
|
118
|
+
else
|
119
|
+
puts "ā Failed to commit"
|
120
|
+
exit 1
|
121
|
+
end
|
122
|
+
else
|
123
|
+
puts "ā Commit cancelled."
|
124
|
+
exit 0
|
125
|
+
end
|
126
|
+
elsif response == 'r' || response == 'regenerate'
|
127
|
+
regenerate_with_feedback(message, diff, client)
|
112
128
|
else
|
113
129
|
puts "ā Commit cancelled."
|
114
130
|
exit 0
|
@@ -172,6 +188,98 @@ module Ai
|
|
172
188
|
puts "ā
Created #{prompts_file} with sample content"
|
173
189
|
puts "š Edit the file to add your custom prompts"
|
174
190
|
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
def edit_message(original_message)
|
195
|
+
puts "\nš Opening editor to modify commit message..."
|
196
|
+
puts "Original message will be loaded in your default editor."
|
197
|
+
puts "Save and close the editor to commit, or close without saving to cancel."
|
198
|
+
|
199
|
+
# Create a temporary file with the original message
|
200
|
+
require 'tempfile'
|
201
|
+
temp_file = Tempfile.new(['commit_message', '.txt'])
|
202
|
+
temp_file.write(original_message)
|
203
|
+
temp_file.close
|
204
|
+
|
205
|
+
# Get the default editor
|
206
|
+
editor = ENV['EDITOR'] || ENV['VISUAL'] || 'nano'
|
207
|
+
|
208
|
+
# Open the file in the editor
|
209
|
+
system("#{editor} #{temp_file.path}")
|
210
|
+
|
211
|
+
# Read the edited content
|
212
|
+
edited_content = File.read(temp_file.path)
|
213
|
+
temp_file.unlink
|
214
|
+
|
215
|
+
edited_content
|
216
|
+
end
|
217
|
+
|
218
|
+
def regenerate_with_feedback(prev_message, diff, client)
|
219
|
+
puts "\nš¬ What would you like to change about the commit message?"
|
220
|
+
puts "Examples: 'make it more concise', 'add more detail about the bug fix', 'change the type to feat'"
|
221
|
+
print "Feedback: "
|
222
|
+
feedback = STDIN.gets.chomp.strip
|
223
|
+
|
224
|
+
if feedback.empty?
|
225
|
+
puts "ā No feedback provided. Cancelling regeneration."
|
226
|
+
return
|
227
|
+
end
|
228
|
+
|
229
|
+
puts "\nš¤ Regenerating commit message with your feedback..."
|
230
|
+
|
231
|
+
begin
|
232
|
+
new_message = client.generate_commit_message_with_feedback(prev_message, diff, feedback)
|
233
|
+
|
234
|
+
puts "\n⨠New commit message:"
|
235
|
+
puts "=" * 50
|
236
|
+
puts new_message
|
237
|
+
puts "=" * 50
|
238
|
+
|
239
|
+
print "\nCommit with this message? (y/N/e to edit/r to regenerate again): "
|
240
|
+
response = STDIN.gets.chomp.downcase
|
241
|
+
|
242
|
+
if response == 'y' || response == 'yes'
|
243
|
+
puts "\nš Committing..."
|
244
|
+
result = system("git", "commit", "-m", new_message)
|
245
|
+
|
246
|
+
if result
|
247
|
+
puts "ā
Successfully committed!"
|
248
|
+
else
|
249
|
+
puts "ā Failed to commit"
|
250
|
+
exit 1
|
251
|
+
end
|
252
|
+
elsif response == 'e' || response == 'edit'
|
253
|
+
edited_message = edit_message(new_message)
|
254
|
+
if edited_message && !edited_message.strip.empty?
|
255
|
+
puts "\nš Committing with edited message..."
|
256
|
+
result = system("git", "commit", "-m", edited_message)
|
257
|
+
|
258
|
+
if result
|
259
|
+
puts "ā
Successfully committed!"
|
260
|
+
else
|
261
|
+
puts "ā Failed to commit"
|
262
|
+
exit 1
|
263
|
+
end
|
264
|
+
else
|
265
|
+
puts "ā Commit cancelled."
|
266
|
+
exit 0
|
267
|
+
end
|
268
|
+
elsif response == 'r' || response == 'regenerate'
|
269
|
+
regenerate_with_feedback(new_message, diff, client)
|
270
|
+
else
|
271
|
+
puts "ā Commit cancelled."
|
272
|
+
exit 0
|
273
|
+
end
|
274
|
+
|
275
|
+
rescue Error => e
|
276
|
+
puts "ā Error regenerating message: #{e.message}"
|
277
|
+
exit 1
|
278
|
+
rescue => e
|
279
|
+
puts "ā Unexpected error: #{e.message}"
|
280
|
+
exit 1
|
281
|
+
end
|
282
|
+
end
|
175
283
|
end
|
176
284
|
end
|
177
285
|
end
|
data/lib/ai/commit/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart-commit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Behrang Mirzamani
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2025-08-
|
10
|
+
date: 2025-08-29 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: thor
|