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

@taurgis/bonsai

v3.2.0

Published

Bonsai is a standalone local research cache CLI for AI agents

Downloads

1,411

Readme

Bonsai

Bonsai is a standalone local research cache CLI for AI agents. It turns official documentation and web pages into source-cited Markdown artifacts, stores them in a durable local cache, and returns deterministic output that agents can reuse instead of repeatedly scraping the same pages.

The package is published as @taurgis/bonsai and installs a bonsai binary.

📚 Full documentation: bonsai.rhino-inquisitor.com

Because the npm package is scoped, the correct one-shot command is npx @taurgis/bonsai .... The unscoped npx bonsai name resolves to the separate bonsai package on npm unless an unscoped shim is published later.


What it Does

| Feature | How it works | Typical use case | | --- | --- | --- | | Scrape and convert | Fetches HTML, extracts main content, sanitizes unsafe markup, and converts it to deterministic Markdown | Capturing API docs, guides, standards, and changelogs | | Cache-first lookup | Normalizes URLs to collision-resistant SHA-256 keys before fetching | Avoiding duplicate network requests and repeated agent research | | Token budgeting | Returns compressed or detailed Markdown variants | Fitting research into limited context windows without losing full detail | | Freshness tiers | Supports stable, standard, volatile, custom TTLs, and stale revalidation | Handling standards differently from release notes or beta docs | | Browser fallback | Uses --rendered for pages that need client-side JavaScript | Capturing SPA documentation when static HTML is incomplete | | Manual import | Stores agent-supplied Markdown from stdin or files | Caching synthesized notes, private docs, or manually extracted pages | | List | Filters cached entries by topic, tags, freshness, and metadata | Seeing what is already cached without reading full content |


Installation

Requires Node.js 22 or newer.

Run Bonsai without installing it globally:

npx @taurgis/bonsai https://nodejs.org/api/url.html

Install it as a normal CLI:

npm install -g @taurgis/bonsai
bonsai https://nodejs.org/api/url.html

Use the local development binary inside this repository:

pnpm install
pnpm build
node bin/cli.mjs --help

Quick Start

1. Fetch and cache a URL

npx @taurgis/bonsai https://nodejs.org/api/url.html

The first run fetches the page, extracts the main article content, converts it to Markdown, estimates token size, and stores it locally.

2. Reuse the cache

npx @taurgis/bonsai https://nodejs.org/api/url.html

The second run returns from cache when the entry is still fresh.

3. Check cache state and metadata

npx @taurgis/bonsai status https://nodejs.org/api/url.html
npx @taurgis/bonsai inspect https://nodejs.org/api/url.html

4. Import manual research notes

echo "# My Custom Node API Notes" | npx @taurgis/bonsai import https://nodejs.org/api/url.html --stdin

echo "# Synthesized React Cache Guide" | npx @taurgis/bonsai import --stdin --topic "React Suspense" --source-url https://react.dev/a --source-url https://react.dev/b

5. List cached entries

npx @taurgis/bonsai list --tags node

Command Reference

<url>

Fetch and format a webpage, or retrieve it from cache.

npx @taurgis/bonsai <url> [flags]

Common flags:

  • --topic, -t: Primary category/topic for metadata tagging.
  • --tags, -g: Searchable tags. Can be repeated. When omitted, tags are auto-generated from the content by keyword detection (recorded with an auto-generated tags via keyword extraction quality note); passing --tags always takes precedence.
  • --format, -f: Output density: compressed or detailed.
  • --tier: Freshness tier: stable, standard, or volatile.
  • --ttl, -l: Custom predicted lifespan, such as 2h, 7d, or 30d.
  • --max-age: Read-time freshness threshold.
  • --force: Force a fresh fetch.
  • --dry-run: Scrape and validate without writing to cache.
  • --allow-stale: Serve stale cache if the remote site is offline.
  • --rendered: Use browser-rendered extraction for SPA pages.
  • --read-only (alias --plan): Block all filesystem writes/deletes across every command; network fetches still run. See Read-only / plan mode below.
  • --json: Return structured machine-readable output.

import [url]

Save custom Markdown notes directly to the cache. As with fetch, when --tags is omitted the tags are auto-generated from the note content by keyword detection.

npx @taurgis/bonsai import [url] --stdin [flags]

status <url>

Inspect cache state and planned action without fetching.

npx @taurgis/bonsai status <url> [flags]

inspect <url>

Display stored YAML frontmatter metadata for a URL.

npx @taurgis/bonsai inspect <url>

list

List cached artifacts by metadata filters (--topic, --tags, --freshness, --artifact-type, --capture-method, --limit), newest first, without printing content.

npx @taurgis/bonsai list [flags]

prune

Delete old or inactive cache entries. Requires a filter (--older-than, --inactive, --artifact-type, or --url) and exactly one of --dry-run or --yes (passing both is a usage error). In read-only mode, --yes is rejected and the safety check is implicitly satisfied by a preview.

npx @taurgis/bonsai prune --older-than 90d --dry-run

config

Two keys are configurable:

| Key | Values | Default | Effect | | --- | --- | --- | --- | | storage | global, project | global | Where cache files are stored. | | summary | conservative, balanced, aggressive | conservative | How aggressively the compressed format is shortened when structural compression alone leaves it close to detailed. Prose is condensed extractively (no LLM); headings, code blocks, tables, and lists are always preserved. |

npx @taurgis/bonsai config set storage project --local
npx @taurgis/bonsai config set summary balanced

Both keys can also be overridden per-invocation via the BONSAI_STORAGE and BONSAI_SUMMARY environment variables. Project config is stored in .bonsai.json; project cache files are stored under .bonsai/research/.

Read-only / plan mode

Every command accepts a global --read-only flag (alias --plan) that blocks all filesystem writes and deletes — cache persistence, config file writes, prune deletions — while still allowing network fetches to run. This is for agent harnesses (Claude Code and others) that enter a read-only "plan mode": set it once and every bonsai invocation for the rest of that session automatically skips writes, without needing the flag on every call.

BONSAI_READ_ONLY=1 npx @taurgis/bonsai https://example.com/docs
npx @taurgis/bonsai import https://example.com/docs --file notes.md --read-only
npx @taurgis/bonsai prune --older-than 90d --plan

It can also be set via the BONSAI_READ_ONLY or BONSAI_PLAN_MODE environment variables (both are equivalent). Composition is OR, not override: read-only mode is active if either env var or the flag is set, and there is no way to force writes back on once one of them is — this is a safety gate, not a preference. Commands that already expose --dry-run (fetch, prune, config set/unset) treat it the same as an explicit --dry-run; import (which has no --dry-run of its own) previews the write and reports dryRun: true instead of persisting.


Shell Autocomplete

Bonsai ships with shell autocomplete via @oclif/plugin-autocomplete. After installing globally, set it up once for your shell:

# Bash — add to ~/.bashrc
eval "$(bonsai autocomplete bash)"

# Zsh — add to ~/.zshrc
eval "$(bonsai autocomplete zsh)"

# Fish
bonsai autocomplete fish > ~/.config/fish/completions/bonsai.fish

To see full setup instructions including the copy-paste snippet for your shell:

bonsai autocomplete

Refresh cached completions after upgrading:

bonsai autocomplete --refresh-cache

Freshness and Cache Rules

Global cache files live in Bonsai's oclif data directory, typically:

  • macOS: ~/Library/Application Support/bonsai/research/
  • Linux: ~/.local/share/bonsai/research/
  • Windows: %LOCALAPPDATA%\bonsai\research\

Project-local storage uses:

  • .bonsai.json for the project config
  • .bonsai/research/ for Markdown cache artifacts

If no --ttl is specified, freshness is computed from the tier:

| Tier | Fresh duration | Grace window | Use case | | --- | --- | --- | --- | | volatile | 7 days | 5 days | Latest releases, volatile changelogs, beta docs | | standard | 30 days | 14 days | General API docs and developer guides | | stable | 180 days | 60 days | RFCs, standards, long-lived references |

When stale entries still have ETag or Last-Modified metadata, Bonsai attempts cheap revalidation before a full refetch. If revalidation fails and --allow-stale is omitted, the CLI can serve the stale content while exiting with code 5.


JSON Envelope

When run with --json, commands return a stable envelope:

{
  "schemaVersion": 1,
  "command": "bonsai",
  "ok": true,
  "exitCode": 0,
  "stdout": "",
  "stderr": "",
  "data": {
    "schemaVersion": 1,
    "command": "bonsai",
    "cache": {
      "key": "0f115db062b7c0dd030b16878c99dea5c354b49dc37b38eb8846179c7783e9d7",
      "status": "hit",
      "freshness": "fresh",
      "path": "/Users/user/Library/Application Support/bonsai/research/0f115db062b7c0dd030b16878c99dea5c354b49dc37b38eb8846179c7783e9d7.md"
    },
    "source": {
      "url": "https://example.com",
      "normalizedUrl": "https://example.com/",
      "captureMethod": "static_fetch",
      "extractionStatus": "extracted",
      "extractionConfidence": "low",
      "qualityNotes": ["readability extracted main article"],
      "fetchedAt": "2026-06-24T07:33:20.519Z",
      "validatedAt": "2026-06-24T07:33:20.519Z",
      "staleAfter": "2026-07-24T07:33:20.519Z"
    },
    "format": "compressed",
    "tokenEstimate": 29,
    "content": "Cleaned main content markdown text..."
  }
}

Environment Variables

| Variable | Effect | | --- | --- | | BONSAI_STORAGE | Override the default storage location per-invocation (global or project). | | BONSAI_SUMMARY | Override the summary compression level per-invocation (conservative, balanced, or aggressive). | | BONSAI_READ_ONLY / BONSAI_PLAN_MODE | Set to 1/true/yes to enable read-only/plan mode for every command in the session, equivalent to passing --read-only (--plan) each time. Either variable is sufficient; there is no way to override it back off from a single invocation. | | NO_COLOR | Set to any non-empty value to disable all ANSI color output. An empty NO_COLOR is treated as unset. | | FORCE_COLOR | Set to any value other than an empty string, 0, or false to force ANSI color on, even in non-TTY environments. | | TERM=dumb | Disables ANSI color output when the terminal cannot render escape sequences. | | NO_UPDATE_NOTIFIER | Suppress the "update available" notification. | | CI | Set to 1 or true to suppress the update notification in CI environments (detected automatically). | | DEBUG | Enable debug output for specific Bonsai namespaces, e.g. DEBUG=bonsai:*. |


Exit Codes

| Code | Meaning | | --- | --- | | 0 | Success. | | 1 | Runtime failure (network error, fetch failed, file read error). | | 2 | Usage error (invalid flag, bad URL, missing required argument). | | 5 | Stale content served — the cache entry is past its grace window but --allow-stale is set. The returned content is still usable. |


Security and Limits

  • Fetched HTML is treated as untrusted input.
  • Only http: and https: URLs are accepted.
  • Private and local IP ranges are blocked to reduce SSRF risk.
  • Static extraction does not execute JavaScript; use --rendered when a page needs browser execution.
  • Authenticated/private scraping is not supported in the default workflow. Import trusted Markdown manually instead.

Reference Documentation

The full documentation site lives at bonsai.rhino-inquisitor.com (built with VitePress from the docs/ folder). Key pages: