@@ -13,6 +13,7 @@ import os from 'os';
1313import { z } from "zod" ;
1414import { zodToJsonSchema } from "zod-to-json-schema" ;
1515import { diffLines , createTwoFilesPatch } from 'diff' ;
16+ import { minimatch } from 'minimatch' ;
1617
1718// Command line argument parsing
1819const args = process . argv . slice ( 2 ) ;
@@ -134,6 +135,7 @@ const MoveFileArgsSchema = z.object({
134135const SearchFilesArgsSchema = z . object ( {
135136 path : z . string ( ) ,
136137 pattern : z . string ( ) ,
138+ excludePatterns : z . array ( z . string ( ) ) . optional ( ) . default ( [ ] )
137139} ) ;
138140
139141const GetFileInfoArgsSchema = z . object ( {
@@ -183,6 +185,7 @@ async function getFileStats(filePath: string): Promise<FileInfo> {
183185async function searchFiles (
184186 rootPath : string ,
185187 pattern : string ,
188+ excludePatterns : string [ ] = [ ]
186189) : Promise < string [ ] > {
187190 const results : string [ ] = [ ] ;
188191
@@ -191,11 +194,22 @@ async function searchFiles(
191194
192195 for ( const entry of entries ) {
193196 const fullPath = path . join ( currentPath , entry . name ) ;
194-
197+
195198 try {
196199 // Validate each path before processing
197200 await validatePath ( fullPath ) ;
198201
202+ // Check if path matches any exclude pattern
203+ const relativePath = path . relative ( rootPath , fullPath ) ;
204+ const shouldExclude = excludePatterns . some ( pattern => {
205+ const globPattern = pattern . includes ( '*' ) ? pattern : `**/${ pattern } /**` ;
206+ return minimatch ( relativePath , globPattern , { dot : true } ) ;
207+ } ) ;
208+
209+ if ( shouldExclude ) {
210+ continue ;
211+ }
212+
199213 if ( entry . name . toLowerCase ( ) . includes ( pattern . toLowerCase ( ) ) ) {
200214 results . push ( fullPath ) ;
201215 }
@@ -522,7 +536,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
522536 throw new Error ( `Invalid arguments for search_files: ${ parsed . error } ` ) ;
523537 }
524538 const validPath = await validatePath ( parsed . data . path ) ;
525- const results = await searchFiles ( validPath , parsed . data . pattern ) ;
539+ const results = await searchFiles ( validPath , parsed . data . pattern , parsed . data . excludePatterns ) ;
526540 return {
527541 content : [ { type : "text" , text : results . length > 0 ? results . join ( "\n" ) : "No matches found" } ] ,
528542 } ;
@@ -544,9 +558,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
544558
545559 case "list_allowed_directories" : {
546560 return {
547- content : [ {
548- type : "text" ,
549- text : `Allowed directories:\n${ allowedDirectories . join ( '\n' ) } `
561+ content : [ {
562+ type : "text" ,
563+ text : `Allowed directories:\n${ allowedDirectories . join ( '\n' ) } `
550564 } ] ,
551565 } ;
552566 }
@@ -574,4 +588,4 @@ async function runServer() {
574588runServer ( ) . catch ( ( error ) => {
575589 console . error ( "Fatal error running server:" , error ) ;
576590 process . exit ( 1 ) ;
577- } ) ;
591+ } ) ;
0 commit comments