36 Commits
Author SHA1 Message Date
Julius Brussee ec7ce3614b Better install docs+scripts 2026-05-01 02:14:49 +02:00
Julius BrusseeandClaude Opus 4.7 56875e883f feat: stats receipts, smart installer, cavecrew, cavepack, MCP-shrink
- 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>
2026-05-01 01:36:18 +02:00
31fa95478d feat: /caveman-stats — real session token usage + savings estimate
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>
2026-05-01 01:14:53 +02:00
a660db02c9 fix(hooks): /caveman arg whitelist + symlinked-parent ~/.claude support
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>
2026-05-01 01:06:43 +02:00
b24b915e0a fix(windows): write PowerShell node script to temp file (#250)
PowerShell 5.1 mangles the multiline $nodeScript when passed to
node -e — the embedded `"` after `node ` terminates the argument
early, causing SyntaxError mid-install. Hook files copy but
settings.json never updates, leaving caveman non-functional.

Write the script to %TEMP%\caveman-install-<pid>.js, run it, clean
up in a finally block. Verified clean install on Windows 11 /
PowerShell 5.1 / Node 24.

Closes #249.

Co-Authored-By: Scott Converse <scottconverse@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 01:04:40 +02:00
Julius BrusseeandClaude Opus 4.6 5ad8f6d684 fix(security): harden flag-file reads and refuse sensitive-file compression
Writes were hardened via safeWriteFlag (PRs #70/#71) but readers still
trusted whatever the flag contained. A local attacker with write access
to ~/.claude/ could symlink the flag at a secret file and have the
per-turn reinforcement inject its bytes into model context, or the
statuslines echo ANSI escapes to the terminal on every keystroke.

- caveman-config.js: new readFlag() — lstat symlink refuse, 64-byte cap,
  O_NOFOLLOW, VALID_MODES whitelist. Returns null on any anomaly.
- caveman-mode-tracker.js: per-turn reinforcement routes through
  readFlag() instead of fs.readFileSync.
- caveman-statusline.sh / .ps1: symlink + size refuse, strip to
  [a-z0-9-], whitelist-validate before rendering.
- compress.py (3 synced copies): is_sensitive_path() denylist refuses
  .env*, .netrc, keys/certs, ~/.ssh|.aws|.gnupg|.kube|.docker, and any
  basename containing secret/credential/password/apikey/token/privatekey
  (separator-insensitive). Fails loudly before read — no silent exfil
  of credentials to the Anthropic API.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:49:26 +02:00
Julius Brussee d8d53115d0 fix(hooks): safeWriteFlag check immediate parent not full chain
Parent-chain walk produced false positives: macOS /tmp -> /private/tmp
and symlinked home dirs broke all flag writes. Check only the immediate
parent directory and the target itself — that covers the threat model
(attacker replacing the flag with a symlink) without breaking legit
paths.
2026-04-15 14:44:38 +02:00
Julius Brusseeandtuanaiseo 205e537103 Merge PR #71: strengthen safeWriteFlag with parent-chain check
Extend safeWriteFlag() in caveman-config.js with:
- hasSymlinkInPath() walks every ancestor component and refuses
  if any is a symlink (protects against parent-dir redirect)
- Atomic write via temp file + rename
- O_EXCL on temp open to prevent race

Removes duplicate local helper from mode-tracker.

Co-Authored-By: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com>
2026-04-15 14:44:38 +02:00
Julius Brusseeandtuanaiseo adafaba5cd Merge PR #70: symlink-safe flag file writes
Consolidate write protection into safeWriteFlag() helper in
caveman-config.js. Applied to all flag write sites:
- caveman-activate.js (SessionStart)
- caveman-mode-tracker.js slash command
- caveman-mode-tracker.js natural-language activation

Refuses symlink targets via lstat, opens with O_NOFOLLOW where
supported, writes with 0600.

Co-Authored-By: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com>
2026-04-15 14:44:34 +02:00
Julius Brussee e50325b040 Merge PR #119: per-turn reinforcement in UserPromptSubmit 2026-04-15 14:44:20 +02:00
Julius Brussee 23ce800ad6 Merge PR #120: natural language activation/deactivation 2026-04-15 14:44:20 +02:00
Julius Brussee 4345efd45a Merge PR #146: respect CLAUDE_CONFIG_DIR 2026-04-15 14:27:23 +02:00
Dmitrii Malakhov b50aa6d4b3 fix: isolate hooks as CommonJS so they survive ESM parent package.json
When ~/.claude/package.json (or any ancestor) contains "type": "module",
Node treats every .js file under that tree as an ES module. The caveman
hooks use require() and crash with:

  ReferenceError: require is not defined in ES module scope

surfaced as:

  SessionStart:clear hook error / UserPromptSubmit hook error
  Failed with non-blocking status code: .../caveman-activate.js:9

This pins the hooks directory to CommonJS via a local package.json, so
module resolution no longer depends on whatever the user's ~/.claude
directory declares. Also wires the new file into install/uninstall
scripts so standalone installs (curl | bash / Invoke-WebRequest)
copy it into ~/.claude/hooks/ alongside the JS files.

Addresses the ESM sub-case flagged in #167 (comment by mrx-arafat).
Does not fix the Windows path-with-spaces expansion issues in #167/#78/#72
which have a separate root cause in plugin.json ${CLAUDE_PLUGIN_ROOT}
quoting.
2026-04-15 10:49:52 +02:00
Brendan Izu 7b4649fad0 fix: respect CLAUDE_CONFIG_DIR env var across all hooks
All hook files hardcoded ~/.claude as the Claude config directory.
Users who set CLAUDE_CONFIG_DIR (e.g. for XDG compliance) had hooks
writing to the wrong location. Now all hooks check CLAUDE_CONFIG_DIR
first, falling back to ~/.claude.

Closes #140
2026-04-13 21:21:48 -07:00
Matthias HumtandClaude Opus 4.6 f7ef823b91 fix: guard natural language activation against off default mode
Mirror the /caveman command path: skip writing flag file when
getDefaultMode() returns 'off'. Without this, "talk like caveman"
with CAVEMAN_DEFAULT_MODE=off would write 'off' to the flag file,
making statusline/reinforcement inconsistent.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:19:09 +02:00
Matthias HumtandClaude Opus 4.6 4c6dad829a fix: skip reinforcement for independent modes (commit/review/compress)
Independent modes have their own skill behavior — emitting base caveman
rules ("Drop articles, fragments OK") on every turn conflicts with the
specialized format those modes expect.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:18:45 +02:00
Matthias HumtandClaude Opus 4.6 56f4047ab3 fix: detect natural language activation/deactivation in mode tracker
README tells users they can say "talk like caveman" to activate, but the
UserPromptSubmit hook only matched /caveman commands. This meant the flag
file and statusline badge stayed out of sync when users activated via
natural language — the model would speak caveman (it reads the prompt)
but the hook never wrote the flag file.

Now matches: "activate caveman", "turn on caveman mode", "talk like
caveman", "disable caveman", "turn off caveman", etc. Uses a negative
guard so "stop caveman" doesn't trigger activation first.

Uses getDefaultMode() for natural language activation to respect
CAVEMAN_DEFAULT_MODE and config.json, same as /caveman command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:12:11 +02:00
Matthias HumtandClaude Opus 4.6 3ed7b732b0 fix: add per-turn reinforcement to UserPromptSubmit hook
The SessionStart hook injects caveman rules once, but models lose them
when other plugins (output styles, learning modes) inject competing
style instructions on every turn. Recency and repetition win in LLM
attention — a one-shot injection loses to per-turn reinforcement.

Emit a short structured reminder via hookSpecificOutput on every user
message when caveman is active. Uses the same JSON format Claude Code
expects from hooks, keeping the full ruleset from SessionStart in
context while this reminder keeps it top-of-mind.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 13:11:15 +02:00
Julius Brussee 600e8efcd6 Load SKILL.md; handle independent modes
Replace hardcoded intensity table and examples with runtime loading of skills/caveman/SKILL.md (single source of truth). Strip YAML frontmatter and filter the intensity table and examples to include only the active mode; fall back to a minimal built-in ruleset when SKILL.md is missing (standalone installs). Add INDEPENDENT_MODES (commit, review, compress) to short-circuit and emit a brief activation line for modes that use their own skill files. Normalize the wenyan alias to wenyan-full. Overall simplifies maintenance and prevents duplicated, stale rule text in the hook.
2026-04-12 00:17:07 +02:00
Julius Brussee 80a317e472 Expand caveman ruleset and add intensity levels
Replace the terse one-line caveman activation message with a full, structured ruleset and examples. Introduces INTENSITY and EXAMPLES maps (lite/full/ultra + wenyan variants), selects the active level from mode with a fallback, and builds a detailed output covering persistence, rules, examples, auto-clarity and boundaries. Rationale: anchor terse response behavior more reliably to prevent drift and provide selectable verbosity/compression profiles while preserving exact code/commit formatting.
2026-04-12 00:11:14 +02:00
Julius BrusseeandClaude Opus 4.6 8bab5c739e fix: prevent /caveman from writing "off" to flag file
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>
2026-04-11 18:27:41 +02:00
Julius BrusseeandClaude Opus 4.6 c80f8d7fe1 feat: add "off" default mode to disable auto-activation
Set CAVEMAN_DEFAULT_MODE=off or {"defaultMode":"off"} in config to
skip session-start activation. No flag file written, no rules injected.
User can still manually activate with /caveman.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:23:42 +02:00
Julius BrusseeandClaude Opus 4.6 ea89000141 feat: make default caveman mode configurable
Add caveman-config.js shared config resolver. Default mode resolves via:
CAVEMAN_DEFAULT_MODE env var > XDG config file > 'full'.

Updated all install/uninstall scripts (bash + PowerShell) and tests.

Closes #86

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 17:56:45 +02:00
Julius Brussee 8783f63296 Require statusLine and fix PS5.1 parsing
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.
2026-04-11 12:22:07 +02:00
Julius Brussee 7e2c94c541 Add Windows statusline & robust hook install
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.
2026-04-11 12:14:46 +02:00
Julius Brussee 8fb2f013a9 Improve hooks safety, validation, and docs
Make several robustness and clarity fixes across scripts and docs:

- README: Clarify agent-specific behavior (Codex, Cursor/Windsurf) and note Codex uses $caveman and lacks some bundled plugins.
- caveman-compress: Avoid division-by-zero when computing token savings; skip unclosed markdown fences when extracting code blocks to prevent false positives.
- hooks (install/uninstall, PowerShell and shell): Pass settings and hooks paths via environment variables to avoid injection issues with special characters, quote generated command paths, use safer here-strings in PowerShell, and ensure settings.json is written via the resolved path. Also remove installer backup files during uninstall and add explanatory comments.

These changes improve security, correctness, and developer-facing documentation.
2026-04-11 11:59:05 +02:00
Julius Brussee 79fa46a4a0 Add windsurf skill, hooks, and install docs
Add .windsurf/skills/caveman SKILL.md and update the sync workflow to copy and commit the new file. Expand README install docs with agent-specific install instructions and standalone hook usage; update AGENTS.md and GEMINI.md to use the new caveman-compress path. Add Windows PowerShell installers (hooks/install.ps1 and hooks/uninstall.ps1) and enhance shell installers (hooks/install.sh, hooks/uninstall.sh) to support --force, plugin detection, clearer statusline wiring messages, and idempotent JSON merging/removal of hook entries. Provides uninstall guidance for other agents and improves overall install/uninstall robustness.
2026-04-11 11:30:34 +02:00
Julius Brussee cfd76590bd Add statusline badge, hooks, and compress fixes
Add statusline support and installer/uninstaller hooks, improve compression tooling and docs. Key changes:

- Add caveman statusline badge script (hooks/caveman-statusline.sh) and wire it into install/uninstall (hooks/install.sh, hooks/uninstall.sh); installer now requires node, backs up settings.json, and makes the statusline executable.
- Enhance SessionStart hook (hooks/caveman-activate.js) to detect missing statusline config and emit a setup nudge; update hooks README with statusline usage and setup instructions.
- Add gemini-extension.json, AGENTS.md, and GEMINI.md to register skills and support Gemini CLI installation.
- Update README to mention statusline badge, Gemini CLI install, and agent list.
- Improve caveman-compress: rename skill (caveman-compress), clarify CLI path/usage in SKILL.md, return on validation failure without overwriting, bump benchmark encoding, and make compressor robust to LLM outer fences by stripping wrapping fences and expanding max_tokens; add explicit rule to avoid wrapping entire output in fences.
- Strengthen code-block extraction in validate.py to handle variable-length fences (```/~~~), nested fences, and CommonMark rules.
- Minor SKILL.md tweak: resume caveman mode when user asks to clarify or repeats question.

These changes integrate a visible status badge for Claude Code users, improve install/uninstall reliability, extend Gemini support, and make the compressor/validator more robust when interacting with LLM outputs.
2026-04-11 11:15:03 +02:00
tuanaiseo 5580f8e28f fix(security): mode tracker flag file write also vulnerable to sy
The UserPromptSubmit hook similarly writes to `~/.claude/.caveman-active` without checking whether the path is a symlink. This duplicates the same local file-clobber risk in another execution path.

Affected files: caveman-mode-tracker.js

Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com>
2026-04-10 20:34:08 +07:00
tuanaiseo 7906016383 fix(security): hook writes to predictable path without symlink pr
The SessionStart hook writes to `~/.claude/.caveman-active` using `fs.writeFileSync` on a predictable path. If that path is replaced with a symlink, Node will follow it and overwrite the symlink target. A local attacker (or another process running as the same user) could abuse this to modify unintended files writable by the user.

Affected files: caveman-activate.js, caveman-mode-tracker.js

Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com>
2026-04-10 20:33:24 +07:00
tuanaiseo 9449c8a05a fix(security): hook writes to predictable path without symlink pr
The SessionStart hook writes to `~/.claude/.caveman-active` using `fs.writeFileSync` on a predictable path. If that path is replaced with a symlink, Node will follow it and overwrite the symlink target. A local attacker (or another process running as the same user) could abuse this to modify unintended files writable by the user.

Affected files: caveman-activate.js, caveman-mode-tracker.js

Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com>
2026-04-10 20:33:23 +07:00
Julius Brussee 1be0340955 Add plugin hooks and update docs
Register SessionStart and UserPromptSubmit hooks in .claude-plugin/plugin.json to auto-load caveman rules and track active mode (writes to ~/.claude/.caveman-active). Update README and hooks/README.md to reflect automatic activation when installed as a plugin, remove the one-line install snippet, clarify the optional statusline badge, and adjust uninstall instructions (replace PostToolUse with UserPromptSubmit and note disabling the plugin deactivates hooks).
2026-04-09 21:22:10 +02:00
Julius Brussee 602d1639c6 Use UserPromptSubmit for caveman mode tracking
Switch caveman mode tracking from PostToolUse to UserPromptSubmit: update README to document the new hook, adjust caveman-mode-tracker.js to read the incoming `prompt` field (removing `user_prompt`), and modify install.sh to register the UserPromptSubmit hook with timeouts and status messages (and add a timeout/status for the activate hook). This ensures mode detection runs on every user prompt and prevents hook stalls by setting command timeouts and status text. Files changed: hooks/README.md, hooks/caveman-mode-tracker.js, hooks/install.sh.
2026-04-09 21:14:43 +02:00
Julius Brussee a9e62b48c3 Add mode-tracker hook and update install/docs
Add a new caveman-mode-tracker.js hook to track active /caveman modes and write them to ~/.claude/.caveman-active (supports full/lite/ultra/wenyan/commit/review/compress and detects deactivation). Update caveman-activate.js to write 'full' to the flag file on SessionStart. Enhance hooks/install.sh to install both hooks and idempotently wire SessionStart and UserPromptSubmit hooks into ~/.claude/settings.json. Revise hooks/README.md and top-level README.md to document the two hooks, improved statusline badge snippet (shows [CAVEMAN] or [CAVEMAN:MODE]), and how the flag file bridges hooks and the statusline. Minor SKILL.md whitespace/newline cleanups.
2026-04-09 21:09:56 +02:00
Julius Brussee 4e919547fb Add Claude SessionStart hook installer and docs
Replace the long README hook section with a concise "Auto-Load Hook (Claude Code only)" install hint and link to new docs. Add hooks/README.md documenting the optional SessionStart hook, statusline badge, and quick install. Add hooks/install.sh: a one-command installer that copies or downloads caveman-activate.js into ~/.claude/hooks, idempotently wires a SessionStart entry into ~/.claude/settings.json (using node), and prints usage/uninstall notes. Restart Claude Code to activate the hook.
2026-04-09 20:53:28 +02:00
Jimmy CrakCrn a62d6602c3 feat: optional SessionStart hook + visible statusline badge pattern
Adds hooks/caveman-activate.js — an optional Claude Code SessionStart
hook users can wire up via ~/.claude/settings.json to auto-load the
caveman ruleset at session start. The hook also writes a flag file
at ~/.claude/.caveman-active that a statusline script can read to
render a persistent [CAVEMAN] badge.

Why: SessionStart hook stdout is injected as hidden system-reminder
context — useful for Claude, invisible to users in the terminal. This
means users have no way to confirm the hook fired. The flag file is
a minimal bridge between 'the hook ran' and 'the statusline can
prove it', giving users persistent visual confirmation that caveman
mode is loaded.

This is a pure addition:

- New file: hooks/caveman-activate.js (~30 lines, no dependencies
  beyond Node.js stdlib)
- README section 'Optional: SessionStart Hook + Visible Mode Badge'
  documents both the hook install and the statusline snippet
- Marked Claude Code-only since it relies on Claude Code's hooks
  and statusline mechanisms — Cursor/Codex/other users can ignore
- No existing files changed except README

If you don't wire up the hook, nothing changes. Skill install works
exactly as before.
2026-04-09 07:37:18 -05:00