{"version":3,"file":"write.d.ts","sourceRoot":"","sources":["../../../src/core/tools/write.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAMtD,QAAA,MAAM,WAAW;;;EAGf,CAAC;AAEH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,WAAW,CAAC,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,8BAA8B;IAC9B,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,qCAAqC;IACrC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAOD,MAAM,WAAW,gBAAgB;IAChC,oEAAoE;IACpE,UAAU,CAAC,EAAE,eAAe,CAAC;CAC7B;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC,OAAO,WAAW,CAAC,CAsFtG;AAED,2EAA2E;AAC3E,eAAO,MAAM,SAAS;;;QAAiC,CAAC","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport { mkdir as fsMkdir, writeFile as fsWriteFile } from \"fs/promises\";\nimport { dirname } from \"path\";\nimport { withFileMutationQueue } from \"./file-mutation-queue.js\";\nimport { resolveToCwd } from \"./path-utils.js\";\n\nconst writeSchema = Type.Object({\n\tpath: Type.String({ description: \"Path to the file to write (relative or absolute)\" }),\n\tcontent: Type.String({ description: \"Content to write to the file\" }),\n});\n\nexport type WriteToolInput = Static;\n\n/**\n * Pluggable operations for the write tool.\n * Override these to delegate file writing to remote systems (e.g., SSH).\n */\nexport interface WriteOperations {\n\t/** Write content to a file */\n\twriteFile: (absolutePath: string, content: string) => Promise;\n\t/** Create directory (recursively) */\n\tmkdir: (dir: string) => Promise;\n}\n\nconst defaultWriteOperations: WriteOperations = {\n\twriteFile: (path, content) => fsWriteFile(path, content, \"utf-8\"),\n\tmkdir: (dir) => fsMkdir(dir, { recursive: true }).then(() => {}),\n};\n\nexport interface WriteToolOptions {\n\t/** Custom operations for file writing. Default: local filesystem */\n\toperations?: WriteOperations;\n}\n\nexport function createWriteTool(cwd: string, options?: WriteToolOptions): AgentTool {\n\tconst ops = options?.operations ?? defaultWriteOperations;\n\n\treturn {\n\t\tname: \"write\",\n\t\tlabel: \"write\",\n\t\tdescription:\n\t\t\t\"Write content to a file. Creates the file if it doesn't exist, overwrites if it does. Automatically creates parent directories.\",\n\t\tparameters: writeSchema,\n\t\texecute: async (\n\t\t\t_toolCallId: string,\n\t\t\t{ path, content }: { path: string; content: string },\n\t\t\tsignal?: AbortSignal,\n\t\t) => {\n\t\t\tconst absolutePath = resolveToCwd(path, cwd);\n\t\t\tconst dir = dirname(absolutePath);\n\n\t\t\treturn withFileMutationQueue(\n\t\t\t\tabsolutePath,\n\t\t\t\t() =>\n\t\t\t\t\tnew Promise<{ content: Array<{ type: \"text\"; text: string }>; details: undefined }>(\n\t\t\t\t\t\t(resolve, reject) => {\n\t\t\t\t\t\t\t// Check if already aborted\n\t\t\t\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tlet aborted = false;\n\n\t\t\t\t\t\t\t// Set up abort handler\n\t\t\t\t\t\t\tconst onAbort = () => {\n\t\t\t\t\t\t\t\taborted = true;\n\t\t\t\t\t\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Perform the write operation\n\t\t\t\t\t\t\t(async () => {\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t// Create parent directories if needed\n\t\t\t\t\t\t\t\t\tawait ops.mkdir(dir);\n\n\t\t\t\t\t\t\t\t\t// Check if aborted before writing\n\t\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Write the file\n\t\t\t\t\t\t\t\t\tawait ops.writeFile(absolutePath, content);\n\n\t\t\t\t\t\t\t\t\t// Check if aborted after writing\n\t\t\t\t\t\t\t\t\tif (aborted) {\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Clean up abort handler\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tresolve({\n\t\t\t\t\t\t\t\t\t\tcontent: [\n\t\t\t\t\t\t\t\t\t\t\t{ type: \"text\", text: `Successfully wrote ${content.length} bytes to ${path}` },\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\tdetails: undefined,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t} catch (error: any) {\n\t\t\t\t\t\t\t\t\t// Clean up abort handler\n\t\t\t\t\t\t\t\t\tif (signal) {\n\t\t\t\t\t\t\t\t\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (!aborted) {\n\t\t\t\t\t\t\t\t\t\treject(error);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})();\n\t\t\t\t\t\t},\n\t\t\t\t\t),\n\t\t\t);\n\t\t},\n\t};\n}\n\n/** Default write tool using process.cwd() - for backwards compatibility */\nexport const writeTool = createWriteTool(process.cwd());\n"]}