diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 29358176..87ddb815 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -4,6 +4,7 @@ ### Added +- Added `PI_CODING_AGENT_SESSION_DIR` as an environment equivalent to `--session-dir` ([#4027](https://github.com/badlogic/pi-mono/issues/4027)). - Added `message_end` extension result support for replacing finalized messages, enabling extensions to override assistant usage cost ([#3982](https://github.com/badlogic/pi-mono/issues/3982)). - Added top-level `name` support to `pi.registerProvider()` so extension-registered providers can show a friendly name in `/login` ([#3956](https://github.com/badlogic/pi-mono/issues/3956)). - Added `ctx.ui.getEditorComponent()` so extensions can wrap the currently configured custom editor factory ([#3935](https://github.com/badlogic/pi-mono/issues/3935)). diff --git a/packages/coding-agent/README.md b/packages/coding-agent/README.md index fe3f06b1..5a29f6e0 100644 --- a/packages/coding-agent/README.md +++ b/packages/coding-agent/README.md @@ -619,6 +619,7 @@ pi --thinking high "Solve this complex problem" | Variable | Description | |----------|-------------| | `PI_CODING_AGENT_DIR` | Override config directory (default: `~/.pi/agent`) | +| `PI_CODING_AGENT_SESSION_DIR` | Override session storage directory (overridden by `--session-dir`) | | `PI_PACKAGE_DIR` | Override package directory (useful for Nix/Guix where store paths tokenize poorly) | | `PI_OFFLINE` | Disable startup network operations, including update checks, package update checks, and install/update telemetry | | `PI_SKIP_VERSION_CHECK` | Skip the Pi version update check at startup. This prevents the `pi.dev` latest-version request | diff --git a/packages/coding-agent/docs/settings.md b/packages/coding-agent/docs/settings.md index fd5771f1..05b38fa1 100644 --- a/packages/coding-agent/docs/settings.md +++ b/packages/coding-agent/docs/settings.md @@ -167,7 +167,7 @@ Normally the package manager's global modules location is queried using `root -g { "sessionDir": ".pi/sessions" } ``` -When multiple sources specify a session directory, `--session-dir` CLI flag takes precedence over `sessionDir` in settings.json. +When multiple sources specify a session directory, precedence is `--session-dir`, `PI_CODING_AGENT_SESSION_DIR`, then `sessionDir` in settings.json. ### Model Cycling diff --git a/packages/coding-agent/docs/usage.md b/packages/coding-agent/docs/usage.md index 9de6ac59..487e72ac 100644 --- a/packages/coding-agent/docs/usage.md +++ b/packages/coding-agent/docs/usage.md @@ -260,6 +260,7 @@ pi --tools read,grep,find,ls -p "Review the code" | Variable | Description | |----------|-------------| | `PI_CODING_AGENT_DIR` | Override config directory; default is `~/.pi/agent` | +| `PI_CODING_AGENT_SESSION_DIR` | Override session storage directory; overridden by `--session-dir` | | `PI_PACKAGE_DIR` | Override package directory, useful for Nix/Guix store paths | | `PI_OFFLINE` | Disable startup network operations, including update checks, package update checks, and install/update telemetry | | `PI_SKIP_VERSION_CHECK` | Skip the Pi version update check at startup. This prevents the `pi.dev` latest-version request | diff --git a/packages/coding-agent/src/cli/args.ts b/packages/coding-agent/src/cli/args.ts index de0a79d7..b2c5532a 100644 --- a/packages/coding-agent/src/cli/args.ts +++ b/packages/coding-agent/src/cli/args.ts @@ -4,7 +4,7 @@ import type { ThinkingLevel } from "@mariozechner/pi-agent-core"; import chalk from "chalk"; -import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR } from "../config.js"; +import { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, ENV_SESSION_DIR } from "../config.js"; import type { ExtensionFlag } from "../core/extensions/types.js"; export type Mode = "text" | "json" | "rpc"; @@ -324,7 +324,8 @@ ${chalk.bold("Environment Variables:")} AWS_SECRET_ACCESS_KEY - AWS secret key for Amazon Bedrock AWS_BEARER_TOKEN_BEDROCK - Bedrock API key (bearer token) AWS_REGION - AWS region for Amazon Bedrock (e.g., us-east-1) - ${ENV_AGENT_DIR.padEnd(32)} - Session storage directory (default: ~/${CONFIG_DIR_NAME}/agent) + ${ENV_AGENT_DIR.padEnd(32)} - Config directory (default: ~/${CONFIG_DIR_NAME}/agent) + ${ENV_SESSION_DIR.padEnd(32)} - Session storage directory (overridden by --session-dir) PI_PACKAGE_DIR - Override package directory (for Nix/Guix store paths) PI_OFFLINE - Disable startup network operations when set to 1/true/yes PI_TELEMETRY - Override install telemetry when set to 1/true/yes or 0/false/no diff --git a/packages/coding-agent/src/config.ts b/packages/coding-agent/src/config.ts index 7a8a477e..20876fa1 100644 --- a/packages/coding-agent/src/config.ts +++ b/packages/coding-agent/src/config.ts @@ -327,6 +327,13 @@ export const VERSION: string = pkg.version || "0.0.0"; // e.g., PI_CODING_AGENT_DIR or TAU_CODING_AGENT_DIR export const ENV_AGENT_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_DIR`; +export const ENV_SESSION_DIR = `${APP_NAME.toUpperCase()}_CODING_AGENT_SESSION_DIR`; + +export function expandTildePath(path: string): string { + if (path === "~") return homedir(); + if (path.startsWith("~/")) return homedir() + path.slice(1); + return path; +} const DEFAULT_SHARE_VIEWER_URL = "https://pi.dev/session/"; @@ -344,10 +351,7 @@ export function getShareViewerUrl(gistId: string): string { export function getAgentDir(): string { const envDir = process.env[ENV_AGENT_DIR]; if (envDir) { - // Expand tilde to home directory - if (envDir === "~") return homedir(); - if (envDir.startsWith("~/")) return homedir() + envDir.slice(1); - return envDir; + return expandTildePath(envDir); } return join(homedir(), CONFIG_DIR_NAME, "agent"); } diff --git a/packages/coding-agent/src/main.ts b/packages/coding-agent/src/main.ts index 821f602c..c68f5cb1 100644 --- a/packages/coding-agent/src/main.ts +++ b/packages/coding-agent/src/main.ts @@ -15,7 +15,7 @@ import { processFileArguments } from "./cli/file-processor.js"; import { buildInitialMessage } from "./cli/initial-message.js"; import { listModels } from "./cli/list-models.js"; import { selectSession } from "./cli/session-picker.js"; -import { getAgentDir, VERSION } from "./config.js"; +import { ENV_SESSION_DIR, expandTildePath, getAgentDir, VERSION } from "./config.js"; import { type CreateAgentSessionRuntimeFactory, createAgentSessionRuntime } from "./core/agent-session-runtime.js"; import { type AgentSessionRuntimeDiagnostic, @@ -493,7 +493,11 @@ export async function main(args: string[], options?: MainOptions) { // settings, resources, provider registrations, and models must be resolved only after // the target session cwd is known. The startup-cwd settings manager is used only for // sessionDir lookup during session selection. - const sessionDir = parsed.sessionDir ?? startupSettingsManager.getSessionDir(); + const envSessionDir = process.env[ENV_SESSION_DIR]; + const sessionDir = + parsed.sessionDir ?? + (envSessionDir ? expandTildePath(envSessionDir) : undefined) ?? + startupSettingsManager.getSessionDir(); let sessionManager = await createSessionManager(parsed, cwd, sessionDir, startupSettingsManager); const missingSessionCwdIssue = getMissingSessionCwdIssue(sessionManager, cwd); if (missingSessionCwdIssue) {