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.
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 ☀️
What clines measures, and what it skips.
No config file is required, and none is ever written to the repo. A
clines.json can override the defaults if you need it.
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.
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.
Code, comments and blanks per language. Counts agree with cloc to within
0.12% on react and 0.02% on flask, docstrings included.
A label from Meteoroid to Universe, derived from the total lines of code.
--readme writes the metrics table into
README.md, between marker comments.
clines dup reports duplicated blocks and a duplication
percentage. --html writes a report with each snippet and every location.
clines cx ranks files by decision-point count, in the
terminal or as an --html report.
clines ctx estimates the token cost of the tree, compares it
against a context window, and exits 2 above a
--max budget.
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.
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.
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.
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 writes one stable, deterministic document to stdout,
under a versioned schema field. Progress goes to stderr, so
clines ctx --json | jq just works.
--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.
--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.
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.
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.
Bold headings, dim table rules, and refactor verdicts by severity. Piped output stays plain, so redirecting to a file is unchanged.
TypeScript, with 100% statement, branch, function and line coverage enforced in CI. Published with provenance over OIDC.
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
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>.
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.
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
}
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 🌠 |