From 32bb56ef3f12f1b341e338c18ee8043751beb1e7 Mon Sep 17 00:00:00 2001 From: Martin Vogel Date: Tue, 19 May 2026 23:43:42 +0200 Subject: [PATCH] fix(mcp): force grep filename prefix in scoped search_code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build_grep_cmd's POSIX scoped path uses xargs to pass indexed files to grep. When xargs supplies a single file, BSD/GNU grep omit the filename from output by default (only added with multiple files), yielding 'linenum:content' instead of the 'path:linenum:content' that collect_grep_matches requires — matches were silently discarded and search_code returned zero results. Add -H so grep always prefixes the filename regardless of file count. Harmless for the common multi-file case (output is unchanged), fixes the single-indexed-file edge case exposed by the search_code_multi_word test fixture. --- src/mcp/mcp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mcp/mcp.c b/src/mcp/mcp.c index 434446488..03e33d584 100644 --- a/src/mcp/mcp.c +++ b/src/mcp/mcp.c @@ -3013,10 +3013,10 @@ static void build_grep_cmd(char *cmd, size_t cmd_sz, bool use_regex, bool scoped const char *flag = use_regex ? "-E" : "-F"; if (scoped) { if (file_pattern) { - snprintf(cmd, cmd_sz, "xargs grep -n %s --include='%s' -f '%s' < '%s' 2>/dev/null", + snprintf(cmd, cmd_sz, "xargs grep -Hn %s --include='%s' -f '%s' < '%s' 2>/dev/null", flag, file_pattern, tmpfile, filelist); } else { - snprintf(cmd, cmd_sz, "xargs grep -n %s -f '%s' < '%s' 2>/dev/null", flag, tmpfile, + snprintf(cmd, cmd_sz, "xargs grep -Hn %s -f '%s' < '%s' 2>/dev/null", flag, tmpfile, filelist); } } else {