-- Write text to a file, creating parent directories as needed. Pi-style -- terse description because every byte of every tool description rides -- in the system prompt on every turn. local uv = require("luv") -- mkdir -p equivalent: walk the path components and create each. -- Ignores EEXIST so the call is idempotent. local function mkdir_p(path) if path == "" or path == "." or path == "/" then return true end local parts = {} for piece in string.gmatch(path, "[^/]+") do parts[#parts + 1] = piece end local cur = (path:sub(1, 1) == "/") and "" or "." for _, piece in ipairs(parts) do cur = cur .. "/" .. piece local ok, err, name = uv.fs_mkdir(cur, tonumber("755", 8)) if not ok and name ~= "EEXIST" then return nil, err end end return true end -- Return the dirname of `path`, or nil if there isn't one (basename only). local function dirname(path) local slash = path:find("/[^/]*$") if not slash or slash == 1 then return nil end return path:sub(1, slash - 1) end return { name = "write", description = "Save content to a path. Overwrites existing files; missing parent directories are created automatically.", schema = { type = "object", properties = { path = { type = "string", description = "Path to the file (relative or absolute)." }, content = { type = "string", description = "Exact bytes to write. No newline is added." }, }, required = { "path", "content" }, }, handler = function(input) local path = input.path local content = input.content if type(path) ~= "string" or path == "" then return "Error: `path` must be a non-empty string." end if type(content) ~= "string" then return "Error: `content` must be a string." end local parent = dirname(path) if parent then local ok, err = mkdir_p(parent) if not ok then return "Error: could not create parent directory " .. parent .. ": " .. tostring(err) end end local f, open_err = io.open(path, "wb") if not f then return "Error: " .. (open_err or ("could not open " .. path .. " for writing")) end local ok, write_err = f:write(content) if not ok then f:close() return "Error: write failed: " .. tostring(write_err) end local close_ok, close_err = f:close() if not close_ok then return "Error: close failed: " .. tostring(close_err) end return string.format("Wrote %d bytes to %s.", #content, path) end, }