[FEATURE] Desktop app: surface prompt-cache warmth and a TTL countdown — the data is already computed, no client renders it
Preflight Checklist
- [x] I have searched existing requests. The closest matches are linked under Alternative Solutions; none cover the desktop app.
- [x] This is a single feature request.
Problem Statement
The desktop app's Code tab surfaces no prompt-cache state at all, even though the bundled CLI already computes it for every session. There is no way, from inside the desktop app, to tell whether this conversation is warm or how long it has left — so there is no way to decide whether to send one more message now or let the session go cold.
The data exists. The bundled CLI computes a prompt_cache object per session (warm, ttl, expires_at, recache_tokens_if_cold, hit_ratio, misses, last_miss_cause) and two other surfaces render it:
| Surface | Cache warmth | Countdown | Re-cache estimate |
|---|---|---|---|
| Terminal CLI — /usage Prompt cache (main) line (v2.1.251+) | yes | no (shows "last activity 40s ago") | yes, on misses |
| Terminal CLI — statusLine prompt_cache object | yes | yes (expires_at) | yes (recache_tokens_if_cold) |
| VS Code extension — idle warning on resume (per #94456) | yes | no | yes ("will re-cache about 594k tokens") |
| Desktop app (Code tab) | no | no | no |
Three things close off in the desktop app specifically:
- The usage ring carries context and plan usage only. It is the natural home for this and shows nothing about the cache.
statusLineis silently inert in the desktop app, so the documented extension point cannot be used as a workaround. Independently verified in #88598 (a script instrumented to append a timestamp on every run logged zero lines in two minutes, in both an existing session and one started after the settings were written).- The
get_usageMCP tool exposes no cache fields, so the agent cannot see its own cache state either. Called in a desktop session on 2.1.275 just now, thecontextblock returns:
"context": {
"session": "self", "status": "ok",
"tokensUsed": 192431, "contextWindow": 1000000,
"percentUsed": 19, "autoCompactsAtPercent": 97,
"categories": [ { "name": "Messages", "tokens": 124270, "percent": 12 }, ... ]
}
No warm, no expires_at, no recache_tokens_if_cold. An agent told "finish this session warm" has no field to act on.
Why this matters more since Fable 5.1. Cache reads on Fable 5.1 and Mythos 5.1 are priced at 0.025x base input rather than the standard 0.1x (pricing). The read got four times cheaper; the relative cost of letting a cache lapse got four times worse:
| Model | 1h cache write | Cache read | One lapsed TTL costs |
|---|---|---|---|
| Fable 5.1 / Mythos 5.1 | $20 / MTok | $0.25 / MTok | 80 warm turns |
| Fable 5 / Mythos 5 | $20 / MTok | $1.00 / MTok | 20 warm turns |
| Opus 5 / 4.8 / 4.7 | $10 / MTok | $0.50 / MTok | 20 warm turns |
On a 500k-token desktop session on Fable 5.1, one TTL lapse rewrites $10 of context — eighty turns' worth of warm reads — and nothing in the window gives any warning before or after it happens. On a subscription the TTL is an hour, which is precisely long enough that you stop tracking it by hand.
Proposed Solution
Any one of these solves it; listed in order of preference.
- Put the cache state on the usage ring. It already opens to show context and plan usage; add a cache row —
warm · 41m left (1h TTL)/cold · next message re-caches 594k. A colour on the ring itself (or a small dot beside it) when the cache is inside its last few minutes would make it glanceable without a click. The refresh trigger already exists in the CLI: the status line re-runs when a warm cache reaches itsexpires_at, so the desktop renderer can hook the same event rather than poll.
- Add the
prompt_cachefields toget_usage'scontextblock. Cheapest of the three and the only one that helps the agent. Withwarm,ttl,expires_atandrecache_tokens_if_coldavailable, a session can pace itself against the TTL — batch its remaining tool calls, or say "we have 6 minutes of warm cache, want me to wrap up?" — which is impossible today at any prompt.
- Honor
statusLinein the desktop app, or document that it is TUI-only. This is #88598's third option, and it would let users build the display themselves. Today it fails silently: valid config, executable script, no output, no warning, no log.
Alternative Solutions
Tried and rejected:
- A
statusLinescript readingprompt_cache.expires_at— works in the terminal CLI, inert in the desktop app (#88598). This is the workaround the documentation implies exists and it does not apply here. /usagein the desktop app — the Code tab documents that terminal-dialog commands behave differently, and there is no equivalent panel carrying thePrompt cache (main)line.- Watching the wall clock by hand — what the 1-hour subscription TTL makes unreliable: an hour is long enough to lose track of, and the cost of being wrong is a silent full-context rewrite.
Related issues, none of which cover the desktop case:
- #94456 — the cold-cache warning appears in the VS Code extension on
--resumebut not the terminal CLI. Same underlying data, two other surfaces; the desktop app has it on neither resume nor live. - #88598 —
statusLineandfooterLinksRegexesare silently inert in the desktop app. That request wants a GitHub-issue footer chip; this one wants cache state, and its option 3 would serve both. - #52665 — "surface prompt cache expiry status in CLI status bar" (Apr 2026), closed
not plannedby the stale bot and locked. Its request was for the TUI, and the underlying data shipped afterwards. - #66115 — auto-compact on idle timeout to prevent cache expiry cost. An automatic mitigation rather than a display; a countdown lets the user decide instead.
Priority
Medium - Would be very helpful
Feature Category
Configuration and settings
Use Case Example
Long desktop sessions on Fable 5.1, several open across git worktrees, one per ticket.
The decision I want to make, several times a day: I am about to step away. Is this session warm, and for how long? If it has forty minutes left, I leave it. If it has four, I either finish the thought now or accept that the next message pays a full re-cache. On Fable 5.1 that re-cache is eighty times a warm read, so the answer changes what I do — and the desktop window gives me nothing to answer it with.
The same decision at the end of a session: "finish warm" is only actionable if something tells me where the boundary is.
Additional Context
- Desktop app bundled CLI: 2.1.275 (Windows 11). Standalone CLI on the same machine: 2.1.273.
- Plan: Max (1-hour cache TTL; per the costs documentation this drops to five minutes once drawing on usage credits, which is a second reason to surface the TTL in effect rather than assume it).
- The
prompt_cachefields and theexpires_atrefresh trigger are documented under status line — prompt cache fields; thePrompt cache (main)line is documented under costs — prompt cache statistics. Both are terminal-CLI surfaces. - Since the counts are derived from the cache token fields in API responses, they work on every provider and gateway — so a desktop renderer for them has no provider-specific dependency.