ira-review 0.1.0 → 0.2.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.
@@ -0,0 +1,448 @@
1
+ # ira-review
2
+
3
+ **AI-powered PR reviews with built-in JIRA intelligence.**
4
+
5
+ We've all been there. SonarQube flags a bunch of issues on your PR, and now someone has to go through each one, understand what it actually means, and figure out how to fix it. It's tedious and eats up review time.
6
+
7
+ IRA takes that off your plate. It picks up your SonarQube issues, sends them through AI, and posts clear comments right on your pull request with an explanation, the impact, and a suggested fix. On top of that, it scores the overall risk of your PR, flags complex code, and can even check your JIRA acceptance criteria automatically.
8
+
9
+ ## Language and framework support
10
+
11
+ IRA works with **any language** that SonarQube or SonarCloud can analyze. It doesn't read your source code directly. It picks up the issues that Sonar already found and sends them to AI for explanation and fixes. So if Sonar can analyze your code, IRA can review it.
12
+
13
+ IRA itself is an npm package and needs Node.js to run, but your project doesn't have to be a JavaScript project. You just run IRA as a CLI tool in your pipeline, the same way you'd use any other linting or code quality tool.
14
+
15
+ ### JavaScript and TypeScript projects
16
+
17
+ JS/TS projects get the most out of IRA. You can install it as a dev dependency and use the CLI or the programmatic API directly.
18
+
19
+ ```bash
20
+ npm install --save-dev ira-review
21
+ npx ira-review review --pr 42 --dry-run
22
+ ```
23
+
24
+ IRA also auto-detects your framework and tailors AI suggestions to match its conventions:
25
+
26
+ | Framework | How it's detected |
27
+ |---|---|
28
+ | React | `react` in `package.json` dependencies |
29
+ | Angular | `@angular/core` in `package.json` dependencies |
30
+ | Vue | `vue` in `package.json` dependencies |
31
+ | NestJS | `@nestjs/core` in `package.json` dependencies |
32
+ | Node.js | `package.json` exists (fallback) |
33
+
34
+ ### Java, Kotlin, Scala, and other JVM projects
35
+
36
+ You don't need to touch your `pom.xml` or `build.gradle`. Just add a step in your CI that runs IRA using `npx`. Most CI runners already have Node.js installed.
37
+
38
+ ```yaml
39
+ # GitHub Actions example
40
+ - uses: actions/setup-node@v4
41
+ with:
42
+ node-version: 20
43
+ - run: npx ira-review review --pr ${{ github.event.pull_request.number }} --dry-run
44
+ ```
45
+
46
+ ### Python projects
47
+
48
+ Same idea. Just run IRA as a one-off command in your pipeline.
49
+
50
+ ```yaml
51
+ # GitHub Actions example
52
+ - uses: actions/setup-node@v4
53
+ with:
54
+ node-version: 20
55
+ - run: npx ira-review review --pr ${{ github.event.pull_request.number }} --dry-run
56
+ ```
57
+
58
+ You can also add it to a Makefile if that's how your team works:
59
+
60
+ ```makefile
61
+ review:
62
+ npx ira-review review --pr $(PR) --dry-run
63
+ ```
64
+
65
+ ### Go, Rust, C#, PHP, Ruby, Swift, and everything else
66
+
67
+ It all works the same way. If Node.js is available in your CI environment (and it almost always is), just run:
68
+
69
+ ```bash
70
+ npx ira-review review \
71
+ --sonar-url https://sonarcloud.io \
72
+ --sonar-token $SONAR_TOKEN \
73
+ --project-key my-project \
74
+ --pr $PR_ID \
75
+ --dry-run
76
+ ```
77
+
78
+ `npx` downloads and runs IRA on the fly, so there's nothing to install beforehand.
79
+
80
+ ### No Node.js? Use Docker
81
+
82
+ If your CI environment doesn't have Node.js and you can't install it, you can run IRA through Docker:
83
+
84
+ ```bash
85
+ docker run --rm node:20-slim npx ira-review review \
86
+ --sonar-url https://sonarcloud.io \
87
+ --sonar-token $SONAR_TOKEN \
88
+ --project-key my-project \
89
+ --pr $PR_ID \
90
+ --dry-run
91
+ ```
92
+
93
+ ## How it works
94
+
95
+ ```mermaid
96
+ flowchart LR
97
+ subgraph Your CI/CD Pipeline
98
+ A[Developer pushes code] --> B[SonarQube analyzes PR]
99
+ B --> C[IRA picks up issues]
100
+ end
101
+ subgraph IRA Review Engine
102
+ C --> D[Filters BLOCKER & CRITICAL]
103
+ D --> E[Detects framework]
104
+ E --> F[AI generates reviews]
105
+ F --> G[Calculates risk score]
106
+ end
107
+ G --> H[Posts comments on PR]
108
+ G --> I[Validates JIRA AC]
109
+ ```
110
+
111
+ Here's the full flow in detail:
112
+
113
+ ```mermaid
114
+ sequenceDiagram
115
+ participant Dev as Developer
116
+ participant CI as CI/CD Pipeline
117
+ participant Sonar as SonarQube
118
+ participant IRA as IRA Review
119
+ participant AI as OpenAI
120
+ participant SCM as Bitbucket
121
+ participant JIRA as JIRA (optional)
122
+
123
+ Dev->>CI: Push code / Open PR
124
+ CI->>Sonar: Run static analysis
125
+ Sonar-->>CI: Analysis complete
126
+ CI->>IRA: Run ira-review
127
+ IRA->>Sonar: Fetch PR issues (API)
128
+ Sonar-->>IRA: BLOCKER & CRITICAL issues
129
+ IRA->>AI: Send each issue for review
130
+ AI-->>IRA: Explanation + Impact + Fix
131
+ IRA->>IRA: Calculate risk score
132
+ IRA->>JIRA: Fetch acceptance criteria
133
+ JIRA-->>IRA: AC from ticket
134
+ IRA->>AI: Validate AC against issues
135
+ AI-->>IRA: Pass/Fail per criterion
136
+ IRA->>SCM: Post inline comments
137
+ IRA->>SCM: Post risk summary
138
+ ```
139
+
140
+ ## What it does
141
+
142
+ 1. Pulls issues from SonarQube or SonarCloud for a specific pull request
143
+ 2. Filters them down to what actually matters (BLOCKER and CRITICAL severity only)
144
+ 3. Detects your framework (React, Angular, Vue, NestJS, Node) to give smarter suggestions
145
+ 4. Sends each issue to AI for a plain-English explanation and a concrete fix
146
+ 5. Calculates a risk score for the PR based on issues, security concerns, and complexity
147
+ 6. Analyzes code complexity and highlights the hotspots
148
+ 7. Validates JIRA acceptance criteria against the PR (if you've set up JIRA)
149
+ 8. Posts inline comments back to your pull request on Bitbucket
150
+
151
+ ## Install
152
+
153
+ ```bash
154
+ npm install ira-review
155
+ ```
156
+
157
+ ## Quick start
158
+
159
+ The fastest way to try it out. This runs against your real Sonar data but prints everything to your terminal instead of posting to Bitbucket, so you don't need a Bitbucket token.
160
+
161
+ ```bash
162
+ export OPENAI_API_KEY=[REDACTED:api-key]
163
+
164
+ npx ira-review review \
165
+ --sonar-url https://sonarcloud.io \
166
+ --sonar-token sqa_xxxxx \
167
+ --project-key my-org_my-project \
168
+ --pr 42 \
169
+ --dry-run
170
+ ```
171
+
172
+ Once you're happy with how it works, drop the `--dry-run` flag and add your Bitbucket credentials to start posting comments on real PRs:
173
+
174
+ ```bash
175
+ npx ira-review review \
176
+ --sonar-url https://sonarcloud.io \
177
+ --sonar-token sqa_xxxxx \
178
+ --project-key my-org_my-project \
179
+ --pr 42 \
180
+ --bitbucket-token bb_xxxxx \
181
+ --repo my-workspace/my-repo
182
+ ```
183
+
184
+ ## PR risk scoring
185
+
186
+ Every review automatically calculates a risk score based on five factors:
187
+
188
+ | Factor | Max Points | What it measures |
189
+ |---|---|---|
190
+ | Blocker Issues | 30 | Number of blocker-level issues |
191
+ | Critical Issues | 20 | Number of critical-level issues |
192
+ | Issue Density | 15 | Issues per file changed |
193
+ | Security Concerns | 20 | Vulnerabilities, CWE/OWASP-tagged issues |
194
+ | Code Complexity | 15 | Files with cyclomatic/cognitive complexity > 15 |
195
+
196
+ Risk levels: **LOW** (0-19), **MEDIUM** (20-39), **HIGH** (40-59), **CRITICAL** (60+)
197
+
198
+ In dry-run mode you'll see something like:
199
+
200
+ ```
201
+ ═══════════════════════════════════════════════════
202
+ 🟠 PR Risk Score: HIGH (45/100)
203
+ ═══════════════════════════════════════════════════
204
+ ▓ Blocker Issues: 20/30 - 2 blocker issues found
205
+ ▓ Security Concerns: 10/20 - 1 security-related issue
206
+ ▓ Code Complexity: 10/15 - 2 high-complexity files
207
+ ▓ Critical Issues: 5/20 - 1 critical issue found
208
+ ░ Issue Density: 0/15 - 0.5 issues per file changed
209
+ ```
210
+
211
+ ## Code complexity insights
212
+
213
+ IRA fetches complexity metrics from SonarQube's measures API and flags the files that need attention:
214
+
215
+ - **Cyclomatic complexity** tells you how many paths exist through the code
216
+ - **Cognitive complexity** tells you how hard it is to understand
217
+ - **Lines of code** per file gives you a sense of scale
218
+
219
+ Any file with complexity above 15 gets flagged as a hotspot. This feeds into the risk score and shows up in dry-run output.
220
+
221
+ ## JIRA acceptance criteria validation
222
+
223
+ If your team tracks acceptance criteria in JIRA, IRA can check whether a PR actually meets them. This is completely optional and only kicks in when you provide your JIRA config.
224
+
225
+ ```bash
226
+ npx ira-review review \
227
+ --sonar-url https://sonarcloud.io \
228
+ --sonar-token sqa_xxxxx \
229
+ --project-key my-org_my-project \
230
+ --pr 42 \
231
+ --jira-url https://yourcompany.atlassian.net \
232
+ --jira-email dev@company.com \
233
+ --jira-token jira_xxxxx \
234
+ --jira-ticket PROJ-123 \
235
+ --dry-run
236
+ ```
237
+
238
+ IRA fetches the JIRA ticket, pulls out the acceptance criteria, and uses AI to check each one against the SonarQube analysis. The output looks like:
239
+
240
+ ```
241
+ ✅ JIRA Acceptance: PROJ-123 - Add user authentication
242
+ ✅ CRITERION_1: MET - Authentication endpoint implemented
243
+ No blocker issues in auth module
244
+ ❌ CRITERION_2: NOT_MET - Input validation
245
+ Critical security issue found in login handler
246
+ ```
247
+
248
+ If your team stores acceptance criteria in a custom field, just pass the field ID:
249
+
250
+ ```bash
251
+ --jira-ac-field customfield_10042
252
+ ```
253
+
254
+ The default field is `customfield_10035`.
255
+
256
+ ## Using it in code
257
+
258
+ If you want more control, you can use IRA programmatically instead of the CLI:
259
+
260
+ ```typescript
261
+ import { ReviewEngine } from "ira-review";
262
+
263
+ const engine = new ReviewEngine({
264
+ sonar: {
265
+ baseUrl: "https://sonarcloud.io",
266
+ token: "sqa_xxxxx",
267
+ projectKey: "my-org_my-project",
268
+ },
269
+ scm: {
270
+ token: "bb_xxxxx",
271
+ workspace: "my-workspace",
272
+ repoSlug: "my-repo",
273
+ },
274
+ ai: {
275
+ provider: "openai",
276
+ apiKey: process.env.OPENAI_API_KEY!,
277
+ },
278
+ pullRequestId: "42",
279
+ // Optional JIRA integration
280
+ jira: {
281
+ baseUrl: "https://yourcompany.atlassian.net",
282
+ email: "dev@company.com",
283
+ token: "jira_xxxxx",
284
+ },
285
+ jiraTicket: "PROJ-123",
286
+ });
287
+
288
+ const result = await engine.run();
289
+
290
+ console.log(`Risk: ${result.risk?.level}`);
291
+ console.log(`Complexity hotspots: ${result.complexity?.hotspots.length}`);
292
+ console.log(`AC validation: ${result.acceptanceValidation?.overallPass}`);
293
+ ```
294
+
295
+ If you just want to preview without posting anything, add `dryRun: true` to the config.
296
+
297
+ ## Environment variables
298
+
299
+ If you're tired of passing flags every time, set these environment variables instead. CLI flags still take priority if you pass both.
300
+
301
+ | Variable | What it does |
302
+ |---|---|
303
+ | `OPENAI_API_KEY` | Your OpenAI API key (required) |
304
+ | `IRA_SONAR_URL` | SonarQube/SonarCloud URL |
305
+ | `IRA_SONAR_TOKEN` | Sonar API token |
306
+ | `IRA_PROJECT_KEY` | Sonar project key |
307
+ | `IRA_PR` | Pull request ID |
308
+ | `IRA_BITBUCKET_TOKEN` | Bitbucket API token |
309
+ | `IRA_BITBUCKET_URL` | Bitbucket Server URL (only for self-hosted) |
310
+ | `IRA_REPO` | `workspace/repo-slug` format |
311
+ | `IRA_JIRA_URL` | JIRA base URL (optional) |
312
+ | `IRA_JIRA_EMAIL` | JIRA account email (optional) |
313
+ | `IRA_JIRA_TOKEN` | JIRA API token (optional) |
314
+
315
+ You can also copy `.env.example` to `.env` and fill in the values there.
316
+
317
+ ## CI/CD example
318
+
319
+ Here's how you'd wire it into a Bitbucket Pipeline:
320
+
321
+ ```yaml
322
+ pipelines:
323
+ pull-requests:
324
+ '**':
325
+ - step:
326
+ name: AI Code Review
327
+ script:
328
+ - npx ira-review review --pr $BITBUCKET_PR_ID --repo $BITBUCKET_REPO_FULL_NAME
329
+ environment:
330
+ OPENAI_API_KEY: $OPENAI_API_KEY
331
+ IRA_SONAR_URL: $SONAR_URL
332
+ IRA_SONAR_TOKEN: $SONAR_TOKEN
333
+ IRA_PROJECT_KEY: $SONAR_PROJECT_KEY
334
+ IRA_BITBUCKET_TOKEN: $BB_TOKEN
335
+ ```
336
+
337
+ All tokens come from your pipeline's secret variables. IRA never stores or transmits them anywhere else.
338
+
339
+ ## What the comments look like
340
+
341
+ When IRA posts to your PR, each comment looks something like this:
342
+
343
+ ```
344
+ 🔍 IRA Review - typescript:S1854 (BLOCKER)
345
+
346
+ > Remove this useless assignment to local variable "data".
347
+
348
+ Explanation: The variable "data" is assigned a value that is never used
349
+ before being reassigned on line 15. This is dead code that adds confusion.
350
+
351
+ Impact: Dead code makes the codebase harder to read and maintain. It can
352
+ also mask real bugs if developers assume the assignment has a purpose.
353
+
354
+ Suggested Fix: Remove the assignment on line 10 entirely, or if the
355
+ variable is needed later, move the declaration to where it's first used.
356
+ ```
357
+
358
+ ## CLI reference
359
+
360
+ ```
361
+ ira-review review [options]
362
+
363
+ Options:
364
+ --sonar-url <url> SonarQube base URL
365
+ --sonar-token <token> Sonar API token
366
+ --project-key <key> Sonar project key
367
+ --pr <id> Pull request ID
368
+ --bitbucket-token <token> Bitbucket API token
369
+ --repo <repo> workspace/repo-slug
370
+ --ai-provider <provider> AI provider (default: openai)
371
+ --ai-model <model> AI model (default: gpt-4o-mini)
372
+ --bitbucket-url <url> Bitbucket base URL (self-hosted)
373
+ --dry-run Print to terminal instead of posting
374
+ --jira-url <url> JIRA base URL
375
+ --jira-email <email> JIRA account email
376
+ --jira-token <token> JIRA API token
377
+ --jira-ticket <key> JIRA ticket key (e.g. PROJ-123)
378
+ --jira-ac-field <field> Custom field ID for acceptance criteria
379
+ ```
380
+
381
+ ## How it's built
382
+
383
+ ```
384
+ src/
385
+ core/
386
+ sonarClient.ts Sonar API client with pagination and retry
387
+ issueProcessor.ts Filters and groups issues by file
388
+ reviewEngine.ts Orchestrates the full review pipeline
389
+ riskScorer.ts Calculates PR risk score from 5 factors
390
+ complexityAnalyzer.ts Fetches and analyzes code complexity metrics
391
+ acceptanceValidator.ts Validates JIRA acceptance criteria using AI
392
+ ai/
393
+ aiClient.ts Pluggable AI provider (OpenAI for now)
394
+ promptBuilder.ts Builds structured prompts per issue
395
+ scm/
396
+ bitbucket.ts Posts inline PR comments
397
+ integrations/
398
+ jiraClient.ts JIRA REST API client
399
+ frameworks/
400
+ detector.ts Auto-detects React, Angular, Vue, NestJS, Node
401
+ utils/
402
+ retry.ts Exponential backoff with jitter
403
+ concurrency.ts Caps parallel AI calls (default: 3)
404
+ env.ts Resolves config from env vars and CLI flags
405
+ types/
406
+ config.ts All config interfaces
407
+ sonar.ts Sonar API types
408
+ review.ts Review result types and provider interfaces
409
+ risk.ts Risk scoring and complexity types
410
+ jira.ts JIRA and acceptance criteria types
411
+ ```
412
+
413
+ ## Built-in reliability
414
+
415
+ All external API calls to Sonar, OpenAI, Bitbucket, and JIRA automatically retry up to 3 times with exponential backoff. AI calls run with a concurrency limit of 3 so you don't hit rate limits. If something optional like complexity analysis or JIRA validation fails, the review still completes and the failure shows up as a warning instead of crashing the whole run. You don't need to configure any of this.
416
+
417
+ ## Security
418
+
419
+ Your tokens are safe.
420
+
421
+ - IRA runs on your servers, not ours. It's just an npm package. When it runs in your CI/CD pipeline, your tokens stay in your infrastructure. The package author has zero access to them.
422
+ - The code is fully open source. Every line is auditable. Tokens are only used in `Authorization` headers to APIs you already own.
423
+ - Only compiled code ships to npm. No source files, no config, no secrets. Just the `dist/` folder.
424
+ - There's no telemetry, no analytics, and no tracking. The only network calls IRA makes are to the APIs you explicitly configure: Sonar, OpenAI, Bitbucket, and optionally JIRA.
425
+
426
+ Think of it like ESLint or the AWS CLI. You install it, give it your credentials at runtime, and it does its job. Nobody else sees your data.
427
+
428
+ ## Development
429
+
430
+ ```bash
431
+ npm install # install deps
432
+ npm run typecheck # type check
433
+ npm test # run all 74 tests
434
+ npm run test:watch # watch mode
435
+ npm run build # build ESM + CJS + types
436
+ ```
437
+
438
+ ## Requirements
439
+
440
+ - Node.js 18+
441
+ - A SonarQube or SonarCloud project with PR analysis enabled
442
+ - An OpenAI API key (pay-per-use, not free tier)
443
+ - A Bitbucket repo with an open pull request
444
+ - JIRA Cloud instance for acceptance criteria validation (optional)
445
+
446
+ ## License
447
+
448
+ MIT