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

@justestif/pk

v0.13.0

Published

Project knowledge — structured intake, search, and recall

Downloads

287

Readme

pk

Structured project memory for AI agents. Decisions, questions, notes, and sources — organized, searchable, stored locally.

Install

CLI

One-liner (macOS / Linux):

curl -fsSL https://justestif.github.io/pk/install.sh | bash

Or manually:

# npm
npm install -g @justestif/pk

# bun
bun install -g @justestif/pk

# Homebrew
brew install justEstif/tap/pk

Requires:

  • Git — tracks all knowledge operations via commits and git notes
  • Bun — runtime

Note: If you have GPG commit signing enabled globally (commit.gpgsign=true), pk init bypasses it for the knowledge repo to avoid interactive prompts. No configuration needed.

Setup

pk init

Tip: You can override the knowledge directory at any time by setting PK_KNOWLEDGE_DIR in your shell or a .env file your shell loads:

export PK_KNOWLEDGE_DIR=~/.pk/my-project

All pk commands read this variable directly — no re-init needed. This is also how you switch between projects without changing harness config.

Interactive: picks a project name and one or more harnesses (space to toggle, enter to confirm).

Non-interactive:

pk init --harness opencode                        # local: knowledge in .pk/ (default)
pk init my-project --harness opencode --global   # global: knowledge in ~/.pk/my-project/
pk init my-project --harness opencode,pi --global   # multiple harnesses

Available harnesses: opencode (OpenCode), pi (Pi).

pk init does four things:

  1. Creates the knowledge store — in .pk/ (local, default) or ~/.pk/<name>/ (with --global)
  2. Writes config: local mode creates .pk/config.json in the project; global mode sets currentProject in ~/.pk/config.json
  3. Adds .pk/ to your project's .gitignore (local mode only)
  4. Installs plugin/extension and skill to global locations (~/.config/opencode/plugins/, ~/.pi/agent/extensions/, ~/.agents/skills/pk/)

| Harness | Files written (global) | | ----------------- | ------------------------------------------------------------------------------ | | opencode | ~/.config/opencode/plugins/pk-eval.ts | | pi | ~/.pi/agent/extensions/pk-eval.ts | | both | ~/.agents/skills/pk/ |

Override: PK_KNOWLEDGE_DIR env var takes precedence over all resolution. For persistent switching, use pk use <name>.

Commands

pk init [name] [--harness h1,h2,...]   # set up project + global harness
pk use <name>                          # set current global project
pk projects                            # list global projects

pk new <type> <title> [--tags t1,t2] [--expires YYYY-MM-DD]
pk delete <path>                       # JSON output, non-interactive
pk search <query> [--limit 5] [--type] [--status] [--tag]
pk gc [--dry-run] [--compress]          # lifecycle: decay + expiry + compress
pk synthesize [query] [--all]
pk history [--limit 20] [--type <type>] [--filter-type <type>] [--filter-tag <tag>] [--filter-operation <op>]
pk read <path>
pk write <path>                        # write content from stdin + commit
pk vocab
pk index                               # rebuild FTS5 + markdown indexes
pk lint [paths...]
pk prime                               # output priming context for hooks
pk instructions <command>
pk config [--embedding <model>] [--no-embedding] [--base-url <url>]

All commands output JSON by default. Use --pretty for human-readable output.

Note types

| Type | Purpose | | ---------- | -------------------------------------------------- | | note | Durable project knowledge | | decision | Chosen direction with rationale and consequences | | question | Unresolved uncertainty that blocks or informs work | | source | Raw input preserved for provenance | | index | Navigation/map-of-content over a topic or tag |

Example

pk init --harness opencode
pk new decision "Use SQLite for search index" --tags search,architecture
pk new question "Should we support multi-project mode?" --tags scope
pk index
pk search "sqlite"
pk synthesize

Lifecycle

Knowledge has a lifecycle. Notes decay, expire, and get superseded.

  • Decay: notes not accessed fade over time (exponential decay, 30-day half-life). pk gc archives notes below threshold.
  • Expiry: pk new note "Title" --expires 2026-12-31 adds an expiry date. pk gc archives expired notes automatically.
  • Compression: pk gc --compress identifies similar/duplicate notes (Jaccard similarity ≥ 0.5 within same type) and detects near-duplicate tags (plural variants, edit distance ≤ 2). Tag normalization is applied automatically — variants are replaced with the canonical (most-used) form. Similar note pairs are reported for manual review. Use --dry-run to preview without changes. Run weekly.
  • Contradictions: when new knowledge supersedes old, mark the old note status: superseded and link to the new one. pk lint warns on high-overlap note pairs.
# Daily: decay scoring + archive stale + purge expired
pk gc

# Weekly: find similar notes for merge
pk gc --compress

# Preview without changes
pk gc --dry-run --pretty

Configure decay speed: PK_DECAY_HALF_LIFE=30 (default, days).

Knowledge structure

Notes live as plain markdown files — human-editable and git-diffable. Agents read and write them exclusively through the CLI. Humans can edit files directly, but should run pk write <path> < <file> or commit manually afterward to keep the git history clean.

Local (default — .pk/ in your project):

your-project/
  .pk/
    notes/
    decisions/
    questions/
    sources/
    indexes/        ← generated by pk index
    .index.db       ← FTS5 search index, gitignored
    config.json     ← points to this knowledge store

Global (--global — shared across machines, survives project moves):

~/.pk/
  config.json            ← currentProject: which global project is active
  <project-name>/
    notes/ decisions/ questions/ sources/ ...

Run pk index after creating or editing notes to update .index.db and indexes/.

pk vocab lists all tags by frequency — useful for orienting before searching.

pk history shows all knowledge operations (create, update, delete) as git commits and synthesize operations as git notes. Supports filtering by type, tag, and operation.

Embeddings (optional)

pk can generate embeddings via a local Ollama model and store them alongside the FTS5 index. Once configured, pk search automatically uses hybrid search — BM25 keyword ranking fused with vector similarity via RRF.

# Install Ollama — https://ollama.com
ollama pull nomic-embed-text

# Enable embeddings
pk config --embedding nomic-embed-text

# Rebuild index to generate embeddings
pk index

# Search now uses hybrid automatically
pk search "slow database queries"

Embeddings are stored in .index.db and rebuilt on pk index. If no embedding model is configured, search falls back to keyword-only FTS.

License

MIT