import { defer } from "@/util/defer" import { existsSync } from "node:fs" import { rm } from "node:fs/promises" import { tmpdir } from "node:os" import { join } from "node:path" import { CliRenderer } from "@opentui/core" import { Filesystem } from "@/util/filesystem" import { Process } from "@/util/process" export async function open(opts: { value: string; renderer: CliRenderer; cwd?: string }): Promise { const editor = process.env["VISUAL"] || process.env["EDITOR"] if (!editor) return const filepath = join(tmpdir(), `${Date.now()}.md`) await using _ = defer(async () => rm(filepath, { force: true })) // In attach mode the server's project directory may not exist locally. // Fall back to the local process cwd so the editor can still spawn. const cwd = opts.cwd && existsSync(opts.cwd) ? opts.cwd : process.cwd() await Filesystem.write(filepath, opts.value) opts.renderer.suspend() opts.renderer.currentRenderBuffer.clear() try { const parts = editor.split(" ") const proc = Process.spawn([...parts, filepath], { cwd, stdin: "inherit", stdout: "inherit", stderr: "inherit", shell: process.platform === "win32", }) await proc.exited const content = await Filesystem.readText(filepath) return content || undefined } finally { opts.renderer.currentRenderBuffer.clear() opts.renderer.resume() opts.renderer.requestRender() } } export * as Editor from "./editor"