nitpicker-code-review 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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: b493182d8ba98bc4e102c13f0a379eaf545f920f9cb4f72ce4b4a0db4d164d51
4
+ data.tar.gz: 285e6dd3c76d4a2a7d4df310d3618f058fd6e39335dd5d965b1155205376a399
5
+ SHA512:
6
+ metadata.gz: eb1d96af03c6add163aca48519af15bbccc4ebc685d9d212b3cf52f925b345ff1bbd908c807f686e2e240e5d7075ee12f9e78dbf5ea45abb69d1da9b8ca91ad3
7
+ data.tar.gz: 54a486f87f322170dd2c0edfb41a225f5723f1507e8280f45d74dfd5a16026ed5a1a529a36eac3d08255c953ee2f076b760fc433e75d2272cc9c0a3c68d68fc8
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Your Name
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,201 @@
1
+ # NitPicker
2
+
3
+ NitPicker is a command-line tool that provides AI-powered code reviews for your Git changes. It analyzes your staged changes and offers constructive feedback to help improve code quality, security, performance, and maintainability.
4
+
5
+ ## Features
6
+
7
+ - AI-powered code review of staged Git changes
8
+ - Comprehensive analysis covering code quality, security, performance, and best practices
9
+ - Customizable AI prompts for tailored review feedback
10
+ - Support for repository-specific prompts
11
+ - Choose any AI model (Google Gemini 2.5 Flash by default)
12
+ - Easy integration into your Git workflow
13
+
14
+ ## Installation
15
+
16
+ ### Requirements
17
+
18
+ - Ruby 2.6 or higher
19
+ - Git
20
+
21
+ ### Option 1: Install as a Gem (Recommended)
22
+
23
+ ```bash
24
+ gem install nitpicker-code-review
25
+ ```
26
+
27
+ This automatically adds NitPicker to your PATH.
28
+
29
+ ### Option 2: Build and Install from Source
30
+
31
+ Clone this repository:
32
+
33
+ ```bash
34
+ git clone https://github.com/jubishop/NitPicker.git
35
+ cd NitPicker
36
+ ```
37
+
38
+ Build and install the gem:
39
+
40
+ ```bash
41
+ gem build gemspec/nitpicker.gemspec
42
+ gem install nitpicker-code-review-*.gem
43
+ ```
44
+
45
+ ### Option 3: Manual Installation
46
+
47
+ Clone this repository:
48
+
49
+ ```bash
50
+ git clone https://github.com/jubishop/NitPicker.git
51
+ cd NitPicker
52
+ ```
53
+
54
+ Make the script executable:
55
+
56
+ ```bash
57
+ chmod +x bin/nitpicker
58
+ ```
59
+
60
+ Create a symbolic link to make NitPicker available globally:
61
+
62
+ ```bash
63
+ ln -s "$(pwd)/bin/nitpicker" /usr/local/bin/nitpicker
64
+ ```
65
+
66
+ ## Configuration
67
+
68
+ ### API Key Setup
69
+
70
+ NitPicker requires an OpenRouter API key to generate code reviews. You need to set this as an environment variable:
71
+
72
+ ```bash
73
+ export OPENROUTER_API_KEY="your_openrouter_api_key"
74
+ ```
75
+
76
+ You can get an API key from [OpenRouter](https://openrouter.ai/).
77
+
78
+ Optionally, you can specify a different model by setting:
79
+
80
+ ```bash
81
+ export GIT_REVIEW_MODEL="openai/gpt-4o"
82
+ ```
83
+
84
+ The default model is `google/gemini-2.5-flash-preview-05-20` if not specified.
85
+
86
+ ### Prompt Configuration
87
+
88
+ NitPicker supports two levels of prompt configuration:
89
+
90
+ - **Global Prompt (Default)**: Stored in `~/.config/nitpicker/prompt`. This is used for all repositories unless overridden.
91
+ - **Repository-Specific Prompt**: Create a `.nitpicker_prompt` file in the root of your Git repository to customize the prompt for that specific project.
92
+
93
+ When you run NitPicker, it will:
94
+ - First look for a `.nitpicker_prompt` file in the root of the current Git repository
95
+ - If not found, fall back to the global prompt at `~/.config/nitpicker/prompt`
96
+
97
+ When you run NitPicker for the first time, if there's no global prompt file in the config directory, it will copy `config/prompt` to the config directory automatically.
98
+
99
+ The special string `{{DIFF}}` in your prompt will be replaced with the current git diff of staged changes.
100
+
101
+ ## Usage
102
+
103
+ Navigate to your Git repository, stage your changes, and run:
104
+
105
+ ```bash
106
+ nitpicker [options]
107
+ ```
108
+
109
+ Options:
110
+ - `--version`: Show version information
111
+ - `-h, --help`: Show help message
112
+
113
+ ## Examples
114
+
115
+ ```bash
116
+ # Stage some changes first
117
+ git add .
118
+
119
+ # Get AI code review of staged changes
120
+ nitpicker
121
+ ```
122
+
123
+ Example output:
124
+ ```
125
+ ## Code Review Summary
126
+
127
+ **Overall Assessment:** The changes look good with a few minor suggestions for improvement.
128
+
129
+ ### Positive Aspects:
130
+ - Clean, readable code structure
131
+ - Proper error handling implemented
132
+ - Good variable naming conventions
133
+
134
+ ### Suggestions for Improvement:
135
+
136
+ **Security:**
137
+ - Consider validating user input on line 45 to prevent potential injection attacks
138
+
139
+ **Performance:**
140
+ - The database query on line 23 could be optimized by adding an index on the `user_id` column
141
+
142
+ **Best Practices:**
143
+ - Consider extracting the validation logic into a separate method for better reusability
144
+ ```
145
+
146
+ ## License
147
+
148
+ MIT
149
+
150
+ ## Development
151
+
152
+ ### Project Structure
153
+
154
+ NitPicker follows a specific project structure where all gemspec files and built gem files (.gem) are placed in the `gemspec/` folder rather than the root directory. This keeps the root directory clean and organized.
155
+
156
+ ### Rake Tasks
157
+
158
+ NitPicker provides several rake tasks to streamline development:
159
+
160
+ ```bash
161
+ # Run the test suite
162
+ rake test
163
+
164
+ # Build the gem and place it in the gemspec/ folder
165
+ rake build
166
+
167
+ # Build, install and test the gem
168
+ rake install
169
+
170
+ # Build and push the gem to RubyGems
171
+ rake push
172
+ ```
173
+
174
+ The default task is `rake test`.
175
+
176
+ ### Testing
177
+
178
+ NitPicker uses Minitest for testing. To run the tests:
179
+
180
+ ```bash
181
+ bundle install
182
+ rake test
183
+ ```
184
+
185
+ The test suite includes:
186
+ - Unit tests for the CLI functionality
187
+ - Tests for version consistency
188
+ - Mock tests for API interactions (using WebMock)
189
+
190
+ ## Contributing
191
+
192
+ 1. Fork the repository
193
+ 2. Create a feature branch
194
+ 3. Make your changes
195
+ 4. Add tests for new functionality
196
+ 5. Ensure all tests pass
197
+ 6. Submit a pull request
198
+
199
+ ## Author
200
+
201
+ Justin Bishop (jubishop)
data/bin/nitpicker ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # This file is part of the standard gem pattern for executables.
5
+ # When installed as a gem, RubyGems will create a wrapper script
6
+ # that sets up the correct load path and then requires this file.
7
+
8
+ # Add lib to the load path when running from source
9
+ lib_dir = File.expand_path('../lib', __dir__)
10
+ $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
11
+
12
+ require 'nitpicker'
13
+
14
+ # Execute the CLI
15
+ NitPicker::CLI.new.run
data/config/prompt ADDED
@@ -0,0 +1,39 @@
1
+ You are an expert software engineer conducting a thorough code review. Analyze the following git diff and provide constructive feedback focusing on:
2
+
3
+ **Code Quality & Best Practices:**
4
+ - Code readability, maintainability, and organization
5
+ - Adherence to language-specific conventions and idioms
6
+ - Proper error handling and edge cases
7
+ - Code duplication and refactoring opportunities
8
+
9
+ **Security & Performance:**
10
+ - Potential security vulnerabilities
11
+ - Performance implications and optimization opportunities
12
+ - Resource management and memory usage
13
+ - Database query efficiency (if applicable)
14
+
15
+ **Testing & Documentation:**
16
+ - Test coverage for new functionality
17
+ - Missing or inadequate documentation
18
+ - API documentation and code comments
19
+
20
+ **Architecture & Design:**
21
+ - Design patterns and architectural consistency
22
+ - Separation of concerns and modularity
23
+ - Potential breaking changes or backwards compatibility
24
+
25
+ **Specific Issues:**
26
+ - Logic errors or bugs
27
+ - Incorrect variable names or typos
28
+ - Missing validation or sanitization
29
+ - Hardcoded values that should be configurable
30
+
31
+ Provide your feedback in a clear, constructive manner. For each issue identified:
32
+ 1. Explain the problem clearly
33
+ 2. Suggest specific improvements
34
+ 3. Explain why the change would be beneficial
35
+
36
+ If the code looks good overall, highlight what was done well and provide any minor suggestions for improvement.
37
+
38
+ DIFF:
39
+ {{DIFF}}
@@ -0,0 +1,3 @@
1
+ module NitPicker
2
+ VERSION = '1.0.0'
3
+ end
data/lib/nitpicker.rb ADDED
@@ -0,0 +1,130 @@
1
+ require 'nitpicker/version'
2
+ require 'net/http'
3
+ require 'uri'
4
+ require 'json'
5
+ require 'fileutils'
6
+ require 'tmpdir'
7
+
8
+ module NitPicker
9
+ class CLI
10
+ CONFIG_DIR = File.expand_path('~/.config/nitpicker')
11
+ PROMPT_FILE = File.join(CONFIG_DIR, 'prompt')
12
+ REPO_PROMPT_FILE = '.nitpicker_prompt'
13
+
14
+ def initialize
15
+ @options = {}
16
+ setup_config_dir
17
+ end
18
+
19
+ def parse_options
20
+ require 'optparse'
21
+
22
+ OptionParser.new do |opts|
23
+ opts.banner = 'Usage: nitpicker [options]'
24
+ opts.version = VERSION
25
+
26
+ opts.on('-h', '--help', 'Show this help message') do
27
+ puts opts
28
+ exit
29
+ end
30
+ end.parse!
31
+ end
32
+
33
+ def run
34
+ parse_options
35
+
36
+ # Get git diff of staged changes
37
+ diff = `git diff --staged`
38
+
39
+ if diff.empty?
40
+ puts "No changes staged for review."
41
+ exit 1
42
+ end
43
+
44
+ # Get AI-generated code review
45
+ review = generate_code_review(diff)
46
+
47
+ # Display the review
48
+ puts review
49
+ end
50
+
51
+ private
52
+
53
+ def setup_config_dir
54
+ unless Dir.exist?(CONFIG_DIR)
55
+ FileUtils.mkdir_p(CONFIG_DIR)
56
+ end
57
+
58
+ unless File.exist?(PROMPT_FILE)
59
+ # Check for bundled prompt file in the config directory
60
+ config_prompt = File.join(File.dirname(__FILE__), '..', 'config', 'prompt')
61
+
62
+ if File.exist?(config_prompt)
63
+ puts "Copying bundled prompt file to #{PROMPT_FILE}"
64
+ FileUtils.cp(config_prompt, PROMPT_FILE)
65
+ puts "Prompt file installed successfully."
66
+ else
67
+ puts "Error: Prompt file not found at #{PROMPT_FILE}"
68
+ puts "No bundled prompt file found at: #{config_prompt}"
69
+ puts "Please create a prompt file with your custom prompt."
70
+ exit 1 unless defined?(TESTING_MODE) && TESTING_MODE
71
+ end
72
+ end
73
+ end
74
+
75
+ def get_prompt
76
+ # First check for repository-specific prompt
77
+ if File.exist?(REPO_PROMPT_FILE)
78
+ return File.read(REPO_PROMPT_FILE)
79
+ end
80
+
81
+ # Fall back to global prompt
82
+ File.read(PROMPT_FILE)
83
+ end
84
+
85
+ def generate_code_review(diff)
86
+ api_key = ENV['OPENROUTER_API_KEY']
87
+ if api_key.nil? || api_key.empty?
88
+ puts "Error: OPENROUTER_API_KEY environment variable not set"
89
+ exit 1
90
+ end
91
+
92
+ model = ENV['GIT_REVIEW_MODEL'] || 'google/gemini-2.5-flash-preview-05-20'
93
+
94
+ prompt = get_prompt.gsub('{{DIFF}}', diff)
95
+
96
+ uri = URI.parse('https://openrouter.ai/api/v1/chat/completions')
97
+ http = Net::HTTP.new(uri.host, uri.port)
98
+ http.use_ssl = true
99
+
100
+ request = Net::HTTP::Post.new(uri.request_uri)
101
+ request['Content-Type'] = 'application/json'
102
+ request['Authorization'] = "Bearer #{api_key}"
103
+ request['HTTP-Referer'] = 'https://github.com/nitpicker-code-review'
104
+
105
+ request.body = {
106
+ model: model,
107
+ messages: [
108
+ { role: 'user', content: prompt }
109
+ ],
110
+ max_tokens: 2000
111
+ }.to_json
112
+
113
+ begin
114
+ response = http.request(request)
115
+
116
+ if response.code == '200'
117
+ result = JSON.parse(response.body)
118
+ review = result['choices'][0]['message']['content'].strip
119
+ return review
120
+ else
121
+ puts "API Error (#{response.code}): #{response.body}"
122
+ exit 1
123
+ end
124
+ rescue => e
125
+ puts "Error: #{e.message}"
126
+ exit 1
127
+ end
128
+ end
129
+ end
130
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: nitpicker-code-review
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-28 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
+ - !ruby/object:Gem::Dependency
27
+ name: rake
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '13.0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '13.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: minitest
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '5.0'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '5.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: webmock
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.0'
61
+ type: :development
62
+ prerelease: false
63
+ version_requirements: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '3.0'
68
+ description: NitPicker is a command-line tool that uses AI to review your staged Git
69
+ changes and provide constructive feedback
70
+ email:
71
+ - jubishop@gmail.com
72
+ executables:
73
+ - nitpicker
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - LICENSE
78
+ - README.md
79
+ - bin/nitpicker
80
+ - config/prompt
81
+ - lib/nitpicker.rb
82
+ - lib/nitpicker/version.rb
83
+ homepage: https://github.com/jubishop/NitPicker
84
+ licenses:
85
+ - MIT
86
+ metadata: {}
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: 2.6.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.6.6
102
+ specification_version: 4
103
+ summary: AI-powered Git code review tool
104
+ test_files: []