@@ -8,67 +8,80 @@ class Tool(BaseTool):
88 SCHEMA = {
99 "type" : "function" ,
1010 "function" : {
11- "name" : "Ls " ,
12- "description" : "List files in a directory." ,
11+ "name" : "ls " ,
12+ "description" : "List files in a directory. Paths are relative to the project root. " ,
1313 "parameters" : {
1414 "type" : "object" ,
1515 "properties" : {
16- "directory " : {
16+ "path " : {
1717 "type" : "string" ,
18- "description" : "The directory to list." ,
19- },
18+ "description" : (
19+ "The path of the directory to list, relative to the project root. "
20+ "Defaults to the project root."
21+ ),
22+ "default" : "." ,
23+ }
2024 },
21- "required" : ["directory" ],
25+ "required" : [],
2226 },
2327 },
2428 }
2529
2630 @classmethod
27- def execute (cls , coder , dir_path = None , directory = None , ** kwargs ):
28- # Handle both positional and keyword arguments for backward compatibility
29- if dir_path is None and directory is not None :
30- dir_path = directory
31- elif dir_path is None :
32- return "Error: Missing directory parameter"
31+ def execute (cls , coder , path = None , directory = None , ** kwargs ):
3332 """
3433 List files in directory and optionally add some to context.
3534
3635 This provides information about the structure of the codebase,
3736 similar to how a developer would explore directories.
3837 """
38+ # Handle both positional and keyword arguments for backward compatibility
39+ dir_path = path or directory or "."
40+
3941 try :
40- # Make the path relative to root if it's absolute
41- if dir_path .startswith ("/" ):
42- rel_dir = os .path .relpath (dir_path , coder .root )
43- else :
44- rel_dir = dir_path
42+ # Create an absolute path from the provided relative path
43+ abs_path = os .path .abspath (os .path .join (coder .root , dir_path ))
4544
46- # Get absolute path
47- abs_dir = coder .abs_root_path (rel_dir )
45+ # Security check: ensure the resolved path is within the project root
46+ if not abs_path .startswith (os .path .abspath (coder .root )):
47+ coder .io .tool_error (
48+ f"Error: Path '{ dir_path } ' attempts to access files outside the project"
49+ " root."
50+ )
51+ return "Error: Path is outside the project root."
4852
4953 # Check if path exists
50- if not os .path .exists (abs_dir ):
51- coder .io .tool_output (f"⚠️ Directory '{ dir_path } ' not found" )
54+ if not os .path .exists (abs_path ):
55+ coder .io .tool_output (f"⚠️ Path '{ dir_path } ' not found" )
5256 return "Directory not found"
5357
5458 # Get directory contents
5559 contents = []
56- try :
57- with os .scandir (abs_dir ) as entries :
58- for entry in entries :
59- if entry .is_file () and not entry .name .startswith ("." ):
60- rel_path = os .path .join (rel_dir , entry .name )
61- contents .append (rel_path )
62- except NotADirectoryError :
63- # If it's a file, just return the file
64- contents = [rel_dir ]
60+ if os .path .isdir (abs_path ):
61+ # It's a directory, list its contents
62+ try :
63+ with os .scandir (abs_path ) as entries :
64+ for entry in entries :
65+ if entry .is_file () and not entry .name .startswith ("." ):
66+ rel_path = os .path .relpath (entry .path , coder .root )
67+ contents .append (rel_path )
68+ except OSError as e :
69+ coder .io .tool_error (f"Error listing directory '{ dir_path } ': { e } " )
70+ return f"Error: { e } "
71+ elif os .path .isfile (abs_path ):
72+ # It's a file, just return its relative path
73+ contents .append (os .path .relpath (abs_path , coder .root ))
6574
6675 if contents :
6776 coder .io .tool_output (f"📋 Listed { len (contents )} file(s) in '{ dir_path } '" )
68- if len (contents ) > 10 :
69- return f"Found { len (contents )} files: { ', ' .join (contents [:10 ])} ..."
77+ sorted_contents = sorted (contents )
78+ if len (sorted_contents ) > 10 :
79+ return (
80+ f"Found { len (sorted_contents )} files:"
81+ f" { ', ' .join (sorted_contents [:10 ])} ..."
82+ )
7083 else :
71- return f"Found { len (contents )} files: { ', ' .join (contents )} "
84+ return f"Found { len (sorted_contents )} files: { ', ' .join (sorted_contents )} "
7285 else :
7386 coder .io .tool_output (f"📋 No files found in '{ dir_path } '" )
7487 return "No files found in directory"
0 commit comments