refactor(recipe): add ResolvedParams for better param handling

Introduce ResolvedParams field to Recipe struct for storing resolved
parameter values from defaults and user overrides. Update loader to
populate and use it for template rendering. Adjust runner to use
ResolvedParams for root path and generalize file discovery.
This commit is contained in:
Greg Gauthier 2026-03-07 00:07:21 +00:00
parent 1c79abce8d
commit f5c73ab291
3 changed files with 18 additions and 16 deletions

View File

@ -32,26 +32,26 @@ func Load(path string, userParams map[string]any) (*Recipe, error) {
return nil, fmt.Errorf("yaml parse: %w", err) return nil, fmt.Errorf("yaml parse: %w", err)
} }
// Apply defaults // Apply defaults + user --param overrides
if r.Parameters == nil { if r.Parameters == nil {
r.Parameters = make(map[string]Parameter) r.Parameters = make(map[string]Parameter)
} }
params := make(map[string]any) r.ResolvedParams = make(map[string]any)
for name, p := range r.Parameters { for name, p := range r.Parameters {
if v, ok := userParams[name]; ok { if v, ok := userParams[name]; ok {
params[name] = v r.ResolvedParams[name] = v
} else if p.Default != nil { } else if p.Default != nil {
params[name] = p.Default r.ResolvedParams[name] = p.Default
} }
} }
// Render templates (so {{.package_path}} becomes "internal") // Render templates with resolved values
tpl, err := template.New("recipe").Parse(string(parts[2])) tpl, err := template.New("recipe").Parse(string(parts[2]))
if err != nil { if err != nil {
return nil, err return nil, err
} }
var rendered bytes.Buffer var rendered bytes.Buffer
if err := tpl.Execute(&rendered, params); err != nil { if err := tpl.Execute(&rendered, r.ResolvedParams); err != nil {
return nil, err return nil, err
} }
body := rendered.String() body := rendered.String()

View File

@ -85,15 +85,15 @@ Execute this step now. Respond ONLY with the expected output format — no expla
func (r *Runner) discoverFiles() []string { func (r *Runner) discoverFiles() []string {
var files []string var files []string
// Get root from parameter or default // Get root from --param or default
root := "internal" root := "."
if p, ok := r.Recipe.Parameters["package_path"]; ok { if v, ok := r.Recipe.ResolvedParams["package_path"]; ok {
if def, ok := p.Default.(string); ok && def != "" { if s, ok := v.(string); ok && s != "" {
root = def root = s
} }
} }
// Build set of allowed extensions from recipe frontmatter // Build allowed extensions from recipe frontmatter
allowedExt := make(map[string]bool) allowedExt := make(map[string]bool)
for _, lang := range r.Recipe.ProjectLanguages { for _, lang := range r.Recipe.ProjectLanguages {
if exts, ok := r.Recipe.Extensions[lang]; ok { if exts, ok := r.Recipe.Extensions[lang]; ok {
@ -107,10 +107,9 @@ func (r *Runner) discoverFiles() []string {
if err != nil || d.IsDir() { if err != nil || d.IsDir() {
return nil return nil
} }
ext := filepath.Ext(path) if allowedExt[filepath.Ext(path)] {
if allowedExt[ext] {
b, _ := os.ReadFile(path) b, _ := os.ReadFile(path)
if strings.Contains(string(b), "if err != nil") { // this is still Go-specific for now; we can generalize later if strings.Contains(string(b), "if err != nil") {
files = append(files, path) files = append(files, path)
} }
} }

View File

@ -7,10 +7,13 @@ type Recipe struct {
Parameters map[string]Parameter `yaml:"parameters"` Parameters map[string]Parameter `yaml:"parameters"`
AllowedShellCommands []string `yaml:"allowed_shell_commands"` AllowedShellCommands []string `yaml:"allowed_shell_commands"`
// New fields for generic file discovery (option 2) // Generic discovery support (option 2)
ProjectLanguages []string `yaml:"project_languages"` ProjectLanguages []string `yaml:"project_languages"`
Extensions map[string][]string `yaml:"extensions"` Extensions map[string][]string `yaml:"extensions"`
// Resolved runtime values from --param flags
ResolvedParams map[string]any `yaml:"-"`
// Internal fields populated by loader // Internal fields populated by loader
Overview string `yaml:"-"` Overview string `yaml:"-"`
Steps []Step `yaml:"-"` Steps []Step `yaml:"-"`