What Is `hooks/ponytail-runtime.js`? Purpose and Implementation in Ponytail
hooks/ponytail-runtime.js is the central runtime helper that enables Ponytail to communicate its current mode to VS Code Copilot, Codex, Qoder, and native Claude by detecting the host environment, persisting state to disk, and formatting platform-specific hook outputs.
In the DietrichGebert/ponytail repository, hooks/ponytail-runtime.js functions as the unified communication layer between Ponytail's core logic and the various AI assistant platforms it supports. This single file abstracts environment detection, state management, and output formatting to ensure consistent "PONYTAIL:" signaling across different coding assistants.
Core Responsibilities of hooks/ponytail-runtime.js
Environment Detection (Lines 13-23)
The runtime begins by identifying which AI assistant is hosting Ponytail. As implemented in lines 13-23 of hooks/ponytail-runtime.js, the script sets three Boolean flags—isCopilot, isCodex, and isQoder—by inspecting the execution context. If none of these flags match, the system defaults to native Claude UI mode.
Mode Persistence (Lines 33-49)
To maintain state across sessions, the file manages a hidden .ponytail-active file stored in platform-specific directories. The setMode() function creates this file with the current mode string, while readMode() retrieves the stored value and clearMode() removes the file for cleanup. These operations rely on directory helpers from hooks/ponytail-config.js, which provides getClaudeDir() and getConfigDir() to locate the appropriate state directory for each environment.
Hook Output Formatting (Lines 51-90)
The writeHookOutput() function generates environment-specific JSON payloads based on the detected host. For VS Code Copilot, it emits additionalContext only during SessionStart events. Codex receives a systemMessage with the mode plus optional hookSpecificOutput, while Qoder gets similar formatting without the system message wrapper. For native Claude, the function sends raw additionalContext for SessionStart or wraps it in a hookSpecificOutput object for SubagentStart.
Working with hooks/ponytail-runtime.js: Practical Examples
The following examples demonstrate how to interact with the runtime's public API:
Setting and Reading the Current Mode
To activate Ponytail in live mode or check the current state:
const { setMode, readMode } = require('./hooks/ponytail-runtime');
// Activate live mode - creates .ponytail-active file
setMode('live');
// Read current state
const current = readMode(); // => 'live' | 'off' | null
console.log(`Ponytail is ${current || 'inactive'}`);
Emitting Formatted Output for VS Code Copilot
When running under Copilot, use writeHookOutput with the isCopilot flag:
const { writeHookOutput, isCopilot } = require('./hooks/ponytail-runtime');
if (isCopilot) {
writeHookOutput('SessionStart', 'live', 'Here is extra context');
// Output: {"additionalContext":"Here is extra context"}
}
Handling Native Claude Subagent Events
For native Claude UI subagent interactions:
const { writeHookOutput } = require('./hooks/ponytail-runtime');
writeHookOutput('SubagentStart', 'debug', 'debug information');
// Output: {"hookSpecificOutput":{"hookEventName":"SubagentStart","additionalContext":"debug information"}}
Integration with the Ponytail Ecosystem
hooks/ponytail-runtime.js imports directory resolution logic from hooks/ponytail-config.js, which exposes getClaudeDir() and getConfigDir(). The runtime's behavior is validated by tests/hooks.test.js and consumed by the TOML command definitions in commands/ponytail-*.toml that trigger setMode and clearMode operations.
Summary
- Environment detection:
hooks/ponytail-runtime.jsidentifies the host AI assistant (Copilot, Codex, Qoder, or native Claude) during initialization by settingisCopilot,isCodex, andisQoderflags. - Mode persistence: The runtime stores the current operational mode (live, off, or debug) in a
.ponytail-activefile usingsetMode(),readMode(), andclearMode(). - Output formatting: The
writeHookOutput()function emits JSON payloads tailored to each platform's expected input structure, handlingSessionStartandSubagentStartevents differently per environment. - Cross-agent consistency: By centralizing these responsibilities, the file ensures that all supported agents receive a consistent mode signal regardless of the underlying platform.
Frequently Asked Questions
What is the primary purpose of hooks/ponytail-runtime.js?
hooks/ponytail-runtime.js serves as the central runtime helper bridging Ponytail's core with AI assistant environments. It detects the host platform, persists modes to disk, and formats output for VS Code Copilot, Codex, Qoder, and Claude.
How does hooks/ponytail-runtime.js detect which AI assistant is running?
The runtime inspects execution context at lines 13-23 to set Boolean flags isCopilot, isCodex, and isQoder. If none match, it defaults to native Claude UI mode.
Where does Ponytail store the current mode state?
The runtime stores modes in a hidden .ponytail-active file via setMode(), using directories resolved by getClaudeDir() and getConfigDir() from hooks/ponytail-config.js. This handles Claude config, Copilot plugin data, and Qoder home paths.
Can I use functions from hooks/ponytail-runtime.js in my own scripts?
Yes, you can require the module to call setMode(), readMode(), or writeHookOutput() for custom integrations. However, it is designed primarily for internal use by Ponytail's TOML command definitions.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →