Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions detection/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ var SupportedToolsInMentions = []string{
"Nemotron",
"Salesforce Codegen",
"CodeWhisperer",
"Codebuff",
"Freebuff",
}

// KnownAgentBranchPrefixes maps branch name prefixes used by AI coding CLIs/agents
Expand All @@ -158,6 +160,8 @@ var KnownCoAuthorEmails = map[string]string{
"cursoragent@cursor.com": "Cursor",
"noreply@aider.chat": "Aider",
"copilot@github.com": "Copilot",
"noreply@codebuff.com": "Codebuff",
"noreply@freebuff.com": "Freebuff",
}

// CoAuthorPattern Regex to look for Co-Authored-By trailer with name and email
Expand All @@ -172,6 +176,15 @@ var AiderCommitPrefix = "aider:"
// ClaudeAttributionText
var ClaudeAttributionText = "Generated with Claude Code"

// CodebuffAttributionText commit message text added by Codebuff
var CodebuffAttributionText = "Generated with Codebuff"

// FreebuffAttributionText commit message text added by Freebuff
var FreebuffAttributionText = "Generated with Freebuff"

// FreebuffGeneratedWithPattern matches the Freebuff-style "Generated with: github.com/<user>/<repo>@<sha>" trailer
var FreebuffGeneratedWithPattern = regexp.MustCompile(`(?im)Generated with:\s+github\.com/[^/]+/[^@\s]*(?:codebuff|freebuff)[^@\s]*@[0-9a-f]+`)

// EntireIOTrailers List of EntireIO related trailers to check for
var EntireIOTrailers = []string{
"Entire-Metadata",
Expand Down
35 changes: 35 additions & 0 deletions detection/toolmention/toolmention_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,41 @@ func TestDetect(t *testing.T) {
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Codebuff mention",
input: detection.Input{Text: "Code in this PR was generated with Codebuff"},
wantTools: []string{"Codebuff"},
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Freebuff mention",
input: detection.Input{Text: "Written using Freebuff AI agent"},
wantTools: []string{"Freebuff"},
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Codebuff and Freebuff mention in commit message",
input: detection.Input{CommitMessage: "feat: implemented with Codebuff and Freebuff"},
wantTools: []string{"Codebuff", "Freebuff"},
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Codebuff and Freebuff case insensitive",
input: detection.Input{Text: "tested with CODEBUFF and freebuff"},
wantTools: []string{"Codebuff", "Freebuff"},
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Codebuff and Freebuff word boundary prevents partial match",
input: detection.Input{Text: "the codebuffering system and freebuffer cache"},
wantTools: nil,
wantScore: 20,
wantConfidence: detection.ConfidenceLow,
},
{
name: "Yi AI",
input: detection.Input{Text: "Test cases generated with Yi AI"},
Expand Down
21 changes: 21 additions & 0 deletions detection/trailer/trailer.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,27 @@ var commitMessagePatterns = []struct {
},
name: "Replit",
},
{
check: func(msg string) (float64, bool) {
if strings.Contains(msg, detection.CodebuffAttributionText) {
return detection.TrailerMatchBaseScore, true
}
return detection.TrailerNotMatchedScore, false
},
name: "Codebuff",
},
{
check: func(msg string) (float64, bool) {
if strings.Contains(msg, detection.FreebuffAttributionText) {
return detection.TrailerMatchBaseScore, true
}
if detection.FreebuffGeneratedWithPattern.MatchString(msg) {
return detection.TrailerMatchBaseScore, true
}
return detection.TrailerNotMatchedScore, false
},
name: "Freebuff",
},
}

type Detector struct {
Expand Down
64 changes: 64 additions & 0 deletions detection/trailer/trailer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,70 @@ Signed-off-by: some human <test@example.com>
wantScore: nil,
wantConfidence: nil,
},
{
name: "codebuff: Generated with Codebuff in commit message",
message: "fix: update handler\n\n🤖 Generated with Codebuff",
wantTools: []string{"Codebuff"},
wantModels: []string{""},
wantScore: []float64{35},
wantConfidence: []detection.Confidence{detection.ConfidenceMedium},
},
{
name: "codebuff: Generated with Codebuff (no emoji) in commit message",
message: "feat: add feature\n\nGenerated with Codebuff",
wantTools: []string{"Codebuff"},
wantModels: []string{""},
wantScore: []float64{35},
wantConfidence: []detection.Confidence{detection.ConfidenceMedium},
},
{
name: "codebuff: Co-Authored-By trailer with Codebuff email",
message: "fix: update handler\n\nCo-Authored-By: Codebuff <noreply@codebuff.com>",
wantTools: []string{"Codebuff"},
wantModels: []string{""},
wantScore: []float64{75},
wantConfidence: []detection.Confidence{detection.ConfidenceHigh},
},
{
name: "freebuff: Generated with Freebuff in commit message",
message: "fix: update handler\n\n🤖 Generated with Freebuff",
wantTools: []string{"Freebuff"},
wantModels: []string{""},
wantScore: []float64{35},
wantConfidence: []detection.Confidence{detection.ConfidenceMedium},
},
{
name: "freebuff: Generated with github.com URL with freebuff in repo name",
message: "feat: add feature\n\nGenerated with: github.com/LCHEROURI/cook-with-freebuff@08624f0b1b",
wantTools: []string{"Freebuff"},
wantModels: []string{""},
wantScore: []float64{35},
wantConfidence: []detection.Confidence{detection.ConfidenceMedium},
},
{
name: "freebuff: Generated with github.com URL with codebuff in repo name",
message: "feat: add feature\n\nGenerated with: github.com/LCHEROURI/cook-with-codebuff@08624f0b1b",
wantTools: []string{"Freebuff"},
wantModels: []string{""},
wantScore: []float64{35},
wantConfidence: []detection.Confidence{detection.ConfidenceMedium},
},
{
name: "freebuff: Co-Authored-By trailer with Freebuff email",
message: "fix: update handler\n\nCo-Authored-By: Freebuff <noreply@freebuff.com>",
wantTools: []string{"Freebuff"},
wantModels: []string{""},
wantScore: []float64{75},
wantConfidence: []detection.Confidence{detection.ConfidenceHigh},
},
{
name: "freebuff: unrelated repo URL does not match Generated with pattern",
message: "check out https://github.com/example/freebuff for docs",
wantTools: nil,
wantModels: nil,
wantScore: nil,
wantConfidence: nil,
},
{
name: "aider in middle of message not prefix",
message: "fix the aider: integration test",
Expand Down