Prompt cache warmth: show whether the next prompt is cheap #147
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/cache-warmth"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A session left idle goes cold silently, and the next prompt rewrites the whole conversation prefix instead of reading it — roughly 20× the input cost, visible only as the 5h quota window moving. Nothing in Nexus distinguished the two.
What it does
Each session row gains a cache mark beside its cost and context:
Same three states in the terminal statusline, and on the rail hover card and session settings panel.
How
claude-code 2.1.269 already computes this —
prompt_cache.expires_atarrives on the statusline payload Nexus already parses for quota. This forwards that one integer through the existing pipe; everything else is derivation.The measurement that shaped the design
claude-code renders the statusline on state change, not on a timer — four renders in sixty seconds of a live session. So the session that is going cold is precisely the one emitting nothing, and coldness can never be reported. Both surfaces derive it from the absolute
expires_at, which is what keeps a reading correct through any amount of silence.statusLine.refreshInterval: 60is seeded so the terminal line redraws; the browser needs nothing, it re-derives on the existing 10s poll.Also verified against the binary rather than the docs:
expires_atmoved +41s across two turns. Cross-checked on six transcripts: a 3705s gap missed, 2956s hit, boundary at 3600s.prompt_cacheis an absent key until the first API response — the same unknown-vs-zero trap asrate_limits.recache_tokens_if_coldequalscontext_window.total_input_tokens(delta 0, three captures), so cold prints no token count — it would restate thectxalready on the row.last_miss_causedoes not work as shipped. Rewriting a projectCLAUDE.mdmid-session caused no miss at all, and a forced miss (model switch) left itnull. Recorded in AGENTS.md so nobody builds on it.Cold is violet, not red
--cold: #af87ff. Cold is the resting state — every session idle an hour is cold — so red lit the entire sidebar overnight, collided withunhealthyReasonin the same block, and sat beside the--runninggreen dot on every row, the worst pairing for deuteranopia on an otherwise colour-only signal.#af87ffis xterm-256 index 141, so the terminal renders the identical colour rather than an approximation; it can't draw the zap icons, so colour is the only identity the two surfaces share.Also in here
The statusline got 6.4× faster (276ms → 43ms per render), because
refreshIntervalmultiplies its cost. Eightjqspawns became one@shpass emitting named shell assignments — byte-identical output across five payloads including empty stdin and invalid JSON, and injection-safe (tested with acwdcontaining a quote, a semicolon and a command).Testing
157 files / 1689 tests, plus 42 shell cases. The derivation exists twice (TS + POSIX sh, neither can import the other), so
cache-warmth-parity.test.tsruns the real script and compares its segment tocacheLabel()— the same knowing-duplication rule asmount-parityandtoken-scope-parity.Every new guard was mutation-tested, and four were found incapable of failing and fixed:
-levs-ltcache_expires_atat the endpointnullleft 37/37 greenThe four render surfaces were verified in a real browser with computed colours, not just typechecked — this repo's vitest runs in
nodewith no DOM, so components are structurally untestable.Note for deploying
seedStatusLineOnBootis one-shot and this instance'sstatusline_seededflag is already set, sorefreshInterval: 60must be added by hand tostatusLinein the Config Explorer. Without it the web UI is fully correct and the terminal countdown freezes. Legacy-support machinery was deliberately not built for this.View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.Merge
Merge the changes and update on Forgejo.