8
8
import fnmatch
9
9
import json
10
10
import logging
11
+ import os
11
12
import threading
12
13
import time
13
- from typing import Dict , Any , Optional , Callable
14
+ import traceback
15
+ from typing import Dict , Any
14
16
from mcp .server .fastmcp import Context
15
17
16
18
from .base_service import BaseService
@@ -98,13 +100,14 @@ def find_files_by_pattern(self, pattern: str) -> Dict[str, Any]:
98
100
if not self .index_cache :
99
101
self ._index_project (self .base_path )
100
102
101
- # Search using current index
103
+ # Search using directory tree
102
104
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
+ )
108
111
109
112
# Return results - file watcher now handles all index updates proactively
110
113
return ResponseFormatter .file_list_response (
@@ -220,15 +223,13 @@ def run_sync_rebuild():
220
223
file_count = self ._index_project (self .base_path )
221
224
222
225
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 )
225
228
226
229
return True
227
230
228
231
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 )
232
233
self .logger .error ("Traceback: %s" , traceback .format_exc ())
233
234
return False
234
235
finally :
@@ -249,7 +250,7 @@ def on_complete(fut):
249
250
else :
250
251
self .logger .error ("Background rebuild failed" )
251
252
except Exception as e :
252
- self .logger .error (f "Background rebuild thread failed: { e } " )
253
+ self .logger .error ("Background rebuild thread failed: %s" , e )
253
254
254
255
future .add_done_callback (on_complete )
255
256
@@ -261,8 +262,7 @@ def on_complete(fut):
261
262
with self ._rebuild_lock :
262
263
self .is_rebuilding = False
263
264
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 )
266
266
self .logger .error ("Traceback: %s" , traceback .format_exc ())
267
267
return False
268
268
@@ -293,3 +293,40 @@ def get_rebuild_status(self) -> dict:
293
293
"is_rebuilding" : is_rebuilding ,
294
294
"index_cache_size" : len (self .index_cache .get ('files' , [])) if self .index_cache else 0
295
295
}
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