@dietrichgebert/ponytail 4.8.1 → 4.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.es.md CHANGED
@@ -14,6 +14,7 @@
14
14
  <p align="center">
15
15
  <img src="https://img.shields.io/github/stars/DietrichGebert/ponytail?style=flat-square&color=111111&label=stars" alt="Stars">
16
16
  <img src="https://img.shields.io/github/v/release/DietrichGebert/ponytail?style=flat-square&color=111111&label=release" alt="Release">
17
+ <img src="https://img.shields.io/npm/v/@dietrichgebert/ponytail?style=flat-square&color=111111&label=npm" alt="npm">
17
18
  <img src="https://img.shields.io/badge/funciona%20con-14%20agentes-111111?style=flat-square" alt="Works with 14 agents">
18
19
  <img src="https://img.shields.io/badge/licencia-MIT-111111?style=flat-square" alt="MIT license">
19
20
  </p>
@@ -150,7 +151,13 @@ pi install git:github.com/DietrichGebert/ponytail
150
151
 
151
152
  ### OpenCode
152
153
 
153
- Ejecuta OpenCode desde un checkout de este repo (el plugin reutiliza sus `hooks/` y `skills/`), y agrega esto a `opencode.json`:
154
+ Agrega esto a `opencode.json`:
155
+
156
+ ```json
157
+ { "plugin": ["@dietrichgebert/ponytail"] }
158
+ ```
159
+
160
+ O ejecútalo desde un checkout (el plugin reutiliza sus `hooks/` y `skills/`):
154
161
 
155
162
  ```json
156
163
  { "plugin": ["./.opencode/plugins/ponytail.mjs"] }
package/README.ko.md ADDED
@@ -0,0 +1,277 @@
1
+ <p align="center">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="assets/logo-dark.png">
4
+ <img src="assets/logo.png" width="220" alt="Ponytail, the lazy senior dev">
5
+ </picture>
6
+ </p>
7
+
8
+ <h1 align="center">Ponytail</h1>
9
+
10
+ <p align="center">
11
+ <em>말이 없다. 한 줄을 쓴다. 돌아간다.</em>
12
+ </p>
13
+
14
+ <p align="center">
15
+ <img src="https://img.shields.io/github/stars/DietrichGebert/ponytail?style=flat-square&color=111111&label=stars" alt="Stars">
16
+ <img src="https://img.shields.io/github/v/release/DietrichGebert/ponytail?style=flat-square&color=111111&label=release" alt="Release">
17
+ <img src="https://img.shields.io/npm/v/@dietrichgebert/ponytail?style=flat-square&color=111111&label=npm" alt="npm">
18
+ <img src="https://img.shields.io/badge/works%20with-14%20agents-111111?style=flat-square" alt="Works with 14 agents">
19
+ <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
20
+ </p>
21
+
22
+ <p align="center">
23
+ <strong>코드 약 54% 감소(최대 94%) &middot; 약 20% 저렴 &middot; 약 27% 빠름 &middot; 100% 안전</strong><br>
24
+ <sub>실제 오픈소스 저장소(FastAPI + React)를 고치는 실제 Claude Code 세션에서, 스킬을 끈 같은 에이전트와 견줘 측정했다. 약 54%는 기능 작업 12건의 평균이다(Haiku 4.5, n=4). 에이전트가 과하게 짤 여지가 있는 곳(날짜 선택기)에선 94%까지 오르고, 코드가 이미 최소한인 곳에선 0에 가깝다. ponytail은 안전 가드를 하나도 빼놓지 않지만, 그냥 "한 줄로 써"라고만 시킨 프롬프트는 그중 하나를 놓친다. (예전 단발성 벤치마크는 80-94%를 단일 수치로 내세웠는데, 공정한 에이전트 기준선에 견주면 그건 평균이 아니라 작업별 상한이다.) <a href="benchmarks/results/2026-06-18-agentic.md">전체 보고서</a> &middot; <a href="benchmarks/">직접 재현하기</a>.</sub>
25
+ </p>
26
+
27
+ <p align="center">
28
+ <sub>커뮤니티 번역이다. 기준이 되는 최신 버전은 <a href="README.md">영어 README</a>다.</sub>
29
+ </p>
30
+
31
+ ---
32
+
33
+ 이런 사람, 다들 알 거다. 긴 포니테일에 타원형 안경. 버전 관리 시스템보다 회사에 오래 있었다. 코드 쉰 줄을 들이밀면 잠깐 보더니, 말없이 한 줄로 바꿔 놓는다.
34
+
35
+ Ponytail은 그를 당신의 AI 에이전트 안에 앉혀 둔다.
36
+
37
+ ## Before / after
38
+
39
+ 날짜 선택기 하나 만들어 달라고 한다. 에이전트는 flatpickr를 깔고, 래퍼 컴포넌트를 짜고, 스타일시트를 붙이더니, 타임존 얘기를 꺼내기 시작한다.
40
+
41
+ ponytail이라면:
42
+
43
+ ```html
44
+ <!-- ponytail: browser has one -->
45
+ <input type="date">
46
+ ```
47
+
48
+ 살아남은 것들이 더 궁금하다면 [examples/](examples/)로.
49
+
50
+ ## Numbers
51
+
52
+ 공정하게 재려면 실제 에이전트에게 실질적인 작업을 시켜 봐야 한다. 헤드리스 Claude Code 세션에게 [tiangolo의 full-stack-fastapi-template](https://github.com/fastapi/full-stack-fastapi-template)(진짜 FastAPI + React 저장소)을 맡기고, 남긴 `git diff`로 점수를 매겼다. 기능 티켓 12건, 같은 에이전트를 스킬만 켜고 끄며 비교, n=4, Haiku 4.5.
53
+
54
+ <p align="center">
55
+ <img src="assets/benchmark-agentic.svg" width="860" alt="Each arm as a percent of the no-skill baseline across LOC, tokens, cost and time (Haiku 4.5). ponytail is lowest on every metric (LOC 46%, tokens 78%, cost 80%, time 73%); caveman rises above 100% on tokens, cost and time; yagni-oneliner LOC 67%. Safety, separate adversarial tier: baseline, caveman and ponytail 100%, yagni-oneliner 95%.">
56
+ </p>
57
+
58
+ | 스킬 없는 기준선 대비 | LOC | tokens | cost | time | safe |
59
+ |---|--:|--:|--:|--:|--:|
60
+ | **ponytail** | **-54%** | **-22%** | **-20%** | **-27%** | **100%** |
61
+ | caveman (간결한 산문 대조군) | -20% | +7% | +3% | +2% | 100% |
62
+ | "YAGNI + one-liners" 프롬프트 | -33% | -14% | -21% | -30% | 95% |
63
+
64
+ 모든 지표를 깎은 건 ponytail뿐이고, 그러면서 안전까지 온전히 지킨 것도 ponytail뿐이다. 깎이는 폭은 과잉 구현의 함정이 실제로 있는 곳에서 가장 크다. 컴포넌트 대신 네이티브 `<input>`으로 손이 가니 날짜 선택기는 404줄에서 23줄로, 색상 선택기는 287줄에서 23줄로 줄어든다. 반대로 이미 군더더기 없는 코드에선 거의 0이다. 전체 방법론, 작업별 표, 한계는 [benchmarks/results/2026-06-18-agentic.md](benchmarks/results/2026-06-18-agentic.md)에 있다.
65
+
66
+ <details>
67
+ <summary><strong>예전 단발성 수치 (격리된 생성)</strong></summary>
68
+
69
+ 일상적인 작업 다섯 가지, 모델 셋, 비교군 셋(스킬 없음, [caveman](https://github.com/JuliusBrussee/caveman), ponytail), 10회 실행, 중앙값 기준. 프롬프트 하나에 응답 하나, 답변의 줄 수를 셌다:
70
+
71
+ <p align="center">
72
+ <img src="assets/benchmark-3model.svg" width="860" alt="Median lines of code per arm across Haiku, Sonnet and Opus">
73
+ </p>
74
+
75
+ 여기선 **코드 80-94% 감소**가 나왔다. 다만 [#126](https://github.com/DietrichGebert/ponytail/issues/126)이 맞게 짚었듯, 스킬을 전혀 안 붙인 기준선 모델은 답변을 설명과 선택지로 부풀린다. 그래서 그 격차의 일부는 대화형 기준선이 만들어 낸 착시다. 위의 에이전트 수치가 그걸 바로잡은, 근거 있는 버전이다. 단발성 실행은 `npx promptfoo eval -c benchmarks/promptfooconfig.yaml`로 재현할 수 있다.
76
+
77
+ </details>
78
+
79
+ **규칙은 애초에 "토큰 최소화"가 아니었다.** 작업에 필요한 만큼만 쓰되, 검증·에러 처리·보안·접근성은 절대 덜어내지 않는다는 것이다. 코드가 작아지는 건 억지로 줄여서가 아니라 딱 그만큼만 필요해서다. 비용과 지연이 낮아지는 것도 단계를 충실히 밟는 모델에서나 부수적으로 딸려 오는 효과일 뿐이다. 그 단계를 고민하느라 사고 토큰을 쏟는 간결한 추론 모델은 오히려 거꾸로 갈 수도 있다(GPT-5.5가 그렇다).
80
+
81
+ ## How it works
82
+
83
+ 코드를 쓰기 전에, 에이전트는 가장 먼저 들어맞는 단계에서 멈춘다:
84
+
85
+ ```
86
+ 1. 이게 있을 필요가 있나? → 없다: 건너뛴다 (YAGNI)
87
+ 2. 이미 이 코드베이스에 있나? → 다시 짜지 말고 가져다 쓴다
88
+ 3. 표준 라이브러리로 되나? → 쓴다
89
+ 4. 네이티브 플랫폼 기능인가? → 쓴다
90
+ 5. 깔려 있는 의존성이 푸나? → 쓴다
91
+ 6. 한 줄로 되나? → 한 줄
92
+ 7. 그제서야: 돌아가는 최소한
93
+ ```
94
+
95
+ 단계를 밟는 건 문제를 이해한 *다음*이지, 이해를 대신하는 게 아니다. 변경이 닿는 코드를 읽고 실제 흐름을 따라가 본 뒤에야 단계를 고른다. 해법에는 게을러도, 읽는 데는 절대 게으르지 않다.
96
+
97
+ 게으른 거지 부주의한 게 아니다. 신뢰 경계의 검증, 데이터 손실 방지, 보안, 접근성은 결코 잘려 나가지 않는다.
98
+
99
+ ## Install
100
+
101
+ ponytail이 당신에게 요구할 수고의 최대치:
102
+
103
+ Claude Code와 Codex 플러그인은 자그마한 Node.js 라이프사이클 훅 두 개를 돌리니, `node`가 PATH에 잡혀 있어야 한다(Nix/nvm 사용자라면 비대화형 셸의 PATH에 있어야 한다). 없어도 스킬은 멀쩡히 돌아간다. 다만 늘 켜져 있던 자동 활성화가 매 프롬프트마다 에러를 뱉는 대신 조용히 비활성으로 남을 뿐이다.
104
+
105
+ ### Claude Code
106
+
107
+ ```
108
+ /plugin marketplace add DietrichGebert/ponytail
109
+ ```
110
+ ```
111
+ /plugin install ponytail@ponytail
112
+ ```
113
+ (설치가 되려면 두 프롬프트를 따로 보내야 한다)
114
+
115
+ 데스크톱 앱에는 `/plugin` 명령이 없다. 대신 UI에서 설치한다: Customize, 개인 플러그인 옆의 +, Create plugin and add marketplace, Add from repository, 그다음 저장소 URL 입력(감사합니다 @NiklasDHahn, #98).
116
+
117
+ ### Codex
118
+
119
+ ```bash
120
+ codex plugin marketplace add DietrichGebert/ponytail
121
+ codex
122
+ ```
123
+
124
+ `/plugins`를 열어 Ponytail 마켓플레이스를 고르고 Ponytail을 설치한다. 그런 다음
125
+ `/hooks`를 열어 라이프사이클 훅 두 개를 검토하고 신뢰한 뒤, 새 스레드를 시작한다.
126
+
127
+ 이 설치 한 번이면 Codex 데스크톱 앱도 같이 잡힌다. 설치 후 앱을 다시 켜면 플러그인을 알아챈다.
128
+
129
+ ### GitHub Copilot CLI
130
+
131
+ ```bash
132
+ copilot plugin marketplace add DietrichGebert/ponytail
133
+ copilot plugin install ponytail@ponytail
134
+ ```
135
+
136
+ 대화형 Copilot CLI 세션에서는 슬래시 명령으로 똑같이 하면 된다:
137
+
138
+ ```
139
+ /plugin marketplace add DietrichGebert/ponytail
140
+ /plugin install ponytail@ponytail
141
+ ```
142
+
143
+ Copilot CLI는 플러그인 명령에 그 이름을 네임스페이스로 붙인다. 예를 들면:
144
+
145
+ ```text
146
+ /ponytail:ponytail ultra
147
+ /ponytail:ponytail-review
148
+ ```
149
+
150
+ ### Pi agent harness
151
+
152
+ ```
153
+ pi install git:github.com/DietrichGebert/ponytail
154
+ ```
155
+
156
+ ### OpenCode
157
+
158
+ `opencode.json`에 다음을 더한다:
159
+
160
+ ```json
161
+ { "plugin": ["@dietrichgebert/ponytail"] }
162
+ ```
163
+
164
+ 체크아웃에서 직접 돌려도 된다(플러그인이 `hooks/`와 `skills/`를 그대로 쓴다):
165
+
166
+ ```json
167
+ { "plugin": ["./.opencode/plugins/ponytail.mjs"] }
168
+ ```
169
+
170
+ 매 턴마다 지금 레벨의 룰셋을 주입하고, `/ponytail` 명령들을 붙여 준다([Commands](#commands) 참고). OpenCode는 이 저장소의 `AGENTS.md`도 알아서 불러오니, 플러그인이 없어도 규칙은 살아 있다. 플러그인은 `lite/full/ultra/off` 레벨을 얹어 준다.
171
+
172
+ `./` 경로는 프로젝트의 `opencode.json`을 기준으로 풀린다. 체크아웃 하나를 여러 프로젝트에서 같이 쓰려면, 대신 `.mjs`의 절대 경로를 가리키면 된다(그 파일은 제 위치를 기준으로 `hooks/`와 `skills/`를 찾는다).
173
+
174
+ ### Gemini CLI
175
+
176
+ ```bash
177
+ gemini extensions install https://github.com/DietrichGebert/ponytail
178
+ ```
179
+
180
+ 매 세션 룰셋을 늘 켜진 컨텍스트로 불러오고 `/ponytail` 명령들을 등록한다. `skills/`도 함께 실리며, 작업에 필요할 때 켜진다.
181
+ Gemini 어댑터는 일부러 루트 `hooks/hooks.json`을 두지 않는다. Gemini는 그 경로를 자동으로 불러오는데, ponytail의 라이프사이클 훅은 Claude/Codex 이벤트 이름을 쓰기 때문이다.
182
+
183
+ ### Antigravity CLI
184
+
185
+ Google이 Gemini CLI를 Antigravity CLI(`agy` 바이너리)로 이름을 바꾸는 중인데, 같은 확장이 거기에도 설치된다:
186
+
187
+ ```bash
188
+ agy plugin install https://github.com/DietrichGebert/ponytail
189
+ ```
190
+
191
+ 이 저장소의 `gemini-extension.json`을 그대로 재사용한다. 차이는 하나다. Antigravity는 `/ponytail` 명령들을 스킬로 바꿔 버려서, 슬래시 메뉴에서 고르는 대신 채팅에 직접 친다(예: `/ponytail-review`를 메시지로). 전환이 마무리될 때까지(2026년 6월 18일경)는 `gemini extensions install`도 여전히 먹힌다. 늘 켜진 규칙으로 돌리고 싶으면, 룰셋을 `.agents/rules/`에 넣으면 된다.
192
+
193
+ ### CodeWhale
194
+
195
+ 프로젝트 루트의 `AGENTS.md`를 읽고, 설정은 전혀 필요 없다. [`AGENTS.md`](AGENTS.md)를 프로젝트에 복사하거나, 이 저장소를 체크아웃한 곳에서 `codewhale`을 돌리면 된다. 그게 끝이다.
196
+
197
+ ### Swival
198
+
199
+ 먼저 컬렉션을 라이브러리에 스테이징한 다음, 원하는 스킬을 더한다:
200
+
201
+ ```bash
202
+ swival skills add --global https://github.com/DietrichGebert/ponytail # ~/.config/swival/library에 스테이징
203
+ swival skills add ponytail # 이 프로젝트에 컬렉션 설치
204
+ swival skills add --global ponytail # 또는 모든 프로젝트에서 켜기
205
+ ```
206
+
207
+ Swival도 프로젝트 루트의 `AGENTS.md`와 전역의 `~/.config/swival/AGENTS.md`를 읽는다. 지시문 전용 폴백이다.
208
+
209
+ 명령줄에서는 `$` 접두사로 스킬을 명시적으로 켠다. 예: `$ponytail-review`.
210
+
211
+ ### OpenClaw
212
+
213
+ ```bash
214
+ clawhub install ponytail
215
+ ```
216
+
217
+ ClawHub에서 ponytail을 OpenClaw 스킬로 설치한다. review, audit, debt, gain, help 스킬도 같은 식으로 깐다(`clawhub install ponytail-review` 등). OpenClaw는 코딩 작업에 이를 적용하고 `/ponytail` 명령으로도 열어 준다. ClawHub가 없으면 [`.openclaw/skills/ponytail`](.openclaw/skills/)을 `~/.openclaw/skills/`에 복사하면 된다.
218
+
219
+ 이게 끝이었다. 그 사람이라면 흐뭇해할 거다. 입 밖으로 내진 않겠지만.
220
+
221
+ 매 세션 켜져 있고, 명령 몇 개가 딸려 온다([Commands](#commands) 참고). `/ponytail ultra`는 코드베이스가 당신에게 단단히 밉보인 날을 위해 있다. 시작할 때와 모드를 바꿀 때 지금 모드를 보여 준다.
222
+
223
+ 새 세션마다 적용할 레벨은 `PONYTAIL_DEFAULT_MODE` 환경 변수(`lite`/`full`/`ultra`/`off`)로, 또는 `~/.config/ponytail/config.json`의 `defaultMode` 필드(Windows에선 `%APPDATA%\ponytail\config.json`)로 정한다. 기본값은 `full`이다.
224
+
225
+ Cursor, Windsurf, Cline, GitHub Copilot(에디터), Aider, Kiro, Zed, CodeWhale: 이 저장소에서 맞는 규칙 파일을 복사하면 된다([`.cursor/rules/`](.cursor/rules/), [`.windsurf/rules/`](.windsurf/rules/), [`.clinerules/`](.clinerules/), [`.github/copilot-instructions.md`](.github/copilot-instructions.md), [`AGENTS.md`](AGENTS.md), [`.kiro/steering/`](.kiro/steering/)).
226
+
227
+ Kiro: `.kiro/steering/ponytail.md`를 `~/.kiro/steering/`(전역)이나 프로젝트의 `.kiro/steering/`에 복사한다.
228
+
229
+ GitHub Copilot CLI 폴백(지시문 전용 모드): 프로젝트의 `AGENTS.md`와 `.github/copilot-instructions.md`를 읽거나, 모든 프로젝트에서 ponytail을 돌리려면 규칙을 `~/.copilot/copilot-instructions.md`에 복사한다. 이 경로는 늘 켜진 가이드는 살리지만, 플러그인 모드 전환이나 훅은 더해 주지 않는다.
230
+
231
+ Codex 확장을 쓰는 VS Code는 이 저장소가 함께 싣는 `AGENTS.md`를 읽으니, 저장소 루트에서 설정 없이 돌아간다(`~/.codex/AGENTS.md`를 두면 Codex 전역으로 잡힌다).
232
+
233
+ 어떤 파일이 어느 에이전트에 매핑되는지: [Agent portability](docs/agent-portability.md).
234
+
235
+ ## Commands
236
+
237
+ | 명령 | 하는 일 |
238
+ |---------|--------------|
239
+ | `/ponytail [lite \| full \| ultra \| off]` | 강도를 정하거나, 끈다. 인수가 없으면 지금 레벨을 알려 준다. |
240
+ | `/ponytail-review` | 지금 diff를 과잉 구현 관점에서 훑고, 삭제 목록을 돌려준다. |
241
+ | `/ponytail-audit` | diff만이 아니라 저장소 전체를 과잉 구현 관점에서 감사한다. |
242
+ | `/ponytail-debt` | 미뤄 둔 `ponytail:` 간소화들을 장부로 모아, "나중에"가 "영영"이 되지 않게 한다. |
243
+ | `/ponytail-gain` | 벤치마크로 잰 효과 스코어보드(코드 절감, 비용 절감, 속도 향상)를 보여 준다. |
244
+ | `/ponytail-help` | 위 명령들의 빠른 참조. |
245
+
246
+ 명령들은 스킬을 지원하는 호스트가 있어야 돈다(Claude Code, Codex, OpenCode, Gemini, pi). Codex에선 스킬이라 `@`로 부른다(`@ponytail-review`). 지시문 전용 어댑터(Cursor, Windsurf, Cline, Copilot, Kiro, Antigravity)는 명령 없이 늘 켜진 룰셋만 불러온다.
247
+
248
+ ## Development
249
+
250
+ 압축 규칙 텍스트를 바꿀 때는, 에이전트 사본들을 같은 상태로 맞춰 둔다:
251
+
252
+ ```bash
253
+ node scripts/check-rule-copies.js
254
+ npm test
255
+ ```
256
+
257
+ OpenClaw 스킬 패키지(`.openclaw/skills/`)는 `skills/`에서 생성된다. 스킬을 바꾼 뒤에는 `node scripts/build-openclaw-skills.js`를 다시 돌린다. 묵은 상태면 테스트 스위트가 실패한다.
258
+
259
+ 정확성 벤치마크는 이메일·CSV 검사를 위해 Python을 띄운다. `python`보다 `python3`를 먼저 시도한다. CSV 검사는 로컬에 `pandas`가 깔려 있어야 한다.
260
+
261
+ ## FAQ
262
+
263
+ **설정 파일이 필요한가?**
264
+ 아니다. 선택 사항인 `~/.config/ponytail/config.json`이나 `PONYTAIL_DEFAULT_MODE` 환경 변수로 기본 레벨을 정할 순 있지만, 꼭 있어야 하는 건 없다.
265
+
266
+ **그래도 120줄짜리 캐시 클래스가 정말 필요하다면?**
267
+ 필요 없다. 그래도 우기면 그가 만들어 준다. 천천히. 정확하게. 당신을 쳐다보면서.
268
+
269
+ **확장은 되나?**
270
+ 당신이 안 쓴 코드는 무한히 확장된다. 버그 0, CVE 0, 가동률 100%. 예나 지금이나.
271
+
272
+ **왜 하필 "ponytail"인가?**
273
+ 당신은 이유를 정확히 안다.
274
+
275
+ ## License
276
+
277
+ [MIT](LICENSE). 돌아가는 가장 짧은 라이선스.
package/README.md CHANGED
@@ -14,6 +14,7 @@
14
14
  <p align="center">
15
15
  <img src="https://img.shields.io/github/stars/DietrichGebert/ponytail?style=flat-square&color=111111&label=stars" alt="Stars">
16
16
  <img src="https://img.shields.io/github/v/release/DietrichGebert/ponytail?style=flat-square&color=111111&label=release" alt="Release">
17
+ <img src="https://img.shields.io/npm/v/@dietrichgebert/ponytail?style=flat-square&color=111111&label=npm" alt="npm">
17
18
  <img src="https://img.shields.io/badge/works%20with-14%20agents-111111?style=flat-square" alt="Works with 14 agents">
18
19
  <img src="https://img.shields.io/badge/license-MIT-111111?style=flat-square" alt="MIT license">
19
20
  </p>
@@ -24,7 +25,7 @@
24
25
  </p>
25
26
 
26
27
  <p align="center">
27
- <sub><a href="README.es.md">Español</a></sub>
28
+ <sub><a href="README.es.md">Español</a> &middot; <a href="README.ko.md">한국어</a></sub>
28
29
  </p>
29
30
 
30
31
  ---
@@ -170,8 +171,6 @@ Injects the ruleset every turn at the active level; adds the `/ponytail` command
170
171
 
171
172
  The `./` path resolves against your project's `opencode.json`; to share one checkout across projects, point it at the absolute path of the `.mjs` instead (it finds its `hooks/` and `skills/` relative to its own file).
172
173
 
173
- The plugin path loads the ruleset everywhere, but the `/ponytail` commands are separate files in `.opencode/command/` that OpenCode only discovers from your project or the global commands dir. To use them outside this checkout, link them once: `ln -sf /absolute/path/to/ponytail/.opencode/command/* ~/.config/opencode/command/`.
174
-
175
174
  ### Gemini CLI
176
175
 
177
176
  ```bash
@@ -14,6 +14,19 @@
14
14
  ]
15
15
  }
16
16
  ],
17
+ "SubagentStart": [
18
+ {
19
+ "hooks": [
20
+ {
21
+ "type": "command",
22
+ "command": "node \"${CLAUDE_PLUGIN_ROOT}/hooks/ponytail-subagent.js\"; exit 0",
23
+ "commandWindows": "if (Get-Command node -ErrorAction SilentlyContinue) { node \"$env:CLAUDE_PLUGIN_ROOT\\hooks\\ponytail-subagent.js\" }",
24
+ "timeout": 5,
25
+ "statusMessage": "Loading ponytail mode..."
26
+ }
27
+ ]
28
+ }
29
+ ],
17
30
  "UserPromptSubmit": [
18
31
  {
19
32
  "hooks": [
@@ -21,6 +21,15 @@ function clearMode() {
21
21
  try { fs.unlinkSync(statePath); } catch (e) {}
22
22
  }
23
23
 
24
+ // Live mode written by activate/mode-tracker. Absent flag = ponytail off.
25
+ function readMode() {
26
+ try {
27
+ return fs.readFileSync(statePath, 'utf8').trim() || null;
28
+ } catch (e) {
29
+ return null;
30
+ }
31
+ }
32
+
24
33
  function writeHookOutput(event, mode, context = '') {
25
34
  if (isCopilot) {
26
35
  // Copilot reads additionalContext on SessionStart; ignores output elsewhere.
@@ -39,6 +48,13 @@ function writeHookOutput(event, mode, context = '') {
39
48
  process.stdout.write(JSON.stringify(output));
40
49
  return;
41
50
  }
51
+ // Native Claude: SessionStart accepts raw stdout, but SubagentStart needs the
52
+ // hookSpecificOutput JSON form or the context is dropped.
53
+ if (event === 'SubagentStart') {
54
+ process.stdout.write(JSON.stringify(
55
+ { hookSpecificOutput: { hookEventName: event, additionalContext: context } }));
56
+ return;
57
+ }
42
58
  process.stdout.write(context);
43
59
  }
44
60
 
@@ -46,6 +62,7 @@ module.exports = {
46
62
  clearMode,
47
63
  isCodex,
48
64
  isCopilot,
65
+ readMode,
49
66
  setMode,
50
67
  writeHookOutput,
51
68
  };
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ // ponytail — Claude Code SubagentStart hook
3
+ //
4
+ // SessionStart context is parent-thread only and never reaches subagents, so
5
+ // without this every Task-spawned agent runs ponytail-unaware (issue #252).
6
+ // When ponytail mode is active, inject the same ruleset into each subagent.
7
+
8
+ const { getPonytailInstructions } = require('./ponytail-instructions');
9
+ const { readMode, writeHookOutput } = require('./ponytail-runtime');
10
+
11
+ const mode = readMode();
12
+
13
+ // Absent flag or off → ponytail isn't active; inject nothing.
14
+ if (!mode || mode === 'off') {
15
+ process.exit(0);
16
+ }
17
+
18
+ try {
19
+ writeHookOutput('SubagentStart', mode, getPonytailInstructions(mode));
20
+ } catch (e) {
21
+ // Silent fail — a stdout error at hook exit must not surface as a hook failure.
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dietrichgebert/ponytail",
3
- "version": "4.8.1",
3
+ "version": "4.8.3",
4
4
  "description": "Lazy senior dev mode for AI agents. The best code is the code you never wrote.",
5
5
  "keywords": ["opencode-plugin", "opencode", "ponytail", "pi-package", "pi", "skills"],
6
6
  "license": "MIT",