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

openclaw-clawmark

v0.3.0

Published

Clawmark — durable facts and semantic recall for OpenClaw, derived from the message history you already keep. No duplicate message store; crash-safe by design.

Readme

Clawmark 🦞

Durable facts and semantic recall for OpenClaw, derived from the message history you already keep. Clawmark: the marks a claw leaves behind — traces of past conversations.

What it does

Clawmark adds the two memory capabilities a stock OpenClaw install lacks:

  1. Facts — small, structured, always-injected: preferences, decisions, active projects, corrections. Written by an explicit tool (clawmark_set) and by a background extraction job, with confidence gating and user-beats-extracted precedence.
  2. Recall — query-relevant retrieval over your full message history: an embedding index built over the messages OpenClaw already stores, injected as short excerpts when relevant to the current prompt.

What it deliberately does not do:

  • No duplicate message store. Clawmark never copies your history. It reads the canonical log (Lossless Claw's database, or OpenClaw's own session transcripts) read-only, behind cursors.
  • No history summarization. That's compaction's job (or Lossless Claw's).
  • No cloud. Embeddings and extraction hit whatever OpenAI-compatible endpoints you configure — typically local llama.cpp servers.

Why it's crash-safe by design

Both background jobs (the embedding indexer and the fact extractor) are cursor-based readers of a durable log. Cursors advance in the same SQLite transaction as the writes they cover. kill -9 the gateway at any moment: on the next start, both jobs continue from their last committed cursor. Nothing is lost, and re-processing a batch is a no-op (upserts + a precedence ladder absorb repeats).

Requirements

  • OpenClaw 2026.5.28+
  • An OpenAI-compatible embeddings endpoint (e.g. llama.cpp/bge-m3, 1024 dims by default)
  • An OpenAI-compatible chat endpoint for background fact extraction (a small 4–8B model is plenty — prefer one that doesn't share slots with your interactive chat model)
  • No plugin dependencies. If Lossless Claw is installed, Clawmark auto-detects and prefers its message log.

Install

openclaw plugins install openclaw-clawmark

Then set the environment (see .env.example for the full list):

CLAWMARK_DB_PATH=~/.openclaw/clawmark.db
CLAWMARK_TRANSCRIPTS_DIR=~/.openclaw/agents/main/sessions
CLAWMARK_EMBEDDING_URL=http://your-inference-box:11438
CLAWMARK_EMBEDDING_MODEL=bge-m3-fp16
CLAWMARK_EXTRACT_URL=http://your-inference-box:11437
CLAWMARK_EXTRACT_MODEL=your-small-model.gguf

Restart the gateway. Clawmark logs which message source it selected; if configuration is incomplete it stays inert and logs the missing variable — it never breaks the agent.

Configuration

| Variable | Required | Default | Purpose | |---|---|---|---| | CLAWMARK_DB_PATH | yes | — | Clawmark's own SQLite DB (facts, vectors, cursors, audit events) | | CLAWMARK_SOURCE | no | auto | auto | lcm | transcripts | | CLAWMARK_TRANSCRIPTS_DIR | yes* | — | OpenClaw session-transcript dir (the always-available source) | | CLAWMARK_LCM_DB_PATH | no | — | Lossless Claw's SQLite DB; auto-preferred when set and valid | | CLAWMARK_EMBEDDING_URL / _MODEL | yes | — | OpenAI-compatible /v1/embeddings endpoint | | CLAWMARK_EMBEDDING_DIM | no | 1024 | Embedding dimensionality | | CLAWMARK_EXTRACT_URL / _MODEL | yes | — | OpenAI-compatible chat endpoint for extraction | | CLAWMARK_CONFIDENCE_THRESHOLD | no | 0.8 | Extracted facts below this are discarded | | CLAWMARK_RECALL_LIMIT | no | 6 | Max recalled excerpts per turn | | CLAWMARK_IDLE_HOURS | no | 3 | Idle time before a full backlog drain |

* required unless CLAWMARK_LCM_DB_PATH is set and valid.

Tools

  • clawmark_set(key, value) — remember a fact explicitly. User-set facts always win.
  • clawmark_search(query, limit?) — search facts + recall excerpts from past sessions.
  • clawmark_reconcile(drain?) — force the background jobs to run now (index new messages, extract facts, prune) instead of waiting for the message-count or idle triggers. Say "reconcile memory" to your agent and it should call this.
  • clawmark_review(days?) — list extracted facts that haven't been reinforced recently, so the agent can confirm them with you before they decay out.
  • clawmark_forget(key) — delete a fact.

Fact lifecycle — reinforcement, not TTL

Facts don't expire on a clock: "prefers tabs" is true for years, "the deck is due Friday" was stale in a week. So Clawmark uses reinforcement as the staleness signal instead of time-to-live:

  • When the extractor re-observes an unchanged fact, its decay clock resets (logged as a reinforce audit event) — facts that keep coming up stay fresh forever.
  • Extracted facts unreinforced for 90 days start losing effective confidence (exponential decay). Once below the confidence threshold they stop being injected — but remain stored and auditable.
  • After 365 days without reinforcement they're tombstoned (audit event delete, source decay).
  • User-stated facts never decay. If you said it explicitly, it stays until you clawmark_forget it.

Security model

Everything Clawmark injects is wrapped in a guard block that labels it as DATA, not instructions, and the closing marker survives truncation. On the write path, extracted fact values are scanned against prompt-injection patterns before storage; blocked writes are logged as injection_blocked audit events. Every mutation lands in an append-only memory_events table:

sqlite3 ~/.openclaw/clawmark.db "SELECT event_type, COUNT(*) FROM memory_events GROUP BY 1;"
sqlite3 ~/.openclaw/clawmark.db "SELECT key, confidence, source FROM facts WHERE is_deleted=0 ORDER BY updated_at DESC LIMIT 20;"

Running alongside other plugins

| Plugin | Status | Notes | |---|---|---| | Lossless Claw (LCM) | compatible, preferred source | Read-only, schema validated at startup; on drift Clawmark logs source_fallback and uses transcripts. Tested against the schema of LCM ≥ 2026.6. | | OpenClaw native markdown memory | compatible | Clawmark never touches MEMORY.md. Once facts migrate into Clawmark you can trim the markdown to reclaim prompt budget. | | Mem0 / ClawXMemory / Maximem / other memory plugins | works, but redundant | Two extractors double background LLM calls and inject overlapping context. Pick one fact-extraction layer. Tool names never collide (clawmark_ prefix). | | Everything else | untested | Clawmark only reads message logs and injects ≤ ~3.5k tokens via before_prompt_build; conflicts are unlikely but unverified. |

Prompt-budget math: Clawmark injects at most TOTAL_CAP_CHARS (12,000 chars ≈ 3.5k tokens) per turn, and usually far less — facts cap at 6,000 chars and recall only fires when the query matches something. Whatever Lossless Claw and other plugins inject is additive; a typical combined turn looks like: system prompt + LCM context + Clawmark block (0.5–3.5k tokens) + your message.

Message sources — pluggable, nothing required

Clawmark reads history through a MessageSource interface (src/sources/). Out of the box: a native-transcript adapter (always available) and a Lossless Claw adapter (auto-preferred). Adapters are ~100 lines; contributions for other history stores are welcome — implement validate / messagesAfter / getMessages with an opaque cursor.

Development

npm install
npm test          # vitest — 60 tests, fixtures only, no network
npm run check     # tsc --noEmit
npm run build     # emit dist/

License

MIT