Skip to content

Commit 9749bb4

Browse files
authored
fix: list directory tool fixes (#473)
1 parent eb7ca74 commit 9749bb4

File tree

1 file changed

+44
-31
lines changed

1 file changed

+44
-31
lines changed

src/codegen/extensions/tools/file_operations.py

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
"""File operations for manipulating the codebase."""
22

3-
import os
43
from typing import Any, Literal
54

65
from codegen import Codebase
@@ -36,17 +35,31 @@ def view_file(codebase: Codebase, filepath: str) -> dict[str, Any]:
3635
def list_directory(codebase: Codebase, dirpath: str = "./", depth: int = 1) -> dict[str, Any]:
3736
"""List contents of a directory.
3837
39-
TODO(CG-10729): add support for directories that only including non-SourceFiles (code files). At the moment,
40-
only files and directories that have SourceFile objects are included.
41-
4238
Args:
4339
codebase: The codebase to operate on
4440
dirpath: Path to directory relative to workspace root
4541
depth: How deep to traverse the directory tree. Default is 1 (immediate children only).
4642
Use -1 for unlimited depth.
4743
44+
TODO(CG-10729): add support for directories that only including non-SourceFiles (code files). At the moment,
45+
only files and directories that have SourceFile objects are included.
46+
4847
Returns:
49-
Dict containing directory contents and metadata, or error information if directory not found
48+
Dict containing directory contents and metadata in a nested structure:
49+
{
50+
"path": str,
51+
"name": str,
52+
"files": list[str],
53+
"subdirectories": [
54+
{
55+
"path": str,
56+
"name": str,
57+
"files": list[str],
58+
"subdirectories": [...],
59+
},
60+
...
61+
]
62+
}
5063
"""
5164
try:
5265
directory = codebase.get_directory(dirpath)
@@ -56,33 +69,33 @@ def list_directory(codebase: Codebase, dirpath: str = "./", depth: int = 1) -> d
5669
if not directory:
5770
return {"error": f"Directory not found: {dirpath}"}
5871

59-
# Get immediate files
60-
files = []
61-
subdirs = []
62-
63-
for item in directory.items.values():
64-
if isinstance(item, Directory):
65-
subdirs.append(item.name)
66-
else:
67-
# Get full filename with extension from filepath
68-
files.append(os.path.basename(item.filepath))
69-
70-
# If depth > 1 or unlimited (-1), recursively get subdirectories
71-
if depth != 1:
72-
new_depth = depth - 1 if depth > 1 else -1
73-
for item in directory.items.values():
74-
if isinstance(item, Directory):
75-
subdir_result = list_directory(codebase, os.path.join(dirpath, item.name), depth=new_depth)
76-
if "error" not in subdir_result:
77-
files.extend(subdir_result["files"])
78-
subdirs.extend(subdir_result["subdirectories"])
72+
def get_directory_info(dir_obj: Directory, current_depth: int) -> dict[str, Any]:
73+
"""Helper function to get directory info recursively."""
74+
# Get direct files
75+
all_files = []
76+
for file in dir_obj.files:
77+
if file.directory == dir_obj:
78+
all_files.append(file.filepath.split("/")[-1])
79+
80+
# Get direct subdirectories
81+
subdirs = []
82+
for subdir in dir_obj.subdirectories:
83+
# Only include direct descendants
84+
if subdir.parent == dir_obj:
85+
if current_depth != 1:
86+
new_depth = current_depth - 1 if current_depth > 1 else -1
87+
subdirs.append(get_directory_info(subdir, new_depth))
88+
else:
89+
# At max depth, just include name
90+
subdirs.append(subdir.name)
91+
return {
92+
"name": dir_obj.name,
93+
"path": dir_obj.dirpath,
94+
"files": all_files,
95+
"subdirectories": subdirs,
96+
}
7997

80-
return {
81-
"path": str(directory.path), # Convert PosixPath to string
82-
"name": directory.name,
83-
"files": files,
84-
"subdirectories": subdirs,
85-
}
98+
return get_directory_info(directory, depth)
8699

87100

88101
def edit_file(codebase: Codebase, filepath: str, content: str) -> dict[str, Any]:

0 commit comments

Comments
 (0)