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

@gnolith/seedbed

v0.3.2

Published

Headless local process assembly for Gnolith.

Readme

Seedbed

Seedbed assembles Gnolith as one local, headless Node.js process. It uses a durable SQLite file, exposes tools over MCP stdio or one-shot commands, and never starts an HTTP server, listening socket, UI, or implicit migration.

Requirements

  • Node.js 24
  • public exact @gnolith/diamond, @gnolith/taproot, and @gnolith/workshop versions
  • a restart-stable file or inherited descriptor containing exactly 32 random bytes

Start

Create the root-secret file with an operating-system secret manager or a CSPRNG, and restrict it to the Seedbed process account. Never place the bytes in a command, environment variable, JSON configuration, log, or MCP argument.

seedbed --base-iri https://example.com/my-gnolith/ --root-secret-file /run/secrets/seedbed-root init
seedbed --base-iri https://example.com/my-gnolith/ --root-secret-file /run/secrets/seedbed-root \
  --principal owner --workspace primary auth bootstrap
seedbed --base-iri https://example.com/my-gnolith/ --root-secret-file /run/secrets/seedbed-root \
  --principal owner --workspace primary auth status
seedbed --base-iri https://example.com/my-gnolith/ --root-secret-file /run/secrets/seedbed-root \
  --principal owner --workspace primary mcp --stdio

init only creates a new package assembly. migrate is the only normal command that advances package schemas. Authorization remains quarantined until the explicit, one-time auth bootstrap atomically creates the first durable grants and advances Taproot's sole authorization/search generation. An identical bootstrap retry is idempotent; a different second bootstrap is rejected.

Commands

seedbed init
seedbed migrate
seedbed doctor
seedbed auth bootstrap
seedbed auth status
seedbed auth apply --manifest ./principal-authorization.json
seedbed auth backfill taproot --manifest <path>
seedbed auth backfill workshop --domain <task|memory>
seedbed snapshot create --output ./installation.seedbed-snapshot.gz
seedbed snapshot inspect --input ./installation.seedbed-snapshot.gz
seedbed snapshot verify --input ./installation.seedbed-snapshot.gz
seedbed snapshot restore --input ./installation.seedbed-snapshot.gz
seedbed mcp --stdio
seedbed tools
seedbed call <tool-name> [--arguments '{"key":"value"}']

Principal authorization changes are strict host-only manifests and never MCP tools. They replace the principal's enabled flag, complete workspace set, and complete capability set in one Taproot authorization advance. Bind every change to the revision reported by auth status:

{
  "version": 1,
  "expectedAuthorizationRevision": 2,
  "principal": "agent",
  "enabled": true,
  "workspaces": ["primary"],
  "capabilities": ["read", "task-write"]
}

To revoke a principal, set enabled to false and both arrays to empty. Stale manifests fail without writes. Seedbed also rejects any update that would remove the final enabled principal holding exact admin, knowledge:write, and knowledge:policy, preventing an unrecoverable authorization lockout.

There is no raw SPARQL command. Legacy authorization rows remain invisible until an explicit, bounded host-only backfill. Maintenance requires exact search:admin; principal changes additionally require exact admin, Taproot knowledge:write, and Taproot knowledge:policy. These Taproot capabilities are required by its guarded installation advance and are distinct from Workshop's knowledge-write; generic admin implies none of them.

Taproot's search and search_hydrate tools provide the single relevance-search surface. Seedbed owns Resource and Annotation CRUD/hydration tools and runs the bounded Taproot materializer after successful mutations and during graceful drain. Materialization and semantic maintenance tools require exact search:admin. Task, Memory, and Prompt results are enabled only when their exact Workshop-owned producer adapters are present; Seedbed does not duplicate those domain owners.

Authorized item_history/item_revision, statement_history/statement_revision, resource_history/resource_revision, and annotation_history/annotation_revision expose bounded canonical revisions without bypassing current visibility. Existing Item mutations preserve the complete current statement authorization map when statementRestrictions is omitted; an explicitly supplied replacement must exactly cover the post-mutation statement IDs. Workshop-owned task_history, memory_history, and prompt_history are composed through the same current-authorization recheck across process and MCP boundaries.

Structured results are one-line JSON on stdout. Diagnostics and JSON logs go only to stderr. Exit codes are 0 success, 2 usage, 3 configuration, 4 persistence/readiness, 5 authorization, and 6 operation failure.

Configuration

Precedence is CLI, then SEEDBED_* environment variables, then seedbed.config.json, then defaults.

| Setting | CLI | Environment | Default | | --- | --- | --- | --- | | SQLite path | --database | SEEDBED_DATABASE_PATH | ./.seedbed/gnolith.sqlite | | local blob path | --blobs | SEEDBED_BLOB_PATH | ./.seedbed/blobs | | SQLite busy timeout | --busy-timeout-ms | SEEDBED_BUSY_TIMEOUT_MS | 5000 | | stable base IRI | --base-iri | SEEDBED_BASE_IRI | none | | root-secret file selector | --root-secret-file | SEEDBED_ROOT_SECRET_FILE | none | | inherited secret descriptor | --root-secret-fd | SEEDBED_ROOT_SECRET_FD | none | | principal selector | --principal | SEEDBED_PRINCIPAL_SELECTOR | none | | workspace selector | --workspace | SEEDBED_WORKSPACE_SELECTOR | none | | log level | --log-level | SEEDBED_LOG_LEVEL | info |

Exactly one root-secret selector is required for authorization. Seedbed derives non-extractable, installation-bound and domain-separated keys with HKDF-SHA-256. Changing the secret, installation, or base IRI fails closed across restarts.

Optional semanticConfigurations are declared only in the JSON configuration. Each chooses an OpenAI- or Ollama-compatible embedding endpoint and either SQLite or Qdrant vectors. Provider and Qdrant credentials use { "file": "..." } or { "fd": 3 } selectors; literal credential values, environment credential bytes, CLI credential flags, and MCP credential arguments are intentionally unsupported. Private endpoints require the explicit allowPrivateEndpoint opt-in. See seedbed.config.example.json for the complete shape.

Snapshot and restore

Snapshot maintenance requires an authorized principal with exact search:admin. snapshot create uses SQLite's consistent VACUUM INTO boundary, includes every local blob with byte length and SHA-256 metadata, and writes a compressed portable envelope with an exclusive create. Root secrets, credential bytes, access tokens, and secret selectors are never included. Keep those separately in an OS secret facility. The candidate archive is fully decoded and checksum-verified before it is atomically published. Compressed, expanded, and decoded payload sizes are explicitly bounded, including archives containing blobs larger than 32 MiB.

snapshot verify checks the database and every blob before any restore write. snapshot restore accepts only an empty target installation, validates the exact package schema, stable base IRI, root-secret binding, installation identity, and administrator authorization in staging, installs blobs first, and exposes the canonical database last. A failed or interrupted restore removes staging state without replacing a valid installation.

Docker

The image runs as the unprivileged node user, uses tini, exposes no port, defaults to MCP stdio, and stores SQLite at /var/lib/seedbed/gnolith.sqlite. Mount the root secret read-only; do not pass its bytes as an environment value. On Linux it must be owned so the image's non-root node user can read it while group and other permission bits remain clear (for example, owner-readable mode 0400).

docker volume create seedbed-data
docker run --rm -i \
  -v seedbed-data:/var/lib/seedbed \
  -v /host/secret/seedbed-root:/run/secrets/seedbed-root:ro \
  -e SEEDBED_BASE_IRI=https://example.com/my-gnolith/ \
  -e SEEDBED_ROOT_SECRET_FILE=/run/secrets/seedbed-root \
  ghcr.io/gnolith/seedbed:0.3.2 init

See docs/migrations.md for exact transition and recovery rules and docs/release.md for trusted publishing.