diff --git a/src/agents/command/attempt-execution.cli.test.ts b/src/agents/command/attempt-execution.cli.test.ts index c13eaa09e2b..14ce506b85d 100644 --- a/src/agents/command/attempt-execution.cli.test.ts +++ b/src/agents/command/attempt-execution.cli.test.ts @@ -2,7 +2,8 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { loadSessionStore, saveSessionStore, type SessionEntry } from "../../config/sessions.js"; +import type { SessionEntry } from "../../config/sessions.js"; +import { listSessionEntries, upsertSessionEntry } from "../../config/sessions/store.js"; import { appendSessionTranscriptMessage } from "../../config/sessions/transcript-append.js"; import { loadSqliteSessionTranscriptEvents } from "../../config/sessions/transcript-store.sqlite.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; @@ -120,11 +121,9 @@ function expectMockArgFields( describe("CLI attempt execution", () => { let tmpDir: string; - let storePath: string; beforeEach(async () => { tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-cli-attempt-")); - storePath = path.join(tmpDir, "agents", "main", "sessions", "sessions.json"); vi.stubEnv("OPENCLAW_STATE_DIR", tmpDir); runCliAgentMock.mockReset(); runEmbeddedPiAgentMock.mockReset(); @@ -142,7 +141,15 @@ describe("CLI attempt execution", () => { }); async function writeStore(store: Record) { - await saveSessionStore(storePath, store); + for (const [sessionKey, entry] of Object.entries(store)) { + upsertSessionEntry({ agentId: "main", sessionKey, entry }); + } + } + + function readStore(): Record { + return Object.fromEntries( + listSessionEntries({ agentId: "main" }).map(({ sessionKey, entry }) => [sessionKey, entry]), + ); } async function runClaudeCliAttempt(params: { @@ -178,7 +185,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "claude-cli", sessionStore: params.sessionStore, - storePath, sessionHasHistory: false, }); } @@ -243,7 +249,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "claude-cli", sessionStore, - storePath, sessionHasHistory: false, }); @@ -253,7 +258,7 @@ describe("CLI attempt execution", () => { expect(sessionStore[sessionKey]?.cliSessionIds?.["claude-cli"]).toBeUndefined(); expect(sessionStore[sessionKey]?.claudeCliSessionId).toBeUndefined(); - const persisted = loadSessionStore(storePath); + const persisted = readStore(); expect(persisted[sessionKey]?.cliSessionIds?.["claude-cli"]).toBeUndefined(); expect(persisted[sessionKey]?.claudeCliSessionId).toBeUndefined(); }); @@ -293,7 +298,7 @@ describe("CLI attempt execution", () => { expect(sessionStore[sessionKey]?.cliSessionIds?.["claude-cli"]).toBeUndefined(); expect(sessionStore[sessionKey]?.claudeCliSessionId).toBeUndefined(); - const persisted = loadSessionStore(storePath); + const persisted = readStore(); expect(persisted[sessionKey]?.cliSessionBindings?.["claude-cli"]).toBeUndefined(); expect(persisted[sessionKey]?.cliSessionIds?.["claude-cli"]).toBeUndefined(); expect(persisted[sessionKey]?.claudeCliSessionId).toBeUndefined(); @@ -389,7 +394,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "openai-codex", sessionStore, - storePath, sessionHasHistory: false, }); @@ -413,7 +417,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -477,7 +480,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -498,7 +500,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry: updatedFirst, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -533,7 +534,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -566,7 +566,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry: updatedFirst, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -604,7 +603,6 @@ describe("CLI attempt execution", () => { sessionKey, sessionEntry, sessionStore, - storePath, sessionAgentId: "main", sessionCwd: tmpDir, config: {}, @@ -656,7 +654,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "claude-cli", sessionStore, - storePath, sessionHasHistory: false, }); @@ -761,7 +758,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "anthropic", sessionStore, - storePath, sessionHasHistory: false, }); @@ -816,7 +812,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "openai", sessionStore, - storePath, sessionHasHistory: false, }); @@ -881,7 +876,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "anthropic", sessionStore, - storePath, sessionHasHistory: true, }); @@ -999,7 +993,6 @@ describe("CLI attempt execution", () => { onAgentEvent: vi.fn(), authProfileProvider: "claude-cli", sessionStore, - storePath, sessionHasHistory: false, }); diff --git a/src/agents/harness/native-hook-relay.test.ts b/src/agents/harness/native-hook-relay.test.ts index 395e7c2eec8..4da18d50c0c 100644 --- a/src/agents/harness/native-hook-relay.test.ts +++ b/src/agents/harness/native-hook-relay.test.ts @@ -4,7 +4,8 @@ import { createServer } from "node:http"; import { tmpdir } from "node:os"; import path from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; -import { updateSessionStore, type SessionEntry } from "../../config/sessions.js"; +import type { SessionEntry } from "../../config/sessions.js"; +import { upsertSessionEntry } from "../../config/sessions/store.js"; import { initializeGlobalHookRunner, resetGlobalHookRunner, @@ -691,8 +692,8 @@ describe("native hook relay registry", () => { it("passes config to trusted policies for native pre-tool session extension reads", async () => { const stateDir = await fs.mkdtemp(path.join(tmpdir(), "openclaw-native-relay-policy-")); - const storePath = path.join(stateDir, "sessions.json"); - const config = { session: { store: storePath } }; + const config = { session: {} }; + const previousStateDir = process.env.OPENCLAW_STATE_DIR; const seen: unknown[] = []; const registry = createEmptyPluginRegistry(); registry.sessionExtensions = [ @@ -727,11 +728,14 @@ describe("native hook relay registry", () => { ]; setActivePluginRegistry(registry); try { - await updateSessionStore(storePath, (store) => { - store["agent:main:session-1"] = { + process.env.OPENCLAW_STATE_DIR = stateDir; + upsertSessionEntry({ + agentId: "main", + sessionKey: "agent:main:session-1", + entry: { sessionId: "session-1", updatedAt: Date.now(), - } as SessionEntry; + } satisfies SessionEntry, }); const patchResult = await patchPluginSessionExtension({ cfg: config as never, @@ -773,6 +777,11 @@ describe("native hook relay registry", () => { }); expect(seen).toEqual([{ block: true }]); } finally { + if (previousStateDir === undefined) { + delete process.env.OPENCLAW_STATE_DIR; + } else { + process.env.OPENCLAW_STATE_DIR = previousStateDir; + } await fs.rm(stateDir, { recursive: true, force: true }); } }); diff --git a/src/agents/pi-tools.before-tool-call.integration.e2e.test.ts b/src/agents/pi-tools.before-tool-call.integration.e2e.test.ts index db278b78d79..4d55d827766 100644 --- a/src/agents/pi-tools.before-tool-call.integration.e2e.test.ts +++ b/src/agents/pi-tools.before-tool-call.integration.e2e.test.ts @@ -2,7 +2,8 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import { beforeEach, describe, expect, it, vi } from "vitest"; -import { updateSessionStore, type SessionEntry } from "../config/sessions.js"; +import type { SessionEntry } from "../config/sessions.js"; +import { upsertSessionEntry } from "../config/sessions/store.js"; import { resetDiagnosticSessionStateForTest } from "../logging/diagnostic-session-state.js"; import { initializeGlobalHookRunner, @@ -470,8 +471,8 @@ describe("before_tool_call hook integration for client tools", () => { it("lets trusted policies read session extensions for client tools when config is provided", async () => { resetGlobalHookRunner(); const stateDir = await fs.mkdtemp(path.join(os.tmpdir(), "openclaw-client-tool-policy-")); - const storePath = path.join(stateDir, "sessions.json"); - const config = { session: { store: storePath } }; + const config = { session: {} }; + const previousStateDir = process.env.OPENCLAW_STATE_DIR; const seen: unknown[] = []; const registry = createEmptyPluginRegistry(); registry.sessionExtensions = [ @@ -502,11 +503,14 @@ describe("before_tool_call hook integration for client tools", () => { ]; setActivePluginRegistry(registry); try { - await updateSessionStore(storePath, (store) => { - store["agent:main:client"] = { + process.env.OPENCLAW_STATE_DIR = stateDir; + upsertSessionEntry({ + agentId: "main", + sessionKey: "agent:main:client", + entry: { sessionId: "session-client", updatedAt: Date.now(), - } as SessionEntry; + } satisfies SessionEntry, }); await expect( patchPluginSessionExtension({ @@ -546,6 +550,11 @@ describe("before_tool_call hook integration for client tools", () => { expect(seen).toEqual([{ gate: "client" }]); } finally { + if (previousStateDir === undefined) { + delete process.env.OPENCLAW_STATE_DIR; + } else { + process.env.OPENCLAW_STATE_DIR = previousStateDir; + } setActivePluginRegistry(createEmptyPluginRegistry()); await fs.rm(stateDir, { recursive: true, force: true }); } diff --git a/src/auto-reply/reply/session.heartbeat-no-reset.test.ts b/src/auto-reply/reply/session.heartbeat-no-reset.test.ts index 59e1b0a9b2e..bac4891ee5c 100644 --- a/src/auto-reply/reply/session.heartbeat-no-reset.test.ts +++ b/src/auto-reply/reply/session.heartbeat-no-reset.test.ts @@ -15,11 +15,9 @@ vi.mock("../../plugin-sdk/browser-maintenance.js", () => ({ describe("initSessionState - heartbeat should not trigger session reset", () => { let tempDir: string; - let storePath: string; beforeEach(async () => { tempDir = await fs.mkdtemp("/tmp/openclaw-test-"); - storePath = path.join(tempDir, "agents", "main", "sessions", "sessions.json"); }); afterEach(async () => { @@ -74,7 +72,6 @@ describe("initSessionState - heartbeat should not trigger session reset", () => updatedAt: number, overrides: Partial = {}, ): Promise => { - void storePath; upsertSessionEntry({ agentId: "main", sessionKey: "main:user123",