- bd-19: Fix import zero-value field handling using JSON presence detection - bd-20: Add --strict flag for dependency import failures - bd-21: Simplify getNextID SQL query (reduce params from 4 to 2) - bd-22: Add validation/warning for malformed issue IDs - bd-23: Optimize export dependency queries (fix N+1 problem) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
bd - Beads Issue Tracker 🔗
Issues chained together like beads.
A lightweight, dependency-aware issue tracker designed for AI-supervised coding workflows. Track dependencies, find ready work, and let agents chain together tasks automatically.
The Problem
You're 200 messages deep in a coding session with your AI agent. You've discovered 12 bugs, planned 8 features, debated 3 architectural changes. The agent asks: "What should I work on next?"
You scroll up. Your TODO.md has 47 unchecked boxes. Half are blocked by other tasks. Some are duplicates. You have no idea what's actually ready to work on.
The agent has forgotten. You've lost track. Work is being duplicated.
This is the reality of AI-assisted development:
- Agents hit context limits - Long conversations lose early tasks
- TODOs don't track dependencies - No way to know what's blocked
- Markdown doesn't scale - Finding ready work means manual scanning
- No shared state - Agent on your laptop, agent on your desktop, both out of sync
Agents need external memory. You need dependency tracking. Both of you need to know what's ready to work on.
Features
- ✨ Zero setup -
bd initcreates project-local database - 🔗 Dependency tracking - Four dependency types (blocks, related, parent-child, discovered-from)
- 📋 Ready work detection - Automatically finds issues with no open blockers
- 🤖 Agent-friendly -
--jsonflags for programmatic integration - 📦 Git-versioned - JSONL records stored in git, synced across machines
- 🌍 Distributed by design - Agents on multiple machines share one logical database via git
- 🏗️ Extensible - Add your own tables to the SQLite database
- 🔍 Project-aware - Auto-discovers database in
.beads/directory - 🌲 Dependency trees - Visualize full dependency graphs
- 🎨 Beautiful CLI - Colored output for humans, JSON for bots
- 💾 Full audit trail - Every change is logged
Installation
Quick Install (Recommended)
curl -fsSL https://raw.githubusercontent.com/steveyegge/beads/main/install.sh | bash
The installer will:
- Detect your platform (macOS/Linux, amd64/arm64)
- Install via
go installif Go is available - Fall back to building from source if needed
- Guide you through PATH setup if necessary
Manual Install
# Using go install (requires Go 1.21+)
go install github.com/steveyegge/beads/cmd/bd@latest
# Or build from source
git clone https://github.com/steveyegge/beads
cd beads
go build -o bd ./cmd/bd
sudo mv bd /usr/local/bin/ # or anywhere in your PATH
Quick Start
For Humans
Beads is designed for AI coding agents to use on your behalf. As a human, you typically just:
# 1. Initialize beads in your project
bd init
# 2. Add a note to your agent instructions (CLAUDE.md, AGENTS.md, etc.)
echo "We track work in Beads instead of Markdown. Run \`bd quickstart\` to see how." >> CLAUDE.md
# 3. Let agents handle the rest!
Most tasks will be created and managed by agents during conversations. You can check on things with:
bd list # See what's being tracked
bd show <issue-id> # Review a specific issue
bd ready # See what's ready to work on
bd dep tree <issue-id> # Visualize dependencies
For AI Agents
Run the interactive guide to learn the full workflow:
bd quickstart
Quick reference for agent workflows:
# Find ready work
bd ready --json | jq '.[0]'
# Create issues during work
bd create "Discovered bug" -t bug -p 0 --json
# Link discovered work back to parent
bd dep add <new-id> <parent-id> --type discovered-from
# Update status
bd update <issue-id> --status in_progress --json
# Complete work
bd close <issue-id> --reason "Implemented" --json
The Magic: Distributed Database via Git
Here's the crazy part: bd acts like a centralized database, but it's actually distributed via git.
When you install bd on any machine with your project repo, you get:
- ✅ Full query capabilities (dependencies, ready work, etc.)
- ✅ Fast local operations (<100ms via SQLite)
- ✅ Shared state across all machines (via git)
- ✅ No server, no daemon, no configuration
- ✅ AI-assisted merge conflict resolution
How it works:
- Each machine has a local SQLite cache (
.beads/*.db) - gitignored - Source of truth is JSONL (
.beads/issues.jsonl) - committed to git bd exportsyncs SQLite → JSONL before commitsbd importsyncs JSONL → SQLite after pulls- Git handles distribution; AI handles merge conflicts
The result: Agents on your laptop, your desktop, and your coworker's machine all query and update what feels like a single shared database, but it's really just git doing what git does best - syncing text files across machines.
No PostgreSQL instance. No MySQL server. No hosted service. Just install bd, clone the repo, and you're connected to the "database."
Usage
Creating Issues
bd create "Fix bug" -d "Description" -p 1 -t bug
bd create "Add feature" --description "Long description" --priority 2 --type feature
bd create "Task" -l "backend,urgent" --assignee alice
# Get JSON output for programmatic use
bd create "Fix bug" -d "Description" --json
Options:
-d, --description- Issue description-p, --priority- Priority (0-4, 0=highest)-t, --type- Type (bug|feature|task|epic|chore)-a, --assignee- Assign to user-l, --labels- Comma-separated labels--json- Output in JSON format
Viewing Issues
bd show bd-1 # Show full details
bd list # List all issues
bd list --status open # Filter by status
bd list --priority 1 # Filter by priority
bd list --assignee alice # Filter by assignee
# JSON output for agents
bd list --json
bd show bd-1 --json
Updating Issues
bd update bd-1 --status in_progress
bd update bd-1 --priority 2
bd update bd-1 --assignee bob
bd close bd-1 --reason "Completed"
bd close bd-1 bd-2 bd-3 # Close multiple
# JSON output
bd update bd-1 --status in_progress --json
bd close bd-1 --json
Dependencies
# Add dependency (bd-2 depends on bd-1)
bd dep add bd-2 bd-1
bd dep add bd-3 bd-1 --type blocks
# Remove dependency
bd dep remove bd-2 bd-1
# Show dependency tree
bd dep tree bd-2
# Detect cycles
bd dep cycles
Finding Work
# Show ready work (no blockers)
bd ready
bd ready --limit 20
bd ready --priority 1
bd ready --assignee alice
# Show blocked issues
bd blocked
# Statistics
bd stats
# JSON output for agents
bd ready --json
Database Discovery
bd automatically discovers your database in this order:
--dbflag:bd --db /path/to/db.db create "Issue"$BEADS_DBenvironment variable:export BEADS_DB=/path/to/db.db.beads/*.dbin current directory or ancestors (walks up like git)~/.beads/default.dbas fallback
This means you can:
- Initialize per-project databases with
bd init - Work from any subdirectory (bd finds the database automatically)
- Override for testing or multiple projects
Example:
# Initialize in project root
cd ~/myproject
bd init --prefix myapp
# Work from any subdirectory
cd ~/myproject/src/components
bd create "Fix navbar bug" # Uses ~/myproject/.beads/myapp.db
# Override for a different project
bd --db ~/otherproject/.beads/other.db list
Dependency Model
Beads has four types of dependencies:
- blocks - Hard blocker (affects ready work calculation)
- related - Soft relationship (just for context)
- parent-child - Epic/subtask hierarchy
- discovered-from - Tracks issues discovered while working on another issue
Only blocks dependencies affect the ready work queue.
Dependency Type Usage
-
blocks: Use when issue X cannot start until issue Y is completed
bd dep add bd-5 bd-3 --type blocks # bd-5 blocked by bd-3 -
related: Use for issues that are connected but don't block each other
bd dep add bd-10 bd-8 --type related # bd-10 related to bd-8 -
parent-child: Use for epic/subtask hierarchies
bd dep add bd-15 bd-12 --type parent-child # bd-15 is child of epic bd-12 -
discovered-from: Use when you discover new work while working on an issue
# While working on bd-20, you discover a bug bd create "Fix edge case bug" -t bug -p 1 bd dep add bd-21 bd-20 --type discovered-from # bd-21 discovered from bd-20
The discovered-from type is particularly useful for AI-supervised workflows, where the AI can automatically create issues for discovered work and link them back to the parent task.
AI Agent Integration
bd is designed to work seamlessly with AI coding agents:
# Agent discovers ready work
WORK=$(bd ready --limit 1 --json)
ISSUE_ID=$(echo $WORK | jq -r '.[0].id')
# Agent claims and starts work
bd update $ISSUE_ID --status in_progress --json
# Agent discovers new work while executing
bd create "Fix bug found in testing" -t bug -p 0 --json > new_issue.json
NEW_ID=$(cat new_issue.json | jq -r '.id')
bd dep add $NEW_ID $ISSUE_ID --type discovered-from
# Agent completes work
bd close $ISSUE_ID --reason "Implemented and tested" --json
The --json flag on every command makes bd perfect for programmatic workflows.
Ready Work Algorithm
An issue is "ready" if:
- Status is
open - It has NO open
blocksdependencies - All blockers are either closed or non-existent
Example:
bd-1 [open] ← blocks ← bd-2 [open] ← blocks ← bd-3 [open]
Ready work: [bd-1]
Blocked: [bd-2, bd-3]
Issue Lifecycle
open → in_progress → closed
↓
blocked (manually set, or has open blockers)
Architecture
beads/
├── cmd/bd/ # CLI entry point
│ ├── main.go # Core commands (create, list, show, update, close)
│ ├── init.go # Project initialization
│ ├── quickstart.go # Interactive guide
│ └── ...
├── internal/
│ ├── types/ # Core data types (Issue, Dependency, etc.)
│ └── storage/ # Storage interface
│ └── sqlite/ # SQLite implementation
└── EXTENDING.md # Database extension guide
Extending bd
Applications can extend bd's SQLite database with their own tables. See EXTENDING.md for the full guide.
Quick example:
-- Add your own tables to .beads/myapp.db
CREATE TABLE myapp_executions (
id INTEGER PRIMARY KEY,
issue_id TEXT NOT NULL,
status TEXT NOT NULL,
started_at DATETIME,
FOREIGN KEY (issue_id) REFERENCES issues(id)
);
-- Query across layers
SELECT i.*, e.status as execution_status
FROM issues i
LEFT JOIN myapp_executions e ON i.id = e.issue_id
WHERE i.status = 'in_progress';
This pattern enables powerful integrations while keeping bd simple and focused.
Comparison to Other Tools
| Feature | bd | Taskwarrior | GitHub Issues | Jira | Linear |
|---|---|---|---|---|---|
| Zero setup | ✅ | ✅ | ❌ | ❌ | ❌ |
| Dependency tracking | ✅ | ✅ | ⚠️ | ✅ | ✅ |
| Ready work detection | ✅ | ⚠️ | ❌ | ❌ | ❌ |
| Agent-friendly (JSON) | ✅ | ⚠️ | ⚠️ | ⚠️ | ⚠️ |
| Distributed via git | ✅ | ⚠️ | ❌ | ❌ | ❌ |
| Works offline | ✅ | ✅ | ❌ | ❌ | ❌ |
| AI-resolvable conflicts | ✅ | ❌ | ❌ | ❌ | ❌ |
| Extensible database | ✅ | ❌ | ❌ | ❌ | ❌ |
| No server required | ✅ | ✅ | ❌ | ❌ | ❌ |
| Built for AI agents | ✅ | ❌ | ❌ | ❌ | ❌ |
vs. Taskwarrior: Taskwarrior is great for personal task management, but bd is designed specifically for AI agents. bd has explicit dependency types (discovered-from), JSON-first API design, and JSONL storage optimized for git merging. Taskwarrior's sync server requires setup; bd uses git automatically.
Why bd?
bd is designed for AI coding agents, not humans.
Traditional issue trackers (Jira, GitHub Issues, Linear) assume humans are the primary users. Humans click through web UIs, drag cards on boards, and manually update status.
bd assumes AI agents are the primary users, with humans supervising:
- Agents discover work -
bd ready --jsongives agents unblocked tasks to execute - Dependencies prevent wasted work - Agents don't duplicate effort or work on blocked tasks
- Discovery during execution - Agents create issues for work they discover while executing, linked with
discovered-from - Agents lose focus - Long-running conversations can forget tasks; bd remembers everything
- Humans supervise - Check on progress with
bd listandbd dep tree, but don't micromanage
In human-managed workflows, issues are planning artifacts. In agent-managed workflows, issues are memory - preventing agents from forgetting tasks during long coding sessions.
Traditional issue trackers were built for human project managers. bd is built for autonomous agents.
Architecture: JSONL + SQLite
bd uses a dual-storage approach:
- JSONL files (
.beads/issues.jsonl) - Source of truth, committed to git - SQLite database (
.beads/*.db) - Ephemeral cache for fast queries, gitignored
This gives you:
- ✅ Git-friendly storage - Text diffs, AI-resolvable conflicts
- ✅ Fast queries - SQLite indexes for dependency graphs
- ✅ Simple workflow - Export before commit, import after pull
- ✅ No daemon required - In-process SQLite, ~10-100ms per command
When you run bd create, it writes to SQLite. Before committing to git, run bd export to sync to JSONL. After pulling, run bd import to sync back to SQLite. Git hooks can automate this.
Export/Import (JSONL Format)
bd can export and import issues as JSON Lines (one JSON object per line). This is perfect for git workflows and data portability.
Export Issues
# Export all issues to stdout
bd export --format=jsonl
# Export to file
bd export --format=jsonl -o issues.jsonl
# Export filtered issues
bd export --format=jsonl --status=open -o open-issues.jsonl
Issues are exported sorted by ID for consistent git diffs.
Import Issues
# Import from stdin
cat issues.jsonl | bd import
# Import from file
bd import -i issues.jsonl
# Skip existing issues (only create new ones)
bd import -i issues.jsonl --skip-existing
Import behavior:
- Existing issues (same ID) are updated with new values
- New issues are created
- All imports are atomic (all or nothing)
JSONL Format
Each line is a complete JSON issue object:
{"id":"bd-1","title":"Fix login bug","status":"open","priority":1,"issue_type":"bug","created_at":"2025-10-12T10:00:00Z","updated_at":"2025-10-12T10:00:00Z"}
{"id":"bd-2","title":"Add dark mode","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-10-12T11:00:00Z","updated_at":"2025-10-12T12:00:00Z"}
Git Workflow
Recommended approach: Use JSONL export as source of truth, SQLite database as ephemeral cache (not committed to git).
Setup
Add to .gitignore:
.beads/*.db
.beads/*.db-*
Add to git:
.beads/issues.jsonl
Workflow
# Export before committing
bd export -o .beads/issues.jsonl
git add .beads/issues.jsonl
git commit -m "Update issues"
git push
# Import after pulling
git pull
bd import -i .beads/issues.jsonl
Automated with Git Hooks
Create .git/hooks/pre-commit:
#!/bin/bash
bd export -o .beads/issues.jsonl
git add .beads/issues.jsonl
Create .git/hooks/post-merge:
#!/bin/bash
bd import -i .beads/issues.jsonl
Make hooks executable:
chmod +x .git/hooks/pre-commit .git/hooks/post-merge
Why JSONL?
- ✅ Git-friendly: One line per issue = clean diffs
- ✅ Mergeable: Concurrent appends rarely conflict
- ✅ Human-readable: Easy to review changes
- ✅ Scriptable: Use
jq,grep, or any text tools - ✅ Portable: Export/import between databases
Handling Conflicts
When two developers create new issues:
{"id":"bd-1","title":"First issue",...}
{"id":"bd-2","title":"Second issue",...}
+{"id":"bd-3","title":"From branch A",...}
+{"id":"bd-4","title":"From branch B",...}
Git may show a conflict, but resolution is simple: keep both lines (both changes are compatible).
See TEXT_FORMATS.md for detailed analysis of JSONL merge strategies and conflict resolution.
Examples
Check out the examples/ directory for:
- Python agent - Full agent implementation in Python
- Bash agent - Shell script agent example
- Git hooks - Automatic export/import on git operations
- Claude Desktop MCP - MCP server integration (coming soon)
FAQ
Why not just use GitHub Issues?
GitHub Issues requires internet, has API rate limits, and isn't designed for agents. bd works offline, has no limits, and gives you bd ready --json to instantly find unblocked work. Plus, bd's distributed database means agents on multiple machines share state via git—no API calls needed.
How is this different from Taskwarrior?
Taskwarrior is excellent for personal task management, but bd is built for AI agents:
- Explicit agent semantics:
discovered-fromdependency type,bd readyfor queue management - JSON-first design: Every command has
--jsonoutput - Git-native sync: No sync server setup required
- Merge-friendly JSONL: One issue per line, AI-resolvable conflicts
- Extensible SQLite: Add your own tables without forking
Can I use bd without AI agents?
Absolutely! bd is a great CLI issue tracker for humans too. The bd ready command is useful for anyone managing dependencies. Think of it as "Taskwarrior meets git."
What happens if two agents work on the same issue?
The last agent to export/commit wins. This is the same as any git-based workflow. To prevent conflicts:
- Have agents claim work with
bd update <id> --status in_progress - Query by assignee:
bd ready --assignee agent-name - Review git diffs before merging
For true multi-agent coordination, you'd need additional tooling (like locks or a coordination server). bd handles the simpler case: multiple humans/agents working on different tasks, syncing via git.
Do I need to run export/import manually?
No! Install the git hooks from examples/git-hooks/:
cd examples/git-hooks && ./install.sh
The hooks automatically export before commits and import after pulls/merges/checkouts. Set it up once, forget about it.
Can I track issues for multiple projects?
Yes! bd uses project-local databases:
cd ~/project1 && bd init --prefix proj1
cd ~/project2 && bd init --prefix proj2
Each project gets its own .beads/ directory with its own database and JSONL file. bd auto-discovers the correct database based on your current directory (walks up like git).
How do I migrate from GitHub Issues / Jira / Linear?
We don't have automated migration tools yet, but you can:
- Export issues from your current tracker (usually CSV or JSON)
- Write a simple script to convert to bd's JSONL format
- Import with
bd import -i issues.jsonl
See examples/ for scripting patterns. Contributions welcome!
Is this production-ready?
bd is in active development and used for real projects. The core functionality (create, update, dependencies, ready work) is stable. However:
- No 1.0 release yet
- API may change before 1.0
- Use for development/internal projects first
- Expect rapid iteration
Follow the repo for updates!
How does bd handle scale?
bd uses SQLite, which handles millions of rows efficiently. For a typical project with thousands of issues:
- Commands complete in <100ms
- Full-text search is instant
- Dependency graphs traverse quickly
- JSONL files stay small (one line per issue)
For extremely large projects (100k+ issues), you might want to filter exports or use multiple databases per component.
Can I use bd for non-code projects?
Sure! bd is just an issue tracker. Use it for:
- Writing projects (chapters as issues, dependencies as outlines)
- Research projects (papers, experiments, dependencies)
- Home projects (renovations with blocking tasks)
- Any workflow with dependencies
The agent-friendly design works for any AI-assisted workflow.
Troubleshooting
bd: command not found
bd is not in your PATH. Either:
# Check if installed
go list -f {{.Target}} github.com/steveyegge/beads/cmd/bd
# Add Go bin to PATH
export PATH="$PATH:$(go env GOPATH)/bin"
# Or reinstall
go install github.com/steveyegge/beads/cmd/bd@latest
database is locked
Another bd process is accessing the database, or SQLite didn't close properly. Solutions:
# Find and kill hanging processes
ps aux | grep bd
kill <pid>
# Remove lock files (safe if no bd processes running)
rm .beads/*.db-journal .beads/*.db-wal .beads/*.db-shm
failed to import: issue already exists
You're trying to import issues that conflict with existing ones. Options:
# Skip existing issues (only import new ones)
bd import -i issues.jsonl --skip-existing
# Or clear database and re-import everything
rm .beads/*.db
bd import -i .beads/issues.jsonl
Git merge conflict in issues.jsonl
When both sides add issues, you'll get conflicts. Resolution:
- Open
.beads/issues.jsonl - Look for
<<<<<<< HEADmarkers - Most conflicts can be resolved by keeping both sides
- Each line is independent unless IDs conflict
- For same-ID conflicts, keep the newest (check
updated_at)
Example resolution:
# After resolving conflicts manually
git add .beads/issues.jsonl
git commit
bd import -i .beads/issues.jsonl # Sync to SQLite
See TEXT_FORMATS.md for detailed merge strategies.
bd ready shows nothing but I have open issues
Those issues probably have open blockers. Check:
# See blocked issues
bd blocked
# Show dependency tree
bd dep tree <issue-id>
# Remove blocking dependency if needed
bd dep remove <from-id> <to-id>
Remember: Only blocks dependencies affect ready work.
Permission denied on git hooks
Git hooks need execute permissions:
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/post-merge
chmod +x .git/hooks/post-checkout
Or use the installer: cd examples/git-hooks && ./install.sh
bd init fails with "directory not empty"
.beads/ already exists. Options:
# Use existing database
bd list # Should work if already initialized
# Or remove and reinitialize (DESTROYS DATA!)
rm -rf .beads/
bd init
Export/import is slow
For large databases (10k+ issues):
# Export only open issues
bd export --format=jsonl --status=open -o .beads/issues.jsonl
# Or filter by priority
bd export --format=jsonl --priority=0 --priority=1 -o critical.jsonl
Consider splitting large projects into multiple databases.
Agent creates duplicate issues
Agents may not realize an issue already exists. Prevention strategies:
- Have agents search first:
bd list --json | grep "title" - Use labels to mark auto-created issues:
bd create "..." -l auto-generated - Review and deduplicate periodically:
bd list | sort
True deduplication logic would require fuzzy matching - contributions welcome!
Documentation
- README.md - You are here! Complete guide
- TEXT_FORMATS.md - JSONL format analysis and merge strategies
- GIT_WORKFLOW.md - Historical analysis of binary vs text approaches
- EXTENDING.md - Database extension patterns
- Run
bd quickstartfor interactive tutorial
Development
# Run tests
go test ./...
# Build
go build -o bd ./cmd/bd
# Run
./bd create "Test issue"
License
MIT
Credits
Built with ❤️ by developers who love tracking dependencies and finding ready work.
Inspired by the need for a simpler, dependency-aware issue tracker.
