nitpicker-code-review 1.0.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b493182d8ba98bc4e102c13f0a379eaf545f920f9cb4f72ce4b4a0db4d164d51
4
- data.tar.gz: 285e6dd3c76d4a2a7d4df310d3618f058fd6e39335dd5d965b1155205376a399
3
+ metadata.gz: 31c3b5ac8a702f1fe70c8a091aa91fd1d1c08c747e1153e02d9d2544ada2ac39
4
+ data.tar.gz: dbcf2976eeb26bfb26e0cc1038b0d9227ba9ca16bb058ac9e15095cbbbe47a5b
5
5
  SHA512:
6
- metadata.gz: eb1d96af03c6add163aca48519af15bbccc4ebc685d9d212b3cf52f925b345ff1bbd908c807f686e2e240e5d7075ee12f9e78dbf5ea45abb69d1da9b8ca91ad3
7
- data.tar.gz: 54a486f87f322170dd2c0edfb41a225f5723f1507e8280f45d74dfd5a16026ed5a1a529a36eac3d08255c953ee2f076b760fc433e75d2272cc9c0a3c68d68fc8
6
+ metadata.gz: '0059ec81a853e134d0f3e2639e0512ec765991faaba0a87573259bac561ed837a16cbc377031fdea61e71877f19b0baf4c0e8732e2d564df395ce2b36db57a51'
7
+ data.tar.gz: bfb36e09ea2700822f7b6222286d51e4adcbd10c5870df6e87ff334cc91db64257759568065e8c31976d697442036274829a146dad9448f8f9046ecd491f6c6e
data/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Your Name
3
+ Copyright (c) 2025 Justin Bishop
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
1
  # NitPicker
2
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.
3
+ NitPicker is a command-line tool that provides AI-powered code reviews for your Git changes. It analyzes your staged changes by default, but can also review any diff piped to it. It offers constructive feedback to help improve code quality, security, performance, and maintainability.
4
4
 
5
5
  ## Features
6
6
 
7
- - AI-powered code review of staged Git changes
7
+ - AI-powered code review of staged Git changes or any piped diff
8
8
  - Comprehensive analysis covering code quality, security, performance, and best practices
9
9
  - Customizable AI prompts for tailored review feedback
10
10
  - Support for repository-specific prompts
11
- - Choose any AI model (Google Gemini 2.5 Flash by default)
11
+ - Choose any AI model (OpenAI GPT-4.1-mini by default)
12
12
  - Easy integration into your Git workflow
13
13
 
14
14
  ## Installation
@@ -81,7 +81,7 @@ Optionally, you can specify a different model by setting:
81
81
  export GIT_REVIEW_MODEL="openai/gpt-4o"
82
82
  ```
83
83
 
84
- The default model is `google/gemini-2.5-flash-preview-05-20` if not specified.
84
+ The default model is `openai/gpt-4.1-mini` if not specified.
85
85
 
86
86
  ### Prompt Configuration
87
87
 
@@ -100,18 +100,31 @@ The special string `{{DIFF}}` in your prompt will be replaced with the current g
100
100
 
101
101
  ## Usage
102
102
 
103
+ ### Review Staged Changes (Default)
104
+
103
105
  Navigate to your Git repository, stage your changes, and run:
104
106
 
105
107
  ```bash
106
108
  nitpicker [options]
107
109
  ```
108
110
 
111
+ ### Review Any Diff via Pipe
112
+
113
+ You can pipe any diff into nitpicker for review:
114
+
115
+ ```bash
116
+ git show | nitpicker # Review a specific commit
117
+ git diff HEAD~1 | nitpicker # Review changes from previous commit
118
+ git diff main..feature | nitpicker # Review differences between branches
119
+ ```
120
+
109
121
  Options:
110
122
  - `--version`: Show version information
111
123
  - `-h, --help`: Show help message
112
124
 
113
125
  ## Examples
114
126
 
127
+ ### Review Staged Changes
115
128
  ```bash
116
129
  # Stage some changes first
117
130
  git add .
@@ -120,6 +133,24 @@ git add .
120
133
  nitpicker
121
134
  ```
122
135
 
136
+ ### Review Specific Commits or Diffs
137
+ ```bash
138
+ # Review the last commit
139
+ git show | nitpicker
140
+
141
+ # Review changes from 2 commits ago
142
+ git show HEAD~2 | nitpicker
143
+
144
+ # Review uncommitted changes (both staged and unstaged)
145
+ git diff HEAD | nitpicker
146
+
147
+ # Review differences between branches
148
+ git diff main..feature-branch | nitpicker
149
+
150
+ # Review a range of commits
151
+ git diff HEAD~3..HEAD | nitpicker
152
+ ```
153
+
123
154
  Example output:
124
155
  ```
125
156
  ## Code Review Summary
data/config/prompt CHANGED
@@ -1,4 +1,8 @@
1
- You are an expert software engineer conducting a thorough code review. Analyze the following git diff and provide constructive feedback focusing on:
1
+ You are an expert software engineer conducting a thorough code review.
2
+
3
+ IMPORTANT: Do NOT reproduce, echo, or reformat the code. Your job is to ANALYZE and provide FEEDBACK only.
4
+
5
+ Analyze the following git diff and provide constructive feedback focusing on:
2
6
 
3
7
  **Code Quality & Best Practices:**
4
8
  - Code readability, maintainability, and organization
@@ -35,5 +39,7 @@ Provide your feedback in a clear, constructive manner. For each issue identified
35
39
 
36
40
  If the code looks good overall, highlight what was done well and provide any minor suggestions for improvement.
37
41
 
42
+ Start your response with "## Code Review" and provide analysis in prose, NOT code blocks or diffs.
43
+
38
44
  DIFF:
39
45
  {{DIFF}}
@@ -1,3 +1,3 @@
1
1
  module NitPicker
2
- VERSION = '1.0.0'
3
- end
2
+ VERSION = '1.1'
3
+ end
data/lib/nitpicker.rb CHANGED
@@ -20,7 +20,10 @@ module NitPicker
20
20
  require 'optparse'
21
21
 
22
22
  OptionParser.new do |opts|
23
- opts.banner = 'Usage: nitpicker [options]'
23
+ opts.banner = 'Usage: nitpicker [options]
24
+ git show | nitpicker # Review a specific commit
25
+ git diff HEAD~1 | nitpicker # Review changes from previous commit
26
+ nitpicker # Review staged changes (default)'
24
27
  opts.version = VERSION
25
28
 
26
29
  opts.on('-h', '--help', 'Show this help message') do
@@ -33,12 +36,25 @@ module NitPicker
33
36
  def run
34
37
  parse_options
35
38
 
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
39
+ # Check if we have piped input
40
+ if STDIN.tty?
41
+ # Interactive terminal - use git diff of staged changes
42
+ diff = `git diff --staged`
43
+ if diff.empty?
44
+ puts "No changes staged for review."
45
+ exit 1
46
+ end
47
+ else
48
+ # STDIN is redirected - try to read from it
49
+ diff = STDIN.read
50
+ if diff.empty?
51
+ # Empty piped input, fall back to git diff
52
+ diff = `git diff --staged`
53
+ if diff.empty?
54
+ puts "No changes staged for review."
55
+ exit 1
56
+ end
57
+ end
42
58
  end
43
59
 
44
60
  # Get AI-generated code review
@@ -85,13 +101,24 @@ module NitPicker
85
101
  def generate_code_review(diff)
86
102
  api_key = ENV['OPENROUTER_API_KEY']
87
103
  if api_key.nil? || api_key.empty?
88
- puts "Error: OPENROUTER_API_KEY environment variable not set"
89
- exit 1
104
+ puts "Error: OPENROUTER_API_KEY environment variable not set"
105
+ puts ""
106
+ puts "To get AI code reviews, you need an OpenRouter API key:"
107
+ puts "1. Sign up at https://openrouter.ai/"
108
+ puts "2. Get your API key from the dashboard"
109
+ puts "3. Set it as an environment variable:"
110
+ puts " export OPENROUTER_API_KEY=\"sk-or-v1-your-key-here\""
111
+ puts ""
112
+ puts "For now, showing the raw diff instead:"
113
+ puts "=" * 50
114
+ return diff
90
115
  end
91
116
 
92
- model = ENV['GIT_REVIEW_MODEL'] || 'google/gemini-2.5-flash-preview-05-20'
117
+ model = ENV['GIT_REVIEW_MODEL'] || 'openai/gpt-4.1-mini'
118
+ puts "Using model: #{model}" if ENV['DEBUG']
93
119
 
94
120
  prompt = get_prompt.gsub('{{DIFF}}', diff)
121
+ puts "Prompt length: #{prompt.length} characters" if ENV['DEBUG']
95
122
 
96
123
  uri = URI.parse('https://openrouter.ai/api/v1/chat/completions')
97
124
  http = Net::HTTP.new(uri.host, uri.port)
@@ -102,28 +129,80 @@ module NitPicker
102
129
  request['Authorization'] = "Bearer #{api_key}"
103
130
  request['HTTP-Referer'] = 'https://github.com/nitpicker-code-review'
104
131
 
105
- request.body = {
132
+ request_payload = {
106
133
  model: model,
107
134
  messages: [
108
135
  { role: 'user', content: prompt }
109
136
  ],
110
137
  max_tokens: 2000
111
- }.to_json
138
+ }
139
+
140
+ request.body = request_payload.to_json
141
+ puts "Making API request to OpenRouter..." if ENV['DEBUG']
112
142
 
113
143
  begin
114
144
  response = http.request(request)
145
+ puts "API Response code: #{response.code}" if ENV['DEBUG']
115
146
 
116
147
  if response.code == '200'
117
148
  result = JSON.parse(response.body)
118
- review = result['choices'][0]['message']['content'].strip
119
- return review
149
+ puts "API Response parsed successfully" if ENV['DEBUG']
150
+
151
+ if result['choices'] && result['choices'][0] && result['choices'][0]['message']
152
+ review = result['choices'][0]['message']['content'].strip
153
+ puts "Review length: #{review.length} characters" if ENV['DEBUG']
154
+ puts "Review content preview: #{review[0..200]}..." if ENV['DEBUG']
155
+ return review
156
+ else
157
+ puts "❌ Error: Unexpected API response structure"
158
+ puts "Response: #{response.body}" if ENV['DEBUG']
159
+ puts ""
160
+ puts "Showing raw diff instead:"
161
+ puts "=" * 50
162
+ return diff
163
+ end
120
164
  else
121
- puts "API Error (#{response.code}): #{response.body}"
122
- exit 1
165
+ error_body = JSON.parse(response.body) rescue response.body
166
+ error_message = error_body.is_a?(Hash) && error_body['error'] ? error_body['error']['message'] || error_body['error'] : response.body
167
+
168
+ puts "❌ API Error (#{response.code}): #{error_message}"
169
+
170
+ if response.code == '401'
171
+ puts ""
172
+ puts "This usually means:"
173
+ puts "• Your API key is invalid or expired"
174
+ puts "• You haven't set the OPENROUTER_API_KEY environment variable"
175
+ puts "• Your API key doesn't have sufficient credits"
176
+ puts ""
177
+ puts "Please check your API key at https://openrouter.ai/"
178
+ elsif response.code == '429'
179
+ puts ""
180
+ puts "You've hit the rate limit. Please wait a moment and try again."
181
+ end
182
+
183
+ puts ""
184
+ puts "Showing raw diff instead:"
185
+ puts "=" * 50
186
+ return diff
123
187
  end
188
+ rescue JSON::ParserError => e
189
+ puts "❌ Error parsing API response: #{e.message}"
190
+ puts "Raw response: #{response.body}" if ENV['DEBUG']
191
+ puts ""
192
+ puts "Showing raw diff instead:"
193
+ puts "=" * 50
194
+ return diff
124
195
  rescue => e
125
- puts "Error: #{e.message}"
126
- exit 1
196
+ puts "Error making API request: #{e.message}"
197
+ puts ""
198
+ puts "This could be due to:"
199
+ puts "• Network connectivity issues"
200
+ puts "• OpenRouter API service being temporarily unavailable"
201
+ puts "• Invalid API configuration"
202
+ puts ""
203
+ puts "Showing raw diff instead:"
204
+ puts "=" * 50
205
+ return diff
127
206
  end
128
207
  end
129
208
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nitpicker-code-review
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: '1.1'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bishop