# Beads Library Usage Example This example demonstrates using Beads as a Go library in external projects (like VC). ## Why Use Beads as a Library? Instead of spawning `bd` CLI processes: - ✅ **Direct API access** - Call functions directly instead of parsing JSON output - ✅ **Type safety** - Compile-time checking of types and interfaces - ✅ **Performance** - No process spawn overhead - ✅ **Transactions** - Access to database transactions for complex operations - ✅ **Shared database** - Multiple components can use same database connection - ✅ **Error handling** - Proper Go error types instead of parsing stderr ## Installation In your Go project: ```bash go get github.com/steveyegge/beads@latest ``` ## Basic Usage ```go package main import ( "context" "log" "github.com/steveyegge/beads" ) func main() { ctx := context.Background() // Find and open database dbPath := beads.FindDatabasePath() store, err := beads.NewSQLiteStorage(dbPath) if err != nil { log.Fatal(err) } defer store.Close() // Get ready work ready, err := store.GetReadyWork(ctx, beads.WorkFilter{ Status: beads.StatusOpen, Limit: 10, }) if err != nil { log.Fatal(err) } // Process ready issues... } ``` ## Running This Example ```bash # From this directory cd examples/library-usage # Make sure there's a Beads database bd init --prefix demo # Run the example go run main.go ``` ## Available Operations The `beads.Storage` interface provides: ### Issues - `CreateIssue(ctx, issue, actor)` - Create a new issue - `CreateIssues(ctx, issues, actor)` - Batch create issues - `GetIssue(ctx, id)` - Get issue by ID - `UpdateIssue(ctx, id, updates, actor)` - Update issue fields - `CloseIssue(ctx, id, reason, actor)` - Close an issue - `SearchIssues(ctx, query, filter)` - Search with filters ### Dependencies - `AddDependency(ctx, dep, actor)` - Add dependency between issues - `RemoveDependency(ctx, issueID, dependsOnID, actor)` - Remove dependency - `GetDependencies(ctx, issueID)` - Get what this issue depends on - `GetDependents(ctx, issueID)` - Get what depends on this issue - `GetDependencyTree(ctx, issueID, maxDepth, showAllPaths)` - Visualize tree ### Labels - `AddLabel(ctx, issueID, label, actor)` - Add label to issue - `RemoveLabel(ctx, issueID, label, actor)` - Remove label - `GetLabels(ctx, issueID)` - Get all labels for an issue - `GetIssuesByLabel(ctx, label)` - Find issues with label ### Ready Work & Blocking - `GetReadyWork(ctx, filter)` - Find issues with no blockers - `GetBlockedIssues(ctx)` - Find blocked issues with blocker info - `GetEpicsEligibleForClosure(ctx)` - Find completable epics ### Comments & Events - `AddIssueComment(ctx, issueID, author, text)` - Add comment - `GetIssueComments(ctx, issueID)` - Get all comments - `GetEvents(ctx, issueID, limit)` - Get audit trail ### Statistics - `GetStatistics(ctx)` - Get aggregate metrics ## Types All types are exported via the `beads` package: ```go // Core types beads.Issue beads.Status (Open, InProgress, Closed, Blocked) beads.IssueType (Bug, Feature, Task, Epic, Chore) beads.Priority (0-4) // Relationships beads.Dependency beads.DependencyType (Blocks, Related, ParentChild, DiscoveredFrom) // Metadata beads.Label beads.Comment beads.Event // Queries beads.IssueFilter beads.WorkFilter beads.BlockedIssue beads.EpicStatus beads.Statistics ``` ## VC Integration Example For VC (VibeCoder), the integration would look like: ```go // In VC's storage layer type VCStorage struct { beads beads.Storage } func NewVCStorage(dbPath string) (*VCStorage, error) { store, err := beads.NewSQLiteStorage(dbPath) if err != nil { return nil, err } return &VCStorage{beads: store}, nil } // Claim ready work for executor func (s *VCStorage) ClaimWork(ctx context.Context, executorID string) (*beads.Issue, error) { ready, err := s.beads.GetReadyWork(ctx, beads.WorkFilter{ Status: beads.StatusOpen, Limit: 1, }) if err != nil { return nil, err } if len(ready) == 0 { return nil, nil // No work available } issue := ready[0] // Claim it updates := map[string]interface{}{ "status": beads.StatusInProgress, "assignee": executorID, } if err := s.beads.UpdateIssue(ctx, issue.ID, updates, executorID); err != nil { return nil, err } return issue, nil } ``` ## Best Practices 1. **Context** - Always pass `context.Context` for cancellation support 2. **Actor** - Provide meaningful actor strings for audit trail 3. **Error handling** - Check all errors; database operations can fail 4. **Close** - Always `defer store.Close()` after opening 5. **Transactions** - For complex multi-step operations, consider using the underlying database connection directly ## See Also - [EXTENDING.md](../../EXTENDING.md) - Detailed extension guide - [beads.go](../../beads.go) - Public API source - [internal/storage/storage.go](../../internal/storage/storage.go) - Storage interface