directory_tree base implementation

This commit is contained in:
Enrico Ballardini
2024-12-03 22:52:29 +01:00
parent a096c95e8e
commit deffdb94ac

View File

@@ -114,6 +114,10 @@ const ListDirectoryArgsSchema = z.object({
path: z.string(),
});
const DirectoryTreeArgsSchema = z.object({
path: z.string(),
});
const MoveFileArgsSchema = z.object({
source: z.string(),
destination: z.string(),
@@ -251,6 +255,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
"finding specific files within a directory. Only works within allowed directories.",
inputSchema: zodToJsonSchema(ListDirectoryArgsSchema) as ToolInput,
},
{
name: "directory_tree",
description:
"Get a recursive tree view of files and directories starting from a specified path. " +
"Results are formatted in a hierarchical ASCII tree structure with proper indentation " +
"using pipes and dashes (│ ├ └ ─). Files and directories are distinguished " +
"with [F] and [D] prefixes. This tool provides a comprehensive visualization of nested " +
"directory structures. Only works within allowed directories.",
inputSchema: zodToJsonSchema(DirectoryTreeArgsSchema) as ToolInput,
},
{
name: "move_file",
description:
@@ -373,6 +387,40 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
};
}
case "directory_tree": {
const parsed = ListDirectoryArgsSchema.safeParse(args);
if (!parsed.success) {
throw new Error(`Invalid arguments for directory_tree: ${parsed.error}`);
}
async function buildTree(currentPath: string, prefix = ""): Promise<string> {
const validPath = await validatePath(currentPath);
const entries = await fs.readdir(validPath, {withFileTypes: true});
let result = "";
for (let i = 0; i < entries.length; i++) {
const entry = entries[i];
const isLast = i === entries.length - 1;
const connector = isLast ? "└── " : "├── ";
const newPrefix = prefix + (isLast ? " " : "│ ");
result += `${prefix}${connector}${entry.isDirectory() ? "[D]" : "[F]"} ${entry.name}\n`;
if (entry.isDirectory()) {
const subPath = path.join(currentPath, entry.name);
result += await buildTree(subPath, newPrefix);
}
}
return result;
}
const treeOutput = await buildTree(parsed.data.path);
return {
content: [{type: "text", text: treeOutput}],
};
}
case "move_file": {
const parsed = MoveFileArgsSchema.safeParse(args);
if (!parsed.success) {