# Perch: Semantic Code Linting with Jev

> Source: <https://github.com/lakeday-org/perch>
> Published: 2026-09-25 04:29:44+00:00

Semantic code linting with Jev.

Create an API key at [console.typesafe.ai](https://console.typesafe.ai) and set
it as `PERCH_API_KEY`.

```
npm install -g @lakeday/perch
export PERCH_API_KEY=<your TypeSafe API key>
bash
$ perch scan
checkout.py
  ID        Line  Severity  Type    Confidence  Problem                     Method
  bdc67421    14  P1 (0.8)  defect         81%  wrong_order                 place_order
  ddc5c917    24  P1 (0.8)  defect         92%  inverted_condition          can_fulfil

cart.py
  ID        Line  Severity  Type    Confidence  Problem             Method
  287bfb9d     9  P1 (1.0)  defect         90%  off_by_one          subtotal
  80d6ebbb    29  P1 (1.4)  defect         89%  unhandled_null      cheapest

✖ 20 problems in 5 files, all failing
```

`perch issues` lists them worst first. `perch issues <id>` opens one up. `perch check <id>` asks again after a fix, and records what it finds nowhere.

```
perch setup claude-code   # .claude/skills/perch/SKILL.md
perch setup codex         # .codex/skills/perch/SKILL.md
perch setup pi            # .pi/skills/perch/SKILL.md
perch setup cursor        # .cursor/rules/perch.mdc
```

Extend perch with custom rules, in `perch.yaml`:

```
- name: env-read-once
  where: "src/**/*.js"
  each: method
  min: 70
  ensure: >
    This method takes its configuration as arguments. Reading process.env is the
    command line's job.
```

| [Getting started](https://docs.perchscan.com/install/) | Install, the key, the first scan. | 
| [Reading issues](https://docs.perchscan.com/issues/) | The list, the filters, closing what does not matter. | 
| [Semantic linting](https://docs.perchscan.com/rules/) | `where` ,`each` ,`sees` ,`min` ,`gate` , and the longhand grammar. | 
| [Checking a change](https://docs.perchscan.com/check/) | `perch check` on work in progress. | 
| [perch in CI](https://docs.perchscan.com/ci/) | What a build can gate on, and what it cannot. | 
| [Command reference](https://docs.perchscan.com/cli/) | Every command, its flags, and what each exit code means. | 
| [Inside a scan](https://docs.perchscan.com/scan/) | The graph walk, the questions, and how probabilities turn into a ranking. | 

| Location | Contents | 
|---|---|
| `.perch/` | Generated scan results and cache files, alongside the committed files below. Use `--out <directory>` to choose another results location. | 
| `.perch/rules/` | Custom rules split across `.yaml` and`.yml` files. Commit these files. | 
| `.perch/closed.jsonl` | Dismissed findings and their reasons. Commit this file. | 
| `perch.yaml` | Custom rules. Updated by `perch rules add` ,`edit` , and`remove` . | 
| `.claude/` ,`.codex/` ,`.pi/` ,`.cursor/` | Instructions installed for the selected assistant by `perch setup <assistant>` . | 

```
npm run check     # lint, typecheck, test
npm run build     # bundle src/cli.js into dist/cli.mjs
```

From a checkout: `npm install && npm run build && npm link` puts `perch` on the
path.
