Replace the ~50-65% range and the ~50%-vs-terse figure with a single 65%
(the measured average output reduction vs verbose baseline) on every product
surface: README hero + ASCII card + benchmark blurb, plugin.json,
marketplace.json, gemini-extension.json, caveman SKILL.md + skill README,
caveman-init rule frontmatter, and the docs site (index.html telemetry widget
+ marquee still showed the old 75%). Trim HONEST-NUMBERS.md to match. Raw
benchmark/eval snapshots and the eval-harness methodology docs are untouched.
Bump PINNED_REF v1.9.0 -> v1.9.1 so the standalone hook-download fallback
fetches cavecrew-model-overrides.js from the release tag instead of 404ing.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0163QczkBHKpYgxx3sBc7X3b
README gets a two-line Caveman Cloud section near the bottom; the
installer summary now points at /caveman-stats (labeled estimates)
and getcaveman.dev. One link, one honest sentence each — local
numbers are estimates, Cloud measures and verifies them.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011kmm2umRGb5nLxdimrwweZ
--force on an AGENTS.md containing the legacy un-fenced sentinel
replaced the entire file with the fenced block — destroying all
user-authored content around the legacy block. The installer's own
hint told users with mixed files to run exactly that.
Migrate instead: back up once to AGENTS.md.bak, remove the legacy
block (exact match of the current rule body when possible, otherwise
cut from the sentinel's paragraph start — the legacy path appended the
block, so user content precedes it), and write the fenced block after
the preserved user content.
Fixes#594
A truncated/stray marker (interrupted write, partial user edit) chained
into deleting user content: appendBootstrapToSoul saw 'no complete
block' and appended a second one; stripBootstrapFromSoul then cut from
the FIRST begin to the FIRST end — spanning everything between the
stray marker and the appended block. Reported reproduction ended with
the whole SOUL.md deleted.
Replace the single-span cut with a scan that pairs each begin with the
nearest end before the next begin; unpaired markers are removed as just
the marker text, never as a span. Append now detects damaged markers
(orphans, duplicates), strips them safely, and writes one clean block.
Fixes#596
The trailing-comma sweep ran a global regex over the whole
comment-stripped output, including string contents — a JSONC
settings.json with a value containing ',}' or ',]' (shell brace
expansion, inline JSON in hook args) was silently corrupted on read
and persisted corrupted on the next write.
Replace the regex with a scan that tracks string state (same approach
as the comment stripper above it) and only drops commas outside
strings.
Fixes#595
removeCavemanHooks stripped any settings.json hook whose command
contained the substring 'caveman' anywhere — a user-authored hook like
'node ~/Projects/caveman-notes/my-hook.js' was silently deleted by
--uninstall.
Match tokens against MANAGED_HOOK_BASENAMES by exact basename instead
(win32.basename so Windows-written configs match anywhere), the same
pattern pruneOrphanedManagedHooks already uses. Hoist the tokenizer to
module scope and reuse it in the prune pass. Add caveman-statusline.ps1
to the managed set so the Windows statusline wiring is covered by
removal and orphan-pruning too.
Fixes#593
spawnSync reports a missing binary as { status: null, error }, and the
(r.status || 0) === 0 checks coerced that null to success. On a machine
without the claude CLI, --only claude printed 'installed: claude',
skipped the standalone-hook fallback (which works offline), and left
nothing installed. Same pattern at 8 sites: claude, gemini, npx-skills
providers, mcp-shrink, runInit (both paths), uninstall, skills-auto.
Route every spawn result through spawnOk() (!r.error && r.status === 0)
and warn when the claude CLI itself could not be spawned. Regression
test runs the installer with an empty PATH and asserts failure is
reported and standalone hooks get wired.
Fixes#592
This fixes the edge case for the following error by instantiating the
paths differently.
✘ Failed to install plugin "caveman@caveman": EXDEV: cross-device link not permitted
Adversarial review against a live Hermes Agent install (v0.11.0) found the
forward install was correct (skills land in the real ~/.hermes/skills/
productivity/<skill>/ layout, all 7 load as 'enabled' via 'hermes skills
list' — verified empirically, no version: field required), but uninstall had
NO Hermes handling: --uninstall silently orphaned all 7 skill folders forever.
- add Hermes block to uninstall() honoring HERMES_HOME (mirrors opencode/openclaw)
- tests/installer/hermes.test.mjs: install lands 7 skills, uninstall removes
them (regression guard for the asymmetry), dry-run uninstall is a no-op
- INSTALL.md: add Hermes Agent row to the per-agent install table (CLAUDE.md
mandates the install table stay complete)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- restore 2-space PROVIDERS indent and 4-space dispatch-loop indent (PR
re-indented existing gemini/opencode/openclaw lines as churn)
- correct mech label: 'native hermes skills copy' (it does a native dir
copy via installHermes, not 'npx skills add')
- drop dead profile: 'hermes' — shadowed by the installHermes special-case
and not a valid upstream vercel-labs/skills slug
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds Hermes Agent as a supported provider with native skill installation.
Hermes Agent uses SKILL.md format (same as upstream), so the installer
copies all 7 caveman skills directly to ~/.hermes/skills/productivity/.
Closes#45914 (related)
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>
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>
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>
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.