install.sh:
- detect_match: replace `awk -v RS='||'` (rejected by macOS BSD awk:
"illegal primary in regular expression") with bash parameter expansion.
Compound detection specs were silently failing, so cursor / windsurf /
continue / and 28 other compound-spec providers were never detected.
- --with-mcp-shrink: flip default OFF + probe `npm view caveman-shrink`
before registering. Was registering a config that 404s on first spawn.
install.ps1: mirror the MCP-shrink default flip + npm probe.
tests: update statusline tests for default-on suffix behavior. Add a
regression for fresh installs where the suffix file is absent.
Add npm-pkg-fix formatting to package.json.
cavecrew: promote agents/cavecrew-*.md to top-level canonical, refine
subagent contracts (sharper output formats, terminal refusal
lines, model: haiku for read-only roles). CI workflow syncs
agents/ + skills/cavecrew/ into plugins/caveman/.
docs: README & CLAUDE.md align with new opt-in MCP-shrink policy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- caveman-stats: dollar math via per-million model pricing, --share
tweetable line, lifetime log via symlink-safe appendFlag, --all and
--since N[d|h] aggregation, opt-in statusline savings suffix, and
detection of *.original.md compress backups for input-side savings.
- install.sh / install.ps1 at repo root: smart multi-agent installer
that detects Claude Code, Gemini, Codex, Cursor, Windsurf, Cline,
Copilot and runs each one's native install. Idempotent, --dry-run,
--only, --force.
- cavecrew: skills/cavecrew + three Claude Code subagents
(investigator / builder / reviewer) for caveman-style machine-to-
machine handoffs.
- cavepack: tools/caveman-init.js drops the always-on caveman rule
into Cursor / Windsurf / Cline / Copilot / AGENTS.md in one shot,
idempotent, with a sentinel check so re-runs never duplicate.
- caveman-shrink: MCP middleware proxy + pure-Node prose compressor
that strips articles/filler/hedging from tools/list descriptions
while preserving code, URLs, paths, and identifiers byte-for-byte.
59 tests passing (27 stats, 8 init, 12 mcp-shrink, 12 symlink-flag).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New slash command that reads the active Claude Code session JSONL
(.claude/projects/**/*.jsonl), sums output_tokens and
cache_read_input_tokens from assistant turns, and shows an estimated
savings figure when the active mode is 'full'.
Real numbers, not the model's guess:
Caveman Stats
──────────────────────────────────
Session: ...projects/my-app/abc123.jsonl
Turns: 47
──────────────────────────────────
Output tokens: 3,210
Cache-read tokens: 128,400
──────────────────────────────────
Est. without caveman: 9,171
Est. tokens saved: 5,961 (~65%)
Savings est. from benchmarks/ (mean per-task). Actual varies by task.
Implementation:
* hooks/caveman-stats.js — script. Run directly with
`node hooks/caveman-stats.js`, or via `--session-file <path>`.
Falls back to most-recent JSONL under .claude/projects/ when no
session file is passed.
* hooks/caveman-mode-tracker.js — `/caveman-stats` triggers an
execFileSync call to caveman-stats.js with the hook's transcript_path,
and the output is returned via `decision: "block"` so the user sees
the stats inline without a model round-trip.
* install.sh / install.ps1 / uninstall.{sh,ps1} include
caveman-stats.js in HOOK_FILES.
* skills/caveman-stats/SKILL.md (+ plugin mirror) for skill listing.
* README install matrix and Caveman Skills section updated.
Compression ratio (0.65) is the mean per-task figure from
benchmarks/results/*.json (avg_savings: 65 across 10 tasks). Only 'full'
mode has measured data — lite/ultra/wenyan show no estimate.
Tests: 6 passing in tests/test_caveman_stats.js covering direct
invocation, full-mode estimate math, non-full skip, no-session error,
mode-tracker block behavior, and flag preservation.
Closes#305 (re-implementation; takes the design from
@DeeptimaanB but rewritten against current main).
Co-Authored-By: Deeptimaan Banerjee <DeeptimaanB@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two converging hook fixes:
* /caveman arg parser uses VALID_MODES whitelist (#314 by @jgttech).
Drops the silent fallback to getDefaultMode() on unknown args. Three
bugs collapsed: /caveman full was impossible if defaultMode was set
to anything else, /caveman off had no effect, and typos like
/caveman fulll silently clobbered state. Now: bare /caveman activates
default; /caveman off|stop|disable removes flag; unknown args leave
flag untouched (no silent overwrite); independent modes (commit,
review, compress) cannot be selected as args.
* safeWriteFlag through symlinked ~/.claude (#224 by @voidborne-d,
closes#207). Earlier hardening (5ad8f6d) refused every symlinked
parent including legitimate ~/.claude → /opt/shared-claude or
/mnt/d/claude-config patterns. Now resolves the parent via
realpathSync, verifies ownership on Unix (uid match) or under-home
on Windows, and uses the resolved path for the atomic write. Flag
file itself still must not be a symlink — that's the actual clobber
vector. CAVEMAN_DEBUG=1 emits stderr diagnostics on refusal.
12 regression tests in tests/test_symlink_flag.js — all pass.
Verified:
/caveman / lite / full / ultra / wenyan{,-lite,-full,-ultra} → mode set
/caveman off / stop / disable → flag deleted
/caveman commit → no flag (rejected)
/caveman fulll (typo) → no flag (rejected)
symlink ~/.claude → owned dir → write succeeds in real dir
symlink ~/.claude → other-user dir → refused
Co-Authored-By: Jonathon Tech <jgttech@users.noreply.github.com>
Co-Authored-By: voidborne-d <voidborne-d@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five user-contributed fixes consolidated:
* UTF-8 stdout (#289 by @ousamabenyounes) — reconfigure stdout/stderr at the
top of cli.py so Windows cp1252 consoles don't crash on the ❌ glyph in
error/validation branches and mask the real error.
* Empty / unchanged compression guards (#292 by @ousamabenyounes, closes#237)
— refuse empty input, refuse empty/whitespace/identical Claude output,
read back the backup before touching the input. Five regression tests in
tests/test_compress_safety.py.
* Inline backtick validation (#309 by @hireblackout) — validate_inline_codes
closes the silent-overwrite gap where `npm install` → `yarn install`
passed validation. Wired into validate(); 11 unit tests in
tests/test_validate_inline.py.
* Frontmatter angle-bracket fix (#268 by @Bortlesboat, closes#266) —
caveman-compress/SKILL.md description now uses FILEPATH instead of
<filepath>, plus verify_repo gains a new
verify_skill_frontmatter_upload_compatibility check, UTF-8 hardening for
Windows, and the activation-banner regex no longer requires a trailing
period.
* Two test fixtures (claude-md-project.md, mixed-with-code.md) updated so
the new inline-backtick validator passes — they were silently dropping
`server/src/`, `type(scope): description`, and `status` references in
compression. The fixture is documentation of "good" compression, so the
fix is to preserve those references.
Co-Authored-By: Ben Younes <ousama.benyounes@oratelecom.net>
Co-Authored-By: hireblackout <hireblackout@users.noreply.github.com>
Co-Authored-By: Andrew Barnes <Bortlesboat@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mode tracker wrote getDefaultMode() result to flag file even when it
returned "off". Now guards against it — same pattern as caveman-activate.
Added test coverage for off mode in both activate and tracker paths.
Also: fix swapped step comments in uninstall.sh, update stale CLAUDE.md
description for /caveman default.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Make the installer require a configured statusLine before treating hooks as already installed and ensure PowerShell 5.1 compatibility. hooks/install.ps1: stop using -AsHashtable, adjust hooks access, track presence of settings.statusLine and only skip installation when SessionStart, UserPromptSubmit and statusLine are present. hooks/install.sh: add HAS_STATUSLINE check and update the Node-based settings validation to require settings.statusLine. tests/test_hooks.py: add test_install_reconfigures_missing_statusline to verify installer adds a missing statusLine. tests/verify_repo.py: add a manifest path to the verification list and assert that -AsHashtable is not used in install.ps1 to preserve compatibility with Windows PowerShell 5.1.
Add a PowerShell statusline script (hooks/caveman-statusline.ps1) and update activation/installer logic to support Windows and avoid clobbering custom statuslines. install.sh and install.ps1 now check for a full set of hook files and wired hook entries before short-circuiting, wire a managed statusline path, and prefer not to overwrite user statusLine settings. Uninstall scripts now remove the managed statusline only when it was installed. caveman-activate.js updated to detect existing statusLine entries and emit a platform-appropriate snippet. Add tests (tests/test_hooks.py) and a local verification runner (tests/verify_repo.py) to validate install/uninstall/activation flows and caveman-compress fixtures. Also update README and caveman-compress docs and stats (token savings ~45%→~46%) and clarify auto-activation and statusline behavior.
Add Caveman Compress documentation to README (usage, how it works, preservation rules, benchmarks) and a new skills/caveman/SKILL.md defining caveman modes, intensity, and rules. Update .gitignore to more accurately ignore macOS .DS_Store files. Trim and adjust tests/caveman-compress fixtures to match compressed output format.