Skip to content

v3.1.0 — prefix-diff + deferred-tools-restore extensions; closes #59

Choose a tag to compare

@cnighswonger cnighswonger released this 25 Apr 01:13
· 125 commits to main since this release
c0baa01

The final piece of the #59 port-from-preload effort lands. Two new proxy extensions plus three pre-existing ones now enabled by default. No breaking changes, no migration required.

New proxy extensions

prefix-diff — opt-in cache-bust hunting (#65)

Pure diagnostic. Set CACHE_FIX_PREFIXDIFF=1 and the proxy snapshots a small projection of every request's prefix (system prompt + tools + first 5 messages) to ~/.claude/cache-fix-snapshots/<key>-last.json. If a prior snapshot exists and content differs, also writes <key>-diff.json and emits a one-line stderr summary so you can see drift across turns.

Atomic writes (per-invocation unique tmp suffix). No request mutation. Per-call diff — no boot-flag gating, so it works correctly under hot-reload and concurrent calls.

deferred-tools-restore — preserves cache prefix across MCP reconnect race (#66)

On by default. Opt out with CACHE_FIX_SKIP_DEFERRED_TOOLS_RESTORE=1.

On claude --continue, if MCP servers haven't finished reconnecting before the first post-resume request, the deferred-tools attachment block at the root of the message array shrinks dramatically (~40 tools collapse to a handful of CC built-ins, with an UNAVAILABLE marker appended). That root-level change busts the cache at the very top — the entire ~940K prompt re-caches.

This extension persists the clean form of the block keyed per-project, then substitutes it on subsequent shrunken requests. Strict downgrade guard: never substitutes unless the snapshot is strictly longer than the current block. Defense-in-depth: rejects snapshots that themselves contain the UNAVAILABLE marker.

The snapshot key is derived from the cwd parsed out of CC's # Environment section in the system prompt (line-based section parser with strict structural requirements + ambiguity guard — fails open if the marker can't be found cleanly, never silently restores the wrong snapshot).

Default config update (#69)

Three pre-existing extensions now enabled in the default extensions.json:

  • smoosh-split (order 320) — peels system-reminders out of tool_result.content into standalone blocks
  • content-strip (order 330) — removes per-turn bookkeeping reminders (Token usage:, Output tokens —, idle-tool nudges) entirely
  • tool-input-normalize (order 340) — normalizes tool input fields for cache-stable JSON serialization

Triggered by a real-world cache-miss event: a 606K-message context with a warmer running dropped to 5.9% hit rate; recovered to 99.9% within ~2 calls after enabling these. They were Codex-reviewed and merged days ago but had remained dormant in the default config.

Issue #59 closed (10/10 items resolved)

Item 10 (git-status injection strip) is intentionally not ported as a proxy extension — the proxy intercepts requests after CC has already composed the system prompt, so post-hoc stripping would itself bust the cache. The fix has to happen at the source. README updated to point users at the native CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1 flag with the technical rationale.

Other changes

  • README + ko/zh translations: removed broken claude-code-meter sharing references (#71). The integration loaded via NODE_OPTIONS which CC v2.1.113+ ignores (Bun binary). Refactor to consume from the proxy's usage-log JSONL is tracked in #70.
  • TRACKED_ISSUES.md backfilled with Apr 23 activity (v3.0.3/4/5 ship notes, three filed CC issues, three new contributor entries).
  • docs/deferred/proxy-session-serializer.md — preserves the Phase 3b session-serializer design as a deferred reference. Tracked in #67.

Tests

391 → 433 (added 42 for deferred-tools-restore, 25 for prefix-diff). Full suite green on the release commit.

Tarball

claude-code-cache-fix-3.1.0.tgz — 118.1 kB packed / 399.4 kB unpacked / 43 files.

— AI Team Lead