First tag shipping src/hooks/checksums.sha256 — with PINNED_REF now
pointing at it, curl|bash / detached installs fetch hook files from the
immutable v1.9.0 ref and SHA-256 enforcement activates fully (#261,
#262). Manifest verified current against src/hooks/ before the bump.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Smoke-tested against real opencode 1.4.0 (the missing verification
flagged in 22f75e3) — the plugin never loaded: opencode runs plugins
inside a compiled Bun binary where require() of on-disk files is
rejected ('require() async module is unsupported') and await import()
of a CJS file returns an empty namespace. caveman-config.cjs is now
evaluated as CommonJS by hand (readFileSync + Function wrapper with a
createRequire shim — built-ins still resolve fine).
Three more real-runtime gaps found and fixed in the same pass:
- session-init flag write now also happens at plugin factory time; in
one-shot 'opencode run' the first session.created publishes before
plugin event dispatch is wired, so the event handler alone missed it
- the TUI expands '/caveman <level>' into the command template before
chat.message fires; the parser now recovers the level from the
expanded 'Activate caveman mode: <level>' text
- the non-interactive run path wraps messages in literal quotes
('"/caveman ultra"'); the parser unwraps symmetric quotes
Verified end-to-end against opencode 1.4.0: plugin loads clean,
session-init writes the flag, /caveman ultra flips it, 'stop caveman'
deletes it, and the reinforcement line shows up in the outgoing LLM
system prompt.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Counts were stale after the opencode + openclaw targets landed (5 -> 6
repo files, 7 with the openclaw line). Tests also ran the openclaw
installer against the developer's real ~/.openclaw/workspace; runInit()
now pins OPENCLAW_WORKSPACE inside the fixture tmp dir so nothing
escapes the sandbox. verify_repo.py drops the removed
.agents/plugins/marketplace.json from its manifest list.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
.junie/, .kiro/, .roo/, .agents/ held pre-cleanup cavecrew/SKILL.md
mirrors (plus an unused .agents/plugins/marketplace.json). Nothing in
the current install path reads them — bin/install.js handles Codex via
npx skills add, and Claude Code marketplace discovery uses
.claude-plugin/marketplace.json. CLAUDE.md marks these remove-on-sight.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Sponsors section to README promoting Atlas Cloud with a centered logo, link, and a call to sponsor the project. Include two new SVG assets (atlas-cloud.svg and atlas-cloud-dark.svg) under docs/assets for light/dark mode logo display.
Verbatim copies of edited sources into the CI-managed plugins/caveman mirror and rebuilt dist/caveman.skill, so local main is self-consistent without a push. CI's sync-skill.yml regenerates these on push; this just keeps verify_repo green locally.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #419 (replace the non-existent session.created/tui.prompt.append hooks with real opencode hooks: event dispatcher for session.created, chat.message for mode parsing, experimental.chat.system.transform for reinforcement; fixes #418/#421), #398 (ship the missing caveman-compress.md command + un-ignore it; fixes #426/#451/#464), and #376 plugin-side (drop %APPDATA% branch). Smoke test rewritten for the new hook shapes. NOTE: not smoke-tested against a real opencode runtime here — verify before release.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Installer fixes: #414 (rename PS1 $Args->$InstallerArgs), #437 (detect Copilot via extension dirs, fixes#336), #395 (--skill '*' instead of --all so -a <agent> is honored, fixes#389), #472 (prune orphaned managed hooks from settings.json, fixes#471), #393 (don't double-wire hooks when the plugin manifest already does, fixes#392), #380 (MCP-shrink off by default, requires an upstream, fixes#474), #376 install-side (opencode uses ~/.config/opencode, drop %APPDATA%), #443 (strip tools: from cavecrew agent copies for opencode, #386), #434 (existsSync guard on command copy), #396 (doc: discover profile slugs via --list).
Security hardening: #261 (pin remote fetch to release tag PINNED_REF=v1.8.2, not moving main) and #262 (SHA-256-verify downloaded hook files against src/hooks/checksums.sha256 before they execute; abort on mismatch). #260 (inspect-before-run note). NOTE: enforcement activates fully once a release tag shipping checksums.sha256 is published and PINNED_REF is bumped; v1.8.2 predates the manifest so downloads there warn-and-proceed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #429 (repo-local <repo>/.caveman/config.json resolution layer between env and user config; symlink-safe, bounded walk) and #248 intent (recognize 'less tokens'/'be brief'/'be terse' as natural-language caveman activation).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #387 — extract spawn options to spawn-options.js; shell:true only on win32 (PATHEXT resolution), POSIX unchanged. Args still come from installer-controlled config (trust boundary unchanged).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #438 — the docs demo terminal interpolated user input via innerHTML (real reflected/DOM XSS); build nodes with textContent instead. (PR title 'CLI input handler' was a misnomer.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #466 (correct Opus 4.5-4.8 output price to $25/M, keep legacy 4.0/4.1 carve-outs at $75/M; fixes#465) and #459 (UTF-8 console + Get-Content so the pickaxe renders on Windows; +spacing).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Folds in #388 (pin claude subprocess to utf-8, fixes#152 Windows cp1252 crash), #435 (resolve claude via shutil.which for .cmd shims), #424 (preserve YAML frontmatter across compression), #420 (write .original.md backups outside the source tree; cross-platform base dir incl. Windows %LOCALAPPDATA%).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the top-of-README alert banner with a centered callout card
placed right after the savings proof, where the reader is most sold.
Cross-sells caveman-code (the full terminal coding agent) on the
momentum of the compression demo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a prominent caveman-code callout to the README hero and a
caveman-code row to the ecosystem table. Swap the rock emoji for
the dancing-rock SVG logo across the README, the compress skill
README, and the docs-site cursor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
curl|bash one-liner stdin is not a TTY, so the upstream skills CLI
renders its interactive skill-picker TUI with nothing selected, exits
0, and installs zero skills — while our installer reports "done".
Pass --yes --all to skip the picker and confirmation prompts in both
the per-provider call and the auto-detect fallback.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- PR #372 (Dave): strip YAML fences from commands/caveman-init.toml — Gemini CLI's FileCommandLoader rejected the file with 'Failed to parse TOML' on extension install. Verified main was broken.
- PR #350 intent (David): rename codex_hooks → hooks in .codex/config.toml. Codex source confirms canonical key is now 'hooks'; codex_hooks is a legacy alias that emits a deprecation log.
Closes#372#326 (duplicate) #350 locally — push deferred.
Codex's CodexHooks feature now exposes key 'hooks' (Stable). codex_hooks
kept as legacy alias in codex-rs/features/src/legacy.rs but emits a
deprecation log. Match the canonical name.
Verified against openai/codex codex-rs/features/src/lib.rs:
FeatureSpec { id: Feature::CodexHooks, key: "hooks", stage: Stage::Stable, default_enabled: true }
Co-Authored-By: David <davidbits@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two bugs at the curl|bash entry point made the headline install command
fail immediately:
1. install.sh used `${BASH_SOURCE[0]}` under `set -u`. That variable is
unset when bash is invoked from stdin (curl | bash), tripping the
nounset trap before we ever reached the npx fallback.
2. install.sh + install.ps1 passed `--` between npx and the package args.
On modern npm, npx forwards the literal `--` to bin/install.js, which
parseArgs rejected as an unknown flag.
Fix:
- install.sh: default BASH_SOURCE[0] to empty so the curl-pipe path falls
through cleanly under set -u.
- install.sh + install.ps1: drop the `--` separator. npm 7+ npx already
forwards trailing args correctly.
- bin/install.js parseArgs: accept a bare `--` as a no-op (POSIX
end-of-options marker) so future shim drift can't re-break this.
- New regression test asserts `--` is accepted.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Refactor and harden the unified Node installer and related docs. Major changes:
- bin/install.js: validate --only ids, expand ~ for --config-dir, make Claude/install flows async (await hooks/init), add many CLI flags (--no-mcp-shrink, --with-hooks/--no-hooks, --skip-skills, --config-dir docs), preserve original backups once, avoid overwriting plugin/command files unless --force, and add opencode AGENTS.md fenced begin/end markers so installs/uninstalls can append/strip cleanly. Also add opencode idempotency probes for claude/gemini uninstall paths and better handling of opencode plugin payload.
- bin/lib/settings.js: safer removeCavemanHooks that validates shapes before mutating hooks.
- runInit/installHooks/downloadTo calls made async and awaited; runInit returns promise now.
- Docs and README/INSTALL/CONTRIBUTING/CLAUDE.md/src/hooks/README.md: update user-facing text to match new flags/behaviour, standardize use of $CLAUDE_CONFIG_DIR, clarify --with-init semantics, and note opencode/openclaw handling. Change command name usages from `/caveman:compress` to `/caveman-compress`.
- opencode: write fenced caveman block to AGENTS.md and handle legacy unfenced blocks; tests updated to expect fence markers.
These changes improve idempotency, safer upgrades/uninstalls, clearer UX around per-repo vs per-user init, and make the opencode rule block removable without destroying user content.
OpenClaw is a self-hosted gateway that orchestrates multiple agents and
loads workspace skills on-demand. To make caveman always-on through it we
write a spec-correct skill folder plus a marker-fenced bootstrap block in
SOUL.md (which OpenClaw auto-injects every turn). Both writes are
idempotent and reachable from `bin/install.js --only openclaw` and
`caveman-init.js --only openclaw`. Side-effect: `--only <id>` now bypasses
the detect-match guard so explicit opt-in works for any provider whose
preconditions can't be probed (e.g. custom OPENCLAW_WORKSPACE paths).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces opencode's Tier-4 npx-skills entry with a native in-repo plugin
that mirrors the Claude Code hook architecture (session.created +
tui.prompt.append) using opencode's lifecycle hook system. Reaches Tier-1
parity minus the statusline (opencode TUI exposes no plugin-writable
badge). Skill files drop in unchanged — opencode reads SKILL.md natively.
Plugin reuses src/hooks/caveman-config.js for the symlink-safe flag-write
helpers via createRequire (renamed .cjs post-install to coexist with the
plugin dir's "type":"module"). AGENTS.md provides a Tier-3 always-on
fallback if the plugin runtime breaks.
5 new tests cover fresh install, idempotency, JSONC tolerance of
pre-existing opencode.json, uninstall, and a plugin smoke test that fires
synthetic tui.prompt.append events. All 38 installer tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings the long-stashed Node installer onto main. install.sh and install.ps1
shrink to thin shims (~50 lines each) that delegate to bin/install.js, fixing
the cross-platform drift that caused #249-class quoting bugs.
- bin/install.js (850 lines) — unified PROVIDERS-driven installer
- bin/lib/settings.js (221 lines) — JSONC parser + hook validator
(validateHookFields prevents single bad hook from poisoning settings.json)
- tests/installer/{unit.argv,unit.settings,e2e.dryrun}.test.mjs — npm test
now actually runs four real tests (was silently passing 0)
- .agents/skills/cavecrew, .junie/, .kiro/, .roo/ — per-agent skill mirrors
- skills-lock.json — vercel-labs/skills slug pinning
- install.{sh,ps1}.legacy escape hatch dropped (git history is the fallback)
- Minor cavecrew agent description refinements
Closes the gap between docs (already merged) describing bin/install.js and
the actual implementation.
Reflect the post-cleanup repo layout: consolidated caveman-compress
under skills/, removed agent-dotdir mirrors, build artifacts in dist/,
per-skill READMEs alongside SKILL.md, bin/install.js as the only
installer entry point, and INSTALL.md for the per-agent reference.
Adds a top-level "What lives where" tree, trims the auto-synced table
to what CI actually mirrors, and updates the key rules accordingly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Real install harness — writes hooks, merges settings.json, asserts on-disk
state. Catches regressions a dry-run can't see (missing hooks, malformed
settings, broken statusline). Five cases:
- Fresh install populates hooks dir + wires SessionStart/UserPromptSubmit
- Idempotent install does not duplicate hook entries
- Uninstall strips caveman hooks, preserves user-authored ones
- Install tolerates JSONC settings.json (#249 regression guard)
- Lib-level addCommandHook idempotency (always runs, no claude CLI)
Tests requiring `claude` on PATH skip cleanly with a clear reason. Uninstall
test strips claude/gemini from PATH so the user's real plugin/extension
state is never touched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Trim README from 16.4 KB to 10.2 KB (~38% shorter, 331 -> 220 lines)
so non-technical readers can scan it in 60 seconds. Front door now
keeps the Before/After pitch, one-line install, top-6 manual install
table, condensed feature matrix, real benchmark numbers, and a short
"how it work" section in caveman voice.
Moves to other docs:
- Full 30+ agent install matrix and detailed flag reference -> INSTALL.md
- Hook architecture deep-dive -> CLAUDE.md (already there)
- Eval methodology paragraphs -> evals/ link
Caveman voice phrases preserved ("Brain still big", "Cost go down
forever", "One rock. Two rock. Three rock. That it.", "caveman speak").
Benchmark numbers untouched (verbatim from benchmarks/results/). All
top-of-funnel install commands still work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drop CI-generated mirrors that self-applied caveman to this repo when
opened in Cursor/Windsurf/Cline/Copilot. The installer never read them
(bin/install.js consumes only hooks/, rules/, tools/, agents/, skills/,
mcp-servers/, plugins/caveman/), so removing them just declutters the
root. Devs who want self-application can opt in via npx caveman --only
<agent>.
Removed:
- .cursor/skills/, .cursor/rules/caveman.mdc
- .windsurf/skills/, .windsurf/rules/caveman.md
- .clinerules/caveman.md
- .github/copilot-instructions.md
- caveman/SKILL.md (and empty caveman/ parent)
Updated .github/workflows/sync-skill.yml: drop the cp + mkdir lines and
git add paths for those mirrors, drop the entire "Sync auto-activation
rules" step, and drop rules/caveman-activate.md from the paths: trigger
since the workflow no longer consumes it. plugins/caveman/, cavecrew,
compress, and caveman.skill ZIP sync steps are preserved.
Updated CONTRIBUTING.md note to reflect the smaller auto-synced set.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Move caveman-compress/ source (SKILL.md, scripts/, README.md, SECURITY.md) to skills/caveman-compress/.
- Delete skills/compress/ — the CI-generated rename mirror that caused dual-source confusion.
- Move plugins/caveman/skills/compress/ to plugins/caveman/skills/caveman-compress/. Plugin keeps the consolidated name; CI no longer rewrites the frontmatter.
- Replace the two sed-heavy CI sync steps with one verbatim cp -r from source to plugin.
- Update verify_repo.py, test_compress_safety.py, test_validate_inline.py, GEMINI.md, AGENTS.md, CONTRIBUTING.md, README.md, and the workflow paths to reference the new location.
- Use Path.resolve().parents[N] for the benchmark.py repo-root walk now that the directory depth changed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expand the 25-line stub to a scannable 190-line guide reflecting the
post-cleanup repo layout. Adds:
- Sources-of-truth table covering all editable skill, agent, hook, and
installer files (skills/caveman-compress/, bin/install.js PROVIDERS,
tools/caveman-init.js, mcp-servers/caveman-shrink/).
- CI-mirrors table calling out plugins/caveman/* and dist/caveman.skill
as auto-rebuilt, edits-will-be-reverted.
- Step-by-step recipes for adding a new agent (PROVIDERS row +
--list verification) and a new skill (frontmatter + sync workflow).
- Test commands (npm test, compress safety, init, symlink), benchmark
and eval invocations, PR guidelines, and the load-bearing code-style
invariants (silent-fail hooks, JSONC-tolerant settings.js,
safeWriteFlag, CLAUDE_CONFIG_DIR).
Preserves caveman voice in the framing and Ideas section.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Splits install guidance out of README into a dedicated INSTALL.md so
users can find the install path in one glance. Covers the one-liner,
per-agent table for all 33 providers, manual install, verify, uninstall,
troubleshooting, and a privacy note. README and installer source are
unchanged.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The caveman.skill ZIP is regenerated by CI on every push and lived at
the repo root, where users mistook it for an editable source. Moving it
to dist/ makes its build-product nature obvious while keeping it
tracked so GitHub release links and npm packaging keep working.
Updates:
- git mv caveman.skill -> dist/caveman.skill
- .github/workflows/sync-skill.yml rebuild step now writes to dist/
- .gitignore ignores dist/* but allows dist/caveman.skill
- package.json files array includes dist/caveman.skill for npm pack
- CONTRIBUTING.md and tests/verify_repo.py path references updated
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a human-facing README.md to each skill directory so users browsing
skills/ can quickly see what each skill does, how to invoke it, and an
example output. Mirrors the per-skill README pattern used by upstream
skill libraries (vercel-labs/skills, claude-code-sdk).
SKILL.md remains the LLM-facing system prompt; README.md is the human
front door.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CLAUDE.original.md was a backup snapshot from the initial caveman-compress
of the project's own CLAUDE.md. It is not referenced by any tooling — the
mentions in caveman-compress/README.md and tests/test_caveman_stats.js
describe the compress skill's output naming convention, not this file.
The other deletion targets from the cleanup brief (install.sh.legacy,
install.ps1.legacy, .junie/, .kiro/, .roo/, .agents/) either don't exist
in this branch or — in the case of .agents/plugins/marketplace.json — are
real manifests verified by tests/verify_repo.py.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
caveman-shrink@0.1.0 is now live on npm (pre-1.0). Restore the original
default-on behavior for --with-mcp-shrink / -WithMcpShrink. Keep the
`npm view caveman-shrink` probe — a transient registry outage now degrades
to a clean manual-config skip instead of registering a `npx -y caveman-shrink`
entry that would have spawned-failed.
Also: sync `model: haiku` onto cavecrew investigator/reviewer canonicals
so the top-level agents/ matches the synced plugins/caveman/agents/.
README + CLAUDE.md flipped back to "On by default."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>