File tree Expand file tree Collapse file tree 1 file changed +27
-0
lines changed
packages/angular/cli/src/commands/mcp/tools Expand file tree Collapse file tree 1 file changed +27
-0
lines changed Original file line number Diff line number Diff 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+
547572async 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
You can’t perform that action at this time.
0 commit comments