Skip to content

Commit ccbc632

Browse files
committed
fix: avoid Bun file IO in morph edit
1 parent 3e5ea87 commit ccbc632

2 files changed

Lines changed: 33 additions & 10 deletions

File tree

index.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,6 +1089,14 @@ describe("ToolContext path resolution", () => {
10891089
rmSync(tempRoot, { recursive: true, force: true });
10901090
}
10911091
});
1092+
1093+
test("morph_edit file IO avoids Bun runtime globals", () => {
1094+
const source = readFileSync(join(import.meta.dir, "index.ts"), "utf-8");
1095+
1096+
expect(source).toContain('from "node:fs/promises"');
1097+
expect(source).not.toContain("Bun.file");
1098+
expect(source).not.toContain("Bun.write");
1099+
});
10921100
});
10931101

10941102
describe("formatWarpGrepResult edge cases", () => {

index.ts

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { type Plugin, tool } from "@opencode-ai/plugin";
1111
import { MorphClient, WarpGrepClient, CompactClient } from "@morphllm/morphsdk";
1212
import type { WarpGrepResult, CompactResult } from "@morphllm/morphsdk";
1313
import type { Part, TextPart, ToolPart, Message } from "@opencode-ai/sdk";
14+
import { readFile, writeFile } from "node:fs/promises";
1415
import { isAbsolute, resolve as resolvePath } from "node:path";
1516

1617
// API key from MORPH_API_KEY env var, or the `morph.apiKey` field in
@@ -369,6 +370,14 @@ function resolveSessionFilepath(
369370
: resolvePath(sessionDirectory, targetFilepath);
370371
}
371372

373+
function isFileNotFoundError(error: unknown): boolean {
374+
return (
375+
error instanceof Error &&
376+
"code" in error &&
377+
(error as { code?: string }).code === "ENOENT"
378+
);
379+
}
380+
372381
function resolveSessionRepoRoot(
373382
sessionDirectory: string,
374383
sessionWorktree: string,
@@ -952,19 +961,25 @@ Alternatively, use the native 'edit' tool for this change.`;
952961
// Read the original file
953962
let originalCode: string;
954963
try {
955-
const file = Bun.file(filepath);
956-
if (!(await file.exists())) {
957-
if (!normalizedCodeEdit.includes(EXISTING_CODE_MARKER)) {
958-
await Bun.write(filepath, normalizedCodeEdit);
959-
return `Created new file: ${target_filepath}\n\nLines: ${normalizedCodeEdit.split("\n").length}`;
960-
}
961-
return `Error: File not found: ${target_filepath}
964+
originalCode = await readFile(filepath, "utf8");
965+
} catch (err) {
966+
if (isFileNotFoundError(err)) {
967+
if (normalizedCodeEdit.includes(EXISTING_CODE_MARKER)) {
968+
return `Error: File not found: ${target_filepath}
962969
963970
The file doesn't exist and the code_edit contains lazy markers.
964971
For new files, provide the complete content without "${EXISTING_CODE_MARKER}" markers.`;
972+
}
973+
974+
try {
975+
await writeFile(filepath, normalizedCodeEdit, "utf8");
976+
} catch (writeErr) {
977+
const error = writeErr as Error;
978+
return `Error writing file ${target_filepath}: ${error.message}`;
979+
}
980+
return `Created new file: ${target_filepath}\n\nLines: ${normalizedCodeEdit.split("\n").length}`;
965981
}
966-
originalCode = await file.text();
967-
} catch (err) {
982+
968983
const error = err as Error;
969984
return `Error reading file ${target_filepath}: ${error.message}`;
970985
}
@@ -1072,7 +1087,7 @@ Options:
10721087

10731088
// Write the merged result
10741089
try {
1075-
await Bun.write(filepath, mergedCode);
1090+
await writeFile(filepath, mergedCode, "utf8");
10761091
} catch (err) {
10771092
const error = err as Error;
10781093
return `Error writing file ${target_filepath}: ${error.message}`;

0 commit comments

Comments
 (0)