n2b 0.3.0 โ†’ 0.3.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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +89 -5
  3. data/lib/n2b/cli.rb +146 -7
  4. data/lib/n2b/version.rb +1 -1
  5. metadata +1 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 698bca4814bd42e8587efb9d278ce1cb090b3ea23afd645c9c082b1c277ea22d
4
- data.tar.gz: c7ec9715a8b5807b1ea5eb90e448fd70767fdc3e6ace987e1b123e29ee37dd33
3
+ metadata.gz: 644455363c88bf95c4ab4f21121ed6b8f56a591fb32bd1a8fa9f8f36d981e515
4
+ data.tar.gz: f899199e26524f38f88e4416217616c048e588c1f54becb228261b07ffcda3d1
5
5
  SHA512:
6
- metadata.gz: 7d00b68b8e2925b63d4bf6b2e4842a18034e2dc318686d55261480c2612f47f8574379df85ae166670a721aa6bd41406d08323cddb0ebd831e3777dc1773ca1a
7
- data.tar.gz: e7b3621fcf9051d433ca0fba961b12d348b03f9d73981d641b252b4a4223b8edfec0f8ee438f6c603382ca62c1cf4679e9960f6c40f16b84c644d6939290dbe5
6
+ metadata.gz: 2b3cfcba02a3c41017737317df2d932e1ff053c2d470c529a3158ccba11696ccf09367369f4530de78fc7669cc26795a3dad8abe49a26da0f5a8f836758baf4d
7
+ data.tar.gz: f664e6b0e9099aecc969e7d46a71b7cf7da0bf1238e9fbf203f445bed9d7073c2a643cce09a3a50fc1ce666805505c7e8d6222817a207fd3b4ec9491c8fcd4e4
data/README.md CHANGED
@@ -6,10 +6,15 @@ N2B (Natural Language to Bash & Ruby) is a Ruby gem that leverages AI to convert
6
6
 
7
7
  ## Features
8
8
 
9
- - Convert natural language to bash commands
10
- - Generate Ruby code from natural language instructions
11
- - Analyze Errbit errors and generate detailed reports
12
- - Create formatted Scrum tickets from errors
9
+ - **๐Ÿค– Natural Language to Commands**: Convert natural language to bash commands
10
+ - **๐Ÿ’Ž Ruby Code Generation**: Generate Ruby code from natural language instructions
11
+ - **๐Ÿ” AI-Powered Diff Analysis**: Analyze git/hg diffs with comprehensive code review
12
+ - **๐Ÿ“‹ Requirements Compliance**: Check if code changes meet specified requirements
13
+ - **๐Ÿงช Test Coverage Assessment**: Evaluate test coverage for code changes
14
+ - **๐ŸŒฟ Branch Comparison**: Compare changes against any branch (main/master/default)
15
+ - **๐Ÿ› ๏ธ VCS Support**: Full support for both Git and Mercurial repositories
16
+ - **๐Ÿ“Š Errbit Integration**: Analyze Errbit errors and generate detailed reports
17
+ - **๐ŸŽซ Scrum Tickets**: Create formatted Scrum tickets from errors
13
18
 
14
19
  ## Installation
15
20
 
@@ -135,6 +140,9 @@ n2b [options] your natural language instruction
135
140
 
136
141
  Options:
137
142
  - `-x` or `--execute`: Execute the generated commands after confirmation
143
+ - `-d` or `--diff`: Analyze git/hg diff with AI-powered code review
144
+ - `-b` or `--branch [BRANCH]`: Compare against specific branch (auto-detects main/master/default)
145
+ - `-r` or `--requirements FILE`: Requirements file for compliance checking
138
146
  - `-c` or `--config`: Reconfigure the tool
139
147
  - `-h` or `--help`: Display help information
140
148
 
@@ -152,6 +160,82 @@ Examples:
152
160
 
153
161
  ```n2b -c ```
154
162
 
163
+ ## ๐Ÿ” AI-Powered Diff Analysis
164
+
165
+ N2B provides comprehensive AI-powered code review for your git and mercurial repositories.
166
+
167
+ ### Basic Diff Analysis
168
+
169
+ ```bash
170
+ # Analyze uncommitted changes
171
+ n2b --diff
172
+
173
+ # Analyze changes against specific branch
174
+ n2b --diff --branch main
175
+ n2b --diff --branch feature/auth
176
+
177
+ # Auto-detect default branch (main/master/default)
178
+ n2b --diff --branch
179
+
180
+ # Short form
181
+ n2b -d -b main
182
+ ```
183
+
184
+ ### Requirements Compliance Checking
185
+
186
+ ```bash
187
+ # Check if changes meet requirements
188
+ n2b --diff --requirements requirements.md
189
+ n2b -d -r req.md
190
+
191
+ # Combine with branch comparison
192
+ n2b --diff --branch main --requirements requirements.md
193
+ ```
194
+
195
+ ### What You Get
196
+
197
+ The AI analysis provides:
198
+
199
+ - **๐Ÿ“ Summary**: Clear overview of what changed
200
+ - **๐Ÿšจ Potential Errors**: Bugs, security issues, logic problems with exact file/line references
201
+ - **๐Ÿ’ก Suggested Improvements**: Code quality, performance, style recommendations
202
+ - **๐Ÿงช Test Coverage Assessment**: Evaluation of test completeness and quality
203
+ - **๐Ÿ“‹ Requirements Evaluation**: Compliance check with clear status indicators:
204
+ - โœ… **IMPLEMENTED**: Requirement fully satisfied
205
+ - โš ๏ธ **PARTIALLY IMPLEMENTED**: Needs more work
206
+ - โŒ **NOT IMPLEMENTED**: Not addressed
207
+ - ๐Ÿ” **UNCLEAR**: Cannot determine from diff
208
+
209
+ ### Example Output
210
+
211
+ ```
212
+ Code Diff Analysis:
213
+ -------------------
214
+ Summary:
215
+ Added user authentication with JWT tokens and password validation.
216
+
217
+ Potential Errors:
218
+ - lib/auth.rb line 42: Password validation allows weak passwords
219
+ - controllers/auth_controller.rb lines 15-20: Missing rate limiting for login attempts
220
+
221
+ Suggested Improvements:
222
+ - lib/auth.rb line 30: Consider using bcrypt for password hashing
223
+ - spec/auth_spec.rb: Add tests for edge cases and security scenarios
224
+
225
+ Test Coverage Assessment:
226
+ Good: Basic authentication flow is tested. Missing: No tests for password validation edge cases, JWT expiration handling, or security attack scenarios.
227
+
228
+ Requirements Evaluation:
229
+ โœ… IMPLEMENTED: User login/logout functionality fully working
230
+ โš ๏ธ PARTIALLY IMPLEMENTED: Password strength requirements present but not comprehensive
231
+ โŒ NOT IMPLEMENTED: Two-factor authentication not addressed in this diff
232
+ -------------------
233
+ ```
234
+
235
+ ### Supported Version Control Systems
236
+
237
+ - **Git**: Full support with auto-detection of main/master branches
238
+ - **Mercurial (hg)**: Full support with auto-detection of default branch
155
239
 
156
240
  n2r in ruby or rails console
157
241
  n2r "your question", files:['file1.rb', 'file2.rb'], exception: AnError
@@ -240,4 +324,4 @@ The generated tickets include:
240
324
  - Acceptance criteria
241
325
  - Story point estimate
242
326
  - Priority level
243
- - Reference to the original Errbit URL
327
+ - Reference to the original Errbit URL# Test change
data/lib/n2b/cli.rb CHANGED
@@ -46,7 +46,7 @@ module N2B
46
46
  requirements_content = File.read(requirements_filepath)
47
47
  end
48
48
 
49
- diff_output = execute_vcs_diff(vcs_type)
49
+ diff_output = execute_vcs_diff(vcs_type, @options[:branch])
50
50
  analyze_diff(diff_output, config, user_prompt_addition, requirements_content)
51
51
  end
52
52
 
@@ -60,17 +60,139 @@ module N2B
60
60
  end
61
61
  end
62
62
 
63
- def execute_vcs_diff(vcs_type)
63
+ def execute_vcs_diff(vcs_type, branch_option = nil)
64
64
  case vcs_type
65
65
  when :git
66
- `git diff HEAD`
66
+ if branch_option
67
+ target_branch = branch_option == 'auto' ? detect_git_default_branch : branch_option
68
+ if target_branch
69
+ # Validate that the target branch exists
70
+ unless validate_git_branch_exists(target_branch)
71
+ puts "Error: Branch '#{target_branch}' does not exist."
72
+ puts "Available branches:"
73
+ puts `git branch -a`.lines.map(&:strip).reject(&:empty?)
74
+ exit 1
75
+ end
76
+
77
+ puts "Comparing current branch against '#{target_branch}'..."
78
+ `git diff #{target_branch}...HEAD`
79
+ else
80
+ puts "Could not detect default branch, falling back to HEAD diff..."
81
+ `git diff HEAD`
82
+ end
83
+ else
84
+ `git diff HEAD`
85
+ end
67
86
  when :hg
68
- `hg diff`
87
+ if branch_option
88
+ target_branch = branch_option == 'auto' ? detect_hg_default_branch : branch_option
89
+ if target_branch
90
+ # Validate that the target branch exists
91
+ unless validate_hg_branch_exists(target_branch)
92
+ puts "Error: Branch '#{target_branch}' does not exist."
93
+ puts "Available branches:"
94
+ puts `hg branches`.lines.map(&:strip).reject(&:empty?)
95
+ exit 1
96
+ end
97
+
98
+ puts "Comparing current branch against '#{target_branch}'..."
99
+ `hg diff -r #{target_branch}`
100
+ else
101
+ puts "Could not detect default branch, falling back to standard diff..."
102
+ `hg diff`
103
+ end
104
+ else
105
+ `hg diff`
106
+ end
69
107
  else
70
108
  "" # Should not happen if get_vcs_type logic is correct and checked before calling
71
109
  end
72
110
  end
73
111
 
112
+ def detect_git_default_branch
113
+ # Try multiple methods to detect the default branch
114
+
115
+ # Method 1: Check origin/HEAD symbolic ref
116
+ result = `git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null`.strip
117
+ if $?.success? && !result.empty?
118
+ return result.split('/').last
119
+ end
120
+
121
+ # Method 2: Check remote show origin
122
+ result = `git remote show origin 2>/dev/null | grep "HEAD branch"`.strip
123
+ if $?.success? && !result.empty?
124
+ match = result.match(/HEAD branch:\s*(\w+)/)
125
+ return match[1] if match
126
+ end
127
+
128
+ # Method 3: Check if common default branches exist
129
+ ['main', 'master'].each do |branch|
130
+ result = `git rev-parse --verify origin/#{branch} 2>/dev/null`
131
+ if $?.success?
132
+ return branch
133
+ end
134
+ end
135
+
136
+ # Method 4: Fallback - check local branches
137
+ ['main', 'master'].each do |branch|
138
+ result = `git rev-parse --verify #{branch} 2>/dev/null`
139
+ if $?.success?
140
+ return branch
141
+ end
142
+ end
143
+
144
+ # If all else fails, return nil
145
+ nil
146
+ end
147
+
148
+ def detect_hg_default_branch
149
+ # Method 1: Check current branch (if it's 'default', that's the main branch)
150
+ result = `hg branch 2>/dev/null`.strip
151
+ if $?.success? && result == 'default'
152
+ return 'default'
153
+ end
154
+
155
+ # Method 2: Look for 'default' branch in branch list
156
+ result = `hg branches 2>/dev/null`
157
+ if $?.success? && result.include?('default')
158
+ return 'default'
159
+ end
160
+
161
+ # Method 3: Check if there are any branches at all
162
+ result = `hg branches 2>/dev/null`.strip
163
+ if $?.success? && !result.empty?
164
+ # Get the first branch (usually the main one)
165
+ first_branch = result.lines.first&.split&.first
166
+ return first_branch if first_branch
167
+ end
168
+
169
+ # Fallback to 'default' (standard hg main branch name)
170
+ 'default'
171
+ end
172
+
173
+ def validate_git_branch_exists(branch)
174
+ # Check if branch exists locally
175
+ result = `git rev-parse --verify #{branch} 2>/dev/null`
176
+ return true if $?.success?
177
+
178
+ # Check if branch exists on remote
179
+ result = `git rev-parse --verify origin/#{branch} 2>/dev/null`
180
+ return true if $?.success?
181
+
182
+ false
183
+ end
184
+
185
+ def validate_hg_branch_exists(branch)
186
+ # Check if branch exists in hg branches
187
+ result = `hg branches 2>/dev/null`
188
+ if $?.success?
189
+ return result.lines.any? { |line| line.strip.start_with?(branch) }
190
+ end
191
+
192
+ # If we can't list branches, assume it exists (hg is more permissive)
193
+ true
194
+ end
195
+
74
196
  private
75
197
 
76
198
  def process_natural_language_command(input_text, config)
@@ -387,8 +509,13 @@ JSON_INSTRUCTION
387
509
  # This internal JSON parsing is for the *content* of a successful LLM response.
388
510
  # The LlmApiError for network/auth issues should be caught before this.
389
511
  begin
390
- parsed_response = JSON.parse(response_json_str)
391
- parsed_response
512
+ # Check if response_json_str is already a Hash (parsed JSON)
513
+ if response_json_str.is_a?(Hash)
514
+ response_json_str
515
+ else
516
+ parsed_response = JSON.parse(response_json_str)
517
+ parsed_response
518
+ end
392
519
  rescue JSON::ParserError => e
393
520
  puts "Error parsing LLM response JSON for command generation: #{e.message}"
394
521
  # This is a fallback for when the LLM response *content* is not valid JSON.
@@ -490,7 +617,7 @@ JSON_INSTRUCTION
490
617
 
491
618
 
492
619
  def parse_options
493
- options = { execute: false, config: nil, diff: false, requirements: nil }
620
+ options = { execute: false, config: nil, diff: false, requirements: nil, branch: nil }
494
621
 
495
622
  parser = OptionParser.new do |opts|
496
623
  opts.banner = "Usage: n2b [options] [natural language command]"
@@ -503,6 +630,10 @@ JSON_INSTRUCTION
503
630
  options[:diff] = true
504
631
  end
505
632
 
633
+ opts.on('-b', '--branch [BRANCH]', 'Compare against branch (default: auto-detect main/master)') do |branch|
634
+ options[:branch] = branch || 'auto'
635
+ end
636
+
506
637
  opts.on('-r', '--requirements FILE', 'Requirements file for diff analysis') do |file|
507
638
  options[:requirements] = file
508
639
  end
@@ -526,6 +657,14 @@ JSON_INSTRUCTION
526
657
  exit 1
527
658
  end
528
659
 
660
+ # Validate option combinations
661
+ if options[:branch] && !options[:diff]
662
+ puts "Error: --branch option can only be used with --diff"
663
+ puts ""
664
+ puts parser.help
665
+ exit 1
666
+ end
667
+
529
668
  options
530
669
  end
531
670
  end
data/lib/n2b/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  # lib/n2b/version.rb
2
2
  module N2B
3
- VERSION = "0.3.0"
3
+ VERSION = "0.3.1"
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: n2b
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Nothegger