caveman
AI Coding Toolsπͺ¨ why use many token when few token do trick β Claude Code skill that cuts 65% of tokens by talking like caveman
Features
- Compresses AI-generated responses to ~25% of original token count while preserving technical accuracy
- Provides multiple compression levels (lite, full, ultra, wenyan) via simple command switches
- Offers additional utilities: commit message generation, PR review snippets, usage statistics, and fileβlevel compression
Recent releases
View all 14 releases βFixed install script errors when using curl|bash with set -u and npx flag handling.
Full changelog
Hotfix for v1.8.0 β curl|bash one-liner
The headline install command in v1.8.0 was broken at first contact:
$ curl -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash -s -- --only openclaw
bash: line 39: BASH_SOURCE[0]: unbound variable
error: unknown flag: --
Two regressions β neither caught by CI because both are stdin-pipe-only.
What broke
set -u+${BASH_SOURCE[0]}is fatal under curl|bash. When bash reads from stdin,BASH_SOURCEis unset; the strict-mode shell trapped on the first reference.--separator survivednpx.install.shandinstall.ps1passednpx -y "github:..." -- "$@"and modern npx forwards the literal--to the package, whichparseArgsrejected asunknown flag: --.
What this release fixes
install.shdefaultsBASH_SOURCE[0]to empty so the curl-pipe path falls through cleanly underset -u.install.sh+install.ps1no longer pass--between npx and the package β npm 7+ npx forwards trailing args correctly without it.bin/install.jsparseArgsnow accepts a bare--as a no-op (POSIX end-of-options marker). Future shim drift can't re-break this.- New regression test asserts
--is accepted.
Upgrade
curl -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash -s -- --only openclaw
If you tried v1.8.0 and got the error above, just re-run this command. No state was written on the failed install.
What's unchanged from v1.8.0
Everything else β OpenClaw, opencode, the installer fixes, the test bump (now 51 tests). See v1.8.0 release notes for the full feature list.
- v1.8.0's `curl|bash` one-liner is broken (BASH_SOURCE unbound + stray `--`); requires upgrade to v1.8.1
Full changelog
β οΈ v1.8.0's curl|bash one-liner was broken (BASH_SOURCE unbound + stray
--to parseArgs). Use v1.8.1 instead β same release contents plus the hotfix.
Brain still big. Two more mouths now small.
This release teaches caveman to two new agents: OpenClaw (the lobster) and opencode (the TUI). Both now grunt fluent caveman from message one β no /caveman per session, no setup nag.
Plus a stack of installer fixes from a top-to-bottom review of bin/install.js.
What's new
π¦ OpenClaw β first-class always-on target
npx -y github:JuliusBrussee/caveman -- --only openclaw and the lobster talks like a caveman every turn.
Two tiny writes do the work:
- Skill drop at
~/.openclaw/workspace/skills/caveman/SKILL.mdβ spec-correct frontmatter (version,always: true), discoverable byopenclaw skills list. - SOUL.md nudge β marker-fenced bootstrap block at
~/.openclaw/workspace/SOUL.md, auto-injected each turn under "Project Context". Stays well under OpenClaw's 12K-per-file cap.
Idempotent on both writes. Uninstall strips the skill folder + the marker block, leaves your other workspace content alone. Custom workspace via OPENCLAW_WORKSPACE.
See README's Lobster, Meet Rock section for the longer pitch.
π€ opencode β native plugin replaces npx-skills fallback
opencode goes from "manual /caveman per session" to always-on. The installer drops:
- A real opencode plugin (
~/.config/opencode/plugins/caveman/) usingsession.createdandtui.prompt.appendlifecycle hooks - Six slash-command prompt templates (
/caveman,/caveman-{commit,review,compress,stats,help}) - Three cavecrew subagents
- Seven skill folders (caveman, caveman-commit/review/help/stats/compress, cavecrew)
- A Tier-3 always-on ruleset in
AGENTS.md, fenced with<!-- caveman-begin -->/<!-- caveman-end -->markers (clean uninstall later)
opencode.json gets patched with the plugin entry plus the caveman-shrink MCP server (when --with-mcp-shrink is on, which is the default).
opencode reaches Tier-1 minus the statusline (opencode's TUI exposes no plugin-writable badge).
π οΈ Installer rewrite + correctness fixes
The unified bin/install.js got reviewed end-to-end. What changed in this release:
Bug fixes (high-severity)
downloadToPromise was unawaited on the https fallback path β silent partial install ifcurlwas missing. Now properly awaited.--only <typo>used to exit0with no work done. Now validates against the provider matrix and exits2witherror: unknown agent: <id>..bakfiles were silently overwritten on every reinstall, destroying recovery. Now preserved on first install only.- opencode plugin payload (
plugin.js,package.json,caveman-config.cjs) used to be rewritten on every reinstall, wiping user edits. Now honors the same!--forceskip the rest of the payload uses. --config-dirhelp text now discloses scope honestly: it does not sandboxclaude plugin install,gemini extensions install, opencode (XDG_CONFIG_HOME), or openclaw (OPENCLAW_WORKSPACE).
Idempotency / hygiene
- Uninstall now probes
claude plugin list/gemini extensions listbefore firing the uninstaller β no more "Plugin not installed" stderr noise on cold uninstalls. - Uninstall now also runs
claude mcp remove caveman-shrink(when the subcommand exists). - opencode AGENTS.md is now fenced with
<!-- caveman-begin -->/<!-- caveman-end -->. Uninstall strips just the fenced block, preserving any user content above and below it. --config-dirvalue is now~-expanded.removeCavemanHooksno longer crashes on malformed pre-existingsettings.hooks(e.g. when a user hand-edited and broke things).
π§Ή Repo layout consolidated
hooks/, rules/, tools/, mcp-servers/ all moved under src/. Sources of truth are at the top of the tree; distribution mirrors live below. See CLAUDE.md for the new map.
Tests
50/50 passing (npm test). Up from 43 in v1.7.0 β seven new tests cover:
--onlytypo validation--config-dir ~expansion--helpdiscloses--config-dirscoperemoveCavemanHooksmalformed-input safety- AGENTS.md fence assertion
- opencode plugin.js hand-edit survives reinstall (without
--force) - AGENTS.md fenced uninstall preserves user prefix and suffix
Verify after upgrade
node bin/install.js --list # 34 providers; OpenClaw + opencode visible
node bin/install.js --help # --config-dir scope is now spelled out
For the lobster: npx -y github:JuliusBrussee/caveman -- --only openclaw.
For opencode: npx -y github:JuliusBrussee/caveman -- --only opencode (needs a local clone or npx-extracted repo for the native plugin payload).
Upgrade
Existing users:
npx -y github:JuliusBrussee/caveman
Auto-detects everything you already had + picks up OpenClaw and opencode if present. Safe to re-run.
Behavior changes worth knowing
- opencode plugin payload no longer overwrites on reinstall. If you've edited
~/.config/opencode/plugins/caveman/plugin.jsand want the new version, pass--force. Without--force, your edits stay. - opencode
AGENTS.mdfrom v1.7.x and earlier was un-fenced. Reinstall won't replace a legacy block by default; pass--forceto rewrite with the fenced version. Uninstall still removes legacy blocks correctly.
Caveman ecosystem
- caveman (you here) β output compression
- cavemem β cross-agent memory
- cavekit β spec-driven build loop
One rock. Two rock. Three rock. That it.
- Reβrun the installer (curl pipe or `bash install.sh`) to apply macOS detection fix and new defaults.
- Use `--minimal` with the installer if you do not want MCPβshrink registration or perβrepo init files.
- safeWriteFlag() extended to all flag-file writes with whitelist validation
- Statusline scripts now refuse symlinked flag/suffix files and strip control bytes to prevent terminal escape injection
- /caveman-stats: real token receipts with pricing, statusline badge and aggregation options
- caveman-shrink MCP middleware (npm package) that compresses description fields without altering code/URLs
- cavecrew subagents (investigator, builder, reviewer) emitting ~60% fewer handoff tokens
Full changelog
v1.7.0 β Stats receipts, smart installer, cavecrew, MCP-shrink
The biggest release since v1.0. Caveman now has measurement (real token receipts, not vibes), an installer that detects 30+ agents and runs each one's native install, three caveman-mode subagents that emit ~60% fewer handoff tokens than vanilla, an MCP middleware that shrinks tool descriptions in flight, and a one-command rule-file dropper for any repo.
Plus a critical macOS installer fix that was silently breaking detection for every compound-spec provider (cursor / windsurf / continue / 28 others).
π New: /caveman-stats β real receipts, not vibes
Caveman Stats
ββββββββββββββββββββββββββββββββββ
Session: ...projects/my-app/abc123.jsonl
Turns: 47
ββββββββββββββββββββββββββββββββββ
Output tokens: 3,210
Cache-read tokens: 128,400
ββββββββββββββββββββββββββββββββββ
Est. tokens saved: 5,961 (~65%)
Est. saved (USD): ~$0.089
ββββββββββββββββββββββββββββββββββ
Memory compressed: 2 files, ~1,920 tokens saved per session start
Reads the active Claude Code session JSONL directly β no model-side guessing. Pricing matches by model-id prefix (claude-sonnet-4-* β $15/M, etc.) so it stays correct across point releases. Lifetime aggregation via --all, time window via --since 7d / --since 24h, tweetable one-liner via --share.
Statusline savings badge β on by default. After your first /caveman-stats run the bar shows [CAVEMAN] β 12.4k (lifetime tokens saved) and updates every run. Opt out with CAVEMAN_STATUSLINE_SAVINGS=0. Suffix file is absent until stats has run, so fresh installs render no fake number.
29 tests cover: pricing prefix-match, lifetime aggregation latest-per-session semantics, --since parsing, malformed-duration rejection, compressed-memory pair detection, statusline default-on / opt-out / fresh-install behaviors, ANSI-escape stripping in the suffix file, and symlink-safe history append.
π New: caveman-shrink β MCP middleware (published to npm)
[email protected] is a stdio proxy that wraps any MCP server, intercepts tools/list / prompts/list / resources/list responses, and compresses the description fields. Same boundaries as the parent skill β code, URLs, paths, and identifiers stay byte-for-byte identical.
{
"mcpServers": {
"fs-shrunk": {
"command": "npx",
"args": ["caveman-shrink", "npx", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
}
}
}
V1 deliberately does not touch tool-call response bodies or request payloads β only prose-y description fields. Configurable extra fields via CAVEMAN_SHRINK_FIELDS, debug deltas via CAVEMAN_SHRINK_DEBUG=1. Auto-registered by install.sh (use --minimal to skip). 12 tests cover: article/filler/hedge stripping, fenced code preservation, inline code preservation, URL preservation, filesystem-path preservation, identifier preservation, real MCP-style descriptions, nested-object walking.
π New: cavecrew β three caveman subagents for Claude Code
Subagent tool-output gets injected back into the main thread context. Vanilla Explore / reviewer agents return verbose prose that eats main-context fast. Cavecrew agents emit caveman-ultra by default, ~60% fewer handoff tokens.
| Subagent | Model | Job | Output |
|---|---|---|---|
| cavecrew-investigator | haiku | Read-only locator. "Where is X defined?" / "what calls Y?" / "map this dir" | path:line β \symbol` β note, grouped headers when 3+ | | cavecrew-builder| sonnet | 1-2 file surgical edits. Refuses 3+ file scope. |path:line-range β change β€10 words.+verified: re-read OK| |cavecrew-reviewer| haiku | Diff/branch/file review. One line per finding. |path:line: π΄ bug: problem. fix.` + severity totals |
Builder has no Bash tool β can't shell out, can't push, can't delete. Refusals are terminal one-liners (too-big. split: ..., needs-confirm. op: ..., regressed. revert path:line).
π New: smart multi-agent installer
# macOS / Linux / WSL
curl -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash
# Windows
irm https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.ps1 | iex
Detects which AI coding agents are on your machine and runs each one's native install (plugin / extension / skill / rule file). Skips what you don't have. Safe to re-run.
Coverage: 33 agents. Native: Claude Code, Gemini CLI, Codex. IDE/VS Code-family: Cursor, Windsurf, Cline, Copilot, Continue, Kilo, Roo, Augment. CLI: Aider Desk, Amp, Bob, Crush, Devin, Droid, ForgeCode, Goose, iFlow, JetBrains Junie, Kiro CLI, Mistral Vibe, OpenHands, opencode, Qwen Code, Qoder, Rovo Dev, Tabnine, Trae, Warp, Replit Agent, Antigravity. Plus universal AGENTS.md / IDE rule files for everything else via npx skills.
| Flag | What |
|---|---|
| --all | Plugin + hooks + statusline + MCP shrink + per-repo rule files. The full ride. |
| --minimal | Plugin/extension only. |
| --with-hooks | Standalone hooks + statusline + stats badge. On by default. |
| --with-mcp-shrink | Register caveman-shrink MCP proxy. On by default. |
| --with-init | Drop per-repo rule files for Cursor/Windsurf/Cline/Copilot/AGENTS.md. |
| --list | Print full agent matrix and exit. |
| --only <agent> | One target only (repeatable). |
| --dry-run | Preview, write nothing. |
install.sh --help for full reference.
π New: caveman-init (cavepack) β drop rule files into any repo
node tools/caveman-init.js # writes rule files for all targets
node tools/caveman-init.js --dry-run # preview
node tools/caveman-init.js --only cline # one target only
Idempotent β uses a sentinel string to detect prior installs and skip them. Existing rule files are preserved unless --force is passed. Appendable targets (AGENTS.md, .github/copilot-instructions.md) get the caveman block appended below your existing content; replace-mode targets (.cursor/rules/caveman.mdc, .windsurf/rules/caveman.md, .clinerules/caveman.md) get fresh files. 8 tests cover: greenfield create, idempotent skip, append-vs-replace semantics, sentinel detection, --force, --dry-run, --only.
π Critical fixes
-
macOS installer detection was silently broken.
detect_match()usedawk -v RS='||'to split compound detection specs. BSD awk on macOS rejects||as a regex (illegal primary in regular expression), the awk silently failed, the fallback re-ran the whole spec as a single clause, and every compound-spec provider (cursor, windsurf, continue, kilo, roo, augment, aider-desk, bob, crush, devin, droid, forgecode, goose, iflow, kiro, mistral, openhands, opencode, qwen, rovodev, tabnine, trae, warp, replit) was undetectable on macOS. Replaced with bash parameter expansion (${rest%%||*}/${rest#*||}) β works on bash 3.2+, no awk dependency. Verified with reproducer: compound match, fallback match, all-miss compound, single-clause all behave correctly. -
--with-mcp-shrinkregistered a config that 404'd on first spawn. Pre-publish,claude mcp add caveman-shrink -- npx -y caveman-shrinkwould store an entry that failed every time Claude tried to spawn it. Now the installer probesnpm view caveman-shrinkfirst β package missing or registry unreachable degrades to a clean manual-config skip with a print-the-snippet fallback. Default-on restored after[email protected]shipped to npm. -
Windows install.ps1 syntax error from
node -e. Powershell tokenizer truncated the embedded JS at double-quotes, breaking standalone hook install. Fix writes the script to a temp file, runsnode script.js, and removes it. (Thanks @scottconverse β #250, fixes #249/#199/#72) -
/cavemanargument whitelist + symlinked-parent~/.claudesupport.~/.claudesymlinked to another drive (legitimate pattern) was previously refused as a "symlink attack." Now: lstat parent, resolve, verify uid match (Unix) or home-dir prefix (Windows), then allow. The flag file itself still must never be a symlink β that's the actual clobber vector. Plus argument validation: only known mode tokens reach the flag write. -
caveman-compressreliability. UTF-8 stdout enforced (Windows console no longer corrupts compressed output), empty/identical-input guards prevent silently writing zero-byte files, inline-code validation now matches the fenced-code rule, frontmatter cleanup preserves YAML.
π‘ Security
-
safeWriteFlag()extended to all flag-file writes. Adds:safeWriteFlagfor the active-mode flag,appendFlag(withO_APPEND) for the lifetime stats log, andreadFlag(with size cap + whitelist) for the per-turn reinforcement read. The whitelist (VALID_MODES) is the load-bearing part β without it, a flag pointing at~/.ssh/id_rsacould exfiltrate via stdout. -
Statusline scripts no longer trust the flag file blindly. Both
caveman-statusline.shand.ps1now refuse symlinked flag/suffix files and strip control bytes (tr -d '\000-\037') so a hostile flag can't render terminal escape sequences in your status bar.
π Skill changes
- Ultra-mode code-symbol guard. Previously the rule "abbreviate everything" was over-aggressive β symbols like
useMemoorgetUserByIdwould get truncated. Now: ultra abbreviates prose, never code/symbols/error strings. - Auto-clarity expanded. Drop caveman for: security warnings, irreversible action confirmations, multi-step sequences where fragment ambiguity risks misread, compression itself creating ambiguity, user repeating a question.
- Typst + LaTeX added to the protected-content list β math/markup blocks pass through untouched.
π Docs
- README cleanup: install table now shows the smart installer first, manual install second, "What You Get" matrix collapsed to one table with footnotes, no more 4 nested
<details>walls. Voice preserved (60-second readability check). Benchmark table re-anchored to realbenchmarks/results/*.jsonruns (mean 65%, range 22-87%). - Codex install clarified β repo-local
.codex/hooks.jsonmakes auto-activation work for this repo on macOS/Linux; for other repos, copy the hook or use$cavemanmanually. Codex hooks currently disabled on Windows. - New:
docs/install-windows.mdβ manual fallback for stubborn Windows envs (PR-merged plugin install path, symlink config for Codex). - CLAUDE.md heavily expanded: hook system, distribution matrix, skill-system, "adding a new agent" checklist (profile slug must exist in upstream
vercel-labs/skills, install.ps1 is hand-kept-in-sync with install.sh),caveman-shrinkintegration notes, cavecrew canonical-vs-synced layout.
π§ͺ Tests
- 73 tests now ship: 29 stats + 12 mcp-shrink + 8 init + 12 symlink-flag + 4 hooks (py) + 8 verify_repo + Python compress safety + inline-validate.
- All tests run on every CI push.
Upgrade
Plugin users:
claude plugin update caveman
Standalone hook users (re-run for the new statusline, MCP-shrink registration, and crash fixes):
bash hooks/install.sh --force
Curl-pipe / fresh install:
curl -fsSL https://raw.githubusercontent.com/JuliusBrussee/caveman/main/install.sh | bash
Other agents:
npx skills add JuliusBrussee/caveman
Don't want the MCP shrink or per-repo init? --minimal skips them. Want everything? --all.
Thanks
@scottconverse (#250 Windows fix), @ikattur-ota (#199 Windows hook reports), @confluencepoint (#72 module-loader report), and everyone who hammered the installer until the awk-on-macOS bug fell out.
- safeWriteFlag() helper hardens flag file writes against symlink attacks on ~/.claude/.caveman-active, preventing clobbering of ~/.ssh/authorized_keys and ~/.bashrc
- Hooks no longer crash when ancestor package.json declares 'type': 'module'
- Natural-language activation phrases now work ('talk like caveman', 'normal mode', 'stop caveman')
- CLAUDE_CONFIG_DIR environment variable now respected in all hooks and scripts
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.