From 330065de49075105ef78a171d219c416d4c7daf2 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 12 Jul 2025 21:52:35 +0300 Subject: feat: add vibe-coded project detection to showcase MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add detection for "vibe code" mentions in README files - Display vibe-coded indicator in project summaries - Include vibe-coded count in overall statistics - Clarify that AI-assisted count includes vibe-coded projects - Bump version to 0.6.0 ๐Ÿค– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- internal/showcase/showcase.go | 50 ++++++++++++++++++++++++++++++++++++++----- internal/version/version.go | 2 +- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/internal/showcase/showcase.go b/internal/showcase/showcase.go index 32492a9..8c49b54 100644 --- a/internal/showcase/showcase.go +++ b/internal/showcase/showcase.go @@ -30,6 +30,7 @@ type ProjectSummary struct { CodeSnippet string // Code snippet to show when no images CodeLanguage string // Language and file info for the snippet AIAssisted bool // Whether AI was detected in the project + VibeCoded bool // Whether the project was vibe-coded } // LegacyRepoMetadata for backwards compatibility with old cache files @@ -276,8 +277,9 @@ func (g *Generator) generateProjectSummary(repoName string, forceRegenerate bool } } - // Check for AI assistance + // Check for AI assistance and vibe coding aiAssisted := detectAIUsage(repoPath) + vibeCoded := detectVibeCodedProject(repoPath) projectSummary := &ProjectSummary{ Name: repoName, @@ -289,6 +291,7 @@ func (g *Generator) generateProjectSummary(repoName string, forceRegenerate bool CodeSnippet: codeSnippet, CodeLanguage: codeLanguage, AIAssisted: aiAssisted, + VibeCoded: vibeCoded, } // Save to cache @@ -323,14 +326,18 @@ func (g *Generator) formatGemtext(summaries []ProjectSummary) string { totalLOC := 0 totalDocs := 0 aiAssistedCount := 0 + vibeCodedCount := 0 releasedCount := 0 languageTotals := make(map[string]int) docTotals := make(map[string]int) for _, summary := range summaries { - if summary.AIAssisted { + if summary.AIAssisted || summary.VibeCoded { aiAssistedCount++ } + if summary.VibeCoded { + vibeCodedCount++ + } if summary.Metadata != nil { totalCommits += summary.Metadata.CommitCount @@ -406,8 +413,13 @@ func (g *Generator) formatGemtext(summaries []ProjectSummary) string { if len(docStats) > 0 { builder.WriteString(fmt.Sprintf("* ๐Ÿ“š Documentation: %s\n", FormatLanguagesWithPercentages(docStats))) } + if vibeCodedCount > 0 { + builder.WriteString(fmt.Sprintf("* ๐ŸŽต Vibe-Coded Projects: %d out of %d (%.1f%%)\n", + vibeCodedCount, totalProjects, + float64(vibeCodedCount)*100/float64(totalProjects))) + } nonAICount := totalProjects - aiAssistedCount - builder.WriteString(fmt.Sprintf("* ๐Ÿค– AI-Assisted Projects: %d out of %d (%.1f%% AI-assisted, %.1f%% human-only)\n", + builder.WriteString(fmt.Sprintf("* ๐Ÿค– AI-Assisted Projects (including vibe-coded): %d out of %d (%.1f%% AI-assisted, %.1f%% human-only)\n", aiAssistedCount, totalProjects, float64(aiAssistedCount)*100/float64(totalProjects), float64(nonAICount)*100/float64(totalProjects))) @@ -457,8 +469,10 @@ func (g *Generator) formatGemtext(summaries []ProjectSummary) string { builder.WriteString("* ๐Ÿงช Status: Experimental (no releases yet)\n") } - // Add AI-Assisted notice if detected - if summary.AIAssisted { + // Add AI-Assisted or Vibe-Coded notice if detected + if summary.VibeCoded { + builder.WriteString("* ๐ŸŽต Vibe-Coded: This project has been vibe coded\n") + } else if summary.AIAssisted { builder.WriteString("* ๐Ÿค– AI-Assisted: This project was partially created with the help of generative AI\n") } @@ -713,6 +727,32 @@ func formatNumber(n int) string { return string(result) } +// detectVibeCodedProject checks if the repository mentions "vibe code" in README +func detectVibeCodedProject(repoPath string) bool { + // Check for "vibe code" in README files + readmeFiles := []string{ + "README.md", "readme.md", "Readme.md", + "README.MD", "README.txt", "readme.txt", + "README", "readme", + } + + for _, readmeFile := range readmeFiles { + filePath := filepath.Join(repoPath, readmeFile) + content, err := os.ReadFile(filePath) + if err != nil { + continue + } + + // Case-insensitive search for "vibe code" + lowerContent := strings.ToLower(string(content)) + if strings.Contains(lowerContent, "vibe code") { + return true + } + } + + return false +} + // detectAIUsage checks if the repository was generated with AI assistance func detectAIUsage(repoPath string) bool { // Check for AI-related files diff --git a/internal/version/version.go b/internal/version/version.go index 03181e4..5dcb8fb 100644 --- a/internal/version/version.go +++ b/internal/version/version.go @@ -7,7 +7,7 @@ import ( var ( // Version is the current version of gitsyncer - Version = "0.5.0" + Version = "0.6.0" // GitCommit is the git commit hash at build time GitCommit = "unknown" -- cgit v1.2.3