29 Commits
Author SHA1 Message Date
Julius BrusseeandClaude Opus 4.8 e2c09c9a7e docs: flatten savings claim to a flat 65% across all surfaces; bump PINNED_REF to v1.9.1
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
2026-07-03 13:07:25 +02:00
Julius Brussee 686c0cce64 Teaser; Caveman 2
(It'll be good)
2026-07-03 00:36:08 +02:00
Julius BrusseeandClaude Fable 5 e6cce23ed6 feat: bridge to Caveman Cloud — verified savings link in README + install summary
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
2026-07-02 15:33:28 +02:00
Julius Brussee 14eea5d5ee Merge PR #586: fix(install): avoid EXDEV cross-device link on claude plugin install (fixes #585)
# Conflicts:
#	bin/install.js
2026-07-02 14:55:21 +02:00
Julius Brussee cdb0d0c613 Merge PR #604: fix(install): treat spawn ENOENT as failure, not success (fixes #592)
# Conflicts:
#	tests/installer/e2e.freshinstall.test.mjs
2026-07-02 14:54:36 +02:00
Julius Brussee 9663344b79 Merge PR #607: fix(settings): string-aware trailing-comma removal in JSONC reader (fixes #595) 2026-07-02 14:52:58 +02:00
Julius Brussee d900443b84 Merge PR #605: fix(uninstall): match managed hook basenames, not substring (fixes #593) 2026-07-02 14:52:58 +02:00
Julius Brussee 5b875b8e2e Merge PR #609: fix(openclaw): stray SOUL.md marker no longer chains into data loss (fixes #596)
# Conflicts:
#	tests/installer/e2e.freshinstall.test.mjs
2026-07-02 14:52:49 +02:00
Julius Brussee 79a14ee79f Merge PR #610: fix(opencode): --force migrates legacy AGENTS.md, never wipes it (fixes #594) 2026-07-02 14:51:43 +02:00
AmirF194 516f917619 fix(opencode): --force migrates legacy AGENTS.md, never wipes it
--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
2026-07-01 23:52:36 -06:00
AmirF194 ae02d2a560 fix(openclaw): stray SOUL.md marker no longer chains into data loss
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
2026-07-01 23:50:28 -06:00
AmirF194 704a460ef8 fix(settings): string-aware trailing-comma removal in JSONC reader
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
2026-07-01 23:44:57 -06:00
AmirF194 70ea40dced fix(uninstall): match managed hook basenames, not substring
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
2026-07-01 23:34:41 -06:00
AmirF194 959b943ad4 fix(install): treat spawn ENOENT as failure, not success
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
2026-07-01 23:31:35 -06:00
Paul Jobson e0bb39f267 Fix for: https://github.com/JuliusBrussee/caveman/issues/585
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
2026-06-30 21:44:27 -04:00
Julius BrusseeandClaude Opus 4.8 e8139f86e3 fix(#524): make Hermes install/uninstall symmetric + verify against real Hermes
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>
2026-06-14 22:25:44 +02:00
Julius BrusseeandClaude Opus 4.8 6ebdb375c4 fix(#524): clean up Hermes provider entry
- 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>
2026-06-14 22:05:27 +02:00
Julius Brussee 62446eb525 Merge PR #524: add Hermes Agent install support 2026-06-14 22:03:00 +02:00
Ijtihed Kilani a325c64dd4 feat(cavecrew): add per-agent model overrides 2026-06-14 13:16:56 +03:00
vagesh 8753bf90d5 feat(install): add Hermes Agent support
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)
2026-06-14 12:29:42 +10:00
Julius BrusseeandClaude Opus 4.8 32f37af81a chore(release): pin remote fetches to v1.9.0
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>
2026-06-12 14:57:52 +02:00
Julius BrusseeandClaude Opus 4.8 f0dd780305 fix(install): Windows/Copilot/skills fixes, hook-wiring + MCP-shrink, security hardening
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>
2026-06-01 21:05:24 +02:00
Julius BrusseeandClaude Opus 4.7 63a91ecadb fix(install): force --yes --all on npx skills add (issue #370)
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>
2026-05-12 21:44:32 +02:00
Julius BrusseeandClaude Opus 4.7 754795ada4 fix(install): unbreak curl|bash one-liner (regression in v1.8.0)
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>
2026-05-10 16:04:44 +02:00
Julius Brussee e843518438 Improve installer idempotency and opencode fencing
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.
2026-05-10 15:50:33 +02:00
Julius BrusseeandClaude Opus 4.7 7b2bed2d0b feat(openclaw): add OpenClaw as a first-class agent target
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>
2026-05-10 15:18:00 +02:00
Julius BrusseeandClaude Opus 4.7 8b8068d8ca feat(opencode): native plugin replaces npx-skills fallback
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>
2026-05-10 15:08:17 +02:00
Julius Brussee 1ce38a2295 refactor: consolidate hooks/ rules/ tools/ mcp-servers/ under src/
Drops top-level entry count from ~26 to ~22 to align with conventions in
mature skill libraries (anthropics/skills, vercel-labs/skills). agents/,
commands/, skills/, and .claude-plugin/plugin.json stay at the repo root
because Claude Code auto-discovers them at the plugin root.

What moved:
  hooks/        → src/hooks/
  rules/        → src/rules/
  tools/        → src/tools/
  mcp-servers/  → src/mcp-servers/

Path references updated atomically in:
  - bin/install.js (HOOKS_REMOTE, INIT_SCRIPT_URL, repoRoot/sourceDir paths,
    user-facing install hints)
  - .claude-plugin/plugin.json (CLAUDE_PLUGIN_ROOT/src/hooks/...)
  - package.json files: array
  - tests/{test_hooks,test_symlink_flag,test_caveman_init,test_mcp_shrink,
    verify_repo}: bash/node command paths and require() args
  - tests/verify_repo.py: also drops the dead .cursor/.windsurf/.clinerules/
    copilot-instructions/caveman dotdir-mirror checks left behind by be714a3
    plus adds bin/install.js + bin/lib/settings.js regression guards
  - commands/caveman-init.toml prompt
  - src/mcp-servers/caveman-shrink/package.json repository.directory
  - CLAUDE.md, CONTRIBUTING.md, README.md, src/hooks/install.{sh,ps1},
    src/hooks/uninstall.{sh,ps1}, src/tools/caveman-init.js: docstrings,
    URL paths, source-of-truth tables

External raw.githubusercontent.com URL updates (referrers, blog posts) are
the maintainer's lane.
2026-05-10 14:26:11 +02:00
Julius Brussee 4f2314ae43 feat: land bin/install.js + JSONC settings helper + installer tests
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.
2026-05-10 14:11:17 +02:00