examples/library-usage/README.md
This example demonstrates using Beads as a Go library in external projects (like VC).
Instead of spawning bd CLI processes:
In your Go project:
go get github.com/steveyegge/beads@latest
package main
import (
"context"
"log"
"github.com/steveyegge/beads"
)
func main() {
ctx := context.Background()
// Find and open database
dbPath := beads.FindDatabasePath()
store, err := beads.Open(ctx, 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...
}
# 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
The beads.Storage interface provides:
CreateIssue(ctx, issue, actor) - Create a new issueCreateIssues(ctx, issues, actor) - Batch create issuesGetIssue(ctx, id) - Get issue by IDUpdateIssue(ctx, id, updates, actor) - Update issue fieldsCloseIssue(ctx, id, reason, actor) - Close an issueSearchIssues(ctx, query, filter) - Search with filtersAddDependency(ctx, dep, actor) - Add dependency between issuesRemoveDependency(ctx, issueID, dependsOnID, actor) - Remove dependencyGetDependencies(ctx, issueID) - Get what this issue depends onGetDependents(ctx, issueID) - Get what depends on this issueGetDependencyTree(ctx, issueID, maxDepth, showAllPaths) - Visualize treeAddLabel(ctx, issueID, label, actor) - Add label to issueRemoveLabel(ctx, issueID, label, actor) - Remove labelGetLabels(ctx, issueID) - Get all labels for an issueGetIssuesByLabel(ctx, label) - Find issues with labelGetReadyWork(ctx, filter) - Find issues with no blockersGetBlockedIssues(ctx) - Find blocked issues with blocker infoGetEpicsEligibleForClosure(ctx) - Find completable epicsAddIssueComment(ctx, issueID, author, text) - Add commentGetIssueComments(ctx, issueID) - Get all commentsGetEvents(ctx, issueID, limit) - Get audit trailGetStatistics(ctx) - Get aggregate metricsAll types are exported via the beads package:
// 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
For VC (VibeCoder), the integration would look like:
// In VC's storage layer
type VCStorage struct {
beads beads.Storage
}
func NewVCStorage(ctx context.Context, dbPath string) (*VCStorage, error) {
store, err := beads.Open(ctx, 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
}
context.Context for cancellation supportdefer store.Close() after opening