Bonsai turns a local repository into a small, repeatable context file for LLMs.
It scans source files, compresses code with syntax-aware summaries, respects your token budget, and writes XML or JSON you can paste into ChatGPT, Codex, Claude, Copilot, or another agent.
Use it when you want an LLM to understand a whole project before asking for architecture, onboarding, review, or branch-change help.
The core is a Rust CLI. Tree-sitter handles code structure; compact fallbacks handle Markdown, manifests, web templates, and Objective-C. The VS Code extension has its own TypeScript engine, while the Codex and Claude integrations use the CLI.
brew tap MickyBalladelli/bonsai https://github.com/MickyBalladelli/bonsai.git
brew install bonsaiInstall Bonsai, check it once, then run it inside a repository:
bonsai setupFull repository context:
bonsai .This writes:
bonsai.xml
The default is 12,000 tokens at compression level 1, written as XML. Level 1 preserves full source including implementation logic, types, configuration values, and meaningful comments, and fails if it cannot fit instead of silently downgrading or truncating; choose --level 2 or 3 explicitly for lossy compression.
Paste that file into an LLM and ask:
Use this Bonsai repo context. Explain the architecture and tell me where to start reading.
For a larger context budget:
bonsai . --max-tokens 24000 --level 1 --output-file /tmp/bonsai.xmlFor a paste-ready prompt:
bonsai . --prompt --output-file /tmp/bonsai-prompt.txtChoose the right flow from the decision table.
Save common choices in .bonsai.toml. Bonsai loads this file from the target
repository automatically. Command-line flags win over config values.
Full context:
bonsai .Changed context against a Git branch:
bonsai . --preset changed --changed-since main --output-file bonsai-changes.xmlProject map only:
bonsai . --preset map --output-file bonsai-map.xmlRun this once in any repo where you want agents to use Bonsai first:
bonsai init-agentIf the files do not already exist, it writes:
AGENTS.md
CLAUDE.md
Those files tell Codex, Claude Code, and similar agents to run Bonsai before answering broad project questions.
The command refuses to overwrite an existing file unless you pass --force.
Create only one file, or tune the generated instruction:
bonsai init-agent --files agents
bonsai init-agent --files claude --style detailed
bonsai init-agent --max-tokens 8000 --output-file /tmp/bonsai.xmlOverwrite existing files:
bonsai init-agent --forceDownload a release binary. The commands below verify SHA-256, install to the
standard /usr/local/bin/bonsai path, and leave no binary-path guessing.
https://github.com/MickyBalladelli/bonsai/releases/latest
Release assets:
bonsai-linux-x64
bonsai-macos-arm64
bonsai-linux-x64.sha256
bonsai-macos-arm64.sha256
bonsai-vscode-*.vsix
macOS Apple Silicon:
curl -fL -o bonsai-macos-arm64 https://github.com/MickyBalladelli/bonsai/releases/latest/download/bonsai-macos-arm64
curl -fL -o bonsai-macos-arm64.sha256 https://github.com/MickyBalladelli/bonsai/releases/latest/download/bonsai-macos-arm64.sha256
if test "$(awk '{print $1}' bonsai-macos-arm64.sha256)" != "$(shasum -a 256 bonsai-macos-arm64 | awk '{print $1}')"; then
echo "SHA-256 verification failed"
exit 1
fi
chmod +x bonsai-macos-arm64
sudo install -m 755 bonsai-macos-arm64 /usr/local/bin/bonsai
bonsai --versionLinux x64:
curl -fL -o bonsai-linux-x64 https://github.com/MickyBalladelli/bonsai/releases/latest/download/bonsai-linux-x64
curl -fL -o bonsai-linux-x64.sha256 https://github.com/MickyBalladelli/bonsai/releases/latest/download/bonsai-linux-x64.sha256
if test "$(awk '{print $1}' bonsai-linux-x64.sha256)" != "$(sha256sum bonsai-linux-x64 | awk '{print $1}')"; then
echo "SHA-256 verification failed"
exit 1
fi
sudo install -m 755 bonsai-linux-x64 /usr/local/bin/bonsai
bonsai --versionInstall from this checkout:
cargo install --path .Install from GitHub:
cargo install --git https://github.com/MickyBalladelli/bonsai.gitHomebrew formula:
brew install --build-from-source ./Formula/bonsai.rbTo install this repository as a tap, use the explicit URL because the
repository is named bonsai, not homebrew-bonsai:
brew tap MickyBalladelli/bonsai https://github.com/MickyBalladelli/bonsai.git
brew install bonsaiThe formula builds from the tagged source and needs Rust. Release binaries are faster when a matching macOS Apple Silicon or Linux x64 asset is available. See the Homebrew guide if you are publishing a tap.
Check your install:
bonsai setup
bonsai doctorBonsai has three compression levels:
--level 1 Full source including implementation logic, types, configuration values, and meaningful comments; fails if it cannot fit (default)
--level 2 Explicit opt-in lossy imports, signatures, types, classes, and function shapes
--level 3 Explicit opt-in lossy compact tree map only
Example source:
fn greet(name: &str) -> String {
let message = format!("hello {name}");
println!("{message}");
message
}Level 2 skeleton:
fn greet(name: &str) -> String { ... }Level 3 tree map:
fn greet(name: &str) -> String
Markdown keeps headings, useful summary text, tables, lists, links, and code fence language names. Config files keep important top-level shape, supported top-level comments, and tuned nested sections for common manifests like package.json, GitHub workflows, Cargo.toml, Codex plugin manifests, and VS Code manifests. Markdown, config, and web-template line truncation is token-aware. Long Markdown tables/lists and import/include/use blocks keep the first few lines and collapse the rest.
Write XML to bonsai.xml:
bonsai .Use a simple flow preset:
bonsai . --preset full
bonsai . --preset changed
bonsai . --preset map
bonsai . --preset promptfull is the normal context, changed uses the local cache, map writes only
the project map, and prompt wraps the context and copies it to the clipboard.
Create .bonsai.toml in a repository to keep the settings you use most:
max_tokens = 12000
level = 1
format = "xml"
output = "file"
output_file = "bonsai.xml"
include = ["src/**"]
exclude = ["**/generated/**"]
respect_gitignore = true
exclude_generated = falseSupported settings are preset, max_tokens, tokenizer, max_file_bytes,
max_file_tokens, level, output, output_file, format,
project_map_only, incremental, changed_since, include, exclude,
respect_gitignore, and exclude_generated. Use --config PATH to load a
different file.
Check first-run setup:
bonsai setupWrite JSON:
bonsai . --format json --output-file /tmp/bonsai.json
bonsai . --format text --output-file /tmp/bonsai.txtCopy a prompt to the clipboard:
bonsai . --prompt --output clipboardUse a model-family tokenizer:
bonsai . --tokenizer gpt-4o
bonsai . --tokenizer o200k_baseMake a compact architecture map:
bonsai . --level 3Write only the project map:
bonsai . --project-map-only
bonsai . --project-map compact --project-map-onlyInclude stable file hashes in the project map:
bonsai . --file-hashesOmit token count fields from XML/JSON:
bonsai . --no-token-countsWrite metadata and project map without file bodies:
bonsai . --no-contentShow selected files:
bonsai . --print-filesPreview selected files and estimated tokens without writing output:
bonsai . --dry-runSuppress normal stdout for scripts:
bonsai . --quiet --output-file /tmp/bonsai.xmlGenerate shell completions:
bonsai completions bash > ~/.local/share/bash-completion/completions/bonsai
bonsai completions zsh > ~/.zfunc/_bonsai
bonsai completions fish > ~/.config/fish/completions/bonsai.fishFilter files:
bonsai . --include 'src/**' --exclude '**/generated.rs'
bonsai . --exclude-generated--exclude-generated skips minified, vendored, generated, and lockfile-like files. A matching --include pattern keeps explicit paths.
Sort output:
bonsai . --sort priority
bonsai . --sort tokens
bonsai . --sort pathAdd directory token summaries:
bonsai . --directory-summariesUse only metadata, the project map, and directory summaries when the requested budget is tiny:
bonsai . --max-tokens 800 --map-only-under 1000Fail if output cannot fit after maximum compression:
bonsai . --max-tokens 12000 --fail-over-budgetDrop lowest-priority files if maximum compression still does not fit:
bonsai . --max-tokens 12000 --drop-low-priorityCap very large files before the global budget pass:
bonsai . --max-file-tokens 2000Advanced options are grouped in bonsai --help under Budget, Output, Changes,
Selection, Diagnostics, and Prompt.
See the generated CLI option reference. Refresh it after
changing CLI flags with sh scripts/generate-cli-reference.sh.
Recommended local changed-context flow:
bonsai .
bonsai . --preset changedThe first command creates the local baseline. The second command includes only
added or changed files and prints change counts. Run the normal command again
when you want to refresh the baseline. Use bonsai cache clear if the baseline
becomes stale.
Only include files changed since the last cached local run:
bonsai . --incrementalShow the incremental counts:
bonsai . --incremental --incremental-summaryCompare with another checkout or cache file:
bonsai . --incremental-base /path/to/base/repo
bonsai . --incremental-base /path/to/base.cacheInclude tracked changes and untracked files against a git ref:
bonsai . --preset changed --changed-since mainUse the local cache for repeated work. Use --changed-since <git-ref> for a
branch comparison. Do not combine --changed-since with --incremental or an
incremental base.
Clear the local parse cache for a repo:
bonsai cache clear
bonsai cache clear /path/to/repoSee the cache guide for cache location, invalidation, and the three changed-context workflows.
Bonsai stores file-selection options with the cache. If --include, --exclude, --exclude-generated, --max-file-bytes, or gitignore handling changes, the next incremental run includes selected files once instead of comparing against stale selection.
XML is default. JSON is available with --format json. Lower-overhead text is available with --format text.
Output includes:
metadata generated time, repo root, token budget, level, file count
project_map file path, selected level, token count, optional hash
files compressed file content and per-file token count
Use --no-token-counts to omit token count fields from XML/JSON output.
Schema details:
docs/output-schema.md
Tree-sitter parsing:
.js .jsx .ts .tsx .py .rs .go .java .cs .swift .kt .c .h .cpp .hpp
Compact fallback:
.m .mm .vue .svelte .astro .html .md .json .yaml .yml .toml
The supported-file table shows parser-backed files and compact fallback files:
bonsai doctor reports the installed parser mode and availability.
Bonsai respects .gitignore and .cursorignore by default.
This repo includes a Codex plugin:
plugins/bonsai
Add the local marketplace:
codex plugin marketplace add ./.agents/pluginsThen install or enable bonsai in Codex.
Ask:
Use $bonsai to compress this repo before answering.
This repo includes a Claude Code plugin:
claude/bonsai
Run Claude Code with the plugin:
claude --plugin-dir ./claude/bonsaiUse the skill:
/bonsai:bonsai
The VS Code extension Bonsai Context Manager is published on the Visual Studio Marketplace:
https://marketplace.visualstudio.com/items?itemName=MickyBalladelli.bonsai-vscode
Install it from the Marketplace, or run:
code --install-extension MickyBalladelli.bonsai-vscodeThe extension source lives here:
copilot/bonsai-vscode
Primary Command Palette commands:
Bonsai Context Manager: Generate
Bonsai Context Manager: Generate Changed
Bonsai Context Manager: Generate for Request
Bonsai Context Manager: Generate and Ask
Bonsai Context Manager: Preview Project Map
Other commands add agent instructions or create .bonsai.toml. More Actions
currently exposes Open Last Context. The extension scans, compresses, and
writes context itself. No Bonsai binary is required.
In VS Code 1.99 or newer, enable Generate Bonsai Context under Agent
Select Tools, or reference #bonsai_generate_context in chat. It generates
request-aware context and returns the context file paths to the agent.
Command palette:
Output stats:
VS Code extension:
Install the latest from the Marketplace. The VS Code extension is self-contained and does not
need Bonsai installed separately.
Clipboard failure:
Use --output file --output-file /tmp/bonsai.xml.
Clipboard access can fail in headless shells, remote sessions, or sandboxes.
No files selected:
Run with --print-files.
Check --include, --exclude, .gitignore, and .cursorignore.
Use --no-respect-gitignore if ignored files should be included.
Output over budget:
Use a smaller path, add --exclude, increase --max-tokens, or explicitly opt in to lossy compression with --level 2 or 3.
Check parser and tokenizer health:
bonsai doctor
bonsai doctor --jsonIt also reports the cache path, cache size, cache entry count, stored selection metadata, and stale entries.
bonsai setup shows the CLI version and checks the binary, tokenizer, parsers,
clipboard, repository, and output path.
Check:
cargo checkTest:
cargo testCLI integration tests include golden output and token-cost fixtures for large Markdown tables, large config files, import-heavy code, and many-file repos.
Build:
cargo build --releaseBuild the VS Code extension:
cd copilot/bonsai-vscode
npm install
npm run compile
npm run packageMaintenance notes and the release checklist live in
docs/maintenance.md. What Bonsai is for is defined in
docs/distinct-value.md, and how we measure quality
in docs/evaluation.md (run with
BONSAI_BIN=target/release/bonsai python3 tests/eval/run.py).
The GitHub repository, CLI binary, Codex plugin, and Claude plugin are named bonsai.
The VS Code package is named bonsai-vscode.


