# What Is the SessionStart Hook in Ponytail? Bootstrap Logic and Implementation

> Discover the Ponytail SessionStart hook's role in initializing Claude-Code sessions. Learn how it writes flag files, injects rulesets, and adapts payloads for AI runtimes.

- Repository: [DietrichGebert/ponytail](https://github.com/DietrichGebert/ponytail)
- Tags: api-reference
- Published: 2026-08-30

---

**The SessionStart hook in Ponytail is the initialization trigger that activates the plugin for every new Claude-Code session by writing a flag file, injecting mode-specific rulesets, and adapting the payload format for the specific AI runtime environment.**

The SessionStart hook in Ponytail serves as the critical entry point that prepares the plugin infrastructure before the first LLM interaction occurs. As implemented in the DietrichGebert/ponytail repository, this hook orchestrates the bootstrapping sequence that enables the `lite`, `full`, or `ultra` operating modes across compatible AI coding assistants. When triggered, it executes a four-phase initialization protocol that ensures the AI receives the correct context and UI indicators from the very first turn.

## Core Responsibilities of the SessionStart Hook

The SessionStart hook implementation in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) performs four distinct operations to establish the Ponytail environment. Each step ensures that subsequent interactions operate with the correct configuration state and visual indicators.

### Writing the Activation Flag

First, the hook creates a marker file at `$CLAUDE_CONFIG_DIR/.ponytail-active` to signal that Ponytail is active for the current session. This flag allows other components to verify plugin status before executing runtime-specific logic. The file operation occurs in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) at lines 34-38.

### Injecting the Mode-Specific Ruleset

Second, the hook generates the appropriate ruleset based on the current mode (`lite`, `full`, or `ultra`) and prepares it as hidden context for the LLM. This payload is generated in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) (lines 41-44) and later consumed by the runtime hook to provide behavioral guidelines to the AI.

### Configuring the Status Line Badge

Third, the hook inspects the Claude settings to detect missing `statusLine` configurations and injects setup guidance into the emitted context. This ensures users see a visual "PONYTAIL" indicator in the UI, implemented in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) at lines 45-77.

### Formatting Runtime Output

Finally, the hook calls `writeHookOutput('SessionStart', mode, output)` at lines 92-96 of [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js), which delegates to the runtime-specific formatter. This abstraction allows Ponytail to support multiple AI platforms without modifying the core activation logic.

## Runtime-Specific Payload Adaptation

The [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) file handles platform-specific serialization, transforming the generic hook output into formats required by Copilot, Codex, Qoder, and native Claude environments. This adaptation occurs immediately after the SessionStart hook generates its internal payload.

- **Copilot**: Sends `additionalContext` objects only during SessionStart events (lines 51-56).

- **Codex**: Emits a `systemMessage` prefixed with `PONYTAIL:<MODE>` alongside optional `hookSpecificOutput` (lines 58-67).

- **Qoder**: Transmits only `hookSpecificOutput` without system messages (lines 69-80).

- **Native Claude**: Uses JSON-encoded payloads for `SubagentStart` events, while writing raw context strings for standard SessionStart operations (lines 82-89).

## Implementation Examples

When the SessionStart hook executes on a standard (non-off) startup, it writes a structured payload to stdout through the `writeHookOutput` function. The following JavaScript demonstrates the output structure generated by [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js):

```javascript
// Example: SessionStart hook output for a 'full' mode launch
// Source: hooks/ponytail-activate.js → writeHookOutput('SessionStart', mode, output)
process.stdout.write(JSON.stringify({
  hookSpecificOutput: {
    hookEventName: 'SessionStart',
    additionalContext: '...generated ruleset...'
  },
  systemMessage: 'PONYTAIL:FULL'   // Only emitted for Codex runtime
}));

```

For testing purposes, you can capture and assert the hook output using the test utilities provided in the repository. The following pattern validates that the SessionStart event properly emits the activation signal:

```python

# In a test you can assert the hook output

from tests.hooks.test import capture_hook_output

output = capture_hook_output('SessionStart')
assert 'PONYTAIL' in output  # ensures the rule set was emitted

```

## Summary

The SessionStart hook in Ponytail functions as the bootstrap mechanism that prepares the plugin environment across Claude-Code and compatible AI platforms. Key operational takeaways include:

- The hook writes `$CLAUDE_CONFIG_DIR/.ponytail-active` to persist activation state across components, as implemented in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) lines 34-38.

- It injects mode-specific rulesets (`lite`, `full`, `ultra`) as hidden context via [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) lines 41-44.

- Platform-specific serialization in [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) adapts the payload for Copilot, Codex, Qoder, or native Claude requirements.

- Status line configuration nudges ensure users receive visual confirmation of Ponytail activation in the UI.

## Frequently Asked Questions

### What triggers the SessionStart hook in Ponytail?

The SessionStart hook fires automatically at the beginning of every new Claude-Code or compatible AI session before the first user message is processed. According to the source code in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py), the plugin registers this hook via `pre_llm_call`, ensuring Ponytail initializes its context and configuration state immediately upon session creation.

### How does the SessionStart hook handle different operating modes?

The hook detects the current mode—`lite`, `full`, or `ultra`—through [`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js) and generates the corresponding ruleset during the emission phase. This mode-specific context is then passed to `writeHookOutput()` in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) (lines 92-96), which serializes the payload appropriately for the target runtime environment.

### What is the purpose of the .ponytail-active flag file?

The flag file created at `$CLAUDE_CONFIG_DIR/.ponytail-active` serves as a persistent marker that Ponytail is enabled for the current session, allowing other components like the runtime hook to verify activation status before processing subsequent events. This file is written during step one of the SessionStart sequence as implemented in [`hooks/ponytail-activate.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-activate.js) (lines 34-38).

### Why does the SessionStart hook format output differently for Copilot versus Codex?

Each AI platform expects distinct message structures: Copilot receives `additionalContext` objects, while Codex requires `systemMessage` strings prefixed with `PONYTAIL:<MODE>`. The [`hooks/ponytail-runtime.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-runtime.js) file (lines 51-89) contains the platform-specific serialization logic that transforms the internal hook output into the format required by the host environment.