Skip to content
Merged
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
10 changes: 10 additions & 0 deletions guards/github-guard/rust-guard/src/labels/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3478,6 +3478,11 @@ mod tests {
// response_items should label the PR from GraphQL format
let items = label_response_items("list_pull_requests", &tool_args, &response, &ctx);
assert_eq!(items.len(), 1, "Should find 1 PR in GraphQL response");
assert_eq!(
items[0].labels.description,
"pr:testorg/testrepo#1",
"PR without embedded repo should fall back to tool_args repo scope"
);
assert!(
items[0].labels.integrity.iter().any(|t| t == "approved" || t.starts_with("approved:")),
"Merged MEMBER PR should get approved integrity, got: {:?}",
Expand Down Expand Up @@ -3519,6 +3524,11 @@ mod tests {

let items = label_response_items("list_issues", &tool_args, &response, &ctx);
assert_eq!(items.len(), 1, "Should find 1 issue in GraphQL response");
assert_eq!(
items[0].labels.description,
"issue:testorg/testrepo#10",
"Issue without embedded repo should fall back to tool_args repo scope"
);

let paths = label_response_paths("list_issues", &tool_args, &response, &ctx);
assert!(paths.is_some(), "Should generate path labels for GraphQL issue response");
Expand Down
23 changes: 12 additions & 11 deletions guards/github-guard/rust-guard/src/labels/response_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use super::extract_mcp_response;
use super::helpers::*;
use crate::{LabeledItem, ResourceLabels, SharedLabels};
use serde_json::Value;
use std::borrow::Cow;

/// Label individual items in a response (fine-grained labeling)
/// This returns labeled items using the legacy format that works with MCP wrappers
Expand Down Expand Up @@ -147,6 +148,7 @@ pub fn label_response_items(
} else {
vec![]
};
let secrecy_shared: SharedLabels = secrecy.into();

for item in items_to_process.iter() {
let number = extract_resource_number(item, "pr", &arg_repo_full);
Expand Down Expand Up @@ -201,11 +203,10 @@ pub fn label_response_items(
labels: ResourceLabels {
description: format!("pr:{}#{}", repo_full_name, number),
secrecy: if tool_name == "search_pull_requests" {
repo_visibility_secrecy_for_repo_id(repo_full_name, ctx)
repo_visibility_secrecy_for_repo_id(repo_full_name, ctx).into()
} else {
secrecy.clone()
}
.into(),
secrecy_shared.clone()
},
integrity: integrity.into(),
},
});
Expand Down Expand Up @@ -261,13 +262,14 @@ pub fn label_response_items(
} else {
vec![]
};
let secrecy_shared: SharedLabels = secrecy.into();

for item in items_limited.iter().copied() {
let item_repo = extract_repo_from_item(item);
let repo_full_name = if item_repo.is_empty() {
default_repo_full_name.clone()
let repo_full_name: Cow<'_, str> = if item_repo.is_empty() {
Cow::Borrowed(default_repo_full_name.as_str())
} else {
item_repo
Cow::Owned(item_repo)
};

let repo_private = repo_visibility_private_for_repo_id(&repo_full_name)
Expand All @@ -285,11 +287,10 @@ pub fn label_response_items(
labels: ResourceLabels {
description: format!("issue:{}#{}", repo_full_name, number),
secrecy: if tool_name == "search_issues" {
repo_visibility_secrecy_for_repo_id(&repo_full_name, ctx)
repo_visibility_secrecy_for_repo_id(&repo_full_name, ctx).into()
} else {
secrecy.clone()
}
.into(),
secrecy_shared.clone()
},
integrity: integrity.into(),
},
});
Expand Down
Loading