clines — measure your codebase from the terminal

A CLI that counts code, comments and blanks per language, finds duplicate code, ranks files by complexity, estimates token cost, finds comments the code has moved away from and files that keep changing together, and decides what is worth refactoring — and what is safe to hand to an AI agent.

$ npm install --save-dev clines
clines count ~/repos/react
Language      Files      Lines     Code  Comments    Blank       %
──────────────────────────────────────────────────────────────────
JavaScript    3,954    673,654  546,899    62,317   64,438   66.4%
Markdown      1,998    157,717  130,135         0   27,582   15.8%
TypeScript      419     81,509   65,140    11,248    5,121    7.9%
Rust            120     76,448   64,936     6,531    4,981    7.9%
CSS             111      5,284    4,525        72      687    0.5%
TSX             122      4,484    3,417       635      432    0.4%

──────────────────────────────────────────────────────────────────
Total         6,913  1,008,315  823,120    81,280  103,915  100.0%

Project size: Solar System ☀️

Features

What clines measures, and what it skips.

🚀

Optional config

No config file is required, and none is ever written to the repo. A clines.json can override the defaults if you need it.

🏷️

Source by default

Files are classified as source, test, generated, vendored or docs — using .gitattributes, @generated headers and path conventions. Headline figures cover source only; --all includes everything.

🙈

.gitignore aware

Respects .gitignore. Lockfiles, source maps and build output are skipped by default. A shallow clone is detected and reported rather than quietly skewing the git-based analyses.

📊

Per-language table

Code, comments and blanks per language. Counts agree with cloc to within 0.12% on react and 0.02% on flask, docstrings included.

🌌

Size label

A label from Meteoroid to Universe, derived from the total lines of code.

📝

README integration

--readme writes the metrics table into README.md, between marker comments.

👯

Duplicate detection

clines dup reports duplicated blocks and a duplication percentage. --html writes a report with each snippet and every location.

🔥

Complexity ranking

clines cx ranks files by decision-point count, in the terminal or as an --html report.

🤖

Token cost

clines ctx estimates the token cost of the tree, compares it against a context window, and exits 2 above a --max budget.

🕰️

Comment drift

clines comments uses git blame to find comment blocks the code has moved away from. Models treat comments as fact, so a stale one is worse than none.

⚖️

Refactor verdict

clines refactor joins complexity to how often each file changes in git, and ranks by tokens × changes — what re-reading it keeps costing. Bot commits are excluded, renames are followed, and recent changes weigh more than old ones.

🔗

Change coupling

clines coupling mines git history for files that keep changing together — the logical dependencies static analysis cannot see. It explains why a hotspot is expensive rather than merely busy.

🛡️

Agent risk

clines agent rates each file safe, review or human for an AI coding agent to modify unattended, from density, size, duplication and how spread out the complexity is.

🧾

JSON on every command

--json writes one stable, deterministic document to stdout, under a versioned schema field. Progress goes to stderr, so clines ctx --json | jq just works.

🚦

CI gates

--max, --max-duplication, --max-density, --max-drift and --max-reread exit 2 on a breach — distinct from 1 for a real error, so a pipeline can tell them apart.

🔀

Pull-request scope

--diff main narrows any command to what a branch changed. dup still detects across the whole tree, then reports only the clone groups a changed file takes part in.

🔌

MCP server

clines mcp serves all eight analyses to a coding agent over the Model Context Protocol, with compact capped responses. Hand-rolled JSON-RPC, so it still adds no dependency.

🔎

Scroll long output

Output taller than the terminal opens in a built-in scroller — arrows or j/k, space to page, q or Esc to leave. --top all lists every file instead of truncating.

🎨

Readable in colour

Bold headings, dim table rules, and refactor verdicts by severity. Piped output stays plain, so redirecting to a file is unchanged.

100% tested

TypeScript, with 100% statement, branch, function and line coverage enforced in CI. Published with provenance over OIDC.

Usage

count is read-only by default and does not modify any file.

# count the current directory, print the table
$ npx clines count

# count a specific directory
$ npx clines count src

# also write the report into README.md
$ npx clines count --readme

# find duplicated code blocks in source files
$ npx clines dup

# ...including tests, fixtures and generated files
$ npx clines dup --all

# rank files by complexity, into an HTML report
$ npx clines cx --html cx-report.html

# estimate token cost against a 1M window
$ npx clines ctx --window 1m

# fail CI once the repo no longer fits a 200k window
$ npx clines ctx --max 200k

# find comments the code has drifted away from
$ npx clines comments

# decide which files are worth refactoring
$ npx clines refactor

# ...priced at $3 per million tokens
$ npx clines refactor --price 3

# list every file, scrolling instead of truncating
$ npx clines cx --top all

# machine-readable output, from any command
$ npx clines ctx --json | jq '.result.totalTokens'

# fail the build above 5% duplication (exit 2)
$ npx clines dup --max-duplication 5

# only the files this branch changed
$ npx clines ctx --diff main --max 50k

# find files that keep changing together
$ npx clines coupling

# what is safe to hand to a coding agent?
$ npx clines agent

# serve the analyses to a coding agent
$ npx clines mcp

# the bare command prints a banner + version
$ npx clines
Exit codes. A breached threshold exits 2; a real error — a bad flag, a missing directory — exits 1. A pipeline can therefore tell a finding from a failure. Every command accepts --json and --diff <ref>.
README markers. Place the clines · code metrics and clines · end marker comments anywhere in the README, and the section between them is updated in place. If the markers are absent, the report is appended to the end of the file.

Configuration

Optional. A clines.json layers additions and removals onto the defaults, for both directories and files.

{
  "ignore": {
    "dirs": ["fixtures", "vendor"],
    "files": ["CHANGELOG.md"],
    "extensions": [".snap"],
    "globs": ["**/*.min.js"]
  },
  "unignore": {
    "dirs": ["public"],
    "files": ["package.json"]
  },
  "respectGitignore": true
}

Project size scale

Thresholds are based on real codebases: react is a Solar System, Linux a Universe.

< 1,000 Meteoroid 🪨
1k – 10k Asteroid ☄️
10k – 50k Moon 🌑
50k – 100k Planet 🪐
100k – 500k Star ⭐
500k – 1M Solar System ☀️
1M – 5M Galaxy 🌌
5M+ Universe 🌠