crimes

A crime scene investigator for your codebase. Built for agents, readable by humans.

crimes is an open-source CLI that scans a repository for maintainability risks, duplicated business rules, and patterns that confuse AI coding agents — before humans or agents make risky changes.

Install

# Once crimes@0.0.1 ships to npm:
npx crimes scan

The v0.0.1 tarball is built and smoke-tested in CI — every commit packs the package, installs it into a clean temp directory, and runs --version, --help, scan, and scan --format json against the bundled fixture. The npm publish step itself is the only thing standing between the snippet above and a live install.

Until the package is on the registry, clone the repo and run pnpm install && pnpm build && pnpm scan:example from the repo root. Homebrew lands after npm.

Example output

Running crimes scan against the bundled messy-ts-app fixture (a deliberately crime-ridden TypeScript app):

CRIME SCENE REPORT
repo: messy-ts-app  ·  5 findings

HIGH severity (1)
  1. src/billing.ts:37-240 (generateInvoice)
     Charge: God Function
     Summary: generateInvoice spans 204 lines — past the 60-line
     threshold for a single function. Bodies this size usually mix
     unrelated responsibilities, and an agent editing one section
     often misses interactions in another.
     Evidence:
       · lines 37–240 (204 lines)
       · 3.4× the configured 60-line threshold
       · function declaration
     id=crime_00001  confidence=0.95

MEDIUM severity (3)
  1. src/billing.ts:44-260
     Charge: Temporal Recklessness
     Summary: 7 direct uses of Date.now()/new Date(). Reading the
     system clock in domain code makes behaviour non-deterministic
     and couples tests to wall time.
     ...

LOW severity (1)
  ...

Total 5  ·  high 1  medium 3  low 1

Every finding includes evidence (raw facts) and scores (severity, confidence, agent risk). No verdicts without receipts.

Agent-native JSON

Humans get the colourful report. Agents get a stable, versioned JSON contract — the same scan, structured for machines:

crimes scan ./src --format json
{
  "schema_version": "0.1.0",
  "repo": { "name": "messy-ts-app", "root": "/..." },
  "summary": { "total": 5, "high": 1, "medium": 3, "low": 1 },
  "findings": [
    {
      "id": "crime_00001",
      "type": "large_function",
      "charge": "God Function",
      "severity": "high",
      "confidence": 0.95,
      "file": "src/billing.ts",
      "symbol": "generateInvoice",
      "lines": [37, 240],
      "summary": "generateInvoice spans 204 lines — past the ...",
      "evidence": [
        "lines 37–240 (204 lines)",
        "3.4× the configured 60-line threshold",
        "function declaration"
      ],
      "scores": {
        "severity": 0.9,
        "confidence": 0.95,
        "agent_risk": 0.95
      }
    }
  ]
}

schema_version is bumped on breaking changes, so agents can pin against a known shape. JSON is the product contract; the human report is a renderer over it. Three docs back this up:

What it finds today

Coming next: duplication, circular dependencies, layer violations, git hotspots, and crimes context <file> for pre-edit briefings.

Open source, local, no cloud

crimes is MIT-licensed and runs entirely on your machine. No accounts, no telemetry, no SaaS dashboard. The wedge isn't "better linter" — it's local, open-source, agent-native codebase risk and context. Core detectors are deterministic; LLM-assisted features are optional and additive.

Detectors live in packages/core, language parsing in packages/language-js, reporters in packages/reporter. Adding a detector is a pull request, not a plugin marketplace.