Skip to content

Commit cd58954

Browse files
gkzeclaude
andcommitted
fix(import): preserve completion timestamps on beads update
Avoid clearing an existing completed_at when a Beads closed issue is re-imported without closed_at during --update. Co-Authored-By: gpt-5.3-codex <noreply@anthropic.com>
1 parent bd86409 commit cd58954

2 files changed

Lines changed: 41 additions & 1 deletion

File tree

src/cli/import.test.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1429,6 +1429,42 @@ Old subtask context.
14291429
expect(child?.blockedBy).toEqual([]);
14301430
});
14311431

1432+
it("preserves completed_at on update when Beads closed issue has no closed_at", async () => {
1433+
const filePath = writeBeadsFixture(
1434+
`${JSON.stringify({
1435+
id: "completed-preserve",
1436+
title: "Completed v1",
1437+
status: "closed",
1438+
priority: 1,
1439+
closed_at: "2026-01-05T00:00:00Z",
1440+
})}\n`,
1441+
);
1442+
1443+
await runCli(["import", "--beads", filePath], { storage });
1444+
1445+
writeBeadsFixture(
1446+
`${JSON.stringify({
1447+
id: "completed-preserve",
1448+
title: "Completed v2",
1449+
status: "closed",
1450+
priority: 1,
1451+
})}\n`,
1452+
);
1453+
1454+
await runCli(["import", "--beads", filePath, "--update"], {
1455+
storage,
1456+
});
1457+
1458+
const tasks = await storage.readAsync();
1459+
const task = tasks.tasks.find((item) => item.id === "completed-preserve");
1460+
1461+
expect(task?.completed).toBe(true);
1462+
expect(task?.name).toBe("Completed v2");
1463+
expect(new Date(task?.completed_at ?? "").toISOString()).toBe(
1464+
"2026-01-05T00:00:00.000Z",
1465+
);
1466+
});
1467+
14321468
it("reports warnings for missing relationship targets without failing import", async () => {
14331469
const filePath = writeBeadsFixture(
14341470
`${JSON.stringify({

src/cli/import.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,11 @@ async function importFromBeadsFile(
281281
description: issue.description,
282282
priority: issue.priority,
283283
completed: issue.completed,
284-
completed_at: issue.completed ? (issue.completed_at ?? null) : null,
284+
...(!issue.completed
285+
? { completed_at: null }
286+
: issue.completed_at
287+
? { completed_at: issue.completed_at }
288+
: {}),
285289
result: issue.completed ? issue.result : null,
286290
started_at: issue.started_at ?? null,
287291
metadata: {

0 commit comments

Comments
 (0)