diff options
Diffstat (limited to 'internal/task/validator.go')
| -rw-r--r-- | internal/task/validator.go | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/internal/task/validator.go b/internal/task/validator.go new file mode 100644 index 0000000..ea0b1c2 --- /dev/null +++ b/internal/task/validator.go @@ -0,0 +1,65 @@ +package task + +import ( + "fmt" + "strings" +) + +// ValidationError collects multiple validation failures. +type ValidationError struct { + Errors []string +} + +func (e *ValidationError) Error() string { + return fmt.Sprintf("validation failed: %s", strings.Join(e.Errors, "; ")) +} + +func (e *ValidationError) Add(msg string) { + e.Errors = append(e.Errors, msg) +} + +func (e *ValidationError) HasErrors() bool { + return len(e.Errors) > 0 +} + +// Validate checks a task for required fields and valid values. +func Validate(t *Task) error { + ve := &ValidationError{} + + if t.Name == "" { + ve.Add("name is required") + } + if t.Claude.Instructions == "" { + ve.Add("claude.instructions is required") + } + if t.Claude.MaxBudgetUSD < 0 { + ve.Add("claude.max_budget_usd must be non-negative") + } + if t.Timeout.Duration < 0 { + ve.Add("timeout must be non-negative") + } + if t.Retry.MaxAttempts < 1 { + ve.Add("retry.max_attempts must be at least 1") + } + if t.Retry.Backoff != "" && t.Retry.Backoff != "linear" && t.Retry.Backoff != "exponential" { + ve.Add("retry.backoff must be 'linear' or 'exponential'") + } + validPriorities := map[Priority]bool{PriorityHigh: true, PriorityNormal: true, PriorityLow: true} + if t.Priority != "" && !validPriorities[t.Priority] { + ve.Add(fmt.Sprintf("invalid priority %q; must be high, normal, or low", t.Priority)) + } + if t.Claude.PermissionMode != "" { + validModes := map[string]bool{ + "default": true, "acceptEdits": true, "bypassPermissions": true, + "plan": true, "dontAsk": true, "delegate": true, + } + if !validModes[t.Claude.PermissionMode] { + ve.Add(fmt.Sprintf("invalid permission_mode %q", t.Claude.PermissionMode)) + } + } + + if ve.HasErrors() { + return ve + } + return nil +} |
