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
- func ExtractEpicBranch(b Bead) stringdeprecated
- func ExtractParentBranch(b Bead) string
- func IsEpicBead(b Bead) bool
- func ResolveBlocks(ctx context.Context, beads []Bead, anvilPaths map[string]string)
- func ResolveEpicBranches(ctx context.Context, beads []Bead, anvilPaths map[string]string)
- type AnvilResult
- type Bead
- type BeadPoller
Constants ¶
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>".
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.
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
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 ¶
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 ¶
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 ¶
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 ¶
ResolveEpicBranches enriches beads that belong to an epic with the epic's branch name. It discovers the epic relationship via two paths:
- Parent field: child.Parent is set to an epic bead ID (legacy).
- 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 ¶
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
// 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 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 ¶
PollSingle polls a single anvil by name and returns its beads.