The tokens are rising — get out fast before the stupidity zone locks you in.
An always-on gauge for your context window, built for the Claude Code CLI. It
lives in your status line and shows — every turn, without you asking — how full your
context is, so you can /clear at exactly the right moment.
Why "Clepsydre"? A clepsydra is a water clock. In Fort Boyard, it slowly fills the room until the door locks and you're trapped — "Sors ! Sors ! Sors !". Your context window works the same way: it fills with tokens, and if you don't step out in time (
/clear), you stay stuck in the context-rot room. Clepsydre is your "get out in time" signal.
In the Claude Code CLI, context engineering has a blind spot: the window fills up turn after turn, but nothing keeps it in view — and you can't steer what you can't see.
- Checking costs you. Hammering
/contextto find where you stand wastes time — and once MCP servers are loaded, each call carries a huge call stack. Clepsydre shows it for you, always. No call needed. - Overflow builds silently, on two fronts. Your context window fills with tokens
(🧠→
⚠️ →🤪) andMEMORY.md— reloaded in full every session — quietly bloats and rots your context (🧩→⚠️ →🧨). Clepsydre watches both, so you see it coming. - The right moment is narrow.
/cleartoo early and you throw away useful context; too late and you're already stupid. A live gauge lets you time it.
[Opus 4.8] 📁 my-project ⎇ main ↑2 ↓1 ±8 · 🧠 65.3k/230.0k (28%) · 🧩 MEMORY.md 4.2K · mem 18.0K/12f
- Model · folder · git branch
- Live token usage vs your working window, colored by the anti-context-rot threshold:
- 🧠 green — you're fine
⚠️ orange — ≥ 150k, ease off- 🤪 red — ≥ 200k, the stupidity zone,
/clearnow
- Memory weight — size of
MEMORY.md(reloaded in full every session) and the memory folder:- 🧩 green < 15K ·
⚠️ orange 15–25K · 🧨 red ≥ 25K
- 🧩 green < 15K ·
Plenty of headroom — 🧠 green, you're fine:
Deep in the stupidity zone — 🤪 bold red, /clear now:
Reading the example line above from left to right:
| Piece | Means |
|---|---|
[Opus 4.8] |
The model currently answering you. |
📁 my-project |
The folder (project) you're working in. |
⎇ main |
The current git branch (⎇ is the git branch symbol). Outside a repo, this whole part just disappears. |
↑2 ↓1 ±8 |
Git state — on by default, opt-out (see git counts). ↑2 = 2 local commits ahead of the remote (to push); ↓1 = 1 commit behind (to pull); ±8 = 8 files with uncommitted changes (your edits + brand-new files). Each shows only when it isn't zero — a clean, in-sync repo shows nothing here. |
· |
Just a separator between groups. |
🧠 65.3k/230.0k (28%) |
The one that matters most: how full the context window is. 65.3k tokens used out of a 230.0k working window = 28%. The icon is a traffic light: 🧠 green (fine) → /clear now). |
🧩 MEMORY.md 4.2K |
Size of your MEMORY.md file — it's reloaded in full every session, so it eats context; the icon warns as it grows (🧩 → |
mem 18.0K/12f |
The whole memory folder: 18.0K total across every memory file, 12f = 12 files. Reads on demand, so it doesn't cost context the way MEMORY.md does — this is just its footprint on disk. |
Context doesn't just fill — it degrades as it fills (context rot). As the context grows, the agent forgets, confuses, and hallucinates more. This is about size, not position: the old "info in the middle gets read worse" effect is outdated on frontier models — what stays measured today is degradation tied to context size.
Where the trouble starts (~150–200K). It's not exact science — it's model-dependent and opinions differ — but heavy users find that past ~150–200K tokens, coding quality starts to slip. Treat it as a prudent comfort zone, not a hard wall. (Chroma's Context Rot report puts clear degradation nearer ~300–400K on 1M models, so ~150–200K stays conservative for reliable coding.)
The 1M-window trap. Anthropic shipped 1M context to analyse big documents without auto-compacting from the start — not to code inside all of it. Because you can doesn't mean you should: stay under ~150–200K and flee the stupidity zone.
Auto-compaction is a guardrail — but left unguarded,
especially on 1M windows, it fires far too late, when you're already deep in the
stupidity zone. The summary that then seeds every later turn is written by "someone drunk,
tired, hallucinating," and your whole subsequent working context inherits that degraded
state — compounding harm. Clepsydre's value: see it coming and /clear at the right
time, before auto-compaction rescues you too late.
Keep memory lean — pointers, not copies. MEMORY.md is reloaded in full every
session. Forget to tell your harness to store pointers to the plan rather than the plan
itself, and it will re-paste the whole thing every time you ask "can I /clear?" —
bloating and rotting context. The 🧩→
More, in Thomas's own words (French): "Comment éviter de devenir zinzin (votre IA, et vous un peu aussi)" and "Des pointeurs, pas des copies, banane".
You're already in the Claude Code CLI, so let it install Clepsydre for you. Paste this to Claude:
Install Clepsydre on my machine by following its README
(https://github.com/tpierrain/clepsydre). First ask me which directory to clone it
into, suggesting my home directory (e.g. ~/clepsydre) as the default. Then, before
touching anything, explain what you're going to do and where — which files you'll
create or change — and wait for my go-ahead.
Claude asks where to clone it (your home directory, e.g. ~/clepsydre, is a safe
default), then walks you through the plan (clone the repo, then merge a statusLine entry
into ~/.claude/settings.json after backing it up). Once you approve, it runs the
installer and tells you to restart Claude Code.
Works the same on macOS, Linux and Windows — it's plain Node.js, and any machine that runs Claude Code already has Node.
Clone it wherever you like — pick a stable spot, since the status line runs from there. Your home directory is a safe default (avoid a folder you might move or wipe):
git clone https://github.com/tpierrain/clepsydre.git ~/clepsydre
cd ~/clepsydre
node install.mjs # or node install.mjs --check for a dry-runinstall.mjs is idempotent and touches only ~/.claude/settings.json. It points your
Claude Code statusLine at this repo's clepsydre.mjs (absolute path — no symlink, no
~ expansion, so it's Windows-safe), after making a timestamped .bak of your settings.
Your other settings are preserved.
Restart Claude Code to see it.
Your status line runs this repo's file directly, so git pull is all it takes to get
new versions — no re-install, on any OS. Pull, restart Claude Code, and you're on the latest.
| What you want | What to do |
|---|---|
| Get the latest Clepsydre (fixes, new segments) | git pull in the repo, then restart Claude Code |
| Tune your colors, thresholds or git counts | set the CLEPSYDRE_* env vars in your own settings.json — it takes effect on the next render, no pull needed (see Customize the color thresholds) |
| Moved the repo to another folder | git pull, then node install.mjs again (it rewrites the path Claude Code points at) |
The gauge's denominator is your working window — Clepsydre never picks it for you:
- if you've set
CLAUDE_CODE_AUTO_COMPACT_WINDOW, the gauge uses that value; - otherwise it falls back to the model's real window reported by Claude Code (e.g. 1M on Opus 4.8 1M);
- as a last resort (field absent), it floors at
200000.
So out of the box the gauge just tracks your real model window — no opinion imposed, and no change to when auto-compaction fires.
CLAUDE_CODE_AUTO_COMPACT_WINDOW is a real Claude Code setting: it controls when
auto-compaction triggers, not just what this gauge displays. Setting it is a deliberate
choice, so Clepsydre leaves it to you. Add it to your own ~/.claude/settings.json:
{
"env": {
"CLAUDE_CODE_AUTO_COMPACT_WINDOW": "230000"
}
}Rule of thumb (my own): for coding I don't go past ~230k tokens; quality is meant to hold up to roughly 300–400k. Pick what fits your context — Clepsydre will show it.
The tier colors flip at sensible defaults, but changing a threshold is configuration,
not code — so you set it in your own settings.json, never by editing clepsydre.mjs
(that file stays identical for everyone, so git pull keeps working). Four optional env
vars, each defaulting to today's behavior:
| Env var | Default | Tier it moves |
|---|---|---|
CLEPSYDRE_TOKEN_WARN |
150000 |
🧠 → |
CLEPSYDRE_TOKEN_CRAZY |
200000 |
|
CLEPSYDRE_MEM_WARN |
15360 |
🧩 → MEMORY.md, bytes) |
CLEPSYDRE_MEM_ROT |
25600 |
MEMORY.md, bytes) |
Where to set them:
- Everywhere on this machine → your global
~/.claude/settings.json. - For one project only → that project's
.claude/settings.json(Claude Code gives the project file precedence over the global one).
{
"env": {
"CLEPSYDRE_TOKEN_WARN": "180000",
"CLEPSYDRE_TOKEN_CRAZY": "250000"
}
}Set only the ones you care about; the rest keep their defaults. Anything empty,
non-numeric, or non-positive is ignored, and a pair whose WARN isn't below its
CRAZY/ROT quietly reverts to its defaults — a bad value can never break the gauge.
A compact git state suffix shows after the branch, out of the box:
[Opus 4.8] 📁 my-project ⎇ main ↑2 ↓1 ±8 · 🧠 65.3k/230.0k (28%) · …
- ↑2 commits ahead of upstream (to push) · ↓1 behind (to pull) · ±8 uncommitted changes (tracked edits + untracked files). Each part shows only when non-zero; a clean, in-sync repo adds nothing.
| Env var | Default | What it does |
|---|---|---|
CLEPSYDRE_GIT_COUNTS |
(on) | 0 (or false/no/off) hides the ↑↓± suffix and falls back to a cheap branch-only read |
To opt out — e.g. on a very large monorepo — set it in the same "env" block, globally
or per-project (see above):
{
"env": {
"CLEPSYDRE_GIT_COUNTS": "0"
}
}Why on by default, and when to opt out. The counts need git status, which scans the
whole working tree on every render. We benchmarked that scan: on a normal repo it's ~0 ms,
and even on the Linux kernel (~95k files) it stays around ~0.24 s warm — cheap enough that the
counts are worth having on by default (full numbers and rationale in
maintainers/docs/adr/0001-git-counts-default-on.md).
On a genuinely huge monorepo where that per-render cost bites, opt out with =0 and the branch
still shows via a cheap ref read. Either way it's robust: if git ever fails with the counts on,
the line falls back to the plain branch and the rest of the status line is never affected.
- Node.js — already present on any machine running Claude Code (that's what it runs
on). No
jq, nobc, no bash. gitis optional: the status line keeps working outside a repo — the branch segment just disappears.- macOS, Linux and Windows.
- Claude Code CLI only. Clepsydre plugs into the CLI's status line. The Claude Desktop app doesn't work like that — it has its own context-management mechanisms and no status line to hook into — so Clepsydre doesn't apply there (for now).


