diff --git a/packages/cli-workflow/__tests__/thread-cli.test.ts b/packages/cli-workflow/__tests__/thread-cli.test.ts index f0db13d..edbf617 100644 --- a/packages/cli-workflow/__tests__/thread-cli.test.ts +++ b/packages/cli-workflow/__tests__/thread-cli.test.ts @@ -180,6 +180,9 @@ describe("cli thread commands", () => { } expect(threads.value.some((l) => l.includes(threadId))).toBe(true); + const runningPath = join(storageRoot, "logs", added.value.hash, `${threadId}.running`); + await waitUntilRunningFileAbsent(runningPath, 120); + const shown = await cmdThreadShow(storageRoot, threadId); expect(shown.ok).toBe(true); if (!shown.ok) { diff --git a/packages/cli-workflow/src/commands/thread/rm.ts b/packages/cli-workflow/src/commands/thread/rm.ts index 814e346..fb2d998 100644 --- a/packages/cli-workflow/src/commands/thread/rm.ts +++ b/packages/cli-workflow/src/commands/thread/rm.ts @@ -18,13 +18,13 @@ export async function cmdThreadRemove( return err(`thread not found: ${threadId}`); } - if (resolved.source === "active") { - await removeThreadEntry(resolved.bundleDir, threadId); - } else { - const hist = await removeThreadHistoryEntries(resolved.bundleDir, threadId); - if (!hist.ok) { - return hist; - } + // Always clear both stores: between resolve and delete the worker may finish and + // move the thread from threads.json into history; branching only on resolved.source + // would skip history removal and leave a dangling row. + await removeThreadEntry(resolved.bundleDir, threadId); + const hist = await removeThreadHistoryEntries(resolved.bundleDir, threadId); + if (!hist.ok) { + return hist; } const infoPath = join(storageRoot, "logs", resolved.bundleHash, `${threadId}.info.jsonl`);