poller

package
v0.5.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 13, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package poller provides the BeadPoller which discovers ready work across registered anvils by invoking 'bd ready --json' in each anvil directory.

Index

Constants

View Source
const DefaultEpicBranchPrefix = "epic/"

DefaultEpicBranchPrefix is the branch name prefix used when an epic bead has no explicit epic-branch label. The branch name is derived as "epic/<epic-id>".

View Source
const DefaultFeatureBranchPrefix = "feature/"

DefaultFeatureBranchPrefix is the branch name prefix used for non-epic parent beads (e.g. features) that have no explicit epic-branch label.

View Source
const EpicBranchLabelPrefix = "epic-branch:"

EpicBranchLabelPrefix is the label prefix used to define an epic's feature branch. A label "epic-branch:feature/depcheck" means the epic uses "feature/depcheck" as its shared branch.

Variables

This section is empty.

Functions

func ExtractEpicBranch deprecated

func ExtractEpicBranch(b Bead) string

ExtractEpicBranch is a backward-compatible wrapper that preserves the legacy semantics used by older callers. It mirrors the label parsing logic of ExtractParentBranch, but for non-epic beads without an explicit epic-branch label it returns the empty string instead of a default feature branch. New code should prefer ExtractParentBranch.

Deprecated: Use ExtractParentBranch instead.

func ExtractParentBranch

func ExtractParentBranch(b Bead) string

ExtractParentBranch extracts the shared feature branch name from a parent bead's labels. It looks for a label with the "epic-branch:" prefix. If none is found, it returns a default branch: "epic/<bead-id>" for epics, or "feature/<bead-id>" for other types (e.g. features with children).

func IsEpicBead

func IsEpicBead(b Bead) bool

IsEpicBead returns true if the bead is an epic type. This is used by the daemon for the legacy epic branch creation path. For Crucible candidacy, use crucible.IsCrucibleCandidate which checks for children (Blocks) instead.

func ResolveBlocks

func ResolveBlocks(ctx context.Context, beads []Bead, anvilPaths map[string]string)

ResolveBlocks enriches ready beads with their blocks (children) field by calling `bd show <id> --json` for each bead. Lookups are run concurrently to avoid adding sequential latency when there are many beads.

This is needed because `bd ready --json` may not include the blocks field. All bead types are checked — any bead (feature, task, etc.) can have children that need to be resolved.

func ResolveEpicBranches

func ResolveEpicBranches(ctx context.Context, beads []Bead, anvilPaths map[string]string)

ResolveEpicBranches enriches beads that belong to an epic with the epic's branch name. It discovers the epic relationship via two paths:

  1. Parent field: child.Parent is set to an epic bead ID (legacy).
  2. Blocks field: child.Blocks contains an epic-type bead ID, meaning the child blocks the epic in the dependency graph. This is the preferred approach because beads with a parent set are hidden from `bd ready`.

It calls `bd show <id> --json` for each unique candidate, caching results to avoid duplicate calls.

Types

type AnvilResult

type AnvilResult struct {
	Name  string
	Beads []Bead
	Err   error
}

AnvilResult holds the poll result for a single anvil.

type Bead

type Bead struct {
	ID           string    `json:"id"`
	Title        string    `json:"title"`
	Description  string    `json:"description"`
	Status       string    `json:"status"`
	Priority     int       `json:"priority"`
	IssueType    string    `json:"issue_type"`
	Assignee     string    `json:"assignee"`
	Parent       string    `json:"parent"`
	Labels       []string  `json:"labels"`
	Blocks       []string  `json:"blocks"`       // Bead IDs that this bead blocks (children)
	DependsOn    []string  `json:"depends_on"`   // Bead IDs that this bead depends on
	Dependencies []BeadDep `json:"dependencies"` // Detailed dependency info from bd

	// Forge-injected: which anvil this bead belongs to
	Anvil string `json:"-"`
	// Forge-injected: epic branch name resolved from parent epic's labels.
	// When set, this bead should branch from and PR to this branch instead of main.
	EpicBranch string `json:"-"`
}

Bead represents an issue returned by 'bd ready --json'. Only the fields Forge needs are extracted.

type BeadDep added in v0.2.0

type BeadDep struct {
	IssueID     string `json:"issue_id"`
	DependsOnID string `json:"depends_on_id"`
	Type        string `json:"type"` // "parent-child", "blocks", etc.
}

BeadDep represents a dependency entry in the bd JSON output.

type BeadPoller

type BeadPoller struct {
	// contains filtered or unexported fields
}

BeadPoller polls registered anvils for ready beads.

func New

func New(anvils map[string]config.AnvilConfig) *BeadPoller

New creates a BeadPoller for the given anvil configurations.

func (*BeadPoller) Poll

func (p *BeadPoller) Poll(ctx context.Context) ([]Bead, []AnvilResult)

Poll runs 'bd ready --json' in each anvil directory, merges results, and returns them sorted by priority (lowest number = highest priority). Errors per-anvil are collected but do not stop other anvils from being polled.

func (*BeadPoller) PollInProgress

func (p *BeadPoller) PollInProgress(ctx context.Context) ([]Bead, []AnvilResult)

PollInProgress runs 'bd list --status=in_progress --json' in each anvil directory concurrently. It returns all in-progress beads, merged and sorted by priority, along with per-anvil results so callers can distinguish "no in-progress beads" from "bd list failed" and log errors accordingly.

func (*BeadPoller) PollSingle

func (p *BeadPoller) PollSingle(ctx context.Context, name string) ([]Bead, error)

PollSingle polls a single anvil by name and returns its beads.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL