# How Ponytail Works as an OpenCode Server Plugin: Architecture and Implementation

> Discover how Ponytail functions as an OpenCode server plugin, registering commands, saving settings, and enhancing LLM prompts for better performance. Explore its architecture and implementation.

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

---

**Ponytail operates as a self-contained module-style OpenCode server plugin that registers slash commands, persists user-selected intensity modes to local state, and injects filtered rulesets into the LLM system prompt on every turn.**

Ponytail is a specialized tool for OpenCode servers that enforces minimal-code-focus behavior through persistent configuration and automatic prompt engineering. According to the DietrichGebert/ponytail source code, the plugin is delivered as a single ES module (`.opencode/plugins/ponytail.mjs`) that wires together state management, command registration, and system prompt transformation to create an intensity-aware coding assistant.

## Plugin Entry Point and Module Structure

The plugin follows OpenCode’s module-style architecture. When the server loads, it executes the default export from `.opencode/plugins/ponytail.mjs`, which initializes three core subsystems.

### State Persistence Layer

Ponytail stores the active intensity mode in `~/.config/opencode/.ponytail-active`. The plugin exposes two utility functions for managing this state:

- **`readMode()`** – Reads the persisted mode from disk
- **`writeMode()`** – Persists the selected mode (lines 33‑44 in `ponytail.mjs`)

The default mode resolution logic lives in **[`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js)**. The `getDefaultMode()` function checks (in order) the `PONYTAIL_DEFAULT_MODE` environment variable, a configuration file, and finally falls back to `"full"` if no state exists.

### Instruction Generation

The **[`hooks/ponytail-instructions.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-instructions.js)** module exports `getPonytailInstructions(mode)`, which loads [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) and filters the master ruleset based on the requested intensity. If the mode is `off`, the function returns an empty string; if `review`, it returns a short behavior definition line; otherwise it returns the full filtered skill text appropriate for `lite`, `full`, or `ultra` intensities.

## Slash Command Registration

During the `config` hook, Ponytail scans the `command/` directory for markdown files and parses their front matter using **`hooks/ponytail-frontmatter.cjs`**. The parsed definitions are injected into `config.command`, registering the `/ponytail …` commands that users invoke to switch modes or trigger built-in skills.

When a user executes a command like `/ponytail ultra`, the `command.execute.before` hook (lines 89‑96 in `ponytail.mjs`) triggers. This handler calls `writeMode("ultra")` to persist the new state, ensuring subsequent chat turns respect the updated intensity.

## System Prompt Injection

Ponytail’s primary mechanism for influencing LLM behavior is the **`experimental.chat.system.transform`** hook. This hook runs on every LLM turn and performs the following steps:

1. Reads the current mode via `readMode()`
2. Generates tailored instructions via `getPonytailInstructions(mode)`
3. Appends the resulting text to the system prompt

This transformation happens silently, giving OpenCode an **always-on ruleset** that adapts to the user's selected intensity level without manual prompt engineering.

## Installation and Configuration

To activate Ponytail as an OpenCode server plugin, add the module reference to your [`opencode.json`](https://github.com/DietrichGebert/ponytail/blob/main/opencode.json) configuration:

```json
{
  "plugin": ["@dietrichgebert/ponytail"]
}

```

For local development or custom forks, reference the file directly:

```json
{
  "plugin": ["./.opencode/plugins/ponytail.mjs"]
}

```

### Customizing the Default Mode

Set the `PONYTAIL_DEFAULT_MODE` environment variable before starting the server to override the fallback behavior:

```bash
export PONYTAIL_DEFAULT_MODE=lite
node my-open-code-server.js

```

The `getDefaultMode()` function in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js) reads this variable during initialization. If no state file exists at `~/.config/opencode/.ponytail-active`, the server starts with the specified default intensity.

### Manual Instruction Loading

For testing or debugging, you can load the instruction set directly in a Node.js script:

```javascript
import { getPonytailInstructions } from './hooks/ponytail-instructions.js';

const instr = getPonytailInstructions('full');
console.log(instr);   // Prints filtered SKILL.md rules for "full" mode

```

## Summary

- Ponytail is a **module-style OpenCode server plugin** delivered as `.opencode/plugins/ponytail.mjs`.
- It persists user preferences to `~/.config/opencode/.ponytail-active` using `readMode()` and `writeMode()`.
- Default modes are resolved via `getDefaultMode()` in [`hooks/ponytail-config.js`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/ponytail-config.js), respecting the `PONYTAIL_DEFAULT_MODE` environment variable.
- Slash commands are auto-registered by parsing markdown files in `command/` with `hooks/ponytail-frontmatter.cjs`.
- The `experimental.chat.system.transform` hook injects filtered rules from [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) into every LLM system prompt via `getPonytailInstructions()`.
- The plugin is **self-contained**, requiring only a single entry in [`opencode.json`](https://github.com/DietrichGebert/ponytail/blob/main/opencode.json) to enable persistent, intensity-aware coding assistance.

## Frequently Asked Questions

### How do I install Ponytail as an OpenCode server plugin?

Add `"@dietrichgebert/ponytail"` to the `plugin` array in your [`opencode.json`](https://github.com/DietrichGebert/ponytail/blob/main/opencode.json) file. For local testing, use the relative path to `.opencode/plugins/ponytail.mjs` instead of the npm package name.

### What intensity modes does Ponytail support?

Ponytail supports four primary intensity levels—`lite`, `full`, `ultra`, and `off`—plus a specialized `review` mode. The `off` mode disables prompt injection entirely, while `review` provides a lightweight behavior definition rather than the full ruleset.

### Where does Ponytail store the active mode between sessions?

The plugin writes the current mode to `~/.config/opencode/.ponytail-active` on your filesystem. This state file is read at the start of every chat turn to determine which ruleset to inject into the system prompt.

### How does Ponytail modify the LLM's behavior without changing my code?

Ponytail uses the `experimental.chat.system.transform` hook to append filtered instructions from [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) to the system prompt automatically. This happens on every turn, ensuring the LLM follows the minimal-code-focus rules appropriate to your selected intensity level.