How Ponytail Works as an OpenCode Server Plugin: Architecture and Implementation
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 diskwriteMode()– Persists the selected mode (lines 33‑44 inponytail.mjs)
The default mode resolution logic lives in 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 module exports getPonytailInstructions(mode), which loads 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:
- Reads the current mode via
readMode() - Generates tailored instructions via
getPonytailInstructions(mode) - 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 configuration:
{
"plugin": ["@dietrichgebert/ponytail"]
}
For local development or custom forks, reference the file directly:
{
"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:
export PONYTAIL_DEFAULT_MODE=lite
node my-open-code-server.js
The getDefaultMode() function in 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:
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-activeusingreadMode()andwriteMode(). - Default modes are resolved via
getDefaultMode()inhooks/ponytail-config.js, respecting thePONYTAIL_DEFAULT_MODEenvironment variable. - Slash commands are auto-registered by parsing markdown files in
command/withhooks/ponytail-frontmatter.cjs. - The
experimental.chat.system.transformhook injects filtered rules fromskills/ponytail/SKILL.mdinto every LLM system prompt viagetPonytailInstructions(). - The plugin is self-contained, requiring only a single entry in
opencode.jsonto 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 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 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.
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 →