Ponytail: la skill que convierte a Claude Code en un senior perezoso
Le pides a un agente un selector de fecha. Instala flatpickr, escribe un componente envoltorio, añade una hoja de estilos y abre un debate sobre zonas horarias. Lo que querías era esto:
<!-- ponytail: browser has one -->
<input type="date">
Ese es el ejemplo con el que abre su README Ponytail, un plugin para Claude Code (y para otra veintena de agentes) que a principios de octubre pasa de las 154.000 estrellas en GitHub, más que Agency Agents, del que hablé hace un par de semanas. Pero aquí la comparación termina, porque Ponytail va justo en la dirección contraria: no te da 273 personalidades, te da una sola, y su trabajo es conseguir que el agente escriba menos.
Como con Agency Agents, lo he clonado y he leído lo que hay dentro antes de opinar. Si no tienes claro qué es una skill, empieza por el post sobre skills en Claude Code; aquí doy eso por sabido.
Qué es, en una frase
Ponytail es un conjunto de reglas sobre lo que tu agente no debería construir. Lo mantiene Dietrich Gebert en github.com/DietrichGebert/ponytail, es MIT, nació en junio de 2026 y va por la versión 4.10.3.
El nombre viene de un personaje que todos hemos conocido: el veterano de la coleta y las gafas ovaladas que lleva en la empresa más tiempo que el control de versiones. Le enseñas cincuenta líneas, las mira, no dice nada y las sustituye por una. El README lo resume con una frase que me hizo gracia: «He says nothing. He writes one line. It works.»
Técnicamente, en Claude Code no es una skill suelta sino un plugin que trae seis skills y tres hooks. Volveré sobre esto porque es lo más importante del post.
La escalera
Todo Ponytail cabe en una escalera de siete peldaños. Antes de escribir código, el agente se detiene en el primero que se sostenga:
1. ¿Hace falta que esto exista? → no: no se hace (YAGNI)
2. ¿Ya está en este código? → reutilízalo, no lo reescribas
3. ¿Lo hace la librería estándar? → úsala
4. ¿Lo cubre la plataforma? → úsala
5. ¿Lo resuelve una dependencia
que ya tienes instalada? → úsala
6. ¿Cabe en una línea? → una línea
7. Solo entonces: lo mínimo que funcione
El matiz que separa esto de un «escribe menos código» a secas está en el propio SKILL.md: la escalera se recorre después de entender el problema, no en lugar de entenderlo. Primero se lee el código que toca el cambio y se sigue el flujo real; luego se sube. «Perezoso con la solución, nunca con la lectura». Y para los bugs, la regla es arreglar la causa raíz en la función compartida, no poner un parche en el único sitio que menciona el ticket.
Hay una lista explícita de cosas que nunca se recortan: validación de entrada en las fronteras de confianza, manejo de errores que evita pérdida de datos, seguridad, accesibilidad básica y cualquier cosa que hayas pedido expresamente. Si insistes en la versión completa, la construye sin volver a discutir.
Y una convención que me parece lo mejor del invento: cuando el agente toma un atajo deliberado con un techo conocido (un lock global, un recorrido O(n²), una heurística ingenua), lo marca con un comentario ponytail: que dice cuál es el techo y cuándo habría que mejorarlo:
# ponytail: global lock, per-account locks if throughput matters
Instalación en Claude Code
Son dos órdenes, y el README insiste en que van en dos mensajes separados:
/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytail
Requisito previo: node tiene que estar en el PATH, y en concreto en el PATH de una shell no interactiva (aviso para quien use nvm o Nix). Los hooks están escritos en Node. Si no lo encuentra, las skills siguen funcionando, pero cada llamada a un hook te escupe un node: command not found inofensivo y molesto.
En la app de escritorio, en la pestaña Code, vale lo mismo: escribes los dos /plugin en el prompt o vas por + → Plugins → Add plugin.
Para actualizar, la skill de ayuda recomienda activar la actualización automática desde /plugin → Marketplaces → ponytail. A mano:
/plugin marketplace update ponytail
/reload-plugins
Y para desinstalar hay una trampa que conviene leer antes de instalar. /plugin remove ponytail borra los ficheros del plugin, pero Ponytail deja estado fuera de su carpeta: el fichero de modo en ~/.claude/.ponytail-active, la configuración en ~/.config/ponytail/config.json y, si aceptaste la oferta, una entrada statusLine en tu ~/.claude/settings.json. Para limpiar eso está node scripts/uninstall.js, que hay que ejecutar antes del /plugin remove, porque el script es parte del plugin y desaparece con él. Si llegas tarde, lo ejecutas desde un clon aparte del repo.
Niveles
Ponytail viene activado por defecto en cada sesión, en nivel full. Hay tres niveles más el apagado:
/ponytail lite
/ponytail full
/ponytail ultra
/ponytail off
El SKILL.md los explica con el mismo encargo, «añade una caché para estas respuestas de la API», y me parece la mejor forma de entenderlos:
- lite: construye lo que pides, pero te dice en una línea cuál era la alternativa perezosa. «Hecho, caché añadida. Por cierto:
functools.lru_cachehace esto en una línea si no quieres mantener una clase de caché». - full: la escalera aplicada. «
@lru_cache(maxsize=1000)en la función de fetch. Me he saltado la clase de caché propia; añádela cuandolru_cachese quede corto de forma medible». - ultra: el integrista del YAGNI. «Nada de caché hasta que lo diga un profiler. Cuando lo diga:
@lru_cache. Una clase de caché con TTL hecha a mano es una granja de bugs con tasa de aciertos».
El README lo dice con más gracia: /ponytail ultra existe para cuando el código base te ha ofendido personalmente.
Para apagarlo también basta con escribir stop ponytail o normal mode, y /ponytail a secas lo vuelve a encender. El nivel dura hasta que lo cambias o termina la sesión. Si quieres otro por defecto para todas las sesiones, tienes una variable de entorno, que manda sobre todo lo demás:
export PONYTAIL_DEFAULT_MODE=lite
o un fichero ~/.config/ponytail/config.json:
{ "defaultMode": "lite" }
Ese fichero también lo puedes escribir desde dentro de la sesión con /ponytail default lite. Con off como valor por defecto, Ponytail no arranca solo y lo activas con /ponytail cuando lo quieras.
Las otras cinco skills
Además del modo en sí, el plugin trae cinco skills de un solo disparo:
/ponytail-reviewrevisa el diff actual buscando solo sobreingeniería. Una línea por hallazgo, con una etiqueta:delete,stdlib,native,reuse,yagnioshrink. Termina connet: -<N> lines possible.o, si no hay nada que quitar, con un secoLean already. Ship./ponytail-audithace lo mismo pero con todo el repositorio, ordenado de mayor a menor recorte./ponytail-debtrecoge todos los comentariosponytail:en un libro de deuda, y marca comono-triggerlos que no dicen cuándo habría que volver sobre ellos. Que son, como dice la propia skill, los que se pudren en silencio./ponytail-gainenseña un marcador con los números del benchmark./ponytail-help, la chuleta.
Los ejemplos de formato que da la skill de revisión te dicen exactamente qué esperar:
L4: native: moment.js imported for one format call. Intl.DateTimeFormat, 0 deps.
L18-29: reuse: slugify helper duplicates src/lib/slug.ts slugify. Delete it, import the existing one.
repo.py:L88: yagni: AbstractRepository with one implementation. Inline it until a second one exists.
Dos detalles. Primero, tanto la revisión como la auditoría declaran fuera de su alcance los bugs de corrección, la seguridad y el rendimiento: no sustituyen a una revisión normal, la complementan. Segundo, como todo plugin, sus skills viven en su propio espacio de nombres; si en el menú de barras no ves /ponytail-review tal cual, búscala como /ponytail:ponytail-review.
Lo que hace por dentro, y por qué importa
Aquí está lo que más me interesa, y es lo que no cuenta la portada.
En el post sobre skills defendía que su gracia es la carga diferida: solo la description está siempre en contexto y el cuerpo entra cuando hace falta. Ponytail, en Claude Code, no funciona así. El plugin registra tres hooks:
SessionStart(al arrancar, reanudar, limpiar o compactar): inyecta el cuerpo de la skill principal, filtrado al nivel activo, como contexto oculto.UserPromptSubmit: vigila tus mensajes para detectar/ponytail lite,stop ponytaily compañía, y cambiar de modo.SubagentStart: inyecta el mismo reglamento en cada subagente que se lance.
He medido el texto que inyecta: unos 5.200 caracteres en cualquiera de los tres niveles, unas 880 palabras en inglés. No es una barbaridad, pero es un peaje fijo en cada sesión y en cada subagente, lo uses para programar o para preguntar por la sintaxis de rsync. Es la decisión correcta para lo que pretende (una regla que solo se aplica cuando el modelo se acuerda de cargarla no es una regla), pero conviene saber que estás pagando lo mismo que si lo hubieras pegado en tu CLAUDE.md.
Si quieres que no llegue a todos los subagentes, por ejemplo a los de solo búsqueda, la variable PONYTAIL_SUBAGENT_MATCHER acepta una expresión regular que se compara con el tipo de agente. Sin anclar y sin distinguir mayúsculas: explore|general casa con cualquiera de los dos, ^general$ es exacto. Sin la variable, se inyecta en todos.
Y un aviso más. La primera vez que arranca, si no tienes una línea de estado configurada, el hook le pide a Claude que te ofrezca añadir una a tu ~/.claude/settings.json, con un indicador [PONYTAIL] o [PONYTAIL:ULTRA]. El hook no la escribe: se limita a pedirle a Claude que te lo proponga, y solo la primera vez. Pero que un plugin le diga al modelo que te proponga tocar tu configuración global es de las cosas que me gusta saber antes, no después.
Los números, con la letra pequeña
La portada promete ~54% menos código, ~20% más barato y ~27% más rápido, sin perder ni una salvaguarda de seguridad. El método está bien explicado: sesiones reales de Claude Code editando un repositorio real (la plantilla full-stack de FastAPI con React), doce tareas, cada una con y sin la skill, midiendo el git diff resultante.
Lo que me parece honesto es lo que viene detrás:
- Es un solo modelo, Haiku 4.5, con n=4 por tarea. Sonnet y Opus no se midieron en esa prueba por coste.
- El recorte medio esconde una distribución muy desigual: el selector de fecha pasa de 404 líneas a 23 y el de color de 287 a 23, pero en código que ya era mínimo la diferencia es casi cero. Ponytail ahorra donde hay una trampa de sobreconstrucción, no en general.
- Las primeras cifras que publicaron eran un 80-94% menos código. Alguien les señaló en una issue que la comparación base inflaba el número (el modelo sin skill rellenaba la respuesta con prosa y alternativas), rehicieron el benchmark y corrigieron la portada a la baja. En su documento de resultados lo reconocen sin rodeos.
- El README avisa además de que el ahorro de coste no es universal: un modelo de razonamiento escueto que gasta tokens de pensamiento deliberando sobre los peldaños puede acabar costando más, y con GPT-5.5 ocurre.
Una incoherencia que sí he visto: el marcador de /ponytail-gain sigue mostrando las cifras antiguas, el 80-94%, que el README ya da por infladas. Al menos la skill tiene la decencia de negarse a inventar cuánto has ahorrado tú en tu repo, porque la versión que no se escribió nunca existió y no hay con qué compararla. Esa frase, por cierto, está en el propio SKILL.md.
Trucos
/ponytail-reviewantes de abrir un PR. Es el uso que menos compromete: no cambia el comportamiento del agente, solo te da una lista de lo que sobra en el diff./ponytail-debtde vez en cuando. Si aceptas la convención de los comentariosponytail:, este es el mecanismo que impide que «ya lo haré» se convierta en «nunca».litepara empezar. Si no te fías, enliteel agente sigue haciendo lo que le pides y solo te señala la alternativa corta. Ves el criterio sin ceder el control.- Con Caveman, no en lugar de Caveman. El FAQ lo deja claro: Caveman acorta lo que el agente dice; Ponytail, lo que construye. No se pisan.
Limitaciones
- No es gratis en contexto: unas 880 palabras en cada sesión y en cada subagente, como he contado arriba.
- Necesita Node para los hooks. Sin él, te quedas con las skills pero sin el modo automático ni el cambio de nivel.
- Deja estado fuera de su carpeta, y desinstalarlo bien requiere ejecutar un script antes de quitar el plugin.
- Los números sólidos son de un modelo pequeño y doce tareas. Con modelos mayores el hueco puede cerrarse o abrirse; nadie lo ha medido en su benchmark agéntico.
- Las revisiones no buscan bugs ni agujeros de seguridad. Un
Lean already. Ship.no significa que el código esté bien.
Lo que opino
Que me cae bien, y no solo porque el chiste del veterano de la coleta sea bueno. Este blog no tiene base de datos, usa el router de la librería estándar de Go y su CLAUDE.md dice literalmente «preferir stdlib» y «no añadir dependencias externas sin justificación». La escalera de Ponytail es esa misma filosofía escrita para un modelo, y mejor redactada de lo que yo la tenía.
¿Podrías conseguir parte del efecto con cuatro líneas en tu CLAUDE.md? Probablemente sí, y el propio benchmark lo sugiere: un prompt de «YAGNI y una línea» recorta bastante. Pero ese prompt fue el único de los comparados que se dejó una salvaguarda de seguridad por el camino, y esa es la diferencia que justifica el invento: no es «escribe menos», es «escribe menos sin tocar lo que no se toca».
Lo que más me convence, de todas formas, no está en el código sino en cómo se comporta el proyecto. Publicaron un número espectacular, alguien les demostró que estaba inflado y lo bajaron en la portada, con un documento explicando por qué. En un ecosistema de repos de IA que compiten por estrellas a base de promesas, que alguien prefiera una cifra menor y defendible a una mayor y bonita dice mucho. Es exactamente lo que haría el de la coleta: mirar el número, no decir nada y quitarle la mitad.