ira-review 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mayur Patil
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.
package/README.md ADDED
@@ -0,0 +1,317 @@
1
+ # ira-review
2
+
3
+ **AI-powered PR reviews with built-in JIRA intelligence.**
4
+
5
+ Your PRs get flagged by SonarQube. Then someone has to go read each issue, figure out what it means, and decide how to fix it. That takes time.
6
+
7
+ **ira-review** does that for you. It pulls your SonarQube issues, runs them through AI, and posts clear, actionable comments right on your pull request. Explanation, impact, suggested fix. Done.
8
+
9
+ It also scores the overall risk of your PR, highlights complex code, and can validate JIRA acceptance criteria automatically.
10
+
11
+ ## What it does
12
+
13
+ 1. Fetches issues from SonarQube/SonarCloud for a specific PR
14
+ 2. Filters down to what matters (BLOCKER and CRITICAL only)
15
+ 3. Detects your framework (React, Angular, Vue, NestJS, Node) for smarter suggestions
16
+ 4. Sends each issue to AI for a human-readable explanation and fix
17
+ 5. Calculates a PR risk score based on issues, security concerns, and complexity
18
+ 6. Analyzes code complexity and flags hotspots
19
+ 7. Validates JIRA acceptance criteria against the PR (optional)
20
+ 8. Posts inline comments back to your PR on Bitbucket
21
+
22
+ ## Install
23
+
24
+ ```bash
25
+ npm install ira-review
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ The fastest way to try it out. This runs against real Sonar data but prints results to your terminal instead of posting to Bitbucket. No Bitbucket token needed.
31
+
32
+ ```bash
33
+ export OPENAI_API_KEY=sk-xxxxx
34
+
35
+ npx ira-review review \
36
+ --sonar-url https://sonarcloud.io \
37
+ --sonar-token sqa_xxxxx \
38
+ --project-key my-org_my-project \
39
+ --pr 42 \
40
+ --dry-run
41
+ ```
42
+
43
+ When you're ready to post comments to a real PR:
44
+
45
+ ```bash
46
+ npx ira-review review \
47
+ --sonar-url https://sonarcloud.io \
48
+ --sonar-token sqa_xxxxx \
49
+ --project-key my-org_my-project \
50
+ --pr 42 \
51
+ --bitbucket-token bb_xxxxx \
52
+ --repo my-workspace/my-repo
53
+ ```
54
+
55
+ ## PR Risk Scoring
56
+
57
+ Every review automatically calculates a risk score based on five factors:
58
+
59
+ | Factor | Max Points | What it measures |
60
+ |---|---|---|
61
+ | Blocker Issues | 30 | Number of blocker-level issues |
62
+ | Critical Issues | 20 | Number of critical-level issues |
63
+ | Issue Density | 15 | Issues per file changed |
64
+ | Security Concerns | 20 | Vulnerabilities, CWE/OWASP-tagged issues |
65
+ | Code Complexity | 15 | Files with cyclomatic/cognitive complexity > 15 |
66
+
67
+ Risk levels: **LOW** (0-19), **MEDIUM** (20-39), **HIGH** (40-59), **CRITICAL** (60+)
68
+
69
+ In dry-run mode you'll see output like:
70
+
71
+ ```
72
+ ═══════════════════════════════════════════════════
73
+ 🟠 PR Risk Score: HIGH (45/100)
74
+ ═══════════════════════════════════════════════════
75
+ ▓ Blocker Issues: 20/30 - 2 blocker issues found
76
+ ▓ Security Concerns: 10/20 - 1 security-related issue
77
+ ▓ Code Complexity: 10/15 - 2 high-complexity files
78
+ ▓ Critical Issues: 5/20 - 1 critical issue found
79
+ ░ Issue Density: 0/15 - 0.5 issues per file changed
80
+ ```
81
+
82
+ ## Code Complexity Insights
83
+
84
+ ira-review fetches complexity metrics from SonarQube's measures API and flags hotspots:
85
+
86
+ - **Cyclomatic complexity** (how many paths through the code)
87
+ - **Cognitive complexity** (how hard it is to understand)
88
+ - **Lines of code** per file
89
+
90
+ Files with complexity > 15 are flagged as hotspots. This feeds into the risk score and shows up in dry-run output.
91
+
92
+ ## JIRA Acceptance Criteria Validation
93
+
94
+ Connect your JIRA to validate whether a PR meets its ticket's acceptance criteria. This is optional and only runs when you provide JIRA config.
95
+
96
+ ```bash
97
+ npx ira-review review \
98
+ --sonar-url https://sonarcloud.io \
99
+ --sonar-token sqa_xxxxx \
100
+ --project-key my-org_my-project \
101
+ --pr 42 \
102
+ --jira-url https://yourcompany.atlassian.net \
103
+ --jira-email dev@company.com \
104
+ --jira-token jira_xxxxx \
105
+ --jira-ticket PROJ-123 \
106
+ --dry-run
107
+ ```
108
+
109
+ It fetches the JIRA ticket, extracts the acceptance criteria, and uses AI to check each criterion against the SonarQube analysis. Output looks like:
110
+
111
+ ```
112
+ ✅ JIRA Acceptance: PROJ-123 - Add user authentication
113
+ ✅ CRITERION_1: MET - Authentication endpoint implemented
114
+ No blocker issues in auth module
115
+ ❌ CRITERION_2: NOT_MET - Input validation
116
+ Critical security issue found in login handler
117
+ ```
118
+
119
+ If your team uses a custom field for acceptance criteria, pass the field ID:
120
+
121
+ ```bash
122
+ --jira-ac-field customfield_10042
123
+ ```
124
+
125
+ Default field is `customfield_10035`.
126
+
127
+ ## Use it in code
128
+
129
+ ```typescript
130
+ import { ReviewEngine } from "ira-review";
131
+
132
+ const engine = new ReviewEngine({
133
+ sonar: {
134
+ baseUrl: "https://sonarcloud.io",
135
+ token: "sqa_xxxxx",
136
+ projectKey: "my-org_my-project",
137
+ },
138
+ scm: {
139
+ token: "bb_xxxxx",
140
+ workspace: "my-workspace",
141
+ repoSlug: "my-repo",
142
+ },
143
+ ai: {
144
+ provider: "openai",
145
+ apiKey: process.env.OPENAI_API_KEY!,
146
+ },
147
+ pullRequestId: "42",
148
+ // Optional: JIRA integration
149
+ jira: {
150
+ baseUrl: "https://yourcompany.atlassian.net",
151
+ email: "dev@company.com",
152
+ token: "jira_xxxxx",
153
+ },
154
+ jiraTicket: "PROJ-123",
155
+ });
156
+
157
+ const result = await engine.run();
158
+
159
+ console.log(`Risk: ${result.risk?.level}`);
160
+ console.log(`Complexity hotspots: ${result.complexity?.hotspots.length}`);
161
+ console.log(`AC validation: ${result.acceptanceValidation?.overallPass}`);
162
+ ```
163
+
164
+ Want to preview without posting? Add `dryRun: true` to the config.
165
+
166
+ ## Environment variables
167
+
168
+ Tired of passing flags every time? Set these instead. CLI flags still override them if you pass both.
169
+
170
+ | Variable | What it does |
171
+ |---|---|
172
+ | `OPENAI_API_KEY` | Your OpenAI API key (required) |
173
+ | `IRA_SONAR_URL` | SonarQube/SonarCloud URL |
174
+ | `IRA_SONAR_TOKEN` | Sonar API token |
175
+ | `IRA_PROJECT_KEY` | Sonar project key |
176
+ | `IRA_PR` | Pull request ID |
177
+ | `IRA_BITBUCKET_TOKEN` | Bitbucket API token |
178
+ | `IRA_BITBUCKET_URL` | Bitbucket Server URL (only for self-hosted) |
179
+ | `IRA_REPO` | `workspace/repo-slug` format |
180
+ | `IRA_JIRA_URL` | JIRA base URL (optional) |
181
+ | `IRA_JIRA_EMAIL` | JIRA account email (optional) |
182
+ | `IRA_JIRA_TOKEN` | JIRA API token (optional) |
183
+
184
+ Copy `.env.example` to `.env` and fill it in.
185
+
186
+ ## CI/CD example
187
+
188
+ Here's how you'd wire it into a Bitbucket Pipeline:
189
+
190
+ ```yaml
191
+ pipelines:
192
+ pull-requests:
193
+ '**':
194
+ - step:
195
+ name: AI Code Review
196
+ script:
197
+ - npx ira-review review --pr $BITBUCKET_PR_ID --repo $BITBUCKET_REPO_FULL_NAME
198
+ environment:
199
+ OPENAI_API_KEY: $OPENAI_API_KEY
200
+ IRA_SONAR_URL: $SONAR_URL
201
+ IRA_SONAR_TOKEN: $SONAR_TOKEN
202
+ IRA_PROJECT_KEY: $SONAR_PROJECT_KEY
203
+ IRA_BITBUCKET_TOKEN: $BB_TOKEN
204
+ ```
205
+
206
+ All tokens come from your pipeline's secret variables. The package never sees or stores them.
207
+
208
+ ## What comments look like
209
+
210
+ When ira-review posts to your PR, each comment looks like this:
211
+
212
+ ```
213
+ 🔍 IRA Review - typescript:S1854 (BLOCKER)
214
+
215
+ > Remove this useless assignment to local variable "data".
216
+
217
+ Explanation: The variable "data" is assigned a value that is never used
218
+ before being reassigned on line 15. This is dead code that adds confusion.
219
+
220
+ Impact: Dead code makes the codebase harder to read and maintain. It can
221
+ also mask real bugs if developers assume the assignment has a purpose.
222
+
223
+ Suggested Fix: Remove the assignment on line 10 entirely, or if the
224
+ variable is needed later, move the declaration to where it's first used.
225
+ ```
226
+
227
+ ## CLI reference
228
+
229
+ ```
230
+ ira-review review [options]
231
+
232
+ Options:
233
+ --sonar-url <url> SonarQube base URL
234
+ --sonar-token <token> Sonar API token
235
+ --project-key <key> Sonar project key
236
+ --pr <id> Pull request ID
237
+ --bitbucket-token <token> Bitbucket API token
238
+ --repo <repo> workspace/repo-slug
239
+ --ai-provider <provider> AI provider (default: openai)
240
+ --ai-model <model> AI model (default: gpt-4o-mini)
241
+ --bitbucket-url <url> Bitbucket base URL (self-hosted)
242
+ --dry-run Print to terminal instead of posting
243
+ --jira-url <url> JIRA base URL
244
+ --jira-email <email> JIRA account email
245
+ --jira-token <token> JIRA API token
246
+ --jira-ticket <key> JIRA ticket key (e.g. PROJ-123)
247
+ --jira-ac-field <field> Custom field ID for acceptance criteria
248
+ ```
249
+
250
+ ## How it's built
251
+
252
+ ```
253
+ src/
254
+ core/
255
+ sonarClient.ts Sonar API client with pagination and retry
256
+ issueProcessor.ts Filters and groups issues by file
257
+ reviewEngine.ts Orchestrates the full pipeline
258
+ riskScorer.ts Calculates PR risk score from 5 factors
259
+ complexityAnalyzer.ts Fetches and analyzes code complexity metrics
260
+ acceptanceValidator.ts Validates JIRA AC using AI
261
+ ai/
262
+ aiClient.ts Pluggable AI provider (OpenAI today)
263
+ promptBuilder.ts Builds structured prompts per issue
264
+ scm/
265
+ bitbucket.ts Posts inline PR comments
266
+ integrations/
267
+ jiraClient.ts JIRA REST API client
268
+ frameworks/
269
+ detector.ts Auto-detects React, Angular, Vue, NestJS, Node
270
+ utils/
271
+ retry.ts Exponential backoff with jitter
272
+ concurrency.ts Caps parallel AI calls (default: 3)
273
+ env.ts Resolves config from env vars + CLI flags
274
+ types/
275
+ config.ts All config interfaces
276
+ sonar.ts Sonar API types
277
+ review.ts Review result types and provider interfaces
278
+ risk.ts Risk scoring and complexity types
279
+ jira.ts JIRA and acceptance criteria types
280
+ ```
281
+
282
+ ## Built-in reliability
283
+
284
+ Every external API call (Sonar, OpenAI, Bitbucket, JIRA) automatically retries up to 3 times with exponential backoff. AI calls run with a concurrency limit of 3 to avoid hitting rate limits. Complexity analysis is fault-tolerant and won't block the review if the measures API is unavailable. You don't need to configure any of this.
285
+
286
+ ## Security
287
+
288
+ Your tokens are safe. Here's why:
289
+
290
+ - **ira-review runs on your servers, not ours.** It's just an npm package. When it runs in your CI/CD pipeline, tokens live in your infrastructure. The package author has zero access.
291
+ - **The code is open source.** Every line is auditable. Tokens are only used in `Authorization` headers to APIs you already own.
292
+ - **Only compiled code ships to npm.** No source files, no config, no secrets. Just the `dist/` folder.
293
+ - **No telemetry. No analytics. No tracking.** The only network calls are the APIs you explicitly configure: Sonar, OpenAI, Bitbucket, and optionally JIRA.
294
+
295
+ Think of it like any CLI tool (ESLint, AWS CLI, Docker). You install it, you give it your credentials at runtime, it does its job. The author never sees your data.
296
+
297
+ ## Development
298
+
299
+ ```bash
300
+ npm install # install deps
301
+ npm run typecheck # type check
302
+ npm test # run all 64 tests
303
+ npm run test:watch # watch mode
304
+ npm run build # build ESM + CJS + types
305
+ ```
306
+
307
+ ## Requirements
308
+
309
+ - Node.js 18+
310
+ - A SonarQube or SonarCloud project with PR analysis enabled
311
+ - An OpenAI API key (pay-per-use, not free)
312
+ - A Bitbucket repo with an open PR
313
+ - (Optional) JIRA Cloud instance for acceptance criteria validation
314
+
315
+ ## License
316
+
317
+ MIT