workflow

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Dec 26, 2025 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package workflow provides workflow state management and node implementations for AI-powered development workflows.

Core types:

  • State: Workflow execution state with git, spec, implementation, and review data
  • NodeFunc: Function signature for workflow nodes
  • NodeConfig: Configuration for node behavior (retries, transcripts, etc.)
  • Ticket: External ticket reference (Jira, GitHub issue, etc.)

Workflow nodes:

  • CreateWorktreeNode: Creates git worktree for isolated work
  • GenerateSpecNode: Generates feature specification from ticket
  • ImplementNode: Implements code based on specification
  • ReviewNode: Reviews implementation for issues
  • FixFindingsNode: Fixes issues found during review
  • RunTestsNode: Executes test suite
  • CheckLintNode: Runs linting checks
  • CreatePRNode: Creates pull request
  • NotifyNode: Sends workflow notifications

Example usage:

state := workflow.NewState("ticket-to-pr")
state.SetTicket(workflow.Ticket{ID: "TK-421", Title: "Add feature"})
result, err := workflow.CreateWorktreeNode(ctx, state)

Index

Constants

View Source
const DefaultLintCommand = "go vet ./..."

DefaultLintCommand is the default command used to run linting.

View Source
const DefaultTestCommand = "go test -race ./..."

DefaultTestCommand is the default command used to run tests.

Variables

This section is empty.

Functions

func DefaultReviewRouter

func DefaultReviewRouter(state State) string

DefaultReviewRouter uses 3 max attempts

func ReviewRouter

func ReviewRouter(state State, maxAttempts int) string

ReviewRouter returns the next node based on review results. Used with flowgraph conditional edges.

Types

type FileChange

type FileChange struct {
	Path      string `json:"path"`
	Operation string `json:"operation"` // "create", "modify", "delete"
	Content   string `json:"content,omitempty"`
}

FileChange represents a file modification during implementation

type GitState

type GitState struct {
	Worktree   string `json:"worktree,omitempty"`
	Branch     string `json:"branch,omitempty"`
	BaseBranch string `json:"baseBranch,omitempty"`
}

GitState tracks git workspace state

type ImplementState

type ImplementState struct {
	Implementation     string       `json:"implementation,omitempty"`
	Files              []FileChange `json:"files,omitempty"`
	ImplementTokensIn  int          `json:"implementTokensIn,omitempty"`
	ImplementTokensOut int          `json:"implementTokensOut,omitempty"`
}

ImplementState tracks implementation progress

type LintState

type LintState struct {
	LintOutput *artifact.LintOutput `json:"lintOutput,omitempty"`
	LintPassed bool                 `json:"lintPassed,omitempty"`
	LintRunAt  time.Time            `json:"lintRunAt,omitempty"`
}

LintState tracks lint/type check execution

type MetricsState

type MetricsState struct {
	TotalTokensIn  int           `json:"totalTokensIn"`
	TotalTokensOut int           `json:"totalTokensOut"`
	TotalCost      float64       `json:"totalCost"`
	StartTime      time.Time     `json:"startTime"`
	TotalDuration  time.Duration `json:"totalDuration"`
}

MetricsState tracks execution metrics

type NodeConfig

type NodeConfig struct {
	MaxReviewAttempts int    // Max review/fix cycles (default: 3)
	TestCommand       string // Test command (default: "go test ./...")
	LintCommand       string // Lint command (default: "go vet ./...")
	BaseBranch        string // Default base branch (default: "main")
}

NodeConfig configures node behavior

func DefaultNodeConfig

func DefaultNodeConfig() NodeConfig

DefaultNodeConfig returns sensible defaults

type NodeFunc

type NodeFunc func(ctx flowgraph.Context, state State) (State, error)

NodeFunc is a function that processes state and returns updated state. This signature is compatible with flowgraph's NodeFunc[State].

func WithRetry

func WithRetry(node NodeFunc, maxRetries int) NodeFunc

WithRetry wraps a node with retry logic

func WithTiming

func WithTiming(node NodeFunc) NodeFunc

WithTiming wraps a node with timing metrics

func WithTranscript

func WithTranscript(node NodeFunc, nodeName string) NodeFunc

WithTranscript wraps a node with transcript recording

type PullRequestState

type PullRequestState struct {
	PR        *pr.PullRequest `json:"pr,omitempty"`
	PRCreated time.Time       `json:"prCreated,omitempty"`
}

PullRequestState tracks pull request creation Named to avoid collision with pr.State (open/closed/merged)

type ReviewState

type ReviewState struct {
	Review          *artifact.ReviewResult `json:"review,omitempty"`
	ReviewAttempts  int                    `json:"reviewAttempts,omitempty"`
	ReviewTokensIn  int                    `json:"reviewTokensIn,omitempty"`
	ReviewTokensOut int                    `json:"reviewTokensOut,omitempty"`
}

ReviewState tracks code review

type SpecState

type SpecState struct {
	Spec            string    `json:"spec,omitempty"`
	SpecTokensIn    int       `json:"specTokensIn,omitempty"`
	SpecTokensOut   int       `json:"specTokensOut,omitempty"`
	SpecGeneratedAt time.Time `json:"specGeneratedAt,omitempty"`
}

SpecState tracks specification generation

type State

type State struct {
	// Identification
	RunID    string `json:"runId"`
	FlowID   string `json:"flowId"`
	TicketID string `json:"ticketId,omitempty"`

	// Input
	Ticket *Ticket `json:"ticket,omitempty"`

	// Embedded state components
	GitState
	SpecState
	ImplementState
	ReviewState
	PullRequestState
	TestState
	LintState
	MetricsState

	// Error tracking
	Error string `json:"error,omitempty"`
}

State is the complete state for dev workflows

func CheckLintNode

func CheckLintNode(ctx flowgraph.Context, state State) (State, error)

CheckLintNode runs linting and type checks.

Prerequisites: state.Worktree must be set Updates: state.LintOutput, state.LintPassed, state.LintRunAt

The node uses CommandRunner from context if available, otherwise falls back to ExecRunner. This allows for easy testing with MockRunner.

func CleanupNode

func CleanupNode(ctx flowgraph.Context, state State) (State, error)

CleanupNode cleans up the worktree.

Prerequisites: state.Worktree must be set Updates: clears state.Worktree

func CreatePRNode

func CreatePRNode(ctx flowgraph.Context, state State) (State, error)

CreatePRNode creates a pull request.

Prerequisites: state.Branch must be set and pushed Updates: state.PR, state.PRCreated

func CreateWorktreeNode

func CreateWorktreeNode(ctx flowgraph.Context, state State) (State, error)

CreateWorktreeNode creates an isolated git worktree for the task.

Prerequisites: state.TicketID or state.Branch must be set Updates: state.Worktree, state.Branch

func FixFindingsNode

func FixFindingsNode(ctx flowgraph.Context, state State) (State, error)

FixFindingsNode fixes issues found in review.

Prerequisites: state.Review with findings, state.Worktree Updates: state.Implementation, state.Files

func GenerateSpecNode

func GenerateSpecNode(ctx flowgraph.Context, state State) (State, error)

GenerateSpecNode generates a technical specification from the ticket.

Prerequisites: state.Ticket must be set Updates: state.Spec, state.SpecTokensIn/Out, state.SpecGeneratedAt

func ImplementNode

func ImplementNode(ctx flowgraph.Context, state State) (State, error)

ImplementNode implements code based on the specification.

Prerequisites: state.Spec, state.Worktree must be set Updates: state.Implementation, state.Files, state.ImplementTokensIn/Out

func NewState

func NewState(flowID string) State

NewState creates a new dev workflow state

func NotifyNode

func NotifyNode(ctx flowgraph.Context, state State) (State, error)

NotifyNode sends a notification based on current state.

This node is typically placed at the end of a workflow to notify interested parties of completion or failure. If no notifier is configured in the context, this is a no-op.

Updates: None (only sends notification)

func ReviewNode

func ReviewNode(ctx flowgraph.Context, state State) (State, error)

ReviewNode reviews implementation for issues.

Prerequisites: state.Spec or state.Implementation must be set Updates: state.Review, state.ReviewAttempts, state.ReviewTokensIn/Out

func RunTestsNode

func RunTestsNode(ctx flowgraph.Context, state State) (State, error)

RunTestsNode runs the test suite.

Prerequisites: state.Worktree must be set Updates: state.TestOutput, state.TestPassed, state.TestRunAt

The node uses CommandRunner from context if available, otherwise falls back to ExecRunner. This allows for easy testing with MockRunner.

func (*State) AddTokens

func (s *State) AddTokens(in, out int)

AddTokens updates token metrics

func (*State) AddTokensWithCost

func (s *State) AddTokensWithCost(in, out int, cost float64)

AddTokensWithCost updates token metrics with explicit cost

func (State) CanRetryReview

func (s State) CanRetryReview(maxAttempts int) bool

CanRetryReview returns true if we haven't exceeded review attempts

func (*State) FinalizeDuration

func (s *State) FinalizeDuration()

FinalizeDuration sets total duration from start time

func (State) HasError

func (s State) HasError() bool

HasError returns true if state has an error

func (State) NeedsReviewFix

func (s State) NeedsReviewFix() bool

NeedsReviewFix returns true if review found issues that need fixing

func (*State) SetError

func (s *State) SetError(err error)

SetError sets the error state

func (State) ShouldCreateDraftPR

func (s State) ShouldCreateDraftPR(maxAttempts int) bool

ShouldCreateDraftPR returns true if we should create a draft PR (review found issues but we've hit max attempts)

func (State) Summary

func (s State) Summary() string

Summary returns a human-readable summary of the state

func (State) Validate

func (s State) Validate(requirements ...StateRequirement) error

Validate checks if state has required fields

func (State) ValidateStrings

func (s State) ValidateStrings(requirements ...string) error

ValidateStrings validates using string requirements (for flexibility)

func (State) WithBaseBranch

func (s State) WithBaseBranch(branch string) State

WithBaseBranch sets the base branch for the workflow

func (State) WithRunID

func (s State) WithRunID(runID string) State

WithRunID sets a custom run ID

func (State) WithTicket

func (s State) WithTicket(ticket *Ticket) State

WithTicket adds ticket information to state

func (State) WithTicketID

func (s State) WithTicketID(ticketID string) State

WithTicketID sets just the ticket ID (for when full ticket isn't needed)

type StateRequirement

type StateRequirement string

StateRequirement defines a state prerequisite

const (
	RequireTicket         StateRequirement = "ticket"
	RequireWorktree       StateRequirement = "worktree"
	RequireSpec           StateRequirement = "spec"
	RequireImplementation StateRequirement = "implementation"
	RequireReview         StateRequirement = "review"
	RequireBranch         StateRequirement = "branch"
	RequireFiles          StateRequirement = "files"
)

type TestState

type TestState struct {
	TestOutput *artifact.TestOutput `json:"testOutput,omitempty"`
	TestPassed bool                 `json:"testPassed,omitempty"`
	TestRunAt  time.Time            `json:"testRunAt,omitempty"`
}

TestState tracks test execution

type Ticket

type Ticket struct {
	ID          string            `json:"id"`
	Title       string            `json:"title"`
	Description string            `json:"description"`
	Priority    string            `json:"priority,omitempty"`
	Type        string            `json:"type,omitempty"` // bug, feature, task, etc.
	Labels      []string          `json:"labels,omitempty"`
	Assignee    string            `json:"assignee,omitempty"`
	Reporter    string            `json:"reporter,omitempty"`
	URL         string            `json:"url,omitempty"`
	Metadata    map[string]string `json:"metadata,omitempty"`
}

Ticket represents input ticket data from an issue tracker

Jump to

Keyboard shortcuts

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