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

knowbrew

v0.0.13

Published

Brew durable knowledge from Claude Code and Codex session logs

Readme

knowbrew

Your coding agent forgets everything when the session ends.

You explain the same context again. You correct the same mistake again. You re-solve a problem you already solved last month, because the answer only ever existed in a session you closed.

knowbrew turns your Claude Code and Codex session logs into durable knowledge: plain Markdown files in a folder you own, searchable by your agent in future sessions.

npm install -g knowbrew
knowbrew init

日本語版 README

What you get

  • Your agent can look things up. Past decisions, conventions, corrections, and solutions become searchable records your agent reads when they are relevant — instead of you re-explaining them.
  • Nothing reaches your agent without your approval. Everything knowbrew writes starts with approved: false, invisible to normal retrieval. You decide what to approve, so a bad inference stays harmless.
  • Plain Markdown in your own folder. Point it at an Obsidian vault or any directory. Read it, edit it, grep it, sync it, delete it. No service, no account, no lock-in.
  • Works across Claude Code and Codex. One knowledge base, both agents.
  • Everything traces back. Every record cites the exact turns it came from, and your original logs are never modified or copied.

How it works

The flow follows a brewing metaphor:

session logs ──draw──▶ feedstock + unorganized knowledge ──brew──▶ organized knowledge ──approve/distill──▶ documents
(untouched)             (what happened)                           (durable claims)                          (derived views)

draw reads your session logs and records one feedstock per turn: a short summary plus broad Knowledge type candidates. In the same run, it reads the dialogue and surrounding context to extract unorganized Knowledge. The raw dialogue stays in the source log and is no longer needed by later pipeline stages after extraction.

brew organizes stored Knowledge one Subject at a time without reading the session logs. It compares every new claim with all current Knowledge heads for that Subject, then keeps, merges, replaces, or discards it.

You approve. Organized Knowledge remains unchecked after Brew. Check its approved property in Obsidian, or change it to approved: true in Markdown. Unapproved Knowledge stays out of the default search; --include-pending shows it. Only approved Knowledge reaches your agent through Distill and session-start injection.

distill regenerates readable Subject documents from approved, current knowledge. Each document follows a Template assigned by its Subject and records the exact Knowledge IDs it used. Knowledge remains the source of truth; files under documents/ are reproducible derived views.

Getting started

Run init in the directory that should hold your knowledge files — an Obsidian vault folder works well:

knowbrew init

It asks which session logs to read, which LLM backend to use, and whether to register itself with Claude Code and Codex. Registration adds a SessionStart hook for approved Knowledge and a Stop hook that Draws the completed session turn. Running init again seeds the form from your current configuration and keeps settings it does not ask about.

Then build your knowledge base:

Upgrading from a release before the two-stage Draw? Delete the generated records first: the feedstocks/, knowledge/, and documents/ directories. Keep masters/, .knowbrew/config.toml, and .knowbrew/state/. Feedstock and Knowledge progress changed shape, and no migration runs on existing data.

knowbrew draw    # session logs → feedstock + unorganized knowledge
knowbrew brew    # unorganized knowledge → organized pending knowledge
# review and approve Knowledge, then:
knowbrew distill # approved Knowledge → Subject documents

The commands are safe to re-run: Draw and Brew resume unfinished work, while Distill regenerates derived documents. Run them from a hook, from cron, or by hand.

With no arguments, draw looks at configured session files modified in the last 24 hours. Use --since 7d (or an RFC3339 timestamp) to widen the window. --max N safely works through historical data: it selects at most N unfinished turns across all configured history, resumes already acquired turns first, and then proceeds from newer turns to older ones. Repeating it from cron eventually consumes the backlog without an unbounded LLM run:

knowbrew draw --max 100
knowbrew brew --max 100
knowbrew distill --max 2

The draw summary reports turns_selected for the current run and turns_pending for the unfinished turns remaining in its source scope. For Brew, --max counts Subjects with unorganized Knowledge, and changed_subjects names the Subjects whose Knowledge actually changed, so you know where to start approving. For Distill, --max counts Subject documents. Bounded Distill runs continue from the next Subject and Template on the following run, so repeated invocations rotate through all assigned documents even though each document remains regenerable.

Review what was created, and promote what you want your agent to use:

# knowledge/kn-8f17c9a6b4d2e301.md
approved: true   # was: false

The SessionStart hook that init registers runs knowbrew context: it injects distilled Subject documents whose template declares inject: always, plus the documents of the subject whose aliases match the current working directory (inject: subject — the default decisions template opts in). Documents distill only approved knowledge. [context] max_tokens bounds how much document body is injected; the fixed preamble that marks the documents as untrusted data, and the closing note listing anything left out, are always emitted on top of it. Everything else your agent finds by searching.

Daily use

Search your knowledge:

knowbrew knowledge -- sqlite locking
knowbrew knowledge --subject myproject --type decision

Look back at what actually happened:

knowbrew feedstock --last 10       # the last 10 turns
knowbrew feedstock -- deploy       # when did we touch deploys?
knowbrew show <feedstock-id> --raw # the original conversation

Keywords go after --. With keywords you get relevance ranking; without them you get newest-first, which makes feedstock a readable timeline of what you worked on.

When semantic search is enabled, keyword queries run FTS5 and vector search in parallel and merge their ranks with reciprocal rank fusion. Knowledge vectors contain only the claim; feedstock vectors contain only the summary. Exact subject, type, lifecycle, agent, session, and time filters still apply. Search scores are intentionally not exposed because they are ranks, not confidence. Use --search-mode text or --search-mode vector only when diagnosing one branch; the default is hybrid.

Your agent uses these same commands. init writes usage instructions into your CLAUDE.md / AGENTS.md so it knows when to reach for them.

Token usage

While draw, brew, or distill runs, the progress line shows cumulative input and output tokens (in ... / out ...), and the final JSON includes a usage object with the backend, model, and per-class token counts. Multiply those by your provider's current rates to get the cost. knowbrew ships no price table because provider prices change independently of the CLI.

Knowledge types

Every knowledge record has exactly one type. Types are master notes under masters/types/; their filenames are the values accepted by --type. init creates these eight defaults:

| Type | What it holds | |---|---| | definition | The established meaning or boundary of a term or concept | | property | A durable established attribute or capability, excluding temporary configuration, execution results, and task state | | relation | An established relationship between subjects or concepts | | principle | An established generalized cause, mechanism, or recurring tendency | | constraint | An established externally imposed limit or required condition | | decision | A settled choice intended beyond the current task, excluding tentative or one-time adjustments | | intent | A durable intended outcome or quality that explains why a subject, rule, or design exists independently of its current implementation | | preference | A stable stated preference, rather than a one-time request or binding decision |

Types are useful as filters (--type decision to review your decisions), and they keep brewing honest: a claim is recorded only when it fits one type exactly.

You can edit the master wording, add types, or delete unused ones. Defaults are regenerated only when masters/types/ has no type notes at all; if even one remains, knowbrew leaves the directory untouched.

Subjects

Subjects are stable target names stored as master notes under masters/subjects/. knowbrew adds one automatically only when it can derive it from a Git repository, recording the remote and working directory as aliases.

A subject note may contain definition, includes, excludes, and documents. The documents property declares which documents should be generated for that Subject. Each value is a wikilink to the corresponding definition under masters/templates/; an empty list excludes that Subject from distillation. The other fields decide what belongs to the subject; a name alone is the fallback when they are absent, and an exclusion overrides a name match.

Only you can create subjects — knowbrew never invents one. An unknown --subject is an error, and there is no --new-subject flag. Create, rename, merge, or delete subject notes directly in your vault. Claims that match no subject are stored unorganized without a Subject and stay outside Brew, search, Distill, and session-start injection until their Knowledge file is assigned an existing Subject.

Distilled documents

init creates four starter Template masters: concept, reference, decisions, and glossary. A Template describes the document's purpose, readers, scope, completion criteria, output filename, and Markdown structure. Declare the documents to generate in a Subject note:

documents:
  - "[[concept]]"
  - "[[reference]]"

knowbrew distill checks every approved, current Knowledge record for each requested Subject document, then writes documents/<subject>/<template-output>. It removes outputs that no longer have any valid supporting Knowledge. Use --subject or --template to limit a run.

Configuration

init writes <root>/.knowbrew/config.toml:

root = ".."

[llm]
backend = "claude-cli"    # or codex-cli, api, ollama
draw_draft_model = ""     # per-turn classification: prefer a fast model
draw_extract_model = ""   # Knowledge extraction: prefer a strong model
brew_model = ""           # Subject organization: prefer a strong model
distill_model = ""        # document synthesis: prefer a strong model
draw_draft_effort = "low" # repeated classification: low is the init default
draw_extract_effort = ""  # empty uses the backend or user default
brew_effort = ""          # empty uses the backend or user default
distill_effort = "high"   # document selection and synthesis
timeout = "5m"

[draw]
concurrency = 5           # parallel LLM workers
context_turns = 3         # earlier dialogue turns given to the extractor
max_context_turns = 20    # bounded fallback window

[context]
max_tokens = 2000         # approximate token budget for injected document bodies

[embedding]
model = "ruri-v3-130m-int8-onnx" # or snowflake..., qwen3..., disabled, custom
# path = "/absolute/path/to/model" # required only for custom

[[sources]]
agent = "claude"
parser = "claude"
paths = ["/Users/example/.claude/projects"]

[[sources]]
agent = "codex"
parser = "codex"
paths = [
  "/Users/example/.codex/sessions",
  "/Users/example/.codex/archived_sessions",
]

Draw runs two stages, and each names its own model and effort. The retired draw_model and draw_effort keys are rejected with migration guidance; run knowbrew init to rewrite them, which carries the retired values into draw_draft_* and the Brew values into draw_extract_*.

Each source is one logical collection and can span multiple directories. init configures both the active and archived Codex session directories. Feedstocks do not store these physical paths, so moving a session between the configured directories does not break show --raw, Draw resume, or Brew.

Empty model values use the CLI backend's own default. api and ollama require all four models and read credentials from the environment:

export KNOWBREW_API_URL=https://api.example.com/v1/chat/completions
export KNOWBREW_API_KEY=...

Keys are read from the environment only and are never written into your knowledge root. ~/.config/knowbrew/location.toml records where your root is, so knowbrew works from any directory.

CLI backends run your own agent, so your CLAUDE.md / AGENTS.md apply: what knowbrew writes follows your instructions, including the language you write in. Your MCP servers are not loaded for these background jobs. knowbrew's own hooks exit immediately inside them, preventing recursive Draws and Knowledge lookup.

init offers Japanese-recommended Ruri, English-recommended Snowflake, quality-first Qwen3, or disabled full-text-only search. knowbrew downloads and pins the selected managed model and runtime under .knowbrew/state/models/. Configured managed or custom model files must be usable; knowbrew never hides a model error by silently falling back to text search.

For a self-managed model, set model = "custom" and point path at a directory containing manifest.json. The manifest requires id, backend, dimension, and model_file; ONNX additionally uses tokenizer_file, runtime_file, input_names, and output_name, while llama.cpp uses executable_file. Manifest file paths are relative to that directory.

Requirements

  • One LLM backend: Claude Code CLI, Codex CLI, an OpenAI-compatible endpoint with tool calling, or Ollama with a tool-capable model
  • Go 1.25 or later and a C compiler only if you build from source (FTS5 uses pure Go; sqlite-vec is statically linked through its official Go binding)

Alternative installs:

go install github.com/siro33950/knowbrew/cmd/knowbrew@latest

Prebuilt binaries are on GitHub Releases.

Command reference

knowbrew init                      interactive setup
knowbrew draw [flags] [path...]    session logs → feedstock + unorganized knowledge
knowbrew brew [flags]              unorganized → organized pending knowledge
knowbrew distill [flags]           approved knowledge → Subject documents
knowbrew knowledge [keywords...]   search knowledge (alias: kn)
knowbrew knowledge show <id...>    inspect knowledge in any lifecycle state
knowbrew feedstock [keywords...]   search or replay feedstock
knowbrew document [keywords...]    search distilled Subject documents
knowbrew context                   print session-start context from distilled documents
knowbrew show <id...>              one feedstock record; --raw for the dialogue
knowbrew index sync|rebuild|status maintain the derived search indexes

knowledge and feedstock share --type, --since, --until, --limit, --max-tokens, --reindex, and --search-mode. knowledge adds --subject, --include-pending, and --include-retired; feedstock adds --session, --agent, and --last N. document searches distilled Subject documents with --subject and --template instead of --type.

draw flags: --max N, --since, --until, --source claude|codex, --verbose. Explicit files and directories must be inside a configured source path. They are never time-limited unless you also pass --since or --until.

brew flags: --max N, --verbose.

distill flags: --max N, --subject, --template, --verbose.

Some subcommands exist only for the LLM backend to call and are not meant for direct use.

Security

Your session logs are read-only, generated knowledge stays unapproved until you check it, and API credentials are read from environment variables only. See SECURITY.md for the trust model and how to report a vulnerability.

Development

go test ./...
go vet ./...
gofmt -l .

Parser checks against real logs, without copying them:

KNOWBREW_TEST_CLAUDE_LOG=/path/to/session.jsonl \
KNOWBREW_TEST_CODEX_LOG=/path/to/rollout.jsonl \
go test -v ./internal/parser -run TestRealLogWhenConfigured

Maintainers release by pushing a version tag; ordinary pushes only run tests.

git tag vX.Y.Z
git push origin vX.Y.Z

License

MIT