diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 4eeb7988..d6ab7f14 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -4,6 +4,7 @@ ### Fixed +- Fixed `sessionDir` in `settings.json` to expand `~`, so portable session-directory settings no longer require a shell wrapper ([#3514](https://github.com/badlogic/pi-mono/issues/3514)) - Fixed parallel tool-call rows to leave the pending state as soon as each tool is finalized, while still appending persisted tool results in assistant source order ([#3503](https://github.com/badlogic/pi-mono/issues/3503)) - Fixed exported session markdown to render Markdown while showing HTML-like message content such as `...` verbatim, so shared sessions match the TUI instead of letting the browser interpret message text ([#3484](https://github.com/badlogic/pi-mono/issues/3484)) diff --git a/packages/coding-agent/docs/settings.md b/packages/coding-agent/docs/settings.md index 63d4aa88..563c3aa3 100644 --- a/packages/coding-agent/docs/settings.md +++ b/packages/coding-agent/docs/settings.md @@ -132,7 +132,7 @@ When a provider requests a retry delay longer than `maxDelayMs` (e.g., Google's | Setting | Type | Default | Description | |---------|------|---------|-------------| -| `sessionDir` | string | - | Directory where session files are stored. Accepts absolute or relative paths. | +| `sessionDir` | string | - | Directory where session files are stored. Accepts absolute or relative paths, plus `~`. | ```json { "sessionDir": ".pi/sessions" } diff --git a/packages/coding-agent/src/core/settings-manager.ts b/packages/coding-agent/src/core/settings-manager.ts index 8700029a..fb923770 100644 --- a/packages/coding-agent/src/core/settings-manager.ts +++ b/packages/coding-agent/src/core/settings-manager.ts @@ -1,5 +1,6 @@ import type { Transport } from "@mariozechner/pi-ai"; import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs"; +import { homedir } from "os"; import { dirname, join } from "path"; import lockfile from "proper-lockfile"; import { CONFIG_DIR_NAME, getAgentDir } from "../config.js"; @@ -534,7 +535,17 @@ export class SettingsManager { } getSessionDir(): string | undefined { - return this.settings.sessionDir; + const sessionDir = this.settings.sessionDir; + if (!sessionDir) { + return sessionDir; + } + if (sessionDir === "~") { + return homedir(); + } + if (sessionDir.startsWith("~/")) { + return join(homedir(), sessionDir.slice(2)); + } + return sessionDir; } getDefaultProvider(): string | undefined { diff --git a/packages/coding-agent/test/settings-manager.test.ts b/packages/coding-agent/test/settings-manager.test.ts index 2461b601..d01b1363 100644 --- a/packages/coding-agent/test/settings-manager.test.ts +++ b/packages/coding-agent/test/settings-manager.test.ts @@ -1,4 +1,5 @@ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs"; +import { homedir } from "os"; import { join } from "path"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { SettingsManager } from "../src/core/settings-manager.js"; @@ -308,5 +309,11 @@ describe("SettingsManager", () => { const manager = SettingsManager.create(projectDir, agentDir); expect(manager.getSessionDir()).toBe("./sessions"); }); + + it("should expand ~ in sessionDir", () => { + writeFileSync(join(agentDir, "settings.json"), JSON.stringify({ sessionDir: "~/sessions" })); + const manager = SettingsManager.create(projectDir, agentDir); + expect(manager.getSessionDir()).toBe(join(homedir(), "sessions")); + }); }); });