> ## Documentation Index
> Fetch the complete documentation index at: https://docs.peepsai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Complexity check

> A check on each GitHub pull request that names the functions crossing a complexity limit, with the number before and after.

The complexity check measures the functions a pull request changes and names the ones that cross a limit. The check itself never fails a pull request. To block a merge on it, set **Complexity findings** to **Request changes**, and the code review does the blocking.

## What you see

A check named `Peeps / static analysis` appears on the pull request's latest commit, beside your other checks.

Each function that needs your attention gets one annotation, with its number before and after, the limit and the metric:

```text theme={null}
parseOrder 12 → 17, limit 15, cyclomatic
```

A function over both limits gets one annotation with both numbers. A new function reads `new → 17`.

| A changed function that is | Shows as |
| - | - |
| New and over the limit | A warning |
| Over the limit for the first time in this pull request | A warning |
| Already over the limit, and higher now | A notice |
| Already over the limit, and no higher | A count in the summary |
| Over the limit, with no earlier number to compare | A warning that reads `now` and the number, such as `now 20` |
| Within the limit | Nothing |

The summary has a line for each metric that's on, with the tool and version it used, followed by any files it couldn't analyse. A check shows up to 50 annotations, and the summary counts the rest per file.

## Turn it on

You set it up one repository at a time. It's off until you turn it on, and it doesn't depend on the [code review](https://docs.peepsai.com/code-review/settings.md) switch for that repository.

**1. Pick the repository**

Go to **Settings** > **Code review** > **Review settings** and choose it from the **Repository** menu.

**2. Turn on the check**

In the **Static code analysis** section, use the **Complexity check** switch.

**3. Choose the metrics and limits**

| Metric | Starts | Default limit | What it counts |
| - | - | - | - |
| **Cyclomatic** | On | 15 | Paths through a function |
| **Cognitive** | Off | 20 | Nesting and breaks in the flow |

Each has its own switch and limit, a whole number from 5 to 50. With both off, Peeps posts no check.

**4. Save**

Click **Save changes**.

A change applies from the next push. A commit that already has its check isn't checked again. Presets don't change this section.

If the GitHub App was reinstalled since you saved, the section says the check isn't running. Click **Save changes** to turn it back on.

## Who can use it

You need the Owner role. You also need code review available on your organization and the [Peeps GitHub App](https://docs.peepsai.com/integrations/github.md) connected.

> [!NOTE]
>
> If you don't see the **Static code analysis** section, it isn't turned on for your organization yet. [Get in touch](mailto:support@peepsai.com) to request access.

## Where the numbers come from

| Metric | Tool | To get the same number yourself |
| - | - | - |
| **Cyclomatic** | Oxlint | ESLint 9 or later, `complexity` rule |
| **Cognitive** | Biome | Biome, `noExcessiveCognitiveComplexity` rule |

The check's summary names the version it used.

* **ESLint can read one higher in one case.** It counts a default inside an array assignment, such as `[s = ""] = run()`, and Oxlint doesn't.
* **Biome reports only scores above 1.** A function with no score reads `≤ 1`.
* **Biome doesn't score getters, setters or static blocks.** They read `≤ 1` and can't cross a limit.
* **Biome's score stops at 255.** The check shows it as `255+`.

Nothing runs in your CI, and nothing from your pull request is executed. Peeps reads the changed files through the GitHub App and the tools read a copy of them as data. No AI model is involved in the check.

Your config files, ignore files and suppression comments, such as `eslint-disable` and `biome-ignore`, don't change what it reports.

## Don't make it a required check

> [!WARNING]
>
> Don't add `Peeps / static analysis` to your required checks.

The check reads `success` or `neutral`, never `failure`, so requiring it protects nothing. In a merge queue it also stops merges: a required check waits on the queue's commit, and this check never runs on that commit.

It reads `success` only when every metric that's on analysed every file it should and nothing crossed a limit. Anything else reads `neutral`, including:

* A function that's new over a limit, crossed one, or has no earlier number to compare
* Any file that wasn't analysed
* Another open pull request on the same commit, which the summary names as not judged here

If the check can't finish, it reads **Couldn't analyse**, also `neutral`. The next push runs it again.

## What it analyses

It runs on every pull request's latest commit, including drafts and pull requests from bots and forks. Code review skips some of these, so you can see this check on a pull request with no review. It runs again when a pull request's base branch changes.

| Files | What happens |
| - | - |
| `.ts`, `.tsx`, `.js`, `.jsx`, `.mjs`, `.cjs`, `.mts`, `.cts` | Analysed |
| Data, docs, styles and lock files, such as `.json`, `.md`, `.yml`, `.sql` and `.css` | Left out |
| Generated or vendored files, such as `dist/`, `Pods/` and `.min.js` | Skipped and named in the summary |
| Any other language, such as Python, Swift or Kotlin | Named as not analysed |

The summary reads **3 Swift files not analysed**, or lists a file with its reason:

| Reason | Means |
| - | - |
| **couldn't be parsed** | The file has a syntax error the tool can't read past. |
| **over 1 MB** | The file is too large. |
| **not valid UTF-8** | The file isn't text the tools can read. |
| **Flow isn't supported** | The file is marked `@flow` and uses syntax the tools can't read. |
| **the tool failed on it** | The tool crashed or ran out of time, for example on very deep nesting. |
| **couldn't be read** | Peeps couldn't fetch it, as can happen on a fork. |

A pull request with more than 100 changed files has the rest counted and not read.

## In the code review

When code review is also on for the repository, the review's main comment shows the functions that matter in a folded **Complexity** section:

* **Over the limit**, in red: a function this pull request made new over a limit, pushed over, or made worse while over. One it lowered but is still over shows too, as progress.
* **Brought back under**, in green: a function that was over a limit and this pull request brought under it.

Other changed functions, such as small changes under the limit, aren't shown in the comment. The check's page still lists every one.

* **The heading** counts them: `Complexity · 1 over the limit · 1 brought under`.
* **A table** of the worst ten, each row linked to its function's line on the pull request's **Files changed** tab, with each metric's earlier score and its new one. `new → 16` marks a new function, and `now 21` a function with no earlier score. A function with no name reads `Function at line 4`.
* **A last row** that links to the check's summary and counts what the table doesn't show, such as `3 more · All results in Peeps / static analysis`.

The section is left out when no function is over a limit or brought back under. The review's own text gives no numbers. It may say which lines drove one, which is its reading, not a measurement.

### What the review does with them

In the **Static code analysis** section, **Complexity findings** sets what the review does when this pull request makes a function cross a limit:

| Option | What the review does |
| - | - |
| **Comment** (default) | Shows the functions as above. The review's verdict doesn't change. |
| **Request changes** | Requests changes when a function this pull request changed is new over a limit or crossed one. Up to five of them come first under **Issues**, marked **Blocking**, with a last row that links to the check, such as `2 more in Peeps / static analysis`. The other changed functions stay in the folded section, as **Other complexity changes**. This applies even when **Request changes** under **Verdict** is off. |

With **Request changes**, a function that was already over its limit and got worse, or has no earlier number to compare, is still shown but doesn't block. The code review check reads `neutral` and names the issues. If **Fail the check** is set to **Also on changes requested**, it fails.

To leave complexity out of the review, turn the **Complexity check** off. The row is unavailable while the check or both metrics are off.

If the check hasn't finished when the review posts, the functions are left out. With **Request changes**, the review then neither requests changes nor approves, and says the complexity check hadn't finished. The review is headed **Complexity not judged** when it found nothing else, and the code review check's title ends with "complexity check hadn't finished". The code review check fails, as for any review that couldn't finish, unless **Fail the check** is **Never**. The next push gets it. **Retry** or `/peeps review` before the check finishes settles the check again and spends no review.

While complexity isn't judged, the review lifts an earlier Peeps review that requested changes only for findings. One that requested changes for complexity stays until a review that judged complexity replaces it.

With **Request changes**, a push the review would otherwise skip, such as one that changes only ignored files, waits up to 5 minutes for the check. If a function crossed a limit, the review runs in full.

A pull request whose changed files are all in **Ignore paths**, generated or likely secrets gets a short **Nothing to review** review, which doesn't count toward your daily reviews. With **Request changes**, it waits up to 5 minutes for the check, and still requests changes if a function in those files crossed a limit.

On a pull request Peeps opened itself, the review comments instead of requesting changes, since GitHub doesn't let it block its own pull request.

The review follows its own [trigger](https://docs.peepsai.com/code-review/settings.md#when-to-review), so a review set to **When a PR opens** won't explain later pushes. The check still runs on them.

***

Questions about the complexity check? [Get in touch](mailto:support@peepsai.com).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.