From ccbc632dd37498cc1c751924d9652e0cd53457d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=AF=E5=9F=BA=E9=AD=81?= <1412414664@qq.com> Date: Wed, 8 Jul 2026 03:04:07 +0800 Subject: [PATCH] fix: avoid Bun file IO in morph edit --- index.test.ts | 8 ++++++++ index.ts | 35 +++++++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/index.test.ts b/index.test.ts index 7c5b2d0..a7934d7 100644 --- a/index.test.ts +++ b/index.test.ts @@ -1089,6 +1089,14 @@ describe("ToolContext path resolution", () => { rmSync(tempRoot, { recursive: true, force: true }); } }); + + test("morph_edit file IO avoids Bun runtime globals", () => { + const source = readFileSync(join(import.meta.dir, "index.ts"), "utf-8"); + + expect(source).toContain('from "node:fs/promises"'); + expect(source).not.toContain("Bun.file"); + expect(source).not.toContain("Bun.write"); + }); }); describe("formatWarpGrepResult edge cases", () => { diff --git a/index.ts b/index.ts index 0355fae..05edaef 100644 --- a/index.ts +++ b/index.ts @@ -11,6 +11,7 @@ import { type Plugin, tool } from "@opencode-ai/plugin"; import { MorphClient, WarpGrepClient, CompactClient } from "@morphllm/morphsdk"; import type { WarpGrepResult, CompactResult } from "@morphllm/morphsdk"; import type { Part, TextPart, ToolPart, Message } from "@opencode-ai/sdk"; +import { readFile, writeFile } from "node:fs/promises"; import { isAbsolute, resolve as resolvePath } from "node:path"; // API key from MORPH_API_KEY env var, or the `morph.apiKey` field in @@ -369,6 +370,14 @@ function resolveSessionFilepath( : resolvePath(sessionDirectory, targetFilepath); } +function isFileNotFoundError(error: unknown): boolean { + return ( + error instanceof Error && + "code" in error && + (error as { code?: string }).code === "ENOENT" + ); +} + function resolveSessionRepoRoot( sessionDirectory: string, sessionWorktree: string, @@ -952,19 +961,25 @@ Alternatively, use the native 'edit' tool for this change.`; // Read the original file let originalCode: string; try { - const file = Bun.file(filepath); - if (!(await file.exists())) { - if (!normalizedCodeEdit.includes(EXISTING_CODE_MARKER)) { - await Bun.write(filepath, normalizedCodeEdit); - return `Created new file: ${target_filepath}\n\nLines: ${normalizedCodeEdit.split("\n").length}`; - } - return `Error: File not found: ${target_filepath} + originalCode = await readFile(filepath, "utf8"); + } catch (err) { + if (isFileNotFoundError(err)) { + if (normalizedCodeEdit.includes(EXISTING_CODE_MARKER)) { + return `Error: File not found: ${target_filepath} The file doesn't exist and the code_edit contains lazy markers. For new files, provide the complete content without "${EXISTING_CODE_MARKER}" markers.`; + } + + try { + await writeFile(filepath, normalizedCodeEdit, "utf8"); + } catch (writeErr) { + const error = writeErr as Error; + return `Error writing file ${target_filepath}: ${error.message}`; + } + return `Created new file: ${target_filepath}\n\nLines: ${normalizedCodeEdit.split("\n").length}`; } - originalCode = await file.text(); - } catch (err) { + const error = err as Error; return `Error reading file ${target_filepath}: ${error.message}`; } @@ -1072,7 +1087,7 @@ Options: // Write the merged result try { - await Bun.write(filepath, mergedCode); + await writeFile(filepath, mergedCode, "utf8"); } catch (err) { const error = err as Error; return `Error writing file ${target_filepath}: ${error.message}`;