package main import ( "os" "path/filepath" "slices" "strings" ) func expandPath(path string) (string, error) { if path == "~" || strings.HasPrefix(path, "~/") { home, err := os.UserHomeDir() if err != nil { return "", err } if path == "~" { return home, nil } return filepath.Join(home, strings.TrimPrefix(path, "~/")), nil } return path, nil } func dirLooksLikeFrontendSource(path string) bool { info, err := os.Stat(path) if err != nil || !info.IsDir() { return false } entries, err := os.ReadDir(path) if err != nil { return false } for _, entry := range entries { if entry.IsDir() { continue } name := entry.Name() if strings.HasSuffix(name, ".ts") || strings.HasSuffix(name, ".tsx") || strings.HasSuffix(name, ".js") || strings.HasSuffix(name, ".jsx") { return true } } return false } func dirExists(path string) bool { info, err := os.Stat(path) return err == nil && info.IsDir() } func samePath(a, b string) bool { if a == "" || b == "" { return false } absA, err := filepath.Abs(a) if err != nil { return false } absB, err := filepath.Abs(b) if err != nil { return false } return absA == absB } func normalizeDisplayLabel(label string) string { if label == "." { return "" } return label } func fileExists(path string) bool { info, err := os.Stat(path) return err == nil && !info.IsDir() } func prefixDisplayPath(prefix, path string) string { if prefix == "" || prefix == "." { return path } if path == "" { return prefix } return prefix + "/" + filepath.ToSlash(path) } func shortPluginLabel(path string) string { cleaned := filepath.Clean(path) base := filepath.Base(cleaned) if base == "." || base == string(filepath.Separator) || base == "" { return path } return base } func isPluginModuleRoot(root string) bool { modulePath, err := readModulePath(root) if err != nil { return fileExists(filepath.Join(root, "plugin.mod")) } return strings.Contains(modulePath, "/internal/plugins/") || fileExists(filepath.Join(root, "plugin.mod")) } func containsString(values []string, target string) bool { return slices.Contains(values, target) }