capsule-ai-cli
Version:
The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing
99 lines • 3.4 kB
JavaScript
import { readdir } from 'fs/promises';
import path from 'path';
import { BaseTool } from '../base.js';
export class FileListTool extends BaseTool {
name = 'file_list';
displayName = '📁 List Files';
description = 'Explore directory structure. Use when you need to see what files exist before reading/editing them.';
category = 'file';
icon = '📁';
parameters = [
{
name: 'path',
type: 'string',
description: 'Path to list (default: current directory)',
default: '.'
},
{
name: 'recursive',
type: 'boolean',
description: 'List files recursively',
default: false
}
];
permissions = {
fileSystem: 'read'
};
ui = {
showProgress: false,
collapsible: true,
dangerous: false
};
async run(params, context) {
const { path: dirPath = '.', recursive = false } = params;
const resolvedPath = path.isAbsolute(dirPath)
? dirPath
: path.join(context.workingDirectory || process.cwd(), dirPath);
this.reportProgress(context, `Listing files in: ${resolvedPath}`);
try {
if (recursive) {
const files = await this.listRecursive(resolvedPath);
return {
path: resolvedPath,
type: 'recursive',
files,
count: files.length
};
}
else {
const entries = await readdir(resolvedPath, { withFileTypes: true });
const files = entries
.filter(entry => entry.isFile())
.map(entry => entry.name)
.sort();
const directories = entries
.filter(entry => entry.isDirectory())
.map(entry => entry.name + '/')
.sort();
return {
path: resolvedPath,
type: 'flat',
directories,
files,
total: entries.length
};
}
}
catch (error) {
if (error.code === 'ENOENT') {
throw new Error(`Directory not found: ${resolvedPath}`);
}
else if (error.code === 'EACCES') {
throw new Error(`Permission denied: ${resolvedPath}`);
}
else if (error.code === 'ENOTDIR') {
throw new Error(`Not a directory: ${resolvedPath}`);
}
throw error;
}
}
async listRecursive(dir, baseDir = dir) {
const entries = await readdir(dir, { withFileTypes: true });
const files = [];
for (const entry of entries) {
const fullPath = path.join(dir, entry.name);
const relativePath = path.relative(baseDir, fullPath);
if (entry.isDirectory()) {
if (entry.name === 'node_modules' || entry.name === '.git') {
continue;
}
files.push(...await this.listRecursive(fullPath, baseDir));
}
else {
files.push(relativePath);
}
}
return files.sort();
}
}
//# sourceMappingURL=file-list.js.map