diff --git a/pkg/workflow/close_entity_helpers.go b/pkg/workflow/close_entity_helpers.go index 445621d3aa..70e79624bd 100644 --- a/pkg/workflow/close_entity_helpers.go +++ b/pkg/workflow/close_entity_helpers.go @@ -106,10 +106,12 @@ func (c *Compiler) parseCloseEntityConfig(outputMap map[string]any, params Close // Set default max if not specified if config.Max == 0 { config.Max = 1 + logger.Printf("Set default max to 1 for %s", params.ConfigKey) } // Validate target-repo (wildcard "*" is not allowed) if validateTargetRepoSlug(config.TargetRepoSlug, logger) { + logger.Printf("Invalid target-repo slug for %s", params.ConfigKey) return nil } diff --git a/pkg/workflow/expression_patterns.go b/pkg/workflow/expression_patterns.go index 10bb10467b..303a8bb458 100644 --- a/pkg/workflow/expression_patterns.go +++ b/pkg/workflow/expression_patterns.go @@ -56,7 +56,17 @@ package workflow -import "regexp" +import ( + "regexp" + + "github.com/github/gh-aw/pkg/logger" +) + +var expressionPatternsLog = logger.New("workflow:expression_patterns") + +func init() { + expressionPatternsLog.Print("Initializing expression pattern regex compilation") +} // Core Expression Patterns var ( diff --git a/pkg/workflow/frontmatter_extraction_metadata.go b/pkg/workflow/frontmatter_extraction_metadata.go index 68befa9598..a763211eb4 100644 --- a/pkg/workflow/frontmatter_extraction_metadata.go +++ b/pkg/workflow/frontmatter_extraction_metadata.go @@ -4,8 +4,12 @@ import ( "fmt" "math" "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var frontmatterMetadataLog = logger.New("workflow:frontmatter_extraction_metadata") + // extractFeatures extracts the features field from frontmatter // Returns a map of feature flags and configuration options (supports boolean flags and string values) func (c *Compiler) extractFeatures(frontmatter map[string]any) map[string]any { @@ -67,9 +71,12 @@ func (c *Compiler) extractTrackerID(frontmatter map[string]any) (string, error) return "", nil } + frontmatterMetadataLog.Print("Extracting and validating tracker-id") + // Convert the value to string strValue, ok := value.(string) if !ok { + frontmatterMetadataLog.Printf("Invalid tracker-id type: %T", value) return "", fmt.Errorf("tracker-id must be a string, got %T. Example: tracker-id: \"my-tracker-123\"", value) } @@ -77,6 +84,7 @@ func (c *Compiler) extractTrackerID(frontmatter map[string]any) (string, error) // Validate minimum length if len(trackerID) < 8 { + frontmatterMetadataLog.Printf("tracker-id too short: %d characters", len(trackerID)) return "", fmt.Errorf("tracker-id must be at least 8 characters long (got %d)", len(trackerID)) } @@ -84,10 +92,12 @@ func (c *Compiler) extractTrackerID(frontmatter map[string]any) (string, error) for i, char := range trackerID { if (char < 'a' || char > 'z') && (char < 'A' || char > 'Z') && (char < '0' || char > '9') && char != '-' && char != '_' { + frontmatterMetadataLog.Printf("Invalid character in tracker-id at position %d", i+1) return "", fmt.Errorf("tracker-id contains invalid character at position %d: '%c' (only alphanumeric, hyphens, and underscores allowed)", i+1, char) } } + frontmatterMetadataLog.Printf("Successfully validated tracker-id: %s", trackerID) return trackerID, nil } @@ -152,6 +162,7 @@ func (c *Compiler) extractToolsTimeout(tools map[string]any) (int, error) { // Check if timeout is explicitly set in tools if timeoutValue, exists := tools["timeout"]; exists { + frontmatterMetadataLog.Printf("Extracting tools.timeout value: type=%T", timeoutValue) var timeout int // Handle different numeric types with safe conversions to prevent overflow switch v := timeoutValue.(type) { @@ -166,14 +177,17 @@ func (c *Compiler) extractToolsTimeout(tools map[string]any) (int, error) { case float64: timeout = int(v) default: + frontmatterMetadataLog.Printf("Invalid tools.timeout type: %T", timeoutValue) return 0, fmt.Errorf("tools.timeout must be an integer, got %T", timeoutValue) } // Validate minimum value per schema constraint if timeout < 1 { + frontmatterMetadataLog.Printf("Invalid tools.timeout value: %d (must be >= 1)", timeout) return 0, fmt.Errorf("tools.timeout must be at least 1 second, got %d. Example:\ntools:\n timeout: 60", timeout) } + frontmatterMetadataLog.Printf("Extracted tools.timeout: %d seconds", timeout) return timeout, nil } diff --git a/pkg/workflow/safe_outputs_config_helpers_reflection.go b/pkg/workflow/safe_outputs_config_helpers_reflection.go index 364d2070b3..017ae8fecb 100644 --- a/pkg/workflow/safe_outputs_config_helpers_reflection.go +++ b/pkg/workflow/safe_outputs_config_helpers_reflection.go @@ -3,8 +3,12 @@ package workflow import ( "reflect" "sort" + + "github.com/github/gh-aw/pkg/logger" ) +var safeOutputReflectionLog = logger.New("workflow:safe_outputs_config_helpers_reflection") + // safeOutputFieldMapping maps struct field names to their tool names var safeOutputFieldMapping = map[string]string{ "CreateIssues": "create_issue", @@ -46,8 +50,11 @@ func hasAnySafeOutputEnabled(safeOutputs *SafeOutputsConfig) bool { return false } + safeOutputReflectionLog.Print("Checking if any safe outputs are enabled using reflection") + // Check Jobs separately as it's a map if len(safeOutputs.Jobs) > 0 { + safeOutputReflectionLog.Printf("Found %d custom jobs enabled", len(safeOutputs.Jobs)) return true } @@ -56,10 +63,12 @@ func hasAnySafeOutputEnabled(safeOutputs *SafeOutputsConfig) bool { for fieldName := range safeOutputFieldMapping { field := val.FieldByName(fieldName) if field.IsValid() && !field.IsNil() { + safeOutputReflectionLog.Printf("Found enabled safe output field: %s", fieldName) return true } } + safeOutputReflectionLog.Print("No safe outputs enabled") return false } @@ -69,6 +78,7 @@ func getEnabledSafeOutputToolNamesReflection(safeOutputs *SafeOutputsConfig) []s return nil } + safeOutputReflectionLog.Print("Getting enabled safe output tool names using reflection") var tools []string // Use reflection to check all pointer fields @@ -83,10 +93,12 @@ func getEnabledSafeOutputToolNamesReflection(safeOutputs *SafeOutputsConfig) []s // Add custom job tools for jobName := range safeOutputs.Jobs { tools = append(tools, jobName) + safeOutputReflectionLog.Printf("Added custom job tool: %s", jobName) } // Sort tools to ensure deterministic compilation sort.Strings(tools) + safeOutputReflectionLog.Printf("Found %d enabled safe output tools", len(tools)) return tools } diff --git a/pkg/workflow/safe_outputs_config_messages.go b/pkg/workflow/safe_outputs_config_messages.go index 8afea14360..373f5739e8 100644 --- a/pkg/workflow/safe_outputs_config_messages.go +++ b/pkg/workflow/safe_outputs_config_messages.go @@ -3,19 +3,25 @@ package workflow import ( "encoding/json" "fmt" + + "github.com/github/gh-aw/pkg/logger" ) +var safeOutputMessagesLog = logger.New("workflow:safe_outputs_config_messages") + // ======================================== // Safe Output Messages Configuration // ======================================== // parseMessagesConfig parses the messages configuration from safe-outputs frontmatter func parseMessagesConfig(messagesMap map[string]any) *SafeOutputMessagesConfig { + safeOutputMessagesLog.Printf("Parsing messages configuration with %d fields", len(messagesMap)) config := &SafeOutputMessagesConfig{} if appendOnly, exists := messagesMap["append-only-comments"]; exists { if appendOnlyBool, ok := appendOnly.(bool); ok { config.AppendOnlyComments = appendOnlyBool + safeOutputMessagesLog.Printf("Set append-only-comments: %t", appendOnlyBool) } } @@ -82,11 +88,13 @@ func parseMessagesConfig(messagesMap map[string]any) *SafeOutputMessagesConfig { // - true: always allows mentions (error in strict mode) // - object: detailed configuration with allow-team-members, allow-context, allowed, max func parseMentionsConfig(mentions any) *MentionsConfig { + safeOutputMessagesLog.Printf("Parsing mentions configuration: type=%T", mentions) config := &MentionsConfig{} // Handle boolean value if boolVal, ok := mentions.(bool); ok { config.Enabled = &boolVal + safeOutputMessagesLog.Printf("Mentions configured as boolean: %t", boolVal) return config } @@ -157,9 +165,12 @@ func serializeMessagesConfig(messages *SafeOutputMessagesConfig) (string, error) if messages == nil { return "", nil } + safeOutputMessagesLog.Print("Serializing messages configuration to JSON") jsonBytes, err := json.Marshal(messages) if err != nil { + safeOutputMessagesLog.Printf("Failed to serialize messages config: %v", err) return "", fmt.Errorf("failed to serialize messages config: %w", err) } + safeOutputMessagesLog.Printf("Serialized messages config: %d bytes", len(jsonBytes)) return string(jsonBytes), nil }