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

@theritual/cerebro

v14.0.0

Published

MCP server that keeps project memory — plan, rules, ADRs, docs and file notes — in a hayson document store or SQLite

Readme

cerebro

Serwer MCP trzymający pamięć projektu: plan rozwoju, zasady, ADR-y, dokumentację i notatki przypięte do konkretnych plików, oraz słownik pojęć projektu, wraz z relacjami między wpisami, historią zmian i blokadami koordynującymi pracę na wielu worktree. Domyślnym składowaniem jest @theritual/hayson — baza jest katalogiem plików tekstowych.

Pamięć jest wspólna dla całego repozytorium — każda gałąź i każde worktree widzi to samo.

Cerebro nie zastępuje dokumentacji projektu. Dokumentacja dla ludzi zostaje w repo. Cerebro jest warstwą operacyjną dla agenta i ma jedno zadanie: usunąć potrzebę pisania komentarzy dla AI w kodzie.

Po co

Plan, zasady i decyzje w plikach MD są albo wczytywane całe (spalony kontekst), albo w ogóle (agent nie wie, że istnieją). Cerebro daje selektywny dostęp:

cerebro_brief                        → otwarte punkty planu, zasady must, ostatnie decyzje, przestarzałe docs
cerebro_file src/db/open.ts          → kto trzyma plik, zasady, decyzje, notatki i punkty planu dla tej ścieżki
cerebro_topic accessibility          → to samo, ale dla tematu: aliasy, tagi pokrewne i wszystko pod nimi
cerebro_get refs=[ADR-42,NOTE-a3f9]  → wpisy w całości, jednym wywołaniem
cerebro_define walk                  → co to słowo znaczy tutaj, choćby padło w innej pisowni

Wspólny język

Drugi problem jest cichszy niż spalony kontekst: model zgaduje, co znaczą twoje słowa. Kiedy piszesz „przebieg", „brama różnic" albo „walk", znaczenie jest oczywiste dla ciebie i wywnioskowane z kontekstu przez model — za każdym razem trochę inaczej.

Wpis rodzaju term to jedno słowo i jego znaczenie w tym projekcie: tytułem jest samo słowo, treścią definicja, a meta.aliases trzyma inne słowa na to samo — warianty polsko-angielskie, skróty, częste literówki. Dzięki temu cerebro_define walk trafia w termin „przebieg", a cerebro_search sam rozszerza zapytanie po aliasie. Słownik wychodzi też w cerebro_brief, więc model zna język projektu od pierwszego wywołania w sesji.

Jedno żywe słowo znaczy jedną rzecz: cerebro odmówi aliasu, który należy już do innego terminu. Kiedy słowo naprawdę zmienia znaczenie, nowy termin zastępuje stary (supersedes) — dawne znaczenie zostaje w pamięci, bo „to kiedyś znaczyło co innego" jest informacją, nie śmieciem. To jest ubiquitous language z DDD, tyle że utrzymywany tam, gdzie pracuje agent.

Jak wpis się nazywa

Wpis ma tożsamość, ref techniczny i — opcjonalnie — etykietę:

  • tożsamość to ULID nadawany raz i nigdy niepokazywany; to on jest kluczem w bazie, dzięki czemu dwie gałęzie nie nadadzą dwóm wpisom tego samego identyfikatora;
  • ref techniczny (NOTE-a3f9) ma każdy wpis od chwili powstania. To cztery znaki z losowej części ULID-a, rozszerzane tylko przy faktycznej kolizji;
  • etykieta (ADR-42, RULE-nazwy) jest nadawana przez człowieka i to ona nadaje się do cytowania w kodzie i w commitach.
cerebro note new "Pułapka w otwieraniu bazy" --path src/db/open.ts
# → Created NOTE-a3f9: Pułapka w otwieraniu bazy

cerebro note label NOTE-a3f9 otwieranie     # nadaj nazwę → NOTE-otwieranie
cerebro note label NOTE-otwieranie -        # zdejmij ją z powrotem
cerebro adr new "Trzymamy pamięć w hayson" --label 42   # albo od razu przy zakładaniu

Nowy wpis nie dostaje numeru z licznika — numerowanie skończyło się razem z przejściem na ULID-y (0015); wpisy sprzed migracji mają swoje dawne numery jako zwykłe etykiety, więc ADR-4 działa dalej. Refu szukasz etykietą, refem technicznym albo pełnym ULID-em; gdy token pasuje do kilku wpisów, cerebro pokazuje kandydatów i nie zgaduje.

Instalacja

Trzy tryby — szczegóły w docs/install.md.

Globalnie, dla siebie:

npm i -g @theritual/cerebro
cerebro install -y            # rejestracja w scope user + skill + subagent

W repo, dla zespołu:

pnpm add -D @theritual/cerebro
./node_modules/@theritual/cerebro/install.sh --scope project --skill-scope project

--scope project zapisuje .mcp.json w repo (plik do commitu), --scope local rejestruje serwer tylko dla ciebie i nie dodaje niczego do repozytorium.

Z repo źródłowego cerebro:

./install.sh --dry-run       # plan bez zapisu
./install.sh -y --claude-md  # bez pytań, plus ściągawka w ~/.claude/CLAUDE.md
./install.sh --uninstall     # zdejmuje rejestrację, skill i subagenta; baza i config zostają

Wymagania: Node ≥ 24, zero natywnych zależności. Do rozwoju dodatkowo pnpm.

Jako biblioteka

import { createCerebroServer, createCerebroContext } from '@theritual/cerebro'

const context = await createCerebroContextAsync({ cwd: process.cwd() })
await myServer.connect(myTransport)

Kontekst rozstrzyga się asynchronicznie i inaczej się nie da — baza otwiera się asynchronicznie. Stąd createCerebroContextAsync i startStdioServer; synchronicznych wariantów nie ma.

Publiczna powierzchnia to src/index.ts (typy w dist/index.d.ts); pozostałe moduły są wewnętrzne.

Gdzie co leży

| Co | Gdzie | |---|---| | konfiguracja użytkownika | ~/.config/cerebro/config.json | | konfiguracja projektu | cerebro.config.json w korzeniu repo (do commitu) | | baza globalna | ~/.local/share/cerebro/db | | baza per projekt | ~/.local/share/cerebro/projects/<slug> (db.scope: "project") | | baza w repo | .cerebro/db (db.scope: "repo") | | kopie zapasowe | ~/.local/share/cerebro/backups/ |

Baza jest katalogiem, nie jednym plikiem, więc db.path, --db i CEREBRO_DB wskazują katalog. Trzyma ją @theritual/hayson i jest to jedyne składowanie — decisions/0034.

Do katalogu pisze jeden proces naraz. Drugi czeka na blokadę i po chwili odmawia z komunikatem mówiącym, kto trzyma. Do zaglądania z innego worktree jest cerebro serve --read-only, które blokady nie bierze.

Pamięć zapisana w SQLite przez cerebro 13 i starsze nie otwiera się tutaj. Przenieś ją tamtą wersją — npx @theritual/cerebro@13 project move --to-engine hayson — a potem usuń dbEngine z konfiguracji. Konfiguracja nadal nazywająca sqlite kończy się czytelnym błędem, nie cichym otwarciem pustej bazy.

Dopóki w repo nie ma cerebro.config.json, cerebro nie zapisuje tam nic z własnej inicjatywy. Ten plik jest zgodą — i decyduje, co dokładnie wolno: gdzie leży baza, czy dokumentacja i ADR-y są generowane do plików MD, i co agent może zostawić w kodzie jako komentarz.

Konfiguracja repo

cerebro init                                   # baza globalnie, zrzut MD na żądanie, notki z odsyłaczem
cerebro init --db-scope repo --gitignore-db    # baza przy kodzie, wpisana do .gitignore
cerebro init --sync onWrite --comments none    # zrzut po każdym zapisie, zero komentarzy dla AI w kodzie
cerebro config                                 # warstwy i to, co z nich realnie wyszło

Warstwy, późniejsza wygrywa: domyślki → ~/.config/cerebro/config.jsoncerebro.config.jsonCEREBRO_DB--db.

Trzy rzeczy, które ten plik ustala:

  • db.scopeglobal, project albo repo. Przy repo decyzję o .gitignore cerebro zostawia Tobie: commit bazy daje pamięć od ręki po klonie, kosztem bazy w historii. Baza jest tekstowa i ma sterownik scalania (cerebro merge-driver install), który scala wpisy, a przy ścieżkach i tagach uczciwie odmawia — docs/merge.md.
  • sync.mode — kiedy z bazy powstaje markdown: manual (domyślnie, na cerebro sync), onWrite, onClose, albo off jako twarda blokada, której nie zdejmie nawet force. Kierunek jest zawsze jeden: baza → pliki. Pliki są generowane i nadpisywane, nic nie wraca do bazy.
  • comments.policynone, pointer albo full. To ustawienie jest doradcze: cerebro nie ma jak niczego wymusić w Twoim kodzie, więc robi jedyną rzecz, która działa — podaje politykę agentowi w instructions serwera i w każdej odpowiedzi cerebro_file, czyli bezpośrednio przed edycją pliku.

Szczegóły i pełny plik — docs/config.md.

CLI

Cerebro nie jest tylko serwerem MCP — ta sama pamięć jest dostępna po ludzku z terminala. Komendy operujące na wpisach wołają dokładnie te handlery, których używa MCP, więc nie ma dwóch implementacji do rozjechania się.

cerebro                                  ściągawka z listą komend
cerebro serve [--db <path>]              serwer MCP na stdio (alias: cerebro mcp)
cerebro init [flagi]                     cerebro.config.json dla tego repo
cerebro config                           warstwy konfiguracji i wynik
cerebro project                          projekty w bieżącej bazie
cerebro project move --to <scope>        przeniesienie pamięci między bazami

Przeprowadzka pamięci między bazą globalną, plikiem per projekt i bazą w repo jest osobną komendą, bo sama zmiana db.scope w configu niczego nie przenosi — mówi tylko, gdzie odtąd szukać:

cerebro project move --to repo           # z globalnej do repo
cerebro project move --to global         # z powrotem
cerebro project move --to repo --dry-run # pokaż plan, nie ruszaj niczego

Refy przeżywają przeprowadzkę — wpis zabiera ze sobą ULID, etykietę i ref techniczny, więc ADR-42 zostaje ADR-42, a NOTE-a3f9 zostaje NOTE-a3f9. Kopia jest weryfikowana przez policzenie wszystkich tabel po obu stronach, źródło ląduje w kopii zapasowej przed usunięciem czegokolwiek, a konfiguracja jest przestawiana tak, żeby następny proces sam trafił w nowe miejsce.

Czytanie:

cerebro brief                            plan, zasady must, słownik, decyzje, przestarzałe docs
cerebro file src/db/open.ts              wszystko, co dotyczy tej ścieżki
cerebro define walk                      co to słowo znaczy w tym projekcie
cerebro search "blokada" [--kind adr]    szukanie pełnotekstowe
cerebro show ADR-4 ADR-25 [--history]    wpisy w całości
cerebro journal [--related-to PLAN-7]    co zostało zrobione, w kolejności
cerebro browse [--project <slug>]        przeglądarka pełnoekranowa (alias: cerebro ui)

cerebro bez argumentów wypisuje pomoc (tak samo -h i --help) — nie startuje serwera.

Przeglądarka pełnoekranowa

cerebro browse otwiera pamięć projektu jako interfejs terminalowy: zakładki z kategoriami u góry, lista wpisów po lewej, a po prawej szczegół dopasowany do rodzaju wpisu — reguła pokazuje wagę i zasięg, ADR deciderów i rozważane opcje, plan pod-kroki i blokady, dokument i notatka nieaktualność względem sourceCommit, termin swoje aliasy.

cerebro · magic-diff  (main)                       ~/.local/share/cerebro/cerebro.db
 plan 10   rule 10   adr 160   doc 1   note 41   term 12
╭─────────────────────────────────╮╭───────────────────────────────────────────────╮
│ > ADR-160 accepted  Zrzut DOM…  ││ ADR-160 — Zrzut obrazu i zrzut DOM w jednym…  │
│   ADR-159 accepted  Brama róż…  ││ accepted · updated 2026-08-14 21:06           │
│   ADR-158 accepted  Poświadcz…  ││ tags: brama-roznic, dom, scenariusz           │
│   …                             ││ decided at: 2026-08-14                        │
╰─────────────────────────────────╯╰───────────────────────────────────────────────╯

| klawisz | co robi | |---|---| | Tab / Shift+Tab | następna / poprzednia kategoria | | , j k | ruch po liście wpisów | | g / G | pierwszy / ostatni wpis | | PgUp / PgDn | przewijanie treści wpisu | | Ctrl+O | lista projektów z bazy globalnej i z baz per projekt (plus projekt tego katalogu) | | Ctrl+E | kreator eksportu do markdownu | | q, Ctrl+C | wyjście |

Przeglądarka otwiera się wszędzie — nie wymaga ani cerebro init, ani istniejącego pliku bazy. Gdy w tym katalogu nie ma jeszcze pamięci, od razu wchodzi lista projektów (Ctrl+O), bo bazy globalnej i baz per projekt można przeglądać z dowolnego miejsca. Samo przeglądanie nie tworzy pliku bazy: jeśli baza wskazana konfiguracją jeszcze nie istnieje, czytana jest globalna.

Na macOS używa się Ctrl, nie Cmd. Terminal.app i iTerm przechwytują Cmd jako skrót aplikacji, więc taka kombinacja nigdy nie dociera do procesu — żaden program terminalowy jej nie zobaczy. Kto woli Cmd, mapuje ją w ustawieniach terminala: w iTerm2 Preferences → Keys → Key Bindings → +, akcja Send Hex Codes, 0x0f dla Cmd+O i 0x05 dla Cmd+E.

Kreator eksportu (Ctrl+E) pyta po kolei o kształt, zakres, katalog i tryb zapisu:

  • całość do jednego pliku<katalog>/<slug>.md, sekcja na kategorię;
  • każda kategoria do jednego plikuplan.md, rules.md, adrs.md, docs.md, notes.md, glossary.md;
  • każdy wpis do osobnego plikuplan/, rules/, adr/, docs/, notes/, terms/.

Przy dwóch ostatnich zaznacza się, które kategorie i które wpisy mają wyjść (Space, a, n). Wybór wpisów rozumie każdą z trzech postaci refu — etykietę (ADR-42), ref techniczny (ADR-a3f9) i pełny ULID — a nazwa, która nie trafia w żaden wpis, przerywa eksport z wypisaniem nietrafionych zamiast cicho zniknąć z wyniku. Domyślny katalog to docs/cerebro-export w korzeniu repo. Eksport niczego nie kasuje — pliki, których nie wygenerował, zostają nietknięte. Wyczyszczenie katalogu jest osobną opcją „Replace", pokazywaną tylko wtedy, gdy w katalogu już jest markdown, i wymaga potwierdzenia z wypisaną liczbą plików do usunięcia. Tym różni się od cerebro sync, który jest lustrem katalogu i usuwa z niego wszystko, czego sam nie zapisał.

Pisanie — <kind> to plan, rule, adr, doc, note albo term:

cerebro adr new "Pamięć w plikach tekstowych" --body "Bo zero zależności." --path src/store/open.ts
cerebro adr new "Decyzja" --editor        treść z $EDITOR
cerebro note new "Pułapka" --path a.ts --path b.ts --tag io   flagi się kumulują
cerebro rule new "Zasada" --meta severity=must
cerebro term new "przebieg" --body "Jedno przejście crawlera." --meta 'aliases=["walk","run"]'
cerebro <kind> list [--tag t] [--open] [--all]
cerebro <kind> edit REF --reason "dlaczego"    powód jest wymagany, leci do dziennika rewizji
cerebro <kind> rm REF --reason "dlaczego" [--hard]
cerebro <kind> label REF NAZWA|-          nadaj wpisowi nazwę dla ludzi (- ją zdejmuje)

cerebro adr accept|reject ADR-1           skrót na zmianę statusu
cerebro adr supersede ADR-1 "Nowa decyzja" decyzji się nie nadpisuje
cerebro term supersede TERM-1 "przebieg"  gdy słowo zmienia znaczenie
cerebro plan start|done|drop PLAN-1

Higiena:

cerebro sync [--dir <p>] [--kinds adr,doc]   generowanie markdownu z bazy
cerebro check-mapping                     które wskaźniki w bazie prowadzą w pustkę
cerebro check-mapping --fix               podąż za zmianami nazw, które git potrafi udowodnić
cerebro check-mapping --prune             usuń odniesienia bez następcy
cerebro doctor                            baza, tożsamość projektu, martwe ścieżki, blokady
                                          oraz etykiety noszone przez więcej niż jeden wpis
                                          czyta i tylko czyta: nie zakłada bazy, nie migruje jej
cerebro doctor --all-projects             to samo dla każdego projektu w tej bazie
cerebro reindex                           otwarcie do zapisu: migracje i odbudowa indeksów
cerebro merge-driver install|status       sterownik scalania bazy trzymanej w repo (hayson)
cerebro migrate                           utworzenie/aktualizacja schematu
cerebro backup [--out <path>]             snapshot bazy do ~/.local/share/cerebro/backups/
cerebro export [--dir <p>] [--force]      to samo co sync, nazwa historyczna
cerebro import --from <dir> [--apply]     bootstrap z istniejących plików MD
cerebro paths check|move|prune [--apply]  niżejpoziomowa higiena ścieżek (te same narzędzia, co MCP)
cerebro tags list|merge <from> <into>     porządkowanie tagów
cerebro config init                       domyślny plik konfiguracyjny użytkownika

cerebro doctor kończy się kodem 1, gdy któraś etykieta należy do więcej niż jednego wpisu albo zabiera cudzy ref techniczny (sekcje label clashes i shadowed refs); cerebro check-mapping kończy się kodem 1, gdy martwe ścieżki są i nic nie zostało naprawione — nadaje się do CI.

Uzupełnianie w shellu

cerebro completions <shell> wypisuje na standardowe wyjście skrypt uzupełniania dla bash, zsh albo fish — komendy, podkomendy, flagi każdej komendy i wartości flag wyliczeniowych (--db-scope, --sync, --comments, --to, --kind). Bez argumentu shell jest rozpoznawany z $SHELL.

cerebro completions bash > ~/.local/share/bash-completion/completions/cerebro
cerebro completions zsh  > "${fpath[1]}/_cerebro"
cerebro completions fish > ~/.config/fish/completions/cerebro.fish

Doraźnie wystarczy source <(cerebro completions bash) (w zsh to samo z zsh).

Rozwój

Repozytorium pracuje na worktree, kontener obok katalogu master:

git -C master worktree add ../<branch> -b <branch>
pnpm install
pnpm build          # tsc + kopia migracji do dist/
pnpm test           # vitest w trybie watch
pnpm test:run       # jednorazowo
pnpm lint           # biome
pnpm check-types    # tsc --noEmit
pnpm verify         # lint + typy + testy
pnpm smoke          # test dymny na prawdziwym stdio: dwa worktree, blokady, zmiana nazwy pliku, eksport, CLI
pnpm commitlint     # sprawdzenie ostatniego komunikatu commita

Commity i wydania

To repozytorium wymaga Conventional Commits — z komunikatów wyliczana jest wersja paczki:

fix(bin): stop crashing when the output pipe closes early     → patch
feat(cli): add moving a project between databases             → minor
feat(tools)!: drop cerebro_export                             → major
docs: describe the sync modes                                 → bez wydania

Wersji nie podbijasz i nie tagujesz ręcznie. Po scaleniu na main semantic-release liczy numer z commitów, publikuje na npm i zakłada tag vX.Y.Z wraz z wpisem wydania w GitLabie. Pole version w package.json zostaje nieaktualne i to jest zamierzone — źródłem prawdy są tagi.

Pełna tabela typów i uzasadnienie: CLAUDE.md.

pnpm smoke uruchamia cerebro serve dokładnie tak, jak robi to Claude Code (proces + stdio), na tymczasowym repo z dwoma worktree — sprawdza to, czego testy jednostkowe nie ruszają: rejestrację narzędzi przez protokół, wspólną pamięć między gałęziami i higienę ścieżek po git mv.

Dokumentacja

  • docs/install.md — trzy tryby instalacji, rejestracja MCP, użycie jako biblioteka
  • docs/config.md — warstwy konfiguracji, cerebro.config.json, tryby synchronizacji, higiena wskaźników
  • docs/architecture.md — warstwy, przepływ wywołania, granice
  • docs/schema.md — schemat bazy, statusy per grupa, meta
  • docs/identity.md — tożsamość projektu, worktree, ścieżki, blokady
  • docs/merge.md — sterownik scalania bazy trzymanej w repozytorium: rejestracja, tabela po tabeli, kiedy odmawia
  • docs/tools.md — 27 narzędzi MCP z kontraktem wejścia i wyjścia
  • docs/decisions/ — decyzje podjęte przy budowie cerebro, ze spisem