diff --git a/pkg/cli/fix_codemods.go b/pkg/cli/fix_codemods.go index ddabbbd18a5..f84a687cd34 100644 --- a/pkg/cli/fix_codemods.go +++ b/pkg/cli/fix_codemods.go @@ -1,5 +1,9 @@ package cli +import "github.com/github/gh-aw/pkg/logger" + +var fixCodemodsLog = logger.New("cli:fix_codemods") + // Codemod represents a single code transformation that can be applied to workflow files type Codemod struct { ID string // Unique identifier for the codemod @@ -17,7 +21,7 @@ type CodemodResult struct { // GetAllCodemods returns all available codemods in the registry func GetAllCodemods() []Codemod { - return []Codemod{ + codemods := []Codemod{ getTimeoutMinutesCodemod(), getNetworkFirewallCodemod(), getCommandToSlashCommandCodemod(), @@ -45,4 +49,6 @@ func GetAllCodemods() []Codemod { getSerenaLocalModeCodemod(), // Replace tools.serena mode: local with mode: docker getGitHubAppCodemod(), // Rename deprecated 'app' to 'github-app' } + fixCodemodsLog.Printf("Loaded codemod registry: %d codemods available", len(codemods)) + return codemods } diff --git a/pkg/console/spinner.go b/pkg/console/spinner.go index 1bea3b6181b..803e83a0a73 100644 --- a/pkg/console/spinner.go +++ b/pkg/console/spinner.go @@ -45,10 +45,13 @@ import ( "github.com/charmbracelet/bubbles/spinner" tea "github.com/charmbracelet/bubbletea" + "github.com/github/gh-aw/pkg/logger" "github.com/github/gh-aw/pkg/styles" "github.com/github/gh-aw/pkg/tty" ) +var spinnerLog = logger.New("console:spinner") + // updateMessageMsg is a custom message for updating the spinner message type updateMessageMsg string @@ -101,7 +104,10 @@ type SpinnerWrapper struct { // NewSpinner creates a new spinner with the given message using MiniDot style. // Automatically disabled when not running in a TTY or when ACCESSIBLE env var is set. func NewSpinner(message string) *SpinnerWrapper { - enabled := tty.IsStderrTerminal() && os.Getenv("ACCESSIBLE") == "" + isTTY := tty.IsStderrTerminal() + isAccessible := os.Getenv("ACCESSIBLE") != "" + enabled := isTTY && !isAccessible + spinnerLog.Printf("Creating spinner: message=%q, tty=%t, accessible=%t, enabled=%t", message, isTTY, isAccessible, enabled) s := &SpinnerWrapper{enabled: enabled} if enabled { @@ -120,11 +126,13 @@ func (s *SpinnerWrapper) Start() { s.mu.Lock() if s.running { s.mu.Unlock() + spinnerLog.Print("Spinner already running, skipping Start") return } s.running = true s.wg.Add(1) s.mu.Unlock() + spinnerLog.Print("Starting spinner") go func() { defer s.wg.Done() _, _ = s.program.Run() @@ -138,6 +146,7 @@ func (s *SpinnerWrapper) Stop() { if s.running { s.running = false s.mu.Unlock() + spinnerLog.Print("Stopping spinner") s.program.Quit() s.wg.Wait() // Wait for the goroutine to complete fmt.Fprintf(os.Stderr, "%s%s", ansiCarriageReturn, ansiClearLine) diff --git a/pkg/parser/import_processor.go b/pkg/parser/import_processor.go index 118c44e3f3d..d51c82229b4 100644 --- a/pkg/parser/import_processor.go +++ b/pkg/parser/import_processor.go @@ -72,5 +72,14 @@ type ImportSpec struct { // ProcessImportsFromFrontmatterWithSource processes imports field from frontmatter with source tracking // This version includes the workflow file path and YAML content for better error reporting func ProcessImportsFromFrontmatterWithSource(frontmatter map[string]any, baseDir string, cache *ImportCache, workflowFilePath string, yamlContent string) (*ImportsResult, error) { - return processImportsFromFrontmatterWithManifestAndSource(frontmatter, baseDir, cache, workflowFilePath, yamlContent) + importLog.Printf("Processing imports: workflowFile=%s, baseDir=%s", workflowFilePath, baseDir) + result, err := processImportsFromFrontmatterWithManifestAndSource(frontmatter, baseDir, cache, workflowFilePath, yamlContent) + if err != nil { + importLog.Printf("Import processing failed for %s: %v", workflowFilePath, err) + return result, err + } + if result != nil { + importLog.Printf("Import processing complete: importedFiles=%d, mergedTools=%d bytes", len(result.ImportedFiles), len(result.MergedTools)) + } + return result, nil } diff --git a/pkg/stringutil/identifiers.go b/pkg/stringutil/identifiers.go index 8ae8607533a..f1ed2f24ceb 100644 --- a/pkg/stringutil/identifiers.go +++ b/pkg/stringutil/identifiers.go @@ -3,8 +3,12 @@ package stringutil import ( "path/filepath" "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var identifiersLog = logger.New("stringutil:identifiers") + // NormalizeWorkflowName removes .md and .lock.yml extensions from workflow names. // This is used to standardize workflow identifiers regardless of the file format. // @@ -75,7 +79,9 @@ func MarkdownToLockFile(mdPath string) string { } cleaned := filepath.Clean(mdPath) - return strings.TrimSuffix(cleaned, ".md") + ".lock.yml" + lockPath := strings.TrimSuffix(cleaned, ".md") + ".lock.yml" + identifiersLog.Printf("MarkdownToLockFile: %s -> %s", mdPath, lockPath) + return lockPath } // LockFileToMarkdown converts a compiled lock file path back to its markdown source path. @@ -97,5 +103,7 @@ func LockFileToMarkdown(lockPath string) string { } cleaned := filepath.Clean(lockPath) - return strings.TrimSuffix(cleaned, ".lock.yml") + ".md" + mdPath := strings.TrimSuffix(cleaned, ".lock.yml") + ".md" + identifiersLog.Printf("LockFileToMarkdown: %s -> %s", lockPath, mdPath) + return mdPath } diff --git a/pkg/stringutil/urls.go b/pkg/stringutil/urls.go index b2fd023e0f9..16bd4a7a059 100644 --- a/pkg/stringutil/urls.go +++ b/pkg/stringutil/urls.go @@ -3,8 +3,12 @@ package stringutil import ( "net/url" "strings" + + "github.com/github/gh-aw/pkg/logger" ) +var urlsLog = logger.New("stringutil:urls") + // NormalizeGitHubHostURL ensures the host URL has a scheme (defaulting to https://) and no trailing slashes. // It is safe to call with URLs that already have an http:// or https:// scheme. func NormalizeGitHubHostURL(rawHostURL string) string { @@ -35,12 +39,14 @@ func NormalizeGitHubHostURL(rawHostURL string) string { // ExtractDomainFromURL("http://sub.domain.com:8080/path") // returns "sub.domain.com" // ExtractDomainFromURL("localhost:8080") // returns "localhost" func ExtractDomainFromURL(urlStr string) string { + urlsLog.Printf("Extracting domain from URL: %s", urlStr) // Handle full URLs with protocols (http://, https://) if strings.HasPrefix(urlStr, "http://") || strings.HasPrefix(urlStr, "https://") { // Parse full URL parsedURL, err := url.Parse(urlStr) if err != nil { // Fall back to string manipulation if parsing fails + urlsLog.Printf("URL parse failed, using fallback: %v", err) return extractDomainFallback(urlStr) } return parsedURL.Hostname()