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

saripati

v0.5.0

Published

Local-first, provider-agnostic MCP knowledge vault + research capture. Give any AI host a persistent, compounding memory.

Readme

SARIPATI

npm node CI license

A local-first, provider-agnostic knowledge vault for any AI host.

sari pati (Malay) — the essence, the concentrated extract.

Most AI tools start every conversation cold. SARIPATI is the memory layer that sits underneath whatever AI you already use — Claude Code, Cursor, Windsurf, Cline, Continue — and lets knowledge compound across sessions. The AI researches with its own tools; you call SARIPATI to distill and store the essence. Weeks later, it recalls it semantically.

It is not a chat app. It runs no LLM and needs no API keys. Your entire knowledge base is a single SQLite file on your own machine.


Why

  • Compounding, not disposable. Research done in a session persists and accumulates by topic — the corpus grows every time the agent runs, not only when you take notes.
  • Semantic recall, local. Bundled embeddings (all-MiniLM-L6-v2) power hybrid semantic + keyword search entirely on-device.
  • A steerer, not just a store. The agent gets signal, not just recall: proactive nudges at session start (open questions, live intentions, unread memos, stale projects), per-kind priority, and conflict detection — every save is checked against the corpus so contradictions surface instead of piling up as equal "truth."
  • Knows who it serves. An optional identity + AI-companion persona loads at session start, so any host can adopt the right voice and address you correctly.
  • Visible. A launch-on-demand dashboard makes the growing knowledge base browsable, searchable, and (opt-in) editable.
  • Zero lock-in. Local SQLite, MIT-licensed, no cloud account, no vendor.

Non-goals

  • Not a chat app or LLM wrapper — it does not run or require an LLM.
  • No cloud dependency required.
  • Not tied to any single AI host or provider.

Install

Requires Node 22 or newer (Node 22 LTS recommended; 24 supported). Every native dependency ships prebuilt binaries, so no compiler, Visual Studio, or Xcode is needed. Windows on ARM is not currently supported — sqlite-vec publishes no win32-arm64 build. SARIPATI tells you plainly if your machine is unsupported instead of failing with a build log.

Guided path — let your AI do it. Open ONBOARD.md, copy its contents, and paste them into your AI host (Claude Code, Cursor, Windsurf, etc.), then say "set up saripati." It checks your environment, asks five identity questions, generates and runs the setup, and adds the system prompt — all in one conversation, before MCP is running.

Paste the contents; do not just link the file. Most agents treat fetched files as data to read, not instructions to execute, so pointing an agent at this URL will usually get you a summary instead of an install.

Manual path — do it yourself. Equally supported:

npx saripati setup                          # create vault, print config + detected hosts
npx saripati setup ./setup.md --write       # load identity from file + register with hosts
npx saripati version                        # what version is actually running here

Upgrading on a machine that already has it? npx caches by package spec, so pin explicitly — npx saripati@latest ui — and restart your MCP host. See Troubleshooting.

Either way, your host connects by package name — no folder path:

{
  "mcpServers": {
    "saripati": { "command": "npx", "args": ["-y", "saripati", "mcp"] }
  }
}

Restart your AI host. The first vault call downloads the ~90 MB embedding model once (with a progress heartbeat), then works offline forever.

To remove SARIPATI later, open UNINSTALL.md in your AI host.


The tools (9)

| Tool | What it does — and when to call it | |------|------------------------------------| | on | Start of every session, unprompted. Loads identity, last session, recent entries, active projects, and nudges. | | off | Session end. Write the digest + next steps yourself. | | vault | The one door to knowledge. Pass query to recall; pass content/findings to save. Every save runs a conflict check. | | entry_update | Resolve a flagged conflict: supersede, relink, lower confidence, resolve a question, close an intention. | | corpus | A map of what already exists — counts, top tags, per-project last activity. | | project_update / project_list | A lightweight project registry (metadata merges). | | whoami | Return the vault owner's identity + companion persona. | | identity_set | Create/update identity + tuning (companion_config) — fields merge. |

A typical flow: on at session start → the AI researches with its own tools → vault save → (conflict? entry_update) → next week vault recall → off at the end.

What that actually looks like

Monday — the agent finishes researching and distils what it learned.

vault({
  topic:    "Postgres connection pooling for serverless",
  findings: [
    "PgBouncer transaction mode breaks prepared statements; use session mode or disable them.",
    "Supabase's pooler runs on 6543; the direct 5432 port bypasses it and exhausts connections."
  ],
  tags:     ["postgres", "serverless", "pooling"],
  project:  "checkout-api",
  sources:  [{ url: "https://supabase.com/docs/guides/database/connecting-to-postgres" }]
})

// → "Saved research #142: \"Postgres connection pooling for serverless\"."
// { "saved": { "id": 142, "title": "Postgres connection pooling for serverless",
//              "kind": "research" } }

Three weeks later, in a cold session with no shared history — a paraphrase finds it:

vault({ query: "why do our prepared statements fail in production?" })

// → "Recalled 2 entries for \"why do our prepared statements fail in production?\"."
// [
//   { "id": 142, "kind": "research", "title": "Postgres connection pooling for serverless",
//     "excerpt": "- PgBouncer transaction mode breaks prepared statements; use session…",
//     "tags": ["postgres", "serverless", "pooling"], "project": "checkout-api",
//     "status": "active", "confidence": null, "score": 0.03252,
//     "matched": ["semantic", "keyword"] },
//   { "id": 98, "kind": "decision", "title": "Pin the pooler to session mode",
//     "excerpt": "We accept the connection ceiling in exchange for prepared…",
//     "status": "active", "score": 0.01639, "matched": ["semantic"] }
// ]

Nothing was re-researched, and no keyword in the question appears in the stored title. matched shows which retriever fired — score is the fused rank.


The Steerer model

Entries carry a kind and a lifecycle, so recall returns signal, not noise.

  • Kinds: research · note · decision · pattern · question · memo · intention. Questions track resolved; intentions track active; memos are the agent's notes to its future self and surface first at on.
  • Status: active · superseded · archived. Superseded/archived entries drop out of default recall (pass include_superseded to see them) — old decisions stop being cited as current truth.
  • Priority: a per-kind boost (memo > question > decision/intention > pattern > research/ note), tunable per vault via identity_set({ companion_config: { recall_boost: … } }).
  • Conflict detection: after every save, vault runs a narrow similarity check and returns near-duplicate or contradicting entries so the agent can entry_update them.

Identity — who the vault serves

The ONBOARD.md flow collects your identity conversationally and generates a filled setup.md. You can also fill it manually:

---
name:      Your Name
field:     Software Engineering
skills:    [supabase, next.js, laravel]
language:  English
companion: librarian     # plain | librarian | research-assistant
---

Stored in a singleton identity row. From then on on and whoami hand your host that context at session start, so it adopts the right voice and addresses you correctly. Update any time with identity_set (fields merge). Set a focus with identity_set({ user_prefs: { focus: "project-name" } }) and on biases recent entries toward it.


The dashboard

npx saripati ui                  # http://localhost:4319 — read-only by default
npx saripati ui --write          # enable in-browser tag/kind edits
npx saripati ui --no-semantic    # FTS only — faster cold start, no model load
npx saripati ui --port 8080      # custom port

The Steer tab — nudges, retrieval trace, and the live corpus

A local browser UI built on Preact 10 + HTM (no CDN, no bundler — vendored ESM served at /vendor/*.js). Five tabs — Steer opens by default:

| Tab | What it shows | |-----|---------------| | Steer | Live nudge console: open questions · active intentions · unread memos · stale projects. Retrieval trace (last vault recall — query, timestamp, scored results). Click any row to jump to the entry. | | Entries | Hybrid search · 7 kind chips · status chips (active / superseded / archived) · @project / tag filters · entry detail with sources, backlinks, typed links, lifecycle fields (superseded_by, resolved, active). Infinite scroll in browse mode (50 entries per page); search and filtered views fetch the full matching set. | | Graph | Physics force-graph over derived links. Up to 150 nodes; four edge types — relation (author-asserted typed links), wikilink, project, tag — strongest wins per pair, each toggleable (hidden types leave the simulation, not just the render). Node size scales with connection count. Search (/ to focus) rings matches and dims the rest. Ubiquitous tags are excluded from edges — vault-wide (>25 % of nodes) and, for entries in the same project, within that project too, so a tag saturating one small project can't turn it into a mesh. Scroll to zoom, drag canvas to pan, drag a node to pin it where you drop it, shift-click to pin/unpin; pins persist across reloads. The layout stops when it actually settles and auto-fits once — use reset to re-run it. | | Tags | Tag cloud and frequency. | | Identity | Profile · companion config (stale_days, conflict_threshold, per-kind recall boosts) · session history. |

Editing is off by default — pass --write to enable mutations (kind, tags, status, resolved, active).


How it works

AI host (its own web tools)  ──stdio/MCP──▶  saripati mcp
                                                 │
                    embed (MiniLM 384d) ─────────┤
                    hybrid search (vec ∪ FTS5) ──┤
                    per-kind boost + status ─────┤
                                                 ▼
                                    ~/.saripati/vault.db  (SQLite)
                                    ▲
                    saripati ui ────┘  (read-only dashboard)
  • Storage: SQLite via better-sqlite3, versioned with a PRAGMA user_version migration runner — existing vaults upgrade in place on open.
  • Vectors: sqlite-vec (vec0) — embeddings are L2-normalized so KNN ranks like cosine.
  • Keyword: SQLite FTS5. Fusion: Reciprocal Rank Fusion combines the two rankings.
  • Embeddings: @xenova/transformers running all-MiniLM-L6-v2 in-process.
  • Terminal voice: a small zero-dep presentation layer (src/term/theme.ts) that degrades to plain ASCII off-TTY and never touches the JSON-RPC channel (banners go to stderr).

Data lives in ~/.saripati/ by default (override with SARIPATI_HOME or SARIPATI_DB).


Develop

npm install
npm run build      # tsc → dist/ (+ vendored UI bundles)
npm test           # end-to-end smoke test (from source)
npm run test:install # cold install: pack, install the tarball, drive it as a user would
npm run dev -- mcp # run from source via tsx

Contributing

Issues and pull requests are welcome — bug reports, platform coverage, and documentation fixes especially. Open an issue or start a discussion.

Before opening a PR, run the full gate:

npm run build
npm test              # smoke suite, from source
npm run test:install  # cold install — packs, installs, and drives the tarball

If you hit an install failure, include the output of npx saripati@latest version and your node -v — that pair identifies almost every case.

License

MIT © Kyou