write.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import { z } from "zod"
  2. import * as path from "path"
  3. import { Tool } from "./tool"
  4. import { FileTimes } from "./util/file-times"
  5. import { LSP } from "../lsp"
  6. import { Permission } from "../permission"
  7. import DESCRIPTION from "./write.txt"
  8. export const WriteTool = Tool.define({
  9. id: "opencode.write",
  10. description: DESCRIPTION,
  11. parameters: z.object({
  12. filePath: z
  13. .string()
  14. .describe(
  15. "The absolute path to the file to write (must be absolute, not relative)",
  16. ),
  17. content: z.string().describe("The content to write to the file"),
  18. }),
  19. async execute(params, ctx) {
  20. const filepath = path.isAbsolute(params.filePath)
  21. ? params.filePath
  22. : path.join(process.cwd(), params.filePath)
  23. const file = Bun.file(filepath)
  24. const exists = await file.exists()
  25. if (exists) await FileTimes.assert(ctx.sessionID, filepath)
  26. await Permission.ask({
  27. id: "opencode.write",
  28. sessionID: ctx.sessionID,
  29. title: exists
  30. ? "Overwrite this file: " + filepath
  31. : "Create new file: " + filepath,
  32. metadata: {
  33. filePath: filepath,
  34. content: params.content,
  35. exists,
  36. },
  37. })
  38. await Bun.write(filepath, params.content)
  39. FileTimes.read(ctx.sessionID, filepath)
  40. let output = ""
  41. await LSP.file(filepath)
  42. const diagnostics = await LSP.diagnostics()
  43. for (const [file, issues] of Object.entries(diagnostics)) {
  44. if (issues.length === 0) continue
  45. if (file === filepath) {
  46. output += `\nThis file has errors, please fix\n<file_diagnostics>\n${issues.map(LSP.Diagnostic.pretty).join("\n")}\n</file_diagnostics>\n`
  47. continue
  48. }
  49. output += `\n<project_diagnostics>\n${file}\n${issues.map(LSP.Diagnostic.pretty).join("\n")}\n</project_diagnostics>\n`
  50. }
  51. return {
  52. metadata: {
  53. diagnostics,
  54. filepath,
  55. exists: exists,
  56. },
  57. output,
  58. }
  59. },
  60. })