github JuliusBrussee/caveman v4.1.0
Caveman 4.1.0

45 minutes ago

Caveman 4.1.0 is a maintenance release: bug fixes across compress, OpenCode, Hermes, Pi, the proxy and the hooks, a recovery store that no longer fills up and stops compressing, and a few small switches people asked for. caveman-compress now refuses a file with a key or token in it, and installs from skill hubs again.

Action needed

  • forward_headers under a providers.<name> block now stops the proxy from starting. Before, it was silently ignored: no headers were forwarded and the only symptom was an upstream 401. Configure that upstream as a compat mount instead: compat.<name> with base_url and forward_headers, plus wire_dialect: anthropic if it speaks the Anthropic protocol (see docs/technical/configuration.md) (#1458).
  • caveman-compress refuses a file whose text holds a credential, such as a private key block or a cloud, Git host or model API token. Compression sends the file to your model provider, so move the secret into an env var or secret manager first. The error names the line, never the secret. Placeholders like sk-... or $OPENAI_API_KEY still compress (#1471).

Changed

  • Old recovery handles can now expire. The recovery store used to keep every compressed original forever, so it filled up and compression stopped (#1370). When a write would exceed the store's cap, it now frees room: typed objects of sessions idle 14 days (archived) or 30 days (any) are expired, oldest first, until the store is at 80%. Retrieving an expired handle answers cave_expired_recovery, and each expiry is logged in proxy.log. Blob recoveries never expire (#1481).

New

  • caveman-proxy recovery-store status|check|repair for a damaged ccr.db. A damaged store now refuses writes instead of staying corrupt across upgrades; reads keep working. Repair copies only rows whose bytes still match their hash, and moves the damaged files aside untouched. caveman status and caveman doctor point at it (#1369, #1481).

  • Turn off the per-prompt reminder with CAVEMAN_REINFORCE=0, or "reinforce": false in ~/.config/caveman/config.json or a repo's .caveman.json. The full ruleset is still sent at session start (#1468).

  • --hook-node node makes installed hooks find Node through PATH at run time instead of pinning the install-time path, for people who switch Node versions (#1452). The default is unchanged, because apps started outside a terminal don't see the shell's PATH.

  • The installer falls back to Bun when Node is absent. Node stays first (#570, #1344 by @cyrus-za).

  • caveman learn scans Pi sessions, and honors PI_CODING_AGENT_DIR / PI_CODING_AGENT_SESSION_DIR (#1317 by @tranducquy0).

  • caveman mem can revert a memory to an earlier value, and supersede --stdin takes replacements too large for a command line (#1386 by @PARTHDESHMUKH2005). The client checks that the installed binary supports --stdin first, so an older binary can no longer store the literal text --stdin as the fact.

Fixed

caveman-compress

  • Hermes' skill hub blocked the install with a DANGEROUS verdict that --force can't override. Every finding was a false match, and the matched text is respelled with identical behavior (#1464).
  • Backups are keyed on the file's full path, so two projects' CLAUDE.md no longer share one backup slot. A run that dies before writing removes its backup and staging file, so the next run doesn't abort.
  • Validation now refuses commentary appended after the body (#1433). The prompt keeps the verb that carries an instruction (#1434). Frontmatter stays local on both passes (#1359 by @leninworld). Trailing punctuation on URLs and paths no longer fails validation (#1356 by @Pharex38). Credential dotfiles and bare dotfiles like .env are refused by name (#1357 by @Pharex38, #1363).

OpenCode

  • OpenCode 2: the shrink plugin is generated for the API the installed major actually loads (#1445). OPENCODE_CONFIG_DIR is honored everywhere (#1441). Deleted sessions are acted on (#1444), and the host's project directory is passed through (#1443).
  • The installer's already-installed probe reads JSONC settings.json correctly, and the plugin honors a repo defaultMode: "off" (#1430, #1431 by @Quinnod345).

Hermes

  • caveman enable hermes writes YAML that still parses (#1405). It reads ownership by value, so a reformatted config stays owned (#1410). It honors plugins.enabled / plugins.disabled membership (#1442, #1446 by @Ha1baraA11).

Pi (@caveman-ai/pi 0.3.2)

  • Per-prompt context is sent as a message, so the provider's prompt cache survives each prompt (#1364, #1376 by @worldofgeese).
  • Tool outputs under 4 KB are no longer replaced by a retrieval handle (#1365, #1378 by @danieldutu). caveman_retrieve with a query now says it returns an excerpt (#1368, #1377 by @danieldutu).
  • Pi's virtual router/auto model no longer warns that it is unroutable (#1449). The compat route is verified for an OpenAI base URL without /v1 (#1325 by @szsunyuan).

Proxy, stats and cost

  • Claude Code requests that declare the advisor tool are priced again, instead of every request showing "Unknown" cost (#1465). Streaming Anthropic responses read their outcome qualifiers from the right place (#1453).
  • A completed Codex stream closed by the client keeps its token counts (#1397, #1398 by @Ha1baraA11).
  • caveman start reads the proxy's top-level mode, not a nested middleware.mode (#1457).
  • A compat upstream blocked by the SSRF guard now answers cave_upstream_blocked and logs the host plus the CAVE_SSRF_ALLOWLIST fix, instead of a generic 502 (#1440).
  • caveman stats no longer times out on large stores: per-request cache digests moved to their own table, migrated in the background (#1371, #1481). On a timeout it names the database size and suggests --days 7.
  • Native runtime: CCR writes no longer re-scan the whole store, which in large homes made native requests run out their 250 ms budget and close empty (#1279). Overlong native.sock paths are reported (#1399, #1402 by @Ha1baraA11).
  • Recovery bytes that don't match their handle are refused (#1373 by @zsltg). The recovery store's page cap applies on every connection, and its writes are serialized (#1374, #1375 by @zsltg). Stats windows are indexed (#1372 by @zsltg). Bedrock ARN model ids keep their encoded slash (#1345 by @AlSh007). A middleware response is not marked over the limit at a quarter of it (#1367 by @AlSh007). Kimi K3 effort is mapped (#1306 by @ysntony). The wrap plugin's caveman_retrieve results are no longer recompressed (#1432).
  • Claude OAuth token refresh is relayed through the proxy. Routed Gemini pins API-key auth instead of exiting 41.
  • The pricing catalog was re-verified against vendor pages (no price changed). Vertex gemini-2.5-pro and gemini-2.5-flash were removed: Google retired both on 2026-10-20, and those requests now show as unpriced rather than mispriced (#1473).

Hooks and installer

  • Statusline setup keeps literal $ in CLAUDE_CONFIG_DIR paths (#1400, #1401 by @Ha1baraA11). Managed hook entries are compared ignoring key order, so doctor --fix stops fighting a reordered entry (#1437, #1420 by @jamestrandung). Uninstall no longer deletes a settings.json.bak it didn't create (#1330 by @AlSh007).
  • Codex PostCompact hook output is valid (#1467 by @mauhpr). Cursor stops always injecting skill files from AGENTS.md (#1411 by @minhhung2556). Hook downloads are bounded and pinned to HTTPS (#1269 by @tejgokani).
  • ENABLE_TOOL_SEARCH defaults to "true" to match Claude Code (#1362 by @AliReza99).

Engine, shrink and learn

  • Escaped pipes stay inside Markdown table cells (#1456 by @kevin9327). Integers above 2^53 stay off the numeric range track (#1332 by @AlSh007). Elision notes are placed stably (#1343 by @CHLIN0). CR-separated terminal output is no longer truncated.
  • caveman-shrink skips null list entries instead of exiting (#1435, #1436 by @shaikn6), and reads Anthropic input_schema tools (#1331 by @AlSh007).
  • caveman learn stops reporting caveman's own injected context as text you pasted (#1459), and separates cold resumes from cache churn (#1419 by @jamestrandung).

Agent versions

  • Tested agent versions move up: Codex 0.166.0, Claude Code 2.1.318, Gemini CLI 0.67.0, OpenCode 1.19.5, Qwen Code 0.26.8, Kilo 7.8.27, OpenClaw 2026.11.1 and Hermes 0.23.0, each passing the repo's conformance run (#1474, with #1416 by @szsunyuan and #1451 by @anirudhqwerty). Pi stays at 1.0.4 for now; Pi 1.5.0 needs compatibility work (#1225).

Maintenance

  • Security: klauspost/compress v1.20.3 (GO-2026-6865), golang.org/x/net v0.62.0 (GO-2026-6860, GO-2026-6866), and a patched Go toolchain. @caveman-ai/middleware's MCP adapter now requires @modelcontextprotocol/sdk 1.32.0 or newer (GHSA-6prh-2h8m-c8cw), and says so when it finds an older one (#1466 by @sudip28122812-creator). filelock is patched, and the broken litellm releases are excluded (#1379 by @szsunyuan).
  • Dependency bumps: npm dev group (#1479), golang image, pip group.
  • Binaries: bin-v4.1.0. CLI: @caveman-ai/cli 4.1.0. Pi: @caveman-ai/pi 0.3.2.

Packages

Don't miss a new caveman release

NewReleases is sending notifications on new releases.