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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc1d59ff49319c54e1f73ced0cbf81c80546300a72c2fbdcc167fb0fbbbf8424
4
- data.tar.gz: 72c46e4dbc7a18fa36c786416b39fa7ef54e664d551f0569f137c2ece8ddce2a
3
+ metadata.gz: dad9d6b1f2eb509d7db0ebdfec326224fbba0d93d03a58ef499c19c5cc09edce
4
+ data.tar.gz: 330abdd45bc9b6b2203d7095a006dd8e28ee5e6a5ab70b46e4eb508024a25970
5
5
  SHA512:
6
- metadata.gz: 9e3f8c6187d3162752779729cb2e2c57736e5fa7df6ee949569b36c15f3452df1e06cf819e2459de97b82f5a4071572c29d961ce6fcc39b85e598e257ce09b5a
7
- data.tar.gz: 112fdd778c200dbf88a0f91cf4ac643e891aa5d98cf925e30f953f9ceb39d1d4a510b1d3922e8962957ec5d25fe3dfdb5c21067bf98055f915cf3e8f93c3963e
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 = `git commit -m "#{message}"`
102
+ result = system("git", "commit", "-m", message)
103
103
 
104
- if $?.exitstatus == 0
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
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Ai
4
4
  module Commit
5
- VERSION = "0.1.0"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
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.1.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-27 00:00:00.000000000 Z
10
+ date: 2025-08-29 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: thor