diff --git a/packages/coding-agent/src/core/session-manager.ts b/packages/coding-agent/src/core/session-manager.ts index 89431f2a3..784cd8e3b 100644 --- a/packages/coding-agent/src/core/session-manager.ts +++ b/packages/coding-agent/src/core/session-manager.ts @@ -1790,8 +1790,11 @@ export class SessionManager { } } const cwd = cwdOverride ?? (header ? getSessionHeaderCwd(header) : undefined) ?? process.cwd(); - // If no sessionDir provided, derive from file's parent directory - const dir = sessionDir ? normalizePath(sessionDir) : resolve(resolvedPath, ".."); + // If no sessionDir provided, use the cwd's default directory for files in the sessions directory, + // otherwise the file's parent directory + const parentDir = resolve(resolvedPath, ".."); + const inSessionsDir = resolve(parentDir, "..") === resolvePath(getSessionsDir()); + const dir = sessionDir ? normalizePath(sessionDir) : inSessionsDir ? getDefaultSessionDirPath(cwd) : parentDir; return new SessionManager(cwd, dir, resolvedPath, true, undefined, preloadedFileEntries); } diff --git a/packages/coding-agent/test/session-manager/file-operations.test.ts b/packages/coding-agent/test/session-manager/file-operations.test.ts index ac6441490..fb9864643 100644 --- a/packages/coding-agent/test/session-manager/file-operations.test.ts +++ b/packages/coding-agent/test/session-manager/file-operations.test.ts @@ -15,6 +15,7 @@ import { import { tmpdir } from "os"; import { join } from "path"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { ENV_AGENT_DIR } from "../../src/config.ts"; import { findMostRecentSession, loadEntriesFromFile, SessionManager } from "../../src/core/session-manager.ts"; import { assistantMsg, readSessionFileRoles, userMsg } from "../utilities.ts"; @@ -356,6 +357,44 @@ describe("SessionManager custom flat session directory", () => { }); }); +describe("SessionManager.open session directory", () => { + let tempDir: string; + let savedAgentDir: string | undefined; + + beforeEach(() => { + tempDir = mkdtempSync(join(tmpdir(), "session-default-dir-")); + savedAgentDir = process.env[ENV_AGENT_DIR]; + process.env[ENV_AGENT_DIR] = join(tempDir, "agent"); + mkdirSync(join(tempDir, "a")); + mkdirSync(join(tempDir, "b")); + }); + + afterEach(() => { + if (savedAgentDir === undefined) delete process.env[ENV_AGENT_DIR]; + else process.env[ENV_AGENT_DIR] = savedAgentDir; + rmSync(tempDir, { recursive: true, force: true }); + }); + + it("uses the default directory of the cwd for a session opened with another cwd", () => { + const session = SessionManager.create(join(tempDir, "a")); + session.appendMessage(userMsg("hello")); + + const reopened = SessionManager.open(session.getSessionFile()!, undefined, join(tempDir, "b")); + expect(reopened.getSessionDir()).toBe(SessionManager.create(join(tempDir, "b")).getSessionDir()); + expect(reopened.usesDefaultSessionDir()).toBe(true); + }); + + it("keeps a custom session directory", () => { + const customDir = join(tempDir, "custom"); + const session = SessionManager.create(join(tempDir, "a"), customDir); + session.appendMessage(userMsg("hello")); + + const reopened = SessionManager.open(session.getSessionFile()!, undefined, join(tempDir, "b")); + expect(reopened.getSessionDir()).toBe(customDir); + expect(reopened.usesDefaultSessionDir()).toBe(false); + }); +}); + describe("SessionManager.setSessionFile with corrupted files", () => { let tempDir: string;