fix(FN-882): show file changes on done cards using modifiedFiles fallback

Done-column task cards failed to show file changes when mergeDetails was
missing (e.g. tasks moved to done without the merge flow). The executor
already captures modifiedFiles but TaskCard never read it. Add
modifiedFiles.length as a fallback between mergeDetails.filesChanged and
the worktree-based session files check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
gsxdsm
2026-04-04 19:52:25 -07:00
parent e28cbb1c1f
commit ad68e66105
2 changed files with 53 additions and 1 deletions

View File

@@ -721,6 +721,20 @@ function TaskCardComponent({
</button>
);
}
const modifiedCount = task.modifiedFiles?.length;
if (modifiedCount != null && modifiedCount > 0) {
return (
<button
type="button"
className="card-session-files"
onClick={handleOpenFiles}
disabled={!onOpenDetailWithTab}
>
<Folder size={12} />
<span>{modifiedCount} files changed</span>
</button>
);
}
if (task.worktree && sessionFiles.length > 0) {
return (
<button

View File

@@ -3039,7 +3039,7 @@ describe("TaskCard files-changed in done column", () => {
expect(screen.getByText("3 files changed")).toBeInTheDocument();
});
it("shows nothing for done column without worktree and without mergeDetails.filesChanged", () => {
it("shows nothing for done column without worktree, modifiedFiles, and mergeDetails.filesChanged", () => {
const task = makeTask({ column: "done" });
mockUseSessionFiles.mockReturnValue({ files: [], loading: false });
@@ -3054,6 +3054,44 @@ describe("TaskCard files-changed in done column", () => {
expect(screen.queryByText(/files changed/)).not.toBeInTheDocument();
});
it("shows modifiedFiles count for done column without mergeDetails", () => {
const task = makeTask({
column: "done",
modifiedFiles: ["src/a.ts", "src/b.ts", "src/c.ts"],
});
mockUseSessionFiles.mockReturnValue({ files: [], loading: false });
render(
<TaskCard
task={task}
onOpenDetail={vi.fn()}
addToast={noopToast}
/>
);
expect(screen.getByText("3 files changed")).toBeInTheDocument();
});
it("prefers mergeDetails.filesChanged over modifiedFiles for done column", () => {
const task = makeTask({
column: "done",
modifiedFiles: ["src/a.ts", "src/b.ts"],
mergeDetails: { filesChanged: 7, mergedAt: "2026-01-01T00:00:00Z", targetBranch: "main" },
});
mockUseSessionFiles.mockReturnValue({ files: [], loading: false });
render(
<TaskCard
task={task}
onOpenDetail={vi.fn()}
addToast={noopToast}
/>
);
expect(screen.getByText("7 files changed")).toBeInTheDocument();
expect(screen.queryByText("2 files changed")).not.toBeInTheDocument();
});
it("prefers mergeDetails.filesChanged over sessionFiles for done column", () => {
const task = makeTask({
column: "done",