nitpik 1.4.2

AI-powered code review CLI
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
# nitpik

**Free for personal and open-source use.** No license key needed — just install and go.

AI-powered code reviews for your team. Bring your own model, bring your own API key. One flat platform fee — no per-seat charges, no usage caps.

[Website](https://nitpik.dev) · [Documentation](https://github.com/nsrosenqvist/nitpik/wiki) · [Get a License](https://nitpik.dev) · `nitpik help`

---

## Why nitpik?

- **Bring your own model** — use Anthropic, OpenAI, Gemini, Cohere, DeepSeek, xAI, Groq, Perplexity, or any OpenAI-compatible API. Your keys, your infrastructure, your data.
- **Flat platform fee** — one price for your whole team. No per-seat licensing, no usage-based billing, no surprises.
- **Free for personal & OSS** — use nitpik on personal projects and open-source repos at no cost, forever. No license key required.
- **Single binary + Docker image** — drop it into any CI pipeline in minutes.
- **Configurable reviewer agents** — built-in profiles or custom Markdown-defined reviewers with your team's conventions.
- **Agentic mode** — let the LLM explore your codebase with built-in and custom tools.
- **Secret scanning** — 200+ rules detect and redact secrets before code reaches the LLM.
- **Threat scanning** — 44 rules plus structural heuristics detect obfuscated payloads, backdoors, supply chain attacks, invisible Unicode tricks, and homoglyph identifiers.
- **Every major CI platform** — GitHub Actions, GitLab CI, Bitbucket Pipelines, Woodpecker/Forgejo/Gitea.

---

## Getting Started

### 1. Install

**Install script (recommended)**

```bash
curl -sSfL https://raw.githubusercontent.com/nsrosenqvist/nitpik/main/install.sh | bash
```

This detects your platform, downloads the latest release, verifies the checksum, and installs the binary to `/usr/local/bin`. Pass options to customize:

```bash
# Install to a custom directory
curl -sSfL https://raw.githubusercontent.com/nsrosenqvist/nitpik/main/install.sh | bash -s -- --dir ~/.local/bin

# Install a specific version
curl -sSfL https://raw.githubusercontent.com/nsrosenqvist/nitpik/main/install.sh | bash -s -- --version v0.3.0
```

**Homebrew (macOS and Linux)**

```bash
brew tap nsrosenqvist/nitpik
brew install nitpik
```

Or build from source:

```bash
cargo install --path .
```

Once installed, update to the latest release at any time:

```bash
nitpik update
```

**Docker**

```bash
docker pull ghcr.io/nsrosenqvist/nitpik:latest
```

### 2. Activate Your License (commercial use only)

For commercial use, activate your license key:

```bash
nitpik license activate <YOUR_LICENSE_KEY>
nitpik license status   # verify activation
```

The key is stored in `~/.config/nitpik/config.toml`. You can also set the `NITPIK_LICENSE_KEY` environment variable in CI.

**Personal and open-source projects do not need a license key.**

### 3. Connect an LLM Provider

nitpik is bring-your-own-model. Set two environment variables — a provider name and the corresponding API key:

```bash
export NITPIK_PROVIDER=anthropic        # or openai, gemini, cohere, deepseek, xai, groq, mistral, ollama, and more
export ANTHROPIC_API_KEY=sk-...         # provider-specific key
```

Or use `NITPIK_API_KEY` as a universal fallback. To use a custom or self-hosted endpoint (any OpenAI-compatible API), also set `NITPIK_BASE_URL`.

### 4. Run Your First Review

```bash
nitpik review --diff-base main
```

That's it. nitpik diffs your current branch against `main`, picks a reviewer profile, scans for secrets, and prints findings to your terminal:

```
nitpik · Free for personal & open-source use. Commercial use requires a license.

✔ w/handler.rs done

 ✖ error in handler.rs:21
   Backend crashes due to unhandled file I/O and parsing errors — The
   `load_users` function uses `unwrap()` for file reading and parsing,
   and accesses array elements without bounds checking.
   → Implement robust error handling (e.g., using `Result` and propagating
     errors) instead of `unwrap()`. Add bounds checking for array access.

 ⚠ warning in handler.rs:36
   N+1 query in `get_users_by_ids` — Calling `get_user` in a loop for
   each ID results in an N+1 query pattern, leading to significant
   performance degradation for large ID lists.
   → Consider implementing a batch fetch mechanism that retrieves all
     users in a single operation.

───────────────────────────────────
 2 findings: 1 errors, 1 warnings, 0 infos
```

---

## Core Concepts

### Diff Inputs

nitpik needs a diff to review. Pick whichever suits your workflow:

```bash
nitpik review --diff-base main              # git diff against a branch/commit
nitpik review --scan src/main.rs            # review a file directly (no git)
nitpik review --diff-file changes.patch     # pre-computed unified diff
git diff main | nitpik review --diff-stdin  # piped from another tool
```

### Reviewer Profiles

Profiles are specialist reviewers with their own system prompts and focus areas. Four ship built-in:

| Profile | Focus |
|---|---|
| `backend` | Correctness, error handling, performance, API design |
| `frontend` | Accessibility, rendering, state management, UX |
| `architect` | System design, coupling, abstractions, scalability |
| `security` | Vulnerabilities, injection, auth, data exposure |

Use one or combine several:

```bash
nitpik review --diff-base main --profile backend,security
```

Auto-select profiles based on what changed — nitpik looks at file extensions, directory structure, and project root files (like `package.json`) to pick the right combination of `frontend`, `backend`, `architect`, and `security`:

```bash
nitpik review --diff-base main --profile auto
```

Select profiles by tag — all profiles (built-in and custom) whose tags match are included:

```bash
nitpik review --diff-base main --tag security          # all profiles tagged "security"
nitpik review --diff-base main --tag css,accessibility  # union of both tags
```

Combine `--tag` with `--profile` to add tag-matched profiles on top of explicit ones:

```bash
nitpik review --diff-base main --profile backend --tag css
```

Tag matching is case-insensitive. See [Custom Agent Profiles](#custom-agent-profiles) for how to set tags on your own profiles.

List all available profiles (including custom ones):

```bash
nitpik profiles
nitpik profiles --profile-dir ./agents
```

### Output Formats

| Format | Flag | Use case |
|---|---|---|
| Styled terminal | `--format terminal` | Local development (default) |
| JSON | `--format json` | Custom tooling / dashboards |
| GitHub annotations | `--format github` | GitHub Actions |
| GitLab Code Quality | `--format gitlab` | GitLab CI merge request widgets |
| Bitbucket Code Insights | `--format bitbucket` | Bitbucket Pipelines |
| Checkstyle XML | `--format checkstyle` | Jenkins, reviewdog, Bitbucket Pipes, and any tool that reads checkstyle |
| Forgejo/Gitea PR review | `--format forgejo` | Woodpecker CI / Forgejo / Gitea (requires `FORGEJO_TOKEN`) |

nitpik exits non-zero on `error`-severity findings by default — just like standard test runners and linters. Adjust the threshold or disable it:

```bash
nitpik review --diff-base main --format github --fail-on warning  # also fail on warnings
nitpik review --diff-base main --no-fail                          # always exit 0
```

Run `nitpik help review` for the full list of flags.

### Intelligent Review Orchestration

nitpik doesn't just pass your diff to an LLM and hope for the best. Every review is carefully assembled to maximize precision and minimize noise:

- **Full-context awareness** — the LLM sees the complete file (or smart excerpts for large files), your project's conventions, commit history, and the focused diff — so it understands what changed and why it matters.
- **Multi-agent coordination** — when multiple reviewer profiles run in parallel, each one knows what the others cover and stays in its lane, eliminating duplicate findings and ensuring nothing falls through the cracks.
- **Iterative continuity** — when you push new changes, nitpik carries forward context from previous reviews so the LLM can distinguish resolved issues from persistent ones, keeping feedback consistent as your code evolves.
- **Quality post-processing** — findings are deduplicated across agents, filtered to only the lines you actually changed, and severity-normalized before they reach you. The result: actionable findings, not LLM noise.

---

## Configuration

Settings are layered — each level overrides the one below it:

**CLI flags → environment variables → `.nitpik.toml` (repo) → `~/.config/nitpik/config.toml` (global) → defaults**

### Project Config (`.nitpik.toml`)

Drop this in your repo root to set defaults for everyone on the team:

```toml
[provider]
name = "anthropic"
model = "claude-sonnet-4-20250514"

[review]
default_profiles = ["backend", "security"]
fail_on = "warning"

[review.agentic]
enabled = false
max_turns = 10
max_tool_calls = 10

[review.context]
max_file_lines = 1000
surrounding_lines = 100

[secrets]
enabled = false
severity = "warning"

[threats]
enabled = false
```

### Environment Variables

| Variable | Purpose |
|---|---|
| `NITPIK_PROVIDER` | LLM provider (`anthropic`, `openai`, `gemini`, etc.) |
| `NITPIK_MODEL` | Model name (e.g. `claude-sonnet-4-20250514`) |
| `NITPIK_API_KEY` | Universal API key fallback |
| `NITPIK_BASE_URL` | Custom endpoint for OpenAI-compatible APIs |
| `NITPIK_LICENSE_KEY` | License key (alternative to `nitpik license activate`) |
| `ANTHROPIC_API_KEY` | Anthropic-specific key |
| `OPENAI_API_KEY` | OpenAI-specific key (also used for openai-compatible) |
| `GEMINI_API_KEY` | Gemini-specific key |
| `BITBUCKET_TOKEN` | Bitbucket access token (optional inside Bitbucket Pipelines) |
| `FORGEJO_TOKEN` | Forgejo/Gitea API token (required for `--format forgejo`) |

nitpik tries to use the provider specific environment variable if it exists, and falls back to `NITPIK_API_KEY`.

---

## Custom Agent Profiles

Create a Markdown file with YAML frontmatter to define your own reviewer. See the [built-in profiles](src/agents/builtin/) for real examples of how to structure effective review prompts.

```markdown
---
name: team-conventions
description: Enforces our internal coding standards
model: claude-sonnet-4-20250514            # optional model override
tags: [style, conventions]
agentic_instructions: >                    # optional — only used in --agent mode
  Use `search_text` to find other usages of renamed symbols and verify
  they follow the new naming convention.
---

You are a code reviewer enforcing our team's conventions.

Check for:
- snake_case functions, PascalCase types
- Result-based error handling (no unwrap in production)
- Doc comments on all public items
```

The `tags` field lets you select this profile with `--tag` instead of (or alongside) `--profile`:

```bash
# Select every profile tagged "style" — including team-conventions above
nitpik review --diff-base main --profile-dir ./agents --tag style
```

Multiple profiles can share tags. For example, if two custom profiles are both tagged `css`, running `--tag css` selects them both (along with any built-in profiles that also carry the tag, such as `frontend`).

Use it directly by path, or place it in a directory and reference by name:

```bash
nitpik review --diff-base main --profile ./team-conventions.md
nitpik review --diff-base main --profile-dir ./agents --profile team-conventions
```

Validate a profile before using it:

```bash
nitpik validate ./team-conventions.md
```

### Custom Agentic Tools

Profiles can define CLI tools that the LLM can invoke during agentic reviews. Add a `tools` section to the frontmatter:

```markdown
---
name: test-aware-reviewer
description: Reviews code and can run the test suite
tools:
  - name: run_tests
    description: Run the test suite with an optional filter
    command: cargo test
    parameters:
      - name: filter
        type: string
        description: Test name filter
        required: false
---

You are a reviewer that validates changes against the test suite...
```

When `--agent` is enabled, the LLM can call `run_tests` (along with the built-in `read_file`, `search_text`, and `list_directory` tools) to explore the codebase and gather context.

```bash
nitpik review --diff-base main --profile ./test-aware-reviewer.md --agent
```

### Environment Passthrough

Custom command tools run in a sandboxed subprocess that uses an **allowlist** model: only essential system variables (`PATH`, `HOME`, `SHELL`, `TERM`, `LANG`, `USER`, locale prefixes like `LC_*`, and XDG directories like `XDG_*`) are inherited. Everything else — API keys, tokens, database credentials, CI secrets — is stripped by default. This prevents accidental credential leakage to LLM-invoked commands.

If your custom tools need additional environment variables (e.g. to authenticate against Jira, Docker, or AWS), declare them in the profile's `environment` frontmatter field:

```markdown
---
name: infra-reviewer
description: Reviews infrastructure changes
environment:
  - JIRA_TOKEN
  - AWS_*          # prefix glob — matches AWS_REGION, AWS_SECRET_ACCESS_KEY, etc.
  - DOCKER_HOST
tools:
  - name: deploy_check
    description: Check deployment status
    command: curl -sH "Authorization: Bearer $JIRA_TOKEN" https://jira.example.com/status
---

You are an infrastructure reviewer...
```

Exact names and prefix globs (ending with `*`) are supported. All env vars not in the default safe set are stripped unless explicitly listed in `environment`.

---

## CI / CD Integration

> **Note:** As of the initial release, only GitHub Actions has been thoroughly tested. More in-depth testing of other CI platforms will follow.

### Docker

The official image ships with `git` and the `nitpik` binary. Mount your repo and pass environment variables:

```bash
docker run --rm \
  -v "$(pwd)":/repo \
  -e NITPIK_PROVIDER=anthropic \
  -e ANTHROPIC_API_KEY \
  -e NITPIK_LICENSE_KEY \
  ghcr.io/nsrosenqvist/nitpik:latest review --diff-base main --scan-secrets
```

### GitHub Actions

The easiest way — use the official action:

```yaml
on: pull_request

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/cache/restore@v4
        with:
          path: ~/.config/nitpik/cache
          key: nitpik-${{ github.repository }}
      - uses: nsrosenqvist/nitpik@v1
        with:
          profiles: backend,security
          fail_on: warning
          scan_secrets: "true"
        env:
          NITPIK_PROVIDER: anthropic
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          NITPIK_LICENSE_KEY: ${{ secrets.NITPIK_LICENSE_KEY }}
      - uses: actions/cache/save@v4
        if: always()
        with:
          path: ~/.config/nitpik/cache
          key: nitpik-${{ github.repository }}
```

The action auto-detects the PR target branch, downloads the binary, and outputs findings as inline annotations.

> **Security:** Always pass API keys via `${{ secrets.* }}` — never hardcode them in workflow files.

<details>
<summary>Manual setup (without the action)</summary>

```yaml
on: pull_request

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: actions/cache/restore@v4
        with:
          path: ~/.config/nitpik/cache
          key: nitpik-${{ github.repository }}
      - name: Install nitpik
        run: curl -sSfL https://raw.githubusercontent.com/nsrosenqvist/nitpik/main/install.sh | bash
      - name: AI Code Review
        run: |
          nitpik review \
            --diff-base "origin/$GITHUB_BASE_REF" \
            --profile backend,security \
            --format github \
            --fail-on warning \
            --scan-secrets
        env:
          NITPIK_PROVIDER: anthropic
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
          NITPIK_LICENSE_KEY: ${{ secrets.NITPIK_LICENSE_KEY }}
      - uses: actions/cache/save@v4
        if: always()
        with:
          path: ~/.config/nitpik/cache
          key: nitpik-${{ github.repository }}
```

</details>

Findings appear as inline annotations on the pull request.

### GitLab CI/CD

```yaml
code-review:
  stage: test
  image: ghcr.io/nsrosenqvist/nitpik:latest
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  script:
    - git fetch origin "$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
    - nitpik review
        --diff-base "origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME"
        --profile backend,security
        --format gitlab
        --fail-on warning
        --scan-secrets
        > gl-code-quality-report.json
  cache:
    key: nitpik
    paths:
      - .nitpik-cache/
    when: always
  artifacts:
    reports:
      codequality: gl-code-quality-report.json
  variables:
    NITPIK_PROVIDER: anthropic
    ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
    NITPIK_LICENSE_KEY: $NITPIK_LICENSE_KEY
    XDG_CONFIG_HOME: $CI_PROJECT_DIR/.nitpik-cache
```

Findings appear in the merge request Code Quality widget.

### Bitbucket Pipelines

The `bitbucket` format posts findings as Code Insights annotations via the Bitbucket API. Inside Bitbucket Pipelines, authentication is handled automatically through the built-in proxy — no token required.

```yaml
definitions:
  caches:
    nitpik: /root/.config/nitpik/cache

pipelines:
  pull-requests:
    '**':
      - step:
          image: ghcr.io/nsrosenqvist/nitpik:latest
          caches:
            - nitpik
          script:
            - git fetch origin "$BITBUCKET_PR_DESTINATION_BRANCH"
            - nitpik review
                --diff-base "origin/$BITBUCKET_PR_DESTINATION_BRANCH"
                --profile security,backend
                --format bitbucket
                --fail-on error
                --scan-secrets
          variables:
            NITPIK_PROVIDER: anthropic
            ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
            NITPIK_LICENSE_KEY: $NITPIK_LICENSE_KEY
```

> **Note:** Outside Bitbucket Pipelines (e.g. a self-hosted runner), set `BITBUCKET_TOKEN` with `pullrequest` and `repository:write` scopes.

> **Security:** Add `ANTHROPIC_API_KEY` and `NITPIK_LICENSE_KEY` as **secured** pipeline variables — never hardcode them in `bitbucket-pipelines.yml`.

### Woodpecker CI (Forgejo / Gitea / Codeberg)

The `forgejo` format posts findings as inline PR review comments via the Forgejo/Gitea API. This requires a **personal access token** with (at minimum) the **`write:repository`** scope.

Create one under **User settings → Applications → Generate New Token** in your Forgejo or Gitea instance. Add it as a Woodpecker secret named `forgejo_token` so it is exposed as `FORGEJO_TOKEN` at runtime.

```yaml
when:
  event: pull_request

steps:
  - name: ai-review
    image: ghcr.io/nsrosenqvist/nitpik:latest
    commands:
      - git fetch origin "$CI_COMMIT_TARGET_BRANCH"
      - nitpik review
          --diff-base "origin/$CI_COMMIT_TARGET_BRANCH"
          --profile backend,security
          --format forgejo
          --fail-on warning
          --scan-secrets
    secrets: [forgejo_token, anthropic_api_key, nitpik_license_key]
    environment:
      NITPIK_PROVIDER: anthropic
    volumes:
      - nitpik-cache:/root/.config/nitpik/cache
```

> **Security:** Add `anthropic_api_key`, `nitpik_license_key`, and `forgejo_token` as [Woodpecker secrets](https://woodpecker-ci.org/docs/usage/secrets) — never hardcode them in the pipeline file.

---

## Secret Scanning

nitpik ships with 200+ gitleaks-compatible rules and Shannon entropy checks. When enabled, secrets are detected and redacted **before** any code is sent to the LLM.

```bash
nitpik review --diff-base main --scan-secrets
```

> **Performance note:** Compiling the built-in regex rules adds a few seconds of startup time. This cost is paid once per invocation and only when secret scanning is enabled — normal reviews without `--scan-secrets` are unaffected.

Always-on in CI:

```toml
# .nitpik.toml
[secrets]
enabled = true
```

Bring your own rules:

```bash
nitpik review --diff-base main --scan-secrets --secrets-rules ./custom-rules.toml
```

---

## Threat Scanning

nitpik detects potentially harmful code patterns — obfuscated payloads, dangerous API calls, supply chain hooks, backdoors, and data exfiltration — using 44 built-in rules plus structural heuristics. When an LLM provider is configured, flagged patterns are triaged by the model to reduce false positives.

```bash
nitpik review --diff-base main --scan-threats
```

Beyond regex rules, nitpik detects **invisible Unicode** characters (zero-width spaces, Hangul filler payloads used by Glassworm), **Trojan Source** bidi overrides (CVE-2021-42574), and **mixed-script homoglyph identifiers** — where Cyrillic or Greek lookalike characters are mixed into Latin identifiers to create visually identical but semantically different symbols.

Enable both threat and secret scanning for maximum coverage:

```bash
nitpik review --diff-base main --scan-secrets --scan-threats
```

Always-on in CI:

```toml
# .nitpik.toml
[threats]
enabled = true
```

Bring your own rules:

```bash
nitpik review --diff-base main --scan-threats --threat-rules ./custom-threats.toml
```

---

## Project Documentation Context

nitpik automatically detects documentation files in your repository root and includes them in the review prompt so the LLM understands your team's conventions.

### Priority review context (`REVIEW.md` / `NITPIK.md`)

If a **`REVIEW.md`** or **`NITPIK.md`** file exists in the repo root, nitpik uses *only* those files as review context and skips the generic doc list entirely. This lets you provide focused review guidance without polluting the prompt with coding-agent instructions (like `AGENTS.md` or `.cursorrules`) that aren't relevant to a reviewer.

Both files can coexist — if both are present, both are included.

### Generic fallback docs

When no priority file is found, nitpik falls back to scanning for these well-known files:

`AGENTS.md`, `ARCHITECTURE.md`, `CONVENTIONS.md`, `CONTRIBUTING.md`, `CLAUDE.md`, `.github/copilot-instructions.md`, `.cursorrules`, `CODING_GUIDELINES.md`, `STYLE_GUIDE.md`, `DEVELOPMENT.md`

Files larger than 256 KB are skipped.

### Controlling project docs

| Flag | Default | Effect |
|---|---|---|
| `--no-project-docs` | `false` | Skip all auto-detected project documentation files |
| `--exclude-doc <NAME>` | *(none)* | Exclude specific docs by filename (comma-separated) |

Skip all project docs (useful to reduce prompt size or cost):

```bash
nitpik review --diff-base main --no-project-docs
```

Exclude only specific files while keeping the rest:

```bash
nitpik review --diff-base main --exclude-doc AGENTS.md
nitpik review --diff-base main --exclude-doc AGENTS.md,CONTRIBUTING.md
```

> **Note:** Excluding all priority files (e.g. `--exclude-doc REVIEW.md`) causes nitpik to fall back to the generic doc list.

---

## Commit History Context

When reviewing a git ref diff (`--diff-base`), nitpik includes the commit log between the base and HEAD in the review prompt. This gives the LLM insight into the *intent* behind the changes — commit messages explain *why* code was changed, helping the reviewer calibrate severity and avoid flagging deliberate refactors or fixes.

Up to 50 commit summaries (newest first) are included automatically. This feature only applies to `--diff-base` mode — stdin diffs, diff files, and directory scans have no commit history to include.

| Flag | Default | Effect |
|---|---|---|
| `--no-commit-context` | `false` | Skip injecting commit summaries into the review prompt |

Disable commit context when commit messages are noisy or to reduce token usage:

```bash
nitpik review --diff-base main --no-commit-context
```

---

## Caching

nitpik caches review results by content hash. Unchanged files are not re-reviewed, saving time and API cost.

When a file changes and the cache is invalidated, nitpik automatically includes the **previous findings** in the LLM prompt. This lets the model distinguish resolved issues from persistent or new ones, improving consistency across successive reviews of the same file.

### Branch-scoped prior findings

Prior findings are tracked per **branch** so that parallel PRs reviewing the same file don't cross-contaminate each other. nitpik detects the branch from `git rev-parse --abbrev-ref HEAD`, falling back to CI environment variables (`GITHUB_HEAD_REF`, `CI_COMMIT_BRANCH`, `CI_MERGE_REQUEST_SOURCE_BRANCH_NAME`, `BITBUCKET_BRANCH`, `CI_BRANCH`) when running in detached-HEAD mode.

Previous findings are sorted by severity (errors first) before being injected, so the most important context is always preserved.

### Stale sidecar cleanup

Sidecar metadata files older than **30 days** are automatically removed at the start of each review run, keeping the cache directory from growing unbounded after branches are merged or deleted.

```bash
nitpik cache stats   # show entry count and size
nitpik cache clear   # wipe the cache (including all sidecar metadata)
nitpik cache path    # print the cache directory
```

| Flag | Default | Effect |
|---|---|---|
| `--no-cache` | `false` | Disable caching entirely for this run |
| `--no-prior-context` | `false` | Skip injecting previous findings on cache invalidation |
| `--max-prior-findings <N>` | unlimited | Cap the number of prior findings included in the prompt |

Disable caching for a single run with `--no-cache`. Use `--no-prior-context` for a clean-slate review without prior-finding context, or `--max-prior-findings` to limit prompt token usage when prior reviews produced many findings.

---

## Limitations & Disclaimer

nitpik uses third-party large language models (LLMs) to analyze code. **All findings are AI-generated and advisory.** They may be incorrect, incomplete, or hallucinated. nitpik does not guarantee code quality, security, or correctness.

- **Always review AI suggestions with human judgment** before acting on them.
- **Code diffs are sent to your configured LLM provider** (e.g. Anthropic, OpenAI, Gemini). nitpik does not store or retain your code, but the LLM provider's data policies apply. Choose a provider whose terms you trust. See the [Privacy Policy]https://nitpik.dev/privacy for details on what nitpik itself collects.
- **Enable `--scan-secrets`** to detect and redact secrets before code is sent to the LLM. This is a best-effort safety net — unusual or custom secret formats may not be detected. Without this flag, secrets present in your diffs will be transmitted to the provider.
- **Enable `--scan-threats`** to detect obfuscated payloads, backdoors, and other malicious patterns. This is a best-effort defense layer — novel attack techniques or sophisticated payloads may evade detection. Threat findings are advisory — always verify with human judgment.
- **Neither secret scanning nor threat scanning guarantees detection of all issues.** Use them alongside dedicated security tools, dependency audits, and manual review.
- **Provider integrations rely on a third-party open-source library.** LLM provider support may change, break, or be removed due to upstream updates outside of nitpik's control. If you plan to purchase a commercial license, **please verify that your provider and model work correctly using the free unlicensed version first.** No license key is required for this — just install and test with your own API key.
- nitpik is a development aid, not a replacement for human code review, testing, or security auditing.

---

## Telemetry

nitpik sends a single anonymous heartbeat per review run — **no code, file names, findings, or PII**. Just aggregate counts (files, lines, profiles) and whether you're in CI. You can verify exactly what is sent by reading [`src/telemetry/mod.rs`](src/telemetry/mod.rs).

The heartbeat payload contains only:

- A random run ID (not persisted across runs)
- File count and total changed lines
- Number of agent profiles used
- Whether a commercial license is active
- Whether the run is in a CI environment
- CLI version string

Disable it:

```bash
nitpik review --diff-base main --no-telemetry   # per-run
export NITPIK_TELEMETRY=false                    # env var
```

```toml
# .nitpik.toml or ~/.config/nitpik/config.toml
[telemetry]
enabled = false
```

---

## Updating

nitpik can update itself to the latest release from GitHub:

```bash
nitpik update           # update to latest version (skips if already current)
nitpik update --force   # re-download even if already on latest
```

The update process downloads the release archive for your platform, verifies its SHA256 checksum, and atomically replaces the running binary.

If the binary is installed in a system directory (e.g. `/usr/local/bin`), you may need `sudo`:

```bash
sudo nitpik update
```

> **Note:** In Docker containers and CI environments, nitpik will print a warning suggesting you rebuild the image or pin a version in your pipeline instead of self-updating.

---

## Version Information

Print detailed build metadata:

```bash
nitpik version
```

Outputs version, git commit, build date, and target triple:

```
nitpik 0.2.0
commit:     a1b2c3d
built:      2026-02-14
target:     x86_64-unknown-linux-gnu
```

For the short one-liner, use the standard `--version` flag:

```bash
nitpik --version         # nitpik 0.2.0
```

---

## Further Help

Every command and flag is documented in the built-in help:

```bash
nitpik help              # overview of all commands
nitpik help review       # full review flag reference
nitpik help license      # license management
nitpik help cache        # cache management
nitpik help update       # self-update
nitpik version           # version, commit, build date, target
```

---

## Feedback & Issues

Found a bug, false positive, or harmful AI output? Please [open an issue](https://github.com/nsrosenqvist/nitpik/issues) on GitHub. Feedback helps improve nitpik for everyone.

---

## License

Licensed under the [Business Source License 1.1](LICENSE).

**Free for personal, educational, and open-source use — no license key required.** Commercial use requires a license. One flat fee, any team size, unlimited usage. Visit [nitpik.dev](https://nitpik.dev) for pricing.

You bring your own LLM provider and API key — nitpik never proxies, stores, or meters your API calls.

The code converts to [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) three years after each release.

[Terms of Service](https://nitpik.dev/terms) · [Privacy Policy](https://nitpik.dev/privacy)