Skip to content
Merged
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
49 changes: 49 additions & 0 deletions src/mcp_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2427,6 +2427,27 @@ impl AgentflareMcp {
)),
}
}

/// Rejects PR titles that don't start with a conventional-commit type,
/// mirroring `.github/workflows/pr-title.yml`'s
/// `amannn/action-semantic-pull-request` config so the check fires here
/// instead of only after push+PR-open. Keep this type list in sync with
/// that workflow file if it changes.
fn validate_conventional_pr_title(title: &str) -> Result<(), String> {
const TYPES: &[&str] = &[
"feat", "fix", "docs", "perf", "refactor", "style", "test", "chore", "ci",
];
let pattern = format!(r"^(?:{})(?:\([^)]+\))?!?:\s", TYPES.join("|"));
let re = regex::Regex::new(&pattern).expect("valid conventional-commit regex");
if re.is_match(title) {
Comment on lines +2440 to +2442

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the validation logic and nearby tests in src/mcp_server.rs.
sed -n '2428,2488p' src/mcp_server.rs
printf '\n--- TESTS ---\n'
sed -n '3590,3635p' src/mcp_server.rs

Repository: getappz/agentflare

Length of output: 4835


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for other title-validation tests and the exact regex usage.
grep -n "conventional-commit\|feat: \|TYPES.join" -n src/mcp_server.rs

Repository: getappz/agentflare

Length of output: 606


Require a non-empty PR title description. feat: still passes this regex, so a title with no Conventional Commit description can slip through. Require a non-whitespace subject and add a regression test for the empty-description case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mcp_server.rs` around lines 2440 - 2442, Update the Conventional Commit
regex and validation around `re` so the title requires a non-empty,
non-whitespace subject after the type and optional scope/breaking marker; keep
valid descriptions accepted. Add a regression test covering an empty-description
title such as `feat: ` and assert that it is rejected.

Ok(())
} else {
Err(format!(
"PR title must start with a conventional-commit type ({}), e.g. \"chore: ...\" — got {title:?}",
TYPES.join(", ")
))
}
}
#[tool(
description = "GitHub repo management via the flare_git module. Single action-dispatch tool: action=pr_create|pr_list|pr_get|pr_merge|pr_comment|pr_request_review|issue_create|issue_list|issue_get|issue_comment|issue_close|issue_label|release_list|release_get|release_latest|release_create|run_list|run_get|run_rerun|workflow_dispatch. Uses gh/GITHUB_TOKEN credentials; repo defaults to the current repo's origin."
)]
Expand All @@ -2452,6 +2473,8 @@ impl AgentflareMcp {
.title
.as_deref()
.ok_or_else(|| ErrorData::invalid_params("title is required", None))?;
Self::validate_conventional_pr_title(title)
.map_err(|e| ErrorData::invalid_params(e, None))?;
Comment on lines +2476 to +2477

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Validate the title before repository and client setup.

Client::new() and repository resolution run before this validation. If either fails, an invalid PR title can return an unrelated setup error instead of ErrorData::invalid_params. Prevalidate pr_create titles before resolving the repo/client, then reuse the validated title in the action arm.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/mcp_server.rs` around lines 2476 - 2477, Move the pr_create title
validation using Self::validate_conventional_pr_title before repository
resolution and Client::new setup, so invalid titles immediately return
ErrorData::invalid_params. Store the validated title and reuse it in the
pr_create action arm instead of validating it again.

let head = req
.head
.as_deref()
Expand Down Expand Up @@ -3574,6 +3597,32 @@ mod tests {
assert_eq!(parse_flared_port(""), None);
}

#[test]
fn validate_conventional_pr_title_accepts_known_types_rejects_others() {
for good in [
"feat: add thing",
"fix(scope): bug",
"chore!: breaking rename",
"docs: update readme",
] {
assert!(
AgentflareMcp::validate_conventional_pr_title(good).is_ok(),
"expected {good:?} to pass"
);
}
for bad in [
"Add thing",
"Relicense repo from MIT to Apache-2.0",
"Feat: wrong case",
"unknown: not a real type",
] {
assert!(
AgentflareMcp::validate_conventional_pr_title(bad).is_err(),
"expected {bad:?} to fail"
);
}
}

#[test]
fn get_info_reports_agentflare_identity() {
let s = AgentflareMcp::default();
Expand Down
Loading