# Where Does the .ponytail-active State File Live? Host-Specific Storage in Ponytail

> Discover where the .ponytail-active state file resides on different hosts like Claude Code, VS Code Copilot, and Qoder. Understand runtime environment detection for Ponytail.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: internals
- Published: 2026-09-12

---

**The `.ponytail-active` state file lives in host-specific directories such as `~/.claude/` for Claude Code, `~/.vscode/agent-plugins/<plugin>/` for VS Code Copilot, or `~/.qoder/` for Qoder, determined at runtime by environment detection logic in [`ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-runtime.js).**

Ponytail is an open-source AI coding assistant manager that tracks its activation mode—**off**, **lite**, **full**, **ultra**, or **review**—using a simple flag file. The exact location of this `.ponytail-active` state file varies depending on which host environment is running the extension, with the runtime dynamically selecting the appropriate directory based on environment variables and host detection.

## Native Claude (Codex) Host Location

When running in native Claude Code (Codex), the state file resides in the Claude configuration directory.

The system defaults to the directory returned by `getClaudeDir()` in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) (lines 71-74). This helper checks for the `CLAUDE_CONFIG_DIR` environment variable first, then falls back to `~/.claude` in the user's home directory.

```javascript
// hooks/ponytail-runtime.js lines 24-33 (simplified)
const stateDir = getClaudeDir();  // Returns process.env.CLAUDE_CONFIG_DIR || ~/.claude
const statePath = path.join(stateDir, '.ponytail-active');

```

**Full path:** `~/.claude/.ponytail-active` (or `$CLAUDE_CONFIG_DIR/.ponytail-active` if the override is set).

## VS Code Copilot Extension Location

For the VS Code Copilot integration, Ponytail checks for a plugin-specific data directory before falling back to the Claude directory.

The runtime examines `process.env.COPILOT_PLUGIN_DATA` (lines 24-29 in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)). If this variable is set—or if the installation path matches an agent-plugins structure under `.vscode`—that directory is used; otherwise, it defaults to `getClaudeDir()`.

**Full path:** `$COPILOT_PLUGIN_DATA/.ponytail-active` (typically resolving to `~/.vscode/agent-plugins/<plugin-name>/.ponytail-active`).

## Qoder Environment Location

When running under Qoder, the runtime detects the host via the `QODER_SESSION_ID` environment variable.

In this scenario (lines 29-33 in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)), the `stateDir` is explicitly set to `~/.qoder` using `path.join(os.homedir(), '.qoder')`.

**Full path:** `~/.qoder/.ponytail-active`.

## Runtime Path Resolution Logic

The file [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) contains the definitive logic for assembling the final path. It defines the constant `STATE_FILE = '.ponytail-active'` and joins it with the resolved `stateDir` based on the following priority:

1. **Qoder:** If `process.env.QODER_SESSION_ID` exists, use `~/.qoder`.
2. **Copilot:** If `process.env.COPILOT_PLUGIN_DATA` exists, use that path.
3. **Claude (Native):** Default to `getClaudeDir()` (respecting `CLAUDE_CONFIG_DIR` overrides).

This ensures each host maintains **independent state**, preventing mode conflicts when running multiple AI assistants simultaneously.

## Overriding the Default Directory

You can override the storage location for any host by setting the `CLAUDE_CONFIG_DIR` environment variable. As implemented in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) (lines 71-74), this variable takes precedence in the `getClaudeDir()` function:

```bash
export CLAUDE_CONFIG_DIR=/custom/path

# The state file will now be /custom/path/.ponytail-active

```

This override affects both native Claude usage and serves as the fallback for Copilot when `COPILOT_PLUGIN_DATA` is unavailable.

## Practical Examples for Locating the Flag

Use these commands to inspect the current state file on your system:

```bash

# Native Claude Code

cat ~/.claude/.ponytail-active

# VS Code Copilot (example path structure)

cat ~/.vscode/agent-plugins/ponytail/.ponytail-active

# Qoder environment

cat ~/.qoder/.ponytail-active

```

To programmatically resolve the path in JavaScript:

```javascript
const path = require('path');
const os = require('os');
const { getClaudeDir } = require('./hooks/ponytail-config');

function getStatePath() {
  let stateDir = getClaudeDir(); // ~/.claude or $CLAUDE_CONFIG_DIR
  
  if (process.env.COPILOT_PLUGIN_DATA) {
    stateDir = process.env.COPILOT_PLUGIN_DATA;
  } else if (process.env.QODER_SESSION_ID) {
    stateDir = path.join(os.homedir(), '.qoder');
  }
  
  return path.join(stateDir, '.ponytail-active');
}

console.log('State file location:', getStatePath());

```

## Summary

- **`.ponytail-active`** is the flag file that stores Ponytail's current operational mode (off, lite, full, ultra, or review).
- **Native Claude** stores the file at `~/.claude/.ponytail-active`, configurable via `CLAUDE_CONFIG_DIR`.
- **VS Code Copilot** uses `COPILOT_PLUGIN_DATA/.ponytail-active`, typically under `~/.vscode/agent-plugins/`.
- **Qoder** isolates state at `~/.qoder/.ponytail-active` when `QODER_SESSION_ID` is present.
- **Source files:** Path logic resides in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) (lines 24-33), with directory resolution helpers in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) (lines 71-74).
- The **[`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js)** utility removes this file via `removeIfExists(path.join(getClaudeDir(), '.ponytail-active'))` during cleanup.

## Frequently Asked Questions

### What filename does Ponytail use to store the active mode?

Ponytail uses a file named **`.ponytail-active`** (defined as the constant `STATE_FILE` in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js)). This file contains a string indicating the current mode: `off`, `lite`, `full`, `ultra`, or `review`.

### Can I move the .ponytail-active file to a custom directory?

Yes. Set the `CLAUDE_CONFIG_DIR` environment variable to your desired path. The `getClaudeDir()` function in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) prioritizes this variable over the default `~/.claude` directory. For Copilot-specific overrides, set `COPILOT_PLUGIN_DATA` instead.

### Why does the state file location differ between Copilot and Claude?

Each host runs as a separate process with distinct extension directories and permission models. According to the source code in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js), isolating the `.ponytail-active` file prevents mode conflicts—for example, preventing a "full" mode setting in VS Code Copilot from unintentionally affecting a Claude Code session running in the same user environment.

### How do I clean up the state file when uninstalling?

The [`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js) script automatically removes the file by calling `removeIfExists(path.join(getClaudeDir(), '.ponytail-active'))`. To manually clean up, delete the file from the host-specific directory: `~/.claude/.ponytail-active` for Claude, your Copilot plugin data directory for VS Code, or `~/.qoder/.ponytail-active` for Qoder.