diff --git a/pkg/stringutil/ansi.go b/pkg/stringutil/ansi.go index 648bf00df50..5bbb36dd055 100644 --- a/pkg/stringutil/ansi.go +++ b/pkg/stringutil/ansi.go @@ -3,8 +3,12 @@ package stringutil import ( "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var ansiLog = logger.New("stringutil:ansi") + // StripANSI removes ANSI escape codes from a string using a comprehensive byte scanner. // It handles CSI sequences (\x1b[), OSC sequences (\x1b]), G0/G1 character set selections, // keypad mode sequences, reset sequences, and other common 2-character escape sequences. @@ -16,6 +20,8 @@ func StripANSI(s string) string { return s } + ansiLog.Printf("StripANSI: input length=%d", len(s)) + var result strings.Builder result.Grow(len(s)) // Pre-allocate capacity for efficiency diff --git a/pkg/workflow/compiler_safe_outputs_builder.go b/pkg/workflow/compiler_safe_outputs_builder.go index e21d57cb6cb..1df303bc144 100644 --- a/pkg/workflow/compiler_safe_outputs_builder.go +++ b/pkg/workflow/compiler_safe_outputs_builder.go @@ -1,5 +1,9 @@ package workflow +import "github.com/github/gh-aw/pkg/logger" + +var safeOutputsBuilderLog = logger.New("workflow:safe_outputs_builder") + // handlerConfigBuilder provides a fluent API for building handler configurations type handlerConfigBuilder struct { config map[string]any @@ -89,6 +93,7 @@ type handlerBuilder func(*SafeOutputsConfig) map[string]any // Returns nil if neither is set (default to true in JavaScript). func getEffectiveFooterForTemplatable(localFooter *string, globalFooter *bool) *string { if localFooter != nil { + safeOutputsBuilderLog.Printf("Footer: using local override %q", *localFooter) return localFooter } if globalFooter != nil { @@ -98,8 +103,10 @@ func getEffectiveFooterForTemplatable(localFooter *string, globalFooter *bool) * } else { s = "false" } + safeOutputsBuilderLog.Printf("Footer: derived %q from global bool", s) return &s } + safeOutputsBuilderLog.Print("Footer: not configured, deferring to JS default") return nil } @@ -108,6 +115,7 @@ func getEffectiveFooterForTemplatable(localFooter *string, globalFooter *bool) * // Returns nil if neither is set (default to "always" in JavaScript). func getEffectiveFooterString(localFooter *string, globalFooter *bool) *string { if localFooter != nil { + safeOutputsBuilderLog.Printf("FooterString: using local override %q", *localFooter) return localFooter } if globalFooter != nil { @@ -117,7 +125,9 @@ func getEffectiveFooterString(localFooter *string, globalFooter *bool) *string { } else { s = "none" } + safeOutputsBuilderLog.Printf("FooterString: derived %q from global bool", s) return &s } + safeOutputsBuilderLog.Print("FooterString: not configured, deferring to JS default") return nil } diff --git a/pkg/workflow/mcp_playwright_config.go b/pkg/workflow/mcp_playwright_config.go index c02984f2fc5..8ccdace2fdf 100644 --- a/pkg/workflow/mcp_playwright_config.go +++ b/pkg/workflow/mcp_playwright_config.go @@ -2,8 +2,12 @@ package workflow import ( "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var playwrightConfigLog = logger.New("workflow:mcp_playwright") + // PlaywrightDockerArgs represents the common Docker arguments for Playwright container type PlaywrightDockerArgs struct { ImageVersion string // Version for Docker image (mcr.microsoft.com/playwright:version) @@ -14,7 +18,7 @@ type PlaywrightDockerArgs struct { // Returns a map of environment variable names to their original expressions // Uses the same ExpressionExtractor as used for shell script security func extractExpressionsFromPlaywrightArgs(customArgs []string) map[string]string { - log.Printf("Extracting expressions from %d Playwright args", len(customArgs)) + playwrightConfigLog.Printf("Extracting expressions from %d Playwright args", len(customArgs)) if len(customArgs) == 0 { return make(map[string]string) } @@ -26,7 +30,7 @@ func extractExpressionsFromPlaywrightArgs(customArgs []string) map[string]string extractor := NewExpressionExtractor() mappings, err := extractor.ExtractExpressions(combined) if err != nil { - log.Printf("Failed to extract expressions from Playwright args: %s", err) + playwrightConfigLog.Printf("Failed to extract expressions from Playwright args: %s", err) return make(map[string]string) } @@ -36,7 +40,7 @@ func extractExpressionsFromPlaywrightArgs(customArgs []string) map[string]string result[mapping.EnvVar] = mapping.Original } - log.Printf("Extracted %d unique expressions from Playwright args", len(result)) + playwrightConfigLog.Printf("Extracted %d unique expressions from Playwright args", len(result)) return result } diff --git a/pkg/workflow/prompts.go b/pkg/workflow/prompts.go index 00b9e7b132c..d286c219cca 100644 --- a/pkg/workflow/prompts.go +++ b/pkg/workflow/prompts.go @@ -2,8 +2,12 @@ package workflow import ( "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var promptsLog = logger.New("workflow:prompts") + // prompts.go consolidates all prompt-related functions for agentic workflows. // This file contains functions that generate workflow steps to append various // contextual instructions to the agent's prompt file during execution. @@ -21,11 +25,11 @@ import ( // hasPlaywrightTool checks if the playwright tool is enabled in the tools configuration func hasPlaywrightTool(parsedTools *Tools) bool { if parsedTools == nil { - log.Print("Checking for Playwright tool: no parsed tools provided") + promptsLog.Print("Checking for Playwright tool: no parsed tools provided") return false } hasPlaywright := parsedTools.Playwright != nil - log.Printf("Playwright tool enabled: %v", hasPlaywright) + promptsLog.Printf("Playwright tool enabled: %v", hasPlaywright) return hasPlaywright } @@ -36,11 +40,11 @@ func hasPlaywrightTool(parsedTools *Tools) bool { // hasAgenticWorkflowsTool checks if the agentic workflows tool is enabled in the tools configuration func hasAgenticWorkflowsTool(parsedTools *Tools) bool { if parsedTools == nil { - log.Print("Checking for agentic-workflows tool: no parsed tools provided") + promptsLog.Print("Checking for agentic-workflows tool: no parsed tools provided") return false } hasAgenticWorkflows := parsedTools.AgenticWorkflows != nil - log.Printf("Agentic-workflows tool enabled: %v", hasAgenticWorkflows) + promptsLog.Printf("Agentic-workflows tool enabled: %v", hasAgenticWorkflows) return hasAgenticWorkflows } @@ -50,16 +54,16 @@ func hasAgenticWorkflowsTool(parsedTools *Tools) bool { // hasCommentRelatedTriggers checks if the workflow has any comment-related event triggers func (c *Compiler) hasCommentRelatedTriggers(data *WorkflowData) bool { - log.Printf("Checking for comment-related triggers: command_count=%d, on=%s", len(data.Command), data.On) + promptsLog.Printf("Checking for comment-related triggers: command_count=%d, on=%s", len(data.Command), data.On) // Check for command trigger (which expands to comment events) if len(data.Command) > 0 { - log.Print("Found command trigger, enabling comment-related features") + promptsLog.Print("Found command trigger, enabling comment-related features") return true } if data.On == "" { - log.Print("No 'on' trigger defined") + promptsLog.Print("No 'on' trigger defined") return false } @@ -67,11 +71,11 @@ func (c *Compiler) hasCommentRelatedTriggers(data *WorkflowData) bool { commentEvents := []string{"issue_comment", "pull_request_review_comment", "pull_request_review"} for _, event := range commentEvents { if strings.Contains(data.On, event) { - log.Printf("Found comment-related event trigger: %s", event) + promptsLog.Printf("Found comment-related event trigger: %s", event) return true } } - log.Print("No comment-related triggers found") + promptsLog.Print("No comment-related triggers found") return false } diff --git a/pkg/workflow/runtime_deduplication.go b/pkg/workflow/runtime_deduplication.go index 8b34ea3ea0d..9bdb4198b98 100644 --- a/pkg/workflow/runtime_deduplication.go +++ b/pkg/workflow/runtime_deduplication.go @@ -4,9 +4,12 @@ import ( "fmt" "strings" + "github.com/github/gh-aw/pkg/logger" "github.com/goccy/go-yaml" ) +var runtimeDeduplicationLog = logger.New("workflow:runtime_deduplication") + // DeduplicateRuntimeSetupStepsFromCustomSteps removes runtime setup action steps from custom steps // to avoid duplication when runtime steps are added before custom steps. // This function parses the YAML custom steps, removes any steps that use runtime setup actions, @@ -19,7 +22,7 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ return customSteps, runtimeRequirements, nil } - log.Printf("Deduplicating runtime setup steps from custom steps (%d runtimes)", len(runtimeRequirements)) + runtimeDeduplicationLog.Printf("Deduplicating runtime setup steps from custom steps (%d runtimes)", len(runtimeRequirements)) // Extract version comments from uses lines before unmarshaling // This is necessary because YAML treats "# comment" as a comment, not part of the value @@ -60,7 +63,7 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ for i := range runtimeRequirements { if runtimeRequirements[i].Runtime.ActionRepo != "" { actionRepoToReq[runtimeRequirements[i].Runtime.ActionRepo] = &runtimeRequirements[i] - log.Printf(" Will check steps using action: %s", runtimeRequirements[i].Runtime.ActionRepo) + runtimeDeduplicationLog.Printf(" Will check steps using action: %s", runtimeRequirements[i].Runtime.ActionRepo) } } @@ -145,7 +148,7 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ // User has truly customized the setup action - preserve it shouldPreserve = true filteredRuntimeIDs[req.Runtime.ID] = true - log.Printf(" Preserving user-customized runtime setup step: %s", usesStr) + runtimeDeduplicationLog.Printf(" Preserving user-customized runtime setup step: %s", usesStr) preservedCount++ break } @@ -166,14 +169,14 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ } // Carry over any other fields req.ExtraFields[key] = value - log.Printf(" Capturing extra field from setup step: %s = %v", key, value) + runtimeDeduplicationLog.Printf(" Capturing extra field from setup step: %s = %v", key, value) } } } // No real customization - remove this duplicate but keep extra fields shouldRemove = true - log.Printf(" Removing duplicate runtime setup step: %s", usesStr) + runtimeDeduplicationLog.Printf(" Removing duplicate runtime setup step: %s", usesStr) removedCount++ break } @@ -185,11 +188,11 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ } if removedCount == 0 && preservedCount == 0 { - log.Print(" No duplicate runtime setup steps found") + runtimeDeduplicationLog.Print(" No duplicate runtime setup steps found") return customSteps, runtimeRequirements, nil } - log.Printf(" Removed %d duplicate runtime setup steps, preserved %d user-customized steps", removedCount, preservedCount) + runtimeDeduplicationLog.Printf(" Removed %d duplicate runtime setup steps, preserved %d user-customized steps", removedCount, preservedCount) // Filter runtime requirements to exclude those with user-customized setup actions var filteredRequirements []RuntimeRequirement @@ -197,7 +200,7 @@ func DeduplicateRuntimeSetupStepsFromCustomSteps(customSteps string, runtimeRequ if !filteredRuntimeIDs[req.Runtime.ID] { filteredRequirements = append(filteredRequirements, req) } else { - log.Printf(" Excluding runtime %s from generated setup steps (user has custom setup)", req.Runtime.ID) + runtimeDeduplicationLog.Printf(" Excluding runtime %s from generated setup steps (user has custom setup)", req.Runtime.ID) } }