# br - Beads Rust

<div align="center">
  <img src="docs/assets/br_illustration.webp" alt="br - Fast, non-invasive issue tracker for git repositories" width="600">
</div>

<div align="center">

[![License: MIT](https://img.shields.io/badge/License-MIT%2BOpenAI%2FAnthropic%20Rider-blue.svg)](./LICENSE)
[![Rust](https://img.shields.io/badge/rust-nightly-orange.svg)](https://www.rust-lang.org/)
[![SQLite](https://img.shields.io/badge/storage-SQLite-green.svg)](https://www.sqlite.org/)

</div>

A Rust port of Steve Yegge's [beads](https://github.com/steveyegge/beads), frozen at the "classic" SQLite + JSONL architecture I built my Agent Flywheel tooling around.

[Quick Start](#quick-start) | [Commands](#commands) | [Configuration](#configuration) | [VCS Integration](#vcs-integration) | [FAQ](#faq)

<div align="center">
<h3>Quick Install</h3>

```bash
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/beads_rust/main/install.sh?$(date +%s)" | bash
```

<p><em>Works on Linux, macOS, and Windows (WSL). Auto-detects your platform and downloads the right binary.</em></p>

<p><em>Useful install flags: <code>--skip-skills</code> to skip all Claude Code / Codex skills, or <code>--no-migration-skill</code> to skip just the bd-to-br-migration skill (handy for clean agent sandboxes where you're only using <code>br</code>).</em></p>
</div>

---

## Why This Project Exists

I (Jeffrey Emanuel) LOVE [Steve Yegge's Beads project](https://github.com/steveyegge/beads). Discovering it and seeing how well it worked together with my [MCP Agent Mail](https://github.com/Dicklesworthstone/mcp_agent_mail) was a truly transformative moment in my development workflows and professional life. This quickly also led to [beads_viewer (bv)](https://github.com/Dicklesworthstone/beads_viewer), which added another layer of analysis to beads that gives swarms of agents the insight into what beads they should work on next to de-bottleneck the development process and increase velocity. I'm very grateful for finding beads when I did and to Steve for making it.

At this point, my [Agent Flywheel](http://agent-flywheel.com/tldr) System is built around beads operating in a specific way. As Steve continues evolving beads toward [GasTown](https://github.com/steveyegge/gastown) and beyond, our use cases have naturally diverged. The hybrid SQLite + JSONL-git architecture that I built my tooling around (and independently mirrored in MCP Agent Mail) is being replaced with approaches better suited to Steve's vision.

Rather than ask Steve to maintain a legacy mode for my niche use case, I created this Rust port that freezes the "classic beads" architecture I depend on. The command is `br` to distinguish it from the original `bd`.

**This isn't a criticism of beads**; Steve's taking it in exciting directions. It's simply that my tooling needs a stable snapshot of the architecture I built around, and maintaining my own fork is the right solution for that. Steve has given his full endorsement of this project.

---

## TL;DR

### The Problem

You need to track issues for your project, but:
- **GitHub/GitLab Issues** require internet, fragment context from code, and don't work offline
- **TODO comments** get lost, have no status tracking, and can't express dependencies
- **External tools** (Jira, Linear) add overhead, require context switching, and cost money

### The Solution

**br** is a local-first issue tracker that stores issues in SQLite with JSONL export for git-friendly collaboration. It provides dependency-aware issue tracking, machine-readable output, sync/recovery tooling, and agent-friendly workflows without leaving your repository.

```bash
br init                              # Initialize in your repo
br create "Fix login timeout" -p 1   # Create high-priority issue
br ready                             # See what's actionable
br close br-abc123                   # Close when done; JSONL auto-flushes by default
br sync --flush-only                 # Optional final export check before git commit
```

### Why br?

| Feature | br | GitHub Issues | Jira | TODO comments |
|---------|-----|---------------|------|---------------|
| Works offline | **Yes** | No | No | Yes |
| Lives in repo | **Yes** | No | No | Yes |
| Tracks dependencies | **Yes** | Limited | Yes | No |
| Zero cost | **Yes** | Free tier | No | Yes |
| No account required | **Yes** | No | No | Yes |
| Machine-readable | **Yes** (`--json`) | API only | API only | No |
| Git-friendly sync | **Yes** (JSONL) | N/A | N/A | N/A |
| Non-invasive | **Yes** | N/A | N/A | Yes |
| AI agent integration | **Yes** | Limited | Limited | No |

---

## Quick Example

```bash
# Initialize br in your project
cd my-project
br init

# Add agent instructions to AGENTS.md (creates file if needed)
br agents --add --force

# Create issues with priority (0=critical, 4=backlog)
br create "Implement user auth" --type feature --priority 1
# Created: br-7f3a2c

br create "Set up database schema" --type task --priority 1
# Created: br-e9b1d4

# Auth depends on database schema
br dep add br-7f3a2c br-e9b1d4

# See what's ready to work on (not blocked)
br ready
# br-e9b1d4  P1  task     Set up database schema

# Claim and complete work
br update br-e9b1d4 --status in_progress
br close br-e9b1d4 --reason "Schema implemented"

# Now auth is unblocked
br ready
# br-7f3a2c  P1  feature  Implement user auth

# Mutations auto-flushed JSONL by default; run an idempotent final export check
br sync --flush-only
git add .beads/ && git commit -m "Update issues"
```

---

## Design Philosophy

### 1. Non-Invasive by Default

For normal issue tracking and sync, br keeps its state in `.beads/` and leaves
git handoff to you. It never commits, pushes, pulls, installs hooks, or runs as a
background service.

Some explicit commands intentionally step outside that default storage boundary:
`br agents` edits requested agent-instruction files, `br doctor --repair` can fix
the project `.gitignore`, `br config edit/set` updates config files,
`br completions -o` writes shell completion files, `br upgrade` updates the
installed binary, and git-reporting commands such as `br changelog`, `br
orphans`, and commit-activity `br stats` inspect git history.

```bash
# Normal issue state lives under .beads/
ls -la .beads/
# beads.db       # SQLite database
# issues.jsonl   # Git-friendly export
# config.yaml    # Optional config
```

### 2. SQLite + JSONL Hybrid

**SQLite** for fast local queries. **JSONL** for git-friendly collaboration.

```bash
# Local: Fast queries via SQLite
br list --priority 0-1 --status open --assignee alice

# Collaboration: JSONL merges cleanly in git
git diff .beads/issues.jsonl
# +{"id":"br-abc123","title":"New feature",...}
```

### 3. Explicit Over Implicit

State changes are explicit. Successful mutating commands update SQLite and
auto-flush JSONL by default, but `br` still never commits, pushes, pulls, or
imports remote changes without a command. Git-inspection behavior is limited to
explicit reporting commands and reads history only.

```bash
# Mutations auto-flush .beads/issues.jsonl by default
br close br-abc123 --reason "Done"

# Re-run export after --no-auto-flush/config changes, recovery, or as a final check
br sync --flush-only

# Import is explicit (not automatic)
br sync --import-only

# Merge divergent DB and JSONL edits using the saved base snapshot
br sync --merge

# Rebuild SQLite from authoritative JSONL after recovery/corruption
br sync --import-only --rebuild

# Git operations are YOUR responsibility
git add .beads/ && git commit -m "..."
```

### 4. Agent-First Design

Every command supports `--json` for AI coding agents:

```bash
br list --json | jq '.issues[] | select(.priority <= 1)'
br ready --json  # Structured output for agents
br show br-abc123 --json
```

For routine operator or agent use, prefer `RUST_LOG=error br ...` to suppress internal Rust dependency logs while preserving normal stdout/JSON output:

```bash
RUST_LOG=error br ready --json
RUST_LOG=error br sync --flush-only
```

### 5. Rich Terminal Output

Interactive terminals get enhanced visual output:

```bash
# Rich mode (default in TTY)
br list           # Formatted tables with colors
br show br-abc    # Styled panels with metadata

# Plain mode (piped or --no-color)
br list | cat     # Clean text, no ANSI codes

# JSON mode (--json or --robot)
br list --json    # Structured output for tools ({issues, total, limit, offset, has_more})
```

Output mode is auto-detected:
- **Rich**: Interactive TTY with color support
- **Plain**: Piped output or `NO_COLOR` environment
- **JSON**: Machine-readable (`--json` flag)
- **Quiet**: Minimal output (`--quiet` flag)

### 6. Focused Local Scope

br has grown into a full CLI surface for local issue tracking: routing, recovery,
TOON/JSON schemas, MCP support, conformance checks, and sync safety tools are
all part of the current scope. The focus is still local-first operation, explicit
git/VCS handoff, and no background services installed behind your back.

---

## Comparison vs Alternatives

### br vs Original beads (Go)

| Aspect | br (Rust) | beads (Go) |
|--------|-----------|------------|
| Git operations | **No automatic commits/pushes/pulls**; reporting commands can inspect git history | Auto-commit, hooks |
| Storage | SQLite + JSONL | Dolt/SQLite |
| Background daemon | **No** | Yes |
| Hook installation | **Manual** | Automatic |
| Binary size | ~5-8 MB | ~30+ MB |
| Scope | Local CLI, sync, recovery, and agent workflows | Feature-rich ecosystem |

**When to use br:** You want a stable, local-first issue tracker with explicit sync, dependency-aware planning, and machine-readable output.

**When to use beads:** You want advanced features like Linear/Jira sync, RPC daemon, automatic hooks.

### br vs GitHub Issues

| Aspect | br | GitHub Issues |
|--------|-----|---------------|
| Works offline | **Yes** | No |
| Lives in repo | **Yes** | Separate |
| Dependencies | **Yes** | Workarounds |
| Custom fields | Via labels | Limited |
| Machine API | `--json` flag | REST API |
| Cost | Free | Free (limits) |

### br vs Linear/Jira

| Aspect | br | Linear/Jira |
|--------|-----|-------------|
| Setup time | 1 command | Account + config |
| Cost | Free | $8-15/user/mo |
| Works offline | **Yes** | Limited |
| Learning curve | CLI | GUI + workflows |
| Git integration | Native | Webhooks |

---

## Installation

### Quick Install (Recommended)

```bash
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/beads_rust/main/install.sh?$(date +%s)" | bash
```

### From Source

```bash
# Requires Rust nightly
git clone https://github.com/Dicklesworthstone/beads_rust.git
cd beads_rust
cargo build --release
./target/release/br --help

# Or install globally
cargo install --path .
```

### Cargo Install

```bash
cargo install --git https://github.com/Dicklesworthstone/beads_rust.git
```

> **Note:** `cargo install` places binaries in `~/.cargo/bin/`, while the install script uses `~/.local/bin/`. If you have both in PATH, ensure the desired location has higher priority to avoid running an outdated version. Run `which br` to verify which binary is active.

### Disable Self-Update

```bash
# Build without self-update feature
cargo build --release --no-default-features

# Or install without it
cargo install --git https://github.com/Dicklesworthstone/beads_rust.git --no-default-features
```

### Enable MCP Server Support

`br serve` is optional and is not built by the default feature set. Build with
the `mcp` feature when you want an AI agent to talk to `br` over the Model
Context Protocol instead of shelling out to CLI commands.

```bash
cargo build --release --features mcp

# Or install globally with MCP support
cargo install --git https://github.com/Dicklesworthstone/beads_rust.git --features mcp
```

Run it from an initialized beads workspace:

```bash
RUST_LOG=error br serve --actor codex
```

The server uses MCP over stdio. It is launched by an MCP client, does not listen
on a network port, and uses the same SQLite database, JSONL export path, write
locks, audit events, and sync safety model as the normal CLI. It does not run
git. Use shell/JSON
commands for simple scripts; use MCP when an agent benefits from discoverable
tools, resources, prompts, and structured recovery hints.

### Verify Installation

```bash
br --version
# br 0.1.45
```

---

## Quick Start

### 1. Initialize in Your Project

```bash
cd my-project
br init
# Initialized beads workspace in .beads/
```

### 2. Create Your First Issue

```bash
br create "Fix login timeout bug" \
  --type bug \
  --priority 1 \
  --description "Users report login times out after 30 seconds"
# Created: br-a1b2c3
```

### 3. Add Labels

```bash
br label add br-a1b2c3 backend auth
```

### 4. Check Ready Work

```bash
br ready
# Shows issues that are open, not blocked, not deferred
```

### 5. Claim and Work

```bash
br update br-a1b2c3 --status in_progress --assignee "$(git config user.email)"
```

### 6. Close When Done

```bash
br close br-a1b2c3 --reason "Increased timeout to 60s, added retry logic"
```

### 7. Sync to Git

```bash
br sync --flush-only        # Idempotent final JSONL export check
git add .beads/             # Stage changes
git commit -m "Fix: login timeout (br-a1b2c3)"
```

---

## Commands

### Issue Lifecycle

| Command | Description | Example |
|---------|-------------|---------|
| `init` | Initialize workspace | `br init` |
| `create` | Create issue | `br create "Title" -p 1 --type bug` |
| `q` | Quick capture (ID only) | `br q "Fix typo"` |
| `show` | Show issue details | `br show br-abc123` |
| `update` | Update issue | `br update br-abc123 --priority 0` |
| `close` | Close issue | `br close br-abc123 --reason "Done"` |
| `reopen` | Reopen closed issue | `br reopen br-abc123` |
| `delete` | Delete issue (tombstone) | `br delete br-abc123` |
| `defer` | Schedule issue for later | `br defer br-abc123 --until tomorrow` |
| `undefer` | Make deferred issue ready again | `br undefer br-abc123` |

### Querying

| Command | Description | Example |
|---------|-------------|---------|
| `list` | List issues | `br list --status open --priority 0-1` |
| `ready` | Actionable work | `br ready` |
| `blocked` | Blocked issues | `br blocked` |
| `search` | Full-text search | `br search "authentication"` |
| `stale` | Stale issues | `br stale --days 30` |
| `count` | Count with grouping | `br count --by status` |
| `query` | Manage saved queries | `br query save mine --status open --assignee alice` |

### Dependencies

| Command | Description | Example |
|---------|-------------|---------|
| `dep add` | Add dependency | `br dep add br-child br-parent` |
| `dep remove` | Remove dependency | `br dep remove br-child br-parent` |
| `dep list` | List dependencies | `br dep list br-abc123` |
| `dep tree` | Dependency tree | `br dep tree br-abc123` |
| `dep cycles` | Find cycles | `br dep cycles` |

### Labels

| Command | Description | Example |
|---------|-------------|---------|
| `label add` | Add labels | `br label add br-abc123 backend urgent` |
| `label remove` | Remove label | `br label remove br-abc123 urgent` |
| `label list` | List issue labels | `br label list br-abc123` |
| `label list-all` | All labels in project | `br label list-all` |

### Comments

| Command | Description | Example |
|---------|-------------|---------|
| `comments add` | Add comment | `br comments add br-abc123 "Found root cause"` |
| `comments list` | List comments | `br comments list br-abc123` |

### Planning & Reporting

| Command | Description | Example |
|---------|-------------|---------|
| `epic` | Manage epic rollups | `br epic status --eligible-only` |
| `graph` | Visualize dependency graph | `br graph br-abc123` |
| `lint` | Check issues for missing template sections | `br lint --status all` |
| `orphans` | List open issues referenced in commits | `br orphans` |
| `changelog` | Generate changelog from closed issues | `br changelog --since-tag v0.1.44` |
| `history` | Manage local history backups | `br history list` |
| `status` | Alias for project statistics | `br status` |

### Agents & Tooling

| Command | Description | Example |
|---------|-------------|---------|
| `agents` | Manage AGENTS.md workflow instructions | `br agents --add --force` |
| `audit` | Record and label agent interactions | `br audit record --kind note` |
| `completions` | Generate shell completions | `br completions zsh` |
| `info` | Show workspace diagnostics | `br info` |
| `schema` | Emit JSON Schemas for outputs | `br schema all --format json` |
| `where` | Show active `.beads` directory | `br where` |

### Sync & System

| Command | Description | Example |
|---------|-------------|---------|
| `sync` | Sync DB ↔ JSONL | `br sync --flush-only` |
| `doctor` | Run diagnostics | `br doctor` |
| `stats` | Project statistics | `br stats` |
| `config` | Manage config | `br config list` |
| `upgrade` | Self-update | `br upgrade` |
| `version` | Show version | `br version` |

### Global Flags

| Flag | Description |
|------|-------------|
| `--json` | JSON output (machine-readable) |
| `--quiet` / `-q` | Suppress output |
| `--verbose` / `-v` | Increase verbosity (-vv for debug) |
| `--no-color` | Disable colored output |
| `--db <path>` | Override database path |

---

## Configuration

br uses layered configuration:

1. **CLI flags** (highest priority)
2. **Environment variables**
3. **Project config**: `.beads/config.yaml`
4. **User config**: `~/.config/beads/config.yaml`
5. **Defaults** (lowest priority)

### Example Config

```yaml
# .beads/config.yaml

# Default issue ID prefix for newly created issues
id:
  prefix: "proj"

# Default values for new issues
defaults:
  priority: 2
  type: "task"
  assignee: "team@example.com"

# Output formatting
output:
  color: true
  date_format: "%Y-%m-%d"

# Sync behavior
sync:
  auto_import: false
  auto_flush: false
```

### Config Commands

```bash
# Show all config
br config list

# Get specific value
br config get id.prefix

# Set value
br config set defaults.priority=1

# Open in editor
br config edit
```

### Environment Variables

| Variable | Description |
|----------|-------------|
| `BD_DB` / `BD_DATABASE` | Override database path |
| `BEADS_JSONL` | Override JSONL path (requires `--allow-external-jsonl`) |
| `RUST_LOG` | Logging level (debug, info, warn, error) |

Recommended default for normal CLI use:

```bash
export RUST_LOG=error
```

This keeps successful commands readable by suppressing low-level dependency logging. Remove or override it when debugging `br` internals.

---

## Architecture

```
┌──────────────────────────────────────────────────────────────┐
│                         CLI (br)                              │
│  Commands: create, list, ready, close, sync, etc.            │
└──────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│                      Storage Layer                            │
│  ┌─────────────────┐              ┌─────────────────────┐    │
│  │  SqliteStorage  │◄────────────►│  JSONL Export/Import │    │
│  │                 │   sync       │                     │    │
│  │  - WAL mode     │              │  - Atomic writes    │    │
│  │  - Dirty track  │              │  - Content hashing  │    │
│  │  - Blocked cache│              │  - Merge support    │    │
│  └────────┬────────┘              └──────────┬──────────┘    │
└───────────│──────────────────────────────────│───────────────┘
            │                                  │
            ▼                                  ▼
     .beads/beads.db                    .beads/issues.jsonl
     (Primary storage)                  (Git-friendly export)
```

### Data Flow

```
User Action                    br Command              Storage
───────────────────────────────────────────────────────────────
Create issue        ──►      br create        ──►    SQLite INSERT
                                              ──►    Mark dirty

Update issue        ──►      br update        ──►    SQLite UPDATE
                                              ──►    Mark dirty

Query issues        ──►      br list          ──►    SQLite SELECT

Export to git       ──►      br sync          ──►    Write JSONL
                             --flush-only     ──►    Clear dirty flags

Pull from git       ──►      git pull         ──►    JSONL updated
                    ──►      br sync          ──►    Merge to SQLite
                             --import-only
```

### Safety Model

`br sync` is designed to be **provably safe**:

| Guarantee | Implementation |
|-----------|----------------|
| Sync never executes git | No runtime `Command::new("git")` calls in `src/sync/` or `src/cli/commands/sync.rs` |
| Sync uses an allowlist for writes | Default writes stay in `.beads/`; external JSONL paths require `--allow-external-jsonl` or an explicit external DB/JSONL family and `.git/` paths are still rejected |
| Atomic writes | Write to temp file, then rename |
| No data loss | Guards prevent overwriting non-empty JSONL with empty DB |

---

## Troubleshooting

### Error: "Database locked"

**Cause:** Another process has the database open.

```bash
# Check for other br processes
pgrep -f "br "

# Force close and retry
br sync --status  # Safe read-only check
```

### Error: "Issue not found"

**Cause:** Issue ID doesn't exist or was deleted.

```bash
# Check if issue exists
br list --json | jq '.issues[] | select(.id == "br-abc123")'

# Check for similar IDs
br list | grep -i "abc"
```

### Error: "Prefix mismatch"

**Cause:** This now only applies when you explicitly ask br to enforce or rewrite
prefixes during import. Mixed prefixes in a project are supported by default.

```bash
# Check your default creation prefix
br config get id.prefix

# Import while rewriting IDs into your configured default prefix
br sync --import-only --rename-prefix
```

If you want to preserve imported IDs exactly as-is, omit `--rename-prefix`.

### Error: "Stale database"

**Cause:** JSONL has issues that don't exist in database.

```bash
# Check sync status
br sync --status

# Force import (may lose local changes)
br sync --import-only --force

# If JSONL is authoritative, rebuild SQLite to match it exactly
br sync --import-only --rebuild
```

`--rebuild` is an import-mode operation. It is not valid with `--flush-only` or
`--merge`; after import it removes database entries that are absent from JSONL,
while preserving deletion tombstones used by sync.

### Sync Issues After Git Merge

```bash
# 1. Check for JSONL merge conflicts
git status .beads/

# 2. If conflicts, resolve manually then:
br sync --import-only

# 3. If both SQLite and JSONL changed cleanly, run a three-way merge:
br sync --merge

# 4. If database seems stale:
br doctor
```

`br sync --merge` uses `.beads/beads.base.jsonl` as the common ancestor. If the
same issue changed on both sides, br stops and asks for an explicit policy:
`--force-db` keeps the local SQLite version, `--force-jsonl` keeps the JSONL
version, and `--force` keeps the newer timestamp.

### Command Output is Garbled

```bash
# Disable colors
br list --no-color

# Or use JSON output
br list --json | jq '.issues'
```

---

## Limitations

br intentionally does **not** support:

| Feature | Reason |
|---------|--------|
| **Automatic git commits** | Non-invasive philosophy |
| **Git hook installation** | User-controlled, add manually if desired |
| **Background daemon** | Simple CLI, no processes to manage |
| **Dolt backend** | SQLite + JSONL only |
| **Linear/Jira sync** | Focused scope |
| **Web UI** | CLI-first (see beads_viewer for TUI) |
| **Automatic multi-repo sync** | Route-aware commands can target configured workspaces, but git/VCS sync remains explicit per repo |
| **Real-time collaboration** | Git-based async collaboration |

---

## FAQ

### Q: How do I integrate with beads_viewer (bv)?

br works seamlessly with [beads_viewer](https://github.com/Dicklesworthstone/beads_viewer):

```bash
# Use bv for interactive TUI
bv

# Use br for CLI/scripting
br ready --json | jq
```

### Q: Can I use br with AI coding agents?

Yes! br is designed for AI agent integration:

```bash
# Agents can use --json for structured output
br list --json
br ready --json
br show br-abc123 --json

# Create issues programmatically
br create "Title" --json  # Returns created issue as JSON
```

See [AGENTS.md](AGENTS.md) for the complete agent integration guide.

### Q: How do I migrate from the original beads?

br uses the same JSONL format as classic beads:

```bash
# Copy your existing issues.jsonl
cp /path/to/beads/.beads/issues.jsonl .beads/

# Import into br
br sync --import-only
```

### Q: Why Rust instead of Go?

- **Smaller binary:** ~5-8 MB vs ~30+ MB
- **Memory safety:** No runtime garbage collection
- **Operational fit:** The CLI, release pipeline, and agent tooling are already Rust-based
- **Personal preference:** The author's flywheel tooling is Rust-based

### Q: How do dependencies work?

```bash
# Issue A depends on Issue B (A is blocked until B is closed)
br dep add br-A br-B

# Now br-A won't appear in `br ready` until br-B is closed
br ready  # Only shows br-B

# Close the blocker
br close br-B

# Now br-A is ready
br ready  # Shows br-A
```

### Q: How do I handle merge conflicts in JSONL?

JSONL is line-based, so conflicts are usually easy to resolve:

```bash
# After git merge with conflicts
git status .beads/issues.jsonl

# Edit to resolve (each line is one issue)
vim .beads/issues.jsonl

# Mark resolved and import
git add .beads/issues.jsonl
br sync --import-only
```

If git merged `.beads/issues.jsonl` without textual conflict markers but both
SQLite and JSONL have independent br changes, use the sync merge path instead:

```bash
br sync --merge

# If br reports semantic conflicts, choose one resolution policy:
br sync --merge --force-db     # keep local SQLite changes
br sync --merge --force-jsonl  # keep JSONL changes
br sync --merge --force        # keep the newer timestamp
```

### Q: Can I customize the issue ID prefix?

Yes:

```bash
br config set id.prefix=myproj
# New issues: myproj-abc123
```

You can also mix multiple prefixes in the same project. The configured prefix is
the default for newly created issues, not a restriction on existing IDs.

### Q: Where is data stored?

```
.beads/
├── beads.db        # SQLite database (primary storage)
├── issues.jsonl    # JSONL export (for git)
├── config.yaml     # Project configuration
├── routes.jsonl    # Optional cross-project prefix routes
└── metadata.json   # Workspace metadata
```

### Q: Can one workspace refer to issues in another workspace?

Yes, with explicit cross-project routing. Add one JSON object per line to
`.beads/routes.jsonl`:

```jsonl
{"prefix":"api-","path":"../api"}
{"prefix":"ops-","path":"/srv/projects/ops/.beads"}
```

When an issue ID starts with a routed prefix, route-aware commands resolve that
ID against the target workspace's `.beads` directory. The path can point at a
project root or directly at a `.beads`/`_beads` directory; relative paths are
resolved from the workspace root, and town-level routing can also be discovered
from a parent with `mayor/town.json`.

Common route-aware operations include `show`, `update`, `close`, `reopen`,
`delete`, `defer`, `comments`, `label`, `dep`, `graph`, `audit`, and `lint`.
Routed mutations acquire the target workspace write lock and update the target
workspace's storage, not the caller's local database.

This is not automatic multi-repo synchronization. Routed issue operations still
do not push or pull remote repositories, copy issues between repositories, or
provide real-time collaboration. Routes are a local dispatch table for explicit
cross-workspace operations. Commit and synchronize each affected repository's
`.beads/` files through your normal VCS workflow.

External dependency status checks use explicit dependency IDs such as
`external:api:api-123` together with configured `external_projects.<name>` paths.
They let `ready`, `blocked`, `show`, `dep`, and `stats` account for blockers in
other workspaces without importing those issues into the local database.

---

## AI Agent Integration

br is designed for AI coding agents. See [AGENTS.md](AGENTS.md) for:

- JSON output schemas
- Workflow patterns
- Integration with MCP Agent Mail
- Degraded coordination when Agent Mail is unavailable
- Robot mode flags
- Best practices

You can also emit machine-readable JSON Schema documents directly:

```bash
br schema all --format json | jq '.schemas.Issue'
br schema issue-details --format toon
```

---

## VCS Integration

Using non-git version control? See [VCS_INTEGRATION.md](docs/VCS_INTEGRATION.md) for
equivalent commands and workflows.

Quick example:

```bash
# Agent workflow
br ready --json | jq '.[0]'           # Get top priority
br update br-abc --status in_progress # Claim work
# ... do work ...
br close br-abc --reason "Completed"  # Done; JSONL auto-flushes by default
br sync --flush-only                  # Final export check before staging .beads/
```

---

## Community Projects

- [**Beads Task-Issue Tracker**](https://github.com/w3dev33/beads-task-issue-tracker) — A desktop GUI for `br`, built with Tauri + Nuxt. Reads the same SQLite + JSONL files that `br` produces, providing a graphical interface for browsing and managing issues.

---

## About Contributions

Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via `gh` and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.

---

## License

MIT License (with OpenAI/Anthropic Rider) — see [LICENSE](LICENSE) for details.

---

<div align="center">
  <sub>Built with Rust. Powered by SQLite. Synced with Git.</sub>
</div>
