feat: add ponytail-audit skill (#20)
* Add ponytail-audit skill Whole-codebase audit for over-engineering. Scans a repository and produces a ranked report of things to delete, simplify, or replace with stdlib/native equivalents. * Drop counting-by-number heuristics: remove Phase 5 (structural audit) and TODO-age heuristic per review * feat: slim ponytail-audit and add cross-platform parity Rewrite the ponytail-audit skill to ponytail-review's lean shape (35 lines, was 111): same five tags, repo-wide scope, ranked output. Drop the prescriptive phase walkthrough, sampling rules, report template, and the license frontmatter that no other skill carries. Add the adapters the skill was missing so it ships on every supported platform the way ponytail-review does: - commands/ponytail-audit.toml - .opencode/command/ponytail-audit.md - pi-extension registerCommand (+ test) - agent-portability and README entries Co-authored-by: Alexander Brandt <github@a13x.de> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Emeriko <dietrich.gebert@gmail.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
Emeriko
parent
0882e2d256
commit
92efc4a648
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
description: Audit the whole repo for over-engineering, what can be deleted
|
||||||
|
---
|
||||||
|
|
||||||
|
Audit the entire repository for over-engineering only, not correctness. Scan the whole tree, not a diff. One line per finding, ranked biggest cut first: <tag> <what to cut>. <replacement>. [path]. Tags: delete (dead code/speculative feature), stdlib (reinvented standard library), native (dependency doing what the platform does), yagni (abstraction with one implementation), shrink (same logic, fewer lines). End with the net lines and dependencies removable. If nothing to cut: 'Lean already. Ship.'
|
||||||
@@ -99,14 +99,15 @@ Run OpenCode from a checkout of this repo (the plugin reuses its `hooks/` and `s
|
|||||||
{ "plugin": ["./.opencode/plugins/ponytail.mjs"] }
|
{ "plugin": ["./.opencode/plugins/ponytail.mjs"] }
|
||||||
```
|
```
|
||||||
|
|
||||||
Injects the ruleset every turn at the active level; adds `/ponytail` and `/ponytail-review`. OpenCode also auto-loads this repo's `AGENTS.md`, so the rules hold even without the plugin. The plugin adds the `lite/full/ultra/off` levels.
|
Injects the ruleset every turn at the active level; adds `/ponytail`, `/ponytail-review`, and `/ponytail-audit`. OpenCode also auto-loads this repo's `AGENTS.md`, so the rules hold even without the plugin. The plugin adds the `lite/full/ultra/off` levels.
|
||||||
|
|
||||||
That was it. He'd be proud. He won't say it.
|
That was it. He'd be proud. He won't say it.
|
||||||
|
|
||||||
Active every session. `/ponytail-review` finds what to delete in your diff. `/ponytail ultra` exists for when the codebase has wronged you personally. `/ponytail-help` explains the rest.
|
Active every session. `/ponytail-review` finds what to delete in your diff, `/ponytail-audit` does the same for the whole repo. `/ponytail ultra` exists for when the codebase has wronged you personally. `/ponytail-help` explains the rest.
|
||||||
|
|
||||||
In Codex, invoke the skills as `@ponytail`, `@ponytail-review`, and
|
In Codex, invoke the skills as `@ponytail`, `@ponytail-review`,
|
||||||
`@ponytail-help`. Startup and mode-change text shows the current mode.
|
`@ponytail-audit`, and `@ponytail-help`. Startup and mode-change text shows the
|
||||||
|
current mode.
|
||||||
|
|
||||||
Cursor, Windsurf, Cline, Copilot, Aider, Kiro: copy the matching rules file from this repo ([`.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/)).
|
Cursor, Windsurf, Cline, Copilot, Aider, Kiro: copy the matching rules file from this repo ([`.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/)).
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
description = "Audit the whole repo for over-engineering, what can be deleted"
|
||||||
|
prompt = "Audit the entire repository for over-engineering only, not correctness. Scan the whole tree, not a diff. One line per finding, ranked biggest cut first: <tag> <what to cut>. <replacement>. [path]. Tags: delete (dead code/speculative feature), stdlib (reinvented standard library), native (dependency doing what the platform does), yagni (abstraction with one implementation), shrink (same logic, fewer lines). End with the net lines and dependencies removable. If nothing to cut: 'Lean already. Ship.'"
|
||||||
@@ -28,5 +28,6 @@ instructions, keep its copied rule text aligned with `AGENTS.md`.
|
|||||||
|
|
||||||
- `skills/ponytail/SKILL.md`: lazy senior dev mode
|
- `skills/ponytail/SKILL.md`: lazy senior dev mode
|
||||||
- `skills/ponytail-review/SKILL.md`: over-engineering review
|
- `skills/ponytail-review/SKILL.md`: over-engineering review
|
||||||
|
- `skills/ponytail-audit/SKILL.md`: whole-repo over-engineering audit
|
||||||
- `skills/ponytail-help/SKILL.md`: quick reference
|
- `skills/ponytail-help/SKILL.md`: quick reference
|
||||||
- `AGENTS.md`: compact always-on instruction set for agents without skill support
|
- `AGENTS.md`: compact always-on instruction set for agents without skill support
|
||||||
|
|||||||
@@ -114,6 +114,11 @@ export default function ponytailExtension(pi) {
|
|||||||
handler: (_args, ctx) => sendAlias("/skill:ponytail-review", "", ctx),
|
handler: (_args, ctx) => sendAlias("/skill:ponytail-review", "", ctx),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
pi.registerCommand("ponytail-audit", {
|
||||||
|
description: "Run /skill:ponytail-audit",
|
||||||
|
handler: (_args, ctx) => sendAlias("/skill:ponytail-audit", "", ctx),
|
||||||
|
});
|
||||||
|
|
||||||
pi.registerCommand("ponytail-help", {
|
pi.registerCommand("ponytail-help", {
|
||||||
description: "Run /skill:ponytail-help",
|
description: "Run /skill:ponytail-help",
|
||||||
handler: (_args, ctx) => sendAlias("/skill:ponytail-help", "", ctx),
|
handler: (_args, ctx) => sendAlias("/skill:ponytail-help", "", ctx),
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ function withTempConfig(fn) {
|
|||||||
test("extension registers Ponytail commands", () => {
|
test("extension registers Ponytail commands", () => {
|
||||||
const { commands } = createPiHarness();
|
const { commands } = createPiHarness();
|
||||||
|
|
||||||
assert.deepEqual([...commands.keys()].sort(), ["ponytail", "ponytail-help", "ponytail-review"]);
|
assert.deepEqual([...commands.keys()].sort(), ["ponytail", "ponytail-audit", "ponytail-help", "ponytail-review"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("/ponytail updates session mode and injects instructions", async () => withTempConfig(async () => {
|
test("/ponytail updates session mode and injects instructions", async () => withTempConfig(async () => {
|
||||||
@@ -98,10 +98,12 @@ test("skill alias commands delegate to Pi skill commands", async () => {
|
|||||||
const ctx = createCommandContext();
|
const ctx = createCommandContext();
|
||||||
|
|
||||||
await commands.get("ponytail-review").handler("", ctx);
|
await commands.get("ponytail-review").handler("", ctx);
|
||||||
|
await commands.get("ponytail-audit").handler("", ctx);
|
||||||
await commands.get("ponytail-help").handler("", ctx);
|
await commands.get("ponytail-help").handler("", ctx);
|
||||||
|
|
||||||
assert.deepEqual(sentUserMessages.map((entry) => entry.text), [
|
assert.deepEqual(sentUserMessages.map((entry) => entry.text), [
|
||||||
"/skill:ponytail-review",
|
"/skill:ponytail-review",
|
||||||
|
"/skill:ponytail-audit",
|
||||||
"/skill:ponytail-help",
|
"/skill:ponytail-help",
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
name: ponytail-audit
|
||||||
|
description: >
|
||||||
|
Whole-repo audit for over-engineering. Like ponytail-review, but scans the
|
||||||
|
entire codebase instead of a diff: a ranked list of what to delete, simplify,
|
||||||
|
or replace with stdlib/native equivalents. Use when the user says "audit this
|
||||||
|
codebase", "audit for over-engineering", "what can I delete from this repo",
|
||||||
|
"find bloat", "ponytail-audit", or "/ponytail-audit". One-shot report, does
|
||||||
|
not apply fixes.
|
||||||
|
---
|
||||||
|
|
||||||
|
ponytail-review, repo-wide. Scan the whole tree instead of a diff. Rank
|
||||||
|
findings biggest cut first.
|
||||||
|
|
||||||
|
## Tags
|
||||||
|
|
||||||
|
Same as ponytail-review:
|
||||||
|
|
||||||
|
- `delete:` dead code, unused flexibility, speculative feature. Replacement: nothing.
|
||||||
|
- `stdlib:` hand-rolled thing the standard library ships. Name the function.
|
||||||
|
- `native:` dependency or code doing what the platform already does. Name the feature.
|
||||||
|
- `yagni:` abstraction with one implementation, config nobody sets, layer with one caller.
|
||||||
|
- `shrink:` same logic, fewer lines. Show the shorter form.
|
||||||
|
|
||||||
|
## Hunt
|
||||||
|
|
||||||
|
Deps the stdlib or platform already ships, single-implementation interfaces,
|
||||||
|
factories with one product, wrappers that only delegate, files exporting one
|
||||||
|
thing, dead flags and config, hand-rolled stdlib.
|
||||||
|
|
||||||
|
## Output
|
||||||
|
|
||||||
|
One line per finding, ranked: `<tag> <what to cut>. <replacement>. [path]`.
|
||||||
|
End with `net: -<N> lines, -<M> deps possible.` Nothing to cut: `Lean already. Ship.`
|
||||||
|
|
||||||
|
## Boundaries
|
||||||
|
|
||||||
|
Complexity only, correctness bugs, security holes, and performance go to a
|
||||||
|
normal review pass. Lists findings, applies nothing. One-shot.
|
||||||
|
"stop ponytail-audit" or "normal mode" to revert.
|
||||||
Reference in New Issue
Block a user