"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerFileTools = registerFileTools;
const sdk_1 = require("@lmstudio/sdk");
const zod_1 = require("zod");
const fileUtilities_1 = require("../fileUtilities");
const securityEnhanced_1 = require("../securityEnhanced");
const logger_1 = require("../logger");
async function registerFileTools() {
const tools = [];
tools.push((0, sdk_1.tool)({
name: "file_write",
description: "Write content to a file.",
parameters: {
path: zod_1.z.string().describe("File path to write to"),
content: zod_1.z.string().describe("Content to write"),
overwrite: zod_1.z.boolean().optional().describe("Overwrite if file exists (default: true)"),
create_dirs: zod_1.z.boolean().optional().describe("Create parent directories (default: true)"),
},
implementation: async ({ path: filePath, content, overwrite, create_dirs }) => {
try {
const validation = (0, securityEnhanced_1.validateWritePath)(filePath);
if (!validation.valid) {
return { success: false, path: filePath, error: validation.error };
}
const safePath = validation.sanitized;
const fs = require("fs");
const pathMod = require("path");
if (create_dirs !== false) {
const dir = pathMod.dirname(safePath);
if (!fs.existsSync(dir))
fs.mkdirSync(dir, { recursive: true });
}
if (overwrite === false && fs.existsSync(safePath)) {
return { success: false, path: safePath, error: "File already exists and overwrite is false" };
}
(0, fileUtilities_1.writeFileSync)(safePath, content);
const stats = (0, fileUtilities_1.getFileStats)(safePath);
return { success: true, path: safePath, size: stats.size };
}
catch (err) {
logger_1.logger.error('file_write failed', { error: err.message });
return { success: false, path: filePath, error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "read_file",
description: "Read the contents of a file.",
parameters: { path: zod_1.z.string().describe("File path to read") },
implementation: async ({ path: filePath }) => {
try {
const validation = (0, securityEnhanced_1.sanitizeFilePath)(filePath);
if (!validation.valid) {
return { success: false, content: "", error: validation.error };
}
const safePath = validation.sanitized;
const content = (0, fileUtilities_1.readFile)(safePath);
return { success: true, content };
}
catch (err) {
logger_1.logger.error('read_file failed', { error: err.message });
return { success: false, content: "", error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "file_diff",
description: "Compare two files.",
parameters: { file1: zod_1.z.string().describe("First file"), file2: zod_1.z.string().describe("Second file") },
implementation: async ({ file1, file2 }) => {
try {
const v1 = (0, securityEnhanced_1.sanitizeFilePath)(file1);
if (!v1.valid)
return { success: false, diff: "", error: `file1: ${v1.error}` };
const v2 = (0, securityEnhanced_1.sanitizeFilePath)(file2);
if (!v2.valid)
return { success: false, diff: "", error: `file2: ${v2.error}` };
const diff = (0, fileUtilities_1.diffFiles)(v1.sanitized, v2.sanitized);
const lines = diff.split("\n");
return { success: true, diff, diff_lines: lines.length, truncated: diff.length > 10000 };
}
catch (err) {
logger_1.logger.error('file_diff failed', { error: err.message });
return { success: false, diff: "", error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "file_checksum",
description: "Calculate file hash.",
parameters: { path: zod_1.z.string().describe("File path"), algorithm: zod_1.z.enum(["sha256", "md5"]).optional() },
implementation: async ({ path: filePath, algorithm }) => {
try {
const validation = (0, securityEnhanced_1.sanitizeFilePath)(filePath);
if (!validation.valid) {
return { success: false, checksum: "", error: validation.error };
}
const safePath = validation.sanitized;
const result = await require("../fileUtilities").fileChecksum(safePath, algorithm ?? "sha256");
return { success: true, checksum: result };
}
catch (err) {
logger_1.logger.error('file_checksum failed', { error: err.message });
return { success: false, checksum: "", error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "file_stats",
description: "Get file metadata.",
parameters: { path: zod_1.z.string().describe("File path") },
implementation: async ({ path: filePath }) => {
try {
const validation = (0, securityEnhanced_1.sanitizeFilePath)(filePath);
if (!validation.valid) {
return { success: false, stats: null, error: validation.error };
}
const safePath = validation.sanitized;
const stats = (0, fileUtilities_1.getFileStats)(safePath);
return { success: true, stats };
}
catch (err) {
logger_1.logger.error('file_stats failed', { error: err.message });
return { success: false, stats: null, error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "list_directory",
description: "List directory contents.",
parameters: {
path: zod_1.z.string().describe("Directory path"),
recursive: zod_1.z.boolean().optional().describe("Recursive"),
show_hidden: zod_1.z.boolean().optional().describe("Show hidden"),
max_entries: zod_1.z.number().optional().describe("Max entries"),
},
implementation: async ({ path: dirPath, recursive, show_hidden, max_entries }) => {
try {
const validation = (0, securityEnhanced_1.sanitizeFilePath)(dirPath);
if (!validation.valid) {
return { success: false, path: dirPath, entries: [], error: validation.error };
}
const safePath = validation.sanitized;
const entries = (0, fileUtilities_1.listDirectory)(safePath, { recursive: recursive ?? false })
.filter(e => show_hidden ? true : !e.name.startsWith('.'));
const total = entries.length;
const max = max_entries ?? 100;
if (max === 0) {
return {
success: true,
path: dirPath,
summary: true,
total_entries: total,
directories: entries.filter(e => e.isDirectory).length,
files: entries.filter(e => !e.isDirectory).length,
entries: []
};
}
const limited = entries.slice(0, max);
return {
success: true,
path: dirPath,
total_entries: total,
shown: limited.length,
truncated: total > max,
entries: limited
};
}
catch (err) {
logger_1.logger.error('list_directory failed', { error: err.message });
return { success: false, path: dirPath, entries: [], error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "create_directory",
description: "Create a directory.",
parameters: { path: zod_1.z.string().describe("Path"), recursive: zod_1.z.boolean().optional() },
implementation: async ({ path: dirPath, recursive }) => {
try {
const validation = (0, securityEnhanced_1.validateWritePath)(dirPath);
if (!validation.valid) {
return { success: false, path: dirPath, error: validation.error };
}
const safePath = validation.sanitized;
if (recursive === false) {
const fs = require("fs");
if (fs.existsSync(safePath) && !fs.statSync(safePath).isDirectory()) {
return { success: false, path: safePath, error: "Path exists and is not a directory" };
}
fs.mkdirSync(safePath);
}
else {
(0, fileUtilities_1.ensureDirectory)(safePath);
}
return { success: true, path: safePath };
}
catch (err) {
logger_1.logger.error('create_directory failed', { error: err.message });
return { success: false, path: dirPath, error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "delete_file",
description: "Delete file or directory.",
parameters: { path: zod_1.z.string().describe("Path"), recursive: zod_1.z.boolean().optional(), missing_ok: zod_1.z.boolean().optional() },
implementation: async ({ path: filePath, recursive, missing_ok }) => {
try {
const validation = (0, securityEnhanced_1.validateWritePath)(filePath);
if (!validation.valid) {
return { success: false, path: filePath, error: validation.error };
}
const safePath = validation.sanitized;
const fs = require("fs");
if (!fs.existsSync(safePath)) {
return missing_ok === true
? { success: true, path: safePath, deleted: false, message: "File not found" }
: { success: false, path: safePath, deleted: false, error: "File not found" };
}
const stat = fs.statSync(safePath);
if (stat.isDirectory()) {
fs.rmSync(safePath, { recursive: recursive ?? true, force: missing_ok === true });
}
else {
fs.unlinkSync(safePath);
}
return { success: true, path: safePath, deleted: true };
}
catch (err) {
logger_1.logger.error('delete_file failed', { error: err.message });
return { success: false, path: filePath, error: err.message };
}
},
}));
tools.push((0, sdk_1.tool)({
name: "delete_directory",
description: "Delete a directory.",
parameters: { path: zod_1.z.string().describe("Path"), recursive: zod_1.z.boolean().optional(), missing_ok: zod_1.z.boolean().optional() },
implementation: async ({ path: dirPath, recursive, missing_ok }) => {
try {
const validation = (0, securityEnhanced_1.validateWritePath)(dirPath);
if (!validation.valid) {
return { success: false, path: dirPath, error: validation.error };
}
const safePath = validation.sanitized;
const fs = require("fs");
if (!fs.existsSync(safePath)) {
return { success: true, path: safePath, deleted: false, message: "Directory not found" };
}
fs.rmSync(safePath, { recursive: recursive ?? true, force: missing_ok === true });
return { success: true, path: safePath, deleted: true };
}
catch (err) {
logger_1.logger.error('delete_directory failed', { error: err.message });
return { success: false, path: dirPath, error: err.message };
}
},
}));
return tools;
}
//# sourceMappingURL=file_tools.js.map