Skip to content

Commit 4bcaab9

Browse files
authored
fix(init): remove JSON minification that breaks edit-based codemods (#719)
## Summary Removes JSON minification (`JSON.stringify(JSON.parse())`) from `readSingleFile` and `preReadCommonFiles`. This was causing all `package.json` edit-based codemods to fail. ### Root cause The server's codemod-planner agent saw minified JSON (all whitespace stripped) and generated `oldString`/`newString` edits based on it. But `applyEdits` reads the actual file from disk (pretty-printed with indentation). The fuzzy replacer chain can't bridge minified vs pretty-printed JSON — it's structurally too different. ### Evidence All three reference projects (opencode, gemini-cli, cline) read files **raw without any content transformation**. The model always sees exactly what's on disk. Our minification was an outlier that broke when we switched from full-content replacement to edit-based codemods. Fixes failures on node-express and remix test projects: ``` Applying changes failed after 4 attempts: Edit #1 failed on "package.json": Could not find oldString in the file. ``` ## Test plan - [x] All 68 local-ops tests pass - [x] Typecheck clean - [x] Lint clean Made with [Cursor](https://cursor.com)
1 parent ca16b2f commit 4bcaab9

1 file changed

Lines changed: 1 addition & 17 deletions

File tree

src/lib/init/local-ops.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -80,15 +80,6 @@ function prettyPrintJson(content: string, indent: JsonIndent): string {
8080
}
8181
}
8282

83-
/** Strip whitespace/formatting from JSON. Returns input unchanged if not valid JSON. */
84-
function minifyJson(content: string): string {
85-
try {
86-
return JSON.stringify(JSON.parse(content));
87-
} catch {
88-
return content;
89-
}
90-
}
91-
9283
/**
9384
* Patterns that indicate shell injection. Commands run via `spawn` (no shell),
9485
* so these have no runtime effect — they are defense-in-depth against command
@@ -400,10 +391,7 @@ export async function preReadCommonFiles(
400391
if (stat.size > MAX_FILE_BYTES) {
401392
continue;
402393
}
403-
let content = await fs.promises.readFile(absPath, "utf-8");
404-
if (filePath.endsWith(".json")) {
405-
content = minifyJson(content);
406-
}
394+
const content = await fs.promises.readFile(absPath, "utf-8");
407395
if (totalBytes + content.length <= MAX_PREREAD_TOTAL_BYTES) {
408396
cache[filePath] = content;
409397
totalBytes += content.length;
@@ -549,10 +537,6 @@ async function readSingleFile(
549537
content = await fs.promises.readFile(absPath, "utf-8");
550538
}
551539

552-
if (filePath.endsWith(".json")) {
553-
content = minifyJson(content);
554-
}
555-
556540
return content;
557541
} catch {
558542
return null;

0 commit comments

Comments
 (0)