From 45a16c1c6830f34e58f5e18cc3b4ea4d03e42552 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 8 May 2026 20:16:04 +0100 Subject: [PATCH] fix: detect legacy dreaming corpus directories --- src/commands/doctor-sqlite-state.test.ts | 45 +++++++++++++++++++ .../dreaming-state-migration.ts | 7 ++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/commands/doctor-sqlite-state.test.ts b/src/commands/doctor-sqlite-state.test.ts index 052f9d08840..475717379b9 100644 --- a/src/commands/doctor-sqlite-state.test.ts +++ b/src/commands/doctor-sqlite-state.test.ts @@ -757,4 +757,49 @@ describe("maybeRepairLegacyRuntimeStateFiles", () => { }); }); }); + + it("imports legacy memory-core session corpus when it is the only dreaming file", async () => { + await withTempDir("openclaw-doctor-memory-core-corpus-", async (rootDir) => { + const stateDir = path.join(rootDir, "state"); + const workspaceDir = path.join(rootDir, "workspace"); + const sessionCorpusDir = path.join(workspaceDir, "memory", ".dreams", "session-corpus"); + const env = { ...process.env, OPENCLAW_STATE_DIR: stateDir, OPENCLAW_TEST_FAST: "1" }; + const cfg = { + agents: { + defaults: { + workspace: workspaceDir, + }, + }, + }; + await withEnvAsync(env, async () => { + await fs.mkdir(sessionCorpusDir, { recursive: true }); + await fs.writeFile( + path.join(sessionCorpusDir, "2026-04-06.txt"), + "User: Store the legacy corpus in SQLite.\n", + "utf8", + ); + + await maybeRepairLegacyRuntimeStateFiles({ + prompter: { shouldRepair: true }, + env, + cfg, + }); + + expect(noteMock).toHaveBeenCalledWith( + expect.stringContaining("memory-core dreaming checkpoint row"), + "Doctor changes", + ); + await expect(fs.stat(path.join(sessionCorpusDir, "2026-04-06.txt"))).rejects.toMatchObject({ + code: "ENOENT", + }); + await expect( + readDreamingSessionCorpusText({ + workspaceDir, + relativePath: "memory/.dreams/session-corpus/2026-04-06.txt", + env, + }), + ).resolves.toBe("User: Store the legacy corpus in SQLite.\n"); + }); + }); + }); }); diff --git a/src/memory-host-sdk/dreaming-state-migration.ts b/src/memory-host-sdk/dreaming-state-migration.ts index 955bfbac1c7..b6544045be8 100644 --- a/src/memory-host-sdk/dreaming-state-migration.ts +++ b/src/memory-host-sdk/dreaming-state-migration.ts @@ -151,7 +151,12 @@ export async function legacyMemoryCoreDreamingStateFilesExist(params: { }): Promise { for (const workspaceDir of configuredDreamingWorkspaces(params.cfg)) { for (const relativePath of Object.values(DREAMING_STATE_RELATIVE_PATHS)) { - if (await fileExists(path.join(workspaceDir, relativePath))) { + const absolutePath = path.join(workspaceDir, relativePath); + const exists = + relativePath === DREAMING_STATE_RELATIVE_PATHS.sessionCorpusDir + ? await dirExists(absolutePath) + : await fileExists(absolutePath); + if (exists) { return true; } }