diff --git a/pkg/parser/schedule_time_utils.go b/pkg/parser/schedule_time_utils.go index 165b3bd64de..c07738e7331 100644 --- a/pkg/parser/schedule_time_utils.go +++ b/pkg/parser/schedule_time_utils.go @@ -75,6 +75,7 @@ func parseTimeToMinutes(hourStr, minuteStr string) int { // parseTime converts a time string to minute and hour, with optional UTC offset // Supports formats: HH:MM, midnight, noon, 3pm, 1am, HH:MM utc+N, HH:MM utc+HH:MM, HH:MM utc-N, 3pm utc+9 func parseTime(timeStr string) (minute string, hour string) { + scheduleTimeUtilsLog.Printf("Parsing time string: %q", timeStr) // Check for UTC offset parts := strings.Split(timeStr, " ") var utcOffset int @@ -241,5 +242,9 @@ func mapWeekday(day string) string { "saturday": "6", "sat": "6", } - return weekdays[day] + result := weekdays[day] + if result == "" { + scheduleTimeUtilsLog.Printf("Unrecognized weekday name: %q", day) + } + return result } diff --git a/pkg/parser/schema_validation.go b/pkg/parser/schema_validation.go index 3c12c4dbe5d..a445a6acd4f 100644 --- a/pkg/parser/schema_validation.go +++ b/pkg/parser/schema_validation.go @@ -5,8 +5,11 @@ import ( "maps" "github.com/github/gh-aw/pkg/constants" + "github.com/github/gh-aw/pkg/logger" ) +var schemaValidationLog = logger.New("parser:schema_validation") + // sharedWorkflowForbiddenFields is a map for O(1) lookup of forbidden fields in shared workflows var sharedWorkflowForbiddenFields = buildForbiddenFieldsMap() @@ -21,6 +24,7 @@ func buildForbiddenFieldsMap() map[string]bool { // validateSharedWorkflowFields checks that a shared workflow doesn't contain forbidden fields func validateSharedWorkflowFields(frontmatter map[string]any) error { + schemaValidationLog.Printf("Checking shared workflow for forbidden fields: %d fields present", len(frontmatter)) var forbiddenFound []string for key := range frontmatter { @@ -30,6 +34,7 @@ func validateSharedWorkflowFields(frontmatter map[string]any) error { } if len(forbiddenFound) > 0 { + schemaValidationLog.Printf("Found %d forbidden field(s) in shared workflow: %v", len(forbiddenFound), forbiddenFound) if len(forbiddenFound) == 1 { return fmt.Errorf("field '%s' cannot be used in shared workflows (only allowed in main workflows with 'on' trigger)", forbiddenFound[0]) } @@ -52,6 +57,7 @@ func validateSharedWorkflowFields(frontmatter map[string]any) error { // ValidateMainWorkflowFrontmatterWithSchemaAndLocation validates main workflow frontmatter with file location info func ValidateMainWorkflowFrontmatterWithSchemaAndLocation(frontmatter map[string]any, filePath string) error { + schemaValidationLog.Printf("Validating main workflow frontmatter: file=%s, fields=%d", filePath, len(frontmatter)) // Filter out ignored fields before validation filtered := filterIgnoredFields(frontmatter) @@ -73,6 +79,7 @@ func ValidateMainWorkflowFrontmatterWithSchemaAndLocation(frontmatter map[string // ValidateIncludedFileFrontmatterWithSchemaAndLocation validates included file frontmatter with file location info func ValidateIncludedFileFrontmatterWithSchemaAndLocation(frontmatter map[string]any, filePath string) error { + schemaValidationLog.Printf("Validating included file frontmatter: file=%s, fields=%d", filePath, len(frontmatter)) // Filter out ignored fields before validation filtered := filterIgnoredFields(frontmatter) diff --git a/pkg/parser/yaml_error.go b/pkg/parser/yaml_error.go index b46ee4a8383..bf05c09e4a4 100644 --- a/pkg/parser/yaml_error.go +++ b/pkg/parser/yaml_error.go @@ -43,6 +43,8 @@ func adjustLineNumbersInFormattedError(formatted string, offset int) string { return formatted } + yamlErrorLog.Printf("Adjusting YAML error line numbers with offset: +%d", offset) + // Pattern to match line numbers in the format: // [line:col] at the start // " 1 | content" in the source context diff --git a/pkg/workflow/copilot_mcp.go b/pkg/workflow/copilot_mcp.go index b954cd0abce..f75cb53a3bc 100644 --- a/pkg/workflow/copilot_mcp.go +++ b/pkg/workflow/copilot_mcp.go @@ -88,6 +88,7 @@ func (e *CopilotEngine) renderCopilotMCPConfigWithContext(yaml *strings.Builder, // Determine if localhost URLs should be rewritten to host.docker.internal // This is needed when firewall is enabled (agent is not disabled) rewriteLocalhost := shouldRewriteLocalhostToDocker(workflowData) + copilotMCPLog.Printf("Localhost URL rewriting for tool %s: enabled=%t", toolName, rewriteLocalhost) // Use the shared renderer with copilot-specific requirements renderer := MCPConfigRenderer{ diff --git a/pkg/workflow/mcp_config_playwright_renderer.go b/pkg/workflow/mcp_config_playwright_renderer.go index c86818ef084..4b8962cba38 100644 --- a/pkg/workflow/mcp_config_playwright_renderer.go +++ b/pkg/workflow/mcp_config_playwright_renderer.go @@ -77,6 +77,7 @@ func renderPlaywrightMCPConfig(yaml *strings.Builder, playwrightConfig *Playwrig // Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. // Uses MCP Gateway spec format: container, entrypointArgs, mounts, and args fields. func renderPlaywrightMCPConfigWithOptions(yaml *strings.Builder, playwrightConfig *PlaywrightToolConfig, isLast bool, includeCopilotFields bool, inlineArgs bool) { + mcpPlaywrightLog.Printf("Rendering Playwright MCP config options: copilot_fields=%t, inline_args=%t", includeCopilotFields, inlineArgs) customArgs := getPlaywrightCustomArgs(playwrightConfig) // Extract all expressions from playwright arguments and replace them with env var references @@ -84,6 +85,7 @@ func renderPlaywrightMCPConfigWithOptions(yaml *strings.Builder, playwrightConfi // Replace expressions in custom args if len(customArgs) > 0 { + mcpPlaywrightLog.Printf("Applying %d custom Playwright args with %d extracted expressions", len(customArgs), len(expressions)) customArgs = replaceExpressionsInPlaywrightArgs(customArgs, expressions) }