Ponytail

Lazy senior dev skill — DietrichGebert/ponytail

1 — 概要

Ponytail は、AI コーディングエージェントに「lazy senior dev」の判断基準を注入するスキル配布パッケージ。YAGNI・標準ライブラリ・ネイティブ機能を優先し、依存追加や抽象化レイヤーを書く前に止まる。セキュリティ・信頼境界の検証・アクセシビリティなど、削ってはいけない領域は例外として残す。

80–94%baseline 比 LOC 削減
3–6×レイテンシ短縮
47–77%コスト削減
10対応エージェント
設計の芯: skills/ponytail/SKILL.md が行動定義の正。AGENTS.md はスキル非対応ホスト向けのコンパクト版。各ホスト用ファイル(.cursor/rules/ など)は薄いアダプタで、コアを複製しない。

タスク「フォームに日付ピッカーを追加」への応答例(examples/date-picker.md より)。

スキルなし

flatpickr 導入、ラッパー、2 つの useEffect、CSS import。

npm install flatpickr
// + wrapper component (~30 lines)
Ponytail

依存 0・1 行。ブラウザ組み込みを採用。

<!-- ponytail: browser has one -->
<input type="date">

意図的な簡略化は ponytail: コメントで残し、上限とアップグレード経路を明示する。

2 — 6 段階ラダー

コードを書く前に上から順に確認し、成立する最初の段で止める。2 段が成立するなら上の段を選び、調査ループに入らない。

1
存在する必要があるか(YAGNI)
投機的需要ならスキップし、1 行で理由を述べる。
2
標準ライブラリで足りるか
言語・ランタイム付属 API を優先する。
3
ネイティブ機能で足りるか
<input type="date">、CSS、DB 制約などプラットフォーム機能を使う。
4
既存依存で足りるか
新規依存は数行で済む処理には追加しない。
5
1 行にできるか
成立するなら 1 行で書く。
6
最小の動く実装
上記すべて不可のときだけ、必要最小のコードを書く。
%%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f4f8', 'primaryTextColor': '#1a3a4a', 'primaryBorderColor': '#5a9aaa', 'lineColor': '#5a9aaa', 'fontSize': '14px'}}}%%
flowchart TD
  A[タスク受領] --> B{YAGNI?}
  B -->|不要| Z[スキップ + 1行説明]
  B -->|必要| C{stdlib?}
  C -->|Yes| R[採用して終了]
  C -->|No| D{native?}
  D -->|Yes| R
  D -->|No| E{既存 deps?}
  E -->|Yes| R
  E -->|No| F{1行?}
  F -->|Yes| R
  F -->|No| G[最小実装]
        
3 — 強度レベル

切り替え: /ponytail lite/ponytail full/ponytail ultra。終了は stop ponytail または normal mode。

レベル挙動例(API キャッシュ要求)
lite依頼どおり実装しつつ、より短い代替を 1 行で提示キャッシュ実装 +「functools.lru_cache で 1 行」の FYI
full(既定)ラダーを強制。最短 diff・最短説明@lru_cache(maxsize=1000)。カスタムキャッシュクラスは計測で不足が出るまで保留
ultraYAGNI 極大。削除優先。要件自体を問い直すプロファイラ結果があるまでキャッシュなし。必要時も lru_cache のみ
出力形式: コードを先に出し、説明は最大 3 行。[code] → skipped: [X], add when [Y]. 説明がコードより長い場合は説明を削る。
4 — ベンチマーク

5 タスク(メール検証、debounce、CSV 合計、React カウントダウン、FastAPI レート制限)× Haiku / Sonnet / Opus。各セル 10 回実行の中央値。アームは no skill / caveman / ponytail。

コード行数(LOC・中央値)

armHaikuSonnetOpus
baseline(no skill)518693256
caveman11612067
ponytail394451

コスト(USD・5 タスク合計)

armHaikuSonnetOpus
baseline0.0320.1410.135
caveman0.0140.0450.075
ponytail0.0100.0320.071

再現: npx promptfoo@latest eval -c benchmarks/promptfooconfig.yaml --repeat 10(リポジトリ内 benchmarks/)。caveman は prose 圧縮が主でコード量は ponytail より中間。実セッションではスキルが 1 回注入されプロンプトキャッシュされるため、コスト差はさらに広がる。

5 — エージェント対応

詳細は docs/agent-portability.md。アダプタは薄く保ち、可能なら既存 skills/ と hooks/ を参照する。

Claude Code
.claude-plugin/, commands/, hooks/
Codex
.codex-plugin/, hooks/, skills/
OpenCode
.opencode/plugins/, command/, hooks/
Pi harness
pi-extension/
Cursor
.cursor/rules/ponytail.mdc
Windsurf / Cline
.windsurf/rules/, .clinerules/
GitHub Copilot
.github/copilot-instructions.md
Kiro / 汎用
.kiro/steering/, AGENTS.md, skills/*

フック(Claude Code 例)

SessionStart で ponytail-activate.js がモードをロード。UserPromptSubmit で ponytail-mode-tracker.js がレベル変更を追跡する(hooks/hooks.json)。

6 — インストール

Claude Code

/plugin marketplace add DietrichGebert/ponytail
/plugin install ponytail@ponytail

Codex

codex plugin marketplace add DietrichGebert/ponytail
# /plugins でインストール → /hooks で 2 つの lifecycle hook を信頼

Pi agent harness

pi install git:github.com/DietrichGebert/ponytail

OpenCode

リポジトリを checkout したディレクトリから起動し、opencode.json にプラグインを追加:

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

Cursor など(ルールコピー)

.cursor/rules/ponytail.mdc 等をプロジェクトへコピー。ルール本文を変更したら node scripts/check-rule-copies.js で各コピーの整合を確認する。

設定ファイル: 必須ではない。セッション開始時に有効。Codex では @ponytail 等でスキルを明示呼び出し可能。
7 — スキルとコマンド
名前役割起動
ponytaillazy senior dev モード(ラダー・出力規律)常時 / /ponytail [lite|full|ultra]
ponytail-reviewdiff の過剰実装だけを狩るレビュー(正しさレビューとは別)/ponytail-review
ponytail-helpクイックリファレンス/ponytail-help

ponytail-review の出力形式

L12-38: stdlib: 27-line validator class. "@" in email, 1 line.
L4: native: moment.js for one format. Intl.DateTimeFormat, 0 deps.
L52-71: delete: retry wrapper around idempotent local call.

タグ: delete / stdlib / native / yagni / shrink。1 指摘 1 行。diff の最良結果は行数が減ること。

参考リンク