import { isAbsolute, relative, resolve, sep } from 'node:path';
import { createEditTool } from '../../tools/edit.js';
import { createGrepTool } from '../../tools/grep.js';
import { createReadTool } from '../../tools/read.js';
import { createWriteTool } from '../../tools/write.js';
/** True if `targetPath` resolves to `rootDir` or one of its descendants. */
function isWithinRoot(rootDir, targetPath) {
    const relativePath = relative(resolve(rootDir), resolve(targetPath));
    return (relativePath === '' ||
        (relativePath !== '..' && !relativePath.startsWith(`..${sep}`) && !isAbsolute(relativePath)));
}
/** Throw if `inputPath` is outside the durable-memory write root. */
function assertPathWithinRoot(rootDir, inputPath) {
    const absolutePath = resolve(rootDir, inputPath);
    if (!isWithinRoot(rootDir, absolutePath)) {
        throw new Error(`Path is outside durable-memory root: ${inputPath}`);
    }
}
/** Throw if `inputPath` is outside every allowed durable-memory read root. */
function assertPathWithinAnyRoot(roots, inputPath) {
    const absolutePath = resolve(roots[0], inputPath);
    if (!roots.some((root) => isWithinRoot(root, absolutePath))) {
        throw new Error(`Path is outside durable-memory read roots: ${inputPath}`);
    }
}
/** Attach durable-memory path-policy validation to an underlying file tool. */
function wrapScopedTool(tool, validate) {
    return {
        ...tool,
        execute: async (toolCallId, rawParams, signal, onUpdate, ctx) => {
            validate(rawParams);
            return tool.execute(toolCallId, rawParams, signal, onUpdate, ctx);
        }
    };
}
/** Build the path-scoped read/edit/write/grep tool set for the durable-memory agent. */
export function createDurableMemoryTools(rootDir, options = {}) {
    const readRoots = [rootDir, ...(options.readRoots ?? [])];
    const readTool = wrapScopedTool(createReadTool(rootDir), (params) => {
        assertPathWithinAnyRoot(readRoots, params.path);
    });
    const editTool = wrapScopedTool(createEditTool(rootDir), (params) => {
        assertPathWithinRoot(rootDir, params.path);
    });
    const writeTool = wrapScopedTool(createWriteTool(rootDir), (params) => {
        assertPathWithinRoot(rootDir, params.path);
    });
    const grepTool = wrapScopedTool(createGrepTool(rootDir), (params) => {
        if (params.path) {
            assertPathWithinAnyRoot(readRoots, params.path);
        }
    });
    return [readTool, editTool, writeTool, grepTool];
}
//# sourceMappingURL=memory-tools.js.map