What changed in clines 4.x
3.x measured a repository. 4.x tries to measure the right things, and two of the changes are breaking. The short version: clines stopped counting everything by default, stopped treating a context window as the unit of cost, and started checking whether comments are telling the truth.
4.0.0 — source by default
Every file is now classified as source, test,
generated, vendored or docs, using
.gitattributes linguist-* markers,
@generated headers and path conventions, with
clines.json overrides on top. Headline figures cover source only; everything
else is named beneath the report.
This was worth breaking compatibility for. On facebook/react, tests, fixtures
and generated files accounted for 59% of the estimated token cost and 72% of
all duplicated lines — so the previous headline of "43.5% duplicated" was mostly
__tests__. It is now 28.4%.
| react | 3.11 | 4.x | 4.x --all |
|---|---|---|---|
ctx tokens |
8,776,571 | 3,303,084 | 8,776,571 |
dup |
43.5% | 28.4% | 43.5% |
count files |
6,915 | 2,022 | 6,915 |
--all reproduces the old numbers exactly on every command, which is how the
change was verified. count also gained a per-role breakdown and a
test-to-source ratio — react runs at 1.32:1 by code lines.
4.1.0 — working set, not window
Reporting "2217% of a 200,000-token window" implies that fitting a repository into context is the goal. It isn't. Accuracy degrades well before a window fills, and agents read files one at a time, so the useful question is which files are too expensive to read at all.
Working set (50,000 tokens)
15 files exceed 50% of it on a single read (> 25,000 tokens)
32 files exceed 25% of it on a single read (> 12,500 tokens)
140 files exceed 10% of it on a single read (> 5,000 tokens)
react's median file is 411 tokens. Fifteen files each consume half a working set on one read. That distribution was invisible in the old percentage.
The same release added navigability — how many files share a basename, and how deep the
tree goes. react has 553 of 2,022 files (27%) sharing a name with another file, including
index.js 89 times. Agents mislocalize on name similarity, so an instruction
mentioning "the server index" has 89 candidates.
4.2.0 and 4.3.0 — comment drift
Language models treat comments as authoritative and do not separate them from the code, so
a comment that has stopped being true is worse than no comment at all.
clines comments uses git blame to compare, per comment block,
when the comment was last touched against when the code beneath it was.
Comment drift: 13% of comment blocks describe code that changed later
1,027 of 8,066 blocks across 50 files · 3-year threshold
The threshold matters. Flagging any block whose code is merely newer catches 52–68% of them, which is noise — a comment describing unchanged intent legitimately outlives edits below it. At a three-year gap the figure settles at 7–23% per file, which is a usable suspicion signal rather than a verdict.
It shipped in 4.2.0 as ctx --comments and moved to its own command in 4.3.0,
the second breaking change. git blame is slow enough — around eight seconds
on react — that it did not belong on a command people run constantly.
Upgrading from 3.x
-
Numbers will drop, because tests, fixtures and generated files no longer count. Add
--allto reproduce 3.x output. -
If a directory is misclassified, override it in
clines.jsonunderroles. ctx --commentsis gone; useclines comments.-
clines.jsonis otherwise unchanged, and--readmestill writes into the same markers.