Repository navigation
v0.5.0
context-guru: what is new since v0.4.2
This release makes the cache-aware summarizer the default way to shorten long sessions, keeps each agent thread's cache warm separately, and fixes several cost figures. It also starts recording why an agent waits, so a later release can tune the keep-alive from real data.
Items marked [Notice] change something you will see, or need an action from you.
New and changed
Presets now use the cache-aware summarizer (#402, #414, #456, #467)
- The cache-aware summarizer now works on Claude Code (Anthropic) traffic. When a session nears 90% of the context window, it summarizes the older part of the conversation. It reads that part from the provider's cache, so the summary call costs much less than a normal call.
- [Notice]
xhighandhighnow use the cache-aware summarizer. They use the summary on the next request. - [Notice]
mediumnow prepares a summary in the background, and uses it only when you come back after the cache has expired. Somediumcan now make summary calls. It needs keep-alive to be on. - [Notice] The older
summarizecomponent is no longer in any preset. You can still select it by name. - A summary that is cut off is rejected, and never stored.
- When a summary goes out of date, the old one is still used while a new one is made, so the prompt stays short.
Keep-alive works per agent thread (#426, #469)
- A Claude Code session has several threads: the main agent, each subagent, each teammate. Each thread has its own cache.
- Before, the keep-alive kept only one thread per session warm, usually the last subagent. The main thread's cache then expired while subagents were working.
- Now each thread gets its own keep-alive pings, and its own summarizer state. A thread keeps its identity across turns, across Claude Code's own compaction, and across
/resumeor a restart. - On our production data, this was the main reason idle gaps went without a ping: 74% of them.
New keep-alive defaults (#444)
- [Notice] When keep-alive is on, the defaults are now: a ping after 270 s idle (was 280 s), up to 2 pings per idle gap, only for prompts of 80,000 tokens or more (was 20,000), and at most $0.50 per ping (was $0.25).
- Keep-alive itself stays off by default.
A keep-alive ping can carry a summary (#402)
- When a summary is due, the summary call can take the place of one keep-alive ping. It keeps the cache warm too, so no separate ping is needed.
The dashboard records why an agent waits (#453, #447, #494)
- Each request now records what its thread was waiting for (its own tool call, a background task, a teammate, or you) and what ended the wait.
- The dashboard also records the time since the previous response ended, the cache lifetime the provider granted, and the order of keep-alive pings (#494). This is on by default; set
--dashboard-lifecycle-signals=falseto turn it off. - This is data collection only. It does not change the keep-alive. A later release will use it to choose how many pings each kind of wait gets.
Expanding content without a cache rewrite (opt-in) (#409)
- When the agent asks for a compacted tool output back, context-guru puts the full output back at its old place. That rewrites the cache after that point, which cost $0.62 in one measured case to restore 300 tokens.
- A new opt-in setting,
expand.fixed_restore, adds the full output as a new message instead, so the cache stays valid. It is off by default.
Dashboard: the bottom line first (#443, #477, #438)
- [Notice] The dashboard home is now 5 pages: Home, Savings, Cache, Tools & context, and Sessions. The previous dashboard stays at
/dashboard/index.html, for settings, requests and admin. - Every page starts with one number and one sentence, then at most 3 ranked recommendations, each with a command or link to copy.
- Savings that happened and estimates are shown separately, and never added together.
- The keep-alive simulator no longer treats a request the provider rejected as a cache event, so its estimates are closer to the real bill. They are still estimates, not exact figures.
Plugin: one prefix, new commands and a new status line (#403, #421, #442, #478)
-
[Notice, plugin update] Every command now starts with
/context-guru:. Each one answers one question:status: how am I doing, and what next?savings: how much did it save?cache: is my cache about to cost me?waste: what do I carry and never use?session: what happened in this session?doctor: is it set up right?
Each screen starts with the bottom line, and keeps the details behind
details. -
[Notice, plugin update] The 4
insights*commands still work for this release, but only to point you to their new names. -
New terminal views draw in your terminal:
watch(live caches),timeline,chart,heatmapandfill. -
[Notice, plugin update] The status line is redesigned. By default it has 2 lines (1 with
--layout=minimal): savings for the session, today and lifetime, then a cache bar that drains toward expiry and a context bar. It shows at most one hint, for example how much a pause would cost to rewrite. -
Saved and estimated amounts are always shown apart, and never added together.
-
It no longer shows
cg!when the proxy is only slow.cg!now means the proxy cannot be reached. -
The installer sets Claude Code to refresh the status line every 5 seconds. A value you set yourself is kept.
-
Codex gets the same commands as skills (
context-guru-status,-savings,-cache,-waste,-session).
Codex plugin (#397, #393, #394, #399)
- Reset and uninstall now remove the proxy binary that the plugin downloaded. They keep a proxy that you installed yourself.
- New
$context-guru-status --statsprints the raw stats, as in Claude Code.
Fixed
- The summarizers missed what you typed while a tool ran (#460). Text that Claude Code adds next to a tool result was left out of the summarizer's view: your mid-turn messages, notifications, and reminders. It is now included.
xhighnever made a summary (#431). Other components changed tool output before the request was sent, so the summarizer's safety check always failed. Fixed, also when Claude Code moves its cache marker each turn, and on the OpenAI Responses route.- Summary and sweep calls failed with extended thinking (#406). They returned an error on Claude Code requests that use extended thinking. Fixed. This also removes a 5-minute hang at the gateway.
- Summary and sweep calls failed on Sonnet 5 (#413) when Claude Code's request ended with a system reminder. Fixed, and the calls now read the full cache.
- [Notice] A keep-alive summary call was counted twice in the dashboard's cost and savings figures (#458). It is now counted once. Data recorded before this release still counts each such call twice.
- The status line stopped working in long sessions (#498, #509). Above about 1,000 requests in a session, its stats never loaded: it showed
cg: stats loading…forever, and the proxy used a lot of CPU trying. The status line now asks only for figures whose cost does not grow with the session's size. For a 5,800-request session they take about 140 ms (against over 2 minutes before), and today's total takes about 3 ms. - An expand could make the next request fail (#450). When the agent asked for a compacted output back while extended thinking was on, the next request got an HTTP 400 error. Claude Code then retried without thinking, and the retry wrote the cache again. In production this followed 18 of 65 expands. Fixed.
- [Notice] Keep-alive campaign windows ran 3 hours early (#432). Windows that a campaign generated were read in Israel time instead of UTC. Fixed. Campaign strategies created before this release must be generated or activated again after the upgrade. Strategies written by hand with their own time zone are not affected.
- [Notice] With debug logging on (
CG_LOG_LEVEL=debug), a failed sweep call is no longer retried at full price (#401). The provider's error is logged and recorded.
Known limits
- On Claude Haiku 4.5, and older Sonnet and Opus models with extended thinking, the cache-aware summarizer does not run, because it would rewrite the cache. The agent's own compaction still runs.
- A proxy restart loses summaries that were prepared but not used yet.
- The older
summarizecomponent, which you can still select by name, can store a cut-off summary as if it were complete (#418). The cache-aware summarizer that the presets use rejects such a summary. expand.fixed_restorewas tested live on Claude Haiku 4.5 only. Sonnet and Opus use the same gateway and message layout, but were not tested.- With
expand.fixed_restoreon, the dashboard's "saved" figure does not subtract the restored copy, so it reads a little high (#481). - In a custom pipeline where a component before the summarizer changes the number of messages, the summarizer skips that turn, including an existing summary (#462, low priority). The presets are not affected.
What we measured on production
On the 2 production hosts, from Sep 9 to Oct 11:
- About 2,170 idle gaps longer than 4.7 minutes. 83% of them ended in a cache miss.
- 2 keep-alive pings per thread would have saved about $446 over that time, out of $1,195 spent on those gaps.
- Most gaps without a ping were inside a keep-alive window, in sessions with subagents. Per-thread keep-alive (#426) fixes that.
Changelog
- a18722f: Merge origin/main into feat/thread-key-423 (@amiddavid)
- 875efdf: Merge pull request #393 from rossoctl/docs/codex-manual-updates (@amiddavid)
- 1f576c0: Merge pull request #394 from rossoctl/docs/subscription-sandbox-testing (@amiddavid)
- 7ffcf35: Merge pull request #397 from rossoctl/fix/codex-reset-and-raw-status (@amiddavid)
- 47eeae9: Merge pull request #399 from rossoctl/docs/codex-sparse-marketplace (@amiddavid)
- 3bf3f19: Merge pull request #401 from rossoctl/feat/sweep-debug-block-fallback (@amiddavid)
- 8db1275: Merge pull request #402 from rossoctl/feat/cache-aware-summarizer-trigger (@amiddavid)
- 43e61b5: Merge pull request #403 from rossoctl/feat/statusline-stats-timeout (@amiddavid)
- df37564: Merge pull request #406 from rossoctl/feat/prefixask-thinking-budget (@amiddavid)
- 231b049: Merge pull request #409 from rossoctl/feat/expand-fixed-restore (@amiddavid)
- 942f648: Merge pull request #413 from rossoctl/feat/prefixask-trailing-system (@amiddavid)
- bfdc2ba: Merge pull request #414 from rossoctl/feat/xhigh-cache-aware (@amiddavid)
- 3e3351e: Merge pull request #420 from rossoctl/docs/claude-md-layout-link (@amiddavid)
- 5986d89: Merge pull request #421 from rossoctl/feat/statusline-saved-text (@amiddavid)
- 099239b: Merge pull request #425 from rossoctl/feat/wait-cause-analysis (@amiddavid)
- addcd1e: Merge pull request #426 from rossoctl/feat/thread-key-423 (@amiddavid)
- 76f2cbc: Merge pull request #431 from rossoctl/feat/prefix-hash-followup (@amiddavid)
- f1c962d: Merge pull request #432 from rossoctl/fix/keepalive-campaign-timezone (@OsherElhadad)
- 8521bb1: Merge pull request #438 from rossoctl/fix/kvcache-sim-reconcile (@amiddavid)
- b33f2ce: Merge pull request #441 from rossoctl/feat/plugin-insights (@amiddavid)
- dfb9644: Merge pull request #442 from rossoctl/feat/statusline-redesign (@OsherElhadad)
- 653671e: Merge pull request #443 from rossoctl/feat/dashboard-bottom-line (@OsherElhadad)
- 2f6bd96: Merge pull request #444 from rossoctl/feat/keepalive-recommended-defaults (@OsherElhadad)
- 59777b3: Merge pull request #447 from rossoctl/feat/lifecycle-signals (@OsherElhadad)
- f4240ed: Merge pull request #450 from rossoctl/fix/expand-followup-400 (@OsherElhadad)
- 3ea2d7b: Merge pull request #453 from rossoctl/feat/wait-cause-record (@amiddavid)
- 74df042: Merge pull request #456 from rossoctl/feat/preset-ladder (@amiddavid)
- caf1926: Merge pull request #458 from rossoctl/feat/keepalive-summary-billed-once (@amiddavid)
- a7140ee: Merge pull request #459 from rossoctl/docs/eval-box-rules (@amiddavid)
- acbe5e1: Merge pull request #460 from rossoctl/fix/normalizer-siblings (@amiddavid)
- cf1483b: Merge pull request #463 from rossoctl/test/billed-marker-contract (@amiddavid)
- 32798fd: Merge pull request #464 from rossoctl/docs/eval-box-sync-clean (@amiddavid)
- 589829f: Merge pull request #467 from rossoctl/fix/cache-aware-stale-replay (@amiddavid)
- 6f6cc67: Merge pull request #469 from rossoctl/fix/thread-side-request-tail (@amiddavid)
- 9336b46: Merge pull request #477 from rossoctl/feat/dashboard-five-pages (@amiddavid)
- a9ee930: Merge pull request #478 from rossoctl/feat/plugin-v2 (@amiddavid)
- cff0e71: Merge pull request #487 from rossoctl/feat/cold-verdict-per-thread (@amiddavid)
- 11b2a06: Merge pull request #494 from rossoctl/feat/lifecycle-default-on (@amiddavid)
- 1ccad2f: Merge pull request #497 from rossoctl/feat/summarizer-per-thread (@amiddavid)
- 96ebf41: Merge pull request #498 from rossoctl/fix/lean-stats-session (@amiddavid)
- 2a7a86f: Merge pull request #509 from rossoctl/fix/lean-bounded (@amiddavid)
- b5e342b: docs(analysis): state the policy result and teammate-wait finding plainly (@amiddavid)
- f60c986: docs(claude): eval-box rules for waiting on long remote runs (@amiddavid)
- bc75265: docs(claude): sync to the eval box into an empty directory (@amiddavid)
- bca3208: docs(codex): clarify sparse marketplace upgrades (@amiddavid)
- 4c505b6: docs(codex): require periodic manual update checks (@amiddavid)
- 86e7a3d: docs(codex): use sparse marketplace checkout (@amiddavid)
- 4edd8ea: docs(dash): point the sessions how-to at the classic view; describe the new home ( <>)
- 4d29023: docs(keepalive): align example configs and comments with the new defaults ( <>)
- 8365907: docs(offload): write up any vs. pre_expiry for cache_aware_summarizer (@amiddavid)
- 8a1ecbd: docs(plugin): one word for plain facts (measured), Saved vs Estimated kept apart, colour claim fixed ( <>)
- 2905722: docs(plugin): plain wording for the context bar ( <>)
- d5125b3: docs(plugin): status line modes ( <>)
- 156dbf8: docs(plugin): status line modes match the labelled layouts ( <>)
- 880f123: docs(plugin): status line page matches the current sub-agent form, shed order and render cost ( <>)
- 2f4b916: docs(plugin): status line render time, heat and spark wording ( <>)
- 25cfee3: docs(plugin): status line skill shows saved money plainly ( <>)
- e9f27d1: docs(plugin): sub-agent line in the status line skill matches the render ( <>)
- cb498b5: docs(plugin): user guide for the commands and the status line, and a README section ( <>)
- 0be6fe2: docs(summarizer): record why the 0.9 trigger floor protects the warm splice (@amiddavid)
- 1b64f95: feat(analysis): add turn_gate.py's DB-only mode (@amiddavid)
- b66cfdd: feat(analysis): add turn_gate.py, ping cost and value by turn index (@amiddavid)
- c563b5f: feat(analysis): add wait-cause and ping-budget analysis script (@amiddavid)
- cda42e5: feat(analysis): add waiting_for to wait_causes.py (@amiddavid)
- 3bcc131: feat(analysis): learn a ping budget per tool, with a generic fallback (@amiddavid)
- 40328be: feat(components): put the parent thread on Ctx (@amiddavid)
- 637204a: feat(config): run cache_aware_summarizer in medium (pre_expiry) and high (any) (@amiddavid)
- 7836726: feat(config): switch the xhigh preset to cache_aware_summarizer (@amiddavid)
- 035608d: feat(dash): bottom line + ranked recommendations on every page, one net savings figure ( <>)
- db0cd5c: feat(dash): five-page dashboard (home, savings, cache, tools and context, sessions) ( <>)
- 331c6ab: feat(dash): record lifecycle signals by default (@amiddavid)
- d83bfcc: feat(dash): record the lifecycle signals main does not already hold ( <>)
- 73ef35a: feat(dash,proxy): record wait cause and wake cause per request (issue #424 record half) (@amiddavid)
- 5406add: feat(expand): restore expanded content at a fixed anchor (expand.fixed_restore) (@amiddavid)
- fc5524a: feat(keepalive): make the recommended policy the default (270 s, K=2, 80k floor, $0.50 ceiling) ( <>)
- b390522: feat(keepalive,dash): key cache attribution and keep-alive per thread (@amiddavid)
- 10932b6: feat(offload): give cache_aware_summarizer a real trigger and feed the keep-alive (@amiddavid)
- 84efcec: feat(offload): hold cache_state: pre_expiry checkpoints in reserve (@amiddavid)
- 90ceb27: feat(offload): run cache_aware_summarizer on Anthropic traffic via PrefixAsk (@amiddavid)
- 98359cd: feat(plugin): five cost commands with spend and last-used endpoints ( <>)
- 04bb185: feat(plugin): list the terminal views on the home screen and in the docs ( <>)
- cbaa404: feat(plugin): live cache clock, sub-agent clocks, model-switch warning ( <>)
- 11f465d: feat(plugin): one prefix, a two-line status line, and the new commands ( <>)
- cd5df33: feat(plugin): terminal views - watch, timeline, chart, heatmap, fill ( <>)
- da62833: feat(plugin): terminal views as status line layouts (spark, strip, heat, fill, watch) ( <>)
- 15bdedf: feat(proxy,offload): gate a pre_expiry refresh on expected saving vs. cost (@amiddavid)
- 35ebc68: feat(statusline): redesign with layouts, server cache state and cold-send hint ( <>)
- 727ba2a: feat(thread): tell a changed prefix from a cold start by shared mass (@amiddavid)
- 0040c91: fix(analysis): address PR #425 review (prices, wake causes, sim edge, DB match) (@amiddavid)
- 7badafe: fix(analysis): correct the cache-hit rule and split observed/simulated cost (@amiddavid)
- 8e2146a: fix(analysis): count real keep-alive ping rows directly (@amiddavid)
- 789924c: fix(analysis): fix 3 waiting_for leaks found in the context-guru cross-tab (@amiddavid)
- ac56294: fix(analysis): reconcile per-tool table, state the policy result plainly (@amiddavid)
- bfb9541: fix(apply): keep sibling text blocks beside a tool_result in the normalized view (@amiddavid)
- 41819fc: fix(apply): key the cached boundary and idle clock per thread (@amiddavid)
- 73d5177: fix(apply): set Ctx.RawInput on the Responses route too (@amiddavid)
- 36b85f0: fix(apply,modes): protect a new thread's shared prefix; drop keys safely (@amiddavid)
- 4688958: fix(apply,modes,extract_llm): key the TTL record and growth per thread; LRU tracker (@amiddavid)
- 56a9bfa: fix(campaign): write UTC timezone on generated keep-alive windows ( <>)
- 58e7070: fix(cheapmodel): append after a trailing system message, not before it (@amiddavid)
- 9b1e53a: fix(cheapmodel): cap thinking-adjusted max_tokens at the model's own limit (@amiddavid)
- 10adab4: fix(cheapmodel): default the thinking live test to Sonnet, not Haiku (@amiddavid)
- 0c93fe3: fix(cheapmodel): fail on a truncated prefix-ask reply, pin a minor case (@amiddavid)
- 0e51464: fix(cheapmodel): insert the prefix ask before a trailing system message (@amiddavid)
- 0218244: fix(cheapmodel): raise max_tokens above thinking.budget_tokens on prefix asks (@amiddavid)
- ae03f68: fix(codex): clean reset and expose raw stats (@amiddavid)
- 1b065f1: fix(codex): move proxy updates outside routed sessions (@amiddavid)
- 1bb7fc8: fix(dash): fix gofmt and serve a stale size-spread cache on error (@amiddavid)
- 0aed0eb: fix(dash): keep DeclFilterSavings for day scope, fix a rollup double-count (@amiddavid)
- 0b3de83: fix(dash): keep a ping-billed summary call out of the gateway cost split (@amiddavid)
- 1c0445d: fix(dash): keep the whole decl-filter credit in the lean stats path (@amiddavid)
- 94f6d06: fix(dash): label keep-alive as an upper bound in the bottom line, rank on low bounds, restrict copyable commands ( <>)
- dd7d22a: fix(dash): make lean=1 a strictly bounded path (@amiddavid)
- da84035: fix(dash): scope session-filtered lean queries to the session, not the table (@amiddavid)
- 27b11d3: fix(dash): ship bounded session/day lean; keep lifetime exact for now (@amiddavid)
- 5173d56: fix(dash,plugin): address PR #403 review findings (@amiddavid)
- c942aac: fix(dash,plugin): stop statusline cg! on slow stats, dedupe cache refresh (@amiddavid)
- 4d06d4f: fix(internal/waitcause): read as a background wake, not human (@amiddavid)
- 0dddde4: fix(internal/waitcause): share apply's normalizer, keep open items across compaction (@amiddavid)
- ac5c794: fix(keepalive): align remaining entry points with the new defaults ( <>)
- 2a87339: fix(keepalive,offload): key the summary keep-alive candidate by thread (@amiddavid)
- fcbaedc: fix(kvcache): rejected requests no longer erase the live cache entry in replay ( <>)
- 952b30f: fix(kvcache): skip only non-2xx requests with no usage in replay ( <>)
- d35e98c: fix(modes): read a new thread of an evicted parent as all cached (@amiddavid)
- 7575e4c: fix(offload): book a keep-alive summary call once, on its ping row (@amiddavid)
- fbe1fd4: fix(offload): book every keep-alive summary call exactly once (@amiddavid)
- 3f069e8: fix(offload): decline rather than act unaligned when WireGroup goes stale (@amiddavid)
- 99bacd4: fix(offload): decline when a last-turn-only model would strip thinking (@amiddavid)
- 33986a9: fix(offload): hash the raw pre-pipeline span in both stale-prefix guards (@amiddavid)
- 316410e: fix(offload): imply block_fallback under debug logging, WARN on ask failure (@amiddavid)
- da59be5: fix(offload): key the summarizer's checkpoint and in-flight state by thread (@amiddavid)
- 015b476: fix(offload): make emitCheckpoint use the same wire-group boundary rule (@amiddavid)
- 45bd937: fix(offload): name the rest of the last-turn-only thinking models (@amiddavid)
- 211c7f5: fix(offload): reject a truncated summary before it becomes a checkpoint (@amiddavid)
- 8241fc4: fix(offload): send a stale summary while the fresh one is made (@amiddavid)
- c77497d: fix(offload): send the stale summary on a cold turn too (@amiddavid)
- 5aa2c24: fix(offload): stop flipping expanded content inside the cached prefix (@amiddavid)
- e9a7f00: fix(offload): surface the summary call's own usage, fix a keep-alive (@amiddavid)
- 6284886: fix(offload,proxy): decline a stale PrefixAsk commission instead of answering from an old body (@amiddavid)
- a695e9b: fix(offload,proxy): keep-alive substitution never fired on real traffic (@amiddavid)
- 1db80d0: fix(offload,proxy): the stale-prefix guard ignored a moving cache marker and the pipeline order (@amiddavid)
- 738b525: fix(plugin): atomic refresh lock; a cached stats body never renders as loading ( <>)
- 534f7d1: fix(plugin): finish every render within a half-second budget; spark and heat follow local time ( <>)
- ec131b8: fix(plugin): heat says what the dollars cover ( <>)
- 960a76b: fix(plugin): label the strip, heat, spark and watch layouts and make heat readable without colour ( <>)
- 638a1ea: fix(plugin): one phrasing per hint, sub-agent count with soonest clock, 80-column renders ( <>)
- 38d70cc: fix(plugin): show saved money plainly; keep ≈ for avoidable-spend hints ( <>)
- 7a1a5bc: fix(plugin): terminal views say measured, not observed ( <>)
- d6f4328: fix(plugin): upstream latency only when slow, actionable tool-set hint ( <>)
- 7f687ff: fix(proxy): move the wait-cause body scan off the request path (@amiddavid)
- 9563651: fix(proxy): withhold a continuation's thinking when the spliced client already holds some ( <>)
- e52851d: fix(proxy,offload): drain the keep-alive candidate registry and price its substitute calls right (@amiddavid)
- ec918bd: fix(proxy,offload): key the prefix-ask stash by thread (@amiddavid)
- 3702dd3: fix(statusline): stop printing savings "of" the current context size (@amiddavid)
- 6af9b24: fix(thread): address PR #426 re-check nitpicks (@amiddavid)
- 2af908c: fix(thread): address PR #426 review (@amiddavid)
- 8f0f0e9: fix(thread): exclude agent compaction from the side-request branch (@amiddavid)
- 7cc0175: fix(thread): give a side request its own thread, not the main thread's (@amiddavid)
- bce2a19: fix(thread): give the primary id to the thread that declares tools (@amiddavid)
- 7b7b572: fix(thread): hash a string content the same as a one-text-block array (@amiddavid)
- 82eedec: merge main into dash perf base ( <>)
- 1831023: perf(dash): cut the all-time dashboard endpoints' cold latency 3-25x ( <>)
- abf80e0: perf(plugin): tvlib imports shutil lazily ( <>)
- f94197c: refactor(expand): share MessagesField and keep large integers exact in Fingerprint (@amiddavid)
- 22fdb42: refactor(plugin): fill estimate uses tvlib.growth ( <>)
- 4275e8a: refactor(plugin): heat grid, growth and extra-cost helpers are pure functions in tvlib ( <>)
- 645c3e2: refactor(plugin): request ctx/kind helpers live in tvlib so other renderers can import them without cg ( <>)
- 739e284: revert(cheapmodel): keep a truncated reply a free decline, not a 400-style error (@amiddavid)
- b5a9315: revert(offload): drop the per-component keep_frozen_after_expand switch (@amiddavid)
- b58959e: revert: send the stale summary on a cold turn too (@amiddavid)
- 36401b8: style(dash): gofmt event.go after the WaitCauseResult field addition (@amiddavid)
- 288d8f6: style(offload): gofmt summarize_async.go (@amiddavid)
- 8afc1b6: test(campaign): generated windows keep UTC through storage and across DST ( <>)
- 40339d8: test(cheapmodel): pin the truncated-reply pass-through directly, trim comments (@amiddavid)
- b8e30ac: test(dash): regenerate golden files after merging main (keep-alive defaults, billed-elsewhere); fixture writer for demo databases ( <>)
- a7be5f0: test(internal/waitcause): cover the full teammate open/wait/close lifecycle (@amiddavid)
- f5198c0: test(proxy): check the presets' own summarizer settings, not the test's (@amiddavid)
- bb9ce5d: test(proxy): check the shipped xhigh preset commits a summary (@amiddavid)
- b8c8990: test(proxy): pin a summary call to exactly one keep-alive ping (@amiddavid)
- 3923f76: test(proxy): pin the "_billed" marker between offload and dash (@amiddavid)
- e1e73b9: test(thread): pin that a Codex resume stays on its thread (@amiddavid)
Install
No Go toolchain and no C compiler are needed — the binary is statically linked.
Download the tarball for your platform, untar it, and put context-guru-proxy on your
PATH. The archive unpacks into its own directory, so this is safe to run anywhere:
tar xzf context-guru_*_darwin_arm64.tar.gz
install -m 755 context-guru_*/context-guru-proxy ~/.local/bin/
Then see docs/get-started/quickstart-proxy.md.