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:
-
docs/agent-usage.md— pre-edit / post-edit workflow, what's shipped vs deferred, exit-code behaviour -
docs/json-schema.md— every field of the wire format, what's required, what's reserved -
docs/fixtures/messy-ts-app.json— the full pinned sample output, version-controlled
What it finds today
-
God Function — functions past a body-line threshold
(default 60). Escalates to
highat 2× threshold. - God File — files past a line threshold (default 300). Same severity ramp.
-
Unfinished Business — files dense with
TODO/FIXME/XXX/HACKmarkers, with line ranges for each cluster. -
Temporal Recklessness — direct
Date.now()/new Date()calls in source files, with per-call line numbers.
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.