import { z } from 'zod';
import * as fileSystem from '../core/fileSystem';
import path from 'path';
import { createErrorResponse, ErrorCodes } from '../utils/errors';
/**
* Automation tools for bulk operations
*/
export const CreateFolderStructureInputSchema = z.object({
basePath: z.string(),
structure: z.record(z.any()),
});
export async function createFolderStructureTool(
input: z.infer<typeof CreateFolderStructureInputSchema>
) {
try {
await fileSystem.createDirectoryStructure(input.basePath, input.structure);
return {
content: [
{
type: 'text',
text: JSON.stringify({
success: true,
message: `Folder structure created at ${input.basePath}`,
}),
},
],
};
} catch (error) {
return {
content: [createErrorResponse(ErrorCodes.INTERNAL_ERROR, String(error))],
};
}
}
export const BulkRenameInputSchema = z.object({
directory: z.string(),
pattern: z.string(), // e.g., "file_*.txt"
prefix: z.string().optional(),
suffix: z.string().optional(),
});
export async function bulkRenameTool(input: z.infer<typeof BulkRenameInputSchema>) {
try {
const items = await fileSystem.listDirectory(input.directory, false);
const renamed: Array<{ old: string; new: string }> = [];
for (const item of items) {
// Simple pattern matching
if (item.name.includes(input.pattern.replace('*', ''))) {
let newName = item.name;
if (input.prefix) {
newName = input.prefix + newName;
}
if (input.suffix) {
const ext = path.extname(newName);
const base = path.basename(newName, ext);
newName = base + input.suffix + ext;
}
if (newName !== item.name) {
const oldPath = path.join(input.directory, item.name);
const newPath = path.join(input.directory, newName);
await fileSystem.moveFile(oldPath, newPath);
renamed.push({ old: item.name, new: newName });
}
}
}
return {
content: [
{
type: 'text',
text: JSON.stringify(
{ success: true, count: renamed.length, renamed },
null,
2
),
},
],
};
} catch (error) {
return {
content: [createErrorResponse(ErrorCodes.INTERNAL_ERROR, String(error))],
};
}
}
export const CleanupDesktopInputSchema = z.object({
desktopPath: z.string(),
});
export async function cleanupDesktopTool(input: z.infer<typeof CleanupDesktopInputSchema>) {
try {
const items = await fileSystem.listDirectory(input.desktopPath, false);
const organized: Array<{ file: string; movedTo: string }> = [];
// File type to folder mapping
const typeMap: Record<string, string[]> = {
'Documents': ['.pdf', '.doc', '.docx', '.txt', '.xlsx'],
'Images': ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg'],
'Videos': ['.mp4', '.mov', '.avi', '.mkv'],
'Archives': ['.zip', '.rar', '.7z', '.tar', '.gz'],
'Code': ['.js', '.ts', '.py', '.java', '.cpp', '.rs'],
};
for (const item of items) {
if (item.type === 'file') {
const ext = path.extname(item.name).toLowerCase();
for (const [folder, extensions] of Object.entries(typeMap)) {
if (extensions.includes(ext)) {
const folderPath = path.join(input.desktopPath, folder);
const newPath = path.join(folderPath, item.name);
await fileSystem.writeFileContents(folderPath, ''); // Create folder if needed
await fileSystem.moveFile(path.join(input.desktopPath, item.name), newPath);
organized.push({ file: item.name, movedTo: folder });
break;
}
}
}
}
return {
content: [
{
type: 'text',
text: JSON.stringify(
{
success: true,
count: organized.length,
organized,
},
null,
2
),
},
],
};
} catch (error) {
return {
content: [createErrorResponse(ErrorCodes.INTERNAL_ERROR, String(error))],
};
}
}