Documentation
¶
Overview ¶
Package loop provides the core agent loop that orchestrates Claude Code to implement user stories. It includes the main Loop struct for single PRD execution, Manager for parallel PRD execution, and Parser for processing Claude's stream-json output.
Index ¶
- Constants
- type Event
- type EventType
- type Loop
- func (l *Loop) DisableRetry()
- func (l *Loop) Events() <-chan Event
- func (l *Loop) IsPaused() bool
- func (l *Loop) IsRunning() bool
- func (l *Loop) IsStopped() bool
- func (l *Loop) Iteration() int
- func (l *Loop) MaxIterations() int
- func (l *Loop) Pause()
- func (l *Loop) Resume()
- func (l *Loop) Run(ctx context.Context) error
- func (l *Loop) SetMaxIterations(maxIter int)
- func (l *Loop) SetRetryConfig(config RetryConfig)
- func (l *Loop) SetWatchdogTimeout(timeout time.Duration)
- func (l *Loop) Stop()
- func (l *Loop) WatchdogTimeout() time.Duration
- type LoopInstance
- type LoopState
- type Manager
- func (m *Manager) ClearWorktreeInfo(name string, clearBranch bool) error
- func (m *Manager) Config() *config.Config
- func (m *Manager) DisableRetry()
- func (m *Manager) Events() <-chan ManagerEvent
- func (m *Manager) GetAllInstances() []*LoopInstance
- func (m *Manager) GetInstance(name string) *LoopInstance
- func (m *Manager) GetRunningCount() int
- func (m *Manager) GetRunningPRDs() []string
- func (m *Manager) GetState(name string) (LoopState, int, error)
- func (m *Manager) IsAnyRunning() bool
- func (m *Manager) MaxIterations() int
- func (m *Manager) Pause(name string) error
- func (m *Manager) Register(name, prdPath string) error
- func (m *Manager) RegisterWithWorktree(name, prdPath, worktreeDir, branch string) error
- func (m *Manager) SetBaseDir(baseDir string)
- func (m *Manager) SetCompletionCallback(fn func(prdName string))
- func (m *Manager) SetConfig(cfg *config.Config)
- func (m *Manager) SetMaxIterations(maxIter int)
- func (m *Manager) SetMaxIterationsForInstance(name string, maxIter int) error
- func (m *Manager) SetPostCompleteCallback(fn func(prdName, branch, workDir string))
- func (m *Manager) SetRetryConfig(config RetryConfig)
- func (m *Manager) Start(name string) error
- func (m *Manager) Stop(name string) error
- func (m *Manager) StopAll()
- func (m *Manager) Unregister(name string) error
- func (m *Manager) UpdateWorktreeInfo(name, worktreeDir, branch string) error
- type ManagerEvent
- type Provider
- type RetryConfig
Constants ¶
const DefaultWatchdogTimeout = 5 * time.Minute
DefaultWatchdogTimeout is the default duration of silence before the watchdog kills a hung process.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Event ¶
type Event struct {
Type EventType
Iteration int
Text string
Tool string
ToolInput map[string]interface{}
StoryID string
Err error
RetryCount int // Current retry attempt (1-based)
RetryMax int // Maximum retries allowed
}
Event represents a parsed event from Claude's stream-json output.
func ParseLine ¶
ParseLine parses a single line of stream-json output and returns an Event. If the line cannot be parsed or is not relevant, it returns nil.
func ParseLineCodex ¶
ParseLineCodex parses a single line of Codex exec --json JSONL output and returns an Event. If the line cannot be parsed or is not relevant, it returns nil.
func ParseLineCursor ¶ added in v0.8.0
ParseLineCursor parses a single line of Cursor CLI stream-json NDJSON and returns an Event. If the line cannot be parsed or is not relevant, it returns nil.
func ParseLineOpenCode ¶
type EventType ¶
type EventType int
EventType represents the type of event parsed from Claude's stream-json output.
const ( // EventUnknown represents an unrecognized event type. EventUnknown EventType = iota // EventIterationStart is emitted at the start of a Claude iteration (system init). EventIterationStart // EventAssistantText is emitted when Claude outputs text. EventAssistantText // EventToolStart is emitted when Claude invokes a tool. EventToolStart // EventToolResult is emitted when a tool returns a result. EventToolResult // EventStoryDone is emitted when Claude signals a story is done via <chief-done/>. EventStoryDone // EventComplete is emitted when all stories are complete (buildPrompt returns error). EventComplete // EventMaxIterationsReached is emitted when max iterations are reached. EventMaxIterationsReached // EventError is emitted when an error occurs. EventError // EventRetrying is emitted when retrying after a crash. EventRetrying // EventWatchdogTimeout is emitted when the watchdog kills a hung process. EventWatchdogTimeout )
type Loop ¶
type Loop struct {
// contains filtered or unexported fields
}
Loop manages the core agent loop that invokes the configured agent repeatedly until all stories are complete.
func NewLoopWithEmbeddedPrompt ¶
NewLoopWithEmbeddedPrompt creates a new Loop instance using the embedded agent prompt. The prompt is rebuilt on each iteration to inline the current story context.
func NewLoopWithWorkDir ¶
func NewLoopWithWorkDir(prdPath, workDir string, prompt string, maxIter int, provider Provider) *Loop
NewLoopWithWorkDir creates a new Loop instance with a configurable working directory. When workDir is empty, defaults to the project root for backward compatibility.
func (*Loop) DisableRetry ¶
func (l *Loop) DisableRetry()
DisableRetry disables automatic retry on crash.
func (*Loop) MaxIterations ¶
MaxIterations returns the current max iterations limit.
func (*Loop) Pause ¶
func (l *Loop) Pause()
Pause sets the pause flag. The loop will stop after the current iteration completes.
func (*Loop) SetMaxIterations ¶
SetMaxIterations updates the maximum iterations limit.
func (*Loop) SetRetryConfig ¶
func (l *Loop) SetRetryConfig(config RetryConfig)
SetRetryConfig updates the retry configuration.
func (*Loop) SetWatchdogTimeout ¶
SetWatchdogTimeout sets the watchdog timeout duration. Setting timeout to 0 disables the watchdog.
func (*Loop) Stop ¶
func (l *Loop) Stop()
Stop terminates the current agent process and stops the loop.
func (*Loop) WatchdogTimeout ¶
WatchdogTimeout returns the current watchdog timeout duration.
type LoopInstance ¶
type LoopInstance struct {
Name string
PRDPath string
WorktreeDir string // Working directory for this PRD (empty = project root)
Branch string // Git branch for this PRD (empty = current branch)
Loop *Loop
State LoopState
Iteration int
StartTime time.Time
Error error
// contains filtered or unexported fields
}
LoopInstance represents a single loop with its metadata.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager manages multiple Loop instances for parallel PRD execution.
func NewManager ¶
NewManager creates a new loop manager.
func (*Manager) ClearWorktreeInfo ¶
ClearWorktreeInfo clears the worktree directory and optionally the branch for a PRD instance.
func (*Manager) DisableRetry ¶
func (m *Manager) DisableRetry()
DisableRetry disables automatic retry for new loops.
func (*Manager) Events ¶
func (m *Manager) Events() <-chan ManagerEvent
Events returns the channel for receiving events from all loops.
func (*Manager) GetAllInstances ¶
func (m *Manager) GetAllInstances() []*LoopInstance
GetAllInstances returns a snapshot of all loop instances.
func (*Manager) GetInstance ¶
func (m *Manager) GetInstance(name string) *LoopInstance
GetInstance returns a copy of the loop instance data for a specific PRD.
func (*Manager) GetRunningCount ¶
GetRunningCount returns the number of currently running loops.
func (*Manager) GetRunningPRDs ¶
GetRunningPRDs returns the names of all currently running PRDs.
func (*Manager) IsAnyRunning ¶
IsAnyRunning returns true if any loop is currently running.
func (*Manager) MaxIterations ¶
MaxIterations returns the current default max iterations.
func (*Manager) RegisterWithWorktree ¶
RegisterWithWorktree registers a PRD with worktree metadata (does not start it).
func (*Manager) SetBaseDir ¶
SetBaseDir sets the project root directory so Claude runs from there and picks up CLAUDE.md.
func (*Manager) SetCompletionCallback ¶
SetCompletionCallback sets a callback that is called when any PRD completes.
func (*Manager) SetMaxIterations ¶
SetMaxIterations updates the default max iterations for new loops.
func (*Manager) SetMaxIterationsForInstance ¶
SetMaxIterationsForInstance updates max iterations for a specific running loop.
func (*Manager) SetPostCompleteCallback ¶
SetPostCompleteCallback sets a callback for post-completion actions (push, PR creation). The callback receives the PRD name, branch name, and working directory.
func (*Manager) SetRetryConfig ¶
func (m *Manager) SetRetryConfig(config RetryConfig)
SetRetryConfig sets the retry configuration for new loops.
func (*Manager) Unregister ¶
Unregister removes a PRD from the manager (stops it first if running).
func (*Manager) UpdateWorktreeInfo ¶
UpdateWorktreeInfo updates the worktree directory and branch for an existing PRD instance.
type ManagerEvent ¶
type ManagerEvent struct {
PRDName string
Event Event
Completed bool // True if this PRD just completed all stories
}
ManagerEvent represents an event from any managed loop.
type Provider ¶
type Provider interface {
Name() string
CLIPath() string
LoopCommand(ctx context.Context, prompt, workDir string) *exec.Cmd
InteractiveCommand(workDir, prompt string) *exec.Cmd
// CleanOutput extracts JSON from the provider's output format (e.g., NDJSON).
// Returns the original output if no cleaning needed.
CleanOutput(output string) string
ParseLine(line string) *Event
LogFileName() string
}
Provider is the interface for an agent CLI (e.g. Claude, Codex). Implementations live in internal/agent to avoid import cycles.
type RetryConfig ¶
type RetryConfig struct {
MaxRetries int // Maximum number of retry attempts (default: 3)
RetryDelays []time.Duration // Delays between retries (default: 0s, 5s, 15s)
Enabled bool // Whether retry is enabled (default: true)
}
RetryConfig configures automatic retry behavior on Claude crashes.
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig returns the default retry configuration.