Public API for programmatic use of Loom
pkg/api
go get github.com/uttufy/loom
import "github.com/uttufy/loom/pkg/api" loom, err := api.NewFromConfigFile("loom.yaml")
import ( "github.com/uttufy/loom/internal/config" "github.com/uttufy/loom/pkg/api" ) cfg := config.DefaultConfig() loom, err := api.New(cfg)
err := loom.Run(ctx)
loom.Stop()
tasks, err := loom.GetReadyTasks(ctx) for _, task := range tasks { fmt.Printf("%s: %s (score: %d)\n", task.Issue.ID, task.Issue.Title, task.Score) }
err := loom.ClaimTask(ctx, "issue-123", "my-agent", []string{"src/main.go"})
err := loom.CompleteTask(ctx, "issue-123", "Implemented feature X")
err := loom.FailTask(ctx, "issue-123", fmt.Errorf("tests failed"))
loom.RegisterHook(hooks.EventPreToolCall, func(ctx context.Context, hc *hooks.Context) (*hooks.Result, error) { // Validate tool call if hc.ToolCall.Name == "bash" { if isDestructive(hc.ToolCall.Command) { return &hooks.Result{ Block: true, Reason: "destructive command blocked", }, nil } } return &hooks.Result{}, nil })
err := loom.ValidateCommand("bash", "rm -rf /") if safety.IsBlocked(err) { fmt.Println("Command was blocked") }
loom.ApproveCommand("git push origin main")
locks := loom.GetLocks() for _, lock := range locks { fmt.Printf("%s locked by %s\n", lock.FilePath, lock.AgentID) }
conflicts, err := loom.DetectConflicts(ctx) for _, c := range conflicts { fmt.Printf("Conflict on %s between %s and %s\n", c.File, c.Agent1, c.Agent2) }
patterns := loom.GetPatterns() for _, p := range patterns { fmt.Printf("%s: %s\n", p.Name, p.Description) }
retro := &retrospective.Retrospective{ SessionID: "session-123", AgentID: "my-agent", Completed: []string{"issue-1", "issue-2"}, Strategies: []string{"TDD approach worked well"}, } err := loom.SaveRetrospective(retro)
stats := loom.GetMemoryStats() fmt.Printf("Context usage: %.0f%%\n", stats.ContextUsage * 100)
if loom.ShouldCompact(0.75) { loom.Compact(ctx) }
issue := &beadsclient.Issue{ ID: "issue-1", Title: "Fix bug", Priority: 1, } score, err := loom.ScoreTask(ctx, issue) fmt.Printf("Score: %d\n", score)
client := loom.GetClient() issues, err := client.Ready(ctx, beadsclient.WorkFilter{})
cfg := loom.GetConfig() fmt.Printf("Compact threshold: %.0f%%\n", cfg.Memory.CompactThreshold * 100)
type ScoredIssue struct { Issue *beadsclient.Issue Score int }
type FileLock struct { FilePath string IssueID string AgentID string ClaimedAt time.Time ExpiresAt time.Time }
type Pattern struct { ID string Name string Description string Applicability string SuccessRate float64 Examples []string UseCount int }
type Retrospective struct { ID string SessionID string AgentID string CreatedAt time.Time Completed []string Failed []FailedTask Strategies []string Patterns []Pattern }
err := loom.ValidateCommand("bash", "rm -rf /") if blocked, ok := err.(*safety.BlockedError); ok { fmt.Printf("Blocked: %s\n", blocked.Reason) }
if confirm, ok := err.(*safety.ConfirmationRequiredError); ok { fmt.Printf("Needs confirmation: %s\n", confirm.Command) }
err := loom.ClaimTask(ctx, issueID, agentID, files) if conflict, ok := err.(*coordinator.ConflictError); ok { fmt.Printf("Conflict on %s with %s\n", conflict.File, conflict.AgentID) }