# How Ponytail Integrates with the Claude Statusline to Display the Active Mode

> Learn how Ponytail integrates with the Claude statusline to display active modes. Discover how this tool uses flag files and shell scripts for real-time visual feedback in your Claude environment.

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

---

**Ponytail adds a colored badge to the Claude Code statusline by writing the current mode to a hidden flag file at `$CLAUDE_CONFIG_DIR/.ponytail-active` and executing a shell script that reads this file to generate the display text.**

Ponytail statusline integration relies on a file-based signaling mechanism that bridges JavaScript activation hooks with platform-specific shell scripts. The DietrichGebert/ponytail repository implements this architecture through three coordinated components that activate on session start, render dynamically during prompts, and clean up safely on uninstall. This ensures the active mode—whether `full`, `ultra`, or `off`—always appears in the Claude interface without requiring manual configuration beyond the initial setup nudge.

## The Three-Component Architecture

Ponytail's statusline integration consists of tightly-coupled parts operating across different execution contexts. The **activation hook** ([`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js)) initializes the mode state, the **statusline scripts** ([`hooks/ponytail-statusline.sh`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-statusline.sh) for Unix and `hooks/ponytail-statusline.ps1` for Windows) render the visual badge, and the **uninstall helper** ([`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js)) manages configuration cleanup. Each component interfaces with Claude's configuration directory to persist state between sessions.

## Step 1: Activation and Flag File Creation

### Session Start Hook ([`ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-activate.js))

On every `SessionStart`, Claude executes [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) to synchronize the Ponytail mode with the statusline. The script determines the default mode by calling `getDefaultMode()` and persists it by invoking `setMode(mode)`, which writes the value to `$CLAUDE_CONFIG_DIR/.ponytail-active`. This hidden flag file serves as the single source of truth for the current intensity level that the statusline will display.

### Helper Functions in [`ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-config.js)

The activation logic relies on utility functions defined in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js). The `getClaudeDir()` function resolves the configuration directory path, while `isShellSafe()` validates path strings before embedding them in shell commands. These helpers ensure cross-platform compatibility when constructing the statusline command strings that will execute in the user's shell environment.

## Step 2: Reading the Mode in the Statusline

When Claude renders the prompt interface, it executes the command defined in [`settings.json`](https://github.com/DietrichGebert/ponytail/blob/main/settings.json)'s `statusLine` field. Ponytail configures this to run platform-specific scripts that read the flag file and emit formatted text with ANSI color codes.

### Unix Implementation ([`ponytail-statusline.sh`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-statusline.sh))

The Unix script located at [`hooks/ponytail-statusline.sh`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-statusline.sh) reads `$CLAUDE_CONFIG_DIR/.ponytail-active` and outputs a colored badge via `printf`. For the default `full` mode, it prints green text using ANSI color code `38;5;108`:

```bash
printf '\033[38;5;108m[PONYTAIL]\033[0m'

```

### Windows Implementation (`ponytail-statusline.ps1`)

The PowerShell equivalent at `hooks/ponytail-statusline.ps1` performs the same operation for Windows environments. It reads the flag file and outputs the appropriate string with escape sequences compatible with Windows Terminal and PowerShell consoles.

### Color Coding and Output Format

For `ultra` mode, both scripts switch to amber coloring using code `38;5;173` and append the mode label to the badge:

```bash
printf '\033[38;5;173m[PONYTAIL:ULTRA]\033[0m'

```

The colored output appears directly in the Claude statusline, providing immediate visual feedback about the active processing intensity without consuming screen space.

## Step 3: Automatic Configuration Management

### Detecting Missing Statusline Configurations

During activation, [`ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-activate.js) checks whether `~/.claude/settings.json` contains a `statusLine` entry. If absent, the hook constructs a configuration snippet that invokes the appropriate platform-specific script. This detection happens automatically during the session initialization phase.

### The Setup Nudge Mechanism

Rather than silently modifying user settings, Ponytail emits a **setup nudge** that proposes adding the statusline configuration. The suggested snippet follows this JSON structure:

```json
{
  "statusLine": {
    "type": "command",
    "command": "bash \"/home/user/.claude/plugins/ponytail/hooks/ponytail-statusline.sh\""
  }
}

```

When users accept this prompt, Claude writes the configuration to [`settings.json`](https://github.com/DietrichGebert/ponytail/blob/main/settings.json), establishing the persistent integration. From that point forward, every prompt execution triggers the statusline script, which reads the current mode from the flag file in real-time.

## Safe Removal and Cleanup

### Selective Uninstall Logic ([`uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/uninstall.js))

The [`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js) file ensures that removing Ponytail does not destroy user-customized statuslines. During uninstallation, the script checks whether the existing `statusLine.command` value includes the substring `ponytail-statusline`. Only if this condition returns true does the uninstaller delete the configuration entry:

```javascript
if (statusLine.command.includes('ponytail-statusline')) {
  // remove only Ponytail's entry
}

```

This selective approach preserves any manually crafted statusline configurations that the user may have created independently of Ponytail.

## Summary

- Ponytail writes the active mode to `$CLAUDE_CONFIG_DIR/.ponytail-active` via `setMode(mode)` in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) during every session start.
- The statusline badge renders through platform-specific scripts ([`ponytail-statusline.sh`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-statusline.sh) for Unix, `ponytail-statusline.ps1` for Windows) that read the flag file and output colored ANSI text.
- Green color code `38;5;108` indicates `full` mode, while amber code `38;5;173` signals `ultra` intensity.
- Automatic configuration detection proposes a setup nudge when no statusline exists, inserting a command-type configuration into Claude's [`settings.json`](https://github.com/DietrichGebert/ponytail/blob/main/settings.json).
- The [`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js) utility performs surgical cleanup, removing only statusline entries that reference Ponytail's own scripts.

## Frequently Asked Questions

### How does Ponytail store the current mode between Claude sessions?

Ponytail persists the active mode by writing to a hidden flag file at `$CLAUDE_CONFIG_DIR/.ponytail-active`. The `setMode(mode)` function in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) handles this write operation during the `SessionStart` hook execution, ensuring the statusline script can read the current state even across Claude restarts.

### What happens to my custom statusline configuration when I uninstall Ponytail?

The uninstaller in [`scripts/uninstall.js`](https://github.com/DietrichGebert/ponytail/blob/main/scripts/uninstall.js) checks if your `statusLine.command` contains the string `ponytail-statusline`. If it detects Ponytail's script path, it removes the entry; if it finds any other command, it leaves the configuration untouched. This ensures that user-customized statuslines survive the uninstallation process.

### Why does the statusline badge display different colors for different modes?

The shell scripts use ANSI color codes to provide visual distinction between intensity levels. The script outputs green text (color `38;5;108`) for standard `full` mode and switches to amber (color `38;5;173`) when `ultra` mode is active. This immediate color change helps users visually confirm which Ponytail processing level is currently engaged.

### Where does Ponytail place its statusline scripts on different operating systems?

The repository includes two platform-specific implementations located in the `hooks/` directory. Unix-based systems (Linux and macOS) use [`hooks/ponytail-statusline.sh`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-statusline.sh), while Windows systems execute `hooks/ponytail-statusline.ps1`. The activation hook automatically detects the platform and suggests the appropriate script path in the configuration nudge.