88import fnmatch
99import json
1010import logging
11+ import os
1112import threading
1213import time
13- from typing import Dict , Any , Optional , Callable
14+ import traceback
15+ from typing import Dict , Any
1416from mcp .server .fastmcp import Context
1517
1618from .base_service import BaseService
@@ -98,13 +100,14 @@ def find_files_by_pattern(self, pattern: str) -> Dict[str, Any]:
98100 if not self .index_cache :
99101 self ._index_project (self .base_path )
100102
101- # Search using current index
103+ # Search using directory tree
102104 matching_files = []
103- if self .index_cache and 'files' in self .index_cache :
104- for file_entry in self .index_cache ['files' ]:
105- file_path = file_entry .get ('path' , '' )
106- if fnmatch .fnmatch (file_path , pattern ):
107- matching_files .append (file_path )
105+ if self .index_cache and 'directory_tree' in self .index_cache :
106+ matching_files = self ._search_directory_tree (
107+ self .index_cache ['directory_tree' ],
108+ pattern ,
109+ ""
110+ )
108111
109112 # Return results - file watcher now handles all index updates proactively
110113 return ResponseFormatter .file_list_response (
@@ -220,15 +223,13 @@ def run_sync_rebuild():
220223 file_count = self ._index_project (self .base_path )
221224
222225 duration = time .time () - start_time
223- message = f "Background rebuild completed in { duration :.2f } s with { file_count } files"
224- self . logger . info ( message )
226+ self . logger . info ( "Background rebuild completed in %.2fs with %d files" ,
227+ duration , file_count )
225228
226229 return True
227230
228231 except Exception as e :
229- error_msg = f"Background rebuild failed: { e } "
230- self .logger .error (error_msg )
231- import traceback
232+ self .logger .error ("Background rebuild failed: %s" , e )
232233 self .logger .error ("Traceback: %s" , traceback .format_exc ())
233234 return False
234235 finally :
@@ -249,7 +250,7 @@ def on_complete(fut):
249250 else :
250251 self .logger .error ("Background rebuild failed" )
251252 except Exception as e :
252- self .logger .error (f "Background rebuild thread failed: { e } " )
253+ self .logger .error ("Background rebuild thread failed: %s" , e )
253254
254255 future .add_done_callback (on_complete )
255256
@@ -261,8 +262,7 @@ def on_complete(fut):
261262 with self ._rebuild_lock :
262263 self .is_rebuilding = False
263264
264- self .logger .error (f"Failed to start background rebuild: { e } " )
265- import traceback
265+ self .logger .error ("Failed to start background rebuild: %s" , e )
266266 self .logger .error ("Traceback: %s" , traceback .format_exc ())
267267 return False
268268
@@ -293,3 +293,40 @@ def get_rebuild_status(self) -> dict:
293293 "is_rebuilding" : is_rebuilding ,
294294 "index_cache_size" : len (self .index_cache .get ('files' , [])) if self .index_cache else 0
295295 }
296+
297+ def _search_directory_tree (self , tree : dict , pattern : str , current_path : str ) -> list :
298+ """
299+ Search files in directory tree using glob pattern.
300+
301+ Args:
302+ tree: Directory tree dictionary
303+ pattern: Glob pattern to match
304+ current_path: Current path being traversed
305+
306+ Returns:
307+ List of matching file paths
308+ """
309+ matching_files = []
310+
311+ for name , subtree in tree .items ():
312+ # Build the full path using forward slashes for consistency
313+ if current_path :
314+ full_path = f"{ current_path } /{ name } "
315+ else :
316+ full_path = name
317+
318+ if subtree is None :
319+ # This is a file
320+ # Try matching against full path
321+ if fnmatch .fnmatch (full_path , pattern ):
322+ matching_files .append (full_path )
323+ # Also try matching against just the filename
324+ elif fnmatch .fnmatch (name , pattern ):
325+ matching_files .append (full_path )
326+ else :
327+ # This is a directory, recurse into it
328+ matching_files .extend (
329+ self ._search_directory_tree (subtree , pattern , full_path )
330+ )
331+
332+ return matching_files
0 commit comments