# How Ponytail Persists Its Active Mode Across Sessions: Environment Variables vs. Config Files

> Learn how Ponytail keeps its active mode across sessions using environment variables or config files. Understand persistence for your developer workflow.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: how-to-guide
- Published: 2026-09-04

---

**Ponytail persists its active mode across sessions by checking the `PONYTAIL_DEFAULT_MODE` environment variable first, then falling back to a JSON configuration file at `~/.config/ponytail/config.json` (or `%APPDATA%\ponytail\config.json` on Windows), and finally defaulting to `"full"` if neither is set, while the in-memory `_current_mode` variable only lasts for the current Python process.**

Understanding how Ponytail persists its active mode across sessions requires examining the hierarchical configuration system implemented in the DietrichGebert/ponytail repository. The plugin uses a three-tier lookup mechanism to determine whether to run in `off`, `lite`, `full`, or `ultra` mode when a new Python process starts.

## How Ponytail Resolves the Active Mode at Startup

The resolution logic lives in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py) and follows a strict priority order. When the module loads, the `_default_mode()` function executes this cascade:

1. **Environment Variable Check** – The system looks for `PONYTAIL_DEFAULT_MODE` in the environment. If present, its value becomes the active mode immediately.
2. **Configuration File Lookup** – If the environment variable is unset, Ponytail attempts to read [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) from the user-specific configuration directory.
3. **Hardcoded Fallback** – When neither source provides a value, the constant `DEFAULT_MODE = "full"` defined in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py) takes effect.

### Environment Variable Override

The `PONYTAIL_DEFAULT_MODE` environment variable provides the highest priority configuration method. According to the source code in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py), this variable is checked first in the `_default_mode()` function, allowing users to temporarily override persistent settings without modifying files.

### User Configuration File

For persistent settings without environment variables, Ponytail reads [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) from a platform-specific directory. The `_config_dir()` function returns:

- `$XDG_CONFIG_HOME/ponytail` on Unix-like systems (falling back to `~/.config/ponytail`)
- `%APPDATA%\ponytail` on Windows

The file must contain a JSON object with a `defaultMode` key:

```json
{
  "defaultMode": "ultra"
}

```

### Built-in Default Fallback

If both the environment variable and configuration file are absent, the system uses the module constant `DEFAULT_MODE = "full"` defined in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py). This ensures the plugin never starts without a valid mode setting.

## In-Memory vs. Persistent State

A critical distinction exists between the current session mode and persisted defaults. When users run the `/ponytail <mode>` command, the `_handle_mode_command` function updates the module-level variable `_current_mode`.

**Important**: This variable exists only for the duration of the current Python process. It does not write to the configuration file or modify environment variables. Consequently, restarting the Python interpreter resets the mode to the value determined by the three-tier lookup, not the previous session's `_current_mode` value.

## Practical Configuration Examples

### Setting Mode via Environment Variable

Force `lite` mode for a single session or script:

```python
import os
os.environ["PONYTAIL_DEFAULT_MODE"] = "lite"
import ponytail  # Plugin picks up env var on import

```

### Creating a Persistent Config File

For permanent mode settings across all sessions, create the configuration file:

```json
// ~/.config/ponytail/config.json (Unix)
// %APPDATA%\ponytail\config.json (Windows)
{
  "defaultMode": "ultra"
}

```

### Runtime Mode Changes (Non-Persistent)

Switch modes temporarily within the current process using the internal API:

```python
from ponytail import _handle_mode_command, _current_mode

# Change for current session only

_handle_mode_command("lite")
print(_current_mode)  # Output: "lite"

# After process exit, next run uses env/config defaults

```

## Summary

- **Environment variable `PONYTAIL_DEFAULT_MODE`** takes precedence over all other settings for cross-session persistence.
- **Configuration file** at `~/.config/ponytail/config.json` (or Windows equivalent) stores persistent defaults when environment variables are unset.
- **Built-in fallback** `DEFAULT_MODE = "full"` in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py) ensures the plugin always starts with a valid mode.
- **In-memory `_current_mode`** set by `/ponytail` commands lasts only for the current Python process and does not persist to disk.
- **Mode values** must be one of: `off`, `lite`, `full`, or `ultra`.

## Frequently Asked Questions

### What is the exact order Ponytail uses to determine the active mode?

Ponytail checks sources in this strict order: first the `PONYTAIL_DEFAULT_MODE` environment variable, then the `defaultMode` key in `~/.config/ponytail/config.json` (or `%APPDATA%\ponytail\config.json` on Windows), and finally the hardcoded constant `DEFAULT_MODE = "full"` in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py). The first valid value found wins.

### Does the `/ponytail` command change my permanent settings?

No. Issuing `/ponytail <mode>` only updates the in-memory `_current_mode` variable via `_handle_mode_command`. This change affects only the current Python process. To make permanent changes, you must either set the `PONYTAIL_DEFAULT_MODE` environment variable or modify the [`config.json`](https://github.com/DietrichGebert/ponytail/blob/main/config.json) file directly.

### Where is the Ponytail configuration file located on different operating systems?

On Unix-like systems (Linux, macOS), Ponytail looks for `~/.config/ponytail/config.json` or `$XDG_CONFIG_HOME/ponytail/config.json`. On Windows, it uses `%APPDATA%\ponytail\config.json`. The `_config_dir()` function in [`ponytail/main/__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail/main/__init__.py) handles these platform-specific path resolutions automatically.

### What values are valid for the default mode setting?

According to the source code and documentation, valid mode values are `off`, `lite`, `full`, and `ultra`. These strings are case-sensitive and must match exactly when set in either the `PONYTAIL_DEFAULT_MODE` environment variable or the `defaultMode` JSON key.