From 984b9aa77fe3eba64f9fbe876cf6c0bfdf4f033b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 8 May 2026 17:57:21 +0100 Subject: [PATCH] refactor: mark legacy transcript dirs explicitly --- src/commands/doctor-state-integrity.test.ts | 36 ++++++++++++++++----- src/commands/doctor-state-integrity.ts | 4 +-- src/config/sessions/paths.ts | 6 ++-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/commands/doctor-state-integrity.test.ts b/src/commands/doctor-state-integrity.test.ts index 8921d6cbaaf..d7accb046e2 100644 --- a/src/commands/doctor-state-integrity.test.ts +++ b/src/commands/doctor-state-integrity.test.ts @@ -4,7 +4,7 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { HEARTBEAT_TRANSCRIPT_PROMPT } from "../auto-reply/heartbeat.js"; import type { OpenClawConfig } from "../config/config.js"; -import { resolveSessionTranscriptsDirForAgent } from "../config/sessions/paths.js"; +import { resolveLegacySessionTranscriptsDirForAgent } from "../config/sessions/paths.js"; import { deleteSessionEntry, listSessionEntries, @@ -69,7 +69,7 @@ function restoreEnv(snapshot: EnvSnapshot) { function setupSessionState(env: NodeJS.ProcessEnv, homeDir: string) { const agentId = "main"; - const sessionsDir = resolveSessionTranscriptsDirForAgent(agentId, env, () => homeDir); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent(agentId, env, () => homeDir); fs.mkdirSync(sessionsDir, { recursive: true }); } @@ -163,7 +163,11 @@ async function runOrphanTranscriptCheckWithQmdSessions(enabled: boolean, homeDir }, }; setupSessionState(process.env, homeDir); - const sessionsDir = resolveSessionTranscriptsDirForAgent("main", process.env, () => homeDir); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( + "main", + process.env, + () => homeDir, + ); fs.writeFileSync(path.join(sessionsDir, "orphan-session.jsonl"), '{"type":"session"}\n'); const confirmRuntimeRepair = vi.fn(async () => false); await noteStateIntegrity(cfg, { confirmRuntimeRepair, note: noteMock }); @@ -448,7 +452,11 @@ describe("doctor state integrity oauth dir checks", () => { it("detects orphan transcripts and offers delete remediation", async () => { const cfg: OpenClawConfig = {}; setupSessionState(process.env, process.env.HOME ?? ""); - const sessionsDir = resolveSessionTranscriptsDirForAgent("main", process.env, () => tempHome); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( + "main", + process.env, + () => tempHome, + ); fs.writeFileSync(path.join(sessionsDir, "orphan-session.jsonl"), '{"type":"session"}\n'); const confirmRuntimeRepair = vi.fn(async (params: { message: string }) => params.message.includes("Delete 1 orphan transcript file"), @@ -469,7 +477,11 @@ describe("doctor state integrity oauth dir checks", () => { it("does not auto-delete orphan transcripts from non-interactive repair mode", async () => { const cfg: OpenClawConfig = {}; setupSessionState(process.env, process.env.HOME ?? ""); - const sessionsDir = resolveSessionTranscriptsDirForAgent("main", process.env, () => tempHome); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( + "main", + process.env, + () => tempHome, + ); fs.writeFileSync(path.join(sessionsDir, "orphan-session.jsonl"), '{"type":"session"}\n'); const confirmRuntimeRepair = vi.fn( async (params: { initialValue?: boolean; requiresInteractiveConfirmation?: boolean }) => @@ -501,7 +513,7 @@ describe("doctor state integrity oauth dir checks", () => { process.env.OPENCLAW_STATE_DIR = path.join(symlinkHome, ".openclaw"); setupSessionState(process.env, symlinkHome); - const sessionsDir = resolveSessionTranscriptsDirForAgent( + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( "main", process.env, () => symlinkHome, @@ -568,7 +580,11 @@ describe("doctor state integrity oauth dir checks", () => { it("moves a heartbeat-poisoned main session and clears stale TUI restore pointers", async () => { const cfg: OpenClawConfig = {}; setupSessionState(process.env, tempHome); - const sessionsDir = resolveSessionTranscriptsDirForAgent("main", process.env, () => tempHome); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( + "main", + process.env, + () => tempHome, + ); const heartbeatTranscriptPath = path.join(sessionsDir, "heartbeat-session.jsonl"); replaceSqliteSessionTranscriptEvents({ agentId: "main", @@ -622,7 +638,11 @@ describe("doctor state integrity oauth dir checks", () => { it("does not move a mixed main transcript that has real user activity", async () => { const cfg: OpenClawConfig = {}; setupSessionState(process.env, tempHome); - const sessionsDir = resolveSessionTranscriptsDirForAgent("main", process.env, () => tempHome); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent( + "main", + process.env, + () => tempHome, + ); const mixedTranscriptPath = path.join(sessionsDir, "mixed-session.jsonl"); replaceSqliteSessionTranscriptEvents({ agentId: "main", diff --git a/src/commands/doctor-state-integrity.ts b/src/commands/doctor-state-integrity.ts index 5feb0035fed..6a03cffba71 100644 --- a/src/commands/doctor-state-integrity.ts +++ b/src/commands/doctor-state-integrity.ts @@ -12,8 +12,8 @@ import { resolveOAuthDir, resolveStateDir } from "../config/paths.js"; import { isPrimarySessionTranscriptFileName } from "../config/sessions/artifacts.js"; import { resolveMainSessionKey } from "../config/sessions/main-session.js"; import { + resolveLegacySessionTranscriptsDirForAgent, resolveSessionTranscriptLocator, - resolveSessionTranscriptsDirForAgent, } from "../config/sessions/paths.js"; import { listSessionEntries, upsertSessionEntry } from "../config/sessions/store.js"; import { @@ -657,7 +657,7 @@ export async function noteStateIntegrity( const defaultStateDir = path.join(homedir(), ".openclaw"); const oauthDir = resolveOAuthDir(env, stateDir); const agentId = resolveDefaultAgentId(cfg); - const sessionsDir = resolveSessionTranscriptsDirForAgent(agentId, env, homedir); + const sessionsDir = resolveLegacySessionTranscriptsDirForAgent(agentId, env, homedir); const displayStateDir = shortenHomePath(stateDir); const displayOauthDir = shortenHomePath(oauthDir); const displaySessionsDir = shortenHomePath(sessionsDir); diff --git a/src/config/sessions/paths.ts b/src/config/sessions/paths.ts index 2b25fb09e14..49ce0360ad4 100644 --- a/src/config/sessions/paths.ts +++ b/src/config/sessions/paths.ts @@ -5,7 +5,7 @@ import { DEFAULT_AGENT_ID, normalizeAgentId } from "../../routing/session-key.js import { resolveStateDir } from "../paths.js"; import { isCompactionCheckpointTranscriptFileName } from "./artifacts.js"; -function resolveAgentSessionsDir( +function resolveLegacyAgentSessionsDir( agentId?: string, env: NodeJS.ProcessEnv = process.env, homedir: () => string = () => resolveRequiredHomeDir(env, os.homedir), @@ -15,12 +15,12 @@ function resolveAgentSessionsDir( return path.join(root, "agents", id, "sessions"); } -export function resolveSessionTranscriptsDirForAgent( +export function resolveLegacySessionTranscriptsDirForAgent( agentId?: string, env: NodeJS.ProcessEnv = process.env, homedir: () => string = () => resolveRequiredHomeDir(env, os.homedir), ): string { - return resolveAgentSessionsDir(agentId, env, homedir); + return resolveLegacyAgentSessionsDir(agentId, env, homedir); } export type SessionTranscriptLocatorOptions = {