npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@chiefmojo/cavemem

v0.4.3

Published

Cross-agent persistent memory with compressed storage. Plug-and-play memory for Claude Code, Gemini CLI, OpenCode, Codex, Cursor, GitHub Copilot, Augment Code, Antigravity, and IBM Bob.

Readme

cavemem

why agent forget when agent can remember

npm Stars Last Commit License

Install • How it works • CLI • MCP • Settings

Fork. Upstream JuliusBrussee/cavemem froze in August 2026. This repo (chiefmojo/cavemem) is a detached fork carried forward for its own use — active, but with no contribution flow back upstream. The wider caveman family lives on in caveman and caveman-browse.


Cross-agent persistent memory for coding assistants. In the default local configuration, hooks fire at session boundaries, compress observations with the caveman grammar (~75% fewer prose tokens, code and paths preserved byte-for-byte), and write to local SQLite; agents query their own history over local MCP without network or cloud calls. Remote embedding providers, web enrichment, and remote mode are opt-in network features; remote mode sends hook and MCP traffic over the LAN to a central worker-owned store.

Supports: Claude Code · OpenCode · Codex · GitHub Copilot · Augment Code · Cursor (query-only) · Gemini CLI (query-only) · Antigravity (query-only) · IBM Bob (query-only)

  • Persistent memory across sessions. Hooks capture what happened; the store keeps it.
  • Compressed at rest. Deterministic caveman grammar, round-trip-guaranteed expansion for humans.
  • Progressive MCP retrieval. search, timeline, get_observations — agents filter before fetching.
  • Hybrid search. SQLite FTS5 keyword + local vector index, combined with a tunable ranker.
  • Local by default. The default local configuration makes no network calls. Remote embedding providers and web enrichment are opt-in, and opt-in remote mode sends hook and MCP traffic to a central worker.
  • Web viewer. Read-only UI at http://localhost:37777 for browsing sessions in human-readable form. Token-protected: the worker generates a local bearer token on first start; cavemem viewer uses it to mint a short-lived single-use nonce and opens the browser with a handshake that trades the nonce for a session cookie — the durable token itself never reaches a URL or a spawned browser process's arguments, so viewing still has zero friction while every route rejects requests without the token or cookie.
  • Cross-IDE installers. Claude Code, OpenCode, Codex, GitHub Copilot, Augment Code capture observations; Cursor, Gemini CLI, Antigravity, IBM Bob are query-only (MCP search over memory captured elsewhere) — one command each, see the capability matrix.
  • Privacy-aware. <private>...</private> stripped at write boundary. Path globs exclude whole directories.

Install

npm install -g @chiefmojo/cavemem
cavemem install                    # Claude Code
cavemem install --ide cursor       # cursor | gemini-cli | opencode | codex | copilot | augment | antigravity | bob
cavemem status                     # see wiring + embedding backfill
cavemem viewer                     # open http://127.0.0.1:37777

In local mode, no daemon needs to be started manually. Hooks write synchronously, and a local worker auto-spawns in the background on the first hook to build embeddings and serve the viewer; it self-exits when idle (set embedding.idleShutdownMs to 0 to keep it running until killed). Disable auto-spawn — and with it the HTTP listener — with cavemem config set embedding.autoStart false.

Remote mode

Remote mode lets one central worker own the memory store for agents on multiple machines. After setting remote.url, rerun cavemem install --ide claude-code, cavemem install --ide codex, and cavemem install --ide opencode so each IDE's existing MCP entry is rewritten for streamable HTTP; see Remote mode for settings, client behavior, and failure handling. See the deployment runbook to install and operate the shared server.

IDE capability matrix

"Query" means the MCP server can search memory captured elsewhere. "Capture" means this IDE's own sessions write new observations — without it, the DB never fills for that IDE no matter how healthy cavemem status otherwise looks (#58).

| IDE | capture (hooks) | query (MCP) | notes | |-----|:---:|:---:|-------| | Claude Code | ✓ | ✓ | 5 hooks: SessionStart, UserPromptSubmit, PostToolUse, Stop, SessionEnd | | OpenCode | ✓ | ✓ | via bundled bridge plugin¹ | | Codex CLI | ✓ | ✓ | no SessionEnd event² | | GitHub Copilot | ✓ | ✓ | no SessionEnd event² | | Augment Code | ✓ | ✓ | no UserPromptSubmit event² | | Cursor | — | ✓ | query-only — no hooks system | | Gemini CLI | — | ✓ | query-only — no hooks system | | Antigravity | — | ✓ | query-only — no hooks system | | IBM Bob | — | ✓ | query-only — no hooks system |

¹ OpenCode has no hooks.json-style event system. Capture instead goes through a bundled bridge plugin (opencodeBridge.js, symlinked into OpenCode's plugin dir on install) that subscribes to OpenCode's native event and tool.execute.after hooks and shells out to the same cavemem hook run handlers every other IDE uses — same lifecycle coverage, different wiring. Install verifies the effective merged OpenCode MCP configuration, and the bridge advertises memory tools only while Cavemem's MCP connection is confirmed available. A confirmed unavailable connection gets a declarative diagnostic; a transient status error or timeout gets a neutral diagnostic rather than an installation instruction.

² Copilot's and Codex's hook payloads are close enough to Claude Code's shape that the same handlers are reused unmodified, but neither event set is complete: Codex and Copilot have no SessionEnd, and Augment has no UserPromptSubmit. Every other lifecycle moment still fires and gets written.

Run cavemem status after installing to see which IDEs are wired up, with query-only ones flagged inline (ides: claude-code, antigravity (query-only)).

Windows

Claude Code runs hook commands through sh -c even on Windows. If Git for Windows' Git\bin isn't on your user Path, sh doesn't resolve, hooks fail silently, and capture quietly stops — cavemem doctor/status keep reporting healthy because the failure never reaches the CLI. Add C:\Program Files\Git\bin (or <scoop dir>\apps\git\current\usr\bin for a Scoop install) to your user Path, then verify with where.exe sh. cavemem doctor and cavemem install both check sh resolvability on win32 and print a warning if it's missing.

Claude Code's hooks docs also describe a shell field ("bash" / "powershell") and a shell-free args exec form. We looked at emitting either instead of the plain sh-shaped command string, but held off: we can't verify those fields against every Claude Code version in the wild, and the current command has no shell metacharacters, so it already tokenizes the same way whether Claude Code runs it through sh or falls back to PowerShell. Once there's a way to gate on a minimum Claude Code version, switching to the shell-free args form would drop the sh dependency entirely.


How it works

session event  →  redact <private>  →  compress  →  SQLite + FTS5
                                                           ↑
                                                MCP queries on demand

What compression looks like in practice:

Input:  "The auth middleware throws a 401 when the session token expires; we should add a refresh path."
Stored: "auth mw throws 401 @ session token expires. add refresh path."
Viewed: "The auth middleware throws a 401 when session token expires. Add refresh path."

Code blocks, URLs, paths, identifiers, and version numbers are never touched. Hook handlers complete in under 150ms. Full bodies fetched on demand via get_observations.


CLI

| Command | | |---------|--| | cavemem install [--ide <name>] | Register hooks + MCP for an IDE | | cavemem uninstall [--ide <name>] | Remove hooks + MCP | | cavemem status | Single dashboard: wiring, DB counts, embedding backfill, worker pid | | cavemem config show\|get\|set\|open | View/edit settings — schema is self-documenting | | cavemem start\|stop\|restart | Control the worker daemon (usually unnecessary — auto-starts) | | cavemem viewer | Open the memory viewer in your browser | | cavemem doctor | Verify installation | | cavemem search <query> [--limit N] [--no-semantic] | Search memory (BM25 + cosine re-rank) | | cavemem compress <file> | Compress a file with caveman grammar | | cavemem reindex | Rebuild FTS5 + vector index | | cavemem export <out.jsonl> | Dump sessions + observations to JSONL | | cavemem import <file.jsonl> [--dry-run] | Load a JSONL export back in (merge, safe to re-run) | | cavemem mcp | Start MCP server (stdio) |

Manual cross-device transfer: on machine A, cavemem export backup.jsonl. Copy the file to machine B, then on B, stop the worker (cavemem stop), run cavemem import backup.jsonl, and restart it (cavemem start). Records already present are skipped, and imported observations whose ids clash with different local ones get fresh ids — nothing is overwritten, and importing the same file twice is a no-op. Imported observations keep their original compressed content and get picked up by the embedding backfill like any new write — vectors themselves aren't exported.


MCP

Progressive disclosure: search and timeline return compact results; get_observations fetches full bodies.

| Tool | Returns | |------|---------| | search(query, limit?) | [{id, score, snippet, session_id, ts}] — BM25 + optional cosine re-rank | | timeline(session_id, around_id?, limit?) | [{id, kind, ts}] | | get_observations(ids[], expand?) | Full bodies, expanded by default | | list_sessions(limit?) | [{id, ide, cwd, started_at, ended_at}] | | enrich(query, note?) | {results: [{title, url, extract, observation_id}]} — opt-in web enrichment |

enrich is off by default. When enrich.enabled is false the tool is not registered and cavemem makes no network call, ever. When enabled, it searches DuckDuckGo, stores compressed plain-text extracts as observations (tagged source: web + URL for provenance), and returns them.


Settings

<cavemem home>/settings.json, where the cavemem home directory resolves in this order:

  1. CAVEMEM_HOME env var, if set.
  2. An existing ~/.cavemem — zero breaking change for current installs.
  3. $XDG_DATA_HOME/cavemem whenever XDG_DATA_HOME is explicitly set — on any platform, not just Linux. Without the var, Linux uses the XDG default ~/.local/share/cavemem; macOS/Windows keep ~/.cavemem.

Non-absolute env values (no leading / or ~) are ignored, per the XDG spec — otherwise hooks running from a project directory would fragment the store per-project.

Run cavemem doctor or cavemem status to see which directory is actually in use.

cavemem doctor also checks enabled IDE integrations for missing Node interpreters and version-pinned Homebrew Cellar paths. It reports cavemem install --ide <name> to repair the affected integration; diagnosis leaves IDE configs unchanged. Reinstall records a stable absolute Node PATH link when it resolves to the running interpreter.

| Key | Default | | |-----|---------|--| | dataDir | resolved cavemem home (above) | SQLite database, models, pidfile, logs — set this explicitly (e.g. "~/.cavemem") to relocate just the data, independent of where settings.json lives. Only an explicit value is written to settings.json; the default is re-resolved on every load, so the file stays portable across machines | | compression.intensity | "full" | lite / full / ultra | | compression.expandForModel | false | Return expanded text to model | | embedding.provider | "local" | local / ollama / openai | | workerPort | 37777 | Local viewer port | | search.alpha | 0.5 | BM25 / vector blend | | search.defaultLimit | 10 | Default result count | | privacy.excludePatterns | [] | Path globs (e.g. ["**/.env", "**/secrets/**"]) never captured | | privacy.redactSecrets | true | Scrub secret-shaped substrings (API keys, tokens, passwords) with [REDACTED] | | capture.excludeTools | [] | Tool names/globs never captured; wins over includeTools | | capture.includeTools | [] | If non-empty, only these tool names/globs are captured | | enrich.enabled | false | Opt-in web enrichment tool |

Content inside <private>...</private> is stripped before write. Paths matching excludePatterns are never captured into memory, whether they appear in a tool's file_path/path/notebook_path field or embedded in a command string. The worker binds to 127.0.0.1 only, checks the Host/Origin headers on every request, and requires a local bearer token (<dataDir>/worker-token, mode 0600) on /api/*.


🪨 The Caveman Ecosystem

Four tools. One philosophy: agent do more with less.

| Repo | What | One-liner | |------|------|-----------| | caveman | Output compression skill | why use many token when few do trick — ~75% fewer output tokens across Claude Code, Cursor, Gemini, Codex | | cavemem (you are here) | Cross-agent persistent memory | why agent forget when agent can remember — compressed SQLite + MCP, local by default | | cavekit | Spec-driven autonomous build loop | why agent guess when agent can know — natural language → kits → parallel build → verified | | cavegemma | Gemma 4 31B fine-tuned on caveman pairs | why prompt every turn when weight remember — LoRA + merged bf16 on HF, no system prompt needed |

They compose: cavekit orchestrates the build, caveman compresses what the agent says, cavemem compresses what the agent remembers, cavegemma bakes the compression into the model weights. Install one, some, or all — each stands alone.

Also by Julius Brussee

  • Revu — local-first macOS study app with FSRS spaced repetition. revu.cards

License

MIT