Per-chat context-window monitoring + four on-device view modes - #129
Per-chat context-window monitoring + four on-device view modes#129grabbly wants to merge 4 commits into
Conversation
- read_token_for: a credentials file that yields no usable token (e.g. one
holding only mcpOAuth entries) no longer shadows the macOS Keychain
fallback; the regex miner only runs on non-JSON blobs so it can't grab
an unrelated MCP server's token.
- Scan <config_dir>/projects/*/*.jsonl transcript tails for each chat's
context-window fill (last main-chain assistant usage) and ship it as
"cc":[{n,p,k,l,a}] in the BLE payload; cc-only updates push every TICK
when content changes, between the 60s API polls.
- Chats count as active for 15 min after their last token movement; the
most recently active chat is always reported. Window size is fixed at
CONTEXT_WINDOW_TOKENS (1M) — transcripts carry no window-size info.
- Payloads trim trailing cc entries to fit the negotiated BLE MTU so
writes never fail on firmware with the default 255-byte MTU.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…TU 517 - Four cycling view modes replace the single usage screen: Focus (slim 5h/7d rows + big current-chat context card with background-chat leak dots), Chats (all active chats on one screen with age lines), Classic (the original panels + a bottom context strip), Rings (concentric ctx/5h/7d watch face). Splash is boot-only and auto-exits on first data. - Navigation: tap = next mode; top buttons = prev/next (HID keystrokes removed — the HID service itself stays for pairing compatibility). The active mode persists in NVS. Swipe navigation removed. - Screensaver driven by token movement instead of touch: no change in session/weekly/context numbers for 10 min turns the panel off (USB included); it wakes on new tokens, tap, or any button. - parse_json reads per-chat "a" (minutes since last activity); ChatCtx gains age_min. - NimBLE negotiates MTU 517 so full 4-chat payloads fit a single write-without-response. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
CONTEXT_WINDOW_TOKENS was a hardcoded 1M constant that only fit the original author's all-1M-window setup; upstream users on standard 200k windows would have every chat mis-reported as 1M. Default (upstream, context_window_k unset): per-chat heuristic, since transcripts don't record the actual window size. Assume 1M if the assistant message's "model" string carries a "[1m]" marker, else 200k; if usage ever exceeds that guess, snap the assumed limit up to 1M (and beyond, to the next 1M multiple) so the gauge keeps tracking progress instead of pegging at 100% on a wrong guess. Override (context_window_k = N in the config file, thousands of tokens): every chat's limit is N * 1000, no guessing or snap-up — a user-declared window is taken as fact. E.g. context_window_k = 1000 reproduces the old hardcoded 1M-everywhere behavior. Added read_config_value(key) as a shared single-key reader for the config file (key = value, # comments), and refactored read_config_dirs, read_chime_setting, and read_clock_setting to use it instead of each duplicating the same parsing loop. context_window_k is re-read once per scan_chat_contexts() call so it takes effect without a daemon restart; the per-file context cache now keys on (mtime, context_window_k) so a config change invalidates cached entries for unchanged transcripts too. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
"Token-activity screensaver" already an existing functionality which turns the screen off after 30m The changes in the controls are not ideal. Suggest you use the touch screen tap to cycle between screens instead, or a swipe gesture or something other than taking over the useful physical button controls for something cosmetic like the screen selection. Please keep any bugfix in a separate PR Don't worry about backwards compatibility, there is no auto update for the daemon we assume everyone using the platform has the latest firmware and daemon for the time being at least. |
|
I appreciate the UX concepts but I'd like to challenge you to think of the context for each of them and if we can make the experience more seamless for users For example you have a multi chat UX, we know how many chats a user has active so perhaps we don't need to show that screen unless we see more than one chat that is active, defined by some 30m window perhaps The idea to show more info on the current session is something I like but it needs to be limited to one screen or possibly two screens if we want to show the state of multiple chats. Idk how old your fork is btw but the latest firmware also shows the current time instead of "Clawdmeter". I'd like to avoid displaying "Clawdmeter" anywhere in the UX since it just detracts from the experience of using it in my opinion and doesn't add value. Try ditching the concentric rings screen, focus on the single/multi chat view where we show the current session limits and the chat contexts and auto switch between the single and multi view depending on how many chats are active. Scenario idea Normally with pull requests this large it's hard to see the value in them since they contain so many things but I appreciated your UX concepts a lot and I think this is close to being workable as a new feature. Thanks for opening the PR! |
|
Closing in favor of #136 which consolidates this and a couple of other pull requests and feature requests I've gotten on this topic. Would appreciate any help on testing that one since it's a large change so any help validating it would be appreciated. |
The 5h/7d strip uses #129's measured layout — styrene_24 percentages in fixed right-aligned columns, styrene_20 dim tags, a 30px vertically centered band — and its vertical rhythm: list top at 148, 10px card gaps (90px pitch, keeping the mid-card clip affordance). Card internals unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This PR adds live context-window monitoring of your local Claude Code chats to Clawdmeter, plus a set of new on-device view modes to show it. Everything is verified on real hardware (AMOLED-2.16) and all six build envs compile.
What it does
The daemon scans
<config_dir>/projects/*/*.jsonltranscript tails and computes each chat's context fill from the last main-chain assistant message's usage (input + cache_read + cache_creation). Chats stay listed while active in the last 15 minutes; the most recent chat is always kept. The payload gains"cc":[{n,p,k,l,a}, …](project name, percent, tokens-used in k, window size in k, minutes since last activity), pushed within ~5 s of any change — much faster than the 60 s API poll, so the gauge moves while you work.Four view modes (tap or top buttons to cycle, choice persists in NVS)
Also in here
NimBLEDevice::setMTU) so the larger payload fits one write-without-response; the daemon also trims trailingccentries to the negotiated MTU, so it stays compatible with older firmware (which simply ignores"cc"). Compatibility holds both ways: new firmware with an old daemon just shows the empty context states.~/.claude/.credentials.jsonthat contains onlymcpOAuthentries (no Claude OAuth token) no longer shadows the Keychain fallback, and the regex miner can no longer pick up an unrelated MCP server's token. This bit me on a fresh machine; happy to split it into its own PR if you prefer.[1m]marker → 1M, snap up when usage exceeds the guess). Users whose plan runs a known window on every chat can pin it in the config:context_window_k = 1000.Breaking changes to discuss
I made two opinionated choices that change existing behavior — flagging them explicitly so you can push back:
Testing
screenshotserial command (the PNGs above are actual device captures); empty states, enterprise variants, and the pair/idle overlays covered; all six PlatformIO envs build clean.🤖 Generated with Claude Code