# Environment variables

Your shell env passes through unchanged. Pane adds a few variables that describe the current pane, so your scripts, dev servers and agents know where they're running.

## Pane-injected variables

| Variable | Value |
|----------|-------|
| `PANE_WORKSPACE_PATH` | Absolute path to the folder the terminal started in. For a worktree pane, that's the pane's worktree. |
| `PANE_PORT` | The first port in a block of 10 reserved for this pane. Two panes never get the same block, so parallel dev servers don't fight over ports. |
| `PANE_SESSION_ID` | The pane's ID. It stays the same across restarts. |
| `PANE_PANEL_ID` | The ID of this tab inside the pane. |
| `PANE_ORCHESTRATION_SESSION_ID` | Only set in a [Session](/docs/sessions) chat. It's the Session's stable ID. |

They're there in every terminal tab, run script and agent Pane starts. On Windows, Pane also adds them to `WSLENV`, so they cross into WSL shells too.

Use `PANE_PORT` in your run script so every pane gets its own dev server port:

```json
{ "scripts": { "run": "PORT=$PANE_PORT pnpm dev" } }
```

### Commit attribution

Pane also sets `GIT_COMMITTER_NAME=Pane` and `GIT_COMMITTER_EMAIL=runpane@users.noreply.github.com` in the processes it starts. You stay the commit author. GitHub just shows "committed by Pane". Don't want that? Turn off **Settings → Worktrees & Git → Attribute commits to Pane**. New terminals stop getting them. Ones already running keep the env they started with.

## Setting env vars per pane

Three common patterns:

**1. Shell init script with conditional logic**

In `~/.zshrc` or `~/.bashrc`, branch on `PANE_WORKSPACE_PATH`:

```bash
if [[ "$PANE_WORKSPACE_PATH" == *"/api-pane"* ]]; then
  export ANTHROPIC_API_KEY="sk-ant-api-key..."
fi
```

**2. Per-pane `.envrc` with direnv**

Add a `.envrc` to the worktree root:

```bash
export ANTHROPIC_API_KEY="sk-ant-..."
export DATABASE_URL="postgres://localhost/myapp_dev"
```

Run `direnv allow` once in the pane's terminal. direnv re-loads the vars whenever you enter the directory. Install direnv from [direnv.net](https://direnv.net).

**3. Per-pane `.env` with dotenv-cli**

```bash
# .env in worktree root
ANTHROPIC_API_KEY=sk-ant-...
DATABASE_URL=postgres://localhost/myapp_dev
```

Prefix commands with `dotenv --`:

```bash
dotenv -- claude
```

Install with `npm install -g dotenv-cli`.

## Provider keys

Pane does not store provider API keys. Agents read keys directly from your shell environment. See [AI providers](/docs/providers) for the full list of `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, and other provider-specific variables.

## Avoiding collision in parallel panes

Two panes can run the same agent with different provider keys simultaneously:

<TerminalPreview lines={[
  { type: "output",  text: "# Pane A" },
  { type: "command", text: "export ANTHROPIC_API_KEY=\"sk-ant-account-a\"" },
  { type: "command", text: "claude" },
  { type: "output",  text: "" },
  { type: "output",  text: "# Pane B (separate shell)" },
  { type: "command", text: "export ANTHROPIC_API_KEY=\"sk-ant-account-b\"" },
  { type: "command", text: "claude" }
]} />

Each pane's shell is a separate process. Env vars set in one shell do not leak into another. Both agents run concurrently against their own keys with no interference.

## Related

- [AI providers](/docs/providers) — provider-specific env var names and docs links
- [MCP servers](/docs/mcp) — passing credentials to MCP servers
- [Security & permissions](/docs/security) — what Pane does and does not transmit off-device
