bb help [options] [command...]
display help for a command, or list all commands
command— command to describe; include a subcommand forbb help <cmd> <sub>(omit for the command list)
Documentation · bb 0.1.0
Install, index your first project, understand what the indexer does with your files, keep it fresh, and read the generated CLI reference. Everything here is generated against the real bb surface.
Backbencher runs fully local: the bb CLI, the SQLite index, and the analysis all live on your machine. Your source code never leaves it.
Primary · npm
The published artifact every release ships, so the CLI and the package version always agree. Requires Node.js 18 or newer.
npm install -g @backbencher/brainShell installer
A one-line installer, an alternative to npm.
curl -fsSL https://backbencher.cc/install.sh | bashPowerShell installer
A one-line installer, the Windows alternative to npm.
irm https://backbencher.cc/install.ps1 | iexBoth installers prefer npm and install the same package. Only when npm is unavailable do they fall back to a release binary from the backbencher-hq/backbencher-brain GitHub releases, and only after its sha256 checksum verifies against the release’s checksums.txt. Pin with VERSION=0.1.0 in front of either command ($env:VERSION="0.1.0" on Windows).
Pin the npm package with npm install -g @backbencher/brain@0.1.0.
bb --version
If bb is not found, check that your npm global prefix (npm prefix -g) or ~/.local/bin is on your PATH, then run the absolute path to verify.
Run bb index from the repository root, then bb stats to see what landed. The four follow-ups below are what you reach for when the tree, the derived data, or a run needs attention.
cd /path/to/project bb index bb stats
bb index --changedbb index --forcebb index --postbb index --resumebb index walks your project, parses every file with the right grammar, extracts symbols and relationships, and persists them into one local database per project — the same store every read surface answers from. Nothing is sent anywhere: the index lives on your machine.
For 50 of the 53 registry ids a dedicated analyzer (tree-sitter grammar or hand-written oracle) reads the file with AST precision. The other 3 — TSX, Sass and Terraform — are aliases served by the TypeScript, CSS and HCL analyzers rather than separate languages, so the editor lane can never exceed the analyzer set. See the language reference for the per-family depth label.
Each analyzer records what it can prove: symbols with a kind and exact byte bounds (functions, classes, modules, selectors, tables — whatever the family has), and the relationships between them — calls, imports, references, instantiations, uses. Cross-language edges carry an explicit evidence label (structural, import-based, usage-contextual, reference-qualified, or inferred), never a silent guess. What a file could not be parsed into is declared, not invented.
Extracted rows land in one local SQLite database per project (the brain): files, symbols, relationships, imports, and index status as first-class tables; agent annotations and semantic embedding vectors stored alongside when configured; security taint flows and project health as derived tables. A migration layer keeps the schema versioned.
One index, several doors: the 16 MCP tools over bb mcp, the CLI (bb search, bb stats, bb health), and the editor integration, which talks to the same index through the LSP server — hover, symbol navigation, and call-graph views answer from the same rows a tool call reads.
Reads resolve freshness against the live working tree and say so when the index is behind (and how to catch up). Writes are guarded: path checks, AST byte bounds, validation, and rollback, with dryRun previews before risky edits. After an edit, the changed file is reindexed so the agent answers from what it just wrote.
Depth is declared, never assumed
Symbol kinds, relationship edges, and depth labels on this site are audited against the analyzers. If a family parses deeper or shallower than documented, that is a bug worth reporting.
The indexer walks your project once and then keeps up incrementally. Three layers decide what it reads — in this order.
Always on, in every project, before any of your own rules are read. These directories never reach the parser:
.gitnode_modulesdistbuildoutcoverage.nexttarget__pycache__.venvvenvAnything git ignores, the indexer skips — a .gitignore at any level of the tree is read as it walks, so a project that is already gitignored correctly needs no extra configuration.
A project-local .bbignore file (gitignore syntax) has higher priority than .gitignore — use it when you want git to track something but the indexer to skip it, like large generated fixtures. After you add it, bb index --changed applies it. If an unexpected directory shows up in your index, that is the fix — and it is a bug worth reporting.
One generated blob can stall a whole run, so very large files are handled by tier instead of being parsed blindly:
| File size | What the indexer does |
|---|---|
| up to 1 MB | Full AST parse — symbols with byte bounds, and the relationships between them. |
| 1 MB–5 MB | Structural symbols only, for .json, .yaml, .yml, .toml, .xml, .xsd, .dtd, .md, .proto — the formats where a huge file is usually machine-generated. |
| over 5 MB | Skipped, never parsed (5 MB walk limit). The tiers are tuned, not dogma: if a file you care about is skipped, tell us. |
The first index is the expensive pass: it parses every discovered file and then runs the derived phases. A re-run of an unchanged project is fast, because files whose size and modification time are unchanged are not re-parsed at all. Progress streams while it runs, and bb status reports per-phase timings of the last run.
A code index is only useful while it matches the working tree. Three mechanisms, in the order you will normally meet them.
When a read path touches files that are stale or missing in the index, it repairs exactly those files within a budget before answering, and says so in an auto-refreshed N files in Xms line. The budget is 25 files or 2 MiB of changed bytes, whichever comes first, and it is tunable through the environment:
BB_NO_AUTO_REFRESHBB_AUTO_REFRESH_MAX_FILESBB_AUTO_REFRESH_MAX_BYTESBB_NO_AUTO_REFRESH=1 opts out entirely. If the repair would exceed the budget, or another index run holds the lock, the tool answers from existing data with a staleness footer instead of pretending the index is current.
Routine sync
bb index --changed
Re-parses only files changed since the last index, and runs the bounded derived-data pass so relationships stay current. This is the routine “I edited things, sync my index” command.
One file
bb index --file src/session.ts
Re-indexes one file’s symbols and relationships. Use it right after an agent creates or edits a function.
Derived data
bb index --post
Re-runs the derived phases without re-parsing anything — the remediation when derived data was skipped or went stale (for example after --skip-post-processing).
Interrupted run
bb index --resume
Continues an interrupted run from its checkpoint: only missing or changed files are processed, then the bounded derived pass runs.
Only what the changed files touch — never the whole index. This is the exact list, phase by phase:
| Data | Updated for changed files | How |
|---|---|---|
| symbols | yes | Changed files are re-parsed by the same analyzers and their symbol rows are rewritten; unchanged files are not touched. |
| relationships | yes | The re-parsed file's own edges resolve at insert time; cross-file edges from other files pointing into the changed file are repaired; unresolved external targets are re-resolved, scoped to the touched symbols. |
| enrichment | yes | Re-run scoped to the touched source symbols. |
| gravity | yes | Recomputed for the touched symbols, plus every symbol whose in-degree changed because of the edit. |
| taint | yes | Resolution re-processes only the flows that are still unresolved. |
| health | yes | Recomputed (cheap SQL aggregates). |
| analyze | yes | SQLite's own ANALYZE, so the query planner has statistics. Without sqlite_stat1 it guesses: measured on a real 4.8 GB index, that guess cost a full brain_symbol scan per graph hop — about 15s per bb_graph call, and bb_patterns timed out at 45s. With the statistics present the same hops are sub-millisecond. One-time cost around 8s on that index, covered by the single-flight index lock. |
| deleted files | yes | Purged from the index, including their derived rows. |
| embeddings | queued | New and changed symbols are queued for the embedding provider during storage; vectors fill in asynchronously with a local fallback when no provider is configured. |
Two honest edges: embeddings are asynchronous, so semantic search can lag symbol and relationship freshness by a few seconds after an edit; and a derived phase that fails leaves the run’s status partial rather than silently claiming success. A run summary reports what it did as derivedPass: full | bounded | deferred | skipped-unchanged — a bounded pass covers the touched files, a full pass covers everything, and a deferred pass means the derived data is still owed (run bb index --post).
Only a full rebuild recomputes everything
bb index --force wipes the project’s index and rebuilds it from scratch. Incremental runs cover every case above, so you should rarely need it.
Semantic search (bb_ask semantic mode) uses embedding vectors. Without a provider key, the indexer still works — semantic search just falls back to weaker local vectors, and the CLI tells you so honestly.
bb setup # interactive: provider, API key, model bb setup show # inspect config — the key is shown as a fingerprint only
Diagnose a broken setup or inconsistent index:
bb doctor
bb doctor is read-only. bb doctor --fix repairs file-permission problems only (0600 on the config); it changes nothing else. The first bb index run also offers the setup wizard interactively — skip it once with bb index --no-setup.
Keys stay on your machine
The API key is stored with owner-only permissions (0600) and is never sent to any AI agent — tools see a fingerprint only.
Backbencher exposes 16 public MCP tools for indexed discovery, analysis, documentation, guarded mutation, diagnostics, security analysis, migration planning, and graph export. These are tool calls an MCP client invokes — not shell subcommands. Each row carries the tool’s registry summary; the tool reference adds the full contract — the complete generated description, modes, defaults, parameters and examples.
| Tool | Group | What it does |
|---|---|---|
| bb_search | Discovery | Unified lexical, content, exact-symbol, and file retrieval. |
| bb_ask | Discovery | Exact aggregates, exact-name lookups, and scored semantic or lexical matches — each labelled with its route and bounds. |
| bb_patterns | Analysis | Pattern/orphan analysis ranked by confidence, with a bounded page, a declared census, per-finding staleness, and optional persisted run history. |
| bb_migrate | Analysis | Batch cross-language migration plans with ordering, waves, cohort rollup, scope completeness, and unsupported mappings. |
| bb_analyze | Analysis | One typed analysis surface over the graph, the file graph, project counts, complexity, impact and test evidence. Every mode is bounded, declares its own bounds, and reports what it returned against what exists. |
| bb_doc | Analysis | Cited Markdown or JSON documentation over indexed source and relationships, with declared bounds, emitted-citation freshness counts, and a payload-measured output budget. |
| bb_graph | Analysis | Per-symbol graph with per-edge evidence tiers — the agent view of the editor's graph panel. |
| bb_impact | Analysis | Bounded impact with declared truncation — identical numbers to the editor's impact mode. |
| bb_cross_language | Analysis | Stored cross-language pairs, each naming both ends, with member rows reported separately as the member's, absence declared as a property of the store, and declared bounds and truncation. |
| bb_annotate | Analysis | Agent note with enforced provenance, stored where the human reads. |
| bb_annotations | Analysis | Annotations with full provenance; declared absence; both name forms matched; path canonicalized. |
| bb_health | Diagnostics | Unified index, schema, freshness, embeddings, runtime, integrity, completeness and analysis-history report — status by default, one explicit refresh behaviour, and no mode parameter. |
| bb_security | Diagnostics | Taint-flow findings over the index, with optional persisted run history. A flow is a finding only when both endpoints resolve to indexed symbols; one-sided flows are reported as unvalidated observations. A findings answer states the pre-cap census so a capped scan is never mistaken for a complete one; a history answer states its run count and its finding total, and its findings page is capped and declared. Reads open the index read-only and refuse an unindexed project; recordRun is the one write. Not detected: hardcoded secrets; genuine cross-language taint; standalone weak crypto. |
| bb_visualize | Diagnostics | Scoped canonical dependency graphs with explicit truncation and provenance. |
| bb_edit | Operations | Unified safe source editing with preview, validation, rollback, and reindex. |
| bb_index | Operations | Immediately refresh the index for a just-written/edited file or directory; mode=post re-derives relationships/taints/health without re-parsing. |
Full schemas, defaults, safety behavior, and limitations
From the terminal, run any tool with JSON arguments:
bb tool bb_search --args '{"mode":"symbol","query":"createSession"}'bb mcp starts the Backbencher MCP server over stdio. Point any MCP client at it — Claude Code, Cursor, VS Code, opencode, and others.
# Claude Code
claude mcp add backbencher -- bb mcp --dir /path/to/project
# Generic MCP client configuration
{
"mcpServers": {
"backbencher": {
"command": "bb",
"args": ["mcp", "--dir", "/path/to/project"]
}
}
}bb mcp starts a server, it does not configure clients
bb mcp is the server process. Client registration happens in your MCP client’s own configuration, as shown above.
All 14 top-level commands and every flag they accept. This reference is generated from the CLI’s own help text, so it cannot list a flag the binary does not have — run bb <command> --help for the same output on your machine.
display help for a command, or list all commands
command — command to describe; include a subcommand for bb help <cmd> <sub> (omit for the command list)run one of the public tools with JSON arguments
name — public tool name, e.g. bb_search or bb_docunexpected — rejected: tool arguments are passed with --args '<json>' so a stray positional is an error, not a silent no-op| Flag | What it does |
|---|---|
| --dir <dir> | project directory (default: cwd) |
| --args <json> | tool arguments as a JSON object (default: "{}") |
index a project (default: current directory)
dir — project directory (default: current directory)| Flag | What it does |
|---|---|
| --force | wipe the existing index and rebuild |
| --no-setup | skip the first-run embedding setup prompt |
| --skip-post-processing | parse + store only; SKIP relationship resolution/enrichment/gravity/taint/health (derived data goes stale until: bb index --post) |
| --post | re-run relationship/enrichment/gravity/taint/health phases only — no re-parse (remediation for stale derived data after --changed/--resume/agent edits) |
| --file <path> | reindex a single file's symbols + relationships, relative to <dir> or absolute and must be inside the project (runs a scoped derived-data pass for that file; refuses a missing/outside path) |
| --changed | reindex only files changed since the last index (runs the bounded derived-data pass for touched files — relationships stay current) |
| --resume | continue from an interrupted run's checkpoint (incremental: only missing/changed files; runs the bounded derived-data pass) |
| --import <db> | adopt an existing brain.db file (re-home a moved project's index) |
| --exclude <globs> | skip files matching comma-separated globs during discovery (repeatable); NON-DESTRUCTIVE: files already indexed by an earlier run keep their rows (default: []) |
| --concurrency <n> | worker count for this run (1-64; default max(2, min(cpus-1, 12))) |
embedding provider setup (API key, model)
bb setup showdiagnose embedding setup and index consistency (read-only)
| Flag | What it does |
|---|---|
| --dir <dir> | project directory (default: cwd) |
| --fix | repair permission problems (0600 only; this IS the explicit apply — without it doctor is read-only) |
check for a newer bb and report exactly how to install it
| Flag | What it does |
|---|---|
| --check | only report whether a newer version exists; change nothing |
| --to <dist-tag-or-range> | npm dist-tag or version range to compare against (default: latest) |
query index counts anytime: files/symbols/relationships/embeddings (default:
dir — project directory (default: current directory)| Flag | What it does |
|---|---|
| --json | machine-readable JSON output (stable keys for scripts) |
show in-flight/last-run index state and per-phase timings (default: cwd)
dir — project directory (default: current directory)| Flag | What it does |
|---|---|
| --json | machine-readable JSON output (stable keys for scripts) |
list every indexed project: DB path, size, counts, last index (default: all
| Flag | What it does |
|---|---|
| --sort <field> | sort by name|size|time (default: "name") |
| --remove <id> | remove one indexed project by id (reclaims its DB + embeddings) |
| --force | remove even if that project is currently being indexed |
| --json | machine-readable JSON output for the project list (stable keys for scripts) |
search the index (modes: symbols [default], content, symbol, file — parity with
query — query text; in file mode, the file path to print (omit when --symbol-name or --file-path is given)| Flag | What it does |
|---|---|
| --mode <mode> | retrieval mode: symbols (default), content, symbol, or file |
| --file-path <path> | file target for --mode file (overrides the positional query) |
| --symbol-name <name> | exact symbol name for --mode symbol (overrides the positional query) |
| --dir <dir> | project directory (default: cwd) |
| --limit <n> | max results (default: "15") |
| --language <lang> | filter by language |
| --no-auto-refresh | answer from the existing index with the staleness footer instead of auto-refreshing stale files within budget |
index health and freshness
dir — project directory (default: cwd)| Flag | What it does |
|---|---|
| --refresh | reindex the project before reporting |
| --force | force a full in-place reindex (implies --refresh) |
| --no-wait | do not wait for the refresh to finish |
| --complete | check freshness for all files (not just a sample) |
| --integrity | run the 12-point index integrity check |
| --sample-size <n> | freshness sample size (default: 200) (default: "200") |
| --verbose-config | show effective embedding config + per-field source |
write the bb tools guidance section into <dir>/AGENTS.md (generated from the
dir — project directory (default: current directory)| Flag | What it does |
|---|---|
| --check | report drift/ghost tool names without writing (exit 1 when not current) |
| print the generated section to stdout without writing | |
| --file <path> | guide file to write (default: <dir>/AGENTS.md) |
start the MCP server over stdio (for Claude Code, Cursor, VS Code…)
| Flag | What it does |
|---|---|
| --dir <dir> | default project directory (default: cwd) |
print the bb version
Global flags, accepted by every command: -v, --version · --verbose · --quiet.
Daily diagnostics:
bb stats # counts bb status # is an index running? what did the last run do? bb health # is the index healthy and fresh? bb doctor # is the embedding setup consistent?
Where the index lives, what an upgrade keeps, and how to clean up.
One directory, keyed per project, outside your repository and outside the installed program:
~/.bb/projects/<project-id>/brain.db~/.bb/wasmThe <project-id> is a sha1 of the project's absolute path, so two checkouts of the same repository at different paths have separate indexes. Override the whole location with BB_DATA_DIR — recommended where the home directory is not reliably writable or persistent (sandboxes, CI, editor hosts).
New releases run idempotent schema migrations when they open the database: an upgraded bb either uses the existing index as it is or upgrades it in place — it never wipes it. To move to a new release, run npm install -g @backbencher/brain@latest (or re-run the installer, which does the same thing through npm); npm install -g @backbencher/brain@0.1.0 pins a specific release. There is no separate in-place upgrade subcommand.
Uninstalling removes the program, not ~/.bb. Reinstall and every index, embedding and history entry is exactly where you left it. You start from zero only if the project moved to a different absolute path — then:
bb index --import /path/to/old-brain.db
adopts (re-homes) an existing index for the project at its current location. Moving a database between machines works the same way when the codebase fingerprint matches.
bb projects # every indexed project: DB path, size, counts, last index bb projects --sort size # biggest indexes first bb projects --remove <id> # delete one project's index + embeddings bb stats # committed counts for the current project
Removing a project is the only operation that deletes an index. Nothing else in the CLI does, and no command sends your code or your index anywhere.
Symptom-based fixes. Each one names a real command that resolves it.
Freshness
Indexed results state their freshness. Reindex changed files, or re-run the derived phases without a full re-parse:
bb index --changed # or, when only derived data (relationships, health) is stale: bb index --post
Recovery
Wipes this project's index and rebuilds it in place. Your source files are never touched:
bb index --force
Interrupted run
Check where the run stopped, then continue from its checkpoint:
bb status bb index --resume
Embeddings
Without a configured embedding provider, semantic modes fall back to weaker local vectors. Check your setup and its consistency:
bb setup show bb doctor
Configure a provider with bb setup. bb doctor --fix repairs file-permission problems only (0600 on the config) — it is explicit and changes nothing else.
Evidence
Tool results carry a freshness block (fresh/stale/missing counts plus a remediation command). Run the remediation it names — usually bb index --changed or bb index --post:
bb health
Diagnostics
Show debug logs and per-file worker/WASM lines for any command; suppress informational output with --quiet:
bb --verbose stats bb --quiet search createSession
Still stuck? Send the output of bb health and bb stats to support.
Upgrading keeps your data
To move to a new release, run npm install -g @backbencher/brain@latest — it replaces the installed package in place, leaves your index untouched, and there is no separate in-place upgrade subcommand. Details in Data, upgrades & uninstall.
The guide stops where the references begin. These pages go deeper than a guide can.