# How Ponytail Achieves Agent Portability: A Skill-First, Adapter-Thin Architecture

> Discover how Ponytail achieves agent portability with its skill-first, adapter-thin architecture. Deploy seamlessly across Claude, Codex, Gemini, and more LLM agents.

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

---

**Ponytail uses a skill-first, adapter-thin architecture where reusable Markdown-based skills combine with lightweight host-specific manifests to enable seamless deployment across Claude, Codex, Gemini, and other LLM agents.**

The DietrichGebert/ponytail repository solves LLM ecosystem fragmentation by treating **agent portability** as a core design constraint rather than an afterthought. Instead of rewriting logic for each host, the codebase centralizes functionality in language-agnostic definitions and surrounds them with minimal adapter glue. This ensures that a single update to a skill in [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) automatically propagates to every supported agent environment.

## Core Architectural Layers for Agent Portability

Ponytail organizes its codebase into five distinct layers that separate portable logic from host-specific integration.

### Skills: The Reusable Core

The **Skills** layer contains the reusable, language-model-agnostic behavior. Each skill is defined in a [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) file—such as [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) for the core lazy-developer mode or [`skills/ponytail-review/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-review/SKILL.md) for over-engineering detection—that contains the prompt template, expected inputs, and output format. Because these descriptions are pure Markdown, any agent capable of loading a file can invoke the skill unchanged without code execution.

### Hooks: Lifecycle Integration

**Hooks** provide optional lifecycle callbacks for activation, mode switching, and status-line updates. Stored as JSON payloads in files like [`hooks/claude-codex-hooks.json`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/claude-codex-hooks.json) and [`hooks/qoder-hooks.json`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/qoder-hooks.json), these map host-specific events to the generic skill set. Hosts that support hooks register the JSON file; others ignore it safely without breaking functionality.

### Commands: Host-Specific Invocation

The **Commands** layer translates user requests—such as `/ponytail-review`—into appropriate skill calls. Defined in TOML files within the `commands/` directory, these adapt to different hosts' slash-command UIs while the underlying skill file remains constant.

### Adapters: The Minimal Glue Layer

**Adapters** are thin manifests that tell each host where to find shared assets. For example, [`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json) points Claude to the relevant [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) files, while `.opencode/plugins/ponytail.mjs` provides a JavaScript loader for the OpenCode environment. According to the adapter rule documented in [`docs/agent-portability.md`](https://github.com/DietrichGebert/ponytail/blob/main/docs/agent-portability.md) (lines 37–39), these adapters merely reference the existing `skills/` and `hooks/` directories rather than duplicating logic. All adapters share the same `benchmarks/generate-examples.mjs` module for prompt building, preventing code duplication across hosts.

### AGENTS.md: The Universal Fallback

For "instruction-tier" agents like GitHub Copilot, Amp, or Zed that cannot load skills directly, the **Project-wide Instruction File** provides a compressed rule set. The [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md) file at the repository root distills the entire skill set into a compact format that these tools automatically discover, guaranteeing baseline functionality even without explicit adapter support.

## How the Adapter-Thin Design Works in Practice

The architecture enforces a **single source of truth** principle: core logic lives exclusively in the `skills/` directory, while adapters act as pure pointers. When a developer updates [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md), that change instantly reflects in Claude, Codex, OpenCode, and any other supported host because all adapters reference the same file paths. The shared instruction builder in `benchmarks/generate-examples.mjs` ensures consistent prompt construction across JavaScript-based adapters, while JSON hook files allow declarative lifecycle management without imperative code.

## Implementing Agent Portability: Code Examples

### Loading Skills in OpenCode

The OpenCode adapter demonstrates how a host loads Ponytail skills dynamically:

```javascript
import { loadSkill } from ".opencode/plugins/ponytail.mjs";

// Load the `ponytail` skill (lazy senior dev mode)
const ponytail = await loadSkill("ponytail");

// Invoke the skill with a task
const result = await ponytail.run({
  task: "Refactor this function to be more efficient",
});
console.log(result);

```

This loader imports the shared instruction builder and points to the same [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md) file used by all other adapters.

### Configuring the Claude Plugin

Claude integration requires only a JSON manifest in [`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json):

```json
{
  "name": "ponytail",
  "description": "Skill distribution for Claude agents",
  "plugins": [
    {
      "type": "skill",
      "path": "skills/ponytail/SKILL.md"
    }
  ],
  "hooks": "hooks/claude-codex-hooks.json"
}

```

Placing this file in the `.claude-plugin/` directory exposes the `/ponytail` command, which internally loads the shared skill definition.

### Static Invocation via AGENTS.md

For agents that only consume static instructions, trigger skills through the compact rule file:

```markdown
/ponytail

```

The agent reads the instruction from [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md) (lines 49–50) and executes the corresponding behavior without requiring dynamic skill loading capabilities.

### Bootstrapping a New Host Adapter

Adding support for a new LLM agent typically requires only a manifest file. Create [`plugin.yaml`](https://github.com/DietrichGebert/ponytail/blob/main/plugin.yaml) in the host's plugin directory:

```yaml
name: ponytail
version: "1.0"
skills:
  - path: skills/ponytail/SKILL.md
hooks:
  - path: hooks/qoder-hooks.json

```

This adapter instantly gains access to all six core Ponytail skills by referencing the existing `skills/` and `hooks/` directories, following the thin-adapter rule from [`docs/agent-portability.md`](https://github.com/DietrichGebert/ponytail/blob/main/docs/agent-portability.md).

## Summary

- **Skill-first architecture** places all logic in Markdown files like [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md), making behavior readable by any LLM.
- **Adapter-thin design** mandates that host integrations ([`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json), `.opencode/plugins/ponytail.mjs`) only point to shared assets rather than implementing logic.
- **Single source of truth** guarantees that updates to skill definitions propagate automatically to all supported agents.
- **JSON hooks** ([`hooks/claude-codex-hooks.json`](https://github.com/DietrichGebert/ponytail/blob/main/hooks/claude-codex-hooks.json)) provide optional lifecycle integration without mandating host support.
- **AGENTS.md fallback** ensures baseline functionality for instruction-tier agents like GitHub Copilot and Zed.

## Frequently Asked Questions

### What makes Ponytail's architecture agent-portable?

Ponytail achieves agent portability by decoupling skill logic from host integration. Core behaviors reside in plain-text [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) files that any LLM can ingest, while lightweight adapters handle the mechanical task of telling each host where to find these files. This separation allows the same skill to run across Claude, Codex, Gemini, and other environments without modification.

### How do adapters stay thin while supporting diverse hosts?

Adapters follow the rule documented in [`docs/agent-portability.md`](https://github.com/DietrichGebert/ponytail/blob/main/docs/agent-portability.md) (lines 37–39): they must only reference existing `skills/` and `hooks/` files or copy text from [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md). They never reimplement skill logic. For example, `.opencode/plugins/ponytail.mjs` simply imports the shared instruction builder and loads the skill, while [`.claude-plugin/plugin.json`](https://github.com/DietrichGebert/ponytail/blob/main/.claude-plugin/plugin.json) merely lists file paths.

### What happens if an LLM agent cannot load skills dynamically?

Agents without dynamic skill loading—such as GitHub Copilot, Amp, or Zed—automatically fall back to [`AGENTS.md`](https://github.com/DietrichGebert/ponytail/blob/main/AGENTS.md). This file, located at the repository root, contains a compact version of all skill instructions that these tools discover and apply as static project rules, ensuring baseline functionality without explicit adapter support.

### Where are the skill definitions stored?

Skill definitions live in the `skills/` directory, with each skill occupying its own subdirectory containing a [`SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/SKILL.md) file. For instance, the core lazy-developer skill resides at [`skills/ponytail/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail/SKILL.md), while the review skill is at [`skills/ponytail-review/SKILL.md`](https://github.com/DietrichGebert/ponytail/blob/main/skills/ponytail-review/SKILL.md). All adapters reference these exact file paths to ensure consistency.