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

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 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 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 (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 at lines 45-77.

Formatting Runtime Output

Finally, the hook calls writeHookOutput('SessionStart', mode, output) at lines 92-96 of 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 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:

// 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:


# 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 lines 34-38.

  • It injects mode-specific rulesets (lite, full, ultra) as hidden context via hooks/ponytail-activate.js lines 41-44.

  • Platform-specific serialization in 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, 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 and generates the corresponding ruleset during the emission phase. This mode-specific context is then passed to writeHookOutput() in 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 (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 file (lines 51-89) contains the platform-specific serialization logic that transforms the internal hook output into the format required by the host environment.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →