Skip to content

fix(mcp): preserve multi_grep constraints and OR results - #739

Closed
Kh05ifr4nD wants to merge 2 commits into
dmtrKovalenko:mainfrom
Kh05ifr4nD:fix/mcp-multi-grep-constraints-minimal
Closed

fix(mcp): preserve multi_grep constraints and OR results#739
Kh05ifr4nD wants to merge 2 commits into
dmtrKovalenko:mainfrom
Kh05ifr4nD:fix/mcp-multi-grep-constraints-minimal

Conversation

@Kh05ifr4nD

Copy link
Copy Markdown

Closes #738

Root cause

multi_grep receives constraints separately from patterns, but the MCP implementation parsed a standalone positive path token with the single-token query path. That dropped positive directory and exact-file constraints. Its fallback also returned after the first pattern, so OR queries lost later pattern results.

Fix

  • Add an explicit parse_constraints parser entry point for independently supplied constraints. Ordinary parse semantics remain unchanged, while standalone paths and exact filenames stay constraints instead of becoming fuzzy text.
  • Aggregate fallback results as a deduplicated OR union, with independent per-pattern offsets and an opaque composite cursor for pagination.
  • Keep the existing formatter and native cursor behavior unchanged; the fallback only adds the state required to continue each pattern without losing results.

Verification

  • nix develop --command cargo test --workspace
  • nix develop --command cargo clippy -p fff-query-parser -p fff-mcp --all-targets -- -D warnings
  • nix develop --command cargo fmt --all -- --check
  • nix develop --command cargo build -p fff-mcp --release
  • Real release-stdio MCP harnesses covering positive directory/glob/exact-file constraints, negative controls, missing-pattern OR, fallback union/cursors, files_with_matches deduplication, and all output modes.

All checks passed on commit affbdaadd640387a3e4976faaba75c1c88efe923.

let parsed_constraints = parser.parse(constraint_query);
let constraints = parsed_constraints.constraints.as_slice();
if !is_multi_cursor {
let parsed_constraints = parser.parse_constraints(&constraint_query);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I am not sure this whole situation with demote_lone_constraints is needed cause we never ever want to consider a pattern AI submits to the query field as a constraint, please remove this

..fallback_options
let mut cursor = multi_cursor
.unwrap_or_else(|| MultiGrepCursor::new(patterns.clone(), constraint_query.clone()));
let (fallback_options, _) = make_grep_options(output_mode, GrepMode::PlainText, 0, context);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I don't think we do have correct support for fallbacks for multi grep

],
);
let cases = [
(

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

make a struct for every case so it is more readable

use super::*;
use std::fs;
use std::sync::atomic::Ordering;
use tempfile::TempDir;

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

we already have a tempdir depenency no need in tempfile

/// Parse a query supplied as an independent set of search constraints.
/// Unlike ordinary single-token search, a lone path or filename remains a
/// constraint instead of being promoted to fuzzy text.
pub fn parse_constraints<'a>(&self, query: &'a str) -> FFFQuery<'a> {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

I think this should be solved at the configuration level rather than as a boolean flag or maybe not, but i don't like this separation via flag

@Kh05ifr4nD

Copy link
Copy Markdown
Author

Superseded by #753. The replacement handles the standalone constraint field directly and removes the unsupported fallback.

@Kh05ifr4nD Kh05ifr4nD closed this Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: multi_grep drops standalone positive path constraints

2 participants