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

memhook

v0.5.0

Published

Semantic memory router for Claude Code — picks relevant feedbacks & rules per prompt via Haiku, injects them as additionalContext.

Readme

memhook

Stop telling Claude to check its memory. memhook auto-injects the notes relevant to each prompt — so it already knows what you told it.

A semantic memory router for Claude Code — a UserPromptSubmit hook that picks the feedback_*.md & rule_*.md notes relevant to this prompt and injects them as additionalContext. Your memory gets consulted automatically — you stop saying "go read your memory."

✨ Features

  • 🎯 Right note, right moment — auto-selects the 0–5 memory files relevant to this prompt and injects them. No more "go read your memory."
  • 🧠 Gets better as your memory grows — relevance is picked per prompt, so a large memory helps instead of drowning the model.
  • 🛡️ Fail-soft — never blocks Claude Code; every error path falls back to empty context.
  • 🔌 Multi-provider — Anthropic (default), OpenAI, or local Ollama. Your key, your endpoint.
  • 💸 Light on context — injects ~2k tokens of signal instead of a 10–14k-token catalog dump.
  • 🤫 Zero telemetry — the only outbound call is the LLM endpoint you chose.
  • 🪶 One dependencyyaml, with zero sub-deps.
  • Cached & pre-filtered — an LRU cache + a trivial-prompt skip keep latency near zero.
  • 🧰 One-command setupmemhook init wires the hooks (with backup); memhook tail shows routing live.
  • 🧩 Companion skills — optional /wrap, /curate, /relay to capture, tidy, and hand off your memory.

🤔 Why

Claude Code's ~/.claude/ directory accumulates a growing set of feedback_*.md (behavioural corrections) and rule_*.md (project doctrine) files. The problem isn't their size — it's that Claude doesn't know what's in there: it misses notes that apply, so you keep telling it "you wrote that down, go read it."

memhook removes that chore. A cheap router model (Haiku 4.5 by default) matches each prompt against a one-line catalog of all your memory files and injects just the relevant ones — so the right note is already in context, automatically. The rest sit on disk, invisible until they matter.

| Approach | What Claude sees | Tokens / prompt | | --------------------- | ------------------------------- | --------------- | | Load all memory files | mostly irrelevant noise | 10–14k | | memhook | only what matches this prompt | ~2k |

🚀 Quick start

npm install -g memhook
export ANTHROPIC_API_KEY=sk-ant-…   # or see Providers for OpenAI / Ollama
memhook init

memhook init detects your Claude Code config, wires the two hooks into ~/.claude/settings.json (backing it up first, never clobbering existing hooks), and builds the initial catalog. It is idempotent and supports --dry-run. Restart Claude Code and you're done — then watch it work live with memhook tail.

  1. Build the initial catalog

    memhook build-catalog
    # → ~/.claude/cache/memory-catalog.txt
  2. Wire the hooks in ~/.claude/settings.json:

    {
      "hooks": {
        "UserPromptSubmit": [{ "hooks": [{ "type": "command", "command": "memhook run" }] }],
        "SessionStart": [{ "hooks": [{ "type": "command", "command": "memhook build-catalog" }] }]
      }
    }

Remove it all later with memhook uninstall (also backs up first).

git clone https://github.com/utilia-ai-wox/memhook.git
cd memhook
bun install
bun run build
npm link

🔍 How it works

UserPromptSubmit hook
    │
    ▼
┌────────────────────────────────────────┐
│ 1. Pre-filter trivial prompts          │ ── "ok" / "merci" → skip LLM
│ 2. Check local LRU cache               │ ── identical prompt < 60min → hit
│ 3. Call the router with catalog        │ ── ephemeral 1h cache control
│ 4. Parse JSON array of basenames       │ ── ["feedback_X.md", "rule_Y.md"]
│ 5. Read files, cap by token budget     │ ── max 9.5k chars or 5 files
│ 6. Emit additionalContext              │
└────────────────────────────────────────┘

⚙️ Configuration

Every knob is an env var, and optionally a YAML file. Precedence per key is env var > YAML file > built-in default, so an env-var-only setup behaves exactly as before. Sensible defaults work for most users.

| Variable | Default | Purpose | | -------------------------------- | ------------------------------- | -------------------------------------- | | MEMHOOK_ENABLED | true | Master toggle | | MEMHOOK_PROVIDER | anthropic | anthropic | openai | ollama | | MEMHOOK_MODEL | per-provider | Model id (provider default if unset) | | MEMHOOK_API_KEY_ENV | per-provider | Name of env var holding the API key | | MEMHOOK_BASE_URL | per-provider | Override the provider API endpoint | | MEMHOOK_CONFIG | ~/.config/memhook/config.yaml | Path to the optional YAML config file | | MEMHOOK_MAX_FILES | 5 | Hard cap on injected files | | MEMHOOK_MAX_ADDITIONAL_CHARS | 9500 | Soft cap on injected chars (≈2.4k tok) | | MEMHOOK_MAX_OUTPUT_TOKENS | 200 | Model output cap for the selection | | MEMHOOK_TIMEOUT_MS | 8000 (30000 for ollama) | Per-request timeout | | MEMHOOK_DISABLE_CACHE=true | (off) | Skip local LRU cache | | MEMHOOK_DISABLE_PREFILTER=true | (off) | Skip trivial-prompt skip | | MEMHOOK_DEBUG=true | (off) | Print errors to stderr |

YAML config (optional)

memhook works with no config file at all. If you prefer YAML, copy config.example.yaml to ~/.config/memhook/config.yaml (or point MEMHOOK_CONFIG at it). A missing or malformed file is ignored silently — memhook falls back to env vars and defaults, never blocking your prompt.

provider:
  type: openai
  # model + apiKeyEnv default to gpt-4o-mini + OPENAI_API_KEY
selection:
  maxFiles: 5

🔌 Providers

The default provider is Anthropic — with no MEMHOOK_PROVIDER set, the only outbound call memhook ever makes is to api.anthropic.com, using your own key. Selecting another provider is opt-in and changes which endpoint is contacted. memhook never phones home and has no telemetry; "provider" means the LLM endpoint you choose to route through.

| Provider | MEMHOOK_PROVIDER | Default model | API key | Endpoint | | --------- | ------------------ | ------------------ | ------------------- | --------------------------------------- | | Anthropic | anthropic | claude-haiku-4-5 | ANTHROPIC_API_KEY | api.anthropic.com | | OpenAI | openai | gpt-4o-mini | OPENAI_API_KEY | api.openai.com | | Ollama | ollama | llama3.1 | none (local) | http://localhost:11434 (configurable) |

  • OpenAI — set MEMHOOK_PROVIDER=openai and OPENAI_API_KEY. Uses the Chat Completions API; the catalog rides as the leading system message so OpenAI's automatic prompt caching can engage on a large catalog.
  • Ollama — set MEMHOOK_PROVIDER=ollama and make sure the model is pulled (ollama pull llama3.1) with the daemon running. No API key required. Hits the native /api/chat endpoint with stream:false; the timeout defaults to 30s to absorb cold model loads.

📊 Observability

Every invocation appends one JSON line to ~/.claude/logs/memhook.log:

{
  "ts": "2026-05-28T08:41:18Z",
  "prompt_preview": "fix the OPAQUE wire format drift…",
  "selected": ["opaque-interop-rust-ts.md"],
  "latency_ms": 1727,
  "tokens_in": 12,
  "tokens_out": 28,
  "cache_create": 0,
  "cache_read": 13398,
  "additional_size_chars": 20225,
  "additional_size_tokens_est": 5056,
  "status": "ok",
  "model": "claude-haiku-4-5"
}

Live view — memhook tail

Watch routing decisions as they happen, in colour:

memhook tail                          # follow live (Ctrl-C to quit)
memhook tail --no-follow              # print recent log + summary, then exit
memhook tail --status ok,cache_hit    # filter by status
memhook tail -n 50                    # show more history first

Each row shows the time, status, prompt preview, latency, and model, plus the memories that were injected; a summary line reports the cache-hit rate and p50/p95 latency. Colour degrades to plain text when piped or under NO_COLOR. tail only reads the log, so it can never affect the hook. For raw analysis, the log is plain JSONL — e.g. the last 7 days by status:

jq -c 'select((.ts | fromdateiso8601) > (now - 7*86400)) | .status' \
  ~/.claude/logs/memhook.log | sort | uniq -c

Status values

| status | Meaning | | ---------------------- | ----------------------------------------------------- | | ok | Files injected from a fresh model selection | | cache_hit | Files injected from local LRU cache | | pre_filter_skip | Trivial prompt, LLM call skipped | | empty_selection | The model returned [] (no memory needed) | | all_unfound | The model returned basenames that don't exist on disk | | no_catalog | Catalog missing — run memhook build-catalog | | no_api_key | API key env var not set (not needed for ollama) | | provider_init_failed | Provider couldn't be constructed (bad config) | | api_no_response | Network error or timeout | | api_no_content | API returned 200 but no text | | parse_invalid | Response wasn't a valid JSON array |

🧩 Companion skills

Routing only works well when your memory stays healthy. memhook ships three optional Claude Code skills for that — install them with one command:

memhook skills install      # copy them into ~/.claude/skills
memhook skills list         # show install status
memhook skills uninstall    # remove them (backs up any edits first)

memhook init also offers to install them.

| Skill | What it does | | --------- | ---------------------------------------------------------------------------------------------------------------------------- | | /wrap | End-of-session wrap-up — captures the session's lessons into memory + a dated journal entry. Proposes; never writes unasked. | | /curate | Memory hygiene — dedupes, fixes the MEMORY.md index, splits oversized files, then rebuilds the catalog. | | /relay | Generates a self-contained prompt to resume work in a fresh session. Read-only. |

They're standalone skills, so you invoke them directly as /wrap, /curate, /relay. They are user-invoked only — Claude won't trigger them on its own.

When your catalog grows large, memhook also adds a one-line reminder to run /curate (a local-only systemMessage, 7-day cooldown — toggle with MEMHOOK_CURATE_NUDGE).

🛡️ Fail-soft

memhook never blocks Claude Code. On any error — missing key, network timeout, malformed JSON, broken filesystem — it emits an empty additionalContext and logs the status. Your prompt always reaches the model, just without injected memories for that turn.

🗺️ Roadmap

  • v0.2 ✅ — YAML config file, OpenAI provider, Ollama local provider (published on npm)
  • v0.3 ✅ — memhook init / memhook uninstall setup wizard + zero-dep live monitor (memhook tail)
  • v0.4 ✅ — Companion skills (/wrap, /curate, /relay) + memhook skills installer + /curate nudge
  • v1.0 — API frozen, cross-platform validated, polished docs

🤝 Contributing

Contributions welcome — please read CONTRIBUTING.md first. The hook contract (fail-soft, no telemetry, strict TypeScript) is non-negotiable; the failsoft-auditor agent guards it on every PR.

[!TIP] ⭐ If memhook keeps Claude on-context without the "go read your memory" nudges, star the repo — it helps other Claude Code users find it.

License

MIT © wox