feat(FN-926): filter out files with empty diffs from file-diffs endpoint

- Filter files where diff body is empty (e.g., binary files, unchanged) from the /api/tasks/:id/file-diffs response
- Add tests verifying empty diffs are excluded while non-empty diffs are preserved
- Reduces noise in the dashboard diff viewer by omitting irrelevant file entries
This commit is contained in:
gsxdsm
2026-04-04 15:19:48 -07:00
parent 773f22a620
commit a829a55edd
2 changed files with 37 additions and 2 deletions

View File

@@ -511,6 +511,36 @@ describe("GET /api/tasks/:id/file-diffs", () => {
expect(paths.sort()).toEqual(["src/d.ts", "src/e.ts"]);
});
it("filters out files with empty diffs (mode-only changes, binary files)", async () => {
const store = new MockStore();
store.addTask(createTask({ baseBranch: "main", baseCommitSha: "taskbase456" }));
mockExecSync.mockImplementation((command) => {
const cmd = String(command);
if (cmd === "git merge-base --is-ancestor taskbase456 HEAD") {
return "" as any;
}
// git reports the file as modified
if (cmd === "git diff --name-status taskbase456..HEAD") {
return "M\tsrc/mode-only.txt\n" as any;
}
if (cmd === "git diff --name-status") {
return "" as any;
}
// but the diff is empty (mode-only change)
if (cmd === 'git diff taskbase456..HEAD -- "src/mode-only.txt"') {
return "" as any;
}
throw new Error(`Unexpected command: ${cmd}`);
});
const response = await requestFileDiffs(store);
expect(response.status).toBe(200);
// File should be filtered out because diff is empty
expect(response.body).toHaveLength(0);
});
it("agrees with session-files under task-scoped base resolution", async () => {
const store = new MockStore();
// Both routes should produce the same file list when baseCommitSha is valid

View File

@@ -7577,7 +7577,7 @@ Output ONLY the prompt text (no markdown, no explanations).`;
// against the resolved merge-base.
const diffRange = diffBase ? `${diffBase}..HEAD` : "HEAD";
const files = Array.from(fileMap.entries()).map(([filePath, { statusCode, oldPath }]) => {
const files = Array.from(fileMap.entries()).flatMap(([filePath, { statusCode, oldPath }]) => {
let status: "added" | "modified" | "deleted" | "renamed" = "modified";
if (statusCode.startsWith("A")) {
@@ -7599,7 +7599,12 @@ Output ONLY the prompt text (no markdown, no explanations).`;
diff = "";
}
return oldPath ? { path: filePath, status, diff, oldPath } : { path: filePath, status, diff };
// Filter out files with empty diffs (mode-only changes, binary files, etc.)
if (!diff) {
return [];
}
return oldPath ? [{ path: filePath, status, diff, oldPath }] : [{ path: filePath, status, diff }];
});
fileDiffsCache.set(task.id, {