package analyze import ( "fmt" "os" "path/filepath" "strings" "gmgauthier.com/grokkit/internal/git" "gmgauthier.com/grokkit/internal/linter" ) // DiscoverSourceFiles finds all supported source files in a directory tree. // Exported for use by MCP server and other packages. func DiscoverSourceFiles(root string) ([]string, error) { var files []string err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if err != nil { return err } name := info.Name() if info.IsDir() { if strings.HasPrefix(name, ".") && name != "." && name != ".." || name == "node_modules" || name == "vendor" || name == "build" || name == "dist" { return filepath.SkipDir } return nil } if _, detectErr := linter.DetectLanguage(path); detectErr == nil { files = append(files, path) } return nil }) return files, err } // BuildProjectContext builds a context string for analysis prompts. // Exported for use by MCP server. func BuildProjectContext(dir string, files []string) string { var sb strings.Builder sb.WriteString("Project Root: " + dir + "\n\n") _, _ = fmt.Fprintf(&sb, "Total source files discovered: %d\n\n", len(files)) sb.WriteString("Key files (top-level view):\n") for _, f := range files { rel, _ := filepath.Rel(dir, f) if strings.Count(rel, string(filepath.Separator)) <= 2 { sb.WriteString(" - " + rel + "\n") } if sb.Len() > 2500 { break } } // Add git remotes if available if out, err := git.Run([]string{"remote", "-v"}); err == nil && out != "" { sb.WriteString("\nGit Remotes:\n" + out + "\n") } return sb.String() }