Refs #7756, #5607. Problem: when a wrapper or another package manager provides Pi (mise, a `PNPM_HOME` wrapper such as nub, Nix), `pi update` cannot update it and prints "pi cannot self-update this installation." Users with several machines have to remember which tool updates Pi on which machine. Example: ```sh export PI_SELF_UPDATE_COMMAND="mise use -g npm:{packageName}@{version}" pi update # Updating pi with mise use -g npm:@earendil-works/pi-coding-agent@1.4.0... # Updated pi from 1.3.0 to 1.4.0 ``` or in `~/.pi/agent/settings.json`: ```json { "selfUpdateCommand": ["nix", "profile", "upgrade", "pi"] } ``` Behavior: - `pi update` still checks pi.dev first. The command runs only when a newer release exists, or with `--force`, and the release note prints first. - Placeholders come from that release: `{packageName}`, `{version}`, `{installSpec}` (`<packageName>@<version>`). A package rename announced by pi.dev flows into them. - `PI_SELF_UPDATE_COMMAND` takes precedence and is split on whitespace (no quoting). The setting is argv, for arguments with spaces, and is read only from global settings, so a project's `.pi/settings.json` cannot inject a command. - The configured command replaces Pi's own update logic for every install method, including installer-managed installs: it is explicit user intent. - Exit code 0 does not prove an update. Pi reports "Updated pi from X to Y" when its own `package.json` now shows Y (in-place updates) or when `pi --version` from PATH reports Y (wrappers such as mise or Nix that install each version into a new directory). Otherwise it warns: ``Ran <cmd>, but `pi --version` reports X, not Y.`` - "cannot self-update this installation" now mentions the env var and setting. Docs: `docs/cli.md` (new "Custom update command" section), `docs/settings.md`, `docs/environment-variables.md`, `--help` env list, regenerated `schemas/settings.schema.json`. Tests: unit tests for argv resolution and placeholders in `test/config.test.ts`; CLI tests in `test/package-command-paths.test.ts` for env precedence over the setting and the managed install, global-only setting gated by the version check, and command failure. `npm run check` passes. Manual end-to-end check with real mise 2026.10.23 in a sandboxed HOME, running this branch as the mise-installed 1.3.0 (`PI_PACKAGE_DIR` pointing at mise's install): | Scenario | Result | |---|---| | `mise use -g npm:{packageName}@{version}` | mise installs 1.4.0; `Updated pi from 1.3.0 to 1.4.0` | | Already 1.4.0 | `pi is already up to date (v1.4.0)`, mise not run | | In-place `npm install -g --prefix <dir> {installSpec}` via the setting | `Updated pi from 1.3.0 to 1.4.0` | | Command `true` (exit 0, installs nothing) | ``Ran true, but `pi --version` reports 1.3.0, not 1.4.0.`` | This PR is AI-generated.
5.9 KiB
Environment Variables
Pi uses environment variables in three ways:
- Variables such as
PI_OFFLINEconfigure the Pi process. - Pi sets process markers so child processes can identify Pi as the launching agent.
- Commands run by the LLM-callable shell tools receive
PI_*variables describing the current session.
Provider API-key variables are documented separately in Providers.
Process Marker
The CLI and RPC entry points set two process markers:
AI_AGENT=piis a generic marker that lets tooling identify Pi as the agent that launched the process.PI_CODING_AGENT=trueis Pi-specific and lets child processes detect that they run inside Pi.
Child processes inherit both markers. They are not session-specific and are not set automatically when Pi is embedded through the SDK.
Shell Tool Session Environment
Commands run by the bash and powershell tools receive the current Pi session state:
| Variable | Description |
|---|---|
PI_SESSION_ID |
Current session ID |
PI_SESSION_FILE |
Absolute path to the current session JSONL file; unset for ephemeral sessions |
PI_PROVIDER |
Currently selected model provider |
PI_MODEL |
Currently selected model ID |
PI_REASONING_LEVEL |
Current effective reasoning level: off, minimal, low, medium, high, xhigh, or max |
The values are resolved when each command starts. Switching models or changing the reasoning level therefore affects the next shell command without restarting Pi. PI_PROVIDER and PI_MODEL identify the selected Pi model, not a different upstream model that a router may choose internally.
When asked which model or provider is running, inspect these variables instead of inferring the answer from the system prompt:
printf '%s/%s\n' "$PI_PROVIDER" "$PI_MODEL"
printf 'reasoning=%s session=%s\n' "$PI_REASONING_LEVEL" "$PI_SESSION_ID"
The session file can be inspected directly when the session is persistent:
if [ -n "$PI_SESSION_FILE" ]; then
tail -n 1 "$PI_SESSION_FILE"
fi
These variables are injected into the LLM-callable bash and powershell tools. They are not injected into user-entered ! or !! commands.
Custom Shell Tools
Tools created with createBashTool() or createPowerShellTool() expose the session environment by default when registered with Pi. Injection happens before spawnHook, so a hook receives the variables in ctx.env:
const bashTool = createBashTool(cwd, {
spawnHook: (ctx) => ({
...ctx,
env: { ...ctx.env, CI: "1" },
}),
});
Disable session metadata independently of the spawn hook:
const powershellTool = createPowerShellTool(cwd, {
exposeSessionEnvironment: false,
spawnHook: (ctx) => ctx,
});
When disabled, Pi removes inherited values for these variables so nested Pi processes do not expose stale parent-session metadata.
Pi Process Configuration
These variables are read by Pi itself:
| Variable | Description |
|---|---|
PI_CODING_AGENT_DIR |
Override the config directory; default is ~/.pi/agent |
PI_CODING_AGENT_SESSION_DIR |
Override session storage; overridden by --session-dir |
PI_PACKAGE_DIR |
Override the package directory, useful for Nix/Guix store paths |
PI_OFFLINE |
Disable automatic network activity, including model catalog refreshes |
PI_SKIP_VERSION_CHECK |
Disable the pi.dev latest-version request |
PI_SELF_UPDATE_COMMAND |
Command pi update runs to update Pi itself, split on whitespace, with {packageName}, {version}, and {installSpec} placeholders. Takes precedence over the selfUpdateCommand setting. See Custom update command |
PI_TELEMETRY |
Override install/update telemetry and provider attribution headers: 1/true/yes or 0/false/no |
PI_CODEMODE_MAX_WORKERS |
Maximum codemode workers alive at once across all sessions in the process; default 2. Each worker's script may use up to 256 MB. Raise it when one process runs several sessions, such as in-process subagents. Further scripts wait for a free worker. See Codemode |
PI_CACHE_RETENTION |
Set to long for extended provider prompt caching where supported |
PI_SHARE_VIEWER_URL |
Override the base URL used by /share |
PI_RADIUS_GATEWAY |
Override the Radius gateway origin used by /bug uploads |
PI_CLEAR_ON_SHRINK |
Set to 1 to clear empty rows when rendered content shrinks; the terminal.clearOnShrink setting takes precedence. See Settings |
PI_HARDWARE_CURSOR |
Set to 1 to show the hardware cursor; see Terminal setup |
PI_CLIPBOARD_OSC52 |
Set to 1 to also send copied text to the terminal with OSC 52 after the local clipboard write, as Pi does over SSH. Use it when a remote client reaches Pi without SSH variables, such as a multiplexer attached from another machine or a remote IDE daemon |
PI_HYPERLINKS |
Override OSC 8 hyperlink detection with 1, 0, or auto |
PI_PROGRAM_STATUS |
Override OSC 7501 program status detection: 1 always reports, 0 never reports; otherwise Pi reports only after the terminal confirms support. See Terminal setup |
PI_IMAGE_PROTOCOL |
Override inline image detection with kitty, iterm2, none, or auto |
PI_TRUE_COLOR |
Override truecolor detection with 1, 0, or auto |
PI_TUI_ESC_TIMEOUT |
How long to wait after a lone ESC before treating it as Escape, in milliseconds; defaults to 100 over SSH and 10 otherwise. Increase if Alt-key input is misread as Escape |
VISUAL, EDITOR |
External editor fallback when externalEditor is unset |
HTTP_PROXY, HTTPS_PROXY |
Proxy outbound HTTP requests |
Provider credentials such as ANTHROPIC_API_KEY, OPENAI_API_KEY, and provider-specific configuration are listed in Providers.