# How Ponytail Tracks User Prompt Commands: Architecture and Implementation

> Discover how Ponytail tracks user prompt commands by rewriting CLI inputs into structured agent prompts and persisting them to a local cache. Understand the architecture and implementation behind this powerful feature.

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

---

**Ponytail tracks every user command by rewriting CLI inputs into structured agent prompts via `_skill_prompt` in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py), then persists them through the mode-tracker hook to a local cache file at `$HOME/.cache/ponytail/commands.log`.**

Ponytail, an open-source agent framework maintained in the DietrichGebert/ponytail repository, implements a comprehensive audit system that captures every user interaction. Understanding how Ponytail tracks user prompt commands reveals the mechanics behind its reproducible debugging capabilities and intelligent suggestion engine.

## The Skill Prompt Rewriter

The entry point for command tracking begins in the core initialization logic. When a user executes any Ponytail sub-command—such as `ponytail-review` or `ponytail-help`—the system immediately transforms the raw CLI input into a format the agent can process.

### Rewriting CLI Commands

Inside [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py), the private function `_skill_prompt` handles this transformation. It accepts the command name and its arguments, then formats them into a natural-language prompt. The function returns a JSON object containing an `"action": "rewrite"` marker, signaling that the input has been processed for agent consumption. This rewriting step is critical because it standardizes diverse command syntax into a unified message stream that downstream components can monitor consistently.

### Injecting Messages into Context

Once reformatted, the prompt enters the agent's message stream through `ctx.inject_message(prompt)`. This injection mechanism makes the command visible to all hooks and monitoring components attached to the session context. By centralizing command input through this injection point, Ponytail ensures that every user instruction—regardless of origin—passes through a single observable channel.

## The Mode-Tracker Hook

While the rewriter prepares the command for the agent, the mode-tracker hook handles persistence. Implemented in [`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js), this component monitors the contextual state of the active agent session and captures each injected prompt for the audit trail.

### Session State Monitoring

The hook activates whenever `ctx.inject_message` fires, extracting the command name, arguments, and current timestamp from the injected payload. It writes these details to a per-session log file stored in the hidden `.ponytail/` directory within the user's home folder. This chronological record enables the `ponytail-audit` command to reconstruct exact interaction sequences later.

### Log File Structure

Each entry in the session log follows a structured JSON format. A typical log line appears as:

```json
{"command":"ponytail-review","args":"src/app.py","timestamp":"2026-09-06T12:34:56Z"}

```

This schema captures the essential metadata needed for debugging and compliance auditing without storing excessive sensitive data.

## Cache Persistence Layer

For long-term storage, Ponytail leverages a dedicated cache system implemented in the `ponytail-mcp` package. The cache provides a simple key-value store that appends each rewritten prompt to `commands.log`.

### Unix-like Cache Directory

On Unix-like systems, the cache resides at `$HOME/.cache/ponytail/`. The implementation in [`ponytail-mcp/index.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/index.js) handles file appending and rotation, ensuring that the command history persists across agent restarts. This location serves as the definitive source for diagnostic tools and audit skills that need to analyze historical command patterns.

## Complete Execution Flow

The following Python example illustrates the complete tracking pipeline from user input to persistent storage:

```python

# User executes: ponytail-review src/app.py

# 1. __init__.py rewrites the CLI call

prompt = _skill_prompt("ponytail-review", "src/app.py")

# Returns: {"action": "rewrite", "text": "Review the file src/app.py ..."}

# 2. Inject into agent context

ctx.inject_message(prompt)

# 3. Mode-tracker hook records to commands.log

# Resulting JSON line appended to $HOME/.cache/ponytail/commands.log:

# {"command":"ponytail-review","args":"src/app.py","timestamp":"2026-09-06T12:34:56Z"}

```

## Key Implementation Files

Understanding the tracking architecture requires familiarity with these specific source files:

- **[`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py)**: Contains the `_skill_prompt` function that transforms CLI commands into agent-compatible prompts with `action: rewrite` markers.

- **[`hooks/ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-mode-tracker.js)**: Implements the monitoring hook that listens for injected messages and writes chronological logs to the `.ponytail/` directory.

- **[`ponytail-mcp/index.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/index.js)**: Manages the cache layer where `commands.log` persists across sessions, typically under `$HOME/.cache/ponytail/`.

- **`commands/*.toml`**: Declares available Ponytail sub-commands that flow through the `_skill_prompt` rewriter.

- **[`tests/commands.test.js`](https://github.com/DietrichGebert/ponytail/blob/main/tests/commands.test.js)**: Validates the prompt rewriting logic and ensures accurate logging behavior.

## Summary

- **Rewriting Layer**: The `_skill_prompt` function in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py) converts raw CLI commands into structured JSON prompts with `"action": "rewrite"` markers before injection.
- **Monitoring Layer**: The mode-tracker hook in [`ponytail-mode-tracker.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mode-tracker.js) captures every injected prompt with timestamps to per-session logs in the `.ponytail/` directory.
- **Persistence Layer**: The `ponytail-mcp` cache implementation appends commands to `$HOME/.cache/ponytail/commands.log` for long-term audit trails.
- **Integration**: This three-tier architecture enables reproducible debugging, compliance auditing, and intelligent suggestions based on historical interaction patterns.

## Frequently Asked Questions

### Where does Ponytail store the command history?

Ponytail stores command history in two locations: per-session logs in the hidden `.ponytail/` directory within the user's home folder, and a persistent cache file at `$HOME/.cache/ponytail/commands.log` on Unix-like systems. The cache implementation in [`ponytail-mcp/index.js`](https://github.com/DietrichGebert/ponytail/blob/main/ponytail-mcp/index.js) handles the key-value append operations to this file, ensuring data persists across agent restarts.

### What triggers the command tracking mechanism?

The tracking mechanism triggers when `_skill_prompt` in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py) processes a user command and `ctx.inject_message()` broadcasts the rewritten prompt. The mode-tracker hook listens for these specific injection events and immediately records the command details, arguments, and timestamp to the audit log before the agent executes the task.

### How does Ponytail format tracked commands for the audit log?

Each tracked command is serialized as a JSON object containing the command name, arguments, and ISO timestamp. For example: `{"command":"ponytail-review","args":"src/app.py","timestamp":"2026-09-06T12:34:56Z"}`. This standardized format enables efficient parsing by the `ponytail-audit` diagnostic tool and supports structured querying of historical interactions.

### Can developers access the prompt rewriting logic for custom commands?

Yes. Developers can leverage the `_skill_prompt` function in [`__init__.py`](https://github.com/DietrichGebert/ponytail/blob/main/__init__.py) by passing custom command names and arguments to generate properly formatted prompts with the required `"action": "rewrite"` structure. This ensures custom commands integrate seamlessly with the existing mode-tracker and cache persistence layers, maintaining full audit capability across the framework.