Skip to content

Commit 4e00c7f

Browse files
committed
refactor(@angular/cli): deduplicate search roots for MCP projects tool
Sorting by length ensures parent directories are processed before children, filtering out overlapping search trees.
1 parent f1ed025 commit 4e00c7f

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

packages/angular/cli/src/commands/mcp/tools/projects.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,31 @@ async function processConfigFile(
544544
}
545545
}
546546

547+
/**
548+
* Deduplicates overlapping search roots (e.g., if one is a child of another).
549+
* Sorting by length ensures parent directories are processed before children.
550+
* @param roots A list of normalized absolute paths used as search roots.
551+
* @returns A deduplicated list of search roots.
552+
*/
553+
function deduplicateSearchRoots(roots: string[]): string[] {
554+
const sortedRoots = [...roots].sort((a, b) => a.length - b.length);
555+
const deduplicated: string[] = [];
556+
557+
for (const root of sortedRoots) {
558+
const isSubdirectory = deduplicated.some((existing) => {
559+
const rel = relative(existing, root);
560+
561+
return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel));
562+
});
563+
564+
if (!isSubdirectory) {
565+
deduplicated.push(root);
566+
}
567+
}
568+
569+
return deduplicated;
570+
}
571+
547572
async function createListProjectsHandler({ server }: McpToolContext) {
548573
return async () => {
549574
const workspaces: WorkspaceData[] = [];
@@ -562,6 +587,8 @@ async function createListProjectsHandler({ server }: McpToolContext) {
562587
searchRoots = [process.cwd()];
563588
}
564589

590+
searchRoots = deduplicateSearchRoots(searchRoots);
591+
565592
// Pre-resolve allowed roots to handle their own symlinks or normalizations.
566593
// We ignore failures here; if a root is broken, we simply won't match against it.
567594
const realAllowedRoots = searchRoots

0 commit comments

Comments
 (0)