feat: Add workflow template system for agent-executable checklists
Adds `bd workflow` command group that creates epics with dependent child tasks
from YAML templates. This enables structured multi-step workflows like version
bumps where agents can work through tasks with verification and dependencies.
Commands:
- `bd workflow list` - List available workflow templates
- `bd workflow show <name>` - Show template details and task graph
- `bd workflow create <name> --var key=value` - Instantiate workflow
- `bd workflow status <epic-id>` - Show workflow progress
- `bd workflow verify <task-id>` - Run verification command
Features:
- Variable substitution with {{var}} syntax
- Built-in variables: {{today}}, {{user}}
- Preflight checks before workflow creation
- Hierarchical task IDs under epic (bd-xxx.1, bd-xxx.2)
- Dependency graph between tasks
- Verification commands embedded in task descriptions
Includes built-in `version-bump` template with 21 tasks covering:
- All 10+ version files
- check-versions.sh verification
- Git commit, tag, push
- CI monitoring (goreleaser, npm, pypi, homebrew)
- Local machine upgrades
- Final verification
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
70
internal/types/workflow.go
Normal file
70
internal/types/workflow.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package types
|
||||
|
||||
// WorkflowTemplate represents a workflow definition loaded from YAML
|
||||
type WorkflowTemplate struct {
|
||||
SchemaVersion int `yaml:"schema_version" json:"schema_version"`
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
Defaults WorkflowDefaults `yaml:"defaults" json:"defaults"`
|
||||
Variables []WorkflowVariable `yaml:"variables" json:"variables"`
|
||||
Preflight []PreflightCheck `yaml:"preflight" json:"preflight"`
|
||||
Epic WorkflowEpic `yaml:"epic" json:"epic"`
|
||||
Tasks []WorkflowTask `yaml:"tasks" json:"tasks"`
|
||||
}
|
||||
|
||||
// WorkflowDefaults contains default values for task fields
|
||||
type WorkflowDefaults struct {
|
||||
Priority int `yaml:"priority" json:"priority"`
|
||||
Type string `yaml:"type" json:"type"`
|
||||
}
|
||||
|
||||
// WorkflowVariable defines a variable that can be substituted in the template
|
||||
type WorkflowVariable struct {
|
||||
Name string `yaml:"name" json:"name"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
Required bool `yaml:"required" json:"required"`
|
||||
Pattern string `yaml:"pattern" json:"pattern"` // Optional regex validation
|
||||
DefaultValue string `yaml:"default" json:"default"` // Static default
|
||||
DefaultCommand string `yaml:"default_command" json:"default_command"` // Command to run for default
|
||||
}
|
||||
|
||||
// PreflightCheck is a check that must pass before workflow creation
|
||||
type PreflightCheck struct {
|
||||
Command string `yaml:"command" json:"command"`
|
||||
Message string `yaml:"message" json:"message"`
|
||||
}
|
||||
|
||||
// WorkflowEpic defines the parent epic for the workflow
|
||||
type WorkflowEpic struct {
|
||||
Title string `yaml:"title" json:"title"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
Priority int `yaml:"priority" json:"priority"`
|
||||
Labels []string `yaml:"labels" json:"labels"`
|
||||
}
|
||||
|
||||
// WorkflowTask defines a single task in the workflow
|
||||
type WorkflowTask struct {
|
||||
ID string `yaml:"id" json:"id"`
|
||||
Title string `yaml:"title" json:"title"`
|
||||
Description string `yaml:"description" json:"description"`
|
||||
Type string `yaml:"type" json:"type"`
|
||||
Priority int `yaml:"priority" json:"priority"`
|
||||
Estimate int `yaml:"estimate" json:"estimate"` // Minutes
|
||||
DependsOn []string `yaml:"depends_on" json:"depends_on"`
|
||||
Verification *Verification `yaml:"verification" json:"verification"`
|
||||
}
|
||||
|
||||
// Verification defines how to verify a task was completed successfully
|
||||
type Verification struct {
|
||||
Command string `yaml:"command" json:"command"`
|
||||
ExpectExit *int `yaml:"expect_exit" json:"expect_exit"`
|
||||
ExpectStdout string `yaml:"expect_stdout" json:"expect_stdout"`
|
||||
}
|
||||
|
||||
// WorkflowInstance represents a created workflow (epic + tasks)
|
||||
type WorkflowInstance struct {
|
||||
EpicID string `json:"epic_id"`
|
||||
TemplateName string `json:"template_name"`
|
||||
Variables map[string]string `json:"variables"`
|
||||
TaskMap map[string]string `json:"task_map"` // template task ID -> actual issue ID
|
||||
}
|
||||
Reference in New Issue
Block a user