From 0a60e18cc3395a2bacdd45d3713dd0a959c51a3b Mon Sep 17 00:00:00 2001 From: Juan Ibiapina Date: Thu, 29 Oct 2026 12:17:18 +0100 Subject: [PATCH] fix(coding-agent): start new sessions in the cwd's default directory SessionManager.open() without a session directory used the file's folder for new sessions. When the session's cwd differs from the project the folder belongs to, for example after choosing "continue in current cwd" at the missing-cwd prompt, pi treated that folder as a custom --session-dir: /resume All listed only that folder, the resume hint added --session-dir, and /new, /fork and /clone saved into the old project's folder. For a file in the sessions directory, open() now uses the default directory of the session's cwd. Files elsewhere, such as in a custom --session-dir, keep their folder. --- .../coding-agent/src/core/session-manager.ts | 7 +++- .../session-manager/file-operations.test.ts | 39 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) 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;